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