Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * USB 10M/100M ethernet adapter
0003  *
0004  * This file is licensed under the terms of the GNU General Public License
0005  * version 2. This program is licensed "as is" without any warranty of any
0006  * kind, whether express or implied
0007  *
0008  */
0009 
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/sched.h>
0013 #include <linux/stddef.h>
0014 #include <linux/init.h>
0015 #include <linux/netdevice.h>
0016 #include <linux/etherdevice.h>
0017 #include <linux/ethtool.h>
0018 #include <linux/mii.h>
0019 #include <linux/usb.h>
0020 #include <linux/crc32.h>
0021 #include <linux/usb/usbnet.h>
0022 #include <linux/slab.h>
0023 
0024 #define CH9200_VID      0x1A86
0025 #define CH9200_PID_E092     0xE092
0026 
0027 #define CTRL_TIMEOUT_MS     1000
0028 
0029 #define CONTROL_TIMEOUT_MS 1000
0030 
0031 #define REQUEST_READ    0x0E
0032 #define REQUEST_WRITE   0x0F
0033 
0034 /* Address space:
0035  * 00-63 : MII
0036  * 64-128: MAC
0037  *
0038  * Note: all accesses must be 16-bit
0039  */
0040 
0041 #define MAC_REG_CTRL 64
0042 #define MAC_REG_STATUS 66
0043 #define MAC_REG_INTERRUPT_MASK 68
0044 #define MAC_REG_PHY_COMMAND 70
0045 #define MAC_REG_PHY_DATA 72
0046 #define MAC_REG_STATION_L 74
0047 #define MAC_REG_STATION_M 76
0048 #define MAC_REG_STATION_H 78
0049 #define MAC_REG_HASH_L 80
0050 #define MAC_REG_HASH_M1 82
0051 #define MAC_REG_HASH_M2 84
0052 #define MAC_REG_HASH_H 86
0053 #define MAC_REG_THRESHOLD 88
0054 #define MAC_REG_FIFO_DEPTH 90
0055 #define MAC_REG_PAUSE 92
0056 #define MAC_REG_FLOW_CONTROL 94
0057 
0058 /* Control register bits
0059  *
0060  * Note: bits 13 and 15 are reserved
0061  */
0062 #define LOOPBACK        (0x01 << 14)
0063 #define BASE100X        (0x01 << 12)
0064 #define MBPS_10         (0x01 << 11)
0065 #define DUPLEX_MODE     (0x01 << 10)
0066 #define PAUSE_FRAME     (0x01 << 9)
0067 #define PROMISCUOUS     (0x01 << 8)
0068 #define MULTICAST       (0x01 << 7)
0069 #define BROADCAST       (0x01 << 6)
0070 #define HASH            (0x01 << 5)
0071 #define APPEND_PAD      (0x01 << 4)
0072 #define APPEND_CRC      (0x01 << 3)
0073 #define TRANSMITTER_ACTION  (0x01 << 2)
0074 #define RECEIVER_ACTION     (0x01 << 1)
0075 #define DMA_ACTION      (0x01 << 0)
0076 
0077 /* Status register bits
0078  *
0079  * Note: bits 7-15 are reserved
0080  */
0081 #define ALIGNMENT       (0x01 << 6)
0082 #define FIFO_OVER_RUN       (0x01 << 5)
0083 #define FIFO_UNDER_RUN      (0x01 << 4)
0084 #define RX_ERROR        (0x01 << 3)
0085 #define RX_COMPLETE     (0x01 << 2)
0086 #define TX_ERROR        (0x01 << 1)
0087 #define TX_COMPLETE     (0x01 << 0)
0088 
0089 /* FIFO depth register bits
0090  *
0091  * Note: bits 6 and 14 are reserved
0092  */
0093 
0094 #define ETH_TXBD        (0x01 << 15)
0095 #define ETN_TX_FIFO_DEPTH   (0x01 << 8)
0096 #define ETH_RXBD        (0x01 << 7)
0097 #define ETH_RX_FIFO_DEPTH   (0x01 << 0)
0098 
0099 static int control_read(struct usbnet *dev,
0100             unsigned char request, unsigned short value,
0101             unsigned short index, void *data, unsigned short size,
0102             int timeout)
0103 {
0104     unsigned char *buf = NULL;
0105     unsigned char request_type;
0106     int err = 0;
0107 
0108     if (request == REQUEST_READ)
0109         request_type = (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER);
0110     else
0111         request_type = (USB_DIR_IN | USB_TYPE_VENDOR |
0112                 USB_RECIP_DEVICE);
0113 
0114     netdev_dbg(dev->net, "%s() index=0x%02x size=%d\n",
0115            __func__, index, size);
0116 
0117     buf = kmalloc(size, GFP_KERNEL);
0118     if (!buf) {
0119         err = -ENOMEM;
0120         goto err_out;
0121     }
0122 
0123     err = usb_control_msg(dev->udev,
0124                   usb_rcvctrlpipe(dev->udev, 0),
0125                   request, request_type, value, index, buf, size,
0126                   timeout);
0127     if (err == size)
0128         memcpy(data, buf, size);
0129     else if (err >= 0)
0130         err = -EINVAL;
0131     kfree(buf);
0132 
0133 err_out:
0134     return err;
0135 }
0136 
0137 static int control_write(struct usbnet *dev, unsigned char request,
0138              unsigned short value, unsigned short index,
0139              void *data, unsigned short size, int timeout)
0140 {
0141     unsigned char *buf = NULL;
0142     unsigned char request_type;
0143     int err = 0;
0144 
0145     if (request == REQUEST_WRITE)
0146         request_type = (USB_DIR_OUT | USB_TYPE_VENDOR |
0147                 USB_RECIP_OTHER);
0148     else
0149         request_type = (USB_DIR_OUT | USB_TYPE_VENDOR |
0150                 USB_RECIP_DEVICE);
0151 
0152     netdev_dbg(dev->net, "%s() index=0x%02x size=%d\n",
0153            __func__, index, size);
0154 
0155     if (data) {
0156         buf = kmemdup(data, size, GFP_KERNEL);
0157         if (!buf) {
0158             err = -ENOMEM;
0159             goto err_out;
0160         }
0161     }
0162 
0163     err = usb_control_msg(dev->udev,
0164                   usb_sndctrlpipe(dev->udev, 0),
0165                   request, request_type, value, index, buf, size,
0166                   timeout);
0167     if (err >= 0 && err < size)
0168         err = -EINVAL;
0169     kfree(buf);
0170 
0171     return 0;
0172 
0173 err_out:
0174     return err;
0175 }
0176 
0177 static int ch9200_mdio_read(struct net_device *netdev, int phy_id, int loc)
0178 {
0179     struct usbnet *dev = netdev_priv(netdev);
0180     unsigned char buff[2];
0181 
0182     netdev_dbg(netdev, "%s phy_id:%02x loc:%02x\n",
0183            __func__, phy_id, loc);
0184 
0185     if (phy_id != 0)
0186         return -ENODEV;
0187 
0188     control_read(dev, REQUEST_READ, 0, loc * 2, buff, 0x02,
0189              CONTROL_TIMEOUT_MS);
0190 
0191     return (buff[0] | buff[1] << 8);
0192 }
0193 
0194 static void ch9200_mdio_write(struct net_device *netdev,
0195                   int phy_id, int loc, int val)
0196 {
0197     struct usbnet *dev = netdev_priv(netdev);
0198     unsigned char buff[2];
0199 
0200     netdev_dbg(netdev, "%s() phy_id=%02x loc:%02x\n",
0201            __func__, phy_id, loc);
0202 
0203     if (phy_id != 0)
0204         return;
0205 
0206     buff[0] = (unsigned char)val;
0207     buff[1] = (unsigned char)(val >> 8);
0208 
0209     control_write(dev, REQUEST_WRITE, 0, loc * 2, buff, 0x02,
0210               CONTROL_TIMEOUT_MS);
0211 }
0212 
0213 static int ch9200_link_reset(struct usbnet *dev)
0214 {
0215     struct ethtool_cmd ecmd;
0216 
0217     mii_check_media(&dev->mii, 1, 1);
0218     mii_ethtool_gset(&dev->mii, &ecmd);
0219 
0220     netdev_dbg(dev->net, "%s() speed:%d duplex:%d\n",
0221            __func__, ecmd.speed, ecmd.duplex);
0222 
0223     return 0;
0224 }
0225 
0226 static void ch9200_status(struct usbnet *dev, struct urb *urb)
0227 {
0228     int link;
0229     unsigned char *buf;
0230 
0231     if (urb->actual_length < 16)
0232         return;
0233 
0234     buf = urb->transfer_buffer;
0235     link = !!(buf[0] & 0x01);
0236 
0237     if (link) {
0238         netif_carrier_on(dev->net);
0239         usbnet_defer_kevent(dev, EVENT_LINK_RESET);
0240     } else {
0241         netif_carrier_off(dev->net);
0242     }
0243 }
0244 
0245 static struct sk_buff *ch9200_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
0246                        gfp_t flags)
0247 {
0248     int i = 0;
0249     int len = 0;
0250     int tx_overhead = 0;
0251 
0252     tx_overhead = 0x40;
0253 
0254     len = skb->len;
0255     if (skb_cow_head(skb, tx_overhead)) {
0256         dev_kfree_skb_any(skb);
0257         return NULL;
0258     }
0259 
0260     __skb_push(skb, tx_overhead);
0261     /* usbnet adds padding if length is a multiple of packet size
0262      * if so, adjust length value in header
0263      */
0264     if ((skb->len % dev->maxpacket) == 0)
0265         len++;
0266 
0267     skb->data[0] = len;
0268     skb->data[1] = len >> 8;
0269     skb->data[2] = 0x00;
0270     skb->data[3] = 0x80;
0271 
0272     for (i = 4; i < 48; i++)
0273         skb->data[i] = 0x00;
0274 
0275     skb->data[48] = len;
0276     skb->data[49] = len >> 8;
0277     skb->data[50] = 0x00;
0278     skb->data[51] = 0x80;
0279 
0280     for (i = 52; i < 64; i++)
0281         skb->data[i] = 0x00;
0282 
0283     return skb;
0284 }
0285 
0286 static int ch9200_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
0287 {
0288     int len = 0;
0289     int rx_overhead = 0;
0290 
0291     rx_overhead = 64;
0292 
0293     if (unlikely(skb->len < rx_overhead)) {
0294         dev_err(&dev->udev->dev, "unexpected tiny rx frame\n");
0295         return 0;
0296     }
0297 
0298     len = (skb->data[skb->len - 16] | skb->data[skb->len - 15] << 8);
0299     skb_trim(skb, len);
0300 
0301     return 1;
0302 }
0303 
0304 static int get_mac_address(struct usbnet *dev, unsigned char *data)
0305 {
0306     int err = 0;
0307     unsigned char mac_addr[0x06];
0308     int rd_mac_len = 0;
0309 
0310     netdev_dbg(dev->net, "%s:\n\tusbnet VID:%0x PID:%0x\n", __func__,
0311            le16_to_cpu(dev->udev->descriptor.idVendor),
0312            le16_to_cpu(dev->udev->descriptor.idProduct));
0313 
0314     memset(mac_addr, 0, sizeof(mac_addr));
0315     rd_mac_len = control_read(dev, REQUEST_READ, 0,
0316                   MAC_REG_STATION_L, mac_addr, 0x02,
0317                   CONTROL_TIMEOUT_MS);
0318     rd_mac_len += control_read(dev, REQUEST_READ, 0, MAC_REG_STATION_M,
0319                    mac_addr + 2, 0x02, CONTROL_TIMEOUT_MS);
0320     rd_mac_len += control_read(dev, REQUEST_READ, 0, MAC_REG_STATION_H,
0321                    mac_addr + 4, 0x02, CONTROL_TIMEOUT_MS);
0322     if (rd_mac_len != ETH_ALEN)
0323         err = -EINVAL;
0324 
0325     data[0] = mac_addr[5];
0326     data[1] = mac_addr[4];
0327     data[2] = mac_addr[3];
0328     data[3] = mac_addr[2];
0329     data[4] = mac_addr[1];
0330     data[5] = mac_addr[0];
0331 
0332     return err;
0333 }
0334 
0335 static int ch9200_bind(struct usbnet *dev, struct usb_interface *intf)
0336 {
0337     int retval = 0;
0338     unsigned char data[2];
0339     u8 addr[ETH_ALEN];
0340 
0341     retval = usbnet_get_endpoints(dev, intf);
0342     if (retval)
0343         return retval;
0344 
0345     dev->mii.dev = dev->net;
0346     dev->mii.mdio_read = ch9200_mdio_read;
0347     dev->mii.mdio_write = ch9200_mdio_write;
0348     dev->mii.reg_num_mask = 0x1f;
0349 
0350     dev->mii.phy_id_mask = 0x1f;
0351 
0352     dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
0353     dev->rx_urb_size = 24 * 64 + 16;
0354     mii_nway_restart(&dev->mii);
0355 
0356     data[0] = 0x01;
0357     data[1] = 0x0F;
0358     retval = control_write(dev, REQUEST_WRITE, 0, MAC_REG_THRESHOLD, data,
0359                    0x02, CONTROL_TIMEOUT_MS);
0360 
0361     data[0] = 0xA0;
0362     data[1] = 0x90;
0363     retval = control_write(dev, REQUEST_WRITE, 0, MAC_REG_FIFO_DEPTH, data,
0364                    0x02, CONTROL_TIMEOUT_MS);
0365 
0366     data[0] = 0x30;
0367     data[1] = 0x00;
0368     retval = control_write(dev, REQUEST_WRITE, 0, MAC_REG_PAUSE, data,
0369                    0x02, CONTROL_TIMEOUT_MS);
0370 
0371     data[0] = 0x17;
0372     data[1] = 0xD8;
0373     retval = control_write(dev, REQUEST_WRITE, 0, MAC_REG_FLOW_CONTROL,
0374                    data, 0x02, CONTROL_TIMEOUT_MS);
0375 
0376     /* Undocumented register */
0377     data[0] = 0x01;
0378     data[1] = 0x00;
0379     retval = control_write(dev, REQUEST_WRITE, 0, 254, data, 0x02,
0380                    CONTROL_TIMEOUT_MS);
0381 
0382     data[0] = 0x5F;
0383     data[1] = 0x0D;
0384     retval = control_write(dev, REQUEST_WRITE, 0, MAC_REG_CTRL, data, 0x02,
0385                    CONTROL_TIMEOUT_MS);
0386 
0387     retval = get_mac_address(dev, addr);
0388     eth_hw_addr_set(dev->net, addr);
0389 
0390     return retval;
0391 }
0392 
0393 static const struct driver_info ch9200_info = {
0394     .description = "CH9200 USB to Network Adaptor",
0395     .flags = FLAG_ETHER,
0396     .bind = ch9200_bind,
0397     .rx_fixup = ch9200_rx_fixup,
0398     .tx_fixup = ch9200_tx_fixup,
0399     .status = ch9200_status,
0400     .link_reset = ch9200_link_reset,
0401     .reset = ch9200_link_reset,
0402 };
0403 
0404 static const struct usb_device_id ch9200_products[] = {
0405     {
0406      USB_DEVICE(0x1A86, 0xE092),
0407      .driver_info = (unsigned long)&ch9200_info,
0408      },
0409     {},
0410 };
0411 
0412 MODULE_DEVICE_TABLE(usb, ch9200_products);
0413 
0414 static struct usb_driver ch9200_driver = {
0415     .name = "ch9200",
0416     .id_table = ch9200_products,
0417     .probe = usbnet_probe,
0418     .disconnect = usbnet_disconnect,
0419     .suspend = usbnet_suspend,
0420     .resume = usbnet_resume,
0421 };
0422 
0423 module_usb_driver(ch9200_driver);
0424 
0425 MODULE_DESCRIPTION("QinHeng CH9200 USB Network device");
0426 MODULE_LICENSE("GPL");