⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dec21041.c

📁 开源的BIOS启动软件
💻 C
字号:
#include <bios/types.h>#include <bios/malloc.h>#include <bios/netdev.h>#include <bios/string.h>#include <bios/pci.h>#include <bios/if_ether.h>#include <bios/stdio.h>struct netdev net_dev_dec_21041;extern const struct trans_ops eth_trans_ops;#define virt_to_bus(x)	((int)(x) + 0x10000000)#define inw(x)		pci_io_read_word(nd->io_base + (x))#define outw(w,x)	pci_io_write_word((w), nd->io_base + (x))#define inl(x)		pci_io_read_long(nd->io_base + (x))#define outl(w,x)	pci_io_write_long((w), nd->io_base + (x))#define RECVBUFFERSZ 1600static volatile unsigned int recvdesc[4];static volatile unsigned int transdesc[4];static unsigned short pci_ids[] = { 0x0014, 0x0019 };struct nd_21041_priv {	unsigned long csr14;	unsigned long csr15;	unsigned long csr13;	unsigned long csr6;	char recvbuffer[RECVBUFFERSZ];};static int nd_21041_probe(void){	struct netdev *nd = &net_dev_dec_21041;	struct pci_dev *dev;	struct nd_21041_priv *ndp;	int i;	for (i = 0; i < sizeof(pci_ids) / sizeof(pci_ids[0]); i++) {		dev = pci_lookup_vendor_device(NULL, 0x1011, pci_ids[i]);		if (!dev)			continue;		if (pci_enable(dev))			continue;		if (pci_set_master(dev))			continue;		nd->io_base = dev->bar[0] & ~3;		ndp = nd->ptr1 = malloc(sizeof(*ndp));		nd->hw_addr[0] = 0x45; /* E */		nd->hw_addr[1] = 0x42; /* B */		nd->hw_addr[2] = 0x53; /* S */		nd->hw_addr[3] = 0x41; /* A */		nd->hw_addr[4] = 0x44; /* D */		nd->hw_addr[5] = 0x47; /* G */		/* read h/w address */		nd->hw_addr_len = 6;		printf(" net: DEC21041 at %04x, ether address 45:42:53:41:44:47\n",			nd->io_base);		switch (pci_ids[i]) {		case 0x0014:	/* 21041 */			ndp->csr14 = 0x0000f7fd;			ndp->csr15 = 0x00000006;			ndp->csr13 = 0x0000ef09;			ndp->csr6  = 0x80020000;			break;		case 0x0019:	/* 21143 */			ndp->csr14 = 0x0000ffff;			ndp->csr15 = 0x00000008;			ndp->csr13 = 0x000e0001;			ndp->csr6  = 0x82020000;			break;		}	}	return nd->io_base ? 0 : -1;}static int nd_21041_setmedia(struct netdev *nd, media_t media){	return 0;}static int nd_21041_checkmedia(struct netdev *nd){	return 0;}static int nd_21041_open(struct netdev *nd){	struct nd_21041_priv *ndp = nd->ptr1;	unsigned int setupframe[3*16];	int i;	/* CSR0 - mus mode reg	 *  no transmit poll, 16 lword burst, 8 word cache align, little endian	 */	outl(0x5006, 0);	/* CSR7 - interrupt mask reg	 *   no interrupts thanks	 */	outl(0, 0x38);	/* Disable SIA	 */	outl(0, 0x68);	/* From table 3-64 on p.94 of the 21041 hardware ref manual	 * Use ef09,f7fd,0006 for 10base2 (Auto Negotiation) - seems to work for b2	 * Use ef01,ffff,0008 for 10baseT (Auto Negotiation) - seems to work for bT	 * Use ef09,0705,0006 for 10base2 (Auto sensing and negotiation disabled) - seems to work for b2	 * Hang on - if its auto neg why the difference?	 * We have to see if there is a link beat and if missing try the other	 */	/* CSR14 - SIA transmit/receive	 */	outl(ndp->csr14, 0x70);	/* CSR15 - SIA general	 */	outl(ndp->csr15, 0x78);	/* CSR13 connectivity reg	 *  (must do last)	 */	outl(ndp->csr13, 0x68);	for (i = 0; i < 3*8; i += 3) {		setupframe[i] = nd->hw_addr[0] | nd->hw_addr[1] << 8;		setupframe[i + 1] = nd->hw_addr[2] | nd->hw_addr[3] << 8;		setupframe[i + 2] = nd->hw_addr[4] | nd->hw_addr[5] << 8;	}	transdesc[0] = 0x80000000;	/* TDES0 - 21041 owns the descriptor */	transdesc[1] = 0x0b0000c0;	/* TDES1 - End of ring, chained 2nd desc, setup, size of frame */	transdesc[2] = virt_to_bus(setupframe); /* TDES2 - buffer 1 address */	transdesc[3] = virt_to_bus(transdesc); /* TDES3 - next descriptor is same descriptor */	outl(virt_to_bus(transdesc), 0x20);	/* CSR6 - operating mode	 *  kick the transmitter to process the setup frame	 *  Enable special capture mode, bit17 enable capture mode,	 *  large transmit threshold, enable transmit	 */	outl(ndp->csr6 | 0xe000, 0x30); 	while (transdesc[0] & 0x80000000);	/* RDES1 - end of ting, second address chained, sizeof buffer */	recvdesc[1] = 0x03000000 | RECVBUFFERSZ;	/* RDES2 - buffer address */	recvdesc[2] = virt_to_bus(ndp->recvbuffer);	/* RDES3 - next descriptor is same descriptor */	recvdesc[3] = virt_to_bus(recvdesc);	/* First/last descriptor, let 21041 own it */	recvdesc[0] = 0x80000300;	/* CSR3 - receive list base address reg	 */	outl(virt_to_bus(recvdesc), 0x18);	/* Stop transmitter and start receiver	 *   - As above, but no transmit enable, start receiver	 */	outl(ndp->csr6 | 0xc002, 0x30);	return 0;}static int nd_21041_close(struct netdev *nd){	return 0;}static int nd_21041_status(struct netdev *nd){	return 0;}static int nd_21041_send(struct netdev *nd, void *buffer, int size){	struct nd_21041_priv *ndp = nd->ptr1;	transdesc[0] = 0x80000000;	transdesc[1] = size | 0x63000000;	transdesc[2] = virt_to_bus(buffer);	transdesc[3] = virt_to_bus(transdesc);	/* CSR4 - transmit list base address	 */	outl(virt_to_bus(transdesc), 0x20);	/* CSR6 - operating mode	 *  setup operating mode and kick transmitter	 *  - enable special capture, bit17 enable capture mode,	 *    large transmit threshold, enable transmit	 */	outl(ndp->csr6 | 0xe002, 0x30);	/* Spin waiting for the end of the transmission	 */	while (transdesc[0] & 0x80000000);	/* CSR6 - operating mode	 *  stop the transmitter and start receiver	 */	outl(ndp->csr6 | 0xc002, 0x30);	return 0;}static int nd_21041_recv(struct netdev *nd, void *buf){	struct nd_21041_priv *ndp = nd->ptr1;	int len = 0;	switch (recvdesc[0] & 0x80008000) {	case 0:		len = (recvdesc[0] >> 16) & 0x7fff;		memcpy(buf, ndp->recvbuffer, len);	case 0x8000:	/* error */		/* RDES1 - end of ting, second address chained, sizeof buffer */		recvdesc[1] = 0x03000000 | RECVBUFFERSZ;		/* RDES2 - buffer address */		recvdesc[2] = virt_to_bus(ndp->recvbuffer);		/* RDES3 - next descriptor is same descriptor */		recvdesc[3] = virt_to_bus(recvdesc);		/* First/last descriptor, let 21041 own it */		recvdesc[0] = 0x80000300;		default:		break;	}	/* CSR6 - operating mode	 *  make sure that the receiver is running	 */	outl(ndp->csr6 | 0xc002, 0x30);	return len;}static const struct netdev_ops nd_21041_ops = {	nd_21041_probe,	nd_21041_open,	nd_21041_close,	nd_21041_status,	nd_21041_setmedia,	nd_21041_checkmedia,	nd_21041_send,	nd_21041_recv,};struct netdev net_dev_dec_21041 = {	&nd_21041_ops,	&eth_trans_ops,};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -