bnx2x: Fix BCM84833 link and LED behavior

This patch contain several fixes for the BCM84833. This PHY is still not in bnx2x production, hence this patch can be considered as enhancement.

Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Yaniv Rosner 2011-11-28 00:49:48 +00:00 committed by David S. Miller
parent b76070b405
commit 521683da84
2 changed files with 230 additions and 191 deletions
drivers/net/ethernet/broadcom/bnx2x

View file

@ -4055,13 +4055,11 @@ static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy, static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
struct link_params *params, struct link_params *params,
u8 fiber_mode) u8 fiber_mode,
u8 always_autoneg)
{ {
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
u16 val16, digctrl_kx1, digctrl_kx2; u16 val16, digctrl_kx1, digctrl_kx2;
u8 lane;
lane = bnx2x_get_warpcore_lane(phy, params);
/* Clear XFI clock comp in non-10G single lane mode. */ /* Clear XFI clock comp in non-10G single lane mode. */
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
@ -4069,7 +4067,7 @@ static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13)); MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13));
if (phy->req_line_speed == SPEED_AUTO_NEG) { if (always_autoneg || phy->req_line_speed == SPEED_AUTO_NEG) {
/* SGMII Autoneg */ /* SGMII Autoneg */
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
@ -4080,7 +4078,7 @@ static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
} else { } else {
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
val16 &= 0xcfbf; val16 &= 0xcebf;
switch (phy->req_line_speed) { switch (phy->req_line_speed) {
case SPEED_10: case SPEED_10:
break; break;
@ -4363,7 +4361,7 @@ static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
vars->phy_flags |= PHY_SGMII_FLAG; vars->phy_flags |= PHY_SGMII_FLAG;
DP(NETIF_MSG_LINK, "Setting SGMII mode\n"); DP(NETIF_MSG_LINK, "Setting SGMII mode\n");
bnx2x_warpcore_clear_regs(phy, params, lane); bnx2x_warpcore_clear_regs(phy, params, lane);
bnx2x_warpcore_set_sgmii_speed(phy, params, 0); bnx2x_warpcore_set_sgmii_speed(phy, params, 0, 1);
} else { } else {
switch (serdes_net_if) { switch (serdes_net_if) {
case PORT_HW_CFG_NET_SERDES_IF_KR: case PORT_HW_CFG_NET_SERDES_IF_KR:
@ -4391,7 +4389,8 @@ static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
} }
bnx2x_warpcore_set_sgmii_speed(phy, bnx2x_warpcore_set_sgmii_speed(phy,
params, params,
fiber_mode); fiber_mode,
0);
} }
break; break;
@ -4404,7 +4403,8 @@ static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
bnx2x_warpcore_set_10G_XFI(phy, params, 0); bnx2x_warpcore_set_10G_XFI(phy, params, 0);
} else if (vars->line_speed == SPEED_1000) { } else if (vars->line_speed == SPEED_1000) {
DP(NETIF_MSG_LINK, "Setting 1G Fiber\n"); DP(NETIF_MSG_LINK, "Setting 1G Fiber\n");
bnx2x_warpcore_set_sgmii_speed(phy, params, 1); bnx2x_warpcore_set_sgmii_speed(
phy, params, 1, 0);
} }
/* Issue Module detection */ /* Issue Module detection */
if (bnx2x_is_sfp_module_plugged(phy, params)) if (bnx2x_is_sfp_module_plugged(phy, params))
@ -4541,12 +4541,6 @@ static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy,
/* Switch back to 4-copy registers */ /* Switch back to 4-copy registers */
bnx2x_set_aer_mmd(params, phy); bnx2x_set_aer_mmd(params, phy);
/* Global loopback, not recommended. */
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
0x4000);
} else { } else {
/* 10G & 20G */ /* 10G & 20G */
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
@ -9349,7 +9343,7 @@ static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
static void bnx2x_848xx_set_led(struct bnx2x *bp, static void bnx2x_848xx_set_led(struct bnx2x *bp,
struct bnx2x_phy *phy) struct bnx2x_phy *phy)
{ {
u16 val; u16 val, offset;
/* PHYC_CTL_LED_CTL */ /* PHYC_CTL_LED_CTL */
bnx2x_cl45_read(bp, phy, bnx2x_cl45_read(bp, phy,
@ -9384,14 +9378,22 @@ static void bnx2x_848xx_set_led(struct bnx2x *bp,
MDIO_PMA_REG_8481_LED3_BLINK, MDIO_PMA_REG_8481_LED3_BLINK,
0); 0);
bnx2x_cl45_read(bp, phy, /* Configure the blink rate to ~15.9 Hz */
MDIO_PMA_DEVAD,
MDIO_PMA_REG_84823_CTL_LED_CTL_1, &val);
val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
bnx2x_cl45_write(bp, phy, bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD, MDIO_PMA_DEVAD,
MDIO_PMA_REG_84823_CTL_LED_CTL_1, val); MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH,
MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ);
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
offset = MDIO_PMA_REG_84833_CTL_LED_CTL_1;
else
offset = MDIO_PMA_REG_84823_CTL_LED_CTL_1;
bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD, offset, &val);
val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD, offset, val);
/* 'Interrupt Mask' */ /* 'Interrupt Mask' */
bnx2x_cl45_write(bp, phy, bnx2x_cl45_write(bp, phy,
@ -9404,7 +9406,7 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
struct link_vars *vars) struct link_vars *vars)
{ {
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
u16 autoneg_val, an_1000_val, an_10_100_val; u16 autoneg_val, an_1000_val, an_10_100_val, an_10g_val;
u16 tmp_req_line_speed; u16 tmp_req_line_speed;
tmp_req_line_speed = phy->req_line_speed; tmp_req_line_speed = phy->req_line_speed;
@ -9499,6 +9501,8 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
bnx2x_cl45_write(bp, phy, bnx2x_cl45_write(bp, phy,
MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL, MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
(1<<15 | 1<<9 | 7<<0)); (1<<15 | 1<<9 | 7<<0));
/* The PHY needs this set even for forced link. */
an_10_100_val |= (1<<8) | (1<<7);
DP(NETIF_MSG_LINK, "Setting 100M force\n"); DP(NETIF_MSG_LINK, "Setting 100M force\n");
} }
if ((phy->req_line_speed == SPEED_10) && if ((phy->req_line_speed == SPEED_10) &&
@ -9536,9 +9540,17 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
DP(NETIF_MSG_LINK, "Advertising 10G\n"); DP(NETIF_MSG_LINK, "Advertising 10G\n");
/* Restart autoneg for 10G*/ /* Restart autoneg for 10G*/
bnx2x_cl45_read(bp, phy,
MDIO_AN_DEVAD,
MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
&an_10g_val);
bnx2x_cl45_write(bp, phy, bnx2x_cl45_write(bp, phy,
MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, MDIO_AN_DEVAD,
0x3200); MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
an_10g_val | 0x1000);
bnx2x_cl45_write(bp, phy,
MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
0x3200);
} else } else
bnx2x_cl45_write(bp, phy, bnx2x_cl45_write(bp, phy,
MDIO_AN_DEVAD, MDIO_AN_DEVAD,
@ -9570,18 +9582,74 @@ static int bnx2x_8481_config_init(struct bnx2x_phy *phy,
return bnx2x_848xx_cmn_config_init(phy, params, vars); return bnx2x_848xx_cmn_config_init(phy, params, vars);
} }
#define PHY84833_CMDHDLR_WAIT 300
#define PHY84833_CMDHDLR_MAX_ARGS 5
static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy,
struct link_params *params,
u16 fw_cmd,
u16 cmd_args[])
{
u32 idx;
u16 val;
struct bnx2x *bp = params->bp;
/* Write CMD_OPEN_OVERRIDE to STATUS reg */
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_CMD_HDLR_STATUS,
PHY84833_STATUS_CMD_OPEN_OVERRIDE);
for (idx = 0; idx < PHY84833_CMDHDLR_WAIT; idx++) {
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_CMD_HDLR_STATUS, &val);
if (val == PHY84833_STATUS_CMD_OPEN_FOR_CMDS)
break;
msleep(1);
}
if (idx >= PHY84833_CMDHDLR_WAIT) {
DP(NETIF_MSG_LINK, "FW cmd: FW not ready.\n");
return -EINVAL;
}
/* Prepare argument(s) and issue command */
for (idx = 0; idx < PHY84833_CMDHDLR_MAX_ARGS; idx++) {
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_CMD_HDLR_DATA1 + idx,
cmd_args[idx]);
}
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_CMD_HDLR_COMMAND, fw_cmd);
for (idx = 0; idx < PHY84833_CMDHDLR_WAIT; idx++) {
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_CMD_HDLR_STATUS, &val);
if ((val == PHY84833_STATUS_CMD_COMPLETE_PASS) ||
(val == PHY84833_STATUS_CMD_COMPLETE_ERROR))
break;
msleep(1);
}
if ((idx >= PHY84833_CMDHDLR_WAIT) ||
(val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) {
DP(NETIF_MSG_LINK, "FW cmd failed.\n");
return -EINVAL;
}
/* Gather returning data */
for (idx = 0; idx < PHY84833_CMDHDLR_MAX_ARGS; idx++) {
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_CMD_HDLR_DATA1 + idx,
&cmd_args[idx]);
}
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_CMD_HDLR_STATUS,
PHY84833_STATUS_CMD_CLEAR_COMPLETE);
return 0;
}
#define PHY84833_HDSHK_WAIT 300
static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy, static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy,
struct link_params *params, struct link_params *params,
struct link_vars *vars) struct link_vars *vars)
{ {
u32 idx;
u32 pair_swap; u32 pair_swap;
u16 val; u16 data[PHY84833_CMDHDLR_MAX_ARGS];
u16 data; int status;
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
/* Do pair swap */
/* Check for configuration. */ /* Check for configuration. */
pair_swap = REG_RD(bp, params->shmem_base + pair_swap = REG_RD(bp, params->shmem_base +
@ -9592,52 +9660,17 @@ static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy,
if (pair_swap == 0) if (pair_swap == 0)
return 0; return 0;
data = (u16)pair_swap; /* Only the second argument is used for this command */
data[1] = (u16)pair_swap;
/* Write CMD_OPEN_OVERRIDE to STATUS reg */ status = bnx2x_84833_cmd_hdlr(phy, params,
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, PHY84833_CMD_SET_PAIR_SWAP, data);
MDIO_84833_TOP_CFG_SCRATCH_REG2, if (status == 0)
PHY84833_CMD_OPEN_OVERRIDE); DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]);
for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
if (val == PHY84833_CMD_OPEN_FOR_CMDS)
break;
msleep(1);
}
if (idx >= PHY84833_HDSHK_WAIT) {
DP(NETIF_MSG_LINK, "Pairswap: FW not ready.\n");
return -EINVAL;
}
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, return status;
MDIO_84833_TOP_CFG_SCRATCH_REG4,
data);
/* Issue pair swap command */
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_TOP_CFG_SCRATCH_REG0,
PHY84833_DIAG_CMD_PAIR_SWAP_CHANGE);
for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
if ((val == PHY84833_CMD_COMPLETE_PASS) ||
(val == PHY84833_CMD_COMPLETE_ERROR))
break;
msleep(1);
}
if ((idx >= PHY84833_HDSHK_WAIT) ||
(val == PHY84833_CMD_COMPLETE_ERROR)) {
DP(NETIF_MSG_LINK, "Pairswap: override failed.\n");
return -EINVAL;
}
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_TOP_CFG_SCRATCH_REG2,
PHY84833_CMD_CLEAR_COMPLETE);
DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data);
return 0;
} }
static u8 bnx2x_84833_get_reset_gpios(struct bnx2x *bp, static u8 bnx2x_84833_get_reset_gpios(struct bnx2x *bp,
u32 shmem_base_path[], u32 shmem_base_path[],
u32 chip_id) u32 chip_id)
@ -9700,24 +9733,6 @@ static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy,
return 0; return 0;
} }
static int bnx2x_84833_common_init_phy(struct bnx2x *bp,
u32 shmem_base_path[],
u32 chip_id)
{
u8 reset_gpios;
reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, chip_id);
bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
udelay(10);
bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH);
msleep(800);
DP(NETIF_MSG_LINK, "84833 reset pulse on pin values 0x%x\n",
reset_gpios);
return 0;
}
#define PHY84833_CONSTANT_LATENCY 1193 #define PHY84833_CONSTANT_LATENCY 1193
static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
struct link_params *params, struct link_params *params,
@ -9726,8 +9741,8 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
u8 port, initialize = 1; u8 port, initialize = 1;
u16 val; u16 val;
u16 temp; u32 actual_phy_selection, cms_enable;
u32 actual_phy_selection, cms_enable, idx; u16 cmd_args[PHY84833_CMDHDLR_MAX_ARGS];
int rc = 0; int rc = 0;
msleep(1); msleep(1);
@ -9746,6 +9761,13 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
bnx2x_cl45_write(bp, phy, bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD, MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL, 0x8000); MDIO_PMA_REG_CTRL, 0x8000);
}
bnx2x_wait_reset_complete(bp, phy, params);
/* Wait for GPHY to come out of reset */
msleep(50);
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
/* Bring PHY out of super isolate mode */ /* Bring PHY out of super isolate mode */
bnx2x_cl45_read(bp, phy, bnx2x_cl45_read(bp, phy,
MDIO_CTL_DEVAD, MDIO_CTL_DEVAD,
@ -9754,26 +9776,19 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
bnx2x_cl45_write(bp, phy, bnx2x_cl45_write(bp, phy,
MDIO_CTL_DEVAD, MDIO_CTL_DEVAD,
MDIO_84833_TOP_CFG_XGPHY_STRAP1, val); MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
}
bnx2x_wait_reset_complete(bp, phy, params);
/* Wait for GPHY to come out of reset */
msleep(50);
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
bnx2x_84833_pair_swap_cfg(phy, params, vars); bnx2x_84833_pair_swap_cfg(phy, params, vars);
} else {
/* /*
* BCM84823 requires that XGXS links up first @ 10G for normal behavior * BCM84823 requires that XGXS links up first @ 10G for normal
*/ * behavior.
temp = vars->line_speed; */
vars->line_speed = SPEED_10000; u16 temp;
bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0); temp = vars->line_speed;
bnx2x_program_serdes(&params->phy[INT_PHY], params, vars); vars->line_speed = SPEED_10000;
vars->line_speed = temp; bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0);
bnx2x_program_serdes(&params->phy[INT_PHY], params, vars);
/* Set dual-media configuration according to configuration */ vars->line_speed = temp;
}
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
MDIO_CTL_REG_84823_MEDIA, &val); MDIO_CTL_REG_84823_MEDIA, &val);
@ -9821,64 +9836,18 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
/* AutogrEEEn */ /* AutogrEEEn */
if (params->feature_config_flags & if (params->feature_config_flags &
FEATURE_CONFIG_AUTOGREEEN_ENABLED) { FEATURE_CONFIG_AUTOGREEEN_ENABLED)
/* Ensure that f/w is ready */ cmd_args[0] = 0x2;
for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) { else
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, cmd_args[0] = 0x0;
MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
if (val == PHY84833_CMD_OPEN_FOR_CMDS)
break;
usleep_range(1000, 1000);
}
if (idx >= PHY84833_HDSHK_WAIT) {
DP(NETIF_MSG_LINK, "AutogrEEEn: FW not ready.\n");
return -EINVAL;
}
/* Select EEE mode */
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_TOP_CFG_SCRATCH_REG3,
0x2);
/* Set Idle and Latency */
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_TOP_CFG_SCRATCH_REG4,
PHY84833_CONSTANT_LATENCY + 1);
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_TOP_CFG_DATA3_REG,
PHY84833_CONSTANT_LATENCY + 1);
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_TOP_CFG_DATA4_REG,
PHY84833_CONSTANT_LATENCY);
/* Send EEE instruction to command register */
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_TOP_CFG_SCRATCH_REG0,
PHY84833_DIAG_CMD_SET_EEE_MODE);
/* Ensure that the command has completed */
for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
if ((val == PHY84833_CMD_COMPLETE_PASS) ||
(val == PHY84833_CMD_COMPLETE_ERROR))
break;
usleep_range(1000, 1000);
}
if ((idx >= PHY84833_HDSHK_WAIT) ||
(val == PHY84833_CMD_COMPLETE_ERROR)) {
DP(NETIF_MSG_LINK, "AutogrEEEn: command failed.\n");
return -EINVAL;
}
/* Reset command handler */
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
MDIO_84833_TOP_CFG_SCRATCH_REG2,
PHY84833_CMD_CLEAR_COMPLETE);
}
cmd_args[1] = 0x0;
cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1;
cmd_args[3] = PHY84833_CONSTANT_LATENCY;
rc = bnx2x_84833_cmd_hdlr(phy, params,
PHY84833_CMD_SET_EEE_MODE, cmd_args);
if (rc != 0)
DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n");
if (initialize) if (initialize)
rc = bnx2x_848xx_cmn_config_init(phy, params, vars); rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
else else
@ -12368,6 +12337,63 @@ static int bnx2x_8727_common_init_phy(struct bnx2x *bp,
return 0; return 0;
} }
static int bnx2x_84833_common_init_phy(struct bnx2x *bp,
u32 shmem_base_path[],
u32 shmem2_base_path[],
u8 phy_index,
u32 chip_id)
{
u8 reset_gpios;
struct bnx2x_phy phy;
u32 shmem_base, shmem2_base, cnt;
s8 port = 0;
u16 val;
reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, chip_id);
bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
udelay(10);
bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH);
DP(NETIF_MSG_LINK, "84833 reset pulse on pin values 0x%x\n",
reset_gpios);
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
/* This PHY is for E2 and E3. */
shmem_base = shmem_base_path[port];
shmem2_base = shmem2_base_path[port];
/* Extract the ext phy address for the port */
if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
0, &phy) !=
0) {
DP(NETIF_MSG_LINK, "populate_phy failed\n");
return -EINVAL;
}
/* Wait for FW completing its initialization. */
for (cnt = 0; cnt < 1000; cnt++) {
bnx2x_cl45_read(bp, &phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL, &val);
if (!(val & (1<<15)))
break;
msleep(1);
}
if (cnt >= 1000)
DP(NETIF_MSG_LINK,
"84833 Cmn reset timeout (%d)\n", port);
/* Put the port in super isolate mode. */
bnx2x_cl45_read(bp, &phy,
MDIO_CTL_DEVAD,
MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
val |= MDIO_84833_SUPER_ISOLATE;
bnx2x_cl45_write(bp, &phy,
MDIO_CTL_DEVAD,
MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
}
return 0;
}
static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
u32 shmem2_base_path[], u8 phy_index, u32 shmem2_base_path[], u8 phy_index,
u32 ext_phy_type, u32 chip_id) u32 ext_phy_type, u32 chip_id)
@ -12402,7 +12428,9 @@ static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
* GPIO3's are linked, and so both need to be toggled * GPIO3's are linked, and so both need to be toggled
* to obtain required 2us pulse. * to obtain required 2us pulse.
*/ */
rc = bnx2x_84833_common_init_phy(bp, shmem_base_path, chip_id); rc = bnx2x_84833_common_init_phy(bp, shmem_base_path,
shmem2_base_path,
phy_index, chip_id);
break; break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
rc = -EINVAL; rc = -EINVAL;

