599 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */3 4#include <net/devlink.h>5 6#include "prestera_devlink.h"7#include "prestera_hw.h"8 9/* All driver-specific traps must be documented in10 * Documentation/networking/devlink/prestera.rst11 */12enum {13 DEVLINK_PRESTERA_TRAP_ID_BASE = DEVLINK_TRAP_GENERIC_ID_MAX,14 DEVLINK_PRESTERA_TRAP_ID_ARP_BC,15 DEVLINK_PRESTERA_TRAP_ID_IS_IS,16 DEVLINK_PRESTERA_TRAP_ID_OSPF,17 DEVLINK_PRESTERA_TRAP_ID_IP_BC_MAC,18 DEVLINK_PRESTERA_TRAP_ID_ROUTER_MC,19 DEVLINK_PRESTERA_TRAP_ID_VRRP,20 DEVLINK_PRESTERA_TRAP_ID_DHCP,21 DEVLINK_PRESTERA_TRAP_ID_MAC_TO_ME,22 DEVLINK_PRESTERA_TRAP_ID_IPV4_OPTIONS,23 DEVLINK_PRESTERA_TRAP_ID_IP_DEFAULT_ROUTE,24 DEVLINK_PRESTERA_TRAP_ID_IP_TO_ME,25 DEVLINK_PRESTERA_TRAP_ID_IPV4_ICMP_REDIRECT,26 DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_0,27 DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_1,28 DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_2,29 DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_3,30 DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_4,31 DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_5,32 DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_6,33 DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_7,34 DEVLINK_PRESTERA_TRAP_ID_BGP,35 DEVLINK_PRESTERA_TRAP_ID_SSH,36 DEVLINK_PRESTERA_TRAP_ID_TELNET,37 DEVLINK_PRESTERA_TRAP_ID_ICMP,38 DEVLINK_PRESTERA_TRAP_ID_MET_RED,39 DEVLINK_PRESTERA_TRAP_ID_IP_SIP_IS_ZERO,40 DEVLINK_PRESTERA_TRAP_ID_IP_UC_DIP_DA_MISMATCH,41 DEVLINK_PRESTERA_TRAP_ID_ILLEGAL_IPV4_HDR,42 DEVLINK_PRESTERA_TRAP_ID_ILLEGAL_IP_ADDR,43 DEVLINK_PRESTERA_TRAP_ID_INVALID_SA,44 DEVLINK_PRESTERA_TRAP_ID_LOCAL_PORT,45 DEVLINK_PRESTERA_TRAP_ID_PORT_NO_VLAN,46 DEVLINK_PRESTERA_TRAP_ID_RXDMA_DROP,47};48 49#define DEVLINK_PRESTERA_TRAP_NAME_ARP_BC \50 "arp_bc"51#define DEVLINK_PRESTERA_TRAP_NAME_IS_IS \52 "is_is"53#define DEVLINK_PRESTERA_TRAP_NAME_OSPF \54 "ospf"55#define DEVLINK_PRESTERA_TRAP_NAME_IP_BC_MAC \56 "ip_bc_mac"57#define DEVLINK_PRESTERA_TRAP_NAME_ROUTER_MC \58 "router_mc"59#define DEVLINK_PRESTERA_TRAP_NAME_VRRP \60 "vrrp"61#define DEVLINK_PRESTERA_TRAP_NAME_DHCP \62 "dhcp"63#define DEVLINK_PRESTERA_TRAP_NAME_MAC_TO_ME \64 "mac_to_me"65#define DEVLINK_PRESTERA_TRAP_NAME_IPV4_OPTIONS \66 "ipv4_options"67#define DEVLINK_PRESTERA_TRAP_NAME_IP_DEFAULT_ROUTE \68 "ip_default_route"69#define DEVLINK_PRESTERA_TRAP_NAME_IP_TO_ME \70 "ip_to_me"71#define DEVLINK_PRESTERA_TRAP_NAME_IPV4_ICMP_REDIRECT \72 "ipv4_icmp_redirect"73#define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_0 \74 "acl_code_0"75#define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_1 \76 "acl_code_1"77#define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_2 \78 "acl_code_2"79#define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_3 \80 "acl_code_3"81#define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_4 \82 "acl_code_4"83#define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_5 \84 "acl_code_5"85#define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_6 \86 "acl_code_6"87#define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_7 \88 "acl_code_7"89#define DEVLINK_PRESTERA_TRAP_NAME_BGP \90 "bgp"91#define DEVLINK_PRESTERA_TRAP_NAME_SSH \92 "ssh"93#define DEVLINK_PRESTERA_TRAP_NAME_TELNET \94 "telnet"95#define DEVLINK_PRESTERA_TRAP_NAME_ICMP \96 "icmp"97#define DEVLINK_PRESTERA_TRAP_NAME_RXDMA_DROP \98 "rxdma_drop"99#define DEVLINK_PRESTERA_TRAP_NAME_PORT_NO_VLAN \100 "port_no_vlan"101#define DEVLINK_PRESTERA_TRAP_NAME_LOCAL_PORT \102 "local_port"103#define DEVLINK_PRESTERA_TRAP_NAME_INVALID_SA \104 "invalid_sa"105#define DEVLINK_PRESTERA_TRAP_NAME_ILLEGAL_IP_ADDR \106 "illegal_ip_addr"107#define DEVLINK_PRESTERA_TRAP_NAME_ILLEGAL_IPV4_HDR \108 "illegal_ipv4_hdr"109#define DEVLINK_PRESTERA_TRAP_NAME_IP_UC_DIP_DA_MISMATCH \110 "ip_uc_dip_da_mismatch"111#define DEVLINK_PRESTERA_TRAP_NAME_IP_SIP_IS_ZERO \112 "ip_sip_is_zero"113#define DEVLINK_PRESTERA_TRAP_NAME_MET_RED \114 "met_red"115 116struct prestera_trap {117 struct devlink_trap trap;118 u8 cpu_code;119};120 121struct prestera_trap_item {122 enum devlink_trap_action action;123 void *trap_ctx;124};125 126struct prestera_trap_data {127 struct prestera_switch *sw;128 struct prestera_trap_item *trap_items_arr;129 u32 traps_count;130};131 132#define PRESTERA_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT133 134#define PRESTERA_TRAP_CONTROL(_id, _group_id, _action) \135 DEVLINK_TRAP_GENERIC(CONTROL, _action, _id, \136 DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \137 PRESTERA_TRAP_METADATA)138 139#define PRESTERA_TRAP_DRIVER_CONTROL(_id, _group_id) \140 DEVLINK_TRAP_DRIVER(CONTROL, TRAP, DEVLINK_PRESTERA_TRAP_ID_##_id, \141 DEVLINK_PRESTERA_TRAP_NAME_##_id, \142 DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \143 PRESTERA_TRAP_METADATA)144 145#define PRESTERA_TRAP_EXCEPTION(_id, _group_id) \146 DEVLINK_TRAP_GENERIC(EXCEPTION, TRAP, _id, \147 DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \148 PRESTERA_TRAP_METADATA)149 150#define PRESTERA_TRAP_DRIVER_EXCEPTION(_id, _group_id) \151 DEVLINK_TRAP_DRIVER(EXCEPTION, TRAP, DEVLINK_PRESTERA_TRAP_ID_##_id, \152 DEVLINK_PRESTERA_TRAP_NAME_##_id, \153 DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \154 PRESTERA_TRAP_METADATA)155 156#define PRESTERA_TRAP_DRIVER_DROP(_id, _group_id) \157 DEVLINK_TRAP_DRIVER(DROP, DROP, DEVLINK_PRESTERA_TRAP_ID_##_id, \158 DEVLINK_PRESTERA_TRAP_NAME_##_id, \159 DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \160 PRESTERA_TRAP_METADATA)161 162static const struct devlink_trap_group prestera_trap_groups_arr[] = {163 /* No policer is associated with following groups (policerid == 0)*/164 DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),165 DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS, 0),166 DEVLINK_TRAP_GROUP_GENERIC(L3_EXCEPTIONS, 0),167 DEVLINK_TRAP_GROUP_GENERIC(NEIGH_DISCOVERY, 0),168 DEVLINK_TRAP_GROUP_GENERIC(ACL_TRAP, 0),169 DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS, 0),170 DEVLINK_TRAP_GROUP_GENERIC(ACL_SAMPLE, 0),171 DEVLINK_TRAP_GROUP_GENERIC(OSPF, 0),172 DEVLINK_TRAP_GROUP_GENERIC(STP, 0),173 DEVLINK_TRAP_GROUP_GENERIC(LACP, 0),174 DEVLINK_TRAP_GROUP_GENERIC(LLDP, 0),175 DEVLINK_TRAP_GROUP_GENERIC(VRRP, 0),176 DEVLINK_TRAP_GROUP_GENERIC(DHCP, 0),177 DEVLINK_TRAP_GROUP_GENERIC(BGP, 0),178 DEVLINK_TRAP_GROUP_GENERIC(LOCAL_DELIVERY, 0),179 DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS, 0),180};181 182/* Initialize trap list, as well as associate CPU code with them. */183static struct prestera_trap prestera_trap_items_arr[] = {184 {185 .trap = PRESTERA_TRAP_DRIVER_CONTROL(ARP_BC, NEIGH_DISCOVERY),186 .cpu_code = 5,187 },188 {189 .trap = PRESTERA_TRAP_DRIVER_CONTROL(IS_IS, LOCAL_DELIVERY),190 .cpu_code = 13,191 },192 {193 .trap = PRESTERA_TRAP_DRIVER_CONTROL(OSPF, OSPF),194 .cpu_code = 16,195 },196 {197 .trap = PRESTERA_TRAP_DRIVER_CONTROL(IP_BC_MAC, LOCAL_DELIVERY),198 .cpu_code = 19,199 },200 {201 .trap = PRESTERA_TRAP_CONTROL(STP, STP, TRAP),202 .cpu_code = 26,203 },204 {205 .trap = PRESTERA_TRAP_CONTROL(LACP, LACP, TRAP),206 .cpu_code = 27,207 },208 {209 .trap = PRESTERA_TRAP_CONTROL(LLDP, LLDP, TRAP),210 .cpu_code = 28,211 },212 {213 .trap = PRESTERA_TRAP_DRIVER_CONTROL(ROUTER_MC, LOCAL_DELIVERY),214 .cpu_code = 29,215 },216 {217 .trap = PRESTERA_TRAP_DRIVER_CONTROL(VRRP, VRRP),218 .cpu_code = 30,219 },220 {221 .trap = PRESTERA_TRAP_DRIVER_CONTROL(DHCP, DHCP),222 .cpu_code = 33,223 },224 {225 .trap = PRESTERA_TRAP_EXCEPTION(MTU_ERROR, L3_EXCEPTIONS),226 .cpu_code = 63,227 },228 {229 .trap = PRESTERA_TRAP_DRIVER_CONTROL(MAC_TO_ME, LOCAL_DELIVERY),230 .cpu_code = 65,231 },232 {233 .trap = PRESTERA_TRAP_EXCEPTION(TTL_ERROR, L3_EXCEPTIONS),234 .cpu_code = 133,235 },236 {237 .trap = PRESTERA_TRAP_DRIVER_EXCEPTION(IPV4_OPTIONS,238 L3_EXCEPTIONS),239 .cpu_code = 141,240 },241 {242 .trap = PRESTERA_TRAP_DRIVER_CONTROL(IP_DEFAULT_ROUTE,243 LOCAL_DELIVERY),244 .cpu_code = 160,245 },246 {247 .trap = PRESTERA_TRAP_CONTROL(LOCAL_ROUTE, LOCAL_DELIVERY,248 TRAP),249 .cpu_code = 161,250 },251 {252 .trap = PRESTERA_TRAP_DRIVER_EXCEPTION(IPV4_ICMP_REDIRECT,253 L3_EXCEPTIONS),254 .cpu_code = 180,255 },256 {257 .trap = PRESTERA_TRAP_CONTROL(ARP_RESPONSE, NEIGH_DISCOVERY,258 TRAP),259 .cpu_code = 188,260 },261 {262 .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_0, ACL_TRAP),263 .cpu_code = 192,264 },265 {266 .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_1, ACL_TRAP),267 .cpu_code = 193,268 },269 {270 .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_2, ACL_TRAP),271 .cpu_code = 194,272 },273 {274 .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_3, ACL_TRAP),275 .cpu_code = 195,276 },277 {278 .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_4, ACL_TRAP),279 .cpu_code = 196,280 },281 {282 .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_5, ACL_TRAP),283 .cpu_code = 197,284 },285 {286 .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_6, ACL_TRAP),287 .cpu_code = 198,288 },289 {290 .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_7, ACL_TRAP),291 .cpu_code = 199,292 },293 {294 .trap = PRESTERA_TRAP_DRIVER_CONTROL(BGP, BGP),295 .cpu_code = 206,296 },297 {298 .trap = PRESTERA_TRAP_DRIVER_CONTROL(SSH, LOCAL_DELIVERY),299 .cpu_code = 207,300 },301 {302 .trap = PRESTERA_TRAP_DRIVER_CONTROL(TELNET, LOCAL_DELIVERY),303 .cpu_code = 208,304 },305 {306 .trap = PRESTERA_TRAP_DRIVER_CONTROL(ICMP, LOCAL_DELIVERY),307 .cpu_code = 209,308 },309 {310 .trap = PRESTERA_TRAP_DRIVER_DROP(RXDMA_DROP, BUFFER_DROPS),311 .cpu_code = 37,312 },313 {314 .trap = PRESTERA_TRAP_DRIVER_DROP(PORT_NO_VLAN, L2_DROPS),315 .cpu_code = 39,316 },317 {318 .trap = PRESTERA_TRAP_DRIVER_DROP(LOCAL_PORT, L2_DROPS),319 .cpu_code = 56,320 },321 {322 .trap = PRESTERA_TRAP_DRIVER_DROP(INVALID_SA, L2_DROPS),323 .cpu_code = 60,324 },325 {326 .trap = PRESTERA_TRAP_DRIVER_DROP(ILLEGAL_IP_ADDR, L3_DROPS),327 .cpu_code = 136,328 },329 {330 .trap = PRESTERA_TRAP_DRIVER_DROP(ILLEGAL_IPV4_HDR, L3_DROPS),331 .cpu_code = 137,332 },333 {334 .trap = PRESTERA_TRAP_DRIVER_DROP(IP_UC_DIP_DA_MISMATCH,335 L3_DROPS),336 .cpu_code = 138,337 },338 {339 .trap = PRESTERA_TRAP_DRIVER_DROP(IP_SIP_IS_ZERO, L3_DROPS),340 .cpu_code = 145,341 },342 {343 .trap = PRESTERA_TRAP_DRIVER_DROP(MET_RED, BUFFER_DROPS),344 .cpu_code = 185,345 },346};347 348static int prestera_drop_counter_get(struct devlink *devlink,349 const struct devlink_trap *trap,350 u64 *p_drops);351 352static int prestera_dl_info_get(struct devlink *dl,353 struct devlink_info_req *req,354 struct netlink_ext_ack *extack)355{356 struct prestera_switch *sw = devlink_priv(dl);357 char buf[16];358 359 snprintf(buf, sizeof(buf), "%d.%d.%d",360 sw->dev->fw_rev.maj,361 sw->dev->fw_rev.min,362 sw->dev->fw_rev.sub);363 364 return devlink_info_version_running_put(req,365 DEVLINK_INFO_VERSION_GENERIC_FW,366 buf);367}368 369static int prestera_trap_init(struct devlink *devlink,370 const struct devlink_trap *trap, void *trap_ctx);371 372static int prestera_trap_action_set(struct devlink *devlink,373 const struct devlink_trap *trap,374 enum devlink_trap_action action,375 struct netlink_ext_ack *extack);376 377static const struct devlink_ops prestera_dl_ops = {378 .info_get = prestera_dl_info_get,379 .trap_init = prestera_trap_init,380 .trap_action_set = prestera_trap_action_set,381 .trap_drop_counter_get = prestera_drop_counter_get,382};383 384struct prestera_switch *prestera_devlink_alloc(struct prestera_device *dev)385{386 struct devlink *dl;387 388 dl = devlink_alloc(&prestera_dl_ops, sizeof(struct prestera_switch),389 dev->dev);390 391 return devlink_priv(dl);392}393 394void prestera_devlink_free(struct prestera_switch *sw)395{396 struct devlink *dl = priv_to_devlink(sw);397 398 devlink_free(dl);399}400 401void prestera_devlink_register(struct prestera_switch *sw)402{403 struct devlink *dl = priv_to_devlink(sw);404 405 devlink_register(dl);406}407 408void prestera_devlink_unregister(struct prestera_switch *sw)409{410 struct devlink *dl = priv_to_devlink(sw);411 412 devlink_unregister(dl);413}414 415int prestera_devlink_port_register(struct prestera_port *port)416{417 struct prestera_switch *sw = port->sw;418 struct devlink *dl = priv_to_devlink(sw);419 struct devlink_port_attrs attrs = {};420 int err;421 422 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;423 attrs.phys.port_number = port->fp_id;424 attrs.switch_id.id_len = sizeof(sw->id);425 memcpy(attrs.switch_id.id, &sw->id, attrs.switch_id.id_len);426 427 devlink_port_attrs_set(&port->dl_port, &attrs);428 429 err = devlink_port_register(dl, &port->dl_port, port->fp_id);430 if (err) {431 dev_err(prestera_dev(sw), "devlink_port_register failed: %d\n", err);432 return err;433 }434 435 return 0;436}437 438void prestera_devlink_port_unregister(struct prestera_port *port)439{440 devlink_port_unregister(&port->dl_port);441}442 443int prestera_devlink_traps_register(struct prestera_switch *sw)444{445 const u32 groups_count = ARRAY_SIZE(prestera_trap_groups_arr);446 const u32 traps_count = ARRAY_SIZE(prestera_trap_items_arr);447 struct devlink *devlink = priv_to_devlink(sw);448 struct prestera_trap_data *trap_data;449 struct prestera_trap *prestera_trap;450 int err, i;451 452 trap_data = kzalloc(sizeof(*trap_data), GFP_KERNEL);453 if (!trap_data)454 return -ENOMEM;455 456 trap_data->trap_items_arr = kcalloc(traps_count,457 sizeof(struct prestera_trap_item),458 GFP_KERNEL);459 if (!trap_data->trap_items_arr) {460 err = -ENOMEM;461 goto err_trap_items_alloc;462 }463 464 trap_data->sw = sw;465 trap_data->traps_count = traps_count;466 sw->trap_data = trap_data;467 468 err = devlink_trap_groups_register(devlink, prestera_trap_groups_arr,469 groups_count);470 if (err)471 goto err_groups_register;472 473 for (i = 0; i < traps_count; i++) {474 prestera_trap = &prestera_trap_items_arr[i];475 err = devlink_traps_register(devlink, &prestera_trap->trap, 1,476 sw);477 if (err)478 goto err_trap_register;479 }480 481 return 0;482 483err_trap_register:484 for (i--; i >= 0; i--) {485 prestera_trap = &prestera_trap_items_arr[i];486 devlink_traps_unregister(devlink, &prestera_trap->trap, 1);487 }488 devlink_trap_groups_unregister(devlink, prestera_trap_groups_arr,489 groups_count);490err_groups_register:491 kfree(trap_data->trap_items_arr);492err_trap_items_alloc:493 kfree(trap_data);494 return err;495}496 497static struct prestera_trap_item *498prestera_get_trap_item_by_cpu_code(struct prestera_switch *sw, u8 cpu_code)499{500 struct prestera_trap_data *trap_data = sw->trap_data;501 struct prestera_trap *prestera_trap;502 int i;503 504 for (i = 0; i < trap_data->traps_count; i++) {505 prestera_trap = &prestera_trap_items_arr[i];506 if (cpu_code == prestera_trap->cpu_code)507 return &trap_data->trap_items_arr[i];508 }509 510 return NULL;511}512 513void prestera_devlink_trap_report(struct prestera_port *port,514 struct sk_buff *skb, u8 cpu_code)515{516 struct prestera_trap_item *trap_item;517 struct devlink *devlink;518 519 devlink = port->dl_port.devlink;520 521 trap_item = prestera_get_trap_item_by_cpu_code(port->sw, cpu_code);522 if (unlikely(!trap_item))523 return;524 525 devlink_trap_report(devlink, skb, trap_item->trap_ctx,526 &port->dl_port, NULL);527}528 529static struct prestera_trap_item *530prestera_devlink_trap_item_lookup(struct prestera_switch *sw, u16 trap_id)531{532 struct prestera_trap_data *trap_data = sw->trap_data;533 int i;534 535 for (i = 0; i < ARRAY_SIZE(prestera_trap_items_arr); i++) {536 if (prestera_trap_items_arr[i].trap.id == trap_id)537 return &trap_data->trap_items_arr[i];538 }539 540 return NULL;541}542 543static int prestera_trap_init(struct devlink *devlink,544 const struct devlink_trap *trap, void *trap_ctx)545{546 struct prestera_switch *sw = devlink_priv(devlink);547 struct prestera_trap_item *trap_item;548 549 trap_item = prestera_devlink_trap_item_lookup(sw, trap->id);550 if (WARN_ON(!trap_item))551 return -EINVAL;552 553 trap_item->trap_ctx = trap_ctx;554 trap_item->action = trap->init_action;555 556 return 0;557}558 559static int prestera_trap_action_set(struct devlink *devlink,560 const struct devlink_trap *trap,561 enum devlink_trap_action action,562 struct netlink_ext_ack *extack)563{564 /* Currently, driver does not support trap action altering */565 return -EOPNOTSUPP;566}567 568static int prestera_drop_counter_get(struct devlink *devlink,569 const struct devlink_trap *trap,570 u64 *p_drops)571{572 struct prestera_switch *sw = devlink_priv(devlink);573 enum prestera_hw_cpu_code_cnt_t cpu_code_type =574 PRESTERA_HW_CPU_CODE_CNT_TYPE_DROP;575 struct prestera_trap *prestera_trap =576 container_of(trap, struct prestera_trap, trap);577 578 return prestera_hw_cpu_code_counters_get(sw, prestera_trap->cpu_code,579 cpu_code_type, p_drops);580}581 582void prestera_devlink_traps_unregister(struct prestera_switch *sw)583{584 struct prestera_trap_data *trap_data = sw->trap_data;585 struct devlink *dl = priv_to_devlink(sw);586 const struct devlink_trap *trap;587 int i;588 589 for (i = 0; i < ARRAY_SIZE(prestera_trap_items_arr); ++i) {590 trap = &prestera_trap_items_arr[i].trap;591 devlink_traps_unregister(dl, trap, 1);592 }593 594 devlink_trap_groups_unregister(dl, prestera_trap_groups_arr,595 ARRAY_SIZE(prestera_trap_groups_arr));596 kfree(trap_data->trap_items_arr);597 kfree(trap_data);598}599