Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/sociox make sure to use mac_write() for GMACxxx...



details:   https://anonhg.NetBSD.org/src/rev/01148a383c17
branches:  trunk
changeset: 746221:01148a383c17
user:      nisimura <nisimura%NetBSD.org@localhost>
date:      Wed Mar 25 01:39:49 2020 +0000

description:
make sure to use mac_write() for GMACxxx registers. try to decode xMII link status report

diffstat:

 sys/arch/arm/sociox/if_scx.c |  148 +++++++++++++++++++++++++++---------------
 1 files changed, 96 insertions(+), 52 deletions(-)

diffs (truncated from 312 to 300 lines):

diff -r 7783ccf0bce7 -r 01148a383c17 sys/arch/arm/sociox/if_scx.c
--- a/sys/arch/arm/sociox/if_scx.c      Tue Mar 24 22:09:50 2020 +0000
+++ b/sys/arch/arm/sociox/if_scx.c      Wed Mar 25 01:39:49 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_scx.c,v 1.12 2020/03/24 13:44:21 nisimura Exp $     */
+/*     $NetBSD: if_scx.c,v 1.13 2020/03/25 01:39:49 nisimura Exp $     */
 
 /*-
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -56,7 +56,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1.12 2020/03/24 13:44:21 nisimura Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1.13 2020/03/25 01:39:49 nisimura Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -83,6 +83,7 @@
 #include <dev/acpi/acpivar.h>
 #include <dev/acpi/acpi_intr.h>
 
+/* SC2A11 register block */
 #define SWRESET                0x104
 #define COMINIT                0x120
 #define INTRST         0x200
@@ -124,6 +125,7 @@
 #define DESCENG_INIT   0x11fc
 #define DESCENG_SRST   0x1204
 
+/* GMAC register block. use mac_write()/mac_read() to handle */
 #define GMACMCR                0x0000          /* MAC configuration */
 #define  MCR_IBN       (1U<<30)        /* */
 #define  MCR_CST       (1U<<25)        /* strip CRC */
@@ -169,13 +171,21 @@
 #define GMACMAL0       0x0044          /* MAC address 0 31:0 */
 #define GMACMAH(i)     ((i)*8+0x40)    /* supplimental MAC addr 1 - 15 */
 #define GMACMAL(i)     ((i)*8+0x44)
-#define GMACMDSR       0x00d8          /* GMII/RGMII/MII command/status */
+#define GMACMIISR      0x00d8          /* resolved xMII link status */
+                                       /*  3   link up detected
+                                        *  2:1 resovled speed
+                                        *      0 2.5Mhz (10Mbps) 
+                                        *      1 25Mhz  (100bps)
+                                        *      2 125Mhz (1000Mbps)
+                                        *  1   full duplex detected */
+
 #define GMACMHT0       0x0500          /* multicast hash table 0 - 7 */
 #define GMACMHT(i)     ((i)*4+0x500)
 #define GMACVHT                0x0588          /* VLAN tag hash */
 #define GMACAMAH(i)    ((i)*8+0x800)   /* supplimental MAC addr 16-127 */
 #define GMACAMAL(i)    ((i)*8+0x804)
 #define GMACEVCNT(i)   ((i)*4+0x114)   /* event counter 0x114~284 */
+#define GMACEVCTL      0x0100          /* clear event counter registers */
 
 #define GMACBMR                0x1000          /* DMA bus mode control
                                         * 24    4PBL
@@ -202,8 +212,6 @@
 #define  OMR_TXE       (1U<<13)        /* start Tx DMA engine, 0 to stop */
 #define  OMR_RXE       (1U<<1)         /* start Rx DMA engine, 0 to stop */
 
-static int get_mdioclk(uint32_t);
-
 /* descriptor format definition */
 struct tdes {
        uint32_t t0, t1, t2, t3;
@@ -390,6 +398,8 @@
 static void txreap(struct scx_softc *);
 static void rxintr(struct scx_softc *);
 static int add_rxbuf(struct scx_softc *, int);
+
+static int get_mdioclk(uint32_t);
 static int spin_waitfor(struct scx_softc *, int, int);
 static int mac_read(struct scx_softc *, int);
 static void mac_write(struct scx_softc *, int, int);
@@ -585,7 +595,7 @@
        csr = bus_space_read_4(sc->sc_st, sc->sc_eesh, 4);
        enaddr[4] = csr >> 24;
        enaddr[5] = csr >> 16;
-       csr = CSR_READ(sc, GMACIMPL);
+       csr = mac_read(sc, GMACIMPL);
 
        aprint_normal_dev(sc->sc_dev, "NetSec GbE (%d.%d) impl (%x.%x)\n",
            hwver >> 16, hwver & 0xffff, csr >> 16, csr & 0xffff);
@@ -747,6 +757,7 @@
        mac_write(sc, GMACRDLAR, _RDLAR);
        mac_write(sc, GMACTDLAR, _TDLAR);
        mac_write(sc, GMACAFR, _AFR);
+       mac_write(sc, GMACEVCTL, 1);
 }
 
 static int
