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

📄 rtl8150.c

📁 linux的网卡实用驱动及应用源码rtl8150
💻 C
📖 第 1 页 / 共 3 页
字号:
	rtl8150->dr.requesttype = RTL8150_REQT_WRITE;
	rtl8150->dr.request = RTL8150_REQ_SET_REG;
	rtl8150->dr.value = cpu_to_le16p( &indx );
	rtl8150->dr.index = 0;
	rtl8150->dr.length = rtl8150->ctrl_urb.transfer_buffer_length = cpu_to_le16p( &size );

	FILL_CONTROL_URB( &rtl8150->ctrl_urb, rtl8150->usb,
			  usb_sndctrlpipe(rtl8150->usb,0),
			  (char *)&rtl8150->dr,
			  data, size, set_registers_callback, rtl8150 );

	if ( (ret = usb_submit_urb( &rtl8150->ctrl_urb )) ) {
		info( " set_registers: usb_submit_urb failed" );
		err( __FUNCTION__ " BAD CTRL %d", ret);
		return	ret;
	}
	rtl8150->flags |= CTRL_URB_SLEEP;
	/// marked by Owen on 01/11/2001
	//interruptible_sleep_on( &rtl8150->ctrl_wait );
	
	///info( "-set_registers()<=====" );

	return	ret;
}



static int read_phy_word( rtl8150_t *rtl8150, __u8 phy, __u8 indx, __u16 *regd )
{
	int	i;
	__u8	MiiPhyAccessContent;

	/*
	set_register( rtl8150, MiiPhyAccess, 0 );
	set_register( rtl8150, MiiPhyAddr, phy );
	set_register( rtl8150, MiiPhyAccess, (0x40 | indx) );
	for (i = 0; i < REG_TIMEOUT; i++) 
	{
		get_registers( rtl8150, MiiPhyAccess, 1, &MiiPhyAccessContent );
		if ( (MiiPhyAccessContent & 0x40) == 0)
			break;
	}
	if ( i < REG_TIMEOUT ) 
	{
		get_registers( rtl8150, MiiPhyData, 2, regd );
		return	0;
	}
	warn( __FUNCTION__ " failed" );
	*/
	
	return 1;
}



static int write_phy_word( rtl8150_t *rtl8150, __u8 phy, __u8 indx, __u16 regd )
{
	int	i;
	__u8	data[2] = { 0, 0 };
	__u8	MiiPhyAccessContent;
	
	//info( "write_phy_word() =====>" );

	/*
	*data = cpu_to_le16p( &regd );
	set_register( rtl8150, MiiPhyAccess, 0 );
	set_register( rtl8150, MiiPhyAddr, phy );
	set_registers( rtl8150, MiiPhyData, 2, data );
	set_register( rtl8150, MiiPhyAccess, (0x60 | indx) );
	for (i = 0; i < REG_TIMEOUT; i++) 
	{
		get_registers( rtl8150, MiiPhyAccess, 1, &MiiPhyAccessContent );
		if ( (MiiPhyAccessContent & 0x40) == 0)
			break;
	}

	if ( i < REG_TIMEOUT )
		return	0;
	
	warn( __FUNCTION__ " failed" );
	*/

	return 1;
}



static int read_eprom_word( rtl8150_t *rtl8150, __u8 index, __u16 *retdata )
{
	int	i, tmp;

	//info( "+read_eprom_word() =====>" );

	while( rtl8150->get_registers_flag == 1 )
		;
	rtl8150->get_registers_flag = 1;
	get_registers( rtl8150, index, 2, retdata );
	while( rtl8150->get_registers_flag == 1 )
		;
	
	//info( "-read_eprom_word() <=====" );
	return	0;
}



static int read_eprom_byte( rtl8150_t *rtl8150, __u16 index, __u8 *retdata )
{
	int	i, tmp;

	//info( "+read_eprom_byte() =====>" );

	while( rtl8150->get_registers_flag == 1 )
		;
	rtl8150->get_registers_flag = 1;
	get_registers( rtl8150,  index, 1, retdata );
	while( rtl8150->get_registers_flag == 1 )
		;
	
	//info( "-read_eprom_byte() <=====");

	return 0;
}

