Use queue(3) macros for if_multiaddrs.
[dragonfly.git] / sys / dev / netif / le / if_le.c
CommitLineData
984263bc
MD
1/*-
2 * Copyright (c) 1994 Matt Thomas (thomas@lkg.dec.com)
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. The name of the author may not be used to endorse or promote products
11 * derived from this software withough specific prior written permission
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * $FreeBSD: src/sys/i386/isa/if_le.c,v 1.56.2.4 2002/06/05 23:24:10 paul Exp $
03df8a20 25 * $DragonFly: src/sys/dev/netif/le/if_le.c,v 1.26 2005/06/20 15:10:41 joerg Exp $
984263bc
MD
26 */
27
28/*
29 * DEC EtherWORKS 2 Ethernet Controllers
30 * DEC EtherWORKS 3 Ethernet Controllers
31 *
32 * Written by Matt Thomas
33 * BPF support code stolen directly from if_ec.c
34 *
35 * This driver supports the DEPCA, DE100, DE101, DE200, DE201,
36 * DE2002, DE203, DE204, DE205, and DE422 cards.
37 */
38
1f2de5d4 39#include "use_le.h"
984263bc
MD
40#include "opt_inet.h"
41#include "opt_ipx.h"
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/conf.h>
46#include <sys/mbuf.h>
47#include <sys/socket.h>
48#include <sys/sockio.h>
73dabe5e 49#include <sys/thread2.h>
984263bc 50#include <sys/malloc.h>
32832096
MD
51#include <sys/linker_set.h>
52#include <sys/module.h>
984263bc
MD
53
54#include <net/ethernet.h>
55#include <net/if.h>
6da7a95a 56#include <net/ifq_var.h>
984263bc
MD
57#include <net/if_types.h>
58#include <net/if_dl.h>
59
60#include <netinet/in.h>
61#include <netinet/if_ether.h>
62
1f2de5d4 63#include <bus/isa/i386/isa_device.h>
984263bc
MD
64#include <i386/isa/icu.h>
65
66#include <vm/vm.h>
67#include <vm/pmap.h>
68
69#include <net/bpf.h>
70
984263bc
MD
71typedef u_short le_mcbits_t;
72#define LE_MC_NBPW_LOG2 4
73#define LE_MC_NBPW (1 << LE_MC_NBPW_LOG2)
cee3a5f0
JS
74
75struct le_softc;
76
77struct le_board {
78 int (*bd_probe)(struct le_softc *sc, const struct le_board *bd, int *msize);
79};
80
984263bc
MD
81/*
82 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
83 *
84 * Start of DEC EtherWORKS III (LEMAC) dependent structures
85 *
86 */
87#include <i386/isa/ic/lemac.h> /* Include LEMAC definitions */
88
32832096
MD
89DECLARE_DUMMY_MODULE(if_le);
90
cee3a5f0 91static int lemac_probe(struct le_softc *sc, const struct le_board *bd, int *msize);
984263bc
MD
92
93struct le_lemac_info {
94 u_int lemac__lastpage; /* last 2K page */
95 u_int lemac__memmode; /* Are we in 2K, 32K, or 64K mode */
96 u_int lemac__membase; /* Physical address of start of RAM */
97 u_int lemac__txctl; /* Transmit Control Byte */
98 u_int lemac__txmax; /* Maximum # of outstanding transmits */
99 le_mcbits_t lemac__mctbl[LEMAC_MCTBL_SIZE/sizeof(le_mcbits_t)];
100 /* local copy of multicast table */
101 u_char lemac__eeprom[LEMAC_EEP_SIZE]; /* local copy eeprom */
102 char lemac__prodname[LEMAC_EEP_PRDNMSZ+1]; /* prodname name */
103#define lemac_lastpage le_un.un_lemac.lemac__lastpage
104#define lemac_memmode le_un.un_lemac.lemac__memmode
105#define lemac_membase le_un.un_lemac.lemac__membase
106#define lemac_txctl le_un.un_lemac.lemac__txctl
107#define lemac_txmax le_un.un_lemac.lemac__txmax
108#define lemac_mctbl le_un.un_lemac.lemac__mctbl
109#define lemac_eeprom le_un.un_lemac.lemac__eeprom
110#define lemac_prodname le_un.un_lemac.lemac__prodname
111};
cee3a5f0 112
984263bc
MD
113/*
114 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
115 *
116 * Start of DEC EtherWORKS II (LANCE) dependent structures
117 *
118 */
119
120#include <i386/isa/ic/am7990.h>
121
122#ifndef LN_DOSTATS
123#define LN_DOSTATS 1
124#endif
125
cee3a5f0 126static int depca_probe(struct le_softc *sc, const struct le_board *bd, int *msize);
984263bc
MD
127
128typedef struct lance_descinfo lance_descinfo_t;
129typedef struct lance_ring lance_ring_t;
130
131typedef unsigned lance_addr_t;
132
133struct lance_descinfo {
134 caddr_t di_addr; /* address of descriptor */
135 lance_addr_t di_bufaddr; /* LANCE address of buffer owned by descriptor */
136 unsigned di_buflen; /* size of buffer owned by descriptor */
137 struct mbuf *di_mbuf; /* mbuf being transmitted/received */
138};
139
140struct lance_ring {
141 lance_descinfo_t *ri_first; /* Pointer to first descriptor in ring */
142 lance_descinfo_t *ri_last; /* Pointer to last + 1 descriptor in ring */
143 lance_descinfo_t *ri_nextin; /* Pointer to next one to be given to HOST */
144 lance_descinfo_t *ri_nextout; /* Pointer to next one to be given to LANCE */
145 unsigned ri_max; /* Size of Ring - 1 */
146 unsigned ri_free; /* Number of free rings entires (owned by HOST) */
147 lance_addr_t ri_heap; /* Start of RAM for this ring */
148 lance_addr_t ri_heapend; /* End + 1 of RAM for this ring */
149 lance_addr_t ri_outptr; /* Pointer to first output byte */
150 unsigned ri_outsize; /* Space remaining for output */
151};
152
153struct le_lance_info {
154 unsigned lance__csr1; /* LANCE Address of init block (low 16) */
155 unsigned lance__csr2; /* LANCE Address of init block (high 8) */
156 unsigned lance__csr3; /* Copy of CSR3 */
157 unsigned lance__rap; /* IO Port Offset of RAP */
158 unsigned lance__rdp; /* IO Port Offset of RDP */
159 unsigned lance__ramoffset; /* Offset to valid LANCE RAM */
160 unsigned lance__ramsize; /* Amount of RAM shared by LANCE */
161 unsigned lance__rxbufsize; /* Size of a receive buffer */
162 ln_initb_t lance__initb; /* local copy of LANCE initblock */
163 ln_initb_t *lance__raminitb; /* copy to board's LANCE initblock (debugging) */
164 ln_desc_t *lance__ramdesc; /* copy to board's LANCE descriptors (debugging) */
165 lance_ring_t lance__rxinfo; /* Receive ring information */
166 lance_ring_t lance__txinfo; /* Transmit ring information */
167#define lance_csr1 le_un.un_lance.lance__csr1
168#define lance_csr2 le_un.un_lance.lance__csr2
169#define lance_csr3 le_un.un_lance.lance__csr3
170#define lance_rap le_un.un_lance.lance__rap
171#define lance_rdp le_un.un_lance.lance__rdp
172#define lance_ramoffset le_un.un_lance.lance__ramoffset
173#define lance_ramsize le_un.un_lance.lance__ramsize
174#define lance_rxbufsize le_un.un_lance.lance__rxbufsize
175#define lance_initb le_un.un_lance.lance__initb
176#define lance_raminitb le_un.un_lance.lance__raminitb
177#define lance_ramdesc le_un.un_lance.lance__ramdesc
178#define lance_rxinfo le_un.un_lance.lance__rxinfo
179#define lance_txinfo le_un.un_lance.lance__txinfo
180};
cee3a5f0 181
984263bc
MD
182/*
183 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
184 *
185 * Start of Common Code
186 *
187 */
188
cee3a5f0 189static void (*le_intrvec[NLE])(struct le_softc *sc);
984263bc
MD
190
191/*
192 * Ethernet status, per interface.
193 */
194struct le_softc {
195 struct arpcom le_ac; /* Common Ethernet/ARP Structure */
b5101a88 196 void (*if_init) (void *);/* Interface init routine */
cee3a5f0 197 void (*if_reset) (struct le_softc*);/* Interface reset routine */
984263bc
MD
198 caddr_t le_membase; /* Starting memory address (virtual) */
199 unsigned le_iobase; /* Starting I/O base address */
200 unsigned le_irq; /* Interrupt Request Value */
201 unsigned le_flags; /* local copy of if_flags */
202#define LE_BRDCSTONLY 0x01000000 /* If only broadcast is enabled */
203 u_int le_mcmask; /* bit mask for CRC-32 for multicast hash */
204 le_mcbits_t *le_mctbl; /* pointer to multicast table */
205 const char *le_prodname; /* product name DE20x-xx */
206 u_char le_hwaddr[6]; /* local copy of hwaddr */
207 union {
984263bc 208 struct le_lemac_info un_lemac; /* LEMAC specific information */
984263bc 209 struct le_lance_info un_lance; /* Am7990 specific information */
984263bc
MD
210 } le_un;
211};
212#define le_if le_ac.ac_if
213
214
215static int le_probe(struct isa_device *dvp);
216static int le_attach(struct isa_device *dvp);
217static ointhand2_t le_intr;
9974b71d
JS
218static int le_ioctl(struct ifnet *ifp, u_long command, caddr_t data,
219 struct ucred *cr);
cee3a5f0 220static void le_input(struct le_softc *sc, caddr_t seg1, size_t total_len,
984263bc 221 size_t len2, caddr_t seg2);
cee3a5f0
JS
222static void le_multi_filter(struct le_softc *sc);
223static void le_multi_op(struct le_softc *sc, const u_char *mca, int oper_flg);
224static int le_read_macaddr(struct le_softc *sc, int ioreg, int skippat);
984263bc 225
cee3a5f0 226static struct le_softc le_softc[NLE];
984263bc 227
cee3a5f0 228static const struct le_board le_boards[] = {
984263bc 229 { lemac_probe }, /* DE20[345] */
984263bc 230 { depca_probe }, /* DE{20[012],422} */
984263bc
MD
231 { NULL } /* Must Be Last! */
232};
233
234/*
235 * This tells the autoconf code how to set us up.
236 */
237struct isa_driver ledriver = {
238 le_probe, le_attach, "le",
239};
240
241static unsigned le_intrs[NLE];
242
ecabc716
JS
243#define LE_INL(sc, reg) inl((sc)->le_iobase + (reg))
244#define LE_OUTL(sc, reg, data) outl((sc)->le_iobase + (reg), data)
245#define LE_INW(sc, reg) inw((sc)->le_iobase + (reg))
246#define LE_OUTW(sc, reg, data) outw((sc)->le_iobase + (reg), data)
247#define LE_INB(sc, reg) inb((sc)->le_iobase + (reg))
248#define LE_OUTB(sc, reg, data) outb((sc)->le_iobase + (reg), data)
984263bc 249
984263bc 250static int
cee3a5f0 251le_probe(struct isa_device *dvp)
984263bc 252{
cee3a5f0
JS
253 struct le_softc *sc = &le_softc[dvp->id_unit];
254 const struct le_board *bd;
984263bc
MD
255 int iospace;
256
257 if (dvp->id_unit >= NLE) {
258 printf("%s%d not configured -- too many devices\n",
259 ledriver.name, dvp->id_unit);
260 return 0;
261 }
262
263 sc->le_iobase = dvp->id_iobase;
264 sc->le_membase = (u_char *) dvp->id_maddr;
265 sc->le_irq = dvp->id_irq;
3e4a09e7 266 if_initname(&(sc->le_if), ledriver.name, dvp->id_unit);
984263bc
MD
267
268 /*
269 * Find and Initialize board..
270 */
271
272 sc->le_flags &= ~(IFF_UP|IFF_ALLMULTI);
273
274 for (bd = le_boards; bd->bd_probe != NULL; bd++) {
275 if ((iospace = (*bd->bd_probe)(sc, bd, &dvp->id_msize)) != 0) {
276 return iospace;
277 }
278 }
279
280 return 0;
281}
cee3a5f0 282
984263bc 283static int
cee3a5f0 284le_attach(struct isa_device *dvp)
984263bc 285{
cee3a5f0 286 struct le_softc *sc = &le_softc[dvp->id_unit];
984263bc
MD
287 struct ifnet *ifp = &sc->le_if;
288
289 dvp->id_ointr = le_intr;
290 ifp->if_softc = sc;
291 ifp->if_mtu = ETHERMTU;
984263bc
MD
292
293 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
984263bc
MD
294 ifp->if_ioctl = le_ioctl;
295 ifp->if_type = IFT_ETHER;
296 ifp->if_addrlen = 6;
297 ifp->if_hdrlen = 14;
298 ifp->if_init = sc->if_init;
6da7a95a
JS
299 ifp->if_baudrate = 10000000;
300 ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
301 ifq_set_ready(&ifp->if_snd);
984263bc 302
0a8b5977 303 ether_ifattach(ifp, sc->le_ac.ac_enaddr);
984263bc
MD
304
305 return 1;
306}
cee3a5f0 307
984263bc 308static void
cee3a5f0 309le_intr(int unit)
984263bc 310{
984263bc
MD
311 le_intrs[unit]++;
312 (*le_intrvec[unit])(&le_softc[unit]);
984263bc
MD
313}
314
315#define LE_XTRA 0
316
317static void
cee3a5f0
JS
318le_input(struct le_softc *sc, caddr_t seg1, size_t total_len,
319 size_t len1, caddr_t seg2)
984263bc
MD
320{
321 struct ether_header eh;
322 struct mbuf *m;
323
324 if (total_len - sizeof(eh) > ETHERMTU
325 || total_len - sizeof(eh) < ETHERMIN) {
326 sc->le_if.if_ierrors++;
327 return;
328 }
56f37904 329 bcopy(seg1, &eh, ETHER_HDR_LEN);
984263bc 330
56f37904
JS
331 seg1 += ETHER_HDR_LEN;
332 total_len -= ETHER_HDR_LEN;
333 len1 -= ETHER_HDR_LEN;
984263bc 334
74f1caca 335 MGETHDR(m, MB_DONTWAIT, MT_DATA);
984263bc
MD
336 if (m == NULL) {
337 sc->le_if.if_ierrors++;
338 return;
339 }
340 m->m_pkthdr.len = total_len;
341 m->m_pkthdr.rcvif = &sc->le_if;
342 if (total_len + LE_XTRA > MHLEN /* >= MINCLSIZE */) {
74f1caca 343 MCLGET(m, MB_DONTWAIT);
984263bc
MD
344 if ((m->m_flags & M_EXT) == 0) {
345 m_free(m);
346 sc->le_if.if_ierrors++;
347 return;
348 }
349 } else if (total_len + LE_XTRA > MHLEN && MINCLSIZE == (MHLEN+MLEN)) {
74f1caca 350 MGET(m->m_next, MB_DONTWAIT, MT_DATA);
984263bc
MD
351 if (m->m_next == NULL) {
352 m_free(m);
353 sc->le_if.if_ierrors++;
354 return;
355 }
356 m->m_next->m_len = total_len - MHLEN - LE_XTRA;
357 len1 = total_len = MHLEN - LE_XTRA;
56f37904 358 bcopy(&seg1[MHLEN-LE_XTRA], mtod(m->m_next, caddr_t), m->m_next->m_len);
984263bc
MD
359 } else if (total_len + LE_XTRA > MHLEN) {
360 panic("le_input: pkt of unknown length");
361 }
362 m->m_data += LE_XTRA;
363 m->m_len = total_len;
56f37904 364 bcopy(seg1, mtod(m, caddr_t), len1);
984263bc 365 if (seg2 != NULL)
56f37904 366 bcopy(seg2, mtod(m, caddr_t) + len1, total_len - len1);
984263bc
MD
367 ether_input(&sc->le_if, &eh, m);
368}
cee3a5f0 369
984263bc 370static int
9974b71d 371le_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
984263bc 372{
cee3a5f0 373 struct le_softc *sc = ifp->if_softc;
73dabe5e 374 int error = 0;
984263bc
MD
375
376 if ((sc->le_flags & IFF_UP) == 0)
377 return EIO;
378
73dabe5e 379 crit_enter();
984263bc
MD
380
381 switch (cmd) {
984263bc
MD
382 case SIOCSIFFLAGS: {
383 sc->if_init(sc);
384 break;
385 }
386
387 case SIOCADDMULTI:
388 case SIOCDELMULTI:
389 /*
390 * Update multicast listeners
391 */
392 sc->if_init(sc);
393 error = 0;
394 break;
395
4cde4dd5
JS
396 default:
397 error = ether_ioctl(ifp, cmd, data);
398 break;
984263bc
MD
399 }
400
73dabe5e
JS
401 crit_exit();
402
984263bc
MD
403 return error;
404}
cee3a5f0 405
984263bc
MD
406/*
407 * This is the standard method of reading the DEC Address ROMS.
408 * I don't understand it but it does work.
409 */
410static int
cee3a5f0 411le_read_macaddr(struct le_softc *sc, int ioreg, int skippat)
984263bc
MD
412{
413 int cksum, rom_cksum;
414
415 if (!skippat) {
416 int idx, idx2, found, octet;
417 static u_char testpat[] = { 0xFF, 0, 0x55, 0xAA, 0xFF, 0, 0x55, 0xAA };
418 idx2 = found = 0;
419
420 for (idx = 0; idx < 32; idx++) {
421 octet = LE_INB(sc, ioreg);
422
423 if (octet == testpat[idx2]) {
424 if (++idx2 == sizeof testpat) {
425 ++found;
426 break;
427 }
428 } else {
429 idx2 = 0;
430 }
431 }
432
433 if (!found)
434 return -1;
435 }
436
437 cksum = 0;
438 sc->le_hwaddr[0] = LE_INB(sc, ioreg);
439 sc->le_hwaddr[1] = LE_INB(sc, ioreg);
440
441 cksum = *(u_short *) &sc->le_hwaddr[0];
442
443 sc->le_hwaddr[2] = LE_INB(sc, ioreg);
444 sc->le_hwaddr[3] = LE_INB(sc, ioreg);
445 cksum *= 2;
446 if (cksum > 65535) cksum -= 65535;
447 cksum += *(u_short *) &sc->le_hwaddr[2];
448 if (cksum > 65535) cksum -= 65535;
449
450 sc->le_hwaddr[4] = LE_INB(sc, ioreg);
451 sc->le_hwaddr[5] = LE_INB(sc, ioreg);
452 cksum *= 2;
453 if (cksum > 65535) cksum -= 65535;
454 cksum += *(u_short *) &sc->le_hwaddr[4];
455 if (cksum >= 65535) cksum -= 65535;
456
457 rom_cksum = LE_INB(sc, ioreg);
458 rom_cksum |= LE_INB(sc, ioreg) << 8;
459
460 if (cksum != rom_cksum)
461 return -1;
462 return 0;
463}
cee3a5f0 464
984263bc 465static void
cee3a5f0 466le_multi_filter(struct le_softc *sc)
984263bc 467{
c401f0fd 468 struct ifnet *ifp = &sc->le_ac.ac_if;
984263bc
MD
469 struct ifmultiaddr *ifma;
470
56f37904 471 bzero(sc->le_mctbl, (sc->le_mcmask + 1) / 8);
984263bc
MD
472
473 if (sc->le_if.if_flags & IFF_ALLMULTI) {
474 sc->le_flags |= IFF_MULTICAST|IFF_ALLMULTI;
475 return;
476 }
477 sc->le_flags &= ~IFF_MULTICAST;
478 /* if (interface has had an address assigned) { */
c401f0fd 479 le_multi_op(sc, ifp->if_broadcastaddr, TRUE);
984263bc
MD
480 sc->le_flags |= LE_BRDCSTONLY|IFF_MULTICAST;
481 /* } */
482
483 sc->le_flags |= IFF_MULTICAST;
484
03df8a20 485 LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
984263bc
MD
486 if (ifma->ifma_addr->sa_family != AF_LINK)
487 continue;
488
489 le_multi_op(sc, LLADDR((struct sockaddr_dl *)ifma->ifma_addr), 1);
490 sc->le_flags &= ~LE_BRDCSTONLY;
491 }
492}
cee3a5f0 493
984263bc 494static void
cee3a5f0 495le_multi_op(struct le_softc *sc, const u_char *mca, int enable)
984263bc 496{
02d187be
JS
497 uint32_t bit, idx, crc;
498
499 crc = ether_crc32_le(mca, ETHER_ADDR_LEN);
984263bc 500
984263bc
MD
501 /*
502 * The following two line convert the N bit index into a longword index
503 * and a longword mask.
504 */
505 crc &= sc->le_mcmask;
506 bit = 1 << (crc & (LE_MC_NBPW -1));
507 idx = crc >> (LE_MC_NBPW_LOG2);
508
509 /*
510 * Set or clear hash filter bit in our table.
511 */
512 if (enable) {
513 sc->le_mctbl[idx] |= bit; /* Set Bit */
514 } else {
515 sc->le_mctbl[idx] &= ~bit; /* Clear Bit */
516 }
517}
cee3a5f0 518
984263bc
MD
519/*
520 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
521 *
522 * Start of DEC EtherWORKS III (LEMAC) dependent code
523 *
524 */
525
526#define LEMAC_INTR_ENABLE(sc) \
527 LE_OUTB(sc, LEMAC_REG_IC, LE_INB(sc, LEMAC_REG_IC) | LEMAC_IC_ALL)
528
529#define LEMAC_INTR_DISABLE(sc) \
530 LE_OUTB(sc, LEMAC_REG_IC, LE_INB(sc, LEMAC_REG_IC) & ~LEMAC_IC_ALL)
531
532#define LEMAC_64K_MODE(mbase) (((mbase) >= 0x0A) && ((mbase) <= 0x0F))
533#define LEMAC_32K_MODE(mbase) (((mbase) >= 0x14) && ((mbase) <= 0x1F))
534#define LEMAC_2K_MODE(mbase) ( (mbase) >= 0x40)
535
cee3a5f0
JS
536static void lemac_init(void *xsc);
537static void lemac_start(struct ifnet *ifp);
538static void lemac_reset(struct le_softc *sc);
539static void lemac_intr(struct le_softc *sc);
540static void lemac_rne_intr(struct le_softc *sc);
541static void lemac_tne_intr(struct le_softc *sc);
542static void lemac_txd_intr(struct le_softc *sc, unsigned cs_value);
543static void lemac_rxd_intr(struct le_softc *sc, unsigned cs_value);
544static int lemac_read_eeprom(struct le_softc *sc);
545static void lemac_init_adapmem(struct le_softc *sc);
984263bc
MD
546
547#define LE_MCBITS_ALL_1S ((le_mcbits_t)~(le_mcbits_t)0)
548
549static const le_mcbits_t lemac_allmulti_mctbl[16] = {
550 LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S,
551 LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S,
552 LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S,
553 LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S,
554};
555/*
556 * An IRQ mapping table. Less space than switch statement.
557 */
558static const int lemac_irqs[] = { IRQ5, IRQ10, IRQ11, IRQ15 };
559
560/*
561 * Some tuning/monitoring variables.
562 */
563static unsigned lemac_deftxmax = 16; /* see lemac_max above */
564static unsigned lemac_txnospc = 0; /* total # of tranmit starvations */
565
566static unsigned lemac_tne_intrs = 0; /* total # of tranmit done intrs */
567static unsigned lemac_rne_intrs = 0; /* total # of receive done intrs */
568static unsigned lemac_txd_intrs = 0; /* total # of tranmit error intrs */
569static unsigned lemac_rxd_intrs = 0; /* total # of receive error intrs */
984263bc
MD
570
571static int
cee3a5f0 572lemac_probe(struct le_softc *sc, const struct le_board *bd, int *msize)
984263bc
MD
573{
574 int irq, portval;
575
576 LE_OUTB(sc, LEMAC_REG_IOP, LEMAC_IOP_EEINIT);
577 DELAY(LEMAC_EEP_DELAY);
578
579 /*
580 * Read Ethernet address if card is present.
581 */
582 if (le_read_macaddr(sc, LEMAC_REG_APD, 0) < 0)
583 return 0;
584
56f37904 585 bcopy(sc->le_hwaddr, sc->le_ac.ac_enaddr, ETHER_ADDR_LEN);
984263bc
MD
586 /*
587 * Clear interrupts and set IRQ.
588 */
589
590 portval = LE_INB(sc, LEMAC_REG_IC) & LEMAC_IC_IRQMSK;
591 irq = lemac_irqs[portval >> 5];
592 LE_OUTB(sc, LEMAC_REG_IC, portval);
593
594 /*
595 * Make sure settings match.
596 */
597
598 if (irq != sc->le_irq) {
cee3a5f0
JS
599 if_printf(&sc->le_if, "lemac configuration error: expected IRQ 0x%x actual 0x%x\n",
600 sc->le_irq, irq);
984263bc
MD
601 return 0;
602 }
603
604 /*
605 * Try to reset the unit
606 */
607 sc->if_init = lemac_init;
608 sc->le_if.if_start = lemac_start;
609 sc->if_reset = lemac_reset;
610 sc->lemac_memmode = 2;
611 sc->if_reset(sc);
612 if ((sc->le_flags & IFF_UP) == 0)
613 return 0;
614
615 /*
616 * Check for correct memory base configuration.
617 */
618 if (vtophys(sc->le_membase) != sc->lemac_membase) {
cee3a5f0 619 if_printf(&sc->le_if, "lemac configuration error: expected iomem 0x%llx actual 0x%x\n",
984263bc
MD
620 vtophys(sc->le_membase), sc->lemac_membase);
621 return 0;
622 }
623
624 sc->le_prodname = sc->lemac_prodname;
625 sc->le_mctbl = sc->lemac_mctbl;
626 sc->le_mcmask = (1 << LEMAC_MCTBL_BITS) - 1;
627 sc->lemac_txmax = lemac_deftxmax;
628 *msize = 2048;
3e4a09e7 629 le_intrvec[sc->le_if.if_dunit] = lemac_intr;
984263bc
MD
630
631 return LEMAC_IOSPACE;
632}
cee3a5f0 633
984263bc
MD
634/*
635 * Do a hard reset of the board;
636 */
637static void
cee3a5f0 638lemac_reset(struct le_softc *sc)
984263bc 639{
cee3a5f0 640 struct ifnet *ifp = &sc->le_if;
984263bc
MD
641 int portval, cksum;
642
643 /*
644 * Initialize board..
645 */
646
647 sc->le_flags &= IFF_UP;
cee3a5f0 648 ifp->if_flags &= ~IFF_OACTIVE;
984263bc
MD
649 LEMAC_INTR_DISABLE(sc);
650
651 LE_OUTB(sc, LEMAC_REG_IOP, LEMAC_IOP_EEINIT);
652 DELAY(LEMAC_EEP_DELAY);
653
654 /* Disable Interrupts */
655 /* LE_OUTB(sc, LEMAC_REG_IC, LE_INB(sc, LEMAC_REG_IC) & ICR_IRQ_SEL); */
656
657 /*
658 * Read EEPROM information. NOTE - the placement of this function
659 * is important because functions hereafter may rely on information
660 * read from the EEPROM.
661 */
662 if ((cksum = lemac_read_eeprom(sc)) != LEMAC_EEP_CKSUM) {
cee3a5f0 663 if_printf(ifp, "reset: EEPROM checksum failed (0x%x)\n", cksum);
984263bc
MD
664 return;
665 }
666
667 /*
668 * Force to 2K mode if not already configured.
669 */
670
671 portval = LE_INB(sc, LEMAC_REG_MBR);
672 if (!LEMAC_2K_MODE(portval)) {
673 if (LEMAC_64K_MODE(portval)) {
674 portval = (((portval * 2) & 0xF) << 4);
675 sc->lemac_memmode = 64;
676 } else if (LEMAC_32K_MODE(portval)) {
677 portval = ((portval & 0xF) << 4);
678 sc->lemac_memmode = 32;
679 }
680 LE_OUTB(sc, LEMAC_REG_MBR, portval);
681 }
682 sc->lemac_membase = portval * (2 * 1024) + (512 * 1024);
683
684 /*
685 * Initialize Free Memory Queue, Init mcast table with broadcast.
686 */
687
688 lemac_init_adapmem(sc);
689 sc->le_flags |= IFF_UP;
984263bc 690}
cee3a5f0 691
984263bc 692static void
cee3a5f0 693lemac_init(void *xsc)
984263bc 694{
cee3a5f0 695 struct le_softc *sc = (struct le_softc *)xsc;
984263bc
MD
696
697 if ((sc->le_flags & IFF_UP) == 0)
698 return;
699
73dabe5e 700 crit_enter();
984263bc
MD
701
702 /*
703 * If the interface has the up flag
704 */
705 if (sc->le_if.if_flags & IFF_UP) {
706 int saved_cs = LE_INB(sc, LEMAC_REG_CS);
707 LE_OUTB(sc, LEMAC_REG_CS, saved_cs | (LEMAC_CS_TXD | LEMAC_CS_RXD));
708 LE_OUTB(sc, LEMAC_REG_PA0, sc->le_ac.ac_enaddr[0]);
709 LE_OUTB(sc, LEMAC_REG_PA1, sc->le_ac.ac_enaddr[1]);
710 LE_OUTB(sc, LEMAC_REG_PA2, sc->le_ac.ac_enaddr[2]);
711 LE_OUTB(sc, LEMAC_REG_PA3, sc->le_ac.ac_enaddr[3]);
712 LE_OUTB(sc, LEMAC_REG_PA4, sc->le_ac.ac_enaddr[4]);
713 LE_OUTB(sc, LEMAC_REG_PA5, sc->le_ac.ac_enaddr[5]);
714
715 LE_OUTB(sc, LEMAC_REG_IC, LE_INB(sc, LEMAC_REG_IC) | LEMAC_IC_IE);
716
717 if (sc->le_if.if_flags & IFF_PROMISC) {
718 LE_OUTB(sc, LEMAC_REG_CS, LEMAC_CS_MCE | LEMAC_CS_PME);
719 } else {
720 LEMAC_INTR_DISABLE(sc);
721 le_multi_filter(sc);
722 LE_OUTB(sc, LEMAC_REG_MPN, 0);
723 if ((sc->le_flags | sc->le_if.if_flags) & IFF_ALLMULTI) {
56f37904 724 bcopy(lemac_allmulti_mctbl, &sc->le_membase[LEMAC_MCTBL_OFF], sizeof(lemac_allmulti_mctbl));
984263bc 725 } else {
56f37904 726 bcopy(sc->lemac_mctbl, &sc->le_membase[LEMAC_MCTBL_OFF], sizeof(sc->lemac_mctbl));
984263bc
MD
727 }
728 LE_OUTB(sc, LEMAC_REG_CS, LEMAC_CS_MCE);
729 }
730
731 LE_OUTB(sc, LEMAC_REG_CTL, LE_INB(sc, LEMAC_REG_CTL) ^ LEMAC_CTL_LED);
732
733 LEMAC_INTR_ENABLE(sc);
734 sc->le_if.if_flags |= IFF_RUNNING;
735 } else {
736 LE_OUTB(sc, LEMAC_REG_CS, LEMAC_CS_RXD|LEMAC_CS_TXD);
737
738 LEMAC_INTR_DISABLE(sc);
739 sc->le_if.if_flags &= ~IFF_RUNNING;
740 }
73dabe5e
JS
741
742 crit_exit();
984263bc 743}
cee3a5f0 744
984263bc
MD
745/*
746 * What to do upon receipt of an interrupt.
747 */
748static void
cee3a5f0 749lemac_intr(struct le_softc *sc)
984263bc
MD
750{
751 int cs_value;
752
753 LEMAC_INTR_DISABLE(sc); /* Mask interrupts */
754
755 /*
756 * Determine cause of interrupt. Receive events take
757 * priority over Transmit.
758 */
759
760 cs_value = LE_INB(sc, LEMAC_REG_CS);
761
762 /*
763 * Check for Receive Queue not being empty.
764 * Check for Transmit Done Queue not being empty.
765 */
766
767 if (cs_value & LEMAC_CS_RNE)
768 lemac_rne_intr(sc);
769 if (cs_value & LEMAC_CS_TNE)
770 lemac_tne_intr(sc);
771
772 /*
773 * Check for Transmitter Disabled.
774 * Check for Receiver Disabled.
775 */
776
777 if (cs_value & LEMAC_CS_TXD)
778 lemac_txd_intr(sc, cs_value);
779 if (cs_value & LEMAC_CS_RXD)
780 lemac_rxd_intr(sc, cs_value);
781
782 /*
783 * Toggle LED and unmask interrupts.
784 */
785
786 LE_OUTB(sc, LEMAC_REG_CTL, LE_INB(sc, LEMAC_REG_CTL) ^ LEMAC_CTL_LED);
787 LEMAC_INTR_ENABLE(sc); /* Unmask interrupts */
788}
cee3a5f0 789
984263bc 790static void
cee3a5f0 791lemac_rne_intr(struct le_softc *sc)
984263bc
MD
792{
793 int rxcount, rxlen, rxpg;
794 u_char *rxptr;
795
796 lemac_rne_intrs++;
797 rxcount = LE_INB(sc, LEMAC_REG_RQC);
798 while (rxcount--) {
799 rxpg = LE_INB(sc, LEMAC_REG_RQ);
800 LE_OUTB(sc, LEMAC_REG_MPN, rxpg);
801
802 rxptr = sc->le_membase;
803 sc->le_if.if_ipackets++;
804 if (*rxptr & LEMAC_RX_OK) {
805
806 /*
807 * Get receive length - subtract out checksum.
808 */
809
810 rxlen = ((*(u_int *)rxptr >> 8) & 0x7FF) - 4;
811 le_input(sc, rxptr + sizeof(u_int), rxlen, rxlen, NULL);
812 } else { /* end if (*rxptr & LEMAC_RX_OK) */
813 sc->le_if.if_ierrors++;
814 }
815 LE_OUTB(sc, LEMAC_REG_FMQ, rxpg); /* Return this page to Free Memory Queue */
816 } /* end while (recv_count--) */
984263bc 817}
cee3a5f0 818
984263bc 819static void
cee3a5f0 820lemac_rxd_intr(struct le_softc *sc, unsigned cs_value)
984263bc
MD
821{
822 /*
823 * Handle CS_RXD (Receiver disabled) here.
824 *
825 * Check Free Memory Queue Count. If not equal to zero
826 * then just turn Receiver back on. If it is equal to
827 * zero then check to see if transmitter is disabled.
828 * Process transmit TXD loop once more. If all else
829 * fails then do software init (0xC0 to EEPROM Init)
830 * and rebuild Free Memory Queue.
831 */
832
833 lemac_rxd_intrs++;
834
835 /*
836 * Re-enable Receiver.
837 */
838
839 cs_value &= ~LEMAC_CS_RXD;
840 LE_OUTB(sc, LEMAC_REG_CS, cs_value);
841
842 if (LE_INB(sc, LEMAC_REG_FMC) > 0)
843 return;
844
845 if (cs_value & LEMAC_CS_TXD)
846 lemac_txd_intr(sc, cs_value);
847
848 if ((LE_INB(sc, LEMAC_REG_CS) & LEMAC_CS_RXD) == 0)
849 return;
850
cee3a5f0 851 if_printf(&sc->le_if, "fatal RXD error, attempting recovery\n");
984263bc
MD
852
853 sc->if_reset(sc);
854 if (sc->le_flags & IFF_UP) {
855 lemac_init(sc);
856 return;
857 }
858
859 /*
860 * Error during initializion. Mark card as disabled.
861 */
cee3a5f0 862 if_printf(&sc->le_if, "recovery failed -- board disabled\n");
984263bc 863}
cee3a5f0 864
984263bc 865static void
cee3a5f0 866lemac_start(struct ifnet *ifp)
984263bc 867{
cee3a5f0 868 struct le_softc *sc = (struct le_softc *) ifp;
984263bc
MD
869
870 if ((ifp->if_flags & IFF_RUNNING) == 0)
871 return;
872
873 LEMAC_INTR_DISABLE(sc);
874
6da7a95a 875 while (!ifq_is_empty(&ifp->if_snd)) {
984263bc
MD
876 struct mbuf *m;
877 int tx_pg;
878 u_int txhdr, txoff;
879
880 if (LE_INB(sc, LEMAC_REG_TQC) >= sc->lemac_txmax) {
881 ifp->if_flags |= IFF_OACTIVE;
882 break;
883 }
884
885 tx_pg = LE_INB(sc, LEMAC_REG_FMQ); /* get free memory page */
886 /*
887 * Check for good transmit page.
888 */
889 if (tx_pg == 0 || tx_pg > sc->lemac_lastpage) {
890 lemac_txnospc++;
891 ifp->if_flags |= IFF_OACTIVE;
892 break;
893 }
894
6da7a95a 895 m = ifq_dequeue(&ifp->if_snd);
984263bc
MD
896 LE_OUTB(sc, LEMAC_REG_MPN, tx_pg); /* Shift 2K window. */
897
898 /*
899 * The first four bytes of each transmit buffer are for
900 * control information. The first byte is the control
901 * byte, then the length (why not word aligned?), then
902 * the off to the buffer.
903 */
904
905 txoff = (mtod(m, u_int) & (sizeof(u_long) - 1)) + LEMAC_TX_HDRSZ;
906 txhdr = sc->lemac_txctl | (m->m_pkthdr.len << 8) | (txoff << 24);
907 *(u_int *) sc->le_membase = txhdr;
908
909 /*
910 * Copy the packet to the board
911 */
912
913 m_copydata(m, 0, m->m_pkthdr.len, sc->le_membase + txoff);
914
915 LE_OUTB(sc, LEMAC_REG_TQ, tx_pg); /* tell chip to transmit this packet */
916
235af63d 917 BPF_MTAP(ifp, m);
984263bc
MD
918
919 m_freem(m); /* free the mbuf */
920 }
921 LEMAC_INTR_ENABLE(sc);
922}
cee3a5f0 923
984263bc 924static void
cee3a5f0 925lemac_tne_intr(struct le_softc *sc)
984263bc
MD
926{
927 int txsts, txcount = LE_INB(sc, LEMAC_REG_TDC);
928
929 lemac_tne_intrs++;
930 while (txcount--) {
931 txsts = LE_INB(sc, LEMAC_REG_TDQ);
932 sc->le_if.if_opackets++; /* another one done */
933 if ((txsts & LEMAC_TDQ_COL) != LEMAC_TDQ_NOCOL)
934 sc->le_if.if_collisions++;
935 }
936 sc->le_if.if_flags &= ~IFF_OACTIVE;
937 lemac_start(&sc->le_if);
938}
939
940static void
cee3a5f0 941lemac_txd_intr(struct le_softc *sc, unsigned cs_value)
984263bc
MD
942{
943 /*
944 * Read transmit status, remove transmit buffer from
945 * transmit queue and place on free memory queue,
946 * then reset transmitter.
947 * Increment appropriate counters.
948 */
949
950 lemac_txd_intrs++;
951 sc->le_if.if_oerrors++;
952 if (LE_INB(sc, LEMAC_REG_TS) & LEMAC_TS_ECL)
953 sc->le_if.if_collisions++;
954 sc->le_if.if_flags &= ~IFF_OACTIVE;
955
956 LE_OUTB(sc, LEMAC_REG_FMQ, LE_INB(sc, LEMAC_REG_TQ));
957 /* Get Page number and write it back out */
958
959 LE_OUTB(sc, LEMAC_REG_CS, cs_value & ~LEMAC_CS_TXD);
960 /* Turn back on transmitter */
984263bc 961}
cee3a5f0 962
984263bc 963static int
cee3a5f0 964lemac_read_eeprom(struct le_softc *sc)
984263bc
MD
965{
966 int word_off, cksum;
967
968 u_char *ep;
969
970 cksum = 0;
971 ep = sc->lemac_eeprom;
972 for (word_off = 0; word_off < LEMAC_EEP_SIZE / 2; word_off++) {
973 LE_OUTB(sc, LEMAC_REG_PI1, word_off);
974 LE_OUTB(sc, LEMAC_REG_IOP, LEMAC_IOP_EEREAD);
975
976 DELAY(LEMAC_EEP_DELAY);
977
978 *ep = LE_INB(sc, LEMAC_REG_EE1); cksum += *ep++;
979 *ep = LE_INB(sc, LEMAC_REG_EE2); cksum += *ep++;
980 }
981
982 /*
983 * Set up Transmit Control Byte for use later during transmit.
984 */
985
986 sc->lemac_txctl |= LEMAC_TX_FLAGS;
987
988 if ((sc->lemac_eeprom[LEMAC_EEP_SWFLAGS] & LEMAC_EEP_SW_SQE) == 0)
989 sc->lemac_txctl &= ~LEMAC_TX_SQE;
990
991 if (sc->lemac_eeprom[LEMAC_EEP_SWFLAGS] & LEMAC_EEP_SW_LAB)
992 sc->lemac_txctl |= LEMAC_TX_LAB;
993
56f37904 994 bcopy(&sc->lemac_eeprom[LEMAC_EEP_PRDNM], sc->lemac_prodname, LEMAC_EEP_PRDNMSZ);
984263bc
MD
995 sc->lemac_prodname[LEMAC_EEP_PRDNMSZ] = '\0';
996
997 return cksum % 256;
998}
cee3a5f0 999
984263bc 1000static void
cee3a5f0 1001lemac_init_adapmem(struct le_softc *sc)
984263bc
MD
1002{
1003 int pg, conf;
1004
1005 conf = LE_INB(sc, LEMAC_REG_CNF);
1006
1007 if ((sc->lemac_eeprom[LEMAC_EEP_SETUP] & LEMAC_EEP_ST_DRAM) == 0) {
1008 sc->lemac_lastpage = 63;
1009 conf &= ~LEMAC_CNF_DRAM;
1010 } else {
1011 sc->lemac_lastpage = 127;
1012 conf |= LEMAC_CNF_DRAM;
1013 }
1014
1015 LE_OUTB(sc, LEMAC_REG_CNF, conf);
1016
1017 for (pg = 1; pg <= sc->lemac_lastpage; pg++)
1018 LE_OUTB(sc, LEMAC_REG_FMQ, pg);
1019
1020 return;
1021}
cee3a5f0 1022
984263bc
MD
1023/*
1024 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1025 *
1026 * Start of DEPCA (DE200/DE201/DE202/DE422 etal) support.
1027 *
1028 */
cee3a5f0
JS
1029static void depca_intr(struct le_softc *sc);
1030static int lance_init_adapmem(struct le_softc *sc);
1031static int lance_init_ring(struct le_softc *sc, ln_ring_t *rp, lance_ring_t *ri,
984263bc
MD
1032 unsigned ndescs, unsigned bufoffset,
1033 unsigned descoffset);
1034static void lance_init(void *xsc);
cee3a5f0
JS
1035static void lance_reset(struct le_softc *sc);
1036static void lance_intr(struct le_softc *sc);
1037static int lance_rx_intr(struct le_softc *sc);
984263bc 1038static void lance_start(struct ifnet *ifp);
cee3a5f0 1039static int lance_tx_intr(struct le_softc *sc);
984263bc
MD
1040
1041#define LN_BUFSIZE /* 380 */ 304 /* 1520 / 4 */
1042#define LN_TXDESC_RATIO 2048
1043#define LN_DESC_MAX 128
1044
1045#if LN_DOSTATS
1046static struct {
1047 unsigned lance_rx_misses;
1048 unsigned lance_rx_badcrc;
1049 unsigned lance_rx_badalign;
1050 unsigned lance_rx_badframe;
1051 unsigned lance_rx_buferror;
1052 unsigned lance_tx_deferred;
1053 unsigned lance_tx_single_collisions;
1054 unsigned lance_tx_multiple_collisions;
1055 unsigned lance_tx_excessive_collisions;
1056 unsigned lance_tx_late_collisions;
1057
1058 unsigned lance_memory_errors;
1059 unsigned lance_inits;
1060 unsigned lance_tx_intrs;
1061 unsigned lance_tx_nospc[2];
1062 unsigned lance_tx_drains[2];
1063 unsigned lance_tx_orphaned;
1064 unsigned lance_tx_adoptions;
1065 unsigned lance_tx_emptied;
1066 unsigned lance_tx_deftxint;
1067 unsigned lance_tx_buferror;
1068 unsigned lance_high_txoutptr;
1069 unsigned lance_low_txheapsize;
1070 unsigned lance_low_txfree;
1071 unsigned lance_tx_intr_hidescs;
1072 /* unsigned lance_tx_intr_descs[LN_DESC_MAX]; */
1073
1074 unsigned lance_rx_intrs;
1075 unsigned lance_rx_badsop;
1076 unsigned lance_rx_contig;
1077 unsigned lance_rx_noncontig;
1078 unsigned lance_rx_intr_hidescs;
1079 unsigned lance_rx_ndescs[4096 / LN_BUFSIZE];
1080 /* unsigned lance_rx_intr_descs[LN_DESC_MAX]; */
1081} lance_stats;
1082
1083#define LN_STAT(stat) (lance_stats.lance_ ## stat)
1084#define LN_MINSTAT(stat, val) (LN_STAT(stat > (val)) ? LN_STAT(stat = (val)) : 0)
1085#define LN_MAXSTAT(stat, val) (LN_STAT(stat < (val)) ? LN_STAT(stat = (val)) : 0)
1086
1087#else
1088#define LN_STAT(stat) 0
1089#define LN_MINSTAT(stat, val) 0
1090#define LN_MAXSTAT(stat, val) 0
1091#endif
1092
1093#define LN_SELCSR(sc, csrno) (LE_OUTW(sc, sc->lance_rap, csrno))
1094#define LN_INQCSR(sc) (LE_INW(sc, sc->lance_rap))
1095
1096#define LN_WRCSR(sc, val) (LE_OUTW(sc, sc->lance_rdp, val))
1097#define LN_RDCSR(sc) (LE_INW(sc, sc->lance_rdp))
1098
1099
1100#define LN_ZERO(sc, vaddr, len) bzero(vaddr, len)
1101#define LN_COPYTO(sc, from, to, len) bcopy(from, to, len)
1102
1103#define LN_SETFLAG(sc, vaddr, val) \
1104 (((volatile u_char *) vaddr)[3] = (val))
1105
1106#define LN_PUTDESC(sc, desc, vaddr) \
1107 (((volatile u_short *) vaddr)[0] = ((u_short *) desc)[0], \
1108 ((volatile u_short *) vaddr)[2] = ((u_short *) desc)[2], \
1109 ((volatile u_short *) vaddr)[1] = ((u_short *) desc)[1])
1110
1111/*
1112 * Only get the descriptor flags and length/status. All else
1113 * read-only.
1114 */
1115#define LN_GETDESC(sc, desc, vaddr) \
1116 (((u_short *) desc)[1] = ((volatile u_short *) vaddr)[1], \
1117 ((u_short *) desc)[3] = ((volatile u_short *) vaddr)[3])
1118
984263bc
MD
1119/*
1120 * These definitions are specific to the DEC "DEPCA-style" NICs.
1121 * (DEPCA, DE10x, DE20[012], DE422)
1122 *
1123 */
1124#define DEPCA_REG_NICSR 0 /* (RW;16) NI Control / Status */
1125#define DEPCA_REG_RDP 4 /* (RW:16) LANCE RDP (data) register */
1126#define DEPCA_REG_RAP 6 /* (RW:16) LANCE RAP (address) register */
1127#define DEPCA_REG_ADDRROM 12 /* (R : 8) DEPCA Ethernet Address ROM */
1128#define DEPCA_IOSPACE 16 /* DEPCAs use 16 bytes of IO space */
1129
1130#define DEPCA_NICSR_LED 0x0001 /* Light the LED on the back of the DEPCA */
1131#define DEPCA_NICSR_ENABINTR 0x0002 /* Enable Interrupts */
1132#define DEPCA_NICSR_MASKINTR 0x0004 /* Mask Interrupts */
1133#define DEPCA_NICSR_AAC 0x0008 /* Address Counter Clear */
1134#define DEPCA_NICSR_REMOTEBOOT 0x0010 /* Remote Boot Enabled (ignored) */
1135#define DEPCA_NICSR_32KRAM 0x0020 /* DEPCA LANCE RAM size 64K (C) / 32K (S) */
1136#define DEPCA_NICSR_LOW32K 0x0040 /* Bank Select (A15 = !This Bit) */
1137#define DEPCA_NICSR_SHE 0x0080 /* Shared RAM Enabled (ie hide ROM) */
1138#define DEPCA_NICSR_BOOTTMO 0x0100 /* Remote Boot Timeout (ignored) */
1139
1140#define DEPCA_RDNICSR(sc) (LE_INW(sc, DEPCA_REG_NICSR))
1141#define DEPCA_WRNICSR(sc, val) (LE_OUTW(sc, DEPCA_REG_NICSR, val))
1142
1143#define DEPCA_IDSTR_OFFSET 0xC006 /* ID String Offset */
1144
1145#define DEPCA_REG_EISAID 0x80
1146#define DEPCA_EISAID_MASK 0xf0ffffff
1147#define DEPCA_EISAID_DE422 0x2042A310
1148
1149typedef enum {
1150 DEPCA_CLASSIC,
1151 DEPCA_DE100, DEPCA_DE101,
1152 DEPCA_EE100,
1153 DEPCA_DE200, DEPCA_DE201, DEPCA_DE202,
1154 DEPCA_DE422,
1155 DEPCA_UNKNOWN
1156} depca_t;
1157
1158static const char *depca_signatures[] = {
1159 "DEPCA",
1160 "DE100", "DE101",
1161 "EE100",
1162 "DE200", "DE201", "DE202",
1163 "DE422",
1164 NULL
1165};
cee3a5f0 1166
984263bc 1167static int
cee3a5f0 1168depca_probe(struct le_softc *sc, const struct le_board *bd, int *msize)
984263bc
MD
1169{
1170 unsigned nicsr, idx, idstr_offset = DEPCA_IDSTR_OFFSET;
1171
1172 /*
1173 * Find out how memory we are dealing with. Adjust
1174 * the ID string offset approriately if we are at
1175 * 32K. Make sure the ROM is enabled.
1176 */
1177 nicsr = DEPCA_RDNICSR(sc);
1178 nicsr &= ~(DEPCA_NICSR_SHE|DEPCA_NICSR_LED|DEPCA_NICSR_ENABINTR);
1179
1180 if (nicsr & DEPCA_NICSR_32KRAM) {
1181 /*
1182 * Make we are going to read the upper
1183 * 32K so we do read the ROM.
1184 */
1185 sc->lance_ramsize = 32 * 1024;
1186 nicsr &= ~DEPCA_NICSR_LOW32K;
1187 sc->lance_ramoffset = 32 * 1024;
1188 idstr_offset -= sc->lance_ramsize;
1189 } else {
1190 sc->lance_ramsize = 64 * 1024;
1191 sc->lance_ramoffset = 0;
1192 }
1193 DEPCA_WRNICSR(sc, nicsr);
1194
1195 sc->le_prodname = NULL;
1196 for (idx = 0; depca_signatures[idx] != NULL; idx++) {
1197 if (bcmp(depca_signatures[idx], sc->le_membase + idstr_offset, 5) == 0) {
1198 sc->le_prodname = depca_signatures[idx];
1199 break;
1200 }
1201 }
1202
1203 if (sc->le_prodname == NULL) {
1204 /*
1205 * Try to get the EISA device if it's a DE422.
1206 */
1207 if (sc->le_iobase > 0x1000 && (sc->le_iobase & 0x0F00) == 0x0C00
1208 && (LE_INL(sc, DEPCA_REG_EISAID) & DEPCA_EISAID_MASK)
1209 == DEPCA_EISAID_DE422) {
1210 sc->le_prodname = "DE422";
1211 } else {
1212 return 0;
1213 }
1214 }
1215 if (idx == DEPCA_CLASSIC)
1216 sc->lance_ramsize -= 16384; /* Can't use the ROM area on a DEPCA */
1217
1218 /*
1219 * Try to read the address ROM.
1220 * Stop the LANCE, reset the Address ROM Counter (AAC),
1221 * read the NICSR to "clock" in the reset, and then
1222 * re-enable the Address ROM Counter. Now read the
1223 * address ROM.
1224 */
1225 sc->lance_rdp = DEPCA_REG_RDP;
1226 sc->lance_rap = DEPCA_REG_RAP;
1227 sc->lance_csr3 = LN_CSR3_ALE;
1228 sc->le_mctbl = sc->lance_initb.ln_multi_mask;
1229 sc->le_mcmask = LN_MC_MASK;
1230 LN_SELCSR(sc, LN_CSR0);
1231 LN_WRCSR(sc, LN_CSR0_STOP);
1232
1233 if (idx < DEPCA_DE200) {
1234 DEPCA_WRNICSR(sc, DEPCA_RDNICSR(sc) & ~DEPCA_NICSR_AAC);
1235 DEPCA_WRNICSR(sc, DEPCA_RDNICSR(sc) | DEPCA_NICSR_AAC);
1236 }
1237
1238 if (le_read_macaddr(sc, DEPCA_REG_ADDRROM, idx == DEPCA_CLASSIC) < 0)
1239 return 0;
1240
56f37904 1241 bcopy(sc->le_hwaddr, sc->le_ac.ac_enaddr, ETHER_ADDR_LEN);
984263bc
MD
1242 /*
1243 * Renable shared RAM.
1244 */
1245 DEPCA_WRNICSR(sc, DEPCA_RDNICSR(sc) | DEPCA_NICSR_SHE);
1246
3e4a09e7 1247 le_intrvec[sc->le_if.if_dunit] = depca_intr;
984263bc
MD
1248 if (!lance_init_adapmem(sc))
1249 return 0;
1250
1251 sc->if_reset = lance_reset;
1252 sc->if_init = lance_init;
1253 sc->le_if.if_start = lance_start;
1254 DEPCA_WRNICSR(sc, DEPCA_NICSR_SHE | DEPCA_NICSR_ENABINTR);
1255 sc->if_reset(sc);
1256
1257 LN_STAT(low_txfree = sc->lance_txinfo.ri_max);
1258 LN_STAT(low_txheapsize = 0xFFFFFFFF);
1259 *msize = sc->lance_ramsize;
1260 return DEPCA_IOSPACE;
1261}
1262
1263static void
cee3a5f0 1264depca_intr(struct le_softc *sc)
984263bc
MD
1265{
1266 DEPCA_WRNICSR(sc, DEPCA_RDNICSR(sc) ^ DEPCA_NICSR_LED);
1267 lance_intr(sc);
1268}
cee3a5f0 1269
984263bc
MD
1270/*
1271 * Here's as good a place to describe our paritioning of the
1272 * LANCE shared RAM space. (NOTE: this driver does not yet support
1273 * the concept of a LANCE being able to DMA).
1274 *
1275 * First is the 24 (00:23) bytes for LANCE Initialization Block
1276 * Next are the recieve descriptors. The number is calculated from
1277 * how many LN_BUFSIZE buffers we can allocate (this number must
1278 * be a power of 2). Next are the transmit descriptors. The amount
1279 * of transmit descriptors is derived from the size of the RAM
1280 * divided by 1K. Now come the receive buffers (one for each receive
1281 * descriptor). Finally is the transmit heap. (no fixed buffers are
1282 * allocated so as to make the most use of the limited space).
1283 */
1284static int
cee3a5f0 1285lance_init_adapmem(struct le_softc *sc)
984263bc
MD
1286{
1287 lance_addr_t rxbufoffset;
1288 lance_addr_t rxdescoffset, txdescoffset;
1289 unsigned rxdescs, txdescs;
1290
1291 /*
1292 * First calculate how many descriptors we heap.
1293 * Note this assumes the ramsize is a power of two.
1294 */
1295 sc->lance_rxbufsize = LN_BUFSIZE;
1296 rxdescs = 1;
1297 while (rxdescs * sc->lance_rxbufsize < sc->lance_ramsize)
1298 rxdescs *= 2;
1299 rxdescs /= 2;
1300 if (rxdescs > LN_DESC_MAX) {
1301 sc->lance_rxbufsize *= rxdescs / LN_DESC_MAX;
1302 rxdescs = LN_DESC_MAX;
1303 }
1304 txdescs = sc->lance_ramsize / LN_TXDESC_RATIO;
1305 if (txdescs > LN_DESC_MAX)
1306 txdescs = LN_DESC_MAX;
1307
1308 /*
1309 * Now calculate where everything goes in memory
1310 */
1311 rxdescoffset = sizeof(ln_initb_t);
1312 txdescoffset = rxdescoffset + sizeof(ln_desc_t) * rxdescs;
1313 rxbufoffset = txdescoffset + sizeof(ln_desc_t) * txdescs;
1314
1315 sc->le_mctbl = (le_mcbits_t *) sc->lance_initb.ln_multi_mask;
1316 /*
1317 * Remember these for debugging.
1318 */
1319 sc->lance_raminitb = (ln_initb_t *) sc->le_membase;
1320 sc->lance_ramdesc = (ln_desc_t *) (sc->le_membase + rxdescoffset);
1321
1322 /*
1323 * Initialize the rings.
1324 */
1325 if (!lance_init_ring(sc, &sc->lance_initb.ln_rxring, &sc->lance_rxinfo,
1326 rxdescs, rxbufoffset, rxdescoffset))
1327 return 0;
1328 sc->lance_rxinfo.ri_heap = rxbufoffset;
1329 sc->lance_rxinfo.ri_heapend = rxbufoffset + sc->lance_rxbufsize * rxdescs;
1330
1331 if (!lance_init_ring(sc, &sc->lance_initb.ln_txring, &sc->lance_txinfo,
1332 txdescs, 0, txdescoffset))
1333 return 0;
1334 sc->lance_txinfo.ri_heap = sc->lance_rxinfo.ri_heapend;
1335 sc->lance_txinfo.ri_heapend = sc->lance_ramsize;
1336
1337 /*
1338 * Set CSR1 and CSR2 to the address of the init block (which
1339 * for us is always 0.
1340 */
1341 sc->lance_csr1 = LN_ADDR_LO(0 + sc->lance_ramoffset);
1342 sc->lance_csr2 = LN_ADDR_HI(0 + sc->lance_ramoffset);
1343 return 1;
1344}
cee3a5f0 1345
984263bc 1346static int
cee3a5f0
JS
1347lance_init_ring(struct le_softc *sc, ln_ring_t *rp, lance_ring_t *ri,
1348 unsigned ndescs, lance_addr_t bufoffset, lance_addr_t descoffset)
984263bc
MD
1349{
1350 lance_descinfo_t *di;
1351
1352 /*
1353 * Initialize the ring pointer in the LANCE InitBlock
1354 */
1355 rp->r_addr_lo = LN_ADDR_LO(descoffset + sc->lance_ramoffset);
1356 rp->r_addr_hi = LN_ADDR_HI(descoffset + sc->lance_ramoffset);
1357 rp->r_log2_size = ffs(ndescs) - 1;
1358
1359 /*
1360 * Allocate the ring entry descriptors and initialize
1361 * our ring information data structure. All these are
1362 * our copies and do not live in the LANCE RAM.
1363 */
c5541aee 1364 ri->ri_first = malloc(ndescs * sizeof(*di), M_DEVBUF, M_WAITOK);
984263bc
MD
1365 ri->ri_free = ri->ri_max = ndescs;
1366 ri->ri_last = ri->ri_first + ri->ri_max;
1367 for (di = ri->ri_first; di < ri->ri_last; di++) {
1368 di->di_addr = sc->le_membase + descoffset;
1369 di->di_mbuf = NULL;
1370 if (bufoffset) {
1371 di->di_bufaddr = bufoffset;
1372 di->di_buflen = sc->lance_rxbufsize;
1373 bufoffset += sc->lance_rxbufsize;
1374 }
1375 descoffset += sizeof(ln_desc_t);
1376 }
1377 return 1;
1378}
cee3a5f0 1379
984263bc 1380static void
cee3a5f0 1381lance_dumpcsrs(struct le_softc *sc, const char *id)
984263bc 1382{
cee3a5f0
JS
1383 if_printf(&sc->le_if, "%s: nicsr=%04x", id, DEPCA_RDNICSR(sc));
1384 LN_SELCSR(sc, LN_CSR0);
1385 printf(" csr0=%04x", LN_RDCSR(sc));
1386 LN_SELCSR(sc, LN_CSR1);
1387 printf(" csr1=%04x", LN_RDCSR(sc));
1388 LN_SELCSR(sc, LN_CSR2);
1389 printf(" csr2=%04x", LN_RDCSR(sc));
1390 LN_SELCSR(sc, LN_CSR3);
1391 printf(" csr3=%04x\n", LN_RDCSR(sc));
984263bc
MD
1392 LN_SELCSR(sc, LN_CSR0);
1393}
1394
1395static void
cee3a5f0 1396lance_reset(struct le_softc *sc)
984263bc 1397{
c9faf524 1398 int cnt, csr;
984263bc
MD
1399
1400 /* lance_dumpcsrs(sc, "lance_reset: start"); */
1401
1402 LN_WRCSR(sc, LN_RDCSR(sc) & ~LN_CSR0_ENABINTR);
1403 LN_WRCSR(sc, LN_CSR0_STOP);
1404 DELAY(100);
1405
1406 sc->le_flags &= ~IFF_UP;
1407 sc->le_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
1408
1409 le_multi_filter(sc); /* initialize the multicast table */
1410 if ((sc->le_flags | sc->le_if.if_flags) & IFF_ALLMULTI) {
1411 sc->lance_initb.ln_multi_mask[0] = 0xFFFFU;
1412 sc->lance_initb.ln_multi_mask[1] = 0xFFFFU;
1413 sc->lance_initb.ln_multi_mask[2] = 0xFFFFU;
1414 sc->lance_initb.ln_multi_mask[3] = 0xFFFFU;
1415 }
1416 sc->lance_initb.ln_physaddr[0] = ((u_short *) sc->le_ac.ac_enaddr)[0];
1417 sc->lance_initb.ln_physaddr[1] = ((u_short *) sc->le_ac.ac_enaddr)[1];
1418 sc->lance_initb.ln_physaddr[2] = ((u_short *) sc->le_ac.ac_enaddr)[2];
1419 if (sc->le_if.if_flags & IFF_PROMISC) {
1420 sc->lance_initb.ln_mode |= LN_MODE_PROMISC;
1421 } else {
1422 sc->lance_initb.ln_mode &= ~LN_MODE_PROMISC;
1423 }
1424 /*
1425 * We force the init block to be at the start
1426 * of the LANCE's RAM buffer.
1427 */
1428 LN_COPYTO(sc, &sc->lance_initb, sc->le_membase, sizeof(sc->lance_initb));
1429 LN_SELCSR(sc, LN_CSR1); LN_WRCSR(sc, sc->lance_csr1);
1430 LN_SELCSR(sc, LN_CSR2); LN_WRCSR(sc, sc->lance_csr2);
1431 LN_SELCSR(sc, LN_CSR3); LN_WRCSR(sc, sc->lance_csr3);
1432
1433 /* lance_dumpcsrs(sc, "lance_reset: preinit"); */
1434
1435 /*
1436 * clear INITDONE and INIT the chip
1437 */
1438 LN_SELCSR(sc, LN_CSR0);
1439 LN_WRCSR(sc, LN_CSR0_INIT|LN_CSR0_INITDONE);
1440
1441 csr = 0;
1442 cnt = 100;
1443 while (cnt-- > 0) {
1444 if (((csr = LN_RDCSR(sc)) & LN_CSR0_INITDONE) != 0)
1445 break;
1446 DELAY(10000);
1447 }
1448
1449 if ((csr & LN_CSR0_INITDONE) == 0) { /* make sure we got out okay */
1450 lance_dumpcsrs(sc, "lance_reset: reset failure");
1451 } else {
1452 /* lance_dumpcsrs(sc, "lance_reset: end"); */
1453 sc->le_if.if_flags |= IFF_UP;
1454 sc->le_flags |= IFF_UP;
1455 }
1456}
cee3a5f0 1457
984263bc 1458static void
cee3a5f0 1459lance_init(void *xsc)
984263bc 1460{
cee3a5f0 1461 struct le_softc *sc = (struct le_softc *)xsc;
984263bc
MD
1462 lance_ring_t *ri;
1463 lance_descinfo_t *di;
1464 ln_desc_t desc;
1465
1466 LN_STAT(inits++);
1467 if (sc->le_if.if_flags & IFF_RUNNING) {
1468 sc->if_reset(sc);
1469 lance_tx_intr(sc);
1470 /*
6da7a95a 1471 * If we were running, abort any pending transmits.
984263bc
MD
1472 */
1473 ri = &sc->lance_txinfo;
1474 di = ri->ri_nextout;
1475 while (ri->ri_free < ri->ri_max) {
1476 if (--di == ri->ri_first)
1477 di = ri->ri_nextout - 1;
1478 if (di->di_mbuf == NULL)
1479 break;
6da7a95a 1480 m_free(di->di_mbuf);
984263bc
MD
1481 di->di_mbuf = NULL;
1482 ri->ri_free++;
1483 }
1484 } else {
1485 sc->if_reset(sc);
1486 }
1487
1488 /*
1489 * Reset the transmit ring. Make sure we own all the buffers.
1490 * Also reset the transmit heap.
1491 */
1492 sc->le_if.if_flags &= ~IFF_OACTIVE;
1493 ri = &sc->lance_txinfo;
1494 for (di = ri->ri_first; di < ri->ri_last; di++) {
1495 if (di->di_mbuf != NULL) {
1496 m_freem(di->di_mbuf);
1497 di->di_mbuf = NULL;
1498 }
1499 desc.d_flag = 0;
1500 desc.d_addr_lo = LN_ADDR_LO(ri->ri_heap + sc->lance_ramoffset);
1501 desc.d_addr_hi = LN_ADDR_HI(ri->ri_heap + sc->lance_ramoffset);
1502 desc.d_buflen = 0;
1503 LN_PUTDESC(sc, &desc, di->di_addr);
1504 }
1505 ri->ri_nextin = ri->ri_nextout = ri->ri_first;
1506 ri->ri_free = ri->ri_max;
1507 ri->ri_outptr = ri->ri_heap;
1508 ri->ri_outsize = ri->ri_heapend - ri->ri_heap;
1509
1510 ri = &sc->lance_rxinfo;
1511 desc.d_flag = LN_DFLAG_OWNER;
1512 desc.d_buflen = 0 - sc->lance_rxbufsize;
1513 for (di = ri->ri_first; di < ri->ri_last; di++) {
1514 desc.d_addr_lo = LN_ADDR_LO(di->di_bufaddr + sc->lance_ramoffset);
1515 desc.d_addr_hi = LN_ADDR_HI(di->di_bufaddr + sc->lance_ramoffset);
1516 LN_PUTDESC(sc, &desc, di->di_addr);
1517 }
1518 ri->ri_nextin = ri->ri_nextout = ri->ri_first;
1519 ri->ri_outptr = ri->ri_heap;
1520 ri->ri_outsize = ri->ri_heapend - ri->ri_heap;
1521 ri->ri_free = 0;
1522
1523 if (sc->le_if.if_flags & IFF_UP) {
1524 sc->le_if.if_flags |= IFF_RUNNING;
1525 LN_WRCSR(sc, LN_CSR0_START|LN_CSR0_INITDONE|LN_CSR0_ENABINTR);
1526 /* lance_dumpcsrs(sc, "lance_init: up"); */
1527 lance_start(&sc->le_if);
1528 } else {
1529 /* lance_dumpcsrs(sc, "lance_init: down"); */
1530 sc->le_if.if_flags &= ~IFF_RUNNING;
1531 }
1532}
cee3a5f0 1533
984263bc 1534static void
cee3a5f0 1535lance_intr(struct le_softc *sc)
984263bc
MD
1536{
1537 unsigned oldcsr;
1538
1539 oldcsr = LN_RDCSR(sc);
1540 oldcsr &= ~LN_CSR0_ENABINTR;
1541 LN_WRCSR(sc, oldcsr);
1542 LN_WRCSR(sc, LN_CSR0_ENABINTR);
1543
1544 if (oldcsr & LN_CSR0_ERRSUM) {
1545 if (oldcsr & LN_CSR0_MISS) {
1546 /*
1547 * LN_CSR0_MISS is signaled when the LANCE receiver
1548 * loses a packet because it doesn't own a receive
1549 * descriptor. Rev. D LANCE chips, which are no
1550 * longer used, require a chip reset as described
1551 * below.
1552 */
1553 LN_STAT(rx_misses++);
1554 }
1555 if (oldcsr & LN_CSR0_MEMERROR) {
1556 LN_STAT(memory_errors++);
1557 if (oldcsr & (LN_CSR0_RXON|LN_CSR0_TXON)) {
1558 lance_init(sc);
1559 return;
1560 }
1561 }
1562 }
1563
1564 if ((oldcsr & LN_CSR0_RXINT) && lance_rx_intr(sc)) {
1565 lance_init(sc);
1566 return;
1567 }
1568
1569 if (oldcsr & LN_CSR0_TXINT) {
1570 if (lance_tx_intr(sc))
1571 lance_start(&sc->le_if);
1572 }
1573
1574 if (oldcsr == (LN_CSR0_PENDINTR|LN_CSR0_RXON|LN_CSR0_TXON))
cee3a5f0 1575 if_printf(&sc->le_if, "lance_intr: stray interrupt\n");
984263bc 1576}
cee3a5f0 1577
984263bc 1578static int
cee3a5f0 1579lance_rx_intr(struct le_softc *sc)
984263bc
MD
1580{
1581 lance_ring_t *ri = &sc->lance_rxinfo;
1582 lance_descinfo_t *eop;
1583 ln_desc_t desc;
1584 int ndescs, total_len, rxdescs;
1585
1586 LN_STAT(rx_intrs++);
1587
1588 for (rxdescs = 0;;) {
1589 /*
1590 * Now to try to find the end of this packet chain.
1591 */
1592 for (ndescs = 1, eop = ri->ri_nextin;; ndescs++) {
1593 /*
1594 * If we don't own this descriptor, the packet ain't
1595 * all here so return because we are done.
1596 */
1597 LN_GETDESC(sc, &desc, eop->di_addr);
1598 if (desc.d_flag & LN_DFLAG_OWNER)
1599 return 0;
1600 /*
1601 * In case we have missed a packet and gotten the
1602 * LANCE confused, make sure we are pointing at the
1603 * start of a packet. If we aren't, something is really
1604 * strange so reinit the LANCE.
1605 */
1606 if (desc.d_flag & LN_DFLAG_RxBUFERROR) {
1607 LN_STAT(rx_buferror++);
1608 return 1;
1609 }
1610 if ((desc.d_flag & LN_DFLAG_SOP) && eop != ri->ri_nextin) {
1611 LN_STAT(rx_badsop++);
1612 return 1;
1613 }
1614 if (desc.d_flag & LN_DFLAG_EOP)
1615 break;
1616 if (++eop == ri->ri_last)
1617 eop = ri->ri_first;
1618 }
1619
1620 total_len = (desc.d_status & LN_DSTS_RxLENMASK) - 4;
1621 if ((desc.d_flag & LN_DFLAG_RxERRSUM) == 0) {
1622 /*
1623 * Valid Packet -- If the SOP is less than or equal to the EOP
1624 * or the length is less than the receive buffer size, then the
1625 * packet is contiguous in memory and can be copied in one shot.
1626 * Otherwise we need to copy two segments to get the entire
1627 * packet.
1628 */
1629 if (ri->ri_nextin <= eop || total_len <= ri->ri_heapend - ri->ri_nextin->di_bufaddr) {
1630 le_input(sc, sc->le_membase + ri->ri_nextin->di_bufaddr,
1631 total_len, total_len, NULL);
1632 LN_STAT(rx_contig++);
1633 } else {
1634 le_input(sc, sc->le_membase + ri->ri_nextin->di_bufaddr,
1635 total_len,
1636 ri->ri_heapend - ri->ri_nextin->di_bufaddr,
1637 sc->le_membase + ri->ri_first->di_bufaddr);
1638 LN_STAT(rx_noncontig++);
1639 }
1640 } else {
1641 /*
1642 * If the packet is bad, increment the
1643 * counters.
1644 */
1645 sc->le_if.if_ierrors++;
1646 if (desc.d_flag & LN_DFLAG_RxBADCRC)
1647 LN_STAT(rx_badcrc++);
1648 if (desc.d_flag & LN_DFLAG_RxOVERFLOW)
1649 LN_STAT(rx_badalign++);
1650 if (desc.d_flag & LN_DFLAG_RxFRAMING)
1651 LN_STAT(rx_badframe++);
1652 }
1653 sc->le_if.if_ipackets++;
1654 LN_STAT(rx_ndescs[ndescs-1]++);
1655 rxdescs += ndescs;
1656 while (ndescs-- > 0) {
1657 LN_SETFLAG(sc, ri->ri_nextin->di_addr, LN_DFLAG_OWNER);
1658 if (++ri->ri_nextin == ri->ri_last)
1659 ri->ri_nextin = ri->ri_first;
1660 }
1661 }
1662 /* LN_STAT(rx_intr_descs[rxdescs]++); */
1663 LN_MAXSTAT(rx_intr_hidescs, rxdescs);
1664
1665 return 0;
1666}
cee3a5f0 1667
984263bc 1668static void
cee3a5f0 1669lance_start(struct ifnet *ifp)
984263bc 1670{
cee3a5f0 1671 struct le_softc *sc = (struct le_softc *) ifp;
984263bc
MD
1672 lance_ring_t *ri = &sc->lance_txinfo;
1673 lance_descinfo_t *di;
1674 ln_desc_t desc;
1675 unsigned len, slop;
1676 struct mbuf *m, *m0;
1677 caddr_t bp;
1678
1679 if ((ifp->if_flags & IFF_RUNNING) == 0)
1680 return;
1681
1682 for (;;) {
6da7a95a 1683 m = ifq_poll(&ifp->if_snd);
984263bc
MD
1684 if (m == NULL)
1685 break;
1686
1687 /*
1688 * Make the packet meets the minimum size for Ethernet.
1689 * The slop is so that we also use an even number of longwards.
1690 */
1691 len = ETHERMIN + sizeof(struct ether_header);
1692 if (m->m_pkthdr.len > len)
1693 len = m->m_pkthdr.len;
1694
1695 slop = (8 - len) & 3;
1696 /*
1697 * If there are no free ring entries (there must be always
1698 * one owned by the host), or there's not enough space for
1699 * this packet, or this packet would wrap around the end
1700 * of LANCE RAM then wait for the transmits to empty for
1701 * space and ring entries to become available.
1702 */
1703 if (ri->ri_free == 1 || len + slop > ri->ri_outsize) {
1704 /*
1705 * Try to see if we can free up anything off the transit ring.
1706 */
1707 if (lance_tx_intr(sc) > 0) {
1708 LN_STAT(tx_drains[0]++);
984263bc
MD
1709 continue;
1710 }
1711 LN_STAT(tx_nospc[0]++);
1712 break;
1713 }
1714
1715 if (len + slop > ri->ri_heapend - ri->ri_outptr) {
1716 /*
1717 * Since the packet won't fit in the end of the transmit
1718 * heap, see if there is space at the beginning of the transmit
1719 * heap. If not, try again when there is space.
1720 */
1721 LN_STAT(tx_orphaned++);
1722 slop += ri->ri_heapend - ri->ri_outptr;
1723 if (len + slop > ri->ri_outsize) {
1724 LN_STAT(tx_nospc[1]++);
1725 break;
1726 }
1727 /*
1728 * Point to the beginning of the heap
1729 */
1730 ri->ri_outptr = ri->ri_heap;
1731 LN_STAT(tx_adoptions++);
1732 }
1733
1734 /*
1735 * Initialize the descriptor (saving the buffer address,
1736 * buffer length, and mbuf) and write the packet out
1737 * to the board.
1738 */
1739 di = ri->ri_nextout;
1740 di->di_bufaddr = ri->ri_outptr;
1741 di->di_buflen = len + slop;
1742 di->di_mbuf = m;
1743 bp = sc->le_membase + di->di_bufaddr;
1744 for (m0 = m; m0 != NULL; m0 = m0->m_next) {
1745 LN_COPYTO(sc, mtod(m0, caddr_t), bp, m0->m_len);
1746 bp += m0->m_len;
1747 }
1748 /*
1749 * Zero out the remainder if needed (< ETHERMIN).
1750 */
1751 if (m->m_pkthdr.len < len)
1752 LN_ZERO(sc, bp, len - m->m_pkthdr.len);
1753
6da7a95a
JS
1754 m = ifq_dequeue(&ifp->if_snd);
1755
984263bc
MD
1756 /*
1757 * Finally, copy out the descriptor and tell the
1758 * LANCE to transmit!.
1759 */
1760 desc.d_buflen = 0 - len;
1761 desc.d_addr_lo = LN_ADDR_LO(di->di_bufaddr + sc->lance_ramoffset);
1762 desc.d_addr_hi = LN_ADDR_HI(di->di_bufaddr + sc->lance_ramoffset);
1763 desc.d_flag = LN_DFLAG_SOP|LN_DFLAG_EOP|LN_DFLAG_OWNER;
1764 LN_PUTDESC(sc, &desc, di->di_addr);
1765 LN_WRCSR(sc, LN_CSR0_TXDEMAND|LN_CSR0_ENABINTR);
1766
1767 /*
1768 * Do our bookkeeping with our transmit heap.
1769 * (if we wrap, point back to the beginning).
1770 */
1771 ri->ri_outptr += di->di_buflen;
1772 ri->ri_outsize -= di->di_buflen;
1773 LN_MAXSTAT(high_txoutptr, ri->ri_outptr);
1774 LN_MINSTAT(low_txheapsize, ri->ri_outsize);
1775
1776 if (ri->ri_outptr == ri->ri_heapend)
1777 ri->ri_outptr = ri->ri_heap;
1778
1779 ri->ri_free--;
1780 if (++ri->ri_nextout == ri->ri_last)
1781 ri->ri_nextout = ri->ri_first;
1782 LN_MINSTAT(low_txfree, ri->ri_free);
1783 }
6da7a95a 1784 if (m != NULL)
984263bc 1785 ifp->if_flags |= IFF_OACTIVE;
984263bc 1786}
cee3a5f0 1787
984263bc 1788static int
cee3a5f0 1789lance_tx_intr(struct le_softc *sc)
984263bc
MD
1790{
1791 lance_ring_t *ri = &sc->lance_txinfo;
1792 unsigned xmits;
1793
1794 LN_STAT(tx_intrs++);
1795 for (xmits = 0; ri->ri_free < ri->ri_max; ) {
1796 ln_desc_t desc;
1797
1798 LN_GETDESC(sc, &desc, ri->ri_nextin->di_addr);
1799 if (desc.d_flag & LN_DFLAG_OWNER)
1800 break;
1801
1802 if (desc.d_flag & (LN_DFLAG_TxONECOLL|LN_DFLAG_TxMULTCOLL))
1803 sc->le_if.if_collisions++;
1804 if (desc.d_flag & LN_DFLAG_TxDEFERRED)
1805 LN_STAT(tx_deferred++);
1806 if (desc.d_flag & LN_DFLAG_TxONECOLL)
1807 LN_STAT(tx_single_collisions++);
1808 if (desc.d_flag & LN_DFLAG_TxMULTCOLL)
1809 LN_STAT(tx_multiple_collisions++);
1810
1811 if (desc.d_flag & LN_DFLAG_TxERRSUM) {
1812 if (desc.d_status & (LN_DSTS_TxUNDERFLOW|LN_DSTS_TxBUFERROR|
1813 LN_DSTS_TxEXCCOLL|LN_DSTS_TxLATECOLL)) {
1814 if (desc.d_status & LN_DSTS_TxEXCCOLL) {
1815 unsigned tdr;
1816 LN_STAT(tx_excessive_collisions++);
1817 if ((tdr = (desc.d_status & LN_DSTS_TxTDRMASK)) > 0) {
1818 tdr *= 100;
cee3a5f0 1819 if_printf(&sc->le_if, "lance: warning: excessive collisions: TDR %dns (%d-%dm)\n",
984263bc
MD
1820 tdr, (tdr*99)/1000, (tdr*117)/1000);
1821 }
1822 }
1823 if (desc.d_status & LN_DSTS_TxBUFERROR)
1824 LN_STAT(tx_buferror++);
1825 sc->le_if.if_oerrors++;
1826 if ((desc.d_status & LN_DSTS_TxLATECOLL) == 0) {
1827 lance_init(sc);
1828 return 0;
1829 } else {
1830 LN_STAT(tx_late_collisions++);
1831 }
1832 }
1833 }
1834 m_freem(ri->ri_nextin->di_mbuf);
1835 ri->ri_nextin->di_mbuf = NULL;
1836 sc->le_if.if_opackets++;
1837 ri->ri_free++;
1838 ri->ri_outsize += ri->ri_nextin->di_buflen;
1839 if (++ri->ri_nextin == ri->ri_last)
1840 ri->ri_nextin = ri->ri_first;
1841 sc->le_if.if_flags &= ~IFF_OACTIVE;
1842 xmits++;
1843 }
1844 if (ri->ri_free == ri->ri_max)
1845 LN_STAT(tx_emptied++);
1846 /* LN_STAT(tx_intr_descs[xmits]++); */
1847 LN_MAXSTAT(tx_intr_hidescs, xmits);
1848 return xmits;
1849}