Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 May 2009 16:01:05 GMT
From:      Arnar Mar Sig <antab@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 163091 for review
Message-ID:  <200905301601.n4UG15lX065795@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=163091

Change 163091 by antab@antab_farm on 2009/05/30 16:00:08

	* Update in_cksum with copy from mips.
	* Update if_ate and hack it to work on at32ap700x, need to clean it up later.
	rootfs over NFS is now working

Affected files ...

.. //depot/projects/avr32/src/sys/avr32/avr32/in_cksum.c#2 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/trap.c#10 edit
.. //depot/projects/avr32/src/sys/dev/ate/if_ate.c#2 edit
.. //depot/projects/avr32/src/sys/dev/ate/if_atereg.h#1 add
.. //depot/projects/avr32/src/sys/netinet/udp_usrreq.c#7 edit

Differences ...

==== //depot/projects/avr32/src/sys/avr32/avr32/in_cksum.c#2 (text+ko) ====

@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/mips/mips/in_cksum.c,v 1.1 2008/04/13 07:27:37 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/mips/mips/in_cksum.c,v 1.3 2009/02/08 23:43:36 gonzo Exp $");
 
 #include <sys/param.h>
 #include <sys/mbuf.h>
@@ -69,7 +69,7 @@
     }
 
 static const u_int32_t in_masks[] = {
-#ifndef _MISEB
+#if _BYTE_ORDER == _LITTLE_ENDIAN
 	/*0 bytes*/ /*1 byte*/	/*2 bytes*/ /*3 bytes*/
 	0x00000000, 0x000000FF, 0x0000FFFF, 0x00FFFFFF,	/* offset 0 */
 	0x00000000, 0x0000FF00, 0x00FFFF00, 0xFFFFFF00,	/* offset 1 */
@@ -104,9 +104,9 @@
 	union q_util q_util;
 
 	if ((3 & (long) lw) == 0 && len == 20) {
-	     sum = (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3] + lw[4];
-	     REDUCE32;
-	     return sum;
+		sum = (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3] + lw[4];
+		REDUCE32;
+		return sum;
 	}
 
 	if ((offset = 3 & (long) lw) != 0) {
@@ -190,7 +190,7 @@
 	u_int64_t sum;
 	union q_util q_util;
 	union l_util l_util;
-		    
+
 	sum = (u_int64_t) a + b + c;
 	REDUCE16;
 	return (sum);
@@ -206,16 +206,16 @@
 	union q_util q_util;
 	union l_util l_util;
 
-        len -= skip;
-        for (; skip && m; m = m->m_next) {
-                if (m->m_len > skip) {
-                        mlen = m->m_len - skip;
+	len -= skip;
+	for (; skip && m; m = m->m_next) {
+		if (m->m_len > skip) {
+			mlen = m->m_len - skip;
 			addr = mtod(m, caddr_t) + skip;
-                        goto skip_start;
-                } else {
-                        skip -= m->m_len;
-                }
-        }
+			goto skip_start;
+		} else {
+			skip -= m->m_len;
+		}
+	}
 
 	for (; m && len; m = m->m_next) {
 		if (m->m_len == 0)
@@ -227,9 +227,9 @@
 			mlen = len;
 
 		if ((clen ^ (int) addr) & 1)
-		    sum += in_cksumdata(addr, mlen) << 8;
+			sum += in_cksumdata(addr, mlen) << 8;
 		else
-		    sum += in_cksumdata(addr, mlen);
+			sum += in_cksumdata(addr, mlen);
 
 		clen += mlen;
 		len -= mlen;
@@ -240,9 +240,9 @@
 
 u_int in_cksum_hdr(const struct ip *ip)
 {
-    u_int64_t sum = in_cksumdata(ip, sizeof(struct ip));
-    union q_util q_util;
-    union l_util l_util;
-    REDUCE16;
-    return (~sum & 0xffff);
+	u_int64_t sum = in_cksumdata(ip, sizeof(struct ip));
+	union q_util q_util;
+	union l_util l_util;
+	REDUCE16;
+	return (~sum & 0xffff);
 }

==== //depot/projects/avr32/src/sys/avr32/avr32/trap.c#10 (text+ko) ====

@@ -545,6 +545,8 @@
 	    , frame->regs.sr);
 
 	switch (type) {
+	case T_DATA_READ_ALIGNMENT:
+	case T_DATA_WRITE_ALIGNMENT:
 	case T_TLB_MISS_EXECUTE:
 	case T_TLB_MISS_READ:
 	case T_TLB_MISS_WRITE:

==== //depot/projects/avr32/src/sys/dev/ate/if_ate.c#2 (text) ====

@@ -23,18 +23,14 @@
  * SUCH DAMAGE.
  */
 
-/* TODO: (in no order)
+/* TODO
  *
- * 8) Need to sync busdma goo in atestop
- * 9) atestop should maybe free the mbufs?
- *
- * 1) detach
- * 2) Free dma setup
- * 3) Turn on the clock in pmc?  Turn off?
+ * 1) Turn on the clock in pmc?  Turn off?
+ * 2) GPIO initializtion in board setup code.
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/arm/at91/if_ate.c,v 1.30 2008/11/25 00:14:49 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/arm/at91/if_ate.c,v 1.37 2009/05/13 21:01:10 stas Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -69,86 +65,116 @@
 
 #include <dev/mii/mii.h>
 #include <dev/mii/miivar.h>
-#include <arm/at91/if_atereg.h>
+#include "if_atereg.h"
 
 #include "miibus_if.h"
 
-#define ATE_MAX_TX_BUFFERS 2		/* We have ping-pong tx buffers */
-#define ATE_MAX_RX_BUFFERS 64
+
+/*
+ * Driver-specific flags.
+ */
+#define	ATE_FLAG_DETACHING	0x01
+#define	ATE_FLAG_MULTICAST	0x02
 
 struct ate_softc
 {
-	struct ifnet *ifp;		/* ifnet pointer */
-	struct mtx sc_mtx;		/* basically a perimeter lock */
-	device_t dev;			/* Myself */
-	device_t miibus;		/* My child miibus */
-	void *intrhand;			/* Interrupt handle */
-	struct resource *irq_res;	/* IRQ resource */
+	struct ifnet	*ifp;		/* ifnet pointer */
+	struct mtx	sc_mtx;		/* Basically a perimeter lock */
+	device_t	dev;		/* Myself */
+	device_t	miibus;		/* My child miibus */
+	struct resource	*irq_res;	/* IRQ resource */
 	struct resource	*mem_res;	/* Memory resource */
-	struct callout tick_ch;		/* Tick callout */
-	bus_dma_tag_t mtag;		/* bus dma tag for mbufs */
-	bus_dmamap_t tx_map[ATE_MAX_TX_BUFFERS];
-	struct mbuf *sent_mbuf[ATE_MAX_TX_BUFFERS]; /* Sent mbufs */
-	bus_dma_tag_t rxtag;
-	bus_dmamap_t rx_map[ATE_MAX_RX_BUFFERS];
-	void *rx_buf[ATE_MAX_RX_BUFFERS]; /* RX buffer space */
-	int rx_buf_ptr;
-	bus_dma_tag_t rx_desc_tag;
-	bus_dmamap_t rx_desc_map;
-	int txcur;			/* current tx map pointer */
-	bus_addr_t rx_desc_phys;
-	eth_rx_desc_t *rx_descs;
-	int use_rmii;
-	struct	ifmib_iso_8802_3 mibdata; /* stuff for network mgmt */
+	struct callout	tick_ch;	/* Tick callout */
+	struct ifmib_iso_8802_3 mibdata; /* Stuff for network mgmt */
+
+#ifdef ATE_EMACB
+	bus_dma_tag_t	tx_desc_tag;
+	bus_dmamap_t	tx_desc_map;
+	eth_tx_desc_t	*tx_descs;
+	bus_addr_t	tx_desc_phys;
+#endif
+	struct mbuf	*sent_mbuf[ATE_MAX_TX_BUFFERS]; /* Sent mbufs */
+	bus_dma_tag_t	mtag;		/* bus dma tag for mbufs */
+	bus_dmamap_t	tx_map[ATE_MAX_TX_BUFFERS];
+	int		txcur;		/* Current TX map pointer */
+	int		tx_clean_ptr;	/* Last TX map entry we cleaned */
+
+	bus_dma_tag_t	rxtag;
+	bus_dma_tag_t	rx_desc_tag;
+	bus_dmamap_t	rx_desc_map;
+	bus_dmamap_t	rx_map[ATE_MAX_RX_BUFFERS];
+	bus_addr_t	rx_desc_phys;
+	eth_rx_desc_t	*rx_descs;
+	void		*rx_buf[ATE_MAX_RX_BUFFERS]; /* RX buffer space */
+	int		rx_buf_ptr;
+
+	void		*intrhand;	/* Interrupt handle */
+	int		flags;
+	int		if_flags;
+	int		use_rmii;
 };
 
 static inline uint32_t
 RD4(struct ate_softc *sc, bus_size_t off)
 {
-	return bus_read_4(sc->mem_res, off);
+
+	return (bus_read_4(sc->mem_res, off));
 }
 
 static inline void
 WR4(struct ate_softc *sc, bus_size_t off, uint32_t val)
 {
+
 	bus_write_4(sc->mem_res, off, val);
 }
 
-#define ATE_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+static inline void
+BARRIER(struct ate_softc *sc, bus_size_t off, bus_size_t len, int flags)
+{
+
+	bus_barrier(sc->mem_res, off, len, flags);
+}
+
+#define	ATE_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
 #define	ATE_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
-#define ATE_LOCK_INIT(_sc) \
-	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \
+#define	ATE_LOCK_INIT(_sc)					\
+	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev),	\
 	    MTX_NETWORK_LOCK, MTX_DEF)
-#define ATE_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
-#define ATE_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
-#define ATE_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+#define	ATE_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
+#define	ATE_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
+#define	ATE_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
 
 static devclass_t ate_devclass;
 
-/* ifnet entry points */
+/*
+ * ifnet entry points.
+ */
+static void	ateinit_locked(void *);
+static void	atestart_locked(struct ifnet *);
 
-static void ateinit_locked(void *);
-static void atestart_locked(struct ifnet *);
+static void	ateinit(void *);
+static void	atestart(struct ifnet *);
+static void	atestop(struct ate_softc *);
+static int	ateioctl(struct ifnet * ifp, u_long, caddr_t);
 
-static void ateinit(void *);
-static void atestart(struct ifnet *);
-static void atestop(struct ate_softc *);
-static int ateioctl(struct ifnet * ifp, u_long, caddr_t);
+/*
+ * Bus entry points.
+ */
+static int	ate_probe(device_t dev);
+static int	ate_attach(device_t dev);
+static int	ate_detach(device_t dev);
+static void	ate_intr(void *);
 
-/* bus entry points */
-
-static int ate_probe(device_t dev);
-static int ate_attach(device_t dev);
-static int ate_detach(device_t dev);
-static void ate_intr(void *);
-
-/* helper routines */
-static int ate_activate(device_t dev);
-static void ate_deactivate(device_t dev);
-static int ate_ifmedia_upd(struct ifnet *ifp);
-static void ate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr);
-static int ate_get_mac(struct ate_softc *sc, u_char *eaddr);
-static void ate_set_mac(struct ate_softc *sc, u_char *eaddr);
+/*
+ * Helper routines.
+ */
+static int	ate_activate(device_t dev);
+static void	ate_deactivate(struct ate_softc *sc);
+static int	ate_ifmedia_upd(struct ifnet *ifp);
+static void	ate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr);
+static int	ate_get_mac(struct ate_softc *sc, u_char *eaddr);
+static void	ate_set_mac(struct ate_softc *sc, u_char *eaddr);
+static void	ate_rxfilter(struct ate_softc *sc);
 
 /*
  * The AT91 family of products has the ethernet called EMAC.  However,
@@ -159,6 +185,7 @@
 static int
 ate_probe(device_t dev)
 {
+
 	device_set_desc(dev, "EMAC");
 	return (0);
 }
@@ -166,20 +193,50 @@
 static int
 ate_attach(device_t dev)
 {
-	struct ate_softc *sc = device_get_softc(dev);
+	struct ate_softc *sc;
 	struct ifnet *ifp = NULL;
 	struct sysctl_ctx_list *sctx;
 	struct sysctl_oid *soid;
-	int err;
 	u_char eaddr[ETHER_ADDR_LEN];
 	uint32_t rnd;
+	int rid, err;
 
+	sc = device_get_softc(dev);
 	sc->dev = dev;
+	ATE_LOCK_INIT(sc);
+	
+	/*
+	 * Allocate resources.
+	 */
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "could not allocate memory resources.\n");
+		err = ENOMEM;
+		goto out;
+	}
+	rid = 0;
+	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (sc->irq_res == NULL) {
+		device_printf(dev, "could not allocate interrupt resources.\n");
+		err = ENOMEM;
+		goto out;
+	}
+
 	err = ate_activate(dev);
 	if (err)
 		goto out;
 
