18 #include <linux/slab.h>
19 #include <linux/kernel.h>
20 #include <linux/device.h>
92 return 13 * 1024 * 8 * 1000 * 8;
94 return 13 * 512 * 8 * 1000 * 8;
96 return 19 * 64 * 1 * 1000 * 8;
104 #define LOG2_STATUS_INTERVAL_MSEC 5
105 #define STATUS_BYTECOUNT 8
111 .bLength =
sizeof rndis_control_intf,
124 .bLength =
sizeof header_desc,
132 .bLength =
sizeof call_mgmt_descriptor,
136 .bmCapabilities = 0x00,
137 .bDataInterface = 0x01,
141 .bLength =
sizeof rndis_acm_descriptor,
145 .bmCapabilities = 0x00,
149 .bLength =
sizeof(rndis_union_desc),
159 .bLength =
sizeof rndis_data_intf,
165 .bInterfaceSubClass = 0,
166 .bInterfaceProtocol = 0,
172 rndis_iad_descriptor = {
173 .bLength =
sizeof rndis_iad_descriptor,
176 .bFirstInterface = 0,
177 .bInterfaceCount = 2,
291 .bLength =
sizeof ss_intr_comp_desc,
319 .bLength =
sizeof ss_bulk_comp_desc,
350 static struct usb_string rndis_string_defs[] = {
351 [0].s =
"RNDIS Communications Control",
352 [1].s =
"RNDIS Ethernet Data",
359 .strings = rndis_string_defs,
382 static void rndis_response_available(
void *_rndis)
384 struct f_rndis *rndis = _rndis;
404 DBG(cdev,
"notify/0 --> %d\n", status);
425 DBG(cdev,
"RNDIS %s response error %d, %d/%d\n",
441 DBG(cdev,
"notify/1 --> %d\n", status);
457 ERROR(cdev,
"RNDIS command error %d, %d/%d\n",
465 struct f_rndis *rndis = func_to_rndis(f);
483 if (w_value || w_index != rndis->
ctrl_id)
487 req->
complete = rndis_command_complete;
494 if (w_value || w_index != rndis->
ctrl_id)
504 req->
complete = rndis_response_complete;
515 VDBG(cdev,
"invalid control req%02x.%02x v%04x i%04x l%d\n",
517 w_value, w_index, w_length);
522 DBG(cdev,
"rndis req%02x.%02x v%04x i%04x l%d\n",
524 w_value, w_index, w_length);
529 ERROR(cdev,
"rndis response on err %d\n", value);
537 static int rndis_set_alt(
struct usb_function *f,
unsigned intf,
unsigned alt)
539 struct f_rndis *rndis = func_to_rndis(f);
545 if (rndis->
notify->driver_data) {
546 VDBG(cdev,
"reset rndis control %d\n", intf);
547 usb_ep_disable(rndis->
notify);
549 if (!rndis->
notify->desc) {
550 VDBG(cdev,
"init rndis ctrl %d\n", intf);
554 usb_ep_enable(rndis->
notify);
555 rndis->
notify->driver_data = rndis;
557 }
else if (intf == rndis->
data_id) {
560 if (rndis->
port.in_ep->driver_data) {
561 DBG(cdev,
"reset rndis\n");
565 if (!rndis->
port.in_ep->desc || !rndis->
port.out_ep->desc) {
566 DBG(cdev,
"init rndis\n");
568 rndis->
port.in_ep) ||
570 rndis->
port.out_ep)) {
578 rndis->
port.is_zlp_ok =
false;
592 rndis->
port.cdc_filter = 0;
594 DBG(cdev,
"RNDIS RX/TX early activation ... \n");
600 &rndis->
port.cdc_filter);
611 struct f_rndis *rndis = func_to_rndis(f);
614 if (!rndis->
notify->driver_data)
617 DBG(cdev,
"rndis deactivated\n");
622 usb_ep_disable(rndis->
notify);
635 static void rndis_open(
struct gether *geth)
637 struct f_rndis *rndis = func_to_rndis(&geth->
func);
640 DBG(cdev,
"%s\n", __func__);
647 static void rndis_close(
struct gether *geth)
649 struct f_rndis *rndis = func_to_rndis(&geth->
func);
651 DBG(geth->
func.config->cdev,
"%s\n", __func__);
665 struct f_rndis *rndis = func_to_rndis(f);
693 rndis->
port.in_ep = ep;
699 rndis->
port.out_ep = ep;
723 rndis->
notify_req->complete = rndis_response_complete;
734 if (gadget_is_dualspeed(c->
cdev->gadget)) {
748 if (gadget_is_superspeed(c->
cdev->gadget)) {
762 rndis->
port.open = rndis_open;
763 rndis->
port.close = rndis_close;
783 DBG(cdev,
"RNDIS: %s speed IN/%s OUT/%s NOTIFY/%s\n",
784 gadget_is_superspeed(c->
cdev->gadget) ?
"super" :
785 gadget_is_dualspeed(c->
cdev->gadget) ?
"dual" :
"full",
786 rndis->
port.in_ep->name, rndis->
port.out_ep->name,
806 if (rndis->
port.out_ep->desc)
807 rndis->
port.out_ep->driver_data =
NULL;
808 if (rndis->
port.in_ep->desc)
809 rndis->
port.in_ep->driver_data =
NULL;
811 ERROR(cdev,
"%s: can't bind, err %d\n", f->
name, status);
819 struct f_rndis *rndis = func_to_rndis(f);
823 rndis_string_defs[0].
id = 0;
825 if (gadget_is_superspeed(c->
cdev->gadget))
827 if (gadget_is_dualspeed(c->
cdev->gadget))
851 if (!can_support_rndis(c) || !
ethaddr)
855 if (rndis_string_defs[0].
id == 0) {
895 rndis->
port.cdc_filter = 0;
899 rndis->
port.wrap = rndis_add_header;
902 rndis->
port.func.name =
"rndis";
903 rndis->
port.func.strings = rndis_strings;
905 rndis->
port.func.bind = rndis_bind;
907 rndis->
port.func.set_alt = rndis_set_alt;
908 rndis->
port.func.setup = rndis_setup;
909 rndis->
port.func.disable = rndis_disable;