Lines Matching +full:hw +full:- +full:flow +full:- +full:ctrl
1 // SPDX-License-Identifier: GPL-2.0
7 * igc_check_reset_block - Check if PHY reset is blocked
8 * @hw: pointer to the HW structure
14 s32 igc_check_reset_block(struct igc_hw *hw) in igc_check_reset_block() argument
25 * igc_get_phy_id - Retrieve the PHY ID and revision
26 * @hw: pointer to the HW structure
31 s32 igc_get_phy_id(struct igc_hw *hw) in igc_get_phy_id() argument
33 struct igc_phy_info *phy = &hw->phy; in igc_get_phy_id()
37 ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id); in igc_get_phy_id()
41 phy->id = (u32)(phy_id << 16); in igc_get_phy_id()
43 ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id); in igc_get_phy_id()
47 phy->id |= (u32)(phy_id & PHY_REVISION_MASK); in igc_get_phy_id()
48 phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK); in igc_get_phy_id()
55 * igc_phy_has_link - Polls PHY for link
56 * @hw: pointer to the HW structure
63 s32 igc_phy_has_link(struct igc_hw *hw, u32 iterations, in igc_phy_has_link() argument
74 ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); in igc_phy_has_link()
85 ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); in igc_phy_has_link()
102 * igc_power_up_phy_copper - Restore copper link in case of PHY power down
103 * @hw: pointer to the HW structure
108 void igc_power_up_phy_copper(struct igc_hw *hw) in igc_power_up_phy_copper() argument
113 hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg); in igc_power_up_phy_copper()
115 hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg); in igc_power_up_phy_copper()
119 * igc_power_down_phy_copper - Power down copper PHY
120 * @hw: pointer to the HW structure
125 void igc_power_down_phy_copper(struct igc_hw *hw) in igc_power_down_phy_copper() argument
130 hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg); in igc_power_down_phy_copper()
133 /* Temporary workaround - should be removed when PHY will implement in igc_power_down_phy_copper()
136 /* hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);*/ in igc_power_down_phy_copper()
141 * igc_check_downshift - Checks whether a downshift in speed occurred
142 * @hw: pointer to the HW structure
148 s32 igc_check_downshift(struct igc_hw *hw) in igc_check_downshift() argument
150 struct igc_phy_info *phy = &hw->phy; in igc_check_downshift()
153 switch (phy->type) { in igc_check_downshift()
157 phy->speed_downgraded = false; in igc_check_downshift()
165 * igc_phy_hw_reset - PHY hardware reset
166 * @hw: pointer to the HW structure
173 s32 igc_phy_hw_reset(struct igc_hw *hw) in igc_phy_hw_reset() argument
175 struct igc_phy_info *phy = &hw->phy; in igc_phy_hw_reset()
178 u32 ctrl; in igc_phy_hw_reset() local
180 ret_val = igc_check_reset_block(hw); in igc_phy_hw_reset()
186 ret_val = phy->ops.acquire(hw); in igc_phy_hw_reset()
192 ctrl = rd32(IGC_CTRL); in igc_phy_hw_reset()
193 wr32(IGC_CTRL, ctrl | IGC_CTRL_PHY_RST); in igc_phy_hw_reset()
196 udelay(phy->reset_delay_us); in igc_phy_hw_reset()
198 wr32(IGC_CTRL, ctrl); in igc_phy_hw_reset()
205 timeout--; in igc_phy_hw_reset()
214 phy->ops.release(hw); in igc_phy_hw_reset()
221 * igc_phy_setup_autoneg - Configure PHY for auto-negotiation
222 * @hw: pointer to the HW structure
224 * Reads the MII auto-neg advertisement register and/or the 1000T control
225 * register and if the PHY is already setup for auto-negotiation, then
226 * return successful. Otherwise, setup advertisement and flow control to
227 * the appropriate values for the wanted auto-negotiation.
229 static s32 igc_phy_setup_autoneg(struct igc_hw *hw) in igc_phy_setup_autoneg() argument
231 struct igc_phy_info *phy = &hw->phy; in igc_phy_setup_autoneg()
237 phy->autoneg_advertised &= phy->autoneg_mask; in igc_phy_setup_autoneg()
239 /* Read the MII Auto-Neg Advertisement Register (Address 4). */ in igc_phy_setup_autoneg()
240 ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg); in igc_phy_setup_autoneg()
244 if (phy->autoneg_mask & ADVERTISE_1000_FULL) { in igc_phy_setup_autoneg()
245 /* Read the MII 1000Base-T Control Register (Address 9). */ in igc_phy_setup_autoneg()
246 ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, in igc_phy_setup_autoneg()
252 if ((phy->autoneg_mask & ADVERTISE_2500_FULL) && in igc_phy_setup_autoneg()
253 hw->phy.id == I225_I_PHY_ID) { in igc_phy_setup_autoneg()
254 /* Read the MULTI GBT AN Control Register - reg 7.32 */ in igc_phy_setup_autoneg()
255 ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK << in igc_phy_setup_autoneg()
271 /* First we clear all the 10/100 mb speed bits in the Auto-Neg in igc_phy_setup_autoneg()
273 * the 1000Base-T Control Register (Address 9). in igc_phy_setup_autoneg()
281 hw_dbg("autoneg_advertised %x\n", phy->autoneg_advertised); in igc_phy_setup_autoneg()
284 if (phy->autoneg_advertised & ADVERTISE_10_HALF) { in igc_phy_setup_autoneg()
290 if (phy->autoneg_advertised & ADVERTISE_10_FULL) { in igc_phy_setup_autoneg()
296 if (phy->autoneg_advertised & ADVERTISE_100_HALF) { in igc_phy_setup_autoneg()
302 if (phy->autoneg_advertised & ADVERTISE_100_FULL) { in igc_phy_setup_autoneg()
308 if (phy->autoneg_advertised & ADVERTISE_1000_HALF) in igc_phy_setup_autoneg()
312 if (phy->autoneg_advertised & ADVERTISE_1000_FULL) { in igc_phy_setup_autoneg()
318 if (phy->autoneg_advertised & ADVERTISE_2500_HALF) in igc_phy_setup_autoneg()
322 if (phy->autoneg_advertised & ADVERTISE_2500_FULL) { in igc_phy_setup_autoneg()
329 /* Check for a software override of the flow control settings, and in igc_phy_setup_autoneg()
331 * auto-negotiation is enabled, then software will have to set the in igc_phy_setup_autoneg()
332 * "PAUSE" bits to the correct value in the Auto-Negotiation in igc_phy_setup_autoneg()
333 * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto- in igc_phy_setup_autoneg()
337 * 0: Flow control is completely disabled in igc_phy_setup_autoneg()
338 * 1: Rx flow control is enabled (we can receive pause frames in igc_phy_setup_autoneg()
340 * 2: Tx flow control is enabled (we can send pause frames in igc_phy_setup_autoneg()
342 * 3: Both Rx and Tx flow control (symmetric) are enabled. in igc_phy_setup_autoneg()
343 * other: No software override. The flow control configuration in igc_phy_setup_autoneg()
346 switch (hw->fc.current_mode) { in igc_phy_setup_autoneg()
348 /* Flow control (Rx & Tx) is completely disabled by a in igc_phy_setup_autoneg()
349 * software over-ride. in igc_phy_setup_autoneg()
354 /* Rx Flow control is enabled, and Tx Flow control is in igc_phy_setup_autoneg()
355 * disabled, by a software over-ride. in igc_phy_setup_autoneg()
361 * hw's ability to send PAUSE frames. in igc_phy_setup_autoneg()
366 /* Tx Flow control is enabled, and Rx Flow control is in igc_phy_setup_autoneg()
367 * disabled, by a software over-ride. in igc_phy_setup_autoneg()
373 /* Flow control (both Rx and Tx) is enabled by a software in igc_phy_setup_autoneg()
374 * over-ride. in igc_phy_setup_autoneg()
379 hw_dbg("Flow control param set incorrectly\n"); in igc_phy_setup_autoneg()
380 return -IGC_ERR_CONFIG; in igc_phy_setup_autoneg()
383 ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg); in igc_phy_setup_autoneg()
387 hw_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); in igc_phy_setup_autoneg()
389 if (phy->autoneg_mask & ADVERTISE_1000_FULL) in igc_phy_setup_autoneg()
390 ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, in igc_phy_setup_autoneg()
393 if ((phy->autoneg_mask & ADVERTISE_2500_FULL) && in igc_phy_setup_autoneg()
394 hw->phy.id == I225_I_PHY_ID) in igc_phy_setup_autoneg()
395 ret_val = phy->ops.write_reg(hw, in igc_phy_setup_autoneg()
405 * igc_wait_autoneg - Wait for auto-neg completion
406 * @hw: pointer to the HW structure
408 * Waits for auto-negotiation to complete or for the auto-negotiation time
411 static s32 igc_wait_autoneg(struct igc_hw *hw) in igc_wait_autoneg() argument
417 for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) { in igc_wait_autoneg()
418 ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); in igc_wait_autoneg()
421 ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); in igc_wait_autoneg()
429 /* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation in igc_wait_autoneg()
436 * igc_copper_link_autoneg - Setup/Enable autoneg for copper link
437 * @hw: pointer to the HW structure
444 static s32 igc_copper_link_autoneg(struct igc_hw *hw) in igc_copper_link_autoneg() argument
446 struct igc_phy_info *phy = &hw->phy; in igc_copper_link_autoneg()
453 phy->autoneg_advertised &= phy->autoneg_mask; in igc_copper_link_autoneg()
458 if (phy->autoneg_advertised == 0) in igc_copper_link_autoneg()
459 phy->autoneg_advertised = phy->autoneg_mask; in igc_copper_link_autoneg()
461 hw_dbg("Reconfiguring auto-neg advertisement params\n"); in igc_copper_link_autoneg()
462 ret_val = igc_phy_setup_autoneg(hw); in igc_copper_link_autoneg()
464 hw_dbg("Error Setting up Auto-Negotiation\n"); in igc_copper_link_autoneg()
467 hw_dbg("Restarting Auto-Neg\n"); in igc_copper_link_autoneg()
469 /* Restart auto-negotiation by setting the Auto Neg Enable bit and in igc_copper_link_autoneg()
472 ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl); in igc_copper_link_autoneg()
477 ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl); in igc_copper_link_autoneg()
481 /* Does the user want to wait for Auto-Neg to complete here, or in igc_copper_link_autoneg()
484 if (phy->autoneg_wait_to_complete) { in igc_copper_link_autoneg()
485 ret_val = igc_wait_autoneg(hw); in igc_copper_link_autoneg()
492 hw->mac.get_link_status = true; in igc_copper_link_autoneg()
499 * igc_setup_copper_link - Configure copper link settings
500 * @hw: pointer to the HW structure
502 * Calls the appropriate function to configure the link for auto-neg or forced
504 * to configure collision distance and flow control are called. If link is
505 * not established, we return -IGC_ERR_PHY (-2).
507 s32 igc_setup_copper_link(struct igc_hw *hw) in igc_setup_copper_link() argument
512 if (hw->mac.autoneg) { in igc_setup_copper_link()
513 /* Setup autoneg and flow control advertisement and perform in igc_setup_copper_link()
516 ret_val = igc_copper_link_autoneg(hw); in igc_setup_copper_link()
524 ret_val = hw->phy.ops.force_speed_duplex(hw); in igc_setup_copper_link()
534 ret_val = igc_phy_has_link(hw, COPPER_LINK_UP_LIMIT, 10, &link); in igc_setup_copper_link()
540 igc_config_collision_dist(hw); in igc_setup_copper_link()
541 ret_val = igc_config_fc_after_link_up(hw); in igc_setup_copper_link()
551 * igc_read_phy_reg_mdic - Read MDI control register
552 * @hw: pointer to the HW structure
559 static s32 igc_read_phy_reg_mdic(struct igc_hw *hw, u32 offset, u16 *data) in igc_read_phy_reg_mdic() argument
561 struct igc_phy_info *phy = &hw->phy; in igc_read_phy_reg_mdic()
567 ret_val = -IGC_ERR_PARAM; in igc_read_phy_reg_mdic()
571 /* Set up Op-code, Phy Address, and register offset in the MDI in igc_read_phy_reg_mdic()
576 (phy->addr << IGC_MDIC_PHY_SHIFT) | in igc_read_phy_reg_mdic()
593 ret_val = -IGC_ERR_PHY; in igc_read_phy_reg_mdic()
598 ret_val = -IGC_ERR_PHY; in igc_read_phy_reg_mdic()
608 * igc_write_phy_reg_mdic - Write MDI control register
609 * @hw: pointer to the HW structure
615 static s32 igc_write_phy_reg_mdic(struct igc_hw *hw, u32 offset, u16 data) in igc_write_phy_reg_mdic() argument
617 struct igc_phy_info *phy = &hw->phy; in igc_write_phy_reg_mdic()
623 ret_val = -IGC_ERR_PARAM; in igc_write_phy_reg_mdic()
627 /* Set up Op-code, Phy Address, and register offset in the MDI in igc_write_phy_reg_mdic()
633 (phy->addr << IGC_MDIC_PHY_SHIFT) | in igc_write_phy_reg_mdic()
650 ret_val = -IGC_ERR_PHY; in igc_write_phy_reg_mdic()
655 ret_val = -IGC_ERR_PHY; in igc_write_phy_reg_mdic()
664 * __igc_access_xmdio_reg - Read/write XMDIO register
665 * @hw: pointer to the HW structure
671 static s32 __igc_access_xmdio_reg(struct igc_hw *hw, u16 address, in __igc_access_xmdio_reg() argument
676 ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, dev_addr); in __igc_access_xmdio_reg()
680 ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAAD, address); in __igc_access_xmdio_reg()
684 ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, IGC_MMDAC_FUNC_DATA | in __igc_access_xmdio_reg()
690 ret_val = hw->phy.ops.read_reg(hw, IGC_MMDAAD, data); in __igc_access_xmdio_reg()
692 ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAAD, *data); in __igc_access_xmdio_reg()
697 ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, 0); in __igc_access_xmdio_reg()
705 * igc_read_xmdio_reg - Read XMDIO register
706 * @hw: pointer to the HW structure
711 static s32 igc_read_xmdio_reg(struct igc_hw *hw, u16 addr, in igc_read_xmdio_reg() argument
714 return __igc_access_xmdio_reg(hw, addr, dev_addr, data, true); in igc_read_xmdio_reg()
718 * igc_write_xmdio_reg - Write XMDIO register
719 * @hw: pointer to the HW structure
724 static s32 igc_write_xmdio_reg(struct igc_hw *hw, u16 addr, in igc_write_xmdio_reg() argument
727 return __igc_access_xmdio_reg(hw, addr, dev_addr, &data, false); in igc_write_xmdio_reg()
731 * igc_write_phy_reg_gpy - Write GPY PHY register
732 * @hw: pointer to the HW structure
739 s32 igc_write_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 data) in igc_write_phy_reg_gpy() argument
747 ret_val = hw->phy.ops.acquire(hw); in igc_write_phy_reg_gpy()
750 ret_val = igc_write_phy_reg_mdic(hw, offset, data); in igc_write_phy_reg_gpy()
753 hw->phy.ops.release(hw); in igc_write_phy_reg_gpy()
755 ret_val = igc_write_xmdio_reg(hw, (u16)offset, dev_addr, in igc_write_phy_reg_gpy()
763 * igc_read_phy_reg_gpy - Read GPY PHY register
764 * @hw: pointer to the HW structure
772 s32 igc_read_phy_reg_gpy(struct igc_hw *hw, u32 offset, u16 *data) in igc_read_phy_reg_gpy() argument
780 ret_val = hw->phy.ops.acquire(hw); in igc_read_phy_reg_gpy()
783 ret_val = igc_read_phy_reg_mdic(hw, offset, data); in igc_read_phy_reg_gpy()
786 hw->phy.ops.release(hw); in igc_read_phy_reg_gpy()
788 ret_val = igc_read_xmdio_reg(hw, (u16)offset, dev_addr, in igc_read_phy_reg_gpy()