1 /* $OpenBSD: be.c,v 1.34 2003/06/02 18:40:58 jason Exp $ */
2
3 /*
4 * Copyright (c) 1998 Theo de Raadt and Jason L. Wright.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/kernel.h>
31 #include <sys/errno.h>
32 #include <sys/ioctl.h>
33 #include <sys/mbuf.h>
34 #include <sys/socket.h>
35 #include <sys/syslog.h>
36 #include <sys/device.h>
37 #include <sys/malloc.h>
38 #include <sys/timeout.h>
39
40 #include <net/if.h>
41 #include <net/if_dl.h>
42 #include <net/if_types.h>
43 #include <net/netisr.h>
44 #include <net/if_media.h>
45
46 #ifdef INET
47 #include <netinet/in.h>
48 #include <netinet/in_systm.h>
49 #include <netinet/in_var.h>
50 #include <netinet/ip.h>
51 #include <netinet/if_ether.h>
52 #endif
53
54 #include "bpfilter.h"
55 #if NBPFILTER > 0
56 #include <net/bpf.h>
57 #include <net/bpfdesc.h>
58 #endif
59
60 #include <machine/autoconf.h>
61 #include <machine/cpu.h>
62
63 #include <sparc/dev/sbusvar.h>
64 #include <sparc/dev/dmareg.h>
65 #include <sparc/dev/dmavar.h>
66
67 #include <sparc/dev/qecvar.h>
68 #include <sparc/dev/qecreg.h>
69 #include <sparc/dev/bereg.h>
70 #include <sparc/dev/bevar.h>
71
72 int bematch(struct device *, void *, void *);
73 void beattach(struct device *, struct device *, void *);
74
75 void beinit(struct besoftc *);
76 void bestart(struct ifnet *);
77 void bestop(struct besoftc *);
78 void bewatchdog(struct ifnet *);
79 int beioctl(struct ifnet *, u_long, caddr_t);
80 void bereset(struct besoftc *);
81
82 int beintr(void *);
83 int berint(struct besoftc *);
84 int betint(struct besoftc *);
85 int beqint(struct besoftc *, u_int32_t);
86 int beeint(struct besoftc *, u_int32_t);
87 void be_read(struct besoftc *, int, int);
88
89 void be_tcvr_idle(struct besoftc *);
90 void be_tcvr_init(struct besoftc *);
91 void be_tcvr_write(struct besoftc *, u_int8_t, u_int16_t);
92 void be_tcvr_write_bit(struct besoftc *, int);
93 int be_tcvr_read_bit1(struct besoftc *);
94 int be_tcvr_read_bit2(struct besoftc *);
95 int be_tcvr_read(struct besoftc *, u_int8_t);
96 void be_ifmedia_sts(struct ifnet *, struct ifmediareq *);
97 int be_ifmedia_upd(struct ifnet *);
98 void be_mcreset(struct besoftc *);
99 void betick(void *);
100 void be_tx_harvest(struct besoftc *);
101
102 struct cfdriver be_cd = {
103 NULL, "be", DV_IFNET
104 };
105
106 struct cfattach be_ca = {
107 sizeof(struct besoftc), bematch, beattach
108 };
109
110 int
bematch(parent,vcf,aux)111 bematch(parent, vcf, aux)
112 struct device *parent;
113 void *vcf, *aux;
114 {
115 struct cfdata *cf = vcf;
116 struct confargs *ca = aux;
117 register struct romaux *ra = &ca->ca_ra;
118
119 if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
120 return (0);
121 return (1);
122 }
123
124 void
beattach(parent,self,aux)125 beattach(parent, self, aux)
126 struct device *parent, *self;
127 void *aux;
128 {
129 struct qec_softc *qec = (struct qec_softc *)parent;
130 struct besoftc *sc = (struct besoftc *)self;
131 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
132 struct confargs *ca = aux;
133 struct bootpath *bp;
134 extern void myetheraddr(u_char *);
135 int pri, bmsr;
136
137 if (ca->ca_ra.ra_nintr != 1) {
138 printf(": expected 1 interrupt, got %d\n", ca->ca_ra.ra_nintr);
139 return;
140 }
141 pri = ca->ca_ra.ra_intr[0].int_pri;
142 sc->sc_rev = getpropint(ca->ca_ra.ra_node, "board-version", -1);
143
144 timeout_set(&sc->sc_tick, betick, sc);
145
146 sc->sc_cr = mapiodev(&ca->ca_ra.ra_reg[0], 0, sizeof(struct be_cregs));
147 sc->sc_br = mapiodev(&ca->ca_ra.ra_reg[1], 0, sizeof(struct be_bregs));
148 sc->sc_tr = mapiodev(&ca->ca_ra.ra_reg[2], 0, sizeof(struct be_tregs));
149 sc->sc_qec = qec;
150 sc->sc_qr = qec->sc_regs;
151 bestop(sc);
152
153 sc->sc_channel = getpropint(ca->ca_ra.ra_node, "channel#", -1);
154 if (sc->sc_channel == -1)
155 sc->sc_channel = 0;
156
157 sc->sc_burst = getpropint(ca->ca_ra.ra_node, "burst-sizes", -1);
158 if (sc->sc_burst == -1)
159 sc->sc_burst = qec->sc_burst;
160
161 /* Clamp at parent's burst sizes */
162 sc->sc_burst &= qec->sc_burst;
163
164 sc->sc_ih.ih_fun = beintr;
165 sc->sc_ih.ih_arg = sc;
166 intr_establish(pri, &sc->sc_ih, IPL_NET);
167
168 myetheraddr(sc->sc_arpcom.ac_enaddr);
169
170 be_tcvr_init(sc);
171
172 ifmedia_init(&sc->sc_ifmedia, 0, be_ifmedia_upd, be_ifmedia_sts);
173 bmsr = be_tcvr_read(sc, PHY_BMSR);
174 if (bmsr == BE_TCVR_READ_INVALID)
175 return;
176
177 if (bmsr & PHY_BMSR_10BASET_HALF) {
178 ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_10_T, 0, NULL);
179 ifmedia_add(&sc->sc_ifmedia,
180 IFM_ETHER | IFM_10_T | IFM_HDX, 0, NULL);
181 sc->sc_ifmedia.ifm_media = IFM_ETHER | IFM_10_T | IFM_HDX;
182 }
183
184 if (bmsr & PHY_BMSR_10BASET_FULL) {
185 ifmedia_add(&sc->sc_ifmedia,
186 IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
187 sc->sc_ifmedia.ifm_media = IFM_ETHER | IFM_10_T | IFM_FDX;
188 }
189
190 if (bmsr & PHY_BMSR_100BASETX_HALF) {
191 ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_100_TX, 0, NULL);
192 ifmedia_add(&sc->sc_ifmedia,
193 IFM_ETHER | IFM_100_TX | IFM_HDX, 0, NULL);
194 sc->sc_ifmedia.ifm_media = IFM_ETHER | IFM_100_TX | IFM_HDX;
195 }
196
197 if (bmsr & PHY_BMSR_100BASETX_FULL) {
198 ifmedia_add(&sc->sc_ifmedia,
199 IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);
200 sc->sc_ifmedia.ifm_media = IFM_ETHER | IFM_100_TX | IFM_FDX;
201 }
202
203 if (bmsr & PHY_BMSR_100BASET4) {
204 ifmedia_add(&sc->sc_ifmedia,
205 IFM_ETHER | IFM_100_T4, 0, NULL);
206 sc->sc_ifmedia.ifm_media = IFM_ETHER | IFM_100_T4;
207 }
208
209 if (bmsr & PHY_BMSR_ANC) {
210 ifmedia_add(&sc->sc_ifmedia,
211 IFM_ETHER | IFM_AUTO, 0, NULL);
212 sc->sc_ifmedia.ifm_media = IFM_ETHER | IFM_AUTO;
213 }
214
215 ifmedia_set(&sc->sc_ifmedia, sc->sc_ifmedia.ifm_media);
216
217 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
218 ifp->if_softc = sc;
219 ifp->if_start = bestart;
220 ifp->if_ioctl = beioctl;
221 ifp->if_watchdog = bewatchdog;
222 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS |
223 IFF_MULTICAST;
224
225 IFQ_SET_MAXLEN(&ifp->if_snd, BE_TX_RING_SIZE);
226 IFQ_SET_READY(&ifp->if_snd);
227
228 /* Attach the interface. */
229 if_attach(ifp);
230 ether_ifattach(ifp);
231
232 printf(" pri %d: rev %x address %s\n", pri, sc->sc_rev,
233 ether_sprintf(sc->sc_arpcom.ac_enaddr));
234
235 bp = ca->ca_ra.ra_bp;
236 if (bp != NULL && strcmp(bp->name, "be") == 0 &&
237 sc->sc_dev.dv_unit == bp->val[1])
238 bp->dev = &sc->sc_dev;
239 }
240
241 /*
242 * Start output on interface.
243 * We make two assumptions here:
244 * 1) that the current priority is set to splnet _before_ this code
245 * is called *and* is returned to the appropriate priority after
246 * return
247 * 2) that the IFF_OACTIVE flag is checked before this code is called
248 * (i.e. that the output part of the interface is idle)
249 */
250 void
bestart(ifp)251 bestart(ifp)
252 struct ifnet *ifp;
253 {
254 struct besoftc *sc = (struct besoftc *)ifp->if_softc;
255 struct mbuf *m;
256 int bix, len, cnt;
257
258 if (sc->sc_no_td > 0) {
259 /* Try to free previous stuff */
260 be_tx_harvest(sc);
261 }
262
263 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
264 return;
265
266 bix = sc->sc_last_td;
267 cnt = sc->sc_no_td;
268
269 for (;;) {
270 IFQ_POLL(&ifp->if_snd, m);
271 if (m == NULL)
272 break;
273
274 IFQ_DEQUEUE(&ifp->if_snd, m);
275
276 #if NBPFILTER > 0
277 /*
278 * If BPF is listening on this interface, let it see the
279 * packet before we commit it to the wire.
280 */
281 if (ifp->if_bpf)
282 bpf_mtap(ifp->if_bpf, m);
283 #endif
284
285 /*
286 * Copy the mbuf chain into the transmit buffer.
287 */
288 len = qec_put(sc->sc_bufs->tx_buf[bix & BE_TX_RING_MASK], m);
289
290 /*
291 * Initialize transmit registers and start transmission
292 */
293 sc->sc_desc->be_txd[bix].tx_flags =
294 BE_TXD_OWN | BE_TXD_SOP | BE_TXD_EOP |
295 (len & BE_TXD_LENGTH);
296 sc->sc_cr->ctrl = BE_CR_CTRL_TWAKEUP;
297
298 if (++bix == BE_TX_RING_MAXSIZE)
299 bix = 0;
300
301 if (++cnt == BE_TX_RING_SIZE) {
302 ifp->if_flags |= IFF_OACTIVE;
303 break;
304 }
305 }
306
307 if (cnt > BE_TX_HIGH_WATER) {
308 /* turn on interrupt */
309 sc->sc_tx_intr = 1;
310 sc->sc_cr->timask = 0;
311 }
312
313 if (cnt != sc->sc_no_td) {
314 ifp->if_timer = 5;
315 sc->sc_last_td = bix;
316 sc->sc_no_td = cnt;
317 }
318 }
319
320 void
bestop(sc)321 bestop(sc)
322 struct besoftc *sc;
323 {
324 int tries;
325
326 sc->sc_arpcom.ac_if.if_timer = 0;
327 if (timeout_pending(&sc->sc_tick))
328 timeout_del(&sc->sc_tick);
329
330 tries = 32;
331 sc->sc_br->tx_cfg = 0;
332 while (sc->sc_br->tx_cfg != 0 && --tries)
333 DELAY(20);
334
335 tries = 32;
336 sc->sc_br->rx_cfg = 0;
337 while (sc->sc_br->rx_cfg != 0 && --tries)
338 DELAY(20);
339 }
340
341 /*
342 * Reset interface.
343 */
344 void
bereset(sc)345 bereset(sc)
346 struct besoftc *sc;
347 {
348 int s;
349
350 s = splnet();
351 bestop(sc);
352 beinit(sc);
353 splx(s);
354 }
355
356 void
bewatchdog(ifp)357 bewatchdog(ifp)
358 struct ifnet *ifp;
359 {
360 struct besoftc *sc = ifp->if_softc;
361
362 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
363 ++sc->sc_arpcom.ac_if.if_oerrors;
364
365 bereset(sc);
366 }
367
368 int
beintr(v)369 beintr(v)
370 void *v;
371 {
372 struct besoftc *sc = (struct besoftc *)v;
373 u_int32_t whyq, whyb, whyc;
374 int r = 0;
375
376 whyq = sc->sc_qr->stat; /* qec status */
377 whyc = sc->sc_cr->stat; /* be channel status */
378 whyb = sc->sc_br->stat; /* be status */
379
380 if (whyq & QEC_STAT_BM)
381 r |= beeint(sc, whyb);
382
383 if (whyq & QEC_STAT_ER)
384 r |= beqint(sc, whyc);
385
386 if (sc->sc_tx_intr && (whyq & QEC_STAT_TX) && (whyc & BE_CR_STAT_TXIRQ))
387 r |= betint(sc);
388
389 if (whyq & QEC_STAT_RX && whyc & BE_CR_STAT_RXIRQ)
390 r |= berint(sc);
391
392 return (r);
393 }
394
395 /*
396 * QEC Interrupt.
397 */
398 int
beqint(sc,why)399 beqint(sc, why)
400 struct besoftc *sc;
401 u_int32_t why;
402 {
403 int r = 0, rst = 0;
404
405 if (why & BE_CR_STAT_TXIRQ)
406 r |= 1;
407 if (why & BE_CR_STAT_RXIRQ)
408 r |= 1;
409
410 if (why & BE_CR_STAT_ERRORS) {
411 r |= 1;
412 rst = 1;
413 }
414
415 if (rst || r == 0) {
416 printf("%s:%s qstat=%b\n", sc->sc_dev.dv_xname,
417 (r) ? "" : " unexpected",
418 why, BE_CR_STAT_BITS);
419 printf("%s: resetting\n", sc->sc_dev.dv_xname);
420 bereset(sc);
421 }
422
423 return r;
424 }
425
426 /*
427 * Error interrupt.
428 */
429 int
beeint(sc,why)430 beeint(sc, why)
431 struct besoftc *sc;
432 u_int32_t why;
433 {
434 int r = 0;
435
436 if (why & (BE_BR_STAT_RFIFOVF | BE_BR_STAT_TFIFO_UND |
437 BE_BR_STAT_MAXPKTERR)) {
438 r |= 1;
439 }
440
441 printf("%s:%s stat=%b\n", sc->sc_dev.dv_xname,
442 (r) ? "" : " unexpected", why, BE_BR_STAT_BITS);
443
444 printf("%s: resetting\n", sc->sc_dev.dv_xname);
445 bereset(sc);
446
447 return r;
448 }
449
450 void
be_tx_harvest(sc)451 be_tx_harvest(sc)
452 struct besoftc *sc;
453 {
454 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
455 int bix, cnt;
456 struct be_txd txd;
457
458 bix = sc->sc_first_td;
459 cnt = sc->sc_no_td;
460
461 for (;;) {
462 if (cnt <= 0)
463 break;
464
465 txd.tx_flags = sc->sc_desc->be_txd[bix].tx_flags;
466
467 if (txd.tx_flags & BE_TXD_OWN)
468 break;
469
470 ifp->if_opackets++;
471
472 if (++bix == BE_TX_RING_MAXSIZE)
473 bix = 0;
474
475 --cnt;
476 }
477
478 if (cnt <= 0)
479 ifp->if_timer = 0;
480
481 if (sc->sc_no_td != cnt) {
482 sc->sc_first_td = bix;
483 sc->sc_no_td = cnt;
484 ifp->if_flags &= ~IFF_OACTIVE;
485 }
486
487 if (sc->sc_no_td < BE_TX_LOW_WATER) {
488 /* turn off interrupt */
489 sc->sc_tx_intr = 0;
490 sc->sc_cr->timask = 0xffffffff;
491 }
492 }
493
494 /*
495 * Transmit interrupt.
496 */
497 int
betint(sc)498 betint(sc)
499 struct besoftc *sc;
500 {
501 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
502
503 bestart(ifp);
504 return (1);
505 }
506
507 /*
508 * Receive interrupt.
509 */
510 int
berint(sc)511 berint(sc)
512 struct besoftc *sc;
513 {
514 int bix, len;
515
516 bix = sc->sc_last_rd;
517
518 /*
519 * Process all buffers with valid data.
520 */
521 for (;;) {
522 if (sc->sc_desc->be_rxd[bix].rx_flags & BE_RXD_OWN)
523 break;
524
525 len = sc->sc_desc->be_rxd[bix].rx_flags & BE_RXD_LENGTH;
526 be_read(sc, bix, len);
527
528 sc->sc_desc->be_rxd[(bix + BE_RX_RING_SIZE) & BE_RX_RING_MAXMASK].rx_flags =
529 BE_RXD_OWN | (BE_PKT_BUF_SZ & BE_RXD_LENGTH);
530
531 if (++bix == BE_RX_RING_MAXSIZE)
532 bix = 0;
533 }
534
535 sc->sc_last_rd = bix;
536
537 return 1;
538 }
539
540 void
betick(vsc)541 betick(vsc)
542 void *vsc;
543 {
544 struct besoftc *sc = vsc;
545 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
546 struct be_bregs *br = sc->sc_br;
547 int s;
548
549 s = splnet();
550 /*
551 * Get collision counters
552 */
553 ifp->if_collisions += br->nc_ctr + br->fc_ctr + br->ex_ctr + br->lt_ctr;
554 br->nc_ctr = 0;
555 br->fc_ctr = 0;
556 br->ex_ctr = 0;
557 br->lt_ctr = 0;
558 bestart(ifp);
559 splx(s);
560 timeout_add(&sc->sc_tick, hz);
561 }
562
563 int
beioctl(ifp,cmd,data)564 beioctl(ifp, cmd, data)
565 struct ifnet *ifp;
566 u_long cmd;
567 caddr_t data;
568 {
569 struct besoftc *sc = ifp->if_softc;
570 struct ifaddr *ifa = (struct ifaddr *)data;
571 struct ifreq *ifr = (struct ifreq *)data;
572 int s, error = 0;
573
574 s = splnet();
575
576 switch (cmd) {
577 case SIOCSIFADDR:
578 ifp->if_flags |= IFF_UP;
579 switch (ifa->ifa_addr->sa_family) {
580 #ifdef INET
581 case AF_INET:
582 beinit(sc);
583 arp_ifinit(&sc->sc_arpcom, ifa);
584 break;
585 #endif /* INET */
586 #ifdef NS
587 /* XXX - This code is probably wrong. */
588 case AF_NS:
589 {
590 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
591
592 if (ns_nullhost(*ina))
593 ina->x_host = *(union ns_host *)
594 (sc->sc_arpcom.ac_enaddr);
595 else
596 bcopy(ina->x_host.c_host,
597 sc->sc_arpcom.ac_enaddr,
598 sizeof(sc->sc_arpcom.ac_enaddr));
599 /* Set new address. */
600 beinit(sc);
601 break;
602 }
603 #endif /* NS */
604 default:
605 beinit(sc);
606 break;
607 }
608 break;
609
610 case SIOCSIFFLAGS:
611 if ((ifp->if_flags & IFF_UP) == 0 &&
612 (ifp->if_flags & IFF_RUNNING) != 0) {
613 /*
614 * If interface is marked down and it is running, then
615 * stop it.
616 */
617 bestop(sc);
618 ifp->if_flags &= ~IFF_RUNNING;
619 } else if ((ifp->if_flags & IFF_UP) != 0 &&
620 (ifp->if_flags & IFF_RUNNING) == 0) {
621 /*
622 * If interface is marked up and it is stopped, then
623 * start it.
624 */
625 beinit(sc);
626 } else {
627 /*
628 * Reset the interface to pick up changes in any other
629 * flags that affect hardware registers.
630 */
631 bestop(sc);
632 beinit(sc);
633 }
634 break;
635
636 case SIOCADDMULTI:
637 case SIOCDELMULTI:
638 error = (cmd == SIOCADDMULTI) ?
639 ether_addmulti(ifr, &sc->sc_arpcom):
640 ether_delmulti(ifr, &sc->sc_arpcom);
641
642 if (error == ENETRESET) {
643 /*
644 * Multicast list has changed; set the hardware filter
645 * accordingly.
646 */
647 be_mcreset(sc);
648 error = 0;
649 }
650 break;
651 case SIOCGIFMEDIA:
652 case SIOCSIFMEDIA:
653 error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd);
654 break;
655 default:
656 if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
657 splx(s);
658 return error;
659 }
660 error = EINVAL;
661 break;
662 }
663 splx(s);
664 return error;
665 }
666
667 void
beinit(sc)668 beinit(sc)
669 struct besoftc *sc;
670 {
671 struct be_bregs *br = sc->sc_br;
672 struct be_cregs *cr = sc->sc_cr;
673 struct qec_softc *qec = sc->sc_qec;
674 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
675 int s = splimp();
676 int i;
677
678 /*
679 * Allocate descriptor ring and buffers, if not already done
680 */
681 if (sc->sc_desc == NULL)
682 sc->sc_desc_dva = (struct be_desc *) dvma_malloc(
683 sizeof(struct be_desc), &sc->sc_desc, M_NOWAIT);
684 if (sc->sc_bufs == NULL)
685 sc->sc_bufs_dva = (struct be_bufs *) dvma_malloc(
686 sizeof(struct be_bufs), &sc->sc_bufs, M_NOWAIT);
687
688 for (i = 0; i < BE_TX_RING_MAXSIZE; i++) {
689 sc->sc_desc->be_txd[i].tx_addr =
690 (u_int32_t)sc->sc_bufs_dva->tx_buf[i & BE_TX_RING_MASK];
691 sc->sc_desc->be_txd[i].tx_flags = 0;
692 }
693 for (i = 0; i < BE_RX_RING_MAXSIZE; i++) {
694 sc->sc_desc->be_rxd[i].rx_addr =
695 (u_int32_t)sc->sc_bufs_dva->rx_buf[i & BE_RX_RING_MASK];
696 if (i < BE_RX_RING_SIZE)
697 sc->sc_desc->be_rxd[i].rx_flags =
698 BE_RXD_OWN | (BE_PKT_BUF_SZ & BE_RXD_LENGTH);
699 else
700 sc->sc_desc->be_rxd[i].rx_flags = 0;
701 }
702
703 sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0;
704 sc->sc_last_rd = 0;
705
706 be_tcvr_init(sc);
707
708 be_ifmedia_upd(ifp);
709
710 bestop(sc);
711
712 br->mac_addr2 = (sc->sc_arpcom.ac_enaddr[4] << 8) |
713 sc->sc_arpcom.ac_enaddr[5];
714 br->mac_addr1 = (sc->sc_arpcom.ac_enaddr[2] << 8) |
715 sc->sc_arpcom.ac_enaddr[3];
716 br->mac_addr0 = (sc->sc_arpcom.ac_enaddr[0] << 8) |
717 sc->sc_arpcom.ac_enaddr[1];
718
719 br->rx_cfg = BE_BR_RXCFG_HENABLE | BE_BR_RXCFG_FIFO;
720
721 be_mcreset(sc);
722
723 DELAY(20);
724
725 br->tx_cfg = BE_BR_TXCFG_FIFO;
726 br->rand_seed = 0xbd;
727
728 br->xif_cfg = BE_BR_XCFG_ODENABLE | BE_BR_XCFG_RESV;
729
730 cr->rxds = (u_int32_t)sc->sc_desc_dva->be_rxd;
731 cr->txds = (u_int32_t)sc->sc_desc_dva->be_txd;
732
733 cr->rxwbufptr = cr->rxrbufptr = sc->sc_channel * qec->sc_msize;
734 cr->txwbufptr = cr->txrbufptr = cr->rxrbufptr + qec->sc_rsize;
735
736 /*
737 * Turn off counter expiration interrupts as well as
738 * 'gotframe' and 'sentframe'
739 */
740 br->imask = BE_BR_IMASK_GOTFRAME |
741 BE_BR_IMASK_RCNTEXP |
742 BE_BR_IMASK_ACNTEXP |
743 BE_BR_IMASK_CCNTEXP |
744 BE_BR_IMASK_LCNTEXP |
745 BE_BR_IMASK_CVCNTEXP |
746 BE_BR_IMASK_SENTFRAME |
747 BE_BR_IMASK_NCNTEXP |
748 BE_BR_IMASK_ECNTEXP |
749 BE_BR_IMASK_LCCNTEXP |
750 BE_BR_IMASK_FCNTEXP |
751 BE_BR_IMASK_DTIMEXP;
752
753 cr->rimask = 0;
754
755 /* disable tx interrupts initially */
756 cr->timask = 0xffffffff;
757 sc->sc_tx_intr = 0;
758
759 cr->qmask = 0;
760 cr->bmask = 0;
761
762 br->jsize = 4;
763
764 cr->ccnt = 0;
765
766 br->tx_cfg |= BE_BR_TXCFG_ENABLE;
767 br->rx_cfg |= BE_BR_RXCFG_ENABLE;
768
769 ifp->if_flags |= IFF_RUNNING;
770 ifp->if_flags &= ~IFF_OACTIVE;
771 splx(s);
772
773 timeout_add(&sc->sc_tick, hz);
774 bestart(ifp);
775 }
776
777 /*
778 * Set the tcvr to an idle state
779 */
780 void
be_tcvr_idle(sc)781 be_tcvr_idle(sc)
782 struct besoftc *sc;
783 {
784 struct be_tregs *tr = sc->sc_tr;
785 volatile u_int32_t x;
786 int i = 20;
787
788 while (i--) {
789 tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO |
790 MGMT_PAL_OENAB;
791 x = tr->mgmt_pal;
792 tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO |
793 MGMT_PAL_OENAB | MGMT_PAL_DCLOCK;
794 x = tr->mgmt_pal;
795 }
796 }
797
798 /*
799 * Initialize the transceiver and figure out whether we're using the
800 * external or internal one.
801 */
802 void
be_tcvr_init(sc)803 be_tcvr_init(sc)
804 struct besoftc *sc;
805 {
806 volatile u_int32_t x;
807 struct be_tregs *tr = sc->sc_tr;
808
809 be_tcvr_idle(sc);
810
811 if (sc->sc_rev != 1) {
812 printf("%s: rev %d PAL not supported.\n",
813 sc->sc_dev.dv_xname,
814 sc->sc_rev);
815 return;
816 }
817
818 tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK;
819 x = tr->mgmt_pal;
820
821 tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO;
822 x = tr->mgmt_pal;
823 DELAY(200);
824
825 if (tr->mgmt_pal & MGMT_PAL_EXT_MDIO) {
826 sc->sc_tcvr_type = BE_TCVR_EXTERNAL;
827 tr->tcvr_pal = ~(TCVR_PAL_EXTLBACK | TCVR_PAL_MSENSE |
828 TCVR_PAL_LTENABLE);
829 x = tr->tcvr_pal;
830 }
831 else if (tr->mgmt_pal & MGMT_PAL_INT_MDIO) {
832 sc->sc_tcvr_type = BE_TCVR_INTERNAL;
833 tr->tcvr_pal = ~(TCVR_PAL_EXTLBACK | TCVR_PAL_MSENSE |
834 TCVR_PAL_LTENABLE | TCVR_PAL_SERIAL);
835 x = tr->tcvr_pal;
836 }
837 else {
838 printf("%s: no internal or external transceiver found.\n",
839 sc->sc_dev.dv_xname);
840 }
841 }
842
843 int
be_tcvr_read(sc,reg)844 be_tcvr_read(sc, reg)
845 struct besoftc *sc;
846 u_int8_t reg;
847 {
848 int phy, i;
849 u_int32_t ret = 0;
850
851 if (sc->sc_tcvr_type == BE_TCVR_INTERNAL)
852 phy = BE_PHY_INTERNAL;
853 else if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL)
854 phy = BE_PHY_EXTERNAL;
855 else {
856 printf("%s: invalid tcvr type\n", sc->sc_dev.dv_xname);
857 return BE_TCVR_READ_INVALID;
858 }
859
860 be_tcvr_idle(sc);
861
862 be_tcvr_write_bit(sc, 0);
863 be_tcvr_write_bit(sc, 1);
864 be_tcvr_write_bit(sc, 1);
865 be_tcvr_write_bit(sc, 0);
866
867 for (i = 4; i >= 0; i--)
868 be_tcvr_write_bit(sc, (phy >> i) & 1);
869
870 for (i = 4; i >= 0; i--)
871 be_tcvr_write_bit(sc, (reg >> i) & 1);
872
873 if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL) {
874 (void) be_tcvr_read_bit2(sc);
875 (void) be_tcvr_read_bit2(sc);
876
877 for (i = 15; i >= 0; i--) {
878 int b;
879
880 b = be_tcvr_read_bit2(sc);
881 ret |= (b & 1) << i;
882 }
883
884 (void) be_tcvr_read_bit2(sc);
885 (void) be_tcvr_read_bit2(sc);
886 (void) be_tcvr_read_bit2(sc);
887 }
888 else {
889 (void) be_tcvr_read_bit1(sc);
890 (void) be_tcvr_read_bit1(sc);
891
892 for (i = 15; i >= 0; i--) {
893 int b;
894
895 b = be_tcvr_read_bit1(sc);
896 ret |= (b & 1) << i;
897 }
898
899 (void) be_tcvr_read_bit1(sc);
900 (void) be_tcvr_read_bit1(sc);
901 (void) be_tcvr_read_bit1(sc);
902 }
903 return ret;
904 }
905
906 int
be_tcvr_read_bit1(sc)907 be_tcvr_read_bit1(sc)
908 struct besoftc *sc;
909 {
910 volatile u_int32_t x;
911 struct be_tregs *tr = sc->sc_tr;
912 int ret = 0;
913
914 if (sc->sc_tcvr_type == BE_TCVR_INTERNAL) {
915 tr->mgmt_pal = MGMT_PAL_EXT_MDIO;
916 x = tr->mgmt_pal;
917 tr->mgmt_pal = MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK;
918 x = tr->mgmt_pal;
919 DELAY(20);
920 ret = (tr->mgmt_pal & MGMT_PAL_INT_MDIO) >> 3;
921 } else if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL) {
922 tr->mgmt_pal = MGMT_PAL_INT_MDIO;
923 x = tr->mgmt_pal;
924 tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_DCLOCK;
925 x = tr->mgmt_pal;
926 DELAY(20);
927 ret = (tr->mgmt_pal & MGMT_PAL_EXT_MDIO) >> 2;
928 } else {
929 printf("%s: invalid tcvr type\n", sc->sc_dev.dv_xname);
930 }
931 return (ret & 1);
932 }
933
934 int
be_tcvr_read_bit2(sc)935 be_tcvr_read_bit2(sc)
936 struct besoftc *sc;
937 {
938 volatile u_int32_t x;
939 struct be_tregs *tr = sc->sc_tr;
940 int ret = 0;
941
942 if (sc->sc_tcvr_type == BE_TCVR_INTERNAL) {
943 tr->mgmt_pal = MGMT_PAL_EXT_MDIO;
944 x = tr->mgmt_pal;
945 DELAY(20);
946 ret = (tr->mgmt_pal & MGMT_PAL_INT_MDIO) >> 3;
947 tr->mgmt_pal = MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK;
948 x = tr->mgmt_pal;
949 } else if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL) {
950 tr->mgmt_pal = MGMT_PAL_INT_MDIO;
951 x = tr->mgmt_pal;
952 DELAY(20);
953 ret = (tr->mgmt_pal & MGMT_PAL_EXT_MDIO) >> 2;
954 tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_DCLOCK;
955 x = tr->mgmt_pal;
956 } else {
957 printf("%s: invalid tcvr type\n", sc->sc_dev.dv_xname);
958 }
959 return ret;
960 }
961
962 void
be_tcvr_write(sc,reg,val)963 be_tcvr_write(sc, reg, val)
964 struct besoftc *sc;
965 u_int8_t reg;
966 u_int16_t val;
967 {
968 int phy, i;
969
970 if (sc->sc_tcvr_type == BE_TCVR_INTERNAL)
971 phy = BE_PHY_INTERNAL;
972 else if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL)
973 phy = BE_PHY_EXTERNAL;
974 else {
975 printf("%s: invalid tcvr type\n", sc->sc_dev.dv_xname);
976 return;
977 }
978
979 be_tcvr_idle(sc);
980
981 be_tcvr_write_bit(sc, 0);
982 be_tcvr_write_bit(sc, 1);
983 be_tcvr_write_bit(sc, 0);
984 be_tcvr_write_bit(sc, 1);
985
986 for (i = 4; i >= 0; i--)
987 be_tcvr_write_bit(sc, (phy >> i) & 1);
988
989 for (i = 4; i >= 0; i--)
990 be_tcvr_write_bit(sc, (reg >> i) & 1);
991
992 be_tcvr_write_bit(sc, 1);
993 be_tcvr_write_bit(sc, 0);
994
995 for (i = 15; i >= 0; i--)
996 be_tcvr_write_bit(sc, (val >> i) & 1);
997 }
998
999 void
be_tcvr_write_bit(sc,bit)1000 be_tcvr_write_bit(sc, bit)
1001 struct besoftc *sc;
1002 int bit;
1003 {
1004 volatile u_int32_t x;
1005
1006 if (sc->sc_tcvr_type == BE_TCVR_INTERNAL) {
1007 bit = ((bit & 1) << 3) | MGMT_PAL_OENAB | MGMT_PAL_EXT_MDIO;
1008 sc->sc_tr->mgmt_pal = bit;
1009 x = sc->sc_tr->mgmt_pal;
1010 sc->sc_tr->mgmt_pal = bit | MGMT_PAL_DCLOCK;
1011 x = sc->sc_tr->mgmt_pal;
1012 } else {
1013 bit = ((bit & 1) << 2) | MGMT_PAL_OENAB | MGMT_PAL_INT_MDIO;
1014 sc->sc_tr->mgmt_pal = bit;
1015 x = sc->sc_tr->mgmt_pal;
1016 sc->sc_tr->mgmt_pal = bit | MGMT_PAL_DCLOCK;
1017 x = sc->sc_tr->mgmt_pal;
1018 }
1019 }
1020
1021 /*
1022 * Pass a packet to the higher levels.
1023 */
1024 void
be_read(sc,idx,len)1025 be_read(sc, idx, len)
1026 struct besoftc *sc;
1027 int idx, len;
1028 {
1029 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1030 struct mbuf *m;
1031
1032 if (len <= sizeof(struct ether_header) ||
1033 len > ETHERMTU + sizeof(struct ether_header)) {
1034
1035 printf("%s: invalid packet size %d; dropping\n",
1036 ifp->if_xname, len);
1037
1038 ifp->if_ierrors++;
1039 return;
1040 }
1041
1042 /*
1043 * Pull packet off interface.
1044 */
1045 m = qec_get(ifp, sc->sc_bufs->rx_buf[idx & BE_RX_RING_MASK], len);
1046 if (m == NULL) {
1047 ifp->if_ierrors++;
1048 return;
1049 }
1050 ifp->if_ipackets++;
1051
1052
1053 #if NBPFILTER > 0
1054 /*
1055 * Check if there's a BPF listener on this interface.
1056 * If so, hand off the raw packet to BPF.
1057 */
1058 if (ifp->if_bpf)
1059 bpf_mtap(ifp->if_bpf, m);
1060 #endif
1061 /* Pass the packet up. */
1062 ether_input_mbuf(ifp, m);
1063 }
1064
1065 /*
1066 * Get current media settings.
1067 */
1068 void
be_ifmedia_sts(ifp,ifmr)1069 be_ifmedia_sts(ifp, ifmr)
1070 struct ifnet *ifp;
1071 struct ifmediareq *ifmr;
1072 {
1073 struct besoftc *sc = ifp->if_softc;
1074 int bmcr, bmsr;
1075
1076 bmcr = be_tcvr_read(sc, PHY_BMCR);
1077
1078 switch (bmcr & (PHY_BMCR_SPEED | PHY_BMCR_DUPLEX)) {
1079 case (PHY_BMCR_SPEED | PHY_BMCR_DUPLEX):
1080 ifmr->ifm_active = IFM_ETHER | IFM_100_TX | IFM_FDX;
1081 break;
1082 case PHY_BMCR_SPEED:
1083 ifmr->ifm_active = IFM_ETHER | IFM_100_TX | IFM_HDX;
1084 break;
1085 case PHY_BMCR_DUPLEX:
1086 ifmr->ifm_active = IFM_ETHER | IFM_10_T | IFM_FDX;
1087 break;
1088 case 0:
1089 ifmr->ifm_active = IFM_ETHER | IFM_10_T | IFM_HDX;
1090 break;
1091 }
1092
1093 bmsr = be_tcvr_read(sc, PHY_BMSR);
1094 if (bmsr & PHY_BMSR_LINKSTATUS)
1095 ifmr->ifm_status |= IFM_AVALID | IFM_ACTIVE;
1096 else {
1097 ifmr->ifm_status |= IFM_AVALID;
1098 ifmr->ifm_status &= ~IFM_ACTIVE;
1099 }
1100 }
1101
1102 /*
1103 * Set media options.
1104 */
1105 int
be_ifmedia_upd(ifp)1106 be_ifmedia_upd(ifp)
1107 struct ifnet *ifp;
1108 {
1109 struct besoftc *sc = ifp->if_softc;
1110 struct ifmedia *ifm = &sc->sc_ifmedia;
1111 int bmcr, tries;
1112
1113 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
1114 return (EINVAL);
1115
1116 be_tcvr_write(sc, PHY_BMCR,
1117 PHY_BMCR_LOOPBACK | PHY_BMCR_PDOWN | PHY_BMCR_ISOLATE);
1118 be_tcvr_write(sc, PHY_BMCR, PHY_BMCR_RESET);
1119
1120 for (tries = 16; tries >= 0; tries--) {
1121 bmcr = be_tcvr_read(sc, PHY_BMCR);
1122 if ((bmcr & PHY_BMCR_RESET) == 0)
1123 break;
1124 DELAY(20);
1125 }
1126 if (tries == 0) {
1127 printf("%s: bmcr reset failed\n", sc->sc_dev.dv_xname);
1128 return (EIO);
1129 }
1130
1131 bmcr = be_tcvr_read(sc, PHY_BMCR);
1132
1133 if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_T4) {
1134 bmcr |= PHY_BMCR_SPEED;
1135 bmcr &= ~PHY_BMCR_DUPLEX;
1136 }
1137
1138 if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_TX) {
1139 bmcr |= PHY_BMCR_SPEED;
1140 }
1141
1142 if (IFM_SUBTYPE(ifm->ifm_media) == IFM_10_T) {
1143 bmcr &= ~PHY_BMCR_SPEED;
1144 }
1145
1146 if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) {
1147 bmcr |= PHY_BMCR_DUPLEX;
1148 sc->sc_br->tx_cfg |= BE_BR_TXCFG_FULLDPLX;
1149 }
1150 else {
1151 bmcr &= ~PHY_BMCR_DUPLEX;
1152 sc->sc_br->tx_cfg &= ~BE_BR_TXCFG_FULLDPLX;
1153 }
1154
1155 be_tcvr_write(sc, PHY_BMCR, bmcr & (~PHY_BMCR_ISOLATE));
1156
1157 for (tries = 32; tries >= 0; tries--) {
1158 bmcr = be_tcvr_read(sc, PHY_BMCR);
1159 if ((bmcr & PHY_BMCR_ISOLATE) == 0)
1160 break;
1161 DELAY(20);
1162 }
1163 if (tries == 0) {
1164 printf("%s: bmcr unisolate failed\n", sc->sc_dev.dv_xname);
1165 return (EIO);
1166 }
1167
1168 return (0);
1169 }
1170
1171 void
be_mcreset(sc)1172 be_mcreset(sc)
1173 struct besoftc *sc;
1174 {
1175 struct arpcom *ac = &sc->sc_arpcom;
1176 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1177 struct be_bregs *br = sc->sc_br;
1178 u_int32_t crc;
1179 u_int16_t hash[4];
1180 u_int8_t octet;
1181 int i, j;
1182 struct ether_multi *enm;
1183 struct ether_multistep step;
1184
1185 if (ifp->if_flags & IFF_PROMISC) {
1186 br->rx_cfg |= BE_BR_RXCFG_PMISC;
1187 return;
1188 }
1189 else
1190 br->rx_cfg &= ~BE_BR_RXCFG_PMISC;
1191
1192 if (ifp->if_flags & IFF_ALLMULTI) {
1193 br->htable3 = 0xffff;
1194 br->htable2 = 0xffff;
1195 br->htable1 = 0xffff;
1196 br->htable0 = 0xffff;
1197 return;
1198 }
1199
1200 hash[3] = hash[2] = hash[1] = hash[0] = 0;
1201
1202 ETHER_FIRST_MULTI(step, ac, enm);
1203 while (enm != NULL) {
1204 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
1205 /*
1206 * We must listen to a range of multicast
1207 * addresses. For now, just accept all
1208 * multicasts, rather than trying to set only
1209 * those filter bits needed to match the range.
1210 * (At this time, the only use of address
1211 * ranges is for IP multicast routing, for
1212 * which the range is big enough to require
1213 * all bits set.)
1214 */
1215 br->htable3 = 0xffff;
1216 br->htable2 = 0xffff;
1217 br->htable1 = 0xffff;
1218 br->htable0 = 0xffff;
1219 ifp->if_flags |= IFF_ALLMULTI;
1220 return;
1221 }
1222
1223 crc = 0xffffffff;
1224
1225 for (i = 0; i < ETHER_ADDR_LEN; i++) {
1226 octet = enm->enm_addrlo[i];
1227
1228 for (j = 0; j < 8; j++) {
1229 if ((crc & 1) ^ (octet & 1)) {
1230 crc >>= 1;
1231 crc ^= MC_POLY_LE;
1232 }
1233 else
1234 crc >>= 1;
1235 octet >>= 1;
1236 }
1237 }
1238
1239 crc >>= 26;
1240 hash[crc >> 4] |= 1 << (crc & 0xf);
1241 ETHER_NEXT_MULTI(step, enm);
1242 }
1243
1244 br->htable3 = hash[3];
1245 br->htable2 = hash[2];
1246 br->htable1 = hash[1];
1247 br->htable0 = hash[0];
1248 ifp->if_flags &= ~IFF_ALLMULTI;
1249 }
1250