@@ -763,28 +774,43 @@
        /* Reset the chip to a known state. */
        scx_reset(sc);
 
-       /* build sane Tx and load Rx descriptors with mbuf */
-       for (i = 0; i < MD_NTXDESC; i++)
-               sc->sc_txdescs[i].t0 = T0_OWN;
-       sc->sc_txdescs[MD_NTXDESC - 1].t0 |= T0_EOD; /* tie off the ring */
-       for (i = 0; i < MD_NRXDESC; i++)
-               (void)add_rxbuf(sc, i);
-
        /* set my address in perfect match slot 0 */
        csr = (ea[3] << 24) | (ea[2] << 16) | (ea[1] << 8) |  ea[0];
-       CSR_WRITE(sc, GMACMAL0, csr);
+       mac_write(sc, GMACMAL0, csr);
        csr = (ea[5] << 8) | ea[4];
-       CSR_WRITE(sc, GMACMAH0, csr | 1U<<31); /* always valid? */
+       mac_write(sc, GMACMAH0, csr | 1U<<31); /* always valid? */
 
        /* accept multicast frame or run promisc mode */
        scx_set_rcvfilt(sc);
 
        (void)scx_ifmedia_upd(ifp);
 
+       /* build sane Tx */
+       memset(sc->sc_txdescs, 0, sizeof(struct tdes) * MD_NTXDESC);
+       sc->sc_txdescs[MD_NTXDESC - 1].t0 |= T0_EOD; /* tie off the ring */
+       SCX_CDTXSYNC(sc, 0, MD_NTXDESC,
+                   BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+       sc->sc_txfree = MD_NTXDESC;
+       sc->sc_txnext = 0;
+       for (i = 0; i < MD_TXQUEUELEN; i++)
+               sc->sc_txsoft[i].txs_mbuf = NULL;
+       sc->sc_txsfree = MD_TXQUEUELEN;
+       sc->sc_txsnext = 0;
+       sc->sc_txsdirty = 0;
+
+       /* load Rx descriptors with fresh mbuf */
+       for (i = 0; i < MD_NRXDESC; i++)
+               (void)add_rxbuf(sc, i);
+       sc->sc_rxptr = 0;
+
+       /* XXX 32 bit paddr XXX hand Tx/Rx rings to HW XXX */
+       mac_write(sc, GMACTDLAR, SCX_CDTXADDR(sc, 0));
+       mac_write(sc, GMACRDLAR, SCX_CDRXADDR(sc, 0));
+
        /* kick to start GMAC engine */
-       csr = mac_read(sc, GMACOMR);
        CSR_WRITE(sc, RXINT_CLR, ~0);
        CSR_WRITE(sc, TXINT_CLR, ~0);
+       csr = mac_read(sc, GMACOMR);
        mac_write(sc, GMACOMR, csr | OMR_RXE | OMR_TXE);
 
        ifp->if_flags |= IFF_RUNNING;
@@ -898,9 +924,9 @@
        uint32_t csr, crc;
        int i;
 
-       csr = CSR_READ(sc, GMACAFR);
+       csr = mac_read(sc, GMACAFR);
        csr &= ~(AFR_PM | AFR_AM | AFR_MHTE);
-       CSR_WRITE(sc, GMACAFR, csr);
+       mac_write(sc, GMACAFR, csr);
 
        ETHER_LOCK(ec);
        if (ifp->if_flags & IFF_PROMISC) {
@@ -912,7 +938,7 @@
 
        /* clear 15 entry supplimental perfect match filter */
        for (i = 1; i < 16; i++)
-                CSR_WRITE(sc, GMACMAH(i), 0);
+                mac_write(sc, GMACMAH(i), 0);
        /* build 256 bit multicast hash filter */
        memset(mchash, 0, sizeof(mchash));
        crc = 0;
@@ -940,9 +966,9 @@
                        uint8_t *ep = enm->enm_addrlo;
                        addr = (ep[3] << 24) | (ep[2] << 16)
                             | (ep[1] <<  8) |  ep[0];
-                       CSR_WRITE(sc, GMACMAL(i), addr);
+                       mac_write(sc, GMACMAL(i), addr);
                        addr = (ep[5] << 8) | ep[4];
-                       CSR_WRITE(sc, GMACMAH(i), addr | 1U<<31);
+                       mac_write(sc, GMACMAH(i), addr | 1U<<31);
                } else {
                        /* use hash table when too many */
                        /* bit_reserve_32(~crc) !? */
@@ -958,8 +984,8 @@
        if (crc)
                csr |= AFR_MHTE;
        for (i = 0; i < __arraycount(mchash); i++)
-               CSR_WRITE(sc, GMACMHT(i), mchash[i]);
-       CSR_WRITE(sc, GMACAFR, csr);
+               mac_write(sc, GMACMHT(i), mchash[i]);
+       mac_write(sc, GMACAFR, csr);
        return;
 
  update:
@@ -968,7 +994,7 @@
                csr |= AFR_PM;  /* run promisc. mode */
        else
                csr |= AFR_AM;  /* accept all multicast */
-       CSR_WRITE(sc, GMACAFR, csr);
+       mac_write(sc, GMACAFR, csr);
        return;
 }
 
@@ -1023,7 +1049,16 @@
        struct scx_softc *sc = ifp->if_softc;
        struct mii_data *mii = &sc->sc_mii;
        uint32_t fcr;
-
+#if 1
+       /* decode MIISR register value */
+       uint32_t miisr = mac_read(sc, GMACMIISR);
+       int spd = (miisr >> 1) & 03;
+       printf("xMII link status (0x%x) spd%d", miisr,
+               (spd == 2) ? 1000 : (spd == 1) ? 100 : 10);
+       if (miisr & 1)
+               printf(",full-duplex");
+       printf("\n");
+#endif
        /* Get flow control negotiation result. */
        if (IFM_SUBTYPE(mii->mii_media.ifm_cur->ifm_media) == IFM_AUTO &&
            (mii->mii_media_active & IFM_ETH_FMASK) != sc->sc_flowflags)
@@ -1207,7 +1242,7 @@
                    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
                /* Tell DMA start transmit */
-               /* CSR_WRITE(sc, GMACTDS, 1); */
+               mac_write(sc, GMACTDS, 1);
 
                txs->txs_mbuf = m0;
                txs->txs_firstdesc = sc->sc_txnext;
@@ -1241,6 +1276,7 @@
        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 
        (void)ifp;
+       /* XXX decode interrupt cause to pick isr() XXX */
        rxintr(sc);
        txreap(sc);
        return 1;
@@ -1388,6 +1424,8 @@
        return (loop > 0) ? 0 : ETIMEDOUT;
 }
 