+	/*
+	 * RMII bit is stored in USRIO and inverted in EMACB
+	 */
+#ifdef ATE_EMACB
+	sc->use_rmii = (RD4(sc, ETH_CFG) & ETH_USRIO_RMII) != ETH_USRIO_RMII;
+#else
 	sc->use_rmii = (RD4(sc, ETH_CFG) & ETH_CFG_RMII) == ETH_CFG_RMII;
+#endif
 
 	/* Sysctls */
 	sctx = device_get_sysctl_ctx(dev);
@@ -187,9 +244,10 @@
 	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "rmii",
 	    CTLFLAG_RD, &sc->use_rmii, 0, "rmii in use");
 
-	/* calling atestop before ifp is set is OK */
+	/* Calling atestop before ifp is set is OK. */
+	ATE_LOCK(sc);
 	atestop(sc);
-	ATE_LOCK_INIT(sc);
+	ATE_UNLOCK(sc);
 	callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0);
 
 	if ((err = ate_get_mac(sc, eaddr)) != 0) {
@@ -213,7 +271,6 @@
 		eaddr[4] = (rnd >> 8) & 0xff;
 		eaddr[5] = rnd & 0xff;
 	}
-	ate_set_mac(sc, eaddr);
 
 	sc->ifp = ifp = if_alloc(IFT_ETHER);
 	if (mii_phy_probe(dev, &sc->miibus, ate_ifmedia_upd, ate_ifmedia_sts)) {
@@ -226,7 +283,7 @@
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_capabilities |= IFCAP_VLAN_MTU;
-	ifp->if_capenable |= IFCAP_VLAN_MTU; /* the hw bits already set */
+	ifp->if_capenable |= IFCAP_VLAN_MTU;	/* The hw bits already set. */
 	ifp->if_start = atestart;
 	ifp->if_ioctl = ateioctl;
 	ifp->if_init = ateinit;
@@ -238,34 +295,74 @@
 	ifp->if_linkmib = &sc->mibdata;
 	ifp->if_linkmiblen = sizeof(sc->mibdata);
 	sc->mibdata.dot3Compliance = DOT3COMPLIANCE_COLLS;
+	sc->if_flags = ifp->if_flags;
 
 	ether_ifattach(ifp, eaddr);
 
 	/*
-	 * Activate the interrupt
+	 * Activate the interrupt.
 	 */
 	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
 	    NULL, ate_intr, sc, &sc->intrhand);
 	if (err) {
+		device_printf(dev, "could not establish interrupt handler.\n");
 		ether_ifdetach(ifp);
-		ATE_LOCK_DESTROY(sc);
+		goto out;
 	}
