]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.drivers/e1000e-Fixes-possible-phy-corrupton-on-82571-design.patch
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / e1000e-Fixes-possible-phy-corrupton-on-82571-design.patch
1 From 23a2d1b233f535fc74f8dca66e488980b4db041b Mon Sep 17 00:00:00 2001
2 From: Dave Graham <david.graham@intel.com>
3 Date: Mon, 8 Jun 2009 14:28:17 +0000
4 Subject: [PATCH] e1000e: Fixes possible phy corrupton on 82571 designs.
5 References: bnc#495259
6
7 Phy corruption has been observed on 2-port 82571 adapters, and is root-caused
8 to lack of synchronization between the 2 driver instances, which conflict
9 when attempting to access the phy via the single MDIC register.
10 A semaphore exists for this purpose, and is now used on these designs. Because
11 PXE &/or EFI boot code (which we cannot expect to be built with this fix) may
12 leave the inter-instance semaphore in an invalid initial state when the driver
13 first loads, this fix also includes a one-time (per driver load) fix-up of the
14 semaphore initial state.
15
16 Signed-off-by: dave graham <david.graham@intel.com>
17 Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
18 Signed-off-by: David S. Miller <davem@davemloft.net>
19 Acked-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
26 Index: 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
162 Index: 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 */
175 Index: 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 {