bnx2x: use native EEE instead of auto-greeen
authorYuval Mintz <yuvalmin@broadcom.com>
Mon, 10 Sep 2012 05:51:08 +0000 (05:51 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 10 Sep 2012 20:40:29 +0000 (16:40 -0400)
This patch enables boards with 54618SE phys and a sufficiently new
firmware to use native EEE instead of auto-greeen.

Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h

index 839ddd2519d3042566efc2766e9dc99786d252cb..c660afdbdf5636aae303ef189d4537e8ceafdc62 100644 (file)
@@ -1584,6 +1584,16 @@ static void bnx2x_umac_enable(struct link_params *params,
        REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
        udelay(50);
 
+       /* Configure UMAC for EEE */
+       if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
+               DP(NETIF_MSG_LINK, "configured UMAC for EEE\n");
+               REG_WR(bp, umac_base + UMAC_REG_UMAC_EEE_CTRL,
+                      UMAC_UMAC_EEE_CTRL_REG_EEE_EN);
+               REG_WR(bp, umac_base + UMAC_REG_EEE_WAKE_TIMER, 0x11);
+       } else {
+               REG_WR(bp, umac_base + UMAC_REG_UMAC_EEE_CTRL, 0x0);
+       }
+
        /* Set MAC address for source TX Pause/PFC frames (under SW reset) */
        REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR0,
               ((params->mac_addr[2] << 24) |
@@ -4263,6 +4273,8 @@ static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
        bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
                         MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13));
 
+       bnx2x_warpcore_set_lpi_passthrough(phy, params);
+
        if (always_autoneg || phy->req_line_speed == SPEED_AUTO_NEG) {
                /* SGMII Autoneg */
                bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
@@ -10792,28 +10804,52 @@ static int bnx2x_54618se_config_init(struct bnx2x_phy *phy,
                DP(NETIF_MSG_LINK, "Setting 10M force\n");
        }
 
-       /* Check if we should turn on Auto-GrEEEn */
-       bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &temp);
-       if (temp == MDIO_REG_GPHY_ID_54618SE) {
-               if (params->feature_config_flags &
-                   FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
-                       temp = 6;
-                       DP(NETIF_MSG_LINK, "Enabling Auto-GrEEEn\n");
+       if ((phy->flags & FLAGS_EEE) && bnx2x_eee_has_cap(params)) {
+               int rc;
+
+               bnx2x_cl22_write(bp, phy, MDIO_REG_GPHY_EXP_ACCESS,
+                                MDIO_REG_GPHY_EXP_ACCESS_TOP |
+                                MDIO_REG_GPHY_EXP_TOP_2K_BUF);
+               bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, &temp);
+               temp &= 0xfffe;
+               bnx2x_cl22_write(bp, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, temp);
+
+               rc = bnx2x_eee_initial_config(params, vars, SHMEM_EEE_1G_ADV);
+               if (rc) {
+                       DP(NETIF_MSG_LINK, "Failed to configure EEE timers\n");
+                       bnx2x_eee_disable(phy, params, vars);
+               } else if ((params->eee_mode & EEE_MODE_ADV_LPI) &&
+                          (phy->req_duplex == DUPLEX_FULL) &&
+                          (bnx2x_eee_calc_timer(params) ||
+                           !(params->eee_mode & EEE_MODE_ENABLE_LPI))) {
+                       /* Need to advertise EEE only when requested,
+                        * and either no LPI assertion was requested,
+                        * or it was requested and a valid timer was set.
+                        * Also notice full duplex is required for EEE.
+                        */
+                       bnx2x_eee_advertise(phy, params, vars,
+                                           SHMEM_EEE_1G_ADV);
                } else {
-                       temp = 0;
-                       DP(NETIF_MSG_LINK, "Disabling Auto-GrEEEn\n");
+                       DP(NETIF_MSG_LINK, "Don't Advertise 1GBase-T EEE\n");
+                       bnx2x_eee_disable(phy, params, vars);
+               }
+       } else {
+               vars->eee_status &= ~SHMEM_EEE_1G_ADV <<
+                                   SHMEM_EEE_SUPPORTED_SHIFT;
+
+               if (phy->flags & FLAGS_EEE) {
+                       /* Handle legacy auto-grEEEn */
+                       if (params->feature_config_flags &
+                           FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
+                               temp = 6;
+                               DP(NETIF_MSG_LINK, "Enabling Auto-GrEEEn\n");
+                       } else {
+                               temp = 0;
+                               DP(NETIF_MSG_LINK, "Don't Adv. EEE\n");
+                       }
+                       bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
+                                        MDIO_AN_REG_EEE_ADV, temp);
                }
-               bnx2x_cl22_write(bp, phy,
-                                MDIO_REG_GPHY_CL45_ADDR_REG, MDIO_AN_DEVAD);
-               bnx2x_cl22_write(bp, phy,
-                                MDIO_REG_GPHY_CL45_DATA_REG,
-                                MDIO_REG_GPHY_EEE_ADV);
-               bnx2x_cl22_write(bp, phy,
-                                MDIO_REG_GPHY_CL45_ADDR_REG,
-                                (0x1 << 14) | MDIO_AN_DEVAD);
-               bnx2x_cl22_write(bp, phy,
-                                MDIO_REG_GPHY_CL45_DATA_REG,
-                                temp);
        }
 
        bnx2x_cl22_write(bp, phy,
@@ -10960,29 +10996,6 @@ static u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy,
                DP(NETIF_MSG_LINK, "BCM54618SE: link speed is %d\n",
                           vars->line_speed);
 
-               /* Report whether EEE is resolved. */
-               bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &val);
-               if (val == MDIO_REG_GPHY_ID_54618SE) {
-                       if (vars->link_status &
-                           LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
-                               val = 0;
-                       else {
-                               bnx2x_cl22_write(bp, phy,
-                                       MDIO_REG_GPHY_CL45_ADDR_REG,
-                                       MDIO_AN_DEVAD);
-                               bnx2x_cl22_write(bp, phy,
-                                       MDIO_REG_GPHY_CL45_DATA_REG,
-                                       MDIO_REG_GPHY_EEE_RESOLVED);
-                               bnx2x_cl22_write(bp, phy,
-                                       MDIO_REG_GPHY_CL45_ADDR_REG,
-                                       (0x1 << 14) | MDIO_AN_DEVAD);
-                               bnx2x_cl22_read(bp, phy,
-                                       MDIO_REG_GPHY_CL45_DATA_REG,
-                                       &val);
-                       }
-                       DP(NETIF_MSG_LINK, "EEE resolution: 0x%x\n", val);
-               }
-
                bnx2x_ext_phy_resolve_fc(phy, params, vars);
 
                if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
@@ -11012,6 +11025,10 @@ static u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy,
                        if (val & (1<<11))
                                vars->link_status |=
                                  LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
+
+                       if ((phy->flags & FLAGS_EEE) &&
+                           bnx2x_eee_has_cap(params))
+                               bnx2x_eee_an_resolve(phy, params, vars);
                }
        }
        return link_up;
