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