Skip to content

Commit d3c9828

Browse files
Pavan Chebbidavem330
authored andcommitted
bnxt_en: Add function to calculate Toeplitz hash
For ntuple filters added by aRFS, the Toeplitz hash calculated by our NIC is available and is used to store the ntuple filter for quick retrieval. In the next patches, user defined ntuple filter support will be added and we need to calculate the same hash for these filters. The same hash function needs to be used so we can detect duplicates. Add the function bnxt_toeplitz() to calculate the Toeplitz hash for user defined ntuple filters. bnxt_toeplitz() uses the same Toeplitz key and the same key length as the NIC. bnxt_get_ntp_filter_idx() is added to return the hash index. For aRFS, the hash comes from the NIC. For user defined ntuple, we call bnxt_toeplitz() to calculate the hash index. Reviewed-by: Andy Gospodarek <[email protected]> Signed-off-by: Pavan Chebbi <[email protected]> Signed-off-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 96c9bed commit d3c9828

File tree

2 files changed

+108
-3
lines changed

2 files changed

+108
-3
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4199,13 +4199,22 @@ static void bnxt_init_vnics(struct bnxt *bp)
41994199
vnic->fw_l2_ctx_id = INVALID_HW_RING_ID;
42004200

42014201
if (bp->vnic_info[i].rss_hash_key) {
4202-
if (i == 0)
4202+
if (!i) {
4203+
u8 *key = (void *)vnic->rss_hash_key;
4204+
int k;
4205+
4206+
bp->toeplitz_prefix = 0;
42034207
get_random_bytes(vnic->rss_hash_key,
42044208
HW_HASH_KEY_SIZE);
4205-
else
4209+
for (k = 0; k < 8; k++) {
4210+
bp->toeplitz_prefix <<= 8;
4211+
bp->toeplitz_prefix |= key[k];
4212+
}
4213+
} else {
42064214
memcpy(vnic->rss_hash_key,
42074215
bp->vnic_info[0].rss_hash_key,
42084216
HW_HASH_KEY_SIZE);
4217+
}
42094218
}
42104219
}
42114220
}
@@ -5374,6 +5383,79 @@ static struct bnxt_l2_filter *bnxt_lookup_l2_filter(struct bnxt *bp,
53745383
return fltr;
53755384
}
53765385

5386+
#define BNXT_IPV4_4TUPLE(bp, fkeys) \
5387+
(((fkeys)->basic.ip_proto == IPPROTO_TCP && \
5388+
(bp)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4) || \
5389+
((fkeys)->basic.ip_proto == IPPROTO_UDP && \
5390+
(bp)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV4))
5391+
5392+
#define BNXT_IPV6_4TUPLE(bp, fkeys) \
5393+
(((fkeys)->basic.ip_proto == IPPROTO_TCP && \
5394+
(bp)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6) || \
5395+
((fkeys)->basic.ip_proto == IPPROTO_UDP && \
5396+
(bp)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6))
5397+
5398+
static u32 bnxt_get_rss_flow_tuple_len(struct bnxt *bp, struct flow_keys *fkeys)
5399+
{
5400+
if (fkeys->basic.n_proto == htons(ETH_P_IP)) {
5401+
if (BNXT_IPV4_4TUPLE(bp, fkeys))
5402+
return sizeof(fkeys->addrs.v4addrs) +
5403+
sizeof(fkeys->ports);
5404+
5405+
if (bp->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_IPV4)
5406+
return sizeof(fkeys->addrs.v4addrs);
5407+
}
5408+
5409+
if (fkeys->basic.n_proto == htons(ETH_P_IPV6)) {
5410+
if (BNXT_IPV6_4TUPLE(bp, fkeys))
5411+
return sizeof(fkeys->addrs.v6addrs) +
5412+
sizeof(fkeys->ports);
5413+
5414+
if (bp->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6)
5415+
return sizeof(fkeys->addrs.v6addrs);
5416+
}
5417+
5418+
return 0;
5419+
}
5420+
5421+
static u32 bnxt_toeplitz(struct bnxt *bp, struct flow_keys *fkeys,
5422+
const unsigned char *key)
5423+
{
5424+
u64 prefix = bp->toeplitz_prefix, hash = 0;
5425+
struct bnxt_ipv4_tuple tuple4;
5426+
struct bnxt_ipv6_tuple tuple6;
5427+
int i, j, len = 0;
5428+
u8 *four_tuple;
5429+
5430+
len = bnxt_get_rss_flow_tuple_len(bp, fkeys);
5431+
if (!len)
5432+
return 0;
5433+
5434+
if (fkeys->basic.n_proto == htons(ETH_P_IP)) {
5435+
tuple4.v4addrs = fkeys->addrs.v4addrs;
5436+
tuple4.ports = fkeys->ports;
5437+
four_tuple = (unsigned char *)&tuple4;
5438+
} else {
5439+
tuple6.v6addrs = fkeys->addrs.v6addrs;
5440+
tuple6.ports = fkeys->ports;
5441+
four_tuple = (unsigned char *)&tuple6;
5442+
}
5443+
5444+
for (i = 0, j = 8; i < len; i++, j++) {
5445+
u8 byte = four_tuple[i];
5446+
int bit;
5447+
5448+
for (bit = 0; bit < 8; bit++, prefix <<= 1, byte <<= 1) {
5449+
if (byte & 0x80)
5450+
hash ^= prefix;
5451+
}
5452+
prefix |= (j < HW_HASH_KEY_SIZE) ? key[j] : 0;
5453+
}
5454+
5455+
/* The valid part of the hash is in the upper 32 bits. */
5456+
return (hash >> 32) & BNXT_NTP_FLTR_HASH_MASK;
5457+
}
5458+
53775459
#ifdef CONFIG_RFS_ACCEL
53785460
static struct bnxt_l2_filter *
53795461
bnxt_lookup_l2_filter_from_key(struct bnxt *bp, struct bnxt_l2_key *key)
@@ -13774,6 +13856,18 @@ static int bnxt_setup_tc(struct net_device *dev, enum tc_setup_type type,
1377413856
}
1377513857
}
1377613858

