* Revision 2.14 1993/11/22 10:55:30 davidg

* change all splnet's to splimp's
 *
 * Revision 2.13  1993/11/22  10:53:52  davidg
 * patch to add support for SMC8216 (Elite-Ultra) boards
 * from Glen H. Lowe
 *
 * Revision 2.12  1993/11/07  18:04:13  davidg
 * fix from Garrett Wollman:
 * add a return(0) at the end of ed_probe so that if the various device
 * specific probes fail that we just don't fall of the end of the function.
This commit is contained in:
David Greenman 1993-11-22 11:08:16 +00:00
parent b513c26294
commit 047ea5bd0c
4 changed files with 296 additions and 112 deletions

View File

@ -20,12 +20,24 @@
*/
/*
* $Id: if_ed.c,v 1.21 1993/10/23 04:52:41 davidg Exp $
* $Id: if_ed.c,v 2.14 1993/11/22 10:55:30 davidg Exp davidg $
*/
/*
* Modification history
*
* Revision 2.14 1993/11/22 10:55:30 davidg
* change all splnet's to splimp's
*
* Revision 2.13 1993/11/22 10:53:52 davidg
* patch to add support for SMC8216 (Elite-Ultra) boards
* from Glen H. Lowe
*
* Revision 2.12 1993/11/07 18:04:13 davidg
* fix from Garrett Wollman:
* add a return(0) at the end of ed_probe so that if the various device
* specific probes fail that we just don't fall of the end of the function.
*
* Revision 2.11 1993/10/23 04:21:03 davidg
* Novell probe changed to be invasive because of too many complaints
* about some clone boards not being reset properly and thus not
@ -151,6 +163,7 @@ struct ed_softc {
*/
u_char wd_laar_proto;
u_char isa16bit; /* width of access to card 0=8 or 1=16 */
int is790; /* set by the probe code if the card is 790 based */
caddr_t bpf; /* BPF "magic cookie" */
caddr_t mem_start; /* NIC memory start address */
@ -211,6 +224,19 @@ static unsigned short ed_intr_mask[] = {
IRQ4
};
/*
* Interrupt conversion table for 585/790 Combo
*/
static unsigned short ed_790_intr_mask[] = {
0,
IRQ9,
IRQ3,
IRQ4,
IRQ5,
IRQ10,
IRQ11,
IRQ15
};
#define ETHER_MIN_LEN 64
#define ETHER_MAX_LEN 1518
#define ETHER_ADDR_LEN 6
@ -241,7 +267,7 @@ ed_probe(isa_dev)
if (nports = ed_probe_Novell(isa_dev))
return (nports);
return 0; /* Added by GW: don't fall off the end */
return(0);
}
/*
@ -295,6 +321,7 @@ ed_probe_WD80x3(isa_dev)
sc->asic_addr = isa_dev->id_iobase;
sc->nic_addr = sc->asic_addr + ED_WD_NIC_OFFSET;
sc->is790 = 0;
/*
* Attempt to do a checksum over the station address PROM.
@ -372,6 +399,18 @@ ed_probe_WD80x3(isa_dev)
memsize = 16384;
isa16bit = 1;
break;
case ED_TYPE_SMC8216C:
sc->type_str = "SMC8216/SMC8216C";
memsize = 16384;
isa16bit = 1;
sc->is790 = 1;
break;
case ED_TYPE_SMC8216T:
sc->type_str = "SMC8216T";
memsize = 16384;
isa16bit = 1;
sc->is790 = 1;
break;
default:
sc->type_str = "";
memsize = 8192;
@ -413,7 +452,7 @@ ed_probe_WD80x3(isa_dev)
* XXX - we could also check the IO address register. But why
* bother...if we get past this, it *has* to be correct.
*/
if (sc->type & ED_WD_SOFTCONFIG) {
if ((sc->type & ED_WD_SOFTCONFIG) && (!sc->is790)) {
/*
* Assemble together the encoded interrupt number.
*/
@ -434,6 +473,19 @@ ed_probe_WD80x3(isa_dev)
outb(isa_dev->id_iobase + ED_WD_IRR,
inb(isa_dev->id_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
}
if (sc->is790) {
outb(isa_dev->id_iobase + 0x04, inb(isa_dev->id_iobase + 0x04) | 0x80);
iptr = ((inb(isa_dev->id_iobase + 0x0d) & 0x0c ) >> 2) |
((inb(isa_dev->id_iobase + 0x0d) & 0x40) >> 4);
outb(isa_dev->id_iobase + 0x04, inb(isa_dev->id_iobase + 0x04) & ~0x80);
if (ed_790_intr_mask[iptr] != isa_dev->id_irq) {
printf("ed%d: kernel configured irq %d doesn't match board configured irq %d %d\n",
isa_dev->id_unit, ffs(isa_dev->id_irq) - 1, ffs(ed_790_intr_mask[iptr]) -1, iptr);
return 0;
}
outb(isa_dev->id_iobase + 0x06, inb(isa_dev->id_iobase + 0x06) | 0x01);
}
sc->isa16bit = isa16bit;
@ -483,20 +535,34 @@ ed_probe_WD80x3(isa_dev)
/*
* Set address and enable interface shared memory.
*/
outb(sc->asic_addr + ED_WD_MSR, ((kvtop(sc->mem_start) >> 13) &
ED_WD_MSR_ADDR) | ED_WD_MSR_MENB);
if(!sc->is790) {
outb(sc->asic_addr + ED_WD_MSR, ((kvtop(sc->mem_start) >> 13) &
ED_WD_MSR_ADDR) | ED_WD_MSR_MENB);
} else {
outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_MENB);
outb(sc->asic_addr + 0x04, (inb(sc->asic_addr + 0x04) | 0x80));
outb(sc->asic_addr + 0x0b, ((kvtop(sc->mem_start) >> 13) & 0x0f) |
((kvtop(sc->mem_start) >> 11) & 0x40) |
(inb(sc->asic_addr + 0x0b) & 0xb0));
outb(sc->asic_addr + 0x04, (inb(sc->asic_addr + 0x04) & ~0x80));
}
/*
* Set upper address bits and 8/16 bit access to shared memory
*/
if (isa16bit) {
outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
ED_WD_LAAR_L16EN | ED_WD_LAAR_M16EN |
((kvtop(sc->mem_start) >> 19) & ED_WD_LAAR_ADDRHI)));
} else {
if ((sc->type & ED_WD_SOFTCONFIG) || (sc->type == ED_TYPE_WD8013EBT)) {
if (sc->is790) {
sc->wd_laar_proto = inb(sc->asic_addr + ED_WD_LAAR);
outb(sc->asic_addr + ED_WD_LAAR, ED_WD_LAAR_M16EN);
} else {
outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
((kvtop(sc->mem_start) >> 19) & ED_WD_LAAR_ADDRHI)));
ED_WD_LAAR_L16EN | ED_WD_LAAR_M16EN |
((kvtop(sc->mem_start) >> 19) & ED_WD_LAAR_ADDRHI)));
}
} else {
if ((sc->type & ED_WD_SOFTCONFIG) || (sc->type == ED_TYPE_WD8013EBT) && (!sc->is790)) {
outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
((kvtop(sc->mem_start) >> 19) & ED_WD_LAAR_ADDRHI)));
}
}
@ -1059,7 +1125,7 @@ ed_reset(unit)
{
int s;
s = splnet();
s = splimp();
/*
* Stop interface and re-initialize.
@ -1083,8 +1149,11 @@ ed_stop(unit)
/*
* Stop everything on the interface, and select page 0 registers.
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_STP);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
}
/*
* Wait for interface to enter stopped state, but limit # of checks
* to 'n' (about 5ms). It shouldn't even take 5us on modern
@ -1130,7 +1199,7 @@ ed_init(unit)
* This init procedure is "mandatory"...don't change what or when
* things happen.
*/
s = splnet();
s = splimp();
/* reset transmitter flags */
sc->xmit_busy = 0;
@ -1146,8 +1215,11 @@ ed_init(unit)
/*
* Set interface for page 0, Remote DMA complete, Stopped
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_STP);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
}
if (sc->isa16bit) {
/*
* Set FIFO threshold to 8, No auto-init Remote DMA,
@ -1182,6 +1254,9 @@ ed_init(unit)
*/
outb(sc->nic_addr + ED_P0_TPSR, sc->tx_page_start);
outb(sc->nic_addr + ED_P0_PSTART, sc->rec_page_start);
/* Set lower bits of byte addressable framing to 0 */
if (sc->is790)
outb(sc->nic_addr + 0x09, 0);
/*
* Initialize Receiver (ring-buffer) Page Stop and Boundry
@ -1207,8 +1282,11 @@ ed_init(unit)
/*
* Program Command Register for page 1
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STP);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_STP);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STP);
}
/*
* Copy out our station address
*/
@ -1233,8 +1311,11 @@ ed_init(unit)
* Set Command Register for page 0, Remote DMA complete,
* and interface Start.
*/
outb(sc->nic_addr + ED_P1_CR, ED_CR_RD2|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P1_CR, ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P1_CR, ED_CR_RD2|ED_CR_STA);
}
/*
* Take interface out of loopback
*/
@ -1280,8 +1361,11 @@ static inline void ed_xmit(ifp)
/*
* Set NIC for page 0 register access
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
}
/*
* Set TX buffer start page
*/
@ -1297,8 +1381,11 @@ static inline void ed_xmit(ifp)
/*
* Set page 0, Remote DMA complete, Transmit Packet, and *Start*
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_TXP|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_TXP | ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_TXP|ED_CR_STA);
}
sc->xmit_busy = 1;
/*
@ -1317,7 +1404,7 @@ static inline void ed_xmit(ifp)
/*
* Start output on interface.
* We make two assumptions here:
* 1) that the current priority is set to splnet _before_ this code
* 1) that the current priority is set to splimp _before_ this code
* is called *and* is returned to the appropriate priority after
* return
* 2) that the IFF_OACTIVE flag is checked before this code is called
@ -1534,8 +1621,11 @@ ed_rint(unit)
/*
* Set NIC to page 1 registers to get 'current' pointer
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STA);
}
/*
* 'sc->next_packet' is the logical beginning of the ring-buffer - i.e.
* it points to where new data has been buffered. The 'CURR'
@ -1596,15 +1686,22 @@ ed_rint(unit)
/*
* Set NIC to page 0 registers to update boundry register
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
}
outb(sc->nic_addr + ED_P0_BNRY, boundry);
/*
* Set NIC to page 1 registers before looping to top (prepare to
* get 'CURR' current pointer)
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STA);
}
}
}
@ -1621,8 +1718,11 @@ edintr(unit)
/*
* Set NIC to page 0 registers
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
}
/*
* loop until there are no more new interrupts
*/
@ -1641,7 +1741,7 @@ edintr(unit)
* some conditions.
*/
if (isr & (ED_ISR_PTX|ED_ISR_TXE)) {
u_char collisions = inb(sc->nic_addr + ED_P0_NCR);
u_char collisions = inb(sc->nic_addr + ED_P0_NCR) & 0x0f;
/*
* Check for transmit error. If a TX completed with an
@ -1652,6 +1752,7 @@ edintr(unit)
* course, with UDP we're screwed, but this is expected
* when a network is heavily loaded.
*/
(void) inb(sc->nic_addr + ED_P0_TSR);
if (isr & ED_ISR_TXE) {
/*
@ -1793,8 +1894,11 @@ edintr(unit)
* in the transmit routine, is *okay* - it is 'edge'
* triggered from low to high)
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
}
/*
* If the Network Talley Counters overflow, read them to
* reset them. It appears that old 8390's won't
@ -1824,7 +1928,7 @@ ed_ioctl(ifp, command, data)
struct ifreq *ifr = (struct ifreq *)data;
int s, error = 0;
s = splnet();
s = splimp();
switch (command) {

View File

@ -1,33 +1,19 @@
/*
* National Semiconductor DS8390 NIC register definitions
*
* $Id: if_edreg.h,v 2.0 93/09/29 00:37:15 davidg Exp Locker: davidg $
* $Id: if_edreg.h,v 2.1 1993/11/22 10:52:33 davidg Exp davidg $
*
* Modification history
*
* $Log: if_edreg.h,v $
* Revision 2.1 1993/11/22 10:52:33 davidg
* patch to add support for SMC8216 (Elite-Ultra) boards
* from Glen H. Lowe
*
* Revision 2.0 93/09/29 00:37:15 davidg
* changed double buffering flag to multi buffering
* made changes/additions for 3c503 multi-buffering
* ...companion to Rev. 2.0 of 'ed' driver.
*
* Revision 1.6 93/09/28 17:20:03 davidg
* first cut at PIO (e.g. NE1000/2000) support
*
* Revision 1.5 93/08/25 20:38:34 davidg
* added define for card type WD8013WC (10BaseT)
*
* Revision 1.4 93/08/14 20:07:55 davidg
* fix board type definition for 8013EP
*
* Revision 1.3 93/07/20 15:25:25 davidg
* added config flags for forcing 8/16bit mode and disabling double
* xmit buffers.
*
* Revision 1.2 93/06/23 03:03:05 davidg
* added some additional definitions for the 83C584 bus interface
* chip (SMC/WD boards)
*
* Revision 1.1 93/06/23 03:01:07 davidg
* Initial revision
*
@ -692,6 +678,8 @@ struct ed_ring {
#define ED_TYPE_WD8013WC 0x28
#define ED_TYPE_WD8013EBP 0x2c
#define ED_TYPE_WD8013EPC 0x29
#define ED_TYPE_SMC8216T 0x2a
#define ED_TYPE_SMC8216C 0x2b
/* Bit definitions in card ID */
#define ED_WD_REV_MASK 0x1f /* Revision mask */

View File

@ -20,12 +20,24 @@
*/
/*
* $Id: if_ed.c,v 1.21 1993/10/23 04:52:41 davidg Exp $
* $Id: if_ed.c,v 2.14 1993/11/22 10:55:30 davidg Exp davidg $
*/
/*
* Modification history
*
* Revision 2.14 1993/11/22 10:55:30 davidg
* change all splnet's to splimp's
*
* Revision 2.13 1993/11/22 10:53:52 davidg
* patch to add support for SMC8216 (Elite-Ultra) boards
* from Glen H. Lowe
*
* Revision 2.12 1993/11/07 18:04:13 davidg
* fix from Garrett Wollman:
* add a return(0) at the end of ed_probe so that if the various device
* specific probes fail that we just don't fall of the end of the function.
*
* Revision 2.11 1993/10/23 04:21:03 davidg
* Novell probe changed to be invasive because of too many complaints
* about some clone boards not being reset properly and thus not
@ -151,6 +163,7 @@ struct ed_softc {
*/
u_char wd_laar_proto;
u_char isa16bit; /* width of access to card 0=8 or 1=16 */
int is790; /* set by the probe code if the card is 790 based */
caddr_t bpf; /* BPF "magic cookie" */
caddr_t mem_start; /* NIC memory start address */
@ -211,6 +224,19 @@ static unsigned short ed_intr_mask[] = {
IRQ4
};
/*
* Interrupt conversion table for 585/790 Combo
*/
static unsigned short ed_790_intr_mask[] = {
0,
IRQ9,
IRQ3,
IRQ4,
IRQ5,
IRQ10,
IRQ11,
IRQ15
};
#define ETHER_MIN_LEN 64
#define ETHER_MAX_LEN 1518
#define ETHER_ADDR_LEN 6
@ -241,7 +267,7 @@ ed_probe(isa_dev)
if (nports = ed_probe_Novell(isa_dev))
return (nports);
return 0; /* Added by GW: don't fall off the end */
return(0);
}
/*
@ -295,6 +321,7 @@ ed_probe_WD80x3(isa_dev)
sc->asic_addr = isa_dev->id_iobase;
sc->nic_addr = sc->asic_addr + ED_WD_NIC_OFFSET;
sc->is790 = 0;
/*
* Attempt to do a checksum over the station address PROM.
@ -372,6 +399,18 @@ ed_probe_WD80x3(isa_dev)
memsize = 16384;
isa16bit = 1;
break;
case ED_TYPE_SMC8216C:
sc->type_str = "SMC8216/SMC8216C";
memsize = 16384;
isa16bit = 1;
sc->is790 = 1;
break;
case ED_TYPE_SMC8216T:
sc->type_str = "SMC8216T";
memsize = 16384;
isa16bit = 1;
sc->is790 = 1;
break;
default:
sc->type_str = "";
memsize = 8192;
@ -413,7 +452,7 @@ ed_probe_WD80x3(isa_dev)
* XXX - we could also check the IO address register. But why
* bother...if we get past this, it *has* to be correct.
*/
if (sc->type & ED_WD_SOFTCONFIG) {
if ((sc->type & ED_WD_SOFTCONFIG) && (!sc->is790)) {
/*
* Assemble together the encoded interrupt number.
*/
@ -434,6 +473,19 @@ ed_probe_WD80x3(isa_dev)
outb(isa_dev->id_iobase + ED_WD_IRR,
inb(isa_dev->id_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
}
if (sc->is790) {
outb(isa_dev->id_iobase + 0x04, inb(isa_dev->id_iobase + 0x04) | 0x80);
iptr = ((inb(isa_dev->id_iobase + 0x0d) & 0x0c ) >> 2) |
((inb(isa_dev->id_iobase + 0x0d) & 0x40) >> 4);
outb(isa_dev->id_iobase + 0x04, inb(isa_dev->id_iobase + 0x04) & ~0x80);
if (ed_790_intr_mask[iptr] != isa_dev->id_irq) {
printf("ed%d: kernel configured irq %d doesn't match board configured irq %d %d\n",
isa_dev->id_unit, ffs(isa_dev->id_irq) - 1, ffs(ed_790_intr_mask[iptr]) -1, iptr);
return 0;
}
outb(isa_dev->id_iobase + 0x06, inb(isa_dev->id_iobase + 0x06) | 0x01);
}
sc->isa16bit = isa16bit;
@ -483,20 +535,34 @@ ed_probe_WD80x3(isa_dev)
/*
* Set address and enable interface shared memory.
*/
outb(sc->asic_addr + ED_WD_MSR, ((kvtop(sc->mem_start) >> 13) &
ED_WD_MSR_ADDR) | ED_WD_MSR_MENB);
if(!sc->is790) {
outb(sc->asic_addr + ED_WD_MSR, ((kvtop(sc->mem_start) >> 13) &
ED_WD_MSR_ADDR) | ED_WD_MSR_MENB);
} else {
outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_MENB);
outb(sc->asic_addr + 0x04, (inb(sc->asic_addr + 0x04) | 0x80));
outb(sc->asic_addr + 0x0b, ((kvtop(sc->mem_start) >> 13) & 0x0f) |
((kvtop(sc->mem_start) >> 11) & 0x40) |
(inb(sc->asic_addr + 0x0b) & 0xb0));
outb(sc->asic_addr + 0x04, (inb(sc->asic_addr + 0x04) & ~0x80));
}
/*
* Set upper address bits and 8/16 bit access to shared memory
*/
if (isa16bit) {
outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
ED_WD_LAAR_L16EN | ED_WD_LAAR_M16EN |
((kvtop(sc->mem_start) >> 19) & ED_WD_LAAR_ADDRHI)));
} else {
if ((sc->type & ED_WD_SOFTCONFIG) || (sc->type == ED_TYPE_WD8013EBT)) {
if (sc->is790) {
sc->wd_laar_proto = inb(sc->asic_addr + ED_WD_LAAR);
outb(sc->asic_addr + ED_WD_LAAR, ED_WD_LAAR_M16EN);
} else {
outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
((kvtop(sc->mem_start) >> 19) & ED_WD_LAAR_ADDRHI)));
ED_WD_LAAR_L16EN | ED_WD_LAAR_M16EN |
((kvtop(sc->mem_start) >> 19) & ED_WD_LAAR_ADDRHI)));
}
} else {
if ((sc->type & ED_WD_SOFTCONFIG) || (sc->type == ED_TYPE_WD8013EBT) && (!sc->is790)) {
outb(sc->asic_addr + ED_WD_LAAR, (sc->wd_laar_proto =
((kvtop(sc->mem_start) >> 19) & ED_WD_LAAR_ADDRHI)));
}
}
@ -1059,7 +1125,7 @@ ed_reset(unit)
{
int s;
s = splnet();
s = splimp();
/*
* Stop interface and re-initialize.
@ -1083,8 +1149,11 @@ ed_stop(unit)
/*
* Stop everything on the interface, and select page 0 registers.
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_STP);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
}
/*
* Wait for interface to enter stopped state, but limit # of checks
* to 'n' (about 5ms). It shouldn't even take 5us on modern
@ -1130,7 +1199,7 @@ ed_init(unit)
* This init procedure is "mandatory"...don't change what or when
* things happen.
*/
s = splnet();
s = splimp();
/* reset transmitter flags */
sc->xmit_busy = 0;
@ -1146,8 +1215,11 @@ ed_init(unit)
/*
* Set interface for page 0, Remote DMA complete, Stopped
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_STP);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
}
if (sc->isa16bit) {
/*
* Set FIFO threshold to 8, No auto-init Remote DMA,
@ -1182,6 +1254,9 @@ ed_init(unit)
*/
outb(sc->nic_addr + ED_P0_TPSR, sc->tx_page_start);
outb(sc->nic_addr + ED_P0_PSTART, sc->rec_page_start);
/* Set lower bits of byte addressable framing to 0 */
if (sc->is790)
outb(sc->nic_addr + 0x09, 0);
/*
* Initialize Receiver (ring-buffer) Page Stop and Boundry
@ -1207,8 +1282,11 @@ ed_init(unit)
/*
* Program Command Register for page 1
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STP);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_STP);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STP);
}
/*
* Copy out our station address
*/
@ -1233,8 +1311,11 @@ ed_init(unit)
* Set Command Register for page 0, Remote DMA complete,
* and interface Start.
*/
outb(sc->nic_addr + ED_P1_CR, ED_CR_RD2|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P1_CR, ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P1_CR, ED_CR_RD2|ED_CR_STA);
}
/*
* Take interface out of loopback
*/
@ -1280,8 +1361,11 @@ static inline void ed_xmit(ifp)
/*
* Set NIC for page 0 register access
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
}
/*
* Set TX buffer start page
*/
@ -1297,8 +1381,11 @@ static inline void ed_xmit(ifp)
/*
* Set page 0, Remote DMA complete, Transmit Packet, and *Start*
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_TXP|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_TXP | ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_TXP|ED_CR_STA);
}
sc->xmit_busy = 1;
/*
@ -1317,7 +1404,7 @@ static inline void ed_xmit(ifp)
/*
* Start output on interface.
* We make two assumptions here:
* 1) that the current priority is set to splnet _before_ this code
* 1) that the current priority is set to splimp _before_ this code
* is called *and* is returned to the appropriate priority after
* return
* 2) that the IFF_OACTIVE flag is checked before this code is called
@ -1534,8 +1621,11 @@ ed_rint(unit)
/*
* Set NIC to page 1 registers to get 'current' pointer
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STA);
}
/*
* 'sc->next_packet' is the logical beginning of the ring-buffer - i.e.
* it points to where new data has been buffered. The 'CURR'
@ -1596,15 +1686,22 @@ ed_rint(unit)
/*
* Set NIC to page 0 registers to update boundry register
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
}
outb(sc->nic_addr + ED_P0_BNRY, boundry);
/*
* Set NIC to page 1 registers before looping to top (prepare to
* get 'CURR' current pointer)
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STA);
}
}
}
@ -1621,8 +1718,11 @@ edintr(unit)
/*
* Set NIC to page 0 registers
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
}
/*
* loop until there are no more new interrupts
*/
@ -1641,7 +1741,7 @@ edintr(unit)
* some conditions.
*/
if (isr & (ED_ISR_PTX|ED_ISR_TXE)) {
u_char collisions = inb(sc->nic_addr + ED_P0_NCR);
u_char collisions = inb(sc->nic_addr + ED_P0_NCR) & 0x0f;
/*
* Check for transmit error. If a TX completed with an
@ -1652,6 +1752,7 @@ edintr(unit)
* course, with UDP we're screwed, but this is expected
* when a network is heavily loaded.
*/
(void) inb(sc->nic_addr + ED_P0_TSR);
if (isr & ED_ISR_TXE) {
/*
@ -1793,8 +1894,11 @@ edintr(unit)
* in the transmit routine, is *okay* - it is 'edge'
* triggered from low to high)
*/
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
if (sc->is790) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_STA);
} else {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
}
/*
* If the Network Talley Counters overflow, read them to
* reset them. It appears that old 8390's won't
@ -1824,7 +1928,7 @@ ed_ioctl(ifp, command, data)
struct ifreq *ifr = (struct ifreq *)data;
int s, error = 0;
s = splnet();
s = splimp();
switch (command) {

View File

@ -1,33 +1,19 @@
/*
* National Semiconductor DS8390 NIC register definitions
*
* $Id: if_edreg.h,v 2.0 93/09/29 00:37:15 davidg Exp Locker: davidg $
* $Id: if_edreg.h,v 2.1 1993/11/22 10:52:33 davidg Exp davidg $
*
* Modification history
*
* $Log: if_edreg.h,v $
* Revision 2.1 1993/11/22 10:52:33 davidg
* patch to add support for SMC8216 (Elite-Ultra) boards
* from Glen H. Lowe
*
* Revision 2.0 93/09/29 00:37:15 davidg
* changed double buffering flag to multi buffering
* made changes/additions for 3c503 multi-buffering
* ...companion to Rev. 2.0 of 'ed' driver.
*
* Revision 1.6 93/09/28 17:20:03 davidg
* first cut at PIO (e.g. NE1000/2000) support
*
* Revision 1.5 93/08/25 20:38:34 davidg
* added define for card type WD8013WC (10BaseT)
*
* Revision 1.4 93/08/14 20:07:55 davidg
* fix board type definition for 8013EP
*
* Revision 1.3 93/07/20 15:25:25 davidg
* added config flags for forcing 8/16bit mode and disabling double
* xmit buffers.
*
* Revision 1.2 93/06/23 03:03:05 davidg
* added some additional definitions for the 83C584 bus interface
* chip (SMC/WD boards)
*
* Revision 1.1 93/06/23 03:01:07 davidg
* Initial revision
*
@ -692,6 +678,8 @@ struct ed_ring {
#define ED_TYPE_WD8013WC 0x28
#define ED_TYPE_WD8013EBP 0x2c
#define ED_TYPE_WD8013EPC 0x29
#define ED_TYPE_SMC8216T 0x2a
#define ED_TYPE_SMC8216C 0x2b
/* Bit definitions in card ID */
#define ED_WD_REV_MASK 0x1f /* Revision mask */