Commit 85730a63 authored by Michael Chan's avatar Michael Chan Committed by David S. Miller

tg3: Add SGMII phy support for 5719/5718 serdes

Signed-off-by: default avatarNithin Nayak Sujir <nsujir@broadcom.com>
Signed-off-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3310e248
...@@ -5465,11 +5465,50 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset) ...@@ -5465,11 +5465,50 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
{ {
int current_link_up, err = 0; int current_link_up = 0, err = 0;
u32 bmsr, bmcr; u32 bmsr, bmcr;
u16 current_speed; u16 current_speed = SPEED_UNKNOWN;
u8 current_duplex; u8 current_duplex = DUPLEX_UNKNOWN;
u32 local_adv, remote_adv; u32 local_adv, remote_adv, sgsr;
if ((tg3_asic_rev(tp) == ASIC_REV_5719 ||
tg3_asic_rev(tp) == ASIC_REV_5720) &&
!tg3_readphy(tp, SERDES_TG3_1000X_STATUS, &sgsr) &&
(sgsr & SERDES_TG3_SGMII_MODE)) {
if (force_reset)
tg3_phy_reset(tp);
tp->mac_mode &= ~MAC_MODE_PORT_MODE_MASK;
if (!(sgsr & SERDES_TG3_LINK_UP)) {
tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
} else {
current_link_up = 1;
if (sgsr & SERDES_TG3_SPEED_1000) {
current_speed = SPEED_1000;
tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
} else if (sgsr & SERDES_TG3_SPEED_100) {
current_speed = SPEED_100;
tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
} else {
current_speed = SPEED_10;
tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
}
if (sgsr & SERDES_TG3_FULL_DUPLEX)
current_duplex = DUPLEX_FULL;
else
current_duplex = DUPLEX_HALF;
}
tw32_f(MAC_MODE, tp->mac_mode);
udelay(40);
tg3_clear_mac_status(tp);
goto fiber_setup_done;
}
tp->mac_mode |= MAC_MODE_PORT_MODE_GMII; tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
tw32_f(MAC_MODE, tp->mac_mode); tw32_f(MAC_MODE, tp->mac_mode);
...@@ -5480,9 +5519,6 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) ...@@ -5480,9 +5519,6 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
if (force_reset) if (force_reset)
tg3_phy_reset(tp); tg3_phy_reset(tp);
current_link_up = 0;
current_speed = SPEED_UNKNOWN;
current_duplex = DUPLEX_UNKNOWN;
tp->link_config.rmt_adv = 0; tp->link_config.rmt_adv = 0;
err |= tg3_readphy(tp, MII_BMSR, &bmsr); err |= tg3_readphy(tp, MII_BMSR, &bmsr);
...@@ -5600,6 +5636,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) ...@@ -5600,6 +5636,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
} }
} }
fiber_setup_done:
if (current_link_up == 1 && current_duplex == DUPLEX_FULL) if (current_link_up == 1 && current_duplex == DUPLEX_FULL)
tg3_setup_flow_control(tp, local_adv, remote_adv); tg3_setup_flow_control(tp, local_adv, remote_adv);
......
...@@ -2371,6 +2371,13 @@ ...@@ -2371,6 +2371,13 @@
#define MII_TG3_FET_SHDW_AUXSTAT2 0x1b #define MII_TG3_FET_SHDW_AUXSTAT2 0x1b
#define MII_TG3_FET_SHDW_AUXSTAT2_APD 0x0020 #define MII_TG3_FET_SHDW_AUXSTAT2_APD 0x0020
/* Serdes PHY Register Definitions */
#define SERDES_TG3_1000X_STATUS 0x14
#define SERDES_TG3_SGMII_MODE 0x0001
#define SERDES_TG3_LINK_UP 0x0002
#define SERDES_TG3_FULL_DUPLEX 0x0004
#define SERDES_TG3_SPEED_100 0x0008
#define SERDES_TG3_SPEED_1000 0x0010
/* APE registers. Accessible through BAR1 */ /* APE registers. Accessible through BAR1 */
#define TG3_APE_GPIO_MSG 0x0008 #define TG3_APE_GPIO_MSG 0x0008
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment