if_bce.c revision 1.17 1 /* $NetBSD: if_bce.c,v 1.17 2007/07/19 22:04:22 dsl Exp $ */
2
3 /*
4 * Copyright (c) 2003 Clifford Wright. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 /*
31 * Broadcom BCM440x 10/100 ethernet (broadcom.com)
32 * SiliconBackplane is technology from Sonics, Inc.(sonicsinc.com)
33 *
34 * Cliff Wright cliff (at) snipe444.org
35 */
36
37 #include <sys/cdefs.h>
38
39 #include "bpfilter.h"
40 #include "vlan.h"
41 #include "rnd.h"
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/callout.h>
46 #include <sys/sockio.h>
47 #include <sys/mbuf.h>
48 #include <sys/malloc.h>
49 #include <sys/kernel.h>
50 #include <sys/device.h>
51 #include <sys/socket.h>
52
53 #include <net/if.h>
54 #include <net/if_dl.h>
55 #include <net/if_media.h>
56 #include <net/if_ether.h>
57
58 #if NBPFILTER > 0
59 #include <net/bpf.h>
60 #endif
61 #if NRND > 0
62 #include <sys/rnd.h>
63 #endif
64
65 #include <dev/pci/pcireg.h>
66 #include <dev/pci/pcivar.h>
67 #include <dev/pci/pcidevs.h>
68
69 #include <dev/mii/mii.h>
70 #include <dev/mii/miivar.h>
71 #include <dev/mii/miidevs.h>
72 #include <dev/mii/brgphyreg.h>
73
74 #include <dev/pci/if_bcereg.h>
75
76 #include <uvm/uvm_extern.h>
77
78 /* transmit buffer max frags allowed */
79 #define BCE_NTXFRAGS 16
80
81 /* ring descriptor */
82 struct bce_dma_slot {
83 u_int32_t ctrl;
84 u_int32_t addr;
85 };
86 #define CTRL_BC_MASK 0x1fff /* buffer byte count */
87 #define CTRL_EOT 0x10000000 /* end of descriptor table */
88 #define CTRL_IOC 0x20000000 /* interrupt on completion */
89 #define CTRL_EOF 0x40000000 /* end of frame */
90 #define CTRL_SOF 0x80000000 /* start of frame */
91
92 /* Packet status is returned in a pre-packet header */
93 struct rx_pph {
94 u_int16_t len;
95 u_int16_t flags;
96 u_int16_t pad[12];
97 };
98
99 /* packet status flags bits */
100 #define RXF_NO 0x8 /* odd number of nibbles */
101 #define RXF_RXER 0x4 /* receive symbol error */
102 #define RXF_CRC 0x2 /* crc error */
103 #define RXF_OV 0x1 /* fifo overflow */
104
105 /* number of descriptors used in a ring */
106 #define BCE_NRXDESC 128
107 #define BCE_NTXDESC 128
108
109 /*
110 * Mbuf pointers. We need these to keep track of the virtual addresses
111 * of our mbuf chains since we can only convert from physical to virtual,
112 * not the other way around.
113 */
114 struct bce_chain_data {
115 struct mbuf *bce_tx_chain[BCE_NTXDESC];
116 struct mbuf *bce_rx_chain[BCE_NRXDESC];
117 bus_dmamap_t bce_tx_map[BCE_NTXDESC];
118 bus_dmamap_t bce_rx_map[BCE_NRXDESC];
119 };
120
121 #define BCE_TIMEOUT 100 /* # 10us for mii read/write */
122
123 struct bce_softc {
124 struct device bce_dev;
125 bus_space_tag_t bce_btag;
126 bus_space_handle_t bce_bhandle;
127 bus_dma_tag_t bce_dmatag;
128 struct ethercom ethercom; /* interface info */
129 void *bce_intrhand;
130 struct pci_attach_args bce_pa;
131 struct mii_data bce_mii;
132 u_int32_t bce_phy; /* eeprom indicated phy */
133 struct ifmedia bce_ifmedia; /* media info *//* Check */
134 u_int8_t enaddr[ETHER_ADDR_LEN];
135 struct bce_dma_slot *bce_rx_ring; /* receive ring */
136 struct bce_dma_slot *bce_tx_ring; /* transmit ring */
137 struct bce_chain_data bce_cdata; /* mbufs */
138 bus_dmamap_t bce_ring_map;
139 u_int32_t bce_intmask; /* current intr mask */
140 u_int32_t bce_rxin; /* last rx descriptor seen */
141 u_int32_t bce_txin; /* last tx descriptor seen */
142 int bce_txsfree; /* no. tx slots available */
143 int bce_txsnext; /* next available tx slot */
144 callout_t bce_timeout;
145 #if NRND > 0
146 rndsource_element_t rnd_source;
147 #endif
148 };
149
150 /* for ring descriptors */
151 #define BCE_RXBUF_LEN (MCLBYTES - 4)
152 #define BCE_INIT_RXDESC(sc, x) \
153 do { \
154 struct bce_dma_slot *__bced = &sc->bce_rx_ring[x]; \
155 \
156 *mtod(sc->bce_cdata.bce_rx_chain[x], u_int32_t *) = 0; \
157 __bced->addr = \
158 htole32(sc->bce_cdata.bce_rx_map[x]->dm_segs[0].ds_addr \
159 + 0x40000000); \
160 if (x != (BCE_NRXDESC - 1)) \
161 __bced->ctrl = htole32(BCE_RXBUF_LEN); \
162 else \
163 __bced->ctrl = htole32(BCE_RXBUF_LEN | CTRL_EOT); \
164 bus_dmamap_sync(sc->bce_dmatag, sc->bce_ring_map, \
165 sizeof(struct bce_dma_slot) * x, \
166 sizeof(struct bce_dma_slot), \
167 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
168 } while (/* CONSTCOND */ 0)
169
170 static int bce_probe(struct device *, struct cfdata *, void *);
171 static void bce_attach(struct device *, struct device *, void *);
172 static int bce_ioctl(struct ifnet *, u_long, void *);
173 static void bce_start(struct ifnet *);
174 static void bce_watchdog(struct ifnet *);
175 static int bce_intr(void *);
176 static void bce_rxintr(struct bce_softc *);
177 static void bce_txintr(struct bce_softc *);
178 static int bce_init(struct ifnet *);
179 static void bce_add_mac(struct bce_softc *, u_int8_t *, unsigned long);
180 static int bce_add_rxbuf(struct bce_softc *, int);
181 static void bce_rxdrain(struct bce_softc *);
182 static void bce_stop(struct ifnet *, int);
183 static void bce_reset(struct bce_softc *);
184 static void bce_set_filter(struct ifnet *);
185 static int bce_mii_read(struct device *, int, int);
186 static void bce_mii_write(struct device *, int, int, int);
187 static void bce_statchg(struct device *);
188 static int bce_mediachange(struct ifnet *);
189 static void bce_mediastatus(struct ifnet *, struct ifmediareq *);
190 static void bce_tick(void *);
191
192 #define BCE_DEBUG
193 #ifdef BCE_DEBUG
194 #define DPRINTF(x) do { \
195 if (bcedebug) \
196 printf x; \
197 } while (/* CONSTCOND */ 0)
198 #define DPRINTFN(n,x) do { \
199 if (bcedebug >= (n)) \
200 printf x; \
201 } while (/* CONSTCOND */ 0)
202 int bcedebug = 0;
203 #else
204 #define DPRINTF(x)
205 #define DPRINTFN(n,x)
206 #endif
207
208 #if __NetBSD_Version__ >= 106080000
209 CFATTACH_DECL(bce, sizeof(struct bce_softc),
210 bce_probe, bce_attach, NULL, NULL);
211 #else
212 struct cfattach bce_ca = {
213 sizeof(struct bce_softc), bce_probe, bce_attach
214 };
215 #endif
216
217 #if __NetBSD_Version__ >= 106120000
218 #define APRINT_ERROR aprint_error
219 #define APRINT_NORMAL aprint_normal
220 #else
221 #define APRINT_ERROR printf
222 #define APRINT_NORMAL printf
223 #endif
224
225
226 static const struct bce_product {
227 pci_vendor_id_t bp_vendor;
228 pci_product_id_t bp_product;
229 const char *bp_name;
230 } bce_products[] = {
231 {
232 PCI_VENDOR_BROADCOM,
233 PCI_PRODUCT_BROADCOM_BCM4401,
234 "Broadcom BCM4401 10/100 Ethernet"
235 },
236 {
237 PCI_VENDOR_BROADCOM,
238 PCI_PRODUCT_BROADCOM_BCM4401_B0,
239 "Broadcom BCM4401-B0 10/100 Ethernet"
240 },
241 {
242
243 0,
244 0,
245 NULL
246 },
247 };
248
249 static const struct bce_product *
250 bce_lookup(const struct pci_attach_args * pa)
251 {
252 const struct bce_product *bp;
253
254 for (bp = bce_products; bp->bp_name != NULL; bp++) {
255 if (PCI_VENDOR(pa->pa_id) == bp->bp_vendor &&
256 PCI_PRODUCT(pa->pa_id) == bp->bp_product)
257 return (bp);
258 }
259
260 return (NULL);
261 }
262
263 /*
264 * Probe for a Broadcom chip. Check the PCI vendor and device IDs
265 * against drivers product list, and return its name if a match is found.
266 */
267 static int
268 bce_probe(struct device *parent, struct cfdata *match,
269 void *aux)
270 {
271 struct pci_attach_args *pa = (struct pci_attach_args *) aux;
272
273 if (bce_lookup(pa) != NULL)
274 return (1);
275
276 return (0);
277 }
278
279 static void
280 bce_attach(struct device *parent, struct device *self, void *aux)
281 {
282 struct bce_softc *sc = (struct bce_softc *) self;
283 struct pci_attach_args *pa = aux;
284 const struct bce_product *bp;
285 pci_chipset_tag_t pc = pa->pa_pc;
286 pci_intr_handle_t ih;
287 const char *intrstr = NULL;
288 void * kva;
289 bus_dma_segment_t seg;
290 int rseg;
291 u_int32_t command;
292 struct ifnet *ifp;
293 pcireg_t memtype;
294 bus_addr_t memaddr;
295 bus_size_t memsize;
296 int pmreg;
297 pcireg_t pmode;
298 int error;
299 int i;
300
301 bp = bce_lookup(pa);
302 KASSERT(bp != NULL);
303
304 sc->bce_pa = *pa;
305
306 /* BCM440x can only address 30 bits (1GB) */
307 if (bus_dmatag_subregion(pa->pa_dmat, 0, (1 << 30),
308 &(sc->bce_dmatag), BUS_DMA_NOWAIT) != 0)
309 {
310 APRINT_ERROR("WARNING: %s failed to restrict dma range,"
311 " falling back to parent bus dma range\n",
312 sc->bce_dev.dv_xname);
313 sc->bce_dmatag = pa->pa_dmat;
314 }
315
316 #if __NetBSD_Version__ >= 106120000
317 aprint_naive(": Ethernet controller\n");
318 #endif
319 APRINT_NORMAL(": %s\n", bp->bp_name);
320
321 /*
322 * Map control/status registers.
323 */
324 command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
325 command |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
326 pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command);
327 command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
328
329 if (!(command & PCI_COMMAND_MEM_ENABLE)) {
330 APRINT_ERROR("%s: failed to enable memory mapping!\n",
331 sc->bce_dev.dv_xname);
332 return;
333 }
334 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BCE_PCI_BAR0);
335 switch (memtype) {
336 case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
337 case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
338 if (pci_mapreg_map(pa, BCE_PCI_BAR0, memtype, 0, &sc->bce_btag,
339 &sc->bce_bhandle, &memaddr, &memsize) == 0)
340 break;
341 default:
342 APRINT_ERROR("%s: unable to find mem space\n",
343 sc->bce_dev.dv_xname);
344 return;
345 }
346
347 /* Get it out of power save mode if needed. */
348 if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
349 pmode = pci_conf_read(pc, pa->pa_tag, pmreg + 4) & 0x3;
350 if (pmode == 3) {
351 /*
352 * The card has lost all configuration data in
353 * this state, so punt.
354 */
355 printf("%s: unable to wake up from power state D3\n",
356 sc->bce_dev.dv_xname);
357 return;
358 }
359 if (pmode != 0) {
360 printf("%s: waking up from power state D%d\n",
361 sc->bce_dev.dv_xname, pmode);
362 pci_conf_write(pc, pa->pa_tag, pmreg + 4, 0);
363 }
364 }
365 if (pci_intr_map(pa, &ih)) {
366 APRINT_ERROR("%s: couldn't map interrupt\n",
367 sc->bce_dev.dv_xname);
368 return;
369 }
370 intrstr = pci_intr_string(pc, ih);
371
372 sc->bce_intrhand = pci_intr_establish(pc, ih, IPL_NET, bce_intr, sc);
373
374 if (sc->bce_intrhand == NULL) {
375 APRINT_ERROR("%s: couldn't establish interrupt",
376 sc->bce_dev.dv_xname);
377 if (intrstr != NULL)
378 APRINT_NORMAL(" at %s", intrstr);
379 APRINT_NORMAL("\n");
380 return;
381 }
382 APRINT_NORMAL("%s: interrupting at %s\n",
383 sc->bce_dev.dv_xname, intrstr);
384
385 /* reset the chip */
386 bce_reset(sc);
387
388 /*
389 * Allocate DMA-safe memory for ring descriptors.
390 * The receive, and transmit rings can not share the same
391 * 4k space, however both are allocated at once here.
392 */
393 /*
394 * XXX PAGE_SIZE is wasteful; we only need 1KB + 1KB, but
395 * due to the limition above. ??
396 */
397 if ((error = bus_dmamem_alloc(sc->bce_dmatag,
398 2 * PAGE_SIZE, PAGE_SIZE, 2 * PAGE_SIZE,
399 &seg, 1, &rseg, BUS_DMA_NOWAIT))) {
400 printf("%s: unable to alloc space for ring descriptors, "
401 "error = %d\n", sc->bce_dev.dv_xname, error);
402 return;
403 }
404 /* map ring space to kernel */
405 if ((error = bus_dmamem_map(sc->bce_dmatag, &seg, rseg,
406 2 * PAGE_SIZE, &kva, BUS_DMA_NOWAIT))) {
407 printf("%s: unable to map DMA buffers, error = %d\n",
408 sc->bce_dev.dv_xname, error);
409 bus_dmamem_free(sc->bce_dmatag, &seg, rseg);
410 return;
411 }
412 /* create a dma map for the ring */
413 if ((error = bus_dmamap_create(sc->bce_dmatag,
414 2 * PAGE_SIZE, 1, 2 * PAGE_SIZE, 0, BUS_DMA_NOWAIT,
415 &sc->bce_ring_map))) {
416 printf("%s: unable to create ring DMA map, error = %d\n",
417 sc->bce_dev.dv_xname, error);
418 bus_dmamem_unmap(sc->bce_dmatag, kva, 2 * PAGE_SIZE);
419 bus_dmamem_free(sc->bce_dmatag, &seg, rseg);
420 return;
421 }
422 /* connect the ring space to the dma map */
423 if (bus_dmamap_load(sc->bce_dmatag, sc->bce_ring_map, kva,
424 2 * PAGE_SIZE, NULL, BUS_DMA_NOWAIT)) {
425 bus_dmamap_destroy(sc->bce_dmatag, sc->bce_ring_map);
426 bus_dmamem_unmap(sc->bce_dmatag, kva, 2 * PAGE_SIZE);
427 bus_dmamem_free(sc->bce_dmatag, &seg, rseg);
428 return;
429 }
430 /* save the ring space in softc */
431 sc->bce_rx_ring = (struct bce_dma_slot *) kva;
432 sc->bce_tx_ring = (struct bce_dma_slot *) ((char *)kva + PAGE_SIZE);
433
434 /* Create the transmit buffer DMA maps. */
435 for (i = 0; i < BCE_NTXDESC; i++) {
436 if ((error = bus_dmamap_create(sc->bce_dmatag, MCLBYTES,
437 BCE_NTXFRAGS, MCLBYTES, 0, 0, &sc->bce_cdata.bce_tx_map[i])) != 0) {
438 printf("%s: unable to create tx DMA map, error = %d\n",
439 sc->bce_dev.dv_xname, error);
440 }
441 sc->bce_cdata.bce_tx_chain[i] = NULL;
442 }
443
444 /* Create the receive buffer DMA maps. */
445 for (i = 0; i < BCE_NRXDESC; i++) {
446 if ((error = bus_dmamap_create(sc->bce_dmatag, MCLBYTES, 1,
447 MCLBYTES, 0, 0, &sc->bce_cdata.bce_rx_map[i])) != 0) {
448 printf("%s: unable to create rx DMA map, error = %d\n",
449 sc->bce_dev.dv_xname, error);
450 }
451 sc->bce_cdata.bce_rx_chain[i] = NULL;
452 }
453
454 /* Set up ifnet structure */
455 ifp = &sc->ethercom.ec_if;
456 strcpy(ifp->if_xname, sc->bce_dev.dv_xname);
457 ifp->if_softc = sc;
458 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
459 ifp->if_ioctl = bce_ioctl;
460 ifp->if_start = bce_start;
461 ifp->if_watchdog = bce_watchdog;
462 ifp->if_init = bce_init;
463 ifp->if_stop = bce_stop;
464 IFQ_SET_READY(&ifp->if_snd);
465
466 /* Initialize our media structures and probe the MII. */
467
468 sc->bce_mii.mii_ifp = ifp;
469 sc->bce_mii.mii_readreg = bce_mii_read;
470 sc->bce_mii.mii_writereg = bce_mii_write;
471 sc->bce_mii.mii_statchg = bce_statchg;
472 ifmedia_init(&sc->bce_mii.mii_media, 0, bce_mediachange,
473 bce_mediastatus);
474 mii_attach(&sc->bce_dev, &sc->bce_mii, 0xffffffff, MII_PHY_ANY,
475 MII_OFFSET_ANY, 0);
476 if (LIST_FIRST(&sc->bce_mii.mii_phys) == NULL) {
477 ifmedia_add(&sc->bce_mii.mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
478 ifmedia_set(&sc->bce_mii.mii_media, IFM_ETHER | IFM_NONE);
479 } else
480 ifmedia_set(&sc->bce_mii.mii_media, IFM_ETHER | IFM_AUTO);
481 /* get the phy */
482 sc->bce_phy = bus_space_read_1(sc->bce_btag, sc->bce_bhandle,
483 BCE_MAGIC_PHY) & 0x1f;
484 /*
485 * Enable activity led.
486 * XXX This should be in a phy driver, but not currently.
487 */
488 bce_mii_write((struct device *) sc, 1, 26, /* MAGIC */
489 bce_mii_read((struct device *) sc, 1, 26) & 0x7fff); /* MAGIC */
490 /* enable traffic meter led mode */
491 bce_mii_write((struct device *) sc, 1, 27, /* MAGIC */
492 bce_mii_read((struct device *) sc, 1, 27) | (1 << 6)); /* MAGIC */
493
494
495 /* Attach the interface */
496 if_attach(ifp);
497 sc->enaddr[0] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle,
498 BCE_MAGIC_ENET0);
499 sc->enaddr[1] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle,
500 BCE_MAGIC_ENET1);
501 sc->enaddr[2] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle,
502 BCE_MAGIC_ENET2);
503 sc->enaddr[3] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle,
504 BCE_MAGIC_ENET3);
505 sc->enaddr[4] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle,
506 BCE_MAGIC_ENET4);
507 sc->enaddr[5] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle,
508 BCE_MAGIC_ENET5);
509 printf("%s: Ethernet address %s\n", sc->bce_dev.dv_xname,
510 ether_sprintf(sc->enaddr));
511 ether_ifattach(ifp, sc->enaddr);
512 #if NRND > 0
513 rnd_attach_source(&sc->rnd_source, sc->bce_dev.dv_xname,
514 RND_TYPE_NET, 0);
515 #endif
516 callout_init(&sc->bce_timeout, 0);
517 }
518
519 /* handle media, and ethernet requests */
520 static int
521 bce_ioctl(struct ifnet *ifp, u_long cmd, void *data)
522 {
523 struct bce_softc *sc = ifp->if_softc;
524 struct ifreq *ifr = (struct ifreq *) data;
525 int s, error;
526
527 s = splnet();
528 switch (cmd) {
529 case SIOCSIFMEDIA:
530 case SIOCGIFMEDIA:
531 error = ifmedia_ioctl(ifp, ifr, &sc->bce_mii.mii_media, cmd);
532 break;
533 default:
534 error = ether_ioctl(ifp, cmd, data);
535 if (error == ENETRESET) {
536 /* change multicast list */
537 error = 0;
538 }
539 break;
540 }
541
542 /* Try to get more packets going. */
543 bce_start(ifp);
544
545 splx(s);
546 return error;
547 }
548
549 /* Start packet transmission on the interface. */
550 static void
551 bce_start(struct ifnet *ifp)
552 {
553 struct bce_softc *sc = ifp->if_softc;
554 struct mbuf *m0;
555 bus_dmamap_t dmamap;
556 int txstart;
557 int txsfree;
558 int newpkts = 0;
559 int error;
560
561 /*
562 * do not start another if currently transmitting, and more
563 * descriptors(tx slots) are needed for next packet.
564 */
565 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
566 return;
567
568 /* determine number of descriptors available */
569 if (sc->bce_txsnext >= sc->bce_txin)
570 txsfree = BCE_NTXDESC - 1 + sc->bce_txin - sc->bce_txsnext;
571 else
572 txsfree = sc->bce_txin - sc->bce_txsnext - 1;
573
574 /*
575 * Loop through the send queue, setting up transmit descriptors
576 * until we drain the queue, or use up all available transmit
577 * descriptors.
578 */
579 while (txsfree > 0) {
580 int seg;
581
582 /* Grab a packet off the queue. */
583 IFQ_POLL(&ifp->if_snd, m0);
584 if (m0 == NULL)
585 break;
586
587 /* get the transmit slot dma map */
588 dmamap = sc->bce_cdata.bce_tx_map[sc->bce_txsnext];
589
590 /*
591 * Load the DMA map. If this fails, the packet either
592 * didn't fit in the alloted number of segments, or we
593 * were short on resources. If the packet will not fit,
594 * it will be dropped. If short on resources, it will
595 * be tried again later.
596 */
597 error = bus_dmamap_load_mbuf(sc->bce_dmatag, dmamap, m0,
598 BUS_DMA_WRITE | BUS_DMA_NOWAIT);
599 if (error == EFBIG) {
600 printf("%s: Tx packet consumes too many DMA segments, "
601 "dropping...\n", sc->bce_dev.dv_xname);
602 IFQ_DEQUEUE(&ifp->if_snd, m0);
603 m_freem(m0);
604 ifp->if_oerrors++;
605 continue;
606 } else if (error) {
607 /* short on resources, come back later */
608 printf("%s: unable to load Tx buffer, error = %d\n",
609 sc->bce_dev.dv_xname, error);
610 break;
611 }
612 /* If not enough descriptors available, try again later */
613 if (dmamap->dm_nsegs > txsfree) {
614 ifp->if_flags |= IFF_OACTIVE;
615 bus_dmamap_unload(sc->bce_dmatag, dmamap);
616 break;
617 }
618 /* WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET. */
619
620 /* So take it off the queue */
621 IFQ_DEQUEUE(&ifp->if_snd, m0);
622
623 /* save the pointer so it can be freed later */
624 sc->bce_cdata.bce_tx_chain[sc->bce_txsnext] = m0;
625
626 /* Sync the data DMA map. */
627 bus_dmamap_sync(sc->bce_dmatag, dmamap, 0, dmamap->dm_mapsize,
628 BUS_DMASYNC_PREWRITE);
629
630 /* Initialize the transmit descriptor(s). */
631 txstart = sc->bce_txsnext;
632 for (seg = 0; seg < dmamap->dm_nsegs; seg++) {
633 u_int32_t ctrl;
634
635 ctrl = dmamap->dm_segs[seg].ds_len & CTRL_BC_MASK;
636 if (seg == 0)
637 ctrl |= CTRL_SOF;
638 if (seg == dmamap->dm_nsegs - 1)
639 ctrl |= CTRL_EOF;
640 if (sc->bce_txsnext == BCE_NTXDESC - 1)
641 ctrl |= CTRL_EOT;
642 ctrl |= CTRL_IOC;
643 sc->bce_tx_ring[sc->bce_txsnext].ctrl = htole32(ctrl);
644 sc->bce_tx_ring[sc->bce_txsnext].addr =
645 htole32(dmamap->dm_segs[seg].ds_addr + 0x40000000); /* MAGIC */
646 if (sc->bce_txsnext + 1 > BCE_NTXDESC - 1)
647 sc->bce_txsnext = 0;
648 else
649 sc->bce_txsnext++;
650 txsfree--;
651 }
652 /* sync descriptors being used */
653 bus_dmamap_sync(sc->bce_dmatag, sc->bce_ring_map,
654 sizeof(struct bce_dma_slot) * txstart + PAGE_SIZE,
655 sizeof(struct bce_dma_slot) * dmamap->dm_nsegs,
656 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
657
658 /* Give the packet to the chip. */
659 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_DMA_DPTR,
660 sc->bce_txsnext * sizeof(struct bce_dma_slot));
661
662 newpkts++;
663
664 #if NBPFILTER > 0
665 /* Pass the packet to any BPF listeners. */
666 if (ifp->if_bpf)
667 bpf_mtap(ifp->if_bpf, m0);
668 #endif /* NBPFILTER > 0 */
669 }
670 if (txsfree == 0) {
671 /* No more slots left; notify upper layer. */
672 ifp->if_flags |= IFF_OACTIVE;
673 }
674 if (newpkts) {
675 /* Set a watchdog timer in case the chip flakes out. */
676 ifp->if_timer = 5;
677 }
678 }
679
680 /* Watchdog timer handler. */
681 static void
682 bce_watchdog(struct ifnet *ifp)
683 {
684 struct bce_softc *sc = ifp->if_softc;
685
686 printf("%s: device timeout\n", sc->bce_dev.dv_xname);
687 ifp->if_oerrors++;
688
689 (void) bce_init(ifp);
690
691 /* Try to get more packets going. */
692 bce_start(ifp);
693 }
694
695 int
696 bce_intr(void *xsc)
697 {
698 struct bce_softc *sc;
699 struct ifnet *ifp;
700 u_int32_t intstatus;
701 int wantinit;
702 int handled = 0;
703
704 sc = xsc;
705 ifp = &sc->ethercom.ec_if;
706
707
708 for (wantinit = 0; wantinit == 0;) {
709 intstatus = bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
710 BCE_INT_STS);
711
712 /* ignore if not ours, or unsolicited interrupts */
713 intstatus &= sc->bce_intmask;
714 if (intstatus == 0)
715 break;
716
717 handled = 1;
718
719 /* Ack interrupt */
720 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_INT_STS,
721 intstatus);
722
723 /* Receive interrupts. */
724 if (intstatus & I_RI)
725 bce_rxintr(sc);
726 /* Transmit interrupts. */
727 if (intstatus & I_XI)
728 bce_txintr(sc);
729 /* Error interrupts */
730 if (intstatus & ~(I_RI | I_XI)) {
731 if (intstatus & I_XU)
732 printf("%s: transmit fifo underflow\n",
733 sc->bce_dev.dv_xname);
734 if (intstatus & I_RO) {
735 printf("%s: receive fifo overflow\n",
736 sc->bce_dev.dv_xname);
737 ifp->if_ierrors++;
738 }
739 if (intstatus & I_RU)
740 printf("%s: receive descriptor underflow\n",
741 sc->bce_dev.dv_xname);
742 if (intstatus & I_DE)
743 printf("%s: descriptor protocol error\n",
744 sc->bce_dev.dv_xname);
745 if (intstatus & I_PD)
746 printf("%s: data error\n",
747 sc->bce_dev.dv_xname);
748 if (intstatus & I_PC)
749 printf("%s: descriptor error\n",
750 sc->bce_dev.dv_xname);
751 if (intstatus & I_TO)
752 printf("%s: general purpose timeout\n",
753 sc->bce_dev.dv_xname);
754 wantinit = 1;
755 }
756 }
757
758 if (handled) {
759 if (wantinit)
760 bce_init(ifp);
761 #if NRND > 0
762 if (RND_ENABLED(&sc->rnd_source))
763 rnd_add_uint32(&sc->rnd_source, intstatus);
764 #endif
765 /* Try to get more packets going. */
766 bce_start(ifp);
767 }
768 return (handled);
769 }
770
771 /* Receive interrupt handler */
772 void
773 bce_rxintr(struct bce_softc *sc)
774 {
775 struct ifnet *ifp = &sc->ethercom.ec_if;
776 struct rx_pph *pph;
777 struct mbuf *m;
778 int curr;
779 int len;
780 int i;
781
782 /* get pointer to active receive slot */
783 curr = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_DMA_RXSTATUS)
784 & RS_CD_MASK;
785 curr = curr / sizeof(struct bce_dma_slot);
786 if (curr >= BCE_NRXDESC)
787 curr = BCE_NRXDESC - 1;
788
789 /* process packets up to but not current packet being worked on */
790 for (i = sc->bce_rxin; i != curr;
791 i + 1 > BCE_NRXDESC - 1 ? i = 0 : i++) {
792 /* complete any post dma memory ops on packet */
793 bus_dmamap_sync(sc->bce_dmatag, sc->bce_cdata.bce_rx_map[i], 0,
794 sc->bce_cdata.bce_rx_map[i]->dm_mapsize,
795 BUS_DMASYNC_POSTREAD);
796
797 /*
798 * If the packet had an error, simply recycle the buffer,
799 * resetting the len, and flags.
800 */
801 pph = mtod(sc->bce_cdata.bce_rx_chain[i], struct rx_pph *);
802 if (pph->flags & (RXF_NO | RXF_RXER | RXF_CRC | RXF_OV)) {
803 ifp->if_ierrors++;
804 pph->len = 0;
805 pph->flags = 0;
806 continue;
807 }
808 /* receive the packet */
809 len = pph->len;
810 if (len == 0)
811 continue; /* no packet if empty */
812 pph->len = 0;
813 pph->flags = 0;
814 /* bump past pre header to packet */
815 sc->bce_cdata.bce_rx_chain[i]->m_data += 30; /* MAGIC */
816
817 /*
818 * The chip includes the CRC with every packet. Trim
819 * it off here.
820 */
821 len -= ETHER_CRC_LEN;
822
823 /*
824 * If the packet is small enough to fit in a
825 * single header mbuf, allocate one and copy
826 * the data into it. This greatly reduces
827 * memory consumption when receiving lots
828 * of small packets.
829 *
830 * Otherwise, add a new buffer to the receive
831 * chain. If this fails, drop the packet and
832 * recycle the old buffer.
833 */
834 if (len <= (MHLEN - 2)) {
835 MGETHDR(m, M_DONTWAIT, MT_DATA);
836 if (m == NULL)
837 goto dropit;
838 m->m_data += 2;
839 memcpy(mtod(m, void *),
840 mtod(sc->bce_cdata.bce_rx_chain[i], void *), len);
841 sc->bce_cdata.bce_rx_chain[i]->m_data -= 30; /* MAGIC */
842 } else {
843 m = sc->bce_cdata.bce_rx_chain[i];
844 if (bce_add_rxbuf(sc, i) != 0) {
845 dropit:
846 ifp->if_ierrors++;
847 /* continue to use old buffer */
848 sc->bce_cdata.bce_rx_chain[i]->m_data -= 30;
849 bus_dmamap_sync(sc->bce_dmatag,
850 sc->bce_cdata.bce_rx_map[i], 0,
851 sc->bce_cdata.bce_rx_map[i]->dm_mapsize,
852 BUS_DMASYNC_PREREAD);
853 continue;
854 }
855 }
856
857 m->m_pkthdr.rcvif = ifp;
858 m->m_pkthdr.len = m->m_len = len;
859 ifp->if_ipackets++;
860
861 #if NBPFILTER > 0
862 /*
863 * Pass this up to any BPF listeners, but only
864 * pass it up the stack if it's for us.
865 */
866 if (ifp->if_bpf)
867 bpf_mtap(ifp->if_bpf, m);
868 #endif /* NBPFILTER > 0 */
869
870 /* Pass it on. */
871 (*ifp->if_input) (ifp, m);
872
873 /* re-check current in case it changed */
874 curr = (bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
875 BCE_DMA_RXSTATUS) & RS_CD_MASK) /
876 sizeof(struct bce_dma_slot);
877 if (curr >= BCE_NRXDESC)
878 curr = BCE_NRXDESC - 1;
879 }
880 sc->bce_rxin = curr;
881 }
882
883 /* Transmit interrupt handler */
884 void
885 bce_txintr(struct bce_softc *sc)
886 {
887 struct ifnet *ifp = &sc->ethercom.ec_if;
888 int curr;
889 int i;
890
891 ifp->if_flags &= ~IFF_OACTIVE;
892
893 /*
894 * Go through the Tx list and free mbufs for those
895 * frames which have been transmitted.
896 */
897 curr = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_DMA_TXSTATUS) &
898 RS_CD_MASK;
899 curr = curr / sizeof(struct bce_dma_slot);
900 if (curr >= BCE_NTXDESC)
901 curr = BCE_NTXDESC - 1;
902 for (i = sc->bce_txin; i != curr;
903 i + 1 > BCE_NTXDESC - 1 ? i = 0 : i++) {
904 /* do any post dma memory ops on transmit data */
905 if (sc->bce_cdata.bce_tx_chain[i] == NULL)
906 continue;
907 bus_dmamap_sync(sc->bce_dmatag, sc->bce_cdata.bce_tx_map[i], 0,
908 sc->bce_cdata.bce_tx_map[i]->dm_mapsize,
909 BUS_DMASYNC_POSTWRITE);
910 bus_dmamap_unload(sc->bce_dmatag, sc->bce_cdata.bce_tx_map[i]);
911 m_freem(sc->bce_cdata.bce_tx_chain[i]);
912 sc->bce_cdata.bce_tx_chain[i] = NULL;
913 ifp->if_opackets++;
914 }
915 sc->bce_txin = curr;
916
917 /*
918 * If there are no more pending transmissions, cancel the watchdog
919 * timer
920 */
921 if (sc->bce_txsnext == sc->bce_txin)
922 ifp->if_timer = 0;
923 }
924
925 /* initialize the interface */
926 static int
927 bce_init(struct ifnet *ifp)
928 {
929 struct bce_softc *sc = ifp->if_softc;
930 u_int32_t reg_win;
931 int error;
932 int i;
933
934 /* Cancel any pending I/O. */
935 bce_stop(ifp, 0);
936
937 /* enable pci inerrupts, bursts, and prefetch */
938
939 /* remap the pci registers to the Sonics config registers */
940
941 /* save the current map, so it can be restored */
942 reg_win = pci_conf_read(sc->bce_pa.pa_pc, sc->bce_pa.pa_tag,
943 BCE_REG_WIN);
944
945 /* set register window to Sonics registers */
946 pci_conf_write(sc->bce_pa.pa_pc, sc->bce_pa.pa_tag, BCE_REG_WIN,
947 BCE_SONICS_WIN);
948
949 /* enable SB to PCI interrupt */
950 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_SBINTVEC,
951 bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_SBINTVEC) |
952 SBIV_ENET0);
953
954 /* enable prefetch and bursts for sonics-to-pci translation 2 */
955 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_SPCI_TR2,
956 bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_SPCI_TR2) |
957 SBTOPCI_PREF | SBTOPCI_BURST);
958
959 /* restore to ethernet register space */
960 pci_conf_write(sc->bce_pa.pa_pc, sc->bce_pa.pa_tag, BCE_REG_WIN,
961 reg_win);
962
963 /* Reset the chip to a known state. */
964 bce_reset(sc);
965
966 /* Initialize transmit descriptors */
967 memset(sc->bce_tx_ring, 0, BCE_NTXDESC * sizeof(struct bce_dma_slot));
968 sc->bce_txsnext = 0;
969 sc->bce_txin = 0;
970
971 /* enable crc32 generation */
972 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_MACCTL,
973 bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_MACCTL) |
974 BCE_EMC_CG);
975
976 /* setup DMA interrupt control */
977 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_DMAI_CTL, 1 << 24); /* MAGIC */
978
979 /* setup packet filter */
980 bce_set_filter(ifp);
981
982 /* set max frame length, account for possible vlan tag */
983 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_RX_MAX,
984 ETHER_MAX_LEN + 32);
985 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_TX_MAX,
986 ETHER_MAX_LEN + 32);
987
988 /* set tx watermark */
989 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_TX_WATER, 56);
990
991 /* enable transmit */
992 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_DMA_TXCTL, XC_XE);
993 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_DMA_TXADDR,
994 sc->bce_ring_map->dm_segs[0].ds_addr + PAGE_SIZE + 0x40000000); /* MAGIC */
995
996 /*
997 * Give the receive ring to the chip, and
998 * start the receive DMA engine.
999 */
1000 sc->bce_rxin = 0;
1001
1002 /* clear the rx descriptor ring */
1003 memset(sc->bce_rx_ring, 0, BCE_NRXDESC * sizeof(struct bce_dma_slot));
1004 /* enable receive */
1005 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_DMA_RXCTL,
1006 30 << 1 | 1); /* MAGIC */
1007 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_DMA_RXADDR,
1008 sc->bce_ring_map->dm_segs[0].ds_addr + 0x40000000); /* MAGIC */
1009
1010 /* Initalize receive descriptors */
1011 for (i = 0; i < BCE_NRXDESC; i++) {
1012 if (sc->bce_cdata.bce_rx_chain[i] == NULL) {
1013 if ((error = bce_add_rxbuf(sc, i)) != 0) {
1014 printf("%s: unable to allocate or map rx(%d) "
1015 "mbuf, error = %d\n", sc->bce_dev.dv_xname,
1016 i, error);
1017 bce_rxdrain(sc);
1018 return (error);
1019 }
1020 } else
1021 BCE_INIT_RXDESC(sc, i);
1022 }
1023
1024 /* Enable interrupts */
1025 sc->bce_intmask =
1026 I_XI | I_RI | I_XU | I_RO | I_RU | I_DE | I_PD | I_PC | I_TO;
1027 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_INT_MASK,
1028 sc->bce_intmask);
1029
1030 /* start the receive dma */
1031 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_DMA_RXDPTR,
1032 BCE_NRXDESC * sizeof(struct bce_dma_slot));
1033
1034 /* set media */
1035 mii_mediachg(&sc->bce_mii);
1036
1037 /* turn on the ethernet mac */
1038 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_ENET_CTL,
1039 bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
1040 BCE_ENET_CTL) | EC_EE);
1041
1042 /* start timer */
1043 callout_reset(&sc->bce_timeout, hz, bce_tick, sc);
1044
1045 /* mark as running, and no outputs active */
1046 ifp->if_flags |= IFF_RUNNING;
1047 ifp->if_flags &= ~IFF_OACTIVE;
1048
1049 return 0;
1050 }
1051
1052 /* add a mac address to packet filter */
1053 void
1054 bce_add_mac(struct bce_softc *sc, u_int8_t *mac, u_long idx)
1055 {
1056 int i;
1057 u_int32_t rval;
1058
1059 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_FILT_LOW,
1060 mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]);
1061 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_FILT_HI,
1062 mac[0] << 8 | mac[1] | 0x10000); /* MAGIC */
1063 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_FILT_CTL,
1064 idx << 16 | 8); /* MAGIC */
1065 /* wait for write to complete */
1066 for (i = 0; i < 100; i++) {
1067 rval = bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
1068 BCE_FILT_CTL);
1069 if (!(rval & 0x80000000)) /* MAGIC */
1070 break;
1071 delay(10);
1072 }
1073 if (i == 100) {
1074 printf("%s: timed out writing pkt filter ctl\n",
1075 sc->bce_dev.dv_xname);
1076 }
1077 }
1078
1079 /* Add a receive buffer to the indiciated descriptor. */
1080 static int
1081 bce_add_rxbuf(struct bce_softc *sc, int idx)
1082 {
1083 struct mbuf *m;
1084 int error;
1085
1086 MGETHDR(m, M_DONTWAIT, MT_DATA);
1087 if (m == NULL)
1088 return (ENOBUFS);
1089
1090 MCLGET(m, M_DONTWAIT);
1091 if ((m->m_flags & M_EXT) == 0) {
1092 m_freem(m);
1093 return (ENOBUFS);
1094 }
1095 if (sc->bce_cdata.bce_rx_chain[idx] != NULL)
1096 bus_dmamap_unload(sc->bce_dmatag,
1097 sc->bce_cdata.bce_rx_map[idx]);
1098
1099 sc->bce_cdata.bce_rx_chain[idx] = m;
1100
1101 error = bus_dmamap_load(sc->bce_dmatag, sc->bce_cdata.bce_rx_map[idx],
1102 m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
1103 BUS_DMA_READ | BUS_DMA_NOWAIT);
1104 if (error)
1105 return (error);
1106
1107 bus_dmamap_sync(sc->bce_dmatag, sc->bce_cdata.bce_rx_map[idx], 0,
1108 sc->bce_cdata.bce_rx_map[idx]->dm_mapsize, BUS_DMASYNC_PREREAD);
1109
1110 BCE_INIT_RXDESC(sc, idx);
1111
1112 return (0);
1113
1114 }
1115
1116 /* Drain the receive queue. */
1117 static void
1118 bce_rxdrain(struct bce_softc *sc)
1119 {
1120 int i;
1121
1122 for (i = 0; i < BCE_NRXDESC; i++) {
1123 if (sc->bce_cdata.bce_rx_chain[i] != NULL) {
1124 bus_dmamap_unload(sc->bce_dmatag,
1125 sc->bce_cdata.bce_rx_map[i]);
1126 m_freem(sc->bce_cdata.bce_rx_chain[i]);
1127 sc->bce_cdata.bce_rx_chain[i] = NULL;
1128 }
1129 }
1130 }
1131
1132 /* Stop transmission on the interface */
1133 static void
1134 bce_stop(struct ifnet *ifp, int disable)
1135 {
1136 struct bce_softc *sc = ifp->if_softc;
1137 int i;
1138 u_int32_t val;
1139
1140 /* Stop the 1 second timer */
1141 callout_stop(&sc->bce_timeout);
1142
1143 /* Down the MII. */
1144 mii_down(&sc->bce_mii);
1145
1146 /* Disable interrupts. */
1147 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_INT_MASK, 0);
1148 sc->bce_intmask = 0;
1149 delay(10);
1150
1151 /* Disable emac */
1152 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_ENET_CTL, EC_ED);
1153 for (i = 0; i < 200; i++) {
1154 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
1155 BCE_ENET_CTL);
1156 if (!(val & EC_ED))
1157 break;
1158 delay(10);
1159 }
1160
1161 /* Stop the DMA */
1162 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_DMA_RXCTL, 0);
1163 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_DMA_TXCTL, 0);
1164 delay(10);
1165
1166 /* Release any queued transmit buffers. */
1167 for (i = 0; i < BCE_NTXDESC; i++) {
1168 if (sc->bce_cdata.bce_tx_chain[i] != NULL) {
1169 bus_dmamap_unload(sc->bce_dmatag,
1170 sc->bce_cdata.bce_tx_map[i]);
1171 m_freem(sc->bce_cdata.bce_tx_chain[i]);
1172 sc->bce_cdata.bce_tx_chain[i] = NULL;
1173 }
1174 }
1175
1176 /* drain receive queue */
1177 if (disable)
1178 bce_rxdrain(sc);
1179
1180 /* Mark the interface down and cancel the watchdog timer. */
1181 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1182 ifp->if_timer = 0;
1183 }
1184
1185 /* reset the chip */
1186 static void
1187 bce_reset(struct bce_softc *sc)
1188 {
1189 u_int32_t val;
1190 u_int32_t sbval;
1191 int i;
1192
1193 /* if SB core is up */
1194 sbval = bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
1195 BCE_SBTMSTATELOW);
1196 if ((sbval & (SBTML_RESET | SBTML_REJ | SBTML_CLK)) == SBTML_CLK) {
1197 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_DMAI_CTL,
1198 0);
1199
1200 /* disable emac */
1201 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_ENET_CTL,
1202 EC_ED);
1203 for (i = 0; i < 200; i++) {
1204 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
1205 BCE_ENET_CTL);
1206 if (!(val & EC_ED))
1207 break;
1208 delay(10);
1209 }
1210 if (i == 200)
1211 printf("%s: timed out disabling ethernet mac\n",
1212 sc->bce_dev.dv_xname);
1213
1214 /* reset the dma engines */
1215 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_DMA_TXCTL, 0);
1216 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_DMA_RXSTATUS);
1217 /* if error on receive, wait to go idle */
1218 if (val & RS_ERROR) {
1219 for (i = 0; i < 100; i++) {
1220 val = bus_space_read_4(sc->bce_btag,
1221 sc->bce_bhandle, BCE_DMA_RXSTATUS);
1222 if (val & RS_DMA_IDLE)
1223 break;
1224 delay(10);
1225 }
1226 if (i == 100)
1227 printf("%s: receive dma did not go idle after"
1228 " error\n", sc->bce_dev.dv_xname);
1229 }
1230 bus_space_write_4(sc->bce_btag, sc->bce_bhandle,
1231 BCE_DMA_RXSTATUS, 0);
1232
1233 /* reset ethernet mac */
1234 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_ENET_CTL,
1235 EC_ES);
1236 for (i = 0; i < 200; i++) {
1237 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
1238 BCE_ENET_CTL);
1239 if (!(val & EC_ES))
1240 break;
1241 delay(10);
1242 }
1243 if (i == 200)
1244 printf("%s: timed out restting ethernet mac\n",
1245 sc->bce_dev.dv_xname);
1246 } else {
1247 u_int32_t reg_win;
1248
1249 /* remap the pci registers to the Sonics config registers */
1250
1251 /* save the current map, so it can be restored */
1252 reg_win = pci_conf_read(sc->bce_pa.pa_pc, sc->bce_pa.pa_tag,
1253 BCE_REG_WIN);
1254 /* set register window to Sonics registers */
1255 pci_conf_write(sc->bce_pa.pa_pc, sc->bce_pa.pa_tag,
1256 BCE_REG_WIN, BCE_SONICS_WIN);
1257
1258 /* enable SB to PCI interrupt */
1259 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_SBINTVEC,
1260 bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
1261 BCE_SBINTVEC) |
1262 SBIV_ENET0);
1263
1264 /* enable prefetch and bursts for sonics-to-pci translation 2 */
1265 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_SPCI_TR2,
1266 bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
1267 BCE_SPCI_TR2) |
1268 SBTOPCI_PREF | SBTOPCI_BURST);
1269
1270 /* restore to ethernet register space */
1271 pci_conf_write(sc->bce_pa.pa_pc, sc->bce_pa.pa_tag, BCE_REG_WIN,
1272 reg_win);
1273 }
1274
1275 /* disable SB core if not in reset */
1276 if (!(sbval & SBTML_RESET)) {
1277
1278 /* set the reject bit */
1279 bus_space_write_4(sc->bce_btag, sc->bce_bhandle,
1280 BCE_SBTMSTATELOW, SBTML_REJ | SBTML_CLK);
1281 for (i = 0; i < 200; i++) {
1282 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
1283 BCE_SBTMSTATELOW);
1284 if (val & SBTML_REJ)
1285 break;
1286 delay(1);
1287 }
1288 if (i == 200)
1289 printf("%s: while restting core, reject did not set\n",
1290 sc->bce_dev.dv_xname);
1291 /* wait until busy is clear */
1292 for (i = 0; i < 200; i++) {
1293 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
1294 BCE_SBTMSTATEHI);
1295 if (!(val & 0x4))
1296 break;
1297 delay(1);
1298 }
1299 if (i == 200)
1300 printf("%s: while restting core, busy did not clear\n",
1301 sc->bce_dev.dv_xname);
1302 /* set reset and reject while enabling the clocks */
1303 bus_space_write_4(sc->bce_btag, sc->bce_bhandle,
1304 BCE_SBTMSTATELOW,
1305 SBTML_FGC | SBTML_CLK | SBTML_REJ | SBTML_RESET);
1306 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
1307 BCE_SBTMSTATELOW);
1308 delay(10);
1309 bus_space_write_4(sc->bce_btag, sc->bce_bhandle,
1310 BCE_SBTMSTATELOW, SBTML_REJ | SBTML_RESET);
1311 delay(1);
1312 }
1313 /* enable clock */
1314 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_SBTMSTATELOW,
1315 SBTML_FGC | SBTML_CLK | SBTML_RESET);
1316 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_SBTMSTATELOW);
1317 delay(1);
1318
1319 /* clear any error bits that may be on */
1320 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_SBTMSTATEHI);
1321 if (val & 1)
1322 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_SBTMSTATEHI,
1323 0);
1324 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_SBIMSTATE);
1325 if (val & SBIM_MAGIC_ERRORBITS)
1326 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_SBIMSTATE,
1327 val & ~SBIM_MAGIC_ERRORBITS);
1328
1329 /* clear reset and allow it to propagate throughout the core */
1330 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_SBTMSTATELOW,
1331 SBTML_FGC | SBTML_CLK);
1332 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_SBTMSTATELOW);
1333 delay(1);
1334
1335 /* leave clock enabled */
1336 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_SBTMSTATELOW,
1337 SBTML_CLK);
1338 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_SBTMSTATELOW);
1339 delay(1);
1340
1341 /* initialize MDC preamble, frequency */
1342 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_MI_CTL, 0x8d); /* MAGIC */
1343
1344 /* enable phy, differs for internal, and external */
1345 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_DEVCTL);
1346 if (!(val & BCE_DC_IP)) {
1347 /* select external phy */
1348 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_ENET_CTL, EC_EP);
1349 } else if (val & BCE_DC_ER) { /* internal, clear reset bit if on */
1350 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_DEVCTL,
1351 val & ~BCE_DC_ER);
1352 delay(100);
1353 }
1354 }
1355
1356 /* Set up the receive filter. */
1357 void
1358 bce_set_filter(struct ifnet *ifp)
1359 {
1360 struct bce_softc *sc = ifp->if_softc;
1361
1362 if (ifp->if_flags & IFF_PROMISC) {
1363 ifp->if_flags |= IFF_ALLMULTI;
1364 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_RX_CTL,
1365 bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_RX_CTL)
1366 | ERC_PE);
1367 } else {
1368 ifp->if_flags &= ~IFF_ALLMULTI;
1369
1370 /* turn off promiscuous */
1371 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_RX_CTL,
1372 bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
1373 BCE_RX_CTL) & ~ERC_PE);
1374
1375 /* enable/disable broadcast */
1376 if (ifp->if_flags & IFF_BROADCAST)
1377 bus_space_write_4(sc->bce_btag, sc->bce_bhandle,
1378 BCE_RX_CTL, bus_space_read_4(sc->bce_btag,
1379 sc->bce_bhandle, BCE_RX_CTL) & ~ERC_DB);
1380 else
1381 bus_space_write_4(sc->bce_btag, sc->bce_bhandle,
1382 BCE_RX_CTL, bus_space_read_4(sc->bce_btag,
1383 sc->bce_bhandle, BCE_RX_CTL) | ERC_DB);
1384
1385 /* disable the filter */
1386 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_FILT_CTL,
1387 0);
1388
1389 /* add our own address */
1390 bce_add_mac(sc, sc->enaddr, 0);
1391
1392 /* for now accept all multicast */
1393 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_RX_CTL,
1394 bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_RX_CTL) |
1395 ERC_AM);
1396 ifp->if_flags |= IFF_ALLMULTI;
1397
1398 /* enable the filter */
1399 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_FILT_CTL,
1400 bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
1401 BCE_FILT_CTL) | 1);
1402 }
1403 }
1404
1405 /* Read a PHY register on the MII. */
1406 int
1407 bce_mii_read(struct device *self, int phy, int reg)
1408 {
1409 struct bce_softc *sc = (struct bce_softc *) self;
1410 int i;
1411 u_int32_t val;
1412
1413 /* clear mii_int */
1414 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_MI_STS, BCE_MIINTR);
1415
1416 /* Read the PHY register */
1417 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_MI_COMM,
1418 (MII_COMMAND_READ << 28) | (MII_COMMAND_START << 30) | /* MAGIC */
1419 (MII_COMMAND_ACK << 16) | BCE_MIPHY(phy) | BCE_MIREG(reg)); /* MAGIC */
1420
1421 for (i = 0; i < BCE_TIMEOUT; i++) {
1422 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_MI_STS);
1423 if (val & BCE_MIINTR)
1424 break;
1425 delay(10);
1426 }
1427 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_MI_COMM);
1428 if (i == BCE_TIMEOUT) {
1429 printf("%s: PHY read timed out reading phy %d, reg %d, val = "
1430 "0x%08x\n", sc->bce_dev.dv_xname, phy, reg, val);
1431 return (0);
1432 }
1433 return (val & BCE_MICOMM_DATA);
1434 }
1435
1436 /* Write a PHY register on the MII */
1437 void
1438 bce_mii_write(struct device *self, int phy, int reg, int val)
1439 {
1440 struct bce_softc *sc = (struct bce_softc *) self;
1441 int i;
1442 u_int32_t rval;
1443
1444 /* clear mii_int */
1445 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_MI_STS,
1446 BCE_MIINTR);
1447
1448 /* Write the PHY register */
1449 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_MI_COMM,
1450 (MII_COMMAND_WRITE << 28) | (MII_COMMAND_START << 30) | /* MAGIC */
1451 (MII_COMMAND_ACK << 16) | (val & BCE_MICOMM_DATA) | /* MAGIC */
1452 BCE_MIPHY(phy) | BCE_MIREG(reg));
1453
1454 /* wait for write to complete */
1455 for (i = 0; i < BCE_TIMEOUT; i++) {
1456 rval = bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
1457 BCE_MI_STS);
1458 if (rval & BCE_MIINTR)
1459 break;
1460 delay(10);
1461 }
1462 rval = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_MI_COMM);
1463 if (i == BCE_TIMEOUT) {
1464 printf("%s: PHY timed out writing phy %d, reg %d, val "
1465 "= 0x%08x\n", sc->bce_dev.dv_xname, phy, reg, val);
1466 }
1467 }
1468
1469 /* sync hardware duplex mode to software state */
1470 void
1471 bce_statchg(struct device *self)
1472 {
1473 struct bce_softc *sc = (struct bce_softc *) self;
1474 u_int32_t reg;
1475
1476 /* if needed, change register to match duplex mode */
1477 reg = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_TX_CTL);
1478 if (sc->bce_mii.mii_media_active & IFM_FDX && !(reg & EXC_FD))
1479 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_TX_CTL,
1480 reg | EXC_FD);
1481 else if (!(sc->bce_mii.mii_media_active & IFM_FDX) && reg & EXC_FD)
1482 bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_TX_CTL,
1483 reg & ~EXC_FD);
1484
1485 /*
1486 * Enable activity led.
1487 * XXX This should be in a phy driver, but not currently.
1488 */
1489 bce_mii_write((struct device *) sc, 1, 26, /* MAGIC */
1490 bce_mii_read((struct device *) sc, 1, 26) & 0x7fff); /* MAGIC */
1491 /* enable traffic meter led mode */
1492 bce_mii_write((struct device *) sc, 1, 26, /* MAGIC */
1493 bce_mii_read((struct device *) sc, 1, 27) | (1 << 6)); /* MAGIC */
1494 }
1495
1496 /* Set hardware to newly-selected media */
1497 int
1498 bce_mediachange(struct ifnet *ifp)
1499 {
1500 struct bce_softc *sc = ifp->if_softc;
1501
1502 if (ifp->if_flags & IFF_UP)
1503 mii_mediachg(&sc->bce_mii);
1504 return (0);
1505 }
1506
1507 /* Get the current interface media status */
1508 static void
1509 bce_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
1510 {
1511 struct bce_softc *sc = ifp->if_softc;
1512
1513 mii_pollstat(&sc->bce_mii);
1514 ifmr->ifm_active = sc->bce_mii.mii_media_active;
1515 ifmr->ifm_status = sc->bce_mii.mii_media_status;
1516 }
1517
1518 /* One second timer, checks link status */
1519 static void
1520 bce_tick(void *v)
1521 {
1522 struct bce_softc *sc = v;
1523
1524 /* Tick the MII. */
1525 mii_tick(&sc->bce_mii);
1526
1527 callout_reset(&sc->bce_timeout, hz, bce_tick, sc);
1528 }
1529