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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'mlx5-updates-2023-06-16' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

mlx5-updates-2023-06-16

1) Added a new event handler to firmware sync reset, which is used to
support firmware sync reset flow on smart NIC. Adding this new stage to
the flow enables the firmware to ensure host PFs unload before ECPFs
unload, to avoid race of PFs recovery.

2) Debugfs for mlx5 eswitch bridge offloads

3) Added two new counters for vport stats

4) Minor Fixups and cleanups for net-next branch

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

+435 -167
+10
Documentation/networking/device_drivers/ethernet/mellanox/mlx5/counters.rst
··· 797 797 RoCE/UD/RC traffic) [#accel]_. 798 798 - Acceleration 799 799 800 + * - `vport_loopback_packets` 801 + - Unicast, multicast and broadcast packets that were loop-back (received 802 + and transmitted), IB/Eth [#accel]_. 803 + - Acceleration 804 + 805 + * - `vport_loopback_bytes` 806 + - Unicast, multicast and broadcast bytes that were loop-back (received 807 + and transmitted), IB/Eth [#accel]_. 808 + - Acceleration 809 + 800 810 * - `rx_steer_missed_packets` 801 811 - Number of packets that was received by the NIC, however was discarded 802 812 because it did not match any flow in the NIC flow table.
+2 -1
drivers/net/ethernet/mellanox/mlx5/core/Makefile
··· 75 75 esw/acl/egress_lgcy.o esw/acl/egress_ofld.o \ 76 76 esw/acl/ingress_lgcy.o esw/acl/ingress_ofld.o 77 77 78 - mlx5_core-$(CONFIG_MLX5_BRIDGE) += esw/bridge.o esw/bridge_mcast.o en/rep/bridge.o 78 + mlx5_core-$(CONFIG_MLX5_BRIDGE) += esw/bridge.o esw/bridge_mcast.o esw/bridge_debugfs.o \ 79 + en/rep/bridge.o 79 80 80 81 mlx5_core-$(CONFIG_THERMAL) += thermal.o 81 82 mlx5_core-$(CONFIG_MLX5_MPFS) += lib/mpfs.o
-10
drivers/net/ethernet/mellanox/mlx5/core/en.h
··· 165 165 #define MLX5E_MAX_KLM_PER_WQE(mdev) \ 166 166 MLX5E_KLM_ENTRIES_PER_WQE(MLX5_SEND_WQE_BB * mlx5e_get_max_sq_aligned_wqebbs(mdev)) 167 167 168 - #define MLX5E_MSG_LEVEL NETIF_MSG_LINK 169 - 170 - #define mlx5e_dbg(mlevel, priv, format, ...) \ 171 - do { \ 172 - if (NETIF_MSG_##mlevel & (priv)->msglevel) \ 173 - netdev_warn(priv->netdev, format, \ 174 - ##__VA_ARGS__); \ 175 - } while (0) 176 - 177 168 #define mlx5e_state_dereference(priv, p) \ 178 169 rcu_dereference_protected((p), lockdep_is_held(&(priv)->state_lock)) 179 170 ··· 871 880 #endif 872 881 /* priv data path fields - end */ 873 882 874 - u32 msglevel; 875 883 unsigned long state; 876 884 struct mutex state_lock; /* Protects Interface state */ 877 885 struct mlx5e_rq drop_rq;
+23 -21
drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
··· 65 65 MLX5_GET(bufferx_reg, buffer, xoff_threshold) * port_buff_cell_sz; 66 66 total_used += port_buffer->buffer[i].size; 67 67 68 - mlx5e_dbg(HW, priv, "buffer %d: size=%d, xon=%d, xoff=%d, epsb=%d, lossy=%d\n", i, 69 - port_buffer->buffer[i].size, 70 - port_buffer->buffer[i].xon, 71 - port_buffer->buffer[i].xoff, 72 - port_buffer->buffer[i].epsb, 73 - port_buffer->buffer[i].lossy); 68 + netdev_dbg(priv->netdev, "buffer %d: size=%d, xon=%d, xoff=%d, epsb=%d, lossy=%d\n", 69 + i, 70 + port_buffer->buffer[i].size, 71 + port_buffer->buffer[i].xon, 72 + port_buffer->buffer[i].xoff, 73 + port_buffer->buffer[i].epsb, 74 + port_buffer->buffer[i].lossy); 74 75 } 75 76 76 77 port_buffer->internal_buffers_size = 0; ··· 88 87 port_buffer->internal_buffers_size - 89 88 port_buffer->headroom_size; 90 89 91 - mlx5e_dbg(HW, priv, 92 - "total buffer size=%u, headroom buffer size=%u, internal buffers size=%u, spare buffer size=%u\n", 93 - port_buffer->port_buffer_size, port_buffer->headroom_size, 94 - port_buffer->internal_buffers_size, 95 - port_buffer->spare_buffer_size); 90 + netdev_dbg(priv->netdev, 91 + "total buffer size=%u, headroom buffer size=%u, internal buffers size=%u, spare buffer size=%u\n", 92 + port_buffer->port_buffer_size, port_buffer->headroom_size, 93 + port_buffer->internal_buffers_size, 94 + port_buffer->spare_buffer_size); 96 95 out: 97 96 kfree(out); 98 97 return err; ··· 353 352 354 353 xoff = (301 + 216 * priv->dcbx.cable_len / 100) * speed / 1000 + 272 * mtu / 100; 355 354 356 - mlx5e_dbg(HW, priv, "%s: xoff=%d\n", __func__, xoff); 355 + netdev_dbg(priv->netdev, "%s: xoff=%d\n", __func__, xoff); 357 356 return xoff; 358 357 } 359 358 ··· 485 484 u8 *prio2buffer) 486 485 { 487 486 u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz; 487 + struct net_device *netdev = priv->netdev; 488 488 struct mlx5e_port_buffer port_buffer; 489 489 u32 xoff = calculate_xoff(priv, mtu); 490 490 bool update_prio2buffer = false; ··· 497 495 int err; 498 496 int i; 499 497 500 - mlx5e_dbg(HW, priv, "%s: change=%x\n", __func__, change); 498 + netdev_dbg(netdev, "%s: change=%x\n", __func__, change); 501 499 max_mtu = max_t(unsigned int, priv->netdev->max_mtu, MINIMUM_MAX_MTU); 502 500 503 501 err = mlx5e_port_query_buffer(priv, &port_buffer); ··· 512 510 } 513 511 514 512 if (change & MLX5E_PORT_BUFFER_PFC) { 515 - mlx5e_dbg(HW, priv, "%s: requested PFC per priority bitmask: 0x%x\n", 516 - __func__, pfc->pfc_en); 513 + netdev_dbg(netdev, "%s: requested PFC per priority bitmask: 0x%x\n", 514 + __func__, pfc->pfc_en); 517 515 err = mlx5e_port_query_priority2buffer(priv->mdev, buffer); 518 516 if (err) 519 517 return err; ··· 528 526 if (change & MLX5E_PORT_BUFFER_PRIO2BUFFER) { 529 527 update_prio2buffer = true; 530 528 for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++) 531 - mlx5e_dbg(HW, priv, "%s: requested to map prio[%d] to buffer %d\n", 532 - __func__, i, prio2buffer[i]); 529 + netdev_dbg(priv->netdev, "%s: requested to map prio[%d] to buffer %d\n", 530 + __func__, i, prio2buffer[i]); 533 531 534 532 err = fill_pfc_en(priv->mdev, &curr_pfc_en); 535 533 if (err) ··· 543 541 544 542 if (change & MLX5E_PORT_BUFFER_SIZE) { 545 543 for (i = 0; i < MLX5E_MAX_NETWORK_BUFFER; i++) { 546 - mlx5e_dbg(HW, priv, "%s: buffer[%d]=%d\n", __func__, i, buffer_size[i]); 544 + netdev_dbg(priv->netdev, "%s: buffer[%d]=%d\n", __func__, i, buffer_size[i]); 547 545 if (!port_buffer.buffer[i].lossy && !buffer_size[i]) { 548 - mlx5e_dbg(HW, priv, "%s: lossless buffer[%d] size cannot be zero\n", 549 - __func__, i); 546 + netdev_dbg(priv->netdev, "%s: lossless buffer[%d] size cannot be zero\n", 547 + __func__, i); 550 548 return -EINVAL; 551 549 } 552 550 ··· 554 552 total_used += buffer_size[i]; 555 553 } 556 554 557 - mlx5e_dbg(HW, priv, "%s: total buffer requested=%d\n", __func__, total_used); 555 + netdev_dbg(priv->netdev, "%s: total buffer requested=%d\n", __func__, total_used); 558 556 559 557 if (total_used > port_buffer.headroom_size && 560 558 (total_used - port_buffer.headroom_size) >
+4 -5
drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
··· 136 136 struct mlx5_eswitch *esw = br_offloads->esw; 137 137 u16 vport_num, esw_owner_vhca_id; 138 138 struct netlink_ext_ack *extack; 139 - int ifindex = upper->ifindex; 140 139 int err = 0; 141 140 142 141 if (!netif_is_bridge_master(upper)) ··· 149 150 150 151 if (mlx5_esw_bridge_is_local(dev, rep, esw)) 151 152 err = info->linking ? 152 - mlx5_esw_bridge_vport_link(ifindex, vport_num, esw_owner_vhca_id, 153 + mlx5_esw_bridge_vport_link(upper, vport_num, esw_owner_vhca_id, 153 154 br_offloads, extack) : 154 - mlx5_esw_bridge_vport_unlink(ifindex, vport_num, esw_owner_vhca_id, 155 + mlx5_esw_bridge_vport_unlink(upper, vport_num, esw_owner_vhca_id, 155 156 br_offloads, extack); 156 157 else if (mlx5_esw_bridge_dev_same_hw(rep, esw)) 157 158 err = info->linking ? 158 - mlx5_esw_bridge_vport_peer_link(ifindex, vport_num, esw_owner_vhca_id, 159 + mlx5_esw_bridge_vport_peer_link(upper, vport_num, esw_owner_vhca_id, 159 160 br_offloads, extack) : 160 - mlx5_esw_bridge_vport_peer_unlink(ifindex, vport_num, esw_owner_vhca_id, 161 + mlx5_esw_bridge_vport_peer_unlink(upper, vport_num, esw_owner_vhca_id, 161 162 br_offloads, extack); 162 163 163 164 return err;
+4 -4
drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
··· 570 570 if (IS_ERR(rule)) { 571 571 err = PTR_ERR(rule); 572 572 priv->channel_stats[arfs_rule->rxq]->rq.arfs_err++; 573 - mlx5e_dbg(HW, priv, 574 - "%s: add rule(filter id=%d, rq idx=%d, ip proto=0x%x) failed,err=%d\n", 575 - __func__, arfs_rule->filter_id, arfs_rule->rxq, 576 - tuple->ip_proto, err); 573 + netdev_dbg(priv->netdev, 574 + "%s: add rule(filter id=%d, rq idx=%d, ip proto=0x%x) failed,err=%d\n", 575 + __func__, arfs_rule->filter_id, arfs_rule->rxq, 576 + tuple->ip_proto, err); 577 577 } 578 578 579 579 out:
+13 -13
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
··· 275 275 memcpy(priv->dcbx.tc_tsa, ets->tc_tsa, sizeof(ets->tc_tsa)); 276 276 277 277 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 278 - mlx5e_dbg(HW, priv, "%s: prio_%d <=> tc_%d\n", 279 - __func__, i, ets->prio_tc[i]); 280 - mlx5e_dbg(HW, priv, "%s: tc_%d <=> tx_bw_%d%%, group_%d\n", 281 - __func__, i, tc_tx_bw[i], tc_group[i]); 278 + netdev_dbg(priv->netdev, "%s: prio_%d <=> tc_%d\n", 279 + __func__, i, ets->prio_tc[i]); 280 + netdev_dbg(priv->netdev, "%s: tc_%d <=> tx_bw_%d%%, group_%d\n", 281 + __func__, i, tc_tx_bw[i], tc_group[i]); 282 282 } 283 283 284 284 return err; ··· 399 399 } 400 400 401 401 if (!ret) { 402 - mlx5e_dbg(HW, priv, 403 - "%s: PFC per priority bit mask: 0x%x\n", 404 - __func__, pfc->pfc_en); 402 + netdev_dbg(dev, 403 + "%s: PFC per priority bit mask: 0x%x\n", 404 + __func__, pfc->pfc_en); 405 405 } 406 406 return ret; 407 407 } ··· 611 611 } 612 612 613 613 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 614 - mlx5e_dbg(HW, priv, "%s: tc_%d <=> max_bw %d Gbps\n", 615 - __func__, i, max_bw_value[i]); 614 + netdev_dbg(netdev, "%s: tc_%d <=> max_bw %d Gbps\n", 615 + __func__, i, max_bw_value[i]); 616 616 } 617 617 618 618 return mlx5_modify_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit); ··· 640 640 ets.tc_rx_bw[i] = cee_cfg->pg_bw_pct[i]; 641 641 ets.tc_tsa[i] = IEEE_8021QAZ_TSA_ETS; 642 642 ets.prio_tc[i] = cee_cfg->prio_to_pg_map[i]; 643 - mlx5e_dbg(HW, priv, 644 - "%s: Priority group %d: tx_bw %d, rx_bw %d, prio_tc %d\n", 645 - __func__, i, ets.tc_tx_bw[i], ets.tc_rx_bw[i], 646 - ets.prio_tc[i]); 643 + netdev_dbg(netdev, 644 + "%s: Priority group %d: tx_bw %d, rx_bw %d, prio_tc %d\n", 645 + __func__, i, ets.tc_tx_bw[i], ets.tc_rx_bw[i], 646 + ets.prio_tc[i]); 647 647 } 648 648 649 649 err = mlx5e_dbcnl_validate_ets(netdev, &ets, true);
+3 -15
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
··· 1689 1689 return 0; 1690 1690 } 1691 1691 1692 - static u32 mlx5e_get_msglevel(struct net_device *dev) 1693 - { 1694 - return ((struct mlx5e_priv *)netdev_priv(dev))->msglevel; 1695 - } 1696 - 1697 - static void mlx5e_set_msglevel(struct net_device *dev, u32 val) 1698 - { 1699 - ((struct mlx5e_priv *)netdev_priv(dev))->msglevel = val; 1700 - } 1701 - 1702 1692 static int mlx5e_set_phys_id(struct net_device *dev, 1703 1693 enum ethtool_phys_id_state state) 1704 1694 { ··· 1942 1952 if (err) 1943 1953 return err; 1944 1954 1945 - mlx5e_dbg(DRV, priv, "MLX5E: RxCqeCmprss was turned %s\n", 1946 - MLX5E_GET_PFLAG(&priv->channels.params, 1947 - MLX5E_PFLAG_RX_CQE_COMPRESS) ? "ON" : "OFF"); 1955 + netdev_dbg(priv->netdev, "MLX5E: RxCqeCmprss was turned %s\n", 1956 + MLX5E_GET_PFLAG(&priv->channels.params, 1957 + MLX5E_PFLAG_RX_CQE_COMPRESS) ? "ON" : "OFF"); 1948 1958 1949 1959 return 0; 1950 1960 } ··· 2434 2444 .get_priv_flags = mlx5e_get_priv_flags, 2435 2445 .set_priv_flags = mlx5e_set_priv_flags, 2436 2446 .self_test = mlx5e_self_test, 2437 - .get_msglevel = mlx5e_get_msglevel, 2438 - .set_msglevel = mlx5e_set_msglevel, 2439 2447 .get_fec_stats = mlx5e_get_fec_stats, 2440 2448 .get_fecparam = mlx5e_get_fecparam, 2441 2449 .set_fecparam = mlx5e_set_fecparam,
+2 -3
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
··· 2401 2401 /* Asymmetric dynamic memory allocation. 2402 2402 * Freed in mlx5e_priv_arrays_free, not on channel closure. 2403 2403 */ 2404 - mlx5e_dbg(DRV, priv, "Creating channel stats %d\n", ix); 2404 + netdev_dbg(priv->netdev, "Creating channel stats %d\n", ix); 2405 2405 priv->channel_stats[ix] = kvzalloc_node(sizeof(**priv->channel_stats), 2406 2406 GFP_KERNEL, cpu_to_node(cpu)); 2407 2407 if (!priv->channel_stats[ix]) ··· 2779 2779 if (MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_TX_PORT_TS)) 2780 2780 num_txqs += ntc; 2781 2781 2782 - mlx5e_dbg(DRV, priv, "Setting num_txqs %d\n", num_txqs); 2782 + netdev_dbg(priv->netdev, "Setting num_txqs %d\n", num_txqs); 2783 2783 err = netif_set_real_num_tx_queues(priv->netdev, num_txqs); 2784 2784 if (err) 2785 2785 netdev_warn(priv->netdev, "netif_set_real_num_tx_queues failed, %d\n", err); ··· 5585 5585 /* priv init */ 5586 5586 priv->mdev = mdev; 5587 5587 priv->netdev = netdev; 5588 - priv->msglevel = MLX5E_MSG_LEVEL; 5589 5588 priv->max_nch = nch; 5590 5589 priv->max_opened_tc = 1; 5591 5590
+23 -2
drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
··· 30 30 * SOFTWARE. 31 31 */ 32 32 33 - #include "lib/mlx5.h" 33 + #include "lib/events.h" 34 34 #include "en.h" 35 35 #include "en_accel/ktls.h" 36 36 #include "en_accel/en_accel.h" ··· 748 748 VPORT_COUNTER_OFF(transmitted_ib_multicast.octets) }, 749 749 }; 750 750 751 + static const struct counter_desc vport_loopback_stats_desc[] = { 752 + { "vport_loopback_packets", 753 + VPORT_COUNTER_OFF(local_loopback.packets) }, 754 + { "vport_loopback_bytes", 755 + VPORT_COUNTER_OFF(local_loopback.octets) }, 756 + }; 757 + 751 758 #define NUM_VPORT_COUNTERS ARRAY_SIZE(vport_stats_desc) 759 + #define NUM_VPORT_LOOPBACK_COUNTERS(dev) \ 760 + (MLX5_CAP_GEN(dev, vport_counter_local_loopback) ? \ 761 + ARRAY_SIZE(vport_loopback_stats_desc) : 0) 752 762 753 763 static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(vport) 754 764 { 755 - return NUM_VPORT_COUNTERS; 765 + return NUM_VPORT_COUNTERS + 766 + NUM_VPORT_LOOPBACK_COUNTERS(priv->mdev); 756 767 } 757 768 758 769 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(vport) ··· 772 761 773 762 for (i = 0; i < NUM_VPORT_COUNTERS; i++) 774 763 strcpy(data + (idx++) * ETH_GSTRING_LEN, vport_stats_desc[i].format); 764 + 765 + for (i = 0; i < NUM_VPORT_LOOPBACK_COUNTERS(priv->mdev); i++) 766 + strcpy(data + (idx++) * ETH_GSTRING_LEN, 767 + vport_loopback_stats_desc[i].format); 768 + 775 769 return idx; 776 770 } 777 771 ··· 787 771 for (i = 0; i < NUM_VPORT_COUNTERS; i++) 788 772 data[idx++] = MLX5E_READ_CTR64_BE(priv->stats.vport.query_vport_out, 789 773 vport_stats_desc, i); 774 + 775 + for (i = 0; i < NUM_VPORT_LOOPBACK_COUNTERS(priv->mdev); i++) 776 + data[idx++] = MLX5E_READ_CTR64_BE(priv->stats.vport.query_vport_out, 777 + vport_loopback_stats_desc, i); 778 + 790 779 return idx; 791 780 } 792 781
+23 -16
drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
··· 834 834 return handle; 835 835 } 836 836 837 - static struct mlx5_esw_bridge *mlx5_esw_bridge_create(int ifindex, 837 + static struct mlx5_esw_bridge *mlx5_esw_bridge_create(struct net_device *br_netdev, 838 838 struct mlx5_esw_bridge_offloads *br_offloads) 839 839 { 840 840 struct mlx5_esw_bridge *bridge; ··· 858 858 goto err_mdb_ht; 859 859 860 860 INIT_LIST_HEAD(&bridge->fdb_list); 861 - bridge->ifindex = ifindex; 861 + bridge->ifindex = br_netdev->ifindex; 862 862 bridge->refcnt = 1; 863 863 bridge->ageing_time = clock_t_to_jiffies(BR_DEFAULT_AGEING_TIME); 864 864 bridge->vlan_proto = ETH_P_8021Q; 865 865 list_add(&bridge->list, &br_offloads->bridges); 866 + mlx5_esw_bridge_debugfs_init(br_netdev, bridge); 866 867 867 868 return bridge; 868 869 ··· 887 886 if (--bridge->refcnt) 888 887 return; 889 888 889 + mlx5_esw_bridge_debugfs_cleanup(bridge); 890 890 mlx5_esw_bridge_egress_table_cleanup(bridge); 891 891 mlx5_esw_bridge_mcast_disable(bridge); 892 892 list_del(&bridge->list); ··· 900 898 } 901 899 902 900 static struct mlx5_esw_bridge * 903 - mlx5_esw_bridge_lookup(int ifindex, struct mlx5_esw_bridge_offloads *br_offloads) 901 + mlx5_esw_bridge_lookup(struct net_device *br_netdev, struct mlx5_esw_bridge_offloads *br_offloads) 904 902 { 905 903 struct mlx5_esw_bridge *bridge; 906 904 907 905 ASSERT_RTNL(); 908 906 909 907 list_for_each_entry(bridge, &br_offloads->bridges, list) { 910 - if (bridge->ifindex == ifindex) { 908 + if (bridge->ifindex == br_netdev->ifindex) { 911 909 mlx5_esw_bridge_get(bridge); 912 910 return bridge; 913 911 } ··· 920 918 return ERR_PTR(err); 921 919 } 922 920 923 - bridge = mlx5_esw_bridge_create(ifindex, br_offloads); 921 + bridge = mlx5_esw_bridge_create(br_netdev, br_offloads); 924 922 if (IS_ERR(bridge) && list_empty(&br_offloads->bridges)) 925 923 mlx5_esw_bridge_ingress_table_cleanup(br_offloads); 926 924 return bridge; ··· 1603 1601 return 0; 1604 1602 } 1605 1603 1606 - static int mlx5_esw_bridge_vport_link_with_flags(int ifindex, u16 vport_num, u16 esw_owner_vhca_id, 1607 - u16 flags, 1604 + static int mlx5_esw_bridge_vport_link_with_flags(struct net_device *br_netdev, u16 vport_num, 1605 + u16 esw_owner_vhca_id, u16 flags, 1608 1606 struct mlx5_esw_bridge_offloads *br_offloads, 1609 1607 struct netlink_ext_ack *extack) 1610 1608 { 1611 1609 struct mlx5_esw_bridge *bridge; 1612 1610 int err; 1613 1611 1614 - bridge = mlx5_esw_bridge_lookup(ifindex, br_offloads); 1612 + bridge = mlx5_esw_bridge_lookup(br_netdev, br_offloads); 1615 1613 if (IS_ERR(bridge)) { 1616 1614 NL_SET_ERR_MSG_MOD(extack, "Error checking for existing bridge with same ifindex"); 1617 1615 return PTR_ERR(bridge); ··· 1629 1627 return err; 1630 1628 } 1631 1629 1632 - int mlx5_esw_bridge_vport_link(int ifindex, u16 vport_num, u16 esw_owner_vhca_id, 1630 + int mlx5_esw_bridge_vport_link(struct net_device *br_netdev, u16 vport_num, u16 esw_owner_vhca_id, 1633 1631 struct mlx5_esw_bridge_offloads *br_offloads, 1634 1632 struct netlink_ext_ack *extack) 1635 1633 { 1636 - return mlx5_esw_bridge_vport_link_with_flags(ifindex, vport_num, esw_owner_vhca_id, 0, 1634 + return mlx5_esw_bridge_vport_link_with_flags(br_netdev, vport_num, esw_owner_vhca_id, 0, 1637 1635 br_offloads, extack); 1638 1636 } 1639 1637 1640 - int mlx5_esw_bridge_vport_unlink(int ifindex, u16 vport_num, u16 esw_owner_vhca_id, 1638 + int mlx5_esw_bridge_vport_unlink(struct net_device *br_netdev, u16 vport_num, 1639 + u16 esw_owner_vhca_id, 1641 1640 struct mlx5_esw_bridge_offloads *br_offloads, 1642 1641 struct netlink_ext_ack *extack) 1643 1642 { ··· 1650 1647 NL_SET_ERR_MSG_MOD(extack, "Port is not attached to any bridge"); 1651 1648 return -EINVAL; 1652 1649 } 1653 - if (port->bridge->ifindex != ifindex) { 1650 + if (port->bridge->ifindex != br_netdev->ifindex) { 1654 1651 NL_SET_ERR_MSG_MOD(extack, "Port is attached to another bridge"); 1655 1652 return -EINVAL; 1656 1653 } ··· 1661 1658 return err; 1662 1659 } 1663 1660 1664 - int mlx5_esw_bridge_vport_peer_link(int ifindex, u16 vport_num, u16 esw_owner_vhca_id, 1661 + int mlx5_esw_bridge_vport_peer_link(struct net_device *br_netdev, u16 vport_num, 1662 + u16 esw_owner_vhca_id, 1665 1663 struct mlx5_esw_bridge_offloads *br_offloads, 1666 1664 struct netlink_ext_ack *extack) 1667 1665 { 1668 1666 if (!MLX5_CAP_ESW(br_offloads->esw->dev, merged_eswitch)) 1669 1667 return 0; 1670 1668 1671 - return mlx5_esw_bridge_vport_link_with_flags(ifindex, vport_num, esw_owner_vhca_id, 1669 + return mlx5_esw_bridge_vport_link_with_flags(br_netdev, vport_num, esw_owner_vhca_id, 1672 1670 MLX5_ESW_BRIDGE_PORT_FLAG_PEER, 1673 1671 br_offloads, extack); 1674 1672 } 1675 1673 1676 - int mlx5_esw_bridge_vport_peer_unlink(int ifindex, u16 vport_num, u16 esw_owner_vhca_id, 1674 + int mlx5_esw_bridge_vport_peer_unlink(struct net_device *br_netdev, u16 vport_num, 1675 + u16 esw_owner_vhca_id, 1677 1676 struct mlx5_esw_bridge_offloads *br_offloads, 1678 1677 struct netlink_ext_ack *extack) 1679 1678 { 1680 - return mlx5_esw_bridge_vport_unlink(ifindex, vport_num, esw_owner_vhca_id, br_offloads, 1679 + return mlx5_esw_bridge_vport_unlink(br_netdev, vport_num, esw_owner_vhca_id, br_offloads, 1681 1680 extack); 1682 1681 } 1683 1682 ··· 1906 1901 xa_init(&br_offloads->ports); 1907 1902 br_offloads->esw = esw; 1908 1903 esw->br_offloads = br_offloads; 1904 + mlx5_esw_bridge_debugfs_offloads_init(br_offloads); 1909 1905 1910 1906 return br_offloads; 1911 1907 } ··· 1922 1916 1923 1917 mlx5_esw_bridge_flush(br_offloads); 1924 1918 WARN_ON(!xa_empty(&br_offloads->ports)); 1919 + mlx5_esw_bridge_debugfs_offloads_cleanup(br_offloads); 1925 1920 1926 1921 esw->br_offloads = NULL; 1927 1922 kvfree(br_offloads);
+8 -4
drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.h
··· 10 10 #include <linux/xarray.h> 11 11 #include "eswitch.h" 12 12 13 + struct dentry; 13 14 struct mlx5_flow_table; 14 15 struct mlx5_flow_group; 15 16 ··· 18 17 struct mlx5_eswitch *esw; 19 18 struct list_head bridges; 20 19 struct xarray ports; 20 + struct dentry *debugfs_root; 21 21 22 22 struct notifier_block netdev_nb; 23 23 struct notifier_block nb_blk; ··· 45 43 46 44 struct mlx5_esw_bridge_offloads *mlx5_esw_bridge_init(struct mlx5_eswitch *esw); 47 45 void mlx5_esw_bridge_cleanup(struct mlx5_eswitch *esw); 48 - int mlx5_esw_bridge_vport_link(int ifindex, u16 vport_num, u16 esw_owner_vhca_id, 46 + int mlx5_esw_bridge_vport_link(struct net_device *br_netdev, u16 vport_num, u16 esw_owner_vhca_id, 49 47 struct mlx5_esw_bridge_offloads *br_offloads, 50 48 struct netlink_ext_ack *extack); 51 - int mlx5_esw_bridge_vport_unlink(int ifindex, u16 vport_num, u16 esw_owner_vhca_id, 49 + int mlx5_esw_bridge_vport_unlink(struct net_device *br_netdev, u16 vport_num, u16 esw_owner_vhca_id, 52 50 struct mlx5_esw_bridge_offloads *br_offloads, 53 51 struct netlink_ext_ack *extack); 54 - int mlx5_esw_bridge_vport_peer_link(int ifindex, u16 vport_num, u16 esw_owner_vhca_id, 52 + int mlx5_esw_bridge_vport_peer_link(struct net_device *br_netdev, u16 vport_num, 53 + u16 esw_owner_vhca_id, 55 54 struct mlx5_esw_bridge_offloads *br_offloads, 56 55 struct netlink_ext_ack *extack); 57 - int mlx5_esw_bridge_vport_peer_unlink(int ifindex, u16 vport_num, u16 esw_owner_vhca_id, 56 + int mlx5_esw_bridge_vport_peer_unlink(struct net_device *br_netdev, u16 vport_num, 57 + u16 esw_owner_vhca_id, 58 58 struct mlx5_esw_bridge_offloads *br_offloads, 59 59 struct netlink_ext_ack *extack); 60 60 void mlx5_esw_bridge_fdb_update_used(struct net_device *dev, u16 vport_num, u16 esw_owner_vhca_id,
+89
drivers/net/ethernet/mellanox/mlx5/core/esw/bridge_debugfs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 + /* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ 3 + 4 + #include <linux/debugfs.h> 5 + #include "bridge.h" 6 + #include "bridge_priv.h" 7 + 8 + static void *mlx5_esw_bridge_debugfs_start(struct seq_file *seq, loff_t *pos); 9 + static void *mlx5_esw_bridge_debugfs_next(struct seq_file *seq, void *v, loff_t *pos); 10 + static void mlx5_esw_bridge_debugfs_stop(struct seq_file *seq, void *v); 11 + static int mlx5_esw_bridge_debugfs_show(struct seq_file *seq, void *v); 12 + 13 + static const struct seq_operations mlx5_esw_bridge_debugfs_sops = { 14 + .start = mlx5_esw_bridge_debugfs_start, 15 + .next = mlx5_esw_bridge_debugfs_next, 16 + .stop = mlx5_esw_bridge_debugfs_stop, 17 + .show = mlx5_esw_bridge_debugfs_show, 18 + }; 19 + DEFINE_SEQ_ATTRIBUTE(mlx5_esw_bridge_debugfs); 20 + 21 + static void *mlx5_esw_bridge_debugfs_start(struct seq_file *seq, loff_t *pos) 22 + { 23 + struct mlx5_esw_bridge *bridge = seq->private; 24 + 25 + rtnl_lock(); 26 + return *pos ? seq_list_start(&bridge->fdb_list, *pos - 1) : SEQ_START_TOKEN; 27 + } 28 + 29 + static void *mlx5_esw_bridge_debugfs_next(struct seq_file *seq, void *v, loff_t *pos) 30 + { 31 + struct mlx5_esw_bridge *bridge = seq->private; 32 + 33 + return seq_list_next(v == SEQ_START_TOKEN ? &bridge->fdb_list : v, &bridge->fdb_list, pos); 34 + } 35 + 36 + static void mlx5_esw_bridge_debugfs_stop(struct seq_file *seq, void *v) 37 + { 38 + rtnl_unlock(); 39 + } 40 + 41 + static int mlx5_esw_bridge_debugfs_show(struct seq_file *seq, void *v) 42 + { 43 + struct mlx5_esw_bridge_fdb_entry *entry; 44 + u64 packets, bytes, lastuse; 45 + 46 + if (v == SEQ_START_TOKEN) { 47 + seq_printf(seq, "%-16s %-17s %4s %20s %20s %20s %5s\n", 48 + "DEV", "MAC", "VLAN", "PACKETS", "BYTES", "LASTUSE", "FLAGS"); 49 + return 0; 50 + } 51 + 52 + entry = list_entry(v, struct mlx5_esw_bridge_fdb_entry, list); 53 + mlx5_fc_query_cached_raw(entry->ingress_counter, &bytes, &packets, &lastuse); 54 + seq_printf(seq, "%-16s %-17pM %4d %20llu %20llu %20llu %#5x\n", 55 + entry->dev->name, entry->key.addr, entry->key.vid, packets, bytes, lastuse, 56 + entry->flags); 57 + return 0; 58 + } 59 + 60 + void mlx5_esw_bridge_debugfs_init(struct net_device *br_netdev, struct mlx5_esw_bridge *bridge) 61 + { 62 + if (!bridge->br_offloads->debugfs_root) 63 + return; 64 + 65 + bridge->debugfs_dir = debugfs_create_dir(br_netdev->name, 66 + bridge->br_offloads->debugfs_root); 67 + debugfs_create_file("fdb", 0444, bridge->debugfs_dir, bridge, 68 + &mlx5_esw_bridge_debugfs_fops); 69 + } 70 + 71 + void mlx5_esw_bridge_debugfs_cleanup(struct mlx5_esw_bridge *bridge) 72 + { 73 + debugfs_remove_recursive(bridge->debugfs_dir); 74 + bridge->debugfs_dir = NULL; 75 + } 76 + 77 + void mlx5_esw_bridge_debugfs_offloads_init(struct mlx5_esw_bridge_offloads *br_offloads) 78 + { 79 + if (!br_offloads->esw->debugfs_root) 80 + return; 81 + 82 + br_offloads->debugfs_root = debugfs_create_dir("bridge", br_offloads->esw->debugfs_root); 83 + } 84 + 85 + void mlx5_esw_bridge_debugfs_offloads_cleanup(struct mlx5_esw_bridge_offloads *br_offloads) 86 + { 87 + debugfs_remove_recursive(br_offloads->debugfs_root); 88 + br_offloads->debugfs_root = NULL; 89 + }
+6
drivers/net/ethernet/mellanox/mlx5/core/esw/bridge_priv.h
··· 199 199 int refcnt; 200 200 struct list_head list; 201 201 struct mlx5_esw_bridge_offloads *br_offloads; 202 + struct dentry *debugfs_dir; 202 203 203 204 struct list_head fdb_list; 204 205 struct rhashtable fdb_ht; ··· 241 240 void mlx5_esw_bridge_port_mdb_vlan_flush(struct mlx5_esw_bridge_port *port, 242 241 struct mlx5_esw_bridge_vlan *vlan); 243 242 void mlx5_esw_bridge_mdb_flush(struct mlx5_esw_bridge *bridge); 243 + 244 + void mlx5_esw_bridge_debugfs_offloads_init(struct mlx5_esw_bridge_offloads *br_offloads); 245 + void mlx5_esw_bridge_debugfs_offloads_cleanup(struct mlx5_esw_bridge_offloads *br_offloads); 246 + void mlx5_esw_bridge_debugfs_init(struct net_device *br_netdev, struct mlx5_esw_bridge *bridge); 247 + void mlx5_esw_bridge_debugfs_cleanup(struct mlx5_esw_bridge *bridge); 244 248 245 249 #endif /* _MLX5_ESW_BRIDGE_PRIVATE_ */
+2 -4
drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c
··· 285 285 if (IS_ERR(flow_rule)) { 286 286 err = PTR_ERR(flow_rule); 287 287 goto out; 288 - } else { 289 - esw->fdb_table.legacy.vepa_uplink_rule = flow_rule; 290 288 } 289 + esw->fdb_table.legacy.vepa_uplink_rule = flow_rule; 291 290 292 291 /* Star rule to forward all traffic to uplink vport */ 293 292 memset(&dest, 0, sizeof(dest)); ··· 298 299 if (IS_ERR(flow_rule)) { 299 300 err = PTR_ERR(flow_rule); 300 301 goto out; 301 - } else { 302 - esw->fdb_table.legacy.vepa_star_rule = flow_rule; 303 302 } 303 + esw->fdb_table.legacy.vepa_star_rule = flow_rule; 304 304 305 305 out: 306 306 kvfree(spec);
+4
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
··· 31 31 */ 32 32 33 33 #include <linux/etherdevice.h> 34 + #include <linux/debugfs.h> 34 35 #include <linux/mlx5/driver.h> 35 36 #include <linux/mlx5/mlx5_ifc.h> 36 37 #include <linux/mlx5/vport.h> ··· 1766 1765 esw->manager_vport = mlx5_eswitch_manager_vport(dev); 1767 1766 esw->first_host_vport = mlx5_eswitch_first_host_vport_num(dev); 1768 1767 1768 + esw->debugfs_root = debugfs_create_dir("esw", mlx5_debugfs_get_dev_root(dev)); 1769 1769 esw->work_queue = create_singlethread_workqueue("mlx5_esw_wq"); 1770 1770 if (!esw->work_queue) { 1771 1771 err = -ENOMEM; ··· 1820 1818 abort: 1821 1819 if (esw->work_queue) 1822 1820 destroy_workqueue(esw->work_queue); 1821 + debugfs_remove_recursive(esw->debugfs_root); 1823 1822 kfree(esw); 1824 1823 unregister_param: 1825 1824 devl_params_unregister(priv_to_devlink(dev), mlx5_eswitch_params, ··· 1847 1844 mutex_destroy(&esw->offloads.decap_tbl_lock); 1848 1845 esw_offloads_cleanup(esw); 1849 1846 mlx5_esw_vports_cleanup(esw); 1847 + debugfs_remove_recursive(esw->debugfs_root); 1850 1848 kfree(esw); 1851 1849 devl_params_unregister(priv_to_devlink(esw->dev), mlx5_eswitch_params, 1852 1850 ARRAY_SIZE(mlx5_eswitch_params));
+4
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
··· 304 304 MLX5_ESW_FDB_CREATED = BIT(0), 305 305 }; 306 306 307 + struct dentry; 308 + 307 309 struct mlx5_eswitch { 308 310 struct mlx5_core_dev *dev; 309 311 struct mlx5_nb nb; ··· 314 312 struct hlist_head mc_table[MLX5_L2_ADDR_HASH_SIZE]; 315 313 struct esw_mc_addr mc_promisc; 316 314 /* end of legacy */ 315 + struct dentry *debugfs_root; 317 316 struct workqueue_struct *work_queue; 318 317 struct xarray vports; 319 318 u32 flags; ··· 668 665 index, \ 669 666 vport, \ 670 667 MLX5_CAP_GEN_2((esw->dev), ec_vf_vport_base), \ 668 + MLX5_CAP_GEN_2((esw->dev), ec_vf_vport_base) +\ 671 669 (last) - 1) 672 670 673 671 struct mlx5_eswitch *mlx5_devlink_eswitch_get(struct devlink *devlink);
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/events.c
··· 5 5 6 6 #include "mlx5_core.h" 7 7 #include "lib/eq.h" 8 - #include "lib/mlx5.h" 8 + #include "lib/events.h" 9 9 10 10 struct mlx5_event_nb { 11 11 struct mlx5_nb nb;
+142 -18
drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
··· 21 21 struct workqueue_struct *wq; 22 22 struct work_struct fw_live_patch_work; 23 23 struct work_struct reset_request_work; 24 + struct work_struct reset_unload_work; 24 25 struct work_struct reset_reload_work; 25 26 struct work_struct reset_now_work; 26 27 struct work_struct reset_abort_work; ··· 30 29 struct completion done; 31 30 int ret; 32 31 }; 32 + 33 + enum { 34 + MLX5_FW_RST_STATE_IDLE = 0, 35 + MLX5_FW_RST_STATE_TOGGLE_REQ = 4, 36 + }; 37 + 38 + enum { 39 + MLX5_RST_STATE_BIT_NUM = 12, 40 + MLX5_RST_ACK_BIT_NUM = 22, 41 + }; 42 + 43 + static u8 mlx5_get_fw_rst_state(struct mlx5_core_dev *dev) 44 + { 45 + return (ioread32be(&dev->iseg->initializing) >> MLX5_RST_STATE_BIT_NUM) & 0xF; 46 + } 47 + 48 + static void mlx5_set_fw_rst_ack(struct mlx5_core_dev *dev) 49 + { 50 + iowrite32be(BIT(MLX5_RST_ACK_BIT_NUM), &dev->iseg->initializing); 51 + } 33 52 34 53 static int mlx5_fw_reset_enable_remote_dev_reset_set(struct devlink *devlink, u32 id, 35 54 struct devlink_param_gset_ctx *ctx) ··· 176 155 return mlx5_reg_mfrl_set(dev, MLX5_MFRL_REG_RESET_LEVEL0, 0, 0, false); 177 156 } 178 157 179 - static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev) 158 + static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unloaded) 180 159 { 181 160 struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset; 182 161 ··· 184 163 if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) { 185 164 complete(&fw_reset->done); 186 165 } else { 187 - mlx5_unload_one(dev, false); 166 + if (!unloaded) 167 + mlx5_unload_one(dev, false); 188 168 if (mlx5_health_wait_pci_up(dev)) 189 169 mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n"); 190 170 else ··· 226 204 227 205 mlx5_sync_reset_clear_reset_requested(dev, false); 228 206 mlx5_enter_error_state(dev, true); 229 - mlx5_fw_reset_complete_reload(dev); 207 + mlx5_fw_reset_complete_reload(dev, false); 230 208 } 231 209 232 210 #define MLX5_RESET_POLL_INTERVAL (HZ / 10) ··· 298 276 mlx5_core_err(dev, "Failed to reload FW tracer\n"); 299 277 } 300 278 279 + static int mlx5_check_dev_ids(struct mlx5_core_dev *dev, u16 dev_id) 280 + { 281 + struct pci_bus *bridge_bus = dev->pdev->bus; 282 + struct pci_dev *sdev; 283 + u16 sdev_id; 284 + int err; 285 + 286 + /* Check that all functions under the pci bridge are PFs of 287 + * this device otherwise fail this function. 288 + */ 289 + list_for_each_entry(sdev, &bridge_bus->devices, bus_list) { 290 + err = pci_read_config_word(sdev, PCI_DEVICE_ID, &sdev_id); 291 + if (err) 292 + return err; 293 + if (sdev_id != dev_id) { 294 + mlx5_core_warn(dev, "unrecognized dev_id (0x%x)\n", sdev_id); 295 + return -EPERM; 296 + } 297 + } 298 + return 0; 299 + } 300 + 301 + static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev) 302 + { 303 + u16 dev_id; 304 + int err; 305 + 306 + if (!MLX5_CAP_GEN(dev, fast_teardown)) { 307 + mlx5_core_warn(dev, "fast teardown is not supported by firmware\n"); 308 + return -EOPNOTSUPP; 309 + } 310 + 311 + err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &dev_id); 312 + if (err) 313 + return false; 314 + return (!mlx5_check_dev_ids(dev, dev_id)); 315 + } 316 + 301 317 static void mlx5_sync_reset_request_event(struct work_struct *work) 302 318 { 303 319 struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset, ··· 343 283 struct mlx5_core_dev *dev = fw_reset->dev; 344 284 int err; 345 285 346 - if (test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags)) { 286 + if (test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags) || 287 + !mlx5_is_reset_now_capable(dev)) { 347 288 err = mlx5_fw_reset_set_reset_sync_nack(dev); 348 289 mlx5_core_warn(dev, "PCI Sync FW Update Reset Nack %s", 349 290 err ? "Failed" : "Sent"); ··· 364 303 { 365 304 struct pci_bus *bridge_bus = dev->pdev->bus; 366 305 struct pci_dev *bridge = bridge_bus->self; 367 - u16 reg16, dev_id, sdev_id; 368 306 unsigned long timeout; 369 307 struct pci_dev *sdev; 308 + u16 reg16, dev_id; 370 309 int cap, err; 371 310 u32 reg32; 372 311 373 - /* Check that all functions under the pci bridge are PFs of 374 - * this device otherwise fail this function. 375 - */ 376 312 err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &dev_id); 377 313 if (err) 378 314 return err; 379 - list_for_each_entry(sdev, &bridge_bus->devices, bus_list) { 380 - err = pci_read_config_word(sdev, PCI_DEVICE_ID, &sdev_id); 381 - if (err) 382 - return err; 383 - if (sdev_id != dev_id) 384 - return -EPERM; 385 - } 386 - 315 + err = mlx5_check_dev_ids(dev, dev_id); 316 + if (err) 317 + return err; 387 318 cap = pci_find_capability(bridge, PCI_CAP_ID_EXP); 388 319 if (!cap) 389 320 return -EOPNOTSUPP; ··· 480 427 mlx5_enter_error_state(dev, true); 481 428 done: 482 429 fw_reset->ret = err; 483 - mlx5_fw_reset_complete_reload(dev); 430 + mlx5_fw_reset_complete_reload(dev, false); 431 + } 432 + 433 + static void mlx5_sync_reset_unload_event(struct work_struct *work) 434 + { 435 + struct mlx5_fw_reset *fw_reset; 436 + struct mlx5_core_dev *dev; 437 + unsigned long timeout; 438 + bool reset_action; 439 + u8 rst_state; 440 + int err; 441 + 442 + fw_reset = container_of(work, struct mlx5_fw_reset, reset_unload_work); 443 + dev = fw_reset->dev; 444 + 445 + if (mlx5_sync_reset_clear_reset_requested(dev, false)) 446 + return; 447 + 448 + mlx5_core_warn(dev, "Sync Reset Unload. Function is forced down.\n"); 449 + 450 + err = mlx5_cmd_fast_teardown_hca(dev); 451 + if (err) 452 + mlx5_core_warn(dev, "Fast teardown failed, unloading, err %d\n", err); 453 + else 454 + mlx5_enter_error_state(dev, true); 455 + 456 + if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) 457 + mlx5_unload_one_devl_locked(dev, false); 458 + else 459 + mlx5_unload_one(dev, false); 460 + 461 + mlx5_set_fw_rst_ack(dev); 462 + mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n"); 463 + 464 + reset_action = false; 465 + timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD)); 466 + do { 467 + rst_state = mlx5_get_fw_rst_state(dev); 468 + if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ || 469 + rst_state == MLX5_FW_RST_STATE_IDLE) { 470 + reset_action = true; 471 + break; 472 + } 473 + msleep(20); 474 + } while (!time_after(jiffies, timeout)); 475 + 476 + if (!reset_action) { 477 + mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n", 478 + rst_state); 479 + fw_reset->ret = -ETIMEDOUT; 480 + goto done; 481 + } 482 + 483 + mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n", rst_state); 484 + if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) { 485 + err = mlx5_pci_link_toggle(dev); 486 + if (err) { 487 + mlx5_core_warn(dev, "mlx5_pci_link_toggle failed, err %d\n", err); 488 + fw_reset->ret = err; 489 + } 490 + } 491 + 492 + done: 493 + mlx5_fw_reset_complete_reload(dev, true); 484 494 } 485 495 486 496 static void mlx5_sync_reset_abort_event(struct work_struct *work) ··· 567 451 switch (sync_event_rst_type) { 568 452 case MLX5_SYNC_RST_STATE_RESET_REQUEST: 569 453 queue_work(fw_reset->wq, &fw_reset->reset_request_work); 454 + break; 455 + case MLX5_SYNC_RST_STATE_RESET_UNLOAD: 456 + queue_work(fw_reset->wq, &fw_reset->reset_unload_work); 570 457 break; 571 458 case MLX5_SYNC_RST_STATE_RESET_NOW: 572 459 queue_work(fw_reset->wq, &fw_reset->reset_now_work); ··· 605 486 int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev) 606 487 { 607 488 unsigned long pci_sync_update_timeout = mlx5_tout_ms(dev, PCI_SYNC_UPDATE); 608 - unsigned long timeout = msecs_to_jiffies(pci_sync_update_timeout); 609 489 struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset; 490 + unsigned long timeout; 610 491 int err; 611 492 493 + if (MLX5_CAP_GEN(dev, pci_sync_for_fw_update_with_driver_unload)) 494 + pci_sync_update_timeout += mlx5_tout_ms(dev, RESET_UNLOAD); 495 + timeout = msecs_to_jiffies(pci_sync_update_timeout); 612 496 if (!wait_for_completion_timeout(&fw_reset->done, timeout)) { 613 497 mlx5_core_warn(dev, "FW sync reset timeout after %lu seconds\n", 614 498 pci_sync_update_timeout / 1000); ··· 648 526 set_bit(MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS, &fw_reset->reset_flags); 649 527 cancel_work_sync(&fw_reset->fw_live_patch_work); 650 528 cancel_work_sync(&fw_reset->reset_request_work); 529 + cancel_work_sync(&fw_reset->reset_unload_work); 651 530 cancel_work_sync(&fw_reset->reset_reload_work); 652 531 cancel_work_sync(&fw_reset->reset_now_work); 653 532 cancel_work_sync(&fw_reset->reset_abort_work); ··· 687 564 688 565 INIT_WORK(&fw_reset->fw_live_patch_work, mlx5_fw_live_patch_event); 689 566 INIT_WORK(&fw_reset->reset_request_work, mlx5_sync_reset_request_event); 567 + INIT_WORK(&fw_reset->reset_unload_work, mlx5_sync_reset_unload_event); 690 568 INIT_WORK(&fw_reset->reset_reload_work, mlx5_sync_reset_reload_work); 691 569 INIT_WORK(&fw_reset->reset_now_work, mlx5_sync_reset_now_event); 692 570 INIT_WORK(&fw_reset->reset_abort_work, mlx5_sync_reset_abort_event);
+1
drivers/net/ethernet/mellanox/mlx5/core/health.c
··· 39 39 #include "mlx5_core.h" 40 40 #include "lib/eq.h" 41 41 #include "lib/mlx5.h" 42 + #include "lib/events.h" 42 43 #include "lib/pci_vsc.h" 43 44 #include "lib/tout.h" 44 45 #include "diag/fw_tracer.h"
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/lag/mp.c
··· 7 7 #include "lag/mp.h" 8 8 #include "mlx5_core.h" 9 9 #include "eswitch.h" 10 - #include "lib/mlx5.h" 10 + #include "lib/events.h" 11 11 12 12 static bool __mlx5_lag_is_multipath(struct mlx5_lag *ldev) 13 13 {
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
··· 6 6 #include "lag/lag.h" 7 7 #include "eswitch.h" 8 8 #include "esw/acl/ofld.h" 9 - #include "lib/mlx5.h" 9 + #include "lib/events.h" 10 10 11 11 static void mlx5_mpesw_metadata_cleanup(struct mlx5_lag *ldev) 12 12 {
+40
drivers/net/ethernet/mellanox/mlx5/core/lib/events.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ 2 + /* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ 3 + 4 + #ifndef __LIB_EVENTS_H__ 5 + #define __LIB_EVENTS_H__ 6 + 7 + #include "mlx5_core.h" 8 + 9 + #define PORT_MODULE_EVENT_MODULE_STATUS_MASK 0xF 10 + #define PORT_MODULE_EVENT_ERROR_TYPE_MASK 0xF 11 + 12 + enum port_module_event_status_type { 13 + MLX5_MODULE_STATUS_PLUGGED = 0x1, 14 + MLX5_MODULE_STATUS_UNPLUGGED = 0x2, 15 + MLX5_MODULE_STATUS_ERROR = 0x3, 16 + MLX5_MODULE_STATUS_DISABLED = 0x4, 17 + MLX5_MODULE_STATUS_NUM, 18 + }; 19 + 20 + enum port_module_event_error_type { 21 + MLX5_MODULE_EVENT_ERROR_POWER_BUDGET_EXCEEDED = 0x0, 22 + MLX5_MODULE_EVENT_ERROR_LONG_RANGE_FOR_NON_MLNX = 0x1, 23 + MLX5_MODULE_EVENT_ERROR_BUS_STUCK = 0x2, 24 + MLX5_MODULE_EVENT_ERROR_NO_EEPROM_RETRY_TIMEOUT = 0x3, 25 + MLX5_MODULE_EVENT_ERROR_ENFORCE_PART_NUMBER_LIST = 0x4, 26 + MLX5_MODULE_EVENT_ERROR_UNKNOWN_IDENTIFIER = 0x5, 27 + MLX5_MODULE_EVENT_ERROR_HIGH_TEMPERATURE = 0x6, 28 + MLX5_MODULE_EVENT_ERROR_BAD_CABLE = 0x7, 29 + MLX5_MODULE_EVENT_ERROR_PCIE_POWER_SLOT_EXCEEDED = 0xc, 30 + MLX5_MODULE_EVENT_ERROR_NUM, 31 + }; 32 + 33 + struct mlx5_pme_stats { 34 + u64 status_counters[MLX5_MODULE_STATUS_NUM]; 35 + u64 error_counters[MLX5_MODULE_EVENT_ERROR_NUM]; 36 + }; 37 + 38 + void mlx5_get_pme_stats(struct mlx5_core_dev *dev, struct mlx5_pme_stats *stats); 39 + int mlx5_notifier_call_chain(struct mlx5_events *events, unsigned int event, void *data); 40 + #endif
-34
drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h
··· 45 45 void mlx5_crdump_disable(struct mlx5_core_dev *dev); 46 46 int mlx5_crdump_collect(struct mlx5_core_dev *dev, u32 *cr_data); 47 47 48 - /* TODO move to lib/events.h */ 49 - 50 - #define PORT_MODULE_EVENT_MODULE_STATUS_MASK 0xF 51 - #define PORT_MODULE_EVENT_ERROR_TYPE_MASK 0xF 52 - 53 - enum port_module_event_status_type { 54 - MLX5_MODULE_STATUS_PLUGGED = 0x1, 55 - MLX5_MODULE_STATUS_UNPLUGGED = 0x2, 56 - MLX5_MODULE_STATUS_ERROR = 0x3, 57 - MLX5_MODULE_STATUS_DISABLED = 0x4, 58 - MLX5_MODULE_STATUS_NUM, 59 - }; 60 - 61 - enum port_module_event_error_type { 62 - MLX5_MODULE_EVENT_ERROR_POWER_BUDGET_EXCEEDED = 0x0, 63 - MLX5_MODULE_EVENT_ERROR_LONG_RANGE_FOR_NON_MLNX = 0x1, 64 - MLX5_MODULE_EVENT_ERROR_BUS_STUCK = 0x2, 65 - MLX5_MODULE_EVENT_ERROR_NO_EEPROM_RETRY_TIMEOUT = 0x3, 66 - MLX5_MODULE_EVENT_ERROR_ENFORCE_PART_NUMBER_LIST = 0x4, 67 - MLX5_MODULE_EVENT_ERROR_UNKNOWN_IDENTIFIER = 0x5, 68 - MLX5_MODULE_EVENT_ERROR_HIGH_TEMPERATURE = 0x6, 69 - MLX5_MODULE_EVENT_ERROR_BAD_CABLE = 0x7, 70 - MLX5_MODULE_EVENT_ERROR_PCIE_POWER_SLOT_EXCEEDED = 0xc, 71 - MLX5_MODULE_EVENT_ERROR_NUM, 72 - }; 73 - 74 - struct mlx5_pme_stats { 75 - u64 status_counters[MLX5_MODULE_STATUS_NUM]; 76 - u64 error_counters[MLX5_MODULE_EVENT_ERROR_NUM]; 77 - }; 78 - 79 - void mlx5_get_pme_stats(struct mlx5_core_dev *dev, struct mlx5_pme_stats *stats); 80 - int mlx5_notifier_call_chain(struct mlx5_events *events, unsigned int event, void *data); 81 - 82 48 static inline struct net *mlx5_core_net(struct mlx5_core_dev *dev) 83 49 { 84 50 return devlink_net(priv_to_devlink(dev));
+5 -2
drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c
··· 24 24 [MLX5_TO_TEARDOWN_MS] = 3000, 25 25 [MLX5_TO_FSM_REACTIVATE_MS] = 5000, 26 26 [MLX5_TO_RECLAIM_PAGES_MS] = 5000, 27 - [MLX5_TO_RECLAIM_VFS_PAGES_MS] = 120000 27 + [MLX5_TO_RECLAIM_VFS_PAGES_MS] = 120000, 28 + [MLX5_TO_RESET_UNLOAD_MS] = 300000 28 29 }; 29 30 30 31 static void tout_set(struct mlx5_core_dev *dev, u64 val, enum mlx5_timeouts_types type) ··· 119 118 #define MLX5_TIMEOUT_FILL(fld, reg_out, dev, to_type, to_extra) \ 120 119 ({ \ 121 120 u64 fw_to = MLX5_TIMEOUT_QUERY(fld, reg_out); \ 122 - tout_set(dev, fw_to + (to_extra), to_type); \ 121 + if (fw_to) \ 122 + tout_set(dev, fw_to + (to_extra), to_type); \ 123 123 fw_to; \ 124 124 }) 125 125 ··· 148 146 MLX5_TIMEOUT_FILL(fsm_reactivate_to, out, dev, MLX5_TO_FSM_REACTIVATE_MS, 0); 149 147 MLX5_TIMEOUT_FILL(reclaim_pages_to, out, dev, MLX5_TO_RECLAIM_PAGES_MS, 0); 150 148 MLX5_TIMEOUT_FILL(reclaim_vfs_pages_to, out, dev, MLX5_TO_RECLAIM_VFS_PAGES_MS, 0); 149 + MLX5_TIMEOUT_FILL(reset_unload_to, out, dev, MLX5_TO_RESET_UNLOAD_MS, 0); 151 150 152 151 return 0; 153 152 }
+1
drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h
··· 26 26 MLX5_TO_FSM_REACTIVATE_MS, 27 27 MLX5_TO_RECLAIM_PAGES_MS, 28 28 MLX5_TO_RECLAIM_VFS_PAGES_MS, 29 + MLX5_TO_RESET_UNLOAD_MS, 29 30 30 31 MAX_TIMEOUT_TYPES 31 32 };
+3
drivers/net/ethernet/mellanox/mlx5/core/main.c
··· 619 619 620 620 if (MLX5_CAP_GEN_MAX(dev, pci_sync_for_fw_update_event)) 621 621 MLX5_SET(cmd_hca_cap, set_hca_cap, pci_sync_for_fw_update_event, 1); 622 + if (MLX5_CAP_GEN_MAX(dev, pci_sync_for_fw_update_with_driver_unload)) 623 + MLX5_SET(cmd_hca_cap, set_hca_cap, 624 + pci_sync_for_fw_update_with_driver_unload, 1); 622 625 623 626 if (MLX5_CAP_GEN_MAX(dev, num_vhca_ports)) 624 627 MLX5_SET(cmd_hca_cap,
+7
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
··· 358 358 359 359 return (vport_num >= base_vport && vport_num < max_vport); 360 360 } 361 + 362 + static inline int mlx5_vport_to_func_id(const struct mlx5_core_dev *dev, u16 vport, bool ec_vf_func) 363 + { 364 + return ec_vf_func ? vport - mlx5_core_ec_vf_vport_base(dev) 365 + : vport; 366 + } 367 + 361 368 #endif /* __MLX5_CORE_H__ */
-1
drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
··· 28 28 struct mutex sf_state_lock; /* Serializes sf state among user cmds & vhca event handler. */ 29 29 struct notifier_block esw_nb; 30 30 struct notifier_block vhca_nb; 31 - u8 ecpu: 1; 32 31 }; 33 32 34 33 static struct mlx5_sf *
+3 -1
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c
··· 34 34 int mlx5dr_cmd_query_gvmi(struct mlx5_core_dev *mdev, bool other_vport, 35 35 u16 vport_number, u16 *gvmi) 36 36 { 37 + bool ec_vf_func = other_vport ? mlx5_core_is_ec_vf_vport(mdev, vport_number) : false; 37 38 u32 in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {}; 38 39 int out_size; 39 40 void *out; ··· 47 46 48 47 MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); 49 48 MLX5_SET(query_hca_cap_in, in, other_function, other_vport); 50 - MLX5_SET(query_hca_cap_in, in, function_id, vport_number); 49 + MLX5_SET(query_hca_cap_in, in, function_id, mlx5_vport_to_func_id(mdev, vport_number, ec_vf_func)); 50 + MLX5_SET(query_hca_cap_in, in, ec_vf_function, ec_vf_func); 51 51 MLX5_SET(query_hca_cap_in, in, op_mod, 52 52 MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE << 1 | 53 53 HCA_CAP_OPMOD_GET_CUR);
-6
drivers/net/ethernet/mellanox/mlx5/core/vport.c
··· 1161 1161 } 1162 1162 EXPORT_SYMBOL_GPL(mlx5_query_nic_system_image_guid); 1163 1163 1164 - static int mlx5_vport_to_func_id(const struct mlx5_core_dev *dev, u16 vport, bool ec_vf_func) 1165 - { 1166 - return ec_vf_func ? vport - mlx5_core_ec_vf_vport_base(dev) 1167 - : vport; 1168 - } 1169 - 1170 1164 int mlx5_vport_get_other_func_cap(struct mlx5_core_dev *dev, u16 vport, void *out, 1171 1165 u16 opmod) 1172 1166 {
+1
include/linux/mlx5/device.h
··· 716 716 MLX5_SYNC_RST_STATE_RESET_REQUEST = 0x0, 717 717 MLX5_SYNC_RST_STATE_RESET_NOW = 0x1, 718 718 MLX5_SYNC_RST_STATE_RESET_ABORT = 0x2, 719 + MLX5_SYNC_RST_STATE_RESET_UNLOAD = 0x3, 719 720 }; 720 721 721 722 struct mlx5_eqe_sync_fw_update {
+9 -4
include/linux/mlx5/mlx5_ifc.h
··· 1755 1755 u8 reserved_at_328[0x2]; 1756 1756 u8 relaxed_ordering_read[0x1]; 1757 1757 u8 log_max_pd[0x5]; 1758 - u8 reserved_at_330[0x7]; 1758 + u8 reserved_at_330[0x6]; 1759 + u8 pci_sync_for_fw_update_with_driver_unload[0x1]; 1759 1760 u8 vnic_env_cnt_steering_fail[0x1]; 1760 - u8 reserved_at_338[0x1]; 1761 + u8 vport_counter_local_loopback[0x1]; 1761 1762 u8 q_counter_aggregation[0x1]; 1762 1763 u8 q_counter_other_vport[0x1]; 1763 1764 u8 log_max_xrcd[0x5]; ··· 3118 3117 3119 3118 struct mlx5_ifc_default_timeout_bits reclaim_vfs_pages_to; 3120 3119 3121 - u8 reserved_at_1c0[0x40]; 3120 + struct mlx5_ifc_default_timeout_bits reset_unload_to; 3121 + 3122 + u8 reserved_at_1c0[0x20]; 3122 3123 }; 3123 3124 3124 3125 enum { ··· 5190 5187 5191 5188 struct mlx5_ifc_traffic_counter_bits transmitted_eth_multicast; 5192 5189 5193 - u8 reserved_at_680[0xa00]; 5190 + struct mlx5_ifc_traffic_counter_bits local_loopback; 5191 + 5192 + u8 reserved_at_700[0x980]; 5194 5193 }; 5195 5194 5196 5195 enum {