diff options
author | Ayyappan Veeraiyan <ayyappan.veeraiyan@intel.com> | 2008-03-03 18:03:52 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-03-17 07:49:28 -0400 |
commit | 30eba97a3f076cf4e100b598ee9a1b1439b0cfaa (patch) | |
tree | 53799731423fd257ef34bfbb1e6efad7cdfa9b98 | |
parent | 021230d40ae0e6508d6c717b6e0d6d81cd77ac25 (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>
-rw-r--r-- | drivers/net/ixgbe/ixgbe_ethtool.c | 15 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 56 |
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 | ||
247 | static int ixgbe_set_tso(struct net_device *netdev, u32 data) | 247 | static 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 | ||
1988 | out: | 2004 | out: |
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 | ||