vserver 1.9.3
[linux-2.6.git] / drivers / usb / net / usbnet.c
index 58b3cf1..cca6e72 100644 (file)
  *             disconnect; other cleanups. (db)  Flush net1080 fifos
  *             after several sequential framing errors. (Johannes Erdfelt)
  * 22-aug-2003 AX8817X support (Dave Hollis).
+ * 14-jun-2004  Trivial patch for AX8817X based Buffalo LUA-U2-KTX in Japan
+ *             (Neil Bortnak)
  *
  *-------------------------------------------------------------------------*/
 
+// #define     DEBUG                   // error path messages, extra info
+// #define     VERBOSE                 // more; success messages
+
 #include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+#   define DEBUG
+#endif
 #include <linux/module.h>
 #include <linux/kmod.h>
 #include <linux/sched.h>
 #include <linux/mii.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
-
-
-// #define     DEBUG                   // error path messages, extra info
-// #define     VERBOSE                 // more; success messages
-#define        REALLY_QUEUE
-
-#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)
-#   define DEBUG
-#endif
 #include <linux/usb.h>
-
 #include <asm/io.h>
 #include <asm/scatterlist.h>
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
 
-
 #define DRIVER_VERSION         "25-Aug-2003"
 
+
 /*-------------------------------------------------------------------------*/
 
 /*
  * For high speed, each frame comfortably fits almost 36 max size
  * Ethernet packets (so queues should be bigger).
  */
-#ifdef REALLY_QUEUE
 #define        RX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4)
 #define        TX_QLEN(dev) (((dev)->udev->speed == USB_SPEED_HIGH) ? 60 : 4)
-#else
-#define        RX_QLEN(dev)            1
-#define        TX_QLEN(dev)            1
-#endif
 
 // packets are always ethernet inside
 // ... except they can be bigger (limit of 64K with NetChip framing)
 #define CONTROL_TIMEOUT_JIFFIES ((CONTROL_TIMEOUT_MS * HZ)/1000)
 
 // between wakeups
-#define UNLINK_TIMEOUT_JIFFIES ((3  /*ms*/ * HZ)/1000)
+#define UNLINK_TIMEOUT_MS      3
 
 /*-------------------------------------------------------------------------*/
 
@@ -275,7 +268,7 @@ static const char driver_name [] = "usbnet";
 
 /* use ethtool to change the level for any given device */
 static int msg_level = 1;
-MODULE_PARM (msg_level, "i");
+module_param (msg_level, int, 0);
 MODULE_PARM_DESC (msg_level, "Initial message level (default = 1)");
 
 
@@ -323,7 +316,7 @@ get_endpoints (struct usbnet *dev, struct usb_interface *intf)
        for (tmp = 0; tmp < intf->num_altsetting; tmp++) {
                unsigned        ep;
 
-               in = out = 0;
+               in = out = NULL;
                alt = intf->altsetting + tmp;
 
                /* take the first altsetting with in-bulk + out-bulk;
@@ -461,6 +454,15 @@ static const struct driver_info    an2720_info = {
 #define AX_MCAST_FILTER_SIZE           8
 #define AX_MAX_MCAST                   64
 
+#define AX_INTERRUPT_BUFSIZE           8
+
+/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
+struct ax8817x_data {
+       u8 multi_filter[AX_MCAST_FILTER_SIZE];
+       struct urb *int_urb;
+       u8 *int_buf;
+};
+
 static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
                            u16 size, void *data)
 {
@@ -503,6 +505,30 @@ static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
        usb_free_urb(urb);
 }
 
+static void ax8817x_interrupt_complete(struct urb *urb, struct pt_regs *regs)
+{
+       struct usbnet *dev = (struct usbnet *)urb->context;
+       struct ax8817x_data *data = (struct ax8817x_data *)&dev->data;
+       int link;
+
+       if (urb->status < 0) {
+               printk(KERN_DEBUG "ax8817x_interrupt_complete() failed with %d",
+                       urb->status);
+       } else {
+               if (data->int_buf[5] == 0x90) {
+                       link = data->int_buf[2] & 0x01;
+                       if (netif_carrier_ok(dev->net) != link) {
+                               if (link)
+                                       netif_carrier_on(dev->net);
+                               else
+                                       netif_carrier_off(dev->net);
+                               devdbg(dev, "ax8817x - Link Status is: %d", link);
+                       }
+               }
+               usb_submit_urb(data->int_urb, GFP_KERNEL);
+       }
+}
+
 static void ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
                                    u16 size, void *data)
 {
@@ -542,6 +568,7 @@ static void ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 i
 static void ax8817x_set_multicast(struct net_device *net)
 {
        struct usbnet *dev = (struct usbnet *) net->priv;
+       struct ax8817x_data *data = (struct ax8817x_data *)&dev->data;
        u8 rx_ctl = 0x8c;
 
        if (net->flags & IFF_PROMISC) {
@@ -556,25 +583,24 @@ static void ax8817x_set_multicast(struct net_device *net)
                 * for our 8 byte filter buffer
                 * to avoid allocating memory that
                 * is tricky to free later */
-               u8 *multi_filter = (u8 *)&dev->data;
                struct dev_mc_list *mc_list = net->mc_list;
                u32 crc_bits;
                int i;
 
-               memset(multi_filter, 0, AX_MCAST_FILTER_SIZE);
+               memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);
 
                /* Build the multicast hash filter. */
                for (i = 0; i < net->mc_count; i++) {
                        crc_bits =
                            ether_crc(ETH_ALEN,
                                      mc_list->dmi_addr) >> 26;
-                       multi_filter[crc_bits >> 3] |=
+                       data->multi_filter[crc_bits >> 3] |=
                            1 << (crc_bits & 7);
                        mc_list = mc_list->next;
                }
 
                ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
-                                  AX_MCAST_FILTER_SIZE, multi_filter);
+                                  AX_MCAST_FILTER_SIZE, data->multi_filter);
 
                rx_ctl |= 0x10;
        }
@@ -606,7 +632,7 @@ static void ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, i
        ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
 }
 
-void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
+static void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
 {
        struct usbnet *dev = (struct usbnet *)net->priv;
        u8 opt;
@@ -626,7 +652,7 @@ void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
        }
 }
 
-int ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
+static int ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
 {
        struct usbnet *dev = (struct usbnet *)net->priv;
        u8 opt = 0;
@@ -646,8 +672,8 @@ int ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
        return 0;
 }
 
-int ax8817x_get_eeprom(struct net_device *net, 
-                      struct ethtool_eeprom *eeprom, u8 *data)
+static int ax8817x_get_eeprom(struct net_device *net,
+                             struct ethtool_eeprom *eeprom, u8 *data)
 {
        struct usbnet *dev = (struct usbnet *)net->priv;
        u16 *ebuf = (u16 *)data;
@@ -676,13 +702,6 @@ static void ax8817x_get_drvinfo (struct net_device *net,
        info->eedump_len = 0x3e;
 }
 
-static u32 ax8817x_get_link (struct net_device *net)
-{
-       struct usbnet *dev = (struct usbnet *)net->priv;
-
-       return (u32)mii_link_ok(&dev->mii);
-}
-
 static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd)
 {
        struct usbnet *dev = (struct usbnet *)net->priv;
@@ -702,7 +721,7 @@ static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
    devices that may be connected at the same time. */
 static struct ethtool_ops ax8817x_ethtool_ops = {
        .get_drvinfo            = ax8817x_get_drvinfo,
-       .get_link               = ax8817x_get_link,
+       .get_link               = ethtool_op_get_link,
        .get_msglevel           = usbnet_get_msglevel,
        .set_msglevel           = usbnet_set_msglevel,
        .get_wol                = ax8817x_get_wol,
@@ -716,20 +735,41 @@ static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf)
 {
        int ret;
        u8 buf[6];
-       u16 *buf16 = (u16 *) buf;
        int i;
        unsigned long gpio_bits = dev->driver_info->data;
+       struct ax8817x_data *data = (struct ax8817x_data *)dev->data;
 
        dev->in = usb_rcvbulkpipe(dev->udev, 3);
        dev->out = usb_sndbulkpipe(dev->udev, 2);
 
+       // allocate irq urb
+       if ((data->int_urb = usb_alloc_urb (0, GFP_KERNEL)) == 0) {
+               dbg ("%s: cannot allocate interrupt URB",
+                       dev->net->name);
+               return -ENOMEM;
+       }
+       
+       if ((data->int_buf = kmalloc(AX_INTERRUPT_BUFSIZE, GFP_KERNEL)) == NULL) {
+               dbg ("%s: cannot allocate memory for interrupt buffer",
+                       dev->net->name);
+               usb_free_urb(data->int_urb);
+               return -ENOMEM;
+       }
+       memset(data->int_buf, 0, AX_INTERRUPT_BUFSIZE);
+
+       usb_fill_int_urb (data->int_urb, dev->udev,
+               usb_rcvintpipe (dev->udev, 1),
+               data->int_buf, AX_INTERRUPT_BUFSIZE,
+               ax8817x_interrupt_complete, dev,
+               dev->udev->speed == USB_SPEED_HIGH ? 8 : 100);
+
        /* Toggle the GPIOs in a manufacturer/model specific way */
        for (i = 2; i >= 0; i--) {
                if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
                                        (gpio_bits >> (i * 8)) & 0xff, 0, 0,
                                        buf)) < 0)
                        return ret;
-               wait_ms(5);
+               msleep(5);
        }
 
        if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf)) < 0) {
@@ -763,49 +803,37 @@ static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf)
        dev->mii.reg_num_mask = 0x1f;
        dev->mii.phy_id = buf[1];
 
-       if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf)) < 0) {
-               dbg("Failed to go to software MII mode: %02x", ret);
-               return ret;
-       }
-
-       *buf16 = cpu_to_le16(BMCR_RESET);
-       if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG,
-                                    dev->mii.phy_id, MII_BMCR, 2, buf16)) < 0) {
-               dbg("Failed to write MII reg - MII_BMCR: %02x", ret);
-               return ret;
-       }
+       dev->net->set_multicast_list = ax8817x_set_multicast;
+       dev->net->ethtool_ops = &ax8817x_ethtool_ops;
 
-       /* Advertise that we can do full-duplex pause */
-       *buf16 = cpu_to_le16(ADVERTISE_ALL | ADVERTISE_CSMA | 0x0400);
-       if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG,
-                                    dev->mii.phy_id, MII_ADVERTISE, 
-                                    2, buf16)) < 0) {
-               dbg("Failed to write MII_REG advertisement: %02x", ret);
-               return ret;
-       }
+       ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR,
+                       cpu_to_le16(BMCR_RESET));
+       ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
+                       cpu_to_le16(ADVERTISE_ALL | ADVERTISE_CSMA | 0x0400));
+       mii_nway_restart(&dev->mii);
 
-       *buf16 = cpu_to_le16(BMCR_ANENABLE | BMCR_ANRESTART);
-       if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG,
-                                    dev->mii.phy_id, MII_BMCR, 
-                                    2, buf16)) < 0) {
-               dbg("Failed to write MII reg autonegotiate: %02x", ret);
+       if((ret = usb_submit_urb(data->int_urb, GFP_KERNEL)) < 0) {
+               dbg("Failed to submit interrupt URB: %02x", ret);
+               usb_free_urb(data->int_urb);
                return ret;
        }
 
-       if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) {
-               dbg("Failed to set hardware MII: %02x", ret);
-               return ret;
-       }
+       return 0;
+}
 
-       dev->net->set_multicast_list = ax8817x_set_multicast;
-       dev->net->ethtool_ops = &ax8817x_ethtool_ops;
+static void ax8817x_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+       struct ax8817x_data *data = (struct ax8817x_data *)dev->data;
 
-       return 0;
+       usb_unlink_urb(data->int_urb);
+       usb_free_urb(data->int_urb);
+       kfree(data->int_buf);
 }
 
 static const struct driver_info ax8817x_info = {
        .description = "ASIX AX8817x USB 2.0 Ethernet",
        .bind = ax8817x_bind,
+       .unbind = ax8817x_unbind,
        .flags =  FLAG_ETHER,
        .data = 0x00130103,
 };
@@ -813,6 +841,7 @@ static const struct driver_info ax8817x_info = {
 static const struct driver_info dlink_dub_e100_info = {
        .description = "DLink DUB-E100 USB Ethernet",
        .bind = ax8817x_bind,
+       .unbind = ax8817x_unbind,
        .flags =  FLAG_ETHER,
        .data = 0x009f9d9f,
 };
@@ -820,6 +849,7 @@ static const struct driver_info dlink_dub_e100_info = {
 static const struct driver_info netgear_fa120_info = {
        .description = "Netgear FA-120 USB Ethernet",
        .bind = ax8817x_bind,
+       .unbind = ax8817x_unbind,
        .flags =  FLAG_ETHER,
        .data = 0x00130103,
 };
@@ -827,6 +857,7 @@ static const struct driver_info netgear_fa120_info = {
 static const struct driver_info hawking_uf200_info = {
        .description = "Hawking UF200 USB Ethernet",
        .bind = ax8817x_bind,
+       .unbind = ax8817x_unbind,
        .flags =  FLAG_ETHER,
        .data = 0x001f1d1f,
 };
@@ -906,8 +937,8 @@ struct ether_desc {
 
        u8      iMACAddress;
        u32     bmEthernetStatistics;
-       u16     wMaxSegmentSize;
-       u16     wNumberMCFilters;
+       __le16  wMaxSegmentSize;
+       __le16  wNumberMCFilters;
        u8      bNumberPowerFilters;
 } __attribute__ ((packed));
 
@@ -928,8 +959,8 @@ static struct usb_driver usbnet_driver;
  */
 static int generic_cdc_bind (struct usbnet *dev, struct usb_interface *intf)
 {
-       u8                              *buf = intf->altsetting->extra;
-       int                             len = intf->altsetting->extralen;
+       u8                              *buf = intf->cur_altsetting->extra;
+       int                             len = intf->cur_altsetting->extralen;
        struct usb_interface_descriptor *d;
        struct cdc_state                *info = (void *) &dev->data;
        int                             status;
@@ -955,7 +986,7 @@ static int generic_cdc_bind (struct usbnet *dev, struct usb_interface *intf)
        /* this assumes that if there's a non-RNDIS vendor variant
         * of cdc-acm, it'll fail RNDIS requests cleanly.
         */
-       rndis = (intf->altsetting->desc.bInterfaceProtocol == 0xff);
+       rndis = (intf->cur_altsetting->desc.bInterfaceProtocol == 0xff);
 
        memset (info, 0, sizeof *info);
        info->control = intf;
@@ -1006,7 +1037,7 @@ static int generic_cdc_bind (struct usbnet *dev, struct usb_interface *intf)
                        if (!info->control || !info->data) {
                                dev_dbg (&intf->dev,
                                        "master #%u/%p slave #%u/%p\n",
-                                       info->u->bMasterInterface0
+                                       info->u->bMasterInterface0,
                                        info->control,
                                        info->u->bSlaveInterface0,
                                        info->data);
@@ -1025,7 +1056,7 @@ static int generic_cdc_bind (struct usbnet *dev, struct usb_interface *intf)
                        }
 
                        /* a data interface altsetting does the real i/o */
-                       d = &info->data->altsetting->desc;
+                       d = &info->data->cur_altsetting->desc;
                        if (d->bInterfaceClass != USB_CLASS_CDC_DATA) {
                                dev_dbg (&intf->dev, "slave class %u\n",
                                        d->bInterfaceClass);
@@ -1043,7 +1074,7 @@ static int generic_cdc_bind (struct usbnet *dev, struct usb_interface *intf)
                                        info->u->bLength);
                                goto bad_desc;
                        }
-                       dev->net->mtu = cpu_to_le16p (
+                       dev->net->mtu = le16_to_cpup (
                                                &info->ether->wMaxSegmentSize)
                                        - ETH_HLEN;
                        /* because of Zaurus, we may be ignoring the host
@@ -1093,7 +1124,7 @@ static void cdc_unbind (struct usbnet *dev, struct usb_interface *intf)
                /* ensure immediate exit from usbnet_disconnect */
                usb_set_intfdata(info->data, NULL);
                usb_driver_release_interface (&usbnet_driver, info->data);
-               info->data = 0;
+               info->data = NULL;
        }
 
        /* and vice versa (just in case) */
@@ -1101,7 +1132,7 @@ static void cdc_unbind (struct usbnet *dev, struct usb_interface *intf)
                /* ensure immediate exit from usbnet_disconnect */
                usb_set_intfdata(info->control, NULL);
                usb_driver_release_interface (&usbnet_driver, info->control);
-               info->control = 0;
+               info->control = NULL;
        }
 }
 
@@ -1142,10 +1173,13 @@ get_ethernet_addr (struct usbnet *dev, struct ether_desc *e)
        unsigned char   buf [13];
 
        tmp = usb_string (dev->udev, e->iMACAddress, buf, sizeof buf);
-       if (tmp < 0)
+       if (tmp != 12) {
+               dev_dbg (&dev->udev->dev,
+                       "bad MAC string %d fetch, %d\n", e->iMACAddress, tmp);
+               if (tmp >= 0)
+                       tmp = -EINVAL;
                return tmp;
-       else if (tmp != 12)
-               return -EINVAL;
+       }
        for (i = tmp = 0; i < 6; i++, tmp += 2)
                dev->net->dev_addr [i] =
                         (nibble (buf [tmp]) << 4) + nibble (buf [tmp + 1]);
@@ -1163,6 +1197,7 @@ static int cdc_bind (struct usbnet *dev, struct usb_interface *intf)
 
        status = get_ethernet_addr (dev, info->ether);
        if (status < 0) {
+               usb_set_intfdata(info->data, NULL);
                usb_driver_release_interface (&usbnet_driver, info->data);
                return status;
        }
@@ -1644,7 +1679,7 @@ nc_vendor_write (struct usbnet *dev, u8 req, u8 regnum, u16 value)
                req,
                USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                value, regnum,
-               0, 0,                   // data is in setup packet
+               NULL, 0,                        // data is in setup packet
                CONTROL_TIMEOUT_JIFFIES);
 }
 
@@ -2087,7 +2122,7 @@ pl_vendor_req (struct usbnet *dev, u8 req, u8 val, u8 index)
                req,
                USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                val, index,
-               0, 0,
+               NULL, 0,
                CONTROL_TIMEOUT_JIFFIES);
 }
 
@@ -2421,7 +2456,7 @@ static void rx_complete (struct urb *urb, struct pt_regs *regs)
 
        skb_put (skb, urb->actual_length);
        entry->state = rx_done;
-       entry->urb = 0;
+       entry->urb = NULL;
 
        switch (urb_status) {
            // success
@@ -2465,7 +2500,7 @@ static void rx_complete (struct urb *urb, struct pt_regs *regs)
 block:
                entry->state = rx_cleanup;
                entry->urb = urb;
-               urb = 0;
+               urb = NULL;
                break;
 
            // data overrun ... flush fifo?
@@ -2556,11 +2591,10 @@ static int usbnet_stop (struct net_device *net)
        while (skb_queue_len (&dev->rxq)
                        && skb_queue_len (&dev->txq)
                        && skb_queue_len (&dev->done)) {
-               set_current_state (TASK_UNINTERRUPTIBLE);
-               schedule_timeout (UNLINK_TIMEOUT_JIFFIES);
+               msleep(UNLINK_TIMEOUT_MS);
                devdbg (dev, "waited for %d urb completions", temp);
        }
-       dev->wait = 0;
+       dev->wait = NULL;
        remove_wait_queue (&unlink_wakeup, &wait); 
 
        /* deferred work (task, timer, softirq) must also stop.
@@ -2674,9 +2708,7 @@ static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
        struct usbnet *dev = (struct usbnet *)net->priv;
 
        if (dev->mii.mdio_read != NULL && dev->mii.mdio_write != NULL)
-               return generic_mii_ioctl(&dev->mii,
-                               (struct mii_ioctl_data *) &rq->ifr_data,
-                               cmd, NULL);
+               return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
        }
 #endif
        return -EOPNOTSUPP;
@@ -2721,7 +2753,7 @@ kevent (void *data)
 
        /* tasklet could resubmit itself forever if memory is tight */
        if (test_bit (EVENT_RX_MEMORY, &dev->flags)) {
-               struct urb      *urb = 0;
+               struct urb      *urb = NULL;
 
                if (netif_running (dev->net))
                        urb = usb_alloc_urb (0, GFP_KERNEL);
@@ -2776,7 +2808,7 @@ static void tx_complete (struct urb *urb, struct pt_regs *regs)
                }
        }
 