+/* GMAC register needs to use indirect rd/wr via memory mapped registers. */
+
 static int
 mac_read(struct scx_softc *sc, int reg)
 {
@@ -1406,32 +1444,10 @@
        (void)spin_waitfor(sc, MACCMD, CMD_BUSY);
 }
 
-static int
-get_mdioclk(uint32_t freq)
-{
-
-       const struct {
-               uint16_t freq, bit; /* GAR 5:2 MDIO frequency selection */
-       } mdioclk[] = {
-               { 35,   2 },    /* 25-35 MHz */
-               { 60,   3 },    /* 35-60 MHz */
-               { 100,  0 },    /* 60-100 MHz */
-               { 150,  1 },    /* 100-150 MHz */
-               { 250,  4 },    /* 150-250 MHz */
-               { 300,  5 },    /* 250-300 MHz */
-       };
-       int i;
-
-       /* convert MDIO clk to a divisor value */
-       if (freq < mdioclk[0].freq)
-               return mdioclk[0].bit;
-       for (i = 1; i < __arraycount(mdioclk); i++) {
-               if (freq < mdioclk[i].freq)
-                       return mdioclk[i-1].bit;
-       }
-       return mdioclk[__arraycount(mdioclk) - 1].bit << GAR_CTL;
-}
-
+/*
+ * 3 independent uengines exist * to process host2media, media2host and
+ * packet data flows.
+ */
 static void
 loaducode(struct scx_softc *sc)
 {
@@ -1482,3 +1498,31 @@
        }
        bus_space_unmap(sc->sc_st, bsh, size);
 }
+
+/* bit selection to determine MDIO speed */
+
+static int
+get_mdioclk(uint32_t freq)
+{
+
+       const struct {
+               uint16_t freq, bit; /* GAR 5:2 MDIO frequency selection */
+       } mdioclk[] = {
+               { 35,   2 },    /* 25-35 MHz */
+               { 60,   3 },    /* 35-60 MHz */
+               { 100,  0 },    /* 60-100 MHz */
+               { 150,  1 },    /* 100-150 MHz */
+               { 250,  4 },    /* 150-250 MHz */
+               { 300,  5 },    /* 250-300 MHz */



Home | Main Index | Thread Index | Old Index