net/cxgbe: query firmware for HASH filter resources

Fetch available HASH filter resources and allocate table for managing
them. Currently only supported on Chelsio T6 family of NICs.

Signed-off-by: Shagun Agrawal <shaguna@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
This commit is contained in:
Shagun Agrawal 2018-06-29 23:42:16 +05:30 committed by Ferruh Yigit
parent ab3ce1e0c1
commit 3a381a4116
7 changed files with 134 additions and 6 deletions

View File

@ -251,6 +251,8 @@ struct adapter_params {
unsigned char nports; /* # of ethernet ports */
unsigned char portvec;
unsigned char hash_filter;
enum chip_type chip; /* chip code */
struct arch_specific_params arch; /* chip specific params */
@ -314,6 +316,11 @@ static inline int is_pf4(struct adapter *adap)
#define for_each_port(adapter, iter) \
for (iter = 0; iter < (adapter)->params.nports; ++iter)
static inline int is_hashfilter(const struct adapter *adap)
{
return adap->params.hash_filter;
}
void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log);
void t4_tp_wr_bits_indirect(struct adapter *adap, unsigned int addr,
unsigned int mask, unsigned int val);

View File

@ -937,3 +937,12 @@
#define M_REV 0xfU
#define V_REV(x) ((x) << S_REV)
#define G_REV(x) (((x) >> S_REV) & M_REV)
/* registers for module LE */
#define A_LE_DB_CONFIG 0x19c04
#define S_HASHEN 20
#define V_HASHEN(x) ((x) << S_HASHEN)
#define F_HASHEN V_HASHEN(1U)
#define A_LE_DB_TID_HASHBASE 0x19df8

View File

@ -250,4 +250,16 @@ static inline void writel_relaxed(unsigned int val, volatile void __iomem *addr)
rte_write32_relaxed(val, addr);
}
/*
* Multiplies an integer by a fraction, while avoiding unnecessary
* overflow or loss of precision.
*/
#define mult_frac(x, numer, denom)( \
{ \
typeof(x) quot = (x) / (denom); \
typeof(x) rem = (x) % (denom); \
(quot * (numer)) + ((rem * (numer)) / (denom)); \
} \
)
#endif /* _CXGBE_COMPAT_H_ */

View File

