2 * f_rndis.c -- RNDIS link function driver
4 * Copyright (C) 2003-2005,2008 David Brownell
5 * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
6 * Copyright (C) 2008 Nokia Corporation
7 * Copyright (C) 2009 Samsung Electronics
8 * Author: Michal Nazarewicz (m.nazarewicz@samsung.com)
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 /* #define VERBOSE_DEBUG */
27 #include <linux/slab.h>
28 #include <linux/kernel.h>
29 #include <linux/platform_device.h>
30 #include <linux/etherdevice.h>
31 #include <linux/usb/android_composite.h>
33 #include <asm/atomic.h>
40 * This function is an RNDIS Ethernet port -- a Microsoft protocol that's
41 * been promoted instead of the standard CDC Ethernet. The published RNDIS
42 * spec is ambiguous, incomplete, and needlessly complex. Variants such as
43 * ActiveSync have even worse status in terms of specification.
45 * In short: it's a protocol controlled by (and for) Microsoft, not for an
46 * Open ecosystem or markets. Linux supports it *only* because Microsoft
47 * doesn't support the CDC Ethernet standard.
49 * The RNDIS data transfer model is complex, with multiple Ethernet packets
50 * per USB message, and out of band data. The control model is built around
51 * what's essentially an "RNDIS RPC" protocol. It's all wrapped in a CDC ACM
52 * (modem, not Ethernet) veneer, with those ACM descriptors being entirely
53 * useless (they're ignored). RNDIS expects to be the only function in its
54 * configuration, so it's no real help if you need composite devices; and
55 * it expects to be the first configuration too.
57 * There is a single technical advantage of RNDIS over CDC Ethernet, if you
58 * discount the fluff that its RPC can be made to deliver: it doesn't need
59 * a NOP altsetting for the data interface. That lets it work on some of the
60 * "so smart it's stupid" hardware which takes over configuration changes
61 * from the software, and adds restrictions like "no altsettings".
63 * Unfortunately MSFT's RNDIS drivers are buggy. They hang or oops, and
64 * have all sorts of contrary-to-specification oddities that can prevent
65 * them from working sanely. Since bugfixes (or accurate specs, letting
66 * Linux work around those bugs) are unlikely to ever come from MSFT, you
67 * may want to avoid using RNDIS on purely operational grounds.
69 * Omissions from the RNDIS 1.0 specification include:
71 * - Power management ... references data that's scattered around lots
72 * of other documentation, which is incorrect/incomplete there too.
74 * - There are various undocumented protocol requirements, like the need
75 * to send garbage in some control-OUT messages.
77 * - MS-Windows drivers sometimes emit undocumented requests.
80 #ifdef CONFIG_USB_ANDROID_SAMSUNG_COMPOSITE
81 #define USB_SAMSUNG_FIXED_IAD_INTERFACE_NUMBER
84 struct rndis_ep_descs {
85 struct usb_endpoint_descriptor *in;
86 struct usb_endpoint_descriptor *out;
87 struct usb_endpoint_descriptor *notify;
96 struct rndis_ep_descs fs;
97 struct rndis_ep_descs hs;
99 struct usb_ep *notify;
100 struct usb_endpoint_descriptor *notify_desc;
101 struct usb_request *notify_req;
102 atomic_t notify_count;
105 static inline struct f_rndis *func_to_rndis(struct usb_function *f)
107 return container_of(f, struct f_rndis, port.func);
110 /* peak (theoretical) bulk transfer rate in bits-per-second */
111 static unsigned int bitrate(struct usb_gadget *g)
113 if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
114 return 13 * 512 * 8 * 1000 * 8;
116 return 19 * 64 * 1 * 1000 * 8;
119 /*-------------------------------------------------------------------------*/
124 #define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
125 #define STATUS_BYTECOUNT 8 /* 8 bytes data */
128 /* interface descriptor: */
130 static struct usb_interface_descriptor rndis_control_intf = {
131 .bLength = sizeof rndis_control_intf,
132 .bDescriptorType = USB_DT_INTERFACE,
134 /* .bInterfaceNumber = DYNAMIC */
135 /* status endpoint is optional; this could be patched later */
137 #ifdef CONFIG_USB_ANDROID_RNDIS_WCEIS
138 /* "Wireless" RNDIS; auto-detected by Windows */
139 .bInterfaceClass = USB_CLASS_WIRELESS_CONTROLLER,
140 .bInterfaceSubClass = 1,
141 .bInterfaceProtocol = 3,
143 .bInterfaceClass = USB_CLASS_COMM,
144 .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
145 .bInterfaceProtocol = USB_CDC_ACM_PROTO_VENDOR,
147 /* .iInterface = DYNAMIC */
150 static struct usb_cdc_header_desc header_desc = {
151 .bLength = sizeof header_desc,
152 .bDescriptorType = USB_DT_CS_INTERFACE,
153 .bDescriptorSubType = USB_CDC_HEADER_TYPE,
155 .bcdCDC = cpu_to_le16(0x0110),
158 static struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor = {
159 .bLength = sizeof call_mgmt_descriptor,
160 .bDescriptorType = USB_DT_CS_INTERFACE,
161 .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE,
163 .bmCapabilities = 0x00,
164 .bDataInterface = 0x01,
167 static struct usb_cdc_acm_descriptor rndis_acm_descriptor = {
168 .bLength = sizeof rndis_acm_descriptor,
169 .bDescriptorType = USB_DT_CS_INTERFACE,
170 .bDescriptorSubType = USB_CDC_ACM_TYPE,
172 .bmCapabilities = 0x00,
175 static struct usb_cdc_union_desc rndis_union_desc = {
176 .bLength = sizeof(rndis_union_desc),
177 .bDescriptorType = USB_DT_CS_INTERFACE,
178 .bDescriptorSubType = USB_CDC_UNION_TYPE,
179 /* .bMasterInterface0 = DYNAMIC */
180 /* .bSlaveInterface0 = DYNAMIC */
183 /* the data interface has two bulk endpoints */
185 static struct usb_interface_descriptor rndis_data_intf = {
186 .bLength = sizeof rndis_data_intf,
187 .bDescriptorType = USB_DT_INTERFACE,
189 /* .bInterfaceNumber = DYNAMIC */
191 .bInterfaceClass = USB_CLASS_CDC_DATA,
192 .bInterfaceSubClass = 0,
193 .bInterfaceProtocol = 0,
194 /* .iInterface = DYNAMIC */
197 #ifndef USB_SAMSUNG_NO_IAD
198 static struct usb_interface_assoc_descriptor
199 rndis_iad_descriptor = {
200 .bLength = sizeof rndis_iad_descriptor,
201 .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
203 .bFirstInterface = 0, /* XXX, hardcoded */
204 .bInterfaceCount = 2, // control + data
205 # ifdef CONFIG_USB_ANDROID_SAMSUNG_RNDIS_WITH_MS_COMPOSITE
206 .bFunctionClass = 0xe0,
207 .bFunctionSubClass = 0x01,
208 .bFunctionProtocol = 0x03,
210 .bFunctionClass = USB_CLASS_COMM,
211 .bFunctionSubClass = USB_CDC_SUBCLASS_ETHERNET,
212 .bFunctionProtocol = USB_CDC_PROTO_NONE,
214 /* .iFunction = DYNAMIC */
218 /* full speed support: */
220 static struct usb_endpoint_descriptor fs_notify_desc = {
221 .bLength = USB_DT_ENDPOINT_SIZE,
222 .bDescriptorType = USB_DT_ENDPOINT,
224 .bEndpointAddress = USB_DIR_IN,
225 .bmAttributes = USB_ENDPOINT_XFER_INT,
226 .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
227 .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
230 static struct usb_endpoint_descriptor fs_in_desc = {
231 .bLength = USB_DT_ENDPOINT_SIZE,
232 .bDescriptorType = USB_DT_ENDPOINT,
234 .bEndpointAddress = USB_DIR_IN,
235 .bmAttributes = USB_ENDPOINT_XFER_BULK,
238 static struct usb_endpoint_descriptor fs_out_desc = {
239 .bLength = USB_DT_ENDPOINT_SIZE,
240 .bDescriptorType = USB_DT_ENDPOINT,
242 .bEndpointAddress = USB_DIR_OUT,
243 .bmAttributes = USB_ENDPOINT_XFER_BULK,
246 static struct usb_descriptor_header *eth_fs_function[] = {
247 #ifndef USB_SAMSUNG_NO_IAD
248 (struct usb_descriptor_header *) &rndis_iad_descriptor,
250 /* control interface matches ACM, not Ethernet */
251 (struct usb_descriptor_header *) &rndis_control_intf,
252 (struct usb_descriptor_header *) &header_desc,
253 (struct usb_descriptor_header *) &call_mgmt_descriptor,
254 (struct usb_descriptor_header *) &rndis_acm_descriptor,
255 (struct usb_descriptor_header *) &rndis_union_desc,
256 (struct usb_descriptor_header *) &fs_notify_desc,
257 /* data interface has no altsetting */
258 (struct usb_descriptor_header *) &rndis_data_intf,
259 (struct usb_descriptor_header *) &fs_in_desc,
260 (struct usb_descriptor_header *) &fs_out_desc,
264 /* high speed support: */
266 static struct usb_endpoint_descriptor hs_notify_desc = {
267 .bLength = USB_DT_ENDPOINT_SIZE,
268 .bDescriptorType = USB_DT_ENDPOINT,
270 .bEndpointAddress = USB_DIR_IN,
271 .bmAttributes = USB_ENDPOINT_XFER_INT,
272 .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
273 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
275 static struct usb_endpoint_descriptor hs_in_desc = {
276 .bLength = USB_DT_ENDPOINT_SIZE,
277 .bDescriptorType = USB_DT_ENDPOINT,
279 .bEndpointAddress = USB_DIR_IN,
280 .bmAttributes = USB_ENDPOINT_XFER_BULK,
281 .wMaxPacketSize = cpu_to_le16(512),
284 static struct usb_endpoint_descriptor hs_out_desc = {
285 .bLength = USB_DT_ENDPOINT_SIZE,
286 .bDescriptorType = USB_DT_ENDPOINT,
288 .bEndpointAddress = USB_DIR_OUT,
289 .bmAttributes = USB_ENDPOINT_XFER_BULK,
290 .wMaxPacketSize = cpu_to_le16(512),
293 static struct usb_descriptor_header *eth_hs_function[] = {
294 #ifndef USB_SAMSUNG_NO_IAD
295 (struct usb_descriptor_header *) &rndis_iad_descriptor,
297 /* control interface matches ACM, not Ethernet */
298 (struct usb_descriptor_header *) &rndis_control_intf,
299 (struct usb_descriptor_header *) &header_desc,
300 (struct usb_descriptor_header *) &call_mgmt_descriptor,
301 (struct usb_descriptor_header *) &rndis_acm_descriptor,
302 (struct usb_descriptor_header *) &rndis_union_desc,
303 (struct usb_descriptor_header *) &hs_notify_desc,
304 /* data interface has no altsetting */
305 (struct usb_descriptor_header *) &rndis_data_intf,
306 (struct usb_descriptor_header *) &hs_in_desc,
307 (struct usb_descriptor_header *) &hs_out_desc,
311 /* string descriptors: */
313 static struct usb_string rndis_string_defs[] = {
314 [0].s = "RNDIS Communications Control",
315 [1].s = "RNDIS Ethernet Data",
316 #ifndef USB_SAMSUNG_NO_IAD
319 { } /* end of list */
322 static struct usb_gadget_strings rndis_string_table = {
323 .language = 0x0409, /* en-us */
324 .strings = rndis_string_defs,
327 static struct usb_gadget_strings *rndis_strings[] = {
332 #ifdef CONFIG_USB_ANDROID_RNDIS
333 static struct usb_ether_platform_data *rndis_pdata;
336 /*-------------------------------------------------------------------------*/
338 static struct sk_buff *rndis_add_header(struct gether *port,
341 struct sk_buff *skb2;
343 skb2 = skb_realloc_headroom(skb, sizeof(struct rndis_packet_msg_type));
347 dev_kfree_skb_any(skb);
351 static void rndis_response_available(void *_rndis)
353 struct f_rndis *rndis = _rndis;
354 struct usb_request *req = rndis->notify_req;
355 struct usb_composite_dev *cdev = rndis->port.func.config->cdev;
356 __le32 *data = req->buf;
359 if (atomic_inc_return(&rndis->notify_count) != 1)
362 /* Send RNDIS RESPONSE_AVAILABLE notification; a
363 * USB_CDC_NOTIFY_RESPONSE_AVAILABLE "should" work too
365 * This is the only notification defined by RNDIS.
367 data[0] = cpu_to_le32(1);
368 data[1] = cpu_to_le32(0);
370 status = usb_ep_queue(rndis->notify, req, GFP_ATOMIC);
372 atomic_dec(&rndis->notify_count);
373 DBG(cdev, "notify/0 --> %d\n", status);
377 static void rndis_response_complete(struct usb_ep *ep, struct usb_request *req)
379 struct f_rndis *rndis = req->context;
380 struct usb_composite_dev *cdev = rndis->port.func.config->cdev;
381 int status = req->status;
384 * - USB_CDC_GET_ENCAPSULATED_RESPONSE (ep0/control)
385 * - RNDIS_RESPONSE_AVAILABLE (status/irq)
390 /* connection gone */
391 atomic_set(&rndis->notify_count, 0);
394 DBG(cdev, "RNDIS %s response error %d, %d/%d\n",
396 req->actual, req->length);
399 if (ep != rndis->notify)
402 /* handle multiple pending RNDIS_RESPONSE_AVAILABLE
403 * notifications by resending until we're done
405 if (atomic_dec_and_test(&rndis->notify_count))
407 status = usb_ep_queue(rndis->notify, req, GFP_ATOMIC);
409 atomic_dec(&rndis->notify_count);
410 DBG(cdev, "notify/1 --> %d\n", status);
416 static void rndis_command_complete(struct usb_ep *ep, struct usb_request *req)
418 struct f_rndis *rndis = req->context;
419 struct usb_composite_dev *cdev = rndis->port.func.config->cdev;
422 /* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */
423 // spin_lock(&dev->lock);
424 status = rndis_msg_parser(rndis->config, (u8 *) req->buf);
426 ERROR(cdev, "RNDIS command error %d, %d/%d\n",
427 status, req->actual, req->length);
428 // spin_unlock(&dev->lock);
432 rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
434 struct f_rndis *rndis = func_to_rndis(f);
435 struct usb_composite_dev *cdev = f->config->cdev;
436 struct usb_request *req = cdev->req;
437 int value = -EOPNOTSUPP;
438 u16 w_index = le16_to_cpu(ctrl->wIndex);
439 u16 w_value = le16_to_cpu(ctrl->wValue);
440 u16 w_length = le16_to_cpu(ctrl->wLength);
442 #ifdef CONFIG_USB_ANDROID_SAMSUNG_COMPOSITE
443 /* soonyong.cho : if you use composite framework and RNDIS is not first in all function list,
444 you have to change w_index number. And please use RNDIS only if you possible.
447 w_index = rndis->ctrl_id;
450 /* composite driver infrastructure handles everything except
451 * CDC class messages; interface activation uses set_alt().
453 switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
455 /* RNDIS uses the CDC command encapsulation mechanism to implement
456 * an RPC scheme, with much getting/setting of attributes by OID.
458 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
459 | USB_CDC_SEND_ENCAPSULATED_COMMAND:
460 if (w_length > req->length || w_value
461 || w_index != rndis->ctrl_id)
463 /* read the request; process it later */
465 req->complete = rndis_command_complete;
466 req->context = rndis;
467 /* later, rndis_response_available() sends a notification */
470 case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
471 | USB_CDC_GET_ENCAPSULATED_RESPONSE:
472 if (w_value || w_index != rndis->ctrl_id)
478 /* return the result */
479 buf = rndis_get_next_response(rndis->config, &n);
481 memcpy(req->buf, buf, n);
482 req->complete = rndis_response_complete;
483 rndis_free_response(rndis->config, buf);
486 /* else stalls ... spec says to avoid that */
492 VDBG(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n",
493 ctrl->bRequestType, ctrl->bRequest,
494 w_value, w_index, w_length);
497 /* respond with data transfer or status phase? */
499 DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n",
500 ctrl->bRequestType, ctrl->bRequest,
501 w_value, w_index, w_length);
502 req->zero = (value < w_length);
504 value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
506 ERROR(cdev, "rndis response on err %d\n", value);
509 /* device either stalls (value < 0) or reports success */
514 static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
516 struct f_rndis *rndis = func_to_rndis(f);
517 struct usb_composite_dev *cdev = f->config->cdev;
519 /* we know alt == 0 */
521 if (intf == rndis->ctrl_id) {
522 if (rndis->notify->driver_data) {
523 VDBG(cdev, "reset rndis control %d\n", intf);
524 usb_ep_disable(rndis->notify);
526 VDBG(cdev, "init rndis ctrl %d\n", intf);
528 rndis->notify_desc = ep_choose(cdev->gadget,
531 usb_ep_enable(rndis->notify, rndis->notify_desc);
532 rndis->notify->driver_data = rndis;
534 } else if (intf == rndis->data_id) {
535 struct net_device *net;
537 if (rndis->port.in_ep->driver_data) {
538 DBG(cdev, "reset rndis\n");
539 gether_disconnect(&rndis->port);
542 if (!rndis->port.in) {
543 DBG(cdev, "init rndis\n");
545 rndis->port.in = ep_choose(cdev->gadget,
546 rndis->hs.in, rndis->fs.in);
547 rndis->port.out = ep_choose(cdev->gadget,
548 rndis->hs.out, rndis->fs.out);
550 /* Avoid ZLPs; they can be troublesome. */
551 rndis->port.is_zlp_ok = false;
553 /* RNDIS should be in the "RNDIS uninitialized" state,
554 * either never activated or after rndis_uninit().
556 * We don't want data to flow here until a nonzero packet
557 * filter is set, at which point it enters "RNDIS data
558 * initialized" state ... but we do want the endpoints
559 * to be activated. It's a strange little state.
561 * REVISIT the RNDIS gadget code has done this wrong for a
562 * very long time. We need another call to the link layer
563 * code -- gether_updown(...bool) maybe -- to do it right.
565 rndis->port.cdc_filter = 0;
567 DBG(cdev, "RNDIS RX/TX early activation ... \n");
568 net = gether_connect(&rndis->port);
572 rndis_set_param_dev(rndis->config, net,
573 &rndis->port.cdc_filter);
582 static void rndis_disable(struct usb_function *f)
584 struct f_rndis *rndis = func_to_rndis(f);
585 struct usb_composite_dev *cdev = f->config->cdev;
587 if (!rndis->notify->driver_data)
590 DBG(cdev, "rndis deactivated\n");
592 rndis_uninit(rndis->config);
593 gether_disconnect(&rndis->port);
595 usb_ep_disable(rndis->notify);
596 rndis->notify->driver_data = NULL;
599 /*-------------------------------------------------------------------------*/
602 * This isn't quite the same mechanism as CDC Ethernet, since the
603 * notification scheme passes less data, but the same set of link
604 * states must be tested. A key difference is that altsettings are
605 * not used to tell whether the link should send packets or not.
608 static void rndis_open(struct gether *geth)
610 struct f_rndis *rndis = func_to_rndis(&geth->func);
611 struct usb_composite_dev *cdev = geth->func.config->cdev;
613 DBG(cdev, "%s\n", __func__);
615 rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3,
616 bitrate(cdev->gadget) / 100);
617 rndis_signal_connect(rndis->config);
620 static void rndis_close(struct gether *geth)
622 struct f_rndis *rndis = func_to_rndis(&geth->func);
624 DBG(geth->func.config->cdev, "%s\n", __func__);
626 rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3, 0);
627 rndis_signal_disconnect(rndis->config);
630 /*-------------------------------------------------------------------------*/
632 /* ethernet function driver setup/binding */
635 rndis_bind(struct usb_configuration *c, struct usb_function *f)
637 struct usb_composite_dev *cdev = c->cdev;
638 struct f_rndis *rndis = func_to_rndis(f);
642 /* allocate instance-specific interface IDs */
643 status = usb_interface_id(c, f);
646 rndis->ctrl_id = status;
647 #if !defined(USB_SAMSUNG_NO_IAD) && defined(USB_SAMSUNG_FIXED_IAD_INTERFACE_NUMBER)//yskim
648 rndis_iad_descriptor.bFirstInterface = status;
651 rndis_control_intf.bInterfaceNumber = status;
652 rndis_union_desc.bMasterInterface0 = status;
654 status = usb_interface_id(c, f);
657 rndis->data_id = status;
659 rndis_data_intf.bInterfaceNumber = status;
660 rndis_union_desc.bSlaveInterface0 = status;
664 /* allocate instance-specific endpoints */
665 ep = usb_ep_autoconfig(cdev->gadget, &fs_in_desc);
668 rndis->port.in_ep = ep;
669 ep->driver_data = cdev; /* claim */
671 ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc);
674 rndis->port.out_ep = ep;
675 ep->driver_data = cdev; /* claim */
677 /* NOTE: a status/notification endpoint is, strictly speaking,
678 * optional. We don't treat it that way though! It's simpler,
679 * and some newer profiles don't treat it as optional.
681 ep = usb_ep_autoconfig(cdev->gadget, &fs_notify_desc);
685 ep->driver_data = cdev; /* claim */
689 /* allocate notification request and buffer */
690 rndis->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL);
691 if (!rndis->notify_req)
693 rndis->notify_req->buf = kmalloc(STATUS_BYTECOUNT, GFP_KERNEL);
694 if (!rndis->notify_req->buf)
696 rndis->notify_req->length = STATUS_BYTECOUNT;
697 rndis->notify_req->context = rndis;
698 rndis->notify_req->complete = rndis_response_complete;
700 /* copy descriptors, and track endpoint copies */
701 f->descriptors = usb_copy_descriptors(eth_fs_function);
705 rndis->fs.in = usb_find_endpoint(eth_fs_function,
706 f->descriptors, &fs_in_desc);
707 rndis->fs.out = usb_find_endpoint(eth_fs_function,
708 f->descriptors, &fs_out_desc);
709 rndis->fs.notify = usb_find_endpoint(eth_fs_function,
710 f->descriptors, &fs_notify_desc);
712 /* support all relevant hardware speeds... we expect that when
713 * hardware is dual speed, all bulk-capable endpoints work at
716 if (gadget_is_dualspeed(c->cdev->gadget)) {
717 hs_in_desc.bEndpointAddress =
718 fs_in_desc.bEndpointAddress;
719 hs_out_desc.bEndpointAddress =
720 fs_out_desc.bEndpointAddress;
721 hs_notify_desc.bEndpointAddress =
722 fs_notify_desc.bEndpointAddress;
724 /* copy descriptors, and track endpoint copies */
725 f->hs_descriptors = usb_copy_descriptors(eth_hs_function);
727 if (!f->hs_descriptors)
730 rndis->hs.in = usb_find_endpoint(eth_hs_function,
731 f->hs_descriptors, &hs_in_desc);
732 rndis->hs.out = usb_find_endpoint(eth_hs_function,
733 f->hs_descriptors, &hs_out_desc);
734 rndis->hs.notify = usb_find_endpoint(eth_hs_function,
735 f->hs_descriptors, &hs_notify_desc);
738 rndis->port.open = rndis_open;
739 rndis->port.close = rndis_close;
741 status = rndis_register(rndis_response_available, rndis);
744 rndis->config = status;
746 rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3, 0);
747 rndis_set_host_mac(rndis->config, rndis->ethaddr);
749 #ifdef CONFIG_USB_ANDROID_RNDIS
751 if (rndis_set_param_vendor(rndis->config, rndis_pdata->vendorID,
752 rndis_pdata->vendorDescr))
757 /* NOTE: all that is done without knowing or caring about
758 * the network link ... which is unavailable to this code
759 * until we're activated via set_alt().
762 DBG(cdev, "RNDIS: %s speed IN/%s OUT/%s NOTIFY/%s\n",
763 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
764 rndis->port.in_ep->name, rndis->port.out_ep->name,
765 rndis->notify->name);
769 if (gadget_is_dualspeed(c->cdev->gadget) && f->hs_descriptors)
770 usb_free_descriptors(f->hs_descriptors);
772 usb_free_descriptors(f->descriptors);
774 if (rndis->notify_req) {
775 kfree(rndis->notify_req->buf);
776 usb_ep_free_request(rndis->notify, rndis->notify_req);
779 /* we might as well release our claims on endpoints */
781 rndis->notify->driver_data = NULL;
783 rndis->port.out_ep->driver_data = NULL;
785 rndis->port.in_ep->driver_data = NULL;
787 ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
793 rndis_unbind(struct usb_configuration *c, struct usb_function *f)
795 struct f_rndis *rndis = func_to_rndis(f);
797 rndis_deregister(rndis->config);
800 if (gadget_is_dualspeed(c->cdev->gadget))
801 usb_free_descriptors(f->hs_descriptors);
802 usb_free_descriptors(f->descriptors);
804 kfree(rndis->notify_req->buf);
805 usb_ep_free_request(rndis->notify, rndis->notify_req);
810 /* Some controllers can't support RNDIS ... */
811 static inline bool can_support_rndis(struct usb_configuration *c)
813 /* everything else is *presumably* fine */
818 * rndis_bind_config - add RNDIS network link to a configuration
819 * @c: the configuration to support the network link
820 * @ethaddr: a buffer in which the ethernet address of the host side
821 * side of the link was recorded
822 * Context: single threaded during gadget setup
824 * Returns zero on success, else negative errno.
826 * Caller must have called @gether_setup(). Caller is also responsible
827 * for calling @gether_cleanup() before module unload.
829 #ifdef CONFIG_USB_ANDROID_SAMSUNG_COMPOSITE_ADVANCED
831 rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
833 struct f_rndis *rndis;
837 /* allocate and initialize one new instance */
839 rndis = kzalloc(sizeof *rndis, GFP_KERNEL);
843 memcpy(rndis->ethaddr, ethaddr, ETH_ALEN);
845 /* RNDIS activates when the host changes this filter */
846 rndis->port.cdc_filter = 0;
848 /* RNDIS has special (and complex) framing */
849 rndis->port.header_len = sizeof(struct rndis_packet_msg_type);
850 rndis->port.wrap = rndis_add_header;
851 rndis->port.unwrap = rndis_rm_hdr;
853 rndis->port.func.name = "rndis";
854 rndis->port.func.strings = rndis_strings;
855 /* descriptors are per-instance copies */
856 rndis->port.func.bind = rndis_bind;
857 rndis->port.func.unbind = rndis_unbind;
858 rndis->port.func.set_alt = rndis_set_alt;
859 rndis->port.func.setup = rndis_setup;
860 rndis->port.func.disable = rndis_disable;
862 status = usb_add_function(c, &rndis->port.func);
872 rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
874 struct f_rndis *rndis;
877 if (!can_support_rndis(c) || !ethaddr)
880 /* maybe allocate device-global string IDs */
881 if (rndis_string_defs[0].id == 0) {
883 /* ... and setup RNDIS itself */
884 status = rndis_init();
888 /* control interface label */
889 status = usb_string_id(c->cdev);
892 rndis_string_defs[0].id = status;
893 rndis_control_intf.iInterface = status;
895 /* data interface label */
896 status = usb_string_id(c->cdev);
899 rndis_string_defs[1].id = status;
900 rndis_data_intf.iInterface = status;
901 #ifndef USB_SAMSUNG_NO_IAD
902 /* IAD iFunction label */
903 status = usb_string_id(c->cdev);
906 rndis_string_defs[2].id = status;
907 rndis_iad_descriptor.iFunction = status;
911 /* allocate and initialize one new instance */
913 rndis = kzalloc(sizeof *rndis, GFP_KERNEL);
917 memcpy(rndis->ethaddr, ethaddr, ETH_ALEN);
919 /* RNDIS activates when the host changes this filter */
920 rndis->port.cdc_filter = 0;
922 /* RNDIS has special (and complex) framing */
923 rndis->port.header_len = sizeof(struct rndis_packet_msg_type);
924 rndis->port.wrap = rndis_add_header;
925 rndis->port.unwrap = rndis_rm_hdr;
927 rndis->port.func.name = "rndis";
928 rndis->port.func.strings = rndis_strings;
929 /* descriptors are per-instance copies */
930 rndis->port.func.bind = rndis_bind;
931 rndis->port.func.unbind = rndis_unbind;
932 rndis->port.func.set_alt = rndis_set_alt;
933 rndis->port.func.setup = rndis_setup;
934 rndis->port.func.disable = rndis_disable;
936 #ifdef CONFIG_USB_ANDROID_RNDIS
938 rndis->port.func.disabled = 1;
941 status = usb_add_function(c, &rndis->port.func);
951 #ifdef CONFIG_USB_ANDROID_RNDIS
954 static int rndis_probe(struct platform_device *pdev)
956 rndis_pdata = pdev->dev.platform_data;
960 static struct platform_driver rndis_platform_driver = {
961 .driver = { .name = "rndis", },
962 .probe = rndis_probe,
965 #ifdef CONFIG_USB_ANDROID_SAMSUNG_COMPOSITE_ADVANCED
966 int rndis_function_bind_upper_config(struct usb_composite_dev *cdev)
972 printk(KERN_ERR "rndis_pdata null in rndis_function_bind_config\n");
976 "rndis_function_bind_config MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
977 rndis_pdata->ethaddr[0], rndis_pdata->ethaddr[1],
978 rndis_pdata->ethaddr[2], rndis_pdata->ethaddr[3],
979 rndis_pdata->ethaddr[4], rndis_pdata->ethaddr[5]);
981 ret = gether_setup(cdev->gadget, rndis_pdata->ethaddr);
982 printk(KERN_DEBUG "gether_setup ret=%d\n",ret);
984 if (!rndis_pdata->ethaddr)
987 /* maybe allocate device-global string IDs */
988 if (rndis_string_defs[0].id == 0) {
990 /* ... and setup RNDIS itself */
991 status = rndis_init();
995 /* control interface label */
996 status = usb_string_id(cdev);
999 rndis_string_defs[0].id = status;
1000 rndis_control_intf.iInterface = status;
1002 /* data interface label */
1003 status = usb_string_id(cdev);
1006 rndis_string_defs[1].id = status;
1007 rndis_data_intf.iInterface = status;
1008 #ifndef USB_SAMSUNG_NO_IAD
1009 /* IAD iFunction label */
1010 status = usb_string_id(cdev);
1013 rndis_string_defs[2].id = status;
1014 rndis_iad_descriptor.iFunction = status;
1021 int rndis_function_bind_config(struct usb_configuration *c)
1025 if (!can_support_rndis(c))
1029 "ecm_function_bind_config MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
1030 ecm_pdata->ethaddr[0], ecm_pdata->ethaddr[1],
1031 ecm_pdata->ethaddr[2], ecm_pdata->ethaddr[3],
1032 ecm_pdata->ethaddr[4], ecm_pdata->ethaddr[5]);
1035 ret = rndis_bind_config(c, rndis_pdata->ethaddr);
1036 printk(KERN_DEBUG "rndis_bind_config ret=%d\n", ret);
1042 int rndis_function_bind_config(struct usb_configuration *c)
1047 printk(KERN_ERR "rndis_pdata null in rndis_function_bind_config\n");
1051 "rndis_function_bind_config MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
1052 rndis_pdata->ethaddr[0], rndis_pdata->ethaddr[1],
1053 rndis_pdata->ethaddr[2], rndis_pdata->ethaddr[3],
1054 rndis_pdata->ethaddr[4], rndis_pdata->ethaddr[5]);
1056 ret = gether_setup(c->cdev->gadget, rndis_pdata->ethaddr);
1057 printk(KERN_DEBUG "gether_setup ret=%d\n",ret);
1059 ret = rndis_bind_config(c, rndis_pdata->ethaddr);
1060 printk(KERN_DEBUG "rndis_bind_config ret=%d\n", ret);
1066 static struct android_usb_function rndis_function = {
1068 #ifdef CONFIG_USB_ANDROID_SAMSUNG_COMPOSITE_ADVANCED
1069 .bind_upper_config = rndis_function_bind_upper_config,
1070 .bind_config = rndis_function_bind_config,
1072 .bind_config = rndis_function_bind_config,
1076 static int __init init(void)
1078 printk(KERN_INFO "f_rndis init\n");
1079 platform_driver_register(&rndis_platform_driver);
1080 android_register_function(&rndis_function);
1085 #endif /* CONFIG_USB_ANDROID_RNDIS */