aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/igc/igc_base.c
diff options
context:
space:
mode:
authorSasha Neftin <sasha.neftin@intel.com>2018-10-11 03:17:31 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2018-10-17 16:55:18 -0400
commit5586838fe9ced0980e210b39d635ff3842297448 (patch)
tree1646f8cca19ced662aac1f065426d27344ec5fa9 /drivers/net/ethernet/intel/igc/igc_base.c
parentab4056126813c889ee6c8fb24ca8f75b84c981ab (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.c122
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 */
133static 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 */
210static 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
255out:
256 return ret_val;
257}
258
190static s32 igc_get_invariants_base(struct igc_hw *hw) 259static 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 */
299static 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 */
313static 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 */
398void 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
489static 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
376const struct igc_info igc_base_info = { 497const 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};