Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'mlxsw-trap-groups-and-policers'

Jiri Pirko says:

====================
mlxsw: traps, trap groups and policers

Nogah says:

For a packet to be sent from the HW to the cpu, it needs to be trapped.
For a trap to be activate it should be assigned to a trap group.
Those trap groups can have policers, to limit the packet rate (the max
number of packets that can be sent to the cpu in a time slot, the rest
will be discarded) or the data rate (the same, but the count is not by the
number of packets but by their total length in bytes).

This patchset rearrange the trap setting API, re-write the traps and the
trap groups list in spectrum and assign them policers.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+625 -408
+79 -37
drivers/net/ethernet/mellanox/mlxsw/core.c
··· 572 572 dev_kfree_skb(skb); 573 573 } 574 574 575 - static const struct mlxsw_rx_listener mlxsw_emad_rx_listener = { 576 - .func = mlxsw_emad_rx_listener_func, 577 - .local_port = MLXSW_PORT_DONT_CARE, 578 - .trap_id = MLXSW_TRAP_ID_ETHEMAD, 579 - }; 580 - 581 - static int mlxsw_emad_traps_set(struct mlxsw_core *mlxsw_core) 582 - { 583 - char htgt_pl[MLXSW_REG_HTGT_LEN]; 584 - char hpkt_pl[MLXSW_REG_HPKT_LEN]; 585 - int err; 586 - 587 - mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_EMAD); 588 - err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl); 589 - if (err) 590 - return err; 591 - 592 - mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU, 593 - MLXSW_TRAP_ID_ETHEMAD); 594 - return mlxsw_reg_write(mlxsw_core, MLXSW_REG(hpkt), hpkt_pl); 595 - } 575 + static const struct mlxsw_listener mlxsw_emad_rx_listener = 576 + MLXSW_RXL(mlxsw_emad_rx_listener_func, ETHEMAD, TRAP_TO_CPU, false, 577 + EMAD, DISCARD); 596 578 597 579 static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core) 598 580 { ··· 595 613 INIT_LIST_HEAD(&mlxsw_core->emad.trans_list); 596 614 spin_lock_init(&mlxsw_core->emad.trans_list_lock); 597 615 598 - err = mlxsw_core_rx_listener_register(mlxsw_core, 599 - &mlxsw_emad_rx_listener, 600 - mlxsw_core); 616 + err = mlxsw_core_trap_register(mlxsw_core, &mlxsw_emad_rx_listener, 617 + mlxsw_core); 601 618 if (err) 602 619 return err; 603 620 604 - err = mlxsw_emad_traps_set(mlxsw_core); 621 + err = mlxsw_core->driver->basic_trap_groups_set(mlxsw_core); 605 622 if (err) 606 623 goto err_emad_trap_set; 607 - 608 624 mlxsw_core->emad.use_emad = true; 609 625 610 626 return 0; 611 627 612 628 err_emad_trap_set: 613 - mlxsw_core_rx_listener_unregister(mlxsw_core, 614 - &mlxsw_emad_rx_listener, 615 - mlxsw_core); 629 + mlxsw_core_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener, 630 + mlxsw_core); 616 631 return err; 617 632 } 618 633 619 634 static void mlxsw_emad_fini(struct mlxsw_core *mlxsw_core) 620 635 { 621 - char hpkt_pl[MLXSW_REG_HPKT_LEN]; 622 636 623 637 if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX)) 624 638 return; 625 639 626 640 mlxsw_core->emad.use_emad = false; 627 - mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_DISCARD, 628 - MLXSW_TRAP_ID_ETHEMAD); 629 - mlxsw_reg_write(mlxsw_core, MLXSW_REG(hpkt), hpkt_pl); 630 - 631 - mlxsw_core_rx_listener_unregister(mlxsw_core, 632 - &mlxsw_emad_rx_listener, 633 - mlxsw_core); 641 + mlxsw_core_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener, 642 + mlxsw_core); 634 643 } 635 644 636 645 static struct sk_buff *mlxsw_emad_alloc(const struct mlxsw_core *mlxsw_core, ··· 1364 1391 kfree(el_item); 1365 1392 } 1366 1393 EXPORT_SYMBOL(mlxsw_core_event_listener_unregister); 1394 + 1395 + static int mlxsw_core_listener_register(struct mlxsw_core *mlxsw_core, 1396 + const struct mlxsw_listener *listener, 1397 + void *priv) 1398 + { 1399 + if (listener->is_event) 1400 + return mlxsw_core_event_listener_register(mlxsw_core, 1401 + &listener->u.event_listener, 1402 + priv); 1403 + else 1404 + return mlxsw_core_rx_listener_register(mlxsw_core, 1405 + &listener->u.rx_listener, 1406 + priv); 1407 + } 1408 + 1409 + static void mlxsw_core_listener_unregister(struct mlxsw_core *mlxsw_core, 1410 + const struct mlxsw_listener *listener, 1411 + void *priv) 1412 + { 1413 + if (listener->is_event) 1414 + mlxsw_core_event_listener_unregister(mlxsw_core, 1415 + &listener->u.event_listener, 1416 + priv); 1417 + else 1418 + mlxsw_core_rx_listener_unregister(mlxsw_core, 1419 + &listener->u.rx_listener, 1420 + priv); 1421 + } 1422 + 1423 + int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core, 1424 + const struct mlxsw_listener *listener, void *priv) 1425 + { 1426 + char hpkt_pl[MLXSW_REG_HPKT_LEN]; 1427 + int err; 1428 + 1429 + err = mlxsw_core_listener_register(mlxsw_core, listener, priv); 1430 + if (err) 1431 + return err; 1432 + 1433 + mlxsw_reg_hpkt_pack(hpkt_pl, listener->action, listener->trap_id, 1434 + listener->trap_group, listener->is_ctrl); 1435 + err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(hpkt), hpkt_pl); 1436 + if (err) 1437 + goto err_trap_set; 1438 + 1439 + return 0; 1440 + 1441 + err_trap_set: 1442 + mlxsw_core_listener_unregister(mlxsw_core, listener, priv); 1443 + return err; 1444 + } 1445 + EXPORT_SYMBOL(mlxsw_core_trap_register); 1446 + 1447 + void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core, 1448 + const struct mlxsw_listener *listener, 1449 + void *priv) 1450 + { 1451 + char hpkt_pl[MLXSW_REG_HPKT_LEN]; 1452 + 1453 + if (!listener->is_event) { 1454 + mlxsw_reg_hpkt_pack(hpkt_pl, listener->unreg_action, 1455 + listener->trap_id, listener->trap_group, 1456 + listener->is_ctrl); 1457 + mlxsw_reg_write(mlxsw_core, MLXSW_REG(hpkt), hpkt_pl); 1458 + } 1459 + 1460 + mlxsw_core_listener_unregister(mlxsw_core, listener, priv); 1461 + } 1462 + EXPORT_SYMBOL(mlxsw_core_trap_unregister); 1367 1463 1368 1464 static u64 mlxsw_core_tid_get(struct mlxsw_core *mlxsw_core) 1369 1465 {
+52
drivers/net/ethernet/mellanox/mlxsw/core.h
··· 90 90 enum mlxsw_event_trap_id trap_id; 91 91 }; 92 92 93 + struct mlxsw_listener { 94 + u16 trap_id; 95 + union { 96 + struct mlxsw_rx_listener rx_listener; 97 + struct mlxsw_event_listener event_listener; 98 + } u; 99 + enum mlxsw_reg_hpkt_action action; 100 + enum mlxsw_reg_hpkt_action unreg_action; 101 + u8 trap_group; 102 + bool is_ctrl; /* should go via control buffer or not */ 103 + bool is_event; 104 + }; 105 + 106 + #define MLXSW_RXL(_func, _trap_id, _action, _is_ctrl, _trap_group, \ 107 + _unreg_action) \ 108 + { \ 109 + .trap_id = MLXSW_TRAP_ID_##_trap_id, \ 110 + .u.rx_listener = \ 111 + { \ 112 + .func = _func, \ 113 + .local_port = MLXSW_PORT_DONT_CARE, \ 114 + .trap_id = MLXSW_TRAP_ID_##_trap_id, \ 115 + }, \ 116 + .action = MLXSW_REG_HPKT_ACTION_##_action, \ 117 + .unreg_action = MLXSW_REG_HPKT_ACTION_##_unreg_action, \ 118 + .trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group, \ 119 + .is_ctrl = _is_ctrl, \ 120 + .is_event = false, \ 121 + } 122 + 123 + #define MLXSW_EVENTL(_func, _trap_id, _trap_group) \ 124 + { \ 125 + .trap_id = MLXSW_TRAP_ID_##_trap_id, \ 126 + .u.event_listener = \ 127 + { \ 128 + .func = _func, \ 129 + .trap_id = MLXSW_TRAP_ID_##_trap_id, \ 130 + }, \ 131 + .action = MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU, \ 132 + .trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group, \ 133 + .is_ctrl = false, \ 134 + .is_event = true, \ 135 + } 136 + 93 137 int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core, 94 138 const struct mlxsw_rx_listener *rxl, 95 139 void *priv); ··· 147 103 void mlxsw_core_event_listener_unregister(struct mlxsw_core *mlxsw_core, 148 104 const struct mlxsw_event_listener *el, 149 105 void *priv); 106 + 107 + int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core, 108 + const struct mlxsw_listener *listener, 109 + void *priv); 110 + void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core, 111 + const struct mlxsw_listener *listener, 112 + void *priv); 150 113 151 114 typedef void mlxsw_reg_trans_cb_t(struct mlxsw_core *mlxsw_core, char *payload, 152 115 size_t payload_len, unsigned long cb_priv); ··· 265 214 int (*init)(struct mlxsw_core *mlxsw_core, 266 215 const struct mlxsw_bus_info *mlxsw_bus_info); 267 216 void (*fini)(struct mlxsw_core *mlxsw_core); 217 + int (*basic_trap_groups_set)(struct mlxsw_core *mlxsw_core); 268 218 int (*port_type_set)(struct mlxsw_core *mlxsw_core, u8 local_port, 269 219 enum devlink_port_type new_type); 270 220 int (*port_split)(struct mlxsw_core *mlxsw_core, u8 local_port,
+189 -42
drivers/net/ethernet/mellanox/mlxsw/reg.h
··· 1757 1757 } 1758 1758 } 1759 1759 1760 + /* QPCR - QoS Policer Configuration Register 1761 + * ----------------------------------------- 1762 + * The QPCR register is used to create policers - that limit 1763 + * the rate of bytes or packets via some trap group. 1764 + */ 1765 + #define MLXSW_REG_QPCR_ID 0x4004 1766 + #define MLXSW_REG_QPCR_LEN 0x28 1767 + 1768 + MLXSW_REG_DEFINE(qpcr, MLXSW_REG_QPCR_ID, MLXSW_REG_QPCR_LEN); 1769 + 1770 + enum mlxsw_reg_qpcr_g { 1771 + MLXSW_REG_QPCR_G_GLOBAL = 2, 1772 + MLXSW_REG_QPCR_G_STORM_CONTROL = 3, 1773 + }; 1774 + 1775 + /* reg_qpcr_g 1776 + * The policer type. 1777 + * Access: Index 1778 + */ 1779 + MLXSW_ITEM32(reg, qpcr, g, 0x00, 14, 2); 1780 + 1781 + /* reg_qpcr_pid 1782 + * Policer ID. 1783 + * Access: Index 1784 + */ 1785 + MLXSW_ITEM32(reg, qpcr, pid, 0x00, 0, 14); 1786 + 1787 + /* reg_qpcr_color_aware 1788 + * Is the policer aware of colors. 1789 + * Must be 0 (unaware) for cpu port. 1790 + * Access: RW for unbounded policer. RO for bounded policer. 1791 + */ 1792 + MLXSW_ITEM32(reg, qpcr, color_aware, 0x04, 15, 1); 1793 + 1794 + /* reg_qpcr_bytes 1795 + * Is policer limit is for bytes per sec or packets per sec. 1796 + * 0 - packets 1797 + * 1 - bytes 1798 + * Access: RW for unbounded policer. RO for bounded policer. 1799 + */ 1800 + MLXSW_ITEM32(reg, qpcr, bytes, 0x04, 14, 1); 1801 + 1802 + enum mlxsw_reg_qpcr_ir_units { 1803 + MLXSW_REG_QPCR_IR_UNITS_M, 1804 + MLXSW_REG_QPCR_IR_UNITS_K, 1805 + }; 1806 + 1807 + /* reg_qpcr_ir_units 1808 + * Policer's units for cir and eir fields (for bytes limits only) 1809 + * 1 - 10^3 1810 + * 0 - 10^6 1811 + * Access: OP 1812 + */ 1813 + MLXSW_ITEM32(reg, qpcr, ir_units, 0x04, 12, 1); 1814 + 1815 + enum mlxsw_reg_qpcr_rate_type { 1816 + MLXSW_REG_QPCR_RATE_TYPE_SINGLE = 1, 1817 + MLXSW_REG_QPCR_RATE_TYPE_DOUBLE = 2, 1818 + }; 1819 + 1820 + /* reg_qpcr_rate_type 1821 + * Policer can have one limit (single rate) or 2 limits with specific operation 1822 + * for packets that exceed the lower rate but not the upper one. 1823 + * (For cpu port must be single rate) 1824 + * Access: RW for unbounded policer. RO for bounded policer. 1825 + */ 1826 + MLXSW_ITEM32(reg, qpcr, rate_type, 0x04, 8, 2); 1827 + 1828 + /* reg_qpc_cbs 1829 + * Policer's committed burst size. 1830 + * The policer is working with time slices of 50 nano sec. By default every 1831 + * slice is granted the proportionate share of the committed rate. If we want to 1832 + * allow a slice to exceed that share (while still keeping the rate per sec) we 1833 + * can allow burst. The burst size is between the default proportionate share 1834 + * (and no lower than 8) to 32Gb. (Even though giving a number higher than the 1835 + * committed rate will result in exceeding the rate). The burst size must be a 1836 + * log of 2 and will be determined by 2^cbs. 1837 + * Access: RW 1838 + */ 1839 + MLXSW_ITEM32(reg, qpcr, cbs, 0x08, 24, 6); 1840 + 1841 + /* reg_qpcr_cir 1842 + * Policer's committed rate. 1843 + * The rate used for sungle rate, the lower rate for double rate. 1844 + * For bytes limits, the rate will be this value * the unit from ir_units. 1845 + * (Resolution error is up to 1%). 1846 + * Access: RW 1847 + */ 1848 + MLXSW_ITEM32(reg, qpcr, cir, 0x0C, 0, 32); 1849 + 1850 + /* reg_qpcr_eir 1851 + * Policer's exceed rate. 1852 + * The higher rate for double rate, reserved for single rate. 1853 + * Lower rate for double rate policer. 1854 + * For bytes limits, the rate will be this value * the unit from ir_units. 1855 + * (Resolution error is up to 1%). 1856 + * Access: RW 1857 + */ 1858 + MLXSW_ITEM32(reg, qpcr, eir, 0x10, 0, 32); 1859 + 1860 + #define MLXSW_REG_QPCR_DOUBLE_RATE_ACTION 2 1861 + 1862 + /* reg_qpcr_exceed_action. 1863 + * What to do with packets between the 2 limits for double rate. 1864 + * Access: RW for unbounded policer. RO for bounded policer. 1865 + */ 1866 + MLXSW_ITEM32(reg, qpcr, exceed_action, 0x14, 0, 4); 1867 + 1868 + enum mlxsw_reg_qpcr_action { 1869 + /* Discard */ 1870 + MLXSW_REG_QPCR_ACTION_DISCARD = 1, 1871 + /* Forward and set color to red. 1872 + * If the packet is intended to cpu port, it will be dropped. 1873 + */ 1874 + MLXSW_REG_QPCR_ACTION_FORWARD = 2, 1875 + }; 1876 + 1877 + /* reg_qpcr_violate_action 1878 + * What to do with packets that cross the cir limit (for single rate) or the eir 1879 + * limit (for double rate). 1880 + * Access: RW for unbounded policer. RO for bounded policer. 1881 + */ 1882 + MLXSW_ITEM32(reg, qpcr, violate_action, 0x18, 0, 4); 1883 + 1884 + static inline void mlxsw_reg_qpcr_pack(char *payload, u16 pid, 1885 + enum mlxsw_reg_qpcr_ir_units ir_units, 1886 + bool bytes, u32 cir, u16 cbs) 1887 + { 1888 + MLXSW_REG_ZERO(qpcr, payload); 1889 + mlxsw_reg_qpcr_pid_set(payload, pid); 1890 + mlxsw_reg_qpcr_g_set(payload, MLXSW_REG_QPCR_G_GLOBAL); 1891 + mlxsw_reg_qpcr_rate_type_set(payload, MLXSW_REG_QPCR_RATE_TYPE_SINGLE); 1892 + mlxsw_reg_qpcr_violate_action_set(payload, 1893 + MLXSW_REG_QPCR_ACTION_DISCARD); 1894 + mlxsw_reg_qpcr_cir_set(payload, cir); 1895 + mlxsw_reg_qpcr_ir_units_set(payload, ir_units); 1896 + mlxsw_reg_qpcr_bytes_set(payload, bytes); 1897 + mlxsw_reg_qpcr_cbs_set(payload, cbs); 1898 + } 1899 + 1760 1900 /* QTCT - QoS Switch Traffic Class Table 1761 1901 * ------------------------------------- 1762 1902 * Configures the mapping between the packet switch priority and the ··· 3174 3034 3175 3035 enum mlxsw_reg_htgt_trap_group { 3176 3036 MLXSW_REG_HTGT_TRAP_GROUP_EMAD, 3177 - MLXSW_REG_HTGT_TRAP_GROUP_RX, 3178 - MLXSW_REG_HTGT_TRAP_GROUP_CTRL, 3037 + MLXSW_REG_HTGT_TRAP_GROUP_SX2_RX, 3038 + MLXSW_REG_HTGT_TRAP_GROUP_SX2_CTRL, 3039 + MLXSW_REG_HTGT_TRAP_GROUP_SP_STP, 3040 + MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP, 3041 + MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP, 3042 + MLXSW_REG_HTGT_TRAP_GROUP_SP_IGMP, 3043 + MLXSW_REG_HTGT_TRAP_GROUP_SP_BGP_IPV4, 3044 + MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF, 3045 + MLXSW_REG_HTGT_TRAP_GROUP_SP_ARP, 3046 + MLXSW_REG_HTGT_TRAP_GROUP_SP_ARP_MISS, 3047 + MLXSW_REG_HTGT_TRAP_GROUP_SP_ROUTER_EXP, 3048 + MLXSW_REG_HTGT_TRAP_GROUP_SP_REMOTE_ROUTE, 3049 + MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME, 3050 + MLXSW_REG_HTGT_TRAP_GROUP_SP_DHCP, 3051 + MLXSW_REG_HTGT_TRAP_GROUP_SP_EVENT, 3179 3052 }; 3180 3053 3181 3054 /* reg_htgt_trap_group ··· 3209 3056 * Access: RW 3210 3057 */ 3211 3058 MLXSW_ITEM32(reg, htgt, pide, 0x04, 15, 1); 3059 + 3060 + #define MLXSW_REG_HTGT_INVALID_POLICER 0xff 3212 3061 3213 3062 /* reg_htgt_pid 3214 3063 * Policer ID for the trap group. ··· 3237 3082 */ 3238 3083 MLXSW_ITEM32(reg, htgt, mirroring_agent, 0x08, 0, 3); 3239 3084 3085 + #define MLXSW_REG_HTGT_DEFAULT_PRIORITY 0 3086 + 3240 3087 /* reg_htgt_priority 3241 3088 * Trap group priority. 3242 3089 * In case a packet matches multiple classification rules, the packet will ··· 3252 3095 */ 3253 3096 MLXSW_ITEM32(reg, htgt, priority, 0x0C, 0, 4); 3254 3097 3098 + #define MLXSW_REG_HTGT_DEFAULT_TC 7 3099 + 3255 3100 /* reg_htgt_local_path_cpu_tclass 3256 3101 * CPU ingress traffic class for the trap group. 3257 3102 * Access: RW 3258 3103 */ 3259 3104 MLXSW_ITEM32(reg, htgt, local_path_cpu_tclass, 0x10, 16, 6); 3260 3105 3261 - #define MLXSW_REG_HTGT_LOCAL_PATH_RDQ_EMAD 0x15 3262 - #define MLXSW_REG_HTGT_LOCAL_PATH_RDQ_RX 0x14 3263 - #define MLXSW_REG_HTGT_LOCAL_PATH_RDQ_CTRL 0x13 3264 - 3106 + enum mlxsw_reg_htgt_local_path_rdq { 3107 + MLXSW_REG_HTGT_LOCAL_PATH_RDQ_SX2_CTRL = 0x13, 3108 + MLXSW_REG_HTGT_LOCAL_PATH_RDQ_SX2_RX = 0x14, 3109 + MLXSW_REG_HTGT_LOCAL_PATH_RDQ_SX2_EMAD = 0x15, 3110 + MLXSW_REG_HTGT_LOCAL_PATH_RDQ_SIB_EMAD = 0x15, 3111 + }; 3265 3112 /* reg_htgt_local_path_rdq 3266 3113 * Receive descriptor queue (RDQ) to use for the trap group. 3267 3114 * Access: RW 3268 3115 */ 3269 3116 MLXSW_ITEM32(reg, htgt, local_path_rdq, 0x10, 0, 6); 3270 3117 3271 - static inline void mlxsw_reg_htgt_pack(char *payload, 3272 - enum mlxsw_reg_htgt_trap_group group) 3118 + static inline void mlxsw_reg_htgt_pack(char *payload, u8 group, u8 policer_id, 3119 + u8 priority, u8 tc) 3273 3120 { 3274 - u8 swid, rdq; 3275 - 3276 3121 MLXSW_REG_ZERO(htgt, payload); 3277 - switch (group) { 3278 - case MLXSW_REG_HTGT_TRAP_GROUP_EMAD: 3279 - swid = MLXSW_PORT_SWID_ALL_SWIDS; 3280 - rdq = MLXSW_REG_HTGT_LOCAL_PATH_RDQ_EMAD; 3281 - break; 3282 - case MLXSW_REG_HTGT_TRAP_GROUP_RX: 3283 - swid = 0; 3284 - rdq = MLXSW_REG_HTGT_LOCAL_PATH_RDQ_RX; 3285 - break; 3286 - case MLXSW_REG_HTGT_TRAP_GROUP_CTRL: 3287 - swid = 0; 3288 - rdq = MLXSW_REG_HTGT_LOCAL_PATH_RDQ_CTRL; 3289 - break; 3122 + 3123 + if (policer_id == MLXSW_REG_HTGT_INVALID_POLICER) { 3124 + mlxsw_reg_htgt_pide_set(payload, 3125 + MLXSW_REG_HTGT_POLICER_DISABLE); 3126 + } else { 3127 + mlxsw_reg_htgt_pide_set(payload, 3128 + MLXSW_REG_HTGT_POLICER_ENABLE); 3129 + mlxsw_reg_htgt_pid_set(payload, policer_id); 3290 3130 } 3291 - mlxsw_reg_htgt_swid_set(payload, swid); 3131 + 3292 3132 mlxsw_reg_htgt_type_set(payload, MLXSW_REG_HTGT_PATH_TYPE_LOCAL); 3293 3133 mlxsw_reg_htgt_trap_group_set(payload, group); 3294 - mlxsw_reg_htgt_pide_set(payload, MLXSW_REG_HTGT_POLICER_DISABLE); 3295 - mlxsw_reg_htgt_pid_set(payload, 0); 3296 3134 mlxsw_reg_htgt_mirror_action_set(payload, MLXSW_REG_HTGT_TRAP_TO_CPU); 3297 3135 mlxsw_reg_htgt_mirroring_agent_set(payload, 0); 3298 - mlxsw_reg_htgt_priority_set(payload, 0); 3299 - mlxsw_reg_htgt_local_path_cpu_tclass_set(payload, 7); 3300 - mlxsw_reg_htgt_local_path_rdq_set(payload, rdq); 3136 + mlxsw_reg_htgt_priority_set(payload, priority); 3137 + mlxsw_reg_htgt_local_path_cpu_tclass_set(payload, tc); 3138 + mlxsw_reg_htgt_local_path_rdq_set(payload, group); 3301 3139 } 3302 3140 3303 3141 /* HPKT - Host Packet Trap ··· 3366 3214 3367 3215 /* reg_hpkt_ctrl 3368 3216 * Configure dedicated buffer resources for control packets. 3217 + * Ignored by SwitchX-2. 3369 3218 * 0 - Keep factory defaults. 3370 3219 * 1 - Do not use control buffer for this trap ID. 3371 3220 * 2 - Use control buffer for this trap ID. ··· 3374 3221 */ 3375 3222 MLXSW_ITEM32(reg, hpkt, ctrl, 0x04, 16, 2); 3376 3223 3377 - static inline void mlxsw_reg_hpkt_pack(char *payload, u8 action, u16 trap_id) 3224 + static inline void mlxsw_reg_hpkt_pack(char *payload, u8 action, u16 trap_id, 3225 + enum mlxsw_reg_htgt_trap_group trap_group, 3226 + bool is_ctrl) 3378 3227 { 3379 - enum mlxsw_reg_htgt_trap_group trap_group; 3380 - 3381 3228 MLXSW_REG_ZERO(hpkt, payload); 3382 3229 mlxsw_reg_hpkt_ack_set(payload, MLXSW_REG_HPKT_ACK_NOT_REQUIRED); 3383 3230 mlxsw_reg_hpkt_action_set(payload, action); 3384 - switch (trap_id) { 3385 - case MLXSW_TRAP_ID_ETHEMAD: 3386 - case MLXSW_TRAP_ID_PUDE: 3387 - trap_group = MLXSW_REG_HTGT_TRAP_GROUP_EMAD; 3388 - break; 3389 - default: 3390 - trap_group = MLXSW_REG_HTGT_TRAP_GROUP_RX; 3391 - break; 3392 - } 3393 3231 mlxsw_reg_hpkt_trap_group_set(payload, trap_group); 3394 3232 mlxsw_reg_hpkt_trap_id_set(payload, trap_id); 3395 - mlxsw_reg_hpkt_ctrl_set(payload, MLXSW_REG_HPKT_CTRL_PACKET_DEFAULT); 3233 + mlxsw_reg_hpkt_ctrl_set(payload, is_ctrl ? 3234 + MLXSW_REG_HPKT_CTRL_PACKET_USE_BUFFER : 3235 + MLXSW_REG_HPKT_CTRL_PACKET_NO_BUFFER); 3396 3236 } 3397 3237 3398 3238 /* RGCR - Router General Configuration Register ··· 5394 5248 MLXSW_REG(svpe), 5395 5249 MLXSW_REG(sfmr), 5396 5250 MLXSW_REG(spvmlr), 5251 + MLXSW_REG(qpcr), 5397 5252 MLXSW_REG(qtct), 5398 5253 MLXSW_REG(qeec), 5399 5254 MLXSW_REG(pmlp),
+4
drivers/net/ethernet/mellanox/mlxsw/resources.h
··· 42 42 MLXSW_RES_ID_KVD_SIZE, 43 43 MLXSW_RES_ID_KVD_SINGLE_MIN_SIZE, 44 44 MLXSW_RES_ID_KVD_DOUBLE_MIN_SIZE, 45 + MLXSW_RES_ID_MAX_TRAP_GROUPS, 45 46 MLXSW_RES_ID_MAX_SPAN, 46 47 MLXSW_RES_ID_MAX_SYSTEM_PORT, 47 48 MLXSW_RES_ID_MAX_LAG, 48 49 MLXSW_RES_ID_MAX_LAG_MEMBERS, 50 + MLXSW_RES_ID_MAX_CPU_POLICERS, 49 51 MLXSW_RES_ID_MAX_VRS, 50 52 MLXSW_RES_ID_MAX_RIFS, 51 53 ··· 65 63 [MLXSW_RES_ID_KVD_SIZE] = 0x1001, 66 64 [MLXSW_RES_ID_KVD_SINGLE_MIN_SIZE] = 0x1002, 67 65 [MLXSW_RES_ID_KVD_DOUBLE_MIN_SIZE] = 0x1003, 66 + [MLXSW_RES_ID_MAX_TRAP_GROUPS] = 0x2201, 68 67 [MLXSW_RES_ID_MAX_SPAN] = 0x2420, 69 68 [MLXSW_RES_ID_MAX_SYSTEM_PORT] = 0x2502, 70 69 [MLXSW_RES_ID_MAX_LAG] = 0x2520, 71 70 [MLXSW_RES_ID_MAX_LAG_MEMBERS] = 0x2521, 71 + [MLXSW_RES_ID_MAX_CPU_POLICERS] = 0x2A13, 72 72 [MLXSW_RES_ID_MAX_VRS] = 0x2C01, 73 73 [MLXSW_RES_ID_MAX_RIFS] = 0x2C02, 74 74 };
+192 -130
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
··· 2698 2698 } 2699 2699 } 2700 2700 2701 - static struct mlxsw_event_listener mlxsw_sp_pude_event = { 2702 - .func = mlxsw_sp_pude_event_func, 2703 - .trap_id = MLXSW_TRAP_ID_PUDE, 2704 - }; 2705 - 2706 - static int mlxsw_sp_event_register(struct mlxsw_sp *mlxsw_sp, 2707 - enum mlxsw_event_trap_id trap_id) 2708 - { 2709 - struct mlxsw_event_listener *el; 2710 - char hpkt_pl[MLXSW_REG_HPKT_LEN]; 2711 - int err; 2712 - 2713 - switch (trap_id) { 2714 - case MLXSW_TRAP_ID_PUDE: 2715 - el = &mlxsw_sp_pude_event; 2716 - break; 2717 - } 2718 - err = mlxsw_core_event_listener_register(mlxsw_sp->core, el, mlxsw_sp); 2719 - if (err) 2720 - return err; 2721 - 2722 - mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_FORWARD, trap_id); 2723 - err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl); 2724 - if (err) 2725 - goto err_event_trap_set; 2726 - 2727 - return 0; 2728 - 2729 - err_event_trap_set: 2730 - mlxsw_core_event_listener_unregister(mlxsw_sp->core, el, mlxsw_sp); 2731 - return err; 2732 - } 2733 - 2734 - static void mlxsw_sp_event_unregister(struct mlxsw_sp *mlxsw_sp, 2735 - enum mlxsw_event_trap_id trap_id) 2736 - { 2737 - struct mlxsw_event_listener *el; 2738 - 2739 - switch (trap_id) { 2740 - case MLXSW_TRAP_ID_PUDE: 2741 - el = &mlxsw_sp_pude_event; 2742 - break; 2743 - } 2744 - mlxsw_core_event_listener_unregister(mlxsw_sp->core, el, mlxsw_sp); 2745 - } 2746 - 2747 - static void mlxsw_sp_rx_listener_func(struct sk_buff *skb, u8 local_port, 2748 - void *priv) 2701 + static void mlxsw_sp_rx_listener_no_mark_func(struct sk_buff *skb, 2702 + u8 local_port, void *priv) 2749 2703 { 2750 2704 struct mlxsw_sp *mlxsw_sp = priv; 2751 2705 struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port]; ··· 2727 2773 void *priv) 2728 2774 { 2729 2775 skb->offload_fwd_mark = 1; 2730 - return mlxsw_sp_rx_listener_func(skb, local_port, priv); 2776 + return mlxsw_sp_rx_listener_no_mark_func(skb, local_port, priv); 2731 2777 } 2732 2778 2733 - #define MLXSW_SP_RXL(_func, _trap_id, _action) \ 2734 - { \ 2735 - .func = _func, \ 2736 - .local_port = MLXSW_PORT_DONT_CARE, \ 2737 - .trap_id = MLXSW_TRAP_ID_##_trap_id, \ 2738 - .action = MLXSW_REG_HPKT_ACTION_##_action, \ 2779 + #define MLXSW_SP_RXL_NO_MARK(_trap_id, _action, _trap_group, _is_ctrl) \ 2780 + MLXSW_RXL(mlxsw_sp_rx_listener_no_mark_func, _trap_id, _action, \ 2781 + _is_ctrl, SP_##_trap_group, DISCARD) 2782 + 2783 + #define MLXSW_SP_RXL_MARK(_trap_id, _action, _trap_group, _is_ctrl) \ 2784 + MLXSW_RXL(mlxsw_sp_rx_listener_mark_func, _trap_id, _action, \ 2785 + _is_ctrl, SP_##_trap_group, DISCARD) 2786 + 2787 + #define MLXSW_SP_EVENTL(_func, _trap_id) \ 2788 + MLXSW_EVENTL(_func, _trap_id, SP_EVENT) 2789 + 2790 + static const struct mlxsw_listener mlxsw_sp_listener[] = { 2791 + /* Events */ 2792 + MLXSW_SP_EVENTL(mlxsw_sp_pude_event_func, PUDE), 2793 + /* L2 traps */ 2794 + MLXSW_SP_RXL_NO_MARK(STP, TRAP_TO_CPU, STP, true), 2795 + MLXSW_SP_RXL_NO_MARK(LACP, TRAP_TO_CPU, LACP, true), 2796 + MLXSW_SP_RXL_NO_MARK(LLDP, TRAP_TO_CPU, LLDP, true), 2797 + MLXSW_SP_RXL_MARK(DHCP, MIRROR_TO_CPU, DHCP, false), 2798 + MLXSW_SP_RXL_MARK(IGMP_QUERY, MIRROR_TO_CPU, IGMP, false), 2799 + MLXSW_SP_RXL_NO_MARK(IGMP_V1_REPORT, TRAP_TO_CPU, IGMP, false), 2800 + MLXSW_SP_RXL_NO_MARK(IGMP_V2_REPORT, TRAP_TO_CPU, IGMP, false), 2801 + MLXSW_SP_RXL_NO_MARK(IGMP_V2_LEAVE, TRAP_TO_CPU, IGMP, false), 2802 + MLXSW_SP_RXL_NO_MARK(IGMP_V3_REPORT, TRAP_TO_CPU, IGMP, false), 2803 + MLXSW_SP_RXL_MARK(ARPBC, MIRROR_TO_CPU, ARP, false), 2804 + MLXSW_SP_RXL_MARK(ARPUC, MIRROR_TO_CPU, ARP, false), 2805 + /* L3 traps */ 2806 + MLXSW_SP_RXL_NO_MARK(MTUERROR, TRAP_TO_CPU, ROUTER_EXP, false), 2807 + MLXSW_SP_RXL_NO_MARK(TTLERROR, TRAP_TO_CPU, ROUTER_EXP, false), 2808 + MLXSW_SP_RXL_NO_MARK(LBERROR, TRAP_TO_CPU, ROUTER_EXP, false), 2809 + MLXSW_SP_RXL_MARK(OSPF, TRAP_TO_CPU, OSPF, false), 2810 + MLXSW_SP_RXL_NO_MARK(IP2ME, TRAP_TO_CPU, IP2ME, false), 2811 + MLXSW_SP_RXL_NO_MARK(RTR_INGRESS0, TRAP_TO_CPU, REMOTE_ROUTE, false), 2812 + MLXSW_SP_RXL_NO_MARK(HOST_MISS_IPV4, TRAP_TO_CPU, ARP_MISS, false), 2813 + MLXSW_SP_RXL_NO_MARK(BGP_IPV4, TRAP_TO_CPU, BGP_IPV4, false), 2814 + }; 2815 + 2816 + static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core) 2817 + { 2818 + char qpcr_pl[MLXSW_REG_QPCR_LEN]; 2819 + enum mlxsw_reg_qpcr_ir_units ir_units; 2820 + int max_cpu_policers; 2821 + bool is_bytes; 2822 + u8 burst_size; 2823 + u32 rate; 2824 + int i, err; 2825 + 2826 + if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_CPU_POLICERS)) 2827 + return -EIO; 2828 + 2829 + max_cpu_policers = MLXSW_CORE_RES_GET(mlxsw_core, MAX_CPU_POLICERS); 2830 + 2831 + ir_units = MLXSW_REG_QPCR_IR_UNITS_M; 2832 + for (i = 0; i < max_cpu_policers; i++) { 2833 + is_bytes = false; 2834 + switch (i) { 2835 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_STP: 2836 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP: 2837 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP: 2838 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF: 2839 + rate = 128; 2840 + burst_size = 7; 2841 + break; 2842 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_IGMP: 2843 + rate = 16 * 1024; 2844 + burst_size = 10; 2845 + break; 2846 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_BGP_IPV4: 2847 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_ARP: 2848 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_DHCP: 2849 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_ARP_MISS: 2850 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_ROUTER_EXP: 2851 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_REMOTE_ROUTE: 2852 + rate = 1024; 2853 + burst_size = 7; 2854 + break; 2855 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME: 2856 + is_bytes = true; 2857 + rate = 4 * 1024; 2858 + burst_size = 4; 2859 + break; 2860 + default: 2861 + continue; 2862 + } 2863 + 2864 + mlxsw_reg_qpcr_pack(qpcr_pl, i, ir_units, is_bytes, rate, 2865 + burst_size); 2866 + err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(qpcr), qpcr_pl); 2867 + if (err) 2868 + return err; 2739 2869 } 2740 2870 2741 - static const struct mlxsw_rx_listener mlxsw_sp_rx_listener[] = { 2742 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, FDB_MC, TRAP_TO_CPU), 2743 - /* Traps for specific L2 packet types, not trapped as FDB MC */ 2744 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, STP, TRAP_TO_CPU), 2745 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, LACP, TRAP_TO_CPU), 2746 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, EAPOL, TRAP_TO_CPU), 2747 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, LLDP, TRAP_TO_CPU), 2748 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, MMRP, TRAP_TO_CPU), 2749 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, MVRP, TRAP_TO_CPU), 2750 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, RPVST, TRAP_TO_CPU), 2751 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_mark_func, DHCP, MIRROR_TO_CPU), 2752 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_mark_func, IGMP_QUERY, MIRROR_TO_CPU), 2753 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, IGMP_V1_REPORT, TRAP_TO_CPU), 2754 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, IGMP_V2_REPORT, TRAP_TO_CPU), 2755 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, IGMP_V2_LEAVE, TRAP_TO_CPU), 2756 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, IGMP_V3_REPORT, TRAP_TO_CPU), 2757 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_mark_func, ARPBC, MIRROR_TO_CPU), 2758 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_mark_func, ARPUC, MIRROR_TO_CPU), 2759 - /* L3 traps */ 2760 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, MTUERROR, TRAP_TO_CPU), 2761 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, TTLERROR, TRAP_TO_CPU), 2762 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, LBERROR, TRAP_TO_CPU), 2763 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_mark_func, OSPF, TRAP_TO_CPU), 2764 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, IP2ME, TRAP_TO_CPU), 2765 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, RTR_INGRESS0, TRAP_TO_CPU), 2766 - MLXSW_SP_RXL(mlxsw_sp_rx_listener_func, HOST_MISS_IPV4, TRAP_TO_CPU), 2767 - }; 2871 + return 0; 2872 + } 2873 + 2874 + static int mlxsw_sp_trap_groups_set(struct mlxsw_core *mlxsw_core) 2875 + { 2876 + char htgt_pl[MLXSW_REG_HTGT_LEN]; 2877 + enum mlxsw_reg_htgt_trap_group i; 2878 + int max_cpu_policers; 2879 + int max_trap_groups; 2880 + u8 priority, tc; 2881 + u16 policer_id; 2882 + int err; 2883 + 2884 + if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_TRAP_GROUPS)) 2885 + return -EIO; 2886 + 2887 + max_trap_groups = MLXSW_CORE_RES_GET(mlxsw_core, MAX_TRAP_GROUPS); 2888 + max_cpu_policers = MLXSW_CORE_RES_GET(mlxsw_core, MAX_CPU_POLICERS); 2889 + 2890 + for (i = 0; i < max_trap_groups; i++) { 2891 + policer_id = i; 2892 + switch (i) { 2893 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_STP: 2894 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP: 2895 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP: 2896 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF: 2897 + priority = 5; 2898 + tc = 5; 2899 + break; 2900 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_BGP_IPV4: 2901 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_DHCP: 2902 + priority = 4; 2903 + tc = 4; 2904 + break; 2905 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_IGMP: 2906 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME: 2907 + priority = 3; 2908 + tc = 3; 2909 + break; 2910 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_ARP: 2911 + priority = 2; 2912 + tc = 2; 2913 + break; 2914 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_ARP_MISS: 2915 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_ROUTER_EXP: 2916 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_REMOTE_ROUTE: 2917 + priority = 1; 2918 + tc = 1; 2919 + break; 2920 + case MLXSW_REG_HTGT_TRAP_GROUP_SP_EVENT: 2921 + priority = MLXSW_REG_HTGT_DEFAULT_PRIORITY; 2922 + tc = MLXSW_REG_HTGT_DEFAULT_TC; 2923 + policer_id = MLXSW_REG_HTGT_INVALID_POLICER; 2924 + break; 2925 + default: 2926 + continue; 2927 + } 2928 + 2929 + if (max_cpu_policers <= policer_id && 2930 + policer_id != MLXSW_REG_HTGT_INVALID_POLICER) 2931 + return -EIO; 2932 + 2933 + mlxsw_reg_htgt_pack(htgt_pl, i, policer_id, priority, tc); 2934 + err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl); 2935 + if (err) 2936 + return err; 2937 + } 2938 + 2939 + return 0; 2940 + } 2768 2941 2769 2942 static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp) 2770 2943 { 2771 - char htgt_pl[MLXSW_REG_HTGT_LEN]; 2772 - char hpkt_pl[MLXSW_REG_HPKT_LEN]; 2773 2944 int i; 2774 2945 int err; 2775 2946 2776 - mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_RX); 2777 - err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(htgt), htgt_pl); 2947 + err = mlxsw_sp_cpu_policers_set(mlxsw_sp->core); 2778 2948 if (err) 2779 2949 return err; 2780 2950 2781 - mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_CTRL); 2782 - err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(htgt), htgt_pl); 2951 + err = mlxsw_sp_trap_groups_set(mlxsw_sp->core); 2783 2952 if (err) 2784 2953 return err; 2785 2954 2786 - for (i = 0; i < ARRAY_SIZE(mlxsw_sp_rx_listener); i++) { 2787 - err = mlxsw_core_rx_listener_register(mlxsw_sp->core, 2788 - &mlxsw_sp_rx_listener[i], 2789 - mlxsw_sp); 2955 + for (i = 0; i < ARRAY_SIZE(mlxsw_sp_listener); i++) { 2956 + err = mlxsw_core_trap_register(mlxsw_sp->core, 2957 + &mlxsw_sp_listener[i], 2958 + mlxsw_sp); 2790 2959 if (err) 2791 - goto err_rx_listener_register; 2960 + goto err_listener_register; 2792 2961 2793 - mlxsw_reg_hpkt_pack(hpkt_pl, mlxsw_sp_rx_listener[i].action, 2794 - mlxsw_sp_rx_listener[i].trap_id); 2795 - err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl); 2796 - if (err) 2797 - goto err_rx_trap_set; 2798 2962 } 2799 2963 return 0; 2800 2964 2801 - err_rx_trap_set: 2802 - mlxsw_core_rx_listener_unregister(mlxsw_sp->core, 2803 - &mlxsw_sp_rx_listener[i], 2804 - mlxsw_sp); 2805 - err_rx_listener_register: 2965 + err_listener_register: 2806 2966 for (i--; i >= 0; i--) { 2807 - mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_DISCARD, 2808 - mlxsw_sp_rx_listener[i].trap_id); 2809 - mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl); 2810 - 2811 - mlxsw_core_rx_listener_unregister(mlxsw_sp->core, 2812 - &mlxsw_sp_rx_listener[i], 2813 - mlxsw_sp); 2967 + mlxsw_core_trap_unregister(mlxsw_sp->core, 2968 + &mlxsw_sp_listener[i], 2969 + mlxsw_sp); 2814 2970 } 2815 2971 return err; 2816 2972 } 2817 2973 2818 2974 static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp) 2819 2975 { 2820 - char hpkt_pl[MLXSW_REG_HPKT_LEN]; 2821 2976 int i; 2822 2977 2823 - for (i = 0; i < ARRAY_SIZE(mlxsw_sp_rx_listener); i++) { 2824 - mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_DISCARD, 2825 - mlxsw_sp_rx_listener[i].trap_id); 2826 - mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(hpkt), hpkt_pl); 2827 - 2828 - mlxsw_core_rx_listener_unregister(mlxsw_sp->core, 2829 - &mlxsw_sp_rx_listener[i], 2830 - mlxsw_sp); 2978 + for (i = 0; i < ARRAY_SIZE(mlxsw_sp_listener); i++) { 2979 + mlxsw_core_trap_unregister(mlxsw_sp->core, 2980 + &mlxsw_sp_listener[i], 2981 + mlxsw_sp); 2831 2982 } 2832 2983 } 2833 2984 ··· 3017 2958 kfree(mlxsw_sp->lags); 3018 2959 } 3019 2960 2961 + static int mlxsw_sp_basic_trap_groups_set(struct mlxsw_core *mlxsw_core) 2962 + { 2963 + char htgt_pl[MLXSW_REG_HTGT_LEN]; 2964 + 2965 + mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_EMAD, 2966 + MLXSW_REG_HTGT_INVALID_POLICER, 2967 + MLXSW_REG_HTGT_DEFAULT_PRIORITY, 2968 + MLXSW_REG_HTGT_DEFAULT_TC); 2969 + return mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl); 2970 + } 2971 + 3020 2972 static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core, 3021 2973 const struct mlxsw_bus_info *mlxsw_bus_info) 3022 2974 { ··· 3046 2976 return err; 3047 2977 } 3048 2978 3049 - err = mlxsw_sp_event_register(mlxsw_sp, MLXSW_TRAP_ID_PUDE); 3050 - if (err) { 3051 - dev_err(mlxsw_sp->bus_info->dev, "Failed to register for PUDE events\n"); 3052 - return err; 3053 - } 3054 - 3055 2979 err = mlxsw_sp_traps_init(mlxsw_sp); 3056 2980 if (err) { 3057 - dev_err(mlxsw_sp->bus_info->dev, "Failed to set traps for RX\n"); 3058 - goto err_rx_listener_register; 2981 + dev_err(mlxsw_sp->bus_info->dev, "Failed to set traps\n"); 2982 + return err; 3059 2983 } 3060 2984 3061 2985 err = mlxsw_sp_flood_init(mlxsw_sp); ··· 3109 3045 err_buffers_init: 3110 3046 err_flood_init: 3111 3047 mlxsw_sp_traps_fini(mlxsw_sp); 3112 - err_rx_listener_register: 3113 - mlxsw_sp_event_unregister(mlxsw_sp, MLXSW_TRAP_ID_PUDE); 3114 3048 return err; 3115 3049 } 3116 3050 ··· 3123 3061 mlxsw_sp_lag_fini(mlxsw_sp); 3124 3062 mlxsw_sp_buffers_fini(mlxsw_sp); 3125 3063 mlxsw_sp_traps_fini(mlxsw_sp); 3126 - mlxsw_sp_event_unregister(mlxsw_sp, MLXSW_TRAP_ID_PUDE); 3127 3064 WARN_ON(!list_empty(&mlxsw_sp->vfids.list)); 3128 3065 WARN_ON(!list_empty(&mlxsw_sp->fids)); 3129 3066 } ··· 3164 3103 .priv_size = sizeof(struct mlxsw_sp), 3165 3104 .init = mlxsw_sp_init, 3166 3105 .fini = mlxsw_sp_fini, 3106 + .basic_trap_groups_set = mlxsw_sp_basic_trap_groups_set, 3167 3107 .port_split = mlxsw_sp_port_split, 3168 3108 .port_unsplit = mlxsw_sp_port_unsplit, 3169 3109 .sb_pool_get = mlxsw_sp_sb_pool_get,
+43 -35
drivers/net/ethernet/mellanox/mlxsw/switchib.c
··· 408 408 mlxsw_sib_pude_ib_event_func(mlxsw_sib_port, status); 409 409 } 410 410 411 - static struct mlxsw_event_listener mlxsw_sib_pude_event = { 412 - .func = mlxsw_sib_pude_event_func, 413 - .trap_id = MLXSW_TRAP_ID_PUDE, 411 + static const struct mlxsw_listener mlxsw_sib_listener[] = { 412 + MLXSW_EVENTL(mlxsw_sib_pude_event_func, PUDE, EMAD), 414 413 }; 415 414 416 - static int mlxsw_sib_event_register(struct mlxsw_sib *mlxsw_sib, 417 - enum mlxsw_event_trap_id trap_id) 415 + static int mlxsw_sib_taps_init(struct mlxsw_sib *mlxsw_sib) 418 416 { 419 - struct mlxsw_event_listener *el; 420 - char hpkt_pl[MLXSW_REG_HPKT_LEN]; 417 + int i; 421 418 int err; 422 419 423 - switch (trap_id) { 424 - case MLXSW_TRAP_ID_PUDE: 425 - el = &mlxsw_sib_pude_event; 426 - break; 420 + for (i = 0; i < ARRAY_SIZE(mlxsw_sib_listener); i++) { 421 + err = mlxsw_core_trap_register(mlxsw_sib->core, 422 + &mlxsw_sib_listener[i], 423 + mlxsw_sib); 424 + if (err) 425 + goto err_rx_listener_register; 427 426 } 428 - err = mlxsw_core_event_listener_register(mlxsw_sib->core, el, 429 - mlxsw_sib); 430 - if (err) 431 - return err; 432 - 433 - mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_FORWARD, trap_id); 434 - err = mlxsw_reg_write(mlxsw_sib->core, MLXSW_REG(hpkt), hpkt_pl); 435 - if (err) 436 - goto err_event_trap_set; 437 427 438 428 return 0; 439 429 440 - err_event_trap_set: 441 - mlxsw_core_event_listener_unregister(mlxsw_sib->core, el, mlxsw_sib); 430 + err_rx_listener_register: 431 + for (i--; i >= 0; i--) { 432 + mlxsw_core_trap_unregister(mlxsw_sib->core, 433 + &mlxsw_sib_listener[i], 434 + mlxsw_sib); 435 + } 436 + 442 437 return err; 443 438 } 444 439 445 - static void mlxsw_sib_event_unregister(struct mlxsw_sib *mlxsw_sib, 446 - enum mlxsw_event_trap_id trap_id) 440 + static void mlxsw_sib_traps_fini(struct mlxsw_sib *mlxsw_sib) 447 441 { 448 - struct mlxsw_event_listener *el; 442 + int i; 449 443 450 - switch (trap_id) { 451 - case MLXSW_TRAP_ID_PUDE: 452 - el = &mlxsw_sib_pude_event; 453 - break; 444 + for (i = 0; i < ARRAY_SIZE(mlxsw_sib_listener); i++) { 445 + mlxsw_core_trap_unregister(mlxsw_sib->core, 446 + &mlxsw_sib_listener[i], mlxsw_sib); 454 447 } 455 - mlxsw_core_event_listener_unregister(mlxsw_sib->core, el, mlxsw_sib); 448 + } 449 + 450 + static int mlxsw_sib_basic_trap_groups_set(struct mlxsw_core *mlxsw_core) 451 + { 452 + char htgt_pl[MLXSW_REG_HTGT_LEN]; 453 + 454 + mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_EMAD, 455 + MLXSW_REG_HTGT_INVALID_POLICER, 456 + MLXSW_REG_HTGT_DEFAULT_PRIORITY, 457 + MLXSW_REG_HTGT_DEFAULT_TC); 458 + mlxsw_reg_htgt_swid_set(htgt_pl, MLXSW_PORT_SWID_ALL_SWIDS); 459 + mlxsw_reg_htgt_local_path_rdq_set(htgt_pl, 460 + MLXSW_REG_HTGT_LOCAL_PATH_RDQ_SIB_EMAD); 461 + return mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl); 456 462 } 457 463 458 464 static int mlxsw_sib_init(struct mlxsw_core *mlxsw_core, ··· 476 470 return err; 477 471 } 478 472 479 - err = mlxsw_sib_event_register(mlxsw_sib, MLXSW_TRAP_ID_PUDE); 473 + err = mlxsw_sib_taps_init(mlxsw_sib); 480 474 if (err) { 481 - dev_err(mlxsw_sib->bus_info->dev, "Failed to register for PUDE events\n"); 482 - goto err_event_register; 475 + dev_err(mlxsw_sib->bus_info->dev, "Failed to set traps\n"); 476 + goto err_traps_init_err; 483 477 } 484 478 485 479 return 0; 486 480 487 - err_event_register: 481 + err_traps_init_err: 488 482 mlxsw_sib_ports_remove(mlxsw_sib); 489 483 return err; 490 484 } ··· 493 487 { 494 488 struct mlxsw_sib *mlxsw_sib = mlxsw_core_driver_priv(mlxsw_core); 495 489 496 - mlxsw_sib_event_unregister(mlxsw_sib, MLXSW_TRAP_ID_PUDE); 490 + mlxsw_sib_traps_fini(mlxsw_sib); 497 491 mlxsw_sib_ports_remove(mlxsw_sib); 498 492 } 499 493 ··· 518 512 .priv_size = sizeof(struct mlxsw_sib), 519 513 .init = mlxsw_sib_init, 520 514 .fini = mlxsw_sib_fini, 515 + .basic_trap_groups_set = mlxsw_sib_basic_trap_groups_set, 521 516 .txhdr_construct = mlxsw_sib_tx_v1_hdr_construct, 522 517 .txhdr_len = MLXSW_TXHDR_LEN, 523 518 .profile = &mlxsw_sib_config_profile, ··· 529 522 .priv_size = sizeof(struct mlxsw_sib), 530 523 .init = mlxsw_sib_init, 531 524 .fini = mlxsw_sib_fini, 525 + .basic_trap_groups_set = mlxsw_sib_basic_trap_groups_set, 532 526 .txhdr_construct = mlxsw_sib_tx_v1_hdr_construct, 533 527 .txhdr_len = MLXSW_TXHDR_LEN, 534 528 .profile = &mlxsw_sib_config_profile,
+65 -164
drivers/net/ethernet/mellanox/mlxsw/switchx2.c
··· 1396 1396 mlxsw_sx_pude_ib_event_func(mlxsw_sx_port, status); 1397 1397 } 1398 1398 1399 - static struct mlxsw_event_listener mlxsw_sx_pude_event = { 1400 - .func = mlxsw_sx_pude_event_func, 1401 - .trap_id = MLXSW_TRAP_ID_PUDE, 1402 - }; 1403 - 1404 - static int mlxsw_sx_event_register(struct mlxsw_sx *mlxsw_sx, 1405 - enum mlxsw_event_trap_id trap_id) 1406 - { 1407 - struct mlxsw_event_listener *el; 1408 - char hpkt_pl[MLXSW_REG_HPKT_LEN]; 1409 - int err; 1410 - 1411 - switch (trap_id) { 1412 - case MLXSW_TRAP_ID_PUDE: 1413 - el = &mlxsw_sx_pude_event; 1414 - break; 1415 - } 1416 - err = mlxsw_core_event_listener_register(mlxsw_sx->core, el, mlxsw_sx); 1417 - if (err) 1418 - return err; 1419 - 1420 - mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_FORWARD, trap_id); 1421 - err = mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(hpkt), hpkt_pl); 1422 - if (err) 1423 - goto err_event_trap_set; 1424 - 1425 - return 0; 1426 - 1427 - err_event_trap_set: 1428 - mlxsw_core_event_listener_unregister(mlxsw_sx->core, el, mlxsw_sx); 1429 - return err; 1430 - } 1431 - 1432 - static void mlxsw_sx_event_unregister(struct mlxsw_sx *mlxsw_sx, 1433 - enum mlxsw_event_trap_id trap_id) 1434 - { 1435 - struct mlxsw_event_listener *el; 1436 - 1437 - switch (trap_id) { 1438 - case MLXSW_TRAP_ID_PUDE: 1439 - el = &mlxsw_sx_pude_event; 1440 - break; 1441 - } 1442 - mlxsw_core_event_listener_unregister(mlxsw_sx->core, el, mlxsw_sx); 1443 - } 1444 - 1445 1399 static void mlxsw_sx_rx_listener_func(struct sk_buff *skb, u8 local_port, 1446 1400 void *priv) 1447 1401 { ··· 1448 1494 return err; 1449 1495 } 1450 1496 1451 - static const struct mlxsw_rx_listener mlxsw_sx_rx_listener[] = { 1452 - { 1453 - .func = mlxsw_sx_rx_listener_func, 1454 - .local_port = MLXSW_PORT_DONT_CARE, 1455 - .trap_id = MLXSW_TRAP_ID_FDB_MC, 1456 - }, 1457 - /* Traps for specific L2 packet types, not trapped as FDB MC */ 1458 - { 1459 - .func = mlxsw_sx_rx_listener_func, 1460 - .local_port = MLXSW_PORT_DONT_CARE, 1461 - .trap_id = MLXSW_TRAP_ID_STP, 1462 - }, 1463 - { 1464 - .func = mlxsw_sx_rx_listener_func, 1465 - .local_port = MLXSW_PORT_DONT_CARE, 1466 - .trap_id = MLXSW_TRAP_ID_LACP, 1467 - }, 1468 - { 1469 - .func = mlxsw_sx_rx_listener_func, 1470 - .local_port = MLXSW_PORT_DONT_CARE, 1471 - .trap_id = MLXSW_TRAP_ID_EAPOL, 1472 - }, 1473 - { 1474 - .func = mlxsw_sx_rx_listener_func, 1475 - .local_port = MLXSW_PORT_DONT_CARE, 1476 - .trap_id = MLXSW_TRAP_ID_LLDP, 1477 - }, 1478 - { 1479 - .func = mlxsw_sx_rx_listener_func, 1480 - .local_port = MLXSW_PORT_DONT_CARE, 1481 - .trap_id = MLXSW_TRAP_ID_MMRP, 1482 - }, 1483 - { 1484 - .func = mlxsw_sx_rx_listener_func, 1485 - .local_port = MLXSW_PORT_DONT_CARE, 1486 - .trap_id = MLXSW_TRAP_ID_MVRP, 1487 - }, 1488 - { 1489 - .func = mlxsw_sx_rx_listener_func, 1490 - .local_port = MLXSW_PORT_DONT_CARE, 1491 - .trap_id = MLXSW_TRAP_ID_RPVST, 1492 - }, 1493 - { 1494 - .func = mlxsw_sx_rx_listener_func, 1495 - .local_port = MLXSW_PORT_DONT_CARE, 1496 - .trap_id = MLXSW_TRAP_ID_DHCP, 1497 - }, 1498 - { 1499 - .func = mlxsw_sx_rx_listener_func, 1500 - .local_port = MLXSW_PORT_DONT_CARE, 1501 - .trap_id = MLXSW_TRAP_ID_IGMP_QUERY, 1502 - }, 1503 - { 1504 - .func = mlxsw_sx_rx_listener_func, 1505 - .local_port = MLXSW_PORT_DONT_CARE, 1506 - .trap_id = MLXSW_TRAP_ID_IGMP_V1_REPORT, 1507 - }, 1508 - { 1509 - .func = mlxsw_sx_rx_listener_func, 1510 - .local_port = MLXSW_PORT_DONT_CARE, 1511 - .trap_id = MLXSW_TRAP_ID_IGMP_V2_REPORT, 1512 - }, 1513 - { 1514 - .func = mlxsw_sx_rx_listener_func, 1515 - .local_port = MLXSW_PORT_DONT_CARE, 1516 - .trap_id = MLXSW_TRAP_ID_IGMP_V2_LEAVE, 1517 - }, 1518 - { 1519 - .func = mlxsw_sx_rx_listener_func, 1520 - .local_port = MLXSW_PORT_DONT_CARE, 1521 - .trap_id = MLXSW_TRAP_ID_IGMP_V3_REPORT, 1522 - }, 1497 + #define MLXSW_SX_RXL(_trap_id) \ 1498 + MLXSW_RXL(mlxsw_sx_rx_listener_func, _trap_id, TRAP_TO_CPU, \ 1499 + false, SX2_RX, FORWARD) 1500 + 1501 + static const struct mlxsw_listener mlxsw_sx_listener[] = { 1502 + MLXSW_EVENTL(mlxsw_sx_pude_event_func, PUDE, EMAD), 1503 + MLXSW_SX_RXL(FDB_MC), 1504 + MLXSW_SX_RXL(STP), 1505 + MLXSW_SX_RXL(LACP), 1506 + MLXSW_SX_RXL(EAPOL), 1507 + MLXSW_SX_RXL(LLDP), 1508 + MLXSW_SX_RXL(MMRP), 1509 + MLXSW_SX_RXL(MVRP), 1510 + MLXSW_SX_RXL(RPVST), 1511 + MLXSW_SX_RXL(DHCP), 1512 + MLXSW_SX_RXL(IGMP_QUERY), 1513 + MLXSW_SX_RXL(IGMP_V1_REPORT), 1514 + MLXSW_SX_RXL(IGMP_V2_REPORT), 1515 + MLXSW_SX_RXL(IGMP_V2_LEAVE), 1516 + MLXSW_SX_RXL(IGMP_V3_REPORT), 1523 1517 }; 1524 1518 1525 1519 static int mlxsw_sx_traps_init(struct mlxsw_sx *mlxsw_sx) 1526 1520 { 1527 1521 char htgt_pl[MLXSW_REG_HTGT_LEN]; 1528 - char hpkt_pl[MLXSW_REG_HPKT_LEN]; 1529 1522 int i; 1530 1523 int err; 1531 1524 1532 - mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_RX); 1525 + mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_SX2_RX, 1526 + MLXSW_REG_HTGT_INVALID_POLICER, 1527 + MLXSW_REG_HTGT_DEFAULT_PRIORITY, 1528 + MLXSW_REG_HTGT_DEFAULT_TC); 1529 + mlxsw_reg_htgt_local_path_rdq_set(htgt_pl, 1530 + MLXSW_REG_HTGT_LOCAL_PATH_RDQ_SX2_RX); 1531 + 1533 1532 err = mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(htgt), htgt_pl); 1534 1533 if (err) 1535 1534 return err; 1536 1535 1537 - mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_CTRL); 1536 + mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_SX2_CTRL, 1537 + MLXSW_REG_HTGT_INVALID_POLICER, 1538 + MLXSW_REG_HTGT_DEFAULT_PRIORITY, 1539 + MLXSW_REG_HTGT_DEFAULT_TC); 1540 + mlxsw_reg_htgt_local_path_rdq_set(htgt_pl, 1541 + MLXSW_REG_HTGT_LOCAL_PATH_RDQ_SX2_CTRL); 1542 + 1538 1543 err = mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(htgt), htgt_pl); 1539 1544 if (err) 1540 1545 return err; 1541 1546 1542 - for (i = 0; i < ARRAY_SIZE(mlxsw_sx_rx_listener); i++) { 1543 - err = mlxsw_core_rx_listener_register(mlxsw_sx->core, 1544 - &mlxsw_sx_rx_listener[i], 1545 - mlxsw_sx); 1547 + for (i = 0; i < ARRAY_SIZE(mlxsw_sx_listener); i++) { 1548 + err = mlxsw_core_trap_register(mlxsw_sx->core, 1549 + &mlxsw_sx_listener[i], 1550 + mlxsw_sx); 1546 1551 if (err) 1547 - goto err_rx_listener_register; 1552 + goto err_listener_register; 1548 1553 1549 - mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU, 1550 - mlxsw_sx_rx_listener[i].trap_id); 1551 - err = mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(hpkt), hpkt_pl); 1552 - if (err) 1553 - goto err_rx_trap_set; 1554 1554 } 1555 1555 return 0; 1556 1556 1557 - err_rx_trap_set: 1558 - mlxsw_core_rx_listener_unregister(mlxsw_sx->core, 1559 - &mlxsw_sx_rx_listener[i], 1560 - mlxsw_sx); 1561 - err_rx_listener_register: 1557 + err_listener_register: 1562 1558 for (i--; i >= 0; i--) { 1563 - mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_FORWARD, 1564 - mlxsw_sx_rx_listener[i].trap_id); 1565 - mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(hpkt), hpkt_pl); 1566 - 1567 - mlxsw_core_rx_listener_unregister(mlxsw_sx->core, 1568 - &mlxsw_sx_rx_listener[i], 1569 - mlxsw_sx); 1559 + mlxsw_core_trap_unregister(mlxsw_sx->core, 1560 + &mlxsw_sx_listener[i], 1561 + mlxsw_sx); 1570 1562 } 1571 1563 return err; 1572 1564 } 1573 1565 1574 1566 static void mlxsw_sx_traps_fini(struct mlxsw_sx *mlxsw_sx) 1575 1567 { 1576 - char hpkt_pl[MLXSW_REG_HPKT_LEN]; 1577 1568 int i; 1578 1569 1579 - for (i = 0; i < ARRAY_SIZE(mlxsw_sx_rx_listener); i++) { 1580 - mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_FORWARD, 1581 - mlxsw_sx_rx_listener[i].trap_id); 1582 - mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(hpkt), hpkt_pl); 1583 - 1584 - mlxsw_core_rx_listener_unregister(mlxsw_sx->core, 1585 - &mlxsw_sx_rx_listener[i], 1586 - mlxsw_sx); 1570 + for (i = 0; i < ARRAY_SIZE(mlxsw_sx_listener); i++) { 1571 + mlxsw_core_trap_unregister(mlxsw_sx->core, 1572 + &mlxsw_sx_listener[i], 1573 + mlxsw_sx); 1587 1574 } 1588 1575 } 1589 1576 ··· 1596 1701 return mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(sgcr), sgcr_pl); 1597 1702 } 1598 1703 1704 + static int mlxsw_sx_basic_trap_groups_set(struct mlxsw_core *mlxsw_core) 1705 + { 1706 + char htgt_pl[MLXSW_REG_HTGT_LEN]; 1707 + 1708 + mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_EMAD, 1709 + MLXSW_REG_HTGT_INVALID_POLICER, 1710 + MLXSW_REG_HTGT_DEFAULT_PRIORITY, 1711 + MLXSW_REG_HTGT_DEFAULT_TC); 1712 + mlxsw_reg_htgt_swid_set(htgt_pl, MLXSW_PORT_SWID_ALL_SWIDS); 1713 + mlxsw_reg_htgt_local_path_rdq_set(htgt_pl, 1714 + MLXSW_REG_HTGT_LOCAL_PATH_RDQ_SX2_EMAD); 1715 + return mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl); 1716 + } 1717 + 1599 1718 static int mlxsw_sx_init(struct mlxsw_core *mlxsw_core, 1600 1719 const struct mlxsw_bus_info *mlxsw_bus_info) 1601 1720 { ··· 1631 1722 return err; 1632 1723 } 1633 1724 1634 - err = mlxsw_sx_event_register(mlxsw_sx, MLXSW_TRAP_ID_PUDE); 1635 - if (err) { 1636 - dev_err(mlxsw_sx->bus_info->dev, "Failed to register for PUDE events\n"); 1637 - goto err_event_register; 1638 - } 1639 - 1640 1725 err = mlxsw_sx_traps_init(mlxsw_sx); 1641 1726 if (err) { 1642 - dev_err(mlxsw_sx->bus_info->dev, "Failed to set traps for RX\n"); 1643 - goto err_rx_listener_register; 1727 + dev_err(mlxsw_sx->bus_info->dev, "Failed to set traps\n"); 1728 + goto err_listener_register; 1644 1729 } 1645 1730 1646 1731 err = mlxsw_sx_flood_init(mlxsw_sx); ··· 1647 1744 1648 1745 err_flood_init: 1649 1746 mlxsw_sx_traps_fini(mlxsw_sx); 1650 - err_rx_listener_register: 1651 - mlxsw_sx_event_unregister(mlxsw_sx, MLXSW_TRAP_ID_PUDE); 1652 - err_event_register: 1747 + err_listener_register: 1653 1748 mlxsw_sx_ports_remove(mlxsw_sx); 1654 1749 return err; 1655 1750 } ··· 1657 1756 struct mlxsw_sx *mlxsw_sx = mlxsw_core_driver_priv(mlxsw_core); 1658 1757 1659 1758 mlxsw_sx_traps_fini(mlxsw_sx); 1660 - mlxsw_sx_event_unregister(mlxsw_sx, MLXSW_TRAP_ID_PUDE); 1661 1759 mlxsw_sx_ports_remove(mlxsw_sx); 1662 1760 } 1663 1761 ··· 1700 1800 .priv_size = sizeof(struct mlxsw_sx), 1701 1801 .init = mlxsw_sx_init, 1702 1802 .fini = mlxsw_sx_fini, 1803 + .basic_trap_groups_set = mlxsw_sx_basic_trap_groups_set, 1703 1804 .txhdr_construct = mlxsw_sx_txhdr_construct, 1704 1805 .txhdr_len = MLXSW_TXHDR_LEN, 1705 1806 .profile = &mlxsw_sx_config_profile,
+1
drivers/net/ethernet/mellanox/mlxsw/trap.h
··· 62 62 MLXSW_TRAP_ID_OSPF = 0x55, 63 63 MLXSW_TRAP_ID_IP2ME = 0x5F, 64 64 MLXSW_TRAP_ID_RTR_INGRESS0 = 0x70, 65 + MLXSW_TRAP_ID_BGP_IPV4 = 0x88, 65 66 MLXSW_TRAP_ID_HOST_MISS_IPV4 = 0x90, 66 67 67 68 MLXSW_TRAP_ID_MAX = 0x1FF