Author: adrian
Date: Sat Feb  3 00:59:08 2018
New Revision: 328823
URL: https://svnweb.freebsd.org/changeset/base/328823

Log:
  [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

Modified:
  head/sys/dev/etherswitch/arswitch/arswitch_8327.c
  head/sys/dev/etherswitch/arswitch/arswitchreg.h

Modified: head/sys/dev/etherswitch/arswitch/arswitch_8327.c
==============================================================================
--- head/sys/dev/etherswitch/arswitch/arswitch_8327.c   Fri Feb  2 23:34:33 
2018        (r328822)
+++ head/sys/dev/etherswitch/arswitch/arswitch_8327.c   Sat Feb  3 00:59:08 
2018        (r328823)
@@ -1100,16 +1100,78 @@ ar8327_atu_flush_port(struct arswitch_softc *sc, int p
        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)
 {

Modified: head/sys/dev/etherswitch/arswitch/arswitchreg.h
==============================================================================
--- head/sys/dev/etherswitch/arswitch/arswitchreg.h     Fri Feb  2 23:34:33 
2018        (r328822)
+++ head/sys/dev/etherswitch/arswitch/arswitchreg.h     Sat Feb  3 00:59:08 
2018        (r328823)
@@ -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)
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to