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