## diffname pc/ether8390.c 1992/1222 ## diff -e /dev/null /n/bootesdump/1992/1222/sys/src/9/pc/ether8390.c 0a /* * National Semiconductor DP8390 * and SMC 83C90 * Network Interface Controller. */ #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" #include "io.h" #include "devtab.h" #include "ether.h" enum { Cr = 0x00, /* command register, all pages */ Stp = 0x01, /* stop */ Sta = 0x02, /* start */ Txp = 0x04, /* transmit packet */ RDMAread = (1<<3), /* remote DMA read */ RDMAwrite = (2<<3), /* remote DMA write */ RDMAsend = (3<<3), /* remote DMA send packet */ RDMAabort = (4<<3), /* abort/complete remote DMA */ Page0 = (0x00<<6), /* page select */ Page1 = (0x01<<6), Page2 = (0x02<<6), }; enum { /* Page 0, read */ Clda0 = 0x01, /* current local DMA address 0 */ Clda1 = 0x02, /* current local DMA address 1 */ Bnry = 0x03, /* boundary pointer (R/W) */ Tsr = 0x04, /* transmit status register */ Ncr = 0x05, /* number of collisions register */ Fifo = 0x06, /* FIFO */ Isr = 0x07, /* interrupt status register (R/W) */ Crda0 = 0x08, /* current remote DMA address 0 */ Crda1 = 0x08, /* current remote DMA address 1 */ Rsr = 0x0C, /* receive status register */ Cntr0 = 0x0D, /* frame alignment errors */ Cntr1 = 0x0E, /* CRC errors */ Cntr2 = 0x0F, /* missed packet errors */ }; enum { /* Page 0, write */ Pstart = 0x01, /* page start register */ Pstop = 0x02, /* page stop register */ Tpsr = 0x04, /* transmit page start address */ Tbcr0 = 0x05, /* transmit byte count register 0 */ Tbcr1 = 0x06, /* transmit byte count register 1 */ Rsar0 = 0x08, /* remote start address register 0 */ Rsar1 = 0x09, /* remote start address register 1 */ Rbcr0 = 0x0A, /* remote byte count register 0 */ Rbcr1 = 0x0B, /* remote byte count register 1 */ Rcr = 0x0C, /* receive configuration register */ Tcr = 0x0D, /* transmit configuration register */ Dcr = 0x0E, /* data configuration register */ Imr = 0x0F, /* interrupt mask */ }; enum { /* Page 1, read/write */ Par0 = 0x01, /* physical address register 0 */ Curr = 0x07, /* current page register */ Mar0 = 0x08, /* multicast address register 0 */ }; enum { /* Interrupt Status Register */ Prx = 0x01, /* packet received */ Ptx = 0x02, /* packet transmitted */ Rxe = 0x04, /* receive error */ Txe = 0x08, /* transmit error */ Ovw = 0x10, /* overwrite warning */ Cnt = 0x20, /* counter overflow */ Rdc = 0x40, /* remote DMA complete */ Rst = 0x80, /* reset status */ }; enum { /* Interrupt Mask Register */ Prxe = 0x01, /* packet received interrupt enable */ Ptxe = 0x02, /* packet transmitted interrupt enable */ Rxee = 0x04, /* receive error interrupt enable */ Txee = 0x08, /* transmit error interrupt enable */ Ovwe = 0x10, /* overwrite warning interrupt enable */ Cnte = 0x20, /* counter overflow interrupt enable */ Rdce = 0x40, /* DMA complete interrupt enable */ }; enum { /* Data Configuration register */ Wts = 0x01, /* word transfer select */ Bos = 0x02, /* byte order select */ Las = 0x04, /* long address select */ Ls = 0x08, /* loopback select */ Arm = 0x10, /* auto-initialise remote */ Ft1 = (0x00<<5), /* FIFO threshhold select 1 byte/word */ Ft2 = (0x01<<5), /* FIFO threshhold select 2 bytes/words */ Ft4 = (0x02<<5), /* FIFO threshhold select 4 bytes/words */ Ft6 = (0x03<<5), /* FIFO threshhold select 6 bytes/words */ }; enum { /* Transmit Configuration Register */ Crc = 0x01, /* inhibit CRC */ Lb = 0x02, /* internal loopback */ Atd = 0x08, /* auto transmit disable */ Ofst = 0x10, /* collision offset enable */ }; enum { /* Transmit Status Register */ Ptxok = 0x01, /* packet transmitted */ Col = 0x04, /* transmit collided */ Abt = 0x08, /* tranmit aborted */ Crs = 0x10, /* carrier sense lost */ Fu = 0x20, /* FIFO underrun */ Cdh = 0x40, /* CD heartbeat */ Owc = 0x80, /* out of window collision */ }; enum { /* Receive Configuration Register */ Sep = 0x01, /* save errored packets */ Ar = 0x02, /* accept runt packets */ Ab = 0x04, /* accept broadcast */ Am = 0x08, /* accept multicast */ Pro = 0x10, /* promiscuous physical */ Mon = 0x20, /* monitor mode */ }; enum { /* Receive Status Register */ Prxok = 0x01, /* packet received intact */ Crce = 0x02, /* CRC error */ Fae = 0x04, /* frame alignment error */ Fo = 0x08, /* FIFO overrun */ Mpa = 0x10, /* missed packet */ Phy = 0x20, /* physical/multicast address */ Dis = 0x40, /* receiver disabled */ Dfr = 0x80, /* deferring */ }; typedef struct { uchar status; uchar next; uchar len0; uchar len1; } Hdr; typedef struct { Hdr; uchar data[Dp8390BufSz-sizeof(Hdr)]; } Buf; static void dp8390disable(Ctlr *ctlr) { Board *board = ctlr->board; int timo; /* * Stop the chip. Set the Stp bit and wait for the chip * to finish whatever was on its tiny mind before it sets * the Rst bit. * We need the timeout because there may not be a real * chip there if this is called when probing for a device * at boot. */ outb(board->dp8390+Cr, Page0|RDMAabort|Stp); for(timo = 10000; (inb(board->dp8390+Isr) & Rst) == 0 && timo; timo--) ; } void dp8390reset(Ctlr *ctlr) { Board *board = ctlr->board; /* * This is the initialisation procedure described * as 'mandatory' in the datasheet. */ dp8390disable(ctlr); if(board->bit16) outb(board->dp8390+Dcr, Ft4|Ls|Wts); else outb(board->dp8390+Dcr, Ft4|Ls); outb(board->dp8390+Rbcr0, 0); outb(board->dp8390+Rbcr1, 0); outb(board->dp8390+Rcr, Ab); outb(board->dp8390+Tcr, Lb); outb(board->dp8390+Bnry, board->pstart); outb(board->dp8390+Pstart, board->pstart); outb(board->dp8390+Pstop, board->pstop); outb(board->dp8390+Isr, 0xFF); outb(board->dp8390+Imr, Ovwe|Txee|Rxee|Ptxe|Prxe); outb(board->dp8390+Cr, Page1|RDMAabort|Stp); /* * Can't initialise ethernet address as we may * not know it yet. */ outb(board->dp8390+Curr, board->pstart+1); /* * Leave the chip initialised, * but in internal loopback mode. */ outb(board->dp8390+Cr, Page0|RDMAabort|Sta); outb(board->dp8390+Tpsr, board->tstart); } void dp8390attach(Ctlr *ctlr) { /* * Enable the chip for transmit/receive. * The init routine leaves the chip in internal * loopback. */ outb(ctlr->board->dp8390+Tcr, 0); } void dp8390mode(Ctlr *ctlr, int on) { if(on) outb(ctlr->board->dp8390+Rcr, Pro|Ab); else outb(ctlr->board->dp8390+Rcr, Ab); } void dp8390setea(Ctlr *ctlr) { Board *board = ctlr->board; uchar cr; int i; /* * Set the ethernet address into the chip. * Take care to restore the command register * afterwards. We don't care about multicast * addresses as we never set the multicast * enable. */ cr = inb(board->dp8390+Cr); outb(board->dp8390+Cr, Page1|(~Page0 & cr)); for(i = 0; i < sizeof(ctlr->ea); i++) outb(board->dp8390+Par0+i, ctlr->ea[i]); outb(board->dp8390+Cr, cr); } void* dp8390read(Ctlr *ctlr, void *to, ulong from, ulong len) { Board *board = ctlr->board; uchar cr; int timo; /* * If the interface has shared memory, just * do a memmove. * In this case, 'from' is an index into the shared memory. */ if(board->ram){ memmove(to, (void*)(board->ramstart+from), len); return to; } /* * Read some data at offset 'from' in the board's memory * using the DP8390 remote DMA facility, and place it at * 'to' in main memory, via the I/O data port. */ cr = inb(board->dp8390+Cr); outb(board->dp8390+Cr, Page0|RDMAabort|Sta); outb(board->dp8390+Isr, Rdc); /* * Set up the remote DMA address and count. */ if(board->bit16) len = ROUNDUP(len, 2); outb(board->dp8390+Rbcr0, len & 0xFF); outb(board->dp8390+Rbcr1, (len>>8) & 0xFF); outb(board->dp8390+Rsar0, from & 0xFF); outb(board->dp8390+Rsar1, (from>>8) & 0xFF); /* * Start the remote DMA read and suck the data * out of the I/O port. */ outb(board->dp8390+Cr, Page0|RDMAread|Sta); if(board->bit16) inss(board->data, to, len/2); else insb(board->data, to, len); /* * Wait for the remote DMA to complete. The timeout * is necessary because we may call this routine on * a non-existent chip during initialisation and, due * to the miracles of the bus, we could get this far * and still be talking to a slot full of nothing. */ for(timo = 10000; (inb(board->dp8390+Isr) & Rdc) == 0 && timo; timo--) ; outb(board->dp8390+Isr, Rdc); outb(board->dp8390+Cr, cr); return to; } void* dp8390write(Ctlr *ctlr, ulong to, void *from, ulong len) { Board *board = ctlr->board; uchar cr; /* * If the interface has shared memory, just * do a memmove. * In this case, 'to' is an index into the shared memory. */ if(board->ram){ memmove((void*)(board->ramstart+to), from, len); return (void*)to; } /* * Write some data to offset 'to' in the board's memory * using the DP8390 remote DMA facility, reading it at * 'from' in main memory, via the I/O data port. */ cr = inb(board->dp8390+Cr); outb(board->dp8390+Cr, Page0|RDMAabort|Sta); outb(board->dp8390+Isr, Rdc); /* * Set up the remote DMA address and count. * This is straight from the datasheet, hence * the initial write to Rbcr0 and Cr. */ outb(board->dp8390+Rbcr0, 0xFF); outb(board->dp8390+Cr, Page0|RDMAread|Sta); if(board->bit16) len = ROUNDUP(len, 2); outb(board->dp8390+Rbcr0, len & 0xFF); outb(board->dp8390+Rbcr1, (len>>8) & 0xFF); outb(board->dp8390+Rsar0, to & 0xFF); outb(board->dp8390+Rsar1, (to>>8) & 0xFF); /* * Start the remote DMA write and pump the data * into the I/O port. */ outb(board->dp8390+Cr, Page0|RDMAwrite|Sta); if(board->bit16) outss(board->data, from, len/2); else outsb(board->data, from, len); /* * Wait for the remote DMA to finish. We'll need * a timeout here if this ever gets called before * we know there really is a chip there. */ while((inb(board->dp8390+Isr) & Rdc) == 0) ; outb(board->dp8390+Isr, Rdc); outb(board->dp8390+Cr, cr); return (void*)to; } void dp8390receive(Ctlr *ctlr) { Board *board = ctlr->board; RingBuf *ring; uchar bnry, curr, next; Hdr hdr; ulong data; int i, len; bnry = inb(board->dp8390+Bnry); next = bnry+1; if(next >= board->pstop) next = board->pstart; for(i = 0; ; i++){ outb(board->dp8390+Cr, Page1|RDMAabort|Sta); curr = inb(board->dp8390+Curr); outb(board->dp8390+Cr, Page0|RDMAabort|Sta); if(next == curr) break; /* * Hack to keep away from the card's memory while it is receiving * a packet. This is only a problem on the NCR 3170 Safari. * * We peek at the current local DMA registers and, if they are * changing, wait. */ if(strcmp(arch->id, "NCRD.0") == 0){ uchar a, b, c; for(;;delay(10)){ a = inb(board->dp8390+Clda0); b = inb(board->dp8390+Clda0); if(a != b) continue; c = inb(board->dp8390+Clda0); if(c != b) continue; break; } } ctlr->inpackets++; data = next*Dp8390BufSz; dp8390read(ctlr, &hdr, data, sizeof(Hdr)); len = ((hdr.len1<<8)|hdr.len0)-4; /* * Chip is badly scrogged, reinitialise it. * dp8390reset() calls the disable function. * There's no need to reload the ethernet * address. * * Untested. */ if(hdr.next < board->pstart || hdr.next >= board->pstop || len < 60){ print("scrogged\n"); dp8390reset(ctlr); dp8390attach(ctlr); return; } ring = &ctlr->rb[ctlr->ri]; if(ring->owner == Interface){ ring->len = len; data += sizeof(Hdr); if((data+len) >= board->pstop*Dp8390BufSz){ len = board->pstop*Dp8390BufSz - data; dp8390read(ctlr, ring->pkt+len, board->pstart*Dp8390BufSz, (data+ring->len) - board->pstop*Dp8390BufSz); } dp8390read(ctlr, ring->pkt, data, len); ring->owner = Host; ctlr->ri = NEXT(ctlr->ri, ctlr->nrb); } next = hdr.next; bnry = next-1; if(bnry < board->pstart) bnry = board->pstop-1; outb(board->dp8390+Bnry, bnry); } } void dp8390transmit(Ctlr *ctlr) { Board *board; RingBuf *ring; int s; s = splhi(); board = ctlr->board; ring = &ctlr->tb[ctlr->ti]; if(ring->busy == 0 && ring->owner == Interface){ dp8390write(ctlr, board->tstart*Dp8390BufSz, ring->pkt, ring->len); outb(board->dp8390+Tbcr0, ring->len & 0xFF); outb(board->dp8390+Tbcr1, (ring->len>>8) & 0xFF); outb(board->dp8390+Cr, Page0|RDMAabort|Txp|Sta); ring->busy = 1; } splx(s); } void dp8390intr(Ctlr *ctlr) { Board *board = ctlr->board; RingBuf *ring; uchar isr; /* * While there is something of interest, * clear all the interrupts and process. */ while(isr = inb(board->dp8390+Isr)){ outb(board->dp8390+Isr, isr); if(isr & Ovw){ /* * Need to do some work here: * stop the chip; * clear out the ring; * re-enable the chip. * The procedure to put the chip back on * an active network is to first put it * into internal loopback mode, enable it, * then take it out of loopback. * * Untested. */ ctlr->overflows++; dp8390disable(ctlr); (*ctlr->board->receive)(ctlr); outb(board->dp8390+Tcr, Lb); outb(board->dp8390+Cr, Page0|RDMAabort|Sta); dp8390attach(ctlr); } /* * We have received packets. * Take a spin round the ring and * wakeup the kproc. */ if(isr & (Rxe|Prx)){ (*ctlr->board->receive)(ctlr); wakeup(&ctlr->rr); } /* * Log errors and successful transmissions. */ if(isr & Txe) ctlr->oerrs++; if(isr & Rxe){ ctlr->frames += inb(board->dp8390+Cntr0); ctlr->crcs += inb(board->dp8390+Cntr1); ctlr->buffs += inb(board->dp8390+Cntr2); } if(isr & Ptx) ctlr->outpackets++; /* * A packet completed transmission, successfully or * not. Start transmission on the next buffered packet, * and wake the output routine. */ if(isr & (Txe|Ptx)){ ring = &ctlr->tb[ctlr->ti]; ring->owner = Host; ring->busy = 0; ctlr->ti = NEXT(ctlr->ti, ctlr->ntb); (*ctlr->board->transmit)(ctlr); wakeup(&ctlr->tr); } } } . ## diffname pc/ether8390.c 1993/0212 ## diff -e /n/bootesdump/1992/1222/sys/src/9/pc/ether8390.c /n/bootesdump/1993/0212/sys/src/9/pc/ether8390.c 560a dp8390outb(ctlr->card.dp8390+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); . 559a if(isr & Cnt){ ctlr->frames += dp8390inb(ctlr->card.dp8390+Cntr0); ctlr->crcs += dp8390inb(ctlr->card.dp8390+Cntr1); ctlr->buffs += dp8390inb(ctlr->card.dp8390+Cntr2); dp8390outb(ctlr->card.dp8390+Isr, Cnt); } . 557c (*ctlr->card.transmit)(ctlr); . 555c ctlr->tbusy = 0; . 552a r = dp8390inb(ctlr->card.dp8390+Tsr); if(isr & Txe){ if((r & (Cdh|Fu|Crs|Abt)) && ctlr->debug) print("Tsr#%2.2ux|", r); ctlr->oerrs++; } dp8390outb(ctlr->card.dp8390+Isr, Txe|Ptx); if(isr & Ptx) ctlr->outpackets++; . 535,547d 530c (*ctlr->card.receive)(ctlr); dp8390outb(ctlr->card.dp8390+Isr, Rxe|Prx); . 516,521d 503,514c if(ctlr->card.overflow) (*ctlr->card.overflow)(ctlr); dp8390outb(ctlr->card.dp8390+Isr, Ovw); . 499,500c dp8390outb(ctlr->card.dp8390+Imr, 0x00); while(isr = dp8390inb(ctlr->card.dp8390+Isr)){ . 493c uchar isr, r; . 491d 476,483c if(ctlr->tbusy){ ctlr->tbusy++; if(ctlr->tbusy > 1 && ctlr->debug) print("TB%d|", ctlr->tbusy); . 474a /* * Stub watchdog routine. * Whine if a transmit takes too long. */ . 472a ring = &ctlr->tb[ctlr->ti]; if(ctlr->tbusy == 0 && ring->owner == Interface){ (*ctlr->card.write)(ctlr, ctlr->card.tstart*Dp8390BufSz, ring->pkt, ring->len); dp8390outb(ctlr->card.dp8390+Tbcr0, ring->len & 0xFF); dp8390outb(ctlr->card.dp8390+Tbcr1, (ring->len>>8) & 0xFF); dp8390outb(ctlr->card.dp8390+Cr, Page0|RDMAabort|Txp|Sta); ctlr->tbusy = 1; } } void dp8390overflow(Ctlr *ctlr) { uchar txp; int resend; /* * The following procedure is taken from the DP8390[12D] datasheet, * it seems pretty adamant that this is what has to be done. */ txp = dp8390inb(ctlr->card.dp8390+Cr) & Txp; dp8390outb(ctlr->card.dp8390+Cr, Page0|RDMAabort|Stp); delay(2); dp8390outb(ctlr->card.dp8390+Rbcr0, 0); dp8390outb(ctlr->card.dp8390+Rbcr1, 0); resend = 0; if(txp && (dp8390inb(ctlr->card.dp8390+Isr) & (Txe|Ptx)) == 0) resend = 1; dp8390outb(ctlr->card.dp8390+Tcr, Lb); dp8390outb(ctlr->card.dp8390+Cr, Page0|RDMAabort|Sta); (*ctlr->card.receive)(ctlr); dp8390outb(ctlr->card.dp8390+Isr, Ovw); wakeup(&ctlr->rr); dp8390outb(ctlr->card.dp8390+Tcr, 0); if(resend) dp8390outb(ctlr->card.dp8390+Cr, Page0|RDMAabort|Txp|Sta); } void dp8390watch(Ctlr *ctlr) { . 471d 467a /* * Initiate a transmission. Must be called splhi(). */ . 460,464c /* * Finished woth this packet, update the * hardware and software ring pointers. */ ctlr->card.nxtpkt = hdr.next; hdr.next--; if(hdr.next < ctlr->card.pstart) hdr.next = ctlr->card.pstop-1; dp8390outb(ctlr->card.dp8390+Bnry, hdr.next); . 455c if(len) (*ctlr->card.read)(ctlr, pkt, data, len); . 450,453c ring->len = len; if((data+len) >= ctlr->card.pstop*Dp8390BufSz){ ulong count = ctlr->card.pstop*Dp8390BufSz - data; (*ctlr->card.read)(ctlr, pkt, data, count); pkt += count; data = ctlr->card.pstart*Dp8390BufSz; len -= count; . 447,448c if((hdr.status & (Fo|Fae|Crce|Prxok)) == Prxok && ring->owner == Interface){ pkt = ring->pkt; . 445a /* * If it's a good packet and we have a place to put it, * read it in to the software ring. * If the packet wraps round the hardware ring, read it * in two pieces. */ . 439,442c if(hdr.next > ctlr->card.nxtpkt) len1 = hdr.next - ctlr->card.nxtpkt - 1; else len1 = (ctlr->card.pstop-ctlr->card.nxtpkt) + (hdr.next-ctlr->card.pstart) - 1; if(hdr.len0 > (Dp8390BufSz-sizeof(Hdr))) len1--; len = ((len1<<8)|hdr.len0)-4; /* * Chip is badly scrogged, reinitialise the ring. */ if(hdr.next < ctlr->card.pstart || hdr.next >= ctlr->card.pstop || len < 60 || len > sizeof(Etherpkt)){ print("H#%2.2ux#%2.2ux#%2.2ux#%2.2ux,%d|", hdr.status, hdr.next, hdr.len0, hdr.len1, len); dp8390outb(ctlr->card.dp8390+Cr, Page0|RDMAabort|Stp); dp8390ring(ctlr); dp8390outb(ctlr->card.dp8390+Cr, Page0|RDMAabort|Sta); . 432,437c * Don't believe the upper byte count, work it * out from the software next-page pointer and * the current next-page pointer. . 427,429c data = ctlr->card.nxtpkt*Dp8390BufSz; (*ctlr->card.read)(ctlr, &hdr, data, sizeof(Hdr)); . 418c c = dp8390inb(ctlr->card.dp8390+Clda0); . 414,415c a = dp8390inb(ctlr->card.dp8390+Clda0); b = dp8390inb(ctlr->card.dp8390+Clda0); . 391,402c for(curr = getcurr(ctlr); ctlr->card.nxtpkt != curr; curr = getcurr(ctlr)){ . 388,389c ulong data, len; . 386c uchar curr, len1, *pkt; . 384d 380a static uchar getcurr(Ctlr *ctlr) { uchar cr, curr; cr = dp8390inb(ctlr->card.dp8390+Cr) & ~Txp; dp8390outb(ctlr->card.dp8390+Cr, Page1|(~(Ps1|Ps0) & cr)); curr = dp8390inb(ctlr->card.dp8390+Curr); dp8390outb(ctlr->card.dp8390+Cr, cr); return curr; } . 376,377c dp8390outb(ctlr->card.dp8390+Isr, Rdc); dp8390outb(ctlr->card.dp8390+Cr, cr); . 373c while((dp8390inb(ctlr->card.dp8390+Isr) & Rdc) == 0) . 366c outsb(ctlr->card.data, from, len); . 362,364c if(ctlr->card.bit16) outss(ctlr->card.data, from, len/2); . 359,360c * Pump the data into the I/O port. . 357a crda = dp8390inb(ctlr->card.dp8390+Crda0); crda |= dp8390inb(ctlr->card.dp8390+Crda1)<<8; if(crda != to) panic("crda write %d to %d\n", crda, to); break; } } . 351,356c for(;;){ crda = dp8390inb(ctlr->card.dp8390+Crda0); crda |= dp8390inb(ctlr->card.dp8390+Crda1)<<8; if(crda == to){ /* * Start the remote DMA write and make sure * the registers are correct. */ dp8390outb(ctlr->card.dp8390+Cr, Page0|RDMAwrite|Sta); . 348,349c crda = to-1-ctlr->card.bit16; dp8390outb(ctlr->card.dp8390+Rbcr0, (len+1+ctlr->card.bit16) & 0xFF); dp8390outb(ctlr->card.dp8390+Rbcr1, ((len+1+ctlr->card.bit16)>>8) & 0xFF); dp8390outb(ctlr->card.dp8390+Rsar0, crda & 0xFF); dp8390outb(ctlr->card.dp8390+Rsar1, (crda>>8) & 0xFF); dp8390outb(ctlr->card.dp8390+Cr, Page0|RDMAread|Sta); . 345,346c * This is straight from the DP8390[12D] datasheet, hence * the initial set up for read. . 342a if(ctlr->card.bit16) len = ROUNDUP(len, 2); . 339,341c cr = dp8390inb(ctlr->card.dp8390+Cr) & ~Txp; dp8390outb(ctlr->card.dp8390+Cr, Page0|RDMAabort|Sta); dp8390outb(ctlr->card.dp8390+Isr, Rdc); . 325,335c * Write some data to offset 'to' in the card's memory . 322a ulong crda; . 321d 313,314c dp8390outb(ctlr->card.dp8390+Isr, Rdc); dp8390outb(ctlr->card.dp8390+Cr, cr); . 310c for(timo = 10000; (dp8390inb(ctlr->card.dp8390+Isr) & Rdc) == 0 && timo; timo--) . 301c insb(ctlr->card.data, to, len); . 297,299c dp8390outb(ctlr->card.dp8390+Cr, Page0|RDMAread|Sta); if(ctlr->card.bit16) inss(ctlr->card.data, to, len/2); . 288,291c dp8390outb(ctlr->card.dp8390+Rbcr0, len & 0xFF); dp8390outb(ctlr->card.dp8390+Rbcr1, (len>>8) & 0xFF); dp8390outb(ctlr->card.dp8390+Rsar0, from & 0xFF); dp8390outb(ctlr->card.dp8390+Rsar1, (from>>8) & 0xFF); . 286c if(ctlr->card.bit16) . 279,281c cr = dp8390inb(ctlr->card.dp8390+Cr) & ~Txp; dp8390outb(ctlr->card.dp8390+Cr, Page0|RDMAabort|Sta); dp8390outb(ctlr->card.dp8390+Isr, Rdc); . 265,275c * Read some data at offset 'from' in the card's memory . 260d 253,254c dp8390outb(ctlr->card.dp8390+Par0+i, ctlr->ea[i]); dp8390outb(ctlr->card.dp8390+Cr, cr); . 250,251c cr = dp8390inb(ctlr->card.dp8390+Cr) & ~Txp; dp8390outb(ctlr->card.dp8390+Cr, Page1|(~(Ps1|Ps0) & cr)); . 239d 233c dp8390outb(ctlr->card.dp8390+Rcr, Ab); . 231c dp8390outb(ctlr->card.dp8390+Rcr, Pro|Ab); . 229a /* * Set/reset promiscuous mode. */ . 224c dp8390outb(ctlr->card.dp8390+Rcr, Ab); . 221,222c * The init routine leaves the chip in monitor * mode. . 211,213c dp8390outb(ctlr->card.dp8390+Cr, Page0|RDMAabort|Sta); . 206a dp8390outb(ctlr->card.dp8390+Isr, 0xFF); dp8390outb(ctlr->card.dp8390+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); . 205c dp8390ring(ctlr); dp8390outb(ctlr->card.dp8390+Tpsr, ctlr->card.tstart); . 202,203c * Init the ring hardware and software ring pointers. * Can't initialise ethernet address as we may not know * it yet. . 192,200d 189,190c dp8390outb(ctlr->card.dp8390+Tcr, 0); dp8390outb(ctlr->card.dp8390+Rcr, Mon); . 186,187c dp8390outb(ctlr->card.dp8390+Rbcr0, 0); dp8390outb(ctlr->card.dp8390+Rbcr1, 0); . 184c dp8390outb(ctlr->card.dp8390+Dcr, Ft4|Ls); . 181,182c if(ctlr->card.bit16) dp8390outb(ctlr->card.dp8390+Dcr, Ft4|Ls|Wts); . 178c * as 'mandatory' in the datasheet, with references * to the 3Com503 technical reference manual. . 174,175d 170a static void dp8390ring(Ctlr *ctlr) { dp8390outb(ctlr->card.dp8390+Pstart, ctlr->card.pstart); dp8390outb(ctlr->card.dp8390+Pstop, ctlr->card.pstop); dp8390outb(ctlr->card.dp8390+Bnry, ctlr->card.pstop-1); dp8390outb(ctlr->card.dp8390+Cr, Page1|RDMAabort|Stp); dp8390outb(ctlr->card.dp8390+Curr, ctlr->card.pstart); dp8390outb(ctlr->card.dp8390+Cr, Page0|RDMAabort|Stp); ctlr->card.nxtpkt = ctlr->card.pstart; } . 166,167c dp8390outb(ctlr->card.dp8390+Cr, Page0|RDMAabort|Stp); dp8390outb(ctlr->card.dp8390+Rbcr0, 0); dp8390outb(ctlr->card.dp8390+Rbcr1, 0); for(timo = 10000; (dp8390inb(ctlr->card.dp8390+Isr) & Rst) == 0 && timo; timo--) . 155d 147,151d 41c Crda1 = 0x09, /* current remote DMA address 1 */ . 27,29c Ps0 = 0x40, /* page select */ Ps1 = 0x80, /* page select */ Page0 = 0x00, Page1 = Ps0, Page2 = Ps1, . ## diffname pc/ether8390.c 1993/0213 ## diff -e /n/bootesdump/1993/0212/sys/src/9/pc/ether8390.c /n/bootesdump/1993/0213/sys/src/9/pc/ether8390.c 513d 509a . 508a ctlr->tbusy = 1; . 405,425c if(strcmp(arch->id, "NCRD.0") == 0) cldaquiet(ctlr); . 395a static void cldaquiet(Ctlr *ctlr) { uchar a, b, c; /* * Hack to keep away from the card's memory while it is receiving * a packet. This is only a problem on the NCR 3170 Safari. * * We peek at the current local DMA registers and, if they are * changing, wait. */ for(;;delay(10)){ a = dp8390inb(ctlr->card.dp8390+Clda0); b = dp8390inb(ctlr->card.dp8390+Clda0); if(a != b) continue; c = dp8390inb(ctlr->card.dp8390+Clda0); if(c != b) continue; break; } } . 229a dp8390inb(ctlr->card.dp8390+Cntr2); . 227c * mode. Clear the missed-packet counter, it * increments while in monitor mode. . 216c * but in monitor mode. . ## diffname pc/ether8390.c 1993/0915 ## diff -e /n/bootesdump/1993/0213/sys/src/9/pc/ether8390.c /n/fornaxdump/1993/0915/sys/src/brazil/pc/ether8390.c 641c dp8390outb(dp8390+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); . 635,638c ctlr->frames += dp8390inb(dp8390+Cntr0); ctlr->crcs += dp8390inb(dp8390+Cntr1); ctlr->buffs += dp8390inb(dp8390+Cntr2); dp8390outb(dp8390+Isr, Cnt); . 621c dp8390outb(dp8390+Isr, Txe|Ptx); . 614c r = dp8390inb(dp8390+Tsr); . 604c dp8390outb(dp8390+Isr, Rxe|Prx); . 593c dp8390outb(dp8390+Isr, Ovw); . 587,588c dp8390outb(dp8390+Imr, 0x00); while(isr = dp8390inb(dp8390+Isr)){ . 582a dp8390 = ctlr->card.dp8390; . 579a ulong dp8390; . 556c dp8390outb(dp8390+Cr, Page0|RDMAabort|Txp|Sta); . 553c dp8390outb(dp8390+Tcr, 0); . 551c dp8390outb(dp8390+Isr, Ovw); . 548,549c dp8390outb(dp8390+Tcr, Lb); dp8390outb(dp8390+Cr, Page0|RDMAabort|Sta); . 545c if(txp && (dp8390inb(dp8390+Isr) & (Txe|Ptx)) == 0) . 541,542c dp8390outb(dp8390+Rbcr0, 0); dp8390outb(dp8390+Rbcr1, 0); . 538,539c txp = dp8390inb(dp8390+Cr) & Txp; dp8390outb(dp8390+Cr, Page0|RDMAabort|Stp); . 533a dp8390 = ctlr->card.dp8390; . 530a ulong dp8390; . 522,524c dp8390outb(dp8390+Tbcr0, ring->len & 0xFF); dp8390outb(dp8390+Tbcr1, (ring->len>>8) & 0xFF); dp8390outb(dp8390+Cr, Page0|RDMAabort|Txp|Sta); . 514a dp8390 = ctlr->card.dp8390; . 512a ulong dp8390; . 503c dp8390outb(dp8390+Bnry, hdr.next); . 463c dp8390outb(dp8390+Cr, Page0|RDMAabort|Sta); . 461c dp8390outb(dp8390+Cr, Page0|RDMAabort|Stp); . 433c cldaquiet(dp8390); . 431c dp8390 = ctlr->card.dp8390; for(curr = getcurr(dp8390); ctlr->card.nxtpkt != curr; curr = getcurr(dp8390)){ . 429c ulong dp8390, data, len; . 416c c = dp8390inb(dp8390+Clda0); . 412,413c a = dp8390inb(dp8390+Clda0); b = dp8390inb(dp8390+Clda0); . 399c cldaquiet(ulong dp8390) . 391,394c cr = dp8390inb(dp8390+Cr) & ~Txp; dp8390outb(dp8390+Cr, Page1|(~(Ps1|Ps0) & cr)); curr = dp8390inb(dp8390+Curr); dp8390outb(dp8390+Cr, cr); . 387c getcurr(ulong dp8390) . 381,382c dp8390outb(dp8390+Isr, Rdc); dp8390outb(dp8390+Cr, cr); . 378c while((dp8390inb(dp8390+Isr) & Rdc) == 0) . 356,357c crda = dp8390inb(dp8390+Crda0); crda |= dp8390inb(dp8390+Crda1)<<8; . 354c dp8390outb(dp8390+Cr, Page0|RDMAwrite|Sta); . 347,348c crda = dp8390inb(dp8390+Crda0); crda |= dp8390inb(dp8390+Crda1)<<8; . 340,344c dp8390outb(dp8390+Rbcr0, (len+1+ctlr->card.bit16) & 0xFF); dp8390outb(dp8390+Rbcr1, ((len+1+ctlr->card.bit16)>>8) & 0xFF); dp8390outb(dp8390+Rsar0, crda & 0xFF); dp8390outb(dp8390+Rsar1, (crda>>8) & 0xFF); dp8390outb(dp8390+Cr, Page0|RDMAread|Sta); . 327,329c cr = dp8390inb(dp8390+Cr) & ~Txp; dp8390outb(dp8390+Cr, Page0|RDMAabort|Sta); dp8390outb(dp8390+Isr, Rdc); . 321a dp8390 = ctlr->card.dp8390; . 320d 318a ulong dp8390, crda; . 311,312c dp8390outb(dp8390+Isr, Rdc); dp8390outb(dp8390+Cr, cr); . 308c for(timo = 10000; (dp8390inb(dp8390+Isr) & Rdc) == 0 && timo; timo--) . 295c dp8390outb(dp8390+Cr, Page0|RDMAread|Sta); . 286,289c dp8390outb(dp8390+Rbcr0, len & 0xFF); dp8390outb(dp8390+Rbcr1, (len>>8) & 0xFF); dp8390outb(dp8390+Rsar0, from & 0xFF); dp8390outb(dp8390+Rsar1, (from>>8) & 0xFF); . 277,279c cr = dp8390inb(dp8390+Cr) & ~Txp; dp8390outb(dp8390+Cr, Page0|RDMAabort|Sta); dp8390outb(dp8390+Isr, Rdc); . 271a dp8390 = ctlr->card.dp8390; . 268a ulong dp8390; . 265a void dp8390getea(Ctlr *ctlr) { ulong dp8390; uchar cr; int i; dp8390 = ctlr->card.dp8390; /* * Set the ethernet address into the chip. * Take care to restore the command register * afterwards. We don't care about multicast * addresses as we never set the multicast * enable. */ cr = dp8390inb(dp8390+Cr) & ~Txp; dp8390outb(dp8390+Cr, Page1|(~(Ps1|Ps0) & cr)); for(i = 0; i < sizeof(ctlr->ea); i++) ctlr->ea[i] = dp8390inb(dp8390+Par0+i); dp8390outb(dp8390+Cr, cr); } . 262,263c dp8390outb(dp8390+Par0+i, ctlr->ea[i]); dp8390outb(dp8390+Cr, cr); . 259,260c cr = dp8390inb(dp8390+Cr) & ~Txp; dp8390outb(dp8390+Cr, Page1|(~(Ps1|Ps0) & cr)); . 251a dp8390 = ctlr->card.dp8390; . 248a ulong dp8390; . 218c dp8390outb(dp8390+Cr, Page0|RDMAabort|Sta); . 211,212c dp8390outb(dp8390+Isr, 0xFF); dp8390outb(dp8390+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); . 209c dp8390outb(dp8390+Tpsr, ctlr->card.tstart); . 200,201c dp8390outb(dp8390+Tcr, 0); dp8390outb(dp8390+Rcr, Mon); . 197,198c dp8390outb(dp8390+Rbcr0, 0); dp8390outb(dp8390+Rbcr1, 0); . 195c dp8390outb(dp8390+Dcr, Ft4|Ls); . 193c dp8390outb(dp8390+Dcr, Ft4|Ls|Wts); . 185a ulong dp8390; dp8390 = ctlr->card.dp8390; . 179a dp8390outb(dp8390+Cr, Page1|RDMAabort|Stp); dp8390outb(dp8390+Curr, ctlr->card.pstart); dp8390outb(dp8390+Cr, Page0|RDMAabort|Stp); . 176,178c dp8390 = ctlr->card.dp8390; dp8390outb(dp8390+Pstart, ctlr->card.pstart); dp8390outb(dp8390+Pstop, ctlr->card.pstop); dp8390outb(dp8390+Bnry, ctlr->card.pstop-1); . 172,174c ulong dp8390; . 162,165c dp8390outb(dp8390+Cr, Page0|RDMAabort|Stp); dp8390outb(dp8390+Rbcr0, 0); dp8390outb(dp8390+Rbcr1, 0); for(timo = 10000; (dp8390inb(dp8390+Isr) & Rst) == 0 && timo; timo--) . 153a dp8390 = ctlr->card.dp8390; . 151a ulong dp8390; . ## diffname pc/ether8390.c 1993/1116 ## diff -e /n/fornaxdump/1993/0915/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1993/1116/sys/src/brazil/pc/ether8390.c 683a } static void promiscuous(Ether *ether, int on) { /* * Set/reset promiscuous mode. */ if(on) dp8390outb(ether->dp8390+Rcr, Pro|Ab); else dp8390outb(ether->dp8390+Rcr, Ab); } void dp8390attach(Ether *ether) { /* * Enable the chip for transmit/receive. * The init routine leaves the chip in monitor * mode. Clear the missed-packet counter, it * increments while in monitor mode. */ dp8390outb(ether->dp8390+Rcr, Ab); dp8390inb(ether->dp8390+Cntr2); } static int dp8390reset(Ether *ether) { ulong dp8390; dp8390 = ether->dp8390; /* * This is the initialisation procedure described * as 'mandatory' in the datasheet, with references * to the 3Com503 technical reference manual. */ dp8390disable(ether); if(ether->bit16) dp8390outb(dp8390+Dcr, Ft4|Ls|Wts); else dp8390outb(dp8390+Dcr, Ft4|Ls); dp8390outb(dp8390+Rbcr0, 0); dp8390outb(dp8390+Rbcr1, 0); dp8390outb(dp8390+Tcr, 0); dp8390outb(dp8390+Rcr, Mon); /* * Init the ring hardware and software ring pointers. * Can't initialise ethernet address as we may not know * it yet. */ dp8390ring(ether); dp8390outb(dp8390+Tpsr, ether->tstart); dp8390outb(dp8390+Isr, 0xFF); dp8390outb(dp8390+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); /* * Leave the chip initialised, * but in monitor mode. */ dp8390outb(dp8390+Cr, Page0|RDMAabort|Sta); /* * Set up the software configuration. */ ether->attach = attach; ether->write = write; ether->interrupt = interrupt; ether->promiscuous = promiscuous; ether->arg = ether; return 0; . 677,679c ether->frames += dp8390inb(dp8390+Cntr0); ether->crcs += dp8390inb(dp8390+Cntr1); ether->buffs += dp8390inb(dp8390+Cntr2); . 666,673c ether->outpackets++; wakeup(ðer->tr); . 660c ether->oerrs++; . 658c if((r & (Cdh|Fu|Crs|Abt)) && ether->debug) . 647d 645c receive(ether); . 641,642c * Take a spin round the ring. and . 636c ether->overflows++; . 633,634c overflow(ether); . 624c dp8390 = ether->dp8390; . 621d 602,619d 599,600c static void interrupt(Ether *ether) . 592c wakeup(ðer->rr); . 590c (*ether->receive)(ether); . 573c dp8390 = ether->dp8390; . 566,567c static void overflow(Ether *ether) . 558c (*ether->write)(ctlr, ether->tstart*Dp8390BufSz, ring->pkt, ring->len); . 556c ether->tbusy = 1; . 552,554c dp8390 = ether->dp8390; ring = ðer->tb[ether->ti]; if(ether->tbusy == 0 && ring->owner == Interface){ . 547c dp8390transmit(Ether *ether) . 537,538c if(hdr.next < ether->pstart) hdr.next = ether->pstop-1; . 534c ether->nxtpkt = hdr.next; . 526,527c /* * Copy the packet to whoever wants it. */ type = (ether->rpkt.type[0]<<8)|ether->rpkt.type[1]; ep = ðer->f[Ntypes]; for(fp = ether->f; fp < ep; fp++) { f = *fp; if(f && (f->type == type || f->type < 0)) qproduce(f->in, ðer->rpkt, len); } . 524c (*ether->read)(ctlr, pkt, data, len); . 520c data = ether->pstart*Dp8390BufSz; . 518c (*ether->read)(ctlr, pkt, data, count); . 515,516c if((data+len) >= ether->pstop*Dp8390BufSz){ ulong count = ether->pstop*Dp8390BufSz - data; . 509,511c if((hdr.status & (Fo|Fae|Crce|Prxok)) == Prxok){ pkt = ether->rpkt; . 504,507c * If it's a good packet read it in to the software buffer. * If the packet wraps round the hardware ring, read it in two pieces. . 498c dp8390ring(ether); . 493c if(hdr.next < ether->pstart || hdr.next >= ether->pstop . 484c len1 = (ether->pstop-ether->nxtpkt) + (hdr.next-ether->pstart) - 1; . 481,482c if(hdr.next > ether->nxtpkt) len1 = hdr.next - ether->nxtpkt - 1; . 473,475d 471c data = ether->nxtpkt*Dp8390BufSz; (*ether->read)(ctlr, &hdr, data, sizeof(Hdr)); . 466,469c dp8390 = ether->dp8390; for(curr = getcurr(dp8390); ether->nxtpkt != curr; curr = getcurr(dp8390)){ ether->inpackets++; . 464a ushort type; Netfile *f, **fp, **ep; . 436,461d 434c receive(Ether *ether) . 406c outsb(ether->data, from, len); . 403,404c if(ether->bit16) outss(ether->data, from, len/2); . 374,376c crda = to-1-ether->bit16; dp8390outb(dp8390+Rbcr0, (len+1+ether->bit16) & 0xFF); dp8390outb(dp8390+Rbcr1, ((len+1+ether->bit16)>>8) & 0xFF); . 366c if(ether->bit16) . 356c dp8390 = ether->dp8390; . 350,351c static void* dp8390write(Ether *ether, ulong to, void *from, ulong len) . 333c insb(ether->data, to, len); . 330,331c if(ether->bit16) inss(ether->data, to, len/2); . 318c if(ether->bit16) . 305c dp8390 = ether->dp8390; . 298,299c static void* dp8390read(Ether *ether, void *to, ulong from, ulong len) . 293,294c for(i = 0; i < sizeof(ether->ea); i++) ether->ea[i] = dp8390inb(dp8390+Par0+i); . 285c * Get the ethernet address from the chip. . 283c dp8390 = ether->dp8390; . 277c dp8390getea(Ether *ether) . 271,272c for(i = 0; i < sizeof(ether->ea); i++) dp8390outb(dp8390+Par0+i, ether->ea[i]); . 261c dp8390 = ether->dp8390; . 192,257d 189c dp8390setea(Ether *ether) . 185c ether->nxtpkt = ether->pstart; . 182c dp8390outb(dp8390+Curr, ether->pstart); . 176,179c dp8390 = ether->dp8390; dp8390outb(dp8390+Pstart, ether->pstart); dp8390outb(dp8390+Pstop, ether->pstop); dp8390outb(dp8390+Bnry, ether->pstop-1); . 172c dp8390ring(Ether *ether) . 155c dp8390 = ether->dp8390; . 150c dp8390disable(Ether *ether) . 15c #include "etherif.h" . 13c #include "../port/error.h" #include "../port/netif.h" . 11d ## diffname pc/ether8390.c 1993/1117 ## diff -e /n/fornaxdump/1993/1116/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1993/1117/sys/src/brazil/pc/ether8390.c 600c dp8390 = ((Dp8390*)ether->private)->dp8390; . 584a ulong dp8390; dp8390 = ((Dp8390*)ether->private)->dp8390; . 572a ulong dp8390; dp8390 = ((Dp8390*)ether->private)->dp8390; . 517c dp8390 = ((Dp8390*)ether->private)->dp8390; . 485c dp8390 = ((Dp8390*)ether->private)->dp8390; . 464c dp8390 = ((Dp8390*)ether->private)->dp8390; . 376c dp8390 = ((Dp8390*)ether->private)->dp8390; . 290c dp8390 = ((Dp8390*)ether->private)->dp8390; . 279,280c dp8390outb(port+Isr, Rdc); dp8390outb(port+Cr, cr); . 276c for(timo = 10000; (dp8390inb(port+Isr) & Rdc) == 0 && timo; timo--) . 267c insb(dp8390->data, to, len); . 263,265c dp8390outb(port+Cr, Page0|RDMAread|Sta); if(dp8390->bit16) inss(dp8390->data, to, len/2); . 254,257c dp8390outb(port+Rbcr0, len & 0xFF); dp8390outb(port+Rbcr1, (len>>8) & 0xFF); dp8390outb(port+Rsar0, from & 0xFF); dp8390outb(port+Rsar1, (from>>8) & 0xFF); . 252c if(dp8390->bit16) . 245,247c cr = dp8390inb(port+Cr) & ~Txp; dp8390outb(port+Cr, Page0|RDMAabort|Sta); dp8390outb(port+Isr, Rdc); . 239c port = dp8390->dp8390; . 235c ulong port; . 233c dp8390read(Dp8390 *dp8390, void *to, ulong from, ulong len) . 228,229c ether->ea[i] = dp8390inb(port+Par0+i); dp8390outb(port+Cr, cr); . 225,226c cr = dp8390inb(port+Cr) & ~Txp; dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); . 217c port = ((Dp8390*)ether->private)->dp8390; . 213c ulong port; . 206,207c dp8390outb(port+Par0+i, ether->ea[i]); dp8390outb(port+Cr, cr); . 203,204c cr = dp8390inb(port+Cr) & ~Txp; dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); . 195c port = ((Dp8390*)ether->private)->dp8390; . 191c ulong port; . 185c dp8390->nxtpkt = dp8390->pstart; . 181,183c dp8390outb(port+Cr, Page1|RDMAabort|Stp); dp8390outb(port+Curr, dp8390->pstart); dp8390outb(port+Cr, Page0|RDMAabort|Stp); . 176,179c port = dp8390->dp8390; dp8390outb(port+Pstart, dp8390->pstart); dp8390outb(port+Pstop, dp8390->pstop); dp8390outb(port+Bnry, dp8390->pstop-1); . 174c ulong port; . 172c dp8390ring(Dp8390 *dp8390) . 164,167c dp8390outb(port+Cr, Page0|RDMAabort|Stp); dp8390outb(port+Rbcr0, 0); dp8390outb(port+Rbcr1, 0); for(timo = 10000; (dp8390inb(port+Isr) & Rst) == 0 && timo; timo--) . 155c port = dp8390->dp8390; . 152c ulong port; . 150c dp8390disable(Dp8390 *dp8390) . ## diffname pc/ether8390.c 1993/1118 ## diff -e /n/fornaxdump/1993/1117/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1993/1118/sys/src/brazil/pc/ether8390.c 639c dp8390outb(port+Cr, Page0|RDMAabort|Sta); . 632,633c dp8390outb(port+Isr, 0xFF); dp8390outb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); . 629,630c dp8390ring(dp8390); dp8390outb(port+Tpsr, dp8390->tstart); . 621,622c dp8390outb(port+Tcr, 0); dp8390outb(port+Rcr, Mon); . 618,619c dp8390outb(port+Rbcr0, 0); dp8390outb(port+Rbcr1, 0); . 616c dp8390outb(port+Dcr, Ft4|Ls); . 612,614c dp8390disable(dp8390); if(dp8390->bit16) dp8390outb(port+Dcr, Ft4|Ls|Wts); . 606c dp8390 = ether->private; port = dp8390->dp8390; . 604c Dp8390 *dp8390; ulong port; . 601c int . 597,598c dp8390outb(dp8390->dp8390+Rcr, Ab); dp8390inb(dp8390->dp8390+Cntr2); . 590d 588c Dp8390 *dp8390 = ether->private; . 585,586c static void attach(Ether *ether) . 582c dp8390outb(dp8390->dp8390+Rcr, Ab); . 580c dp8390outb(dp8390->dp8390+Rcr, Pro|Ab); . 575d 573c Dp8390 *dp8390 = ((Ether*)arg)->private; . 571c promiscuous(void *arg, int on) . 567c dp8390outb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); . 561,564c ether->frames += dp8390inb(port+Cntr0); ether->crcs += dp8390inb(port+Cntr1); ether->buffs += dp8390inb(port+Cntr2); dp8390outb(port+Isr, Cnt); . 556a dp8390->busy = 0; . 553c dp8390outb(port+Isr, Txe|Ptx); . 548,549c if((r & (Cdh|Fu|Crs|Abt))) print("dp8390: Tsr#%2.2ux\n", r); . 546c r = dp8390inb(port+Tsr); . 537c dp8390outb(port+Isr, Rxe|Prx); . 527c dp8390outb(port+Isr, Ovw); . 522,523c dp8390outb(port+Imr, 0x00); while(isr = dp8390inb(port+Isr)){ . 517c dp8390 = ether->private; port = dp8390->dp8390; . 514c Dp8390 *dp8390; ulong port; . 508c dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta); . 500,505c dp8390outb(port+Tcr, Lb); dp8390outb(port+Cr, Page0|RDMAabort|Sta); receive(ether); dp8390outb(port+Isr, Ovw); dp8390outb(port+Tcr, 0); . 497c if(txp && (dp8390inb(port+Isr) & (Txe|Ptx)) == 0) . 493,494c dp8390outb(port+Rbcr0, 0); dp8390outb(port+Rbcr1, 0); . 490,491c txp = dp8390inb(port+Cr) & Txp; dp8390outb(port+Cr, Page0|RDMAabort|Stp); . 485c dp8390 = ether->private; port = dp8390->dp8390; . 481c Dp8390 *dp8390; ulong port; . 475a tsleep(ðer->tr, istxbusy, dp8390, 10000); if(dp8390->busy) print("dp8390: transmitter jammed\n"); dp8390->busy = 1; if(dp8390->ram) memmove((void*)(ether->mem+dp8390->tstart*Dp8390BufSz), buf, n); else dp8390write(dp8390, dp8390->tstart*Dp8390BufSz, buf, n); dp8390outb(port+Tbcr0, n & 0xFF); dp8390outb(port+Tbcr1, (n>>8) & 0xFF); dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta); poperror(); qunlock(ðer->tlock); return n; . 470,474c qlock(ðer->tlock); if(waserror()) { qunlock(ðer->tlock); nexterror(); . 468c dp8390 = ether->private; port = dp8390->dp8390; . 464,466c static long write(Ether *ether, void *buf, long n) { Dp8390 *dp8390; ulong port; . 461,462c return ((Dp8390*)arg)->busy == 0; } . 455,459c static int istxbusy(void *arg) . 449,451c if(hdr.next < dp8390->pstart) hdr.next = dp8390->pstop-1; dp8390outb(port+Bnry, hdr.next); . 446c dp8390->nxtpkt = hdr.next; . 443c * Finished with this packet, update the . 427,428c if(len1){ if(dp8390->ram) memmove(pkt, (void*)(ether->mem+data), len1); else dp8390read(dp8390, pkt, data, len1); } . 424,425c data = dp8390->pstart*Dp8390BufSz; len1 -= count; . 422c if(dp8390->ram) memmove(pkt, (void*)(ether->mem+data), count); else dp8390read(dp8390, pkt, data, count); . 419,420c if((data+len1) >= dp8390->pstop*Dp8390BufSz){ ulong count = dp8390->pstop*Dp8390BufSz - data; . 417c len1 = len; . 415c pkt = (uchar*)ðer->rpkt; . 404,406c dp8390outb(port+Cr, Page0|RDMAabort|Stp); dp8390ring(dp8390); dp8390outb(port+Cr, Page0|RDMAabort|Sta); . 402c print("dp8390: H#%2.2ux#%2.2ux#%2.2ux#%2.2ux,%d\n", . 400c if(hdr.next < dp8390->pstart || hdr.next >= dp8390->pstop . 391c len1 = (dp8390->pstop-dp8390->nxtpkt) + (hdr.next-dp8390->pstart) - 1; . 388,389c if(hdr.next > dp8390->nxtpkt) len1 = hdr.next - dp8390->nxtpkt - 1; . 380,381c data = dp8390->nxtpkt*Dp8390BufSz; if(dp8390->ram) memmove(&hdr, (void*)(ether->mem+data), sizeof(Hdr)); else dp8390read(dp8390, &hdr, data, sizeof(Hdr)); . 376,377c dp8390 = ether->private; port = dp8390->dp8390; for(curr = getcurr(dp8390); dp8390->nxtpkt != curr; curr = getcurr(dp8390)){ . 372c ulong port, data, len, len1; . 370c Dp8390 *dp8390; uchar curr, *pkt; . 360,363c cr = dp8390inb(port+Cr) & ~Txp; dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); curr = dp8390inb(port+Curr); dp8390outb(port+Cr, cr); . 357a ulong port = dp8390->dp8390; . 356c getcurr(Dp8390 *dp8390) . 350,351c dp8390outb(port+Isr, Rdc); dp8390outb(port+Cr, cr); . 347c while((dp8390inb(port+Isr) & Rdc) == 0) . 340c outsb(dp8390->data, from, len); . 337,338c if(dp8390->bit16) outss(dp8390->data, from, len/2); . 325,326c crda = dp8390inb(port+Crda0); crda |= dp8390inb(port+Crda1)<<8; . 323c dp8390outb(port+Cr, Page0|RDMAwrite|Sta); . 316,317c crda = dp8390inb(port+Crda0); crda |= dp8390inb(port+Crda1)<<8; . 308,313c crda = to-1-dp8390->bit16; 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); . 300c if(dp8390->bit16) . 296,298c cr = dp8390inb(port+Cr) & ~Txp; dp8390outb(port+Cr, Page0|RDMAabort|Sta); dp8390outb(port+Isr, Rdc); . 290d 287c ulong port = dp8390->dp8390; ulong crda; . 285c dp8390write(Dp8390 *dp8390, ulong to, void *from, ulong len) . 239d 235c ulong port = dp8390->dp8390; . 217d 213c ulong port = ((Dp8390*)ether->private)->dp8390; . 195d 191c ulong port = ((Dp8390*)ether->private)->dp8390; . 176d 174c ulong port = dp8390->dp8390; . 155d 152c ulong port = dp8390->dp8390; . 16a extern int dp8390inb(ulong); extern void dp8390outb(ulong, uchar); . ## diffname pc/ether8390.c 1993/1119 ## diff -e /n/fornaxdump/1993/1118/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1993/1119/sys/src/brazil/pc/ether8390.c 591c ether->tlen = 0; . 557a print("I%2.2ux|", isr); . 501,503d 487,491d 485a ether->tlen = n; . 481,484c tsleep(ðer->tr, istxavail, ether, 10000); if(ether->tlen){ print("dp8390: transmitter jammed\n"); return 0; . 469c return ((Ether*)arg)->tlen == 0; . 467c istxavail(void *arg) . 449a } . 448a { print("Q%d|", len); . ## diffname pc/ether8390.c 1993/1120 ## diff -e /n/fornaxdump/1993/1119/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1993/1120/sys/src/brazil/pc/ether8390.c 554d 500c return len; . 496,497c /* * Give the packet a source address and make sure it * is of minimum length. */ memmove(pkt->s, ether->ea, sizeof(ether->ea)); if(len < ETHERMINTU){ memset(pkt->d+len, 0, ETHERMINTU-len); len = ETHERMINTU; } if(dp8390->ram == 0) dp8390write(dp8390, dp8390->tstart*Dp8390BufSz, pkt, len); dp8390outb(port+Tbcr0, len & 0xFF); dp8390outb(port+Tbcr1, (len>>8) & 0xFF); . 494c pkt = ðer->tpkt; memmove(pkt, buf, len); . 492c pkt = (Etherpkt*)(ether->mem+dp8390->tstart*Dp8390BufSz); . 490a /* * If it's a shared-memory interface, copy the packet * directly to the shared-memory area. Otherwise, copy * it to a staging buffer so the I/O-port write can be * done in one. */ . 489c ether->tlen = len; . 479a Etherpkt *pkt; . 476c write(Ether *ether, void *buf, long len) . 452d 449,450d ## diffname pc/ether8390.c 1993/1124 ## diff -e /n/fornaxdump/1993/1120/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1993/1124/sys/src/brazil/pc/ether8390.c 562a USED(ur); ether = arg; . 558a Ether *ether; . 557c interrupt(Ureg *ur, void *arg) . ## diffname pc/ether8390.c 1994/0128 ## diff -e /n/fornaxdump/1993/1124/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1994/0128/sys/src/brazil/pc/ether8390.c 282c void* . 231c void* . ## diffname pc/ether8390.c 1994/0130 ## diff -e /n/fornaxdump/1994/0128/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1994/0130/sys/src/brazil/pc/ether8390.c 693c slowoutb(port+Cr, Page0|RDMAabort|Sta); . 686,687c slowoutb(port+Isr, 0xFF); slowoutb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); . 684c slowoutb(port+Tpsr, dp8390->tstart); . 675,676c slowoutb(port+Tcr, 0); slowoutb(port+Rcr, Mon); . 672,673c slowoutb(port+Rbcr0, 0); slowoutb(port+Rbcr1, 0); . 670c slowoutb(port+Dcr, Ft4|Ls); . 668c slowoutb(port+Dcr, Ft4|Ls|Wts); . 648,649c slowoutb(dp8390->dp8390+Rcr, Ab); slowinb(dp8390->dp8390+Cntr2); . 634c slowoutb(dp8390->dp8390+Rcr, Ab); . 632c slowoutb(dp8390->dp8390+Rcr, Pro|Ab); . 620c slowoutb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); . 614,617c ether->frames += slowinb(port+Cntr0); ether->crcs += slowinb(port+Cntr1); ether->buffs += slowinb(port+Cntr2); slowoutb(port+Isr, Cnt); . 605c slowoutb(port+Isr, Txe|Ptx); . 598c r = slowinb(port+Tsr); . 589c slowoutb(port+Isr, Rxe|Prx); . 579c slowoutb(port+Isr, Ovw); . 574,575c slowoutb(port+Imr, 0x00); while(isr = slowinb(port+Isr)){ . 553c slowoutb(port+Cr, Page0|RDMAabort|Txp|Sta); . 549,550c slowoutb(port+Isr, Ovw); slowoutb(port+Tcr, 0); . 546,547c slowoutb(port+Tcr, Lb); slowoutb(port+Cr, Page0|RDMAabort|Sta); . 543c if(txp && (slowinb(port+Isr) & (Txe|Ptx)) == 0) . 539,540c slowoutb(port+Rbcr0, 0); slowoutb(port+Rbcr1, 0); . 536,537c txp = slowinb(port+Cr) & Txp; slowoutb(port+Cr, Page0|RDMAabort|Stp); . 514,516c slowoutb(port+Tbcr0, len & 0xFF); slowoutb(port+Tbcr1, (len>>8) & 0xFF); slowoutb(port+Cr, Page0|RDMAabort|Txp|Sta); . 462c slowoutb(port+Bnry, hdr.next); . 410c slowoutb(port+Cr, Page0|RDMAabort|Sta); . 408c slowoutb(port+Cr, Page0|RDMAabort|Stp); . 359,362c cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); curr = slowinb(port+Curr); slowoutb(port+Cr, cr); . 348,349c slowoutb(port+Isr, Rdc); slowoutb(port+Cr, cr); . 345c while((slowinb(port+Isr) & Rdc) == 0) . 323,324c crda = slowinb(port+Crda0); crda |= slowinb(port+Crda1)<<8; . 321c slowoutb(port+Cr, Page0|RDMAwrite|Sta); . 314,315c crda = slowinb(port+Crda0); crda |= slowinb(port+Crda1)<<8; . 307,311c 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); . 294,296c cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page0|RDMAabort|Sta); slowoutb(port+Isr, Rdc); . 277,278c slowoutb(port+Isr, Rdc); slowoutb(port+Cr, cr); . 274c for(timo = 10000; (slowinb(port+Isr) & Rdc) == 0 && timo; timo--) . 261c slowoutb(port+Cr, Page0|RDMAread|Sta); . 252,255c slowoutb(port+Rbcr0, len & 0xFF); slowoutb(port+Rbcr1, (len>>8) & 0xFF); slowoutb(port+Rsar0, from & 0xFF); slowoutb(port+Rsar1, (from>>8) & 0xFF); . 243,245c cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page0|RDMAabort|Sta); slowoutb(port+Isr, Rdc); . 227,228c ether->ea[i] = slowinb(port+Par0+i); slowoutb(port+Cr, cr); . 224,225c cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); . 206,207c slowoutb(port+Par0+i, ether->ea[i]); slowoutb(port+Cr, cr); . 203,204c cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); . 182,184c slowoutb(port+Cr, Page1|RDMAabort|Stp); slowoutb(port+Curr, dp8390->pstart); slowoutb(port+Cr, Page0|RDMAabort|Stp); . 178,180c slowoutb(port+Pstart, dp8390->pstart); slowoutb(port+Pstop, dp8390->pstop); slowoutb(port+Bnry, dp8390->pstop-1); . 166,169c slowoutb(port+Cr, Page0|RDMAabort|Stp); slowoutb(port+Rbcr0, 0); slowoutb(port+Rbcr1, 0); for(timo = 10000; (slowinb(port+Isr) & Rst) == 0 && timo; timo--) . 17,18c extern int slowinb(ulong); extern void slowoutb(ulong, uchar); . ## diffname pc/ether8390.c 1994/0201 ## diff -e /n/fornaxdump/1994/0130/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1994/0201/sys/src/brazil/pc/ether8390.c 346c if(tries++ >= 10000000){ print("dp8390write whoops\n"); break; } . 344a tries = 0; . 338a splx(s); . 288a s = splhi(); . 287a int s, tries; . ## diffname pc/ether8390.c 1994/0202 ## diff -e /n/fornaxdump/1994/0201/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1994/0202/sys/src/brazil/pc/ether8390.c 451,457c etherrloop(ether, ðer->rpkt, len); . 423a * * We could conceivably remove the copy into rpkt here by wrapping * this up with the etherrloop code. . 380,381d 356a splx(s); . 353a } . 349,351c while((slowinb(port+Isr) & Rdc) == 0){ if(tries++ >= 100000){ print("dp8390write dma timed out\n"); . 344,346c * Wait for the remote DMA to finish. It should * be almost immediate. . 341d 290a . 289a /* * Keep out interrupts since reading and writing * use the same DMA engine. */ . ## diffname pc/ether8390.c 1994/0715 ## diff -e /n/fornaxdump/1994/0202/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1994/0715/sys/src/brazil/pc/ether8390.c 458c etherrloop(ether, ðer->rpkt, len, 1); . ## diffname pc/ether8390.c 1995/0408 ## diff -e /n/fornaxdump/1994/0715/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1995/0408/sys/src/brazil/pc/ether8390.c 701c dp8390outb(port+Cr, Page0|RDMAabort|Sta); . 694,695c dp8390outb(port+Isr, 0xFF); dp8390outb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); . 692c dp8390outb(port+Tpsr, dp8390->tstart); . 683,684c dp8390outb(port+Tcr, 0); dp8390outb(port+Rcr, Mon); . 680,681c dp8390outb(port+Rbcr0, 0); dp8390outb(port+Rbcr1, 0); . 678c dp8390outb(port+Dcr, Ft4|Ls); . 676c dp8390outb(port+Dcr, Ft4|Ls|Wts); . 656,657c dp8390outb(dp8390->dp8390+Rcr, Ab); dp8390inb(dp8390->dp8390+Cntr2); . 642c dp8390outb(dp8390->dp8390+Rcr, Ab); . 640c dp8390outb(dp8390->dp8390+Rcr, Pro|Ab); . 628c dp8390outb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); . 622,625c ether->frames += dp8390inb(port+Cntr0); ether->crcs += dp8390inb(port+Cntr1); ether->buffs += dp8390inb(port+Cntr2); dp8390outb(port+Isr, Cnt); . 613c dp8390outb(port+Isr, Txe|Ptx); . 606c r = dp8390inb(port+Tsr); . 597c dp8390outb(port+Isr, Rxe|Prx); . 587c dp8390outb(port+Isr, Ovw); . 582,583c dp8390outb(port+Imr, 0x00); while(isr = dp8390inb(port+Isr)){ . 561c dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta); . 557,558c dp8390outb(port+Isr, Ovw); dp8390outb(port+Tcr, 0); . 554,555c dp8390outb(port+Tcr, Lb); dp8390outb(port+Cr, Page0|RDMAabort|Sta); . 551c if(txp && (dp8390inb(port+Isr) & (Txe|Ptx)) == 0) . 547,548c dp8390outb(port+Rbcr0, 0); dp8390outb(port+Rbcr1, 0); . 544,545c txp = dp8390inb(port+Cr) & Txp; dp8390outb(port+Cr, Page0|RDMAabort|Stp); . 522,524c dp8390outb(port+Tbcr0, len & 0xFF); dp8390outb(port+Tbcr1, (len>>8) & 0xFF); dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta); . 470c dp8390outb(port+Bnry, hdr.next); . 421c dp8390outb(port+Cr, Page0|RDMAabort|Sta); . 419c dp8390outb(port+Cr, Page0|RDMAabort|Stp); . 372,375c cr = dp8390inb(port+Cr) & ~Txp; dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); curr = dp8390inb(port+Curr); dp8390outb(port+Cr, cr); . 359,360c dp8390outb(port+Isr, Rdc); dp8390outb(port+Cr, cr); . 352c while((dp8390inb(port+Isr) & Rdc) == 0){ . 330,331c crda = dp8390inb(port+Crda0); crda |= dp8390inb(port+Crda1)<<8; . 328c dp8390outb(port+Cr, Page0|RDMAwrite|Sta); . 321,322c crda = dp8390inb(port+Crda0); crda |= dp8390inb(port+Crda1)<<8; . 314,318c 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); . 301,303c cr = dp8390inb(port+Cr) & ~Txp; dp8390outb(port+Cr, Page0|RDMAabort|Sta); dp8390outb(port+Isr, Rdc); . 277,278c dp8390outb(port+Isr, Rdc); dp8390outb(port+Cr, cr); . 274c for(timo = 10000; (dp8390inb(port+Isr) & Rdc) == 0 && timo; timo--) . 261c dp8390outb(port+Cr, Page0|RDMAread|Sta); . 252,255c dp8390outb(port+Rbcr0, len & 0xFF); dp8390outb(port+Rbcr1, (len>>8) & 0xFF); dp8390outb(port+Rsar0, from & 0xFF); dp8390outb(port+Rsar1, (from>>8) & 0xFF); . 243,245c cr = dp8390inb(port+Cr) & ~Txp; dp8390outb(port+Cr, Page0|RDMAabort|Sta); dp8390outb(port+Isr, Rdc); . 227,228c ether->ea[i] = dp8390inb(port+Par0+i); dp8390outb(port+Cr, cr); . 224,225c cr = dp8390inb(port+Cr) & ~Txp; dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); . 206,207c dp8390outb(port+Par0+i, ether->ea[i]); dp8390outb(port+Cr, cr); . 203,204c cr = dp8390inb(port+Cr) & ~Txp; dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); . 182,184c dp8390outb(port+Cr, Page1|RDMAabort|Stp); dp8390outb(port+Curr, dp8390->pstart); dp8390outb(port+Cr, Page0|RDMAabort|Stp); . 178,180c dp8390outb(port+Pstart, dp8390->pstart); dp8390outb(port+Pstop, dp8390->pstop); dp8390outb(port+Bnry, dp8390->pstop-1); . 166,169c dp8390outb(port+Cr, Page0|RDMAabort|Stp); dp8390outb(port+Rbcr0, 0); dp8390outb(port+Rbcr1, 0); for(timo = 10000; (dp8390inb(port+Isr) & Rst) == 0 && timo; timo--) . 151a /* * 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; } . 17,19d ## diffname pc/ether8390.c 1995/0409 ## diff -e /n/fornaxdump/1995/0408/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1995/0409/sys/src/brazil/pc/ether8390.c 718c slowoutb(port+Cr, Page0|RDMAabort|Sta); . 711,712c slowoutb(port+Isr, 0xFF); slowoutb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); . 709c slowoutb(port+Tpsr, dp8390->tstart); . 700,701c slowoutb(port+Tcr, 0); slowoutb(port+Rcr, Mon); . 697,698c slowoutb(port+Rbcr0, 0); slowoutb(port+Rbcr1, 0); . 695c slowoutb(port+Dcr, Ft4|Ls); . 693c slowoutb(port+Dcr, Ft4|Ls|Wts); . 673,674c slowoutb(dp8390->dp8390+Rcr, Ab); slowinb(dp8390->dp8390+Cntr2); . 659c slowoutb(dp8390->dp8390+Rcr, Ab); . 657c slowoutb(dp8390->dp8390+Rcr, Pro|Ab); . 645c slowoutb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); . 639,642c ether->frames += slowinb(port+Cntr0); ether->crcs += slowinb(port+Cntr1); ether->buffs += slowinb(port+Cntr2); slowoutb(port+Isr, Cnt); . 630c slowoutb(port+Isr, Txe|Ptx); . 623c r = slowinb(port+Tsr); . 614c slowoutb(port+Isr, Rxe|Prx); . 604c slowoutb(port+Isr, Ovw); . 599,600c slowoutb(port+Imr, 0x00); while(isr = slowinb(port+Isr)){ . 578c slowoutb(port+Cr, Page0|RDMAabort|Txp|Sta); . 574,575c slowoutb(port+Isr, Ovw); slowoutb(port+Tcr, 0); . 571,572c slowoutb(port+Tcr, Lb); slowoutb(port+Cr, Page0|RDMAabort|Sta); . 568c if(txp && (slowinb(port+Isr) & (Txe|Ptx)) == 0) . 564,565c slowoutb(port+Rbcr0, 0); slowoutb(port+Rbcr1, 0); . 561,562c txp = slowinb(port+Cr) & Txp; slowoutb(port+Cr, Page0|RDMAabort|Stp); . 539,541c slowoutb(port+Tbcr0, len & 0xFF); slowoutb(port+Tbcr1, (len>>8) & 0xFF); slowoutb(port+Cr, Page0|RDMAabort|Txp|Sta); . 487c slowoutb(port+Bnry, hdr.next); . 438c slowoutb(port+Cr, Page0|RDMAabort|Sta); . 436c slowoutb(port+Cr, Page0|RDMAabort|Stp); . 389,392c cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); curr = slowinb(port+Curr); slowoutb(port+Cr, cr); . 376,377c slowoutb(port+Isr, Rdc); slowoutb(port+Cr, cr); . 369c while((slowinb(port+Isr) & Rdc) == 0){ . 347,348c crda = slowinb(port+Crda0); crda |= slowinb(port+Crda1)<<8; . 345c slowoutb(port+Cr, Page0|RDMAwrite|Sta); . 338,339c crda = slowinb(port+Crda0); crda |= slowinb(port+Crda1)<<8; . 331,335c 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); . 318,320c cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page0|RDMAabort|Sta); slowoutb(port+Isr, Rdc); . 294,295c slowoutb(port+Isr, Rdc); slowoutb(port+Cr, cr); . 291c for(timo = 10000; (slowinb(port+Isr) & Rdc) == 0 && timo; timo--) . 278c slowoutb(port+Cr, Page0|RDMAread|Sta); . 269,272c slowoutb(port+Rbcr0, len & 0xFF); slowoutb(port+Rbcr1, (len>>8) & 0xFF); slowoutb(port+Rsar0, from & 0xFF); slowoutb(port+Rsar1, (from>>8) & 0xFF); . 260,262c cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page0|RDMAabort|Sta); slowoutb(port+Isr, Rdc); . 244,245c ether->ea[i] = slowinb(port+Par0+i); slowoutb(port+Cr, cr); . 241,242c cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); . 223,224c slowoutb(port+Par0+i, ether->ea[i]); slowoutb(port+Cr, cr); . 220,221c cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); . 199,201c slowoutb(port+Cr, Page1|RDMAabort|Stp); slowoutb(port+Curr, dp8390->pstart); slowoutb(port+Cr, Page0|RDMAabort|Stp); . 195,197c slowoutb(port+Pstart, dp8390->pstart); slowoutb(port+Pstop, dp8390->pstop); slowoutb(port+Bnry, dp8390->pstop-1); . 183,186c slowoutb(port+Cr, Page0|RDMAabort|Stp); slowoutb(port+Rbcr0, 0); slowoutb(port+Rbcr1, 0); for(timo = 10000; (slowinb(port+Isr) & Rst) == 0 && timo; timo--) . 149,168d 16a extern int slowinb(ulong); extern void slowoutb(ulong, uchar); . ## diffname pc/ether8390.c 1995/0721 ## diff -e /n/fornaxdump/1995/0409/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1995/0721/sys/src/brazil/pc/ether8390.c 666c dp8390 = ether->ctlr; . 648c Dp8390 *dp8390 = ether->ctlr; . 634c Dp8390 *dp8390 = ((Ether*)arg)->ctlr; . 575c dp8390 = ether->ctlr; . 537c dp8390 = ether->ctlr; . 487c dp8390 = ether->ctlr; . 458c etherrloop(ether, ðer->rpkt, len); . 387c dp8390 = ether->ctlr; . 213c ulong port = ((Dp8390*)ether->ctlr)->dp8390; . 192c ulong port = ((Dp8390*)ether->ctlr)->dp8390; . ## diffname pc/ether8390.c 1995/0801 ## diff -e /n/fornaxdump/1995/0721/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1995/0801/sys/src/brazil/pc/ether8390.c 655a x = Ab; if(ether->prom) x |= Pro; . 648a int x; . ## diffname pc/ether8390.c 1995/0829 ## diff -e /n/fornaxdump/1995/0801/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1995/0829/sys/src/brazil/pc/ether8390.c 660c slowoutb(dp8390->dp8390+Rcr, x); . 583c while(isr = (slowinb(port+Isr) & (Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe))){ . 572,573d 565c interrupt(Ureg*, void *arg) . ## diffname pc/ether8390.c 1996/0420 ## diff -e /n/fornaxdump/1995/0829/sys/src/brazil/pc/ether8390.c /n/fornaxdump/1996/0420/sys/src/brazil/pc/ether8390.c 210,230d ## diffname pc/ether8390.c 1997/0327 ## diff -e /n/fornaxdump/1996/0420/sys/src/brazil/pc/ether8390.c /n/emeliedump/1997/0327/sys/src/brazil/pc/ether8390.c 689a ether->ifstat = 0; . 688c ether->transmit = transmit; . 682c regw(ctlr, Cr, Page0|RdABORT|Sta); . 675,676c regw(ctlr, Isr, 0xFF); regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx); . 672,673c ringinit(ctlr); regw(ctlr, Tpsr, ctlr->tstart); . 669,670c * Can't initialise ethernet address as it may not be * known yet. . 664,665c regw(ctlr, Tcr, 0); regw(ctlr, Rcr, Mon); . 661,662c regw(ctlr, Rbcr0, 0); regw(ctlr, Rbcr1, 0); . 659c regw(ctlr, Dcr, Ft4WORD|Ls); . 655,657c disable(ctlr); if(ctlr->width != 1) regw(ctlr, Dcr, Ft4WORD|Ls|Wts); . 653c * to the 3C503 technical reference manual. . 647,648c ctlr = ether->ctlr; . 644,645c Dp8390 *ctlr; . 642c dp8390reset(Ether* ether) . 640a static void disable(Dp8390* ctlr) { int timo; /* * Stop the chip. Set the Stp bit and wait for the chip * to finish whatever was on its tiny mind before it sets * the Rst bit. * The timeout is needed because there may not be a real * chip there if this is called when probing for a device * at boot. */ regw(ctlr, Cr, Page0|RdABORT|Stp); regw(ctlr, Rbcr0, 0); regw(ctlr, Rbcr1, 0); for(timo = 10000; (regr(ctlr, Isr) & Rst) == 0 && timo; timo--) ; } . 636,638c r |= Pro; ilock(ctlr); regw(ctlr, Rcr, r); r = regr(ctlr, Cntr2); iunlock(ctlr); USED(r); . 634c r = Ab; . 627a ctlr = ether->ctlr; . 625,626c Dp8390 *ctlr; uchar r; . 623c attach(Ether* ether) . 617,619c r |= Pro; ilock(ctlr); regw(ctlr, Rcr, r); iunlock(ctlr); . 615a r = Ab; . 612a ether = arg; ctlr = ether->ctlr; . 611c Ether *ether; Dp8390 *ctlr; uchar r; . 605c regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx); unlock(ctlr); . 599,602c ether->frames += regr(ctlr, Cntr0); ether->crcs += regr(ctlr, Cntr1); ether->buffs += regr(ctlr, Cntr2); regw(ctlr, Isr, Cnt); . 594,595c ctlr->txbusy = 0; txstart(ether); . 590c regw(ctlr, Isr, Txe|Ptx); . 583,586c r = regr(ctlr, Tsr); if((isr & Txe) && (r & (Cdh|Fu|Crs|Abt))){ print("dp8390: Tsr#%2.2ux|", r); . 574c regw(ctlr, Isr, Rxe|Prx); . 569,570c * Packets have been received. * Take a spin round the ring. . 564c regw(ctlr, Isr, Ovw); . 559,561c lock(ctlr); regw(ctlr, Imr, 0x00); while(isr = (regr(ctlr, Isr) & (Cnt|Ovw|Txe|Rxe|Ptx|Prx))){ . 552,553c ctlr = ether->ctlr; . 547,548c Dp8390 *ctlr; . 544c interrupt(Ureg*, void* arg) . 540c regw(ctlr, Cr, Page0|RdABORT|Txp|Sta); . 536,537c regw(ctlr, Isr, Ovw); regw(ctlr, Tcr, 0); . 533,534c regw(ctlr, Tcr, LpbkNIC); regw(ctlr, Cr, Page0|RdABORT|Sta); . 530c if(txp && (regr(ctlr, Isr) & (Txe|Ptx)) == 0) . 526,527c regw(ctlr, Rbcr0, 0); regw(ctlr, Rbcr1, 0); . 523,524c txp = regr(ctlr, Cr) & Txp; regw(ctlr, Cr, Page0|RdABORT|Stp); . 516,517c ctlr = ether->ctlr; . 511,512c Dp8390 *ctlr; . 508a transmit(Ether* ether) { Dp8390 *ctlr; ctlr = ether->ctlr; ilock(ctlr); txstart(ether); iunlock(ctlr); } static void . 505c ether->outpackets++; ctlr->txbusy = 1; . 501,503c regw(ctlr, Tbcr0, len & 0xFF); regw(ctlr, Tbcr1, (len>>8) & 0xFF); regw(ctlr, Cr, Page0|RdABORT|Txp|Sta); . 498,499c if(ctlr->ram) memmove((void*)(ether->mem+ctlr->tstart*Dp8390BufSz), rp, len); else dp8390write(ctlr, ctlr->tstart*Dp8390BufSz, rp, len); freeb(bp); . 494c rp = minpkt; memmove(rp, bp->rp, len); memset(rp+len, 0, ETHERMINTU-len); . 492c len = BLEN(bp); rp = bp->rp; . 489,490c * Make sure the packet is of minimum length; * copy it to the card's memory by the appropriate means; * start the transmission. . 482,486c if(ctlr->txbusy) return; bp = qget(ether->oq); if(bp == nil) return; . 477,480c * This routine is called both from the top level and from interrupt * level and expects to be called with ctlr already locked. . 466,475d 459,464c ctlr = ether->ctlr; . 456,457c int len; Dp8390 *ctlr; Block *bp; uchar minpkt[ETHERMINTU], *rp; . 453,454c static void txstart(Ether* ether) . 447,449c if(hdr.next < ctlr->pstart) hdr.next = ctlr->pstop-1; regw(ctlr, Bnry, hdr.next); . 444c ctlr->nxtpkt = hdr.next; . 437c etheriq(ether, bp, 1); . 431c _dp8390read(ctlr, p, data, len); . 427,429c if(len){ if(ctlr->ram) memmove(p, (void*)(ether->mem+data), len); . 422,425c _dp8390read(ctlr, p, data, count); p += count; data = ctlr->pstart*Dp8390BufSz; len -= count; . 416,420c if((data+len) >= ctlr->pstop*Dp8390BufSz){ count = ctlr->pstop*Dp8390BufSz - data; if(ctlr->ram) memmove(p, (void*)(ether->mem+data), count); . 414d 411,412c if((hdr.status & (Fo|Fae|Crce|Prxok)) == Prxok && (bp = iallocb(len))){ p = bp->rp; bp->wp = p+len; . 406,409c * If the packet wraps round the hardware ring, read it in * two pieces. . 398,400c regw(ctlr, Cr, Page0|RdABORT|Stp); ringinit(ctlr); regw(ctlr, Cr, Page0|RdABORT|Sta); . 394c if(hdr.next < ctlr->pstart || hdr.next >= ctlr->pstop . 389c len = ((len<<8)|hdr.len0)-4; . 387c len--; . 385c len = (ctlr->pstop-ctlr->nxtpkt) + (hdr.next-ctlr->pstart) - 1; . 382,383c if(hdr.next > ctlr->nxtpkt) len = hdr.next - ctlr->nxtpkt - 1; . 375c _dp8390read(ctlr, &hdr, data, sizeof(Hdr)); . 366,372c ctlr = ether->ctlr; for(curr = getcurr(ctlr); ctlr->nxtpkt != curr; curr = getcurr(ctlr)){ data = ctlr->nxtpkt*Dp8390BufSz; if(ctlr->ram) . 364c ulong count, data, len; Block *bp; . 361,362c Dp8390 *ctlr; uchar curr, *p; . 359c receive(Ether* ether) . 351,354c cr = regr(ctlr, Cr) & ~Txp; regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr)); curr = regr(ctlr, Curr); regw(ctlr, Cr, cr); . 348d 346c getcurr(Dp8390* ctlr) . 344a static void ringinit(Dp8390* ctlr) { regw(ctlr, Pstart, ctlr->pstart); regw(ctlr, Pstop, ctlr->pstop); regw(ctlr, Bnry, ctlr->pstop-1); regw(ctlr, Cr, Page1|RdABORT|Stp); regw(ctlr, Curr, ctlr->pstart); regw(ctlr, Cr, Page0|RdABORT|Stp); ctlr->nxtpkt = ctlr->pstart; } . 338,341d 326,336c regw(ctlr, Isr, Rdc); regw(ctlr, Cr, cr); . 321,324c rdwrite(ctlr, from, len); for(timo = 10000; (regr(ctlr, Isr) & Rdc) == 0 && timo; timo--) ; . 319c * Pump the data into the I/O port * then wait for the remote DMA to finish. . 316a else{ regw(ctlr, Rsar0, to & 0xFF); regw(ctlr, Rsar1, (to>>8) & 0xFF); regw(ctlr, Rbcr0, len & 0xFF); regw(ctlr, Rbcr1, (len>>8) & 0xFF); regw(ctlr, Cr, Page0|RdWRITE|Sta); } . 292,314c if(ctlr->dummyrr && (ctlr->width == 1 || ctlr->width == 2)){ if(ctlr->width == 2) width = 1; else width = 0; crda = to-1-width; regw(ctlr, Rbcr0, (len+1+width) & 0xFF); regw(ctlr, Rbcr1, ((len+1+width)>>8) & 0xFF); regw(ctlr, Rsar0, crda & 0xFF); regw(ctlr, Rsar1, (crda>>8) & 0xFF); regw(ctlr, Cr, Page0|RdREAD|Sta); for(;;){ crda = regr(ctlr, Crda0); crda |= regr(ctlr, Crda1)<<8; if(crda == to){ /* * Start the remote DMA write and make sure * the registers are correct. */ regw(ctlr, Cr, Page0|RdWRITE|Sta); crda = regr(ctlr, Crda0); crda |= regr(ctlr, Crda1)<<8; if(crda != to) panic("crda write %d to %d\n", crda, to); break; } . 289,290c * This is straight from the DP8390[12D] datasheet, * hence the initial set up for read. * Assumption here that the A7000 EtherV card will * never need a dummyrr. . 284,285c len = ROUNDUP(len, ctlr->width); . 280,282c cr = regr(ctlr, Cr) & ~Txp; regw(ctlr, Cr, Page0|RdABORT|Sta); regw(ctlr, Isr, Rdc); . 270,275d 267c int timo, width; . 264c void *v; ilock(ctlr); v = dp8390read(ctlr, to, from, len); iunlock(ctlr); return v; } static void* dp8390write(Dp8390* ctlr, ulong to, void* from, ulong len) { . 262c dp8390read(Dp8390* ctlr, void* to, ulong from, ulong len) . 256,257c regw(ctlr, Isr, Rdc); regw(ctlr, Cr, cr); . 253c for(timo = 10000; (regr(ctlr, Isr) & Rdc) == 0 && timo; timo--) . 250,251c * to the miracles of the bus, it's possible to get this * far and still be talking to a slot full of nothing. . 248c * is necessary because this routine may be called on . 240,244c regw(ctlr, Cr, Page0|RdREAD|Sta); rdread(ctlr, to, len); . 229,234c len = ROUNDUP(len, ctlr->width); regw(ctlr, Rbcr0, len & 0xFF); regw(ctlr, Rbcr1, (len>>8) & 0xFF); regw(ctlr, Rsar0, from & 0xFF); regw(ctlr, Rsar1, (from>>8) & 0xFF); . 222,224c cr = regr(ctlr, Cr) & ~Txp; regw(ctlr, Cr, Page0|RdABORT|Sta); regw(ctlr, Isr, Rdc); . 213d 210,211c static void* _dp8390read(Dp8390* ctlr, void* to, ulong from, ulong len) . 203,207c ilock(ctlr); cr = regr(ctlr, Cr) & ~Txp; regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr)); for(i = 0; i < Eaddrlen; i++) regw(ctlr, Par0+i, ether->ea[i]); regw(ctlr, Cr, cr); iunlock(ctlr); . 199,201c * afterwards. Don't care about multicast * addresses as multicast is never enabled * (currently). . 195a ctlr = ether->ctlr; . 194a uchar cr; Dp8390 *ctlr; . 192,193d 190c dp8390setea(Ether* ether) . 173,188d 166,170c ilock(ctlr); cr = regr(ctlr, Cr) & ~Txp; regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr)); for(i = 0; i < Eaddrlen; i++) ea[i] = regr(ctlr, Par0+i); regw(ctlr, Cr, cr); iunlock(ctlr); . 159,164c * Get the ethernet address from the chip. * Take care to restore the command register * afterwards. . 157a ctlr = ether->ctlr; . 155,156c Dp8390 *ctlr; uchar cr; int i; . 152,153c void dp8390getea(Ether* ether, uchar* ea) . 134c enum { /* Rsr */ . 125c enum { /* Rcr */ . 115c enum { /* Tsr */ . 110c Lb0 = 0x02, /* encoded loopback control */ Lb1 = 0x04, LpbkNORMAL = 0x00, /* normal operation */ LpbkNIC = Lb0, /* internal NIC module loopback */ LpbkENDEC = Lb1, /* internal ENDEC module loopback */ LpbkEXTERNAL = Lb1|Lb0, /* external loopback */ . 108c enum { /* Tcr */ . 102,105c Ft0 = 0x20, /* FIFO threshold select */ Ft1 = 0x40, Ft1WORD = 0x00, Ft2WORD = Ft0, Ft4WORD = Ft1, Ft6WORD = Ft1|Ft0, . 86,96c enum { /* Dcr */ . 75c enum { /* Cr */ Stp = 0x01, /* stop */ Sta = 0x02, /* start */ Txp = 0x04, /* transmit packet */ Rd0 = 0x08, /* remote DMA command */ Rd1 = 0x10, Rd2 = 0x20, RdREAD = Rd0, /* remote read */ RdWRITE = Rd1, /* remote write */ RdSEND = Rd1|Rd0, /* send packet */ RdABORT = Rd2, /* abort/complete remote DMA */ Ps0 = 0x40, /* page select */ Ps1 = 0x80, Page0 = 0x00, Page1 = Ps0, Page2 = Ps1, }; enum { /* Isr/Imr */ . 69c /* Page 1, read/write */ . 67d 53c /* Page 0, write */ . 51d 23,37c /* Page 0, read */ . 17,20c enum { /* NIC core registers */ . 15a #include "ether8390.h" . 2,3c * National Semiconductor DP8390 and clone . ## diffname pc/ether8390.c 1997/0415 ## diff -e /n/emeliedump/1997/0327/sys/src/brazil/pc/ether8390.c /n/emeliedump/1997/0415/sys/src/brazil/pc/ether8390.c 721a ether->multicast = multicast; . 644a if(ether->nmaddr) r |= Am; . 628a multicast(void* arg, uchar *addr, int on) { Ether *ether; Dp8390 *ctlr; uchar r, cr; int i; ulong h; USED(addr, on); ether = arg; ctlr = ether->ctlr; /* * change filter bits */ h = ethercrc(addr, 6); h = h>>(32-6); i = h/8; h = h%8; ilock(ctlr); cr = regr(ctlr, Cr) & ~Txp; regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr)); r = regr(ctlr, Mar0+i); if(on){ if(++(ctlr->mref[h]) == 1) r |= 1<mref[h]) <= 0){ ctlr->mref[h] = 0; r &= ~(1<nmaddr) r |= Am; if(ether->prom) r |= Pro; ilock(ctlr); regw(ctlr, Rcr, r); iunlock(ctlr); } static void . 622a if(ether->nmaddr) r |= Am; . ## diffname pc/ether8390.c 1997/0418 ## diff -e /n/emeliedump/1997/0415/sys/src/brazil/pc/ether8390.c /n/emeliedump/1997/0418/sys/src/brazil/pc/ether8390.c 652,677c setbit(ctlr, reverse[h&0x3f], on); setfilter(ether, ctlr); . 648,650d 642a if(reverse[1] == 0){ for(i = 0; i < 64; i++) reverse[i] = ((i&1)<<5) | ((i&2)<<3) | ((i&4)<<1) | ((i&8)>>1) | ((i&16)>>3) | ((i&32)>>5); } . 639c USED(on); . 635d 630a setbit(Dp8390 *ctlr, int bit, int on) { int i, h; i = bit/8; h = bit%8; if(on){ if(++(ctlr->mref[bit]) == 1) ctlr->mar[i] |= 1<mref[bit]) <= 0){ ctlr->mref[bit] = 0; ctlr->mar[i] &= ~(1<prom){ r |= Pro|Am; mar = allmar; } else if(ether->nmaddr){ r |= Am; mar = ctlr->mar; } if(mar){ cr = regr(ctlr, Cr) & ~Txp; regw(ctlr, Cr, Page1|(~(Ps1|Ps0) & cr)); for(i = 0; i < 8; i++) regw(ctlr, Mar0+i, *(mar++)); regw(ctlr, Cr, cr); } regw(ctlr, Rcr, r); } static void . 606a static uchar allmar[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; . ## diffname pc/ether8390.c 1998/0129 ## diff -e /n/emeliedump/1997/0418/sys/src/brazil/pc/ether8390.c /n/emeliedump/1998/0129/sys/src/brazil/pc/ether8390.c 249c v = _dp8390read(ctlr, to, from, len); . ## diffname pc/ether8390.c 1998/0319 ## diff -e /n/emeliedump/1998/0129/sys/src/brazil/pc/ether8390.c /n/emeliedump/1998/0319/sys/src/brazil/pc/ether8390.c 678,679d 641,642d 636c promiscuous(void *arg, int ) . ## diffname pc/ether8390.c 1998/0825 ## diff -e /n/emeliedump/1998/0319/sys/src/brazil/pc/ether8390.c /n/emeliedump/1998/0825/sys/src/brazil/pc/ether8390.c 396c print("dp8390: H#%2.2ux#%2.2ux#%2.2ux#%2.2ux,%lud\n", . ## diffname pc/ether8390.c 2000/0604 ## diff -e /n/emeliedump/1998/0825/sys/src/brazil/pc/ether8390.c /n/emeliedump/2000/0604/sys/src/9/pc/ether8390.c 774c regw(ctlr, Imr, 0); . 772a /* * Clear any pending interrupts and mask then all off. */ . 762c regw(ctlr, Tcr, LpbkNIC); . 716a regw(ctlr, Tcr, LpbkNORMAL); . 714a regw(ctlr, Isr, 0xFF); regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx); . 707a * Sometimes there's an interrupt pending at this * point but there's nothing in the Isr, so * any pending interrupts are cleared and the * mask of acceptable interrupts is enabled here. . 604c iunlock(ctlr); . 558c ilock(ctlr); . 538c regw(ctlr, Tcr, LpbkNORMAL); . ## diffname pc/ether8390.c 2002/0114 ## diff -e /n/emeliedump/2000/0604/sys/src/9/pc/ether8390.c /n/emeliedump/2002/0114/sys/src/9/pc/ether8390.c 305c panic("crda write %lud to %lud\n", crda, to); .