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

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

Saeed Mahameed says:

====================
mlx5-updates-2023-02-10

1) From Roi and Mark: MultiPort eswitch support

MultiPort E-Switch builds on newer hardware's capabilities and introduces
a mode where a single E-Switch is used and all the vports and physical
ports on the NIC are connected to it.

The new mode will allow in the future a decrease in the memory used by the
driver and advanced features that aren't possible today.

This represents a big change in the current E-Switch implantation in mlx5.
Currently, by default, each E-Switch manager manages its E-Switch.
Steering rules in each E-Switch can only forward traffic to the native
physical port associated with that E-Switch. While there are ways to target
non-native physical ports, for example using a bond or via special TC
rules. None of the ways allows a user to configure the driver
to operate by default in such a mode nor can the driver decide
to move to this mode by default as it's user configuration-driven right now.

While MultiPort E-Switch single FDB mode is the preferred mode, older
generations of ConnectX hardware couldn't support this mode so it was never
implemented. Now that there is capable hardware present, start the
transition to having this mode by default.

Introduce a devlink parameter to control MultiPort Eswitch single FDB mode.
This will allow users to select this mode on their system right now
and in the future will allow the driver to move to this mode by default.

2) From Jiri: Improvements and fixes for mlx5 netdev's devlink logic
2.1) Cleanups related to mlx5's devlink port logic
2.2) Move devlink port registration to be done before netdev alloc
2.3) Create auxdev devlink instance in the same ns as parent devlink
2.4) Suspend auxiliary devices only in case of PCI device suspend

* tag 'mlx5-updates-2023-02-10' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux:
net/mlx5: Suspend auxiliary devices only in case of PCI device suspend
net/mlx5: Remove "recovery" arg from mlx5_load_one() function
net/mlx5e: Create auxdev devlink instance in the same ns as parent devlink
net/mlx5e: Move devlink port registration to be done before netdev alloc
net/mlx5e: Move dl_port to struct mlx5e_dev
net/mlx5e: Replace usage of mlx5e_devlink_get_dl_port() by netdev->devlink_port
net/mlx5e: Pass mdev to mlx5e_devlink_port_register()
net/mlx5: Remove outdated comment
net/mlx5e: TC, Remove redundant parse_attr argument
net/mlx5e: Use a simpler comparison for uplink rep
net/mlx5: Lag, Add single RDMA device in multiport mode
net/mlx5: Lag, set different uplink vport metadata in multiport eswitch mode
net/mlx5: E-Switch, rename bond update function to be reused
net/mlx5e: TC, Add peer flow in mpesw mode
net/mlx5: Lag, Control MultiPort E-Switch single FDB mode
====================

