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

📄 3c509.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************ETHERBOOT -  BOOTP/TFTP Bootstrap ProgramAuthor: Martin Renters.  Date: Mar 22 1995 This code is based heavily on David Greenman's if_ed.c driver and  Andres Vega Garcia's if_ep.c driver. Copyright (C) 1993-1994, David Greenman, Martin Renters. Copyright (C) 1993-1995, Andres Vega Garcia. Copyright (C) 1995, Serge Babkin.  This software may be used, modified, copied, distributed, and sold, in  both source and binary form provided that the above copyright and these  terms are retained. Under no circumstances are the authors responsible for  the proper functioning of this software, nor do the authors assume any  responsibility for damages incurred with its use.3c509 support added by Serge Babkin (babkin@hq.icb.chel.su)$Id: 3c509.c,v 1.4 2002/01/02 21:56:40 okuji Exp $***************************************************************************//* #define EDEBUG */#include "etherboot.h"#include "nic.h"#include "cards.h"#include "timer.h"#include "3c509.h"#define	udelay(n)	waiton_timer2(((n)*TICKS_PER_MS)/1000)static unsigned short	eth_nic_base;static enum { none, bnc, utp } connector = none;	/* for 3C509 */#ifdef	INCLUDE_3C529/* * This table and several other pieces of the MCA support * code were shamelessly borrowed from the Linux kernel source. * * MCA support added by Adam Fritzler (mid@auk.cx) * */struct el3_mca_adapters_struct {        const char *name;        int id;};static struct el3_mca_adapters_struct el3_mca_adapters[] = {        { "3Com 3c529 EtherLink III (10base2)", 0x627c },        { "3Com 3c529 EtherLink III (10baseT)", 0x627d },        { "3Com 3c529 EtherLink III (test mode)", 0x62db },        { "3Com 3c529 EtherLink III (TP or coax)", 0x62f6 },        { "3Com 3c529 EtherLink III (TP)", 0x62f7 },        { NULL, 0 },};#endif/**************************************************************************ETH_RESET - Reset adapter***************************************************************************/static void t509_reset(struct nic *nic){	int i;	/***********************************************************			Reset 3Com 509 card	*************************************************************/	/* stop card */	outw(RX_DISABLE, BASE + EP_COMMAND);	outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);	while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)		;	outw(TX_DISABLE, BASE + EP_COMMAND);	outw(STOP_TRANSCEIVER, BASE + EP_COMMAND);	udelay(1000);	outw(RX_RESET, BASE + EP_COMMAND);	outw(TX_RESET, BASE + EP_COMMAND);	outw(C_INTR_LATCH, BASE + EP_COMMAND);	outw(SET_RD_0_MASK, BASE + EP_COMMAND);	outw(SET_INTR_MASK, BASE + EP_COMMAND);	outw(SET_RX_FILTER, BASE + EP_COMMAND);	/*	* initialize card	*/	while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)		;	GO_WINDOW(0);	/* Disable the card */	outw(0, BASE + EP_W0_CONFIG_CTRL);	/* Configure IRQ to none */	outw(SET_IRQ(0), BASE + EP_W0_RESOURCE_CFG);	/* Enable the card */	outw(ENABLE_DRQ_IRQ, BASE + EP_W0_CONFIG_CTRL);	GO_WINDOW(2);	/* Reload the ether_addr. */	for (i = 0; i < ETH_ALEN; i++)		outb(nic->node_addr[i], BASE + EP_W2_ADDR_0 + i);	outw(RX_RESET, BASE + EP_COMMAND);	outw(TX_RESET, BASE + EP_COMMAND);	/* Window 1 is operating window */	GO_WINDOW(1);	for (i = 0; i < 31; i++)		inb(BASE + EP_W1_TX_STATUS);	/* get rid of stray intr's */	outw(ACK_INTR | 0xff, BASE + EP_COMMAND);	outw(SET_RD_0_MASK | S_5_INTS, BASE + EP_COMMAND);	outw(SET_INTR_MASK, BASE + EP_COMMAND);	outw(SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST, BASE + EP_COMMAND);	/* configure BNC */	if (connector == bnc) {		outw(START_TRANSCEIVER, BASE + EP_COMMAND);		udelay(1000);	}	/* configure UTP */	else if (connector == utp) {		GO_WINDOW(4);		outw(ENABLE_UTP, BASE + EP_W4_MEDIA_TYPE);		sleep(2);	/* Give time for media to negotiate */		GO_WINDOW(1);	}	/* start transceiver and receiver */	outw(RX_ENABLE, BASE + EP_COMMAND);	outw(TX_ENABLE, BASE + EP_COMMAND);	/* set early threshold for minimal packet length */	outw(SET_RX_EARLY_THRESH | ETH_ZLEN, BASE + EP_COMMAND);	outw(SET_TX_START_THRESH | 16, BASE + EP_COMMAND);}/**************************************************************************ETH_TRANSMIT - Transmit a frame***************************************************************************/static char padmap[] = {	0, 3, 2, 1};static void t509_transmit(struct nic *nic,const char *d,			/* Destination */unsigned int t,			/* Type */unsigned int s,			/* size */const char *p)			/* Packet */{	register unsigned int len;	int pad;	int status;#ifdef	EDEBUG	printf("{l=%d,t=%hX}",s+ETH_HLEN,t);#endif	/* swap bytes of type */	t= htons(t);	len=s+ETH_HLEN; /* actual length of packet */	pad = padmap[len & 3];	/*	* The 3c509 automatically pads short packets to minimum ethernet length,	* but we drop packets that are too large. Perhaps we should truncate	* them instead?	*/	if (len + pad > ETH_FRAME_LEN) {		return;	}	/* drop acknowledgements */	while ((status=inb(BASE + EP_W1_TX_STATUS)) & TXS_COMPLETE ) {		if (status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {			outw(TX_RESET, BASE + EP_COMMAND);			outw(TX_ENABLE, BASE + EP_COMMAND);		}		outb(0x0, BASE + EP_W1_TX_STATUS);	}	while (inw(BASE + EP_W1_FREE_TX) < (unsigned short)len + pad + 4)		; /* no room in FIFO */	outw(len, BASE + EP_W1_TX_PIO_WR_1);	outw(0x0, BASE + EP_W1_TX_PIO_WR_1);	/* Second dword meaningless */	/* write packet */	outsw(BASE + EP_W1_TX_PIO_WR_1, d, ETH_ALEN/2);	outsw(BASE + EP_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2);	outw(t, BASE + EP_W1_TX_PIO_WR_1);	outsw(BASE + EP_W1_TX_PIO_WR_1, p, s / 2);	if (s & 1)		outb(*(p+s - 1), BASE + EP_W1_TX_PIO_WR_1);	while (pad--)		outb(0, BASE + EP_W1_TX_PIO_WR_1);	/* Padding */	/* wait for Tx complete */	while((inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS) != 0)		;}/**************************************************************************ETH_POLL - Wait for a frame***************************************************************************/static int t509_poll(struct nic *nic){	/* common variables */	unsigned short type = 0;	/* used by EDEBUG */	/* variables for 3C509 */	short status, cst;	register short rx_fifo;	cst=inw(BASE + EP_STATUS);#ifdef	EDEBUG	if(cst & 0x1FFF)		printf("-%hX-",cst);#endif	if( (cst & S_RX_COMPLETE)==0 ) {		/* acknowledge  everything */		outw(ACK_INTR| (cst & S_5_INTS), BASE + EP_COMMAND);		outw(C_INTR_LATCH, BASE + EP_COMMAND);		return 0;	}	status = inw(BASE + EP_W1_RX_STATUS);#ifdef	EDEBUG	printf("*%hX*",status);#endif	if (status & ERR_RX) {		outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);		return 0;	}	rx_fifo = status & RX_BYTES_MASK;	if (rx_fifo==0)		return 0;		/* read packet */#ifdef	EDEBUG	printf("[l=%d",rx_fifo);#endif	insw(BASE + EP_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2);	if(rx_fifo & 1)		nic->packet[rx_fifo-1]=inb(BASE + EP_W1_RX_PIO_RD_1);	nic->packetlen=rx_fifo;	while(1) {		status = inw(BASE + EP_W1_RX_STATUS);#ifdef	EDEBUG		printf("*%hX*",status);#endif		rx_fifo = status & RX_BYTES_MASK;		if(rx_fifo>0) {			insw(BASE + EP_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2);			if(rx_fifo & 1)				nic->packet[nic->packetlen+rx_fifo-1]=inb(BASE + EP_W1_RX_PIO_RD_1);			nic->packetlen+=rx_fifo;#ifdef	EDEBUG			printf("+%d",rx_fifo);#endif		}		if(( status & RX_INCOMPLETE )==0) {#ifdef	EDEBUG			printf("=%d",nic->packetlen);#endif			break;		}		udelay(1000);	/* if incomplete wait 1 ms */	}	/* acknowledge reception of packet */	outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);	while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)		;#ifdef	EDEBUG	type = (nic->packet[12]<<8) | nic->packet[13];	if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+	    nic->packet[5] == 0xFF*ETH_ALEN)		printf(",t=%hX,b]",type);	else		printf(",t=%hX]",type);#endif	return (1);}/*************************************************************************	3Com 509 - specific routines**************************************************************************/static inteeprom_rdy(void){	int i;	for (i = 0; is_eeprom_busy(IS_BASE) && i < MAX_EEPROMBUSY; i++);

⌨️ 快捷键说明

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