Deleted Added
full compact
if_ep.c (51646) if_ep.c (51673)
1/*
2 * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
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

--- 24 unchanged lines hidden (view full) ---

33/*
34 * Modified from the FreeBSD 1.1.5.1 version by:
35 * Andres Vega Garcia
36 * INRIA - Sophia Antipolis, France
37 * avega@sophia.inria.fr
38 */
39
40/*
1/*
2 * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
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

--- 24 unchanged lines hidden (view full) ---

33/*
34 * Modified from the FreeBSD 1.1.5.1 version by:
35 * Andres Vega Garcia
36 * INRIA - Sophia Antipolis, France
37 * avega@sophia.inria.fr
38 */
39
40/*
41 * $FreeBSD: head/sys/dev/ep/if_ep.c 51646 1999-09-25 12:06:01Z phk $
41 * $FreeBSD: head/sys/dev/ep/if_ep.c 51673 1999-09-26 06:42:36Z mdodd $
42 *
43 * Promiscuous mode added and interrupt logic slightly changed
44 * to reduce the number of adapter failures. Transceiver select
45 * logic changed to use value from EEPROM. Autoconfiguration
46 * features added.
47 * Done by:
48 * Serge Babkin
49 * Chelindbank (Chelyabinsk, Russia)

--- 4 unchanged lines hidden (view full) ---

54 * Pccard support for 3C589 by:
55 * HAMADA Naoki
56 * nao@tom-yam.or.jp
57 */
58
59#include "ep.h"
60#if NEP > 0
61
42 *
43 * Promiscuous mode added and interrupt logic slightly changed
44 * to reduce the number of adapter failures. Transceiver select
45 * logic changed to use value from EEPROM. Autoconfiguration
46 * features added.
47 * Done by:
48 * Serge Babkin
49 * Chelindbank (Chelyabinsk, Russia)

--- 4 unchanged lines hidden (view full) ---

