1
2
3
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 "mps_tcam.h"
12#include "clip_tbl.h"
13#include "l2t.h"
14#include "smt.h"
15#include "cxgbe_pfvf.h"
16
17
18
19
20int cxgbe_init_hash_filter(struct adapter *adap)
21{
22 unsigned int user_filter_perc, n_user_filters;
23 u32 param, val;
24 int ret;
25
26 if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) {
27 val = t4_read_reg(adap, A_LE_DB_RSP_CODE_0);
28 if (G_TCAM_ACTV_HIT(val) != 4) {
29 adap->params.hash_filter = 0;
30 return 0;
31 }
32
33 val = t4_read_reg(adap, A_LE_DB_RSP_CODE_1);
34 if (G_HASH_ACTV_HIT(val) != 4) {
35 adap->params.hash_filter = 0;
36 return 0;
37 }
38 }
39
40 param = CXGBE_FW_PARAM_DEV(NTID);
41 ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
42 ¶m, &val);
43 if (ret < 0)
44 return ret;
45 adap->tids.ntids = val;
46 adap->tids.natids = min(adap->tids.ntids / 2, MAX_ATIDS);
47
48 user_filter_perc = 100;
49 n_user_filters = mult_frac(adap->tids.nftids,
50 user_filter_perc,
51 100);
52
53 adap->tids.nftids = n_user_filters;
54 adap->params.hash_filter = 1;
55 return 0;
56}
57
58
59
60
61
62int cxgbe_validate_filter(struct adapter *adapter,
63 struct ch_filter_specification *fs)
64{
65 u32 fconf, iconf;
66
67
68
69
70 fconf = fs->cap ? adapter->params.tp.filter_mask :
71 adapter->params.tp.vlan_pri_map;
72
73 iconf = adapter->params.tp.ingress_config;
74
75#define S(_field) \
76 (fs->val._field || fs->mask._field)
77#define U(_mask, _field) \
78 (!(fconf & (_mask)) && S(_field))
79
80 if (U(F_PORT, iport) || U(F_ETHERTYPE, ethtype) ||
81 U(F_PROTOCOL, proto) || U(F_MACMATCH, macidx) ||
82 U(F_VLAN, ivlan_vld) || U(F_VNIC_ID, ovlan_vld) ||
83 U(F_TOS, tos) || U(F_VNIC_ID, pfvf_vld))
84 return -EOPNOTSUPP;
85
86
87 if ((S(pfvf_vld) && !(iconf & F_VNIC)) ||
88 (S(ovlan_vld) && (iconf & F_VNIC)))
89 return -EOPNOTSUPP;
90
91
92 if ((S(ovlan_vld) && (iconf & F_USE_ENC_IDX)) ||
93 (S(pfvf_vld) && (iconf & F_USE_ENC_IDX)))
94 return -EOPNOTSUPP;
95
96#undef S
97#undef U
98
99
100
101
102
103
104 if (fs->action == FILTER_SWITCH &&
105 fs->eport >= adapter->params.nports)
106 return -ERANGE;
107
108
109
110
111
112 if (fs->val.iport >= adapter->params.nports)
113 return -ERANGE;
114
115 if (!fs->cap && fs->nat_mode && !adapter->params.filter2_wr_support)
116 return -EOPNOTSUPP;
117
118 if (!fs->cap && fs->swapmac && !adapter->params.filter2_wr_support)
119 return -EOPNOTSUPP;
120
121 return 0;
122}
123
124
125
126
127static unsigned int get_filter_steerq(struct rte_eth_dev *dev,
128 struct ch_filter_specification *fs)
129{
130 struct port_info *pi = ethdev2pinfo(dev);
131 struct adapter *adapter = pi->adapter;
132 unsigned int iq;
133
134
135
136
137
138
139
140 if (!fs->dirsteer) {
141 iq = 0;
142 } else {
143
144
145
146
147 if (fs->iq < pi->n_rx_qsets)
148 iq = adapter->sge.ethrxq[pi->first_rxqset +
149 fs->iq].rspq.abs_id;
150 else
151 iq = fs->iq;
152 }
153
154 return iq;
155}
156
157
158static int writable_filter(struct filter_entry *f)
159{
160 if (f->locked)
161 return -EPERM;
162 if (f->pending)
163 return -EBUSY;
164
165 return 0;
166}
167
168
169
170
171static void set_tcb_field(struct adapter *adapter, unsigned int ftid,
172 u16 word, u64 mask, u64 val, int no_reply)
173{
174 struct rte_mbuf *mbuf;
175 struct cpl_set_tcb_field *req;
176 struct sge_ctrl_txq *ctrlq;
177
178 ctrlq = &adapter->sge.ctrlq[0];
179 mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
180 WARN_ON(!mbuf);
181
182 mbuf->data_len = sizeof(*req);
183 mbuf->pkt_len = mbuf->data_len;
184
185 req = rte_pktmbuf_mtod(mbuf, struct cpl_set_tcb_field *);
186 memset(req, 0, sizeof(*req));
187 INIT_TP_WR_MIT_CPL(req, CPL_SET_TCB_FIELD, ftid);
188 req->reply_ctrl = cpu_to_be16(V_REPLY_CHAN(0) |
189 V_QUEUENO(adapter->sge.fw_evtq.abs_id) |
190 V_NO_REPLY(no_reply));
191 req->word_cookie = cpu_to_be16(V_WORD(word) | V_COOKIE(ftid));
192 req->mask = cpu_to_be64(mask);
193 req->val = cpu_to_be64(val);
194
195 t4_mgmt_tx(ctrlq, mbuf);
196}
197
198
199
200
201static void set_tcb_tflag(struct adapter *adap, unsigned int ftid,
202 unsigned int bit_pos, unsigned int val, int no_reply)
203{
204 set_tcb_field(adap, ftid, W_TCB_T_FLAGS, 1ULL << bit_pos,
205 (unsigned long long)val << bit_pos, no_reply);
206}
207
208
209
210
211static inline void mk_set_tcb_field_ulp(struct filter_entry *f,
212 struct cpl_set_tcb_field *req,
213 unsigned int word,
214 u64 mask, u64 val, u8 cookie,
215 int no_reply)
216{
217 struct ulp_txpkt *txpkt = (struct ulp_txpkt *)req;
218 struct ulptx_idata *sc = (struct ulptx_idata *)(txpkt + 1);
219
220 txpkt->cmd_dest = cpu_to_be32(V_ULPTX_CMD(ULP_TX_PKT) |
221 V_ULP_TXPKT_DEST(0));
222 txpkt->len = cpu_to_be32(DIV_ROUND_UP(sizeof(*req), 16));
223 sc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_IMM));
224 sc->len = cpu_to_be32(sizeof(*req) - sizeof(struct work_request_hdr));
225 OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_SET_TCB_FIELD, f->tid));
226 req->reply_ctrl = cpu_to_be16(V_NO_REPLY(no_reply) | V_REPLY_CHAN(0) |
227 V_QUEUENO(0));
228 req->word_cookie = cpu_to_be16(V_WORD(word) | V_COOKIE(cookie));
229 req->mask = cpu_to_be64(mask);
230 req->val = cpu_to_be64(val);
231 sc = (struct ulptx_idata *)(req + 1);
232 sc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_NOOP));
233 sc->len = cpu_to_be32(0);
234}
235
236
237
238
239
240u8 cxgbe_filter_slots(struct adapter *adap, u8 family)
241{
242 if (family == FILTER_TYPE_IPV6) {
243 if (CHELSIO_CHIP_VERSION(adap->params.chip) < CHELSIO_T6)
244 return 4;
245
246 return 2;
247 }
248
249 return 1;
250}
251
252
253
254
255bool cxgbe_is_filter_set(struct tid_info *t, u32 fidx, u8 nentries)
256{
257 bool result = FALSE;
258 u32 i;
259
260
261 t4_os_lock(&t->ftid_lock);
262 for (i = fidx; i < fidx + nentries; i++) {
263 if (rte_bitmap_get(t->ftid_bmap, i)) {
264 result = TRUE;
265 break;
266 }
267 }
268 t4_os_unlock(&t->ftid_lock);
269 return result;
270}
271
272
273
274
275int cxgbe_alloc_ftid(struct adapter *adap, u8 nentries)
276{
277 struct tid_info *t = &adap->tids;
278 int pos;
279 int size = t->nftids;
280
281 t4_os_lock(&t->ftid_lock);
282 if (nentries > 1)
283 pos = cxgbe_bitmap_find_free_region(t->ftid_bmap, size,
284 nentries);
285 else
286 pos = cxgbe_find_first_zero_bit(t->ftid_bmap, size);
287 t4_os_unlock(&t->ftid_lock);
288
289 return pos < size ? pos : -1;
290}
291
292
293
294
295
296static void clear_filter(struct filter_entry *f)
297{
298 struct port_info *pi = ethdev2pinfo(f->dev);
299
300 if (f->clipt)
301 cxgbe_clip_release(f->dev, f->clipt);
302
303 if (f->l2t)
304 cxgbe_l2t_release(f->l2t);
305
306 if (f->fs.mask.macidx)
307 cxgbe_mpstcam_remove(pi, f->fs.val.macidx);
308
309 if (f->smt)
310 cxgbe_smt_release(f->smt);
311
312
313
314
315
316 memset(f, 0, sizeof(*f));
317}
318
319
320
321
322static u64 hash_filter_ntuple(const struct filter_entry *f)
323{
324 struct adapter *adap = ethdev2adap(f->dev);
325 struct tp_params *tp = &adap->params.tp;
326 u64 ntuple = 0;
327 u16 tcp_proto = IPPROTO_TCP;
328
329 if (tp->port_shift >= 0 && f->fs.mask.iport)
330 ntuple |= (u64)f->fs.val.iport << tp->port_shift;
331
332 if (tp->protocol_shift >= 0) {
333 if (!f->fs.val.proto)
334 ntuple |= (u64)tcp_proto << tp->protocol_shift;
335 else
336 ntuple |= (u64)f->fs.val.proto << tp->protocol_shift;
337 }
338
339 if (tp->ethertype_shift >= 0 && f->fs.mask.ethtype)
340 ntuple |= (u64)(f->fs.val.ethtype) << tp->ethertype_shift;
341 if (tp->macmatch_shift >= 0 && f->fs.mask.macidx)
342 ntuple |= (u64)(f->fs.val.macidx) << tp->macmatch_shift;
343 if (tp->vlan_shift >= 0 && f->fs.mask.ivlan)
344 ntuple |= (u64)(F_FT_VLAN_VLD | f->fs.val.ivlan) <<
345 tp->vlan_shift;
346 if (tp->vnic_shift >= 0) {
347 if ((adap->params.tp.ingress_config & F_VNIC) &&
348 f->fs.mask.pfvf_vld)
349 ntuple |= (u64)(f->fs.val.pfvf_vld << 16 |
350 f->fs.val.pf << 13 | f->fs.val.vf) <<
351 tp->vnic_shift;
352 else if (!(adap->params.tp.ingress_config & F_VNIC) &&
353 f->fs.mask.ovlan_vld)
354 ntuple |= (u64)(f->fs.val.ovlan_vld << 16 |
355 f->fs.val.ovlan) << tp->vnic_shift;
356 }
357 if (tp->tos_shift >= 0 && f->fs.mask.tos)
358 ntuple |= (u64)f->fs.val.tos << tp->tos_shift;
359
360 return ntuple;
361}
362
363
364
365
366static void mk_abort_req_ulp(struct cpl_abort_req *abort_req,
367 unsigned int tid)
368{
369 struct ulp_txpkt *txpkt = (struct ulp_txpkt *)abort_req;
370 struct ulptx_idata *sc = (struct ulptx_idata *)(txpkt + 1);
371
372 txpkt->cmd_dest = cpu_to_be32(V_ULPTX_CMD(ULP_TX_PKT) |
373 V_ULP_TXPKT_DEST(0));
374 txpkt->len = cpu_to_be32(DIV_ROUND_UP(sizeof(*abort_req), 16));
375 sc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_IMM));
376 sc->len = cpu_to_be32(sizeof(*abort_req) -
377 sizeof(struct work_request_hdr));
378 OPCODE_TID(abort_req) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_REQ, tid));
379 abort_req->rsvd0 = cpu_to_be32(0);
380 abort_req->rsvd1 = 0;
381 abort_req->cmd = CPL_ABORT_NO_RST;
382 sc = (struct ulptx_idata *)(abort_req + 1);
383 sc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_NOOP));
384 sc->len = cpu_to_be32(0);
385}
386
387
388
389
390static void mk_abort_rpl_ulp(struct cpl_abort_rpl *abort_rpl,
391 unsigned int tid)
392{
393 struct ulp_txpkt *txpkt = (struct ulp_txpkt *)abort_rpl;
394 struct ulptx_idata *sc = (struct ulptx_idata *)(txpkt + 1);
395
396 txpkt->cmd_dest = cpu_to_be32(V_ULPTX_CMD(ULP_TX_PKT) |
397 V_ULP_TXPKT_DEST(0));
398 txpkt->len = cpu_to_be32(DIV_ROUND_UP(sizeof(*abort_rpl), 16));
399 sc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_IMM));
400 sc->len = cpu_to_be32(sizeof(*abort_rpl) -
401 sizeof(struct work_request_hdr));
402 OPCODE_TID(abort_rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_RPL, tid));
403 abort_rpl->rsvd0 = cpu_to_be32(0);
404 abort_rpl->rsvd1 = 0;
405 abort_rpl->cmd = CPL_ABORT_NO_RST;
406 sc = (struct ulptx_idata *)(abort_rpl + 1);
407 sc->cmd_more = cpu_to_be32(V_ULPTX_CMD(ULP_TX_SC_NOOP));
408 sc->len = cpu_to_be32(0);
409}
410
411
412
413
414static int cxgbe_del_hash_filter(struct rte_eth_dev *dev,
415 unsigned int filter_id,
416 struct filter_ctx *ctx)
417{
418 struct adapter *adapter = ethdev2adap(dev);
419 struct tid_info *t = &adapter->tids;
420 struct filter_entry *f;
421 struct sge_ctrl_txq *ctrlq;
422 unsigned int port_id = ethdev2pinfo(dev)->port_id;
423 int ret;
424
425 if (filter_id > adapter->tids.ntids)
426 return -E2BIG;
427
428 f = lookup_tid(t, filter_id);
429 if (!f) {
430 dev_err(adapter, "%s: no filter entry for filter_id = %d\n",
431 __func__, filter_id);
432 return -EINVAL;
433 }
434
435 ret = writable_filter(f);
436 if (ret)
437 return ret;
438
439 if (f->valid) {
440 unsigned int wrlen;
441 struct rte_mbuf *mbuf;
442 struct work_request_hdr *wr;
443 struct ulptx_idata *aligner;
444 struct cpl_set_tcb_field *req;
445 struct cpl_abort_req *abort_req;
446 struct cpl_abort_rpl *abort_rpl;
447
448 f->ctx = ctx;
449 f->pending = 1;
450
451 wrlen = cxgbe_roundup(sizeof(*wr) +
452 (sizeof(*req) + sizeof(*aligner)) +
453 sizeof(*abort_req) + sizeof(*abort_rpl),
454 16);
455
456 ctrlq = &adapter->sge.ctrlq[port_id];
457 mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
458 if (!mbuf) {
459 dev_err(adapter, "%s: could not allocate skb ..\n",
460 __func__);
461 goto out_err;
462 }
463
464 mbuf->data_len = wrlen;
465 mbuf->pkt_len = mbuf->data_len;
466
467 req = rte_pktmbuf_mtod(mbuf, struct cpl_set_tcb_field *);
468 INIT_ULPTX_WR(req, wrlen, 0, 0);
469 wr = (struct work_request_hdr *)req;
470 wr++;
471 req = (struct cpl_set_tcb_field *)wr;
472 mk_set_tcb_field_ulp(f, req, W_TCB_RSS_INFO,
473 V_TCB_RSS_INFO(M_TCB_RSS_INFO),
474 V_TCB_RSS_INFO(adapter->sge.fw_evtq.abs_id),
475 0, 1);
476 aligner = (struct ulptx_idata *)(req + 1);
477 abort_req = (struct cpl_abort_req *)(aligner + 1);
478 mk_abort_req_ulp(abort_req, f->tid);
479 abort_rpl = (struct cpl_abort_rpl *)(abort_req + 1);
480 mk_abort_rpl_ulp(abort_rpl, f->tid);
481 t4_mgmt_tx(ctrlq, mbuf);
482 }
483 return 0;
484
485out_err:
486 return -ENOMEM;
487}
488
489
490
491
492static void mk_act_open_req6(struct filter_entry *f, struct rte_mbuf *mbuf,
493 unsigned int qid_filterid, struct adapter *adap)
494{
495 struct cpl_t6_act_open_req6 *req = NULL;
496 u64 local_lo, local_hi, peer_lo, peer_hi;
497 u32 *lip = (u32 *)f->fs.val.lip;
498 u32 *fip = (u32 *)f->fs.val.fip;
499
500 switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
501 case CHELSIO_T6:
502 req = rte_pktmbuf_mtod(mbuf, struct cpl_t6_act_open_req6 *);
503
504 INIT_TP_WR(req, 0);
505 break;
506 default:
507 dev_err(adap, "%s: unsupported chip type!\n", __func__);
508 return;
509 }
510
511 local_hi = ((u64)lip[1]) << 32 | lip[0];
512 local_lo = ((u64)lip[3]) << 32 | lip[2];
513 peer_hi = ((u64)fip[1]) << 32 | fip[0];
514 peer_lo = ((u64)fip[3]) << 32 | fip[2];
515
516 OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ6,
517 qid_filterid));
518 req->local_port = cpu_to_be16(f->fs.val.lport);
519 req->peer_port = cpu_to_be16(f->fs.val.fport);
520 req->local_ip_hi = local_hi;
521 req->local_ip_lo = local_lo;
522 req->peer_ip_hi = peer_hi;
523 req->peer_ip_lo = peer_lo;
524 req->opt0 = cpu_to_be64(V_NAGLE(f->fs.newvlan == VLAN_REMOVE ||
525 f->fs.newvlan == VLAN_REWRITE) |
526 V_DELACK(f->fs.hitcnts) |
527 V_L2T_IDX(f->l2t ? f->l2t->idx : 0) |
528 V_SMAC_SEL((cxgbe_port_viid(f->dev) & 0x7F)
529 << 1) |
530 V_TX_CHAN(f->fs.eport) |
531 V_ULP_MODE(ULP_MODE_NONE) |
532 F_TCAM_BYPASS | F_NON_OFFLOAD);
533 req->params = cpu_to_be64(V_FILTER_TUPLE(hash_filter_ntuple(f)));
534 req->opt2 = cpu_to_be32(F_RSS_QUEUE_VALID |
535 V_RSS_QUEUE(f->fs.iq) |
536 F_T5_OPT_2_VALID |
537 F_RX_CHANNEL |
538 V_SACK_EN(f->fs.swapmac) |
539 V_CONG_CNTRL((f->fs.action == FILTER_DROP) |
540 (f->fs.dirsteer << 1)) |
541 V_CCTRL_ECN(f->fs.action == FILTER_SWITCH));
542}
543
544
545
546
547static void mk_act_open_req(struct filter_entry *f, struct rte_mbuf *mbuf,
548 unsigned int qid_filterid, struct adapter *adap)
549{
550 struct cpl_t6_act_open_req *req = NULL;
551
552 switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
553 case CHELSIO_T6:
554 req = rte_pktmbuf_mtod(mbuf, struct cpl_t6_act_open_req *);
555
556 INIT_TP_WR(req, 0);
557 break;
558 default:
559 dev_err(adap, "%s: unsupported chip type!\n", __func__);
560 return;
561 }
562
563 OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
564 qid_filterid));
565 req->local_port = cpu_to_be16(f->fs.val.lport);
566 req->peer_port = cpu_to_be16(f->fs.val.fport);
567 req->local_ip = f->fs.val.lip[0] | f->fs.val.lip[1] << 8 |
568 f->fs.val.lip[2] << 16 | f->fs.val.lip[3] << 24;
569 req->peer_ip = f->fs.val.fip[0] | f->fs.val.fip[1] << 8 |
570 f->fs.val.fip[2] << 16 | f->fs.val.fip[3] << 24;
571 req->opt0 = cpu_to_be64(V_NAGLE(f->fs.newvlan == VLAN_REMOVE ||
572 f->fs.newvlan == VLAN_REWRITE) |
573 V_DELACK(f->fs.hitcnts) |
574 V_L2T_IDX(f->l2t ? f->l2t->idx : 0) |
575 V_SMAC_SEL((cxgbe_port_viid(f->dev) & 0x7F)
576 << 1) |
577 V_TX_CHAN(f->fs.eport) |
578 V_ULP_MODE(ULP_MODE_NONE) |
579 F_TCAM_BYPASS | F_NON_OFFLOAD);
580 req->params = cpu_to_be64(V_FILTER_TUPLE(hash_filter_ntuple(f)));
581 req->opt2 = cpu_to_be32(F_RSS_QUEUE_VALID |
582 V_RSS_QUEUE(f->fs.iq) |
583 F_T5_OPT_2_VALID |
584 F_RX_CHANNEL |
585 V_SACK_EN(f->fs.swapmac) |
586 V_CONG_CNTRL((f->fs.action == FILTER_DROP) |
587 (f->fs.dirsteer << 1)) |
588 V_CCTRL_ECN(f->fs.action == FILTER_SWITCH));
589}
590
591
592
593
594static int cxgbe_set_hash_filter(struct rte_eth_dev *dev,
595 struct ch_filter_specification *fs,
596 struct filter_ctx *ctx)
597{
598 struct port_info *pi = ethdev2pinfo(dev);
599 struct adapter *adapter = pi->adapter;
600 struct tid_info *t = &adapter->tids;
601 struct filter_entry *f;
602 struct rte_mbuf *mbuf;
603 struct sge_ctrl_txq *ctrlq;
604 unsigned int iq;
605 int atid, size;
606 int ret = 0;
607
608 ret = cxgbe_validate_filter(adapter, fs);
609 if (ret)
610 return ret;
611
612 iq = get_filter_steerq(dev, fs);
613
614 ctrlq = &adapter->sge.ctrlq[pi->port_id];
615
616 f = t4_os_alloc(sizeof(*f));
617 if (!f)
618 return -ENOMEM;
619
620 f->fs = *fs;
621 f->ctx = ctx;
622 f->dev = dev;
623 f->fs.iq = iq;
624
625
626 if (f->fs.mask.macidx) {
627 int idx;
628
629 idx = cxgbe_mpstcam_alloc(pi, f->fs.val.dmac, f->fs.mask.dmac);
630 if (idx <= 0) {
631 ret = -ENOMEM;
632 goto out_err;
633 }
634
635 f->fs.val.macidx = idx;
636 }
637
638
639
640
641
642
643 if (f->fs.newdmac || f->fs.newvlan == VLAN_INSERT ||
644 f->fs.newvlan == VLAN_REWRITE) {
645
646 f->l2t = cxgbe_l2t_alloc_switching(dev, f->fs.vlan,
647 f->fs.eport, f->fs.dmac);
648 if (!f->l2t) {
649 ret = -ENOMEM;
650 goto out_err;
651 }
652 }
653
654
655
656
657 if (f->fs.newsmac) {
658 f->smt = cxgbe_smt_alloc_switching(f->dev, f->fs.smac);
659 if (!f->smt) {
660 ret = -EAGAIN;
661 goto out_err;
662 }
663 }
664
665 atid = cxgbe_alloc_atid(t, f);
666 if (atid < 0)
667 goto out_err;
668
669 if (f->fs.type == FILTER_TYPE_IPV6) {
670
671 f->clipt = cxgbe_clip_alloc(f->dev, (u32 *)&f->fs.val.lip);
672 if (!f->clipt)
673 goto free_atid;
674
675 size = sizeof(struct cpl_t6_act_open_req6);
676 mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
677 if (!mbuf) {
678 ret = -ENOMEM;
679 goto free_atid;
680 }
681
682 mbuf->data_len = size;
683 mbuf->pkt_len = mbuf->data_len;
684
685 mk_act_open_req6(f, mbuf,
686 ((adapter->sge.fw_evtq.abs_id << 14) | atid),
687 adapter);
688 } else {
689
690 size = sizeof(struct cpl_t6_act_open_req);
691 mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
692 if (!mbuf) {
693 ret = -ENOMEM;
694 goto free_atid;
695 }
696
697 mbuf->data_len = size;
698 mbuf->pkt_len = mbuf->data_len;
699
700 mk_act_open_req(f, mbuf,
701 ((adapter->sge.fw_evtq.abs_id << 14) | atid),
702 adapter);
703 }
704
705 f->pending = 1;
706 t4_mgmt_tx(ctrlq, mbuf);
707 return 0;
708
709free_atid:
710 cxgbe_free_atid(t, atid);
711
712out_err:
713 clear_filter(f);
714 t4_os_free(f);
715 return ret;
716}
717
718
719
720
721
722
723
724
725
726
727
728static void t4_mk_filtdelwr(struct adapter *adap, unsigned int ftid,
729 struct fw_filter2_wr *wr, int qid)
730{
731 memset(wr, 0, sizeof(*wr));
732 if (adap->params.filter2_wr_support)
733 wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER2_WR));
734 else
735 wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
736 wr->len16_pkd = cpu_to_be32(V_FW_WR_LEN16(sizeof(*wr) / 16));
737 wr->tid_to_iq = cpu_to_be32(V_FW_FILTER_WR_TID(ftid) |
738 V_FW_FILTER_WR_NOREPLY(qid < 0));
739 wr->del_filter_to_l2tix = cpu_to_be32(F_FW_FILTER_WR_DEL_FILTER);
740 if (qid >= 0)
741 wr->rx_chan_rx_rpl_iq =
742 cpu_to_be16(V_FW_FILTER_WR_RX_RPL_IQ(qid));
743}
744
745
746
747
748static int del_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
749{
750 struct adapter *adapter = ethdev2adap(dev);
751 struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
752 struct rte_mbuf *mbuf;
753 struct fw_filter2_wr *fwr;
754 struct sge_ctrl_txq *ctrlq;
755 unsigned int port_id = ethdev2pinfo(dev)->port_id;
756
757 ctrlq = &adapter->sge.ctrlq[port_id];
758 mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
759 if (!mbuf)
760 return -ENOMEM;
761
762 mbuf->data_len = sizeof(*fwr);
763 mbuf->pkt_len = mbuf->data_len;
764
765 fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter2_wr *);
766 t4_mk_filtdelwr(adapter, f->tid, fwr, adapter->sge.fw_evtq.abs_id);
767
768
769
770
771
772 f->pending = 1;
773 t4_mgmt_tx(ctrlq, mbuf);
774 return 0;
775}
776
777static int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
778{
779 struct adapter *adapter = ethdev2adap(dev);
780 struct filter_entry *f = &adapter->tids.ftid_tab[fidx];
781 struct rte_mbuf *mbuf;
782 struct fw_filter2_wr *fwr;
783 struct sge_ctrl_txq *ctrlq;
784 unsigned int port_id = ethdev2pinfo(dev)->port_id;
785 int ret;
786
787 ctrlq = &adapter->sge.ctrlq[port_id];
788 mbuf = rte_pktmbuf_alloc(ctrlq->mb_pool);
789 if (!mbuf) {
790 ret = -ENOMEM;
791 goto out;
792 }
793
794 mbuf->data_len = sizeof(*fwr);
795 mbuf->pkt_len = mbuf->data_len;
796
797 fwr = rte_pktmbuf_mtod(mbuf, struct fw_filter2_wr *);
798 memset(fwr, 0, sizeof(*fwr));
799
800
801
802
803 if (adapter->params.filter2_wr_support)
804 fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER2_WR));
805 else
806 fwr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR));
807 fwr->len16_pkd = cpu_to_be32(V_FW_WR_LEN16(sizeof(*fwr) / 16));
808 fwr->tid_to_iq =
809 cpu_to_be32(V_FW_FILTER_WR_TID(f->tid) |
810 V_FW_FILTER_WR_RQTYPE(f->fs.type) |
811 V_FW_FILTER_WR_NOREPLY(0) |
812 V_FW_FILTER_WR_IQ(f->fs.iq));
813 fwr->del_filter_to_l2tix =
814 cpu_to_be32(V_FW_FILTER_WR_DROP(f->fs.action == FILTER_DROP) |
815 V_FW_FILTER_WR_DIRSTEER(f->fs.dirsteer) |
816 V_FW_FILTER_WR_LPBK(f->fs.action == FILTER_SWITCH) |
817 V_FW_FILTER_WR_SMAC(f->fs.newsmac) |
818 V_FW_FILTER_WR_DMAC(f->fs.newdmac) |
819 V_FW_FILTER_WR_INSVLAN
820 (f->fs.newvlan == VLAN_INSERT ||
821 f->fs.newvlan == VLAN_REWRITE) |
822 V_FW_FILTER_WR_RMVLAN
823 (f->fs.newvlan == VLAN_REMOVE ||
824 f->fs.newvlan == VLAN_REWRITE) |
825 V_FW_FILTER_WR_HITCNTS(f->fs.hitcnts) |
826 V_FW_FILTER_WR_TXCHAN(f->fs.eport) |
827 V_FW_FILTER_WR_PRIO(f->fs.prio) |
828 V_FW_FILTER_WR_L2TIX(f->l2t ? f->l2t->idx : 0));
829 fwr->ethtype = cpu_to_be16(f->fs.val.ethtype);
830 fwr->ethtypem = cpu_to_be16(f->fs.mask.ethtype);
831 fwr->frag_to_ovlan_vldm =
832 (V_FW_FILTER_WR_IVLAN_VLD(f->fs.val.ivlan_vld) |
833 V_FW_FILTER_WR_IVLAN_VLDM(f->fs.mask.ivlan_vld) |
834 V_FW_FILTER_WR_OVLAN_VLD(f->fs.val.ovlan_vld) |
835 V_FW_FILTER_WR_OVLAN_VLDM(f->fs.mask.ovlan_vld));
836 fwr->smac_sel = f->smt ? f->smt->hw_idx : 0;
837 fwr->rx_chan_rx_rpl_iq =
838 cpu_to_be16(V_FW_FILTER_WR_RX_CHAN(0) |
839 V_FW_FILTER_WR_RX_RPL_IQ(adapter->sge.fw_evtq.abs_id
840 ));
841 fwr->maci_to_matchtypem =
842 cpu_to_be32(V_FW_FILTER_WR_MACI(f->fs.val.macidx) |
843 V_FW_FILTER_WR_MACIM(f->fs.mask.macidx) |
844 V_FW_FILTER_WR_PORT(f->fs.val.iport) |
845 V_FW_FILTER_WR_PORTM(f->fs.mask.iport));
846 fwr->ptcl = f->fs.val.proto;
847 fwr->ptclm = f->fs.mask.proto;
848 fwr->ttyp = f->fs.val.tos;
849 fwr->ttypm = f->fs.mask.tos;
850 fwr->ivlan = cpu_to_be16(f->fs.val.ivlan);
851 fwr->ivlanm = cpu_to_be16(f->fs.mask.ivlan);
852 fwr->ovlan = cpu_to_be16(f->fs.val.ovlan);
853 fwr->ovlanm = cpu_to_be16(f->fs.mask.ovlan);
854 rte_memcpy(fwr->lip, f->fs.val.lip, sizeof(fwr->lip));
855 rte_memcpy(fwr->lipm, f->fs.mask.lip, sizeof(fwr->lipm));
856 rte_memcpy(fwr->fip, f->fs.val.fip, sizeof(fwr->fip));
857 rte_memcpy(fwr->fipm, f->fs.mask.fip, sizeof(fwr->fipm));
858 fwr->lp = cpu_to_be16(f->fs.val.lport);
859 fwr->lpm = cpu_to_be16(f->fs.mask.lport);
860 fwr->fp = cpu_to_be16(f->fs.val.fport);
861 fwr->fpm = cpu_to_be16(f->fs.mask.fport);
862
863 if (adapter->params.filter2_wr_support) {
864 fwr->filter_type_swapmac =
865 V_FW_FILTER2_WR_SWAPMAC(f->fs.swapmac);
866 fwr->natmode_to_ulp_type =
867 V_FW_FILTER2_WR_ULP_TYPE(f->fs.nat_mode ?
868 ULP_MODE_TCPDDP :
869 ULP_MODE_NONE) |
870 V_FW_FILTER2_WR_NATMODE(f->fs.nat_mode);
871 memcpy(fwr->newlip, f->fs.nat_lip, sizeof(fwr->newlip));
872 memcpy(fwr->newfip, f->fs.nat_fip, sizeof(fwr->newfip));
873 fwr->newlport = cpu_to_be16(f->fs.nat_lport);
874 fwr->newfport = cpu_to_be16(f->fs.nat_fport);
875 }
876
877
878
879
880
881 f->pending = 1;
882 t4_mgmt_tx(ctrlq, mbuf);
883 return 0;
884
885out:
886 return ret;
887}
888
889
890
891
892static int cxgbe_set_ftid(struct tid_info *t, u32 fidx, u8 nentries)
893{
894 u32 i;
895
896 t4_os_lock(&t->ftid_lock);
897 if (rte_bitmap_get(t->ftid_bmap, fidx)) {
898 t4_os_unlock(&t->ftid_lock);
899 return -EBUSY;
900 }
901
902 for (i = fidx; i < fidx + nentries; i++)
903 rte_bitmap_set(t->ftid_bmap, i);
904 t4_os_unlock(&t->ftid_lock);
905 return 0;
906}
907
908
909
910
911static void cxgbe_clear_ftid(struct tid_info *t, u32 fidx, u8 nentries)
912{
913 u32 i;
914
915 t4_os_lock(&t->ftid_lock);
916 for (i = fidx; i < fidx + nentries; i++)
917 rte_bitmap_clear(t->ftid_bmap, i);
918 t4_os_unlock(&t->ftid_lock);
919}
920
921
922
923
924
925
926
927int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
928 struct ch_filter_specification *fs,
929 struct filter_ctx *ctx)
930{
931 struct port_info *pi = dev->data->dev_private;
932 struct adapter *adapter = pi->adapter;
933 struct filter_entry *f;
934 unsigned int chip_ver;
935 u8 nentries;
936 int ret;
937
938 if (is_hashfilter(adapter) && fs->cap)
939 return cxgbe_del_hash_filter(dev, filter_id, ctx);
940
941 if (filter_id >= adapter->tids.nftids)
942 return -ERANGE;
943
944 chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
945
946
947
948
949
950 if (fs->type == FILTER_TYPE_IPV6) {
951 if (chip_ver < CHELSIO_T6)
952 filter_id &= ~(0x3);
953 else
954 filter_id &= ~(0x1);
955 }
956
957 nentries = cxgbe_filter_slots(adapter, fs->type);
958 ret = cxgbe_is_filter_set(&adapter->tids, filter_id, nentries);
959 if (!ret) {
960 dev_warn(adap, "%s: could not find filter entry: %u\n",
961 __func__, filter_id);
962 return -EINVAL;
963 }
964
965 f = &adapter->tids.ftid_tab[filter_id];
966 ret = writable_filter(f);
967 if (ret)
968 return ret;
969
970 if (f->valid) {
971 f->ctx = ctx;
972 cxgbe_clear_ftid(&adapter->tids,
973 f->tid - adapter->tids.ftid_base,
974 nentries);
975 return del_filter_wr(dev, filter_id);
976 }
977
978
979
980
981
982
983 if (ctx) {
984 ctx->result = 0;
985 t4_complete(&ctx->completion);
986 }
987
988 return 0;
989}
990
991
992
993
994
995
996
997
998int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
999 struct ch_filter_specification *fs,
1000 struct filter_ctx *ctx)
1001{
1002 struct port_info *pi = ethdev2pinfo(dev);
1003 struct adapter *adapter = pi->adapter;
1004 u8 nentries, bitoff[16] = {0};
1005 struct filter_entry *f;
1006 unsigned int chip_ver;
1007 unsigned int fidx, iq;
1008 u32 iconf;
1009 int ret;
1010
1011 if (is_hashfilter(adapter) && fs->cap)
1012 return cxgbe_set_hash_filter(dev, fs, ctx);
1013
1014 if (filter_id >= adapter->tids.nftids)
1015 return -ERANGE;
1016
1017 chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
1018
1019 ret = cxgbe_validate_filter(adapter, fs);
1020 if (ret)
1021 return ret;
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031 fidx = filter_id;
1032 if (fs->type == FILTER_TYPE_IPV6) {
1033 if (chip_ver < CHELSIO_T6)
1034 fidx &= ~(0x3);
1035 else
1036 fidx &= ~(0x1);
1037 }
1038
1039 if (fidx != filter_id)
1040 return -EINVAL;
1041
1042 nentries = cxgbe_filter_slots(adapter, fs->type);
1043 ret = cxgbe_is_filter_set(&adapter->tids, filter_id, nentries);
1044 if (ret)
1045 return -EBUSY;
1046
1047 iq = get_filter_steerq(dev, fs);
1048
1049
1050
1051
1052
1053 f = &adapter->tids.ftid_tab[filter_id];
1054 if (f->valid)
1055 return -EBUSY;
1056
1057 fidx = adapter->tids.ftid_base + filter_id;
1058 ret = cxgbe_set_ftid(&adapter->tids, filter_id, nentries);
1059 if (ret)
1060 return ret;
1061
1062
1063
1064
1065 ret = writable_filter(f);
1066 if (ret) {
1067
1068 cxgbe_clear_ftid(&adapter->tids, filter_id, nentries);
1069 return ret;
1070 }
1071
1072
1073
1074
1075
1076
1077
1078 f->fs = *fs;
1079 f->fs.iq = iq;
1080 f->dev = dev;
1081
1082
1083 if (f->fs.mask.macidx) {
1084 int idx;
1085
1086 idx = cxgbe_mpstcam_alloc(pi, f->fs.val.dmac, f->fs.mask.dmac);
1087 if (idx <= 0) {
1088 ret = -ENOMEM;
1089 goto free_tid;
1090 }
1091
1092 f->fs.val.macidx = idx;
1093 }
1094
1095
1096 if (chip_ver > CHELSIO_T5 && f->fs.type &&
1097 memcmp(f->fs.val.lip, bitoff, sizeof(bitoff))) {
1098 f->clipt = cxgbe_clip_alloc(dev, (u32 *)&f->fs.val.lip);
1099 if (!f->clipt) {
1100 ret = -ENOMEM;
1101 goto free_tid;
1102 }
1103 }
1104
1105
1106
1107
1108
1109 if (f->fs.newvlan || f->fs.newdmac) {
1110 f->l2t = cxgbe_l2t_alloc_switching(f->dev, f->fs.vlan,
1111 f->fs.eport, f->fs.dmac);
1112 if (!f->l2t) {
1113 ret = -ENOMEM;
1114 goto free_tid;
1115 }
1116 }
1117
1118
1119
1120
1121 if (f->fs.newsmac) {
1122 f->smt = cxgbe_smt_alloc_switching(f->dev, f->fs.smac);
1123 if (!f->smt) {
1124 ret = -ENOMEM;
1125 goto free_tid;
1126 }
1127 }
1128
1129 iconf = adapter->params.tp.ingress_config;
1130
1131
1132
1133
1134
1135
1136 if (iconf & F_VNIC) {
1137 f->fs.val.ovlan = fs->val.pf << 13 | fs->val.vf;
1138 f->fs.mask.ovlan = fs->mask.pf << 13 | fs->mask.vf;
1139 f->fs.val.ovlan_vld = fs->val.pfvf_vld;
1140 f->fs.mask.ovlan_vld = fs->mask.pfvf_vld;
1141 }
1142
1143
1144
1145
1146
1147 f->ctx = ctx;
1148 f->tid = fidx;
1149 ret = set_filter_wr(dev, filter_id);
1150 if (ret)
1151 goto free_tid;
1152
1153 return ret;
1154
1155free_tid:
1156 cxgbe_clear_ftid(&adapter->tids, filter_id, nentries);
1157 clear_filter(f);
1158 return ret;
1159}
1160
1161
1162
1163
1164void cxgbe_hash_filter_rpl(struct adapter *adap,
1165 const struct cpl_act_open_rpl *rpl)
1166{
1167 struct tid_info *t = &adap->tids;
1168 struct filter_entry *f;
1169 struct filter_ctx *ctx = NULL;
1170 unsigned int tid = GET_TID(rpl);
1171 unsigned int ftid = G_TID_TID(G_AOPEN_ATID
1172 (be32_to_cpu(rpl->atid_status)));
1173 unsigned int status = G_AOPEN_STATUS(be32_to_cpu(rpl->atid_status));
1174
1175 f = lookup_atid(t, ftid);
1176 if (!f) {
1177 dev_warn(adap, "%s: could not find filter entry: %d\n",
1178 __func__, ftid);
1179 return;
1180 }
1181
1182 ctx = f->ctx;
1183 f->ctx = NULL;
1184
1185 switch (status) {
1186 case CPL_ERR_NONE: {
1187 f->tid = tid;
1188 f->pending = 0;
1189 f->valid = 1;
1190
1191 cxgbe_insert_tid(t, f, f->tid, 0);
1192 cxgbe_free_atid(t, ftid);
1193 if (ctx) {
1194 ctx->tid = f->tid;
1195 ctx->result = 0;
1196 }
1197 if (f->fs.hitcnts)
1198 set_tcb_field(adap, tid,
1199 W_TCB_TIMESTAMP,
1200 V_TCB_TIMESTAMP(M_TCB_TIMESTAMP) |
1201 V_TCB_T_RTT_TS_RECENT_AGE
1202 (M_TCB_T_RTT_TS_RECENT_AGE),
1203 V_TCB_TIMESTAMP(0ULL) |
1204 V_TCB_T_RTT_TS_RECENT_AGE(0ULL),
1205 1);
1206 if (f->fs.newdmac)
1207 set_tcb_tflag(adap, tid, S_TF_CCTRL_ECE, 1, 1);
1208 if (f->fs.newvlan == VLAN_INSERT ||
1209 f->fs.newvlan == VLAN_REWRITE)
1210 set_tcb_tflag(adap, tid, S_TF_CCTRL_RFR, 1, 1);
1211 if (f->fs.newsmac) {
1212 set_tcb_tflag(adap, tid, S_TF_CCTRL_CWR, 1, 1);
1213 set_tcb_field(adap, tid, W_TCB_SMAC_SEL,
1214 V_TCB_SMAC_SEL(M_TCB_SMAC_SEL),
1215 V_TCB_SMAC_SEL(f->smt->hw_idx), 1);
1216 }
1217 break;
1218 }
1219 default:
1220 dev_warn(adap, "%s: filter creation failed with status = %u\n",
1221 __func__, status);
1222
1223 if (ctx) {
1224 if (status == CPL_ERR_TCAM_FULL)
1225 ctx->result = -EAGAIN;
1226 else
1227 ctx->result = -EINVAL;
1228 }
1229
1230 cxgbe_free_atid(t, ftid);
1231 clear_filter(f);
1232 t4_os_free(f);
1233 }
1234
1235 if (ctx)
1236 t4_complete(&ctx->completion);
1237}
1238
1239
1240
1241
1242void cxgbe_filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl)
1243{
1244 struct filter_entry *f = NULL;
1245 unsigned int tid = GET_TID(rpl);
1246 int idx, max_fidx = adap->tids.nftids;
1247
1248
1249 if (adap->tids.ftid_tab) {
1250
1251 idx = tid - adap->tids.ftid_base;
1252 if (idx >= max_fidx)
1253 return;
1254
1255 f = &adap->tids.ftid_tab[idx];
1256 if (f->tid != tid)
1257 return;
1258 }
1259
1260
1261 if (f) {
1262 unsigned int ret = G_COOKIE(rpl->cookie);
1263 struct filter_ctx *ctx;
1264
1265
1266
1267
1268
1269 ctx = f->ctx;
1270 f->ctx = NULL;
1271
1272 if (ret == FW_FILTER_WR_FLT_ADDED) {
1273 f->pending = 0;
1274 f->valid = 1;
1275 if (ctx) {
1276 ctx->tid = f->tid;
1277 ctx->result = 0;
1278 }
1279 } else if (ret == FW_FILTER_WR_FLT_DELETED) {
1280
1281
1282
1283
1284 clear_filter(f);
1285 if (ctx)
1286 ctx->result = 0;
1287 } else {
1288
1289
1290
1291
1292 dev_warn(adap, "filter %u setup failed with error %u\n",
1293 idx, ret);
1294 clear_filter(f);
1295 if (ctx)
1296 ctx->result = -EINVAL;
1297 }
1298
1299 if (ctx)
1300 t4_complete(&ctx->completion);
1301 }
1302}
1303
1304
1305
1306
1307int cxgbe_get_filter_count(struct adapter *adapter, unsigned int fidx,
1308 u64 *c, int hash, bool get_byte)
1309{
1310 struct filter_entry *f;
1311 unsigned int tcb_base, tcbaddr;
1312 int ret;
1313
1314 tcb_base = t4_read_reg(adapter, A_TP_CMM_TCB_BASE);
1315 if (is_hashfilter(adapter) && hash) {
1316 if (fidx < adapter->tids.ntids) {
1317 f = adapter->tids.tid_tab[fidx];
1318 if (!f)
1319 return -EINVAL;
1320
1321 if (is_t5(adapter->params.chip)) {
1322 *c = 0;
1323 return 0;
1324 }
1325 tcbaddr = tcb_base + (fidx * TCB_SIZE);
1326 goto get_count;
1327 } else {
1328 return -ERANGE;
1329 }
1330 } else {
1331 if (fidx >= adapter->tids.nftids)
1332 return -ERANGE;
1333
1334 f = &adapter->tids.ftid_tab[fidx];
1335 if (!f->valid)
1336 return -EINVAL;
1337
1338 tcbaddr = tcb_base + f->tid * TCB_SIZE;
1339 }
1340
1341 f = &adapter->tids.ftid_tab[fidx];
1342 if (!f->valid)
1343 return -EINVAL;
1344
1345get_count:
1346 if (is_t5(adapter->params.chip) || is_t6(adapter->params.chip)) {
1347
1348
1349
1350
1351
1352
1353
1354 if (get_byte) {
1355 unsigned int word_offset = 4;
1356 __be64 be64_byte_count;
1357
1358 t4_os_lock(&adapter->win0_lock);
1359 ret = t4_memory_rw(adapter, MEMWIN_NIC, MEM_EDC0,
1360 tcbaddr +
1361 (word_offset * sizeof(__be32)),
1362 sizeof(be64_byte_count),
1363 &be64_byte_count,
1364 T4_MEMORY_READ);
1365 t4_os_unlock(&adapter->win0_lock);
1366 if (ret < 0)
1367 return ret;
1368 *c = be64_to_cpu(be64_byte_count);
1369 } else {
1370 unsigned int word_offset = 6;
1371 __be32 be32_count;
1372
1373 t4_os_lock(&adapter->win0_lock);
1374 ret = t4_memory_rw(adapter, MEMWIN_NIC, MEM_EDC0,
1375 tcbaddr +
1376 (word_offset * sizeof(__be32)),
1377 sizeof(be32_count), &be32_count,
1378 T4_MEMORY_READ);
1379 t4_os_unlock(&adapter->win0_lock);
1380 if (ret < 0)
1381 return ret;
1382 *c = (u64)be32_to_cpu(be32_count);
1383 }
1384 }
1385 return 0;
1386}
1387
1388
1389
1390
1391int cxgbe_clear_filter_count(struct adapter *adapter, unsigned int fidx,
1392 int hash, bool clear_byte)
1393{
1394 u64 tcb_mask = 0, tcb_val = 0;
1395 struct filter_entry *f = NULL;
1396 u16 tcb_word = 0;
1397
1398 if (is_hashfilter(adapter) && hash) {
1399 if (fidx >= adapter->tids.ntids)
1400 return -ERANGE;
1401
1402
1403 if (is_t5(adapter->params.chip))
1404 return 0;
1405
1406 f = adapter->tids.tid_tab[fidx];
1407 } else {
1408 if (fidx >= adapter->tids.nftids)
1409 return -ERANGE;
1410
1411 f = &adapter->tids.ftid_tab[fidx];
1412 }
1413
1414 if (!f || !f->valid)
1415 return -EINVAL;
1416
1417 tcb_word = W_TCB_TIMESTAMP;
1418 tcb_mask = V_TCB_TIMESTAMP(M_TCB_TIMESTAMP);
1419 tcb_val = V_TCB_TIMESTAMP(0ULL);
1420
1421 set_tcb_field(adapter, f->tid, tcb_word, tcb_mask, tcb_val, 1);
1422
1423 if (clear_byte) {
1424 tcb_word = W_TCB_T_RTT_TS_RECENT_AGE;
1425 tcb_mask =
1426 V_TCB_T_RTT_TS_RECENT_AGE(M_TCB_T_RTT_TS_RECENT_AGE) |
1427 V_TCB_T_RTSEQ_RECENT(M_TCB_T_RTSEQ_RECENT);
1428 tcb_val = V_TCB_T_RTT_TS_RECENT_AGE(0ULL) |
1429 V_TCB_T_RTSEQ_RECENT(0ULL);
1430
1431 set_tcb_field(adapter, f->tid, tcb_word, tcb_mask, tcb_val, 1);
1432 }
1433
1434 return 0;
1435}
1436
1437
1438
1439
1440void cxgbe_hash_del_filter_rpl(struct adapter *adap,
1441 const struct cpl_abort_rpl_rss *rpl)
1442{
1443 struct tid_info *t = &adap->tids;
1444 struct filter_entry *f;
1445 struct filter_ctx *ctx = NULL;
1446 unsigned int tid = GET_TID(rpl);
1447
1448 f = lookup_tid(t, tid);
1449 if (!f) {
1450 dev_warn(adap, "%s: could not find filter entry: %u\n",
1451 __func__, tid);
1452 return;
1453 }
1454
1455 ctx = f->ctx;
1456
1457 clear_filter(f);
1458 cxgbe_remove_tid(t, 0, tid, 0);
1459 t4_os_free(f);
1460
1461 if (ctx) {
1462 ctx->result = 0;
1463 t4_complete(&ctx->completion);
1464 }
1465}
1466