From: Eran Ben Elisha <era...@mellanox.com> Disable link up when initializing the HCA. Link up/down will be changed using (Ports Administrative and Operational Status Register) PAOS commands.
If link layer is Ethernet, up/down the link in ndo_open/stop. If link layer is IB, up/down the link as part of the mlx5 IB add/remove flow. Before this patch the link was up when the HCA was initialized, now the driver will manage the link. Signed-off-by: Eran Ben Elisha <era...@mellanox.com> Signed-off-by: Eugenia Emantayev <euge...@mellanox.com> Signed-off-by: Saeed Mahameed <sae...@mellanox.com> --- drivers/infiniband/hw/mlx5/main.c | 11 +++++++++++ drivers/infiniband/hw/mlx5/mlx5_ib.h | 5 +++++ drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 4 ++-- .../net/ethernet/mellanox/mlx5/core/en_ethtool.c | 4 ++-- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 4 ++++ drivers/net/ethernet/mellanox/mlx5/core/main.c | 4 ++++ drivers/net/ethernet/mellanox/mlx5/core/port.c | 5 +++-- include/linux/mlx5/port.h | 3 ++- 8 files changed, 33 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 5acf346..6fd365f 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -2261,6 +2261,9 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev) if (err) goto err_dealloc; + mlx5_foreach_port(dev, i, IB_LINK_LAYER_INFINIBAND) + mlx5_set_port_admin_status(dev->mdev, MLX5_PORT_UP, i + 1); + if (mlx5_use_mad_ifc(dev)) get_ext_port_caps(dev); @@ -2443,6 +2446,9 @@ err_disable_roce: if (ll == IB_LINK_LAYER_ETHERNET) mlx5_disable_roce(dev); + mlx5_foreach_port(dev, i, IB_LINK_LAYER_INFINIBAND) + mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN, i + 1); + err_dealloc: ib_dealloc_device((struct ib_device *)dev); @@ -2453,6 +2459,7 @@ static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context) { struct mlx5_ib_dev *dev = context; enum rdma_link_layer ll = mlx5_ib_port_link_layer(&dev->ib_dev, 1); + int i; ib_unregister_device(&dev->ib_dev); destroy_umrc_res(dev); @@ -2460,6 +2467,10 @@ static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context) destroy_dev_resources(&dev->devr); if (ll == IB_LINK_LAYER_ETHERNET) mlx5_disable_roce(dev); + + mlx5_foreach_port(dev, i, IB_LINK_LAYER_INFINIBAND) + mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN, i + 1); + ib_dealloc_device(&dev->ib_dev); } diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index b46c255..4585fca 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h @@ -62,6 +62,11 @@ pr_warn("%s:%s:%d:(pid %d): " format, (dev)->ib_dev.name, __func__, \ #define MLX5_IB_DEFAULT_UIDX 0xffffff #define MLX5_USER_ASSIGNED_UIDX_MASK __mlx5_mask(qpc, user_index) +#define mlx5_foreach_port(dev, p, type) \ + for ((p) = 0; (p) < MLX5_CAP_GEN(dev->mdev, num_ports); (p)++) \ + if (mlx5_ib_port_link_layer(&dev->ib_dev, (p) + 1) == \ + (type)) + enum { MLX5_IB_MMAP_CMD_SHIFT = 8, MLX5_IB_MMAP_CMD_MASK = 0xff, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c index b2db180..f083797 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c @@ -202,12 +202,12 @@ static int mlx5e_dcbnl_ieee_setpfc(struct net_device *dev, mlx5_query_port_admin_status(mdev, &ps); if (ps == MLX5_PORT_UP) - mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN); + mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN, 1); ret = mlx5_set_port_pfc(mdev, pfc->pfc_en, pfc->pfc_en); if (ps == MLX5_PORT_UP) - mlx5_set_port_admin_status(mdev, MLX5_PORT_UP); + mlx5_set_port_admin_status(mdev, MLX5_PORT_UP, 1); return ret; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 0518c86..2fed67f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c @@ -777,10 +777,10 @@ static int mlx5e_set_settings(struct net_device *netdev, mlx5_query_port_admin_status(mdev, &ps); if (ps == MLX5_PORT_UP) - mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN); + mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN, 1); mlx5_set_port_proto(mdev, link_modes, MLX5_PTYS_EN); if (ps == MLX5_PORT_UP) - mlx5_set_port_admin_status(mdev, MLX5_PORT_UP); + mlx5_set_port_admin_status(mdev, MLX5_PORT_UP, 1); out: return err; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 5bad17d..6c9fa9f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -1632,9 +1632,12 @@ static int mlx5e_open(struct net_device *netdev) { struct mlx5e_priv *priv = netdev_priv(netdev); int err; + u8 state; mutex_lock(&priv->state_lock); err = mlx5e_open_locked(netdev); + state = err ? MLX5_PORT_DOWN : MLX5_PORT_UP; + mlx5_set_port_admin_status(priv->mdev, state, 1); mutex_unlock(&priv->state_lock); return err; @@ -1666,6 +1669,7 @@ static int mlx5e_close(struct net_device *netdev) int err; mutex_lock(&priv->state_lock); + mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_DOWN, 1); err = mlx5e_close_locked(netdev); mutex_unlock(&priv->state_lock); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 3f3b2fa..6211cc3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -497,6 +497,10 @@ static int handle_hca_cap(struct mlx5_core_dev *dev) MLX5_SET(cmd_hca_cap, set_hca_cap, log_uar_page_sz, PAGE_SHIFT - 12); + /* disable link up by INIT_HCA */ + if (MLX5_CAP_GEN_MAX(dev, disable_link_up)) + MLX5_SET(cmd_hca_cap, set_hca_cap, disable_link_up, 1); + err = set_caps(dev, set_ctx, set_sz, MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c index 4cb2a44..5036e14 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c @@ -223,14 +223,15 @@ int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin, EXPORT_SYMBOL_GPL(mlx5_set_port_proto); int mlx5_set_port_admin_status(struct mlx5_core_dev *dev, - enum mlx5_port_status status) + enum mlx5_port_status status, + u8 port) { u32 in[MLX5_ST_SZ_DW(paos_reg)]; u32 out[MLX5_ST_SZ_DW(paos_reg)]; memset(in, 0, sizeof(in)); - MLX5_SET(paos_reg, in, local_port, 1); + MLX5_SET(paos_reg, in, local_port, port); MLX5_SET(paos_reg, in, admin_status, status); MLX5_SET(paos_reg, in, ase, 1); diff --git a/include/linux/mlx5/port.h b/include/linux/mlx5/port.h index 7391eb8..0656118 100644 --- a/include/linux/mlx5/port.h +++ b/include/linux/mlx5/port.h @@ -68,7 +68,8 @@ int mlx5_query_port_proto_oper(struct mlx5_core_dev *dev, int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin, int proto_mask); int mlx5_set_port_admin_status(struct mlx5_core_dev *dev, - enum mlx5_port_status status); + enum mlx5_port_status status, + u8 port); int mlx5_query_port_admin_status(struct mlx5_core_dev *dev, enum mlx5_port_status *status); int mlx5_set_port_beacon(struct mlx5_core_dev *dev, u16 beacon_duration); -- 1.7.1