All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ben Hutchings <bhutchings@solarflare.com>
To: David Miller <davem@davemloft.net>
Cc: netdev@vger.kernel.org, linux-net-drivers@solarflare.com
Subject: [PATCH 04/16] sfc: Use generic MDIO functions and definitions
Date: Wed, 29 Apr 2009 19:05:08 +0100	[thread overview]
Message-ID: <1241028308.3246.38.camel@achroite> (raw)
In-Reply-To: <1241028086.3246.30.camel@achroite>

Make use of the newly-added generic MDIO clause 45 support and remove
redundant definitions.

Add an 'efx_' prefix to the remaining driver-specific MDIO functions
and remove arguments which are redundant with efx->mdio.prtad.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/sfc/Kconfig         |    2 +-
 drivers/net/sfc/efx.c           |   10 +-
 drivers/net/sfc/ethtool.c       |   18 +--
 drivers/net/sfc/falcon.c        |  137 ++++----------
 drivers/net/sfc/falcon_hwdefs.h |    3 -
 drivers/net/sfc/falcon_xmac.c   |    2 +-
 drivers/net/sfc/mdio_10g.c      |  379 +++++++++------------------------------
 drivers/net/sfc/mdio_10g.h      |  281 ++++-------------------------
 drivers/net/sfc/net_driver.h    |    8 +-
 drivers/net/sfc/selftest.c      |   21 +--
 drivers/net/sfc/selftest.h      |    2 +-
 drivers/net/sfc/tenxpress.c     |  227 +++++++++--------------
 drivers/net/sfc/xenpack.h       |   15 +-
 drivers/net/sfc/xfp_phy.c       |   51 +++---
 14 files changed, 311 insertions(+), 845 deletions(-)

diff --git a/drivers/net/sfc/Kconfig b/drivers/net/sfc/Kconfig
index 12a8296..260aafa 100644
--- a/drivers/net/sfc/Kconfig
+++ b/drivers/net/sfc/Kconfig
@@ -1,7 +1,7 @@
 config SFC
 	tristate "Solarflare Solarstorm SFC4000 support"
 	depends on PCI && INET
-	select MII
+	select MDIO
 	select CRC32
 	select I2C
 	select I2C_ALGOBIT
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 7269a42..d3e240b 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1300,10 +1300,16 @@ out_requeue:
 static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
+	struct mii_ioctl_data *data = if_mii(ifr);
 
 	EFX_ASSERT_RESET_SERIALISED(efx);
 
-	return generic_mii_ioctl(&efx->mii, if_mii(ifr), cmd, NULL);
+	/* Convert phy_id from older PRTAD/DEVAD format */
+	if ((cmd == SIOCGMIIREG || cmd == SIOCSMIIREG) &&
+	    (data->phy_id & 0xfc00) == 0x0400)
+		data->phy_id ^= MDIO_PHY_ID_C45 | 0x0400;
+
+	return mdio_mii_ioctl(&efx->mdio, data, cmd);
 }
 
 /**************************************************************************
@@ -1945,7 +1951,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
 	mutex_init(&efx->mac_lock);
 	efx->mac_op = &efx_dummy_mac_operations;
 	efx->phy_op = &efx_dummy_phy_operations;
-	efx->mii.dev = net_dev;
+	efx->mdio.dev = net_dev;
 	INIT_WORK(&efx->phy_work, efx_phy_work);
 	INIT_WORK(&efx->mac_work, efx_mac_work);
 	atomic_set(&efx->netif_stop_count, 1);
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 64309f4..1c7b684 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -10,6 +10,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
+#include <linux/mdio.h>
 #include <linux/rtnetlink.h>
 #include "net_driver.h"
 #include "workarounds.h"
@@ -345,8 +346,8 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
 	unsigned int n = 0, i;
 	enum efx_loopback_mode mode;
 
-	efx_fill_test(n++, strings, data, &tests->mii,
-		      "core", 0, "mii", NULL);
+	efx_fill_test(n++, strings, data, &tests->mdio,
+		      "core", 0, "mdio", NULL);
 	efx_fill_test(n++, strings, data, &tests->nvram,
 		      "core", 0, "nvram", NULL);
 	efx_fill_test(n++, strings, data, &tests->interrupt,
@@ -529,14 +530,7 @@ static int efx_ethtool_nway_reset(struct net_device *net_dev)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
 
-	if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
-		mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
-				       MDIO_MMDREG_CTRL1,
-				       __ffs(BMCR_ANRESTART), true);
-		return 0;
-	}
-
-	return -EOPNOTSUPP;
+	return mdio45_nway_restart(&efx->mdio);
 }
 
 static u32 efx_ethtool_get_link(struct net_device *net_dev)
@@ -689,7 +683,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
 		return -EINVAL;
 	}
 
-	if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) &&
+	if (!(efx->phy_op->mmds & MDIO_DEVS_AN) &&
 	    (wanted_fc & EFX_FC_AUTO)) {
 		EFX_LOG(efx, "PHY does not support flow control "
 			"autonegotiation\n");
@@ -717,7 +711,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
 	mutex_lock(&efx->mac_lock);
 
 	efx->wanted_fc = wanted_fc;
-	mdio_clause45_set_pause(efx);
+	efx_mdio_set_pause(efx);
 	__efx_reconfigure_port(efx);
 
 	mutex_unlock(&efx->mac_lock);
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 466a8ab..c049364 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -2063,26 +2063,6 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset)
  **************************************************************************
  */
 
-/* Use the top bit of the MII PHY id to indicate the PHY type
- * (1G/10G), with the remaining bits as the actual PHY id.
- *
- * This allows us to avoid leaking information from the mii_if_info
- * structure into other data structures.
- */
-#define FALCON_PHY_ID_ID_WIDTH  EFX_WIDTH(MD_PRT_DEV_ADR)
-#define FALCON_PHY_ID_ID_MASK   ((1 << FALCON_PHY_ID_ID_WIDTH) - 1)
-#define FALCON_PHY_ID_WIDTH     (FALCON_PHY_ID_ID_WIDTH + 1)
-#define FALCON_PHY_ID_MASK      ((1 << FALCON_PHY_ID_WIDTH) - 1)
-#define FALCON_PHY_ID_10G       (1 << (FALCON_PHY_ID_WIDTH - 1))
-
-
-/* Packing the clause 45 port and device fields into a single value */
-#define MD_PRT_ADR_COMP_LBN   (MD_PRT_ADR_LBN - MD_DEV_ADR_LBN)
-#define MD_PRT_ADR_COMP_WIDTH  MD_PRT_ADR_WIDTH
-#define MD_DEV_ADR_COMP_LBN    0
-#define MD_DEV_ADR_COMP_WIDTH  MD_DEV_ADR_WIDTH
-
-
 /* Wait for GMII access to complete */
 static int falcon_gmii_wait(struct efx_nic *efx)
 {
@@ -2108,49 +2088,29 @@ static int falcon_gmii_wait(struct efx_nic *efx)
 	return -ETIMEDOUT;
 }
 
-/* Writes a GMII register of a PHY connected to Falcon using MDIO. */
-static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
-			      int addr, int value)
+/* Write an MDIO register of a PHY connected to Falcon. */
+static int falcon_mdio_write(struct net_device *net_dev,
+			     int prtad, int devad, u16 addr, u16 value)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
-	unsigned int phy_id2 = phy_id & FALCON_PHY_ID_ID_MASK;
 	efx_oword_t reg;
+	int rc;
 
-	/* The 'generic' prt/dev packing in mdio_10g.h is conveniently
-	 * chosen so that the only current user, Falcon, can take the
-	 * packed value and use them directly.
-	 * Fail to build if this assumption is broken.
-	 */
-	BUILD_BUG_ON(FALCON_PHY_ID_10G != MDIO45_XPRT_ID_IS10G);
-	BUILD_BUG_ON(FALCON_PHY_ID_ID_WIDTH != MDIO45_PRT_DEV_WIDTH);
-	BUILD_BUG_ON(MD_PRT_ADR_COMP_LBN != MDIO45_PRT_ID_COMP_LBN);
-	BUILD_BUG_ON(MD_DEV_ADR_COMP_LBN != MDIO45_DEV_ID_COMP_LBN);
-
-	if (phy_id2 == PHY_ADDR_INVALID)
-		return;
-
-	/* See falcon_mdio_read for an explanation. */
-	if (!(phy_id & FALCON_PHY_ID_10G)) {
-		int mmd = ffs(efx->phy_op->mmds) - 1;
-		EFX_TRACE(efx, "Fixing erroneous clause22 write\n");
-		phy_id2 = mdio_clause45_pack(phy_id2, mmd)
-			& FALCON_PHY_ID_ID_MASK;
-	}
-
-	EFX_REGDUMP(efx, "writing GMII %d register %02x with %04x\n", phy_id,
-		    addr, value);
+	EFX_REGDUMP(efx, "writing MDIO %d register %d.%d with 0x%04x\n",
+		    prtad, devad, addr, value);
 
 	spin_lock_bh(&efx->phy_lock);
 
-	/* Check MII not currently being accessed */
-	if (falcon_gmii_wait(efx) != 0)
+	/* Check MDIO not currently being accessed */
+	rc = falcon_gmii_wait(efx);
+	if (rc)
 		goto out;
 
 	/* Write the address/ID register */
 	EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr);
 	falcon_write(efx, &reg, MD_PHY_ADR_REG_KER);
 
-	EFX_POPULATE_OWORD_1(reg, MD_PRT_DEV_ADR, phy_id2);
+	EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad);
 	falcon_write(efx, &reg, MD_ID_REG_KER);
 
 	/* Write data */
@@ -2163,7 +2123,8 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
 	falcon_write(efx, &reg, MD_CS_REG_KER);
 
 	/* Wait for data to be written */
-	if (falcon_gmii_wait(efx) != 0) {
+	rc = falcon_gmii_wait(efx);
+	if (rc) {
 		/* Abort the write operation */
 		EFX_POPULATE_OWORD_2(reg,
 				     MD_WRC, 0,
@@ -2174,45 +2135,28 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
 
  out:
 	spin_unlock_bh(&efx->phy_lock);
+	return rc;
 }
 
-/* Reads a GMII register from a PHY connected to Falcon.  If no value
- * could be read, -1 will be returned. */
-static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
+/* Read an MDIO register of a PHY connected to Falcon. */
+static int falcon_mdio_read(struct net_device *net_dev,
+			    int prtad, int devad, u16 addr)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
-	unsigned int phy_addr = phy_id & FALCON_PHY_ID_ID_MASK;
 	efx_oword_t reg;
-	int value = -1;
-
-	if (phy_addr == PHY_ADDR_INVALID)
-		return -1;
-
-	/* Our PHY code knows whether it needs to talk clause 22(1G) or 45(10G)
-	 * but the generic Linux code does not make any distinction or have
-	 * any state for this.
-	 * We spot the case where someone tried to talk 22 to a 45 PHY and
-	 * redirect the request to the lowest numbered MMD as a clause45
-	 * request. This is enough to allow simple queries like id and link
-	 * state to succeed. TODO: We may need to do more in future.
-	 */
-	if (!(phy_id & FALCON_PHY_ID_10G)) {
-		int mmd = ffs(efx->phy_op->mmds) - 1;
-		EFX_TRACE(efx, "Fixing erroneous clause22 read\n");
-		phy_addr = mdio_clause45_pack(phy_addr, mmd)
-			& FALCON_PHY_ID_ID_MASK;
-	}
+	int rc;
 
 	spin_lock_bh(&efx->phy_lock);
 
-	/* Check MII not currently being accessed */
-	if (falcon_gmii_wait(efx) != 0)
+	/* Check MDIO not currently being accessed */
+	rc = falcon_gmii_wait(efx);
+	if (rc)
 		goto out;
 
 	EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr);
 	falcon_write(efx, &reg, MD_PHY_ADR_REG_KER);
 
-	EFX_POPULATE_OWORD_1(reg, MD_PRT_DEV_ADR, phy_addr);
+	EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad);
 	falcon_write(efx, &reg, MD_ID_REG_KER);
 
 	/* Request data to be read */
