Deleted Added
sdiff udiff text old ( 15363 ) new ( 15813 )
full compact
1/*
2 * Copyright (c) 1995, David Greenman
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

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

19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $Id: if_ed.c,v 1.97 1996/04/23 18:36:54 nate Exp $
28 */
29
30/*
31 * Device driver for National Semiconductor DS8390/WD83C690 based ethernet
32 * adapters. By David Greenman, 29-April-1993
33 *
34 * Currently supports the Western Digital/SMC 8003 and 8013 series,
35 * the SMC Elite Ultra (8216), the 3Com 3c503, the NE1000 and NE2000,

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

125 u_char rec_page_start; /* first page of RX ring-buffer */
126 u_char rec_page_stop; /* last page of RX ring-buffer */
127 u_char next_packet; /* pointer to next unread RX packet */
128 struct kern_devconf kdc; /* kernel configuration database info */
129};
130
131static struct ed_softc ed_softc[NED];
132
133static int ed_attach __P((struct ed_softc *, int, int));
134static int ed_attach_isa __P((struct isa_device *));
135
136static void ed_init __P((struct ifnet *));
137static int ed_ioctl __P((struct ifnet *, int, caddr_t));
138static int ed_probe __P((struct isa_device *));
139static void ed_start __P((struct ifnet *));
140static void ed_reset __P((struct ifnet *));
141static void ed_watchdog __P((struct ifnet *));
142
143static void ed_stop __P((struct ed_softc *));
144static int ed_probe_generic8390 __P((struct ed_softc *));
145static int ed_probe_WD80x3 __P((struct isa_device *));
146static int ed_probe_3Com __P((struct isa_device *));
147static int ed_probe_Novell __P((struct isa_device *));
148static int ed_probe_Novell_generic __P((struct ed_softc *, int, int, int));
149
150#include "pci.h"
151#if NPCI > 0
152void *ed_attach_NE2000_pci __P((int, int));
153#endif
154
155#include "crd.h"
156#if NCRD > 0
157static int ed_probe_pccard __P((struct isa_device *, u_char *));
158#endif
159
160static void ds_getmcaf __P((struct ed_softc *, u_long *));
161
162static void ed_get_packet(struct ed_softc *, char *, /* u_short */ int, int);
163
164static void ed_rint __P((struct ed_softc *));
165static void ed_xmit __P((struct ed_softc *));
166static char * ed_ring_copy __P((struct ed_softc *, char *, char *,

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

171static void ed_pio_writemem __P((struct ed_softc *, char *,
172 /* u_short */ int, /* u_short */ int));
173static u_short ed_pio_write_mbufs __P((struct ed_softc *, struct mbuf *,
174 int));
175
176static void ed_setrcr(struct ed_softc *);
177static u_long ds_crc(u_char *ep);
178
179#if NCRD > 0
180#include <sys/select.h>
181#include <pccard/card.h>
182#include <pccard/driver.h>
183#include <pccard/slot.h>
184
185/*
186 * PC-Card (PCMCIA) specific code.

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

231 return(ENODEV);
232 /*
233 * Probe the device. If a value is returned, the
234 * device was found at the location.
235 */
236 sc->gone = 0;
237 if (ed_probe_pccard(&dp->isahd,dp->misc)==0)
238 return(ENXIO);
239 if (ed_attach_isa(&dp->isahd)==0)
240 return(ENXIO);
241 }
242 /*
243 * XXX TODO:
244 * If it was initialized before, the device structure
245 * should also be initialized. We should
246 * reset (and possibly restart) the hardware, but
247 * I am not sure of the best way to do this...

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

277
278/*
279 * card_intr - Shared interrupt called from
280 * front end of PC-Card handler.
281 */
282static int
283card_intr(struct pccard_dev *dp)
284{
285 edintr_sc(&ed_softc[dp->isahd.id_unit]);
286 return(1);
287}
288#endif /* NCRD > 0 */
289
290struct isa_driver eddriver = {
291 ed_probe,
292 ed_attach_isa,
293 "ed",
294 1 /* We are ultra sensitive */
295};
296
297/*
298 * Interrupt conversion table for WD/SMC ASIC/83C584
299 * (IRQ* are defined in icu.h)
300 */

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

1089 isa_dev->id_msize = memsize;
1090 return (ED_3COM_IO_PORTS);
1091}
1092
1093/*
1094 * Probe and vendor-specific initialization routine for NE1000/2000 boards
1095 */
1096static int
1097ed_probe_Novell_generic(sc, port, unit, flags)
1098 struct ed_softc *sc;
1099 int port;
1100 int unit;
1101 int flags;
1102{
1103 u_int memsize, n;
1104 u_char romdata[16], tmp;
1105 static char test_pattern[32] = "THIS is A memory TEST pattern";
1106 char test_buffer[32];
1107
1108 sc->asic_addr = port + ED_NOVELL_ASIC_OFFSET;
1109 sc->nic_addr = port + ED_NOVELL_NIC_OFFSET;
1110
1111 /* XXX - do Novell-specific probe here */
1112
1113 /* Reset the board */
1114#ifdef GWETHER
1115 outb(sc->asic_addr + ED_NOVELL_RESET, 0);
1116 DELAY(200);
1117#endif /* GWETHER */

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

1140
1141 /* Make sure that we really have an 8390 based board */
1142 if (!ed_probe_generic8390(sc))
1143 return (0);
1144
1145 sc->vendor = ED_VENDOR_NOVELL;
1146 sc->mem_shared = 0;
1147 sc->cr_proto = ED_CR_RD2;
1148
1149 /*
1150 * Test the ability to read and write to the NIC memory. This has the
1151 * side affect of determining if this is an NE1000 or an NE2000.
1152 */
1153
1154 /*
1155 * This prevents packets from being stored in the NIC memory when the

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

1242 mstart = x * ED_PAGE_SIZE;
1243 msize = ED_PAGE_SIZE;
1244 break;
1245 }
1246 }
1247 }
1248
1249 if (mstart == 0) {
1250 printf("ed%d: Cannot find start of RAM.\n", unit);
1251 return 0;
1252 }
1253 /* Search for the start of RAM. */
1254 for (x = (mstart / ED_PAGE_SIZE) + 1; x < 256; x++) {
1255 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
1256 if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
1257 for (i = 0; i < ED_PAGE_SIZE; i++)
1258 pbuf[i] = 255 - x;

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

1264 break;
1265 }
1266 } else {
1267 break;
1268 }
1269 }
1270
1271 if (msize == 0) {
1272 printf("ed%d: Cannot find any RAM, start : %d, x = %d.\n", unit, mstart, x);
1273 return 0;
1274 }
1275 printf("ed%d: RAM start at %d, size : %d.\n", unit, mstart, msize);
1276
1277 sc->mem_size = msize;
1278 sc->mem_start = (char *) mstart;
1279 sc->mem_end = (char *) (msize + mstart);
1280 sc->tx_page_start = mstart / ED_PAGE_SIZE;
1281 }
1282#endif /* GWETHER */
1283
1284 /*
1285 * Use one xmit buffer if < 16k, two buffers otherwise (if not told
1286 * otherwise).
1287 */
1288 if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING))
1289 sc->txb_cnt = 1;
1290 else
1291 sc->txb_cnt = 2;
1292
1293 sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
1294 sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE;
1295
1296 sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;

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

1307#endif /* GWETHER */
1308
1309 /* clear any pending interrupts that might have occurred above */
1310 outb(sc->nic_addr + ED_P0_ISR, 0xff);
1311
1312 return (ED_NOVELL_IO_PORTS);
1313}
1314
1315static int
1316ed_probe_Novell(isa_dev)
1317 struct isa_device *isa_dev;
1318{
1319 struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
1320
1321 isa_dev->id_maddr = 0;
1322 return ed_probe_Novell_generic(sc, isa_dev->id_iobase,
1323 isa_dev->id_unit, isa_dev->id_flags);
1324}
1325
1326#if NCRD > 0
1327
1328/*
1329 * Probe and vendor-specific initialization routine for PCCARDs
1330 */
1331static int
1332ed_probe_pccard(isa_dev, ether)
1333 struct isa_device *isa_dev;
1334 u_char *ether;
1335{

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

1428 }
1429
1430 /* clear any pending interupts that we may have caused */
1431 outb(sc->nic_addr + ED_P0_ISR, 0xff);
1432
1433 return (ED_PC_IO_PORTS);
1434}
1435
1436#endif /* NCRD > 0 */
1437
1438/*
1439 * Install interface into kernel networking data structures
1440 */
1441static int
1442ed_attach(sc, unit, flags)
1443 struct ed_softc *sc;
1444 int unit;
1445 int flags;
1446{
1447 struct ifnet *ifp = &sc->arpcom.ac_if;
1448
1449 /*
1450 * Set interface to stopped condition (reset)
1451 */
1452 ed_stop(sc);
1453
1454 if (!ifp->if_name) {
1455 /*
1456 * Initialize ifnet structure
1457 */
1458 ifp->if_softc = sc;
1459 ifp->if_unit = unit;
1460 ifp->if_name = "ed";
1461 ifp->if_output = ether_output;
1462 ifp->if_start = ed_start;
1463 ifp->if_ioctl = ed_ioctl;
1464 ifp->if_watchdog = ed_watchdog;
1465 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
1466
1467 /*
1468 * Set default state for ALTPHYS flag (used to disable the
1469 * tranceiver for AUI operation), based on compile-time
1470 * config option.
1471 */
1472 if (flags & ED_FLAGS_DISABLE_TRANCEIVER)
1473 ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX |
1474 IFF_MULTICAST | IFF_ALTPHYS);
1475 else
1476 ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX |
1477 IFF_MULTICAST);
1478
1479 /*
1480 * Attach the interface
1481 */
1482 if_attach(ifp);
1483 ether_ifattach(ifp);
1484 }
1485 /* device attach does transition from UNCONFIGURED to IDLE state */
1486 sc->kdc.kdc_state = DC_IDLE;
1487
1488 /*
1489 * Print additional info when attached
1490 */
1491 printf("%s%d: address %6D, ", ifp->if_name, ifp->if_unit,
1492 sc->arpcom.ac_enaddr, ":");
1493
1494 if (sc->type_str && (*sc->type_str != 0))
1495 printf("type %s ", sc->type_str);
1496 else
1497 printf("type unknown (0x%x) ", sc->type);
1498
1499 printf("%s ", sc->isa16bit ? "(16 bit)" : "(8 bit)");

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

1505 * If BPF is in the kernel, call the attach for it
1506 */
1507#if NBPFILTER > 0
1508 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
1509#endif
1510 return 1;
1511}
1512
1513static int
1514ed_attach_isa(isa_dev)
1515 struct isa_device *isa_dev;
1516{
1517 int unit = isa_dev->id_unit;
1518 struct ed_softc *sc = &ed_softc[unit];
1519 int flags = isa_dev->id_flags;
1520
1521 return ed_attach(sc, unit, flags);
1522}
1523
1524#if NPCI > 0
1525void *
1526ed_attach_NE2000_pci(unit, port)
1527 int unit;
1528 int port;
1529{
1530 struct ed_softc *sc = malloc(sizeof *sc, M_DEVBUF, M_NOWAIT);
1531 int isa_flags = 0;
1532
1533 if (!sc)
1534 return sc;
1535
1536 if (ed_probe_Novell_generic(sc, port, unit, isa_flags) == 0
1537 || ed_attach(sc, unit, isa_flags) == 0) {
1538 free(sc, M_DEVBUF);
1539 return NULL;
1540 }
1541 return sc;
1542}
1543#endif
1544
1545/*
1546 * Reset interface.
1547 */
1548static void
1549ed_reset(ifp)
1550 struct ifnet *ifp;
1551{
1552 struct ed_softc *sc = ifp->if_softc;

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

2094 outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA);
2095 }
2096}
2097
2098/*
2099 * Ethernet interface interrupt processor
2100 */
2101void
2102edintr_sc(sc)
2103 struct ed_softc *sc;
2104{
2105 struct ifnet *ifp = (struct ifnet *)sc;
2106 u_char isr;
2107
2108 if (sc->gone)
2109 return;
2110 /*
2111 * Set NIC to page 0 registers
2112 */

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

2302 if (isr & ED_ISR_CNT) {
2303 (void) inb(sc->nic_addr + ED_P0_CNTR0);
2304 (void) inb(sc->nic_addr + ED_P0_CNTR1);
2305 (void) inb(sc->nic_addr + ED_P0_CNTR2);
2306 }
2307 }
2308}
2309
2310void
2311edintr(unit)
2312 int unit;
2313{
2314 edintr_sc (&ed_softc[unit]);
2315}
2316
2317/*
2318 * Process an ioctl request. This code needs some work - it looks
2319 * pretty ugly.
2320 */
2321static int
2322ed_ioctl(ifp, command, data)
2323 register struct ifnet *ifp;
2324 int command;

--- 618 unchanged lines hidden ---