net/mlx5e: Initialize all netdev common structures in one place
[sfrench/cifs-2.6.git] / drivers / net / ethernet / mellanox / mlx5 / core / ipoib / ipoib.c
index 299e2a897f7ed0b9098adc15864cb8fb63ceeda2..ed28602c98f65a9cbe9e2cc1939a59749e523c03 100644 (file)
@@ -71,21 +71,18 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev,
 }
 
 /* Called directly after IPoIB netdevice was created to initialize SW structs */
-void mlx5i_init(struct mlx5_core_dev *mdev,
-               struct net_device *netdev,
-               const struct mlx5e_profile *profile,
-               void *ppriv)
+int mlx5i_init(struct mlx5_core_dev *mdev,
+              struct net_device *netdev,
+              const struct mlx5e_profile *profile,
+              void *ppriv)
 {
        struct mlx5e_priv *priv  = mlx5i_epriv(netdev);
        u16 max_mtu;
+       int err;
 
-       /* priv init */
-       priv->mdev        = mdev;
-       priv->netdev      = netdev;
-       priv->profile     = profile;
-       priv->ppriv       = ppriv;
-       priv->max_opened_tc = 1;
-       mutex_init(&priv->state_lock);
+       err = mlx5e_netdev_init(netdev, priv, mdev, profile, ppriv);
+       if (err)
+               return err;
 
        mlx5_query_port_max_mtu(mdev, &max_mtu, 1);
        netdev->mtu = max_mtu;
@@ -108,12 +105,14 @@ void mlx5i_init(struct mlx5_core_dev *mdev,
 
        netdev->netdev_ops = &mlx5i_netdev_ops;
        netdev->ethtool_ops = &mlx5i_ethtool_ops;
+
+       return 0;
 }
 
 /* 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)
@@ -650,7 +649,6 @@ static void mlx5_rdma_netdev_free(struct net_device *netdev)
 
        mlx5e_detach_netdev(priv);
        profile->cleanup(priv);
-       destroy_workqueue(priv->wq);
 
        if (!ipriv->sub_interface) {
                mlx5i_pkey_qpn_ht_cleanup(netdev);
@@ -658,58 +656,37 @@ static void mlx5_rdma_netdev_free(struct net_device *netdev)
        }
 }
 
-struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
-                                         struct ib_device *ibdev,
-                                         const char *name,
-                                         void (*setup)(struct net_device *))
+static bool mlx5_is_sub_interface(struct mlx5_core_dev *mdev)
+{
+       return mdev->mlx5e_res.pdn != 0;
+}
+
+static const struct mlx5e_profile *mlx5_get_profile(struct mlx5_core_dev *mdev)
 {
-       const struct mlx5e_profile *profile;
-       struct net_device *netdev;
+       if (mlx5_is_sub_interface(mdev))
+               return mlx5i_pkey_get_profile();
+       return &mlx5i_nic_profile;
+}
+
+static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u8 port_num,
+                             struct net_device *netdev, void *param)
+{
+       struct mlx5_core_dev *mdev = (struct mlx5_core_dev *)param;
+       const struct mlx5e_profile *prof = mlx5_get_profile(mdev);
        struct mlx5i_priv *ipriv;
        struct mlx5e_priv *epriv;
        struct rdma_netdev *rn;
-       bool sub_interface;
-       int nch;
        int err;
 
-       if (mlx5i_check_required_hca_cap(mdev)) {
-               mlx5_core_warn(mdev, "Accelerated mode is not supported\n");
-               return ERR_PTR(-EOPNOTSUPP);
-       }
-
-       /* TODO: Need to find a better way to check if child device*/
-       sub_interface = (mdev->mlx5e_res.pdn != 0);
-
-       if (sub_interface)
-               profile = mlx5i_pkey_get_profile();
-       else
-               profile = &mlx5i_nic_profile;
-
-       nch = profile->max_nch(mdev);
-
-       netdev = alloc_netdev_mqs(sizeof(struct mlx5i_priv) + sizeof(struct mlx5e_priv),
-                                 name, NET_NAME_UNKNOWN,
-                                 setup,
-                                 nch * MLX5E_MAX_NUM_TC,
-                                 nch);
-       if (!netdev) {
-               mlx5_core_warn(mdev, "alloc_netdev_mqs failed\n");
-               return NULL;
-       }
-
        ipriv = netdev_priv(netdev);
        epriv = mlx5i_epriv(netdev);
 
-       epriv->wq = create_singlethread_workqueue("mlx5i");
-       if (!epriv->wq)
-               goto err_free_netdev;
-
-       ipriv->sub_interface = sub_interface;
+       ipriv->sub_interface = mlx5_is_sub_interface(mdev);
        if (!ipriv->sub_interface) {
                err = mlx5i_pkey_qpn_ht_init(netdev);
                if (err) {
                        mlx5_core_warn(mdev, "allocate qpn_to_netdev ht failed\n");
-                       goto destroy_wq;
+                       return err;
                }
 
                /* This should only be called once per mdev */
@@ -718,7 +695,7 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
                        goto destroy_ht;
        }
 
-       profile->init(mdev, netdev, profile, ipriv);
+       prof->init(mdev, netdev, prof, ipriv);
 
        mlx5e_attach_netdev(epriv);
        netif_carrier_off(netdev);
@@ -734,15 +711,35 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
        netdev->priv_destructor = mlx5_rdma_netdev_free;
        netdev->needs_free_netdev = 1;
 
-       return netdev;
+       return 0;
 
 destroy_ht:
        mlx5i_pkey_qpn_ht_cleanup(netdev);
-destroy_wq:
-       destroy_workqueue(epriv->wq);
-err_free_netdev:
-       free_netdev(netdev);
+       return err;
+}
 
-       return NULL;
+int mlx5_rdma_rn_get_params(struct mlx5_core_dev *mdev,
+                           struct ib_device *device,
+                           struct rdma_netdev_alloc_params *params)
+{
+       int nch;
+       int rc;
+
+       rc = mlx5i_check_required_hca_cap(mdev);
+       if (rc)
+               return rc;
+
+       nch = mlx5_get_profile(mdev)->max_nch(mdev);
+
+       *params = (struct rdma_netdev_alloc_params){
+               .sizeof_priv = sizeof(struct mlx5i_priv) +
+                              sizeof(struct mlx5e_priv),
+               .txqs = nch * MLX5E_MAX_NUM_TC,
+               .rxqs = nch,
+               .param = mdev,
+               .initialize_rdma_netdev = mlx5_rdma_setup_rn,
+       };
+
+       return 0;
 }
-EXPORT_SYMBOL(mlx5_rdma_netdev_alloc);
+EXPORT_SYMBOL(mlx5_rdma_rn_get_params);