net/ngbe: setup PHY link
Setup PHY, determine link and speed status from PHY. Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
This commit is contained in:
parent
b9246b8fa2
commit
3d0af70667
@ -64,6 +64,11 @@ static inline void ngbe_mac_release_swfw_sync_dummy(struct ngbe_hw *TUP0,
|
||||
u32 TUP1)
|
||||
{
|
||||
}
|
||||
static inline s32 ngbe_mac_setup_link_dummy(struct ngbe_hw *TUP0, u32 TUP1,
|
||||
bool TUP2)
|
||||
{
|
||||
return NGBE_ERR_OPS_DUMMY;
|
||||
}
|
||||
static inline s32 ngbe_mac_check_link_dummy(struct ngbe_hw *TUP0, u32 *TUP1,
|
||||
bool *TUP3, bool TUP4)
|
||||
{
|
||||
@ -129,6 +134,16 @@ static inline s32 ngbe_phy_write_reg_unlocked_dummy(struct ngbe_hw *TUP0,
|
||||
{
|
||||
return NGBE_ERR_OPS_DUMMY;
|
||||
}
|
||||
static inline s32 ngbe_phy_setup_link_dummy(struct ngbe_hw *TUP0,
|
||||
u32 TUP1, bool TUP2)
|
||||
{
|
||||
return NGBE_ERR_OPS_DUMMY;
|
||||
}
|
||||
static inline s32 ngbe_phy_check_link_dummy(struct ngbe_hw *TUP0, u32 *TUP1,
|
||||
bool *TUP2)
|
||||
{
|
||||
return NGBE_ERR_OPS_DUMMY;
|
||||
}
|
||||
static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw)
|
||||
{
|
||||
hw->bus.set_lan_id = ngbe_bus_set_lan_id_dummy;
|
||||
@ -140,6 +155,7 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw)
|
||||
hw->mac.get_mac_addr = ngbe_mac_get_mac_addr_dummy;
|
||||
hw->mac.acquire_swfw_sync = ngbe_mac_acquire_swfw_sync_dummy;
|
||||
hw->mac.release_swfw_sync = ngbe_mac_release_swfw_sync_dummy;
|
||||
hw->mac.setup_link = ngbe_mac_setup_link_dummy;
|
||||
hw->mac.check_link = ngbe_mac_check_link_dummy;
|
||||
hw->mac.set_rar = ngbe_mac_set_rar_dummy;
|
||||
hw->mac.clear_rar = ngbe_mac_clear_rar_dummy;
|
||||
@ -154,6 +170,8 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw)
|
||||
hw->phy.write_reg = ngbe_phy_write_reg_dummy;
|
||||
hw->phy.read_reg_unlocked = ngbe_phy_read_reg_unlocked_dummy;
|
||||
hw->phy.write_reg_unlocked = ngbe_phy_write_reg_unlocked_dummy;
|
||||
hw->phy.setup_link = ngbe_phy_setup_link_dummy;
|
||||
hw->phy.check_link = ngbe_phy_check_link_dummy;
|
||||
}
|
||||
|
||||
#endif /* _NGBE_TYPE_DUMMY_H_ */
|
||||
|
@ -599,6 +599,54 @@ s32 ngbe_init_uta_tables(struct ngbe_hw *hw)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ngbe_check_mac_link_em - Determine link and speed status
|
||||
* @hw: pointer to hardware structure
|
||||
* @speed: pointer to link speed
|
||||
* @link_up: true when link is up
|
||||
* @link_up_wait_to_complete: bool used to wait for link up or not
|
||||
*
|
||||
* Reads the links register to determine if link is up and the current speed
|
||||
**/
|
||||
s32 ngbe_check_mac_link_em(struct ngbe_hw *hw, u32 *speed,
|
||||
bool *link_up, bool link_up_wait_to_complete)
|
||||
{
|
||||
u32 i, reg;
|
||||
s32 status = 0;
|
||||
|
||||
DEBUGFUNC("ngbe_check_mac_link_em");
|
||||
|
||||
reg = rd32(hw, NGBE_GPIOINTSTAT);
|
||||
wr32(hw, NGBE_GPIOEOI, reg);
|
||||
|
||||
if (link_up_wait_to_complete) {
|
||||
for (i = 0; i < hw->mac.max_link_up_time; i++) {
|
||||
status = hw->phy.check_link(hw, speed, link_up);
|
||||
if (*link_up)
|
||||
break;
|
||||
msec_delay(100);
|
||||
}
|
||||
} else {
|
||||
status = hw->phy.check_link(hw, speed, link_up);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
s32 ngbe_setup_mac_link_em(struct ngbe_hw *hw,
|
||||
u32 speed,
|
||||
bool autoneg_wait_to_complete)
|
||||
{
|
||||
s32 status;
|
||||
|
||||
DEBUGFUNC("\n");
|
||||
|
||||
/* Setup the PHY according to input speed */
|
||||
status = hw->phy.setup_link(hw, speed, autoneg_wait_to_complete);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ngbe_init_thermal_sensor_thresh - Inits thermal sensor thresholds
|
||||
* @hw: pointer to hardware structure
|
||||
@ -806,6 +854,10 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw)
|
||||
mac->set_vmdq = ngbe_set_vmdq;
|
||||
mac->clear_vmdq = ngbe_clear_vmdq;
|
||||
|
||||
/* Link */
|
||||
mac->check_link = ngbe_check_mac_link_em;
|
||||
mac->setup_link = ngbe_setup_mac_link_em;
|
||||
|
||||
/* Manageability interface */
|
||||
mac->init_thermal_sensor_thresh = ngbe_init_thermal_sensor_thresh;
|
||||
mac->check_overtemp = ngbe_mac_check_overtemp;
|
||||
@ -853,6 +905,7 @@ s32 ngbe_init_shared_code(struct ngbe_hw *hw)
|
||||
status = NGBE_ERR_DEVICE_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
hw->mac.max_link_up_time = NGBE_LINK_UP_TIME;
|
||||
|
||||
hw->bus.set_lan_id(hw);
|
||||
|
||||
|
@ -20,6 +20,12 @@ s32 ngbe_get_mac_addr(struct ngbe_hw *hw, u8 *mac_addr);
|
||||
|
||||
void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw);
|
||||
|
||||
s32 ngbe_check_mac_link_em(struct ngbe_hw *hw, u32 *speed,
|
||||
bool *link_up, bool link_up_wait_to_complete);
|
||||
s32 ngbe_setup_mac_link_em(struct ngbe_hw *hw,
|
||||
u32 speed,
|
||||
bool autoneg_wait_to_complete);
|
||||
|
||||
s32 ngbe_set_rar(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
|
||||
u32 enable_addr);
|
||||
s32 ngbe_clear_rar(struct ngbe_hw *hw, u32 index);
|
||||
|
@ -420,7 +420,29 @@ s32 ngbe_init_phy(struct ngbe_hw *hw)
|
||||
|
||||
/* Identify the PHY */
|
||||
err = phy->identify(hw);
|
||||
if (err == NGBE_ERR_PHY_ADDR_INVALID)
|
||||
goto init_phy_ops_out;
|
||||
|
||||
/* Set necessary function pointers based on PHY type */
|
||||
switch (hw->phy.type) {
|
||||
case ngbe_phy_rtl:
|
||||
hw->phy.check_link = ngbe_check_phy_link_rtl;
|
||||
hw->phy.setup_link = ngbe_setup_phy_link_rtl;
|
||||
break;
|
||||
case ngbe_phy_mvl:
|
||||
case ngbe_phy_mvl_sfi:
|
||||
hw->phy.check_link = ngbe_check_phy_link_mvl;
|
||||
hw->phy.setup_link = ngbe_setup_phy_link_mvl;
|
||||
break;
|
||||
case ngbe_phy_yt8521s:
|
||||
case ngbe_phy_yt8521s_sfi:
|
||||
hw->phy.check_link = ngbe_check_phy_link_yt;
|
||||
hw->phy.setup_link = ngbe_setup_phy_link_yt;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
init_phy_ops_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
#define NGBE_MD_PHY_ID_LOW 0x3 /* PHY ID Low Reg*/
|
||||
#define NGBE_PHY_REVISION_MASK 0xFFFFFFF0
|
||||
|
||||
#define NGBE_MII_AUTONEG_REG 0x0
|
||||
|
||||
/* IEEE 802.3 Clause 22 */
|
||||
struct mdi_reg_22 {
|
||||
u16 page;
|
||||
|
@ -48,6 +48,64 @@ s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 ngbe_setup_phy_link_mvl(struct ngbe_hw *hw, u32 speed,
|
||||
bool autoneg_wait_to_complete)
|
||||
{
|
||||
u16 value_r4 = 0;
|
||||
u16 value_r9 = 0;
|
||||
u16 value;
|
||||
|
||||
DEBUGFUNC("ngbe_setup_phy_link_mvl");
|
||||
UNREFERENCED_PARAMETER(autoneg_wait_to_complete);
|
||||
|
||||
hw->phy.autoneg_advertised = 0;
|
||||
|
||||
if (hw->phy.type == ngbe_phy_mvl) {
|
||||
if (speed & NGBE_LINK_SPEED_1GB_FULL) {
|
||||
value_r9 |= MVL_PHY_1000BASET_FULL;
|
||||
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
|
||||
}
|
||||
|
||||
if (speed & NGBE_LINK_SPEED_100M_FULL) {
|
||||
value_r4 |= MVL_PHY_100BASET_FULL;
|
||||
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_100M_FULL;
|
||||
}
|
||||
|
||||
if (speed & NGBE_LINK_SPEED_10M_FULL) {
|
||||
value_r4 |= MVL_PHY_10BASET_FULL;
|
||||
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_10M_FULL;
|
||||
}
|
||||
|
||||
hw->phy.read_reg(hw, MVL_ANA, 0, &value);
|
||||
value &= ~(MVL_PHY_100BASET_FULL |
|
||||
MVL_PHY_100BASET_HALF |
|
||||
MVL_PHY_10BASET_FULL |
|
||||
MVL_PHY_10BASET_HALF);
|
||||
value_r4 |= value;
|
||||
hw->phy.write_reg(hw, MVL_ANA, 0, value_r4);
|
||||
|
||||
hw->phy.read_reg(hw, MVL_PHY_1000BASET, 0, &value);
|
||||
value &= ~(MVL_PHY_1000BASET_FULL |
|
||||
MVL_PHY_1000BASET_HALF);
|
||||
value_r9 |= value;
|
||||
hw->phy.write_reg(hw, MVL_PHY_1000BASET, 0, value_r9);
|
||||
} else {
|
||||
hw->phy.autoneg_advertised = 1;
|
||||
|
||||
hw->phy.read_reg(hw, MVL_ANA, 0, &value);
|
||||
value &= ~(MVL_PHY_1000BASEX_HALF | MVL_PHY_1000BASEX_FULL);
|
||||
value |= MVL_PHY_1000BASEX_FULL;
|
||||
hw->phy.write_reg(hw, MVL_ANA, 0, value);
|
||||
}
|
||||
|
||||
value = MVL_CTRL_RESTART_AN | MVL_CTRL_ANE;
|
||||
ngbe_write_phy_reg_mdi(hw, MVL_CTRL, 0, value);
|
||||
|
||||
hw->phy.read_reg(hw, MVL_INTR, 0, &value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw)
|
||||
{
|
||||
u32 i;
|
||||
@ -87,3 +145,43 @@ s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw)
|
||||
return status;
|
||||
}
|
||||
|
||||
s32 ngbe_check_phy_link_mvl(struct ngbe_hw *hw,
|
||||
u32 *speed, bool *link_up)
|
||||
{
|
||||
s32 status = 0;
|
||||
u16 phy_link = 0;
|
||||
u16 phy_speed = 0;
|
||||
u16 phy_data = 0;
|
||||
u16 insr = 0;
|
||||
|
||||
DEBUGFUNC("ngbe_check_phy_link_mvl");
|
||||
|
||||
/* Initialize speed and link to default case */
|
||||
*link_up = false;
|
||||
*speed = NGBE_LINK_SPEED_UNKNOWN;
|
||||
|
||||
hw->phy.read_reg(hw, MVL_INTR, 0, &insr);
|
||||
|
||||
/*
|
||||
* Check current speed and link status of the PHY register.
|
||||
* This is a vendor specific register and may have to
|
||||
* be changed for other copper PHYs.
|
||||
*/
|
||||
status = hw->phy.read_reg(hw, MVL_PHYSR, 0, &phy_data);
|
||||
phy_link = phy_data & MVL_PHYSR_LINK;
|
||||
phy_speed = phy_data & MVL_PHYSR_SPEED_MASK;
|
||||
|
||||
if (phy_link == MVL_PHYSR_LINK) {
|
||||
*link_up = true;
|
||||
|
||||
if (phy_speed == MVL_PHYSR_SPEED_1000M)
|
||||
*speed = NGBE_LINK_SPEED_1GB_FULL;
|
||||
else if (phy_speed == MVL_PHYSR_SPEED_100M)
|
||||
*speed = NGBE_LINK_SPEED_100M_FULL;
|
||||
else if (phy_speed == MVL_PHYSR_SPEED_10M)
|
||||
*speed = NGBE_LINK_SPEED_10M_FULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -89,4 +89,8 @@ s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
|
||||
|
||||
s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw);
|
||||
|
||||
s32 ngbe_check_phy_link_mvl(struct ngbe_hw *hw,
|
||||
u32 *speed, bool *link_up);
|
||||
s32 ngbe_setup_phy_link_mvl(struct ngbe_hw *hw,
|
||||
u32 speed, bool autoneg_wait_to_complete);
|
||||
#endif /* _NGBE_PHY_MVL_H_ */
|
||||
|
@ -38,6 +38,134 @@ s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ngbe_setup_phy_link_rtl - Set and restart auto-neg
|
||||
* @hw: pointer to hardware structure
|
||||
*
|
||||
* Restart auto-negotiation and PHY and waits for completion.
|
||||
**/
|
||||
s32 ngbe_setup_phy_link_rtl(struct ngbe_hw *hw,
|
||||
u32 speed, bool autoneg_wait_to_complete)
|
||||
{
|
||||
u16 autoneg_reg = NGBE_MII_AUTONEG_REG;
|
||||
u16 value = 0;
|
||||
|
||||
DEBUGFUNC("ngbe_setup_phy_link_rtl");
|
||||
|
||||
UNREFERENCED_PARAMETER(autoneg_wait_to_complete);
|
||||
|
||||
hw->phy.read_reg(hw, RTL_INSR, 0xa43, &autoneg_reg);
|
||||
|
||||
if (!hw->mac.autoneg) {
|
||||
hw->phy.reset_hw(hw);
|
||||
|
||||
switch (speed) {
|
||||
case NGBE_LINK_SPEED_1GB_FULL:
|
||||
value = RTL_BMCR_SPEED_SELECT1;
|
||||
break;
|
||||
case NGBE_LINK_SPEED_100M_FULL:
|
||||
value = RTL_BMCR_SPEED_SELECT0;
|
||||
break;
|
||||
case NGBE_LINK_SPEED_10M_FULL:
|
||||
value = 0;
|
||||
break;
|
||||
default:
|
||||
value = RTL_BMCR_SPEED_SELECT1 | RTL_BMCR_SPEED_SELECT0;
|
||||
DEBUGOUT("unknown speed = 0x%x.\n", speed);
|
||||
break;
|
||||
}
|
||||
/* duplex full */
|
||||
value |= RTL_BMCR_DUPLEX;
|
||||
hw->phy.write_reg(hw, RTL_BMCR, RTL_DEV_ZERO, value);
|
||||
|
||||
goto skip_an;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear autoneg_advertised and set new values based on input link
|
||||
* speed.
|
||||
*/
|
||||
if (speed) {
|
||||
hw->phy.autoneg_advertised = 0;
|
||||
|
||||
if (speed & NGBE_LINK_SPEED_1GB_FULL)
|
||||
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
|
||||
|
||||
if (speed & NGBE_LINK_SPEED_100M_FULL)
|
||||
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_100M_FULL;
|
||||
|
||||
if (speed & NGBE_LINK_SPEED_10M_FULL)
|
||||
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_10M_FULL;
|
||||
}
|
||||
|
||||
/* disable 10/100M Half Duplex */
|
||||
hw->phy.read_reg(hw, RTL_ANAR, RTL_DEV_ZERO, &autoneg_reg);
|
||||
autoneg_reg &= 0xFF5F;
|
||||
hw->phy.write_reg(hw, RTL_ANAR, RTL_DEV_ZERO, autoneg_reg);
|
||||
|
||||
/* set advertise enable according to input speed */
|
||||
if (!(speed & NGBE_LINK_SPEED_1GB_FULL)) {
|
||||
hw->phy.read_reg(hw, RTL_GBCR,
|
||||
RTL_DEV_ZERO, &autoneg_reg);
|
||||
autoneg_reg &= ~RTL_GBCR_1000F;
|
||||
hw->phy.write_reg(hw, RTL_GBCR,
|
||||
RTL_DEV_ZERO, autoneg_reg);
|
||||
} else {
|
||||
hw->phy.read_reg(hw, RTL_GBCR,
|
||||
RTL_DEV_ZERO, &autoneg_reg);
|
||||
autoneg_reg |= RTL_GBCR_1000F;
|
||||
hw->phy.write_reg(hw, RTL_GBCR,
|
||||
RTL_DEV_ZERO, autoneg_reg);
|
||||
}
|
||||
|
||||
if (!(speed & NGBE_LINK_SPEED_100M_FULL)) {
|
||||
hw->phy.read_reg(hw, RTL_ANAR,
|
||||
RTL_DEV_ZERO, &autoneg_reg);
|
||||
autoneg_reg &= ~RTL_ANAR_100F;
|
||||
autoneg_reg &= ~RTL_ANAR_100H;
|
||||
hw->phy.write_reg(hw, RTL_ANAR,
|
||||
RTL_DEV_ZERO, autoneg_reg);
|
||||
} else {
|
||||
hw->phy.read_reg(hw, RTL_ANAR,
|
||||
RTL_DEV_ZERO, &autoneg_reg);
|
||||
autoneg_reg |= RTL_ANAR_100F;
|
||||
hw->phy.write_reg(hw, RTL_ANAR,
|
||||
RTL_DEV_ZERO, autoneg_reg);
|
||||
}
|
||||
|
||||
if (!(speed & NGBE_LINK_SPEED_10M_FULL)) {
|
||||
hw->phy.read_reg(hw, RTL_ANAR,
|
||||
RTL_DEV_ZERO, &autoneg_reg);
|
||||
autoneg_reg &= ~RTL_ANAR_10F;
|
||||
autoneg_reg &= ~RTL_ANAR_10H;
|
||||
hw->phy.write_reg(hw, RTL_ANAR,
|
||||
RTL_DEV_ZERO, autoneg_reg);
|
||||
} else {
|
||||
hw->phy.read_reg(hw, RTL_ANAR,
|
||||
RTL_DEV_ZERO, &autoneg_reg);
|
||||
autoneg_reg |= RTL_ANAR_10F;
|
||||
hw->phy.write_reg(hw, RTL_ANAR,
|
||||
RTL_DEV_ZERO, autoneg_reg);
|
||||
}
|
||||
|
||||
/* restart AN and wait AN done interrupt */
|
||||
autoneg_reg = RTL_BMCR_RESTART_AN | RTL_BMCR_ANE;
|
||||
hw->phy.write_reg(hw, RTL_BMCR, RTL_DEV_ZERO, autoneg_reg);
|
||||
|
||||
skip_an:
|
||||
autoneg_reg = 0x205B;
|
||||
hw->phy.write_reg(hw, RTL_LCR, 0xd04, autoneg_reg);
|
||||
hw->phy.write_reg(hw, RTL_EEELCR, 0xd04, 0);
|
||||
|
||||
hw->phy.read_reg(hw, RTL_LPCR, 0xd04, &autoneg_reg);
|
||||
autoneg_reg = autoneg_reg & 0xFFFC;
|
||||
/* act led blinking mode set to 60ms */
|
||||
autoneg_reg |= 0x2;
|
||||
hw->phy.write_reg(hw, RTL_LPCR, 0xd04, autoneg_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 ngbe_reset_phy_rtl(struct ngbe_hw *hw)
|
||||
{
|
||||
u16 value = 0, i;
|
||||
@ -63,3 +191,41 @@ s32 ngbe_reset_phy_rtl(struct ngbe_hw *hw)
|
||||
return status;
|
||||
}
|
||||
|
||||
s32 ngbe_check_phy_link_rtl(struct ngbe_hw *hw, u32 *speed, bool *link_up)
|
||||
{
|
||||
s32 status = 0;
|
||||
u16 phy_link = 0;
|
||||
u16 phy_speed = 0;
|
||||
u16 phy_data = 0;
|
||||
u16 insr = 0;
|
||||
|
||||
DEBUGFUNC("ngbe_check_phy_link_rtl");
|
||||
|
||||
hw->phy.read_reg(hw, RTL_INSR, 0xa43, &insr);
|
||||
|
||||
/* Initialize speed and link to default case */
|
||||
*link_up = false;
|
||||
*speed = NGBE_LINK_SPEED_UNKNOWN;
|
||||
|
||||
/*
|
||||
* Check current speed and link status of the PHY register.
|
||||
* This is a vendor specific register and may have to
|
||||
* be changed for other copper PHYs.
|
||||
*/
|
||||
status = hw->phy.read_reg(hw, RTL_PHYSR, 0xa43, &phy_data);
|
||||
phy_link = phy_data & RTL_PHYSR_RTLS;
|
||||
phy_speed = phy_data & (RTL_PHYSR_SPEED_MASK | RTL_PHYSR_DP);
|
||||
if (phy_link == RTL_PHYSR_RTLS) {
|
||||
*link_up = true;
|
||||
|
||||
if (phy_speed == (RTL_PHYSR_SPEED_1000M | RTL_PHYSR_DP))
|
||||
*speed = NGBE_LINK_SPEED_1GB_FULL;
|
||||
else if (phy_speed == (RTL_PHYSR_SPEED_100M | RTL_PHYSR_DP))
|
||||
*speed = NGBE_LINK_SPEED_100M_FULL;
|
||||
else if (phy_speed == (RTL_PHYSR_SPEED_10M | RTL_PHYSR_DP))
|
||||
*speed = NGBE_LINK_SPEED_10M_FULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,10 @@ s32 ngbe_read_phy_reg_rtl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
|
||||
s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
|
||||
u16 phy_data);
|
||||
|
||||
s32 ngbe_setup_phy_link_rtl(struct ngbe_hw *hw,
|
||||
u32 speed, bool autoneg_wait_to_complete);
|
||||
s32 ngbe_reset_phy_rtl(struct ngbe_hw *hw);
|
||||
s32 ngbe_check_phy_link_rtl(struct ngbe_hw *hw,
|
||||
u32 *speed, bool *link_up);
|
||||
|
||||
#endif /* _NGBE_PHY_RTL_H_ */
|
||||
|
@ -78,6 +78,104 @@ s32 ngbe_write_phy_reg_ext_yt(struct ngbe_hw *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 ngbe_read_phy_reg_sds_ext_yt(struct ngbe_hw *hw,
|
||||
u32 reg_addr, u32 device_type, u16 *phy_data)
|
||||
{
|
||||
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, YT_SMI_PHY_SDS);
|
||||
ngbe_read_phy_reg_ext_yt(hw, reg_addr, device_type, phy_data);
|
||||
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 ngbe_write_phy_reg_sds_ext_yt(struct ngbe_hw *hw,
|
||||
u32 reg_addr, u32 device_type, u16 phy_data)
|
||||
{
|
||||
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, YT_SMI_PHY_SDS);
|
||||
ngbe_write_phy_reg_ext_yt(hw, reg_addr, device_type, phy_data);
|
||||
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, device_type, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw, u32 speed,
|
||||
bool autoneg_wait_to_complete)
|
||||
{
|
||||
u16 value_r4 = 0;
|
||||
u16 value_r9 = 0;
|
||||
u16 value;
|
||||
|
||||
DEBUGFUNC("ngbe_setup_phy_link_yt");
|
||||
UNREFERENCED_PARAMETER(autoneg_wait_to_complete);
|
||||
|
||||
hw->phy.autoneg_advertised = 0;
|
||||
|
||||
if (hw->phy.type == ngbe_phy_yt8521s) {
|
||||
/*disable 100/10base-T Self-negotiation ability*/
|
||||
hw->phy.read_reg(hw, YT_ANA, 0, &value);
|
||||
value &= ~(YT_ANA_100BASET_FULL | YT_ANA_10BASET_FULL);
|
||||
hw->phy.write_reg(hw, YT_ANA, 0, value);
|
||||
|
||||
/*disable 1000base-T Self-negotiation ability*/
|
||||
hw->phy.read_reg(hw, YT_MS_CTRL, 0, &value);
|
||||
value &= ~YT_MS_1000BASET_FULL;
|
||||
hw->phy.write_reg(hw, YT_MS_CTRL, 0, value);
|
||||
|
||||
if (speed & NGBE_LINK_SPEED_1GB_FULL) {
|
||||
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
|
||||
value_r9 |= YT_MS_1000BASET_FULL;
|
||||
}
|
||||
if (speed & NGBE_LINK_SPEED_100M_FULL) {
|
||||
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_100M_FULL;
|
||||
value_r4 |= YT_ANA_100BASET_FULL;
|
||||
}
|
||||
if (speed & NGBE_LINK_SPEED_10M_FULL) {
|
||||
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_10M_FULL;
|
||||
value_r4 |= YT_ANA_10BASET_FULL;
|
||||
}
|
||||
|
||||
/* enable 1000base-T Self-negotiation ability */
|
||||
hw->phy.read_reg(hw, YT_MS_CTRL, 0, &value);
|
||||
value |= value_r9;
|
||||
hw->phy.write_reg(hw, YT_MS_CTRL, 0, value);
|
||||
|
||||
/* enable 100/10base-T Self-negotiation ability */
|
||||
hw->phy.read_reg(hw, YT_ANA, 0, &value);
|
||||
value |= value_r4;
|
||||
hw->phy.write_reg(hw, YT_ANA, 0, value);
|
||||
|
||||
/* software reset to make the above configuration take effect*/
|
||||
hw->phy.read_reg(hw, YT_BCR, 0, &value);
|
||||
value |= YT_BCR_RESET;
|
||||
hw->phy.write_reg(hw, YT_BCR, 0, value);
|
||||
} else {
|
||||
hw->phy.autoneg_advertised |= NGBE_LINK_SPEED_1GB_FULL;
|
||||
|
||||
/* RGMII_Config1 : Config rx and tx training delay */
|
||||
value = YT_RGMII_CONF1_RXDELAY |
|
||||
YT_RGMII_CONF1_TXDELAY_FE |
|
||||
YT_RGMII_CONF1_TXDELAY;
|
||||
ngbe_write_phy_reg_ext_yt(hw, YT_RGMII_CONF1, 0, value);
|
||||
value = YT_CHIP_MODE_SEL(1) |
|
||||
YT_CHIP_SW_LDO_EN |
|
||||
YT_CHIP_SW_RST;
|
||||
ngbe_write_phy_reg_ext_yt(hw, YT_CHIP, 0, value);
|
||||
|
||||
/* software reset */
|
||||
ngbe_write_phy_reg_sds_ext_yt(hw, 0x0, 0, 0x9140);
|
||||
|
||||
/* power on phy */
|
||||
hw->phy.read_reg(hw, YT_BCR, 0, &value);
|
||||
value &= ~YT_BCR_PWDN;
|
||||
hw->phy.write_reg(hw, YT_BCR, 0, value);
|
||||
}
|
||||
|
||||
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
|
||||
ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 ngbe_reset_phy_yt(struct ngbe_hw *hw)
|
||||
{
|
||||
u32 i;
|
||||
@ -110,3 +208,39 @@ s32 ngbe_reset_phy_yt(struct ngbe_hw *hw)
|
||||
return status;
|
||||
}
|
||||
|
||||
s32 ngbe_check_phy_link_yt(struct ngbe_hw *hw,
|
||||
u32 *speed, bool *link_up)
|
||||
{
|
||||
s32 status = 0;
|
||||
u16 phy_link = 0;
|
||||
u16 phy_speed = 0;
|
||||
u16 phy_data = 0;
|
||||
u16 insr = 0;
|
||||
|
||||
DEBUGFUNC("ngbe_check_phy_link_yt");
|
||||
|
||||
/* Initialize speed and link to default case */
|
||||
*link_up = false;
|
||||
*speed = NGBE_LINK_SPEED_UNKNOWN;
|
||||
|
||||
ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY, 0, 0);
|
||||
ngbe_read_phy_reg_mdi(hw, YT_INTR_STATUS, 0, &insr);
|
||||
|
||||
status = hw->phy.read_reg(hw, YT_SPST, 0, &phy_data);
|
||||
phy_link = phy_data & YT_SPST_LINK;
|
||||
phy_speed = phy_data & YT_SPST_SPEED_MASK;
|
||||
|
||||
if (phy_link) {
|
||||
*link_up = true;
|
||||
|
||||
if (phy_speed == YT_SPST_SPEED_1000M)
|
||||
*speed = NGBE_LINK_SPEED_1GB_FULL;
|
||||
else if (phy_speed == YT_SPST_SPEED_100M)
|
||||
*speed = NGBE_LINK_SPEED_100M_FULL;
|
||||
else if (phy_speed == YT_SPST_SPEED_10M)
|
||||
*speed = NGBE_LINK_SPEED_10M_FULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,15 @@ s32 ngbe_read_phy_reg_ext_yt(struct ngbe_hw *hw,
|
||||
u32 reg_addr, u32 device_type, u16 *phy_data);
|
||||
s32 ngbe_write_phy_reg_ext_yt(struct ngbe_hw *hw,
|
||||
u32 reg_addr, u32 device_type, u16 phy_data);
|
||||
s32 ngbe_read_phy_reg_sds_ext_yt(struct ngbe_hw *hw,
|
||||
u32 reg_addr, u32 device_type, u16 *phy_data);
|
||||
s32 ngbe_write_phy_reg_sds_ext_yt(struct ngbe_hw *hw,
|
||||
u32 reg_addr, u32 device_type, u16 phy_data);
|
||||
|
||||
s32 ngbe_reset_phy_yt(struct ngbe_hw *hw);
|
||||
|
||||
s32 ngbe_check_phy_link_yt(struct ngbe_hw *hw,
|
||||
u32 *speed, bool *link_up);
|
||||
s32 ngbe_setup_phy_link_yt(struct ngbe_hw *hw,
|
||||
u32 speed, bool autoneg_wait_to_complete);
|
||||
#endif /* _NGBE_PHY_YT_H_ */
|
||||
|
@ -6,6 +6,8 @@
|
||||
#ifndef _NGBE_TYPE_H_
|
||||
#define _NGBE_TYPE_H_
|
||||
|
||||
#define NGBE_LINK_UP_TIME 90 /* 9.0 Seconds */
|
||||
|
||||
#define NGBE_FRAME_SIZE_DFT (1522) /* Default frame size, +FCS */
|
||||
|
||||
#define NGBE_ALIGN 128 /* as intel did */
|
||||
@ -97,6 +99,8 @@ struct ngbe_mac_info {
|
||||
s32 (*acquire_swfw_sync)(struct ngbe_hw *hw, u32 mask);
|
||||
void (*release_swfw_sync)(struct ngbe_hw *hw, u32 mask);
|
||||
|
||||
s32 (*setup_link)(struct ngbe_hw *hw, u32 speed,
|
||||
bool autoneg_wait_to_complete);
|
||||
s32 (*check_link)(struct ngbe_hw *hw, u32 *speed,
|
||||
bool *link_up, bool link_up_wait_to_complete);
|
||||
/* RAR */
|
||||
@ -122,6 +126,9 @@ struct ngbe_mac_info {
|
||||
bool get_link_status;
|
||||
struct ngbe_thermal_sensor_data thermal_sensor_data;
|
||||
bool set_lben;
|
||||
u32 max_link_up_time;
|
||||
|
||||
bool autoneg;
|
||||
};
|
||||
|
||||
struct ngbe_phy_info {
|
||||
@ -135,6 +142,9 @@ struct ngbe_phy_info {
|
||||
u32 device_type, u16 *phy_data);
|
||||
s32 (*write_reg_unlocked)(struct ngbe_hw *hw, u32 reg_addr,
|
||||
u32 device_type, u16 phy_data);
|
||||
s32 (*setup_link)(struct ngbe_hw *hw, u32 speed,
|
||||
bool autoneg_wait_to_complete);
|
||||
s32 (*check_link)(struct ngbe_hw *hw, u32 *speed, bool *link_up);
|
||||
|
||||
enum ngbe_media_type media_type;
|
||||
enum ngbe_phy_type type;
|
||||
@ -143,6 +153,7 @@ struct ngbe_phy_info {
|
||||
u32 revision;
|
||||
u32 phy_semaphore_mask;
|
||||
bool reset_disable;
|
||||
u32 autoneg_advertised;
|
||||
};
|
||||
|
||||
enum ngbe_isb_idx {
|
||||
|
Loading…
Reference in New Issue
Block a user