@@ -11925,6 +11942,8 @@ static int bnx2x_populate_ext_phy(struct bnx2x *bp,
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616:
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE:
                *phy = phy_54618se;
+               if (phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
+                       phy->flags |= FLAGS_EEE;
                break;
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
                *phy = phy_7101;
index 3967aa85fc09696352783a80e5b7845a76db6fba..360ecf9e07398a603197bbbe49144f12cb5b544b 100644 (file)
@@ -155,6 +155,7 @@ struct bnx2x_phy {
 #define FLAGS_DUMMY_READ               (1<<9)
 #define FLAGS_MDC_MDIO_WA_B0           (1<<10)
 #define FLAGS_TX_ERROR_CHECK           (1<<12)
+#define FLAGS_EEE                      (1<<13)
 
        /* preemphasis values for the rx side */
        u16 rx_preemphasis[4];
index d32293fcc81cefdea3ce8230a99744359375062c..1b1999d34c7180f41649b606695ecccfbcb237c5 100644 (file)
 #define UMAC_COMMAND_CONFIG_REG_SW_RESET                        (0x1<<13)
 #define UMAC_COMMAND_CONFIG_REG_TX_ENA                          (0x1<<0)
 #define UMAC_REG_COMMAND_CONFIG                                         0x8
+/* [RW 16] This is the duration for which MAC must wait to go back to ACTIVE
+ * state from LPI state when it receives packet for transmission. The
+ * decrement unit is 1 micro-second. */
+#define UMAC_REG_EEE_WAKE_TIMER                                         0x6c
 /* [RW 32] Register Bit 0 refers to Bit 16 of the MAC address; Bit 1 refers
  * to bit 17 of the MAC address etc. */
 #define UMAC_REG_MAC_ADDR0                                      0xc
 /* [RW 14] Defines a 14-Bit maximum frame length used by the MAC receive
  * logic to check frames. */
 #define UMAC_REG_MAXFR                                          0x14
+#define UMAC_REG_UMAC_EEE_CTRL                                  0x64
+#define UMAC_UMAC_EEE_CTRL_REG_EEE_EN                           (0x1<<3)
 /* [RW 8] The event id for aggregated interrupt 0 */
 #define USDM_REG_AGG_INT_EVENT_0                                0xc4038
 #define USDM_REG_AGG_INT_EVENT_1                                0xc403c
@@ -7161,10 +7167,11 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_REG_GPHY_ID_54618SE               0x5cd5
 #define MDIO_REG_GPHY_CL45_ADDR_REG                    0xd
 #define MDIO_REG_GPHY_CL45_DATA_REG                    0xe
-#define MDIO_REG_GPHY_EEE_ADV                  0x3c
-#define MDIO_REG_GPHY_EEE_1G           (0x1 << 2)
-#define MDIO_REG_GPHY_EEE_100          (0x1 << 1)
 #define MDIO_REG_GPHY_EEE_RESOLVED             0x803e
+#define MDIO_REG_GPHY_EXP_ACCESS_GATE                  0x15
+#define MDIO_REG_GPHY_EXP_ACCESS                       0x17
+#define MDIO_REG_GPHY_EXP_ACCESS_TOP           0xd00
+#define MDIO_REG_GPHY_EXP_TOP_2K_BUF           0x40
 #define MDIO_REG_GPHY_AUX_STATUS                       0x19
 #define MDIO_REG_INTR_STATUS                           0x1a
 #define MDIO_REG_INTR_MASK                             0x1b