net/mlx5e: Initialize all netdev common structures in one place
[sfrench/cifs-2.6.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_main.c
index 35aca9a8e3d6062ddb49a52173423942f57444c1..d5a7bd49324012b53356b45dd6d33ae226404dfd 100644 (file)
@@ -272,7 +272,7 @@ static void mlx5e_update_ndo_stats(struct mlx5e_priv *priv)
                        mlx5e_stats_grps[i].update_stats(priv);
 }
 
-void mlx5e_update_stats_work(struct work_struct *work)
+static void mlx5e_update_stats_work(struct work_struct *work)
 {
        struct delayed_work *dwork = to_delayed_work(work);
        struct mlx5e_priv *priv = container_of(dwork, struct mlx5e_priv,
@@ -4318,7 +4318,7 @@ static int mlx5e_xdp(struct net_device *dev, struct netdev_bpf *xdp)
        }
 }
 
-static const struct net_device_ops mlx5e_netdev_ops = {
+const struct net_device_ops mlx5e_netdev_ops = {
        .ndo_open                = mlx5e_open,
        .ndo_stop                = mlx5e_close,
        .ndo_start_xmit          = mlx5e_xmit,
@@ -4560,33 +4560,6 @@ void mlx5e_build_nic_params(struct mlx5_core_dev *mdev,
        mlx5e_build_rss_params(params);
 }
 
-static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev,
-                                       struct net_device *netdev,
-                                       const struct mlx5e_profile *profile,
-                                       void *ppriv)
-{
-       struct mlx5e_priv *priv = netdev_priv(netdev);
-
-       priv->mdev        = mdev;
-       priv->netdev      = netdev;
-       priv->profile     = profile;
-       priv->ppriv       = ppriv;
-       priv->msglevel    = MLX5E_MSG_LEVEL;
-       priv->max_opened_tc = 1;
-
-       mlx5e_build_nic_params(mdev, &priv->channels.params,
-                              profile->max_nch(mdev), netdev->mtu);
-
-       mutex_init(&priv->state_lock);
-
-       INIT_WORK(&priv->update_carrier_work, mlx5e_update_carrier_work);
-       INIT_WORK(&priv->set_rx_mode_work, mlx5e_set_rx_mode_work);
-       INIT_WORK(&priv->tx_timeout_work, mlx5e_tx_timeout_work);
-       INIT_DELAYED_WORK(&priv->update_stats_work, mlx5e_update_stats_work);
-
-       mlx5e_timestamp_init(priv);
-}
-
 static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
 {
        struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -4749,15 +4722,23 @@ void mlx5e_destroy_q_counters(struct mlx5e_priv *priv)
                mlx5_core_dealloc_q_counter(priv->mdev, priv->drop_rq_q_counter);
 }
 
-static void mlx5e_nic_init(struct mlx5_core_dev *mdev,
-                          struct net_device *netdev,
-                          const struct mlx5e_profile *profile,
-                          void *ppriv)
+static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
+                         struct net_device *netdev,
+                         const struct mlx5e_profile *profile,
+                         void *ppriv)
 {
        struct mlx5e_priv *priv = netdev_priv(netdev);
        int err;
 
-       mlx5e_build_nic_netdev_priv(mdev, netdev, profile, ppriv);
+       err = mlx5e_netdev_init(netdev, priv, mdev, profile, ppriv);
+       if (err)
+               return err;
+
+       mlx5e_build_nic_params(mdev, &priv->channels.params,
+                              profile->max_nch(mdev), netdev->mtu);
+
+       mlx5e_timestamp_init(priv);
+
        err = mlx5e_ipsec_init(priv);
        if (err)
                mlx5_core_err(mdev, "IPSec initialization failed, %d\n", err);
@@ -4766,12 +4747,15 @@ static void mlx5e_nic_init(struct mlx5_core_dev *mdev,
                mlx5_core_err(mdev, "TLS initialization failed, %d\n", err);
        mlx5e_build_nic_netdev(netdev);
        mlx5e_build_tc2txq_maps(priv);
+
+       return 0;
 }
 
 static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
 {
        mlx5e_tls_cleanup(priv);
        mlx5e_ipsec_cleanup(priv);
+       mlx5e_netdev_cleanup(priv->netdev, priv);
 }
 
 static int mlx5e_init_nic_rx(struct mlx5e_priv *priv)
@@ -4943,13 +4927,53 @@ static const struct mlx5e_profile mlx5e_nic_profile = {
 
 /* 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,
+                     struct mlx5_core_dev *mdev,
+                     const struct mlx5e_profile *profile,
+                     void *ppriv)
+{
+       /* priv init */
+       priv->mdev        = mdev;
+       priv->netdev      = netdev;
+       priv->profile     = profile;
+       priv->ppriv       = ppriv;
+       priv->msglevel    = MLX5E_MSG_LEVEL;
+       priv->max_opened_tc = 1;
+
+       mutex_init(&priv->state_lock);
+       INIT_WORK(&priv->update_carrier_work, mlx5e_update_carrier_work);
+       INIT_WORK(&priv->set_rx_mode_work, mlx5e_set_rx_mode_work);
+       INIT_WORK(&priv->tx_timeout_work, mlx5e_tx_timeout_work);
+       INIT_DELAYED_WORK(&priv->update_stats_work, mlx5e_update_stats_work);
+
+       priv->wq = create_singlethread_workqueue("mlx5e");
+       if (!priv->wq)
+               return -ENOMEM;
+
+       /* netdev init */
+       netif_carrier_off(netdev);
+
+#ifdef CONFIG_MLX5_EN_ARFS
+       netdev->rx_cpu_rmap = mdev->rmap;
+#endif
+
+       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,
                                       const struct mlx5e_profile *profile,
                                       void *ppriv)
 {
        int nch = profile->max_nch(mdev);
        struct net_device *netdev;
-       struct mlx5e_priv *priv;
+       int err;
 
        netdev = alloc_etherdev_mqs(sizeof(struct mlx5e_priv),
                                    nch * profile->max_tc,
@@ -4959,25 +4983,15 @@ struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
                return NULL;
        }
 
-#ifdef CONFIG_MLX5_EN_ARFS
-       netdev->rx_cpu_rmap = mdev->rmap;
-#endif
-
-       profile->init(mdev, netdev, profile, ppriv);
-
-       netif_carrier_off(netdev);
-
-       priv = netdev_priv(netdev);
-
-       priv->wq = create_singlethread_workqueue("mlx5e");
-       if (!priv->wq)
-               goto err_cleanup_nic;
+       err = profile->init(mdev, netdev, profile, ppriv);
+       if (err) {
+               mlx5_core_err(mdev, "failed to init mlx5e profile %d\n", err);
+               goto err_free_netdev;
+       }
 
        return netdev;
 
-err_cleanup_nic:
-       if (profile->cleanup)
-               profile->cleanup(priv);
+err_free_netdev:
        free_netdev(netdev);
 
        return NULL;
@@ -5031,7 +5045,6 @@ void mlx5e_destroy_netdev(struct mlx5e_priv *priv)
        const struct mlx5e_profile *profile = priv->profile;
        struct net_device *netdev = priv->netdev;
 
-       destroy_workqueue(priv->wq);
        if (profile->cleanup)
                profile->cleanup(priv);
        free_netdev(netdev);