Commit 717258ba4b3ecca9c7c0ef2b76d7aa5800242bad

Authored by Vasanthy Kolluri
Committed by David S. Miller
1 parent e0e8ab5960

enic: Add support for multiple hardware receive queues

Add support for multiple hardware receive queues. The ingress traffic is hashed into one of the receive queues based on IP or TCP or both headers. The max no. of receive queues supported is 8.

Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 5 changed files with 368 additions and 124 deletions Side-by-side Diff

drivers/net/enic/enic.h
... ... @@ -28,10 +28,11 @@
28 28 #include "vnic_intr.h"
29 29 #include "vnic_stats.h"
30 30 #include "vnic_nic.h"
  31 +#include "vnic_rss.h"
31 32  
32 33 #define DRV_NAME "enic"
33 34 #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
34   -#define DRV_VERSION "1.4.1.2a"
  35 +#define DRV_VERSION "1.4.1.6"
35 36 #define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc"
36 37  
37 38 #define ENIC_BARS_MAX 6
... ... @@ -41,25 +42,6 @@
41 42 #define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX)
42 43 #define ENIC_INTR_MAX (ENIC_CQ_MAX + 2)
43 44  
44   -enum enic_cq_index {
45   - ENIC_CQ_RQ,
46   - ENIC_CQ_WQ,
47   -};
48   -
49   -enum enic_intx_intr_index {
50   - ENIC_INTX_WQ_RQ,
51   - ENIC_INTX_ERR,
52   - ENIC_INTX_NOTIFY,
53   -};
54   -
55   -enum enic_msix_intr_index {
56   - ENIC_MSIX_RQ,
57   - ENIC_MSIX_WQ,
58   - ENIC_MSIX_ERR,
59   - ENIC_MSIX_NOTIFY,
60   - ENIC_MSIX_MAX,
61   -};
62   -
63 45 struct enic_msix_entry {
64 46 int requested;
65 47 char devname[IFNAMSIZ];
... ... @@ -90,8 +72,8 @@
90 72 struct vnic_dev *vdev;
91 73 struct timer_list notify_timer;
92 74 struct work_struct reset;
93   - struct msix_entry msix_entry[ENIC_MSIX_MAX];
94   - struct enic_msix_entry msix[ENIC_MSIX_MAX];
  75 + struct msix_entry msix_entry[ENIC_INTR_MAX];
  76 + struct enic_msix_entry msix[ENIC_INTR_MAX];
95 77 u32 msg_enable;
96 78 spinlock_t devcmd_lock;
97 79 u8 mac_addr[ETH_ALEN];
... ... @@ -118,7 +100,7 @@
118 100 int (*rq_alloc_buf)(struct vnic_rq *rq);
119 101 u64 rq_truncated_pkts;
120 102 u64 rq_bad_fcs;
121   - struct napi_struct napi;
  103 + struct napi_struct napi[ENIC_RQ_MAX];
122 104  
123 105 /* interrupt resource cache line section */
124 106 ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX];
drivers/net/enic/enic_main.c
... ... @@ -122,6 +122,51 @@
122 122 return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN;
123 123 }
124 124  
  125 +static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq)
  126 +{
  127 + return rq;
  128 +}
  129 +
  130 +static inline unsigned int enic_cq_wq(struct enic *enic, unsigned int wq)
  131 +{
  132 + return enic->rq_count + wq;
  133 +}
  134 +
  135 +static inline unsigned int enic_legacy_io_intr(void)
  136 +{
  137 + return 0;
  138 +}
  139 +
  140 +static inline unsigned int enic_legacy_err_intr(void)
  141 +{
  142 + return 1;
  143 +}
  144 +
  145 +static inline unsigned int enic_legacy_notify_intr(void)
  146 +{
  147 + return 2;
  148 +}
  149 +
  150 +static inline unsigned int enic_msix_rq_intr(struct enic *enic, unsigned int rq)
  151 +{
  152 + return rq;
  153 +}
  154 +
  155 +static inline unsigned int enic_msix_wq_intr(struct enic *enic, unsigned int wq)
  156 +{
  157 + return enic->rq_count + wq;
  158 +}
  159 +
  160 +static inline unsigned int enic_msix_err_intr(struct enic *enic)
  161 +{
  162 + return enic->rq_count + enic->wq_count;
  163 +}
  164 +
  165 +static inline unsigned int enic_msix_notify_intr(struct enic *enic)
  166 +{
  167 + return enic->rq_count + enic->wq_count + 1;
  168 +}
  169 +
