diff options
| author | Adrian Chadd <adrian@FreeBSD.org> | 2018-02-03 00:59:08 +0000 |
|---|---|---|
| committer | Adrian Chadd <adrian@FreeBSD.org> | 2018-02-03 00:59:08 +0000 |
| commit | 65d59686e1f877df459c1ea76c93defc16fe0e44 (patch) | |
| tree | 2e11089488619d2524379ba67e876cea5afe18a1 /sys/dev/etherswitch | |
| parent | 46b59ac82b4580ab8eedb89a9db6d78421982380 (diff) | |
Notes
Diffstat (limited to 'sys/dev/etherswitch')
| -rw-r--r-- | sys/dev/etherswitch/arswitch/arswitch_8327.c | 68 | ||||
| -rw-r--r-- | sys/dev/etherswitch/arswitch/arswitchreg.h | 45 |
2 files changed, 108 insertions, 5 deletions
diff --git a/sys/dev/etherswitch/arswitch/arswitch_8327.c b/sys/dev/etherswitch/arswitch/arswitch_8327.c index df58f893c606..8c3f9cff0686 100644 --- a/sys/dev/etherswitch/arswitch/arswitch_8327.c +++ b/sys/dev/etherswitch/arswitch/arswitch_8327.c @@ -1100,16 +1100,78 @@ ar8327_atu_flush_port(struct arswitch_softc *sc, int port) return (ret); } +/* + * Fetch a single entry from the ATU. + */ static int ar8327_atu_fetch_table(struct arswitch_softc *sc, etherswitch_atu_entry_t *e, int atu_fetch_op) { + uint32_t ret0, ret1, ret2, val; - /* XXX TODO */ - return (ENXIO); -} + ARSWITCH_LOCK_ASSERT(sc, MA_OWNED); + + switch (atu_fetch_op) { + case 0: + /* Initialise things for the first fetch */ + + DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: initializing\n", __func__); + (void) ar8327_atu_wait_ready(sc); + arswitch_writereg(sc->sc_dev, + AR8327_REG_ATU_FUNC, AR8327_ATU_FUNC_OP_GET_NEXT); + arswitch_writereg(sc->sc_dev, AR8327_REG_ATU_DATA0, 0); + arswitch_writereg(sc->sc_dev, AR8327_REG_ATU_DATA1, 0); + arswitch_writereg(sc->sc_dev, AR8327_REG_ATU_DATA2, 0); + + return (0); + case 1: + DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: reading next\n", __func__); + /* + * Attempt to read the next address entry; don't modify what + * is there in these registers as its used for the next fetch + */ + (void) ar8327_atu_wait_ready(sc); + /* Begin the next read event; not modifying anything */ + val = arswitch_readreg(sc->sc_dev, AR8327_REG_ATU_FUNC); + val |= AR8327_ATU_FUNC_BUSY; + arswitch_writereg(sc->sc_dev, AR8327_REG_ATU_FUNC, val); + + /* Wait for it to complete */ + (void) ar8327_atu_wait_ready(sc); + + /* Fetch the ethernet address and ATU status */ + ret0 = arswitch_readreg(sc->sc_dev, AR8327_REG_ATU_DATA0); + ret1 = arswitch_readreg(sc->sc_dev, AR8327_REG_ATU_DATA1); + ret2 = arswitch_readreg(sc->sc_dev, AR8327_REG_ATU_DATA2); + + /* If the status is zero, then we're done */ + if (MS(ret2, AR8327_ATU_FUNC_DATA2_STATUS) == 0) + return (-1); + + /* MAC address */ + e->es_macaddr[5] = MS(ret1, AR8327_ATU_DATA1_MAC_ADDR5); + e->es_macaddr[4] = MS(ret1, AR8327_ATU_DATA1_MAC_ADDR4); + e->es_macaddr[3] = MS(ret0, AR8327_ATU_DATA0_MAC_ADDR3); + e->es_macaddr[2] = MS(ret0, AR8327_ATU_DATA0_MAC_ADDR2); + e->es_macaddr[1] = MS(ret0, AR8327_ATU_DATA0_MAC_ADDR1); + e->es_macaddr[0] = MS(ret0, AR8327_ATU_DATA0_MAC_ADDR0); + + /* Bitmask of ports this entry is for */ + e->es_portmask = MS(ret1, AR8327_ATU_DATA1_DEST_PORT); + + /* TODO: other flags that are interesting */ + + DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: MAC %6D portmask 0x%08x\n", + __func__, + e->es_macaddr, ":", e->es_portmask); + return (0); + default: + return (-1); + } + return (-1); +} static int ar8327_flush_dot1q_vlan(struct arswitch_softc *sc) { diff --git a/sys/dev/etherswitch/arswitch/arswitchreg.h b/sys/dev/etherswitch/arswitch/arswitchreg.h index 36b1c51198f3..25e9b0c255c0 100644 --- a/sys/dev/etherswitch/arswitch/arswitchreg.h +++ b/sys/dev/etherswitch/arswitch/arswitchreg.h @@ -485,11 +485,42 @@ #define AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH 3 #define AR8327_REG_ATU_DATA0 0x600 +#define AR8327_ATU_DATA0_MAC_ADDR3 BITS(0, 8) +#define AR8327_ATU_DATA0_MAC_ADDR3_S 0 +#define AR8327_ATU_DATA0_MAC_ADDR2 BITS(8, 8) +#define AR8327_ATU_DATA0_MAC_ADDR2_S 8 +#define AR8327_ATU_DATA0_MAC_ADDR1 BITS(16, 8) +#define AR8327_ATU_DATA0_MAC_ADDR1_S 16 +#define AR8327_ATU_DATA0_MAC_ADDR0 BITS(24, 8) +#define AR8327_ATU_DATA0_MAC_ADDR0_S 24 + #define AR8327_REG_ATU_DATA1 0x604 +#define AR8327_ATU_DATA1_MAC_ADDR4 BITS(0, 8) +#define AR8327_ATU_DATA1_MAC_ADDR4_S 0 +#define AR8327_ATU_DATA1_MAC_ADDR5 BITS(8, 8) +#define AR8327_ATU_DATA1_MAC_ADDR5_S 0 +#define AR8327_ATU_DATA1_DEST_PORT BITS(16, 7) +#define AR8327_ATU_DATA1_DEST_PORT_S 16 +#define AR8327_ATU_DATA1_CROSS_PORT_STATE_EN BIT(23) +#define AR8327_ATU_DATA1_PRI BITS(24, 3) +#define AR8327_ATU_DATA1_SVL_ENTRY BIT(27) +#define AR8327_ATU_DATA1_PRI_OVER_EN BIT(28) +#define AR8327_ATU_DATA1_MIRROR_EN BIT(29) +#define AR8327_ATU_DATA1_SA_DROP_EN BIT(30) +#define AR8327_ATU_DATA1_HASH_HIGH_ADDR BIT(31) + #define AR8327_REG_ATU_DATA2 0x608 +#define AR8327_ATU_FUNC_DATA2_STATUS BITS(0, 4) +#define AR8327_ATU_FUNC_DATA2_STATUS_S 0 +#define AR8327_ATU_FUNC_DATA2_VLAN_LEAKY_EN BIT(4) +#define AR8327_ATU_FUNC_DATA2_REDIRECT_TO_CPU BIT(5) +#define AR8327_ATU_FUNC_DATA2_COPY_TO_CPU BIT(6) +#define AR8327_ATU_FUNC_DATA2_SHORT_LOOP BIT(7) +#define AR8327_ATU_FUNC_DATA2_ATU_VID BITS(8, 12) +#define AR8327_ATU_FUNC_DATA2_ATU_VID_S 8 #define AR8327_REG_ATU_FUNC 0x60c -#define AR8327_ATU_FUNC_OP BITS(0, 3) +#define AR8327_ATU_FUNC_OP BITS(0, 4) #define AR8327_ATU_FUNC_OP_NOOP 0x0 #define AR8327_ATU_FUNC_OP_FLUSH 0x1 #define AR8327_ATU_FUNC_OP_LOAD 0x2 @@ -499,9 +530,19 @@ #define AR8327_ATU_FUNC_OP_GET_NEXT 0x6 #define AR8327_ATU_FUNC_OP_SEARCH_MAC 0x7 #define AR8327_ATU_FUNC_OP_CHANGE_TRUNK 0x8 -#define AR8327_ATU_FUNC_BUSY BIT(3) +#define AR8327_ATU_FUNC_FLUSH_STATIC_EN BIT(4) +#define AR8327_ATU_FUNC_ENTRY_TYPE BIT(5) #define AR8327_ATU_FUNC_PORT_NUM BITS(8, 4) #define AR8327_ATU_FUNC_PORT_NUM_S 8 +#define AR8327_ATU_FUNC_FULL_VIOLATION BIT(12) +#define AR8327_ATU_FUNC_MULTI_EN BIT(13) /* for GET_NEXT */ +#define AR8327_ATU_FUNC_PORT_EN BIT(14) /* for GET_NEXT */ +#define AR8327_ATU_FUNC_VID_EN BIT(15) /* for GET_NEXT */ +#define AR8327_ATU_FUNC_ATU_INDEX BITS(16, 5) +#define AR8327_ATU_FUNC_ATU_INDEX_S 16 +#define AR8327_ATU_FUNC_TRUNK_PORT_NUM BITS(22, 3) /* for CHANGE_TRUNK */ +#define AR8327_ATU_FUNC_TRUNK_PORT_NUM_S 22 +#define AR8327_ATU_FUNC_BUSY BIT(31) #define AR8327_REG_VTU_FUNC0 0x0610 #define AR8327_VTU_FUNC0_EG_MODE BITS(4, 14) |
