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 add interrupt logic stuff



details:   https://anonhg.NetBSD.org/src/rev/36b9f32d0a4c
branches:  trunk
changeset: 1029089:36b9f32d0a4c
user:      nisimura <nisimura%NetBSD.org@localhost>
date:      Tue Dec 21 11:07:51 2021 +0000

description:
add interrupt logic stuff

diffstat:

 sys/arch/arm/sociox/if_scx.c |  142 ++++++++++++++++++++++++++++++------------
 1 files changed, 102 insertions(+), 40 deletions(-)

diffs (truncated from 342 to 300 lines):

diff -r cb11f8eb4919 -r 36b9f32d0a4c sys/arch/arm/sociox/if_scx.c
--- a/sys/arch/arm/sociox/if_scx.c      Tue Dec 21 11:02:38 2021 +0000
+++ b/sys/arch/arm/sociox/if_scx.c      Tue Dec 21 11:07:51 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_scx.c,v 1.30 2021/12/20 06:47:24 nisimura Exp $     */
+/*     $NetBSD: if_scx.c,v 1.31 2021/12/21 11:07:51 nisimura Exp $     */
 
 /*-
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -46,7 +46,7 @@
 #define NOT_MP_SAFE    0
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1.30 2021/12/20 06:47:24 nisimura Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1.31 2021/12/21 11:07:51 nisimura Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -129,28 +129,29 @@
 #define xINTSR         0x200           /* aggregated interrupt status */
 #define  IRQ_RX                (1U<<1)         /* top level Rx interrupt */
 #define  IRQ_TX                (1U<<0)         /* top level Rx interrupt */
-#define  IRQ_UCODE     (1U<<20)        /* ucode load completed */
+#define  IRQ_UCODE     (1U<<20)        /* ucode load completed; W1C */
 #define xINTAEN                0x204           /* INT_A enable */
 #define xINTAE_SET     0x234           /* bit to set */
 #define xINTAE_CLR     0x238           /* bit to clr */
 #define xINTBEN                0x23c           /* INT_B enable */
 #define xINTBE_SET     0x240           /* bit to set */
 #define xINTBE_CLR     0x244           /* bit to clr */
-#define TXISR          0x400           /* transmit status */
+#define TXISR          0x400           /* transmit status; W1C */
 #define TXIEN          0x404           /* tx interrupt enable */
 #define TXIE_SET       0x428           /* bit to set */
 #define TXIE_CLR       0x42c           /* bit to clr */
-#define  TXI_NTOWNR    (1U<<17)        /* ready desc got empty */
+#define  TXI_NTOWNR    (1U<<17)        /* ??? desc array got empty */
 #define  TXI_TR_ERR    (1U<<16)        /* tx error */
 #define  TXI_TXDONE    (1U<<15)        /* tx completed */
 #define  TXI_TMREXP    (1U<<14)        /* coalesce timer expired */
-#define RXISR          0x440           /* receive status */
+#define RXISR          0x440           /* receive status; W1C */
 #define RXIEN          0x444           /* rx interrupt enable */
 #define RXIE_SET       0x468           /* bit to set */
 #define RXIE_CLR       0x46c           /* bit to clr */
 #define  RXI_RC_ERR    (1U<<16)        /* rx error */
 #define  RXI_PKTCNT    (1U<<15)        /* rx counter has new value */
 #define  RXI_TMREXP    (1U<<14)        /* coalesce timer expired */
+/* 13 sets of special purpose desc interrupt handling register exist */
 #define TDBA_LO                0x408           /* tdes array base addr 31:0 */
 #define TDBA_HI                0x434           /* tdes array base addr 63:32 */
 #define RDBA_LO                0x448           /* rdes array base addr 31:0 */
@@ -459,7 +460,6 @@
        int sc_flowflags;               /* 802.3x PAUSE flow control */
        uint32_t sc_mdclk;              /* GAR 5:2 clock selection */
        uint32_t sc_t0cotso;            /* T0_CSUM | T0_TSO to run */
