Module Name:    src
Committed By:   nisimura
Date:           Mon Mar 23 10:26:07 UTC 2020

Modified Files:
        src/sys/arch/arm/sociox: if_ave.c

Log Message:
adapt dual descriptor design both for AVE64 and AVE32


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/arm/sociox/if_ave.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/sociox/if_ave.c
diff -u src/sys/arch/arm/sociox/if_ave.c:1.13 src/sys/arch/arm/sociox/if_ave.c:1.14
--- src/sys/arch/arm/sociox/if_ave.c:1.13	Mon Mar 23 07:42:00 2020
+++ src/sys/arch/arm/sociox/if_ave.c	Mon Mar 23 10:26:07 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ave.c,v 1.13 2020/03/23 07:42:00 nisimura Exp $	*/
+/*	$NetBSD: if_ave.c,v 1.14 2020/03/23 10:26:07 nisimura Exp $	*/
 
 /*-
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ave.c,v 1.13 2020/03/23 07:42:00 nisimura Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ave.c,v 1.14 2020/03/23 10:26:07 nisimura Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -182,29 +182,6 @@ struct rdes32 { uint32_t r0, r1; };
 #define MD_NRXDESC_MASK	(MD_NRXDESC - 1)
 #define MD_NEXTRX(x)		(((x) + 1) & MD_NRXDESC_MASK)
 
-#define AVE_INIT_RXDESC(sc, x)						\
-do {									\
-	struct ave_rxsoft *__rxs = &(sc)->sc_rxsoft[(x)];		\
-	struct rdes *__rxd = &(sc)->sc_rxdescs[(x)];			\
-	struct mbuf *__m = __rxs->rxs_mbuf;				\
-	bus_addr_t __paddr =__rxs->rxs_dmamap->dm_segs[0].ds_addr;	\
-	__m->m_data = __m->m_ext.ext_buf;				\
-	__rxd->r2 = htole32(BUS_ADDR_HI32(__paddr));			\
-	__rxd->r1 = htole32(BUS_ADDR_LO32(__paddr));			\
-	__rxd->r0 = R0_OWN | R0_FL_MASK;				\
-} while (/*CONSTCOND*/0)
-
-#define AVE32_INIT_RXDESC(sc, x)					\
-do {									\
-	struct ave_rxsoft *__rxs = &(sc)->sc_rxsoft[(x)];		\
-	struct rdes32 *__rxd = &(sc)->sc_rxd32[(x)];			\
-	struct mbuf *__m = __rxs->rxs_mbuf;				\
-	bus_addr_t __paddr =__rxs->rxs_dmamap->dm_segs[0].ds_addr;	\
-	__m->m_data = __m->m_ext.ext_buf;				\
-	__rxd->r1 = htole32(__paddr);					\
-	__rxd->r0 = R0_OWN | R0_FL_MASK;				\
-} while (/*CONSTCOND*/0)
-
 struct ave_txsoft {
 	struct mbuf *txs_mbuf;		/* head of our mbuf chain */
 	bus_dmamap_t txs_dmamap;	/* our DMA map */
@@ -218,6 +195,8 @@ struct ave_rxsoft {
 	bus_dmamap_t rxs_dmamap;	/* our DMA map */
 };
 
+struct desops;
+
 struct ave_softc {
 	device_t sc_dev;		/* generic device information */
 	bus_space_tag_t sc_st;		/* bus space tag */
@@ -241,6 +220,7 @@ struct ave_softc {
 	struct rdes *sc_rxdescs;	/* PTR to rdes [NRXDESC] store */
 	struct tdes32 *sc_txd32;
 	struct rdes32 *sc_rxd32;
+	struct desops *sc_desops;	/* descriptor management */
 
 	struct ave_txsoft sc_txsoft[MD_TXQUEUELEN];
 	struct ave_rxsoft sc_rxsoft[MD_NRXDESC];
@@ -286,8 +266,62 @@ static int add_rxbuf(struct ave_softc *,
 #define CSR_WRITE(sc, off, val) \
 	    bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (off), (val))
 
+struct desops {
+	void (*make_tdes)(void *, int, int, int);
+	void (*mark_txfs)(void *, int);
+	void (*mark_txls)(void *, int);
+	void (*mark_txic)(void *, int);
+	int  (*read_tdes0)(void *, int);
+	int  (*read_rdes0)(void *, int);
+	int  (*read_rlen)(void *, int);
+	void (*init_rdes)(void *, int);
+};
+#define MAKE_TDES(sc,x,s,o) (*(sc)->sc_desops->make_tdes)((sc),(x),(s),(o))
+#define MARK_TXFS(sc,x) (*(sc)->sc_desops->mark_txfs)((sc),(x))
+#define MARK_TXLS(sc,x) (*(sc)->sc_desops->mark_txls)((sc),(x))
+#define MARK_TXIC(sc,x) (*(sc)->sc_desops->mark_txic)((sc),(x))
+#define READ_TDES0(sc,x) (*(sc)->sc_desops->read_tdes0)((sc),(x))
+#define READ_RDES0(sc,x) (*(sc)->sc_desops->read_rdes0)((sc),(x))
+#define INIT_RDES(sc,x) (*(sc)->sc_desops->init_rdes)((sc),(x))
+/* received frame length is stored in RDES0 10:0 */
+
+static void make_tdes(void *, int, int, int);
+static void mark_txfs(void *, int);
+static void mark_txls(void *, int);
+static void mark_txic(void *, int);
+static int read_tdes0(void *, int);
+static int read_rdes0(void *, int);
+static void init_rdes(void *, int);
+struct desops ave64ops = {
+	make_tdes,
+	mark_txfs,
+	mark_txls,
+	mark_txic,
+	read_tdes0,
+	read_rdes0,
+	NULL,
+	init_rdes,
+};
+static void omake_tdes(void *, int, int, int);
+static void omark_txfs(void *, int);
+static void omark_txls(void *, int);
+static void omark_txic(void *, int);
+static int oread_tdes0(void *, int);
+static int oread_rdes0(void *, int);
+static void oinit_rdes(void *, int);
+struct desops ave32ops = {
+	omake_tdes,
+	omark_txfs,
+	omark_txls,
+	omark_txic,
+	oread_tdes0,
+	oread_rdes0,
+	NULL,
+	oinit_rdes,
+};
+
 static const struct of_compat_data compat_data[] = {
-	{ "socionext,unifier-ld20-ave4", 64 },	/* XXX only this for now */
+	{ "socionext,unifier-ld20-ave4", 64 },
 	{ "socionext,unifier-pro4-ave4", 32 },
 	{ "socionext,unifier-pxs2-ave4", 32 },
 	{ "socionext,unifier-ld11-ave4", 32 },
@@ -357,12 +391,13 @@ ave_fdt_attach(device_t parent, device_t
 
 	aprint_naive("\n");
 	aprint_normal(": Gigabit Ethernet Controller\n");
-	aprint_normal_dev(self, "UniPhier %c%c%c%c AVE %d GbE (%d.%d) %s\n",
+	aprint_normal_dev(self, "UniPhier %c%c%c%c AVE%d GbE (%d.%d) %s\n",
 	    hwimp >> 24, hwimp >> 16, hwimp >> 8, hwimp,
 	    sc->sc_model, hwver >> 8, hwver & 0xff, phy_mode);
 	aprint_normal_dev(self, "interrupt on %s\n", intrstr);
 
 	sc->sc_100mii = (strcmp(phy_mode, "rgmii") == 0) ? CFG_MII : 0;
+	sc->sc_desops = (sc->sc_model == 64) ? &ave64ops : &ave32ops;
 
 	CSR_WRITE(sc, AVEGR, GR_GRST | GR_PHYRST);
 	DELAY(20);
@@ -996,18 +1031,13 @@ ave_start(struct ifnet *ifp)
 		for (nexttx = sc->sc_txnext, seg = 0;
 		     seg < dmamap->dm_nsegs;
 		     seg++, nexttx = MD_NEXTTX(nexttx)) {
-			struct tdes *tdes = &sc->sc_txdescs[nexttx];
-			bus_addr_t paddr = dmamap->dm_segs[seg].ds_addr;
+			MAKE_TDES(sc, nexttx, seg, tdes0 | sc->sc_t0csum);
 			/*
 			 * If this is the first descriptor we're
 			 * enqueueing, don't set the OWN bit just
 			 * yet.	 That could cause a race condition.
 			 * We'll do it below.
 			 */
-			tdes->t2 = htole32(BUS_ADDR_HI32(paddr));
-			tdes->t1 = htole32(BUS_ADDR_LO32(paddr));
-			tdes->t0 = tdes0 | sc->sc_t0csum
-			     | (dmamap->dm_segs[seg].ds_len & T0_TBS_MASK);
 			tdes0 = T0_OWN; /* 2nd and other segments */
 			lasttx = nexttx;
 		}
@@ -1022,14 +1052,14 @@ ave_start(struct ifnet *ifp)
 		m = m0;
 		do {
 			if ((m->m_flags & M_EXT) && m->m_ext.ext_free) {
-				sc->sc_txdescs[lasttx].t0 |= T0_IOC;
+				MARK_TXIC(sc, lasttx);
 				break;
 			}
 		} while ((m = m->m_next) != NULL);
 
 		/* Write deferred 1st segment T0_OWN at the final stage */
-		sc->sc_txdescs[lasttx].t0 |= T0_LS;
-		sc->sc_txdescs[sc->sc_txnext].t0 |= (T0_FS | T0_OWN);
+		MARK_TXLS(sc, lasttx);
+		MARK_TXFS(sc, sc->sc_txnext);
 		/* AVE_CDTXSYNC(sc, sc->sc_txnext, dmamap->dm_nsegs,
 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); */
 
@@ -1115,7 +1145,7 @@ txreap(struct ave_softc *sc)
 		/* AVE_CDTXSYNC(sc, txs->txs_firstdesc, txs->txs_ndesc,
 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); */
 
-		txstat = sc->sc_txdescs[txs->txs_lastdesc].t0;
+		txstat = READ_TDES0(sc, txs->txs_lastdesc);
 
 		if (txstat & T0_OWN) /* desc is still in use */
 			break;
@@ -1154,7 +1184,7 @@ rxintr(struct ave_softc *sc)
 		/* AVE_CDRXSYNC(sc, i,
 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); */
 
-		rxstat = sc->sc_rxdescs[i].r0;
+		rxstat = READ_RDES0(sc, i);
 		if (rxstat & R0_OWN) /* desc is left empty */
 			break;
 
@@ -1169,7 +1199,7 @@ rxintr(struct ave_softc *sc)
 
 		if (add_rxbuf(sc, i) != 0) {
 			if_statinc(ifp, if_ierrors);
-			AVE_INIT_RXDESC(sc, i);
+			INIT_RDES(sc, i);
 			bus_dmamap_sync(sc->sc_dmat,
 			    rxs->rxs_dmamap, 0,
 			    rxs->rxs_dmamap->dm_mapsize,
@@ -1223,7 +1253,134 @@ add_rxbuf(struct ave_softc *sc, int i)
 
 	bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
 	    rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
-	AVE_INIT_RXDESC(sc, i);
+	INIT_RDES(sc, i);
 
 	return 0;
 }
+
+/* AVE64 descriptor management ops */
+
+static void make_tdes(void *cookie, int x, int seg, int tdes0)
+{
+	struct ave_softc *sc = cookie;
+	struct ave_txsoft *txs = &sc->sc_txsoft[x];
+	struct tdes *txd = &sc->sc_txdescs[x];
+	bus_addr_t p = txs->txs_dmamap->dm_segs[seg].ds_addr;
+	bus_size_t z = txs->txs_dmamap->dm_segs[seg].ds_len;
+
+	txd->t2 = htole32(BUS_ADDR_HI32(p));
+	txd->t1 = htole32(BUS_ADDR_LO32(p));
+	txd->t0 = tdes0 | (z & T0_TBS_MASK);
+}
+
+static void mark_txfs(void *cookie, int x)
+{
+	struct ave_softc *sc = cookie;
+	struct tdes *txd = &sc->sc_txdescs[x];
+	txd->t0 |= (T0_FS | T0_OWN);
+}
+
+static void mark_txls(void *cookie, int x)
+{
+	struct ave_softc *sc = cookie;
+	struct tdes *txd = &sc->sc_txdescs[x];
+	txd->t0 |= T0_LS;
+}
+
+static void mark_txic(void *cookie, int x)
+{
+	struct ave_softc *sc = cookie;
+	struct tdes *txd = &sc->sc_txdescs[x];
+	txd->t0 |= T0_IOC;
+}
+
+static int read_tdes0(void *cookie, int x)
+{
+	struct ave_softc *sc = cookie;
+	struct tdes *txd = &sc->sc_txdescs[x];
+	return txd->t0;
+}
+
+static int read_rdes0(void *cookie, int x)
+{
+	struct ave_softc *sc = cookie;
+	struct rdes *rxd = &sc->sc_rxdescs[x];
+	return rxd->r0;
+}
+
+static void init_rdes(void *cookie, int x)
+{
+	struct ave_softc *sc = cookie;
+	struct ave_rxsoft *rxs = &sc->sc_rxsoft[x];
+	struct rdes *rxd = &sc->sc_rxdescs[x];
+	struct mbuf *m = rxs->rxs_mbuf;
+	bus_addr_t p = rxs->rxs_dmamap->dm_segs[0].ds_addr;
+	bus_size_t z = rxs->rxs_dmamap->dm_segs[0].ds_len;
+
+	m->m_data = m->m_ext.ext_buf;
+	rxd->r1 = htole32(BUS_ADDR_LO32(p));
+	rxd->r0 = R0_OWN | (z & R0_FL_MASK);
+}
+
+/* AVE32 descriptor management ops */
+
+static void omake_tdes(void *cookie, int x, int seg, int tdes0)
+{
+	struct ave_softc *sc = cookie;
+	struct ave_txsoft *txs = &sc->sc_txsoft[x];
+	struct tdes32 *txd = &sc->sc_txd32[x];
+	bus_addr_t p = txs->txs_dmamap->dm_segs[seg].ds_addr;
+	bus_size_t z = txs->txs_dmamap->dm_segs[seg].ds_len;
+
+	txd->t1 = htole32(BUS_ADDR_LO32(p));
+	txd->t0 = tdes0 | (z & T0_TBS_MASK);
+}
+
+static void omark_txfs(void *cookie, int x)
+{
+	struct ave_softc *sc = cookie;
+	struct tdes32 *txd = &sc->sc_txd32[x];
+	txd->t0 |= (T0_FS | T0_OWN);
+}
+
+static void omark_txls(void *cookie, int x)
+{
+	struct ave_softc *sc = cookie;
+	struct tdes32 *txd = &sc->sc_txd32[x];
+	txd->t0 |= T0_LS;
+}
+
+static void omark_txic(void *cookie, int x)
+{
+	struct ave_softc *sc = cookie;
+	struct tdes32 *txd = &sc->sc_txd32[x];
+	txd->t0 |= T0_LS;
+}
+
+static int oread_tdes0(void *cookie, int x)
+{
+	struct ave_softc *sc = cookie;
+	struct tdes32 *txd = &sc->sc_txd32[x];
+	return txd->t0;
+}
+
+static int oread_rdes0(void *cookie, int x)
+{
+	struct ave_softc *sc = cookie;
+	struct rdes32 *rxd = &sc->sc_rxd32[x];
+	return rxd->r0;
+}
+
+static void oinit_rdes(void *cookie, int x)
+{
+	struct ave_softc *sc = cookie;
+	struct ave_rxsoft *rxs = &sc->sc_rxsoft[x];
+	struct rdes32 *rxd = &sc->sc_rxd32[x];
+	struct mbuf *m = rxs->rxs_mbuf;
+	bus_addr_t p = rxs->rxs_dmamap->dm_segs[0].ds_addr;
+	bus_size_t z = rxs->rxs_dmamap->dm_segs[0].ds_len;
+
+	m->m_data = m->m_ext.ext_buf;
+	rxd->r1 = htole32(BUS_ADDR_LO32(p));
+	rxd->r0 = R0_OWN | (z & R0_FL_MASK);
+}

Reply via email to