| 783 | } |
| 784 | |
| 785 | int |
| 786 | rte_thash_adjust_tuple(struct rte_thash_ctx *ctx, |
| 787 | struct rte_thash_subtuple_helper *h, |
| 788 | uint8_t *tuple, unsigned int tuple_len, |
| 789 | uint32_t desired_value, unsigned int attempts, |
| 790 | rte_thash_check_tuple_t fn, void *userdata) |
| 791 | { |
| 792 | uint32_t tmp_tuple[tuple_len / sizeof(uint32_t)]; |
| 793 | unsigned int i, j, ret = 0; |
| 794 | uint32_t hash, adj_bits; |
| 795 | const uint8_t *hash_key; |
| 796 | uint32_t tmp; |
| 797 | int offset; |
| 798 | int tmp_len; |
| 799 | |
| 800 | if ((ctx == NULL) || (h == NULL) || (tuple == NULL) || |
| 801 | (tuple_len % sizeof(uint32_t) != 0) || (attempts <= 0)) |
| 802 | return -EINVAL; |
| 803 | |
| 804 | hash_key = rte_thash_get_key(ctx); |
| 805 | |
| 806 | attempts = RTE_MIN(attempts, 1U << (h->tuple_len - ctx->reta_sz_log)); |
| 807 | |
| 808 | for (i = 0; i < attempts; i++) { |
| 809 | if (ctx->matrices != NULL) |
| 810 | hash = rte_thash_gfni(ctx->matrices, tuple, tuple_len); |
| 811 | else { |
| 812 | for (j = 0; j < (tuple_len / 4); j++) |
| 813 | tmp_tuple[j] = |
| 814 | rte_be_to_cpu_32( |
| 815 | *(uint32_t *)&tuple[j * 4]); |
| 816 | |
| 817 | hash = rte_softrss(tmp_tuple, tuple_len / 4, hash_key); |
| 818 | } |
| 819 | |
| 820 | adj_bits = rte_thash_get_complement(h, hash, desired_value); |
| 821 | |
| 822 | /* |
| 823 | * Hint: LSB of adj_bits corresponds to |
| 824 | * offset + len bit of the subtuple |
| 825 | */ |
| 826 | offset = h->tuple_offset + h->tuple_len - ctx->reta_sz_log; |
| 827 | tmp = read_unaligned_bits(tuple, ctx->reta_sz_log, offset); |
| 828 | tmp ^= adj_bits; |
| 829 | write_unaligned_bits(tuple, ctx->reta_sz_log, offset, tmp); |
| 830 | |
| 831 | if (fn != NULL) { |
| 832 | ret = (fn(userdata, tuple)) ? 0 : -EEXIST; |
| 833 | if (ret == 0) |
| 834 | return 0; |
| 835 | else if (i < (attempts - 1)) { |
| 836 | /* increment subtuple part by 1 */ |
| 837 | tmp_len = RTE_MIN(sizeof(uint32_t) * CHAR_BIT, |
| 838 | h->tuple_len - ctx->reta_sz_log); |
| 839 | offset -= tmp_len; |
| 840 | tmp = read_unaligned_bits(tuple, tmp_len, |
| 841 | offset); |
| 842 | tmp++; |