net/mlx4_core: Fix error flow in mlx4_init_hca()
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx4 / main.c
index e25436b..03e9eb0 100644 (file)
@@ -171,9 +171,9 @@ int mlx4_check_port_params(struct mlx4_dev *dev,
 {
        int i;
 
-       for (i = 0; i < dev->caps.num_ports - 1; i++) {
-               if (port_type[i] != port_type[i + 1]) {
-                       if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) {
+       if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) {
+               for (i = 0; i < dev->caps.num_ports - 1; i++) {
+                       if (port_type[i] != port_type[i + 1]) {
                                mlx4_err(dev, "Only same port types supported on this HCA, aborting\n");
                                return -EINVAL;
                        }
@@ -305,6 +305,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
                mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting\n");
                return err;
        }
+       mlx4_dev_cap_dump(dev, dev_cap);
 
        if (dev_cap->min_page_sz > PAGE_SIZE) {
                mlx4_err(dev, "HCA minimum page size of %d bigger than kernel PAGE_SIZE of %ld, aborting\n",
@@ -1828,7 +1829,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
                err = mlx4_dev_cap(dev, &dev_cap);
                if (err) {
                        mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting\n");
-                       goto err_stop_fw;
+                       return err;
                }
 
                choose_steering_mode(dev, &dev_cap);
@@ -1859,7 +1860,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
                                             &init_hca);
                if ((long long) icm_size < 0) {
                        err = icm_size;
-                       goto err_stop_fw;
+                       return err;
                }
 
                dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1;
@@ -1873,7 +1874,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
 
                err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size);
                if (err)
-                       goto err_stop_fw;
+                       return err;
 
                err = mlx4_INIT_HCA(dev, &init_hca);
                if (err) {
@@ -1885,7 +1886,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
                        err = mlx4_query_func(dev, &dev_cap);
                        if (err < 0) {
                                mlx4_err(dev, "QUERY_FUNC command failed, aborting.\n");
-                               goto err_stop_fw;
+                               goto err_close;
                        } else if (err & MLX4_QUERY_FUNC_NUM_SYS_EQS) {
                                dev->caps.num_eqs = dev_cap.max_eqs;
                                dev->caps.reserved_eqs = dev_cap.reserved_eqs;
@@ -2005,11 +2006,6 @@ err_free_icm:
        if (!mlx4_is_slave(dev))
                mlx4_free_icms(dev);
 
-err_stop_fw:
-       if (!mlx4_is_slave(dev)) {
-               mlx4_UNMAP_FA(dev);
-               mlx4_free_icm(dev, priv->fw.fw_icm, 0);
-       }
        return err;
 }
 
@@ -2488,41 +2484,42 @@ static u64 mlx4_enable_sriov(struct mlx4_dev *dev, struct pci_dev *pdev,
                             u8 total_vfs, int existing_vfs)
 {
        u64 dev_flags = dev->flags;
+       int err = 0;
+
+       atomic_inc(&pf_loading);
+       if (dev->flags &  MLX4_FLAG_SRIOV) {
+               if (existing_vfs != total_vfs) {
+                       mlx4_err(dev, "SR-IOV was already enabled, but with num_vfs (%d) different than requested (%d)\n",
+                                existing_vfs, total_vfs);
+                       total_vfs = existing_vfs;
+               }
+       }
 
-       dev->dev_vfs = kzalloc(
-                       total_vfs * sizeof(*dev->dev_vfs),
-                       GFP_KERNEL);
+       dev->dev_vfs = kzalloc(total_vfs * sizeof(*dev->dev_vfs), GFP_KERNEL);
        if (NULL == dev->dev_vfs) {
                mlx4_err(dev, "Failed to allocate memory for VFs\n");
                goto disable_sriov;
-       } else if (!(dev->flags &  MLX4_FLAG_SRIOV)) {
-               int err = 0;
-
-               atomic_inc(&pf_loading);
-               if (existing_vfs) {
-                       if (existing_vfs != total_vfs)
-                               mlx4_err(dev, "SR-IOV was already enabled, but with num_vfs (%d) different than requested (%d)\n",
-                                        existing_vfs, total_vfs);
-               } else {
-                       mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", total_vfs);
-                       err = pci_enable_sriov(pdev, total_vfs);
-               }
-               if (err) {
-                       mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d)\n",
-                                err);
-                       atomic_dec(&pf_loading);
-                       goto disable_sriov;
-               } else {
-                       mlx4_warn(dev, "Running in master mode\n");
-                       dev_flags |= MLX4_FLAG_SRIOV |
-                               MLX4_FLAG_MASTER;
-                       dev_flags &= ~MLX4_FLAG_SLAVE;
-                       dev->num_vfs = total_vfs;
-               }
+       }
+
+       if (!(dev->flags &  MLX4_FLAG_SRIOV)) {
+               mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", total_vfs);
+               err = pci_enable_sriov(pdev, total_vfs);
+       }
+       if (err) {
+               mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d)\n",
+                        err);
+               goto disable_sriov;
+       } else {
+               mlx4_warn(dev, "Running in master mode\n");
+               dev_flags |= MLX4_FLAG_SRIOV |
+                       MLX4_FLAG_MASTER;
+               dev_flags &= ~MLX4_FLAG_SLAVE;
+               dev->num_vfs = total_vfs;
        }
        return dev_flags;
 
 disable_sriov:
+       atomic_dec(&pf_loading);
        dev->num_vfs = 0;
        kfree(dev->dev_vfs);
        return dev_flags & ~MLX4_FLAG_MASTER;
@@ -2606,8 +2603,10 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
                }
 
                if (total_vfs) {
-                       existing_vfs = pci_num_vf(pdev);
                        dev->flags = MLX4_FLAG_MASTER;
+                       existing_vfs = pci_num_vf(pdev);
+                       if (existing_vfs)
+                               dev->flags |= MLX4_FLAG_SRIOV;
                        dev->num_vfs = total_vfs;
                }
        }
@@ -2643,6 +2642,7 @@ slave_start:
        }
 
        if (mlx4_is_master(dev)) {
+               /* when we hit the goto slave_start below, dev_cap already initialized */
                if (!dev_cap) {
                        dev_cap = kzalloc(sizeof(*dev_cap), GFP_KERNEL);
 
@@ -2849,6 +2849,7 @@ slave_start:
        if (mlx4_is_master(dev) && dev->num_vfs)
                atomic_dec(&pf_loading);
 
+       kfree(dev_cap);
        return 0;
 
 err_port: