summaryrefslogtreecommitdiffstats
path: root/sys
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 /sys
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)
Diffstat (limited to 'sys')
-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