54 * Pccard support for 3C589 by:
55 * HAMADA Naoki
56 * nao@tom-yam.or.jp
57 */
58
59#include "ep.h"
60#if NEP > 0
61
62#include "opt_inet.h"
63#include "opt_ipx.h"
64
65#include <sys/param.h>
62#include <sys/param.h>
66#if defined(__FreeBSD__)
67#include <sys/kernel.h>
68#include <sys/systm.h>
63#include <sys/kernel.h>
64#include <sys/systm.h>
69#endif
70#include <sys/malloc.h>
71#include <sys/mbuf.h>
72#include <sys/socket.h>
73#include <sys/sockio.h>
65#include <sys/malloc.h>
66#include <sys/mbuf.h>
67#include <sys/socket.h>
68#include <sys/sockio.h>
74#if defined(__NetBSD__)
75#include <sys/select.h>
76#endif
77
78#include <net/ethernet.h>
79#include <net/if.h>
69
70#include <net/ethernet.h>
71#include <net/if.h>
80
81#include <netinet/in.h>
82#include <netinet/if_ether.h>
72#include <netinet/in.h>
73#include <netinet/if_ether.h>
83
84#include <net/bpf.h>
85
74#include <net/bpf.h>
75
86#if defined(__FreeBSD__)
87#include <machine/clock.h>
76#include <machine/clock.h>
88#endif
89
77
90#include <i386/isa/isa_device.h>
91#include <i386/isa/if_epreg.h>
92#include <i386/isa/elink.h>
78#include <i386/isa/elink.h>
79#include <dev/ep/if_epreg.h>
80#include <dev/ep/if_epvar.h>
93
81
94/* DELAY_MULTIPLE: How much to boost "base" delays, except
95 * for the inter-bit delays in get_eeprom_data. A cyrix Media GX needed this.
96 */
97#define DELAY_MULTIPLE 10
98#define BIT_DELAY_MULTIPLE 10
99
100/* Exported variables */
82/* Exported variables */
101u_long ep_unit;
83struct ep_softc * ep_softc[NEP];
84struct ep_board ep_board[EP_MAX_BOARDS + 1];
102int ep_boards;
85int ep_boards;
103struct ep_board ep_board[EP_MAX_BOARDS + 1];
86u_long ep_unit;
104
87
105static int eeprom_rdy __P((struct ep_softc *sc));
88static char * ep_conn_type[] = {"UTP", "AUI", "???", "BNC"};
106
89
107static int ep_isa_probe __P((struct isa_device *));
108static struct ep_board * ep_look_for_board_at __P((struct isa_device *is));
109static int ep_isa_attach __P((struct isa_device *));
110static int epioctl __P((struct ifnet * ifp, u_long, caddr_t));
90static int eeprom_rdy __P((struct ep_softc *sc));
91static int epioctl __P((struct ifnet * ifp, u_long, caddr_t));
92static void epinit __P((void *));
93static void epread __P((struct ep_softc *));
94static void epstart __P((struct ifnet *));
95static void epstop __P((struct ep_softc *));
96static void epwatchdog __P((struct ifnet *));
111
97
112static void epinit __P((void *));
113static ointhand2_t epintr;
114static void epread __P((struct ep_softc *));
115void epreset __P((int));
116static void epstart __P((struct ifnet *));
117static void epstop __P((struct ep_softc *));
118static void epwatchdog __P((struct ifnet *));
98#define EP_FTST(sc, f) (sc->stat&(f))
99#define EP_FSET(sc, f) (sc->stat|=(f))
100#define EP_FRST(sc, f) (sc->stat&=~(f))
119
101
120#if 0
121static int send_ID_sequence __P((int));
122#endif
123static int get_eeprom_data __P((int, int));
124
125static struct ep_softc* ep_softc[NEP];
126static int ep_current_tag = EP_LAST_TAG + 1;
127static char *ep_conn_type[] = {"UTP", "AUI", "???", "BNC"};
128
129#define ep_ftst(f) (sc->stat&(f))
130#define ep_fset(f) (sc->stat|=(f))
131#define ep_frst(f) (sc->stat&=~(f))
132
133struct isa_driver epdriver = {
134 ep_isa_probe,
135 ep_isa_attach,
136 "ep",
137 0
138};
139
140#include "card.h"
141
142#if NCARD > 0
143#include <sys/select.h>
144#include <sys/module.h>
145#include <pccard/cardinfo.h>
146#include <pccard/slot.h>
147
148/*
149 * PC-Card (PCMCIA) specific code.
150 */
151static int ep_pccard_init __P((struct pccard_devinfo *));
152static int ep_pccard_attach __P((struct pccard_devinfo *));
153static void ep_unload __P((struct pccard_devinfo *));
154static int card_intr __P((struct pccard_devinfo *));
155static int ep_pccard_identify (struct ep_board *epb, int unit);
156
157PCCARD_MODULE(ep, ep_pccard_init, ep_unload, card_intr, 0, net_imask);
158
159/*
160 * Initialize the device - called from Slot manager.
161 */
162static int
102static int
163ep_pccard_init(devi)
164 struct pccard_devinfo *devi;
165{
166 struct isa_device *is = &devi->isahd;
167 struct ep_softc *sc = ep_softc[is->id_unit];
168 struct ep_board *epb;
169 int i;
170
171 epb = &ep_board[is->id_unit];
172
173 if (sc == 0) {
174 if ((sc = ep_alloc(is->id_unit, epb)) == 0) {
175 return (ENXIO);
176 }
177 ep_unit++;
178 }
179
180 /* get_e() requires these. */
181 sc->ep_io_addr = is->id_iobase;
182 sc->unit = is->id_unit;
183 epb->epb_addr = is->id_iobase;
184 epb->epb_used = 1;
185
186 /*
187 * XXX - Certain (newer?) 3Com cards need epb->cmd_off == 2. Sadly,
188 * you need to have a correct cmd_off in order to identify the card.
189 * So we have to hit it with both and cross our virtual fingers. There's
190 * got to be a better way to do this. jyoung@accessus.net 09/11/1999
191 */
192
193 epb->cmd_off = 0;
194 epb->prod_id = get_e(sc, EEPROM_PROD_ID);
195 if (!ep_pccard_identify(epb, is->id_unit)) {
196 if (bootverbose) printf("ep%d: Pass 1 of 2 detection failed (nonfatal)\n", is->id_unit);
197 epb->cmd_off = 2;
198 epb->prod_id = get_e(sc, EEPROM_PROD_ID);
199 if (!ep_pccard_identify(epb, is->id_unit)) {
200 if (bootverbose) printf("ep%d: Pass 2 of 2 detection failed (fatal!)\n", is->id_unit);
201 printf("ep%d: Unit failed to come ready or product ID unknown! (id 0x%x)\n", is->id_unit, epb->prod_id);
202 return (ENXIO);
203 }
204 }
205
206 epb->res_cfg = get_e(sc, EEPROM_RESOURCE_CFG);
207 for (i = 0; i < 3; i++)
208 sc->epb->eth_addr[i] = get_e(sc, EEPROM_NODE_ADDR_0 + i);
209
210 if (ep_pccard_attach(devi) == 0)
211 return (ENXIO);
212
213 sc->arpcom.ac_if.if_snd.ifq_maxlen = ifqmaxlen;
214 return (0);
215}
216
217static int
218ep_pccard_identify(epb, unit)
219 struct ep_board *epb;
220 int unit;
221{
222 /* Determine device type and associated MII capabilities */
223 switch (epb->prod_id) {
224 case 0x6055: /* 3C556 */
225 if (bootverbose) printf("ep%d: 3Com 3C556\n", unit);
226 epb->mii_trans = 1;
227 return (1);
228 break; /* NOTREACHED */
229 case 0x4057: /* 3C574 */
230 if (bootverbose) printf("ep%d: 3Com 3C574\n", unit);
231 epb->mii_trans = 1;
232 return (1);
233 break; /* NOTREACHED */
234 case 0x4b57: /* 3C574B */
235 if (bootverbose) printf("ep%d: 3Com 3C574B, Megahertz 3CCFE574BT or Fast Etherlink 3C574-TX\n", unit);
236 epb->mii_trans = 1;
237 return (1);
238 break; /* NOTREACHED */
239 case 0x9058: /* 3C589 */
240 if (bootverbose) printf("ep%d: 3Com Etherlink III 3C589[B/C/D]\n", unit);
241 epb->mii_trans = 0;
242 return (1);
243 break; /* NOTREACHED */
244 }
245 return (0);
246}
247
248static int
249ep_pccard_attach(devi)
250 struct pccard_devinfo *devi;
251{
252 struct isa_device *is = &devi->isahd;
253 struct ep_softc *sc = ep_softc[is->id_unit];
254 u_short config;
255
256 sc->ep_connectors = 0;
257 config = inw(IS_BASE + EP_W0_CONFIG_CTRL);
258 if (config & IS_BNC) {
259 sc->ep_connectors |= BNC;
260 }
261 if (config & IS_UTP) {
262 sc->ep_connectors |= UTP;
263 }
264 if (!(sc->ep_connectors & 7))
265 /* (Apparently) non-fatal */
266 if(bootverbose) printf("ep%d: No connectors or MII.\n", is->id_unit);
267
268 sc->ep_connector = inw(BASE + EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;
269
270 /* ROM size = 0, ROM base = 0 */
271 /* For now, ignore AUTO SELECT feature of 3C589B and later. */
272 outw(BASE + EP_W0_ADDRESS_CFG, get_e(sc, EEPROM_ADDR_CFG) & 0xc000);
273
274 /* Fake IRQ must be 3 */
275 outw(BASE + EP_W0_RESOURCE_CFG, (sc->epb->res_cfg & 0x0fff) | 0x3000);
276
277 outw(BASE + EP_W0_PRODUCT_ID, sc->epb->prod_id);
278
279 if (sc->epb->mii_trans) {
280 /*
281 * turn on the MII transciever
282 */
283 GO_WINDOW(3);
284 outw(BASE + EP_W3_OPTIONS, 0x8040);
285 DELAY(1000);
286 outw(BASE + EP_W3_OPTIONS, 0xc040);
287 outw(BASE + EP_COMMAND, RX_RESET);
288 outw(BASE + EP_COMMAND, TX_RESET);
289 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
290 DELAY(1000);
291 outw(BASE + EP_W3_OPTIONS, 0x8040);
292 }
293
294 ep_attach(sc);
295
296 return 1;
297}
298
299static void
300ep_unload(devi)
301 struct pccard_devinfo *devi;
302{
303 struct ep_softc *sc = ep_softc[devi->isahd.id_unit];
304
305 if (sc->gone) {
306 printf("ep%d: already unloaded\n", devi->isahd.id_unit);
307 return;
308 }
309 sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
310 sc->gone = 1;
311 printf("ep%d: unload\n", devi->isahd.id_unit);
312}
313
314/*
315 * card_intr - Shared interrupt called from
316 * front end of PC-Card handler.
317 */
318static int
319card_intr(devi)
320 struct pccard_devinfo *devi;
321{
322 epintr(devi->isahd.id_unit);
323 return(1);
324}
325#endif /* NCARD > 0 */
326
327static int
328eeprom_rdy(sc)
329 struct ep_softc *sc;
330{
331 int i;
332
333 for (i = 0; is_eeprom_busy(BASE) && i < MAX_EEPROMBUSY; i++)
334 continue;
335 if (i >= MAX_EEPROMBUSY) {
336 printf("ep%d: eeprom failed to come ready.\n", sc->unit);
337 return (0);
338 }
339 return (1);
340}
341
103eeprom_rdy(sc)
104 struct ep_softc *sc;
105{
106 int i;
107
108 for (i = 0; is_eeprom_busy(BASE) && i < MAX_EEPROMBUSY; i++)
109 continue;
110 if (i >= MAX_EEPROMBUSY) {
111 printf("ep%d: eeprom failed to come ready.\n", sc->unit);
112 return (0);
113 }
114 return (1);
115}
116
342static struct ep_board *
343ep_look_for_board_at(is)
344 struct isa_device *is;
345{
346 int data, i, j, id_port = ELINK_ID_PORT;
347 int count = 0;
348
349 if (ep_current_tag == (EP_LAST_TAG + 1)) {
350 /* Come here just one time */
351
352 ep_current_tag--;
353
354 /* Look for the ISA boards. Init and leave them actived */
355 outb(id_port, 0);
356 outb(id_port, 0);
357
358 elink_idseq(0xCF);
359
360 elink_reset();
361 DELAY(DELAY_MULTIPLE * 10000);
362 for (i = 0; i < EP_MAX_BOARDS; i++) {
363 outb(id_port, 0);
364 outb(id_port, 0);
365 elink_idseq(0xCF);
366
367 data = get_eeprom_data(id_port, EEPROM_MFG_ID);
368 if (data != MFG_ID)
369 break;
370
371 /* resolve contention using the Ethernet address */
372
373 for (j = 0; j < 3; j++)
374 get_eeprom_data(id_port, j);
375
376 /* and save this address for later use */
377
378 for (j = 0; j < 3; j++)
379 ep_board[ep_boards].eth_addr[j] = get_eeprom_data(id_port, j);
380
381 ep_board[ep_boards].res_cfg =
382 get_eeprom_data(id_port, EEPROM_RESOURCE_CFG);
383
384 ep_board[ep_boards].prod_id =
385 get_eeprom_data(id_port, EEPROM_PROD_ID);
386
387 ep_board[ep_boards].epb_used = 0;
388#ifdef PC98
389 ep_board[ep_boards].epb_addr =
390 (get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x100 + 0x40d0;
391#else
392 ep_board[ep_boards].epb_addr =
393 (get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x10 + 0x200;
394
395 if (ep_board[ep_boards].epb_addr > 0x3E0)
396 /* Board in EISA configuration mode */
397 continue;
398#endif /* PC98 */
399
400 outb(id_port, ep_current_tag); /* tags board */
401 outb(id_port, ACTIVATE_ADAPTER_TO_CONFIG);
402 ep_boards++;
403 count++;
404 ep_current_tag--;
405 }
406
407 ep_board[ep_boards].epb_addr = 0;
408 if (count) {
409 printf("%d 3C5x9 board(s) on ISA found at", count);
410 for (j = 0; ep_board[j].epb_addr; j++)
411 if (ep_board[j].epb_addr <= 0x3E0)
412 printf(" 0x%x", ep_board[j].epb_addr);
413 printf("\n");
414 }
415 }
416
417 /* we have two cases:
418 *
419 * 1. Device was configured with 'port ?'
420 * In this case we search for the first unused card in list
421 *
422 * 2. Device was configured with 'port xxx'
423 * In this case we search for the unused card with that address
424 *
425 */
426
427 if (IS_BASE == -1) { /* port? */
428 for (i = 0; ep_board[i].epb_addr && ep_board[i].epb_used; i++)
429 ;
430 if (ep_board[i].epb_addr == 0)
431 return 0;
432
433 IS_BASE = ep_board[i].epb_addr;
434 ep_board[i].epb_used = 1;
435
436 return &ep_board[i];
437 } else {
438 for (i = 0;
439 ep_board[i].epb_addr && ep_board[i].epb_addr != IS_BASE;
440 i++)
441 ;
442
443 if (ep_board[i].epb_used || ep_board[i].epb_addr != IS_BASE)
444 return 0;
445
446 if (inw(IS_BASE + EP_W0_EEPROM_COMMAND) & EEPROM_TST_MODE) {
447 printf("ep%d: 3c5x9 at 0x%x in PnP mode. Disable PnP mode!\n",
448 is->id_unit, IS_BASE);
449 }
450 ep_board[i].epb_used = 1;
451
452 return &ep_board[i];
453 }
454}
455
456/*
457 * get_e: gets a 16 bits word from the EEPROM. we must have set the window
458 * before
459 */
460u_int16_t
461get_e(sc, offset)
462 struct ep_softc *sc;
463 int offset;
464{
465 if (!eeprom_rdy(sc))
466 return (0xffff);
467 outw(BASE + EP_W0_EEPROM_COMMAND, (EEPROM_CMD_RD << sc->epb->cmd_off) | offset);
468 if (!eeprom_rdy(sc))
469 return (0xffff);
470 return (inw(BASE + EP_W0_EEPROM_DATA));
471}
472
473struct ep_softc *
474ep_alloc(unit, epb)
117/*
118 * get_e: gets a 16 bits word from the EEPROM. we must have set the window
119 * before
120 */
121u_int16_t
122get_e(sc, offset)
123 struct ep_softc *sc;
124 int offset;
125{
126 if (!eeprom_rdy(sc))
127 return (0xffff);
128 outw(BASE + EP_W0_EEPROM_COMMAND, (EEPROM_CMD_RD << sc->epb->cmd_off) | offset);
129 if (!eeprom_rdy(sc))
130 return (0xffff);
131 return (inw(BASE + EP_W0_EEPROM_DATA));
132}
133
134struct ep_softc *
135ep_alloc(unit, epb)
475 int unit;
476 struct ep_board *epb;
136 int unit;
137 struct ep_board *epb;
477{
478 struct ep_softc *sc;
479
480 if (unit >= NEP) {
481 printf("ep: unit number (%d) too high\n", unit);
482 return NULL;
483 }
484

--- 25 unchanged lines hidden (view full) ---

510 struct ep_softc *sc;
511{
512 ep_softc[sc->unit] = NULL;
513 free(sc, M_DEVBUF);
514 return;
515}
516
517int
138{
139 struct ep_softc *sc;
140
141 if (unit >= NEP) {
142 printf("ep: unit number (%d) too high\n", unit);
143 return NULL;
144 }
145

--- 25 unchanged lines hidden (view full) ---

171 struct ep_softc *sc;
172{
173 ep_softc[sc->unit] = NULL;
174 free(sc, M_DEVBUF);
175 return;
176}
177
178int
518ep_isa_probe(is)
519 struct isa_device *is;
520{
521 struct ep_softc *sc;
522 struct ep_board *epb;
523 u_short k;
524
525 if ((epb = ep_look_for_board_at(is)) == 0)
526 return (0);
527
528 /*
529 * Allocate a storage area for us
530 */
531 sc = ep_alloc(ep_unit, epb);
532 if (!sc)
533 return (0);
534
535 is->id_unit = ep_unit++;
536
537 /*
538 * The iobase was found and MFG_ID was 0x6d50. PROD_ID should be
539 * 0x9[0-f]50 (IBM-PC)
540 * 0x9[0-f]5[0-f] (PC-98)
541 */
542 GO_WINDOW(0);
543 k = sc->epb->prod_id;
544#ifdef PC98
545 if ((k & 0xf0f0) != (PROD_ID & 0xf0f0)) {
546#else
547 if ((k & 0xf0ff) != (PROD_ID & 0xf0ff)) {
548#endif
549 printf("ep_isa_probe: ignoring model %04x\n", k);
550 ep_free(sc);
551 return (0);
552 }
553
554 k = sc->epb->res_cfg;
555
556 k >>= 12;
557
558 /* Now we have two cases again:
559 *
560 * 1. Device was configured with 'irq?'
561 * In this case we use irq read from the board
562 *
563 * 2. Device was configured with 'irq xxx'
564 * In this case we set up the board to use specified interrupt
565 *
566 */
567
568 if (is->id_irq == 0) { /* irq? */
569 is->id_irq = 1 << ((k == 2) ? 9 : k);
570 }
571
572 sc->stat = 0; /* 16 bit access */
573
574 /* By now, the adapter is already activated */
575
576 return (EP_IOSIZE); /* 16 bytes of I/O space used. */
577}
578
579static int
580ep_isa_attach(is)
581 struct isa_device *is;
582{
583 struct ep_softc *sc = ep_softc[is->id_unit];
584 u_short config;
585 int irq;
586
587 is->id_ointr = epintr;
588 sc->ep_connectors = 0;
589 config = inw(IS_BASE + EP_W0_CONFIG_CTRL);
590 if (config & IS_AUI) {
591 sc->ep_connectors |= AUI;
592 }
593 if (config & IS_BNC) {
594 sc->ep_connectors |= BNC;
595 }
596 if (config & IS_UTP) {
597 sc->ep_connectors |= UTP;
598 }
599 if (!(sc->ep_connectors & 7))
600 printf("no connectors!");
601 sc->ep_connector = inw(BASE + EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;
602 /*
603 * Write IRQ value to board
604 */
605
606 irq = ffs(is->id_irq) - 1;
607 if (irq == -1) {
608 printf(" invalid irq... cannot attach\n");
609 return 0;
610 }
611
612 GO_WINDOW(0);
613 SET_IRQ(BASE, irq);
614
615 ep_attach(sc);
616 return 1;
617}
618
619int
620ep_attach(sc)
621 struct ep_softc *sc;
622{
623 struct ifnet *ifp = &sc->arpcom.ac_if;
624 u_short *p;
625 int i;
626 int attached;
627

--- 47 unchanged lines hidden (view full) ---

675 ether_ifattach(ifp);
676 }
677
678#ifdef EP_LOCAL_STATS
679 sc->rx_no_first = sc->rx_no_mbuf =
680 sc->rx_bpf_disc = sc->rx_overrunf = sc->rx_overrunl =
681 sc->tx_underrun = 0;
682#endif
179ep_attach(sc)
180 struct ep_softc *sc;
181{
182 struct ifnet *ifp = &sc->arpcom.ac_if;
183 u_short *p;
184 int i;
185 int attached;
186

--- 47 unchanged lines hidden (view full) ---

234 ether_ifattach(ifp);
235 }
236
237#ifdef EP_LOCAL_STATS
238 sc->rx_no_first = sc->rx_no_mbuf =
239 sc->rx_bpf_disc = sc->rx_overrunf = sc->rx_overrunl =
240 sc->tx_underrun = 0;
241#endif
683 ep_fset(F_RX_FIRST);
242 EP_FSET(sc, F_RX_FIRST);
684 sc->top = sc->mcur = 0;
685
686 if (!attached) {
687 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
688 }
689 return 0;
690}
691

--- 122 unchanged lines hidden (view full) ---

814 ifp->if_flags |= IFF_RUNNING;
815 ifp->if_flags &= ~IFF_OACTIVE; /* just in case */
816
817#ifdef EP_LOCAL_STATS
818 sc->rx_no_first = sc->rx_no_mbuf =
819 sc->rx_bpf_disc = sc->rx_overrunf = sc->rx_overrunl =
820 sc->tx_underrun = 0;
821#endif
243 sc->top = sc->mcur = 0;
244
245 if (!attached) {
246 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
247 }
248 return 0;
249}
250

--- 122 unchanged lines hidden (view full) ---

373 ifp->if_flags |= IFF_RUNNING;
374 ifp->if_flags &= ~IFF_OACTIVE; /* just in case */
375
376#ifdef EP_LOCAL_STATS
377 sc->rx_no_first = sc->rx_no_mbuf =
378 sc->rx_bpf_disc = sc->rx_overrunf = sc->rx_overrunl =
379 sc->tx_underrun = 0;
380#endif
822 ep_fset(F_RX_FIRST);
381 EP_FSET(sc, F_RX_FIRST);
823 if (sc->top) {
824 m_freem(sc->top);
825 sc->top = sc->mcur = 0;
826 }
827 outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
828 outw(BASE + EP_COMMAND, SET_TX_START_THRESH | 16);
829
830 /*

--- 65 unchanged lines hidden (view full) ---

896 }
897 }
898 IF_DEQUEUE(&ifp->if_snd, m);
899
900 outw(BASE + EP_W1_TX_PIO_WR_1, len);
901 outw(BASE + EP_W1_TX_PIO_WR_1, 0x0); /* Second dword meaningless */
902
903 for (top = m; m != 0; m = m->m_next)
382 if (sc->top) {
383 m_freem(sc->top);
384 sc->top = sc->mcur = 0;
385 }
386 outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
387 outw(BASE + EP_COMMAND, SET_TX_START_THRESH | 16);
388
389 /*

--- 65 unchanged lines hidden (view full) ---

455 }
456 }
457 IF_DEQUEUE(&ifp->if_snd, m);
458
459 outw(BASE + EP_W1_TX_PIO_WR_1, len);
460 outw(BASE + EP_W1_TX_PIO_WR_1, 0x0); /* Second dword meaningless */
461
462 for (top = m; m != 0; m = m->m_next)
904 if (ep_ftst(F_ACCESS_32_BITS)) {
463 if (EP_FTST(sc, F_ACCESS_32_BITS)) {
905 outsl(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t),
906 m->m_len / 4);
907 if (m->m_len & 3)
908 outsb(BASE + EP_W1_TX_PIO_WR_1,
909 mtod(m, caddr_t) + (m->m_len & (~3)),
910 m->m_len & 3);
911 } else {
912 outsw(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t), m->m_len / 2);

--- 27 unchanged lines hidden (view full) ---

940 outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | 8);
941 }
942 splx(s);
943 return;
944 }
945 goto startagain;
946}
947
464 outsl(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t),
465 m->m_len / 4);
466 if (m->m_len & 3)
467 outsb(BASE + EP_W1_TX_PIO_WR_1,
468 mtod(m, caddr_t) + (m->m_len & (~3)),
469 m->m_len & 3);
470 } else {
471 outsw(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t), m->m_len / 2);

