Deleted Added
full compact
1/*
2 * Device driver for National Semiconductor DS8390/WD83C690 based ethernet
3 * adapters. By David Greenman, 29-April-1993
4 *
5 * Copyright (C) 1993, David Greenman. This software may be used, modified,
6 * copied, distributed, and sold, in both source and binary form provided
7 * that the above copyright and these terms are retained. Under no
8 * circumstances is the author responsible for the proper functioning

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

15 *
16 * Thanks to Charles Hannum for proving to me with example code that the
17 * NE1000/2000 support could be added with minimal impact. Without
18 * this, I wouldn't have proceeded in this direction.
19 *
20 */
21
22/*
23 * $Id: if_ed.c,v 1.21 1993/10/23 04:52:41 davidg Exp $
24 */
25
26/*
27 * Modification history
28 *
29 * Revision 2.11 1993/10/23 04:21:03 davidg
30 * Novell probe changed to be invasive because of too many complaints
31 * about some clone boards not being reset properly and thus not
32 * found on a warmboot. Yuck.
33 *
34 * Revision 2.10 1993/10/23 04:07:12 davidg
35 * increment output errors if the device times out (done via watchdog)
36 *

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

146 u_short nic_addr; /* NIC (DS8390) I/O bus address */
147
148/*
149 * The following 'proto' variable is part of a work-around for 8013EBT asics
150 * being write-only. It's sort of a prototype/shadow of the real thing.
151 */
152 u_char wd_laar_proto;
153 u_char isa16bit; /* width of access to card 0=8 or 1=16 */
154
155 caddr_t bpf; /* BPF "magic cookie" */
156 caddr_t mem_start; /* NIC memory start address */
157 caddr_t mem_end; /* NIC memory end address */
158 u_long mem_size; /* total NIC memory size */
159 caddr_t mem_ring; /* start of RX ring-buffer (in NIC mem) */
160
161 u_char mem_shared; /* NIC memory is shared with host */

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

206 IRQ5,
207 IRQ7,
208 IRQ10,
209 IRQ11,
210 IRQ15,
211 IRQ4
212};
213
214#define ETHER_MIN_LEN 64
215#define ETHER_MAX_LEN 1518
216#define ETHER_ADDR_LEN 6
217#define ETHER_HDR_SIZE 14
218
219/*
220 * Determine if the device is present
221 *

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

236 return (nports);
237
238 if (nports = ed_probe_3Com(isa_dev))
239 return (nports);
240
241 if (nports = ed_probe_Novell(isa_dev))
242 return (nports);
243
244 return 0; /* Added by GW: don't fall off the end */
245}
246
247/*
248 * Generic probe routine for testing for the existance of a DS8390.
249 * Must be called after the NIC has just been reset. This routine
250 * works by looking at certain register values that are gauranteed
251 * to be initialized a certain way after power-up or reset. Seems
252 * not to currently work on the 83C690.

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

290{
291 struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
292 int i;
293 u_int memsize;
294 u_char iptr, isa16bit, sum;
295
296 sc->asic_addr = isa_dev->id_iobase;
297 sc->nic_addr = sc->asic_addr + ED_WD_NIC_OFFSET;
298
299 /*
300 * Attempt to do a checksum over the station address PROM.
301 * If it fails, it's probably not a SMC/WD board. There
302 * is a problem with this, though: some clone WD boards
303 * don't pass the checksum test. Danpex boards for one.
304 */
305 for (sum = 0, i = 0; i < 8; ++i)

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

367 memsize = 16384;
368 isa16bit = 1;
369 break;
370 case ED_TYPE_WD8013EPC:
371 sc->type_str = "WD8013EPC";
372 memsize = 16384;
373 isa16bit = 1;
374 break;
375 default:
376 sc->type_str = "";
377 memsize = 8192;
378 isa16bit = 0;
379 break;
380 }
381 /*
382 * Make some adjustments to initial values depending on what is

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

408 if (isa_dev->id_flags & ED_FLAGS_FORCE_8BIT_MODE)
409 isa16bit = 0;
410
411 /*
412 * Check 83C584 interrupt configuration register if this board has one
413 * XXX - we could also check the IO address register. But why
414 * bother...if we get past this, it *has* to be correct.
415 */
416 if (sc->type & ED_WD_SOFTCONFIG) {
417 /*
418 * Assemble together the encoded interrupt number.
419 */
420 iptr = (inb(isa_dev->id_iobase + ED_WD_ICR) & ED_WD_ICR_IR2) |
421 ((inb(isa_dev->id_iobase + ED_WD_IRR) &
422 (ED_WD_IRR_IR0 | ED_WD_IRR_IR1)) >> 5);
423 /*
424 * Translate it using translation table, and check for correctness.

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

429 return(0);
430 }
431 /*
432 * Enable the interrupt.
433 */
434 outb(isa_dev->id_iobase + ED_WD_IRR,
435 inb(isa_dev->id_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
436 }
437
438 sc->isa16bit = isa16bit;
439
440#ifdef notyet /* XXX - I'm not sure if PIO mode is even possible on WD/SMC boards */
441 /*
442 * The following allows the WD/SMC boards to be used in Programmed I/O
443 * mode - without mapping the NIC memory shared. ...Not the prefered
444 * way, but it might be the only way.
445 */

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

478 */
479 for (i = 0; i < ETHER_ADDR_LEN; ++i)
480 sc->arpcom.ac_enaddr[i] = inb(sc->asic_addr + ED_WD_PROM + i);
481
482 if (sc->mem_shared) {
483 /*
484 * Set address and enable interface shared memory.
485 */
486 outb(sc->asic_addr + ED_WD_MSR, ((kvtop(sc->mem_start) >> 13) &
487 ED_WD_MSR_ADDR) | ED_WD_MSR_MENB);
488
489 /*
490 * Set upper address bits and 8/16 bit access to shared memory
491 */
492 if (isa16bit) {
493 outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
494 ED_WD_LAAR_L16EN | ED_WD_LAAR_M16EN |
495 ((kvtop(sc->mem_start) >> 19) & ED_WD_LAAR_ADDRHI)));
496 } else {
497 if ((sc->type & ED_WD_SOFTCONFIG) || (sc->type == ED_TYPE_WD8013EBT)) {
498 outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
499 ((kvtop(sc->mem_start) >> 19) & ED_WD_LAAR_ADDRHI)));
500 }
501 }
502
503 /*
504 * Now zero memory and verify that it is clear
505 */
506 bzero(sc->mem_start, memsize);
507

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

1054 * Reset interface.
1055 */
1056int
1057ed_reset(unit)
1058 int unit;
1059{
1060 int s;
1061
1062 s = splnet();
1063
1064 /*
1065 * Stop interface and re-initialize.
1066 */
1067 ed_stop(unit);
1068 ed_init(unit);
1069
1070 (void) splx(s);

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

1078 int unit;
1079{
1080 struct ed_softc *sc = &ed_softc[unit];
1081 int n = 5000;
1082
1083 /*
1084 * Stop everything on the interface, and select page 0 registers.
1085 */
1086 outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
1087
1088 /*
1089 * Wait for interface to enter stopped state, but limit # of checks
1090 * to 'n' (about 5ms). It shouldn't even take 5us on modern
1091 * DS8390's, but just in case it's an old one.
1092 */
1093 while (((inb(sc->nic_addr + ED_P0_ISR) & ED_ISR_RST) == 0) && --n);
1094
1095}

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

1125 /* address not known */
1126 if (ifp->if_addrlist == (struct ifaddr *)0) return;
1127
1128 /*
1129 * Initialize the NIC in the exact order outlined in the NS manual.
1130 * This init procedure is "mandatory"...don't change what or when
1131 * things happen.
1132 */
1133 s = splnet();
1134
1135 /* reset transmitter flags */
1136 sc->xmit_busy = 0;
1137 sc->arpcom.ac_if.if_timer = 0;
1138
1139 sc->txb_inuse = 0;
1140 sc->txb_new = 0;
1141 sc->txb_next_tx = 0;
1142
1143 /* This variable is used below - don't move this assignment */
1144 sc->next_packet = sc->rec_page_start + 1;
1145
1146 /*
1147 * Set interface for page 0, Remote DMA complete, Stopped
1148 */
1149 outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
1150
1151 if (sc->isa16bit) {
1152 /*
1153 * Set FIFO threshold to 8, No auto-init Remote DMA,
1154 * byte order=80x86, word-wide DMA xfers,
1155 */
1156 outb(sc->nic_addr + ED_P0_DCR, ED_DCR_FT1|ED_DCR_WTS|ED_DCR_LS);
1157 } else {
1158 /*

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

1177 */
1178 outb(sc->nic_addr + ED_P0_TCR, ED_TCR_LB0);
1179
1180 /*
1181 * Initialize transmit/receive (ring-buffer) Page Start
1182 */
1183 outb(sc->nic_addr + ED_P0_TPSR, sc->tx_page_start);
1184 outb(sc->nic_addr + ED_P0_PSTART, sc->rec_page_start);
1185
1186 /*
1187 * Initialize Receiver (ring-buffer) Page Stop and Boundry
1188 */
1189 outb(sc->nic_addr + ED_P0_PSTOP, sc->rec_page_stop);
1190 outb(sc->nic_addr + ED_P0_BNRY, sc->rec_page_start);
1191
1192 /*

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

1202 * Counter overflow and Remote DMA complete are *not* enabled.
1203 */
1204 outb(sc->nic_addr + ED_P0_IMR,
1205 ED_IMR_PRXE|ED_IMR_PTXE|ED_IMR_RXEE|ED_IMR_TXEE|ED_IMR_OVWE);
1206
1207 /*
1208 * Program Command Register for page 1
1209 */
1210 outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STP);
1211
1212 /*
1213 * Copy out our station address
1214 */
1215 for (i = 0; i < ETHER_ADDR_LEN; ++i)
1216 outb(sc->nic_addr + ED_P1_PAR0 + i, sc->arpcom.ac_enaddr[i]);
1217
1218#if NBPFILTER > 0
1219 /*

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

1228 * Set Current Page pointer to next_packet (initialized above)
1229 */
1230 outb(sc->nic_addr + ED_P1_CURR, sc->next_packet);
1231
1232 /*
1233 * Set Command Register for page 0, Remote DMA complete,
1234 * and interface Start.
1235 */
1236 outb(sc->nic_addr + ED_P1_CR, ED_CR_RD2|ED_CR_STA);
1237
1238 /*
1239 * Take interface out of loopback
1240 */
1241 outb(sc->nic_addr + ED_P0_TCR, 0);
1242
1243 /*
1244 * If this is a 3Com board, the tranceiver must be software enabled
1245 * (there is no settable hardware default).

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

1275 struct ed_softc *sc = &ed_softc[ifp->if_unit];
1276 unsigned short len;
1277
1278 len = sc->txb_len[sc->txb_next_tx];
1279
1280 /*
1281 * Set NIC for page 0 register access
1282 */
1283 outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
1284
1285 /*
1286 * Set TX buffer start page
1287 */
1288 outb(sc->nic_addr + ED_P0_TPSR, sc->tx_page_start +
1289 sc->txb_next_tx * ED_TXBUF_SIZE);
1290
1291 /*
1292 * Set TX length
1293 */
1294 outb(sc->nic_addr + ED_P0_TBCR0, len);
1295 outb(sc->nic_addr + ED_P0_TBCR1, len >> 8);
1296
1297 /*
1298 * Set page 0, Remote DMA complete, Transmit Packet, and *Start*
1299 */
1300 outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_TXP|ED_CR_STA);
1301
1302 sc->xmit_busy = 1;
1303
1304 /*
1305 * Point to next transmit buffer slot and wrap if necessary.
1306 */
1307 sc->txb_next_tx++;
1308 if (sc->txb_next_tx == sc->txb_cnt)
1309 sc->txb_next_tx = 0;
1310
1311 /*
1312 * Set a timer just in case we never hear from the board again
1313 */
1314 ifp->if_timer = 2;
1315}
1316
1317/*
1318 * Start output on interface.
1319 * We make two assumptions here:
1320 * 1) that the current priority is set to splnet _before_ this code
1321 * is called *and* is returned to the appropriate priority after
1322 * return
1323 * 2) that the IFF_OACTIVE flag is checked before this code is called
1324 * (i.e. that the output part of the interface is idle)
1325 */
1326int
1327ed_start(ifp)
1328 struct ifnet *ifp;

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

