Loading drivers/net/myri10ge/myri10ge.c +145 −1 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ #include <linux/if_ether.h> #include <linux/if_vlan.h> #include <linux/inet_lro.h> #include <linux/dca.h> #include <linux/ip.h> #include <linux/inet.h> #include <linux/in.h> Loading Loading @@ -185,6 +186,11 @@ struct myri10ge_slice_state { dma_addr_t fw_stats_bus; int watchdog_tx_done; int watchdog_tx_req; #ifdef CONFIG_DCA int cached_dca_tag; int cpu; __be32 __iomem *dca_tag; #endif char irq_desc[32]; }; Loading Loading @@ -212,6 +218,9 @@ struct myri10ge_priv { int msi_enabled; int msix_enabled; struct msix_entry *msix_vectors; #ifdef CONFIG_DCA int dca_enabled; #endif u32 link_state; unsigned int rdma_tags_available; int intr_coal_delay; Loading Loading @@ -335,6 +344,10 @@ static int myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT; module_param(myri10ge_rss_hash, int, S_IRUGO); MODULE_PARM_DESC(myri10ge_rss_hash, "Type of RSS hashing to do"); static int myri10ge_dca = 1; module_param(myri10ge_dca, int, S_IRUGO); MODULE_PARM_DESC(myri10ge_dca, "Enable DCA if possible"); #define MYRI10GE_FW_OFFSET 1024*1024 #define MYRI10GE_HIGHPART_TO_U32(X) \ (sizeof (X) == 8) ? ((u32)((u64)(X) >> 32)) : (0) Loading Loading @@ -878,6 +891,9 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) struct myri10ge_slice_state *ss; int i, status; size_t bytes; #ifdef CONFIG_DCA unsigned long dca_tag_off; #endif /* try to send a reset command to the card to see if it * is alive */ Loading Loading @@ -970,6 +986,20 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) } put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); #ifdef CONFIG_DCA status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_DCA_OFFSET, &cmd, 0); dca_tag_off = cmd.data0; for (i = 0; i < mgp->num_slices; i++) { ss = &mgp->ss[i]; if (status == 0) { ss->dca_tag = (__iomem __be32 *) (mgp->sram + dca_tag_off + 4 * i); } else { ss->dca_tag = NULL; } } #endif /* CONFIG_DCA */ /* reset mcp/driver shared state back to 0 */ mgp->link_changes = 0; Loading @@ -995,6 +1025,77 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) return status; } #ifdef CONFIG_DCA static void myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag) { ss->cpu = cpu; ss->cached_dca_tag = tag; put_be32(htonl(tag), ss->dca_tag); } static inline void myri10ge_update_dca(struct myri10ge_slice_state *ss) { int cpu = get_cpu(); int tag; if (cpu != ss->cpu) { tag = dca_get_tag(cpu); if (ss->cached_dca_tag != tag) myri10ge_write_dca(ss, cpu, tag); } put_cpu(); } static void myri10ge_setup_dca(struct myri10ge_priv *mgp) { int err, i; struct pci_dev *pdev = mgp->pdev; if (mgp->ss[0].dca_tag == NULL || mgp->dca_enabled) return; if (!myri10ge_dca) { dev_err(&pdev->dev, "dca disabled by administrator\n"); return; } err = dca_add_requester(&pdev->dev); if (err) { dev_err(&pdev->dev, "dca_add_requester() failed, err=%d\n", err); return; } mgp->dca_enabled = 1; for (i = 0; i < mgp->num_slices; i++) myri10ge_write_dca(&mgp->ss[i], -1, 0); } static void myri10ge_teardown_dca(struct myri10ge_priv *mgp) { struct pci_dev *pdev = mgp->pdev; int err; if (!mgp->dca_enabled) return; mgp->dca_enabled = 0; err = dca_remove_requester(&pdev->dev); } static int myri10ge_notify_dca_device(struct device *dev, void *data) { struct myri10ge_priv *mgp; unsigned long event; mgp = dev_get_drvdata(dev); event = *(unsigned long *)data; if (event == DCA_PROVIDER_ADD) myri10ge_setup_dca(mgp); else if (event == DCA_PROVIDER_REMOVE) myri10ge_teardown_dca(mgp); return 0; } #endif /* CONFIG_DCA */ static inline void myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst, struct mcp_kreq_ether_recv *src) Loading Loading @@ -1362,6 +1463,11 @@ static int myri10ge_poll(struct napi_struct *napi, int budget) struct net_device *netdev = ss->mgp->dev; int work_done; #ifdef CONFIG_DCA if (ss->mgp->dca_enabled) myri10ge_update_dca(ss); #endif /* process as many rx events as NAPI will allow */ work_done = myri10ge_clean_rx_done(ss, budget); Loading Loading @@ -1586,6 +1692,9 @@ static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = { "tx_boundary", "WC", "irq", "MSI", "MSIX", "read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs", "serial_number", "watchdog_resets", #ifdef CONFIG_DCA "dca_capable", "dca_enabled", #endif "link_changes", "link_up", "dropped_link_overflow", "dropped_link_error_or_filtered", "dropped_pause", "dropped_bad_phy", "dropped_bad_crc32", Loading Loading @@ -1662,6 +1771,10 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, data[i++] = (unsigned int)mgp->read_write_dma; data[i++] = (unsigned int)mgp->serial_number; data[i++] = (unsigned int)mgp->watchdog_resets; #ifdef CONFIG_DCA data[i++] = (unsigned int)(mgp->ss[0].dca_tag != NULL); data[i++] = (unsigned int)(mgp->dca_enabled); #endif data[i++] = (unsigned int)mgp->link_changes; /* firmware stats are useful only in the first slice */ Loading Loading @@ -3687,7 +3800,9 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_err(&pdev->dev, "failed reset\n"); goto abort_with_slices; } #ifdef CONFIG_DCA myri10ge_setup_dca(mgp); #endif pci_set_drvdata(pdev, mgp); if ((myri10ge_initial_mtu + ETH_HLEN) > MYRI10GE_MAX_ETHER_MTU) myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; Loading Loading @@ -3788,6 +3903,9 @@ static void myri10ge_remove(struct pci_dev *pdev) netdev = mgp->dev; unregister_netdev(netdev); #ifdef CONFIG_DCA myri10ge_teardown_dca(mgp); #endif myri10ge_dummy_rdma(mgp, 0); /* avoid a memory leak */ Loading Loading @@ -3830,6 +3948,26 @@ static struct pci_driver myri10ge_driver = { #endif }; #ifdef CONFIG_DCA static int myri10ge_notify_dca(struct notifier_block *nb, unsigned long event, void *p) { int err = driver_for_each_device(&myri10ge_driver.driver, NULL, &event, myri10ge_notify_dca_device); if (err) return NOTIFY_BAD; return NOTIFY_DONE; } static struct notifier_block myri10ge_dca_notifier = { .notifier_call = myri10ge_notify_dca, .next = NULL, .priority = 0, }; #endif /* CONFIG_DCA */ static __init int myri10ge_init_module(void) { printk(KERN_INFO "%s: Version %s\n", myri10ge_driver.name, Loading @@ -3842,6 +3980,9 @@ static __init int myri10ge_init_module(void) myri10ge_driver.name, myri10ge_rss_hash); myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT; } #ifdef CONFIG_DCA dca_register_notify(&myri10ge_dca_notifier); #endif return pci_register_driver(&myri10ge_driver); } Loading @@ -3850,6 +3991,9 @@ module_init(myri10ge_init_module); static __exit void myri10ge_cleanup_module(void) { #ifdef CONFIG_DCA dca_unregister_notify(&myri10ge_dca_notifier); #endif pci_unregister_driver(&myri10ge_driver); } Loading Loading
drivers/net/myri10ge/myri10ge.c +145 −1 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ #include <linux/if_ether.h> #include <linux/if_vlan.h> #include <linux/inet_lro.h> #include <linux/dca.h> #include <linux/ip.h> #include <linux/inet.h> #include <linux/in.h> Loading Loading @@ -185,6 +186,11 @@ struct myri10ge_slice_state { dma_addr_t fw_stats_bus; int watchdog_tx_done; int watchdog_tx_req; #ifdef CONFIG_DCA int cached_dca_tag; int cpu; __be32 __iomem *dca_tag; #endif char irq_desc[32]; }; Loading Loading @@ -212,6 +218,9 @@ struct myri10ge_priv { int msi_enabled; int msix_enabled; struct msix_entry *msix_vectors; #ifdef CONFIG_DCA int dca_enabled; #endif u32 link_state; unsigned int rdma_tags_available; int intr_coal_delay; Loading Loading @@ -335,6 +344,10 @@ static int myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT; module_param(myri10ge_rss_hash, int, S_IRUGO); MODULE_PARM_DESC(myri10ge_rss_hash, "Type of RSS hashing to do"); static int myri10ge_dca = 1; module_param(myri10ge_dca, int, S_IRUGO); MODULE_PARM_DESC(myri10ge_dca, "Enable DCA if possible"); #define MYRI10GE_FW_OFFSET 1024*1024 #define MYRI10GE_HIGHPART_TO_U32(X) \ (sizeof (X) == 8) ? ((u32)((u64)(X) >> 32)) : (0) Loading Loading @@ -878,6 +891,9 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) struct myri10ge_slice_state *ss; int i, status; size_t bytes; #ifdef CONFIG_DCA unsigned long dca_tag_off; #endif /* try to send a reset command to the card to see if it * is alive */ Loading Loading @@ -970,6 +986,20 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) } put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); #ifdef CONFIG_DCA status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_DCA_OFFSET, &cmd, 0); dca_tag_off = cmd.data0; for (i = 0; i < mgp->num_slices; i++) { ss = &mgp->ss[i]; if (status == 0) { ss->dca_tag = (__iomem __be32 *) (mgp->sram + dca_tag_off + 4 * i); } else { ss->dca_tag = NULL; } } #endif /* CONFIG_DCA */ /* reset mcp/driver shared state back to 0 */ mgp->link_changes = 0; Loading @@ -995,6 +1025,77 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) return status; } #ifdef CONFIG_DCA static void myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag) { ss->cpu = cpu; ss->cached_dca_tag = tag; put_be32(htonl(tag), ss->dca_tag); } static inline void myri10ge_update_dca(struct myri10ge_slice_state *ss) { int cpu = get_cpu(); int tag; if (cpu != ss->cpu) { tag = dca_get_tag(cpu); if (ss->cached_dca_tag != tag) myri10ge_write_dca(ss, cpu, tag); } put_cpu(); } static void myri10ge_setup_dca(struct myri10ge_priv *mgp) { int err, i; struct pci_dev *pdev = mgp->pdev; if (mgp->ss[0].dca_tag == NULL || mgp->dca_enabled) return; if (!myri10ge_dca) { dev_err(&pdev->dev, "dca disabled by administrator\n"); return; } err = dca_add_requester(&pdev->dev); if (err) { dev_err(&pdev->dev, "dca_add_requester() failed, err=%d\n", err); return; } mgp->dca_enabled = 1; for (i = 0; i < mgp->num_slices; i++) myri10ge_write_dca(&mgp->ss[i], -1, 0); } static void myri10ge_teardown_dca(struct myri10ge_priv *mgp) { struct pci_dev *pdev = mgp->pdev; int err; if (!mgp->dca_enabled) return; mgp->dca_enabled = 0; err = dca_remove_requester(&pdev->dev); } static int myri10ge_notify_dca_device(struct device *dev, void *data) { struct myri10ge_priv *mgp; unsigned long event; mgp = dev_get_drvdata(dev); event = *(unsigned long *)data; if (event == DCA_PROVIDER_ADD) myri10ge_setup_dca(mgp); else if (event == DCA_PROVIDER_REMOVE) myri10ge_teardown_dca(mgp); return 0; } #endif /* CONFIG_DCA */ static inline void myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst, struct mcp_kreq_ether_recv *src) Loading Loading @@ -1362,6 +1463,11 @@ static int myri10ge_poll(struct napi_struct *napi, int budget) struct net_device *netdev = ss->mgp->dev; int work_done; #ifdef CONFIG_DCA if (ss->mgp->dca_enabled) myri10ge_update_dca(ss); #endif /* process as many rx events as NAPI will allow */ work_done = myri10ge_clean_rx_done(ss, budget); Loading Loading @@ -1586,6 +1692,9 @@ static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = { "tx_boundary", "WC", "irq", "MSI", "MSIX", "read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs", "serial_number", "watchdog_resets", #ifdef CONFIG_DCA "dca_capable", "dca_enabled", #endif "link_changes", "link_up", "dropped_link_overflow", "dropped_link_error_or_filtered", "dropped_pause", "dropped_bad_phy", "dropped_bad_crc32", Loading Loading @@ -1662,6 +1771,10 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, data[i++] = (unsigned int)mgp->read_write_dma; data[i++] = (unsigned int)mgp->serial_number; data[i++] = (unsigned int)mgp->watchdog_resets; #ifdef CONFIG_DCA data[i++] = (unsigned int)(mgp->ss[0].dca_tag != NULL); data[i++] = (unsigned int)(mgp->dca_enabled); #endif data[i++] = (unsigned int)mgp->link_changes; /* firmware stats are useful only in the first slice */ Loading Loading @@ -3687,7 +3800,9 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_err(&pdev->dev, "failed reset\n"); goto abort_with_slices; } #ifdef CONFIG_DCA myri10ge_setup_dca(mgp); #endif pci_set_drvdata(pdev, mgp); if ((myri10ge_initial_mtu + ETH_HLEN) > MYRI10GE_MAX_ETHER_MTU) myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; Loading Loading @@ -3788,6 +3903,9 @@ static void myri10ge_remove(struct pci_dev *pdev) netdev = mgp->dev; unregister_netdev(netdev); #ifdef CONFIG_DCA myri10ge_teardown_dca(mgp); #endif myri10ge_dummy_rdma(mgp, 0); /* avoid a memory leak */ Loading Loading @@ -3830,6 +3948,26 @@ static struct pci_driver myri10ge_driver = { #endif }; #ifdef CONFIG_DCA static int myri10ge_notify_dca(struct notifier_block *nb, unsigned long event, void *p) { int err = driver_for_each_device(&myri10ge_driver.driver, NULL, &event, myri10ge_notify_dca_device); if (err) return NOTIFY_BAD; return NOTIFY_DONE; } static struct notifier_block myri10ge_dca_notifier = { .notifier_call = myri10ge_notify_dca, .next = NULL, .priority = 0, }; #endif /* CONFIG_DCA */ static __init int myri10ge_init_module(void) { printk(KERN_INFO "%s: Version %s\n", myri10ge_driver.name, Loading @@ -3842,6 +3980,9 @@ static __init int myri10ge_init_module(void) myri10ge_driver.name, myri10ge_rss_hash); myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT; } #ifdef CONFIG_DCA dca_register_notify(&myri10ge_dca_notifier); #endif return pci_register_driver(&myri10ge_driver); } Loading @@ -3850,6 +3991,9 @@ module_init(myri10ge_init_module); static __exit void myri10ge_cleanup_module(void) { #ifdef CONFIG_DCA dca_unregister_notify(&myri10ge_dca_notifier); #endif pci_unregister_driver(&myri10ge_driver); } Loading