]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.drivers/e1000e-Fixes-possible-phy-corrupton-on-82571-design.patch
Revert "Move xen patchset to new version's subdir."
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / e1000e-Fixes-possible-phy-corrupton-on-82571-design.patch
CommitLineData
00e5a55c
BS
1From 23a2d1b233f535fc74f8dca66e488980b4db041b Mon Sep 17 00:00:00 2001
2From: Dave Graham <david.graham@intel.com>
3Date: Mon, 8 Jun 2009 14:28:17 +0000
4Subject: [PATCH] e1000e: Fixes possible phy corrupton on 82571 designs.
5References: bnc#495259
6
7Phy corruption has been observed on 2-port 82571 adapters, and is root-caused
8to lack of synchronization between the 2 driver instances, which conflict
9when attempting to access the phy via the single MDIC register.
10A semaphore exists for this purpose, and is now used on these designs. Because
11PXE &/or EFI boot code (which we cannot expect to be built with this fix) may
12leave the inter-instance semaphore in an invalid initial state when the driver
13first loads, this fix also includes a one-time (per driver load) fix-up of the
14semaphore initial state.
15
16Signed-off-by: dave graham <david.graham@intel.com>
17Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
18Signed-off-by: David S. Miller <davem@davemloft.net>
19Acked-by: Brandon Philips <bphilips@suse.de>
20---
21 drivers/net/e1000e/82571.c | 86 +++++++++++++++++++++++++++++++++++++++----
22 drivers/net/e1000e/defines.h | 2 +
23 drivers/net/e1000e/hw.h | 2 +
24 3 files changed, 83 insertions(+), 7 deletions(-)
25
26Index: linux-2.6.27-SLE11_BRANCH/drivers/net/e1000e/82571.c
27===================================================================
28--- linux-2.6.27-SLE11_BRANCH.orig/drivers/net/e1000e/82571.c
29+++ linux-2.6.27-SLE11_BRANCH/drivers/net/e1000e/82571.c
30@@ -68,6 +68,7 @@ static s32 e1000_setup_link_82571(struct
31 static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
32 static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
33 static s32 e1000_led_on_82574(struct e1000_hw *hw);
34+static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
35
36 /**
37 * e1000_init_phy_params_82571 - Init PHY func ptrs.
38@@ -206,6 +207,9 @@ static s32 e1000_init_mac_params_82571(s
39 struct e1000_hw *hw = &adapter->hw;
40 struct e1000_mac_info *mac = &hw->mac;
41 struct e1000_mac_operations *func = &mac->ops;
42+ u32 swsm = 0;
43+ u32 swsm2 = 0;
44+ bool force_clear_smbi = false;
45
46 /* Set media type */
47 switch (adapter->pdev->device) {
48@@ -269,6 +273,50 @@ static s32 e1000_init_mac_params_82571(s
49 break;
50 }
51
52+ /*
53+ * Ensure that the inter-port SWSM.SMBI lock bit is clear before
54+ * first NVM or PHY acess. This should be done for single-port
55+ * devices, and for one port only on dual-port devices so that
56+ * for those devices we can still use the SMBI lock to synchronize
57+ * inter-port accesses to the PHY & NVM.
58+ */
59+ switch (hw->mac.type) {
60+ case e1000_82571:
61+ case e1000_82572:
62+ swsm2 = er32(SWSM2);
63+
64+ if (!(swsm2 & E1000_SWSM2_LOCK)) {
65+ /* Only do this for the first interface on this card */
66+ ew32(SWSM2,
67+ swsm2 | E1000_SWSM2_LOCK);
68+ force_clear_smbi = true;
69+ } else
70+ force_clear_smbi = false;
71+ break;
72+ default:
73+ force_clear_smbi = true;
74+ break;
75+ }
76+
77+ if (force_clear_smbi) {
78+ /* Make sure SWSM.SMBI is clear */
79+ swsm = er32(SWSM);
80+ if (swsm & E1000_SWSM_SMBI) {
81+ /* This bit should not be set on a first interface, and
82+ * indicates that the bootagent or EFI code has
83+ * improperly left this bit enabled
84+ */
85+ hw_dbg(hw, "Please update your 82571 Bootagent\n");
86+ }
87+ ew32(SWSM, swsm & ~E1000_SWSM_SMBI);
88+ }
89+
90+ /*
91+ * Initialze device specific counter of SMBI acquisition
92+ * timeouts.
93+ */
94+ hw->dev_spec.e82571.smb_counter = 0;
95+
96 return 0;
97 }
98
99@@ -402,11 +450,37 @@ static s32 e1000_get_phy_id_82571(struct
100 static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
101 {
102 u32 swsm;
103- s32 timeout = hw->nvm.word_size + 1;
104+ s32 sw_timeout = hw->nvm.word_size + 1;
105+ s32 fw_timeout = hw->nvm.word_size + 1;
106 s32 i = 0;
107
108+ /*
109+ * If we have timedout 3 times on trying to acquire
110+ * the inter-port SMBI semaphore, there is old code
111+ * operating on the other port, and it is not
112+ * releasing SMBI. Modify the number of times that
113+ * we try for the semaphore to interwork with this
114+ * older code.
115+ */
116+ if (hw->dev_spec.e82571.smb_counter > 2)
117+ sw_timeout = 1;
118+
119+ /* Get the SW semaphore */
120+ while (i < sw_timeout) {
121+ swsm = er32(SWSM);
122+ if (!(swsm & E1000_SWSM_SMBI))
123+ break;
124+
125+ udelay(50);
126+ i++;
127+ }
128+
129+ if (i == sw_timeout) {
130+ hw_dbg(hw, "Driver can't access device - SMBI bit is set.\n");
131+ hw->dev_spec.e82571.smb_counter++;
132+ }
133 /* Get the FW semaphore. */
134- for (i = 0; i < timeout; i++) {
135+ for (i = 0; i < fw_timeout; i++) {
136 swsm = er32(SWSM);
137 ew32(SWSM, swsm | E1000_SWSM_SWESMBI);
138
139@@ -417,9 +491,9 @@ static s32 e1000_get_hw_semaphore_82571(
140 udelay(50);
141 }
142
143- if (i == timeout) {
144+ if (i == fw_timeout) {
145 /* Release semaphores */
146- e1000e_put_hw_semaphore(hw);
147+ e1000_put_hw_semaphore_82571(hw);
148 hw_dbg(hw, "Driver can't access the NVM\n");
149 return -E1000_ERR_NVM;
150 }
151@@ -438,9 +512,7 @@ static void e1000_put_hw_semaphore_82571
152 u32 swsm;
153
154 swsm = er32(SWSM);
155-
156- swsm &= ~E1000_SWSM_SWESMBI;
157-
158+ swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
159 ew32(SWSM, swsm);
160 }
161
162Index: linux-2.6.27-SLE11_BRANCH/drivers/net/e1000e/defines.h
163===================================================================
164--- linux-2.6.27-SLE11_BRANCH.orig/drivers/net/e1000e/defines.h
165+++ linux-2.6.27-SLE11_BRANCH/drivers/net/e1000e/defines.h
166@@ -359,6 +359,8 @@
167 #define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
168 #define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
169
170+#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */
171+
172 /* Interrupt Cause Read */
173 #define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
174 #define E1000_ICR_LSC 0x00000004 /* Link Status Change */
175Index: linux-2.6.27-SLE11_BRANCH/drivers/net/e1000e/hw.h
176===================================================================
177--- linux-2.6.27-SLE11_BRANCH.orig/drivers/net/e1000e/hw.h
178+++ linux-2.6.27-SLE11_BRANCH/drivers/net/e1000e/hw.h
179@@ -209,6 +209,7 @@ enum e1e_registers {
180 E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */
181 E1000_SWSM = 0x05B50, /* SW Semaphore */
182 E1000_FWSM = 0x05B54, /* FW Semaphore */
183+ E1000_SWSM2 = 0x05B58, /* Driver-only SW semaphore */
184 E1000_HICR = 0x08F00, /* Host Interface Control */
185 };
186
187@@ -856,6 +857,7 @@ struct e1000_fc_info {
188 struct e1000_dev_spec_82571 {
189 bool laa_is_present;
190 bool alt_mac_addr_is_present;
191+ u32 smb_counter;
192 };
193
194 struct e1000_shadow_ram {