aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBrice Goglin <brice@myri.com>2008-05-08 20:22:16 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-05-30 22:11:47 -0400
commit981813d8e0a16946f511f4eda17bb4ee4fa2769c (patch)
tree177ad13be780a25ee8cc5052b2aa266243d12fe6 /drivers
parent0dcffac1a329be69bab0ac604bf7283737108e68 (diff)
myri10ge: add Direct Cache Access support
Add I/O AT DCA (Direct Cache Access) support. Signed-off-by: Brice Goglin <brice@myri.com> Signed-off-by: Andrew Gallatin <gallatin@myri.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/myri10ge/myri10ge.c146
1 files changed, 145 insertions, 1 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index eddcee326f06..93007d38df57 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -49,6 +49,7 @@
49#include <linux/if_ether.h> 49#include <linux/if_ether.h>
50#include <linux/if_vlan.h> 50#include <linux/if_vlan.h>
51#include <linux/inet_lro.h> 51#include <linux/inet_lro.h>
52#include <linux/dca.h>
52#include <linux/ip.h> 53#include <linux/ip.h>
53#include <linux/inet.h> 54#include <linux/inet.h>
54#include <linux/in.h> 55#include <linux/in.h>
@@ -185,6 +186,11 @@ struct myri10ge_slice_state {
185 dma_addr_t fw_stats_bus; 186 dma_addr_t fw_stats_bus;
186 int watchdog_tx_done; 187 int watchdog_tx_done;
187 int watchdog_tx_req; 188 int watchdog_tx_req;
189#ifdef CONFIG_DCA
190 int cached_dca_tag;
191 int cpu;
192 __be32 __iomem *dca_tag;
193#endif
188 char irq_desc[32]; 194 char irq_desc[32];
189}; 195};
190 196
@@ -212,6 +218,9 @@ struct myri10ge_priv {
212 int msi_enabled; 218 int msi_enabled;
213 int msix_enabled; 219 int msix_enabled;
214 struct msix_entry *msix_vectors; 220 struct msix_entry *msix_vectors;
221#ifdef CONFIG_DCA
222 int dca_enabled;
223#endif
215 u32 link_state; 224 u32 link_state;
216 unsigned int rdma_tags_available; 225 unsigned int rdma_tags_available;
217 int intr_coal_delay; 226 int intr_coal_delay;
@@ -335,6 +344,10 @@ static int myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
335module_param(myri10ge_rss_hash, int, S_IRUGO); 344module_param(myri10ge_rss_hash, int, S_IRUGO);
336MODULE_PARM_DESC(myri10ge_rss_hash, "Type of RSS hashing to do"); 345MODULE_PARM_DESC(myri10ge_rss_hash, "Type of RSS hashing to do");
337 346
347static int myri10ge_dca = 1;
348module_param(myri10ge_dca, int, S_IRUGO);
349MODULE_PARM_DESC(myri10ge_dca, "Enable DCA if possible");
350
338#define MYRI10GE_FW_OFFSET 1024*1024 351#define MYRI10GE_FW_OFFSET 1024*1024
339#define MYRI10GE_HIGHPART_TO_U32(X) \ 352#define MYRI10GE_HIGHPART_TO_U32(X) \
340(sizeof (X) == 8) ? ((u32)((u64)(X) >> 32)) : (0) 353(sizeof (X) == 8) ? ((u32)((u64)(X) >> 32)) : (0)
@@ -878,6 +891,9 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
878 struct myri10ge_slice_state *ss; 891 struct myri10ge_slice_state *ss;
879 int i, status; 892 int i, status;
880 size_t bytes; 893 size_t bytes;
894#ifdef CONFIG_DCA
895 unsigned long dca_tag_off;
896#endif
881 897
882 /* try to send a reset command to the card to see if it 898 /* try to send a reset command to the card to see if it
883 * is alive */ 899 * is alive */
@@ -970,6 +986,20 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
970 } 986 }
971 put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); 987 put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
972 988
989#ifdef CONFIG_DCA
990 status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_DCA_OFFSET, &cmd, 0);
991 dca_tag_off = cmd.data0;
992 for (i = 0; i < mgp->num_slices; i++) {
993 ss = &mgp->ss[i];
994 if (status == 0) {
995 ss->dca_tag = (__iomem __be32 *)
996 (mgp->sram + dca_tag_off + 4 * i);
997 } else {
998 ss->dca_tag = NULL;
999 }
1000 }
1001#endif /* CONFIG_DCA */
1002
973 /* reset mcp/driver shared state back to 0 */ 1003 /* reset mcp/driver shared state back to 0 */
974 1004
975 mgp->link_changes = 0; 1005 mgp->link_changes = 0;
@@ -995,6 +1025,77 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
995 return status; 1025 return status;
996} 1026}
997 1027
1028#ifdef CONFIG_DCA
1029static void
1030myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag)
1031{
1032 ss->cpu = cpu;
1033 ss->cached_dca_tag = tag;
1034 put_be32(htonl(tag), ss->dca_tag);
1035}
1036
1037static inline void myri10ge_update_dca(struct myri10ge_slice_state *ss)
1038{
1039 int cpu = get_cpu();
1040 int tag;
1041
1042 if (cpu != ss->cpu) {
1043 tag = dca_get_tag(cpu);
1044 if (ss->cached_dca_tag != tag)
1045 myri10ge_write_dca(ss, cpu, tag);
1046 }
1047 put_cpu();
1048}
1049
1050static void myri10ge_setup_dca(struct myri10ge_priv *mgp)
1051{
1052 int err, i;
1053 struct pci_dev *pdev = mgp->pdev;
1054
1055 if (mgp->ss[0].dca_tag == NULL || mgp->dca_enabled)
1056 return;
1057 if (!myri10ge_dca) {
1058 dev_err(&pdev->dev, "dca disabled by administrator\n");
1059 return;
1060 }
1061 err = dca_add_requester(&pdev->dev);
1062 if (err) {
1063 dev_err(&pdev->dev,
1064 "dca_add_requester() failed, err=%d\n", err);
1065 return;
1066 }
1067 mgp->dca_enabled = 1;
1068 for (i = 0; i < mgp->num_slices; i++)
1069 myri10ge_write_dca(&mgp->ss[i], -1, 0);
1070}
1071
1072static void myri10ge_teardown_dca(struct myri10ge_priv *mgp)
1073{
1074 struct pci_dev *pdev = mgp->pdev;
1075 int err;
1076
1077 if (!mgp->dca_enabled)
1078 return;
1079 mgp->dca_enabled = 0;
1080 err = dca_remove_requester(&pdev->dev);
1081}
1082
1083static int myri10ge_notify_dca_device(struct device *dev, void *data)
1084{
1085 struct myri10ge_priv *mgp;
1086 unsigned long event;
1087
1088 mgp = dev_get_drvdata(dev);
1089 event = *(unsigned long *)data;
1090
1091 if (event == DCA_PROVIDER_ADD)
1092 myri10ge_setup_dca(mgp);
1093 else if (event == DCA_PROVIDER_REMOVE)
1094 myri10ge_teardown_dca(mgp);
1095 return 0;
1096}
1097#endif /* CONFIG_DCA */
1098
998static inline void 1099static inline void
999myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst, 1100myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst,
1000 struct mcp_kreq_ether_recv *src) 1101 struct mcp_kreq_ether_recv *src)
@@ -1362,6 +1463,11 @@ static int myri10ge_poll(struct napi_struct *napi, int budget)
1362 struct net_device *netdev = ss->mgp->dev; 1463 struct net_device *netdev = ss->mgp->dev;
1363 int work_done; 1464 int work_done;
1364 1465
1466#ifdef CONFIG_DCA
1467 if (ss->mgp->dca_enabled)
1468 myri10ge_update_dca(ss);
1469#endif
1470
1365 /* process as many rx events as NAPI will allow */ 1471 /* process as many rx events as NAPI will allow */
1366 work_done = myri10ge_clean_rx_done(ss, budget); 1472 work_done = myri10ge_clean_rx_done(ss, budget);
1367 1473
@@ -1586,6 +1692,9 @@ static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = {
1586 "tx_boundary", "WC", "irq", "MSI", "MSIX", 1692 "tx_boundary", "WC", "irq", "MSI", "MSIX",
1587 "read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs", 1693 "read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs",
1588 "serial_number", "watchdog_resets", 1694 "serial_number", "watchdog_resets",
1695#ifdef CONFIG_DCA
1696 "dca_capable", "dca_enabled",
1697#endif
1589 "link_changes", "link_up", "dropped_link_overflow", 1698 "link_changes", "link_up", "dropped_link_overflow",
1590 "dropped_link_error_or_filtered", 1699 "dropped_link_error_or_filtered",
1591 "dropped_pause", "dropped_bad_phy", "dropped_bad_crc32", 1700 "dropped_pause", "dropped_bad_phy", "dropped_bad_crc32",
@@ -1662,6 +1771,10 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
1662 data[i++] = (unsigned int)mgp->read_write_dma; 1771 data[i++] = (unsigned int)mgp->read_write_dma;
1663 data[i++] = (unsigned int)mgp->serial_number; 1772 data[i++] = (unsigned int)mgp->serial_number;
1664 data[i++] = (unsigned int)mgp->watchdog_resets; 1773 data[i++] = (unsigned int)mgp->watchdog_resets;
1774#ifdef CONFIG_DCA
1775 data[i++] = (unsigned int)(mgp->ss[0].dca_tag != NULL);
1776 data[i++] = (unsigned int)(mgp->dca_enabled);
1777#endif
1665 data[i++] = (unsigned int)mgp->link_changes; 1778 data[i++] = (unsigned int)mgp->link_changes;
1666 1779
1667 /* firmware stats are useful only in the first slice */ 1780 /* firmware stats are useful only in the first slice */
@@ -3687,7 +3800,9 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3687 dev_err(&pdev->dev, "failed reset\n"); 3800 dev_err(&pdev->dev, "failed reset\n");
3688 goto abort_with_slices; 3801 goto abort_with_slices;
3689 } 3802 }
3690 3803#ifdef CONFIG_DCA
3804 myri10ge_setup_dca(mgp);
3805#endif
3691 pci_set_drvdata(pdev, mgp); 3806 pci_set_drvdata(pdev, mgp);
3692 if ((myri10ge_initial_mtu + ETH_HLEN) > MYRI10GE_MAX_ETHER_MTU) 3807 if ((myri10ge_initial_mtu + ETH_HLEN) > MYRI10GE_MAX_ETHER_MTU)
3693 myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; 3808 myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN;
@@ -3788,6 +3903,9 @@ static void myri10ge_remove(struct pci_dev *pdev)
3788 netdev = mgp->dev; 3903 netdev = mgp->dev;
3789 unregister_netdev(netdev); 3904 unregister_netdev(netdev);
3790 3905
3906#ifdef CONFIG_DCA
3907 myri10ge_teardown_dca(mgp);
3908#endif
3791 myri10ge_dummy_rdma(mgp, 0); 3909 myri10ge_dummy_rdma(mgp, 0);
3792 3910
3793 /* avoid a memory leak */ 3911 /* avoid a memory leak */
@@ -3830,6 +3948,26 @@ static struct pci_driver myri10ge_driver = {
3830#endif 3948#endif
3831}; 3949};
3832 3950
3951#ifdef CONFIG_DCA
3952static int
3953myri10ge_notify_dca(struct notifier_block *nb, unsigned long event, void *p)
3954{
3955 int err = driver_for_each_device(&myri10ge_driver.driver,
3956 NULL, &event,
3957 myri10ge_notify_dca_device);
3958
3959 if (err)
3960 return NOTIFY_BAD;
3961 return NOTIFY_DONE;
3962}
3963
3964static struct notifier_block myri10ge_dca_notifier = {
3965 .notifier_call = myri10ge_notify_dca,
3966 .next = NULL,
3967 .priority = 0,
3968};
3969#endif /* CONFIG_DCA */
3970
3833static __init int myri10ge_init_module(void) 3971static __init int myri10ge_init_module(void)
3834{ 3972{
3835 printk(KERN_INFO "%s: Version %s\n", myri10ge_driver.name, 3973 printk(KERN_INFO "%s: Version %s\n", myri10ge_driver.name,
@@ -3842,6 +3980,9 @@ static __init int myri10ge_init_module(void)
3842 myri10ge_driver.name, myri10ge_rss_hash); 3980 myri10ge_driver.name, myri10ge_rss_hash);
3843 myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT; 3981 myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
3844 } 3982 }
3983#ifdef CONFIG_DCA
3984 dca_register_notify(&myri10ge_dca_notifier);
3985#endif
3845 3986
3846 return pci_register_driver(&myri10ge_driver); 3987 return pci_register_driver(&myri10ge_driver);
3847} 3988}
@@ -3850,6 +3991,9 @@ module_init(myri10ge_init_module);
3850 3991
3851static __exit void myri10ge_cleanup_module(void) 3992static __exit void myri10ge_cleanup_module(void)
3852{ 3993{
3994#ifdef CONFIG_DCA
3995 dca_unregister_notify(&myri10ge_dca_notifier);
3996#endif
3853 pci_unregister_driver(&myri10ge_driver); 3997 pci_unregister_driver(&myri10ge_driver);
3854} 3998}
3855 3999