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

📄 rtl8150.c

📁 ep9315平台下USB驱动的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Copyright (c) 2002 Petko Manolov (petkan@users.sourceforge.net) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License  * version 2 as published by the Free Software Foundation. */#include <linux/config.h>#include <linux/sched.h>#include <linux/signal.h>#include <linux/slab.h>#include <linux/module.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/mii.h>#include <linux/ethtool.h>#include <linux/devfs_fs_kernel.h>#include <linux/usb.h>#include <linux/init.h>#include <asm/uaccess.h>/* Version Information */#define DRIVER_VERSION "v0.4.3 (2002/12/31)"#define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"#define DRIVER_DESC "rtl8150 based usb-ethernet driver"#define	IDR			0x0120#define	MAR			0x0126#define	CR			0x012e#define	TCR			0x012f#define	RCR			0x0130#define	TSR			0x0132#define	RSR			0x0133#define	CON0			0x0135#define	CON1			0x0136#define	MSR			0x0137#define	PHYADD			0x0138#define	PHYDAT			0x0139#define	PHYCNT			0x013b#define	GPPC			0x013d#define	BMCR			0x0140#define	BMSR			0x0142#define	ANAR			0x0144#define	ANLP			0x0146#define	AER			0x0148#define	IDR_EEPROM		0x1202#define	PHY_READ		0#define	PHY_WRITE		0x20#define	PHY_GO			0x40#define	RTL8150_REQT_READ	0xc0#define	RTL8150_REQT_WRITE	0x40#define	RTL8150_REQ_GET_REGS	0x05#define	RTL8150_REQ_SET_REGS	0x05#define	RTL8150_MTU		1500#define	RTL8150_MAX_MTU		1536#define	RTL8150_TX_TIMEOUT	(HZ)/* rtl8150 flags */#define	RTL8150_FLAG_HWCRC	0#define	RX_REG_SET		1#define	RTL8150_UNPLUG		2/* Define these values to match your device */#define VENDOR_ID_REALTEK		0x0bda#define	VENDOR_ID_MELCO			0x0411#define PRODUCT_ID_RTL8150		0x8150#define	PRODUCT_ID_LUAKTX		0x0012#undef EEPROM_WRITE/* table of devices that work with this driver */static struct usb_device_id rtl8150_table[] = {	{USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8150)},	{USB_DEVICE(VENDOR_ID_MELCO, PRODUCT_ID_LUAKTX)},	{}};MODULE_DEVICE_TABLE(usb, rtl8150_table);struct rtl8150 {	unsigned int flags;	struct usb_device *udev;	struct usb_interface *interface;	struct semaphore sem;	struct net_device_stats stats;	struct net_device *netdev;	struct urb *rx_urb, *tx_urb, *intr_urb, *ctrl_urb;	struct usb_ctrlrequest dr;	int intr_interval;	u16 rx_creg;	u8 rx_buff[RTL8150_MAX_MTU];	u8 tx_buff[RTL8150_MAX_MTU];	u8 intr_buff[8];	u8 phy;};typedef struct rtl8150 rtl8150_t;/* the global usb devfs handle */extern devfs_handle_t usb_devfs_handle;unsigned long multicast_filter_limit = 32;static void rtl8150_disconnect(struct usb_device *dev, void *ptr);static void *rtl8150_probe(struct usb_device *dev, unsigned int ifnum,			   const struct usb_device_id *id);static struct usb_driver rtl8150_driver = {	name:		"rtl8150",	probe:		rtl8150_probe,	disconnect:	rtl8150_disconnect,	id_table:	rtl8150_table,};/*****	device related part of the code***/static int get_registers(rtl8150_t * dev, u16 indx, u16 size, void *data){	return usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),			       RTL8150_REQ_GET_REGS, RTL8150_REQT_READ,			       indx, 0, data, size, HZ / 2);}static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data){	return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),			       RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE,			       indx, 0, data, size, HZ / 2);}static void ctrl_callback(struct urb *urb){	rtl8150_t *dev;	switch (urb->status) {	case 0:		break;	case -EINPROGRESS:		break;	case -ENOENT:		break;	default:		warn("ctrl urb status %d", urb->status);	}	dev = urb->context;	clear_bit(RX_REG_SET, &dev->flags);}static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data){	int ret;	if (test_bit(RX_REG_SET, &dev->flags))		return -EAGAIN;	dev->dr.bRequestType = RTL8150_REQT_WRITE;	dev->dr.bRequest = RTL8150_REQ_SET_REGS;	dev->dr.wValue = cpu_to_le16(indx);	dev->dr.wIndex = 0;	dev->dr.wLength = cpu_to_le16(2);	dev->ctrl_urb->transfer_buffer_length = 2;	FILL_CONTROL_URB(dev->ctrl_urb, dev->udev,			 usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr,			 &dev->rx_creg, 2, ctrl_callback, dev);	if ((ret = usb_submit_urb(dev->ctrl_urb)))		err("control request submission failed: %d", ret);	else		set_bit(RX_REG_SET, &dev->flags);	return ret;}static int read_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 * reg){	int i;	u8 data[3], tmp;	data[0] = phy;	data[1] = data[2] = 0;	tmp = indx | PHY_READ | PHY_GO;	i = 0;	set_registers(dev, PHYADD, sizeof(data), data);	set_registers(dev, PHYCNT, 1, &tmp);	do {		get_registers(dev, PHYCNT, 1, data);	} while ((data[0] & PHY_GO) && (i++ < HZ));	if (i < HZ) {		get_registers(dev, PHYDAT, 2, data);		*reg = le16_to_cpup((u16 *)data);		return 0;	} else		return 1;}static int write_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 reg){	int i;	u8 data[3], tmp;	data[0] = phy;	*(data + 1) = cpu_to_le16p(&reg);	tmp = indx | PHY_WRITE | PHY_GO;	i = 0;	set_registers(dev, PHYADD, sizeof(data), data);	set_registers(dev, PHYCNT, 1, &tmp);	do {		get_registers(dev, PHYCNT, 1, data);	} while ((data[0] & PHY_GO) && (i++ < HZ));	if (i < HZ)		return 0;	else		return 1;}static inline void set_ethernet_addr(rtl8150_t * dev){	u8 node_id[6];	get_registers(dev, IDR, sizeof(node_id), node_id);	memcpy(dev->netdev->dev_addr, node_id, sizeof(node_id));}static int rtl8150_set_mac_address(struct net_device *netdev, void *p){	struct sockaddr *addr = p;	rtl8150_t *dev;	int i;	if (netif_running(netdev))		return -EBUSY;	dev = netdev->priv;	if (dev == NULL) {		return -ENODEV;	}	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);	dbg("%s: Setting MAC address to ", netdev->name);	for (i = 0; i < 5; i++)		printk("%02X:", netdev->dev_addr[i]);	dbg("%02X\n", netdev->dev_addr[i]);	/* Set the IDR registers. */	set_registers(dev, IDR, sizeof(netdev->dev_addr), netdev->dev_addr);#ifdef EEPROM_WRITE	{	u8 cr;	/* Get the CR contents. */	get_registers(dev, CR, 1, &cr);	/* Set the WEPROM bit (eeprom write enable). */	cr |= 0x20;	set_registers(dev, CR, 1, &cr);	/* Write the MAC address into eeprom. Eeprom writes must be word-sized,	   so we need to split them up. */	for (i = 0; i * 2 < netdev->addr_len; i++) {		set_registers(dev, IDR_EEPROM + (i * 2), 2, 		              netdev->dev_addr + (i * 2));	}	/* Clear the WEPROM bit (preventing accidental eeprom writes). */	cr &= 0xdf;	set_registers(dev, CR, 1, &cr);	}#endif		return 0;}static int rtl8150_reset(rtl8150_t * dev){	u8 data = 0x10;	int i = HZ;	set_registers(dev, CR, 1, &data);	do {		get_registers(dev, CR, 1, &data);	} while ((data & 0x10) && --i);	return (i > 0) ? 0 : -1;}static int alloc_all_urbs(rtl8150_t * dev){	dev->rx_urb = usb_alloc_urb(0);	if (!dev->rx_urb)		return 0;	dev->tx_urb = usb_alloc_urb(0);	if (!dev->tx_urb) {		usb_free_urb(dev->rx_urb);		return 0;	}	dev->intr_urb = usb_alloc_urb(0);	if (!dev->intr_urb) {		usb_free_urb(dev->rx_urb);		usb_free_urb(dev->tx_urb);		return 0;	}	dev->ctrl_urb = usb_alloc_urb(0);	if (!dev->ctrl_urb) {		usb_free_urb(dev->rx_urb);		usb_free_urb(dev->tx_urb);		usb_free_urb(dev->intr_urb);		return 0;	}	return 1;}static void free_all_urbs(rtl8150_t * dev){	usb_free_urb(dev->rx_urb);	usb_free_urb(dev->tx_urb);	usb_free_urb(dev->intr_urb);	usb_free_urb(dev->ctrl_urb);}static void unlink_all_urbs(rtl8150_t * dev){	usb_unlink_urb(dev->rx_urb);	usb_unlink_urb(dev->tx_urb);	usb_unlink_urb(dev->intr_urb);	usb_unlink_urb(dev->ctrl_urb);}static void read_bulk_callback(struct urb *urb){	rtl8150_t *dev;	int pkt_len, res;	struct sk_buff *skb;	struct net_device *netdev;	u16 rx_stat;	dev = urb->context;	if (!dev) {		warn("!dev");		return;	}	netdev = dev->netdev;	if (!netif_device_present(netdev)) {		warn("netdev is not present");		return;	}	switch (urb->status) {	case 0:		break;	case -ENOENT:		return;	case -ETIMEDOUT:		warn("need a device reset?..");		goto goon;	default:		warn("Rx status %d", urb->status);		goto goon;	}	pkt_len = urb->actual_length - 4;	rx_stat = le16_to_cpu(*(u16 *) (dev->rx_buff + pkt_len));	if (!(skb = dev_alloc_skb(pkt_len + 2)))		goto goon;	skb->dev = netdev;	skb_reserve(skb, 2);	eth_copy_and_sum(skb, dev->rx_buff, pkt_len, 0);	skb_put(skb, pkt_len);	skb->protocol = eth_type_trans(skb, netdev);	netif_rx(skb);	dev->stats.rx_packets++;	dev->stats.rx_bytes += pkt_len;goon:	FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),		      dev->rx_buff, RTL8150_MAX_MTU, read_bulk_callback, dev);	if ((res = usb_submit_urb(dev->rx_urb)))		warn("%s: Rx urb submission failed %d", netdev->name, res);}static void write_bulk_callback(struct urb *urb){	rtl8150_t *dev;

⌨️ 快捷键说明

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