kernels/linux-2.4.0/drivers/net/tlan.c
/***************************************************************
	 *	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.
	 *
	 **************************************************************/
TLan_MiiReadReg
Returns:
0       if ack received ok
1       otherwise.

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.
TLan_MiiReadReg Returns : 0 if ack received ok 1 otherwise . 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 = (TLanPrivateInfo *) 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;
	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 );	
	TLan_MiiSendData( dev->base_addr, 0x2, 2 );	
	TLan_MiiSendData( dev->base_addr, phy, 5 );	
	TLan_MiiSendData( dev->base_addr, reg, 5 );	
	TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio);		
	TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);		
	TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
	TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);		
	nack = TLan_GetBit(TLAN_NET_SIO_MDATA, sio);	
	TLan_SetBit(TLAN_NET_SIO_MCLK, sio);		
	if (nack) {					
		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 {					
		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);		
	TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
	if ( minten )
		TLan_SetBit(TLAN_NET_SIO_MINTEN, sio);
	*val = tmp;
	spin_unlock_irqrestore(&priv->lock, flags);
	return err;
}
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 = ( TLanPrivateInfo * ) 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 ; 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 ) ; TLan_MiiSendData ( dev -> base_addr , 0x2 , 2 ) ; TLan_MiiSendData ( dev -> base_addr , phy , 5 ) ; TLan_MiiSendData ( dev -> base_addr , reg , 5 ) ; TLan_ClearBit ( TLAN_NET_SIO_MTXEN , sio ) ; TLan_ClearBit ( TLAN_NET_SIO_MCLK , sio ) ; TLan_SetBit ( TLAN_NET_SIO_MCLK , sio ) ; TLan_ClearBit ( TLAN_NET_SIO_MCLK , sio ) ; nack = TLan_GetBit ( TLAN_NET_SIO_MDATA , sio ) ; TLan_SetBit ( TLAN_NET_SIO_MCLK , sio ) ; if ( nack ) { 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 { 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 ) ; TLan_SetBit ( TLAN_NET_SIO_MCLK , sio ) ; if ( minten ) TLan_SetBit ( TLAN_NET_SIO_MINTEN , sio ) ; * val = tmp ; spin_unlock_irqrestore ( & priv -> lock , flags ) ; return err ; }
TLan_MiiReadReg
      Returns:
              0       if ack received ok
              1       otherwise.
TLan_MiiReadReg Returns : 0 if ack received ok 1 otherwise .
/* Start ( 01b ) */ /* Read  ( 10b ) */ /* Device #      */ /* Register #    */ /* Change direction */ /* Clock Idle bit */ /* Wait 300ns */ /* Check for ACK */ /* Finish ACK */ /* No ACK, so fake it */ /* ACK, so read data */ /* Idle cycle */