-out:;
+
+out:
 	if (err)
-		ate_deactivate(dev);
-	if (err && ifp)
-		if_free(ifp);
+		ate_detach(dev);
 	return (err);
 }
 
 static int
 ate_detach(device_t dev)
 {
-	return EBUSY;	/* XXX TODO(1) */
+	struct ate_softc *sc;
+	struct ifnet *ifp;
+
+	sc = device_get_softc(dev);
+	KASSERT(sc != NULL, ("[ate: %d]: sc is NULL", __LINE__));
+	ifp = sc->ifp;
+	if (device_is_attached(dev)) {
+		ATE_LOCK(sc);
+			sc->flags |= ATE_FLAG_DETACHING;
+			atestop(sc);
+		ATE_UNLOCK(sc);
+		callout_drain(&sc->tick_ch);
+		ether_ifdetach(ifp);
+	}
+	if (sc->miibus != NULL) {
+		device_delete_child(dev, sc->miibus);
+		sc->miibus = NULL;
+	}
+	bus_generic_detach(sc->dev);
+	ate_deactivate(sc);
+	if (sc->intrhand != NULL) {
+		bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
+		sc->intrhand = NULL;
+	}
+	if (ifp != NULL) {
+		if_free(ifp);
+		sc->ifp = NULL;
+	}
+	if (sc->mem_res != NULL) {
+		bus_release_resource(dev, SYS_RES_IOPORT,
+		    rman_get_rid(sc->mem_res), sc->mem_res);
+		sc->mem_res = NULL;
+	}
+	if (sc->irq_res != NULL) {
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    rman_get_rid(sc->irq_res), sc->irq_res);
+		sc->irq_res = NULL;
+	}
+	ATE_LOCK_DESTROY(sc);
+	return (0);
 }
 
 static void
