Skip to content

Commit

Permalink
cxgb4/chtls: fix ULD connection failures due to wrong TID base
Browse files Browse the repository at this point in the history
Currently, the hardware TID index is assumed to start from index 0.
However, with the following changeset,

commit c219399 ("cxgb4: add support for high priority filters")

hardware TID index can start after the high priority region, which
has introduced a regression resulting in connection failures for
ULDs.

So, fix all related code to properly recalculate the TID start index
based on whether high priority filters are enabled or not.

Fixes: c219399 ("cxgb4: add support for high priority filters")
Signed-off-by: Shahjada Abul Husain <shahjada@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Shahjada Abul Husain authored and David S. Miller committed Dec 18, 2019
1 parent 3646ae0 commit 59437d7
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 26 deletions.
2 changes: 1 addition & 1 deletion drivers/crypto/chelsio/chtls/chtls_cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1273,7 +1273,7 @@ static int chtls_pass_accept_req(struct chtls_dev *cdev, struct sk_buff *skb)
ctx = (struct listen_ctx *)data;
lsk = ctx->lsk;

if (unlikely(tid >= cdev->tids->ntids)) {
if (unlikely(tid_out_of_range(cdev->tids, tid))) {
pr_info("passive open TID %u too large\n", tid);
return 1;
}
Expand Down
22 changes: 10 additions & 12 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3171,14 +3171,12 @@ static const struct file_operations mem_debugfs_fops = {

static int tid_info_show(struct seq_file *seq, void *v)
{
unsigned int tid_start = 0;
struct adapter *adap = seq->private;
const struct tid_info *t = &adap->tids;
enum chip_type chip = CHELSIO_CHIP_VERSION(adap->params.chip);

if (chip > CHELSIO_T5)
tid_start = t4_read_reg(adap, LE_DB_ACTIVE_TABLE_START_INDEX_A);
const struct tid_info *t;
enum chip_type chip;

t = &adap->tids;
chip = CHELSIO_CHIP_VERSION(adap->params.chip);
if (t4_read_reg(adap, LE_DB_CONFIG_A) & HASHEN_F) {
unsigned int sb;
seq_printf(seq, "Connections in use: %u\n",
Expand All @@ -3190,9 +3188,9 @@ static int tid_info_show(struct seq_file *seq, void *v)
sb = t4_read_reg(adap, LE_DB_SRVR_START_INDEX_A);

if (sb) {
seq_printf(seq, "TID range: %u..%u/%u..%u", tid_start,
seq_printf(seq, "TID range: %u..%u/%u..%u", t->tid_base,
sb - 1, adap->tids.hash_base,
t->ntids - 1);
t->tid_base + t->ntids - 1);
seq_printf(seq, ", in use: %u/%u\n",
atomic_read(&t->tids_in_use),
atomic_read(&t->hash_tids_in_use));
Expand All @@ -3201,23 +3199,23 @@ static int tid_info_show(struct seq_file *seq, void *v)
t->aftid_base,
t->aftid_end,
adap->tids.hash_base,
t->ntids - 1);
t->tid_base + t->ntids - 1);
seq_printf(seq, ", in use: %u/%u\n",
atomic_read(&t->tids_in_use),
atomic_read(&t->hash_tids_in_use));
} else {
seq_printf(seq, "TID range: %u..%u",
adap->tids.hash_base,
t->ntids - 1);
t->tid_base + t->ntids - 1);
seq_printf(seq, ", in use: %u\n",
atomic_read(&t->hash_tids_in_use));
}
} else if (t->ntids) {
seq_printf(seq, "Connections in use: %u\n",
atomic_read(&t->conns_in_use));

seq_printf(seq, "TID range: %u..%u", tid_start,
tid_start + t->ntids - 1);
seq_printf(seq, "TID range: %u..%u", t->tid_base,
t->tid_base + t->ntids - 1);
seq_printf(seq, ", in use: %u\n",
atomic_read(&t->tids_in_use));
}
Expand Down
12 changes: 5 additions & 7 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,13 +361,11 @@ static int get_filter_count(struct adapter *adapter, unsigned int fidx,

tcb_base = t4_read_reg(adapter, TP_CMM_TCB_BASE_A);
if (is_hashfilter(adapter) && hash) {
if (fidx < adapter->tids.ntids) {
f = adapter->tids.tid_tab[fidx];
if (!f)
return -EINVAL;
} else {
if (tid_out_of_range(&adapter->tids, fidx))
return -E2BIG;
}
f = adapter->tids.tid_tab[fidx - adapter->tids.tid_base];
if (!f)
return -EINVAL;
} else {
if ((fidx != (adapter->tids.nftids + adapter->tids.nsftids +
adapter->tids.nhpftids - 1)) &&
Expand Down Expand Up @@ -1615,7 +1613,7 @@ static int cxgb4_del_hash_filter(struct net_device *dev, int filter_id,
netdev_dbg(dev, "%s: filter_id = %d ; nftids = %d\n",
__func__, filter_id, adapter->tids.nftids);

if (filter_id > adapter->tids.ntids)
if (tid_out_of_range(t, filter_id))
return -E2BIG;

f = lookup_tid(t, filter_id);
Expand Down
13 changes: 8 additions & 5 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1447,8 +1447,8 @@ static void mk_tid_release(struct sk_buff *skb, unsigned int chan,
static void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
unsigned int tid)
{
void **p = &t->tid_tab[tid];
struct adapter *adap = container_of(t, struct adapter, tids);
void **p = &t->tid_tab[tid - t->tid_base];

spin_lock_bh(&adap->tid_release_lock);
*p = adap->tid_release_head;
Expand Down Expand Up @@ -1500,13 +1500,13 @@ static void process_tid_release_list(struct work_struct *work)
void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid,
unsigned short family)
{
struct sk_buff *skb;
struct adapter *adap = container_of(t, struct adapter, tids);
struct sk_buff *skb;

WARN_ON(tid >= t->ntids);
WARN_ON(tid_out_of_range(&adap->tids, tid));

if (t->tid_tab[tid]) {
t->tid_tab[tid] = NULL;
if (t->tid_tab[tid - adap->tids.tid_base]) {
t->tid_tab[tid - adap->tids.tid_base] = NULL;
atomic_dec(&t->conns_in_use);
if (t->hash_base && (tid >= t->hash_base)) {
if (family == AF_INET6)
Expand Down Expand Up @@ -4727,6 +4727,9 @@ static int adap_init0(struct adapter *adap, int vpd_skip)
adap->rawf_start = val[0];
adap->rawf_cnt = val[1] - val[0] + 1;
}

adap->tids.tid_base =
t4_read_reg(adap, LE_DB_ACTIVE_TABLE_START_INDEX_A);
}

/* qids (ingress/egress) returned from firmware can be anywhere
Expand Down
9 changes: 8 additions & 1 deletion drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ struct eotid_entry {
*/
struct tid_info {
void **tid_tab;
unsigned int tid_base;
unsigned int ntids;

struct serv_entry *stid_tab;
Expand Down Expand Up @@ -152,9 +153,15 @@ struct tid_info {

static inline void *lookup_tid(const struct tid_info *t, unsigned int tid)
{
tid -= t->tid_base;
return tid < t->ntids ? t->tid_tab[tid] : NULL;
}

static inline bool tid_out_of_range(const struct tid_info *t, unsigned int tid)
{
return ((tid - t->tid_base) >= t->ntids);
}

static inline void *lookup_atid(const struct tid_info *t, unsigned int atid)
{
return atid < t->natids ? t->atid_tab[atid].data : NULL;
Expand All @@ -176,7 +183,7 @@ static inline void *lookup_stid(const struct tid_info *t, unsigned int stid)
static inline void cxgb4_insert_tid(struct tid_info *t, void *data,
unsigned int tid, unsigned short family)
{
t->tid_tab[tid] = data;
t->tid_tab[tid - t->tid_base] = data;
if (t->hash_base && (tid >= t->hash_base)) {
if (family == AF_INET6)
atomic_add(2, &t->hash_tids_in_use);
Expand Down

0 comments on commit 59437d7

Please sign in to comment.