]> Pileus Git - ~andy/linux/blobdiff - drivers/net/ethernet/mellanox/mlx4/main.c
Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[~andy/linux] / drivers / net / ethernet / mellanox / mlx4 / main.c
index 01fc6515384db04fe03d548db8c16f8952f211e4..936c15364739171993bfcb52598bd03f5be8afb6 100644 (file)
@@ -96,10 +96,10 @@ MODULE_PARM_DESC(log_num_mgm_entry_size, "log mgm size, that defines the num"
                                         " To activate device managed"
                                         " flow steering when available, set to -1");
 
-static bool enable_64b_cqe_eqe;
+static bool enable_64b_cqe_eqe = true;
 module_param(enable_64b_cqe_eqe, bool, 0444);
 MODULE_PARM_DESC(enable_64b_cqe_eqe,
-                "Enable 64 byte CQEs/EQEs when the FW supports this");
+                "Enable 64 byte CQEs/EQEs when the FW supports this (default: True)");
 
 #define HCA_GLOBAL_CAP_MASK            0
 
@@ -150,6 +150,8 @@ struct mlx4_port_config {
        struct pci_dev *pdev;
 };
 
+static atomic_t pf_loading = ATOMIC_INIT(0);
+
 int mlx4_check_port_params(struct mlx4_dev *dev,
                           enum mlx4_port_type *port_type)
 {
@@ -388,6 +390,84 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
 
        return 0;
 }
+
+static int mlx4_get_pcie_dev_link_caps(struct mlx4_dev *dev,
+                                      enum pci_bus_speed *speed,
+                                      enum pcie_link_width *width)
+{
+       u32 lnkcap1, lnkcap2;
+       int err1, err2;
+
+#define  PCIE_MLW_CAP_SHIFT 4  /* start of MLW mask in link capabilities */
+
+       *speed = PCI_SPEED_UNKNOWN;
+       *width = PCIE_LNK_WIDTH_UNKNOWN;
+
+       err1 = pcie_capability_read_dword(dev->pdev, PCI_EXP_LNKCAP, &lnkcap1);
+       err2 = pcie_capability_read_dword(dev->pdev, PCI_EXP_LNKCAP2, &lnkcap2);
+       if (!err2 && lnkcap2) { /* PCIe r3.0-compliant */
+               if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB)
+                       *speed = PCIE_SPEED_8_0GT;
+               else if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB)
+                       *speed = PCIE_SPEED_5_0GT;
+               else if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_2_5GB)
+                       *speed = PCIE_SPEED_2_5GT;
+       }
+       if (!err1) {
+               *width = (lnkcap1 & PCI_EXP_LNKCAP_MLW) >> PCIE_MLW_CAP_SHIFT;
+               if (!lnkcap2) { /* pre-r3.0 */
+                       if (lnkcap1 & PCI_EXP_LNKCAP_SLS_5_0GB)
+                               *speed = PCIE_SPEED_5_0GT;
+                       else if (lnkcap1 & PCI_EXP_LNKCAP_SLS_2_5GB)
+                               *speed = PCIE_SPEED_2_5GT;
+               }
+       }
+
+       if (*speed == PCI_SPEED_UNKNOWN || *width == PCIE_LNK_WIDTH_UNKNOWN) {
+               return err1 ? err1 :
+                       err2 ? err2 : -EINVAL;
+       }
+       return 0;
+}
+
+static void mlx4_check_pcie_caps(struct mlx4_dev *dev)
+{
+       enum pcie_link_width width, width_cap;
+       enum pci_bus_speed speed, speed_cap;
+       int err;
+
+#define PCIE_SPEED_STR(speed) \
+       (speed == PCIE_SPEED_8_0GT ? "8.0GT/s" : \
+        speed == PCIE_SPEED_5_0GT ? "5.0GT/s" : \
+        speed == PCIE_SPEED_2_5GT ? "2.5GT/s" : \
+        "Unknown")
+
+       err = mlx4_get_pcie_dev_link_caps(dev, &speed_cap, &width_cap);
+       if (err) {
+               mlx4_warn(dev,
+                         "Unable to determine PCIe device BW capabilities\n");
+               return;
+       }
+
+       err = pcie_get_minimum_link(dev->pdev, &speed, &width);
+       if (err || speed == PCI_SPEED_UNKNOWN ||
+           width == PCIE_LNK_WIDTH_UNKNOWN) {
+               mlx4_warn(dev,
+                         "Unable to determine PCI device chain minimum BW\n");
+               return;
+       }
+
+       if (width != width_cap || speed != speed_cap)
+               mlx4_warn(dev,
+                         "PCIe BW is different than device's capability\n");
+
+       mlx4_info(dev, "PCIe link speed is %s, device supports %s\n",
+                 PCIE_SPEED_STR(speed), PCIE_SPEED_STR(speed_cap));
+       mlx4_info(dev, "PCIe link width is x%d, device supports x%d\n",
+                 width, width_cap);
+       return;
+}
+
 /*The function checks if there are live vf, return the num of them*/
 static int mlx4_how_many_lives_vf(struct mlx4_dev *dev)
 {
@@ -606,6 +686,7 @@ static int mlx4_slave_cap(struct mlx4_dev *dev)
                dev->caps.qp1_tunnel[i - 1] = func_cap.qp1_tunnel_qpn;
                dev->caps.qp1_proxy[i - 1] = func_cap.qp1_proxy_qpn;
                dev->caps.port_mask[i] = dev->caps.port_type[i];
+               dev->caps.phys_port_id[i] = func_cap.phys_port_id;
                if (mlx4_get_slave_pkey_gid_tbl_len(dev, i,
                                                    &dev->caps.gid_table_len[i],
                                                    &dev->caps.pkey_table_len[i]))
@@ -670,7 +751,7 @@ static void mlx4_request_modules(struct mlx4_dev *dev)
                        has_eth_port = true;
        }
 
