]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/sfc/falcon_xmac.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes...
[linux-2.6-omap-h63xx.git] / drivers / net / sfc / falcon_xmac.c
index 55c0d9760be8d12cc52ae592e0febf1e16f5e7b1..d4012314dd01f1af81c0ca7be57da7d4dc67a639 100644 (file)
 #include "boards.h"
 #include "workarounds.h"
 
-/**************************************************************************
- *
- * MAC register access
- *
- **************************************************************************/
-
-/* Offset of an XMAC register within Falcon */
-#define FALCON_XMAC_REG(mac_reg)                                       \
-       (FALCON_XMAC_REGBANK + ((mac_reg) * FALCON_XMAC_REG_SIZE))
-
-void falcon_xmac_writel(struct efx_nic *efx,
-                        efx_dword_t *value, unsigned int mac_reg)
-{
-       efx_oword_t temp;
-
-       EFX_POPULATE_OWORD_1(temp, MAC_DATA, EFX_DWORD_FIELD(*value, MAC_DATA));
-       falcon_write(efx, &temp, FALCON_XMAC_REG(mac_reg));
-}
-
-void falcon_xmac_readl(struct efx_nic *efx,
-                      efx_dword_t *value, unsigned int mac_reg)
-{
-       efx_oword_t temp;
-
-       falcon_read(efx, &temp, FALCON_XMAC_REG(mac_reg));
-       EFX_POPULATE_DWORD_1(*value, MAC_DATA, EFX_OWORD_FIELD(temp, MAC_DATA));
-}
-
 /**************************************************************************
  *
  * MAC operations
@@ -56,23 +28,19 @@ void falcon_xmac_readl(struct efx_nic *efx,
  *************************************************************************/
 static int falcon_reset_xmac(struct efx_nic *efx)
 {
-       efx_dword_t reg;
+       efx_oword_t reg;
        int count;
 
-       EFX_POPULATE_DWORD_1(reg, XM_CORE_RST, 1);
-       falcon_xmac_writel(efx, &reg, XM_GLB_CFG_REG_MAC);
+       EFX_POPULATE_OWORD_1(reg, XM_CORE_RST, 1);
+       falcon_write(efx, &reg, XM_GLB_CFG_REG);
 
        for (count = 0; count < 10000; count++) {       /* wait upto 100ms */
-               falcon_xmac_readl(efx, &reg, XM_GLB_CFG_REG_MAC);
-               if (EFX_DWORD_FIELD(reg, XM_CORE_RST) == 0)
+               falcon_read(efx, &reg, XM_GLB_CFG_REG);
+               if (EFX_OWORD_FIELD(reg, XM_CORE_RST) == 0)
                        return 0;
                udelay(10);
        }
 
-       /* This often fails when DSP is disabled, ignore it */
-       if (sfe4001_phy_flash_cfg != 0)
-               return 0;
-
        EFX_ERR(efx, "timed out waiting for XMAC core reset\n");
        return -ETIMEDOUT;
 }