View file

@ -6835,11 +6835,13 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER 0x0000 #define MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER 0x0000
#define MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER 0x0100 #define MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER 0x0100
#define MDIO_CTL_REG_84823_MEDIA_FIBER_1G 0x1000 #define MDIO_CTL_REG_84823_MEDIA_FIBER_1G 0x1000
#define MDIO_CTL_REG_84823_USER_CTRL_REG 0x4005 #define MDIO_CTL_REG_84823_USER_CTRL_REG 0x4005
#define MDIO_CTL_REG_84823_USER_CTRL_CMS 0x0080 #define MDIO_CTL_REG_84823_USER_CTRL_CMS 0x0080
#define MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH 0xa82b
#define MDIO_PMA_REG_84823_CTL_LED_CTL_1 0xa8e3 #define MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ 0x2f
#define MDIO_PMA_REG_84823_LED3_STRETCH_EN 0x0080 #define MDIO_PMA_REG_84823_CTL_LED_CTL_1 0xa8e3
#define MDIO_PMA_REG_84833_CTL_LED_CTL_1 0xa8ec
#define MDIO_PMA_REG_84823_LED3_STRETCH_EN 0x0080
/* BCM84833 only */ /* BCM84833 only */
#define MDIO_84833_TOP_CFG_XGPHY_STRAP1 0x401a #define MDIO_84833_TOP_CFG_XGPHY_STRAP1 0x401a
@ -6850,27 +6852,36 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_84833_TOP_CFG_SCRATCH_REG2 0x4007 #define MDIO_84833_TOP_CFG_SCRATCH_REG2 0x4007
#define MDIO_84833_TOP_CFG_SCRATCH_REG3 0x4008 #define MDIO_84833_TOP_CFG_SCRATCH_REG3 0x4008
#define MDIO_84833_TOP_CFG_SCRATCH_REG4 0x4009 #define MDIO_84833_TOP_CFG_SCRATCH_REG4 0x4009
#define MDIO_84833_TOP_CFG_DATA3_REG 0x4011 #define MDIO_84833_TOP_CFG_SCRATCH_REG26 0x4037
#define MDIO_84833_TOP_CFG_DATA4_REG 0x4012 #define MDIO_84833_TOP_CFG_SCRATCH_REG27 0x4038
#define MDIO_84833_TOP_CFG_SCRATCH_REG28 0x4039
#define MDIO_84833_TOP_CFG_SCRATCH_REG29 0x403a
#define MDIO_84833_TOP_CFG_SCRATCH_REG30 0x403b
#define MDIO_84833_TOP_CFG_SCRATCH_REG31 0x403c
#define MDIO_84833_CMD_HDLR_COMMAND MDIO_84833_TOP_CFG_SCRATCH_REG0
#define MDIO_84833_CMD_HDLR_STATUS MDIO_84833_TOP_CFG_SCRATCH_REG26
#define MDIO_84833_CMD_HDLR_DATA1 MDIO_84833_TOP_CFG_SCRATCH_REG27
#define MDIO_84833_CMD_HDLR_DATA2 MDIO_84833_TOP_CFG_SCRATCH_REG28
#define MDIO_84833_CMD_HDLR_DATA3 MDIO_84833_TOP_CFG_SCRATCH_REG29
#define MDIO_84833_CMD_HDLR_DATA4 MDIO_84833_TOP_CFG_SCRATCH_REG30
#define MDIO_84833_CMD_HDLR_DATA5 MDIO_84833_TOP_CFG_SCRATCH_REG31
/* Mailbox command set used by 84833. */ /* Mailbox command set used by 84833. */
#define PHY84833_DIAG_CMD_PAIR_SWAP_CHANGE 0x2 #define PHY84833_CMD_SET_PAIR_SWAP 0x8001
#define PHY84833_CMD_GET_EEE_MODE 0x8008
#define PHY84833_CMD_SET_EEE_MODE 0x8009
/* Mailbox status set used by 84833. */ /* Mailbox status set used by 84833. */
#define PHY84833_CMD_RECEIVED 0x0001 #define PHY84833_STATUS_CMD_RECEIVED 0x0001
#define PHY84833_CMD_IN_PROGRESS 0x0002 #define PHY84833_STATUS_CMD_IN_PROGRESS 0x0002
#define PHY84833_CMD_COMPLETE_PASS 0x0004 #define PHY84833_STATUS_CMD_COMPLETE_PASS 0x0004
#define PHY84833_CMD_COMPLETE_ERROR 0x0008 #define PHY84833_STATUS_CMD_COMPLETE_ERROR 0x0008
#define PHY84833_CMD_OPEN_FOR_CMDS 0x0010 #define PHY84833_STATUS_CMD_OPEN_FOR_CMDS 0x0010
#define PHY84833_CMD_SYSTEM_BOOT 0x0020 #define PHY84833_STATUS_CMD_SYSTEM_BOOT 0x0020
#define PHY84833_CMD_NOT_OPEN_FOR_CMDS 0x0040 #define PHY84833_STATUS_CMD_NOT_OPEN_FOR_CMDS 0x0040
#define PHY84833_CMD_CLEAR_COMPLETE 0x0080 #define PHY84833_STATUS_CMD_CLEAR_COMPLETE 0x0080
#define PHY84833_CMD_OPEN_OVERRIDE 0xa5a5 #define PHY84833_STATUS_CMD_OPEN_OVERRIDE 0xa5a5
/* 84833 F/W Feature Commands */
#define PHY84833_DIAG_CMD_GET_EEE_MODE 0x27
#define PHY84833_DIAG_CMD_SET_EEE_MODE 0x28
/* Warpcore clause 45 addressing */ /* Warpcore clause 45 addressing */
#define MDIO_WC_DEVAD 0x3 #define MDIO_WC_DEVAD 0x3
#define MDIO_WC_REG_IEEE0BLK_MIICNTL 0x0 #define MDIO_WC_REG_IEEE0BLK_MIICNTL 0x0