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 interlim commit to snapshot SC2A11 GbE p...
details: https://anonhg.NetBSD.org/src/rev/a3387d0d1ef6
branches: trunk
changeset: 1027703:a3387d0d1ef6
user: nisimura <nisimura%NetBSD.org@localhost>
date: Thu Dec 16 11:36:25 2021 +0000
description:
interlim commit to snapshot SC2A11 GbE progress.
diffstat:
sys/arch/arm/sociox/if_scx.c | 184 ++++++++++++++++++++++++------------------
1 files changed, 103 insertions(+), 81 deletions(-)
diffs (truncated from 388 to 300 lines):
diff -r df0b881cb218 -r a3387d0d1ef6 sys/arch/arm/sociox/if_scx.c
--- a/sys/arch/arm/sociox/if_scx.c Thu Dec 16 11:32:22 2021 +0000
+++ b/sys/arch/arm/sociox/if_scx.c Thu Dec 16 11:36:25 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_scx.c,v 1.26 2021/12/16 11:32:22 nisimura Exp $ */
+/* $NetBSD: if_scx.c,v 1.27 2021/12/16 11:36:25 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.26 2021/12/16 11:32:22 nisimura Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1.27 2021/12/16 11:36:25 nisimura Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -408,7 +408,7 @@
int sc_phy_id; /* PHY address */
int sc_flowflags; /* 802.3x PAUSE flow control */
uint32_t sc_mdclk; /* GAR 5:2 clock selection */
- uint32_t sc_t0coso; /* T0_CSUM | T0_SGOL to run */
+ 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 */
@@ -431,6 +431,9 @@
int sc_rxptr; /* next ready Rx descriptor/descsoft */
krndsource_t rnd_source; /* random source */
+#ifdef GMAC_EVENT_COUNTER
+ /* 80 event counter exist */
+#endif
};
#define SCX_CDTXADDR(sc, x) ((sc)->sc_cddma + SCX_CDTXOFF((x)))
@@ -477,6 +480,16 @@
if ((x) == MD_NRXDESC - 1) __rxd->r0 |= R0_EOD; \
} while (/*CONSTCOND*/0)
+/* memory mapped CSR register access */
+#define CSR_READ(sc,off) \
+ bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (off))
+#define CSR_WRITE(sc,off,val) \
+ bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (off), (val))
+
+/* flash memory access */
+#define EE_READ(sc,off) \
+ bus_space_read_4((sc)->sc_st, (sc)->sc_eesh, (off))
+
static int scx_fdt_match(device_t, cfdata_t, void *);
static void scx_fdt_attach(device_t, device_t, void *);
static int scx_acpi_match(device_t, cfdata_t, void *);
@@ -558,6 +571,10 @@
{ .compat = "socionext,synquacer-netsec" },
DEVICE_COMPAT_EOL
};
+static const struct device_compatible_entry compatible[] = {
+ { .compat = "SCX0001" },
+ DEVICE_COMPAT_EOL
+};
static int
scx_fdt_match(device_t parent, cfdata_t cf, void *aux)
@@ -634,15 +651,9 @@
static int
scx_acpi_match(device_t parent, cfdata_t cf, void *aux)
{
- static const char * compatible[] = {
- "SCX0001",
- NULL
- };
struct acpi_attach_args *aa = aux;
- if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE)
- return 0;
- return acpi_match_hid(aa->aa_node->ad_devinfo, compatible);
+ return acpi_compatible_match(aa, compatible);
}
static void
@@ -660,6 +671,7 @@
ACPI_INTEGER acpi_phy, acpi_freq;
ACPI_STATUS rv;
+aprint_normal(": Gigabit Ethernet Controller\n");
rv = acpi_resource_parse(self, handle, "_CRS",
&res, &acpi_resource_parse_ops_default);
if (ACPI_FAILURE(rv))
@@ -713,7 +725,7 @@
sc->sc_sh = bsh;
sc->sc_eesh = eebsh;
sc->sc_dmat = aa->aa_dmat64;
- sc->sc_dmat32 = aa->aa_dmat; /* descriptor needs dma32 */
+ sc->sc_dmat32 = aa->aa_dmat;
aprint_normal_dev(self,
"phy mode %s, phy id %d, freq %ld\n", phy_mode, (int)acpi_phy, acpi_freq);
@@ -742,18 +754,19 @@
struct ifnet * const ifp = &sc->sc_ethercom.ec_if;
struct mii_data * const mii = &sc->sc_mii;
struct ifmedia * const ifm = &mii->mii_media;
- uint32_t hwver, dwimp, dwfea;
+ uint32_t which, dwimp, dwfea;
uint8_t enaddr[ETHER_ADDR_LEN];
bus_dma_segment_t seg;
uint32_t csr;
int i, nseg, error = 0;
- hwver = CSR_READ(sc, HWVER); /* Socionext version */
- dwimp = mac_read(sc, GMACIMPL); /* DW EMAC XX.YY */
- dwfea = mac_read(sc, HWFEA); /* DW feature */
+ which = CSR_READ(sc, HWVER); /* Socionext version 5.00xx */
+ dwimp = mac_read(sc, GMACIMPL); /* DWC EMAC XX.YY */
+ dwfea = mac_read(sc, HWFEA); /* DWC feature */
aprint_normal_dev(sc->sc_dev,
- "Socionext NetSec GbE %d.%d (impl 0x%x, feature 0x%x)\n",
- hwver >> 16, hwver & 0xffff,
+ "Socionext NetSec GbE %x.%x"
+ " (impl 0x%x, feature 0x%x)\n",
+ which >> 16, which & 0xffff,
dwimp, dwfea);
/* fetch MAC address in flash. stored in big endian order */
@@ -762,14 +775,13 @@
enaddr[1] = csr >> 16;
enaddr[2] = csr >> 8;
enaddr[3] = csr;
- csr = bus_space_read_4(sc->sc_st, sc->sc_eesh, 4);
csr = EE_READ(sc, 0x04);
enaddr[4] = csr >> 24;
enaddr[5] = csr >> 16;
aprint_normal_dev(sc->sc_dev,
"Ethernet address %s\n", ether_sprintf(enaddr));
- sc->sc_mdclk = get_mdioclk(sc->sc_freq); /* 5:2 clk control */
+ sc->sc_mdclk = get_mdioclk(sc->sc_freq) << GAR_CLK; /* 5:2 clk ratio */
if (sc->sc_ucodeloaded == 0)
loaducode(sc);
@@ -917,10 +929,11 @@
mac_write(sc, GMACBMR, _BMR);
mac_write(sc, GMACAFR, 0);
- CSR_WRITE(sc, CLKEN, CLK_ALL); /* distribute clock sources */
- CSR_WRITE(sc, SWRESET, 0); /* reset operation */
- CSR_WRITE(sc, SWRESET, 1U<<31); /* manifest run */
- CSR_WRITE(sc, COMINIT, 3); /* DB|CLS */
+ CSR_WRITE(sc, CLKEN, CLK_ALL); /* distribute clock sources */
+ CSR_WRITE(sc, SWRESET, 0); /* reset operation */
+ CSR_WRITE(sc, SWRESET, SRST_RUN); /* manifest run */
+ CSR_WRITE(sc, COMINIT, INIT_DB | INIT_CLS);
+ WAIT_FOR_CLR(sc, COMINIT, (INIT_DB | INIT_CLS), 0);
mac_write(sc, GMACEVCTL, 1);
}
@@ -930,6 +943,7 @@
{
struct scx_softc *sc = ifp->if_softc;
const uint8_t *ea = CLLADDR(ifp->if_sadl);
+ paddr_t paddr;
uint32_t csr;
int i, error;
@@ -984,15 +998,34 @@
if ((error = ether_mediachange(ifp)) != 0)
goto out;
- /* XXX 32 bit paddr XXX hand Tx/Rx rings to HW XXX */
- mac_write(sc, GMACTDLA, SCX_CDTXADDR(sc, 0));
- mac_write(sc, GMACRDLA, SCX_CDRXADDR(sc, 0));
+ 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, 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);
/* kick to start GMAC engine */
- CSR_WRITE(sc, RXI_CLR, ~0);
- CSR_WRITE(sc, TXI_CLR, ~0);
csr = mac_read(sc, GMACOMR);
- mac_write(sc, GMACOMR, csr | OMR_RS | OMR_ST);
+ mac_write(sc, GMACOMR, csr | OMR_SR | OMR_ST);
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
@@ -1017,6 +1050,14 @@
/* Mark the interface down and cancel the watchdog timer. */
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
ifp->if_timer = 0;
+
+ if (CSR_READ(sc, CORESTAT) != 0) {
+ CSR_WRITE(sc, DMACTL_H2M, DMACTL_STOP);
+ CSR_WRITE(sc, DMACTL_M2H, DMACTL_STOP);
+
+ WAIT_FOR_CLR(sc, DMACTL_H2M, DMACTL_STOP, 0);
+ WAIT_FOR_CLR(sc, DMACTL_M2H, DMACTL_STOP, 0);
+ }
}
static int
@@ -1068,6 +1109,16 @@
return error;
}
+static uint32_t
+bit_reverse_32(uint32_t x)
+{
+ x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
+ x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
+ x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
+ x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
+ return (x >> 16) | (x << 16);
+}
+
static void
scx_set_rcvfilt(struct scx_softc *sc)
{
@@ -1128,8 +1179,8 @@
mac_write(sc, GMACMAH(i), addr | 1U<<31);
} else {
/* use hash table when too many */
- /* bit_reserve_32(~crc) !? */
crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN);
+ crc = bit_reverse_32(~crc);
/* 1(31) 5(30:26) bit sampling */
mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f);
}
@@ -1152,7 +1203,7 @@
scx_start(struct ifnet *ifp)
{
struct scx_softc *sc = ifp->if_softc;
- struct mbuf *m0, *m;
+ struct mbuf *m0;
struct scx_txsoft *txs;
bus_dmamap_t dmamap;
int error, nexttx, lasttx, ofree, seg;
@@ -1236,26 +1287,12 @@
tdes->t2 = htole32(BUS_ADDR_LO32(paddr));
tdes->t1 = htole32(BUS_ADDR_HI32(paddr));
tdes->t0 = tdes0 | (tdes->t0 & T0_EOD) |
- (15 << T0_TRID) | T0_PT |
- sc->sc_t0coso | T0_TRS;
+ (15 << T0_TDRID) | T0_PT |
+ sc->sc_t0cotso | T0_TRS;
tdes0 = T0_OWN; /* 2nd and other segments */
+ /* NB; t0 DRID field contains zero */
lasttx = nexttx;
}
- /*
- * Outgoing NFS mbuf must be unloaded when Tx completed.
- * Without T1_IC NFS mbuf is left unack'ed for excessive
- * time and NFS stops to proceed until scx_watchdog()
- * calls txreap() to reclaim the unack'ed mbuf.
- * It's painful to traverse every mbuf chain to determine
- * whether someone is waiting for Tx completion.
- */
- m = m0;
- do {
- if ((m->m_flags & M_EXT) && m->m_ext.ext_free) {
- sc->sc_txdescs[lasttx].t0 |= T0_IOC; /* !!! */
- break;
- }
- } while ((m = m->m_next) != NULL);
/* Write deferred 1st segment T0_OWN at the final stage */
sc->sc_txdescs[lasttx].t0 |= T0_LS;
@@ -1546,11 +1583,7 @@
uint32_t miia;
int ntries;
-#define CLK_150_250M (1<<2)
-uint32_t clk = CSR_READ(sc, CLKEN);
-CSR_WRITE(sc, CLKEN, clk | CLK_G);
-
- miia = (phy << GAR_PHY) | (reg << GAR_REG) | CLK_150_250M;
+ miia = (phy << GAR_PHY) | (reg << GAR_REG) | sc->sc_mdclk;
mac_write(sc, GMACGAR, miia | GAR_BUSY);
for (ntries = 0; ntries < 1000; ntries++) {
if ((mac_read(sc, GMACGAR) & GAR_BUSY) == 0)
Home |
Main Index |
Thread Index |
Old Index