/drivers/net/usb/rtl8150.c
C | 1009 lines | 833 code | 135 blank | 41 comment | 106 complexity | a1e9fdb351e17b0e3737c81f34193753 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
- /*
- * 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/init.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/usb.h>
- #include <asm/uaccess.h>
- /* Version Information */
- #define DRIVER_VERSION "v0.6.2 (2004/08/27)"
- #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 CSCR 0x014C /* This one has the link status */
- #define CSCR_LINK_STATUS (1 << 3)
- #define IDR_EEPROM 0x1202
- #define PHY_READ 0
- #define PHY_WRITE 0x20
- #define PHY_GO 0x40
- #define MII_TIMEOUT 10
- #define INTBUFSIZE 8
- #define RTL8150_REQT_READ 0xc0
- #define RTL8150_REQT_WRITE 0x40
- #define RTL8150_REQ_GET_REGS 0x05
- #define RTL8150_REQ_SET_REGS 0x05
- /* Transmit status register errors */
- #define TSR_ECOL (1<<5)
- #define TSR_LCOL (1<<4)
- #define TSR_LOSS_CRS (1<<3)
- #define TSR_JBR (1<<2)
- #define TSR_ERRORS (TSR_ECOL | TSR_LCOL | TSR_LOSS_CRS | TSR_JBR)
- /* Receive status register errors */
- #define RSR_CRC (1<<2)
- #define RSR_FAE (1<<1)
- #define RSR_ERRORS (RSR_CRC | RSR_FAE)
- /* Media status register definitions */
- #define MSR_DUPLEX (1<<4)
- #define MSR_SPEED (1<<3)
- #define MSR_LINK (1<<2)
- /* Interrupt pipe data */
- #define INT_TSR 0x00
- #define INT_RSR 0x01
- #define INT_MSR 0x02
- #define INT_WAKSR 0x03
- #define INT_TXOK_CNT 0x04
- #define INT_RXLOST_CNT 0x05
- #define INT_CRERR_CNT 0x06
- #define INT_COL_CNT 0x07
- /* Transmit status register errors */
- #define TSR_ECOL (1<<5)
- #define TSR_LCOL (1<<4)
- #define TSR_LOSS_CRS (1<<3)
- #define TSR_JBR (1<<2)
- #define TSR_ERRORS (TSR_ECOL | TSR_LCOL | TSR_LOSS_CRS | TSR_JBR)
- /* Receive status register errors */
- #define RSR_CRC (1<<2)
- #define RSR_FAE (1<<1)
- #define RSR_ERRORS (RSR_CRC | RSR_FAE)
- /* Media status register definitions */
- #define MSR_DUPLEX (1<<4)
- #define MSR_SPEED (1<<3)
- #define MSR_LINK (1<<2)
- /* Interrupt pipe data */
- #define INT_TSR 0x00
- #define INT_RSR 0x01
- #define INT_MSR 0x02
- #define INT_WAKSR 0x03
- #define INT_TXOK_CNT 0x04
- #define INT_RXLOST_CNT 0x05
- #define INT_CRERR_CNT 0x06
- #define INT_COL_CNT 0x07
- #define RTL8150_MTU 1540
- #define RTL8150_TX_TIMEOUT (HZ)
- #define RX_SKB_POOL_SIZE 4
- /* rtl8150 flags */
- #define RTL8150_HW_CRC 0
- #define RX_REG_SET 1
- #define RTL8150_UNPLUG 2
- #define RX_URB_FAIL 3
- /* Define these values to match your device */
- #define VENDOR_ID_REALTEK 0x0bda
- #define VENDOR_ID_MELCO 0x0411
- #define VENDOR_ID_MICRONET 0x3980
- #define VENDOR_ID_LONGSHINE 0x07b8
- #define VENDOR_ID_OQO 0x1557
- #define VENDOR_ID_ZYXEL 0x0586
- #define PRODUCT_ID_RTL8150 0x8150
- #define PRODUCT_ID_LUAKTX 0x0012
- #define PRODUCT_ID_LCS8138TX 0x401a
- #define PRODUCT_ID_SP128AR 0x0003
- #define PRODUCT_ID_PRESTIGE 0x401a
- #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)},
- {USB_DEVICE(VENDOR_ID_MICRONET, PRODUCT_ID_SP128AR)},
- {USB_DEVICE(VENDOR_ID_LONGSHINE, PRODUCT_ID_LCS8138TX)},
- {USB_DEVICE(VENDOR_ID_OQO, PRODUCT_ID_RTL8150)},
- {USB_DEVICE(VENDOR_ID_ZYXEL, PRODUCT_ID_PRESTIGE)},
- {}
- };
- MODULE_DEVICE_TABLE(usb, rtl8150_table);
- struct rtl8150 {
- unsigned long flags;
- struct usb_device *udev;
- struct tasklet_struct tl;
- struct net_device *netdev;
- struct urb *rx_urb, *tx_urb, *intr_urb, *ctrl_urb;
- struct sk_buff *tx_skb, *rx_skb;
- struct sk_buff *rx_skb_pool[RX_SKB_POOL_SIZE];
- spinlock_t rx_pool_lock;
- struct usb_ctrlrequest dr;
- int intr_interval;
- __le16 rx_creg;
- u8 *intr_buff;
- u8 phy;
- };
- typedef struct rtl8150 rtl8150_t;
- static void fill_skb_pool(rtl8150_t *);
- static void free_skb_pool(rtl8150_t *);
- static inline struct sk_buff *pull_skb(rtl8150_t *);
- static void rtl8150_disconnect(struct usb_interface *intf);
- static int rtl8150_probe(struct usb_interface *intf,
- const struct usb_device_id *id);
- static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message);
- static int rtl8150_resume(struct usb_interface *intf);
- static const char driver_name [] = "rtl8150";
- static struct usb_driver rtl8150_driver = {
- .name = driver_name,
- .probe = rtl8150_probe,
- .disconnect = rtl8150_disconnect,
- .id_table = rtl8150_table,
- .suspend = rtl8150_suspend,
- .resume = rtl8150_resume
- };
- /*
- **
- ** 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, 500);
- }
- 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, 500);
- }
- static void ctrl_callback(struct urb *urb)
- {
- rtl8150_t *dev;
- int status = urb->status;
- switch (status) {
- case 0:
- break;
- case -EINPROGRESS:
- break;
- case -ENOENT:
- break;
- default:
- if (printk_ratelimit())
- dev_warn(&urb->dev->dev, "ctrl urb status %d\n", status);
- }
- dev = urb->context;
- clear_bit(RX_REG_SET, &dev->flags);
- }
- static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size)
- {
- 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(size);
- dev->ctrl_urb->transfer_buffer_length = size;
- usb_fill_control_urb(dev->ctrl_urb, dev->udev,
- usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr,
- &dev->rx_creg, size, ctrl_callback, dev);
- if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) {
-