xref: /openbmc/linux/drivers/net/usb/cdc_mbim.c (revision b664e06d)
1 /*
2  * Copyright (c) 2012  Smith Micro Software, Inc.
3  * Copyright (c) 2012  Bjørn Mork <bjorn@mork.no>
4  *
5  * This driver is based on and reuse most of cdc_ncm, which is
6  * Copyright (C) ST-Ericsson 2010-2012
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * version 2 as published by the Free Software Foundation.
11  */
12 
13 #include <linux/module.h>
14 #include <linux/netdevice.h>
15 #include <linux/ethtool.h>
16 #include <linux/if_vlan.h>
17 #include <linux/ip.h>
18 #include <linux/mii.h>
19 #include <linux/usb.h>
20 #include <linux/usb/cdc.h>
21 #include <linux/usb/usbnet.h>
22 #include <linux/usb/cdc-wdm.h>
23 #include <linux/usb/cdc_ncm.h>
24 #include <net/ipv6.h>
25 #include <net/addrconf.h>
26 #include <net/ipv6_stubs.h>
27 
28 /* alternative VLAN for IP session 0 if not untagged */
29 #define MBIM_IPS0_VID	4094
30 
31 /* driver specific data - must match cdc_ncm usage */
32 struct cdc_mbim_state {
33 	struct cdc_ncm_ctx *ctx;
34 	atomic_t pmcount;
35 	struct usb_driver *subdriver;
36 	unsigned long _unused;
37 	unsigned long flags;
38 };
39 
40 /* flags for the cdc_mbim_state.flags field */
41 enum cdc_mbim_flags {
42 	FLAG_IPS0_VLAN = 1 << 0,	/* IP session 0 is tagged  */
43 };
44 
45 /* using a counter to merge subdriver requests with our own into a combined state */
46 static int cdc_mbim_manage_power(struct usbnet *dev, int on)
47 {
48 	struct cdc_mbim_state *info = (void *)&dev->data;
49 	int rv = 0;
50 
51 	dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, atomic_read(&info->pmcount), on);
52 
53 	if ((on && atomic_add_return(1, &info->pmcount) == 1) || (!on && atomic_dec_and_test(&info->pmcount))) {
54 		/* need autopm_get/put here to ensure the usbcore sees the new value */
55 		rv = usb_autopm_get_interface(dev->intf);
56 		dev->intf->needs_remote_wakeup = on;
57 		if (!rv)
58 			usb_autopm_put_interface(dev->intf);
59 	}
60 	return 0;
61 }
62 
63 static int cdc_mbim_wdm_manage_power(struct usb_interface *intf, int status)
64 {
65 	struct usbnet *dev = usb_get_intfdata(intf);
66 
67 	/* can be called while disconnecting */
68 	if (!dev)
69 		return 0;
70 
71 	return cdc_mbim_manage_power(dev, status);
72 }
73 
74 static int cdc_mbim_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
75 {
76 	struct usbnet *dev = netdev_priv(netdev);
77 	struct cdc_mbim_state *info = (void *)&dev->data;
78 
79 	/* creation of this VLAN is a request to tag IP session 0 */
80 	if (vid == MBIM_IPS0_VID)
81 		info->flags |= FLAG_IPS0_VLAN;
82 	else
83 		if (vid >= 512)	/* we don't map these to MBIM session */
84 			return -EINVAL;
85 	return 0;
86 }
87 
88 static int cdc_mbim_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
89 {
90 	struct usbnet *dev = netdev_priv(netdev);
91 	struct cdc_mbim_state *info = (void *)&dev->data;
92 
93 	/* this is a request for an untagged IP session 0 */
94 	if (vid == MBIM_IPS0_VID)
95 		info->flags &= ~FLAG_IPS0_VLAN;
96 	return 0;
97 }
98 
99 static const struct net_device_ops cdc_mbim_netdev_ops = {
100 	.ndo_open             = usbnet_open,
101 	.ndo_stop             = usbnet_stop,
102 	.ndo_start_xmit       = usbnet_start_xmit,
103 	.ndo_tx_timeout       = usbnet_tx_timeout,
104 	.ndo_get_stats64      = usbnet_get_stats64,
105 	.ndo_change_mtu       = cdc_ncm_change_mtu,
106 	.ndo_set_mac_address  = eth_mac_addr,
107 	.ndo_validate_addr    = eth_validate_addr,
108 	.ndo_vlan_rx_add_vid  = cdc_mbim_rx_add_vid,
109 	.ndo_vlan_rx_kill_vid = cdc_mbim_rx_kill_vid,
110 };
111 
112 /* Change the control interface altsetting and update the .driver_info
113  * pointer if the matching entry after changing class codes points to
114  * a different struct
115  */
116 static int cdc_mbim_set_ctrlalt(struct usbnet *dev, struct usb_interface *intf, u8 alt)
117 {
118 	struct usb_driver *driver = to_usb_driver(intf->dev.driver);
119 	const struct usb_device_id *id;
120 	struct driver_info *info;
121 	int ret;
122 
123 	ret = usb_set_interface(dev->udev,
124 				intf->cur_altsetting->desc.bInterfaceNumber,
125 				alt);
126 	if (ret)
127 		return ret;
128 
129 	id = usb_match_id(intf, driver->id_table);
130 	if (!id)
131 		return -ENODEV;
132 
133 	info = (struct driver_info *)id->driver_info;
134 	if (info != dev->driver_info) {
135 		dev_dbg(&intf->dev, "driver_info updated to '%s'\n",
136 			info->description);
137 		dev->driver_info = info;
138 	}
139 	return 0;
140 }
141 
142 static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf)
143 {
144 	struct cdc_ncm_ctx *ctx;
145 	struct usb_driver *subdriver = ERR_PTR(-ENODEV);
146 	int ret = -ENODEV;
147 	u8 data_altsetting = 1;
148 	struct cdc_mbim_state *info = (void *)&dev->data;
149 
150 	/* should we change control altsetting on a NCM/MBIM function? */
151 	if (cdc_ncm_select_altsetting(intf) == CDC_NCM_COMM_ALTSETTING_MBIM) {
152 		data_altsetting = CDC_NCM_DATA_ALTSETTING_MBIM;
153 		ret = cdc_mbim_set_ctrlalt(dev, intf, CDC_NCM_COMM_ALTSETTING_MBIM);
154 		if (ret)
155 			goto err;
156 		ret = -ENODEV;
157 	}
158 
159 	/* we will hit this for NCM/MBIM functions if prefer_mbim is false */
160 	if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
161 		goto err;
162 
163 	ret = cdc_ncm_bind_common(dev, intf, data_altsetting, dev->driver_info->data);
164 	if (ret)
165 		goto err;
166 
167 	ctx = info->ctx;
168 
169 	/* The MBIM descriptor and the status endpoint are required */
170 	if (ctx->mbim_desc && dev->status)
171 		subdriver = usb_cdc_wdm_register(ctx->control,
172 						 &dev->status->desc,
173 						 le16_to_cpu(ctx->mbim_desc->wMaxControlMessage),
174 						 cdc_mbim_wdm_manage_power);
175 	if (IS_ERR(subdriver)) {
176 		ret = PTR_ERR(subdriver);
177 		cdc_ncm_unbind(dev, intf);
178 		goto err;
179 	}
180 
181 	/* can't let usbnet use the interrupt endpoint */
182 	dev->status = NULL;
183 	info->subdriver = subdriver;
184 
185 	/* MBIM cannot do ARP */
186 	dev->net->flags |= IFF_NOARP;
187 
188 	/* no need to put the VLAN tci in the packet headers */
189 	dev->net->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_FILTER;
190 
191 	/* monitor VLAN additions and removals */
192 	dev->net->netdev_ops = &cdc_mbim_netdev_ops;
193 err:
194 	return ret;
195 }
196 
197 static void cdc_mbim_unbind(struct usbnet *dev, struct usb_interface *intf)
198 {
199 	struct cdc_mbim_state *info = (void *)&dev->data;
200 	struct cdc_ncm_ctx *ctx = info->ctx;
201 
202 	/* disconnect subdriver from control interface */
203 	if (info->subdriver && info->subdriver->disconnect)
204 		info->subdriver->disconnect(ctx->control);
205 	info->subdriver = NULL;
206 
207 	/* let NCM unbind clean up both control and data interface */
208 	cdc_ncm_unbind(dev, intf);
209 }
210 
211 /* verify that the ethernet protocol is IPv4 or IPv6 */
212 static bool is_ip_proto(__be16 proto)
213 {
214 	switch (proto) {
215 	case htons(ETH_P_IP):
216 	case htons(ETH_P_IPV6):
217 		return true;
218 	}
219 	return false;
220 }
221 
222 static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
223 {
224 	struct sk_buff *skb_out;
225 	struct cdc_mbim_state *info = (void *)&dev->data;
226 	struct cdc_ncm_ctx *ctx = info->ctx;
227 	__le32 sign = cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN);
228 	u16 tci = 0;
229 	bool is_ip;
230 	u8 *c;
231 
232 	if (!ctx)
233 		goto error;
234 
235 	if (skb) {
236 		if (skb->len <= ETH_HLEN)
237 			goto error;
238 
239 		/* Some applications using e.g. packet sockets will
240 		 * bypass the VLAN acceleration and create tagged
241 		 * ethernet frames directly.  We primarily look for
242 		 * the accelerated out-of-band tag, but fall back if
243 		 * required
244 		 */
245 		skb_reset_mac_header(skb);
246 		if (vlan_get_tag(skb, &tci) < 0 && skb->len > VLAN_ETH_HLEN &&
247 		    __vlan_get_tag(skb, &tci) == 0) {
248 			is_ip = is_ip_proto(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto);
249 			skb_pull(skb, VLAN_ETH_HLEN);
250 		} else {
251 			is_ip = is_ip_proto(eth_hdr(skb)->h_proto);
252 			skb_pull(skb, ETH_HLEN);
253 		}
254 
255 		/* Is IP session <0> tagged too? */
256 		if (info->flags & FLAG_IPS0_VLAN) {
257 			/* drop all untagged packets */
258 			if (!tci)
259 				goto error;
260 			/* map MBIM_IPS0_VID to IPS<0> */
261 			if (tci == MBIM_IPS0_VID)
262 				tci = 0;
263 		}
264 
265 		/* mapping VLANs to MBIM sessions:
266 		 *   no tag     => IPS session <0> if !FLAG_IPS0_VLAN
267 		 *   1 - 255    => IPS session <vlanid>
268 		 *   256 - 511  => DSS session <vlanid - 256>
269 		 *   512 - 4093 => unsupported, drop
270 		 *   4094       => IPS session <0> if FLAG_IPS0_VLAN
271 		 */
272 
273 		switch (tci & 0x0f00) {
274 		case 0x0000: /* VLAN ID 0 - 255 */
275 			if (!is_ip)
276 				goto error;
277 			c = (u8 *)&sign;
278 			c[3] = tci;
279 			break;
280 		case 0x0100: /* VLAN ID 256 - 511 */
281 			if (is_ip)
282 				goto error;
283 			sign = cpu_to_le32(USB_CDC_MBIM_NDP16_DSS_SIGN);
284 			c = (u8 *)&sign;
285 			c[3] = tci;
286 			break;
287 		default:
288 			netif_err(dev, tx_err, dev->net,
289 				  "unsupported tci=0x%04x\n", tci);
290 			goto error;
291 		}
292 	}
293 
294 	spin_lock_bh(&ctx->mtx);
295 	skb_out = cdc_ncm_fill_tx_frame(dev, skb, sign);
296 	spin_unlock_bh(&ctx->mtx);
297 	return skb_out;
298 
299 error:
300 	if (skb)
301 		dev_kfree_skb_any(skb);
302 
303 	return NULL;
304 }
305 
306 /* Some devices are known to send Neigbor Solicitation messages and
307  * require Neigbor Advertisement replies.  The IPv6 core will not
308  * respond since IFF_NOARP is set, so we must handle them ourselves.
309  */
310 static void do_neigh_solicit(struct usbnet *dev, u8 *buf, u16 tci)
311 {
312 	struct ipv6hdr *iph = (void *)buf;
313 	struct nd_msg *msg = (void *)(iph + 1);
314 	struct net_device *netdev;
315 	struct inet6_dev *in6_dev;
316 	bool is_router;
317 
318 	/* we'll only respond to requests from unicast addresses to
319 	 * our solicited node addresses.
320 	 */
321 	if (!ipv6_addr_is_solict_mult(&iph->daddr) ||
322 	    !(ipv6_addr_type(&iph->saddr) & IPV6_ADDR_UNICAST))
323 		return;
324 
325 	/* need to send the NA on the VLAN dev, if any */
326 	rcu_read_lock();
327 	if (tci) {
328 		netdev = __vlan_find_dev_deep_rcu(dev->net, htons(ETH_P_8021Q),
329 						  tci);
330 		if (!netdev) {
331 			rcu_read_unlock();
332 			return;
333 		}
334 	} else {
335 		netdev = dev->net;
336 	}
337 	dev_hold(netdev);
338 	rcu_read_unlock();
339 
340 	in6_dev = in6_dev_get(netdev);
341 	if (!in6_dev)
342 		goto out;
343 	is_router = !!in6_dev->cnf.forwarding;
344 	in6_dev_put(in6_dev);
345 
346 	/* ipv6_stub != NULL if in6_dev_get returned an inet6_dev */
347 	ipv6_stub->ndisc_send_na(netdev, &iph->saddr, &msg->target,
348 				 is_router /* router */,
349 				 true /* solicited */,
350 				 false /* override */,
351 				 true /* inc_opt */);
352 out:
353 	dev_put(netdev);
354 }
355 
356 static bool is_neigh_solicit(u8 *buf, size_t len)
357 {
358 	struct ipv6hdr *iph = (void *)buf;
359 	struct nd_msg *msg = (void *)(iph + 1);
360 
361 	return (len >= sizeof(struct ipv6hdr) + sizeof(struct nd_msg) &&
362 		iph->nexthdr == IPPROTO_ICMPV6 &&
363 		msg->icmph.icmp6_code == 0 &&
364 		msg->icmph.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION);
365 }
366 
367 
368 static struct sk_buff *cdc_mbim_process_dgram(struct usbnet *dev, u8 *buf, size_t len, u16 tci)
369 {
370 	__be16 proto = htons(ETH_P_802_3);
371 	struct sk_buff *skb = NULL;
372 
373 	if (tci < 256 || tci == MBIM_IPS0_VID) { /* IPS session? */
374 		if (len < sizeof(struct iphdr))
375 			goto err;
376 
377 		switch (*buf & 0xf0) {
378 		case 0x40:
379 			proto = htons(ETH_P_IP);
380 			break;
381 		case 0x60:
382 			if (is_neigh_solicit(buf, len))
383 				do_neigh_solicit(dev, buf, tci);
384 			proto = htons(ETH_P_IPV6);
385 			break;
386 		default:
387 			goto err;
388 		}
389 	}
390 
391 	skb = netdev_alloc_skb_ip_align(dev->net,  len + ETH_HLEN);
392 	if (!skb)
393 		goto err;
394 
395 	/* add an ethernet header */
396 	skb_put(skb, ETH_HLEN);
397 	skb_reset_mac_header(skb);
398 	eth_hdr(skb)->h_proto = proto;
399 	eth_zero_addr(eth_hdr(skb)->h_source);
400 	memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN);
401 
402 	/* add datagram */
403 	skb_put_data(skb, buf, len);
404 
405 	/* map MBIM session to VLAN */
406 	if (tci)
407 		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), tci);
408 err:
409 	return skb;
410 }
411 
412 static int cdc_mbim_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
413 {
414 	struct sk_buff *skb;
415 	struct cdc_mbim_state *info = (void *)&dev->data;
416 	struct cdc_ncm_ctx *ctx = info->ctx;
417 	int len;
418 	int nframes;
419 	int x;
420 	int offset;
421 	struct usb_cdc_ncm_ndp16 *ndp16;
422 	struct usb_cdc_ncm_dpe16 *dpe16;
423 	int ndpoffset;
424 	int loopcount = 50; /* arbitrary max preventing infinite loop */
425 	u32 payload = 0;
426 	u8 *c;
427 	u16 tci;
428 
429 	ndpoffset = cdc_ncm_rx_verify_nth16(ctx, skb_in);
430 	if (ndpoffset < 0)
431 		goto error;
432 
433 next_ndp:
434 	nframes = cdc_ncm_rx_verify_ndp16(skb_in, ndpoffset);
435 	if (nframes < 0)
436 		goto error;
437 
438 	ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset);
439 
440 	switch (ndp16->dwSignature & cpu_to_le32(0x00ffffff)) {
441 	case cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN):
442 		c = (u8 *)&ndp16->dwSignature;
443 		tci = c[3];
444 		/* tag IPS<0> packets too if MBIM_IPS0_VID exists */
445 		if (!tci && info->flags & FLAG_IPS0_VLAN)
446 			tci = MBIM_IPS0_VID;
447 		break;
448 	case cpu_to_le32(USB_CDC_MBIM_NDP16_DSS_SIGN):
449 		c = (u8 *)&ndp16->dwSignature;
450 		tci = c[3] + 256;
451 		break;
452 	default:
453 		netif_dbg(dev, rx_err, dev->net,
454 			  "unsupported NDP signature <0x%08x>\n",
455 			  le32_to_cpu(ndp16->dwSignature));
456 		goto err_ndp;
457 
458 	}
459 
460 	dpe16 = ndp16->dpe16;
461 	for (x = 0; x < nframes; x++, dpe16++) {
462 		offset = le16_to_cpu(dpe16->wDatagramIndex);
463 		len = le16_to_cpu(dpe16->wDatagramLength);
464 
465 		/*
466 		 * CDC NCM ch. 3.7
467 		 * All entries after first NULL entry are to be ignored
468 		 */
469 		if ((offset == 0) || (len == 0)) {
470 			if (!x)
471 				goto err_ndp; /* empty NTB */
472 			break;
473 		}
474 
475 		/* sanity checking */
476 		if (((offset + len) > skb_in->len) || (len > ctx->rx_max)) {
477 			netif_dbg(dev, rx_err, dev->net,
478 				  "invalid frame detected (ignored) offset[%u]=%u, length=%u, skb=%p\n",
479 				  x, offset, len, skb_in);
480 			if (!x)
481 				goto err_ndp;
482 			break;
483 		} else {
484 			skb = cdc_mbim_process_dgram(dev, skb_in->data + offset, len, tci);
485 			if (!skb)
486 				goto error;
487 			usbnet_skb_return(dev, skb);
488 			payload += len;	/* count payload bytes in this NTB */
489 		}
490 	}
491 err_ndp:
492 	/* are there more NDPs to process? */
493 	ndpoffset = le16_to_cpu(ndp16->wNextNdpIndex);
494 	if (ndpoffset && loopcount--)
495 		goto next_ndp;
496 
497 	/* update stats */
498 	ctx->rx_overhead += skb_in->len - payload;
499 	ctx->rx_ntbs++;
500 
501 	return 1;
502 error:
503 	return 0;
504 }
505 
506 static int cdc_mbim_suspend(struct usb_interface *intf, pm_message_t message)
507 {
508 	int ret = -ENODEV;
509 	struct usbnet *dev = usb_get_intfdata(intf);
510 	struct cdc_mbim_state *info = (void *)&dev->data;
511 	struct cdc_ncm_ctx *ctx = info->ctx;
512 
513 	if (!ctx)
514 		goto error;
515 
516 	/*
517 	 * Both usbnet_suspend() and subdriver->suspend() MUST return 0
518 	 * in system sleep context, otherwise, the resume callback has
519 	 * to recover device from previous suspend failure.
520 	 */
521 	ret = usbnet_suspend(intf, message);
522 	if (ret < 0)
523 		goto error;
524 
525 	if (intf == ctx->control && info->subdriver && info->subdriver->suspend)
526 		ret = info->subdriver->suspend(intf, message);
527 	if (ret < 0)
528 		usbnet_resume(intf);
529 
530 error:
531 	return ret;
532 }
533 
534 static int cdc_mbim_resume(struct usb_interface *intf)
535 {
536 	int  ret = 0;
537 	struct usbnet *dev = usb_get_intfdata(intf);
538 	struct cdc_mbim_state *info = (void *)&dev->data;
539 	struct cdc_ncm_ctx *ctx = info->ctx;
540 	bool callsub = (intf == ctx->control && info->subdriver && info->subdriver->resume);
541 
542 	if (callsub)
543 		ret = info->subdriver->resume(intf);
544 	if (ret < 0)
545 		goto err;
546 	ret = usbnet_resume(intf);
547 	if (ret < 0 && callsub)
548 		info->subdriver->suspend(intf, PMSG_SUSPEND);
549 err:
550 	return ret;
551 }
552 
553 static const struct driver_info cdc_mbim_info = {
554 	.description = "CDC MBIM",
555 	.flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN,
556 	.bind = cdc_mbim_bind,
557 	.unbind = cdc_mbim_unbind,
558 	.manage_power = cdc_mbim_manage_power,
559 	.rx_fixup = cdc_mbim_rx_fixup,
560 	.tx_fixup = cdc_mbim_tx_fixup,
561 };
562 
563 /* MBIM and NCM devices should not need a ZLP after NTBs with
564  * dwNtbOutMaxSize length. Nevertheless, a number of devices from
565  * different vendor IDs will fail unless we send ZLPs, forcing us
566  * to make this the default.
567  *
568  * This default may cause a performance penalty for spec conforming
569  * devices wanting to take advantage of optimizations possible without
570  * ZLPs.  A whitelist is added in an attempt to avoid this for devices
571  * known to conform to the MBIM specification.
572  *
573  * All known devices supporting NCM compatibility mode are also
574  * conforming to the NCM and MBIM specifications. For this reason, the
575  * NCM subclass entry is also in the ZLP whitelist.
576  */
577 static const struct driver_info cdc_mbim_info_zlp = {
578 	.description = "CDC MBIM",
579 	.flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN | FLAG_SEND_ZLP,
580 	.bind = cdc_mbim_bind,
581 	.unbind = cdc_mbim_unbind,
582 	.manage_power = cdc_mbim_manage_power,
583 	.rx_fixup = cdc_mbim_rx_fixup,
584 	.tx_fixup = cdc_mbim_tx_fixup,
585 };
586 
587 /* The spefication explicitly allows NDPs to be placed anywhere in the
588  * frame, but some devices fail unless the NDP is placed after the IP
589  * packets.  Using the CDC_NCM_FLAG_NDP_TO_END flags to force this
590  * behaviour.
591  *
592  * Note: The current implementation of this feature restricts each NTB
593  * to a single NDP, implying that multiplexed sessions cannot share an
594  * NTB. This might affect performace for multiplexed sessions.
595  */
596 static const struct driver_info cdc_mbim_info_ndp_to_end = {
597 	.description = "CDC MBIM",
598 	.flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN,
599 	.bind = cdc_mbim_bind,
600 	.unbind = cdc_mbim_unbind,
601 	.manage_power = cdc_mbim_manage_power,
602 	.rx_fixup = cdc_mbim_rx_fixup,
603 	.tx_fixup = cdc_mbim_tx_fixup,
604 	.data = CDC_NCM_FLAG_NDP_TO_END,
605 };
606 
607 /* Some modems (e.g. Telit LE922A6) do not work properly with altsetting
608  * toggle done in cdc_ncm_bind_common. CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE
609  * flag is used to avoid this procedure.
610  */
611 static const struct driver_info cdc_mbim_info_avoid_altsetting_toggle = {
612 	.description = "CDC MBIM",
613 	.flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN | FLAG_SEND_ZLP,
614 	.bind = cdc_mbim_bind,
615 	.unbind = cdc_mbim_unbind,
616 	.manage_power = cdc_mbim_manage_power,
617 	.rx_fixup = cdc_mbim_rx_fixup,
618 	.tx_fixup = cdc_mbim_tx_fixup,
619 	.data = CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE,
620 };
621 
622 static const struct usb_device_id mbim_devs[] = {
623 	/* This duplicate NCM entry is intentional. MBIM devices can
624 	 * be disguised as NCM by default, and this is necessary to
625 	 * allow us to bind the correct driver_info to such devices.
626 	 *
627 	 * bind() will sort out this for us, selecting the correct
628 	 * entry and reject the other
629 	 */
630 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
631 	  .driver_info = (unsigned long)&cdc_mbim_info,
632 	},
633 	/* ZLP conformance whitelist: All Ericsson MBIM devices */
634 	{ USB_VENDOR_AND_INTERFACE_INFO(0x0bdb, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
635 	  .driver_info = (unsigned long)&cdc_mbim_info,
636 	},
637 
638 	/* Some Huawei devices, ME906s-158 (12d1:15c1) and E3372
639 	 * (12d1:157d), are known to fail unless the NDP is placed
640 	 * after the IP packets.  Applying the quirk to all Huawei
641 	 * devices is broader than necessary, but harmless.
642 	 */
643 	{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
644 	  .driver_info = (unsigned long)&cdc_mbim_info_ndp_to_end,
645 	},
646 
647 	/* The HP lt4132 (03f0:a31d) is a rebranded Huawei ME906s-158,
648 	 * therefore it too requires the above "NDP to end" quirk.
649 	 */
650 	{ USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0xa31d, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
651 	  .driver_info = (unsigned long)&cdc_mbim_info_ndp_to_end,
652 	},
653 
654 	/* Telit LE922A6 in MBIM composition */
655 	{ USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1041, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
656 	  .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
657 	},
658 
659 	/* default entry */
660 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
661 	  .driver_info = (unsigned long)&cdc_mbim_info_zlp,
662 	},
663 	{
664 	},
665 };
666 MODULE_DEVICE_TABLE(usb, mbim_devs);
667 
668 static struct usb_driver cdc_mbim_driver = {
669 	.name = "cdc_mbim",
670 	.id_table = mbim_devs,
671 	.probe = usbnet_probe,
672 	.disconnect = usbnet_disconnect,
673 	.suspend = cdc_mbim_suspend,
674 	.resume = cdc_mbim_resume,
675 	.reset_resume =	cdc_mbim_resume,
676 	.supports_autosuspend = 1,
677 	.disable_hub_initiated_lpm = 1,
678 };
679 module_usb_driver(cdc_mbim_driver);
680 
681 MODULE_AUTHOR("Greg Suarez <gsuarez@smithmicro.com>");
682 MODULE_AUTHOR("Bjørn Mork <bjorn@mork.no>");
683 MODULE_DESCRIPTION("USB CDC MBIM host driver");
684 MODULE_LICENSE("GPL");
685