#ifdef	RTL8150_WRITE_EEPROM
static inline void enable_eprom_write( rtl8150_t *rtl8150 )
{
	__u8	tmp;

	//info( "+enable_eprom_write() =====>" );

	//info( "-enable_eprom_write() <=====" );
}


static inline void disable_eprom_write( rtl8150_t *rtl8150 )
{
	__u8 	tmp;

	//info( "+disable_eprom_write() =====>" );
	
	//info( "-disable_eprom_write() <=====" );
}


static int write_eprom_word( rtl8150_t *rtl8150, __u8 index, __u16 data )
{
	int	i, tmp;
	__u8	d[4] = {0x3f, 0, 0, EPROM_WRITE};

	//info( "+write_eprom_word() =====>" );

	/*
	set_registers( rtl8150, EpromOffset, 4, d );
	enable_eprom_write( rtl8150 );
	set_register( rtl8150, EpromOffset, index );
	set_registers( rtl8150, EpromData, 2, &data );
	set_register( rtl8150, EpromCtrl, EPROM_WRITE );

	for ( i=0; i < REG_TIMEOUT; i++ ) {
		get_registers( rtl8150, EpromCtrl, 1, &tmp );
		if ( tmp & EPROM_DONE )
			break;
	}
	disable_eprom_write( rtl8150 );
	if ( i < REG_TIMEOUT )
		return	0;
	warn( __FUNCTION__ " failed" );
	*/
	//info( "-write_eprom_word <=====");
	return	-1;
}
#endif	/* RTL8150_WRITE_EEPROM */


static inline void get_node_id( rtl8150_t *rtl8150, __u8 *id )
{
	int	i;

	info( "+get_node_id() =====>" );
	for (i=0; i < 6; i++)
	{
		while( rtl8150->get_registers_flag == 1 )
			;
		rtl8150->get_registers_flag = 1;
		get_registers( rtl8150, IDR0+i, 1, &id[i] );
		while( rtl8150->get_registers_flag == 1 )
			;
	}
	info( "-get_node_id() <=====" );
}


static void set_ethernet_addr( rtl8150_t *rtl8150 )
{
	__u8	node_id[6];

	info( "+set_ethernet_addr() =====>" );
	get_node_id(rtl8150, node_id);
	memcpy( rtl8150->net->dev_addr, node_id, sizeof(node_id) );
	info( " set_ethernet_addr: node id = %x %x %x %x %x %x",
		node_id[0], node_id[1], node_id[2], node_id[3], node_id[4], node_id[5] );
	info( "-set_ethernet_addr() <======" );
}


static inline int reset_mac( rtl8150_t *rtl8150 )
{
	__u8	data = 0;
	int	i;

	info( "+reset_mac() =====>" );
	/// software reset
	data = SOFT_RST;

	///info( " reset_mac: before set_register(rtl8150, Command, data)" );
	while( rtl8150->set_registers_flag == 1 )
		;
	rtl8150->set_registers_flag = 1;
	set_registers(rtl8150, Command, 1, &data);
	while( rtl8150->set_registers_flag == 1 )
		;
	
	///info( " reset_mac: after set_register( rtl8150, Command, data)" );
	for (i = 0; i < REG_TIMEOUT; i++)
	{
		while( rtl8150->get_registers_flag == 1 )
			;
		rtl8150->get_registers_flag = 1;
		get_registers(rtl8150, Command, 1, &data);
		while( rtl8150->get_registers_flag == 1 )
			;
		if ( ~(data & SOFT_RST) )
		{
			break;
		}
	}
	if ( i == REG_TIMEOUT )
	{
		info( " reset_mac: software reset failed" );
		return 1;
	}
	
	info( "-reset_mac() <=====" );
	return	0;
}


