aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAyyappan Veeraiyan <ayyappan.veeraiyan@intel.com>2008-03-03 18:03:52 -0500
committerJeff Garzik <jeff@garzik.org>2008-03-17 07:49:28 -0400
commit30eba97a3f076cf4e100b598ee9a1b1439b0cfaa (patch)
tree53799731423fd257ef34bfbb1e6efad7cdfa9b98 /drivers/net
parent021230d40ae0e6508d6c717b6e0d6d81cd77ac25 (diff)
ixgbe: Introduce Multiqueue TX
Now that the irq vector code is in place, we can add the conditional multiqueue TX code in the driver. This requires the optional CONFIG_NETDEVICES_MULTIQUEUE=y and will not be enabled without it. Signed-off-by: Ayyappan Veeraiyan <ayyappan.veeraiyan@intel.com> Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com> Acked-by: Waskiewicz Jr, Peter P <peter.p.waskiewicz.jr@intel.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c15
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c56
2 files changed, 66 insertions, 5 deletions
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index a119cbd8dbb8..85b7d15e1217 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -246,13 +246,26 @@ static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
246 246
247static int ixgbe_set_tso(struct net_device *netdev, u32 data) 247static int ixgbe_set_tso(struct net_device *netdev, u32 data)
248{ 248{
249
250 if (data) { 249 if (data) {
251 netdev->features |= NETIF_F_TSO; 250 netdev->features |= NETIF_F_TSO;
252 netdev->features |= NETIF_F_TSO6; 251 netdev->features |= NETIF_F_TSO6;
253 } else { 252 } else {
253#ifdef CONFIG_NETDEVICES_MULTIQUEUE
254 struct ixgbe_adapter *adapter = netdev_priv(netdev);
255 int i;
256#endif
257 netif_stop_queue(netdev);
258#ifdef CONFIG_NETDEVICES_MULTIQUEUE
259 for (i = 0; i < adapter->num_tx_queues; i++)
260 netif_stop_subqueue(netdev, i);
261#endif
254 netdev->features &= ~NETIF_F_TSO; 262 netdev->features &= ~NETIF_F_TSO;
255 netdev->features &= ~NETIF_F_TSO6; 263 netdev->features &= ~NETIF_F_TSO6;
264#ifdef CONFIG_NETDEVICES_MULTIQUEUE
265 for (i = 0; i < adapter->num_tx_queues; i++)
266 netif_start_subqueue(netdev, i);
267#endif
268 netif_start_queue(netdev);
256 } 269 }
257 return 0; 270 return 0;
258} 271}
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index fecc8ea79e9d..fc1c226f5751 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -256,16 +256,28 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
256 * sees the new next_to_clean. 256 * sees the new next_to_clean.
257 */ 257 */
258 smp_mb(); 258 smp_mb();
259#ifdef CONFIG_NETDEVICES_MULTIQUEUE
260 if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
261 !test_bit(__IXGBE_DOWN, &adapter->state)) {
262 netif_wake_subqueue(netdev, tx_ring->queue_index);
263 adapter->restart_queue++;
264 }
265#else
259 if (netif_queue_stopped(netdev) && 266 if (netif_queue_stopped(netdev) &&
260 !test_bit(__IXGBE_DOWN, &adapter->state)) { 267 !test_bit(__IXGBE_DOWN, &adapter->state)) {
261 netif_wake_queue(netdev); 268 netif_wake_queue(netdev);
262 adapter->restart_queue++; 269 adapter->restart_queue++;
263 } 270 }
271#endif
264 } 272 }
265 273
266 if (adapter->detect_tx_hung) 274 if (adapter->detect_tx_hung)
267 if (ixgbe_check_tx_hang(adapter, tx_ring, eop, eop_desc)) 275 if (ixgbe_check_tx_hang(adapter, tx_ring, eop, eop_desc))
276#ifdef CONFIG_NETDEVICES_MULTIQUEUE
277 netif_stop_subqueue(netdev, tx_ring->queue_index);
278#else
268 netif_stop_queue(netdev); 279 netif_stop_queue(netdev);
280#endif
269 281
270 if (total_tx_packets >= tx_ring->work_limit) 282 if (total_tx_packets >= tx_ring->work_limit)
271 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->eims_value); 283 IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->eims_value);
@@ -1812,7 +1824,11 @@ static void __devinit ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
1812 case (IXGBE_FLAG_RSS_ENABLED): 1824 case (IXGBE_FLAG_RSS_ENABLED):
1813 rss_m = 0xF; 1825 rss_m = 0xF;
1814 nrq = rss_i; 1826 nrq = rss_i;
1827#ifdef CONFIG_NETDEVICES_MULTIQUEUE
1828 ntq = rss_i;
1829#else
1815 ntq = 1; 1830 ntq = 1;
1831#endif
1816 break; 1832 break;
1817 case 0: 1833 case 0:
1818 default: 1834 default:
@@ -1986,6 +2002,10 @@ try_msi:
1986 } 2002 }
1987 2003
1988out: 2004out:
2005#ifdef CONFIG_NETDEVICES_MULTIQUEUE
2006 /* Notify the stack of the (possibly) reduced Tx Queue count. */
2007 adapter->netdev->egress_subqueue_count = adapter->num_tx_queues;
2008#endif
1989 2009
1990 return err; 2010 return err;
1991} 2011}
@@ -2504,6 +2524,9 @@ static void ixgbe_watchdog(unsigned long data)
2504 struct net_device *netdev = adapter->netdev; 2524 struct net_device *netdev = adapter->netdev;
2505 bool link_up; 2525 bool link_up;
2506 u32 link_speed = 0; 2526 u32 link_speed = 0;
2527#ifdef CONFIG_NETDEVICES_MULTIQUEUE
2528 int i;
2529#endif
2507 2530
2508 adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up); 2531 adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up);
2509 2532
@@ -2525,6 +2548,10 @@ static void ixgbe_watchdog(unsigned long data)
2525 2548
2526 netif_carrier_on(netdev); 2549 netif_carrier_on(netdev);
2527 netif_wake_queue(netdev); 2550 netif_wake_queue(netdev);
2551#ifdef CONFIG_NETDEVICES_MULTIQUEUE
2552 for (i = 0; i < adapter->num_tx_queues; i++)
2553 netif_wake_subqueue(netdev, i);
2554#endif
2528 } else { 2555 } else {
2529 /* Force detection of hung controller */ 2556 /* Force detection of hung controller */
2530 adapter->detect_tx_hung = true; 2557 adapter->detect_tx_hung = true;
@@ -2568,7 +2595,6 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
2568 struct ixgbe_tx_buffer *tx_buffer_info; 2595 struct ixgbe_tx_buffer *tx_buffer_info;
2569 u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0; 2596 u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0;
2570 u32 mss_l4len_idx = 0, l4len; 2597 u32 mss_l4len_idx = 0, l4len;
2571 *hdr_len = 0;
2572 2598
2573 if (skb_is_gso(skb)) { 2599 if (skb_is_gso(skb)) {
2574 if (skb_header_cloned(skb)) { 2600 if (skb_header_cloned(skb)) {
@@ -2852,7 +2878,11 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
2852{ 2878{
2853 struct ixgbe_adapter *adapter = netdev_priv(netdev); 2879 struct ixgbe_adapter *adapter = netdev_priv(netdev);
2854 2880
2881#ifdef CONFIG_NETDEVICES_MULTIQUEUE
2882 netif_stop_subqueue(netdev, tx_ring->queue_index);
2883#else
2855 netif_stop_queue(netdev); 2884 netif_stop_queue(netdev);
2885#endif
2856 /* Herbert's original patch had: 2886 /* Herbert's original patch had:
2857 * smp_mb__after_netif_stop_queue(); 2887 * smp_mb__after_netif_stop_queue();
2858 * but since that doesn't exist yet, just open code it. */ 2888 * but since that doesn't exist yet, just open code it. */
@@ -2864,7 +2894,11 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
2864 return -EBUSY; 2894 return -EBUSY;
2865 2895
2866 /* A reprieve! - use start_queue because it doesn't call schedule */ 2896 /* A reprieve! - use start_queue because it doesn't call schedule */
2897#ifdef CONFIG_NETDEVICES_MULTIQUEUE
2898 netif_wake_subqueue(netdev, tx_ring->queue_index);
2899#else
2867 netif_wake_queue(netdev); 2900 netif_wake_queue(netdev);
2901#endif
2868 ++adapter->restart_queue; 2902 ++adapter->restart_queue;
2869 return 0; 2903 return 0;
2870} 2904}
@@ -2885,15 +2919,18 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
2885 unsigned int len = skb->len; 2919 unsigned int len = skb->len;
2886 unsigned int first; 2920 unsigned int first;
2887 unsigned int tx_flags = 0; 2921 unsigned int tx_flags = 0;
2888 u8 hdr_len; 2922 u8 hdr_len = 0;
2889 int tso; 2923 int r_idx = 0, tso;
2890 unsigned int mss = 0; 2924 unsigned int mss = 0;
2891 int count = 0; 2925 int count = 0;
2892 unsigned int f; 2926 unsigned int f;
2893 unsigned int nr_frags = skb_shinfo(skb)->nr_frags; 2927 unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
2894 len -= skb->data_len; 2928 len -= skb->data_len;
2929#ifdef CONFIG_NETDEVICES_MULTIQUEUE
2930 r_idx = (adapter->num_tx_queues - 1) & skb->queue_mapping;
2931#endif
2932 tx_ring = &adapter->tx_ring[r_idx];
2895 2933
2896 tx_ring = adapter->tx_ring;
2897 2934
2898 if (skb->len <= 0) { 2935 if (skb->len <= 0) {
2899 dev_kfree_skb(skb); 2936 dev_kfree_skb(skb);
@@ -3078,7 +3115,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
3078 3115
3079 pci_set_master(pdev); 3116 pci_set_master(pdev);
3080 3117
3118#ifdef CONFIG_NETDEVICES_MULTIQUEUE
3119 netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), MAX_TX_QUEUES);
3120#else
3081 netdev = alloc_etherdev(sizeof(struct ixgbe_adapter)); 3121 netdev = alloc_etherdev(sizeof(struct ixgbe_adapter));
3122#endif
3082 if (!netdev) { 3123 if (!netdev) {
3083 err = -ENOMEM; 3124 err = -ENOMEM;
3084 goto err_alloc_etherdev; 3125 goto err_alloc_etherdev;
@@ -3164,6 +3205,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
3164 if (pci_using_dac) 3205 if (pci_using_dac)
3165 netdev->features |= NETIF_F_HIGHDMA; 3206 netdev->features |= NETIF_F_HIGHDMA;
3166 3207
3208#ifdef CONFIG_NETDEVICES_MULTIQUEUE
3209 netdev->features |= NETIF_F_MULTI_QUEUE;
3210#endif
3167 3211
3168 /* make sure the EEPROM is good */ 3212 /* make sure the EEPROM is good */
3169 if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) { 3213 if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) {
@@ -3231,6 +3275,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
3231 3275
3232 netif_carrier_off(netdev); 3276 netif_carrier_off(netdev);
3233 netif_stop_queue(netdev); 3277 netif_stop_queue(netdev);
3278#ifdef CONFIG_NETDEVICES_MULTIQUEUE
3279 for (i = 0; i < adapter->num_tx_queues; i++)
3280 netif_stop_subqueue(netdev, i);
3281#endif
3234 3282
3235 ixgbe_napi_add_all(adapter); 3283 ixgbe_napi_add_all(adapter);
3236 3284