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.
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.
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>
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(-)
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);
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;
44 + bool force_clear_smbi = false;
47 switch (adapter->pdev->device) {
48 @@ -269,6 +273,50 @@ static s32 e1000_init_mac_params_82571(s
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.
59 + switch (hw->mac.type) {
62 + swsm2 = er32(SWSM2);
64 + if (!(swsm2 & E1000_SWSM2_LOCK)) {
65 + /* Only do this for the first interface on this card */
67 + swsm2 | E1000_SWSM2_LOCK);
68 + force_clear_smbi = true;
70 + force_clear_smbi = false;
73 + force_clear_smbi = true;
77 + if (force_clear_smbi) {
78 + /* Make sure SWSM.SMBI is clear */
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
85 + hw_dbg(hw, "Please update your 82571 Bootagent\n");
87 + ew32(SWSM, swsm & ~E1000_SWSM_SMBI);
91 + * Initialze device specific counter of SMBI acquisition
94 + hw->dev_spec.e82571.smb_counter = 0;
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)
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;
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
116 + if (hw->dev_spec.e82571.smb_counter > 2)
119 + /* Get the SW semaphore */
120 + while (i < sw_timeout) {
122 + if (!(swsm & E1000_SWSM_SMBI))
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++;
133 /* Get the FW semaphore. */
134 - for (i = 0; i < timeout; i++) {
135 + for (i = 0; i < fw_timeout; i++) {
137 ew32(SWSM, swsm | E1000_SWSM_SWESMBI);
139 @@ -417,9 +491,9 @@ static s32 e1000_get_hw_semaphore_82571(
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;
151 @@ -438,9 +512,7 @@ static void e1000_put_hw_semaphore_82571
156 - swsm &= ~E1000_SWSM_SWESMBI;
158 + swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
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
167 #define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
168 #define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
170 +#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */
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 */
187 @@ -856,6 +857,7 @@ struct e1000_fc_info {
188 struct e1000_dev_spec_82571 {
190 bool alt_mac_addr_is_present;
194 struct e1000_shadow_ram {