diff options
author | David S. Miller <davem@davemloft.net> | 2013-09-05 12:39:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-09-05 12:39:39 -0400 |
commit | c3de991feb5f785175ca3fc1ea30e21c1086a109 (patch) | |
tree | 05637ea85d3c9b0eec188590b9f07fa143a7372a | |
parent | 3c3769e63301fd92fcaf51870c371583dd0282ce (diff) | |
parent | 001e1c1d5ec6282726e3d051eeaf776504ee8e45 (diff) |
Merge branch 'enic'
Govindarajulu Varadarajan says:
====================
The following patch adds multi tx support for enic.
Signed-off-by: Nishank Trivedi <nistrive@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: Govindarajulu Varadarajan <govindarajulu90@gmail.com>
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | MAINTAINERS | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/enic.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/enic_main.c | 55 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/vnic_dev.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/vnic_dev.h | 1 |
5 files changed, 54 insertions, 19 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 705bb96bc37e..ecb83cdf06c0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2076,7 +2076,8 @@ F: drivers/usb/chipidea/ | |||
2076 | 2076 | ||
2077 | CISCO VIC ETHERNET NIC DRIVER | 2077 | CISCO VIC ETHERNET NIC DRIVER |
2078 | M: Christian Benvenuti <benve@cisco.com> | 2078 | M: Christian Benvenuti <benve@cisco.com> |
2079 | M: Roopa Prabhu <roprabhu@cisco.com> | 2079 | M: Sujith Sankar <ssujith@cisco.com> |
2080 | M: Govindarajulu Varadarajan <govindarajulu90@gmail.com> | ||
2080 | M: Neel Patel <neepatel@cisco.com> | 2081 | M: Neel Patel <neepatel@cisco.com> |
2081 | M: Nishank Trivedi <nistrive@cisco.com> | 2082 | M: Nishank Trivedi <nistrive@cisco.com> |
2082 | S: Supported | 2083 | S: Supported |
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h index be167318015a..e9f7c656ddda 100644 --- a/drivers/net/ethernet/cisco/enic/enic.h +++ b/drivers/net/ethernet/cisco/enic/enic.h | |||
@@ -32,12 +32,12 @@ | |||
32 | 32 | ||
33 | #define DRV_NAME "enic" | 33 | #define DRV_NAME "enic" |
34 | #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" | 34 | #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" |
35 | #define DRV_VERSION "2.1.1.43" | 35 | #define DRV_VERSION "2.1.1.50" |
36 | #define DRV_COPYRIGHT "Copyright 2008-2013 Cisco Systems, Inc" | 36 | #define DRV_COPYRIGHT "Copyright 2008-2013 Cisco Systems, Inc" |
37 | 37 | ||
38 | #define ENIC_BARS_MAX 6 | 38 | #define ENIC_BARS_MAX 6 |
39 | 39 | ||
40 | #define ENIC_WQ_MAX 1 | 40 | #define ENIC_WQ_MAX 8 |
41 | #define ENIC_RQ_MAX 8 | 41 | #define ENIC_RQ_MAX 8 |
42 | #define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX) | 42 | #define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX) |
43 | #define ENIC_INTR_MAX (ENIC_CQ_MAX + 2) | 43 | #define ENIC_INTR_MAX (ENIC_CQ_MAX + 2) |
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index bcf15b176f41..7b756cf9474a 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c | |||
@@ -128,10 +128,10 @@ static int enic_wq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, | |||
128 | completed_index, enic_wq_free_buf, | 128 | completed_index, enic_wq_free_buf, |
129 | opaque); | 129 | opaque); |
130 | 130 | ||
131 | if (netif_queue_stopped(enic->netdev) && | 131 | if (netif_tx_queue_stopped(netdev_get_tx_queue(enic->netdev, q_number)) && |
132 | vnic_wq_desc_avail(&enic->wq[q_number]) >= | 132 | vnic_wq_desc_avail(&enic->wq[q_number]) >= |
133 | (MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS)) | 133 | (MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS)) |
134 | netif_wake_queue(enic->netdev); | 134 | netif_wake_subqueue(enic->netdev, q_number); |
135 | 135 | ||
136 | spin_unlock(&enic->wq_lock[q_number]); | 136 | spin_unlock(&enic->wq_lock[q_number]); |
137 | 137 | ||
@@ -292,10 +292,15 @@ static irqreturn_t enic_isr_msix_rq(int irq, void *data) | |||
292 | static irqreturn_t enic_isr_msix_wq(int irq, void *data) | 292 | static irqreturn_t enic_isr_msix_wq(int irq, void *data) |
293 | { | 293 | { |
294 | struct enic *enic = data; | 294 | struct enic *enic = data; |
295 | unsigned int cq = enic_cq_wq(enic, 0); | 295 | unsigned int cq; |
296 | unsigned int intr = enic_msix_wq_intr(enic, 0); | 296 | unsigned int intr; |
297 | unsigned int wq_work_to_do = -1; /* no limit */ | 297 | unsigned int wq_work_to_do = -1; /* no limit */ |
298 | unsigned int wq_work_done; | 298 | unsigned int wq_work_done; |
299 | unsigned int wq_irq; | ||
300 | |||
301 | wq_irq = (u32)irq - enic->msix_entry[enic_msix_wq_intr(enic, 0)].vector; | ||
302 | cq = enic_cq_wq(enic, wq_irq); | ||
303 | intr = enic_msix_wq_intr(enic, wq_irq); | ||
299 | 304 | ||
300 | wq_work_done = vnic_cq_service(&enic->cq[cq], | 305 | wq_work_done = vnic_cq_service(&enic->cq[cq], |
301 | wq_work_to_do, enic_wq_service, NULL); | 306 | wq_work_to_do, enic_wq_service, NULL); |
@@ -511,14 +516,18 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb, | |||
511 | struct net_device *netdev) | 516 | struct net_device *netdev) |
512 | { | 517 | { |
513 | struct enic *enic = netdev_priv(netdev); | 518 | struct enic *enic = netdev_priv(netdev); |
514 | struct vnic_wq *wq = &enic->wq[0]; | 519 | struct vnic_wq *wq; |
515 | unsigned long flags; | 520 | unsigned long flags; |
521 | unsigned int txq_map; | ||
516 | 522 | ||
517 | if (skb->len <= 0) { | 523 | if (skb->len <= 0) { |
518 | dev_kfree_skb(skb); | 524 | dev_kfree_skb(skb); |
519 | return NETDEV_TX_OK; | 525 | return NETDEV_TX_OK; |
520 | } | 526 | } |
521 | 527 | ||
528 | txq_map = skb_get_queue_mapping(skb) % enic->wq_count; | ||
529 | wq = &enic->wq[txq_map]; | ||
530 | |||
522 | /* Non-TSO sends must fit within ENIC_NON_TSO_MAX_DESC descs, | 531 | /* Non-TSO sends must fit within ENIC_NON_TSO_MAX_DESC descs, |
523 | * which is very likely. In the off chance it's going to take | 532 | * which is very likely. In the off chance it's going to take |
524 | * more than * ENIC_NON_TSO_MAX_DESC, linearize the skb. | 533 | * more than * ENIC_NON_TSO_MAX_DESC, linearize the skb. |
@@ -531,23 +540,23 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb, | |||
531 | return NETDEV_TX_OK; | 540 | return NETDEV_TX_OK; |
532 | } | 541 | } |
533 | 542 | ||
534 | spin_lock_irqsave(&enic->wq_lock[0], flags); | 543 | spin_lock_irqsave(&enic->wq_lock[txq_map], flags); |
535 | 544 | ||
536 | if (vnic_wq_desc_avail(wq) < | 545 | if (vnic_wq_desc_avail(wq) < |
537 | skb_shinfo(skb)->nr_frags + ENIC_DESC_MAX_SPLITS) { | 546 | skb_shinfo(skb)->nr_frags + ENIC_DESC_MAX_SPLITS) { |
538 | netif_stop_queue(netdev); | 547 | netif_tx_stop_queue(netdev_get_tx_queue(netdev, txq_map)); |
539 | /* This is a hard error, log it */ | 548 | /* This is a hard error, log it */ |
540 | netdev_err(netdev, "BUG! Tx ring full when queue awake!\n"); | 549 | netdev_err(netdev, "BUG! Tx ring full when queue awake!\n"); |
541 | spin_unlock_irqrestore(&enic->wq_lock[0], flags); | 550 | spin_unlock_irqrestore(&enic->wq_lock[txq_map], flags); |
542 | return NETDEV_TX_BUSY; | 551 | return NETDEV_TX_BUSY; |
543 | } | 552 | } |
544 | 553 | ||
545 | enic_queue_wq_skb(enic, wq, skb); | 554 | enic_queue_wq_skb(enic, wq, skb); |
546 | 555 | ||
547 | if (vnic_wq_desc_avail(wq) < MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS) | 556 | if (vnic_wq_desc_avail(wq) < MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS) |
548 | netif_stop_queue(netdev); | 557 | netif_tx_stop_queue(netdev_get_tx_queue(netdev, txq_map)); |
549 | 558 | ||
550 | spin_unlock_irqrestore(&enic->wq_lock[0], flags); | 559 | spin_unlock_irqrestore(&enic->wq_lock[txq_map], flags); |
551 | 560 | ||
552 | return NETDEV_TX_OK; | 561 | return NETDEV_TX_OK; |
553 | } | 562 | } |
@@ -1025,6 +1034,14 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, | |||
1025 | 1034 | ||
1026 | skb_put(skb, bytes_written); | 1035 | skb_put(skb, bytes_written); |
1027 | skb->protocol = eth_type_trans(skb, netdev); | 1036 | skb->protocol = eth_type_trans(skb, netdev); |
1037 | skb_record_rx_queue(skb, q_number); | ||
1038 | if (netdev->features & NETIF_F_RXHASH) { | ||
1039 | skb->rxhash = rss_hash; | ||
1040 | if (rss_type & (NIC_CFG_RSS_HASH_TYPE_TCP_IPV6_EX | | ||
1041 | NIC_CFG_RSS_HASH_TYPE_TCP_IPV6 | | ||
1042 | NIC_CFG_RSS_HASH_TYPE_TCP_IPV4)) | ||
1043 | skb->l4_rxhash = true; | ||
1044 | } | ||
1028 | 1045 | ||
1029 | if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc) { | 1046 | if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc) { |
1030 | skb->csum = htons(checksum); | 1047 | skb->csum = htons(checksum); |
@@ -1369,7 +1386,7 @@ static int enic_open(struct net_device *netdev) | |||
1369 | 1386 | ||
1370 | enic_set_rx_mode(netdev); | 1387 | enic_set_rx_mode(netdev); |
1371 | 1388 | ||
1372 | netif_wake_queue(netdev); | 1389 | netif_tx_wake_all_queues(netdev); |
1373 | 1390 | ||
1374 | for (i = 0; i < enic->rq_count; i++) | 1391 | for (i = 0; i < enic->rq_count; i++) |
1375 | napi_enable(&enic->napi[i]); | 1392 | napi_enable(&enic->napi[i]); |
@@ -2032,7 +2049,8 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2032 | * instance data is initialized to zero. | 2049 | * instance data is initialized to zero. |
2033 | */ | 2050 | */ |
2034 | 2051 | ||
2035 | netdev = alloc_etherdev(sizeof(struct enic)); | 2052 | netdev = alloc_etherdev_mqs(sizeof(struct enic), |
2053 | ENIC_RQ_MAX, ENIC_WQ_MAX); | ||
2036 | if (!netdev) | 2054 | if (!netdev) |
2037 | return -ENOMEM; | 2055 | return -ENOMEM; |
2038 | 2056 | ||
@@ -2062,11 +2080,11 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2062 | pci_set_master(pdev); | 2080 | pci_set_master(pdev); |
2063 | 2081 | ||
2064 | /* Query PCI controller on system for DMA addressing | 2082 | /* Query PCI controller on system for DMA addressing |
2065 | * limitation for the device. Try 40-bit first, and | 2083 | * limitation for the device. Try 64-bit first, and |
2066 | * fail to 32-bit. | 2084 | * fail to 32-bit. |
2067 | */ | 2085 | */ |
2068 | 2086 | ||
2069 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(40)); | 2087 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); |
2070 | if (err) { | 2088 | if (err) { |
2071 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 2089 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
2072 | if (err) { | 2090 | if (err) { |
@@ -2080,10 +2098,10 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2080 | goto err_out_release_regions; | 2098 | goto err_out_release_regions; |
2081 | } | 2099 | } |
2082 | } else { | 2100 | } else { |
2083 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40)); | 2101 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); |
2084 | if (err) { | 2102 | if (err) { |
2085 | dev_err(dev, "Unable to obtain %u-bit DMA " | 2103 | dev_err(dev, "Unable to obtain %u-bit DMA " |
2086 | "for consistent allocations, aborting\n", 40); | 2104 | "for consistent allocations, aborting\n", 64); |
2087 | goto err_out_release_regions; | 2105 | goto err_out_release_regions; |
2088 | } | 2106 | } |
2089 | using_dac = 1; | 2107 | using_dac = 1; |
@@ -2198,6 +2216,9 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2198 | goto err_out_dev_close; | 2216 | goto err_out_dev_close; |
2199 | } | 2217 | } |
2200 | 2218 | ||
2219 | netif_set_real_num_tx_queues(netdev, enic->wq_count); | ||
2220 | netif_set_real_num_rx_queues(netdev, enic->rq_count); | ||
2221 | |||
2201 | /* Setup notification timer, HW reset task, and wq locks | 2222 | /* Setup notification timer, HW reset task, and wq locks |
2202 | */ | 2223 | */ |
2203 | 2224 | ||
@@ -2246,6 +2267,8 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2246 | if (ENIC_SETTING(enic, TSO)) | 2267 | if (ENIC_SETTING(enic, TSO)) |
2247 | netdev->hw_features |= NETIF_F_TSO | | 2268 | netdev->hw_features |= NETIF_F_TSO | |
2248 | NETIF_F_TSO6 | NETIF_F_TSO_ECN; | 2269 | NETIF_F_TSO6 | NETIF_F_TSO_ECN; |
2270 | if (ENIC_SETTING(enic, RSS)) | ||
2271 | netdev->hw_features |= NETIF_F_RXHASH; | ||
2249 | if (ENIC_SETTING(enic, RXCSUM)) | 2272 | if (ENIC_SETTING(enic, RXCSUM)) |
2250 | netdev->hw_features |= NETIF_F_RXCSUM; | 2273 | netdev->hw_features |= NETIF_F_RXCSUM; |
2251 | 2274 | ||
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.c b/drivers/net/ethernet/cisco/enic/vnic_dev.c index 97455c573db5..69dd92598b7e 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_dev.c +++ b/drivers/net/ethernet/cisco/enic/vnic_dev.c | |||
@@ -175,6 +175,7 @@ unsigned int vnic_dev_get_res_count(struct vnic_dev *vdev, | |||
175 | { | 175 | { |
176 | return vdev->res[type].count; | 176 | return vdev->res[type].count; |
177 | } | 177 | } |
178 | EXPORT_SYMBOL(vnic_dev_get_res_count); | ||
178 | 179 | ||
179 | void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type, | 180 | void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type, |
180 | unsigned int index) | 181 | unsigned int index) |
@@ -193,6 +194,7 @@ void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type, | |||
193 | return (char __iomem *)vdev->res[type].vaddr; | 194 | return (char __iomem *)vdev->res[type].vaddr; |
194 | } | 195 | } |
195 | } | 196 | } |
197 | EXPORT_SYMBOL(vnic_dev_get_res); | ||
196 | 198 | ||
197 | static unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, | 199 | static unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, |
198 | unsigned int desc_count, unsigned int desc_size) | 200 | unsigned int desc_count, unsigned int desc_size) |
@@ -942,6 +944,7 @@ void vnic_dev_unregister(struct vnic_dev *vdev) | |||
942 | kfree(vdev); | 944 | kfree(vdev); |
943 | } | 945 | } |
944 | } | 946 | } |
947 | EXPORT_SYMBOL(vnic_dev_unregister); | ||
945 | 948 | ||
946 | struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, | 949 | struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, |
947 | void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar, | 950 | void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar, |
@@ -969,6 +972,13 @@ err_out: | |||
969 | vnic_dev_unregister(vdev); | 972 | vnic_dev_unregister(vdev); |
970 | return NULL; | 973 | return NULL; |
971 | } | 974 | } |
975 | EXPORT_SYMBOL(vnic_dev_register); | ||
976 | |||
977 | struct pci_dev *vnic_dev_get_pdev(struct vnic_dev *vdev) | ||
978 | { | ||
979 | return vdev->pdev; | ||
980 | } | ||
981 | EXPORT_SYMBOL(vnic_dev_get_pdev); | ||
972 | 982 | ||
973 | int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len) | 983 | int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len) |
974 | { | 984 | { |
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.h b/drivers/net/ethernet/cisco/enic/vnic_dev.h index f3d9b79ba77e..e670029862a1 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_dev.h +++ b/drivers/net/ethernet/cisco/enic/vnic_dev.h | |||
@@ -127,6 +127,7 @@ int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev, | |||
127 | struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, | 127 | struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, |
128 | void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar, | 128 | void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar, |
129 | unsigned int num_bars); | 129 | unsigned int num_bars); |
130 | struct pci_dev *vnic_dev_get_pdev(struct vnic_dev *vdev); | ||
130 | int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len); | 131 | int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len); |
131 | int vnic_dev_enable2(struct vnic_dev *vdev, int active); | 132 | int vnic_dev_enable2(struct vnic_dev *vdev, int active); |
132 | int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status); | 133 | int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status); |