From 26b8828ef10e292c920bf850df44a2aff5dbd3c5 Mon Sep 17 00:00:00 2001 From: Luiz Souza Date: Thu, 8 Mar 2018 14:49:31 -0300 Subject: Make e6000sw_waitready() more generic to also allow the check of bits in REG_GLOBAL2. While here, make a simpler multi-chip check. No functional change. (cherry picked from commit 371bcca94e5ce1f7a0eeb73277e1247bef140278) --- sys/dev/etherswitch/e6000sw/e6000sw.c | 61 ++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/sys/dev/etherswitch/e6000sw/e6000sw.c b/sys/dev/etherswitch/e6000sw/e6000sw.c index 68a7697..7a82b88 100644 --- a/sys/dev/etherswitch/e6000sw/e6000sw.c +++ b/sys/dev/etherswitch/e6000sw/e6000sw.c @@ -66,6 +66,15 @@ MALLOC_DEFINE(M_E6000SW, "e6000sw", "e6000sw switch"); #define E6000SW_UNLOCK(_sc) sx_unlock(&(_sc)->sx) #define E6000SW_LOCK_ASSERT(_sc, _what) sx_assert(&(_sc)->sx, (_what)) #define E6000SW_TRYLOCK(_sc) sx_tryxlock(&(_sc)->sx) +#define E6000SW_MULTICHIP(_sc) (((_sc)->sw_addr != 0) ? 1 : 0) +#define E6000SW_WAITREADY(_sc, _reg, _bit) \ + e6000sw_waitready((_sc), REG_GLOBAL, (_reg), (_bit)) +#define E6000SW_WAITREADY2(_sc, _reg, _bit) \ + e6000sw_waitready((_sc), REG_GLOBAL2, (_reg), (_bit)) +#define MDIO_READ(dev, addr, reg) \ + MDIO_READREG(device_get_parent(dev), (addr), (reg)) +#define MDIO_WRITE(dev, addr, reg, val) \ + MDIO_WRITEREG(device_get_parent(dev), (addr), (reg), (val)) typedef struct e6000sw_softc { device_t dev; @@ -91,7 +100,6 @@ typedef struct e6000sw_softc { int port_base; /* SMI base addr of port regs */ int sw_addr; int num_ports; - boolean_t multi_chip; } e6000sw_softc_t; static etherswitch_info_t etherswitch_info = { @@ -136,7 +144,7 @@ static int e6000sw_atu_mac_table(device_t, e6000sw_softc_t *, struct atu_opt *, int); static int e6000sw_vtu_flush(e6000sw_softc_t *); static int e6000sw_vtu_update(e6000sw_softc_t *, int, int, int, int, int); -static int e6000sw_waitready(e6000sw_softc_t *, uint32_t, uint32_t); +static int e6000sw_waitready(e6000sw_softc_t *, uint32_t, uint32_t, uint32_t); static void e6000sw_get_pvid(e6000sw_softc_t *, int, int *); static void e6000sw_set_pvid(e6000sw_softc_t *, int, int); static __inline bool e6000sw_is_cpuport(e6000sw_softc_t *, int); @@ -196,11 +204,6 @@ MODULE_DEPEND(e6000sw, mdio, 1, 1, 1); #define SMI_CMD_OP_WRITE ((1 << 10) | SMI_CMD_BUSY | (1 << 12)) #define SMI_DATA 1 -#define MDIO_READ(dev, addr, reg) \ - MDIO_READREG(device_get_parent(dev), (addr), (reg)) -#define MDIO_WRITE(dev, addr, reg, val) \ - MDIO_WRITEREG(device_get_parent(dev), (addr), (reg), (val)) - #undef E6000SW_DEBUG #if defined(E6000SW_DEBUG) static void @@ -208,7 +211,7 @@ e6000sw_atu_dump(e6000sw_softc_t *sc, int fid) { uint16_t data, mac1, mac2, mac3, reg; - if (e6000sw_waitready(sc, ATU_OPERATION, ATU_UNIT_BUSY)) { + if (E6000SW_WAITREADY(sc, ATU_OPERATION, ATU_UNIT_BUSY)) { device_printf(sc->dev, "ATU unit is busy, cannot access\n"); return; } @@ -229,7 +232,7 @@ e6000sw_atu_dump(e6000sw_softc_t *sc, int fid) } e6000sw_writereg(sc, REG_GLOBAL, ATU_OPERATION, reg | ATU_UNIT_BUSY); - if (e6000sw_waitready(sc, ATU_OPERATION, ATU_UNIT_BUSY)) { + if (E6000SW_WAITREADY(sc, ATU_OPERATION, ATU_UNIT_BUSY)) { device_printf(sc->dev, "Timeout while reading\n"); return; } @@ -264,7 +267,7 @@ e6000sw_vtu_dump(e6000sw_softc_t *sc) int i, port, vlan; uint32_t reg; - if (e6000sw_waitready(sc, VTU_OPERATION, VTU_BUSY)) { + if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) { device_printf(sc->dev, "VTU unit is busy, cannot access\n"); return; } @@ -280,7 +283,7 @@ e6000sw_vtu_dump(e6000sw_softc_t *sc) return; } e6000sw_writereg(sc, REG_GLOBAL, VTU_OPERATION, reg | VTU_BUSY); - if (e6000sw_waitready(sc, VTU_OPERATION, VTU_BUSY)) { + if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) { device_printf(sc->dev, "Timeout while reading\n"); return; } @@ -372,8 +375,6 @@ e6000sw_probe(device_t dev) #endif if (sc->sw_addr < 0 || sc->sw_addr > 32) return (ENXIO); - if (sc->sw_addr != 0) - sc->multi_chip = true; /* Set defaults for 88E6XXX family. */ sc->port_vlan_mask = 0x7f; @@ -583,8 +584,9 @@ e6000sw_attach(device_t dev) err = 0; sc = device_get_softc(dev); - if (sc->multi_chip) - device_printf(dev, "multi-chip addressing mode\n"); + if (E6000SW_MULTICHIP(sc)) + device_printf(dev, "multi-chip addressing mode (%#x)\n", + sc->sw_addr); else device_printf(dev, "single-chip addressing mode\n"); @@ -1312,7 +1314,7 @@ e6000sw_get_dot1q_vlan(e6000sw_softc_t *sc, etherswitch_vlangroup_t *vg) if (vg->es_vid == 0) return (0); - if (e6000sw_waitready(sc, VTU_OPERATION, VTU_BUSY)) { + if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) { device_printf(sc->dev, "VTU unit is busy, cannot access\n"); return (EBUSY); } @@ -1323,7 +1325,7 @@ e6000sw_get_dot1q_vlan(e6000sw_softc_t *sc, etherswitch_vlangroup_t *vg) reg &= ~VTU_OP_MASK; reg |= VTU_GET_NEXT | VTU_BUSY; e6000sw_writereg(sc, REG_GLOBAL, VTU_OPERATION, reg); - if (e6000sw_waitready(sc, VTU_OPERATION, VTU_BUSY)) { + if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) { device_printf(sc->dev, "Timeout while reading\n"); return (EBUSY); } @@ -1428,7 +1430,7 @@ e6000sw_readreg(e6000sw_softc_t *sc, int addr, int reg) E6000SW_LOCK_ASSERT(sc, SA_XLOCKED); - if (!sc->multi_chip) + if (!E6000SW_MULTICHIP(sc)) return (MDIO_READ(sc->dev, addr, reg) & 0xffff); if (e6000sw_smi_waitready(sc, sc->sw_addr)) { @@ -1451,7 +1453,7 @@ e6000sw_writereg(e6000sw_softc_t *sc, int addr, int reg, int val) E6000SW_LOCK_ASSERT(sc, SA_XLOCKED); - if (!sc->multi_chip) { + if (!E6000SW_MULTICHIP(sc)) { MDIO_WRITE(sc->dev, addr, reg, val); return; } @@ -1660,7 +1662,7 @@ e6000sw_atu_mac_table(device_t dev, e6000sw_softc_t *sc, struct atu_opt *atu, return (EINVAL); } - if (e6000sw_waitready(sc, ATU_OPERATION, ATU_UNIT_BUSY)) { + if (E6000SW_WAITREADY(sc, ATU_OPERATION, ATU_UNIT_BUSY)) { device_printf(dev, "ATU unit is busy, cannot access\n"); return (EBUSY); } @@ -1679,7 +1681,7 @@ e6000sw_atu_mac_table(device_t dev, e6000sw_softc_t *sc, struct atu_opt *atu, e6000sw_writereg(sc, REG_GLOBAL, ATU_OPERATION, (ret_opt | ATU_UNIT_BUSY | flag)); - if (e6000sw_waitready(sc, ATU_OPERATION, ATU_UNIT_BUSY)) + if (E6000SW_WAITREADY(sc, ATU_OPERATION, ATU_UNIT_BUSY)) device_printf(dev, "Timeout while waiting ATU\n"); else if (flag & GET_NEXT_IN_FIB) { atu->mac_01 = e6000sw_readreg(sc, REG_GLOBAL, @@ -1701,26 +1703,27 @@ e6000sw_atu_flush(device_t dev, e6000sw_softc_t *sc, int flag) if (flag == NO_OPERATION) return (0); - if (e6000sw_waitready(sc, ATU_OPERATION, ATU_UNIT_BUSY)) { + if (E6000SW_WAITREADY(sc, ATU_OPERATION, ATU_UNIT_BUSY)) { device_printf(dev, "ATU unit is busy, cannot access\n"); return (EBUSY); } ret = e6000sw_readreg(sc, REG_GLOBAL, ATU_OPERATION); e6000sw_writereg(sc, REG_GLOBAL, ATU_OPERATION, (ret | ATU_UNIT_BUSY | flag)); - if (e6000sw_waitready(sc, ATU_OPERATION, ATU_UNIT_BUSY)) + if (E6000SW_WAITREADY(sc, ATU_OPERATION, ATU_UNIT_BUSY)) device_printf(dev, "Timeout while flushing ATU\n"); return (0); } static int -e6000sw_waitready(e6000sw_softc_t *sc, uint32_t reg, uint32_t cmdbusy) +e6000sw_waitready(e6000sw_softc_t *sc, uint32_t phy, uint32_t reg, + uint32_t busybit) { int i; for (i = 0; i < E6000SW_RETRIES; i++) { - if ((e6000sw_readreg(sc, REG_GLOBAL, reg) & cmdbusy) == 0) + if ((e6000sw_readreg(sc, phy, reg) & busybit) == 0) return (0); DELAY(1); } @@ -1732,13 +1735,13 @@ static int e6000sw_vtu_flush(e6000sw_softc_t *sc) { - if (e6000sw_waitready(sc, VTU_OPERATION, VTU_BUSY)) { + if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) { device_printf(sc->dev, "VTU unit is busy, cannot access\n"); return (EBUSY); } e6000sw_writereg(sc, REG_GLOBAL, VTU_OPERATION, VTU_FLUSH | VTU_BUSY); - if (e6000sw_waitready(sc, VTU_OPERATION, VTU_BUSY)) { + if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) { device_printf(sc->dev, "Timeout while flushing VTU\n"); return (ETIMEDOUT); } @@ -1753,7 +1756,7 @@ e6000sw_vtu_update(e6000sw_softc_t *sc, int purge, int vid, int fid, int i, op; uint32_t data[2]; - if (e6000sw_waitready(sc, VTU_OPERATION, VTU_BUSY)) { + if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) { device_printf(sc->dev, "VTU unit is busy, cannot access\n"); return (EBUSY); } @@ -1786,7 +1789,7 @@ e6000sw_vtu_update(e6000sw_softc_t *sc, int purge, int vid, int fid, op = VTU_PURGE; e6000sw_writereg(sc, REG_GLOBAL, VTU_OPERATION, op | VTU_BUSY); - if (e6000sw_waitready(sc, VTU_OPERATION, VTU_BUSY)) { + if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) { device_printf(sc->dev, "Timeout while flushing VTU\n"); return (ETIMEDOUT); } -- cgit v1.1