-       int sc_ucodeloaded;             /* ucode for H2M/M2H/PKT */
        int sc_100mii;                  /* 1 for RMII/MII, 0 for RGMII */
        int sc_phandle;                 /* fdt phandle */
        uint64_t sc_freq;
@@ -603,7 +603,7 @@
 mac_read(struct scx_softc *sc, int reg)
 {
 
-       CSR_WRITE(sc, MACCMD, reg);
+       CSR_WRITE(sc, MACCMD, reg | CMD_BUSY);
        (void)WAIT_FOR_CLR(sc, MACCMD, CMD_BUSY, 0);
        return CSR_READ(sc, MACDATA);
 }
@@ -613,10 +613,11 @@
 {
 
        CSR_WRITE(sc, MACDATA, val);
-       CSR_WRITE(sc, MACCMD, reg | CMD_IOWR);
+       CSR_WRITE(sc, MACCMD, reg | CMD_IOWR | CMD_BUSY);
        (void)WAIT_FOR_CLR(sc, MACCMD, CMD_BUSY, 0);
 }
 
+/* dig and decode "clock-frequency" value for a given clkname */
 static int
 get_clk_freq(int phandle, const char *clkname)
 {
@@ -671,7 +672,6 @@
        struct scx_softc * const sc = device_private(self);
        struct fdt_attach_args * const faa = aux;
        const int phandle = faa->faa_phandle;
-       bus_space_tag_t bst = faa->faa_bst;
        bus_space_handle_t bsh;
        bus_space_handle_t eebsh;
        bus_addr_t addr[2];
@@ -683,7 +683,7 @@
        long ref_clk;
 
        aprint_naive("\n");
-       aprint_normal(": Gigabit Ethernet Controller\n");
+       aprint_normal(": Socionext Gigabit Ethernet controller\n");
 
        if (fdtbus_get_reg(phandle, 0, addr+0, size+0) != 0
            || bus_space_map(faa->faa_bst, addr[0], size[0], 0, &bsh) != 0) {
@@ -707,7 +707,7 @@
        }
 
        sc->sc_dev = self;
-       sc->sc_st = bst;
+       sc->sc_st = faa->faa_bst;
        sc->sc_sh = bsh;
        sc->sc_sz = size[0];
        sc->sc_eesh = eebsh;
@@ -754,7 +754,6 @@
        struct scx_softc * const sc = device_private(self);
        struct acpi_attach_args * const aa = aux;
        ACPI_HANDLE handle = aa->aa_node->ad_handle;
-       bus_space_tag_t bst = aa->aa_memt;
        bus_space_handle_t bsh, eebsh;
        struct acpi_resources res;
        struct acpi_mem *mem;
@@ -763,7 +762,7 @@
        ACPI_STATUS rv;
 
        aprint_naive("\n");
-       aprint_normal(": Gigabit Ethernet Controller\n");
+       aprint_normal(": Socionext Gigabit Ethernet controller\n");
 
        rv = acpi_resource_parse(self, handle, "_CRS",
            &res, &acpi_resource_parse_ops_default);
@@ -777,7 +776,8 @@
                aprint_error_dev(self, "incomplete crs resources\n");
                return;
        }
-       if (bus_space_map(bst, mem->ar_base, mem->ar_length, 0, &bsh) != 0) {
+       if (bus_space_map(aa->aa_memt, mem->ar_base, mem->ar_length, 0,
+           &bsh) != 0) {
                aprint_error_dev(self, "couldn't map registers\n");
                return;
        }
@@ -793,7 +793,8 @@
                aprint_error_dev(self, "incomplete eeprom resources\n");
                goto fail;
        }
