Commit 182570b2 authored by Feras Daoud's avatar Feras Daoud Committed by Saeed Mahameed

net/mlx5e: Gather common netdev init/cleanup functionality in one place

Introduce a helper init/cleanup function that initializes mlx5e generic
netdev private structure, and use them from all profiles init/cleanup
callbacks.

This patch will also be helpful to initialize/cleanup netdevs that are
not created by mlx5 driver, e.g: accelerated ipoib child netdevs.

Fixes: 26e59d80 ("net/mlx5e: Implement mlx5e interface attach/detach callbacks")
Signed-off-by: default avatarFeras Daoud <ferasda@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 5d6b0cb3
...@@ -698,7 +698,7 @@ struct mlx5e_priv { ...@@ -698,7 +698,7 @@ struct mlx5e_priv {
}; };
struct mlx5e_profile { struct mlx5e_profile {
void (*init)(struct mlx5_core_dev *mdev, int (*init)(struct mlx5_core_dev *mdev,
struct net_device *netdev, struct net_device *netdev,
const struct mlx5e_profile *profile, void *ppriv); const struct mlx5e_profile *profile, void *ppriv);
void (*cleanup)(struct mlx5e_priv *priv); void (*cleanup)(struct mlx5e_priv *priv);
...@@ -962,6 +962,8 @@ int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv, ...@@ -962,6 +962,8 @@ int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
struct ethtool_flash *flash); struct ethtool_flash *flash);
/* mlx5e generic netdev management API */ /* mlx5e generic netdev management API */
int mlx5e_netdev_init(struct net_device *netdev, struct mlx5e_priv *priv);
void mlx5e_netdev_cleanup(struct net_device *netdev, struct mlx5e_priv *priv);
struct net_device* struct net_device*
mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile, mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile,
void *ppriv); void *ppriv);
......
...@@ -4749,7 +4749,7 @@ void mlx5e_destroy_q_counters(struct mlx5e_priv *priv) ...@@ -4749,7 +4749,7 @@ void mlx5e_destroy_q_counters(struct mlx5e_priv *priv)
mlx5_core_dealloc_q_counter(priv->mdev, priv->drop_rq_q_counter); mlx5_core_dealloc_q_counter(priv->mdev, priv->drop_rq_q_counter);
} }
static void mlx5e_nic_init(struct mlx5_core_dev *mdev, static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
struct net_device *netdev, struct net_device *netdev,
const struct mlx5e_profile *profile, const struct mlx5e_profile *profile,
void *ppriv) void *ppriv)
...@@ -4757,6 +4757,10 @@ static void mlx5e_nic_init(struct mlx5_core_dev *mdev, ...@@ -4757,6 +4757,10 @@ static void mlx5e_nic_init(struct mlx5_core_dev *mdev,
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(netdev);
int err; int err;
err = mlx5e_netdev_init(netdev, priv);
if (err)
return err;
mlx5e_build_nic_netdev_priv(mdev, netdev, profile, ppriv); mlx5e_build_nic_netdev_priv(mdev, netdev, profile, ppriv);
err = mlx5e_ipsec_init(priv); err = mlx5e_ipsec_init(priv);
if (err) if (err)
...@@ -4766,12 +4770,15 @@ static void mlx5e_nic_init(struct mlx5_core_dev *mdev, ...@@ -4766,12 +4770,15 @@ static void mlx5e_nic_init(struct mlx5_core_dev *mdev,
mlx5_core_err(mdev, "TLS initialization failed, %d\n", err); mlx5_core_err(mdev, "TLS initialization failed, %d\n", err);
mlx5e_build_nic_netdev(netdev); mlx5e_build_nic_netdev(netdev);
mlx5e_build_tc2txq_maps(priv); mlx5e_build_tc2txq_maps(priv);
return 0;
} }
static void mlx5e_nic_cleanup(struct mlx5e_priv *priv) static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
{ {
mlx5e_tls_cleanup(priv); mlx5e_tls_cleanup(priv);
mlx5e_ipsec_cleanup(priv); mlx5e_ipsec_cleanup(priv);
mlx5e_netdev_cleanup(priv->netdev, priv);
} }
static int mlx5e_init_nic_rx(struct mlx5e_priv *priv) static int mlx5e_init_nic_rx(struct mlx5e_priv *priv)
...@@ -4943,13 +4950,30 @@ static const struct mlx5e_profile mlx5e_nic_profile = { ...@@ -4943,13 +4950,30 @@ static const struct mlx5e_profile mlx5e_nic_profile = {
/* mlx5e generic netdev management API (move to en_common.c) */ /* mlx5e generic netdev management API (move to en_common.c) */
/* mlx5e_netdev_init/cleanup must be called from profile->init/cleanup callbacks */
int mlx5e_netdev_init(struct net_device *netdev, struct mlx5e_priv *priv)
{
netif_carrier_off(netdev);
priv->wq = create_singlethread_workqueue("mlx5e");
if (!priv->wq)
return -ENOMEM;
return 0;
}
void mlx5e_netdev_cleanup(struct net_device *netdev, struct mlx5e_priv *priv)
{
destroy_workqueue(priv->wq);
}
struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev, struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
const struct mlx5e_profile *profile, const struct mlx5e_profile *profile,
void *ppriv) void *ppriv)
{ {
int nch = profile->max_nch(mdev); int nch = profile->max_nch(mdev);
struct net_device *netdev; struct net_device *netdev;
struct mlx5e_priv *priv; int err;
netdev = alloc_etherdev_mqs(sizeof(struct mlx5e_priv), netdev = alloc_etherdev_mqs(sizeof(struct mlx5e_priv),
nch * profile->max_tc, nch * profile->max_tc,
...@@ -4963,21 +4987,15 @@ struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev, ...@@ -4963,21 +4987,15 @@ struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
netdev->rx_cpu_rmap = mdev->rmap; netdev->rx_cpu_rmap = mdev->rmap;
#endif #endif
profile->init(mdev, netdev, profile, ppriv); err = profile->init(mdev, netdev, profile, ppriv);
if (err) {
netif_carrier_off(netdev); mlx5_core_err(mdev, "failed to init mlx5e profile %d\n", err);
goto err_free_netdev;
priv = netdev_priv(netdev); }
priv->wq = create_singlethread_workqueue("mlx5e");
if (!priv->wq)
goto err_cleanup_nic;
return netdev; return netdev;
err_cleanup_nic: err_free_netdev:
if (profile->cleanup)
profile->cleanup(priv);
free_netdev(netdev); free_netdev(netdev);
return NULL; return NULL;
...@@ -5031,7 +5049,6 @@ void mlx5e_destroy_netdev(struct mlx5e_priv *priv) ...@@ -5031,7 +5049,6 @@ void mlx5e_destroy_netdev(struct mlx5e_priv *priv)
const struct mlx5e_profile *profile = priv->profile; const struct mlx5e_profile *profile = priv->profile;
struct net_device *netdev = priv->netdev; struct net_device *netdev = priv->netdev;
destroy_workqueue(priv->wq);
if (profile->cleanup) if (profile->cleanup)
profile->cleanup(priv); profile->cleanup(priv);
free_netdev(netdev); free_netdev(netdev);
......
...@@ -1078,28 +1078,40 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev) ...@@ -1078,28 +1078,40 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev)
netdev->max_mtu = MLX5E_HW2SW_MTU(&priv->channels.params, max_mtu); netdev->max_mtu = MLX5E_HW2SW_MTU(&priv->channels.params, max_mtu);
} }
static void mlx5e_init_rep(struct mlx5_core_dev *mdev, static int mlx5e_init_rep(struct mlx5_core_dev *mdev,
struct net_device *netdev, struct net_device *netdev,
const struct mlx5e_profile *profile, const struct mlx5e_profile *profile,
void *ppriv) void *ppriv)
{ {
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(netdev);
int err;
priv->mdev = mdev; priv->mdev = mdev;
priv->netdev = netdev; priv->netdev = netdev;
priv->profile = profile; priv->profile = profile;
priv->ppriv = ppriv; priv->ppriv = ppriv;
mutex_init(&priv->state_lock); err = mlx5e_netdev_init(netdev, priv);
if (err)
return err;
INIT_DELAYED_WORK(&priv->update_stats_work, mlx5e_update_stats_work); INIT_DELAYED_WORK(&priv->update_stats_work, mlx5e_update_stats_work);
priv->channels.params.num_channels = 1; mutex_init(&priv->state_lock);
priv->channels.params.num_channels = profile->max_nch(mdev);
mlx5e_build_rep_params(mdev, &priv->channels.params, netdev->mtu); mlx5e_build_rep_params(mdev, &priv->channels.params, netdev->mtu);
mlx5e_build_rep_netdev(netdev); mlx5e_build_rep_netdev(netdev);
mlx5e_timestamp_init(priv); mlx5e_timestamp_init(priv);
return 0;
}
static void mlx5e_cleanup_rep(struct mlx5e_priv *priv)
{
mlx5e_netdev_cleanup(priv->netdev, priv);
} }
static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv) static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv)
...@@ -1224,6 +1236,7 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv) ...@@ -1224,6 +1236,7 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
static const struct mlx5e_profile mlx5e_rep_profile = { static const struct mlx5e_profile mlx5e_rep_profile = {
.init = mlx5e_init_rep, .init = mlx5e_init_rep,
.cleanup = mlx5e_cleanup_rep,
.init_rx = mlx5e_init_rep_rx, .init_rx = mlx5e_init_rep_rx,
.cleanup_rx = mlx5e_cleanup_rep_rx, .cleanup_rx = mlx5e_cleanup_rep_rx,
.init_tx = mlx5e_init_rep_tx, .init_tx = mlx5e_init_rep_tx,
......
...@@ -71,13 +71,14 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev, ...@@ -71,13 +71,14 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev,
} }
/* Called directly after IPoIB netdevice was created to initialize SW structs */ /* Called directly after IPoIB netdevice was created to initialize SW structs */
void mlx5i_init(struct mlx5_core_dev *mdev, int mlx5i_init(struct mlx5_core_dev *mdev,
struct net_device *netdev, struct net_device *netdev,
const struct mlx5e_profile *profile, const struct mlx5e_profile *profile,
void *ppriv) void *ppriv)
{ {
struct mlx5e_priv *priv = mlx5i_epriv(netdev); struct mlx5e_priv *priv = mlx5i_epriv(netdev);
u16 max_mtu; u16 max_mtu;
int err;
/* priv init */ /* priv init */
priv->mdev = mdev; priv->mdev = mdev;
...@@ -87,6 +88,10 @@ void mlx5i_init(struct mlx5_core_dev *mdev, ...@@ -87,6 +88,10 @@ void mlx5i_init(struct mlx5_core_dev *mdev,
priv->max_opened_tc = 1; priv->max_opened_tc = 1;
mutex_init(&priv->state_lock); mutex_init(&priv->state_lock);
err = mlx5e_netdev_init(netdev, priv);
if (err)
return err;
mlx5_query_port_max_mtu(mdev, &max_mtu, 1); mlx5_query_port_max_mtu(mdev, &max_mtu, 1);
netdev->mtu = max_mtu; netdev->mtu = max_mtu;
...@@ -108,12 +113,14 @@ void mlx5i_init(struct mlx5_core_dev *mdev, ...@@ -108,12 +113,14 @@ void mlx5i_init(struct mlx5_core_dev *mdev,
netdev->netdev_ops = &mlx5i_netdev_ops; netdev->netdev_ops = &mlx5i_netdev_ops;
netdev->ethtool_ops = &mlx5i_ethtool_ops; netdev->ethtool_ops = &mlx5i_ethtool_ops;
return 0;
} }
/* Called directly before IPoIB netdevice is destroyed to cleanup SW structs */ /* Called directly before IPoIB netdevice is destroyed to cleanup SW structs */
static void mlx5i_cleanup(struct mlx5e_priv *priv) void mlx5i_cleanup(struct mlx5e_priv *priv)
{ {
/* Do nothing .. */ mlx5e_netdev_cleanup(priv->netdev, priv);
} }
static void mlx5i_grp_sw_update_stats(struct mlx5e_priv *priv) static void mlx5i_grp_sw_update_stats(struct mlx5e_priv *priv)
...@@ -650,7 +657,6 @@ static void mlx5_rdma_netdev_free(struct net_device *netdev) ...@@ -650,7 +657,6 @@ static void mlx5_rdma_netdev_free(struct net_device *netdev)
mlx5e_detach_netdev(priv); mlx5e_detach_netdev(priv);
profile->cleanup(priv); profile->cleanup(priv);
destroy_workqueue(priv->wq);
if (!ipriv->sub_interface) { if (!ipriv->sub_interface) {
mlx5i_pkey_qpn_ht_cleanup(netdev); mlx5i_pkey_qpn_ht_cleanup(netdev);
...@@ -683,16 +689,12 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u8 port_num, ...@@ -683,16 +689,12 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u8 port_num,
ipriv = netdev_priv(netdev); ipriv = netdev_priv(netdev);
epriv = mlx5i_epriv(netdev); epriv = mlx5i_epriv(netdev);
epriv->wq = create_singlethread_workqueue("mlx5i");
if (!epriv->wq)
return -ENOMEM;
ipriv->sub_interface = mlx5_is_sub_interface(mdev); ipriv->sub_interface = mlx5_is_sub_interface(mdev);
if (!ipriv->sub_interface) { if (!ipriv->sub_interface) {
err = mlx5i_pkey_qpn_ht_init(netdev); err = mlx5i_pkey_qpn_ht_init(netdev);
if (err) { if (err) {
mlx5_core_warn(mdev, "allocate qpn_to_netdev ht failed\n"); mlx5_core_warn(mdev, "allocate qpn_to_netdev ht failed\n");
goto destroy_wq; return err;
} }
/* This should only be called once per mdev */ /* This should only be called once per mdev */
...@@ -721,8 +723,6 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u8 port_num, ...@@ -721,8 +723,6 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u8 port_num,
destroy_ht: destroy_ht:
mlx5i_pkey_qpn_ht_cleanup(netdev); mlx5i_pkey_qpn_ht_cleanup(netdev);
destroy_wq:
destroy_workqueue(epriv->wq);
return err; return err;
} }
......
...@@ -84,10 +84,11 @@ void mlx5i_dev_cleanup(struct net_device *dev); ...@@ -84,10 +84,11 @@ void mlx5i_dev_cleanup(struct net_device *dev);
int mlx5i_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); int mlx5i_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
/* Parent profile functions */ /* Parent profile functions */
void mlx5i_init(struct mlx5_core_dev *mdev, int mlx5i_init(struct mlx5_core_dev *mdev,
struct net_device *netdev, struct net_device *netdev,
const struct mlx5e_profile *profile, const struct mlx5e_profile *profile,
void *ppriv); void *ppriv);
void mlx5i_cleanup(struct mlx5e_priv *priv);
/* Get child interface nic profile */ /* Get child interface nic profile */
const struct mlx5e_profile *mlx5i_pkey_get_profile(void); const struct mlx5e_profile *mlx5i_pkey_get_profile(void);
......
...@@ -275,14 +275,17 @@ static int mlx5i_pkey_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -275,14 +275,17 @@ static int mlx5i_pkey_change_mtu(struct net_device *netdev, int new_mtu)
} }
/* Called directly after IPoIB netdevice was created to initialize SW structs */ /* Called directly after IPoIB netdevice was created to initialize SW structs */
static void mlx5i_pkey_init(struct mlx5_core_dev *mdev, static int mlx5i_pkey_init(struct mlx5_core_dev *mdev,
struct net_device *netdev, struct net_device *netdev,
const struct mlx5e_profile *profile, const struct mlx5e_profile *profile,
void *ppriv) void *ppriv)
{ {
struct mlx5e_priv *priv = mlx5i_epriv(netdev); struct mlx5e_priv *priv = mlx5i_epriv(netdev);
int err;
mlx5i_init(mdev, netdev, profile, ppriv); err = mlx5i_init(mdev, netdev, profile, ppriv);
if (err)
return err;
/* Override parent ndo */ /* Override parent ndo */
netdev->netdev_ops = &mlx5i_pkey_netdev_ops; netdev->netdev_ops = &mlx5i_pkey_netdev_ops;
...@@ -292,12 +295,14 @@ static void mlx5i_pkey_init(struct mlx5_core_dev *mdev, ...@@ -292,12 +295,14 @@ static void mlx5i_pkey_init(struct mlx5_core_dev *mdev,
/* Use dummy rqs */ /* Use dummy rqs */
priv->channels.params.log_rq_mtu_frames = MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE; priv->channels.params.log_rq_mtu_frames = MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE;
return 0;
} }
/* Called directly before IPoIB netdevice is destroyed to cleanup SW structs */ /* Called directly before IPoIB netdevice is destroyed to cleanup SW structs */
static void mlx5i_pkey_cleanup(struct mlx5e_priv *priv) static void mlx5i_pkey_cleanup(struct mlx5e_priv *priv)
{ {
/* Do nothing .. */ mlx5i_cleanup(priv);
} }
static int mlx5i_pkey_init_tx(struct mlx5e_priv *priv) static int mlx5i_pkey_init_tx(struct mlx5e_priv *priv)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment