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:
parent
ab3ce1e0c1
commit
3a381a4116
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user