13859+
static u32 bnxt_get_ntp_filter_idx(struct bnxt *bp, struct flow_keys *fkeys,
13860+
const struct sk_buff *skb)
13861+
{
13862+
struct bnxt_vnic_info *vnic;
13863+
13864+
if (skb)
13865+
return skb_get_hash_raw(skb) & BNXT_NTP_FLTR_HASH_MASK;
13866+
13867+
vnic = &bp->vnic_info[0];
13868+
return bnxt_toeplitz(bp, fkeys, (void *)vnic->rss_hash_key);
13869+
}
13870+
1377713871
#ifdef CONFIG_RFS_ACCEL
1377813872
static bool bnxt_fltr_match(struct bnxt_ntuple_filter *f1,
1377913873
struct bnxt_ntuple_filter *f2)
@@ -13866,7 +13960,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
1386613960

1386713961
new_fltr->l2_fltr = l2_fltr;
1386813962

13869-
idx = skb_get_hash_raw(skb) & BNXT_NTP_FLTR_HASH_MASK;
13963+
idx = bnxt_get_ntp_filter_idx(bp, fkeys, skb);
1387013964
head = &bp->ntp_fltr_hash_tbl[idx];
1387113965
rcu_read_lock();
1387213966
hlist_for_each_entry_rcu(fltr, head, base.hash) {

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,6 +1370,16 @@ struct bnxt_l2_key {
13701370
};
13711371
};
13721372

1373+
struct bnxt_ipv4_tuple {
1374+
struct flow_dissector_key_ipv4_addrs v4addrs;
1375+
struct flow_dissector_key_ports ports;
1376+
};
1377+
1378+
struct bnxt_ipv6_tuple {
1379+
struct flow_dissector_key_ipv6_addrs v6addrs;
1380+
struct flow_dissector_key_ports ports;
1381+
};
1382+
13731383
#define BNXT_L2_KEY_SIZE (sizeof(struct bnxt_l2_key) / 4)
13741384

13751385
struct bnxt_l2_filter {
@@ -2413,6 +2423,7 @@ struct bnxt {
24132423
struct hlist_head l2_fltr_hash_tbl[BNXT_L2_FLTR_HASH_SIZE];
24142424

24152425
u32 hash_seed;
2426+
u64 toeplitz_prefix;
24162427

24172428
/* To protect link related settings during link changes and
24182429
* ethtool settings changes.

0 commit comments

Comments
 (0)