1529 u_char boundry, current;
1530 u_short len;
1531 struct ed_ring packet_hdr;
1532 char *packet_ptr;
1533
1534 /*
1535 * Set NIC to page 1 registers to get 'current' pointer
1536 */
1537 outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STA);
1538
1539 /*
1540 * 'sc->next_packet' is the logical beginning of the ring-buffer - i.e.
1541 * it points to where new data has been buffered. The 'CURR'
1542 * (current) register points to the logical end of the ring-buffer
1543 * - i.e. it points to where additional new data will be added.
1544 * We loop here until the logical beginning equals the logical
1545 * end (or in other words, until the ring-buffer is empty).
1546 */

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

1591 */
1592 boundry = sc->next_packet - 1;
1593 if (boundry < sc->rec_page_start)
1594 boundry = sc->rec_page_stop - 1;
1595
1596 /*
1597 * Set NIC to page 0 registers to update boundry register
1598 */
1599 outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
1600
1601 outb(sc->nic_addr + ED_P0_BNRY, boundry);
1602
1603 /*
1604 * Set NIC to page 1 registers before looping to top (prepare to
1605 * get 'CURR' current pointer)
1606 */
1607 outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STA);
1608 }
1609}
1610
1611/*
1612 * Ethernet interface interrupt processor
1613 */
1614int
1615edintr(unit)
1616 int unit;
1617{
1618 struct ed_softc *sc = &ed_softc[unit];
1619 u_char isr;
1620
1621 /*
1622 * Set NIC to page 0 registers
1623 */
1624 outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
1625
1626 /*
1627 * loop until there are no more new interrupts
1628 */
1629 while (isr = inb(sc->nic_addr + ED_P0_ISR)) {
1630
1631 /*
1632 * reset all the bits that we are 'acknowledging'
1633 * by writing a '1' to each bit position that was set
1634 * (writing a '1' *clears* the bit)
1635 */
1636 outb(sc->nic_addr + ED_P0_ISR, isr);
1637
1638 /*
1639 * Handle transmitter interrupts. Handle these first
1640 * because the receiver will reset the board under
1641 * some conditions.
1642 */
1643 if (isr & (ED_ISR_PTX|ED_ISR_TXE)) {
1644 u_char collisions = inb(sc->nic_addr + ED_P0_NCR);
1645
1646 /*
1647 * Check for transmit error. If a TX completed with an
1648 * error, we end up throwing the packet away. Really
1649 * the only error that is possible is excessive
1650 * collisions, and in this case it is best to allow the
1651 * automatic mechanisms of TCP to backoff the flow. Of
1652 * course, with UDP we're screwed, but this is expected
1653 * when a network is heavily loaded.
1654 */
1655 if (isr & ED_ISR_TXE) {
1656
1657 /*
1658 * Excessive collisions (16)
1659 */
1660 if ((inb(sc->nic_addr + ED_P0_TSR) & ED_TSR_ABT)
1661 && (collisions == 0)) {
1662 /*

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

1788 ed_start(&sc->arpcom.ac_if);
1789
1790 /*
1791 * return NIC CR to standard state: page 0, remote DMA complete,
1792 * start (toggling the TXP bit off, even if was just set
1793 * in the transmit routine, is *okay* - it is 'edge'
1794 * triggered from low to high)
1795 */
1796 outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
1797
1798 /*
1799 * If the Network Talley Counters overflow, read them to
1800 * reset them. It appears that old 8390's won't
1801 * clear the ISR flag otherwise - resulting in an
1802 * infinite loop.
1803 */
1804 if (isr & ED_ISR_CNT) {
1805 (void) inb(sc->nic_addr + ED_P0_CNTR0);

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

1819 int command;
1820 caddr_t data;
1821{
1822 register struct ifaddr *ifa = (struct ifaddr *)data;
1823 struct ed_softc *sc = &ed_softc[ifp->if_unit];
1824 struct ifreq *ifr = (struct ifreq *)data;
1825 int s, error = 0;
1826
1827 s = splnet();
1828
1829 switch (command) {
1830
1831 case SIOCSIFADDR:
1832 ifp->if_flags |= IFF_UP;
1833
1834 switch (ifa->ifa_addr->sa_family) {
1835#ifdef INET

--- 542 unchanged lines hidden ---