net/mlx5e: Unregister netdev before detaching it
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_rep.c
index 134de4a..7fe6559 100644 (file)
@@ -413,19 +413,51 @@ static struct mlx5e_profile mlx5e_rep_profile = {
 int mlx5e_vport_rep_load(struct mlx5_eswitch *esw,
                         struct mlx5_eswitch_rep *rep)
 {
-       rep->priv_data = mlx5e_create_netdev(esw->dev, &mlx5e_rep_profile, rep);
-       if (!rep->priv_data) {
-               pr_warn("Failed to create representor for vport %d\n",
+       struct net_device *netdev;
+       int err;
+
+       netdev = mlx5e_create_netdev(esw->dev, &mlx5e_rep_profile, rep);
+       if (!netdev) {
+               pr_warn("Failed to create representor netdev for vport %d\n",
                        rep->vport);
                return -EINVAL;
        }
+
+       rep->priv_data = netdev_priv(netdev);
+
+       err = mlx5e_attach_netdev(esw->dev, netdev);
+       if (err) {
+               pr_warn("Failed to attach representor netdev for vport %d\n",
+                       rep->vport);
+               goto err_destroy_netdev;
+       }
+
+       err = register_netdev(netdev);
+       if (err) {
+               pr_warn("Failed to register representor netdev for vport %d\n",
+                       rep->vport);
+               goto err_detach_netdev;
+       }
+
        return 0;
+
+err_detach_netdev:
+       mlx5e_detach_netdev(esw->dev, netdev);
+
+err_destroy_netdev:
+       mlx5e_destroy_netdev(esw->dev, rep->priv_data);
+
+       return err;
+
 }
 
 void mlx5e_vport_rep_unload(struct mlx5_eswitch *esw,
                            struct mlx5_eswitch_rep *rep)
 {
        struct mlx5e_priv *priv = rep->priv_data;
+       struct net_device *netdev = priv->netdev;
 
+       unregister_netdev(netdev);
+       mlx5e_detach_netdev(esw->dev, netdev);
        mlx5e_destroy_netdev(esw->dev, priv);
 }