aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/bnx2x_link.c380
-rw-r--r--drivers/net/bnx2x_reg.h2
2 files changed, 216 insertions, 166 deletions
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c
index ff2743db10d9..3b63c8ce952a 100644
--- a/drivers/net/bnx2x_link.c
+++ b/drivers/net/bnx2x_link.c
@@ -1690,7 +1690,11 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
1690 1690
1691 vars->link_status |= LINK_STATUS_SERDES_LINK; 1691 vars->link_status |= LINK_STATUS_SERDES_LINK;
1692 1692
1693 if (params->req_line_speed == SPEED_AUTO_NEG) { 1693 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1694 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1695 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1696 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1697 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
1694 vars->autoneg = AUTO_NEG_ENABLED; 1698 vars->autoneg = AUTO_NEG_ENABLED;
1695 1699
1696 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { 1700 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
@@ -1716,7 +1720,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
1716 DP(NETIF_MSG_LINK, "phy link down\n"); 1720 DP(NETIF_MSG_LINK, "phy link down\n");
1717 1721
1718 vars->phy_link_up = 0; 1722 vars->phy_link_up = 0;
1719 vars->line_speed = 0; 1723
1720 vars->duplex = DUPLEX_FULL; 1724 vars->duplex = DUPLEX_FULL;
1721 vars->flow_ctrl = FLOW_CTRL_NONE; 1725 vars->flow_ctrl = FLOW_CTRL_NONE;
1722 vars->autoneg = AUTO_NEG_DISABLED; 1726 vars->autoneg = AUTO_NEG_DISABLED;
@@ -2302,6 +2306,65 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params,
2302 MDIO_AN_REG_ADV_PAUSE, val); 2306 MDIO_AN_REG_ADV_PAUSE, val);
2303} 2307}
2304 2308
2309
2310static void bnx2x_init_internal_phy(struct link_params *params,
2311 struct link_vars *vars)
2312{
2313 struct bnx2x *bp = params->bp;
2314 u8 port = params->port;
2315 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2316 u16 bank, rx_eq;
2317
2318 rx_eq = ((params->serdes_config &
2319 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2320 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2321
2322 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2323 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2324 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2325 CL45_WR_OVER_CL22(bp, port,
2326 params->phy_addr,
2327 bank ,
2328 MDIO_RX0_RX_EQ_BOOST,
2329 ((rx_eq &
2330 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2331 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2332 }
2333
2334 /* forced speed requested? */
2335 if (vars->line_speed != SPEED_AUTO_NEG) {
2336 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2337
2338 /* disable autoneg */
2339 bnx2x_set_autoneg(params, vars);
2340
2341 /* program speed and duplex */
2342 bnx2x_program_serdes(params);
2343
2344 } else { /* AN_mode */
2345 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2346
2347 /* AN enabled */
2348 bnx2x_set_brcm_cl37_advertisment(params);
2349
2350 /* program duplex & pause advertisement (for aneg) */
2351 bnx2x_set_ieee_aneg_advertisment(params,
2352 &vars->ieee_fc);
2353
2354 /* enable autoneg */
2355 bnx2x_set_autoneg(params, vars);
2356
2357 /* enable and restart AN */
2358 bnx2x_restart_autoneg(params);
2359 }
2360
2361 } else { /* SGMII mode */
2362 DP(NETIF_MSG_LINK, "SGMII\n");
2363
2364 bnx2x_initialize_sgmii_process(params);
2365 }
2366}
2367
2305static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) 2368static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2306{ 2369{
2307 struct bnx2x *bp = params->bp; 2370 struct bnx2x *bp = params->bp;
@@ -2343,7 +2406,6 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2343 2406
2344 switch (ext_phy_type) { 2407 switch (ext_phy_type) {
2345 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: 2408 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2346 DP(NETIF_MSG_LINK, "XGXS Direct\n");
2347 break; 2409 break;
2348 2410
2349 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: 2411 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
@@ -2701,10 +2763,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2701 } 2763 }
2702 2764
2703 } else { /* SerDes */ 2765 } else { /* SerDes */
2704/* ext_phy_addr = ((bp->ext_phy_config & 2766
2705 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) >>
2706 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT);
2707*/
2708 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); 2767 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2709 switch (ext_phy_type) { 2768 switch (ext_phy_type) {
2710 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: 2769 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
@@ -2810,6 +2869,13 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2810 */ 2869 */
2811 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) || 2870 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
2812 (val2 & (1<<1))); 2871 (val2 & (1<<1)));
2872 if (ext_phy_link_up) {
2873 if (val2 & (1<<1))
2874 vars->line_speed = SPEED_1000;
2875 else
2876 vars->line_speed = SPEED_10000;
2877 }
2878
2813 /* clear LASI indication*/ 2879 /* clear LASI indication*/
2814 bnx2x_cl45_read(bp, params->port, ext_phy_type, 2880 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2815 ext_phy_addr, 2881 ext_phy_addr,
@@ -3006,6 +3072,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
3006 MDIO_AN_DEVAD, 3072 MDIO_AN_DEVAD,
3007 MDIO_AN_REG_MASTER_STATUS, 3073 MDIO_AN_REG_MASTER_STATUS,
3008 &val2); 3074 &val2);
3075 vars->line_speed = SPEED_10000;
3009 DP(NETIF_MSG_LINK, 3076 DP(NETIF_MSG_LINK,
3010 "SFX7101 AN status 0x%x->Master=%x\n", 3077 "SFX7101 AN status 0x%x->Master=%x\n",
3011 val2, 3078 val2,
@@ -3181,7 +3248,8 @@ static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
3181} 3248}
3182 3249
3183 3250
3184static void bnx2x_turn_on_sf(struct bnx2x *bp, u8 port, u8 ext_phy_addr) 3251static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
3252 u32 ext_phy_type)
3185{ 3253{
3186 u32 cnt = 0; 3254 u32 cnt = 0;
3187 u16 ctrl = 0; 3255 u16 ctrl = 0;
@@ -3205,7 +3273,7 @@ static void bnx2x_turn_on_sf(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
3205 for (cnt = 0; cnt < 1000; cnt++) { 3273 for (cnt = 0; cnt < 1000; cnt++) {
3206 msleep(1); 3274 msleep(1);
3207 bnx2x_cl45_read(bp, port, 3275 bnx2x_cl45_read(bp, port,
3208 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, 3276 ext_phy_type,
3209 ext_phy_addr, 3277 ext_phy_addr,
3210 MDIO_PMA_DEVAD, 3278 MDIO_PMA_DEVAD,
3211 MDIO_PMA_REG_CTRL, 3279 MDIO_PMA_REG_CTRL,
@@ -3253,7 +3321,8 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3253 3321
3254 /* Take ext phy out of reset */ 3322 /* Take ext phy out of reset */
3255 if (!driver_loaded) 3323 if (!driver_loaded)
3256 bnx2x_turn_on_sf(bp, params->port, ext_phy_addr); 3324 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3325 ext_phy_type);
3257 3326
3258 /* wait for 1ms */ 3327 /* wait for 1ms */
3259 msleep(1); 3328 msleep(1);
@@ -3281,6 +3350,11 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3281 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: 3350 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3282 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 3351 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3283 { 3352 {
3353 /* Take ext phy out of reset */
3354 if (!driver_loaded)
3355 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3356 ext_phy_type);
3357
3284 bnx2x_cl45_read(bp, params->port, ext_phy_type, 3358 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3285 ext_phy_addr, 3359 ext_phy_addr,
3286 MDIO_PMA_DEVAD, 3360 MDIO_PMA_DEVAD,
@@ -3622,7 +3696,8 @@ static u8 bnx2x_link_initialize(struct link_params *params,
3622 struct bnx2x *bp = params->bp; 3696 struct bnx2x *bp = params->bp;
3623 u8 port = params->port; 3697 u8 port = params->port;
3624 u8 rc = 0; 3698 u8 rc = 0;
3625 3699 u8 non_ext_phy;
3700 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3626 /* Activate the external PHY */ 3701 /* Activate the external PHY */
3627 bnx2x_ext_phy_reset(params, vars); 3702 bnx2x_ext_phy_reset(params, vars);
3628 3703
@@ -3644,10 +3719,6 @@ static u8 bnx2x_link_initialize(struct link_params *params,
3644 bnx2x_set_swap_lanes(params); 3719 bnx2x_set_swap_lanes(params);
3645 } 3720 }
3646 3721
3647 /* Set Parallel Detect */
3648 if (params->req_line_speed == SPEED_AUTO_NEG)
3649 bnx2x_set_parallel_detection(params, vars->phy_flags);
3650
3651 if (vars->phy_flags & PHY_XGXS_FLAG) { 3722 if (vars->phy_flags & PHY_XGXS_FLAG) {
3652 if (params->req_line_speed && 3723 if (params->req_line_speed &&
3653 ((params->req_line_speed == SPEED_100) || 3724 ((params->req_line_speed == SPEED_100) ||
@@ -3657,68 +3728,33 @@ static u8 bnx2x_link_initialize(struct link_params *params,
3657 vars->phy_flags &= ~PHY_SGMII_FLAG; 3728 vars->phy_flags &= ~PHY_SGMII_FLAG;
3658 } 3729 }
3659 } 3730 }
3731 /* In case of external phy existance, the line speed would be the
3732 line speed linked up by the external phy. In case it is direct only,
3733 then the line_speed during initialization will be equal to the
3734 req_line_speed*/
3735 vars->line_speed = params->req_line_speed;
3660 3736
3661 if (!(vars->phy_flags & PHY_SGMII_FLAG)) { 3737 bnx2x_set_ieee_aneg_advertisment(params, &vars->ieee_fc);
3662 u16 bank, rx_eq;
3663
3664 rx_eq = ((params->serdes_config &
3665 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
3666 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
3667
3668 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
3669 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
3670 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
3671 CL45_WR_OVER_CL22(bp, port,
3672 params->phy_addr,
3673 bank ,
3674 MDIO_RX0_RX_EQ_BOOST,
3675 ((rx_eq &
3676 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
3677 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
3678 }
3679
3680 /* forced speed requested? */
3681 if (params->req_line_speed != SPEED_AUTO_NEG) {
3682 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
3683
3684 /* disable autoneg */
3685 bnx2x_set_autoneg(params, vars);
3686
3687 /* program speed and duplex */
3688 bnx2x_program_serdes(params);
3689 vars->ieee_fc =
3690 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
3691
3692 } else { /* AN_mode */
3693 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
3694
3695 /* AN enabled */
3696 bnx2x_set_brcm_cl37_advertisment(params);
3697
3698 /* program duplex & pause advertisement (for aneg) */
3699 bnx2x_set_ieee_aneg_advertisment(params,
3700 &vars->ieee_fc);
3701
3702 /* enable autoneg */
3703 bnx2x_set_autoneg(params, vars);
3704
3705 /* enable and restart AN */
3706 bnx2x_restart_autoneg(params);
3707 }
3708 3738
3709 } else { /* SGMII mode */ 3739 /* init ext phy and enable link state int */
3710 DP(NETIF_MSG_LINK, "SGMII\n"); 3740 non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
3711 3741 (params->loopback_mode == LOOPBACK_XGXS_10) ||
3712 bnx2x_initialize_sgmii_process(params); 3742 (params->loopback_mode == LOOPBACK_EXT_PHY));
3743
3744 if (non_ext_phy ||
3745 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) {
3746 if (params->req_line_speed == SPEED_AUTO_NEG)
3747 bnx2x_set_parallel_detection(params, vars->phy_flags);
3748 bnx2x_init_internal_phy(params, vars);
3713 } 3749 }
3714 3750
3715 /* init ext phy and enable link state int */ 3751 if (!non_ext_phy)
3716 rc |= bnx2x_ext_phy_init(params, vars); 3752 rc |= bnx2x_ext_phy_init(params, vars);
3717 3753
3718 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, 3754 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3719 (NIG_STATUS_XGXS0_LINK10G | 3755 (NIG_STATUS_XGXS0_LINK10G |
3720 NIG_STATUS_XGXS0_LINK_STATUS | 3756 NIG_STATUS_XGXS0_LINK_STATUS |
3721 NIG_STATUS_SERDES0_LINK_STATUS)); 3757 NIG_STATUS_SERDES0_LINK_STATUS));
3722 3758
3723 return rc; 3759 return rc;
3724 3760
@@ -3734,6 +3770,13 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
3734 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n", 3770 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
3735 params->req_line_speed, params->req_flow_ctrl); 3771 params->req_line_speed, params->req_flow_ctrl);
3736 vars->link_status = 0; 3772 vars->link_status = 0;
3773 vars->phy_link_up = 0;
3774 vars->link_up = 0;
3775 vars->line_speed = 0;
3776 vars->duplex = DUPLEX_FULL;
3777 vars->flow_ctrl = FLOW_CTRL_NONE;
3778 vars->mac_type = MAC_TYPE_NONE;
3779
3737 if (params->switch_cfg == SWITCH_CFG_1G) 3780 if (params->switch_cfg == SWITCH_CFG_1G)
3738 vars->phy_flags = PHY_SERDES_FLAG; 3781 vars->phy_flags = PHY_SERDES_FLAG;
3739 else 3782 else
@@ -3894,6 +3937,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
3894 } 3937 }
3895 3938
3896 bnx2x_link_initialize(params, vars); 3939 bnx2x_link_initialize(params, vars);
3940 msleep(30);
3897 bnx2x_link_int_enable(params); 3941 bnx2x_link_int_enable(params);
3898 } 3942 }
3899 return 0; 3943 return 0;
@@ -3949,33 +3993,13 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
3949 MISC_REGISTERS_GPIO_OUTPUT_LOW); 3993 MISC_REGISTERS_GPIO_OUTPUT_LOW);
3950 3994
3951 DP(NETIF_MSG_LINK, "reset external PHY\n"); 3995 DP(NETIF_MSG_LINK, "reset external PHY\n");
3952 } else { 3996 } else if (ext_phy_type ==
3953 3997 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3954 u8 ext_phy_addr = ((ext_phy_config & 3998 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
3955 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3956 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3957
3958 /* SW reset */
3959 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3960 MDIO_PMA_DEVAD,
3961 MDIO_PMA_REG_CTRL,
3962 1<<15);
3963
3964 /* Set Low Power Mode */
3965 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3966 MDIO_PMA_DEVAD,
3967 MDIO_PMA_REG_CTRL,
3968 1<<11);
3969
3970
3971 if (ext_phy_type ==
3972 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3973 DP(NETIF_MSG_LINK, "Setting 8073 port %d into"
3974 "low power mode\n", 3999 "low power mode\n",
3975 port); 4000 port);
3976 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 4001 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3977 MISC_REGISTERS_GPIO_OUTPUT_LOW); 4002 MISC_REGISTERS_GPIO_OUTPUT_LOW);
3978 }
3979 } 4003 }
3980 } 4004 }
3981 /* reset the SerDes/XGXS */ 4005 /* reset the SerDes/XGXS */
@@ -3995,6 +4019,73 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
3995 return 0; 4019 return 0;
3996} 4020}
3997 4021
4022static u8 bnx2x_update_link_down(struct link_params *params,
4023 struct link_vars *vars)
4024{
4025 struct bnx2x *bp = params->bp;
4026 u8 port = params->port;
4027 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4028 bnx2x_set_led(bp, port, LED_MODE_OFF,
4029 0, params->hw_led_mode,
4030 params->chip_id);
4031
4032 /* indicate no mac active */
4033 vars->mac_type = MAC_TYPE_NONE;
4034
4035 /* update shared memory */
4036 vars->link_status = 0;
4037 vars->line_speed = 0;
4038 bnx2x_update_mng(params, vars->link_status);
4039
4040 /* activate nig drain */
4041 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4042
4043 /* reset BigMac */
4044 bnx2x_bmac_rx_disable(bp, params->port);
4045 REG_WR(bp, GRCBASE_MISC +
4046 MISC_REGISTERS_RESET_REG_2_CLEAR,
4047 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4048 return 0;
4049}
4050
4051static u8 bnx2x_update_link_up(struct link_params *params,
4052 struct link_vars *vars,
4053 u8 link_10g, u32 gp_status)
4054{
4055 struct bnx2x *bp = params->bp;
4056 u8 port = params->port;
4057 u8 rc = 0;
4058 vars->link_status |= LINK_STATUS_LINK_UP;
4059 if (link_10g) {
4060 bnx2x_bmac_enable(params, vars, 0);
4061 bnx2x_set_led(bp, port, LED_MODE_OPER,
4062 SPEED_10000, params->hw_led_mode,
4063 params->chip_id);
4064
4065 } else {
4066 bnx2x_emac_enable(params, vars, 0);
4067 rc = bnx2x_emac_program(params, vars->line_speed,
4068 vars->duplex);
4069
4070 /* AN complete? */
4071 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4072 if (!(vars->phy_flags &
4073 PHY_SGMII_FLAG))
4074 bnx2x_set_sgmii_tx_driver(params);
4075 }
4076 }
4077
4078 /* PBF - link up */
4079 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4080 vars->line_speed);
4081
4082 /* disable drain */
4083 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4084
4085 /* update shared memory */
4086 bnx2x_update_mng(params, vars->link_status);
4087 return rc;
4088}
3998/* This function should called upon link interrupt */ 4089/* This function should called upon link interrupt */
3999/* In case vars->link_up, driver needs to 4090/* In case vars->link_up, driver needs to
4000 1. Update the pbf 4091 1. Update the pbf
@@ -4012,10 +4103,10 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4012{ 4103{
4013 struct bnx2x *bp = params->bp; 4104 struct bnx2x *bp = params->bp;
4014 u8 port = params->port; 4105 u8 port = params->port;
4015 u16 i;
4016 u16 gp_status; 4106 u16 gp_status;
4017 u16 link_10g; 4107 u8 link_10g;
4018 u8 rc = 0; 4108 u8 ext_phy_link_up, rc = 0;
4109 u32 ext_phy_type;
4019 4110
4020 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", 4111 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4021 port, 4112 port,
@@ -4031,15 +4122,16 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4031 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), 4122 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4032 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); 4123 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4033 4124
4125 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4034 4126
4035 /* avoid fast toggling */ 4127 /* Check external link change only for non-direct */
4036 for (i = 0; i < 10; i++) { 4128 ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4037 msleep(10); 4129
4038 CL45_RD_OVER_CL22(bp, port, params->phy_addr, 4130 /* Read gp_status */
4039 MDIO_REG_BANK_GP_STATUS, 4131 CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4040 MDIO_GP_STATUS_TOP_AN_STATUS1, 4132 MDIO_REG_BANK_GP_STATUS,
4041 &gp_status); 4133 MDIO_GP_STATUS_TOP_AN_STATUS1,
4042 } 4134 &gp_status);
4043 4135
4044 rc = bnx2x_link_settings_status(params, vars, gp_status); 4136 rc = bnx2x_link_settings_status(params, vars, gp_status);
4045 if (rc != 0) 4137 if (rc != 0)
@@ -4055,69 +4147,25 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4055 4147
4056 bnx2x_link_int_ack(params, vars, link_10g); 4148 bnx2x_link_int_ack(params, vars, link_10g);
4057 4149
4058 /* link is up only if both local phy and external phy are up */ 4150 /* In case external phy link is up, and internal link is down
4059 vars->link_up = (vars->phy_link_up && 4151 ( not initialized yet probably after link initialization, it needs
4060 bnx2x_ext_phy_is_link_up(params, vars)); 4152 to be initialized.
4061 4153 Note that after link down-up as result of cable plug,
4062 if (!vars->phy_link_up && 4154 the xgxs link would probably become up again without the need to
4063 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18)) { 4155 initialize it*/
4064 bnx2x_ext_phy_is_link_up(params, vars); /* Clear interrupt */
4065 }
4066
4067 if (vars->link_up) {
4068 vars->link_status |= LINK_STATUS_LINK_UP;
4069 if (link_10g) {
4070 bnx2x_bmac_enable(params, vars, 0);
4071 bnx2x_set_led(bp, port, LED_MODE_OPER,
4072 SPEED_10000, params->hw_led_mode,
4073 params->chip_id);
4074
4075 } else {
4076 bnx2x_emac_enable(params, vars, 0);
4077 rc = bnx2x_emac_program(params, vars->line_speed,
4078 vars->duplex);
4079
4080 /* AN complete? */
4081 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4082 if (!(vars->phy_flags &
4083 PHY_SGMII_FLAG))
4084 bnx2x_set_sgmii_tx_driver(params);
4085 }
4086 }
4087
4088 /* PBF - link up */
4089 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4090 vars->line_speed);
4091 4156
4092 /* disable drain */ 4157 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4093 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0); 4158 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4159 (ext_phy_link_up && !vars->phy_link_up))
4160 bnx2x_init_internal_phy(params, vars);
4094 4161
4095 /* update shared memory */ 4162 /* link is up only if both local phy and external phy are up */
4096 bnx2x_update_mng(params, vars->link_status); 4163 vars->link_up = (ext_phy_link_up && vars->phy_link_up);
4097
4098 } else { /* link down */
4099 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", params->port);
4100 bnx2x_set_led(bp, port, LED_MODE_OFF,
4101 0, params->hw_led_mode,
4102 params->chip_id);
4103
4104 /* indicate no mac active */
4105 vars->mac_type = MAC_TYPE_NONE;
4106
4107 /* update shared memory */
4108 vars->link_status = 0;
4109 bnx2x_update_mng(params, vars->link_status);
4110
4111 /* activate nig drain */
4112 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4113
4114 /* reset BigMac */
4115 bnx2x_bmac_rx_disable(bp, params->port);
4116 REG_WR(bp, GRCBASE_MISC +
4117 MISC_REGISTERS_RESET_REG_2_CLEAR,
4118 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4119 4164
4120 } 4165 if (vars->link_up)
4166 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
4167 else
4168 rc = bnx2x_update_link_down(params, vars);
4121 4169
4122 return rc; 4170 return rc;
4123} 4171}
@@ -4508,7 +4556,7 @@ u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
4508 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: 4556 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4509 /* Take ext phy out of reset */ 4557 /* Take ext phy out of reset */
4510 if (!driver_loaded) 4558 if (!driver_loaded)
4511 bnx2x_turn_on_sf(bp, port, ext_phy_addr); 4559 bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
4512 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr, 4560 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
4513 data, size); 4561 data, size);
4514 if (!driver_loaded) 4562 if (!driver_loaded)
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
index a85ff2073681..58fbeb1cf78d 100644
--- a/drivers/net/bnx2x_reg.h
+++ b/drivers/net/bnx2x_reg.h
@@ -5559,6 +5559,8 @@ Theotherbitsarereservedandshouldbezero*/
5559#define MDIO_PMA_REG_GEN_CTRL 0xca10 5559#define MDIO_PMA_REG_GEN_CTRL 0xca10
5560#define MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP 0x0188 5560#define MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP 0x0188
5561#define MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET 0x018a 5561#define MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET 0x018a
5562#define MDIO_PMA_REG_M8051_MSGIN_REG 0xca12
5563#define MDIO_PMA_REG_M8051_MSGOUT_REG 0xca13
5562#define MDIO_PMA_REG_ROM_VER1 0xca19 5564#define MDIO_PMA_REG_ROM_VER1 0xca19
5563#define MDIO_PMA_REG_ROM_VER2 0xca1a 5565#define MDIO_PMA_REG_ROM_VER2 0xca1a
5564#define MDIO_PMA_REG_EDC_FFE_MAIN 0xca1b 5566#define MDIO_PMA_REG_EDC_FFE_MAIN 0xca1b