[arswitch] add initial functionality for AR8327 ATU management.
* Add the bulk of the ATU table read function * Correct how the ATU function and WAIT bits work TODO: * more testing, figure out how the multi-vlan table stuff works and push that up to userspace
This commit is contained in:
parent
46b59ac82b
commit
65d59686e1
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user