1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * DPAA2 Ethernet Switch flower support 4 * 5 * Copyright 2021 NXP 6 * 7 */ 8 9 #include "dpaa2-switch.h" 10 11 static int dpaa2_switch_flower_parse_key(struct flow_cls_offload *cls, 12 struct dpsw_acl_key *acl_key) 13 { 14 struct flow_rule *rule = flow_cls_offload_flow_rule(cls); 15 struct flow_dissector *dissector = rule->match.dissector; 16 struct netlink_ext_ack *extack = cls->common.extack; 17 struct dpsw_acl_fields *acl_h, *acl_m; 18 19 if (dissector->used_keys & 20 ~(BIT(FLOW_DISSECTOR_KEY_BASIC) | 21 BIT(FLOW_DISSECTOR_KEY_CONTROL) | 22 BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) | 23 BIT(FLOW_DISSECTOR_KEY_VLAN) | 24 BIT(FLOW_DISSECTOR_KEY_PORTS) | 25 BIT(FLOW_DISSECTOR_KEY_IP) | 26 BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) | 27 BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS))) { 28 NL_SET_ERR_MSG_MOD(extack, 29 "Unsupported keys used"); 30 return -EOPNOTSUPP; 31 } 32 33 acl_h = &acl_key->match; 34 acl_m = &acl_key->mask; 35 36 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) { 37 struct flow_match_basic match; 38 39 flow_rule_match_basic(rule, &match); 40 acl_h->l3_protocol = match.key->ip_proto; 41 acl_h->l2_ether_type = be16_to_cpu(match.key->n_proto); 42 acl_m->l3_protocol = match.mask->ip_proto; 43 acl_m->l2_ether_type = be16_to_cpu(match.mask->n_proto); 44 } 45 46 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { 47 struct flow_match_eth_addrs match; 48 49 flow_rule_match_eth_addrs(rule, &match); 50 ether_addr_copy(acl_h->l2_dest_mac, &match.key->dst[0]); 51 ether_addr_copy(acl_h->l2_source_mac, &match.key->src[0]); 52 ether_addr_copy(acl_m->l2_dest_mac, &match.mask->dst[0]); 53 ether_addr_copy(acl_m->l2_source_mac, &match.mask->src[0]); 54 } 55 56 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) { 57 struct flow_match_vlan match; 58 59 flow_rule_match_vlan(rule, &match); 60 acl_h->l2_vlan_id = match.key->vlan_id; 61 acl_h->l2_tpid = be16_to_cpu(match.key->vlan_tpid); 62 acl_h->l2_pcp_dei = match.key->vlan_priority << 1 | 63 match.key->vlan_dei; 64 65 acl_m->l2_vlan_id = match.mask->vlan_id; 66 acl_m->l2_tpid = be16_to_cpu(match.mask->vlan_tpid); 67 acl_m->l2_pcp_dei = match.mask->vlan_priority << 1 | 68 match.mask->vlan_dei; 69 } 70 71 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) { 72 struct flow_match_ipv4_addrs match; 73 74 flow_rule_match_ipv4_addrs(rule, &match); 75 acl_h->l3_source_ip = be32_to_cpu(match.key->src); 76 acl_h->l3_dest_ip = be32_to_cpu(match.key->dst); 77 acl_m->l3_source_ip = be32_to_cpu(match.mask->src); 78 acl_m->l3_dest_ip = be32_to_cpu(match.mask->dst); 79 } 80 81 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) { 82 struct flow_match_ports match; 83 84 flow_rule_match_ports(rule, &match); 85 acl_h->l4_source_port = be16_to_cpu(match.key->src); 86 acl_h->l4_dest_port = be16_to_cpu(match.key->dst); 87 acl_m->l4_source_port = be16_to_cpu(match.mask->src); 88 acl_m->l4_dest_port = be16_to_cpu(match.mask->dst); 89 } 90 91 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) { 92 struct flow_match_ip match; 93 94 flow_rule_match_ip(rule, &match); 95 if (match.mask->ttl != 0) { 96 NL_SET_ERR_MSG_MOD(extack, 97 "Matching on TTL not supported"); 98 return -EOPNOTSUPP; 99 } 100 101 if ((match.mask->tos & 0x3) != 0) { 102 NL_SET_ERR_MSG_MOD(extack, 103 "Matching on ECN not supported, only DSCP"); 104 return -EOPNOTSUPP; 105 } 106 107 acl_h->l3_dscp = match.key->tos >> 2; 108 acl_m->l3_dscp = match.mask->tos >> 2; 109 } 110 111 return 0; 112 } 113 114 int dpaa2_switch_acl_entry_add(struct dpaa2_switch_filter_block *filter_block, 115 struct dpaa2_switch_acl_entry *entry) 116 { 117 struct dpsw_acl_entry_cfg *acl_entry_cfg = &entry->cfg; 118 struct ethsw_core *ethsw = filter_block->ethsw; 119 struct dpsw_acl_key *acl_key = &entry->key; 120 struct device *dev = ethsw->dev; 121 u8 *cmd_buff; 122 int err; 123 124 cmd_buff = kzalloc(DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, GFP_KERNEL); 125 if (!cmd_buff) 126 return -ENOMEM; 127 128 dpsw_acl_prepare_entry_cfg(acl_key, cmd_buff); 129 130 acl_entry_cfg->key_iova = dma_map_single(dev, cmd_buff, 131 DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, 132 DMA_TO_DEVICE); 133 if (unlikely(dma_mapping_error(dev, acl_entry_cfg->key_iova))) { 134 dev_err(dev, "DMA mapping failed\n"); 135 return -EFAULT; 136 } 137 138 err = dpsw_acl_add_entry(ethsw->mc_io, 0, ethsw->dpsw_handle, 139 filter_block->acl_id, acl_entry_cfg); 140 141 dma_unmap_single(dev, acl_entry_cfg->key_iova, sizeof(cmd_buff), 142 DMA_TO_DEVICE); 143 if (err) { 144 dev_err(dev, "dpsw_acl_add_entry() failed %d\n", err); 145 return err; 146 } 147 148 kfree(cmd_buff); 149 150 return 0; 151 } 152 153 static int 154 dpaa2_switch_acl_entry_remove(struct dpaa2_switch_filter_block *block, 155 struct dpaa2_switch_acl_entry *entry) 156 { 157 struct dpsw_acl_entry_cfg *acl_entry_cfg = &entry->cfg; 158 struct dpsw_acl_key *acl_key = &entry->key; 159 struct ethsw_core *ethsw = block->ethsw; 160 struct device *dev = ethsw->dev; 161 u8 *cmd_buff; 162 int err; 163 164 cmd_buff = kzalloc(DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, GFP_KERNEL); 165 if (!cmd_buff) 166 return -ENOMEM; 167 168 dpsw_acl_prepare_entry_cfg(acl_key, cmd_buff); 169 170 acl_entry_cfg->key_iova = dma_map_single(dev, cmd_buff, 171 DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, 172 DMA_TO_DEVICE); 173 if (unlikely(dma_mapping_error(dev, acl_entry_cfg->key_iova))) { 174 dev_err(dev, "DMA mapping failed\n"); 175 return -EFAULT; 176 } 177 178 err = dpsw_acl_remove_entry(ethsw->mc_io, 0, ethsw->dpsw_handle, 179 block->acl_id, acl_entry_cfg); 180 181 dma_unmap_single(dev, acl_entry_cfg->key_iova, sizeof(cmd_buff), 182 DMA_TO_DEVICE); 183 if (err) { 184 dev_err(dev, "dpsw_acl_remove_entry() failed %d\n", err); 185 return err; 186 } 187 188 kfree(cmd_buff); 189 190 return 0; 191 } 192 193 static int 194 dpaa2_switch_acl_entry_add_to_list(struct dpaa2_switch_filter_block *block, 195 struct dpaa2_switch_acl_entry *entry) 196 { 197 struct dpaa2_switch_acl_entry *tmp; 198 struct list_head *pos, *n; 199 int index = 0; 200 201 if (list_empty(&block->acl_entries)) { 202 list_add(&entry->list, &block->acl_entries); 203 return index; 204 } 205 206 list_for_each_safe(pos, n, &block->acl_entries) { 207 tmp = list_entry(pos, struct dpaa2_switch_acl_entry, list); 208 if (entry->prio < tmp->prio) 209 break; 210 index++; 211 } 212 list_add(&entry->list, pos->prev); 213 return index; 214 } 215 216 static struct dpaa2_switch_acl_entry* 217 dpaa2_switch_acl_entry_get_by_index(struct dpaa2_switch_filter_block *block, 218 int index) 219 { 220 struct dpaa2_switch_acl_entry *tmp; 221 int i = 0; 222 223 list_for_each_entry(tmp, &block->acl_entries, list) { 224 if (i == index) 225 return tmp; 226 ++i; 227 } 228 229 return NULL; 230 } 231 232 static int 233 dpaa2_switch_acl_entry_set_precedence(struct dpaa2_switch_filter_block *block, 234 struct dpaa2_switch_acl_entry *entry, 235 int precedence) 236 { 237 int err; 238 239 err = dpaa2_switch_acl_entry_remove(block, entry); 240 if (err) 241 return err; 242 243 entry->cfg.precedence = precedence; 244 return dpaa2_switch_acl_entry_add(block, entry); 245 } 246 247 static int 248 dpaa2_switch_acl_tbl_add_entry(struct dpaa2_switch_filter_block *block, 249 struct dpaa2_switch_acl_entry *entry) 250 { 251 struct dpaa2_switch_acl_entry *tmp; 252 int index, i, precedence, err; 253 254 /* Add the new ACL entry to the linked list and get its index */ 255 index = dpaa2_switch_acl_entry_add_to_list(block, entry); 256 257 /* Move up in priority the ACL entries to make space 258 * for the new filter. 259 */ 260 precedence = DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES - block->num_acl_rules - 1; 261 for (i = 0; i < index; i++) { 262 tmp = dpaa2_switch_acl_entry_get_by_index(block, i); 263 264 err = dpaa2_switch_acl_entry_set_precedence(block, tmp, 265 precedence); 266 if (err) 267 return err; 268 269 precedence++; 270 } 271 272 /* Add the new entry to hardware */ 273 entry->cfg.precedence = precedence; 274 err = dpaa2_switch_acl_entry_add(block, entry); 275 block->num_acl_rules++; 276 277 return err; 278 } 279 280 static struct dpaa2_switch_acl_entry * 281 dpaa2_switch_acl_tbl_find_entry_by_cookie(struct dpaa2_switch_filter_block *block, 282 unsigned long cookie) 283 { 284 struct dpaa2_switch_acl_entry *tmp, *n; 285 286 list_for_each_entry_safe(tmp, n, &block->acl_entries, list) { 287 if (tmp->cookie == cookie) 288 return tmp; 289 } 290 return NULL; 291 } 292 293 static int 294 dpaa2_switch_acl_entry_get_index(struct dpaa2_switch_filter_block *block, 295 struct dpaa2_switch_acl_entry *entry) 296 { 297 struct dpaa2_switch_acl_entry *tmp, *n; 298 int index = 0; 299 300 list_for_each_entry_safe(tmp, n, &block->acl_entries, list) { 301 if (tmp->cookie == entry->cookie) 302 return index; 303 index++; 304 } 305 return -ENOENT; 306 } 307 308 static struct dpaa2_switch_mirror_entry * 309 dpaa2_switch_mirror_find_entry_by_cookie(struct dpaa2_switch_filter_block *block, 310 unsigned long cookie) 311 { 312 struct dpaa2_switch_mirror_entry *tmp, *n; 313 314 list_for_each_entry_safe(tmp, n, &block->mirror_entries, list) { 315 if (tmp->cookie == cookie) 316 return tmp; 317 } 318 return NULL; 319 } 320 321 static int 322 dpaa2_switch_acl_tbl_remove_entry(struct dpaa2_switch_filter_block *block, 323 struct dpaa2_switch_acl_entry *entry) 324 { 325 struct dpaa2_switch_acl_entry *tmp; 326 int index, i, precedence, err; 327 328 index = dpaa2_switch_acl_entry_get_index(block, entry); 329 330 /* Remove from hardware the ACL entry */ 331 err = dpaa2_switch_acl_entry_remove(block, entry); 332 if (err) 333 return err; 334 335 block->num_acl_rules--; 336 337 /* Remove it from the list also */ 338 list_del(&entry->list); 339 340 /* Move down in priority the entries over the deleted one */ 341 precedence = entry->cfg.precedence; 342 for (i = index - 1; i >= 0; i--) { 343 tmp = dpaa2_switch_acl_entry_get_by_index(block, i); 344 err = dpaa2_switch_acl_entry_set_precedence(block, tmp, 345 precedence); 346 if (err) 347 return err; 348 349 precedence--; 350 } 351 352 kfree(entry); 353 354 return 0; 355 } 356 357 static int dpaa2_switch_tc_parse_action_acl(struct ethsw_core *ethsw, 358 struct flow_action_entry *cls_act, 359 struct dpsw_acl_result *dpsw_act, 360 struct netlink_ext_ack *extack) 361 { 362 int err = 0; 363 364 switch (cls_act->id) { 365 case FLOW_ACTION_TRAP: 366 dpsw_act->action = DPSW_ACL_ACTION_REDIRECT_TO_CTRL_IF; 367 break; 368 case FLOW_ACTION_REDIRECT: 369 if (!dpaa2_switch_port_dev_check(cls_act->dev)) { 370 NL_SET_ERR_MSG_MOD(extack, 371 "Destination not a DPAA2 switch port"); 372 return -EOPNOTSUPP; 373 } 374 375 dpsw_act->if_id = dpaa2_switch_get_index(ethsw, cls_act->dev); 376 dpsw_act->action = DPSW_ACL_ACTION_REDIRECT; 377 break; 378 case FLOW_ACTION_DROP: 379 dpsw_act->action = DPSW_ACL_ACTION_DROP; 380 break; 381 default: 382 NL_SET_ERR_MSG_MOD(extack, 383 "Action not supported"); 384 err = -EOPNOTSUPP; 385 goto out; 386 } 387 388 out: 389 return err; 390 } 391 392 static int 393 dpaa2_switch_block_add_mirror(struct dpaa2_switch_filter_block *block, 394 struct dpaa2_switch_mirror_entry *entry, 395 u16 to, struct netlink_ext_ack *extack) 396 { 397 unsigned long block_ports = block->ports; 398 struct ethsw_core *ethsw = block->ethsw; 399 struct ethsw_port_priv *port_priv; 400 unsigned long ports_added = 0; 401 u16 vlan = entry->cfg.vlan_id; 402 bool mirror_port_enabled; 403 int err, port; 404 405 /* Setup the mirroring port */ 406 mirror_port_enabled = (ethsw->mirror_port != ethsw->sw_attr.num_ifs); 407 if (!mirror_port_enabled) { 408 err = dpsw_set_reflection_if(ethsw->mc_io, 0, 409 ethsw->dpsw_handle, to); 410 if (err) 411 return err; 412 ethsw->mirror_port = to; 413 } 414 415 /* Setup the same egress mirroring configuration on all the switch 416 * ports that share the same filter block. 417 */ 418 for_each_set_bit(port, &block_ports, ethsw->sw_attr.num_ifs) { 419 port_priv = ethsw->ports[port]; 420 421 /* We cannot add a per VLAN mirroring rule if the VLAN in 422 * question is not installed on the switch port. 423 */ 424 if (entry->cfg.filter == DPSW_REFLECTION_FILTER_INGRESS_VLAN && 425 !(port_priv->vlans[vlan] & ETHSW_VLAN_MEMBER)) { 426 NL_SET_ERR_MSG(extack, 427 "VLAN must be installed on the switch port"); 428 err = -EINVAL; 429 goto err_remove_filters; 430 } 431 432 err = dpsw_if_add_reflection(ethsw->mc_io, 0, 433 ethsw->dpsw_handle, 434 port, &entry->cfg); 435 if (err) 436 goto err_remove_filters; 437 438 ports_added |= BIT(port); 439 } 440 441 list_add(&entry->list, &block->mirror_entries); 442 443 return 0; 444 445 err_remove_filters: 446 for_each_set_bit(port, &ports_added, ethsw->sw_attr.num_ifs) { 447 dpsw_if_remove_reflection(ethsw->mc_io, 0, ethsw->dpsw_handle, 448 port, &entry->cfg); 449 } 450 451 if (!mirror_port_enabled) 452 ethsw->mirror_port = ethsw->sw_attr.num_ifs; 453 454 return err; 455 } 456 457 static int 458 dpaa2_switch_block_remove_mirror(struct dpaa2_switch_filter_block *block, 459 struct dpaa2_switch_mirror_entry *entry) 460 { 461 struct dpsw_reflection_cfg *cfg = &entry->cfg; 462 unsigned long block_ports = block->ports; 463 struct ethsw_core *ethsw = block->ethsw; 464 int port; 465 466 /* Remove this mirroring configuration from all the ports belonging to 467 * the filter block. 468 */ 469 for_each_set_bit(port, &block_ports, ethsw->sw_attr.num_ifs) 470 dpsw_if_remove_reflection(ethsw->mc_io, 0, ethsw->dpsw_handle, 471 port, cfg); 472 473 /* Also remove it from the list of mirror filters */ 474 list_del(&entry->list); 475 kfree(entry); 476 477 /* If this was the last mirror filter, then unset the mirror port */ 478 if (list_empty(&block->mirror_entries)) 479 ethsw->mirror_port = ethsw->sw_attr.num_ifs; 480 481 return 0; 482 } 483 484 static int 485 dpaa2_switch_cls_flower_replace_acl(struct dpaa2_switch_filter_block *block, 486 struct flow_cls_offload *cls) 487 { 488 struct flow_rule *rule = flow_cls_offload_flow_rule(cls); 489 struct netlink_ext_ack *extack = cls->common.extack; 490 struct dpaa2_switch_acl_entry *acl_entry; 491 struct ethsw_core *ethsw = block->ethsw; 492 struct flow_action_entry *act; 493 int err; 494 495 if (dpaa2_switch_acl_tbl_is_full(block)) { 496 NL_SET_ERR_MSG(extack, "Maximum filter capacity reached"); 497 return -ENOMEM; 498 } 499 500 acl_entry = kzalloc(sizeof(*acl_entry), GFP_KERNEL); 501 if (!acl_entry) 502 return -ENOMEM; 503 504 err = dpaa2_switch_flower_parse_key(cls, &acl_entry->key); 505 if (err) 506 goto free_acl_entry; 507 508 act = &rule->action.entries[0]; 509 err = dpaa2_switch_tc_parse_action_acl(ethsw, act, 510 &acl_entry->cfg.result, extack); 511 if (err) 512 goto free_acl_entry; 513 514 acl_entry->prio = cls->common.prio; 515 acl_entry->cookie = cls->cookie; 516 517 err = dpaa2_switch_acl_tbl_add_entry(block, acl_entry); 518 if (err) 519 goto free_acl_entry; 520 521 return 0; 522 523 free_acl_entry: 524 kfree(acl_entry); 525 526 return err; 527 } 528 529 static int dpaa2_switch_flower_parse_mirror_key(struct flow_cls_offload *cls, 530 u16 *vlan) 531 { 532 struct flow_rule *rule = flow_cls_offload_flow_rule(cls); 533 struct flow_dissector *dissector = rule->match.dissector; 534 struct netlink_ext_ack *extack = cls->common.extack; 535 536 if (dissector->used_keys & 537 ~(BIT(FLOW_DISSECTOR_KEY_BASIC) | 538 BIT(FLOW_DISSECTOR_KEY_CONTROL) | 539 BIT(FLOW_DISSECTOR_KEY_VLAN))) { 540 NL_SET_ERR_MSG_MOD(extack, 541 "Mirroring is supported only per VLAN"); 542 return -EOPNOTSUPP; 543 } 544 545 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) { 546 struct flow_match_vlan match; 547 548 flow_rule_match_vlan(rule, &match); 549 550 if (match.mask->vlan_priority != 0 || 551 match.mask->vlan_dei != 0) { 552 NL_SET_ERR_MSG_MOD(extack, 553 "Only matching on VLAN ID supported"); 554 return -EOPNOTSUPP; 555 } 556 557 if (match.mask->vlan_id != 0xFFF) { 558 NL_SET_ERR_MSG_MOD(extack, 559 "Masked matching not supported"); 560 return -EOPNOTSUPP; 561 } 562 563 *vlan = (u16)match.key->vlan_id; 564 } 565 566 return 0; 567 } 568 569 static int 570 dpaa2_switch_cls_flower_replace_mirror(struct dpaa2_switch_filter_block *block, 571 struct flow_cls_offload *cls) 572 { 573 struct netlink_ext_ack *extack = cls->common.extack; 574 struct dpaa2_switch_mirror_entry *mirror_entry; 575 struct ethsw_core *ethsw = block->ethsw; 576 struct dpaa2_switch_mirror_entry *tmp; 577 struct flow_action_entry *cls_act; 578 struct list_head *pos, *n; 579 bool mirror_port_enabled; 580 u16 if_id, vlan; 581 int err; 582 583 mirror_port_enabled = (ethsw->mirror_port != ethsw->sw_attr.num_ifs); 584 cls_act = &cls->rule->action.entries[0]; 585 586 /* Offload rules only when the destination is a DPAA2 switch port */ 587 if (!dpaa2_switch_port_dev_check(cls_act->dev)) { 588 NL_SET_ERR_MSG_MOD(extack, 589 "Destination not a DPAA2 switch port"); 590 return -EOPNOTSUPP; 591 } 592 if_id = dpaa2_switch_get_index(ethsw, cls_act->dev); 593 594 /* We have a single mirror port but can configure egress mirroring on 595 * all the other switch ports. We need to allow mirroring rules only 596 * when the destination port is the same. 597 */ 598 if (mirror_port_enabled && ethsw->mirror_port != if_id) { 599 NL_SET_ERR_MSG_MOD(extack, 600 "Multiple mirror ports not supported"); 601 return -EBUSY; 602 } 603 604 /* Parse the key */ 605 err = dpaa2_switch_flower_parse_mirror_key(cls, &vlan); 606 if (err) 607 return err; 608 609 /* Make sure that we don't already have a mirror rule with the same 610 * configuration. 611 */ 612 list_for_each_safe(pos, n, &block->mirror_entries) { 613 tmp = list_entry(pos, struct dpaa2_switch_mirror_entry, list); 614 615 if (tmp->cfg.filter == DPSW_REFLECTION_FILTER_INGRESS_VLAN && 616 tmp->cfg.vlan_id == vlan) { 617 NL_SET_ERR_MSG_MOD(extack, 618 "VLAN mirror filter already installed"); 619 return -EBUSY; 620 } 621 } 622 623 mirror_entry = kzalloc(sizeof(*mirror_entry), GFP_KERNEL); 624 if (!mirror_entry) 625 return -ENOMEM; 626 627 mirror_entry->cfg.filter = DPSW_REFLECTION_FILTER_INGRESS_VLAN; 628 mirror_entry->cfg.vlan_id = vlan; 629 mirror_entry->cookie = cls->cookie; 630 631 return dpaa2_switch_block_add_mirror(block, mirror_entry, if_id, 632 extack); 633 } 634 635 int dpaa2_switch_cls_flower_replace(struct dpaa2_switch_filter_block *block, 636 struct flow_cls_offload *cls) 637 { 638 struct flow_rule *rule = flow_cls_offload_flow_rule(cls); 639 struct netlink_ext_ack *extack = cls->common.extack; 640 struct flow_action_entry *act; 641 642 if (!flow_offload_has_one_action(&rule->action)) { 643 NL_SET_ERR_MSG(extack, "Only singular actions are supported"); 644 return -EOPNOTSUPP; 645 } 646 647 act = &rule->action.entries[0]; 648 switch (act->id) { 649 case FLOW_ACTION_REDIRECT: 650 case FLOW_ACTION_TRAP: 651 case FLOW_ACTION_DROP: 652 return dpaa2_switch_cls_flower_replace_acl(block, cls); 653 case FLOW_ACTION_MIRRED: 654 return dpaa2_switch_cls_flower_replace_mirror(block, cls); 655 default: 656 NL_SET_ERR_MSG_MOD(extack, "Action not supported"); 657 return -EOPNOTSUPP; 658 } 659 } 660 661 int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_filter_block *block, 662 struct flow_cls_offload *cls) 663 { 664 struct dpaa2_switch_mirror_entry *mirror_entry; 665 struct dpaa2_switch_acl_entry *acl_entry; 666 667 /* If this filter is a an ACL one, remove it */ 668 acl_entry = dpaa2_switch_acl_tbl_find_entry_by_cookie(block, 669 cls->cookie); 670 if (acl_entry) 671 return dpaa2_switch_acl_tbl_remove_entry(block, acl_entry); 672 673 /* If not, then it has to be a mirror */ 674 mirror_entry = dpaa2_switch_mirror_find_entry_by_cookie(block, 675 cls->cookie); 676 if (mirror_entry) 677 return dpaa2_switch_block_remove_mirror(block, 678 mirror_entry); 679 680 return 0; 681 } 682 683 static int 684 dpaa2_switch_cls_matchall_replace_acl(struct dpaa2_switch_filter_block *block, 685 struct tc_cls_matchall_offload *cls) 686 { 687 struct netlink_ext_ack *extack = cls->common.extack; 688 struct ethsw_core *ethsw = block->ethsw; 689 struct dpaa2_switch_acl_entry *acl_entry; 690 struct flow_action_entry *act; 691 int err; 692 693 if (dpaa2_switch_acl_tbl_is_full(block)) { 694 NL_SET_ERR_MSG(extack, "Maximum filter capacity reached"); 695 return -ENOMEM; 696 } 697 698 acl_entry = kzalloc(sizeof(*acl_entry), GFP_KERNEL); 699 if (!acl_entry) 700 return -ENOMEM; 701 702 act = &cls->rule->action.entries[0]; 703 err = dpaa2_switch_tc_parse_action_acl(ethsw, act, 704 &acl_entry->cfg.result, extack); 705 if (err) 706 goto free_acl_entry; 707 708 acl_entry->prio = cls->common.prio; 709 acl_entry->cookie = cls->cookie; 710 711 err = dpaa2_switch_acl_tbl_add_entry(block, acl_entry); 712 if (err) 713 goto free_acl_entry; 714 715 return 0; 716 717 free_acl_entry: 718 kfree(acl_entry); 719 720 return err; 721 } 722 723 static int 724 dpaa2_switch_cls_matchall_replace_mirror(struct dpaa2_switch_filter_block *block, 725 struct tc_cls_matchall_offload *cls) 726 { 727 struct netlink_ext_ack *extack = cls->common.extack; 728 struct dpaa2_switch_mirror_entry *mirror_entry; 729 struct ethsw_core *ethsw = block->ethsw; 730 struct dpaa2_switch_mirror_entry *tmp; 731 struct flow_action_entry *cls_act; 732 struct list_head *pos, *n; 733 bool mirror_port_enabled; 734 u16 if_id; 735 736 mirror_port_enabled = (ethsw->mirror_port != ethsw->sw_attr.num_ifs); 737 cls_act = &cls->rule->action.entries[0]; 738 739 /* Offload rules only when the destination is a DPAA2 switch port */ 740 if (!dpaa2_switch_port_dev_check(cls_act->dev)) { 741 NL_SET_ERR_MSG_MOD(extack, 742 "Destination not a DPAA2 switch port"); 743 return -EOPNOTSUPP; 744 } 745 if_id = dpaa2_switch_get_index(ethsw, cls_act->dev); 746 747 /* We have a single mirror port but can configure egress mirroring on 748 * all the other switch ports. We need to allow mirroring rules only 749 * when the destination port is the same. 750 */ 751 if (mirror_port_enabled && ethsw->mirror_port != if_id) { 752 NL_SET_ERR_MSG_MOD(extack, 753 "Multiple mirror ports not supported"); 754 return -EBUSY; 755 } 756 757 /* Make sure that we don't already have a mirror rule with the same 758 * configuration. One matchall rule per block is the maximum. 759 */ 760 list_for_each_safe(pos, n, &block->mirror_entries) { 761 tmp = list_entry(pos, struct dpaa2_switch_mirror_entry, list); 762 763 if (tmp->cfg.filter == DPSW_REFLECTION_FILTER_INGRESS_ALL) { 764 NL_SET_ERR_MSG_MOD(extack, 765 "Matchall mirror filter already installed"); 766 return -EBUSY; 767 } 768 } 769 770 mirror_entry = kzalloc(sizeof(*mirror_entry), GFP_KERNEL); 771 if (!mirror_entry) 772 return -ENOMEM; 773 774 mirror_entry->cfg.filter = DPSW_REFLECTION_FILTER_INGRESS_ALL; 775 mirror_entry->cookie = cls->cookie; 776 777 return dpaa2_switch_block_add_mirror(block, mirror_entry, if_id, 778 extack); 779 } 780 781 int dpaa2_switch_cls_matchall_replace(struct dpaa2_switch_filter_block *block, 782 struct tc_cls_matchall_offload *cls) 783 { 784 struct netlink_ext_ack *extack = cls->common.extack; 785 struct flow_action_entry *act; 786 787 if (!flow_offload_has_one_action(&cls->rule->action)) { 788 NL_SET_ERR_MSG(extack, "Only singular actions are supported"); 789 return -EOPNOTSUPP; 790 } 791 792 act = &cls->rule->action.entries[0]; 793 switch (act->id) { 794 case FLOW_ACTION_REDIRECT: 795 case FLOW_ACTION_TRAP: 796 case FLOW_ACTION_DROP: 797 return dpaa2_switch_cls_matchall_replace_acl(block, cls); 798 case FLOW_ACTION_MIRRED: 799 return dpaa2_switch_cls_matchall_replace_mirror(block, cls); 800 default: 801 NL_SET_ERR_MSG_MOD(extack, "Action not supported"); 802 return -EOPNOTSUPP; 803 } 804 } 805 806 int dpaa2_switch_block_offload_mirror(struct dpaa2_switch_filter_block *block, 807 struct ethsw_port_priv *port_priv) 808 { 809 struct ethsw_core *ethsw = port_priv->ethsw_data; 810 struct dpaa2_switch_mirror_entry *tmp; 811 int err; 812 813 list_for_each_entry(tmp, &block->mirror_entries, list) { 814 err = dpsw_if_add_reflection(ethsw->mc_io, 0, 815 ethsw->dpsw_handle, 816 port_priv->idx, &tmp->cfg); 817 if (err) 818 goto unwind_add; 819 } 820 821 return 0; 822 823 unwind_add: 824 list_for_each_entry(tmp, &block->mirror_entries, list) 825 dpsw_if_remove_reflection(ethsw->mc_io, 0, 826 ethsw->dpsw_handle, 827 port_priv->idx, &tmp->cfg); 828 829 return err; 830 } 831 832 int dpaa2_switch_block_unoffload_mirror(struct dpaa2_switch_filter_block *block, 833 struct ethsw_port_priv *port_priv) 834 { 835 struct ethsw_core *ethsw = port_priv->ethsw_data; 836 struct dpaa2_switch_mirror_entry *tmp; 837 int err; 838 839 list_for_each_entry(tmp, &block->mirror_entries, list) { 840 err = dpsw_if_remove_reflection(ethsw->mc_io, 0, 841 ethsw->dpsw_handle, 842 port_priv->idx, &tmp->cfg); 843 if (err) 844 goto unwind_remove; 845 } 846 847 return 0; 848 849 unwind_remove: 850 list_for_each_entry(tmp, &block->mirror_entries, list) 851 dpsw_if_add_reflection(ethsw->mc_io, 0, ethsw->dpsw_handle, 852 port_priv->idx, &tmp->cfg); 853 854 return err; 855 } 856 857 int dpaa2_switch_cls_matchall_destroy(struct dpaa2_switch_filter_block *block, 858 struct tc_cls_matchall_offload *cls) 859 { 860 struct dpaa2_switch_mirror_entry *mirror_entry; 861 struct dpaa2_switch_acl_entry *acl_entry; 862 863 /* If this filter is a an ACL one, remove it */ 864 acl_entry = dpaa2_switch_acl_tbl_find_entry_by_cookie(block, 865 cls->cookie); 866 if (acl_entry) 867 return dpaa2_switch_acl_tbl_remove_entry(block, 868 acl_entry); 869 870 /* If not, then it has to be a mirror */ 871 mirror_entry = dpaa2_switch_mirror_find_entry_by_cookie(block, 872 cls->cookie); 873 if (mirror_entry) 874 return dpaa2_switch_block_remove_mirror(block, 875 mirror_entry); 876 877 return 0; 878 } 879