static int enable_net_traffic( struct net_device *dev, struct usb_device *usb )
{
	__u16	linkpart, bmsr;
	__u8	data[4];
	__u8	byte_tmp = 0;
	rtl8150_t *rtl8150 = dev->priv;
	__u16  	rx_config_content;

	info("+enable_net_traffic() =====>");
	
	/// check if link okay!
	while( rtl8150->get_registers_flag == 1 )
		;
	rtl8150->get_registers_flag = 1;
	get_registers( rtl8150, MediaStst, 1, &byte_tmp );
	while( rtl8150->get_registers_flag == 1 )
		;
	info(" enable_net_traffic: MediaStst = 0x%x", byte_tmp);
	if ( byte_tmp & LINK )
		info(" enable_net_traffic: LINK ON");
	else
		info(" enable_net_traffic: LINK OFF");

	
	/// software reset
	/// byte_tmp = SOFT_RST;
	///set_register( rtl8150, Command, 1, &byte_tmp );
	
	/// set Transmit Configuration Register
	///info(" enable_net_traffic: before setting Tx Config");
	while( rtl8150->set_registers_flag == 1 )
		;
	rtl8150->set_registers_flag = 1;
	byte_tmp = TXRR1 | TXRR0 | IFG1 | IFG0;
	set_registers( rtl8150, TxConfig, 1, &byte_tmp);
	while( rtl8150->set_registers_flag == 1)
		;
	///while( rtl8150->get_registers_flag == 1 )
	///	;
	///rtl8150->get_registers_flag = 1;
	///get_registers( rtl8150, TxConfig, 1, &byte_tmp );
	///while( rtl8150->get_registers_flag == 1 )
	///	;
	///info( "enable_net_traffic: TxConfig = 0x%x", byte_tmp );
	///info(" enable_net_traffic: after setting Tx Config");

	/// set Receive Configuration Register
	///info(" enable_net_traffic: before setting Rx Config");
	while( rtl8150->set_registers_flag == 1 )
		;
	rtl8150->set_registers_flag = 1;
	rx_config_content = AM | AB | AD | AAM;
	set_registers( rtl8150, RxConfig, 2, &rx_config_content );
	while( rtl8150->set_registers_flag == 1 )
		;
	///info(" enable_net_traffic: after setting Rx Config");

	/// enable Tx and Rx
	///info(" enable_net_traffic: before enabling Tx and Rx" );
	while( rtl8150->set_registers_flag == 1 )
		;
	rtl8150->set_registers_flag = 1;
	byte_tmp = RE | TE;
	set_registers( rtl8150, Command, 1, &byte_tmp );
	while( rtl8150->set_registers_flag == 1 )
		;
	///info(" enable_net_traffic: after enabling Tx and Rx" );
	
	///while( rtl8150->get_registers_flag == 1 )
	///	;
	///rtl8150->get_registers_flag = 1;
	///get_register( rtl8150, Command, &byte_tmp);
	///while( rtl8150->get_registers_flag == 1 )
	///	;
	///info(" enable_net_traffic: Command = 0x%x", byte_tmp );

	info( "-enable_net_traffic() <=====");
	return 0;
}