@ -7,6 +7,44 @@
#include "t4_regs.h"
#include "cxgbe_filter.h"
/**
* Initialize Hash Filters
*/
int init_hash_filter(struct adapter *adap)
{
unsigned int n_user_filters;
unsigned int user_filter_perc;
int ret;
u32 params[7], val[7];
#define FW_PARAM_DEV(param) \
(V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \
V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param))
#define FW_PARAM_PFVF(param) \
(V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \
V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param) | \
V_FW_PARAMS_PARAM_Y(0) | \
V_FW_PARAMS_PARAM_Z(0))
params[0] = FW_PARAM_DEV(NTID);
ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
params, val);
if (ret < 0)
return ret;
adap->tids.ntids = val[0];
adap->tids.natids = min(adap->tids.ntids / 2, MAX_ATIDS);
user_filter_perc = 100;
n_user_filters = mult_frac(adap->tids.nftids,
user_filter_perc,
100);
adap->tids.nftids = n_user_filters;
adap->params.hash_filter = 1;
return 0;
}
/**
* Validate if the requested filter specification can be set by checking
* if the requested features have been enabled

View File

@ -220,6 +220,7 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
struct ch_filter_specification *fs,
struct filter_ctx *ctx);
int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family);
int init_hash_filter(struct adapter *adap);
int validate_filter(struct adapter *adap, struct ch_filter_specification *fs);
int cxgbe_get_filter_count(struct adapter *adapter, unsigned int fidx,
u64 *c, bool get_byte);

View File

@ -287,24 +287,43 @@ static int tid_init(struct tid_info *t)
{
size_t size;
unsigned int ftid_bmap_size;
unsigned int natids = t->natids;
unsigned int max_ftids = t->nftids;
ftid_bmap_size = rte_bitmap_get_memory_footprint(t->nftids);
size = t->ntids * sizeof(*t->tid_tab) +
max_ftids * sizeof(*t->ftid_tab);
max_ftids * sizeof(*t->ftid_tab) +
natids * sizeof(*t->atid_tab);
t->tid_tab = t4_os_alloc(size);
if (!t->tid_tab)
return -ENOMEM;
t->ftid_tab = (struct filter_entry *)&t->tid_tab[t->ntids];
t->atid_tab = (union aopen_entry *)&t->tid_tab[t->ntids];
t->ftid_tab = (struct filter_entry *)&t->tid_tab[t->natids];
t->ftid_bmap_array = t4_os_alloc(ftid_bmap_size);
if (!t->ftid_bmap_array) {
tid_free(t);
return -ENOMEM;
}
t4_os_lock_init(&t->atid_lock);
t4_os_lock_init(&t->ftid_lock);
t->afree = NULL;
t->atids_in_use = 0;
rte_atomic32_init(&t->tids_in_use);
rte_atomic32_set(&t->tids_in_use, 0);
rte_atomic32_init(&t->conns_in_use);
rte_atomic32_set(&t->conns_in_use, 0);
/* Setup the free list for atid_tab and clear the stid bitmap. */
if (natids) {
while (--natids)
t->atid_tab[natids - 1].next = &t->atid_tab[natids];
t->afree = t->atid_tab;
}
t->ftid_bmap = rte_bitmap_init(t->nftids, t->ftid_bmap_array,
ftid_bmap_size);
if (!t->ftid_bmap) {
@ -784,8 +803,7 @@ static int adap_init0_config(struct adapter *adapter, int reset)
* This will allow the firmware to optimize aspects of the hardware
* configuration which will result in improved performance.
*/
caps_cmd.niccaps &= cpu_to_be16(~(FW_CAPS_CONFIG_NIC_HASHFILTER |
FW_CAPS_CONFIG_NIC_ETHOFLD));
caps_cmd.niccaps &= cpu_to_be16(~FW_CAPS_CONFIG_NIC_ETHOFLD);
caps_cmd.toecaps = 0;
caps_cmd.iscsicaps = 0;
caps_cmd.rdmacaps = 0;
@ -990,6 +1008,12 @@ static int adap_init0(struct adapter *adap)
if (ret < 0)
goto bye;
if ((caps_cmd.niccaps & cpu_to_be16(FW_CAPS_CONFIG_NIC_HASHFILTER)) &&
is_t6(adap->params.chip)) {
if (init_hash_filter(adap) < 0)
goto bye;
}
/* query tid-related parameters */
params[0] = FW_PARAM_DEV(NTID);
ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
@ -997,6 +1021,7 @@ static int adap_init0(struct adapter *adap)
if (ret < 0)
goto bye;
adap->tids.ntids = val[0];
adap->tids.natids = min(adap->tids.ntids / 2, MAX_ATIDS);
/* If we're running on newer firmware, let it know that we're
* prepared to deal with encapsulated CPL messages. Older
@ -1653,6 +1678,20 @@ int cxgbe_probe(struct adapter *adapter)
"filter support disabled. Continuing\n");
}
if (is_hashfilter(adapter)) {
if (t4_read_reg(adapter, A_LE_DB_CONFIG) & F_HASHEN) {
u32 hash_base, hash_reg;
hash_reg = A_LE_DB_TID_HASHBASE;
hash_base = t4_read_reg(adapter, hash_reg);
adapter->tids.hash_base = hash_base / 4;
}
} else {
/* Disable hash filtering support */
dev_warn(adapter,
"Maskless filter support disabled. Continuing\n");
}
err = init_rss(adapter);
if (err)
goto out_free;

View File

@ -10,6 +10,16 @@
#include "cxgbe_filter.h"
/*
* Max # of ATIDs. The absolute HW max is 16K but we keep it lower.
*/
#define MAX_ATIDS 8192U
union aopen_entry {
void *data;
union aopen_entry *next;
};
/*
* Holds the size, base address, free list start, etc of filter TID.
* The tables themselves are allocated dynamically.
@ -18,10 +28,22 @@ struct tid_info {
void **tid_tab;
unsigned int ntids;
struct filter_entry *ftid_tab; /* Normal filters */
union aopen_entry *atid_tab;
struct rte_bitmap *ftid_bmap;
uint8_t *ftid_bmap_array;
unsigned int nftids;
unsigned int ftid_base;
unsigned int nftids, natids;
unsigned int ftid_base, hash_base;
union aopen_entry *afree;
unsigned int atids_in_use;
/* TIDs in the TCAM */
rte_atomic32_t tids_in_use;
/* TIDs in the HASH */
rte_atomic32_t hash_tids_in_use;
rte_atomic32_t conns_in_use;
rte_spinlock_t atid_lock __rte_cache_aligned;
rte_spinlock_t ftid_lock;
};
#endif /* _CXGBE_OFLD_H_ */