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