Link: https://lore.kernel.org/r/20230214221239.159033-1-saeed@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+337 -185
+18
Documentation/networking/devlink/mlx5.rst
··· 54 54 - Control the number of large groups (size > 1) in the FDB table. 55 55 56 56 * The default value is 15, and the range is between 1 and 1024. 57 + * - ``esw_multiport`` 58 + - Boolean 59 + - runtime 60 + - Control MultiPort E-Switch shared fdb mode. 61 + 62 + An experimental mode where a single E-Switch is used and all the vports 63 + and physical ports on the NIC are connected to it. 64 + 65 + An example is to send traffic from a VF that is created on PF0 to an 66 + uplink that is natively associated with the uplink of PF1 67 + 68 + Note: Future devices, ConnectX-8 and onward, will eventually have this 69 + as the default to allow forwarding between all NIC ports in a single 70 + E-switch environment and the dual E-switch mode will likely get 71 + deprecated. 72 + 73 + Default: disabled 74 + 57 75 58 76 The ``mlx5`` driver supports reloading via ``DEVLINK_CMD_RELOAD`` 59 77
+13 -5
drivers/infiniband/hw/mlx5/ib_rep.c
··· 37 37 const struct mlx5_ib_profile *profile; 38 38 struct mlx5_core_dev *peer_dev; 39 39 struct mlx5_ib_dev *ibdev; 40 + int second_uplink = false; 40 41 u32 peer_num_ports; 41 42 int vport_index; 42 43 int ret; ··· 48 47 peer_dev = mlx5_lag_get_peer_mdev(dev); 49 48 peer_num_ports = mlx5_eswitch_get_total_vports(peer_dev); 50 49 if (mlx5_lag_is_master(dev)) { 51 - /* Only 1 ib port is the representor for both uplinks */ 52 - num_ports += peer_num_ports - 1; 50 + if (mlx5_lag_is_mpesw(dev)) 51 + num_ports += peer_num_ports; 52 + else 53 + num_ports += peer_num_ports - 1; 54 + 53 55 } else { 54 - if (rep->vport == MLX5_VPORT_UPLINK) 55 - return 0; 56 + if (rep->vport == MLX5_VPORT_UPLINK) { 57 + if (!mlx5_lag_is_mpesw(dev)) 58 + return 0; 59 + second_uplink = true; 60 + } 61 + 56 62 vport_index += peer_num_ports; 57 63 dev = peer_dev; 58 64 } 59 65 } 60 66 61 - if (rep->vport == MLX5_VPORT_UPLINK) 67 + if (rep->vport == MLX5_VPORT_UPLINK && !second_uplink) 62 68 profile = &raw_eth_profile; 63 69 else 64 70 return mlx5_ib_set_vport_rep(dev, rep, vport_index);
+2 -6
drivers/net/ethernet/mellanox/mlx5/core/dev.c
··· 377 377 378 378 /* Pay attention that this is not PCI driver that 379 379 * mlx5_core_dev is connected, but auxiliary driver. 380 - * 381 - * Here we can race of module unload with devlink 382 - * reload, but we don't need to take extra lock because 383 - * we are holding global mlx5_intf_mutex. 384 380 */ 385 381 if (!adev->dev.driver) 386 382 continue; ··· 396 400 return ret; 397 401 } 398 402 399 - void mlx5_detach_device(struct mlx5_core_dev *dev) 403 + void mlx5_detach_device(struct mlx5_core_dev *dev, bool suspend) 400 404 { 401 405 struct mlx5_priv *priv = &dev->priv; 402 406 struct auxiliary_device *adev; ··· 425 429 426 430 adrv = to_auxiliary_drv(adev->dev.driver); 427 431 428 - if (adrv->suspend) { 432 + if (adrv->suspend && suspend) { 429 433 adrv->suspend(adev, pm); 430 434 continue; 431 435 }
+56 -2
drivers/net/ethernet/mellanox/mlx5/core/devlink.c
··· 7 7 #include "fw_reset.h" 8 8 #include "fs_core.h" 9 9 #include "eswitch.h" 10 + #include "lag/lag.h" 10 11 #include "esw/qos.h" 11 12 #include "sf/dev/dev.h" 12 13 #include "sf/sf.h" ··· 105 104 if (err) 106 105 return err; 107 106 108 - mlx5_unload_one_devl_locked(dev); 107 + mlx5_unload_one_devl_locked(dev, true); 109 108 err = mlx5_health_wait_pci_up(dev); 110 109 if (err) 111 110 NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset"); ··· 168 167 169 168 switch (action) { 170 169 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: 171 - mlx5_unload_one_devl_locked(dev); 170 + mlx5_unload_one_devl_locked(dev, false); 172 171 break; 173 172 case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: 174 173 if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET) ··· 438 437 return 0; 439 438 } 440 439 440 + static int mlx5_devlink_esw_multiport_set(struct devlink *devlink, u32 id, 441 + struct devlink_param_gset_ctx *ctx) 442 + { 443 + struct mlx5_core_dev *dev = devlink_priv(devlink); 444 + 445 + if (!MLX5_ESWITCH_MANAGER(dev)) 446 + return -EOPNOTSUPP; 447 + 448 + if (ctx->val.vbool) 449 + return mlx5_lag_mpesw_enable(dev); 450 + 451 + mlx5_lag_mpesw_disable(dev); 452 + return 0; 453 + } 454 + 455 + static int mlx5_devlink_esw_multiport_get(struct devlink *devlink, u32 id, 456 + struct devlink_param_gset_ctx *ctx) 457 + { 458 + struct mlx5_core_dev *dev = devlink_priv(devlink); 459 + 460 + if (!MLX5_ESWITCH_MANAGER(dev)) 461 + return -EOPNOTSUPP; 462 + 463 + ctx->val.vbool = mlx5_lag_is_mpesw(dev); 464 + return 0; 465 + } 466 + 467 + static int mlx5_devlink_esw_multiport_validate(struct devlink *devlink, u32 id, 468 + union devlink_param_value val, 469 + struct netlink_ext_ack *extack) 470 + { 471 + struct mlx5_core_dev *dev = devlink_priv(devlink); 472 + 473 + if (!MLX5_ESWITCH_MANAGER(dev)) { 474 + NL_SET_ERR_MSG_MOD(extack, "E-Switch is unsupported"); 475 + return -EOPNOTSUPP; 476 + } 477 + 478 + if (mlx5_eswitch_mode(dev) != MLX5_ESWITCH_OFFLOADS) { 479 + NL_SET_ERR_MSG_MOD(extack, 480 + "E-Switch must be in switchdev mode"); 481 + return -EBUSY; 482 + } 483 + 484 + return 0; 485 + } 486 + 441 487 #endif 442 488 443 489 static int mlx5_devlink_eq_depth_validate(struct devlink *devlink, u32 id, ··· 503 455 BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), 504 456 NULL, NULL, 505 457 mlx5_devlink_large_group_num_validate), 458 + DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_ID_ESW_MULTIPORT, 459 + "esw_multiport", DEVLINK_PARAM_TYPE_BOOL, 460 + BIT(DEVLINK_PARAM_CMODE_RUNTIME), 461 + mlx5_devlink_esw_multiport_get, 462 + mlx5_devlink_esw_multiport_set, 463 + mlx5_devlink_esw_multiport_validate), 506 464 #endif 507 465 DEVLINK_PARAM_GENERIC(IO_EQ_SIZE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), 508 466 NULL, NULL, mlx5_devlink_eq_depth_validate),
+1
drivers/net/ethernet/mellanox/mlx5/core/devlink.h
··· 11 11 MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE, 12 12 MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM, 13 13 MLX5_DEVLINK_PARAM_ID_ESW_PORT_METADATA, 14 + MLX5_DEVLINK_PARAM_ID_ESW_MULTIPORT, 14 15 }; 15 16 16 17 struct mlx5_trap_ctx {
+1
drivers/net/ethernet/mellanox/mlx5/core/en.h
··· 975 975 976 976 struct mlx5e_dev { 977 977 struct mlx5e_priv *priv; 978 + struct devlink_port dl_port; 978 979 }; 979 980 980 981 struct mlx5e_rx_handlers {
+16 -18
drivers/net/ethernet/mellanox/mlx5/core/en/devlink.c
··· 7 7 static const struct devlink_ops mlx5e_devlink_ops = { 8 8 }; 9 9 10 - struct mlx5e_dev *mlx5e_create_devlink(struct device *dev) 10 + struct mlx5e_dev *mlx5e_create_devlink(struct device *dev, 11 + struct mlx5_core_dev *mdev) 11 12 { 12 13 struct mlx5e_dev *mlx5e_dev; 13 14 struct devlink *devlink; 14 15 15 - devlink = devlink_alloc(&mlx5e_devlink_ops, sizeof(*mlx5e_dev), dev); 16 + devlink = devlink_alloc_ns(&mlx5e_devlink_ops, sizeof(*mlx5e_dev), 17 + devlink_net(priv_to_devlink(mdev)), dev); 16 18 if (!devlink) 17 19 return ERR_PTR(-ENOMEM); 18 20 devlink_register(devlink); ··· 40 38 } 41 39 42 40 int mlx5e_devlink_port_register(struct mlx5e_dev *mlx5e_dev, 43 - struct mlx5e_priv *priv) 41 + struct mlx5_core_dev *mdev) 44 42 { 45 43 struct devlink *devlink = priv_to_devlink(mlx5e_dev); 46 44 struct devlink_port_attrs attrs = {}; 47 45 struct netdev_phys_item_id ppid = {}; 48 - struct devlink_port *dl_port; 49 46 unsigned int dl_port_index; 50 47 51 - if (mlx5_core_is_pf(priv->mdev)) { 48 + if (mlx5_core_is_pf(mdev)) { 52 49 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 53 - attrs.phys.port_number = mlx5_get_dev_index(priv->mdev); 54 - if (MLX5_ESWITCH_MANAGER(priv->mdev)) { 55 - mlx5e_devlink_get_port_parent_id(priv->mdev, &ppid); 50 + attrs.phys.port_number = mlx5_get_dev_index(mdev); 51 + if (MLX5_ESWITCH_MANAGER(mdev)) { 52 + mlx5e_devlink_get_port_parent_id(mdev, &ppid); 56 53 memcpy(attrs.switch_id.id, ppid.id, ppid.id_len); 57 54 attrs.switch_id.id_len = ppid.id_len; 58 55 } 59 - dl_port_index = mlx5_esw_vport_to_devlink_port_index(priv->mdev, 56 + dl_port_index = mlx5_esw_vport_to_devlink_port_index(mdev, 60 57 MLX5_VPORT_UPLINK); 61 58 } else { 62 59 attrs.flavour = DEVLINK_PORT_FLAVOUR_VIRTUAL; 63 - dl_port_index = mlx5_esw_vport_to_devlink_port_index(priv->mdev, 0); 60 + dl_port_index = mlx5_esw_vport_to_devlink_port_index(mdev, 0); 64 61 } 65 62 66 - dl_port = mlx5e_devlink_get_dl_port(priv); 67 - memset(dl_port, 0, sizeof(*dl_port)); 68 - devlink_port_attrs_set(dl_port, &attrs); 63 + devlink_port_attrs_set(&mlx5e_dev->dl_port, &attrs); 69 64 70 - return devlink_port_register(devlink, dl_port, dl_port_index); 65 + return devlink_port_register(devlink, &mlx5e_dev->dl_port, 66 + dl_port_index); 71 67 } 72 68 73 - void mlx5e_devlink_port_unregister(struct mlx5e_priv *priv) 69 + void mlx5e_devlink_port_unregister(struct mlx5e_dev *mlx5e_dev) 74 70 { 75 - struct devlink_port *dl_port = mlx5e_devlink_get_dl_port(priv); 76 - 77 - devlink_port_unregister(dl_port); 71 + devlink_port_unregister(&mlx5e_dev->dl_port); 78 72 }
+4 -9
drivers/net/ethernet/mellanox/mlx5/core/en/devlink.h
··· 7 7 #include <net/devlink.h> 8 8 #include "en.h" 9 9 10 - struct mlx5e_dev *mlx5e_create_devlink(struct device *dev); 10 + struct mlx5e_dev *mlx5e_create_devlink(struct device *dev, 11 + struct mlx5_core_dev *mdev); 11 12 void mlx5e_destroy_devlink(struct mlx5e_dev *mlx5e_dev); 12 13 int mlx5e_devlink_port_register(struct mlx5e_dev *mlx5e_dev, 13 - struct mlx5e_priv *priv); 14 - void mlx5e_devlink_port_unregister(struct mlx5e_priv *priv); 15 - 16 - static inline struct devlink_port * 17 - mlx5e_devlink_get_dl_port(struct mlx5e_priv *priv) 18 - { 19 - return &priv->mdev->mlx5e_res.dl_port; 20 - } 14 + struct mlx5_core_dev *mdev); 15 + void mlx5e_devlink_port_unregister(struct mlx5e_dev *mlx5e_dev); 21 16 22 17 #endif
+3 -3
drivers/net/ethernet/mellanox/mlx5/core/en/rep/bond.c
··· 120 120 priv = netdev_priv(netdev); 121 121 rpriv = priv->ppriv; 122 122 123 - err = mlx5_esw_acl_ingress_vport_bond_update(esw, rpriv->rep->vport, 124 - mdata->metadata_reg_c_0); 123 + err = mlx5_esw_acl_ingress_vport_metadata_update(esw, rpriv->rep->vport, 124 + mdata->metadata_reg_c_0); 125 125 if (err) 126 126 goto ingress_err; 127 127 ··· 167 167 /* Reset bond_metadata to zero first then reset all ingress/egress 168 168 * acls and rx rules of unslave representor's vport 169 169 */ 170 - mlx5_esw_acl_ingress_vport_bond_update(esw, rpriv->rep->vport, 0); 170 + mlx5_esw_acl_ingress_vport_metadata_update(esw, rpriv->rep->vport, 0); 171 171 mlx5_esw_acl_egress_vport_unbond(esw, rpriv->rep->vport); 172 172 mlx5e_rep_bond_update(priv, false); 173 173
+2 -2
drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
··· 736 736 737 737 void mlx5e_reporter_rx_create(struct mlx5e_priv *priv) 738 738 { 739 - struct devlink_port *dl_port = mlx5e_devlink_get_dl_port(priv); 740 739 struct devlink_health_reporter *reporter; 741 740 742 - reporter = devlink_port_health_reporter_create(dl_port, &mlx5_rx_reporter_ops, 741 + reporter = devlink_port_health_reporter_create(priv->netdev->devlink_port, 742 + &mlx5_rx_reporter_ops, 743 743 MLX5E_REPORTER_RX_GRACEFUL_PERIOD, priv); 744 744 if (IS_ERR(reporter)) { 745 745 netdev_warn(priv->netdev, "Failed to create rx reporter, err = %ld\n",
+2 -2
drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
··· 594 594 595 595 void mlx5e_reporter_tx_create(struct mlx5e_priv *priv) 596 596 { 597 - struct devlink_port *dl_port = mlx5e_devlink_get_dl_port(priv); 598 597 struct devlink_health_reporter *reporter; 599 598 600 - reporter = devlink_port_health_reporter_create(dl_port, &mlx5_tx_reporter_ops, 599 + reporter = devlink_port_health_reporter_create(priv->netdev->devlink_port, 600 + &mlx5_tx_reporter_ops, 601 601 MLX5_REPORTER_TX_GRACEFUL_PERIOD, priv); 602 602 if (IS_ERR(reporter)) { 603 603 netdev_warn(priv->netdev,
-9
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/mirred.c
··· 216 216 struct net_device *uplink_dev; 217 217 struct mlx5e_priv *out_priv; 218 218 struct mlx5_eswitch *esw; 219 - bool is_uplink_rep; 220 219 int *ifindexes; 221 220 int if_count; 222 221 int err; ··· 230 231 231 232 parse_state->ifindexes[if_count] = out_dev->ifindex; 232 233 parse_state->if_count++; 233 - is_uplink_rep = mlx5e_eswitch_uplink_rep(out_dev); 234 234 235 235 if (mlx5_lag_mpesw_do_mirred(priv->mdev, out_dev, extack)) 236 236 return -EOPNOTSUPP; ··· 272 274 rpriv = out_priv->ppriv; 273 275 esw_attr->dests[esw_attr->out_count].rep = rpriv->rep; 274 276 esw_attr->dests[esw_attr->out_count].mdev = out_priv->mdev; 275 - 276 - /* If output device is bond master then rules are not explicit 277 - * so we don't attempt to count them. 278 - */ 279 - if (is_uplink_rep && MLX5_CAP_PORT_SELECTION(priv->mdev, port_select_flow_table) && 280 - MLX5_CAP_GEN(priv->mdev, create_lag_when_not_master_up)) 281 - attr->lag.count = true; 282 277 283 278 esw_attr->out_count++; 284 279
+3 -3
drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c
··· 93 93 else 94 94 return -EOPNOTSUPP; 95 95 96 - if (!(mlx5e_eswitch_rep(*out_dev) && 97 - mlx5e_is_uplink_rep(netdev_priv(*out_dev)))) 96 + if (!mlx5e_eswitch_uplink_rep(*out_dev)) 98 97 return -EOPNOTSUPP; 99 98 100 - if (mlx5e_eswitch_uplink_rep(priv->netdev) && *out_dev != priv->netdev) 99 + if (mlx5e_eswitch_uplink_rep(priv->netdev) && *out_dev != priv->netdev && 100 + !mlx5_lag_is_mpesw(priv->mdev)) 101 101 return -EOPNOTSUPP; 102 102 103 103 return 0;
+13 -13
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
··· 5898 5898 struct mlx5e_priv *priv; 5899 5899 int err; 5900 5900 5901 - mlx5e_dev = mlx5e_create_devlink(&adev->dev); 5901 + mlx5e_dev = mlx5e_create_devlink(&adev->dev, mdev); 5902 5902 if (IS_ERR(mlx5e_dev)) 5903 5903 return PTR_ERR(mlx5e_dev); 5904 5904 auxiliary_set_drvdata(adev, mlx5e_dev); 5905 + 5906 + err = mlx5e_devlink_port_register(mlx5e_dev, mdev); 5907 + if (err) { 5908 + mlx5_core_err(mdev, "mlx5e_devlink_port_register failed, %d\n", err); 5909 + goto err_devlink_unregister; 5910 + } 5905 5911 5906 5912 netdev = mlx5e_create_netdev(mdev, profile); 5907 5913 if (!netdev) { 5908 5914 mlx5_core_err(mdev, "mlx5e_create_netdev failed\n"); 5909 5915 err = -ENOMEM; 5910 - goto err_devlink_unregister; 5916 + goto err_devlink_port_unregister; 5911 5917 } 5918 + SET_NETDEV_DEVLINK_PORT(netdev, &mlx5e_dev->dl_port); 5912 5919 5913 5920 mlx5e_build_nic_netdev(netdev); 5914 5921 ··· 5928 5921 priv->dfs_root = debugfs_create_dir("nic", 5929 5922 mlx5_debugfs_get_dev_root(priv->mdev)); 5930 5923 5931 - err = mlx5e_devlink_port_register(mlx5e_dev, priv); 5932 - if (err) { 5933 - mlx5_core_err(mdev, "mlx5e_devlink_port_register failed, %d\n", err); 5934 - goto err_destroy_netdev; 5935 - } 5936 - 5937 5924 err = profile->init(mdev, netdev); 5938 5925 if (err) { 5939 5926 mlx5_core_err(mdev, "mlx5e_nic_profile init failed, %d\n", err); 5940 - goto err_devlink_cleanup; 5927 + goto err_destroy_netdev; 5941 5928 } 5942 5929 5943 5930 err = mlx5e_resume(adev); ··· 5940 5939 goto err_profile_cleanup; 5941 5940 } 5942 5941 5943 - SET_NETDEV_DEVLINK_PORT(netdev, mlx5e_devlink_get_dl_port(priv)); 5944 5942 err = register_netdev(netdev); 5945 5943 if (err) { 5946 5944 mlx5_core_err(mdev, "register_netdev failed, %d\n", err); ··· 5955 5955 mlx5e_suspend(adev, state); 5956 5956 err_profile_cleanup: 5957 5957 profile->cleanup(priv); 5958 - err_devlink_cleanup: 5959 - mlx5e_devlink_port_unregister(priv); 5960 5958 err_destroy_netdev: 5961 5959 debugfs_remove_recursive(priv->dfs_root); 5962 5960 mlx5e_destroy_netdev(priv); 5961 + err_devlink_port_unregister: 5962 + mlx5e_devlink_port_unregister(mlx5e_dev); 5963 5963 err_devlink_unregister: 5964 5964 mlx5e_destroy_devlink(mlx5e_dev); 5965 5965 return err; ··· 5976 5976 unregister_netdev(priv->netdev); 5977 5977 mlx5e_suspend(adev, state); 5978 5978 priv->profile->cleanup(priv); 5979 - mlx5e_devlink_port_unregister(priv); 5980 5979 debugfs_remove_recursive(priv->dfs_root); 5981 5980 mlx5e_destroy_netdev(priv); 5981 + mlx5e_devlink_port_unregister(mlx5e_dev); 5982 5982 mlx5e_destroy_devlink(mlx5e_dev); 5983 5983 } 5984 5984
+35
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
··· 1007 1007 priv->rx_res = NULL; 1008 1008 } 1009 1009 1010 + static void mlx5e_rep_mpesw_work(struct work_struct *work) 1011 + { 1012 + struct mlx5_rep_uplink_priv *uplink_priv = 1013 + container_of(work, struct mlx5_rep_uplink_priv, 1014 + mpesw_work); 1015 + struct mlx5e_rep_priv *rpriv = 1016 + container_of(uplink_priv, struct mlx5e_rep_priv, 1017 + uplink_priv); 1018 + struct mlx5e_priv *priv = netdev_priv(rpriv->netdev); 1019 + 1020 + rep_vport_rx_rule_destroy(priv); 1021 + mlx5e_create_rep_vport_rx_rule(priv); 1022 + } 1023 + 1010 1024 static int mlx5e_init_ul_rep_rx(struct mlx5e_priv *priv) 1011 1025 { 1026 + struct mlx5e_rep_priv *rpriv = priv->ppriv; 1012 1027 int err; 1013 1028 1014 1029 mlx5e_create_q_counters(priv); ··· 1033 1018 1034 1019 mlx5e_tc_int_port_init_rep_rx(priv); 1035 1020 1021 + INIT_WORK(&rpriv->uplink_priv.mpesw_work, mlx5e_rep_mpesw_work); 1022 + 1036 1023 out: 1037 1024 return err; 1038 1025 } 1039 1026 1040 1027 static void mlx5e_cleanup_ul_rep_rx(struct mlx5e_priv *priv) 1041 1028 { 1029 + struct mlx5e_rep_priv *rpriv = priv->ppriv; 1030 + 1031 + cancel_work_sync(&rpriv->uplink_priv.mpesw_work); 1042 1032 mlx5e_tc_int_port_cleanup_rep_rx(priv); 1043 1033 mlx5e_cleanup_rep_rx(priv); 1044 1034 mlx5e_destroy_q_counters(priv); ··· 1152 1132 return 0; 1153 1133 } 1154 1134 1135 + static int mlx5e_rep_event_mpesw(struct mlx5e_priv *priv) 1136 + { 1137 + struct mlx5e_rep_priv *rpriv = priv->ppriv; 1138 + struct mlx5_eswitch_rep *rep = rpriv->rep; 1139 + 1140 + if (rep->vport != MLX5_VPORT_UPLINK) 1141 + return NOTIFY_DONE; 1142 + 1143 + queue_work(priv->wq, &rpriv->uplink_priv.mpesw_work); 1144 + 1145 + return NOTIFY_OK; 1146 + } 1147 + 1155 1148 static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event, void *data) 1156 1149 { 1157 1150 struct mlx5e_priv *priv = container_of(nb, struct mlx5e_priv, events_nb); ··· 1186 1153 1187 1154 if (event == MLX5_DEV_EVENT_PORT_AFFINITY) 1188 1155 return mlx5e_rep_tc_event_port_affinity(priv); 1156 + else if (event == MLX5_DEV_EVENT_MULTIPORT_ESW) 1157 + return mlx5e_rep_event_mpesw(priv); 1189 1158 1190 1159 return NOTIFY_DONE; 1191 1160 }
+2
drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
··· 103 103 104 104 /* tc action stats */ 105 105 struct mlx5e_tc_act_stats_handle *action_stats_handle; 106 + 107 + struct work_struct mpesw_work; 106 108 }; 107 109 108 110 struct mlx5e_rep_priv {
+2 -4
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
··· 2570 2570 2571 2571 static void mlx5e_trap_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe) 2572 2572 { 2573 - struct mlx5e_priv *priv = netdev_priv(rq->netdev); 2574 2573 struct mlx5_wq_cyc *wq = &rq->wqe.wq; 2575 2574 struct mlx5e_wqe_frag_info *wi; 2576 - struct devlink_port *dl_port; 2577 2575 struct sk_buff *skb; 2578 2576 u32 cqe_bcnt; 2579 2577 u16 trap_id; ··· 2594 2596 mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb); 2595 2597 skb_push(skb, ETH_HLEN); 2596 2598 2597 - dl_port = mlx5e_devlink_get_dl_port(priv); 2598 - mlx5_devlink_trap_report(rq->mdev, trap_id, skb, dl_port); 2599 + mlx5_devlink_trap_report(rq->mdev, trap_id, skb, 2600 + rq->netdev->devlink_port); 2599 2601 dev_kfree_skb_any(skb); 2600 2602 2601 2603 free_wqe:
+9 -23
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
··· 2152 2152 free_branch_attr(flow, attr->branch_true); 2153 2153 free_branch_attr(flow, attr->branch_false); 2154 2154 2155 - if (flow->attr->lag.count) 2156 - mlx5_lag_del_mpesw_rule(esw->dev); 2157 - 2158 2155 kvfree(attr->esw_attr->rx_tun_attr); 2159 2156 kvfree(attr->parse_attr); 2160 2157 kfree(flow->attr); ··· 3678 3681 3679 3682 static bool 3680 3683 actions_match_supported_fdb(struct mlx5e_priv *priv, 3681 - struct mlx5e_tc_flow_parse_attr *parse_attr, 3682 3684 struct mlx5e_tc_flow *flow, 3683 3685 struct netlink_ext_ack *extack) 3684 3686 { ··· 3726 3730 return false; 3727 3731 3728 3732 if (mlx5e_is_eswitch_flow(flow) && 3729 - !actions_match_supported_fdb(priv, parse_attr, flow, extack)) 3733 + !actions_match_supported_fdb(priv, flow, extack)) 3730 3734 return false; 3731 3735 3732 3736 return true; ··· 4310 4314 4311 4315 static bool is_multiport_eligible(struct mlx5e_priv *priv, struct net_device *out_dev) 4312 4316 { 4313 - if (same_hw_reps(priv, out_dev) && 4314 - MLX5_CAP_PORT_SELECTION(priv->mdev, port_select_flow_table) && 4315 - MLX5_CAP_GEN(priv->mdev, create_lag_when_not_master_up)) 4316 - return true; 4317 - 4318 - return false; 4317 + return same_hw_reps(priv, out_dev) && mlx5_lag_is_mpesw(priv->mdev); 4319 4318 } 4320 4319 4321 4320 bool mlx5e_is_valid_eswitch_fwd_dev(struct mlx5e_priv *priv, ··· 4481 4490 (is_rep_ingress || act_is_encap)) 4482 4491 return true; 4483 4492 4493 + if (mlx5_lag_is_mpesw(esw_attr->in_mdev)) 4494 + return true; 4495 + 4484 4496 return false; 4485 4497 } 4486 4498 ··· 4615 4621 struct mlx5_core_dev *in_mdev) 4616 4622 { 4617 4623 struct flow_rule *rule = flow_cls_offload_flow_rule(f); 4618 - struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 4619 4624 struct netlink_ext_ack *extack = f->common.extack; 4620 4625 struct mlx5e_tc_flow_parse_attr *parse_attr; 4621 4626 struct mlx5e_tc_flow *flow; ··· 4647 4654 if (err) 4648 4655 goto err_free; 4649 4656 4650 - if (flow->attr->lag.count) { 4651 - err = mlx5_lag_add_mpesw_rule(esw->dev); 4652 - if (err) 4653 - goto err_free; 4654 - } 4655 - 4656 4657 err = mlx5e_tc_add_fdb_flow(priv, flow, extack); 4657 4658 complete_all(&flow->init_done); 4658 4659 if (err) { 4659 4660 if (!(err == -ENETUNREACH && mlx5_lag_is_multipath(in_mdev))) 4660 - goto err_lag; 4661 + goto err_free; 4661 4662 4662 4663 add_unready_flow(flow); 4663 4664 } 4664 4665 4665 4666 return flow; 4666 4667 4667 - err_lag: 4668 - if (flow->attr->lag.count) 4669 - mlx5_lag_del_mpesw_rule(esw->dev); 4670 4668 err_free: 4671 4669 mlx5e_flow_put(priv, flow); 4672 4670 out: ··· 4689 4705 * So packets redirected to uplink use the same mdev of the 4690 4706 * original flow and packets redirected from uplink use the 4691 4707 * peer mdev. 4708 + * In multiport eswitch it's a special case that we need to 4709 + * keep the original mdev. 4692 4710 */ 4693 - if (attr->in_rep->vport == MLX5_VPORT_UPLINK) 4711 + if (attr->in_rep->vport == MLX5_VPORT_UPLINK && !mlx5_lag_is_mpesw(priv->mdev)) 4694 4712 in_mdev = peer_priv->mdev; 4695 4713 else 4696 4714 in_mdev = priv->mdev;
-6
drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
··· 92 92 u32 exe_aso_type; 93 93 struct list_head list; 94 94 struct mlx5e_post_act_handle *post_act_handle; 95 - struct { 96 - /* Indicate whether the parsed flow should be counted for lag mode decision 97 - * making 98 - */ 99 - bool count; 100 - } lag; 101 95 struct mlx5_flow_attr *branch_true; 102 96 struct mlx5_flow_attr *branch_false; 103 97 struct mlx5_flow_attr *jumping_attr;
+2 -2
drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c
··· 356 356 } 357 357 358 358 /* Caller must hold rtnl_lock */ 359 - int mlx5_esw_acl_ingress_vport_bond_update(struct mlx5_eswitch *esw, u16 vport_num, 360 - u32 metadata) 359 + int mlx5_esw_acl_ingress_vport_metadata_update(struct mlx5_eswitch *esw, u16 vport_num, 360 + u32 metadata) 361 361 { 362 362 struct mlx5_vport *vport = mlx5_eswitch_get_vport(esw, vport_num); 363 363 int err;
+2 -2
drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ofld.h
··· 24 24 /* Eswitch acl ingress external APIs */ 25 25 int esw_acl_ingress_ofld_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport); 26 26 void esw_acl_ingress_ofld_cleanup(struct mlx5_eswitch *esw, struct mlx5_vport *vport); 27 - int mlx5_esw_acl_ingress_vport_bond_update(struct mlx5_eswitch *esw, u16 vport_num, 28 - u32 metadata); 27 + int mlx5_esw_acl_ingress_vport_metadata_update(struct mlx5_eswitch *esw, u16 vport_num, 28 + u32 metadata); 29 29 void mlx5_esw_acl_ingress_vport_drop_rule_destroy(struct mlx5_eswitch *esw, u16 vport_num); 30 30 int mlx5_esw_acl_ingress_vport_drop_rule_create(struct mlx5_eswitch *esw, u16 vport_num); 31 31
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
··· 443 443 MLX5_CAP_GEN(esw_attr->dests[attr_idx].mdev, vhca_id); 444 444 dest[dest_idx].vport.flags |= MLX5_FLOW_DEST_VPORT_VHCA_ID; 445 445 if (dest[dest_idx].vport.num == MLX5_VPORT_UPLINK && 446 - mlx5_lag_mpesw_is_activated(esw->dev)) 446 + mlx5_lag_is_mpesw(esw->dev)) 447 447 dest[dest_idx].type = MLX5_FLOW_DESTINATION_TYPE_UPLINK; 448 448 } 449 449 if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP_VALID) {
+3 -3
drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
··· 163 163 if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) { 164 164 complete(&fw_reset->done); 165 165 } else { 166 - mlx5_unload_one(dev); 166 + mlx5_unload_one(dev, false); 167 167 if (mlx5_health_wait_pci_up(dev)) 168 168 mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n"); 169 169 else 170 - mlx5_load_one(dev, false); 170 + mlx5_load_one(dev); 171 171 devlink_remote_reload_actions_performed(priv_to_devlink(dev), 0, 172 172 BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) | 173 173 BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE)); ··· 498 498 } 499 499 err = fw_reset->ret; 500 500 if (test_and_clear_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags)) { 501 - mlx5_unload_one_devl_locked(dev); 501 + mlx5_unload_one_devl_locked(dev, false); 502 502 mlx5_load_one_devl_locked(dev, false); 503 503 } 504 504 out:
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/health.c
··· 699 699 * requests from the kernel. 700 700 */ 701 701 mlx5_core_err(dev, "Driver is in error state. Unloading\n"); 702 - mlx5_unload_one(dev); 702 + mlx5_unload_one(dev, false); 703 703 } 704 704 } 705 705
+4 -6
drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
··· 230 230 mlx5_lag_mp_cleanup(ldev); 231 231 cancel_delayed_work_sync(&ldev->bond_work); 232 232 destroy_workqueue(ldev->wq); 233 - mlx5_lag_mpesw_cleanup(ldev); 234 233 mutex_destroy(&ldev->lock); 235 234 kfree(ldev); 236 235 } ··· 275 276 mlx5_core_err(dev, "Failed to init multipath lag err=%d\n", 276 277 err); 277 278 278 - mlx5_lag_mpesw_init(ldev); 279 279 ldev->ports = MLX5_CAP_GEN(dev, num_lag_ports); 280 280 ldev->buckets = 1; 281 281 ··· 644 646 return 0; 645 647 } 646 648 647 - static int mlx5_deactivate_lag(struct mlx5_lag *ldev) 649 + int mlx5_deactivate_lag(struct mlx5_lag *ldev) 648 650 { 649 651 struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev; 650 652 struct mlx5_core_dev *dev1 = ldev->pf[MLX5_LAG_P2].dev; ··· 686 688 } 687 689 688 690 #define MLX5_LAG_OFFLOADS_SUPPORTED_PORTS 2 689 - static bool mlx5_lag_check_prereq(struct mlx5_lag *ldev) 691 + bool mlx5_lag_check_prereq(struct mlx5_lag *ldev) 690 692 { 691 693 #ifdef CONFIG_MLX5_ESWITCH 692 694 struct mlx5_core_dev *dev; ··· 721 723 return true; 722 724 } 723 725 724 - static void mlx5_lag_add_devices(struct mlx5_lag *ldev) 726 + void mlx5_lag_add_devices(struct mlx5_lag *ldev) 725 727 { 726 728 int i; 727 729 ··· 738 740 } 739 741 } 740 742 741 - static void mlx5_lag_remove_devices(struct mlx5_lag *ldev) 743 + void mlx5_lag_remove_devices(struct mlx5_lag *ldev) 742 744 { 743 745 int i; 744 746
+4
drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
··· 102 102 return test_bit(MLX5_LAG_FLAG_NDEVS_READY, &ldev->state_flags); 103 103 } 104 104 105 + bool mlx5_lag_check_prereq(struct mlx5_lag *ldev); 105 106 void mlx5_modify_lag(struct mlx5_lag *ldev, 106 107 struct lag_tracker *tracker); 107 108 int mlx5_activate_lag(struct mlx5_lag *ldev, ··· 120 119 void mlx5_ldev_add_debugfs(struct mlx5_core_dev *dev); 121 120 void mlx5_ldev_remove_debugfs(struct dentry *dbg); 122 121 void mlx5_disable_lag(struct mlx5_lag *ldev); 122 + void mlx5_lag_remove_devices(struct mlx5_lag *ldev); 123 + int mlx5_deactivate_lag(struct mlx5_lag *ldev); 124 + void mlx5_lag_add_devices(struct mlx5_lag *ldev); 123 125 124 126 #endif /* __MLX5_LAG_H__ */
+115 -35
drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
··· 5 5 #include <net/nexthop.h> 6 6 #include "lag/lag.h" 7 7 #include "eswitch.h" 8 + #include "esw/acl/ofld.h" 8 9 #include "lib/mlx5.h" 9 10 10 - static int add_mpesw_rule(struct mlx5_lag *ldev) 11 + static void mlx5_mpesw_metadata_cleanup(struct mlx5_lag *ldev) 11 12 { 12 - struct mlx5_core_dev *dev = ldev->pf[MLX5_LAG_P1].dev; 13 - int err; 13 + struct mlx5_core_dev *dev; 14 + struct mlx5_eswitch *esw; 15 + u32 pf_metadata; 16 + int i; 14 17 15 - if (atomic_add_return(1, &ldev->lag_mpesw.mpesw_rule_count) != 1) 16 - return 0; 18 + for (i = 0; i < ldev->ports; i++) { 19 + dev = ldev->pf[i].dev; 20 + esw = dev->priv.eswitch; 21 + pf_metadata = ldev->lag_mpesw.pf_metadata[i]; 22 + if (!pf_metadata) 23 + continue; 24 + mlx5_esw_acl_ingress_vport_metadata_update(esw, MLX5_VPORT_UPLINK, 0); 25 + mlx5_notifier_call_chain(dev->priv.events, MLX5_DEV_EVENT_MULTIPORT_ESW, 26 + (void *)0); 27 + mlx5_esw_match_metadata_free(esw, pf_metadata); 28 + ldev->lag_mpesw.pf_metadata[i] = 0; 29 + } 30 + } 17 31 18 - if (ldev->mode != MLX5_LAG_MODE_NONE) { 19 - err = -EINVAL; 20 - goto out_err; 32 + static int mlx5_mpesw_metadata_set(struct mlx5_lag *ldev) 33 + { 34 + struct mlx5_core_dev *dev; 35 + struct mlx5_eswitch *esw; 36 + u32 pf_metadata; 37 + int i, err; 38 + 39 + for (i = 0; i < ldev->ports; i++) { 40 + dev = ldev->pf[i].dev; 41 + esw = dev->priv.eswitch; 42 + pf_metadata = mlx5_esw_match_metadata_alloc(esw); 43 + if (!pf_metadata) { 44 + err = -ENOSPC; 45 + goto err_metadata; 46 + } 47 + 48 + ldev->lag_mpesw.pf_metadata[i] = pf_metadata; 49 + err = mlx5_esw_acl_ingress_vport_metadata_update(esw, MLX5_VPORT_UPLINK, 50 + pf_metadata); 51 + if (err) 52 + goto err_metadata; 21 53 } 22 54 23 - err = mlx5_activate_lag(ldev, NULL, MLX5_LAG_MODE_MPESW, false); 24 - if (err) { 25 - mlx5_core_warn(dev, "Failed to create LAG in MPESW mode (%d)\n", err); 26 - goto out_err; 55 + for (i = 0; i < ldev->ports; i++) { 56 + dev = ldev->pf[i].dev; 57 + mlx5_notifier_call_chain(dev->priv.events, MLX5_DEV_EVENT_MULTIPORT_ESW, 58 + (void *)0); 27 59 } 28 60 29 61 return 0; 30 62 31 - out_err: 32 - atomic_dec(&ldev->lag_mpesw.mpesw_rule_count); 63 + err_metadata: 64 + mlx5_mpesw_metadata_cleanup(ldev); 33 65 return err; 34 66 } 35 67 36 - static void del_mpesw_rule(struct mlx5_lag *ldev) 68 + static int enable_mpesw(struct mlx5_lag *ldev) 37 69 { 38 - if (!atomic_dec_return(&ldev->lag_mpesw.mpesw_rule_count) && 39 - ldev->mode == MLX5_LAG_MODE_MPESW) 70 + struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev; 71 + struct mlx5_core_dev *dev1 = ldev->pf[MLX5_LAG_P2].dev; 72 + int err; 73 + 74 + if (ldev->mode != MLX5_LAG_MODE_NONE) 75 + return -EINVAL; 76 + 77 + if (mlx5_eswitch_mode(dev0) != MLX5_ESWITCH_OFFLOADS || 78 + !MLX5_CAP_PORT_SELECTION(dev0, port_select_flow_table) || 79 + !MLX5_CAP_GEN(dev0, create_lag_when_not_master_up) || 80 + !mlx5_lag_check_prereq(ldev)) 81 + return -EOPNOTSUPP; 82 + 83 + err = mlx5_mpesw_metadata_set(ldev); 84 + if (err) 85 + return err; 86 + 87 + mlx5_lag_remove_devices(ldev); 88 + 89 + err = mlx5_activate_lag(ldev, NULL, MLX5_LAG_MODE_MPESW, true); 90 + if (err) { 91 + mlx5_core_warn(dev0, "Failed to create LAG in MPESW mode (%d)\n", err); 92 + goto err_add_devices; 93 + } 94 + 95 + dev0->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_IB_ADEV; 96 + mlx5_rescan_drivers_locked(dev0); 97 + err = mlx5_eswitch_reload_reps(dev0->priv.eswitch); 98 + if (!err) 99 + err = mlx5_eswitch_reload_reps(dev1->priv.eswitch); 100 + if (err) 101 + goto err_rescan_drivers; 102 + 103 + return 0; 104 + 105 + err_rescan_drivers: 106 + dev0->priv.flags |= MLX5_PRIV_FLAGS_DISABLE_IB_ADEV; 107 + mlx5_rescan_drivers_locked(dev0); 108 + mlx5_deactivate_lag(ldev); 109 + err_add_devices: 110 + mlx5_lag_add_devices(ldev); 111 + mlx5_eswitch_reload_reps(dev0->priv.eswitch); 112 + mlx5_eswitch_reload_reps(dev1->priv.eswitch); 113 + mlx5_mpesw_metadata_cleanup(ldev); 114 + return err; 115 + } 116 + 117 + static void disable_mpesw(struct mlx5_lag *ldev) 118 + { 119 + if (ldev->mode == MLX5_LAG_MODE_MPESW) { 120 + mlx5_mpesw_metadata_cleanup(ldev); 40 121 mlx5_disable_lag(ldev); 122 + } 41 123 } 42 124 43 125 static void mlx5_mpesw_work(struct work_struct *work) ··· 127 45 struct mlx5_mpesw_work_st *mpesww = container_of(work, struct mlx5_mpesw_work_st, work); 128 46 struct mlx5_lag *ldev = mpesww->lag; 129 47 48 + mlx5_dev_list_lock(); 130 49 mutex_lock(&ldev->lock); 131 - if (mpesww->op == MLX5_MPESW_OP_ENABLE) 132 - mpesww->result = add_mpesw_rule(ldev); 133 - else if (mpesww->op == MLX5_MPESW_OP_DISABLE) 134 - del_mpesw_rule(ldev); 135 - mutex_unlock(&ldev->lock); 50 + if (ldev->mode_changes_in_progress) { 51 + mpesww->result = -EAGAIN; 52 + goto unlock; 53 + } 136 54 55 + if (mpesww->op == MLX5_MPESW_OP_ENABLE) 56 + mpesww->result = enable_mpesw(ldev); 57 + else if (mpesww->op == MLX5_MPESW_OP_DISABLE) 58 + disable_mpesw(ldev); 59 + unlock: 60 + mutex_unlock(&ldev->lock); 61 + mlx5_dev_list_unlock(); 137 62 complete(&mpesww->comp); 138 63 } 139 64 ··· 175 86 return err; 176 87 } 177 88 178 - void mlx5_lag_del_mpesw_rule(struct mlx5_core_dev *dev) 89 + void mlx5_lag_mpesw_disable(struct mlx5_core_dev *dev) 179 90 { 180 91 mlx5_lag_mpesw_queue_work(dev, MLX5_MPESW_OP_DISABLE); 181 92 } 182 93 183 - int mlx5_lag_add_mpesw_rule(struct mlx5_core_dev *dev) 94 + int mlx5_lag_mpesw_enable(struct mlx5_core_dev *dev) 184 95 { 185 96 return mlx5_lag_mpesw_queue_work(dev, MLX5_MPESW_OP_ENABLE); 186 97 } ··· 201 112 return -EOPNOTSUPP; 202 113 } 203 114 204 - bool mlx5_lag_mpesw_is_activated(struct mlx5_core_dev *dev) 115 + bool mlx5_lag_is_mpesw(struct mlx5_core_dev *dev) 205 116 { 206 117 struct mlx5_lag *ldev = mlx5_lag_dev(dev); 207 118 208 119 return ldev && ldev->mode == MLX5_LAG_MODE_MPESW; 209 120 } 210 - 211 - void mlx5_lag_mpesw_init(struct mlx5_lag *ldev) 212 - { 213 - atomic_set(&ldev->lag_mpesw.mpesw_rule_count, 0); 214 - } 215 - 216 - void mlx5_lag_mpesw_cleanup(struct mlx5_lag *ldev) 217 - { 218 - WARN_ON(atomic_read(&ldev->lag_mpesw.mpesw_rule_count)); 219 - } 121 + EXPORT_SYMBOL(mlx5_lag_is_mpesw);
+4 -11
drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.h
··· 9 9 10 10 struct lag_mpesw { 11 11 struct work_struct mpesw_work; 12 - atomic_t mpesw_rule_count; 12 + u32 pf_metadata[MLX5_MAX_PORTS]; 13 13 }; 14 14 15 15 enum mpesw_op { ··· 28 28 int mlx5_lag_mpesw_do_mirred(struct mlx5_core_dev *mdev, 29 29 struct net_device *out_dev, 30 30 struct netlink_ext_ack *extack); 31 - bool mlx5_lag_mpesw_is_activated(struct mlx5_core_dev *dev); 32 - void mlx5_lag_del_mpesw_rule(struct mlx5_core_dev *dev); 33 - int mlx5_lag_add_mpesw_rule(struct mlx5_core_dev *dev); 34 - #if IS_ENABLED(CONFIG_MLX5_ESWITCH) 35 - void mlx5_lag_mpesw_init(struct mlx5_lag *ldev); 36 - void mlx5_lag_mpesw_cleanup(struct mlx5_lag *ldev); 37 - #else 38 - static inline void mlx5_lag_mpesw_init(struct mlx5_lag *ldev) {} 39 - static inline void mlx5_lag_mpesw_cleanup(struct mlx5_lag *ldev) {} 40 - #endif 31 + bool mlx5_lag_is_mpesw(struct mlx5_core_dev *dev); 32 + void mlx5_lag_mpesw_disable(struct mlx5_core_dev *dev); 33 + int mlx5_lag_mpesw_enable(struct mlx5_core_dev *dev); 41 34 42 35 #endif /* __MLX5_LAG_MPESW_H__ */
+12 -13
drivers/net/ethernet/mellanox/mlx5/core/main.c
··· 1509 1509 return err; 1510 1510 } 1511 1511 1512 - int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery) 1512 + int mlx5_load_one(struct mlx5_core_dev *dev) 1513 1513 { 1514 1514 struct devlink *devlink = priv_to_devlink(dev); 1515 1515 int ret; 1516 1516 1517 1517 devl_lock(devlink); 1518 - ret = mlx5_load_one_devl_locked(dev, recovery); 1518 + ret = mlx5_load_one_devl_locked(dev, false); 1519 1519 devl_unlock(devlink); 1520 1520 return ret; 1521 1521 } 1522 1522 1523 - void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev) 1523 + void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev, bool suspend) 1524 1524 { 1525 1525 devl_assert_locked(priv_to_devlink(dev)); 1526 1526 mutex_lock(&dev->intf_state_mutex); 1527 1527 1528 - mlx5_detach_device(dev); 1528 + mlx5_detach_device(dev, suspend); 1529 1529 1530 1530 if (!test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) { 1531 1531 mlx5_core_warn(dev, "%s: interface is down, NOP\n", ··· 1540 1540 mutex_unlock(&dev->intf_state_mutex); 1541 1541 } 1542 1542 1543 - void mlx5_unload_one(struct mlx5_core_dev *dev) 1543 + void mlx5_unload_one(struct mlx5_core_dev *dev, bool suspend) 1544 1544 { 1545 1545 struct devlink *devlink = priv_to_devlink(dev); 1546 1546 1547 1547 devl_lock(devlink); 1548 - mlx5_unload_one_devl_locked(dev); 1548 + mlx5_unload_one_devl_locked(dev, suspend); 1549 1549 devl_unlock(devlink); 1550 1550 } 1551 1551 ··· 1830 1830 1831 1831 mlx5_enter_error_state(dev, false); 1832 1832 mlx5_error_sw_reset(dev); 1833 - mlx5_unload_one(dev); 1833 + mlx5_unload_one(dev, true); 1834 1834 mlx5_drain_health_wq(dev); 1835 1835 mlx5_pci_disable_device(dev); 1836 1836 ··· 1912 1912 1913 1913 mlx5_pci_trace(dev, "Enter, loading driver..\n"); 1914 1914 1915 - err = mlx5_load_one(dev, false); 1916 - 1915 + err = mlx5_load_one(dev); 1917 1916 if (!err) 1918 1917 devlink_health_reporter_state_update(dev->priv.health.fw_fatal_reporter, 1919 1918 DEVLINK_HEALTH_REPORTER_STATE_HEALTHY); ··· 1986 1987 set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state); 1987 1988 err = mlx5_try_fast_unload(dev); 1988 1989 if (err) 1989 - mlx5_unload_one(dev); 1990 + mlx5_unload_one(dev, false); 1990 1991 mlx5_pci_disable_device(dev); 1991 1992 } 1992 1993 ··· 1994 1995 { 1995 1996 struct mlx5_core_dev *dev = pci_get_drvdata(pdev); 1996 1997 1997 - mlx5_unload_one(dev); 1998 + mlx5_unload_one(dev, true); 1998 1999 1999 2000 return 0; 2000 2001 } ··· 2003 2004 { 2004 2005 struct mlx5_core_dev *dev = pci_get_drvdata(pdev); 2005 2006 2006 - return mlx5_load_one(dev, false); 2007 + return mlx5_load_one(dev); 2007 2008 } 2008 2009 2009 2010 static const struct pci_device_id mlx5_core_pci_table[] = { ··· 2037 2038 void mlx5_disable_device(struct mlx5_core_dev *dev) 2038 2039 { 2039 2040 mlx5_error_sw_reset(dev); 2040 - mlx5_unload_one_devl_locked(dev); 2041 + mlx5_unload_one_devl_locked(dev, false); 2041 2042 } 2042 2043 2043 2044 int mlx5_recover_device(struct mlx5_core_dev *dev)
+4 -4
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
··· 236 236 int mlx5_adev_init(struct mlx5_core_dev *dev); 237 237 238 238 int mlx5_attach_device(struct mlx5_core_dev *dev); 239 - void mlx5_detach_device(struct mlx5_core_dev *dev); 239 + void mlx5_detach_device(struct mlx5_core_dev *dev, bool suspend); 240 240 int mlx5_register_device(struct mlx5_core_dev *dev); 241 241 void mlx5_unregister_device(struct mlx5_core_dev *dev); 242 242 struct mlx5_core_dev *mlx5_get_next_phys_dev_lag(struct mlx5_core_dev *dev); ··· 319 319 void mlx5_mdev_uninit(struct mlx5_core_dev *dev); 320 320 int mlx5_init_one(struct mlx5_core_dev *dev); 321 321 void mlx5_uninit_one(struct mlx5_core_dev *dev); 322 - void mlx5_unload_one(struct mlx5_core_dev *dev); 323 - void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev); 324 - int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery); 322 + void mlx5_unload_one(struct mlx5_core_dev *dev, bool suspend); 323 + void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev, bool suspend); 324 + int mlx5_load_one(struct mlx5_core_dev *dev); 325 325 int mlx5_load_one_devl_locked(struct mlx5_core_dev *dev, bool recovery); 326 326 327 327 int mlx5_vport_set_other_func_cap(struct mlx5_core_dev *dev, const void *hca_cap, u16 function_id,
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c
··· 74 74 { 75 75 struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev); 76 76 77 - mlx5_unload_one(sf_dev->mdev); 77 + mlx5_unload_one(sf_dev->mdev, false); 78 78 } 79 79 80 80 static const struct auxiliary_device_id mlx5_sf_dev_id_table[] = {
+2 -1
include/linux/mlx5/driver.h
··· 217 217 enum mlx5_dev_event { 218 218 MLX5_DEV_EVENT_SYS_ERROR = 128, /* 0 - 127 are FW events */ 219 219 MLX5_DEV_EVENT_PORT_AFFINITY = 129, 220 + MLX5_DEV_EVENT_MULTIPORT_ESW = 130, 220 221 }; 221 222 222 223 enum mlx5_port_status { ··· 679 678 u32 mkey; 680 679 struct mlx5_sq_bfreg bfreg; 681 680 } hw_objs; 682 - struct devlink_port dl_port; 683 681 struct net_device *uplink_netdev; 684 682 struct mutex uplink_netdev_lock; 685 683 struct mlx5_crypto_dek_priv *dek_priv; ··· 1161 1161 bool mlx5_lag_mode_is_hash(struct mlx5_core_dev *dev); 1162 1162 bool mlx5_lag_is_master(struct mlx5_core_dev *dev); 1163 1163 bool mlx5_lag_is_shared_fdb(struct mlx5_core_dev *dev); 1164 + bool mlx5_lag_is_mpesw(struct mlx5_core_dev *dev); 1164 1165 struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev); 1165 1166 u8 mlx5_lag_get_slave_port(struct mlx5_core_dev *dev, 1166 1167 struct net_device *slave);