]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/cxgbe/t4_filter.c
cxgbe/t4_tom: Tweaks to some of the AIO related CTRs.
[FreeBSD/FreeBSD.git] / sys / dev / cxgbe / t4_filter.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2018 Chelsio Communications, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include "opt_inet.h"
32 #include "opt_inet6.h"
33
34 #include <sys/param.h>
35 #include <sys/eventhandler.h>
36 #include <sys/fnv_hash.h>
37 #include <sys/systm.h>
38 #include <sys/kernel.h>
39 #include <sys/module.h>
40 #include <sys/bus.h>
41 #include <sys/lock.h>
42 #include <sys/mutex.h>
43 #include <sys/rwlock.h>
44 #include <sys/socket.h>
45 #include <sys/sbuf.h>
46 #include <netinet/in.h>
47
48 #include "common/common.h"
49 #include "common/t4_msg.h"
50 #include "common/t4_regs.h"
51 #include "common/t4_regs_values.h"
52 #include "common/t4_tcb.h"
53 #include "t4_l2t.h"
54 #include "t4_smt.h"
55
56 struct filter_entry {
57         LIST_ENTRY(filter_entry) link_4t;
58         LIST_ENTRY(filter_entry) link_tid;
59
60         uint32_t valid:1;       /* filter allocated and valid */
61         uint32_t locked:1;      /* filter is administratively locked or busy */
62         uint32_t pending:1;     /* filter action is pending firmware reply */
63         int tid;                /* tid of the filter TCB */
64         struct l2t_entry *l2te; /* L2 table entry for DMAC rewrite */
65         struct smt_entry *smt;  /* SMT entry for SMAC rewrite */
66
67         struct t4_filter_specification fs;
68 };
69
70 static void free_filter_resources(struct filter_entry *);
71 static int get_tcamfilter(struct adapter *, struct t4_filter *);
72 static int get_hashfilter(struct adapter *, struct t4_filter *);
73 static int set_hashfilter(struct adapter *, struct t4_filter *, uint64_t,
74     struct l2t_entry *, struct smt_entry *);
75 static int del_hashfilter(struct adapter *, struct t4_filter *);
76 static int configure_hashfilter_tcb(struct adapter *, struct filter_entry *);
77
78 static inline bool
79 separate_hpfilter_region(struct adapter *sc)
80 {
81
82         return (chip_id(sc) >= CHELSIO_T6);
83 }
84
85 static inline uint32_t
86 hf_hashfn_4t(struct t4_filter_specification *fs)
87 {
88         struct t4_filter_tuple *ft = &fs->val;
89         uint32_t hash;
90
91         if (fs->type) {
92                 /* IPv6 */
93                 hash = fnv_32_buf(&ft->sip[0], 16, FNV1_32_INIT);
94                 hash = fnv_32_buf(&ft->dip[0], 16, hash);
95         } else {
96                 hash = fnv_32_buf(&ft->sip[0], 4, FNV1_32_INIT);
97                 hash = fnv_32_buf(&ft->dip[0], 4, hash);
98         }
99         hash = fnv_32_buf(&ft->sport, sizeof(ft->sport), hash);
100         hash = fnv_32_buf(&ft->dport, sizeof(ft->dport), hash);
101
102         return (hash);
103 }
104
105 static inline uint32_t
106 hf_hashfn_tid(int tid)
107 {
108
109         return (fnv_32_buf(&tid, sizeof(tid), FNV1_32_INIT));
110 }
111
112 static int
113 alloc_hftid_hash(struct tid_info *t, int flags)
114 {
115         int n;
116
117         MPASS(t->ntids > 0);
118         MPASS(t->hftid_hash_4t == NULL);
119         MPASS(t->hftid_hash_tid == NULL);
120
121         n = max(t->ntids / 1024, 16);
122         t->hftid_hash_4t = hashinit_flags(n, M_CXGBE, &t->hftid_4t_mask, flags);
123         if (t->hftid_hash_4t == NULL)
124                 return (ENOMEM);
125         t->hftid_hash_tid = hashinit_flags(n, M_CXGBE, &t->hftid_tid_mask,
126             flags);
127         if (t->hftid_hash_tid == NULL) {
128                 hashdestroy(t->hftid_hash_4t, M_CXGBE, t->hftid_4t_mask);
129                 t->hftid_hash_4t = NULL;
130                 return (ENOMEM);
131         }
132
133         mtx_init(&t->hftid_lock, "T4 hashfilters", 0, MTX_DEF);
134         cv_init(&t->hftid_cv, "t4hfcv");
135
136         return (0);
137 }
138
139 void
140 free_hftid_hash(struct tid_info *t)
141 {
142         struct filter_entry *f, *ftmp;
143         LIST_HEAD(, filter_entry) *head;
144         int i;
145 #ifdef INVARIANTS
146         int n = 0;
147 #endif
148
149         if (t->tids_in_use > 0) {
150                 /* Remove everything from the tid hash. */
151                 head = t->hftid_hash_tid;
152                 for (i = 0; i <= t->hftid_tid_mask; i++) {
153                         LIST_FOREACH_SAFE(f, &head[i], link_tid, ftmp) {
154                                 LIST_REMOVE(f, link_tid);
155                         }
156                 }
157
158                 /* Remove and then free each filter in the 4t hash. */
159                 head = t->hftid_hash_4t;
160                 for (i = 0; i <= t->hftid_4t_mask; i++) {
161                         LIST_FOREACH_SAFE(f, &head[i], link_4t, ftmp) {
162 #ifdef INVARIANTS
163                                 n += f->fs.type ? 2 : 1;
164 #endif
165                                 LIST_REMOVE(f, link_4t);
166                                 free(f, M_CXGBE);
167                         }
168                 }
169                 MPASS(t->tids_in_use == n);
170                 t->tids_in_use = 0;
171         }
172
173         if (t->hftid_hash_4t) {
174                 hashdestroy(t->hftid_hash_4t, M_CXGBE, t->hftid_4t_mask);
175                 t->hftid_hash_4t = NULL;
176         }
177         if (t->hftid_hash_tid) {
178                 hashdestroy(t->hftid_hash_tid, M_CXGBE, t->hftid_tid_mask);
179                 t->hftid_hash_tid = NULL;
180         }
181         if (mtx_initialized(&t->hftid_lock)) {
182                 mtx_destroy(&t->hftid_lock);
183                 cv_destroy(&t->hftid_cv);
184         }
185 }
186
187 static void
188 insert_hf(struct adapter *sc, struct filter_entry *f, uint32_t hash)
189 {
190         struct tid_info *t = &sc->tids;
191         LIST_HEAD(, filter_entry) *head = t->hftid_hash_4t;
192
193         MPASS(head != NULL);
194         if (hash == 0)
195                 hash = hf_hashfn_4t(&f->fs);
196         LIST_INSERT_HEAD(&head[hash & t->hftid_4t_mask], f, link_4t);
197         atomic_add_int(&t->tids_in_use, f->fs.type ? 2 : 1);
198 }
199
200 static void
201 insert_hftid(struct adapter *sc, struct filter_entry *f)
202 {
203         struct tid_info *t = &sc->tids;
204         LIST_HEAD(, filter_entry) *head = t->hftid_hash_tid;
205         uint32_t hash;
206
207         MPASS(f->tid >= t->tid_base);
208         MPASS(f->tid - t->tid_base < t->ntids);
209         mtx_assert(&t->hftid_lock, MA_OWNED);
210
211         hash = hf_hashfn_tid(f->tid);
212         LIST_INSERT_HEAD(&head[hash & t->hftid_tid_mask], f, link_tid);
213 }
214
215 static bool
216 filter_eq(struct t4_filter_specification *fs1,
217     struct t4_filter_specification *fs2)
218 {
219         int n;
220
221         MPASS(fs1->hash && fs2->hash);
222
223         if (fs1->type != fs2->type)
224                 return (false);
225
226         n = fs1->type ? 16 : 4;
227         if (bcmp(&fs1->val.sip[0], &fs2->val.sip[0], n) ||
228             bcmp(&fs1->val.dip[0], &fs2->val.dip[0], n) ||
229             fs1->val.sport != fs2->val.sport ||
230             fs1->val.dport != fs2->val.dport)
231                 return (false);
232
233         /*
234          * We know the masks are the same because all hashfilter masks have to
235          * conform to the global tp->hash_filter_mask and the driver has
236          * verified that already.
237          */
238
239         if ((fs1->mask.pfvf_vld || fs1->mask.ovlan_vld) &&
240             fs1->val.vnic != fs2->val.vnic)
241                 return (false);
242         if (fs1->mask.vlan_vld && fs1->val.vlan != fs2->val.vlan)
243                 return (false);
244         if (fs1->mask.macidx && fs1->val.macidx != fs2->val.macidx)
245                 return (false);
246         if (fs1->mask.frag && fs1->val.frag != fs2->val.frag)
247                 return (false);
248         if (fs1->mask.matchtype && fs1->val.matchtype != fs2->val.matchtype)
249                 return (false);
250         if (fs1->mask.iport && fs1->val.iport != fs2->val.iport)
251                 return (false);
252         if (fs1->mask.fcoe && fs1->val.fcoe != fs2->val.fcoe)
253                 return (false);
254         if (fs1->mask.proto && fs1->val.proto != fs2->val.proto)
255                 return (false);
256         if (fs1->mask.tos && fs1->val.tos != fs2->val.tos)
257                 return (false);
258         if (fs1->mask.ethtype && fs1->val.ethtype != fs2->val.ethtype)
259                 return (false);
260
261         return (true);
262 }
263
264 static struct filter_entry *
265 lookup_hf(struct adapter *sc, struct t4_filter_specification *fs, uint32_t hash)
266 {
267         struct tid_info *t = &sc->tids;
268         LIST_HEAD(, filter_entry) *head = t->hftid_hash_4t;
269         struct filter_entry *f;
270
271         mtx_assert(&t->hftid_lock, MA_OWNED);
272         MPASS(head != NULL);
273
274         if (hash == 0)
275                 hash = hf_hashfn_4t(fs);
276
277         LIST_FOREACH(f, &head[hash & t->hftid_4t_mask], link_4t) {
278                 if (filter_eq(&f->fs, fs))
279                         return (f);
280         }
281
282         return (NULL);
283 }
284
285 static struct filter_entry *
286 lookup_hftid(struct adapter *sc, int tid)
287 {
288         struct tid_info *t = &sc->tids;
289         LIST_HEAD(, filter_entry) *head = t->hftid_hash_tid;
290         struct filter_entry *f;
291         uint32_t hash;
292
293         mtx_assert(&t->hftid_lock, MA_OWNED);
294         MPASS(head != NULL);
295
296         hash = hf_hashfn_tid(tid);
297         LIST_FOREACH(f, &head[hash & t->hftid_tid_mask], link_tid) {
298                 if (f->tid == tid)
299                         return (f);
300         }
301
302         return (NULL);
303 }
304
305 static void
306 remove_hf(struct adapter *sc, struct filter_entry *f)
307 {
308         struct tid_info *t = &sc->tids;
309
310         mtx_assert(&t->hftid_lock, MA_OWNED);
311
312         LIST_REMOVE(f, link_4t);
313         atomic_subtract_int(&t->tids_in_use, f->fs.type ? 2 : 1);
314 }
315
316 static void
317 remove_hftid(struct adapter *sc, struct filter_entry *f)
318 {
319 #ifdef INVARIANTS
320         struct tid_info *t = &sc->tids;
321
322         mtx_assert(&t->hftid_lock, MA_OWNED);
323 #endif
324
325         LIST_REMOVE(f, link_tid);
326 }
327
328 static uint32_t
329 mode_to_fconf(uint32_t mode)
330 {
331         uint32_t fconf = 0;
332
333         if (mode & T4_FILTER_IP_FRAGMENT)
334                 fconf |= F_FRAGMENTATION;
335
336         if (mode & T4_FILTER_MPS_HIT_TYPE)
337                 fconf |= F_MPSHITTYPE;
338
339         if (mode & T4_FILTER_MAC_IDX)
340                 fconf |= F_MACMATCH;
341
342         if (mode & T4_FILTER_ETH_TYPE)
343                 fconf |= F_ETHERTYPE;
344
345         if (mode & T4_FILTER_IP_PROTO)
346                 fconf |= F_PROTOCOL;
347
348         if (mode & T4_FILTER_IP_TOS)
349                 fconf |= F_TOS;
350
351         if (mode & T4_FILTER_VLAN)
352                 fconf |= F_VLAN;
353
354         if (mode & T4_FILTER_VNIC)
355                 fconf |= F_VNIC_ID;
356
357         if (mode & T4_FILTER_PORT)
358                 fconf |= F_PORT;
359
360         if (mode & T4_FILTER_FCoE)
361                 fconf |= F_FCOE;
362
363         return (fconf);
364 }
365
366 static uint32_t
367 mode_to_iconf(uint32_t mode)
368 {
369
370         if (mode & T4_FILTER_IC_VNIC)
371                 return (F_VNIC);
372         return (0);
373 }
374
375 static int
376 check_fspec_against_fconf_iconf(struct adapter *sc,
377     struct t4_filter_specification *fs)
378 {
379         struct tp_params *tpp = &sc->params.tp;
380         uint32_t fconf = 0;
381
382         if (fs->val.frag || fs->mask.frag)
383                 fconf |= F_FRAGMENTATION;
384
385         if (fs->val.matchtype || fs->mask.matchtype)
386                 fconf |= F_MPSHITTYPE;
387
388         if (fs->val.macidx || fs->mask.macidx)
389                 fconf |= F_MACMATCH;
390
391         if (fs->val.ethtype || fs->mask.ethtype)
392                 fconf |= F_ETHERTYPE;
393
394         if (fs->val.proto || fs->mask.proto)
395                 fconf |= F_PROTOCOL;
396
397         if (fs->val.tos || fs->mask.tos)
398                 fconf |= F_TOS;
399
400         if (fs->val.vlan_vld || fs->mask.vlan_vld)
401                 fconf |= F_VLAN;
402
403         if (fs->val.ovlan_vld || fs->mask.ovlan_vld) {
404                 fconf |= F_VNIC_ID;
405                 if (tpp->ingress_config & F_VNIC)
406                         return (EINVAL);
407         }
408
409         if (fs->val.pfvf_vld || fs->mask.pfvf_vld) {
410                 fconf |= F_VNIC_ID;
411                 if ((tpp->ingress_config & F_VNIC) == 0)
412                         return (EINVAL);
413         }
414
415         if (fs->val.iport || fs->mask.iport)
416                 fconf |= F_PORT;
417
418         if (fs->val.fcoe || fs->mask.fcoe)
419                 fconf |= F_FCOE;
420
421         if ((tpp->vlan_pri_map | fconf) != tpp->vlan_pri_map)
422                 return (E2BIG);
423
424         return (0);
425 }
426
427 int
428 get_filter_mode(struct adapter *sc, uint32_t *mode)
429 {
430         struct tp_params *tp = &sc->params.tp;
431         uint64_t mask;
432
433         /* Non-zero incoming value in mode means "hashfilter mode". */
434         mask = *mode ? tp->hash_filter_mask : UINT64_MAX;
435
436         /* Always */
437         *mode = T4_FILTER_IPv4 | T4_FILTER_IPv6 | T4_FILTER_IP_SADDR |
438             T4_FILTER_IP_DADDR | T4_FILTER_IP_SPORT | T4_FILTER_IP_DPORT;
439
440 #define CHECK_FIELD(fconf_bit, field_shift, field_mask, mode_bit)  do { \
441         if (tp->vlan_pri_map & (fconf_bit)) { \
442                 MPASS(tp->field_shift >= 0); \
443                 if ((mask >> tp->field_shift & field_mask) == field_mask) \
444                 *mode |= (mode_bit); \
445         } \
446 } while (0)
447
448         CHECK_FIELD(F_FRAGMENTATION, frag_shift, M_FT_FRAGMENTATION, T4_FILTER_IP_FRAGMENT);
449         CHECK_FIELD(F_MPSHITTYPE, matchtype_shift, M_FT_MPSHITTYPE, T4_FILTER_MPS_HIT_TYPE);
450         CHECK_FIELD(F_MACMATCH, macmatch_shift, M_FT_MACMATCH, T4_FILTER_MAC_IDX);
451         CHECK_FIELD(F_ETHERTYPE, ethertype_shift, M_FT_ETHERTYPE, T4_FILTER_ETH_TYPE);
452         CHECK_FIELD(F_PROTOCOL, protocol_shift, M_FT_PROTOCOL, T4_FILTER_IP_PROTO);
453         CHECK_FIELD(F_TOS, tos_shift, M_FT_TOS, T4_FILTER_IP_TOS);
454         CHECK_FIELD(F_VLAN, vlan_shift, M_FT_VLAN, T4_FILTER_VLAN);
455         CHECK_FIELD(F_VNIC_ID, vnic_shift, M_FT_VNIC_ID , T4_FILTER_VNIC);
456         if (tp->ingress_config & F_VNIC)
457                 *mode |= T4_FILTER_IC_VNIC;
458         CHECK_FIELD(F_PORT, port_shift, M_FT_PORT , T4_FILTER_PORT);
459         CHECK_FIELD(F_FCOE, fcoe_shift, M_FT_FCOE , T4_FILTER_FCoE);
460 #undef CHECK_FIELD
461
462         return (0);
463 }
464
465 int
466 set_filter_mode(struct adapter *sc, uint32_t mode)
467 {
468         struct tp_params *tpp = &sc->params.tp;
469         uint32_t fconf, iconf;
470         int rc;
471
472         iconf = mode_to_iconf(mode);
473         if ((iconf ^ tpp->ingress_config) & F_VNIC) {
474                 /*
475                  * For now we just complain if A_TP_INGRESS_CONFIG is not
476                  * already set to the correct value for the requested filter
477                  * mode.  It's not clear if it's safe to write to this register
478                  * on the fly.  (And we trust the cached value of the register).
479                  *
480                  * check_fspec_against_fconf_iconf and other code that looks at
481                  * tp->vlan_pri_map and tp->ingress_config needs to be reviewed
482                  * thorougly before allowing dynamic filter mode changes.
483                  */
484                 return (EBUSY);
485         }
486
487         fconf = mode_to_fconf(mode);
488
489         rc = begin_synchronized_op(sc, NULL, HOLD_LOCK | SLEEP_OK | INTR_OK,
490             "t4setfm");
491         if (rc)
492                 return (rc);
493
494         if (sc->tids.ftids_in_use > 0 || sc->tids.hpftids_in_use > 0) {
495                 rc = EBUSY;
496                 goto done;
497         }
498
499 #ifdef TCP_OFFLOAD
500         if (uld_active(sc, ULD_TOM)) {
501                 rc = EBUSY;
502                 goto done;
503         }
504 #endif
505
506         rc = -t4_set_filter_mode(sc, fconf, true);
507 done:
508         end_synchronized_op(sc, LOCK_HELD);
509         return (rc);
510 }
511
512 static inline uint64_t
513 get_filter_hits(struct adapter *sc, uint32_t tid)
514 {
515         uint32_t tcb_addr;
516
517         tcb_addr = t4_read_reg(sc, A_TP_CMM_TCB_BASE) + tid * TCB_SIZE;
518
519         if (is_t4(sc)) {
520                 uint64_t hits;
521
522                 read_via_memwin(sc, 0, tcb_addr + 16, (uint32_t *)&hits, 8);
523                 return (be64toh(hits));
524         } else {
525                 uint32_t hits;
526
527                 read_via_memwin(sc, 0, tcb_addr + 24, &hits, 4);
528                 return (be32toh(hits));
529         }
530 }
531
532 int
533 get_filter(struct adapter *sc, struct t4_filter *t)
534 {
535         if (t->fs.hash)
536                 return (get_hashfilter(sc, t));
537         else
538                 return (get_tcamfilter(sc, t));
539 }
540
541 static int
542 set_tcamfilter(struct adapter *sc, struct t4_filter *t, struct l2t_entry *l2te,
543     struct smt_entry *smt)
544 {
545         struct filter_entry *f;
546         struct fw_filter2_wr *fwr;
547         u_int vnic_vld, vnic_vld_mask;
548         struct wrq_cookie cookie;
549         int i, rc, busy, locked;
550         u_int tid;
551         const int ntids = t->fs.type ? 4 : 1;
552
553         MPASS(!t->fs.hash);
554         /* Already validated against fconf, iconf */
555         MPASS((t->fs.val.pfvf_vld & t->fs.val.ovlan_vld) == 0);
556         MPASS((t->fs.mask.pfvf_vld & t->fs.mask.ovlan_vld) == 0);
557
558         if (separate_hpfilter_region(sc) && t->fs.prio) {
559                 MPASS(t->idx < sc->tids.nhpftids);
560                 f = &sc->tids.hpftid_tab[t->idx];
561                 tid = sc->tids.hpftid_base + t->idx;
562         } else {
563                 MPASS(t->idx < sc->tids.nftids);
564                 f = &sc->tids.ftid_tab[t->idx];
565                 tid = sc->tids.ftid_base + t->idx;
566         }
567         rc = busy = locked = 0;
568         mtx_lock(&sc->tids.ftid_lock);
569         for (i = 0; i < ntids; i++) {
570                 busy += f[i].pending + f[i].valid;
571                 locked += f[i].locked;
572         }
573         if (locked > 0)
574                 rc = EPERM;
575         else if (busy > 0)
576                 rc = EBUSY;
577         else {
578                 int len16;
579
580                 if (sc->params.filter2_wr_support)
581                         len16 = howmany(sizeof(struct fw_filter2_wr), 16);
582                 else
583                         len16 = howmany(sizeof(struct fw_filter_wr), 16);
584                 fwr = start_wrq_wr(&sc->sge.ctrlq[0], len16, &cookie);
585                 if (__predict_false(fwr == NULL))
586                         rc = ENOMEM;
587                 else {
588                         f->pending = 1;
589                         if (separate_hpfilter_region(sc) && t->fs.prio)
590                                 sc->tids.hpftids_in_use++;
591                         else
592                                 sc->tids.ftids_in_use++;
593                 }
594         }
595         mtx_unlock(&sc->tids.ftid_lock);
596         if (rc != 0)
597                 return (rc);
598
599         /*
600          * Can't fail now.  A set-filter WR will definitely be sent.
601          */
602
603         f->tid = tid;
604         f->fs = t->fs;
605         f->l2te = l2te;
606         f->smt = smt;
607
608         if (t->fs.val.pfvf_vld || t->fs.val.ovlan_vld)
609                 vnic_vld = 1;
610         else
611                 vnic_vld = 0;
612         if (t->fs.mask.pfvf_vld || t->fs.mask.ovlan_vld)
613                 vnic_vld_mask = 1;
614         else
615                 vnic_vld_mask = 0;
616
617         bzero(fwr, sizeof(*fwr));
618         if (sc->params.filter2_wr_support)
619                 fwr->op_pkd = htobe32(V_FW_WR_OP(FW_FILTER2_WR));
620         else
621                 fwr->op_pkd = htobe32(V_FW_WR_OP(FW_FILTER_WR));
622         fwr->len16_pkd = htobe32(FW_LEN16(*fwr));
623         fwr->tid_to_iq =
624             htobe32(V_FW_FILTER_WR_TID(f->tid) |
625                 V_FW_FILTER_WR_RQTYPE(f->fs.type) |
626                 V_FW_FILTER_WR_NOREPLY(0) |
627                 V_FW_FILTER_WR_IQ(f->fs.iq));
628         fwr->del_filter_to_l2tix =
629             htobe32(V_FW_FILTER_WR_RPTTID(f->fs.rpttid) |
630                 V_FW_FILTER_WR_DROP(f->fs.action == FILTER_DROP) |
631                 V_FW_FILTER_WR_DIRSTEER(f->fs.dirsteer) |
632                 V_FW_FILTER_WR_MASKHASH(f->fs.maskhash) |
633                 V_FW_FILTER_WR_DIRSTEERHASH(f->fs.dirsteerhash) |
634                 V_FW_FILTER_WR_LPBK(f->fs.action == FILTER_SWITCH) |
635                 V_FW_FILTER_WR_DMAC(f->fs.newdmac) |
636                 V_FW_FILTER_WR_SMAC(f->fs.newsmac) |
637                 V_FW_FILTER_WR_INSVLAN(f->fs.newvlan == VLAN_INSERT ||
638                     f->fs.newvlan == VLAN_REWRITE) |
639                 V_FW_FILTER_WR_RMVLAN(f->fs.newvlan == VLAN_REMOVE ||
640                     f->fs.newvlan == VLAN_REWRITE) |
641                 V_FW_FILTER_WR_HITCNTS(f->fs.hitcnts) |
642                 V_FW_FILTER_WR_TXCHAN(f->fs.eport) |
643                 V_FW_FILTER_WR_PRIO(f->fs.prio) |
644                 V_FW_FILTER_WR_L2TIX(f->l2te ? f->l2te->idx : 0));
645         fwr->ethtype = htobe16(f->fs.val.ethtype);
646         fwr->ethtypem = htobe16(f->fs.mask.ethtype);
647         fwr->frag_to_ovlan_vldm =
648             (V_FW_FILTER_WR_FRAG(f->fs.val.frag) |
649                 V_FW_FILTER_WR_FRAGM(f->fs.mask.frag) |
650                 V_FW_FILTER_WR_IVLAN_VLD(f->fs.val.vlan_vld) |
651                 V_FW_FILTER_WR_OVLAN_VLD(vnic_vld) |
652                 V_FW_FILTER_WR_IVLAN_VLDM(f->fs.mask.vlan_vld) |
653                 V_FW_FILTER_WR_OVLAN_VLDM(vnic_vld_mask));
654         fwr->smac_sel = 0;
655         fwr->rx_chan_rx_rpl_iq = htobe16(V_FW_FILTER_WR_RX_CHAN(0) |
656             V_FW_FILTER_WR_RX_RPL_IQ(sc->sge.fwq.abs_id));
657         fwr->maci_to_matchtypem =
658             htobe32(V_FW_FILTER_WR_MACI(f->fs.val.macidx) |
659                 V_FW_FILTER_WR_MACIM(f->fs.mask.macidx) |
660                 V_FW_FILTER_WR_FCOE(f->fs.val.fcoe) |
661                 V_FW_FILTER_WR_FCOEM(f->fs.mask.fcoe) |
662                 V_FW_FILTER_WR_PORT(f->fs.val.iport) |
663                 V_FW_FILTER_WR_PORTM(f->fs.mask.iport) |
664                 V_FW_FILTER_WR_MATCHTYPE(f->fs.val.matchtype) |
665                 V_FW_FILTER_WR_MATCHTYPEM(f->fs.mask.matchtype));
666         fwr->ptcl = f->fs.val.proto;
667         fwr->ptclm = f->fs.mask.proto;
668         fwr->ttyp = f->fs.val.tos;
669         fwr->ttypm = f->fs.mask.tos;
670         fwr->ivlan = htobe16(f->fs.val.vlan);
671         fwr->ivlanm = htobe16(f->fs.mask.vlan);
672         fwr->ovlan = htobe16(f->fs.val.vnic);
673         fwr->ovlanm = htobe16(f->fs.mask.vnic);
674         bcopy(f->fs.val.dip, fwr->lip, sizeof (fwr->lip));
675         bcopy(f->fs.mask.dip, fwr->lipm, sizeof (fwr->lipm));
676         bcopy(f->fs.val.sip, fwr->fip, sizeof (fwr->fip));
677         bcopy(f->fs.mask.sip, fwr->fipm, sizeof (fwr->fipm));
678         fwr->lp = htobe16(f->fs.val.dport);
679         fwr->lpm = htobe16(f->fs.mask.dport);
680         fwr->fp = htobe16(f->fs.val.sport);
681         fwr->fpm = htobe16(f->fs.mask.sport);
682         /* sma = 0 tells the fw to use SMAC_SEL for source MAC address */
683         bzero(fwr->sma, sizeof (fwr->sma));
684         if (sc->params.filter2_wr_support) {
685                 fwr->filter_type_swapmac =
686                     V_FW_FILTER2_WR_SWAPMAC(f->fs.swapmac);
687                 fwr->natmode_to_ulp_type =
688                     V_FW_FILTER2_WR_ULP_TYPE(f->fs.nat_mode ?
689                         ULP_MODE_TCPDDP : ULP_MODE_NONE) |
690                     V_FW_FILTER2_WR_NATFLAGCHECK(f->fs.nat_flag_chk) |
691                     V_FW_FILTER2_WR_NATMODE(f->fs.nat_mode);
692                 memcpy(fwr->newlip, f->fs.nat_dip, sizeof(fwr->newlip));
693                 memcpy(fwr->newfip, f->fs.nat_sip, sizeof(fwr->newfip));
694                 fwr->newlport = htobe16(f->fs.nat_dport);
695                 fwr->newfport = htobe16(f->fs.nat_sport);
696                 fwr->natseqcheck = htobe32(f->fs.nat_seq_chk);
697         }
698         commit_wrq_wr(&sc->sge.ctrlq[0], fwr, &cookie);
699
700         /* Wait for response. */
701         mtx_lock(&sc->tids.ftid_lock);
702         for (;;) {
703                 if (f->pending == 0) {
704                         rc = f->valid ? 0 : EIO;
705                         break;
706                 }
707                 if (cv_wait_sig(&sc->tids.ftid_cv, &sc->tids.ftid_lock) != 0) {
708                         rc = EINPROGRESS;
709                         break;
710                 }
711         }
712         mtx_unlock(&sc->tids.ftid_lock);
713         return (rc);
714 }
715
716 static int
717 hashfilter_ntuple(struct adapter *sc, const struct t4_filter_specification *fs,
718     uint64_t *ftuple)
719 {
720         struct tp_params *tp = &sc->params.tp;
721         uint64_t fmask;
722
723         *ftuple = fmask = 0;
724
725         /*
726          * Initialize each of the fields which we care about which are present
727          * in the Compressed Filter Tuple.
728          */
729         if (tp->vlan_shift >= 0 && fs->mask.vlan) {
730                 *ftuple |= (F_FT_VLAN_VLD | fs->val.vlan) << tp->vlan_shift;
731                 fmask |= M_FT_VLAN << tp->vlan_shift;
732         }
733
734         if (tp->port_shift >= 0 && fs->mask.iport) {
735                 *ftuple |= (uint64_t)fs->val.iport << tp->port_shift;
736                 fmask |= M_FT_PORT << tp->port_shift;
737         }
738
739         if (tp->protocol_shift >= 0 && fs->mask.proto) {
740                 *ftuple |= (uint64_t)fs->val.proto << tp->protocol_shift;
741                 fmask |= M_FT_PROTOCOL << tp->protocol_shift;
742         }
743
744         if (tp->tos_shift >= 0 && fs->mask.tos) {
745                 *ftuple |= (uint64_t)(fs->val.tos) << tp->tos_shift;
746                 fmask |= M_FT_TOS << tp->tos_shift;
747         }
748
749         if (tp->vnic_shift >= 0 && fs->mask.vnic) {
750                 /* F_VNIC in ingress config was already validated. */
751                 if (tp->ingress_config & F_VNIC)
752                         MPASS(fs->mask.pfvf_vld);
753                 else
754                         MPASS(fs->mask.ovlan_vld);
755
756                 *ftuple |= ((1ULL << 16) | fs->val.vnic) << tp->vnic_shift;
757                 fmask |= M_FT_VNIC_ID << tp->vnic_shift;
758         }
759
760         if (tp->macmatch_shift >= 0 && fs->mask.macidx) {
761                 *ftuple |= (uint64_t)(fs->val.macidx) << tp->macmatch_shift;
762                 fmask |= M_FT_MACMATCH << tp->macmatch_shift;
763         }
764
765         if (tp->ethertype_shift >= 0 && fs->mask.ethtype) {
766                 *ftuple |= (uint64_t)(fs->val.ethtype) << tp->ethertype_shift;
767                 fmask |= M_FT_ETHERTYPE << tp->ethertype_shift;
768         }
769
770         if (tp->matchtype_shift >= 0 && fs->mask.matchtype) {
771                 *ftuple |= (uint64_t)(fs->val.matchtype) << tp->matchtype_shift;
772                 fmask |= M_FT_MPSHITTYPE << tp->matchtype_shift;
773         }
774
775         if (tp->frag_shift >= 0 && fs->mask.frag) {
776                 *ftuple |= (uint64_t)(fs->val.frag) << tp->frag_shift;
777                 fmask |= M_FT_FRAGMENTATION << tp->frag_shift;
778         }
779
780         if (tp->fcoe_shift >= 0 && fs->mask.fcoe) {
781                 *ftuple |= (uint64_t)(fs->val.fcoe) << tp->fcoe_shift;
782                 fmask |= M_FT_FCOE << tp->fcoe_shift;
783         }
784
785         /* A hashfilter must conform to the filterMask. */
786         if (fmask != tp->hash_filter_mask)
787                 return (EINVAL);
788
789         return (0);
790 }
791
792 static bool
793 is_4tuple_specified(struct t4_filter_specification *fs)
794 {
795         int i;
796         const int n = fs->type ? 16 : 4;
797
798         if (fs->mask.sport != 0xffff || fs->mask.dport != 0xffff)
799                 return (false);
800
801         for (i = 0; i < n; i++) {
802                 if (fs->mask.sip[i] != 0xff)
803                         return (false);
804                 if (fs->mask.dip[i] != 0xff)
805                         return (false);
806         }
807
808         return (true);
809 }
810
811 int
812 set_filter(struct adapter *sc, struct t4_filter *t)
813 {
814         struct tid_info *ti = &sc->tids;
815         struct l2t_entry *l2te = NULL;
816         struct smt_entry *smt = NULL;
817         uint64_t ftuple;
818         int rc;
819
820         /*
821          * Basic filter checks first.
822          */
823
824         if (t->fs.hash) {
825                 if (!is_hashfilter(sc) || ti->ntids == 0)
826                         return (ENOTSUP);
827                 /* Hardware, not user, selects a tid for hashfilters. */
828                 if (t->idx != (uint32_t)-1)
829                         return (EINVAL);
830                 /* T5 can't count hashfilter hits. */
831                 if (is_t5(sc) && t->fs.hitcnts)
832                         return (EINVAL);
833                 if (!is_4tuple_specified(&t->fs))
834                         return (EINVAL);
835                 rc = hashfilter_ntuple(sc, &t->fs, &ftuple);
836                 if (rc != 0)
837                         return (rc);
838         } else {
839                 if (separate_hpfilter_region(sc) && t->fs.prio) {
840                         if (ti->nhpftids == 0)
841                                 return (ENOTSUP);
842                         if (t->idx >= ti->nhpftids)
843                                 return (EINVAL);
844                 } else {
845                         if (ti->nftids == 0)
846                                 return (ENOTSUP);
847                         if (t->idx >= ti->nftids)
848                                 return (EINVAL);
849                 }
850                 /* IPv6 filter idx must be 4 aligned */
851                 if (t->fs.type == 1 &&
852                     ((t->idx & 0x3) || t->idx + 4 >= ti->nftids))
853                         return (EINVAL);
854         }
855
856         /* T4 doesn't support VLAN tag removal or rewrite, swapmac, and NAT. */
857         if (is_t4(sc) && t->fs.action == FILTER_SWITCH &&
858             (t->fs.newvlan == VLAN_REMOVE || t->fs.newvlan == VLAN_REWRITE ||
859             t->fs.swapmac || t->fs.nat_mode))
860                 return (ENOTSUP);
861
862         if (t->fs.action == FILTER_SWITCH && t->fs.eport >= sc->params.nports)
863                 return (EINVAL);
864         if (t->fs.val.iport >= sc->params.nports)
865                 return (EINVAL);
866
867         /* Can't specify an iqid/rss_info if not steering. */
868         if (!t->fs.dirsteer && !t->fs.dirsteerhash && !t->fs.maskhash && t->fs.iq)
869                 return (EINVAL);
870
871         /* Validate against the global filter mode and ingress config */
872         rc = check_fspec_against_fconf_iconf(sc, &t->fs);
873         if (rc != 0)
874                 return (rc);
875
876         /*
877          * Basic checks passed.  Make sure the queues and tid tables are setup.
878          */
879
880         rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4setf");
881         if (rc)
882                 return (rc);
883         if (!(sc->flags & FULL_INIT_DONE) &&
884             ((rc = adapter_full_init(sc)) != 0)) {
885                 end_synchronized_op(sc, 0);
886                 return (rc);
887         }
888         if (t->fs.hash) {
889                 if (__predict_false(ti->hftid_hash_4t == NULL)) {
890                         rc = alloc_hftid_hash(&sc->tids, HASH_NOWAIT);
891                         if (rc != 0)
892                                 goto done;
893                 }
894                 if (__predict_false(sc->tids.atid_tab == NULL)) {
895                         rc = alloc_atid_tab(&sc->tids, M_NOWAIT);
896                         if (rc != 0)
897                                 goto done;
898                 }
899         } else if (separate_hpfilter_region(sc) && t->fs.prio &&
900             __predict_false(ti->hpftid_tab == NULL)) {
901                 MPASS(ti->nhpftids != 0);
902                 KASSERT(ti->hpftids_in_use == 0,
903                     ("%s: no memory allocated but hpftids_in_use is %u",
904                     __func__, ti->hpftids_in_use));
905                 ti->hpftid_tab = malloc(sizeof(struct filter_entry) *
906                     ti->nhpftids, M_CXGBE, M_NOWAIT | M_ZERO);
907                 if (ti->hpftid_tab == NULL) {
908                         rc = ENOMEM;
909                         goto done;
910                 }
911                 if (!mtx_initialized(&sc->tids.ftid_lock)) {
912                         mtx_init(&ti->ftid_lock, "T4 filters", 0, MTX_DEF);
913                         cv_init(&ti->ftid_cv, "t4fcv");
914                 }
915         } else if (__predict_false(ti->ftid_tab == NULL)) {
916                 MPASS(ti->nftids != 0);
917                 KASSERT(ti->ftids_in_use == 0,
918                     ("%s: no memory allocated but ftids_in_use is %u",
919                     __func__, ti->ftids_in_use));
920                 ti->ftid_tab = malloc(sizeof(struct filter_entry) * ti->nftids,
921                     M_CXGBE, M_NOWAIT | M_ZERO);
922                 if (ti->ftid_tab == NULL) {
923                         rc = ENOMEM;
924                         goto done;
925                 }
926                 if (!mtx_initialized(&sc->tids.ftid_lock)) {
927                         mtx_init(&ti->ftid_lock, "T4 filters", 0, MTX_DEF);
928                         cv_init(&ti->ftid_cv, "t4fcv");
929                 }
930         }
931 done:
932         end_synchronized_op(sc, 0);
933         if (rc != 0)
934                 return (rc);
935
936         /*
937          * Allocate L2T entry, SMT entry, etc.
938          */
939
940         if (t->fs.newdmac || t->fs.newvlan) {
941                 /* This filter needs an L2T entry; allocate one. */
942                 l2te = t4_l2t_alloc_switching(sc, t->fs.vlan, t->fs.eport,
943                     t->fs.dmac);
944                 if (__predict_false(l2te == NULL)) {
945                         rc = EAGAIN;
946                         goto error;
947                 }
948         }
949
950         if (t->fs.newsmac) {
951                 /* This filter needs an SMT entry; allocate one. */
952                 smt = t4_smt_alloc_switching(sc->smt, t->fs.smac);
953                 if (__predict_false(smt == NULL)) {
954                         rc = EAGAIN;
955                         goto error;
956                 }
957                 rc = t4_smt_set_switching(sc, smt, 0x0, t->fs.smac);
958                 if (rc)
959                         goto error;
960         }
961
962         if (t->fs.hash)
963                 rc = set_hashfilter(sc, t, ftuple, l2te, smt);
964         else
965                 rc = set_tcamfilter(sc, t, l2te, smt);
966
967         if (rc != 0 && rc != EINPROGRESS) {
968 error:
969                 if (l2te)
970                         t4_l2t_release(l2te);
971                 if (smt)
972                         t4_smt_release(smt);
973         }
974         return (rc);
975 }
976
977 static int
978 del_tcamfilter(struct adapter *sc, struct t4_filter *t)
979 {
980         struct filter_entry *f;
981         struct fw_filter_wr *fwr;
982         struct wrq_cookie cookie;
983         int rc, nfilters;
984 #ifdef INVARIANTS
985         u_int tid_base;
986 #endif
987
988         mtx_lock(&sc->tids.ftid_lock);
989         if (separate_hpfilter_region(sc) && t->fs.prio) {
990                 nfilters = sc->tids.nhpftids;
991                 f = sc->tids.hpftid_tab;
992 #ifdef INVARIANTS
993                 tid_base = sc->tids.hpftid_base;
994 #endif
995         } else {
996                 nfilters = sc->tids.nftids;
997                 f = sc->tids.ftid_tab;
998 #ifdef INVARIANTS
999                 tid_base = sc->tids.ftid_base;
1000 #endif
1001         }
1002         MPASS(f != NULL);       /* Caller checked this. */
1003         if (t->idx >= nfilters) {
1004                 rc = EINVAL;
1005                 goto done;
1006         }
1007         f += t->idx;
1008
1009         if (f->locked) {
1010                 rc = EPERM;
1011                 goto done;
1012         }
1013         if (f->pending) {
1014                 rc = EBUSY;
1015                 goto done;
1016         }
1017         if (f->valid == 0) {
1018                 rc = EINVAL;
1019                 goto done;
1020         }
1021         MPASS(f->tid == tid_base + t->idx);
1022         fwr = start_wrq_wr(&sc->sge.ctrlq[0], howmany(sizeof(*fwr), 16), &cookie);
1023         if (fwr == NULL) {
1024                 rc = ENOMEM;
1025                 goto done;
1026         }
1027
1028         bzero(fwr, sizeof (*fwr));
1029         t4_mk_filtdelwr(f->tid, fwr, sc->sge.fwq.abs_id);
1030         f->pending = 1;
1031         commit_wrq_wr(&sc->sge.ctrlq[0], fwr, &cookie);
1032         t->fs = f->fs;  /* extra info for the caller */
1033
1034         for (;;) {
1035                 if (f->pending == 0) {
1036                         rc = f->valid ? EIO : 0;
1037                         break;
1038                 }
1039                 if (cv_wait_sig(&sc->tids.ftid_cv, &sc->tids.ftid_lock) != 0) {
1040                         rc = EINPROGRESS;
1041                         break;
1042                 }
1043         }
1044 done:
1045         mtx_unlock(&sc->tids.ftid_lock);
1046         return (rc);
1047 }
1048
1049 int
1050 del_filter(struct adapter *sc, struct t4_filter *t)
1051 {
1052
1053         /* No filters possible if not initialized yet. */
1054         if (!(sc->flags & FULL_INIT_DONE))
1055                 return (EINVAL);
1056
1057         /*
1058          * The checks for tid tables ensure that the locks that del_* will reach
1059          * for are initialized.
1060          */
1061         if (t->fs.hash) {
1062                 if (sc->tids.hftid_hash_4t != NULL)
1063                         return (del_hashfilter(sc, t));
1064         } else if (separate_hpfilter_region(sc) && t->fs.prio) {
1065                 if (sc->tids.hpftid_tab != NULL)
1066                         return (del_tcamfilter(sc, t));
1067         } else {
1068                 if (sc->tids.ftid_tab != NULL)
1069                         return (del_tcamfilter(sc, t));
1070         }
1071
1072         return (EINVAL);
1073 }
1074
1075 /*
1076  * Release secondary resources associated with the filter.
1077  */
1078 static void
1079 free_filter_resources(struct filter_entry *f)
1080 {
1081
1082         if (f->l2te) {
1083                 t4_l2t_release(f->l2te);
1084                 f->l2te = NULL;
1085         }
1086         if (f->smt) {
1087                 t4_smt_release(f->smt);
1088                 f->smt = NULL;
1089         }
1090 }
1091
1092 static int
1093 set_tcb_field(struct adapter *sc, u_int tid, uint16_t word, uint64_t mask,
1094     uint64_t val, int no_reply)
1095 {
1096         struct wrq_cookie cookie;
1097         struct cpl_set_tcb_field *req;
1098
1099         req = start_wrq_wr(&sc->sge.ctrlq[0], howmany(sizeof(*req), 16), &cookie);
1100         if (req == NULL)
1101                 return (ENOMEM);
1102         bzero(req, sizeof(*req));
1103         INIT_TP_WR_MIT_CPL(req, CPL_SET_TCB_FIELD, tid);
1104         if (no_reply == 0) {
1105                 req->reply_ctrl = htobe16(V_QUEUENO(sc->sge.fwq.abs_id) |
1106                     V_NO_REPLY(0));
1107         } else
1108                 req->reply_ctrl = htobe16(V_NO_REPLY(1));
1109         req->word_cookie = htobe16(V_WORD(word) | V_COOKIE(CPL_COOKIE_HASHFILTER));
1110         req->mask = htobe64(mask);
1111         req->val = htobe64(val);
1112         commit_wrq_wr(&sc->sge.ctrlq[0], req, &cookie);
1113
1114         return (0);
1115 }
1116
1117 /* Set one of the t_flags bits in the TCB. */
1118 static inline int
1119 set_tcb_tflag(struct adapter *sc, int tid, u_int bit_pos, u_int val,
1120     u_int no_reply)
1121 {
1122
1123         return (set_tcb_field(sc, tid,  W_TCB_T_FLAGS, 1ULL << bit_pos,
1124             (uint64_t)val << bit_pos, no_reply));
1125 }
1126
1127 int
1128 t4_filter_rpl(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
1129 {
1130         struct adapter *sc = iq->adapter;
1131         const struct cpl_set_tcb_rpl *rpl = (const void *)(rss + 1);
1132         u_int tid = GET_TID(rpl);
1133         u_int rc, idx;
1134         struct filter_entry *f;
1135
1136         KASSERT(m == NULL, ("%s: payload with opcode %02x", __func__,
1137             rss->opcode));
1138
1139
1140         if (is_hpftid(sc, tid)) {
1141                 idx = tid - sc->tids.hpftid_base;
1142                 f = &sc->tids.hpftid_tab[idx];
1143         } else if (is_ftid(sc, tid)) {
1144                 idx = tid - sc->tids.ftid_base;
1145                 f = &sc->tids.ftid_tab[idx];
1146         } else
1147                 panic("%s: FW reply for invalid TID %d.", __func__, tid);
1148
1149         MPASS(f->tid == tid);
1150         rc = G_COOKIE(rpl->cookie);
1151
1152         mtx_lock(&sc->tids.ftid_lock);
1153         KASSERT(f->pending, ("%s: reply %d for filter[%u] that isn't pending.",
1154             __func__, rc, tid));
1155         switch(rc) {
1156         case FW_FILTER_WR_FLT_ADDED:
1157                 /* set-filter succeeded */
1158                 f->valid = 1;
1159                 if (f->fs.newsmac) {
1160                         MPASS(f->smt != NULL);
1161                         set_tcb_tflag(sc, f->tid, S_TF_CCTRL_CWR, 1, 1);
1162                         set_tcb_field(sc, f->tid, W_TCB_SMAC_SEL,
1163                             V_TCB_SMAC_SEL(M_TCB_SMAC_SEL),
1164                             V_TCB_SMAC_SEL(f->smt->idx), 1);
1165                         /* XXX: wait for reply to TCB update before !pending */
1166                 }
1167                 break;
1168         case FW_FILTER_WR_FLT_DELETED:
1169                 /* del-filter succeeded */
1170                 MPASS(f->valid == 1);
1171                 f->valid = 0;
1172                 /* Fall through */
1173         case FW_FILTER_WR_SMT_TBL_FULL:
1174                 /* set-filter failed due to lack of SMT space. */
1175                 MPASS(f->valid == 0);
1176                 free_filter_resources(f);
1177                 if (separate_hpfilter_region(sc) && f->fs.prio)
1178                         sc->tids.hpftids_in_use--;
1179                 else
1180                         sc->tids.ftids_in_use--;
1181                 break;
1182         case FW_FILTER_WR_SUCCESS:
1183         case FW_FILTER_WR_EINVAL:
1184         default:
1185                 panic("%s: unexpected reply %d for filter[%d].", __func__, rc,
1186                     idx);
1187         }
1188         f->pending = 0;
1189         cv_broadcast(&sc->tids.ftid_cv);
1190         mtx_unlock(&sc->tids.ftid_lock);
1191
1192         return (0);
1193 }
1194
1195 /*
1196  * This is the reply to the Active Open that created the filter.  Additional TCB
1197  * updates may be required to complete the filter configuration.
1198  */
1199 int
1200 t4_hashfilter_ao_rpl(struct sge_iq *iq, const struct rss_header *rss,
1201     struct mbuf *m)
1202 {
1203         struct adapter *sc = iq->adapter;
1204         const struct cpl_act_open_rpl *cpl = (const void *)(rss + 1);
1205         u_int atid = G_TID_TID(G_AOPEN_ATID(be32toh(cpl->atid_status)));
1206         u_int status = G_AOPEN_STATUS(be32toh(cpl->atid_status));
1207         struct filter_entry *f = lookup_atid(sc, atid);
1208
1209         KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__));
1210
1211         mtx_lock(&sc->tids.hftid_lock);
1212         KASSERT(f->pending, ("%s: hashfilter[%p] isn't pending.", __func__, f));
1213         KASSERT(f->tid == -1, ("%s: hashfilter[%p] has tid %d already.",
1214             __func__, f, f->tid));
1215         if (status == CPL_ERR_NONE) {
1216                 f->tid = GET_TID(cpl);
1217                 MPASS(lookup_hftid(sc, f->tid) == NULL);
1218                 insert_hftid(sc, f);
1219                 /*
1220                  * Leave the filter pending until it is fully set up, which will
1221                  * be indicated by the reply to the last TCB update.  No need to
1222                  * unblock the ioctl thread either.
1223                  */
1224                 if (configure_hashfilter_tcb(sc, f) == EINPROGRESS)
1225                         goto done;
1226                 f->valid = 1;
1227                 f->pending = 0;
1228         } else {
1229                 /* provide errno instead of tid to ioctl */
1230                 f->tid = act_open_rpl_status_to_errno(status);
1231                 f->valid = 0;
1232                 f->pending = 0;
1233                 if (act_open_has_tid(status))
1234                         release_tid(sc, GET_TID(cpl), &sc->sge.ctrlq[0]);
1235                 free_filter_resources(f);
1236                 remove_hf(sc, f);
1237                 if (f->locked == 0)
1238                         free(f, M_CXGBE);
1239         }
1240         cv_broadcast(&sc->tids.hftid_cv);
1241 done:
1242         mtx_unlock(&sc->tids.hftid_lock);
1243
1244         free_atid(sc, atid);
1245         return (0);
1246 }
1247
1248 int
1249 t4_hashfilter_tcb_rpl(struct sge_iq *iq, const struct rss_header *rss,
1250     struct mbuf *m)
1251 {
1252         struct adapter *sc = iq->adapter;
1253         const struct cpl_set_tcb_rpl *rpl = (const void *)(rss + 1);
1254         u_int tid = GET_TID(rpl);
1255         struct filter_entry *f;
1256
1257         mtx_lock(&sc->tids.hftid_lock);
1258         f = lookup_hftid(sc, tid);
1259         KASSERT(f->tid == tid, ("%s: filter tid mismatch", __func__));
1260         KASSERT(f->pending, ("%s: hashfilter %p [%u] isn't pending.", __func__,
1261             f, tid));
1262         KASSERT(f->valid == 0, ("%s: hashfilter %p [%u] is valid already.",
1263             __func__, f, tid));
1264         f->pending = 0;
1265         if (rpl->status == 0) {
1266                 f->valid = 1;
1267         } else {
1268                 f->tid = EIO;
1269                 f->valid = 0;
1270                 free_filter_resources(f);
1271                 remove_hftid(sc, f);
1272                 remove_hf(sc, f);
1273                 release_tid(sc, tid, &sc->sge.ctrlq[0]);
1274                 if (f->locked == 0)
1275                         free(f, M_CXGBE);
1276         }
1277         cv_broadcast(&sc->tids.hftid_cv);
1278         mtx_unlock(&sc->tids.hftid_lock);
1279
1280         return (0);
1281 }
1282
1283 int
1284 t4_del_hashfilter_rpl(struct sge_iq *iq, const struct rss_header *rss,
1285     struct mbuf *m)
1286 {
1287         struct adapter *sc = iq->adapter;
1288         const struct cpl_abort_rpl_rss *cpl = (const void *)(rss + 1);
1289         unsigned int tid = GET_TID(cpl);
1290         struct filter_entry *f;
1291
1292         mtx_lock(&sc->tids.hftid_lock);
1293         f = lookup_hftid(sc, tid);
1294         KASSERT(f->tid == tid, ("%s: filter tid mismatch", __func__));
1295         KASSERT(f->pending, ("%s: hashfilter %p [%u] isn't pending.", __func__,
1296             f, tid));
1297         KASSERT(f->valid, ("%s: hashfilter %p [%u] isn't valid.", __func__, f,
1298             tid));
1299         f->pending = 0;
1300         if (cpl->status == 0) {
1301                 f->valid = 0;
1302                 free_filter_resources(f);
1303                 remove_hftid(sc, f);
1304                 remove_hf(sc, f);
1305                 release_tid(sc, tid, &sc->sge.ctrlq[0]);
1306                 if (f->locked == 0)
1307                         free(f, M_CXGBE);
1308         }
1309         cv_broadcast(&sc->tids.hftid_cv);
1310         mtx_unlock(&sc->tids.hftid_lock);
1311
1312         return (0);
1313 }
1314
1315 static int
1316 get_tcamfilter(struct adapter *sc, struct t4_filter *t)
1317 {
1318         int i, nfilters;
1319         struct filter_entry *f;
1320         u_int in_use;
1321 #ifdef INVARIANTS
1322         u_int tid_base;
1323 #endif
1324
1325         MPASS(!t->fs.hash);
1326
1327         if (separate_hpfilter_region(sc) && t->fs.prio) {
1328                 nfilters = sc->tids.nhpftids;
1329                 f = sc->tids.hpftid_tab;
1330                 in_use = sc->tids.hpftids_in_use;
1331 #ifdef INVARIANTS
1332                 tid_base = sc->tids.hpftid_base;
1333 #endif
1334         } else {
1335                 nfilters = sc->tids.nftids;
1336                 f = sc->tids.ftid_tab;
1337                 in_use = sc->tids.ftids_in_use;
1338 #ifdef INVARIANTS
1339                 tid_base = sc->tids.ftid_base;
1340 #endif
1341         }
1342
1343         if (in_use == 0 || f == NULL || t->idx >= nfilters) {
1344                 t->idx = 0xffffffff;
1345                 return (0);
1346         }
1347
1348         f += t->idx;
1349         mtx_lock(&sc->tids.ftid_lock);
1350         for (i = t->idx; i < nfilters; i++, f++) {
1351                 if (f->valid) {
1352                         MPASS(f->tid == tid_base + i);
1353                         t->idx = i;
1354                         t->l2tidx = f->l2te ? f->l2te->idx : 0;
1355                         t->smtidx = f->smt ? f->smt->idx : 0;
1356                         if (f->fs.hitcnts)
1357                                 t->hits = get_filter_hits(sc, f->tid);
1358                         else
1359                                 t->hits = UINT64_MAX;
1360                         t->fs = f->fs;
1361
1362                         goto done;
1363                 }
1364         }
1365         t->idx = 0xffffffff;
1366 done:
1367         mtx_unlock(&sc->tids.ftid_lock);
1368         return (0);
1369 }
1370
1371 static int
1372 get_hashfilter(struct adapter *sc, struct t4_filter *t)
1373 {
1374         struct tid_info *ti = &sc->tids;
1375         int tid;
1376         struct filter_entry *f;
1377         const int inv_tid = ti->ntids + ti->tid_base;
1378
1379         MPASS(t->fs.hash);
1380
1381         if (ti->tids_in_use == 0 || ti->hftid_hash_tid == NULL ||
1382             t->idx >= inv_tid) {
1383                 t->idx = 0xffffffff;
1384                 return (0);
1385         }
1386         if (t->idx < ti->tid_base)
1387                 t->idx = ti->tid_base;
1388
1389         mtx_lock(&ti->hftid_lock);
1390         for (tid = t->idx; tid < inv_tid; tid++) {
1391                 f = lookup_hftid(sc, tid);
1392                 if (f != NULL && f->valid) {
1393                         t->idx = tid;
1394                         t->l2tidx = f->l2te ? f->l2te->idx : 0;
1395                         t->smtidx = f->smt ? f->smt->idx : 0;
1396                         if (f->fs.hitcnts)
1397                                 t->hits = get_filter_hits(sc, tid);
1398                         else
1399                                 t->hits = UINT64_MAX;
1400                         t->fs = f->fs;
1401
1402                         goto done;
1403                 }
1404         }
1405         t->idx = 0xffffffff;
1406 done:
1407         mtx_unlock(&ti->hftid_lock);
1408         return (0);
1409 }
1410
1411 static void
1412 mk_act_open_req6(struct adapter *sc, struct filter_entry *f, int atid,
1413     uint64_t ftuple, struct cpl_act_open_req6 *cpl)
1414 {
1415         struct cpl_t5_act_open_req6 *cpl5 = (void *)cpl;
1416         struct cpl_t6_act_open_req6 *cpl6 = (void *)cpl;
1417
1418         /* Review changes to CPL after cpl_t6_act_open_req if this goes off. */
1419         MPASS(chip_id(sc) >= CHELSIO_T5 && chip_id(sc) <= CHELSIO_T6);
1420         MPASS(atid >= 0);
1421
1422         if (chip_id(sc) == CHELSIO_T5) {
1423                 INIT_TP_WR(cpl5, 0);
1424         } else {
1425                 INIT_TP_WR(cpl6, 0);
1426                 cpl6->rsvd2 = 0;
1427                 cpl6->opt3 = 0;
1428         }
1429
1430         OPCODE_TID(cpl) = htobe32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ6,
1431             V_TID_QID(sc->sge.fwq.abs_id) | V_TID_TID(atid) |
1432             V_TID_COOKIE(CPL_COOKIE_HASHFILTER)));
1433         cpl->local_port = htobe16(f->fs.val.dport);
1434         cpl->peer_port = htobe16(f->fs.val.sport);
1435         cpl->local_ip_hi = *(uint64_t *)(&f->fs.val.dip);
1436         cpl->local_ip_lo = *(((uint64_t *)&f->fs.val.dip) + 1);
1437         cpl->peer_ip_hi = *(uint64_t *)(&f->fs.val.sip);
1438         cpl->peer_ip_lo = *(((uint64_t *)&f->fs.val.sip) + 1);
1439         cpl->opt0 = htobe64(V_NAGLE(f->fs.newvlan == VLAN_REMOVE ||
1440             f->fs.newvlan == VLAN_REWRITE) | V_DELACK(f->fs.hitcnts) |
1441             V_L2T_IDX(f->l2te ? f->l2te->idx : 0) | V_TX_CHAN(f->fs.eport) |
1442             V_NO_CONG(f->fs.rpttid) |
1443             V_ULP_MODE(f->fs.nat_mode ? ULP_MODE_TCPDDP : ULP_MODE_NONE) |
1444             F_TCAM_BYPASS | F_NON_OFFLOAD);
1445
1446         cpl6->params = htobe64(V_FILTER_TUPLE(ftuple));
1447         cpl6->opt2 = htobe32(F_RSS_QUEUE_VALID | V_RSS_QUEUE(f->fs.iq) |
1448             V_TX_QUEUE(f->fs.nat_mode) | V_WND_SCALE_EN(f->fs.nat_flag_chk) |
1449             V_RX_FC_DISABLE(f->fs.nat_seq_chk ? 1 : 0) | F_T5_OPT_2_VALID |
1450             F_RX_CHANNEL | V_SACK_EN(f->fs.swapmac) |
1451             V_CONG_CNTRL((f->fs.action == FILTER_DROP) | (f->fs.dirsteer << 1)) |
1452             V_PACE(f->fs.maskhash | (f->fs.dirsteerhash << 1)));
1453 }
1454
1455 static void
1456 mk_act_open_req(struct adapter *sc, struct filter_entry *f, int atid,
1457     uint64_t ftuple, struct cpl_act_open_req *cpl)
1458 {
1459         struct cpl_t5_act_open_req *cpl5 = (void *)cpl;
1460         struct cpl_t6_act_open_req *cpl6 = (void *)cpl;
1461
1462         /* Review changes to CPL after cpl_t6_act_open_req if this goes off. */
1463         MPASS(chip_id(sc) >= CHELSIO_T5 && chip_id(sc) <= CHELSIO_T6);
1464         MPASS(atid >= 0);
1465
1466         if (chip_id(sc) == CHELSIO_T5) {
1467                 INIT_TP_WR(cpl5, 0);
1468         } else {
1469                 INIT_TP_WR(cpl6, 0);
1470                 cpl6->rsvd2 = 0;
1471                 cpl6->opt3 = 0;
1472         }
1473
1474         OPCODE_TID(cpl) = htobe32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
1475             V_TID_QID(sc->sge.fwq.abs_id) | V_TID_TID(atid) |
1476             V_TID_COOKIE(CPL_COOKIE_HASHFILTER)));
1477         cpl->local_port = htobe16(f->fs.val.dport);
1478         cpl->peer_port = htobe16(f->fs.val.sport);
1479         cpl->local_ip = f->fs.val.dip[0] | f->fs.val.dip[1] << 8 |
1480             f->fs.val.dip[2] << 16 | f->fs.val.dip[3] << 24;
1481         cpl->peer_ip = f->fs.val.sip[0] | f->fs.val.sip[1] << 8 |
1482                 f->fs.val.sip[2] << 16 | f->fs.val.sip[3] << 24;
1483         cpl->opt0 = htobe64(V_NAGLE(f->fs.newvlan == VLAN_REMOVE ||
1484             f->fs.newvlan == VLAN_REWRITE) | V_DELACK(f->fs.hitcnts) |
1485             V_L2T_IDX(f->l2te ? f->l2te->idx : 0) | V_TX_CHAN(f->fs.eport) |
1486             V_NO_CONG(f->fs.rpttid) |
1487             V_ULP_MODE(f->fs.nat_mode ? ULP_MODE_TCPDDP : ULP_MODE_NONE) |
1488             F_TCAM_BYPASS | F_NON_OFFLOAD);
1489
1490         cpl6->params = htobe64(V_FILTER_TUPLE(ftuple));
1491         cpl6->opt2 = htobe32(F_RSS_QUEUE_VALID | V_RSS_QUEUE(f->fs.iq) |
1492             V_TX_QUEUE(f->fs.nat_mode) | V_WND_SCALE_EN(f->fs.nat_flag_chk) |
1493             V_RX_FC_DISABLE(f->fs.nat_seq_chk ? 1 : 0) | F_T5_OPT_2_VALID |
1494             F_RX_CHANNEL | V_SACK_EN(f->fs.swapmac) |
1495             V_CONG_CNTRL((f->fs.action == FILTER_DROP) | (f->fs.dirsteer << 1)) |
1496             V_PACE(f->fs.maskhash | (f->fs.dirsteerhash << 1)));
1497 }
1498
1499 static int
1500 act_open_cpl_len16(struct adapter *sc, int isipv6)
1501 {
1502         int idx;
1503         static const int sz_table[3][2] = {
1504                 {
1505                         howmany(sizeof (struct cpl_act_open_req), 16),
1506                         howmany(sizeof (struct cpl_act_open_req6), 16)
1507                 },
1508                 {
1509                         howmany(sizeof (struct cpl_t5_act_open_req), 16),
1510                         howmany(sizeof (struct cpl_t5_act_open_req6), 16)
1511                 },
1512                 {
1513                         howmany(sizeof (struct cpl_t6_act_open_req), 16),
1514                         howmany(sizeof (struct cpl_t6_act_open_req6), 16)
1515                 },
1516         };
1517
1518         MPASS(chip_id(sc) >= CHELSIO_T4);
1519         idx = min(chip_id(sc) - CHELSIO_T4, 2);
1520
1521         return (sz_table[idx][!!isipv6]);
1522 }
1523
1524 static int
1525 set_hashfilter(struct adapter *sc, struct t4_filter *t, uint64_t ftuple,
1526     struct l2t_entry *l2te, struct smt_entry *smt)
1527 {
1528         void *wr;
1529         struct wrq_cookie cookie;
1530         struct filter_entry *f;
1531         int rc, atid = -1;
1532         uint32_t hash;
1533
1534         MPASS(t->fs.hash);
1535         /* Already validated against fconf, iconf */
1536         MPASS((t->fs.val.pfvf_vld & t->fs.val.ovlan_vld) == 0);
1537         MPASS((t->fs.mask.pfvf_vld & t->fs.mask.ovlan_vld) == 0);
1538
1539         hash = hf_hashfn_4t(&t->fs);
1540
1541         mtx_lock(&sc->tids.hftid_lock);
1542         if (lookup_hf(sc, &t->fs, hash) != NULL) {
1543                 rc = EEXIST;
1544                 goto done;
1545         }
1546
1547         f = malloc(sizeof(*f), M_CXGBE, M_ZERO | M_NOWAIT);
1548         if (__predict_false(f == NULL)) {
1549                 rc = ENOMEM;
1550                 goto done;
1551         }
1552         f->fs = t->fs;
1553         f->l2te = l2te;
1554         f->smt = smt;
1555
1556         atid = alloc_atid(sc, f);
1557         if (__predict_false(atid) == -1) {
1558                 free(f, M_CXGBE);
1559                 rc = EAGAIN;
1560                 goto done;
1561         }
1562         MPASS(atid >= 0);
1563
1564         wr = start_wrq_wr(&sc->sge.ctrlq[0], act_open_cpl_len16(sc, f->fs.type),
1565             &cookie);
1566         if (wr == NULL) {
1567                 free_atid(sc, atid);
1568                 free(f, M_CXGBE);
1569                 rc = ENOMEM;
1570                 goto done;
1571         }
1572         if (f->fs.type)
1573                 mk_act_open_req6(sc, f, atid, ftuple, wr);
1574         else
1575                 mk_act_open_req(sc, f, atid, ftuple, wr);
1576
1577         f->locked = 1; /* ithread mustn't free f if ioctl is still around. */
1578         f->pending = 1;
1579         f->tid = -1;
1580         insert_hf(sc, f, hash);
1581         commit_wrq_wr(&sc->sge.ctrlq[0], wr, &cookie);
1582
1583         for (;;) {
1584                 MPASS(f->locked);
1585                 if (f->pending == 0) {
1586                         if (f->valid) {
1587                                 rc = 0;
1588                                 f->locked = 0;
1589                                 t->idx = f->tid;
1590                         } else {
1591                                 rc = f->tid;
1592                                 free(f, M_CXGBE);
1593                         }
1594                         break;
1595                 }
1596                 if (cv_wait_sig(&sc->tids.hftid_cv, &sc->tids.hftid_lock) != 0) {
1597                         f->locked = 0;
1598                         rc = EINPROGRESS;
1599                         break;
1600                 }
1601         }
1602 done:
1603         mtx_unlock(&sc->tids.hftid_lock);
1604         return (rc);
1605 }
1606
1607 /* SET_TCB_FIELD sent as a ULP command looks like this */
1608 #define LEN__SET_TCB_FIELD_ULP (sizeof(struct ulp_txpkt) + \
1609     sizeof(struct ulptx_idata) + sizeof(struct cpl_set_tcb_field_core))
1610
1611 static void *
1612 mk_set_tcb_field_ulp(struct ulp_txpkt *ulpmc, uint64_t word, uint64_t mask,
1613                 uint64_t val, uint32_t tid, uint32_t qid)
1614 {
1615         struct ulptx_idata *ulpsc;
1616         struct cpl_set_tcb_field_core *req;
1617
1618         ulpmc->cmd_dest = htonl(V_ULPTX_CMD(ULP_TX_PKT) | V_ULP_TXPKT_DEST(0));
1619         ulpmc->len = htobe32(howmany(LEN__SET_TCB_FIELD_ULP, 16));
1620
1621         ulpsc = (struct ulptx_idata *)(ulpmc + 1);
1622         ulpsc->cmd_more = htobe32(V_ULPTX_CMD(ULP_TX_SC_IMM));
1623         ulpsc->len = htobe32(sizeof(*req));
1624
1625         req = (struct cpl_set_tcb_field_core *)(ulpsc + 1);
1626         OPCODE_TID(req) = htobe32(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
1627         req->reply_ctrl = htobe16(V_NO_REPLY(1) | V_QUEUENO(qid));
1628         req->word_cookie = htobe16(V_WORD(word) | V_COOKIE(0));
1629         req->mask = htobe64(mask);
1630         req->val = htobe64(val);
1631
1632         ulpsc = (struct ulptx_idata *)(req + 1);
1633         if (LEN__SET_TCB_FIELD_ULP % 16) {
1634                 ulpsc->cmd_more = htobe32(V_ULPTX_CMD(ULP_TX_SC_NOOP));
1635                 ulpsc->len = htobe32(0);
1636                 return (ulpsc + 1);
1637         }
1638         return (ulpsc);
1639 }
1640
1641 /* ABORT_REQ sent as a ULP command looks like this */
1642 #define LEN__ABORT_REQ_ULP (sizeof(struct ulp_txpkt) + \
1643         sizeof(struct ulptx_idata) + sizeof(struct cpl_abort_req_core))
1644
1645 static void *
1646 mk_abort_req_ulp(struct ulp_txpkt *ulpmc, uint32_t tid)
1647 {
1648         struct ulptx_idata *ulpsc;
1649         struct cpl_abort_req_core *req;
1650
1651         ulpmc->cmd_dest = htonl(V_ULPTX_CMD(ULP_TX_PKT) | V_ULP_TXPKT_DEST(0));
1652         ulpmc->len = htobe32(howmany(LEN__ABORT_REQ_ULP, 16));
1653
1654         ulpsc = (struct ulptx_idata *)(ulpmc + 1);
1655         ulpsc->cmd_more = htobe32(V_ULPTX_CMD(ULP_TX_SC_IMM));
1656         ulpsc->len = htobe32(sizeof(*req));
1657
1658         req = (struct cpl_abort_req_core *)(ulpsc + 1);
1659         OPCODE_TID(req) = htobe32(MK_OPCODE_TID(CPL_ABORT_REQ, tid));
1660         req->rsvd0 = htonl(0);
1661         req->rsvd1 = 0;
1662         req->cmd = CPL_ABORT_NO_RST;
1663
1664         ulpsc = (struct ulptx_idata *)(req + 1);
1665         if (LEN__ABORT_REQ_ULP % 16) {
1666                 ulpsc->cmd_more = htobe32(V_ULPTX_CMD(ULP_TX_SC_NOOP));
1667                 ulpsc->len = htobe32(0);
1668                 return (ulpsc + 1);
1669         }
1670         return (ulpsc);
1671 }
1672
1673 /* ABORT_RPL sent as a ULP command looks like this */
1674 #define LEN__ABORT_RPL_ULP (sizeof(struct ulp_txpkt) + \
1675         sizeof(struct ulptx_idata) + sizeof(struct cpl_abort_rpl_core))
1676
1677 static void *
1678 mk_abort_rpl_ulp(struct ulp_txpkt *ulpmc, uint32_t tid)
1679 {
1680         struct ulptx_idata *ulpsc;
1681         struct cpl_abort_rpl_core *rpl;
1682
1683         ulpmc->cmd_dest = htonl(V_ULPTX_CMD(ULP_TX_PKT) | V_ULP_TXPKT_DEST(0));
1684         ulpmc->len = htobe32(howmany(LEN__ABORT_RPL_ULP, 16));
1685
1686         ulpsc = (struct ulptx_idata *)(ulpmc + 1);
1687         ulpsc->cmd_more = htobe32(V_ULPTX_CMD(ULP_TX_SC_IMM));
1688         ulpsc->len = htobe32(sizeof(*rpl));
1689
1690         rpl = (struct cpl_abort_rpl_core *)(ulpsc + 1);
1691         OPCODE_TID(rpl) = htobe32(MK_OPCODE_TID(CPL_ABORT_RPL, tid));
1692         rpl->rsvd0 = htonl(0);
1693         rpl->rsvd1 = 0;
1694         rpl->cmd = CPL_ABORT_NO_RST;
1695
1696         ulpsc = (struct ulptx_idata *)(rpl + 1);
1697         if (LEN__ABORT_RPL_ULP % 16) {
1698                 ulpsc->cmd_more = htobe32(V_ULPTX_CMD(ULP_TX_SC_NOOP));
1699                 ulpsc->len = htobe32(0);
1700                 return (ulpsc + 1);
1701         }
1702         return (ulpsc);
1703 }
1704
1705 static inline int
1706 del_hashfilter_wrlen(void)
1707 {
1708
1709         return (sizeof(struct work_request_hdr) +
1710             roundup2(LEN__SET_TCB_FIELD_ULP, 16) +
1711             roundup2(LEN__ABORT_REQ_ULP, 16) +
1712             roundup2(LEN__ABORT_RPL_ULP, 16));
1713 }
1714
1715 static void
1716 mk_del_hashfilter_wr(int tid, struct work_request_hdr *wrh, int wrlen, int qid)
1717 {
1718         struct ulp_txpkt *ulpmc;
1719
1720         INIT_ULPTX_WRH(wrh, wrlen, 0, 0);
1721         ulpmc = (struct ulp_txpkt *)(wrh + 1);
1722         ulpmc = mk_set_tcb_field_ulp(ulpmc, W_TCB_RSS_INFO,
1723             V_TCB_RSS_INFO(M_TCB_RSS_INFO), V_TCB_RSS_INFO(qid), tid, 0);
1724         ulpmc = mk_abort_req_ulp(ulpmc, tid);
1725         ulpmc = mk_abort_rpl_ulp(ulpmc, tid);
1726 }
1727
1728 static int
1729 del_hashfilter(struct adapter *sc, struct t4_filter *t)
1730 {
1731         struct tid_info *ti = &sc->tids;
1732         void *wr;
1733         struct filter_entry *f;
1734         struct wrq_cookie cookie;
1735         int rc;
1736         const int wrlen = del_hashfilter_wrlen();
1737         const int inv_tid = ti->ntids + ti->tid_base;
1738
1739         MPASS(sc->tids.hftid_hash_4t != NULL);
1740         MPASS(sc->tids.ntids > 0);
1741
1742         if (t->idx < sc->tids.tid_base || t->idx >= inv_tid)
1743                 return (EINVAL);
1744
1745         mtx_lock(&ti->hftid_lock);
1746         f = lookup_hftid(sc, t->idx);
1747         if (f == NULL || f->valid == 0) {
1748                 rc = EINVAL;
1749                 goto done;
1750         }
1751         MPASS(f->tid == t->idx);
1752         if (f->locked) {
1753                 rc = EPERM;
1754                 goto done;
1755         }
1756         if (f->pending) {
1757                 rc = EBUSY;
1758                 goto done;
1759         }
1760         wr = start_wrq_wr(&sc->sge.ctrlq[0], howmany(wrlen, 16), &cookie);
1761         if (wr == NULL) {
1762                 rc = ENOMEM;
1763                 goto done;
1764         }
1765
1766         mk_del_hashfilter_wr(t->idx, wr, wrlen, sc->sge.fwq.abs_id);
1767         f->locked = 1;
1768         f->pending = 1;
1769         commit_wrq_wr(&sc->sge.ctrlq[0], wr, &cookie);
1770         t->fs = f->fs;  /* extra info for the caller */
1771
1772         for (;;) {
1773                 MPASS(f->locked);
1774                 if (f->pending == 0) {
1775                         if (f->valid) {
1776                                 f->locked = 0;
1777                                 rc = EIO;
1778                         } else {
1779                                 rc = 0;
1780                                 free(f, M_CXGBE);
1781                         }
1782                         break;
1783                 }
1784                 if (cv_wait_sig(&ti->hftid_cv, &ti->hftid_lock) != 0) {
1785                         f->locked = 0;
1786                         rc = EINPROGRESS;
1787                         break;
1788                 }
1789         }
1790 done:
1791         mtx_unlock(&ti->hftid_lock);
1792         return (rc);
1793 }
1794
1795 #define WORD_MASK       0xffffffff
1796 static void
1797 set_nat_params(struct adapter *sc, struct filter_entry *f, const bool dip,
1798     const bool sip, const bool dp, const bool sp)
1799 {
1800
1801         if (dip) {
1802                 if (f->fs.type) {
1803                         set_tcb_field(sc, f->tid, W_TCB_SND_UNA_RAW, WORD_MASK,
1804                             f->fs.nat_dip[15] | f->fs.nat_dip[14] << 8 |
1805                             f->fs.nat_dip[13] << 16 | f->fs.nat_dip[12] << 24, 1);
1806
1807                         set_tcb_field(sc, f->tid,
1808                             W_TCB_SND_UNA_RAW + 1, WORD_MASK,
1809                             f->fs.nat_dip[11] | f->fs.nat_dip[10] << 8 |
1810                             f->fs.nat_dip[9] << 16 | f->fs.nat_dip[8] << 24, 1);
1811
1812                         set_tcb_field(sc, f->tid,
1813                             W_TCB_SND_UNA_RAW + 2, WORD_MASK,
1814                             f->fs.nat_dip[7] | f->fs.nat_dip[6] << 8 |
1815                             f->fs.nat_dip[5] << 16 | f->fs.nat_dip[4] << 24, 1);
1816
1817                         set_tcb_field(sc, f->tid,
1818                             W_TCB_SND_UNA_RAW + 3, WORD_MASK,
1819                             f->fs.nat_dip[3] | f->fs.nat_dip[2] << 8 |
1820                             f->fs.nat_dip[1] << 16 | f->fs.nat_dip[0] << 24, 1);
1821                 } else {
1822                         set_tcb_field(sc, f->tid,
1823                             W_TCB_RX_FRAG3_LEN_RAW, WORD_MASK,
1824                             f->fs.nat_dip[3] | f->fs.nat_dip[2] << 8 |
1825                             f->fs.nat_dip[1] << 16 | f->fs.nat_dip[0] << 24, 1);
1826                 }
1827         }
1828
1829         if (sip) {
1830                 if (f->fs.type) {
1831                         set_tcb_field(sc, f->tid,
1832                             W_TCB_RX_FRAG2_PTR_RAW, WORD_MASK,
1833                             f->fs.nat_sip[15] | f->fs.nat_sip[14] << 8 |
1834                             f->fs.nat_sip[13] << 16 | f->fs.nat_sip[12] << 24, 1);
1835
1836                         set_tcb_field(sc, f->tid,
1837                             W_TCB_RX_FRAG2_PTR_RAW + 1, WORD_MASK,
1838                             f->fs.nat_sip[11] | f->fs.nat_sip[10] << 8 |
1839                             f->fs.nat_sip[9] << 16 | f->fs.nat_sip[8] << 24, 1);
1840
1841                         set_tcb_field(sc, f->tid,
1842                             W_TCB_RX_FRAG2_PTR_RAW + 2, WORD_MASK,
1843                             f->fs.nat_sip[7] | f->fs.nat_sip[6] << 8 |
1844                             f->fs.nat_sip[5] << 16 | f->fs.nat_sip[4] << 24, 1);
1845
1846                         set_tcb_field(sc, f->tid,
1847                             W_TCB_RX_FRAG2_PTR_RAW + 3, WORD_MASK,
1848                             f->fs.nat_sip[3] | f->fs.nat_sip[2] << 8 |
1849                             f->fs.nat_sip[1] << 16 | f->fs.nat_sip[0] << 24, 1);
1850
1851                 } else {
1852                         set_tcb_field(sc, f->tid,
1853                             W_TCB_RX_FRAG3_START_IDX_OFFSET_RAW, WORD_MASK,
1854                             f->fs.nat_sip[3] | f->fs.nat_sip[2] << 8 |
1855                             f->fs.nat_sip[1] << 16 | f->fs.nat_sip[0] << 24, 1);
1856                 }
1857         }
1858
1859         set_tcb_field(sc, f->tid, W_TCB_PDU_HDR_LEN, WORD_MASK,
1860             (dp ? f->fs.nat_dport : 0) | (sp ? f->fs.nat_sport << 16 : 0), 1);
1861 }
1862
1863 /*
1864  * Returns EINPROGRESS to indicate that at least one TCB update was sent and the
1865  * last of the series of updates requested a reply.  The reply informs the
1866  * driver that the filter is fully setup.
1867  */
1868 static int
1869 configure_hashfilter_tcb(struct adapter *sc, struct filter_entry *f)
1870 {
1871         int updated = 0;
1872
1873         MPASS(f->tid < sc->tids.ntids);
1874         MPASS(f->fs.hash);
1875         MPASS(f->pending);
1876         MPASS(f->valid == 0);
1877
1878         if (f->fs.newdmac) {
1879                 set_tcb_tflag(sc, f->tid, S_TF_CCTRL_ECE, 1, 1);
1880                 updated++;
1881         }
1882
1883         if (f->fs.newvlan == VLAN_INSERT || f->fs.newvlan == VLAN_REWRITE) {
1884                 set_tcb_tflag(sc, f->tid, S_TF_CCTRL_RFR, 1, 1);
1885                 updated++;
1886         }
1887
1888         if (f->fs.newsmac) {
1889                 MPASS(f->smt != NULL);
1890                 set_tcb_tflag(sc, f->tid, S_TF_CCTRL_CWR, 1, 1);
1891                 set_tcb_field(sc, f->tid, W_TCB_SMAC_SEL,
1892                     V_TCB_SMAC_SEL(M_TCB_SMAC_SEL), V_TCB_SMAC_SEL(f->smt->idx),
1893                     1);
1894                 updated++;
1895         }
1896
1897         switch(f->fs.nat_mode) {
1898         case NAT_MODE_NONE:
1899                 break;
1900         case NAT_MODE_DIP:
1901                 set_nat_params(sc, f, true, false, false, false);
1902                 updated++;
1903                 break;
1904         case NAT_MODE_DIP_DP:
1905                 set_nat_params(sc, f, true, false, true, false);
1906                 updated++;
1907                 break;
1908         case NAT_MODE_DIP_DP_SIP:
1909                 set_nat_params(sc, f, true, true, true, false);
1910                 updated++;
1911                 break;
1912         case NAT_MODE_DIP_DP_SP:
1913                 set_nat_params(sc, f, true, false, true, true);
1914                 updated++;
1915                 break;
1916         case NAT_MODE_SIP_SP:
1917                 set_nat_params(sc, f, false, true, false, true);
1918                 updated++;
1919                 break;
1920         case NAT_MODE_DIP_SIP_SP:
1921                 set_nat_params(sc, f, true, true, false, true);
1922                 updated++;
1923                 break;
1924         case NAT_MODE_ALL:
1925                 set_nat_params(sc, f, true, true, true, true);
1926                 updated++;
1927                 break;
1928         default:
1929                 MPASS(0);       /* should have been validated earlier */
1930                 break;
1931
1932         }
1933
1934         if (f->fs.nat_seq_chk) {
1935                 set_tcb_field(sc, f->tid, W_TCB_RCV_NXT,
1936                     V_TCB_RCV_NXT(M_TCB_RCV_NXT),
1937                     V_TCB_RCV_NXT(f->fs.nat_seq_chk), 1);
1938                 updated++;
1939         }
1940
1941         if (is_t5(sc) && f->fs.action == FILTER_DROP) {
1942                 /*
1943                  * Migrating = 1, Non-offload = 0 to get a T5 hashfilter to drop.
1944                  */
1945                 set_tcb_field(sc, f->tid, W_TCB_T_FLAGS, V_TF_NON_OFFLOAD(1) |
1946                     V_TF_MIGRATING(1), V_TF_MIGRATING(1), 1);
1947                 updated++;
1948         }
1949
1950         /*
1951          * Enable switching after all secondary resources (L2T entry, SMT entry,
1952          * etc.) are setup so that any switched packet will use correct
1953          * values.
1954          */
1955         if (f->fs.action == FILTER_SWITCH) {
1956                 set_tcb_tflag(sc, f->tid, S_TF_CCTRL_ECN, 1, 1);
1957                 updated++;
1958         }
1959
1960         if (f->fs.hitcnts || updated > 0) {
1961                 set_tcb_field(sc, f->tid, W_TCB_TIMESTAMP,
1962                     V_TCB_TIMESTAMP(M_TCB_TIMESTAMP) |
1963                     V_TCB_T_RTT_TS_RECENT_AGE(M_TCB_T_RTT_TS_RECENT_AGE),
1964                     V_TCB_TIMESTAMP(0ULL) | V_TCB_T_RTT_TS_RECENT_AGE(0ULL), 0);
1965                 return (EINPROGRESS);
1966         }
1967
1968         return (0);
1969 }