@@ -80,25 +48,25 @@ static int falcon_reset_xmac(struct efx_nic *efx)
 /* Configure the XAUI driver that is an output from Falcon */
 static void falcon_setup_xaui(struct efx_nic *efx)
 {
-       efx_dword_t sdctl, txdrv;
+       efx_oword_t sdctl, txdrv;
 
        /* Move the XAUI into low power, unless there is no PHY, in
         * which case the XAUI will have to drive a cable. */
        if (efx->phy_type == PHY_TYPE_NONE)
                return;
 
-       falcon_xmac_readl(efx, &sdctl, XX_SD_CTL_REG_MAC);
-       EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVD, XX_SD_CTL_DRV_DEFAULT);
-       EFX_SET_DWORD_FIELD(sdctl, XX_LODRVD, XX_SD_CTL_DRV_DEFAULT);
-       EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVC, XX_SD_CTL_DRV_DEFAULT);
-       EFX_SET_DWORD_FIELD(sdctl, XX_LODRVC, XX_SD_CTL_DRV_DEFAULT);
-       EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVB, XX_SD_CTL_DRV_DEFAULT);
-       EFX_SET_DWORD_FIELD(sdctl, XX_LODRVB, XX_SD_CTL_DRV_DEFAULT);
-       EFX_SET_DWORD_FIELD(sdctl, XX_HIDRVA, XX_SD_CTL_DRV_DEFAULT);
-       EFX_SET_DWORD_FIELD(sdctl, XX_LODRVA, XX_SD_CTL_DRV_DEFAULT);
-       falcon_xmac_writel(efx, &sdctl, XX_SD_CTL_REG_MAC);
-
-       EFX_POPULATE_DWORD_8(txdrv,
+       falcon_read(efx, &sdctl, XX_SD_CTL_REG);
+       EFX_SET_OWORD_FIELD(sdctl, XX_HIDRVD, XX_SD_CTL_DRV_DEFAULT);
+       EFX_SET_OWORD_FIELD(sdctl, XX_LODRVD, XX_SD_CTL_DRV_DEFAULT);
+       EFX_SET_OWORD_FIELD(sdctl, XX_HIDRVC, XX_SD_CTL_DRV_DEFAULT);
+       EFX_SET_OWORD_FIELD(sdctl, XX_LODRVC, XX_SD_CTL_DRV_DEFAULT);
+       EFX_SET_OWORD_FIELD(sdctl, XX_HIDRVB, XX_SD_CTL_DRV_DEFAULT);
+       EFX_SET_OWORD_FIELD(sdctl, XX_LODRVB, XX_SD_CTL_DRV_DEFAULT);
+       EFX_SET_OWORD_FIELD(sdctl, XX_HIDRVA, XX_SD_CTL_DRV_DEFAULT);
+       EFX_SET_OWORD_FIELD(sdctl, XX_LODRVA, XX_SD_CTL_DRV_DEFAULT);
+       falcon_write(efx, &sdctl, XX_SD_CTL_REG);
+
+       EFX_POPULATE_OWORD_8(txdrv,
                             XX_DEQD, XX_TXDRV_DEQ_DEFAULT,
                             XX_DEQC, XX_TXDRV_DEQ_DEFAULT,
                             XX_DEQB, XX_TXDRV_DEQ_DEFAULT,
@@ -107,93 +75,21 @@ static void falcon_setup_xaui(struct efx_nic *efx)
                             XX_DTXC, XX_TXDRV_DTX_DEFAULT,
                             XX_DTXB, XX_TXDRV_DTX_DEFAULT,
                             XX_DTXA, XX_TXDRV_DTX_DEFAULT);
-       falcon_xmac_writel(efx, &txdrv, XX_TXDRV_CTL_REG_MAC);
+       falcon_write(efx, &txdrv, XX_TXDRV_CTL_REG);
 }
 
-static void falcon_hold_xaui_in_rst(struct efx_nic *efx)
-{
-       efx_dword_t reg;
-
-       EFX_ZERO_DWORD(reg);
-       EFX_SET_DWORD_FIELD(reg, XX_PWRDNA_EN, 1);
-       EFX_SET_DWORD_FIELD(reg, XX_PWRDNB_EN, 1);
-       EFX_SET_DWORD_FIELD(reg, XX_PWRDNC_EN, 1);
-       EFX_SET_DWORD_FIELD(reg, XX_PWRDND_EN, 1);
-       EFX_SET_DWORD_FIELD(reg, XX_RSTPLLAB_EN, 1);
-       EFX_SET_DWORD_FIELD(reg, XX_RSTPLLCD_EN, 1);
-       EFX_SET_DWORD_FIELD(reg, XX_RESETA_EN, 1);
-       EFX_SET_DWORD_FIELD(reg, XX_RESETB_EN, 1);
-       EFX_SET_DWORD_FIELD(reg, XX_RESETC_EN, 1);
-       EFX_SET_DWORD_FIELD(reg, XX_RESETD_EN, 1);
-       EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
-       EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
-       falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
-       udelay(10);
-}
-
-static int _falcon_reset_xaui_a(struct efx_nic *efx)
-{
-       efx_dword_t reg;
-
-       falcon_hold_xaui_in_rst(efx);
-       falcon_xmac_readl(efx, &reg, XX_PWR_RST_REG_MAC);
-
-       /* Follow the RAMBUS XAUI data reset sequencing
-        * Channels A and B first: power down, reset PLL, reset, clear
-        */
-       EFX_SET_DWORD_FIELD(reg, XX_PWRDNA_EN, 0);
-       EFX_SET_DWORD_FIELD(reg, XX_PWRDNB_EN, 0);
-       falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
-       udelay(10);
-
-       EFX_SET_DWORD_FIELD(reg, XX_RSTPLLAB_EN, 0);
-       falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
-       udelay(10);
-
-       EFX_SET_DWORD_FIELD(reg, XX_RESETA_EN, 0);
-       EFX_SET_DWORD_FIELD(reg, XX_RESETB_EN, 0);
-       falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
-       udelay(10);
-
-       /* Channels C and D: power down, reset PLL, reset, clear */
-       EFX_SET_DWORD_FIELD(reg, XX_PWRDNC_EN, 0);
-       EFX_SET_DWORD_FIELD(reg, XX_PWRDND_EN, 0);
-       falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
-       udelay(10);
-
-       EFX_SET_DWORD_FIELD(reg, XX_RSTPLLCD_EN, 0);
-       falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
-       udelay(10);
-
-       EFX_SET_DWORD_FIELD(reg, XX_RESETC_EN, 0);
-       EFX_SET_DWORD_FIELD(reg, XX_RESETD_EN, 0);
-       falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
-       udelay(10);
-
-       /* Setup XAUI */
-       falcon_setup_xaui(efx);
-       udelay(10);
-
-       /* Take XGXS out of reset */
-       EFX_ZERO_DWORD(reg);
-       falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
-       udelay(10);
-
-       return 0;
-}
-
-static int _falcon_reset_xaui_b(struct efx_nic *efx)
+int falcon_reset_xaui(struct efx_nic *efx)
 {
-       efx_dword_t reg;
+       efx_oword_t reg;
        int count;
 
        EFX_POPULATE_DWORD_1(reg, XX_RST_XX_EN, 1);
-       falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
+       falcon_write(efx, &reg, XX_PWR_RST_REG);
 
        /* Give some time for the link to establish */
        for (count = 0; count < 1000; count++) { /* wait upto 10ms */
-               falcon_xmac_readl(efx, &reg, XX_PWR_RST_REG_MAC);
-               if (EFX_DWORD_FIELD(reg, XX_RST_XX_EN) == 0) {
+               falcon_read(efx, &reg, XX_PWR_RST_REG);
+               if (EFX_OWORD_FIELD(reg, XX_RST_XX_EN) == 0) {
                        falcon_setup_xaui(efx);
                        return 0;
                }
@@ -203,55 +99,41 @@ static int _falcon_reset_xaui_b(struct efx_nic *efx)
        return -ETIMEDOUT;
 }
 
-int falcon_reset_xaui(struct efx_nic *efx)
+static bool falcon_xgmii_status(struct efx_nic *efx)
 {
-       int rc;
-
-       if (EFX_WORKAROUND_9388(efx)) {
-               falcon_hold_xaui_in_rst(efx);
-               efx->phy_op->reset_xaui(efx);
-               rc = _falcon_reset_xaui_a(efx);
-       } else {
-               rc = _falcon_reset_xaui_b(efx);
-       }
-       return rc;
-}
-
-static int falcon_xgmii_status(struct efx_nic *efx)
-{
-       efx_dword_t reg;
+       efx_oword_t reg;
 
        if (falcon_rev(efx) < FALCON_REV_B0)
-               return 1;
+               return true;
 
        /* The ISR latches, so clear it and re-read */
-       falcon_xmac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0);
-       falcon_xmac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0);
+       falcon_read(efx, &reg, XM_MGT_INT_REG_B0);
+       falcon_read(efx, &reg, XM_MGT_INT_REG_B0);
 
-       if (EFX_DWORD_FIELD(reg, XM_LCLFLT) ||
-           EFX_DWORD_FIELD(reg, XM_RMTFLT)) {
+       if (EFX_OWORD_FIELD(reg, XM_LCLFLT) ||
+           EFX_OWORD_FIELD(reg, XM_RMTFLT)) {
                EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg));
-               return 0;
+               return false;
        }
 
-       return 1;
+       return true;
 }
 