-       if (bus_space_map(bst, mem->ar_base, mem->ar_length, 0, &eebsh) != 0) {
+       if (bus_space_map(aa->aa_memt, mem->ar_base, mem->ar_length, 0,
+           &eebsh)) {
                aprint_error_dev(self, "couldn't map registers\n");
                goto fail;
        }
@@ -813,7 +814,7 @@
                ref_freq = 250 * 1000 * 1000;
 
        sc->sc_dev = self;
-       sc->sc_st = bst;
+       sc->sc_st = aa->aa_memt;
        sc->sc_sh = bsh;
        sc->sc_eesh = eebsh;
        sc->sc_dmat = aa->aa_dmat64;
@@ -874,8 +875,7 @@
 
        sc->sc_mdclk = get_mdioclk(sc->sc_freq) << GAR_CLK; /* 5:2 clk ratio */
 
-       if (sc->sc_ucodeloaded == 0)
-               loaducode(sc);
+       loaducode(sc);
 
        mii->mii_ifp = ifp;
        mii->mii_readreg = mii_readreg;
@@ -1026,6 +1026,9 @@
        CSR_WRITE(sc, COMINIT, INIT_DB | INIT_CLS);
        WAIT_FOR_CLR(sc, COMINIT, (INIT_DB | INIT_CLS), 0);
 
+       CSR_WRITE(sc, TXISR, ~0);
+       CSR_WRITE(sc, xINTAE_CLR, ~0);
+
        mac_write(sc, GMACEVCTL, 1);
 }
 
@@ -1076,6 +1079,16 @@
        sc->sc_rxptr = 0;
        sc->sc_rxptr = 0;
 
+       paddr = SCX_CDTXADDR(sc, 0);            /* tdes array (ring#0) */
+       mac_write(sc, TDBA_HI, BUS_ADDR_HI32(paddr));
+       mac_write(sc, TDBA_LO, BUS_ADDR_LO32(paddr));
+       paddr = SCX_CDRXADDR(sc, 0);            /* rdes array (ring#1) */
+       mac_write(sc, RDBA_HI, BUS_ADDR_HI32(paddr));
+       mac_write(sc, RDBA_LO, BUS_ADDR_LO32(paddr));
+
+       CSR_WRITE(sc, TXCONF, DESCNF_LE);       /* little endian */
+       CSR_WRITE(sc, RXCONF, DESCNF_LE);       /* little endian */
+
        /* set my address in perfect match slot 0. little endian order */
        csr = (ea[3] << 24) | (ea[2] << 16) | (ea[1] << 8) |  ea[0];
        mac_write(sc, GMACMAL0, csr);
@@ -1089,30 +1102,30 @@
        if ((error = ether_mediachange(ifp)) != 0)
                goto out;
 
-       paddr = SCX_CDTXADDR(sc, 0);
-       mac_write(sc, TDBA_HI, BUS_ADDR_HI32(paddr));
-       mac_write(sc, TDBA_LO, BUS_ADDR_LO32(paddr));
-       paddr = SCX_CDRXADDR(sc, 0);
-       mac_write(sc, RDBA_HI, BUS_ADDR_HI32(paddr));
-       mac_write(sc, RDBA_LO, BUS_ADDR_LO32(paddr));
-
-       CSR_WRITE(sc, TXCONF, DESCNF_LE);       /* little endian */
-       CSR_WRITE(sc, RXCONF, DESCNF_LE);       /* little endian */
-
        CSR_WRITE(sc, DESC_SRST, 01);
        WAIT_FOR_CLR(sc, DESC_SRST, 01, 0);
 
        CSR_WRITE(sc, DESC_INIT, 01);
        WAIT_FOR_CLR(sc, DESC_INIT, 01, 0);
 
-       CSR_WRITE(sc, GMACRDLA, _RDLA);
-       CSR_WRITE(sc, GMACTDLA, _TDLA);
+       CSR_WRITE(sc, GMACRDLA, _RDLA);         /* GMAC rdes store */
+       CSR_WRITE(sc, GMACTDLA, _TDLA);         /* GMAC tdes store */
 
        CSR_WRITE(sc, FLOWTHR, (48<<16) | 36);  /* pause|resume threshold */
        mac_write(sc, GMACFCR, 256 << 16);      /* 31:16 pause value */
 
-       CSR_WRITE(sc, RXIE_CLR, ~0);
-       CSR_WRITE(sc, TXIE_CLR, ~0);
+       CSR_WRITE(sc, RXIE_CLR, ~0);    /* clear Rx interrupt enable */
+       CSR_WRITE(sc, TXIE_CLR, ~0);    /* clear Tx interrupt enable */
+
+       CSR_WRITE(sc, RXCOLMAX, 8);     /* Rx coalesce upper bound */
+       CSR_WRITE(sc, TXCOLMAX, 8);     /* Tx coalesce upper bound */
+       CSR_WRITE(sc, RXITIMER, 500);   /* Rx co. timer usec */
+       CSR_WRITE(sc, TXITIMER, 500);   /* Tx co. timer usec */
+
+       CSR_WRITE(sc, RXIE_SET, RXI_RC_ERR | RXI_PKTCNT | RXI_TMREXP);
+       CSR_WRITE(sc, TXIE_SET, TXI_TR_ERR | TXI_TXDONE | TXI_TMREXP);
+       
+       CSR_WRITE(sc, xINTAE_SET, IRQ_RX | IRQ_TX);
 
        /* kick to start GMAC engine */
        csr = mac_read(sc, GMACOMR);
@@ -1142,6 +1155,10 @@
        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
        ifp->if_timer = 0;
 
+       CSR_WRITE(sc, xINTAE_CLR, ~0);
+       CSR_WRITE(sc, TXISR, ~0);
+       CSR_WRITE(sc, RXISR, ~0);
+
        if (CSR_READ(sc, CORESTAT) != 0) {
                CSR_WRITE(sc, DMACTL_H2M, DMACTL_STOP);
                CSR_WRITE(sc, DMACTL_M2H, DMACTL_STOP);
@@ -1447,12 +1464,35 @@
 scx_intr(void *arg)
 {
        struct scx_softc *sc = arg;
-       struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+       uint32_t enable, status;
+
+       status = CSR_READ(sc, xINTSR); /* not W1C */
+       enable = CSR_READ(sc, xINTAEN);
+       if ((status & enable) == 0)
+               return 0;
+       if (status & (IRQ_TX | IRQ_RX)) {
+               CSR_WRITE(sc, xINTAE_CLR, (IRQ_TX | IRQ_RX));
 
-       (void)ifp;
-       /* XXX decode interrupt cause to pick isr() XXX */
-       rxintr(sc);
-       txreap(sc);
+               status = CSR_READ(sc, RXISR);
+               CSR_WRITE(sc, RXISR, status);
+               if (status & RXI_RC_ERR)
+                       aprint_error_dev(sc->sc_dev, "Rx error\n");
+               if (status & (RXI_PKTCNT | RXI_TMREXP)) {
+                       rxintr(sc);
+                       (void)CSR_READ(sc, RXDONECNT); /* clear RXI_RXDONE */
+               }
+
+               status = CSR_READ(sc, TXISR);
+               CSR_WRITE(sc, TXISR, status);
+               if (status & TXI_TR_ERR)
+                       aprint_error_dev(sc->sc_dev, "Tx error\n");
+               if (status & (TXI_TXDONE | TXI_TMREXP)) {
+                       txreap(sc);
+                       (void)CSR_READ(sc, TXDONECNT); /* clear TXI_TXDONE */
+               }
+
+               CSR_WRITE(sc, xINTAE_SET, (IRQ_TX | IRQ_RX));
+       }
        return 1;
 }
 
@@ -1473,7 +1513,7 @@
                SCX_CDTXSYNC(sc, txs->txs_firstdesc, txs->txs_ndesc,
                    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 
-               txstat = sc->sc_txdescs[txs->txs_lastdesc].t0;
+               txstat = le32toh(sc->sc_txdescs[txs->txs_lastdesc].t0);
                if (txstat & T0_OWN) /* desc is still in use */
                        break;
 
@@ -1734,6 +1774,23 @@
        callout_schedule(&sc->sc_callout, hz);
 }



Home | Main Index | Thread Index | Old Index