~kris/9p

9hist

a5da6053df47f9cbd3b02bbf8a49a4355023f009 — David du Colombier 25 years ago fbb116e
Plan 9 from Bell Labs 2001-04-19
1 files changed, 54 insertions(+), 56 deletions(-)

M pc/ether82557.c
M pc/ether82557.c => pc/ether82557.c +54 -56
@@ 183,11 183,16 @@ enum {					/* CbTransmit count */
	CbEOF		= 0x8000,
};

typedef struct Ctlr Ctlr;
typedef struct Ctlr {
	Lock	slock;			/* attach */
	int	state;

	int	port;
	Pcidev*	pcidev;
	Ctlr*	next;
	int	active;

	int	eepromsz;		/* address size in bits */
	ushort*	eeprom;



@@ 219,6 224,9 @@ typedef struct Ctlr {
	ulong	dump[17];
} Ctlr;

static Ctlr* ctlrhead;
static Ctlr* ctlrtail;

static uchar configdata[24] = {
	0x16,				/* byte count */
	0x08,				/* Rx/Tx FIFO limit */


@@ 882,34 890,12 @@ reread:
	return data;
}

typedef struct Adapter {
	int	port;
	int	irq;
	int	tbdf;
} Adapter;
static Block* adapter;

static void
i82557adapter(Block** bpp, int port, int irq, int tbdf)
{
	Block *bp;
	Adapter *ap;

	bp = allocb(sizeof(Adapter));
	ap = (Adapter*)bp->rp;
	ap->port = port;
	ap->irq = irq;
	ap->tbdf = tbdf;

	bp->next = *bpp;
	*bpp = bp;
}

static void
i82557pci(void)
{
	Pcidev *p;
	int port;
	Pcidev *p;
	Ctlr *ctlr;

	p = nil;
	while(p = pcimatch(p, 0x8086, 0x1229)){


@@ 919,11 905,21 @@ i82557pci(void)
		 * bar[2] is for the flash ROM (1MB).
		 */
		port = p->mem[1].bar & ~0x01;
		if(ioalloc(port, p->mem[1].size, 0, "i82557pci") < 0){
			print("i82557pci: port 0x%uX in use\n", port);
		if(ioalloc(port, p->mem[1].size, 0, "i82557") < 0){
			print("i82557: port 0x%uX in use\n", port);
			continue;
		}
		i82557adapter(&adapter, port, p->intl, p->tbdf);

		ctlr = malloc(sizeof(Ctlr));
		ctlr->port = port;
		ctlr->pcidev = p;

		if(ctlrhead != nil)
			ctlrtail->next = ctlr;
		else
			ctlrhead = ctlr;
		ctlrtail = ctlr;

		pcisetbme(p);
	}
}


@@ 970,51 966,41 @@ scanphy(Ctlr* ctlr)
static int
reset(Ether* ether)
{
	int anar, anlpar, bmcr, bmsr, i, k, medium, phyaddr, port, x;
	int anar, anlpar, bmcr, bmsr, i, k, medium, phyaddr, x;
	unsigned short sum;
	Block *bp, **bpp;
	Adapter *ap;
	uchar ea[Eaddrlen];
	Ctlr *ctlr;
	static int scandone;

	if(scandone == 0){
	if(ctlrhead == nil)
		i82557pci();
		scandone = 1;
	}

	/*
	 * Any adapter matches if no port is supplied,
	 * Any adapter matches if no ether->port is supplied,
	 * otherwise the ports must match.
	 */
	port = 0;
	bpp = &adapter;
	for(bp = *bpp; bp; bp = bp->next){
		ap = (Adapter*)bp->rp;
		if(ether->port == 0 || ether->port == ap->port){
			port = ap->port;
			ether->irq = ap->irq;
			ether->tbdf = ap->tbdf;
			*bpp = bp->next;
			freeb(bp);
	for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
		if(ctlr->active)
			continue;
		if(ether->port == 0 || ether->port == ctlr->port){
			ctlr->active = 1;
			break;
		}
		bpp = &bp->next;
	}
	if(port == 0)
	if(ctlr == nil)
		return -1;

	/*
	 * Allocate a controller structure and start to initialise it.
	 * Initialise the Ctlr structure.
	 * Perform a software reset after which should ensure busmastering
	 * is still enabled. The EtherExpress PRO/100B appears to leave
	 * the PCI configuration alone (see the 'To do' list above) so punt
	 * for now.
	 * Load the RUB and CUB registers for linear addressing (0).
	 */
	ether->ctlr = malloc(sizeof(Ctlr));
	ctlr = ether->ctlr;
	ctlr->port = port;
	ether->ctlr = ctlr;
	ether->port = ctlr->port;
	ether->irq = ctlr->pcidev->intl;
	ether->tbdf = ctlr->pcidev->tbdf;

	ilock(&ctlr->rlock);
	csr32w(ctlr, Port, 0);


@@ 1053,16 1039,29 @@ reset(Ether* ether)
	 * to set any PHY specific options and determine the speed.
	 * Unfortunately, sometimes the EEPROM is blank except for
	 * the ether address and checksum; in this case look at the
	 * controller type and if 0 scan for the first PHY and try to
	 * use that.
	 * controller type and if it's am 82558 or 82559 it has an
	 * embedded PHY so scan for that.
	 * If no PHY, assume 82503 (serial) operation.
	 */
	if((ctlr->eeprom[6] & 0x1F00) && !(ctlr->eeprom[6] & 0x8000))
		phyaddr = ctlr->eeprom[6] & 0x00FF;
	else if(!(ctlr->eeprom[5] & 0xFF00))
		phyaddr = scanphy(ctlr);
	else
	switch(ctlr->pcidev->rid){
	case 0x01:			/* 82557 A-step */
	case 0x02:			/* 82557 B-step */
	case 0x03:			/* 82557 C-step */
	default:
		phyaddr = -1;
		break;
	case 0x04:			/* 82558 A-step */
	case 0x05:			/* 82558 B-step */
	case 0x06:			/* 82559 A-step */
	case 0x07:			/* 82559 B-step */
	case 0x08:			/* 82559 C-step */
	case 0x09:			/* 82559ER A-step */
		phyaddr = scanphy(ctlr);
		break;
	}
	if(phyaddr >= 0){
		/*
		 * Resolve the highest common ability of the two


@@ 1234,7 1233,6 @@ reset(Ether* ether)
	/*
	 * Linkage to the generic ethernet driver.
	 */
	ether->port = port;
	ether->attach = attach;
	ether->transmit = transmit;
	ether->interrupt = interrupt;