-static void falcon_mask_status_intr(struct efx_nic *efx, int enable)
+static void falcon_mask_status_intr(struct efx_nic *efx, bool enable)
 {
-       efx_dword_t reg;
+       efx_oword_t reg;
 
        if ((falcon_rev(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx))
                return;
 
        /* Flush the ISR */
        if (enable)
-               falcon_xmac_readl(efx, &reg, XM_MGT_INT_REG_MAC_B0);
+               falcon_read(efx, &reg, XM_MGT_INT_REG_B0);
 
-       EFX_POPULATE_DWORD_2(reg,
+       EFX_POPULATE_OWORD_2(reg,
                             XM_MSK_RMTFLT, !enable,
                             XM_MSK_LCLFLT, !enable);
-       falcon_xmac_writel(efx, &reg, XM_MGT_INT_MSK_REG_MAC_B0);
+       falcon_write(efx, &reg, XM_MGT_INT_MSK_REG_B0);
 }
 
 int falcon_init_xmac(struct efx_nic *efx)
@@ -274,7 +156,7 @@ int falcon_init_xmac(struct efx_nic *efx)
        if (rc)
                goto fail2;
 
-       falcon_mask_status_intr(efx, 1);
+       falcon_mask_status_intr(efx, true);
        return 0;
 
  fail2:
@@ -283,34 +165,34 @@ int falcon_init_xmac(struct efx_nic *efx)
        return rc;
 }
 
-int falcon_xaui_link_ok(struct efx_nic *efx)
+bool falcon_xaui_link_ok(struct efx_nic *efx)
 {
-       efx_dword_t reg;
-       int align_done, sync_status, link_ok = 0;
+       efx_oword_t reg;
+       bool align_done, link_ok = false;
+       int sync_status;
 
        if (LOOPBACK_INTERNAL(efx))
-               return 1;
+               return true;
 
        /* Read link status */
-       falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC);
+       falcon_read(efx, &reg, XX_CORE_STAT_REG);
 
-       align_done = EFX_DWORD_FIELD(reg, XX_ALIGN_DONE);
-       sync_status = EFX_DWORD_FIELD(reg, XX_SYNC_STAT);
+       align_done = EFX_OWORD_FIELD(reg, XX_ALIGN_DONE);
+       sync_status = EFX_OWORD_FIELD(reg, XX_SYNC_STAT);
        if (align_done && (sync_status == XX_SYNC_STAT_DECODE_SYNCED))
-               link_ok = 1;
+               link_ok = true;
 
        /* Clear link status ready for next read */
-       EFX_SET_DWORD_FIELD(reg, XX_COMMA_DET, XX_COMMA_DET_RESET);
-       EFX_SET_DWORD_FIELD(reg, XX_CHARERR, XX_CHARERR_RESET);
-       EFX_SET_DWORD_FIELD(reg, XX_DISPERR, XX_DISPERR_RESET);
-       falcon_xmac_writel(efx, &reg, XX_CORE_STAT_REG_MAC);
+       EFX_SET_OWORD_FIELD(reg, XX_COMMA_DET, XX_COMMA_DET_RESET);
+       EFX_SET_OWORD_FIELD(reg, XX_CHARERR, XX_CHARERR_RESET);
+       EFX_SET_OWORD_FIELD(reg, XX_DISPERR, XX_DISPERR_RESET);
+       falcon_write(efx, &reg, XX_CORE_STAT_REG);
 
        /* If the link is up, then check the phy side of the xaui link
         * (error conditions from the wire side propoagate back through
         * the phy to the xaui side). */
        if (efx->link_up && link_ok) {
-               int has_phyxs = efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS);
-               if (has_phyxs)
+               if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS))
                        link_ok = mdio_clause45_phyxgxs_lane_sync(efx);
        }
 
