| plan 9 kernel history: overview | file list | diff list |
1995/0409/pc/ether8390.c (diff list | history)
| 1995/0408/sys/src/9/pc/ether8390.c:14,19 – 1995/0409/sys/src/9/pc/ether8390.c:14,22 (short | long | prev | next) | ||
| 1992/1222 | ||
| 1993/1116 | #include "etherif.h" | |
| 1992/1222 | ||
| 1995/0409 | extern int slowinb(ulong); extern void slowoutb(ulong, uchar); | |
| 1992/1222 | enum { Cr = 0x00, /* command register, all pages */ | |
| 1995/0408/sys/src/9/pc/ether8390.c:146,171 – 1995/0409/sys/src/9/pc/ether8390.c:149,154 | ||
| 1992/1222 | uchar len1; } Hdr; | |
| 1995/0408 |
| |
| 1992/1222 | static void | |
| 1993/1117 | dp8390disable(Dp8390 *dp8390) | |
| 1992/1222 | { | |
| 1995/0408/sys/src/9/pc/ether8390.c:180,189 – 1995/0409/sys/src/9/pc/ether8390.c:163,172 | ||
| 1992/1222 | * chip there if this is called when probing for a device * at boot. */ | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Cr, Page0|RDMAabort|Stp); slowoutb(port+Rbcr0, 0); slowoutb(port+Rbcr1, 0); for(timo = 10000; (slowinb(port+Isr) & Rst) == 0 && timo; timo--) | |
| 1992/1222 | ; } | |
| 1995/0408/sys/src/9/pc/ether8390.c:192,204 – 1995/0409/sys/src/9/pc/ether8390.c:175,187 | ||
| 1993/0212 | { | |
| 1993/1118 | ulong port = dp8390->dp8390; | |
| 1993/0212 | ||
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Pstart, dp8390->pstart); slowoutb(port+Pstop, dp8390->pstop); slowoutb(port+Bnry, dp8390->pstop-1); | |
| 1993/0212 | ||
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Cr, Page1|RDMAabort|Stp); slowoutb(port+Curr, dp8390->pstart); slowoutb(port+Cr, Page0|RDMAabort|Stp); | |
| 1993/0915 | ||
| 1993/1117 | dp8390->nxtpkt = dp8390->pstart; | |
| 1993/0212 | } | |
| 1995/0408/sys/src/9/pc/ether8390.c:217,227 – 1995/0409/sys/src/9/pc/ether8390.c:200,210 | ||
| 1992/1222 | * addresses as we never set the multicast * enable. */ | |
| 1995/0408 |
| |
| 1995/0409 | cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); | |
| 1993/1116 | for(i = 0; i < sizeof(ether->ea); i++) | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Par0+i, ether->ea[i]); slowoutb(port+Cr, cr); | |
| 1992/1222 | } | |
| 1993/0915 | void | |
| 1995/0408/sys/src/9/pc/ether8390.c:238,248 – 1995/0409/sys/src/9/pc/ether8390.c:221,231 | ||
| 1993/0915 | * addresses as we never set the multicast * enable. */ | |
| 1995/0408 |
| |
| 1995/0409 | cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); | |
| 1993/1116 | for(i = 0; i < sizeof(ether->ea); i++) | |
| 1995/0408 |
| |
| 1995/0409 | ether->ea[i] = slowinb(port+Par0+i); slowoutb(port+Cr, cr); | |
| 1993/0915 | } | |
| 1994/0128 | void* | |
| 1995/0408/sys/src/9/pc/ether8390.c:257,265 – 1995/0409/sys/src/9/pc/ether8390.c:240,248 | ||
| 1992/1222 | * using the DP8390 remote DMA facility, and place it at * 'to' in main memory, via the I/O data port. */ | |
| 1995/0408 |
| |
| 1995/0409 | cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page0|RDMAabort|Sta); slowoutb(port+Isr, Rdc); | |
| 1992/1222 | /* * Set up the remote DMA address and count. | |
| 1995/0408/sys/src/9/pc/ether8390.c:266,281 – 1995/0409/sys/src/9/pc/ether8390.c:249,264 | ||
| 1992/1222 | */ | |
| 1993/1117 | if(dp8390->bit16) | |
| 1992/1222 | len = ROUNDUP(len, 2); | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Rbcr0, len & 0xFF); slowoutb(port+Rbcr1, (len>>8) & 0xFF); slowoutb(port+Rsar0, from & 0xFF); slowoutb(port+Rsar1, (from>>8) & 0xFF); | |
| 1992/1222 | /* * Start the remote DMA read and suck the data * out of the I/O port. */ | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Cr, Page0|RDMAread|Sta); | |
| 1993/1117 | if(dp8390->bit16) inss(dp8390->data, to, len/2); | |
| 1992/1222 | else | |
| 1995/0408/sys/src/9/pc/ether8390.c:288,298 – 1995/0409/sys/src/9/pc/ether8390.c:271,281 | ||
| 1992/1222 | * to the miracles of the bus, we could get this far * and still be talking to a slot full of nothing. */ | |
| 1995/0408 |
| |
| 1995/0409 | for(timo = 10000; (slowinb(port+Isr) & Rdc) == 0 && timo; timo--) | |
| 1992/1222 | ; | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Isr, Rdc); slowoutb(port+Cr, cr); | |
| 1992/1222 | return to; } | |
| 1995/0408/sys/src/9/pc/ether8390.c:315,323 – 1995/0409/sys/src/9/pc/ether8390.c:298,306 | ||
| 1992/1222 | * using the DP8390 remote DMA facility, reading it at * 'from' in main memory, via the I/O data port. */ | |
| 1995/0408 |
| |
| 1995/0409 | cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page0|RDMAabort|Sta); slowoutb(port+Isr, Rdc); | |
| 1992/1222 | ||
| 1993/1118 | if(dp8390->bit16) | |
| 1993/0212 | len = ROUNDUP(len, 2); | |
| 1995/0408/sys/src/9/pc/ether8390.c:328,351 – 1995/0409/sys/src/9/pc/ether8390.c:311,334 | ||
| 1993/0212 | * the initial set up for read. | |
| 1992/1222 | */ | |
| 1993/1118 | crda = to-1-dp8390->bit16; | |
| 1995/0408 |
| |
| 1995/0409 | 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); | |
| 1992/1222 | ||
| 1993/0212 | for(;;){ | |
| 1995/0408 |
| |
| 1995/0409 | crda = slowinb(port+Crda0); crda |= slowinb(port+Crda1)<<8; | |
| 1993/0212 | if(crda == to){ /* * Start the remote DMA write and make sure * the registers are correct. */ | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Cr, Page0|RDMAwrite|Sta); | |
| 1992/1222 | ||
| 1995/0408 |
| |
| 1995/0409 | crda = slowinb(port+Crda0); crda |= slowinb(port+Crda1)<<8; | |
| 1993/0212 | if(crda != to) panic("crda write %d to %d\n", crda, to); | |
| 1995/0408/sys/src/9/pc/ether8390.c:366,372 – 1995/0409/sys/src/9/pc/ether8390.c:349,355 | ||
| 1994/0202 | * be almost immediate. | |
| 1992/1222 | */ | |
| 1994/0201 | tries = 0; | |
| 1995/0408 |
| |
| 1995/0409 | while((slowinb(port+Isr) & Rdc) == 0){ | |
| 1994/0202 | if(tries++ >= 100000){ print("dp8390write dma timed out\n"); | |
| 1994/0201 | break; | |
| 1995/0408/sys/src/9/pc/ether8390.c:373,380 – 1995/0409/sys/src/9/pc/ether8390.c:356,363 | ||
| 1994/0201 | } | |
| 1994/0202 | } | |
| 1992/1222 | ||
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Isr, Rdc); slowoutb(port+Cr, cr); | |
| 1994/0202 | splx(s); | |
| 1992/1222 | return (void*)to; | |
| 1995/0408/sys/src/9/pc/ether8390.c:386,395 – 1995/0409/sys/src/9/pc/ether8390.c:369,378 | ||
| 1993/1118 | ulong port = dp8390->dp8390; | |
| 1993/0212 | uchar cr, curr; | |
| 1995/0408 |
| |
| 1995/0409 | cr = slowinb(port+Cr) & ~Txp; slowoutb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); curr = slowinb(port+Curr); slowoutb(port+Cr, cr); | |
| 1993/0212 | return curr; } | |
| 1995/0408/sys/src/9/pc/ether8390.c:433,441 – 1995/0409/sys/src/9/pc/ether8390.c:416,424 | ||
| 1993/0212 | || len < 60 || len > sizeof(Etherpkt)){ | |
| 1993/1118 | print("dp8390: H#%2.2ux#%2.2ux#%2.2ux#%2.2ux,%d\n", | |
| 1993/0212 | hdr.status, hdr.next, hdr.len0, hdr.len1, len); | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Cr, Page0|RDMAabort|Stp); | |
| 1993/1118 | dp8390ring(dp8390); | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Cr, Page0|RDMAabort|Sta); | |
| 1992/1222 | return; } | |
| 1995/0408/sys/src/9/pc/ether8390.c:484,490 – 1995/0409/sys/src/9/pc/ether8390.c:467,473 | ||
| 1993/0212 | hdr.next--; | |
| 1993/1118 | if(hdr.next < dp8390->pstart) hdr.next = dp8390->pstop-1; | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Bnry, hdr.next); | |
| 1992/1222 | } } | |
| 1995/0408/sys/src/9/pc/ether8390.c:536,544 – 1995/0409/sys/src/9/pc/ether8390.c:519,527 | ||
| 1993/1120 | if(dp8390->ram == 0) dp8390write(dp8390, dp8390->tstart*Dp8390BufSz, pkt, len); | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Tbcr0, len & 0xFF); slowoutb(port+Tbcr1, (len>>8) & 0xFF); slowoutb(port+Cr, Page0|RDMAabort|Txp|Sta); | |
| 1993/1118 | ||
| 1993/1120 | return len; | |
| 1993/0212 | } | |
| 1995/0408/sys/src/9/pc/ether8390.c:558,581 – 1995/0409/sys/src/9/pc/ether8390.c:541,564 | ||
| 1993/0212 | * The following procedure is taken from the DP8390[12D] datasheet, * it seems pretty adamant that this is what has to be done. */ | |
| 1995/0408 |
| |
| 1995/0409 | txp = slowinb(port+Cr) & Txp; slowoutb(port+Cr, Page0|RDMAabort|Stp); | |
| 1993/0212 | delay(2); | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Rbcr0, 0); slowoutb(port+Rbcr1, 0); | |
| 1993/0212 | resend = 0; | |
| 1995/0408 |
| |
| 1995/0409 | if(txp && (slowinb(port+Isr) & (Txe|Ptx)) == 0) | |
| 1993/0212 | resend = 1; | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Tcr, Lb); slowoutb(port+Cr, Page0|RDMAabort|Sta); | |
| 1993/1118 | receive(ether); | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Isr, Ovw); slowoutb(port+Tcr, 0); | |
| 1993/0212 | if(resend) | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Cr, Page0|RDMAabort|Txp|Sta); | |
| 1993/0212 | } | |
| 1993/1116 | static void | |
| 1995/0408/sys/src/9/pc/ether8390.c:596,607 – 1995/0409/sys/src/9/pc/ether8390.c:579,590 | ||
| 1992/1222 | * While there is something of interest, * clear all the interrupts and process. */ | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Imr, 0x00); while(isr = slowinb(port+Isr)){ | |
| 1992/1222 | if(isr & Ovw){ | |
| 1993/1116 | overflow(ether); | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Isr, Ovw); | |
| 1993/1116 | ether->overflows++; | |
| 1992/1222 | } | |
| 1995/0408/sys/src/9/pc/ether8390.c:611,617 – 1995/0409/sys/src/9/pc/ether8390.c:594,600 | ||
| 1992/1222 | */ if(isr & (Rxe|Prx)){ | |
| 1993/1116 | receive(ether); | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Isr, Rxe|Prx); | |
| 1992/1222 | } /* | |
| 1995/0408/sys/src/9/pc/ether8390.c:620,626 – 1995/0409/sys/src/9/pc/ether8390.c:603,609 | ||
| 1992/1222 | * and wake the output routine. */ if(isr & (Txe|Ptx)){ | |
| 1995/0408 |
| |
| 1995/0409 | r = slowinb(port+Tsr); | |
| 1993/0212 | if(isr & Txe){ | |
| 1993/1118 | if((r & (Cdh|Fu|Crs|Abt))) print("dp8390: Tsr#%2.2ux\n", r); | |
| 1995/0408/sys/src/9/pc/ether8390.c:627,633 – 1995/0409/sys/src/9/pc/ether8390.c:610,616 | ||
| 1993/1116 | ether->oerrs++; | |
| 1993/0212 | } | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Isr, Txe|Ptx); | |
| 1993/0212 | if(isr & Ptx) | |
| 1993/1116 | ether->outpackets++; | |
| 1995/0408/sys/src/9/pc/ether8390.c:636,648 – 1995/0409/sys/src/9/pc/ether8390.c:619,631 | ||
| 1992/1222 | } | |
| 1993/0212 | if(isr & Cnt){ | |
| 1995/0408 |
| |
| 1995/0409 | ether->frames += slowinb(port+Cntr0); ether->crcs += slowinb(port+Cntr1); ether->buffs += slowinb(port+Cntr2); slowoutb(port+Isr, Cnt); | |
| 1993/0212 | } | |
| 1992/1222 | } | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); | |
| 1993/1116 | } static void | |
| 1995/0408/sys/src/9/pc/ether8390.c:654,662 – 1995/0409/sys/src/9/pc/ether8390.c:637,645 | ||
| 1993/1116 | * Set/reset promiscuous mode. */ if(on) | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(dp8390->dp8390+Rcr, Pro|Ab); | |
| 1993/1116 | else | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(dp8390->dp8390+Rcr, Ab); | |
| 1993/1116 | } | |
| 1993/1118 | static void | |
| 1995/0408/sys/src/9/pc/ether8390.c:670,677 – 1995/0409/sys/src/9/pc/ether8390.c:653,660 | ||
| 1993/1116 | * mode. Clear the missed-packet counter, it * increments while in monitor mode. */ | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(dp8390->dp8390+Rcr, Ab); slowinb(dp8390->dp8390+Cntr2); | |
| 1993/1116 | } | |
| 1993/1118 | int | |
| 1995/0408/sys/src/9/pc/ether8390.c:690,704 – 1995/0409/sys/src/9/pc/ether8390.c:673,687 | ||
| 1993/1116 | */ | |
| 1993/1118 | dp8390disable(dp8390); if(dp8390->bit16) | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Dcr, Ft4|Ls|Wts); | |
| 1993/1116 | else | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Dcr, Ft4|Ls); | |
| 1993/1116 | ||
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Rbcr0, 0); slowoutb(port+Rbcr1, 0); | |
| 1993/1116 | ||
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Tcr, 0); slowoutb(port+Rcr, Mon); | |
| 1993/1116 | /* * Init the ring hardware and software ring pointers. | |
| 1995/0408/sys/src/9/pc/ether8390.c:706,721 – 1995/0409/sys/src/9/pc/ether8390.c:689,704 | ||
| 1993/1116 | * it yet. */ | |
| 1993/1118 | dp8390ring(dp8390); | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Tpsr, dp8390->tstart); | |
| 1993/1116 | ||
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Isr, 0xFF); slowoutb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); | |
| 1993/1116 | /* * Leave the chip initialised, * but in monitor mode. */ | |
| 1995/0408 |
| |
| 1995/0409 | slowoutb(port+Cr, Page0|RDMAabort|Sta); | |
| 1993/1116 | /* * Set up the software configuration. | |