aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c109
-rw-r--r--include/linux/mlx4/device.h7
2 files changed, 92 insertions, 24 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index abd0b1d277aa..e1a55857af71 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -2193,6 +2193,10 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
2193 struct mlx4_dev *dev; 2193 struct mlx4_dev *dev;
2194 int err; 2194 int err;
2195 int port; 2195 int port;
2196 int nvfs[MLX4_MAX_PORTS + 1], prb_vf[MLX4_MAX_PORTS + 1];
2197 unsigned total_vfs = 0;
2198 int sriov_initialized = 0;
2199 unsigned int i;
2196 2200
2197 pr_info(DRV_NAME ": Initializing %s\n", pci_name(pdev)); 2201 pr_info(DRV_NAME ": Initializing %s\n", pci_name(pdev));
2198 2202
@@ -2207,17 +2211,39 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
2207 * per port, we must limit the number of VFs to 63 (since their are 2211 * per port, we must limit the number of VFs to 63 (since their are
2208 * 128 MACs) 2212 * 128 MACs)
2209 */ 2213 */
2210 if (num_vfs >= MLX4_MAX_NUM_VF) { 2214 for (i = 0; i < sizeof(nvfs)/sizeof(nvfs[0]);
2215 total_vfs += nvfs[i], i++) {
2216 nvfs[i] = i == MLX4_MAX_PORTS ? num_vfs : 0;
2217 if (nvfs[i] < 0) {
2218 dev_err(&pdev->dev, "num_vfs module parameter cannot be negative\n");
2219 return -EINVAL;
2220 }
2221 }
2222 for (i = 0; i < sizeof(prb_vf)/sizeof(prb_vf[0]); i++) {
2223 prb_vf[i] = i == MLX4_MAX_PORTS ? probe_vf : 0;
2224 if (prb_vf[i] < 0 || prb_vf[i] > nvfs[i]) {
2225 dev_err(&pdev->dev, "probe_vf module parameter cannot be negative or greater than num_vfs\n");
2226 return -EINVAL;
2227 }
2228 }
2229 if (total_vfs >= MLX4_MAX_NUM_VF) {
2211 dev_err(&pdev->dev, 2230 dev_err(&pdev->dev,
2212 "Requested more VF's (%d) than allowed (%d)\n", 2231 "Requested more VF's (%d) than allowed (%d)\n",
2213 num_vfs, MLX4_MAX_NUM_VF - 1); 2232 total_vfs, MLX4_MAX_NUM_VF - 1);
2214 return -EINVAL; 2233 return -EINVAL;
2215 } 2234 }
2216 2235
2217 if (num_vfs < 0) { 2236 for (i = 0; i < MLX4_MAX_PORTS; i++) {
2218 pr_err("num_vfs module parameter cannot be negative\n"); 2237 if (nvfs[i] + nvfs[2] >= MLX4_MAX_NUM_VF_P_PORT) {
2219 return -EINVAL; 2238 dev_err(&pdev->dev,
2239 "Requested more VF's (%d) for port (%d) than allowed (%d)\n",
2240 nvfs[i] + nvfs[2], i + 1,
2241 MLX4_MAX_NUM_VF_P_PORT - 1);
2242 return -EINVAL;
2243 }
2220 } 2244 }
2245
2246
2221 /* 2247 /*
2222 * Check for BARs. 2248 * Check for BARs.
2223 */ 2249 */
@@ -2292,11 +2318,23 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
2292 if (pci_dev_data & MLX4_PCI_DEV_IS_VF) { 2318 if (pci_dev_data & MLX4_PCI_DEV_IS_VF) {
2293 /* When acting as pf, we normally skip vfs unless explicitly 2319 /* When acting as pf, we normally skip vfs unless explicitly
2294 * requested to probe them. */ 2320 * requested to probe them. */
2295 if (num_vfs && extended_func_num(pdev) > probe_vf) { 2321 if (total_vfs) {
2296 mlx4_warn(dev, "Skipping virtual function:%d\n", 2322 unsigned vfs_offset = 0;
2297 extended_func_num(pdev)); 2323 for (i = 0; i < sizeof(nvfs)/sizeof(nvfs[0]) &&
2298 err = -ENODEV; 2324 vfs_offset + nvfs[i] < extended_func_num(pdev);
2299 goto err_free_dev; 2325 vfs_offset += nvfs[i], i++)
2326 ;
2327 if (i == sizeof(nvfs)/sizeof(nvfs[0])) {
2328 err = -ENODEV;
2329 goto err_free_dev;
2330 }
2331 if ((extended_func_num(pdev) - vfs_offset)
2332 > prb_vf[i]) {
2333 mlx4_warn(dev, "Skipping virtual function:%d\n",
2334 extended_func_num(pdev));
2335 err = -ENODEV;
2336 goto err_free_dev;
2337 }
2300 } 2338 }
2301 mlx4_warn(dev, "Detected virtual function - running in slave mode\n"); 2339 mlx4_warn(dev, "Detected virtual function - running in slave mode\n");
2302 dev->flags |= MLX4_FLAG_SLAVE; 2340 dev->flags |= MLX4_FLAG_SLAVE;
@@ -2316,22 +2354,30 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
2316 } 2354 }
2317 } 2355 }
2318 2356
2319 if (num_vfs) { 2357 if (total_vfs) {
2320 mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", num_vfs); 2358 mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n",
2321 2359 total_vfs);
2322 atomic_inc(&pf_loading); 2360 dev->dev_vfs = kzalloc(
2323 err = pci_enable_sriov(pdev, num_vfs); 2361 total_vfs * sizeof(*dev->dev_vfs),
2324 atomic_dec(&pf_loading); 2362 GFP_KERNEL);
2325 2363 if (NULL == dev->dev_vfs) {
2326 if (err) { 2364 mlx4_err(dev, "Failed to allocate memory for VFs\n");
2327 mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n",
2328 err);
2329 err = 0; 2365 err = 0;
2330 } else { 2366 } else {
2331 mlx4_warn(dev, "Running in master mode\n"); 2367 atomic_inc(&pf_loading);
2332 dev->flags |= MLX4_FLAG_SRIOV | 2368 err = pci_enable_sriov(pdev, total_vfs);
2333 MLX4_FLAG_MASTER; 2369 atomic_dec(&pf_loading);
2334 dev->num_vfs = num_vfs; 2370 if (err) {
2371 mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n",
2372 err);
2373 err = 0;
2374 } else {
2375 mlx4_warn(dev, "Running in master mode\n");
2376 dev->flags |= MLX4_FLAG_SRIOV |
2377 MLX4_FLAG_MASTER;
2378 dev->num_vfs = total_vfs;
2379 sriov_initialized = 1;
2380 }
2335 } 2381 }
2336 } 2382 }
2337 2383
@@ -2396,12 +2442,24 @@ slave_start:
2396 /* In master functions, the communication channel must be initialized 2442 /* In master functions, the communication channel must be initialized
2397 * after obtaining its address from fw */ 2443 * after obtaining its address from fw */
2398 if (mlx4_is_master(dev)) { 2444 if (mlx4_is_master(dev)) {
2445 unsigned sum = 0;
2399 err = mlx4_multi_func_init(dev); 2446 err = mlx4_multi_func_init(dev);
2400 if (err) { 2447 if (err) {
2401 mlx4_err(dev, "Failed to init master mfunc" 2448 mlx4_err(dev, "Failed to init master mfunc"
2402 "interface, aborting.\n"); 2449 "interface, aborting.\n");
2403 goto err_close; 2450 goto err_close;
2404 } 2451 }
2452 if (sriov_initialized) {
2453 for (i = 0; i < sizeof(nvfs)/sizeof(nvfs[0]); i++) {
2454 unsigned j;
2455 for (j = 0; j < nvfs[i]; ++sum, ++j) {
2456 dev->dev_vfs[sum].min_port =
2457 i < 2 ? i + 1 : 1;
2458 dev->dev_vfs[sum].n_ports = i < 2 ? 1 :
2459 dev->caps.num_ports;
2460 }
2461 }
2462 }
2405 } 2463 }
2406 2464
2407 err = mlx4_alloc_eq_table(dev); 2465 err = mlx4_alloc_eq_table(dev);
@@ -2509,6 +2567,8 @@ err_rel_own:
2509 if (!mlx4_is_slave(dev)) 2567 if (!mlx4_is_slave(dev))
2510 mlx4_free_ownership(dev); 2568 mlx4_free_ownership(dev);
2511 2569
2570 kfree(priv->dev.dev_vfs);
2571
2512err_free_dev: 2572err_free_dev:
2513 kfree(priv); 2573 kfree(priv);