summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authordg <dg@FreeBSD.org>1993-09-22 17:47:43 +0000
committerdg <dg@FreeBSD.org>1993-09-22 17:47:43 +0000
commitee104ee3b555974be9e9aa1469f52a007de717cb (patch)
tree36df7a7721fa4906774a0406be16dee5071a3942 /sys/dev
parent79766d4d8db1baee779de44f10f31516568ee0b1 (diff)
downloadFreeBSD-src-ee104ee3b555974be9e9aa1469f52a007de717cb.zip
FreeBSD-src-ee104ee3b555974be9e9aa1469f52a007de717cb.tar.gz
rewrote interrupt code to be cleaner, fixed up some other parts
to make it easier to add future board types.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ed/if_ed.c406
-rw-r--r--sys/dev/ed/if_edreg.h4
2 files changed, 218 insertions, 192 deletions
diff --git a/sys/dev/ed/if_ed.c b/sys/dev/ed/if_ed.c
index 85524fa..eccee0f 100644
--- a/sys/dev/ed/if_ed.c
+++ b/sys/dev/ed/if_ed.c
@@ -14,9 +14,25 @@
*/
/*
+ * $Id: if_ed.c,v 1.29 93/09/12 04:43:31 davidg Exp Locker: davidg $
+ */
+
+/*
* Modification history
*
- * $Log: if_ed.c,v $
+ * Revision 1.29 93/09/12 04:43:31 davidg
+ * cleaned-up probe routine to make it easier to add future board types
+ *
+ * Revision 1.28 93/09/11 19:17:56 davidg
+ * rewrote interrupt code; leaner and meaner.
+ *
+ * Revision 1.27 93/09/10 19:15:09 davidg
+ * changed probe/attach so that the type code is printed if the board
+ * type isn't unknown
+ *
+ * Revision 1.26 93/09/09 02:12:08 davidg
+ * cleaned up header comments a little
+ *
* Revision 1.25 93/09/08 23:04:25 davidg
* fixed problem where 3c503 boards lock up if the cable is
* disconnected at boot time. Added printing of irq number if
@@ -59,6 +75,7 @@
#include "ed.h"
#if NED > 0
+/* bpfilter included here in case it is needed in future net includes */
#include "bpfilter.h"
#include "param.h"
@@ -114,10 +131,17 @@ struct ed_softc {
u_char vendor; /* interface vendor */
u_char type; /* interface type code */
- u_short vector; /* interrupt vector */
u_short asic_addr; /* ASIC I/O bus address */
u_short nic_addr; /* NIC (DS8390) I/O bus address */
+/*
+ * The following 'proto' variable is part of a work-around for 8013EBT asics
+ * being write-only. It's sort of a prototype/shadow of the real thing.
+ */
+ u_char wd_laar_proto;
+
+ u_char isa16bit; /* width of access to card mem 0=8 or 1=16 */
+
caddr_t smem_start; /* shared memory start address */
caddr_t smem_end; /* shared memory end address */
u_long smem_size; /* total shared memory size */
@@ -125,22 +149,16 @@ struct ed_softc {
caddr_t bpf; /* BPF "magic cookie" */
- u_char memwidth; /* width of access to card mem 8 or 16 */
u_char xmit_busy; /* transmitter is busy */
+ u_char data_buffered; /* data has been buffered in interface memory */
u_char txb_cnt; /* Number of transmit buffers */
u_char txb_next; /* Pointer to next buffer ready to xmit */
u_short txb_next_len; /* next xmit buffer length */
- u_char data_buffered; /* data has been buffered in interface memory */
u_char tx_page_start; /* first page of TX buffer area */
u_char rec_page_start; /* first page of RX ring-buffer */
u_char rec_page_stop; /* last page of RX ring-buffer */
u_char next_packet; /* pointer to next unread RX packet */
-/*
- * The following 'proto' variable is part of a work-around for 8013EBT asics
- * being write-only. It's sort of a prototype/shadow of the real thing.
- */
- u_char wd_laar_proto;
} ed_softc[NED];
int ed_attach(), ed_init(), edintr(), ed_ioctl(), ed_probe(),
@@ -193,37 +211,13 @@ ed_probe(isa_dev)
struct isa_device *isa_dev;
{
struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
- int i;
- u_char sum;
+ int nports;
- /*
- * Setup initial i/o address for ASIC and NIC
- */
- sc->asic_addr = isa_dev->id_iobase;
- sc->vector = isa_dev->id_irq;
- sc->smem_start = (caddr_t)isa_dev->id_maddr;
-
- /*
- * Attempt to do a checksum over the station address PROM.
- * This is mapped differently on the WD80x3 and 3C503, so if
- * it fails, it might be a 3C503. There is a problem with
- * this, though: some clone WD boards don't pass the
- * checksum test. Danpex boards for one. We need to do
- * additional checking for this case.
- */
- for (sum = 0, i = 0; i < 8; ++i) {
- sum += inb(sc->asic_addr + ED_WD_PROM + i);
- }
-
- if (sum == ED_WD_ROM_CHECKSUM_TOTAL) {
- return (ed_probe_WD80x3(isa_dev));
- } else {
- /*
- * XXX - Should do additional checking to make sure its a 3Com
- * and not a broken WD clone
- */
- return (ed_probe_3Com(isa_dev));
- }
+ if (nports = ed_probe_WD80x3(isa_dev))
+ return (nports);
+
+ if (nports = ed_probe_3Com(isa_dev))
+ return (nports);
}
/*
@@ -236,13 +230,27 @@ ed_probe_WD80x3(isa_dev)
struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
int i;
u_int memsize;
- u_char iptr, memwidth, sum, tmp;
+ u_char iptr, isa16bit, sum;
+
+ sc->asic_addr = isa_dev->id_iobase;
+ sc->nic_addr = sc->asic_addr + ED_WD_NIC_OFFSET;
+ /*
+ * Attempt to do a checksum over the station address PROM.
+ * If it fails, it's probably not a SMC/WD board. There
+ * is a problem with this, though: some clone WD boards
+ * don't pass the checksum test. Danpex boards for one.
+ * XXX - We need to do additional checking for this case.
+ */
+ for (sum = 0, i = 0; i < 8; ++i)
+ sum += inb(sc->asic_addr + ED_WD_PROM + i);
+
+ if (sum != ED_WD_ROM_CHECKSUM_TOTAL)
+ return(0);
+
sc->vendor = ED_VENDOR_WD_SMC;
sc->type = inb(sc->asic_addr + ED_WD_CARD_ID);
- sc->nic_addr = sc->asic_addr + ED_WD_NIC_OFFSET;
-
/* reset card to force it into a known state. */
outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST);
DELAY(100);
@@ -257,58 +265,58 @@ ed_probe_WD80x3(isa_dev)
case ED_TYPE_WD8003S:
sc->type_str = "WD8003S";
memsize = 8192;
- memwidth = 8;
+ isa16bit = 0;
break;
case ED_TYPE_WD8003E:
sc->type_str = "WD8003E";
memsize = 8192;
- memwidth = 8;
+ isa16bit = 0;
break;
case ED_TYPE_WD8013EBT:
sc->type_str = "WD8013EBT";
memsize = 16384;
- memwidth = 16;
+ isa16bit = 1;
break;
case ED_TYPE_WD8013EP: /* also WD8003EP */
if (inb(sc->asic_addr + ED_WD_ICR)
& ED_WD_ICR_16BIT) {
- memwidth = 16;
+ isa16bit = 1;
memsize = 16384;
sc->type_str = "WD8013EP";
} else {
- sc->type_str = "WD8003EP";
+ isa16bit = 0;
memsize = 8192;
- memwidth = 8;
+ sc->type_str = "WD8003EP";
}
break;
case ED_TYPE_WD8013WC:
sc->type_str = "WD8013WC";
memsize = 16384;
- memwidth = 16;
+ isa16bit = 1;
break;
case ED_TYPE_WD8013EBP:
sc->type_str = "WD8013EBP";
memsize = 16384;
- memwidth = 16;
+ isa16bit = 1;
break;
case ED_TYPE_WD8013EPC:
sc->type_str = "WD8013EPC";
memsize = 16384;
- memwidth = 16;
+ isa16bit = 1;
break;
default:
- sc->type_str = "unknown";
+ sc->type_str = "";
memsize = 8192;
- memwidth = 8;
+ isa16bit = 0;
break;
}
/*
* Make some adjustments to initial values depending on what is
* found in the ICR.
*/
- if ((memwidth == 16) && (sc->type != ED_TYPE_WD8013EBT)
+ if (isa16bit && (sc->type != ED_TYPE_WD8013EBT)
&& ((inb(sc->asic_addr + ED_WD_ICR) & ED_WD_ICR_16BIT) == 0)) {
- memwidth = 8;
+ isa16bit = 0;
memsize = 8192;
}
#if 0 /* This has caused more problems than it's worth */
@@ -318,8 +326,8 @@ ed_probe_WD80x3(isa_dev)
#endif
#if ED_DEBUG
- printf("type=%s memwidth=%d memsize=%d id_msize=%d\n",
- sc->type_str,memwidth,memsize,isa_dev->id_msize);
+ printf("type=%s isa16bit=%d memsize=%d id_msize=%d\n",
+ sc->type_str,isa16bit,memsize,isa_dev->id_msize);
for (i=0; i<8; i++)
printf("%x -> %x\n", i, inb(sc->asic_addr + i));
#endif
@@ -333,9 +341,9 @@ ed_probe_WD80x3(isa_dev)
* that '8bit' mode intentionally has precedence)
*/
if (isa_dev->id_flags & ED_FLAGS_FORCE_16BIT_MODE)
- memwidth = 16;
+ isa16bit = 1;
if (isa_dev->id_flags & ED_FLAGS_FORCE_8BIT_MODE)
- memwidth = 8;
+ isa16bit = 0;
/*
* Check 83C584 interrupt configuration register if this board has one
@@ -364,7 +372,9 @@ ed_probe_WD80x3(isa_dev)
inb(isa_dev->id_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
}
- sc->memwidth = memwidth;
+ sc->isa16bit = isa16bit;
+ sc->smem_start = (caddr_t)isa_dev->id_maddr;
+
/*
* allocate one xmit buffer if < 16k, two buffers otherwise
*/
@@ -398,13 +408,13 @@ ed_probe_WD80x3(isa_dev)
* Set upper address bits and 8/16 bit access to shared memory
*/
if ((sc->type & ED_WD_SOFTCONFIG) || (sc->type == ED_TYPE_WD8013EBT)) {
- if (memwidth == 8) {
- outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
- ((kvtop(sc->smem_start) >> 19) & ED_WD_LAAR_ADDRHI)));
- } else {
+ if (isa16bit) {
outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
ED_WD_LAAR_L16EN | ED_WD_LAAR_M16EN |
((kvtop(sc->smem_start) >> 19) & ED_WD_LAAR_ADDRHI)));
+ } else {
+ outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
+ ((kvtop(sc->smem_start) >> 19) & ED_WD_LAAR_ADDRHI)));
}
}
@@ -421,7 +431,7 @@ ed_probe_WD80x3(isa_dev)
/*
* Disable 16 bit access to shared memory
*/
- if (memwidth == 16)
+ if (isa16bit)
outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto &=
~ED_WD_LAAR_M16EN));
@@ -436,7 +446,7 @@ ed_probe_WD80x3(isa_dev)
* memory. and 2) so that other 8 bit devices with shared
* memory can be used in this 128k region, too.
*/
- if (memwidth == 16)
+ if (isa16bit)
outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto &=
~ED_WD_LAAR_M16EN));
@@ -453,16 +463,11 @@ ed_probe_3Com(isa_dev)
struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
int i;
u_int memsize;
- u_char memwidth, sum;
+ u_char isa16bit, sum;
- sc->vendor = ED_VENDOR_3COM;
sc->asic_addr = isa_dev->id_iobase + ED_3COM_ASIC_OFFSET;
sc->nic_addr = isa_dev->id_iobase + ED_3COM_NIC_OFFSET;
- sc->type_str = "3c503";
-
- memsize = 8192;
-
/*
* Verify that the kernel configured I/O address matches the board
* configured address
@@ -529,9 +534,15 @@ ed_probe_3Com(isa_dev)
return(0);
}
+ sc->vendor = ED_VENDOR_3COM;
+ sc->type_str = "3c503";
+
+ memsize = 8192;
+
/*
- * Reset NIC and ASIC. Enable on-board transceiver through reset sequence
- * because it'll lock up if the cable isn't connected if we don't.
+ * Reset NIC and ASIC. Enable on-board transceiver throughout reset
+ * sequence because it'll lock up if the cable isn't connected
+ * if we don't.
*/
outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_RST | ED_3COM_CR_XSEL);
@@ -595,9 +606,9 @@ ed_probe_3Com(isa_dev)
* The 3c503 forces the WTS bit to a one if this is a 16bit board
*/
if (inb(sc->nic_addr + ED_P2_DCR) & ED_DCR_WTS)
- memwidth = 16;
+ isa16bit = 1;
else
- memwidth = 8;
+ isa16bit = 0;
/*
* select page 0 registers
@@ -610,11 +621,12 @@ ed_probe_3Com(isa_dev)
sc->rec_page_start = ED_TXBUF_SIZE + ED_3COM_PAGE_OFFSET;
sc->rec_page_stop = memsize / ED_PAGE_SIZE + ED_3COM_PAGE_OFFSET;
+ sc->smem_start = (caddr_t)isa_dev->id_maddr;
sc->smem_size = memsize;
sc->smem_end = sc->smem_start + memsize;
sc->smem_ring = sc->smem_start + (ED_PAGE_SIZE * ED_TXBUF_SIZE);
- sc->memwidth = memwidth;
+ sc->isa16bit = isa16bit;
/*
* Initialize GA page start/stop registers. Probably only needed
@@ -748,10 +760,18 @@ ed_attach(isa_dev)
/*
* Print additional info when attached
*/
- printf("ed%d: address %s, type %s (%dbit) %s\n", isa_dev->id_unit,
- ether_sprintf(sc->arpcom.ac_enaddr), sc->type_str,
- sc->memwidth, ((sc->vendor == ED_VENDOR_3COM) &&
- (ifp->if_flags & IFF_ALTPHYS)) ? "tranceiver disabled" : "");
+ printf("ed%d: address %s, ", isa_dev->id_unit,
+ ether_sprintf(sc->arpcom.ac_enaddr));
+
+ if (sc->type_str && (*sc->type_str != 0))
+ printf("type %s ", sc->type_str);
+ else
+ printf("type unknown (0x%x) ", sc->type);
+
+ printf("%s ",sc->isa16bit ? "(16 bit)" : "(8 bit)");
+
+ printf("%s\n", ((sc->vendor == ED_VENDOR_3COM) &&
+ (ifp->if_flags & IFF_ALTPHYS)) ? "tranceiver disabled" : "");
/*
* If BPF is in the kernel, call the attach for it
@@ -856,7 +876,7 @@ ed_init(unit)
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
- if (sc->memwidth == 16) {
+ if (sc->isa16bit) {
/*
* Set FIFO threshold to 8, No auto-init Remote DMA,
* byte order=80x86, word-wide DMA xfers,
@@ -1088,12 +1108,12 @@ outloop:
* Don't update wd_laar_proto because we want to restore the
* previous state (because an arp reply in the input code
* may cause a call-back to ed_start)
+ * XXX - the call-back to 'start' is a bug, IMHO.
*/
- if (sc->memwidth == 16)
- if (sc->vendor == ED_VENDOR_WD_SMC) {
- outb(sc->asic_addr + ED_WD_LAAR,
- (sc->wd_laar_proto | ED_WD_LAAR_M16EN));
- }
+ if (sc->isa16bit && (sc->vendor == ED_VENDOR_WD_SMC)) {
+ outb(sc->asic_addr + ED_WD_LAAR,
+ (sc->wd_laar_proto | ED_WD_LAAR_M16EN));
+ }
buffer = sc->smem_start + (sc->txb_next * ED_TXBUF_SIZE * ED_PAGE_SIZE);
len = 0;
@@ -1106,10 +1126,8 @@ outloop:
/*
* Restore previous shared mem access type
*/
- if (sc->memwidth == 16)
- if (sc->vendor == ED_VENDOR_WD_SMC) {
- outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto);
- }
+ if (sc->isa16bit && (sc->vendor == ED_VENDOR_WD_SMC))
+ outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto);
sc->txb_next_len = MAX(len, ETHER_MIN_LEN);
@@ -1125,6 +1143,9 @@ outloop:
* If there is BPF support in the configuration, tap off here.
* The following has support for converting trailer packets
* back to normal.
+ * XXX - support for trailer packets in BPF should be moved into
+ * the bpf code proper to avoid code duplication in all of
+ * the drivers.
*/
#if NBPFILTER > 0
if (sc->bpf) {
@@ -1207,7 +1228,7 @@ outloop:
/*
* Ethernet interface receiver interrupt.
*/
-static inline void /* only called from one place, so may as well integrate */
+static inline void
ed_rint(unit)
int unit;
{
@@ -1310,40 +1331,55 @@ edintr(unit)
while (isr = inb(sc->nic_addr + ED_P0_ISR)) {
/*
- * reset all the bits that we are 'acknowleging'
+ * reset all the bits that we are 'acknowledging'
* by writing a '1' to each bit position that was set
* (writing a '1' *clears* the bit)
*/
outb(sc->nic_addr + ED_P0_ISR, isr);
/*
- * Transmit error. If a TX completed with an error, we end up
- * throwing the packet away. Really the only error that is
- * possible is excessive collisions, and in this case it is
- * best to allow the automatic mechanisms of TCP to backoff
- * the flow. Of course, with UDP we're screwed, but this is
- * expected when a network is heavily loaded.
+ * Handle transmitter interrupts. Handle these first
+ * because the receiver will reset the board under
+ * some conditions.
*/
- if (isr & ED_ISR_TXE) {
- u_char tsr = inb(sc->nic_addr + ED_P0_TSR);
- u_char ncr = inb(sc->nic_addr + ED_P0_NCR);
+ if (isr & (ED_ISR_PTX|ED_ISR_TXE)) {
+ u_char collisions = inb(sc->nic_addr + ED_P0_NCR);
/*
- * Excessive collisions (16)
+ * Check for transmit error. If a TX completed with an
+ * error, we end up throwing the packet away. Really
+ * the only error that is possible is excessive
+ * collisions, and in this case it is best to allow the
+ * automatic mechanisms of TCP to backoff the flow. Of
+ * course, with UDP we're screwed, but this is expected
+ * when a network is heavily loaded.
*/
- if ((tsr & ED_TSR_ABT) && (ncr == 0)) {
+ if (isr & ED_ISR_TXE) {
+
/*
- * When collisions total 16, the P0_NCR will
- * indicate 0, and the TSR_ABT is set.
+ * Excessive collisions (16)
*/
- sc->arpcom.ac_if.if_collisions += 16;
- } else
- sc->arpcom.ac_if.if_collisions += ncr;
+ if ((inb(sc->nic_addr + ED_P0_TSR) & ED_TSR_ABT)
+ && (collisions == 0)) {
+ /*
+ * When collisions total 16, the
+ * P0_NCR will indicate 0, and the
+ * TSR_ABT is set.
+ */
+ collisions = 16;
+ }
- /*
- * update output errors counter
- */
- ++sc->arpcom.ac_if.if_oerrors;
+ /*
+ * update output errors counter
+ */
+ ++sc->arpcom.ac_if.if_oerrors;
+ } else {
+ /*
+ * Update total number of successfully
+ * transmitted packets.
+ */
+ ++sc->arpcom.ac_if.if_opackets;
+ }
/*
* reset tx busy and output active flags
@@ -1355,111 +1391,98 @@ edintr(unit)
* clear watchdog timer
*/
sc->arpcom.ac_if.if_timer = 0;
- }
-
-
- /*
- * Receiver Error. One or more of: CRC error, frame alignment error
- * FIFO overrun, or missed packet.
- */
- if (isr & ED_ISR_RXE) {
- ++sc->arpcom.ac_if.if_ierrors;
-#ifdef ED_DEBUG
- printf("ed%d: receive error %x\n", unit,
- inb(sc->nic_addr + ED_P0_RSR));
-#endif
- }
- /*
- * Overwrite warning. In order to make sure that a lockup
- * of the local DMA hasn't occurred, we reset and
- * re-init the NIC. The NSC manual suggests only a
- * partial reset/re-init is necessary - but some
- * chips seem to want more. The DMA lockup has been
- * seen only with early rev chips - Methinks this
- * bug was fixed in later revs. -DG
- */
- if (isr & ED_ISR_OVW) {
- ++sc->arpcom.ac_if.if_ierrors;
- log(LOG_WARNING,
- "ed%d: warning - receiver ring buffer overrun\n",
- unit);
/*
- * Stop/reset/re-init NIC
+ * Add in total number of collisions on last
+ * transmission.
*/
- ed_reset(unit);
+ sc->arpcom.ac_if.if_collisions += collisions;
+
+ /*
+ * If data is ready to transmit, start it transmitting,
+ * otherwise defer until after handling receiver
+ */
+ if (sc->data_buffered)
+ ed_xmit(&sc->arpcom.ac_if);
}
/*
- * Transmission completed normally.
+ * Handle receiver interrupts
*/
- if (isr & ED_ISR_PTX) {
-
- /*
- * reset tx busy and output active flags
- */
- sc->xmit_busy = 0;
- sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
+ if (isr & (ED_ISR_PRX|ED_ISR_RXE|ED_ISR_OVW)) {
+ /*
+ * Overwrite warning. In order to make sure that a lockup
+ * of the local DMA hasn't occurred, we reset and
+ * re-init the NIC. The NSC manual suggests only a
+ * partial reset/re-init is necessary - but some
+ * chips seem to want more. The DMA lockup has been
+ * seen only with early rev chips - Methinks this
+ * bug was fixed in later revs. -DG
+ */
+ if (isr & ED_ISR_OVW) {
+ ++sc->arpcom.ac_if.if_ierrors;
+ log(LOG_WARNING,
+ "ed%d: warning - receiver ring buffer overrun\n",
+ unit);
+ /*
+ * Stop/reset/re-init NIC
+ */
+ ed_reset(unit);
+ } else {
- /*
- * clear watchdog timer
- */
- sc->arpcom.ac_if.if_timer = 0;
+ /*
+ * Receiver Error. One or more of: CRC error, frame
+ * alignment error FIFO overrun, or missed packet.
+ */
+ if (isr & ED_ISR_RXE) {
+ ++sc->arpcom.ac_if.if_ierrors;
+#ifdef ED_DEBUG
+ printf("ed%d: receive error %x\n", unit,
+ inb(sc->nic_addr + ED_P0_RSR));
+#endif
+ }
- /*
- * Update total number of successfully transmitted
- * packets.
- */
- ++sc->arpcom.ac_if.if_opackets;
+ /*
+ * Go get the packet(s)
+ * XXX - Doing this on an error is dubious
+ * because there shouldn't be any data to
+ * get (we've configured the interface to
+ * not accept packets with errors).
+ */
- /*
- * Add in total number of collisions on last
- * transmission.
- */
- sc->arpcom.ac_if.if_collisions += inb(sc->nic_addr +
- ED_P0_TBCR0);
- }
+ /*
+ * Enable 16bit access to shared memory first
+ * on WD/SMC boards.
+ */
+ if (sc->isa16bit &&
+ (sc->vendor == ED_VENDOR_WD_SMC)) {
- /*
- * Receive Completion. Go and get the packet.
- * XXX - Doing this on an error is dubious because there
- * shouldn't be any data to get (we've configured the
- * interface to not accept packets with errors).
- */
- if (isr & (ED_ISR_PRX|ED_ISR_RXE)) {
- /*
- * Enable access to shared memory on WD/SMC boards
- */
- if (sc->memwidth == 16)
- if (sc->vendor == ED_VENDOR_WD_SMC) {
outb(sc->asic_addr + ED_WD_LAAR,
(sc->wd_laar_proto |=
ED_WD_LAAR_M16EN));
}
- ed_rint (unit);
+ ed_rint (unit);
+
+ /* disable 16bit access */
+ if (sc->isa16bit &&
+ (sc->vendor == ED_VENDOR_WD_SMC)) {
- /*
- * Disable access to shared memory
- */
- if (sc->memwidth == 16)
- if (sc->vendor == ED_VENDOR_WD_SMC) {
outb(sc->asic_addr + ED_WD_LAAR,
(sc->wd_laar_proto &=
~ED_WD_LAAR_M16EN));
}
+ }
}
/*
* If it looks like the transmitter can take more data,
- * attempt to start output on the interface. If data is
- * already buffered and ready to go, send it first.
+ * attempt to start output on the interface.
+ * This is done after handling the receiver to
+ * give the receiver priority.
*/
- if ((sc->arpcom.ac_if.if_flags & IFF_OACTIVE) == 0) {
- if (sc->data_buffered)
- ed_xmit(&sc->arpcom.ac_if);
+ if ((sc->arpcom.ac_if.if_flags & IFF_OACTIVE) == 0)
ed_start(&sc->arpcom.ac_if);
- }
/*
* return NIC CR to standard state: page 0, remote DMA complete,
@@ -1835,4 +1858,3 @@ ed_ring_to_mbuf(sc,src,dst,total_len)
return (m);
}
#endif
-
diff --git a/sys/dev/ed/if_edreg.h b/sys/dev/ed/if_edreg.h
index 79f84c2..949acb4 100644
--- a/sys/dev/ed/if_edreg.h
+++ b/sys/dev/ed/if_edreg.h
@@ -1,6 +1,10 @@
/*
* National Semiconductor DS8390 NIC register definitions
*
+ * $Id$
+ *
+ * Modification history
+ *
* $Log: if_edreg.h,v $
* Revision 1.5 93/08/25 20:38:34 davidg
* added define for card type WD8013WC (10BaseT)
OpenPOWER on IntegriCloud