@@ -2220,12 +2164,12 @@ static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
 	falcon_write(efx, &reg, MD_CS_REG_KER);
 
 	/* Wait for data to become available */
-	value = falcon_gmii_wait(efx);
-	if (value == 0) {
+	rc = falcon_gmii_wait(efx);
+	if (rc == 0) {
 		falcon_read(efx, &reg, MD_RXD_REG_KER);
-		value = EFX_OWORD_FIELD(reg, MD_RXD);
-		EFX_REGDUMP(efx, "read from GMII %d register %02x, got %04x\n",
-			    phy_id, addr, value);
+		rc = EFX_OWORD_FIELD(reg, MD_RXD);
+		EFX_REGDUMP(efx, "read from MDIO %d register %d.%d, got %04x\n",
+			    prtad, devad, addr, rc);
 	} else {
 		/* Abort the read operation */
 		EFX_POPULATE_OWORD_2(reg,
@@ -2233,22 +2177,13 @@ static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
 				     MD_GC, 1);
 		falcon_write(efx, &reg, MD_CS_REG_KER);
 
-		EFX_LOG(efx, "read from GMII 0x%x register %02x, got "
-			"error %d\n", phy_id, addr, value);
+		EFX_LOG(efx, "read from MDIO %d register %d.%d, got error %d\n",
+			prtad, devad, addr, rc);
 	}
 
  out:
 	spin_unlock_bh(&efx->phy_lock);
-
-	return value;
-}
-
-static void falcon_init_mdio(struct mii_if_info *gmii)
-{
-	gmii->mdio_read = falcon_mdio_read;
-	gmii->mdio_write = falcon_mdio_write;
-	gmii->phy_id_mask = FALCON_PHY_ID_MASK;
-	gmii->reg_num_mask = ((1 << EFX_WIDTH(MD_PHY_ADR)) - 1);
+	return rc;
 }
 
 static int falcon_probe_phy(struct efx_nic *efx)
@@ -2342,9 +2277,11 @@ int falcon_probe_port(struct efx_nic *efx)
 	if (rc)
 		return rc;
 
-	/* Set up GMII structure for PHY */
-	efx->mii.supports_gmii = true;
-	falcon_init_mdio(&efx->mii);
+	/* Set up MDIO structure for PHY */
+	efx->mdio.mmds = efx->phy_op->mmds;
+	efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+	efx->mdio.mdio_read = falcon_mdio_read;
+	efx->mdio.mdio_write = falcon_mdio_write;
 
 	/* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */
 	if (falcon_rev(efx) >= FALCON_REV_B0)
@@ -2761,7 +2698,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
 	if (rc == -EINVAL) {
 		EFX_ERR(efx, "NVRAM is invalid therefore using defaults\n");
 		efx->phy_type = PHY_TYPE_NONE;
-		efx->mii.phy_id = PHY_ADDR_INVALID;
+		efx->mdio.prtad = MDIO_PRTAD_NONE;
 		board_rev = 0;
 		rc = 0;
 	} else if (rc) {
@@ -2771,7 +2708,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
 		struct falcon_nvconfig_board_v3 *v3 = &nvconfig->board_v3;
 
 		efx->phy_type = v2->port0_phy_type;
-		efx->mii.phy_id = v2->port0_phy_addr;
+		efx->mdio.prtad = v2->port0_phy_addr;
 		board_rev = le16_to_cpu(v2->board_revision);
 
 		if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) {
@@ -2793,7 +2730,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
 	/* Read the MAC addresses */
 	memcpy(efx->mac_address, nvconfig->mac_address[0], ETH_ALEN);
 
-	EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mii.phy_id);
+	EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad);
 
 	efx_set_board_info(efx, board_rev);
 
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h
index bda8d5b..375e2a5 100644
--- a/drivers/net/sfc/falcon_hwdefs.h
+++ b/drivers/net/sfc/falcon_hwdefs.h
@@ -456,9 +456,6 @@
 #define MD_PRT_ADR_WIDTH 5
 #define MD_DEV_ADR_LBN 6
 #define MD_DEV_ADR_WIDTH 5
-/* Used for writing both at once */
-#define MD_PRT_DEV_ADR_LBN 6
-#define MD_PRT_DEV_ADR_WIDTH 10
 
 /* PHY management status & mask register (DWORD read only) */
 #define MD_STAT_REG_KER 0xc50
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index 5a03713..2b3269c 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -133,7 +133,7 @@ bool falcon_xaui_link_ok(struct efx_nic *efx)
 	/* If the link is up, then check the phy side of the xaui link */
 	if (efx->link_up && link_ok)
 		if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS))
-			link_ok = mdio_clause45_phyxgxs_lane_sync(efx);
+			link_ok = efx_mdio_phyxgxs_lane_sync(efx);
 
 	return link_ok;
 }
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 9f5ec3e..11c231a 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -17,7 +17,7 @@
 #include "boards.h"
 #include "workarounds.h"
 
-unsigned mdio_id_oui(u32 id)
+unsigned efx_mdio_id_oui(u32 id)
 {
 	unsigned oui = 0;
 	int i;
@@ -32,52 +32,45 @@ unsigned mdio_id_oui(u32 id)
 	return oui;
 }
 
-int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
+int efx_mdio_reset_mmd(struct efx_nic *port, int mmd,
 			    int spins, int spintime)
 {
 	u32 ctrl;
-	int phy_id = port->mii.phy_id;
 
 	/* Catch callers passing values in the wrong units (or just silly) */
 	EFX_BUG_ON_PARANOID(spins * spintime >= 5000);
 
-	mdio_clause45_write(port, phy_id, mmd, MDIO_MMDREG_CTRL1,
-			    (1 << MDIO_MMDREG_CTRL1_RESET_LBN));
+	efx_mdio_write(port, mmd, MDIO_CTRL1, MDIO_CTRL1_RESET);
 	/* Wait for the reset bit to clear. */
 	do {
 		msleep(spintime);
-		ctrl = mdio_clause45_read(port, phy_id, mmd, MDIO_MMDREG_CTRL1);
+		ctrl = efx_mdio_read(port, mmd, MDIO_CTRL1);
 		spins--;
 
-	} while (spins && (ctrl & (1 << MDIO_MMDREG_CTRL1_RESET_LBN)));
+	} while (spins && (ctrl & MDIO_CTRL1_RESET));
 
 	return spins ? spins : -ETIMEDOUT;
 }
 
-static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd,
-				   int fault_fatal)
+static int efx_mdio_check_mmd(struct efx_nic *efx, int mmd, int fault_fatal)
 {
 	int status;
-	int phy_id = efx->mii.phy_id;
 
 	if (LOOPBACK_INTERNAL(efx))
 		return 0;
 
 	if (mmd != MDIO_MMD_AN) {
 		/* Read MMD STATUS2 to check it is responding. */
-		status = mdio_clause45_read(efx, phy_id, mmd,
-					    MDIO_MMDREG_STAT2);
-		if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) &
-		     ((1 << MDIO_MMDREG_STAT2_PRESENT_WIDTH) - 1)) !=
-		    MDIO_MMDREG_STAT2_PRESENT_VAL) {
+		status = efx_mdio_read(efx, mmd, MDIO_STAT2);
+		if ((status & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL) {
 			EFX_ERR(efx, "PHY MMD %d not responding.\n", mmd);
 			return -EIO;
 		}
 	}
 
 	/* Read MMD STATUS 1 to check for fault. */
-	status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT1);
-	if ((status & (1 << MDIO_MMDREG_STAT1_FAULT_LBN)) != 0) {
+	status = efx_mdio_read(efx, mmd, MDIO_STAT1);
+	if (status & MDIO_STAT1_FAULT) {
 		if (fault_fatal) {
 			EFX_ERR(efx, "PHY MMD %d reporting fatal"
 				" fault: status %x\n", mmd, status);
@@ -94,8 +87,7 @@ static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd,
 #define MDIO45_RESET_TIME	1000 /* ms */
 #define MDIO45_RESET_ITERS	100
 
-int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
-				  unsigned int mmd_mask)
+int efx_mdio_wait_reset_mmds(struct efx_nic *efx, unsigned int mmd_mask)
 {
 	const int spintime = MDIO45_RESET_TIME / MDIO45_RESET_ITERS;
 	int tries = MDIO45_RESET_ITERS;
@@ -109,16 +101,13 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
 		in_reset = 0;
 		while (mask) {
 			if (mask & 1) {
-				stat = mdio_clause45_read(efx,
-							  efx->mii.phy_id,
-							  mmd,
-							  MDIO_MMDREG_CTRL1);
+				stat = efx_mdio_read(efx, mmd, MDIO_CTRL1);
 				if (stat < 0) {
 					EFX_ERR(efx, "failed to read status of"
 						" MMD %d\n", mmd);
 					return -EIO;
 				}
-				if (stat & (1 << MDIO_MMDREG_CTRL1_RESET_LBN))
+				if (stat & MDIO_CTRL1_RESET)
 					in_reset |= (1 << mmd);
 			}
 			mask = mask >> 1;
@@ -137,28 +126,26 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
 	return rc;
 }
 
-int mdio_clause45_check_mmds(struct efx_nic *efx,
-			     unsigned int mmd_mask, unsigned int fatal_mask)
+int efx_mdio_check_mmds(struct efx_nic *efx,
+			unsigned int mmd_mask, unsigned int fatal_mask)
 {
-	int mmd = 0, probe_mmd, devs0, devs1;
+	int mmd = 0, probe_mmd, devs1, devs2;
 	u32 devices;
 
 	/* Historically we have probed the PHYXS to find out what devices are
 	 * present,but that doesn't work so well if the PHYXS isn't expected
 	 * to exist, if so just find the first item in the list supplied. */
-	probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS_PHYXS) ? MDIO_MMD_PHYXS :
+	probe_mmd = (mmd_mask & MDIO_DEVS_PHYXS) ? MDIO_MMD_PHYXS :
 	    __ffs(mmd_mask);
 
 	/* Check all the expected MMDs are present */
-	devs0 = mdio_clause45_read(efx, efx->mii.phy_id,
-				   probe_mmd, MDIO_MMDREG_DEVS0);
-	devs1 = mdio_clause45_read(efx, efx->mii.phy_id,
-				   probe_mmd, MDIO_MMDREG_DEVS1);
-	if (devs0 < 0 || devs1 < 0) {
+	devs1 = efx_mdio_read(efx, probe_mmd, MDIO_DEVS1);
+	devs2 = efx_mdio_read(efx, probe_mmd, MDIO_DEVS2);
+	if (devs1 < 0 || devs2 < 0) {
 		EFX_ERR(efx, "failed to read devices present\n");
 		return -EIO;
 	}
-	devices = devs0 | (devs1 << 16);
+	devices = devs1 | (devs2 << 16);
 	if ((devices & mmd_mask) != mmd_mask) {
 		EFX_ERR(efx, "required MMDs not present: got %x, "
 			"wanted %x\n", devices, mmd_mask);
@@ -170,7 +157,7 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,
 	while (mmd_mask) {
 		if (mmd_mask & 1) {
 			int fault_fatal = fatal_mask & 1;
-			if (mdio_clause45_check_mmd(efx, mmd, fault_fatal))
+			if (efx_mdio_check_mmd(efx, mmd, fault_fatal))
 				return -EIO;
 		}
 		mmd_mask = mmd_mask >> 1;
@@ -181,13 +168,8 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,
 	return 0;
 }
 
-bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
+bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
 {
-	int phy_id = efx->mii.phy_id;
-	u32 reg;
-	bool ok = true;
-	int mmd = 0;
-
 	/* If the port is in loopback, then we should only consider a subset
 	 * of mmd's */
 	if (LOOPBACK_INTERNAL(efx))
@@ -197,241 +179,75 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
 	else if (efx_phy_mode_disabled(efx->phy_mode))
 		return false;
 	else if (efx->loopback_mode == LOOPBACK_PHYXS)
-		mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS |
-			      MDIO_MMDREG_DEVS_PCS |
-			      MDIO_MMDREG_DEVS_PMAPMD |
-			      MDIO_MMDREG_DEVS_AN);
+		mmd_mask &= ~(MDIO_DEVS_PHYXS |
+			      MDIO_DEVS_PCS |
+			      MDIO_DEVS_PMAPMD |
+			      MDIO_DEVS_AN);
 	else if (efx->loopback_mode == LOOPBACK_PCS)
-		mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS |
-			      MDIO_MMDREG_DEVS_PMAPMD |
-			      MDIO_MMDREG_DEVS_AN);
+		mmd_mask &= ~(MDIO_DEVS_PCS |
+			      MDIO_DEVS_PMAPMD |
+			      MDIO_DEVS_AN);
 	else if (efx->loopback_mode == LOOPBACK_PMAPMD)
-		mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD |
-			      MDIO_MMDREG_DEVS_AN);
-
-	if (!mmd_mask) {
-		/* Use presence of XGMII faults in leui of link state */
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
-					 MDIO_PHYXS_STATUS2);
-		return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
-	}
+		mmd_mask &= ~(MDIO_DEVS_PMAPMD |
+			      MDIO_DEVS_AN);
 
-	while (mmd_mask) {
-		if (mmd_mask & 1) {
-			/* Double reads because link state is latched, and a
-			 * read moves the current state into the register */
-			reg = mdio_clause45_read(efx, phy_id,
-						 mmd, MDIO_MMDREG_STAT1);
-			reg = mdio_clause45_read(efx, phy_id,
-						 mmd, MDIO_MMDREG_STAT1);
-			ok = ok && (reg & (1 << MDIO_MMDREG_STAT1_LINK_LBN));
-		}
-		mmd_mask = (mmd_mask >> 1);
-		mmd++;
-	}
-	return ok;
+	return mdio45_links_ok(&efx->mdio, mmd_mask);
 }
 
-void mdio_clause45_transmit_disable(struct efx_nic *efx)
+void efx_mdio_transmit_disable(struct efx_nic *efx)
 {
-	mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-			       MDIO_MMDREG_TXDIS, MDIO_MMDREG_TXDIS_GLOBAL_LBN,
-			       efx->phy_mode & PHY_MODE_TX_DISABLED);
+	efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD,
+			  MDIO_PMA_TXDIS, MDIO_PMD_TXDIS_GLOBAL,
+			  efx->phy_mode & PHY_MODE_TX_DISABLED);
 }
 