@@ -325,15 +207,15 @@ int falcon_xaui_link_ok(struct efx_nic *efx)
 static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
 {
        unsigned int max_frame_len;
-       efx_dword_t reg;
-       int rx_fc = (efx->flow_control & EFX_FC_RX) ? 1 : 0;
+       efx_oword_t reg;
+       bool rx_fc = !!(efx->flow_control & EFX_FC_RX);
 
        /* Configure MAC  - cut-thru mode is hard wired on */
        EFX_POPULATE_DWORD_3(reg,
                             XM_RX_JUMBO_MODE, 1,
                             XM_TX_STAT_EN, 1,
                             XM_RX_STAT_EN, 1);
-       falcon_xmac_writel(efx, &reg, XM_GLB_CFG_REG_MAC);
+       falcon_write(efx, &reg, XM_GLB_CFG_REG);
 
        /* Configure TX */
        EFX_POPULATE_DWORD_6(reg,
@@ -343,7 +225,7 @@ static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
                             XM_TXCRC, 1,
                             XM_FCNTL, 1,
                             XM_IPG, 0x3);
-       falcon_xmac_writel(efx, &reg, XM_TX_CFG_REG_MAC);
+       falcon_write(efx, &reg, XM_TX_CFG_REG);
 
        /* Configure RX */
        EFX_POPULATE_DWORD_5(reg,
@@ -352,21 +234,21 @@ static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
                             XM_ACPT_ALL_MCAST, 1,
                             XM_ACPT_ALL_UCAST, efx->promiscuous,
                             XM_PASS_CRC_ERR, 1);
-       falcon_xmac_writel(efx, &reg, XM_RX_CFG_REG_MAC);
+       falcon_write(efx, &reg, XM_RX_CFG_REG);
 
        /* Set frame length */
        max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
        EFX_POPULATE_DWORD_1(reg, XM_MAX_RX_FRM_SIZE, max_frame_len);
-       falcon_xmac_writel(efx, &reg, XM_RX_PARAM_REG_MAC);
+       falcon_write(efx, &reg, XM_RX_PARAM_REG);
        EFX_POPULATE_DWORD_2(reg,
                             XM_MAX_TX_FRM_SIZE, max_frame_len,
                             XM_TX_JUMBO_MODE, 1);
-       falcon_xmac_writel(efx, &reg, XM_TX_PARAM_REG_MAC);
+       falcon_write(efx, &reg, XM_TX_PARAM_REG);
 
        EFX_POPULATE_DWORD_2(reg,
                             XM_PAUSE_TIME, 0xfffe, /* MAX PAUSE TIME */
-                            XM_DIS_FCNTL, rx_fc ? 0 : 1);
-       falcon_xmac_writel(efx, &reg, XM_FC_REG_MAC);
+                            XM_DIS_FCNTL, !rx_fc);
+       falcon_write(efx, &reg, XM_FC_REG);
 
        /* Set MAC address */
        EFX_POPULATE_DWORD_4(reg,
@@ -374,83 +256,75 @@ static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
                             XM_ADR_1, efx->net_dev->dev_addr[1],
                             XM_ADR_2, efx->net_dev->dev_addr[2],
                             XM_ADR_3, efx->net_dev->dev_addr[3]);
-       falcon_xmac_writel(efx, &reg, XM_ADR_LO_REG_MAC);
+       falcon_write(efx, &reg, XM_ADR_LO_REG);
        EFX_POPULATE_DWORD_2(reg,
                             XM_ADR_4, efx->net_dev->dev_addr[4],
                             XM_ADR_5, efx->net_dev->dev_addr[5]);
