Skip to content

Commit

Permalink
cxgb4: add skeleton for ethtool n-tuple filters
Browse files Browse the repository at this point in the history
Allocate and manage resources required for ethtool n-tuple filters.
Also fetch the HASH filter region size and calculate nhash entries.

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Vishal Kulkarni <vishal@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Vishal Kulkarni authored and David S. Miller committed Jun 19, 2020
1 parent 4b61d3e commit d915c29
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 16 deletions.
14 changes: 14 additions & 0 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,17 @@ struct mps_entries_ref {
refcount_t refcnt;
};

struct cxgb4_ethtool_filter_info {
u32 *loc_array; /* Array holding the actual TIDs set to filters */
unsigned long *bmap; /* Bitmap for managing filters in use */
u32 in_use; /* # of filters in use */
};

struct cxgb4_ethtool_filter {
u32 nentries; /* Adapter wide number of supported filters */
struct cxgb4_ethtool_filter_info *port; /* Per port entry */
};

struct adapter {
void __iomem *regs;
void __iomem *bar2;
Expand Down Expand Up @@ -1191,6 +1202,9 @@ struct adapter {

/* TC MATCHALL classifier offload */
struct cxgb4_tc_matchall *tc_matchall;

/* Ethtool n-tuple */
struct cxgb4_ethtool_filter *ethtool_filters;
};

/* Support for "sched-class" command to allow a TX Scheduling Class to be
Expand Down
82 changes: 82 additions & 0 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "t4_regs.h"
#include "t4fw_api.h"
#include "cxgb4_cudbg.h"
#include "cxgb4_filter.h"

#define EEPROM_MAGIC 0x38E2F10C

Expand Down Expand Up @@ -1853,6 +1854,87 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
.set_priv_flags = cxgb4_set_priv_flags,
};

void cxgb4_cleanup_ethtool_filters(struct adapter *adap)
{
struct cxgb4_ethtool_filter_info *eth_filter_info;
u8 i;

if (!adap->ethtool_filters)
return;

eth_filter_info = adap->ethtool_filters->port;

if (eth_filter_info) {
for (i = 0; i < adap->params.nports; i++) {
kvfree(eth_filter_info[i].loc_array);
kfree(eth_filter_info[i].bmap);
}
kfree(eth_filter_info);
}

kfree(adap->ethtool_filters);
}

int cxgb4_init_ethtool_filters(struct adapter *adap)
{
struct cxgb4_ethtool_filter_info *eth_filter_info;
struct cxgb4_ethtool_filter *eth_filter;
struct tid_info *tids = &adap->tids;
u32 nentries, i;
int ret;

eth_filter = kzalloc(sizeof(*eth_filter), GFP_KERNEL);
if (!eth_filter)
return -ENOMEM;

eth_filter_info = kcalloc(adap->params.nports,
sizeof(*eth_filter_info),
GFP_KERNEL);
if (!eth_filter_info) {
ret = -ENOMEM;
goto free_eth_filter;
}

eth_filter->port = eth_filter_info;

nentries = tids->nhpftids + tids->nftids;
if (is_hashfilter(adap))
nentries += tids->nhash +
(adap->tids.stid_base - adap->tids.tid_base);
eth_filter->nentries = nentries;

for (i = 0; i < adap->params.nports; i++) {
eth_filter->port[i].loc_array = kvzalloc(nentries, GFP_KERNEL);
if (!eth_filter->port[i].loc_array) {
ret = -ENOMEM;
goto free_eth_finfo;
}

eth_filter->port[i].bmap = kcalloc(BITS_TO_LONGS(nentries),
sizeof(unsigned long),
GFP_KERNEL);
if (!eth_filter->port[i].bmap) {
ret = -ENOMEM;
goto free_eth_finfo;
}
}

adap->ethtool_filters = eth_filter;
return 0;

free_eth_finfo:
while (i-- > 0) {
kfree(eth_filter->port[i].bmap);
kvfree(eth_filter->port[i].loc_array);
}
kfree(eth_filter_info);

free_eth_filter:
kfree(eth_filter);

return ret;
}

void cxgb4_set_ethtool_ops(struct net_device *netdev)
{
netdev->ethtool_ops = &cxgb_ethtool_ops;
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,6 @@ void clear_all_filters(struct adapter *adapter);
void init_hash_filter(struct adapter *adap);
bool is_filter_exact_match(struct adapter *adap,
struct ch_filter_specification *fs);
void cxgb4_cleanup_ethtool_filters(struct adapter *adap);
int cxgb4_init_ethtool_filters(struct adapter *adap);
#endif /* __CXGB4_FILTER_H */
38 changes: 22 additions & 16 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5860,6 +5860,7 @@ static void free_some_resources(struct adapter *adapter)
cxgb4_cleanup_tc_mqprio(adapter);
cxgb4_cleanup_tc_flower(adapter);
cxgb4_cleanup_tc_u32(adapter);
cxgb4_cleanup_ethtool_filters(adapter);
kfree(adapter->sge.egr_map);
kfree(adapter->sge.ingr_map);
kfree(adapter->sge.starving_fl);
Expand Down Expand Up @@ -6493,6 +6494,24 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
i);
}

