1 /* $NetBSD: dp83932.c,v 1.31 2009/09/02 14:58:38 tsutsui Exp $ */
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Device driver for the National Semiconductor DP83932
34 * Systems-Oriented Network Interface Controller (SONIC).
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: dp83932.c,v 1.31 2009/09/02 14:58:38 tsutsui Exp $");
42 #include <sys/param.h>
43 #include <sys/systm.h>
45 #include <sys/malloc.h>
46 #include <sys/kernel.h>
47 #include <sys/socket.h>
48 #include <sys/ioctl.h>
49 #include <sys/errno.h>
50 #include <sys/device.h>
52 #include <uvm/uvm_extern.h>
55 #include <net/if_dl.h>
56 #include <net/if_ether.h>
65 #include <dev/ic/dp83932reg.h>
66 #include <dev/ic/dp83932var.h>
68 static void sonic_start(struct ifnet
*);
69 static void sonic_watchdog(struct ifnet
*);
70 static int sonic_ioctl(struct ifnet
*, u_long
, void *);
71 static int sonic_init(struct ifnet
*);
72 static void sonic_stop(struct ifnet
*, int);
74 static bool sonic_shutdown(device_t
, int);
76 static void sonic_reset(struct sonic_softc
*);
77 static void sonic_rxdrain(struct sonic_softc
*);
78 static int sonic_add_rxbuf(struct sonic_softc
*, int);
79 static void sonic_set_filter(struct sonic_softc
*);
81 static uint16_t sonic_txintr(struct sonic_softc
*);
82 static void sonic_rxintr(struct sonic_softc
*);
84 int sonic_copy_small
= 0;
86 #define ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN)
91 * Attach a SONIC interface to the system.
94 sonic_attach(struct sonic_softc
*sc
, const uint8_t *enaddr
)
96 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
98 bus_dma_segment_t seg
;
103 * Allocate the control data structures, and create and load the
107 cdatasize
= sizeof(struct sonic_control_data32
);
109 cdatasize
= sizeof(struct sonic_control_data16
);
111 if ((error
= bus_dmamem_alloc(sc
->sc_dmat
, cdatasize
+ ETHER_PAD_LEN
,
112 PAGE_SIZE
, (64 * 1024), &seg
, 1, &rseg
,
113 BUS_DMA_NOWAIT
)) != 0) {
114 aprint_error_dev(sc
->sc_dev
,
115 "unable to allocate control data, error = %d\n", error
);
119 if ((error
= bus_dmamem_map(sc
->sc_dmat
, &seg
, rseg
,
120 cdatasize
+ ETHER_PAD_LEN
, (void **) &sc
->sc_cdata16
,
121 BUS_DMA_NOWAIT
|BUS_DMA_COHERENT
)) != 0) {
122 aprint_error_dev(sc
->sc_dev
,
123 "unable to map control data, error = %d\n", error
);
126 nullbuf
= (uint8_t *)sc
->sc_cdata16
+ cdatasize
;
127 memset(nullbuf
, 0, ETHER_PAD_LEN
);
129 if ((error
= bus_dmamap_create(sc
->sc_dmat
,
130 cdatasize
, 1, cdatasize
, 0, BUS_DMA_NOWAIT
,
131 &sc
->sc_cddmamap
)) != 0) {
132 aprint_error_dev(sc
->sc_dev
,
133 "unable to create control data DMA map, error = %d\n",
138 if ((error
= bus_dmamap_load(sc
->sc_dmat
, sc
->sc_cddmamap
,
139 sc
->sc_cdata16
, cdatasize
, NULL
, BUS_DMA_NOWAIT
)) != 0) {
140 aprint_error_dev(sc
->sc_dev
,
141 "unable to load control data DMA map, error = %d\n", error
);
146 * Create the transmit buffer DMA maps.
148 for (i
= 0; i
< SONIC_NTXDESC
; i
++) {
149 if ((error
= bus_dmamap_create(sc
->sc_dmat
, MCLBYTES
,
150 SONIC_NTXFRAGS
, MCLBYTES
, 0, BUS_DMA_NOWAIT
,
151 &sc
->sc_txsoft
[i
].ds_dmamap
)) != 0) {
152 aprint_error_dev(sc
->sc_dev
,
153 "unable to create tx DMA map %d, error = %d\n",
160 * Create the receive buffer DMA maps.
162 for (i
= 0; i
< SONIC_NRXDESC
; i
++) {
163 if ((error
= bus_dmamap_create(sc
->sc_dmat
, MCLBYTES
, 1,
164 MCLBYTES
, 0, BUS_DMA_NOWAIT
,
165 &sc
->sc_rxsoft
[i
].ds_dmamap
)) != 0) {
166 aprint_error_dev(sc
->sc_dev
,
167 "unable to create rx DMA map %d, error = %d\n",
171 sc
->sc_rxsoft
[i
].ds_mbuf
= NULL
;
175 * create and map the pad buffer
177 if ((error
= bus_dmamap_create(sc
->sc_dmat
, ETHER_PAD_LEN
, 1,
178 ETHER_PAD_LEN
, 0, BUS_DMA_NOWAIT
, &sc
->sc_nulldmamap
)) != 0) {
179 aprint_error_dev(sc
->sc_dev
,
180 "unable to create pad buffer DMA map, error = %d\n", error
);
184 if ((error
= bus_dmamap_load(sc
->sc_dmat
, sc
->sc_nulldmamap
,
185 nullbuf
, ETHER_PAD_LEN
, NULL
, BUS_DMA_NOWAIT
)) != 0) {
186 aprint_error_dev(sc
->sc_dev
,
187 "unable to load pad buffer DMA map, error = %d\n", error
);
190 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_nulldmamap
, 0, ETHER_PAD_LEN
,
191 BUS_DMASYNC_PREWRITE
);
194 * Reset the chip to a known state.
198 aprint_normal_dev(sc
->sc_dev
, "Ethernet address %s\n",
199 ether_sprintf(enaddr
));
201 strlcpy(ifp
->if_xname
, device_xname(sc
->sc_dev
), IFNAMSIZ
);
203 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
204 ifp
->if_ioctl
= sonic_ioctl
;
205 ifp
->if_start
= sonic_start
;
206 ifp
->if_watchdog
= sonic_watchdog
;
207 ifp
->if_init
= sonic_init
;
208 ifp
->if_stop
= sonic_stop
;
209 IFQ_SET_READY(&ifp
->if_snd
);
212 * We can support 802.1Q VLAN-sized frames.
214 sc
->sc_ethercom
.ec_capabilities
|= ETHERCAP_VLAN_MTU
;
217 * Attach the interface.
220 ether_ifattach(ifp
, enaddr
);
223 * Make sure the interface is shutdown during reboot.
225 if (pmf_device_register1(sc
->sc_dev
, NULL
, NULL
, sonic_shutdown
))
226 pmf_class_network_register(sc
->sc_dev
, ifp
);
228 aprint_error_dev(sc
->sc_dev
,
229 "couldn't establish power handler\n");
234 * Free any resources we've allocated during the failed attach
235 * attempt. Do this in reverse order and fall through.
238 bus_dmamap_destroy(sc
->sc_dmat
, sc
->sc_nulldmamap
);
240 for (i
= 0; i
< SONIC_NRXDESC
; i
++) {
241 if (sc
->sc_rxsoft
[i
].ds_dmamap
!= NULL
)
242 bus_dmamap_destroy(sc
->sc_dmat
,
243 sc
->sc_rxsoft
[i
].ds_dmamap
);
246 for (i
= 0; i
< SONIC_NTXDESC
; i
++) {
247 if (sc
->sc_txsoft
[i
].ds_dmamap
!= NULL
)
248 bus_dmamap_destroy(sc
->sc_dmat
,
249 sc
->sc_txsoft
[i
].ds_dmamap
);
251 bus_dmamap_unload(sc
->sc_dmat
, sc
->sc_cddmamap
);
253 bus_dmamap_destroy(sc
->sc_dmat
, sc
->sc_cddmamap
);
255 bus_dmamem_unmap(sc
->sc_dmat
, (void *)sc
->sc_cdata16
, cdatasize
);
257 bus_dmamem_free(sc
->sc_dmat
, &seg
, rseg
);
265 * Make sure the interface is stopped at reboot.
268 sonic_shutdown(device_t self
, int howto
)
270 struct sonic_softc
*sc
= device_private(self
);
272 sonic_stop(&sc
->sc_ethercom
.ec_if
, 1);
278 * sonic_start: [ifnet interface function]
280 * Start packet transmission on the interface.
283 sonic_start(struct ifnet
*ifp
)
285 struct sonic_softc
*sc
= ifp
->if_softc
;
287 struct sonic_tda16
*tda16
;
288 struct sonic_tda32
*tda32
;
289 struct sonic_descsoft
*ds
;
291 int error
, olasttx
, nexttx
, opending
, totlen
, olseg
;
292 int seg
= 0; /* XXX: gcc */
294 if ((ifp
->if_flags
& (IFF_RUNNING
|IFF_OACTIVE
)) != IFF_RUNNING
)
298 * Remember the previous txpending and the current "last txdesc
301 opending
= sc
->sc_txpending
;
302 olasttx
= sc
->sc_txlast
;
305 * Loop through the send queue, setting up transmit descriptors
306 * until we drain the queue, or use up all available transmit
307 * descriptors. Leave one at the end for sanity's sake.
309 while (sc
->sc_txpending
< (SONIC_NTXDESC
- 1)) {
311 * Grab a packet off the queue.
313 IFQ_POLL(&ifp
->if_snd
, m0
);
319 * Get the next available transmit descriptor.
321 nexttx
= SONIC_NEXTTX(sc
->sc_txlast
);
322 ds
= &sc
->sc_txsoft
[nexttx
];
323 dmamap
= ds
->ds_dmamap
;
326 * Load the DMA map. If this fails, the packet either
327 * didn't fit in the allotted number of frags, or we were
328 * short on resources. In this case, we'll copy and try
331 if ((error
= bus_dmamap_load_mbuf(sc
->sc_dmat
, dmamap
, m0
,
332 BUS_DMA_WRITE
|BUS_DMA_NOWAIT
)) != 0 ||
333 (m0
->m_pkthdr
.len
< ETHER_PAD_LEN
&&
334 dmamap
->dm_nsegs
== SONIC_NTXFRAGS
)) {
336 bus_dmamap_unload(sc
->sc_dmat
, dmamap
);
337 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
339 printf("%s: unable to allocate Tx mbuf\n",
340 device_xname(sc
->sc_dev
));
343 if (m0
->m_pkthdr
.len
> MHLEN
) {
344 MCLGET(m
, M_DONTWAIT
);
345 if ((m
->m_flags
& M_EXT
) == 0) {
346 printf("%s: unable to allocate Tx "
348 device_xname(sc
->sc_dev
));
353 m_copydata(m0
, 0, m0
->m_pkthdr
.len
, mtod(m
, void *));
354 m
->m_pkthdr
.len
= m
->m_len
= m0
->m_pkthdr
.len
;
355 error
= bus_dmamap_load_mbuf(sc
->sc_dmat
, dmamap
,
356 m
, BUS_DMA_WRITE
|BUS_DMA_NOWAIT
);
358 printf("%s: unable to load Tx buffer, "
359 "error = %d\n", device_xname(sc
->sc_dev
),
365 IFQ_DEQUEUE(&ifp
->if_snd
, m0
);
372 * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET.
375 /* Sync the DMA map. */
376 bus_dmamap_sync(sc
->sc_dmat
, dmamap
, 0, dmamap
->dm_mapsize
,
377 BUS_DMASYNC_PREWRITE
);
380 * Store a pointer to the packet so we can free it later.
385 * Initialize the transmit descriptor.
389 tda32
= &sc
->sc_tda32
[nexttx
];
390 for (seg
= 0; seg
< dmamap
->dm_nsegs
; seg
++) {
391 tda32
->tda_frags
[seg
].frag_ptr1
=
393 (dmamap
->dm_segs
[seg
].ds_addr
>> 16) &
395 tda32
->tda_frags
[seg
].frag_ptr0
=
397 dmamap
->dm_segs
[seg
].ds_addr
& 0xffff);
398 tda32
->tda_frags
[seg
].frag_size
=
399 htosonic32(sc
, dmamap
->dm_segs
[seg
].ds_len
);
400 totlen
+= dmamap
->dm_segs
[seg
].ds_len
;
402 if (totlen
< ETHER_PAD_LEN
) {
403 tda32
->tda_frags
[seg
].frag_ptr1
=
405 (sc
->sc_nulldma
>> 16) & 0xffff);
406 tda32
->tda_frags
[seg
].frag_ptr0
=
407 htosonic32(sc
, sc
->sc_nulldma
& 0xffff);
408 tda32
->tda_frags
[seg
].frag_size
=
409 htosonic32(sc
, ETHER_PAD_LEN
- totlen
);
410 totlen
= ETHER_PAD_LEN
;
414 tda32
->tda_status
= 0;
415 tda32
->tda_pktconfig
= 0;
416 tda32
->tda_pktsize
= htosonic32(sc
, totlen
);
417 tda32
->tda_fragcnt
= htosonic32(sc
, seg
);
420 tda32
->tda_frags
[seg
].frag_ptr0
=
421 htosonic32(sc
, SONIC_CDTXADDR32(sc
,
422 SONIC_NEXTTX(nexttx
)) & 0xffff);
424 /* Sync the Tx descriptor. */
425 SONIC_CDTXSYNC32(sc
, nexttx
,
426 BUS_DMASYNC_PREREAD
|BUS_DMASYNC_PREWRITE
);
428 tda16
= &sc
->sc_tda16
[nexttx
];
429 for (seg
= 0; seg
< dmamap
->dm_nsegs
; seg
++) {
430 tda16
->tda_frags
[seg
].frag_ptr1
=
432 (dmamap
->dm_segs
[seg
].ds_addr
>> 16) &
434 tda16
->tda_frags
[seg
].frag_ptr0
=
436 dmamap
->dm_segs
[seg
].ds_addr
& 0xffff);
437 tda16
->tda_frags
[seg
].frag_size
=
438 htosonic16(sc
, dmamap
->dm_segs
[seg
].ds_len
);
439 totlen
+= dmamap
->dm_segs
[seg
].ds_len
;
441 if (totlen
< ETHER_PAD_LEN
) {
442 tda16
->tda_frags
[seg
].frag_ptr1
=
444 (sc
->sc_nulldma
>> 16) & 0xffff);
445 tda16
->tda_frags
[seg
].frag_ptr0
=
446 htosonic16(sc
, sc
->sc_nulldma
& 0xffff);
447 tda16
->tda_frags
[seg
].frag_size
=
448 htosonic16(sc
, ETHER_PAD_LEN
- totlen
);
449 totlen
= ETHER_PAD_LEN
;
453 tda16
->tda_status
= 0;
454 tda16
->tda_pktconfig
= 0;
455 tda16
->tda_pktsize
= htosonic16(sc
, totlen
);
456 tda16
->tda_fragcnt
= htosonic16(sc
, seg
);
459 tda16
->tda_frags
[seg
].frag_ptr0
=
460 htosonic16(sc
, SONIC_CDTXADDR16(sc
,
461 SONIC_NEXTTX(nexttx
)) & 0xffff);
463 /* Sync the Tx descriptor. */
464 SONIC_CDTXSYNC16(sc
, nexttx
,
465 BUS_DMASYNC_PREREAD
|BUS_DMASYNC_PREWRITE
);
468 /* Advance the Tx pointer. */
470 sc
->sc_txlast
= nexttx
;
474 * Pass the packet to any BPF listeners.
477 bpf_mtap(ifp
->if_bpf
, m0
);
481 if (sc
->sc_txpending
== (SONIC_NTXDESC
- 1)) {
482 /* No more slots left; notify upper layer. */
483 ifp
->if_flags
|= IFF_OACTIVE
;
486 if (sc
->sc_txpending
!= opending
) {
488 * We enqueued packets. If the transmitter was idle,
489 * reset the txdirty pointer.
492 sc
->sc_txdirty
= SONIC_NEXTTX(olasttx
);
495 * Stop the SONIC on the last packet we've set up,
496 * and clear end-of-list on the descriptor previous
499 * NOTE: our `seg' variable should still be valid!
503 sonic32toh(sc
, sc
->sc_tda32
[olasttx
].tda_fragcnt
);
504 sc
->sc_tda32
[sc
->sc_txlast
].tda_frags
[seg
].frag_ptr0
|=
505 htosonic32(sc
, TDA_LINK_EOL
);
506 SONIC_CDTXSYNC32(sc
, sc
->sc_txlast
,
507 BUS_DMASYNC_PREREAD
|BUS_DMASYNC_PREWRITE
);
508 sc
->sc_tda32
[olasttx
].tda_frags
[olseg
].frag_ptr0
&=
509 htosonic32(sc
, ~TDA_LINK_EOL
);
510 SONIC_CDTXSYNC32(sc
, olasttx
,
511 BUS_DMASYNC_PREREAD
|BUS_DMASYNC_PREWRITE
);
514 sonic16toh(sc
, sc
->sc_tda16
[olasttx
].tda_fragcnt
);
515 sc
->sc_tda16
[sc
->sc_txlast
].tda_frags
[seg
].frag_ptr0
|=
516 htosonic16(sc
, TDA_LINK_EOL
);
517 SONIC_CDTXSYNC16(sc
, sc
->sc_txlast
,
518 BUS_DMASYNC_PREREAD
|BUS_DMASYNC_PREWRITE
);
519 sc
->sc_tda16
[olasttx
].tda_frags
[olseg
].frag_ptr0
&=
520 htosonic16(sc
, ~TDA_LINK_EOL
);
521 SONIC_CDTXSYNC16(sc
, olasttx
,
522 BUS_DMASYNC_PREREAD
|BUS_DMASYNC_PREWRITE
);
525 /* Start the transmitter. */
526 CSR_WRITE(sc
, SONIC_CR
, CR_TXP
);
528 /* Set a watchdog timer in case the chip flakes out. */
534 * sonic_watchdog: [ifnet interface function]
536 * Watchdog timer handler.
539 sonic_watchdog(struct ifnet
*ifp
)
541 struct sonic_softc
*sc
= ifp
->if_softc
;
543 printf("%s: device timeout\n", device_xname(sc
->sc_dev
));
546 (void)sonic_init(ifp
);
550 * sonic_ioctl: [ifnet interface function]
552 * Handle control requests from the operator.
555 sonic_ioctl(struct ifnet
*ifp
, u_long cmd
, void *data
)
561 error
= ether_ioctl(ifp
, cmd
, data
);
562 if (error
== ENETRESET
) {
564 * Multicast list has changed; set the hardware
565 * filter accordingly.
567 if (ifp
->if_flags
& IFF_RUNNING
)
568 (void)sonic_init(ifp
);
579 * Interrupt service routine.
582 sonic_intr(void *arg
)
584 struct sonic_softc
*sc
= arg
;
585 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
587 int handled
= 0, wantinit
;
589 for (wantinit
= 0; wantinit
== 0;) {
590 isr
= CSR_READ(sc
, SONIC_ISR
) & sc
->sc_imr
;
593 CSR_WRITE(sc
, SONIC_ISR
, isr
); /* ACK */
600 if (isr
& (IMR_PTX
|IMR_TXER
)) {
601 if (sonic_txintr(sc
) & TCR_FU
) {
602 printf("%s: transmit FIFO underrun\n",
603 device_xname(sc
->sc_dev
));
608 if (isr
& (IMR_RFO
|IMR_RBA
|IMR_RBE
|IMR_RDE
)) {
609 #define PRINTERR(bit, str) \
611 printf("%s: %s\n",device_xname(sc->sc_dev), str)
612 PRINTERR(IMR_RFO
, "receive FIFO overrun");
613 PRINTERR(IMR_RBA
, "receive buffer exceeded");
614 PRINTERR(IMR_RBE
, "receive buffers exhausted");
615 PRINTERR(IMR_RDE
, "receive descriptors exhausted");
622 (void)sonic_init(ifp
);
632 * Helper; handle transmit complete interrupts.
635 sonic_txintr(struct sonic_softc
*sc
)
637 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
638 struct sonic_descsoft
*ds
;
639 struct sonic_tda32
*tda32
;
640 struct sonic_tda16
*tda16
;
641 uint16_t status
, totstat
= 0;
644 ifp
->if_flags
&= ~IFF_OACTIVE
;
646 for (i
= sc
->sc_txdirty
; sc
->sc_txpending
!= 0;
647 i
= SONIC_NEXTTX(i
), sc
->sc_txpending
--) {
648 ds
= &sc
->sc_txsoft
[i
];
651 SONIC_CDTXSYNC32(sc
, i
,
652 BUS_DMASYNC_POSTREAD
|BUS_DMASYNC_POSTWRITE
);
653 tda32
= &sc
->sc_tda32
[i
];
654 status
= sonic32toh(sc
, tda32
->tda_status
);
655 SONIC_CDTXSYNC32(sc
, i
, BUS_DMASYNC_PREREAD
);
657 SONIC_CDTXSYNC16(sc
, i
,
658 BUS_DMASYNC_POSTREAD
|BUS_DMASYNC_POSTWRITE
);
659 tda16
= &sc
->sc_tda16
[i
];
660 status
= sonic16toh(sc
, tda16
->tda_status
);
661 SONIC_CDTXSYNC16(sc
, i
, BUS_DMASYNC_PREREAD
);
664 if ((status
& ~(TCR_EXDIS
|TCR_CRCI
|TCR_POWC
|TCR_PINT
)) == 0)
669 bus_dmamap_sync(sc
->sc_dmat
, ds
->ds_dmamap
, 0,
670 ds
->ds_dmamap
->dm_mapsize
, BUS_DMASYNC_POSTWRITE
);
671 bus_dmamap_unload(sc
->sc_dmat
, ds
->ds_dmamap
);
672 m_freem(ds
->ds_mbuf
);
676 * Check for errors and collisions.
678 if (status
& TCR_PTX
)
682 ifp
->if_collisions
+= TDA_STATUS_NCOL(status
);
685 /* Update the dirty transmit buffer pointer. */
689 * Cancel the watchdog timer if there are no pending
692 if (sc
->sc_txpending
== 0)
701 * Helper; handle receive interrupts.
704 sonic_rxintr(struct sonic_softc
*sc
)
706 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
707 struct sonic_descsoft
*ds
;
708 struct sonic_rda32
*rda32
;
709 struct sonic_rda16
*rda16
;
712 uint16_t status
, bytecount
, ptr0
, ptr1
, seqno
;
714 for (i
= sc
->sc_rxptr
;; i
= SONIC_NEXTRX(i
)) {
715 ds
= &sc
->sc_rxsoft
[i
];
718 SONIC_CDRXSYNC32(sc
, i
,
719 BUS_DMASYNC_POSTREAD
|BUS_DMASYNC_POSTWRITE
);
720 rda32
= &sc
->sc_rda32
[i
];
721 SONIC_CDRXSYNC32(sc
, i
, BUS_DMASYNC_PREREAD
);
722 if (rda32
->rda_inuse
!= 0)
724 status
= sonic32toh(sc
, rda32
->rda_status
);
725 bytecount
= sonic32toh(sc
, rda32
->rda_bytecount
);
726 ptr0
= sonic32toh(sc
, rda32
->rda_pkt_ptr0
);
727 ptr1
= sonic32toh(sc
, rda32
->rda_pkt_ptr1
);
728 seqno
= sonic32toh(sc
, rda32
->rda_seqno
);
730 SONIC_CDRXSYNC16(sc
, i
,
731 BUS_DMASYNC_POSTREAD
|BUS_DMASYNC_POSTWRITE
);
732 rda16
= &sc
->sc_rda16
[i
];
733 SONIC_CDRXSYNC16(sc
, i
, BUS_DMASYNC_PREREAD
);
734 if (rda16
->rda_inuse
!= 0)
736 status
= sonic16toh(sc
, rda16
->rda_status
);
737 bytecount
= sonic16toh(sc
, rda16
->rda_bytecount
);
738 ptr0
= sonic16toh(sc
, rda16
->rda_pkt_ptr0
);
739 ptr1
= sonic16toh(sc
, rda16
->rda_pkt_ptr1
);
740 seqno
= sonic16toh(sc
, rda16
->rda_seqno
);
744 * Make absolutely sure this is the only packet
745 * in this receive buffer. Our entire Rx buffer
746 * management scheme depends on this, and if the
747 * SONIC didn't follow our rule, it means we've
750 KASSERT(status
& RCR_LPKT
);
753 * Make sure the packet arrived OK. If an error occurred,
754 * update stats and reset the descriptor. The buffer will
755 * be reused the next time the descriptor comes up in the
758 if ((status
& RCR_PRX
) == 0) {
759 if (status
& RCR_FAER
)
760 printf("%s: Rx frame alignment error\n",
761 device_xname(sc
->sc_dev
));
762 else if (status
& RCR_CRCR
)
763 printf("%s: Rx CRC error\n",
764 device_xname(sc
->sc_dev
));
766 SONIC_INIT_RXDESC(sc
, i
);
770 bus_dmamap_sync(sc
->sc_dmat
, ds
->ds_dmamap
, 0,
771 ds
->ds_dmamap
->dm_mapsize
, BUS_DMASYNC_POSTREAD
);
774 * The SONIC includes the CRC with every packet.
776 len
= bytecount
- ETHER_CRC_LEN
;
779 * Ok, if the chip is in 32-bit mode, then receive
780 * buffers must be aligned to 32-bit boundaries,
781 * which means the payload is misaligned. In this
782 * case, we must allocate a new mbuf, and copy the
783 * packet into it, scooted forward 2 bytes to ensure
786 * Note, in 16-bit mode, we can configure the SONIC
787 * to do what we want, and we have.
789 #ifndef __NO_STRICT_ALIGNMENT
791 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
794 if (len
> (MHLEN
- 2)) {
795 MCLGET(m
, M_DONTWAIT
);
796 if ((m
->m_flags
& M_EXT
) == 0)
801 * Note that we use a cluster for incoming frames,
802 * so the buffer is virtually contiguous.
804 memcpy(mtod(m
, void *), mtod(ds
->ds_mbuf
, void *),
806 SONIC_INIT_RXDESC(sc
, i
);
807 bus_dmamap_sync(sc
->sc_dmat
, ds
->ds_dmamap
, 0,
808 ds
->ds_dmamap
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
810 #endif /* ! __NO_STRICT_ALIGNMENT */
812 * If the packet is small enough to fit in a single
813 * header mbuf, allocate one and copy the data into
814 * it. This greatly reduces memory consumption when
815 * we receive lots of small packets.
817 if (sonic_copy_small
!= 0 && len
<= (MHLEN
- 2)) {
818 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
823 * Note that we use a cluster for incoming frames,
824 * so the buffer is virtually contiguous.
826 memcpy(mtod(m
, void *), mtod(ds
->ds_mbuf
, void *),
828 SONIC_INIT_RXDESC(sc
, i
);
829 bus_dmamap_sync(sc
->sc_dmat
, ds
->ds_dmamap
, 0,
830 ds
->ds_dmamap
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
833 if (sonic_add_rxbuf(sc
, i
) != 0) {
836 SONIC_INIT_RXDESC(sc
, i
);
837 bus_dmamap_sync(sc
->sc_dmat
, ds
->ds_dmamap
, 0,
838 ds
->ds_dmamap
->dm_mapsize
,
839 BUS_DMASYNC_PREREAD
);
845 m
->m_pkthdr
.rcvif
= ifp
;
846 m
->m_pkthdr
.len
= m
->m_len
= len
;
850 * Pass this up to any BPF listeners.
853 bpf_mtap(ifp
->if_bpf
, m
);
854 #endif /* NBPFILTER > 0 */
857 (*ifp
->if_input
)(ifp
, m
);
860 /* Update the receive pointer. */
862 CSR_WRITE(sc
, SONIC_RWR
, SONIC_CDRRADDR(sc
, SONIC_PREVRX(i
)));
868 * Perform a soft reset on the SONIC.
871 sonic_reset(struct sonic_softc
*sc
)
874 /* stop TX, RX and timer, and ensure RST is clear */
875 CSR_WRITE(sc
, SONIC_CR
, CR_STP
| CR_RXDIS
| CR_HTX
);
878 CSR_WRITE(sc
, SONIC_CR
, CR_RST
);
881 /* clear all interrupts */
882 CSR_WRITE(sc
, SONIC_IMR
, 0);
883 CSR_WRITE(sc
, SONIC_ISR
, IMR_ALL
);
885 CSR_WRITE(sc
, SONIC_CR
, 0);
890 * sonic_init: [ifnet interface function]
892 * Initialize the interface. Must be called at splnet().
895 sonic_init(struct ifnet
*ifp
)
897 struct sonic_softc
*sc
= ifp
->if_softc
;
898 struct sonic_descsoft
*ds
;
903 * Cancel any pending I/O.
908 * Reset the SONIC to a known state.
913 * Bring the SONIC into reset state, and program the DCR.
915 * Note: We don't bother optimizing the transmit and receive
916 * thresholds, here. TFT/RFT values should be set in MD attachments.
921 CSR_WRITE(sc
, SONIC_CR
, CR_RST
);
922 CSR_WRITE(sc
, SONIC_DCR
, reg
);
923 CSR_WRITE(sc
, SONIC_DCR2
, sc
->sc_dcr2
);
924 CSR_WRITE(sc
, SONIC_CR
, 0);
927 * Initialize the transmit descriptors.
930 for (i
= 0; i
< SONIC_NTXDESC
; i
++) {
931 memset(&sc
->sc_tda32
[i
], 0, sizeof(struct sonic_tda32
));
932 SONIC_CDTXSYNC32(sc
, i
,
933 BUS_DMASYNC_PREREAD
|BUS_DMASYNC_PREWRITE
);
936 for (i
= 0; i
< SONIC_NTXDESC
; i
++) {
937 memset(&sc
->sc_tda16
[i
], 0, sizeof(struct sonic_tda16
));
938 SONIC_CDTXSYNC16(sc
, i
,
939 BUS_DMASYNC_PREREAD
|BUS_DMASYNC_PREWRITE
);
942 sc
->sc_txpending
= 0;
944 sc
->sc_txlast
= SONIC_NTXDESC
- 1;
947 * Initialize the receive descriptor ring.
949 for (i
= 0; i
< SONIC_NRXDESC
; i
++) {
950 ds
= &sc
->sc_rxsoft
[i
];
951 if (ds
->ds_mbuf
== NULL
) {
952 if ((error
= sonic_add_rxbuf(sc
, i
)) != 0) {
953 printf("%s: unable to allocate or map Rx "
954 "buffer %d, error = %d\n",
955 device_xname(sc
->sc_dev
), i
, error
);
957 * XXX Should attempt to run with fewer receive
958 * XXX buffers instead of just failing.
964 SONIC_INIT_RXDESC(sc
, i
);
968 /* Give the transmit ring to the SONIC. */
969 CSR_WRITE(sc
, SONIC_UTDAR
, (SONIC_CDTXADDR(sc
, 0) >> 16) & 0xffff);
970 CSR_WRITE(sc
, SONIC_CTDAR
, SONIC_CDTXADDR(sc
, 0) & 0xffff);
972 /* Give the receive descriptor ring to the SONIC. */
973 CSR_WRITE(sc
, SONIC_URDAR
, (SONIC_CDRXADDR(sc
, 0) >> 16) & 0xffff);
974 CSR_WRITE(sc
, SONIC_CRDAR
, SONIC_CDRXADDR(sc
, 0) & 0xffff);
976 /* Give the receive buffer ring to the SONIC. */
977 CSR_WRITE(sc
, SONIC_URRAR
, (SONIC_CDRRADDR(sc
, 0) >> 16) & 0xffff);
978 CSR_WRITE(sc
, SONIC_RSAR
, SONIC_CDRRADDR(sc
, 0) & 0xffff);
980 CSR_WRITE(sc
, SONIC_REAR
,
981 (SONIC_CDRRADDR(sc
, SONIC_NRXDESC
- 1) +
982 sizeof(struct sonic_rra32
)) & 0xffff);
984 CSR_WRITE(sc
, SONIC_REAR
,
985 (SONIC_CDRRADDR(sc
, SONIC_NRXDESC
- 1) +
986 sizeof(struct sonic_rra16
)) & 0xffff);
987 CSR_WRITE(sc
, SONIC_RRR
, SONIC_CDRRADDR(sc
, 0) & 0xffff);
988 CSR_WRITE(sc
, SONIC_RWR
, SONIC_CDRRADDR(sc
, SONIC_NRXDESC
- 1));
991 * Set the End-Of-Buffer counter such that only one packet
992 * will be placed into each buffer we provide. Note we are
993 * following the recommendation of section 3.4.4 of the manual
994 * here, and have "lengthened" the receive buffers accordingly.
997 CSR_WRITE(sc
, SONIC_EOBC
, (ETHER_MAX_LEN
+ 2) / 2);
999 CSR_WRITE(sc
, SONIC_EOBC
, (ETHER_MAX_LEN
/ 2));
1001 /* Reset the receive sequence counter. */
1002 CSR_WRITE(sc
, SONIC_RSC
, 0);
1004 /* Clear the tally registers. */
1005 CSR_WRITE(sc
, SONIC_CRCETC
, 0xffff);
1006 CSR_WRITE(sc
, SONIC_FAET
, 0xffff);
1007 CSR_WRITE(sc
, SONIC_MPT
, 0xffff);
1009 /* Set the receive filter. */
1010 sonic_set_filter(sc
);
1013 * Set the interrupt mask register.
1015 sc
->sc_imr
= IMR_RFO
| IMR_RBA
| IMR_RBE
| IMR_RDE
|
1016 IMR_TXER
| IMR_PTX
| IMR_PRX
;
1017 CSR_WRITE(sc
, SONIC_IMR
, sc
->sc_imr
);
1020 * Start the receive process in motion. Note, we don't
1021 * start the transmit process until we actually try to
1024 CSR_WRITE(sc
, SONIC_CR
, CR_RXEN
| CR_RRRA
);
1029 ifp
->if_flags
|= IFF_RUNNING
;
1030 ifp
->if_flags
&= ~IFF_OACTIVE
;
1034 printf("%s: interface not running\n", device_xname(sc
->sc_dev
));
1041 * Drain the receive queue.
1044 sonic_rxdrain(struct sonic_softc
*sc
)
1046 struct sonic_descsoft
*ds
;
1049 for (i
= 0; i
< SONIC_NRXDESC
; i
++) {
1050 ds
= &sc
->sc_rxsoft
[i
];
1051 if (ds
->ds_mbuf
!= NULL
) {
1052 bus_dmamap_unload(sc
->sc_dmat
, ds
->ds_dmamap
);
1053 m_freem(ds
->ds_mbuf
);
1060 * sonic_stop: [ifnet interface function]
1062 * Stop transmission on the interface.
1065 sonic_stop(struct ifnet
*ifp
, int disable
)
1067 struct sonic_softc
*sc
= ifp
->if_softc
;
1068 struct sonic_descsoft
*ds
;
1072 * Disable interrupts.
1074 CSR_WRITE(sc
, SONIC_IMR
, 0);
1077 * Stop the transmitter, receiver, and timer.
1079 CSR_WRITE(sc
, SONIC_CR
, CR_HTX
|CR_RXDIS
|CR_STP
);
1080 for (i
= 0; i
< 1000; i
++) {
1081 if ((CSR_READ(sc
, SONIC_CR
) & (CR_TXP
|CR_RXEN
|CR_ST
)) == 0)
1085 if ((CSR_READ(sc
, SONIC_CR
) & (CR_TXP
|CR_RXEN
|CR_ST
)) != 0)
1086 printf("%s: SONIC failed to stop\n", device_xname(sc
->sc_dev
));
1089 * Release any queued transmit buffers.
1091 for (i
= 0; i
< SONIC_NTXDESC
; i
++) {
1092 ds
= &sc
->sc_txsoft
[i
];
1093 if (ds
->ds_mbuf
!= NULL
) {
1094 bus_dmamap_unload(sc
->sc_dmat
, ds
->ds_dmamap
);
1095 m_freem(ds
->ds_mbuf
);
1101 * Mark the interface down and cancel the watchdog timer.
1103 ifp
->if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);
1113 * Add a receive buffer to the indicated descriptor.
1116 sonic_add_rxbuf(struct sonic_softc
*sc
, int idx
)
1118 struct sonic_descsoft
*ds
= &sc
->sc_rxsoft
[idx
];
1122 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
1126 MCLGET(m
, M_DONTWAIT
);
1127 if ((m
->m_flags
& M_EXT
) == 0) {
1132 if (ds
->ds_mbuf
!= NULL
)
1133 bus_dmamap_unload(sc
->sc_dmat
, ds
->ds_dmamap
);
1137 error
= bus_dmamap_load(sc
->sc_dmat
, ds
->ds_dmamap
,
1138 m
->m_ext
.ext_buf
, m
->m_ext
.ext_size
, NULL
,
1139 BUS_DMA_READ
|BUS_DMA_NOWAIT
);
1141 printf("%s: can't load rx DMA map %d, error = %d\n",
1142 device_xname(sc
->sc_dev
), idx
, error
);
1143 panic("sonic_add_rxbuf"); /* XXX */
1146 bus_dmamap_sync(sc
->sc_dmat
, ds
->ds_dmamap
, 0,
1147 ds
->ds_dmamap
->dm_mapsize
, BUS_DMASYNC_PREREAD
);
1149 SONIC_INIT_RXDESC(sc
, idx
);
1155 sonic_set_camentry(struct sonic_softc
*sc
, int entry
, const uint8_t *enaddr
)
1159 struct sonic_cda32
*cda
= &sc
->sc_cda32
[entry
];
1161 cda
->cda_entry
= htosonic32(sc
, entry
);
1162 cda
->cda_addr0
= htosonic32(sc
, enaddr
[0] | (enaddr
[1] << 8));
1163 cda
->cda_addr1
= htosonic32(sc
, enaddr
[2] | (enaddr
[3] << 8));
1164 cda
->cda_addr2
= htosonic32(sc
, enaddr
[4] | (enaddr
[5] << 8));
1166 struct sonic_cda16
*cda
= &sc
->sc_cda16
[entry
];
1168 cda
->cda_entry
= htosonic16(sc
, entry
);
1169 cda
->cda_addr0
= htosonic16(sc
, enaddr
[0] | (enaddr
[1] << 8));
1170 cda
->cda_addr1
= htosonic16(sc
, enaddr
[2] | (enaddr
[3] << 8));
1171 cda
->cda_addr2
= htosonic16(sc
, enaddr
[4] | (enaddr
[5] << 8));
1178 * Set the SONIC receive filter.
1181 sonic_set_filter(struct sonic_softc
*sc
)
1183 struct ethercom
*ec
= &sc
->sc_ethercom
;
1184 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
1185 struct ether_multi
*enm
;
1186 struct ether_multistep step
;
1188 uint16_t camvalid
= 0;
1191 if (ifp
->if_flags
& IFF_BROADCAST
)
1194 if (ifp
->if_flags
& IFF_PROMISC
) {
1199 /* Put our station address in the first CAM slot. */
1200 sonic_set_camentry(sc
, entry
, CLLADDR(ifp
->if_sadl
));
1201 camvalid
|= (1U << entry
);
1204 /* Add the multicast addresses to the CAM. */
1205 ETHER_FIRST_MULTI(step
, ec
, enm
);
1206 while (enm
!= NULL
) {
1207 if (memcmp(enm
->enm_addrlo
, enm
->enm_addrhi
, ETHER_ADDR_LEN
)) {
1209 * We must listen to a range of multicast addresses.
1210 * The only way to do this on the SONIC is to enable
1211 * reception of all multicast packets.
1216 if (entry
== SONIC_NCAMENT
) {
1218 * Out of CAM slots. Have to enable reception
1219 * of all multicast addresses.
1224 sonic_set_camentry(sc
, entry
, enm
->enm_addrlo
);
1225 camvalid
|= (1U << entry
);
1228 ETHER_NEXT_MULTI(step
, enm
);
1231 ifp
->if_flags
&= ~IFF_ALLMULTI
;
1235 /* Use only the first CAM slot (station address). */
1241 /* set mask for the CAM Enable register */
1243 if (entry
== SONIC_NCAMENT
)
1244 sc
->sc_cdaenable32
= htosonic32(sc
, camvalid
);
1246 sc
->sc_cda32
[entry
].cda_entry
=
1247 htosonic32(sc
, camvalid
);
1249 if (entry
== SONIC_NCAMENT
)
1250 sc
->sc_cdaenable16
= htosonic16(sc
, camvalid
);
1252 sc
->sc_cda16
[entry
].cda_entry
=
1253 htosonic16(sc
, camvalid
);
1257 SONIC_CDCAMSYNC(sc
, BUS_DMASYNC_PREWRITE
);
1258 CSR_WRITE(sc
, SONIC_CDP
, SONIC_CDCAMADDR(sc
) & 0xffff);
1259 CSR_WRITE(sc
, SONIC_CDC
, entry
);
1260 CSR_WRITE(sc
, SONIC_CR
, CR_LCAM
);
1261 for (i
= 0; i
< 10000; i
++) {
1262 if ((CSR_READ(sc
, SONIC_CR
) & CR_LCAM
) == 0)
1266 if (CSR_READ(sc
, SONIC_CR
) & CR_LCAM
)
1267 printf("%s: CAM load failed\n", device_xname(sc
->sc_dev
));
1268 SONIC_CDCAMSYNC(sc
, BUS_DMASYNC_POSTWRITE
);
1270 /* Set the receive control register. */
1271 CSR_WRITE(sc
, SONIC_RCR
, rcr
);