-void mdio_clause45_phy_reconfigure(struct efx_nic *efx)
+void efx_mdio_phy_reconfigure(struct efx_nic *efx)
 {
-	int phy_id = efx->mii.phy_id;
-
-	mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
-			       MDIO_MMDREG_CTRL1, MDIO_PMAPMD_CTRL1_LBACK_LBN,
-			       efx->loopback_mode == LOOPBACK_PMAPMD);
-	mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PCS,
-			       MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
-			       efx->loopback_mode == LOOPBACK_PCS);
-	mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS,
-			       MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
-			       efx->loopback_mode == LOOPBACK_NETWORK);
+	efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD,
+			  MDIO_CTRL1, MDIO_PMA_CTRL1_LOOPBACK,
+			  efx->loopback_mode == LOOPBACK_PMAPMD);
+	efx_mdio_set_flag(efx, MDIO_MMD_PCS,
+			  MDIO_CTRL1, MDIO_PCS_CTRL1_LOOPBACK,
+			  efx->loopback_mode == LOOPBACK_PCS);
+	efx_mdio_set_flag(efx, MDIO_MMD_PHYXS,
+			  MDIO_CTRL1, MDIO_PHYXS_CTRL1_LOOPBACK,
+			  efx->loopback_mode == LOOPBACK_NETWORK);
 }
 
-static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx,
-					 int lpower, int mmd)
+static void efx_mdio_set_mmd_lpower(struct efx_nic *efx,
+				    int lpower, int mmd)
 {
-	int phy = efx->mii.phy_id;
-	int stat = mdio_clause45_read(efx, phy, mmd, MDIO_MMDREG_STAT1);
+	int stat = efx_mdio_read(efx, mmd, MDIO_STAT1);
 
 	EFX_TRACE(efx, "Setting low power mode for MMD %d to %d\n",
 		  mmd, lpower);
 
-	if (stat & (1 << MDIO_MMDREG_STAT1_LPABLE_LBN)) {
-		mdio_clause45_set_flag(efx, phy, mmd, MDIO_MMDREG_CTRL1,
-				       MDIO_MMDREG_CTRL1_LPOWER_LBN, lpower);
+	if (stat & MDIO_STAT1_LPOWERABLE) {
+		efx_mdio_set_flag(efx, mmd, MDIO_CTRL1,
+				  MDIO_CTRL1_LPOWER, lpower);
 	}
 }
 
-void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
-				   int low_power, unsigned int mmd_mask)
+void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
+			      int low_power, unsigned int mmd_mask)
 {
 	int mmd = 0;
-	mmd_mask &= ~MDIO_MMDREG_DEVS_AN;
+	mmd_mask &= ~MDIO_DEVS_AN;
 	while (mmd_mask) {
 		if (mmd_mask & 1)
-			mdio_clause45_set_mmd_lpower(efx, low_power, mmd);
+			efx_mdio_set_mmd_lpower(efx, low_power, mmd);
 		mmd_mask = (mmd_mask >> 1);
 		mmd++;
 	}
 }
 
-static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr)
-{
-	int phy_id = efx->mii.phy_id;
-	u32 result = 0;
-	int reg;
-
-	reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, addr);
-	if (reg & ADVERTISE_10HALF)
-		result |= ADVERTISED_10baseT_Half;
-	if (reg & ADVERTISE_10FULL)
-		result |= ADVERTISED_10baseT_Full;
-	if (reg & ADVERTISE_100HALF)
-		result |= ADVERTISED_100baseT_Half;
-	if (reg & ADVERTISE_100FULL)
-		result |= ADVERTISED_100baseT_Full;
-	return result;
-}
-
-/**
- * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO.
- * @efx:		Efx NIC
- * @ecmd: 		Buffer for settings
- *
- * On return the 'port', 'speed', 'supported' and 'advertising' fields of
- * ecmd have been filled out.
- */
-void mdio_clause45_get_settings(struct efx_nic *efx,
-				struct ethtool_cmd *ecmd)
-{
-	mdio_clause45_get_settings_ext(efx, ecmd, 0, 0);
-}
-
 /**
- * mdio_clause45_get_settings_ext - Read (some of) the PHY settings over MDIO.
- * @efx:		Efx NIC
- * @ecmd: 		Buffer for settings
- * @xnp:		Advertised Extended Next Page state
- * @xnp_lpa:		Link Partner's advertised XNP state
- *
- * On return the 'port', 'speed', 'supported' and 'advertising' fields of
- * ecmd have been filled out.
- */
-void mdio_clause45_get_settings_ext(struct efx_nic *efx,
-				    struct ethtool_cmd *ecmd,
-				    u32 npage_adv, u32 npage_lpa)
-{
-	int phy_id = efx->mii.phy_id;
-	int reg;
-
-	ecmd->transceiver = XCVR_INTERNAL;
-	ecmd->phy_address = phy_id;
-
-	reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-				 MDIO_MMDREG_CTRL2);
-	switch (reg & MDIO_PMAPMD_CTRL2_TYPE_MASK) {
-	case MDIO_PMAPMD_CTRL2_10G_BT:
-	case MDIO_PMAPMD_CTRL2_1G_BT:
-	case MDIO_PMAPMD_CTRL2_100_BT:
-	case MDIO_PMAPMD_CTRL2_10_BT:
-		ecmd->port = PORT_TP;
-		ecmd->supported = SUPPORTED_TP;
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-					 MDIO_MMDREG_SPEED);
-		if (reg & (1 << MDIO_MMDREG_SPEED_10G_LBN))
-			ecmd->supported |= SUPPORTED_10000baseT_Full;
-		if (reg & (1 << MDIO_MMDREG_SPEED_1000M_LBN))
-			ecmd->supported |= (SUPPORTED_1000baseT_Full |
-					    SUPPORTED_1000baseT_Half);
-		if (reg & (1 << MDIO_MMDREG_SPEED_100M_LBN))
-			ecmd->supported |= (SUPPORTED_100baseT_Full |
-					    SUPPORTED_100baseT_Half);
-		if (reg & (1 << MDIO_MMDREG_SPEED_10M_LBN))
-			ecmd->supported |= (SUPPORTED_10baseT_Full |
-					    SUPPORTED_10baseT_Half);
-		ecmd->advertising = ADVERTISED_TP;
-		break;
-
-	/* We represent CX4 as fibre in the absence of anything better */
-	case MDIO_PMAPMD_CTRL2_10G_CX4:
-	/* All the other defined modes are flavours of optical */
-	default:
-		ecmd->port = PORT_FIBRE;
-		ecmd->supported = SUPPORTED_FIBRE;
-		ecmd->advertising = ADVERTISED_FIBRE;
-		break;
-	}
-
-	if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
-		ecmd->supported |= SUPPORTED_Autoneg;
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-					 MDIO_MMDREG_CTRL1);
-		if (reg & BMCR_ANENABLE) {
-			ecmd->autoneg = AUTONEG_ENABLE;
-			ecmd->advertising |=
-				ADVERTISED_Autoneg |
-				mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) |
-				npage_adv;
-		} else
-			ecmd->autoneg = AUTONEG_DISABLE;
-	} else
-		ecmd->autoneg = AUTONEG_DISABLE;
-
-	if (ecmd->autoneg) {
-		/* If AN is complete, report best common mode,
-		 * otherwise report best advertised mode. */
-		u32 modes = 0;
-		if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-				       MDIO_MMDREG_STAT1) &
-		    (1 << MDIO_AN_STATUS_AN_DONE_LBN))
-			modes = (ecmd->advertising &
-				 (mdio_clause45_get_an(efx, MDIO_AN_LPA) |
-				  npage_lpa));
-		if (modes == 0)
-			modes = ecmd->advertising;
-
-		if (modes & ADVERTISED_10000baseT_Full) {
-			ecmd->speed = SPEED_10000;
-			ecmd->duplex = DUPLEX_FULL;
-		} else if (modes & (ADVERTISED_1000baseT_Full |
-				    ADVERTISED_1000baseT_Half)) {
-			ecmd->speed = SPEED_1000;
-			ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full);
-		} else if (modes & (ADVERTISED_100baseT_Full |
-				    ADVERTISED_100baseT_Half)) {
-			ecmd->speed = SPEED_100;
-			ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
-		} else {
-			ecmd->speed = SPEED_10;
-			ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
-		}
-	} else {
-		/* Report forced settings */
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-					 MDIO_MMDREG_CTRL1);
-		ecmd->speed = (((reg & BMCR_SPEED1000) ? 100 : 1) *
-			       ((reg & BMCR_SPEED100) ? 100 : 10));
-		ecmd->duplex = (reg & BMCR_FULLDPLX ||
-				ecmd->speed == SPEED_10000);
-	}
-}
-
-/**
- * mdio_clause45_set_settings - Set (some of) the PHY settings over MDIO.
+ * efx_mdio_set_settings - Set (some of) the PHY settings over MDIO.
  * @efx:		Efx NIC
  * @ecmd: 		New settings
  */