-ate_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+ate_rx_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
 {
 	struct ate_softc *sc;
 
@@ -275,7 +372,38 @@
 	sc->rx_desc_phys = segs[0].ds_addr;
 }
 
+#ifdef ATE_EMACB
+static void
+ate_tx_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+	struct ate_softc *sc;
+
+	if (error != 0)
+		return;
+	sc = (struct ate_softc *)arg;
+	sc->tx_desc_phys = segs[0].ds_addr;
+}
+
 static void
+ate_load_tx_buf(void *arg, bus_dma_segment_t *segs, int nsegs, bus_size_t mapsize, int error)
+{
+	struct ate_softc *sc;
+
+	if (error != 0)
+		return;
+	sc = (struct ate_softc *)arg;
+
+	KASSERT(nsegs == 1, ("too many segments: %d\n", nsegs));
+	KASSERT(mapsize < ATE_MAX_TX_BUFFER_LENGTH, ("Transmit buffer to long"));
+
+	bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map, BUS_DMASYNC_PREWRITE);
+	sc->tx_descs[sc->txcur].addr = segs[0].ds_addr;
+	sc->tx_descs[sc->txcur].status = mapsize | ETH_TX_DESC_LAST;
+	bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map, BUS_DMASYNC_POSTWRITE);
+}
+#endif /* ATE_EMACB */
+
+static void
 ate_load_rx_buf(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
 {
 	struct ate_softc *sc;
@@ -307,26 +435,39 @@
  * of different MAC chips use this method (or the reverse the bits)
  * method.
  */
-static void
+static int
 ate_setmcast(struct ate_softc *sc)
 {
 	uint32_t index;
 	uint32_t mcaf[2];
 	u_char *af = (u_char *) mcaf;
 	struct ifmultiaddr *ifma;
+	struct ifnet *ifp;
+
+	ifp = sc->ifp;
+
+	if ((ifp->if_flags & IFF_PROMISC) != 0)
+		return (0);
+	if ((ifp->if_flags & IFF_ALLMULTI) != 0) {
+		WR4(sc, ETH_HSL, 0xffffffff);
+		WR4(sc, ETH_HSH, 0xffffffff);
+		return (1);
+	}
 
+	/*
+	 * Compute the multicast hash.
+	 */
 	mcaf[0] = 0;
 	mcaf[1] = 0;
-
-	IF_ADDR_LOCK(sc->ifp);
-	TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) {
+	IF_ADDR_LOCK(ifp);
+	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
 		if (ifma->ifma_addr->sa_family != AF_LINK)
 			continue;
 		index = ether_crc32_be(LLADDR((struct sockaddr_dl *)
 		    ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
 		af[index >> 3] |= 1 << (index & 7);
 	}
-	IF_ADDR_UNLOCK(sc->ifp);
+	IF_ADDR_UNLOCK(ifp);
 
 	/*
 	 * Write the hash to the hash register.  This card can also
@@ -337,44 +478,68 @@
 	 */
 	WR4(sc, ETH_HSL, mcaf[0]);
 	WR4(sc, ETH_HSH, mcaf[1]);
+	return (mcaf[0] || mcaf[1]);
 }
 
 static int
 ate_activate(device_t dev)
 {
 	struct ate_softc *sc;
-	int rid, err, i;
+	int err, i;
 
 	sc = device_get_softc(dev);
-	rid = 0;
-	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
-	    RF_ACTIVE);
-	if (sc->mem_res == NULL)
-		goto errout;
-	rid = 0;
-	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
-	    RF_ACTIVE);
-	if (sc->irq_res == NULL)
-		goto errout;
 
 	/*
-	 * Allocate DMA tags and maps
+	 * Allocate DMA tags and maps.
 	 */
 	err = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
 	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
 	    1, MCLBYTES, 0, busdma_lock_mutex, &sc->sc_mtx, &sc->mtag);
 	if (err != 0)
 		goto errout;
+
 	for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
 		err = bus_dmamap_create(sc->mtag, 0, &sc->tx_map[i]);
 		if (err != 0)
 			goto errout;
 	}
