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