xref: /netbsd-src/sys/arch/mips/sibyte/dev/sbmac.c (revision 274254cdae52594c1aa480a736aef78313d15c9c)
1 /* $NetBSD: sbmac.c,v 1.32 2009/03/18 17:06:45 cegger Exp $ */
2 
3 /*
4  * Copyright 2000, 2001, 2004
5  * Broadcom Corporation. All rights reserved.
6  *
7  * This software is furnished under license and may be used and copied only
8  * in accordance with the following terms and conditions.  Subject to these
9  * conditions, you may download, copy, install, use, modify and distribute
10  * modified or unmodified copies of this software in source and/or binary
11  * form. No title or ownership is transferred hereby.
12  *
13  * 1) Any source code used, modified or distributed must reproduce and
14  *    retain this copyright notice and list of conditions as they appear in
15  *    the source file.
16  *
17  * 2) No right is granted to use any trade name, trademark, or logo of
18  *    Broadcom Corporation.  The "Broadcom Corporation" name may not be
19  *    used to endorse or promote products derived from this software
20  *    without the prior written permission of Broadcom Corporation.
21  *
22  * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
23  *    WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
24  *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
25  *    NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
26  *    FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
27  *    LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30  *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31  *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32  *    OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include <sys/cdefs.h>
36 __KERNEL_RCSID(0, "$NetBSD: sbmac.c,v 1.32 2009/03/18 17:06:45 cegger Exp $");
37 
38 #include "bpfilter.h"
39 #include "opt_inet.h"
40 #include "opt_ns.h"
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/sockio.h>
45 #include <sys/mbuf.h>
46 #include <sys/malloc.h>
47 #include <sys/kernel.h>
48 #include <sys/socket.h>
49 #include <sys/queue.h>
50 #include <sys/device.h>
51 
52 #include <net/if.h>
53 #include <net/if_arp.h>
54 #include <net/if_ether.h>
55 #include <net/if_dl.h>
56 #include <net/if_media.h>
57 
58 #if NBPFILTER > 0
59 #include <net/bpf.h>
60 #endif
61 
62 #ifdef INET
63 #include <netinet/in.h>
64 #include <netinet/if_inarp.h>
65 #endif
66 
67 #ifdef NS
68 #include <netns/ns.h>
69 #include <netns/ns_if.h>
70 #endif
71 
72 #include <machine/locore.h>
73 
74 #include "sbobiovar.h"
75 
76 #include <dev/mii/mii.h>
77 #include <dev/mii/miivar.h>
78 #include <dev/mii/mii_bitbang.h>
79 
80 #include <mips/sibyte/include/sb1250_defs.h>
81 #include <mips/sibyte/include/sb1250_regs.h>
82 #include <mips/sibyte/include/sb1250_mac.h>
83 #include <mips/sibyte/include/sb1250_dma.h>
84 #include <mips/sibyte/include/sb1250_scd.h>
85 
86 /* Simple types */
87 
88 typedef u_long sbmac_port_t;
89 typedef uint64_t sbmac_physaddr_t;
90 typedef uint64_t sbmac_enetaddr_t;
91 
92 typedef enum { sbmac_speed_auto, sbmac_speed_10,
93 	       sbmac_speed_100, sbmac_speed_1000 } sbmac_speed_t;
94 
95 typedef enum { sbmac_duplex_auto, sbmac_duplex_half,
96 	       sbmac_duplex_full } sbmac_duplex_t;
97 
98 typedef enum { sbmac_fc_auto, sbmac_fc_disabled, sbmac_fc_frame,
99 	       sbmac_fc_collision, sbmac_fc_carrier } sbmac_fc_t;
100 
101 typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on,
102 	       sbmac_state_broken } sbmac_state_t;
103 
104 
105 /* Macros */
106 
107 #define	SBMAC_EVENT_COUNTERS	/* Include counters for various events */
108 
109 #define	SBDMA_NEXTBUF(d, f)	((f + 1) & (d)->sbdma_dscr_mask)
110 
111 #define	CACHELINESIZE 32
112 #define	NUMCACHEBLKS(x) (((x)+CACHELINESIZE-1)/CACHELINESIZE)
113 #define	KMALLOC(x) malloc((x), M_DEVBUF, M_DONTWAIT)
114 #define	KVTOPHYS(x) kvtophys((vaddr_t)(x))
115 
116 #ifdef SBMACDEBUG
117 #define	dprintf(x)	printf x
118 #else
119 #define	dprintf(x)
120 #endif
121 
122 #define	SBMAC_READCSR(t) mips3_ld((uint64_t *) (t))
123 #define	SBMAC_WRITECSR(t, v) mips3_sd((uint64_t *) (t), (v))
124 
125 #define	PKSEG1(x) ((sbmac_port_t) MIPS_PHYS_TO_KSEG1(x))
126 
127 /* These are limited to fit within one virtual page, and must be 2**N.  */
128 #define	SBMAC_MAX_TXDESCR	256		/* should be 1024 */
129 #define	SBMAC_MAX_RXDESCR	256		/* should be 512 */
130 
131 #define	ETHER_ALIGN	2
132 
133 /* DMA Descriptor structure */
134 
135 typedef struct sbdmadscr_s {
136 	uint64_t dscr_a;
137 	uint64_t dscr_b;
138 } sbdmadscr_t;
139 
140 
141 /* DMA Controller structure */
142 
143 typedef struct sbmacdma_s {
144 
145 	/*
146 	 * This stuff is used to identify the channel and the registers
147 	 * associated with it.
148 	 */
149 
150 	struct sbmac_softc *sbdma_eth;	/* back pointer to associated MAC */
151 	int		sbdma_channel;	/* channel number */
152 	int		sbdma_txdir;	/* direction (1=transmit) */
153 	int		sbdma_maxdescr;	/* total # of descriptors in ring */
154 	sbmac_port_t	sbdma_config0;	/* DMA config register 0 */
155 	sbmac_port_t	sbdma_config1;	/* DMA config register 1 */
156 	sbmac_port_t	sbdma_dscrbase;	/* Descriptor base address */
157 	sbmac_port_t	sbdma_dscrcnt; 	/* Descriptor count register */
158 	sbmac_port_t	sbdma_curdscr;	/* current descriptor address */
159 
160 	/*
161 	 * This stuff is for maintenance of the ring
162 	 */
163 	sbdmadscr_t	*sbdma_dscrtable;	/* base of descriptor table */
164 	struct mbuf	**sbdma_ctxtable;	/* context table, one per descr */
165 	unsigned int	sbdma_dscr_mask;	/* sbdma_maxdescr - 1 */
166 	paddr_t		sbdma_dscrtable_phys;	/* and also the phys addr */
167 	unsigned int	sbdma_add_index;	/* next dscr for sw to add */
168 	unsigned int	sbdma_rem_index;	/* next dscr for sw to remove */
169 } sbmacdma_t;
170 
171 
172 /* Ethernet softc structure */
173 
174 struct sbmac_softc {
175 
176 	/*
177 	 * NetBSD-specific things
178 	 */
179 	struct device	sc_dev;		/* base device (must be first) */
180 	struct ethercom	sc_ethercom;	/* Ethernet common part */
181 	struct mii_data	sc_mii;
182 	struct callout	sc_tick_ch;
183 
184 	int		sbm_if_flags;
185 	void		*sbm_intrhand;
186 
187 	/*
188 	 * Controller-specific things
189 	 */
190 
191 	sbmac_port_t	sbm_base;	/* MAC's base address */
192 	sbmac_state_t	sbm_state;	/* current state */
193 
194 	sbmac_port_t	sbm_macenable;	/* MAC Enable Register */
195 	sbmac_port_t	sbm_maccfg;	/* MAC Configuration Register */
196 	sbmac_port_t	sbm_fifocfg;	/* FIFO configuration register */
197 	sbmac_port_t	sbm_framecfg;	/* Frame configuration register */
198 	sbmac_port_t	sbm_rxfilter;	/* receive filter register */
199 	sbmac_port_t	sbm_isr;	/* Interrupt status register */
200 	sbmac_port_t	sbm_imr;	/* Interrupt mask register */
201 
202 	sbmac_speed_t	sbm_speed;	/* current speed */
203 	sbmac_duplex_t	sbm_duplex;	/* current duplex */
204 	sbmac_fc_t	sbm_fc;		/* current flow control setting */
205 	int		sbm_rxflags;	/* received packet flags */
206 
207 	u_char		sbm_hwaddr[ETHER_ADDR_LEN];
208 
209 	sbmacdma_t	sbm_txdma;	/* for now, only use channel 0 */
210 	sbmacdma_t	sbm_rxdma;
211 
212 	int		sbm_pass3_dma;	/* chip has pass3 SOC DMA features */
213 
214 #ifdef SBMAC_EVENT_COUNTERS
215 	struct evcnt	sbm_ev_rxintr;	/* Rx interrupts */
216 	struct evcnt	sbm_ev_txintr;	/* Tx interrupts */
217 	struct evcnt	sbm_ev_txdrop;	/* Tx dropped due to no mbuf alloc failed */
218 	struct evcnt	sbm_ev_txstall;	/* Tx stalled due to no descriptors free */
219 
220 	struct evcnt	sbm_ev_txsplit;	/* pass3 Tx split mbuf */
221 	struct evcnt	sbm_ev_txkeep;	/* pass3 Tx didn't split mbuf */
222 #endif
223 };
224 
225 
226 #ifdef SBMAC_EVENT_COUNTERS
227 #define	SBMAC_EVCNT_INCR(ev)	(ev).ev_count++
228 #else
229 #define	SBMAC_EVCNT_INCR(ev)	do { /* nothing */ } while (0)
230 #endif
231 
232 /* Externs */
233 
234 extern paddr_t kvtophys(vaddr_t);
235 
236 /* Prototypes */
237 
238 static void sbdma_initctx(sbmacdma_t *d, struct sbmac_softc *s, int chan,
239     int txrx, int maxdescr);
240 static void sbdma_channel_start(sbmacdma_t *d);
241 static int sbdma_add_rcvbuffer(sbmacdma_t *d, struct mbuf *m);
242 static int sbdma_add_txbuffer(sbmacdma_t *d, struct mbuf *m);
243 static void sbdma_emptyring(sbmacdma_t *d);
244 static void sbdma_fillring(sbmacdma_t *d);
245 static void sbdma_rx_process(struct sbmac_softc *sc, sbmacdma_t *d);
246 static void sbdma_tx_process(struct sbmac_softc *sc, sbmacdma_t *d);
247 static void sbmac_initctx(struct sbmac_softc *s);
248 static void sbmac_channel_start(struct sbmac_softc *s);
249 static void sbmac_channel_stop(struct sbmac_softc *s);
250 static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *,
251     sbmac_state_t);
252 static void sbmac_promiscuous_mode(struct sbmac_softc *sc, int onoff);
253 static void sbmac_init_and_start(struct sbmac_softc *sc);
254 static uint64_t sbmac_addr2reg(u_char *ptr);
255 static void sbmac_intr(void *xsc, uint32_t status, uint32_t pc);
256 static void sbmac_start(struct ifnet *ifp);
257 static void sbmac_setmulti(struct sbmac_softc *sc);
258 static int sbmac_ether_ioctl(struct ifnet *ifp, u_long cmd, void *data);
259 static int sbmac_ioctl(struct ifnet *, u_long, void *);
260 static void sbmac_watchdog(struct ifnet *ifp);
261 static int sbmac_match(struct device *parent, struct cfdata *match, void *aux);
262 static void sbmac_attach(struct device *parent, struct device *self, void *aux);
263 static int sbmac_set_speed(struct sbmac_softc *s, sbmac_speed_t speed);
264 static int sbmac_set_duplex(struct sbmac_softc *s, sbmac_duplex_t duplex,
265     sbmac_fc_t fc);
266 static void sbmac_tick(void *arg);
267 
268 
269 /* Globals */
270 
271 CFATTACH_DECL(sbmac, sizeof(struct sbmac_softc),
272     sbmac_match, sbmac_attach, NULL, NULL);
273 
274 static uint32_t sbmac_mii_bitbang_read(struct device *self);
275 static void sbmac_mii_bitbang_write(struct device *self, uint32_t val);
276 
277 static const struct mii_bitbang_ops sbmac_mii_bitbang_ops = {
278 	sbmac_mii_bitbang_read,
279 	sbmac_mii_bitbang_write,
280 	{
281 		(uint32_t)M_MAC_MDIO_OUT,	/* MII_BIT_MDO */
282 		(uint32_t)M_MAC_MDIO_IN,	/* MII_BIT_MDI */
283 		(uint32_t)M_MAC_MDC,		/* MII_BIT_MDC */
284 		0,				/* MII_BIT_DIR_HOST_PHY */
285 		(uint32_t)M_MAC_MDIO_DIR	/* MII_BIT_DIR_PHY_HOST */
286 	}
287 };
288 
289 static uint32_t
290 sbmac_mii_bitbang_read(struct device *self)
291 {
292 	struct sbmac_softc *sc = (void *) self;
293 	sbmac_port_t reg;
294 
295 	reg = PKSEG1(sc->sbm_base + R_MAC_MDIO);
296 	return (uint32_t) SBMAC_READCSR(reg);
297 }
298 
299 static void
300 sbmac_mii_bitbang_write(struct device *self, uint32_t val)
301 {
302 	struct sbmac_softc *sc = (void *) self;
303 	sbmac_port_t reg;
304 
305 	reg = PKSEG1(sc->sbm_base + R_MAC_MDIO);
306 
307 	SBMAC_WRITECSR(reg, (val &
308 	    (M_MAC_MDC|M_MAC_MDIO_DIR|M_MAC_MDIO_OUT|M_MAC_MDIO_IN)));
309 }
310 
311 /*
312  * Read an PHY register through the MII.
313  */
314 static int
315 sbmac_mii_readreg(struct device *self, int phy, int reg)
316 {
317 
318 	return (mii_bitbang_readreg(self, &sbmac_mii_bitbang_ops, phy, reg));
319 }
320 
321 /*
322  * Write to a PHY register through the MII.
323  */
324 static void
325 sbmac_mii_writereg(struct device *self, int phy, int reg, int val)
326 {
327 
328 	mii_bitbang_writereg(self, &sbmac_mii_bitbang_ops, phy, reg, val);
329 }
330 
331 static void
332 sbmac_mii_statchg(struct device *self)
333 {
334 	struct sbmac_softc *sc = (struct sbmac_softc *)self;
335 	sbmac_state_t oldstate;
336 
337 	/* Stop the MAC in preparation for changing all of the parameters. */
338 	oldstate = sbmac_set_channel_state(sc, sbmac_state_off);
339 
340 	switch (sc->sc_ethercom.ec_if.if_baudrate) {
341 	default:		/* if autonegotiation fails, assume 10Mbit */
342 	case IF_Mbps(10):
343 		sbmac_set_speed(sc, sbmac_speed_10);
344 		break;
345 
346 	case IF_Mbps(100):
347 		sbmac_set_speed(sc, sbmac_speed_100);
348 		break;
349 
350 	case IF_Mbps(1000):
351 		sbmac_set_speed(sc, sbmac_speed_1000);
352 		break;
353 	}
354 
355 	if (sc->sc_mii.mii_media_active & IFM_FDX) {
356 		/* Configure for full-duplex */
357 		/* XXX: is flow control right for 10, 100? */
358 		sbmac_set_duplex(sc, sbmac_duplex_full, sbmac_fc_frame);
359 	} else {
360 		/* Configure for half-duplex */
361 		/* XXX: is flow control right? */
362 		sbmac_set_duplex(sc, sbmac_duplex_half, sbmac_fc_disabled);
363 	}
364 
365 	/* And put it back into its former state. */
366 	sbmac_set_channel_state(sc, oldstate);
367 }
368 
369 /*
370  *  SBDMA_INITCTX(d, s, chan, txrx, maxdescr)
371  *
372  *  Initialize a DMA channel context.  Since there are potentially
373  *  eight DMA channels per MAC, it's nice to do this in a standard
374  *  way.
375  *
376  *  Input parameters:
377  *	d - sbmacdma_t structure (DMA channel context)
378  *	s - sbmac_softc structure (pointer to a MAC)
379  *	chan - channel number (0..1 right now)
380  *	txrx - Identifies DMA_TX or DMA_RX for channel direction
381  *	maxdescr - number of descriptors
382  *
383  *  Return value:
384  *	nothing
385  */
386 
387 static void
388 sbdma_initctx(sbmacdma_t *d, struct sbmac_softc *s, int chan, int txrx,
389     int maxdescr)
390 {
391 	/*
392 	 * Save away interesting stuff in the structure
393 	 */
394 
395 	d->sbdma_eth = s;
396 	d->sbdma_channel = chan;
397 	d->sbdma_txdir = txrx;
398 
399 	/*
400 	 * initialize register pointers
401 	 */
402 
403 	d->sbdma_config0 = PKSEG1(s->sbm_base +
404 	    R_MAC_DMA_REGISTER(txrx, chan, R_MAC_DMA_CONFIG0));
405 	d->sbdma_config1 = PKSEG1(s->sbm_base +
406 	    R_MAC_DMA_REGISTER(txrx, chan, R_MAC_DMA_CONFIG1));
407 	d->sbdma_dscrbase = PKSEG1(s->sbm_base +
408 	    R_MAC_DMA_REGISTER(txrx, chan, R_MAC_DMA_DSCR_BASE));
409 	d->sbdma_dscrcnt = PKSEG1(s->sbm_base +
410 	    R_MAC_DMA_REGISTER(txrx, chan, R_MAC_DMA_DSCR_CNT));
411 	d->sbdma_curdscr = PKSEG1(s->sbm_base +
412 	    R_MAC_DMA_REGISTER(txrx, chan, R_MAC_DMA_CUR_DSCRADDR));
413 
414 	/*
415 	 * Allocate memory for the ring
416 	 */
417 
418 	d->sbdma_maxdescr = maxdescr;
419 	d->sbdma_dscr_mask = d->sbdma_maxdescr - 1;
420 
421 	d->sbdma_dscrtable = (sbdmadscr_t *)
422 	    KMALLOC(d->sbdma_maxdescr * sizeof(sbdmadscr_t));
423 
424 	memset(d->sbdma_dscrtable, 0, d->sbdma_maxdescr*sizeof(sbdmadscr_t));
425 
426 	d->sbdma_dscrtable_phys = KVTOPHYS(d->sbdma_dscrtable);
427 
428 	/*
429 	 * And context table
430 	 */
431 
432 	d->sbdma_ctxtable = (struct mbuf **)
433 	    KMALLOC(d->sbdma_maxdescr*sizeof(struct mbuf *));
434 
435 	memset(d->sbdma_ctxtable, 0, d->sbdma_maxdescr*sizeof(struct mbuf *));
436 }
437 
438 /*
439  *  SBDMA_CHANNEL_START(d)
440  *
441  *  Initialize the hardware registers for a DMA channel.
442  *
443  *  Input parameters:
444  *	d - DMA channel to init (context must be previously init'd
445  *
446  *  Return value:
447  *	nothing
448  */
449 
450 static void
451 sbdma_channel_start(sbmacdma_t *d)
452 {
453 	/*
454 	 * Turn on the DMA channel
455 	 */
456 
457 	SBMAC_WRITECSR(d->sbdma_config1, 0);
458 
459 	SBMAC_WRITECSR(d->sbdma_dscrbase, d->sbdma_dscrtable_phys);
460 
461 	SBMAC_WRITECSR(d->sbdma_config0, V_DMA_RINGSZ(d->sbdma_maxdescr) | 0);
462 
463 	/*
464 	 * Initialize ring pointers
465 	 */
466 
467 	d->sbdma_add_index = 0;
468 	d->sbdma_rem_index = 0;
469 }
470 
471 /*
472  *  SBDMA_ADD_RCVBUFFER(d, m)
473  *
474  *  Add a buffer to the specified DMA channel.   For receive channels,
475  *  this queues a buffer for inbound packets.
476  *
477  *  Input parameters:
478  *	d - DMA channel descriptor
479  *	m - mbuf to add, or NULL if we should allocate one.
480  *
481  *  Return value:
482  *	0 if buffer could not be added (ring is full)
483  *	1 if buffer added successfully
484  */
485 
486 static int
487 sbdma_add_rcvbuffer(sbmacdma_t *d, struct mbuf *m)
488 {
489 	unsigned int dsc, nextdsc;
490 	struct mbuf *m_new = NULL;
491 
492 	/* get pointer to our current place in the ring */
493 
494 	dsc = d->sbdma_add_index;
495 	nextdsc = SBDMA_NEXTBUF(d, d->sbdma_add_index);
496 
497 	/*
498 	 * figure out if the ring is full - if the next descriptor
499 	 * is the same as the one that we're going to remove from
500 	 * the ring, the ring is full
501 	 */
502 
503 	if (nextdsc == d->sbdma_rem_index)
504 		return ENOSPC;
505 
506 	/*
507 	 * Allocate an mbuf if we don't already have one.
508 	 * If we do have an mbuf, reset it so that it's empty.
509 	 */
510 
511 	if (m == NULL) {
512 		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
513 		if (m_new == NULL) {
514 			printf("%s: mbuf allocation failed\n",
515 			    d->sbdma_eth->sc_dev.dv_xname);
516 			return ENOBUFS;
517 		}
518 
519 		MCLGET(m_new, M_DONTWAIT);
520 		if (!(m_new->m_flags & M_EXT)) {
521 			printf("%s: mbuf cluster allocation failed\n",
522 			    d->sbdma_eth->sc_dev.dv_xname);
523 			m_freem(m_new);
524 			return ENOBUFS;
525 		}
526 
527 		m_new->m_len = m_new->m_pkthdr.len= MCLBYTES;
528 		m_adj(m_new, ETHER_ALIGN);
529 	} else {
530 		m_new = m;
531 		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
532 		m_new->m_data = m_new->m_ext.ext_buf;
533 		m_adj(m_new, ETHER_ALIGN);
534 	}
535 
536 	/*
537 	 * fill in the descriptor
538 	 */
539 
540 	d->sbdma_dscrtable[dsc].dscr_a = KVTOPHYS(mtod(m_new, void *)) |
541 	    V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(ETHER_ALIGN + m_new->m_len)) |
542 	    M_DMA_DSCRA_INTERRUPT;
543 
544 	/* receiving: no options */
545 	d->sbdma_dscrtable[dsc].dscr_b = 0;
546 
547 	/*
548 	 * fill in the context
549 	 */
550 
551 	d->sbdma_ctxtable[dsc] = m_new;
552 
553 	/*
554 	 * point at next packet
555 	 */
556 
557 	d->sbdma_add_index = nextdsc;
558 
559 	/*
560 	 * Give the buffer to the DMA engine.
561 	 */
562 
563 	SBMAC_WRITECSR(d->sbdma_dscrcnt, 1);
564 
565 	return 0;					/* we did it */
566 }
567 
568 /*
569  *  SBDMA_ADD_TXBUFFER(d, m)
570  *
571  *  Add a transmit buffer to the specified DMA channel, causing a
572  *  transmit to start.
573  *
574  *  Input parameters:
575  *	d - DMA channel descriptor
576  *	m - mbuf to add
577  *
578  *  Return value:
579  *	0 transmit queued successfully
580  *	otherwise error code
581  */
582 
583 static int
584 sbdma_add_txbuffer(sbmacdma_t *d, struct mbuf *m)
585 {
586         unsigned int dsc, nextdsc, prevdsc, origdesc;
587 	int length;
588 	int num_mbufs = 0;
589 	struct sbmac_softc *sc = d->sbdma_eth;
590 
591 	/* get pointer to our current place in the ring */
592 
593 	dsc = d->sbdma_add_index;
594 	nextdsc = SBDMA_NEXTBUF(d, d->sbdma_add_index);
595 
596 	/*
597 	 * figure out if the ring is full - if the next descriptor
598 	 * is the same as the one that we're going to remove from
599 	 * the ring, the ring is full
600 	 */
601 
602 	if (nextdsc == d->sbdma_rem_index) {
603 		SBMAC_EVCNT_INCR(sc->sbm_ev_txstall);
604 		return ENOSPC;
605 	}
606 
607 	/*
608 	 * PASS3 parts do not have buffer alignment restriction.
609 	 * No need to copy/coalesce to new mbuf.  Also has different
610 	 * descriptor format
611 	 */
612 	if (sc->sbm_pass3_dma) {
613 		struct mbuf *m_temp = NULL;
614 
615 		/*
616 		 * Loop thru this mbuf record.
617 		 * The head mbuf will have SOP set.
618 		 */
619 		d->sbdma_dscrtable[dsc].dscr_a = KVTOPHYS(mtod(m,void *)) |
620 		    M_DMA_ETHTX_SOP;
621 
622 		/*
623 		 * transmitting: set outbound options,buffer A size(+ low 5
624 		 * bits of start addr),and packet length.
625 		 */
626 		d->sbdma_dscrtable[dsc].dscr_b =
627 		    V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_APPENDCRC_APPENDPAD) |
628 		    V_DMA_DSCRB_A_SIZE((m->m_len +
629 		      (mtod(m,unsigned int) & 0x0000001F))) |
630 		    V_DMA_DSCRB_PKT_SIZE_MSB((m->m_pkthdr.len & 0xc000) >> 14) |
631 		    V_DMA_DSCRB_PKT_SIZE(m->m_pkthdr.len & 0x3fff);
632 
633 		d->sbdma_add_index = nextdsc;
634 		origdesc = prevdsc = dsc;
635 		dsc = d->sbdma_add_index;
636 		num_mbufs++;
637 
638 		/* Start with first non-head mbuf */
639 		for(m_temp = m->m_next; m_temp != 0; m_temp = m_temp->m_next) {
640 			int len, next_len;
641 			uint64_t addr;
642 
643 			if (m_temp->m_len == 0)
644 				continue;	/* Skip 0-length mbufs */
645 
646 			len = m_temp->m_len;
647 			addr = KVTOPHYS(mtod(m_temp, void *));
648 
649 			/*
650 			 * Check to see if the mbuf spans a page boundary.  If
651 			 * it does, and the physical pages behind the virtual
652 			 * pages are not contiguous, split it so that each
653 			 * virtual page uses it's own Tx descriptor.
654 			 */
655 			if (trunc_page(addr) != trunc_page(addr + len - 1)) {
656 				next_len = (addr + len) - trunc_page(addr + len);
657 
658 				len -= next_len;
659 
660 				if (addr + len ==
661 				    KVTOPHYS(mtod(m_temp, char *) + len)) {
662 					SBMAC_EVCNT_INCR(sc->sbm_ev_txkeep);
663 					len += next_len;
664 					next_len = 0;
665 				} else {
666 					SBMAC_EVCNT_INCR(sc->sbm_ev_txsplit);
667 				}
668 			} else {
669 				next_len = 0;
670 			}
671 
672 again:
673 			/*
674 			 * fill in the descriptor
675 			 */
676 			d->sbdma_dscrtable[dsc].dscr_a = addr;
677 
678 			/*
679 			 * transmitting: set outbound options,buffer A
680 			 * size(+ low 5 bits of start addr)
681 			 */
682 			d->sbdma_dscrtable[dsc].dscr_b = V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_NOTSOP) |
683 			    V_DMA_DSCRB_A_SIZE((len + (addr & 0x0000001F)));
684 
685 			d->sbdma_ctxtable[dsc] = NULL;
686 
687 			/*
688 			 * point at next descriptor
689 			 */
690 			nextdsc = SBDMA_NEXTBUF(d, d->sbdma_add_index);
691 			if (nextdsc == d->sbdma_rem_index) {
692 				d->sbdma_add_index = origdesc;
693 				SBMAC_EVCNT_INCR(sc->sbm_ev_txstall);
694 				return ENOSPC;
695 			}
696 			d->sbdma_add_index = nextdsc;
697 
698 			prevdsc = dsc;
699 			dsc = d->sbdma_add_index;
700 			num_mbufs++;
701 
702 			if (next_len != 0) {
703 				addr = KVTOPHYS(mtod(m_temp, char *) + len);
704 				len = next_len;
705 
706 				next_len = 0;
707 				goto again;
708 			}
709 
710 		}
711 		/* Set head mbuf to last context index */
712 		d->sbdma_ctxtable[prevdsc] = m;
713 
714 		/* Interrupt on last dscr of packet.  */
715 	        d->sbdma_dscrtable[prevdsc].dscr_a |= M_DMA_DSCRA_INTERRUPT;
716 	} else {
717 		struct mbuf *m_new = NULL;
718 		/*
719 		 * [BEGIN XXX]
720 		 * XXX Copy/coalesce the mbufs into a single mbuf cluster (we
721 		 * assume it will fit).  This is a temporary hack to get us
722 		 * going.
723 		 */
724 
725 		MGETHDR(m_new,M_DONTWAIT,MT_DATA);
726 		if (m_new == NULL) {
727 			printf("%s: mbuf allocation failed\n",
728 			    d->sbdma_eth->sc_dev.dv_xname);
729 			SBMAC_EVCNT_INCR(sc->sbm_ev_txdrop);
730 			return ENOBUFS;
731 		}
732 
733 		MCLGET(m_new,M_DONTWAIT);
734 		if (!(m_new->m_flags & M_EXT)) {
735 			printf("%s: mbuf cluster allocation failed\n",
736 			    d->sbdma_eth->sc_dev.dv_xname);
737 			m_freem(m_new);
738 			SBMAC_EVCNT_INCR(sc->sbm_ev_txdrop);
739 			return ENOBUFS;
740 		}
741 
742 		m_new->m_len = m_new->m_pkthdr.len= MCLBYTES;
743 		/*m_adj(m_new,ETHER_ALIGN);*/
744 
745 		/*
746 		 * XXX Don't forget to include the offset portion in the
747 		 * XXX cache block calculation when this code is rewritten!
748 		 */
749 
750 		/*
751 		 * Copy data
752 		 */
753 
754 		m_copydata(m,0,m->m_pkthdr.len,mtod(m_new,void *));
755 		m_new->m_len = m_new->m_pkthdr.len = m->m_pkthdr.len;
756 
757 		/* Free old mbuf 'm', actual mbuf is now 'm_new' */
758 
759 		// XXX: CALLERS WILL FREE, they might have to bpf_mtap() if this
760 		// XXX: function succeeds.
761 		// m_freem(m);
762 		length = m_new->m_len;
763 
764 		/* [END XXX] */
765 		/*
766 		 * fill in the descriptor
767 		 */
768 
769 		d->sbdma_dscrtable[dsc].dscr_a = KVTOPHYS(mtod(m_new,void *)) |
770 		    V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(m_new->m_len)) |
771 		    M_DMA_DSCRA_INTERRUPT |
772 		    M_DMA_ETHTX_SOP;
773 
774 		/* transmitting: set outbound options and length */
775 		d->sbdma_dscrtable[dsc].dscr_b =
776 		    V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_APPENDCRC_APPENDPAD) |
777 		    V_DMA_DSCRB_PKT_SIZE(length);
778 
779 		num_mbufs++;
780 
781 		/*
782 		 * fill in the context
783 		 */
784 
785 		d->sbdma_ctxtable[dsc] = m_new;
786 
787 		/*
788 		 * point at next packet
789 		 */
790 		d->sbdma_add_index = nextdsc;
791 	}
792 
793 	/*
794 	 * Give the buffer to the DMA engine.
795 	 */
796 
797 	SBMAC_WRITECSR(d->sbdma_dscrcnt, num_mbufs);
798 
799 	return 0;					/* we did it */
800 }
801 
802 /*
803  *  SBDMA_EMPTYRING(d)
804  *
805  *  Free all allocated mbufs on the specified DMA channel;
806  *
807  *  Input parameters:
808  *	d  - DMA channel
809  *
810  *  Return value:
811  *	nothing
812  */
813 
814 static void
815 sbdma_emptyring(sbmacdma_t *d)
816 {
817 	int idx;
818 	struct mbuf *m;
819 
820 	for (idx = 0; idx < d->sbdma_maxdescr; idx++) {
821 		m = d->sbdma_ctxtable[idx];
822 		if (m) {
823 			m_freem(m);
824 			d->sbdma_ctxtable[idx] = NULL;
825 		}
826 	}
827 }
828 
829 /*
830  *  SBDMA_FILLRING(d)
831  *
832  *  Fill the specified DMA channel (must be receive channel)
833  *  with mbufs
834  *
835  *  Input parameters:
836  *	d - DMA channel
837  *
838  *  Return value:
839  *	nothing
840  */
841 
842 static void
843 sbdma_fillring(sbmacdma_t *d)
844 {
845 	int idx;
846 
847 	for (idx = 0; idx < SBMAC_MAX_RXDESCR-1; idx++)
848 		if (sbdma_add_rcvbuffer(d, NULL) != 0)
849 			break;
850 }
851 
852 /*
853  *  SBDMA_RX_PROCESS(sc, d)
854  *
855  *  Process "completed" receive buffers on the specified DMA channel.
856  *  Note that this isn't really ideal for priority channels, since
857  *  it processes all of the packets on a given channel before
858  *  returning.
859  *
860  *  Input parameters:
861  *	sc - softc structure
862  *	d - DMA channel context
863  *
864  *  Return value:
865  *	nothing
866  */
867 
868 static void
869 sbdma_rx_process(struct sbmac_softc *sc, sbmacdma_t *d)
870 {
871 	int curidx;
872 	int hwidx;
873 	sbdmadscr_t *dscp;
874 	struct mbuf *m;
875 	int len;
876 
877 	struct ifnet *ifp = &(sc->sc_ethercom.ec_if);
878 
879 	for (;;) {
880 		/*
881 		 * figure out where we are (as an index) and where
882 		 * the hardware is (also as an index)
883 		 *
884 		 * This could be done faster if (for example) the
885 		 * descriptor table was page-aligned and contiguous in
886 		 * both virtual and physical memory -- you could then
887 		 * just compare the low-order bits of the virtual address
888 		 * (sbdma_rem_index) and the physical address
889 		 * (sbdma_curdscr CSR).
890 		 */
891 
892 		curidx = d->sbdma_rem_index;
893 		hwidx = (int)
894 		    (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
895 		    d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
896 
897 		/*
898 		 * If they're the same, that means we've processed all
899 		 * of the descriptors up to (but not including) the one that
900 		 * the hardware is working on right now.
901 		 */
902 
903 		if (curidx == hwidx)
904 			break;
905 
906 		/*
907 		 * Otherwise, get the packet's mbuf ptr back
908 		 */
909 
910 		dscp = &(d->sbdma_dscrtable[curidx]);
911 		m = d->sbdma_ctxtable[curidx];
912 		d->sbdma_ctxtable[curidx] = NULL;
913 
914 		len = (int)G_DMA_DSCRB_PKT_SIZE(dscp->dscr_b) - 4;
915 
916 		/*
917 		 * Check packet status.  If good, process it.
918 		 * If not, silently drop it and put it back on the
919 		 * receive ring.
920 		 */
921 
922 		if (! (dscp->dscr_a & M_DMA_ETHRX_BAD)) {
923 
924 			/*
925 			 * Set length into the packet
926 			 * XXX do we remove the CRC here?
927 			 */
928 			m->m_pkthdr.len = m->m_len = len;
929 
930 			ifp->if_ipackets++;
931 			m->m_pkthdr.rcvif = ifp;
932 
933 
934 			/*
935 			 * Add a new buffer to replace the old one.
936 			 */
937 			sbdma_add_rcvbuffer(d, NULL);
938 
939 #if (NBPFILTER > 0)
940 			/*
941 			 * Handle BPF listeners. Let the BPF user see the
942 			 * packet, but don't pass it up to the ether_input()
943 			 * layer unless it's a broadcast packet, multicast
944 			 * packet, matches our ethernet address or the
945 			 * interface is in promiscuous mode.
946 			 */
947 
948 			if (ifp->if_bpf)
949 				bpf_mtap(ifp->if_bpf, m);
950 #endif
951 			/*
952 			 * Pass the buffer to the kernel
953 			 */
954 			(*ifp->if_input)(ifp, m);
955 		} else {
956 			/*
957 			 * Packet was mangled somehow.  Just drop it and
958 			 * put it back on the receive ring.
959 			 */
960 			sbdma_add_rcvbuffer(d, m);
961 		}
962 
963 		/*
964 		 * .. and advance to the next buffer.
965 		 */
966 
967 		d->sbdma_rem_index = SBDMA_NEXTBUF(d, d->sbdma_rem_index);
968 	}
969 }
970 
971 /*
972  *  SBDMA_TX_PROCESS(sc, d)
973  *
974  *  Process "completed" transmit buffers on the specified DMA channel.
975  *  This is normally called within the interrupt service routine.
976  *  Note that this isn't really ideal for priority channels, since
977  *  it processes all of the packets on a given channel before
978  *  returning.
979  *
980  *  Input parameters:
981  *	sc - softc structure
982  *	d - DMA channel context
983  *
984  *  Return value:
985  *	nothing
986  */
987 
988 static void
989 sbdma_tx_process(struct sbmac_softc *sc, sbmacdma_t *d)
990 {
991 	int curidx;
992 	int hwidx;
993 	struct mbuf *m;
994 
995 	struct ifnet *ifp = &(sc->sc_ethercom.ec_if);
996 
997 	for (;;) {
998 		/*
999 		 * figure out where we are (as an index) and where
1000 		 * the hardware is (also as an index)
1001 		 *
1002 		 * This could be done faster if (for example) the
1003 		 * descriptor table was page-aligned and contiguous in
1004 		 * both virtual and physical memory -- you could then
1005 		 * just compare the low-order bits of the virtual address
1006 		 * (sbdma_rem_index) and the physical address
1007 		 * (sbdma_curdscr CSR).
1008 		 */
1009 
1010 		curidx = d->sbdma_rem_index;
1011 		hwidx = (int)
1012 		    (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
1013 		    d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
1014 
1015 		/*
1016 		 * If they're the same, that means we've processed all
1017 		 * of the descriptors up to (but not including) the one that
1018 		 * the hardware is working on right now.
1019 		 */
1020 
1021 		if (curidx == hwidx)
1022 			break;
1023 
1024 		/*
1025 		 * Otherwise, get the packet's mbuf ptr back
1026 		 */
1027 
1028 		m = d->sbdma_ctxtable[curidx];
1029 		d->sbdma_ctxtable[curidx] = NULL;
1030 
1031 		/*
1032 		 * for transmits we just free buffers and count packets.
1033 		 */
1034 		ifp->if_opackets++;
1035 		m_freem(m);
1036 
1037 		/*
1038 		 * .. and advance to the next buffer.
1039 		 */
1040 
1041 		d->sbdma_rem_index = SBDMA_NEXTBUF(d, d->sbdma_rem_index);
1042 	}
1043 
1044 	/*
1045 	 * Decide what to set the IFF_OACTIVE bit in the interface to.
1046 	 * It's supposed to reflect if the interface is actively
1047 	 * transmitting, but that's really hard to do quickly.
1048 	 */
1049 
1050 	ifp->if_flags &= ~IFF_OACTIVE;
1051 }
1052 
1053 /*
1054  *  SBMAC_INITCTX(s)
1055  *
1056  *  Initialize an Ethernet context structure - this is called
1057  *  once per MAC on the 1250.  Memory is allocated here, so don't
1058  *  call it again from inside the ioctl routines that bring the
1059  *  interface up/down
1060  *
1061  *  Input parameters:
1062  *	s - sbmac context structure
1063  *
1064  *  Return value:
1065  *	0
1066  */
1067 
1068 static void
1069 sbmac_initctx(struct sbmac_softc *s)
1070 {
1071 	uint64_t sysrev;
1072 
1073 	/*
1074 	 * figure out the addresses of some ports
1075 	 */
1076 
1077 	s->sbm_macenable = PKSEG1(s->sbm_base + R_MAC_ENABLE);
1078 	s->sbm_maccfg    = PKSEG1(s->sbm_base + R_MAC_CFG);
1079 	s->sbm_fifocfg   = PKSEG1(s->sbm_base + R_MAC_THRSH_CFG);
1080 	s->sbm_framecfg  = PKSEG1(s->sbm_base + R_MAC_FRAMECFG);
1081 	s->sbm_rxfilter  = PKSEG1(s->sbm_base + R_MAC_ADFILTER_CFG);
1082 	s->sbm_isr       = PKSEG1(s->sbm_base + R_MAC_STATUS);
1083 	s->sbm_imr       = PKSEG1(s->sbm_base + R_MAC_INT_MASK);
1084 
1085 	/*
1086 	 * Initialize the DMA channels.  Right now, only one per MAC is used
1087 	 * Note: Only do this _once_, as it allocates memory from the kernel!
1088 	 */
1089 
1090 	sbdma_initctx(&(s->sbm_txdma), s, 0, DMA_TX, SBMAC_MAX_TXDESCR);
1091 	sbdma_initctx(&(s->sbm_rxdma), s, 0, DMA_RX, SBMAC_MAX_RXDESCR);
1092 
1093 	/*
1094 	 * initial state is OFF
1095 	 */
1096 
1097 	s->sbm_state = sbmac_state_off;
1098 
1099 	/*
1100 	 * Initial speed is (XXX TEMP) 10MBit/s HDX no FC
1101 	 */
1102 
1103 	s->sbm_speed = sbmac_speed_10;
1104 	s->sbm_duplex = sbmac_duplex_half;
1105 	s->sbm_fc = sbmac_fc_disabled;
1106 
1107 	/*
1108 	 * Determine SOC type.  112x has Pass3 SOC features.
1109 	 */
1110 	sysrev = SBMAC_READCSR( PKSEG1(A_SCD_SYSTEM_REVISION) );
1111 	s->sbm_pass3_dma = (SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1120 ||
1112 			    SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1125 ||
1113 			    SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1125H ||
1114 			    (SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1250 &&
1115 			     G_SYS_REVISION(sysrev) >= K_SYS_REVISION_BCM1250_PASS3));
1116 #ifdef SBMAC_EVENT_COUNTERS
1117 	evcnt_attach_dynamic(&s->sbm_ev_rxintr, EVCNT_TYPE_INTR,
1118 	    NULL, s->sc_dev.dv_xname, "rxintr");
1119 	evcnt_attach_dynamic(&s->sbm_ev_txintr, EVCNT_TYPE_INTR,
1120 	    NULL, s->sc_dev.dv_xname, "txintr");
1121 	evcnt_attach_dynamic(&s->sbm_ev_txdrop, EVCNT_TYPE_MISC,
1122 	    NULL, s->sc_dev.dv_xname, "txdrop");
1123 	evcnt_attach_dynamic(&s->sbm_ev_txstall, EVCNT_TYPE_MISC,
1124 	    NULL, s->sc_dev.dv_xname, "txstall");
1125 	if (s->sbm_pass3_dma) {
1126 		evcnt_attach_dynamic(&s->sbm_ev_txsplit, EVCNT_TYPE_MISC,
1127 		    NULL, s->sc_dev.dv_xname, "pass3tx-split");
1128 		evcnt_attach_dynamic(&s->sbm_ev_txkeep, EVCNT_TYPE_MISC,
1129 		    NULL, s->sc_dev.dv_xname, "pass3tx-keep");
1130 	}
1131 #endif
1132 }
1133 
1134 /*
1135  *  SBMAC_CHANNEL_START(s)
1136  *
1137  *  Start packet processing on this MAC.
1138  *
1139  *  Input parameters:
1140  *	s - sbmac structure
1141  *
1142  *  Return value:
1143  *	nothing
1144  */
1145 
1146 static void
1147 sbmac_channel_start(struct sbmac_softc *s)
1148 {
1149 	uint64_t reg;
1150 	sbmac_port_t port;
1151 	uint64_t cfg, fifo, framecfg;
1152 	int idx;
1153 	uint64_t dma_cfg0, fifo_cfg;
1154 	sbmacdma_t *txdma;
1155 
1156 	/*
1157 	 * Don't do this if running
1158 	 */
1159 
1160 	if (s->sbm_state == sbmac_state_on)
1161 		return;
1162 
1163 	/*
1164 	 * Bring the controller out of reset, but leave it off.
1165 	 */
1166 
1167 	SBMAC_WRITECSR(s->sbm_macenable, 0);
1168 
1169 	/*
1170 	 * Ignore all received packets
1171 	 */
1172 
1173 	SBMAC_WRITECSR(s->sbm_rxfilter, 0);
1174 
1175 	/*
1176 	 * Calculate values for various control registers.
1177 	 */
1178 
1179 	cfg = M_MAC_RETRY_EN |
1180 	      M_MAC_TX_HOLD_SOP_EN |
1181 	      V_MAC_TX_PAUSE_CNT_16K |
1182 	      M_MAC_AP_STAT_EN |
1183 	      M_MAC_SS_EN |
1184 	      0;
1185 
1186 	fifo = V_MAC_TX_WR_THRSH(4) |	/* Must be '4' or '8' */
1187 	       V_MAC_TX_RD_THRSH(4) |
1188 	       V_MAC_TX_RL_THRSH(4) |
1189 	       V_MAC_RX_PL_THRSH(4) |
1190 	       V_MAC_RX_RD_THRSH(4) |	/* Must be '4' */
1191 	       V_MAC_RX_PL_THRSH(4) |
1192 	       V_MAC_RX_RL_THRSH(8) |
1193 	       0;
1194 
1195 	framecfg = V_MAC_MIN_FRAMESZ_DEFAULT |
1196 	    V_MAC_MAX_FRAMESZ_DEFAULT |
1197 	    V_MAC_BACKOFF_SEL(1);
1198 
1199 	/*
1200 	 * Clear out the hash address map
1201 	 */
1202 
1203 	port = PKSEG1(s->sbm_base + R_MAC_HASH_BASE);
1204 	for (idx = 0; idx < MAC_HASH_COUNT; idx++) {
1205 		SBMAC_WRITECSR(port, 0);
1206 		port += sizeof(uint64_t);
1207 	}
1208 
1209 	/*
1210 	 * Clear out the exact-match table
1211 	 */
1212 
1213 	port = PKSEG1(s->sbm_base + R_MAC_ADDR_BASE);
1214 	for (idx = 0; idx < MAC_ADDR_COUNT; idx++) {
1215 		SBMAC_WRITECSR(port, 0);
1216 		port += sizeof(uint64_t);
1217 	}
1218 
1219 	/*
1220 	 * Clear out the DMA Channel mapping table registers
1221 	 */
1222 
1223 	port = PKSEG1(s->sbm_base + R_MAC_CHUP0_BASE);
1224 	for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) {
1225 		SBMAC_WRITECSR(port, 0);
1226 		port += sizeof(uint64_t);
1227 	}
1228 
1229 	port = PKSEG1(s->sbm_base + R_MAC_CHLO0_BASE);
1230 	for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) {
1231 		SBMAC_WRITECSR(port, 0);
1232 		port += sizeof(uint64_t);
1233 	}
1234 
1235 	/*
1236 	 * Program the hardware address.  It goes into the hardware-address
1237 	 * register as well as the first filter register.
1238 	 */
1239 
1240 	reg = sbmac_addr2reg(s->sbm_hwaddr);
1241 
1242 	port = PKSEG1(s->sbm_base + R_MAC_ADDR_BASE);
1243 	SBMAC_WRITECSR(port, reg);
1244 	port = PKSEG1(s->sbm_base + R_MAC_ETHERNET_ADDR);
1245 	SBMAC_WRITECSR(port, 0);			// pass1 workaround
1246 
1247 	/*
1248 	 * Set the receive filter for no packets, and write values
1249 	 * to the various config registers
1250 	 */
1251 
1252 	SBMAC_WRITECSR(s->sbm_rxfilter, 0);
1253 	SBMAC_WRITECSR(s->sbm_imr, 0);
1254 	SBMAC_WRITECSR(s->sbm_framecfg, framecfg);
1255 	SBMAC_WRITECSR(s->sbm_fifocfg, fifo);
1256 	SBMAC_WRITECSR(s->sbm_maccfg, cfg);
1257 
1258 	/*
1259 	 * Initialize DMA channels (rings should be ok now)
1260 	 */
1261 
1262 	sbdma_channel_start(&(s->sbm_rxdma));
1263 	sbdma_channel_start(&(s->sbm_txdma));
1264 
1265 	/*
1266 	 * Configure the speed, duplex, and flow control
1267 	 */
1268 
1269 	sbmac_set_speed(s, s->sbm_speed);
1270 	sbmac_set_duplex(s, s->sbm_duplex, s->sbm_fc);
1271 
1272 	/*
1273 	 * Fill the receive ring
1274 	 */
1275 
1276 	sbdma_fillring(&(s->sbm_rxdma));
1277 
1278 	/*
1279 	 * Turn on the rest of the bits in the enable register
1280 	 */
1281 
1282 	SBMAC_WRITECSR(s->sbm_macenable, M_MAC_RXDMA_EN0 | M_MAC_TXDMA_EN0 |
1283 	    M_MAC_RX_ENABLE | M_MAC_TX_ENABLE);
1284 
1285 
1286 	/*
1287 	 * Accept any kind of interrupt on TX and RX DMA channel 0
1288 	 */
1289 	SBMAC_WRITECSR(s->sbm_imr,
1290 	    (M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
1291 	    (M_MAC_INT_CHANNEL << S_MAC_RX_CH0));
1292 
1293 	/*
1294 	 * Enable receiving unicasts and broadcasts
1295 	 */
1296 
1297 	SBMAC_WRITECSR(s->sbm_rxfilter, M_MAC_UCAST_EN | M_MAC_BCAST_EN);
1298 
1299 	/*
1300 	 * On chips which support unaligned DMA features, set the descriptor
1301 	 * ring for transmit channels to use the unaligned buffer format.
1302 	 */
1303 	txdma = &(s->sbm_txdma);
1304 
1305 	if (s->sbm_pass3_dma) {
1306 		dma_cfg0 = SBMAC_READCSR(txdma->sbdma_config0);
1307 		dma_cfg0 |= V_DMA_DESC_TYPE(K_DMA_DESC_TYPE_RING_UAL_RMW) |
1308 		    M_DMA_TBX_EN | M_DMA_TDX_EN;
1309 		SBMAC_WRITECSR(txdma->sbdma_config0,dma_cfg0);
1310 
1311 		fifo_cfg =  SBMAC_READCSR(s->sbm_fifocfg);
1312 		fifo_cfg |= V_MAC_TX_WR_THRSH(8) |
1313 		    V_MAC_TX_RD_THRSH(8) | V_MAC_TX_RL_THRSH(8);
1314 		SBMAC_WRITECSR(s->sbm_fifocfg,fifo_cfg);
1315 	}
1316 
1317 	/*
1318 	 * we're running now.
1319 	 */
1320 
1321 	s->sbm_state = sbmac_state_on;
1322 	s->sc_ethercom.ec_if.if_flags |= IFF_RUNNING;
1323 
1324 	/*
1325 	 * Program multicast addresses
1326 	 */
1327 
1328 	sbmac_setmulti(s);
1329 
1330 	/*
1331 	 * If channel was in promiscuous mode before, turn that on
1332 	 */
1333 
1334 	if (s->sc_ethercom.ec_if.if_flags & IFF_PROMISC)
1335 		sbmac_promiscuous_mode(s, 1);
1336 
1337 	/*
1338 	 * Turn on the once-per-second timer
1339 	 */
1340 
1341 	callout_reset(&(s->sc_tick_ch), hz, sbmac_tick, s);
1342 }
1343 
1344 /*
1345  *  SBMAC_CHANNEL_STOP(s)
1346  *
1347  *  Stop packet processing on this MAC.
1348  *
1349  *  Input parameters:
1350  *	s - sbmac structure
1351  *
1352  *  Return value:
1353  *	nothing
1354  */
1355 
1356 static void
1357 sbmac_channel_stop(struct sbmac_softc *s)
1358 {
1359 	uint64_t ctl;
1360 
1361 	/* don't do this if already stopped */
1362 
1363 	if (s->sbm_state == sbmac_state_off)
1364 		return;
1365 
1366 	/* don't accept any packets, disable all interrupts */
1367 
1368 	SBMAC_WRITECSR(s->sbm_rxfilter, 0);
1369 	SBMAC_WRITECSR(s->sbm_imr, 0);
1370 
1371 	/* Turn off ticker */
1372 
1373 	callout_stop(&(s->sc_tick_ch));
1374 
1375 	/* turn off receiver and transmitter */
1376 
1377 	ctl = SBMAC_READCSR(s->sbm_macenable);
1378 	ctl &= ~(M_MAC_RXDMA_EN0 | M_MAC_TXDMA_EN0);
1379 	SBMAC_WRITECSR(s->sbm_macenable, ctl);
1380 
1381 	/* We're stopped now. */
1382 
1383 	s->sbm_state = sbmac_state_off;
1384 	s->sc_ethercom.ec_if.if_flags &= ~IFF_RUNNING;
1385 
1386 	/* Empty the receive and transmit rings */
1387 
1388 	sbdma_emptyring(&(s->sbm_rxdma));
1389 	sbdma_emptyring(&(s->sbm_txdma));
1390 }
1391 
1392 /*
1393  *  SBMAC_SET_CHANNEL_STATE(state)
1394  *
1395  *  Set the channel's state ON or OFF
1396  *
1397  *  Input parameters:
1398  *	state - new state
1399  *
1400  *  Return value:
1401  *	old state
1402  */
1403 
1404 static sbmac_state_t
1405 sbmac_set_channel_state(struct sbmac_softc *sc, sbmac_state_t state)
1406 {
1407 	sbmac_state_t oldstate = sc->sbm_state;
1408 
1409 	/*
1410 	 * If same as previous state, return
1411 	 */
1412 
1413 	if (state == oldstate)
1414 		return oldstate;
1415 
1416 	/*
1417 	 * If new state is ON, turn channel on
1418 	 */
1419 
1420 	if (state == sbmac_state_on)
1421 		sbmac_channel_start(sc);
1422 	else
1423 		sbmac_channel_stop(sc);
1424 
1425 	/*
1426 	 * Return previous state
1427 	 */
1428 
1429 	return oldstate;
1430 }
1431 
1432 /*
1433  *  SBMAC_PROMISCUOUS_MODE(sc, onoff)
1434  *
1435  *  Turn on or off promiscuous mode
1436  *
1437  *  Input parameters:
1438  *	sc - softc
1439  *	onoff - 1 to turn on, 0 to turn off
1440  *
1441  *  Return value:
1442  *	nothing
1443  */
1444 
1445 static void
1446 sbmac_promiscuous_mode(struct sbmac_softc *sc, int onoff)
1447 {
1448 	uint64_t reg;
1449 
1450 	if (sc->sbm_state != sbmac_state_on)
1451 		return;
1452 
1453 	if (onoff) {
1454 		reg = SBMAC_READCSR(sc->sbm_rxfilter);
1455 		reg |= M_MAC_ALLPKT_EN;
1456 		SBMAC_WRITECSR(sc->sbm_rxfilter, reg);
1457 	} else {
1458 		reg = SBMAC_READCSR(sc->sbm_rxfilter);
1459 		reg &= ~M_MAC_ALLPKT_EN;
1460 		SBMAC_WRITECSR(sc->sbm_rxfilter, reg);
1461 	}
1462 }
1463 
1464 /*
1465  *  SBMAC_INIT_AND_START(sc)
1466  *
1467  *  Stop the channel and restart it.  This is generally used
1468  *  when we have to do something to the channel that requires
1469  *  a swift kick.
1470  *
1471  *  Input parameters:
1472  *	sc - softc
1473  */
1474 
1475 static void
1476 sbmac_init_and_start(struct sbmac_softc *sc)
1477 {
1478 	int s;
1479 
1480 	s = splnet();
1481 
1482 	mii_pollstat(&sc->sc_mii);		/* poll phy for current speed */
1483 	sbmac_mii_statchg((struct device *) sc); /* set state to new speed */
1484 	sbmac_set_channel_state(sc, sbmac_state_on);
1485 
1486 	splx(s);
1487 }
1488 
1489 /*
1490  *  SBMAC_ADDR2REG(ptr)
1491  *
1492  *  Convert six bytes into the 64-bit register value that
1493  *  we typically write into the SBMAC's address/mcast registers
1494  *
1495  *  Input parameters:
1496  *	ptr - pointer to 6 bytes
1497  *
1498  *  Return value:
1499  *	register value
1500  */
1501 
1502 static uint64_t
1503 sbmac_addr2reg(u_char *ptr)
1504 {
1505 	uint64_t reg = 0;
1506 
1507 	ptr += 6;
1508 
1509 	reg |= (uint64_t) *(--ptr);
1510 	reg <<= 8;
1511 	reg |= (uint64_t) *(--ptr);
1512 	reg <<= 8;
1513 	reg |= (uint64_t) *(--ptr);
1514 	reg <<= 8;
1515 	reg |= (uint64_t) *(--ptr);
1516 	reg <<= 8;
1517 	reg |= (uint64_t) *(--ptr);
1518 	reg <<= 8;
1519 	reg |= (uint64_t) *(--ptr);
1520 
1521 	return reg;
1522 }
1523 
1524 /*
1525  *  SBMAC_SET_SPEED(s, speed)
1526  *
1527  *  Configure LAN speed for the specified MAC.
1528  *  Warning: must be called when MAC is off!
1529  *
1530  *  Input parameters:
1531  *	s - sbmac structure
1532  *	speed - speed to set MAC to (see sbmac_speed_t enum)
1533  *
1534  *  Return value:
1535  *	1 if successful
1536  *	0 indicates invalid parameters
1537  */
1538 
1539 static int
1540 sbmac_set_speed(struct sbmac_softc *s, sbmac_speed_t speed)
1541 {
1542 	uint64_t cfg;
1543 	uint64_t framecfg;
1544 
1545 	/*
1546 	 * Save new current values
1547 	 */
1548 
1549 	s->sbm_speed = speed;
1550 
1551 	if (s->sbm_state != sbmac_state_off)
1552 		panic("sbmac_set_speed while MAC not off");
1553 
1554 	/*
1555 	 * Read current register values
1556 	 */
1557 
1558 	cfg = SBMAC_READCSR(s->sbm_maccfg);
1559 	framecfg = SBMAC_READCSR(s->sbm_framecfg);
1560 
1561 	/*
1562 	 * Mask out the stuff we want to change
1563 	 */
1564 
1565 	cfg &= ~(M_MAC_BURST_EN | M_MAC_SPEED_SEL);
1566 	framecfg &= ~(M_MAC_IFG_RX | M_MAC_IFG_TX | M_MAC_IFG_THRSH |
1567 	    M_MAC_SLOT_SIZE);
1568 
1569 	/*
1570 	 * Now add in the new bits
1571 	 */
1572 
1573 	switch (speed) {
1574 	case sbmac_speed_10:
1575 		framecfg |= V_MAC_IFG_RX_10 |
1576 		    V_MAC_IFG_TX_10 |
1577 		    K_MAC_IFG_THRSH_10 |
1578 		    V_MAC_SLOT_SIZE_10;
1579 		cfg |= V_MAC_SPEED_SEL_10MBPS;
1580 		break;
1581 
1582 	case sbmac_speed_100:
1583 		framecfg |= V_MAC_IFG_RX_100 |
1584 		    V_MAC_IFG_TX_100 |
1585 		    V_MAC_IFG_THRSH_100 |
1586 		    V_MAC_SLOT_SIZE_100;
1587 		cfg |= V_MAC_SPEED_SEL_100MBPS ;
1588 		break;
1589 
1590 	case sbmac_speed_1000:
1591 		framecfg |= V_MAC_IFG_RX_1000 |
1592 		    V_MAC_IFG_TX_1000 |
1593 		    V_MAC_IFG_THRSH_1000 |
1594 		    V_MAC_SLOT_SIZE_1000;
1595 		cfg |= V_MAC_SPEED_SEL_1000MBPS | M_MAC_BURST_EN;
1596 		break;
1597 
1598 	case sbmac_speed_auto:		/* XXX not implemented */
1599 		/* fall through */
1600 	default:
1601 		return 0;
1602 	}
1603 
1604 	/*
1605 	 * Send the bits back to the hardware
1606 	 */
1607 
1608 	SBMAC_WRITECSR(s->sbm_framecfg, framecfg);
1609 	SBMAC_WRITECSR(s->sbm_maccfg, cfg);
1610 
1611 	return 1;
1612 }
1613 
1614 /*
1615  *  SBMAC_SET_DUPLEX(s, duplex, fc)
1616  *
1617  *  Set Ethernet duplex and flow control options for this MAC
1618  *  Warning: must be called when MAC is off!
1619  *
1620  *  Input parameters:
1621  *	s - sbmac structure
1622  *	duplex - duplex setting (see sbmac_duplex_t)
1623  *	fc - flow control setting (see sbmac_fc_t)
1624  *
1625  *  Return value:
1626  *	1 if ok
1627  *	0 if an invalid parameter combination was specified
1628  */
1629 
1630 static int
1631 sbmac_set_duplex(struct sbmac_softc *s, sbmac_duplex_t duplex, sbmac_fc_t fc)
1632 {
1633 	uint64_t cfg;
1634 
1635 	/*
1636 	 * Save new current values
1637 	 */
1638 
1639 	s->sbm_duplex = duplex;
1640 	s->sbm_fc = fc;
1641 
1642 	if (s->sbm_state != sbmac_state_off)
1643 		panic("sbmac_set_duplex while MAC not off");
1644 
1645 	/*
1646 	 * Read current register values
1647 	 */
1648 
1649 	cfg = SBMAC_READCSR(s->sbm_maccfg);
1650 
1651 	/*
1652 	 * Mask off the stuff we're about to change
1653 	 */
1654 
1655 	cfg &= ~(M_MAC_FC_SEL | M_MAC_FC_CMD | M_MAC_HDX_EN);
1656 
1657 	switch (duplex) {
1658 	case sbmac_duplex_half:
1659 		switch (fc) {
1660 		case sbmac_fc_disabled:
1661 			cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_DISABLED;
1662 			break;
1663 
1664 		case sbmac_fc_collision:
1665 			cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENABLED;
1666 			break;
1667 
1668 		case sbmac_fc_carrier:
1669 			cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENAB_FALSECARR;
1670 			break;
1671 
1672 		case sbmac_fc_auto:		/* XXX not implemented */
1673 			/* fall through */
1674 		case sbmac_fc_frame:		/* not valid in half duplex */
1675 		default:			/* invalid selection */
1676 			panic("%s: invalid half duplex fc selection %d",
1677 			    s->sc_dev.dv_xname, fc);
1678 			return 0;
1679 		}
1680 		break;
1681 
1682 	case sbmac_duplex_full:
1683 		switch (fc) {
1684 		case sbmac_fc_disabled:
1685 			cfg |= V_MAC_FC_CMD_DISABLED;
1686 			break;
1687 
1688 		case sbmac_fc_frame:
1689 			cfg |= V_MAC_FC_CMD_ENABLED;
1690 			break;
1691 
1692 		case sbmac_fc_collision:	/* not valid in full duplex */
1693 		case sbmac_fc_carrier:		/* not valid in full duplex */
1694 		case sbmac_fc_auto:		/* XXX not implemented */
1695 			/* fall through */
1696 		default:
1697 			panic("%s: invalid full duplex fc selection %d",
1698 			    s->sc_dev.dv_xname, fc);
1699 			return 0;
1700 		}
1701 		break;
1702 
1703 	default:
1704 		/* fall through */
1705 	case sbmac_duplex_auto:
1706 		panic("%s: bad duplex %d", s->sc_dev.dv_xname, duplex);
1707 		/* XXX not implemented */
1708 		break;
1709 	}
1710 
1711 	/*
1712 	 * Send the bits back to the hardware
1713 	 */
1714 
1715 	SBMAC_WRITECSR(s->sbm_maccfg, cfg);
1716 
1717 	return 1;
1718 }
1719 
1720 /*
1721  *  SBMAC_INTR()
1722  *
1723  *  Interrupt handler for MAC interrupts
1724  *
1725  *  Input parameters:
1726  *	MAC structure
1727  *
1728  *  Return value:
1729  *	nothing
1730  */
1731 
1732 /* ARGSUSED */
1733 static void
1734 sbmac_intr(void *xsc, uint32_t status, uint32_t pc)
1735 {
1736 	struct sbmac_softc *sc = (struct sbmac_softc *) xsc;
1737 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1738 	uint64_t isr;
1739 
1740 	for (;;) {
1741 
1742 		/*
1743 		 * Read the ISR (this clears the bits in the real register)
1744 		 */
1745 
1746 		isr = SBMAC_READCSR(sc->sbm_isr);
1747 
1748 		if (isr == 0)
1749 			break;
1750 
1751 		/*
1752 		 * Transmits on channel 0
1753 		 */
1754 
1755 		if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0)) {
1756 			sbdma_tx_process(sc, &(sc->sbm_txdma));
1757 			SBMAC_EVCNT_INCR(sc->sbm_ev_txintr);
1758 		}
1759 
1760 		/*
1761 		 * Receives on channel 0
1762 		 */
1763 
1764 		if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) {
1765 			sbdma_rx_process(sc, &(sc->sbm_rxdma));
1766 			SBMAC_EVCNT_INCR(sc->sbm_ev_rxintr);
1767 		}
1768 	}
1769 
1770 	/* try to get more packets going */
1771 	sbmac_start(ifp);
1772 }
1773 
1774 
1775 /*
1776  *  SBMAC_START(ifp)
1777  *
1778  *  Start output on the specified interface.  Basically, we
1779  *  queue as many buffers as we can until the ring fills up, or
1780  *  we run off the end of the queue, whichever comes first.
1781  *
1782  *  Input parameters:
1783  *	ifp - interface
1784  *
1785  *  Return value:
1786  *	nothing
1787  */
1788 
1789 static void
1790 sbmac_start(struct ifnet *ifp)
1791 {
1792 	struct sbmac_softc	*sc;
1793 	struct mbuf		*m_head = NULL;
1794 	int			rv;
1795 
1796 	if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
1797 		return;
1798 
1799 	sc = ifp->if_softc;
1800 
1801 	for (;;) {
1802 
1803 		IF_DEQUEUE(&ifp->if_snd, m_head);
1804 		if (m_head == NULL)
1805 		    break;
1806 
1807 		/*
1808 		 * Put the buffer on the transmit ring.  If we
1809 		 * don't have room, set the OACTIVE flag and wait
1810 		 * for the NIC to drain the ring.
1811 		 */
1812 
1813 		rv = sbdma_add_txbuffer(&(sc->sbm_txdma), m_head);
1814 
1815 		if (rv == 0) {
1816 			/*
1817 			 * If there's a BPF listener, bounce a copy of this
1818 			 * frame to it.
1819 			 */
1820 #if (NBPFILTER > 0)
1821 			if (ifp->if_bpf)
1822 				bpf_mtap(ifp->if_bpf, m_head);
1823 #endif
1824 			if (!sc->sbm_pass3_dma) {
1825 				/*
1826 				 * Don't free mbuf if we're not copying to new
1827 				 * mbuf in sbdma_add_txbuffer.  It will be
1828 				 * freed in sbdma_tx_process.
1829 				 */
1830 				m_freem(m_head);
1831 			}
1832 		} else {
1833 		    IF_PREPEND(&ifp->if_snd, m_head);
1834 		    ifp->if_flags |= IFF_OACTIVE;
1835 		    break;
1836 		}
1837 	}
1838 }
1839 
1840 /*
1841  *  SBMAC_SETMULTI(sc)
1842  *
1843  *  Reprogram the multicast table into the hardware, given
1844  *  the list of multicasts associated with the interface
1845  *  structure.
1846  *
1847  *  Input parameters:
1848  *	sc - softc
1849  *
1850  *  Return value:
1851  *	nothing
1852  */
1853 
1854 static void
1855 sbmac_setmulti(struct sbmac_softc *sc)
1856 {
1857 	struct ifnet *ifp;
1858 	uint64_t reg;
1859 	sbmac_port_t port;
1860 	int idx;
1861 	struct ether_multi *enm;
1862 	struct ether_multistep step;
1863 
1864 	ifp = &sc->sc_ethercom.ec_if;
1865 
1866 	/*
1867 	 * Clear out entire multicast table.  We do this by nuking
1868 	 * the entire hash table and all the direct matches except
1869 	 * the first one, which is used for our station address
1870 	 */
1871 
1872 	for (idx = 1; idx < MAC_ADDR_COUNT; idx++) {
1873 		port = PKSEG1(sc->sbm_base +
1874 		    R_MAC_ADDR_BASE+(idx*sizeof(uint64_t)));
1875 		SBMAC_WRITECSR(port, 0);
1876 	}
1877 
1878 	for (idx = 0; idx < MAC_HASH_COUNT; idx++) {
1879 		port = PKSEG1(sc->sbm_base +
1880 		    R_MAC_HASH_BASE+(idx*sizeof(uint64_t)));
1881 		SBMAC_WRITECSR(port, 0);
1882 	}
1883 
1884 	/*
1885 	 * Clear the filter to say we don't want any multicasts.
1886 	 */
1887 
1888 	reg = SBMAC_READCSR(sc->sbm_rxfilter);
1889 	reg &= ~(M_MAC_MCAST_INV | M_MAC_MCAST_EN);
1890 	SBMAC_WRITECSR(sc->sbm_rxfilter, reg);
1891 
1892 	if (ifp->if_flags & IFF_ALLMULTI) {
1893 		/*
1894 		 * Enable ALL multicasts.  Do this by inverting the
1895 		 * multicast enable bit.
1896 		 */
1897 		reg = SBMAC_READCSR(sc->sbm_rxfilter);
1898 		reg |= (M_MAC_MCAST_INV | M_MAC_MCAST_EN);
1899 		SBMAC_WRITECSR(sc->sbm_rxfilter, reg);
1900 		return;
1901 	}
1902 
1903 	/*
1904 	 * Progam new multicast entries.  For now, only use the
1905 	 * perfect filter.  In the future we'll need to use the
1906 	 * hash filter if the perfect filter overflows
1907 	 */
1908 
1909 	/*
1910 	 * XXX only using perfect filter for now, need to use hash
1911 	 * XXX if the table overflows
1912 	 */
1913 
1914 	idx = 1;		/* skip station address */
1915 	ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
1916 	while ((enm != NULL) && (idx < MAC_ADDR_COUNT)) {
1917 		reg = sbmac_addr2reg(enm->enm_addrlo);
1918 		port = PKSEG1(sc->sbm_base +
1919 		    R_MAC_ADDR_BASE+(idx*sizeof(uint64_t)));
1920 		SBMAC_WRITECSR(port, reg);
1921 		idx++;
1922 		ETHER_NEXT_MULTI(step, enm);
1923 	}
1924 
1925 	/*
1926 	 * Enable the "accept multicast bits" if we programmed at least one
1927 	 * multicast.
1928 	 */
1929 
1930 	if (idx > 1) {
1931 	    reg = SBMAC_READCSR(sc->sbm_rxfilter);
1932 	    reg |= M_MAC_MCAST_EN;
1933 	    SBMAC_WRITECSR(sc->sbm_rxfilter, reg);
1934 	}
1935 }
1936 
1937 /*
1938  *  SBMAC_ETHER_IOCTL(ifp, cmd, data)
1939  *
1940  *  Generic IOCTL requests for this interface.  The basic
1941  *  stuff is handled here for bringing the interface up,
1942  *  handling multicasts, etc.
1943  *
1944  *  Input parameters:
1945  *	ifp - interface structure
1946  *	cmd - command code
1947  *	data - pointer to data
1948  *
1949  *  Return value:
1950  *	return value (0 is success)
1951  */
1952 
1953 static int
1954 sbmac_ether_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1955 {
1956 	struct ifaddr *ifa = (struct ifaddr *) data;
1957 	struct sbmac_softc *sc = ifp->if_softc;
1958 
1959 	switch (cmd) {
1960 	case SIOCINITIFADDR:
1961 		ifp->if_flags |= IFF_UP;
1962 
1963 		switch (ifa->ifa_addr->sa_family) {
1964 #ifdef INET
1965 		case AF_INET:
1966 			sbmac_init_and_start(sc);
1967 			arp_ifinit(ifp, ifa);
1968 			break;
1969 #endif
1970 #ifdef NS
1971 		case AF_NS:
1972 		{
1973 			struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
1974 
1975 			if (ns_nullhost(*ina))
1976 				ina->x_host =
1977 				    *(union ns_host *)LLADDR(ifp->if_sadl);
1978 			else
1979 				memcpy( LLADDR(ifp->if_sadl), ina->x_host.c_host,
1980 				    ifp->if_addrlen);
1981 			/* Set new address. */
1982 			sbmac_init_and_start(sc);
1983 			break;
1984 		}
1985 #endif
1986 		default:
1987 			sbmac_init_and_start(sc);
1988 			break;
1989 		}
1990 		break;
1991 
1992 	default:
1993 		return ENOTTY;
1994 	}
1995 
1996 	return (0);
1997 }
1998 
1999 /*
2000  *  SBMAC_IOCTL(ifp, cmd, data)
2001  *
2002  *  Main IOCTL handler - dispatches to other IOCTLs for various
2003  *  types of requests.
2004  *
2005  *  Input parameters:
2006  *	ifp - interface pointer
2007  *	cmd - command code
2008  *	data - pointer to argument data
2009  *
2010  *  Return value:
2011  *	0 if ok
2012  *	else error code
2013  */
2014 
2015 static int
2016 sbmac_ioctl(struct ifnet *ifp, u_long cmd, void *data)
2017 {
2018 	struct sbmac_softc *sc = ifp->if_softc;
2019 	struct ifreq *ifr = (struct ifreq *) data;
2020 	int s, error = 0;
2021 
2022 	s = splnet();
2023 
2024 	switch (cmd) {
2025 	case SIOCINITIFADDR:
2026 		error = sbmac_ether_ioctl(ifp, cmd, data);
2027 		break;
2028 	case SIOCSIFMTU:
2029 		if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU)
2030 			error = EINVAL;
2031 		else if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET)
2032 			/* XXX Program new MTU here */
2033 			error = 0;
2034 		break;
2035 	case SIOCSIFFLAGS:
2036 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
2037 			break;
2038 		if (ifp->if_flags & IFF_UP) {
2039 			/*
2040 			 * If only the state of the PROMISC flag changed,
2041 			 * just tweak the hardware registers.
2042 			 */
2043 			if ((ifp->if_flags & IFF_RUNNING) &&
2044 			    (ifp->if_flags & IFF_PROMISC)) {
2045 				/* turn on promiscuous mode */
2046 				sbmac_promiscuous_mode(sc, 1);
2047 			} else if (ifp->if_flags & IFF_RUNNING &&
2048 			    !(ifp->if_flags & IFF_PROMISC)) {
2049 			    /* turn off promiscuous mode */
2050 			    sbmac_promiscuous_mode(sc, 0);
2051 			} else
2052 			    sbmac_set_channel_state(sc, sbmac_state_on);
2053 		} else {
2054 			if (ifp->if_flags & IFF_RUNNING)
2055 				sbmac_set_channel_state(sc, sbmac_state_off);
2056 		}
2057 
2058 		sc->sbm_if_flags = ifp->if_flags;
2059 		error = 0;
2060 		break;
2061 
2062 	case SIOCADDMULTI:
2063 	case SIOCDELMULTI:
2064 	case SIOCSIFMEDIA:
2065 	case SIOCGIFMEDIA:
2066 		if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
2067 			error = 0;
2068 			if (ifp->if_flags & IFF_RUNNING)
2069 				sbmac_setmulti(sc);
2070 		}
2071 		break;
2072 	default:
2073 		error = ether_ioctl(ifp, cmd, data);
2074 		break;
2075 	}
2076 
2077 	(void)splx(s);
2078 
2079 	return(error);
2080 }
2081 
2082 /*
2083  *  SBMAC_IFMEDIA_UPD(ifp)
2084  *
2085  *  Configure an appropriate media type for this interface,
2086  *  given the data in the interface structure
2087  *
2088  *  Input parameters:
2089  *	ifp - interface
2090  *
2091  *  Return value:
2092  *	0 if ok
2093  *	else error code
2094  */
2095 
2096 /*
2097  *  SBMAC_IFMEDIA_STS(ifp, ifmr)
2098  *
2099  *  Report current media status (used by ifconfig, for example)
2100  *
2101  *  Input parameters:
2102  *	ifp - interface structure
2103  *	ifmr - media request structure
2104  *
2105  *  Return value:
2106  *	nothing
2107  */
2108 
2109 /*
2110  *  SBMAC_WATCHDOG(ifp)
2111  *
2112  *  Called periodically to make sure we're still happy.
2113  *
2114  *  Input parameters:
2115  *	ifp - interface structure
2116  *
2117  *  Return value:
2118  *	nothing
2119  */
2120 
2121 static void
2122 sbmac_watchdog(struct ifnet *ifp)
2123 {
2124 
2125 	/* XXX do something */
2126 }
2127 
2128 /*
2129  * One second timer, used to tick MII.
2130  */
2131 static void
2132 sbmac_tick(void *arg)
2133 {
2134 	struct sbmac_softc *sc = arg;
2135 	int s;
2136 
2137 	s = splnet();
2138 	mii_tick(&sc->sc_mii);
2139 	splx(s);
2140 
2141 	callout_reset(&sc->sc_tick_ch, hz, sbmac_tick, sc);
2142 }
2143 
2144 
2145 /*
2146  *  SBMAC_MATCH(parent, match, aux)
2147  *
2148  *  Part of the config process - see if this device matches the
2149  *  info about what we expect to find on the bus.
2150  *
2151  *  Input parameters:
2152  *	parent - parent bus structure
2153  *	match -
2154  *	aux - bus-specific args
2155  *
2156  *  Return value:
2157  *	1 if we match
2158  *	0 if we don't match
2159  */
2160 
2161 static int
2162 sbmac_match(struct device *parent, struct cfdata *match, void *aux)
2163 {
2164 	struct sbobio_attach_args *sap = aux;
2165 
2166 	/*
2167 	 * Make sure it's a MAC
2168 	 */
2169 
2170 	if (sap->sa_locs.sa_type != SBOBIO_DEVTYPE_MAC)
2171 		return 0;
2172 
2173 	/*
2174 	 * Yup, it is.
2175 	 */
2176 
2177 	return 1;
2178 }
2179 
2180 /*
2181  *  SBMAC_PARSE_XDIGIT(str)
2182  *
2183  *  Parse a hex digit, returning its value
2184  *
2185  *  Input parameters:
2186  *	str - character
2187  *
2188  *  Return value:
2189  *	hex value, or -1 if invalid
2190  */
2191 
2192 static int
2193 sbmac_parse_xdigit(char str)
2194 {
2195 	int digit;
2196 
2197 	if ((str >= '0') && (str <= '9'))
2198 		digit = str - '0';
2199 	else if ((str >= 'a') && (str <= 'f'))
2200 		digit = str - 'a' + 10;
2201 	else if ((str >= 'A') && (str <= 'F'))
2202 		digit = str - 'A' + 10;
2203 	else
2204 		digit = -1;
2205 
2206 	return digit;
2207 }
2208 
2209 /*
2210  *  SBMAC_PARSE_HWADDR(str, hwaddr)
2211  *
2212  *  Convert a string in the form xx:xx:xx:xx:xx:xx into a 6-byte
2213  *  Ethernet address.
2214  *
2215  *  Input parameters:
2216  *	str - string
2217  *	hwaddr - pointer to hardware address
2218  *
2219  *  Return value:
2220  *	0 if ok, else -1
2221  */
2222 
2223 static int
2224 sbmac_parse_hwaddr(const char *str, u_char *hwaddr)
2225 {
2226 	int digit1, digit2;
2227 	int idx = 6;
2228 
2229 	while (*str && (idx > 0)) {
2230 		digit1 = sbmac_parse_xdigit(*str);
2231 		if (digit1 < 0)
2232 			return -1;
2233 		str++;
2234 		if (!*str)
2235 			return -1;
2236 
2237 		if ((*str == ':') || (*str == '-')) {
2238 			digit2 = digit1;
2239 			digit1 = 0;
2240 		} else {
2241 			digit2 = sbmac_parse_xdigit(*str);
2242 			if (digit2 < 0)
2243 				return -1;
2244 			str++;
2245 		}
2246 
2247 		*hwaddr++ = (digit1 << 4) | digit2;
2248 		idx--;
2249 
2250 		if (*str == '-')
2251 			str++;
2252 		if (*str == ':')
2253 			str++;
2254 	}
2255 	return 0;
2256 }
2257 
2258 /*
2259  *  SBMAC_ATTACH(parent, self, aux)
2260  *
2261  *  Attach routine - init hardware and hook ourselves into NetBSD.
2262  *
2263  *  Input parameters:
2264  *	parent - parent bus device
2265  *	self - our softc
2266  *	aux - attach data
2267  *
2268  *  Return value:
2269  *	nothing
2270  */
2271 
2272 static void
2273 sbmac_attach(struct device *parent, struct device *self, void *aux)
2274 {
2275 	struct ifnet *ifp;
2276 	struct sbmac_softc *sc;
2277 	struct sbobio_attach_args *sap = aux;
2278 	u_char *eaddr;
2279 	static int unit = 0;	/* XXX */
2280 	uint64_t ea_reg;
2281 	int idx;
2282 
2283 	sc = (struct sbmac_softc *)self;
2284 
2285 	/* Determine controller base address */
2286 
2287 	sc->sbm_base = (sbmac_port_t) sap->sa_base + sap->sa_locs.sa_offset;
2288 
2289 	eaddr = sc->sbm_hwaddr;
2290 
2291 	/*
2292 	 * Initialize context (get pointers to registers and stuff), then
2293 	 * allocate the memory for the descriptor tables.
2294 	 */
2295 
2296 	sbmac_initctx(sc);
2297 
2298 	callout_init(&(sc->sc_tick_ch), 0);
2299 
2300 	/*
2301 	 * Read the ethernet address.  The firwmare left this programmed
2302 	 * for us in the ethernet address register for each mac.
2303 	 */
2304 
2305 	ea_reg = SBMAC_READCSR(PKSEG1(sc->sbm_base + R_MAC_ETHERNET_ADDR));
2306 	for (idx = 0; idx < 6; idx++) {
2307 		eaddr[idx] = (uint8_t) (ea_reg & 0xFF);
2308 		ea_reg >>= 8;
2309 	}
2310 
2311 #define	SBMAC_DEFAULT_HWADDR "40:00:00:00:01:00"
2312 	if (eaddr[0] == 0 && eaddr[1] == 0 && eaddr[2] == 0 &&
2313 		eaddr[3] == 0 && eaddr[4] == 0 && eaddr[5] == 0) {
2314 		sbmac_parse_hwaddr(SBMAC_DEFAULT_HWADDR, eaddr);
2315 		eaddr[5] = unit;
2316 	}
2317 
2318 #ifdef SBMAC_ETH0_HWADDR
2319 	if (unit == 0)
2320 		sbmac_parse_hwaddr(SBMAC_ETH0_HWADDR, eaddr);
2321 #endif
2322 #ifdef SBMAC_ETH1_HWADDR
2323 	if (unit == 1)
2324 		sbmac_parse_hwaddr(SBMAC_ETH1_HWADDR, eaddr);
2325 #endif
2326 #ifdef SBMAC_ETH2_HWADDR
2327 	if (unit == 2)
2328 		sbmac_parse_hwaddr(SBMAC_ETH2_HWADDR, eaddr);
2329 #endif
2330 	unit++;
2331 
2332 	/*
2333 	 * Display Ethernet address (this is called during the config process
2334 	 * so we need to finish off the config message that was being displayed)
2335 	 */
2336 	printf(": Ethernet%s\n",
2337 	    sc->sbm_pass3_dma ? ", using unaligned tx DMA" : "");
2338 	printf("%s: Ethernet address: %s\n", self->dv_xname,
2339 	    ether_sprintf(eaddr));
2340 
2341 
2342 	/*
2343 	 * Set up ifnet structure
2344 	 */
2345 
2346 	ifp = &sc->sc_ethercom.ec_if;
2347 	ifp->if_softc = sc;
2348 	memcpy( ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
2349 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
2350 	    IFF_NOTRAILERS;
2351 	ifp->if_ioctl = sbmac_ioctl;
2352 	ifp->if_start = sbmac_start;
2353 	ifp->if_watchdog = sbmac_watchdog;
2354 	ifp->if_snd.ifq_maxlen = SBMAC_MAX_TXDESCR - 1;
2355 
2356 	/*
2357 	 * Set up ifmedia support.
2358 	 */
2359 
2360 	/*
2361 	 * Initialize MII/media info.
2362 	 */
2363 	sc->sc_mii.mii_ifp      = ifp;
2364 	sc->sc_mii.mii_readreg  = sbmac_mii_readreg;
2365 	sc->sc_mii.mii_writereg = sbmac_mii_writereg;
2366 	sc->sc_mii.mii_statchg  = sbmac_mii_statchg;
2367 	sc->sc_ethercom.ec_mii = &sc->sc_mii;
2368 	ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange,
2369 	    ether_mediastatus);
2370 	mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
2371 	    MII_OFFSET_ANY, 0);
2372 
2373 	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
2374 		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
2375 		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
2376 	} else {
2377 		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
2378 	}
2379 
2380 
2381 	/*
2382 	 * map/route interrupt
2383 	 */
2384 
2385 	sc->sbm_intrhand = cpu_intr_establish(sap->sa_locs.sa_intr[0], IPL_NET,
2386 	    sbmac_intr, sc);
2387 
2388 	/*
2389 	 * Call MI attach routines.
2390 	 */
2391 	if_attach(ifp);
2392 	ether_ifattach(ifp, eaddr);
2393 }
2394