diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ixgbe/ixgbe.h | 9 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 148 |
2 files changed, 157 insertions, 0 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 79f5519e2aa9..d98113472a89 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h | |||
@@ -36,6 +36,9 @@ | |||
36 | #include "ixgbe_type.h" | 36 | #include "ixgbe_type.h" |
37 | #include "ixgbe_common.h" | 37 | #include "ixgbe_common.h" |
38 | 38 | ||
39 | #ifdef CONFIG_DCA | ||
40 | #include <linux/dca.h> | ||
41 | #endif | ||
39 | 42 | ||
40 | #define IXGBE_ERR(args...) printk(KERN_ERR "ixgbe: " args) | 43 | #define IXGBE_ERR(args...) printk(KERN_ERR "ixgbe: " args) |
41 | 44 | ||
@@ -142,6 +145,11 @@ struct ixgbe_ring { | |||
142 | u16 reg_idx; /* holds the special value that gets the hardware register | 145 | u16 reg_idx; /* holds the special value that gets the hardware register |
143 | * offset associated with this ring, which is different | 146 | * offset associated with this ring, which is different |
144 | * for DCE and RSS modes */ | 147 | * for DCE and RSS modes */ |
148 | |||
149 | #ifdef CONFIG_DCA | ||
150 | /* cpu for tx queue */ | ||
151 | int cpu; | ||
152 | #endif | ||
145 | struct ixgbe_queue_stats stats; | 153 | struct ixgbe_queue_stats stats; |
146 | u8 v_idx; /* maps directly to the index for this ring in the hardware | 154 | u8 v_idx; /* maps directly to the index for this ring in the hardware |
147 | * vector array, can also be used for finding the bit in EICR | 155 | * vector array, can also be used for finding the bit in EICR |
@@ -261,6 +269,7 @@ struct ixgbe_adapter { | |||
261 | #define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 5) | 269 | #define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 5) |
262 | #define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 6) | 270 | #define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 6) |
263 | #define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 7) | 271 | #define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 7) |
272 | #define IXGBE_FLAG_DCA_ENABLED (u32)(1 << 8) | ||
264 | 273 | ||
265 | /* OS defined structs */ | 274 | /* OS defined structs */ |
266 | struct net_device *netdev; | 275 | struct net_device *netdev; |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index e1f11e686f47..da8becf9a501 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -80,6 +80,16 @@ static struct pci_device_id ixgbe_pci_tbl[] = { | |||
80 | }; | 80 | }; |
81 | MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl); | 81 | MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl); |
82 | 82 | ||
83 | #ifdef CONFIG_DCA | ||
84 | static int ixgbe_notify_dca(struct notifier_block *, unsigned long event, | ||
85 | void *p); | ||
86 | static struct notifier_block dca_notifier = { | ||
87 | .notifier_call = ixgbe_notify_dca, | ||
88 | .next = NULL, | ||
89 | .priority = 0 | ||
90 | }; | ||
91 | #endif | ||
92 | |||
83 | MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); | 93 | MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); |
84 | MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver"); | 94 | MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver"); |
85 | MODULE_LICENSE("GPL"); | 95 | MODULE_LICENSE("GPL"); |
@@ -290,6 +300,91 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter, | |||
290 | return cleaned; | 300 | return cleaned; |
291 | } | 301 | } |
292 | 302 | ||
303 | #ifdef CONFIG_DCA | ||
304 | static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, | ||
305 | struct ixgbe_ring *rxr) | ||
306 | { | ||
307 | u32 rxctrl; | ||
308 | int cpu = get_cpu(); | ||
309 | int q = rxr - adapter->rx_ring; | ||
310 | |||
311 | if (rxr->cpu != cpu) { | ||
312 | rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q)); | ||
313 | rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK; | ||
314 | rxctrl |= dca_get_tag(cpu); | ||
315 | rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN; | ||
316 | rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN; | ||
317 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl); | ||
318 | rxr->cpu = cpu; | ||
319 | } | ||
320 | put_cpu(); | ||
321 | } | ||
322 | |||
323 | static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter, | ||
324 | struct ixgbe_ring *txr) | ||
325 | { | ||
326 | u32 txctrl; | ||
327 | int cpu = get_cpu(); | ||
328 | int q = txr - adapter->tx_ring; | ||
329 | |||
330 | if (txr->cpu != cpu) { | ||
331 | txctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q)); | ||
332 | txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK; | ||
333 | txctrl |= dca_get_tag(cpu); | ||
334 | txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN; | ||
335 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q), txctrl); | ||
336 | txr->cpu = cpu; | ||
337 | } | ||
338 | put_cpu(); | ||
339 | } | ||
340 | |||
341 | static void ixgbe_setup_dca(struct ixgbe_adapter *adapter) | ||
342 | { | ||
343 | int i; | ||
344 | |||
345 | if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED)) | ||
346 | return; | ||
347 | |||
348 | for (i = 0; i < adapter->num_tx_queues; i++) { | ||
349 | adapter->tx_ring[i].cpu = -1; | ||
350 | ixgbe_update_tx_dca(adapter, &adapter->tx_ring[i]); | ||
351 | } | ||
352 | for (i = 0; i < adapter->num_rx_queues; i++) { | ||
353 | adapter->rx_ring[i].cpu = -1; | ||
354 | ixgbe_update_rx_dca(adapter, &adapter->rx_ring[i]); | ||
355 | } | ||
356 | } | ||
357 | |||
358 | static int __ixgbe_notify_dca(struct device *dev, void *data) | ||
359 | { | ||
360 | struct net_device *netdev = dev_get_drvdata(dev); | ||
361 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||
362 | unsigned long event = *(unsigned long *)data; | ||
363 | |||
364 | switch (event) { | ||
365 | case DCA_PROVIDER_ADD: | ||
366 | adapter->flags |= IXGBE_FLAG_DCA_ENABLED; | ||
367 | /* Always use CB2 mode, difference is masked | ||
368 | * in the CB driver. */ | ||
369 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2); | ||
370 | if (dca_add_requester(dev) == IXGBE_SUCCESS) { | ||
371 | ixgbe_setup_dca(adapter); | ||
372 | break; | ||
373 | } | ||
374 | /* Fall Through since DCA is disabled. */ | ||
375 | case DCA_PROVIDER_REMOVE: | ||
376 | if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { | ||
377 | dca_remove_requester(dev); | ||
378 | adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED; | ||
379 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 1); | ||
380 | } | ||
381 | break; | ||
382 | } | ||
383 | |||
384 | return IXGBE_SUCCESS; | ||
385 | } | ||
386 | |||
387 | #endif /* CONFIG_DCA */ | ||
293 | /** | 388 | /** |
294 | * ixgbe_receive_skb - Send a completed packet up the stack | 389 | * ixgbe_receive_skb - Send a completed packet up the stack |
295 | * @adapter: board private structure | 390 | * @adapter: board private structure |
@@ -811,6 +906,10 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data) | |||
811 | r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); | 906 | r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); |
812 | for (i = 0; i < q_vector->txr_count; i++) { | 907 | for (i = 0; i < q_vector->txr_count; i++) { |
813 | txr = &(adapter->tx_ring[r_idx]); | 908 | txr = &(adapter->tx_ring[r_idx]); |
909 | #ifdef CONFIG_DCA | ||
910 | if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) | ||
911 | ixgbe_update_tx_dca(adapter, txr); | ||
912 | #endif | ||
814 | txr->total_bytes = 0; | 913 | txr->total_bytes = 0; |
815 | txr->total_packets = 0; | 914 | txr->total_packets = 0; |
816 | ixgbe_clean_tx_irq(adapter, txr); | 915 | ixgbe_clean_tx_irq(adapter, txr); |
@@ -872,6 +971,10 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) | |||
872 | 971 | ||
873 | r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); | 972 | r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); |
874 | rxr = &(adapter->rx_ring[r_idx]); | 973 | rxr = &(adapter->rx_ring[r_idx]); |
974 | #ifdef CONFIG_DCA | ||
975 | if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) | ||
976 | ixgbe_update_rx_dca(adapter, rxr); | ||
977 | #endif | ||
875 | 978 | ||
876 | ixgbe_clean_rx_irq(adapter, rxr, &work_done, budget); | 979 | ixgbe_clean_rx_irq(adapter, rxr, &work_done, budget); |
877 | 980 | ||
@@ -1924,6 +2027,13 @@ static int ixgbe_poll(struct napi_struct *napi, int budget) | |||
1924 | struct ixgbe_adapter *adapter = q_vector->adapter; | 2027 | struct ixgbe_adapter *adapter = q_vector->adapter; |
1925 | int tx_cleaned = 0, work_done = 0; | 2028 | int tx_cleaned = 0, work_done = 0; |
1926 | 2029 | ||
2030 | #ifdef CONFIG_DCA | ||
2031 | if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { | ||
2032 | ixgbe_update_tx_dca(adapter, adapter->tx_ring); | ||
2033 | ixgbe_update_rx_dca(adapter, adapter->rx_ring); | ||
2034 | } | ||
2035 | #endif | ||
2036 | |||
1927 | tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring); | 2037 | tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring); |
1928 | ixgbe_clean_rx_irq(adapter, adapter->rx_ring, &work_done, budget); | 2038 | ixgbe_clean_rx_irq(adapter, adapter->rx_ring, &work_done, budget); |
1929 | 2039 | ||
@@ -3494,6 +3604,15 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
3494 | if (err) | 3604 | if (err) |
3495 | goto err_register; | 3605 | goto err_register; |
3496 | 3606 | ||
3607 | #ifdef CONFIG_DCA | ||
3608 | if (dca_add_requester(&pdev->dev) == IXGBE_SUCCESS) { | ||
3609 | adapter->flags |= IXGBE_FLAG_DCA_ENABLED; | ||
3610 | /* always use CB2 mode, difference is masked | ||
3611 | * in the CB driver */ | ||
3612 | IXGBE_WRITE_REG(hw, IXGBE_DCA_CTRL, 2); | ||
3613 | ixgbe_setup_dca(adapter); | ||
3614 | } | ||
3615 | #endif | ||
3497 | 3616 | ||
3498 | dev_info(&pdev->dev, "Intel(R) 10 Gigabit Network Connection\n"); | 3617 | dev_info(&pdev->dev, "Intel(R) 10 Gigabit Network Connection\n"); |
3499 | cards_found++; | 3618 | cards_found++; |
@@ -3535,6 +3654,14 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) | |||
3535 | 3654 | ||
3536 | flush_scheduled_work(); | 3655 | flush_scheduled_work(); |
3537 | 3656 | ||
3657 | #ifdef CONFIG_DCA | ||
3658 | if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { | ||
3659 | adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED; | ||
3660 | dca_remove_requester(&pdev->dev); | ||
3661 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 1); | ||
3662 | } | ||
3663 | |||
3664 | #endif | ||
3538 | unregister_netdev(netdev); | 3665 | unregister_netdev(netdev); |
3539 | 3666 | ||
3540 | ixgbe_reset_interrupt_capability(adapter); | 3667 | ixgbe_reset_interrupt_capability(adapter); |
@@ -3659,6 +3786,10 @@ static int __init ixgbe_init_module(void) | |||
3659 | 3786 | ||
3660 | printk(KERN_INFO "%s: %s\n", ixgbe_driver_name, ixgbe_copyright); | 3787 | printk(KERN_INFO "%s: %s\n", ixgbe_driver_name, ixgbe_copyright); |
3661 | 3788 | ||
3789 | #ifdef CONFIG_DCA | ||
3790 | dca_register_notify(&dca_notifier); | ||
3791 | |||
3792 | #endif | ||
3662 | ret = pci_register_driver(&ixgbe_driver); | 3793 | ret = pci_register_driver(&ixgbe_driver); |
3663 | return ret; | 3794 | return ret; |
3664 | } | 3795 | } |
@@ -3672,8 +3803,25 @@ module_init(ixgbe_init_module); | |||
3672 | **/ | 3803 | **/ |
3673 | static void __exit ixgbe_exit_module(void) | 3804 | static void __exit ixgbe_exit_module(void) |
3674 | { | 3805 | { |
3806 | #ifdef CONFIG_DCA | ||
3807 | dca_unregister_notify(&dca_notifier); | ||
3808 | #endif | ||
3675 | pci_unregister_driver(&ixgbe_driver); | 3809 | pci_unregister_driver(&ixgbe_driver); |
3676 | } | 3810 | } |
3811 | |||
3812 | #ifdef CONFIG_DCA | ||
3813 | static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event, | ||
3814 | void *p) | ||
3815 | { | ||
3816 | int ret_val; | ||
3817 | |||
3818 | ret_val = driver_for_each_device(&ixgbe_driver.driver, NULL, &event, | ||
3819 | __ixgbe_notify_dca); | ||
3820 | |||
3821 | return ret_val ? NOTIFY_BAD : NOTIFY_DONE; | ||
3822 | } | ||
3823 | #endif /* CONFIG_DCA */ | ||
3824 | |||
3677 | module_exit(ixgbe_exit_module); | 3825 | module_exit(ixgbe_exit_module); |
3678 | 3826 | ||
3679 | /* ixgbe_main.c */ | 3827 | /* ixgbe_main.c */ |