sfc: Include XGXS in XMAC link status check except in XGMII loopback
authorBen Hutchings <bhutchings@solarflare.com>
Wed, 23 Dec 2009 13:46:47 +0000 (13:46 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 24 Dec 2009 03:09:05 +0000 (19:09 -0800)
The XGXS block may not get a link immediately in XGXS or XAUI loopback
modes, so we still need to check it.  Split falcon_xaui_link_ok() into
falcon_xgxs_link_ok(), which checks only the Falcon XGXS block, and
falcon_xmac_link_ok(), which checks one or both sides of the link as
appropriate.  Also rename falcon_check_xaui_link() to
falcon_xmac_link_ok_retry().

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/sfc/falcon_xmac.c

index 3da933f8f0797bc577027d489d4717ea8ec79dd3..8ccab2c67a2094680ef743df277cd7e20a8d16c2 100644 (file)
@@ -111,16 +111,12 @@ static void falcon_mask_status_intr(struct efx_nic *efx, bool enable)
        efx_writeo(efx, &reg, FR_AB_XM_MGT_INT_MASK);
 }
 
-/* Get status of XAUI link */
-static bool falcon_xaui_link_ok(struct efx_nic *efx)
+static bool falcon_xgxs_link_ok(struct efx_nic *efx)
 {
        efx_oword_t reg;
        bool align_done, link_ok = false;
        int sync_status;
 
-       if (LOOPBACK_INTERNAL(efx))
-               return true;
-
        /* Read link status */
        efx_reado(efx, &reg, FR_AB_XX_CORE_STAT);
 
@@ -135,14 +131,24 @@ static bool falcon_xaui_link_ok(struct efx_nic *efx)
        EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_DISPERR, FFE_AB_XX_STAT_ALL_LANES);
        efx_writeo(efx, &reg, FR_AB_XX_CORE_STAT);
 
-       /* If the link is up, then check the phy side of the xaui link */
-       if (efx->link_state.up && link_ok)
-               if (efx->mdio.mmds & (1 << MDIO_MMD_PHYXS))
-                       link_ok = efx_mdio_phyxgxs_lane_sync(efx);
-
        return link_ok;
 }
 
+static bool falcon_xmac_link_ok(struct efx_nic *efx)
+{
+       /*
+        * Check MAC's XGXS link status except when using XGMII loopback
+        * which bypasses the XGXS block.
+        * If possible, check PHY's XGXS link status except when using
+        * MAC loopback.
+        */
+       return (efx->loopback_mode == LOOPBACK_XGMII ||
+               falcon_xgxs_link_ok(efx)) &&
+               (!(efx->mdio.mmds & (1 << MDIO_MMD_PHYXS)) ||
+                LOOPBACK_INTERNAL(efx) || 
+                efx_mdio_phyxgxs_lane_sync(efx));
+}
+
 void falcon_reconfigure_xmac_core(struct efx_nic *efx)
 {
        unsigned int max_frame_len;
@@ -245,9 +251,9 @@ static void falcon_reconfigure_xgxs_core(struct efx_nic *efx)
 
 
 /* Try to bring up the Falcon side of the Falcon-Phy XAUI link */
-static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries)
+static bool falcon_xmac_link_ok_retry(struct efx_nic *efx, int tries)
 {
-       bool mac_up = falcon_xaui_link_ok(efx);
+       bool mac_up = falcon_xmac_link_ok(efx);
 
        if (LOOPBACK_MASK(efx) & LOOPBACKS_EXTERNAL(efx) & LOOPBACKS_WS ||
            efx_phy_mode_disabled(efx->phy_mode))
@@ -261,7 +267,7 @@ static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries)
                falcon_reset_xaui(efx);
                udelay(200);
 
-               mac_up = falcon_xaui_link_ok(efx);
+               mac_up = falcon_xmac_link_ok(efx);
                --tries;
        }
 
@@ -272,7 +278,7 @@ static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries)
 
 static bool falcon_xmac_check_fault(struct efx_nic *efx)
 {
-       return !falcon_check_xaui_link_up(efx, 5);
+       return !falcon_xmac_link_ok_retry(efx, 5);
 }
 
 static int falcon_reconfigure_xmac(struct efx_nic *efx)
@@ -284,7 +290,7 @@ static int falcon_reconfigure_xmac(struct efx_nic *efx)
 
        falcon_reconfigure_mac_wrapper(efx);
 
-       efx->xmac_poll_required = !falcon_check_xaui_link_up(efx, 5);
+       efx->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 5);
        falcon_mask_status_intr(efx, true);
 
        return 0;
@@ -357,7 +363,7 @@ void falcon_poll_xmac(struct efx_nic *efx)
                return;
 
        falcon_mask_status_intr(efx, false);
-       efx->xmac_poll_required = !falcon_check_xaui_link_up(efx, 1);
+       efx->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 1);
        falcon_mask_status_intr(efx, true);
 }