Commit 589abe3a authored by Eilon Greenstein's avatar Eilon Greenstein Committed by David S. Miller

bnx2x: Supporting BCM8726 PHY

Also adding the ability to recognize the optic module and disable it if it is
not authorized for safety reasons - since this feature might upset some users
which are willing to take the risk, it is optional and can be disabled by
setting an nvram bit (or a trivial driver patch to set this bit).
This dual port PHY requires special handling if the ports are swapped.
Signed-off-by: default avatarYaniv Rosner <yanivr@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4acac6a5
...@@ -245,7 +245,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ ...@@ -245,7 +245,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073 0x00000300 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073 0x00000300
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705 0x00000400 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705 0x00000400
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706 0x00000500 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706 0x00000500
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8276 0x00000600 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726 0x00000600
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481 0x00000700 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481 0x00000700
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101 0x00000800 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101 0x00000800
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00
...@@ -299,6 +299,12 @@ struct shared_feat_cfg { /* NVRAM Offset */ ...@@ -299,6 +299,12 @@ struct shared_feat_cfg { /* NVRAM Offset */
u32 config; /* 0x450 */ u32 config; /* 0x450 */
#define SHARED_FEATURE_BMC_ECHO_MODE_EN 0x00000001 #define SHARED_FEATURE_BMC_ECHO_MODE_EN 0x00000001
/* Use the values from options 47 and 48 instead of the HW default
values */
#define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_DISABLED 0x00000000
#define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED 0x00000002
#define SHARED_FEATURE_MF_MODE_DISABLED 0x00000100 #define SHARED_FEATURE_MF_MODE_DISABLED 0x00000100
}; };
...@@ -352,6 +358,11 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */ ...@@ -352,6 +358,11 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */
#define PORT_FEATURE_MBA_ENABLED 0x02000000 #define PORT_FEATURE_MBA_ENABLED 0x02000000
#define PORT_FEATURE_MFW_ENABLED 0x04000000 #define PORT_FEATURE_MFW_ENABLED 0x04000000
/* Check the optic vendor via i2c before allowing it to be used by
SW */
#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLED 0x00000000
#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_ENABLED 0x08000000
u32 wol_config; u32 wol_config;
/* Default is used when driver sets to "auto" mode */ /* Default is used when driver sets to "auto" mode */
#define PORT_FEATURE_WOL_DEFAULT_MASK 0x00000003 #define PORT_FEATURE_WOL_DEFAULT_MASK 0x00000003
......
This diff is collapsed.
...@@ -89,6 +89,9 @@ struct link_params { ...@@ -89,6 +89,9 @@ struct link_params {
/* phy_addr populated by the CLC */ /* phy_addr populated by the CLC */
u8 phy_addr; u8 phy_addr;
u32 feature_config_flags;
#define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0)
#define FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED (2<<0)
/* Device pointer passed to all callback functions */ /* Device pointer passed to all callback functions */
struct bnx2x *bp; struct bnx2x *bp;
}; };
...@@ -125,8 +128,11 @@ struct link_vars { ...@@ -125,8 +128,11 @@ struct link_vars {
/* Initialize the phy */ /* Initialize the phy */
u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output); u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output);
/* Reset the link. Should be called when driver or interface goes down */ /* Reset the link. Should be called when driver or interface goes down
u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars); Before calling phy firmware upgrade, the reset_ext_phy should be set
to 0 */
u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
u8 reset_ext_phy);
/* bnx2x_link_update should be called upon link interrupt */ /* bnx2x_link_update should be called upon link interrupt */
u8 bnx2x_link_update(struct link_params *input, struct link_vars *output); u8 bnx2x_link_update(struct link_params *input, struct link_vars *output);
...@@ -163,6 +169,10 @@ u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, u32 led_idx, u32 value); ...@@ -163,6 +169,10 @@ u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, u32 led_idx, u32 value);
u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config, u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
u8 driver_loaded, char data[], u32 size); u8 driver_loaded, char data[], u32 size);
/* bnx2x_handle_module_detect_int should be called upon module detection
interrupt */
void bnx2x_handle_module_detect_int(struct link_params *params);
/* Get the actual link status. In case it returns 0, link is up, /* Get the actual link status. In case it returns 0, link is up,
otherwise link is down*/ otherwise link is down*/
u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars); u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars);
......
...@@ -2112,7 +2112,7 @@ static void bnx2x__link_reset(struct bnx2x *bp) ...@@ -2112,7 +2112,7 @@ static void bnx2x__link_reset(struct bnx2x *bp)
{ {
if (!BP_NOMCP(bp)) { if (!BP_NOMCP(bp)) {
bnx2x_acquire_phy_lock(bp); bnx2x_acquire_phy_lock(bp);
bnx2x_link_reset(&bp->link_params, &bp->link_vars); bnx2x_link_reset(&bp->link_params, &bp->link_vars, 1);
bnx2x_release_phy_lock(bp); bnx2x_release_phy_lock(bp);
} else } else
BNX2X_ERR("Bootcode is missing -not resetting link\n"); BNX2X_ERR("Bootcode is missing -not resetting link\n");
...@@ -2613,6 +2613,13 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) ...@@ -2613,6 +2613,13 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
} }
} }
if (attn & (AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 |
AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1)) {
bnx2x_acquire_phy_lock(bp);
bnx2x_handle_module_detect_int(&bp->link_params);
bnx2x_release_phy_lock(bp);
}
if (attn & HW_INTERRUT_ASSERT_SET_0) { if (attn & HW_INTERRUT_ASSERT_SET_0) {
val = REG_RD(bp, reg_offset); val = REG_RD(bp, reg_offset);
...@@ -5905,6 +5912,37 @@ static int bnx2x_init_port(struct bnx2x *bp) ...@@ -5905,6 +5912,37 @@ static int bnx2x_init_port(struct bnx2x *bp)
/* Port DMAE comes here */ /* Port DMAE comes here */
switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
{
u32 swap_val, swap_override, aeu_gpio_mask, offset;
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
MISC_REGISTERS_GPIO_INPUT_HI_Z, port);
/* The GPIO should be swapped if the swap register is
set and active */
swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
/* Select function upon port-swap configuration */
if (port == 0) {
offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
aeu_gpio_mask = (swap_val && swap_override) ?
AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 :
AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0;
} else {
offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
aeu_gpio_mask = (swap_val && swap_override) ?
AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 :
AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1;
}
val = REG_RD(bp, offset);
/* add GPIO3 to group */
val |= aeu_gpio_mask;
REG_WR(bp, offset, val);
}
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
/* add SPIO 5 to group 0 */ /* add SPIO 5 to group 0 */
val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
...@@ -7623,48 +7661,60 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, ...@@ -7623,48 +7661,60 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
SUPPORTED_Asym_Pause); SUPPORTED_Asym_Pause);
break; break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n", BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
ext_phy_type); ext_phy_type);
bp->port.supported |= (SUPPORTED_10000baseT_Full | bp->port.supported |= (SUPPORTED_10000baseT_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE | SUPPORTED_FIBRE |
SUPPORTED_Autoneg |
SUPPORTED_Pause | SUPPORTED_Pause |
SUPPORTED_Asym_Pause); SUPPORTED_Asym_Pause);
break; break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n", BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n",
ext_phy_type); ext_phy_type);
bp->port.supported |= (SUPPORTED_10000baseT_Full | bp->port.supported |= (SUPPORTED_10000baseT_Full |
SUPPORTED_2500baseX_Full |
SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
SUPPORTED_Autoneg |
SUPPORTED_Pause |
SUPPORTED_Asym_Pause);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
ext_phy_type);
bp->port.supported |= (SUPPORTED_10000baseT_Full |
SUPPORTED_FIBRE | SUPPORTED_FIBRE |
SUPPORTED_Pause | SUPPORTED_Pause |
SUPPORTED_Asym_Pause); SUPPORTED_Asym_Pause);
break; break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n", BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
ext_phy_type); ext_phy_type);
bp->port.supported |= (SUPPORTED_10000baseT_Full | bp->port.supported |= (SUPPORTED_10000baseT_Full |
SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE | SUPPORTED_FIBRE |
SUPPORTED_Autoneg |
SUPPORTED_Pause | SUPPORTED_Pause |
SUPPORTED_Asym_Pause); SUPPORTED_Asym_Pause);
break; break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n", BNX2X_DEV_INFO("ext_phy_type 0x%x (8726)\n",
ext_phy_type); ext_phy_type);
bp->port.supported |= (SUPPORTED_10000baseT_Full | bp->port.supported |= (SUPPORTED_10000baseT_Full |
SUPPORTED_2500baseX_Full |
SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
SUPPORTED_Autoneg | SUPPORTED_Autoneg |
SUPPORTED_FIBRE |
SUPPORTED_Pause | SUPPORTED_Pause |
SUPPORTED_Asym_Pause); SUPPORTED_Asym_Pause);
break; break;
...@@ -7905,6 +7955,7 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) ...@@ -7905,6 +7955,7 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
{ {
int port = BP_PORT(bp); int port = BP_PORT(bp);
u32 val, val2; u32 val, val2;
u32 config;
bp->link_params.bp = bp; bp->link_params.bp = bp;
bp->link_params.port = port; bp->link_params.port = port;
...@@ -7923,6 +7974,14 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) ...@@ -7923,6 +7974,14 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
bp->port.link_config = bp->port.link_config =
SHMEM_RD(bp, dev_info.port_feature_config[port].link_config); SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
config = SHMEM_RD(bp, dev_info.port_feature_config[port].config);
if (config & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_ENABLED)
bp->link_params.feature_config_flags |=
FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED;
else
bp->link_params.feature_config_flags &=
~FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED;
BNX2X_DEV_INFO("serdes_config 0x%08x lane_config 0x%08x\n" BNX2X_DEV_INFO("serdes_config 0x%08x lane_config 0x%08x\n"
KERN_INFO " ext_phy_config 0x%08x speed_cap_mask 0x%08x" KERN_INFO " ext_phy_config 0x%08x speed_cap_mask 0x%08x"
" link_config 0x%08x\n", " link_config 0x%08x\n",
...@@ -8121,10 +8180,11 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -8121,10 +8180,11 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
switch (ext_phy_type) { switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
cmd->port = PORT_FIBRE; cmd->port = PORT_FIBRE;
break; break;
...@@ -8807,7 +8867,7 @@ static int bnx2x_set_eeprom(struct net_device *dev, ...@@ -8807,7 +8867,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
if ((bp->state == BNX2X_STATE_OPEN) || if ((bp->state == BNX2X_STATE_OPEN) ||
(bp->state == BNX2X_STATE_DISABLED)) { (bp->state == BNX2X_STATE_DISABLED)) {
rc |= bnx2x_link_reset(&bp->link_params, rc |= bnx2x_link_reset(&bp->link_params,
&bp->link_vars); &bp->link_vars, 1);
rc |= bnx2x_phy_init(&bp->link_params, rc |= bnx2x_phy_init(&bp->link_params,
&bp->link_vars); &bp->link_vars);
} }
......
...@@ -5800,9 +5800,25 @@ Theotherbitsarereservedandshouldbezero*/ ...@@ -5800,9 +5800,25 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_PMA_REG_ROM_VER2 0xca1a #define MDIO_PMA_REG_ROM_VER2 0xca1a
#define MDIO_PMA_REG_EDC_FFE_MAIN 0xca1b #define MDIO_PMA_REG_EDC_FFE_MAIN 0xca1b
#define MDIO_PMA_REG_PLL_BANDWIDTH 0xca1d #define MDIO_PMA_REG_PLL_BANDWIDTH 0xca1d
#define MDIO_PMA_REG_MISC_CTRL0 0xca23
#define MDIO_PMA_REG_LRM_MODE 0xca3f
#define MDIO_PMA_REG_CDR_BANDWIDTH 0xca46 #define MDIO_PMA_REG_CDR_BANDWIDTH 0xca46
#define MDIO_PMA_REG_MISC_CTRL1 0xca85 #define MDIO_PMA_REG_MISC_CTRL1 0xca85
#define MDIO_PMA_REG_8726_TWO_WIRE_CTRL 0x8000
#define MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK 0x000c
#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE 0x0000
#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE 0x0004
#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IN_PROGRESS 0x0008
#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_FAILED 0x000c
#define MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT 0x8002
#define MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR 0x8003
#define MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF 0xc820
#define MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK 0xff
#define MDIO_PMA_REG_8726_TX_CTRL1 0xca01
#define MDIO_PMA_REG_8726_TX_CTRL2 0xca05
#define MDIO_PMA_REG_7101_RESET 0xc000 #define MDIO_PMA_REG_7101_RESET 0xc000
#define MDIO_PMA_REG_7107_LED_CNTL 0xc007 #define MDIO_PMA_REG_7107_LED_CNTL 0xc007
#define MDIO_PMA_REG_7101_VER1 0xc026 #define MDIO_PMA_REG_7101_VER1 0xc026
...@@ -5832,6 +5848,12 @@ Theotherbitsarereservedandshouldbezero*/ ...@@ -5832,6 +5848,12 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_XS_PLL_SEQUENCER 0x8000 #define MDIO_XS_PLL_SEQUENCER 0x8000
#define MDIO_XS_SFX7101_XGXS_TEST1 0xc00a #define MDIO_XS_SFX7101_XGXS_TEST1 0xc00a
#define MDIO_XS_8706_REG_BANK_RX0 0x80bc
#define MDIO_XS_8706_REG_BANK_RX1 0x80cc
#define MDIO_XS_8706_REG_BANK_RX2 0x80dc
#define MDIO_XS_8706_REG_BANK_RX3 0x80ec
#define MDIO_XS_8706_REG_BANK_RXA 0x80fc
#define MDIO_AN_DEVAD 0x7 #define MDIO_AN_DEVAD 0x7
/*ieee*/ /*ieee*/
#define MDIO_AN_REG_CTRL 0x0000 #define MDIO_AN_REG_CTRL 0x0000
......
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