From ceaea6d8e5412322f588d0013b59be3d3382f483 Mon Sep 17 00:00:00 2001 From: Shagun Agrawal Date: Fri, 29 Jun 2018 23:42:21 +0530 Subject: [PATCH] net/cxgbe: query hit counters for flows in HASH region Add interface to enable hit counters for flows offloaded in HASH region. Signed-off-by: Shagun Agrawal Signed-off-by: Rahul Lakkireddy --- drivers/net/cxgbe/base/t4_tcb.h | 11 +++++ drivers/net/cxgbe/cxgbe_filter.c | 71 +++++++++++++++++++++++++++++--- drivers/net/cxgbe/cxgbe_filter.h | 2 +- drivers/net/cxgbe/cxgbe_flow.c | 5 ++- 4 files changed, 81 insertions(+), 8 deletions(-) diff --git a/drivers/net/cxgbe/base/t4_tcb.h b/drivers/net/cxgbe/base/t4_tcb.h index 6d7f5e8c19..25435f9f44 100644 --- a/drivers/net/cxgbe/base/t4_tcb.h +++ b/drivers/net/cxgbe/base/t4_tcb.h @@ -12,4 +12,15 @@ #define M_TCB_RSS_INFO 0x3ffULL #define V_TCB_RSS_INFO(x) ((x) << S_TCB_RSS_INFO) +/* 191:160 */ +#define W_TCB_TIMESTAMP 5 +#define S_TCB_TIMESTAMP 0 +#define M_TCB_TIMESTAMP 0xffffffffULL +#define V_TCB_TIMESTAMP(x) ((x) << S_TCB_TIMESTAMP) + +/* 223:192 */ +#define S_TCB_T_RTT_TS_RECENT_AGE 0 +#define M_TCB_T_RTT_TS_RECENT_AGE 0xffffffffULL +#define V_TCB_T_RTT_TS_RECENT_AGE(x) ((x) << S_TCB_T_RTT_TS_RECENT_AGE) + #endif /* _T4_TCB_DEFS_H */ diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c index 7759b8acf7..ff43488b5c 100644 --- a/drivers/net/cxgbe/cxgbe_filter.c +++ b/drivers/net/cxgbe/cxgbe_filter.c @@ -117,6 +117,36 @@ int writable_filter(struct filter_entry *f) return 0; } +/** + * Send CPL_SET_TCB_FIELD message + */ +static void set_tcb_field(struct adapter *adapter, unsigned int ftid, + u16 word, u64 mask, u64 val, int no_reply) +{ + struct rte_mbuf *mbuf; + struct cpl_set_tcb_field *req; + struct sge_ctrl_txq *ctrlq; + + ctrlq = &adapter->sge.ctrlq[0]; + mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool); + WARN_ON(!mbuf); + + mbuf->data_len = sizeof(*req); + mbuf->pkt_len = mbuf->data_len; + + req = rte_pktmbuf_mtod(mbuf, struct cpl_set_tcb_field *); + memset(req, 0, sizeof(*req)); + INIT_TP_WR_MIT_CPL(req, CPL_SET_TCB_FIELD, ftid); + req->reply_ctrl = cpu_to_be16(V_REPLY_CHAN(0) | + V_QUEUENO(adapter->sge.fw_evtq.abs_id) | + V_NO_REPLY(no_reply)); + req->word_cookie = cpu_to_be16(V_WORD(word) | V_COOKIE(ftid)); + req->mask = cpu_to_be64(mask); + req->val = cpu_to_be64(val); + + t4_mgmt_tx(ctrlq, mbuf); +} + /** * Build a CPL_SET_TCB_FIELD message as payload of a ULP_TX_PKT command. */ @@ -978,6 +1008,15 @@ void hash_filter_rpl(struct adapter *adap, const struct cpl_act_open_rpl *rpl) ctx->tid = f->tid; ctx->result = 0; } + if (f->fs.hitcnts) + set_tcb_field(adap, tid, + W_TCB_TIMESTAMP, + V_TCB_TIMESTAMP(M_TCB_TIMESTAMP) | + V_TCB_T_RTT_TS_RECENT_AGE + (M_TCB_T_RTT_TS_RECENT_AGE), + V_TCB_TIMESTAMP(0ULL) | + V_TCB_T_RTT_TS_RECENT_AGE(0ULL), + 1); break; } default: @@ -1068,22 +1107,44 @@ void filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl) * Retrieve the packet count for the specified filter. */ int cxgbe_get_filter_count(struct adapter *adapter, unsigned int fidx, - u64 *c, bool get_byte) + u64 *c, int hash, bool get_byte) { struct filter_entry *f; unsigned int tcb_base, tcbaddr; int ret; tcb_base = t4_read_reg(adapter, A_TP_CMM_TCB_BASE); - if (fidx >= adapter->tids.nftids) - return -ERANGE; + if (is_hashfilter(adapter) && hash) { + if (fidx < adapter->tids.ntids) { + f = adapter->tids.tid_tab[fidx]; + if (!f) + return -EINVAL; + + if (is_t5(adapter->params.chip)) { + *c = 0; + return 0; + } + tcbaddr = tcb_base + (fidx * TCB_SIZE); + goto get_count; + } else { + return -ERANGE; + } + } else { + if (fidx >= adapter->tids.nftids) + return -ERANGE; + + f = &adapter->tids.ftid_tab[fidx]; + if (!f->valid) + return -EINVAL; + + tcbaddr = tcb_base + f->tid * TCB_SIZE; + } f = &adapter->tids.ftid_tab[fidx]; if (!f->valid) return -EINVAL; - tcbaddr = tcb_base + f->tid * TCB_SIZE; - +get_count: if (is_t5(adapter->params.chip) || is_t6(adapter->params.chip)) { /* * For T5, the Filter Packet Hit Count is maintained as a diff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h index c51efea7d0..fac1f75f98 100644 --- a/drivers/net/cxgbe/cxgbe_filter.h +++ b/drivers/net/cxgbe/cxgbe_filter.h @@ -228,5 +228,5 @@ void hash_del_filter_rpl(struct adapter *adap, const struct cpl_abort_rpl_rss *rpl); 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); + u64 *c, int hash, bool get_byte); #endif /* _CXGBE_FILTER_H_ */ diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c index 4950cb41ca..48df62affe 100644 --- a/drivers/net/cxgbe/cxgbe_flow.c +++ b/drivers/net/cxgbe/cxgbe_flow.c @@ -591,13 +591,14 @@ static int __cxgbe_flow_query(struct rte_flow *flow, u64 *count, u64 *byte_count) { struct adapter *adap = ethdev2adap(flow->dev); + struct ch_filter_specification fs = flow->f->fs; unsigned int fidx = flow->fidx; int ret = 0; - ret = cxgbe_get_filter_count(adap, fidx, count, 0); + ret = cxgbe_get_filter_count(adap, fidx, count, fs.cap, 0); if (ret) return ret; - return cxgbe_get_filter_count(adap, fidx, byte_count, 1); + return cxgbe_get_filter_count(adap, fidx, byte_count, fs.cap, 1); } static int