{
struct bnx2x *bp = params->bp;
u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+
/* Set Clause 22 */
REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
{
struct bnx2x *bp = params->bp;
+
if (phy_flags & PHY_XGXS_FLAG) {
REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
params->port*0x18, 0);
/* enable access for bmac registers */
REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
- }
+ } else
+ REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
vars->mac_type = MAC_TYPE_EMAC;
return 0;
REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
wb_data, 2);
-
/* set rx mtu */
wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
wb_data[1] = 0;
static void bnx2x_update_mng(struct link_params *params, u32 link_status)
{
struct bnx2x *bp = params->bp;
+
REG_WR(bp, params->shmem_base +
offsetof(struct shmem_region,
port_mb[params->port].link_status),
DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
line_speed);
return -EINVAL;
- break;
}
}
REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
{
u32 emac_base;
+
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
EMAC_MDIO_MODE_CLOCK_CNT));
val |= (EMAC_MDIO_MODE_CLAUSE_45 |
- (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
+ (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
udelay(40);
MDIO_COMBO_IEEE0_MII_CONTROL,
(mii_control |
MDIO_COMBO_IEEO_MII_CONTROL_RESET));
-
- bnx2x_set_serdes_access(params);
+ if (params->switch_cfg == SWITCH_CFG_1G)
+ bnx2x_set_serdes_access(params);
/* wait for the reset to self clear */
for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
struct bnx2x *bp = params->bp;
u16 reg_val;
- /* program duplex, disable autoneg */
-
+ /* program duplex, disable autoneg and sgmii*/
CL45_RD_OVER_CL22(bp, params->port,
params->phy_addr,
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL, ®_val);
reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
- MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
+ MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
+ MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
if (params->req_duplex == DUPLEX_FULL)
reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
CL45_WR_OVER_CL22(bp, params->port,
MDIO_OVER_1G_UP3, 0x400);
}
-static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
+static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc)
{
*ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
/* resolve pause mode and advertisement
}
static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
- u32 ieee_fc)
+ u16 ieee_fc)
{
struct bnx2x *bp = params->bp;
/* for AN, we are always publishing full duplex */
CL45_WR_OVER_CL22(bp, params->port,
params->phy_addr,
MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
}
static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
}
}
-static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
+static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params,
struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
u8 ext_phy_addr;
- u16 ld_pause; /* local */
- u16 lp_pause; /* link partner */
- u16 an_complete; /* AN complete */
+ u16 ld_pause; /* local */
+ u16 lp_pause; /* link partner */
+ u16 an_complete; /* AN complete */
u16 pause_result;
u8 ret = 0;
u32 ext_phy_type;
u8 port = params->port;
- ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
+ ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
/* read twice */
DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
bnx2x_pause_resolve(vars, pause_result);
} else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
- (bnx2x_ext_phy_resove_fc(params, vars))) {
+ (bnx2x_ext_phy_resolve_fc(params, vars))) {
return;
} else {
if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
"link speed unsupported gp_status 0x%x\n",
gp_status);
return -EINVAL;
- break;
+
case GP_STATUS_10G_KX4:
case GP_STATUS_10G_HIG:
case GP_STATUS_10G_CX4:
DP(NETIF_MSG_LINK,
"link speed unsupported gp_status 0x%x\n",
gp_status);
- return -EINVAL;
- break;
+ return -EINVAL;
}
/* Upon link speed change set the NIG into drain mode.
/*****************************************************************************/
/* External Phy section */
/*****************************************************************************/
-static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
+void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
{
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
{
struct bnx2x *bp = params->bp;
u32 ext_phy_type;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
+
DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
/* The PHY reset is controled by GPIO 1
params->port);
/* HW reset */
- bnx2x_hw_reset(bp, params->port);
+ bnx2x_ext_phy_hw_reset(bp, params->port);
bnx2x_cl45_write(bp, params->port,
ext_phy_type,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL,
1<<15);
-
break;
+
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ DP(NETIF_MSG_LINK, "XGXS 8072\n");
+
/* Unset Low Power Mode and SW reset */
/* Restore normal power mode*/
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
MISC_REGISTERS_GPIO_OUTPUT_HIGH,
params->port);
- DP(NETIF_MSG_LINK, "XGXS 8072\n");
bnx2x_cl45_write(bp, params->port,
ext_phy_type,
ext_phy_addr,
MDIO_PMA_REG_CTRL,
1<<15);
break;
+
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- {
+ DP(NETIF_MSG_LINK, "XGXS 8073\n");
/* Restore normal power mode*/
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
MISC_REGISTERS_GPIO_OUTPUT_HIGH,
params->port);
-
- DP(NETIF_MSG_LINK, "XGXS 8073\n");
- }
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
params->port);
/* HW reset */
- bnx2x_hw_reset(bp, params->port);
-
+ bnx2x_ext_phy_hw_reset(bp, params->port);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
-
/* Restore normal power mode*/
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
MISC_REGISTERS_GPIO_OUTPUT_HIGH,
params->port);
/* HW reset */
- bnx2x_hw_reset(bp, params->port);
+ bnx2x_ext_phy_hw_reset(bp, params->port);
bnx2x_cl45_write(bp, params->port,
ext_phy_type,
case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
DP(NETIF_MSG_LINK, "SerDes 5482\n");
- bnx2x_hw_reset(bp, params->port);
+ bnx2x_ext_phy_hw_reset(bp, params->port);
break;
default:
- DP(NETIF_MSG_LINK,
- "BAD SerDes ext_phy_config 0x%x\n",
+ DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
params->ext_phy_config);
break;
}
}
}
-
static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
u32 shmem_base, u32 spirom_ver)
{
- DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x\n",
- (u16)(spirom_ver>>16), (u16)spirom_ver);
+ DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
+ (u16)(spirom_ver>>16), (u16)spirom_ver, port);
REG_WR(bp, shmem_base +
offsetof(struct shmem_region,
port_mb[port].ext_phy_fw_version),
u32 shmem_base)
{
u16 fw_ver1, fw_ver2;
+
bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER1, &fw_ver1);
bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
{
struct bnx2x *bp = params->bp;
u8 port = params->port;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
/* Need to wait 200ms after reset */
/* This is only required for 8073A1, version 102 only */
struct bnx2x *bp = params->bp;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u16 val;
/* Read 8073 HW revision*/
static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
{
struct bnx2x *bp = params->bp;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u16 val, cnt, cnt1 ;
bnx2x_cl45_read(bp, params->port,
}
DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
return -EINVAL;
-
}
static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
{
struct bnx2x *bp = params->bp;
u8 port = params->port;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
/* Need to wait 100ms after reset */
u8 tx_en)
{
u16 val;
+
DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
tx_en, port);
/* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
u16 val = 0;
u16 i;
u8 port = params->port;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
if (byte_cnt > 16) {
DP(NETIF_MSG_LINK, "Reading from eeprom is"
" is limited to 0xf\n");
struct bnx2x *bp = params->bp;
u16 val, i;
u8 port = params->port;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
if (byte_cnt > 16) {
case SFP_EEPROM_CON_TYPE_VAL_COPPER:
{
u8 copper_module_type;
+
/* Check if its active cable( includes SFP+ module)
of passive cable*/
if (bnx2x_read_sfp_module_eeprom(params,
DP(NETIF_MSG_LINK, "Optic module detected\n");
check_limiting_mode = 1;
break;
-
default:
DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
val);
{
struct bnx2x *bp = params->bp;
u8 port = params->port;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u16 cur_limiting_mode;
bnx2x_cl45_read(bp, port,
u8 port = params->port;
u16 phy_identifier;
u16 rom_ver2_val;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
bnx2x_cl45_read(bp, port,
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
struct bnx2x *bp = params->bp;
u16 edc_mode;
u8 rc = 0;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
u32 val = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region, dev_info.
struct bnx2x *bp = params->bp;
u32 gpio_val;
u8 port = params->port;
+
/* Set valid module led off */
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
MISC_REGISTERS_GPIO_HIGH,
else
DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
} else {
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
+
u32 ext_phy_type =
XGXS_EXT_PHY_TYPE(params->ext_phy_config);
u32 val = REG_RD(bp, params->shmem_base +
{
struct bnx2x *bp = params->bp;
u8 port = params->port;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
/* Force KR or KX */
MDIO_AN_REG_CTRL,
0x0000);
}
+
static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
{
struct bnx2x *bp = params->bp;
u8 port = params->port;
u16 val;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
bnx2x_cl45_read(bp, params->port,
static void bnx2x_8073_set_pause_cl37(struct link_params *params,
struct link_vars *vars)
{
-
struct bnx2x *bp = params->bp;
u16 cl37_val;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
bnx2x_cl45_read(bp, params->port,
{
struct bnx2x *bp = params->bp;
u16 val;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
/* read modify write pause advertizing */
u8 enable_cl73)
{
struct bnx2x *bp = params->bp;
+
if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
u16 ctrl = 0;
u16 val = 0;
u8 rc = 0;
+
if (vars->phy_flags & PHY_XGXS_FLAG) {
- ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
/* Make sure that the soft reset is off (expect for the 8072:
bnx2x_8073_set_pause_cl37(params, vars);
if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)
bnx2x_bcm8072_external_rom_boot(params);
- } else {
-
+ else
/* In case of 8073 with long xaui lines,
don't set the 8073 xaui low power*/
bnx2x_bcm8073_set_xaui_low_power_mode(params);
- }
bnx2x_cl45_read(bp, params->port,
ext_phy_type,
ext_phy_addr,
MDIO_AN_DEVAD,
MDIO_AN_REG_ADV, val);
-
if (ext_phy_type ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
-
bnx2x_cl45_read(bp, params->port,
ext_phy_type,
ext_phy_addr,
bnx2x_save_spirom_version(params->bp, params->port,
params->shmem_base,
(u32)(fw_ver1<<16 | fw_ver2));
-
break;
}
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
{
struct bnx2x *bp = params->bp;
u16 mod_abs, rx_alarm_status;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
u32 val = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region, dev_info.
port_feature_config[params->port].
u16 rx_sd, pcs_status;
u8 ext_phy_link_up = 0;
u8 port = params->port;
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ if (vars->phy_flags & PHY_XGXS_FLAG) {
+ ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
break;
}
}
-
if (val2 & (1<<1))
vars->line_speed = SPEED_1000;
else
if ((val1 & (1<<8)) == 0) {
DP(NETIF_MSG_LINK, "8727 Power fault"
- " has been detected on port"
- " %d\n", params->port);
+ " has been detected on "
+ "port %d\n",
+ params->port);
printk(KERN_ERR PFX "Error: Power"
" fault on %s Port %d has"
" been detected and the"
{
u16 link_status = 0;
u16 an1000_status = 0;
+
if (ext_phy_type ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
bnx2x_cl45_read(bp, params->port,
DP(NETIF_MSG_LINK,
"870x LASI status 0x%x->0x%x\n",
val1, val2);
-
} else {
/* In 8073, port1 is directed through emac0 and
* port0 is directed through emac1
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CDR_BANDWIDTH,
0x0333);
-
-
}
bnx2x_cl45_read(bp, params->port,
ext_phy_type,
ext_phy_addr);
}
}
-
break;
default:
DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
ext_phy_link_up = 0;
break;
}
+ /* Set SGMII mode for external phy */
+ if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
+ if (vars->line_speed < SPEED_1000)
+ vars->phy_flags |= PHY_SGMII_FLAG;
+ else
+ vars->phy_flags &= ~PHY_SGMII_FLAG;
+ }
} else { /* SerDes */
ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
u32 ext_phy_type;
u32 mask;
struct bnx2x *bp = params->bp;
+
/* setting the status to report on link up
for either XGXS or SerDes */
bnx2x_bits_en(bp,
NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
mask);
- DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
+
+ DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
(params->switch_cfg == SWITCH_CFG_10G),
REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
-
DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
return 0;
}
-
-static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
- u32 ext_phy_type)
-{
- u32 cnt = 0;
- u16 ctrl = 0;
- /* Enable EMAC0 in to enable MDIO */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
- (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
- msleep(5);
-
- /* take ext phy out of reset */
- bnx2x_set_gpio(bp,
- MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_HIGH,
- port);
-
- bnx2x_set_gpio(bp,
- MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_HIGH,
- port);
-
- /* wait for 5ms */
- msleep(5);
-
- for (cnt = 0; cnt < 1000; cnt++) {
- msleep(1);
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- &ctrl);
- if (!(ctrl & (1<<15))) {
- DP(NETIF_MSG_LINK, "Reset completed\n\n");
- break;
- }
- }
-}
-
-static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
-{
- /* put sf to reset */
- bnx2x_set_gpio(bp,
- MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_LOW,
- port);
- bnx2x_set_gpio(bp,
- MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_LOW,
- port);
-}
-
u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
u8 *version, u16 len)
{
if (params->switch_cfg == SWITCH_CFG_10G) {
ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
/* CL37 Autoneg Enabled */
- ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
u8 rc = 0;
u32 tmp;
u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+
DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
speed, hw_led_mode);
u8 rc = 0;
u8 non_ext_phy;
u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
/* Activate the external PHY */
bnx2x_ext_phy_reset(params, vars);
u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
-
u32 val;
- DP(NETIF_MSG_LINK, "Phy Initialization started \n");
- DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
- params->req_line_speed, params->req_flow_ctrl);
+
+ DP(NETIF_MSG_LINK, "Phy Initialization started\n");
+ DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n",
+ params->req_line_speed, params->req_flow_ctrl);
vars->link_status = 0;
vars->phy_link_up = 0;
vars->link_up = 0;
else
vars->phy_flags = PHY_XGXS_FLAG;
-
/* disable attentions */
bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
(NIG_MASK_XGXS0_LINK_STATUS |
bnx2x_emac_init(params, vars);
if (CHIP_REV_IS_FPGA(bp)) {
+
vars->link_up = 1;
vars->line_speed = SPEED_10000;
vars->duplex = DUPLEX_FULL;
/* enable on E1.5 FPGA */
if (CHIP_IS_E1H(bp)) {
vars->flow_ctrl |=
- (BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
+ (BNX2X_FLOW_CTRL_TX |
+ BNX2X_FLOW_CTRL_RX);
vars->link_status |=
(LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
bnx2x_emac_enable(params, vars, 0);
bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
/* disable drain */
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
- + params->port*4, 0);
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
/* update shared memory */
bnx2x_update_mng(params, vars->link_status);
} else
if (params->loopback_mode == LOOPBACK_BMAC) {
+
vars->link_up = 1;
vars->line_speed = SPEED_10000;
vars->duplex = DUPLEX_FULL;
REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
params->port*4, 0);
+
} else if (params->loopback_mode == LOOPBACK_EMAC) {
+
vars->link_up = 1;
vars->line_speed = SPEED_1000;
vars->duplex = DUPLEX_FULL;
vars->duplex);
REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
params->port*4, 0);
+
} else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
- (params->loopback_mode == LOOPBACK_EXT_PHY)) {
+ (params->loopback_mode == LOOPBACK_EXT_PHY)) {
+
vars->link_up = 1;
vars->line_speed = SPEED_10000;
vars->duplex = DUPLEX_FULL;
} else
/* No loopback */
{
-
bnx2x_phy_deassert(params, vars->phy_flags);
switch (params->switch_cfg) {
case SWITCH_CFG_1G:
if ((params->ext_phy_config &
PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
- vars->phy_flags |=
- PHY_SGMII_FLAG;
+ vars->phy_flags |= PHY_SGMII_FLAG;
}
val = REG_RD(bp,
default:
DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
return -EINVAL;
- break;
}
DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
u8 reset_ext_phy)
{
-
struct bnx2x *bp = params->bp;
u32 ext_phy_config = params->ext_phy_config;
u16 hw_led_mode = params->hw_led_mode;
config));
/* disable attentions */
-
vars->link_status = 0;
bnx2x_update_mng(params, vars->link_status);
bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
{
/* Disable Transmitter */
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr =
+ XGXS_EXT_PHY_ADDR(params->ext_phy_config);
if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
bnx2x_sfp_set_transmitter(bp, port,
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
{
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u8 ext_phy_addr =
+ XGXS_EXT_PHY_ADDR(params->ext_phy_config);
/* Set soft reset */
bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
break;
{
struct bnx2x *bp = params->bp;
u8 port = params->port;
+
DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
bnx2x_set_led(bp, port, LED_MODE_OFF,
0, params->hw_led_mode,
struct bnx2x *bp = params->bp;
u8 port = params->port;
u8 rc = 0;
+
vars->link_status |= LINK_STATUS_LINK_UP;
if (link_10g) {
bnx2x_bmac_enable(params, vars, 0);
NIG_MASK_SERDES0_LINK_STATUS |
NIG_MASK_MI_INT));
- ext_phy_addr[port] =
- ((ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
/* Need to take the phy out of low power mode in order
to write to access its registers */
swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
- bnx2x_hw_reset(bp, 1 ^ (swap_val && swap_override));
+ bnx2x_ext_phy_hw_reset(bp, 1 ^ (swap_val && swap_override));
msleep(5);
if (swap_val && swap_override)
NIG_MASK_SERDES0_LINK_STATUS |
NIG_MASK_MI_INT));
- ext_phy_addr[port] = ((ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
/* Reset the phy */
bnx2x_cl45_write(bp, port,
u8 ext_phy_addr;
u32 val;
s8 port;
+
/* Use port1 because of the static port-swap */
/* Enable the module detection interrupt */
val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
(1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
- bnx2x_hw_reset(bp, 1);
+ bnx2x_ext_phy_hw_reset(bp, 1);
msleep(5);
for (port = 0; port < PORT_MAX; port++) {
/* Extract the ext phy address for the port */
offsetof(struct shmem_region,
dev_info.port_hw_config[port].external_phy_config));
- ext_phy_addr =
- ((ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ ext_phy_addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
ext_phy_addr);
return rc;
}
-
-
-static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
+void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
{
u16 val, cnt;
break;
}
}
-#define RESERVED_SIZE 256
-/* max application is 160K bytes - data at end of RAM */
-#define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
-
-/* Header is 14 bytes */
-#define HEADER_SIZE 14
-#define DATA_OFFSET HEADER_SIZE
-
-#define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
- bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
- ext_phy_addr, \
- MDIO_PCS_DEVAD, \
- MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
-
-/* Programs an image to DSP's flash via the SPI port*/
-static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
- u8 ext_phy_addr,
- char data[], u32 size)
-{
- const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
- /* Doesn't include last trans!*/
- const u16 last_trans_size = size%4; /* Num bytes on last trans */
- u16 trans_cnt, byte_cnt;
- u32 data_index;
- u16 tmp;
- u16 code_started = 0;
- u16 image_revision1, image_revision2;
- u16 cnt;
-
- DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
- /* Going to flash*/
- if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
- /* This very often will be the case, because the image is built
- with 160Kbytes size whereas the total image size must actually
- be 160Kbytes-RESERVED_SIZE */
- DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
- "truncated to %d bytes\n", size, MAX_APP_SIZE);
- size = MAX_APP_SIZE+HEADER_SIZE;
- }
- DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
- DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
- /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
- and issuing a reset.*/
-
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
- MISC_REGISTERS_GPIO_HIGH, port);
-
- bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
-
- /* wait 0.5 sec */
- for (cnt = 0; cnt < 100; cnt++)
- msleep(5);
-
- /* Make sure we can access the DSP
- And it's in the correct mode (waiting for download) */
-
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
-
- if (tmp != 0x000A) {
- DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
- "Expected 0x000A, read 0x%04X\n", tmp);
- DP(NETIF_MSG_LINK, "Download failed\n");
- return -EINVAL;
- }
-
- /* Mux the SPI interface away from the internal processor */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_MUX, 1);
-
- /* Reset the SPI port */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
- (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
-
- /* Erase the flash */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
- 1);
-
- SPI_START_TRANSFER(bp, port, ext_phy_addr);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
- 1);
- SPI_START_TRANSFER(bp, port, ext_phy_addr);
-
- /* Wait 10 seconds, the maximum time for the erase to complete */
- DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
- for (cnt = 0; cnt < 1000; cnt++)
- msleep(10);
-
- DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
- data_index = 0;
- for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
- 1);
- SPI_START_TRANSFER(bp, port, ext_phy_addr);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
-
- /* Bits 23-16 of address */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- (data_index>>16));
- /* Bits 15-8 of address */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- (data_index>>8));
-
- /* Bits 7-0 of address */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- ((u16)data_index));
-
- byte_cnt = 0;
- while (byte_cnt < 4 && data_index < size) {
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- data[data_index++]);
- byte_cnt++;
- }
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
- byte_cnt+4);
-
- SPI_START_TRANSFER(bp, port, ext_phy_addr);
- msleep(5); /* Wait 5 ms minimum between transs */
-
- /* Let the user know something's going on.*/
- /* a pacifier ever 4K */
- if ((data_index % 1023) == 0)
- DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
- }
-
- DP(NETIF_MSG_LINK, "\n");
- /* Transfer the last block if there is data remaining */
- if (last_trans_size) {
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
- 1);
-
- SPI_START_TRANSFER(bp, port, ext_phy_addr);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
-
- /* Bits 23-16 of address */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- (data_index>>16));
- /* Bits 15-8 of address */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- (data_index>>8));
-
- /* Bits 7-0 of address */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- ((u16)data_index));
-
- byte_cnt = 0;
- while (byte_cnt < last_trans_size && data_index < size) {
- /* Bits 7-0 of address */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- data[data_index++]);
- byte_cnt++;
- }
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
- byte_cnt+4);
-
- SPI_START_TRANSFER(bp, port, ext_phy_addr);
- }
-
- /* DSP Remove Download Mode */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
- MISC_REGISTERS_GPIO_LOW, port);
-
- bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
-
- /* wait 0.5 sec to allow it to run */
- for (cnt = 0; cnt < 100; cnt++)
- msleep(5);
-
- bnx2x_hw_reset(bp, port);
-
- for (cnt = 0; cnt < 100; cnt++)
- msleep(5);
-
- /* Check that the code is started. In case the download
- checksum failed, the code won't be started. */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_DSP_ACCESS,
- &tmp);
-
- code_started = (tmp & (1<<4));
- if (!code_started) {
- DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
- return -EINVAL;
- }
-
- /* Verify that the file revision is now equal to the image
- revision within the DSP */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_VER1,
- &image_revision1);
-
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_VER2,
- &image_revision2);
-
- if (data[0x14e] != (image_revision2&0xFF) ||
- data[0x14f] != ((image_revision2&0xFF00)>>8) ||
- data[0x150] != (image_revision1&0xFF) ||
- data[0x151] != ((image_revision1&0xFF00)>>8)) {
- DP(NETIF_MSG_LINK, "Download failed.\n");
- return -EINVAL;
- }
- DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
- return 0;
-}
-
-u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
- u8 driver_loaded, char data[], u32 size)
-{
- u8 rc = 0;
- u32 ext_phy_type;
- u8 ext_phy_addr;
- ext_phy_addr = ((ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
-
- switch (ext_phy_type) {
- 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_BCM8705:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK,
- "Flash download not supported for this ext phy\n");
- rc = -EINVAL;
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- /* Take ext phy out of reset */
- if (!driver_loaded)
- bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
- rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
- data, size);
- if (!driver_loaded)
- bnx2x_turn_off_sf(bp, port);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
- default:
- DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
- rc = -EINVAL;
- break;
- }
- return rc;
-}
-