~kris/9p

9hist

945d71338cd4332fbbd846f9f9256d7eb9939ff7 — David du Colombier 26 years ago 360bd0a
Plan 9 from Bell Labs 2000-06-04
2 files changed, 55 insertions(+), 13 deletions(-)

M pc/ether8390.c
M pc/etherec2t.c
M pc/ether8390.c => pc/ether8390.c +15 -5
@@ 535,7 535,7 @@ overflow(Ether *ether)
	regw(ctlr, Cr, Page0|RdABORT|Sta);
	receive(ether);
	regw(ctlr, Isr, Ovw);
	regw(ctlr, Tcr, 0);
	regw(ctlr, Tcr, LpbkNORMAL);

	if(resend)
		regw(ctlr, Cr, Page0|RdABORT|Txp|Sta);


@@ 555,7 555,7 @@ interrupt(Ureg*, void* arg)
	 * While there is something of interest,
	 * clear all the interrupts and process.
	 */
	lock(ctlr);
	ilock(ctlr);
	regw(ctlr, Imr, 0x00);
	while(isr = (regr(ctlr, Isr) & (Cnt|Ovw|Txe|Rxe|Ptx|Prx))){
		if(isr & Ovw){


@@ 601,7 601,7 @@ interrupt(Ureg*, void* arg)
		}
	}
	regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx);
	unlock(ctlr);
	iunlock(ctlr);
}

static uchar allmar[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };


@@ 705,6 705,10 @@ attach(Ether* ether)
	 * The init routine leaves the chip in monitor
	 * mode. Clear the missed-packet counter, it
	 * increments while in monitor mode.
	 * 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.
	 */
	r = Ab;
	if(ether->prom)


@@ 712,8 716,11 @@ attach(Ether* ether)
	if(ether->nmaddr)
		r |= Am;
	ilock(ctlr);
	regw(ctlr, Isr, 0xFF);
	regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx);
	regw(ctlr, Rcr, r);
	r = regr(ctlr, Cntr2);
	regw(ctlr, Tcr, LpbkNORMAL);
	iunlock(ctlr);
	USED(r);
}


@@ 759,7 766,7 @@ dp8390reset(Ether* ether)
	regw(ctlr, Rbcr0, 0);
	regw(ctlr, Rbcr1, 0);

	regw(ctlr, Tcr, 0);
	regw(ctlr, Tcr, LpbkNIC);
	regw(ctlr, Rcr, Mon);

	/*


@@ 770,8 777,11 @@ dp8390reset(Ether* ether)
	ringinit(ctlr);
	regw(ctlr, Tpsr, ctlr->tstart);

	/*
	 * Clear any pending interrupts and mask then all off.
	 */
	regw(ctlr, Isr, 0xFF);
	regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx);
	regw(ctlr, Imr, 0);

	/*
	 * Leave the chip initialised,

M pc/etherec2t.c => pc/etherec2t.c +40 -8
@@ 1,6 1,7 @@
/*
 * Linksys Combo PCMCIA EthernetCard (EC2T).
 * Supposedly an NE2000 clone, see the comments in ether2000.c
 * Linksys Combo PCMCIA EthernetCard (EC2T)
 * and EtherFast 10/100 PC Card (PCMPC100).
 * Supposedly NE2000 clones, see the comments in ether2000.c
 */
#include "u.h"
#include "../port/lib.h"


@@ 13,11 14,18 @@

#include "etherif.h"
#include "ether8390.h"

enum {
	Data		= 0x10,		/* offset from I/O base of data port */
	Reset		= 0x1F,		/* offset from I/O base of reset port */
};

static char* ec2tpcmcia[] = {
	"EC2T",
	"PCMPC100",
	nil,
};

static int
reset(Ether* ether)
{


@@ 25,7 33,8 @@ reset(Ether* ether)
	ulong port;
	Dp8390 *ctlr;
	int i, slot;
	uchar ea[Eaddrlen];
	uchar ea[Eaddrlen], sum, x;
	char *type;

	/*
	 * Set up the software configuration.


@@ 46,7 55,14 @@ reset(Ether* ether)

	if(ioalloc(ether->port, 0x20, 0, "ec2t") < 0)
		return -1;
	if((slot = pcmspecial(ether->type, ether)) < 0){
	slot = -1;
	type = nil;
	for(i = 0; ec2tpcmcia[i] != nil; i++){
		type = ec2tpcmcia[i];
		if((slot = pcmspecial(type, ether)) >= 0)
			break;
	}
	if(slot < 0){
		iofree(port);
		return -1;
	}


@@ 79,7 95,7 @@ reset(Ether* ether)
	delay(2);
	outb(port+Reset, buf[0]);
	delay(2);
	

	/*
	 * Init the (possible) chip, then use the (possible)
	 * chip to read the (possible) PROM for ethernet address


@@ 90,9 106,25 @@ reset(Ether* ether)
	 * match.
	 */
	dp8390reset(ether);
	memset(buf, 0, sizeof(buf));
	dp8390read(ctlr, buf, 0, sizeof(buf));
	if((buf[0x0E] & 0xFF) != 0x57 || (buf[0x0F] & 0xFF) != 0x57){
	sum = 0;
	if(strcmp(type, "PCMPC100")){
		memset(buf, 0, sizeof(buf));
		dp8390read(ctlr, buf, 0, sizeof(buf));
		if((buf[0x0E] & 0xFF) == 0x57 && (buf[0x0F] & 0xFF) == 0x57)
			sum = 0xFF;
	}
	else{
		/*
		 * The PCMPC100 has the ethernet address in I/O space.
		 * There's a checksum over 8 bytes which sums to 0xFF.
		 */
		for(i = 0; i < 8; i++){
			x = inb(port+0x14+i);
			sum += x;
			buf[i] = (x<<8)|x;
		}
	}
	if(sum != 0xFF){
		pcmspecialclose(slot);
		iofree(ether->port);
		free(ether->ctlr);