if (is_offload(adapter) || is_hashfilter(adapter)) {
if (t4_read_reg(adapter, LE_DB_CONFIG_A) & HASHEN_F) {
u32 v;

v = t4_read_reg(adapter, LE_DB_HASH_CONFIG_A);
if (chip_ver <= CHELSIO_T5) {
adapter->tids.nhash = 1 << HASHTIDSIZE_G(v);
v = t4_read_reg(adapter, LE_DB_TID_HASHBASE_A);
adapter->tids.hash_base = v / 4;
} else {
adapter->tids.nhash = HASHTBLSIZE_G(v) << 3;
v = t4_read_reg(adapter,
T6_LE_DB_HASH_TID_BASE_A);
adapter->tids.hash_base = v;
}
}
}

if (tid_init(&adapter->tids) < 0) {
dev_warn(&pdev->dev, "could not allocate TID table, "
"continuing\n");
Expand All @@ -6514,22 +6533,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (cxgb4_init_tc_matchall(adapter))
dev_warn(&pdev->dev,
"could not offload tc matchall, continuing\n");
}

if (is_offload(adapter) || is_hashfilter(adapter)) {
if (t4_read_reg(adapter, LE_DB_CONFIG_A) & HASHEN_F) {
u32 hash_base, hash_reg;

if (chip_ver <= CHELSIO_T5) {
hash_reg = LE_DB_TID_HASHBASE_A;
hash_base = t4_read_reg(adapter, hash_reg);
adapter->tids.hash_base = hash_base / 4;
} else {
hash_reg = T6_LE_DB_HASH_TID_BASE_A;
hash_base = t4_read_reg(adapter, hash_reg);
adapter->tids.hash_base = hash_base;
}
}
if (cxgb4_init_ethtool_filters(adapter))
dev_warn(&pdev->dev,
"could not initialize ethtool filters, continuing\n");
}

/* See what interrupts we'll be using */
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ struct tid_info {
unsigned long *stid_bmap;
unsigned int nstids;
unsigned int stid_base;

unsigned int nhash;
unsigned int hash_base;

union aopen_entry *atid_tab;
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -3044,6 +3044,10 @@
#define HASHTIDSIZE_M 0x3fU
#define HASHTIDSIZE_G(x) (((x) >> HASHTIDSIZE_S) & HASHTIDSIZE_M)

#define HASHTBLSIZE_S 3
#define HASHTBLSIZE_M 0x1ffffU
#define HASHTBLSIZE_G(x) (((x) >> HASHTBLSIZE_S) & HASHTBLSIZE_M)

#define LE_DB_HASH_TID_BASE_A 0x19c30
#define LE_DB_HASH_TBL_BASE_ADDR_A 0x19c30
#define LE_DB_INT_CAUSE_A 0x19c3c
Expand Down

0 comments on commit d915c29

Please sign in to comment.