summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuiz Souza <luiz@netgate.com>2018-03-08 15:14:48 -0300
committerLuiz Souza <luiz@netgate.com>2018-03-08 21:48:01 -0600
commitb830726ec00156a59a09c554f49777e5b328df81 (patch)
tree106c50ffe10ab62c35ec6a4991ad76f76f0ae2f8
parent26b8828ef10e292c920bf850df44a2aff5dbd3c5 (diff)
downloadFreeBSD-src-b830726ec00156a59a09c554f49777e5b328df81.zip
FreeBSD-src-b830726ec00156a59a09c554f49777e5b328df81.tar.gz
Simplify and consolidate the PHY access routines, remove duplicate defines.
Save some MDIO cycles by not waiting for completion after write operations. (cherry picked from commit 989aac432d068a6d60e41179842e0d7fd5eb479c)
-rw-r--r--sys/dev/etherswitch/e6000sw/e6000sw.c79
-rw-r--r--sys/dev/etherswitch/e6000sw/e6000swreg.h34
2 files changed, 36 insertions, 77 deletions
diff --git a/sys/dev/etherswitch/e6000sw/e6000sw.c b/sys/dev/etherswitch/e6000sw/e6000sw.c
index 7a82b88..11fe59e 100644
--- a/sys/dev/etherswitch/e6000sw/e6000sw.c
+++ b/sys/dev/etherswitch/e6000sw/e6000sw.c
@@ -198,12 +198,6 @@ DRIVER_MODULE(etherswitch, e6000sw, etherswitch_driver, etherswitch_devclass, 0,
DRIVER_MODULE(miibus, e6000sw, miibus_driver, miibus_devclass, 0, 0);
MODULE_DEPEND(e6000sw, mdio, 1, 1, 1);
-#define SMI_CMD 0
-#define SMI_CMD_BUSY (1 << 15)
-#define SMI_CMD_OP_READ ((2 << 10) | SMI_CMD_BUSY | (1 << 12))
-#define SMI_CMD_OP_WRITE ((1 << 10) | SMI_CMD_BUSY | (1 << 12))
-#define SMI_DATA 1
-
#undef E6000SW_DEBUG
#if defined(E6000SW_DEBUG)
static void
@@ -690,23 +684,6 @@ out_fail:
return (err);
}
-static __inline int
-e6000sw_poll_done(e6000sw_softc_t *sc)
-{
- int i;
-
- for (i = 0; i < E6000SW_SMI_TIMEOUT; i++) {
-
- if ((e6000sw_readreg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG) &
- (1 << PHY_CMD_SMI_BUSY)) == 0)
- return (0);
-
- pause("e6000sw PHY poll", hz/1000);
- }
-
- return (ETIMEDOUT);
-}
-
/*
* PHY registers are paged. Put page index in reg 22 (accessible from every
* page), then access specific register.
@@ -715,8 +692,6 @@ static int
e6000sw_readphy(device_t dev, int phy, int reg)
{
e6000sw_softc_t *sc;
- uint32_t val;
- int err;
sc = device_get_softc(dev);
if (!e6000sw_is_phyport(sc, phy) || reg >= E6000SW_NUM_PHY_REGS) {
@@ -725,24 +700,17 @@ e6000sw_readphy(device_t dev, int phy, int reg)
}
E6000SW_LOCK_ASSERT(sc, SA_XLOCKED);
-
- err = e6000sw_poll_done(sc);
- if (err != 0) {
+ if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) {
device_printf(dev, "Timeout while waiting for switch\n");
- return (err);
+ return (ETIMEDOUT);
}
- val = 1 << PHY_CMD_SMI_BUSY;
- val |= PHY_CMD_MODE_MDIO << PHY_CMD_MODE;
- val |= PHY_CMD_OPCODE_READ << PHY_CMD_OPCODE;
- val |= (reg << PHY_CMD_REG_ADDR) & PHY_CMD_REG_ADDR_MASK;
- val |= (phy << PHY_CMD_DEV_ADDR) & PHY_CMD_DEV_ADDR_MASK;
- e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG, val);
-
- err = e6000sw_poll_done(sc);
- if (err != 0) {
+ e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG,
+ SMI_CMD_OP_C22_READ | (reg & SMI_CMD_REG_ADDR_MASK) |
+ ((phy << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK));
+ if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) {
device_printf(dev, "Timeout while waiting for switch\n");
- return (err);
+ return (ETIMEDOUT);
}
val = e6000sw_readreg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG);
@@ -754,8 +722,6 @@ static int
e6000sw_writephy(device_t dev, int phy, int reg, int data)
{
e6000sw_softc_t *sc;
- uint32_t val;
- int err;
sc = device_get_softc(dev);
if (!e6000sw_is_phyport(sc, phy) || reg >= E6000SW_NUM_PHY_REGS) {
@@ -764,27 +730,18 @@ e6000sw_writephy(device_t dev, int phy, int reg, int data)
}
E6000SW_LOCK_ASSERT(sc, SA_XLOCKED);
-
- err = e6000sw_poll_done(sc);
- if (err != 0) {
+ if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) {
device_printf(dev, "Timeout while waiting for switch\n");
- return (err);
+ return (ETIMEDOUT);
}
- val = 1 << PHY_CMD_SMI_BUSY;
- val |= PHY_CMD_MODE_MDIO << PHY_CMD_MODE;
- val |= PHY_CMD_OPCODE_WRITE << PHY_CMD_OPCODE;
- val |= (reg << PHY_CMD_REG_ADDR) & PHY_CMD_REG_ADDR_MASK;
- val |= (phy << PHY_CMD_DEV_ADDR) & PHY_CMD_DEV_ADDR_MASK;
e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG,
data & PHY_DATA_MASK);
- e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG, val);
-
- err = e6000sw_poll_done(sc);
- if (err != 0)
- device_printf(dev, "Timeout while waiting for switch\n");
+ e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG,
+ SMI_CMD_OP_C22_WRITE | (reg & SMI_CMD_REG_ADDR_MASK) |
+ ((phy << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK));
- return (err);
+ return (0);
}
static int
@@ -1438,7 +1395,8 @@ e6000sw_readreg(e6000sw_softc_t *sc, int addr, int reg)
return (0xffff);
}
MDIO_WRITE(sc->dev, sc->sw_addr, SMI_CMD,
- SMI_CMD_OP_READ | (addr << 5) | reg);
+ SMI_CMD_OP_C22_READ | (reg & SMI_CMD_REG_ADDR_MASK) |
+ ((addr << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK));
if (e6000sw_smi_waitready(sc, sc->sw_addr)) {
printf("e6000sw: readreg timeout\n");
return (0xffff);
@@ -1464,11 +1422,8 @@ e6000sw_writereg(e6000sw_softc_t *sc, int addr, int reg, int val)
}
MDIO_WRITE(sc->dev, sc->sw_addr, SMI_DATA, val);
MDIO_WRITE(sc->dev, sc->sw_addr, SMI_CMD,
- SMI_CMD_OP_WRITE | (addr << 5) | reg);
- if (e6000sw_smi_waitready(sc, sc->sw_addr)) {
- printf("e6000sw: readreg timeout\n");
- return;
- }
+ SMI_CMD_OP_C22_WRITE | (reg & SMI_CMD_REG_ADDR_MASK) |
+ ((addr << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK));
}
static __inline bool
diff --git a/sys/dev/etherswitch/e6000sw/e6000swreg.h b/sys/dev/etherswitch/e6000sw/e6000swreg.h
index 8c095e4..80cbd88 100644
--- a/sys/dev/etherswitch/e6000sw/e6000swreg.h
+++ b/sys/dev/etherswitch/e6000sw/e6000swreg.h
@@ -220,25 +220,29 @@ struct atu_opt {
#define ATU_STATS_BIN 14
#define ATU_STATS_FLAG 12
+/* Offset of SMI registers in multi-chip setup. */
+#define SMI_CMD 0
+#define SMI_DATA 1
+
/*
- * PHY registers accessed via 'Switch Global Registers' (REG_GLOBAL2).
+ * 'Switch Global Registers 2' (REG_GLOBAL2).
*/
+
+/* PHY registers */
#define SMI_PHY_CMD_REG 0x18
+#define SMI_CMD_BUSY (1 << 15)
+#define SMI_CMD_MODE_C22 (1 << 12)
+#define SMI_CMD_C22_WRITE (1 << 10)
+#define SMI_CMD_C22_READ (2 << 10)
+#define SMI_CMD_OP_C22_WRITE \
+ (SMI_CMD_C22_WRITE | SMI_CMD_BUSY | SMI_CMD_MODE_C22)
+#define SMI_CMD_OP_C22_READ \
+ (SMI_CMD_C22_READ | SMI_CMD_BUSY | SMI_CMD_MODE_C22)
+#define SMI_CMD_DEV_ADDR 5
+#define SMI_CMD_DEV_ADDR_MASK 0x3e0
+#define SMI_CMD_REG_ADDR_MASK 0x1f
#define SMI_PHY_DATA_REG 0x19
-
-#define PHY_DATA_MASK 0xffff
-
-#define PHY_CMD_SMI_BUSY 15
-#define PHY_CMD_MODE 12
-#define PHY_CMD_MODE_MDIO 1
-#define PHY_CMD_MODE_XMDIO 0
-#define PHY_CMD_OPCODE 10
-#define PHY_CMD_OPCODE_WRITE 1
-#define PHY_CMD_OPCODE_READ 2
-#define PHY_CMD_DEV_ADDR 5
-#define PHY_CMD_DEV_ADDR_MASK 0x3e0
-#define PHY_CMD_REG_ADDR 0
-#define PHY_CMD_REG_ADDR_MASK 0x1f
+#define PHY_DATA_MASK 0xffff
#define PHY_PAGE_REG 22
OpenPOWER on IntegriCloud