-int mdio_clause45_set_settings(struct efx_nic *efx,
-			       struct ethtool_cmd *ecmd)
+int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 {
-	int phy_id = efx->mii.phy_id;
 	struct ethtool_cmd prev;
 	u32 required;
 	int reg;
@@ -489,94 +305,67 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
 					      ADVERTISED_1000baseT_Full))
 			reg |= ADVERTISE_NPAGE;
 		reg |= efx_fc_advertise(efx->wanted_fc);
-		mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
-				    MDIO_AN_ADVERTISE, reg);
+		efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
 
 		/* Set up the (extended) next page if necessary */
 		if (efx->phy_op->set_npage_adv)
 			efx->phy_op->set_npage_adv(efx, ecmd->advertising);
 
 		/* Enable and restart AN */
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-					 MDIO_MMDREG_CTRL1);
-		reg |= BMCR_ANENABLE;
+		reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1);
+		reg |= MDIO_AN_CTRL1_ENABLE;
 		if (!(EFX_WORKAROUND_15195(efx) &&
 		      LOOPBACK_MASK(efx) & efx->phy_op->loopbacks))
-			reg |= BMCR_ANRESTART;
+			reg |= MDIO_AN_CTRL1_RESTART;
 		if (xnp)
-			reg |= 1 << MDIO_AN_CTRL_XNP_LBN;
+			reg |= MDIO_AN_CTRL1_XNP;
 		else
-			reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN);
-		mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
-				    MDIO_MMDREG_CTRL1, reg);
+			reg &= ~MDIO_AN_CTRL1_XNP;
+		efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg);
 	} else {
 		/* Disable AN */
-		mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
-				       MDIO_MMDREG_CTRL1,
-				       __ffs(BMCR_ANENABLE), false);
+		efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_CTRL1,
+				  MDIO_AN_CTRL1_ENABLE, false);
 
 		/* Set the basic control bits */
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-					 MDIO_MMDREG_CTRL1);
-		reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX |
-			 0x003c);
+		reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1);
+		reg &= ~(MDIO_CTRL1_SPEEDSEL | MDIO_CTRL1_FULLDPLX);
 		if (ecmd->speed == SPEED_100)
-			reg |= BMCR_SPEED100;
+			reg |= MDIO_PMA_CTRL1_SPEED100;
 		if (ecmd->duplex)
-			reg |= BMCR_FULLDPLX;
-		mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-				    MDIO_MMDREG_CTRL1, reg);
+			reg |= MDIO_CTRL1_FULLDPLX;
+		efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1, reg);
 	}
 
 	return 0;
 }
 
-void mdio_clause45_set_pause(struct efx_nic *efx)
+void efx_mdio_set_pause(struct efx_nic *efx)
 {
-	int phy_id = efx->mii.phy_id;
 	int reg;
 
-	if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
+	if (efx->phy_op->mmds & MDIO_DEVS_AN) {
 		/* Set pause capability advertising */
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-					 MDIO_AN_ADVERTISE);
+		reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
 		reg &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
 		reg |= efx_fc_advertise(efx->wanted_fc);
-		mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
-				    MDIO_AN_ADVERTISE, reg);
+		efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
 
 		/* Restart auto-negotiation */
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-					 MDIO_MMDREG_CTRL1);
-		if (reg & BMCR_ANENABLE) {
-			reg |= BMCR_ANRESTART;
-			mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
-					    MDIO_MMDREG_CTRL1, reg);
+		reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1);
+		if (reg & MDIO_AN_CTRL1_ENABLE) {
+			reg |= MDIO_AN_CTRL1_RESTART;
+			efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg);
 		}
 	}
 }
 
-enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx)
+enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx)
 {
-	int phy_id = efx->mii.phy_id;
 	int lpa;
 
-	if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)))
+	if (!(efx->phy_op->mmds & MDIO_DEVS_AN))
 		return efx->wanted_fc;
-	lpa = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, MDIO_AN_LPA);
+	lpa = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_LPA);
 	return efx_fc_resolve(efx->wanted_fc, lpa);
 }
-
-void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev,
-			    u16 addr, int bit, bool sense)
-{
-	int old_val = mdio_clause45_read(efx, prt, dev, addr);
-	int new_val;
-
-	if (sense)
-		new_val = old_val | (1 << bit);
-	else
-		new_val = old_val & ~(1 << bit);
-	if (old_val != new_val)
-		mdio_clause45_write(efx, prt, dev, addr, new_val);
-}
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 7014d22..ea4587d 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -10,247 +10,53 @@
 #ifndef EFX_MDIO_10G_H
 #define EFX_MDIO_10G_H
 
+#include <linux/mdio.h>
+
 /*
- * Definitions needed for doing 10G MDIO as specified in clause 45
- * MDIO, which do not appear in Linux yet. Also some helper functions.
+ * Helper functions for doing 10G MDIO as specified in IEEE 802.3 clause 45.
  */
 
 #include "efx.h"
 #include "boards.h"
 
-/* Numbering of the MDIO Manageable Devices (MMDs) */
-/* Physical Medium Attachment/ Physical Medium Dependent sublayer */
-#define MDIO_MMD_PMAPMD	(1)
-/* WAN Interface Sublayer */
-#define MDIO_MMD_WIS	(2)
-/* Physical Coding Sublayer */
-#define MDIO_MMD_PCS	(3)
-/* PHY Extender Sublayer */
-#define MDIO_MMD_PHYXS	(4)
-/* Extender Sublayer */
-#define MDIO_MMD_DTEXS	(5)
-/* Transmission convergence */
-#define MDIO_MMD_TC	(6)
-/* Auto negotiation */
-#define MDIO_MMD_AN	(7)
-/* Clause 22 extension */
-#define MDIO_MMD_C22EXT	29
-
-/* Generic register locations */
-#define MDIO_MMDREG_CTRL1	(0)
-#define MDIO_MMDREG_STAT1	(1)
-#define MDIO_MMDREG_IDHI	(2)
-#define MDIO_MMDREG_IDLOW	(3)
-#define MDIO_MMDREG_SPEED	(4)
-#define MDIO_MMDREG_DEVS0	(5)
-#define MDIO_MMDREG_DEVS1	(6)
-#define MDIO_MMDREG_CTRL2	(7)
-#define MDIO_MMDREG_STAT2	(8)
-#define MDIO_MMDREG_TXDIS	(9)
-
-/* Bits in MMDREG_CTRL1 */
-/* Reset */
-#define MDIO_MMDREG_CTRL1_RESET_LBN	(15)
-#define MDIO_MMDREG_CTRL1_RESET_WIDTH	(1)
-/* Loopback */
-/* Loopback bit for WIS, PCS, PHYSX and DTEXS */
-#define MDIO_MMDREG_CTRL1_LBACK_LBN	(14)
-#define MDIO_MMDREG_CTRL1_LBACK_WIDTH	(1)
-/* Low power */
-#define MDIO_MMDREG_CTRL1_LPOWER_LBN	(11)
-#define MDIO_MMDREG_CTRL1_LPOWER_WIDTH	(1)
-
-/* Bits in MMDREG_STAT1 */
-#define MDIO_MMDREG_STAT1_FAULT_LBN	(7)
-#define MDIO_MMDREG_STAT1_FAULT_WIDTH	(1)
-/* Link state */
-#define MDIO_MMDREG_STAT1_LINK_LBN	(2)
-#define MDIO_MMDREG_STAT1_LINK_WIDTH	(1)
-/* Low power ability */
-#define MDIO_MMDREG_STAT1_LPABLE_LBN	(1)
-#define MDIO_MMDREG_STAT1_LPABLE_WIDTH	(1)
-
-/* Bits in combined ID regs */
-static inline unsigned mdio_id_rev(u32 id) { return id & 0xf; }
-static inline unsigned mdio_id_model(u32 id) { return (id >> 4) & 0x3f; }
-extern unsigned mdio_id_oui(u32 id);
-
-/* Bits in MMDREG_DEVS0/1. Someone thoughtfully layed things out
- * so the 'bit present' bit number of an MMD is the number of
- * that MMD */
-#define DEV_PRESENT_BIT(_b) (1 << _b)
-
-#define MDIO_MMDREG_DEVS_PHYXS	DEV_PRESENT_BIT(MDIO_MMD_PHYXS)
-#define MDIO_MMDREG_DEVS_PCS	DEV_PRESENT_BIT(MDIO_MMD_PCS)
-#define MDIO_MMDREG_DEVS_PMAPMD	DEV_PRESENT_BIT(MDIO_MMD_PMAPMD)
-#define MDIO_MMDREG_DEVS_AN	DEV_PRESENT_BIT(MDIO_MMD_AN)
-#define MDIO_MMDREG_DEVS_C22EXT	DEV_PRESENT_BIT(MDIO_MMD_C22EXT)
-
-/* Bits in MMDREG_SPEED */
-#define MDIO_MMDREG_SPEED_10G_LBN	0
-#define MDIO_MMDREG_SPEED_10G_WIDTH	1
-#define MDIO_MMDREG_SPEED_1000M_LBN	4
-#define MDIO_MMDREG_SPEED_1000M_WIDTH	1
-#define MDIO_MMDREG_SPEED_100M_LBN	5
-#define MDIO_MMDREG_SPEED_100M_WIDTH	1
-#define MDIO_MMDREG_SPEED_10M_LBN	6
-#define MDIO_MMDREG_SPEED_10M_WIDTH	1
-
-/* Bits in MMDREG_STAT2 */
-#define MDIO_MMDREG_STAT2_PRESENT_VAL	(2)
-#define MDIO_MMDREG_STAT2_PRESENT_LBN	(14)
-#define MDIO_MMDREG_STAT2_PRESENT_WIDTH (2)
-
-/* Bits in MMDREG_TXDIS */
-#define MDIO_MMDREG_TXDIS_GLOBAL_LBN    (0)
-#define MDIO_MMDREG_TXDIS_GLOBAL_WIDTH  (1)
-
-/* MMD-specific bits, ordered by MMD, then register */
-#define MDIO_PMAPMD_CTRL1_LBACK_LBN	(0)
-#define MDIO_PMAPMD_CTRL1_LBACK_WIDTH	(1)
-
-/* PMA type (4 bits) */
-#define MDIO_PMAPMD_CTRL2_10G_CX4	(0x0)
-#define MDIO_PMAPMD_CTRL2_10G_EW	(0x1)
-#define MDIO_PMAPMD_CTRL2_10G_LW	(0x2)
-#define MDIO_PMAPMD_CTRL2_10G_SW	(0x3)
-#define MDIO_PMAPMD_CTRL2_10G_LX4	(0x4)
-#define MDIO_PMAPMD_CTRL2_10G_ER	(0x5)
-#define MDIO_PMAPMD_CTRL2_10G_LR	(0x6)
-#define MDIO_PMAPMD_CTRL2_10G_SR	(0x7)
-/* Reserved */
-#define MDIO_PMAPMD_CTRL2_10G_BT	(0x9)
-/* Reserved */
-/* Reserved */
-#define MDIO_PMAPMD_CTRL2_1G_BT		(0xc)
-/* Reserved */
-#define MDIO_PMAPMD_CTRL2_100_BT	(0xe)
-#define MDIO_PMAPMD_CTRL2_10_BT		(0xf)
-#define MDIO_PMAPMD_CTRL2_TYPE_MASK	(0xf)
-
-/* PMA 10GBT registers */
-#define MDIO_PMAPMD_10GBT_TXPWR		(131)
-#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN (0)
-#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_WIDTH (1)
-
-/* PHY XGXS Status 2 */
-#define MDIO_PHYXS_STATUS2              (8)
-#define MDIO_PHYXS_STATUS2_RX_FAULT_LBN 10
-
-/* PHY XGXS lane state */
-#define MDIO_PHYXS_LANE_STATE		(0x18)
-#define MDIO_PHYXS_LANE_ALIGNED_LBN	(12)
-
-/* AN registers */
-#define MDIO_AN_CTRL_XNP_LBN		13
-#define MDIO_AN_STATUS			(1)
-#define MDIO_AN_STATUS_XNP_LBN		(7)
-#define MDIO_AN_STATUS_PAGE_LBN		(6)
-#define MDIO_AN_STATUS_AN_DONE_LBN	(5)
-#define MDIO_AN_STATUS_LP_AN_CAP_LBN	(0)
-
-#define MDIO_AN_ADVERTISE		16
-#define MDIO_AN_ADVERTISE_XNP_LBN	12
-#define MDIO_AN_LPA			19
-#define MDIO_AN_XNP			22
-#define MDIO_AN_LPA_XNP			25
-
-#define MDIO_AN_10GBT_CTRL		32
-#define MDIO_AN_10GBT_CTRL_ADV_10G_LBN	12
-#define MDIO_AN_10GBT_STATUS		(33)
-#define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */
-#define MDIO_AN_10GBT_STATUS_MS_LBN     (14) /* MASTER/SLAVE config */
-#define MDIO_AN_10GBT_STATUS_LOC_OK_LBN (13) /* Local OK */
-#define MDIO_AN_10GBT_STATUS_REM_OK_LBN (12) /* Remote OK */
-#define MDIO_AN_10GBT_STATUS_LP_10G_LBN (11) /* Link partner is 10GBT capable */
-#define MDIO_AN_10GBT_STATUS_LP_LTA_LBN (10) /* LP loop timing ability */
-#define MDIO_AN_10GBT_STATUS_LP_TRR_LBN (9)  /* LP Training Reset Request */
+static inline unsigned efx_mdio_id_rev(u32 id) { return id & 0xf; }
+static inline unsigned efx_mdio_id_model(u32 id) { return (id >> 4) & 0x3f; }
+extern unsigned efx_mdio_id_oui(u32 id);
 
