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