-       falcon_xmac_writel(efx, &reg, XM_ADR_HI_REG_MAC);
+       falcon_write(efx, &reg, XM_ADR_HI_REG);
 }
 
 static void falcon_reconfigure_xgxs_core(struct efx_nic *efx)
 {
-       efx_dword_t reg;
-       int xgxs_loopback = (efx->loopback_mode == LOOPBACK_XGXS) ? 1 : 0;
-       int xaui_loopback = (efx->loopback_mode == LOOPBACK_XAUI) ? 1 : 0;
-       int xgmii_loopback =
-               (efx->loopback_mode == LOOPBACK_XGMII) ? 1 : 0;
+       efx_oword_t reg;
+       bool xgxs_loopback = (efx->loopback_mode == LOOPBACK_XGXS);
+       bool xaui_loopback = (efx->loopback_mode == LOOPBACK_XAUI);
+       bool xgmii_loopback = (efx->loopback_mode == LOOPBACK_XGMII);
 
        /* XGXS block is flaky and will need to be reset if moving
         * into our out of XGMII, XGXS or XAUI loopbacks. */
        if (EFX_WORKAROUND_5147(efx)) {
-               int old_xgmii_loopback, old_xgxs_loopback, old_xaui_loopback;
-               int reset_xgxs;
+               bool old_xgmii_loopback, old_xgxs_loopback, old_xaui_loopback;
+               bool reset_xgxs;
 
-               falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC);
-               old_xgxs_loopback = EFX_DWORD_FIELD(reg, XX_XGXS_LB_EN);
-               old_xgmii_loopback = EFX_DWORD_FIELD(reg, XX_XGMII_LB_EN);
+               falcon_read(efx, &reg, XX_CORE_STAT_REG);
+               old_xgxs_loopback = EFX_OWORD_FIELD(reg, XX_XGXS_LB_EN);
+               old_xgmii_loopback = EFX_OWORD_FIELD(reg, XX_XGMII_LB_EN);
 
-               falcon_xmac_readl(efx, &reg, XX_SD_CTL_REG_MAC);
-               old_xaui_loopback = EFX_DWORD_FIELD(reg, XX_LPBKA);
+               falcon_read(efx, &reg, XX_SD_CTL_REG);
+               old_xaui_loopback = EFX_OWORD_FIELD(reg, XX_LPBKA);
 
                /* The PHY driver may have turned XAUI off */
                reset_xgxs = ((xgxs_loopback != old_xgxs_loopback) ||
                              (xaui_loopback != old_xaui_loopback) ||
                              (xgmii_loopback != old_xgmii_loopback));
-               if (reset_xgxs) {
-                       falcon_xmac_readl(efx, &reg, XX_PWR_RST_REG_MAC);
-                       EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
-                       EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
-                       falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
-                       udelay(1);
-                       EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 0);
-                       EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 0);
-                       falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
-                       udelay(1);
-               }
+
+               if (reset_xgxs)
+                       falcon_reset_xaui(efx);
        }
 
-       falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC);
-       EFX_SET_DWORD_FIELD(reg, XX_FORCE_SIG,
+       falcon_read(efx, &reg, XX_CORE_STAT_REG);
+       EFX_SET_OWORD_FIELD(reg, XX_FORCE_SIG,
                            (xgxs_loopback || xaui_loopback) ?
                            XX_FORCE_SIG_DECODE_FORCED : 0);
-       EFX_SET_DWORD_FIELD(reg, XX_XGXS_LB_EN, xgxs_loopback);
-       EFX_SET_DWORD_FIELD(reg, XX_XGMII_LB_EN, xgmii_loopback);
-       falcon_xmac_writel(efx, &reg, XX_CORE_STAT_REG_MAC);
-
-       falcon_xmac_readl(efx, &reg, XX_SD_CTL_REG_MAC);
-       EFX_SET_DWORD_FIELD(reg, XX_LPBKD, xaui_loopback);
-       EFX_SET_DWORD_FIELD(reg, XX_LPBKC, xaui_loopback);
-       EFX_SET_DWORD_FIELD(reg, XX_LPBKB, xaui_loopback);
-       EFX_SET_DWORD_FIELD(reg, XX_LPBKA, xaui_loopback);
-       falcon_xmac_writel(efx, &reg, XX_SD_CTL_REG_MAC);
+       EFX_SET_OWORD_FIELD(reg, XX_XGXS_LB_EN, xgxs_loopback);
+       EFX_SET_OWORD_FIELD(reg, XX_XGMII_LB_EN, xgmii_loopback);
+       falcon_write(efx, &reg, XX_CORE_STAT_REG);
+
+       falcon_read(efx, &reg, XX_SD_CTL_REG);
+       EFX_SET_OWORD_FIELD(reg, XX_LPBKD, xaui_loopback);
+       EFX_SET_OWORD_FIELD(reg, XX_LPBKC, xaui_loopback);
+       EFX_SET_OWORD_FIELD(reg, XX_LPBKB, xaui_loopback);
+       EFX_SET_OWORD_FIELD(reg, XX_LPBKA, xaui_loopback);
+       falcon_write(efx, &reg, XX_SD_CTL_REG);
 }
 
 
 /* Try and bring the Falcon side of the Falcon-Phy XAUI link fails
  * to come back up. Bash it until it comes back up */
