blob: 295f681f8a036fce050d3f49766b4deeb07104f6 [file] [log] [blame]
Mayank Rana0663c432016-12-06 16:38:18 -08001/*
Mayank Rana2ad687f2017-02-16 15:57:27 -08002 * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
3 *
Mayank Rana0663c432016-12-06 16:38:18 -08004 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details
12 */
13
14#ifndef _F_GSI_H
15#define _F_GSI_H
16
17#include <linux/poll.h>
18#include <linux/miscdevice.h>
19#include <linux/ipa.h>
20#include <uapi/linux/usb/cdc.h>
21#include <linux/usb/ch9.h>
22#include <linux/usb/composite.h>
23#include <linux/usb/gadget.h>
24#include <linux/usb/usb_ctrl_qti.h>
25#include <linux/etherdevice.h>
26#include <linux/debugfs.h>
27#include <linux/ipa_usb.h>
Mayank Rana2ad687f2017-02-16 15:57:27 -080028#include <linux/ipc_logging.h>
Mayank Rana0663c432016-12-06 16:38:18 -080029
30#define GSI_RMNET_CTRL_NAME "rmnet_ctrl"
31#define GSI_MBIM_CTRL_NAME "android_mbim"
32#define GSI_DPL_CTRL_NAME "dpl_ctrl"
33#define GSI_CTRL_NAME_LEN (sizeof(GSI_MBIM_CTRL_NAME)+2)
34#define GSI_MAX_CTRL_PKT_SIZE 4096
35#define GSI_CTRL_DTR (1 << 0)
36
37
38#define GSI_NUM_IN_BUFFERS 15
39#define GSI_IN_BUFF_SIZE 2048
Mayank Rana64d136b2016-11-01 21:01:34 -070040#define GSI_NUM_OUT_BUFFERS 14
Mayank Rana0663c432016-12-06 16:38:18 -080041#define GSI_OUT_AGGR_SIZE 24576
42
43#define GSI_IN_RNDIS_AGGR_SIZE 9216
44#define GSI_IN_MBIM_AGGR_SIZE 16384
45#define GSI_IN_RMNET_AGGR_SIZE 16384
46#define GSI_ECM_AGGR_SIZE 2048
47
48#define GSI_OUT_MBIM_BUF_LEN 16384
49#define GSI_OUT_RMNET_BUF_LEN 16384
50#define GSI_OUT_ECM_BUF_LEN 2048
51
52#define GSI_IPA_READY_TIMEOUT 5000
53
54#define ETH_ADDR_STR_LEN 14
55
56/* mbin and ecm */
57#define GSI_CTRL_NOTIFY_BUFF_LEN 16
58
59/* default max packets per tarnsfer value */
60#define DEFAULT_MAX_PKT_PER_XFER 15
61
62/* default pkt alignment factor */
63#define DEFAULT_PKT_ALIGNMENT_FACTOR 4
64
65#define GSI_MBIM_IOCTL_MAGIC 'o'
66#define GSI_MBIM_GET_NTB_SIZE _IOR(GSI_MBIM_IOCTL_MAGIC, 2, u32)
67#define GSI_MBIM_GET_DATAGRAM_COUNT _IOR(GSI_MBIM_IOCTL_MAGIC, 3, u16)
68#define GSI_MBIM_EP_LOOKUP _IOR(GSI_MBIM_IOCTL_MAGIC, 4, struct ep_info)
69#define GSI_MBIM_DATA_EP_TYPE_HSUSB 0x2
70/* ID for Microsoft OS String */
71#define GSI_MBIM_OS_STRING_ID 0xEE
72
73#define EVT_NONE 0
74#define EVT_UNINITIALIZED 1
75#define EVT_INITIALIZED 2
76#define EVT_CONNECT_IN_PROGRESS 3
77#define EVT_CONNECTED 4
78#define EVT_HOST_NRDY 5
79#define EVT_HOST_READY 6
80#define EVT_DISCONNECTED 7
81#define EVT_SUSPEND 8
82#define EVT_IPA_SUSPEND 9
83#define EVT_RESUMED 10
84
Mayank Rana2ad687f2017-02-16 15:57:27 -080085#define NUM_LOG_PAGES 10
86#define log_event_err(x, ...) do { \
87 if (gsi) { \
88 ipc_log_string(gsi->ipc_log_ctxt, x, ##__VA_ARGS__); \
89 pr_err(x, ##__VA_ARGS__); \
90 } \
91} while (0)
92
93#define log_event_dbg(x, ...) do { \
94 if (gsi) { \
95 ipc_log_string(gsi->ipc_log_ctxt, x, ##__VA_ARGS__); \
96 pr_debug(x, ##__VA_ARGS__); \
97 } \
98} while (0)
99
100#define log_event_info(x, ...) do { \
101 if (gsi) { \
102 ipc_log_string(gsi->ipc_log_ctxt, x, ##__VA_ARGS__); \
103 pr_info(x, ##__VA_ARGS__); \
104 } \
105} while (0)
106
Mayank Rana0663c432016-12-06 16:38:18 -0800107enum connection_state {
108 STATE_UNINITIALIZED,
109 STATE_INITIALIZED,
110 STATE_CONNECT_IN_PROGRESS,
111 STATE_CONNECTED,
112 STATE_DISCONNECTED,
113 STATE_SUSPEND_IN_PROGRESS,
114 STATE_SUSPENDED
115};
116
Mayank Rana16bc4d92016-12-07 13:47:44 -0800117enum gsi_ctrl_notify_state {
118 GSI_CTRL_NOTIFY_NONE,
119 GSI_CTRL_NOTIFY_CONNECT,
120 GSI_CTRL_NOTIFY_SPEED,
121 GSI_CTRL_NOTIFY_OFFLINE,
122 GSI_CTRL_NOTIFY_RESPONSE_AVAILABLE,
123};
124
Mayank Rana0663c432016-12-06 16:38:18 -0800125#define MAXQUEUELEN 128
126struct event_queue {
127 u8 event[MAXQUEUELEN];
128 u8 head, tail;
129 spinlock_t q_lock;
130};
131
132struct gsi_ntb_info {
133 u32 ntb_input_size;
134 u16 ntb_max_datagrams;
135 u16 reserved;
136};
137
138struct gsi_ctrl_pkt {
Mayank Rana16bc4d92016-12-07 13:47:44 -0800139 void *buf;
140 int len;
141 enum gsi_ctrl_notify_state type;
142 struct list_head list;
Mayank Rana0663c432016-12-06 16:38:18 -0800143};
144
145struct gsi_function_bind_info {
146 struct usb_string *string_defs;
147 int ctrl_str_idx;
148 int data_str_idx;
149 int iad_str_idx;
150 int mac_str_idx;
151 struct usb_interface_descriptor *ctrl_desc;
152 struct usb_interface_descriptor *data_desc;
153 struct usb_interface_assoc_descriptor *iad_desc;
154 struct usb_cdc_ether_desc *cdc_eth_desc;
155 struct usb_cdc_union_desc *union_desc;
156 struct usb_interface_descriptor *data_nop_desc;
157 struct usb_endpoint_descriptor *fs_in_desc;
158 struct usb_endpoint_descriptor *fs_out_desc;
159 struct usb_endpoint_descriptor *fs_notify_desc;
160 struct usb_endpoint_descriptor *hs_in_desc;
161 struct usb_endpoint_descriptor *hs_out_desc;
162 struct usb_endpoint_descriptor *hs_notify_desc;
163 struct usb_endpoint_descriptor *ss_in_desc;
164 struct usb_endpoint_descriptor *ss_out_desc;
165 struct usb_endpoint_descriptor *ss_notify_desc;
166
167 struct usb_descriptor_header **fs_desc_hdr;
168 struct usb_descriptor_header **hs_desc_hdr;
169 struct usb_descriptor_header **ss_desc_hdr;
170 const char *in_epname;
171 const char *out_epname;
172
173 u32 in_req_buf_len;
174 u32 in_req_num_buf;
175 u32 out_req_buf_len;
176 u32 out_req_num_buf;
177 u32 notify_buf_len;
178};
179
Mayank Rana0663c432016-12-06 16:38:18 -0800180struct gsi_ctrl_port {
181 char name[GSI_CTRL_NAME_LEN];
182 struct miscdevice ctrl_device;
183
184 struct usb_ep *notify;
185 struct usb_request *notify_req;
Mayank Rana16bc4d92016-12-07 13:47:44 -0800186 bool notify_req_queued;
Mayank Rana0663c432016-12-06 16:38:18 -0800187
188 atomic_t ctrl_online;
189
190 bool is_open;
191
192 wait_queue_head_t read_wq;
193
194 struct list_head cpkt_req_q;
195 struct list_head cpkt_resp_q;
196 unsigned long cpkts_len;
197
198 spinlock_t lock;
199
200 int ipa_cons_clnt_hdl;
201 int ipa_prod_clnt_hdl;
202
203 unsigned int host_to_modem;
204 unsigned int copied_to_modem;
205 unsigned int copied_from_modem;
206 unsigned int modem_to_host;
207 unsigned int cpkt_drop_cnt;
Mayank Rana16bc4d92016-12-07 13:47:44 -0800208 unsigned int get_encap_cnt;
Mayank Rana0663c432016-12-06 16:38:18 -0800209};
210
211struct gsi_data_port {
212 struct usb_ep *in_ep;
213 struct usb_ep *out_ep;
214 struct usb_gsi_request in_request;
215 struct usb_gsi_request out_request;
216 struct usb_gadget *gadget;
217 int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event, void *driver_data);
218 struct ipa_usb_teth_params ipa_init_params;
219 int in_channel_handle;
220 int out_channel_handle;
221 u32 in_db_reg_phs_addr_lsb;
222 u32 in_db_reg_phs_addr_msb;
223 u32 out_db_reg_phs_addr_lsb;
224 u32 out_db_reg_phs_addr_msb;
225 u32 in_xfer_rsc_index;
226 u32 out_xfer_rsc_index;
227 u16 in_last_trb_addr;
228 u16 cdc_filter;
229 u32 in_aggr_size;
230 u32 out_aggr_size;
231
232 bool ipa_ready;
233 bool net_ready_trigger;
234 struct gsi_ntb_info ntb_info;
235
236 spinlock_t lock;
237
238 struct work_struct usb_ipa_w;
239 struct workqueue_struct *ipa_usb_wq;
240 enum connection_state sm_state;
241 struct event_queue evt_q;
242 wait_queue_head_t wait_for_ipa_ready;
243
244 /* Track these for debugfs */
245 struct ipa_usb_xdci_chan_params ipa_in_channel_params;
246 struct ipa_usb_xdci_chan_params ipa_out_channel_params;
247 struct ipa_usb_xdci_connect_params ipa_conn_pms;
248};
249
250struct f_gsi {
251 struct usb_function function;
252 enum ipa_usb_teth_prot prot_id;
253 int ctrl_id;
254 int data_id;
255 u32 vendorID;
256 u8 ethaddr[ETH_ADDR_STR_LEN];
257 const char *manufacturer;
258 struct rndis_params *params;
259 atomic_t connected;
260 bool data_interface_up;
261
262 const struct usb_endpoint_descriptor *in_ep_desc_backup;
263 const struct usb_endpoint_descriptor *out_ep_desc_backup;
264
265 struct gsi_data_port d_port;
266 struct gsi_ctrl_port c_port;
Mayank Rana2ad687f2017-02-16 15:57:27 -0800267 void *ipc_log_ctxt;
Mayank Rana0663c432016-12-06 16:38:18 -0800268};
269
270static inline struct f_gsi *func_to_gsi(struct usb_function *f)
271{
272 return container_of(f, struct f_gsi, function);
273}
274
275static inline struct f_gsi *d_port_to_gsi(struct gsi_data_port *d)
276{
277 return container_of(d, struct f_gsi, d_port);
278}
279
280static inline struct f_gsi *c_port_to_gsi(struct gsi_ctrl_port *d)
281{
282 return container_of(d, struct f_gsi, c_port);
283}
284
285/* for configfs support */
286#define MAX_INST_NAME_LEN 40
287
288struct gsi_opts {
289 struct usb_function_instance func_inst;
290 struct f_gsi *gsi;
291};
292
293static inline struct gsi_opts *to_gsi_opts(struct config_item *item)
294{
295 return container_of(to_config_group(item), struct gsi_opts,
296 func_inst.group);
297}
298
299static enum ipa_usb_teth_prot name_to_prot_id(const char *name)
300{
301 if (!name)
302 goto error;
303
304 if (!strncasecmp(name, "rndis", strlen("rndis")))
305 return IPA_USB_RNDIS;
306 if (!strncasecmp(name, "ecm", strlen("ecm")))
307 return IPA_USB_ECM;
308 if (!strncasecmp(name, "rmnet", strlen("rmnet")))
309 return IPA_USB_RMNET;
310 if (!strncasecmp(name, "mbim", strlen("mbim")))
311 return IPA_USB_MBIM;
312 if (!strncasecmp(name, "dpl", strlen("dpl")))
313 return IPA_USB_DIAG;
314
315error:
316 return -EINVAL;
317}
318
319/* device descriptors */
320
321#define LOG2_STATUS_INTERVAL_MSEC 5
322#define MAX_NOTIFY_SIZE sizeof(struct usb_cdc_notification)
323
324/* rmnet device descriptors */
325
326static struct usb_interface_descriptor rmnet_gsi_interface_desc = {
327 .bLength = USB_DT_INTERFACE_SIZE,
328 .bDescriptorType = USB_DT_INTERFACE,
329 .bNumEndpoints = 3,
330 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
331 .bInterfaceSubClass = USB_CLASS_VENDOR_SPEC,
332 .bInterfaceProtocol = USB_CLASS_VENDOR_SPEC,
333 /* .iInterface = DYNAMIC */
334};
335
336/* Full speed support */
337static struct usb_endpoint_descriptor rmnet_gsi_fs_notify_desc = {
338 .bLength = USB_DT_ENDPOINT_SIZE,
339 .bDescriptorType = USB_DT_ENDPOINT,
340 .bEndpointAddress = USB_DIR_IN,
341 .bmAttributes = USB_ENDPOINT_XFER_INT,
342 .wMaxPacketSize = cpu_to_le16(MAX_NOTIFY_SIZE),
343 .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
344};
345
346static struct usb_endpoint_descriptor rmnet_gsi_fs_in_desc = {
347 .bLength = USB_DT_ENDPOINT_SIZE,
348 .bDescriptorType = USB_DT_ENDPOINT,
349 .bEndpointAddress = USB_DIR_IN,
350 .bmAttributes = USB_ENDPOINT_XFER_BULK,
351 .wMaxPacketSize = cpu_to_le16(64),
352};
353
354static struct usb_endpoint_descriptor rmnet_gsi_fs_out_desc = {
355 .bLength = USB_DT_ENDPOINT_SIZE,
356 .bDescriptorType = USB_DT_ENDPOINT,
357 .bEndpointAddress = USB_DIR_OUT,
358 .bmAttributes = USB_ENDPOINT_XFER_BULK,
359 .wMaxPacketSize = cpu_to_le16(64),
360};
361
362static struct usb_descriptor_header *rmnet_gsi_fs_function[] = {
363 (struct usb_descriptor_header *) &rmnet_gsi_interface_desc,
364 (struct usb_descriptor_header *) &rmnet_gsi_fs_notify_desc,
365 (struct usb_descriptor_header *) &rmnet_gsi_fs_in_desc,
366 (struct usb_descriptor_header *) &rmnet_gsi_fs_out_desc,
367 NULL,
368};
369
370/* High speed support */
371static struct usb_endpoint_descriptor rmnet_gsi_hs_notify_desc = {
372 .bLength = USB_DT_ENDPOINT_SIZE,
373 .bDescriptorType = USB_DT_ENDPOINT,
374 .bEndpointAddress = USB_DIR_IN,
375 .bmAttributes = USB_ENDPOINT_XFER_INT,
376 .wMaxPacketSize = cpu_to_le16(MAX_NOTIFY_SIZE),
377 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
378};
379
380static struct usb_endpoint_descriptor rmnet_gsi_hs_in_desc = {
381 .bLength = USB_DT_ENDPOINT_SIZE,
382 .bDescriptorType = USB_DT_ENDPOINT,
383 .bEndpointAddress = USB_DIR_IN,
384 .bmAttributes = USB_ENDPOINT_XFER_BULK,
385 .wMaxPacketSize = cpu_to_le16(512),
386};
387
388static struct usb_endpoint_descriptor rmnet_gsi_hs_out_desc = {
389 .bLength = USB_DT_ENDPOINT_SIZE,
390 .bDescriptorType = USB_DT_ENDPOINT,
391 .bEndpointAddress = USB_DIR_OUT,
392 .bmAttributes = USB_ENDPOINT_XFER_BULK,
393 .wMaxPacketSize = cpu_to_le16(512),
394};
395
396static struct usb_descriptor_header *rmnet_gsi_hs_function[] = {
397 (struct usb_descriptor_header *) &rmnet_gsi_interface_desc,
398 (struct usb_descriptor_header *) &rmnet_gsi_hs_notify_desc,
399 (struct usb_descriptor_header *) &rmnet_gsi_hs_in_desc,
400 (struct usb_descriptor_header *) &rmnet_gsi_hs_out_desc,
401 NULL,
402};
403
404/* Super speed support */
405static struct usb_endpoint_descriptor rmnet_gsi_ss_notify_desc = {
406 .bLength = USB_DT_ENDPOINT_SIZE,
407 .bDescriptorType = USB_DT_ENDPOINT,
408 .bEndpointAddress = USB_DIR_IN,
409 .bmAttributes = USB_ENDPOINT_XFER_INT,
410 .wMaxPacketSize = cpu_to_le16(MAX_NOTIFY_SIZE),
411 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
412};
413
414static struct usb_ss_ep_comp_descriptor rmnet_gsi_ss_notify_comp_desc = {
415 .bLength = sizeof(rmnet_gsi_ss_notify_comp_desc),
416 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
417
418 /* the following 3 values can be tweaked if necessary */
419 /* .bMaxBurst = 0, */
420 /* .bmAttributes = 0, */
421 .wBytesPerInterval = cpu_to_le16(MAX_NOTIFY_SIZE),
422};
423
424static struct usb_endpoint_descriptor rmnet_gsi_ss_in_desc = {
425 .bLength = USB_DT_ENDPOINT_SIZE,
426 .bDescriptorType = USB_DT_ENDPOINT,
427 .bEndpointAddress = USB_DIR_IN,
428 .bmAttributes = USB_ENDPOINT_XFER_BULK,
429 .wMaxPacketSize = cpu_to_le16(1024),
430};
431
432static struct usb_ss_ep_comp_descriptor rmnet_gsi_ss_in_comp_desc = {
433 .bLength = sizeof(rmnet_gsi_ss_in_comp_desc),
434 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
435
436 /* the following 2 values can be tweaked if necessary */
437 .bMaxBurst = 2,
438 /* .bmAttributes = 0, */
439};
440
441static struct usb_endpoint_descriptor rmnet_gsi_ss_out_desc = {
442 .bLength = USB_DT_ENDPOINT_SIZE,
443 .bDescriptorType = USB_DT_ENDPOINT,
444 .bEndpointAddress = USB_DIR_OUT,
445 .bmAttributes = USB_ENDPOINT_XFER_BULK,
446 .wMaxPacketSize = cpu_to_le16(1024),
447};
448
449static struct usb_ss_ep_comp_descriptor rmnet_gsi_ss_out_comp_desc = {
450 .bLength = sizeof(rmnet_gsi_ss_out_comp_desc),
451 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
452
453 /* the following 2 values can be tweaked if necessary */
454 .bMaxBurst = 2,
455 /* .bmAttributes = 0, */
456};
457
458static struct usb_descriptor_header *rmnet_gsi_ss_function[] = {
459 (struct usb_descriptor_header *) &rmnet_gsi_interface_desc,
460 (struct usb_descriptor_header *) &rmnet_gsi_ss_notify_desc,
461 (struct usb_descriptor_header *) &rmnet_gsi_ss_notify_comp_desc,
462 (struct usb_descriptor_header *) &rmnet_gsi_ss_in_desc,
463 (struct usb_descriptor_header *) &rmnet_gsi_ss_in_comp_desc,
464 (struct usb_descriptor_header *) &rmnet_gsi_ss_out_desc,
465 (struct usb_descriptor_header *) &rmnet_gsi_ss_out_comp_desc,
466 NULL,
467};
468
469/* String descriptors */
470static struct usb_string rmnet_gsi_string_defs[] = {
471 [0].s = "RmNet",
472 { } /* end of list */
473};
474
475static struct usb_gadget_strings rmnet_gsi_string_table = {
476 .language = 0x0409, /* en-us */
477 .strings = rmnet_gsi_string_defs,
478};
479
480static struct usb_gadget_strings *rmnet_gsi_strings[] = {
481 &rmnet_gsi_string_table,
482 NULL,
483};
484
485/* rndis device descriptors */
486
487/* interface descriptor: Supports "Wireless" RNDIS; auto-detected by Windows*/
488static struct usb_interface_descriptor rndis_gsi_control_intf = {
489 .bLength = sizeof(rndis_gsi_control_intf),
490 .bDescriptorType = USB_DT_INTERFACE,
491
492 /* .bInterfaceNumber = DYNAMIC */
493 /* status endpoint is optional; this could be patched later */
494 .bNumEndpoints = 1,
495 .bInterfaceClass = USB_CLASS_WIRELESS_CONTROLLER,
496 .bInterfaceSubClass = 0x01,
497 .bInterfaceProtocol = 0x03,
498 /* .iInterface = DYNAMIC */
499};
500
501static struct usb_cdc_header_desc rndis_gsi_header_desc = {
502 .bLength = sizeof(rndis_gsi_header_desc),
503 .bDescriptorType = USB_DT_CS_INTERFACE,
504 .bDescriptorSubType = USB_CDC_HEADER_TYPE,
505
506 .bcdCDC = cpu_to_le16(0x0110),
507};
508
509static struct usb_cdc_call_mgmt_descriptor rndis_gsi_call_mgmt_descriptor = {
510 .bLength = sizeof(rndis_gsi_call_mgmt_descriptor),
511 .bDescriptorType = USB_DT_CS_INTERFACE,
512 .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE,
513
514 .bmCapabilities = 0x00,
515 .bDataInterface = 0x01,
516};
517
518static struct usb_cdc_acm_descriptor rndis_gsi_acm_descriptor = {
519 .bLength = sizeof(rndis_gsi_acm_descriptor),
520 .bDescriptorType = USB_DT_CS_INTERFACE,
521 .bDescriptorSubType = USB_CDC_ACM_TYPE,
522
523 .bmCapabilities = 0x00,
524};
525
526static struct usb_cdc_union_desc rndis_gsi_union_desc = {
527 .bLength = sizeof(rndis_gsi_union_desc),
528 .bDescriptorType = USB_DT_CS_INTERFACE,
529 .bDescriptorSubType = USB_CDC_UNION_TYPE,
530 /* .bMasterInterface0 = DYNAMIC */
531 /* .bSlaveInterface0 = DYNAMIC */
532};
533
534/* the data interface has two bulk endpoints */
535
536static struct usb_interface_descriptor rndis_gsi_data_intf = {
537 .bLength = sizeof(rndis_gsi_data_intf),
538 .bDescriptorType = USB_DT_INTERFACE,
539
540 /* .bInterfaceNumber = DYNAMIC */
541 .bNumEndpoints = 2,
542 .bInterfaceClass = USB_CLASS_CDC_DATA,
543 .bInterfaceSubClass = 0,
544 .bInterfaceProtocol = 0,
545 /* .iInterface = DYNAMIC */
546};
547
548/* Supports "Wireless" RNDIS; auto-detected by Windows */
549static struct usb_interface_assoc_descriptor
550rndis_gsi_iad_descriptor = {
551 .bLength = sizeof(rndis_gsi_iad_descriptor),
552 .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
553 .bFirstInterface = 0, /* XXX, hardcoded */
554 .bInterfaceCount = 2, /* control + data */
555 .bFunctionClass = USB_CLASS_WIRELESS_CONTROLLER,
556 .bFunctionSubClass = 0x01,
557 .bFunctionProtocol = 0x03,
558 /* .iFunction = DYNAMIC */
559};
560
561/* full speed support: */
562static struct usb_endpoint_descriptor rndis_gsi_fs_notify_desc = {
563 .bLength = USB_DT_ENDPOINT_SIZE,
564 .bDescriptorType = USB_DT_ENDPOINT,
565
566 .bEndpointAddress = USB_DIR_IN,
567 .bmAttributes = USB_ENDPOINT_XFER_INT,
568 .wMaxPacketSize = cpu_to_le16(MAX_NOTIFY_SIZE),
569 .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
570};
571
572static struct usb_endpoint_descriptor rndis_gsi_fs_in_desc = {
573 .bLength = USB_DT_ENDPOINT_SIZE,
574 .bDescriptorType = USB_DT_ENDPOINT,
Pratham Pratap0a1aee52017-12-05 20:44:42 +0530575 .wMaxPacketSize = cpu_to_le16(64),
Mayank Rana0663c432016-12-06 16:38:18 -0800576 .bEndpointAddress = USB_DIR_IN,
577 .bmAttributes = USB_ENDPOINT_XFER_BULK,
578};
579
580static struct usb_endpoint_descriptor rndis_gsi_fs_out_desc = {
581 .bLength = USB_DT_ENDPOINT_SIZE,
582 .bDescriptorType = USB_DT_ENDPOINT,
Pratham Pratap0a1aee52017-12-05 20:44:42 +0530583 .wMaxPacketSize = cpu_to_le16(64),
Mayank Rana0663c432016-12-06 16:38:18 -0800584 .bEndpointAddress = USB_DIR_OUT,
585 .bmAttributes = USB_ENDPOINT_XFER_BULK,
586};
587
588static struct usb_descriptor_header *gsi_eth_fs_function[] = {
Mayank Rana4f7918f2017-11-10 14:20:32 -0800589 (struct usb_descriptor_header *) &rndis_gsi_iad_descriptor,
Mayank Rana0663c432016-12-06 16:38:18 -0800590 /* control interface matches ACM, not Ethernet */
591 (struct usb_descriptor_header *) &rndis_gsi_control_intf,
592 (struct usb_descriptor_header *) &rndis_gsi_header_desc,
593 (struct usb_descriptor_header *) &rndis_gsi_call_mgmt_descriptor,
594 (struct usb_descriptor_header *) &rndis_gsi_acm_descriptor,
595 (struct usb_descriptor_header *) &rndis_gsi_union_desc,
596 (struct usb_descriptor_header *) &rndis_gsi_fs_notify_desc,
597 /* data interface has no altsetting */
598 (struct usb_descriptor_header *) &rndis_gsi_data_intf,
599 (struct usb_descriptor_header *) &rndis_gsi_fs_in_desc,
600 (struct usb_descriptor_header *) &rndis_gsi_fs_out_desc,
601 NULL,
602};
603
604/* high speed support: */
605static struct usb_endpoint_descriptor rndis_gsi_hs_notify_desc = {
606 .bLength = USB_DT_ENDPOINT_SIZE,
607 .bDescriptorType = USB_DT_ENDPOINT,
608
609 .bEndpointAddress = USB_DIR_IN,
610 .bmAttributes = USB_ENDPOINT_XFER_INT,
611 .wMaxPacketSize = cpu_to_le16(MAX_NOTIFY_SIZE),
612 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
613};
614static struct usb_endpoint_descriptor rndis_gsi_hs_in_desc = {
615 .bLength = USB_DT_ENDPOINT_SIZE,
616 .bDescriptorType = USB_DT_ENDPOINT,
617
618 .bEndpointAddress = USB_DIR_IN,
619 .bmAttributes = USB_ENDPOINT_XFER_BULK,
620 .wMaxPacketSize = cpu_to_le16(512),
621};
622
623static struct usb_endpoint_descriptor rndis_gsi_hs_out_desc = {
624 .bLength = USB_DT_ENDPOINT_SIZE,
625 .bDescriptorType = USB_DT_ENDPOINT,
626
627 .bEndpointAddress = USB_DIR_OUT,
628 .bmAttributes = USB_ENDPOINT_XFER_BULK,
629 .wMaxPacketSize = cpu_to_le16(512),
630};
631
632static struct usb_descriptor_header *gsi_eth_hs_function[] = {
633 (struct usb_descriptor_header *) &rndis_gsi_iad_descriptor,
634 /* control interface matches ACM, not Ethernet */
635 (struct usb_descriptor_header *) &rndis_gsi_control_intf,
636 (struct usb_descriptor_header *) &rndis_gsi_header_desc,
637 (struct usb_descriptor_header *) &rndis_gsi_call_mgmt_descriptor,
638 (struct usb_descriptor_header *) &rndis_gsi_acm_descriptor,
639 (struct usb_descriptor_header *) &rndis_gsi_union_desc,
640 (struct usb_descriptor_header *) &rndis_gsi_hs_notify_desc,
641 /* data interface has no altsetting */
642 (struct usb_descriptor_header *) &rndis_gsi_data_intf,
643 (struct usb_descriptor_header *) &rndis_gsi_hs_in_desc,
644 (struct usb_descriptor_header *) &rndis_gsi_hs_out_desc,
645 NULL,
646};
647
648/* super speed support: */
649static struct usb_endpoint_descriptor rndis_gsi_ss_notify_desc = {
650 .bLength = USB_DT_ENDPOINT_SIZE,
651 .bDescriptorType = USB_DT_ENDPOINT,
652
653 .bEndpointAddress = USB_DIR_IN,
654 .bmAttributes = USB_ENDPOINT_XFER_INT,
655 .wMaxPacketSize = cpu_to_le16(MAX_NOTIFY_SIZE),
656 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
657};
658
659static struct usb_ss_ep_comp_descriptor rndis_gsi_ss_intr_comp_desc = {
660 .bLength = sizeof(rndis_gsi_ss_intr_comp_desc),
661 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
662
663 /* the following 3 values can be tweaked if necessary */
664 /* .bMaxBurst = 0, */
665 /* .bmAttributes = 0, */
666 .wBytesPerInterval = cpu_to_le16(MAX_NOTIFY_SIZE),
667};
668
669static struct usb_endpoint_descriptor rndis_gsi_ss_in_desc = {
670 .bLength = USB_DT_ENDPOINT_SIZE,
671 .bDescriptorType = USB_DT_ENDPOINT,
672
673 .bEndpointAddress = USB_DIR_IN,
674 .bmAttributes = USB_ENDPOINT_XFER_BULK,
675 .wMaxPacketSize = cpu_to_le16(1024),
676};
677
678static struct usb_endpoint_descriptor rndis_gsi_ss_out_desc = {
679 .bLength = USB_DT_ENDPOINT_SIZE,
680 .bDescriptorType = USB_DT_ENDPOINT,
681
682 .bEndpointAddress = USB_DIR_OUT,
683 .bmAttributes = USB_ENDPOINT_XFER_BULK,
684 .wMaxPacketSize = cpu_to_le16(1024),
685};
686
687static struct usb_ss_ep_comp_descriptor rndis_gsi_ss_bulk_comp_desc = {
688 .bLength = sizeof(rndis_gsi_ss_bulk_comp_desc),
689 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
690
691 /* the following 2 values can be tweaked if necessary */
692 .bMaxBurst = 2,
693 /* .bmAttributes = 0, */
694};
695
696static struct usb_descriptor_header *gsi_eth_ss_function[] = {
697 (struct usb_descriptor_header *) &rndis_gsi_iad_descriptor,
698
699 /* control interface matches ACM, not Ethernet */
700 (struct usb_descriptor_header *) &rndis_gsi_control_intf,
701 (struct usb_descriptor_header *) &rndis_gsi_header_desc,
702 (struct usb_descriptor_header *) &rndis_gsi_call_mgmt_descriptor,
703 (struct usb_descriptor_header *) &rndis_gsi_acm_descriptor,
704 (struct usb_descriptor_header *) &rndis_gsi_union_desc,
705 (struct usb_descriptor_header *) &rndis_gsi_ss_notify_desc,
706 (struct usb_descriptor_header *) &rndis_gsi_ss_intr_comp_desc,
707
708 /* data interface has no altsetting */
709 (struct usb_descriptor_header *) &rndis_gsi_data_intf,
710 (struct usb_descriptor_header *) &rndis_gsi_ss_in_desc,
711 (struct usb_descriptor_header *) &rndis_gsi_ss_bulk_comp_desc,
712 (struct usb_descriptor_header *) &rndis_gsi_ss_out_desc,
713 (struct usb_descriptor_header *) &rndis_gsi_ss_bulk_comp_desc,
714 NULL,
715};
716
717/* string descriptors: */
718static struct usb_string rndis_gsi_string_defs[] = {
719 [0].s = "RNDIS Communications Control",
720 [1].s = "RNDIS Ethernet Data",
721 [2].s = "RNDIS",
722 { } /* end of list */
723};
724
725static struct usb_gadget_strings rndis_gsi_string_table = {
726 .language = 0x0409, /* en-us */
727 .strings = rndis_gsi_string_defs,
728};
729
730static struct usb_gadget_strings *rndis_gsi_strings[] = {
731 &rndis_gsi_string_table,
732 NULL,
733};
734
735/* mbim device descriptors */
736#define MBIM_NTB_DEFAULT_IN_SIZE (0x4000)
737
738static struct usb_cdc_ncm_ntb_parameters mbim_gsi_ntb_parameters = {
739 .wLength = sizeof(mbim_gsi_ntb_parameters),
740 .bmNtbFormatsSupported = cpu_to_le16(USB_CDC_NCM_NTB16_SUPPORTED),
741 .dwNtbInMaxSize = cpu_to_le32(MBIM_NTB_DEFAULT_IN_SIZE),
742 .wNdpInDivisor = cpu_to_le16(4),
743 .wNdpInPayloadRemainder = cpu_to_le16(0),
744 .wNdpInAlignment = cpu_to_le16(4),
745
746 .dwNtbOutMaxSize = cpu_to_le32(0x4000),
747 .wNdpOutDivisor = cpu_to_le16(4),
748 .wNdpOutPayloadRemainder = cpu_to_le16(0),
749 .wNdpOutAlignment = cpu_to_le16(4),
750 .wNtbOutMaxDatagrams = 16,
751};
752
753/*
754 * Use wMaxPacketSize big enough to fit CDC_NOTIFY_SPEED_CHANGE in one
755 * packet, to simplify cancellation;
756 */
757#define NCM_STATUS_BYTECOUNT 16 /* 8 byte header + data */
758
759static struct usb_interface_assoc_descriptor mbim_gsi_iad_desc = {
760 .bLength = sizeof(mbim_gsi_iad_desc),
761 .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
762
763 /* .bFirstInterface = DYNAMIC, */
764 .bInterfaceCount = 2, /* control + data */
765 .bFunctionClass = 2,
766 .bFunctionSubClass = 0x0e,
767 .bFunctionProtocol = 0,
768 /* .iFunction = DYNAMIC */
769};
770
771/* interface descriptor: */
772static struct usb_interface_descriptor mbim_gsi_control_intf = {
773 .bLength = sizeof(mbim_gsi_control_intf),
774 .bDescriptorType = USB_DT_INTERFACE,
775
776 /* .bInterfaceNumber = DYNAMIC */
777 .bNumEndpoints = 1,
778 .bInterfaceClass = 0x02,
779 .bInterfaceSubClass = 0x0e,
780 .bInterfaceProtocol = 0,
781 /* .iInterface = DYNAMIC */
782};
783
784static struct usb_cdc_header_desc mbim_gsi_header_desc = {
785 .bLength = sizeof(mbim_gsi_header_desc),
786 .bDescriptorType = USB_DT_CS_INTERFACE,
787 .bDescriptorSubType = USB_CDC_HEADER_TYPE,
788
789 .bcdCDC = cpu_to_le16(0x0110),
790};
791
792static struct usb_cdc_union_desc mbim_gsi_union_desc = {
793 .bLength = sizeof(mbim_gsi_union_desc),
794 .bDescriptorType = USB_DT_CS_INTERFACE,
795 .bDescriptorSubType = USB_CDC_UNION_TYPE,
796 /* .bMasterInterface0 = DYNAMIC */
797 /* .bSlaveInterface0 = DYNAMIC */
798};
799
800static struct usb_cdc_mbim_desc mbim_gsi_desc = {
801 .bLength = sizeof(mbim_gsi_desc),
802 .bDescriptorType = USB_DT_CS_INTERFACE,
803 .bDescriptorSubType = USB_CDC_MBIM_TYPE,
804
805 .bcdMBIMVersion = cpu_to_le16(0x0100),
806
807 .wMaxControlMessage = cpu_to_le16(0x1000),
808 .bNumberFilters = 0x20,
809 .bMaxFilterSize = 0x80,
810 .wMaxSegmentSize = cpu_to_le16(0xfe0),
811 .bmNetworkCapabilities = 0x20,
812};
813
814static struct usb_cdc_mbim_extended_desc mbim_gsi_ext_mbb_desc = {
815 .bLength = sizeof(mbim_gsi_ext_mbb_desc),
816 .bDescriptorType = USB_DT_CS_INTERFACE,
817 .bDescriptorSubType = USB_CDC_MBIM_EXTENDED_TYPE,
818
819 .bcdMBIMExtendedVersion = cpu_to_le16(0x0100),
820 .bMaxOutstandingCommandMessages = 64,
821 .wMTU = cpu_to_le16(1500),
822};
823
824/* the default data interface has no endpoints ... */
825static struct usb_interface_descriptor mbim_gsi_data_nop_intf = {
826 .bLength = sizeof(mbim_gsi_data_nop_intf),
827 .bDescriptorType = USB_DT_INTERFACE,
828
829 /* .bInterfaceNumber = DYNAMIC */
830 .bAlternateSetting = 0,
831 .bNumEndpoints = 0,
832 .bInterfaceClass = 0x0a,
833 .bInterfaceSubClass = 0,
834 .bInterfaceProtocol = 0x02,
835 /* .iInterface = DYNAMIC */
836};
837
838/* ... but the "real" data interface has two bulk endpoints */
839static struct usb_interface_descriptor mbim_gsi_data_intf = {
840 .bLength = sizeof(mbim_gsi_data_intf),
841 .bDescriptorType = USB_DT_INTERFACE,
842
843 /* .bInterfaceNumber = DYNAMIC */
844 .bAlternateSetting = 1,
845 .bNumEndpoints = 2,
846 .bInterfaceClass = 0x0a,
847 .bInterfaceSubClass = 0,
848 .bInterfaceProtocol = 0x02,
849 /* .iInterface = DYNAMIC */
850};
851
852/* full speed support: */
853
854static struct usb_endpoint_descriptor mbim_gsi_fs_notify_desc = {
855 .bLength = USB_DT_ENDPOINT_SIZE,
856 .bDescriptorType = USB_DT_ENDPOINT,
857
858 .bEndpointAddress = USB_DIR_IN,
859 .bmAttributes = USB_ENDPOINT_XFER_INT,
860 .wMaxPacketSize = 4*cpu_to_le16(NCM_STATUS_BYTECOUNT),
861 .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
862};
863
864static struct usb_endpoint_descriptor mbim_gsi_fs_in_desc = {
865 .bLength = USB_DT_ENDPOINT_SIZE,
866 .bDescriptorType = USB_DT_ENDPOINT,
867
868 .bEndpointAddress = USB_DIR_IN,
869 .bmAttributes = USB_ENDPOINT_XFER_BULK,
870};
871
872static struct usb_endpoint_descriptor mbim_gsi_fs_out_desc = {
873 .bLength = USB_DT_ENDPOINT_SIZE,
874 .bDescriptorType = USB_DT_ENDPOINT,
875
876 .bEndpointAddress = USB_DIR_OUT,
877 .bmAttributes = USB_ENDPOINT_XFER_BULK,
878};
879
880static struct usb_descriptor_header *mbim_gsi_fs_function[] = {
881 (struct usb_descriptor_header *) &mbim_gsi_iad_desc,
882 /* MBIM control descriptors */
883 (struct usb_descriptor_header *) &mbim_gsi_control_intf,
884 (struct usb_descriptor_header *) &mbim_gsi_header_desc,
885 (struct usb_descriptor_header *) &mbim_gsi_union_desc,
886 (struct usb_descriptor_header *) &mbim_gsi_desc,
887 (struct usb_descriptor_header *) &mbim_gsi_ext_mbb_desc,
888 (struct usb_descriptor_header *) &mbim_gsi_fs_notify_desc,
889 /* data interface, altsettings 0 and 1 */
890 (struct usb_descriptor_header *) &mbim_gsi_data_nop_intf,
891 (struct usb_descriptor_header *) &mbim_gsi_data_intf,
892 (struct usb_descriptor_header *) &mbim_gsi_fs_in_desc,
893 (struct usb_descriptor_header *) &mbim_gsi_fs_out_desc,
894 NULL,
895};
896
897/* high speed support: */
898static struct usb_endpoint_descriptor mbim_gsi_hs_notify_desc = {
899 .bLength = USB_DT_ENDPOINT_SIZE,
900 .bDescriptorType = USB_DT_ENDPOINT,
901
902 .bEndpointAddress = USB_DIR_IN,
903 .bmAttributes = USB_ENDPOINT_XFER_INT,
904 .wMaxPacketSize = 4*cpu_to_le16(NCM_STATUS_BYTECOUNT),
905 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
906};
907static struct usb_endpoint_descriptor mbim_gsi_hs_in_desc = {
908 .bLength = USB_DT_ENDPOINT_SIZE,
909 .bDescriptorType = USB_DT_ENDPOINT,
910
911 .bEndpointAddress = USB_DIR_IN,
912 .bmAttributes = USB_ENDPOINT_XFER_BULK,
913 .wMaxPacketSize = cpu_to_le16(512),
914};
915
916static struct usb_endpoint_descriptor mbim_gsi_hs_out_desc = {
917 .bLength = USB_DT_ENDPOINT_SIZE,
918 .bDescriptorType = USB_DT_ENDPOINT,
919
920 .bEndpointAddress = USB_DIR_OUT,
921 .bmAttributes = USB_ENDPOINT_XFER_BULK,
922 .wMaxPacketSize = cpu_to_le16(512),
923};
924
925static struct usb_descriptor_header *mbim_gsi_hs_function[] = {
926 (struct usb_descriptor_header *) &mbim_gsi_iad_desc,
927 /* MBIM control descriptors */
928 (struct usb_descriptor_header *) &mbim_gsi_control_intf,
929 (struct usb_descriptor_header *) &mbim_gsi_header_desc,
930 (struct usb_descriptor_header *) &mbim_gsi_union_desc,
931 (struct usb_descriptor_header *) &mbim_gsi_desc,
932 (struct usb_descriptor_header *) &mbim_gsi_ext_mbb_desc,
933 (struct usb_descriptor_header *) &mbim_gsi_hs_notify_desc,
934 /* data interface, altsettings 0 and 1 */
935 (struct usb_descriptor_header *) &mbim_gsi_data_nop_intf,
936 (struct usb_descriptor_header *) &mbim_gsi_data_intf,
937 (struct usb_descriptor_header *) &mbim_gsi_hs_in_desc,
938 (struct usb_descriptor_header *) &mbim_gsi_hs_out_desc,
939 NULL,
940};
941
942/* Super Speed Support */
943static struct usb_endpoint_descriptor mbim_gsi_ss_notify_desc = {
944 .bLength = USB_DT_ENDPOINT_SIZE,
945 .bDescriptorType = USB_DT_ENDPOINT,
946 .bEndpointAddress = USB_DIR_IN,
947 .bmAttributes = USB_ENDPOINT_XFER_INT,
948 .wMaxPacketSize = 4*cpu_to_le16(NCM_STATUS_BYTECOUNT),
949 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
950};
951
952static struct usb_ss_ep_comp_descriptor mbim_gsi_ss_notify_comp_desc = {
953 .bLength = sizeof(mbim_gsi_ss_notify_comp_desc),
954 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
955
956 /* the following 3 values can be tweaked if necessary */
957 /* .bMaxBurst = 0, */
958 /* .bmAttributes = 0, */
959 .wBytesPerInterval = 4*cpu_to_le16(NCM_STATUS_BYTECOUNT),
960};
961
962static struct usb_endpoint_descriptor mbim_gsi_ss_in_desc = {
963 .bLength = USB_DT_ENDPOINT_SIZE,
964 .bDescriptorType = USB_DT_ENDPOINT,
965 .bEndpointAddress = USB_DIR_IN,
966 .bmAttributes = USB_ENDPOINT_XFER_BULK,
967 .wMaxPacketSize = cpu_to_le16(1024),
968};
969
970static struct usb_ss_ep_comp_descriptor mbim_gsi_ss_in_comp_desc = {
971 .bLength = sizeof(mbim_gsi_ss_in_comp_desc),
972 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
973
974 /* the following 2 values can be tweaked if necessary */
975 .bMaxBurst = 2,
976 /* .bmAttributes = 0, */
977};
978
979static struct usb_endpoint_descriptor mbim_gsi_ss_out_desc = {
980 .bLength = USB_DT_ENDPOINT_SIZE,
981 .bDescriptorType = USB_DT_ENDPOINT,
982 .bEndpointAddress = USB_DIR_OUT,
983 .bmAttributes = USB_ENDPOINT_XFER_BULK,
984 .wMaxPacketSize = cpu_to_le16(1024),
985};
986
987static struct usb_ss_ep_comp_descriptor mbim_gsi_ss_out_comp_desc = {
988 .bLength = sizeof(mbim_gsi_ss_out_comp_desc),
989 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
990
991 /* the following 2 values can be tweaked if necessary */
992 .bMaxBurst = 2,
993 /* .bmAttributes = 0, */
994};
995
996static struct usb_descriptor_header *mbim_gsi_ss_function[] = {
997 (struct usb_descriptor_header *) &mbim_gsi_iad_desc,
998 /* MBIM control descriptors */
999 (struct usb_descriptor_header *) &mbim_gsi_control_intf,
1000 (struct usb_descriptor_header *) &mbim_gsi_header_desc,
1001 (struct usb_descriptor_header *) &mbim_gsi_union_desc,
1002 (struct usb_descriptor_header *) &mbim_gsi_desc,
1003 (struct usb_descriptor_header *) &mbim_gsi_ext_mbb_desc,
1004 (struct usb_descriptor_header *) &mbim_gsi_ss_notify_desc,
1005 (struct usb_descriptor_header *) &mbim_gsi_ss_notify_comp_desc,
1006 /* data interface, altsettings 0 and 1 */
1007 (struct usb_descriptor_header *) &mbim_gsi_data_nop_intf,
1008 (struct usb_descriptor_header *) &mbim_gsi_data_intf,
1009 (struct usb_descriptor_header *) &mbim_gsi_ss_in_desc,
1010 (struct usb_descriptor_header *) &mbim_gsi_ss_in_comp_desc,
1011 (struct usb_descriptor_header *) &mbim_gsi_ss_out_desc,
1012 (struct usb_descriptor_header *) &mbim_gsi_ss_out_comp_desc,
1013 NULL,
1014};
1015
1016/* string descriptors: */
1017static struct usb_string mbim_gsi_string_defs[] = {
1018 [0].s = "MBIM Control",
1019 [1].s = "MBIM Data",
1020 { } /* end of list */
1021};
1022
1023static struct usb_gadget_strings mbim_gsi_string_table = {
1024 .language = 0x0409, /* en-us */
1025 .strings = mbim_gsi_string_defs,
1026};
1027
1028static struct usb_gadget_strings *mbim_gsi_strings[] = {
1029 &mbim_gsi_string_table,
1030 NULL,
1031};
1032
1033/* Microsoft OS Descriptors */
1034
1035/*
1036 * We specify our own bMS_VendorCode byte which Windows will use
1037 * as the bRequest value in subsequent device get requests.
1038 */
1039#define MBIM_VENDOR_CODE 0xA5
1040
1041/* Microsoft Extended Configuration Descriptor Header Section */
1042struct mbim_gsi_ext_config_desc_header {
1043 __le32 dwLength;
1044 __u16 bcdVersion;
1045 __le16 wIndex;
1046 __u8 bCount;
1047 __u8 reserved[7];
1048};
1049
1050/* Microsoft Extended Configuration Descriptor Function Section */
1051struct mbim_gsi_ext_config_desc_function {
1052 __u8 bFirstInterfaceNumber;
1053 __u8 bInterfaceCount;
1054 __u8 compatibleID[8];
1055 __u8 subCompatibleID[8];
1056 __u8 reserved[6];
1057};
1058
1059/* Microsoft Extended Configuration Descriptor */
1060static struct {
1061 struct mbim_gsi_ext_config_desc_header header;
1062 struct mbim_gsi_ext_config_desc_function function;
1063} mbim_gsi_ext_config_desc = {
1064 .header = {
1065 .dwLength = cpu_to_le32(sizeof(mbim_gsi_ext_config_desc)),
1066 .bcdVersion = cpu_to_le16(0x0100),
1067 .wIndex = cpu_to_le16(4),
1068 .bCount = 1,
1069 },
1070 .function = {
1071 .bFirstInterfaceNumber = 0,
1072 .bInterfaceCount = 1,
1073 .compatibleID = { 'A', 'L', 'T', 'R', 'C', 'F', 'G' },
1074 /* .subCompatibleID = DYNAMIC */
1075 },
1076};
1077/* ecm device descriptors */
1078#define ECM_QC_LOG2_STATUS_INTERVAL_MSEC 5
1079#define ECM_QC_STATUS_BYTECOUNT 16 /* 8 byte header + data */
1080
1081/* interface descriptor: */
1082static struct usb_interface_descriptor ecm_gsi_control_intf = {
1083 .bLength = sizeof(ecm_gsi_control_intf),
1084 .bDescriptorType = USB_DT_INTERFACE,
1085
1086 /* .bInterfaceNumber = DYNAMIC */
1087 /* status endpoint is optional; this could be patched later */
1088 .bNumEndpoints = 1,
1089 .bInterfaceClass = USB_CLASS_COMM,
1090 .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
1091 .bInterfaceProtocol = USB_CDC_PROTO_NONE,
1092 /* .iInterface = DYNAMIC */
1093};
1094
1095static struct usb_cdc_header_desc ecm_gsi_header_desc = {
1096 .bLength = sizeof(ecm_gsi_header_desc),
1097 .bDescriptorType = USB_DT_CS_INTERFACE,
1098 .bDescriptorSubType = USB_CDC_HEADER_TYPE,
1099
1100 .bcdCDC = cpu_to_le16(0x0110),
1101};
1102
1103static struct usb_cdc_union_desc ecm_gsi_union_desc = {
1104 .bLength = sizeof(ecm_gsi_union_desc),
1105 .bDescriptorType = USB_DT_CS_INTERFACE,
1106 .bDescriptorSubType = USB_CDC_UNION_TYPE,
1107 /* .bMasterInterface0 = DYNAMIC */
1108 /* .bSlaveInterface0 = DYNAMIC */
1109};
1110
1111static struct usb_cdc_ether_desc ecm_gsi_desc = {
1112 .bLength = sizeof(ecm_gsi_desc),
1113 .bDescriptorType = USB_DT_CS_INTERFACE,
1114 .bDescriptorSubType = USB_CDC_ETHERNET_TYPE,
1115
1116 /* this descriptor actually adds value, surprise! */
1117 /* .iMACAddress = DYNAMIC */
1118 .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */
1119 .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN),
1120 .wNumberMCFilters = cpu_to_le16(0),
1121 .bNumberPowerFilters = 0,
1122};
1123
1124/* the default data interface has no endpoints ... */
1125
1126static struct usb_interface_descriptor ecm_gsi_data_nop_intf = {
1127 .bLength = sizeof(ecm_gsi_data_nop_intf),
1128 .bDescriptorType = USB_DT_INTERFACE,
1129
1130 .bInterfaceNumber = 1,
1131 .bAlternateSetting = 0,
1132 .bNumEndpoints = 0,
1133 .bInterfaceClass = USB_CLASS_CDC_DATA,
1134 .bInterfaceSubClass = 0,
1135 .bInterfaceProtocol = 0,
1136 /* .iInterface = DYNAMIC */
1137};
1138
1139/* ... but the "real" data interface has two bulk endpoints */
1140
1141static struct usb_interface_descriptor ecm_gsi_data_intf = {
1142 .bLength = sizeof(ecm_gsi_data_intf),
1143 .bDescriptorType = USB_DT_INTERFACE,
1144
1145 .bInterfaceNumber = 1,
1146 .bAlternateSetting = 1,
1147 .bNumEndpoints = 2,
1148 .bInterfaceClass = USB_CLASS_CDC_DATA,
1149 .bInterfaceSubClass = 0,
1150 .bInterfaceProtocol = 0,
1151 /* .iInterface = DYNAMIC */
1152};
1153
1154/* full speed support: */
1155static struct usb_endpoint_descriptor ecm_gsi_fs_notify_desc = {
1156 .bLength = USB_DT_ENDPOINT_SIZE,
1157 .bDescriptorType = USB_DT_ENDPOINT,
1158
1159 .bEndpointAddress = USB_DIR_IN,
1160 .bmAttributes = USB_ENDPOINT_XFER_INT,
1161 .wMaxPacketSize = cpu_to_le16(ECM_QC_STATUS_BYTECOUNT),
1162 .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
1163};
1164
1165static struct usb_endpoint_descriptor ecm_gsi_fs_in_desc = {
1166 .bLength = USB_DT_ENDPOINT_SIZE,
1167 .bDescriptorType = USB_DT_ENDPOINT,
1168
1169 .bEndpointAddress = USB_DIR_IN,
1170 .bmAttributes = USB_ENDPOINT_XFER_BULK,
1171};
1172
1173static struct usb_endpoint_descriptor ecm_gsi_fs_out_desc = {
1174 .bLength = USB_DT_ENDPOINT_SIZE,
1175 .bDescriptorType = USB_DT_ENDPOINT,
1176
1177 .bEndpointAddress = USB_DIR_OUT,
1178 .bmAttributes = USB_ENDPOINT_XFER_BULK,
1179};
1180
1181static struct usb_descriptor_header *ecm_gsi_fs_function[] = {
1182 /* CDC ECM control descriptors */
1183 (struct usb_descriptor_header *) &ecm_gsi_control_intf,
1184 (struct usb_descriptor_header *) &ecm_gsi_header_desc,
1185 (struct usb_descriptor_header *) &ecm_gsi_union_desc,
1186 (struct usb_descriptor_header *) &ecm_gsi_desc,
1187 /* NOTE: status endpoint might need to be removed */
1188 (struct usb_descriptor_header *) &ecm_gsi_fs_notify_desc,
1189 /* data interface, altsettings 0 and 1 */
1190 (struct usb_descriptor_header *) &ecm_gsi_data_nop_intf,
1191 (struct usb_descriptor_header *) &ecm_gsi_data_intf,
1192 (struct usb_descriptor_header *) &ecm_gsi_fs_in_desc,
1193 (struct usb_descriptor_header *) &ecm_gsi_fs_out_desc,
1194 NULL,
1195};
1196
1197/* high speed support: */
1198static struct usb_endpoint_descriptor ecm_gsi_hs_notify_desc = {
1199 .bLength = USB_DT_ENDPOINT_SIZE,
1200 .bDescriptorType = USB_DT_ENDPOINT,
1201
1202 .bEndpointAddress = USB_DIR_IN,
1203 .bmAttributes = USB_ENDPOINT_XFER_INT,
1204 .wMaxPacketSize = cpu_to_le16(ECM_QC_STATUS_BYTECOUNT),
1205 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
1206};
1207static struct usb_endpoint_descriptor ecm_gsi_hs_in_desc = {
1208 .bLength = USB_DT_ENDPOINT_SIZE,
1209 .bDescriptorType = USB_DT_ENDPOINT,
1210
1211 .bEndpointAddress = USB_DIR_IN,
1212 .bmAttributes = USB_ENDPOINT_XFER_BULK,
1213 .wMaxPacketSize = cpu_to_le16(512),
1214};
1215
1216static struct usb_endpoint_descriptor ecm_gsi_hs_out_desc = {
1217 .bLength = USB_DT_ENDPOINT_SIZE,
1218 .bDescriptorType = USB_DT_ENDPOINT,
1219
1220 .bEndpointAddress = USB_DIR_OUT,
1221 .bmAttributes = USB_ENDPOINT_XFER_BULK,
1222 .wMaxPacketSize = cpu_to_le16(512),
1223};
1224
1225static struct usb_descriptor_header *ecm_gsi_hs_function[] = {
1226 /* CDC ECM control descriptors */
1227 (struct usb_descriptor_header *) &ecm_gsi_control_intf,
1228 (struct usb_descriptor_header *) &ecm_gsi_header_desc,
1229 (struct usb_descriptor_header *) &ecm_gsi_union_desc,
1230 (struct usb_descriptor_header *) &ecm_gsi_desc,
1231 /* NOTE: status endpoint might need to be removed */
1232 (struct usb_descriptor_header *) &ecm_gsi_hs_notify_desc,
1233 /* data interface, altsettings 0 and 1 */
1234 (struct usb_descriptor_header *) &ecm_gsi_data_nop_intf,
1235 (struct usb_descriptor_header *) &ecm_gsi_data_intf,
1236 (struct usb_descriptor_header *) &ecm_gsi_hs_in_desc,
1237 (struct usb_descriptor_header *) &ecm_gsi_hs_out_desc,
1238 NULL,
1239};
1240
1241static struct usb_endpoint_descriptor ecm_gsi_ss_notify_desc = {
1242 .bLength = USB_DT_ENDPOINT_SIZE,
1243 .bDescriptorType = USB_DT_ENDPOINT,
1244 .bEndpointAddress = USB_DIR_IN,
1245 .bmAttributes = USB_ENDPOINT_XFER_INT,
1246 .wMaxPacketSize = cpu_to_le16(ECM_QC_STATUS_BYTECOUNT),
1247 .bInterval = ECM_QC_LOG2_STATUS_INTERVAL_MSEC + 4,
1248};
1249
1250static struct usb_ss_ep_comp_descriptor ecm_gsi_ss_notify_comp_desc = {
1251 .bLength = sizeof(ecm_gsi_ss_notify_comp_desc),
1252 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
1253
1254 /* the following 3 values can be tweaked if necessary */
1255 /* .bMaxBurst = 0, */
1256 /* .bmAttributes = 0, */
1257 .wBytesPerInterval = cpu_to_le16(ECM_QC_STATUS_BYTECOUNT),
1258};
1259
1260static struct usb_endpoint_descriptor ecm_gsi_ss_in_desc = {
1261 .bLength = USB_DT_ENDPOINT_SIZE,
1262 .bDescriptorType = USB_DT_ENDPOINT,
1263 .bEndpointAddress = USB_DIR_IN,
1264 .bmAttributes = USB_ENDPOINT_XFER_BULK,
1265 .wMaxPacketSize = cpu_to_le16(1024),
1266};
1267
1268static struct usb_ss_ep_comp_descriptor ecm_gsi_ss_in_comp_desc = {
1269 .bLength = sizeof(ecm_gsi_ss_in_comp_desc),
1270 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
1271
1272 /* the following 2 values can be tweaked if necessary */
1273 .bMaxBurst = 2,
1274 /* .bmAttributes = 0, */
1275};
1276
1277static struct usb_endpoint_descriptor ecm_gsi_ss_out_desc = {
1278 .bLength = USB_DT_ENDPOINT_SIZE,
1279 .bDescriptorType = USB_DT_ENDPOINT,
1280 .bEndpointAddress = USB_DIR_OUT,
1281 .bmAttributes = USB_ENDPOINT_XFER_BULK,
1282 .wMaxPacketSize = cpu_to_le16(1024),
1283};
1284
1285static struct usb_ss_ep_comp_descriptor ecm_gsi_ss_out_comp_desc = {
1286 .bLength = sizeof(ecm_gsi_ss_out_comp_desc),
1287 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
1288
1289 /* the following 2 values can be tweaked if necessary */
1290 .bMaxBurst = 2,
1291 /* .bmAttributes = 0, */
1292};
1293
1294static struct usb_descriptor_header *ecm_gsi_ss_function[] = {
1295 /* CDC ECM control descriptors */
1296 (struct usb_descriptor_header *) &ecm_gsi_control_intf,
1297 (struct usb_descriptor_header *) &ecm_gsi_header_desc,
1298 (struct usb_descriptor_header *) &ecm_gsi_union_desc,
1299 (struct usb_descriptor_header *) &ecm_gsi_desc,
1300 /* NOTE: status endpoint might need to be removed */
1301 (struct usb_descriptor_header *) &ecm_gsi_ss_notify_desc,
1302 (struct usb_descriptor_header *) &ecm_gsi_ss_notify_comp_desc,
1303 /* data interface, altsettings 0 and 1 */
1304 (struct usb_descriptor_header *) &ecm_gsi_data_nop_intf,
1305 (struct usb_descriptor_header *) &ecm_gsi_data_intf,
1306 (struct usb_descriptor_header *) &ecm_gsi_ss_in_desc,
1307 (struct usb_descriptor_header *) &ecm_gsi_ss_in_comp_desc,
1308 (struct usb_descriptor_header *) &ecm_gsi_ss_out_desc,
1309 (struct usb_descriptor_header *) &ecm_gsi_ss_out_comp_desc,
1310 NULL,
1311};
1312
1313/* string descriptors: */
1314static struct usb_string ecm_gsi_string_defs[] = {
1315 [0].s = "CDC Ethernet Control Model (ECM)",
1316 [1].s = NULL /* DYNAMIC */,
1317 [2].s = "CDC Ethernet Data",
1318 { } /* end of list */
1319};
1320
1321static struct usb_gadget_strings ecm_gsi_string_table = {
1322 .language = 0x0409, /* en-us */
1323 .strings = ecm_gsi_string_defs,
1324};
1325
1326static struct usb_gadget_strings *ecm_gsi_strings[] = {
1327 &ecm_gsi_string_table,
1328 NULL,
1329};
1330
1331/* qdss device descriptor */
1332
1333static struct usb_interface_descriptor qdss_gsi_data_intf_desc = {
1334 .bLength = sizeof(qdss_gsi_data_intf_desc),
1335 .bDescriptorType = USB_DT_INTERFACE,
1336 .bAlternateSetting = 0,
1337 .bNumEndpoints = 1,
1338 .bInterfaceClass = 0xff,
1339 .bInterfaceSubClass = 0xff,
1340 .bInterfaceProtocol = 0xff,
1341};
1342
Mayank Rana8c997012017-09-13 15:24:16 -07001343static struct usb_endpoint_descriptor qdss_gsi_fs_data_desc = {
1344 .bLength = USB_DT_ENDPOINT_SIZE,
1345 .bDescriptorType = USB_DT_ENDPOINT,
1346 .bEndpointAddress = USB_DIR_IN,
1347 .bmAttributes = USB_ENDPOINT_XFER_BULK,
1348 .wMaxPacketSize = cpu_to_le16(64),
1349};
1350
Mayank Rana0663c432016-12-06 16:38:18 -08001351static struct usb_endpoint_descriptor qdss_gsi_hs_data_desc = {
1352 .bLength = USB_DT_ENDPOINT_SIZE,
1353 .bDescriptorType = USB_DT_ENDPOINT,
1354 .bEndpointAddress = USB_DIR_IN,
1355 .bmAttributes = USB_ENDPOINT_XFER_BULK,
1356 .wMaxPacketSize = cpu_to_le16(512),
1357};
1358
1359static struct usb_endpoint_descriptor qdss_gsi_ss_data_desc = {
1360 .bLength = USB_DT_ENDPOINT_SIZE,
1361 .bDescriptorType = USB_DT_ENDPOINT,
1362 .bEndpointAddress = USB_DIR_IN,
1363 .bmAttributes = USB_ENDPOINT_XFER_BULK,
1364 .wMaxPacketSize = cpu_to_le16(1024),
1365};
1366
1367static struct usb_ss_ep_comp_descriptor qdss_gsi_data_ep_comp_desc = {
1368 .bLength = sizeof(qdss_gsi_data_ep_comp_desc),
1369 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
1370 .bMaxBurst = 1,
1371 .bmAttributes = 0,
1372 .wBytesPerInterval = 0,
1373};
1374
Mayank Rana8c997012017-09-13 15:24:16 -07001375static struct usb_descriptor_header *qdss_gsi_fs_data_only_desc[] = {
1376 (struct usb_descriptor_header *) &qdss_gsi_data_intf_desc,
1377 (struct usb_descriptor_header *) &qdss_gsi_fs_data_desc,
1378 NULL,
1379};
1380
Mayank Rana0663c432016-12-06 16:38:18 -08001381static struct usb_descriptor_header *qdss_gsi_hs_data_only_desc[] = {
1382 (struct usb_descriptor_header *) &qdss_gsi_data_intf_desc,
1383 (struct usb_descriptor_header *) &qdss_gsi_hs_data_desc,
1384 NULL,
1385};
1386
1387static struct usb_descriptor_header *qdss_gsi_ss_data_only_desc[] = {
1388 (struct usb_descriptor_header *) &qdss_gsi_data_intf_desc,
1389 (struct usb_descriptor_header *) &qdss_gsi_ss_data_desc,
1390 (struct usb_descriptor_header *) &qdss_gsi_data_ep_comp_desc,
1391 NULL,
1392};
1393
1394/* string descriptors: */
1395static struct usb_string qdss_gsi_string_defs[] = {
Mayank Ranace6013c2017-09-25 09:16:46 -07001396 [0].s = "DPL Data",
Mayank Rana0663c432016-12-06 16:38:18 -08001397 {}, /* end of list */
1398};
1399
1400static struct usb_gadget_strings qdss_gsi_string_table = {
1401 .language = 0x0409,
1402 .strings = qdss_gsi_string_defs,
1403};
1404
1405static struct usb_gadget_strings *qdss_gsi_strings[] = {
1406 &qdss_gsi_string_table,
1407 NULL,
1408};
1409#endif