blob: 21b393ed201442b2e878511f7fe22007e3ddf246 [file] [log] [blame]
Anna Perela8c991d2012-04-09 16:44:46 +03001/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#define pr_fmt(fmt) "%s: " fmt, __func__
15
16#include <linux/kernel.h>
17#include <linux/device.h>
18
19#include <linux/usb/cdc.h>
20
21#include <linux/usb/composite.h>
22#include <linux/usb/android_composite.h>
23#include <linux/platform_device.h>
24
25#include <linux/spinlock.h>
26
27/*
28 * This function is a "Mobile Broadband Interface Model" (MBIM) link.
29 * MBIM is intended to be used with high-speed network attachments.
30 *
31 * Note that MBIM requires the use of "alternate settings" for its data
32 * interface. This means that the set_alt() method has real work to do,
33 * and also means that a get_alt() method is required.
34 */
35
36#define MBIM_BULK_BUFFER_SIZE 4096
37
38#define MBIM_IOCTL_MAGIC 'o'
39#define MBIM_GET_NTB_SIZE _IOR(MBIM_IOCTL_MAGIC, 2, u32)
40#define MBIM_GET_DATAGRAM_COUNT _IOR(MBIM_IOCTL_MAGIC, 3, u16)
41
42#define NR_MBIM_PORTS 1
43
44struct ctrl_pkt {
45 void *buf;
46 int len;
47 struct list_head list;
48};
49
50struct mbim_ep_descs {
51 struct usb_endpoint_descriptor *in;
52 struct usb_endpoint_descriptor *out;
53 struct usb_endpoint_descriptor *notify;
54};
55
56struct mbim_notify_port {
57 struct usb_ep *notify;
58 struct usb_request *notify_req;
59 u8 notify_state;
60 atomic_t notify_count;
61};
62
63enum mbim_notify_state {
64 NCM_NOTIFY_NONE,
65 NCM_NOTIFY_CONNECT,
66 NCM_NOTIFY_SPEED,
67};
68
69struct f_mbim {
70 struct usb_function function;
71 struct usb_composite_dev *cdev;
72
73 atomic_t online;
74 bool is_open;
75
76 atomic_t open_excl;
77 atomic_t ioctl_excl;
78 atomic_t read_excl;
79 atomic_t write_excl;
80
81 wait_queue_head_t read_wq;
82 wait_queue_head_t write_wq;
83
84 u8 port_num;
85 struct data_port bam_port;
86 struct mbim_notify_port not_port;
87
88 struct mbim_ep_descs fs;
89 struct mbim_ep_descs hs;
90
91 u8 ctrl_id, data_id;
92
93 struct ndp_parser_opts *parser_opts;
94
95 spinlock_t lock;
96
97 struct list_head cpkt_req_q;
98 struct list_head cpkt_resp_q;
99
100 u32 ntb_input_size;
101 u16 ntb_max_datagrams;
102
103 pid_t user_pid;
104
105 atomic_t error;
106};
107
108struct mbim_ntb_input_size {
109 u32 ntb_input_size;
110 u16 ntb_max_datagrams;
111 u16 reserved;
112};
113
114/* temporary variable used between mbim_open() and mbim_gadget_bind() */
115static struct f_mbim *_mbim_dev;
116
117static unsigned int nr_mbim_ports;
118
119static struct mbim_ports {
120 struct f_mbim *port;
121 unsigned port_num;
122} mbim_ports[NR_MBIM_PORTS];
123
124static inline struct f_mbim *func_to_mbim(struct usb_function *f)
125{
126 return container_of(f, struct f_mbim, function);
127}
128
129/* peak (theoretical) bulk transfer rate in bits-per-second */
130static inline unsigned mbim_bitrate(struct usb_gadget *g)
131{
132 if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
133 return 13 * 512 * 8 * 1000 * 8;
134 else
135 return 19 * 64 * 1 * 1000 * 8;
136}
137
138/*-------------------------------------------------------------------------*/
139
140#define NTB_DEFAULT_IN_SIZE (0x4000)
141#define NTB_OUT_SIZE (0x1000)
142#define NDP_IN_DIVISOR (0x4)
143
144#define FORMATS_SUPPORTED USB_CDC_NCM_NTB16_SUPPORTED
145
146static struct usb_cdc_ncm_ntb_parameters ntb_parameters = {
147 .wLength = sizeof ntb_parameters,
148 .bmNtbFormatsSupported = cpu_to_le16(FORMATS_SUPPORTED),
149 .dwNtbInMaxSize = cpu_to_le32(NTB_DEFAULT_IN_SIZE),
150 .wNdpInDivisor = cpu_to_le16(NDP_IN_DIVISOR),
151 .wNdpInPayloadRemainder = cpu_to_le16(0),
152 .wNdpInAlignment = cpu_to_le16(4),
153
154 .dwNtbOutMaxSize = cpu_to_le32(NTB_OUT_SIZE),
155 .wNdpOutDivisor = cpu_to_le16(4),
156 .wNdpOutPayloadRemainder = cpu_to_le16(0),
157 .wNdpOutAlignment = cpu_to_le16(4),
158 .wNtbOutMaxDatagrams = cpu_to_le16(4),
159};
160
161/*
162 * Use wMaxPacketSize big enough to fit CDC_NOTIFY_SPEED_CHANGE in one
163 * packet, to simplify cancellation; and a big transfer interval, to
164 * waste less bandwidth.
165 */
166
167#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
168#define NCM_STATUS_BYTECOUNT 16 /* 8 byte header + data */
169
170static struct usb_interface_assoc_descriptor mbim_iad_desc = {
171 .bLength = sizeof mbim_iad_desc,
172 .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
173
174 /* .bFirstInterface = DYNAMIC, */
175 .bInterfaceCount = 2, /* control + data */
176 .bFunctionClass = 2,
177 .bFunctionSubClass = 0x0e,
178 .bFunctionProtocol = 0,
179 /* .iFunction = DYNAMIC */
180};
181
182/* interface descriptor: */
183static struct usb_interface_descriptor mbim_control_intf = {
184 .bLength = sizeof mbim_control_intf,
185 .bDescriptorType = USB_DT_INTERFACE,
186
187 /* .bInterfaceNumber = DYNAMIC */
188 .bNumEndpoints = 1,
189 .bInterfaceClass = 0x02,
190 .bInterfaceSubClass = 0x0e,
191 .bInterfaceProtocol = 0,
192 /* .iInterface = DYNAMIC */
193};
194
195static struct usb_cdc_header_desc mbim_header_desc = {
196 .bLength = sizeof mbim_header_desc,
197 .bDescriptorType = USB_DT_CS_INTERFACE,
198 .bDescriptorSubType = USB_CDC_HEADER_TYPE,
199
200 .bcdCDC = cpu_to_le16(0x0110),
201};
202
203static struct usb_cdc_union_desc mbim_union_desc = {
204 .bLength = sizeof(mbim_union_desc),
205 .bDescriptorType = USB_DT_CS_INTERFACE,
206 .bDescriptorSubType = USB_CDC_UNION_TYPE,
207 /* .bMasterInterface0 = DYNAMIC */
208 /* .bSlaveInterface0 = DYNAMIC */
209};
210
211static struct usb_cdc_mbb_desc mbb_desc = {
212 .bLength = sizeof mbb_desc,
213 .bDescriptorType = USB_DT_CS_INTERFACE,
214 .bDescriptorSubType = USB_CDC_MBB_TYPE,
215
216 .bcdMbbVersion = cpu_to_le16(0x0100),
217
218 .wMaxControlMessage = cpu_to_le16(0x1000),
219 .bNumberFilters = 0x10,
220 .bMaxFilterSize = 0x80,
221 .wMaxSegmentSize = cpu_to_le16(0x1000),
222 .bmNetworkCapabilities = 0x20,
223};
224
225/* the default data interface has no endpoints ... */
226static struct usb_interface_descriptor mbim_data_nop_intf = {
227 .bLength = sizeof mbim_data_nop_intf,
228 .bDescriptorType = USB_DT_INTERFACE,
229
230 /* .bInterfaceNumber = DYNAMIC */
231 .bAlternateSetting = 0,
232 .bNumEndpoints = 0,
233 .bInterfaceClass = 0x0a,
234 .bInterfaceSubClass = 0,
235 .bInterfaceProtocol = 0x02,
236 /* .iInterface = DYNAMIC */
237};
238
239/* ... but the "real" data interface has two bulk endpoints */
240static struct usb_interface_descriptor mbim_data_intf = {
241 .bLength = sizeof mbim_data_intf,
242 .bDescriptorType = USB_DT_INTERFACE,
243
244 /* .bInterfaceNumber = DYNAMIC */
245 .bAlternateSetting = 1,
246 .bNumEndpoints = 2,
247 .bInterfaceClass = 0x0a,
248 .bInterfaceSubClass = 0,
249 .bInterfaceProtocol = 0x02,
250 /* .iInterface = DYNAMIC */
251};
252
253/* full speed support: */
254
255static struct usb_endpoint_descriptor fs_mbim_notify_desc = {
256 .bLength = USB_DT_ENDPOINT_SIZE,
257 .bDescriptorType = USB_DT_ENDPOINT,
258
259 .bEndpointAddress = USB_DIR_IN,
260 .bmAttributes = USB_ENDPOINT_XFER_INT,
261 .wMaxPacketSize = 4*cpu_to_le16(NCM_STATUS_BYTECOUNT),
262 .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
263};
264
265static struct usb_endpoint_descriptor fs_mbim_in_desc = {
266 .bLength = USB_DT_ENDPOINT_SIZE,
267 .bDescriptorType = USB_DT_ENDPOINT,
268
269 .bEndpointAddress = USB_DIR_IN,
270 .bmAttributes = USB_ENDPOINT_XFER_BULK,
271};
272
273static struct usb_endpoint_descriptor fs_mbim_out_desc = {
274 .bLength = USB_DT_ENDPOINT_SIZE,
275 .bDescriptorType = USB_DT_ENDPOINT,
276
277 .bEndpointAddress = USB_DIR_OUT,
278 .bmAttributes = USB_ENDPOINT_XFER_BULK,
279};
280
281static struct usb_descriptor_header *mbim_fs_function[] = {
282 (struct usb_descriptor_header *) &mbim_iad_desc,
283 /* MBIM control descriptors */
284 (struct usb_descriptor_header *) &mbim_control_intf,
285 (struct usb_descriptor_header *) &mbim_header_desc,
286 (struct usb_descriptor_header *) &mbb_desc,
287 (struct usb_descriptor_header *) &fs_mbim_notify_desc,
288 /* data interface, altsettings 0 and 1 */
289 (struct usb_descriptor_header *) &mbim_data_nop_intf,
290 (struct usb_descriptor_header *) &mbim_data_intf,
291 (struct usb_descriptor_header *) &fs_mbim_in_desc,
292 (struct usb_descriptor_header *) &fs_mbim_out_desc,
293 NULL,
294};
295
296/* high speed support: */
297
298static struct usb_endpoint_descriptor hs_mbim_notify_desc = {
299 .bLength = USB_DT_ENDPOINT_SIZE,
300 .bDescriptorType = USB_DT_ENDPOINT,
301
302 .bEndpointAddress = USB_DIR_IN,
303 .bmAttributes = USB_ENDPOINT_XFER_INT,
304 .wMaxPacketSize = 4*cpu_to_le16(NCM_STATUS_BYTECOUNT),
305 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
306};
307static struct usb_endpoint_descriptor hs_mbim_in_desc = {
308 .bLength = USB_DT_ENDPOINT_SIZE,
309 .bDescriptorType = USB_DT_ENDPOINT,
310
311 .bEndpointAddress = USB_DIR_IN,
312 .bmAttributes = USB_ENDPOINT_XFER_BULK,
313 .wMaxPacketSize = cpu_to_le16(512),
314};
315
316static struct usb_endpoint_descriptor hs_mbim_out_desc = {
317 .bLength = USB_DT_ENDPOINT_SIZE,
318 .bDescriptorType = USB_DT_ENDPOINT,
319
320 .bEndpointAddress = USB_DIR_OUT,
321 .bmAttributes = USB_ENDPOINT_XFER_BULK,
322 .wMaxPacketSize = cpu_to_le16(512),
323};
324
325static struct usb_descriptor_header *mbim_hs_function[] = {
326 (struct usb_descriptor_header *) &mbim_iad_desc,
327 /* MBIM control descriptors */
328 (struct usb_descriptor_header *) &mbim_control_intf,
329 (struct usb_descriptor_header *) &mbim_header_desc,
330 (struct usb_descriptor_header *) &mbb_desc,
331 (struct usb_descriptor_header *) &hs_mbim_notify_desc,
332 /* data interface, altsettings 0 and 1 */
333 (struct usb_descriptor_header *) &mbim_data_nop_intf,
334 (struct usb_descriptor_header *) &mbim_data_intf,
335 (struct usb_descriptor_header *) &hs_mbim_in_desc,
336 (struct usb_descriptor_header *) &hs_mbim_out_desc,
337 NULL,
338};
339
340/* string descriptors: */
341
342#define STRING_CTRL_IDX 0
343#define STRING_DATA_IDX 1
344
345static struct usb_string mbim_string_defs[] = {
346 [STRING_CTRL_IDX].s = "MBIM Control",
347 [STRING_DATA_IDX].s = "MBIM Data",
348 { } /* end of list */
349};
350
351static struct usb_gadget_strings mbim_string_table = {
352 .language = 0x0409, /* en-us */
353 .strings = mbim_string_defs,
354};
355
356static struct usb_gadget_strings *mbim_strings[] = {
357 &mbim_string_table,
358 NULL,
359};
360
361/*
362 * Here are options for the Datagram Pointer table (NDP) parser.
363 * There are 2 different formats: NDP16 and NDP32 in the spec (ch. 3),
364 * in NDP16 offsets and sizes fields are 1 16bit word wide,
365 * in NDP32 -- 2 16bit words wide. Also signatures are different.
366 * To make the parser code the same, put the differences in the structure,
367 * and switch pointers to the structures when the format is changed.
368 */
369
370struct ndp_parser_opts {
371 u32 nth_sign;
372 u32 ndp_sign;
373 unsigned nth_size;
374 unsigned ndp_size;
375 unsigned ndplen_align;
376 /* sizes in u16 units */
377 unsigned dgram_item_len; /* index or length */
378 unsigned block_length;
379 unsigned fp_index;
380 unsigned reserved1;
381 unsigned reserved2;
382 unsigned next_fp_index;
383};
384
385#define INIT_NDP16_OPTS { \
386 .nth_sign = USB_CDC_NCM_NTH16_SIGN, \
387 .ndp_sign = USB_CDC_NCM_NDP16_NOCRC_SIGN, \
388 .nth_size = sizeof(struct usb_cdc_ncm_nth16), \
389 .ndp_size = sizeof(struct usb_cdc_ncm_ndp16), \
390 .ndplen_align = 4, \
391 .dgram_item_len = 1, \
392 .block_length = 1, \
393 .fp_index = 1, \
394 .reserved1 = 0, \
395 .reserved2 = 0, \
396 .next_fp_index = 1, \
397}
398
399#define INIT_NDP32_OPTS { \
400 .nth_sign = USB_CDC_NCM_NTH32_SIGN, \
401 .ndp_sign = USB_CDC_NCM_NDP32_NOCRC_SIGN, \
402 .nth_size = sizeof(struct usb_cdc_ncm_nth32), \
403 .ndp_size = sizeof(struct usb_cdc_ncm_ndp32), \
404 .ndplen_align = 8, \
405 .dgram_item_len = 2, \
406 .block_length = 2, \
407 .fp_index = 2, \
408 .reserved1 = 1, \
409 .reserved2 = 2, \
410 .next_fp_index = 2, \
411}
412
413static struct ndp_parser_opts ndp16_opts = INIT_NDP16_OPTS;
414static struct ndp_parser_opts ndp32_opts = INIT_NDP32_OPTS;
415
416static inline int mbim_lock(atomic_t *excl)
417{
418 if (atomic_inc_return(excl) == 1) {
419 return 0;
420 } else {
421 atomic_dec(excl);
422 return -EBUSY;
423 }
424}
425
426static inline void mbim_unlock(atomic_t *excl)
427{
428 atomic_dec(excl);
429}
430
431static struct ctrl_pkt *mbim_alloc_ctrl_pkt(unsigned len, gfp_t flags)
432{
433 struct ctrl_pkt *pkt;
434
435 pkt = kzalloc(sizeof(struct ctrl_pkt), flags);
436 if (!pkt)
437 return ERR_PTR(-ENOMEM);
438
439 pkt->buf = kmalloc(len, flags);
440 if (!pkt->buf) {
441 kfree(pkt);
442 return ERR_PTR(-ENOMEM);
443 }
444 pkt->len = len;
445
446 return pkt;
447}
448
449static void mbim_free_ctrl_pkt(struct ctrl_pkt *pkt)
450{
451 if (pkt) {
452 kfree(pkt->buf);
453 kfree(pkt);
454 }
455}
456
457static struct usb_request *mbim_alloc_req(struct usb_ep *ep, int buffer_size)
458{
459 struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL);
460 if (!req)
461 return NULL;
462
463 req->buf = kmalloc(buffer_size, GFP_KERNEL);
464 if (!req->buf) {
465 usb_ep_free_request(ep, req);
466 return NULL;
467 }
468 req->length = buffer_size;
469 return req;
470}
471
472void fmbim_free_req(struct usb_ep *ep, struct usb_request *req)
473{
474 if (req) {
475 kfree(req->buf);
476 usb_ep_free_request(ep, req);
477 }
478}
479
480static void fmbim_ctrl_response_available(struct f_mbim *dev)
481{
482 struct usb_request *req = dev->not_port.notify_req;
483 struct usb_cdc_notification *event = NULL;
484 unsigned long flags;
485 int ret;
486
487 int notif_c = 0;
488
489 pr_info("dev:%p portno#%d\n", dev, dev->port_num);
490
491 spin_lock_irqsave(&dev->lock, flags);
492
493 if (!atomic_read(&dev->online)) {
494 pr_info("dev:%p is not online\n", dev);
495 spin_unlock_irqrestore(&dev->lock, flags);
496 return;
497 }
498
499 if (!req) {
500 pr_info("dev:%p req is NULL\n", dev);
501 spin_unlock_irqrestore(&dev->lock, flags);
502 return;
503 }
504
505 if (!req->buf) {
506 pr_info("dev:%p req->buf is NULL\n", dev);
507 spin_unlock_irqrestore(&dev->lock, flags);
508 return;
509 }
510
511 notif_c = atomic_inc_return(&dev->not_port.notify_count);
512 pr_info("atomic_inc_return[notif_c] = %d", notif_c);
513
514 event = req->buf;
515 event->bmRequestType = USB_DIR_IN | USB_TYPE_CLASS
516 | USB_RECIP_INTERFACE;
517 event->bNotificationType = USB_CDC_NOTIFY_RESPONSE_AVAILABLE;
518 event->wValue = cpu_to_le16(0);
519 event->wIndex = cpu_to_le16(dev->ctrl_id);
520 event->wLength = cpu_to_le16(0);
521 spin_unlock_irqrestore(&dev->lock, flags);
522
523 pr_info("Call usb_ep_queue");
524
525 ret = usb_ep_queue(dev->not_port.notify,
526 dev->not_port.notify_req, GFP_ATOMIC);
527 if (ret) {
528 atomic_dec(&dev->not_port.notify_count);
529 pr_err("ep enqueue error %d\n", ret);
530 }
531
532 pr_info("Succcessfull Exit");
533}
534
535static int
536fmbim_send_cpkt_response(struct f_mbim *gr, struct ctrl_pkt *cpkt)
537{
538 struct f_mbim *dev = gr;
539 unsigned long flags;
540
541 if (!gr || !cpkt) {
542 pr_err("Invalid cpkt, dev:%p cpkt:%p\n",
543 gr, cpkt);
544 return -ENODEV;
545 }
546
547 pr_info("dev:%p port_num#%d\n", dev, dev->port_num);
548
549 if (!atomic_read(&dev->online)) {
550 pr_info("dev:%p is not connected\n", dev);
551 mbim_free_ctrl_pkt(cpkt);
552 return 0;
553 }
554
555 spin_lock_irqsave(&dev->lock, flags);
Anna Perel40c550c2012-04-11 14:09:27 +0300556 list_add_tail(&cpkt->list, &dev->cpkt_resp_q);
Anna Perela8c991d2012-04-09 16:44:46 +0300557 spin_unlock_irqrestore(&dev->lock, flags);
558
559 fmbim_ctrl_response_available(dev);
560
561 return 0;
562}
563
564/* ---------------------------- BAM INTERFACE ----------------------------- */
565
566static int mbim_bam_setup(int no_ports)
567{
568 int ret;
569
570 pr_info("no_ports:%d\n", no_ports);
571
572 ret = bam_data_setup(no_ports);
573 if (ret) {
574 pr_err("bam_data_setup failed err: %d\n", ret);
575 return ret;
576 }
577
578 pr_info("Initialized %d ports\n", no_ports);
579 return 0;
580}
581
582static int mbim_bam_connect(struct f_mbim *dev)
583{
584 int ret;
585
586 pr_info("dev:%p portno:%d\n", dev, dev->port_num);
587
588 ret = bam_data_connect(&dev->bam_port, dev->port_num, dev->port_num);
589 if (ret) {
590 pr_err("bam_data_setup failed: err:%d\n",
591 ret);
592 return ret;
593 } else {
594 pr_info("mbim bam connected\n");
595 }
596
597 return 0;
598}
599
600static int mbim_bam_disconnect(struct f_mbim *dev)
601{
602 pr_info("dev:%p port:%d. Do nothing.\n",
603 dev, dev->port_num);
604
605 /* bam_data_disconnect(&dev->bam_port, dev->port_num); */
606
607 return 0;
608}
609
610/* -------------------------------------------------------------------------*/
611
612static inline void mbim_reset_values(struct f_mbim *mbim)
613{
614 mbim->parser_opts = &ndp16_opts;
615
616 mbim->ntb_input_size = NTB_DEFAULT_IN_SIZE;
617
618 atomic_set(&mbim->not_port.notify_count, 0);
619 atomic_set(&mbim->online, 0);
620}
621
622/*
623 * Context: mbim->lock held
624 */
625static void mbim_do_notify(struct f_mbim *mbim)
626{
627 struct usb_request *req = mbim->not_port.notify_req;
628 struct usb_cdc_notification *event;
629 struct usb_composite_dev *cdev = mbim->cdev;
630 __le32 *data;
631 int status;
632
633 pr_info("notify_state: %d", mbim->not_port.notify_state);
634
635 if (!req)
636 return;
637
638 event = req->buf;
639
640 switch (mbim->not_port.notify_state) {
641
642 case NCM_NOTIFY_NONE:
643 return;
644
645 case NCM_NOTIFY_CONNECT:
646 event->bNotificationType = USB_CDC_NOTIFY_NETWORK_CONNECTION;
647 if (mbim->is_open)
648 event->wValue = cpu_to_le16(1);
649 else
650 event->wValue = cpu_to_le16(0);
651 event->wLength = 0;
652 req->length = sizeof *event;
653
654 pr_info("notify connect %s\n",
655 mbim->is_open ? "true" : "false");
656 mbim->not_port.notify_state = NCM_NOTIFY_NONE;
657 break;
658
659 case NCM_NOTIFY_SPEED:
660 event->bNotificationType = USB_CDC_NOTIFY_SPEED_CHANGE;
661 event->wValue = cpu_to_le16(0);
662 event->wLength = cpu_to_le16(8);
663 req->length = NCM_STATUS_BYTECOUNT;
664
665 /* SPEED_CHANGE data is up/down speeds in bits/sec */
666 data = req->buf + sizeof *event;
667 data[0] = cpu_to_le32(mbim_bitrate(cdev->gadget));
668 data[1] = data[0];
669
670 pr_info("notify speed %d\n",
671 mbim_bitrate(cdev->gadget));
672 mbim->not_port.notify_state = NCM_NOTIFY_CONNECT;
673 break;
674 }
675 event->bmRequestType = 0xA1;
676 event->wIndex = cpu_to_le16(mbim->ctrl_id);
677
678 mbim->not_port.notify_req = NULL;
679 /*
680 * In double buffering if there is a space in FIFO,
681 * completion callback can be called right after the call,
682 * so unlocking
683 */
684 spin_unlock(&mbim->lock);
685 status = usb_ep_queue(mbim->not_port.notify, req, GFP_ATOMIC);
686 spin_lock(&mbim->lock);
687 if (status < 0) {
688 mbim->not_port.notify_req = req;
689 atomic_dec(&mbim->not_port.notify_count);
690 pr_err("usb_ep_queue failed, err: %d", status);
691 }
692}
693
694/*
695 * Context: mbim->lock held
696 */
697static void mbim_notify(struct f_mbim *mbim)
698{
699 /*
700 * If mbim_notify() is called before the second (CONNECT)
701 * notification is sent, then it will reset to send the SPEED
702 * notificaion again (and again, and again), but it's not a problem
703 */
704 pr_info("dev:%p\n", mbim);
705
706 mbim->not_port.notify_state = NCM_NOTIFY_SPEED;
707 mbim_do_notify(mbim);
708}
709
710static void mbim_notify_complete(struct usb_ep *ep, struct usb_request *req)
711{
712 struct f_mbim *mbim = req->context;
713 struct usb_cdc_notification *event = req->buf;
714
715 int notif_c = 0;
716
717 pr_info("dev:%p\n", mbim);
718
719 spin_lock(&mbim->lock);
720 switch (req->status) {
721 case 0:
722 pr_info("Notification %02x sent\n",
723 event->bNotificationType);
724
725 notif_c = atomic_dec_return(&mbim->not_port.notify_count);
726
727 if (notif_c != 0) {
728 pr_info("Continue to mbim_do_notify()");
729 break;
730 } else {
731 pr_info("notify_count decreased to 0. Do not notify");
732 spin_unlock(&mbim->lock);
733 return;
734 }
735
736 break;
737
738 case -ECONNRESET:
739 case -ESHUTDOWN:
740 /* connection gone */
741 mbim->not_port.notify_state = NCM_NOTIFY_NONE;
742 atomic_set(&mbim->not_port.notify_count, 0);
743 pr_info("ESHUTDOWN/ECONNRESET, connection gone");
744 break;
745 default:
746 pr_err("Unknown event %02x --> %d\n",
747 event->bNotificationType, req->status);
748 break;
749 }
750
751 mbim->not_port.notify_req = req;
752 mbim_do_notify(mbim);
753
754 spin_unlock(&mbim->lock);
755
756 pr_info("dev:%p Exit\n", mbim);
757}
758
759static void mbim_ep0out_complete(struct usb_ep *ep, struct usb_request *req)
760{
761 /* now for SET_NTB_INPUT_SIZE only */
762 unsigned in_size = 0;
763 struct usb_function *f = req->context;
764 struct f_mbim *mbim = func_to_mbim(f);
765 struct mbim_ntb_input_size *ntb = NULL;
766
767 pr_info("dev:%p\n", mbim);
768
769 req->context = NULL;
770 if (req->status || req->actual != req->length) {
771 pr_err("Bad control-OUT transfer\n");
772 goto invalid;
773 }
774
775 if (req->length == 4) {
776 in_size = get_unaligned_le32(req->buf);
777 if (in_size < USB_CDC_NCM_NTB_MIN_IN_SIZE ||
778 in_size > le32_to_cpu(ntb_parameters.dwNtbInMaxSize)) {
779 pr_err("Illegal INPUT SIZE (%d) from host\n", in_size);
780 goto invalid;
781 }
782 } else if (req->length == 8) {
783 ntb = (struct mbim_ntb_input_size *)req->buf;
784 in_size = get_unaligned_le32(&(ntb->ntb_input_size));
785 if (in_size < USB_CDC_NCM_NTB_MIN_IN_SIZE ||
786 in_size > le32_to_cpu(ntb_parameters.dwNtbInMaxSize)) {
787 pr_err("Illegal INPUT SIZE (%d) from host\n", in_size);
788 goto invalid;
789 }
790 mbim->ntb_max_datagrams =
791 get_unaligned_le16(&(ntb->ntb_max_datagrams));
792 } else {
793 pr_err("Illegal NTB length %d\n", in_size);
794 goto invalid;
795 }
796
797 pr_info("Set NTB INPUT SIZE %d\n", in_size);
798
799 mbim->ntb_input_size = in_size;
800 return;
801
802invalid:
803 usb_ep_set_halt(ep);
804
805 pr_err("dev:%p Failed\n", mbim);
806
807 return;
808}
809
810static void
811fmbim_cmd_complete(struct usb_ep *ep, struct usb_request *req)
812{
813 struct f_mbim *dev = req->context;
814 struct ctrl_pkt *cpkt = NULL;
815 int len = req->actual;
816
817 if (!dev) {
818 pr_err("mbim dev is null\n");
819 return;
820 }
821
822 if (req->status < 0) {
823 pr_err("mbim command error %d\n", req->status);
824 return;
825 }
826
827 pr_info("dev:%p port#%d\n", dev, dev->port_num);
828
829 spin_lock(&dev->lock);
830 if (!dev->is_open) {
831 pr_err("mbim file handler %p is not open", dev);
832 spin_unlock(&dev->lock);
833 return;
834 }
835
836 cpkt = mbim_alloc_ctrl_pkt(len, GFP_ATOMIC);
837 if (!cpkt) {
838 pr_err("Unable to allocate ctrl pkt\n");
839 spin_unlock(&dev->lock);
840 return;
841 }
842
843 pr_info("Add to cpkt_req_q packet with len = %d\n", len);
844 memcpy(cpkt->buf, req->buf, len);
845 list_add_tail(&cpkt->list, &dev->cpkt_req_q);
846 spin_unlock(&dev->lock);
847
848 /* wakeup read thread */
849 pr_info("Wake up read queue");
850 wake_up(&dev->read_wq);
851
852 return;
853}
854
855static int
856mbim_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
857{
858 struct f_mbim *mbim = func_to_mbim(f);
859 struct usb_composite_dev *cdev = mbim->cdev;
860 struct usb_request *req = cdev->req;
861 struct ctrl_pkt *cpkt = NULL;
862 int value = -EOPNOTSUPP;
863 u16 w_index = le16_to_cpu(ctrl->wIndex);
864 u16 w_value = le16_to_cpu(ctrl->wValue);
865 u16 w_length = le16_to_cpu(ctrl->wLength);
866
867 /*
868 * composite driver infrastructure handles everything except
869 * CDC class messages; interface activation uses set_alt().
870 */
871
872 if (!atomic_read(&mbim->online)) {
873 pr_info("usb cable is not connected\n");
874 return -ENOTCONN;
875 }
876
877 switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
878 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
879 | USB_CDC_RESET_FUNCTION:
880
881 pr_info("USB_CDC_RESET_FUNCTION");
882 value = 0;
883 if (!_mbim_dev->user_pid) {
884 pr_err("QBI pid is not set");
885 break;
886 }
887
888 if (!_mbim_dev->is_open) {
889 pr_err("QBI is not up yet");
890 break;
891 }
892
893 send_sig_info(SIGUSR1, SEND_SIG_NOINFO,
894 find_task_by_vpid(_mbim_dev->user_pid));
895
896 pr_info("Sent signal to QBI pid %d",
897 _mbim_dev->user_pid);
898 break;
899
900 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
901 | USB_CDC_SEND_ENCAPSULATED_COMMAND:
902
903 pr_info("USB_CDC_SEND_ENCAPSULATED_COMMAND");
904
905 if (w_length > req->length) {
906 pr_err("w_length > req->length: %d > %d",
907 w_length, req->length);
908 }
909 value = w_length;
910 req->complete = fmbim_cmd_complete;
911 req->context = mbim;
912 break;
913
914 case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
915 | USB_CDC_GET_ENCAPSULATED_RESPONSE:
916
917 pr_info("USB_CDC_GET_ENCAPSULATED_RESPONSE");
918
919 if (w_value) {
920 pr_err("w_length > 0: %d", w_length);
921 break;
922 }
923
924 pr_info("req%02x.%02x v%04x i%04x l%d\n",
925 ctrl->bRequestType, ctrl->bRequest,
926 w_value, w_index, w_length);
927
928 spin_lock(&mbim->lock);
929 if (list_empty(&mbim->cpkt_resp_q)) {
930 pr_err("ctrl resp queue empty\n");
931 spin_unlock(&mbim->lock);
932 break;
933 }
934
935 cpkt = list_first_entry(&mbim->cpkt_resp_q,
936 struct ctrl_pkt, list);
937 list_del(&cpkt->list);
938 spin_unlock(&mbim->lock);
939
940 value = min_t(unsigned, w_length, cpkt->len);
941 memcpy(req->buf, cpkt->buf, value);
942 mbim_free_ctrl_pkt(cpkt);
943
944 pr_info("copied encapsulated_response %d bytes",
945 value);
946
947 break;
948
949 case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
950 | USB_CDC_GET_NTB_PARAMETERS:
951
952 pr_info("USB_CDC_GET_NTB_PARAMETERS");
953
954 if (w_length == 0 || w_value != 0 || w_index != mbim->ctrl_id)
955 break;
956
957 value = w_length > sizeof ntb_parameters ?
958 sizeof ntb_parameters : w_length;
959 memcpy(req->buf, &ntb_parameters, value);
960 break;
961
962 case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
963 | USB_CDC_GET_NTB_INPUT_SIZE:
964
965 pr_info("USB_CDC_GET_NTB_INPUT_SIZE");
966
967 if (w_length < 4 || w_value != 0 || w_index != mbim->ctrl_id)
968 break;
969
970 put_unaligned_le32(mbim->ntb_input_size, req->buf);
971 value = 4;
972 pr_info("Reply to host INPUT SIZE %d\n",
973 mbim->ntb_input_size);
974 break;
975
976 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
977 | USB_CDC_SET_NTB_INPUT_SIZE:
978
979 pr_info("USB_CDC_SET_NTB_INPUT_SIZE");
980
981 if (w_length != 4 && w_length != 8) {
982 pr_err("wrong NTB length %d", w_length);
983 break;
984 }
985
986 if (w_value != 0 || w_index != mbim->ctrl_id)
987 break;
988
989 req->complete = mbim_ep0out_complete;
990 req->length = w_length;
991 req->context = f;
992
993 value = req->length;
994 break;
995
996 case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
997 | USB_CDC_GET_NTB_FORMAT:
998 {
999 uint16_t format;
1000
1001 pr_info("USB_CDC_GET_NTB_FORMAT");
1002
1003 if (w_length < 2 || w_value != 0 || w_index != mbim->ctrl_id)
1004 break;
1005
1006 format = (mbim->parser_opts == &ndp16_opts) ? 0x0000 : 0x0001;
1007 put_unaligned_le16(format, req->buf);
1008 value = 2;
1009 pr_info("NTB FORMAT: sending %d\n", format);
1010 break;
1011 }
1012
1013 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
1014 | USB_CDC_SET_NTB_FORMAT:
1015 {
1016 pr_info("USB_CDC_SET_NTB_FORMAT");
1017
1018 if (w_length != 0 || w_index != mbim->ctrl_id)
1019 break;
1020 switch (w_value) {
1021 case 0x0000:
1022 mbim->parser_opts = &ndp16_opts;
1023 pr_info("NCM16 selected\n");
1024 break;
1025 case 0x0001:
1026 mbim->parser_opts = &ndp32_opts;
1027 pr_info("NCM32 selected\n");
1028 break;
1029 default:
1030 break;
1031 }
1032 value = 0;
1033 break;
1034 }
1035
1036 /* optional in mbim descriptor: */
1037 /* case USB_CDC_GET_MAX_DATAGRAM_SIZE: */
1038 /* case USB_CDC_SET_MAX_DATAGRAM_SIZE: */
1039
1040 default:
1041 pr_err("invalid control req: %02x.%02x v%04x i%04x l%d\n",
1042 ctrl->bRequestType, ctrl->bRequest,
1043 w_value, w_index, w_length);
1044 }
1045
1046 /* respond with data transfer or status phase? */
1047 if (value >= 0) {
1048 pr_info("control request: %02x.%02x v%04x i%04x l%d\n",
1049 ctrl->bRequestType, ctrl->bRequest,
1050 w_value, w_index, w_length);
1051 req->zero = 0;
1052 req->length = value;
1053 value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
1054 if (value < 0) {
1055 pr_err("queueing req failed: %02x.%02x, err %d\n",
1056 ctrl->bRequestType,
1057 ctrl->bRequest, value);
1058 }
1059 } else {
1060 pr_err("ctrl req err %d: %02x.%02x v%04x i%04x l%d\n",
1061 value, ctrl->bRequestType, ctrl->bRequest,
1062 w_value, w_index, w_length);
1063 }
1064
1065 /* device either stalls (value < 0) or reports success */
1066 return value;
1067}
1068
1069static int mbim_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
1070{
1071 struct f_mbim *mbim = func_to_mbim(f);
1072 struct usb_composite_dev *cdev = mbim->cdev;
1073 int ret = 0;
1074
1075 /* Control interface has only altsetting 0 */
1076 if (intf == mbim->ctrl_id) {
1077
1078 pr_info("CONTROL_INTERFACE");
1079
1080 if (alt != 0)
1081 goto fail;
1082
1083 if (mbim->not_port.notify->driver_data) {
1084 pr_info("reset mbim control %d\n", intf);
1085 usb_ep_disable(mbim->not_port.notify);
1086 }
1087
1088 ret = config_ep_by_speed(cdev->gadget, f,
1089 mbim->not_port.notify);
1090 if (ret) {
1091 mbim->not_port.notify->desc = NULL;
1092 pr_err("Failed configuring notify ep %s: err %d\n",
1093 mbim->not_port.notify->name, ret);
1094 return ret;
1095 }
1096
1097 ret = usb_ep_enable(mbim->not_port.notify);
1098 if (ret) {
1099 pr_err("usb ep#%s enable failed, err#%d\n",
1100 mbim->not_port.notify->name, ret);
1101 return ret;
1102 }
1103 mbim->not_port.notify->driver_data = mbim;
1104
1105 /* Data interface has two altsettings, 0 and 1 */
1106 } else if (intf == mbim->data_id) {
1107
1108 pr_info("DATA_INTERFACE");
1109
1110 if (alt > 1)
1111 goto fail;
1112
1113 if (mbim->bam_port.in->driver_data) {
1114 pr_info("reset mbim\n");
1115 mbim_reset_values(mbim);
1116 mbim_bam_disconnect(mbim);
1117 }
1118
1119 /*
1120 * CDC Network only sends data in non-default altsettings.
1121 * Changing altsettings resets filters, statistics, etc.
1122 */
1123 if (alt == 1) {
1124 pr_info("Alt set 1, initialize ports");
1125
1126 if (!mbim->bam_port.in->desc) {
1127
1128 pr_info("Choose endpoints");
1129
1130 ret = config_ep_by_speed(cdev->gadget, f,
1131 mbim->bam_port.in);
1132 if (ret) {
1133 mbim->bam_port.in->desc = NULL;
1134 pr_err("IN ep %s failed: %d\n",
1135 mbim->bam_port.in->name, ret);
1136 return ret;
1137 }
1138
1139 pr_info("Set mbim port in_desc = 0x%p",
1140 mbim->bam_port.in->desc);
1141
1142 ret = config_ep_by_speed(cdev->gadget, f,
1143 mbim->bam_port.out);
1144 if (ret) {
1145 mbim->bam_port.out->desc = NULL;
1146 pr_err("OUT ep %s failed: %d\n",
1147 mbim->bam_port.out->name, ret);
1148 return ret;
1149 }
1150
1151 pr_info("Set mbim port out_desc = 0x%p",
1152 mbim->bam_port.out->desc);
1153 } else {
1154 pr_info("PORTS already SET");
1155 }
1156
1157 pr_info("Activate mbim\n");
1158 mbim_bam_connect(mbim);
1159 }
1160
1161 spin_lock(&mbim->lock);
1162 mbim_notify(mbim);
1163 spin_unlock(&mbim->lock);
1164 } else {
1165 goto fail;
1166 }
1167
1168 atomic_set(&mbim->online, 1);
1169
1170 pr_info("SET DEVICE ONLINE");
1171
1172 /* wakeup file threads */
1173 wake_up(&mbim->read_wq);
1174 wake_up(&mbim->write_wq);
1175
1176 return 0;
1177
1178fail:
1179 pr_err("ERROR: Illegal Interface");
1180 return -EINVAL;
1181}
1182
1183/*
1184 * Because the data interface supports multiple altsettings,
1185 * this MBIM function *MUST* implement a get_alt() method.
1186 */
1187static int mbim_get_alt(struct usb_function *f, unsigned intf)
1188{
1189 struct f_mbim *mbim = func_to_mbim(f);
1190
1191 if (intf == mbim->ctrl_id)
1192 return 0;
1193 return mbim->bam_port.in->driver_data ? 1 : 0;
1194}
1195
1196static void mbim_disable(struct usb_function *f)
1197{
1198 struct f_mbim *mbim = func_to_mbim(f);
1199
1200 pr_info("SET DEVICE OFFLINE");
1201 atomic_set(&mbim->online, 0);
1202
1203 if (_mbim_dev && _mbim_dev->user_pid && _mbim_dev->is_open) {
1204 send_sig_info(SIGUSR1, SEND_SIG_NOINFO,
1205 find_task_by_vpid(_mbim_dev->user_pid));
1206 pr_info("Sending reset signal to QBI pid %d",
1207 _mbim_dev->user_pid);
1208 }
1209
1210 mbim_bam_disconnect(mbim);
1211
1212 if (mbim->not_port.notify->driver_data) {
1213 usb_ep_disable(mbim->not_port.notify);
1214 mbim->not_port.notify->driver_data = NULL;
1215 }
1216
1217 pr_info("mbim deactivated\n");
1218}
1219
1220/*---------------------- function driver setup/binding ---------------------*/
1221
1222static int
1223mbim_bind(struct usb_configuration *c, struct usb_function *f)
1224{
1225 struct usb_composite_dev *cdev = c->cdev;
1226 struct f_mbim *mbim = func_to_mbim(f);
1227 int status;
1228 struct usb_ep *ep;
1229
1230 pr_info("Enter");
1231
1232 mbim->cdev = cdev;
1233
1234 /* allocate instance-specific interface IDs */
1235 status = usb_interface_id(c, f);
1236 if (status < 0)
1237 goto fail;
1238 mbim->ctrl_id = status;
1239 mbim_iad_desc.bFirstInterface = status;
1240
1241 mbim_control_intf.bInterfaceNumber = status;
1242 mbim_union_desc.bMasterInterface0 = status;
1243
1244 status = usb_interface_id(c, f);
1245 if (status < 0)
1246 goto fail;
1247 mbim->data_id = status;
1248
1249 mbim_data_nop_intf.bInterfaceNumber = status;
1250 mbim_data_intf.bInterfaceNumber = status;
1251 mbim_union_desc.bSlaveInterface0 = status;
1252
1253 status = -ENODEV;
1254
1255 /* allocate instance-specific endpoints */
1256 ep = usb_ep_autoconfig(cdev->gadget, &fs_mbim_in_desc);
1257 if (!ep) {
1258 pr_err("usb epin autoconfig failed\n");
1259 goto fail;
1260 }
1261 pr_info("usb epin autoconfig succeeded\n");
1262 ep->driver_data = cdev; /* claim */
1263 mbim->bam_port.in = ep;
1264
1265 ep = usb_ep_autoconfig(cdev->gadget, &fs_mbim_out_desc);
1266 if (!ep) {
1267 pr_err("usb epout autoconfig failed\n");
1268 goto fail;
1269 }
1270 pr_info("usb epout autoconfig succeeded\n");
1271 ep->driver_data = cdev; /* claim */
1272 mbim->bam_port.out = ep;
1273
1274 ep = usb_ep_autoconfig(cdev->gadget, &fs_mbim_notify_desc);
1275 if (!ep) {
1276 pr_err("usb notify ep autoconfig failed\n");
1277 goto fail;
1278 }
1279 pr_info("usb notify ep autoconfig succeeded\n");
1280 mbim->not_port.notify = ep;
1281 ep->driver_data = cdev; /* claim */
1282
1283 status = -ENOMEM;
1284
1285 /* allocate notification request and buffer */
1286 mbim->not_port.notify_req = mbim_alloc_req(ep, NCM_STATUS_BYTECOUNT);
1287 if (!mbim->not_port.notify_req) {
1288 pr_info("failed to allocate notify request\n");
1289 goto fail;
1290 }
1291 pr_info("allocated notify ep request & request buffer\n");
1292
1293 mbim->not_port.notify_req->context = mbim;
1294 mbim->not_port.notify_req->complete = mbim_notify_complete;
1295
1296 /* copy descriptors, and track endpoint copies */
1297 f->descriptors = usb_copy_descriptors(mbim_fs_function);
1298 if (!f->descriptors)
1299 goto fail;
1300
1301 /*
1302 * support all relevant hardware speeds... we expect that when
1303 * hardware is dual speed, all bulk-capable endpoints work at
1304 * both speeds
1305 */
1306 if (gadget_is_dualspeed(c->cdev->gadget)) {
1307 hs_mbim_in_desc.bEndpointAddress =
1308 fs_mbim_in_desc.bEndpointAddress;
1309 hs_mbim_out_desc.bEndpointAddress =
1310 fs_mbim_out_desc.bEndpointAddress;
1311 hs_mbim_notify_desc.bEndpointAddress =
1312 fs_mbim_notify_desc.bEndpointAddress;
1313
1314 /* copy descriptors, and track endpoint copies */
1315 f->hs_descriptors = usb_copy_descriptors(mbim_hs_function);
1316 if (!f->hs_descriptors)
1317 goto fail;
1318 }
1319
1320 pr_info("mbim(%d): %s speed IN/%s OUT/%s NOTIFY/%s\n",
1321 mbim->port_num,
1322 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
1323 mbim->bam_port.in->name, mbim->bam_port.out->name,
1324 mbim->not_port.notify->name);
1325
1326 return 0;
1327
1328fail:
1329 pr_err("%s failed to bind, err %d\n", f->name, status);
1330
1331 if (f->descriptors)
1332 usb_free_descriptors(f->descriptors);
1333
1334 if (mbim->not_port.notify_req) {
1335 kfree(mbim->not_port.notify_req->buf);
1336 usb_ep_free_request(mbim->not_port.notify,
1337 mbim->not_port.notify_req);
1338 }
1339
1340 /* we might as well release our claims on endpoints */
1341 if (mbim->not_port.notify)
1342 mbim->not_port.notify->driver_data = NULL;
1343 if (mbim->bam_port.out)
1344 mbim->bam_port.out->driver_data = NULL;
1345 if (mbim->bam_port.in)
1346 mbim->bam_port.in->driver_data = NULL;
1347
1348 return status;
1349}
1350
1351static void mbim_unbind(struct usb_configuration *c, struct usb_function *f)
1352{
1353 struct f_mbim *mbim = func_to_mbim(f);
1354
1355 if (gadget_is_dualspeed(c->cdev->gadget))
1356 usb_free_descriptors(f->hs_descriptors);
1357 usb_free_descriptors(f->descriptors);
1358
1359 kfree(mbim->not_port.notify_req->buf);
1360 usb_ep_free_request(mbim->not_port.notify, mbim->not_port.notify_req);
1361}
1362
1363/**
1364 * mbim_bind_config - add MBIM link to a configuration
1365 * @c: the configuration to support the network link
1366 * Context: single threaded during gadget setup
1367 * Returns zero on success, else negative errno.
1368 */
1369int mbim_bind_config(struct usb_configuration *c, unsigned portno)
1370{
1371 struct f_mbim *mbim = NULL;
1372 int status = 0;
1373
1374 pr_info("port number %u", portno);
1375
1376 if (portno >= nr_mbim_ports) {
1377 pr_err("Can not add port %u. Max ports = %d",
1378 portno, nr_mbim_ports);
1379 return -ENODEV;
1380 }
1381
1382 status = mbim_bam_setup(nr_mbim_ports);
1383 if (status) {
1384 pr_err("bam setup failed");
1385 return status;
1386 }
1387
1388 /* maybe allocate device-global string IDs */
1389 if (mbim_string_defs[0].id == 0) {
1390
1391 /* control interface label */
1392 status = usb_string_id(c->cdev);
1393 if (status < 0)
1394 return status;
1395 mbim_string_defs[STRING_CTRL_IDX].id = status;
1396 mbim_control_intf.iInterface = status;
1397
1398 /* data interface label */
1399 status = usb_string_id(c->cdev);
1400 if (status < 0)
1401 return status;
1402 mbim_string_defs[STRING_DATA_IDX].id = status;
1403 mbim_data_nop_intf.iInterface = status;
1404 mbim_data_intf.iInterface = status;
1405 }
1406
1407 /* allocate and initialize one new instance */
1408 mbim = mbim_ports[0].port;
1409 if (!mbim) {
1410 pr_info("mbim struct not allocated");
1411 return -ENOMEM;
1412 }
1413
1414 mbim->cdev = c->cdev;
1415
1416 spin_lock_init(&mbim->lock);
1417
1418 mbim_reset_values(mbim);
1419
1420 mbim->function.name = "usb_mbim";
1421 mbim->function.strings = mbim_strings;
1422 mbim->function.bind = mbim_bind;
1423 mbim->function.unbind = mbim_unbind;
1424 mbim->function.set_alt = mbim_set_alt;
1425 mbim->function.get_alt = mbim_get_alt;
1426 mbim->function.setup = mbim_setup;
1427 mbim->function.disable = mbim_disable;
1428
1429 INIT_LIST_HEAD(&mbim->cpkt_req_q);
1430 INIT_LIST_HEAD(&mbim->cpkt_resp_q);
1431
1432 status = usb_add_function(c, &mbim->function);
1433
1434 pr_info("Exit status %d", status);
1435
1436 return status;
1437}
1438
1439/* ------------ MBIM DRIVER File Operations API for USER SPACE ------------ */
1440
1441static ssize_t
1442mbim_read(struct file *fp, char __user *buf, size_t count, loff_t *pos)
1443{
1444 struct f_mbim *dev = fp->private_data;
1445 struct ctrl_pkt *cpkt = NULL;
1446 int ret = 0;
1447
1448 pr_debug("Enter(%d)\n", count);
1449
1450 if (!dev) {
1451 pr_err("Received NULL mbim pointer\n");
1452 return -ENODEV;
1453 }
1454
1455 if (count > MBIM_BULK_BUFFER_SIZE) {
1456 pr_err("Buffer size is too big %d, should be at most %d\n",
1457 count, MBIM_BULK_BUFFER_SIZE);
1458 return -EINVAL;
1459 }
1460
1461 if (mbim_lock(&dev->read_excl)) {
1462 pr_err("Previous reading is not finished yet\n");
1463 return -EBUSY;
1464 }
1465
1466 /* block until mbim online */
1467 while (!(atomic_read(&dev->online) || atomic_read(&dev->error))) {
1468 pr_err("USB cable not connected. Wait.\n");
1469 ret = wait_event_interruptible(dev->read_wq,
1470 (atomic_read(&dev->online) ||
1471 atomic_read(&dev->error)));
1472 if (ret < 0) {
1473 mbim_unlock(&dev->read_excl);
1474 return 0;
1475 }
1476 }
1477
1478 if (atomic_read(&dev->error)) {
1479 mbim_unlock(&dev->read_excl);
1480 return -EIO;
1481 }
1482
1483 while (list_empty(&dev->cpkt_req_q)) {
1484 pr_err("Requests list is empty. Wait.\n");
1485 ret = wait_event_interruptible(dev->read_wq,
1486 !list_empty(&dev->cpkt_req_q));
1487 if (ret < 0) {
1488 pr_err("Waiting failed\n");
1489 mbim_unlock(&dev->read_excl);
1490 return 0;
1491 }
1492 pr_debug("Received request packet\n");
1493 }
1494
1495 cpkt = list_first_entry(&dev->cpkt_req_q, struct ctrl_pkt,
1496 list);
1497 if (cpkt->len > count) {
1498 mbim_unlock(&dev->read_excl);
1499 pr_err("cpkt size too big:%d > buf size:%d\n",
1500 cpkt->len, count);
1501 return -ENOMEM;
1502 }
1503
1504 pr_debug("cpkt size:%d\n", cpkt->len);
1505
1506 list_del(&cpkt->list);
1507 mbim_unlock(&dev->read_excl);
1508
1509 ret = copy_to_user(buf, cpkt->buf, cpkt->len);
1510 if (ret) {
1511 pr_err("copy_to_user failed: err %d\n", ret);
1512 ret = 0;
1513 } else {
1514 pr_debug("copied %d bytes to user\n", cpkt->len);
1515 ret = cpkt->len;
1516 }
1517
1518 mbim_free_ctrl_pkt(cpkt);
1519
1520 return ret;
1521}
1522
1523static ssize_t
1524mbim_write(struct file *fp, const char __user *buf, size_t count, loff_t *pos)
1525{
1526 struct f_mbim *dev = fp->private_data;
1527 struct ctrl_pkt *cpkt = NULL;
1528 int ret = 0;
1529
1530 pr_debug("Enter(%d)", count);
1531
1532 if (!dev) {
1533 pr_err("Received NULL mbim pointer\n");
1534 return -ENODEV;
1535 }
1536
1537 if (!count) {
1538 pr_err("zero length ctrl pkt\n");
1539 return -ENODEV;
1540 }
1541
1542 if (count > MAX_CTRL_PKT_SIZE) {
1543 pr_err("given pkt size too big:%d > max_pkt_size:%d\n",
1544 count, MAX_CTRL_PKT_SIZE);
1545 return -ENOMEM;
1546 }
1547
1548 if (mbim_lock(&dev->write_excl)) {
1549 pr_err("Previous writing not finished yet\n");
1550 return -EBUSY;
1551 }
1552
1553 if (!atomic_read(&dev->online)) {
1554 pr_err("USB cable not connected\n");
1555 mbim_unlock(&dev->write_excl);
1556 return -EPIPE;
1557 }
1558
1559 cpkt = mbim_alloc_ctrl_pkt(count, GFP_KERNEL);
1560 if (!cpkt) {
1561 pr_err("failed to allocate ctrl pkt\n");
1562 mbim_unlock(&dev->write_excl);
1563 return -ENOMEM;
1564 }
1565
1566 ret = copy_from_user(cpkt->buf, buf, count);
1567 if (ret) {
1568 pr_err("copy_from_user failed err:%d\n", ret);
1569 mbim_free_ctrl_pkt(cpkt);
1570 mbim_unlock(&dev->write_excl);
1571 return 0;
1572 }
1573
1574 fmbim_send_cpkt_response(dev, cpkt);
1575
1576 mbim_unlock(&dev->write_excl);
1577
1578 pr_debug("Exit(%d)", count);
1579
1580 return count;
1581}
1582
1583static int mbim_open(struct inode *ip, struct file *fp)
1584{
1585 pr_info("Open mbim driver\n");
1586
1587 while (!_mbim_dev) {
1588 pr_err("mbim_dev not created yet\n");
1589 return -ENODEV;
1590 }
1591
1592 if (mbim_lock(&_mbim_dev->open_excl)) {
1593 pr_err("Already opened\n");
1594 return -EBUSY;
1595 }
1596
1597 pr_info("Lock mbim_dev->open_excl for open\n");
1598
1599 if (!atomic_read(&_mbim_dev->online))
1600 pr_err("USB cable not connected\n");
1601
1602 pr_info("Set QBI pid %d\n", pid_nr(task_pid(current)));
1603 _mbim_dev->user_pid = pid_nr(task_pid(current));
1604
1605 fp->private_data = _mbim_dev;
1606
1607 atomic_set(&_mbim_dev->error, 0);
1608
1609 spin_lock(&_mbim_dev->lock);
1610 _mbim_dev->is_open = true;
1611 mbim_notify(_mbim_dev);
1612 spin_unlock(&_mbim_dev->lock);
1613
1614 pr_info("Exit, mbim file opened\n");
1615
1616 return 0;
1617}
1618
1619static int mbim_release(struct inode *ip, struct file *fp)
1620{
1621 struct f_mbim *mbim = fp->private_data;
1622
1623 pr_info("Close mbim file");
1624
1625 spin_lock(&mbim->lock);
1626 mbim->is_open = false;
1627 mbim_notify(mbim);
1628 spin_unlock(&mbim->lock);
1629
1630 mbim->user_pid = 0;
1631
1632 mbim_unlock(&_mbim_dev->open_excl);
1633
1634 return 0;
1635}
1636
1637static long mbim_ioctl(struct file *fp, unsigned cmd, unsigned long arg)
1638{
1639 struct f_mbim *mbim = fp->private_data;
1640 int ret = 0;
1641
1642 pr_info("Received command %d", cmd);
1643
1644 if (mbim_lock(&mbim->ioctl_excl))
1645 return -EBUSY;
1646
1647 switch (cmd) {
1648 case MBIM_GET_NTB_SIZE:
1649 ret = copy_to_user((void __user *)arg,
1650 &mbim->ntb_input_size, sizeof(mbim->ntb_input_size));
1651 if (ret) {
1652 pr_err("copying to user space failed");
1653 ret = -EFAULT;
1654 }
1655 pr_info("Sent NTB size %d", mbim->ntb_input_size);
1656 break;
1657 case MBIM_GET_DATAGRAM_COUNT:
1658 ret = copy_to_user((void __user *)arg,
1659 &mbim->ntb_max_datagrams,
1660 sizeof(mbim->ntb_max_datagrams));
1661 if (ret) {
1662 pr_err("copying to user space failed");
1663 ret = -EFAULT;
1664 }
1665 pr_info("Sent NTB datagrams count %d",
1666 mbim->ntb_max_datagrams);
1667 break;
1668 default:
1669 pr_err("wrong parameter");
1670 ret = -EINVAL;
1671 }
1672
1673 mbim_unlock(&mbim->ioctl_excl);
1674
1675 return ret;
1676}
1677
1678/* file operations for MBIM device /dev/android_mbim */
1679static const struct file_operations mbim_fops = {
1680 .owner = THIS_MODULE,
1681 .open = mbim_open,
1682 .release = mbim_release,
1683 .read = mbim_read,
1684 .write = mbim_write,
1685 .unlocked_ioctl = mbim_ioctl,
1686};
1687
1688static struct miscdevice mbim_device = {
1689 .minor = MISC_DYNAMIC_MINOR,
1690 .name = "android_mbim",
1691 .fops = &mbim_fops,
1692};
1693
1694static int mbim_init(int instances)
1695{
1696 int i;
1697 struct f_mbim *dev = NULL;
1698 int ret;
1699
1700 pr_info("initialize %d instances\n", instances);
1701
1702 if (instances > NR_MBIM_PORTS) {
1703 pr_err("Max-%d instances supported\n", NR_MBIM_PORTS);
1704 return -EINVAL;
1705 }
1706
1707 for (i = 0; i < instances; i++) {
1708 dev = kzalloc(sizeof(struct f_mbim), GFP_KERNEL);
1709 if (!dev) {
1710 pr_err("Failed to allocate mbim dev\n");
1711 ret = -ENOMEM;
1712 goto fail_probe;
1713 }
1714
1715 dev->port_num = i;
1716 spin_lock_init(&dev->lock);
1717 INIT_LIST_HEAD(&dev->cpkt_req_q);
1718 INIT_LIST_HEAD(&dev->cpkt_resp_q);
1719
1720 mbim_ports[i].port = dev;
1721 mbim_ports[i].port_num = i;
1722
1723 init_waitqueue_head(&dev->read_wq);
1724 init_waitqueue_head(&dev->write_wq);
1725
1726 atomic_set(&dev->open_excl, 0);
1727 atomic_set(&dev->ioctl_excl, 0);
1728 atomic_set(&dev->read_excl, 0);
1729 atomic_set(&dev->write_excl, 0);
1730
1731 nr_mbim_ports++;
1732
1733 }
1734
1735 _mbim_dev = dev;
1736 ret = misc_register(&mbim_device);
1737 if (ret) {
1738 pr_err("mbim driver failed to register");
1739 goto fail_probe;
1740 }
1741
1742 pr_info("Initialized %d ports\n", nr_mbim_ports);
1743
1744 return ret;
1745
1746fail_probe:
1747 pr_err("Failed");
1748 for (i = 0; i < nr_mbim_ports; i++) {
1749 kfree(mbim_ports[i].port);
1750 mbim_ports[i].port = NULL;
1751 }
1752
1753 return ret;
1754}
1755
1756static void fmbim_cleanup(void)
1757{
1758 int i = 0;
1759
1760 pr_info("Enter");
1761
1762 for (i = 0; i < nr_mbim_ports; i++) {
1763 kfree(mbim_ports[i].port);
1764 mbim_ports[i].port = NULL;
1765 }
1766 nr_mbim_ports = 0;
1767
1768 misc_deregister(&mbim_device);
1769
1770 _mbim_dev = NULL;
1771}
1772