-	 /*
-	  * Allocate our Rx buffers.  This chip has a rx structure that's filled
-	  * in
-	  */
-	
+
+#ifdef ATE_EMACB
+	/*
+	 * DMA tag and map for the TX descriptors.
+	 */
+	err = bus_dma_tag_create(bus_get_dma_tag(dev), sizeof(eth_tx_desc_t),
+	    0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t), 1,
+	    ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t), 0, busdma_lock_mutex,
+	    &sc->sc_mtx, &sc->tx_desc_tag);
+	if (err != 0)
+		goto errout;
+	if (bus_dmamem_alloc(sc->tx_desc_tag, (void **)&sc->tx_descs,
+	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->tx_desc_map) != 0)
+		goto errout;
+	if (bus_dmamap_load(sc->tx_desc_tag, sc->tx_desc_map,
+	    sc->tx_descs, ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t),
+	    ate_tx_getaddr, sc, 0) != 0)
+		goto errout;
+
+	/*
+	 * Init transmit buffer queue descriptors
+	 */
+	for (i = 0; i < ATE_MAX_TX_BUFFERS - 1; i++) {
+		sc->tx_descs[i].addr = 0;
+		sc->tx_descs[i].status = ETH_TX_DESC_CPU_OWNER;
+	}
+	sc->tx_descs[ATE_MAX_TX_BUFFERS - 1].addr = 0;
+	sc->tx_descs[ATE_MAX_TX_BUFFERS - 1].status = ETH_TX_DESC_CPU_OWNER |
+		ETH_TX_DESC_WRAP;
+
+	/* Flush the memory for the EMAC tx descriptor. */
+	bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map, BUS_DMASYNC_PREWRITE);
+	/* Write the descriptor queue address. */
+	WR4(sc, ETH_TBQP, sc->tx_desc_phys);
+#endif
+
 	/*
 	 * Allocate DMA tags and maps for RX.
 	 */
@@ -384,7 +549,9 @@
 	if (err != 0)
 		goto errout;
 