-
-/* Packing of the prt and dev arguments of clause 45 style MDIO into a
- * single int so they can be passed into the mdio_read/write functions
- * that currently exist. Note that as Falcon is the only current user,
- * the packed form is chosen to match what Falcon needs to write into
- * a register. This is checked at compile-time so do not change it. If
- * your target chip needs things layed out differently you will need
- * to unpack the arguments in your chip-specific mdio functions.
- */
- /* These are defined by the standard. */
-#define MDIO45_PRT_ID_WIDTH  (5)
-#define MDIO45_DEV_ID_WIDTH  (5)
-
-/* The prt ID is just packed in immediately to the left of the dev ID */
-#define MDIO45_PRT_DEV_WIDTH (MDIO45_PRT_ID_WIDTH + MDIO45_DEV_ID_WIDTH)
-
-#define MDIO45_PRT_ID_MASK   ((1 << MDIO45_PRT_DEV_WIDTH) - 1)
-/* This is the prt + dev extended by 1 bit to hold the 'is clause 45' flag. */
-#define MDIO45_XPRT_ID_WIDTH   (MDIO45_PRT_DEV_WIDTH + 1)
-#define MDIO45_XPRT_ID_MASK   ((1 << MDIO45_XPRT_ID_WIDTH) - 1)
-#define MDIO45_XPRT_ID_IS10G   (1 << (MDIO45_XPRT_ID_WIDTH - 1))
-
-
-#define MDIO45_PRT_ID_COMP_LBN   MDIO45_DEV_ID_WIDTH
-#define MDIO45_PRT_ID_COMP_WIDTH  MDIO45_PRT_ID_WIDTH
-#define MDIO45_DEV_ID_COMP_LBN    0
-#define MDIO45_DEV_ID_COMP_WIDTH  MDIO45_DEV_ID_WIDTH
-
-/* Compose port and device into a phy_id */
-static inline int mdio_clause45_pack(u8 prt, u8 dev)
-{
-	efx_dword_t phy_id;
-	EFX_POPULATE_DWORD_2(phy_id, MDIO45_PRT_ID_COMP, prt,
-			     MDIO45_DEV_ID_COMP, dev);
-	return MDIO45_XPRT_ID_IS10G | EFX_DWORD_VAL(phy_id);
-}
-
-static inline void mdio_clause45_unpack(u32 val, u8 *prt, u8 *dev)
+static inline int efx_mdio_read(struct efx_nic *efx, int devad, int addr)
 {
-	efx_dword_t phy_id;
-	EFX_POPULATE_DWORD_1(phy_id, EFX_DWORD_0, val);
-	*prt = EFX_DWORD_FIELD(phy_id, MDIO45_PRT_ID_COMP);
-	*dev = EFX_DWORD_FIELD(phy_id, MDIO45_DEV_ID_COMP);
+	return efx->mdio.mdio_read(efx->net_dev, efx->mdio.prtad, devad, addr);
 }
 
-static inline int mdio_clause45_read(struct efx_nic *efx,
-				     u8 prt, u8 dev, u16 addr)
+static inline void
+efx_mdio_write(struct efx_nic *efx, int devad, int addr, int value)
 {
-	return efx->mii.mdio_read(efx->net_dev,
-				  mdio_clause45_pack(prt, dev), addr);
+	efx->mdio.mdio_write(efx->net_dev, efx->mdio.prtad, devad, addr, value);
 }
 
-static inline void mdio_clause45_write(struct efx_nic *efx,
-				       u8 prt, u8 dev, u16 addr, int value)
-{
-	efx->mii.mdio_write(efx->net_dev,
-			    mdio_clause45_pack(prt, dev), addr, value);
-}
-
-
-static inline u32 mdio_clause45_read_id(struct efx_nic *efx, int mmd)
+static inline u32 efx_mdio_read_id(struct efx_nic *efx, int mmd)
 {
-	int phy_id = efx->mii.phy_id;
-	u16 id_low = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_IDLOW);
-	u16 id_hi = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_IDHI);
+	u16 id_low = efx_mdio_read(efx, mmd, MDIO_DEVID2);
+	u16 id_hi = efx_mdio_read(efx, mmd, MDIO_DEVID1);
 	return (id_hi << 16) | (id_low);
 }
 
-static inline bool mdio_clause45_phyxgxs_lane_sync(struct efx_nic *efx)
+static inline bool efx_mdio_phyxgxs_lane_sync(struct efx_nic *efx)
 {
 	int i, lane_status;
 	bool sync;
 
 	for (i = 0; i < 2; ++i)
-		lane_status = mdio_clause45_read(efx, efx->mii.phy_id,
-						 MDIO_MMD_PHYXS,
-						 MDIO_PHYXS_LANE_STATE);
+		lane_status = efx_mdio_read(efx, MDIO_MMD_PHYXS,
+					    MDIO_PHYXS_LNSTAT);
 
-	sync = !!(lane_status & (1 << MDIO_PHYXS_LANE_ALIGNED_LBN));
+	sync = !!(lane_status & MDIO_PHYXS_LNSTAT_ALIGN);
 	if (!sync)
 		EFX_LOG(efx, "XGXS lane status: %x\n", lane_status);
 	return sync;
 }
 
-extern const char *mdio_clause45_mmd_name(int mmd);
+extern const char *efx_mdio_mmd_name(int mmd);
 
 /*
  * Reset a specific MMD and wait for reset to clear.
@@ -258,54 +64,47 @@ extern const char *mdio_clause45_mmd_name(int mmd);
  *
  * This function will sleep
  */
-extern int mdio_clause45_reset_mmd(struct efx_nic *efx, int mmd,
-				   int spins, int spintime);
+extern int efx_mdio_reset_mmd(struct efx_nic *efx, int mmd,
+			      int spins, int spintime);
 
-/* As mdio_clause45_check_mmd but for multiple MMDs */
-int mdio_clause45_check_mmds(struct efx_nic *efx,
-			     unsigned int mmd_mask, unsigned int fatal_mask);
+/* As efx_mdio_check_mmd but for multiple MMDs */
+int efx_mdio_check_mmds(struct efx_nic *efx,
+			unsigned int mmd_mask, unsigned int fatal_mask);
 
 /* Check the link status of specified mmds in bit mask */
-extern bool mdio_clause45_links_ok(struct efx_nic *efx,
-				   unsigned int mmd_mask);
+extern bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask);
 
 /* Generic transmit disable support though PMAPMD */
-extern void mdio_clause45_transmit_disable(struct efx_nic *efx);
+extern void efx_mdio_transmit_disable(struct efx_nic *efx);
 
 /* Generic part of reconfigure: set/clear loopback bits */
-extern void mdio_clause45_phy_reconfigure(struct efx_nic *efx);
+extern void efx_mdio_phy_reconfigure(struct efx_nic *efx);
 
 /* Set the power state of the specified MMDs */
-extern void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
-					  int low_power, unsigned int mmd_mask);
-
-/* Read (some of) the PHY settings over MDIO */
-extern void mdio_clause45_get_settings(struct efx_nic *efx,
-				       struct ethtool_cmd *ecmd);
-
-/* Read (some of) the PHY settings over MDIO */
-extern void
-mdio_clause45_get_settings_ext(struct efx_nic *efx, struct ethtool_cmd *ecmd,
-			       u32 xnp, u32 xnp_lpa);
+extern void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
+				     int low_power, unsigned int mmd_mask);
 
 /* Set (some of) the PHY settings over MDIO */
-extern int mdio_clause45_set_settings(struct efx_nic *efx,
-				      struct ethtool_cmd *ecmd);
+extern int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd);
 
 /* Set pause parameters to be advertised through AN (if available) */
-extern void mdio_clause45_set_pause(struct efx_nic *efx);
+extern void efx_mdio_set_pause(struct efx_nic *efx);
 
 /* Get pause parameters from AN if available (otherwise return
  * requested pause parameters)
  */
-enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx);
+enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx);
 
 /* Wait for specified MMDs to exit reset within a timeout */
-extern int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
-					 unsigned int mmd_mask);
+extern int efx_mdio_wait_reset_mmds(struct efx_nic *efx,
+				    unsigned int mmd_mask);
 
 /* Set or clear flag, debouncing */
