1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Chelsio Communications. 3 * All rights reserved. 4 */ 5 #include "base/common.h" 6 #include "cxgbe_flow.h" 7 8 #define __CXGBE_FILL_FS(__v, __m, fs, elem, e) \ 9 do { \ 10 if ((fs)->mask.elem && ((fs)->val.elem != (__v))) \ 11 return rte_flow_error_set(e, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, \ 12 NULL, "Redefined match item with" \ 13 " different values found"); \ 14 (fs)->val.elem = (__v); \ 15 (fs)->mask.elem = (__m); \ 16 } while (0) 17 18 #define __CXGBE_FILL_FS_MEMCPY(__v, __m, fs, elem) \ 19 do { \ 20 memcpy(&(fs)->val.elem, &(__v), sizeof(__v)); \ 21 memcpy(&(fs)->mask.elem, &(__m), sizeof(__m)); \ 22 } while (0) 23 24 #define CXGBE_FILL_FS(v, m, elem) \ 25 __CXGBE_FILL_FS(v, m, fs, elem, e) 26 27 #define CXGBE_FILL_FS_MEMCPY(v, m, elem) \ 28 __CXGBE_FILL_FS_MEMCPY(v, m, fs, elem) 29 30 static int 31 cxgbe_validate_item(const struct rte_flow_item *i, struct rte_flow_error *e) 32 { 33 /* rte_flow specification does not allow it. */ 34 if (!i->spec && (i->mask || i->last)) 35 return rte_flow_error_set(e, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, 36 i, "last or mask given without spec"); 37 /* 38 * We don't support it. 39 * Although, we can support values in last as 0's or last == spec. 40 * But this will not provide user with any additional functionality 41 * and will only increase the complexity for us. 42 */ 43 if (i->last) 44 return rte_flow_error_set(e, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, 45 i, "last is not supported by chelsio pmd"); 46 return 0; 47 } 48 49 /** 50 * Apart from the 4-tuple IPv4/IPv6 - TCP/UDP information, 51 * there's only 40-bits available to store match fields. 52 * So, to save space, optimize filter spec for some common 53 * known fields that hardware can parse against incoming 54 * packets automatically. 55 */ 56 static void 57 cxgbe_tweak_filter_spec(struct adapter *adap, 58 struct ch_filter_specification *fs) 59 { 60 /* Save 16-bit ethertype field space, by setting corresponding 61 * 1-bit flags in the filter spec for common known ethertypes. 62 * When hardware sees these flags, it automatically infers and 63 * matches incoming packets against the corresponding ethertype. 64 */ 65 if (fs->mask.ethtype == 0xffff) { 66 switch (fs->val.ethtype) { 67 case RTE_ETHER_TYPE_IPV4: 68 if (adap->params.tp.ethertype_shift < 0) { 69 fs->type = FILTER_TYPE_IPV4; 70 fs->val.ethtype = 0; 71 fs->mask.ethtype = 0; 72 } 73 break; 74 case RTE_ETHER_TYPE_IPV6: 75 if (adap->params.tp.ethertype_shift < 0) { 76 fs->type = FILTER_TYPE_IPV6; 77 fs->val.ethtype = 0; 78 fs->mask.ethtype = 0; 79 } 80 break; 81 case RTE_ETHER_TYPE_VLAN: 82 if (adap->params.tp.ethertype_shift < 0 && 83 adap->params.tp.vlan_shift >= 0) { 84 fs->val.ivlan_vld = 1; 85 fs->mask.ivlan_vld = 1; 86 fs->val.ethtype = 0; 87 fs->mask.ethtype = 0; 88 } 89 break; 90 case RTE_ETHER_TYPE_QINQ: 91 if (adap->params.tp.ethertype_shift < 0 && 92 adap->params.tp.vnic_shift >= 0) { 93 fs->val.ovlan_vld = 1; 94 fs->mask.ovlan_vld = 1; 95 fs->val.ethtype = 0; 96 fs->mask.ethtype = 0; 97 } 98 break; 99 default: 100 break; 101 } 102 } 103 } 104 105 static void 106 cxgbe_fill_filter_region(struct adapter *adap, 107 struct ch_filter_specification *fs) 108 { 109 struct tp_params *tp = &adap->params.tp; 110 u64 hash_filter_mask = tp->hash_filter_mask; 111 u64 ntuple_mask = 0; 112 113 fs->cap = 0; 114 115 if (!is_hashfilter(adap)) 116 return; 117 118 if (fs->type) { 119 uint8_t biton[16] = {0xff, 0xff, 0xff, 0xff, 120 0xff, 0xff, 0xff, 0xff, 121 0xff, 0xff, 0xff, 0xff, 122 0xff, 0xff, 0xff, 0xff}; 123 uint8_t bitoff[16] = {0}; 124 125 if (!memcmp(fs->val.lip, bitoff, sizeof(bitoff)) || 126 !memcmp(fs->val.fip, bitoff, sizeof(bitoff)) || 127 memcmp(fs->mask.lip, biton, sizeof(biton)) || 128 memcmp(fs->mask.fip, biton, sizeof(biton))) 129 return; 130 } else { 131 uint32_t biton = 0xffffffff; 132 uint32_t bitoff = 0x0U; 133 134 if (!memcmp(fs->val.lip, &bitoff, sizeof(bitoff)) || 135 !memcmp(fs->val.fip, &bitoff, sizeof(bitoff)) || 136 memcmp(fs->mask.lip, &biton, sizeof(biton)) || 137 memcmp(fs->mask.fip, &biton, sizeof(biton))) 138 return; 139 } 140 141 if (!fs->val.lport || fs->mask.lport != 0xffff) 142 return; 143 if (!fs->val.fport || fs->mask.fport != 0xffff) 144 return; 145 146 if (tp->protocol_shift >= 0) 147 ntuple_mask |= (u64)fs->mask.proto << tp->protocol_shift; 148 if (tp->ethertype_shift >= 0) 149 ntuple_mask |= (u64)fs->mask.ethtype << tp->ethertype_shift; 150 if (tp->port_shift >= 0) 151 ntuple_mask |= (u64)fs->mask.iport << tp->port_shift; 152 if (tp->macmatch_shift >= 0) 153 ntuple_mask |= (u64)fs->mask.macidx << tp->macmatch_shift; 154 if (tp->vlan_shift >= 0 && fs->mask.ivlan_vld) 155 ntuple_mask |= (u64)(F_FT_VLAN_VLD | fs->mask.ivlan) << 156 tp->vlan_shift; 157 if (tp->vnic_shift >= 0) { 158 if (fs->mask.ovlan_vld) 159 ntuple_mask |= (u64)(fs->val.ovlan_vld << 16 | 160 fs->mask.ovlan) << tp->vnic_shift; 161 else if (fs->mask.pfvf_vld) 162 ntuple_mask |= (u64)(fs->mask.pfvf_vld << 16 | 163 fs->mask.pf << 13 | 164 fs->mask.vf) << tp->vnic_shift; 165 } 166 if (tp->tos_shift >= 0) 167 ntuple_mask |= (u64)fs->mask.tos << tp->tos_shift; 168 169 if (ntuple_mask != hash_filter_mask) 170 return; 171 172 fs->cap = 1; /* use hash region */ 173 } 174 175 static int 176 ch_rte_parsetype_eth(const void *dmask, const struct rte_flow_item *item, 177 struct ch_filter_specification *fs, 178 struct rte_flow_error *e) 179 { 180 const struct rte_flow_item_eth *spec = item->spec; 181 const struct rte_flow_item_eth *umask = item->mask; 182 const struct rte_flow_item_eth *mask; 183 184 /* If user has not given any mask, then use chelsio supported mask. */ 185 mask = umask ? umask : (const struct rte_flow_item_eth *)dmask; 186 187 if (!spec) 188 return 0; 189 190 /* we don't support SRC_MAC filtering*/ 191 if (!rte_is_zero_ether_addr(&spec->hdr.src_addr) || 192 (umask && !rte_is_zero_ether_addr(&umask->hdr.src_addr))) 193 return rte_flow_error_set(e, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, 194 item, 195 "src mac filtering not supported"); 196 197 if (!rte_is_zero_ether_addr(&spec->hdr.dst_addr) || 198 (umask && !rte_is_zero_ether_addr(&umask->hdr.dst_addr))) { 199 CXGBE_FILL_FS(0, 0x1ff, macidx); 200 CXGBE_FILL_FS_MEMCPY(spec->hdr.dst_addr.addr_bytes, mask->hdr.dst_addr.addr_bytes, 201 dmac); 202 } 203 204 if (spec->hdr.ether_type || (umask && umask->hdr.ether_type)) 205 CXGBE_FILL_FS(be16_to_cpu(spec->hdr.ether_type), 206 be16_to_cpu(mask->hdr.ether_type), ethtype); 207 208 return 0; 209 } 210 211 static int 212 ch_rte_parsetype_vlan(const void *dmask, const struct rte_flow_item *item, 213 struct ch_filter_specification *fs, 214 struct rte_flow_error *e) 215 { 216 const struct rte_flow_item_vlan *spec = item->spec; 217 const struct rte_flow_item_vlan *umask = item->mask; 218 const struct rte_flow_item_vlan *mask; 219 220 /* If user has not given any mask, then use chelsio supported mask. */ 221 mask = umask ? umask : (const struct rte_flow_item_vlan *)dmask; 222 223 /* If ethertype is already set and is not VLAN (0x8100) or 224 * QINQ(0x88A8), then don't proceed further. Otherwise, 225 * reset the outer ethertype, so that it can be replaced by 226 * innermost ethertype. Note that hardware will automatically 227 * match against VLAN or QINQ packets, based on 'ivlan_vld' or 228 * 'ovlan_vld' bit set in Chelsio filter spec, respectively. 229 */ 230 if (fs->mask.ethtype) { 231 if (fs->val.ethtype != RTE_ETHER_TYPE_VLAN && 232 fs->val.ethtype != RTE_ETHER_TYPE_QINQ) 233 return rte_flow_error_set(e, EINVAL, 234 RTE_FLOW_ERROR_TYPE_ITEM, 235 item, 236 "Ethertype must be 0x8100 or 0x88a8"); 237 } 238 239 if (fs->val.ethtype == RTE_ETHER_TYPE_QINQ) { 240 CXGBE_FILL_FS(1, 1, ovlan_vld); 241 if (spec) { 242 if (spec->hdr.vlan_tci || (umask && umask->hdr.vlan_tci)) 243 CXGBE_FILL_FS(be16_to_cpu(spec->hdr.vlan_tci), 244 be16_to_cpu(mask->hdr.vlan_tci), ovlan); 245 fs->mask.ethtype = 0; 246 fs->val.ethtype = 0; 247 } 248 } else { 249 CXGBE_FILL_FS(1, 1, ivlan_vld); 250 if (spec) { 251 if (spec->hdr.vlan_tci || (umask && umask->hdr.vlan_tci)) 252 CXGBE_FILL_FS(be16_to_cpu(spec->hdr.vlan_tci), 253 be16_to_cpu(mask->hdr.vlan_tci), ivlan); 254 fs->mask.ethtype = 0; 255 fs->val.ethtype = 0; 256 } 257 } 258 259 if (spec && (spec->hdr.eth_proto || (umask && umask->hdr.eth_proto))) 260 CXGBE_FILL_FS(be16_to_cpu(spec->hdr.eth_proto), 261 be16_to_cpu(mask->hdr.eth_proto), ethtype); 262 263 return 0; 264 } 265 266 static int 267 ch_rte_parsetype_udp(const void *dmask, const struct rte_flow_item *item, 268 struct ch_filter_specification *fs, 269 struct rte_flow_error *e) 270 { 271 const struct rte_flow_item_udp *val = item->spec; 272 const struct rte_flow_item_udp *umask = item->mask; 273 const struct rte_flow_item_udp *mask; 274 275 mask = umask ? umask : (const struct rte_flow_item_udp *)dmask; 276 277 if (mask->hdr.dgram_len || mask->hdr.dgram_cksum) 278 return rte_flow_error_set(e, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, 279 item, 280 "udp: only src/dst port supported"); 281 282 CXGBE_FILL_FS(IPPROTO_UDP, 0xff, proto); 283 if (!val) 284 return 0; 285 286 if (val->hdr.src_port || (umask && umask->hdr.src_port)) 287 CXGBE_FILL_FS(be16_to_cpu(val->hdr.src_port), 288 be16_to_cpu(mask->hdr.src_port), fport); 289 290 if (val->hdr.dst_port || (umask && umask->hdr.dst_port)) 291 CXGBE_FILL_FS(be16_to_cpu(val->hdr.dst_port), 292 be16_to_cpu(mask->hdr.dst_port), lport); 293 294 return 0; 295 } 296 297 static int 298 ch_rte_parsetype_tcp(const void *dmask, const struct rte_flow_item *item, 299 struct ch_filter_specification *fs, 300 struct rte_flow_error *e) 301 { 302 const struct rte_flow_item_tcp *val = item->spec; 303 const struct rte_flow_item_tcp *umask = item->mask; 304 const struct rte_flow_item_tcp *mask; 305 306 mask = umask ? umask : (const struct rte_flow_item_tcp *)dmask; 307 308 if (mask->hdr.sent_seq || mask->hdr.recv_ack || mask->hdr.data_off || 309 mask->hdr.tcp_flags || mask->hdr.rx_win || mask->hdr.cksum || 310 mask->hdr.tcp_urp) 311 return rte_flow_error_set(e, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, 312 item, 313 "tcp: only src/dst port supported"); 314 315 CXGBE_FILL_FS(IPPROTO_TCP, 0xff, proto); 316 if (!val) 317 return 0; 318 319 if (val->hdr.src_port || (umask && umask->hdr.src_port)) 320 CXGBE_FILL_FS(be16_to_cpu(val->hdr.src_port), 321 be16_to_cpu(mask->hdr.src_port), fport); 322 323 if (val->hdr.dst_port || (umask && umask->hdr.dst_port)) 324 CXGBE_FILL_FS(be16_to_cpu(val->hdr.dst_port), 325 be16_to_cpu(mask->hdr.dst_port), lport); 326 327 return 0; 328 } 329 330 static int 331 ch_rte_parsetype_ipv4(const void *dmask, const struct rte_flow_item *item, 332 struct ch_filter_specification *fs, 333 struct rte_flow_error *e) 334 { 335 const struct rte_flow_item_ipv4 *val = item->spec; 336 const struct rte_flow_item_ipv4 *umask = item->mask; 337 const struct rte_flow_item_ipv4 *mask; 338 339 mask = umask ? umask : (const struct rte_flow_item_ipv4 *)dmask; 340 341 if (mask->hdr.time_to_live) 342 return rte_flow_error_set(e, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, 343 item, "ttl is not supported"); 344 345 if (fs->mask.ethtype && 346 (fs->val.ethtype != RTE_ETHER_TYPE_IPV4)) 347 return rte_flow_error_set(e, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, 348 item, 349 "Couldn't find IPv4 ethertype"); 350 fs->type = FILTER_TYPE_IPV4; 351 if (!val) 352 return 0; /* ipv4 wild card */ 353 354 if (val->hdr.next_proto_id || (umask && umask->hdr.next_proto_id)) 355 CXGBE_FILL_FS(val->hdr.next_proto_id, mask->hdr.next_proto_id, 356 proto); 357 358 if (val->hdr.dst_addr || (umask && umask->hdr.dst_addr)) 359 CXGBE_FILL_FS_MEMCPY(val->hdr.dst_addr, mask->hdr.dst_addr, 360 lip); 361 362 if (val->hdr.src_addr || (umask && umask->hdr.src_addr)) 363 CXGBE_FILL_FS_MEMCPY(val->hdr.src_addr, mask->hdr.src_addr, 364 fip); 365 366 if (val->hdr.type_of_service || (umask && umask->hdr.type_of_service)) 367 CXGBE_FILL_FS(val->hdr.type_of_service, 368 mask->hdr.type_of_service, tos); 369 370 return 0; 371 } 372 373 static int 374 ch_rte_parsetype_ipv6(const void *dmask, const struct rte_flow_item *item, 375 struct ch_filter_specification *fs, 376 struct rte_flow_error *e) 377 { 378 const struct rte_flow_item_ipv6 *val = item->spec; 379 const struct rte_flow_item_ipv6 *umask = item->mask; 380 const struct rte_flow_item_ipv6 *mask; 381 u32 vtc_flow, vtc_flow_mask; 382 u8 z[16] = { 0 }; 383 384 mask = umask ? umask : (const struct rte_flow_item_ipv6 *)dmask; 385 386 vtc_flow_mask = be32_to_cpu(mask->hdr.vtc_flow); 387 388 if (vtc_flow_mask & RTE_IPV6_HDR_FL_MASK || 389 mask->hdr.payload_len || mask->hdr.hop_limits) 390 return rte_flow_error_set(e, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, 391 item, 392 "flow/hop are not supported"); 393 394 if (fs->mask.ethtype && 395 (fs->val.ethtype != RTE_ETHER_TYPE_IPV6)) 396 return rte_flow_error_set(e, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, 397 item, 398 "Couldn't find IPv6 ethertype"); 399 fs->type = FILTER_TYPE_IPV6; 400 if (!val) 401 return 0; /* ipv6 wild card */ 402 403 if (val->hdr.proto || (umask && umask->hdr.proto)) 404 CXGBE_FILL_FS(val->hdr.proto, mask->hdr.proto, proto); 405 406 vtc_flow = be32_to_cpu(val->hdr.vtc_flow); 407 if (val->hdr.vtc_flow || (umask && umask->hdr.vtc_flow)) 408 CXGBE_FILL_FS((vtc_flow & RTE_IPV6_HDR_TC_MASK) >> 409 RTE_IPV6_HDR_TC_SHIFT, 410 (vtc_flow_mask & RTE_IPV6_HDR_TC_MASK) >> 411 RTE_IPV6_HDR_TC_SHIFT, 412 tos); 413 414 if (memcmp(&val->hdr.dst_addr, z, sizeof(val->hdr.dst_addr)) || 415 (umask && 416 memcmp(&umask->hdr.dst_addr, z, sizeof(umask->hdr.dst_addr)))) 417 CXGBE_FILL_FS_MEMCPY(val->hdr.dst_addr, mask->hdr.dst_addr, 418 lip); 419 420 if (memcmp(&val->hdr.src_addr, z, sizeof(val->hdr.src_addr)) || 421 (umask && 422 memcmp(&umask->hdr.src_addr, z, sizeof(umask->hdr.src_addr)))) 423 CXGBE_FILL_FS_MEMCPY(val->hdr.src_addr, mask->hdr.src_addr, 424 fip); 425 426 return 0; 427 } 428 429 static int 430 cxgbe_rtef_parse_attr(struct rte_flow *flow, const struct rte_flow_attr *attr, 431 struct rte_flow_error *e) 432 { 433 if (attr->egress) 434 return rte_flow_error_set(e, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR, 435 attr, "attribute:<egress> is" 436 " not supported !"); 437 if (attr->group > 0) 438 return rte_flow_error_set(e, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR, 439 attr, "group parameter is" 440 " not supported."); 441 442 flow->fidx = attr->priority ? attr->priority - 1 : FILTER_ID_MAX; 443 444 return 0; 445 } 446 447 static inline int check_rxq(struct rte_eth_dev *dev, uint16_t rxq) 448 { 449 struct port_info *pi = ethdev2pinfo(dev); 450 451 if (rxq > pi->n_rx_qsets) 452 return -EINVAL; 453 return 0; 454 } 455 456 static int cxgbe_validate_fidxondel(struct filter_entry *f, unsigned int fidx) 457 { 458 struct adapter *adap = ethdev2adap(f->dev); 459 struct ch_filter_specification fs = f->fs; 460 u8 nentries; 461 462 if (fidx >= adap->tids.nftids) { 463 dev_err(adap, "invalid flow index %d.\n", fidx); 464 return -EINVAL; 465 } 466 467 nentries = cxgbe_filter_slots(adap, fs.type); 468 if (!cxgbe_is_filter_set(&adap->tids, fidx, nentries)) { 469 dev_err(adap, "Already free fidx:%d f:%p\n", fidx, f); 470 return -EINVAL; 471 } 472 473 return 0; 474 } 475 476 static int 477 cxgbe_validate_fidxonadd(struct ch_filter_specification *fs, 478 struct adapter *adap, unsigned int fidx) 479 { 480 u8 nentries; 481 482 nentries = cxgbe_filter_slots(adap, fs->type); 483 if (cxgbe_is_filter_set(&adap->tids, fidx, nentries)) { 484 dev_err(adap, "filter index: %d is busy.\n", fidx); 485 return -EBUSY; 486 } 487 488 if (fidx >= adap->tids.nftids) { 489 dev_err(adap, "filter index (%u) >= max(%u)\n", 490 fidx, adap->tids.nftids); 491 return -ERANGE; 492 } 493 494 return 0; 495 } 496 497 static int 498 cxgbe_verify_fidx(struct rte_flow *flow, unsigned int fidx, uint8_t del) 499 { 500 if (flow->fs.cap) 501 return 0; /* Hash filters */ 502 return del ? cxgbe_validate_fidxondel(flow->f, fidx) : 503 cxgbe_validate_fidxonadd(&flow->fs, 504 ethdev2adap(flow->dev), fidx); 505 } 506 507 static int cxgbe_get_fidx(struct rte_flow *flow, unsigned int *fidx) 508 { 509 struct ch_filter_specification *fs = &flow->fs; 510 struct adapter *adap = ethdev2adap(flow->dev); 511 512 /* For tcam get the next available slot, if default value specified */ 513 if (flow->fidx == FILTER_ID_MAX) { 514 u8 nentries; 515 int idx; 516 517 nentries = cxgbe_filter_slots(adap, fs->type); 518 idx = cxgbe_alloc_ftid(adap, nentries); 519 if (idx < 0) { 520 dev_err(adap, "unable to get a filter index in tcam\n"); 521 return -ENOMEM; 522 } 523 *fidx = (unsigned int)idx; 524 } else { 525 *fidx = flow->fidx; 526 } 527 528 return 0; 529 } 530 531 static int 532 cxgbe_get_flow_item_index(const struct rte_flow_item items[], u32 type) 533 { 534 const struct rte_flow_item *i; 535 int j, index = -ENOENT; 536 537 for (i = items, j = 0; i->type != RTE_FLOW_ITEM_TYPE_END; i++, j++) { 538 if (i->type == type) { 539 index = j; 540 break; 541 } 542 } 543 544 return index; 545 } 546 547 static int 548 ch_rte_parse_nat(uint8_t nmode, struct ch_filter_specification *fs) 549 { 550 /* nmode: 551 * BIT_0 = [src_ip], BIT_1 = [dst_ip] 552 * BIT_2 = [src_port], BIT_3 = [dst_port] 553 * 554 * Only below cases are supported as per our spec. 555 */ 556 switch (nmode) { 557 case 0: /* 0000b */ 558 fs->nat_mode = NAT_MODE_NONE; 559 break; 560 case 2: /* 0010b */ 561 fs->nat_mode = NAT_MODE_DIP; 562 break; 563 case 5: /* 0101b */ 564 fs->nat_mode = NAT_MODE_SIP_SP; 565 break; 566 case 7: /* 0111b */ 567 fs->nat_mode = NAT_MODE_DIP_SIP_SP; 568 break; 569 case 10: /* 1010b */ 570 fs->nat_mode = NAT_MODE_DIP_DP; 571 break; 572 case 11: /* 1011b */ 573 fs->nat_mode = NAT_MODE_DIP_DP_SIP; 574 break; 575 case 14: /* 1110b */ 576 fs->nat_mode = NAT_MODE_DIP_DP_SP; 577 break; 578 case 15: /* 1111b */ 579 fs->nat_mode = NAT_MODE_ALL; 580 break; 581 default: 582 return -EINVAL; 583 } 584 585 return 0; 586 } 587 588 static int 589 ch_rte_parse_atype_switch(const struct rte_flow_action *a, 590 const struct rte_flow_item items[], 591 uint8_t *nmode, 592 struct ch_filter_specification *fs, 593 struct rte_flow_error *e) 594 { 595 const struct rte_flow_action_of_set_vlan_vid *vlanid; 596 const struct rte_flow_action_of_set_vlan_pcp *vlanpcp; 597 const struct rte_flow_action_of_push_vlan *pushvlan; 598 const struct rte_flow_action_set_ipv4 *ipv4; 599 const struct rte_flow_action_set_ipv6 *ipv6; 600 const struct rte_flow_action_set_tp *tp_port; 601 const struct rte_flow_action_set_mac *mac; 602 int item_index; 603 u16 tmp_vlan; 604 605 switch (a->type) { 606 case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID: 607 vlanid = (const struct rte_flow_action_of_set_vlan_vid *) 608 a->conf; 609 /* If explicitly asked to push a new VLAN header, 610 * then don't set rewrite mode. Otherwise, the 611 * incoming VLAN packets will get their VLAN fields 612 * rewritten, instead of adding an additional outer 613 * VLAN header. 614 */ 615 if (fs->newvlan != VLAN_INSERT) 616 fs->newvlan = VLAN_REWRITE; 617 tmp_vlan = fs->vlan & 0xe000; 618 fs->vlan = (be16_to_cpu(vlanid->vlan_vid) & 0xfff) | tmp_vlan; 619 break; 620 case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP: 621 vlanpcp = (const struct rte_flow_action_of_set_vlan_pcp *) 622 a->conf; 623 /* If explicitly asked to push a new VLAN header, 624 * then don't set rewrite mode. Otherwise, the 625 * incoming VLAN packets will get their VLAN fields 626 * rewritten, instead of adding an additional outer 627 * VLAN header. 628 */ 629 if (fs->newvlan != VLAN_INSERT) 630 fs->newvlan = VLAN_REWRITE; 631 tmp_vlan = fs->vlan & 0xfff; 632 fs->vlan = (vlanpcp->vlan_pcp << 13) | tmp_vlan; 633 break; 634 case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: 635 pushvlan = (const struct rte_flow_action_of_push_vlan *) 636 a->conf; 637 if (be16_to_cpu(pushvlan->ethertype) != RTE_ETHER_TYPE_VLAN) 638 return rte_flow_error_set(e, EINVAL, 639 RTE_FLOW_ERROR_TYPE_ACTION, a, 640 "only ethertype 0x8100 " 641 "supported for push vlan."); 642 fs->newvlan = VLAN_INSERT; 643 break; 644 case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN: 645 fs->newvlan = VLAN_REMOVE; 646 break; 647 case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC: 648 item_index = cxgbe_get_flow_item_index(items, 649 RTE_FLOW_ITEM_TYPE_IPV4); 650 if (item_index < 0) 651 return rte_flow_error_set(e, EINVAL, 652 RTE_FLOW_ERROR_TYPE_ACTION, a, 653 "No RTE_FLOW_ITEM_TYPE_IPV4 " 654 "found."); 655 656 ipv4 = (const struct rte_flow_action_set_ipv4 *)a->conf; 657 memcpy(fs->nat_fip, &ipv4->ipv4_addr, sizeof(ipv4->ipv4_addr)); 658 *nmode |= 1 << 0; 659 break; 660 case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST: 661 item_index = cxgbe_get_flow_item_index(items, 662 RTE_FLOW_ITEM_TYPE_IPV4); 663 if (item_index < 0) 664 return rte_flow_error_set(e, EINVAL, 665 RTE_FLOW_ERROR_TYPE_ACTION, a, 666 "No RTE_FLOW_ITEM_TYPE_IPV4 " 667 "found."); 668 669 ipv4 = (const struct rte_flow_action_set_ipv4 *)a->conf; 670 memcpy(fs->nat_lip, &ipv4->ipv4_addr, sizeof(ipv4->ipv4_addr)); 671 *nmode |= 1 << 1; 672 break; 673 case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC: 674 item_index = cxgbe_get_flow_item_index(items, 675 RTE_FLOW_ITEM_TYPE_IPV6); 676 if (item_index < 0) 677 return rte_flow_error_set(e, EINVAL, 678 RTE_FLOW_ERROR_TYPE_ACTION, a, 679 "No RTE_FLOW_ITEM_TYPE_IPV6 " 680 "found."); 681 682 ipv6 = (const struct rte_flow_action_set_ipv6 *)a->conf; 683 memcpy(fs->nat_fip, &ipv6->ipv6_addr, sizeof(ipv6->ipv6_addr)); 684 *nmode |= 1 << 0; 685 break; 686 case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST: 687 item_index = cxgbe_get_flow_item_index(items, 688 RTE_FLOW_ITEM_TYPE_IPV6); 689 if (item_index < 0) 690 return rte_flow_error_set(e, EINVAL, 691 RTE_FLOW_ERROR_TYPE_ACTION, a, 692 "No RTE_FLOW_ITEM_TYPE_IPV6 " 693 "found."); 694 695 ipv6 = (const struct rte_flow_action_set_ipv6 *)a->conf; 696 memcpy(fs->nat_lip, &ipv6->ipv6_addr, sizeof(ipv6->ipv6_addr)); 697 *nmode |= 1 << 1; 698 break; 699 case RTE_FLOW_ACTION_TYPE_SET_TP_SRC: 700 item_index = cxgbe_get_flow_item_index(items, 701 RTE_FLOW_ITEM_TYPE_TCP); 702 if (item_index < 0) { 703 item_index = 704 cxgbe_get_flow_item_index(items, 705 RTE_FLOW_ITEM_TYPE_UDP); 706 if (item_index < 0) 707 return rte_flow_error_set(e, EINVAL, 708 RTE_FLOW_ERROR_TYPE_ACTION, a, 709 "No RTE_FLOW_ITEM_TYPE_TCP or " 710 "RTE_FLOW_ITEM_TYPE_UDP found"); 711 } 712 713 tp_port = (const struct rte_flow_action_set_tp *)a->conf; 714 fs->nat_fport = be16_to_cpu(tp_port->port); 715 *nmode |= 1 << 2; 716 break; 717 case RTE_FLOW_ACTION_TYPE_SET_TP_DST: 718 item_index = cxgbe_get_flow_item_index(items, 719 RTE_FLOW_ITEM_TYPE_TCP); 720 if (item_index < 0) { 721 item_index = 722 cxgbe_get_flow_item_index(items, 723 RTE_FLOW_ITEM_TYPE_UDP); 724 if (item_index < 0) 725 return rte_flow_error_set(e, EINVAL, 726 RTE_FLOW_ERROR_TYPE_ACTION, a, 727 "No RTE_FLOW_ITEM_TYPE_TCP or " 728 "RTE_FLOW_ITEM_TYPE_UDP found"); 729 } 730 731 tp_port = (const struct rte_flow_action_set_tp *)a->conf; 732 fs->nat_lport = be16_to_cpu(tp_port->port); 733 *nmode |= 1 << 3; 734 break; 735 case RTE_FLOW_ACTION_TYPE_MAC_SWAP: 736 item_index = cxgbe_get_flow_item_index(items, 737 RTE_FLOW_ITEM_TYPE_ETH); 738 if (item_index < 0) 739 return rte_flow_error_set(e, EINVAL, 740 RTE_FLOW_ERROR_TYPE_ACTION, a, 741 "No RTE_FLOW_ITEM_TYPE_ETH " 742 "found"); 743 fs->swapmac = 1; 744 break; 745 case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC: 746 item_index = cxgbe_get_flow_item_index(items, 747 RTE_FLOW_ITEM_TYPE_ETH); 748 if (item_index < 0) 749 return rte_flow_error_set(e, EINVAL, 750 RTE_FLOW_ERROR_TYPE_ACTION, a, 751 "No RTE_FLOW_ITEM_TYPE_ETH " 752 "found"); 753 mac = (const struct rte_flow_action_set_mac *)a->conf; 754 755 fs->newsmac = 1; 756 memcpy(fs->smac, mac->mac_addr, sizeof(fs->smac)); 757 break; 758 case RTE_FLOW_ACTION_TYPE_SET_MAC_DST: 759 item_index = cxgbe_get_flow_item_index(items, 760 RTE_FLOW_ITEM_TYPE_ETH); 761 if (item_index < 0) 762 return rte_flow_error_set(e, EINVAL, 763 RTE_FLOW_ERROR_TYPE_ACTION, a, 764 "No RTE_FLOW_ITEM_TYPE_ETH found"); 765 mac = (const struct rte_flow_action_set_mac *)a->conf; 766 767 fs->newdmac = 1; 768 memcpy(fs->dmac, mac->mac_addr, sizeof(fs->dmac)); 769 break; 770 default: 771 /* We are not supposed to come here */ 772 return rte_flow_error_set(e, EINVAL, 773 RTE_FLOW_ERROR_TYPE_ACTION, a, 774 "Action not supported"); 775 } 776 777 return 0; 778 } 779 780 static int 781 cxgbe_rtef_parse_actions(struct rte_flow *flow, 782 const struct rte_flow_item items[], 783 const struct rte_flow_action action[], 784 struct rte_flow_error *e) 785 { 786 struct ch_filter_specification *fs = &flow->fs; 787 uint8_t nmode = 0, nat_ipv4 = 0, nat_ipv6 = 0; 788 uint8_t vlan_set_vid = 0, vlan_set_pcp = 0; 789 const struct rte_flow_action_queue *q; 790 const struct rte_flow_action *a; 791 char abit = 0; 792 int ret; 793 794 for (a = action; a->type != RTE_FLOW_ACTION_TYPE_END; a++) { 795 switch (a->type) { 796 case RTE_FLOW_ACTION_TYPE_VOID: 797 continue; 798 case RTE_FLOW_ACTION_TYPE_DROP: 799 if (abit++) 800 return rte_flow_error_set(e, EINVAL, 801 RTE_FLOW_ERROR_TYPE_ACTION, a, 802 "specify only 1 pass/drop"); 803 fs->action = FILTER_DROP; 804 break; 805 case RTE_FLOW_ACTION_TYPE_QUEUE: 806 q = (const struct rte_flow_action_queue *)a->conf; 807 if (!q) 808 return rte_flow_error_set(e, EINVAL, 809 RTE_FLOW_ERROR_TYPE_ACTION, q, 810 "specify rx queue index"); 811 if (check_rxq(flow->dev, q->index)) 812 return rte_flow_error_set(e, EINVAL, 813 RTE_FLOW_ERROR_TYPE_ACTION, q, 814 "Invalid rx queue"); 815 if (abit++) 816 return rte_flow_error_set(e, EINVAL, 817 RTE_FLOW_ERROR_TYPE_ACTION, a, 818 "specify only 1 pass/drop"); 819 fs->action = FILTER_PASS; 820 fs->dirsteer = 1; 821 fs->iq = q->index; 822 break; 823 case RTE_FLOW_ACTION_TYPE_COUNT: 824 fs->hitcnts = 1; 825 break; 826 case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID: 827 vlan_set_vid++; 828 goto action_switch; 829 case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP: 830 vlan_set_pcp++; 831 goto action_switch; 832 case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: 833 case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN: 834 case RTE_FLOW_ACTION_TYPE_MAC_SWAP: 835 case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC: 836 case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST: 837 nat_ipv4++; 838 goto action_switch; 839 case RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC: 840 case RTE_FLOW_ACTION_TYPE_SET_IPV6_DST: 841 nat_ipv6++; 842 goto action_switch; 843 case RTE_FLOW_ACTION_TYPE_SET_TP_SRC: 844 case RTE_FLOW_ACTION_TYPE_SET_TP_DST: 845 case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC: 846 case RTE_FLOW_ACTION_TYPE_SET_MAC_DST: 847 action_switch: 848 /* We allow multiple switch actions, but switch is 849 * not compatible with either queue or drop 850 */ 851 if (abit++ && fs->action != FILTER_SWITCH) 852 return rte_flow_error_set(e, EINVAL, 853 RTE_FLOW_ERROR_TYPE_ACTION, a, 854 "overlapping action specified"); 855 if (nat_ipv4 && nat_ipv6) 856 return rte_flow_error_set(e, EINVAL, 857 RTE_FLOW_ERROR_TYPE_ACTION, a, 858 "Can't have one address ipv4 and the" 859 " other ipv6"); 860 861 ret = ch_rte_parse_atype_switch(a, items, &nmode, fs, 862 e); 863 if (ret) 864 return ret; 865 fs->action = FILTER_SWITCH; 866 break; 867 default: 868 /* Not supported action : return error */ 869 return rte_flow_error_set(e, ENOTSUP, 870 RTE_FLOW_ERROR_TYPE_ACTION, 871 a, "Action not supported"); 872 } 873 } 874 875 if (fs->newvlan == VLAN_REWRITE && (!vlan_set_vid || !vlan_set_pcp)) 876 return rte_flow_error_set(e, EINVAL, 877 RTE_FLOW_ERROR_TYPE_ACTION, a, 878 "Both OF_SET_VLAN_VID and " 879 "OF_SET_VLAN_PCP must be specified"); 880 881 if (ch_rte_parse_nat(nmode, fs)) 882 return rte_flow_error_set(e, EINVAL, 883 RTE_FLOW_ERROR_TYPE_ACTION, a, 884 "invalid settings for swich action"); 885 return 0; 886 } 887 888 static struct chrte_fparse parseitem[] = { 889 [RTE_FLOW_ITEM_TYPE_ETH] = { 890 .fptr = ch_rte_parsetype_eth, 891 .dmask = &(const struct rte_flow_item_eth){ 892 .hdr.dst_addr.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 893 .hdr.src_addr.addr_bytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 894 .hdr.ether_type = 0xffff, 895 } 896 }, 897 898 [RTE_FLOW_ITEM_TYPE_VLAN] = { 899 .fptr = ch_rte_parsetype_vlan, 900 .dmask = &(const struct rte_flow_item_vlan){ 901 .hdr.vlan_tci = 0xffff, 902 .hdr.eth_proto = 0xffff, 903 } 904 }, 905 906 [RTE_FLOW_ITEM_TYPE_IPV4] = { 907 .fptr = ch_rte_parsetype_ipv4, 908 .dmask = &(const struct rte_flow_item_ipv4) { 909 .hdr = { 910 .src_addr = RTE_BE32(0xffffffff), 911 .dst_addr = RTE_BE32(0xffffffff), 912 .type_of_service = 0xff, 913 }, 914 }, 915 }, 916 917 [RTE_FLOW_ITEM_TYPE_IPV6] = { 918 .fptr = ch_rte_parsetype_ipv6, 919 .dmask = &(const struct rte_flow_item_ipv6) { 920 .hdr = { 921 .src_addr = RTE_IPV6_MASK_FULL, 922 .dst_addr = RTE_IPV6_MASK_FULL, 923 .vtc_flow = RTE_BE32(0xff000000), 924 }, 925 }, 926 }, 927 928 [RTE_FLOW_ITEM_TYPE_UDP] = { 929 .fptr = ch_rte_parsetype_udp, 930 .dmask = &rte_flow_item_udp_mask, 931 }, 932 933 [RTE_FLOW_ITEM_TYPE_TCP] = { 934 .fptr = ch_rte_parsetype_tcp, 935 .dmask = &rte_flow_item_tcp_mask, 936 }, 937 }; 938 939 static int 940 cxgbe_rtef_parse_items(struct rte_flow *flow, 941 const struct rte_flow_item items[], 942 struct rte_flow_error *e) 943 { 944 struct adapter *adap = ethdev2adap(flow->dev); 945 const struct rte_flow_item *i; 946 char repeat[ARRAY_SIZE(parseitem)] = {0}; 947 948 for (i = items; i->type != RTE_FLOW_ITEM_TYPE_END; i++) { 949 struct chrte_fparse *idx; 950 int ret; 951 952 if (i->type >= ARRAY_SIZE(parseitem)) 953 return rte_flow_error_set(e, ENOTSUP, 954 RTE_FLOW_ERROR_TYPE_ITEM, 955 i, "Item not supported"); 956 957 switch (i->type) { 958 case RTE_FLOW_ITEM_TYPE_VOID: 959 continue; 960 default: 961 /* check if item is repeated */ 962 if (repeat[i->type] && 963 i->type != RTE_FLOW_ITEM_TYPE_VLAN) 964 return rte_flow_error_set(e, ENOTSUP, 965 RTE_FLOW_ERROR_TYPE_ITEM, i, 966 "parse items cannot be repeated(except void/vlan)"); 967 968 repeat[i->type] = 1; 969 970 /* validate the item */ 971 ret = cxgbe_validate_item(i, e); 972 if (ret) 973 return ret; 974 975 idx = &flow->item_parser[i->type]; 976 if (!idx || !idx->fptr) { 977 return rte_flow_error_set(e, ENOTSUP, 978 RTE_FLOW_ERROR_TYPE_ITEM, i, 979 "Item not supported"); 980 } else { 981 ret = idx->fptr(idx->dmask, i, &flow->fs, e); 982 if (ret) 983 return ret; 984 } 985 } 986 } 987 988 cxgbe_tweak_filter_spec(adap, &flow->fs); 989 cxgbe_fill_filter_region(adap, &flow->fs); 990 991 return 0; 992 } 993 994 static int 995 cxgbe_flow_parse(struct rte_flow *flow, 996 const struct rte_flow_attr *attr, 997 const struct rte_flow_item item[], 998 const struct rte_flow_action action[], 999 struct rte_flow_error *e) 1000 { 1001 int ret; 1002 /* parse user request into ch_filter_specification */ 1003 ret = cxgbe_rtef_parse_attr(flow, attr, e); 1004 if (ret) 1005 return ret; 1006 ret = cxgbe_rtef_parse_items(flow, item, e); 1007 if (ret) 1008 return ret; 1009 return cxgbe_rtef_parse_actions(flow, item, action, e); 1010 } 1011 1012 static int __cxgbe_flow_create(struct rte_eth_dev *dev, struct rte_flow *flow) 1013 { 1014 struct ch_filter_specification *fs = &flow->fs; 1015 struct adapter *adap = ethdev2adap(dev); 1016 struct tid_info *t = &adap->tids; 1017 struct filter_ctx ctx; 1018 unsigned int fidx; 1019 int err; 1020 1021 if (cxgbe_get_fidx(flow, &fidx)) 1022 return -ENOMEM; 1023 if (cxgbe_verify_fidx(flow, fidx, 0)) 1024 return -1; 1025 1026 t4_init_completion(&ctx.completion); 1027 /* go create the filter */ 1028 err = cxgbe_set_filter(dev, fidx, fs, &ctx); 1029 if (err) { 1030 dev_err(adap, "Error %d while creating filter.\n", err); 1031 return err; 1032 } 1033 1034 /* Poll the FW for reply */ 1035 err = cxgbe_poll_for_completion(&adap->sge.fw_evtq, 1036 CXGBE_FLOW_POLL_MS, 1037 CXGBE_FLOW_POLL_CNT, 1038 &ctx.completion); 1039 if (err) { 1040 dev_err(adap, "Filter set operation timed out (%d)\n", err); 1041 return err; 1042 } 1043 if (ctx.result) { 1044 dev_err(adap, "Hardware error %d while creating the filter.\n", 1045 ctx.result); 1046 return ctx.result; 1047 } 1048 1049 if (fs->cap) { /* to destroy the filter */ 1050 flow->fidx = ctx.tid; 1051 flow->f = lookup_tid(t, ctx.tid); 1052 } else { 1053 flow->fidx = fidx; 1054 flow->f = &adap->tids.ftid_tab[fidx]; 1055 } 1056 1057 return 0; 1058 } 1059 1060 static struct rte_flow * 1061 cxgbe_flow_create(struct rte_eth_dev *dev, 1062 const struct rte_flow_attr *attr, 1063 const struct rte_flow_item item[], 1064 const struct rte_flow_action action[], 1065 struct rte_flow_error *e) 1066 { 1067 struct adapter *adap = ethdev2adap(dev); 1068 struct rte_flow *flow; 1069 int ret; 1070 1071 flow = t4_os_alloc(sizeof(struct rte_flow)); 1072 if (!flow) { 1073 rte_flow_error_set(e, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE, 1074 NULL, "Unable to allocate memory for" 1075 " filter_entry"); 1076 return NULL; 1077 } 1078 1079 flow->item_parser = parseitem; 1080 flow->dev = dev; 1081 flow->fs.private = (void *)flow; 1082 1083 if (cxgbe_flow_parse(flow, attr, item, action, e)) { 1084 t4_os_free(flow); 1085 return NULL; 1086 } 1087 1088 t4_os_lock(&adap->flow_lock); 1089 /* go, interact with cxgbe_filter */ 1090 ret = __cxgbe_flow_create(dev, flow); 1091 t4_os_unlock(&adap->flow_lock); 1092 if (ret) { 1093 rte_flow_error_set(e, ret, RTE_FLOW_ERROR_TYPE_HANDLE, 1094 NULL, "Unable to create flow rule"); 1095 t4_os_free(flow); 1096 return NULL; 1097 } 1098 1099 flow->f->private = flow; /* Will be used during flush */ 1100 1101 return flow; 1102 } 1103 1104 static int __cxgbe_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow) 1105 { 1106 struct adapter *adap = ethdev2adap(dev); 1107 struct filter_entry *f = flow->f; 1108 struct ch_filter_specification *fs; 1109 struct filter_ctx ctx; 1110 int err; 1111 1112 fs = &f->fs; 1113 if (cxgbe_verify_fidx(flow, flow->fidx, 1)) 1114 return -1; 1115 1116 t4_init_completion(&ctx.completion); 1117 err = cxgbe_del_filter(dev, flow->fidx, fs, &ctx); 1118 if (err) { 1119 dev_err(adap, "Error %d while deleting filter.\n", err); 1120 return err; 1121 } 1122 1123 /* Poll the FW for reply */ 1124 err = cxgbe_poll_for_completion(&adap->sge.fw_evtq, 1125 CXGBE_FLOW_POLL_MS, 1126 CXGBE_FLOW_POLL_CNT, 1127 &ctx.completion); 1128 if (err) { 1129 dev_err(adap, "Filter delete operation timed out (%d)\n", err); 1130 return err; 1131 } 1132 if (ctx.result) { 1133 dev_err(adap, "Hardware error %d while deleting the filter.\n", 1134 ctx.result); 1135 return ctx.result; 1136 } 1137 1138 return 0; 1139 } 1140 1141 static int 1142 cxgbe_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, 1143 struct rte_flow_error *e) 1144 { 1145 struct adapter *adap = ethdev2adap(dev); 1146 int ret; 1147 1148 t4_os_lock(&adap->flow_lock); 1149 ret = __cxgbe_flow_destroy(dev, flow); 1150 t4_os_unlock(&adap->flow_lock); 1151 if (ret) 1152 return rte_flow_error_set(e, ret, RTE_FLOW_ERROR_TYPE_HANDLE, 1153 flow, "error destroying filter."); 1154 t4_os_free(flow); 1155 return 0; 1156 } 1157 1158 static int __cxgbe_flow_query(struct rte_flow *flow, u64 *count, 1159 u64 *byte_count) 1160 { 1161 struct adapter *adap = ethdev2adap(flow->dev); 1162 struct ch_filter_specification fs = flow->f->fs; 1163 unsigned int fidx = flow->fidx; 1164 int ret = 0; 1165 1166 ret = cxgbe_get_filter_count(adap, fidx, count, fs.cap, 0); 1167 if (ret) 1168 return ret; 1169 return cxgbe_get_filter_count(adap, fidx, byte_count, fs.cap, 1); 1170 } 1171 1172 static int 1173 cxgbe_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow, 1174 const struct rte_flow_action *action, void *data, 1175 struct rte_flow_error *e) 1176 { 1177 struct adapter *adap = ethdev2adap(flow->dev); 1178 struct ch_filter_specification fs; 1179 struct rte_flow_query_count *c; 1180 struct filter_entry *f; 1181 int ret; 1182 1183 RTE_SET_USED(dev); 1184 1185 f = flow->f; 1186 fs = f->fs; 1187 1188 if (action->type != RTE_FLOW_ACTION_TYPE_COUNT) 1189 return rte_flow_error_set(e, ENOTSUP, 1190 RTE_FLOW_ERROR_TYPE_ACTION, NULL, 1191 "only count supported for query"); 1192 1193 /* 1194 * This is a valid operation, Since we are allowed to do chelsio 1195 * specific operations in rte side of our code but not vise-versa 1196 * 1197 * So, fs can be queried/modified here BUT rte_flow_query_count 1198 * cannot be worked on by the lower layer since we want to maintain 1199 * it as rte_flow agnostic. 1200 */ 1201 if (!fs.hitcnts) 1202 return rte_flow_error_set(e, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, 1203 &fs, "filter hit counters were not" 1204 " enabled during filter creation"); 1205 1206 c = (struct rte_flow_query_count *)data; 1207 1208 t4_os_lock(&adap->flow_lock); 1209 ret = __cxgbe_flow_query(flow, &c->hits, &c->bytes); 1210 if (ret) { 1211 rte_flow_error_set(e, -ret, RTE_FLOW_ERROR_TYPE_ACTION, 1212 f, "cxgbe pmd failed to perform query"); 1213 goto out; 1214 } 1215 1216 /* Query was successful */ 1217 c->bytes_set = 1; 1218 c->hits_set = 1; 1219 if (c->reset) 1220 cxgbe_clear_filter_count(adap, flow->fidx, f->fs.cap, true); 1221 1222 out: 1223 t4_os_unlock(&adap->flow_lock); 1224 return ret; 1225 } 1226 1227 static int 1228 cxgbe_flow_validate(struct rte_eth_dev *dev, 1229 const struct rte_flow_attr *attr, 1230 const struct rte_flow_item item[], 1231 const struct rte_flow_action action[], 1232 struct rte_flow_error *e) 1233 { 1234 struct adapter *adap = ethdev2adap(dev); 1235 struct rte_flow *flow; 1236 unsigned int fidx; 1237 int ret = 0; 1238 1239 flow = t4_os_alloc(sizeof(struct rte_flow)); 1240 if (!flow) 1241 return rte_flow_error_set(e, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE, 1242 NULL, 1243 "Unable to allocate memory for filter_entry"); 1244 1245 flow->item_parser = parseitem; 1246 flow->dev = dev; 1247 flow->fs.private = (void *)flow; 1248 1249 ret = cxgbe_flow_parse(flow, attr, item, action, e); 1250 if (ret) { 1251 t4_os_free(flow); 1252 return ret; 1253 } 1254 1255 if (cxgbe_validate_filter(adap, &flow->fs)) { 1256 t4_os_free(flow); 1257 return rte_flow_error_set(e, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, 1258 NULL, 1259 "validation failed. Check f/w config file."); 1260 } 1261 1262 t4_os_lock(&adap->flow_lock); 1263 if (cxgbe_get_fidx(flow, &fidx)) { 1264 ret = rte_flow_error_set(e, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE, 1265 NULL, "no memory in tcam."); 1266 goto out; 1267 } 1268 1269 if (cxgbe_verify_fidx(flow, fidx, 0)) { 1270 ret = rte_flow_error_set(e, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, 1271 NULL, "validation failed"); 1272 goto out; 1273 } 1274 1275 out: 1276 t4_os_unlock(&adap->flow_lock); 1277 t4_os_free(flow); 1278 return ret; 1279 } 1280 1281 /* 1282 * @ret : > 0 filter destroyed successfully 1283 * < 0 error destroying filter 1284 * == 1 filter not active / not found 1285 */ 1286 static int 1287 cxgbe_check_n_destroy(struct filter_entry *f, struct rte_eth_dev *dev) 1288 { 1289 if (f && (f->valid || f->pending) && 1290 f->dev == dev && /* Only if user has asked for this port */ 1291 f->private) /* We (rte_flow) created this filter */ 1292 return __cxgbe_flow_destroy(dev, (struct rte_flow *)f->private); 1293 return 1; 1294 } 1295 1296 static int cxgbe_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *e) 1297 { 1298 struct adapter *adap = ethdev2adap(dev); 1299 unsigned int i; 1300 int ret = 0; 1301 1302 t4_os_lock(&adap->flow_lock); 1303 if (adap->tids.ftid_tab) { 1304 struct filter_entry *f = &adap->tids.ftid_tab[0]; 1305 1306 for (i = 0; i < adap->tids.nftids; i++, f++) { 1307 ret = cxgbe_check_n_destroy(f, dev); 1308 if (ret < 0) { 1309 rte_flow_error_set(e, ret, 1310 RTE_FLOW_ERROR_TYPE_HANDLE, 1311 f->private, 1312 "error destroying TCAM " 1313 "filter."); 1314 goto out; 1315 } 1316 } 1317 } 1318 1319 if (is_hashfilter(adap) && adap->tids.tid_tab) { 1320 struct filter_entry *f; 1321 1322 for (i = adap->tids.hash_base; i <= adap->tids.ntids; i++) { 1323 f = (struct filter_entry *)adap->tids.tid_tab[i]; 1324 1325 ret = cxgbe_check_n_destroy(f, dev); 1326 if (ret < 0) { 1327 rte_flow_error_set(e, ret, 1328 RTE_FLOW_ERROR_TYPE_HANDLE, 1329 f->private, 1330 "error destroying HASH " 1331 "filter."); 1332 goto out; 1333 } 1334 } 1335 } 1336 1337 out: 1338 t4_os_unlock(&adap->flow_lock); 1339 return ret >= 0 ? 0 : ret; 1340 } 1341 1342 static const struct rte_flow_ops cxgbe_flow_ops = { 1343 .validate = cxgbe_flow_validate, 1344 .create = cxgbe_flow_create, 1345 .destroy = cxgbe_flow_destroy, 1346 .flush = cxgbe_flow_flush, 1347 .query = cxgbe_flow_query, 1348 .isolate = NULL, 1349 }; 1350 1351 int 1352 cxgbe_dev_flow_ops_get(struct rte_eth_dev *dev __rte_unused, 1353 const struct rte_flow_ops **ops) 1354 { 1355 *ops = &cxgbe_flow_ops; 1356 return 0; 1357 } 1358