FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/if_zp.c
1 /*
2 * This code is based on
3 * (1) FreeBSD implementation on ISA/EISA Ethelink III by Herb Peyerl
4 * (2) Linux implementation on PCMCIA Etherlink III by David Hinds
5 * (3) FreeBSD implementation on PCMCIA IBM Ethernet Card I/II
6 * by David Greenman
7 * (4) RT-Mach implementation on PCMCIA/ISA/EISA Etherlink III
8 * by Seiji Murata
9 *
10 * Copyright (c) by HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>
11 * Copyright (c) by Seiji Murata <seiji@mt.cs.keio.ac.jp>
12 */
13 /*
14 * Copyright (c) 1993 Herb Peyerl <hpeyerl@novatel.ca>
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. The name of the author may not be used to endorse or promote products
23 * derived from this software without specific prior written permission
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 * From: if_ep.c,v 1.9 1994/01/25 10:46:29 deraadt Exp $
37 * $FreeBSD$
38 */
39 /*-
40 * TODO:
41 * [1] integrate into current if_ed.c
42 * [2] parse tuples to find out where to map the shared memory buffer,
43 * and what to write into the configuration register
44 * [3] move pcic-specific code into a separate module.
45 *
46 * Device driver for IBM PCMCIA Credit Card Adapter for Ethernet,
47 * if_ze.c
48 *
49 * Based on the Device driver for National Semiconductor DS8390 ethernet
50 * adapters by David Greenman. Modifications for PCMCIA by Keith Moore.
51 * Adapted for FreeBSD 1.1.5 by Jordan Hubbard.
52 *
53 * Currently supports only the IBM Credit Card Adapter for Ethernet, but
54 * could probably work with other PCMCIA cards also, if it were modified
55 * to get the locations of the PCMCIA configuration option register (COR)
56 * by parsing the configuration tuples, rather than by hard-coding in
57 * the value expected by IBM's card.
58 *
59 * Sources for data on the PCMCIA/IBM CCAE specific portions of the driver:
60 *
61 * [1] _Local Area Network Credit Card Adapters Technical Reference_,
62 * IBM Corp., SC30-3585-00, part # 33G9243.
63 * [2] "pre-alpha" PCMCIA support code for Linux by Barry Jaspan.
64 * [3] Intel 82536SL PC Card Interface Controller Data Sheet, Intel
65 * Order Number 290423-002
66 * [4] National Semiconductor DP83902A ST-NIC (tm) Serial Network
67 * Interface Controller for Twisted Pair data sheet.
68 *
69 *
70 * Copyright (C) 1993, David Greenman. This software may be used, modified,
71 * copied, distributed, and sold, in both source and binary form provided
72 * that the above copyright and these terms are retained. Under no
73 * circumstances is the author responsible for the proper functioning
74 * of this software, nor does the author assume any responsibility
75 * for damages incurred with its use.
76 */
77 /*======================================================================
78
79 A PCMCIA ethernet driver for the 3com 3c589 card.
80
81 Written by David Hinds, dhinds@allegro.stanford.edu
82
83 The network driver code is based on Donald Becker's 3c589 code:
84
85 Written 1994 by Donald Becker.
86 Copyright 1993 United States Government as represented by the
87 Director, National Security Agency. This software may be used and
88 distributed according to the terms of the GNU Public License,
89 incorporated herein by reference.
90 Donald Becker may be reached at becker@cesdis1.gsfc.nasa.gov
91
92 ======================================================================*/
93 /*
94 * I doubled delay loops in this file because it is not enough for some
95 * laptop machines' PCIC (especially, on my Chaplet ILFA 350 ^^;).
96 * HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>
97 */
98 /*
99 * Very small patch for IBM Ethernet PCMCIA Card II and IBM ThinkPad230Cs.
100 * ETO, Toshihisa <eto@osl.fujitsu.co.jp>
101 */
102
103 /* XXX don't mix different PCCARD support code. */
104 #include "card.h"
105 #include "pcic.h"
106 #if NCARD > 0 || NPCIC > 0
107 #include "opt_lint.h"
108 #ifdef COMPILING_LINT
109 static char const zpdummy[] = "code to use the includes of card.h and pcic.h";
110 #else
111 #error "Dedicated PCMCIA drivers and generic PCMCIA support can't be mixed"
112 #endif
113 #endif
114
115 #include "zp.h"
116
117 #include "bpfilter.h"
118 #include "opt_inet.h"
119 #include "opt_ipx.h"
120
121 #include <sys/param.h>
122 #if defined(__FreeBSD__)
123 #include <sys/systm.h>
124 #include <sys/conf.h>
125 #endif
126 #include <sys/mbuf.h>
127 #include <sys/socket.h>
128 #include <sys/sockio.h>
129 #include <sys/syslog.h>
130
131 #include <net/if.h>
132
133 #ifdef INET
134 #include <netinet/in.h>
135 #include <netinet/if_ether.h>
136 #endif
137
138 #ifdef IPX
139 #include <netipx/ipx.h>
140 #include <netipx/ipx_if.h>
141 #endif
142
143 #ifdef NS
144 #include <netns/ns.h>
145 #include <netns/ns_if.h>
146 #endif
147
148 #if NBPFILTER > 0
149 #include <net/bpf.h>
150 #endif
151
152 #include <machine/clock.h>
153 #include <machine/md_var.h>
154
155 #include <i386/isa/isa_device.h>
156 #include <i386/isa/if_zpreg.h>
157 #include <i386/isa/pcic.h>
158
159 #include "apm.h"
160 #if NAPM > 0
161 #include <machine/apm_bios.h>
162 #endif /* NAPM > 0 */
163
164
165 /*****************************************************************************
166 * Driver for Ethernet Adapter *
167 *****************************************************************************/
168 /*
169 * zp_softc: per line info and status
170 */
171 static struct zp_softc {
172 struct arpcom arpcom; /* Ethernet common part */
173 #define MAX_MBS 8 /* # of mbufs we keep around */
174 struct mbuf *mb[MAX_MBS]; /* spare mbuf storage. */
175 int next_mb; /* Which mbuf to use next. */
176 int last_mb; /* Last mbuf. */
177 int ep_io_addr; /* i/o bus address */
178 char ep_connectors; /* Connectors on this card. */
179 int tx_start_thresh;/* Current TX_start_thresh. */
180 char bus32bit; /* 32bit access possible */
181 u_short if_port;
182 u_char last_alive; /* information for reconfiguration */
183 u_char last_up; /* information for reconfiguration */
184 int slot; /* PCMCIA slot */
185 struct callout_handle ch; /* Callout handle for timeouts */
186 int buffill_pending;
187 #if NAPM > 0
188 struct apmhook s_hook; /* reconfiguration support */
189 struct apmhook r_hook; /* reconfiguration support */
190 #endif /* NAPM > 0 */
191 } zp_softc[NZP];
192
193 static int zpprobe __P((struct isa_device *));
194 static int zpattach __P((struct isa_device *));
195 static int zp_suspend __P((void *visa_dev));
196 static int zp_resume __P((void *visa_dev));
197 static int zpioctl __P((struct ifnet * ifp, u_long, caddr_t));
198 static u_short read_eeprom_data __P((int, int));
199
200 static void zpinit __P((int));
201 static ointhand2_t zpintr;
202 static void zpmbuffill __P((void *));
203 static void zpmbufempty __P((struct zp_softc *));
204 static void zpread __P((struct zp_softc *));
205 static void zpreset __P((int));
206 static void zpstart __P((struct ifnet *));
207 static void zpstop __P((int));
208 static void zpwatchdog __P((struct ifnet *));
209
210 struct isa_driver zpdriver = {
211 zpprobe,
212 zpattach,
213 "zp"
214 };
215 #define CARD_INFO "3Com Corporation~3C589"
216
217 static unsigned char card_info[256];
218
219 /*
220 * scan the card information structure looking for the version/product info
221 * tuple. when we find it, compare it to the string we are looking for.
222 * return 1 if we find it, 0 otherwise.
223 */
224
225 static int
226 zp_check_cis(unsigned char *scratch)
227 {
228 int i, j, k;
229
230 card_info[0] = '\0';
231 i = 0;
232 while (scratch[i] != 0xff && i < 1024) {
233 unsigned char link = scratch[i + 2];
234
235 if (scratch[i] == 0x15) {
236 /* level 1 version/product info copy to card_info,
237 * translating '\0' to '~' */
238 k = 0;
239 for (j = i + 8; scratch[j] != 0xff; j += 2)
240 card_info[k++] = scratch[j] == '\0' ? '~' : scratch[j];
241 card_info[k++] = '\0';
242 return (bcmp(card_info, CARD_INFO, sizeof(CARD_INFO) - 1) == 0);
243 }
244 i += 4 + 2 * link;
245 }
246 return 0;
247 }
248 /*
249 * Probe each slot looking for an IBM Credit Card Adapter for Ethernet
250 * For each card that we find, map its card information structure
251 * into system memory at 'scratch' and see whether it's one of ours.
252 * Return the slot number if we find a card, or -1 otherwise.
253 *
254 * Side effects:
255 * + On success, leaves CIS mapped into memory at 'scratch';
256 * caller must free it.
257 * + On success, leaves ethernet address in enet_addr.
258 * + Leaves product/vendor id of last card probed in 'card_info'
259 */
260
261 static int prev_slot = 0;
262
263 static int
264 zp_find_adapter(unsigned char *scratch, int reconfig)
265 {
266 int slot;
267
268 for (slot = prev_slot; slot < MAXSLOT; ++slot) {
269 /* see if there's a PCMCIA controller here Intel PCMCIA
270 * controllers use 0x82 and 0x83 IBM clone chips use 0x88 and
271 * 0x89, apparently */
272 /* IBM ThinkPad230Cs use 0x84. */
273 unsigned char idbyte = pcic_getb(slot, PCIC_ID_REV);
274
275 if (idbyte != 0x82 && idbyte != 0x83 &&
276 idbyte != 0x84 && /* for IBM ThinkPad 230Cs */
277 idbyte != 0x88 && idbyte != 0x89) {
278 continue;
279 }
280 if ((pcic_getb(slot, PCIC_STATUS) & PCIC_CD) != PCIC_CD) {
281 if (!reconfig) {
282 printf("zp: slot %d: no card in slot\n", slot);
283 } else {
284 log(LOG_NOTICE, "zp: slot %d: no card in slot\n", slot);
285 }
286 /* no card in slot */
287 continue;
288 }
289 pcic_power_on(slot);
290 pcic_reset(slot);
291 DELAY(50000);
292 /* map the card's attribute memory and examine its card
293 * information structure tuples for something we recognize. */
294 pcic_map_memory(slot, 0, kvtop(scratch), 0L,
295 0xFFFL, ATTRIBUTE, 1);
296
297 if ((zp_check_cis(scratch)) > 0) {
298 /* found it */
299 if (!reconfig) {
300 printf("zp: found card in slot %d\n", slot);
301 } else {
302 log(LOG_NOTICE, "zp: found card in slot %d\n", slot);
303 }
304 prev_slot = (prev_slot == MAXSLOT - 1) ? 0 : prev_slot + 1;
305
306 return slot;
307 } else {
308 if (!reconfig) {
309 printf("zp: pcmcia slot %d: %s\n", slot, card_info);
310 } else {
311 log(LOG_NOTICE, "zp: pcmcia slot %d: %s\n", slot, card_info);
312 }
313 }
314 pcic_unmap_memory(slot, 0);
315 }
316 prev_slot = 0;
317 return -1;
318 }
319
320
321 /*
322 * macros to handle casting unsigned long to (char *) so we can
323 * read/write into physical memory space.
324 */
325
326 #define PEEK(addr) (*((unsigned char *)(addr)))
327 #define POKE(addr,val) do { PEEK(addr) = (val); } while (0)
328
329 /*
330 * Determine if the device is present
331 *
332 * on entry:
333 * a pointer to an isa_device struct
334 * on exit:
335 * NULL if device not found
336 * or # of i/o addresses used (if found)
337 */
338 static int
339 zpprobe(struct isa_device * isa_dev)
340 {
341 struct zp_softc *sc = &zp_softc[isa_dev->id_unit];
342 int slot;
343 u_short k;
344 int re_init_flag;
345
346 if ((slot = zp_find_adapter(isa_dev->id_maddr, isa_dev->id_reconfig)) < 0)
347 return 0;
348
349 /* okay, we found a card, so set it up */
350 /* Inhibit 16 bit memory delay. POINTETH.SYS apparently does this, for
351 * what reason I don't know. */
352 pcic_putb(slot, PCIC_CDGC,
353 pcic_getb(slot, PCIC_CDGC) | PCIC_16_DL_INH);
354 /* things to map (1) card's EEPROM is already mapped by the
355 * find_adapter routine but we still need to get the card's ethernet
356 * address. after that we unmap that part of attribute memory. (2)
357 * card configuration registers need to be mapped in so we can set the
358 * configuration and socket # registers. (3) shared memory packet
359 * buffer (4) i/o ports (5) IRQ */
360 #ifdef notdef
361 /* Sigh. Location of the ethernet address isn't documented in [1]. It
362 * was derived by doing a hex dump of all of attribute memory and
363 * looking for the IBM vendor prefix. */
364 enet_addr[0] = PEEK(isa_dev->id_maddr + 0xff0);
365 enet_addr[1] = PEEK(isa_dev->id_maddr + 0xff2);
366 enet_addr[2] = PEEK(isa_dev->id_maddr + 0xff4);
367 enet_addr[3] = PEEK(isa_dev->id_maddr + 0xff6);
368 enet_addr[4] = PEEK(isa_dev->id_maddr + 0xff8);
369 enet_addr[5] = PEEK(isa_dev->id_maddr + 0xffa);
370 #endif
371 re_init_flag = 0;
372 re_init:
373 /* (2) map card configuration registers. these are offset in card
374 * memory space by 0x20000. normally we could get this offset from
375 * the card information structure, but I'm too lazy and am not quite
376 * sure if I understand the CIS anyway.
377 *
378 * XXX IF YOU'RE TRYING TO PORT THIS DRIVER FOR A DIFFERENT PCMCIA CARD,
379 * the most likely thing to change is the constant 0x20000 in the next
380 * statement. Oh yes, also change the card id string that we probe
381 * for. */
382 pcic_map_memory(slot, 0, kvtop(isa_dev->id_maddr), 0x10000, 8L,
383 ATTRIBUTE, 1);
384 #if OLD_3C589B_CARDS
385 POKE(isa_dev->id_maddr, 0x80); /* reset the card (how long?) */
386 DELAY(40000);
387 #endif
388 /* Set the configuration index. According to [1], the adapter won't
389 * respond to any i/o signals until we do this; it uses the Memory
390 * Only interface (whatever that is; it's not documented). Also turn
391 * on "level" (not pulse) interrupts.
392 *
393 * XXX probably should init the socket and copy register also, so that we
394 * can deal with multiple instances of the same card. */
395 POKE(isa_dev->id_maddr, 0x41);
396 pcic_unmap_memory(slot, 0);
397
398 /* (4) map i/o ports.
399 *
400 * XXX is it possible that the config file leaves this unspecified, in
401 * which case we have to pick one?
402 *
403 * At least one PCMCIA device driver I'v seen maps a block of 32
404 * consecutive i/o ports as two windows of 16 ports each. Maybe some
405 * other pcic chips are restricted to 16-port windows; the 82365SL
406 * doesn't seem to have that problem. But since we have an extra
407 * window anyway... */
408 pcic_map_io(slot, 0, isa_dev->id_iobase, 16, 2);
409
410 /* (5) configure the card for the desired interrupt
411 *
412 * XXX is it possible that the config file leaves this unspecified? */
413 pcic_map_irq(slot, ffs(isa_dev->id_irq) - 1);
414
415 /* tell the PCIC that this is an I/O card (not memory) */
416 pcic_putb(slot, PCIC_INT_GEN,
417 pcic_getb(slot, PCIC_INT_GEN) | PCIC_CARDTYPE);
418
419 sc->ep_io_addr = isa_dev->id_iobase;
420 GO_WINDOW(0);
421 k = read_eeprom_data(BASE, EEPROM_ADDR_CFG); /* get addr cfg */
422 sc->if_port = k >> 14;
423 k = (k & 0x1f) * 0x10 + 0x200; /* decode base addr. */
424 if (k != (u_short) isa_dev->id_iobase) {
425 if (!re_init_flag) {
426 re_init_flag++;
427 goto re_init;
428 }
429 return (0);
430 }
431 k = read_eeprom_data(BASE, EEPROM_RESOURCE_CFG);
432
433 k >>= 12;
434
435 if (isa_dev->id_irq != (1 << ((k == 2) ? 9 : k)))
436 return (0);
437
438 outb(BASE, ACTIVATE_ADAPTER_TO_CONFIG);
439
440
441 /* information for reconfiguration */
442 sc->last_alive = 0;
443 sc->last_up = 0;
444 sc->slot = slot;
445
446 return (0x10); /* 16 bytes of I/O space used. */
447 }
448 #if NAPM > 0
449 static int
450 zp_suspend(visa_dev)
451 void *visa_dev;
452 {
453 #if 0
454 struct isa_device *isa_dev = visa_dev;
455 struct zp_softc *sc = &zp_softc[isa_dev->id_unit];
456
457 pcic_power_off(sc->slot);
458 #endif
459 return 0;
460 }
461
462 static int
463 zp_resume(visa_dev)
464 void *visa_dev;
465 {
466 struct isa_device *isa_dev = visa_dev;
467
468 prev_slot = 0;
469 reconfig_isadev(isa_dev, &net_imask);
470 return 0;
471 }
472 #endif /* NAPM > 0 */
473
474
475 /*
476 * Install interface into kernel networking data structures
477 */
478
479 static int
480 zpattach(isa_dev)
481 struct isa_device *isa_dev;
482 {
483 struct zp_softc *sc = &zp_softc[isa_dev->id_unit];
484 struct ifnet *ifp = &sc->arpcom.ac_if;
485 u_short i;
486 int pl;
487
488 isa_dev->id_ointr = zpintr;
489
490 /* PCMCIA card can be offlined. Reconfiguration is required */
491 if (isa_dev->id_reconfig) {
492 if (!isa_dev->id_alive && sc->last_alive) {
493 pl = splimp();
494 sc->last_up = (ifp->if_flags & IFF_UP);
495 if_down(ifp);
496 splx(pl);
497 sc->last_alive = 0;
498 }
499 if (isa_dev->id_alive && !sc->last_alive) {
500 zpreset(isa_dev->id_unit);
501 if (sc->last_up) {
502 pl = splimp();
503 if_up(ifp);
504 splx(pl);
505 }
506 sc->last_alive = 1;
507 }
508 return 1;
509 } else {
510 sc->last_alive = 1;
511 }
512
513
514 sc->ep_io_addr = isa_dev->id_iobase;
515 printf("zp%d: ", isa_dev->id_unit);
516
517 sc->buffill_pending = 0;
518 callout_handle_init(&sc->ch);
519
520 sc->ep_connectors = 0;
521
522 i = inw(isa_dev->id_iobase + EP_W0_CONFIG_CTRL);
523
524 if (i & IS_AUI) {
525 printf("aui");
526 sc->ep_connectors |= AUI;
527 }
528 if (i & IS_BNC) {
529 if (sc->ep_connectors)
530 printf("/");
531 printf("bnc");
532 sc->ep_connectors |= BNC;
533 }
534 if (i & IS_UTP) {
535 if (sc->ep_connectors)
536 printf("/");
537 printf("utp");
538 sc->ep_connectors |= UTP;
539 }
540 if (!sc->ep_connectors)
541 printf("no connectors!");
542
543 GO_WINDOW(0);
544 {
545 short tmp_addr[3];
546 int j;
547 for (j = 0; j < 3; j++) {
548 tmp_addr[j] = htons(read_eeprom_data(BASE, j));
549 }
550 bcopy(tmp_addr, sc->arpcom.ac_enaddr, 6);
551 }
552
553 printf(" address %6D\n", sc->arpcom.ac_enaddr, ":");
554
555 ifp->if_softc = sc;
556 ifp->if_mtu = ETHERMTU;
557 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
558 ifp->if_unit = isa_dev->id_unit;
559 ifp->if_name = "zp";
560 ifp->if_output = ether_output;
561 ifp->if_start = zpstart;
562 ifp->if_ioctl = zpioctl;
563 ifp->if_watchdog = zpwatchdog;
564 /* Select connector according to board setting. */
565 ifp->if_flags |= IFF_LINK0;
566
567 if_attach(ifp);
568 ether_ifattach(ifp);
569
570 #if NBPFILTER > 0
571 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
572 #endif
573 #if NAPM > 0
574 sc->s_hook.ah_fun = zp_suspend;
575 sc->s_hook.ah_arg = (void *) isa_dev;
576 sc->s_hook.ah_name = "3Com PCMCIA Etherlink III 3C589";
577 sc->s_hook.ah_order = APM_MID_ORDER;
578 apm_hook_establish(APM_HOOK_SUSPEND, &sc->s_hook);
579 sc->r_hook.ah_fun = zp_resume;
580 sc->r_hook.ah_arg = (void *) isa_dev;
581 sc->r_hook.ah_name = "3Com PCMCIA Etherlink III 3C589";
582 sc->r_hook.ah_order = APM_MID_ORDER;
583 apm_hook_establish(APM_HOOK_RESUME, &sc->r_hook);
584 #endif /* NAPM > 0 */
585 return 1;
586 }
587 /*
588 * The order in here seems important. Otherwise we may not receive
589 * interrupts. ?!
590 */
591 static void
592 zpinit(unit)
593 int unit;
594 {
595 register struct zp_softc *sc = &zp_softc[unit];
596 register struct ifnet *ifp = &sc->arpcom.ac_if;
597 int s, i;
598
599 if (TAILQ_EMPTY(&ifp->if_addrhead)) /* XXX unlikely */
600 return;
601
602 s = splimp();
603 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
604
605 GO_WINDOW(0);
606
607 /* Disable the card */
608 outw(BASE + EP_W0_CONFIG_CTRL, 0);
609
610 /* Enable the card */
611 outw(BASE + EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
612
613 GO_WINDOW(2);
614
615 /* Reload the ether_addr. */
616 for (i = 0; i < 6; i++)
617 outb(BASE + EP_W2_ADDR_0 + i, sc->arpcom.ac_enaddr[i]);
618
619 outw(BASE + EP_COMMAND, RX_RESET);
620 outw(BASE + EP_COMMAND, TX_RESET);
621
622 /* Window 1 is operating window */
623 GO_WINDOW(1);
624 for (i = 0; i < 31; i++)
625 inb(BASE + EP_W1_TX_STATUS);
626
627 /* get rid of stray intr's */
628 outw(BASE + EP_COMMAND, ACK_INTR | 0xff);
629
630 outw(BASE + EP_COMMAND, SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
631 S_TX_COMPLETE | S_TX_AVAIL);
632 outw(BASE + EP_COMMAND, SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
633 S_TX_COMPLETE | S_TX_AVAIL);
634
635 #ifndef IFF_MULTICAST
636 #define IFF_MULTICAST 0x10000
637 #endif
638
639 outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
640 ((sc->arpcom.ac_if.if_flags & IFF_MULTICAST) ? FIL_GROUP : 0) |
641 FIL_BRDCST |
642 ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) ? FIL_ALL : 0));
643 /* you can `ifconfig (link0|-link0) ep0' to get the following
644 * behaviour: -link0 disable AUI/UTP. enable BNC. link0 disable
645 * BNC. enable AUI. if the card has a UTP connector, that is enabled
646 * too. not sure, but it seems you have to be careful to not plug
647 * things into both AUI & UTP. */
648
649 if (!(ifp->if_flags & IFF_LINK0) && (sc->ep_connectors & BNC)) {
650 GO_WINDOW(0);
651 /* set the xcvr */
652 outw(BASE + EP_W0_ADDRESS_CFG, 3 << 14);
653 GO_WINDOW(2);
654 outw(BASE + EP_COMMAND, START_TRANSCEIVER);
655 GO_WINDOW(1);
656 }
657 #if defined(__NetBSD__) || defined(__FreeBSD__)
658 if ((ifp->if_flags & IFF_LINK0) && (sc->ep_connectors & UTP)) {
659 #else
660 if ((ifp->if_flags & IFF_ALTPHYS) && (sc->ep_connectors & UTP)) {
661 #endif
662 GO_WINDOW(4);
663 outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
664 GO_WINDOW(1);
665 }
666 outw(BASE + EP_COMMAND, RX_ENABLE);
667 outw(BASE + EP_COMMAND, TX_ENABLE);
668
669 ifp->if_flags |= IFF_RUNNING;
670 ifp->if_flags &= ~IFF_OACTIVE; /* just in case */
671 sc->tx_start_thresh = 20; /* probably a good starting point. */
672 /* Store up a bunch of mbuf's for use later. (MAX_MBS). First we free
673 * up any that we had in case we're being called from intr or
674 * somewhere else. */
675 sc->last_mb = 0;
676 sc->next_mb = 0;
677 if (sc->buffill_pending != 0) {
678 untimeout(zpmbuffill, sc, sc->ch);
679 sc->buffill_pending = 0;
680 }
681 zpmbuffill(sc);
682 zpstart(ifp);
683 splx(s);
684 }
685
686 static const char padmap[] = {0, 3, 2, 1};
687 static void
688 zpstart(ifp)
689 struct ifnet *ifp;
690 {
691 register struct zp_softc *sc = ifp->if_softc;
692 struct mbuf *m, *top;
693
694 int s, len, pad;
695
696 s = splimp();
697
698 if (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) {
699 splx(s);
700 return;
701 }
702 startagain:
703
704 /* Sneak a peek at the next packet */
705 m = sc->arpcom.ac_if.if_snd.ifq_head;
706 if (m == 0) {
707 splx(s);
708 return;
709 }
710 for (len = 0, top = m; m; m = m->m_next)
711 len += m->m_len;
712
713 pad = padmap[len & 3];
714
715 /* The 3c509 automatically pads short packets to minimum ethernet
716 * length, but we drop packets that are too large. Perhaps we should
717 * truncate them instead? */
718 if (len + pad > ETHER_MAX_LEN) {
719 /* packet is obviously too large: toss it */
720 ++sc->arpcom.ac_if.if_oerrors;
721 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
722 m_freem(m);
723 goto readcheck;
724 }
725 if (inw(BASE + EP_W1_FREE_TX) < len + pad + 4) {
726 /* no room in FIFO */
727 outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | (len + pad + 4));
728 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
729 splx(s);
730
731 return;
732 }
733 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
734
735 if (m == 0) { /* not really needed */
736 splx(s);
737 return;
738 }
739 outw(BASE + EP_COMMAND, SET_TX_START_THRESH |
740 (len / 4 + sc->tx_start_thresh));
741
742 outw(BASE + EP_W1_TX_PIO_WR_1, len);
743 outw(BASE + EP_W1_TX_PIO_WR_1, 0xffff); /* Second dword meaningless */
744
745 for (top = m; m != 0; m = m->m_next) {
746 if (sc->bus32bit) {
747 outsl(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t),
748 m->m_len / 4);
749 if (m->m_len & 3)
750 outsb(BASE + EP_W1_TX_PIO_WR_1,
751 mtod(m, caddr_t) + (m->m_len & (~3)),
752 m->m_len & 3);
753 } else {
754 outsw(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t), m->m_len / 2);
755 if (m->m_len & 1)
756 outb(BASE + EP_W1_TX_PIO_WR_1,
757 *(mtod(m, caddr_t) + m->m_len - 1));
758 }
759 }
760 while (pad--)
761 outb(BASE + EP_W1_TX_PIO_WR_1, 0); /* Padding */
762
763 #if NBPFILTER > 0
764 if (sc->arpcom.ac_if.if_bpf) {
765 bpf_mtap(&sc->arpcom.ac_if, top);
766 }
767 #endif
768
769 m_freem(top);
770 ++sc->arpcom.ac_if.if_opackets;
771 /* Is another packet coming in? We don't want to overflow the tiny RX
772 * fifo. */
773 readcheck:
774 if (inw(BASE + EP_W1_RX_STATUS) & RX_BYTES_MASK) {
775 splx(s);
776 return;
777 }
778 goto startagain;
779 }
780 static void
781 zpintr(unit)
782 int unit;
783 {
784 int status, i;
785 register struct zp_softc *sc = &zp_softc[unit];
786
787 struct ifnet *ifp = &sc->arpcom.ac_if;
788
789
790 status = 0;
791 checkintr:
792 status = inw(BASE + EP_STATUS) &
793 (S_TX_COMPLETE | S_TX_AVAIL | S_RX_COMPLETE | S_CARD_FAILURE);
794 checkintr2:
795 if (status == 0) {
796 /* No interrupts. */
797 outw(BASE + EP_COMMAND, C_INTR_LATCH);
798
799 status = inw(BASE + EP_STATUS) &
800 (S_TX_COMPLETE | S_TX_AVAIL | S_RX_COMPLETE |
801 S_CARD_FAILURE);
802 if (status)
803 goto checkintr2;
804
805 return;
806 }
807 /* important that we do this first. */
808 outw(BASE + EP_COMMAND, ACK_INTR | status);
809
810 if (status & S_TX_AVAIL) {
811 status &= ~S_TX_AVAIL;
812 inw(BASE + EP_W1_FREE_TX);
813 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
814 zpstart(&sc->arpcom.ac_if);
815
816 }
817 if (status & S_RX_COMPLETE) {
818 status &= ~S_RX_COMPLETE;
819 zpread(sc);
820 }
821 if (status & S_CARD_FAILURE) {
822 printf("zp%d: reset (status: %x)\n", unit, status);
823 outw(BASE + EP_COMMAND, C_INTR_LATCH);
824 zpinit(unit);
825 return;
826 }
827 if (status & S_TX_COMPLETE) {
828 status &= ~S_TX_COMPLETE;
829 /* We need to read TX_STATUS until we get a 0 status in order
830 * to turn off the interrupt flag. */
831 while ((i = inb(BASE + EP_W1_TX_STATUS)) & TXS_COMPLETE) {
832 outw(BASE + EP_W1_TX_STATUS, 0x0);
833 if (i & (TXS_MAX_COLLISION | TXS_JABBER | TXS_UNDERRUN)) {
834 if (i & TXS_MAX_COLLISION)
835 ++sc->arpcom.ac_if.if_collisions;
836 if (i & (TXS_JABBER | TXS_UNDERRUN)) {
837 outw(BASE + EP_COMMAND, TX_RESET);
838 if (i & TXS_UNDERRUN) {
839 if (sc->tx_start_thresh < ETHER_MAX_LEN) {
840 sc->tx_start_thresh += 20;
841 outw(BASE + EP_COMMAND,
842 SET_TX_START_THRESH |
843 sc->tx_start_thresh);
844 }
845 }
846 }
847 outw(BASE + EP_COMMAND, TX_ENABLE);
848 ++sc->arpcom.ac_if.if_oerrors;
849 }
850 }
851 zpstart(ifp);
852 }
853 goto checkintr;
854 }
855
856 static void
857 zpread(sc)
858 register struct zp_softc *sc;
859 {
860 struct ether_header *eh;
861 struct mbuf *mcur, *m, *m0, *top;
862 int totlen, lenthisone;
863 int save_totlen;
864 int off;
865
866
867 totlen = inw(BASE + EP_W1_RX_STATUS);
868 off = 0;
869 top = 0;
870
871 if (totlen & ERR_RX) {
872 ++sc->arpcom.ac_if.if_ierrors;
873 goto out;
874 }
875 save_totlen = totlen &= RX_BYTES_MASK; /* Lower 11 bits = RX bytes. */
876
877 m = sc->mb[sc->next_mb];
878 sc->mb[sc->next_mb] = 0;
879
880 if (m == 0) {
881 MGETHDR(m, M_DONTWAIT, MT_DATA);
882 if (m == 0)
883 goto out;
884 } else {
885 /* Convert one of our saved mbuf's */
886 sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
887 m->m_data = m->m_pktdat;
888 m->m_flags = M_PKTHDR;
889 }
890
891 top = m0 = m; /* We assign top so we can "goto out" */
892 #define EROUND ((sizeof(struct ether_header) + 3) & ~3)
893 #define EOFF (EROUND - sizeof(struct ether_header))
894 m0->m_data += EOFF;
895 /* Read what should be the header. */
896 insw(BASE + EP_W1_RX_PIO_RD_1,
897 mtod(m0, caddr_t), sizeof(struct ether_header) / 2);
898 m->m_len = sizeof(struct ether_header);
899 totlen -= sizeof(struct ether_header);
900 /* mostly deal with trailer here. (untested) We do this in a couple
901 * of parts. First we check for a trailer, if we have one we convert
902 * the mbuf back to a regular mbuf and set the offset and subtract
903 * sizeof(struct ether_header) from the pktlen. After we've read the
904 * packet off the interface (all except for the trailer header, we
905 * then get a header mbuf, read the trailer into it, and fix up the
906 * mbuf pointer chain. */
907 eh = mtod(m, struct ether_header *);
908 while (totlen > 0) {
909 lenthisone = min(totlen, M_TRAILINGSPACE(m));
910 if (lenthisone == 0) { /* no room in this one */
911 mcur = m;
912 m = sc->mb[sc->next_mb];
913 sc->mb[sc->next_mb] = 0;
914 if (!m) {
915 MGET(m, M_DONTWAIT, MT_DATA);
916 if (m == 0)
917 goto out;
918 } else if (sc->buffill_pending == 0) {
919 sc->ch = timeout(zpmbuffill, sc, 0);
920 sc->buffill_pending = 1;
921 sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
922 }
923 if (totlen >= MINCLSIZE)
924 MCLGET(m, M_DONTWAIT);
925 m->m_len = 0;
926 mcur->m_next = m;
927 lenthisone = min(totlen, M_TRAILINGSPACE(m));
928 }
929 if (sc->bus32bit) {
930 insl(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len,
931 lenthisone / 4);
932 m->m_len += (lenthisone & ~3);
933 if (lenthisone & 3)
934 insb(BASE + EP_W1_RX_PIO_RD_1,
935 mtod(m, caddr_t) + m->m_len,
936 lenthisone & 3);
937 m->m_len += (lenthisone & 3);
938 } else {
939 insw(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len,
940 lenthisone / 2);
941 m->m_len += lenthisone;
942 if (lenthisone & 1)
943 *(mtod(m, caddr_t) + m->m_len - 1) = inb(BASE + EP_W1_RX_PIO_RD_1);
944 }
945 totlen -= lenthisone;
946 }
947 if (off) {
948 top = sc->mb[sc->next_mb];
949 sc->mb[sc->next_mb] = 0;
950 if (top == 0) {
951 MGETHDR(m, M_DONTWAIT, MT_DATA);
952 if (top == 0) {
953 top = m0;
954 goto out;
955 }
956 } else {
957 /* Convert one of our saved mbuf's */
958 sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
959 top->m_data = top->m_pktdat;
960 top->m_flags = M_PKTHDR;
961 }
962 insw(BASE + EP_W1_RX_PIO_RD_1, mtod(top, caddr_t),
963 sizeof(struct ether_header));
964 top->m_next = m0;
965 top->m_len = sizeof(struct ether_header);
966 /* XXX Accomodate for type and len from beginning of trailer */
967 top->m_pkthdr.len = save_totlen - (2 * sizeof(u_short));
968 } else {
969 top = m0;
970 top->m_pkthdr.len = save_totlen;
971 }
972
973 top->m_pkthdr.rcvif = &sc->arpcom.ac_if;
974 outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
975 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
976 ++sc->arpcom.ac_if.if_ipackets;
977 #if NBPFILTER > 0
978 if (sc->arpcom.ac_if.if_bpf) {
979 bpf_mtap(&sc->arpcom.ac_if, top);
980
981 /* Note that the interface cannot be in promiscuous mode if
982 * there are no BPF listeners. And if we are in promiscuous
983 * mode, we have to check if this packet is really ours. */
984 if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) &&
985 (eh->ether_dhost[0] & 1) == 0 &&
986 bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
987 sizeof(eh->ether_dhost)) != 0 &&
988 bcmp(eh->ether_dhost, etherbroadcastaddr,
989 sizeof(eh->ether_dhost)) != 0) {
990 m_freem(top);
991 return;
992 }
993 }
994 #endif
995 m_adj(top, sizeof(struct ether_header));
996 ether_input(&sc->arpcom.ac_if, eh, top);
997 return;
998
999 out: outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
1000 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
1001 if (top)
1002 m_freem(top);
1003
1004 }
1005
1006
1007 /*
1008 * Look familiar?
1009 */
1010 static int
1011 zpioctl(ifp, cmd, data)
1012 register struct ifnet *ifp;
1013 u_long cmd;
1014 caddr_t data;
1015 {
1016 register struct ifaddr *ifa = (struct ifaddr *) data;
1017 struct zp_softc *sc = ifp->if_softc;
1018 int error = 0;
1019
1020
1021 switch (cmd) {
1022 case SIOCSIFADDR:
1023 ifp->if_flags |= IFF_UP;
1024 switch (ifa->ifa_addr->sa_family) {
1025 #ifdef INET
1026 case AF_INET:
1027 zpinit(ifp->if_unit); /* before arpwhohas */
1028 arp_ifinit((struct arpcom *) ifp, ifa);
1029 break;
1030 #endif
1031 #ifdef IPX
1032 case AF_IPX:
1033 {
1034 register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
1035
1036 if (ipx_nullhost(*ina))
1037 ina->x_host =
1038 *(union ipx_host *) (sc->arpcom.ac_enaddr);
1039 else {
1040 ifp->if_flags &= ~IFF_RUNNING;
1041 bcopy((caddr_t) ina->x_host.c_host,
1042 (caddr_t) sc->arpcom.ac_enaddr,
1043 sizeof(sc->arpcom.ac_enaddr));
1044 }
1045 zpinit(ifp->if_unit);
1046 break;
1047 }
1048 #endif
1049 #ifdef NS
1050 case AF_NS:
1051 {
1052 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
1053
1054 if (ns_nullhost(*ina))
1055 ina->x_host =
1056 *(union ns_host *) (sc->arpcom.ac_enaddr);
1057 else {
1058 ifp->if_flags &= ~IFF_RUNNING;
1059 bcopy((caddr_t) ina->x_host.c_host,
1060 (caddr_t) sc->arpcom.ac_enaddr,
1061 sizeof(sc->arpcom.ac_enaddr));
1062 }
1063 zpinit(ifp->if_unit);
1064 break;
1065 }
1066 #endif
1067 default:
1068 zpinit(ifp->if_unit);
1069 break;
1070 }
1071 break;
1072 case SIOCSIFFLAGS:
1073 if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) {
1074 ifp->if_flags &= ~IFF_RUNNING;
1075 zpstop(ifp->if_unit);
1076 zpmbufempty(sc);
1077 break;
1078 }
1079 zpinit(ifp->if_unit);
1080 break;
1081 default:
1082 error = EINVAL;
1083 }
1084 return (error);
1085 }
1086
1087 static void
1088 zpreset(unit)
1089 int unit;
1090 {
1091 int s = splimp();
1092
1093 zpstop(unit);
1094 zpinit(unit);
1095 splx(s);
1096 }
1097
1098 static void
1099 zpwatchdog(ifp)
1100 struct ifnet *ifp;
1101 {
1102 log(LOG_ERR, "zp%d: watchdog\n", ifp->if_unit);
1103 ifp->if_oerrors++;
1104 zpreset(ifp->if_unit);
1105 }
1106
1107 static void
1108 zpstop(unit)
1109 int unit;
1110 {
1111 struct zp_softc *sc = &zp_softc[unit];
1112
1113 outw(BASE + EP_COMMAND, RX_DISABLE);
1114 outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
1115 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
1116 outw(BASE + EP_COMMAND, TX_DISABLE);
1117 outw(BASE + EP_COMMAND, STOP_TRANSCEIVER);
1118 outw(BASE + EP_COMMAND, RX_RESET);
1119 outw(BASE + EP_COMMAND, TX_RESET);
1120 outw(BASE + EP_COMMAND, C_INTR_LATCH);
1121 outw(BASE + EP_COMMAND, SET_RD_0_MASK);
1122 outw(BASE + EP_COMMAND, SET_INTR_MASK);
1123 outw(BASE + EP_COMMAND, SET_RX_FILTER);
1124 }
1125
1126
1127
1128 static u_short
1129 read_eeprom_data(id_port, offset)
1130 int id_port;
1131 int offset;
1132 {
1133
1134 outb(id_port + 10, 0x80 + offset);
1135 DELAY(1000);
1136 return inw(id_port + 12);
1137 }
1138
1139
1140
1141
1142 static void
1143 zpmbuffill(sp)
1144 void *sp;
1145 {
1146 struct zp_softc *sc = (struct zp_softc *) sp;
1147 int s, i;
1148
1149 s = splimp();
1150 i = sc->last_mb;
1151 do {
1152 if (sc->mb[i] == NULL)
1153 MGET(sc->mb[i], M_DONTWAIT, MT_DATA);
1154 if (sc->mb[i] == NULL)
1155 break;
1156 i = (i + 1) % MAX_MBS;
1157 } while (i != sc->next_mb);
1158 sc->buffill_pending = 0;
1159 sc->last_mb = i;
1160 splx(s);
1161 }
1162
1163 static void
1164 zpmbufempty(sc)
1165 struct zp_softc *sc;
1166 {
1167 int s, i;
1168
1169 s = splimp();
1170 for (i = 0; i < MAX_MBS; i++) {
1171 if (sc->mb[i]) {
1172 m_freem(sc->mb[i]);
1173 sc->mb[i] = NULL;
1174 }
1175 }
1176 sc->last_mb = sc->next_mb = 0;
1177 if (sc->buffill_pending != 0) {
1178 untimeout(zpmbuffill, sc, sc->ch);
1179 sc->buffill_pending = 0;
1180 }
1181 splx(s);
1182 }
Cache object: aec0d33f48b4dcf4015004252d94d296
|