-extern void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev,
-				   u16 addr, int bit, bool sense);
+static inline void
+efx_mdio_set_flag(struct efx_nic *efx, int devad, int addr,
+		  int mask, bool state)
+{
+	mdio_set_flag(&efx->mdio, efx->mdio.prtad, devad, addr, mask, state);
+}
 
 #endif /* EFX_MDIO_10G_H */
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index e169e5d..457e2f1 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -19,7 +19,7 @@
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
 #include <linux/timer.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
 #include <linux/list.h>
 #include <linux/pci.h>
 #include <linux/device.h>
@@ -458,8 +458,6 @@ enum phy_type {
 	PHY_TYPE_MAX	/* Insert any new items before this */
 };
 
-#define PHY_ADDR_INVALID 0xff
-
 #define EFX_IS10G(efx) ((efx)->link_speed == 10000)
 
 enum nic_state {
@@ -758,7 +756,7 @@ union efx_multicast_hash {
  * @phy_lock: PHY access lock
  * @phy_op: PHY interface
  * @phy_data: PHY private data (including PHY-specific stats)
- * @mii: PHY interface
+ * @mdio: PHY MDIO interface
  * @phy_mode: PHY operating mode. Serialised by @mac_lock.
  * @mac_up: MAC link state
  * @link_up: Link status
@@ -845,7 +843,7 @@ struct efx_nic {
 	struct work_struct phy_work;
 	struct efx_phy_operations *phy_op;
 	void *phy_data;
-	struct mii_if_info mii;
+	struct mdio_if_info mdio;
 	enum efx_phy_mode phy_mode;
 
 	bool mac_up;
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 0a59808..0437957 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -80,39 +80,38 @@ struct efx_loopback_state {
  *
  **************************************************************************/
 
-static int efx_test_mii(struct efx_nic *efx, struct efx_self_tests *tests)
+static int efx_test_mdio(struct efx_nic *efx, struct efx_self_tests *tests)
 {
 	int rc = 0;
+	int devad = __ffs(efx->mdio.mmds);
 	u16 physid1, physid2;
-	struct mii_if_info *mii = &efx->mii;
-	struct net_device *net_dev = efx->net_dev;
 
 	if (efx->phy_type == PHY_TYPE_NONE)
 		return 0;
 
 	mutex_lock(&efx->mac_lock);
-	tests->mii = -1;
+	tests->mdio = -1;
 
-	physid1 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID1);
-	physid2 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID2);
+	physid1 = efx_mdio_read(efx, devad, MDIO_DEVID1);
+	physid2 = efx_mdio_read(efx, devad, MDIO_DEVID2);
 
 	if ((physid1 == 0x0000) || (physid1 == 0xffff) ||
 	    (physid2 == 0x0000) || (physid2 == 0xffff)) {
-		EFX_ERR(efx, "no MII PHY present with ID %d\n",
-			mii->phy_id);
+		EFX_ERR(efx, "no MDIO PHY present with ID %d\n",
+			efx->mdio.prtad);
 		rc = -EINVAL;
 		goto out;
 	}
 
 	if (EFX_IS10G(efx)) {
-		rc = mdio_clause45_check_mmds(efx, efx->phy_op->mmds, 0);
+		rc = efx_mdio_check_mmds(efx, efx->phy_op->mmds, 0);
 		if (rc)
 			goto out;
 	}
 
 out:
 	mutex_unlock(&efx->mac_lock);
-	tests->mii = rc ? -1 : 1;
+	tests->mdio = rc ? -1 : 1;
 	return rc;
 }
 
@@ -673,7 +672,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
 	/* Online (i.e. non-disruptive) testing
 	 * This checks interrupt generation, event delivery and PHY presence. */
 
-	rc = efx_test_mii(efx, tests);
+	rc = efx_test_mdio(efx, tests);
 	if (rc && !rc_test)
 		rc_test = rc;
 
diff --git a/drivers/net/sfc/selftest.h b/drivers/net/sfc/selftest.h
index 39451cf..f6feee0 100644
--- a/drivers/net/sfc/selftest.h
+++ b/drivers/net/sfc/selftest.h
@@ -32,7 +32,7 @@ struct efx_loopback_self_tests {
  */
 struct efx_self_tests {
 	/* online tests */
-	int mii;
+	int mdio;
 	int nvram;
 	int interrupt;
 	int eventq_dma[EFX_MAX_CHANNELS];
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index e61dc4d..403f7d7 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -23,10 +23,10 @@
  * clause 22 extension MMD, but since it doesn't have all the generic
  * MMD registers it is pointless to include it here.
  */
-#define TENXPRESS_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PMAPMD	| \
-				 MDIO_MMDREG_DEVS_PCS		| \
-				 MDIO_MMDREG_DEVS_PHYXS		| \
-				 MDIO_MMDREG_DEVS_AN)
+#define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD	| \
+				 MDIO_DEVS_PCS		| \
+				 MDIO_DEVS_PHYXS	| \
+				 MDIO_DEVS_AN)
 
 #define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) |	\
 			   (1 << LOOPBACK_PCS) |	\
@@ -153,10 +153,6 @@
 #define LOOPBACK_NEAR_LBN   (8)
 #define LOOPBACK_NEAR_WIDTH (1)
 
-#define PCS_10GBASET_STAT1       32
-#define PCS_10GBASET_BLKLK_LBN   0
-#define PCS_10GBASET_BLKLK_WIDTH 1
-
 /* Boot status register */
 #define PCS_BOOT_STATUS_REG		53248
 #define PCS_BOOT_FATAL_ERROR_LBN	0
@@ -206,10 +202,8 @@ static ssize_t show_phy_short_reach(struct device *dev,
 	struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
 	int reg;
 
-	reg = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-				 MDIO_PMAPMD_10GBT_TXPWR);
-	return sprintf(buf, "%d\n",
-		       !!(reg & (1 << MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN)));
+	reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR);
+	return sprintf(buf, "%d\n", !!(reg & MDIO_PMA_10GBT_TXPWR_SHORT));
 }
 
 static ssize_t set_phy_short_reach(struct device *dev,
@@ -219,10 +213,9 @@ static ssize_t set_phy_short_reach(struct device *dev,
 	struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
 
 	rtnl_lock();
-	mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-			       MDIO_PMAPMD_10GBT_TXPWR,
-			       MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN,
-			       count != 0 && *buf != '0');
+	efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR,
+			  MDIO_PMA_10GBT_TXPWR_SHORT,
+			  count != 0 && *buf != '0');
 	efx_reconfigure_port(efx);
 	rtnl_unlock();
 
@@ -238,9 +231,8 @@ int sft9001_wait_boot(struct efx_nic *efx)
 	int boot_stat;
 
 	for (;;) {
-		boot_stat = mdio_clause45_read(efx, efx->mii.phy_id,
-					       MDIO_MMD_PCS,
-					       PCS_BOOT_STATUS_REG);
+		boot_stat = efx_mdio_read(efx, MDIO_MMD_PCS,
+					  PCS_BOOT_STATUS_REG);
 		if (boot_stat >= 0) {
 			EFX_LOG(efx, "PHY boot status = %#x\n", boot_stat);
 			switch (boot_stat &
@@ -286,38 +278,32 @@ int sft9001_wait_boot(struct efx_nic *efx)
 
 static int tenxpress_init(struct efx_nic *efx)
 {
-	int phy_id = efx->mii.phy_id;
 	int reg;
 
 	if (efx->phy_type == PHY_TYPE_SFX7101) {
 		/* Enable 312.5 MHz clock */
-		mdio_clause45_write(efx, phy_id,
-				    MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
-				    1 << CLK312_EN_LBN);
+		efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
+			       1 << CLK312_EN_LBN);
 	} else {
 		/* Enable 312.5 MHz clock and GMII */
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-					 PMA_PMD_XCONTROL_REG);
+		reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
 		reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) |
 			(1 << PMA_PMD_EXT_CLK_OUT_LBN) |
 			(1 << PMA_PMD_EXT_CLK312_LBN) |
 			(1 << PMA_PMD_EXT_ROBUST_LBN));
 
-		mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-				    PMA_PMD_XCONTROL_REG, reg);
-		mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
-				       GPHY_XCONTROL_REG, GPHY_ISOLATE_LBN,
-				       false);
+		efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
+		efx_mdio_set_flag(efx, MDIO_MMD_C22EXT,
+			      GPHY_XCONTROL_REG, 1 << GPHY_ISOLATE_LBN,
+			      false);
 	}
 
 	/* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
 	if (efx->phy_type == PHY_TYPE_SFX7101) {
-		mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
-				       PMA_PMD_LED_CTRL_REG,
-				       PMA_PMA_LED_ACTIVITY_LBN,
-				       true);
-		mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-				    PMA_PMD_LED_OVERR_REG, PMA_PMD_LED_DEFAULT);
+		efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG,
+				  1 << PMA_PMA_LED_ACTIVITY_LBN, true);
+		efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG,
+			       PMA_PMD_LED_DEFAULT);
 	}
 
 	return 0;
@@ -337,22 +323,19 @@ static int tenxpress_phy_init(struct efx_nic *efx)
 	if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
 		if (efx->phy_type == PHY_TYPE_SFT9001A) {
 			int reg;
-			reg = mdio_clause45_read(efx, efx->mii.phy_id,
-						 MDIO_MMD_PMAPMD,
-						 PMA_PMD_XCONTROL_REG);
+			reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+					    PMA_PMD_XCONTROL_REG);
 			reg |= (1 << PMA_PMD_EXT_SSR_LBN);
-			mdio_clause45_write(efx, efx->mii.phy_id,
-					    MDIO_MMD_PMAPMD,
-					    PMA_PMD_XCONTROL_REG, reg);
+			efx_mdio_write(efx, MDIO_MMD_PMAPMD,
+				       PMA_PMD_XCONTROL_REG, reg);
 			mdelay(200);
 		}
 
-		rc = mdio_clause45_wait_reset_mmds(efx,
-						   TENXPRESS_REQUIRED_DEVS);
+		rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
 		if (rc < 0)
 			goto fail;
 
-		rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
+		rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
 		if (rc < 0)
 			goto fail;
 	}
@@ -360,7 +343,7 @@ static int tenxpress_phy_init(struct efx_nic *efx)
 	rc = tenxpress_init(efx);
 	if (rc < 0)
 		goto fail;
-	mdio_clause45_set_pause(efx);
+	efx_mdio_set_pause(efx);
 
 	if (efx->phy_type == PHY_TYPE_SFT9001B) {
 		rc = device_create_file(&efx->pci_dev->dev,
@@ -395,17 +378,14 @@ static int tenxpress_special_reset(struct efx_nic *efx)
 	efx_stats_disable(efx);
 
 	/* Initiate reset */
-	reg = mdio_clause45_read(efx, efx->mii.phy_id,
-				 MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
+	reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
 	reg |= (1 << PMA_PMD_EXT_SSR_LBN);
-	mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-			    PMA_PMD_XCONTROL_REG, reg);
+	efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
 
 	mdelay(200);
 
 	/* Wait for the blocks to come out of reset */
-	rc = mdio_clause45_wait_reset_mmds(efx,
-					   TENXPRESS_REQUIRED_DEVS);
+	rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
 	if (rc < 0)
 		goto out;
 
