@@ 14,9 14,6 @@
#include "etherif.h"
-extern int slowinb(ulong);
-extern void slowoutb(ulong, uchar);
-
enum {
Cr = 0x00, /* command register, all pages */
@@ 149,6 146,26 @@ typedef struct {
uchar len1;
} Hdr;
+/*
+ * the 8390 register accesses must not be too close together
+ */
+void
+dp8390outb(ulong port, uchar x)
+{
+ outb(port, x);
+ microdelay(0);
+}
+
+long
+dp8390inb(ulong port)
+{
+ long x;
+
+ x = inb(port);
+ microdelay(0);
+ return x;
+}
+
static void
dp8390disable(Dp8390 *dp8390)
{
@@ 163,10 180,10 @@ dp8390disable(Dp8390 *dp8390)
* chip there if this is called when probing for a device
* at boot.
*/
- slowoutb(port+Cr, Page0|RDMAabort|Stp);
- slowoutb(port+Rbcr0, 0);
- slowoutb(port+Rbcr1, 0);
- for(timo = 10000; (slowinb(port+Isr) & Rst) == 0 && timo; timo--)
+ dp8390outb(port+Cr, Page0|RDMAabort|Stp);
+ dp8390outb(port+Rbcr0, 0);
+ dp8390outb(port+Rbcr1, 0);
+ for(timo = 10000; (dp8390inb(port+Isr) & Rst) == 0 && timo; timo--)
;
}
@@ 175,13 192,13 @@ dp8390ring(Dp8390 *dp8390)
{
ulong port = dp8390->dp8390;
- slowoutb(port+Pstart, dp8390->pstart);
- slowoutb(port+Pstop, dp8390->pstop);
- slowoutb(port+Bnry, dp8390->pstop-1);
+ dp8390outb(port+Pstart, dp8390->pstart);
+ dp8390outb(port+Pstop, dp8390->pstop);
+ dp8390outb(port+Bnry, dp8390->pstop-1);
- slowoutb(port+Cr, Page1|RDMAabort|Stp);
- slowoutb(port+Curr, dp8390->pstart);
- slowoutb(port+Cr, Page0|RDMAabort|Stp);
+ dp8390outb(port+Cr, Page1|RDMAabort|Stp);
+ dp8390outb(port+Curr, dp8390->pstart);
+ dp8390outb(port+Cr, Page0|RDMAabort|Stp);
dp8390->nxtpkt = dp8390->pstart;
}
@@ 200,11 217,11 @@ dp8390setea(Ether *ether)
* addresses as we never set the multicast
* enable.
*/
- cr = slowinb(port+Cr) & ~Txp;
- slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr));
+ cr = dp8390inb(port+Cr) & ~Txp;
+ dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr));
for(i = 0; i < sizeof(ether->ea); i++)
- slowoutb(port+Par0+i, ether->ea[i]);
- slowoutb(port+Cr, cr);
+ dp8390outb(port+Par0+i, ether->ea[i]);
+ dp8390outb(port+Cr, cr);
}
void
@@ 221,11 238,11 @@ dp8390getea(Ether *ether)
* addresses as we never set the multicast
* enable.
*/
- cr = slowinb(port+Cr) & ~Txp;
- slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr));
+ cr = dp8390inb(port+Cr) & ~Txp;
+ dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr));
for(i = 0; i < sizeof(ether->ea); i++)
- ether->ea[i] = slowinb(port+Par0+i);
- slowoutb(port+Cr, cr);
+ ether->ea[i] = dp8390inb(port+Par0+i);
+ dp8390outb(port+Cr, cr);
}
void*
@@ 240,25 257,25 @@ dp8390read(Dp8390 *dp8390, void *to, ulong from, ulong len)
* using the DP8390 remote DMA facility, and place it at
* 'to' in main memory, via the I/O data port.
*/
- cr = slowinb(port+Cr) & ~Txp;
- slowoutb(port+Cr, Page0|RDMAabort|Sta);
- slowoutb(port+Isr, Rdc);
+ cr = dp8390inb(port+Cr) & ~Txp;
+ dp8390outb(port+Cr, Page0|RDMAabort|Sta);
+ dp8390outb(port+Isr, Rdc);
/*
* Set up the remote DMA address and count.
*/
if(dp8390->bit16)
len = ROUNDUP(len, 2);
- slowoutb(port+Rbcr0, len & 0xFF);
- slowoutb(port+Rbcr1, (len>>8) & 0xFF);
- slowoutb(port+Rsar0, from & 0xFF);
- slowoutb(port+Rsar1, (from>>8) & 0xFF);
+ dp8390outb(port+Rbcr0, len & 0xFF);
+ dp8390outb(port+Rbcr1, (len>>8) & 0xFF);
+ dp8390outb(port+Rsar0, from & 0xFF);
+ dp8390outb(port+Rsar1, (from>>8) & 0xFF);
/*
* Start the remote DMA read and suck the data
* out of the I/O port.
*/
- slowoutb(port+Cr, Page0|RDMAread|Sta);
+ dp8390outb(port+Cr, Page0|RDMAread|Sta);
if(dp8390->bit16)
inss(dp8390->data, to, len/2);
else
@@ 271,11 288,11 @@ dp8390read(Dp8390 *dp8390, void *to, ulong from, ulong len)
* to the miracles of the bus, we could get this far
* and still be talking to a slot full of nothing.
*/
- for(timo = 10000; (slowinb(port+Isr) & Rdc) == 0 && timo; timo--)
+ for(timo = 10000; (dp8390inb(port+Isr) & Rdc) == 0 && timo; timo--)
;
- slowoutb(port+Isr, Rdc);
- slowoutb(port+Cr, cr);
+ dp8390outb(port+Isr, Rdc);
+ dp8390outb(port+Cr, cr);
return to;
}
@@ 298,9 315,9 @@ dp8390write(Dp8390 *dp8390, ulong to, void *from, ulong len)
* using the DP8390 remote DMA facility, reading it at
* 'from' in main memory, via the I/O data port.
*/
- cr = slowinb(port+Cr) & ~Txp;
- slowoutb(port+Cr, Page0|RDMAabort|Sta);
- slowoutb(port+Isr, Rdc);
+ cr = dp8390inb(port+Cr) & ~Txp;
+ dp8390outb(port+Cr, Page0|RDMAabort|Sta);
+ dp8390outb(port+Isr, Rdc);
if(dp8390->bit16)
len = ROUNDUP(len, 2);
@@ 311,24 328,24 @@ dp8390write(Dp8390 *dp8390, ulong to, void *from, ulong len)
* the initial set up for read.
*/
crda = to-1-dp8390->bit16;
- slowoutb(port+Rbcr0, (len+1+dp8390->bit16) & 0xFF);
- slowoutb(port+Rbcr1, ((len+1+dp8390->bit16)>>8) & 0xFF);
- slowoutb(port+Rsar0, crda & 0xFF);
- slowoutb(port+Rsar1, (crda>>8) & 0xFF);
- slowoutb(port+Cr, Page0|RDMAread|Sta);
+ dp8390outb(port+Rbcr0, (len+1+dp8390->bit16) & 0xFF);
+ dp8390outb(port+Rbcr1, ((len+1+dp8390->bit16)>>8) & 0xFF);
+ dp8390outb(port+Rsar0, crda & 0xFF);
+ dp8390outb(port+Rsar1, (crda>>8) & 0xFF);
+ dp8390outb(port+Cr, Page0|RDMAread|Sta);
for(;;){
- crda = slowinb(port+Crda0);
- crda |= slowinb(port+Crda1)<<8;
+ crda = dp8390inb(port+Crda0);
+ crda |= dp8390inb(port+Crda1)<<8;
if(crda == to){
/*
* Start the remote DMA write and make sure
* the registers are correct.
*/
- slowoutb(port+Cr, Page0|RDMAwrite|Sta);
+ dp8390outb(port+Cr, Page0|RDMAwrite|Sta);
- crda = slowinb(port+Crda0);
- crda |= slowinb(port+Crda1)<<8;
+ crda = dp8390inb(port+Crda0);
+ crda |= dp8390inb(port+Crda1)<<8;
if(crda != to)
panic("crda write %d to %d\n", crda, to);
@@ 349,15 366,15 @@ dp8390write(Dp8390 *dp8390, ulong to, void *from, ulong len)
* be almost immediate.
*/
tries = 0;
- while((slowinb(port+Isr) & Rdc) == 0){
+ while((dp8390inb(port+Isr) & Rdc) == 0){
if(tries++ >= 100000){
print("dp8390write dma timed out\n");
break;
}
}
- slowoutb(port+Isr, Rdc);
- slowoutb(port+Cr, cr);
+ dp8390outb(port+Isr, Rdc);
+ dp8390outb(port+Cr, cr);
splx(s);
return (void*)to;
@@ 369,10 386,10 @@ getcurr(Dp8390 *dp8390)
ulong port = dp8390->dp8390;
uchar cr, curr;
- cr = slowinb(port+Cr) & ~Txp;
- slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr));
- curr = slowinb(port+Curr);
- slowoutb(port+Cr, cr);
+ cr = dp8390inb(port+Cr) & ~Txp;
+ dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr));
+ curr = dp8390inb(port+Curr);
+ dp8390outb(port+Cr, cr);
return curr;
}
@@ 416,9 433,9 @@ receive(Ether *ether)
|| len < 60 || len > sizeof(Etherpkt)){
print("dp8390: H#%2.2ux#%2.2ux#%2.2ux#%2.2ux,%d\n",
hdr.status, hdr.next, hdr.len0, hdr.len1, len);
- slowoutb(port+Cr, Page0|RDMAabort|Stp);
+ dp8390outb(port+Cr, Page0|RDMAabort|Stp);
dp8390ring(dp8390);
- slowoutb(port+Cr, Page0|RDMAabort|Sta);
+ dp8390outb(port+Cr, Page0|RDMAabort|Sta);
return;
}
@@ 467,7 484,7 @@ receive(Ether *ether)
hdr.next--;
if(hdr.next < dp8390->pstart)
hdr.next = dp8390->pstop-1;
- slowoutb(port+Bnry, hdr.next);
+ dp8390outb(port+Bnry, hdr.next);
}
}
@@ 519,9 536,9 @@ write(Ether *ether, void *buf, long len)
if(dp8390->ram == 0)
dp8390write(dp8390, dp8390->tstart*Dp8390BufSz, pkt, len);
- slowoutb(port+Tbcr0, len & 0xFF);
- slowoutb(port+Tbcr1, (len>>8) & 0xFF);
- slowoutb(port+Cr, Page0|RDMAabort|Txp|Sta);
+ dp8390outb(port+Tbcr0, len & 0xFF);
+ dp8390outb(port+Tbcr1, (len>>8) & 0xFF);
+ dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta);
return len;
}
@@ 541,24 558,24 @@ overflow(Ether *ether)
* The following procedure is taken from the DP8390[12D] datasheet,
* it seems pretty adamant that this is what has to be done.
*/
- txp = slowinb(port+Cr) & Txp;
- slowoutb(port+Cr, Page0|RDMAabort|Stp);
+ txp = dp8390inb(port+Cr) & Txp;
+ dp8390outb(port+Cr, Page0|RDMAabort|Stp);
delay(2);
- slowoutb(port+Rbcr0, 0);
- slowoutb(port+Rbcr1, 0);
+ dp8390outb(port+Rbcr0, 0);
+ dp8390outb(port+Rbcr1, 0);
resend = 0;
- if(txp && (slowinb(port+Isr) & (Txe|Ptx)) == 0)
+ if(txp && (dp8390inb(port+Isr) & (Txe|Ptx)) == 0)
resend = 1;
- slowoutb(port+Tcr, Lb);
- slowoutb(port+Cr, Page0|RDMAabort|Sta);
+ dp8390outb(port+Tcr, Lb);
+ dp8390outb(port+Cr, Page0|RDMAabort|Sta);
receive(ether);
- slowoutb(port+Isr, Ovw);
- slowoutb(port+Tcr, 0);
+ dp8390outb(port+Isr, Ovw);
+ dp8390outb(port+Tcr, 0);
if(resend)
- slowoutb(port+Cr, Page0|RDMAabort|Txp|Sta);
+ dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta);
}
static void
@@ 579,12 596,12 @@ interrupt(Ureg *ur, void *arg)
* While there is something of interest,
* clear all the interrupts and process.
*/
- slowoutb(port+Imr, 0x00);
- while(isr = slowinb(port+Isr)){
+ dp8390outb(port+Imr, 0x00);
+ while(isr = dp8390inb(port+Isr)){
if(isr & Ovw){
overflow(ether);
- slowoutb(port+Isr, Ovw);
+ dp8390outb(port+Isr, Ovw);
ether->overflows++;
}
@@ 594,7 611,7 @@ interrupt(Ureg *ur, void *arg)
*/
if(isr & (Rxe|Prx)){
receive(ether);
- slowoutb(port+Isr, Rxe|Prx);
+ dp8390outb(port+Isr, Rxe|Prx);
}
/*
@@ 603,14 620,14 @@ interrupt(Ureg *ur, void *arg)
* and wake the output routine.
*/
if(isr & (Txe|Ptx)){
- r = slowinb(port+Tsr);
+ r = dp8390inb(port+Tsr);
if(isr & Txe){
if((r & (Cdh|Fu|Crs|Abt)))
print("dp8390: Tsr#%2.2ux\n", r);
ether->oerrs++;
}
- slowoutb(port+Isr, Txe|Ptx);
+ dp8390outb(port+Isr, Txe|Ptx);
if(isr & Ptx)
ether->outpackets++;
@@ 619,13 636,13 @@ interrupt(Ureg *ur, void *arg)
}
if(isr & Cnt){
- ether->frames += slowinb(port+Cntr0);
- ether->crcs += slowinb(port+Cntr1);
- ether->buffs += slowinb(port+Cntr2);
- slowoutb(port+Isr, Cnt);
+ ether->frames += dp8390inb(port+Cntr0);
+ ether->crcs += dp8390inb(port+Cntr1);
+ ether->buffs += dp8390inb(port+Cntr2);
+ dp8390outb(port+Isr, Cnt);
}
}
- slowoutb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe);
+ dp8390outb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe);
}
static void
@@ 637,9 654,9 @@ promiscuous(void *arg, int on)
* Set/reset promiscuous mode.
*/
if(on)
- slowoutb(dp8390->dp8390+Rcr, Pro|Ab);
+ dp8390outb(dp8390->dp8390+Rcr, Pro|Ab);
else
- slowoutb(dp8390->dp8390+Rcr, Ab);
+ dp8390outb(dp8390->dp8390+Rcr, Ab);
}
static void
@@ 653,8 670,8 @@ attach(Ether *ether)
* mode. Clear the missed-packet counter, it
* increments while in monitor mode.
*/
- slowoutb(dp8390->dp8390+Rcr, Ab);
- slowinb(dp8390->dp8390+Cntr2);
+ dp8390outb(dp8390->dp8390+Rcr, Ab);
+ dp8390inb(dp8390->dp8390+Cntr2);
}
int
@@ 673,15 690,15 @@ dp8390reset(Ether *ether)
*/
dp8390disable(dp8390);
if(dp8390->bit16)
- slowoutb(port+Dcr, Ft4|Ls|Wts);
+ dp8390outb(port+Dcr, Ft4|Ls|Wts);
else
- slowoutb(port+Dcr, Ft4|Ls);
+ dp8390outb(port+Dcr, Ft4|Ls);
- slowoutb(port+Rbcr0, 0);
- slowoutb(port+Rbcr1, 0);
+ dp8390outb(port+Rbcr0, 0);
+ dp8390outb(port+Rbcr1, 0);
- slowoutb(port+Tcr, 0);
- slowoutb(port+Rcr, Mon);
+ dp8390outb(port+Tcr, 0);
+ dp8390outb(port+Rcr, Mon);
/*
* Init the ring hardware and software ring pointers.
@@ 689,16 706,16 @@ dp8390reset(Ether *ether)
* it yet.
*/
dp8390ring(dp8390);
- slowoutb(port+Tpsr, dp8390->tstart);
+ dp8390outb(port+Tpsr, dp8390->tstart);
- slowoutb(port+Isr, 0xFF);
- slowoutb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe);
+ dp8390outb(port+Isr, 0xFF);
+ dp8390outb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe);
/*
* Leave the chip initialised,
* but in monitor mode.
*/
- slowoutb(port+Cr, Page0|RDMAabort|Sta);
+ dp8390outb(port+Cr, Page0|RDMAabort|Sta);
/*
* Set up the software configuration.