From 7a0c6e8452f7d7b2169af06b8525b9c411b899a9 Mon Sep 17 00:00:00 2001 From: Andrew Gallatin Date: Tue, 28 Sep 2010 08:13:12 +0000 Subject: [PATCH] --- yaml --- r: 214811 b: refs/heads/master c: ef09aadf7bf1a17f4d4938855238c0fd8749a99f h: refs/heads/master i: 214809: 8e90e4ca4d4a9f4e25643d5a6a85bbcd0a8227ca 214807: fb7f6334ff28847f20743dd7da52e3d9c2d4e2bf v: v3 --- [refs] | 2 +- trunk/drivers/net/myri10ge/myri10ge.c | 34 +++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index 1250a9395d1a..5dc7427c279d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8681dc3abd54e845a2effab441921b4c4457c241 +refs/heads/master: ef09aadf7bf1a17f4d4938855238c0fd8749a99f diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index 3ad1a21ca8ce..8524cc40ec57 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -225,6 +225,7 @@ struct myri10ge_priv { struct msix_entry *msix_vectors; #ifdef CONFIG_MYRI10GE_DCA int dca_enabled; + int relaxed_order; #endif u32 link_state; unsigned int rdma_tags_available; @@ -1074,10 +1075,28 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) } #ifdef CONFIG_MYRI10GE_DCA +static int myri10ge_toggle_relaxed(struct pci_dev *pdev, int on) +{ + int ret, cap, err; + u16 ctl; + + cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); + if (!cap) + return 0; + + err = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); + ret = (ctl & PCI_EXP_DEVCTL_RELAX_EN) >> 4; + if (ret != on) { + ctl &= ~PCI_EXP_DEVCTL_RELAX_EN; + ctl |= (on << 4); + pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl); + } + return ret; +} + 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); } @@ -1088,9 +1107,10 @@ static inline void myri10ge_update_dca(struct myri10ge_slice_state *ss) int tag; if (cpu != ss->cpu) { - tag = dca_get_tag(cpu); + tag = dca3_get_tag(&ss->mgp->pdev->dev, cpu); if (ss->cached_dca_tag != tag) myri10ge_write_dca(ss, cpu, tag); + ss->cpu = cpu; } put_cpu(); } @@ -1113,9 +1133,13 @@ static void myri10ge_setup_dca(struct myri10ge_priv *mgp) "dca_add_requester() failed, err=%d\n", err); return; } + mgp->relaxed_order = myri10ge_toggle_relaxed(pdev, 0); mgp->dca_enabled = 1; - for (i = 0; i < mgp->num_slices; i++) - myri10ge_write_dca(&mgp->ss[i], -1, 0); + for (i = 0; i < mgp->num_slices; i++) { + mgp->ss[i].cpu = -1; + mgp->ss[i].cached_dca_tag = -1; + myri10ge_update_dca(&mgp->ss[i]); + } } static void myri10ge_teardown_dca(struct myri10ge_priv *mgp) @@ -1126,6 +1150,8 @@ static void myri10ge_teardown_dca(struct myri10ge_priv *mgp) if (!mgp->dca_enabled) return; mgp->dca_enabled = 0; + if (mgp->relaxed_order) + myri10ge_toggle_relaxed(pdev, 1); err = dca_remove_requester(&pdev->dev); }