|
@@ -1305,6 +1305,94 @@ int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+/******************************************************************/
|
|
|
|
+/* EEE section */
|
|
|
|
+/******************************************************************/
|
|
|
|
+static u8 bnx2x_eee_has_cap(struct link_params *params)
|
|
|
|
+{
|
|
|
|
+ struct bnx2x *bp = params->bp;
|
|
|
|
+
|
|
|
|
+ if (REG_RD(bp, params->shmem2_base) <=
|
|
|
|
+ offsetof(struct shmem2_region, eee_status[params->port]))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int bnx2x_eee_nvram_to_time(u32 nvram_mode, u32 *idle_timer)
|
|
|
|
+{
|
|
|
|
+ switch (nvram_mode) {
|
|
|
|
+ case PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED:
|
|
|
|
+ *idle_timer = EEE_MODE_NVRAM_BALANCED_TIME;
|
|
|
|
+ break;
|
|
|
|
+ case PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE:
|
|
|
|
+ *idle_timer = EEE_MODE_NVRAM_AGGRESSIVE_TIME;
|
|
|
|
+ break;
|
|
|
|
+ case PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY:
|
|
|
|
+ *idle_timer = EEE_MODE_NVRAM_LATENCY_TIME;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ *idle_timer = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int bnx2x_eee_time_to_nvram(u32 idle_timer, u32 *nvram_mode)
|
|
|
|
+{
|
|
|
|
+ switch (idle_timer) {
|
|
|
|
+ case EEE_MODE_NVRAM_BALANCED_TIME:
|
|
|
|
+ *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED;
|
|
|
|
+ break;
|
|
|
|
+ case EEE_MODE_NVRAM_AGGRESSIVE_TIME:
|
|
|
|
+ *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE;
|
|
|
|
+ break;
|
|
|
|
+ case EEE_MODE_NVRAM_LATENCY_TIME:
|
|
|
|
+ *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static u32 bnx2x_eee_calc_timer(struct link_params *params)
|
|
|
|
+{
|
|
|
|
+ u32 eee_mode, eee_idle;
|
|
|
|
+ struct bnx2x *bp = params->bp;
|
|
|
|
+
|
|
|
|
+ if (params->eee_mode & EEE_MODE_OVERRIDE_NVRAM) {
|
|
|
|
+ if (params->eee_mode & EEE_MODE_OUTPUT_TIME) {
|
|
|
|
+ /* time value in eee_mode --> used directly*/
|
|
|
|
+ eee_idle = params->eee_mode & EEE_MODE_TIMER_MASK;
|
|
|
|
+ } else {
|
|
|
|
+ /* hsi value in eee_mode --> time */
|
|
|
|
+ if (bnx2x_eee_nvram_to_time(params->eee_mode &
|
|
|
|
+ EEE_MODE_NVRAM_MASK,
|
|
|
|
+ &eee_idle))
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ /* hsi values in nvram --> time*/
|
|
|
|
+ eee_mode = ((REG_RD(bp, params->shmem_base +
|
|
|
|
+ offsetof(struct shmem_region, dev_info.
|
|
|
|
+ port_feature_config[params->port].
|
|
|
|
+ eee_power_mode)) &
|
|
|
|
+ PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >>
|
|
|
|
+ PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT);
|
|
|
|
+
|
|
|
|
+ if (bnx2x_eee_nvram_to_time(eee_mode, &eee_idle))
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return eee_idle;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
/******************************************************************/
|
|
/******************************************************************/
|
|
/* PFC section */
|
|
/* PFC section */
|
|
/******************************************************************/
|
|
/******************************************************************/
|
|
@@ -1729,6 +1817,14 @@ static int bnx2x_xmac_enable(struct link_params *params,
|
|
/* update PFC */
|
|
/* update PFC */
|
|
bnx2x_update_pfc_xmac(params, vars, 0);
|
|
bnx2x_update_pfc_xmac(params, vars, 0);
|
|
|
|
|
|
|
|
+ if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
|
|
|
|
+ DP(NETIF_MSG_LINK, "Setting XMAC for EEE\n");
|
|
|
|
+ REG_WR(bp, xmac_base + XMAC_REG_EEE_TIMERS_HI, 0x1380008);
|
|
|
|
+ REG_WR(bp, xmac_base + XMAC_REG_EEE_CTRL, 0x1);
|
|
|
|
+ } else {
|
|
|
|
+ REG_WR(bp, xmac_base + XMAC_REG_EEE_CTRL, 0x0);
|
|
|
|
+ }
|
|
|
|
+
|
|
/* Enable TX and RX */
|
|
/* Enable TX and RX */
|
|
val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
|
|
val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
|
|
|
|
|
|
@@ -2439,6 +2535,16 @@ static void bnx2x_update_mng(struct link_params *params, u32 link_status)
|
|
port_mb[params->port].link_status), link_status);
|
|
port_mb[params->port].link_status), link_status);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void bnx2x_update_mng_eee(struct link_params *params, u32 eee_status)
|
|
|
|
+{
|
|
|
|
+ struct bnx2x *bp = params->bp;
|
|
|
|
+
|
|
|
|
+ if (bnx2x_eee_has_cap(params))
|
|
|
|
+ REG_WR(bp, params->shmem2_base +
|
|
|
|
+ offsetof(struct shmem2_region,
|
|
|
|
+ eee_status[params->port]), eee_status);
|
|
|
|
+}
|
|
|
|
+
|
|
static void bnx2x_update_pfc_nig(struct link_params *params,
|
|
static void bnx2x_update_pfc_nig(struct link_params *params,
|
|
struct link_vars *vars,
|
|
struct link_vars *vars,
|
|
struct bnx2x_nig_brb_pfc_port_params *nig_params)
|
|
struct bnx2x_nig_brb_pfc_port_params *nig_params)
|
|
@@ -3950,6 +4056,20 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
|
|
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
|
|
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
|
|
MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080);
|
|
MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080);
|
|
|
|
|
|
|
|
+ /* Enable LPI pass through */
|
|
|
|
+ if ((params->eee_mode & EEE_MODE_ADV_LPI) &&
|
|
|
|
+ (phy->flags & FLAGS_EEE_10GBT) &&
|
|
|
|
+ (!(params->eee_mode & EEE_MODE_ENABLE_LPI) ||
|
|
|
|
+ bnx2x_eee_calc_timer(params)) &&
|
|
|
|
+ (params->req_duplex[bnx2x_phy_selection(params)] == DUPLEX_FULL)) {
|
|
|
|
+ DP(NETIF_MSG_LINK, "Configure WC for LPI pass through\n");
|
|
|
|
+ bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
|
|
|
|
+ MDIO_WC_REG_EEE_COMBO_CONTROL0,
|
|
|
|
+ 0x7c);
|
|
|
|
+ bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
|
|
|
|
+ MDIO_WC_REG_DIGITAL4_MISC5, 0xc000);
|
|
|
|
+ }
|
|
|
|
+
|
|
/* 10G XFI Full Duplex */
|
|
/* 10G XFI Full Duplex */
|
|
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
|
|
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
|
|
MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
|
|
MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
|
|
@@ -6462,6 +6582,15 @@ static int bnx2x_update_link_down(struct link_params *params,
|
|
(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
|
|
(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
|
|
}
|
|
}
|
|
if (CHIP_IS_E3(bp)) {
|
|
if (CHIP_IS_E3(bp)) {
|
|
|
|
+ REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2),
|
|
|
|
+ 0);
|
|
|
|
+ REG_WR(bp, MISC_REG_CPMU_LP_DR_ENABLE, 0);
|
|
|
|
+ REG_WR(bp, MISC_REG_CPMU_LP_MASK_ENT_P0 + (params->port << 2),
|
|
|
|
+ 0);
|
|
|
|
+ vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
|
|
|
|
+ SHMEM_EEE_ACTIVE_BIT);
|
|
|
|
+
|
|
|
|
+ bnx2x_update_mng_eee(params, vars->eee_status);
|
|
bnx2x_xmac_disable(params);
|
|
bnx2x_xmac_disable(params);
|
|
bnx2x_umac_disable(params);
|
|
bnx2x_umac_disable(params);
|
|
}
|
|
}
|
|
@@ -6501,6 +6630,16 @@ static int bnx2x_update_link_up(struct link_params *params,
|
|
bnx2x_umac_enable(params, vars, 0);
|
|
bnx2x_umac_enable(params, vars, 0);
|
|
bnx2x_set_led(params, vars,
|
|
bnx2x_set_led(params, vars,
|
|
LED_MODE_OPER, vars->line_speed);
|
|
LED_MODE_OPER, vars->line_speed);
|
|
|
|
+
|
|
|
|
+ if ((vars->eee_status & SHMEM_EEE_ACTIVE_BIT) &&
|
|
|
|
+ (vars->eee_status & SHMEM_EEE_LPI_REQUESTED_BIT)) {
|
|
|
|
+ DP(NETIF_MSG_LINK, "Enabling LPI assertion\n");
|
|
|
|
+ REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 +
|
|
|
|
+ (params->port << 2), 1);
|
|
|
|
+ REG_WR(bp, MISC_REG_CPMU_LP_DR_ENABLE, 1);
|
|
|
|
+ REG_WR(bp, MISC_REG_CPMU_LP_MASK_ENT_P0 +
|
|
|
|
+ (params->port << 2), 0xfc20);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
if ((CHIP_IS_E1x(bp) ||
|
|
if ((CHIP_IS_E1x(bp) ||
|
|
CHIP_IS_E2(bp))) {
|
|
CHIP_IS_E2(bp))) {
|
|
@@ -6538,7 +6677,7 @@ static int bnx2x_update_link_up(struct link_params *params,
|
|
|
|
|
|
/* update shared memory */
|
|
/* update shared memory */
|
|
bnx2x_update_mng(params, vars->link_status);
|
|
bnx2x_update_mng(params, vars->link_status);
|
|
-
|
|
|
|
|
|
+ bnx2x_update_mng_eee(params, vars->eee_status);
|
|
/* Check remote fault */
|
|
/* Check remote fault */
|
|
for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
|
|
for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
|
|
if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) {
|
|
if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) {
|
|
@@ -6582,6 +6721,8 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
|
|
phy_vars[phy_index].phy_link_up = 0;
|
|
phy_vars[phy_index].phy_link_up = 0;
|
|
phy_vars[phy_index].link_up = 0;
|
|
phy_vars[phy_index].link_up = 0;
|
|
phy_vars[phy_index].fault_detected = 0;
|
|
phy_vars[phy_index].fault_detected = 0;
|
|
|
|
+ /* different consideration, since vars holds inner state */
|
|
|
|
+ phy_vars[phy_index].eee_status = vars->eee_status;
|
|
}
|
|
}
|
|
|
|
|
|
if (USES_WARPCORE(bp))
|
|
if (USES_WARPCORE(bp))
|
|
@@ -6711,6 +6852,9 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
|
|
vars->link_status |= LINK_STATUS_SERDES_LINK;
|
|
vars->link_status |= LINK_STATUS_SERDES_LINK;
|
|
else
|
|
else
|
|
vars->link_status &= ~LINK_STATUS_SERDES_LINK;
|
|
vars->link_status &= ~LINK_STATUS_SERDES_LINK;
|
|
|
|
+
|
|
|
|
+ vars->eee_status = phy_vars[active_external_phy].eee_status;
|
|
|
|
+
|
|
DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
|
|
DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
|
|
active_external_phy);
|
|
active_external_phy);
|
|
}
|
|
}
|
|
@@ -9579,9 +9723,9 @@ static int bnx2x_8481_config_init(struct bnx2x_phy *phy,
|
|
static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy,
|
|
static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy,
|
|
struct link_params *params,
|
|
struct link_params *params,
|
|
u16 fw_cmd,
|
|
u16 fw_cmd,
|
|
- u16 cmd_args[])
|
|
|
|
|
|
+ u16 cmd_args[], int argc)
|
|
{
|
|
{
|
|
- u32 idx;
|
|
|
|
|
|
+ int idx;
|
|
u16 val;
|
|
u16 val;
|
|
struct bnx2x *bp = params->bp;
|
|
struct bnx2x *bp = params->bp;
|
|
/* Write CMD_OPEN_OVERRIDE to STATUS reg */
|
|
/* Write CMD_OPEN_OVERRIDE to STATUS reg */
|
|
@@ -9601,7 +9745,7 @@ static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy,
|
|
}
|
|
}
|
|
|
|
|
|
/* Prepare argument(s) and issue command */
|
|
/* Prepare argument(s) and issue command */
|
|
- for (idx = 0; idx < PHY84833_CMDHDLR_MAX_ARGS; idx++) {
|
|
|
|
|
|
+ for (idx = 0; idx < argc; idx++) {
|
|
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
|
|
bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
|
|
MDIO_84833_CMD_HDLR_DATA1 + idx,
|
|
MDIO_84833_CMD_HDLR_DATA1 + idx,
|
|
cmd_args[idx]);
|
|
cmd_args[idx]);
|
|
@@ -9622,7 +9766,7 @@ static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy,
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
/* Gather returning data */
|
|
/* Gather returning data */
|
|
- for (idx = 0; idx < PHY84833_CMDHDLR_MAX_ARGS; idx++) {
|
|
|
|
|
|
+ for (idx = 0; idx < argc; idx++) {
|
|
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
|
|
bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
|
|
MDIO_84833_CMD_HDLR_DATA1 + idx,
|
|
MDIO_84833_CMD_HDLR_DATA1 + idx,
|
|
&cmd_args[idx]);
|
|
&cmd_args[idx]);
|
|
@@ -9656,7 +9800,7 @@ static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy,
|
|
data[1] = (u16)pair_swap;
|
|
data[1] = (u16)pair_swap;
|
|
|
|
|
|
status = bnx2x_84833_cmd_hdlr(phy, params,
|
|
status = bnx2x_84833_cmd_hdlr(phy, params,
|
|
- PHY84833_CMD_SET_PAIR_SWAP, data);
|
|
|
|
|
|
+ PHY84833_CMD_SET_PAIR_SWAP, data, PHY84833_CMDHDLR_MAX_ARGS);
|
|
if (status == 0)
|
|
if (status == 0)
|
|
DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]);
|
|
DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]);
|
|
|
|
|
|
@@ -9734,6 +9878,95 @@ static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int bnx2x_8483x_eee_timers(struct link_params *params,
|
|
|
|
+ struct link_vars *vars)
|
|
|
|
+{
|
|
|
|
+ u32 eee_idle = 0, eee_mode;
|
|
|
|
+ struct bnx2x *bp = params->bp;
|
|
|
|
+
|
|
|
|
+ eee_idle = bnx2x_eee_calc_timer(params);
|
|
|
|
+
|
|
|
|
+ if (eee_idle) {
|
|
|
|
+ REG_WR(bp, MISC_REG_CPMU_LP_IDLE_THR_P0 + (params->port << 2),
|
|
|
|
+ eee_idle);
|
|
|
|
+ } else if ((params->eee_mode & EEE_MODE_ENABLE_LPI) &&
|
|
|
|
+ (params->eee_mode & EEE_MODE_OVERRIDE_NVRAM) &&
|
|
|
|
+ (params->eee_mode & EEE_MODE_OUTPUT_TIME)) {
|
|
|
|
+ DP(NETIF_MSG_LINK, "Error: Tx LPI is enabled with timer 0\n");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ vars->eee_status &= ~(SHMEM_EEE_TIMER_MASK | SHMEM_EEE_TIME_OUTPUT_BIT);
|
|
|
|
+ if (params->eee_mode & EEE_MODE_OUTPUT_TIME) {
|
|
|
|
+ /* eee_idle in 1u --> eee_status in 16u */
|
|
|
|
+ eee_idle >>= 4;
|
|
|
|
+ vars->eee_status |= (eee_idle & SHMEM_EEE_TIMER_MASK) |
|
|
|
|
+ SHMEM_EEE_TIME_OUTPUT_BIT;
|
|
|
|
+ } else {
|
|
|
|
+ if (bnx2x_eee_time_to_nvram(eee_idle, &eee_mode))
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ vars->eee_status |= eee_mode;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int bnx2x_8483x_disable_eee(struct bnx2x_phy *phy,
|
|
|
|
+ struct link_params *params,
|
|
|
|
+ struct link_vars *vars)
|
|
|
|
+{
|
|
|
|
+ int rc;
|
|
|
|
+ struct bnx2x *bp = params->bp;
|
|
|
|
+ u16 cmd_args = 0;
|
|
|
|
+
|
|
|
|
+ DP(NETIF_MSG_LINK, "Don't Advertise 10GBase-T EEE\n");
|
|
|
|
+
|
|
|
|
+ /* Make Certain LPI is disabled */
|
|
|
|
+ REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), 0);
|
|
|
|
+ REG_WR(bp, MISC_REG_CPMU_LP_DR_ENABLE, 0);
|
|
|
|
+
|
|
|
|
+ /* Prevent Phy from working in EEE and advertising it */
|
|
|
|
+ rc = bnx2x_84833_cmd_hdlr(phy, params,
|
|
|
|
+ PHY84833_CMD_SET_EEE_MODE, &cmd_args, 1);
|
|
|
|
+ if (rc != 0) {
|
|
|
|
+ DP(NETIF_MSG_LINK, "EEE disable failed.\n");
|
|
|
|
+ return rc;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0);
|
|
|
|
+ vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int bnx2x_8483x_enable_eee(struct bnx2x_phy *phy,
|
|
|
|
+ struct link_params *params,
|
|
|
|
+ struct link_vars *vars)
|
|
|
|
+{
|
|
|
|
+ int rc;
|
|
|
|
+ struct bnx2x *bp = params->bp;
|
|
|
|
+ u16 cmd_args = 1;
|
|
|
|
+
|
|
|
|
+ DP(NETIF_MSG_LINK, "Advertise 10GBase-T EEE\n");
|
|
|
|
+
|
|
|
|
+ rc = bnx2x_84833_cmd_hdlr(phy, params,
|
|
|
|
+ PHY84833_CMD_SET_EEE_MODE, &cmd_args, 1);
|
|
|
|
+ if (rc != 0) {
|
|
|
|
+ DP(NETIF_MSG_LINK, "EEE enable failed.\n");
|
|
|
|
+ return rc;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0x8);
|
|
|
|
+
|
|
|
|
+ /* Mask events preventing LPI generation */
|
|
|
|
+ REG_WR(bp, MISC_REG_CPMU_LP_MASK_EXT_P0 + (params->port << 2), 0xfc20);
|
|
|
|
+
|
|
|
|
+ vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK;
|
|
|
|
+ vars->eee_status |= (SHMEM_EEE_10G_ADV << SHMEM_EEE_ADV_STATUS_SHIFT);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
#define PHY84833_CONSTANT_LATENCY 1193
|
|
#define PHY84833_CONSTANT_LATENCY 1193
|
|
static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
|
|
static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
|
|
struct link_params *params,
|
|
struct link_params *params,
|
|
@@ -9833,7 +10066,8 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
|
|
cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1;
|
|
cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1;
|
|
cmd_args[3] = PHY84833_CONSTANT_LATENCY;
|
|
cmd_args[3] = PHY84833_CONSTANT_LATENCY;
|
|
rc = bnx2x_84833_cmd_hdlr(phy, params,
|
|
rc = bnx2x_84833_cmd_hdlr(phy, params,
|
|
- PHY84833_CMD_SET_EEE_MODE, cmd_args);
|
|
|
|
|
|
+ PHY84833_CMD_SET_EEE_MODE, cmd_args,
|
|
|
|
+ PHY84833_CMDHDLR_MAX_ARGS);
|
|
if (rc != 0)
|
|
if (rc != 0)
|
|
DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n");
|
|
DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n");
|
|
}
|
|
}
|
|
@@ -9858,6 +10092,48 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
|
|
MDIO_CTL_REG_84823_USER_CTRL_REG, val);
|
|
MDIO_CTL_REG_84823_USER_CTRL_REG, val);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
|
|
|
|
+ MDIO_84833_TOP_CFG_FW_REV, &val);
|
|
|
|
+
|
|
|
|
+ /* Configure EEE support */
|
|
|
|
+ if ((val >= MDIO_84833_TOP_CFG_FW_EEE) && bnx2x_eee_has_cap(params)) {
|
|
|
|
+ phy->flags |= FLAGS_EEE_10GBT;
|
|
|
|
+ vars->eee_status |= SHMEM_EEE_10G_ADV <<
|
|
|
|
+ SHMEM_EEE_SUPPORTED_SHIFT;
|
|
|
|
+ /* Propogate params' bits --> vars (for migration exposure) */
|
|
|
|
+ if (params->eee_mode & EEE_MODE_ENABLE_LPI)
|
|
|
|
+ vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT;
|
|
|
|
+ else
|
|
|
|
+ vars->eee_status &= ~SHMEM_EEE_LPI_REQUESTED_BIT;
|
|
|
|
+
|
|
|
|
+ if (params->eee_mode & EEE_MODE_ADV_LPI)
|
|
|
|
+ vars->eee_status |= SHMEM_EEE_REQUESTED_BIT;
|
|
|
|
+ else
|
|
|
|
+ vars->eee_status &= ~SHMEM_EEE_REQUESTED_BIT;
|
|
|
|
+
|
|
|
|
+ rc = bnx2x_8483x_eee_timers(params, vars);
|
|
|
|
+ if (rc != 0) {
|
|
|
|
+ DP(NETIF_MSG_LINK, "Failed to configure EEE timers\n");
|
|
|
|
+ bnx2x_8483x_disable_eee(phy, params, vars);
|
|
|
|
+ return rc;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ((params->req_duplex[actual_phy_selection] == DUPLEX_FULL) &&
|
|
|
|
+ (params->eee_mode & EEE_MODE_ADV_LPI) &&
|
|
|
|
+ (bnx2x_eee_calc_timer(params) ||
|
|
|
|
+ !(params->eee_mode & EEE_MODE_ENABLE_LPI)))
|
|
|
|
+ rc = bnx2x_8483x_enable_eee(phy, params, vars);
|
|
|
|
+ else
|
|
|
|
+ rc = bnx2x_8483x_disable_eee(phy, params, vars);
|
|
|
|
+ if (rc != 0) {
|
|
|
|
+ DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n");
|
|
|
|
+ return rc;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ phy->flags &= ~FLAGS_EEE_10GBT;
|
|
|
|
+ vars->eee_status &= ~SHMEM_EEE_SUPPORTED_MASK;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
|
|
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
|
|
/* Bring PHY out of super isolate mode as the final step. */
|
|
/* Bring PHY out of super isolate mode as the final step. */
|
|
bnx2x_cl45_read(bp, phy,
|
|
bnx2x_cl45_read(bp, phy,
|
|
@@ -9989,6 +10265,31 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
|
|
if (val & (1<<11))
|
|
if (val & (1<<11))
|
|
vars->link_status |=
|
|
vars->link_status |=
|
|
LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
|
|
LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
|
|
|
|
+
|
|
|
|
+ /* Determine if EEE was negotiated */
|
|
|
|
+ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
|
|
|
|
+ u32 eee_shmem = 0;
|
|
|
|
+
|
|
|
|
+ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
|
|
|
|
+ MDIO_AN_REG_EEE_ADV, &val1);
|
|
|
|
+ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
|
|
|
|
+ MDIO_AN_REG_LP_EEE_ADV, &val2);
|
|
|
|
+ if ((val1 & val2) & 0x8) {
|
|
|
|
+ DP(NETIF_MSG_LINK, "EEE negotiated\n");
|
|
|
|
+ vars->eee_status |= SHMEM_EEE_ACTIVE_BIT;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (val2 & 0x12)
|
|
|
|
+ eee_shmem |= SHMEM_EEE_100M_ADV;
|
|
|
|
+ if (val2 & 0x4)
|
|
|
|
+ eee_shmem |= SHMEM_EEE_1G_ADV;
|
|
|
|
+ if (val2 & 0x68)
|
|
|
|
+ eee_shmem |= SHMEM_EEE_10G_ADV;
|
|
|
|
+
|
|
|
|
+ vars->eee_status &= ~SHMEM_EEE_LP_ADV_STATUS_MASK;
|
|
|
|
+ vars->eee_status |= (eee_shmem <<
|
|
|
|
+ SHMEM_EEE_LP_ADV_STATUS_SHIFT);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
return link_up;
|
|
return link_up;
|
|
@@ -11243,7 +11544,8 @@ static struct bnx2x_phy phy_84833 = {
|
|
.def_md_devad = 0,
|
|
.def_md_devad = 0,
|
|
.flags = (FLAGS_FAN_FAILURE_DET_REQ |
|
|
.flags = (FLAGS_FAN_FAILURE_DET_REQ |
|
|
FLAGS_REARM_LATCH_SIGNAL |
|
|
FLAGS_REARM_LATCH_SIGNAL |
|
|
- FLAGS_TX_ERROR_CHECK),
|
|
|
|
|
|
+ FLAGS_TX_ERROR_CHECK |
|
|
|
|
+ FLAGS_EEE_10GBT),
|
|
.rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
|
|
.rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
|
|
.tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
|
|
.tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
|
|
.mdio_ctrl = 0,
|
|
.mdio_ctrl = 0,
|
|
@@ -12011,6 +12313,8 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
bnx2x_update_mng(params, vars->link_status);
|
|
bnx2x_update_mng(params, vars->link_status);
|
|
|
|
+
|
|
|
|
+ bnx2x_update_mng_eee(params, vars->eee_status);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -12023,6 +12327,9 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
|
|
/* disable attentions */
|
|
/* disable attentions */
|
|
vars->link_status = 0;
|
|
vars->link_status = 0;
|
|
bnx2x_update_mng(params, vars->link_status);
|
|
bnx2x_update_mng(params, vars->link_status);
|
|
|
|
+ vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
|
|
|
|
+ SHMEM_EEE_ACTIVE_BIT);
|
|
|
|
+ bnx2x_update_mng_eee(params, vars->eee_status);
|
|
bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
|
|
bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
|
|
(NIG_MASK_XGXS0_LINK_STATUS |
|
|
(NIG_MASK_XGXS0_LINK_STATUS |
|
|
NIG_MASK_XGXS0_LINK10G |
|
|
NIG_MASK_XGXS0_LINK10G |
|