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

📄 tlan.c

📁 linux下从网卡远程启动
💻 C
📖 第 1 页 / 共 4 页
字号:
		if ((status & MII_GS_LINK) &&	/* We only support link info on Nat.Sem. PHY's */		    (tlphy_id1 == NAT_SEM_ID1)		    && (tlphy_id2 == NAT_SEM_ID2)) {			TLan_MiiReadReg(nic, phy, MII_AN_LPA, &partner);			TLan_MiiReadReg(nic, phy, TLAN_TLPHY_PAR,					&tlphy_par);			printf("TLAN: %s: Link active with ",			       priv->nic_name);			if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) {				printf("forced 10%sMbps %s-Duplex\n",				       tlphy_par & TLAN_PHY_SPEED_100 ? ""				       : "0",				       tlphy_par & TLAN_PHY_DUPLEX_FULL ?				       "Full" : "Half");			} else {				printf				    ("AutoNegotiation enabled, at 10%sMbps %s-Duplex\n",				     tlphy_par & TLAN_PHY_SPEED_100 ? "" :				     "0",				     tlphy_par & TLAN_PHY_DUPLEX_FULL ?				     "Full" : "Half");				printf("TLAN: Partner capability: ");				for (i = 5; i <= 10; i++)					if (partner & (1 << i))						printf("%s", media[i - 5]);				printf("\n");			}			TLan_DioWrite8(BASE, TLAN_LED_REG, TLAN_LED_LINK);#ifdef MONITOR			/* We have link beat..for now anyway */			priv->link = 1;			/*Enabling link beat monitoring */			/* TLan_SetTimer( nic, (10*HZ), TLAN_TIMER_LINK_BEAT ); */			mdelay(10000);			TLan_PhyMonitor(nic);#endif		} else if (status & MII_GS_LINK) {			printf("TLAN: %s: Link active\n", priv->nic_name);			TLan_DioWrite8(BASE, TLAN_LED_REG, TLAN_LED_LINK);		}	}	if (priv->phyNum == 0) {		TLan_MiiReadReg(nic, phy, TLAN_TLPHY_CTL, &tlphy_ctl);		tlphy_ctl |= TLAN_TC_INTEN;		TLan_MiiWriteReg(nic, phy, TLAN_TLPHY_CTL, tlphy_ctl);		sio = TLan_DioRead8(BASE, TLAN_NET_SIO);		sio |= TLAN_NET_SIO_MINTEN;		TLan_DioWrite8(BASE, TLAN_NET_SIO, sio);	}	if (status & MII_GS_LINK) {		TLan_SetMac(nic, 0, nic->node_addr);		priv->phyOnline = 1;		outb((TLAN_HC_INT_ON >> 8), BASE + TLAN_HOST_CMD + 1);/*		if ( debug >= 1 && debug != TLAN_DEBUG_PROBE ) {			outb( ( TLAN_HC_REQ_INT >> 8 ), BASE + TLAN_HOST_CMD + 1 );		}		*/		outl(virt_to_bus(&rx_ring), BASE + TLAN_CH_PARM);		outl(TLAN_HC_GO | TLAN_HC_RT, BASE + TLAN_HOST_CMD);	} else {		printf		    ("TLAN: %s: Link inactive, will retry in 10 secs...\n",		     priv->nic_name);		/* TLan_SetTimer( nic, (10*HZ), TLAN_TIMER_FINISH_RESET ); */		mdelay(10000);		TLan_FinishReset(nic);		return;	}}	/* TLan_FinishReset *//**************************************************************************POLL - Wait for a frame***************************************************************************/static int tlan_poll(struct nic *nic){	/* return true if there's an ethernet packet ready to read */	/* nic->packet should contain data on return */	/* nic->packetlen should contain length of data */	u32 framesize;	u32 host_cmd = 0;	u32 ack = 1;	int eoc = 0;	int entry = priv->cur_rx % TLAN_NUM_RX_LISTS;	u16 tmpCStat = le32_to_cpu(rx_ring[entry].cStat);		u16 host_int = inw(BASE + TLAN_HOST_INT);	outw(host_int, BASE + TLAN_HOST_INT);	if (!(tmpCStat & TLAN_CSTAT_FRM_CMP))		return 0;	/* printf("PI-1: 0x%hX\n", host_int); */	if (tmpCStat & TLAN_CSTAT_EOC)		eoc = 1;	framesize = rx_ring[entry].frameSize;	nic->packetlen = framesize;#ifdef EBDEBUG     printf(".%d.", framesize); #endif     	memcpy(nic->packet, rxb +	       (priv->cur_rx * TLAN_MAX_FRAME_SIZE), nic->packetlen);	rx_ring[entry].cStat = 0;#ifdef EBDEBUG	hex_dump(nic->packet, nic->packetlen);	printf("%d", entry);  #endif	entry = (entry + 1) % TLAN_NUM_RX_LISTS;	priv->cur_rx = entry;	if (eoc) {		if ((rx_ring[entry].cStat & TLAN_CSTAT_READY) ==		    TLAN_CSTAT_READY) {			ack |= TLAN_HC_GO | TLAN_HC_RT;			host_cmd = TLAN_HC_ACK | ack | 0x001C0000;			outl(host_cmd, BASE + TLAN_HOST_CMD);		}	} else {		host_cmd = TLAN_HC_ACK | ack | (0x000C0000);		outl(host_cmd, BASE + TLAN_HOST_CMD);#ifdef EBDEBUG		printf("AC: 0x%hX\n", inw(BASE + TLAN_CH_PARM)); 		host_int = inw(BASE + TLAN_HOST_INT);		printf("PI-2: 0x%hX\n", host_int); #endif	}	refill_rx(nic);	return (1);		/* initially as this is called to flush the input */}static void refill_rx(struct nic *nic __unused){	int entry = 0;	for (;	     (priv->cur_rx - priv->dirty_rx +	      TLAN_NUM_RX_LISTS) % TLAN_NUM_RX_LISTS > 0;	     priv->dirty_rx = (priv->dirty_rx + 1) % TLAN_NUM_RX_LISTS) {		entry = priv->dirty_rx % TLAN_NUM_TX_LISTS;		rx_ring[entry].frameSize = TLAN_MAX_FRAME_SIZE;		rx_ring[entry].cStat = TLAN_CSTAT_READY;	}}/* #define EBDEBUG *//**************************************************************************TRANSMIT - Transmit a frame***************************************************************************/static void tlan_transmit(struct nic *nic, const char *d,	/* Destination */			  unsigned int t,	/* Type */			  unsigned int s,	/* size */			  const char *p){				/* Packet */	u16 nstype;	u32 to;	struct TLanList *tail_list;	struct TLanList *head_list;	u8 *tail_buffer;	u32 ack = 0;	u32 host_cmd;	int eoc = 0;	u16 tmpCStat;#ifdef EBDEBUG	u16 host_int = inw(BASE + TLAN_HOST_INT);#endif	int entry = 0;#ifdef EBDEBUG	printf("INT0-0x%hX\n", host_int);#endif	if (!priv->phyOnline) {		printf("TRANSMIT:  %s PHY is not ready\n", priv->nic_name);		return;	}	tail_list = priv->txList + priv->txTail;	if (tail_list->cStat != TLAN_CSTAT_UNUSED) {		printf("TRANSMIT: %s is busy (Head=%d Tail=%d)\n",		       priv->nic_name, priv->txList, priv->txTail);		tx_ring[entry].cStat = TLAN_CSTAT_UNUSED;		priv->txBusyCount++;		return;	}	tail_list->forward = 0;	tail_buffer = txb + (priv->txTail * TLAN_MAX_FRAME_SIZE);	/* send the packet to destination */	memcpy(tail_buffer, d, ETH_ALEN);	memcpy(tail_buffer + ETH_ALEN, nic->node_addr, ETH_ALEN);	nstype = htons((u16) t);	memcpy(tail_buffer + 2 * ETH_ALEN, (u8 *) & nstype, 2);	memcpy(tail_buffer + ETH_HLEN, p, s);	s += ETH_HLEN;	s &= 0x0FFF;	while (s < ETH_ZLEN)		tail_buffer[s++] = '\0';	/*=====================================================*/	/* Receive	 * 0000 0000 0001 1100	 * 0000 0000 0000 1100	 * 0000 0000 0000 0011 = 0x0003	 *	 * 0000 0000 0000 0000 0000 0000 0000 0011	 * 0000 0000 0000 1100 0000 0000 0000 0000 = 0x000C0000	 *	 * Transmit	 * 0000 0000 0001 1100	 * 0000 0000 0000 0100	 * 0000 0000 0000 0001 = 0x0001	 *	 * 0000 0000 0000 0000 0000 0000 0000 0001	 * 0000 0000 0000 0100 0000 0000 0000 0000 = 0x00040000	 * */	/* Setup the transmit descriptor */	tail_list->frameSize = (u16) s;	tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) s;	tail_list->buffer[1].count = 0;	tail_list->buffer[1].address = 0;	tail_list->cStat = TLAN_CSTAT_READY;#ifdef EBDEBUG	host_int = inw(BASE + TLAN_HOST_INT);	printf("INT1-0x%hX\n", host_int);#endif	if (!priv->txInProgress) {		priv->txInProgress = 1;		outl(virt_to_le32desc(tail_list), BASE + TLAN_CH_PARM);		outl(TLAN_HC_GO, BASE + TLAN_HOST_CMD);	} else {		if (priv->txTail == 0) {#ifdef EBDEBUG			printf("Out buffer\n");#endif			(priv->txList + (TLAN_NUM_TX_LISTS - 1))->forward =			    virt_to_le32desc(tail_list);		} else {#ifdef EBDEBUG			printf("Fix this \n");#endif			(priv->txList + (priv->txTail - 1))->forward =			    virt_to_le32desc(tail_list);		}	}		CIRC_INC(priv->txTail, TLAN_NUM_TX_LISTS);#ifdef EBDEBUG	host_int = inw(BASE + TLAN_HOST_INT);	printf("INT2-0x%hX\n", host_int);#endif	to = currticks() + TX_TIME_OUT;	while ((tail_list->cStat == TLAN_CSTAT_READY) && currticks() < to);	head_list = priv->txList + priv->txHead;	while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) 			&& (ack < 255)) {		ack++;		if(tmpCStat & TLAN_CSTAT_EOC)			eoc =1;		head_list->cStat = TLAN_CSTAT_UNUSED;		CIRC_INC(priv->txHead, TLAN_NUM_TX_LISTS);		head_list = priv->txList + priv->txHead;			}	if(!ack)		printf("Incomplete TX Frame\n");	if(eoc) {		head_list = priv->txList + priv->txHead;		if ((head_list->cStat & TLAN_CSTAT_READY) == TLAN_CSTAT_READY) {			outl(virt_to_le32desc(head_list), BASE + TLAN_CH_PARM);			ack |= TLAN_HC_GO;		} else {			priv->txInProgress = 0;		}	}	if(ack) {		host_cmd = TLAN_HC_ACK | ack;		outl(host_cmd, BASE + TLAN_HOST_CMD);	}		if(priv->tlanRev < 0x30 ) {		ack = 1;		head_list = priv->txList + priv->txHead;		if ((head_list->cStat & TLAN_CSTAT_READY) == TLAN_CSTAT_READY) {			outl(virt_to_le32desc(head_list), BASE + TLAN_CH_PARM);			ack |= TLAN_HC_GO;		} else {			priv->txInProgress = 0;		}		host_cmd = TLAN_HC_ACK | ack | 0x00140000;		outl(host_cmd, BASE + TLAN_HOST_CMD);			}				if (currticks() >= to) {		printf("TX Time Out");	}}/**************************************************************************DISABLE - Turn off ethernet interface***************************************************************************/#ifdef EB51static void tlan_disable(struct dev *dev __unused)#elsestatic void tlan_disable(struct nic *nic __unused)#endif{	/* put the card in its initial state */	/* This function serves 3 purposes.	 * This disables DMA and interrupts so we don't receive	 *  unexpected packets or interrupts from the card after	 *  etherboot has finished.	 * This frees resources so etherboot may use	 *  this driver on another interface	 * This allows etherboot to reinitialize the interface	 *  if something is something goes wrong.	 *	 */	outl(TLAN_HC_AD_RST, BASE + TLAN_HOST_CMD);}static void TLan_SetMulticastList(struct nic *nic) {	int i;	u8 tmp;	/* !IFF_PROMISC */	tmp = TLan_DioRead8(BASE, TLAN_NET_CMD);	TLan_DioWrite8(BASE, TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF);	/* IFF_ALLMULTI */	for(i = 0; i< 3; i++)		TLan_SetMac(nic, i + 1, NULL);	TLan_DioWrite32(BASE, TLAN_HASH_1, 0xFFFFFFFF);	TLan_DioWrite32(BASE, TLAN_HASH_2, 0xFFFFFFFF);	}/**************************************************************************PROBE - Look for an adapter, this routine's visible to the outside***************************************************************************/#define board_found 1#define valid_link 0#ifdef EB51static int tlan_probe(struct dev *dev, struct pci_device *pci){	struct nic *nic = (struct nic *) dev;#elsestruct nic *tlan_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci){#endif		u16 data = 0;	int err;	int i;	if (pci->ioaddr == 0)		return 0;	BASE = pci->ioaddr;	printf("\n");	printf("tlan.c: %s, %s\n", drv_version, drv_date);	printf("%s: Probing for Vendor 0x%hX, Device 0x%hX",	       pci->name, pci->vendor, pci->dev_id);	/* I really must find out what this does */	adjust_pci_device(pci);	/* Point to private storage */	priv = &TLanPrivateInfo;	/* Figure out which chip we're dealing with */	i = 0;	chip_idx = -1;	while (tlan_pci_tbl[i].name) {		if ((((u32) pci->dev_id << 16) | pci->vendor) ==		    (tlan_pci_tbl[i].id.pci & 0xffffffff)) {			chip_idx = i;			break;		}		i++;	}	priv->vendor_id = pci->vendor;	priv->dev_id = pci->dev_id;	priv->nic_name = pci->name;	priv->eoc = 0;	err = 0;	for (i = 0; i < 6; i++)		err |= TLan_EeReadByte(BASE,				       (u8) tlan_pci_tbl[chip_idx].				       addrOfs + i,				       (u8 *) & nic->node_addr[i]);	if (err) {		printf("TLAN: %s: Error reading MAC from eeprom: %d\n",		       pci->name, err);	} else		printf("\nAddress: %!\n", nic->node_addr);	priv->tlanRev = TLan_DioRead8(BASE, TLAN_DEF_REVISION);	printf("\nRevision = 0x%hX\n", priv->tlanRev);	TLan_ResetLists(nic);	TLan_ResetAdapter(nic);/*	data = inl(BASE + TLAN_HOST_CMD);	data |= TLAN_HC_EOC;	outw(data, BASE + TLAN_HOST_CMD);*/	data = inl(BASE + TLAN_HOST_CMD);	data |= TLAN_HC_INT_OFF;	outw(data, BASE + TLAN_HOST_CMD);	TLan_SetMulticastList(nic);	udelay(100); 	priv->txList = tx_ring;	priv->rxList = rx_ring;/*	if (board_found && valid_link)	{*/	/* point to NIC specific routines */#ifdef EB51	dev->disable = tlan_disable;	nic->poll = tlan_poll;

⌨️ 快捷键说明

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