diff options
Diffstat (limited to 'ANDROID_3.4.5/drivers/net/usb/ch9x00.c')
-rwxr-xr-x | ANDROID_3.4.5/drivers/net/usb/ch9x00.c | 852 |
1 files changed, 0 insertions, 852 deletions
diff --git a/ANDROID_3.4.5/drivers/net/usb/ch9x00.c b/ANDROID_3.4.5/drivers/net/usb/ch9x00.c deleted file mode 100755 index 11ac3d50..00000000 --- a/ANDROID_3.4.5/drivers/net/usb/ch9x00.c +++ /dev/null @@ -1,852 +0,0 @@ -/* - * USB 10M/100M ethernet adapter - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whther express or implied - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/stddef.h> -#include <linux/init.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/ethtool.h> -#include <linux/mii.h> -#include <linux/usb.h> -#include <linux/crc32.h> -#include <linux/usb/usbnet.h> -#include <linux/slab.h> - - -#define CH9x00_VID 0x1A86 -#define CH9x00_PID_8339 0x8339 -#define CH9x00_PID_E091 0xE091 -#define CH9x00_PID_E092 0xE092 - -#define DRIVER_VERSION "29-May-2013" - -#define DEBUG_PRT //for debug -#undef DEBUG_PRT - -#ifdef DEBUG_PRT -#define dbg_prt(format, arg...) printk(KERN_DEBUG format "\n", ## arg) -#else -#define dbg_prt(format, arg...) do {} while (0) -#endif - -/**** Reg and CMD definition for CH9x00_PID_E091 and CH9x00_PID_8339****/ -#define DEVICE_SPEED_10M 0x80 -#define DEVICE_MEDIA_CONNECTED 0x40 -#define DEVICE_DUPLEX_FULL 0x20 -#define DEVICE_PHY 0x10 - -#define REQ_RD_REG (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE) -#define REQ_WR_REG (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) -#define CTRL_TIMEOUT_MS 1000 - -#define MCAST_MAX 0x40 -#define TX_OVERHEAD 0x04 -#define RX_OVERHEAD 0x04 - -#define GET_MAC_ADDRESS 0x00 -#define SET_HASH_TABLE 0x04 -#define SET_PACKAGE_FILTER 0x05 - #define RECEIVE_ALL 0x08 - #define MULTIPKT_EN 0x04 - #define BROADPKT_EN 0x02 - #define HASH_MULTI_EN 0x01 - #define CTRL_CLOSE 0x00 - #define CTRL_OPEN 0x01 -#define SET_SPEED_DUPLEX 0x06 - #define HALF_DUPLEX 0x00 - #define FULL_DUPLEX 0x01 - #define SPEED_10M 0x00 - #define SPEED_100M 0x02 - #define MT 0x00 - #define AT 0x04 -#define SET_MAC_ADDRESS 0x07 -#define SET_MAC_WAKEUP_FRAME 0x08 -#define SET_WAKEUP_ENABLE 0x09 - #define LINKCHG0_EN 0x01 - #define LINKCHG1_EN 0x02 - #define MAGICPKT_EN 0x04 - #define WAKEUP1_EN 0x08 - #define WAKEUP2_EN 0x10 - #define WAKEUP3_EN 0x20 - #define WAKEUP4_EN 0x40 -#define SET_FULL_DUPLEX_FLOW_CONTROL 0x0A -#define SET_HALF_DUPLEX_FLOW_CONTROL 0x0B - -#define TEST_GET_MAC_ADDRESS -#define TEST_SET_MAC_ADDRESS -//#define TEST_SET_HASH -//#define TEST_SET_PACKAGE_FILTER -#define TEST_SET_SPEED_DUPLEX -//#define TEST_SET_WAKEUP_ENABLE - #if defined(TEST_SET_WAKEUP_ENABLE) - #define WKE1_EN - #define WKE2_EN - #define WKE3_EN - #define WKE4_EN - #define MAGIC_EN - #define LIKCHG1_EN - #define LIKCHG0_EN - #endif - - -/**** Reg and CMD definition for CH9x00_PID_E092 ****/ -// === constant define -#define RX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4) -#define TX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4) - -#define MIN_PACKET sizeof(struct ethhdr) -#define MAX_PACKET 32768 - -#define TX_TIMEOUT_JIFFIES (5 * HZ) -#define THROTTLE_JIFFIES (HZ / 8) -#define UNLINK_TIMEOUT_MS 3 - -// for vendor-specific control operations -#define CONTROL_TIMEOUT_MS 1000 - -// request -#define REQUEST_READ 0x0E -#define REQUEST_WRITE 0x0F - -#define REQUEST_TYPE_READ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER) -#define REQUEST_TYPE_WRITE (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER) - -// address space -// addr 00---63 : mii addr -// addr 64---128 : mac addr -// note : read/write must be in word (16 bit) - -#define MAC_REG_CTRL 64 -#define MAC_REG_STATUS 66 -#define MAC_REG_INTERRUPT_MASK 68 -#define MAC_REG_PHY_COMMAND 70 -#define MAC_REG_PHY_DATA 72 -#define MAC_REG_STATION_L 74 -#define MAC_REG_STATION_M 76 -#define MAC_REG_STATION_H 78 -#define MAC_REG_HASH_L 80 -#define MAC_REG_HASH_M1 82 -#define MAC_REG_HASH_M2 84 -#define MAC_REG_HASH_H 86 -#define MAC_REG_THRESHOLD 88 -#define MAC_REG_FIFO_DEPTH 90 -#define MAC_REG_PAUSE 92 -#define MAC_REG_FLOW_CONTROL 94 - -// BIT -// control register bit15 and bit13 reserve -#define LOOPBACK (0x01 << 14) -#define BASE100X (0x01 << 12) -#define MBPS_10 (0x01 << 11) -#define DUPLEX_MODE (0x01 << 10) -#define PAUSE_FRAME (0x01 << 9) -#define PROMISCUOUS (0x01 << 8) -#define MULTICAST (0x01 << 7) -#define BROADCAST (0x01 << 6) -#define HASH (0x01 << 5) -#define APPEND_PAD (0x01 << 4) -#define APPEND_CRC (0x01 << 3) -#define TRANSMITTER_ACTION (0x01 << 2) -#define RECEIVER_ACTION (0x01 << 1) -#define DMA_ACTION (0x01 << 0) - -// status register bit15-bit7 reserve -#define ALIGNMENT (0x01 << 6) -#define FIFO_OVER_RUN (0x01 << 5) -#define FIFO_UNDER_RUN (0x01 << 4) -#define RX_ERROR (0x01 << 3) -#define RX_COMPLETE (0x01 << 2) -#define TX_ERROR (0x01 << 1) -#define TX_COMPLETE (0x01 << 0) - -// fifo depth register bit14 and bit6 reserve -#define ETH_TXBD (0x01 << 15) -#define ETN_TX_FIFO_DEPTH // bit13:8 -#define ETH_RXBD (0x01 << 7)// bit -#define ETH_RX_FIFO_DEPTH // bit5:0 - - -// ************************************************** -int speed_status; -int link_status; -int duplex_status; -int phy_status; - - -static void ch9x00_async_cmd_callback( struct urb *urb ) -{ - struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; - - if( urb->status < 0 ) - printk( KERN_DEBUG "%s() failed with %d\n", __FUNCTION__, urb->status); - - kfree(req); - usb_free_urb(urb); -} - - -static void ch9x00_set_reg_async( - struct usbnet *dev, - unsigned char request, - unsigned char requesttype, - unsigned short value, - unsigned short index, - unsigned short size, - void *data ) -{ - struct usb_ctrlrequest *req; - int ret; - struct urb *urb; - - urb = usb_alloc_urb( 0, GFP_ATOMIC); - if(!urb) { - dev_dbg( &dev->udev->dev, - "Error allocation URB in write_cmd_async!\n"); - return; - } - - req = kmalloc( sizeof *req, GFP_ATOMIC); - if(!req) { - dev_err( &dev->udev->dev, - "Failed to allocate memory for control request\n"); - goto out; - } - - req->bRequestType = requesttype; - req->bRequest = request; - req->wValue = cpu_to_le16(value); - req->wIndex = cpu_to_le16(index); - req->wLength = cpu_to_le16(size); - - usb_fill_control_urb( urb, dev->udev, - usb_sndctrlpipe(dev->udev, 0), - (void *)req, data, size, ch9x00_async_cmd_callback,req); - - ret = usb_submit_urb(urb, GFP_ATOMIC); - if( ret < 0 ) { - dev_err( &dev->udev->dev, - "Error submitting the control message, ret:%d\n", ret ); - goto out; - } - return; - -out: - kfree(req); - usb_free_urb(urb); -} - - -static void set_speed_duplex( struct usbnet *dev, unsigned char value_l ) -{ - unsigned short value; - unsigned char value_low = 0x00; - unsigned char value_high = 0x00; - - value_low = value_l; - value = value_low | (value_high << 8 ); - ch9x00_set_reg_async( dev, SET_SPEED_DUPLEX, REQ_WR_REG, value, 0, 0, NULL); - - return; -} - - -static int control_read( struct usbnet *dev, - unsigned char request, unsigned char requesttype, - unsigned short value, unsigned short index, - void *data, unsigned short size, int timeout ) -{ - unsigned char *buf = NULL; - int err = 0; - - dbg_prt("\n--> Control_read() index=0x%02x size=%d\n", index, size ); - - buf = kmalloc( size, GFP_KERNEL ); - if( !buf ) { - err = -ENOMEM; - goto err_out; - } - - err = usb_control_msg( dev->udev, - usb_rcvctrlpipe(dev->udev, 0), - request, requesttype, - value, index, - buf, size, timeout); - if( err == size ) - memcpy( data, buf, size ); - else if( err >= 0 ) - err = -EINVAL; - kfree(buf); - - return err; - -err_out: - return err; -} - - -static int control_write( struct usbnet *dev, - unsigned char request, unsigned char requesttype, - unsigned short value, unsigned short index, - void *data, unsigned short size, int timeout ) -{ - unsigned char *buf = NULL; - int err = 0; - - dbg_prt("\n--> Control_write() index=0x%02x size=%d\n", index, size ); - - if( data ) { - buf = kmalloc( size, GFP_KERNEL ); - if( !buf ) { - err = -ENOMEM; - goto err_out; - } - memcpy( buf, data, size ); - } - - err = usb_control_msg( dev->udev, - usb_sndctrlpipe( dev->udev, 0 ), - request, requesttype, - value, index, - buf, size, timeout ); - if( err >= 0 && err < size ) - err = -EINVAL; - kfree( buf ); - - return 0; - -err_out: - return err; -} - -static int ch9x00_mdio_read( struct net_device *netdev, - int phy_id, int loc ) -{ - struct usbnet *dev = netdev_priv(netdev); - int product_id = dev->udev->descriptor.idProduct; - __le16 res = 0x00; //for E091 - unsigned char buff[2]; //for E092 - - dbg_prt("ch9x00_mdio_read phy_id:%02x loc:%02x\n", phy_id, loc); - - if( product_id == CH9x00_PID_E091 || - product_id == CH9x00_PID_8339 ) { - mutex_lock( &dev->phy_mutex ); - if( phy_id == 0x00 ) { - switch(loc) { - case MII_BMCR: //Basic mode control register - { - if(speed_status == DEVICE_SPEED_10M){ - //Do nothing here - } - else - res |= BMCR_SPEED100; - - if(duplex_status == DEVICE_DUPLEX_FULL) - res |= BMCR_FULLDPLX; - else { - //Do nothing here - } - - res |= BMCR_ANENABLE; - break; - } - case MII_BMSR: //Basic mode status register - { - if(link_status == DEVICE_MEDIA_CONNECTED) //up - res |= BMSR_LSTATUS; - else { //down - //Do nothing - } - - if(speed_status == DEVICE_SPEED_10M) { - if(duplex_status == DEVICE_DUPLEX_FULL) - res |= BMSR_10FULL; - else - res |= BMSR_10HALF; - } - else { - if(duplex_status == DEVICE_DUPLEX_FULL) - res |= BMSR_100FULL; - else - res |= BMSR_100HALF; - } - - break; - } - case MII_ADVERTISE: //Advertisement control reg - { - if(speed_status == DEVICE_SPEED_10M) - res |= ADVERTISE_10FULL; - else - res |= ADVERTISE_10HALF; - - res |= 0x01; //IEEE 802.3 - } - case MII_LPA: //Link partner ability reg - { - if(speed_status == DEVICE_SPEED_10M) { - if(duplex_status == DEVICE_DUPLEX_FULL) - res |= LPA_10FULL; - else - res |= LPA_10HALF; - } - else { - if(duplex_status == DEVICE_DUPLEX_FULL) - res |= LPA_100FULL; - else - res |= LPA_100HALF; - } - - res |= 0x01; //IEEE 802.3 - break; - } - case MII_EXPANSION: //Expansion register - break; - default: - break; - } - } - mutex_unlock( &dev->phy_mutex); - return le16_to_cpu(res); - } - else if( product_id == CH9x00_PID_E092 ) { - if( phy_id ) - return 0; - - control_read( dev, REQUEST_READ, REQUEST_TYPE_READ, - 0, loc*2, buff, 0x02, CONTROL_TIMEOUT_MS ); - - return ( buff[0] | buff[1] << 8 ); - } - - return 0; -} - - -static void ch9x00_mdio_write( struct net_device *netdev, - int phy_id, int loc, int val ) -{ - struct usbnet *dev = netdev_priv(netdev); - int product_id = dev->udev->descriptor.idProduct; - unsigned char value_l = 0; //for E091 - unsigned char buff[2]; //for E092 - - dbg_prt("ch9x00_mdio_write() phy_id=%02x loc:%02x\n", phy_id, loc); - - if( product_id == CH9x00_PID_E091 || - product_id == CH9x00_PID_8339 ) { - mutex_lock( &dev->phy_mutex ); - if(phy_id == 0x00) { - switch(loc) { - case MII_BMCR: //Base mode control register - { - if( val & BMCR_ANRESTART ) { - //Do nothing - } - - if( val & BMCR_ANENABLE ) { - value_l |= AT; - goto set; - } - - if( val & BMCR_SPEED100 ) { - value_l |= SPEED_100M; - } - - // bit 8 duplex mode 1 = full-duplex - if( val & BMCR_FULLDPLX ) { - value_l |= FULL_DUPLEX; - } -set: - set_speed_duplex(dev, value_l); - break; - } - case MII_BMSR: //Basic mode status register - break; - case MII_ADVERTISE: //Advertisement control reg - break; - case MII_LPA: //Link partner ability reg - break; - case MII_EXPANSION: //Expansion register - break; - default: - break; - } - } - mutex_unlock( &dev->phy_mutex ); - return; - } - else if( product_id == CH9x00_PID_E092 ) { - buff[0] = (unsigned char)val; - buff[1] = (unsigned char)(val >> 8); - - if(phy_id) - return; - - control_write( dev, REQUEST_WRITE, REQUEST_TYPE_WRITE, - 0, loc*2, buff, 0x02, CONTROL_TIMEOUT_MS ); - - } - -} - - -static int ch9x00_link_reset( struct usbnet *dev ) -{ - struct ethtool_cmd ecmd; - - mii_check_media( &dev->mii, 1, 1 ); - mii_ethtool_gset( &dev->mii, &ecmd ); - - dbg_prt("\nlink_reset() speed:%d duplex:%d \n", ecmd.speed, ecmd.duplex ); - - return 0; -} - - -static void ch9x00_status( struct usbnet *dev, struct urb *urb ) -{ - int link; - unsigned char *buf; - int product_id = dev->udev->descriptor.idProduct; - - if( product_id == CH9x00_PID_E091 || - product_id == CH9x00_PID_8339 ) { - if( urb->actual_length < 8 ) - return; - - buf = urb->transfer_buffer; - link = !!(buf[0] & DEVICE_MEDIA_CONNECTED ); - link_status = buf[0] & DEVICE_MEDIA_CONNECTED; - speed_status = buf[0] & DEVICE_SPEED_10M; - duplex_status = buf[0] & DEVICE_DUPLEX_FULL; - phy_status = buf[0] & DEVICE_PHY; - - if( netif_carrier_ok(dev->net) != link ) { - if(link) { - netif_carrier_on(dev->net); - usbnet_defer_kevent(dev, EVENT_LINK_RESET); - } - else { - netif_carrier_off(dev->net); - } - } - } - else if( product_id == CH9x00_PID_E092 ) { - if( urb->actual_length < 16 ) - return; - - buf = urb->transfer_buffer; - link = !!(buf[0] & 0x01); - - if( link ) { - netif_carrier_on(dev->net); - usbnet_defer_kevent(dev, EVENT_LINK_RESET); - } - else { - netif_carrier_off(dev->net); - } - } - - - return; -} - - -static struct sk_buff *ch9x00_tx_fixup( - struct usbnet *dev, struct sk_buff *skb, gfp_t flags ) -{ - int i = 0; - int len = 0; - int tx_overhead = 0; - int product_id = dev->udev->descriptor.idProduct; - - if( product_id == CH9x00_PID_E091 || - product_id == CH9x00_PID_8339 ) - tx_overhead = TX_OVERHEAD; //TX_OVERHEAD: 0x04 - else if( product_id == CH9x00_PID_E092 ) - tx_overhead = 0x40; //64 - - len = skb->len; - if( skb_headroom(skb) < tx_overhead ) { - struct sk_buff *skb2; - - skb2 = skb_copy_expand(skb, tx_overhead, 0, flags); - dev_kfree_skb_any(skb); - skb = skb2; - if( !skb ) - return NULL; - } - - __skb_push(skb, tx_overhead); - /* usbnet adds padding if length is a multiple of packet size - if so, adjust length value in header */ - if( (skb->len % dev->maxpacket) == 0 ) { - len++; - } - - if( product_id == CH9x00_PID_E091 || - product_id == CH9x00_PID_8339 ) { - skb->data[0] = len; - skb->data[1] = len >> 8; - skb->data[2] = 0x00; - skb->data[3] = 0x00; - } - else if( product_id == CH9x00_PID_E092 ) { - skb->data[0] = len; - skb->data[1] = len >> 8; - skb->data[2] = 0x00; - skb->data[3] = 0x80; - - for( i = 4; i < 48; i++ ) - skb->data[i] = 0x00; - - skb->data[48] = len; - skb->data[49] = len >> 8; - skb->data[50] = 0x00; - skb->data[51] = 0x80; - - for( i = 52; i < 64; i++ ) - skb->data[i] = 0x00; - } - - return skb; -} - - -static int ch9x00_rx_fixup( struct usbnet *dev, struct sk_buff *skb ) -{ - int len = 0; - int rx_overhead = 0; - int product_id = dev->udev->descriptor.idProduct; - - if( product_id == CH9x00_PID_E091 || - product_id == CH9x00_PID_8339 ) { - rx_overhead = RX_OVERHEAD; - - if( unlikely(skb->len < rx_overhead) ) { - dev_err( &dev->udev->dev, "unexpected tiny rx frame\n"); - return 0; - } - - len = (skb->data[0] | skb->data[1] << 8 ); - - skb_pull(skb, rx_overhead); - skb_trim(skb, len); - } - else if( product_id == CH9x00_PID_E092 ) { - // Do nothing here - rx_overhead = 64; - - if( unlikely(skb->len < rx_overhead) ) { - dev_err( &dev->udev->dev, "unexpected tiny rx frame\n"); - return 0; - } - - len = (skb->data[skb->len - 16] | skb->data[skb->len - 15] << 8 ); - /*printk("rx_fixup skb->len=%d, len=%d\n", skb->len, len );*/ - - /*skb_pull(skb, rx_overhead);*/ - skb_trim(skb, len); - } - - return 1; -} - - -static int get_mac_address( struct usbnet *dev, unsigned char *data ) -{ - int err = 0; - //for E092 - unsigned char mac_addr[0x06]; - int rd_mac_len = 0; - - dbg_prt("\n--> get_mac_address:\n\tusbnet VID:%0x PID:%0x\n", - dev->udev->descriptor.idVendor, - dev->udev->descriptor.idProduct); - - if( dev->udev->descriptor.idProduct == CH9x00_PID_E091 || - dev->udev->descriptor.idProduct == CH9x00_PID_8339 ) - err = control_read( dev, GET_MAC_ADDRESS, REQ_RD_REG, - 0, 0, data, 0x06, CTRL_TIMEOUT_MS ); - else if( dev->udev->descriptor.idProduct == CH9x00_PID_E092 ) { - memset( mac_addr, 0, sizeof(mac_addr) ); - rd_mac_len = control_read( dev, REQUEST_READ, REQUEST_TYPE_READ, - 0, MAC_REG_STATION_L, mac_addr, 0x02, CONTROL_TIMEOUT_MS ); - rd_mac_len += control_read( dev, REQUEST_READ, REQUEST_TYPE_READ, - 0, MAC_REG_STATION_M, mac_addr+2, 0x02, CONTROL_TIMEOUT_MS ); - rd_mac_len += control_read( dev, REQUEST_READ, REQUEST_TYPE_READ, - 0, MAC_REG_STATION_H, mac_addr+4, 0x02, CONTROL_TIMEOUT_MS ); - if( rd_mac_len != ETH_ALEN ) - err = -EINVAL; - //Set MAC - data[0] = mac_addr[5]; - data[1] = mac_addr[4]; - data[2] = mac_addr[3]; - data[3] = mac_addr[2]; - data[4] = mac_addr[1]; - data[5] = mac_addr[0]; - } - - if( err < 0 ) - goto err_out; - - return 0; - -err_out: - return err; -} - - -static int ch9x00_bind( struct usbnet *dev, struct usb_interface *intf ) -{ - int retval = 0; - unsigned char data[2]; - - //int vendor_id = dev->udev->descriptor.idVendor; - int product_id = dev->udev->descriptor.idProduct; - - retval = usbnet_get_endpoints(dev, intf); - if(retval) - goto err_out; - - // compatibility of E091 and E092 - if( product_id == CH9x00_PID_E091 || - product_id == CH9x00_PID_8339 ) { - if( (retval = get_mac_address(dev, dev->net->dev_addr)) < 0 ) { - return retval; - goto err_out; - } - } - - // Initialize MII structure for Setting Speed Duplex - dev->mii.dev = dev->net; - dev->mii.mdio_read = ch9x00_mdio_read; - dev->mii.mdio_write = ch9x00_mdio_write; - dev->mii.reg_num_mask = 0x1f; - - if( product_id == CH9x00_PID_E091 || - product_id == CH9x00_PID_8339 ) { - dev->mii.phy_id_mask = 0x3f; - /*dev->rx_urb_size = dev->net->mtu + 14 + RX_OVERHEAD;*/ - // Note: Max package length=1518 (MTU + ETH_HELN + RX_OVERHEAD) - dev->rx_urb_size = dev->net->mtu + ETH_HLEN + RX_OVERHEAD; - // Adaptor can restart, when driver rmmoded or insmoded - mii_nway_restart( &dev->mii ); - } - else if( product_id == CH9x00_PID_E092 ) { - dev->mii.phy_id_mask = 0x1f; - - dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; - // Note: Max package legth= 24*64 + 16 - dev->rx_urb_size = 24*64 + 16; - // Adaptor can restart, when driver rmmoded or insmoded - mii_nway_restart( &dev->mii ); - - // Initilization hardware - data[0] = 0x01; - data[1] = 0x0F; - retval = control_write( dev, REQUEST_WRITE, REQUEST_TYPE_WRITE, - 0, 88, data, 0x02, CONTROL_TIMEOUT_MS ); - - data[0] = 0xA0; - data[1] = 0x90; - retval = control_write( dev, REQUEST_WRITE, REQUEST_TYPE_WRITE, - 0, 90, data, 0x02, CONTROL_TIMEOUT_MS ); - - data[0] = 0x30; - data[1] = 0x00; - retval = control_write( dev, REQUEST_WRITE, REQUEST_TYPE_WRITE, - 0, 92, data, 0x02, CONTROL_TIMEOUT_MS ); - - data[0] = 0x17; - data[1] = 0xD8; - retval = control_write( dev, REQUEST_WRITE, REQUEST_TYPE_WRITE, - 0, 94, data, 0x02, CONTROL_TIMEOUT_MS ); - - data[0] = 0x01; - data[1] = 0x00; - retval = control_write( dev, REQUEST_WRITE, REQUEST_TYPE_WRITE, - 0, 254, data, 0x02, CONTROL_TIMEOUT_MS ); - - data[0] = 0x5F; // 0x0101 1111 - data[1] = 0x0D; // 0x0000 1101 - // Control Register Setting - retval = control_write( dev, REQUEST_WRITE, REQUEST_TYPE_WRITE, - 0, 64, data, 0x02, CONTROL_TIMEOUT_MS ); - - if( (retval = get_mac_address(dev, dev->net->dev_addr)) < 0 ) { - return retval; - goto err_out; - } - } - if( retval < 0 ) - goto err_out; - - return 0; - -err_out: - return retval; -} - - -static const struct driver_info ch9x00_info = { - .description = "CH9x00 USB to Network Adaptor", - .flags = FLAG_ETHER, - .bind = ch9x00_bind, - .rx_fixup = ch9x00_rx_fixup, - .tx_fixup = ch9x00_tx_fixup, - .status = ch9x00_status, - .link_reset = ch9x00_link_reset, - .reset = ch9x00_link_reset, -}; - -static const struct usb_device_id ch9x00_products[] = { - { - USB_DEVICE( 0x1A86, 0xE091 ), - .driver_info = (unsigned long)&ch9x00_info, - }, - { - USB_DEVICE( 0x1A86, 0xE092 ), - .driver_info = (unsigned long)&ch9x00_info, - }, - { USB_DEVICE( 0x1A86, 0x8339 ), - .driver_info = (unsigned long)&ch9x00_info, - }, - {}, -}; -MODULE_DEVICE_TABLE( usb, ch9x00_products ); - -static struct usb_driver ch9x00_driver = { - .name = "ch9x00", - .id_table = ch9x00_products, - .probe = usbnet_probe, - .disconnect = usbnet_disconnect, - .suspend = usbnet_suspend, - .resume = usbnet_resume, -}; - -static int __init ch9x00_init( void ) -{ - printk( KERN_INFO "\tCH9x00 Driver Version:%s\n", DRIVER_VERSION); - return usb_register( &ch9x00_driver ); -} - -static void __exit ch9x00_exit( void ) -{ - usb_deregister( &ch9x00_driver ); -} - -module_init( ch9x00_init ); -module_exit( ch9x00_exit ); - -MODULE_DESCRIPTION( "USB to Network adapter CH9x00" ); -MODULE_LICENSE( "GPL" ); |