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