xref: /netbsd-src/sys/dev/marvell/if_mvxpe.c (revision 4d5abbe83f525258eb479e5fca29f25cb943f379)
1 /*	$NetBSD: if_mvxpe.c,v 1.2 2015/06/03 03:55:47 hsuenaga Exp $	*/
2 /*
3  * Copyright (c) 2015 Internet Initiative Japan Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
19  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 #include <sys/cdefs.h>
28 __KERNEL_RCSID(0, "$NetBSD: if_mvxpe.c,v 1.2 2015/06/03 03:55:47 hsuenaga Exp $");
29 
30 #include "opt_multiprocessor.h"
31 
32 #include <sys/param.h>
33 #include <sys/bus.h>
34 #include <sys/callout.h>
35 #include <sys/device.h>
36 #include <sys/endian.h>
37 #include <sys/errno.h>
38 #include <sys/evcnt.h>
39 #include <sys/kernel.h>
40 #include <sys/kmem.h>
41 #include <sys/mutex.h>
42 #include <sys/sockio.h>
43 #include <sys/sysctl.h>
44 #include <sys/syslog.h>
45 #include <sys/rndsource.h>
46 
47 #include <net/if.h>
48 #include <net/if_ether.h>
49 #include <net/if_media.h>
50 #include <net/bpf.h>
51 
52 #include <netinet/in.h>
53 #include <netinet/in_systm.h>
54 #include <netinet/ip.h>
55 
56 #include <dev/mii/mii.h>
57 #include <dev/mii/miivar.h>
58 
59 #include <dev/marvell/marvellreg.h>
60 #include <dev/marvell/marvellvar.h>
61 #include <dev/marvell/mvxpbmvar.h>
62 #include <dev/marvell/if_mvxpereg.h>
63 #include <dev/marvell/if_mvxpevar.h>
64 
65 #include "locators.h"
66 
67 #if BYTE_ORDER == BIG_ENDIAN
68 #error "BIG ENDIAN not supported"
69 #endif
70 
71 #ifdef MVXPE_DEBUG
72 #define STATIC /* nothing */
73 #else
74 #define STATIC static
75 #endif
76 
77 /* autoconf(9) */
78 STATIC int mvxpe_match(device_t, struct cfdata *, void *);
79 STATIC void mvxpe_attach(device_t, device_t, void *);
80 STATIC int mvxpe_evcnt_attach(struct mvxpe_softc *);
81 CFATTACH_DECL_NEW(mvxpe_mbus, sizeof(struct mvxpe_softc),
82     mvxpe_match, mvxpe_attach, NULL, NULL);
83 STATIC void mvxpe_sc_lock(struct mvxpe_softc *);
84 STATIC void mvxpe_sc_unlock(struct mvxpe_softc *);
85 
86 /* MII */
87 STATIC int mvxpe_miibus_readreg(device_t, int, int);
88 STATIC void mvxpe_miibus_writereg(device_t, int, int, int);
89 STATIC void mvxpe_miibus_statchg(struct ifnet *);
90 
91 /* Addres Decoding Window */
92 STATIC void mvxpe_wininit(struct mvxpe_softc *, enum marvell_tags *);
93 
94 /* Device Register Initialization */
95 STATIC int mvxpe_initreg(struct ifnet *);
96 
97 /* Descriptor Ring Control for each of queues */
98 STATIC void *mvxpe_dma_memalloc(struct mvxpe_softc *, bus_dmamap_t *, size_t);
99 STATIC int mvxpe_ring_alloc_queue(struct mvxpe_softc *, int);
100 STATIC void mvxpe_ring_dealloc_queue(struct mvxpe_softc *, int);
101 STATIC void mvxpe_ring_init_queue(struct mvxpe_softc *, int);
102 STATIC void mvxpe_ring_flush_queue(struct mvxpe_softc *, int);
103 STATIC void mvxpe_ring_sync_rx(struct mvxpe_softc *, int, int, int, int);
104 STATIC void mvxpe_ring_sync_tx(struct mvxpe_softc *, int, int, int, int);
105 
106 /* Rx/Tx Queue Control */
107 STATIC int mvxpe_rx_queue_init(struct ifnet *, int);
108 STATIC int mvxpe_tx_queue_init(struct ifnet *, int);
109 STATIC int mvxpe_rx_queue_enable(struct ifnet *, int);
110 STATIC int mvxpe_tx_queue_enable(struct ifnet *, int);
111 STATIC void mvxpe_rx_lockq(struct mvxpe_softc *, int);
112 STATIC void mvxpe_rx_unlockq(struct mvxpe_softc *, int);
113 STATIC void mvxpe_tx_lockq(struct mvxpe_softc *, int);
114 STATIC void mvxpe_tx_unlockq(struct mvxpe_softc *, int);
115 
116 /* Interrupt Handlers */
117 STATIC void mvxpe_disable_intr(struct mvxpe_softc *);
118 STATIC void mvxpe_enable_intr(struct mvxpe_softc *);
119 STATIC int mvxpe_rxtxth_intr(void *);
120 STATIC int mvxpe_misc_intr(void *);
121 STATIC int mvxpe_rxtx_intr(void *);
122 STATIC void mvxpe_tick(void *);
123 
124 /* struct ifnet and mii callbacks*/
125 STATIC void mvxpe_start(struct ifnet *);
126 STATIC int mvxpe_ioctl(struct ifnet *, u_long, void *);
127 STATIC int mvxpe_init(struct ifnet *);
128 STATIC void mvxpe_stop(struct ifnet *, int);
129 STATIC void mvxpe_watchdog(struct ifnet *);
130 STATIC int mvxpe_ifflags_cb(struct ethercom *);
131 STATIC int mvxpe_mediachange(struct ifnet *);
132 STATIC void mvxpe_mediastatus(struct ifnet *, struct ifmediareq *);
133 
134 /* Link State Notify */
135 STATIC void mvxpe_linkupdate(struct mvxpe_softc *sc);
136 STATIC void mvxpe_linkup(struct mvxpe_softc *);
137 STATIC void mvxpe_linkdown(struct mvxpe_softc *);
138 STATIC void mvxpe_linkreset(struct mvxpe_softc *);
139 
140 /* Tx Subroutines */
141 STATIC int mvxpe_tx_queue_select(struct mvxpe_softc *, struct mbuf *);
142 STATIC int mvxpe_tx_queue(struct mvxpe_softc *, struct mbuf *, int);
143 STATIC void mvxpe_tx_set_csumflag(struct ifnet *,
144     struct mvxpe_tx_desc *, struct mbuf *);
145 STATIC void mvxpe_tx_complete(struct mvxpe_softc *, uint32_t);
146 STATIC void mvxpe_tx_queue_complete(struct mvxpe_softc *, int);
147 
148 /* Rx Subroutines */
149 STATIC void mvxpe_rx(struct mvxpe_softc *, uint32_t);
150 STATIC void mvxpe_rx_queue(struct mvxpe_softc *, int, int);
151 STATIC int mvxpe_rx_queue_select(struct mvxpe_softc *, uint32_t, int *);
152 STATIC void mvxpe_rx_refill(struct mvxpe_softc *, uint32_t);
153 STATIC void mvxpe_rx_queue_refill(struct mvxpe_softc *, int);
154 STATIC int mvxpe_rx_queue_add(struct mvxpe_softc *, int);
155 STATIC void mvxpe_rx_set_csumflag(struct ifnet *,
156     struct mvxpe_rx_desc *, struct mbuf *);
157 
158 /* MAC address filter */
159 STATIC uint8_t mvxpe_crc8(const uint8_t *, size_t);
160 STATIC void mvxpe_filter_setup(struct mvxpe_softc *);
161 
162 /* sysctl(9) */
163 STATIC int sysctl_read_mib(SYSCTLFN_PROTO);
164 STATIC int sysctl_clear_mib(SYSCTLFN_PROTO);
165 STATIC int sysctl_set_queue_length(SYSCTLFN_PROTO);
166 STATIC int sysctl_set_queue_rxthtime(SYSCTLFN_PROTO);
167 STATIC void sysctl_mvxpe_init(struct mvxpe_softc *);
168 
169 /* MIB */
170 STATIC void mvxpe_clear_mib(struct mvxpe_softc *);
171 STATIC void mvxpe_update_mib(struct mvxpe_softc *);
172 
173 /* for Debug */
174 STATIC void mvxpe_dump_txdesc(struct mvxpe_tx_desc *, int) __attribute__((__unused__));
175 STATIC void mvxpe_dump_rxdesc(struct mvxpe_rx_desc *, int) __attribute__((__unused__));
176 
177 STATIC int mvxpe_root_num;
178 STATIC kmutex_t mii_mutex;
179 STATIC int mii_init = 0;
180 #ifdef MVXPE_DEBUG
181 STATIC int mvxpe_debug = MVXPE_DEBUG;
182 #endif
183 
184 /*
185  * List of MIB register and names
186  */
187 STATIC struct mvxpe_mib_def {
188 	uint32_t regnum;
189 	int reg64;
190 	const char *sysctl_name;
191 	const char *desc;
192 } mvxpe_mib_list[] = {
193 	{MVXPE_MIB_RX_GOOD_OCT, 1,	"rx_good_oct",
194 	    "Good Octets Rx"},
195 	{MVXPE_MIB_RX_BAD_OCT, 0,	"rx_bad_oct",
196 	    "Bad  Octets Rx"},
197 	{MVXPE_MIB_RX_MAC_TRNS_ERR, 0,	"rx_mac_err",
198 	    "MAC Transmit Error"},
199 	{MVXPE_MIB_RX_GOOD_FRAME, 0,	"rx_good_frame",
200 	    "Good Frames Rx"},
201 	{MVXPE_MIB_RX_BAD_FRAME, 0,	"rx_bad_frame",
202 	    "Bad Frames Rx"},
203 	{MVXPE_MIB_RX_BCAST_FRAME, 0,	"rx_bcast_frame",
204 	    "Broadcast Frames Rx"},
205 	{MVXPE_MIB_RX_MCAST_FRAME, 0,	"rx_mcast_frame",
206 	    "Multicast Frames Rx"},
207 	{MVXPE_MIB_RX_FRAME64_OCT, 0,	"rx_frame_1_64",
208 	    "Frame Size    1 -   64"},
209 	{MVXPE_MIB_RX_FRAME127_OCT, 0,	"rx_frame_65_127",
210 	    "Frame Size   65 -  127"},
211 	{MVXPE_MIB_RX_FRAME255_OCT, 0,	"rx_frame_128_255",
212 	    "Frame Size  128 -  255"},
213 	{MVXPE_MIB_RX_FRAME511_OCT, 0,	"rx_frame_256_511",
214 	    "Frame Size  256 -  511"},
215 	{MVXPE_MIB_RX_FRAME1023_OCT, 0,	"rx_frame_512_1023",
216 	    "Frame Size  512 - 1023"},
217 	{MVXPE_MIB_RX_FRAMEMAX_OCT, 0,	"rx_fame_1024_max",
218 	    "Frame Size 1024 -  Max"},
219 	{MVXPE_MIB_TX_GOOD_OCT, 1,	"tx_good_oct",
220 	    "Good Octets Tx"},
221 	{MVXPE_MIB_TX_GOOD_FRAME, 0,	"tx_good_frame",
222 	    "Good Frames Tx"},
223 	{MVXPE_MIB_TX_EXCES_COL, 0,	"tx_exces_collision",
224 	    "Excessive Collision"},
225 	{MVXPE_MIB_TX_MCAST_FRAME, 0,	"tx_mcast_frame",
226 	    "Multicast Frames Tx"},
227 	{MVXPE_MIB_TX_BCAST_FRAME, 0,	"tx_bcast_frame",
228 	    "Broadcast Frames Tx"},
229 	{MVXPE_MIB_TX_MAC_CTL_ERR, 0,	"tx_mac_err",
230 	    "Unknown MAC Control"},
231 	{MVXPE_MIB_FC_SENT, 0,		"fc_tx",
232 	    "Flow Control Tx"},
233 	{MVXPE_MIB_FC_GOOD, 0,		"fc_rx_good",
234 	    "Good Flow Control Rx"},
235 	{MVXPE_MIB_FC_BAD, 0,		"fc_rx_bad",
236 	    "Bad Flow Control Rx"},
237 	{MVXPE_MIB_PKT_UNDERSIZE, 0,	"pkt_undersize",
238 	    "Undersized Packets Rx"},
239 	{MVXPE_MIB_PKT_FRAGMENT, 0,	"pkt_fragment",
240 	    "Fragmented Packets Rx"},
241 	{MVXPE_MIB_PKT_OVERSIZE, 0,	"pkt_oversize",
242 	    "Oversized Packets Rx"},
243 	{MVXPE_MIB_PKT_JABBER, 0,	"pkt_jabber",
244 	    "Jabber Packets Rx"},
245 	{MVXPE_MIB_MAC_RX_ERR, 0,	"mac_rx_err",
246 	    "MAC Rx Errors"},
247 	{MVXPE_MIB_MAC_CRC_ERR, 0,	"mac_crc_err",
248 	    "MAC CRC Errors"},
249 	{MVXPE_MIB_MAC_COL, 0,		"mac_collision",
250 	    "MAC Collision"},
251 	{MVXPE_MIB_MAC_LATE_COL, 0,	"mac_late_collision",
252 	    "MAC Late Collision"},
253 };
254 
255 /*
256  * autoconf(9)
257  */
258 /* ARGSUSED */
259 STATIC int
260 mvxpe_match(device_t parent, cfdata_t match, void *aux)
261 {
262 	struct marvell_attach_args *mva = aux;
263 	bus_size_t pv_off;
264 	uint32_t pv;
265 
266 	if (strcmp(mva->mva_name, match->cf_name) != 0)
267 		return 0;
268 	if (mva->mva_offset == MVA_OFFSET_DEFAULT)
269 		return 0;
270 
271 	/* check port version */
272 	pv_off = mva->mva_offset + MVXPE_PV;
273 	pv = bus_space_read_4(mva->mva_iot, mva->mva_ioh, pv_off);
274 	if (MVXPE_PV_GET_VERSION(pv) < 0x10)
275 		return 0; /* old version is not supported */
276 
277 	return 1;
278 }
279 
280 /* ARGSUSED */
281 STATIC void
282 mvxpe_attach(device_t parent, device_t self, void *aux)
283 {
284 	struct mvxpe_softc *sc = device_private(self);
285 	struct mii_softc *mii;
286 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
287 	struct marvell_attach_args *mva = aux;
288 	prop_dictionary_t dict;
289 	prop_data_t enaddrp = NULL;
290 	uint32_t phyaddr, maddrh, maddrl;
291 	uint8_t enaddr[ETHER_ADDR_LEN];
292 	int q;
293 
294 	aprint_naive("\n");
295 	aprint_normal(": Marvell ARMADA GbE Controller\n");
296 	memset(sc, 0, sizeof(*sc));
297 	sc->sc_dev = self;
298 	sc->sc_port = mva->mva_unit;
299 	sc->sc_iot = mva->mva_iot;
300 	sc->sc_dmat = mva->mva_dmat;
301 	mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NET);
302 	callout_init(&sc->sc_tick_ch, 0);
303 	callout_setfunc(&sc->sc_tick_ch, mvxpe_tick, sc);
304 
305 	/*
306 	 * BUS space
307 	 */
308 	if (bus_space_subregion(mva->mva_iot, mva->mva_ioh,
309 	    mva->mva_offset, mva->mva_size, &sc->sc_ioh)) {
310 		aprint_error_dev(self, "Cannot map registers\n");
311 		goto fail;
312 	}
313 	if (bus_space_subregion(mva->mva_iot, mva->mva_ioh,
314 	    mva->mva_offset + MVXPE_PORTMIB_BASE, MVXPE_PORTMIB_SIZE,
315 	    &sc->sc_mibh)) {
316 		aprint_error_dev(self,
317 		    "Cannot map destination address filter registers\n");
318 		goto fail;
319 	}
320 	sc->sc_version = MVXPE_READ(sc, MVXPE_PV);
321 	aprint_normal_dev(self, "Port Version %#x\n", sc->sc_version);
322 
323 	/*
324 	 * Buffer Manager(BM) subsystem.
325 	 */
326 	sc->sc_bm = mvxpbm_device(mva);
327 	if (sc->sc_bm == NULL) {
328 		aprint_error_dev(self, "no Buffer Manager.\n");
329 		goto fail;
330 	}
331 	aprint_normal_dev(self,
332 	    "Using Buffer Manager: %s\n", mvxpbm_xname(sc->sc_bm));
333 	aprint_normal_dev(sc->sc_dev,
334 	    "%zu kbytes managed buffer, %zu bytes * %u entries allocated.\n",
335 	    mvxpbm_buf_size(sc->sc_bm) / 1024,
336 	    mvxpbm_chunk_size(sc->sc_bm), mvxpbm_chunk_count(sc->sc_bm));
337 
338 	/*
339 	 * make sure DMA engines are in reset state
340 	 */
341 	MVXPE_WRITE(sc, MVXPE_PRXINIT, 0x00000001);
342 	MVXPE_WRITE(sc, MVXPE_PTXINIT, 0x00000001);
343 
344 	/*
345 	 * Address decoding window
346 	 */
347 	mvxpe_wininit(sc, mva->mva_tags);
348 
349 	/*
350 	 * MAC address
351 	 */
352 	dict = device_properties(self);
353 	if (dict)
354 		enaddrp = prop_dictionary_get(dict, "mac-address");
355 	if (enaddrp) {
356 		memcpy(enaddr, prop_data_data_nocopy(enaddrp), ETHER_ADDR_LEN);
357 		maddrh  = enaddr[0] << 24;
358 		maddrh |= enaddr[1] << 16;
359 		maddrh |= enaddr[2] << 8;
360 		maddrh |= enaddr[3];
361 		maddrl  = enaddr[4] << 8;
362 		maddrl |= enaddr[5];
363 		MVXPE_WRITE(sc, MVXPE_MACAH, maddrh);
364 		MVXPE_WRITE(sc, MVXPE_MACAL, maddrl);
365 	}
366 	else {
367 		/*
368 		 * even if enaddr is not found in dictionary,
369 		 * the port may be initialized by IPL program such as U-BOOT.
370 		 */
371 		maddrh = MVXPE_READ(sc, MVXPE_MACAH);
372 		maddrl = MVXPE_READ(sc, MVXPE_MACAL);
373 		if ((maddrh | maddrl) == 0) {
374 			aprint_error_dev(self, "No Ethernet address\n");
375 			return;
376 		}
377 	}
378 	sc->sc_enaddr[0] = maddrh >> 24;
379 	sc->sc_enaddr[1] = maddrh >> 16;
380 	sc->sc_enaddr[2] = maddrh >> 8;
381 	sc->sc_enaddr[3] = maddrh >> 0;
382 	sc->sc_enaddr[4] = maddrl >> 8;
383 	sc->sc_enaddr[5] = maddrl >> 0;
384 	aprint_normal_dev(self, "Ethernet address %s\n",
385 	    ether_sprintf(sc->sc_enaddr));
386 
387 	/*
388 	 * Register interrupt handlers
389 	 * XXX: handle Ethernet unit intr. and Error intr.
390 	 */
391 	mvxpe_disable_intr(sc);
392 	marvell_intr_establish(mva->mva_irq, IPL_NET, mvxpe_rxtxth_intr, sc);
393 
394 	/*
395 	 * MIB buffer allocation
396 	 */
397 	sc->sc_sysctl_mib_size =
398 	    __arraycount(mvxpe_mib_list) * sizeof(struct mvxpe_sysctl_mib);
399 	sc->sc_sysctl_mib = kmem_alloc(sc->sc_sysctl_mib_size, KM_NOSLEEP);
400 	if (sc->sc_sysctl_mib == NULL)
401 		goto fail;
402 	memset(sc->sc_sysctl_mib, 0, sc->sc_sysctl_mib_size);
403 
404 	/*
405 	 * Device DMA Buffer allocation
406 	 */
407 	for (q = 0; q < MVXPE_QUEUE_SIZE; q++) {
408 		if (mvxpe_ring_alloc_queue(sc, q) != 0)
409 			goto fail;
410 		mvxpe_ring_init_queue(sc, q);
411 	}
412 
413 	/*
414 	 * We can support 802.1Q VLAN-sized frames and jumbo
415 	 * Ethernet frames.
416 	 */
417 	sc->sc_ethercom.ec_capabilities |=
418 	    ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU;
419 	ifp->if_softc = sc;
420 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
421 	ifp->if_start = mvxpe_start;
422 	ifp->if_ioctl = mvxpe_ioctl;
423 	ifp->if_init = mvxpe_init;
424 	ifp->if_stop = mvxpe_stop;
425 	ifp->if_watchdog = mvxpe_watchdog;
426 
427 	/*
428 	 * We can do IPv4/TCPv4/UDPv4/TCPv6/UDPv6 checksums in hardware.
429 	 */
430 	ifp->if_capabilities |= IFCAP_CSUM_IPv4_Tx;
431 	ifp->if_capabilities |= IFCAP_CSUM_IPv4_Rx;
432 	ifp->if_capabilities |= IFCAP_CSUM_TCPv4_Tx;
433 	ifp->if_capabilities |= IFCAP_CSUM_TCPv4_Rx;
434 	ifp->if_capabilities |= IFCAP_CSUM_UDPv4_Tx;
435 	ifp->if_capabilities |= IFCAP_CSUM_UDPv4_Rx;
436 	ifp->if_capabilities |= IFCAP_CSUM_TCPv6_Tx;
437 	ifp->if_capabilities |= IFCAP_CSUM_TCPv6_Rx;
438 	ifp->if_capabilities |= IFCAP_CSUM_UDPv6_Tx;
439 	ifp->if_capabilities |= IFCAP_CSUM_UDPv6_Rx;
440 
441 	/*
442 	 * Initialize struct ifnet
443 	 */
444 	IFQ_SET_MAXLEN(&ifp->if_snd, max(MVXPE_TX_RING_CNT - 1, IFQ_MAXLEN));
445 	IFQ_SET_READY(&ifp->if_snd);
446 	strlcpy(ifp->if_xname, device_xname(sc->sc_dev), sizeof(ifp->if_xname));
447 
448 	/*
449 	 * Enable DMA engines and Initiazlie Device Regisers.
450 	 */
451 	MVXPE_WRITE(sc, MVXPE_PRXINIT, 0x00000000);
452 	MVXPE_WRITE(sc, MVXPE_PTXINIT, 0x00000000);
453 	MVXPE_WRITE(sc, MVXPE_PACC, MVXPE_PACC_ACCELERATIONMODE_EDM);
454 	mvxpe_sc_lock(sc); /* XXX */
455 	mvxpe_filter_setup(sc);
456 	mvxpe_sc_unlock(sc);
457 	mvxpe_initreg(ifp);
458 
459 	/*
460 	 * Now MAC is working, setup MII.
461 	 */
462 	if (mii_init == 0) {
463 		/*
464 		 * MII bus is shared by all MACs and all PHYs in SoC.
465 		 * serializing the bus access should be safe.
466 		 */
467 		mutex_init(&mii_mutex, MUTEX_DEFAULT, IPL_NET);
468 		mii_init = 1;
469 	}
470 	sc->sc_mii.mii_ifp = ifp;
471 	sc->sc_mii.mii_readreg = mvxpe_miibus_readreg;
472 	sc->sc_mii.mii_writereg = mvxpe_miibus_writereg;
473 	sc->sc_mii.mii_statchg = mvxpe_miibus_statchg;
474 
475 	sc->sc_ethercom.ec_mii = &sc->sc_mii;
476 	ifmedia_init(&sc->sc_mii.mii_media, 0,
477 	    mvxpe_mediachange, mvxpe_mediastatus);
478 	/*
479 	 * XXX: phy addressing highly depends on Board Design.
480 	 * we assume phyaddress == MAC unit number here,
481 	 * but some boards may not.
482 	 */
483 	mii_attach(self, &sc->sc_mii, 0xffffffff,
484 	    MII_PHY_ANY, sc->sc_dev->dv_unit, 0);
485 	mii = LIST_FIRST(&sc->sc_mii.mii_phys);
486 	if (mii == NULL) {
487 		aprint_error_dev(self, "no PHY found!\n");
488 		ifmedia_add(&sc->sc_mii.mii_media,
489 		    IFM_ETHER|IFM_MANUAL, 0, NULL);
490 		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL);
491 	} else {
492 		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
493 		phyaddr = MVXPE_PHYADDR_PHYAD(mii->mii_phy);
494 		MVXPE_WRITE(sc, MVXPE_PHYADDR, phyaddr);
495 		DPRINTSC(sc, 1, "PHYADDR: %#x\n", MVXPE_READ(sc, MVXPE_PHYADDR));
496 	}
497 
498 	/*
499 	 * Call MI attach routines.
500 	 */
501 	if_attach(ifp);
502 
503 	ether_ifattach(ifp, sc->sc_enaddr);
504 	ether_set_ifflags_cb(&sc->sc_ethercom, mvxpe_ifflags_cb);
505 
506 	sysctl_mvxpe_init(sc);
507 	mvxpe_evcnt_attach(sc);
508 	rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev),
509 	    RND_TYPE_NET, RND_FLAG_DEFAULT);
510 
511 	return;
512 
513 fail:
514 	for (q = 0; q < MVXPE_QUEUE_SIZE; q++)
515 		mvxpe_ring_dealloc_queue(sc, q);
516 	if (sc->sc_sysctl_mib)
517 		kmem_free(sc->sc_sysctl_mib, sc->sc_sysctl_mib_size);
518 
519 	return;
520 }
521 
522 STATIC int
523 mvxpe_evcnt_attach(struct mvxpe_softc *sc)
524 {
525 #ifdef MVXPE_EVENT_COUNTERS
526 	int q;
527 
528 	/* Master Interrupt Handler */
529 	evcnt_attach_dynamic(&sc->sc_ev.ev_i_rxtxth, EVCNT_TYPE_INTR,
530 	    NULL, device_xname(sc->sc_dev), "RxTxTH Intr.");
531 	evcnt_attach_dynamic(&sc->sc_ev.ev_i_rxtx, EVCNT_TYPE_INTR,
532 	    NULL, device_xname(sc->sc_dev), "RxTx Intr.");
533 	evcnt_attach_dynamic(&sc->sc_ev.ev_i_misc, EVCNT_TYPE_INTR,
534 	    NULL, device_xname(sc->sc_dev), "MISC Intr.");
535 
536 	/* RXTXTH Interrupt */
537 	evcnt_attach_dynamic(&sc->sc_ev.ev_rxtxth_txerr, EVCNT_TYPE_INTR,
538 	    NULL, device_xname(sc->sc_dev), "RxTxTH Tx error summary");
539 
540 	/* MISC Interrupt */
541 	evcnt_attach_dynamic(&sc->sc_ev.ev_misc_phystatuschng, EVCNT_TYPE_INTR,
542 	    NULL, device_xname(sc->sc_dev), "MISC phy status changed");
543 	evcnt_attach_dynamic(&sc->sc_ev.ev_misc_linkchange, EVCNT_TYPE_INTR,
544 	    NULL, device_xname(sc->sc_dev), "MISC link status changed");
545 	evcnt_attach_dynamic(&sc->sc_ev.ev_misc_iae, EVCNT_TYPE_INTR,
546 	    NULL, device_xname(sc->sc_dev), "MISC internal address error");
547 	evcnt_attach_dynamic(&sc->sc_ev.ev_misc_rxoverrun, EVCNT_TYPE_INTR,
548 	    NULL, device_xname(sc->sc_dev), "MISC Rx FIFO overrun");
549 	evcnt_attach_dynamic(&sc->sc_ev.ev_misc_rxcrc, EVCNT_TYPE_INTR,
550 	    NULL, device_xname(sc->sc_dev), "MISC Rx CRC error");
551 	evcnt_attach_dynamic(&sc->sc_ev.ev_misc_rxlargepacket, EVCNT_TYPE_INTR,
552 	    NULL, device_xname(sc->sc_dev), "MISC Rx too large frame");
553 	evcnt_attach_dynamic(&sc->sc_ev.ev_misc_txunderrun, EVCNT_TYPE_INTR,
554 	    NULL, device_xname(sc->sc_dev), "MISC Tx FIFO underrun");
555 	evcnt_attach_dynamic(&sc->sc_ev.ev_misc_prbserr, EVCNT_TYPE_INTR,
556 	    NULL, device_xname(sc->sc_dev), "MISC SERDES loopback test err");
557 	evcnt_attach_dynamic(&sc->sc_ev.ev_misc_srse, EVCNT_TYPE_INTR,
558 	    NULL, device_xname(sc->sc_dev), "MISC SERDES sync error");
559 	evcnt_attach_dynamic(&sc->sc_ev.ev_misc_txreq, EVCNT_TYPE_INTR,
560 	    NULL, device_xname(sc->sc_dev), "MISC Tx resource erorr");
561 
562 	/* RxTx Interrupt */
563 	evcnt_attach_dynamic(&sc->sc_ev.ev_rxtx_rreq, EVCNT_TYPE_INTR,
564 	    NULL, device_xname(sc->sc_dev), "RxTx Rx resource erorr");
565 	evcnt_attach_dynamic(&sc->sc_ev.ev_rxtx_rpq, EVCNT_TYPE_INTR,
566 	    NULL, device_xname(sc->sc_dev), "RxTx Rx pakcet");
567 	evcnt_attach_dynamic(&sc->sc_ev.ev_rxtx_tbrq, EVCNT_TYPE_INTR,
568 	    NULL, device_xname(sc->sc_dev), "RxTx Tx complete");
569 	evcnt_attach_dynamic(&sc->sc_ev.ev_rxtx_rxtxth, EVCNT_TYPE_INTR,
570 	    NULL, device_xname(sc->sc_dev), "RxTx RxTxTH summary");
571 	evcnt_attach_dynamic(&sc->sc_ev.ev_rxtx_txerr, EVCNT_TYPE_INTR,
572 	    NULL, device_xname(sc->sc_dev), "RxTx Tx error summary");
573 	evcnt_attach_dynamic(&sc->sc_ev.ev_rxtx_misc, EVCNT_TYPE_INTR,
574 	    NULL, device_xname(sc->sc_dev), "RxTx MISC summary");
575 
576 	/* Link */
577 	evcnt_attach_dynamic(&sc->sc_ev.ev_link_up, EVCNT_TYPE_MISC,
578 	    NULL, device_xname(sc->sc_dev), "link up");
579 	evcnt_attach_dynamic(&sc->sc_ev.ev_link_down, EVCNT_TYPE_MISC,
580 	    NULL, device_xname(sc->sc_dev), "link down");
581 
582 	/* Rx Descriptor */
583 	evcnt_attach_dynamic(&sc->sc_ev.ev_rxd_ce, EVCNT_TYPE_MISC,
584 	    NULL, device_xname(sc->sc_dev), "Rx CRC error counter");
585 	evcnt_attach_dynamic(&sc->sc_ev.ev_rxd_or, EVCNT_TYPE_MISC,
586 	    NULL, device_xname(sc->sc_dev), "Rx FIFO overrun counter");
587 	evcnt_attach_dynamic(&sc->sc_ev.ev_rxd_mf, EVCNT_TYPE_MISC,
588 	    NULL, device_xname(sc->sc_dev), "Rx too large frame counter");
589 	evcnt_attach_dynamic(&sc->sc_ev.ev_rxd_re, EVCNT_TYPE_MISC,
590 	    NULL, device_xname(sc->sc_dev), "Rx resource error counter");
591 	evcnt_attach_dynamic(&sc->sc_ev.ev_rxd_scat, EVCNT_TYPE_MISC,
592 	    NULL, device_xname(sc->sc_dev), "Rx unexpected scatter bufs");
593 
594 	/* Tx Descriptor */
595 	evcnt_attach_dynamic(&sc->sc_ev.ev_txd_lc, EVCNT_TYPE_MISC,
596 	    NULL, device_xname(sc->sc_dev), "Tx late collision counter");
597 	evcnt_attach_dynamic(&sc->sc_ev.ev_txd_rl, EVCNT_TYPE_MISC,
598 	    NULL, device_xname(sc->sc_dev), "Tx excess. collision counter");
599 	evcnt_attach_dynamic(&sc->sc_ev.ev_txd_ur, EVCNT_TYPE_MISC,
600 	    NULL, device_xname(sc->sc_dev), "Tx FIFO underrun counter");
601 	evcnt_attach_dynamic(&sc->sc_ev.ev_txd_oth, EVCNT_TYPE_MISC,
602 	    NULL, device_xname(sc->sc_dev), "Tx unkonwn erorr counter");
603 
604 	/* Status Registers */
605 	evcnt_attach_dynamic(&sc->sc_ev.ev_reg_pdfc, EVCNT_TYPE_MISC,
606 	    NULL, device_xname(sc->sc_dev), "Rx discard counter");
607 	evcnt_attach_dynamic(&sc->sc_ev.ev_reg_pofc, EVCNT_TYPE_MISC,
608 	    NULL, device_xname(sc->sc_dev), "Rx overrun counter");
609 	evcnt_attach_dynamic(&sc->sc_ev.ev_reg_txbadfcs, EVCNT_TYPE_MISC,
610 	    NULL, device_xname(sc->sc_dev), "Tx bad FCS counter");
611 	evcnt_attach_dynamic(&sc->sc_ev.ev_reg_txdropped, EVCNT_TYPE_MISC,
612 	    NULL, device_xname(sc->sc_dev), "Tx dorpped counter");
613 	evcnt_attach_dynamic(&sc->sc_ev.ev_reg_lpic, EVCNT_TYPE_MISC,
614 	    NULL, device_xname(sc->sc_dev), "LP_IDLE counter");
615 
616 	/* Device Driver Errors */
617 	evcnt_attach_dynamic(&sc->sc_ev.ev_drv_wdogsoft, EVCNT_TYPE_MISC,
618 	    NULL, device_xname(sc->sc_dev), "watchdog timer expired");
619 	evcnt_attach_dynamic(&sc->sc_ev.ev_drv_txerr, EVCNT_TYPE_MISC,
620 	    NULL, device_xname(sc->sc_dev), "Tx descriptor alloc failed");
621 #define MVXPE_QUEUE_DESC(q) "Rx success in queue " # q
622 	for (q = 0; q < MVXPE_QUEUE_SIZE; q++) {
623 		static const char *rxq_desc[] = {
624 			MVXPE_QUEUE_DESC(0), MVXPE_QUEUE_DESC(1),
625 			MVXPE_QUEUE_DESC(2), MVXPE_QUEUE_DESC(3),
626 			MVXPE_QUEUE_DESC(4), MVXPE_QUEUE_DESC(5),
627 			MVXPE_QUEUE_DESC(6), MVXPE_QUEUE_DESC(7),
628 		};
629 		evcnt_attach_dynamic(&sc->sc_ev.ev_drv_rxq[q], EVCNT_TYPE_MISC,
630 		    NULL, device_xname(sc->sc_dev), rxq_desc[q]);
631 	}
632 #undef MVXPE_QUEUE_DESC
633 #define MVXPE_QUEUE_DESC(q) "Tx success in queue " # q
634 	for (q = 0; q < MVXPE_QUEUE_SIZE; q++) {
635 		static const char *txq_desc[] = {
636 			MVXPE_QUEUE_DESC(0), MVXPE_QUEUE_DESC(1),
637 			MVXPE_QUEUE_DESC(2), MVXPE_QUEUE_DESC(3),
638 			MVXPE_QUEUE_DESC(4), MVXPE_QUEUE_DESC(5),
639 			MVXPE_QUEUE_DESC(6), MVXPE_QUEUE_DESC(7),
640 		};
641 		evcnt_attach_dynamic(&sc->sc_ev.ev_drv_txq[q], EVCNT_TYPE_MISC,
642 		    NULL, device_xname(sc->sc_dev), txq_desc[q]);
643 	}
644 #undef MVXPE_QUEUE_DESC
645 #define MVXPE_QUEUE_DESC(q) "Rx error in queue " # q
646 	for (q = 0; q < MVXPE_QUEUE_SIZE; q++) {
647 		static const char *rxqe_desc[] = {
648 			MVXPE_QUEUE_DESC(0), MVXPE_QUEUE_DESC(1),
649 			MVXPE_QUEUE_DESC(2), MVXPE_QUEUE_DESC(3),
650 			MVXPE_QUEUE_DESC(4), MVXPE_QUEUE_DESC(5),
651 			MVXPE_QUEUE_DESC(6), MVXPE_QUEUE_DESC(7),
652 		};
653 		evcnt_attach_dynamic(&sc->sc_ev.ev_drv_rxqe[q], EVCNT_TYPE_MISC,
654 		    NULL, device_xname(sc->sc_dev), rxqe_desc[q]);
655 	}
656 #undef MVXPE_QUEUE_DESC
657 #define MVXPE_QUEUE_DESC(q) "Tx error in queue " # q
658 	for (q = 0; q < MVXPE_QUEUE_SIZE; q++) {
659 		static const char *txqe_desc[] = {
660 			MVXPE_QUEUE_DESC(0), MVXPE_QUEUE_DESC(1),
661 			MVXPE_QUEUE_DESC(2), MVXPE_QUEUE_DESC(3),
662 			MVXPE_QUEUE_DESC(4), MVXPE_QUEUE_DESC(5),
663 			MVXPE_QUEUE_DESC(6), MVXPE_QUEUE_DESC(7),
664 		};
665 		evcnt_attach_dynamic(&sc->sc_ev.ev_drv_txqe[q], EVCNT_TYPE_MISC,
666 		    NULL, device_xname(sc->sc_dev), txqe_desc[q]);
667 	}
668 #undef MVXPE_QUEUE_DESC
669 
670 #endif /* MVXPE_EVENT_COUNTERS */
671 	return 0;
672 }
673 
674 STATIC void
675 mvxpe_sc_lock(struct mvxpe_softc *sc)
676 {
677 	mutex_enter(&sc->sc_mtx);
678 }
679 
680 STATIC void
681 mvxpe_sc_unlock(struct mvxpe_softc *sc)
682 {
683 	mutex_exit(&sc->sc_mtx);
684 }
685 
686 /*
687  * MII
688  */
689 STATIC int
690 mvxpe_miibus_readreg(device_t dev, int phy, int reg)
691 {
692 	struct mvxpe_softc *sc = device_private(dev);
693 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
694 	uint32_t smi, val;
695 	int i;
696 
697 	mutex_enter(&mii_mutex);
698 
699 	for (i = 0; i < MVXPE_PHY_TIMEOUT; i++) {
700 		DELAY(1);
701 		if (!(MVXPE_READ(sc, MVXPE_SMI) & MVXPE_SMI_BUSY))
702 			break;
703 	}
704 	if (i == MVXPE_PHY_TIMEOUT) {
705 		aprint_error_ifnet(ifp, "SMI busy timeout\n");
706 		mutex_exit(&mii_mutex);
707 		return -1;
708 	}
709 
710 	smi =
711 	    MVXPE_SMI_PHYAD(phy) | MVXPE_SMI_REGAD(reg) | MVXPE_SMI_OPCODE_READ;
712 	MVXPE_WRITE(sc, MVXPE_SMI, smi);
713 
714 	for (i = 0; i < MVXPE_PHY_TIMEOUT; i++) {
715 		DELAY(1);
716 		smi = MVXPE_READ(sc, MVXPE_SMI);
717 		if (smi & MVXPE_SMI_READVALID)
718 			break;
719 	}
720 
721 	mutex_exit(&mii_mutex);
722 
723 	DPRINTDEV(dev, 9, "i=%d, timeout=%d\n", i, MVXPE_PHY_TIMEOUT);
724 
725 	val = smi & MVXPE_SMI_DATA_MASK;
726 
727 	DPRINTDEV(dev, 9, "phy=%d, reg=%#x, val=%#x\n", phy, reg, val);
728 
729 	return val;
730 }
731 
732 STATIC void
733 mvxpe_miibus_writereg(device_t dev, int phy, int reg, int val)
734 {
735 	struct mvxpe_softc *sc = device_private(dev);
736 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
737 	uint32_t smi;
738 	int i;
739 
740 	DPRINTDEV(dev, 9, "phy=%d reg=%#x val=%#x\n", phy, reg, val);
741 
742 	mutex_enter(&mii_mutex);
743 
744 	for (i = 0; i < MVXPE_PHY_TIMEOUT; i++) {
745 		DELAY(1);
746 		if (!(MVXPE_READ(sc, MVXPE_SMI) & MVXPE_SMI_BUSY))
747 			break;
748 	}
749 	if (i == MVXPE_PHY_TIMEOUT) {
750 		aprint_error_ifnet(ifp, "SMI busy timeout\n");
751 		mutex_exit(&mii_mutex);
752 		return;
753 	}
754 
755 	smi = MVXPE_SMI_PHYAD(phy) | MVXPE_SMI_REGAD(reg) |
756 	    MVXPE_SMI_OPCODE_WRITE | (val & MVXPE_SMI_DATA_MASK);
757 	MVXPE_WRITE(sc, MVXPE_SMI, smi);
758 
759 	for (i = 0; i < MVXPE_PHY_TIMEOUT; i++) {
760 		DELAY(1);
761 		if (!(MVXPE_READ(sc, MVXPE_SMI) & MVXPE_SMI_BUSY))
762 			break;
763 	}
764 
765 	mutex_exit(&mii_mutex);
766 
767 	if (i == MVXPE_PHY_TIMEOUT)
768 		aprint_error_ifnet(ifp, "phy write timed out\n");
769 }
770 
771 STATIC void
772 mvxpe_miibus_statchg(struct ifnet *ifp)
773 {
774 
775 	/* nothing to do */
776 }
777 
778 /*
779  * Address Decoding Window
780  */
781 STATIC void
782 mvxpe_wininit(struct mvxpe_softc *sc, enum marvell_tags *tags)
783 {
784 	device_t pdev = device_parent(sc->sc_dev);
785 	uint64_t base;
786 	uint32_t en, ac, size;
787 	int window, target, attr, rv, i;
788 
789 	/* First disable all address decode windows */
790 	en = MVXPE_BARE_EN_MASK;
791 	MVXPE_WRITE(sc, MVXPE_BARE, en);
792 
793 	ac = 0;
794 	for (window = 0, i = 0;
795 	    tags[i] != MARVELL_TAG_UNDEFINED && window < MVXPE_NWINDOW; i++) {
796 		rv = marvell_winparams_by_tag(pdev, tags[i],
797 		    &target, &attr, &base, &size);
798 		if (rv != 0 || size == 0)
799 			continue;
800 
801 		if (base > 0xffffffffULL) {
802 			if (window >= MVXPE_NREMAP) {
803 				aprint_error_dev(sc->sc_dev,
804 				    "can't remap window %d\n", window);
805 				continue;
806 			}
807 			MVXPE_WRITE(sc, MVXPE_HA(window),
808 			    (base >> 32) & 0xffffffff);
809 		}
810 
811 		MVXPE_WRITE(sc, MVXPE_BASEADDR(window),
812 		    MVXPE_BASEADDR_TARGET(target)	|
813 		    MVXPE_BASEADDR_ATTR(attr)		|
814 		    MVXPE_BASEADDR_BASE(base));
815 		MVXPE_WRITE(sc, MVXPE_S(window), MVXPE_S_SIZE(size));
816 
817 		DPRINTSC(sc, 1, "Window %d Base 0x%016llx: Size 0x%08x\n",
818 				window, base, size);
819 
820 		en &= ~(1 << window);
821 		/* set full access (r/w) */
822 		ac |= MVXPE_EPAP_EPAR(window, MVXPE_EPAP_AC_FA);
823 		window++;
824 	}
825 	/* allow to access decode window */
826 	MVXPE_WRITE(sc, MVXPE_EPAP, ac);
827 
828 	MVXPE_WRITE(sc, MVXPE_BARE, en);
829 }
830 
831 /*
832  * Device Register Initialization
833  *  reset device registers to device driver default value.
834  *  the device is not enabled here.
835  */
836 STATIC int
837 mvxpe_initreg(struct ifnet *ifp)
838 {
839 	struct mvxpe_softc *sc = ifp->if_softc;
840 	int serdes = 0;
841 	uint32_t reg;
842 	int q, i;
843 
844 	DPRINTIFNET(ifp, 1, "initializing device register\n");
845 
846 	/* Init TX/RX Queue Registers */
847 	for (q = 0; q < MVXPE_QUEUE_SIZE; q++) {
848 		mvxpe_rx_lockq(sc, q);
849 		if (mvxpe_rx_queue_init(ifp, q) != 0) {
850 			aprint_error_ifnet(ifp,
851 			    "initialization failed: cannot initialize queue\n");
852 			mvxpe_rx_unlockq(sc, q);
853 			mvxpe_tx_unlockq(sc, q);
854 			return ENOBUFS;
855 		}
856 		mvxpe_rx_unlockq(sc, q);
857 
858 		mvxpe_tx_lockq(sc, q);
859 		if (mvxpe_tx_queue_init(ifp, q) != 0) {
860 			aprint_error_ifnet(ifp,
861 			    "initialization failed: cannot initialize queue\n");
862 			mvxpe_rx_unlockq(sc, q);
863 			mvxpe_tx_unlockq(sc, q);
864 			return ENOBUFS;
865 		}
866 		mvxpe_tx_unlockq(sc, q);
867 	}
868 
869 	/* Tx MTU Limit */
870 	MVXPE_WRITE(sc, MVXPE_TXMTU, MVXPE_MTU);
871 
872 	/* Check SGMII or SERDES(asume IPL/U-BOOT initialize this) */
873 	reg = MVXPE_READ(sc, MVXPE_PMACC0);
874 	if ((reg & MVXPE_PMACC0_PORTTYPE) != 0)
875 		serdes = 1;
876 
877 	/* Ethernet Unit Control */
878 	reg = MVXPE_READ(sc, MVXPE_EUC);
879 	reg |= MVXPE_EUC_POLLING;
880 	MVXPE_WRITE(sc, MVXPE_EUC, reg);
881 
882 	/* Auto Negotiation */
883 	reg  = MVXPE_PANC_MUSTSET;	/* must write 0x1 */
884 	reg |= MVXPE_PANC_FORCELINKFAIL;/* force link state down */
885 	reg |= MVXPE_PANC_ANSPEEDEN;	/* interface speed negotiation */
886 	reg |= MVXPE_PANC_ANDUPLEXEN;	/* negotiate duplex mode */
887 	if (serdes) {
888 		reg |= MVXPE_PANC_INBANDANEN; /* In Band negotiation */
889 		reg |= MVXPE_PANC_INBANDANBYPASSEN; /* bypass negotiation */
890 		reg |= MVXPE_PANC_SETFULLDX; /* set full-duplex on failure */
891 	}
892 	MVXPE_WRITE(sc, MVXPE_PANC, reg);
893 
894 	/* EEE: Low Power Idle */
895 	reg  = MVXPE_LPIC0_LILIMIT(MVXPE_LPI_LI);
896 	reg |= MVXPE_LPIC0_TSLIMIT(MVXPE_LPI_TS);
897 	MVXPE_WRITE(sc, MVXPE_LPIC0, reg);
898 
899 	reg  = MVXPE_LPIC1_TWLIMIT(MVXPE_LPI_TS);
900 	MVXPE_WRITE(sc, MVXPE_LPIC1, reg);
901 
902 	reg = MVXPE_LPIC2_MUSTSET;
903 	MVXPE_WRITE(sc, MVXPE_LPIC2, reg);
904 
905 	/* Port MAC Control set 0 */
906 	reg  = MVXPE_PMACC0_MUSTSET;	/* must write 0x1 */
907 	reg &= ~MVXPE_PMACC0_PORTEN;	/* port is still disabled */
908 	reg |= MVXPE_PMACC0_FRAMESIZELIMIT(MVXPE_MRU);
909 	if (serdes)
910 		reg |= MVXPE_PMACC0_PORTTYPE;
911 	MVXPE_WRITE(sc, MVXPE_PMACC0, reg);
912 
913 	/* Port MAC Control set 1 is only used for loop-back test */
914 
915 	/* Port MAC Control set 2 */
916 	reg = MVXPE_READ(sc, MVXPE_PMACC2);
917 	reg &= (MVXPE_PMACC2_PCSEN | MVXPE_PMACC2_RGMIIEN);
918 	reg |= MVXPE_PMACC2_MUSTSET;
919 	MVXPE_WRITE(sc, MVXPE_PMACC2, reg);
920 
921 	/* Port MAC Control set 3 is used for IPG tune */
922 
923 	/* Port MAC Control set 4 is not used */
924 
925 	/* Port Configuration Extended: enable Tx CRC generation */
926 	reg = MVXPE_READ(sc, MVXPE_PXCX);
927 	reg &= ~MVXPE_PXCX_TXCRCDIS;
928 	MVXPE_WRITE(sc, MVXPE_PXCX, reg);
929 
930 	/* clear MIB counter registers(clear by read) */
931 	for (i = 0; i < __arraycount(mvxpe_mib_list); i++)
932 		MVXPE_READ_MIB(sc, (mvxpe_mib_list[i].regnum));
933 
934 	/* Set SDC register except IPGINT bits */
935 	reg  = MVXPE_SDC_RXBSZ_16_64BITWORDS;
936 	reg |= MVXPE_SDC_TXBSZ_16_64BITWORDS;
937 	reg |= MVXPE_SDC_BLMR;
938 	reg |= MVXPE_SDC_BLMT;
939 	MVXPE_WRITE(sc, MVXPE_SDC, reg);
940 
941 	return 0;
942 }
943 
944 /*
945  * Descriptor Ring Controls for each of queues
946  */
947 STATIC void *
948 mvxpe_dma_memalloc(struct mvxpe_softc *sc, bus_dmamap_t *map, size_t size)
949 {
950 	bus_dma_segment_t segs;
951 	void *kva = NULL;
952 	int nsegs;
953 
954 	/*
955 	 * Allocate the descriptor queues.
956 	 * struct mvxpe_ring_data contians array of descriptor per queue.
957 	 */
958 	if (bus_dmamem_alloc(sc->sc_dmat,
959 	    size, PAGE_SIZE, 0, &segs, 1, &nsegs, BUS_DMA_NOWAIT)) {
960 		aprint_error_dev(sc->sc_dev,
961 		    "can't alloc device memory (%zu bytes)\n", size);
962 		return NULL;
963 	}
964 	if (bus_dmamem_map(sc->sc_dmat,
965 	    &segs, nsegs, size, &kva, BUS_DMA_NOWAIT)) {
966 		aprint_error_dev(sc->sc_dev,
967 		    "can't map dma buffers (%zu bytes)\n", size);
968 		goto fail1;
969 	}
970 
971 	if (bus_dmamap_create(sc->sc_dmat,
972 	    size, 1, size, 0, BUS_DMA_NOWAIT, map)) {
973 		aprint_error_dev(sc->sc_dev, "can't create dma map\n");
974 		goto fail2;
975 	}
976 	if (bus_dmamap_load(sc->sc_dmat,
977 	    *map, kva, size, NULL, BUS_DMA_NOWAIT)) {
978 		aprint_error_dev(sc->sc_dev, "can't load dma map\n");
979 		goto fail3;
980 	}
981 	memset(kva, 0, size);
982 	return kva;
983 
984 fail3:
985 	bus_dmamap_destroy(sc->sc_dmat, *map);
986 	memset(map, 0, sizeof(*map));
987 fail2:
988 	bus_dmamem_unmap(sc->sc_dmat, kva, size);
989 fail1:
990 	bus_dmamem_free(sc->sc_dmat, &segs, nsegs);
991 	return NULL;
992 }
993 
994 STATIC int
995 mvxpe_ring_alloc_queue(struct mvxpe_softc *sc, int q)
996 {
997 	struct mvxpe_rx_ring *rx = MVXPE_RX_RING(sc, q);
998 	struct mvxpe_tx_ring *tx = MVXPE_TX_RING(sc, q);
999 
1000 	/*
1001 	 * MVXPE_RX_RING_CNT and MVXPE_TX_RING_CNT is a hard limit of
1002 	 * queue length. real queue length is limited by
1003 	 * sc->sc_rx_ring[q].rx_queue_len and sc->sc_tx_ring[q].tx_queue_len.
1004 	 *
1005 	 * because descriptor ring reallocation needs reprogramming of
1006 	 * DMA registers, we allocate enough descriptor for hard limit
1007 	 * of queue length.
1008 	 */
1009 	rx->rx_descriptors =
1010 	    mvxpe_dma_memalloc(sc, &rx->rx_descriptors_map,
1011 		(sizeof(struct mvxpe_rx_desc) * MVXPE_RX_RING_CNT));
1012 	if (rx->rx_descriptors == NULL)
1013 		goto fail;
1014 
1015 	tx->tx_descriptors =
1016 	    mvxpe_dma_memalloc(sc, &tx->tx_descriptors_map,
1017 		(sizeof(struct mvxpe_tx_desc) * MVXPE_TX_RING_CNT));
1018 	if (tx->tx_descriptors == NULL)
1019 		goto fail;
1020 
1021 	return 0;
1022 fail:
1023 	mvxpe_ring_dealloc_queue(sc, q);
1024 	aprint_error_dev(sc->sc_dev, "DMA Ring buffer allocation failure.\n");
1025 	return ENOMEM;
1026 }
1027 
1028 STATIC void
1029 mvxpe_ring_dealloc_queue(struct mvxpe_softc *sc, int q)
1030 {
1031 	struct mvxpe_rx_ring *rx = MVXPE_RX_RING(sc, q);
1032 	struct mvxpe_tx_ring *tx = MVXPE_TX_RING(sc, q);
1033 	bus_dma_segment_t *segs;
1034 	bus_size_t size;
1035 	void *kva;
1036 	int nsegs;
1037 
1038 	/* Rx */
1039 	kva = (void *)MVXPE_RX_RING_MEM_VA(sc, q);
1040 	if (kva) {
1041 		segs = MVXPE_RX_RING_MEM_MAP(sc, q)->dm_segs;
1042 		nsegs = MVXPE_RX_RING_MEM_MAP(sc, q)->dm_nsegs;
1043 		size = MVXPE_RX_RING_MEM_MAP(sc, q)->dm_mapsize;
1044 
1045 		bus_dmamap_unload(sc->sc_dmat, MVXPE_RX_RING_MEM_MAP(sc, q));
1046 		bus_dmamap_destroy(sc->sc_dmat, MVXPE_RX_RING_MEM_MAP(sc, q));
1047 		bus_dmamem_unmap(sc->sc_dmat, kva, size);
1048 		bus_dmamem_free(sc->sc_dmat, segs, nsegs);
1049 	}
1050 
1051 	/* Tx */
1052 	kva = (void *)MVXPE_TX_RING_MEM_VA(sc, q);
1053 	if (kva) {
1054 		segs = MVXPE_TX_RING_MEM_MAP(sc, q)->dm_segs;
1055 		nsegs = MVXPE_TX_RING_MEM_MAP(sc, q)->dm_nsegs;
1056 		size = MVXPE_TX_RING_MEM_MAP(sc, q)->dm_mapsize;
1057 
1058 		bus_dmamap_unload(sc->sc_dmat, MVXPE_TX_RING_MEM_MAP(sc, q));
1059 		bus_dmamap_destroy(sc->sc_dmat, MVXPE_TX_RING_MEM_MAP(sc, q));
1060 		bus_dmamem_unmap(sc->sc_dmat, kva, size);
1061 		bus_dmamem_free(sc->sc_dmat, segs, nsegs);
1062 	}
1063 
1064 	/* Clear doungling pointers all */
1065 	memset(rx, 0, sizeof(*rx));
1066 	memset(tx, 0, sizeof(*tx));
1067 }
1068 
1069 STATIC void
1070 mvxpe_ring_init_queue(struct mvxpe_softc *sc, int q)
1071 {
1072 	struct mvxpe_rx_desc *rxd = MVXPE_RX_RING_MEM_VA(sc, q);
1073 	struct mvxpe_tx_desc *txd = MVXPE_TX_RING_MEM_VA(sc, q);
1074 	struct mvxpe_rx_ring *rx = MVXPE_RX_RING(sc, q);
1075 	struct mvxpe_tx_ring *tx = MVXPE_TX_RING(sc, q);
1076 	static const int rx_default_queue_len[] = {
1077 		MVXPE_RX_QUEUE_LIMIT_0, MVXPE_RX_QUEUE_LIMIT_1,
1078 		MVXPE_RX_QUEUE_LIMIT_2, MVXPE_RX_QUEUE_LIMIT_3,
1079 		MVXPE_RX_QUEUE_LIMIT_4, MVXPE_RX_QUEUE_LIMIT_5,
1080 		MVXPE_RX_QUEUE_LIMIT_6, MVXPE_RX_QUEUE_LIMIT_7,
1081 	};
1082 	static const int tx_default_queue_len[] = {
1083 		MVXPE_TX_QUEUE_LIMIT_0, MVXPE_TX_QUEUE_LIMIT_1,
1084 		MVXPE_TX_QUEUE_LIMIT_2, MVXPE_TX_QUEUE_LIMIT_3,
1085 		MVXPE_TX_QUEUE_LIMIT_4, MVXPE_TX_QUEUE_LIMIT_5,
1086 		MVXPE_TX_QUEUE_LIMIT_6, MVXPE_TX_QUEUE_LIMIT_7,
1087 	};
1088 	extern uint32_t mvTclk;
1089 	int i;
1090 
1091 	/* Rx handle */
1092 	for (i = 0; i < MVXPE_RX_RING_CNT; i++) {
1093 		MVXPE_RX_DESC(sc, q, i) = &rxd[i];
1094 		MVXPE_RX_DESC_OFF(sc, q, i) = sizeof(struct mvxpe_rx_desc) * i;
1095 		MVXPE_RX_PKTBUF(sc, q, i) = NULL;
1096 	}
1097 	mutex_init(&rx->rx_ring_mtx, MUTEX_DEFAULT, IPL_NET);
1098 	rx->rx_dma = rx->rx_cpu = 0;
1099 	rx->rx_queue_len = rx_default_queue_len[q];
1100 	if (rx->rx_queue_len > MVXPE_RX_RING_CNT)
1101 		rx->rx_queue_len = MVXPE_RX_RING_CNT;
1102 	rx->rx_queue_th_received = rx->rx_queue_len / MVXPE_RXTH_RATIO;
1103 	rx->rx_queue_th_free = rx->rx_queue_len / MVXPE_RXTH_REFILL_RATIO;
1104 	rx->rx_queue_th_time = (mvTclk / 1000) / 2; /* 0.5 [ms] */
1105 
1106 	/* Tx handle */
1107 	for (i = 0; i < MVXPE_TX_RING_CNT; i++) {
1108 		MVXPE_TX_DESC(sc, q, i) = &txd[i];
1109 		MVXPE_TX_DESC_OFF(sc, q, i) = sizeof(struct mvxpe_tx_desc) * i;
1110 		MVXPE_TX_MBUF(sc, q, i) = NULL;
1111 		/* Tx handle needs DMA map for busdma_load_mbuf() */
1112 		if (bus_dmamap_create(sc->sc_dmat,
1113 		    mvxpbm_chunk_size(sc->sc_bm),
1114 		    MVXPE_TX_SEGLIMIT, mvxpbm_chunk_size(sc->sc_bm), 0,
1115 		    BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,
1116 		    &MVXPE_TX_MAP(sc, q, i))) {
1117 			aprint_error_dev(sc->sc_dev,
1118 			    "can't create dma map (tx ring %d)\n", i);
1119 		}
1120 	}
1121 	mutex_init(&tx->tx_ring_mtx, MUTEX_DEFAULT, IPL_NET);
1122 	tx->tx_dma = tx->tx_cpu = 0;
1123 	tx->tx_queue_len = tx_default_queue_len[q];
1124 	if (tx->tx_queue_len > MVXPE_TX_RING_CNT)
1125 		tx->tx_queue_len = MVXPE_TX_RING_CNT;
1126        	tx->tx_used = 0;
1127 	tx->tx_queue_th_free = tx->tx_queue_len / MVXPE_TXTH_RATIO;
1128 }
1129 
1130 STATIC void
1131 mvxpe_ring_flush_queue(struct mvxpe_softc *sc, int q)
1132 {
1133 	struct mvxpe_rx_ring *rx = MVXPE_RX_RING(sc, q);
1134 	struct mvxpe_tx_ring *tx = MVXPE_TX_RING(sc, q);
1135 	int i;
1136 
1137 	KASSERT_RX_MTX(sc, q);
1138 	KASSERT_TX_MTX(sc, q);
1139 
1140 	/* Rx handle */
1141 	for (i = 0; i < MVXPE_RX_RING_CNT; i++) {
1142 		if (MVXPE_RX_PKTBUF(sc, q, i) == NULL)
1143 			continue;
1144 		mvxpbm_free_chunk(MVXPE_RX_PKTBUF(sc, q, i));
1145 		MVXPE_RX_PKTBUF(sc, q, i) = NULL;
1146 	}
1147 	rx->rx_dma = rx->rx_cpu = 0;
1148 
1149 	/* Tx handle */
1150 	for (i = 0; i < MVXPE_TX_RING_CNT; i++) {
1151 		if (MVXPE_TX_MBUF(sc, q, i) == NULL)
1152 			continue;
1153 		bus_dmamap_unload(sc->sc_dmat, MVXPE_TX_MAP(sc, q, i));
1154 		m_freem(MVXPE_TX_MBUF(sc, q, i));
1155 		MVXPE_TX_MBUF(sc, q, i) = NULL;
1156 	}
1157 	tx->tx_dma = tx->tx_cpu = 0;
1158        	tx->tx_used = 0;
1159 }
1160 
1161 STATIC void
1162 mvxpe_ring_sync_rx(struct mvxpe_softc *sc, int q, int idx, int count, int ops)
1163 {
1164 	int wrap;
1165 
1166 	KASSERT_RX_MTX(sc, q);
1167 	KASSERT(count > 0 && count <= MVXPE_RX_RING_CNT);
1168 	KASSERT(idx >= 0 && idx < MVXPE_RX_RING_CNT);
1169 
1170 	wrap = (idx + count) - MVXPE_RX_RING_CNT;
1171 	if (wrap > 0) {
1172 		count -= wrap;
1173 		KASSERT(count > 0);
1174 		bus_dmamap_sync(sc->sc_dmat, MVXPE_RX_RING_MEM_MAP(sc, q),
1175 		    0, sizeof(struct mvxpe_rx_desc) * wrap, ops);
1176 	}
1177 	bus_dmamap_sync(sc->sc_dmat, MVXPE_RX_RING_MEM_MAP(sc, q),
1178 	    MVXPE_RX_DESC_OFF(sc, q, idx),
1179 	    sizeof(struct mvxpe_rx_desc) * count, ops);
1180 }
1181 
1182 STATIC void
1183 mvxpe_ring_sync_tx(struct mvxpe_softc *sc, int q, int idx, int count, int ops)
1184 {
1185 	int wrap = 0;
1186 
1187 	KASSERT_TX_MTX(sc, q);
1188 	KASSERT(count > 0 && count <= MVXPE_TX_RING_CNT);
1189 	KASSERT(idx >= 0 && idx < MVXPE_TX_RING_CNT);
1190 
1191 	wrap = (idx + count) - MVXPE_TX_RING_CNT;
1192 	if (wrap > 0)  {
1193 		count -= wrap;
1194 		bus_dmamap_sync(sc->sc_dmat, MVXPE_TX_RING_MEM_MAP(sc, q),
1195 		    0, sizeof(struct mvxpe_tx_desc) * wrap, ops);
1196 	}
1197 	bus_dmamap_sync(sc->sc_dmat, MVXPE_TX_RING_MEM_MAP(sc, q),
1198 	    MVXPE_TX_DESC_OFF(sc, q, idx),
1199 	    sizeof(struct mvxpe_tx_desc) * count, ops);
1200 }
1201 
1202 /*
1203  * Rx/Tx Queue Control
1204  */
1205 STATIC int
1206 mvxpe_rx_queue_init(struct ifnet *ifp, int q)
1207 {
1208 	struct mvxpe_softc *sc = ifp->if_softc;
1209 	uint32_t reg;
1210 
1211 	KASSERT_RX_MTX(sc, q);
1212 	KASSERT(MVXPE_RX_RING_MEM_PA(sc, q) != 0);
1213 
1214 	/* descriptor address */
1215 	MVXPE_WRITE(sc, MVXPE_PRXDQA(q), MVXPE_RX_RING_MEM_PA(sc, q));
1216 
1217 	/* Rx buffer size and descriptor ring size */
1218 	reg  = MVXPE_PRXDQS_BUFFERSIZE(mvxpbm_chunk_size(sc->sc_bm) >> 3);
1219 	reg |= MVXPE_PRXDQS_DESCRIPTORSQUEUESIZE(MVXPE_RX_RING_CNT);
1220 	MVXPE_WRITE(sc, MVXPE_PRXDQS(q), reg);
1221 	DPRINTIFNET(ifp, 1, "PRXDQS(%d): %#x\n",
1222 	    q, MVXPE_READ(sc, MVXPE_PRXDQS(q)));
1223 
1224 	/* Rx packet offset address */
1225 	reg = MVXPE_PRXC_PACKETOFFSET(mvxpbm_packet_offset(sc->sc_bm) >> 3);
1226 	MVXPE_WRITE(sc, MVXPE_PRXC(q), reg);
1227 	DPRINTIFNET(ifp, 1, "PRXC(%d): %#x\n",
1228 	    q, MVXPE_READ(sc, MVXPE_PRXC(q)));
1229 
1230 	/* Rx DMA SNOOP */
1231 	reg  = MVXPE_PRXSNP_SNOOPNOOFBYTES(MVXPE_MRU);
1232 	reg |= MVXPE_PRXSNP_L2DEPOSITNOOFBYTES(MVXPE_MRU);
1233 	MVXPE_WRITE(sc, MVXPE_PRXSNP(q), reg);
1234 
1235 	/* if DMA is not working, register is not updated */
1236 	KASSERT(MVXPE_READ(sc, MVXPE_PRXDQA(q)) == MVXPE_RX_RING_MEM_PA(sc, q));
1237 	return 0;
1238 }
1239 
1240 STATIC int
1241 mvxpe_tx_queue_init(struct ifnet *ifp, int q)
1242 {
1243 	struct mvxpe_softc *sc = ifp->if_softc;
1244 	struct mvxpe_tx_ring *tx = MVXPE_TX_RING(sc, q);
1245 	uint32_t reg;
1246 
1247 	KASSERT_TX_MTX(sc, q);
1248 	KASSERT(MVXPE_TX_RING_MEM_PA(sc, q) != 0);
1249 
1250 	/* descriptor address */
1251 	MVXPE_WRITE(sc, MVXPE_PTXDQA(q), MVXPE_TX_RING_MEM_PA(sc, q));
1252 
1253 	/* Tx threshold, and descriptor ring size */
1254 	reg  = MVXPE_PTXDQS_TBT(tx->tx_queue_th_free);
1255 	reg |= MVXPE_PTXDQS_DQS(MVXPE_TX_RING_CNT);
1256 	MVXPE_WRITE(sc, MVXPE_PTXDQS(q), reg);
1257 	DPRINTIFNET(ifp, 1, "PTXDQS(%d): %#x\n",
1258 	    q, MVXPE_READ(sc, MVXPE_PTXDQS(q)));
1259 
1260 	/* if DMA is not working, register is not updated */
1261 	KASSERT(MVXPE_READ(sc, MVXPE_PTXDQA(q)) == MVXPE_TX_RING_MEM_PA(sc, q));
1262 	return 0;
1263 }
1264 
1265 STATIC int
1266 mvxpe_rx_queue_enable(struct ifnet *ifp, int q)
1267 {
1268 	struct mvxpe_softc *sc = ifp->if_softc;
1269 	struct mvxpe_rx_ring *rx = MVXPE_RX_RING(sc, q);
1270 	uint32_t reg;
1271 
1272 	KASSERT_RX_MTX(sc, q);
1273 
1274 	/* Set Rx interrupt threshold */
1275 	reg  = MVXPE_PRXDQTH_ODT(rx->rx_queue_th_received);
1276 	reg |= MVXPE_PRXDQTH_NODT(rx->rx_queue_th_free);
1277 	MVXPE_WRITE(sc, MVXPE_PRXDQTH(q), reg);
1278 
1279 	reg  = MVXPE_PRXITTH_RITT(rx->rx_queue_th_time);
1280 	MVXPE_WRITE(sc, MVXPE_PRXITTH(q), reg);
1281 
1282 	/* Unmask RXTX Intr. */
1283 	reg = MVXPE_READ(sc, MVXPE_PRXTXIM);
1284 	reg |= MVXPE_PRXTXI_RREQ(q); /* Rx resource error */
1285 	MVXPE_WRITE(sc, MVXPE_PRXTXIM, reg);
1286 
1287 	/* Unmask RXTX_TH Intr. */
1288 	reg = MVXPE_READ(sc, MVXPE_PRXTXTIM);
1289 	reg |= MVXPE_PRXTXTI_RBICTAPQ(q); /* Rx Buffer Interrupt Coalese */
1290 	reg |= MVXPE_PRXTXTI_RDTAQ(q); /* Rx Descriptor Alart */
1291 	MVXPE_WRITE(sc, MVXPE_PRXTXTIM, reg);
1292 
1293 	/* Enable Rx queue */
1294 	reg = MVXPE_READ(sc, MVXPE_RQC) & MVXPE_RQC_EN_MASK;
1295 	reg |= MVXPE_RQC_ENQ(q);
1296 	MVXPE_WRITE(sc, MVXPE_RQC, reg);
1297 
1298 	return 0;
1299 }
1300 
1301 STATIC int
1302 mvxpe_tx_queue_enable(struct ifnet *ifp, int q)
1303 {
1304 	struct mvxpe_softc *sc = ifp->if_softc;
1305 	struct mvxpe_tx_ring *tx = MVXPE_TX_RING(sc, q);
1306 	uint32_t reg;
1307 
1308 	KASSERT_TX_MTX(sc, q);
1309 
1310 	/* Set Tx interrupt threshold */
1311 	reg  = MVXPE_READ(sc, MVXPE_PTXDQS(q));
1312 	reg &= ~MVXPE_PTXDQS_TBT_MASK; /* keep queue size */
1313 	reg |= MVXPE_PTXDQS_TBT(tx->tx_queue_th_free);
1314 	MVXPE_WRITE(sc, MVXPE_PTXDQS(q), reg);
1315 
1316 	/* Unmask RXTX_TH Intr. */
1317 	reg = MVXPE_READ(sc, MVXPE_PRXTXTIM);
1318 	reg |= MVXPE_PRXTXTI_TBTCQ(q); /* Tx Threshold cross */
1319 	MVXPE_WRITE(sc, MVXPE_PRXTXTIM, reg);
1320 
1321 	/* Don't update MVXPE_TQC here, there is no packet yet. */
1322 	return 0;
1323 }
1324 
1325 STATIC void
1326 mvxpe_rx_lockq(struct mvxpe_softc *sc, int q)
1327 {
1328 	KASSERT(q >= 0);
1329 	KASSERT(q < MVXPE_QUEUE_SIZE);
1330 	mutex_enter(&sc->sc_rx_ring[q].rx_ring_mtx);
1331 }
1332 
1333 STATIC void
1334 mvxpe_rx_unlockq(struct mvxpe_softc *sc, int q)
1335 {
1336 	KASSERT(q >= 0);
1337 	KASSERT(q < MVXPE_QUEUE_SIZE);
1338 	mutex_exit(&sc->sc_rx_ring[q].rx_ring_mtx);
1339 }
1340 
1341 STATIC void
1342 mvxpe_tx_lockq(struct mvxpe_softc *sc, int q)
1343 {
1344 	KASSERT(q >= 0);
1345 	KASSERT(q < MVXPE_QUEUE_SIZE);
1346 	mutex_enter(&sc->sc_tx_ring[q].tx_ring_mtx);
1347 }
1348 
1349 STATIC void
1350 mvxpe_tx_unlockq(struct mvxpe_softc *sc, int q)
1351 {
1352 	KASSERT(q >= 0);
1353 	KASSERT(q < MVXPE_QUEUE_SIZE);
1354 	mutex_exit(&sc->sc_tx_ring[q].tx_ring_mtx);
1355 }
1356 
1357 /*
1358  * Interrupt Handlers
1359  */
1360 STATIC void
1361 mvxpe_disable_intr(struct mvxpe_softc *sc)
1362 {
1363 	MVXPE_WRITE(sc, MVXPE_EUIM, 0);
1364 	MVXPE_WRITE(sc, MVXPE_EUIC, 0);
1365 	MVXPE_WRITE(sc, MVXPE_PRXTXTIM, 0);
1366 	MVXPE_WRITE(sc, MVXPE_PRXTXTIC, 0);
1367 	MVXPE_WRITE(sc, MVXPE_PRXTXIM, 0);
1368 	MVXPE_WRITE(sc, MVXPE_PRXTXIC, 0);
1369 	MVXPE_WRITE(sc, MVXPE_PMIM, 0);
1370 	MVXPE_WRITE(sc, MVXPE_PMIC, 0);
1371 	MVXPE_WRITE(sc, MVXPE_PIE, 0);
1372 }
1373 
1374 STATIC void
1375 mvxpe_enable_intr(struct mvxpe_softc *sc)
1376 {
1377 	uint32_t reg;
1378 
1379 	/* Enable Port MISC Intr. (via RXTX_TH_Summary bit) */
1380 	reg  = MVXPE_READ(sc, MVXPE_PMIM);
1381 	reg |= MVXPE_PMI_PHYSTATUSCHNG;
1382 	reg |= MVXPE_PMI_LINKCHANGE;
1383 	reg |= MVXPE_PMI_IAE;
1384 	reg |= MVXPE_PMI_RXOVERRUN;
1385 	reg |= MVXPE_PMI_RXCRCERROR;
1386 	reg |= MVXPE_PMI_RXLARGEPACKET;
1387 	reg |= MVXPE_PMI_TXUNDRN;
1388 	reg |= MVXPE_PMI_PRBSERROR;
1389 	reg |= MVXPE_PMI_SRSE;
1390 	reg |= MVXPE_PMI_TREQ_MASK;
1391 	MVXPE_WRITE(sc, MVXPE_PMIM, reg);
1392 
1393 	/* Enable RXTX Intr. (via RXTX_TH Summary bit) */
1394 	reg  = MVXPE_READ(sc, MVXPE_PRXTXIM);
1395 	reg |= MVXPE_PRXTXI_RREQ_MASK; /* Rx resource error */
1396 	MVXPE_WRITE(sc, MVXPE_PRXTXIM, reg);
1397 
1398 	/* Enable Summary Bit to check all interrupt cause. */
1399 	reg  = MVXPE_READ(sc, MVXPE_PRXTXTIM);
1400 	reg |= MVXPE_PRXTXTI_PMISCICSUMMARY;
1401 	reg |= MVXPE_PRXTXTI_PTXERRORSUMMARY;
1402 	reg |= MVXPE_PRXTXTI_PRXTXICSUMMARY;
1403 	MVXPE_WRITE(sc, MVXPE_PRXTXTIM, reg);
1404 
1405 	/* Enable All Queue Interrupt */
1406 	reg  = MVXPE_READ(sc, MVXPE_PIE);
1407 	reg |= MVXPE_PIE_RXPKTINTRPTENB_MASK;
1408 	reg |= MVXPE_PIE_TXPKTINTRPTENB_MASK;
1409 	MVXPE_WRITE(sc, MVXPE_PIE, reg);
1410 }
1411 
1412 STATIC int
1413 mvxpe_rxtxth_intr(void *arg)
1414 {
1415 	struct mvxpe_softc *sc = arg;
1416 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1417 	uint32_t ic, queues, datum = 0;
1418 
1419 	DPRINTSC(sc, 2, "got RXTX_TH_Intr\n");
1420 	MVXPE_EVCNT_INCR(&sc->sc_ev.ev_i_rxtxth);
1421 
1422 	mvxpe_sc_lock(sc);
1423 	ic = MVXPE_READ(sc, MVXPE_PRXTXTIC);
1424 	if (ic == 0)
1425 		return 0;
1426 	MVXPE_WRITE(sc, MVXPE_PRXTXTIC, ~ic);
1427 	datum = datum ^ ic;
1428 
1429 	DPRINTIFNET(ifp, 2, "PRXTXTIC: %#x\n", ic);
1430 
1431 	/* ack maintance interrupt first */
1432 	if (ic & MVXPE_PRXTXTI_PTXERRORSUMMARY) {
1433 		DPRINTIFNET(ifp, 1, "PRXTXTIC: +PTXERRORSUMMARY\n");
1434 		MVXPE_EVCNT_INCR(&sc->sc_ev.ev_rxtxth_txerr);
1435 	}
1436 	if ((ic & MVXPE_PRXTXTI_PMISCICSUMMARY)) {
1437 		DPRINTIFNET(ifp, 2, "PTXTXTIC: +PMISCICSUMMARY\n");
1438 		mvxpe_misc_intr(sc);
1439 	}
1440 	if (ic & MVXPE_PRXTXTI_PRXTXICSUMMARY) {
1441 		DPRINTIFNET(ifp, 2, "PTXTXTIC: +PRXTXICSUMMARY\n");
1442 		mvxpe_rxtx_intr(sc);
1443 	}
1444 	if (!(ifp->if_flags & IFF_RUNNING))
1445 		return 1;
1446 
1447 	/* RxTxTH interrupt */
1448 	queues = MVXPE_PRXTXTI_GET_RBICTAPQ(ic);
1449 	if (queues) {
1450 		DPRINTIFNET(ifp, 2, "PRXTXTIC: +RXEOF\n");
1451 		mvxpe_rx(sc, queues);
1452 	}
1453 	queues = MVXPE_PRXTXTI_GET_TBTCQ(ic);
1454 	if (queues) {
1455 		DPRINTIFNET(ifp, 2, "PRXTXTIC: +TBTCQ\n");
1456 		mvxpe_tx_complete(sc, queues);
1457 	}
1458 	queues = MVXPE_PRXTXTI_GET_RDTAQ(ic);
1459 	if (queues) {
1460 		DPRINTIFNET(ifp, 2, "PRXTXTIC: +RDTAQ\n");
1461 		mvxpe_rx_refill(sc, queues);
1462 	}
1463 	mvxpe_sc_unlock(sc);
1464 
1465 	if (!IFQ_IS_EMPTY(&ifp->if_snd))
1466 		mvxpe_start(ifp);
1467 
1468 	rnd_add_uint32(&sc->sc_rnd_source, datum);
1469 
1470 	return 1;
1471 }
1472 
1473 STATIC int
1474 mvxpe_misc_intr(void *arg)
1475 {
1476 	struct mvxpe_softc *sc = arg;
1477 #ifdef MVXPE_DEBUG
1478 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1479 #endif
1480 	uint32_t ic;
1481 	uint32_t datum = 0;
1482 	int claimed = 0;
1483 
1484 	DPRINTSC(sc, 2, "got MISC_INTR\n");
1485 	MVXPE_EVCNT_INCR(&sc->sc_ev.ev_i_misc);
1486 
1487 	KASSERT_SC_MTX(sc);
1488 
1489 	for (;;) {
1490 		ic = MVXPE_READ(sc, MVXPE_PMIC);
1491 		ic &= MVXPE_READ(sc, MVXPE_PMIM);
1492 		if (ic == 0)
1493 			break;
1494 		MVXPE_WRITE(sc, MVXPE_PMIC, ~ic);
1495 		datum = datum ^ ic;
1496 		claimed = 1;
1497 
1498 		DPRINTIFNET(ifp, 2, "PMIC=%#x\n", ic);
1499 		if (ic & MVXPE_PMI_PHYSTATUSCHNG) {
1500 			DPRINTIFNET(ifp, 2, "+PHYSTATUSCHNG\n");
1501 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_misc_phystatuschng);
1502 		}
1503 		if (ic & MVXPE_PMI_LINKCHANGE) {
1504 			DPRINTIFNET(ifp, 2, "+LINKCHANGE\n");
1505 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_misc_linkchange);
1506 			mvxpe_linkupdate(sc);
1507 		}
1508 		if (ic & MVXPE_PMI_IAE) {
1509 			DPRINTIFNET(ifp, 2, "+IAE\n");
1510 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_misc_iae);
1511 		}
1512 		if (ic & MVXPE_PMI_RXOVERRUN) {
1513 			DPRINTIFNET(ifp, 2, "+RXOVERRUN\n");
1514 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_misc_rxoverrun);
1515 		}
1516 		if (ic & MVXPE_PMI_RXCRCERROR) {
1517 			DPRINTIFNET(ifp, 2, "+RXCRCERROR\n");
1518 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_misc_rxcrc);
1519 		}
1520 		if (ic & MVXPE_PMI_RXLARGEPACKET) {
1521 			DPRINTIFNET(ifp, 2, "+RXLARGEPACKET\n");
1522 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_misc_rxlargepacket);
1523 		}
1524 		if (ic & MVXPE_PMI_TXUNDRN) {
1525 			DPRINTIFNET(ifp, 2, "+TXUNDRN\n");
1526 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_misc_txunderrun);
1527 		}
1528 		if (ic & MVXPE_PMI_PRBSERROR) {
1529 			DPRINTIFNET(ifp, 2, "+PRBSERROR\n");
1530 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_misc_prbserr);
1531 		}
1532 		if (ic & MVXPE_PMI_TREQ_MASK) {
1533 			DPRINTIFNET(ifp, 2, "+TREQ\n");
1534 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_misc_txreq);
1535 		}
1536 	}
1537 	if (datum)
1538 		rnd_add_uint32(&sc->sc_rnd_source, datum);
1539 
1540 	return claimed;
1541 }
1542 
1543 STATIC int
1544 mvxpe_rxtx_intr(void *arg)
1545 {
1546 	struct mvxpe_softc *sc = arg;
1547 #ifdef MVXPE_DEBUG
1548 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1549 #endif
1550 	uint32_t datum = 0;
1551 	uint32_t prxtxic;
1552 	int claimed = 0;
1553 
1554 	DPRINTSC(sc, 2, "got RXTX_Intr\n");
1555 	MVXPE_EVCNT_INCR(&sc->sc_ev.ev_i_rxtx);
1556 
1557 	KASSERT_SC_MTX(sc);
1558 
1559 	for (;;) {
1560 		prxtxic = MVXPE_READ(sc, MVXPE_PRXTXIC);
1561 		prxtxic &= MVXPE_READ(sc, MVXPE_PRXTXIM);
1562 		if (prxtxic == 0)
1563 			break;
1564 		MVXPE_WRITE(sc, MVXPE_PRXTXIC, ~prxtxic);
1565 		datum = datum ^ prxtxic;
1566 		claimed = 1;
1567 
1568 		DPRINTSC(sc, 2, "PRXTXIC: %#x\n", prxtxic);
1569 
1570 		if (prxtxic & MVXPE_PRXTXI_RREQ_MASK) {
1571 			DPRINTIFNET(ifp, 1, "Rx Resource Error.\n");
1572 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_rxtx_rreq);
1573 		}
1574 		if (prxtxic & MVXPE_PRXTXI_RPQ_MASK) {
1575 			DPRINTIFNET(ifp, 1, "Rx Packet in Queue.\n");
1576 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_rxtx_rpq);
1577 		}
1578 		if (prxtxic & MVXPE_PRXTXI_TBRQ_MASK) {
1579 			DPRINTIFNET(ifp, 1, "Tx Buffer Return.\n");
1580 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_rxtx_tbrq);
1581 		}
1582 		if (prxtxic & MVXPE_PRXTXI_PRXTXTHICSUMMARY) {
1583 			DPRINTIFNET(ifp, 1, "PRXTXTHIC Sumary\n");
1584 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_rxtx_rxtxth);
1585 		}
1586 		if (prxtxic & MVXPE_PRXTXI_PTXERRORSUMMARY) {
1587 			DPRINTIFNET(ifp, 1, "PTXERROR Sumary\n");
1588 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_rxtx_txerr);
1589 		}
1590 		if (prxtxic & MVXPE_PRXTXI_PMISCICSUMMARY) {
1591 			DPRINTIFNET(ifp, 1, "PMISCIC Sumary\n");
1592 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_rxtx_misc);
1593 		}
1594 	}
1595 	if (datum)
1596 		rnd_add_uint32(&sc->sc_rnd_source, datum);
1597 
1598 	return claimed;
1599 }
1600 
1601 STATIC void
1602 mvxpe_tick(void *arg)
1603 {
1604 	struct mvxpe_softc *sc = arg;
1605 	struct mii_data *mii = &sc->sc_mii;
1606 
1607 	mvxpe_sc_lock(sc);
1608 
1609 	mii_tick(mii);
1610 	mii_pollstat(&sc->sc_mii);
1611 
1612 	/* read mib regisers(clear by read) */
1613 	mvxpe_update_mib(sc);
1614 
1615 	/* read counter registers(clear by read) */
1616 	MVXPE_EVCNT_ADD(&sc->sc_ev.ev_reg_pdfc,
1617 	    MVXPE_READ(sc, MVXPE_PDFC));
1618 	MVXPE_EVCNT_ADD(&sc->sc_ev.ev_reg_pofc,
1619 	    MVXPE_READ(sc, MVXPE_POFC));
1620 	MVXPE_EVCNT_ADD(&sc->sc_ev.ev_reg_txbadfcs,
1621 	    MVXPE_READ(sc, MVXPE_TXBADFCS));
1622 	MVXPE_EVCNT_ADD(&sc->sc_ev.ev_reg_txdropped,
1623 	    MVXPE_READ(sc, MVXPE_TXDROPPED));
1624 	MVXPE_EVCNT_ADD(&sc->sc_ev.ev_reg_lpic,
1625 	    MVXPE_READ(sc, MVXPE_LPIC));
1626 
1627 	mvxpe_sc_unlock(sc);
1628 
1629 	callout_schedule(&sc->sc_tick_ch, hz);
1630 }
1631 
1632 
1633 /*
1634  * struct ifnet and mii callbacks
1635  */
1636 STATIC void
1637 mvxpe_start(struct ifnet *ifp)
1638 {
1639 	struct mvxpe_softc *sc = ifp->if_softc;
1640 	struct mbuf *m;
1641 	int q;
1642 
1643 	if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) {
1644 		DPRINTIFNET(ifp, 1, "not running\n");
1645 		return;
1646 	}
1647 
1648 	mvxpe_sc_lock(sc);
1649 	if (!MVXPE_IS_LINKUP(sc)) {
1650 		/* If Link is DOWN, can't start TX */
1651 		DPRINTIFNET(ifp, 1, "link fail\n");
1652 		for (;;) {
1653 			/*
1654 			 * discard stale packets all.
1655 			 * these may confuse DAD, ARP or timer based protocols.
1656 			 */
1657 			IFQ_DEQUEUE(&ifp->if_snd, m);
1658 			if (m == NULL)
1659 				break;
1660 			m_freem(m);
1661 		}
1662 		mvxpe_sc_unlock(sc);
1663 		return;
1664 	}
1665 	for (;;) {
1666 		/*
1667 		 * don't use IFQ_POLL().
1668 		 * there is lock problem between IFQ_POLL and IFQ_DEQUEUE
1669 		 * on SMP enabled networking stack.
1670 		 */
1671 		IFQ_DEQUEUE(&ifp->if_snd, m);
1672 		if (m == NULL)
1673 			break;
1674 
1675 		q = mvxpe_tx_queue_select(sc, m);
1676 		if (q < 0)
1677 			break;
1678 		/* mutex is held in mvxpe_tx_queue_select() */
1679 
1680 		if (mvxpe_tx_queue(sc, m, q) != 0) {
1681 			DPRINTIFNET(ifp, 1, "cannot add packet to tx ring\n");
1682 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_drv_txerr);
1683 			mvxpe_tx_unlockq(sc, q);
1684 			break;
1685 		}
1686 		mvxpe_tx_unlockq(sc, q);
1687 		KASSERT(sc->sc_tx_ring[q].tx_used >= 0);
1688 		KASSERT(sc->sc_tx_ring[q].tx_used <=
1689 		    sc->sc_tx_ring[q].tx_queue_len);
1690 		DPRINTIFNET(ifp, 1, "a packet is added to tx ring\n");
1691 		sc->sc_tx_pending++;
1692 		ifp->if_timer = 1;
1693 		sc->sc_wdogsoft = 1;
1694 		bpf_mtap(ifp, m);
1695 	}
1696 	mvxpe_sc_unlock(sc);
1697 
1698 	return;
1699 }
1700 
1701 STATIC int
1702 mvxpe_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1703 {
1704 	struct mvxpe_softc *sc = ifp->if_softc;
1705 	struct ifreq *ifr = data;
1706 	int error = 0;
1707 	int s;
1708 
1709 	switch (cmd) {
1710 	case SIOCGIFMEDIA:
1711 	case SIOCSIFMEDIA:
1712 		DPRINTIFNET(ifp, 2, "mvxpe_ioctl MEDIA\n");
1713 		s = splnet(); /* XXX: is there suitable mutex? */
1714 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
1715 		splx(s);
1716 		break;
1717 	default:
1718 		DPRINTIFNET(ifp, 2, "mvxpe_ioctl ETHER\n");
1719 		error = ether_ioctl(ifp, cmd, data);
1720 		if (error == ENETRESET) {
1721 			if (ifp->if_flags & IFF_RUNNING) {
1722 				mvxpe_sc_lock(sc);
1723 				mvxpe_filter_setup(sc);
1724 				mvxpe_sc_unlock(sc);
1725 			}
1726 			error = 0;
1727 		}
1728 		break;
1729 	}
1730 
1731 	return error;
1732 }
1733 
1734 STATIC int
1735 mvxpe_init(struct ifnet *ifp)
1736 {
1737 	struct mvxpe_softc *sc = ifp->if_softc;
1738 	struct mii_data *mii = &sc->sc_mii;
1739 	uint32_t reg;
1740 	int q;
1741 
1742 	mvxpe_sc_lock(sc);
1743 
1744 	/* Start DMA Engine */
1745 	MVXPE_WRITE(sc, MVXPE_PRXINIT, 0x00000000);
1746 	MVXPE_WRITE(sc, MVXPE_PTXINIT, 0x00000000);
1747 	MVXPE_WRITE(sc, MVXPE_PACC, MVXPE_PACC_ACCELERATIONMODE_EDM);
1748 
1749 	/* Enable port */
1750 	reg  = MVXPE_READ(sc, MVXPE_PMACC0);
1751 	reg |= MVXPE_PMACC0_PORTEN;
1752 	MVXPE_WRITE(sc, MVXPE_PMACC0, reg);
1753 
1754 	/* Link up */
1755 	mvxpe_linkup(sc);
1756 
1757 	/* Enable All Queue and interrupt of each Queue */
1758 	for (q = 0; q < MVXPE_QUEUE_SIZE; q++) {
1759 		mvxpe_rx_lockq(sc, q);
1760 		mvxpe_rx_queue_enable(ifp, q);
1761 		mvxpe_rx_queue_refill(sc, q);
1762 		mvxpe_rx_unlockq(sc, q);
1763 
1764 		mvxpe_tx_lockq(sc, q);
1765 		mvxpe_tx_queue_enable(ifp, q);
1766 		mvxpe_tx_unlockq(sc, q);
1767 	}
1768 
1769 	/* Enable interrupt */
1770 	mvxpe_enable_intr(sc);
1771 
1772 	/* Set Counter */
1773 	callout_schedule(&sc->sc_tick_ch, hz);
1774 
1775 	/* Media check */
1776 	mii_mediachg(mii);
1777 
1778 	ifp->if_flags |= IFF_RUNNING;
1779 	ifp->if_flags &= ~IFF_OACTIVE;
1780 
1781 	mvxpe_sc_unlock(sc);
1782 	return 0;
1783 }
1784 
1785 /* ARGSUSED */
1786 STATIC void
1787 mvxpe_stop(struct ifnet *ifp, int disable)
1788 {
1789 	struct mvxpe_softc *sc = ifp->if_softc;
1790 	uint32_t reg;
1791 	int q, cnt;
1792 
1793 	DPRINTIFNET(ifp, 1, "stop device dma and interrupts.\n");
1794 
1795 	mvxpe_sc_lock(sc);
1796 
1797 	callout_stop(&sc->sc_tick_ch);
1798 
1799 	/* Link down */
1800 	mvxpe_linkdown(sc);
1801 
1802 	/* Disable Rx interrupt */
1803 	reg  = MVXPE_READ(sc, MVXPE_PIE);
1804 	reg &= ~MVXPE_PIE_RXPKTINTRPTENB_MASK;
1805 	MVXPE_WRITE(sc, MVXPE_PIE, reg);
1806 
1807 	reg  = MVXPE_READ(sc, MVXPE_PRXTXTIM);
1808 	reg &= ~MVXPE_PRXTXTI_RBICTAPQ_MASK;
1809 	reg &= ~MVXPE_PRXTXTI_RDTAQ_MASK;
1810 	MVXPE_WRITE(sc, MVXPE_PRXTXTIM, reg);
1811 
1812 	/* Wait for all Rx activity to terminate. */
1813 	reg = MVXPE_READ(sc, MVXPE_RQC) & MVXPE_RQC_EN_MASK;
1814 	reg = MVXPE_RQC_DIS(reg);
1815 	MVXPE_WRITE(sc, MVXPE_RQC, reg);
1816 	cnt = 0;
1817 	do {
1818 		if (cnt >= RX_DISABLE_TIMEOUT) {
1819 			aprint_error_ifnet(ifp,
1820 			    "timeout for RX stopped. rqc 0x%x\n", reg);
1821 			break;
1822 		}
1823 		cnt++;
1824 		reg = MVXPE_READ(sc, MVXPE_RQC);
1825 	} while (reg & MVXPE_RQC_EN_MASK);
1826 
1827 	/* Wait for all Tx activety to terminate. */
1828 	reg  = MVXPE_READ(sc, MVXPE_PIE);
1829 	reg &= ~MVXPE_PIE_TXPKTINTRPTENB_MASK;
1830 	MVXPE_WRITE(sc, MVXPE_PIE, reg);
1831 
1832 	reg  = MVXPE_READ(sc, MVXPE_PRXTXTIM);
1833 	reg &= ~MVXPE_PRXTXTI_TBTCQ_MASK;
1834 	MVXPE_WRITE(sc, MVXPE_PRXTXTIM, reg);
1835 
1836 	reg = MVXPE_READ(sc, MVXPE_TQC) & MVXPE_TQC_EN_MASK;
1837 	reg = MVXPE_TQC_DIS(reg);
1838 	MVXPE_WRITE(sc, MVXPE_TQC, reg);
1839 	cnt = 0;
1840 	do {
1841 		if (cnt >= TX_DISABLE_TIMEOUT) {
1842 			aprint_error_ifnet(ifp,
1843 			    "timeout for TX stopped. tqc 0x%x\n", reg);
1844 			break;
1845 		}
1846 		cnt++;
1847 		reg = MVXPE_READ(sc, MVXPE_TQC);
1848 	} while (reg & MVXPE_TQC_EN_MASK);
1849 
1850 	/* Wait for all Tx FIFO is empty */
1851 	cnt = 0;
1852 	do {
1853 		if (cnt >= TX_FIFO_EMPTY_TIMEOUT) {
1854 			aprint_error_ifnet(ifp,
1855 			    "timeout for TX FIFO drained. ps0 0x%x\n", reg);
1856 			break;
1857 		}
1858 		cnt++;
1859 		reg = MVXPE_READ(sc, MVXPE_PS0);
1860 	} while (!(reg & MVXPE_PS0_TXFIFOEMP) && (reg & MVXPE_PS0_TXINPROG));
1861 
1862 	/* Reset the MAC Port Enable bit */
1863 	reg = MVXPE_READ(sc, MVXPE_PMACC0);
1864 	reg &= ~MVXPE_PMACC0_PORTEN;
1865 	MVXPE_WRITE(sc, MVXPE_PMACC0, reg);
1866 
1867 	/* Disable each of queue */
1868 	for (q = 0; q < MVXPE_QUEUE_SIZE; q++) {
1869 		struct mvxpe_rx_ring *rx = MVXPE_RX_RING(sc, q);
1870 
1871 		mvxpe_rx_lockq(sc, q);
1872 		mvxpe_tx_lockq(sc, q);
1873 
1874 		/* Disable Rx packet buffer refill request */
1875 		reg  = MVXPE_PRXDQTH_ODT(rx->rx_queue_th_received);
1876 		reg |= MVXPE_PRXDQTH_NODT(0);
1877 		MVXPE_WRITE(sc, MVXPE_PRXITTH(q), reg);
1878 
1879 		if (disable) {
1880 			/*
1881 			 * Hold Reset state of DMA Engine
1882 			 * (must write 0x0 to restart it)
1883 			 */
1884 			MVXPE_WRITE(sc, MVXPE_PRXINIT, 0x00000001);
1885 			MVXPE_WRITE(sc, MVXPE_PTXINIT, 0x00000001);
1886 			mvxpe_ring_flush_queue(sc, q);
1887 		}
1888 
1889 		mvxpe_tx_unlockq(sc, q);
1890 		mvxpe_rx_unlockq(sc, q);
1891 	}
1892 
1893 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1894 
1895 	mvxpe_sc_unlock(sc);
1896 }
1897 
1898 STATIC void
1899 mvxpe_watchdog(struct ifnet *ifp)
1900 {
1901 	struct mvxpe_softc *sc = ifp->if_softc;
1902 	int q;
1903 
1904 	mvxpe_sc_lock(sc);
1905 
1906 	/*
1907 	 * Reclaim first as there is a possibility of losing Tx completion
1908 	 * interrupts.
1909 	 */
1910 	mvxpe_tx_complete(sc, 0xff);
1911 	for (q = 0; q < MVXPE_QUEUE_SIZE; q++) {
1912 		struct mvxpe_tx_ring *tx = MVXPE_TX_RING(sc, q);
1913 
1914 		if (tx->tx_dma != tx->tx_cpu) {
1915 			if (sc->sc_wdogsoft) {
1916 				/*
1917 				 * There is race condition between CPU and DMA
1918 				 * engine. When DMA engine encounters queue end,
1919 				 * it clears MVXPE_TQC_ENQ bit.
1920 				 * XXX: how about enhanced mode?
1921 				 */
1922 				MVXPE_WRITE(sc, MVXPE_TQC, MVXPE_TQC_ENQ(q));
1923 				ifp->if_timer = 5;
1924 				sc->sc_wdogsoft = 0;
1925 				MVXPE_EVCNT_INCR(&sc->sc_ev.ev_drv_wdogsoft);
1926 			} else {
1927 				aprint_error_ifnet(ifp, "watchdog timeout\n");
1928 				ifp->if_oerrors++;
1929 				mvxpe_linkreset(sc);
1930 				mvxpe_sc_unlock(sc);
1931 
1932 				/* trigger reinitialize sequence */
1933 				mvxpe_stop(ifp, 1);
1934 				mvxpe_init(ifp);
1935 
1936 				mvxpe_sc_lock(sc);
1937 			}
1938 		}
1939 	}
1940 	mvxpe_sc_unlock(sc);
1941 }
1942 
1943 STATIC int
1944 mvxpe_ifflags_cb(struct ethercom *ec)
1945 {
1946 	struct ifnet *ifp = &ec->ec_if;
1947 	struct mvxpe_softc *sc = ifp->if_softc;
1948 	int change = ifp->if_flags ^ sc->sc_if_flags;
1949 
1950 	mvxpe_sc_lock(sc);
1951 
1952 	if (change != 0)
1953 		sc->sc_if_flags = ifp->if_flags;
1954 
1955 	if ((change & ~(IFF_CANTCHANGE|IFF_DEBUG)) != 0) {
1956 		mvxpe_sc_unlock(sc);
1957 		return ENETRESET;
1958 	}
1959 
1960 	if ((change & IFF_PROMISC) != 0)
1961 		mvxpe_filter_setup(sc);
1962 
1963 	if ((change & IFF_UP) != 0)
1964 		mvxpe_linkreset(sc);
1965 
1966 	mvxpe_sc_unlock(sc);
1967 	return 0;
1968 }
1969 
1970 STATIC int
1971 mvxpe_mediachange(struct ifnet *ifp)
1972 {
1973 	return ether_mediachange(ifp);
1974 }
1975 
1976 STATIC void
1977 mvxpe_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
1978 {
1979 	ether_mediastatus(ifp, ifmr);
1980 }
1981 
1982 /*
1983  * Link State Notify
1984  */
1985 STATIC void mvxpe_linkupdate(struct mvxpe_softc *sc)
1986 {
1987 	int linkup; /* bool */
1988 
1989 	KASSERT_SC_MTX(sc);
1990 
1991 	/* tell miibus */
1992 	mii_pollstat(&sc->sc_mii);
1993 
1994 	/* syslog */
1995 	linkup = MVXPE_IS_LINKUP(sc);
1996 	if (sc->sc_linkstate == linkup)
1997 		return;
1998 
1999 #ifdef DEBUG
2000 	log(LOG_DEBUG,
2001 	    "%s: link %s\n", device_xname(sc->sc_dev), linkup ? "up" : "down");
2002 #endif
2003 	if (linkup)
2004 		MVXPE_EVCNT_INCR(&sc->sc_ev.ev_link_up);
2005 	else
2006 		MVXPE_EVCNT_INCR(&sc->sc_ev.ev_link_down);
2007 
2008 	sc->sc_linkstate = linkup;
2009 }
2010 
2011 STATIC void
2012 mvxpe_linkup(struct mvxpe_softc *sc)
2013 {
2014 	uint32_t reg;
2015 
2016 	KASSERT_SC_MTX(sc);
2017 
2018 	/* set EEE parameters */
2019 	reg = MVXPE_READ(sc, MVXPE_LPIC1);
2020 	if (sc->sc_cf.cf_lpi)
2021 		reg |= MVXPE_LPIC1_LPIRE;
2022 	else
2023 		reg &= ~MVXPE_LPIC1_LPIRE;
2024 	MVXPE_WRITE(sc, MVXPE_LPIC1, reg);
2025 
2026 	/* set auto-negotiation parameters */
2027 	reg  = MVXPE_READ(sc, MVXPE_PANC);
2028 	if (sc->sc_cf.cf_fc) {
2029 		/* flow control negotiation */
2030 		reg |= MVXPE_PANC_PAUSEADV;
2031 		reg |= MVXPE_PANC_ANFCEN;
2032 	}
2033 	else {
2034 		reg &= ~MVXPE_PANC_PAUSEADV;
2035 		reg &= ~MVXPE_PANC_ANFCEN;
2036 	}
2037 	reg &= ~MVXPE_PANC_FORCELINKFAIL;
2038 	reg &= ~MVXPE_PANC_FORCELINKPASS;
2039 	MVXPE_WRITE(sc, MVXPE_PANC, reg);
2040 
2041 	mii_mediachg(&sc->sc_mii);
2042 }
2043 
2044 STATIC void
2045 mvxpe_linkdown(struct mvxpe_softc *sc)
2046 {
2047 	struct mii_softc *mii;
2048 	uint32_t reg;
2049 
2050 	KASSERT_SC_MTX(sc);
2051 	return;
2052 
2053 	reg  = MVXPE_READ(sc, MVXPE_PANC);
2054 	reg |= MVXPE_PANC_FORCELINKFAIL;
2055 	reg &= MVXPE_PANC_FORCELINKPASS;
2056 	MVXPE_WRITE(sc, MVXPE_PANC, reg);
2057 
2058 	mii = LIST_FIRST(&sc->sc_mii.mii_phys);
2059 	if (mii)
2060 		mii_phy_down(mii);
2061 }
2062 
2063 STATIC void
2064 mvxpe_linkreset(struct mvxpe_softc *sc)
2065 {
2066 	struct mii_softc *mii;
2067 
2068 	KASSERT_SC_MTX(sc);
2069 
2070 	/* force reset PHY first */
2071 	mii = LIST_FIRST(&sc->sc_mii.mii_phys);
2072 	if (mii)
2073 		mii_phy_reset(mii);
2074 
2075 	/* reinit MAC and PHY */
2076 	mvxpe_linkdown(sc);
2077 	if ((sc->sc_if_flags & IFF_UP) != 0)
2078 		mvxpe_linkup(sc);
2079 }
2080 
2081 /*
2082  * Tx Subroutines
2083  */
2084 STATIC int
2085 mvxpe_tx_queue_select(struct mvxpe_softc *sc, struct mbuf *m)
2086 {
2087 	int q = 0;
2088 
2089 	/* XXX: get attribute from ALTQ framework? */
2090 	mvxpe_tx_lockq(sc, q);
2091 	return 0;
2092 }
2093 
2094 STATIC int
2095 mvxpe_tx_queue(struct mvxpe_softc *sc, struct mbuf *m, int q)
2096 {
2097 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
2098 	bus_dma_segment_t *txsegs;
2099 	struct mvxpe_tx_ring *tx = MVXPE_TX_RING(sc, q);
2100 	struct mvxpe_tx_desc *t = NULL;
2101 	uint32_t ptxsu;
2102 	int txnsegs;
2103 	int start, used;
2104 	int i;
2105 
2106 	KASSERT_TX_MTX(sc, q);
2107 	KASSERT(tx->tx_used >= 0);
2108 	KASSERT(tx->tx_used <= tx->tx_queue_len);
2109 
2110 	/* load mbuf using dmamap of 1st descriptor */
2111 	if (bus_dmamap_load_mbuf(sc->sc_dmat,
2112 	    MVXPE_TX_MAP(sc, q, tx->tx_cpu), m, BUS_DMA_NOWAIT) != 0) {
2113 		m_freem(m);
2114 		return ENOBUFS;
2115 	}
2116 	txsegs = MVXPE_TX_MAP(sc, q, tx->tx_cpu)->dm_segs;
2117 	txnsegs = MVXPE_TX_MAP(sc, q, tx->tx_cpu)->dm_nsegs;
2118 	if (txnsegs <= 0 || (txnsegs + tx->tx_used) > tx->tx_queue_len) {
2119 		/* we have no enough descriptors or mbuf is broken */
2120 		bus_dmamap_unload(sc->sc_dmat, MVXPE_TX_MAP(sc, q, tx->tx_cpu));
2121 		m_freem(m);
2122 		return ENOBUFS;
2123 	}
2124 	DPRINTSC(sc, 2, "send packet %p descriptor %d\n", m, tx->tx_cpu);
2125 	KASSERT(MVXPE_TX_MBUF(sc, q, tx->tx_cpu) == NULL);
2126 
2127 	/* remember mbuf using 1st descriptor */
2128 	MVXPE_TX_MBUF(sc, q, tx->tx_cpu) = m;
2129 	bus_dmamap_sync(sc->sc_dmat,
2130 	    MVXPE_TX_MAP(sc, q, tx->tx_cpu), 0, m->m_pkthdr.len,
2131 	    BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREWRITE);
2132 
2133 	/* load to tx descriptors */
2134 	start = tx->tx_cpu;
2135 	used = 0;
2136 	for (i = 0; i < txnsegs; i++) {
2137 		if (__predict_false(txsegs[i].ds_len == 0))
2138 			continue;
2139 		t = MVXPE_TX_DESC(sc, q, tx->tx_cpu);
2140 		t->command = 0;
2141 		t->l4ichk = 0;
2142 		t->flags = 0;
2143 		if (i == 0) {
2144 			/* 1st descriptor */
2145 			t->command |= MVXPE_TX_CMD_W_PACKET_OFFSET(0);
2146 			t->command |= MVXPE_TX_CMD_PADDING;
2147 			t->command |= MVXPE_TX_CMD_F;
2148 			mvxpe_tx_set_csumflag(ifp, t, m);
2149 		}
2150 		t->bufptr = txsegs[i].ds_addr;
2151 		t->bytecnt = txsegs[i].ds_len;
2152 		tx->tx_cpu = tx_counter_adv(tx->tx_cpu, 1);
2153 		tx->tx_used++;
2154 		used++;
2155 	}
2156 	/* t is last descriptor here */
2157 	KASSERT(t != NULL);
2158 	t->command |= MVXPE_TX_CMD_L;
2159 
2160 	DPRINTSC(sc, 2, "queue %d, %d descriptors used\n", q, used);
2161 #ifdef MVXPE_DEBUG
2162 	if (mvxpe_debug > 2)
2163 		for (i = start; i <= tx->tx_cpu; i++) {
2164 			t = MVXPE_TX_DESC(sc, q, i);
2165 			mvxpe_dump_txdesc(t, i);
2166 		}
2167 #endif
2168 	mvxpe_ring_sync_tx(sc, q, start, used,
2169 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2170 
2171 	while (used > 255) {
2172 		ptxsu = MVXPE_PTXSU_NOWD(255);
2173 		MVXPE_WRITE(sc, MVXPE_PTXSU(q), ptxsu);
2174 		used -= 255;
2175 	}
2176 	if (used > 0) {
2177 		ptxsu = MVXPE_PTXSU_NOWD(used);
2178 		MVXPE_WRITE(sc, MVXPE_PTXSU(q), ptxsu);
2179 	}
2180 	MVXPE_WRITE(sc, MVXPE_TQC, MVXPE_TQC_ENQ(q));
2181 
2182 	DPRINTSC(sc, 2,
2183 	    "PTXDQA: queue %d, %#x\n", q, MVXPE_READ(sc, MVXPE_PTXDQA(q)));
2184 	DPRINTSC(sc, 2,
2185 	    "PTXDQS: queue %d, %#x\n", q, MVXPE_READ(sc, MVXPE_PTXDQS(q)));
2186 	DPRINTSC(sc, 2,
2187 	    "PTXS: queue %d, %#x\n", q, MVXPE_READ(sc, MVXPE_PTXS(q)));
2188 	DPRINTSC(sc, 2,
2189 	    "PTXDI: queue %d, %d\n", q, MVXPE_READ(sc, MVXPE_PTXDI(q)));
2190 	DPRINTSC(sc, 2, "TQC: %#x\n", MVXPE_READ(sc, MVXPE_TQC));
2191 	DPRINTIFNET(ifp, 2,
2192 	    "Tx: tx_cpu = %d, tx_dma = %d, tx_used = %d\n",
2193 	    tx->tx_cpu, tx->tx_dma, tx->tx_used);
2194 	return 0;
2195 }
2196 
2197 STATIC void
2198 mvxpe_tx_set_csumflag(struct ifnet *ifp,
2199     struct mvxpe_tx_desc *t, struct mbuf *m)
2200 {
2201 	struct ether_header *eh;
2202 	int csum_flags;
2203 	uint32_t iphl = 0, ipoff = 0;
2204 
2205 
2206        	csum_flags = ifp->if_csum_flags_tx & m->m_pkthdr.csum_flags;
2207 
2208 	eh = mtod(m, struct ether_header *);
2209 	switch (htons(eh->ether_type)) {
2210 	case ETHERTYPE_IP:
2211 	case ETHERTYPE_IPV6:
2212 		ipoff = ETHER_HDR_LEN;
2213 		break;
2214 	case ETHERTYPE_VLAN:
2215 		ipoff = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
2216 		break;
2217 	}
2218 
2219 	if (csum_flags & (M_CSUM_IPv4|M_CSUM_TCPv4|M_CSUM_UDPv4)) {
2220 		iphl = M_CSUM_DATA_IPv4_IPHL(m->m_pkthdr.csum_data);
2221 		t->command |= MVXPE_TX_CMD_L3_IP4;
2222 	}
2223 	else if (csum_flags & (M_CSUM_TCPv6|M_CSUM_UDPv6)) {
2224 		iphl = M_CSUM_DATA_IPv6_HL(m->m_pkthdr.csum_data);
2225 		t->command |= MVXPE_TX_CMD_L3_IP6;
2226 	}
2227 	else {
2228 		t->command |= MVXPE_TX_CMD_L4_CHECKSUM_NONE;
2229 		return;
2230 	}
2231 
2232 
2233 	/* L3 */
2234 	if (csum_flags & M_CSUM_IPv4) {
2235 		t->command |= MVXPE_TX_CMD_IP4_CHECKSUM;
2236 	}
2237 
2238 	/* L4 */
2239 	if ((csum_flags &
2240 	    (M_CSUM_TCPv4|M_CSUM_UDPv4|M_CSUM_TCPv6|M_CSUM_UDPv6)) == 0) {
2241 		t->command |= MVXPE_TX_CMD_L4_CHECKSUM_NONE;
2242 	}
2243 	else if (csum_flags & M_CSUM_TCPv4) {
2244 		t->command |= MVXPE_TX_CMD_L4_CHECKSUM_NOFRAG;
2245 		t->command |= MVXPE_TX_CMD_L4_TCP;
2246 	}
2247 	else if (csum_flags & M_CSUM_UDPv4) {
2248 		t->command |= MVXPE_TX_CMD_L4_CHECKSUM_NOFRAG;
2249 		t->command |= MVXPE_TX_CMD_L4_UDP;
2250 	}
2251 	else if (csum_flags & M_CSUM_TCPv6) {
2252 		t->command |= MVXPE_TX_CMD_L4_CHECKSUM_NOFRAG;
2253 		t->command |= MVXPE_TX_CMD_L4_TCP;
2254 	}
2255 	else if (csum_flags & M_CSUM_UDPv6) {
2256 		t->command |= MVXPE_TX_CMD_L4_CHECKSUM_NOFRAG;
2257 		t->command |= MVXPE_TX_CMD_L4_UDP;
2258 	}
2259 
2260 	t->l4ichk = 0;
2261 	t->command |= MVXPE_TX_CMD_IP_HEADER_LEN(iphl >> 2);
2262 	t->command |= MVXPE_TX_CMD_L3_OFFSET(ipoff);
2263 }
2264 
2265 STATIC void
2266 mvxpe_tx_complete(struct mvxpe_softc *sc, uint32_t queues)
2267 {
2268 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
2269 	int q;
2270 
2271 	DPRINTSC(sc, 2, "tx completed.\n");
2272 
2273 	KASSERT_SC_MTX(sc);
2274 
2275 	for (q = 0; q < MVXPE_QUEUE_SIZE; q++) {
2276 		if (!MVXPE_IS_QUEUE_BUSY(queues, q))
2277 			continue;
2278 		mvxpe_tx_lockq(sc, q);
2279 		mvxpe_tx_queue_complete(sc, q);
2280 		mvxpe_tx_unlockq(sc, q);
2281 	}
2282 	KASSERT(sc->sc_tx_pending >= 0);
2283 	if (sc->sc_tx_pending == 0)
2284 		ifp->if_timer = 0;
2285 }
2286 
2287 STATIC void
2288 mvxpe_tx_queue_complete(struct mvxpe_softc *sc, int q)
2289 {
2290 	struct mvxpe_tx_ring *tx = MVXPE_TX_RING(sc, q);
2291 	struct mvxpe_tx_desc *t;
2292 	uint32_t ptxs, ptxsu, ndesc;
2293 	int i;
2294 
2295 	KASSERT_TX_MTX(sc, q);
2296 
2297 	ptxs = MVXPE_READ(sc, MVXPE_PTXS(q));
2298 	ndesc = MVXPE_PTXS_GET_TBC(ptxs);
2299 	if (ndesc == 0)
2300 		return;
2301 
2302 	DPRINTSC(sc, 2,
2303 	    "tx complete queue %d, %d descriptors.\n", q, ndesc);
2304 
2305 	mvxpe_ring_sync_tx(sc, q, tx->tx_dma, ndesc,
2306 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
2307 
2308 	for (i = 0; i < ndesc; i++) {
2309 		int error = 0;
2310 
2311 		t = MVXPE_TX_DESC(sc, q, tx->tx_dma);
2312 		if (t->flags & MVXPE_TX_F_ES) {
2313 			DPRINTSC(sc, 1,
2314 			    "tx error queue %d desc %d\n",
2315 			    q, tx->tx_dma);
2316 			switch (t->flags & MVXPE_TX_F_EC_MASK) {
2317 			case MVXPE_TX_F_EC_LC:
2318 				MVXPE_EVCNT_INCR(&sc->sc_ev.ev_txd_lc);
2319 			case MVXPE_TX_F_EC_UR:
2320 				MVXPE_EVCNT_INCR(&sc->sc_ev.ev_txd_ur);
2321 			case MVXPE_TX_F_EC_RL:
2322 				MVXPE_EVCNT_INCR(&sc->sc_ev.ev_txd_rl);
2323 			default:
2324 				MVXPE_EVCNT_INCR(&sc->sc_ev.ev_txd_oth);
2325 			}
2326 			error = 1;
2327 		}
2328 		if (MVXPE_TX_MBUF(sc, q, tx->tx_dma) != NULL) {
2329 			KASSERT((t->command & MVXPE_TX_CMD_F) != 0);
2330 			bus_dmamap_unload(sc->sc_dmat,
2331 			    MVXPE_TX_MAP(sc, q, tx->tx_dma));
2332 			m_freem(MVXPE_TX_MBUF(sc, q, tx->tx_dma));
2333 			MVXPE_TX_MBUF(sc, q, tx->tx_dma) = NULL;
2334 			sc->sc_tx_pending--;
2335 		}
2336 		else
2337 			KASSERT((t->flags & MVXPE_TX_CMD_F) == 0);
2338 		tx->tx_dma = tx_counter_adv(tx->tx_dma, 1);
2339 		tx->tx_used--;
2340 		if (error)
2341 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_drv_txqe[q]);
2342 		else
2343 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_drv_txq[q]);
2344 	}
2345 	KASSERT(tx->tx_used >= 0);
2346 	KASSERT(tx->tx_used <= tx->tx_queue_len);
2347 	while (ndesc > 255) {
2348 		ptxsu = MVXPE_PTXSU_NORB(255);
2349 		MVXPE_WRITE(sc, MVXPE_PTXSU(q), ptxsu);
2350 		ndesc -= 255;
2351 	}
2352 	if (ndesc > 0) {
2353 		ptxsu = MVXPE_PTXSU_NORB(ndesc);
2354 		MVXPE_WRITE(sc, MVXPE_PTXSU(q), ptxsu);
2355 	}
2356 	DPRINTSC(sc, 2,
2357 	    "Tx complete q %d, tx_cpu = %d, tx_dma = %d, tx_used = %d\n",
2358 	    q, tx->tx_cpu, tx->tx_dma, tx->tx_used);
2359 }
2360 
2361 /*
2362  * Rx Subroutines
2363  */
2364 STATIC void
2365 mvxpe_rx(struct mvxpe_softc *sc, uint32_t queues)
2366 {
2367 	int q, npkt;
2368 
2369 	KASSERT_SC_MTX(sc);
2370 
2371 	while ( (npkt = mvxpe_rx_queue_select(sc, queues, &q))) {
2372 		/* mutex is held by rx_queue_select */
2373 		mvxpe_rx_queue(sc, q, npkt);
2374 		mvxpe_rx_unlockq(sc, q);
2375 	}
2376 }
2377 
2378 STATIC void
2379 mvxpe_rx_queue(struct mvxpe_softc *sc, int q, int npkt)
2380 {
2381 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
2382 	struct mvxpe_rx_ring *rx = MVXPE_RX_RING(sc, q);
2383 	struct mvxpe_rx_desc *r;
2384 	struct mvxpbm_chunk *chunk;
2385 	struct mbuf *m;
2386 	uint32_t prxsu;
2387 	int error = 0;
2388 	int i;
2389 
2390 	KASSERT_RX_MTX(sc, q);
2391 
2392 	mvxpe_ring_sync_rx(sc, q, rx->rx_dma, npkt,
2393 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
2394 
2395 	for (i = 0; i < npkt; i++) {
2396 		/* get descriptor and packet */
2397 		chunk = MVXPE_RX_PKTBUF(sc, q, rx->rx_dma);
2398 		MVXPE_RX_PKTBUF(sc, q, rx->rx_dma) = NULL;
2399 		r = MVXPE_RX_DESC(sc, q, rx->rx_dma);
2400 		mvxpbm_dmamap_sync(chunk, r->bytecnt, BUS_DMASYNC_POSTREAD);
2401 
2402 		/* check errors */
2403 		if (r->status & MVXPE_RX_ES) {
2404 			switch (r->status & MVXPE_RX_EC_MASK) {
2405 			case MVXPE_RX_EC_CE:
2406 				DPRINTIFNET(ifp, 1, "CRC error\n");
2407 				MVXPE_EVCNT_INCR(&sc->sc_ev.ev_rxd_ce);
2408 				break;
2409 			case MVXPE_RX_EC_OR:
2410 				DPRINTIFNET(ifp, 1, "Rx FIFO overrun\n");
2411 				MVXPE_EVCNT_INCR(&sc->sc_ev.ev_rxd_or);
2412 				break;
2413 			case MVXPE_RX_EC_MF:
2414 				DPRINTIFNET(ifp, 1, "Rx too large frame\n");
2415 				MVXPE_EVCNT_INCR(&sc->sc_ev.ev_rxd_mf);
2416 				break;
2417 			case MVXPE_RX_EC_RE:
2418 				DPRINTIFNET(ifp, 1, "Rx resource error\n");
2419 				MVXPE_EVCNT_INCR(&sc->sc_ev.ev_rxd_re);
2420 				break;
2421 			}
2422 			error = 1;
2423 			goto rx_done;
2424 		}
2425 		if (!(r->status & MVXPE_RX_F) || !(r->status & MVXPE_RX_L)) {
2426 			DPRINTIFNET(ifp, 1, "not support scatter buf\n");
2427 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_rxd_scat);
2428 			error = 1;
2429 			goto rx_done;
2430 		}
2431 
2432 		if (chunk == NULL) {
2433 			device_printf(sc->sc_dev,
2434 			    "got rx interrupt, but no chunk\n");
2435 			error = 1;
2436 			goto rx_done;
2437 		}
2438 
2439 		/* extract packet buffer */
2440 		if (mvxpbm_init_mbuf_hdr(chunk) != 0) {
2441 			error = 1;
2442 			goto rx_done;
2443 		}
2444 		m = chunk->m;
2445 		m->m_pkthdr.rcvif = ifp;
2446 		m->m_pkthdr.len = m->m_len = r->bytecnt - ETHER_CRC_LEN;
2447 		m_adj(m, MVXPE_HWHEADER_SIZE); /* strip MH */
2448 		mvxpe_rx_set_csumflag(ifp, r, m);
2449 		ifp->if_ipackets++;
2450 		bpf_mtap(ifp, m);
2451 		(*ifp->if_input)(ifp, m);
2452 		chunk = NULL; /* the BM chunk goes to networking stack now */
2453 rx_done:
2454 		if (chunk) {
2455 			/* rx error. just return the chunk to BM. */
2456 			mvxpbm_free_chunk(chunk);
2457 		}
2458 		if (error)
2459 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_drv_rxqe[q]);
2460 		else
2461 			MVXPE_EVCNT_INCR(&sc->sc_ev.ev_drv_rxq[q]);
2462 		rx->rx_dma = rx_counter_adv(rx->rx_dma, 1);
2463 	}
2464 	/* DMA status update */
2465 	DPRINTSC(sc, 2, "%d packets received from queue %d\n", npkt, q);
2466 	while (npkt > 255) {
2467 		prxsu = MVXPE_PRXSU_NOOFPROCESSEDDESCRIPTORS(255);
2468 		MVXPE_WRITE(sc, MVXPE_PRXSU(q), prxsu);
2469 		npkt -= 255;
2470 	}
2471 	if (npkt > 0) {
2472 		prxsu = MVXPE_PRXSU_NOOFPROCESSEDDESCRIPTORS(npkt);
2473 		MVXPE_WRITE(sc, MVXPE_PRXSU(q), prxsu);
2474 	}
2475 
2476 	DPRINTSC(sc, 2,
2477 	    "PRXDQA: queue %d, %#x\n", q, MVXPE_READ(sc, MVXPE_PRXDQA(q)));
2478 	DPRINTSC(sc, 2,
2479 	    "PRXDQS: queue %d, %#x\n", q, MVXPE_READ(sc, MVXPE_PRXDQS(q)));
2480 	DPRINTSC(sc, 2,
2481 	    "PRXS: queue %d, %#x\n", q, MVXPE_READ(sc, MVXPE_PRXS(q)));
2482 	DPRINTSC(sc, 2,
2483 	    "PRXDI: queue %d, %d\n", q, MVXPE_READ(sc, MVXPE_PRXDI(q)));
2484 	DPRINTSC(sc, 2, "RQC: %#x\n", MVXPE_READ(sc, MVXPE_RQC));
2485 	DPRINTIFNET(ifp, 2, "Rx: rx_cpu = %d, rx_dma = %d\n",
2486 	    rx->rx_cpu, rx->rx_dma);
2487 }
2488 
2489 STATIC int
2490 mvxpe_rx_queue_select(struct mvxpe_softc *sc, uint32_t queues, int *queue)
2491 {
2492 	uint32_t prxs, npkt;
2493 	int q;
2494 
2495 	KASSERT_SC_MTX(sc);
2496 	KASSERT(queue != NULL);
2497 	DPRINTSC(sc, 2, "selecting rx queue\n");
2498 
2499 	for (q = MVXPE_QUEUE_SIZE - 1; q >= 0; q--) {
2500 		if (!MVXPE_IS_QUEUE_BUSY(queues, q))
2501 			continue;
2502 
2503 		prxs = MVXPE_READ(sc, MVXPE_PRXS(q));
2504 		npkt = MVXPE_PRXS_GET_ODC(prxs);
2505 		if (npkt == 0)
2506 			continue;
2507 
2508 		DPRINTSC(sc, 2,
2509 		    "queue %d selected: prxs=%#x, %u pakcet received.\n",
2510 		    q, prxs, npkt);
2511 		*queue = q;
2512 		mvxpe_rx_lockq(sc, q);
2513 		return npkt;
2514 	}
2515 
2516 	return 0;
2517 }
2518 
2519 STATIC void
2520 mvxpe_rx_refill(struct mvxpe_softc *sc, uint32_t queues)
2521 {
2522 	int q;
2523 
2524 	KASSERT_SC_MTX(sc);
2525 
2526 	/* XXX: check rx bit array */
2527 	for (q = 0; q < MVXPE_QUEUE_SIZE; q++) {
2528 		if (!MVXPE_IS_QUEUE_BUSY(queues, q))
2529 			continue;
2530 
2531 		mvxpe_rx_lockq(sc, q);
2532 		mvxpe_rx_queue_refill(sc, q);
2533 		mvxpe_rx_unlockq(sc, q);
2534 	}
2535 }
2536 
2537 STATIC void
2538 mvxpe_rx_queue_refill(struct mvxpe_softc *sc, int q)
2539 {
2540 	struct mvxpe_rx_ring *rx = MVXPE_RX_RING(sc, q);
2541 	uint32_t prxs, prxsu, ndesc;
2542 	int idx, refill = 0;
2543 	int npkt;
2544 
2545 	KASSERT_RX_MTX(sc, q);
2546 
2547 	prxs = MVXPE_READ(sc, MVXPE_PRXS(q));
2548 	ndesc = MVXPE_PRXS_GET_NODC(prxs) + MVXPE_PRXS_GET_ODC(prxs);
2549 	refill = rx->rx_queue_len - ndesc;
2550 	if (refill <= 0)
2551 		return;
2552 	DPRINTPRXS(2, q);
2553 	DPRINTSC(sc, 2, "%d buffers to refill.\n", refill);
2554 
2555 	idx = rx->rx_cpu;
2556 	for (npkt = 0; npkt < refill; npkt++)
2557 		if (mvxpe_rx_queue_add(sc, q) != 0)
2558 			break;
2559 	DPRINTSC(sc, 2, "queue %d, %d buffer refilled.\n", q, npkt);
2560 	if (npkt == 0)
2561 		return;
2562 
2563 	mvxpe_ring_sync_rx(sc, q, idx, npkt,
2564 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2565 
2566 	while (npkt > 255) {
2567 		prxsu = MVXPE_PRXSU_NOOFNEWDESCRIPTORS(255);
2568 		MVXPE_WRITE(sc, MVXPE_PRXSU(q), prxsu);
2569 		npkt -= 255;
2570 	}
2571 	if (npkt > 0) {
2572 		prxsu = MVXPE_PRXSU_NOOFNEWDESCRIPTORS(npkt);
2573 		MVXPE_WRITE(sc, MVXPE_PRXSU(q), prxsu);
2574 	}
2575 	DPRINTPRXS(2, q);
2576 	return;
2577 }
2578 
2579 STATIC int
2580 mvxpe_rx_queue_add(struct mvxpe_softc *sc, int q)
2581 {
2582 	struct mvxpe_rx_ring *rx = MVXPE_RX_RING(sc, q);
2583 	struct mvxpe_rx_desc *r;
2584 	struct mvxpbm_chunk *chunk = NULL;
2585 
2586 	KASSERT_RX_MTX(sc, q);
2587 
2588 	/* Allocate the packet buffer */
2589 	chunk = mvxpbm_alloc(sc->sc_bm);
2590 	if (chunk == NULL) {
2591 		DPRINTSC(sc, 1, "BM chunk allocation failed.\n");
2592 		return ENOBUFS;
2593 	}
2594 
2595 	/* Add the packet to descritor */
2596 	KASSERT(MVXPE_RX_PKTBUF(sc, q, rx->rx_cpu) == NULL);
2597 	MVXPE_RX_PKTBUF(sc, q, rx->rx_cpu) = chunk;
2598 	mvxpbm_dmamap_sync(chunk, BM_SYNC_ALL, BUS_DMASYNC_PREREAD);
2599 
2600 	r = MVXPE_RX_DESC(sc, q, rx->rx_cpu);
2601 	r->bufptr = chunk->buf_pa;
2602 	DPRINTSC(sc, 9, "chunk added to index %d\n", rx->rx_cpu);
2603 	rx->rx_cpu = rx_counter_adv(rx->rx_cpu, 1);
2604 	return 0;
2605 }
2606 
2607 STATIC void
2608 mvxpe_rx_set_csumflag(struct ifnet *ifp,
2609     struct mvxpe_rx_desc *r, struct mbuf *m0)
2610 {
2611 	uint32_t csum_flags = 0;
2612 
2613 	if ((r->status & (MVXPE_RX_IP_HEADER_OK|MVXPE_RX_L3_IP)) == 0)
2614 		return; /* not a IP packet */
2615 
2616 	/* L3 */
2617 	if (r->status & MVXPE_RX_L3_IP) {
2618 		csum_flags |= M_CSUM_IPv4;
2619 		if ((r->status & MVXPE_RX_IP_HEADER_OK) == 0) {
2620 			csum_flags |= M_CSUM_IPv4_BAD;
2621 			goto finish;
2622 		}
2623 		else if (r->status & MVXPE_RX_IPV4_FRAGMENT) {
2624 			/*
2625 			 * r->l4chk has partial checksum of each framgment.
2626 			 * but there is no way to use it in NetBSD.
2627 			 */
2628 			return;
2629 		}
2630 	}
2631 
2632 	/* L4 */
2633 	switch (r->status & MVXPE_RX_L4_MASK) {
2634 	case MVXPE_RX_L4_TCP:
2635 		if (r->status & MVXPE_RX_L3_IP)
2636 			csum_flags |= M_CSUM_TCPv4;
2637 		else
2638 			csum_flags |= M_CSUM_TCPv6;
2639 		if ((r->status & MVXPE_RX_L4_CHECKSUM_OK) == 0)
2640 			csum_flags |= M_CSUM_TCP_UDP_BAD;
2641 		break;
2642 	case MVXPE_RX_L4_UDP:
2643 		if (r->status & MVXPE_RX_L3_IP)
2644 			csum_flags |= M_CSUM_UDPv4;
2645 		else
2646 			csum_flags |= M_CSUM_UDPv6;
2647 		if ((r->status & MVXPE_RX_L4_CHECKSUM_OK) == 0)
2648 			csum_flags |= M_CSUM_TCP_UDP_BAD;
2649 		break;
2650 	case MVXPE_RX_L4_OTH:
2651 	default:
2652 		break;
2653 	}
2654 finish:
2655 	m0->m_pkthdr.csum_flags |= (csum_flags & ifp->if_csum_flags_rx);
2656 }
2657 
2658 /*
2659  * MAC address filter
2660  */
2661 STATIC uint8_t
2662 mvxpe_crc8(const uint8_t *data, size_t size)
2663 {
2664 	int bit;
2665 	uint8_t byte;
2666 	uint8_t crc = 0;
2667 	const uint8_t poly = 0x07;
2668 
2669 	while(size--)
2670 	  for (byte = *data++, bit = NBBY-1; bit >= 0; bit--)
2671 	    crc = (crc << 1) ^ ((((crc >> 7) ^ (byte >> bit)) & 1) ? poly : 0);
2672 
2673 	return crc;
2674 }
2675 
2676 CTASSERT(MVXPE_NDFSMT == MVXPE_NDFOMT);
2677 
2678 STATIC void
2679 mvxpe_filter_setup(struct mvxpe_softc *sc)
2680 {
2681 	struct ethercom *ec = &sc->sc_ethercom;
2682 	struct ifnet *ifp= &sc->sc_ethercom.ec_if;
2683 	struct ether_multi *enm;
2684 	struct ether_multistep step;
2685 	uint32_t dfut[MVXPE_NDFUT], dfsmt[MVXPE_NDFSMT], dfomt[MVXPE_NDFOMT];
2686 	uint32_t pxc;
2687 	int i;
2688 	const uint8_t special[ETHER_ADDR_LEN] = {0x01,0x00,0x5e,0x00,0x00,0x00};
2689 
2690 	KASSERT_SC_MTX(sc);
2691 
2692 	memset(dfut, 0, sizeof(dfut));
2693 	memset(dfsmt, 0, sizeof(dfsmt));
2694 	memset(dfomt, 0, sizeof(dfomt));
2695 
2696 	if (ifp->if_flags & (IFF_ALLMULTI|IFF_PROMISC)) {
2697 		goto allmulti;
2698 	}
2699 
2700 	ETHER_FIRST_MULTI(step, ec, enm);
2701 	while (enm != NULL) {
2702 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
2703 			/* ranges are complex and somewhat rare */
2704 			goto allmulti;
2705 		}
2706 		/* chip handles some IPv4 multicast specially */
2707 		if (memcmp(enm->enm_addrlo, special, 5) == 0) {
2708 			i = enm->enm_addrlo[5];
2709 			dfsmt[i>>2] |=
2710 			    MVXPE_DF(i&3, MVXPE_DF_QUEUE_ALL | MVXPE_DF_PASS);
2711 		} else {
2712 			i = mvxpe_crc8(enm->enm_addrlo, ETHER_ADDR_LEN);
2713 			dfomt[i>>2] |=
2714 			    MVXPE_DF(i&3, MVXPE_DF_QUEUE_ALL | MVXPE_DF_PASS);
2715 		}
2716 
2717 		ETHER_NEXT_MULTI(step, enm);
2718 	}
2719 	goto set;
2720 
2721 allmulti:
2722 	if (ifp->if_flags & (IFF_ALLMULTI|IFF_PROMISC)) {
2723 		for (i = 0; i < MVXPE_NDFSMT; i++) {
2724 			dfsmt[i] = dfomt[i] =
2725 			    MVXPE_DF(0, MVXPE_DF_QUEUE_ALL | MVXPE_DF_PASS) |
2726 			    MVXPE_DF(1, MVXPE_DF_QUEUE_ALL | MVXPE_DF_PASS) |
2727 			    MVXPE_DF(2, MVXPE_DF_QUEUE_ALL | MVXPE_DF_PASS) |
2728 			    MVXPE_DF(3, MVXPE_DF_QUEUE_ALL | MVXPE_DF_PASS);
2729 		}
2730 	}
2731 
2732 set:
2733 	pxc = MVXPE_READ(sc, MVXPE_PXC);
2734 	pxc &= ~MVXPE_PXC_UPM;
2735 	pxc |= MVXPE_PXC_RB | MVXPE_PXC_RBIP | MVXPE_PXC_RBARP;
2736 	if (ifp->if_flags & IFF_BROADCAST) {
2737 		pxc &= ~(MVXPE_PXC_RB | MVXPE_PXC_RBIP | MVXPE_PXC_RBARP);
2738 	}
2739 	if (ifp->if_flags & IFF_PROMISC) {
2740 		pxc |= MVXPE_PXC_UPM;
2741 	}
2742 	MVXPE_WRITE(sc, MVXPE_PXC, pxc);
2743 
2744 	/* Set Destination Address Filter Unicast Table */
2745 	i = sc->sc_enaddr[5] & 0xf;		/* last nibble */
2746 	dfut[i>>2] = MVXPE_DF(i&3, MVXPE_DF_QUEUE_ALL | MVXPE_DF_PASS);
2747 	MVXPE_WRITE_REGION(sc, MVXPE_DFUT(0), dfut, MVXPE_NDFUT);
2748 
2749 	/* Set Destination Address Filter Multicast Tables */
2750 	MVXPE_WRITE_REGION(sc, MVXPE_DFSMT(0), dfsmt, MVXPE_NDFSMT);
2751 	MVXPE_WRITE_REGION(sc, MVXPE_DFOMT(0), dfomt, MVXPE_NDFOMT);
2752 }
2753 
2754 /*
2755  * sysctl(9)
2756  */
2757 SYSCTL_SETUP(sysctl_mvxpe, "sysctl mvxpe subtree setup")
2758 {
2759 	int rc;
2760 	const struct sysctlnode *node;
2761 
2762 	if ((rc = sysctl_createv(clog, 0, NULL, &node,
2763 	    0, CTLTYPE_NODE, "mvxpe",
2764 	    SYSCTL_DESCR("mvxpe interface controls"),
2765 	    NULL, 0, NULL, 0,
2766 	    CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {
2767 		goto err;
2768 	}
2769 
2770 	mvxpe_root_num = node->sysctl_num;
2771 	return;
2772 
2773 err:
2774 	aprint_error("%s: syctl_createv failed (rc = %d)\n", __func__, rc);
2775 }
2776 
2777 STATIC int
2778 sysctl_read_mib(SYSCTLFN_ARGS)
2779 {
2780 	struct mvxpe_sysctl_mib *arg;
2781 	struct mvxpe_softc *sc;
2782 	struct sysctlnode node;
2783 	uint64_t val;
2784 	int err;
2785 
2786 	node = *rnode;
2787 	arg = (struct mvxpe_sysctl_mib *)rnode->sysctl_data;
2788 	if (arg == NULL)
2789 		return EINVAL;
2790 
2791 	sc = arg->sc;
2792 	if (sc == NULL)
2793 		return EINVAL;
2794 	if (arg->index < 0 || arg->index > __arraycount(mvxpe_mib_list))
2795 		return EINVAL;
2796 
2797 	mvxpe_sc_lock(sc);
2798 	val = arg->counter;
2799 	mvxpe_sc_unlock(sc);
2800 
2801 	node.sysctl_data = &val;
2802 	err = sysctl_lookup(SYSCTLFN_CALL(&node));
2803 	if (err)
2804 	       return err;
2805 	if (newp)
2806 		return EINVAL;
2807 
2808 	return 0;
2809 }
2810 
2811 
2812 STATIC int
2813 sysctl_clear_mib(SYSCTLFN_ARGS)
2814 {
2815 	struct mvxpe_softc *sc;
2816 	struct sysctlnode node;
2817 	int val;
2818 	int err;
2819 
2820 	node = *rnode;
2821 	sc = (struct mvxpe_softc *)rnode->sysctl_data;
2822 	if (sc == NULL)
2823 		return EINVAL;
2824 
2825 	val = 0;
2826 	node.sysctl_data = &val;
2827 	err = sysctl_lookup(SYSCTLFN_CALL(&node));
2828 	if (err || newp == NULL)
2829 		return err;
2830 	if (val < 0 || val > 1)
2831 		return EINVAL;
2832 	if (val == 1) {
2833 		mvxpe_sc_lock(sc);
2834 		mvxpe_clear_mib(sc);
2835 		mvxpe_sc_unlock(sc);
2836 	}
2837 
2838 	return 0;
2839 }
2840 
2841 STATIC int
2842 sysctl_set_queue_length(SYSCTLFN_ARGS)
2843 {
2844 	struct mvxpe_sysctl_queue *arg;
2845 	struct mvxpe_rx_ring *rx = NULL;
2846 	struct mvxpe_tx_ring *tx = NULL;
2847 	struct mvxpe_softc *sc;
2848 	struct sysctlnode node;
2849 	uint32_t reg;
2850 	int val;
2851 	int err;
2852 
2853 	node = *rnode;
2854 
2855 	arg = (struct mvxpe_sysctl_queue *)rnode->sysctl_data;
2856 	if (arg == NULL)
2857 		return EINVAL;
2858 	if (arg->queue < 0 || arg->queue > MVXPE_RX_RING_CNT)
2859 		return EINVAL;
2860 	if (arg->rxtx != MVXPE_SYSCTL_RX && arg->rxtx != MVXPE_SYSCTL_TX)
2861 		return EINVAL;
2862 
2863 	sc = arg->sc;
2864 	if (sc == NULL)
2865 		return EINVAL;
2866 
2867 	/* read queue length */
2868 	mvxpe_sc_lock(sc);
2869 	switch (arg->rxtx) {
2870 	case  MVXPE_SYSCTL_RX:
2871 		mvxpe_rx_lockq(sc, arg->queue);
2872 		rx = MVXPE_RX_RING(sc, arg->queue);
2873 		val = rx->rx_queue_len;
2874 		mvxpe_rx_unlockq(sc, arg->queue);
2875 		break;
2876 	case  MVXPE_SYSCTL_TX:
2877 		mvxpe_tx_lockq(sc, arg->queue);
2878 		tx = MVXPE_TX_RING(sc, arg->queue);
2879 		val = tx->tx_queue_len;
2880 		mvxpe_tx_unlockq(sc, arg->queue);
2881 		break;
2882 	}
2883 
2884 	node.sysctl_data = &val;
2885 	err = sysctl_lookup(SYSCTLFN_CALL(&node));
2886 	if (err || newp == NULL) {
2887 		mvxpe_sc_unlock(sc);
2888 		return err;
2889 	}
2890 
2891 	/* update queue length */
2892 	if (val < 8 || val > MVXPE_RX_RING_CNT) {
2893 		mvxpe_sc_unlock(sc);
2894 		return EINVAL;
2895 	}
2896 	switch (arg->rxtx) {
2897 	case  MVXPE_SYSCTL_RX:
2898 		mvxpe_rx_lockq(sc, arg->queue);
2899 		rx->rx_queue_len = val;
2900 		rx->rx_queue_th_received =
2901 		    rx->rx_queue_len / MVXPE_RXTH_RATIO;
2902 		rx->rx_queue_th_free =
2903 		    rx->rx_queue_len / MVXPE_RXTH_REFILL_RATIO;
2904 
2905 		reg  = MVXPE_PRXDQTH_ODT(rx->rx_queue_th_received);
2906 		reg |= MVXPE_PRXDQTH_NODT(rx->rx_queue_th_free);
2907 		MVXPE_WRITE(sc, MVXPE_PRXDQTH(arg->queue), reg);
2908 
2909 		mvxpe_rx_unlockq(sc, arg->queue);
2910 		break;
2911 	case  MVXPE_SYSCTL_TX:
2912 		mvxpe_tx_lockq(sc, arg->queue);
2913 		tx->tx_queue_len = val;
2914 		tx->tx_queue_th_free =
2915 		    tx->tx_queue_len / MVXPE_TXTH_RATIO;
2916 
2917 		reg  = MVXPE_PTXDQS_TBT(tx->tx_queue_th_free);
2918 		reg |= MVXPE_PTXDQS_DQS(MVXPE_TX_RING_CNT);
2919 		MVXPE_WRITE(sc, MVXPE_PTXDQS(arg->queue), reg);
2920 
2921 		mvxpe_tx_unlockq(sc, arg->queue);
2922 		break;
2923 	}
2924 	mvxpe_sc_unlock(sc);
2925 
2926 	return 0;
2927 }
2928 
2929 STATIC int
2930 sysctl_set_queue_rxthtime(SYSCTLFN_ARGS)
2931 {
2932 	struct mvxpe_sysctl_queue *arg;
2933 	struct mvxpe_rx_ring *rx = NULL;
2934 	struct mvxpe_softc *sc;
2935 	struct sysctlnode node;
2936 	extern uint32_t mvTclk;
2937 	uint32_t reg, time_mvtclk;
2938 	int time_us;
2939 	int err;
2940 
2941 	node = *rnode;
2942 
2943 	arg = (struct mvxpe_sysctl_queue *)rnode->sysctl_data;
2944 	if (arg == NULL)
2945 		return EINVAL;
2946 	if (arg->queue < 0 || arg->queue > MVXPE_RX_RING_CNT)
2947 		return EINVAL;
2948 	if (arg->rxtx != MVXPE_SYSCTL_RX)
2949 		return EINVAL;
2950 
2951 	sc = arg->sc;
2952 	if (sc == NULL)
2953 		return EINVAL;
2954 
2955 	/* read queue length */
2956 	mvxpe_sc_lock(sc);
2957 	mvxpe_rx_lockq(sc, arg->queue);
2958 	rx = MVXPE_RX_RING(sc, arg->queue);
2959 	time_mvtclk = rx->rx_queue_th_time;
2960 	time_us = ((uint64_t)time_mvtclk * 1000ULL * 1000ULL) / mvTclk;
2961 	node.sysctl_data = &time_us;
2962 	DPRINTSC(sc, 1, "RXITTH(%d) => %#x\n",
2963 	    arg->queue, MVXPE_READ(sc, MVXPE_PRXITTH(arg->queue)));
2964 	err = sysctl_lookup(SYSCTLFN_CALL(&node));
2965 	if (err || newp == NULL) {
2966 		mvxpe_rx_unlockq(sc, arg->queue);
2967 		mvxpe_sc_unlock(sc);
2968 		return err;
2969 	}
2970 
2971 	/* update queue length (0[sec] - 1[sec]) */
2972 	if (time_us < 0 || time_us > (1000 * 1000)) {
2973 		mvxpe_rx_unlockq(sc, arg->queue);
2974 		mvxpe_sc_unlock(sc);
2975 		return EINVAL;
2976 	}
2977 	time_mvtclk =
2978 	    (uint64_t)mvTclk * (uint64_t)time_us / (1000ULL * 1000ULL);
2979 	rx->rx_queue_th_time = time_mvtclk;
2980 	reg = MVXPE_PRXITTH_RITT(rx->rx_queue_th_time);
2981 	MVXPE_WRITE(sc, MVXPE_PRXITTH(arg->queue), reg);
2982 	DPRINTSC(sc, 1, "RXITTH(%d) => %#x\n", arg->queue, reg);
2983 	mvxpe_rx_unlockq(sc, arg->queue);
2984 	mvxpe_sc_unlock(sc);
2985 
2986 	return 0;
2987 }
2988 
2989 
2990 STATIC void
2991 sysctl_mvxpe_init(struct mvxpe_softc *sc)
2992 {
2993 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
2994 	const struct sysctlnode *node;
2995 	int mvxpe_nodenum;
2996 	int mvxpe_mibnum;
2997 	int mvxpe_rxqueuenum;
2998 	int mvxpe_txqueuenum;
2999 	int q, i;
3000 
3001 	/* hw.mvxpe.mvxpe[unit] */
3002 	if (sysctl_createv(&sc->sc_mvxpe_clog, 0, NULL, &node,
3003 	    0, CTLTYPE_NODE, ifp->if_xname,
3004 	    SYSCTL_DESCR("mvxpe per-controller controls"),
3005 	    NULL, 0, NULL, 0,
3006 	    CTL_HW, mvxpe_root_num, CTL_CREATE,
3007 	    CTL_EOL) != 0) {
3008 		aprint_normal_dev(sc->sc_dev, "couldn't create sysctl node\n");
3009 		return;
3010 	}
3011 	mvxpe_nodenum = node->sysctl_num;
3012 
3013 	/* hw.mvxpe.mvxpe[unit].mib */
3014 	if (sysctl_createv(&sc->sc_mvxpe_clog, 0, NULL, &node,
3015 	    0, CTLTYPE_NODE, "mib",
3016 	    SYSCTL_DESCR("mvxpe per-controller MIB counters"),
3017 	    NULL, 0, NULL, 0,
3018 	    CTL_HW, mvxpe_root_num, mvxpe_nodenum, CTL_CREATE,
3019 	    CTL_EOL) != 0) {
3020 		aprint_normal_dev(sc->sc_dev, "couldn't create sysctl node\n");
3021 		return;
3022 	}
3023 	mvxpe_mibnum = node->sysctl_num;
3024 
3025 	/* hw.mvxpe.mvxpe[unit].rx */
3026 	if (sysctl_createv(&sc->sc_mvxpe_clog, 0, NULL, &node,
3027 	    0, CTLTYPE_NODE, "rx",
3028 	    SYSCTL_DESCR("Rx Queues"),
3029 	    NULL, 0, NULL, 0,
3030 	    CTL_HW, mvxpe_root_num, mvxpe_nodenum, CTL_CREATE, CTL_EOL) != 0) {
3031 		aprint_normal_dev(sc->sc_dev, "couldn't create sysctl node\n");
3032 		return;
3033 	}
3034 	mvxpe_rxqueuenum = node->sysctl_num;
3035 
3036 	/* hw.mvxpe.mvxpe[unit].tx */
3037 	if (sysctl_createv(&sc->sc_mvxpe_clog, 0, NULL, &node,
3038 	    0, CTLTYPE_NODE, "tx",
3039 	    SYSCTL_DESCR("Tx Queues"),
3040 	    NULL, 0, NULL, 0,
3041 	    CTL_HW, mvxpe_root_num, mvxpe_nodenum, CTL_CREATE, CTL_EOL) != 0) {
3042 		aprint_normal_dev(sc->sc_dev, "couldn't create sysctl node\n");
3043 		return;
3044 	}
3045 	mvxpe_txqueuenum = node->sysctl_num;
3046 
3047 #ifdef MVXPE_DEBUG
3048 	/* hw.mvxpe.debug */
3049 	if (sysctl_createv(&sc->sc_mvxpe_clog, 0, NULL, &node,
3050 	    CTLFLAG_READWRITE, CTLTYPE_INT, "debug",
3051 	    SYSCTL_DESCR("mvgbe device driver debug control"),
3052 	    NULL, 0, &mvxpe_debug, 0,
3053 	    CTL_HW, mvxpe_root_num, CTL_CREATE, CTL_EOL) != 0) {
3054 		aprint_normal_dev(sc->sc_dev, "couldn't create sysctl node\n");
3055 		return;
3056 	}
3057 #endif
3058 	/*
3059 	 * MIB access
3060 	 */
3061 	/* hw.mvxpe.mvxpe[unit].mib.<mibs> */
3062 	for (i = 0; i < __arraycount(mvxpe_mib_list); i++) {
3063 		const char *name = mvxpe_mib_list[i].sysctl_name;
3064 		const char *desc = mvxpe_mib_list[i].desc;
3065 		struct mvxpe_sysctl_mib *mib_arg = &sc->sc_sysctl_mib[i];
3066 
3067 		mib_arg->sc = sc;
3068 		mib_arg->index = i;
3069 		if (sysctl_createv(&sc->sc_mvxpe_clog, 0, NULL, &node,
3070 		    CTLFLAG_READONLY, CTLTYPE_QUAD, name, desc,
3071 		    sysctl_read_mib, 0, (void *)mib_arg, 0,
3072 		    CTL_HW, mvxpe_root_num, mvxpe_nodenum, mvxpe_mibnum,
3073 		    CTL_CREATE, CTL_EOL) != 0) {
3074 			aprint_normal_dev(sc->sc_dev,
3075 			    "couldn't create sysctl node\n");
3076 			break;
3077 		}
3078 	}
3079 
3080 	for (q = 0; q < MVXPE_QUEUE_SIZE; q++) {
3081 		struct mvxpe_sysctl_queue *rxarg = &sc->sc_sysctl_rx_queue[q];
3082 		struct mvxpe_sysctl_queue *txarg = &sc->sc_sysctl_tx_queue[q];
3083 #define MVXPE_SYSCTL_NAME(num) "queue" # num
3084 		static const char *sysctl_queue_names[] = {
3085 			MVXPE_SYSCTL_NAME(0), MVXPE_SYSCTL_NAME(1),
3086 			MVXPE_SYSCTL_NAME(2), MVXPE_SYSCTL_NAME(3),
3087 			MVXPE_SYSCTL_NAME(4), MVXPE_SYSCTL_NAME(5),
3088 			MVXPE_SYSCTL_NAME(6), MVXPE_SYSCTL_NAME(7),
3089 		};
3090 #undef MVXPE_SYSCTL_NAME
3091 #ifdef SYSCTL_INCLUDE_DESCR
3092 #define MVXPE_SYSCTL_DESCR(num) "configuration parameters for queue " # num
3093 		static const char *sysctl_queue_descrs[] = {
3094 			MVXPE_SYSCTL_DESC(0), MVXPE_SYSCTL_DESC(1),
3095 			MVXPE_SYSCTL_DESC(2), MVXPE_SYSCTL_DESC(3),
3096 			MVXPE_SYSCTL_DESC(4), MVXPE_SYSCTL_DESC(5),
3097 			MVXPE_SYSCTL_DESC(6), MVXPE_SYSCTL_DESC(7),
3098 		};
3099 #undef MVXPE_SYSCTL_DESCR
3100 #endif /* SYSCTL_INCLUDE_DESCR */
3101 		int mvxpe_curnum;
3102 
3103 		rxarg->sc = txarg->sc = sc;
3104 		rxarg->queue = txarg->queue = q;
3105 		rxarg->rxtx = MVXPE_SYSCTL_RX;
3106 		txarg->rxtx = MVXPE_SYSCTL_TX;
3107 
3108 		/* hw.mvxpe.mvxpe[unit].rx.[queue] */
3109 		if (sysctl_createv(&sc->sc_mvxpe_clog, 0, NULL, &node,
3110 		    0, CTLTYPE_NODE,
3111 		    sysctl_queue_names[q], SYSCTL_DESCR(sysctl_queue_descrs[q]),
3112 		    NULL, 0, NULL, 0,
3113 		    CTL_HW, mvxpe_root_num, mvxpe_nodenum, mvxpe_rxqueuenum,
3114 		    CTL_CREATE, CTL_EOL) != 0) {
3115 			aprint_normal_dev(sc->sc_dev,
3116 			    "couldn't create sysctl node\n");
3117 			break;
3118 		}
3119 		mvxpe_curnum = node->sysctl_num;
3120 
3121 		/* hw.mvxpe.mvxpe[unit].rx.[queue].length */
3122 		if (sysctl_createv(&sc->sc_mvxpe_clog, 0, NULL, &node,
3123 		    CTLFLAG_READWRITE, CTLTYPE_INT, "length",
3124 		    SYSCTL_DESCR("maximum length of the queue"),
3125 		    sysctl_set_queue_length, 0, (void *)rxarg, 0,
3126 		    CTL_HW, mvxpe_root_num, mvxpe_nodenum, mvxpe_rxqueuenum,
3127 		    mvxpe_curnum, CTL_CREATE, CTL_EOL) != 0) {
3128 			aprint_normal_dev(sc->sc_dev,
3129 			    "couldn't create sysctl node\n");
3130 			break;
3131 		}
3132 
3133 		/* hw.mvxpe.mvxpe[unit].rx.[queue].threshold_timer_us */
3134 		if (sysctl_createv(&sc->sc_mvxpe_clog, 0, NULL, &node,
3135 		    CTLFLAG_READWRITE, CTLTYPE_INT, "threshold_timer_us",
3136 		    SYSCTL_DESCR("interrupt coalescing threshold timer [us]"),
3137 		    sysctl_set_queue_rxthtime, 0, (void *)rxarg, 0,
3138 		    CTL_HW, mvxpe_root_num, mvxpe_nodenum, mvxpe_rxqueuenum,
3139 		    mvxpe_curnum, CTL_CREATE, CTL_EOL) != 0) {
3140 			aprint_normal_dev(sc->sc_dev,
3141 			    "couldn't create sysctl node\n");
3142 			break;
3143 		}
3144 
3145 		/* hw.mvxpe.mvxpe[unit].tx.[queue] */
3146 		if (sysctl_createv(&sc->sc_mvxpe_clog, 0, NULL, &node,
3147 		    0, CTLTYPE_NODE,
3148 		    sysctl_queue_names[q], SYSCTL_DESCR(sysctl_queue_descs[q]),
3149 		    NULL, 0, NULL, 0,
3150 		    CTL_HW, mvxpe_root_num, mvxpe_nodenum, mvxpe_txqueuenum,
3151 		    CTL_CREATE, CTL_EOL) != 0) {
3152 			aprint_normal_dev(sc->sc_dev,
3153 			    "couldn't create sysctl node\n");
3154 			break;
3155 		}
3156 		mvxpe_curnum = node->sysctl_num;
3157 
3158 		/* hw.mvxpe.mvxpe[unit].tx.length[queue] */
3159 		if (sysctl_createv(&sc->sc_mvxpe_clog, 0, NULL, &node,
3160 		    CTLFLAG_READWRITE, CTLTYPE_INT, "length",
3161 		    SYSCTL_DESCR("maximum length of the queue"),
3162 		    sysctl_set_queue_length, 0, (void *)txarg, 0,
3163 		    CTL_HW, mvxpe_root_num, mvxpe_nodenum, mvxpe_txqueuenum,
3164 		    mvxpe_curnum, CTL_CREATE, CTL_EOL) != 0) {
3165 			aprint_normal_dev(sc->sc_dev,
3166 			    "couldn't create sysctl node\n");
3167 			break;
3168 		}
3169 	}
3170 
3171 	/* hw.mvxpe.mvxpe[unit].clear_mib */
3172 	if (sysctl_createv(&sc->sc_mvxpe_clog, 0, NULL, &node,
3173 	    CTLFLAG_READWRITE, CTLTYPE_INT, "clear_mib",
3174 	    SYSCTL_DESCR("mvgbe device driver debug control"),
3175 	    sysctl_clear_mib, 0, (void *)sc, 0,
3176 	    CTL_HW, mvxpe_root_num, mvxpe_nodenum, CTL_CREATE,
3177 	    CTL_EOL) != 0) {
3178 		aprint_normal_dev(sc->sc_dev, "couldn't create sysctl node\n");
3179 		return;
3180 	}
3181 
3182 }
3183 
3184 /*
3185  * MIB
3186  */
3187 STATIC void
3188 mvxpe_clear_mib(struct mvxpe_softc *sc)
3189 {
3190 	int i;
3191 
3192 	KASSERT_SC_MTX(sc);
3193 
3194 	for (i = 0; i < __arraycount(mvxpe_mib_list); i++) {
3195 		if (mvxpe_mib_list[i].reg64)
3196 			MVXPE_READ_MIB(sc, (mvxpe_mib_list[i].regnum + 4));
3197 		MVXPE_READ_MIB(sc, mvxpe_mib_list[i].regnum);
3198 		sc->sc_sysctl_mib[i].counter = 0;
3199 	}
3200 }
3201 
3202 STATIC void
3203 mvxpe_update_mib(struct mvxpe_softc *sc)
3204 {
3205 	int i;
3206 
3207 	KASSERT_SC_MTX(sc);
3208 
3209 	for (i = 0; i < __arraycount(mvxpe_mib_list); i++) {
3210 		uint32_t val_hi;
3211 		uint32_t val_lo;
3212 
3213 		if (mvxpe_mib_list[i].reg64) {
3214 			/* XXX: implement bus_space_read_8() */
3215 			val_lo = MVXPE_READ_MIB(sc,
3216 			    (mvxpe_mib_list[i].regnum + 4));
3217 			val_hi = MVXPE_READ_MIB(sc, mvxpe_mib_list[i].regnum);
3218 		}
3219 		else {
3220 			val_lo = MVXPE_READ_MIB(sc, mvxpe_mib_list[i].regnum);
3221 			val_hi = 0;
3222 		}
3223 
3224 		if ((val_lo | val_hi) == 0)
3225 			continue;
3226 
3227 		sc->sc_sysctl_mib[i].counter +=
3228 	       	    ((uint64_t)val_hi << 32) | (uint64_t)val_lo;
3229 	}
3230 }
3231 
3232 /*
3233  * for Debug
3234  */
3235 STATIC void
3236 mvxpe_dump_txdesc(struct mvxpe_tx_desc *desc, int idx)
3237 {
3238 #define DESC_PRINT(X)					\
3239 	if (X)						\
3240 		printf("txdesc[%d]." #X "=%#x\n", idx, X);
3241 
3242        DESC_PRINT(desc->command);
3243        DESC_PRINT(desc->l4ichk);
3244        DESC_PRINT(desc->bytecnt);
3245        DESC_PRINT(desc->bufptr);
3246        DESC_PRINT(desc->flags);
3247 #undef DESC_PRINT
3248 }
3249 
3250 STATIC void
3251 mvxpe_dump_rxdesc(struct mvxpe_rx_desc *desc, int idx)
3252 {
3253 #define DESC_PRINT(X)					\
3254 	if (X)						\
3255 		printf("rxdesc[%d]." #X "=%#x\n", idx, X);
3256 
3257        DESC_PRINT(desc->status);
3258        DESC_PRINT(desc->bytecnt);
3259        DESC_PRINT(desc->bufptr);
3260        DESC_PRINT(desc->l4chk);
3261 #undef DESC_PRINT
3262 }
3263