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