@@ -424,7 +404,6 @@ out:
 static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
 {
 	struct tenxpress_phy_data *pd = efx->phy_data;
-	int phy_id = efx->mii.phy_id;
 	bool bad_lp;
 	int reg;
 
@@ -432,11 +411,10 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
 		bad_lp = false;
 	} else {
 		/* Check that AN has started but not completed. */
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-					 MDIO_AN_STATUS);
-		if (!(reg & (1 << MDIO_AN_STATUS_LP_AN_CAP_LBN)))
+		reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_STAT1);
+		if (!(reg & MDIO_AN_STAT1_LPABLE))
 			return; /* LP status is unknown */
-		bad_lp = !(reg & (1 << MDIO_AN_STATUS_AN_DONE_LBN));
+		bad_lp = !(reg & MDIO_AN_STAT1_COMPLETE);
 		if (bad_lp)
 			pd->bad_lp_tries++;
 	}
@@ -448,8 +426,8 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
 	/* Use the RX (red) LED as an error indicator once we've seen AN
 	 * failure several times in a row, and also log a message. */
 	if (!bad_lp || pd->bad_lp_tries == MAX_BAD_LP_TRIES) {
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-					 PMA_PMD_LED_OVERR_REG);
+		reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+				    PMA_PMD_LED_OVERR_REG);
 		reg &= ~(PMA_PMD_LED_MASK << PMA_PMD_LED_RX_LBN);
 		if (!bad_lp) {
 			reg |= PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN;
@@ -460,23 +438,22 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
 				" supports 10GBASE-T ONLY, so no link can"
 				" be established\n");
 		}
-		mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-				    PMA_PMD_LED_OVERR_REG, reg);
+		efx_mdio_write(efx, MDIO_MMD_PMAPMD,
+			       PMA_PMD_LED_OVERR_REG, reg);
 		pd->bad_lp_tries = bad_lp;
 	}
 }
 
 static bool sfx7101_link_ok(struct efx_nic *efx)
 {
-	return mdio_clause45_links_ok(efx,
-				      MDIO_MMDREG_DEVS_PMAPMD |
-				      MDIO_MMDREG_DEVS_PCS |
-				      MDIO_MMDREG_DEVS_PHYXS);
+	return efx_mdio_links_ok(efx,
+				 MDIO_DEVS_PMAPMD |
+				 MDIO_DEVS_PCS |
+				 MDIO_DEVS_PHYXS);
 }
 
 static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 {
-	int phy_id = efx->mii.phy_id;
 	u32 reg;
 
 	if (efx_phy_mode_disabled(efx->phy_mode))
@@ -484,50 +461,43 @@ static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 	else if (efx->loopback_mode == LOOPBACK_GPHY)
 		return true;
 	else if (efx->loopback_mode)
-		return mdio_clause45_links_ok(efx,
-					      MDIO_MMDREG_DEVS_PMAPMD |
-					      MDIO_MMDREG_DEVS_PHYXS);
+		return efx_mdio_links_ok(efx,
+					 MDIO_DEVS_PMAPMD |
+					 MDIO_DEVS_PHYXS);
 
 	/* We must use the same definition of link state as LASI,
 	 * otherwise we can miss a link state transition
 	 */
 	if (ecmd->speed == 10000) {
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
-					 PCS_10GBASET_STAT1);
-		return reg & (1 << PCS_10GBASET_BLKLK_LBN);
+		reg = efx_mdio_read(efx, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1);
+		return reg & MDIO_PCS_10GBRT_STAT1_BLKLK;
 	} else {
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
-					 C22EXT_STATUS_REG);
+		reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_STATUS_REG);
 		return reg & (1 << C22EXT_STATUS_LINK_LBN);
 	}
 }
 
 static void tenxpress_ext_loopback(struct efx_nic *efx)
 {
-	int phy_id = efx->mii.phy_id;
-
-	mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS,
-			       PHYXS_TEST1, LOOPBACK_NEAR_LBN,
-			       efx->loopback_mode == LOOPBACK_PHYXS);
+	efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, PHYXS_TEST1,
+			  1 << LOOPBACK_NEAR_LBN,
+			  efx->loopback_mode == LOOPBACK_PHYXS);
 	if (efx->phy_type != PHY_TYPE_SFX7101)
-		mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
-				       GPHY_XCONTROL_REG,
-				       GPHY_LOOPBACK_NEAR_LBN,
-				       efx->loopback_mode == LOOPBACK_GPHY);
+		efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, GPHY_XCONTROL_REG,
+				  1 << GPHY_LOOPBACK_NEAR_LBN,
+				  efx->loopback_mode == LOOPBACK_GPHY);
 }
 
 static void tenxpress_low_power(struct efx_nic *efx)
 {
-	int phy_id = efx->mii.phy_id;
-
 	if (efx->phy_type == PHY_TYPE_SFX7101)
-		mdio_clause45_set_mmds_lpower(
+		efx_mdio_set_mmds_lpower(
 			efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER),
 			TENXPRESS_REQUIRED_DEVS);
 	else
-		mdio_clause45_set_flag(
-			efx, phy_id, MDIO_MMD_PMAPMD,
-			PMA_PMD_XCONTROL_REG, PMA_PMD_EXT_LPOWER_LBN,
+		efx_mdio_set_flag(
+			efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG,
+			1 << PMA_PMD_EXT_LPOWER_LBN,
 			!!(efx->phy_mode & PHY_MODE_LOW_POWER));
 }
 
@@ -568,8 +538,8 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
 		WARN_ON(rc);
 	}
 
-	mdio_clause45_transmit_disable(efx);
-	mdio_clause45_phy_reconfigure(efx);
+	efx_mdio_transmit_disable(efx);
+	efx_mdio_phy_reconfigure(efx);
 	tenxpress_ext_loopback(efx);
 
 	phy_data->loopback_mode = efx->loopback_mode;
@@ -585,7 +555,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
 		efx->link_fd = ecmd.duplex == DUPLEX_FULL;
 		efx->link_up = sft9001_link_ok(efx, &ecmd);
 	}
-	efx->link_fc = mdio_clause45_get_pause(efx);
+	efx->link_fc = efx_mdio_get_pause(efx);
 }
 
 /* Poll PHY for interrupt */
@@ -599,7 +569,7 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
 		if (link_ok != efx->link_up) {
 			change = true;
 		} else {
-			unsigned int link_fc = mdio_clause45_get_pause(efx);
+			unsigned int link_fc = efx_mdio_get_pause(efx);
 			if (link_fc != efx->link_fc)
 				change = true;
 		}
@@ -609,9 +579,8 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
 		if (link_ok != efx->link_up)
 			change = true;
 	} else {
-		u32 status = mdio_clause45_read(efx, efx->mii.phy_id,
-						MDIO_MMD_PMAPMD,
-						PMA_PMD_LASI_STATUS);
+		int status = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+					   PMA_PMD_LASI_STATUS);
 		if (status & (1 << PMA_PMD_LS_ALARM_LBN))
 			change = true;
 	}
@@ -634,8 +603,7 @@ static void tenxpress_phy_fini(struct efx_nic *efx)
 	if (efx->phy_type == PHY_TYPE_SFX7101) {
 		/* Power down the LNPGA */
 		reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN);
-		mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-				    PMA_PMD_XCONTROL_REG, reg);
+		efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
 
 		/* Waiting here ensures that the board fini, which can turn
 		 * off the power to the PHY, won't get run until the LNPGA
@@ -661,8 +629,7 @@ void tenxpress_phy_blink(struct efx_nic *efx, bool blink)
 	else
 		reg = PMA_PMD_LED_DEFAULT;
 
-	mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-			    PMA_PMD_LED_OVERR_REG, reg);
+	efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg);
 }
 
 static const char *const sfx7101_test_names[] = {
@@ -698,7 +665,6 @@ static const char *const sft9001_test_names[] = {
 static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
 {
 	struct ethtool_cmd ecmd;
-	int phy_id = efx->mii.phy_id;
 	int rc = 0, rc2, i, ctrl_reg, res_reg;
 
 	if (flags & ETH_TEST_FL_OFFLINE)
@@ -717,11 +683,10 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
 		 * must reset the PHY to resume normal service. */
 		ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN);
 	}
-	mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-			    PMA_PMD_CDIAG_CTRL_REG, ctrl_reg);
+	efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG,
+		       ctrl_reg);
 	i = 0;
-	while (mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-				  PMA_PMD_CDIAG_CTRL_REG) &
+	while (efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG) &
 	       (1 << CDIAG_CTRL_IN_PROG_LBN)) {
 		if (++i == 50) {
 			rc = -ETIMEDOUT;
@@ -729,15 +694,13 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
 		}
 		msleep(100);
 	}
-	res_reg = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-				     PMA_PMD_CDIAG_RES_REG);
+	res_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_RES_REG);
 	for (i = 0; i < 4; i++) {
 		int pair_res =
 			(res_reg >> (CDIAG_RES_A_LBN - i * CDIAG_RES_WIDTH))
 			& ((1 << CDIAG_RES_WIDTH) - 1);
-		int len_reg = mdio_clause45_read(efx, efx->mii.phy_id,
-						 MDIO_MMD_PMAPMD,
-						 PMA_PMD_CDIAG_LEN_REG + i);
+		int len_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+					    PMA_PMD_CDIAG_LEN_REG + i);
 		if (pair_res == CDIAG_RES_OK)
 			results[1 + i] = 1;
 		else if (pair_res == CDIAG_RES_INVALID)
@@ -769,32 +732,27 @@ out:
 static void
 tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 {
-	int phy_id = efx->mii.phy_id;
 	u32 adv = 0, lpa = 0;
 	int reg;
 
 	if (efx->phy_type != PHY_TYPE_SFX7101) {
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
-					 C22EXT_MSTSLV_CTRL);
+		reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL);
 		if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN))
 			adv |= ADVERTISED_1000baseT_Full;
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
-					 C22EXT_MSTSLV_STATUS);
+		reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_STATUS);
 		if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN))
 			lpa |= ADVERTISED_1000baseT_Half;
 		if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN))
 			lpa |= ADVERTISED_1000baseT_Full;
 	}
-	reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-				 MDIO_AN_10GBT_CTRL);
-	if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN))
+	reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL);
+	if (reg & MDIO_AN_10GBT_CTRL_ADV10G)
 		adv |= ADVERTISED_10000baseT_Full;
-	reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-				 MDIO_AN_10GBT_STATUS);
-	if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN))
+	reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
+	if (reg & MDIO_AN_10GBT_STAT_LP10G)
 		lpa |= ADVERTISED_10000baseT_Full;
 
