^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Host Side support for RNDIS Networking Links
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2005 by David Brownell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mii.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/usb/cdc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/usb/usbnet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/usb/rndis_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * RNDIS is NDIS remoted over USB. It's a MSFT variant of CDC ACM ... of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * course ACM was intended for modems, not Ethernet links! USB's standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * for Ethernet links is "CDC Ethernet", which is significantly simpler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * NOTE that Microsoft's "RNDIS 1.0" specification is incomplete. Issues
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * include:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * - Power management in particular relies on information that's scattered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * through other documentation, and which is incomplete or incorrect even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * - There are various undocumented protocol requirements, such as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * need to send unused garbage in control-OUT messages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * - In some cases, MS-Windows will emit undocumented requests; this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * matters more to peripheral implementations than host ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Moreover there's a no-open-specs variant of RNDIS called "ActiveSync".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * For these reasons and others, ** USE OF RNDIS IS STRONGLY DISCOURAGED ** in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * favor of such non-proprietary alternatives as CDC Ethernet or the newer (and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * currently rare) "Ethernet Emulation Model" (EEM).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * RNDIS notifications from device: command completion; "reverse"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * keepalives; etc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) void rndis_status(struct usbnet *dev, struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) netdev_dbg(dev->net, "rndis status urb, len %d stat %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) urb->actual_length, urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) // FIXME for keepalives, respond immediately (asynchronously)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) // if not an RNDIS status, do like cdc_status(dev,urb) does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) EXPORT_SYMBOL_GPL(rndis_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * RNDIS indicate messages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct cdc_state *info = (void *)&dev->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct device *udev = &info->control->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (dev->driver_info->indication) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) dev->driver_info->indication(dev, msg, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) u32 status = le32_to_cpu(msg->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) case RNDIS_STATUS_MEDIA_CONNECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) dev_info(udev, "rndis media connect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) case RNDIS_STATUS_MEDIA_DISCONNECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) dev_info(udev, "rndis media disconnect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) dev_info(udev, "rndis indication: 0x%08x\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * RPC done RNDIS-style. Caller guarantees:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * - message is properly byteswapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * - there's no other request pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * - buf can hold up to 1KB response (required by RNDIS spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * On return, the first few entries are already byteswapped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * Call context is likely probe(), before interface name is known,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * which is why we won't try to use it in the diagnostics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct cdc_state *info = (void *) &dev->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct usb_cdc_notification notification;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int master_ifnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int partial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) u32 xid = 0, msg_len, request_id, msg_type, rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* REVISIT when this gets called from contexts other than probe() or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * disconnect(): either serialize, or dispatch responses on xid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) msg_type = le32_to_cpu(buf->msg_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Issue the request; xid is unique, don't bother byteswapping it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (likely(msg_type != RNDIS_MSG_HALT && msg_type != RNDIS_MSG_RESET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) xid = dev->xid++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (!xid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) xid = dev->xid++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) buf->request_id = (__force __le32) xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) master_ifnum = info->control->cur_altsetting->desc.bInterfaceNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) retval = usb_control_msg(dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) usb_sndctrlpipe(dev->udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) USB_CDC_SEND_ENCAPSULATED_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) USB_TYPE_CLASS | USB_RECIP_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 0, master_ifnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) buf, le32_to_cpu(buf->msg_len),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) RNDIS_CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (unlikely(retval < 0 || xid == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* Some devices don't respond on the control channel until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * polled on the status channel, so do that first. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (dev->driver_info->data & RNDIS_DRIVER_DATA_POLL_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) retval = usb_interrupt_msg(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) usb_rcvintpipe(dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) dev->status->desc.bEndpointAddress),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ¬ification, sizeof(notification), &partial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) RNDIS_CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (unlikely(retval < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* Poll the control channel; the request probably completed immediately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) rsp = le32_to_cpu(buf->msg_type) | RNDIS_MSG_COMPLETION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) for (count = 0; count < 10; count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) memset(buf, 0, CONTROL_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) retval = usb_control_msg(dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) usb_rcvctrlpipe(dev->udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) USB_CDC_GET_ENCAPSULATED_RESPONSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 0, master_ifnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) buf, buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) RNDIS_CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (likely(retval >= 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) msg_type = le32_to_cpu(buf->msg_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) msg_len = le32_to_cpu(buf->msg_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) status = le32_to_cpu(buf->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) request_id = (__force u32) buf->request_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (likely(msg_type == rsp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (likely(request_id == xid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (unlikely(rsp == RNDIS_MSG_RESET_C))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (likely(RNDIS_STATUS_SUCCESS ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) dev_dbg(&info->control->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) "rndis reply status %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return -EL3RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) dev_dbg(&info->control->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) "rndis reply id %d expected %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) request_id, xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* then likely retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) } else switch (msg_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case RNDIS_MSG_INDICATE: /* fault/event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) rndis_msg_indicate(dev, (void *)buf, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) case RNDIS_MSG_KEEPALIVE: { /* ping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct rndis_keepalive_c *msg = (void *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) msg->msg_type = cpu_to_le32(RNDIS_MSG_KEEPALIVE_C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) msg->msg_len = cpu_to_le32(sizeof *msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) msg->status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) retval = usb_control_msg(dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) usb_sndctrlpipe(dev->udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) USB_CDC_SEND_ENCAPSULATED_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) USB_TYPE_CLASS | USB_RECIP_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 0, master_ifnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) msg, sizeof *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) RNDIS_CONTROL_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (unlikely(retval < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) dev_dbg(&info->control->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) "rndis keepalive err %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) dev_dbg(&info->control->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) "unexpected rndis msg %08x len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) le32_to_cpu(buf->msg_type), msg_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* device probably issued a protocol stall; ignore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) dev_dbg(&info->control->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) "rndis response error, code %d\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) msleep(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) dev_dbg(&info->control->dev, "rndis response timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) EXPORT_SYMBOL_GPL(rndis_command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * rndis_query:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * Performs a query for @oid along with 0 or more bytes of payload as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * specified by @in_len. If @reply_len is not set to -1 then the reply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * length is checked against this value, resulting in an error if it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * doesn't match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * NOTE: Adding a payload exactly or greater than the size of the expected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * response payload is an evident requirement MSFT added for ActiveSync.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * The only exception is for OIDs that return a variably sized response,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * in which case no payload should be added. This undocumented (and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * nonsensical!) issue was found by sniffing protocol requests from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * ActiveSync 4.1 Windows driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static int rndis_query(struct usbnet *dev, struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) void *buf, u32 oid, u32 in_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) void **reply, int *reply_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) void *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct rndis_msg_hdr *header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct rndis_query *get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct rndis_query_c *get_c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) } u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) u32 off, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) u.buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) memset(u.get, 0, sizeof *u.get + in_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) u.get->msg_type = cpu_to_le32(RNDIS_MSG_QUERY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) u.get->msg_len = cpu_to_le32(sizeof *u.get + in_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) u.get->oid = cpu_to_le32(oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) u.get->len = cpu_to_le32(in_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) u.get->offset = cpu_to_le32(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (unlikely(retval < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) failed, %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) oid, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) off = le32_to_cpu(u.get_c->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) len = le32_to_cpu(u.get_c->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (unlikely((8 + off + len) > CONTROL_BUFFER_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) goto response_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (*reply_len != -1 && len != *reply_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) goto response_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) *reply = (unsigned char *) &u.get_c->request_id + off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) *reply_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) response_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) "invalid response - off %d len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) oid, off, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return -EDOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* same as usbnet_netdev_ops but MTU change not allowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static const struct net_device_ops rndis_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) .ndo_open = usbnet_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) .ndo_stop = usbnet_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) .ndo_start_xmit = usbnet_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) .ndo_tx_timeout = usbnet_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) .ndo_get_stats64 = usbnet_get_stats64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) .ndo_set_mac_address = eth_mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) .ndo_validate_addr = eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct net_device *net = dev->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct cdc_state *info = (void *) &dev->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) void *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct rndis_msg_hdr *header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct rndis_init *init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct rndis_init_c *init_c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct rndis_query *get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct rndis_query_c *get_c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct rndis_set *set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct rndis_set_c *set_c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct rndis_halt *halt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) } u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) __le32 phym_unspec, *phym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int reply_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unsigned char *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* we can't rely on i/o from stack working, or stack allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) u.buf = kmalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!u.buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) retval = usbnet_generic_cdc_bind(dev, intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) u.init->msg_type = cpu_to_le32(RNDIS_MSG_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) u.init->msg_len = cpu_to_le32(sizeof *u.init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) u.init->major_version = cpu_to_le32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) u.init->minor_version = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* max transfer (in spec) is 0x4000 at full speed, but for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * TX we'll stick to one Ethernet packet plus RNDIS framing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * For RX we handle drivers that zero-pad to end-of-packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * Don't let userspace change these settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * NOTE: there still seems to be wierdness here, as if we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * to do some more things to make sure WinCE targets accept this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * They default to jumbograms of 8KB or 16KB, which is absurd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * for such low data rates and which is also more than Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * can usually expect to allocate for SKB data...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) net->hard_header_len += sizeof (struct rndis_data_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) dev->hard_mtu = net->mtu + net->hard_header_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) dev->maxpacket = usb_maxpacket(dev->udev, dev->out, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (dev->maxpacket == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) netif_dbg(dev, probe, dev->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) "dev->maxpacket can't be 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) goto fail_and_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) dev->rx_urb_size &= ~(dev->maxpacket - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) net->netdev_ops = &rndis_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (unlikely(retval < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* it might not even be an RNDIS device!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) dev_err(&intf->dev, "RNDIS init failed, %d\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) goto fail_and_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) tmp = le32_to_cpu(u.init_c->max_transfer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (tmp < dev->hard_mtu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (tmp <= net->hard_header_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) dev_err(&intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) "dev can't take %u byte packets (max %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) dev->hard_mtu, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) goto halt_fail_and_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) dev_warn(&intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) "dev can't take %u byte packets (max %u), "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) "adjusting MTU to %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) dev->hard_mtu, tmp, tmp - net->hard_header_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) dev->hard_mtu = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) net->mtu = dev->hard_mtu - net->hard_header_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* REVISIT: peripheral "alignment" request is ignored ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) dev_dbg(&intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) "hard mtu %u (%u from dev), rx buflen %zu, align %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) dev->hard_mtu, tmp, dev->rx_urb_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 1 << le32_to_cpu(u.init_c->packet_alignment));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* module has some device initialization code needs to be done right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * after RNDIS_INIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (dev->driver_info->early_init &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) dev->driver_info->early_init(dev) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) goto halt_fail_and_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* Check physical medium */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) phym = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) reply_len = sizeof *phym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) retval = rndis_query(dev, intf, u.buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) RNDIS_OID_GEN_PHYSICAL_MEDIUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) reply_len, (void **)&phym, &reply_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (retval != 0 || !phym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* OID is optional so don't fail here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) phym_unspec = cpu_to_le32(RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) phym = &phym_unspec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if ((flags & FLAG_RNDIS_PHYM_WIRELESS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) le32_to_cpup(phym) != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) netif_dbg(dev, probe, dev->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) "driver requires wireless physical medium, but device is not\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) goto halt_fail_and_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) le32_to_cpup(phym) == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) netif_dbg(dev, probe, dev->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) "driver requires non-wireless physical medium, but device is wireless.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) goto halt_fail_and_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /* Get designated host ethernet address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) reply_len = ETH_ALEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) retval = rndis_query(dev, intf, u.buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) RNDIS_OID_802_3_PERMANENT_ADDRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 48, (void **) &bp, &reply_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (unlikely(retval< 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) goto halt_fail_and_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (bp[0] & 0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) eth_hw_addr_random(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ether_addr_copy(net->dev_addr, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) /* set a nonzero filter to enable data transfers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) memset(u.set, 0, sizeof *u.set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) u.set->msg_type = cpu_to_le32(RNDIS_MSG_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) u.set->msg_len = cpu_to_le32(4 + sizeof *u.set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) u.set->oid = cpu_to_le32(RNDIS_OID_GEN_CURRENT_PACKET_FILTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) u.set->len = cpu_to_le32(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) u.set->offset = cpu_to_le32((sizeof *u.set) - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) *(__le32 *)(u.buf + sizeof *u.set) = cpu_to_le32(RNDIS_DEFAULT_FILTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (unlikely(retval < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) dev_err(&intf->dev, "rndis set packet filter, %d\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) goto halt_fail_and_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) kfree(u.buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) halt_fail_and_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) memset(u.halt, 0, sizeof *u.halt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) u.halt->msg_type = cpu_to_le32(RNDIS_MSG_HALT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) u.halt->msg_len = cpu_to_le32(sizeof *u.halt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) (void) rndis_command(dev, (void *)u.halt, CONTROL_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) fail_and_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) usb_set_intfdata(info->data, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) usb_driver_release_interface(driver_of(intf), info->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) info->data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) kfree(u.buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) EXPORT_SYMBOL_GPL(generic_rndis_bind);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_NOT_WIRELESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct rndis_halt *halt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /* try to clear any rndis state/activity (no i/o from stack!) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (halt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) halt->msg_type = cpu_to_le32(RNDIS_MSG_HALT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) halt->msg_len = cpu_to_le32(sizeof *halt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) (void) rndis_command(dev, (void *)halt, CONTROL_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) kfree(halt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) usbnet_cdc_unbind(dev, intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) EXPORT_SYMBOL_GPL(rndis_unbind);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * DATA -- host must not write zlps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /* This check is no longer done by usbnet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (skb->len < dev->net->hard_header_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* peripheral may have batched packets to us... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) while (likely(skb->len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) struct rndis_data_hdr *hdr = (void *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct sk_buff *skb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) u32 msg_type, msg_len, data_offset, data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) msg_type = le32_to_cpu(hdr->msg_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) msg_len = le32_to_cpu(hdr->msg_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) data_offset = le32_to_cpu(hdr->data_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) data_len = le32_to_cpu(hdr->data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* don't choke if we see oob, per-packet data, etc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (unlikely(msg_type != RNDIS_MSG_PACKET || skb->len < msg_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) || (data_offset + data_len + 8) > msg_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) dev->net->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) netdev_dbg(dev->net, "bad rndis message %d/%d/%d/%d, len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) le32_to_cpu(hdr->msg_type),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) msg_len, data_offset, data_len, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) skb_pull(skb, 8 + data_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /* at most one packet left? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (likely((data_len - skb->len) <= sizeof *hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) skb_trim(skb, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* try to return all the packets in the batch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) skb2 = skb_clone(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (unlikely(!skb2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) skb_pull(skb, msg_len - sizeof *hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) skb_trim(skb2, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) usbnet_skb_return(dev, skb2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /* caller will usbnet_skb_return the remaining packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) EXPORT_SYMBOL_GPL(rndis_rx_fixup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct sk_buff *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct rndis_data_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct sk_buff *skb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) unsigned len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (likely(!skb_cloned(skb))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) int room = skb_headroom(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /* enough head room as-is? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (unlikely((sizeof *hdr) <= room))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) goto fill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* enough room, but needs to be readjusted? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) room += skb_tailroom(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (likely((sizeof *hdr) <= room)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) skb->data = memmove(skb->head + sizeof *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) skb->data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) skb_set_tail_pointer(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) goto fill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /* create a new skb, with the correct size (and tailpad) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) skb2 = skb_copy_expand(skb, sizeof *hdr, 1, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (unlikely(!skb2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return skb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) skb = skb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* fill out the RNDIS header. we won't bother trying to batch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * packets; Linux minimizes wasted bandwidth through tx queues.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) fill:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) hdr = __skb_push(skb, sizeof *hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) memset(hdr, 0, sizeof *hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) hdr->msg_type = cpu_to_le32(RNDIS_MSG_PACKET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) hdr->msg_len = cpu_to_le32(skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) hdr->data_offset = cpu_to_le32(sizeof(*hdr) - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) hdr->data_len = cpu_to_le32(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /* FIXME make the last packet always be short ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) EXPORT_SYMBOL_GPL(rndis_tx_fixup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static const struct driver_info rndis_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) .description = "RNDIS device",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) .bind = rndis_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) .unbind = rndis_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) .status = rndis_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) .rx_fixup = rndis_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) .tx_fixup = rndis_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static const struct driver_info rndis_poll_status_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) .description = "RNDIS device (poll status before control)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) .data = RNDIS_DRIVER_DATA_POLL_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) .bind = rndis_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) .unbind = rndis_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) .status = rndis_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) .rx_fixup = rndis_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) .tx_fixup = rndis_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static const struct usb_device_id products [] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* 2Wire HomePortal 1000SW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) USB_DEVICE_AND_INTERFACE_INFO(0x1630, 0x0042,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) .driver_info = (unsigned long) &rndis_poll_status_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /* Hytera Communications DMR radios' "Radio to PC Network" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) USB_VENDOR_AND_INTERFACE_INFO(0x238b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) .driver_info = (unsigned long)&rndis_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /* RNDIS is MSFT's un-official variant of CDC ACM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) .driver_info = (unsigned long) &rndis_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) .driver_info = (unsigned long) &rndis_poll_status_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /* RNDIS for tethering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) .driver_info = (unsigned long) &rndis_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /* Novatel Verizon USB730L */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) .driver_info = (unsigned long) &rndis_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) { }, // END
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) MODULE_DEVICE_TABLE(usb, products);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) static struct usb_driver rndis_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .name = "rndis_host",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .id_table = products,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) .probe = usbnet_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .disconnect = usbnet_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .suspend = usbnet_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .resume = usbnet_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .disable_hub_initiated_lpm = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) module_usb_driver(rndis_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) MODULE_AUTHOR("David Brownell");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) MODULE_DESCRIPTION("USB Host side RNDIS driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) MODULE_LICENSE("GPL");