aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel
diff options
context:
space:
mode:
authorMatthew Vick <matthew.vick@intel.com>2013-03-22 03:34:20 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2013-04-24 21:05:19 -0400
commitd44e7a9a1f1e56918f8e937dcf750626ac5ad9b4 (patch)
tree889ddc1e236a4e3af2eabdefdfa824e2eccae27f /drivers/net/ethernet/intel
parent0ba96d3d91882ae27083d8de8634ce0fae20dee6 (diff)
igb: Add SMBI semaphore to I210/I211
It was previously thought that, since I210/I211 are single port devices, they did not need the SMBI semaphore. This is not the case. Add support for the SMBI semaphore. Signed-off-by: Matthew Vick <matthew.vick@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_82575.c3
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_hw.h1
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.c65
3 files changed, 43 insertions, 26 deletions
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index c9bba39d50bd..6cb0ca2869b9 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -389,6 +389,9 @@ static s32 igb_init_mac_params_82575(struct e1000_hw *hw)
389 dev_spec->eee_disable = false; 389 dev_spec->eee_disable = false;
390 else 390 else
391 dev_spec->eee_disable = true; 391 dev_spec->eee_disable = true;
392 /* Allow a single clear of the SW semaphore on I210 and newer */
393 if (mac->type >= e1000_i210)
394 dev_spec->clear_semaphore_once = true;
392 /* physical interface link setup */ 395 /* physical interface link setup */
393 mac->ops.setup_physical_interface = 396 mac->ops.setup_physical_interface =
394 (hw->phy.media_type == e1000_media_type_copper) 397 (hw->phy.media_type == e1000_media_type_copper)
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h
index 1138ccaf95ff..f1dbab920286 100644
--- a/drivers/net/ethernet/intel/igb/e1000_hw.h
+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h
@@ -529,6 +529,7 @@ struct e1000_dev_spec_82575 {
529 bool sgmii_active; 529 bool sgmii_active;
530 bool global_device_reset; 530 bool global_device_reset;
531 bool eee_disable; 531 bool eee_disable;
532 bool clear_semaphore_once;
532}; 533};
533 534
534struct e1000_hw { 535struct e1000_hw {
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c
index 9764cd3610e5..ddb3cf51b9b9 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.c
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.c
@@ -44,10 +44,42 @@
44static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw) 44static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw)
45{ 45{
46 u32 swsm; 46 u32 swsm;
47 s32 ret_val = E1000_SUCCESS;
48 s32 timeout = hw->nvm.word_size + 1; 47 s32 timeout = hw->nvm.word_size + 1;
49 s32 i = 0; 48 s32 i = 0;
50 49
50 /* Get the SW semaphore */
51 while (i < timeout) {
52 swsm = rd32(E1000_SWSM);
53 if (!(swsm & E1000_SWSM_SMBI))
54 break;
55
56 udelay(50);
57 i++;
58 }
59
60 if (i == timeout) {
61 /* In rare circumstances, the SW semaphore may already be held
62 * unintentionally. Clear the semaphore once before giving up.
63 */
64 if (hw->dev_spec._82575.clear_semaphore_once) {
65 hw->dev_spec._82575.clear_semaphore_once = false;
66 igb_put_hw_semaphore(hw);
67 for (i = 0; i < timeout; i++) {
68 swsm = rd32(E1000_SWSM);
69 if (!(swsm & E1000_SWSM_SMBI))
70 break;
71
72 udelay(50);
73 }
74 }
75
76 /* If we do not have the semaphore here, we have to give up. */
77 if (i == timeout) {
78 hw_dbg("Driver can't access device - SMBI bit is set.\n");
79 return -E1000_ERR_NVM;
80 }
81 }
82
51 /* Get the FW semaphore. */ 83 /* Get the FW semaphore. */
52 for (i = 0; i < timeout; i++) { 84 for (i = 0; i < timeout; i++) {
53 swsm = rd32(E1000_SWSM); 85 swsm = rd32(E1000_SWSM);
@@ -64,12 +96,10 @@ static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw)
64 /* Release semaphores */ 96 /* Release semaphores */
65 igb_put_hw_semaphore(hw); 97 igb_put_hw_semaphore(hw);
66 hw_dbg("Driver can't access the NVM\n"); 98 hw_dbg("Driver can't access the NVM\n");
67 ret_val = -E1000_ERR_NVM; 99 return -E1000_ERR_NVM;
68 goto out;
69 } 100 }
70 101
71out: 102 return E1000_SUCCESS;
72 return ret_val;
73} 103}
74 104
75/** 105/**
@@ -99,23 +129,6 @@ void igb_release_nvm_i210(struct e1000_hw *hw)
99} 129}
100 130
101/** 131/**
102 * igb_put_hw_semaphore_i210 - Release hardware semaphore
103 * @hw: pointer to the HW structure
104 *
105 * Release hardware semaphore used to access the PHY or NVM
106 **/
107static void igb_put_hw_semaphore_i210(struct e1000_hw *hw)
108{
109 u32 swsm;
110
111 swsm = rd32(E1000_SWSM);
112
113 swsm &= ~E1000_SWSM_SWESMBI;
114
115 wr32(E1000_SWSM, swsm);
116}
117
118/**
119 * igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore 132 * igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
120 * @hw: pointer to the HW structure 133 * @hw: pointer to the HW structure
121 * @mask: specifies which semaphore to acquire 134 * @mask: specifies which semaphore to acquire
@@ -138,11 +151,11 @@ s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
138 } 151 }
139 152
140 swfw_sync = rd32(E1000_SW_FW_SYNC); 153 swfw_sync = rd32(E1000_SW_FW_SYNC);
141 if (!(swfw_sync & fwmask)) 154 if (!(swfw_sync & (fwmask | swmask)))
142 break; 155 break;
143 156
144 /* Firmware currently using resource (fwmask) */ 157 /* Firmware currently using resource (fwmask) */
145 igb_put_hw_semaphore_i210(hw); 158 igb_put_hw_semaphore(hw);
146 mdelay(5); 159 mdelay(5);
147 i++; 160 i++;
148 } 161 }
@@ -156,7 +169,7 @@ s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
156 swfw_sync |= swmask; 169 swfw_sync |= swmask;
157 wr32(E1000_SW_FW_SYNC, swfw_sync); 170 wr32(E1000_SW_FW_SYNC, swfw_sync);
158 171
159 igb_put_hw_semaphore_i210(hw); 172 igb_put_hw_semaphore(hw);
160out: 173out:
161 return ret_val; 174 return ret_val;
162} 175}
@@ -180,7 +193,7 @@ void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
180 swfw_sync &= ~mask; 193 swfw_sync &= ~mask;
181 wr32(E1000_SW_FW_SYNC, swfw_sync); 194 wr32(E1000_SW_FW_SYNC, swfw_sync);
182 195
183 igb_put_hw_semaphore_i210(hw); 196 igb_put_hw_semaphore(hw);
184} 197}
185 198
186/** 199/**