static void read_bulk_callback( struct urb *urb )
{
	rtl8150_t *rtl8150 = urb->context;
	struct net_device *net;
	int count = urb->actual_length, res;
	int rx_status;
	struct sk_buff	*skb;
	__u16 pkt_len;

	//info( "+read_bulk_callback() =====>" );

	if ( !rtl8150 || !(rtl8150->flags & RTL8150_RUNNING) )
		return;

	net = rtl8150->net;
	if ( !netif_device_present(net) )
		return;

	if ( rtl8150->flags & RTL8150_RX_BUSY ) 
	{
		rtl8150->stats.rx_errors++;
		return;
	}
	rtl8150->flags |= RTL8150_RX_BUSY;

	switch ( urb->status ) {
		case USB_ST_NOERROR:
			break;
		case USB_ST_NORESPONSE:
			info( " read_bulk_callback: NO RESPONSE" );
			dbg( "reset MAC" );
			rtl8150->flags &= ~RTL8150_RX_BUSY;
			break;
		default:
			info( " read_bulk_callback: Rx status = 0x%x", urb->status);
			dbg( "%s: RX status %d", net->name, urb->status );
			goto goon;
	}
	
	pkt_len = count - 4;
	//info(" read_bulk_callback: packet length = 0x%x", pkt_len );
	//info(" read_bulk_callback: packet = %x %x %x %x %x %x %x %x %x %x %x %x", rtl8150->rx_buff[0], rtl8150->rx_buff[1],
	//	rtl8150->rx_buff[2], rtl8150->rx_buff[3], rtl8150->rx_buff[4], rtl8150->rx_buff[5],
	//	rtl8150->rx_buff[6], rtl8150->rx_buff[7], rtl8150->rx_buff[8], rtl8150->rx_buff[9],
	//	rtl8150->rx_buff[10], rtl8150->rx_buff[11] );

	if ( !(skb = dev_alloc_skb(pkt_len+2)) )   /// why "pkt_len + 2" 
		goto goon;

	skb->dev = net;
	skb_reserve(skb, 2);
	
	eth_copy_and_sum(skb, rtl8150->rx_buff, pkt_len, 0);
	skb_put(skb, pkt_len);
	/// in "Linux Device Drivers", the two statements above should be 
	///	"memcpy( skb_put( skb, pkt_len), rtl8150->rx_buff, pkt_len );"


	skb->protocol = eth_type_trans(skb, net);
	netif_rx(skb);	/// call this system call to transfer the "skb" to the upper layer
	rtl8150->stats.rx_packets++;
	rtl8150->stats.rx_bytes += pkt_len;

goon:
	FILL_BULK_URB( &rtl8150->rx_urb, rtl8150->usb,
			usb_rcvbulkpipe(rtl8150->usb, 1),
			rtl8150->rx_buff, RTL8150_MAX_MTU, 
			read_bulk_callback, rtl8150 );
	if ( (res = usb_submit_urb(&rtl8150->rx_urb)) )
	{
		info( " read_bulk_callback: usb_submit_urb failed" );
		warn( __FUNCTION__ " failed submint rx_urb %d", res);
	}
	rtl8150->flags &= ~RTL8150_RX_BUSY;
	
	//info( "-read_bulk_callback() <=====");
}


static void write_bulk_callback( struct urb *urb )
{
	rtl8150_t *rtl8150 = urb->context;

	///info( "+write_bulk_callback() =====>" );

	if ( !rtl8150 || !(rtl8150->flags & RTL8150_RUNNING) )
		return;

	if ( !netif_device_present(rtl8150->net) )
		return;
		
	if ( urb->status )
		info("%s: TX status %d", rtl8150->net->name, urb->status);

	netif_wake_queue( rtl8150->net );
	///info( "-write_bulk_callback() <=====" );
}



#ifdef	RTL8150_USE_INTR
static void intr_callback( struct urb *urb )
{
	rtl8150_t *rtl8150 = urb->context;
	struct net_device *net;
	__u8	*d;

	///info( "intr_callback() =====>" );

	if ( !rtl8150 )
		return;
	d = urb->transfer_buffer;
	net = rtl8150->net;
///	if ( d[0] & 0xfc ) {
///		rtl8150->stats.tx_errors++;
///		if ( d[0] & TX_UNDERRUN )
///			rtl8150->stats.tx_fifo_errors++;
///		if ( d[0] & (EXCESSIVE_COL | JABBER_TIMEOUT) )
///			rtl8150->stats.tx_aborted_errors++;
///		if ( d[0] & LATE_COL )
///			rtl8150->stats.tx_window_errors++;
///		if ( d[0] & (NO_CARRIER | LOSS_CARRIER) )
///			rtl8150->stats.tx_carrier_errors++;
///	}
	switch ( urb->status ) 
	{
		case USB_ST_NOERROR:
			break;
		case USB_ST_URB_KILLED:
			break;
		default:
			info("intr status %d", urb->status);
	}
}
#endif



static void rtl8150_tx_timeout( struct net_device *net )
{
	rtl8150_t *rtl8150 = net->priv;

	info( "+rtl8150_tx_timeout() =====>" );

	if ( !rtl8150 )

⌨️ 快捷键说明

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