if_ate.c revision 238895
1155324Simp/*-
2155324Simp * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
3213496Scognet * Copyright (c) 2009 Greg Ansley.  All rights reserved.
4155324Simp *
5155324Simp * Redistribution and use in source and binary forms, with or without
6155324Simp * modification, are permitted provided that the following conditions
7155324Simp * are met:
8155324Simp * 1. Redistributions of source code must retain the above copyright
9155324Simp *    notice, this list of conditions and the following disclaimer.
10155324Simp * 2. Redistributions in binary form must reproduce the above copyright
11155324Simp *    notice, this list of conditions and the following disclaimer in the
12155324Simp *    documentation and/or other materials provided with the distribution.
13155324Simp *
14185267Simp * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15185267Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16185267Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17185267Simp * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
18185267Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19185267Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20185267Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21185267Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22185267Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23185267Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24185267Simp * SUCH DAMAGE.
25155324Simp */
26155324Simp
27192018Sstas/* TODO
28155324Simp *
29192018Sstas * 1) Turn on the clock in pmc?  Turn off?
30192018Sstas * 2) GPIO initializtion in board setup code.
31155324Simp */
32155324Simp
33155324Simp#include <sys/cdefs.h>
34155324Simp__FBSDID("$FreeBSD: head/sys/arm/at91/if_ate.c 238895 2012-07-30 06:00:31Z imp $");
35155324Simp
36155324Simp#include <sys/param.h>
37155324Simp#include <sys/systm.h>
38155324Simp#include <sys/bus.h>
39155324Simp#include <sys/kernel.h>
40213496Scognet#include <sys/malloc.h>
41155324Simp#include <sys/mbuf.h>
42155324Simp#include <sys/module.h>
43155324Simp#include <sys/rman.h>
44155324Simp#include <sys/socket.h>
45155324Simp#include <sys/sockio.h>
46163522Simp#include <sys/sysctl.h>
47213496Scognet
48155324Simp#include <machine/bus.h>
49155324Simp
50155324Simp#include <net/ethernet.h>
51155324Simp#include <net/if.h>
52155324Simp#include <net/if_arp.h>
53155324Simp#include <net/if_dl.h>
54155324Simp#include <net/if_media.h>
55155324Simp#include <net/if_mib.h>
56155324Simp#include <net/if_types.h>
57155324Simp
58155324Simp#ifdef INET
59155324Simp#include <netinet/in.h>
60155324Simp#include <netinet/in_systm.h>
61155324Simp#include <netinet/in_var.h>
62155324Simp#include <netinet/ip.h>
63155324Simp#endif
64155324Simp
65155324Simp#include <net/bpf.h>
66155324Simp#include <net/bpfdesc.h>
67155324Simp
68155324Simp#include <dev/mii/mii.h>
69155324Simp#include <dev/mii/miivar.h>
70213496Scognet
71213496Scognet#include "opt_at91.h"
72213496Scognet#include <arm/at91/at91reg.h>
73213496Scognet#include <arm/at91/at91var.h>
74155324Simp#include <arm/at91/if_atereg.h>
75155324Simp
76155324Simp#include "miibus_if.h"
77155324Simp
78191959Sstas/*
79191959Sstas * Driver-specific flags.
80191959Sstas */
81213496Scognet#define	ATE_FLAG_DETACHING	0x01
82213496Scognet#define	ATE_FLAG_MULTICAST	0x02
83191959Sstas
84213496Scognet/*
85213496Scognet * Old EMAC assumes whole packet fits in one buffer;
86213496Scognet * new EBACB assumes all receive buffers are 128 bytes
87213496Scognet */
88213496Scognet#define	RX_BUF_SIZE(sc)	(sc->is_emacb ? 128 : MCLBYTES)
89213496Scognet
90213496Scognet/*
91213496Scognet * EMACB has an 11 bit counter for Rx/Tx Descriptors
92213496Scognet * for max total of 1024 decriptors each.
93213496Scognet */
94213496Scognet#define	ATE_MAX_RX_DESCR	1024
95213496Scognet#define	ATE_MAX_TX_DESCR	1024
96213496Scognet
97213496Scognet/* How many buffers to allocate */
98213496Scognet#define	ATE_MAX_TX_BUFFERS	4	/* We have ping-pong tx buffers */
99213496Scognet
100213496Scognet/* How much memory to use for rx buffers */
101213496Scognet#define	ATE_RX_MEMORY		(ATE_MAX_RX_DESCR * 128)
102213496Scognet
103213496Scognet/* Actual number of descriptors we allocate */
104213496Scognet#define	ATE_NUM_RX_DESCR	ATE_MAX_RX_DESCR
105213496Scognet#define	ATE_NUM_TX_DESCR	ATE_MAX_TX_BUFFERS
106213496Scognet
107213496Scognet#if ATE_NUM_TX_DESCR > ATE_MAX_TX_DESCR
108213496Scognet#error "Can't have more TX buffers that descriptors"
109213496Scognet#endif
110213496Scognet#if ATE_NUM_RX_DESCR > ATE_MAX_RX_DESCR
111213496Scognet#error "Can't have more RX buffers that descriptors"
112213496Scognet#endif
113213496Scognet
114213496Scognet/* Wrap indexes the same way the hardware does */
115213496Scognet#define	NEXT_RX_IDX(sc, cur)	\
116213496Scognet    ((sc->rx_descs[cur].addr & ETH_WRAP_BIT) ? 0 : (cur + 1))
117213496Scognet
118213496Scognet#define	NEXT_TX_IDX(sc, cur)	\
119213496Scognet    ((sc->tx_descs[cur].status & ETHB_TX_WRAP) ? 0 : (cur + 1))
120213496Scognet
121155324Simpstruct ate_softc
122155324Simp{
123234281Smarius	struct ifnet	*ifp;		/* ifnet pointer */
124234281Smarius	struct mtx	sc_mtx;		/* Basically a perimeter lock */
125234281Smarius	device_t	dev;		/* Myself */
126234281Smarius	device_t	miibus;		/* My child miibus */
127234281Smarius	struct resource *irq_res;	/* IRQ resource */
128234281Smarius	struct resource	*mem_res;	/* Memory resource */
129234281Smarius	struct callout  tick_ch;	/* Tick callout */
130192063Sstas	struct ifmib_iso_8802_3 mibdata; /* Stuff for network mgmt */
131234281Smarius	bus_dma_tag_t   mtag;		/* bus dma tag for mbufs */
132213496Scognet	bus_dma_tag_t   rx_tag;
133213496Scognet	bus_dma_tag_t   rx_desc_tag;
134213496Scognet	bus_dmamap_t    rx_desc_map;
135213496Scognet	bus_dmamap_t    rx_map[ATE_MAX_RX_DESCR];
136234281Smarius	bus_addr_t	rx_desc_phys;   /* PA of rx descriptors */
137234281Smarius	eth_rx_desc_t   *rx_descs;	/* VA of rx descriptors */
138234281Smarius	void		*rx_buf[ATE_NUM_RX_DESCR]; /* RX buffer space */
139234281Smarius	int		rxhead;		/* Current RX map/desc index */
140234281Smarius	uint32_t	rx_buf_size;    /* Size of Rx buffers */
141213496Scognet
142213496Scognet	bus_dma_tag_t   tx_desc_tag;
143213496Scognet	bus_dmamap_t    tx_desc_map;
144213496Scognet	bus_dmamap_t    tx_map[ATE_MAX_TX_BUFFERS];
145234281Smarius	bus_addr_t	tx_desc_phys;   /* PA of tx descriptors */
146234281Smarius	eth_tx_desc_t   *tx_descs;	/* VA of tx descriptors */
147234281Smarius	int		txhead;		/* Current TX map/desc index */
148234281Smarius	int		txtail;		/* Current TX map/desc index */
149234281Smarius	struct mbuf	*sent_mbuf[ATE_MAX_TX_BUFFERS]; /* Sent mbufs */
150234281Smarius	void		*intrhand;	/* Interrupt handle */
151234281Smarius	int		flags;
152234281Smarius	int		if_flags;
153234281Smarius	int		use_rmii;
154234281Smarius	int		is_emacb;	/* SAM9x hardware version */
155155324Simp};
156155324Simp
157155324Simpstatic inline uint32_t
158155324SimpRD4(struct ate_softc *sc, bus_size_t off)
159155324Simp{
160192063Sstas
161192063Sstas	return (bus_read_4(sc->mem_res, off));
162155324Simp}
163155324Simp
164155324Simpstatic inline void
165155324SimpWR4(struct ate_softc *sc, bus_size_t off, uint32_t val)
166155324Simp{
167192063Sstas
168155324Simp	bus_write_4(sc->mem_res, off, val);
169155324Simp}
170155324Simp
171192027Sstasstatic inline void
172192027SstasBARRIER(struct ate_softc *sc, bus_size_t off, bus_size_t len, int flags)
173192027Sstas{
174192027Sstas
175192027Sstas	bus_barrier(sc->mem_res, off, len, flags);
176192027Sstas}
177192027Sstas
178192063Sstas#define	ATE_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
179155324Simp#define	ATE_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
180192063Sstas#define	ATE_LOCK_INIT(_sc)					\
181192063Sstas	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev),	\
182155324Simp	    MTX_NETWORK_LOCK, MTX_DEF)
183192063Sstas#define	ATE_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
184192063Sstas#define	ATE_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
185192063Sstas#define	ATE_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
186155324Simp
187155324Simpstatic devclass_t ate_devclass;
188155324Simp
189192063Sstas/*
190192063Sstas * ifnet entry points.
191192063Sstas */
192192063Sstasstatic void	ateinit_locked(void *);
193192063Sstasstatic void	atestart_locked(struct ifnet *);
194155324Simp
195192063Sstasstatic void	ateinit(void *);
196192063Sstasstatic void	atestart(struct ifnet *);
197192063Sstasstatic void	atestop(struct ate_softc *);
198192063Sstasstatic int	ateioctl(struct ifnet * ifp, u_long, caddr_t);
199155324Simp
200192063Sstas/*
201192063Sstas * Bus entry points.
202192063Sstas */
203192063Sstasstatic int	ate_probe(device_t dev);
204192063Sstasstatic int	ate_attach(device_t dev);
205192063Sstasstatic int	ate_detach(device_t dev);
206192063Sstasstatic void	ate_intr(void *);
207155324Simp
208192063Sstas/*
209192063Sstas * Helper routines.
210192063Sstas */
211192063Sstasstatic int	ate_activate(device_t dev);
212192063Sstasstatic void	ate_deactivate(struct ate_softc *sc);
213192063Sstasstatic int	ate_ifmedia_upd(struct ifnet *ifp);
214192063Sstasstatic void	ate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr);
215192063Sstasstatic int	ate_get_mac(struct ate_softc *sc, u_char *eaddr);
216192063Sstasstatic void	ate_set_mac(struct ate_softc *sc, u_char *eaddr);
217191959Sstasstatic void	ate_rxfilter(struct ate_softc *sc);
218155324Simp
219213496Scognetstatic int	ate_miibus_readreg(device_t dev, int phy, int reg);
220213496Scognet
221213496Scognetstatic int	ate_miibus_writereg(device_t dev, int phy, int reg, int data);
222155324Simp/*
223213496Scognet * The AT91 family of products has the ethernet interface called EMAC.
224213496Scognet * However, it isn't self identifying.  It is anticipated that the parent bus
225155324Simp * code will take care to only add ate devices where they really are.  As
226155324Simp * such, we do nothing here to identify the device and just set its name.
227155324Simp */
228155324Simpstatic int
229155324Simpate_probe(device_t dev)
230155324Simp{
231192063Sstas
232155324Simp	device_set_desc(dev, "EMAC");
233155324Simp	return (0);
234155324Simp}
235155324Simp
236155324Simpstatic int
237155324Simpate_attach(device_t dev)
238155324Simp{
239192063Sstas	struct ate_softc *sc;
240155324Simp	struct ifnet *ifp = NULL;
241163522Simp	struct sysctl_ctx_list *sctx;
242163522Simp	struct sysctl_oid *soid;
243182477Sstas	u_char eaddr[ETHER_ADDR_LEN];
244182477Sstas	uint32_t rnd;
245192018Sstas	int rid, err;
246155324Simp
247192063Sstas	sc = device_get_softc(dev);
248155324Simp	sc->dev = dev;
249192018Sstas	ATE_LOCK_INIT(sc);
250234281Smarius
251192018Sstas	rid = 0;
252192018Sstas	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
253192018Sstas	    RF_ACTIVE);
254192018Sstas	if (sc->mem_res == NULL) {
255192018Sstas		device_printf(dev, "could not allocate memory resources.\n");
256192018Sstas		err = ENOMEM;
257192018Sstas		goto out;
258192018Sstas	}
259192018Sstas	rid = 0;
260192018Sstas	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
261192018Sstas	    RF_ACTIVE);
262192018Sstas	if (sc->irq_res == NULL) {
263192018Sstas		device_printf(dev, "could not allocate interrupt resources.\n");
264192018Sstas		err = ENOMEM;
265192018Sstas		goto out;
266192018Sstas	}
267192018Sstas
268213496Scognet	/* New or old version, chooses buffer size. */
269234291Smarius	sc->is_emacb = at91_is_sam9() || at91_is_sam9xe();
270213496Scognet	sc->rx_buf_size = RX_BUF_SIZE(sc);
271213496Scognet
272155324Simp	err = ate_activate(dev);
273155324Simp	if (err)
274155324Simp		goto out;
275155324Simp
276213496Scognet	/* Default to what boot rom did */
277213496Scognet	if (!sc->is_emacb)
278213496Scognet		sc->use_rmii =
279213496Scognet		    (RD4(sc, ETH_CFG) & ETH_CFG_RMII) == ETH_CFG_RMII;
280213496Scognet	else
281213496Scognet		sc->use_rmii =
282213496Scognet		    (RD4(sc, ETHB_UIO) & ETHB_UIO_RMII) == ETHB_UIO_RMII;
283159708Simp
284213496Scognet#ifdef AT91_ATE_USE_RMII
285213496Scognet	/* Compile time override */
286213496Scognet	sc->use_rmii = 1;
287213496Scognet#endif
288182476Sstas	/* Sysctls */
289163522Simp	sctx = device_get_sysctl_ctx(dev);
290163522Simp	soid = device_get_sysctl_tree(dev);
291163522Simp	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "rmii",
292213496Scognet	    CTLFLAG_RW, &sc->use_rmii, 0, "rmii in use");
293163522Simp
294192063Sstas	/* Calling atestop before ifp is set is OK. */
295192018Sstas	ATE_LOCK(sc);
296155324Simp	atestop(sc);
297192018Sstas	ATE_UNLOCK(sc);
298213496Scognet	callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0);
299155324Simp
300166573Simp	if ((err = ate_get_mac(sc, eaddr)) != 0) {
301213496Scognet		/* No MAC address configured. Generate the random one. */
302213496Scognet		if (bootverbose)
303182477Sstas			device_printf(dev,
304182524Sstas			    "Generating random ethernet address.\n");
305182477Sstas		rnd = arc4random();
306182477Sstas
307182477Sstas		/*
308182555Simp		 * Set OUI to convenient locally assigned address.  'b'
309182555Simp		 * is 0x62, which has the locally assigned bit set, and
310182555Simp		 * the broadcast/multicast bit clear.
311182477Sstas		 */
312182555Simp		eaddr[0] = 'b';
313182555Simp		eaddr[1] = 's';
314182555Simp		eaddr[2] = 'd';
315182477Sstas		eaddr[3] = (rnd >> 16) & 0xff;
316213496Scognet		eaddr[4] = (rnd >>  8) & 0xff;
317213496Scognet		eaddr[5] = (rnd >>  0) & 0xff;
318166573Simp	}
319155324Simp
320155405Scognet	sc->ifp = ifp = if_alloc(IFT_ETHER);
321213894Smarius	err = mii_attach(dev, &sc->miibus, ifp, ate_ifmedia_upd,
322213894Smarius	    ate_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0);
323213894Smarius	if (err != 0) {
324213894Smarius		device_printf(dev, "attaching PHYs failed\n");
325155324Simp		goto out;
326155324Simp	}
327213496Scognet	/*
328234281Smarius	 * XXX: Clear the isolate bit, or we won't get up,
329234281Smarius	 * at least on the HL201
330213496Scognet	 */
331213496Scognet	ate_miibus_writereg(dev, 0, 0, 0x3000);
332155324Simp
333155324Simp	ifp->if_softc = sc;
334155324Simp	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
335155324Simp	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
336165779Sticso	ifp->if_capabilities |= IFCAP_VLAN_MTU;
337192063Sstas	ifp->if_capenable |= IFCAP_VLAN_MTU;	/* The hw bits already set. */
338155324Simp	ifp->if_start = atestart;
339155324Simp	ifp->if_ioctl = ateioctl;
340155324Simp	ifp->if_init = ateinit;
341155324Simp	ifp->if_baudrate = 10000000;
342213496Scognet	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
343213496Scognet	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
344155324Simp	IFQ_SET_READY(&ifp->if_snd);
345155324Simp	ifp->if_linkmib = &sc->mibdata;
346155324Simp	ifp->if_linkmiblen = sizeof(sc->mibdata);
347155324Simp	sc->mibdata.dot3Compliance = DOT3COMPLIANCE_COLLS;
348191959Sstas	sc->if_flags = ifp->if_flags;
349155324Simp
350155324Simp	ether_ifattach(ifp, eaddr);
351155324Simp
352213496Scognet	/* Activate the interrupt. */
353155324Simp	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
354166901Spiso	    NULL, ate_intr, sc, &sc->intrhand);
355155324Simp	if (err) {
356192018Sstas		device_printf(dev, "could not establish interrupt handler.\n");
357155324Simp		ether_ifdetach(ifp);
358192018Sstas		goto out;
359155324Simp	}
360192018Sstas
361192018Sstasout:
362155324Simp	if (err)
363192018Sstas		ate_detach(dev);
364155324Simp	return (err);
365155324Simp}
366155324Simp
367155324Simpstatic int
368155324Simpate_detach(device_t dev)
369155324Simp{
370192018Sstas	struct ate_softc *sc;
371192018Sstas	struct ifnet *ifp;
372192018Sstas
373192018Sstas	sc = device_get_softc(dev);
374192018Sstas	KASSERT(sc != NULL, ("[ate: %d]: sc is NULL", __LINE__));
375192018Sstas	ifp = sc->ifp;
376192018Sstas	if (device_is_attached(dev)) {
377192018Sstas		ATE_LOCK(sc);
378213496Scognet			sc->flags |= ATE_FLAG_DETACHING;
379213496Scognet			atestop(sc);
380192018Sstas		ATE_UNLOCK(sc);
381192018Sstas		callout_drain(&sc->tick_ch);
382213496Scognet		ether_ifdetach(ifp);
383192018Sstas	}
384192018Sstas	if (sc->miibus != NULL) {
385192018Sstas		device_delete_child(dev, sc->miibus);
386192018Sstas		sc->miibus = NULL;
387192018Sstas	}
388192018Sstas	bus_generic_detach(sc->dev);
389192018Sstas	ate_deactivate(sc);
390192018Sstas	if (sc->intrhand != NULL) {
391192018Sstas		bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
392192018Sstas		sc->intrhand = NULL;
393192018Sstas	}
394192018Sstas	if (ifp != NULL) {
395192018Sstas		if_free(ifp);
396192018Sstas		sc->ifp = NULL;
397192018Sstas	}
398192018Sstas	if (sc->mem_res != NULL) {
399192018Sstas		bus_release_resource(dev, SYS_RES_IOPORT,
400192018Sstas		    rman_get_rid(sc->mem_res), sc->mem_res);
401192018Sstas		sc->mem_res = NULL;
402192018Sstas	}
403192018Sstas	if (sc->irq_res != NULL) {
404192018Sstas		bus_release_resource(dev, SYS_RES_IRQ,
405192018Sstas		    rman_get_rid(sc->irq_res), sc->irq_res);
406192018Sstas		sc->irq_res = NULL;
407192018Sstas	}
408192018Sstas	ATE_LOCK_DESTROY(sc);
409192018Sstas	return (0);
410155324Simp}
411155324Simp
412155324Simpstatic void
413155324Simpate_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
414155324Simp{
415155324Simp
416155324Simp	if (error != 0)
417155324Simp		return;
418213496Scognet	*(bus_addr_t *)arg = segs[0].ds_addr;
419155324Simp}
420155324Simp
421157562Simpstatic void
422157562Simpate_load_rx_buf(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
423157562Simp{
424157562Simp	struct ate_softc *sc;
425157562Simp
426157562Simp	if (error != 0)
427157562Simp		return;
428157562Simp	sc = (struct ate_softc *)arg;
429157562Simp
430163937Simp	bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE);
431213496Scognet	sc->rx_descs[sc->rxhead].addr = segs[0].ds_addr;
432213496Scognet	sc->rx_descs[sc->rxhead].status = 0;
433163937Simp	bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_POSTWRITE);
434157562Simp}
435157562Simp
436218387Sticsostatic uint32_t
437218387Sticsoate_mac_hash(const uint8_t *buf)
438218387Sticso{
439218387Sticso	uint32_t index = 0;
440218387Sticso	for (int i = 0; i < 48; i++) {
441218387Sticso		index ^= ((buf[i >> 3] >> (i & 7)) & 1) << (i % 6);
442218387Sticso	}
443218387Sticso	return (index);
444218387Sticso}
445218387Sticso
446155324Simp/*
447213251Sticso * Compute the multicast filter for this device.
448155324Simp */
449191960Sstasstatic int
450155324Simpate_setmcast(struct ate_softc *sc)
451155324Simp{
452155324Simp	uint32_t index;
453155324Simp	uint32_t mcaf[2];
454155324Simp	u_char *af = (u_char *) mcaf;
455155324Simp	struct ifmultiaddr *ifma;
456191960Sstas	struct ifnet *ifp;
457155324Simp
458191960Sstas	ifp = sc->ifp;
459191960Sstas
460191960Sstas	if ((ifp->if_flags & IFF_PROMISC) != 0)
461191960Sstas		return (0);
462191960Sstas	if ((ifp->if_flags & IFF_ALLMULTI) != 0) {
463191960Sstas		WR4(sc, ETH_HSL, 0xffffffff);
464191960Sstas		WR4(sc, ETH_HSH, 0xffffffff);
465191960Sstas		return (1);
466191960Sstas	}
467191960Sstas
468213496Scognet	/* Compute the multicast hash. */
469155324Simp	mcaf[0] = 0;
470155324Simp	mcaf[1] = 0;
471195049Srwatson	if_maddr_rlock(ifp);
472191960Sstas	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
473155324Simp		if (ifma->ifma_addr->sa_family != AF_LINK)
474155324Simp			continue;
475218387Sticso		index = ate_mac_hash(LLADDR((struct sockaddr_dl *)
476218387Sticso		    ifma->ifma_addr));
477155324Simp		af[index >> 3] |= 1 << (index & 7);
478155324Simp	}
479195049Srwatson	if_maddr_runlock(ifp);
480155324Simp
481155324Simp	/*
482155324Simp	 * Write the hash to the hash register.  This card can also
483155324Simp	 * accept unicast packets as well as multicast packets using this
484155324Simp	 * register for easier bridging operations, but we don't take
485155324Simp	 * advantage of that.  Locks here are to avoid LOR with the
486195049Srwatson	 * if_maddr_rlock, but might not be strictly necessary.
487155324Simp	 */
488155324Simp	WR4(sc, ETH_HSL, mcaf[0]);
489155324Simp	WR4(sc, ETH_HSH, mcaf[1]);
490191960Sstas	return (mcaf[0] || mcaf[1]);
491155324Simp}
492155324Simp
493155324Simpstatic int
494155324Simpate_activate(device_t dev)
495155324Simp{
496155324Simp	struct ate_softc *sc;
497213496Scognet	int i;
498155324Simp
499155324Simp	sc = device_get_softc(dev);
500192063Sstas
501213496Scognet	/* Allocate DMA tags and maps for TX mbufs */
502213496Scognet	if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
503183670Simp	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
504213496Scognet	    1, MCLBYTES, 0, busdma_lock_mutex, &sc->sc_mtx, &sc->mtag))
505155324Simp		goto errout;
506155324Simp	for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
507213496Scognet		if ( bus_dmamap_create(sc->mtag, 0, &sc->tx_map[i]))
508155324Simp			goto errout;
509155324Simp	}
510192063Sstas
511155324Simp
512213496Scognet	/* DMA tag and map for the RX descriptors. */
513213496Scognet	if (bus_dma_tag_create(bus_get_dma_tag(dev), sizeof(eth_rx_desc_t),
514183670Simp	    0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
515213496Scognet	    ATE_NUM_RX_DESCR * sizeof(eth_rx_desc_t), 1,
516213496Scognet	    ATE_NUM_RX_DESCR * sizeof(eth_rx_desc_t), 0, busdma_lock_mutex,
517213496Scognet	    &sc->sc_mtx, &sc->rx_desc_tag))
518155324Simp		goto errout;
519156831Simp	if (bus_dmamem_alloc(sc->rx_desc_tag, (void **)&sc->rx_descs,
520156831Simp	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->rx_desc_map) != 0)
521155324Simp		goto errout;
522157562Simp	if (bus_dmamap_load(sc->rx_desc_tag, sc->rx_desc_map,
523213496Scognet	    sc->rx_descs, ATE_NUM_RX_DESCR * sizeof(eth_rx_desc_t),
524213496Scognet	    ate_getaddr, &sc->rx_desc_phys, 0) != 0)
525155324Simp		goto errout;
526192063Sstas
527213496Scognet	/* Allocate DMA tags and maps for RX. buffers */
528213496Scognet	if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
529213496Scognet	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
530213496Scognet	    sc->rx_buf_size, 1, sc->rx_buf_size, 0,
531213496Scognet	    busdma_lock_mutex, &sc->sc_mtx, &sc->rx_tag))
532213496Scognet		goto errout;
533213496Scognet
534192063Sstas	/*
535213496Scognet	 * Allocate our RX buffers.
536213496Scognet	 * This chip has a RX structure that's filled in.
537213496Scognet	 * XXX On MACB (SAM9 part) we should receive directly into mbuf
538213496Scognet	 * to avoid the copy.  XXX
539192063Sstas	 */
540213496Scognet	sc->rxhead = 0;
541213496Scognet	for (sc->rxhead = 0; sc->rxhead < ATE_RX_MEMORY/sc->rx_buf_size;
542213496Scognet	    sc->rxhead++) {
543213496Scognet		if (bus_dmamem_alloc(sc->rx_tag,
544213496Scognet		    (void **)&sc->rx_buf[sc->rxhead], BUS_DMA_NOWAIT,
545213496Scognet		    &sc->rx_map[sc->rxhead]) != 0)
546155324Simp			goto errout;
547213496Scognet
548213496Scognet		if (bus_dmamap_load(sc->rx_tag, sc->rx_map[sc->rxhead],
549213496Scognet		    sc->rx_buf[sc->rxhead], sc->rx_buf_size,
550213496Scognet		    ate_load_rx_buf, sc, 0) != 0) {
551213496Scognet			printf("bus_dmamem_load\n");
552157562Simp			goto errout;
553213496Scognet		}
554213496Scognet		bus_dmamap_sync(sc->rx_tag, sc->rx_map[sc->rxhead], BUS_DMASYNC_PREREAD);
555155324Simp	}
556213496Scognet
557213496Scognet	/*
558213496Scognet	 * For the last buffer, set the wrap bit so the controller
559213496Scognet	 * restarts from the first descriptor.
560213496Scognet	 */
561213496Scognet	sc->rx_descs[--sc->rxhead].addr |= ETH_WRAP_BIT;
562213496Scognet	sc->rxhead = 0;
563213496Scognet
564192063Sstas	/* Flush the memory for the EMAC rx descriptor. */
565155324Simp	bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE);
566213496Scognet
567155324Simp	/* Write the descriptor queue address. */
568155324Simp	WR4(sc, ETH_RBQP, sc->rx_desc_phys);
569213496Scognet
570213496Scognet	/*
571213496Scognet	 * DMA tag and map for the TX descriptors.
572213496Scognet	 */
573213496Scognet	if (bus_dma_tag_create(bus_get_dma_tag(dev), sizeof(eth_tx_desc_t),
574213496Scognet	    0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
575213496Scognet	    ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t), 1,
576213496Scognet	    ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t), 0, busdma_lock_mutex,
577213496Scognet	    &sc->sc_mtx, &sc->tx_desc_tag) != 0)
578213496Scognet		goto errout;
579213496Scognet
580213496Scognet	if (bus_dmamem_alloc(sc->tx_desc_tag, (void **)&sc->tx_descs,
581213496Scognet	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->tx_desc_map) != 0)
582213496Scognet		goto errout;
583213496Scognet
584213496Scognet	if (bus_dmamap_load(sc->tx_desc_tag, sc->tx_desc_map,
585213496Scognet	    sc->tx_descs, ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t),
586213496Scognet	    ate_getaddr, &sc->tx_desc_phys, 0) != 0)
587213496Scognet		goto errout;
588213496Scognet
589213496Scognet	/* Initilize descriptors; mark all empty */
590213496Scognet	for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
591213496Scognet		sc->tx_descs[i].addr =0;
592213496Scognet		sc->tx_descs[i].status = ETHB_TX_USED;
593213496Scognet		sc->sent_mbuf[i] = NULL;
594213496Scognet	}
595213496Scognet
596213496Scognet	/* Mark last entry to cause wrap when indexing through */
597213496Scognet	sc->tx_descs[ATE_MAX_TX_BUFFERS - 1].status =
598213496Scognet	    ETHB_TX_WRAP | ETHB_TX_USED;
599213496Scognet
600213496Scognet	/* Flush the memory for the EMAC tx descriptor. */
601213496Scognet	bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map, BUS_DMASYNC_PREWRITE);
602213496Scognet
603213496Scognet	sc->txhead = sc->txtail = 0;
604213496Scognet	if (sc->is_emacb) {
605213496Scognet		/* Write the descriptor queue address. */
606213496Scognet		WR4(sc, ETHB_TBQP, sc->tx_desc_phys);
607213496Scognet
608238895Simp		/* EMACB: Enable transceiver input clock */
609213496Scognet		WR4(sc, ETHB_UIO, RD4(sc, ETHB_UIO) | ETHB_UIO_CLKE);
610238895Simp	}
611213496Scognet
612155324Simp	return (0);
613192018Sstas
614155324Simperrout:
615155324Simp	return (ENOMEM);
616155324Simp}
617155324Simp
618155324Simpstatic void
619192018Sstasate_deactivate(struct ate_softc *sc)
620155324Simp{
621192018Sstas	int i;
622155324Simp
623192018Sstas	KASSERT(sc != NULL, ("[ate, %d]: sc is NULL!", __LINE__));
624192018Sstas	if (sc->mtag != NULL) {
625192018Sstas		for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
626192018Sstas			if (sc->sent_mbuf[i] != NULL) {
627192018Sstas				bus_dmamap_sync(sc->mtag, sc->tx_map[i],
628192018Sstas				    BUS_DMASYNC_POSTWRITE);
629192018Sstas				bus_dmamap_unload(sc->mtag, sc->tx_map[i]);
630192018Sstas				m_freem(sc->sent_mbuf[i]);
631155324Simp			}
632192018Sstas			bus_dmamap_destroy(sc->mtag, sc->tx_map[i]);
633192018Sstas			sc->sent_mbuf[i] = NULL;
634192018Sstas			sc->tx_map[i] = NULL;
635155324Simp		}
636192018Sstas		bus_dma_tag_destroy(sc->mtag);
637192018Sstas	}
638192018Sstas	if (sc->rx_desc_tag != NULL) {
639192018Sstas		if (sc->rx_descs != NULL) {
640192018Sstas			if (sc->rx_desc_phys != 0) {
641192018Sstas				bus_dmamap_sync(sc->rx_desc_tag,
642192018Sstas				    sc->rx_desc_map, BUS_DMASYNC_POSTREAD);
643192018Sstas				bus_dmamap_unload(sc->rx_desc_tag,
644192018Sstas				    sc->rx_desc_map);
645192018Sstas				sc->rx_desc_phys = 0;
646155324Simp			}
647155324Simp		}
648155324Simp	}
649213496Scognet	if (sc->rx_tag != NULL) {
650213496Scognet		for (i = 0; sc->rx_buf[i] != NULL; i++) {
651213496Scognet			if (sc->rx_descs[i].addr != 0) {
652213496Scognet				bus_dmamap_sync(sc->rx_tag,
653213496Scognet				    sc->rx_map[i],
654213496Scognet				    BUS_DMASYNC_POSTREAD);
655213496Scognet				bus_dmamap_unload(sc->rx_tag,
656192018Sstas				    sc->rx_map[i]);
657213496Scognet				sc->rx_descs[i].addr = 0;
658192018Sstas			}
659213496Scognet			bus_dmamem_free(sc->rx_tag, sc->rx_buf[i],
660213496Scognet			    sc->rx_map[i]);
661213496Scognet			sc->rx_buf[i] = NULL;
662213496Scognet			sc->rx_map[i] = NULL;
663192018Sstas		}
664213496Scognet		bus_dma_tag_destroy(sc->rx_tag);
665192018Sstas	}
666192018Sstas	if (sc->rx_desc_tag != NULL) {
667192018Sstas		if (sc->rx_descs != NULL)
668192018Sstas			bus_dmamem_free(sc->rx_desc_tag, sc->rx_descs,
669192018Sstas			    sc->rx_desc_map);
670192018Sstas		bus_dma_tag_destroy(sc->rx_desc_tag);
671192018Sstas		sc->rx_descs = NULL;
672192018Sstas		sc->rx_desc_tag = NULL;
673192018Sstas	}
674213496Scognet
675213496Scognet	if (sc->is_emacb)
676238895Simp		WR4(sc, ETHB_UIO, RD4(sc, ETHB_UIO) & ~ETHB_UIO_CLKE);
677155324Simp}
678155324Simp
679155324Simp/*
680155324Simp * Change media according to request.
681155324Simp */
682155324Simpstatic int
683155324Simpate_ifmedia_upd(struct ifnet *ifp)
684155324Simp{
685155324Simp	struct ate_softc *sc = ifp->if_softc;
686155324Simp	struct mii_data *mii;
687155324Simp
688155324Simp	mii = device_get_softc(sc->miibus);
689155324Simp	ATE_LOCK(sc);
690155324Simp	mii_mediachg(mii);
691155324Simp	ATE_UNLOCK(sc);
692155324Simp	return (0);
693155324Simp}
694155324Simp
695155324Simp/*
696155324Simp * Notify the world which media we're using.
697155324Simp */
698155324Simpstatic void
699155324Simpate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
700155324Simp{
701155324Simp	struct ate_softc *sc = ifp->if_softc;
702155324Simp	struct mii_data *mii;
703155324Simp
704155324Simp	mii = device_get_softc(sc->miibus);
705155324Simp	ATE_LOCK(sc);
706155324Simp	mii_pollstat(mii);
707155324Simp	ifmr->ifm_active = mii->mii_media_active;
708155324Simp	ifmr->ifm_status = mii->mii_media_status;
709155324Simp	ATE_UNLOCK(sc);
710155324Simp}
711155324Simp
712155324Simpstatic void
713163937Simpate_stat_update(struct ate_softc *sc, int active)
714163937Simp{
715192027Sstas	uint32_t reg;
716192027Sstas
717163937Simp	/*
718163937Simp	 * The speed and full/half-duplex state needs to be reflected
719163937Simp	 * in the ETH_CFG register.
720163937Simp	 */
721192027Sstas	reg = RD4(sc, ETH_CFG);
722192027Sstas	reg &= ~(ETH_CFG_SPD | ETH_CFG_FD);
723192027Sstas	if (IFM_SUBTYPE(active) != IFM_10_T)
724192027Sstas		reg |= ETH_CFG_SPD;
725163937Simp	if (active & IFM_FDX)
726192027Sstas		reg |= ETH_CFG_FD;
727192027Sstas	WR4(sc, ETH_CFG, reg);
728163937Simp}
729163937Simp
730163937Simpstatic void
731155324Simpate_tick(void *xsc)
732155324Simp{
733155324Simp	struct ate_softc *sc = xsc;
734163937Simp	struct ifnet *ifp = sc->ifp;
735155324Simp	struct mii_data *mii;
736155324Simp	int active;
737163937Simp	uint32_t c;
738155324Simp
739155324Simp	/*
740155324Simp	 * The KB920x boot loader tests ETH_SR & ETH_SR_LINK and will ask
741155324Simp	 * the MII if there's a link if this bit is clear.  Not sure if we
742155324Simp	 * should do the same thing here or not.
743155324Simp	 */
744155324Simp	ATE_ASSERT_LOCKED(sc);
745155324Simp	if (sc->miibus != NULL) {
746155324Simp		mii = device_get_softc(sc->miibus);
747155324Simp		active = mii->mii_media_active;
748155324Simp		mii_tick(mii);
749155324Simp		if (mii->mii_media_status & IFM_ACTIVE &&
750234281Smarius		    active != mii->mii_media_active)
751163937Simp			ate_stat_update(sc, mii->mii_media_active);
752155324Simp	}
753155324Simp
754155324Simp	/*
755155324Simp	 * Update the stats as best we can.  When we're done, clear
756155324Simp	 * the status counters and start over.  We're supposed to read these
757155324Simp	 * registers often enough that they won't overflow.  Hopefully
758155324Simp	 * once a second is often enough.  Some don't map well to
759155324Simp	 * the dot3Stats mib, so for those we just count them as general
760155324Simp	 * errors.  Stats for iframes, ibutes, oframes and obytes are
761155324Simp	 * collected elsewhere.  These registers zero on a read to prevent
762163937Simp	 * races.  For all the collision stats, also update the collision
763163937Simp	 * stats for the interface.
764155324Simp	 */
765155324Simp	sc->mibdata.dot3StatsAlignmentErrors += RD4(sc, ETH_ALE);
766155324Simp	sc->mibdata.dot3StatsFCSErrors += RD4(sc, ETH_SEQE);
767163937Simp	c = RD4(sc, ETH_SCOL);
768163937Simp	ifp->if_collisions += c;
769163937Simp	sc->mibdata.dot3StatsSingleCollisionFrames += c;
770163937Simp	c = RD4(sc, ETH_MCOL);
771163937Simp	sc->mibdata.dot3StatsMultipleCollisionFrames += c;
772163937Simp	ifp->if_collisions += c;
773155324Simp	sc->mibdata.dot3StatsSQETestErrors += RD4(sc, ETH_SQEE);
774155324Simp	sc->mibdata.dot3StatsDeferredTransmissions += RD4(sc, ETH_DTE);
775163937Simp	c = RD4(sc, ETH_LCOL);
776163937Simp	sc->mibdata.dot3StatsLateCollisions += c;
777163937Simp	ifp->if_collisions += c;
778163937Simp	c = RD4(sc, ETH_ECOL);
779163937Simp	sc->mibdata.dot3StatsExcessiveCollisions += c;
780163937Simp	ifp->if_collisions += c;
781155324Simp	sc->mibdata.dot3StatsCarrierSenseErrors += RD4(sc, ETH_CSE);
782155324Simp	sc->mibdata.dot3StatsFrameTooLongs += RD4(sc, ETH_ELR);
783155324Simp	sc->mibdata.dot3StatsInternalMacReceiveErrors += RD4(sc, ETH_DRFC);
784192063Sstas
785155324Simp	/*
786192063Sstas	 * Not sure where to lump these, so count them against the errors
787155324Simp	 * for the interface.
788155324Simp	 */
789163937Simp	sc->ifp->if_oerrors += RD4(sc, ETH_TUE);
790155324Simp	sc->ifp->if_ierrors += RD4(sc, ETH_CDE) + RD4(sc, ETH_RJB) +
791155324Simp	    RD4(sc, ETH_USF);
792155324Simp
793213496Scognet	/* Schedule another timeout one second from now. */
794155324Simp	callout_reset(&sc->tick_ch, hz, ate_tick, sc);
795155324Simp}
796155324Simp
797155324Simpstatic void
798155445Scognetate_set_mac(struct ate_softc *sc, u_char *eaddr)
799155445Scognet{
800192063Sstas
801155445Scognet	WR4(sc, ETH_SA1L, (eaddr[3] << 24) | (eaddr[2] << 16) |
802155445Scognet	    (eaddr[1] << 8) | eaddr[0]);
803155445Scognet	WR4(sc, ETH_SA1H, (eaddr[5] << 8) | (eaddr[4]));
804155445Scognet}
805155445Scognet
806166573Simpstatic int
807155324Simpate_get_mac(struct ate_softc *sc, u_char *eaddr)
808155324Simp{
809182477Sstas	bus_size_t sa_low_reg[] = { ETH_SA1L, ETH_SA2L, ETH_SA3L, ETH_SA4L };
810182477Sstas	bus_size_t sa_high_reg[] = { ETH_SA1H, ETH_SA2H, ETH_SA3H, ETH_SA4H };
811166573Simp	uint32_t low, high;
812182477Sstas	int i;
813155324Simp
814166573Simp	/*
815213496Scognet	 * The boot loader may setup the MAC with an address(es), grab the
816213496Scognet	 * first MAC address from the SA[1-4][HL] registers.
817166573Simp	 */
818182477Sstas	for (i = 0; i < 4; i++) {
819182477Sstas		low = RD4(sc, sa_low_reg[i]);
820182477Sstas		high = RD4(sc, sa_high_reg[i]);
821182477Sstas		if ((low | (high & 0xffff)) != 0) {
822182477Sstas			eaddr[0] = low & 0xff;
823182477Sstas			eaddr[1] = (low >> 8) & 0xff;
824182477Sstas			eaddr[2] = (low >> 16) & 0xff;
825182477Sstas			eaddr[3] = (low >> 24) & 0xff;
826182477Sstas			eaddr[4] = high & 0xff;
827182477Sstas			eaddr[5] = (high >> 8) & 0xff;
828182477Sstas			return (0);
829182477Sstas		}
830182477Sstas	}
831182477Sstas	return (ENXIO);
832155324Simp}
833155324Simp
834155324Simpstatic void
835155324Simpate_intr(void *xsc)
836155324Simp{
837155324Simp	struct ate_softc *sc = xsc;
838163937Simp	struct ifnet *ifp = sc->ifp;
839192027Sstas	struct mbuf *mb;
840213496Scognet	eth_rx_desc_t	*rxdhead;
841213496Scognet	uint32_t status, reg, idx;
842213496Scognet	int remain, count, done;
843156831Simp
844155324Simp	status = RD4(sc, ETH_ISR);
845155324Simp	if (status == 0)
846155324Simp		return;
847213496Scognet
848155324Simp	if (status & ETH_ISR_RCOM) {
849238895Simp		bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
850155324Simp		    BUS_DMASYNC_POSTREAD);
851213496Scognet
852238895Simp		rxdhead = &sc->rx_descs[sc->rxhead];
853238895Simp		while (rxdhead->addr & ETH_CPU_OWNER) {
854213496Scognet			if (!sc->is_emacb) {
855213496Scognet				/*
856213496Scognet				 * Simulate SAM9 FIRST/LAST bits for RM9200.
857213496Scognet				 * RM9200 EMAC has only on Rx buffer per packet.
858213496Scognet				 * But sometime we are handed a zero lenght packet.
859213496Scognet				 */
860213496Scognet				if ((rxdhead->status & ETH_LEN_MASK) == 0)
861213496Scognet					rxdhead->status = 0; /* Mark error */
862213496Scognet				else
863213496Scognet					rxdhead->status |= ETH_BUF_FIRST | ETH_BUF_LAST;
864213496Scognet			}
865213496Scognet
866213496Scognet			if ((rxdhead->status & ETH_BUF_FIRST) == 0) {
867213496Scognet				/* Something went wrong during RX so
868213496Scognet				   release back to EMAC all buffers of invalid packets.
869213496Scognet				*/
870213496Scognet				rxdhead->status = 0;
871213496Scognet				rxdhead->addr &= ~ETH_CPU_OWNER;
872213496Scognet				sc->rxhead = NEXT_RX_IDX(sc, sc->rxhead);
873213496Scognet				rxdhead = &sc->rx_descs[sc->rxhead];
874156831Simp				continue;
875155324Simp			}
876163937Simp
877213496Scognet			/* Find end of packet or start of next */
878213496Scognet			idx = sc->rxhead;
879213496Scognet			if ((sc->rx_descs[idx].status & ETH_BUF_LAST) == 0) {
880213496Scognet				idx = NEXT_RX_IDX(sc, idx);
881213496Scognet
882213496Scognet				while ((sc->rx_descs[idx].addr & ETH_CPU_OWNER) &&
883213496Scognet					((sc->rx_descs[idx].status &
884213496Scognet					    (ETH_BUF_FIRST|ETH_BUF_LAST))== 0))
885213496Scognet					idx = NEXT_RX_IDX(sc, idx);
886213496Scognet			}
887213496Scognet
888213496Scognet			/* Packet NOT yet completely in memory; we are done */
889213496Scognet			if ((sc->rx_descs[idx].addr & ETH_CPU_OWNER) == 0 ||
890213496Scognet			    ((sc->rx_descs[idx].status & (ETH_BUF_FIRST|ETH_BUF_LAST))== 0))
891213496Scognet					break;
892213496Scognet
893213496Scognet			/* Packets with no end descriptor are invalid. */
894213496Scognet			if ((sc->rx_descs[idx].status & ETH_BUF_LAST) == 0) {
895213496Scognet					rxdhead->status &= ~ETH_BUF_FIRST;
896213496Scognet					continue;
897213496Scognet			}
898213496Scognet
899213496Scognet			/* FCS is not coppied into mbuf. */
900213496Scognet			remain = (sc->rx_descs[idx].status & ETH_LEN_MASK) - 4;
901213496Scognet
902213496Scognet			/* Get an appropriately sized mbuf  */
903213496Scognet			if (remain + ETHER_ALIGN >= MINCLSIZE)
904213496Scognet				mb = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
905213496Scognet			else
906213496Scognet				MGETHDR(mb, M_DONTWAIT, MT_DATA);
907213496Scognet
908213496Scognet			if (mb == NULL) {
909213496Scognet				sc->ifp->if_iqdrops++;
910213496Scognet				rxdhead->status = 0;
911213496Scognet				continue;
912213496Scognet			}
913213496Scognet			mb->m_data += ETHER_ALIGN;
914213496Scognet			mb->m_pkthdr.rcvif = ifp;
915213496Scognet
916213496Scognet			WR4(sc, ETH_RSR, RD4(sc, ETH_RSR));	/* Reset status */
917213496Scognet
918213496Scognet			/* Now we process the buffers that make up the packet */
919213496Scognet			do {
920213496Scognet
921213496Scognet				/* Last buffer may just be 1-4 bytes of FCS so remain
922213496Scognet				 * may be zero for last decriptor.  */
923213496Scognet				if (remain > 0) {
924213496Scognet						/* Make sure we get the current bytes */
925213496Scognet						bus_dmamap_sync(sc->rx_tag, sc->rx_map[sc->rxhead],
926213496Scognet						    BUS_DMASYNC_POSTREAD);
927213496Scognet
928213496Scognet						count = MIN(remain, sc->rx_buf_size);
929213496Scognet
930213496Scognet						/* XXX Performance robbing copy. Could
931213496Scognet						 * recieve directly to mbufs if not an
932238895Simp						 * RM9200. And even then we could likely
933238895Simp						 * copy just the protocol headers. XXX  */
934213496Scognet						m_append(mb, count, sc->rx_buf[sc->rxhead]);
935213496Scognet						remain -= count;
936213496Scognet				}
937213496Scognet
938213496Scognet				done = (rxdhead->status & ETH_BUF_LAST) != 0;
939213496Scognet
940213496Scognet				/* Return the descriptor to the EMAC */
941213496Scognet				rxdhead->status = 0;
942213496Scognet				rxdhead->addr &= ~ETH_CPU_OWNER;
943213496Scognet				bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
944213496Scognet				    BUS_DMASYNC_PREWRITE);
945213496Scognet
946213496Scognet				/* Move on to next descriptor with wrap */
947213496Scognet				sc->rxhead = NEXT_RX_IDX(sc, sc->rxhead);
948213496Scognet				rxdhead = &sc->rx_descs[sc->rxhead];
949213496Scognet
950213496Scognet			} while (!done);
951213496Scognet
952163937Simp			if (mb != NULL) {
953163937Simp				ifp->if_ipackets++;
954163937Simp				(*ifp->if_input)(ifp, mb);
955163937Simp			}
956155324Simp		}
957155324Simp	}
958213496Scognet
959213496Scognet
960155324Simp	if (status & ETH_ISR_TCOM) {
961213496Scognet		bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map,
962213496Scognet		    BUS_DMASYNC_POSTREAD);
963213496Scognet
964156831Simp		ATE_LOCK(sc);
965163937Simp		/* XXX TSR register should be cleared */
966234281Smarius		if (!sc->is_emacb) {
967213496Scognet			/* Simulate Transmit descriptor table */
968213496Scognet
969213496Scognet			/* First packet done */
970213496Scognet			if (sc->txtail < sc->txhead)
971213496Scognet				sc->tx_descs[sc->txtail].status |= ETHB_TX_USED;
972213496Scognet
973213496Scognet			/* Second Packet done */
974213496Scognet			if (sc->txtail + 1 < sc->txhead &&
975213496Scognet			    RD4(sc, ETH_TSR) & ETH_TSR_IDLE)
976213496Scognet				sc->tx_descs[sc->txtail + 1].status |= ETHB_TX_USED;
977213496Scognet		}
978213496Scognet
979213496Scognet		while (sc->txtail != sc->txhead &&
980213496Scognet		    sc->tx_descs[sc->txtail].status & ETHB_TX_USED ) {
981213496Scognet
982213496Scognet			bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txtail],
983163937Simp			    BUS_DMASYNC_POSTWRITE);
984213496Scognet			bus_dmamap_unload(sc->mtag, sc->tx_map[sc->txtail]);
985213496Scognet			m_freem(sc->sent_mbuf[sc->txtail]);
986213496Scognet			sc->tx_descs[sc->txtail].addr = 0;
987213496Scognet			sc->sent_mbuf[sc->txtail] = NULL;
988213496Scognet
989163937Simp			ifp->if_opackets++;
990213496Scognet			sc->txtail = NEXT_TX_IDX(sc, sc->txtail);
991156831Simp		}
992213496Scognet
993213496Scognet		/* Flush descriptors to EMAC */
994213496Scognet		bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map, BUS_DMASYNC_PREWRITE);
995213496Scognet
996156831Simp		/*
997156831Simp		 * We're no longer busy, so clear the busy flag and call the
998156831Simp		 * start routine to xmit more packets.
999156831Simp		 */
1000156831Simp		sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1001156831Simp		atestart_locked(sc->ifp);
1002156831Simp		ATE_UNLOCK(sc);
1003155324Simp	}
1004213496Scognet
1005155324Simp	if (status & ETH_ISR_RBNA) {
1006213496Scognet		/* Workaround RM9200 Errata #11 */
1007192028Sstas		if (bootverbose)
1008192028Sstas			device_printf(sc->dev, "RBNA workaround\n");
1009192027Sstas		reg = RD4(sc, ETH_CTL);
1010192027Sstas		WR4(sc, ETH_CTL, reg & ~ETH_CTL_RE);
1011192027Sstas		BARRIER(sc, ETH_CTL, 4, BUS_SPACE_BARRIER_WRITE);
1012192027Sstas		WR4(sc, ETH_CTL, reg | ETH_CTL_RE);
1013155324Simp	}
1014238895Simp
1015238895Simp	/* XXX need to work around SAM9260 errata 43.2.4.1:
1016238895Simp	 * disable the mac, reset tx buffer, enable mac on TUND */
1017155324Simp}
1018155324Simp
1019155324Simp/*
1020192063Sstas * Reset and initialize the chip.
1021155324Simp */
1022155324Simpstatic void
1023155324Simpateinit_locked(void *xsc)
1024155324Simp{
1025155324Simp	struct ate_softc *sc = xsc;
1026155324Simp	struct ifnet *ifp = sc->ifp;
1027213496Scognet	struct mii_data *mii;
1028192064Sstas	uint8_t eaddr[ETHER_ADDR_LEN];
1029192027Sstas	uint32_t reg;
1030155324Simp
1031155324Simp	ATE_ASSERT_LOCKED(sc);
1032155324Simp
1033155324Simp	/*
1034155324Simp	 * XXX TODO(3)
1035155324Simp	 * we need to turn on the EMAC clock in the pmc.  With the
1036155324Simp	 * default boot loader, this is already turned on.  However, we
1037155324Simp	 * need to think about how best to turn it on/off as the interface
1038155324Simp	 * is brought up/down, as well as dealing with the mii bus...
1039155324Simp	 *
1040213496Scognet	 * We also need to multiplex the pins correctly (in board_xxx.c).
1041155324Simp	 */
1042155324Simp
1043155324Simp	/*
1044155324Simp	 * There are two different ways that the mii bus is connected
1045213496Scognet	 * to this chip mii or rmii.
1046155324Simp	 */
1047213496Scognet	if (!sc->is_emacb) {
1048213496Scognet		/* RM9200 */
1049213496Scognet		reg = RD4(sc, ETH_CFG);
1050213496Scognet		if (sc->use_rmii)
1051213496Scognet			reg |= ETH_CFG_RMII;
1052213496Scognet		else
1053213496Scognet			reg &= ~ETH_CFG_RMII;
1054213496Scognet		WR4(sc, ETH_CFG, reg);
1055213496Scognet	} else  {
1056213496Scognet		/* SAM9 */
1057213496Scognet		reg = ETHB_UIO_CLKE;
1058234281Smarius		reg |= (sc->use_rmii) ? ETHB_UIO_RMII : 0;
1059213496Scognet		WR4(sc, ETHB_UIO, reg);
1060213496Scognet	}
1061159708Simp
1062191960Sstas	ate_rxfilter(sc);
1063191960Sstas
1064191960Sstas	/*
1065192064Sstas	 * Set the chip MAC address.
1066192064Sstas	 */
1067192064Sstas	bcopy(IF_LLADDR(ifp), eaddr, ETHER_ADDR_LEN);
1068192064Sstas	ate_set_mac(sc, eaddr);
1069192064Sstas
1070213496Scognet	/* Make sure we know state of TX queue */
1071213496Scognet	sc->txhead = sc->txtail = 0;
1072213496Scognet	if (sc->is_emacb) {
1073213496Scognet		/* Write the descriptor queue address. */
1074213496Scognet		WR4(sc, ETHB_TBQP, sc->tx_desc_phys);
1075213496Scognet	}
1076213496Scognet
1077192064Sstas	/*
1078191960Sstas	 * Turn on MACs and interrupt processing.
1079191960Sstas	 */
1080155324Simp	WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETH_CTL_TE | ETH_CTL_RE);
1081156831Simp	WR4(sc, ETH_IER, ETH_ISR_RCOM | ETH_ISR_TCOM | ETH_ISR_RBNA);
1082155324Simp
1083192063Sstas	/* Enable big packets. */
1084165779Sticso	WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_BIG);
1085165779Sticso
1086155324Simp	/*
1087155324Simp	 * Set 'running' flag, and clear output active flag
1088192063Sstas	 * and attempt to start the output.
1089155324Simp	 */
1090155324Simp	ifp->if_drv_flags |= IFF_DRV_RUNNING;
1091155324Simp	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1092163937Simp
1093163937Simp	mii = device_get_softc(sc->miibus);
1094163937Simp	mii_pollstat(mii);
1095163937Simp	ate_stat_update(sc, mii->mii_media_active);
1096155324Simp	atestart_locked(ifp);
1097155324Simp
1098155324Simp	callout_reset(&sc->tick_ch, hz, ate_tick, sc);
1099155324Simp}
1100155324Simp
1101155324Simp/*
1102192063Sstas * Dequeue packets and transmit.
1103155324Simp */
1104155324Simpstatic void
1105155324Simpatestart_locked(struct ifnet *ifp)
1106155324Simp{
1107155324Simp	struct ate_softc *sc = ifp->if_softc;
1108155324Simp	struct mbuf *m, *mdefrag;
1109155324Simp	bus_dma_segment_t segs[1];
1110163937Simp	int nseg, e;
1111155324Simp
1112155324Simp	ATE_ASSERT_LOCKED(sc);
1113155324Simp	if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
1114155324Simp		return;
1115155324Simp
1116213496Scognet	while (sc->tx_descs[sc->txhead].status & ETHB_TX_USED) {
1117156831Simp		/*
1118192063Sstas		 * Check to see if there's room to put another packet into the
1119213496Scognet		 * xmit queue. The old EMAC version has a ping-pong buffer for
1120213496Scognet		 * xmit packets.  We use OACTIVE to indicate "we can stuff more
1121213496Scognet		 * into our buffers (clear) or not (set)."
1122156831Simp		 */
1123213496Scognet		if (!sc->is_emacb) {
1124213496Scognet			/* RM9200 has only two hardware entries */
1125213496Scognet			if (!sc->is_emacb && (RD4(sc, ETH_TSR) & ETH_TSR_BNQ) == 0) {
1126213496Scognet				ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1127213496Scognet				return;
1128213496Scognet			}
1129156831Simp		}
1130213496Scognet
1131156831Simp		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1132213496Scognet		if (m == 0)
1133213496Scognet			break;
1134213496Scognet
1135213496Scognet		e = bus_dmamap_load_mbuf_sg(sc->mtag, sc->tx_map[sc->txhead], m,
1136163937Simp		    segs, &nseg, 0);
1137163937Simp		if (e == EFBIG) {
1138163937Simp			mdefrag = m_defrag(m, M_DONTWAIT);
1139163937Simp			if (mdefrag == NULL) {
1140163937Simp				IFQ_DRV_PREPEND(&ifp->if_snd, m);
1141163937Simp				return;
1142163937Simp			}
1143163937Simp			m = mdefrag;
1144163937Simp			e = bus_dmamap_load_mbuf_sg(sc->mtag,
1145213496Scognet			    sc->tx_map[sc->txhead], m, segs, &nseg, 0);
1146156831Simp		}
1147163937Simp		if (e != 0) {
1148156831Simp			m_freem(m);
1149156831Simp			continue;
1150156831Simp		}
1151213496Scognet		sc->sent_mbuf[sc->txhead] = m;
1152213496Scognet
1153213496Scognet		bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txhead],
1154156831Simp		    BUS_DMASYNC_PREWRITE);
1155155324Simp
1156213496Scognet		/* Tell the hardware to xmit the packet. */
1157213496Scognet		if (!sc->is_emacb) {
1158213496Scognet			WR4(sc, ETH_TAR, segs[0].ds_addr);
1159213496Scognet			BARRIER(sc, ETH_TAR, 4, BUS_SPACE_BARRIER_WRITE);
1160213496Scognet			WR4(sc, ETH_TCR, segs[0].ds_len);
1161213496Scognet		} else {
1162213496Scognet			bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map,
1163213496Scognet			    BUS_DMASYNC_POSTWRITE);
1164213496Scognet			sc->tx_descs[sc->txhead].addr = segs[0].ds_addr;
1165213496Scognet			sc->tx_descs[sc->txhead].status = segs[0].ds_len |
1166213496Scognet			    (sc->tx_descs[sc->txhead].status & ETHB_TX_WRAP) |
1167213496Scognet			    ETHB_TX_BUF_LAST;
1168213496Scognet			bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map,
1169213496Scognet			    BUS_DMASYNC_PREWRITE);
1170213496Scognet			WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETHB_CTL_TGO);
1171213496Scognet		}
1172213496Scognet		sc->txhead = NEXT_TX_IDX(sc, sc->txhead);
1173234281Smarius
1174213496Scognet		/* Tap off here if there is a bpf listener. */
1175156831Simp		BPF_MTAP(ifp, m);
1176213496Scognet	}
1177155324Simp
1178213496Scognet	if ((sc->tx_descs[sc->txhead].status & ETHB_TX_USED) == 0)
1179213496Scognet	    ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1180155324Simp}
1181155324Simp
1182155324Simpstatic void
1183155324Simpateinit(void *xsc)
1184155324Simp{
1185155324Simp	struct ate_softc *sc = xsc;
1186192063Sstas
1187155324Simp	ATE_LOCK(sc);
1188155324Simp	ateinit_locked(sc);
1189155324Simp	ATE_UNLOCK(sc);
1190155324Simp}
1191155324Simp
1192155324Simpstatic void
1193155324Simpatestart(struct ifnet *ifp)
1194155324Simp{
1195155324Simp	struct ate_softc *sc = ifp->if_softc;
1196192063Sstas
1197155324Simp	ATE_LOCK(sc);
1198155324Simp	atestart_locked(ifp);
1199155324Simp	ATE_UNLOCK(sc);
1200155324Simp}
1201155324Simp
1202155324Simp/*
1203192063Sstas * Turn off interrupts, and stop the NIC.  Can be called with sc->ifp NULL,
1204155324Simp * so be careful.
1205155324Simp */
1206155324Simpstatic void
1207155324Simpatestop(struct ate_softc *sc)
1208155324Simp{
1209192018Sstas	struct ifnet *ifp;
1210192018Sstas	int i;
1211155324Simp
1212192018Sstas	ATE_ASSERT_LOCKED(sc);
1213192018Sstas	ifp = sc->ifp;
1214155324Simp	if (ifp) {
1215213496Scognet		//ifp->if_timer = 0;
1216155324Simp		ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1217155324Simp	}
1218155324Simp
1219155324Simp	callout_stop(&sc->tick_ch);
1220155324Simp
1221155324Simp	/*
1222155324Simp	 * Enable some parts of the MAC that are needed always (like the
1223155324Simp	 * MII bus.  This turns off the RE and TE bits, which will remain
1224155405Scognet	 * off until ateinit() is called to turn them on.  With RE and TE
1225155324Simp	 * turned off, there's no DMA to worry about after this write.
1226155324Simp	 */
1227155324Simp	WR4(sc, ETH_CTL, ETH_CTL_MPE);
1228155324Simp
1229155324Simp	/*
1230155324Simp	 * Turn off all the configured options and revert to defaults.
1231155324Simp	 */
1232155324Simp
1233213496Scognet	/* Make sure thate the MDIO clk is less than
1234213496Scognet	 * 2.5 Mhz. Can no longer default to /32 since
1235213496Scognet	 * SAM9 family may have MCK > 80 Mhz */
1236213496Scognet	if (at91_master_clock <= 2000000)
1237213496Scognet		WR4(sc, ETH_CFG, ETH_CFG_CLK_8);
1238213496Scognet	else if (at91_master_clock <= 4000000)
1239213496Scognet		WR4(sc, ETH_CFG, ETH_CFG_CLK_16);
1240213496Scognet	else if (at91_master_clock <= 800000)
1241213496Scognet		WR4(sc, ETH_CFG, ETH_CFG_CLK_32);
1242213496Scognet	else
1243213496Scognet		WR4(sc, ETH_CFG, ETH_CFG_CLK_64);
1244213496Scognet
1245155324Simp	/*
1246155324Simp	 * Turn off all the interrupts, and ack any pending ones by reading
1247155324Simp	 * the ISR.
1248155324Simp	 */
1249155324Simp	WR4(sc, ETH_IDR, 0xffffffff);
1250155324Simp	RD4(sc, ETH_ISR);
1251155324Simp
1252155324Simp	/*
1253155324Simp	 * Clear out the Transmit and Receiver Status registers of any
1254155324Simp	 * errors they may be reporting
1255155324Simp	 */
1256155324Simp	WR4(sc, ETH_TSR, 0xffffffff);
1257155324Simp	WR4(sc, ETH_RSR, 0xffffffff);
1258155324Simp
1259213496Scognet	/* Release TX resources. */
1260192018Sstas	for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
1261192018Sstas		if (sc->sent_mbuf[i] != NULL) {
1262192018Sstas			bus_dmamap_sync(sc->mtag, sc->tx_map[i],
1263192018Sstas			    BUS_DMASYNC_POSTWRITE);
1264192018Sstas			bus_dmamap_unload(sc->mtag, sc->tx_map[i]);
1265192018Sstas			m_freem(sc->sent_mbuf[i]);
1266192018Sstas			sc->sent_mbuf[i] = NULL;
1267192018Sstas		}
1268192018Sstas	}
1269155324Simp
1270213496Scognet	/* Turn off transeiver input clock */
1271213496Scognet	if (sc->is_emacb)
1272238895Simp		WR4(sc, ETHB_UIO, RD4(sc, ETHB_UIO) & ~ETHB_UIO_CLKE);
1273213496Scognet
1274155324Simp	/*
1275155324Simp	 * XXX we should power down the EMAC if it isn't in use, after
1276155324Simp	 * putting it into loopback mode.  This saves about 400uA according
1277155324Simp	 * to the datasheet.
1278155324Simp	 */
1279155324Simp}
1280155324Simp
1281191959Sstasstatic void
1282191959Sstasate_rxfilter(struct ate_softc *sc)
1283191959Sstas{
1284191959Sstas	struct ifnet *ifp;
1285191959Sstas	uint32_t reg;
1286191960Sstas	int enabled;
1287191959Sstas
1288191959Sstas	KASSERT(sc != NULL, ("[ate, %d]: sc is NULL!", __LINE__));
1289191959Sstas	ATE_ASSERT_LOCKED(sc);
1290191959Sstas	ifp = sc->ifp;
1291191959Sstas
1292213496Scognet	/* Wipe out old filter settings. */
1293191959Sstas	reg = RD4(sc, ETH_CFG);
1294191959Sstas	reg &= ~(ETH_CFG_CAF | ETH_CFG_MTI | ETH_CFG_UNI);
1295191959Sstas	reg |= ETH_CFG_NBC;
1296191960Sstas	sc->flags &= ~ATE_FLAG_MULTICAST;
1297191959Sstas
1298213496Scognet	/* Set new parameters. */
1299191959Sstas	if ((ifp->if_flags & IFF_BROADCAST) != 0)
1300191959Sstas		reg &= ~ETH_CFG_NBC;
1301191960Sstas	if ((ifp->if_flags & IFF_PROMISC) != 0) {
1302191959Sstas		reg |= ETH_CFG_CAF;
1303191960Sstas	} else {
1304191960Sstas		enabled = ate_setmcast(sc);
1305191960Sstas		if (enabled != 0) {
1306191960Sstas			reg |= ETH_CFG_MTI;
1307191960Sstas			sc->flags |= ATE_FLAG_MULTICAST;
1308191960Sstas		}
1309191960Sstas	}
1310191959Sstas	WR4(sc, ETH_CFG, reg);
1311191959Sstas}
1312191959Sstas
1313155324Simpstatic int
1314155324Simpateioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1315155324Simp{
1316155324Simp	struct ate_softc *sc = ifp->if_softc;
1317213496Scognet	struct mii_data *mii;
1318234281Smarius	struct ifreq *ifr = (struct ifreq *)data;
1319191959Sstas	int drv_flags, flags;
1320191960Sstas	int mask, error, enabled;
1321155324Simp
1322191960Sstas	error = 0;
1323191959Sstas	flags = ifp->if_flags;
1324191959Sstas	drv_flags = ifp->if_drv_flags;
1325155324Simp	switch (cmd) {
1326155324Simp	case SIOCSIFFLAGS:
1327155324Simp		ATE_LOCK(sc);
1328191959Sstas		if ((flags & IFF_UP) != 0) {
1329191959Sstas			if ((drv_flags & IFF_DRV_RUNNING) != 0) {
1330191959Sstas				if (((flags ^ sc->if_flags)
1331191959Sstas				    & (IFF_PROMISC | IFF_ALLMULTI)) != 0)
1332191959Sstas					ate_rxfilter(sc);
1333191959Sstas			} else {
1334213496Scognet				if ((sc->flags & ATE_FLAG_DETACHING) == 0)
1335213496Scognet					ateinit_locked(sc);
1336191959Sstas			}
1337191959Sstas		} else if ((drv_flags & IFF_DRV_RUNNING) != 0) {
1338213496Scognet			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
1339155324Simp			atestop(sc);
1340155324Simp		}
1341191959Sstas		sc->if_flags = flags;
1342155324Simp		ATE_UNLOCK(sc);
1343155324Simp		break;
1344155324Simp
1345155324Simp	case SIOCADDMULTI:
1346155324Simp	case SIOCDELMULTI:
1347191960Sstas		if ((drv_flags & IFF_DRV_RUNNING) != 0) {
1348191960Sstas			ATE_LOCK(sc);
1349191960Sstas			enabled = ate_setmcast(sc);
1350191960Sstas			if (enabled != (sc->flags & ATE_FLAG_MULTICAST))
1351191960Sstas				ate_rxfilter(sc);
1352191960Sstas			ATE_UNLOCK(sc);
1353191960Sstas		}
1354155324Simp		break;
1355155324Simp
1356213496Scognet	case SIOCSIFMEDIA:
1357213496Scognet	case SIOCGIFMEDIA:
1358213496Scognet		mii = device_get_softc(sc->miibus);
1359213496Scognet		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
1360213496Scognet		break;
1361165779Sticso	case SIOCSIFCAP:
1362165779Sticso		mask = ifp->if_capenable ^ ifr->ifr_reqcap;
1363165779Sticso		if (mask & IFCAP_VLAN_MTU) {
1364165779Sticso			ATE_LOCK(sc);
1365165779Sticso			if (ifr->ifr_reqcap & IFCAP_VLAN_MTU) {
1366165779Sticso				WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_BIG);
1367165779Sticso				ifp->if_capenable |= IFCAP_VLAN_MTU;
1368165779Sticso			} else {
1369165779Sticso				WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_BIG);
1370165779Sticso				ifp->if_capenable &= ~IFCAP_VLAN_MTU;
1371165779Sticso			}
1372165779Sticso			ATE_UNLOCK(sc);
1373165779Sticso		}
1374155324Simp	default:
1375155324Simp		error = ether_ioctl(ifp, cmd, data);
1376155324Simp		break;
1377155324Simp	}
1378155324Simp	return (error);
1379155324Simp}
1380155324Simp
1381155324Simpstatic void
1382155324Simpate_child_detached(device_t dev, device_t child)
1383155324Simp{
1384155324Simp	struct ate_softc *sc;
1385155324Simp
1386155324Simp	sc = device_get_softc(dev);
1387155324Simp	if (child == sc->miibus)
1388155324Simp		sc->miibus = NULL;
1389155324Simp}
1390155324Simp
1391155324Simp/*
1392155324Simp * MII bus support routines.
1393155324Simp */
1394155324Simpstatic int
1395155324Simpate_miibus_readreg(device_t dev, int phy, int reg)
1396155324Simp{
1397155324Simp	struct ate_softc *sc;
1398155324Simp	int val;
1399155324Simp
1400155324Simp	/*
1401155324Simp	 * XXX if we implement agressive power savings, then we need
1402155324Simp	 * XXX to make sure that the clock to the emac is on here
1403155324Simp	 */
1404155324Simp
1405155324Simp	sc = device_get_softc(dev);
1406155324Simp	DELAY(1);	/* Hangs w/o this delay really 30.5us atm */
1407155324Simp	WR4(sc, ETH_MAN, ETH_MAN_REG_RD(phy, reg));
1408155324Simp	while ((RD4(sc, ETH_SR) & ETH_SR_IDLE) == 0)
1409155324Simp		continue;
1410155324Simp	val = RD4(sc, ETH_MAN) & ETH_MAN_VALUE_MASK;
1411155324Simp
1412155324Simp	return (val);
1413155324Simp}
1414155324Simp
1415194015Savgstatic int
1416155324Simpate_miibus_writereg(device_t dev, int phy, int reg, int data)
1417155324Simp{
1418155324Simp	struct ate_softc *sc;
1419234281Smarius
1420155324Simp	/*
1421155324Simp	 * XXX if we implement agressive power savings, then we need
1422155324Simp	 * XXX to make sure that the clock to the emac is on here
1423155324Simp	 */
1424155324Simp
1425155324Simp	sc = device_get_softc(dev);
1426155324Simp	WR4(sc, ETH_MAN, ETH_MAN_REG_WR(phy, reg, data));
1427155324Simp	while ((RD4(sc, ETH_SR) & ETH_SR_IDLE) == 0)
1428155324Simp		continue;
1429194015Savg	return (0);
1430155324Simp}
1431155324Simp
1432155324Simpstatic device_method_t ate_methods[] = {
1433155324Simp	/* Device interface */
1434155324Simp	DEVMETHOD(device_probe,		ate_probe),
1435155324Simp	DEVMETHOD(device_attach,	ate_attach),
1436155324Simp	DEVMETHOD(device_detach,	ate_detach),
1437155324Simp
1438155324Simp	/* Bus interface */
1439155324Simp	DEVMETHOD(bus_child_detached,	ate_child_detached),
1440155324Simp
1441155324Simp	/* MII interface */
1442155324Simp	DEVMETHOD(miibus_readreg,	ate_miibus_readreg),
1443155324Simp	DEVMETHOD(miibus_writereg,	ate_miibus_writereg),
1444155324Simp
1445234281Smarius	DEVMETHOD_END
1446155324Simp};
1447155324Simp
1448155324Simpstatic driver_t ate_driver = {
1449155324Simp	"ate",
1450155324Simp	ate_methods,
1451155324Simp	sizeof(struct ate_softc),
1452155324Simp};
1453155324Simp
1454234281SmariusDRIVER_MODULE(ate, atmelarm, ate_driver, ate_devclass, NULL, NULL);
1455234281SmariusDRIVER_MODULE(miibus, ate, miibus_driver, miibus_devclass, NULL, NULL);
1456155324SimpMODULE_DEPEND(ate, miibus, 1, 1, 1);
1457155324SimpMODULE_DEPEND(ate, ether, 1, 1, 1);
1458