1 /* $NetBSD: if_sn.c,v 1.30 2008/04/09 15:40:30 tsutsui Exp $ */
4 * National Semiconductor DP8393X SONIC Driver
5 * Copyright (c) 1991 Algorithmics Ltd (http://www.algor.co.uk)
6 * You may use, copy, and modify this program so long as you retain the
9 * This driver has been substantially modified since Algorithmics donated
12 * Denton Gentry <denny1@home.com>
14 * Yanagisawa Takeshi <yanagisw@aa.ap.titech.ac.jp>
15 * did the work to get this running on the Macintosh.
18 #include <sys/cdefs.h>
19 __KERNEL_RCSID(0, "$NetBSD: if_sn.c,v 1.30 2008/04/09 15:40:30 tsutsui Exp $");
23 #include <sys/param.h>
24 #include <sys/systm.h>
27 #include <sys/protosw.h>
28 #include <sys/socket.h>
29 #include <sys/syslog.h>
30 #include <sys/ioctl.h>
31 #include <sys/errno.h>
32 #include <sys/device.h>
35 #include <net/if_dl.h>
36 #include <net/if_ether.h>
39 #include <netinet/in.h>
40 #include <netinet/in_systm.h>
41 #include <netinet/in_var.h>
42 #include <netinet/ip.h>
43 #include <netinet/if_inarp.h>
46 #include <uvm/uvm_extern.h>
51 #include <net/bpfdesc.h>
54 #include <machine/cpu.h>
55 #include <newsmips/apbus/apbusvar.h>
56 #include <newsmips/apbus/if_snreg.h>
57 #include <newsmips/apbus/if_snvar.h>
59 /* #define SONIC_DEBUG */
62 # define DPRINTF printf
64 # define DPRINTF while (0) printf
67 static void snwatchdog(struct ifnet
*);
68 static int sninit(struct sn_softc
*sc
);
69 static int snstop(struct sn_softc
*sc
);
70 static int snioctl(struct ifnet
*ifp
, u_long cmd
, void *data
);
71 static void snstart(struct ifnet
*ifp
);
72 static void snreset(struct sn_softc
*sc
);
74 static void caminitialise(struct sn_softc
*);
75 static void camentry(struct sn_softc
*, int, const u_char
*ea
);
76 static void camprogram(struct sn_softc
*);
77 static void initialise_tda(struct sn_softc
*);
78 static void initialise_rda(struct sn_softc
*);
79 static void initialise_rra(struct sn_softc
*);
81 static void camdump(struct sn_softc
*sc
);
84 static void sonictxint(struct sn_softc
*);
85 static void sonicrxint(struct sn_softc
*);
87 static inline u_int
sonicput(struct sn_softc
*sc
, struct mbuf
*m0
,
89 static inline int sonic_read(struct sn_softc
*, void *, int);
90 static inline struct mbuf
*sonic_get(struct sn_softc
*, void *, int);
95 * SONIC buffers need to be aligned 16 or 32 bit aligned.
96 * These macros calculate and verify alignment.
98 #define SOALIGN(m, array) (m ? (roundup((int)array, 4)) : \
99 (roundup((int)array, 2)))
101 #define LOWER(x) ((unsigned)(x) & 0xffff)
102 #define UPPER(x) ((unsigned)(x) >> 16)
105 * Interface exists: make available by filling in network interface
106 * record. System will initialize the interface when it is ready
110 snsetup(struct sn_softc
*sc
, uint8_t *lladdr
)
112 struct ifnet
*ifp
= &sc
->sc_if
;
117 if (sc
->space
== NULL
) {
118 aprint_error_dev(sc
->sc_dev
,
119 "memory allocation for descriptors failed\n");
124 * Put the pup in reset mode (sninit() will fix it later),
125 * stop the timer, disable all interrupts and clear any interrupts.
127 NIC_PUT(sc
, SNR_CR
, CR_STP
);
129 NIC_PUT(sc
, SNR_CR
, CR_RST
);
131 NIC_PUT(sc
, SNR_IMR
, 0);
133 NIC_PUT(sc
, SNR_ISR
, ISR_ALL
);
137 * because the SONIC is basically 16bit device it 'concatenates'
138 * a higher buffer address to a 16 bit offset--this will cause wrap
139 * around problems near the end of 64k !!
142 pp
= (uint8_t *)roundup((int)p
, PAGE_SIZE
);
145 for (i
= 0; i
< NRRA
; i
++) {
146 sc
->p_rra
[i
] = (void *)p
;
147 sc
->v_rra
[i
] = SONIC_GETDMA(p
);
148 p
+= RXRSRC_SIZE(sc
);
150 sc
->v_rea
= SONIC_GETDMA(p
);
152 p
= (uint8_t *)SOALIGN(sc
, p
);
154 sc
->p_cda
= (void *)(p
);
155 sc
->v_cda
= SONIC_GETDMA(p
);
158 p
= (uint8_t *)SOALIGN(sc
, p
);
160 for (i
= 0; i
< NTDA
; i
++) {
161 struct mtd
*mtdp
= &sc
->mtda
[i
];
162 mtdp
->mtd_txp
= (void *)p
;
163 mtdp
->mtd_vtxp
= SONIC_GETDMA(p
);
167 p
= (uint8_t *)SOALIGN(sc
, p
);
169 if ((p
- pp
) > PAGE_SIZE
) {
170 aprint_error_dev(sc
->sc_dev
, "sizeof RRA (%ld) + CDA (%ld) +"
171 "TDA (%ld) > PAGE_SIZE (%d). Punt!\n",
172 (ulong
)sc
->p_cda
- (ulong
)sc
->p_rra
[0],
173 (ulong
)sc
->mtda
[0].mtd_txp
- (ulong
)sc
->p_cda
,
174 (ulong
)p
- (ulong
)sc
->mtda
[0].mtd_txp
,
182 sc
->sc_nrda
= PAGE_SIZE
/ RXPKT_SIZE(sc
);
183 sc
->p_rda
= (void *)p
;
184 sc
->v_rda
= SONIC_GETDMA(p
);
188 for (i
= 0; i
< NRBA
; i
++) {
189 sc
->rbuf
[i
] = (void *)p
;
194 for (i
= 0; i
< NTDA
; i
++) {
195 struct mtd
*mtdp
= &sc
->mtda
[i
];
198 mtdp
->mtd_vbuf
= SONIC_GETDMA(p
);
205 aprint_normal_dev(sc
->sc_dev
, "Ethernet address %s\n",
206 ether_sprintf(lladdr
));
209 aprint_debug_dev(sc
->sc_dev
, "buffers: rra=%p cda=%p rda=%p tda=%p\n",
210 sc
->sc_dev
.dv_xname
, sc
->p_rra
[0], sc
->p_cda
,
211 sc
->p_rda
, sc
->mtda
[0].mtd_txp
);
214 strcpy(ifp
->if_xname
, device_xname(sc
->sc_dev
));
216 ifp
->if_ioctl
= snioctl
;
217 ifp
->if_start
= snstart
;
219 IFF_BROADCAST
| IFF_SIMPLEX
| IFF_NOTRAILERS
| IFF_MULTICAST
;
220 ifp
->if_watchdog
= snwatchdog
;
222 ether_ifattach(ifp
, lladdr
);
228 snioctl(struct ifnet
*ifp
, u_long cmd
, void *data
)
231 struct sn_softc
*sc
= ifp
->if_softc
;
232 int s
= splnet(), err
= 0;
238 ifa
= (struct ifaddr
*)data
;
239 ifp
->if_flags
|= IFF_UP
;
241 switch (ifa
->ifa_addr
->sa_family
) {
244 arp_ifinit(ifp
, ifa
);
253 if ((err
= ifioctl_common(ifp
, cmd
, data
)) != 0)
255 if ((ifp
->if_flags
& IFF_UP
) == 0 &&
256 (ifp
->if_flags
& IFF_RUNNING
) != 0) {
258 * If interface is marked down and it is running,
262 ifp
->if_flags
&= ~IFF_RUNNING
;
263 } else if ((ifp
->if_flags
& IFF_UP
) != 0 &&
264 (ifp
->if_flags
& IFF_RUNNING
) == 0) {
266 * If interface is marked up and it is stopped,
272 * reset the interface to pick up any other changes
275 temp
= ifp
->if_flags
& IFF_UP
;
277 ifp
->if_flags
|= temp
;
284 if ((err
= ether_ioctl(ifp
, cmd
, data
)) == ENETRESET
) {
286 * Multicast list has changed; set the hardware
287 * filter accordingly. But remember UP flag!
289 if (ifp
->if_flags
& IFF_RUNNING
) {
290 temp
= ifp
->if_flags
& IFF_UP
;
292 ifp
->if_flags
|= temp
;
298 err
= ether_ioctl(ifp
, cmd
, data
);
306 * Encapsulate a packet of type family for the local net.
309 snstart(struct ifnet
*ifp
)
311 struct sn_softc
*sc
= ifp
->if_softc
;
315 if ((ifp
->if_flags
& (IFF_RUNNING
| IFF_OACTIVE
)) != IFF_RUNNING
)
319 /* Check for room in the xmit buffer. */
320 if ((mtd_next
= (sc
->mtd_free
+ 1)) == NTDA
)
323 if (mtd_next
== sc
->mtd_hw
) {
324 ifp
->if_flags
|= IFF_OACTIVE
;
328 IF_DEQUEUE(&ifp
->if_snd
, m
);
332 /* We need the header for m_pkthdr.len. */
333 if ((m
->m_flags
& M_PKTHDR
) == 0)
334 panic("%s: snstart: no header mbuf", device_xname(sc
->sc_dev
));
338 * If bpf is listening on this interface, let it
339 * see the packet before we commit it to the wire.
342 bpf_mtap(ifp
->if_bpf
, m
);
346 * If there is nothing in the o/p queue, and there is room in
347 * the Tx ring, then send the packet directly. Otherwise append
348 * it to the o/p queue.
350 if ((sonicput(sc
, m
, mtd_next
)) == 0) {
351 IF_PREPEND(&ifp
->if_snd
, m
);
355 sc
->mtd_prev
= sc
->mtd_free
;
356 sc
->mtd_free
= mtd_next
;
358 ifp
->if_opackets
++; /* # of pkts */
360 /* Jump back for possibly more punishment. */
365 * reset and restart the SONIC. Called in case of fatal
366 * hardware/software errors.
369 snreset(struct sn_softc
*sc
)
377 sninit(struct sn_softc
*sc
)
382 if (sc
->sc_if
.if_flags
& IFF_RUNNING
)
383 /* already running */
388 NIC_PUT(sc
, SNR_CR
, CR_RST
); /* DCR only accessible in reset mode! */
391 NIC_PUT(sc
, SNR_DCR
, (sc
->snr_dcr
|
392 (sc
->bitmode
? DCR_DW32
: DCR_DW16
)));
393 NIC_PUT(sc
, SNR_DCR2
, sc
->snr_dcr2
);
395 s_rcr
= RCR_BRD
| RCR_LBNONE
;
396 if (sc
->sc_if
.if_flags
& IFF_PROMISC
)
398 if (sc
->sc_if
.if_flags
& IFF_ALLMULTI
)
400 NIC_PUT(sc
, SNR_RCR
, s_rcr
);
403 NIC_PUT(sc
, SNR_IMR
, (IMR_PRXEN
| IMR_PTXEN
| IMR_TXEREN
| IMR_LCDEN
));
405 NIC_PUT(sc
, SNR_IMR
, IMR_PRXEN
| IMR_PTXEN
| IMR_TXEREN
| IMR_LCDEN
|
406 IMR_BREN
| IMR_HBLEN
| IMR_RDEEN
| IMR_RBEEN
|
407 IMR_RBAEEN
| IMR_RFOEN
);
410 /* clear pending interrupts */
411 NIC_PUT(sc
, SNR_ISR
, ISR_ALL
);
413 /* clear tally counters */
414 NIC_PUT(sc
, SNR_CRCT
, -1);
415 NIC_PUT(sc
, SNR_FAET
, -1);
416 NIC_PUT(sc
, SNR_MPT
, -1);
422 sn_md_init(sc
); /* MD initialization */
424 /* enable the chip */
425 NIC_PUT(sc
, SNR_CR
, 0);
428 /* program the CAM */
431 /* get it to read resource descriptors */
432 NIC_PUT(sc
, SNR_CR
, CR_RRRA
);
434 while ((NIC_GET(sc
, SNR_CR
)) & CR_RRRA
)
438 NIC_PUT(sc
, SNR_CR
, CR_RXEN
);
441 /* flag interface as "running" */
442 sc
->sc_if
.if_flags
|= IFF_RUNNING
;
443 sc
->sc_if
.if_flags
&= ~IFF_OACTIVE
;
450 * close down an interface and free its buffers
451 * Called on final close of device, or if sninit() fails
455 snstop(struct sn_softc
*sc
)
460 /* stick chip in reset */
461 NIC_PUT(sc
, SNR_CR
, CR_RST
);
464 /* free all receive buffers (currently static so nothing to do) */
466 /* free all pending transmit mbufs */
467 while (sc
->mtd_hw
!= sc
->mtd_free
) {
468 mtd
= &sc
->mtda
[sc
->mtd_hw
];
470 m_freem(mtd
->mtd_mbuf
);
471 if (++sc
->mtd_hw
== NTDA
) sc
->mtd_hw
= 0;
474 sc
->sc_if
.if_timer
= 0;
475 sc
->sc_if
.if_flags
&= ~(IFF_RUNNING
| IFF_UP
);
482 * Called if any Tx packets remain unsent after 5 seconds,
483 * In all cases we just reset the chip, and any retransmission
484 * will be handled by higher level protocol timeouts.
487 snwatchdog(struct ifnet
*ifp
)
489 struct sn_softc
*sc
= ifp
->if_softc
;
493 if (sc
->mtd_hw
!= sc
->mtd_free
) {
494 /* something still pending for transmit */
495 mtd
= &sc
->mtda
[sc
->mtd_hw
];
496 if (SRO(sc
->bitmode
, mtd
->mtd_txp
, TXP_STATUS
) == 0)
497 log(LOG_ERR
, "%s: Tx - timeout\n",
498 device_xname(sc
->sc_dev
));
500 log(LOG_ERR
, "%s: Tx - lost interrupt\n",
501 device_xname(sc
->sc_dev
));
502 temp
= ifp
->if_flags
& IFF_UP
;
504 ifp
->if_flags
|= temp
;
509 * stuff packet into sonic (at splnet)
512 sonicput(struct sn_softc
*sc
, struct mbuf
*m0
, int mtd_next
)
521 #ifdef whyonearthwouldyoudothis
522 if (NIC_GET(sc
, SNR_CR
) & CR_TXP
)
526 /* grab the replacement mtd */
527 mtdp
= &sc
->mtda
[sc
->mtd_free
];
529 buff
= mtdp
->mtd_buf
;
531 /* this packet goes to mtdnext fill in the TDA */
535 /* Write to the config word. Every (NTDA/2)+1 packets we set an intr */
536 if (sc
->mtd_pint
== 0) {
537 sc
->mtd_pint
= NTDA
/2;
538 SWO(sc
->bitmode
, txp
, TXP_CONFIG
, TCR_PINT
);
541 SWO(sc
->bitmode
, txp
, TXP_CONFIG
, 0);
544 for (m
= m0
; m
; m
= m
->m_next
) {
545 u_char
*data
= mtod(m
, u_char
*);
548 memcpy(buff
, data
, len
);
551 if (totlen
>= TXBSIZE
) {
552 panic("%s: sonicput: packet overflow",
553 device_xname(sc
->sc_dev
));
556 SWO(sc
->bitmode
, txp
, TXP_FRAGOFF
+ (0 * TXP_FRAGSIZE
) + TXP_FPTRLO
,
557 LOWER(mtdp
->mtd_vbuf
));
558 SWO(sc
->bitmode
, txp
, TXP_FRAGOFF
+ (0 * TXP_FRAGSIZE
) + TXP_FPTRHI
,
559 UPPER(mtdp
->mtd_vbuf
));
561 if (totlen
< ETHERMIN
+ ETHER_HDR_LEN
) {
562 int pad
= ETHERMIN
+ ETHER_HDR_LEN
- totlen
;
563 memset((char *)mtdp
->mtd_buf
+ totlen
, 0, pad
);
564 totlen
= ETHERMIN
+ ETHER_HDR_LEN
;
567 SWO(sc
->bitmode
, txp
, TXP_FRAGOFF
+ (0 * TXP_FRAGSIZE
) + TXP_FSIZE
,
569 SWO(sc
->bitmode
, txp
, TXP_FRAGCNT
, 1);
570 SWO(sc
->bitmode
, txp
, TXP_PKTSIZE
, totlen
);
572 /* link onto the next mtd that will be used */
573 SWO(sc
->bitmode
, txp
, TXP_FRAGOFF
+ (1 * TXP_FRAGSIZE
) + TXP_FPTRLO
,
574 LOWER(sc
->mtda
[mtd_next
].mtd_vtxp
) | EOL
);
577 * The previous txp.tlink currently contains a pointer to
578 * our txp | EOL. Want to clear the EOL, so write our
579 * pointer to the previous txp.
581 SWO(sc
->bitmode
, sc
->mtda
[sc
->mtd_prev
].mtd_txp
, sc
->mtd_tlinko
,
582 LOWER(mtdp
->mtd_vtxp
));
584 /* make sure chip is running */
586 NIC_PUT(sc
, SNR_CR
, CR_TXP
);
588 sc
->sc_if
.if_timer
= 5; /* 5 seconds to watch for failing to transmit */
594 * These are called from sonicioctl() when /etc/ifconfig is run to set
595 * the address or switch the i/f on.
601 caminitialise(struct sn_softc
*sc
)
603 void *p_cda
= sc
->p_cda
;
607 for (i
= 0; i
< MAXCAM
; i
++) {
608 camoffset
= i
* CDA_CAMDESC
;
609 SWO(bitmode
, p_cda
, (camoffset
+ CDA_CAMEP
), i
);
610 SWO(bitmode
, p_cda
, (camoffset
+ CDA_CAMAP2
), 0);
611 SWO(bitmode
, p_cda
, (camoffset
+ CDA_CAMAP1
), 0);
612 SWO(bitmode
, p_cda
, (camoffset
+ CDA_CAMAP0
), 0);
614 SWO(bitmode
, p_cda
, CDA_ENABLE
, 0);
618 camentry(struct sn_softc
*sc
, int entry
, const u_char
*ea
)
620 void *p_cda
= sc
->p_cda
;
621 int camoffset
= entry
* CDA_CAMDESC
;
623 SWO(bitmode
, p_cda
, camoffset
+ CDA_CAMEP
, entry
);
624 SWO(bitmode
, p_cda
, camoffset
+ CDA_CAMAP2
, (ea
[5] << 8) | ea
[4]);
625 SWO(bitmode
, p_cda
, camoffset
+ CDA_CAMAP1
, (ea
[3] << 8) | ea
[2]);
626 SWO(bitmode
, p_cda
, camoffset
+ CDA_CAMAP0
, (ea
[1] << 8) | ea
[0]);
627 SWO(bitmode
, p_cda
, CDA_ENABLE
,
628 (SRO(bitmode
, p_cda
, CDA_ENABLE
) | (1 << entry
)));
632 camprogram(struct sn_softc
*sc
)
634 struct ether_multistep step
;
635 struct ether_multi
*enm
;
644 /* Always load our own address first. */
645 camentry(sc
, mcount
, CLLADDR(ifp
->if_sadl
));
648 /* Assume we won't need allmulti bit. */
649 ifp
->if_flags
&= ~IFF_ALLMULTI
;
651 /* Loop through multicast addresses */
652 ETHER_FIRST_MULTI(step
, &sc
->sc_ethercom
, enm
);
653 while (enm
!= NULL
) {
654 if (mcount
== MAXCAM
) {
655 ifp
->if_flags
|= IFF_ALLMULTI
;
659 if (memcmp(enm
->enm_addrlo
, enm
->enm_addrhi
,
660 sizeof(enm
->enm_addrlo
)) != 0) {
662 * SONIC's CAM is programmed with specific
663 * addresses. It has no way to specify a range.
664 * (Well, thats not exactly true. If the
665 * range is small one could program each addr
666 * within the range as a separate CAM entry)
668 ifp
->if_flags
|= IFF_ALLMULTI
;
672 /* program the CAM with the specified entry */
673 camentry(sc
, mcount
, enm
->enm_addrlo
);
676 ETHER_NEXT_MULTI(step
, enm
);
679 NIC_PUT(sc
, SNR_CDP
, LOWER(sc
->v_cda
));
680 NIC_PUT(sc
, SNR_CDC
, MAXCAM
);
681 NIC_PUT(sc
, SNR_CR
, CR_LCAM
);
685 while ((NIC_GET(sc
, SNR_CR
) & CR_LCAM
) && timeout
--)
689 panic("%s: CAM initialisation failed",
690 device_xname(sc
->sc_dev
));
693 while (((NIC_GET(sc
, SNR_ISR
) & ISR_LCD
) == 0) && timeout
--)
696 if (NIC_GET(sc
, SNR_ISR
) & ISR_LCD
)
697 NIC_PUT(sc
, SNR_ISR
, ISR_LCD
);
699 printf("%s: CAM initialisation without interrupt\n",
700 device_xname(sc
->sc_dev
));
705 camdump(struct sn_softc
*sc
)
709 printf("CAM entries:\n");
710 NIC_PUT(sc
, SNR_CR
, CR_RST
);
713 for (i
= 0; i
< 16; i
++) {
714 ushort ap2
, ap1
, ap0
;
715 NIC_PUT(sc
, SNR_CEP
, i
);
717 ap2
= NIC_GET(sc
, SNR_CAP2
);
718 ap1
= NIC_GET(sc
, SNR_CAP1
);
719 ap0
= NIC_GET(sc
, SNR_CAP0
);
720 printf("%d: ap2=0x%x ap1=0x%x ap0=0x%x\n", i
, ap2
, ap1
, ap0
);
722 printf("CAM enable 0x%x\n", NIC_GET(sc
, SNR_CEP
));
724 NIC_PUT(sc
, SNR_CR
, 0);
730 initialise_tda(struct sn_softc
*sc
)
735 for (i
= 0; i
< NTDA
; i
++) {
741 sc
->mtd_prev
= NTDA
- 1;
743 sc
->mtd_tlinko
= TXP_FRAGOFF
+ 1*TXP_FRAGSIZE
+ TXP_FPTRLO
;
744 sc
->mtd_pint
= NTDA
/2;
746 NIC_PUT(sc
, SNR_UTDA
, UPPER(sc
->mtda
[0].mtd_vtxp
));
747 NIC_PUT(sc
, SNR_CTDA
, LOWER(sc
->mtda
[0].mtd_vtxp
));
751 initialise_rda(struct sn_softc
*sc
)
757 /* link the RDA's together into a circular list */
758 for (i
= 0; i
< (sc
->sc_nrda
- 1); i
++) {
759 p_rda
= (char *)sc
->p_rda
+ (i
* RXPKT_SIZE(sc
));
760 v_rda
= sc
->v_rda
+ ((i
+1) * RXPKT_SIZE(sc
));
761 SWO(bitmode
, p_rda
, RXPKT_RLINK
, LOWER(v_rda
));
762 SWO(bitmode
, p_rda
, RXPKT_INUSE
, 1);
764 p_rda
= (char *)sc
->p_rda
+ ((sc
->sc_nrda
- 1) * RXPKT_SIZE(sc
));
765 SWO(bitmode
, p_rda
, RXPKT_RLINK
, LOWER(sc
->v_rda
) | EOL
);
766 SWO(bitmode
, p_rda
, RXPKT_INUSE
, 1);
768 /* mark end of receive descriptor list */
769 sc
->sc_rdamark
= sc
->sc_nrda
- 1;
773 NIC_PUT(sc
, SNR_URDA
, UPPER(sc
->v_rda
));
774 NIC_PUT(sc
, SNR_CRDA
, LOWER(sc
->v_rda
));
779 initialise_rra(struct sn_softc
*sc
)
783 int bitmode
= sc
->bitmode
;
786 NIC_PUT(sc
, SNR_EOBC
, RBASIZE(sc
) / 2 - 2);
788 NIC_PUT(sc
, SNR_EOBC
, RBASIZE(sc
) / 2 - 1);
790 NIC_PUT(sc
, SNR_URRA
, UPPER(sc
->v_rra
[0]));
791 NIC_PUT(sc
, SNR_RSA
, LOWER(sc
->v_rra
[0]));
792 /* rea must point just past the end of the rra space */
793 NIC_PUT(sc
, SNR_REA
, LOWER(sc
->v_rea
));
794 NIC_PUT(sc
, SNR_RRP
, LOWER(sc
->v_rra
[0]));
795 NIC_PUT(sc
, SNR_RSC
, 0);
797 /* fill up SOME of the rra with buffers */
798 for (i
= 0; i
< NRBA
; i
++) {
799 v
= SONIC_GETDMA(sc
->rbuf
[i
]);
800 SWO(bitmode
, sc
->p_rra
[i
], RXRSRC_PTRHI
, UPPER(v
));
801 SWO(bitmode
, sc
->p_rra
[i
], RXRSRC_PTRLO
, LOWER(v
));
802 SWO(bitmode
, sc
->p_rra
[i
], RXRSRC_WCHI
, UPPER(PAGE_SIZE
/2));
803 SWO(bitmode
, sc
->p_rra
[i
], RXRSRC_WCLO
, LOWER(PAGE_SIZE
/2));
805 sc
->sc_rramark
= NRBA
;
806 NIC_PUT(sc
, SNR_RWP
, LOWER(sc
->v_rra
[sc
->sc_rramark
]));
813 struct sn_softc
*sc
= (struct sn_softc
*)arg
;
817 while ((isr
= (NIC_GET(sc
, SNR_ISR
) & ISR_ALL
)) != 0) {
818 /* scrub the interrupts that we are going to service */
819 NIC_PUT(sc
, SNR_ISR
, isr
);
823 if (isr
& (ISR_BR
| ISR_LCD
| ISR_TC
))
824 printf("%s: unexpected interrupt status 0x%x\n",
825 device_xname(sc
->sc_dev
), isr
);
827 if (isr
& (ISR_TXDN
| ISR_TXER
| ISR_PINT
))
833 if (isr
& (ISR_HBL
| ISR_RDE
| ISR_RBE
| ISR_RBAE
| ISR_RFO
)) {
836 * The repeater is not providing a heartbeat.
837 * In itself this isn't harmful, lots of the
838 * cheap repeater hubs don't supply a heartbeat.
839 * So ignore the lack of heartbeat. Its only
840 * if we can't detect a carrier that we have a
845 printf("%s: receive descriptors exhausted\n",
846 device_xname(sc
->sc_dev
));
848 printf("%s: receive buffers exhausted\n",
849 device_xname(sc
->sc_dev
));
851 printf("%s: receive buffer area exhausted\n",
852 device_xname(sc
->sc_dev
));
854 printf("%s: receive FIFO overrun\n",
855 device_xname(sc
->sc_dev
));
857 if (isr
& (ISR_CRC
| ISR_FAE
| ISR_MP
)) {
873 * Transmit interrupt routine
876 sonictxint(struct sn_softc
*sc
)
880 unsigned short txp_status
;
882 struct ifnet
*ifp
= &sc
->sc_if
;
886 if (mtd_hw
== sc
->mtd_free
)
889 while (mtd_hw
!= sc
->mtd_free
) {
890 mtd
= &sc
->mtda
[mtd_hw
];
894 if (SRO(sc
->bitmode
, txp
, TXP_STATUS
) == 0) {
895 break; /* it hasn't really gone yet */
900 struct ether_header
*eh
;
902 eh
= (struct ether_header
*) mtd
->mtd_buf
;
903 printf("%s: xmit status=0x%x len=%d type=0x%x from %s",
904 device_xname(sc
->sc_dev
),
905 SRO(sc
->bitmode
, txp
, TXP_STATUS
),
906 SRO(sc
->bitmode
, txp
, TXP_PKTSIZE
),
907 htons(eh
->ether_type
),
908 ether_sprintf(eh
->ether_shost
));
909 printf(" (to %s)\n", ether_sprintf(eh
->ether_dhost
));
913 ifp
->if_flags
&= ~IFF_OACTIVE
;
915 if (mtd
->mtd_mbuf
!= 0) {
916 m_freem(mtd
->mtd_mbuf
);
919 if (++mtd_hw
== NTDA
) mtd_hw
= 0;
921 txp_status
= SRO(sc
->bitmode
, txp
, TXP_STATUS
);
923 ifp
->if_collisions
+= (txp_status
& TCR_EXC
) ? 16 :
924 ((txp_status
& TCR_NC
) >> 12);
926 if ((txp_status
& TCR_PTX
) == 0) {
928 printf("%s: Tx packet status=0x%x\n",
929 device_xname(sc
->sc_dev
), txp_status
);
931 /* XXX - DG This looks bogus */
932 if (mtd_hw
!= sc
->mtd_free
) {
933 printf("resubmitting remaining packets\n");
934 mtd
= &sc
->mtda
[mtd_hw
];
935 NIC_PUT(sc
, SNR_CTDA
, LOWER(mtd
->mtd_vtxp
));
936 NIC_PUT(sc
, SNR_CR
, CR_TXP
);
948 * Receive interrupt routine
951 sonicrxint(struct sn_softc
*sc
)
960 rda
= (char *)sc
->p_rda
+ (sc
->sc_rxmark
* RXPKT_SIZE(sc
));
962 while (SRO(bitmode
, rda
, RXPKT_INUSE
) == 0) {
963 u_int status
= SRO(bitmode
, rda
, RXPKT_STATUS
);
965 orra
= RBASEQ(SRO(bitmode
, rda
, RXPKT_SEQNO
)) & RRAMASK
;
966 rxpkt_ptr
= SRO(bitmode
, rda
, RXPKT_PTRLO
);
967 len
= SRO(bitmode
, rda
, RXPKT_BYTEC
) - FCSSIZE
;
968 if (status
& RCR_PRX
) {
970 (char *)sc
->rbuf
[orra
& RBAMASK
] +
971 (rxpkt_ptr
& PGOFSET
);
972 if (sonic_read(sc
, pkt
, len
))
973 sc
->sc_if
.if_ipackets
++;
975 sc
->sc_if
.if_ierrors
++;
977 sc
->sc_if
.if_ierrors
++;
980 * give receive buffer area back to chip.
982 * If this was the last packet in the RRA, give the RRA to
984 * If sonic read didnt copy it out then we would have to
986 * (dont bother add it back in again straight away)
988 * Really, we're doing p_rra[rramark] = p_rra[orra] but
989 * we have to use the macros because SONIC might be in
992 if (status
& RCR_LPKT
) {
995 rramark
= sc
->sc_rramark
;
996 tmp1
= sc
->p_rra
[rramark
];
997 tmp2
= sc
->p_rra
[orra
];
998 SWO(bitmode
, tmp1
, RXRSRC_PTRLO
,
999 SRO(bitmode
, tmp2
, RXRSRC_PTRLO
));
1000 SWO(bitmode
, tmp1
, RXRSRC_PTRHI
,
1001 SRO(bitmode
, tmp2
, RXRSRC_PTRHI
));
1002 SWO(bitmode
, tmp1
, RXRSRC_WCLO
,
1003 SRO(bitmode
, tmp2
, RXRSRC_WCLO
));
1004 SWO(bitmode
, tmp1
, RXRSRC_WCHI
,
1005 SRO(bitmode
, tmp2
, RXRSRC_WCHI
));
1007 /* zap old rra for fun */
1008 SWO(bitmode
, tmp2
, RXRSRC_WCHI
, 0);
1009 SWO(bitmode
, tmp2
, RXRSRC_WCLO
, 0);
1011 sc
->sc_rramark
= (++rramark
) & RRAMASK
;
1012 NIC_PUT(sc
, SNR_RWP
, LOWER(sc
->v_rra
[rramark
]));
1017 * give receive descriptor back to chip simple
1020 rdamark
= sc
->sc_rdamark
;
1021 SWO(bitmode
, rda
, RXPKT_INUSE
, 1);
1022 SWO(bitmode
, rda
, RXPKT_RLINK
,
1023 SRO(bitmode
, rda
, RXPKT_RLINK
) | EOL
);
1024 SWO(bitmode
, ((char *)sc
->p_rda
+ (rdamark
* RXPKT_SIZE(sc
))),
1026 SRO(bitmode
, ((char *)sc
->p_rda
+
1027 (rdamark
* RXPKT_SIZE(sc
))),
1028 RXPKT_RLINK
) & ~EOL
);
1029 sc
->sc_rdamark
= sc
->sc_rxmark
;
1031 if (++sc
->sc_rxmark
>= sc
->sc_nrda
)
1033 rda
= (char *)sc
->p_rda
+ (sc
->sc_rxmark
* RXPKT_SIZE(sc
));
1038 * sonic_read -- pull packet off interface and forward to
1039 * appropriate protocol handler
1042 sonic_read(struct sn_softc
*sc
, void *pkt
, int len
)
1044 struct ifnet
*ifp
= &sc
->sc_if
;
1049 printf("%s: rcvd %p len=%d type=0x%x from %s",
1050 devoce_xname(sc
->sc_dev
), et
, len
, htons(et
->ether_type
),
1051 ether_sprintf(et
->ether_shost
));
1052 printf(" (to %s)\n", ether_sprintf(et
->ether_dhost
));
1054 #endif /* SNDEBUG */
1056 if (len
< (ETHER_MIN_LEN
- ETHER_CRC_LEN
) ||
1057 len
> (ETHER_MAX_LEN
- ETHER_CRC_LEN
)) {
1058 printf("%s: invalid packet length %d bytes\n",
1059 device_xname(sc
->sc_dev
), len
);
1063 m
= sonic_get(sc
, pkt
, len
);
1067 /* Pass the packet to any BPF listeners. */
1069 bpf_mtap(ifp
->if_bpf
, m
);
1071 (*ifp
->if_input
)(ifp
, m
);
1076 * munge the received packet into an mbuf chain
1078 static inline struct mbuf
*
1079 sonic_get(struct sn_softc
*sc
, void *pkt
, int datalen
)
1081 struct mbuf
*m
, *top
, **mp
;
1084 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
1087 m
->m_pkthdr
.rcvif
= &sc
->sc_if
;
1088 m
->m_pkthdr
.len
= datalen
;
1093 while (datalen
> 0) {
1095 MGET(m
, M_DONTWAIT
, MT_DATA
);
1102 if (datalen
>= MINCLSIZE
) {
1103 MCLGET(m
, M_DONTWAIT
);
1104 if ((m
->m_flags
& M_EXT
) == 0) {
1105 if (top
) m_freem(top
);
1112 char *newdata
= (char *)
1113 ALIGN((char *)m
->m_data
+
1114 sizeof(struct ether_header
)) -
1115 sizeof(struct ether_header
);
1116 len
-= newdata
- m
->m_data
;
1117 m
->m_data
= newdata
;
1120 m
->m_len
= len
= min(datalen
, len
);
1122 memcpy(mtod(m
, void *), pkt
, (unsigned) len
);
1123 pkt
= (char *)pkt
+ len
;