aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/myri10ge/myri10ge.c
diff options
context:
space:
mode:
authorAndrew Gallatin <gallatin@myri.com>2010-09-28 04:13:12 -0400
committerDavid S. Miller <davem@davemloft.net>2010-09-29 22:45:37 -0400
commitef09aadf7bf1a17f4d4938855238c0fd8749a99f (patch)
treeeb30777402c9f8f36e0751d1a6854bdc7abe02c1 /drivers/net/myri10ge/myri10ge.c
parent8681dc3abd54e845a2effab441921b4c4457c241 (diff)
myri10ge: DCA update (resubmit)
This patch contains the following DCA improvements to myri10ge: 1) Finally move myri10ge to use dca3 API 2) Disable PCIe relaxed ordering when enabling DCA on myri10ge. This provides a performance boost on Nehalem based Xeons 3) Make sure to properly initialize NIC's DCA state when it is enabled, rather than giving the NIC a bogus tag (0) and waiting for the first received packet to trigger an update. Not using a real tag can cause hardware exceptions on some motherboards when a CPU socket is empty. 3) Always update the cached CPU when our interrupt affinity changes so as to avoid excessive calls to dca3_get_tag() Signed-off-by: Andrew Gallatin <gallatin@myri.com> Signed-off-by: Loic Prylli <loic@myri.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/myri10ge/myri10ge.c')
-rw-r--r--drivers/net/myri10ge/myri10ge.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 3ad1a21ca8ce..8524cc40ec57 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -225,6 +225,7 @@ struct myri10ge_priv {
225 struct msix_entry *msix_vectors; 225 struct msix_entry *msix_vectors;
226#ifdef CONFIG_MYRI10GE_DCA 226#ifdef CONFIG_MYRI10GE_DCA
227 int dca_enabled; 227 int dca_enabled;
228 int relaxed_order;
228#endif 229#endif
229 u32 link_state; 230 u32 link_state;
230 unsigned int rdma_tags_available; 231 unsigned int rdma_tags_available;
@@ -1074,10 +1075,28 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
1074} 1075}
1075 1076
1076#ifdef CONFIG_MYRI10GE_DCA 1077#ifdef CONFIG_MYRI10GE_DCA
1078static int myri10ge_toggle_relaxed(struct pci_dev *pdev, int on)
1079{
1080 int ret, cap, err;
1081 u16 ctl;
1082
1083 cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
1084 if (!cap)
1085 return 0;
1086
1087 err = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
1088 ret = (ctl & PCI_EXP_DEVCTL_RELAX_EN) >> 4;
1089 if (ret != on) {
1090 ctl &= ~PCI_EXP_DEVCTL_RELAX_EN;
1091 ctl |= (on << 4);
1092 pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
1093 }
1094 return ret;
1095}
1096
1077static void 1097static void
1078myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag) 1098myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag)
1079{ 1099{
1080 ss->cpu = cpu;
1081 ss->cached_dca_tag = tag; 1100 ss->cached_dca_tag = tag;
1082 put_be32(htonl(tag), ss->dca_tag); 1101 put_be32(htonl(tag), ss->dca_tag);
1083} 1102}
@@ -1088,9 +1107,10 @@ static inline void myri10ge_update_dca(struct myri10ge_slice_state *ss)
1088 int tag; 1107 int tag;
1089 1108
1090 if (cpu != ss->cpu) { 1109 if (cpu != ss->cpu) {
1091 tag = dca_get_tag(cpu); 1110 tag = dca3_get_tag(&ss->mgp->pdev->dev, cpu);
1092 if (ss->cached_dca_tag != tag) 1111 if (ss->cached_dca_tag != tag)
1093 myri10ge_write_dca(ss, cpu, tag); 1112 myri10ge_write_dca(ss, cpu, tag);
1113 ss->cpu = cpu;
1094 } 1114 }
1095 put_cpu(); 1115 put_cpu();
1096} 1116}
@@ -1113,9 +1133,13 @@ static void myri10ge_setup_dca(struct myri10ge_priv *mgp)
1113 "dca_add_requester() failed, err=%d\n", err); 1133 "dca_add_requester() failed, err=%d\n", err);
1114 return; 1134 return;
1115 } 1135 }
1136 mgp->relaxed_order = myri10ge_toggle_relaxed(pdev, 0);
1116 mgp->dca_enabled = 1; 1137 mgp->dca_enabled = 1;
1117 for (i = 0; i < mgp->num_slices; i++) 1138 for (i = 0; i < mgp->num_slices; i++) {
1118 myri10ge_write_dca(&mgp->ss[i], -1, 0); 1139 mgp->ss[i].cpu = -1;
1140 mgp->ss[i].cached_dca_tag = -1;
1141 myri10ge_update_dca(&mgp->ss[i]);
1142 }
1119} 1143}
1120 1144
1121static void myri10ge_teardown_dca(struct myri10ge_priv *mgp) 1145static void myri10ge_teardown_dca(struct myri10ge_priv *mgp)
@@ -1126,6 +1150,8 @@ static void myri10ge_teardown_dca(struct myri10ge_priv *mgp)
1126 if (!mgp->dca_enabled) 1150 if (!mgp->dca_enabled)
1127 return; 1151 return;
1128 mgp->dca_enabled = 0; 1152 mgp->dca_enabled = 0;
1153 if (mgp->relaxed_order)
1154 myri10ge_toggle_relaxed(pdev, 1);
1129 err = dca_remove_requester(&pdev->dev); 1155 err = dca_remove_requester(&pdev->dev);
1130} 1156}
1131 1157