1 // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 /* Microsemi Ocelot Switch driver 3 * Copyright (c) 2019 Microsemi Corporation 4 */ 5 6 #include <net/pkt_cls.h> 7 #include <net/tc_act/tc_gact.h> 8 #include <soc/mscc/ocelot_vcap.h> 9 #include "ocelot_police.h" 10 #include "ocelot_vcap.h" 11 12 /* Arbitrarily chosen constants for encoding the VCAP block and lookup number 13 * into the chain number. This is UAPI. 14 */ 15 #define VCAP_BLOCK 10000 16 #define VCAP_LOOKUP 1000 17 #define VCAP_IS1_NUM_LOOKUPS 3 18 #define VCAP_IS2_NUM_LOOKUPS 2 19 #define VCAP_IS2_NUM_PAG 256 20 #define VCAP_IS1_CHAIN(lookup) \ 21 (1 * VCAP_BLOCK + (lookup) * VCAP_LOOKUP) 22 #define VCAP_IS2_CHAIN(lookup, pag) \ 23 (2 * VCAP_BLOCK + (lookup) * VCAP_LOOKUP + (pag)) 24 /* PSFP chain and block ID */ 25 #define PSFP_BLOCK_ID OCELOT_NUM_VCAP_BLOCKS 26 #define OCELOT_PSFP_CHAIN (3 * VCAP_BLOCK) 27 28 static int ocelot_chain_to_block(int chain, bool ingress) 29 { 30 int lookup, pag; 31 32 if (!ingress) { 33 if (chain == 0) 34 return VCAP_ES0; 35 return -EOPNOTSUPP; 36 } 37 38 /* Backwards compatibility with older, single-chain tc-flower 39 * offload support in Ocelot 40 */ 41 if (chain == 0) 42 return VCAP_IS2; 43 44 for (lookup = 0; lookup < VCAP_IS1_NUM_LOOKUPS; lookup++) 45 if (chain == VCAP_IS1_CHAIN(lookup)) 46 return VCAP_IS1; 47 48 for (lookup = 0; lookup < VCAP_IS2_NUM_LOOKUPS; lookup++) 49 for (pag = 0; pag < VCAP_IS2_NUM_PAG; pag++) 50 if (chain == VCAP_IS2_CHAIN(lookup, pag)) 51 return VCAP_IS2; 52 53 if (chain == OCELOT_PSFP_CHAIN) 54 return PSFP_BLOCK_ID; 55 56 return -EOPNOTSUPP; 57 } 58 59 /* Caller must ensure this is a valid IS1 or IS2 chain first, 60 * by calling ocelot_chain_to_block. 61 */ 62 static int ocelot_chain_to_lookup(int chain) 63 { 64 /* Backwards compatibility with older, single-chain tc-flower 65 * offload support in Ocelot 66 */ 67 if (chain == 0) 68 return 0; 69 70 return (chain / VCAP_LOOKUP) % 10; 71 } 72 73 /* Caller must ensure this is a valid IS2 chain first, 74 * by calling ocelot_chain_to_block. 75 */ 76 static int ocelot_chain_to_pag(int chain) 77 { 78 int lookup; 79 80 /* Backwards compatibility with older, single-chain tc-flower 81 * offload support in Ocelot 82 */ 83 if (chain == 0) 84 return 0; 85 86 lookup = ocelot_chain_to_lookup(chain); 87 88 /* calculate PAG value as chain index relative to the first PAG */ 89 return chain - VCAP_IS2_CHAIN(lookup, 0); 90 } 91 92 static bool ocelot_is_goto_target_valid(int goto_target, int chain, 93 bool ingress) 94 { 95 int pag; 96 97 /* Can't offload GOTO in VCAP ES0 */ 98 if (!ingress) 99 return (goto_target < 0); 100 101 /* Non-optional GOTOs */ 102 if (chain == 0) 103 /* VCAP IS1 can be skipped, either partially or completely */ 104 return (goto_target == VCAP_IS1_CHAIN(0) || 105 goto_target == VCAP_IS1_CHAIN(1) || 106 goto_target == VCAP_IS1_CHAIN(2) || 107 goto_target == VCAP_IS2_CHAIN(0, 0) || 108 goto_target == VCAP_IS2_CHAIN(1, 0) || 109 goto_target == OCELOT_PSFP_CHAIN); 110 111 if (chain == VCAP_IS1_CHAIN(0)) 112 return (goto_target == VCAP_IS1_CHAIN(1)); 113 114 if (chain == VCAP_IS1_CHAIN(1)) 115 return (goto_target == VCAP_IS1_CHAIN(2)); 116 117 /* Lookup 2 of VCAP IS1 can really support non-optional GOTOs, 118 * using a Policy Association Group (PAG) value, which is an 8-bit 119 * value encoding a VCAP IS2 target chain. 120 */ 121 if (chain == VCAP_IS1_CHAIN(2)) { 122 for (pag = 0; pag < VCAP_IS2_NUM_PAG; pag++) 123 if (goto_target == VCAP_IS2_CHAIN(0, pag)) 124 return true; 125 126 return false; 127 } 128 129 /* Non-optional GOTO from VCAP IS2 lookup 0 to lookup 1. 130 * We cannot change the PAG at this point. 131 */ 132 for (pag = 0; pag < VCAP_IS2_NUM_PAG; pag++) 133 if (chain == VCAP_IS2_CHAIN(0, pag)) 134 return (goto_target == VCAP_IS2_CHAIN(1, pag)); 135 136 /* VCAP IS2 lookup 1 can goto to PSFP block if hardware support */ 137 for (pag = 0; pag < VCAP_IS2_NUM_PAG; pag++) 138 if (chain == VCAP_IS2_CHAIN(1, pag)) 139 return (goto_target == OCELOT_PSFP_CHAIN); 140 141 return false; 142 } 143 144 static struct ocelot_vcap_filter * 145 ocelot_find_vcap_filter_that_points_at(struct ocelot *ocelot, int chain) 146 { 147 struct ocelot_vcap_filter *filter; 148 struct ocelot_vcap_block *block; 149 int block_id; 150 151 block_id = ocelot_chain_to_block(chain, true); 152 if (block_id < 0) 153 return NULL; 154 155 if (block_id == VCAP_IS2) { 156 block = &ocelot->block[VCAP_IS1]; 157 158 list_for_each_entry(filter, &block->rules, list) 159 if (filter->type == OCELOT_VCAP_FILTER_PAG && 160 filter->goto_target == chain) 161 return filter; 162 } 163 164 list_for_each_entry(filter, &ocelot->dummy_rules, list) 165 if (filter->goto_target == chain) 166 return filter; 167 168 return NULL; 169 } 170 171 static int 172 ocelot_flower_parse_ingress_vlan_modify(struct ocelot *ocelot, int port, 173 struct ocelot_vcap_filter *filter, 174 const struct flow_action_entry *a, 175 struct netlink_ext_ack *extack) 176 { 177 struct ocelot_port *ocelot_port = ocelot->ports[port]; 178 179 if (filter->goto_target != -1) { 180 NL_SET_ERR_MSG_MOD(extack, 181 "Last action must be GOTO"); 182 return -EOPNOTSUPP; 183 } 184 185 if (!ocelot_port->vlan_aware) { 186 NL_SET_ERR_MSG_MOD(extack, 187 "Can only modify VLAN under VLAN aware bridge"); 188 return -EOPNOTSUPP; 189 } 190 191 filter->action.vid_replace_ena = true; 192 filter->action.pcp_dei_ena = true; 193 filter->action.vid = a->vlan.vid; 194 filter->action.pcp = a->vlan.prio; 195 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; 196 197 return 0; 198 } 199 200 static int 201 ocelot_flower_parse_egress_vlan_modify(struct ocelot_vcap_filter *filter, 202 const struct flow_action_entry *a, 203 struct netlink_ext_ack *extack) 204 { 205 enum ocelot_tag_tpid_sel tpid; 206 207 switch (ntohs(a->vlan.proto)) { 208 case ETH_P_8021Q: 209 tpid = OCELOT_TAG_TPID_SEL_8021Q; 210 break; 211 case ETH_P_8021AD: 212 tpid = OCELOT_TAG_TPID_SEL_8021AD; 213 break; 214 default: 215 NL_SET_ERR_MSG_MOD(extack, 216 "Cannot modify custom TPID"); 217 return -EOPNOTSUPP; 218 } 219 220 filter->action.tag_a_tpid_sel = tpid; 221 filter->action.push_outer_tag = OCELOT_ES0_TAG; 222 filter->action.tag_a_vid_sel = OCELOT_ES0_VID_PLUS_CLASSIFIED_VID; 223 filter->action.vid_a_val = a->vlan.vid; 224 filter->action.pcp_a_val = a->vlan.prio; 225 filter->action.tag_a_pcp_sel = OCELOT_ES0_PCP; 226 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; 227 228 return 0; 229 } 230 231 static int ocelot_flower_parse_action(struct ocelot *ocelot, int port, 232 bool ingress, struct flow_cls_offload *f, 233 struct ocelot_vcap_filter *filter) 234 { 235 const struct flow_action *action = &f->rule->action; 236 struct netlink_ext_ack *extack = f->common.extack; 237 bool allow_missing_goto_target = false; 238 const struct flow_action_entry *a; 239 enum ocelot_tag_tpid_sel tpid; 240 int i, chain, egress_port; 241 u32 pol_ix, pol_max; 242 u64 rate; 243 int err; 244 245 if (!flow_action_basic_hw_stats_check(&f->rule->action, 246 f->common.extack)) 247 return -EOPNOTSUPP; 248 249 chain = f->common.chain_index; 250 filter->block_id = ocelot_chain_to_block(chain, ingress); 251 if (filter->block_id < 0) { 252 NL_SET_ERR_MSG_MOD(extack, "Cannot offload to this chain"); 253 return -EOPNOTSUPP; 254 } 255 if (filter->block_id == VCAP_IS1 || filter->block_id == VCAP_IS2) 256 filter->lookup = ocelot_chain_to_lookup(chain); 257 if (filter->block_id == VCAP_IS2) 258 filter->pag = ocelot_chain_to_pag(chain); 259 260 filter->goto_target = -1; 261 filter->type = OCELOT_VCAP_FILTER_DUMMY; 262 263 flow_action_for_each(i, a, action) { 264 switch (a->id) { 265 case FLOW_ACTION_DROP: 266 if (filter->block_id != VCAP_IS2) { 267 NL_SET_ERR_MSG_MOD(extack, 268 "Drop action can only be offloaded to VCAP IS2"); 269 return -EOPNOTSUPP; 270 } 271 if (filter->goto_target != -1) { 272 NL_SET_ERR_MSG_MOD(extack, 273 "Last action must be GOTO"); 274 return -EOPNOTSUPP; 275 } 276 filter->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY; 277 filter->action.port_mask = 0; 278 filter->action.police_ena = true; 279 filter->action.pol_ix = OCELOT_POLICER_DISCARD; 280 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; 281 break; 282 case FLOW_ACTION_TRAP: 283 if (filter->block_id != VCAP_IS2 || 284 filter->lookup != 0) { 285 NL_SET_ERR_MSG_MOD(extack, 286 "Trap action can only be offloaded to VCAP IS2 lookup 0"); 287 return -EOPNOTSUPP; 288 } 289 if (filter->goto_target != -1) { 290 NL_SET_ERR_MSG_MOD(extack, 291 "Last action must be GOTO"); 292 return -EOPNOTSUPP; 293 } 294 filter->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY; 295 filter->action.port_mask = 0; 296 filter->action.cpu_copy_ena = true; 297 filter->action.cpu_qu_num = 0; 298 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; 299 filter->is_trap = true; 300 break; 301 case FLOW_ACTION_POLICE: 302 if (filter->block_id == PSFP_BLOCK_ID) { 303 filter->type = OCELOT_PSFP_FILTER_OFFLOAD; 304 break; 305 } 306 if (filter->block_id != VCAP_IS2 || 307 filter->lookup != 0) { 308 NL_SET_ERR_MSG_MOD(extack, 309 "Police action can only be offloaded to VCAP IS2 lookup 0 or PSFP"); 310 return -EOPNOTSUPP; 311 } 312 if (filter->goto_target != -1) { 313 NL_SET_ERR_MSG_MOD(extack, 314 "Last action must be GOTO"); 315 return -EOPNOTSUPP; 316 } 317 318 err = ocelot_policer_validate(action, a, extack); 319 if (err) 320 return err; 321 322 filter->action.police_ena = true; 323 324 pol_ix = a->hw_index + ocelot->vcap_pol.base; 325 pol_max = ocelot->vcap_pol.max; 326 327 if (ocelot->vcap_pol.max2 && pol_ix > pol_max) { 328 pol_ix += ocelot->vcap_pol.base2 - pol_max - 1; 329 pol_max = ocelot->vcap_pol.max2; 330 } 331 332 if (pol_ix >= pol_max) 333 return -EINVAL; 334 335 filter->action.pol_ix = pol_ix; 336 337 rate = a->police.rate_bytes_ps; 338 filter->action.pol.rate = div_u64(rate, 1000) * 8; 339 filter->action.pol.burst = a->police.burst; 340 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; 341 break; 342 case FLOW_ACTION_REDIRECT: 343 if (filter->block_id != VCAP_IS2) { 344 NL_SET_ERR_MSG_MOD(extack, 345 "Redirect action can only be offloaded to VCAP IS2"); 346 return -EOPNOTSUPP; 347 } 348 if (filter->goto_target != -1) { 349 NL_SET_ERR_MSG_MOD(extack, 350 "Last action must be GOTO"); 351 return -EOPNOTSUPP; 352 } 353 egress_port = ocelot->ops->netdev_to_port(a->dev); 354 if (egress_port < 0) { 355 NL_SET_ERR_MSG_MOD(extack, 356 "Destination not an ocelot port"); 357 return -EOPNOTSUPP; 358 } 359 filter->action.mask_mode = OCELOT_MASK_MODE_REDIRECT; 360 filter->action.port_mask = BIT(egress_port); 361 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; 362 break; 363 case FLOW_ACTION_MIRRED: 364 if (filter->block_id != VCAP_IS2) { 365 NL_SET_ERR_MSG_MOD(extack, 366 "Mirror action can only be offloaded to VCAP IS2"); 367 return -EOPNOTSUPP; 368 } 369 if (filter->goto_target != -1) { 370 NL_SET_ERR_MSG_MOD(extack, 371 "Last action must be GOTO"); 372 return -EOPNOTSUPP; 373 } 374 egress_port = ocelot->ops->netdev_to_port(a->dev); 375 if (egress_port < 0) { 376 NL_SET_ERR_MSG_MOD(extack, 377 "Destination not an ocelot port"); 378 return -EOPNOTSUPP; 379 } 380 filter->egress_port.value = egress_port; 381 filter->action.mirror_ena = true; 382 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; 383 break; 384 case FLOW_ACTION_VLAN_POP: 385 if (filter->block_id != VCAP_IS1) { 386 NL_SET_ERR_MSG_MOD(extack, 387 "VLAN pop action can only be offloaded to VCAP IS1"); 388 return -EOPNOTSUPP; 389 } 390 if (filter->goto_target != -1) { 391 NL_SET_ERR_MSG_MOD(extack, 392 "Last action must be GOTO"); 393 return -EOPNOTSUPP; 394 } 395 filter->action.vlan_pop_cnt_ena = true; 396 filter->action.vlan_pop_cnt++; 397 if (filter->action.vlan_pop_cnt > 2) { 398 NL_SET_ERR_MSG_MOD(extack, 399 "Cannot pop more than 2 VLAN headers"); 400 return -EOPNOTSUPP; 401 } 402 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; 403 break; 404 case FLOW_ACTION_VLAN_MANGLE: 405 if (filter->block_id == VCAP_IS1) { 406 err = ocelot_flower_parse_ingress_vlan_modify(ocelot, port, 407 filter, a, 408 extack); 409 } else if (filter->block_id == VCAP_ES0) { 410 err = ocelot_flower_parse_egress_vlan_modify(filter, a, 411 extack); 412 } else { 413 NL_SET_ERR_MSG_MOD(extack, 414 "VLAN modify action can only be offloaded to VCAP IS1 or ES0"); 415 err = -EOPNOTSUPP; 416 } 417 if (err) 418 return err; 419 break; 420 case FLOW_ACTION_PRIORITY: 421 if (filter->block_id != VCAP_IS1) { 422 NL_SET_ERR_MSG_MOD(extack, 423 "Priority action can only be offloaded to VCAP IS1"); 424 return -EOPNOTSUPP; 425 } 426 if (filter->goto_target != -1) { 427 NL_SET_ERR_MSG_MOD(extack, 428 "Last action must be GOTO"); 429 return -EOPNOTSUPP; 430 } 431 filter->action.qos_ena = true; 432 filter->action.qos_val = a->priority; 433 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; 434 break; 435 case FLOW_ACTION_GOTO: 436 filter->goto_target = a->chain_index; 437 438 if (filter->block_id == VCAP_IS1 && filter->lookup == 2) { 439 int pag = ocelot_chain_to_pag(filter->goto_target); 440 441 filter->action.pag_override_mask = 0xff; 442 filter->action.pag_val = pag; 443 filter->type = OCELOT_VCAP_FILTER_PAG; 444 } 445 break; 446 case FLOW_ACTION_VLAN_PUSH: 447 if (filter->block_id != VCAP_ES0) { 448 NL_SET_ERR_MSG_MOD(extack, 449 "VLAN push action can only be offloaded to VCAP ES0"); 450 return -EOPNOTSUPP; 451 } 452 switch (ntohs(a->vlan.proto)) { 453 case ETH_P_8021Q: 454 tpid = OCELOT_TAG_TPID_SEL_8021Q; 455 break; 456 case ETH_P_8021AD: 457 tpid = OCELOT_TAG_TPID_SEL_8021AD; 458 break; 459 default: 460 NL_SET_ERR_MSG_MOD(extack, 461 "Cannot push custom TPID"); 462 return -EOPNOTSUPP; 463 } 464 filter->action.tag_a_tpid_sel = tpid; 465 filter->action.push_outer_tag = OCELOT_ES0_TAG; 466 filter->action.tag_a_vid_sel = OCELOT_ES0_VID; 467 filter->action.vid_a_val = a->vlan.vid; 468 filter->action.pcp_a_val = a->vlan.prio; 469 filter->type = OCELOT_VCAP_FILTER_OFFLOAD; 470 break; 471 case FLOW_ACTION_GATE: 472 if (filter->block_id != PSFP_BLOCK_ID) { 473 NL_SET_ERR_MSG_MOD(extack, 474 "Gate action can only be offloaded to PSFP chain"); 475 return -EOPNOTSUPP; 476 } 477 filter->type = OCELOT_PSFP_FILTER_OFFLOAD; 478 break; 479 default: 480 NL_SET_ERR_MSG_MOD(extack, "Cannot offload action"); 481 return -EOPNOTSUPP; 482 } 483 } 484 485 if (filter->goto_target == -1) { 486 if ((filter->block_id == VCAP_IS2 && filter->lookup == 1) || 487 chain == 0 || filter->block_id == PSFP_BLOCK_ID) { 488 allow_missing_goto_target = true; 489 } else { 490 NL_SET_ERR_MSG_MOD(extack, "Missing GOTO action"); 491 return -EOPNOTSUPP; 492 } 493 } 494 495 if (!ocelot_is_goto_target_valid(filter->goto_target, chain, ingress) && 496 !allow_missing_goto_target) { 497 NL_SET_ERR_MSG_MOD(extack, "Cannot offload this GOTO target"); 498 return -EOPNOTSUPP; 499 } 500 501 return 0; 502 } 503 504 static int ocelot_flower_parse_indev(struct ocelot *ocelot, int port, 505 struct flow_cls_offload *f, 506 struct ocelot_vcap_filter *filter) 507 { 508 struct flow_rule *rule = flow_cls_offload_flow_rule(f); 509 const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0]; 510 int key_length = vcap->keys[VCAP_ES0_IGR_PORT].length; 511 struct netlink_ext_ack *extack = f->common.extack; 512 struct net_device *dev, *indev; 513 struct flow_match_meta match; 514 int ingress_port; 515 516 flow_rule_match_meta(rule, &match); 517 518 if (!match.mask->ingress_ifindex) 519 return 0; 520 521 if (match.mask->ingress_ifindex != 0xFFFFFFFF) { 522 NL_SET_ERR_MSG_MOD(extack, "Unsupported ingress ifindex mask"); 523 return -EOPNOTSUPP; 524 } 525 526 dev = ocelot->ops->port_to_netdev(ocelot, port); 527 if (!dev) 528 return -EINVAL; 529 530 indev = __dev_get_by_index(dev_net(dev), match.key->ingress_ifindex); 531 if (!indev) { 532 NL_SET_ERR_MSG_MOD(extack, 533 "Can't find the ingress port to match on"); 534 return -ENOENT; 535 } 536 537 ingress_port = ocelot->ops->netdev_to_port(indev); 538 if (ingress_port < 0) { 539 NL_SET_ERR_MSG_MOD(extack, 540 "Can only offload an ocelot ingress port"); 541 return -EOPNOTSUPP; 542 } 543 if (ingress_port == port) { 544 NL_SET_ERR_MSG_MOD(extack, 545 "Ingress port is equal to the egress port"); 546 return -EINVAL; 547 } 548 549 filter->ingress_port.value = ingress_port; 550 filter->ingress_port.mask = GENMASK(key_length - 1, 0); 551 552 return 0; 553 } 554 555 static int 556 ocelot_flower_parse_key(struct ocelot *ocelot, int port, bool ingress, 557 struct flow_cls_offload *f, 558 struct ocelot_vcap_filter *filter) 559 { 560 struct flow_rule *rule = flow_cls_offload_flow_rule(f); 561 struct flow_dissector *dissector = rule->match.dissector; 562 struct netlink_ext_ack *extack = f->common.extack; 563 u16 proto = ntohs(f->common.protocol); 564 bool match_protocol = true; 565 int ret; 566 567 if (dissector->used_keys & 568 ~(BIT(FLOW_DISSECTOR_KEY_CONTROL) | 569 BIT(FLOW_DISSECTOR_KEY_BASIC) | 570 BIT(FLOW_DISSECTOR_KEY_META) | 571 BIT(FLOW_DISSECTOR_KEY_PORTS) | 572 BIT(FLOW_DISSECTOR_KEY_VLAN) | 573 BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) | 574 BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) | 575 BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS))) { 576 return -EOPNOTSUPP; 577 } 578 579 /* For VCAP ES0 (egress rewriter) we can match on the ingress port */ 580 if (!ingress) { 581 ret = ocelot_flower_parse_indev(ocelot, port, f, filter); 582 if (ret) 583 return ret; 584 } 585 586 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) { 587 struct flow_match_control match; 588 589 flow_rule_match_control(rule, &match); 590 } 591 592 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { 593 struct flow_match_eth_addrs match; 594 595 if (filter->block_id == VCAP_ES0) { 596 NL_SET_ERR_MSG_MOD(extack, 597 "VCAP ES0 cannot match on MAC address"); 598 return -EOPNOTSUPP; 599 } 600 601 /* The hw support mac matches only for MAC_ETYPE key, 602 * therefore if other matches(port, tcp flags, etc) are added 603 * then just bail out 604 */ 605 if ((dissector->used_keys & 606 (BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) | 607 BIT(FLOW_DISSECTOR_KEY_BASIC) | 608 BIT(FLOW_DISSECTOR_KEY_CONTROL))) != 609 (BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) | 610 BIT(FLOW_DISSECTOR_KEY_BASIC) | 611 BIT(FLOW_DISSECTOR_KEY_CONTROL))) 612 return -EOPNOTSUPP; 613 614 flow_rule_match_eth_addrs(rule, &match); 615 616 if (filter->block_id == VCAP_IS1 && 617 !is_zero_ether_addr(match.mask->dst)) { 618 NL_SET_ERR_MSG_MOD(extack, 619 "Key type S1_NORMAL cannot match on destination MAC"); 620 return -EOPNOTSUPP; 621 } 622 623 filter->key_type = OCELOT_VCAP_KEY_ETYPE; 624 ether_addr_copy(filter->key.etype.dmac.value, 625 match.key->dst); 626 ether_addr_copy(filter->key.etype.smac.value, 627 match.key->src); 628 ether_addr_copy(filter->key.etype.dmac.mask, 629 match.mask->dst); 630 ether_addr_copy(filter->key.etype.smac.mask, 631 match.mask->src); 632 goto finished_key_parsing; 633 } 634 635 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) { 636 struct flow_match_basic match; 637 638 flow_rule_match_basic(rule, &match); 639 if (ntohs(match.key->n_proto) == ETH_P_IP) { 640 if (filter->block_id == VCAP_ES0) { 641 NL_SET_ERR_MSG_MOD(extack, 642 "VCAP ES0 cannot match on IP protocol"); 643 return -EOPNOTSUPP; 644 } 645 646 filter->key_type = OCELOT_VCAP_KEY_IPV4; 647 filter->key.ipv4.proto.value[0] = 648 match.key->ip_proto; 649 filter->key.ipv4.proto.mask[0] = 650 match.mask->ip_proto; 651 match_protocol = false; 652 } 653 if (ntohs(match.key->n_proto) == ETH_P_IPV6) { 654 if (filter->block_id == VCAP_ES0) { 655 NL_SET_ERR_MSG_MOD(extack, 656 "VCAP ES0 cannot match on IP protocol"); 657 return -EOPNOTSUPP; 658 } 659 660 filter->key_type = OCELOT_VCAP_KEY_IPV6; 661 filter->key.ipv6.proto.value[0] = 662 match.key->ip_proto; 663 filter->key.ipv6.proto.mask[0] = 664 match.mask->ip_proto; 665 match_protocol = false; 666 } 667 } 668 669 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS) && 670 proto == ETH_P_IP) { 671 struct flow_match_ipv4_addrs match; 672 u8 *tmp; 673 674 if (filter->block_id == VCAP_ES0) { 675 NL_SET_ERR_MSG_MOD(extack, 676 "VCAP ES0 cannot match on IP address"); 677 return -EOPNOTSUPP; 678 } 679 680 flow_rule_match_ipv4_addrs(rule, &match); 681 682 if (filter->block_id == VCAP_IS1 && *(u32 *)&match.mask->dst) { 683 NL_SET_ERR_MSG_MOD(extack, 684 "Key type S1_NORMAL cannot match on destination IP"); 685 return -EOPNOTSUPP; 686 } 687 688 tmp = &filter->key.ipv4.sip.value.addr[0]; 689 memcpy(tmp, &match.key->src, 4); 690 691 tmp = &filter->key.ipv4.sip.mask.addr[0]; 692 memcpy(tmp, &match.mask->src, 4); 693 694 tmp = &filter->key.ipv4.dip.value.addr[0]; 695 memcpy(tmp, &match.key->dst, 4); 696 697 tmp = &filter->key.ipv4.dip.mask.addr[0]; 698 memcpy(tmp, &match.mask->dst, 4); 699 match_protocol = false; 700 } 701 702 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS) && 703 proto == ETH_P_IPV6) { 704 return -EOPNOTSUPP; 705 } 706 707 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) { 708 struct flow_match_ports match; 709 710 if (filter->block_id == VCAP_ES0) { 711 NL_SET_ERR_MSG_MOD(extack, 712 "VCAP ES0 cannot match on L4 ports"); 713 return -EOPNOTSUPP; 714 } 715 716 flow_rule_match_ports(rule, &match); 717 filter->key.ipv4.sport.value = ntohs(match.key->src); 718 filter->key.ipv4.sport.mask = ntohs(match.mask->src); 719 filter->key.ipv4.dport.value = ntohs(match.key->dst); 720 filter->key.ipv4.dport.mask = ntohs(match.mask->dst); 721 match_protocol = false; 722 } 723 724 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) { 725 struct flow_match_vlan match; 726 727 flow_rule_match_vlan(rule, &match); 728 filter->key_type = OCELOT_VCAP_KEY_ANY; 729 filter->vlan.vid.value = match.key->vlan_id; 730 filter->vlan.vid.mask = match.mask->vlan_id; 731 filter->vlan.pcp.value[0] = match.key->vlan_priority; 732 filter->vlan.pcp.mask[0] = match.mask->vlan_priority; 733 match_protocol = false; 734 } 735 736 finished_key_parsing: 737 if (match_protocol && proto != ETH_P_ALL) { 738 if (filter->block_id == VCAP_ES0) { 739 NL_SET_ERR_MSG_MOD(extack, 740 "VCAP ES0 cannot match on L2 proto"); 741 return -EOPNOTSUPP; 742 } 743 744 /* TODO: support SNAP, LLC etc */ 745 if (proto < ETH_P_802_3_MIN) 746 return -EOPNOTSUPP; 747 filter->key_type = OCELOT_VCAP_KEY_ETYPE; 748 *(__be16 *)filter->key.etype.etype.value = htons(proto); 749 *(__be16 *)filter->key.etype.etype.mask = htons(0xffff); 750 } 751 /* else, a filter of type OCELOT_VCAP_KEY_ANY is implicitly added */ 752 753 return 0; 754 } 755 756 static int ocelot_flower_parse(struct ocelot *ocelot, int port, bool ingress, 757 struct flow_cls_offload *f, 758 struct ocelot_vcap_filter *filter) 759 { 760 int ret; 761 762 filter->prio = f->common.prio; 763 filter->id.cookie = f->cookie; 764 filter->id.tc_offload = true; 765 766 ret = ocelot_flower_parse_action(ocelot, port, ingress, f, filter); 767 if (ret) 768 return ret; 769 770 /* PSFP filter need to parse key by stream identification function. */ 771 if (filter->type == OCELOT_PSFP_FILTER_OFFLOAD) 772 return 0; 773 774 return ocelot_flower_parse_key(ocelot, port, ingress, f, filter); 775 } 776 777 static struct ocelot_vcap_filter 778 *ocelot_vcap_filter_create(struct ocelot *ocelot, int port, bool ingress, 779 struct flow_cls_offload *f) 780 { 781 struct ocelot_vcap_filter *filter; 782 783 filter = kzalloc(sizeof(*filter), GFP_KERNEL); 784 if (!filter) 785 return NULL; 786 787 if (ingress) { 788 filter->ingress_port_mask = BIT(port); 789 } else { 790 const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0]; 791 int key_length = vcap->keys[VCAP_ES0_EGR_PORT].length; 792 793 filter->egress_port.value = port; 794 filter->egress_port.mask = GENMASK(key_length - 1, 0); 795 } 796 797 return filter; 798 } 799 800 static int ocelot_vcap_dummy_filter_add(struct ocelot *ocelot, 801 struct ocelot_vcap_filter *filter) 802 { 803 list_add(&filter->list, &ocelot->dummy_rules); 804 805 return 0; 806 } 807 808 static int ocelot_vcap_dummy_filter_del(struct ocelot *ocelot, 809 struct ocelot_vcap_filter *filter) 810 { 811 list_del(&filter->list); 812 kfree(filter); 813 814 return 0; 815 } 816 817 /* If we have an egress VLAN modification rule, we need to actually write the 818 * delta between the input VLAN (from the key) and the output VLAN (from the 819 * action), but the action was parsed first. So we need to patch the delta into 820 * the action here. 821 */ 822 static int 823 ocelot_flower_patch_es0_vlan_modify(struct ocelot_vcap_filter *filter, 824 struct netlink_ext_ack *extack) 825 { 826 if (filter->block_id != VCAP_ES0 || 827 filter->action.tag_a_vid_sel != OCELOT_ES0_VID_PLUS_CLASSIFIED_VID) 828 return 0; 829 830 if (filter->vlan.vid.mask != VLAN_VID_MASK) { 831 NL_SET_ERR_MSG_MOD(extack, 832 "VCAP ES0 VLAN rewriting needs a full VLAN in the key"); 833 return -EOPNOTSUPP; 834 } 835 836 filter->action.vid_a_val -= filter->vlan.vid.value; 837 filter->action.vid_a_val &= VLAN_VID_MASK; 838 839 return 0; 840 } 841 842 int ocelot_cls_flower_replace(struct ocelot *ocelot, int port, 843 struct flow_cls_offload *f, bool ingress) 844 { 845 struct netlink_ext_ack *extack = f->common.extack; 846 struct ocelot_vcap_filter *filter; 847 int chain = f->common.chain_index; 848 int block_id, ret; 849 850 if (chain && !ocelot_find_vcap_filter_that_points_at(ocelot, chain)) { 851 NL_SET_ERR_MSG_MOD(extack, "No default GOTO action points to this chain"); 852 return -EOPNOTSUPP; 853 } 854 855 block_id = ocelot_chain_to_block(chain, ingress); 856 if (block_id < 0) { 857 NL_SET_ERR_MSG_MOD(extack, "Cannot offload to this chain"); 858 return -EOPNOTSUPP; 859 } 860 861 filter = ocelot_vcap_block_find_filter_by_id(&ocelot->block[block_id], 862 f->cookie, true); 863 if (filter) { 864 /* Filter already exists on other ports */ 865 if (!ingress) { 866 NL_SET_ERR_MSG_MOD(extack, "VCAP ES0 does not support shared filters"); 867 return -EOPNOTSUPP; 868 } 869 870 filter->ingress_port_mask |= BIT(port); 871 872 return ocelot_vcap_filter_replace(ocelot, filter); 873 } 874 875 /* Filter didn't exist, create it now */ 876 filter = ocelot_vcap_filter_create(ocelot, port, ingress, f); 877 if (!filter) 878 return -ENOMEM; 879 880 ret = ocelot_flower_parse(ocelot, port, ingress, f, filter); 881 if (ret) { 882 kfree(filter); 883 return ret; 884 } 885 886 ret = ocelot_flower_patch_es0_vlan_modify(filter, extack); 887 if (ret) { 888 kfree(filter); 889 return ret; 890 } 891 892 /* The non-optional GOTOs for the TCAM skeleton don't need 893 * to be actually offloaded. 894 */ 895 if (filter->type == OCELOT_VCAP_FILTER_DUMMY) 896 return ocelot_vcap_dummy_filter_add(ocelot, filter); 897 898 if (filter->type == OCELOT_PSFP_FILTER_OFFLOAD) { 899 kfree(filter); 900 if (ocelot->ops->psfp_filter_add) 901 return ocelot->ops->psfp_filter_add(ocelot, port, f); 902 903 NL_SET_ERR_MSG_MOD(extack, "PSFP chain is not supported in HW"); 904 return -EOPNOTSUPP; 905 } 906 907 return ocelot_vcap_filter_add(ocelot, filter, f->common.extack); 908 } 909 EXPORT_SYMBOL_GPL(ocelot_cls_flower_replace); 910 911 int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port, 912 struct flow_cls_offload *f, bool ingress) 913 { 914 struct ocelot_vcap_filter *filter; 915 struct ocelot_vcap_block *block; 916 int block_id; 917 918 block_id = ocelot_chain_to_block(f->common.chain_index, ingress); 919 if (block_id < 0) 920 return 0; 921 922 if (block_id == PSFP_BLOCK_ID) { 923 if (ocelot->ops->psfp_filter_del) 924 return ocelot->ops->psfp_filter_del(ocelot, f); 925 926 return -EOPNOTSUPP; 927 } 928 929 block = &ocelot->block[block_id]; 930 931 filter = ocelot_vcap_block_find_filter_by_id(block, f->cookie, true); 932 if (!filter) 933 return 0; 934 935 if (filter->type == OCELOT_VCAP_FILTER_DUMMY) 936 return ocelot_vcap_dummy_filter_del(ocelot, filter); 937 938 if (ingress) { 939 filter->ingress_port_mask &= ~BIT(port); 940 if (filter->ingress_port_mask) 941 return ocelot_vcap_filter_replace(ocelot, filter); 942 } 943 944 return ocelot_vcap_filter_del(ocelot, filter); 945 } 946 EXPORT_SYMBOL_GPL(ocelot_cls_flower_destroy); 947 948 int ocelot_cls_flower_stats(struct ocelot *ocelot, int port, 949 struct flow_cls_offload *f, bool ingress) 950 { 951 struct ocelot_vcap_filter *filter; 952 struct ocelot_vcap_block *block; 953 struct flow_stats stats = {0}; 954 int block_id, ret; 955 956 block_id = ocelot_chain_to_block(f->common.chain_index, ingress); 957 if (block_id < 0) 958 return 0; 959 960 if (block_id == PSFP_BLOCK_ID) { 961 if (ocelot->ops->psfp_stats_get) { 962 ret = ocelot->ops->psfp_stats_get(ocelot, f, &stats); 963 if (ret) 964 return ret; 965 966 goto stats_update; 967 } 968 969 return -EOPNOTSUPP; 970 } 971 972 block = &ocelot->block[block_id]; 973 974 filter = ocelot_vcap_block_find_filter_by_id(block, f->cookie, true); 975 if (!filter || filter->type == OCELOT_VCAP_FILTER_DUMMY) 976 return 0; 977 978 ret = ocelot_vcap_filter_stats_update(ocelot, filter); 979 if (ret) 980 return ret; 981 982 stats.pkts = filter->stats.pkts; 983 984 stats_update: 985 flow_stats_update(&f->stats, 0x0, stats.pkts, stats.drops, 0x0, 986 FLOW_ACTION_HW_STATS_IMMEDIATE); 987 return 0; 988 } 989 EXPORT_SYMBOL_GPL(ocelot_cls_flower_stats); 990