bnx2x: Change BCM848xx configuration according to IEEE

Change BCM848xx behavior to fit IEEE such that setting 10Mb/100Mb will
use force speed, and setting 1Gb/10Gb will use auto-negotiation with the
specific speed advertised

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 2010-09-01 09:51:25 +00:00 committed by David S. Miller
parent 54c2fb7859
commit ac4d944910
2 changed files with 132 additions and 169 deletions

View File

@ -4354,34 +4354,49 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
}
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
{
/* This phy uses the NIG latch mechanism since link
indication arrives through its LED4 and not via
its LASI signal, so we get steady signal
instead of clear on read */
u16 autoneg_val, an_1000_val, an_10_100_val;
bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
1 << NIG_LATCH_BC_ENABLE_MI_INT);
bnx2x_cl45_write(bp, params->port,
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
ext_phy_type,
ext_phy_addr,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL, 0x0000);
bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr);
if (params->req_line_speed == SPEED_AUTO_NEG) {
u16 autoneg_val, an_1000_val, an_10_100_val;
/* set 1000 speed advertisement */
bnx2x_cl45_read(bp, params->port,
ext_phy_type,
ext_phy_addr,
MDIO_AN_DEVAD,
MDIO_AN_REG_8481_1000T_CTRL,
&an_1000_val);
bnx2x_ext_phy_set_pause(params, vars);
bnx2x_cl45_read(bp, params->port, ext_phy_type,
ext_phy_addr, MDIO_AN_DEVAD,
MDIO_AN_REG_8481_LEGACY_AN_ADV,
&an_10_100_val);
bnx2x_cl45_read(bp, params->port, ext_phy_type,
ext_phy_addr, MDIO_AN_DEVAD,
MDIO_AN_REG_8481_LEGACY_MII_CTRL,
&autoneg_val);
/* Disable forced speed */
autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) |
(1<<13));
an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
if (params->speed_cap_mask &
PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
if (((params->req_line_speed == SPEED_AUTO_NEG) &&
(params->speed_cap_mask &
PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
(params->req_line_speed == SPEED_1000)) {
an_1000_val |= (1<<8);
autoneg_val |= (1<<9 | 1<<12);
if (params->req_duplex == DUPLEX_FULL)
an_1000_val |= (1<<9);
DP(NETIF_MSG_LINK, "Advertising 1G\n");
@ -4395,36 +4410,56 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
MDIO_AN_REG_8481_1000T_CTRL,
an_1000_val);
/* set 100 speed advertisement */
bnx2x_cl45_read(bp, params->port,
ext_phy_type,
ext_phy_addr,
MDIO_AN_DEVAD,
MDIO_AN_REG_8481_LEGACY_AN_ADV,
&an_10_100_val);
if (params->speed_cap_mask &
/* set 10 speed advertisement */
if (((params->req_line_speed == SPEED_AUTO_NEG) &&
(params->speed_cap_mask &
(PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) {
PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
an_10_100_val |= (1<<7);
/*
* Enable autoneg and restart autoneg for
* legacy speeds
*/
autoneg_val |= (1<<9 | 1<<12);
if (params->req_duplex == DUPLEX_FULL)
an_10_100_val |= (1<<8);
DP(NETIF_MSG_LINK,
"Advertising 100M\n");
} else
an_10_100_val &= ~((1<<7) | (1<<8));
DP(NETIF_MSG_LINK, "Advertising 100M\n");
}
/* set 10 speed advertisement */
if (params->speed_cap_mask &
if (((params->req_line_speed == SPEED_AUTO_NEG) &&
(params->speed_cap_mask &
(PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) {
PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
an_10_100_val |= (1<<5);
autoneg_val |= (1<<9 | 1<<12);
if (params->req_duplex == DUPLEX_FULL)
an_10_100_val |= (1<<6);
DP(NETIF_MSG_LINK, "Advertising 10M\n");
}
else
an_10_100_val &= ~((1<<5) | (1<<6));
/* Only 10/100 are allowed to work in FORCE mode */
if (params->req_line_speed == SPEED_100) {
autoneg_val |= (1<<13);
/* Enabled AUTO-MDIX when autoneg is disabled */
bnx2x_cl45_write(bp, params->port,
ext_phy_type,
ext_phy_addr,
MDIO_AN_DEVAD,
MDIO_AN_REG_8481_AUX_CTRL,
(1<<15 | 1<<9 | 7<<0));
DP(NETIF_MSG_LINK, "Setting 100M force\n");
}
if (params->req_line_speed == SPEED_10) {
/* Enabled AUTO-MDIX when autoneg is disabled */
bnx2x_cl45_write(bp, params->port,
ext_phy_type,
ext_phy_addr,
MDIO_AN_DEVAD,
MDIO_AN_REG_8481_AUX_CTRL,
(1<<15 | 1<<9 | 7<<0));
DP(NETIF_MSG_LINK, "Setting 10M force\n");
}
bnx2x_cl45_write(bp, params->port,
ext_phy_type,
@ -4433,24 +4468,8 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
MDIO_AN_REG_8481_LEGACY_AN_ADV,
an_10_100_val);
bnx2x_cl45_read(bp, params->port,
ext_phy_type,
ext_phy_addr,
MDIO_AN_DEVAD,
MDIO_AN_REG_8481_LEGACY_MII_CTRL,
&autoneg_val);
/* Disable forced speed */
autoneg_val &= ~(1<<6|1<<13);
/* Enable autoneg and restart autoneg
for legacy speeds */
autoneg_val |= (1<<9|1<<12);
if (params->req_duplex == DUPLEX_FULL)
autoneg_val |= (1<<8);
else
autoneg_val &= ~(1<<8);
bnx2x_cl45_write(bp, params->port,
ext_phy_type,
@ -4459,8 +4478,10 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
MDIO_AN_REG_8481_LEGACY_MII_CTRL,
autoneg_val);
if (params->speed_cap_mask &
PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
if (((params->req_line_speed == SPEED_AUTO_NEG) &&
(params->speed_cap_mask &
PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
(params->req_line_speed == SPEED_10000)) {
DP(NETIF_MSG_LINK, "Advertising 10G\n");
/* Restart autoneg for 10G*/
@ -4468,83 +4489,24 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
ext_phy_type,
ext_phy_addr,
MDIO_AN_DEVAD,
MDIO_AN_REG_CTRL, 0x3200);
}
} else {
/* Force speed */
u16 autoneg_ctrl, pma_ctrl;
bnx2x_cl45_read(bp, params->port,
ext_phy_type,
ext_phy_addr,
MDIO_AN_DEVAD,
MDIO_AN_REG_8481_LEGACY_MII_CTRL,
&autoneg_ctrl);
MDIO_AN_REG_CTRL,
0x3200);
/* Disable autoneg */
autoneg_ctrl &= ~(1<<12);
/* Set 1000 force */
switch (params->req_line_speed) {
case SPEED_10000:
DP(NETIF_MSG_LINK,
"Unable to set 10G force !\n");
break;
case SPEED_1000:
bnx2x_cl45_read(bp, params->port,
ext_phy_type,
ext_phy_addr,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL,
&pma_ctrl);
autoneg_ctrl &= ~(1<<13);
autoneg_ctrl |= (1<<6);
pma_ctrl &= ~(1<<13);
pma_ctrl |= (1<<6);
DP(NETIF_MSG_LINK,
"Setting 1000M force\n");
bnx2x_cl45_write(bp, params->port,
ext_phy_type,
ext_phy_addr,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL,
pma_ctrl);
break;
case SPEED_100:
autoneg_ctrl |= (1<<13);
autoneg_ctrl &= ~(1<<6);
DP(NETIF_MSG_LINK,
"Setting 100M force\n");
break;
case SPEED_10:
autoneg_ctrl &= ~(1<<13);
autoneg_ctrl &= ~(1<<6);
DP(NETIF_MSG_LINK,
"Setting 10M force\n");
break;
}
/* Duplex mode */
if (params->req_duplex == DUPLEX_FULL) {
autoneg_ctrl |= (1<<8);
DP(NETIF_MSG_LINK,
"Setting full duplex\n");
} else
autoneg_ctrl &= ~(1<<8);
/* Update autoneg ctrl and pma ctrl */
} else if (params->req_line_speed != SPEED_10 &&
params->req_line_speed != SPEED_100)
bnx2x_cl45_write(bp, params->port,
ext_phy_type,
ext_phy_addr,
MDIO_AN_DEVAD,
MDIO_AN_REG_8481_LEGACY_MII_CTRL,
autoneg_ctrl);
}
MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
1);
/* Save spirom version */
bnx2x_save_8481_spirom_version(bp, params->port,
ext_phy_addr,
params->shmem_base);
break;
}
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
DP(NETIF_MSG_LINK,
"XGXS PHY Failure detected 0x%x\n",

View File

@ -5212,12 +5212,13 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_AN_REG_8073_2_5G 0x8329
#define MDIO_AN_REG_8727_MISC_CTRL 0x8309
#define MDIO_AN_REG_8481_10GBASE_T_AN_CTRL 0x0020
#define MDIO_AN_REG_8481_LEGACY_MII_CTRL 0xffe0
#define MDIO_AN_REG_8481_LEGACY_AN_ADV 0xffe4
#define MDIO_AN_REG_8481_1000T_CTRL 0xffe9
#define MDIO_AN_REG_8481_EXPANSION_REG_RD_RW 0xfff5
#define MDIO_AN_REG_8481_EXPANSION_REG_ACCESS 0xfff7
#define MDIO_AN_REG_8481_AUX_CTRL 0xfff8
#define MDIO_AN_REG_8481_LEGACY_SHADOW 0xfffc
#define IGU_FUNC_BASE 0x0400