-	mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa);
+	mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa);
 
 	if (efx->phy_type != PHY_TYPE_SFX7101)
 		ecmd->supported |= (SUPPORTED_100baseT_Full |
@@ -813,29 +771,24 @@ static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 	if (!ecmd->autoneg)
 		return -EINVAL;
 
-	return mdio_clause45_set_settings(efx, ecmd);
+	return efx_mdio_set_settings(efx, ecmd);
 }
 
 static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
 {
-	mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
-			       MDIO_AN_10GBT_CTRL,
-			       MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
-			       advertising & ADVERTISED_10000baseT_Full);
+	efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
+			  MDIO_AN_10GBT_CTRL_ADV10G,
+			  advertising & ADVERTISED_10000baseT_Full);
 }
 
 static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising)
 {
-	int phy_id = efx->mii.phy_id;
-
-	mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
-			       C22EXT_MSTSLV_CTRL,
-			       C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
-			       advertising & ADVERTISED_1000baseT_Full);
-	mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
-			       MDIO_AN_10GBT_CTRL,
-			       MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
-			       advertising & ADVERTISED_10000baseT_Full);
+	efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL,
+			  1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
+			  advertising & ADVERTISED_1000baseT_Full);
+	efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
+			  MDIO_AN_10GBT_CTRL_ADV10G,
+			  advertising & ADVERTISED_10000baseT_Full);
 }
 
 struct efx_phy_operations falcon_sfx7101_phy_ops = {
diff --git a/drivers/net/sfc/xenpack.h b/drivers/net/sfc/xenpack.h
index b0d1f22..4e52286 100644
--- a/drivers/net/sfc/xenpack.h
+++ b/drivers/net/sfc/xenpack.h
@@ -34,29 +34,24 @@
 /* Enable LASI interrupts for PHY */
 static inline void xenpack_enable_lasi_irqs(struct efx_nic *efx)
 {
-	int reg;
-	int phy_id = efx->mii.phy_id;
 	/* Read to clear LASI status register */
-	reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-				 MDIO_XP_LASI_STAT);
+	efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_XP_LASI_STAT);
 
-	mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-			    MDIO_XP_LASI_CTRL, XP_LASI_LS_ALARM);
+	efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_XP_LASI_CTRL,
+		       XP_LASI_LS_ALARM);
 }
 
 /* Read the LASI interrupt status to clear the interrupt. */
 static inline int xenpack_clear_lasi_irqs(struct efx_nic *efx)
 {
 	/* Read to clear link status alarm */
-	return mdio_clause45_read(efx, efx->mii.phy_id,
-				  MDIO_MMD_PMAPMD, MDIO_XP_LASI_STAT);
+	return efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_XP_LASI_STAT);
 }
 
 /* Turn off LASI interrupts */
 static inline void xenpack_disable_lasi_irqs(struct efx_nic *efx)
 {
-	mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-			    MDIO_XP_LASI_CTRL, 0);
+	efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_XP_LASI_CTRL, 0);
 }
 
 #endif /* EFX_XENPACK_H */
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index bb1ef77..aad2dca 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -19,9 +19,9 @@
 #include "phy.h"
 #include "falcon.h"
 
-#define XFP_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PCS |	\
-			   MDIO_MMDREG_DEVS_PMAPMD |	\
-			   MDIO_MMDREG_DEVS_PHYXS)
+#define XFP_REQUIRED_DEVS (MDIO_DEVS_PCS |	\
+			   MDIO_DEVS_PMAPMD |	\
+			   MDIO_DEVS_PHYXS)
 
 #define XFP_LOOPBACKS ((1 << LOOPBACK_PCS) |		\
 		       (1 << LOOPBACK_PMAPMD) |		\
@@ -49,8 +49,7 @@
 void xfp_set_led(struct efx_nic *p, int led, int mode)
 {
 	int addr = MDIO_QUAKE_LED0_REG + led;
-	mdio_clause45_write(p, p->mii.phy_id, MDIO_MMD_PMAPMD, addr,
-			    mode);
+	efx_mdio_write(p, MDIO_MMD_PMAPMD, addr, mode);
 }
 
 struct xfp_phy_data {
@@ -63,14 +62,12 @@ struct xfp_phy_data {
 static int qt2025c_wait_reset(struct efx_nic *efx)
 {
 	unsigned long timeout = jiffies + 10 * HZ;
-	int phy_id = efx->mii.phy_id;
 	int reg, old_counter = 0;
 
 	/* Wait for firmware heartbeat to start */
 	for (;;) {
 		int counter;
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
-					 PCS_FW_HEARTBEAT_REG);
+		reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_FW_HEARTBEAT_REG);
 		if (reg < 0)
 			return reg;
 		counter = ((reg >> PCS_FW_HEARTB_LBN) &
@@ -86,8 +83,7 @@ static int qt2025c_wait_reset(struct efx_nic *efx)
 
 	/* Wait for firmware status to look good */
 	for (;;) {
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
-					 PCS_UC8051_STATUS_REG);
+		reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG);
 		if (reg < 0)
 			return reg;
 		if ((reg &
@@ -109,9 +105,9 @@ static int xfp_reset_phy(struct efx_nic *efx)
 {
 	int rc;
 
-	rc = mdio_clause45_reset_mmd(efx, MDIO_MMD_PHYXS,
-				     XFP_MAX_RESET_TIME / XFP_RESET_WAIT,
-				     XFP_RESET_WAIT);
+	rc = efx_mdio_reset_mmd(efx, MDIO_MMD_PHYXS,
+				XFP_MAX_RESET_TIME / XFP_RESET_WAIT,
+				XFP_RESET_WAIT);
 	if (rc < 0)
 		goto fail;
 
@@ -126,8 +122,7 @@ static int xfp_reset_phy(struct efx_nic *efx)
 
 	/* Check that all the MMDs we expect are present and responding. We
 	 * expect faults on some if the link is down, but not on the PHY XS */
-	rc = mdio_clause45_check_mmds(efx, XFP_REQUIRED_DEVS,
-				      MDIO_MMDREG_DEVS_PHYXS);
+	rc = efx_mdio_check_mmds(efx, XFP_REQUIRED_DEVS, MDIO_DEVS_PHYXS);
 	if (rc < 0)
 		goto fail;
 
@@ -143,7 +138,7 @@ static int xfp_reset_phy(struct efx_nic *efx)
 static int xfp_phy_init(struct efx_nic *efx)
 {
 	struct xfp_phy_data *phy_data;
-	u32 devid = mdio_clause45_read_id(efx, MDIO_MMD_PHYXS);
+	u32 devid = efx_mdio_read_id(efx, MDIO_MMD_PHYXS);
 	int rc;
 
 	phy_data = kzalloc(sizeof(struct xfp_phy_data), GFP_KERNEL);
@@ -152,8 +147,8 @@ static int xfp_phy_init(struct efx_nic *efx)
 	efx->phy_data = phy_data;
 
 	EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n",
-		 devid, mdio_id_oui(devid), mdio_id_model(devid),
-		 mdio_id_rev(devid));
+		 devid, efx_mdio_id_oui(devid), efx_mdio_id_model(devid),
+		 efx_mdio_id_rev(devid));
 
 	phy_data->phy_mode = efx->phy_mode;
 
@@ -179,7 +174,7 @@ static void xfp_phy_clear_interrupt(struct efx_nic *efx)
 
 static int xfp_link_ok(struct efx_nic *efx)
 {
-	return mdio_clause45_links_ok(efx, XFP_REQUIRED_DEVS);
+	return efx_mdio_links_ok(efx, XFP_REQUIRED_DEVS);
 }
 
 static void xfp_phy_poll(struct efx_nic *efx)
@@ -200,9 +195,9 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
 		 * or optical transceivers, varying somewhat between
 		 * firmware versions.  Only 'static mode' appears to
 		 * cover everything. */
-		mdio_clause45_set_flag(
-			efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-			PMA_PMD_FTX_CTRL2_REG, PMA_PMD_FTX_STATIC_LBN,
+		mdio_set_flag(
+			&efx->mdio, efx->mdio.prtad, MDIO_MMD_PMAPMD,
+			PMA_PMD_FTX_CTRL2_REG, 1 << PMA_PMD_FTX_STATIC_LBN,
 			efx->phy_mode & PHY_MODE_TX_DISABLED ||
 			efx->phy_mode & PHY_MODE_LOW_POWER ||
 			efx->loopback_mode == LOOPBACK_PCS ||
@@ -213,10 +208,10 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
 		    (phy_data->phy_mode & PHY_MODE_TX_DISABLED))
 			xfp_reset_phy(efx);
 
-		mdio_clause45_transmit_disable(efx);
+		efx_mdio_transmit_disable(efx);
 	}
 
-	mdio_clause45_phy_reconfigure(efx);
+	efx_mdio_phy_reconfigure(efx);
 
 	phy_data->phy_mode = efx->phy_mode;
 	efx->link_up = xfp_link_ok(efx);
@@ -225,6 +220,10 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
 	efx->link_fc = efx->wanted_fc;
 }
 
+static void xfp_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+{
+	mdio45_ethtool_gset(&efx->mdio, ecmd);
+}
 
 static void xfp_phy_fini(struct efx_nic *efx)
 {
@@ -243,8 +242,8 @@ struct efx_phy_operations falcon_xfp_phy_ops = {
 	.poll            = xfp_phy_poll,
 	.fini            = xfp_phy_fini,
 	.clear_interrupt = xfp_phy_clear_interrupt,
-	.get_settings    = mdio_clause45_get_settings,
-	.set_settings	 = mdio_clause45_set_settings,
+	.get_settings    = xfp_phy_get_settings,
+	.set_settings	 = efx_mdio_set_settings,
 	.mmds            = XFP_REQUIRED_DEVS,
 	.loopbacks       = XFP_LOOPBACKS,
 };

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


  parent reply	other threads:[~2009-04-29 18:05 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-29 18:01 [PATCH 00/16] MDIO and ethtool enhancements Ben Hutchings
2009-04-29 18:02 ` [PATCH 01/16] ethtool: Add port type PORT_OTHER Ben Hutchings
2009-04-29 18:04 ` [PATCH 02/16] mdio: Add register definitions for MDIO (clause 45) Ben Hutchings
2009-04-29 18:04 ` [PATCH 03/16] mdio: Add generic MDIO (clause 45) support functions Ben Hutchings
2009-04-29 18:05 ` Ben Hutchings [this message]
2009-04-29 18:06 ` [PATCH 05/16] chelsio: Use generic MDIO definitions and mdio_mii_ioctl() Ben Hutchings
2009-04-29 18:07 ` [PATCH 06/16] cxgb3: " Ben Hutchings
2009-04-29 18:08 ` [PATCH 07/16] ixgbe: Use generic MDIO definitions and functions Ben Hutchings
2009-04-29 18:11 ` [PATCH 08/16] ixgb: Use generic MDIO definitions Ben Hutchings
2009-04-29 18:13 ` [PATCH 09/16] s2io: " Ben Hutchings
2009-04-29 18:15 ` [PATCH 10/16] mii: Simplify mii_resolve_flowctrl_fdx() Ben Hutchings
2009-04-30  8:18   ` Steve.Glendinning
2009-04-29 18:19 ` [PATCH 11/16] mii: Add mii_advertise_flowctrl() Ben Hutchings
2009-04-29 18:19 ` [PATCH 12/16] mdio: Add mdio45_ethtool_spauseparam_an() Ben Hutchings
2009-04-29 18:20 ` [PATCH 13/16] sfc: Use generic MDIO flow control auto-negotiation functions Ben Hutchings
2009-04-29 18:21 ` [PATCH 14/16] ethtool/mdio: Report MDIO mode support and link partner advertising Ben Hutchings
2009-04-29 18:25 ` [PATCH 15/16] ethtool/mdio: Support backplane mode negotiation Ben Hutchings
2009-04-29 18:34 ` [PATCH 16/16] mii: Rewrite mii_ethtool_gset() to report mdio_support and lp_advertising Ben Hutchings
2009-04-30  0:31 ` [PATCH 00/16] MDIO and ethtool enhancements David Miller
2009-04-30  1:28   ` Ben Hutchings

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1241028308.3246.38.camel@achroite \
    --to=bhutchings@solarflare.com \
    --cc=davem@davemloft.net \
    --cc=linux-net-drivers@solarflare.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.