Commit 4d295db0 authored by Eilon Greenstein's avatar Eilon Greenstein Committed by David S. Miller

bnx2x: Supporting BCM8727 PHY

Adding support for BCM8727 - a dual port SFP+ PHY. That includes verification of
the optic module vendor and part number - the list of approved modules resides
on the nvram and the module is verified by the FW. Since not all users would
like to use this verification feature, it can be disabled. The default behavior
is to issue a warning if the module is not approved, but still allow using it -
but it is also possible to disable the link if the module is not approved.
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 5316bc0b
......@@ -1006,6 +1006,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port);
int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
u32 bnx2x_fw_command(struct bnx2x *bp, u32 command);
static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
int wait)
......
......@@ -248,6 +248,8 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
#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_SFX7101 0x00000800
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727 0x00000900
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC 0x00000a00
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN 0x0000ff00
......@@ -358,10 +360,16 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */
#define PORT_FEATURE_MBA_ENABLED 0x02000000
#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
/* Reserved bits: 28-29 */
/* Check the optic vendor via i2c against a list of approved modules
in a separate nvram image */
#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK 0xE0000000
#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_SHIFT 29
#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT 0x00000000
#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER 0x20000000
#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_WARNING_MSG 0x40000000
#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN 0x60000000
u32 wol_config;
/* Default is used when driver sets to "auto" mode */
......@@ -657,6 +665,12 @@ struct drv_func_mb {
#define DRV_MSG_CODE_GET_UPGRADE_KEY 0x81000000
#define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000
#define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000
/*
* The optic module verification commands requris bootcode
* v5.0.6 or later
*/
#define DRV_MSG_CODE_VRFY_OPT_MDL 0xa0000000
#define REQ_BC_VER_4_VRFY_OPT_MDL 0x00050006
#define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000
#define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000
......@@ -691,6 +705,9 @@ struct drv_func_mb {
#define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE 0x90220000
#define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE 0x90230000
#define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE 0x90240000
#define FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS 0xa0100000
#define FW_MSG_CODE_VRFY_OPT_MDL_INVLD_IMG 0xa0200000
#define FW_MSG_CODE_VRFY_OPT_MDL_UNAPPROVED 0xa0300000
#define FW_MSG_CODE_LIC_CHALLENGE 0xff010000
#define FW_MSG_CODE_LIC_RESPONSE 0xff020000
......
This diff is collapsed.
......@@ -39,7 +39,13 @@
#define SPEED_15000 15000
#define SPEED_16000 16000
#define SFP_EEPROM_VENDOR_NAME_ADDR 0x14
#define SFP_EEPROM_VENDOR_NAME_SIZE 16
#define SFP_EEPROM_VENDOR_OUI_ADDR 0x25
#define SFP_EEPROM_VENDOR_OUI_SIZE 3
#define SFP_EEPROM_PART_NO_ADDR 0x28
#define SFP_EEPROM_PART_NO_SIZE 16
#define PWR_FLT_ERR_MSG_LEN 250
/***********************************************************/
/* Structs */
/***********************************************************/
......@@ -91,7 +97,8 @@ struct link_params {
u16 xgxs_config_tx[4]; /* preemphasis values for the tx side */
u32 feature_config_flags;
#define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0)
#define FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED (2<<0)
#define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2)
#define FEATURE_CONFIG_BCM8727_NOC (1<<3)
/* Device pointer passed to all callback functions */
struct bnx2x *bp;
};
......@@ -181,4 +188,7 @@ u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars);
u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base);
u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
u8 byte_cnt, u8 *o_buf);
#endif /* BNX2X_LINK_H */
......@@ -2637,7 +2637,7 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
{
int port = BP_PORT(bp);
int reg_offset;
u32 val;
u32 val, swap_val, swap_override;
reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
......@@ -2661,6 +2661,17 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
/* The PHY reset is controlled by GPIO 1 */
/* fake the port number to cancel the swap done in
set_gpio() */
swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
port = (swap_val && swap_override) ^ 1;
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
break;
default:
break;
}
......@@ -5561,6 +5572,8 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp)
is_required |=
((phy_type ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) ||
(phy_type ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) ||
(phy_type ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481));
}
......@@ -5812,6 +5825,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
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_BCM8726:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
bp->port.need_hw_lock = 1;
break;
......@@ -6050,10 +6064,15 @@ static int bnx2x_init_port(struct bnx2x *bp)
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
/* add SPIO 5 to group 0 */
val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
{
u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
val = REG_RD(bp, reg_addr);
val |= AEU_INPUTS_ATTN_BITS_SPIO5;
REG_WR(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, val);
REG_WR(bp, reg_addr, val);
}
break;
default:
......@@ -6203,7 +6222,7 @@ static int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
}
/* send the MCP a request, block until there is a reply */
static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
{
int func = BP_FUNC(bp);
u32 seq = ++bp->fw_seq;
......@@ -7676,6 +7695,9 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
BNX2X_ERR("This driver needs bc_ver %X but found %X,"
" please upgrade BC\n", BNX2X_BC_VER, val);
}
bp->link_params.feature_config_flags |=
(val >= REQ_BC_VER_4_VRFY_OPT_MDL) ?
FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0;
if (BP_E1HVN(bp) == 0) {
pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc);
......@@ -7836,6 +7858,18 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
SUPPORTED_Asym_Pause);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
BNX2X_DEV_INFO("ext_phy_type 0x%x (8727)\n",
ext_phy_type);
bp->port.supported |= (SUPPORTED_10000baseT_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_Autoneg |
SUPPORTED_FIBRE |
SUPPORTED_Pause |
SUPPORTED_Asym_Pause);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n",
ext_phy_type);
......@@ -8099,6 +8133,17 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
bp->link_params.ext_phy_config =
SHMEM_RD(bp,
dev_info.port_hw_config[port].external_phy_config);
/* BCM8727_NOC => BCM8727 no over current */
if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC) {
bp->link_params.ext_phy_config &=
~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
bp->link_params.ext_phy_config |=
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727;
bp->link_params.feature_config_flags |=
FEATURE_CONFIG_BCM8727_NOC;
}
bp->link_params.speed_cap_mask =
SHMEM_RD(bp,
dev_info.port_hw_config[port].speed_capability_mask);
......@@ -8119,17 +8164,10 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
bp->link_params.xgxs_config_tx[(i << 1) + 1] = (val & 0xffff);
}
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;
/* If the device is capable of WoL, set the default state according
* to the HW
*/
config = SHMEM_RD(bp, dev_info.port_feature_config[port].config);
bp->wol = (!(bp->flags & NO_WOL_FLAG) &&
(config & PORT_FEATURE_WOL_ENABLED));
......@@ -8139,8 +8177,8 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
bp->link_params.ext_phy_config,
bp->link_params.speed_cap_mask, bp->port.link_config);
bp->link_params.switch_cfg = (bp->port.link_config &
PORT_FEATURE_CONNECTED_SWITCH_MASK);
bp->link_params.switch_cfg |= (bp->port.link_config &
PORT_FEATURE_CONNECTED_SWITCH_MASK);
bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg);
bnx2x_link_settings_requested(bp);
......@@ -8336,6 +8374,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
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:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
cmd->port = PORT_FIBRE;
break;
......
......@@ -5845,25 +5845,33 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_PMA_REG_ROM_VER2 0xca1a
#define MDIO_PMA_REG_EDC_FFE_MAIN 0xca1b
#define MDIO_PMA_REG_PLL_BANDWIDTH 0xca1d
#define MDIO_PMA_REG_GEN_CTRL2 0xca1e
#define MDIO_PMA_REG_PLL_CTRL 0xca1e
#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_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_SFP_TWO_WIRE_CTRL 0x8000
#define MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK 0x000c
#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE 0x0000
#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE 0x0004
#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IN_PROGRESS 0x0008
#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_FAILED 0x000c
#define MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT 0x8002
#define MDIO_PMA_REG_SFP_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_8727_TWO_WIRE_SLAVE_ADDR 0x8005
#define MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF 0x8007
#define MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK 0xff
#define MDIO_PMA_REG_8727_MISC_CTRL 0x8309
#define MDIO_PMA_REG_8727_TX_CTRL1 0xca02
#define MDIO_PMA_REG_8727_TX_CTRL2 0xca05
#define MDIO_PMA_REG_8727_PCS_OPT_CTRL 0xc808
#define MDIO_PMA_REG_8727_GPIO_CTRL 0xc80e
#define MDIO_PMA_REG_8073_CHIP_REV 0xc801
#define MDIO_PMA_REG_8073_SPEED_LINK_STATUS 0xc820
......
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