| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598 |
- // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
- /* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */
- #include <net/devlink.h>
- #include "prestera_devlink.h"
- #include "prestera_hw.h"
- /* All driver-specific traps must be documented in
- * Documentation/networking/devlink/prestera.rst
- */
- enum {
- DEVLINK_PRESTERA_TRAP_ID_BASE = DEVLINK_TRAP_GENERIC_ID_MAX,
- DEVLINK_PRESTERA_TRAP_ID_ARP_BC,
- DEVLINK_PRESTERA_TRAP_ID_IS_IS,
- DEVLINK_PRESTERA_TRAP_ID_OSPF,
- DEVLINK_PRESTERA_TRAP_ID_IP_BC_MAC,
- DEVLINK_PRESTERA_TRAP_ID_ROUTER_MC,
- DEVLINK_PRESTERA_TRAP_ID_VRRP,
- DEVLINK_PRESTERA_TRAP_ID_DHCP,
- DEVLINK_PRESTERA_TRAP_ID_MAC_TO_ME,
- DEVLINK_PRESTERA_TRAP_ID_IPV4_OPTIONS,
- DEVLINK_PRESTERA_TRAP_ID_IP_DEFAULT_ROUTE,
- DEVLINK_PRESTERA_TRAP_ID_IP_TO_ME,
- DEVLINK_PRESTERA_TRAP_ID_IPV4_ICMP_REDIRECT,
- DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_0,
- DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_1,
- DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_2,
- DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_3,
- DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_4,
- DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_5,
- DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_6,
- DEVLINK_PRESTERA_TRAP_ID_ACL_CODE_7,
- DEVLINK_PRESTERA_TRAP_ID_BGP,
- DEVLINK_PRESTERA_TRAP_ID_SSH,
- DEVLINK_PRESTERA_TRAP_ID_TELNET,
- DEVLINK_PRESTERA_TRAP_ID_ICMP,
- DEVLINK_PRESTERA_TRAP_ID_MET_RED,
- DEVLINK_PRESTERA_TRAP_ID_IP_SIP_IS_ZERO,
- DEVLINK_PRESTERA_TRAP_ID_IP_UC_DIP_DA_MISMATCH,
- DEVLINK_PRESTERA_TRAP_ID_ILLEGAL_IPV4_HDR,
- DEVLINK_PRESTERA_TRAP_ID_ILLEGAL_IP_ADDR,
- DEVLINK_PRESTERA_TRAP_ID_INVALID_SA,
- DEVLINK_PRESTERA_TRAP_ID_LOCAL_PORT,
- DEVLINK_PRESTERA_TRAP_ID_PORT_NO_VLAN,
- DEVLINK_PRESTERA_TRAP_ID_RXDMA_DROP,
- };
- #define DEVLINK_PRESTERA_TRAP_NAME_ARP_BC \
- "arp_bc"
- #define DEVLINK_PRESTERA_TRAP_NAME_IS_IS \
- "is_is"
- #define DEVLINK_PRESTERA_TRAP_NAME_OSPF \
- "ospf"
- #define DEVLINK_PRESTERA_TRAP_NAME_IP_BC_MAC \
- "ip_bc_mac"
- #define DEVLINK_PRESTERA_TRAP_NAME_ROUTER_MC \
- "router_mc"
- #define DEVLINK_PRESTERA_TRAP_NAME_VRRP \
- "vrrp"
- #define DEVLINK_PRESTERA_TRAP_NAME_DHCP \
- "dhcp"
- #define DEVLINK_PRESTERA_TRAP_NAME_MAC_TO_ME \
- "mac_to_me"
- #define DEVLINK_PRESTERA_TRAP_NAME_IPV4_OPTIONS \
- "ipv4_options"
- #define DEVLINK_PRESTERA_TRAP_NAME_IP_DEFAULT_ROUTE \
- "ip_default_route"
- #define DEVLINK_PRESTERA_TRAP_NAME_IP_TO_ME \
- "ip_to_me"
- #define DEVLINK_PRESTERA_TRAP_NAME_IPV4_ICMP_REDIRECT \
- "ipv4_icmp_redirect"
- #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_0 \
- "acl_code_0"
- #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_1 \
- "acl_code_1"
- #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_2 \
- "acl_code_2"
- #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_3 \
- "acl_code_3"
- #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_4 \
- "acl_code_4"
- #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_5 \
- "acl_code_5"
- #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_6 \
- "acl_code_6"
- #define DEVLINK_PRESTERA_TRAP_NAME_ACL_CODE_7 \
- "acl_code_7"
- #define DEVLINK_PRESTERA_TRAP_NAME_BGP \
- "bgp"
- #define DEVLINK_PRESTERA_TRAP_NAME_SSH \
- "ssh"
- #define DEVLINK_PRESTERA_TRAP_NAME_TELNET \
- "telnet"
- #define DEVLINK_PRESTERA_TRAP_NAME_ICMP \
- "icmp"
- #define DEVLINK_PRESTERA_TRAP_NAME_RXDMA_DROP \
- "rxdma_drop"
- #define DEVLINK_PRESTERA_TRAP_NAME_PORT_NO_VLAN \
- "port_no_vlan"
- #define DEVLINK_PRESTERA_TRAP_NAME_LOCAL_PORT \
- "local_port"
- #define DEVLINK_PRESTERA_TRAP_NAME_INVALID_SA \
- "invalid_sa"
- #define DEVLINK_PRESTERA_TRAP_NAME_ILLEGAL_IP_ADDR \
- "illegal_ip_addr"
- #define DEVLINK_PRESTERA_TRAP_NAME_ILLEGAL_IPV4_HDR \
- "illegal_ipv4_hdr"
- #define DEVLINK_PRESTERA_TRAP_NAME_IP_UC_DIP_DA_MISMATCH \
- "ip_uc_dip_da_mismatch"
- #define DEVLINK_PRESTERA_TRAP_NAME_IP_SIP_IS_ZERO \
- "ip_sip_is_zero"
- #define DEVLINK_PRESTERA_TRAP_NAME_MET_RED \
- "met_red"
- struct prestera_trap {
- struct devlink_trap trap;
- u8 cpu_code;
- };
- struct prestera_trap_item {
- enum devlink_trap_action action;
- void *trap_ctx;
- };
- struct prestera_trap_data {
- struct prestera_switch *sw;
- struct prestera_trap_item *trap_items_arr;
- u32 traps_count;
- };
- #define PRESTERA_TRAP_METADATA DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT
- #define PRESTERA_TRAP_CONTROL(_id, _group_id, _action) \
- DEVLINK_TRAP_GENERIC(CONTROL, _action, _id, \
- DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
- PRESTERA_TRAP_METADATA)
- #define PRESTERA_TRAP_DRIVER_CONTROL(_id, _group_id) \
- DEVLINK_TRAP_DRIVER(CONTROL, TRAP, DEVLINK_PRESTERA_TRAP_ID_##_id, \
- DEVLINK_PRESTERA_TRAP_NAME_##_id, \
- DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
- PRESTERA_TRAP_METADATA)
- #define PRESTERA_TRAP_EXCEPTION(_id, _group_id) \
- DEVLINK_TRAP_GENERIC(EXCEPTION, TRAP, _id, \
- DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
- PRESTERA_TRAP_METADATA)
- #define PRESTERA_TRAP_DRIVER_EXCEPTION(_id, _group_id) \
- DEVLINK_TRAP_DRIVER(EXCEPTION, TRAP, DEVLINK_PRESTERA_TRAP_ID_##_id, \
- DEVLINK_PRESTERA_TRAP_NAME_##_id, \
- DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
- PRESTERA_TRAP_METADATA)
- #define PRESTERA_TRAP_DRIVER_DROP(_id, _group_id) \
- DEVLINK_TRAP_DRIVER(DROP, DROP, DEVLINK_PRESTERA_TRAP_ID_##_id, \
- DEVLINK_PRESTERA_TRAP_NAME_##_id, \
- DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
- PRESTERA_TRAP_METADATA)
- static const struct devlink_trap_group prestera_trap_groups_arr[] = {
- /* No policer is associated with following groups (policerid == 0)*/
- DEVLINK_TRAP_GROUP_GENERIC(L2_DROPS, 0),
- DEVLINK_TRAP_GROUP_GENERIC(L3_DROPS, 0),
- DEVLINK_TRAP_GROUP_GENERIC(L3_EXCEPTIONS, 0),
- DEVLINK_TRAP_GROUP_GENERIC(NEIGH_DISCOVERY, 0),
- DEVLINK_TRAP_GROUP_GENERIC(ACL_TRAP, 0),
- DEVLINK_TRAP_GROUP_GENERIC(ACL_DROPS, 0),
- DEVLINK_TRAP_GROUP_GENERIC(ACL_SAMPLE, 0),
- DEVLINK_TRAP_GROUP_GENERIC(OSPF, 0),
- DEVLINK_TRAP_GROUP_GENERIC(STP, 0),
- DEVLINK_TRAP_GROUP_GENERIC(LACP, 0),
- DEVLINK_TRAP_GROUP_GENERIC(LLDP, 0),
- DEVLINK_TRAP_GROUP_GENERIC(VRRP, 0),
- DEVLINK_TRAP_GROUP_GENERIC(DHCP, 0),
- DEVLINK_TRAP_GROUP_GENERIC(BGP, 0),
- DEVLINK_TRAP_GROUP_GENERIC(LOCAL_DELIVERY, 0),
- DEVLINK_TRAP_GROUP_GENERIC(BUFFER_DROPS, 0),
- };
- /* Initialize trap list, as well as associate CPU code with them. */
- static struct prestera_trap prestera_trap_items_arr[] = {
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(ARP_BC, NEIGH_DISCOVERY),
- .cpu_code = 5,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(IS_IS, LOCAL_DELIVERY),
- .cpu_code = 13,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(OSPF, OSPF),
- .cpu_code = 16,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(IP_BC_MAC, LOCAL_DELIVERY),
- .cpu_code = 19,
- },
- {
- .trap = PRESTERA_TRAP_CONTROL(STP, STP, TRAP),
- .cpu_code = 26,
- },
- {
- .trap = PRESTERA_TRAP_CONTROL(LACP, LACP, TRAP),
- .cpu_code = 27,
- },
- {
- .trap = PRESTERA_TRAP_CONTROL(LLDP, LLDP, TRAP),
- .cpu_code = 28,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(ROUTER_MC, LOCAL_DELIVERY),
- .cpu_code = 29,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(VRRP, VRRP),
- .cpu_code = 30,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(DHCP, DHCP),
- .cpu_code = 33,
- },
- {
- .trap = PRESTERA_TRAP_EXCEPTION(MTU_ERROR, L3_EXCEPTIONS),
- .cpu_code = 63,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(MAC_TO_ME, LOCAL_DELIVERY),
- .cpu_code = 65,
- },
- {
- .trap = PRESTERA_TRAP_EXCEPTION(TTL_ERROR, L3_EXCEPTIONS),
- .cpu_code = 133,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_EXCEPTION(IPV4_OPTIONS,
- L3_EXCEPTIONS),
- .cpu_code = 141,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(IP_DEFAULT_ROUTE,
- LOCAL_DELIVERY),
- .cpu_code = 160,
- },
- {
- .trap = PRESTERA_TRAP_CONTROL(LOCAL_ROUTE, LOCAL_DELIVERY,
- TRAP),
- .cpu_code = 161,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_EXCEPTION(IPV4_ICMP_REDIRECT,
- L3_EXCEPTIONS),
- .cpu_code = 180,
- },
- {
- .trap = PRESTERA_TRAP_CONTROL(ARP_RESPONSE, NEIGH_DISCOVERY,
- TRAP),
- .cpu_code = 188,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_0, ACL_TRAP),
- .cpu_code = 192,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_1, ACL_TRAP),
- .cpu_code = 193,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_2, ACL_TRAP),
- .cpu_code = 194,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_3, ACL_TRAP),
- .cpu_code = 195,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_4, ACL_TRAP),
- .cpu_code = 196,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_5, ACL_TRAP),
- .cpu_code = 197,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_6, ACL_TRAP),
- .cpu_code = 198,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(ACL_CODE_7, ACL_TRAP),
- .cpu_code = 199,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(BGP, BGP),
- .cpu_code = 206,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(SSH, LOCAL_DELIVERY),
- .cpu_code = 207,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(TELNET, LOCAL_DELIVERY),
- .cpu_code = 208,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_CONTROL(ICMP, LOCAL_DELIVERY),
- .cpu_code = 209,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_DROP(RXDMA_DROP, BUFFER_DROPS),
- .cpu_code = 37,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_DROP(PORT_NO_VLAN, L2_DROPS),
- .cpu_code = 39,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_DROP(LOCAL_PORT, L2_DROPS),
- .cpu_code = 56,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_DROP(INVALID_SA, L2_DROPS),
- .cpu_code = 60,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_DROP(ILLEGAL_IP_ADDR, L3_DROPS),
- .cpu_code = 136,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_DROP(ILLEGAL_IPV4_HDR, L3_DROPS),
- .cpu_code = 137,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_DROP(IP_UC_DIP_DA_MISMATCH,
- L3_DROPS),
- .cpu_code = 138,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_DROP(IP_SIP_IS_ZERO, L3_DROPS),
- .cpu_code = 145,
- },
- {
- .trap = PRESTERA_TRAP_DRIVER_DROP(MET_RED, BUFFER_DROPS),
- .cpu_code = 185,
- },
- };
- static int prestera_drop_counter_get(struct devlink *devlink,
- const struct devlink_trap *trap,
- u64 *p_drops);
- static int prestera_dl_info_get(struct devlink *dl,
- struct devlink_info_req *req,
- struct netlink_ext_ack *extack)
- {
- struct prestera_switch *sw = devlink_priv(dl);
- char buf[16];
- snprintf(buf, sizeof(buf), "%d.%d.%d",
- sw->dev->fw_rev.maj,
- sw->dev->fw_rev.min,
- sw->dev->fw_rev.sub);
- return devlink_info_version_running_put(req,
- DEVLINK_INFO_VERSION_GENERIC_FW,
- buf);
- }
- static int prestera_trap_init(struct devlink *devlink,
- const struct devlink_trap *trap, void *trap_ctx);
- static int prestera_trap_action_set(struct devlink *devlink,
- const struct devlink_trap *trap,
- enum devlink_trap_action action,
- struct netlink_ext_ack *extack);
- static const struct devlink_ops prestera_dl_ops = {
- .info_get = prestera_dl_info_get,
- .trap_init = prestera_trap_init,
- .trap_action_set = prestera_trap_action_set,
- .trap_drop_counter_get = prestera_drop_counter_get,
- };
- struct prestera_switch *prestera_devlink_alloc(struct prestera_device *dev)
- {
- struct devlink *dl;
- dl = devlink_alloc(&prestera_dl_ops, sizeof(struct prestera_switch),
- dev->dev);
- return devlink_priv(dl);
- }
- void prestera_devlink_free(struct prestera_switch *sw)
- {
- struct devlink *dl = priv_to_devlink(sw);
- devlink_free(dl);
- }
- void prestera_devlink_register(struct prestera_switch *sw)
- {
- struct devlink *dl = priv_to_devlink(sw);
- devlink_register(dl);
- }
- void prestera_devlink_unregister(struct prestera_switch *sw)
- {
- struct devlink *dl = priv_to_devlink(sw);
- devlink_unregister(dl);
- }
- int prestera_devlink_port_register(struct prestera_port *port)
- {
- struct prestera_switch *sw = port->sw;
- struct devlink *dl = priv_to_devlink(sw);
- struct devlink_port_attrs attrs = {};
- int err;
- attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
- attrs.phys.port_number = port->fp_id;
- attrs.switch_id.id_len = sizeof(sw->id);
- memcpy(attrs.switch_id.id, &sw->id, attrs.switch_id.id_len);
- devlink_port_attrs_set(&port->dl_port, &attrs);
- err = devlink_port_register(dl, &port->dl_port, port->fp_id);
- if (err) {
- dev_err(prestera_dev(sw), "devlink_port_register failed: %d\n", err);
- return err;
- }
- return 0;
- }
- void prestera_devlink_port_unregister(struct prestera_port *port)
- {
- devlink_port_unregister(&port->dl_port);
- }
- int prestera_devlink_traps_register(struct prestera_switch *sw)
- {
- const u32 groups_count = ARRAY_SIZE(prestera_trap_groups_arr);
- const u32 traps_count = ARRAY_SIZE(prestera_trap_items_arr);
- struct devlink *devlink = priv_to_devlink(sw);
- struct prestera_trap_data *trap_data;
- struct prestera_trap *prestera_trap;
- int err, i;
- trap_data = kzalloc(sizeof(*trap_data), GFP_KERNEL);
- if (!trap_data)
- return -ENOMEM;
- trap_data->trap_items_arr = kcalloc(traps_count,
- sizeof(struct prestera_trap_item),
- GFP_KERNEL);
- if (!trap_data->trap_items_arr) {
- err = -ENOMEM;
- goto err_trap_items_alloc;
- }
- trap_data->sw = sw;
- trap_data->traps_count = traps_count;
- sw->trap_data = trap_data;
- err = devlink_trap_groups_register(devlink, prestera_trap_groups_arr,
- groups_count);
- if (err)
- goto err_groups_register;
- for (i = 0; i < traps_count; i++) {
- prestera_trap = &prestera_trap_items_arr[i];
- err = devlink_traps_register(devlink, &prestera_trap->trap, 1,
- sw);
- if (err)
- goto err_trap_register;
- }
- return 0;
- err_trap_register:
- for (i--; i >= 0; i--) {
- prestera_trap = &prestera_trap_items_arr[i];
- devlink_traps_unregister(devlink, &prestera_trap->trap, 1);
- }
- devlink_trap_groups_unregister(devlink, prestera_trap_groups_arr,
- groups_count);
- err_groups_register:
- kfree(trap_data->trap_items_arr);
- err_trap_items_alloc:
- kfree(trap_data);
- return err;
- }
- static struct prestera_trap_item *
- prestera_get_trap_item_by_cpu_code(struct prestera_switch *sw, u8 cpu_code)
- {
- struct prestera_trap_data *trap_data = sw->trap_data;
- struct prestera_trap *prestera_trap;
- int i;
- for (i = 0; i < trap_data->traps_count; i++) {
- prestera_trap = &prestera_trap_items_arr[i];
- if (cpu_code == prestera_trap->cpu_code)
- return &trap_data->trap_items_arr[i];
- }
- return NULL;
- }
- void prestera_devlink_trap_report(struct prestera_port *port,
- struct sk_buff *skb, u8 cpu_code)
- {
- struct prestera_trap_item *trap_item;
- struct devlink *devlink;
- devlink = port->dl_port.devlink;
- trap_item = prestera_get_trap_item_by_cpu_code(port->sw, cpu_code);
- if (unlikely(!trap_item))
- return;
- devlink_trap_report(devlink, skb, trap_item->trap_ctx,
- &port->dl_port, NULL);
- }
- static struct prestera_trap_item *
- prestera_devlink_trap_item_lookup(struct prestera_switch *sw, u16 trap_id)
- {
- struct prestera_trap_data *trap_data = sw->trap_data;
- int i;
- for (i = 0; i < ARRAY_SIZE(prestera_trap_items_arr); i++) {
- if (prestera_trap_items_arr[i].trap.id == trap_id)
- return &trap_data->trap_items_arr[i];
- }
- return NULL;
- }
- static int prestera_trap_init(struct devlink *devlink,
- const struct devlink_trap *trap, void *trap_ctx)
- {
- struct prestera_switch *sw = devlink_priv(devlink);
- struct prestera_trap_item *trap_item;
- trap_item = prestera_devlink_trap_item_lookup(sw, trap->id);
- if (WARN_ON(!trap_item))
- return -EINVAL;
- trap_item->trap_ctx = trap_ctx;
- trap_item->action = trap->init_action;
- return 0;
- }
- static int prestera_trap_action_set(struct devlink *devlink,
- const struct devlink_trap *trap,
- enum devlink_trap_action action,
- struct netlink_ext_ack *extack)
- {
- /* Currently, driver does not support trap action altering */
- return -EOPNOTSUPP;
- }
- static int prestera_drop_counter_get(struct devlink *devlink,
- const struct devlink_trap *trap,
- u64 *p_drops)
- {
- struct prestera_switch *sw = devlink_priv(devlink);
- enum prestera_hw_cpu_code_cnt_t cpu_code_type =
- PRESTERA_HW_CPU_CODE_CNT_TYPE_DROP;
- struct prestera_trap *prestera_trap =
- container_of(trap, struct prestera_trap, trap);
- return prestera_hw_cpu_code_counters_get(sw, prestera_trap->cpu_code,
- cpu_code_type, p_drops);
- }
- void prestera_devlink_traps_unregister(struct prestera_switch *sw)
- {
- struct prestera_trap_data *trap_data = sw->trap_data;
- struct devlink *dl = priv_to_devlink(sw);
- const struct devlink_trap *trap;
- int i;
- for (i = 0; i < ARRAY_SIZE(prestera_trap_items_arr); ++i) {
- trap = &prestera_trap_items_arr[i].trap;
- devlink_traps_unregister(dl, trap, 1);
- }
- devlink_trap_groups_unregister(dl, prestera_trap_groups_arr,
- ARRAY_SIZE(prestera_trap_groups_arr));
- kfree(trap_data->trap_items_arr);
- kfree(trap_data);
- }
|