|
@@ -377,9 +377,60 @@ static u8 bnx2x_emac_enable(struct link_params *params,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void bnx2x_update_bmac2(struct link_params *params,
|
|
|
|
+ struct link_vars *vars,
|
|
|
|
+ u8 is_lb)
|
|
|
|
+{
|
|
|
|
+ /*
|
|
|
|
+ * Set rx control: Strip CRC and enable BigMAC to relay
|
|
|
|
+ * control packets to the system as well
|
|
|
|
+ */
|
|
|
|
+ u32 wb_data[2];
|
|
|
|
+ struct bnx2x *bp = params->bp;
|
|
|
|
+ u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
|
|
|
|
+ NIG_REG_INGRESS_BMAC0_MEM;
|
|
|
|
+ u32 val = 0x14;
|
|
|
|
|
|
|
|
+ if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
|
|
|
|
+ /* Enable BigMAC to react on received Pause packets */
|
|
|
|
+ val |= (1<<5);
|
|
|
|
+ wb_data[0] = val;
|
|
|
|
+ wb_data[1] = 0;
|
|
|
|
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+ udelay(30);
|
|
|
|
|
|
-static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
|
|
|
|
|
|
+ /* Tx control */
|
|
|
|
+ val = 0xc0;
|
|
|
|
+ if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
|
|
|
|
+ val |= 0x800000;
|
|
|
|
+ wb_data[0] = val;
|
|
|
|
+ wb_data[1] = 0;
|
|
|
|
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+
|
|
|
|
+ val = 0x8000;
|
|
|
|
+ wb_data[0] = val;
|
|
|
|
+ wb_data[1] = 0;
|
|
|
|
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+
|
|
|
|
+ /* mac control */
|
|
|
|
+ val = 0x3; /* Enable RX and TX */
|
|
|
|
+ if (is_lb) {
|
|
|
|
+ val |= 0x4; /* Local loopback */
|
|
|
|
+ DP(NETIF_MSG_LINK, "enable bmac loopback\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ wb_data[0] = val;
|
|
|
|
+ wb_data[1] = 0;
|
|
|
|
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+static u8 bnx2x_bmac1_enable(struct link_params *params,
|
|
|
|
+ struct link_vars *vars,
|
|
u8 is_lb)
|
|
u8 is_lb)
|
|
{
|
|
{
|
|
struct bnx2x *bp = params->bp;
|
|
struct bnx2x *bp = params->bp;
|
|
@@ -389,17 +440,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
|
|
u32 wb_data[2];
|
|
u32 wb_data[2];
|
|
u32 val;
|
|
u32 val;
|
|
|
|
|
|
- DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
|
|
|
|
- /* reset and unreset the BigMac */
|
|
|
|
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
|
|
|
|
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
|
|
|
|
- msleep(1);
|
|
|
|
-
|
|
|
|
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
|
|
|
|
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
|
|
|
|
-
|
|
|
|
- /* enable access for bmac registers */
|
|
|
|
- REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
|
|
|
|
|
|
+ DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
|
|
|
|
|
|
/* XGXS control */
|
|
/* XGXS control */
|
|
wb_data[0] = 0x3c;
|
|
wb_data[0] = 0x3c;
|
|
@@ -479,6 +520,103 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
|
|
wb_data, 2);
|
|
wb_data, 2);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static u8 bnx2x_bmac2_enable(struct link_params *params,
|
|
|
|
+ struct link_vars *vars,
|
|
|
|
+ u8 is_lb)
|
|
|
|
+{
|
|
|
|
+ struct bnx2x *bp = params->bp;
|
|
|
|
+ u8 port = params->port;
|
|
|
|
+ u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
|
|
|
|
+ NIG_REG_INGRESS_BMAC0_MEM;
|
|
|
|
+ u32 wb_data[2];
|
|
|
|
+
|
|
|
|
+ DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
|
|
|
|
+
|
|
|
|
+ wb_data[0] = 0;
|
|
|
|
+ wb_data[1] = 0;
|
|
|
|
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+ udelay(30);
|
|
|
|
+
|
|
|
|
+ /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
|
|
|
|
+ wb_data[0] = 0x3c;
|
|
|
|
+ wb_data[1] = 0;
|
|
|
|
+ REG_WR_DMAE(bp, bmac_addr +
|
|
|
|
+ BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+
|
|
|
|
+ udelay(30);
|
|
|
|
+
|
|
|
|
+ /* tx MAC SA */
|
|
|
|
+ wb_data[0] = ((params->mac_addr[2] << 24) |
|
|
|
|
+ (params->mac_addr[3] << 16) |
|
|
|
|
+ (params->mac_addr[4] << 8) |
|
|
|
|
+ params->mac_addr[5]);
|
|
|
|
+ wb_data[1] = ((params->mac_addr[0] << 8) |
|
|
|
|
+ params->mac_addr[1]);
|
|
|
|
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+
|
|
|
|
+ udelay(30);
|
|
|
|
+
|
|
|
|
+ /* Configure SAFC */
|
|
|
|
+ wb_data[0] = 0x1000200;
|
|
|
|
+ wb_data[1] = 0;
|
|
|
|
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+ udelay(30);
|
|
|
|
+
|
|
|
|
+ /* set rx mtu */
|
|
|
|
+ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
|
|
|
|
+ wb_data[1] = 0;
|
|
|
|
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+ udelay(30);
|
|
|
|
+
|
|
|
|
+ /* set tx mtu */
|
|
|
|
+ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
|
|
|
|
+ wb_data[1] = 0;
|
|
|
|
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+ udelay(30);
|
|
|
|
+ /* set cnt max size */
|
|
|
|
+ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
|
|
|
|
+ wb_data[1] = 0;
|
|
|
|
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+ udelay(30);
|
|
|
|
+ bnx2x_update_bmac2(params, vars, is_lb);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+u8 bnx2x_bmac_enable(struct link_params *params,
|
|
|
|
+ struct link_vars *vars,
|
|
|
|
+ u8 is_lb)
|
|
|
|
+{
|
|
|
|
+ u8 rc, port = params->port;
|
|
|
|
+ struct bnx2x *bp = params->bp;
|
|
|
|
+ u32 val;
|
|
|
|
+ /* reset and unreset the BigMac */
|
|
|
|
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
|
|
|
|
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
|
|
|
|
+ udelay(10);
|
|
|
|
+
|
|
|
|
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
|
|
|
|
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
|
|
|
|
+
|
|
|
|
+ /* enable access for bmac registers */
|
|
|
|
+ REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
|
|
|
|
+
|
|
|
|
+ /* Enable BMAC according to BMAC type*/
|
|
|
|
+ if (CHIP_IS_E2(bp))
|
|
|
|
+ rc = bnx2x_bmac2_enable(params, vars, is_lb);
|
|
|
|
+ else
|
|
|
|
+ rc = bnx2x_bmac1_enable(params, vars, is_lb);
|
|
REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
|
|
REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
|
|
REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
|
|
REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
|
|
REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
|
|
REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
|
|
@@ -493,7 +631,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
|
|
REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
|
|
REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
|
|
|
|
|
|
vars->mac_type = MAC_TYPE_BMAC;
|
|
vars->mac_type = MAC_TYPE_BMAC;
|
|
- return 0;
|
|
|
|
|
|
+ return rc;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -519,13 +657,25 @@ static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
|
|
(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
|
|
(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
|
|
nig_bmac_enable) {
|
|
nig_bmac_enable) {
|
|
|
|
|
|
- /* Clear Rx Enable bit in BMAC_CONTROL register */
|
|
|
|
- REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
|
|
|
|
- wb_data, 2);
|
|
|
|
- wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
|
|
|
|
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
|
|
|
|
- wb_data, 2);
|
|
|
|
-
|
|
|
|
|
|
+ if (CHIP_IS_E2(bp)) {
|
|
|
|
+ /* Clear Rx Enable bit in BMAC_CONTROL register */
|
|
|
|
+ REG_RD_DMAE(bp, bmac_addr +
|
|
|
|
+ BIGMAC2_REGISTER_BMAC_CONTROL,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+ wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
|
|
|
|
+ REG_WR_DMAE(bp, bmac_addr +
|
|
|
|
+ BIGMAC2_REGISTER_BMAC_CONTROL,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+ } else {
|
|
|
|
+ /* Clear Rx Enable bit in BMAC_CONTROL register */
|
|
|
|
+ REG_RD_DMAE(bp, bmac_addr +
|
|
|
|
+ BIGMAC_REGISTER_BMAC_CONTROL,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+ wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
|
|
|
|
+ REG_WR_DMAE(bp, bmac_addr +
|
|
|
|
+ BIGMAC_REGISTER_BMAC_CONTROL,
|
|
|
|
+ wb_data, 2);
|
|
|
|
+ }
|
|
msleep(1);
|
|
msleep(1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -821,23 +971,31 @@ u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr,
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
|
|
-static void bnx2x_set_aer_mmd(struct link_params *params,
|
|
|
|
- struct bnx2x_phy *phy)
|
|
|
|
|
|
+static void bnx2x_set_aer_mmd_xgxs(struct link_params *params,
|
|
|
|
+ struct bnx2x_phy *phy)
|
|
{
|
|
{
|
|
- struct bnx2x *bp = params->bp;
|
|
|
|
u32 ser_lane;
|
|
u32 ser_lane;
|
|
- u16 offset;
|
|
|
|
-
|
|
|
|
|
|
+ u16 offset, aer_val;
|
|
|
|
+ struct bnx2x *bp = params->bp;
|
|
ser_lane = ((params->lane_config &
|
|
ser_lane = ((params->lane_config &
|
|
PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
|
|
PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
|
|
PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
|
|
PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
|
|
|
|
|
|
- offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
|
|
|
|
- (phy->addr + ser_lane) : 0;
|
|
|
|
-
|
|
|
|
|
|
+ offset = phy->addr + ser_lane;
|
|
|
|
+ if (CHIP_IS_E2(bp))
|
|
|
|
+ aer_val = 0x2800 + offset - 1;
|
|
|
|
+ else
|
|
|
|
+ aer_val = 0x3800 + offset;
|
|
CL45_WR_OVER_CL22(bp, phy,
|
|
CL45_WR_OVER_CL22(bp, phy,
|
|
- MDIO_REG_BANK_AER_BLOCK,
|
|
|
|
- MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
|
|
|
|
|
|
+ MDIO_REG_BANK_AER_BLOCK,
|
|
|
|
+ MDIO_AER_BLOCK_AER_REG, aer_val);
|
|
|
|
+}
|
|
|
|
+static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp,
|
|
|
|
+ struct bnx2x_phy *phy)
|
|
|
|
+{
|
|
|
|
+ CL45_WR_OVER_CL22(bp, phy,
|
|
|
|
+ MDIO_REG_BANK_AER_BLOCK,
|
|
|
|
+ MDIO_AER_BLOCK_AER_REG, 0x3800);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************/
|
|
/******************************************************************/
|
|
@@ -2046,12 +2204,12 @@ static u8 bnx2x_init_serdes(struct bnx2x_phy *phy,
|
|
u8 rc;
|
|
u8 rc;
|
|
vars->phy_flags |= PHY_SGMII_FLAG;
|
|
vars->phy_flags |= PHY_SGMII_FLAG;
|
|
bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
|
|
bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
|
|
- bnx2x_set_aer_mmd(params, phy);
|
|
|
|
|
|
+ bnx2x_set_aer_mmd_serdes(params->bp, phy);
|
|
rc = bnx2x_reset_unicore(params, phy, 1);
|
|
rc = bnx2x_reset_unicore(params, phy, 1);
|
|
/* reset the SerDes and wait for reset bit return low */
|
|
/* reset the SerDes and wait for reset bit return low */
|
|
if (rc != 0)
|
|
if (rc != 0)
|
|
return rc;
|
|
return rc;
|
|
- bnx2x_set_aer_mmd(params, phy);
|
|
|
|
|
|
+ bnx2x_set_aer_mmd_serdes(params->bp, phy);
|
|
|
|
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
@@ -2076,7 +2234,7 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
|
|
vars->phy_flags &= ~PHY_SGMII_FLAG;
|
|
vars->phy_flags &= ~PHY_SGMII_FLAG;
|
|
|
|
|
|
bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
|
|
bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
|
|
- bnx2x_set_aer_mmd(params, phy);
|
|
|
|
|
|
+ bnx2x_set_aer_mmd_xgxs(params, phy);
|
|
bnx2x_set_master_ln(params, phy);
|
|
bnx2x_set_master_ln(params, phy);
|
|
|
|
|
|
rc = bnx2x_reset_unicore(params, phy, 0);
|
|
rc = bnx2x_reset_unicore(params, phy, 0);
|
|
@@ -2084,7 +2242,7 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
|
|
if (rc != 0)
|
|
if (rc != 0)
|
|
return rc;
|
|
return rc;
|
|
|
|
|
|
- bnx2x_set_aer_mmd(params, phy);
|
|
|
|
|
|
+ bnx2x_set_aer_mmd_xgxs(params, phy);
|
|
|
|
|
|
/* setting the masterLn_def again after the reset */
|
|
/* setting the masterLn_def again after the reset */
|
|
bnx2x_set_master_ln(params, phy);
|
|
bnx2x_set_master_ln(params, phy);
|
|
@@ -2358,7 +2516,7 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
|
|
0x6041);
|
|
0x6041);
|
|
msleep(200);
|
|
msleep(200);
|
|
/* set aer mmd back */
|
|
/* set aer mmd back */
|
|
- bnx2x_set_aer_mmd(params, phy);
|
|
|
|
|
|
+ bnx2x_set_aer_mmd_xgxs(params, phy);
|
|
|
|
|
|
/* and md_devad */
|
|
/* and md_devad */
|
|
REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
|
|
REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
|
|
@@ -2721,7 +2879,10 @@ static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
|
|
struct bnx2x *bp = params->bp;
|
|
struct bnx2x *bp = params->bp;
|
|
u8 gpio_port;
|
|
u8 gpio_port;
|
|
/* HW reset */
|
|
/* HW reset */
|
|
- gpio_port = params->port;
|
|
|
|
|
|
+ if (CHIP_IS_E2(bp))
|
|
|
|
+ gpio_port = BP_PATH(bp);
|
|
|
|
+ else
|
|
|
|
+ gpio_port = params->port;
|
|
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
|
|
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
|
|
MISC_REGISTERS_GPIO_OUTPUT_LOW,
|
|
MISC_REGISTERS_GPIO_OUTPUT_LOW,
|
|
gpio_port);
|
|
gpio_port);
|
|
@@ -2799,8 +2960,9 @@ static u8 bnx2x_update_link_up(struct link_params *params,
|
|
}
|
|
}
|
|
|
|
|
|
/* PBF - link up */
|
|
/* PBF - link up */
|
|
- rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
|
|
|
|
- vars->line_speed);
|
|
|
|
|
|
+ if (!(CHIP_IS_E2(bp)))
|
|
|
|
+ rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
|
|
|
|
+ vars->line_speed);
|
|
|
|
|
|
/* disable drain */
|
|
/* disable drain */
|
|
REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
|
|
REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
|
|
@@ -3443,7 +3605,10 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy,
|
|
u8 gpio_port;
|
|
u8 gpio_port;
|
|
DP(NETIF_MSG_LINK, "Init 8073\n");
|
|
DP(NETIF_MSG_LINK, "Init 8073\n");
|
|
|
|
|
|
- gpio_port = params->port;
|
|
|
|
|
|
+ if (CHIP_IS_E2(bp))
|
|
|
|
+ gpio_port = BP_PATH(bp);
|
|
|
|
+ else
|
|
|
|
+ gpio_port = params->port;
|
|
/* Restore normal power mode*/
|
|
/* Restore normal power mode*/
|
|
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
|
|
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
|
|
MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
|
|
MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
|
|
@@ -3680,7 +3845,10 @@ static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
|
|
{
|
|
{
|
|
struct bnx2x *bp = params->bp;
|
|
struct bnx2x *bp = params->bp;
|
|
u8 gpio_port;
|
|
u8 gpio_port;
|
|
- gpio_port = params->port;
|
|
|
|
|
|
+ if (CHIP_IS_E2(bp))
|
|
|
|
+ gpio_port = BP_PATH(bp);
|
|
|
|
+ else
|
|
|
|
+ gpio_port = params->port;
|
|
DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
|
|
DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
|
|
gpio_port);
|
|
gpio_port);
|
|
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
|
|
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
|
|
@@ -6371,7 +6539,10 @@ static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
|
|
phy->mdio_ctrl = bnx2x_get_emac_base(bp,
|
|
phy->mdio_ctrl = bnx2x_get_emac_base(bp,
|
|
SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
|
|
SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
|
|
port);
|
|
port);
|
|
- phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
|
|
|
|
|
|
+ if (CHIP_IS_E2(bp))
|
|
|
|
+ phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
|
|
|
|
+ else
|
|
|
|
+ phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
|
|
|
|
|
|
DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
|
|
DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
|
|
port, phy->addr, phy->mdio_ctrl);
|
|
port, phy->addr, phy->mdio_ctrl);
|
|
@@ -6742,7 +6913,9 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
|
|
}
|
|
}
|
|
|
|
|
|
bnx2x_emac_enable(params, vars, 0);
|
|
bnx2x_emac_enable(params, vars, 0);
|
|
- bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
|
|
|
|
|
|
+ if (!(CHIP_IS_E2(bp)))
|
|
|
|
+ bnx2x_pbf_update(params, vars->flow_ctrl,
|
|
|
|
+ vars->line_speed);
|
|
/* disable drain */
|
|
/* 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);
|
|
|
|
|
|
@@ -6932,18 +7105,34 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
|
|
/****************************************************************************/
|
|
/****************************************************************************/
|
|
/* Common function */
|
|
/* Common function */
|
|
/****************************************************************************/
|
|
/****************************************************************************/
|
|
-static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base, u8 phy_index)
|
|
|
|
|
|
+static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp,
|
|
|
|
+ u32 shmem_base_path[],
|
|
|
|
+ u32 shmem2_base_path[], u8 phy_index,
|
|
|
|
+ u32 chip_id)
|
|
{
|
|
{
|
|
struct bnx2x_phy phy[PORT_MAX];
|
|
struct bnx2x_phy phy[PORT_MAX];
|
|
struct bnx2x_phy *phy_blk[PORT_MAX];
|
|
struct bnx2x_phy *phy_blk[PORT_MAX];
|
|
u16 val;
|
|
u16 val;
|
|
s8 port;
|
|
s8 port;
|
|
|
|
+ s8 port_of_path = 0;
|
|
|
|
|
|
/* PART1 - Reset both phys */
|
|
/* PART1 - Reset both phys */
|
|
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
|
|
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
|
|
|
|
+ u32 shmem_base, shmem2_base;
|
|
|
|
+ /* In E2, same phy is using for port0 of the two paths */
|
|
|
|
+ if (CHIP_IS_E2(bp)) {
|
|
|
|
+ shmem_base = shmem_base_path[port];
|
|
|
|
+ shmem2_base = shmem2_base_path[port];
|
|
|
|
+ port_of_path = 0;
|
|
|
|
+ } else {
|
|
|
|
+ shmem_base = shmem_base_path[0];
|
|
|
|
+ shmem2_base = shmem2_base_path[0];
|
|
|
|
+ port_of_path = port;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* Extract the ext phy address for the port */
|
|
/* Extract the ext phy address for the port */
|
|
if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
|
|
if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
|
|
- port, &phy[port]) !=
|
|
|
|
|
|
+ port_of_path, &phy[port]) !=
|
|
0) {
|
|
0) {
|
|
DP(NETIF_MSG_LINK, "populate_phy failed\n");
|
|
DP(NETIF_MSG_LINK, "populate_phy failed\n");
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
@@ -6981,9 +7170,15 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem
|
|
/* PART2 - Download firmware to both phys */
|
|
/* PART2 - Download firmware to both phys */
|
|
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
|
|
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
|
|
u16 fw_ver1;
|
|
u16 fw_ver1;
|
|
|
|
+ if (CHIP_IS_E2(bp))
|
|
|
|
+ port_of_path = 0;
|
|
|
|
+ else
|
|
|
|
+ port_of_path = port;
|
|
|
|
|
|
|
|
+ DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
|
|
|
|
+ phy_blk[port]->addr);
|
|
bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
|
|
bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
|
|
- port);
|
|
|
|
|
|
+ port_of_path);
|
|
|
|
|
|
bnx2x_cl45_read(bp, phy_blk[port],
|
|
bnx2x_cl45_read(bp, phy_blk[port],
|
|
MDIO_PMA_DEVAD,
|
|
MDIO_PMA_DEVAD,
|
|
@@ -7039,9 +7234,10 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base, u32 shmem
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
-
|
|
|
|
-static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base,
|
|
|
|
- u32 shmem2_base, u8 phy_index)
|
|
|
|
|
|
+static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp,
|
|
|
|
+ u32 shmem_base_path[],
|
|
|
|
+ u32 shmem2_base_path[], u8 phy_index,
|
|
|
|
+ u32 chip_id)
|
|
{
|
|
{
|
|
u32 val;
|
|
u32 val;
|
|
s8 port;
|
|
s8 port;
|
|
@@ -7056,6 +7252,16 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base,
|
|
bnx2x_ext_phy_hw_reset(bp, 1);
|
|
bnx2x_ext_phy_hw_reset(bp, 1);
|
|
msleep(5);
|
|
msleep(5);
|
|
for (port = 0; port < PORT_MAX; port++) {
|
|
for (port = 0; port < PORT_MAX; port++) {
|
|
|
|
+ u32 shmem_base, shmem2_base;
|
|
|
|
+
|
|
|
|
+ /* In E2, same phy is using for port0 of the two paths */
|
|
|
|
+ if (CHIP_IS_E2(bp)) {
|
|
|
|
+ shmem_base = shmem_base_path[port];
|
|
|
|
+ shmem2_base = shmem2_base_path[port];
|
|
|
|
+ } else {
|
|
|
|
+ shmem_base = shmem_base_path[0];
|
|
|
|
+ shmem2_base = shmem2_base_path[0];
|
|
|
|
+ }
|
|
/* Extract the ext phy address for the port */
|
|
/* Extract the ext phy address for the port */
|
|
if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
|
|
if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
|
|
port, &phy) !=
|
|
port, &phy) !=
|
|
@@ -7077,14 +7283,16 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base,
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
-static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base,
|
|
|
|
- u32 shmem2_base, u8 phy_index)
|
|
|
|
|
|
+static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp,
|
|
|
|
+ u32 shmem_base_path[],
|
|
|
|
+ u32 shmem2_base_path[], u8 phy_index,
|
|
|
|
+ u32 chip_id)
|
|
{
|
|
{
|
|
s8 port;
|
|
s8 port;
|
|
u32 swap_val, swap_override;
|
|
u32 swap_val, swap_override;
|
|
struct bnx2x_phy phy[PORT_MAX];
|
|
struct bnx2x_phy phy[PORT_MAX];
|
|
struct bnx2x_phy *phy_blk[PORT_MAX];
|
|
struct bnx2x_phy *phy_blk[PORT_MAX];
|
|
- DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n");
|
|
|
|
|
|
+ s8 port_of_path;
|
|
swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
|
|
swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
|
|
swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
|
|
swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
|
|
|
|
|
|
@@ -7099,19 +7307,33 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base,
|
|
|
|
|
|
/* PART1 - Reset both phys */
|
|
/* PART1 - Reset both phys */
|
|
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
|
|
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
|
|
|
|
+ u32 shmem_base, shmem2_base;
|
|
|
|
+
|
|
|
|
+ /* In E2, same phy is using for port0 of the two paths */
|
|
|
|
+ if (CHIP_IS_E2(bp)) {
|
|
|
|
+ shmem_base = shmem_base_path[port];
|
|
|
|
+ shmem2_base = shmem2_base_path[port];
|
|
|
|
+ port_of_path = 0;
|
|
|
|
+ } else {
|
|
|
|
+ shmem_base = shmem_base_path[0];
|
|
|
|
+ shmem2_base = shmem2_base_path[0];
|
|
|
|
+ port_of_path = port;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* Extract the ext phy address for the port */
|
|
/* Extract the ext phy address for the port */
|
|
if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
|
|
if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
|
|
- port, &phy[port]) !=
|
|
|
|
|
|
+ port_of_path, &phy[port]) !=
|
|
0) {
|
|
0) {
|
|
DP(NETIF_MSG_LINK, "populate phy failed\n");
|
|
DP(NETIF_MSG_LINK, "populate phy failed\n");
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
/* disable attentions */
|
|
/* disable attentions */
|
|
- bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
|
|
|
|
- (NIG_MASK_XGXS0_LINK_STATUS |
|
|
|
|
- NIG_MASK_XGXS0_LINK10G |
|
|
|
|
- NIG_MASK_SERDES0_LINK_STATUS |
|
|
|
|
- NIG_MASK_MI_INT));
|
|
|
|
|
|
+ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
|
|
|
|
+ port_of_path*4,
|
|
|
|
+ (NIG_MASK_XGXS0_LINK_STATUS |
|
|
|
|
+ NIG_MASK_XGXS0_LINK10G |
|
|
|
|
+ NIG_MASK_SERDES0_LINK_STATUS |
|
|
|
|
+ NIG_MASK_MI_INT));
|
|
|
|
|
|
|
|
|
|
/* Reset the phy */
|
|
/* Reset the phy */
|
|
@@ -7133,9 +7355,14 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base,
|
|
/* PART2 - Download firmware to both phys */
|
|
/* PART2 - Download firmware to both phys */
|
|
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
|
|
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
|
|
u16 fw_ver1;
|
|
u16 fw_ver1;
|
|
-
|
|
|
|
|
|
+ if (CHIP_IS_E2(bp))
|
|
|
|
+ port_of_path = 0;
|
|
|
|
+ else
|
|
|
|
+ port_of_path = port;
|
|
|
|
+ DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
|
|
|
|
+ phy_blk[port]->addr);
|
|
bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
|
|
bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
|
|
- port);
|
|
|
|
|
|
+ port_of_path);
|
|
bnx2x_cl45_read(bp, phy_blk[port],
|
|
bnx2x_cl45_read(bp, phy_blk[port],
|
|
MDIO_PMA_DEVAD,
|
|
MDIO_PMA_DEVAD,
|
|
MDIO_PMA_REG_ROM_VER1, &fw_ver1);
|
|
MDIO_PMA_REG_ROM_VER1, &fw_ver1);
|
|
@@ -7151,29 +7378,32 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base,
|
|
|
|
- u32 shmem2_base, u8 phy_index,
|
|
|
|
- u32 ext_phy_type)
|
|
|
|
|
|
+static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
|
|
|
|
+ u32 shmem2_base_path[], u8 phy_index,
|
|
|
|
+ u32 ext_phy_type, u32 chip_id)
|
|
{
|
|
{
|
|
u8 rc = 0;
|
|
u8 rc = 0;
|
|
|
|
|
|
switch (ext_phy_type) {
|
|
switch (ext_phy_type) {
|
|
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
|
|
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
|
|
- rc = bnx2x_8073_common_init_phy(bp, shmem_base,
|
|
|
|
- shmem2_base, phy_index);
|
|
|
|
|
|
+ rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
|
|
|
|
+ shmem2_base_path,
|
|
|
|
+ phy_index, chip_id);
|
|
break;
|
|
break;
|
|
|
|
|
|
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
|
|
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
|
|
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
|
|
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
|
|
- rc = bnx2x_8727_common_init_phy(bp, shmem_base,
|
|
|
|
- shmem2_base, phy_index);
|
|
|
|
|
|
+ rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
|
|
|
|
+ shmem2_base_path,
|
|
|
|
+ phy_index, chip_id);
|
|
break;
|
|
break;
|
|
|
|
|
|
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
|
|
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
|
|
/* GPIO1 affects both ports, so there's need to pull
|
|
/* GPIO1 affects both ports, so there's need to pull
|
|
it for single port alone */
|
|
it for single port alone */
|
|
- rc = bnx2x_8726_common_init_phy(bp, shmem_base,
|
|
|
|
- shmem2_base, phy_index);
|
|
|
|
|
|
+ rc = bnx2x_8726_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;
|
|
@@ -7188,8 +7418,8 @@ static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base,
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|
|
-u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base,
|
|
|
|
- u32 shmem2_base)
|
|
|
|
|
|
+u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
|
|
|
|
+ u32 shmem2_base_path[], u32 chip_id)
|
|
{
|
|
{
|
|
u8 rc = 0;
|
|
u8 rc = 0;
|
|
u8 phy_index;
|
|
u8 phy_index;
|
|
@@ -7203,12 +7433,13 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base,
|
|
for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
|
|
for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
|
|
phy_index++) {
|
|
phy_index++) {
|
|
ext_phy_config = bnx2x_get_ext_phy_config(bp,
|
|
ext_phy_config = bnx2x_get_ext_phy_config(bp,
|
|
- shmem_base,
|
|
|
|
|
|
+ shmem_base_path[0],
|
|
phy_index, 0);
|
|
phy_index, 0);
|
|
ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
|
|
ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
|
|
- rc |= bnx2x_ext_phy_common_init(bp, shmem_base,
|
|
|
|
- shmem2_base,
|
|
|
|
- phy_index, ext_phy_type);
|
|
|
|
|
|
+ rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
|
|
|
|
+ shmem2_base_path,
|
|
|
|
+ phy_index, ext_phy_type,
|
|
|
|
+ chip_id);
|
|
}
|
|
}
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|