--- 27 unchanged lines hidden (view full) ---

499 outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | 8);
500 }
501 splx(s);
502 return;
503 }
504 goto startagain;
505}
506
948static void
949epintr(unit)
950 int unit;
951{
952 register struct ep_softc *sc = ep_softc[unit];
953
954 if (sc->gone) {
955 return;
956 }
957
958 ep_intr(sc);
959}
960
961void
962ep_intr(arg)
963 void *arg;
964{
965 struct ep_softc *sc;
966 register int status;
967 struct ifnet *ifp;
968 int x;

--- 121 unchanged lines hidden (view full) ---

1090 if (status & ERR_RX) {
1091 ++ifp->if_ierrors;
1092 if (status & ERR_RX_OVERRUN) {
1093 /*
1094 * we can think the rx latency is actually greather than we
1095 * expect
1096 */
1097#ifdef EP_LOCAL_STATS
507void
508ep_intr(arg)
509 void *arg;
510{
511 struct ep_softc *sc;
512 register int status;
513 struct ifnet *ifp;
514 int x;

--- 121 unchanged lines hidden (view full) ---

636 if (status & ERR_RX) {
637 ++ifp->if_ierrors;
638 if (status & ERR_RX_OVERRUN) {
639 /*
640 * we can think the rx latency is actually greather than we
641 * expect
642 */
643#ifdef EP_LOCAL_STATS
1098 if (ep_ftst(F_RX_FIRST))
644 if (EP_FTST(sc, F_RX_FIRST))
1099 sc->rx_overrunf++;
1100 else
1101 sc->rx_overrunl++;
1102#endif
1103 }
1104 goto out;
1105 }
1106 rx_fifo = rx_fifo2 = status & RX_BYTES_MASK;
1107
645 sc->rx_overrunf++;
646 else
647 sc->rx_overrunl++;
648#endif
649 }
650 goto out;
651 }
652 rx_fifo = rx_fifo2 = status & RX_BYTES_MASK;
653
1108 if (ep_ftst(F_RX_FIRST)) {
654 if (EP_FTST(sc, F_RX_FIRST)) {
1109 MGETHDR(m, M_DONTWAIT, MT_DATA);
1110 if (!m)
1111 goto out;
1112 if (rx_fifo >= MINCLSIZE)
1113 MCLGET(m, M_DONTWAIT);
1114 sc->top = sc->mcur = top = m;
1115#define EROUND ((sizeof(struct ether_header) + 3) & ~3)
1116#define EOFF (EROUND - sizeof(struct ether_header))

--- 21 unchanged lines hidden (view full) ---

1138 if (!m)
1139 goto out;
1140 if (rx_fifo >= MINCLSIZE)
1141 MCLGET(m, M_DONTWAIT);
1142 m->m_len = 0;
1143 mcur->m_next = m;
1144 lenthisone = min(rx_fifo, M_TRAILINGSPACE(m));
1145 }
655 MGETHDR(m, M_DONTWAIT, MT_DATA);
656 if (!m)
657 goto out;
658 if (rx_fifo >= MINCLSIZE)
659 MCLGET(m, M_DONTWAIT);
660 sc->top = sc->mcur = top = m;
661#define EROUND ((sizeof(struct ether_header) + 3) & ~3)
662#define EOFF (EROUND - sizeof(struct ether_header))

--- 21 unchanged lines hidden (view full) ---

684 if (!m)
685 goto out;
686 if (rx_fifo >= MINCLSIZE)
687 MCLGET(m, M_DONTWAIT);
688 m->m_len = 0;
689 mcur->m_next = m;
690 lenthisone = min(rx_fifo, M_TRAILINGSPACE(m));
691 }
1146 if (ep_ftst(F_ACCESS_32_BITS)) { /* default for EISA configured cards*/
692 if (EP_FTST(sc, F_ACCESS_32_BITS)) { /* default for EISA configured cards*/
1147 insl(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len,
1148 lenthisone / 4);
1149 m->m_len += (lenthisone & ~3);
1150 if (lenthisone & 3)
1151 insb(BASE + EP_W1_RX_PIO_RD_1,
1152 mtod(m, caddr_t) + m->m_len,
1153 lenthisone & 3);
1154 m->m_len += (lenthisone & 3);

--- 8 unchanged lines hidden (view full) ---

1163 }
1164
1165 if (status & ERR_RX_INCOMPLETE) { /* we haven't received the complete
1166 * packet */
1167 sc->mcur = m;
1168#ifdef EP_LOCAL_STATS
1169 sc->rx_no_first++; /* to know how often we come here */
1170#endif
693 insl(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len,
694 lenthisone / 4);
695 m->m_len += (lenthisone & ~3);
696 if (lenthisone & 3)
697 insb(BASE + EP_W1_RX_PIO_RD_1,
698 mtod(m, caddr_t) + m->m_len,
699 lenthisone & 3);
700 m->m_len += (lenthisone & 3);

--- 8 unchanged lines hidden (view full) ---

709 }
710
711 if (status & ERR_RX_INCOMPLETE) { /* we haven't received the complete
712 * packet */
713 sc->mcur = m;
714#ifdef EP_LOCAL_STATS
715 sc->rx_no_first++; /* to know how often we come here */
716#endif
1171 ep_frst(F_RX_FIRST);
717 EP_FRST(sc, F_RX_FIRST);
1172 if (!((status = inw(BASE + EP_W1_RX_STATUS)) & ERR_RX_INCOMPLETE)) {
1173 /* we see if by now, the packet has completly arrived */
1174 goto read_again;
1175 }
1176 outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_NEXT_EARLY_THRESH);
1177 return;
1178 }
1179 outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
1180 ++ifp->if_ipackets;
718 if (!((status = inw(BASE + EP_W1_RX_STATUS)) & ERR_RX_INCOMPLETE)) {
719 /* we see if by now, the packet has completly arrived */
720 goto read_again;
721 }
722 outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_NEXT_EARLY_THRESH);
723 return;
724 }
725 outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
726 ++ifp->if_ipackets;
1181 ep_fset(F_RX_FIRST);
727 EP_FSET(sc, F_RX_FIRST);
1182 top->m_pkthdr.rcvif = &sc->arpcom.ac_if;
1183 top->m_pkthdr.len = sc->cur_len;
1184
1185 if (ifp->if_bpf) {
1186 bpf_mtap(ifp, top);
1187
1188 /*
1189 * Note that the interface cannot be in promiscuous mode if there are

--- 6 unchanged lines hidden (view full) ---

1196 bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
1197 sizeof(eh->ether_dhost)) != 0 &&
1198 bcmp(eh->ether_dhost, etherbroadcastaddr,
1199 sizeof(eh->ether_dhost)) != 0) {
1200 if (sc->top) {
1201 m_freem(sc->top);
1202 sc->top = 0;
1203 }
728 top->m_pkthdr.rcvif = &sc->arpcom.ac_if;
729 top->m_pkthdr.len = sc->cur_len;
730
731 if (ifp->if_bpf) {
732 bpf_mtap(ifp, top);
733
734 /*
735 * Note that the interface cannot be in promiscuous mode if there are

--- 6 unchanged lines hidden (view full) ---

742 bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
743 sizeof(eh->ether_dhost)) != 0 &&
744 bcmp(eh->ether_dhost, etherbroadcastaddr,
745 sizeof(eh->ether_dhost)) != 0) {
746 if (sc->top) {
747 m_freem(sc->top);
748 sc->top = 0;
749 }
1204 ep_fset(F_RX_FIRST);
750 EP_FSET(sc, F_RX_FIRST);
1205#ifdef EP_LOCAL_STATS
1206 sc->rx_bpf_disc++;
1207#endif
1208 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
1209 outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
1210 return;
1211 }
1212 }

--- 10 unchanged lines hidden (view full) ---

1223 outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
1224 if (sc->top) {
1225 m_freem(sc->top);
1226 sc->top = 0;
1227#ifdef EP_LOCAL_STATS
1228 sc->rx_no_mbuf++;
1229#endif
1230 }
751#ifdef EP_LOCAL_STATS
752 sc->rx_bpf_disc++;
753#endif
754 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
755 outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
756 return;
757 }
758 }

--- 10 unchanged lines hidden (view full) ---

769 outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
770 if (sc->top) {
771 m_freem(sc->top);
772 sc->top = 0;
773#ifdef EP_LOCAL_STATS
774 sc->rx_no_mbuf++;
775#endif
776 }
1231 ep_fset(F_RX_FIRST);
777 EP_FSET(sc, F_RX_FIRST);
1232 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
1233 outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
1234}
1235
1236/*
1237 * Look familiar?
1238 */
1239static int

--- 93 unchanged lines hidden (view full) ---

1333 outw(BASE + EP_COMMAND, TX_RESET);
1334 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
1335 outw(BASE + EP_COMMAND, C_INTR_LATCH);
1336 outw(BASE + EP_COMMAND, SET_RD_0_MASK);
1337 outw(BASE + EP_COMMAND, SET_INTR_MASK);
1338 outw(BASE + EP_COMMAND, SET_RX_FILTER);
1339}
1340
778 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
779 outw(BASE + EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH);
780}
781
782/*
783 * Look familiar?
784 */
785static int

