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