aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x/bnx2x_link.c
diff options
context:
space:
mode:
authorYaniv Rosner <yanivr@broadcom.com>2011-07-04 21:07:05 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-05 07:21:40 -0400
commita89a1d4a738668ccb2270ac218cddd30f0bef2a0 (patch)
tree00ef3bbc9dff7babdf3864dcf4e98ca77cbd8d16 /drivers/net/bnx2x/bnx2x_link.c
parent0520e63acb387a265c2a6abbf51c44c67149cf37 (diff)
bnx2x: Add autogrEEEn support
Add autogrEEEn support on BCM84833 and 54618se, which allows to reduce power consumption. Signed-off-by: Yaniv Rosner <yanivr@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_link.c')
-rw-r--r--drivers/net/bnx2x/bnx2x_link.c115
1 files changed, 103 insertions, 12 deletions
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c
index d6684b38a26..03a2085bd51 100644
--- a/drivers/net/bnx2x/bnx2x_link.c
+++ b/drivers/net/bnx2x/bnx2x_link.c
@@ -9437,6 +9437,7 @@ static int bnx2x_84833_common_init_phy(struct bnx2x *bp,
9437 return 0; 9437 return 0;
9438} 9438}
9439 9439
9440#define PHY84833_CONSTANT_LATENCY 1193
9440static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, 9441static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
9441 struct link_params *params, 9442 struct link_params *params,
9442 struct link_vars *vars) 9443 struct link_vars *vars)
@@ -9445,7 +9446,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
9445 u8 port, initialize = 1; 9446 u8 port, initialize = 1;
9446 u16 val; 9447 u16 val;
9447 u16 temp; 9448 u16 temp;
9448 u32 actual_phy_selection, cms_enable; 9449 u32 actual_phy_selection, cms_enable, idx;
9449 int rc = 0; 9450 int rc = 0;
9450 9451
9451 msleep(1); 9452 msleep(1);
@@ -9537,24 +9538,86 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
9537 DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n", 9538 DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
9538 params->multi_phy_config, val); 9539 params->multi_phy_config, val);
9539 9540
9541 /* AutogrEEEn */
9542 if (params->feature_config_flags &
9543 FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
9544 /* Ensure that f/w is ready */
9545 for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
9546 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9547 MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
9548 if (val == PHY84833_CMD_OPEN_FOR_CMDS)
9549 break;
9550 usleep_range(1000, 1000);
9551 }
9552 if (idx >= PHY84833_HDSHK_WAIT) {
9553 DP(NETIF_MSG_LINK, "AutogrEEEn: FW not ready.\n");
9554 return -EINVAL;
9555 }
9556
9557 /* Select EEE mode */
9558 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9559 MDIO_84833_TOP_CFG_SCRATCH_REG3,
9560 0x2);
9561
9562 /* Set Idle and Latency */
9563 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9564 MDIO_84833_TOP_CFG_SCRATCH_REG4,
9565 PHY84833_CONSTANT_LATENCY + 1);
9566
9567 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9568 MDIO_84833_TOP_CFG_DATA3_REG,
9569 PHY84833_CONSTANT_LATENCY + 1);
9570
9571 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9572 MDIO_84833_TOP_CFG_DATA4_REG,
9573 PHY84833_CONSTANT_LATENCY);
9574
9575 /* Send EEE instruction to command register */
9576 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9577 MDIO_84833_TOP_CFG_SCRATCH_REG0,
9578 PHY84833_DIAG_CMD_SET_EEE_MODE);
9579
9580 /* Ensure that the command has completed */
9581 for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
9582 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9583 MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
9584 if ((val == PHY84833_CMD_COMPLETE_PASS) ||
9585 (val == PHY84833_CMD_COMPLETE_ERROR))
9586 break;
9587 usleep_range(1000, 1000);
9588 }
9589 if ((idx >= PHY84833_HDSHK_WAIT) ||
9590 (val == PHY84833_CMD_COMPLETE_ERROR)) {
9591 DP(NETIF_MSG_LINK, "AutogrEEEn: command failed.\n");
9592 return -EINVAL;
9593 }
9594
9595 /* Reset command handler */
9596 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9597 MDIO_84833_TOP_CFG_SCRATCH_REG2,
9598 PHY84833_CMD_CLEAR_COMPLETE);
9599 }
9600
9540 if (initialize) 9601 if (initialize)
9541 rc = bnx2x_848xx_cmn_config_init(phy, params, vars); 9602 rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
9542 else 9603 else
9543 bnx2x_save_848xx_spirom_version(phy, params); 9604 bnx2x_save_848xx_spirom_version(phy, params);
9544 cms_enable = REG_RD(bp, params->shmem_base + 9605 /* 84833 PHY has a better feature and doesn't need to support this. */
9606 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9607 cms_enable = REG_RD(bp, params->shmem_base +
9545 offsetof(struct shmem_region, 9608 offsetof(struct shmem_region,
9546 dev_info.port_hw_config[params->port].default_cfg)) & 9609 dev_info.port_hw_config[params->port].default_cfg)) &
9547 PORT_HW_CFG_ENABLE_CMS_MASK; 9610 PORT_HW_CFG_ENABLE_CMS_MASK;
9548 9611
9549 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 9612 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9550 MDIO_CTL_REG_84823_USER_CTRL_REG, &val); 9613 MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
9551 if (cms_enable) 9614 if (cms_enable)
9552 val |= MDIO_CTL_REG_84823_USER_CTRL_CMS; 9615 val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
9553 else 9616 else
9554 val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS; 9617 val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
9555 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, 9618 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9556 MDIO_CTL_REG_84823_USER_CTRL_REG, val); 9619 MDIO_CTL_REG_84823_USER_CTRL_REG, val);
9557 9620 }
9558 9621
9559 return rc; 9622 return rc;
9560} 9623}
@@ -10068,6 +10131,30 @@ static int bnx2x_54618se_config_init(struct bnx2x_phy *phy,
10068 DP(NETIF_MSG_LINK, "Setting 10M force\n"); 10131 DP(NETIF_MSG_LINK, "Setting 10M force\n");
10069 } 10132 }
10070 10133
10134 /* Check if we should turn on Auto-GrEEEn */
10135 bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &temp);
10136 if (temp == MDIO_REG_GPHY_ID_54618SE) {
10137 if (params->feature_config_flags &
10138 FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
10139 temp = 6;
10140 DP(NETIF_MSG_LINK, "Enabling Auto-GrEEEn\n");
10141 } else {
10142 temp = 0;
10143 DP(NETIF_MSG_LINK, "Disabling Auto-GrEEEn\n");
10144 }
10145 bnx2x_cl22_write(bp, phy,
10146 MDIO_REG_GPHY_CL45_ADDR_REG, MDIO_AN_DEVAD);
10147 bnx2x_cl22_write(bp, phy,
10148 MDIO_REG_GPHY_CL45_DATA_REG,
10149 MDIO_REG_GPHY_EEE_ADV);
10150 bnx2x_cl22_write(bp, phy,
10151 MDIO_REG_GPHY_CL45_ADDR_REG,
10152 (0x1 << 14) | MDIO_AN_DEVAD);
10153 bnx2x_cl22_write(bp, phy,
10154 MDIO_REG_GPHY_CL45_DATA_REG,
10155 temp);
10156 }
10157
10071 bnx2x_cl22_write(bp, phy, 10158 bnx2x_cl22_write(bp, phy,
10072 0x04, 10159 0x04,
10073 an_10_100_val | fc_val); 10160 an_10_100_val | fc_val);
@@ -11597,12 +11684,16 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
11597 bnx2x_set_led(params, vars, LED_MODE_OFF, 0); 11684 bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
11598 11685
11599 if (reset_ext_phy) { 11686 if (reset_ext_phy) {
11687 bnx2x_set_mdio_clk(bp, params->chip_id, port);
11600 for (phy_index = EXT_PHY1; phy_index < params->num_phys; 11688 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
11601 phy_index++) { 11689 phy_index++) {
11602 if (params->phy[phy_index].link_reset) 11690 if (params->phy[phy_index].link_reset) {
11691 bnx2x_set_aer_mmd(params,
11692 &params->phy[phy_index]);
11603 params->phy[phy_index].link_reset( 11693 params->phy[phy_index].link_reset(
11604 &params->phy[phy_index], 11694 &params->phy[phy_index],
11605 params); 11695 params);
11696 }
11606 if (params->phy[phy_index].flags & 11697 if (params->phy[phy_index].flags &
11607 FLAGS_REARM_LATCH_SIGNAL) 11698 FLAGS_REARM_LATCH_SIGNAL)
11608 clear_latch_ind = 1; 11699 clear_latch_ind = 1;