d26be3cd7bead25e08cf507760cc85295046640d
[dpdk.git] / drivers / net / cxgbe / cxgbe_filter.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Chelsio Communications.
3  * All rights reserved.
4  */
5 #include <rte_net.h>
6
7 #include "base/common.h"
8 #include "base/t4_tcb.h"
9 #include "base/t4_regs.h"
10 #include "cxgbe_filter.h"
11 #include "clip_tbl.h"
12 #include "l2t.h"
13
14 /**
15  * Initialize Hash Filters
16  */
17 int cxgbe_init_hash_filter(struct adapter *adap)
18 {
19         unsigned int n_user_filters;
20         unsigned int user_filter_perc;
21         int ret;
22         u32 params[7], val[7];
23
24 #define FW_PARAM_DEV(param) \
25         (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \
26         V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param))
27
28 #define FW_PARAM_PFVF(param) \
29         (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \
30         V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param) |  \
31         V_FW_PARAMS_PARAM_Y(0) | \
32         V_FW_PARAMS_PARAM_Z(0))
33
34         params[0] = FW_PARAM_DEV(NTID);
35         ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
36                               params, val);
37         if (ret < 0)
38                 return ret;
39         adap->tids.ntids = val[0];
40         adap->tids.natids = min(adap->tids.ntids / 2, MAX_ATIDS);
41
42         user_filter_perc = 100;
43         n_user_filters = mult_frac(adap->tids.nftids,
44                                    user_filter_perc,
45                                    100);
46
47         adap->tids.nftids = n_user_filters;
48         adap->params.hash_filter = 1;
49         return 0;
50 }
51
52 /**
53  * Validate if the requested filter specification can be set by checking
54  * if the requested features have been enabled
55  */
56 int cxgbe_validate_filter(struct adapter *adapter,
57                           struct ch_filter_specification *fs)
58 {
59         u32 fconf, iconf;
60
61         /*
62          * Check for unconfigured fields being used.
63          */
64         fconf = adapter->params.tp.vlan_pri_map;
65
66         iconf = adapter->params.tp.ingress_config;
67
68 #define S(_field) \
69         (fs->val._field || fs->mask._field)
70 #define U(_mask, _field) \
71         (!(fconf & (_mask)) && S(_field))
72
73         if (U(F_PORT, iport) || U(F_ETHERTYPE, ethtype) ||
74             U(F_PROTOCOL, proto) || U(F_MACMATCH, macidx) ||
75             U(F_VLAN, ivlan_vld) || U(F_VNIC_ID, ovlan_vld))
76                 return -EOPNOTSUPP;
77
78         /* Ensure OVLAN match is enabled in hardware */
79         if (S(ovlan_vld) && (iconf & F_VNIC))
80                 return -EOPNOTSUPP;
81
82         /* To use OVLAN, L4 encapsulation match must not be enabled */
83         if (S(ovlan_vld) && (iconf & F_USE_ENC_IDX))
84                 return -EOPNOTSUPP;
85
86 #undef S
87 #undef U
88
89         /*
90          * If the user is requesting that the filter action loop
91          * matching packets back out one of our ports, make sure that
92          * the egress port is in range.
93          */
94         if (fs->action == FILTER_SWITCH &&
95             fs->eport >= adapter->params.nports)
96                 return -ERANGE;
97
98         /*
99          * Don't allow various trivially obvious bogus out-of-range
100          * values ...
101          */
102         if (fs->val.iport >= adapter->params.nports)
103                 return -ERANGE;
104
105         if (!fs->cap && fs->nat_mode && !adapter->params.filter2_wr_support)
106                 return -EOPNOTSUPP;
107
108         if (!fs->cap && fs->swapmac && !adapter->params.filter2_wr_support)
109                 return -EOPNOTSUPP;
110
111         return 0;
112 }
113
114 /**
115  * Get the queue to which the traffic must be steered to.
116  */
117 static unsigned int get_filter_steerq(struct rte_eth_dev *dev,
118                                       struct ch_filter_specification *fs)
119 {
120         struct port_info *pi = ethdev2pinfo(dev);
121         struct adapter *adapter = pi->adapter;
122         unsigned int iq;
123
124         /*
125          * If the user has requested steering matching Ingress Packets
126          * to a specific Queue Set, we need to make sure it's in range
127          * for the port and map that into the Absolute Queue ID of the
128          * Queue Set's Response Queue.
129          */
130         if (!fs->dirsteer) {
131                 iq = 0;
132         } else {
133                 /*
134                  * If the iq id is greater than the number of qsets,
135                  * then assume it is an absolute qid.
136                  */
137                 if (fs->iq < pi->n_rx_qsets)
138                         iq = adapter->sge.ethrxq[pi->first_qset +
139                                                  fs->iq].rspq.abs_id;
140                 else
141                         iq = fs->iq;
142         }
143
144         return iq;
145 }
146
147 /* Return an error number if the indicated filter isn't writable ... */
148 static int writable_filter(struct filter_entry *f)
149 {
150         if (f->locked)
151                 return -EPERM;
152         if (f->pending)
153                 return -EBUSY;
154
155         return 0;
156 }
157
158 /**
159  * Send CPL_SET_TCB_FIELD message
160  */
161 static void set_tcb_field(struct adapter *adapter, unsigned int ftid,
162                           u16 word, u64 mask, u64 val, int no_reply)
163 {
164         struct rte_mbuf *mbuf;
165         struct cpl_set_tcb_field *req;
166         struct sge_ctrl_txq *ctrlq;
167
168         ctrlq = &adapter->sge.ctrlq[0];
169         mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
170         WARN_ON(!mbuf);
171
172         mbuf->data_len = sizeof(*req);
173         mbuf->pkt_len = mbuf->data_len;
174
175         req = rte_pktmbuf_mtod(mbuf, struct cpl_set_tcb_field *);
176         memset(req, 0, sizeof(*req));
177         INIT_TP_WR_MIT_CPL(req, CPL_SET_TCB_FIELD, ftid);
178         req->reply_ctrl = cpu_to_be16(V_REPLY_CHAN(0) |
179                                       V_QUEUENO(adapter->sge.fw_evtq.abs_id) |
180                                       V_NO_REPLY(no_reply));
181         req->word_cookie = cpu_to_be16(V_WORD(word) | V_COOKIE(ftid));
182         req->mask = cpu_to_be64(mask);
183         req->val = cpu_to_be64(val);
184
185         t4_mgmt_tx(ctrlq, mbuf);
186 }
187
188 /**
189  * Set one of the t_flags bits in the TCB.
190  */
191 static void set_tcb_tflag(struct adapter *adap, unsigned int ftid,
192                           unsigned int bit_pos, unsigned int val, int no_reply)
193 {
194         set_tcb_field(adap, ftid,  W_TCB_T_FLAGS, 1ULL << bit_pos,
195                       (unsigned long long)val << bit_pos, no_reply);
196 }
197
198 /**
199  * Build a CPL_SET_TCB_FIELD message as payload of a ULP_TX_PKT command.
200  */
201 static inline void mk_set_tcb_field_ulp(struct filter_entry *f,
202                                         struct cpl_set_tcb_field *req,
203                                         unsigned int word,
204                                         u64 mask, u64 val, u8 cookie,
205                                         int no_reply)
206 {
207         struct ulp_txpkt *txpkt = (struct ulp_txpkt *)req;
208         struct ulptx_idata *sc = (struct ulptx_idata *)(txpkt + 1);
209
210         txpkt->cmd_dest = cpu_to_be32(V_ULPTX_CMD(ULP_TX_PKT) |
211                                       V_ULP_TXPKT_DEST(0));
212         txpkt->len = cpu_to_be32(DIV_ROUND_UP(sizeof(*req), 16));
213         sc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_IMM));
214         sc->len = cpu_to_be32(sizeof(*req) - sizeof(struct work_request_hdr));
215         OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_SET_TCB_FIELD, f->tid));
216         req->reply_ctrl = cpu_to_be16(V_NO_REPLY(no_reply) | V_REPLY_CHAN(0) |
217                                       V_QUEUENO(0));
218         req->word_cookie = cpu_to_be16(V_WORD(word) | V_COOKIE(cookie));
219         req->mask = cpu_to_be64(mask);
220         req->val = cpu_to_be64(val);
221         sc = (struct ulptx_idata *)(req + 1);
222         sc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_NOOP));
223         sc->len = cpu_to_be32(0);
224 }
225
226 /**
227  * IPv6 requires 2 slots on T6 and 4 slots for cards below T6.
228  * IPv4 requires only 1 slot on all cards.
229  */
230 u8 cxgbe_filter_slots(struct adapter *adap, u8 family)
231 {
232         if (family == FILTER_TYPE_IPV6) {
233                 if (CHELSIO_CHIP_VERSION(adap->params.chip) < CHELSIO_T6)
234                         return 4;
235
236                 return 2;
237         }
238
239         return 1;
240 }
241
242 /**
243  * Check if entries are already filled.
244  */
245 bool cxgbe_is_filter_set(struct tid_info *t, u32 fidx, u8 nentries)
246 {
247         bool result = FALSE;
248         u32 i;
249
250         /* Ensure there's enough slots available. */
251         t4_os_lock(&t->ftid_lock);
252         for (i = fidx; i < fidx + nentries; i++) {
253                 if (rte_bitmap_get(t->ftid_bmap, i)) {
254                         result = TRUE;
255                         break;
256                 }
257         }
258         t4_os_unlock(&t->ftid_lock);
259         return result;
260 }
261
262 /**
263  * Allocate available free entries.
264  */
265 int cxgbe_alloc_ftid(struct adapter *adap, u8 nentries)
266 {
267         struct tid_info *t = &adap->tids;
268         int pos;
269         int size = t->nftids;
270
271         t4_os_lock(&t->ftid_lock);
272         if (nentries > 1)
273                 pos = cxgbe_bitmap_find_free_region(t->ftid_bmap, size,
274                                                     nentries);
275         else
276                 pos = cxgbe_find_first_zero_bit(t->ftid_bmap, size);
277         t4_os_unlock(&t->ftid_lock);
278
279         return pos < size ? pos : -1;
280 }
281
282 /**
283  * Construct hash filter ntuple.
284  */
285 static u64 hash_filter_ntuple(const struct filter_entry *f)
286 {
287         struct adapter *adap = ethdev2adap(f->dev);
288         struct tp_params *tp = &adap->params.tp;
289         u64 ntuple = 0;
290         u16 tcp_proto = IPPROTO_TCP; /* TCP Protocol Number */
291
292         if (tp->port_shift >= 0 && f->fs.mask.iport)
293                 ntuple |= (u64)f->fs.val.iport << tp->port_shift;
294
295         if (tp->protocol_shift >= 0) {
296                 if (!f->fs.val.proto)
297                         ntuple |= (u64)tcp_proto << tp->protocol_shift;
298                 else
299                         ntuple |= (u64)f->fs.val.proto << tp->protocol_shift;
300         }
301
302         if (tp->ethertype_shift >= 0 && f->fs.mask.ethtype)
303                 ntuple |= (u64)(f->fs.val.ethtype) << tp->ethertype_shift;
304         if (tp->macmatch_shift >= 0 && f->fs.mask.macidx)
305                 ntuple |= (u64)(f->fs.val.macidx) << tp->macmatch_shift;
306         if (tp->vlan_shift >= 0 && f->fs.mask.ivlan)
307                 ntuple |= (u64)(F_FT_VLAN_VLD | f->fs.val.ivlan) <<
308                           tp->vlan_shift;
309         if (tp->vnic_shift >= 0) {
310                 if (!(adap->params.tp.ingress_config & F_VNIC) &&
311                     f->fs.mask.ovlan_vld)
312                         ntuple |= (u64)(f->fs.val.ovlan_vld << 16 |
313                                         f->fs.val.ovlan) << tp->vnic_shift;
314         }
315
316         return ntuple;
317 }
318
319 /**
320  * Build a CPL_ABORT_REQ message as payload of a ULP_TX_PKT command.
321  */
322 static void mk_abort_req_ulp(struct cpl_abort_req *abort_req,
323                              unsigned int tid)
324 {
325         struct ulp_txpkt *txpkt = (struct ulp_txpkt *)abort_req;
326         struct ulptx_idata *sc = (struct ulptx_idata *)(txpkt + 1);
327
328         txpkt->cmd_dest = cpu_to_be32(V_ULPTX_CMD(ULP_TX_PKT) |
329                                       V_ULP_TXPKT_DEST(0));
330         txpkt->len = cpu_to_be32(DIV_ROUND_UP(sizeof(*abort_req), 16));
331         sc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_IMM));
332         sc->len = cpu_to_be32(sizeof(*abort_req) -
333                               sizeof(struct work_request_hdr));
334         OPCODE_TID(abort_req) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_REQ, tid));
335         abort_req->rsvd0 = cpu_to_be32(0);
336         abort_req->rsvd1 = 0;
337         abort_req->cmd = CPL_ABORT_NO_RST;
338         sc = (struct ulptx_idata *)(abort_req + 1);
339         sc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_NOOP));
340         sc->len = cpu_to_be32(0);
341 }
342
343 /**
344  * Build a CPL_ABORT_RPL message as payload of a ULP_TX_PKT command.
345  */
346 static void mk_abort_rpl_ulp(struct cpl_abort_rpl *abort_rpl,
347                              unsigned int tid)
348 {
349         struct ulp_txpkt *txpkt = (struct ulp_txpkt *)abort_rpl;
350         struct ulptx_idata *sc = (struct ulptx_idata *)(txpkt + 1);
351
352         txpkt->cmd_dest = cpu_to_be32(V_ULPTX_CMD(ULP_TX_PKT) |
353                                       V_ULP_TXPKT_DEST(0));
354         txpkt->len = cpu_to_be32(DIV_ROUND_UP(sizeof(*abort_rpl), 16));
355         sc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_IMM));
356         sc->len = cpu_to_be32(sizeof(*abort_rpl) -
357                               sizeof(struct work_request_hdr));
358         OPCODE_TID(abort_rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_RPL, tid));
359         abort_rpl->rsvd0 = cpu_to_be32(0);
360         abort_rpl->rsvd1 = 0;
361         abort_rpl->cmd = CPL_ABORT_NO_RST;
362         sc = (struct ulptx_idata *)(abort_rpl + 1);
363         sc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_NOOP));
364         sc->len = cpu_to_be32(0);
365 }
366
367 /**
368  * Delete the specified hash filter.
369  */
370 static int cxgbe_del_hash_filter(struct rte_eth_dev *dev,
371                                  unsigned int filter_id,
372                                  struct filter_ctx *ctx)
373 {
374         struct adapter *adapter = ethdev2adap(dev);
375         struct tid_info *t = &adapter->tids;
376         struct filter_entry *f;
377         struct sge_ctrl_txq *ctrlq;
378         unsigned int port_id = ethdev2pinfo(dev)->port_id;
379         int ret;
380
381         if (filter_id > adapter->tids.ntids)
382                 return -E2BIG;
383
384         f = lookup_tid(t, filter_id);
385         if (!f) {
386                 dev_err(adapter, "%s: no filter entry for filter_id = %d\n",
387                         __func__, filter_id);
388                 return -EINVAL;
389         }
390
391         ret = writable_filter(f);
392         if (ret)
393                 return ret;
394
395         if (f->valid) {
396                 unsigned int wrlen;
397                 struct rte_mbuf *mbuf;
398                 struct work_request_hdr *wr;
399                 struct ulptx_idata *aligner;
400                 struct cpl_set_tcb_field *req;
401                 struct cpl_abort_req *abort_req;
402                 struct cpl_abort_rpl *abort_rpl;
403
404                 f->ctx = ctx;
405                 f->pending = 1;
406
407                 wrlen = cxgbe_roundup(sizeof(*wr) +
408                                       (sizeof(*req) + sizeof(*aligner)) +
409                                       sizeof(*abort_req) + sizeof(*abort_rpl),
410                                       16);
411
412                 ctrlq = &adapter->sge.ctrlq[port_id];
413                 mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
414                 if (!mbuf) {
415                         dev_err(adapter, "%s: could not allocate skb ..\n",
416                                 __func__);
417                         goto out_err;
418                 }
419
420                 mbuf->data_len = wrlen;
421                 mbuf->pkt_len = mbuf->data_len;
422
423                 req = rte_pktmbuf_mtod(mbuf, struct cpl_set_tcb_field *);
424                 INIT_ULPTX_WR(req, wrlen, 0, 0);
425                 wr = (struct work_request_hdr *)req;
426                 wr++;
427                 req = (struct cpl_set_tcb_field *)wr;
428                 mk_set_tcb_field_ulp(f, req, W_TCB_RSS_INFO,
429                                 V_TCB_RSS_INFO(M_TCB_RSS_INFO),
430                                 V_TCB_RSS_INFO(adapter->sge.fw_evtq.abs_id),
431                                 0, 1);
432                 aligner = (struct ulptx_idata *)(req + 1);
433                 abort_req = (struct cpl_abort_req *)(aligner + 1);
434                 mk_abort_req_ulp(abort_req, f->tid);
435                 abort_rpl = (struct cpl_abort_rpl *)(abort_req + 1);
436                 mk_abort_rpl_ulp(abort_rpl, f->tid);
437                 t4_mgmt_tx(ctrlq, mbuf);
438         }
439         return 0;
440
441 out_err:
442         return -ENOMEM;
443 }
444
445 /**
446  * Build a ACT_OPEN_REQ6 message for setting IPv6 hash filter.
447  */
448 static void mk_act_open_req6(struct filter_entry *f, struct rte_mbuf *mbuf,
449                              unsigned int qid_filterid, struct adapter *adap)
450 {
451         struct cpl_t6_act_open_req6 *req = NULL;
452         u64 local_lo, local_hi, peer_lo, peer_hi;
453         u32 *lip = (u32 *)f->fs.val.lip;
454         u32 *fip = (u32 *)f->fs.val.fip;
455
456         switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
457         case CHELSIO_T6:
458                 req = rte_pktmbuf_mtod(mbuf, struct cpl_t6_act_open_req6 *);
459
460                 INIT_TP_WR(req, 0);
461                 break;
462         default:
463                 dev_err(adap, "%s: unsupported chip type!\n", __func__);
464                 return;
465         }
466
467         local_hi = ((u64)lip[1]) << 32 | lip[0];
468         local_lo = ((u64)lip[3]) << 32 | lip[2];
469         peer_hi = ((u64)fip[1]) << 32 | fip[0];
470         peer_lo = ((u64)fip[3]) << 32 | fip[2];
471
472         OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ6,
473                                                     qid_filterid));
474         req->local_port = cpu_to_be16(f->fs.val.lport);
475         req->peer_port = cpu_to_be16(f->fs.val.fport);
476         req->local_ip_hi = local_hi;
477         req->local_ip_lo = local_lo;
478         req->peer_ip_hi = peer_hi;
479         req->peer_ip_lo = peer_lo;
480         req->opt0 = cpu_to_be64(V_NAGLE(f->fs.newvlan == VLAN_REMOVE ||
481                                         f->fs.newvlan == VLAN_REWRITE) |
482                                 V_DELACK(f->fs.hitcnts) |
483                                 V_L2T_IDX(f->l2t ? f->l2t->idx : 0) |
484                                 V_SMAC_SEL((cxgbe_port_viid(f->dev) & 0x7F)
485                                            << 1) |
486                                 V_TX_CHAN(f->fs.eport) |
487                                 V_ULP_MODE(ULP_MODE_NONE) |
488                                 F_TCAM_BYPASS | F_NON_OFFLOAD);
489         req->params = cpu_to_be64(V_FILTER_TUPLE(hash_filter_ntuple(f)));
490         req->opt2 = cpu_to_be32(F_RSS_QUEUE_VALID |
491                             V_RSS_QUEUE(f->fs.iq) |
492                             F_T5_OPT_2_VALID |
493                             F_RX_CHANNEL |
494                             V_SACK_EN(f->fs.swapmac) |
495                             V_CONG_CNTRL((f->fs.action == FILTER_DROP) |
496                                          (f->fs.dirsteer << 1)) |
497                             V_CCTRL_ECN(f->fs.action == FILTER_SWITCH));
498 }
499
500 /**
501  * Build a ACT_OPEN_REQ message for setting IPv4 hash filter.
502  */
503 static void mk_act_open_req(struct filter_entry *f, struct rte_mbuf *mbuf,
504                             unsigned int qid_filterid, struct adapter *adap)
505 {
506         struct cpl_t6_act_open_req *req = NULL;
507
508         switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
509         case CHELSIO_T6:
510                 req = rte_pktmbuf_mtod(mbuf, struct cpl_t6_act_open_req *);
511
512                 INIT_TP_WR(req, 0);
513                 break;
514         default:
515                 dev_err(adap, "%s: unsupported chip type!\n", __func__);
516                 return;
517         }
518
519         OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
520                                                     qid_filterid));
521         req->local_port = cpu_to_be16(f->fs.val.lport);
522         req->peer_port = cpu_to_be16(f->fs.val.fport);
523         req->local_ip = f->fs.val.lip[0] | f->fs.val.lip[1] << 8 |
524                         f->fs.val.lip[2] << 16 | f->fs.val.lip[3] << 24;
525         req->peer_ip = f->fs.val.fip[0] | f->fs.val.fip[1] << 8 |
526                         f->fs.val.fip[2] << 16 | f->fs.val.fip[3] << 24;
527         req->opt0 = cpu_to_be64(V_NAGLE(f->fs.newvlan == VLAN_REMOVE ||
528                                         f->fs.newvlan == VLAN_REWRITE) |
529                                 V_DELACK(f->fs.hitcnts) |
530                                 V_L2T_IDX(f->l2t ? f->l2t->idx : 0) |
531                                 V_SMAC_SEL((cxgbe_port_viid(f->dev) & 0x7F)
532                                            << 1) |
533                                 V_TX_CHAN(f->fs.eport) |
534                                 V_ULP_MODE(ULP_MODE_NONE) |
535                                 F_TCAM_BYPASS | F_NON_OFFLOAD);
536         req->params = cpu_to_be64(V_FILTER_TUPLE(hash_filter_ntuple(f)));
537         req->opt2 = cpu_to_be32(F_RSS_QUEUE_VALID |
538                             V_RSS_QUEUE(f->fs.iq) |
539                             F_T5_OPT_2_VALID |
540                             F_RX_CHANNEL |
541                             V_SACK_EN(f->fs.swapmac) |
542                             V_CONG_CNTRL((f->fs.action == FILTER_DROP) |
543                                          (f->fs.dirsteer << 1)) |
544                             V_CCTRL_ECN(f->fs.action == FILTER_SWITCH));
545 }
546
547 /**
548  * Set the specified hash filter.
549  */
550 static int cxgbe_set_hash_filter(struct rte_eth_dev *dev,
551                                  struct ch_filter_specification *fs,
552                                  struct filter_ctx *ctx)
553 {
554         struct port_info *pi = ethdev2pinfo(dev);
555         struct adapter *adapter = pi->adapter;
556         struct tid_info *t = &adapter->tids;
557         struct filter_entry *f;
558         struct rte_mbuf *mbuf;
559         struct sge_ctrl_txq *ctrlq;
560         unsigned int iq;
561         int atid, size;
562         int ret = 0;
563
564         ret = cxgbe_validate_filter(adapter, fs);
565         if (ret)
566                 return ret;
567
568         iq = get_filter_steerq(dev, fs);
569
570         ctrlq = &adapter->sge.ctrlq[pi->port_id];
571
572         f = t4_os_alloc(sizeof(*f));
573         if (!f)
574                 goto out_err;
575
576         f->fs = *fs;
577         f->ctx = ctx;
578         f->dev = dev;
579         f->fs.iq = iq;
580
581         /*
582          * If the new filter requires loopback Destination MAC and/or VLAN
583          * rewriting then we need to allocate a Layer 2 Table (L2T) entry for
584          * the filter.
585          */
586         if (f->fs.newvlan == VLAN_INSERT ||
587             f->fs.newvlan == VLAN_REWRITE) {
588                 /* allocate L2T entry for new filter */
589                 f->l2t = cxgbe_l2t_alloc_switching(dev, f->fs.vlan,
590                                                    f->fs.eport, f->fs.dmac);
591                 if (!f->l2t) {
592                         ret = -ENOMEM;
593                         goto out_err;
594                 }
595         }
596
597         atid = cxgbe_alloc_atid(t, f);
598         if (atid < 0)
599                 goto out_err;
600
601         if (f->fs.type == FILTER_TYPE_IPV6) {
602                 /* IPv6 hash filter */
603                 f->clipt = cxgbe_clip_alloc(f->dev, (u32 *)&f->fs.val.lip);
604                 if (!f->clipt)
605                         goto free_atid;
606
607                 size = sizeof(struct cpl_t6_act_open_req6);
608                 mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
609                 if (!mbuf) {
610                         ret = -ENOMEM;
611                         goto free_clip;
612                 }
613
614                 mbuf->data_len = size;
615                 mbuf->pkt_len = mbuf->data_len;
616
617                 mk_act_open_req6(f, mbuf,
618                                  ((adapter->sge.fw_evtq.abs_id << 14) | atid),
619                                  adapter);
620         } else {
621                 /* IPv4 hash filter */
622                 size = sizeof(struct cpl_t6_act_open_req);
623                 mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
624                 if (!mbuf) {
625                         ret = -ENOMEM;
626                         goto free_atid;
627                 }
628
629                 mbuf->data_len = size;
630                 mbuf->pkt_len = mbuf->data_len;
631
632                 mk_act_open_req(f, mbuf,
633                                 ((adapter->sge.fw_evtq.abs_id << 14) | atid),
634                                 adapter);
635         }
636
637         f->pending = 1;
638         t4_mgmt_tx(ctrlq, mbuf);
639         return 0;
640
641 free_clip:
642         cxgbe_clip_release(f->dev, f->clipt);
643 free_atid:
644         cxgbe_free_atid(t, atid);
645
646 out_err:
647         t4_os_free(f);
648         return ret;
649 }
650
651 /**
652  * Clear a filter and release any of its resources that we own.  This also
653  * clears the filter's "pending" status.
654  */
655 static void clear_filter(struct filter_entry *f)
656 {
657         if (f->clipt)
658                 cxgbe_clip_release(f->dev, f->clipt);
659
660         /*
661          * The zeroing of the filter rule below clears the filter valid,
662          * pending, locked flags etc. so it's all we need for
663          * this operation.
664          */
665         memset(f, 0, sizeof(*f));
666 }
667
668 /**
669  * t4_mk_filtdelwr - create a delete filter WR
670  * @adap: adapter context
671  * @ftid: the filter ID
672  * @wr: the filter work request to populate
673  * @qid: ingress queue to receive the delete notification
674  *
675  * Creates a filter work request to delete the supplied filter.  If @qid is
676  * negative the delete notification is suppressed.
677  */
678 static void t4_mk_filtdelwr(struct adapter *adap, unsigned int ftid,
679                             struct fw_filter2_wr *wr, int qid)
680 {
681         memset(wr, 0, sizeof(*wr));
682         if (adap->params.filter2_wr_support)
683                 wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER2_WR));
684         else
685                 wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
686         wr->len16_pkd = cpu_to_be32(V_FW_WR_LEN16(sizeof(*wr) / 16));
687         wr->tid_to_iq = cpu_to_be32(V_FW_FILTER_WR_TID(ftid) |
688                                     V_FW_FILTER_WR_NOREPLY(qid < 0));
689         wr->del_filter_to_l2tix = cpu_to_be32(F_FW_FILTER_WR_DEL_FILTER);
690         if (qid >= 0)
691                 wr->rx_chan_rx_rpl_iq =
692                                 cpu_to_be16(V_FW_FILTER_WR_RX_RPL_IQ(qid));
693 }
694
695 /**
696  * Create FW work request to delete the filter at a specified index
697  */
698 static int del_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
699 {
700         struct adapter *adapter = ethdev2adap(dev);
701         struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
702         struct rte_mbuf *mbuf;
703         struct fw_filter2_wr *fwr;
704         struct sge_ctrl_txq *ctrlq;
705         unsigned int port_id = ethdev2pinfo(dev)->port_id;
706
707         ctrlq = &adapter->sge.ctrlq[port_id];
708         mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
709         if (!mbuf)
710                 return -ENOMEM;
711
712         mbuf->data_len = sizeof(*fwr);
713         mbuf->pkt_len = mbuf->data_len;
714
715         fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter2_wr *);
716         t4_mk_filtdelwr(adapter, f->tid, fwr, adapter->sge.fw_evtq.abs_id);
717
718         /*
719          * Mark the filter as "pending" and ship off the Filter Work Request.
720          * When we get the Work Request Reply we'll clear the pending status.
721          */
722         f->pending = 1;
723         t4_mgmt_tx(ctrlq, mbuf);
724         return 0;
725 }
726
727 static int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
728 {
729         struct adapter *adapter = ethdev2adap(dev);
730         struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
731         struct rte_mbuf *mbuf;
732         struct fw_filter2_wr *fwr;
733         struct sge_ctrl_txq *ctrlq;
734         unsigned int port_id = ethdev2pinfo(dev)->port_id;
735         int ret;
736
737         /*
738          * If the new filter requires loopback Destination MAC and/or VLAN
739          * rewriting then we need to allocate a Layer 2 Table (L2T) entry for
740          * the filter.
741          */
742         if (f->fs.newvlan) {
743                 /* allocate L2T entry for new filter */
744                 f->l2t = cxgbe_l2t_alloc_switching(f->dev, f->fs.vlan,
745                                                    f->fs.eport, f->fs.dmac);
746                 if (!f->l2t)
747                         return -ENOMEM;
748         }
749
750         ctrlq = &adapter->sge.ctrlq[port_id];
751         mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
752         if (!mbuf) {
753                 ret = -ENOMEM;
754                 goto out;
755         }
756
757         mbuf->data_len = sizeof(*fwr);
758         mbuf->pkt_len = mbuf->data_len;
759
760         fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter2_wr *);
761         memset(fwr, 0, sizeof(*fwr));
762
763         /*
764          * Construct the work request to set the filter.
765          */
766         if (adapter->params.filter2_wr_support)
767                 fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER2_WR));
768         else
769                 fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
770         fwr->len16_pkd = cpu_to_be32(V_FW_WR_LEN16(sizeof(*fwr) / 16));
771         fwr->tid_to_iq =
772                 cpu_to_be32(V_FW_FILTER_WR_TID(f->tid) |
773                             V_FW_FILTER_WR_RQTYPE(f->fs.type) |
774                             V_FW_FILTER_WR_NOREPLY(0) |
775                             V_FW_FILTER_WR_IQ(f->fs.iq));
776         fwr->del_filter_to_l2tix =
777                 cpu_to_be32(V_FW_FILTER_WR_DROP(f->fs.action == FILTER_DROP) |
778                             V_FW_FILTER_WR_DIRSTEER(f->fs.dirsteer) |
779                             V_FW_FILTER_WR_LPBK(f->fs.action == FILTER_SWITCH) |
780                             V_FW_FILTER_WR_INSVLAN
781                                 (f->fs.newvlan == VLAN_INSERT ||
782                                  f->fs.newvlan == VLAN_REWRITE) |
783                             V_FW_FILTER_WR_RMVLAN
784                                 (f->fs.newvlan == VLAN_REMOVE ||
785                                  f->fs.newvlan == VLAN_REWRITE) |
786                             V_FW_FILTER_WR_HITCNTS(f->fs.hitcnts) |
787                             V_FW_FILTER_WR_TXCHAN(f->fs.eport) |
788                             V_FW_FILTER_WR_PRIO(f->fs.prio) |
789                             V_FW_FILTER_WR_L2TIX(f->l2t ? f->l2t->idx : 0));
790         fwr->ethtype = cpu_to_be16(f->fs.val.ethtype);
791         fwr->ethtypem = cpu_to_be16(f->fs.mask.ethtype);
792         fwr->frag_to_ovlan_vldm =
793                 (V_FW_FILTER_WR_IVLAN_VLD(f->fs.val.ivlan_vld) |
794                  V_FW_FILTER_WR_IVLAN_VLDM(f->fs.mask.ivlan_vld) |
795                  V_FW_FILTER_WR_OVLAN_VLD(f->fs.val.ovlan_vld) |
796                  V_FW_FILTER_WR_OVLAN_VLDM(f->fs.mask.ovlan_vld));
797         fwr->smac_sel = 0;
798         fwr->rx_chan_rx_rpl_iq =
799                 cpu_to_be16(V_FW_FILTER_WR_RX_CHAN(0) |
800                             V_FW_FILTER_WR_RX_RPL_IQ(adapter->sge.fw_evtq.abs_id
801                                                      ));
802         fwr->maci_to_matchtypem =
803                 cpu_to_be32(V_FW_FILTER_WR_MACI(f->fs.val.macidx) |
804                             V_FW_FILTER_WR_MACIM(f->fs.mask.macidx) |
805                             V_FW_FILTER_WR_PORT(f->fs.val.iport) |
806                             V_FW_FILTER_WR_PORTM(f->fs.mask.iport));
807         fwr->ptcl = f->fs.val.proto;
808         fwr->ptclm = f->fs.mask.proto;
809         fwr->ivlan = cpu_to_be16(f->fs.val.ivlan);
810         fwr->ivlanm = cpu_to_be16(f->fs.mask.ivlan);
811         fwr->ovlan = cpu_to_be16(f->fs.val.ovlan);
812         fwr->ovlanm = cpu_to_be16(f->fs.mask.ovlan);
813         rte_memcpy(fwr->lip, f->fs.val.lip, sizeof(fwr->lip));
814         rte_memcpy(fwr->lipm, f->fs.mask.lip, sizeof(fwr->lipm));
815         rte_memcpy(fwr->fip, f->fs.val.fip, sizeof(fwr->fip));
816         rte_memcpy(fwr->fipm, f->fs.mask.fip, sizeof(fwr->fipm));
817         fwr->lp = cpu_to_be16(f->fs.val.lport);
818         fwr->lpm = cpu_to_be16(f->fs.mask.lport);
819         fwr->fp = cpu_to_be16(f->fs.val.fport);
820         fwr->fpm = cpu_to_be16(f->fs.mask.fport);
821
822         if (adapter->params.filter2_wr_support) {
823                 fwr->filter_type_swapmac =
824                          V_FW_FILTER2_WR_SWAPMAC(f->fs.swapmac);
825                 fwr->natmode_to_ulp_type =
826                         V_FW_FILTER2_WR_ULP_TYPE(f->fs.nat_mode ?
827                                                  ULP_MODE_TCPDDP :
828                                                  ULP_MODE_NONE) |
829                         V_FW_FILTER2_WR_NATMODE(f->fs.nat_mode);
830                 memcpy(fwr->newlip, f->fs.nat_lip, sizeof(fwr->newlip));
831                 memcpy(fwr->newfip, f->fs.nat_fip, sizeof(fwr->newfip));
832                 fwr->newlport = cpu_to_be16(f->fs.nat_lport);
833                 fwr->newfport = cpu_to_be16(f->fs.nat_fport);
834         }
835
836         /*
837          * Mark the filter as "pending" and ship off the Filter Work Request.
838          * When we get the Work Request Reply we'll clear the pending status.
839          */
840         f->pending = 1;
841         t4_mgmt_tx(ctrlq, mbuf);
842         return 0;
843
844 out:
845         return ret;
846 }
847
848 /**
849  * Set the corresponding entries in the bitmap.
850  */
851 static int cxgbe_set_ftid(struct tid_info *t, u32 fidx, u8 nentries)
852 {
853         u32 i;
854
855         t4_os_lock(&t->ftid_lock);
856         if (rte_bitmap_get(t->ftid_bmap, fidx)) {
857                 t4_os_unlock(&t->ftid_lock);
858                 return -EBUSY;
859         }
860
861         for (i = fidx; i < fidx + nentries; i++)
862                 rte_bitmap_set(t->ftid_bmap, i);
863         t4_os_unlock(&t->ftid_lock);
864         return 0;
865 }
866
867 /**
868  * Clear the corresponding entries in the bitmap.
869  */
870 static void cxgbe_clear_ftid(struct tid_info *t, u32 fidx, u8 nentries)
871 {
872         u32 i;
873
874         t4_os_lock(&t->ftid_lock);
875         for (i = fidx; i < fidx + nentries; i++)
876                 rte_bitmap_clear(t->ftid_bmap, i);
877         t4_os_unlock(&t->ftid_lock);
878 }
879
880 /**
881  * Check a delete filter request for validity and send it to the hardware.
882  * Return 0 on success, an error number otherwise.  We attach any provided
883  * filter operation context to the internal filter specification in order to
884  * facilitate signaling completion of the operation.
885  */
886 int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
887                      struct ch_filter_specification *fs,
888                      struct filter_ctx *ctx)
889 {
890         struct port_info *pi = dev->data->dev_private;
891         struct adapter *adapter = pi->adapter;
892         struct filter_entry *f;
893         unsigned int chip_ver;
894         u8 nentries;
895         int ret;
896
897         if (is_hashfilter(adapter) && fs->cap)
898                 return cxgbe_del_hash_filter(dev, filter_id, ctx);
899
900         if (filter_id >= adapter->tids.nftids)
901                 return -ERANGE;
902
903         chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
904
905         /*
906          * Ensure IPv6 filter id is aligned on the 2 slot boundary for T6,
907          * and 4 slot boundary for cards below T6.
908          */
909         if (fs->type == FILTER_TYPE_IPV6) {
910                 if (chip_ver < CHELSIO_T6)
911                         filter_id &= ~(0x3);
912                 else
913                         filter_id &= ~(0x1);
914         }
915
916         nentries = cxgbe_filter_slots(adapter, fs->type);
917         ret = cxgbe_is_filter_set(&adapter->tids, filter_id, nentries);
918         if (!ret) {
919                 dev_warn(adap, "%s: could not find filter entry: %u\n",
920                          __func__, filter_id);
921                 return -EINVAL;
922         }
923
924         f = &adapter->tids.ftid_tab[filter_id];
925         ret = writable_filter(f);
926         if (ret)
927                 return ret;
928
929         if (f->valid) {
930                 f->ctx = ctx;
931                 cxgbe_clear_ftid(&adapter->tids,
932                                  f->tid - adapter->tids.ftid_base,
933                                  nentries);
934                 return del_filter_wr(dev, filter_id);
935         }
936
937         /*
938          * If the caller has passed in a Completion Context then we need to
939          * mark it as a successful completion so they don't stall waiting
940          * for it.
941          */
942         if (ctx) {
943                 ctx->result = 0;
944                 t4_complete(&ctx->completion);
945         }
946
947         return 0;
948 }
949
950 /**
951  * Check a Chelsio Filter Request for validity, convert it into our internal
952  * format and send it to the hardware.  Return 0 on success, an error number
953  * otherwise.  We attach any provided filter operation context to the internal
954  * filter specification in order to facilitate signaling completion of the
955  * operation.
956  */
957 int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
958                      struct ch_filter_specification *fs,
959                      struct filter_ctx *ctx)
960 {
961         struct port_info *pi = ethdev2pinfo(dev);
962         struct adapter *adapter = pi->adapter;
963         unsigned int fidx, iq;
964         struct filter_entry *f;
965         unsigned int chip_ver;
966         u8 nentries, bitoff[16] = {0};
967         int ret;
968
969         if (is_hashfilter(adapter) && fs->cap)
970                 return cxgbe_set_hash_filter(dev, fs, ctx);
971
972         if (filter_id >= adapter->tids.nftids)
973                 return -ERANGE;
974
975         chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
976
977         ret = cxgbe_validate_filter(adapter, fs);
978         if (ret)
979                 return ret;
980
981         /*
982          * IPv6 filters occupy four slots and must be aligned on four-slot
983          * boundaries for T5. On T6, IPv6 filters occupy two-slots and
984          * must be aligned on two-slot boundaries.
985          *
986          * IPv4 filters only occupy a single slot and have no alignment
987          * requirements.
988          */
989         fidx = filter_id;
990         if (fs->type == FILTER_TYPE_IPV6) {
991                 if (chip_ver < CHELSIO_T6)
992                         fidx &= ~(0x3);
993                 else
994                         fidx &= ~(0x1);
995         }
996
997         if (fidx != filter_id)
998                 return -EINVAL;
999
1000         nentries = cxgbe_filter_slots(adapter, fs->type);
1001         ret = cxgbe_is_filter_set(&adapter->tids, filter_id, nentries);
1002         if (ret)
1003                 return -EBUSY;
1004
1005         iq = get_filter_steerq(dev, fs);
1006
1007         /*
1008          * Check to make sure that provided filter index is not
1009          * already in use by someone else
1010          */
1011         f = &adapter->tids.ftid_tab[filter_id];
1012         if (f->valid)
1013                 return -EBUSY;
1014
1015         fidx = adapter->tids.ftid_base + filter_id;
1016         ret = cxgbe_set_ftid(&adapter->tids, filter_id, nentries);
1017         if (ret)
1018                 return ret;
1019
1020         /*
1021          * Check to make sure the filter requested is writable ...
1022          */
1023         ret = writable_filter(f);
1024         if (ret) {
1025                 /* Clear the bits we have set above */
1026                 cxgbe_clear_ftid(&adapter->tids, filter_id, nentries);
1027                 return ret;
1028         }
1029
1030         /*
1031          * Allocate a clip table entry only if we have non-zero IPv6 address
1032          */
1033         if (chip_ver > CHELSIO_T5 && fs->type &&
1034             memcmp(fs->val.lip, bitoff, sizeof(bitoff))) {
1035                 f->clipt = cxgbe_clip_alloc(dev, (u32 *)&fs->val.lip);
1036                 if (!f->clipt)
1037                         goto free_tid;
1038         }
1039
1040         /*
1041          * Convert the filter specification into our internal format.
1042          * We copy the PF/VF specification into the Outer VLAN field
1043          * here so the rest of the code -- including the interface to
1044          * the firmware -- doesn't have to constantly do these checks.
1045          */
1046         f->fs = *fs;
1047         f->fs.iq = iq;
1048         f->dev = dev;
1049
1050         /*
1051          * Attempt to set the filter.  If we don't succeed, we clear
1052          * it and return the failure.
1053          */
1054         f->ctx = ctx;
1055         f->tid = fidx; /* Save the actual tid */
1056         ret = set_filter_wr(dev, filter_id);
1057         if (ret)
1058                 goto free_tid;
1059
1060         return ret;
1061
1062 free_tid:
1063         cxgbe_clear_ftid(&adapter->tids, filter_id, nentries);
1064         clear_filter(f);
1065         return ret;
1066 }
1067
1068 /**
1069  * Handle a Hash filter write reply.
1070  */
1071 void cxgbe_hash_filter_rpl(struct adapter *adap,
1072                            const struct cpl_act_open_rpl *rpl)
1073 {
1074         struct tid_info *t = &adap->tids;
1075         struct filter_entry *f;
1076         struct filter_ctx *ctx = NULL;
1077         unsigned int tid = GET_TID(rpl);
1078         unsigned int ftid = G_TID_TID(G_AOPEN_ATID
1079                                       (be32_to_cpu(rpl->atid_status)));
1080         unsigned int status  = G_AOPEN_STATUS(be32_to_cpu(rpl->atid_status));
1081
1082         f = lookup_atid(t, ftid);
1083         if (!f) {
1084                 dev_warn(adap, "%s: could not find filter entry: %d\n",
1085                          __func__, ftid);
1086                 return;
1087         }
1088
1089         ctx = f->ctx;
1090         f->ctx = NULL;
1091
1092         switch (status) {
1093         case CPL_ERR_NONE: {
1094                 f->tid = tid;
1095                 f->pending = 0;  /* asynchronous setup completed */
1096                 f->valid = 1;
1097
1098                 cxgbe_insert_tid(t, f, f->tid, 0);
1099                 cxgbe_free_atid(t, ftid);
1100                 if (ctx) {
1101                         ctx->tid = f->tid;
1102                         ctx->result = 0;
1103                 }
1104                 if (f->fs.hitcnts)
1105                         set_tcb_field(adap, tid,
1106                                       W_TCB_TIMESTAMP,
1107                                       V_TCB_TIMESTAMP(M_TCB_TIMESTAMP) |
1108                                       V_TCB_T_RTT_TS_RECENT_AGE
1109                                               (M_TCB_T_RTT_TS_RECENT_AGE),
1110                                       V_TCB_TIMESTAMP(0ULL) |
1111                                       V_TCB_T_RTT_TS_RECENT_AGE(0ULL),
1112                                       1);
1113                 if (f->fs.newvlan == VLAN_INSERT ||
1114                     f->fs.newvlan == VLAN_REWRITE)
1115                         set_tcb_tflag(adap, tid, S_TF_CCTRL_RFR, 1, 1);
1116                 break;
1117         }
1118         default:
1119                 dev_warn(adap, "%s: filter creation failed with status = %u\n",
1120                          __func__, status);
1121
1122                 if (ctx) {
1123                         if (status == CPL_ERR_TCAM_FULL)
1124                                 ctx->result = -EAGAIN;
1125                         else
1126                                 ctx->result = -EINVAL;
1127                 }
1128
1129                 cxgbe_free_atid(t, ftid);
1130                 t4_os_free(f);
1131         }
1132
1133         if (ctx)
1134                 t4_complete(&ctx->completion);
1135 }
1136
1137 /**
1138  * Handle a LE-TCAM filter write/deletion reply.
1139  */
1140 void cxgbe_filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl)
1141 {
1142         struct filter_entry *f = NULL;
1143         unsigned int tid = GET_TID(rpl);
1144         int idx, max_fidx = adap->tids.nftids;
1145
1146         /* Get the corresponding filter entry for this tid */
1147         if (adap->tids.ftid_tab) {
1148                 /* Check this in normal filter region */
1149                 idx = tid - adap->tids.ftid_base;
1150                 if (idx >= max_fidx)
1151                         return;
1152
1153                 f = &adap->tids.ftid_tab[idx];
1154                 if (f->tid != tid)
1155                         return;
1156         }
1157
1158         /* We found the filter entry for this tid */
1159         if (f) {
1160                 unsigned int ret = G_COOKIE(rpl->cookie);
1161                 struct filter_ctx *ctx;
1162
1163                 /*
1164                  * Pull off any filter operation context attached to the
1165                  * filter.
1166                  */
1167                 ctx = f->ctx;
1168                 f->ctx = NULL;
1169
1170                 if (ret == FW_FILTER_WR_FLT_ADDED) {
1171                         f->pending = 0;  /* asynchronous setup completed */
1172                         f->valid = 1;
1173                         if (ctx) {
1174                                 ctx->tid = f->tid;
1175                                 ctx->result = 0;
1176                         }
1177                 } else if (ret == FW_FILTER_WR_FLT_DELETED) {
1178                         /*
1179                          * Clear the filter when we get confirmation from the
1180                          * hardware that the filter has been deleted.
1181                          */
1182                         clear_filter(f);
1183                         if (ctx)
1184                                 ctx->result = 0;
1185                 } else {
1186                         /*
1187                          * Something went wrong.  Issue a warning about the
1188                          * problem and clear everything out.
1189                          */
1190                         dev_warn(adap, "filter %u setup failed with error %u\n",
1191                                  idx, ret);
1192                         clear_filter(f);
1193                         if (ctx)
1194                                 ctx->result = -EINVAL;
1195                 }
1196
1197                 if (ctx)
1198                         t4_complete(&ctx->completion);
1199         }
1200 }
1201
1202 /*
1203  * Retrieve the packet count for the specified filter.
1204  */
1205 int cxgbe_get_filter_count(struct adapter *adapter, unsigned int fidx,
1206                            u64 *c, int hash, bool get_byte)
1207 {
1208         struct filter_entry *f;
1209         unsigned int tcb_base, tcbaddr;
1210         int ret;
1211
1212         tcb_base = t4_read_reg(adapter, A_TP_CMM_TCB_BASE);
1213         if (is_hashfilter(adapter) && hash) {
1214                 if (fidx < adapter->tids.ntids) {
1215                         f = adapter->tids.tid_tab[fidx];
1216                         if (!f)
1217                                 return -EINVAL;
1218
1219                         if (is_t5(adapter->params.chip)) {
1220                                 *c = 0;
1221                                 return 0;
1222                         }
1223                         tcbaddr = tcb_base + (fidx * TCB_SIZE);
1224                         goto get_count;
1225                 } else {
1226                         return -ERANGE;
1227                 }
1228         } else {
1229                 if (fidx >= adapter->tids.nftids)
1230                         return -ERANGE;
1231
1232                 f = &adapter->tids.ftid_tab[fidx];
1233                 if (!f->valid)
1234                         return -EINVAL;
1235
1236                 tcbaddr = tcb_base + f->tid * TCB_SIZE;
1237         }
1238
1239         f = &adapter->tids.ftid_tab[fidx];
1240         if (!f->valid)
1241                 return -EINVAL;
1242
1243 get_count:
1244         if (is_t5(adapter->params.chip) || is_t6(adapter->params.chip)) {
1245                 /*
1246                  * For T5, the Filter Packet Hit Count is maintained as a
1247                  * 32-bit Big Endian value in the TCB field {timestamp}.
1248                  * Similar to the craziness above, instead of the filter hit
1249                  * count showing up at offset 20 ((W_TCB_TIMESTAMP == 5) *
1250                  * sizeof(u32)), it actually shows up at offset 24.  Whacky.
1251                  */
1252                 if (get_byte) {
1253                         unsigned int word_offset = 4;
1254                         __be64 be64_byte_count;
1255
1256                         t4_os_lock(&adapter->win0_lock);
1257                         ret = t4_memory_rw(adapter, MEMWIN_NIC, MEM_EDC0,
1258                                            tcbaddr +
1259                                            (word_offset * sizeof(__be32)),
1260                                            sizeof(be64_byte_count),
1261                                            &be64_byte_count,
1262                                            T4_MEMORY_READ);
1263                         t4_os_unlock(&adapter->win0_lock);
1264                         if (ret < 0)
1265                                 return ret;
1266                         *c = be64_to_cpu(be64_byte_count);
1267                 } else {
1268                         unsigned int word_offset = 6;
1269                         __be32 be32_count;
1270
1271                         t4_os_lock(&adapter->win0_lock);
1272                         ret = t4_memory_rw(adapter, MEMWIN_NIC, MEM_EDC0,
1273                                            tcbaddr +
1274                                            (word_offset * sizeof(__be32)),
1275                                            sizeof(be32_count), &be32_count,
1276                                            T4_MEMORY_READ);
1277                         t4_os_unlock(&adapter->win0_lock);
1278                         if (ret < 0)
1279                                 return ret;
1280                         *c = (u64)be32_to_cpu(be32_count);
1281                 }
1282         }
1283         return 0;
1284 }
1285
1286 /*
1287  * Clear the packet count for the specified filter.
1288  */
1289 int cxgbe_clear_filter_count(struct adapter *adapter, unsigned int fidx,
1290                              int hash, bool clear_byte)
1291 {
1292         u64 tcb_mask = 0, tcb_val = 0;
1293         struct filter_entry *f = NULL;
1294         u16 tcb_word = 0;
1295
1296         if (is_hashfilter(adapter) && hash) {
1297                 if (fidx >= adapter->tids.ntids)
1298                         return -ERANGE;
1299
1300                 /* No hitcounts supported for T5 hashfilters */
1301                 if (is_t5(adapter->params.chip))
1302                         return 0;
1303
1304                 f = adapter->tids.tid_tab[fidx];
1305         } else {
1306                 if (fidx >= adapter->tids.nftids)
1307                         return -ERANGE;
1308
1309                 f = &adapter->tids.ftid_tab[fidx];
1310         }
1311
1312         if (!f || !f->valid)
1313                 return -EINVAL;
1314
1315         tcb_word = W_TCB_TIMESTAMP;
1316         tcb_mask = V_TCB_TIMESTAMP(M_TCB_TIMESTAMP);
1317         tcb_val = V_TCB_TIMESTAMP(0ULL);
1318
1319         set_tcb_field(adapter, f->tid, tcb_word, tcb_mask, tcb_val, 1);
1320
1321         if (clear_byte) {
1322                 tcb_word = W_TCB_T_RTT_TS_RECENT_AGE;
1323                 tcb_mask =
1324                         V_TCB_T_RTT_TS_RECENT_AGE(M_TCB_T_RTT_TS_RECENT_AGE) |
1325                         V_TCB_T_RTSEQ_RECENT(M_TCB_T_RTSEQ_RECENT);
1326                 tcb_val = V_TCB_T_RTT_TS_RECENT_AGE(0ULL) |
1327                           V_TCB_T_RTSEQ_RECENT(0ULL);
1328
1329                 set_tcb_field(adapter, f->tid, tcb_word, tcb_mask, tcb_val, 1);
1330         }
1331
1332         return 0;
1333 }
1334
1335 /**
1336  * Handle a Hash filter delete reply.
1337  */
1338 void cxgbe_hash_del_filter_rpl(struct adapter *adap,
1339                                const struct cpl_abort_rpl_rss *rpl)
1340 {
1341         struct tid_info *t = &adap->tids;
1342         struct filter_entry *f;
1343         struct filter_ctx *ctx = NULL;
1344         unsigned int tid = GET_TID(rpl);
1345
1346         f = lookup_tid(t, tid);
1347         if (!f) {
1348                 dev_warn(adap, "%s: could not find filter entry: %u\n",
1349                          __func__, tid);
1350                 return;
1351         }
1352
1353         ctx = f->ctx;
1354         f->ctx = NULL;
1355
1356         f->valid = 0;
1357
1358         if (f->clipt)
1359                 cxgbe_clip_release(f->dev, f->clipt);
1360
1361         cxgbe_remove_tid(t, 0, tid, 0);
1362         t4_os_free(f);
1363
1364         if (ctx) {
1365                 ctx->result = 0;
1366                 t4_complete(&ctx->completion);
1367         }
1368 }