-	/* Dma TAG and MAP for the rx descriptors. */
+	/*
+	 * DMA tag and map for the RX descriptors.
+	 */
 	err = bus_dma_tag_create(bus_get_dma_tag(dev), sizeof(eth_rx_desc_t),
 	    0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
 	    ATE_MAX_RX_BUFFERS * sizeof(eth_rx_desc_t), 1,
@@ -397,83 +564,114 @@
 		goto errout;
 	if (bus_dmamap_load(sc->rx_desc_tag, sc->rx_desc_map,
 	    sc->rx_descs, ATE_MAX_RX_BUFFERS * sizeof(eth_rx_desc_t),
-	    ate_getaddr, sc, 0) != 0)
+	    ate_rx_getaddr, sc, 0) != 0)
 		goto errout;
-	/* XXX TODO(5) Put this in ateinit_locked? */
+
+	/*
+	 * Allocate our RX buffers.  This chip has a RX structure that's filled
+	 * in.
+	 */
 	for (i = 0; i < ATE_MAX_RX_BUFFERS; i++) {
 		sc->rx_buf_ptr = i;
 		if (bus_dmamem_alloc(sc->rxtag, (void **)&sc->rx_buf[i],
 		      BUS_DMA_NOWAIT, &sc->rx_map[i]) != 0)
 			goto errout;
 		if (bus_dmamap_load(sc->rxtag, sc->rx_map[i], sc->rx_buf[i],
-		    MCLBYTES, ate_load_rx_buf, sc, 0) != 0)
+		    ATE_MAX_RX_BUFFER_LENGTH, ate_load_rx_buf, sc, 0) != 0)
 			goto errout;
 	}
 	sc->rx_buf_ptr = 0;
-	/* Flush the memory for the EMAC rx descriptor */
+	/* Flush the memory for the EMAC rx descriptor. */
 	bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE);
 	/* Write the descriptor queue address. */
 	WR4(sc, ETH_RBQP, sc->rx_desc_phys);
 	return (0);
+
 errout:
-	ate_deactivate(dev);
 	return (ENOMEM);
 }
 
 static void