-static int falcon_check_xaui_link_up(struct efx_nic *efx)
+static bool falcon_check_xaui_link_up(struct efx_nic *efx)
 {
        int max_tries, tries;
        tries = EFX_WORKAROUND_5147(efx) ? 5 : 1;
        max_tries = tries;
 
        if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
-           (efx->phy_type == PHY_TYPE_NONE))
-               return 0;
+           (efx->phy_type == PHY_TYPE_NONE) ||
+           efx_phy_mode_disabled(efx->phy_mode))
+               return false;
 
        while (tries) {
                if (falcon_xaui_link_ok(efx))
-                       return 1;
+                       return true;
 
                EFX_LOG(efx, "%s Clobbering XAUI (%d tries left).\n",
                        __func__, tries);
@@ -461,18 +335,22 @@ static int falcon_check_xaui_link_up(struct efx_nic *efx)
 
        EFX_LOG(efx, "Failed to bring XAUI link back up in %d tries!\n",
                max_tries);
-       return 0;
+       return false;
 }
 
 void falcon_reconfigure_xmac(struct efx_nic *efx)
 {
-       int xaui_link_ok;
+       bool xaui_link_ok;
 
-       falcon_mask_status_intr(efx, 0);
+       falcon_mask_status_intr(efx, false);
 
        falcon_deconfigure_mac_wrapper(efx);
 
-       efx->tx_disabled = LOOPBACK_INTERNAL(efx);
+       /* Reconfigure the PHY, disabling transmit in mac level loopback. */
+       if (LOOPBACK_INTERNAL(efx))
+               efx->phy_mode |= PHY_MODE_TX_DISABLED;
+       else
+               efx->phy_mode &= ~PHY_MODE_TX_DISABLED;
        efx->phy_op->reconfigure(efx);
 
        falcon_reconfigure_xgxs_core(efx);
@@ -484,7 +362,7 @@ void falcon_reconfigure_xmac(struct efx_nic *efx)
        xaui_link_ok = falcon_check_xaui_link_up(efx);
 
        if (xaui_link_ok && efx->link_up)
-               falcon_mask_status_intr(efx, 1);
+               falcon_mask_status_intr(efx, true);
 }
 
 void falcon_fini_xmac(struct efx_nic *efx)
@@ -554,21 +432,23 @@ void falcon_update_stats_xmac(struct efx_nic *efx)
 
        /* Update derived statistics */
        mac_stats->tx_good_bytes =
-               (mac_stats->tx_bytes - mac_stats->tx_bad_bytes);
+               (mac_stats->tx_bytes - mac_stats->tx_bad_bytes -
+                mac_stats->tx_control * 64);
        mac_stats->rx_bad_bytes =
-               (mac_stats->rx_bytes - mac_stats->rx_good_bytes);
+               (mac_stats->rx_bytes - mac_stats->rx_good_bytes -
+                mac_stats->rx_control * 64);
 }
 
 int falcon_check_xmac(struct efx_nic *efx)
 {
-       unsigned xaui_link_ok;
+       bool xaui_link_ok;
        int rc;
 
        if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
-           (efx->phy_type == PHY_TYPE_NONE))
+           efx_phy_mode_disabled(efx->phy_mode))
                return 0;
 
-       falcon_mask_status_intr(efx, 0);
+       falcon_mask_status_intr(efx, false);
        xaui_link_ok = falcon_xaui_link_ok(efx);
 
        if (EFX_WORKAROUND_5147(efx) && !xaui_link_ok)
@@ -579,7 +459,7 @@ int falcon_check_xmac(struct efx_nic *efx)
 
        /* Unmask interrupt if everything was (and still is) ok */
        if (xaui_link_ok && efx->link_up)
-               falcon_mask_status_intr(efx, 1);
+               falcon_mask_status_intr(efx, true);
 
        return rc;
 }
@@ -620,7 +500,7 @@ int falcon_xmac_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 
 int falcon_xmac_set_pause(struct efx_nic *efx, enum efx_fc_type flow_control)
 {
-       int reset;
+       bool reset;
 
        if (flow_control & EFX_FC_AUTO) {
                EFX_LOG(efx, "10G does not support flow control "