diff options
Diffstat (limited to 'drivers/net/cxgb3/cxgb3_main.c')
-rw-r--r-- | drivers/net/cxgb3/cxgb3_main.c | 96 |
1 files changed, 27 insertions, 69 deletions
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 5ab319cfe5de..5db7d4e27ec0 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -339,49 +339,17 @@ static void setup_rss(struct adapter *adap) | |||
339 | V_RRCPLCPUSIZE(6), cpus, rspq_map); | 339 | V_RRCPLCPUSIZE(6), cpus, rspq_map); |
340 | } | 340 | } |
341 | 341 | ||
342 | /* | 342 | static void init_napi(struct adapter *adap) |
343 | * If we have multiple receive queues per port serviced by NAPI we need one | ||
344 | * netdevice per queue as NAPI operates on netdevices. We already have one | ||
345 | * netdevice, namely the one associated with the interface, so we use dummy | ||
346 | * ones for any additional queues. Note that these netdevices exist purely | ||
347 | * so that NAPI has something to work with, they do not represent network | ||
348 | * ports and are not registered. | ||
349 | */ | ||
350 | static int init_dummy_netdevs(struct adapter *adap) | ||
351 | { | 343 | { |
352 | int i, j, dummy_idx = 0; | 344 | int i; |
353 | struct net_device *nd; | ||
354 | |||
355 | for_each_port(adap, i) { | ||
356 | struct net_device *dev = adap->port[i]; | ||
357 | const struct port_info *pi = netdev_priv(dev); | ||
358 | |||
359 | for (j = 0; j < pi->nqsets - 1; j++) { | ||
360 | if (!adap->dummy_netdev[dummy_idx]) { | ||
361 | struct port_info *p; | ||
362 | |||
363 | nd = alloc_netdev(sizeof(*p), "", ether_setup); | ||
364 | if (!nd) | ||
365 | goto free_all; | ||
366 | 345 | ||
367 | p = netdev_priv(nd); | 346 | for (i = 0; i < SGE_QSETS; i++) { |
368 | p->adapter = adap; | 347 | struct sge_qset *qs = &adap->sge.qs[i]; |
369 | nd->weight = 64; | ||
370 | set_bit(__LINK_STATE_START, &nd->state); | ||
371 | adap->dummy_netdev[dummy_idx] = nd; | ||
372 | } | ||
373 | strcpy(adap->dummy_netdev[dummy_idx]->name, dev->name); | ||
374 | dummy_idx++; | ||
375 | } | ||
376 | } | ||
377 | return 0; | ||
378 | 348 | ||
379 | free_all: | 349 | if (qs->adap) |
380 | while (--dummy_idx >= 0) { | 350 | netif_napi_add(qs->netdev, &qs->napi, qs->napi.poll, |
381 | free_netdev(adap->dummy_netdev[dummy_idx]); | 351 | 64); |
382 | adap->dummy_netdev[dummy_idx] = NULL; | ||
383 | } | 352 | } |
384 | return -ENOMEM; | ||
385 | } | 353 | } |
386 | 354 | ||
387 | /* | 355 | /* |
@@ -392,20 +360,18 @@ free_all: | |||
392 | static void quiesce_rx(struct adapter *adap) | 360 | static void quiesce_rx(struct adapter *adap) |
393 | { | 361 | { |
394 | int i; | 362 | int i; |
395 | struct net_device *dev; | ||
396 | 363 | ||
397 | for_each_port(adap, i) { | 364 | for (i = 0; i < SGE_QSETS; i++) |
398 | dev = adap->port[i]; | 365 | if (adap->sge.qs[i].adap) |
399 | while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) | 366 | napi_disable(&adap->sge.qs[i].napi); |
400 | msleep(1); | 367 | } |
401 | } | ||
402 | 368 | ||
403 | for (i = 0; i < ARRAY_SIZE(adap->dummy_netdev); i++) { | 369 | static void enable_all_napi(struct adapter *adap) |
404 | dev = adap->dummy_netdev[i]; | 370 | { |
405 | if (dev) | 371 | int i; |
406 | while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) | 372 | for (i = 0; i < SGE_QSETS; i++) |
407 | msleep(1); | 373 | if (adap->sge.qs[i].adap) |
408 | } | 374 | napi_enable(&adap->sge.qs[i].napi); |
409 | } | 375 | } |
410 | 376 | ||
411 | /** | 377 | /** |
@@ -418,7 +384,7 @@ static void quiesce_rx(struct adapter *adap) | |||
418 | */ | 384 | */ |
419 | static int setup_sge_qsets(struct adapter *adap) | 385 | static int setup_sge_qsets(struct adapter *adap) |
420 | { | 386 | { |
421 | int i, j, err, irq_idx = 0, qset_idx = 0, dummy_dev_idx = 0; | 387 | int i, j, err, irq_idx = 0, qset_idx = 0; |
422 | unsigned int ntxq = SGE_TXQ_PER_SET; | 388 | unsigned int ntxq = SGE_TXQ_PER_SET; |
423 | 389 | ||
424 | if (adap->params.rev > 0 && !(adap->flags & USING_MSI)) | 390 | if (adap->params.rev > 0 && !(adap->flags & USING_MSI)) |
@@ -426,15 +392,14 @@ static int setup_sge_qsets(struct adapter *adap) | |||
426 | 392 | ||
427 | for_each_port(adap, i) { | 393 | for_each_port(adap, i) { |
428 | struct net_device *dev = adap->port[i]; | 394 | struct net_device *dev = adap->port[i]; |
429 | const struct port_info *pi = netdev_priv(dev); | 395 | struct port_info *pi = netdev_priv(dev); |
430 | 396 | ||
397 | pi->qs = &adap->sge.qs[pi->first_qset]; | ||
431 | for (j = 0; j < pi->nqsets; ++j, ++qset_idx) { | 398 | for (j = 0; j < pi->nqsets; ++j, ++qset_idx) { |
432 | err = t3_sge_alloc_qset(adap, qset_idx, 1, | 399 | err = t3_sge_alloc_qset(adap, qset_idx, 1, |
433 | (adap->flags & USING_MSIX) ? qset_idx + 1 : | 400 | (adap->flags & USING_MSIX) ? qset_idx + 1 : |
434 | irq_idx, | 401 | irq_idx, |
435 | &adap->params.sge.qset[qset_idx], ntxq, | 402 | &adap->params.sge.qset[qset_idx], ntxq, dev); |
436 | j == 0 ? dev : | ||
437 | adap-> dummy_netdev[dummy_dev_idx++]); | ||
438 | if (err) { | 403 | if (err) { |
439 | t3_free_sge_resources(adap); | 404 | t3_free_sge_resources(adap); |
440 | return err; | 405 | return err; |
@@ -845,21 +810,18 @@ static int cxgb_up(struct adapter *adap) | |||
845 | goto out; | 810 | goto out; |
846 | } | 811 | } |
847 | 812 | ||
848 | err = init_dummy_netdevs(adap); | ||
849 | if (err) | ||
850 | goto out; | ||
851 | |||
852 | err = t3_init_hw(adap, 0); | 813 | err = t3_init_hw(adap, 0); |
853 | if (err) | 814 | if (err) |
854 | goto out; | 815 | goto out; |
855 | 816 | ||
856 | t3_write_reg(adap, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12)); | 817 | t3_write_reg(adap, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12)); |
857 | 818 | ||
858 | err = setup_sge_qsets(adap); | 819 | err = setup_sge_qsets(adap); |
859 | if (err) | 820 | if (err) |
860 | goto out; | 821 | goto out; |
861 | 822 | ||
862 | setup_rss(adap); | 823 | setup_rss(adap); |
824 | init_napi(adap); | ||
863 | adap->flags |= FULL_INIT_DONE; | 825 | adap->flags |= FULL_INIT_DONE; |
864 | } | 826 | } |
865 | 827 | ||
@@ -886,6 +848,7 @@ static int cxgb_up(struct adapter *adap) | |||
886 | adap->name, adap))) | 848 | adap->name, adap))) |
887 | goto irq_err; | 849 | goto irq_err; |
888 | 850 | ||
851 | enable_all_napi(adap); | ||
889 | t3_sge_start(adap); | 852 | t3_sge_start(adap); |
890 | t3_intr_enable(adap); | 853 | t3_intr_enable(adap); |
891 | 854 | ||
@@ -1012,8 +975,10 @@ static int cxgb_open(struct net_device *dev) | |||
1012 | int other_ports = adapter->open_device_map & PORT_MASK; | 975 | int other_ports = adapter->open_device_map & PORT_MASK; |
1013 | int err; | 976 | int err; |
1014 | 977 | ||
1015 | if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) | 978 | if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) { |
979 | quiesce_rx(adapter); | ||
1016 | return err; | 980 | return err; |
981 | } | ||
1017 | 982 | ||
1018 | set_bit(pi->port_id, &adapter->open_device_map); | 983 | set_bit(pi->port_id, &adapter->open_device_map); |
1019 | if (is_offload(adapter) && !ofld_disable) { | 984 | if (is_offload(adapter) && !ofld_disable) { |
@@ -2524,7 +2489,6 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
2524 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2489 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2525 | netdev->poll_controller = cxgb_netpoll; | 2490 | netdev->poll_controller = cxgb_netpoll; |
2526 | #endif | 2491 | #endif |
2527 | netdev->weight = 64; | ||
2528 | 2492 | ||
2529 | SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops); | 2493 | SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops); |
2530 | } | 2494 | } |
@@ -2625,12 +2589,6 @@ static void __devexit remove_one(struct pci_dev *pdev) | |||
2625 | t3_free_sge_resources(adapter); | 2589 | t3_free_sge_resources(adapter); |
2626 | cxgb_disable_msi(adapter); | 2590 | cxgb_disable_msi(adapter); |
2627 | 2591 | ||
2628 | for (i = 0; i < ARRAY_SIZE(adapter->dummy_netdev); i++) | ||
2629 | if (adapter->dummy_netdev[i]) { | ||
2630 | free_netdev(adapter->dummy_netdev[i]); | ||
2631 | adapter->dummy_netdev[i] = NULL; | ||
2632 | } | ||
2633 | |||
2634 | for_each_port(adapter, i) | 2592 | for_each_port(adapter, i) |
2635 | if (adapter->port[i]) | 2593 | if (adapter->port[i]) |
2636 | free_netdev(adapter->port[i]); | 2594 | free_netdev(adapter->port[i]); |