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

📄 tlan.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 5 页
字号:
				priv->tlanFullDuplex = TRUE;			}			if ( priv->speed == TLAN_SPEED_100 ) {				control |= MII_GC_SPEEDSEL;			}       			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, control );		}        	TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tctl );	}	/* Wait for 2 sec to give the tranceiver time	 * to establish link.	 */	TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET );} /* TLan_PhyStartLink */void TLan_PhyFinishAutoNeg( struct net_device *dev ){	TLanPrivateInfo	*priv = dev->priv;	u16		an_adv;	u16		an_lpa;	u16		data;	u16		mode;	u16		phy;	u16		status;		phy = priv->phy[priv->phyNum];	TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );	udelay( 1000 );	TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );	if ( ! ( status & MII_GS_AUTOCMPLT ) ) {		/* Wait for 8 sec to give the process		 * more time.  Perhaps we should fail after a while.		 */		 if (!priv->neg_be_verbose++) {			 printk(KERN_INFO "TLAN:  Giving autonegotiation more time.\n");		 	 printk(KERN_INFO "TLAN:  Please check that your adapter has\n");		 	 printk(KERN_INFO "TLAN:  been properly connected to a HUB or Switch.\n");			 printk(KERN_INFO "TLAN:  Trying to establish link in the background...\n");		 }		TLan_SetTimer( dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN );		return;	}	printk( "TLAN: %s: Autonegotiation complete.\n", dev->name );	TLan_MiiReadReg( dev, phy, MII_AN_ADV, &an_adv );	TLan_MiiReadReg( dev, phy, MII_AN_LPA, &an_lpa );	mode = an_adv & an_lpa & 0x03E0;	if ( mode & 0x0100 ) {		priv->tlanFullDuplex = TRUE;	} else if ( ! ( mode & 0x0080 ) && ( mode & 0x0040 ) ) {		priv->tlanFullDuplex = TRUE;	}	if ( ( ! ( mode & 0x0180 ) ) && ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) && ( priv->phyNum != 0 ) ) {		priv->phyNum = 0;		data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;		TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );		TLan_SetTimer( dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN );		return;	}	if ( priv->phyNum == 0 ) {		if ( ( priv->duplex == TLAN_DUPLEX_FULL ) || ( an_adv & an_lpa & 0x0040 ) ) {			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB | MII_GC_DUPLEX );			printk( "TLAN:  Starting internal PHY with FULL-DUPLEX\n" );		} else {			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB );			printk( "TLAN:  Starting internal PHY with HALF-DUPLEX\n" );		}	}	/* Wait for 100 ms.  No reason in partiticular.	 */	TLan_SetTimer( dev, (HZ/10), TLAN_TIMER_FINISH_RESET );		} /* TLan_PhyFinishAutoNeg */#ifdef MONITOR        /*********************************************************************        *        *      TLan_phyMonitor        *        *      Returns:         *              None        *        *      Params:        *              dev             The device structure of this device.        *        *              *      This function monitors PHY condition by reading the status        *      register via the MII bus. This can be used to give info        *      about link changes (up/down), and possible switch to alternate        *      media.        *        * ******************************************************************/void TLan_PhyMonitor( struct net_device *dev ){	TLanPrivateInfo *priv = dev->priv;	u16     phy;	u16     phy_status;	phy = priv->phy[priv->phyNum];        /* Get PHY status register */        TLan_MiiReadReg( dev, phy, MII_GEN_STS, &phy_status );        /* Check if link has been lost */        if (!(phy_status & MII_GS_LINK)) {  	       if (priv->link) {		      priv->link = 0;	              printk(KERN_DEBUG "TLAN: %s has lost link\n", dev->name);	              dev->flags &= ~IFF_RUNNING;		      TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );		      return;		}	}        /* Link restablished? */        if ((phy_status & MII_GS_LINK) && !priv->link) { 		priv->link = 1;        	printk(KERN_DEBUG "TLAN: %s has reestablished link\n", dev->name);        	dev->flags |= IFF_RUNNING;        }	/* Setup a new monitor */	TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );}	#endif /* MONITOR *//***********************************************************************************************************************************************************	ThunderLAN Driver MII Routines	These routines are based on the information in Chap. 2 of the	"ThunderLAN Programmer's Guide", pp. 15-24.***********************************************************************************************************************************************************/	/***************************************************************	 *	TLan_MiiReadReg	 *	 *	Returns:	 *		0	if ack received ok	 *		1	otherwise.	 *	 *	Parms:	 *		dev		The device structure containing	 *				The io address and interrupt count	 *				for this device.	 *		phy		The address of the PHY to be queried.	 *		reg		The register whose contents are to be	 *				retreived.	 *		val		A pointer to a variable to store the	 *				retrieved value.	 *	 *	This function uses the TLAN's MII bus to retreive the contents	 *	of a given register on a PHY.  It sends the appropriate info	 *	and then reads the 16-bit register value from the MII bus via	 *	the TLAN SIO register.	 *	 **************************************************************/int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val ){	u8	nack;	u16	sio, tmp; 	u32	i;	int	err;	int	minten;	TLanPrivateInfo *priv = dev->priv;	unsigned long flags = 0;	err = FALSE;	outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);	sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;		if (!in_irq())		spin_lock_irqsave(&priv->lock, flags);	TLan_MiiSync(dev->base_addr);	minten = TLan_GetBit( TLAN_NET_SIO_MINTEN, sio );	if ( minten )		TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio);	TLan_MiiSendData( dev->base_addr, 0x1, 2 );	/* Start ( 01b ) */	TLan_MiiSendData( dev->base_addr, 0x2, 2 );	/* Read  ( 10b ) */	TLan_MiiSendData( dev->base_addr, phy, 5 );	/* Device #      */	TLan_MiiSendData( dev->base_addr, reg, 5 );	/* Register #    */	TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio);		/* Change direction */	TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);		/* Clock Idle bit */	TLan_SetBit(TLAN_NET_SIO_MCLK, sio);	TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);		/* Wait 300ns */	nack = TLan_GetBit(TLAN_NET_SIO_MDATA, sio);	/* Check for ACK */	TLan_SetBit(TLAN_NET_SIO_MCLK, sio);		/* Finish ACK */	if (nack) {					/* No ACK, so fake it */		for (i = 0; i < 16; i++) {			TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);			TLan_SetBit(TLAN_NET_SIO_MCLK, sio);		}		tmp = 0xffff;		err = TRUE;	} else {					/* ACK, so read data */		for (tmp = 0, i = 0x8000; i; i >>= 1) {			TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);			if (TLan_GetBit(TLAN_NET_SIO_MDATA, sio))				tmp |= i;			TLan_SetBit(TLAN_NET_SIO_MCLK, sio);		}	}	TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);		/* Idle cycle */	TLan_SetBit(TLAN_NET_SIO_MCLK, sio);	if ( minten )		TLan_SetBit(TLAN_NET_SIO_MINTEN, sio);	*val = tmp;		if (!in_irq())		spin_unlock_irqrestore(&priv->lock, flags);	return err;} /* TLan_MiiReadReg */	/***************************************************************	 *	TLan_MiiSendData	 *	 *	Returns:	 *		Nothing	 *	Parms:	 *		base_port	The base IO port of the adapter	in	 *				question.	 *		dev		The address of the PHY to be queried.	 *		data		The value to be placed on the MII bus.	 *		num_bits	The number of bits in data that are to	 *				be placed on the MII bus.	 *	 *	This function sends on sequence of bits on the MII	 *	configuration bus.	 *	 **************************************************************/void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits ){	u16 sio;	u32 i;	if ( num_bits == 0 )		return;	outw( TLAN_NET_SIO, base_port + TLAN_DIO_ADR );	sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;	TLan_SetBit( TLAN_NET_SIO_MTXEN, sio );	for ( i = ( 0x1 << ( num_bits - 1 ) ); i; i >>= 1 ) {		TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );		(void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio );		if ( data & i )			TLan_SetBit( TLAN_NET_SIO_MDATA, sio );		else			TLan_ClearBit( TLAN_NET_SIO_MDATA, sio );		TLan_SetBit( TLAN_NET_SIO_MCLK, sio );		(void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio );	}} /* TLan_MiiSendData */	/***************************************************************	 *	TLan_MiiSync	 *	 *	Returns:	 *		Nothing	 *	Parms:	 *		base_port	The base IO port of the adapter in	 *				question.	 *	 *	This functions syncs all PHYs in terms of the MII configuration	 *	bus.	 *	 **************************************************************/void TLan_MiiSync( u16 base_port ){	int i;	u16 sio;	outw( TLAN_NET_SIO, base_port + TLAN_DIO_ADR );	sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;	TLan_ClearBit( TLAN_NET_SIO_MTXEN, sio );	for ( i = 0; i < 32; i++ ) {		TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );		TLan_SetBit( TLAN_NET_SIO_MCLK, sio );	}} /* TLan_MiiSync */	/***************************************************************	 *	TLan_MiiWriteReg	 *	 *	Returns:	 *		Nothing	 *	Parms:	 *		dev		The device structure for the device	 *				to write to.	 *		phy		The address of the PHY to be written to.	 *		reg		The register whose contents are to be	 *				written.	 *		val		The value to be written to the register.	 *	 *	This function uses the TLAN's MII bus to write the contents of a	 *	given register on a PHY.  It sends the appropriate info and then	 *	writes the 16-bit register value from the MII configuration bus	 *	via the TLAN SIO register.	 *	 **************************************************************/void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val ){	u16	sio;	int	minten;	unsigned long flags = 0;	TLanPrivateInfo *priv = dev->priv;	outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);	sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;		if (!in_irq())		spin_lock_irqsave(&priv->lock, flags);	TLan_MiiSync( dev->base_addr );	minten = TLan_GetBit( TLAN_NET_SIO_MINTEN, sio );	if ( minten )		TLan_ClearBit( TLAN_NET_SIO_MINTEN, sio );	TLan_MiiSendData( dev->base_addr, 0x1, 2 );	/* Start ( 01b ) */	TLan_MiiSendData( dev->base_addr, 0x1, 2 );	/* Write ( 01b ) */	TLan_MiiSendData( dev->base_addr, phy, 5 );	/* Device #      */	TLan_MiiSendData( dev->base_addr, reg, 5 );	/* Register #    */	TLan_MiiSendData( dev->base_addr, 0x2, 2 );	/* Send ACK */	TLan_MiiSendData( dev->base_addr, val, 16 );	/* Send Data */	TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );	/* Idle cycle */	TLan_SetBit( TLAN_NET_SIO_MCLK, sio );	if ( minten )		TLan_SetBit( TLAN_NET_SIO_MINTEN, sio );		if (!in_irq())		spin_unlock_irqrestore(&priv->lock, flags);} /* TLan_MiiWriteReg */#endif/**************************************************************************RESET - Reset adapter***************************************************************************/static void skel_reset(struct nic *nic){	/* put the card in its initial state */}/**************************************************************************POLL - Wait for a frame***************************************************************************/static int skel_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 */	return (0);	/* initially as this is called to flush the input */}/**************************************************************************TRANSMIT - Transmit a frame***************************************************************************/static void skel_transmit(	struct nic *nic,	const char *d,			/* Destination */	unsigned int t,			/* Type */	unsigned int s,			/* size */	const char *p)			/* Packet */{	/* send the packet to destination */}/**************************************************************************DISABLE - Turn off ethernet interface***************************************************************************/static void skel_disable(struct nic *nic){}/**************************************************************************PROBE - Look for an adapter, this routine's visible to the outsideYou should omit the last argument struct pci_device * for a non-PCI NIC***************************************************************************/struct nic *tlan_probe(struct nic *nic, unsigned short *probe_addrs,	struct pci_device *p)

⌨️ 快捷键说明

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