Commit 80cfde29 authored by Michael Chan's avatar Michael Chan Committed by David S. Miller

bnxt_en: Refactor the hash table logic for ntuple filters.

Generalize the ethtool logic that walks the ntuple hash table now that
we have the common bnxt_filter_base structure.  This will allow the code
to easily extend to cover user defined ntuple or ether filters.
Reviewed-by: default avatarVasundhara Volam <vasundhara-v.volam@broadcom.com>
Reviewed-by: default avatarAndy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: default avatarPavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 59cde76f
...@@ -5615,6 +5615,7 @@ static int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp, ...@@ -5615,6 +5615,7 @@ static int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
struct hwrm_cfa_ntuple_filter_free_input *req; struct hwrm_cfa_ntuple_filter_free_input *req;
int rc; int rc;
set_bit(BNXT_FLTR_FW_DELETED, &fltr->base.state);
rc = hwrm_req_init(bp, req, HWRM_CFA_NTUPLE_FILTER_FREE); rc = hwrm_req_init(bp, req, HWRM_CFA_NTUPLE_FILTER_FREE);
if (rc) if (rc)
return rc; return rc;
......
...@@ -1349,6 +1349,7 @@ struct bnxt_filter_base { ...@@ -1349,6 +1349,7 @@ struct bnxt_filter_base {
unsigned long state; unsigned long state;
#define BNXT_FLTR_VALID 0 #define BNXT_FLTR_VALID 0
#define BNXT_FLTR_INSERTED 1 #define BNXT_FLTR_INSERTED 1
#define BNXT_FLTR_FW_DELETED 2
struct rcu_head rcu; struct rcu_head rcu;
}; };
......
...@@ -1012,28 +1012,60 @@ static int bnxt_set_channels(struct net_device *dev, ...@@ -1012,28 +1012,60 @@ static int bnxt_set_channels(struct net_device *dev,
} }
#ifdef CONFIG_RFS_ACCEL #ifdef CONFIG_RFS_ACCEL
static int bnxt_grxclsrlall(struct bnxt *bp, struct ethtool_rxnfc *cmd, static u32 bnxt_get_all_fltr_ids_rcu(struct bnxt *bp, struct hlist_head tbl[],
u32 *rule_locs) int tbl_size, u32 *ids, u32 start,
u32 id_cnt)
{ {
int i, j = 0; int i, j = start;
cmd->data = bp->ntp_fltr_count; if (j >= id_cnt)
for (i = 0; i < BNXT_NTP_FLTR_HASH_SIZE; i++) { return j;
for (i = 0; i < tbl_size; i++) {
struct hlist_head *head; struct hlist_head *head;
struct bnxt_ntuple_filter *fltr; struct bnxt_filter_base *fltr;
head = &bp->ntp_fltr_hash_tbl[i]; head = &tbl[i];
rcu_read_lock(); hlist_for_each_entry_rcu(fltr, head, hash) {
hlist_for_each_entry_rcu(fltr, head, base.hash) { if (!fltr->flags ||
if (j == cmd->rule_cnt) test_bit(BNXT_FLTR_FW_DELETED, &fltr->state))
break; continue;
rule_locs[j++] = fltr->base.sw_id; ids[j++] = fltr->sw_id;
if (j == id_cnt)
return j;
} }
rcu_read_unlock();
if (j == cmd->rule_cnt)
break;
} }
cmd->rule_cnt = j; return j;
}
static struct bnxt_filter_base *bnxt_get_one_fltr_rcu(struct bnxt *bp,
struct hlist_head tbl[],
int tbl_size, u32 id)
{
int i;
for (i = 0; i < tbl_size; i++) {
struct hlist_head *head;
struct bnxt_filter_base *fltr;
head = &tbl[i];
hlist_for_each_entry_rcu(fltr, head, hash) {
if (fltr->flags && fltr->sw_id == id)
return fltr;
}
}
return NULL;
}
static int bnxt_grxclsrlall(struct bnxt *bp, struct ethtool_rxnfc *cmd,
u32 *rule_locs)
{
cmd->data = bp->ntp_fltr_count;
rcu_read_lock();
cmd->rule_cnt = bnxt_get_all_fltr_ids_rcu(bp, bp->ntp_fltr_hash_tbl,
BNXT_NTP_FLTR_HASH_SIZE,
rule_locs, 0, cmd->rule_cnt);
rcu_read_unlock();
return 0; return 0;
} }
...@@ -1041,27 +1073,24 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd) ...@@ -1041,27 +1073,24 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd)
{ {
struct ethtool_rx_flow_spec *fs = struct ethtool_rx_flow_spec *fs =
(struct ethtool_rx_flow_spec *)&cmd->fs; (struct ethtool_rx_flow_spec *)&cmd->fs;
struct bnxt_filter_base *fltr_base;
struct bnxt_ntuple_filter *fltr; struct bnxt_ntuple_filter *fltr;
struct flow_keys *fkeys; struct flow_keys *fkeys;
int i, rc = -EINVAL; int rc = -EINVAL;
if (fs->location >= BNXT_NTP_FLTR_MAX_FLTR) if (fs->location >= BNXT_NTP_FLTR_MAX_FLTR)
return rc; return rc;
for (i = 0; i < BNXT_NTP_FLTR_HASH_SIZE; i++) {
struct hlist_head *head;
head = &bp->ntp_fltr_hash_tbl[i];
rcu_read_lock(); rcu_read_lock();
hlist_for_each_entry_rcu(fltr, head, base.hash) { fltr_base = bnxt_get_one_fltr_rcu(bp, bp->ntp_fltr_hash_tbl,
if (fltr->base.sw_id == fs->location) BNXT_NTP_FLTR_HASH_SIZE,
goto fltr_found; fs->location);
} if (!fltr_base) {
rcu_read_unlock(); rcu_read_unlock();
}
return rc; return rc;
}
fltr = container_of(fltr_base, struct bnxt_ntuple_filter, base);
fltr_found:
fkeys = &fltr->fkeys; fkeys = &fltr->fkeys;
if (fkeys->basic.n_proto == htons(ETH_P_IP)) { if (fkeys->basic.n_proto == htons(ETH_P_IP)) {
if (fkeys->basic.ip_proto == IPPROTO_TCP) if (fkeys->basic.ip_proto == IPPROTO_TCP)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment