0001
0002
0003
0004
0005
0006 #include <linux/module.h>
0007 #include <linux/netdevice.h>
0008 #include <linux/etherdevice.h>
0009 #include <linux/ethtool.h>
0010 #include <linux/workqueue.h>
0011 #include <linux/slab.h>
0012 #include <linux/mii.h>
0013 #include <linux/usb.h>
0014 #include <linux/usb/cdc.h>
0015 #include <linux/usb/usbnet.h>
0016 #include <linux/usb/rndis_host.h>
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 void rndis_status(struct usbnet *dev, struct urb *urb)
0046 {
0047 netdev_dbg(dev->net, "rndis status urb, len %d stat %d\n",
0048 urb->actual_length, urb->status);
0049
0050
0051 }
0052 EXPORT_SYMBOL_GPL(rndis_status);
0053
0054
0055
0056
0057 static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
0058 int buflen)
0059 {
0060 struct cdc_state *info = (void *)&dev->data;
0061 struct device *udev = &info->control->dev;
0062
0063 if (dev->driver_info->indication) {
0064 dev->driver_info->indication(dev, msg, buflen);
0065 } else {
0066 u32 status = le32_to_cpu(msg->status);
0067
0068 switch (status) {
0069 case RNDIS_STATUS_MEDIA_CONNECT:
0070 dev_info(udev, "rndis media connect\n");
0071 break;
0072 case RNDIS_STATUS_MEDIA_DISCONNECT:
0073 dev_info(udev, "rndis media disconnect\n");
0074 break;
0075 default:
0076 dev_info(udev, "rndis indication: 0x%08x\n", status);
0077 }
0078 }
0079 }
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
0092 {
0093 struct cdc_state *info = (void *) &dev->data;
0094 struct usb_cdc_notification notification;
0095 int master_ifnum;
0096 int retval;
0097 int partial;
0098 unsigned count;
0099 u32 xid = 0, msg_len, request_id, msg_type, rsp,
0100 status;
0101
0102
0103
0104
0105
0106 msg_type = le32_to_cpu(buf->msg_type);
0107
0108
0109 if (likely(msg_type != RNDIS_MSG_HALT && msg_type != RNDIS_MSG_RESET)) {
0110 xid = dev->xid++;
0111 if (!xid)
0112 xid = dev->xid++;
0113 buf->request_id = (__force __le32) xid;
0114 }
0115 master_ifnum = info->control->cur_altsetting->desc.bInterfaceNumber;
0116 retval = usb_control_msg(dev->udev,
0117 usb_sndctrlpipe(dev->udev, 0),
0118 USB_CDC_SEND_ENCAPSULATED_COMMAND,
0119 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0120 0, master_ifnum,
0121 buf, le32_to_cpu(buf->msg_len),
0122 RNDIS_CONTROL_TIMEOUT_MS);
0123 if (unlikely(retval < 0 || xid == 0))
0124 return retval;
0125
0126
0127
0128 if (dev->driver_info->data & RNDIS_DRIVER_DATA_POLL_STATUS) {
0129 retval = usb_interrupt_msg(
0130 dev->udev,
0131 usb_rcvintpipe(dev->udev,
0132 dev->status->desc.bEndpointAddress),
0133 ¬ification, sizeof(notification), &partial,
0134 RNDIS_CONTROL_TIMEOUT_MS);
0135 if (unlikely(retval < 0))
0136 return retval;
0137 }
0138
0139
0140 rsp = le32_to_cpu(buf->msg_type) | RNDIS_MSG_COMPLETION;
0141 for (count = 0; count < 10; count++) {
0142 memset(buf, 0, CONTROL_BUFFER_SIZE);
0143 retval = usb_control_msg(dev->udev,
0144 usb_rcvctrlpipe(dev->udev, 0),
0145 USB_CDC_GET_ENCAPSULATED_RESPONSE,
0146 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0147 0, master_ifnum,
0148 buf, buflen,
0149 RNDIS_CONTROL_TIMEOUT_MS);
0150 if (likely(retval >= 8)) {
0151 msg_type = le32_to_cpu(buf->msg_type);
0152 msg_len = le32_to_cpu(buf->msg_len);
0153 status = le32_to_cpu(buf->status);
0154 request_id = (__force u32) buf->request_id;
0155 if (likely(msg_type == rsp)) {
0156 if (likely(request_id == xid)) {
0157 if (unlikely(rsp == RNDIS_MSG_RESET_C))
0158 return 0;
0159 if (likely(RNDIS_STATUS_SUCCESS ==
0160 status))
0161 return 0;
0162 dev_dbg(&info->control->dev,
0163 "rndis reply status %08x\n",
0164 status);
0165 return -EL3RST;
0166 }
0167 dev_dbg(&info->control->dev,
0168 "rndis reply id %d expected %d\n",
0169 request_id, xid);
0170
0171 } else switch (msg_type) {
0172 case RNDIS_MSG_INDICATE:
0173 rndis_msg_indicate(dev, (void *)buf, buflen);
0174 break;
0175 case RNDIS_MSG_KEEPALIVE: {
0176 struct rndis_keepalive_c *msg = (void *)buf;
0177
0178 msg->msg_type = cpu_to_le32(RNDIS_MSG_KEEPALIVE_C);
0179 msg->msg_len = cpu_to_le32(sizeof *msg);
0180 msg->status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
0181 retval = usb_control_msg(dev->udev,
0182 usb_sndctrlpipe(dev->udev, 0),
0183 USB_CDC_SEND_ENCAPSULATED_COMMAND,
0184 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0185 0, master_ifnum,
0186 msg, sizeof *msg,
0187 RNDIS_CONTROL_TIMEOUT_MS);
0188 if (unlikely(retval < 0))
0189 dev_dbg(&info->control->dev,
0190 "rndis keepalive err %d\n",
0191 retval);
0192 }
0193 break;
0194 default:
0195 dev_dbg(&info->control->dev,
0196 "unexpected rndis msg %08x len %d\n",
0197 le32_to_cpu(buf->msg_type), msg_len);
0198 }
0199 } else {
0200
0201 dev_dbg(&info->control->dev,
0202 "rndis response error, code %d\n", retval);
0203 }
0204 msleep(40);
0205 }
0206 dev_dbg(&info->control->dev, "rndis response timeout\n");
0207 return -ETIMEDOUT;
0208 }
0209 EXPORT_SYMBOL_GPL(rndis_command);
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227 static int rndis_query(struct usbnet *dev, struct usb_interface *intf,
0228 void *buf, u32 oid, u32 in_len,
0229 void **reply, int *reply_len)
0230 {
0231 int retval;
0232 union {
0233 void *buf;
0234 struct rndis_msg_hdr *header;
0235 struct rndis_query *get;
0236 struct rndis_query_c *get_c;
0237 } u;
0238 u32 off, len;
0239
0240 u.buf = buf;
0241
0242 memset(u.get, 0, sizeof *u.get + in_len);
0243 u.get->msg_type = cpu_to_le32(RNDIS_MSG_QUERY);
0244 u.get->msg_len = cpu_to_le32(sizeof *u.get + in_len);
0245 u.get->oid = cpu_to_le32(oid);
0246 u.get->len = cpu_to_le32(in_len);
0247 u.get->offset = cpu_to_le32(20);
0248
0249 retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
0250 if (unlikely(retval < 0)) {
0251 dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) failed, %d\n",
0252 oid, retval);
0253 return retval;
0254 }
0255
0256 off = le32_to_cpu(u.get_c->offset);
0257 len = le32_to_cpu(u.get_c->len);
0258 if (unlikely((8 + off + len) > CONTROL_BUFFER_SIZE))
0259 goto response_error;
0260
0261 if (*reply_len != -1 && len != *reply_len)
0262 goto response_error;
0263
0264 *reply = (unsigned char *) &u.get_c->request_id + off;
0265 *reply_len = len;
0266
0267 return retval;
0268
0269 response_error:
0270 dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) "
0271 "invalid response - off %d len %d\n",
0272 oid, off, len);
0273 return -EDOM;
0274 }
0275
0276
0277 static const struct net_device_ops rndis_netdev_ops = {
0278 .ndo_open = usbnet_open,
0279 .ndo_stop = usbnet_stop,
0280 .ndo_start_xmit = usbnet_start_xmit,
0281 .ndo_tx_timeout = usbnet_tx_timeout,
0282 .ndo_get_stats64 = dev_get_tstats64,
0283 .ndo_set_mac_address = eth_mac_addr,
0284 .ndo_validate_addr = eth_validate_addr,
0285 };
0286
0287 int
0288 generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
0289 {
0290 int retval;
0291 struct net_device *net = dev->net;
0292 struct cdc_state *info = (void *) &dev->data;
0293 union {
0294 void *buf;
0295 struct rndis_msg_hdr *header;
0296 struct rndis_init *init;
0297 struct rndis_init_c *init_c;
0298 struct rndis_query *get;
0299 struct rndis_query_c *get_c;
0300 struct rndis_set *set;
0301 struct rndis_set_c *set_c;
0302 struct rndis_halt *halt;
0303 } u;
0304 u32 tmp;
0305 __le32 phym_unspec, *phym;
0306 int reply_len;
0307 unsigned char *bp;
0308
0309
0310 u.buf = kmalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
0311 if (!u.buf)
0312 return -ENOMEM;
0313 retval = usbnet_generic_cdc_bind(dev, intf);
0314 if (retval < 0)
0315 goto fail;
0316
0317 u.init->msg_type = cpu_to_le32(RNDIS_MSG_INIT);
0318 u.init->msg_len = cpu_to_le32(sizeof *u.init);
0319 u.init->major_version = cpu_to_le32(1);
0320 u.init->minor_version = cpu_to_le32(0);
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333 net->hard_header_len += sizeof (struct rndis_data_hdr);
0334 dev->hard_mtu = net->mtu + net->hard_header_len;
0335
0336 dev->maxpacket = usb_maxpacket(dev->udev, dev->out);
0337 if (dev->maxpacket == 0) {
0338 netif_dbg(dev, probe, dev->net,
0339 "dev->maxpacket can't be 0\n");
0340 retval = -EINVAL;
0341 goto fail_and_release;
0342 }
0343
0344 dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1);
0345 dev->rx_urb_size &= ~(dev->maxpacket - 1);
0346 u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size);
0347
0348 net->netdev_ops = &rndis_netdev_ops;
0349
0350 retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
0351 if (unlikely(retval < 0)) {
0352
0353 dev_err(&intf->dev, "RNDIS init failed, %d\n", retval);
0354 goto fail_and_release;
0355 }
0356 tmp = le32_to_cpu(u.init_c->max_transfer_size);
0357 if (tmp < dev->hard_mtu) {
0358 if (tmp <= net->hard_header_len) {
0359 dev_err(&intf->dev,
0360 "dev can't take %u byte packets (max %u)\n",
0361 dev->hard_mtu, tmp);
0362 retval = -EINVAL;
0363 goto halt_fail_and_release;
0364 }
0365 dev_warn(&intf->dev,
0366 "dev can't take %u byte packets (max %u), "
0367 "adjusting MTU to %u\n",
0368 dev->hard_mtu, tmp, tmp - net->hard_header_len);
0369 dev->hard_mtu = tmp;
0370 net->mtu = dev->hard_mtu - net->hard_header_len;
0371 }
0372
0373
0374 dev_dbg(&intf->dev,
0375 "hard mtu %u (%u from dev), rx buflen %zu, align %d\n",
0376 dev->hard_mtu, tmp, dev->rx_urb_size,
0377 1 << le32_to_cpu(u.init_c->packet_alignment));
0378
0379
0380
0381 if (dev->driver_info->early_init &&
0382 dev->driver_info->early_init(dev) != 0)
0383 goto halt_fail_and_release;
0384
0385
0386 phym = NULL;
0387 reply_len = sizeof *phym;
0388 retval = rndis_query(dev, intf, u.buf,
0389 RNDIS_OID_GEN_PHYSICAL_MEDIUM,
0390 reply_len, (void **)&phym, &reply_len);
0391 if (retval != 0 || !phym) {
0392
0393 phym_unspec = cpu_to_le32(RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED);
0394 phym = &phym_unspec;
0395 }
0396 if ((flags & FLAG_RNDIS_PHYM_WIRELESS) &&
0397 le32_to_cpup(phym) != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
0398 netif_dbg(dev, probe, dev->net,
0399 "driver requires wireless physical medium, but device is not\n");
0400 retval = -ENODEV;
0401 goto halt_fail_and_release;
0402 }
0403 if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) &&
0404 le32_to_cpup(phym) == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
0405 netif_dbg(dev, probe, dev->net,
0406 "driver requires non-wireless physical medium, but device is wireless.\n");
0407 retval = -ENODEV;
0408 goto halt_fail_and_release;
0409 }
0410
0411
0412 reply_len = ETH_ALEN;
0413 retval = rndis_query(dev, intf, u.buf,
0414 RNDIS_OID_802_3_PERMANENT_ADDRESS,
0415 48, (void **) &bp, &reply_len);
0416 if (unlikely(retval< 0)) {
0417 dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval);
0418 goto halt_fail_and_release;
0419 }
0420
0421 eth_hw_addr_set(net, bp);
0422
0423
0424 memset(u.set, 0, sizeof *u.set);
0425 u.set->msg_type = cpu_to_le32(RNDIS_MSG_SET);
0426 u.set->msg_len = cpu_to_le32(4 + sizeof *u.set);
0427 u.set->oid = cpu_to_le32(RNDIS_OID_GEN_CURRENT_PACKET_FILTER);
0428 u.set->len = cpu_to_le32(4);
0429 u.set->offset = cpu_to_le32((sizeof *u.set) - 8);
0430 *(__le32 *)(u.buf + sizeof *u.set) = cpu_to_le32(RNDIS_DEFAULT_FILTER);
0431
0432 retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
0433 if (unlikely(retval < 0)) {
0434 dev_err(&intf->dev, "rndis set packet filter, %d\n", retval);
0435 goto halt_fail_and_release;
0436 }
0437
0438 retval = 0;
0439
0440 kfree(u.buf);
0441 return retval;
0442
0443 halt_fail_and_release:
0444 memset(u.halt, 0, sizeof *u.halt);
0445 u.halt->msg_type = cpu_to_le32(RNDIS_MSG_HALT);
0446 u.halt->msg_len = cpu_to_le32(sizeof *u.halt);
0447 (void) rndis_command(dev, (void *)u.halt, CONTROL_BUFFER_SIZE);
0448 fail_and_release:
0449 usb_set_intfdata(info->data, NULL);
0450 usb_driver_release_interface(driver_of(intf), info->data);
0451 info->data = NULL;
0452 fail:
0453 kfree(u.buf);
0454 return retval;
0455 }
0456 EXPORT_SYMBOL_GPL(generic_rndis_bind);
0457
0458 static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
0459 {
0460 return generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_NOT_WIRELESS);
0461 }
0462
0463 static int zte_rndis_bind(struct usbnet *dev, struct usb_interface *intf)
0464 {
0465 int status = rndis_bind(dev, intf);
0466
0467 if (!status && (dev->net->dev_addr[0] & 0x02))
0468 eth_hw_addr_random(dev->net);
0469
0470 return status;
0471 }
0472
0473 void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
0474 {
0475 struct rndis_halt *halt;
0476
0477
0478 halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
0479 if (halt) {
0480 halt->msg_type = cpu_to_le32(RNDIS_MSG_HALT);
0481 halt->msg_len = cpu_to_le32(sizeof *halt);
0482 (void) rndis_command(dev, (void *)halt, CONTROL_BUFFER_SIZE);
0483 kfree(halt);
0484 }
0485
0486 usbnet_cdc_unbind(dev, intf);
0487 }
0488 EXPORT_SYMBOL_GPL(rndis_unbind);
0489
0490
0491
0492
0493 int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
0494 {
0495 bool dst_mac_fixup;
0496
0497
0498 if (skb->len < dev->net->hard_header_len)
0499 return 0;
0500
0501 dst_mac_fixup = !!(dev->driver_info->data & RNDIS_DRIVER_DATA_DST_MAC_FIXUP);
0502
0503
0504 while (likely(skb->len)) {
0505 struct rndis_data_hdr *hdr = (void *)skb->data;
0506 struct sk_buff *skb2;
0507 u32 msg_type, msg_len, data_offset, data_len;
0508
0509 msg_type = le32_to_cpu(hdr->msg_type);
0510 msg_len = le32_to_cpu(hdr->msg_len);
0511 data_offset = le32_to_cpu(hdr->data_offset);
0512 data_len = le32_to_cpu(hdr->data_len);
0513
0514
0515 if (unlikely(msg_type != RNDIS_MSG_PACKET || skb->len < msg_len
0516 || (data_offset + data_len + 8) > msg_len)) {
0517 dev->net->stats.rx_frame_errors++;
0518 netdev_dbg(dev->net, "bad rndis message %d/%d/%d/%d, len %d\n",
0519 le32_to_cpu(hdr->msg_type),
0520 msg_len, data_offset, data_len, skb->len);
0521 return 0;
0522 }
0523 skb_pull(skb, 8 + data_offset);
0524
0525
0526 if (likely((data_len - skb->len) <= sizeof *hdr)) {
0527 skb_trim(skb, data_len);
0528 break;
0529 }
0530
0531
0532 skb2 = skb_clone(skb, GFP_ATOMIC);
0533 if (unlikely(!skb2))
0534 break;
0535 skb_pull(skb, msg_len - sizeof *hdr);
0536 skb_trim(skb2, data_len);
0537
0538 if (unlikely(dst_mac_fixup))
0539 usbnet_cdc_zte_rx_fixup(dev, skb2);
0540
0541 usbnet_skb_return(dev, skb2);
0542 }
0543
0544
0545 if (unlikely(dst_mac_fixup))
0546 usbnet_cdc_zte_rx_fixup(dev, skb);
0547
0548 return 1;
0549 }
0550 EXPORT_SYMBOL_GPL(rndis_rx_fixup);
0551
0552 struct sk_buff *
0553 rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
0554 {
0555 struct rndis_data_hdr *hdr;
0556 struct sk_buff *skb2;
0557 unsigned len = skb->len;
0558
0559 if (likely(!skb_cloned(skb))) {
0560 int room = skb_headroom(skb);
0561
0562
0563 if (unlikely((sizeof *hdr) <= room))
0564 goto fill;
0565
0566
0567 room += skb_tailroom(skb);
0568 if (likely((sizeof *hdr) <= room)) {
0569 skb->data = memmove(skb->head + sizeof *hdr,
0570 skb->data, len);
0571 skb_set_tail_pointer(skb, len);
0572 goto fill;
0573 }
0574 }
0575
0576
0577 skb2 = skb_copy_expand(skb, sizeof *hdr, 1, flags);
0578 dev_kfree_skb_any(skb);
0579 if (unlikely(!skb2))
0580 return skb2;
0581 skb = skb2;
0582
0583
0584
0585
0586 fill:
0587 hdr = __skb_push(skb, sizeof *hdr);
0588 memset(hdr, 0, sizeof *hdr);
0589 hdr->msg_type = cpu_to_le32(RNDIS_MSG_PACKET);
0590 hdr->msg_len = cpu_to_le32(skb->len);
0591 hdr->data_offset = cpu_to_le32(sizeof(*hdr) - 8);
0592 hdr->data_len = cpu_to_le32(len);
0593
0594
0595 return skb;
0596 }
0597 EXPORT_SYMBOL_GPL(rndis_tx_fixup);
0598
0599
0600 static const struct driver_info rndis_info = {
0601 .description = "RNDIS device",
0602 .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
0603 .bind = rndis_bind,
0604 .unbind = rndis_unbind,
0605 .status = rndis_status,
0606 .rx_fixup = rndis_rx_fixup,
0607 .tx_fixup = rndis_tx_fixup,
0608 };
0609
0610 static const struct driver_info rndis_poll_status_info = {
0611 .description = "RNDIS device (poll status before control)",
0612 .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
0613 .data = RNDIS_DRIVER_DATA_POLL_STATUS,
0614 .bind = rndis_bind,
0615 .unbind = rndis_unbind,
0616 .status = rndis_status,
0617 .rx_fixup = rndis_rx_fixup,
0618 .tx_fixup = rndis_tx_fixup,
0619 };
0620
0621 static const struct driver_info zte_rndis_info = {
0622 .description = "ZTE RNDIS device",
0623 .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
0624 .data = RNDIS_DRIVER_DATA_DST_MAC_FIXUP,
0625 .bind = zte_rndis_bind,
0626 .unbind = rndis_unbind,
0627 .status = rndis_status,
0628 .rx_fixup = rndis_rx_fixup,
0629 .tx_fixup = rndis_tx_fixup,
0630 };
0631
0632
0633
0634 static const struct usb_device_id products [] = {
0635 {
0636
0637 USB_DEVICE_AND_INTERFACE_INFO(0x1630, 0x0042,
0638 USB_CLASS_COMM, 2 , 0x0ff),
0639 .driver_info = (unsigned long) &rndis_poll_status_info,
0640 }, {
0641
0642 USB_VENDOR_AND_INTERFACE_INFO(0x238b,
0643 USB_CLASS_COMM, 2 , 0x0ff),
0644 .driver_info = (unsigned long)&rndis_info,
0645 }, {
0646
0647 USB_VENDOR_AND_INTERFACE_INFO(0x19d2,
0648 USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
0649 .driver_info = (unsigned long)&zte_rndis_info,
0650 }, {
0651
0652 USB_VENDOR_AND_INTERFACE_INFO(0x19d2,
0653 USB_CLASS_COMM, 2 , 0x0ff),
0654 .driver_info = (unsigned long)&zte_rndis_info,
0655 }, {
0656
0657 USB_INTERFACE_INFO(USB_CLASS_COMM, 2 , 0x0ff),
0658 .driver_info = (unsigned long) &rndis_info,
0659 }, {
0660
0661 USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
0662 .driver_info = (unsigned long) &rndis_poll_status_info,
0663 }, {
0664
0665 USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
0666 .driver_info = (unsigned long) &rndis_info,
0667 }, {
0668
0669 USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1),
0670 .driver_info = (unsigned long) &rndis_info,
0671 },
0672 { },
0673 };
0674 MODULE_DEVICE_TABLE(usb, products);
0675
0676 static struct usb_driver rndis_driver = {
0677 .name = "rndis_host",
0678 .id_table = products,
0679 .probe = usbnet_probe,
0680 .disconnect = usbnet_disconnect,
0681 .suspend = usbnet_suspend,
0682 .resume = usbnet_resume,
0683 .disable_hub_initiated_lpm = 1,
0684 };
0685
0686 module_usb_driver(rndis_driver);
0687
0688 MODULE_AUTHOR("David Brownell");
0689 MODULE_DESCRIPTION("USB Host side RNDIS driver");
0690 MODULE_LICENSE("GPL");