-       urb->dev = 0;
+       urb->dev = NULL;
        entry->state = tx_done;
        defer_bh (dev, skb);
 }
@@ -2800,13 +2832,13 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
        struct usbnet           *dev = (struct usbnet *) net->priv;
        int                     length;
        int                     retval = NET_XMIT_SUCCESS;
-       struct urb              *urb = 0;
+       struct urb              *urb = NULL;
        struct skb_data         *entry;
        struct driver_info      *info = dev->driver_info;
        unsigned long           flags;
 #ifdef CONFIG_USB_NET1080
-       struct nc_header        *header = 0;
-       struct nc_trailer       *trailer = 0;
+       struct nc_header        *header = NULL;
+       struct nc_trailer       *trailer = NULL;
 #endif /* CONFIG_USB_NET1080 */
 
        // some devices want funky USB-level framing, for
@@ -3014,7 +3046,7 @@ static struct ethtool_ops usbnet_ethtool_ops;
 
 // precondition: never called in_interrupt
 
-int
+static int
 usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 {
        struct usbnet                   *dev;
@@ -3204,10 +3236,22 @@ static const struct usb_device_id       products [] = {
        // Hawking UF200, TrendNet TU2-ET100
        USB_DEVICE (0x07b8, 0x420a),
        .driver_info =  (unsigned long) &hawking_uf200_info,
+}, {
+        // Billionton Systems, USB2AR 
+        USB_DEVICE (0x08dd, 0x90ff),
+        .driver_info =  (unsigned long) &ax8817x_info,
 }, {
        // ATEN UC210T
        USB_DEVICE (0x0557, 0x2009),
        .driver_info =  (unsigned long) &ax8817x_info,
+}, {
+       // Buffalo LUA-U2-KTX
+       USB_DEVICE (0x0411, 0x003d),
+       .driver_info =  (unsigned long) &ax8817x_info,
+}, {
+       // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
+       USB_DEVICE (0x6189, 0x182d),
+       .driver_info =  (unsigned long) &ax8817x_info,
 },
 #endif