-       if (has_ib_port)
+       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);
@@ -1328,6 +1409,11 @@ static int mlx4_init_slave(struct mlx4_dev *dev)
        u32 slave_read;
        u32 cmd_channel_ver;
 
+       if (atomic_read(&pf_loading)) {
+               mlx4_warn(dev, "PF is not ready. Deferring probe\n");
+               return -EPROBE_DEFER;
+       }
+
        mutex_lock(&priv->cmd.slave_cmd_mutex);
        priv->cmd.max_cmds = 1;
        mlx4_warn(dev, "Sending reset\n");
@@ -1443,6 +1529,19 @@ static void choose_steering_mode(struct mlx4_dev *dev,
                 mlx4_log_num_mgm_entry_size);
 }
 
+static void choose_tunnel_offload_mode(struct mlx4_dev *dev,
+                                      struct mlx4_dev_cap *dev_cap)
+{
+       if (dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED &&
+           dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS)
+               dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_VXLAN;
+       else
+               dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_NONE;
+
+       mlx4_dbg(dev, "Tunneling offload mode is: %s\n",  (dev->caps.tunnel_offload_mode
+                == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) ? "vxlan" : "none");
+}
+
 static int mlx4_init_hca(struct mlx4_dev *dev)
 {
        struct mlx4_priv          *priv = mlx4_priv(dev);
@@ -1483,6 +1582,11 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
                }
 
                choose_steering_mode(dev, &dev_cap);
+               choose_tunnel_offload_mode(dev, &dev_cap);
+
+               err = mlx4_get_phys_port_id(dev);
+               if (err)
+                       mlx4_err(dev, "Fail to get physical port id\n");
 
                if (mlx4_is_master(dev))
                        mlx4_parav_master_pf_caps(dev);
@@ -1654,7 +1758,7 @@ EXPORT_SYMBOL_GPL(mlx4_counter_alloc);
 
 void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
 {
-       mlx4_bitmap_free(&mlx4_priv(dev)->counters_bitmap, idx);
+       mlx4_bitmap_free(&mlx4_priv(dev)->counters_bitmap, idx, MLX4_USE_RR);
        return;
 }
 
@@ -2222,7 +2326,11 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
 
                if (num_vfs) {
                        mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", num_vfs);
+
+                       atomic_inc(&pf_loading);
                        err = pci_enable_sriov(pdev, num_vfs);
+                       atomic_dec(&pf_loading);
+
                        if (err) {
                                mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n",
                                         err);
@@ -2287,6 +2395,12 @@ slave_start:
                        goto err_mfunc;
        }
 
+       /* check if the device is functioning at its maximum possible speed.
+        * 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);
+
        /* In master functions, the communication channel must be initialized
         * after obtaining its address from fw */
        if (mlx4_is_master(dev)) {
@@ -2581,6 +2695,7 @@ static struct pci_driver mlx4_driver = {
        .name           = DRV_NAME,
        .id_table       = mlx4_pci_table,
        .probe          = mlx4_init_one,
+       .shutdown       = mlx4_remove_one,
        .remove         = mlx4_remove_one,
        .err_handler    = &mlx4_err_handler,
 };