1 /* $OpenBSD: be.c,v 1.15 2004/05/12 06:35:11 tedu Exp $ */
2 /* $NetBSD: be.c,v 1.26 2001/03/20 15:39:20 pk Exp $ */
3
4 /*-
5 * Copyright (c) 1999 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Paul Kranenburg.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*
41 * Copyright (c) 1998 Theo de Raadt and Jason L. Wright.
42 * All rights reserved.
43 *
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
46 * are met:
47 * 1. Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution.
52 *
53 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
54 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
55 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
56 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
57 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
58 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
59 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
60 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
61 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
62 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63 */
64
65 #include "bpfilter.h"
66
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/timeout.h>
70 #include <sys/kernel.h>
71 #include <sys/errno.h>
72 #include <sys/ioctl.h>
73 #include <sys/mbuf.h>
74 #include <sys/socket.h>
75 #include <sys/syslog.h>
76 #include <sys/device.h>
77 #include <sys/malloc.h>
78
79 #include <net/if.h>
80 #include <net/if_dl.h>
81 #include <net/if_types.h>
82 #include <net/netisr.h>
83 #include <net/if_media.h>
84
85 #ifdef INET
86 #include <netinet/in.h>
87 #include <netinet/in_systm.h>
88 #include <netinet/in_var.h>
89 #include <netinet/ip.h>
90 #include <netinet/if_ether.h>
91 #endif
92
93 #ifdef NS
94 #include <netns/ns.h>
95 #include <netns/ns_if.h>
96 #endif
97
98 #if NBPFILTER > 0
99 #include <net/bpf.h>
100 #endif
101
102 #include <machine/bus.h>
103 #include <machine/intr.h>
104 #include <machine/autoconf.h>
105
106 #include <dev/sbus/sbusvar.h>
107
108 #include <dev/mii/mii.h>
109 #include <dev/mii/miivar.h>
110
111 #include <dev/sbus/qecreg.h>
112 #include <dev/sbus/qecvar.h>
113 #include <dev/sbus/bereg.h>
114
115 struct be_softc {
116 struct device sc_dev;
117 struct sbusdev sc_sd; /* sbus device */
118 bus_space_tag_t sc_bustag; /* bus & dma tags */
119 bus_dma_tag_t sc_dmatag;
120 bus_dmamap_t sc_dmamap;
121 struct arpcom sc_arpcom;
122 /*struct ifmedia sc_ifmedia; -* interface media */
123 struct mii_data sc_mii; /* MII media control */
124 #define sc_media sc_mii.mii_media/* shorthand */
125 int sc_phys[2]; /* MII instance -> phy */
126
127 struct timeout sc_tick_ch;
128
129 /*
130 * Some `mii_softc' items we need to emulate MII operation
131 * for our internal transceiver.
132 */
133 int sc_mii_inst; /* instance of internal phy */
134 int sc_mii_active; /* currently active medium */
135 int sc_mii_ticks; /* tick counter */
136 int sc_mii_flags; /* phy status flags */
137 #define MIIF_HAVELINK 0x04000000
138 int sc_intphy_curspeed; /* Established link speed */
139
140 struct qec_softc *sc_qec; /* QEC parent */
141
142 bus_space_handle_t sc_qr; /* QEC registers */
143 bus_space_handle_t sc_br; /* BE registers */
144 bus_space_handle_t sc_cr; /* channel registers */
145 bus_space_handle_t sc_tr; /* transceiver registers */
146
147 u_int sc_rev;
148
149 int sc_channel; /* channel number */
150 int sc_burst;
151
152 struct qec_ring sc_rb; /* Packet Ring Buffer */
153 };
154
155 int bematch(struct device *, void *, void *);
156 void beattach(struct device *, struct device *, void *);
157
158 void beinit(struct be_softc *);
159 void bestart(struct ifnet *);
160 void bestop(struct be_softc *);
161 void bewatchdog(struct ifnet *);
162 int beioctl(struct ifnet *, u_long, caddr_t);
163 void bereset(struct be_softc *);
164
165 int beintr(void *);
166 int berint(struct be_softc *);
167 int betint(struct be_softc *);
168 int beqint(struct be_softc *, u_int32_t);
169 int beeint(struct be_softc *, u_int32_t);
170
171 static void be_read(struct be_softc *, int, int);
172 static int be_put(struct be_softc *, int, struct mbuf *);
173 static struct mbuf *be_get(struct be_softc *, int, int);
174
175 void be_pal_gate(struct be_softc *, int);
176
177 /* ifmedia callbacks */
178 void be_ifmedia_sts(struct ifnet *, struct ifmediareq *);
179 int be_ifmedia_upd(struct ifnet *);
180
181 void be_mcreset(struct be_softc *);
182
183 /* MII methods & callbacks */
184 static int be_mii_readreg(struct device *, int, int);
185 static void be_mii_writereg(struct device *, int, int, int);
186 static void be_mii_statchg(struct device *);
187
188 /* MII helpers */
189 static void be_mii_sync(struct be_softc *);
190 static void be_mii_sendbits(struct be_softc *, int, u_int32_t, int);
191 static int be_mii_reset(struct be_softc *, int);
192 static int be_tcvr_read_bit(struct be_softc *, int);
193 static void be_tcvr_write_bit(struct be_softc *, int, int);
194
195 void be_tick(void *);
196 void be_intphy_auto(struct be_softc *);
197 void be_intphy_status(struct be_softc *);
198 int be_intphy_service(struct be_softc *, struct mii_data *, int);
199
200
201 struct cfattach be_ca = {
202 sizeof(struct be_softc), bematch, beattach
203 };
204
205 struct cfdriver be_cd = {
206 NULL, "be", DV_IFNET
207 };
208
209 int
bematch(struct device * parent,void * vcf,void * aux)210 bematch(struct device *parent, void *vcf, void *aux)
211 {
212 struct cfdata *cf = vcf;
213 struct sbus_attach_args *sa = aux;
214
215 return (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0);
216 }
217
218 void
beattach(struct device * parent,struct device * self,void * aux)219 beattach(struct device *parent, struct device *self, void *aux)
220 {
221 struct sbus_attach_args *sa = aux;
222 struct qec_softc *qec = (struct qec_softc *)parent;
223 struct be_softc *sc = (struct be_softc *)self;
224 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
225 struct mii_data *mii = &sc->sc_mii;
226 struct mii_softc *child;
227 int node = sa->sa_node;
228 bus_dma_tag_t dmatag = sa->sa_dmatag;
229 bus_dma_segment_t seg;
230 bus_size_t size;
231 int instance;
232 int rseg, error;
233 u_int32_t v;
234 extern void myetheraddr(u_char *);
235
236 /* Pass on the bus tags */
237 sc->sc_bustag = sa->sa_bustag;
238 sc->sc_dmatag = sa->sa_dmatag;
239
240 if (sa->sa_nreg < 3) {
241 printf("%s: only %d register sets\n",
242 self->dv_xname, sa->sa_nreg);
243 return;
244 }
245
246 if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
247 (bus_addr_t)sa->sa_reg[0].sbr_offset,
248 (bus_size_t)sa->sa_reg[0].sbr_size, 0, 0, &sc->sc_cr) != 0) {
249 printf("beattach: cannot map registers\n");
250 return;
251 }
252
253 if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[1].sbr_slot,
254 (bus_addr_t)sa->sa_reg[1].sbr_offset,
255 (bus_size_t)sa->sa_reg[1].sbr_size, 0, 0, &sc->sc_br) != 0) {
256 printf("beattach: cannot map registers\n");
257 return;
258 }
259
260 if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[2].sbr_slot,
261 (bus_addr_t)sa->sa_reg[2].sbr_offset,
262 (bus_size_t)sa->sa_reg[2].sbr_size, 0, 0, &sc->sc_tr) != 0) {
263 printf("beattach: cannot map registers\n");
264 return;
265 }
266
267 sc->sc_qec = qec;
268 sc->sc_qr = qec->sc_regs;
269
270 sc->sc_rev = getpropint(node, "board-version", -1);
271 printf(" rev %x", sc->sc_rev);
272
273 bestop(sc);
274
275 sc->sc_channel = getpropint(node, "channel#", -1);
276 if (sc->sc_channel == -1)
277 sc->sc_channel = 0;
278
279 sc->sc_burst = getpropint(node, "burst-sizes", -1);
280 if (sc->sc_burst == -1)
281 sc->sc_burst = qec->sc_burst;
282
283 /* Clamp at parent's burst sizes */
284 sc->sc_burst &= qec->sc_burst;
285
286 /* Establish interrupt handler */
287 if (sa->sa_nintr == 0 || bus_intr_establish(sa->sa_bustag, sa->sa_pri,
288 IPL_NET, 0, beintr, sc, self->dv_xname) == NULL) {
289 printf(": no interrupt established\n");
290 return;
291 }
292
293 myetheraddr(sc->sc_arpcom.ac_enaddr);
294 printf(" address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
295
296 /*
297 * Allocate descriptor ring and buffers.
298 */
299
300 /* for now, allocate as many bufs as there are ring descriptors */
301 sc->sc_rb.rb_ntbuf = QEC_XD_RING_MAXSIZE;
302 sc->sc_rb.rb_nrbuf = QEC_XD_RING_MAXSIZE;
303
304 size = QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd) +
305 QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd) +
306 sc->sc_rb.rb_ntbuf * BE_PKT_BUF_SZ +
307 sc->sc_rb.rb_nrbuf * BE_PKT_BUF_SZ;
308
309 /* Get a DMA handle */
310 if ((error = bus_dmamap_create(dmatag, size, 1, size, 0,
311 BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) {
312 printf("%s: DMA map create error %d\n", self->dv_xname, error);
313 return;
314 }
315
316 /* Allocate DMA buffer */
317 if ((error = bus_dmamem_alloc(sa->sa_dmatag, size, 0, 0,
318 &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
319 printf("%s: DMA buffer alloc error %d\n",
320 self->dv_xname, error);
321 return;
322 }
323
324 /* Map DMA memory in CPU addressable space */
325 if ((error = bus_dmamem_map(sa->sa_dmatag, &seg, rseg, size,
326 &sc->sc_rb.rb_membase, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
327 printf("%s: DMA buffer map error %d\n",
328 self->dv_xname, error);
329 bus_dmamem_free(sa->sa_dmatag, &seg, rseg);
330 return;
331 }
332
333 /* Load the buffer */
334 if ((error = bus_dmamap_load(dmatag, sc->sc_dmamap,
335 sc->sc_rb.rb_membase, size, NULL, BUS_DMA_NOWAIT)) != 0) {
336 printf("%s: DMA buffer map load error %d\n",
337 self->dv_xname, error);
338 bus_dmamem_unmap(dmatag, sc->sc_rb.rb_membase, size);
339 bus_dmamem_free(dmatag, &seg, rseg);
340 return;
341 }
342 sc->sc_rb.rb_dmabase = sc->sc_dmamap->dm_segs[0].ds_addr;
343
344 /*
345 * Initialize our media structures and MII info.
346 */
347 mii->mii_ifp = ifp;
348 mii->mii_readreg = be_mii_readreg;
349 mii->mii_writereg = be_mii_writereg;
350 mii->mii_statchg = be_mii_statchg;
351
352 ifmedia_init(&mii->mii_media, 0, be_ifmedia_upd, be_ifmedia_sts);
353
354 timeout_set(&sc->sc_tick_ch, be_tick, sc);
355
356 /*
357 * Initialize transceiver and determine which PHY connection to use.
358 */
359 be_mii_sync(sc);
360 v = bus_space_read_4(sc->sc_bustag, sc->sc_tr, BE_TRI_MGMTPAL);
361
362 instance = 0;
363
364 if ((v & MGMT_PAL_EXT_MDIO) != 0) {
365
366 mii_attach(&sc->sc_dev, mii, 0xffffffff, BE_PHY_EXTERNAL,
367 MII_OFFSET_ANY, 0);
368
369 child = LIST_FIRST(&mii->mii_phys);
370 if (child == NULL) {
371 /* No PHY attached */
372 ifmedia_add(&sc->sc_media,
373 IFM_MAKEWORD(IFM_ETHER,IFM_NONE,0,instance),
374 0, NULL);
375 ifmedia_set(&sc->sc_media,
376 IFM_MAKEWORD(IFM_ETHER,IFM_NONE,0,instance));
377 } else {
378 /*
379 * Note: we support just one PHY on the external
380 * MII connector.
381 */
382 #ifdef DIAGNOSTIC
383 if (LIST_NEXT(child, mii_list) != NULL) {
384 printf("%s: spurious MII device %s attached\n",
385 sc->sc_dev.dv_xname,
386 child->mii_dev.dv_xname);
387 }
388 #endif
389 if (child->mii_phy != BE_PHY_EXTERNAL ||
390 child->mii_inst > 0) {
391 printf("%s: cannot accommodate MII device %s"
392 " at phy %d, instance %d\n",
393 sc->sc_dev.dv_xname,
394 child->mii_dev.dv_xname,
395 child->mii_phy, child->mii_inst);
396 } else {
397 sc->sc_phys[instance] = child->mii_phy;
398 }
399
400 /*
401 * XXX - we can really do the following ONLY if the
402 * phy indeed has the auto negotiation capability!!
403 */
404 ifmedia_set(&sc->sc_media,
405 IFM_MAKEWORD(IFM_ETHER,IFM_AUTO,0,instance));
406
407 /* Mark our current media setting */
408 be_pal_gate(sc, BE_PHY_EXTERNAL);
409 instance++;
410 }
411
412 }
413
414 if ((v & MGMT_PAL_INT_MDIO) != 0) {
415 /*
416 * The be internal phy looks vaguely like MII hardware,
417 * but not enough to be able to use the MII device
418 * layer. Hence, we have to take care of media selection
419 * ourselves.
420 */
421
422 sc->sc_mii_inst = instance;
423 sc->sc_phys[instance] = BE_PHY_INTERNAL;
424
425 /* Use `ifm_data' to store BMCR bits */
426 ifmedia_add(&sc->sc_media,
427 IFM_MAKEWORD(IFM_ETHER,IFM_10_T,0,instance), 0, NULL);
428 ifmedia_add(&sc->sc_media,
429 IFM_MAKEWORD(IFM_ETHER,IFM_100_TX,0,instance),
430 BMCR_S100, NULL);
431 ifmedia_add(&sc->sc_media,
432 IFM_MAKEWORD(IFM_ETHER,IFM_AUTO,0,instance), 0, NULL);
433
434 printf("on-board transceiver at %s: 10baseT, 100baseTX, auto\n",
435 self->dv_xname);
436
437 be_mii_reset(sc, BE_PHY_INTERNAL);
438 /* Only set default medium here if there's no external PHY */
439 if (instance == 0) {
440 be_pal_gate(sc, BE_PHY_INTERNAL);
441 ifmedia_set(&sc->sc_media,
442 IFM_MAKEWORD(IFM_ETHER,IFM_AUTO,0,instance));
443 } else
444 be_mii_writereg((void *)sc,
445 BE_PHY_INTERNAL, MII_BMCR, BMCR_ISO);
446 }
447
448 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
449 ifp->if_softc = sc;
450 ifp->if_start = bestart;
451 ifp->if_ioctl = beioctl;
452 ifp->if_watchdog = bewatchdog;
453 ifp->if_flags =
454 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
455 IFQ_SET_READY(&ifp->if_snd);
456
457 /* Attach the interface. */
458 if_attach(ifp);
459 ether_ifattach(ifp);
460 }
461
462
463 /*
464 * Routine to copy from mbuf chain to transmit buffer in
465 * network buffer memory.
466 */
467 static __inline__ int
be_put(struct be_softc * sc,int idx,struct mbuf * m)468 be_put(struct be_softc *sc, int idx, struct mbuf *m)
469 {
470 struct mbuf *n;
471 int len, tlen = 0, boff = 0;
472 caddr_t bp;
473
474 bp = sc->sc_rb.rb_txbuf + (idx % sc->sc_rb.rb_ntbuf) * BE_PKT_BUF_SZ;
475
476 for (; m; m = n) {
477 len = m->m_len;
478 if (len == 0) {
479 MFREE(m, n);
480 continue;
481 }
482 bcopy(mtod(m, caddr_t), bp+boff, len);
483 boff += len;
484 tlen += len;
485 MFREE(m, n);
486 }
487 return (tlen);
488 }
489
490 /*
491 * Pull data off an interface.
492 * Len is the length of data, with local net header stripped.
493 * We copy the data into mbufs. When full cluster sized units are present,
494 * we copy into clusters.
495 */
496 static __inline__ struct mbuf *
be_get(struct be_softc * sc,int idx,int totlen)497 be_get(struct be_softc *sc, int idx, int totlen)
498 {
499 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
500 struct mbuf *m;
501 struct mbuf *top, **mp;
502 int len, pad, boff = 0;
503 caddr_t bp;
504
505 bp = sc->sc_rb.rb_rxbuf + (idx % sc->sc_rb.rb_nrbuf) * BE_PKT_BUF_SZ;
506
507 MGETHDR(m, M_DONTWAIT, MT_DATA);
508 if (m == NULL)
509 return (NULL);
510 m->m_pkthdr.rcvif = ifp;
511 m->m_pkthdr.len = totlen;
512
513 pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
514 m->m_data += pad;
515 len = MHLEN - pad;
516 top = NULL;
517 mp = ⊤
518
519 while (totlen > 0) {
520 if (top) {
521 MGET(m, M_DONTWAIT, MT_DATA);
522 if (m == NULL) {
523 m_freem(top);
524 return (NULL);
525 }
526 len = MLEN;
527 }
528 if (top && totlen >= MINCLSIZE) {
529 MCLGET(m, M_DONTWAIT);
530 if (m->m_flags & M_EXT)
531 len = MCLBYTES;
532 }
533 m->m_len = len = min(totlen, len);
534 bcopy(bp + boff, mtod(m, caddr_t), len);
535 boff += len;
536 totlen -= len;
537 *mp = m;
538 mp = &m->m_next;
539 }
540
541 return (top);
542 }
543
544 /*
545 * Pass a packet to the higher levels.
546 */
547 static __inline__ void
be_read(struct be_softc * sc,int idx,int len)548 be_read(struct be_softc *sc, int idx, int len)
549 {
550 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
551 struct mbuf *m;
552
553 if (len <= sizeof(struct ether_header) ||
554 len > ETHERMTU + sizeof(struct ether_header)) {
555
556 printf("%s: invalid packet size %d; dropping\n",
557 ifp->if_xname, len);
558
559 ifp->if_ierrors++;
560 return;
561 }
562
563 /*
564 * Pull packet off interface.
565 */
566 m = be_get(sc, idx, len);
567 if (m == NULL) {
568 ifp->if_ierrors++;
569 return;
570 }
571 ifp->if_ipackets++;
572
573 #if NBPFILTER > 0
574 /*
575 * Check if there's a BPF listener on this interface.
576 * If so, hand off the raw packet to BPF.
577 */
578 if (ifp->if_bpf)
579 bpf_mtap(ifp->if_bpf, m);
580 #endif
581 /* Pass the packet up. */
582 ether_input_mbuf(ifp, m);
583 }
584
585 /*
586 * Start output on interface.
587 * We make two assumptions here:
588 * 1) that the current priority is set to splnet _before_ this code
589 * is called *and* is returned to the appropriate priority after
590 * return
591 * 2) that the IFF_OACTIVE flag is checked before this code is called
592 * (i.e. that the output part of the interface is idle)
593 */
594 void
bestart(struct ifnet * ifp)595 bestart(struct ifnet *ifp)
596 {
597 struct be_softc *sc = (struct be_softc *)ifp->if_softc;
598 struct qec_xd *txd = sc->sc_rb.rb_txd;
599 struct mbuf *m;
600 unsigned int bix, len;
601 unsigned int ntbuf = sc->sc_rb.rb_ntbuf;
602
603 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
604 return;
605
606 bix = sc->sc_rb.rb_tdhead;
607
608 for (;;) {
609 IFQ_DEQUEUE(&ifp->if_snd, m);
610 if (m == 0)
611 break;
612
613 #if NBPFILTER > 0
614 /*
615 * If BPF is listening on this interface, let it see the
616 * packet before we commit it to the wire.
617 */
618 if (ifp->if_bpf)
619 bpf_mtap(ifp->if_bpf, m);
620 #endif
621
622 /*
623 * Copy the mbuf chain into the transmit buffer.
624 */
625 len = be_put(sc, bix, m);
626
627 /*
628 * Initialize transmit registers and start transmission
629 */
630 txd[bix].xd_flags = QEC_XD_OWN | QEC_XD_SOP | QEC_XD_EOP |
631 (len & QEC_XD_LENGTH);
632 bus_space_write_4(sc->sc_bustag, sc->sc_cr, BE_CRI_CTRL,
633 BE_CR_CTRL_TWAKEUP);
634
635 if (++bix == QEC_XD_RING_MAXSIZE)
636 bix = 0;
637
638 if (++sc->sc_rb.rb_td_nbusy == ntbuf) {
639 ifp->if_flags |= IFF_OACTIVE;
640 break;
641 }
642 }
643
644 sc->sc_rb.rb_tdhead = bix;
645 }
646
647 void
bestop(struct be_softc * sc)648 bestop(struct be_softc *sc)
649 {
650 int n;
651 bus_space_tag_t t = sc->sc_bustag;
652 bus_space_handle_t br = sc->sc_br;
653
654 timeout_del(&sc->sc_tick_ch);
655
656 /* Down the MII. */
657 mii_down(&sc->sc_mii);
658 (void)be_intphy_service(sc, &sc->sc_mii, MII_DOWN);
659
660 /* Stop the transmitter */
661 bus_space_write_4(t, br, BE_BRI_TXCFG, 0);
662 for (n = 32; n > 0; n--) {
663 if (bus_space_read_4(t, br, BE_BRI_TXCFG) == 0)
664 break;
665 DELAY(20);
666 }
667
668 /* Stop the receiver */
669 bus_space_write_4(t, br, BE_BRI_RXCFG, 0);
670 for (n = 32; n > 0; n--) {
671 if (bus_space_read_4(t, br, BE_BRI_RXCFG) == 0)
672 break;
673 DELAY(20);
674 }
675 }
676
677 /*
678 * Reset interface.
679 */
680 void
bereset(struct be_softc * sc)681 bereset(struct be_softc *sc)
682 {
683 int s;
684
685 s = splnet();
686 bestop(sc);
687 if ((sc->sc_arpcom.ac_if.if_flags & IFF_UP) != 0)
688 beinit(sc);
689 splx(s);
690 }
691
692 void
bewatchdog(struct ifnet * ifp)693 bewatchdog(struct ifnet *ifp)
694 {
695 struct be_softc *sc = ifp->if_softc;
696
697 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
698 ++sc->sc_arpcom.ac_if.if_oerrors;
699 bereset(sc);
700 }
701
702 int
beintr(void * v)703 beintr(void *v)
704 {
705 struct be_softc *sc = (struct be_softc *)v;
706 bus_space_tag_t t = sc->sc_bustag;
707 u_int32_t whyq, whyb, whyc;
708 int r = 0;
709
710 /* Read QEC status, channel status and BE status */
711 whyq = bus_space_read_4(t, sc->sc_qr, QEC_QRI_STAT);
712 whyc = bus_space_read_4(t, sc->sc_cr, BE_CRI_STAT);
713 whyb = bus_space_read_4(t, sc->sc_br, BE_BRI_STAT);
714
715 if (whyq & QEC_STAT_BM)
716 r |= beeint(sc, whyb);
717
718 if (whyq & QEC_STAT_ER)
719 r |= beqint(sc, whyc);
720
721 if (whyq & QEC_STAT_TX && whyc & BE_CR_STAT_TXIRQ)
722 r |= betint(sc);
723
724 if (whyq & QEC_STAT_RX && whyc & BE_CR_STAT_RXIRQ)
725 r |= berint(sc);
726
727 return (r);
728 }
729
730 /*
731 * QEC Interrupt.
732 */
733 int
beqint(struct be_softc * sc,u_int32_t why)734 beqint(struct be_softc *sc, u_int32_t why)
735 {
736 int r = 0, rst = 0;
737
738 if (why & BE_CR_STAT_TXIRQ)
739 r |= 1;
740 if (why & BE_CR_STAT_RXIRQ)
741 r |= 1;
742
743 if (why & BE_CR_STAT_BERROR) {
744 r |= 1;
745 rst = 1;
746 printf("%s: bigmac error\n", sc->sc_dev.dv_xname);
747 }
748
749 if (why & BE_CR_STAT_TXDERR) {
750 r |= 1;
751 rst = 1;
752 printf("%s: bogus tx descriptor\n", sc->sc_dev.dv_xname);
753 }
754
755 if (why & (BE_CR_STAT_TXLERR | BE_CR_STAT_TXPERR | BE_CR_STAT_TXSERR)) {
756 r |= 1;
757 rst = 1;
758 printf("%s: tx dma error ( ", sc->sc_dev.dv_xname);
759 if (why & BE_CR_STAT_TXLERR)
760 printf("Late ");
761 if (why & BE_CR_STAT_TXPERR)
762 printf("Parity ");
763 if (why & BE_CR_STAT_TXSERR)
764 printf("Generic ");
765 printf(")\n");
766 }
767
768 if (why & BE_CR_STAT_RXDROP) {
769 r |= 1;
770 rst = 1;
771 printf("%s: out of rx descriptors\n", sc->sc_dev.dv_xname);
772 }
773
774 if (why & BE_CR_STAT_RXSMALL) {
775 r |= 1;
776 rst = 1;
777 printf("%s: rx descriptor too small\n", sc->sc_dev.dv_xname);
778 }
779
780 if (why & (BE_CR_STAT_RXLERR | BE_CR_STAT_RXPERR | BE_CR_STAT_RXSERR)) {
781 r |= 1;
782 rst = 1;
783 printf("%s: rx dma error ( ", sc->sc_dev.dv_xname);
784 if (why & BE_CR_STAT_RXLERR)
785 printf("Late ");
786 if (why & BE_CR_STAT_RXPERR)
787 printf("Parity ");
788 if (why & BE_CR_STAT_RXSERR)
789 printf("Generic ");
790 printf(")\n");
791 }
792
793 if (!r) {
794 rst = 1;
795 printf("%s: unexpected error interrupt %08x\n",
796 sc->sc_dev.dv_xname, why);
797 }
798
799 if (rst) {
800 printf("%s: resetting\n", sc->sc_dev.dv_xname);
801 bereset(sc);
802 }
803
804 return (r);
805 }
806
807 /*
808 * Error interrupt.
809 */
810 int
beeint(struct be_softc * sc,u_int32_t why)811 beeint(struct be_softc *sc, u_int32_t why)
812 {
813 int r = 0, rst = 0;
814
815 if (why & BE_BR_STAT_RFIFOVF) {
816 r |= 1;
817 rst = 1;
818 printf("%s: receive fifo overrun\n", sc->sc_dev.dv_xname);
819 }
820 if (why & BE_BR_STAT_TFIFO_UND) {
821 r |= 1;
822 rst = 1;
823 printf("%s: transmit fifo underrun\n", sc->sc_dev.dv_xname);
824 }
825 if (why & BE_BR_STAT_MAXPKTERR) {
826 r |= 1;
827 rst = 1;
828 printf("%s: max packet size error\n", sc->sc_dev.dv_xname);
829 }
830
831 if (!r) {
832 rst = 1;
833 printf("%s: unexpected error interrupt %08x\n",
834 sc->sc_dev.dv_xname, why);
835 }
836
837 if (rst) {
838 printf("%s: resetting\n", sc->sc_dev.dv_xname);
839 bereset(sc);
840 }
841
842 return (r);
843 }
844
845 /*
846 * Transmit interrupt.
847 */
848 int
betint(struct be_softc * sc)849 betint(struct be_softc *sc)
850 {
851 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
852 bus_space_tag_t t = sc->sc_bustag;
853 bus_space_handle_t br = sc->sc_br;
854 unsigned int bix, txflags;
855
856 /*
857 * Unload collision counters
858 */
859 ifp->if_collisions +=
860 bus_space_read_4(t, br, BE_BRI_NCCNT) +
861 bus_space_read_4(t, br, BE_BRI_FCCNT) +
862 bus_space_read_4(t, br, BE_BRI_EXCNT) +
863 bus_space_read_4(t, br, BE_BRI_LTCNT);
864
865 /*
866 * the clear the hardware counters
867 */
868 bus_space_write_4(t, br, BE_BRI_NCCNT, 0);
869 bus_space_write_4(t, br, BE_BRI_FCCNT, 0);
870 bus_space_write_4(t, br, BE_BRI_EXCNT, 0);
871 bus_space_write_4(t, br, BE_BRI_LTCNT, 0);
872
873 bix = sc->sc_rb.rb_tdtail;
874
875 for (;;) {
876 if (sc->sc_rb.rb_td_nbusy <= 0)
877 break;
878
879 txflags = sc->sc_rb.rb_txd[bix].xd_flags;
880
881 if (txflags & QEC_XD_OWN)
882 break;
883
884 ifp->if_flags &= ~IFF_OACTIVE;
885 ifp->if_opackets++;
886
887 if (++bix == QEC_XD_RING_MAXSIZE)
888 bix = 0;
889
890 --sc->sc_rb.rb_td_nbusy;
891 }
892
893 sc->sc_rb.rb_tdtail = bix;
894
895 bestart(ifp);
896
897 if (sc->sc_rb.rb_td_nbusy == 0)
898 ifp->if_timer = 0;
899
900 return (1);
901 }
902
903 /*
904 * Receive interrupt.
905 */
906 int
berint(struct be_softc * sc)907 berint(struct be_softc *sc)
908 {
909 struct qec_xd *xd = sc->sc_rb.rb_rxd;
910 unsigned int bix, len;
911 unsigned int nrbuf = sc->sc_rb.rb_nrbuf;
912
913 bix = sc->sc_rb.rb_rdtail;
914
915 /*
916 * Process all buffers with valid data.
917 */
918 for (;;) {
919 len = xd[bix].xd_flags;
920 if (len & QEC_XD_OWN)
921 break;
922
923 len &= QEC_XD_LENGTH;
924 be_read(sc, bix, len);
925
926 /* ... */
927 xd[(bix+nrbuf) % QEC_XD_RING_MAXSIZE].xd_flags =
928 QEC_XD_OWN | (BE_PKT_BUF_SZ & QEC_XD_LENGTH);
929
930 if (++bix == QEC_XD_RING_MAXSIZE)
931 bix = 0;
932 }
933
934 sc->sc_rb.rb_rdtail = bix;
935
936 return (1);
937 }
938
939 int
beioctl(struct ifnet * ifp,u_long cmd,caddr_t data)940 beioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
941 {
942 struct be_softc *sc = ifp->if_softc;
943 struct ifaddr *ifa = (struct ifaddr *)data;
944 struct ifreq *ifr = (struct ifreq *)data;
945 int s, error = 0;
946
947 s = splnet();
948
949 if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
950 splx(s);
951 return (error);
952 }
953
954 switch (cmd) {
955 case SIOCSIFADDR:
956 ifp->if_flags |= IFF_UP;
957 switch (ifa->ifa_addr->sa_family) {
958 #ifdef INET
959 case AF_INET:
960 beinit(sc);
961 arp_ifinit(&sc->sc_arpcom, ifa);
962 break;
963 #endif /* INET */
964 #ifdef NS
965 case AF_NS:
966 {
967 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
968
969 if (ns_nullhost(*ina))
970 ina->x_host =
971 *(union ns_host *)LLADDR(ifp->if_sadl);
972 else
973 bcopy(ina->x_host.c_host, LLADDR(ifp->if_sadl),
974 sizeof(sc->sc_arpcom.ac_enaddr));
975 /* Set new address. */
976 beinit(sc);
977 break;
978 }
979 #endif /* NS */
980 default:
981 beinit(sc);
982 break;
983 }
984 break;
985
986 case SIOCSIFFLAGS:
987 if ((ifp->if_flags & IFF_UP) == 0 &&
988 (ifp->if_flags & IFF_RUNNING) != 0) {
989 /*
990 * If interface is marked down and it is running, then
991 * stop it.
992 */
993 bestop(sc);
994 ifp->if_flags &= ~IFF_RUNNING;
995 } else if ((ifp->if_flags & IFF_UP) != 0 &&
996 (ifp->if_flags & IFF_RUNNING) == 0) {
997 /*
998 * If interface is marked up and it is stopped, then
999 * start it.
1000 */
1001 beinit(sc);
1002 } else {
1003 /*
1004 * Reset the interface to pick up changes in any other
1005 * flags that affect hardware registers.
1006 */
1007 bestop(sc);
1008 beinit(sc);
1009 }
1010 #ifdef BEDEBUG
1011 if (ifp->if_flags & IFF_DEBUG)
1012 sc->sc_debug = 1;
1013 else
1014 sc->sc_debug = 0;
1015 #endif
1016 break;
1017
1018 case SIOCADDMULTI:
1019 case SIOCDELMULTI:
1020 error = (cmd == SIOCADDMULTI) ?
1021 ether_addmulti(ifr, &sc->sc_arpcom):
1022 ether_delmulti(ifr, &sc->sc_arpcom);
1023
1024 if (error == ENETRESET) {
1025 /*
1026 * Multicast list has changed; set the hardware filter
1027 * accordingly.
1028 */
1029 be_mcreset(sc);
1030 error = 0;
1031 }
1032 break;
1033 case SIOCGIFMEDIA:
1034 case SIOCSIFMEDIA:
1035 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
1036 break;
1037 default:
1038 error = EINVAL;
1039 break;
1040 }
1041 splx(s);
1042 return (error);
1043 }
1044
1045
1046 void
beinit(struct be_softc * sc)1047 beinit(struct be_softc *sc)
1048 {
1049 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1050 bus_space_tag_t t = sc->sc_bustag;
1051 bus_space_handle_t br = sc->sc_br;
1052 bus_space_handle_t cr = sc->sc_cr;
1053 struct qec_softc *qec = sc->sc_qec;
1054 u_int32_t v;
1055 u_int32_t qecaddr;
1056 u_int8_t *ea;
1057 int s;
1058
1059 s = splnet();
1060
1061 qec_meminit(&sc->sc_rb, BE_PKT_BUF_SZ);
1062
1063 bestop(sc);
1064
1065 ea = sc->sc_arpcom.ac_enaddr;
1066 bus_space_write_4(t, br, BE_BRI_MACADDR0, (ea[0] << 8) | ea[1]);
1067 bus_space_write_4(t, br, BE_BRI_MACADDR1, (ea[2] << 8) | ea[3]);
1068 bus_space_write_4(t, br, BE_BRI_MACADDR2, (ea[4] << 8) | ea[5]);
1069
1070 /* Clear hash table */
1071 bus_space_write_4(t, br, BE_BRI_HASHTAB0, 0);
1072 bus_space_write_4(t, br, BE_BRI_HASHTAB1, 0);
1073 bus_space_write_4(t, br, BE_BRI_HASHTAB2, 0);
1074 bus_space_write_4(t, br, BE_BRI_HASHTAB3, 0);
1075
1076 /* Re-initialize RX configuration */
1077 v = BE_BR_RXCFG_FIFO;
1078 bus_space_write_4(t, br, BE_BRI_RXCFG, v);
1079
1080 be_mcreset(sc);
1081
1082 bus_space_write_4(t, br, BE_BRI_RANDSEED, 0xbd);
1083
1084 bus_space_write_4(t, br, BE_BRI_XIFCFG,
1085 BE_BR_XCFG_ODENABLE | BE_BR_XCFG_RESV);
1086
1087 bus_space_write_4(t, br, BE_BRI_JSIZE, 4);
1088
1089 /*
1090 * Turn off counter expiration interrupts as well as
1091 * 'gotframe' and 'sentframe'
1092 */
1093 bus_space_write_4(t, br, BE_BRI_IMASK,
1094 BE_BR_IMASK_GOTFRAME |
1095 BE_BR_IMASK_RCNTEXP |
1096 BE_BR_IMASK_ACNTEXP |
1097 BE_BR_IMASK_CCNTEXP |
1098 BE_BR_IMASK_LCNTEXP |
1099 BE_BR_IMASK_CVCNTEXP |
1100 BE_BR_IMASK_SENTFRAME |
1101 BE_BR_IMASK_NCNTEXP |
1102 BE_BR_IMASK_ECNTEXP |
1103 BE_BR_IMASK_LCCNTEXP |
1104 BE_BR_IMASK_FCNTEXP |
1105 BE_BR_IMASK_DTIMEXP);
1106
1107 /* Channel registers: */
1108 bus_space_write_4(t, cr, BE_CRI_RXDS, (u_int32_t)sc->sc_rb.rb_rxddma);
1109 bus_space_write_4(t, cr, BE_CRI_TXDS, (u_int32_t)sc->sc_rb.rb_txddma);
1110
1111 qecaddr = sc->sc_channel * qec->sc_msize;
1112 bus_space_write_4(t, cr, BE_CRI_RXWBUF, qecaddr);
1113 bus_space_write_4(t, cr, BE_CRI_RXRBUF, qecaddr);
1114 bus_space_write_4(t, cr, BE_CRI_TXWBUF, qecaddr + qec->sc_rsize);
1115 bus_space_write_4(t, cr, BE_CRI_TXRBUF, qecaddr + qec->sc_rsize);
1116
1117 bus_space_write_4(t, cr, BE_CRI_RIMASK, 0);
1118 bus_space_write_4(t, cr, BE_CRI_TIMASK, 0);
1119 bus_space_write_4(t, cr, BE_CRI_QMASK, 0);
1120 bus_space_write_4(t, cr, BE_CRI_BMASK, 0);
1121 bus_space_write_4(t, cr, BE_CRI_CCNT, 0);
1122
1123 /* Enable transmitter */
1124 bus_space_write_4(t, br, BE_BRI_TXCFG,
1125 BE_BR_TXCFG_FIFO | BE_BR_TXCFG_ENABLE);
1126
1127 /* Enable receiver */
1128 v = bus_space_read_4(t, br, BE_BRI_RXCFG);
1129 v |= BE_BR_RXCFG_FIFO | BE_BR_RXCFG_ENABLE;
1130 bus_space_write_4(t, br, BE_BRI_RXCFG, v);
1131
1132 ifp->if_flags |= IFF_RUNNING;
1133 ifp->if_flags &= ~IFF_OACTIVE;
1134
1135 be_ifmedia_upd(ifp);
1136 timeout_add(&sc->sc_tick_ch, hz);
1137 splx(s);
1138 }
1139
1140 void
be_mcreset(struct be_softc * sc)1141 be_mcreset(struct be_softc *sc)
1142 {
1143 struct arpcom *ac = &sc->sc_arpcom;
1144 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1145 bus_space_tag_t t = sc->sc_bustag;
1146 bus_space_handle_t br = sc->sc_br;
1147 u_int32_t crc;
1148 u_int16_t hash[4];
1149 u_int8_t octet;
1150 u_int32_t v;
1151 int i, j;
1152 struct ether_multi *enm;
1153 struct ether_multistep step;
1154
1155 if (ifp->if_flags & IFF_PROMISC) {
1156 v = bus_space_read_4(t, br, BE_BRI_RXCFG);
1157 v |= BE_BR_RXCFG_PMISC;
1158 bus_space_write_4(t, br, BE_BRI_RXCFG, v);
1159 return;
1160 }
1161
1162 if (ifp->if_flags & IFF_ALLMULTI) {
1163 hash[3] = hash[2] = hash[1] = hash[0] = 0xffff;
1164 goto chipit;
1165 }
1166
1167 hash[3] = hash[2] = hash[1] = hash[0] = 0;
1168
1169 ETHER_FIRST_MULTI(step, ac, enm);
1170 while (enm != NULL) {
1171 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
1172 /*
1173 * We must listen to a range of multicast
1174 * addresses. For now, just accept all
1175 * multicasts, rather than trying to set only
1176 * those filter bits needed to match the range.
1177 * (At this time, the only use of address
1178 * ranges is for IP multicast routing, for
1179 * which the range is big enough to require
1180 * all bits set.)
1181 */
1182 hash[3] = hash[2] = hash[1] = hash[0] = 0xffff;
1183 ifp->if_flags |= IFF_ALLMULTI;
1184 goto chipit;
1185 }
1186
1187 crc = 0xffffffff;
1188
1189 for (i = 0; i < ETHER_ADDR_LEN; i++) {
1190 octet = enm->enm_addrlo[i];
1191
1192 for (j = 0; j < 8; j++) {
1193 if ((crc & 1) ^ (octet & 1)) {
1194 crc >>= 1;
1195 crc ^= MC_POLY_LE;
1196 }
1197 else
1198 crc >>= 1;
1199 octet >>= 1;
1200 }
1201 }
1202
1203 crc >>= 26;
1204 hash[crc >> 4] |= 1 << (crc & 0xf);
1205 ETHER_NEXT_MULTI(step, enm);
1206 }
1207
1208 ifp->if_flags &= ~IFF_ALLMULTI;
1209
1210 chipit:
1211 /* Enable the hash filter */
1212 bus_space_write_4(t, br, BE_BRI_HASHTAB0, hash[0]);
1213 bus_space_write_4(t, br, BE_BRI_HASHTAB1, hash[1]);
1214 bus_space_write_4(t, br, BE_BRI_HASHTAB2, hash[2]);
1215 bus_space_write_4(t, br, BE_BRI_HASHTAB3, hash[3]);
1216
1217 v = bus_space_read_4(t, br, BE_BRI_RXCFG);
1218 v &= ~BE_BR_RXCFG_PMISC;
1219 v |= BE_BR_RXCFG_HENABLE;
1220 bus_space_write_4(t, br, BE_BRI_RXCFG, v);
1221 }
1222
1223 /*
1224 * Set the tcvr to an idle state
1225 */
1226 void
be_mii_sync(struct be_softc * sc)1227 be_mii_sync(struct be_softc *sc)
1228 {
1229 bus_space_tag_t t = sc->sc_bustag;
1230 bus_space_handle_t tr = sc->sc_tr;
1231 int n = 32;
1232
1233 while (n--) {
1234 bus_space_write_4(t, tr, BE_TRI_MGMTPAL,
1235 MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO | MGMT_PAL_OENAB);
1236 (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
1237 bus_space_write_4(t, tr, BE_TRI_MGMTPAL,
1238 MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO |
1239 MGMT_PAL_OENAB | MGMT_PAL_DCLOCK);
1240 (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
1241 }
1242 }
1243
1244 void
be_pal_gate(struct be_softc * sc,int phy)1245 be_pal_gate(struct be_softc *sc, int phy)
1246 {
1247 bus_space_tag_t t = sc->sc_bustag;
1248 bus_space_handle_t tr = sc->sc_tr;
1249 u_int32_t v;
1250
1251 be_mii_sync(sc);
1252
1253 v = ~(TCVR_PAL_EXTLBACK | TCVR_PAL_MSENSE | TCVR_PAL_LTENABLE);
1254 if (phy == BE_PHY_INTERNAL)
1255 v &= ~TCVR_PAL_SERIAL;
1256
1257 bus_space_write_4(t, tr, BE_TRI_TCVRPAL, v);
1258 (void)bus_space_read_4(t, tr, BE_TRI_TCVRPAL);
1259 }
1260
1261 static int
be_tcvr_read_bit(struct be_softc * sc,int phy)1262 be_tcvr_read_bit(struct be_softc *sc, int phy)
1263 {
1264 bus_space_tag_t t = sc->sc_bustag;
1265 bus_space_handle_t tr = sc->sc_tr;
1266 int ret;
1267
1268 if (phy == BE_PHY_INTERNAL) {
1269 bus_space_write_4(t, tr, BE_TRI_MGMTPAL, MGMT_PAL_EXT_MDIO);
1270 (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
1271 bus_space_write_4(t, tr, BE_TRI_MGMTPAL,
1272 MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK);
1273 (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
1274 ret = (bus_space_read_4(t, tr, BE_TRI_MGMTPAL) &
1275 MGMT_PAL_INT_MDIO) >> MGMT_PAL_INT_MDIO_SHIFT;
1276 } else {
1277 bus_space_write_4(t, tr, BE_TRI_MGMTPAL, MGMT_PAL_INT_MDIO);
1278 (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
1279 ret = (bus_space_read_4(t, tr, BE_TRI_MGMTPAL) &
1280 MGMT_PAL_EXT_MDIO) >> MGMT_PAL_EXT_MDIO_SHIFT;
1281 bus_space_write_4(t, tr, BE_TRI_MGMTPAL,
1282 MGMT_PAL_INT_MDIO | MGMT_PAL_DCLOCK);
1283 (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
1284 }
1285
1286 return (ret);
1287 }
1288
1289 static void
be_tcvr_write_bit(struct be_softc * sc,int phy,int bit)1290 be_tcvr_write_bit(struct be_softc *sc, int phy, int bit)
1291 {
1292 bus_space_tag_t t = sc->sc_bustag;
1293 bus_space_handle_t tr = sc->sc_tr;
1294 u_int32_t v;
1295
1296 if (phy == BE_PHY_INTERNAL) {
1297 v = ((bit & 1) << MGMT_PAL_INT_MDIO_SHIFT) |
1298 MGMT_PAL_OENAB | MGMT_PAL_EXT_MDIO;
1299 } else {
1300 v = ((bit & 1) << MGMT_PAL_EXT_MDIO_SHIFT)
1301 | MGMT_PAL_OENAB | MGMT_PAL_INT_MDIO;
1302 }
1303 bus_space_write_4(t, tr, BE_TRI_MGMTPAL, v);
1304 (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
1305 bus_space_write_4(t, tr, BE_TRI_MGMTPAL, v | MGMT_PAL_DCLOCK);
1306 (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
1307 }
1308
1309 static void
be_mii_sendbits(struct be_softc * sc,int phy,u_int32_t data,int nbits)1310 be_mii_sendbits(struct be_softc *sc, int phy, u_int32_t data, int nbits)
1311 {
1312 int i;
1313
1314 for (i = 1 << (nbits - 1); i != 0; i >>= 1)
1315 be_tcvr_write_bit(sc, phy, (data & i) != 0);
1316 }
1317
1318 static int
be_mii_readreg(struct device * self,int phy,int reg)1319 be_mii_readreg(struct device *self, int phy, int reg)
1320 {
1321 struct be_softc *sc = (struct be_softc *)self;
1322 int val = 0, i;
1323
1324 /*
1325 * Read the PHY register by manually driving the MII control lines.
1326 */
1327 be_mii_sync(sc);
1328 be_mii_sendbits(sc, phy, MII_COMMAND_START, 2);
1329 be_mii_sendbits(sc, phy, MII_COMMAND_READ, 2);
1330 be_mii_sendbits(sc, phy, phy, 5);
1331 be_mii_sendbits(sc, phy, reg, 5);
1332
1333 (void) be_tcvr_read_bit(sc, phy);
1334 (void) be_tcvr_read_bit(sc, phy);
1335
1336 for (i = 15; i >= 0; i--)
1337 val |= (be_tcvr_read_bit(sc, phy) << i);
1338
1339 (void) be_tcvr_read_bit(sc, phy);
1340 (void) be_tcvr_read_bit(sc, phy);
1341 (void) be_tcvr_read_bit(sc, phy);
1342
1343 return (val);
1344 }
1345
1346 void
be_mii_writereg(struct device * self,int phy,int reg,int val)1347 be_mii_writereg(struct device *self, int phy, int reg, int val)
1348 {
1349 struct be_softc *sc = (struct be_softc *)self;
1350 int i;
1351
1352 /*
1353 * Write the PHY register by manually driving the MII control lines.
1354 */
1355 be_mii_sync(sc);
1356 be_mii_sendbits(sc, phy, MII_COMMAND_START, 2);
1357 be_mii_sendbits(sc, phy, MII_COMMAND_WRITE, 2);
1358 be_mii_sendbits(sc, phy, phy, 5);
1359 be_mii_sendbits(sc, phy, reg, 5);
1360
1361 be_tcvr_write_bit(sc, phy, 1);
1362 be_tcvr_write_bit(sc, phy, 0);
1363
1364 for (i = 15; i >= 0; i--)
1365 be_tcvr_write_bit(sc, phy, (val >> i) & 1);
1366 }
1367
1368 int
be_mii_reset(struct be_softc * sc,int phy)1369 be_mii_reset(struct be_softc *sc, int phy)
1370 {
1371 int n;
1372
1373 be_mii_writereg((struct device *)sc, phy, MII_BMCR,
1374 BMCR_LOOP | BMCR_PDOWN | BMCR_ISO);
1375 be_mii_writereg((struct device *)sc, phy, MII_BMCR, BMCR_RESET);
1376
1377 for (n = 16; n >= 0; n--) {
1378 int bmcr = be_mii_readreg((struct device *)sc, phy, MII_BMCR);
1379 if ((bmcr & BMCR_RESET) == 0)
1380 break;
1381 DELAY(20);
1382 }
1383 if (n == 0) {
1384 printf("%s: bmcr reset failed\n", sc->sc_dev.dv_xname);
1385 return (EIO);
1386 }
1387
1388 return (0);
1389 }
1390
1391 void
be_tick(void * arg)1392 be_tick(void *arg)
1393 {
1394 struct be_softc *sc = arg;
1395 int s = splnet();
1396
1397 mii_tick(&sc->sc_mii);
1398 (void)be_intphy_service(sc, &sc->sc_mii, MII_TICK);
1399
1400 timeout_add(&sc->sc_tick_ch, hz);
1401 splx(s);
1402 }
1403
1404 void
be_mii_statchg(struct device * self)1405 be_mii_statchg(struct device *self)
1406 {
1407 struct be_softc *sc = (struct be_softc *)self;
1408 bus_space_tag_t t = sc->sc_bustag;
1409 bus_space_handle_t br = sc->sc_br;
1410 u_int instance;
1411 u_int32_t v;
1412
1413 instance = IFM_INST(sc->sc_mii.mii_media.ifm_cur->ifm_media);
1414 #ifdef DIAGNOSTIC
1415 if (instance > 1)
1416 panic("be_mii_statchg: instance %d out of range", instance);
1417 #endif
1418
1419 /* Update duplex mode in TX configuration */
1420 v = bus_space_read_4(t, br, BE_BRI_TXCFG);
1421 if ((IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX) != 0)
1422 v |= BE_BR_TXCFG_FULLDPLX;
1423 else
1424 v &= ~BE_BR_TXCFG_FULLDPLX;
1425 bus_space_write_4(t, br, BE_BRI_TXCFG, v);
1426
1427 /* Change to appropriate gate in transceiver PAL */
1428 be_pal_gate(sc, sc->sc_phys[instance]);
1429 }
1430
1431 /*
1432 * Get current media settings.
1433 */
1434 void
be_ifmedia_sts(struct ifnet * ifp,struct ifmediareq * ifmr)1435 be_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
1436 {
1437 struct be_softc *sc = ifp->if_softc;
1438
1439 mii_pollstat(&sc->sc_mii);
1440 (void)be_intphy_service(sc, &sc->sc_mii, MII_POLLSTAT);
1441
1442 ifmr->ifm_status = sc->sc_mii.mii_media_status;
1443 ifmr->ifm_active = sc->sc_mii.mii_media_active;
1444 return;
1445 }
1446
1447 /*
1448 * Set media options.
1449 */
1450 int
be_ifmedia_upd(struct ifnet * ifp)1451 be_ifmedia_upd(struct ifnet *ifp)
1452 {
1453 struct be_softc *sc = ifp->if_softc;
1454 int error;
1455
1456 if ((error = mii_mediachg(&sc->sc_mii)) != 0)
1457 return (error);
1458
1459 return (be_intphy_service(sc, &sc->sc_mii, MII_MEDIACHG));
1460 }
1461
1462 /*
1463 * Service routine for our pseudo-MII internal transceiver.
1464 */
1465 int
be_intphy_service(struct be_softc * sc,struct mii_data * mii,int cmd)1466 be_intphy_service(struct be_softc *sc, struct mii_data *mii, int cmd)
1467 {
1468 struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
1469 int bmcr, bmsr;
1470 int error;
1471
1472 switch (cmd) {
1473 case MII_POLLSTAT:
1474 /*
1475 * If we're not polling our PHY instance, just return.
1476 */
1477 if (IFM_INST(ife->ifm_media) != sc->sc_mii_inst)
1478 return (0);
1479
1480 break;
1481
1482 case MII_MEDIACHG:
1483
1484 /*
1485 * If the media indicates a different PHY instance,
1486 * isolate ourselves.
1487 */
1488 if (IFM_INST(ife->ifm_media) != sc->sc_mii_inst) {
1489 bmcr = be_mii_readreg((void *)sc,
1490 BE_PHY_INTERNAL, MII_BMCR);
1491 be_mii_writereg((void *)sc,
1492 BE_PHY_INTERNAL, MII_BMCR, bmcr | BMCR_ISO);
1493 sc->sc_mii_flags &= ~MIIF_HAVELINK;
1494 sc->sc_intphy_curspeed = 0;
1495 return (0);
1496 }
1497
1498
1499 if ((error = be_mii_reset(sc, BE_PHY_INTERNAL)) != 0)
1500 return (error);
1501
1502 bmcr = be_mii_readreg((void *)sc, BE_PHY_INTERNAL, MII_BMCR);
1503
1504 /*
1505 * Select the new mode and take out of isolation
1506 */
1507 if (IFM_SUBTYPE(ife->ifm_media) == IFM_100_TX)
1508 bmcr |= BMCR_S100;
1509 else if (IFM_SUBTYPE(ife->ifm_media) == IFM_10_T)
1510 bmcr &= ~BMCR_S100;
1511 else if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) {
1512 if ((sc->sc_mii_flags & MIIF_HAVELINK) != 0) {
1513 bmcr &= ~BMCR_S100;
1514 bmcr |= sc->sc_intphy_curspeed;
1515 } else {
1516 /* Keep isolated until link is up */
1517 bmcr |= BMCR_ISO;
1518 sc->sc_mii_flags |= MIIF_DOINGAUTO;
1519 }
1520 }
1521
1522 if ((IFM_OPTIONS(ife->ifm_media) & IFM_FDX) != 0)
1523 bmcr |= BMCR_FDX;
1524 else
1525 bmcr &= ~BMCR_FDX;
1526
1527 be_mii_writereg((void *)sc, BE_PHY_INTERNAL, MII_BMCR, bmcr);
1528 break;
1529
1530 case MII_TICK:
1531 /*
1532 * If we're not currently selected, just return.
1533 */
1534 if (IFM_INST(ife->ifm_media) != sc->sc_mii_inst)
1535 return (0);
1536
1537 /* Only used for automatic media selection */
1538 if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO)
1539 return (0);
1540
1541 /* Is the interface even up? */
1542 if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
1543 return (0);
1544
1545 /*
1546 * Check link status; if we don't have a link, try another
1547 * speed. We can't detect duplex mode, so half-duplex is
1548 * what we have to settle for.
1549 */
1550
1551 /* Read twice in case the register is latched */
1552 bmsr = be_mii_readreg((void *)sc, BE_PHY_INTERNAL, MII_BMSR) |
1553 be_mii_readreg((void *)sc, BE_PHY_INTERNAL, MII_BMSR);
1554
1555 if ((bmsr & BMSR_LINK) != 0) {
1556 /* We have a carrier */
1557 bmcr = be_mii_readreg((void *)sc,
1558 BE_PHY_INTERNAL, MII_BMCR);
1559
1560 if ((sc->sc_mii_flags & MIIF_DOINGAUTO) != 0) {
1561 bmcr = be_mii_readreg((void *)sc,
1562 BE_PHY_INTERNAL, MII_BMCR);
1563
1564 sc->sc_mii_flags |= MIIF_HAVELINK;
1565 sc->sc_intphy_curspeed = (bmcr & BMCR_S100);
1566 sc->sc_mii_flags &= ~MIIF_DOINGAUTO;
1567
1568 bmcr &= ~BMCR_ISO;
1569 be_mii_writereg((void *)sc,
1570 BE_PHY_INTERNAL, MII_BMCR, bmcr);
1571
1572 printf("%s: link up at %s Mbps\n",
1573 sc->sc_dev.dv_xname,
1574 (bmcr & BMCR_S100) ? "100" : "10");
1575 }
1576 return (0);
1577 }
1578
1579 if ((sc->sc_mii_flags & MIIF_DOINGAUTO) == 0) {
1580 sc->sc_mii_flags |= MIIF_DOINGAUTO;
1581 sc->sc_mii_flags &= ~MIIF_HAVELINK;
1582 sc->sc_intphy_curspeed = 0;
1583 printf("%s: link down\n", sc->sc_dev.dv_xname);
1584 }
1585
1586 /* Only retry autonegotiation every 5 seconds. */
1587 if (++sc->sc_mii_ticks < 5)
1588 return(0);
1589
1590 sc->sc_mii_ticks = 0;
1591 bmcr = be_mii_readreg((void *)sc, BE_PHY_INTERNAL, MII_BMCR);
1592 /* Just flip the fast speed bit */
1593 bmcr ^= BMCR_S100;
1594 be_mii_writereg((void *)sc, BE_PHY_INTERNAL, MII_BMCR, bmcr);
1595
1596 break;
1597
1598 case MII_DOWN:
1599 /* Isolate this phy */
1600 bmcr = be_mii_readreg((void *)sc, BE_PHY_INTERNAL, MII_BMCR);
1601 be_mii_writereg((void *)sc,
1602 BE_PHY_INTERNAL, MII_BMCR, bmcr | BMCR_ISO);
1603 return (0);
1604 }
1605
1606 /* Update the media status. */
1607 be_intphy_status(sc);
1608
1609 /* Callback if something changed. */
1610 if (sc->sc_mii_active != mii->mii_media_active || cmd == MII_MEDIACHG) {
1611 (*mii->mii_statchg)((struct device *)sc);
1612 sc->sc_mii_active = mii->mii_media_active;
1613 }
1614 return (0);
1615 }
1616
1617 /*
1618 * Determine status of internal transceiver
1619 */
1620 void
be_intphy_status(struct be_softc * sc)1621 be_intphy_status(struct be_softc *sc)
1622 {
1623 struct mii_data *mii = &sc->sc_mii;
1624 int media_active, media_status;
1625 int bmcr, bmsr;
1626
1627 media_status = IFM_AVALID;
1628 media_active = 0;
1629
1630 /*
1631 * Internal transceiver; do the work here.
1632 */
1633 bmcr = be_mii_readreg((struct device *)sc, BE_PHY_INTERNAL, MII_BMCR);
1634
1635 switch (bmcr & (BMCR_S100 | BMCR_FDX)) {
1636 case (BMCR_S100 | BMCR_FDX):
1637 media_active = IFM_ETHER | IFM_100_TX | IFM_FDX;
1638 break;
1639 case BMCR_S100:
1640 media_active = IFM_ETHER | IFM_100_TX | IFM_HDX;
1641 break;
1642 case BMCR_FDX:
1643 media_active = IFM_ETHER | IFM_10_T | IFM_FDX;
1644 break;
1645 case 0:
1646 media_active = IFM_ETHER | IFM_10_T | IFM_HDX;
1647 break;
1648 }
1649
1650 /* Read twice in case the register is latched */
1651 bmsr = be_mii_readreg((struct device *)sc, BE_PHY_INTERNAL, MII_BMSR)|
1652 be_mii_readreg((struct device *)sc, BE_PHY_INTERNAL, MII_BMSR);
1653 if (bmsr & BMSR_LINK)
1654 media_status |= IFM_ACTIVE;
1655
1656 mii->mii_media_status = media_status;
1657 mii->mii_media_active = media_active;
1658 }
1659