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
7 * (4) RT-Mach implementation on PCMCIA/ISA/EISA Etherlink III
10 * Copyright (c) by HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>
11 * Copyright (c) by Seiji Murata <seiji@mt.cs.keio.ac.jp>
14 * Copyright (c) 1993 Herb Peyerl <hpeyerl@novatel.ca>
15 * All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
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
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.
36 * From: if_ep.c,v 1.9 1994/01/25 10:46:29 deraadt Exp $
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.
46 * Device driver for IBM PCMCIA Credit Card Adapter for Ethernet,
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.
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.
59 * Sources for data on the PCMCIA/IBM CCAE specific portions of the driver:
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.
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.
77 /*======================================================================
79 A PCMCIA ethernet driver for the 3com 3c589 card.
81 Written by David Hinds, dhinds@allegro.stanford.edu
83 The network driver code is based on Donald Becker's 3c589 code:
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
92 ======================================================================*/
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>
99 * Very small patch for IBM Ethernet PCMCIA Card II and IBM ThinkPad230Cs.
100 * ETO, Toshihisa <eto@osl.fujitsu.co.jp>
103 /* XXX don't mix different PCCARD support code. */
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";
111 #error "Dedicated PCMCIA drivers and generic PCMCIA support can't be mixed"
117 #include "opt_inet.h"
120 #include <sys/param.h>
121 #if defined(__FreeBSD__)
122 #include <sys/systm.h>
123 #include <sys/conf.h>
125 #include <sys/mbuf.h>
126 #include <sys/socket.h>
127 #include <sys/sockio.h>
128 #include <sys/syslog.h>
130 #include <net/ethernet.h>
133 #include <netinet/in.h>
134 #include <netinet/if_ether.h>
138 #include <machine/clock.h>
139 #include <machine/md_var.h>
141 #include <i386/isa/isa_device.h>
142 #include <i386/isa/if_zpreg.h>
143 #include <i386/isa/pcic.h>
147 #include <machine/apm_bios.h>
148 #endif /* NAPM > 0 */
151 /*****************************************************************************
152 * Driver for Ethernet Adapter *
153 *****************************************************************************/
155 * zp_softc: per line info and status
157 static struct zp_softc {
158 struct arpcom arpcom; /* Ethernet common part */
159 #define MAX_MBS 8 /* # of mbufs we keep around */
160 struct mbuf *mb[MAX_MBS]; /* spare mbuf storage. */
161 int next_mb; /* Which mbuf to use next. */
162 int last_mb; /* Last mbuf. */
163 int ep_io_addr; /* i/o bus address */
164 char ep_connectors; /* Connectors on this card. */
165 int tx_start_thresh;/* Current TX_start_thresh. */
166 char bus32bit; /* 32bit access possible */
168 u_char last_alive; /* information for reconfiguration */
169 u_char last_up; /* information for reconfiguration */
170 int slot; /* PCMCIA slot */
171 struct callout_handle ch; /* Callout handle for timeouts */
174 struct apmhook s_hook; /* reconfiguration support */
175 struct apmhook r_hook; /* reconfiguration support */
176 #endif /* NAPM > 0 */
179 static int zpprobe __P((struct isa_device *));
180 static int zpattach __P((struct isa_device *));
181 static int zp_suspend __P((void *visa_dev));
182 static int zp_resume __P((void *visa_dev));
183 static int zpioctl __P((struct ifnet * ifp, u_long, caddr_t));
184 static u_short read_eeprom_data __P((int, int));
186 static void zpinit __P((int));
187 static ointhand2_t zpintr;
188 static void zpmbuffill __P((void *));
189 static void zpmbufempty __P((struct zp_softc *));
190 static void zpread __P((struct zp_softc *));
191 static void zpreset __P((int));
192 static void zpstart __P((struct ifnet *));
193 static void zpstop __P((int));
194 static void zpwatchdog __P((struct ifnet *));
196 struct isa_driver zpdriver = {
201 #define CARD_INFO "3Com Corporation~3C589"
203 static unsigned char card_info[256];
206 * scan the card information structure looking for the version/product info
207 * tuple. when we find it, compare it to the string we are looking for.
208 * return 1 if we find it, 0 otherwise.
212 zp_check_cis(unsigned char *scratch)
218 while (scratch[i] != 0xff && i < 1024) {
219 unsigned char link = scratch[i + 2];
221 if (scratch[i] == 0x15) {
222 /* level 1 version/product info copy to card_info,
223 * translating '\0' to '~' */
225 for (j = i + 8; scratch[j] != 0xff; j += 2)
226 card_info[k++] = scratch[j] == '\0' ? '~' : scratch[j];
227 card_info[k++] = '\0';
228 return (bcmp(card_info, CARD_INFO, sizeof(CARD_INFO) - 1) == 0);
235 * Probe each slot looking for an IBM Credit Card Adapter for Ethernet
236 * For each card that we find, map its card information structure
237 * into system memory at 'scratch' and see whether it's one of ours.
238 * Return the slot number if we find a card, or -1 otherwise.
241 * + On success, leaves CIS mapped into memory at 'scratch';
242 * caller must free it.
243 * + On success, leaves ethernet address in enet_addr.
244 * + Leaves product/vendor id of last card probed in 'card_info'
247 static int prev_slot = 0;
250 zp_find_adapter(unsigned char *scratch, int reconfig)
254 for (slot = prev_slot; slot < MAXSLOT; ++slot) {
255 /* see if there's a PCMCIA controller here Intel PCMCIA
256 * controllers use 0x82 and 0x83 IBM clone chips use 0x88 and
257 * 0x89, apparently */
258 /* IBM ThinkPad230Cs use 0x84. */
259 unsigned char idbyte = pcic_getb(slot, PCIC_ID_REV);
261 if (idbyte != 0x82 && idbyte != 0x83 &&
262 idbyte != 0x84 && /* for IBM ThinkPad 230Cs */
263 idbyte != 0x88 && idbyte != 0x89) {
266 if ((pcic_getb(slot, PCIC_STATUS) & PCIC_CD) != PCIC_CD) {
268 printf("zp: slot %d: no card in slot\n", slot);
270 log(LOG_NOTICE, "zp: slot %d: no card in slot\n", slot);
272 /* no card in slot */
278 /* map the card's attribute memory and examine its card
279 * information structure tuples for something we recognize. */
280 pcic_map_memory(slot, 0, kvtop(scratch), 0L,
281 0xFFFL, ATTRIBUTE, 1);
283 if ((zp_check_cis(scratch)) > 0) {
286 printf("zp: found card in slot %d\n", slot);
288 log(LOG_NOTICE, "zp: found card in slot %d\n", slot);
290 prev_slot = (prev_slot == MAXSLOT - 1) ? 0 : prev_slot + 1;
295 printf("zp: pcmcia slot %d: %s\n", slot, card_info);
297 log(LOG_NOTICE, "zp: pcmcia slot %d: %s\n", slot, card_info);
300 pcic_unmap_memory(slot, 0);
308 * macros to handle casting unsigned long to (char *) so we can
309 * read/write into physical memory space.
312 #define PEEK(addr) (*((unsigned char *)(addr)))
313 #define POKE(addr,val) do { PEEK(addr) = (val); } while (0)
316 * Determine if the device is present
319 * a pointer to an isa_device struct
321 * NULL if device not found
322 * or # of i/o addresses used (if found)
325 zpprobe(struct isa_device * isa_dev)
327 struct zp_softc *sc = &zp_softc[isa_dev->id_unit];
332 if ((slot = zp_find_adapter(isa_dev->id_maddr, isa_dev->id_reconfig)) < 0)
335 /* okay, we found a card, so set it up */
336 /* Inhibit 16 bit memory delay. POINTETH.SYS apparently does this, for
337 * what reason I don't know. */
338 pcic_putb(slot, PCIC_CDGC,
339 pcic_getb(slot, PCIC_CDGC) | PCIC_16_DL_INH);
340 /* things to map (1) card's EEPROM is already mapped by the
341 * find_adapter routine but we still need to get the card's ethernet
342 * address. after that we unmap that part of attribute memory. (2)
343 * card configuration registers need to be mapped in so we can set the
344 * configuration and socket # registers. (3) shared memory packet
345 * buffer (4) i/o ports (5) IRQ */
347 /* Sigh. Location of the ethernet address isn't documented in [1]. It
348 * was derived by doing a hex dump of all of attribute memory and
349 * looking for the IBM vendor prefix. */
350 enet_addr[0] = PEEK(isa_dev->id_maddr + 0xff0);
351 enet_addr[1] = PEEK(isa_dev->id_maddr + 0xff2);
352 enet_addr[2] = PEEK(isa_dev->id_maddr + 0xff4);
353 enet_addr[3] = PEEK(isa_dev->id_maddr + 0xff6);
354 enet_addr[4] = PEEK(isa_dev->id_maddr + 0xff8);
355 enet_addr[5] = PEEK(isa_dev->id_maddr + 0xffa);
359 /* (2) map card configuration registers. these are offset in card
360 * memory space by 0x20000. normally we could get this offset from
361 * the card information structure, but I'm too lazy and am not quite
362 * sure if I understand the CIS anyway.
364 * XXX IF YOU'RE TRYING TO PORT THIS DRIVER FOR A DIFFERENT PCMCIA CARD,
365 * the most likely thing to change is the constant 0x20000 in the next
366 * statement. Oh yes, also change the card id string that we probe
368 pcic_map_memory(slot, 0, kvtop(isa_dev->id_maddr), 0x10000, 8L,
371 POKE(isa_dev->id_maddr, 0x80); /* reset the card (how long?) */
374 /* Set the configuration index. According to [1], the adapter won't
375 * respond to any i/o signals until we do this; it uses the Memory
376 * Only interface (whatever that is; it's not documented). Also turn
377 * on "level" (not pulse) interrupts.
379 * XXX probably should init the socket and copy register also, so that we
380 * can deal with multiple instances of the same card. */
381 POKE(isa_dev->id_maddr, 0x41);
382 pcic_unmap_memory(slot, 0);
384 /* (4) map i/o ports.
386 * XXX is it possible that the config file leaves this unspecified, in
387 * which case we have to pick one?
389 * At least one PCMCIA device driver I'v seen maps a block of 32
390 * consecutive i/o ports as two windows of 16 ports each. Maybe some
391 * other pcic chips are restricted to 16-port windows; the 82365SL
392 * doesn't seem to have that problem. But since we have an extra
393 * window anyway... */
394 pcic_map_io(slot, 0, isa_dev->id_iobase, 16, 2);
396 /* (5) configure the card for the desired interrupt
398 * XXX is it possible that the config file leaves this unspecified? */
399 pcic_map_irq(slot, ffs(isa_dev->id_irq) - 1);
401 /* tell the PCIC that this is an I/O card (not memory) */
402 pcic_putb(slot, PCIC_INT_GEN,
403 pcic_getb(slot, PCIC_INT_GEN) | PCIC_CARDTYPE);
405 sc->ep_io_addr = isa_dev->id_iobase;
407 k = read_eeprom_data(BASE, EEPROM_ADDR_CFG); /* get addr cfg */
408 sc->if_port = k >> 14;
409 k = (k & 0x1f) * 0x10 + 0x200; /* decode base addr. */
410 if (k != (u_short) isa_dev->id_iobase) {
417 k = read_eeprom_data(BASE, EEPROM_RESOURCE_CFG);
421 if (isa_dev->id_irq != (1 << ((k == 2) ? 9 : k)))
424 outb(BASE, ACTIVATE_ADAPTER_TO_CONFIG);
427 /* information for reconfiguration */
432 return (0x10); /* 16 bytes of I/O space used. */
440 struct isa_device *isa_dev = visa_dev;
441 struct zp_softc *sc = &zp_softc[isa_dev->id_unit];
443 pcic_power_off(sc->slot);
452 struct isa_device *isa_dev = visa_dev;
455 reconfig_isadev(isa_dev, &net_imask);
458 #endif /* NAPM > 0 */
462 * Install interface into kernel networking data structures
467 struct isa_device *isa_dev;
469 struct zp_softc *sc = &zp_softc[isa_dev->id_unit];
470 struct ifnet *ifp = &sc->arpcom.ac_if;
474 isa_dev->id_ointr = zpintr;
476 /* PCMCIA card can be offlined. Reconfiguration is required */
477 if (isa_dev->id_reconfig) {
478 if (!isa_dev->id_alive && sc->last_alive) {
480 sc->last_up = (ifp->if_flags & IFF_UP);
485 if (isa_dev->id_alive && !sc->last_alive) {
486 zpreset(isa_dev->id_unit);
500 sc->ep_io_addr = isa_dev->id_iobase;
501 printf("zp%d: ", isa_dev->id_unit);
503 sc->buffill_pending = 0;
504 callout_handle_init(&sc->ch);
506 sc->ep_connectors = 0;
508 i = inw(isa_dev->id_iobase + EP_W0_CONFIG_CTRL);
512 sc->ep_connectors |= AUI;
515 if (sc->ep_connectors)
518 sc->ep_connectors |= BNC;
521 if (sc->ep_connectors)
524 sc->ep_connectors |= UTP;
526 if (!sc->ep_connectors)
527 printf("no connectors!");
533 for (j = 0; j < 3; j++) {
534 tmp_addr[j] = htons(read_eeprom_data(BASE, j));
536 bcopy(tmp_addr, sc->arpcom.ac_enaddr, 6);
539 printf(" address %6D\n", sc->arpcom.ac_enaddr, ":");
541 sc->arpcom.ac_if.if_snd.ifq_maxlen = ifqmaxlen;
543 ifp->if_mtu = ETHERMTU;
544 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
545 ifp->if_unit = isa_dev->id_unit;
547 ifp->if_output = ether_output;
548 ifp->if_start = zpstart;
549 ifp->if_ioctl = zpioctl;
550 ifp->if_watchdog = zpwatchdog;
551 /* Select connector according to board setting. */
552 ifp->if_flags |= IFF_LINK0;
557 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
559 sc->s_hook.ah_fun = zp_suspend;
560 sc->s_hook.ah_arg = (void *) isa_dev;
561 sc->s_hook.ah_name = "3Com PCMCIA Etherlink III 3C589";
562 sc->s_hook.ah_order = APM_MID_ORDER;
563 apm_hook_establish(APM_HOOK_SUSPEND, &sc->s_hook);
564 sc->r_hook.ah_fun = zp_resume;
565 sc->r_hook.ah_arg = (void *) isa_dev;
566 sc->r_hook.ah_name = "3Com PCMCIA Etherlink III 3C589";
567 sc->r_hook.ah_order = APM_MID_ORDER;
568 apm_hook_establish(APM_HOOK_RESUME, &sc->r_hook);
569 #endif /* NAPM > 0 */
573 * The order in here seems important. Otherwise we may not receive
580 register struct zp_softc *sc = &zp_softc[unit];
581 register struct ifnet *ifp = &sc->arpcom.ac_if;
584 if (TAILQ_EMPTY(&ifp->if_addrhead)) /* XXX unlikely */
588 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
592 /* Disable the card */
593 outw(BASE + EP_W0_CONFIG_CTRL, 0);
595 /* Enable the card */
596 outw(BASE + EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
600 /* Reload the ether_addr. */
601 for (i = 0; i < 6; i++)
602 outb(BASE + EP_W2_ADDR_0 + i, sc->arpcom.ac_enaddr[i]);
604 outw(BASE + EP_COMMAND, RX_RESET);
605 outw(BASE + EP_COMMAND, TX_RESET);
607 /* Window 1 is operating window */
609 for (i = 0; i < 31; i++)
610 inb(BASE + EP_W1_TX_STATUS);
612 /* get rid of stray intr's */
613 outw(BASE + EP_COMMAND, ACK_INTR | 0xff);
615 outw(BASE + EP_COMMAND, SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
616 S_TX_COMPLETE | S_TX_AVAIL);
617 outw(BASE + EP_COMMAND, SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
618 S_TX_COMPLETE | S_TX_AVAIL);
620 #ifndef IFF_MULTICAST
621 #define IFF_MULTICAST 0x10000
624 outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
625 ((sc->arpcom.ac_if.if_flags & IFF_MULTICAST) ? FIL_GROUP : 0) |
627 ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) ? FIL_ALL : 0));
628 /* you can `ifconfig (link0|-link0) ep0' to get the following
629 * behaviour: -link0 disable AUI/UTP. enable BNC. link0 disable
630 * BNC. enable AUI. if the card has a UTP connector, that is enabled
631 * too. not sure, but it seems you have to be careful to not plug
632 * things into both AUI & UTP. */
634 if (!(ifp->if_flags & IFF_LINK0) && (sc->ep_connectors & BNC)) {
637 outw(BASE + EP_W0_ADDRESS_CFG, 3 << 14);
639 outw(BASE + EP_COMMAND, START_TRANSCEIVER);
642 #if defined(__NetBSD__) || defined(__FreeBSD__)
643 if ((ifp->if_flags & IFF_LINK0) && (sc->ep_connectors & UTP)) {
645 if ((ifp->if_flags & IFF_ALTPHYS) && (sc->ep_connectors & UTP)) {
648 outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
651 outw(BASE + EP_COMMAND, RX_ENABLE);
652 outw(BASE + EP_COMMAND, TX_ENABLE);
654 ifp->if_flags |= IFF_RUNNING;
655 ifp->if_flags &= ~IFF_OACTIVE; /* just in case */
656 sc->tx_start_thresh = 20; /* probably a good starting point. */
657 /* Store up a bunch of mbuf's for use later. (MAX_MBS). First we free
658 * up any that we had in case we're being called from intr or
662 if (sc->buffill_pending != 0) {
663 untimeout(zpmbuffill, sc, sc->ch);
664 sc->buffill_pending = 0;
671 static const char padmap[] = {0, 3, 2, 1};
676 register struct zp_softc *sc = ifp->if_softc;
677 struct mbuf *m, *top;
683 if (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) {
689 /* Sneak a peek at the next packet */
690 m = sc->arpcom.ac_if.if_snd.ifq_head;
695 for (len = 0, top = m; m; m = m->m_next)
698 pad = padmap[len & 3];
700 /* The 3c509 automatically pads short packets to minimum ethernet
701 * length, but we drop packets that are too large. Perhaps we should
702 * truncate them instead? */
703 if (len + pad > ETHER_MAX_LEN) {
704 /* packet is obviously too large: toss it */
705 ++sc->arpcom.ac_if.if_oerrors;
706 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
710 if (inw(BASE + EP_W1_FREE_TX) < len + pad + 4) {
711 /* no room in FIFO */
712 outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | (len + pad + 4));
713 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
718 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
720 if (m == 0) { /* not really needed */
724 outw(BASE + EP_COMMAND, SET_TX_START_THRESH |
725 (len / 4 + sc->tx_start_thresh));
727 outw(BASE + EP_W1_TX_PIO_WR_1, len);
728 outw(BASE + EP_W1_TX_PIO_WR_1, 0xffff); /* Second dword meaningless */
730 for (top = m; m != 0; m = m->m_next) {
732 outsl(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t),
735 outsb(BASE + EP_W1_TX_PIO_WR_1,
736 mtod(m, caddr_t) + (m->m_len & (~3)),
739 outsw(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t), m->m_len / 2);
741 outb(BASE + EP_W1_TX_PIO_WR_1,
742 *(mtod(m, caddr_t) + m->m_len - 1));
746 outb(BASE + EP_W1_TX_PIO_WR_1, 0); /* Padding */
748 if (sc->arpcom.ac_if.if_bpf) {
749 bpf_mtap(&sc->arpcom.ac_if, top);
753 ++sc->arpcom.ac_if.if_opackets;
754 /* Is another packet coming in? We don't want to overflow the tiny RX
757 if (inw(BASE + EP_W1_RX_STATUS) & RX_BYTES_MASK) {
768 register struct zp_softc *sc = &zp_softc[unit];
770 struct ifnet *ifp = &sc->arpcom.ac_if;
775 status = inw(BASE + EP_STATUS) &
776 (S_TX_COMPLETE | S_TX_AVAIL | S_RX_COMPLETE | S_CARD_FAILURE);
780 outw(BASE + EP_COMMAND, C_INTR_LATCH);
782 status = inw(BASE + EP_STATUS) &
783 (S_TX_COMPLETE | S_TX_AVAIL | S_RX_COMPLETE |
790 /* important that we do this first. */
791 outw(BASE + EP_COMMAND, ACK_INTR | status);
793 if (status & S_TX_AVAIL) {
794 status &= ~S_TX_AVAIL;
795 inw(BASE + EP_W1_FREE_TX);
796 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
797 zpstart(&sc->arpcom.ac_if);
800 if (status & S_RX_COMPLETE) {
801 status &= ~S_RX_COMPLETE;
804 if (status & S_CARD_FAILURE) {
805 printf("zp%d: reset (status: %x)\n", unit, status);
806 outw(BASE + EP_COMMAND, C_INTR_LATCH);
810 if (status & S_TX_COMPLETE) {
811 status &= ~S_TX_COMPLETE;
812 /* We need to read TX_STATUS until we get a 0 status in order
813 * to turn off the interrupt flag. */
814 while ((i = inb(BASE + EP_W1_TX_STATUS)) & TXS_COMPLETE) {
815 outw(BASE + EP_W1_TX_STATUS, 0x0);
816 if (i & (TXS_MAX_COLLISION | TXS_JABBER | TXS_UNDERRUN)) {
817 if (i & TXS_MAX_COLLISION)
818 ++sc->arpcom.ac_if.if_collisions;
819 if (i & (TXS_JABBER | TXS_UNDERRUN)) {
820 outw(BASE + EP_COMMAND, TX_RESET);
821 if (i & TXS_UNDERRUN) {
822 if (sc->tx_start_thresh < ETHER_MAX_LEN) {
823 sc->tx_start_thresh += 20;
824 outw(BASE + EP_COMMAND,
825 SET_TX_START_THRESH |
826 sc->tx_start_thresh);
830 outw(BASE + EP_COMMAND, TX_ENABLE);
831 ++sc->arpcom.ac_if.if_oerrors;
841 register struct zp_softc *sc;
843 struct ether_header *eh;
844 struct mbuf *mcur, *m, *m0, *top;
845 int totlen, lenthisone;
850 totlen = inw(BASE + EP_W1_RX_STATUS);
854 if (totlen & ERR_RX) {
855 ++sc->arpcom.ac_if.if_ierrors;
858 save_totlen = totlen &= RX_BYTES_MASK; /* Lower 11 bits = RX bytes. */
860 m = sc->mb[sc->next_mb];
861 sc->mb[sc->next_mb] = 0;
864 MGETHDR(m, M_DONTWAIT, MT_DATA);
868 /* Convert one of our saved mbuf's */
869 sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
870 m->m_data = m->m_pktdat;
871 m->m_flags = M_PKTHDR;
874 top = m0 = m; /* We assign top so we can "goto out" */
875 #define EROUND ((sizeof(struct ether_header) + 3) & ~3)
876 #define EOFF (EROUND - sizeof(struct ether_header))
878 /* Read what should be the header. */
879 insw(BASE + EP_W1_RX_PIO_RD_1,
880 mtod(m0, caddr_t), sizeof(struct ether_header) / 2);
881 m->m_len = sizeof(struct ether_header);
882 totlen -= sizeof(struct ether_header);
883 /* mostly deal with trailer here. (untested) We do this in a couple
884 * of parts. First we check for a trailer, if we have one we convert
885 * the mbuf back to a regular mbuf and set the offset and subtract
886 * sizeof(struct ether_header) from the pktlen. After we've read the
887 * packet off the interface (all except for the trailer header, we
888 * then get a header mbuf, read the trailer into it, and fix up the
889 * mbuf pointer chain. */
890 eh = mtod(m, struct ether_header *);
892 lenthisone = min(totlen, M_TRAILINGSPACE(m));
893 if (lenthisone == 0) { /* no room in this one */
895 m = sc->mb[sc->next_mb];
896 sc->mb[sc->next_mb] = 0;
898 MGET(m, M_DONTWAIT, MT_DATA);
901 } else if (sc->buffill_pending == 0) {
902 sc->ch = timeout(zpmbuffill, sc, 0);
903 sc->buffill_pending = 1;
904 sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
906 if (totlen >= MINCLSIZE)
907 MCLGET(m, M_DONTWAIT);
910 lenthisone = min(totlen, M_TRAILINGSPACE(m));
913 insl(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len,
915 m->m_len += (lenthisone & ~3);
917 insb(BASE + EP_W1_RX_PIO_RD_1,
918 mtod(m, caddr_t) + m->m_len,
920 m->m_len += (lenthisone & 3);
922 insw(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len,
924 m->m_len += lenthisone;
926 *(mtod(m, caddr_t) + m->m_len - 1) = inb(BASE + EP_W1_RX_PIO_RD_1);
928 totlen -= lenthisone;
931 top = sc->mb[sc->next_mb];
932 sc->mb[sc->next_mb] = 0;
934 MGETHDR(m, M_DONTWAIT, MT_DATA);
940 /* Convert one of our saved mbuf's */
941 sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
942 top->m_data = top->m_pktdat;
943 top->m_flags = M_PKTHDR;
945 insw(BASE + EP_W1_RX_PIO_RD_1, mtod(top, caddr_t),
946 sizeof(struct ether_header));
948 top->m_len = sizeof(struct ether_header);
949 /* XXX Accomodate for type and len from beginning of trailer */
950 top->m_pkthdr.len = save_totlen - (2 * sizeof(u_short));
953 top->m_pkthdr.len = save_totlen;
956 top->m_pkthdr.rcvif = &sc->arpcom.ac_if;
957 outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
958 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
959 ++sc->arpcom.ac_if.if_ipackets;
960 if (sc->arpcom.ac_if.if_bpf) {
961 bpf_mtap(&sc->arpcom.ac_if, top);
963 /* Note that the interface cannot be in promiscuous mode if
964 * there are no BPF listeners. And if we are in promiscuous
965 * mode, we have to check if this packet is really ours. */
966 if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) &&
967 (eh->ether_dhost[0] & 1) == 0 &&
968 bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
969 sizeof(eh->ether_dhost)) != 0 &&
970 bcmp(eh->ether_dhost, etherbroadcastaddr,
971 sizeof(eh->ether_dhost)) != 0) {
976 m_adj(top, sizeof(struct ether_header));
977 ether_input(&sc->arpcom.ac_if, eh, top);
980 out: outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
981 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
992 zpioctl(ifp, cmd, data)
993 register struct ifnet *ifp;
997 struct zp_softc *sc = ifp->if_softc;
1005 error = ether_ioctl(ifp, cmd, data);
1009 if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) {
1010 ifp->if_flags &= ~IFF_RUNNING;
1011 zpstop(ifp->if_unit);
1015 zpinit(ifp->if_unit);
1038 log(LOG_ERR, "zp%d: watchdog\n", ifp->if_unit);
1040 zpreset(ifp->if_unit);
1047 struct zp_softc *sc = &zp_softc[unit];
1049 outw(BASE + EP_COMMAND, RX_DISABLE);
1050 outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
1051 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
1052 outw(BASE + EP_COMMAND, TX_DISABLE);
1053 outw(BASE + EP_COMMAND, STOP_TRANSCEIVER);
1054 outw(BASE + EP_COMMAND, RX_RESET);
1055 outw(BASE + EP_COMMAND, TX_RESET);
1056 outw(BASE + EP_COMMAND, C_INTR_LATCH);
1057 outw(BASE + EP_COMMAND, SET_RD_0_MASK);
1058 outw(BASE + EP_COMMAND, SET_INTR_MASK);
1059 outw(BASE + EP_COMMAND, SET_RX_FILTER);
1065 read_eeprom_data(id_port, offset)
1070 outb(id_port + 10, 0x80 + offset);
1072 return inw(id_port + 12);
1082 struct zp_softc *sc = (struct zp_softc *) sp;
1088 if (sc->mb[i] == NULL)
1089 MGET(sc->mb[i], M_DONTWAIT, MT_DATA);
1090 if (sc->mb[i] == NULL)
1092 i = (i + 1) % MAX_MBS;
1093 } while (i != sc->next_mb);
1094 sc->buffill_pending = 0;
1101 struct zp_softc *sc;
1106 for (i = 0; i < MAX_MBS; i++) {
1112 sc->last_mb = sc->next_mb = 0;
1113 if (sc->buffill_pending != 0) {
1114 untimeout(zpmbuffill, sc, sc->ch);
1115 sc->buffill_pending = 0;