-ate_deactivate(device_t dev)
+ate_deactivate(struct ate_softc *sc)
 {
-	struct ate_softc *sc;
+	int i;
 
-	sc = device_get_softc(dev);
-	/* XXX TODO(2) teardown busdma junk, below from fxp -- customize */
-#if 0
-	if (sc->fxp_mtag) {
-		for (i = 0; i < FXP_NRFABUFS; i++) {
-			rxp = &sc->fxp_desc.rx_list[i];
-			if (rxp->rx_mbuf != NULL) {
-				bus_dmamap_sync(sc->fxp_mtag, rxp->rx_map,
-				    BUS_DMASYNC_POSTREAD);
-				bus_dmamap_unload(sc->fxp_mtag, rxp->rx_map);
-				m_freem(rxp->rx_mbuf);
+	KASSERT(sc != NULL, ("[ate, %d]: sc is NULL!", __LINE__));
+#ifdef ATE_EMACB
+	if (sc->tx_desc_tag != NULL) {
+		if (sc->tx_descs != NULL) {
+			if (sc->tx_desc_phys != 0) {
+				bus_dmamap_sync(sc->tx_desc_tag,
+				    sc->tx_desc_map, BUS_DMASYNC_POSTREAD);
+				bus_dmamap_unload(sc->tx_desc_tag,
+				    sc->tx_desc_map);
+				sc->tx_desc_phys = 0;
 			}
-			bus_dmamap_destroy(sc->fxp_mtag, rxp->rx_map);
 		}
-		bus_dmamap_destroy(sc->fxp_mtag, sc->spare_map);
-		for (i = 0; i < FXP_NTXCB; i++) {
-			txp = &sc->fxp_desc.tx_list[i];
-			if (txp->tx_mbuf != NULL) {
-				bus_dmamap_sync(sc->fxp_mtag, txp->tx_map,
+	}
+#endif
+	if (sc->mtag != NULL) {
+		for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
+			if (sc->sent_mbuf[i] != NULL) {
+				bus_dmamap_sync(sc->mtag, sc->tx_map[i],
 				    BUS_DMASYNC_POSTWRITE);
-				bus_dmamap_unload(sc->fxp_mtag, txp->tx_map);
-				m_freem(txp->tx_mbuf);
+				bus_dmamap_unload(sc->mtag, sc->tx_map[i]);
+				m_freem(sc->sent_mbuf[i]);
 			}
-			bus_dmamap_destroy(sc->fxp_mtag, txp->tx_map);
+			bus_dmamap_destroy(sc->mtag, sc->tx_map[i]);
+			sc->sent_mbuf[i] = NULL;
+			sc->tx_map[i] = NULL;
 		}
-		bus_dma_tag_destroy(sc->fxp_mtag);
+		bus_dma_tag_destroy(sc->mtag);
+	}
+#ifdef ATE_EMACB
+	if (sc->tx_desc_tag != NULL) {
+		if (sc->tx_descs != NULL)
+			bus_dmamem_free(sc->tx_desc_tag, sc->tx_descs,
+			    sc->tx_desc_map);
+		bus_dma_tag_destroy(sc->tx_desc_tag);
+		sc->tx_descs = NULL;
+		sc->tx_desc_tag = NULL;
 	}
-	if (sc->fxp_stag)
-		bus_dma_tag_destroy(sc->fxp_stag);
-	if (sc->cbl_tag)
-		bus_dma_tag_destroy(sc->cbl_tag);
-	if (sc->mcs_tag)
-		bus_dma_tag_destroy(sc->mcs_tag);
 #endif
-	if (sc->intrhand)
-		bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
-	sc->intrhand = 0;
-	bus_generic_detach(sc->dev);
-	if (sc->miibus)
-		device_delete_child(sc->dev, sc->miibus);
-	if (sc->mem_res)
-		bus_release_resource(dev, SYS_RES_IOPORT,
-		    rman_get_rid(sc->mem_res), sc->mem_res);
-	sc->mem_res = 0;
-	if (sc->irq_res)
-		bus_release_resource(dev, SYS_RES_IRQ,
-		    rman_get_rid(sc->irq_res), sc->irq_res);
-	sc->irq_res = 0;
-	return;
+	if (sc->rx_desc_tag != NULL) {
+		if (sc->rx_descs != NULL) {
+			if (sc->rx_desc_phys != 0) {
+				bus_dmamap_sync(sc->rx_desc_tag,
+				    sc->rx_desc_map, BUS_DMASYNC_POSTREAD);
+				bus_dmamap_unload(sc->rx_desc_tag,
+				    sc->rx_desc_map);
+				sc->rx_desc_phys = 0;
+			}
+		}
+	}
+	if (sc->rxtag != NULL) {
+		for (i = 0; i < ATE_MAX_RX_BUFFERS; i++) {
+			if (sc->rx_buf[i] != NULL) {
+				if (sc->rx_descs[i].addr != 0) {
+					bus_dmamap_sync(sc->rxtag,
+					    sc->rx_map[i],
+					    BUS_DMASYNC_POSTREAD);
+					bus_dmamap_unload(sc->rxtag,
+					    sc->rx_map[i]);
+					sc->rx_descs[i].addr = 0;
+				}
+				bus_dmamem_free(sc->rxtag, sc->rx_buf[i],
+				    sc->rx_map[i]);
+				sc->rx_buf[i] = NULL;
+				sc->rx_map[i] = NULL;
+			}
+		}
+		bus_dma_tag_destroy(sc->rxtag);
+	}
+	if (sc->rx_desc_tag != NULL) {
+		if (sc->rx_descs != NULL)
+			bus_dmamem_free(sc->rx_desc_tag, sc->rx_descs,
+			    sc->rx_desc_map);
+		bus_dma_tag_destroy(sc->rx_desc_tag);
+		sc->rx_descs = NULL;
+		sc->rx_desc_tag = NULL;
+	}
 }
 
 /*
@@ -512,18 +710,19 @@
 static void
 ate_stat_update(struct ate_softc *sc, int active)
 {
+	uint32_t reg;
+
 	/*
 	 * The speed and full/half-duplex state needs to be reflected
 	 * in the ETH_CFG register.
 	 */
-	if (IFM_SUBTYPE(active) == IFM_10_T)
-		WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_SPD);
-	else
-		WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_SPD);
+	reg = RD4(sc, ETH_CFG);
+	reg &= ~(ETH_CFG_SPD | ETH_CFG_FD);
+	if (IFM_SUBTYPE(active) != IFM_10_T)
+		reg |= ETH_CFG_SPD;
 	if (active & IFM_FDX)
-		WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_FD);
-	else
-		WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_FD);
+		reg |= ETH_CFG_FD;
+	WR4(sc, ETH_CFG, reg);
 }
 
 static void
@@ -580,8 +779,9 @@
 	sc->mibdata.dot3StatsCarrierSenseErrors += RD4(sc, ETH_CSE);
 	sc->mibdata.dot3StatsFrameTooLongs += RD4(sc, ETH_ELR);
 	sc->mibdata.dot3StatsInternalMacReceiveErrors += RD4(sc, ETH_DRFC);
+
 	/*
-	 * not sure where to lump these, so count them against the errors
+	 * Not sure where to lump these, so count them against the errors
 	 * for the interface.
 	 */
 	sc->ifp->if_oerrors += RD4(sc, ETH_TUE);
