aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJeb Cramer <cramerj@intel.com>2008-03-03 18:04:02 -0500
committerJeff Garzik <jeff@garzik.org>2008-03-17 07:49:28 -0400
commitbd0362dde080cef377d99fa5beb5c25308c29c73 (patch)
tree45269ba2224fb3e27d8384e85fd5fc8be7884cb9 /drivers/net
parentf494e8faa77bd4147324f7666441e0b780e7db94 (diff)
ixgbe: Add optional DCA infrastructure
82598 cards and up support DCA, which enables the chipset to warm up the caches for upcoming payload data. This code makes the driver plug into the CONFIG_DCA infrastructure that was merged earlier. Signed-off-by: Jeb Cramer <cramerj@intel.com> Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ixgbe/ixgbe.h9
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c148
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};
81MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl); 81MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl);
82 82
83#ifdef CONFIG_DCA
84static int ixgbe_notify_dca(struct notifier_block *, unsigned long event,
85 void *p);
86static struct notifier_block dca_notifier = {
87 .notifier_call = ixgbe_notify_dca,
88 .next = NULL,
89 .priority = 0
90};
91#endif
92
83MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>"); 93MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
84MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver"); 94MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver");
85MODULE_LICENSE("GPL"); 95MODULE_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
304static 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
323static 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
341static 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
358static 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 **/
3673static void __exit ixgbe_exit_module(void) 3804static 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
3813static 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
3677module_exit(ixgbe_exit_module); 3825module_exit(ixgbe_exit_module);
3678 3826
3679/* ixgbe_main.c */ 3827/* ixgbe_main.c */