mlx4: Add infrastructure for selecting VFs to enable QP0 via MLX proxy QPs
[linux-2.6-block.git] / drivers / net / ethernet / mellanox / mlx4 / main.c
index cef267e24f9c9c680613ec4ed2817c040b21c964..908326876ab5de176fff9f13d84b891c1486f33d 100644 (file)
@@ -666,13 +666,15 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
                return -ENODEV;
        }
 
+       dev->caps.qp0_qkey = kcalloc(dev->caps.num_ports, sizeof(u32), GFP_KERNEL);
        dev->caps.qp0_tunnel = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL);
        dev->caps.qp0_proxy = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL);
        dev->caps.qp1_tunnel = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL);
        dev->caps.qp1_proxy = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL);
 
        if (!dev->caps.qp0_tunnel || !dev->caps.qp0_proxy ||
-           !dev->caps.qp1_tunnel || !dev->caps.qp1_proxy) {
+           !dev->caps.qp1_tunnel || !dev->caps.qp1_proxy ||
+           !dev->caps.qp0_qkey) {
                err = -ENOMEM;
                goto err_mem;
        }
@@ -684,6 +686,7 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
                                 " port %d, aborting (%d).\n", i, err);
                        goto err_mem;
                }
+               dev->caps.qp0_qkey[i - 1] = func_cap.qp0_qkey;
                dev->caps.qp0_tunnel[i - 1] = func_cap.qp0_tunnel_qpn;
                dev->caps.qp0_proxy[i - 1] = func_cap.qp0_proxy_qpn;
                dev->caps.qp1_tunnel[i - 1] = func_cap.qp1_tunnel_qpn;
@@ -729,12 +732,16 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
        return 0;
 
 err_mem:
+       kfree(dev->caps.qp0_qkey);
        kfree(dev->caps.qp0_tunnel);
        kfree(dev->caps.qp0_proxy);
        kfree(dev->caps.qp1_tunnel);
        kfree(dev->caps.qp1_proxy);
-       dev->caps.qp0_tunnel = dev->caps.qp0_proxy =
-               dev->caps.qp1_tunnel = dev->caps.qp1_proxy = NULL;
+       dev->caps.qp0_qkey = NULL;
+       dev->caps.qp0_tunnel = NULL;
+       dev->caps.qp0_proxy = NULL;
+       dev->caps.qp1_tunnel = NULL;
+       dev->caps.qp1_proxy = NULL;
 
        return err;
 }
@@ -754,10 +761,10 @@ static void mlx4_request_modules(struct mlx4_dev *dev)
                        has_eth_port = true;
        }
 
-       if (has_ib_port || (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE))
-               request_module_nowait(IB_DRV_NAME);
        if (has_eth_port)
                request_module_nowait(EN_DRV_NAME);
+       if (has_ib_port || (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE))
+               request_module_nowait(IB_DRV_NAME);
 }
 
 /*
@@ -1696,6 +1703,14 @@ unmap_bf:
        unmap_internal_clock(dev);
        unmap_bf_area(dev);
 
+       if (mlx4_is_slave(dev)) {
+               kfree(dev->caps.qp0_qkey);
+               kfree(dev->caps.qp0_tunnel);
+               kfree(dev->caps.qp0_proxy);
+               kfree(dev->caps.qp1_tunnel);
+               kfree(dev->caps.qp1_proxy);
+       }
+
 err_close:
        if (mlx4_is_slave(dev))
                mlx4_slave_exit(dev);
@@ -2440,7 +2455,8 @@ slave_start:
         * No return code for this call, just warn the user in case of PCI
         * express device capabilities are under-satisfied by the bus.
         */
-       mlx4_check_pcie_caps(dev);
+       if (!mlx4_is_slave(dev))
+               mlx4_check_pcie_caps(dev);
 
        /* In master functions, the communication channel must be initialized
         * after obtaining its address from fw */
@@ -2564,6 +2580,14 @@ err_master_mfunc:
        if (mlx4_is_master(dev))
                mlx4_multi_func_cleanup(dev);
 
+       if (mlx4_is_slave(dev)) {
+               kfree(dev->caps.qp0_qkey);
+               kfree(dev->caps.qp0_tunnel);
+               kfree(dev->caps.qp0_proxy);
+               kfree(dev->caps.qp1_tunnel);
+               kfree(dev->caps.qp1_proxy);
+       }
+
 err_close:
        if (dev->flags & MLX4_FLAG_MSI_X)
                pci_disable_msix(pdev);
@@ -2687,6 +2711,7 @@ static void __mlx4_remove_one(struct pci_dev *pdev)
        if (!mlx4_is_slave(dev))
                mlx4_free_ownership(dev);
 
+       kfree(dev->caps.qp0_qkey);
        kfree(dev->caps.qp0_tunnel);
        kfree(dev->caps.qp0_proxy);
        kfree(dev->caps.qp1_tunnel);