125 170 static int enic_get_settings(struct net_device *netdev,
126 171 struct ethtool_cmd *ecmd)
127 172 {
... ... @@ -306,6 +351,7 @@
306 351 struct enic *enic = netdev_priv(netdev);
307 352 u32 tx_coalesce_usecs;
308 353 u32 rx_coalesce_usecs;
  354 + unsigned int i, intr;
309 355  
310 356 tx_coalesce_usecs = min_t(u32,
311 357 INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX),
... ... @@ -319,7 +365,8 @@
319 365 if (tx_coalesce_usecs != rx_coalesce_usecs)
320 366 return -EINVAL;
321 367  
322   - vnic_intr_coalescing_timer_set(&enic->intr[ENIC_INTX_WQ_RQ],
  368 + intr = enic_legacy_io_intr();
  369 + vnic_intr_coalescing_timer_set(&enic->intr[intr],
323 370 INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
324 371 break;
325 372 case VNIC_DEV_INTR_MODE_MSI:
... ... @@ -330,10 +377,18 @@
330 377 INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
331 378 break;
332 379 case VNIC_DEV_INTR_MODE_MSIX:
333   - vnic_intr_coalescing_timer_set(&enic->intr[ENIC_MSIX_WQ],
334   - INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
335   - vnic_intr_coalescing_timer_set(&enic->intr[ENIC_MSIX_RQ],
336   - INTR_COALESCE_USEC_TO_HW(rx_coalesce_usecs));
  380 + for (i = 0; i < enic->wq_count; i++) {
  381 + intr = enic_msix_wq_intr(enic, i);
  382 + vnic_intr_coalescing_timer_set(&enic->intr[intr],
  383 + INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs));
  384 + }
  385 +
  386 + for (i = 0; i < enic->rq_count; i++) {
  387 + intr = enic_msix_rq_intr(enic, i);
  388 + vnic_intr_coalescing_timer_set(&enic->intr[intr],
  389 + INTR_COALESCE_USEC_TO_HW(rx_coalesce_usecs));
  390 + }
  391 +
337 392 break;
338 393 default:
339 394 break;
340 395  
341 396  
342 397  
343 398  
344 399  
345 400  
... ... @@ -482,34 +537,37 @@
482 537 {
483 538 struct net_device *netdev = data;
484 539 struct enic *enic = netdev_priv(netdev);
  540 + unsigned int io_intr = enic_legacy_io_intr();
  541 + unsigned int err_intr = enic_legacy_err_intr();
  542 + unsigned int notify_intr = enic_legacy_notify_intr();
485 543 u32 pba;
486 544  
487   - vnic_intr_mask(&enic->intr[ENIC_INTX_WQ_RQ]);
  545 + vnic_intr_mask(&enic->intr[io_intr]);
488 546  
489 547 pba = vnic_intr_legacy_pba(enic->legacy_pba);
490 548 if (!pba) {
491   - vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
  549 + vnic_intr_unmask(&enic->intr[io_intr]);
492 550 return IRQ_NONE; /* not our interrupt */
493 551 }
494 552  
495   - if (ENIC_TEST_INTR(pba, ENIC_INTX_NOTIFY)) {
496   - vnic_intr_return_all_credits(&enic->intr[ENIC_INTX_NOTIFY]);
  553 + if (ENIC_TEST_INTR(pba, notify_intr)) {
  554 + vnic_intr_return_all_credits(&enic->intr[notify_intr]);
497 555 enic_notify_check(enic);
498 556 }
499 557  
500   - if (ENIC_TEST_INTR(pba, ENIC_INTX_ERR)) {
501   - vnic_intr_return_all_credits(&enic->intr[ENIC_INTX_ERR]);
  558 + if (ENIC_TEST_INTR(pba, err_intr)) {
  559 + vnic_intr_return_all_credits(&enic->intr[err_intr]);
502 560 enic_log_q_error(enic);
503 561 /* schedule recovery from WQ/RQ error */
504 562 schedule_work(&enic->reset);
505 563 return IRQ_HANDLED;
506 564 }
507 565  
508   - if (ENIC_TEST_INTR(pba, ENIC_INTX_WQ_RQ)) {
509   - if (napi_schedule_prep(&enic->napi))
510   - __napi_schedule(&enic->napi);
  566 + if (ENIC_TEST_INTR(pba, io_intr)) {
  567 + if (napi_schedule_prep(&enic->napi[0]))
  568 + __napi_schedule(&enic->napi[0]);
511 569 } else {
512   - vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
  570 + vnic_intr_unmask(&enic->intr[io_intr]);
513 571 }
514 572  
515 573 return IRQ_HANDLED;
516 574  
517 575  
... ... @@ -535,17 +593,17 @@
535 593 * writes).
536 594 */
537 595  
538   - napi_schedule(&enic->napi);
  596 + napi_schedule(&enic->napi[0]);
539 597  
540 598 return IRQ_HANDLED;
541 599 }
542 600  
543 601 static irqreturn_t enic_isr_msix_rq(int irq, void *data)
544 602 {
545   - struct enic *enic = data;
  603 + struct napi_struct *napi = data;
546 604  
547 605 /* schedule NAPI polling for RQ cleanup */
548   - napi_schedule(&enic->napi);
  606 + napi_schedule(napi);
549 607  
550 608 return IRQ_HANDLED;
551 609 }
552 610  
553 611  
... ... @@ -553,13 +611,15 @@
553 611 static irqreturn_t enic_isr_msix_wq(int irq, void *data)
554 612 {
555 613 struct enic *enic = data;
  614 + unsigned int cq = enic_cq_wq(enic, 0);
  615 + unsigned int intr = enic_msix_wq_intr(enic, 0);
556 616 unsigned int wq_work_to_do = -1; /* no limit */
557 617 unsigned int wq_work_done;
558 618  
559   - wq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_WQ],
  619 + wq_work_done = vnic_cq_service(&enic->cq[cq],
560 620 wq_work_to_do, enic_wq_service, NULL);
561 621  
562   - vnic_intr_return_credits(&enic->intr[ENIC_MSIX_WQ],
  622 + vnic_intr_return_credits(&enic->intr[intr],
563 623 wq_work_done,
564 624 1 /* unmask intr */,
565 625 1 /* reset intr timer */);
566 626  
... ... @@ -570,8 +630,9 @@
570 630 static irqreturn_t enic_isr_msix_err(int irq, void *data)
571 631 {
572 632 struct enic *enic = data;
  633 + unsigned int intr = enic_msix_err_intr(enic);
573 634  
574   - vnic_intr_return_all_credits(&enic->intr[ENIC_MSIX_ERR]);
  635 + vnic_intr_return_all_credits(&enic->intr[intr]);
575 636  
576 637 enic_log_q_error(enic);
577 638  
578 639  
... ... @@ -584,8 +645,9 @@
584 645 static irqreturn_t enic_isr_msix_notify(int irq, void *data)
585 646 {
586 647 struct enic *enic = data;
  648 + unsigned int intr = enic_msix_notify_intr(enic);
587 649  
588   - vnic_intr_return_all_credits(&enic->intr[ENIC_MSIX_NOTIFY]);
  650 + vnic_intr_return_all_credits(&enic->intr[intr]);
589 651 enic_notify_check(enic);
590 652  
591 653 return IRQ_HANDLED;
... ... @@ -1409,8 +1471,8 @@
1409 1471 (vlan_tci & CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_MASK)) {
1410 1472  
1411 1473 if (netdev->features & NETIF_F_GRO)
1412   - vlan_gro_receive(&enic->napi, enic->vlan_group,
1413   - vlan_tci, skb);
  1474 + vlan_gro_receive(&enic->napi[q_number],
  1475 + enic->vlan_group, vlan_tci, skb);
1414 1476 else
1415 1477 vlan_hwaccel_receive_skb(skb,
1416 1478 enic->vlan_group, vlan_tci);
1417 1479  
... ... @@ -1418,12 +1480,11 @@
1418 1480 } else {
1419 1481  
1420 1482 if (netdev->features & NETIF_F_GRO)
1421   - napi_gro_receive(&enic->napi, skb);
  1483 + napi_gro_receive(&enic->napi[q_number], skb);
1422 1484 else
1423 1485 netif_receive_skb(skb);
1424 1486  
1425 1487 }
1426   -
1427 1488 } else {
1428 1489  
1429 1490 /* Buffer overflow
... ... @@ -1447,7 +1508,11 @@
1447 1508  
1448 1509 static int enic_poll(struct napi_struct *napi, int budget)
1449 1510 {
1450   - struct enic *enic = container_of(napi, struct enic, napi);
  1511 + struct net_device *netdev = napi->dev;
  1512 + struct enic *enic = netdev_priv(netdev);
  1513 + unsigned int cq_rq = enic_cq_rq(enic, 0);
  1514 + unsigned int cq_wq = enic_cq_wq(enic, 0);
  1515 + unsigned int intr = enic_legacy_io_intr();
1451 1516 unsigned int rq_work_to_do = budget;
1452 1517 unsigned int wq_work_to_do = -1; /* no limit */
1453 1518 unsigned int work_done, rq_work_done, wq_work_done;
1454 1519  
... ... @@ -1456,10 +1521,10 @@
1456 1521 /* Service RQ (first) and WQ
1457 1522 */
1458 1523  
1459   - rq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_RQ],
  1524 + rq_work_done = vnic_cq_service(&enic->cq[cq_rq],
1460 1525 rq_work_to_do, enic_rq_service, NULL);
1461 1526  
1462   - wq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_WQ],
  1527 + wq_work_done = vnic_cq_service(&enic->cq[cq_wq],
1463 1528 wq_work_to_do, enic_wq_service, NULL);
1464 1529  
1465 1530 /* Accumulate intr event credits for this polling
... ... @@ -1470,7 +1535,7 @@
1470 1535 work_done = rq_work_done + wq_work_done;
1471 1536  
1472 1537 if (work_done > 0)
1473   - vnic_intr_return_credits(&enic->intr[ENIC_INTX_WQ_RQ],
  1538 + vnic_intr_return_credits(&enic->intr[intr],
1474 1539 work_done,
1475 1540 0 /* don't unmask intr */,
1476 1541 0 /* don't reset intr timer */);
... ... @@ -1491,7 +1556,7 @@
1491 1556 */
1492 1557  
1493 1558 napi_complete(napi);
1494   - vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
  1559 + vnic_intr_unmask(&enic->intr[intr]);
1495 1560 }
1496 1561  
1497 1562 return rq_work_done;
... ... @@ -1499,7 +1564,11 @@
1499 1564  
1500 1565 static int enic_poll_msix(struct napi_struct *napi, int budget)
1501 1566 {
1502   - struct enic *enic = container_of(napi, struct enic, napi);
  1567 + struct net_device *netdev = napi->dev;
  1568 + struct enic *enic = netdev_priv(netdev);
  1569 + unsigned int rq = (napi - &enic->napi[0]);
  1570 + unsigned int cq = enic_cq_rq(enic, rq);
  1571 + unsigned int intr = enic_msix_rq_intr(enic, rq);
1503 1572 unsigned int work_to_do = budget;
1504 1573 unsigned int work_done;
1505 1574 int err;
... ... @@ -1507,7 +1576,7 @@
1507 1576 /* Service RQ
1508 1577 */
1509 1578  
1510   - work_done = vnic_cq_service(&enic->cq[ENIC_CQ_RQ],
  1579 + work_done = vnic_cq_service(&enic->cq[cq],
1511 1580 work_to_do, enic_rq_service, NULL);
1512 1581  
1513 1582 /* Return intr event credits for this polling
1514 1583  
... ... @@ -1516,12 +1585,12 @@
1516 1585 */
1517 1586  
1518 1587 if (work_done > 0)
1519   - vnic_intr_return_credits(&enic->intr[ENIC_MSIX_RQ],
  1588 + vnic_intr_return_credits(&enic->intr[intr],
1520 1589 work_done,
1521 1590 0 /* don't unmask intr */,
1522 1591 0 /* don't reset intr timer */);
1523 1592  
1524   - err = vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf);
  1593 + err = vnic_rq_fill(&enic->rq[rq], enic->rq_alloc_buf);
1525 1594  
1526 1595 /* Buffer allocation failed. Stay in polling mode
1527 1596 * so we can try to fill the ring again.
... ... @@ -1537,7 +1606,7 @@
1537 1606 */
1538 1607  
1539 1608 napi_complete(napi);
1540   - vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]);
  1609 + vnic_intr_unmask(&enic->intr[intr]);
1541 1610 }
1542 1611  
1543 1612 return work_done;
... ... @@ -1579,7 +1648,7 @@
1579 1648 static int enic_request_intr(struct enic *enic)
1580 1649 {
1581 1650 struct net_device *netdev = enic->netdev;
1582   - unsigned int i;
  1651 + unsigned int i, intr;
1583 1652 int err = 0;
1584 1653  
1585 1654 switch (vnic_dev_get_intr_mode(enic->vdev)) {
1586 1655  
1587 1656  
1588 1657  
1589 1658  
1590 1659  
1591 1660  
... ... @@ -1598,27 +1667,38 @@
1598 1667  
1599 1668 case VNIC_DEV_INTR_MODE_MSIX:
1600 1669  
1601   - sprintf(enic->msix[ENIC_MSIX_RQ].devname,
1602   - "%.11s-rx-0", netdev->name);
1603   - enic->msix[ENIC_MSIX_RQ].isr = enic_isr_msix_rq;
1604   - enic->msix[ENIC_MSIX_RQ].devid = enic;
  1670 + for (i = 0; i < enic->rq_count; i++) {
  1671 + intr = enic_msix_rq_intr(enic, i);
  1672 + sprintf(enic->msix[intr].devname,
  1673 + "%.11s-rx-%d", netdev->name, i);
  1674 + enic->msix[intr].isr = enic_isr_msix_rq;
  1675 + enic->msix[intr].devid = &enic->napi[i];
  1676 + }
1605 1677  
1606   - sprintf(enic->msix[ENIC_MSIX_WQ].devname,
1607   - "%.11s-tx-0", netdev->name);
1608   - enic->msix[ENIC_MSIX_WQ].isr = enic_isr_msix_wq;
1609   - enic->msix[ENIC_MSIX_WQ].devid = enic;
  1678 + for (i = 0; i < enic->wq_count; i++) {
  1679 + intr = enic_msix_wq_intr(enic, i);
  1680 + sprintf(enic->msix[intr].devname,
  1681 + "%.11s-tx-%d", netdev->name, i);
  1682 + enic->msix[intr].isr = enic_isr_msix_wq;
  1683 + enic->msix[intr].devid = enic;
  1684 + }
1610 1685  
1611   - sprintf(enic->msix[ENIC_MSIX_ERR].devname,
  1686 + intr = enic_msix_err_intr(enic);
  1687 + sprintf(enic->msix[intr].devname,
1612 1688 "%.11s-err", netdev->name);
1613   - enic->msix[ENIC_MSIX_ERR].isr = enic_isr_msix_err;
1614   - enic->msix[ENIC_MSIX_ERR].devid = enic;
  1689 + enic->msix[intr].isr = enic_isr_msix_err;
  1690 + enic->msix[intr].devid = enic;
1615 1691  
1616   - sprintf(enic->msix[ENIC_MSIX_NOTIFY].devname,
  1692 + intr = enic_msix_notify_intr(enic);
  1693 + sprintf(enic->msix[intr].devname,
1617 1694 "%.11s-notify", netdev->name);
1618   - enic->msix[ENIC_MSIX_NOTIFY].isr = enic_isr_msix_notify;
1619   - enic->msix[ENIC_MSIX_NOTIFY].devid = enic;
  1695 + enic->msix[intr].isr = enic_isr_msix_notify;
  1696 + enic->msix[intr].devid = enic;
1620 1697  
1621   - for (i = 0; i < ARRAY_SIZE(enic->msix); i++) {
  1698 + for (i = 0; i < ARRAY_SIZE(enic->msix); i++)
  1699 + enic->msix[i].requested = 0;
  1700 +
  1701 + for (i = 0; i < enic->intr_count; i++) {
1622 1702 err = request_irq(enic->msix_entry[i].vector,
1623 1703 enic->msix[i].isr, 0,
1624 1704 enic->msix[i].devname,
1625 1705  
... ... @@ -1664,10 +1744,12 @@
1664 1744 spin_lock(&enic->devcmd_lock);
1665 1745 switch (vnic_dev_get_intr_mode(enic->vdev)) {
1666 1746 case VNIC_DEV_INTR_MODE_INTX:
1667   - err = vnic_dev_notify_set(enic->vdev, ENIC_INTX_NOTIFY);
  1747 + err = vnic_dev_notify_set(enic->vdev,
  1748 + enic_legacy_notify_intr());
1668 1749 break;
1669 1750 case VNIC_DEV_INTR_MODE_MSIX:
1670   - err = vnic_dev_notify_set(enic->vdev, ENIC_MSIX_NOTIFY);
  1751 + err = vnic_dev_notify_set(enic->vdev,
  1752 + enic_msix_notify_intr(enic));
1671 1753 break;
1672 1754 default:
1673 1755 err = vnic_dev_notify_set(enic->vdev, -1 /* no intr */);
... ... @@ -1762,7 +1844,10 @@
1762 1844 enic_set_multicast_list(netdev);
1763 1845  
1764 1846 netif_wake_queue(netdev);
1765   - napi_enable(&enic->napi);
  1847 +
  1848 + for (i = 0; i < enic->rq_count; i++)
  1849 + napi_enable(&enic->napi[i]);
  1850 +
1766 1851 enic_dev_enable(enic);
1767 1852  
1768 1853 for (i = 0; i < enic->intr_count; i++)
... ... @@ -1797,7 +1882,10 @@
1797 1882 del_timer_sync(&enic->notify_timer);
1798 1883  
1799 1884 enic_dev_disable(enic);
1800   - napi_disable(&enic->napi);
  1885 +
  1886 + for (i = 0; i < enic->rq_count; i++)
  1887 + napi_disable(&enic->napi[i]);
  1888 +
1801 1889 netif_carrier_off(netdev);
1802 1890 netif_tx_disable(netdev);
1803 1891 enic_dev_del_station_addr(enic);
1804 1892  
... ... @@ -1857,11 +1945,16 @@
1857 1945 {
1858 1946 struct enic *enic = netdev_priv(netdev);
1859 1947 struct vnic_dev *vdev = enic->vdev;
  1948 + unsigned int i, intr;
1860 1949  
1861 1950 switch (vnic_dev_get_intr_mode(vdev)) {
1862 1951 case VNIC_DEV_INTR_MODE_MSIX:
1863   - enic_isr_msix_rq(enic->pdev->irq, enic);
1864   - enic_isr_msix_wq(enic->pdev->irq, enic);
  1952 + for (i = 0; i < enic->rq_count; i++) {
  1953 + intr = enic_msix_rq_intr(enic, i);
  1954 + enic_isr_msix_rq(enic->msix_entry[intr].vector, enic);
  1955 + }
  1956 + intr = enic_msix_wq_intr(enic, i);
  1957 + enic_isr_msix_wq(enic->msix_entry[intr].vector, enic);
1865 1958 break;
1866 1959 case VNIC_DEV_INTR_MODE_MSI:
1867 1960 enic_isr_msi(enic->pdev->irq, enic);
1868 1961  
1869 1962  
... ... @@ -1936,19 +2029,73 @@
1936 2029 return err;
1937 2030 }
1938 2031  
1939   -static int enic_set_niccfg(struct enic *enic)
  2032 +static int enic_set_rsskey(struct enic *enic)
1940 2033 {
1941   - const u8 rss_default_cpu = 0;
1942   - const u8 rss_hash_type = 0;
1943   - const u8 rss_hash_bits = 0;
1944   - const u8 rss_base_cpu = 0;
1945   - const u8 rss_enable = 0;
  2034 + u64 rss_key_buf_pa;
  2035 + union vnic_rss_key *rss_key_buf_va = NULL;
  2036 + union vnic_rss_key rss_key = {
  2037 + .key[0].b = {85, 67, 83, 97, 119, 101, 115, 111, 109, 101},
  2038 + .key[1].b = {80, 65, 76, 79, 117, 110, 105, 113, 117, 101},
  2039 + .key[2].b = {76, 73, 78, 85, 88, 114, 111, 99, 107, 115},
  2040 + .key[3].b = {69, 78, 73, 67, 105, 115, 99, 111, 111, 108},
  2041 + };
  2042 + int err;
  2043 +
  2044 + rss_key_buf_va = pci_alloc_consistent(enic->pdev,
  2045 + sizeof(union vnic_rss_key), &rss_key_buf_pa);
  2046 + if (!rss_key_buf_va)
  2047 + return -ENOMEM;
  2048 +
  2049 + memcpy(rss_key_buf_va, &rss_key, sizeof(union vnic_rss_key));
  2050 +
  2051 + spin_lock(&enic->devcmd_lock);
  2052 + err = enic_set_rss_key(enic,
  2053 + rss_key_buf_pa,
  2054 + sizeof(union vnic_rss_key));
  2055 + spin_unlock(&enic->devcmd_lock);
  2056 +
  2057 + pci_free_consistent(enic->pdev, sizeof(union vnic_rss_key),
  2058 + rss_key_buf_va, rss_key_buf_pa);
  2059 +
  2060 + return err;
  2061 +}
  2062 +
  2063 +static int enic_set_rsscpu(struct enic *enic, u8 rss_hash_bits)
  2064 +{
  2065 + u64 rss_cpu_buf_pa;
  2066 + union vnic_rss_cpu *rss_cpu_buf_va = NULL;
  2067 + unsigned int i;
  2068 + int err;
  2069 +
  2070 + rss_cpu_buf_va = pci_alloc_consistent(enic->pdev,
  2071 + sizeof(union vnic_rss_cpu), &rss_cpu_buf_pa);
  2072 + if (!rss_cpu_buf_va)
  2073 + return -ENOMEM;
  2074 +
  2075 + for (i = 0; i < (1 << rss_hash_bits); i++)
  2076 + (*rss_cpu_buf_va).cpu[i/4].b[i%4] = i % enic->rq_count;
  2077 +
  2078 + spin_lock(&enic->devcmd_lock);
  2079 + err = enic_set_rss_cpu(enic,
  2080 + rss_cpu_buf_pa,
  2081 + sizeof(union vnic_rss_cpu));
  2082 + spin_unlock(&enic->devcmd_lock);
  2083 +
  2084 + pci_free_consistent(enic->pdev, sizeof(union vnic_rss_cpu),
  2085 + rss_cpu_buf_va, rss_cpu_buf_pa);
  2086 +
  2087 + return err;
  2088 +}
  2089 +
  2090 +static int enic_set_niccfg(struct enic *enic, u8 rss_default_cpu,
  2091 + u8 rss_hash_type, u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable)
  2092 +{
1946 2093 const u8 tso_ipid_split_en = 0;
1947 2094 const u8 ig_vlan_strip_en = 1;
1948 2095 int err;
1949 2096  
1950   - /* Enable VLAN tag stripping. RSS not enabled (yet).
1951   - */
  2097 + /* Enable VLAN tag stripping.
  2098 + */
1952 2099  
1953 2100 spin_lock(&enic->devcmd_lock);
1954 2101 err = enic_set_nic_cfg(enic,
... ... @@ -1961,6 +2108,35 @@
1961 2108 return err;
1962 2109 }
1963 2110  
  2111 +static int enic_set_rss_nic_cfg(struct enic *enic)
  2112 +{
  2113 + struct device *dev = enic_get_dev(enic);
  2114 + const u8 rss_default_cpu = 0;
  2115 + const u8 rss_hash_type = NIC_CFG_RSS_HASH_TYPE_IPV4 |
  2116 + NIC_CFG_RSS_HASH_TYPE_TCP_IPV4 |
  2117 + NIC_CFG_RSS_HASH_TYPE_IPV6 |
  2118 + NIC_CFG_RSS_HASH_TYPE_TCP_IPV6;
  2119 + const u8 rss_hash_bits = 7;
  2120 + const u8 rss_base_cpu = 0;
  2121 + u8 rss_enable = ENIC_SETTING(enic, RSS) && (enic->rq_count > 1);
  2122 +
  2123 + if (rss_enable) {
  2124 + if (!enic_set_rsskey(enic)) {
  2125 + if (enic_set_rsscpu(enic, rss_hash_bits)) {
  2126 + rss_enable = 0;
  2127 + dev_warn(dev, "RSS disabled, "
  2128 + "Failed to set RSS cpu indirection table.");
  2129 + }
  2130 + } else {
  2131 + rss_enable = 0;
  2132 + dev_warn(dev, "RSS disabled, Failed to set RSS key.\n");
  2133 + }
  2134 + }
  2135 +
  2136 + return enic_set_niccfg(enic, rss_default_cpu, rss_hash_type,
  2137 + rss_hash_bits, rss_base_cpu, rss_enable);
  2138 +}
  2139 +
1964 2140 static int enic_dev_hang_notify(struct enic *enic)
1965 2141 {
1966 2142 int err;
... ... @@ -1998,7 +2174,7 @@
1998 2174 enic_dev_hang_reset(enic);
1999 2175 enic_reset_multicast_list(enic);
2000 2176 enic_init_vnic_resources(enic);
2001   - enic_set_niccfg(enic);
  2177 + enic_set_rss_nic_cfg(enic);
2002 2178 enic_dev_set_ig_vlan_rewrite_mode(enic);
2003 2179 enic_open(enic->netdev);
2004 2180  
2005 2181  
... ... @@ -2007,12 +2183,12 @@
2007 2183  
2008 2184 static int enic_set_intr_mode(struct enic *enic)
2009 2185 {
2010   - unsigned int n = 1;
  2186 + unsigned int n = min_t(unsigned int, enic->rq_count, ENIC_RQ_MAX);
2011 2187 unsigned int m = 1;
2012 2188 unsigned int i;
2013 2189  
2014 2190 /* Set interrupt mode (INTx, MSI, MSI-X) depending
2015   - * system capabilities.
  2191 + * on system capabilities.
2016 2192 *
2017 2193 * Try MSI-X first
2018 2194 *
2019 2195  
2020 2196  
2021 2197  
2022 2198  
2023 2199  
... ... @@ -2025,23 +2201,49 @@
2025 2201 for (i = 0; i < n + m + 2; i++)
2026 2202 enic->msix_entry[i].entry = i;
2027 2203  
2028   - if (enic->config.intr_mode < 1 &&
  2204 + /* Use multiple RQs if RSS is enabled
  2205 + */
  2206 +
  2207 + if (ENIC_SETTING(enic, RSS) &&
  2208 + enic->config.intr_mode < 1 &&
2029 2209 enic->rq_count >= n &&
2030 2210 enic->wq_count >= m &&
2031 2211 enic->cq_count >= n + m &&
2032   - enic->intr_count >= n + m + 2 &&
2033   - !pci_enable_msix(enic->pdev, enic->msix_entry, n + m + 2)) {
  2212 + enic->intr_count >= n + m + 2) {
2034 2213  
2035   - enic->rq_count = n;
2036   - enic->wq_count = m;
2037   - enic->cq_count = n + m;
2038   - enic->intr_count = n + m + 2;
  2214 + if (!pci_enable_msix(enic->pdev, enic->msix_entry, n + m + 2)) {
2039 2215  
2040   - vnic_dev_set_intr_mode(enic->vdev, VNIC_DEV_INTR_MODE_MSIX);
  2216 + enic->rq_count = n;
  2217 + enic->wq_count = m;
  2218 + enic->cq_count = n + m;
  2219 + enic->intr_count = n + m + 2;
2041 2220  
2042   - return 0;
  2221 + vnic_dev_set_intr_mode(enic->vdev,
  2222 + VNIC_DEV_INTR_MODE_MSIX);
  2223 +
  2224 + return 0;
  2225 + }
2043 2226 }
2044 2227  
  2228 + if (enic->config.intr_mode < 1 &&
  2229 + enic->rq_count >= 1 &&
  2230 + enic->wq_count >= m &&
  2231 + enic->cq_count >= 1 + m &&
  2232 + enic->intr_count >= 1 + m + 2) {
  2233 + if (!pci_enable_msix(enic->pdev, enic->msix_entry, 1 + m + 2)) {
  2234 +
  2235 + enic->rq_count = 1;
  2236 + enic->wq_count = m;
  2237 + enic->cq_count = 1 + m;
  2238 + enic->intr_count = 1 + m + 2;
  2239 +
  2240 + vnic_dev_set_intr_mode(enic->vdev,
  2241 + VNIC_DEV_INTR_MODE_MSIX);
  2242 +
  2243 + return 0;
  2244 + }
  2245 + }
  2246 +
2045 2247 /* Next try MSI
2046 2248 *
2047 2249 * We need 1 RQ, 1 WQ, 2 CQs, and 1 INTR
... ... @@ -2149,7 +2351,11 @@
2149 2351  
2150 2352 static void enic_dev_deinit(struct enic *enic)
2151 2353 {
2152   - netif_napi_del(&enic->napi);
  2354 + unsigned int i;
  2355 +
  2356 + for (i = 0; i < enic->rq_count; i++)
  2357 + netif_napi_del(&enic->napi[i]);
  2358 +
2153 2359 enic_free_vnic_resources(enic);
2154 2360 enic_clear_intr_mode(enic);
2155 2361 }
... ... @@ -2158,6 +2364,7 @@
2158 2364 {
2159 2365 struct device *dev = enic_get_dev(enic);
2160 2366 struct net_device *netdev = enic->netdev;
  2367 + unsigned int i;
2161 2368 int err;
2162 2369  
2163 2370 /* Get vNIC configuration
... ... @@ -2202,7 +2409,7 @@
2202 2409 goto err_out_free_vnic_resources;
2203 2410 }
2204 2411  
2205   - err = enic_set_niccfg(enic);
  2412 + err = enic_set_rss_nic_cfg(enic);
2206 2413 if (err) {
2207 2414 dev_err(dev, "Failed to config nic, aborting\n");
2208 2415 goto err_out_free_vnic_resources;
2209 2416  
... ... @@ -2217,10 +2424,12 @@
2217 2424  
2218 2425 switch (vnic_dev_get_intr_mode(enic->vdev)) {
2219 2426 default:
2220   - netif_napi_add(netdev, &enic->napi, enic_poll, 64);
  2427 + netif_napi_add(netdev, &enic->napi[0], enic_poll, 64);
2221 2428 break;
2222 2429 case VNIC_DEV_INTR_MODE_MSIX:
2223   - netif_napi_add(netdev, &enic->napi, enic_poll_msix, 64);
  2430 + for (i = 0; i < enic->rq_count; i++)
  2431 + netif_napi_add(netdev, &enic->napi[i],
  2432 + enic_poll_msix, 64);
2224 2433 break;
2225 2434 }
2226 2435  
drivers/net/enic/enic_res.c
... ... @@ -35,6 +35,7 @@
35 35 #include "vnic_intr.h"
36 36 #include "vnic_stats.h"
37 37 #include "vnic_nic.h"
  38 +#include "vnic_rss.h"
38 39 #include "enic_res.h"
39 40 #include "enic.h"
40 41  
... ... @@ -93,13 +94,14 @@
93 94 INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX),
94 95 c->intr_timer_usec);
95 96  
96   - dev_info(enic_get_dev(enic), "vNIC MAC addr %pM wq/rq %d/%d\n",
97   - enic->mac_addr, c->wq_desc_count, c->rq_desc_count);
98   - dev_info(enic_get_dev(enic), "vNIC mtu %d csum tx/rx %d/%d "
99   - "tso/lro %d/%d intr timer %d usec\n",
100   - c->mtu, ENIC_SETTING(enic, TXCSUM),
101   - ENIC_SETTING(enic, RXCSUM), ENIC_SETTING(enic, TSO),
102   - ENIC_SETTING(enic, LRO), c->intr_timer_usec);
  97 + dev_info(enic_get_dev(enic),
  98 + "vNIC MAC addr %pM wq/rq %d/%d mtu %d\n",
  99 + enic->mac_addr, c->wq_desc_count, c->rq_desc_count, c->mtu);
  100 + dev_info(enic_get_dev(enic), "vNIC csum tx/rx %d/%d "
  101 + "tso/lro %d/%d intr timer %d usec rss %d\n",
  102 + ENIC_SETTING(enic, TXCSUM), ENIC_SETTING(enic, RXCSUM),
  103 + ENIC_SETTING(enic, TSO), ENIC_SETTING(enic, LRO),
  104 + c->intr_timer_usec, ENIC_SETTING(enic, RSS));
103 105  
104 106 return 0;
105 107 }
... ... @@ -148,6 +150,22 @@
148 150 return vnic_dev_cmd(enic->vdev, CMD_NIC_CFG, &a0, &a1, wait);
149 151 }
150 152  
  153 +int enic_set_rss_key(struct enic *enic, dma_addr_t key_pa, u64 len)
  154 +{
  155 + u64 a0 = (u64)key_pa, a1 = len;
  156 + int wait = 1000;
  157 +
  158 + return vnic_dev_cmd(enic->vdev, CMD_RSS_KEY, &a0, &a1, wait);
  159 +}
  160 +
  161 +int enic_set_rss_cpu(struct enic *enic, dma_addr_t cpu_pa, u64 len)
  162 +{
  163 + u64 a0 = (u64)cpu_pa, a1 = len;
  164 + int wait = 1000;
  165 +
  166 + return vnic_dev_cmd(enic->vdev, CMD_RSS_CPU, &a0, &a1, wait);
  167 +}
  168 +
151 169 void enic_free_vnic_resources(struct enic *enic)
152 170 {
153 171 unsigned int i;
... ... @@ -164,18 +182,11 @@
164 182  
165 183 void enic_get_res_counts(struct enic *enic)
166 184 {
167   - enic->wq_count = min_t(int,
168   - vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ),
169   - ENIC_WQ_MAX);
170   - enic->rq_count = min_t(int,
171   - vnic_dev_get_res_count(enic->vdev, RES_TYPE_RQ),
172   - ENIC_RQ_MAX);
173   - enic->cq_count = min_t(int,
174   - vnic_dev_get_res_count(enic->vdev, RES_TYPE_CQ),
175   - ENIC_CQ_MAX);
176   - enic->intr_count = min_t(int,
177   - vnic_dev_get_res_count(enic->vdev, RES_TYPE_INTR_CTRL),
178   - ENIC_INTR_MAX);
  185 + enic->wq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ);
  186 + enic->rq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_RQ);
  187 + enic->cq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_CQ);
  188 + enic->intr_count = vnic_dev_get_res_count(enic->vdev,
  189 + RES_TYPE_INTR_CTRL);
179 190  
180 191 dev_info(enic_get_dev(enic),
181 192 "vNIC resources avail: wq %d rq %d cq %d intr %d\n",
drivers/net/enic/enic_res.h
... ... @@ -137,6 +137,8 @@
137 137 int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type,
138 138 u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en,
139 139 u8 ig_vlan_strip_en);
  140 +int enic_set_rss_key(struct enic *enic, dma_addr_t key_pa, u64 len);
  141 +int enic_set_rss_cpu(struct enic *enic, dma_addr_t cpu_pa, u64 len);
140 142 void enic_get_res_counts(struct enic *enic);
141 143 void enic_init_vnic_resources(struct enic *enic);
142 144 int enic_alloc_vnic_resources(struct enic *);
drivers/net/enic/vnic_rss.h
  1 +/*
  2 + * Copyright 2008-2010 Cisco Systems, Inc. All rights reserved.
  3 + * Copyright 2007 Nuova Systems, Inc. All rights reserved.
  4 + *
  5 + * This program is free software; you may redistribute it and/or modify
  6 + * it under the terms of the GNU General Public License as published by
  7 + * the Free Software Foundation; version 2 of the License.
  8 + *
  9 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  10 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  11 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  12 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  13 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  14 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  15 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  16 + * SOFTWARE.
  17 + */
  18 +
  19 +#ifndef _VNIC_RSS_H_
  20 +#define _VNIC_RSS_H_
  21 +
  22 +/* RSS key array */
  23 +union vnic_rss_key {
  24 + struct {
  25 + u8 b[10];
  26 + u8 b_pad[6];
  27 + } key[4];
  28 + u64 raw[8];
  29 +};
  30 +
  31 +/* RSS cpu array */
  32 +union vnic_rss_cpu {
  33 + struct {
  34 + u8 b[4] ;
  35 + u8 b_pad[4];
  36 + } cpu[32];
  37 + u64 raw[32];
  38 +};
  39 +
  40 +#endif /* _VNIC_RSS_H_ */