summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuiz Souza <luiz@netgate.com>2018-03-08 14:49:31 -0300
committerLuiz Souza <luiz@netgate.com>2018-03-08 21:47:45 -0600
commit26b8828ef10e292c920bf850df44a2aff5dbd3c5 (patch)
tree1066c6ce6c637f2aed28675a8a66a68032bb5030
parent71e3c5cbbbdaf7023423bf4aecf933a3165f58ee (diff)
downloadFreeBSD-src-26b8828ef10e292c920bf850df44a2aff5dbd3c5.zip
FreeBSD-src-26b8828ef10e292c920bf850df44a2aff5dbd3c5.tar.gz
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)
-rw-r--r--sys/dev/etherswitch/e6000sw/e6000sw.c61
1 files 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);
}
OpenPOWER on IntegriCloud