@@ -597,6 +797,7 @@
 static void
 ate_set_mac(struct ate_softc *sc, u_char *eaddr)
 {
+
 	WR4(sc, ETH_SA1L, (eaddr[3] << 24) | (eaddr[2] << 16) |
 	    (eaddr[1] << 8) | eaddr[0]);
 	WR4(sc, ETH_SA1H, (eaddr[5] << 8) | (eaddr[4]));
@@ -629,31 +830,99 @@
 	}
 	return (ENXIO);
 }
+#ifdef ATE_EMACB
+/*
+ * Not sure if this is the best way to create the rx mbuf, but it seems to work
+ */
+static struct mbuf *
+ate_rx_frame(struct ate_softc *sc, int start, int end, int len)
+{
+	int at, i, clen;
+	struct mbuf *m;
 
+	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+	if (m == NULL) {
+		device_printf(sc->dev, "Unable to alloc mbuf\n");
+		return (NULL);
+	}
+	m->m_pkthdr.rcvif = sc->ifp;
+
+	at = 0;
+	for (i = start; len > 0; i = (i + 1) % ATE_MAX_RX_BUFFERS) {
+		clen = (len > ATE_MAX_RX_BUFFER_LENGTH) ? ATE_MAX_RX_BUFFER_LENGTH : len;
+		len -= ATE_MAX_RX_BUFFER_LENGTH;
+
+		bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
+		    BUS_DMASYNC_POSTREAD);
+		m_copyback(m, at, clen, sc->rx_buf[i]);
+
+		bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
+		    BUS_DMASYNC_PREWRITE);
+		sc->rx_descs[i].addr &= ~ETH_CPU_OWNER;
+		bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
+		    BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
+		    BUS_DMASYNC_PREREAD);
+
+		at += clen;
+	}
+	sc->rx_buf_ptr = i;
+	return (m);
+}
+#endif
+
 static void
 ate_intr(void *xsc)
 {
 	struct ate_softc *sc = xsc;
 	struct ifnet *ifp = sc->ifp;
-	int status;
+	struct mbuf *mb;
+	void *bp;
+	uint32_t status, reg, rx_stat, frame_len;
+	int frame_start;
 	int i;
-	void *bp;
-	struct mbuf *mb;
-	uint32_t rx_stat;
+
 
 	status = RD4(sc, ETH_ISR);
 	if (status == 0)
 		return;
+
 	if (status & ETH_ISR_RCOM) {
 		bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
 		    BUS_DMASYNC_POSTREAD);
+#ifdef ATE_EMACB
+		i = sc->rx_buf_ptr;
+		frame_start = -1;
+		while (sc->rx_descs[i].addr & ETH_CPU_OWNER && i != (sc->rx_buf_ptr - 1)) {
+			rx_stat = sc->rx_descs[i].status;
+			if ((rx_stat & ETH_FRAME_START)) {
+				KASSERT(frame_start == -1, ("New frame with out finishing last"));
+				frame_start = i;
+			}
+			if ((rx_stat & ETH_FRAME_END)) {
+				frame_len = rx_stat & ETH_LEN_MASK;
+				KASSERT(frame_start != -1, ("End of frame without begining"));
+				KASSERT(frame_len != 0, ("Zero length frame"));
+
+				WR4(sc, ETH_RSR, RD4(sc, ETH_RSR));
+				mb = ate_rx_frame(sc, frame_start, i, frame_len);
+				if (mb != NULL) {
+					frame_start = -1;
+					ifp->if_ipackets++;
+					(*ifp->if_input)(ifp, mb);
+				}
+			}
+			i = (i + 1) % ATE_MAX_RX_BUFFERS;
+		}
+#else /* ATE_EMACB */
 		while (sc->rx_descs[sc->rx_buf_ptr].addr & ETH_CPU_OWNER) {
 			i = sc->rx_buf_ptr;
 			sc->rx_buf_ptr = (i + 1) % ATE_MAX_RX_BUFFERS;
 			bp = sc->rx_buf[i];
 			rx_stat = sc->rx_descs[i].status;
 			if ((rx_stat & ETH_LEN_MASK) == 0) {
-				printf("ignoring bogus 0 len packet\n");
+				if (bootverbose)
+					device_printf(sc->dev, "ignoring bogus zero-length packet\n");
 				bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
 				    BUS_DMASYNC_PREWRITE);
 				sc->rx_descs[i].addr &= ~ETH_CPU_OWNER;
@@ -681,19 +950,47 @@
 			    BUS_DMASYNC_POSTWRITE);
 			bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
 			    BUS_DMASYNC_PREREAD);
+
 			if (mb != NULL) {
 				ifp->if_ipackets++;
 				(*ifp->if_input)(ifp, mb);
 			}
-			
 		}
+#endif /* !ATE_EMACB */

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905301601.n4UG15lX065795>