--- 93 unchanged lines hidden (view full) ---

879 outw(BASE + EP_COMMAND, TX_RESET);
880 while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
881 outw(BASE + EP_COMMAND, C_INTR_LATCH);
882 outw(BASE + EP_COMMAND, SET_RD_0_MASK);
883 outw(BASE + EP_COMMAND, SET_INTR_MASK);
884 outw(BASE + EP_COMMAND, SET_RX_FILTER);
885}
886
1341
1342#if 0
1343static int
1344send_ID_sequence(port)
1345 int port;
1346{
1347 int cx, al;
1348
1349 for (al = 0xff, cx = 0; cx < 255; cx++) {
1350 outb(port, al);
1351 al <<= 1;
1352 if (al & 0x100)
1353 al ^= 0xcf;
1354 }
1355 return (1);
1356}
1357#endif
1358
1359
1360/*
1361 * We get eeprom data from the id_port given an offset into the eeprom.
1362 * Basically; after the ID_sequence is sent to all of the cards; they enter
1363 * the ID_CMD state where they will accept command requests. 0x80-0xbf loads
1364 * the eeprom data. We then read the port 16 times and with every read; the
1365 * cards check for contention (ie: if one card writes a 0 bit and another
1366 * writes a 1 bit then the host sees a 0. At the end of the cycle; each card
1367 * compares the data on the bus; if there is a difference then that card goes
1368 * into ID_WAIT state again). In the meantime; one bit of data is returned in
1369 * the AX register which is conveniently returned to us by inb(). Hence; we
1370 * read 16 times getting one bit of data with each read.
1371 */
1372
1373static int
1374get_eeprom_data(id_port, offset)
1375 int id_port;
1376 int offset;
1377{
1378 int i, data = 0;
1379 outb(id_port, 0x80 + offset);
1380 for (i = 0; i < 16; i++) {
1381 DELAY(BIT_DELAY_MULTIPLE * 1000);
1382 data = (data << 1) | (inw(id_port) & 1);
1383 }
1384 return (data);
1385}
1386
1387#endif /* NEP > 0 */
887#endif /* NEP > 0 */