bnx2x: Enable FC when parallel-detect is used
authorYaniv Rosner <yanivr@broadcom.com>
Thu, 5 Nov 2009 17:18:12 +0000 (19:18 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 6 Nov 2009 04:00:35 +0000 (20:00 -0800)
When parallel detect is used, flow-control is set to the
req_fc_auto_adv instead of none.

Motive: when 577xx is FC configuration is set to AUTO, while LP speed
is set to FORCE mode and FC to force RX/TX, link would come up using
parallel detect, and the FC will be set to NONE since FC capabilities
were not negotiated, although the LP is setting FC to force RX/TX.

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>
drivers/net/bnx2x_link.c
drivers/net/bnx2x_reg.h

index bf1021ed5dd6c7d32d7c5ce4625c83e69687985e..4c16a46f0caf4f1cd1f1557ee4b4325aa5aebb1c 100644 (file)
@@ -1621,6 +1621,39 @@ static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params,
        return ret;
 }
 
+static u8 bnx2x_direct_parallel_detect_used(struct link_params *params)
+{
+       struct bnx2x *bp = params->bp;
+       u16 pd_10g, status2_1000x;
+       CL45_RD_OVER_CL22(bp, params->port,
+                             params->phy_addr,
+                             MDIO_REG_BANK_SERDES_DIGITAL,
+                             MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
+                             &status2_1000x);
+       CL45_RD_OVER_CL22(bp, params->port,
+                             params->phy_addr,
+                             MDIO_REG_BANK_SERDES_DIGITAL,
+                             MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
+                             &status2_1000x);
+       if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
+               DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
+                        params->port);
+               return 1;
+       }
+
+       CL45_RD_OVER_CL22(bp, params->port,
+                             params->phy_addr,
+                             MDIO_REG_BANK_10G_PARALLEL_DETECT,
+                             MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
+                             &pd_10g);
+
+       if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
+               DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
+                        params->port);
+               return 1;
+       }
+       return 0;
+}
 
 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
                                  struct link_vars *vars,
@@ -1639,6 +1672,10 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
            (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
            (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
+               if (bnx2x_direct_parallel_detect_used(params)) {
+                       vars->flow_ctrl = params->req_fc_auto_adv;
+                       return;
+               }
                if ((gp_status &
                    (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
                     MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
index b80fde44c85d50a374f5133235883d2d7565ce5e..4be9bab42f5c7dd1c65e14e53755288e15433100 100644 (file)
 
 
 #define MDIO_REG_BANK_10G_PARALLEL_DETECT              0x8130
+#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS            0x10
+#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK            0x8000
 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL           0x11
 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN      0x1
 #define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK              0x13
 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_1G                   0x0010
 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_100M                 0x0008
 #define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_10M                  0x0000
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS2                    0x15
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED                0x0002
 #define MDIO_SERDES_DIGITAL_MISC1                              0x18
 #define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_MASK                      0xE000
 #define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_25M                       0x0000