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

📄 cs89x0.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* disable interrupts and memory accesses */	writereg(PP_BusCTL, 0);	/* set the ethernet address */	for (i=0; i < ETH_ALEN/2; i++)		writereg(PP_IA+i*2,			 nic->node_addr[i*2] |			 (nic->node_addr[i*2+1] << 8));	/* receive only error free packets addressed to this card */	writereg(PP_RxCTL, DEF_RX_ACCEPT);	/* do not generate any interrupts on receive operations */	writereg(PP_RxCFG, 0);	/* do not generate any interrupts on transmit operations */	writereg(PP_TxCFG, 0);	/* do not generate any interrupts on buffer operations */	writereg(PP_BufCFG, 0);	/* reset address port, so that autoprobing will keep working */	outw(PP_ChipID, eth_nic_base + ADD_PORT);	return;}/**************************************************************************ETH_TRANSMIT - Transmit a frame***************************************************************************/static void cs89x0_transmit(	struct nic *nic,	const char *d,			/* Destination */	unsigned int t,			/* Type */	unsigned int s,			/* size */	const char *p)			/* Packet */{	unsigned long tmo;	int           sr;	/* does this size have to be rounded??? please,	   somebody have a look in the specs */	if ((sr = ((s + ETH_HLEN + 1)&~1)) < ETH_ZLEN)		sr = ETH_ZLEN;retry:	/* initiate a transmit sequence */	outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT);	outw(sr, eth_nic_base + TX_LEN_PORT);	/* Test to see if the chip has allocated memory for the packet */	if ((readreg(PP_BusST) & READY_FOR_TX_NOW) == 0) {		/* Oops... this should not happen! */		printf("cs: unable to send packet; retrying...\n");		for (tmo = currticks() + 5*TICKS_PER_SEC; currticks() < tmo; );		cs89x0_reset(nic);		goto retry; }	/* Write the contents of the packet */	outsw(eth_nic_base + TX_FRAME_PORT, d, ETH_ALEN/2);	outsw(eth_nic_base + TX_FRAME_PORT, nic->node_addr,	      ETH_ALEN/2);	outw(((t >> 8)&0xFF)|(t << 8), eth_nic_base + TX_FRAME_PORT);	outsw(eth_nic_base + TX_FRAME_PORT, p, (s+1)/2);	for (sr = sr/2 - (s+1)/2 - ETH_ALEN - 1; sr-- > 0;	     outw(0, eth_nic_base + TX_FRAME_PORT));	/* wait for transfer to succeed */	for (tmo = currticks()+5*TICKS_PER_SEC;	     (s = readreg(PP_TxEvent)&~0x1F) == 0 && currticks() < tmo;)		/* nothing */ ;	if ((s & TX_SEND_OK_BITS) != TX_OK) {		printf("\ntransmission error %#hX\n", s);	}	return;}/**************************************************************************ETH_POLL - Wait for a frame***************************************************************************/static int cs89x0_poll(struct nic *nic){	int status;	status = readreg(PP_RxEvent);	if ((status & RX_OK) == 0)		return(0);	status = inw(eth_nic_base + RX_FRAME_PORT);	nic->packetlen = inw(eth_nic_base + RX_FRAME_PORT);	insw(eth_nic_base + RX_FRAME_PORT, nic->packet, nic->packetlen >> 1);	if (nic->packetlen & 1)		nic->packet[nic->packetlen-1] = inw(eth_nic_base + RX_FRAME_PORT);	return 1;}static void cs89x0_disable(struct nic *nic){	cs89x0_reset(nic);}/**************************************************************************ETH_PROBE - Look for an adapter***************************************************************************/struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs){	static const unsigned int netcard_portlist[] = {#ifdef	CS_SCAN		CS_SCAN,#else	/* use "conservative" default values for autoprobing */		0x300,0x320,0x340,0x200,0x220,0x240,		0x260,0x280,0x2a0,0x2c0,0x2e0,	/* if that did not work, then be more aggressive */		0x301,0x321,0x341,0x201,0x221,0x241,		0x261,0x281,0x2a1,0x2c1,0x2e1,#endif		0};	int      i, result = -1;	unsigned rev_type = 0, ioaddr, ioidx, isa_cnf, cs_revision;	unsigned short eeprom_buff[CHKSUM_LEN];	for (ioidx = 0; (ioaddr=netcard_portlist[ioidx++]) != 0; ) {		/* if they give us an odd I/O address, then do ONE write to		   the address port, to get it back to address zero, where we		   expect to find the EISA signature word. */		if (ioaddr & 1) {			ioaddr &= ~1;			if ((inw(ioaddr + ADD_PORT) & ADD_MASK) != ADD_SIG)				continue;			outw(PP_ChipID, ioaddr + ADD_PORT);		}		if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG)			continue;		eth_nic_base = ioaddr;		/* get the chip type */		rev_type = readreg(PRODUCT_ID_ADD);		eth_cs_type = rev_type &~ REVISON_BITS;		cs_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';		printf("\ncs: cs89%c0%s rev %c, base %#hX",		       eth_cs_type==CS8900?'0':'2',		       eth_cs_type==CS8920M?"M":"",		       cs_revision,		       eth_nic_base);		/* First check to see if an EEPROM is attached*/		if ((readreg(PP_SelfST) & EEPROM_PRESENT) == 0) {			printf("\ncs: no EEPROM...\n");			outw(PP_ChipID, eth_nic_base + ADD_PORT);			continue; }		else if (get_eeprom_data(START_EEPROM_DATA,CHKSUM_LEN,					 eeprom_buff) < 0) {			printf("\ncs: EEPROM read failed...\n");			outw(PP_ChipID, eth_nic_base + ADD_PORT);			continue; }		else if (get_eeprom_chksum(START_EEPROM_DATA,CHKSUM_LEN,					   eeprom_buff) < 0) {			printf("\ncs: EEPROM checksum bad...\n");			outw(PP_ChipID, eth_nic_base + ADD_PORT);			continue; }		/* get transmission control word but keep the		   autonegotiation bits */		eth_auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2];		/* Store adapter configuration */		eth_adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2];		/* Store ISA configuration */		isa_cnf = eeprom_buff[ISA_CNF_OFFSET/2];		/* store the initial memory base address */		eth_mem_start = eeprom_buff[PACKET_PAGE_OFFSET/2] << 8;		printf("%s%s%s, addr ",		       (eth_adapter_cnf & A_CNF_10B_T)?", RJ-45":"",		       (eth_adapter_cnf & A_CNF_AUI)?", AUI":"",		       (eth_adapter_cnf & A_CNF_10B_2)?", BNC":"");		/* If this is a CS8900 then no pnp soft */		if (eth_cs_type != CS8900 &&		    /* Check if the ISA IRQ has been set  */		    (i = readreg(PP_CS8920_ISAINT) & 0xff,		     (i != 0 && i < CS8920_NO_INTS)))			eth_irq = i;		else {			i = isa_cnf & INT_NO_MASK;			if (eth_cs_type == CS8900) {				/* the table that follows is dependent				   upon how you wired up your cs8900				   in your system.  The table is the				   same as the cs8900 engineering demo				   board.  irq_map also depends on the				   contents of the table.  Also see				   write_irq, which is the reverse				   mapping of the table below. */				if (i < 4) i = "\012\013\014\005"[i];				else printf("\ncs: BUG: isa_config is %d\n", i); }			eth_irq = i; }		/* Retrieve and print the ethernet address. */		for (i=0; i<ETH_ALEN; i++) {			nic->node_addr[i] = ((unsigned char *)eeprom_buff)[i];		}		printf("%!\n", nic->node_addr);		/* Set the LineCTL quintuplet based on adapter		   configuration read from EEPROM */		if ((eth_adapter_cnf & A_CNF_EXTND_10B_2) &&		    (eth_adapter_cnf & A_CNF_LOW_RX_SQUELCH))			eth_linectl = LOW_RX_SQUELCH;		else			eth_linectl = 0;		/* check to make sure that they have the "right"		   hardware available */		switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) {		case A_CNF_MEDIA_10B_T: result = eth_adapter_cnf & A_CNF_10B_T;			break;		case A_CNF_MEDIA_AUI:   result = eth_adapter_cnf & A_CNF_AUI;			break;		case A_CNF_MEDIA_10B_2: result = eth_adapter_cnf & A_CNF_10B_2;			break;		default: result = eth_adapter_cnf & (A_CNF_10B_T | A_CNF_AUI |						     A_CNF_10B_2);		}		if (!result) {			printf("cs: EEPROM is configured for unavailable media\n");		error:			writereg(PP_LineCTL, readreg(PP_LineCTL) &				 ~(SERIAL_TX_ON | SERIAL_RX_ON));			outw(PP_ChipID, eth_nic_base + ADD_PORT);			continue;		}		/* Initialize the card for probing of the attached media */		cs89x0_reset(nic);		/* set the hardware to the configured choice */		switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) {		case A_CNF_MEDIA_10B_T:			result = detect_tp();			if (!result) {				clrline();				printf("10Base-T (RJ-45%s",				       ") has no cable\n"); }			/* check "ignore missing media" bit */			if (eth_auto_neg_cnf & IMM_BIT)				/* Yes! I don't care if I see a link pulse */				result = A_CNF_MEDIA_10B_T;			break;		case A_CNF_MEDIA_AUI:			result = detect_aui(nic);			if (!result) {				clrline();				printf("10Base-5 (AUI%s",				       ") has no cable\n"); }			/* check "ignore missing media" bit */			if (eth_auto_neg_cnf & IMM_BIT)				/* Yes! I don't care if I see a carrrier */				result = A_CNF_MEDIA_AUI;			break;		case A_CNF_MEDIA_10B_2:			result = detect_bnc(nic);			if (!result) {				clrline();				printf("10Base-2 (BNC%s",				       ") has no cable\n"); }			/* check "ignore missing media" bit */			if (eth_auto_neg_cnf & IMM_BIT)				/* Yes! I don't care if I can xmit a packet */				result = A_CNF_MEDIA_10B_2;			break;		case A_CNF_MEDIA_AUTO:			writereg(PP_LineCTL, eth_linectl | AUTO_AUI_10BASET);			if (eth_adapter_cnf & A_CNF_10B_T)				if ((result = detect_tp()) != 0)					break;			if (eth_adapter_cnf & A_CNF_AUI)				if ((result = detect_aui(nic)) != 0)					break;			if (eth_adapter_cnf & A_CNF_10B_2)				if ((result = detect_bnc(nic)) != 0)					break;			clrline(); printf("no media detected\n");			goto error;		}		clrline();		switch(result) {		case 0:                 printf("no network cable attached to configured media\n");			goto error;		case A_CNF_MEDIA_10B_T: printf("using 10Base-T (RJ-45)\n");			break;		case A_CNF_MEDIA_AUI:   printf("using 10Base-5 (AUI)\n");			break;		case A_CNF_MEDIA_10B_2: printf("using 10Base-2 (BNC)\n");			break;		}		/* Turn on both receive and transmit operations */		writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_RX_ON |			 SERIAL_TX_ON);		break;	}	if (ioaddr == 0)		return (0);	nic->reset = cs89x0_reset;	nic->poll = cs89x0_poll;	nic->transmit = cs89x0_transmit;	nic->disable = cs89x0_disable;	return (nic);}/* * Local variables: *  c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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