diff options
author | Sasha Neftin <sasha.neftin@intel.com> | 2018-10-11 03:17:31 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2018-10-17 16:55:18 -0400 |
commit | 5586838fe9ced0980e210b39d635ff3842297448 (patch) | |
tree | 1646f8cca19ced662aac1f065426d27344ec5fa9 /drivers/net/ethernet/intel/igc/igc_base.c | |
parent | ab4056126813c889ee6c8fb24ca8f75b84c981ab (diff) |
igc: Add code for PHY support
Add PHY's ID support
Add support for initialization, acquire and release of PHY
Enable register access
Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@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/igc/igc_base.c')
-rw-r--r-- | drivers/net/ethernet/intel/igc/igc_base.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/igc/igc_base.c b/drivers/net/ethernet/intel/igc/igc_base.c index 2d49814966d3..55faef987479 100644 --- a/drivers/net/ethernet/intel/igc/igc_base.c +++ b/drivers/net/ethernet/intel/igc/igc_base.c | |||
@@ -124,6 +124,22 @@ static s32 igc_reset_hw_base(struct igc_hw *hw) | |||
124 | } | 124 | } |
125 | 125 | ||
126 | /** | 126 | /** |
127 | * igc_get_phy_id_base - Retrieve PHY addr and id | ||
128 | * @hw: pointer to the HW structure | ||
129 | * | ||
130 | * Retrieves the PHY address and ID for both PHY's which do and do not use | ||
131 | * sgmi interface. | ||
132 | */ | ||
133 | static s32 igc_get_phy_id_base(struct igc_hw *hw) | ||
134 | { | ||
135 | s32 ret_val = 0; | ||
136 | |||
137 | ret_val = igc_get_phy_id(hw); | ||
138 | |||
139 | return ret_val; | ||
140 | } | ||
141 | |||
142 | /** | ||
127 | * igc_init_nvm_params_base - Init NVM func ptrs. | 143 | * igc_init_nvm_params_base - Init NVM func ptrs. |
128 | * @hw: pointer to the HW structure | 144 | * @hw: pointer to the HW structure |
129 | */ | 145 | */ |
@@ -187,6 +203,59 @@ static s32 igc_init_mac_params_base(struct igc_hw *hw) | |||
187 | return 0; | 203 | return 0; |
188 | } | 204 | } |
189 | 205 | ||
206 | /** | ||
207 | * igc_init_phy_params_base - Init PHY func ptrs. | ||
208 | * @hw: pointer to the HW structure | ||
209 | */ | ||
210 | static s32 igc_init_phy_params_base(struct igc_hw *hw) | ||
211 | { | ||
212 | struct igc_phy_info *phy = &hw->phy; | ||
213 | s32 ret_val = 0; | ||
214 | u32 ctrl_ext; | ||
215 | |||
216 | if (hw->phy.media_type != igc_media_type_copper) { | ||
217 | phy->type = igc_phy_none; | ||
218 | goto out; | ||
219 | } | ||
220 | |||
221 | phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT_2500; | ||
222 | phy->reset_delay_us = 100; | ||
223 | |||
224 | ctrl_ext = rd32(IGC_CTRL_EXT); | ||
225 | |||
226 | /* set lan id */ | ||
227 | hw->bus.func = (rd32(IGC_STATUS) & IGC_STATUS_FUNC_MASK) >> | ||
228 | IGC_STATUS_FUNC_SHIFT; | ||
229 | |||
230 | /* Make sure the PHY is in a good state. Several people have reported | ||
231 | * firmware leaving the PHY's page select register set to something | ||
232 | * other than the default of zero, which causes the PHY ID read to | ||
233 | * access something other than the intended register. | ||
234 | */ | ||
235 | ret_val = hw->phy.ops.reset(hw); | ||
236 | if (ret_val) { | ||
237 | hw_dbg("Error resetting the PHY.\n"); | ||
238 | goto out; | ||
239 | } | ||
240 | |||
241 | ret_val = igc_get_phy_id_base(hw); | ||
242 | if (ret_val) | ||
243 | return ret_val; | ||
244 | |||
245 | /* Verify phy id and set remaining function pointers */ | ||
246 | switch (phy->id) { | ||
247 | case I225_I_PHY_ID: | ||
248 | phy->type = igc_phy_i225; | ||
249 | break; | ||
250 | default: | ||
251 | ret_val = -IGC_ERR_PHY; | ||
252 | goto out; | ||
253 | } | ||
254 | |||
255 | out: | ||
256 | return ret_val; | ||
257 | } | ||
258 | |||
190 | static s32 igc_get_invariants_base(struct igc_hw *hw) | 259 | static s32 igc_get_invariants_base(struct igc_hw *hw) |
191 | { | 260 | { |
192 | u32 link_mode = 0; | 261 | u32 link_mode = 0; |
@@ -211,6 +280,8 @@ static s32 igc_get_invariants_base(struct igc_hw *hw) | |||
211 | break; | 280 | break; |
212 | } | 281 | } |
213 | 282 | ||
283 | /* setup PHY parameters */ | ||
284 | ret_val = igc_init_phy_params_base(hw); | ||
214 | if (ret_val) | 285 | if (ret_val) |
215 | goto out; | 286 | goto out; |
216 | 287 | ||
@@ -219,6 +290,34 @@ out: | |||
219 | } | 290 | } |
220 | 291 | ||
221 | /** | 292 | /** |
293 | * igc_acquire_phy_base - Acquire rights to access PHY | ||
294 | * @hw: pointer to the HW structure | ||
295 | * | ||
296 | * Acquire access rights to the correct PHY. This is a | ||
297 | * function pointer entry point called by the api module. | ||
298 | */ | ||
299 | static s32 igc_acquire_phy_base(struct igc_hw *hw) | ||
300 | { | ||
301 | u16 mask = IGC_SWFW_PHY0_SM; | ||
302 | |||
303 | return hw->mac.ops.acquire_swfw_sync(hw, mask); | ||
304 | } | ||
305 | |||
306 | /** | ||
307 | * igc_release_phy_base - Release rights to access PHY | ||
308 | * @hw: pointer to the HW structure | ||
309 | * | ||
310 | * A wrapper to release access rights to the correct PHY. This is a | ||
311 | * function pointer entry point called by the api module. | ||
312 | */ | ||
313 | static void igc_release_phy_base(struct igc_hw *hw) | ||
314 | { | ||
315 | u16 mask = IGC_SWFW_PHY0_SM; | ||
316 | |||
317 | hw->mac.ops.release_swfw_sync(hw, mask); | ||
318 | } | ||
319 | |||
320 | /** | ||
222 | * igc_get_link_up_info_base - Get link speed/duplex info | 321 | * igc_get_link_up_info_base - Get link speed/duplex info |
223 | * @hw: pointer to the HW structure | 322 | * @hw: pointer to the HW structure |
224 | * @speed: stores the current speed | 323 | * @speed: stores the current speed |
@@ -290,6 +389,20 @@ static s32 igc_read_mac_addr_base(struct igc_hw *hw) | |||
290 | } | 389 | } |
291 | 390 | ||
292 | /** | 391 | /** |
392 | * igc_power_down_phy_copper_base - Remove link during PHY power down | ||
393 | * @hw: pointer to the HW structure | ||
394 | * | ||
395 | * In the case of a PHY power down to save power, or to turn off link during a | ||
396 | * driver unload, or wake on lan is not enabled, remove the link. | ||
397 | */ | ||
398 | void igc_power_down_phy_copper_base(struct igc_hw *hw) | ||
399 | { | ||
400 | /* If the management interface is not enabled, then power down */ | ||
401 | if (!(igc_enable_mng_pass_thru(hw) || igc_check_reset_block(hw))) | ||
402 | igc_power_down_phy_copper(hw); | ||
403 | } | ||
404 | |||
405 | /** | ||
293 | * igc_rx_fifo_flush_base - Clean rx fifo after Rx enable | 406 | * igc_rx_fifo_flush_base - Clean rx fifo after Rx enable |
294 | * @hw: pointer to the HW structure | 407 | * @hw: pointer to the HW structure |
295 | * | 408 | * |
@@ -373,7 +486,16 @@ static struct igc_mac_operations igc_mac_ops_base = { | |||
373 | .get_speed_and_duplex = igc_get_link_up_info_base, | 486 | .get_speed_and_duplex = igc_get_link_up_info_base, |
374 | }; | 487 | }; |
375 | 488 | ||
489 | static const struct igc_phy_operations igc_phy_ops_base = { | ||
490 | .acquire = igc_acquire_phy_base, | ||
491 | .release = igc_release_phy_base, | ||
492 | .reset = igc_phy_hw_reset, | ||
493 | .read_reg = igc_read_phy_reg_gpy, | ||
494 | .write_reg = igc_write_phy_reg_gpy, | ||
495 | }; | ||
496 | |||
376 | const struct igc_info igc_base_info = { | 497 | const struct igc_info igc_base_info = { |
377 | .get_invariants = igc_get_invariants_base, | 498 | .get_invariants = igc_get_invariants_base, |
378 | .mac_ops = &igc_mac_ops_base, | 499 | .mac_ops = &igc_mac_ops_base, |
500 | .phy_ops = &igc_phy_ops_base, | ||
379 | }; | 501 | }; |