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 /* driver specific data - must match cdc_ncm usage */ 28 struct cdc_mbim_state { 29 struct cdc_ncm_ctx *ctx; 30 atomic_t pmcount; 31 struct usb_driver *subdriver; 32 struct usb_interface *control; 33 struct usb_interface *data; 34 }; 35 36 /* using a counter to merge subdriver requests with our own into a combined state */ 37 static int cdc_mbim_manage_power(struct usbnet *dev, int on) 38 { 39 struct cdc_mbim_state *info = (void *)&dev->data; 40 int rv = 0; 41 42 dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, atomic_read(&info->pmcount), on); 43 44 if ((on && atomic_add_return(1, &info->pmcount) == 1) || (!on && atomic_dec_and_test(&info->pmcount))) { 45 /* need autopm_get/put here to ensure the usbcore sees the new value */ 46 rv = usb_autopm_get_interface(dev->intf); 47 dev->intf->needs_remote_wakeup = on; 48 if (!rv) 49 usb_autopm_put_interface(dev->intf); 50 } 51 return 0; 52 } 53 54 static int cdc_mbim_wdm_manage_power(struct usb_interface *intf, int status) 55 { 56 struct usbnet *dev = usb_get_intfdata(intf); 57 58 /* can be called while disconnecting */ 59 if (!dev) 60 return 0; 61 62 return cdc_mbim_manage_power(dev, status); 63 } 64 65 66 static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf) 67 { 68 struct cdc_ncm_ctx *ctx; 69 struct usb_driver *subdriver = ERR_PTR(-ENODEV); 70 int ret = -ENODEV; 71 u8 data_altsetting = cdc_ncm_select_altsetting(dev, intf); 72 struct cdc_mbim_state *info = (void *)&dev->data; 73 74 /* Probably NCM, defer for cdc_ncm_bind */ 75 if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) 76 goto err; 77 78 ret = cdc_ncm_bind_common(dev, intf, data_altsetting); 79 if (ret) 80 goto err; 81 82 ctx = info->ctx; 83 84 /* The MBIM descriptor and the status endpoint are required */ 85 if (ctx->mbim_desc && dev->status) 86 subdriver = usb_cdc_wdm_register(ctx->control, 87 &dev->status->desc, 88 le16_to_cpu(ctx->mbim_desc->wMaxControlMessage), 89 cdc_mbim_wdm_manage_power); 90 if (IS_ERR(subdriver)) { 91 ret = PTR_ERR(subdriver); 92 cdc_ncm_unbind(dev, intf); 93 goto err; 94 } 95 96 /* can't let usbnet use the interrupt endpoint */ 97 dev->status = NULL; 98 info->subdriver = subdriver; 99 100 /* MBIM cannot do ARP */ 101 dev->net->flags |= IFF_NOARP; 102 103 /* no need to put the VLAN tci in the packet headers */ 104 dev->net->features |= NETIF_F_HW_VLAN_CTAG_TX; 105 err: 106 return ret; 107 } 108 109 static void cdc_mbim_unbind(struct usbnet *dev, struct usb_interface *intf) 110 { 111 struct cdc_mbim_state *info = (void *)&dev->data; 112 struct cdc_ncm_ctx *ctx = info->ctx; 113 114 /* disconnect subdriver from control interface */ 115 if (info->subdriver && info->subdriver->disconnect) 116 info->subdriver->disconnect(ctx->control); 117 info->subdriver = NULL; 118 119 /* let NCM unbind clean up both control and data interface */ 120 cdc_ncm_unbind(dev, intf); 121 } 122 123 124 static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) 125 { 126 struct sk_buff *skb_out; 127 struct cdc_mbim_state *info = (void *)&dev->data; 128 struct cdc_ncm_ctx *ctx = info->ctx; 129 __le32 sign = cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN); 130 u16 tci = 0; 131 u8 *c; 132 133 if (!ctx) 134 goto error; 135 136 if (skb) { 137 if (skb->len <= ETH_HLEN) 138 goto error; 139 140 /* mapping VLANs to MBIM sessions: 141 * no tag => IPS session <0> 142 * 1 - 255 => IPS session <vlanid> 143 * 256 - 511 => DSS session <vlanid - 256> 144 * 512 - 4095 => unsupported, drop 145 */ 146 vlan_get_tag(skb, &tci); 147 148 switch (tci & 0x0f00) { 149 case 0x0000: /* VLAN ID 0 - 255 */ 150 /* verify that datagram is IPv4 or IPv6 */ 151 skb_reset_mac_header(skb); 152 switch (eth_hdr(skb)->h_proto) { 153 case htons(ETH_P_IP): 154 case htons(ETH_P_IPV6): 155 break; 156 default: 157 goto error; 158 } 159 c = (u8 *)&sign; 160 c[3] = tci; 161 break; 162 case 0x0100: /* VLAN ID 256 - 511 */ 163 sign = cpu_to_le32(USB_CDC_MBIM_NDP16_DSS_SIGN); 164 c = (u8 *)&sign; 165 c[3] = tci; 166 break; 167 default: 168 netif_err(dev, tx_err, dev->net, 169 "unsupported tci=0x%04x\n", tci); 170 goto error; 171 } 172 skb_pull(skb, ETH_HLEN); 173 } 174 175 spin_lock_bh(&ctx->mtx); 176 skb_out = cdc_ncm_fill_tx_frame(dev, skb, sign); 177 spin_unlock_bh(&ctx->mtx); 178 return skb_out; 179 180 error: 181 if (skb) 182 dev_kfree_skb_any(skb); 183 184 return NULL; 185 } 186 187 /* Some devices are known to send Neigbor Solicitation messages and 188 * require Neigbor Advertisement replies. The IPv6 core will not 189 * respond since IFF_NOARP is set, so we must handle them ourselves. 190 */ 191 static void do_neigh_solicit(struct usbnet *dev, u8 *buf, u16 tci) 192 { 193 struct ipv6hdr *iph = (void *)buf; 194 struct nd_msg *msg = (void *)(iph + 1); 195 struct net_device *netdev; 196 struct inet6_dev *in6_dev; 197 bool is_router; 198 199 /* we'll only respond to requests from unicast addresses to 200 * our solicited node addresses. 201 */ 202 if (!ipv6_addr_is_solict_mult(&iph->daddr) || 203 !(ipv6_addr_type(&iph->saddr) & IPV6_ADDR_UNICAST)) 204 return; 205 206 /* need to send the NA on the VLAN dev, if any */ 207 if (tci) 208 netdev = __vlan_find_dev_deep(dev->net, htons(ETH_P_8021Q), 209 tci); 210 else 211 netdev = dev->net; 212 if (!netdev) 213 return; 214 215 in6_dev = in6_dev_get(netdev); 216 if (!in6_dev) 217 return; 218 is_router = !!in6_dev->cnf.forwarding; 219 in6_dev_put(in6_dev); 220 221 /* ipv6_stub != NULL if in6_dev_get returned an inet6_dev */ 222 ipv6_stub->ndisc_send_na(netdev, NULL, &iph->saddr, &msg->target, 223 is_router /* router */, 224 true /* solicited */, 225 false /* override */, 226 true /* inc_opt */); 227 } 228 229 static bool is_neigh_solicit(u8 *buf, size_t len) 230 { 231 struct ipv6hdr *iph = (void *)buf; 232 struct nd_msg *msg = (void *)(iph + 1); 233 234 return (len >= sizeof(struct ipv6hdr) + sizeof(struct nd_msg) && 235 iph->nexthdr == IPPROTO_ICMPV6 && 236 msg->icmph.icmp6_code == 0 && 237 msg->icmph.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION); 238 } 239 240 241 static struct sk_buff *cdc_mbim_process_dgram(struct usbnet *dev, u8 *buf, size_t len, u16 tci) 242 { 243 __be16 proto = htons(ETH_P_802_3); 244 struct sk_buff *skb = NULL; 245 246 if (tci < 256) { /* IPS session? */ 247 if (len < sizeof(struct iphdr)) 248 goto err; 249 250 switch (*buf & 0xf0) { 251 case 0x40: 252 proto = htons(ETH_P_IP); 253 break; 254 case 0x60: 255 if (is_neigh_solicit(buf, len)) 256 do_neigh_solicit(dev, buf, tci); 257 proto = htons(ETH_P_IPV6); 258 break; 259 default: 260 goto err; 261 } 262 } 263 264 skb = netdev_alloc_skb_ip_align(dev->net, len + ETH_HLEN); 265 if (!skb) 266 goto err; 267 268 /* add an ethernet header */ 269 skb_put(skb, ETH_HLEN); 270 skb_reset_mac_header(skb); 271 eth_hdr(skb)->h_proto = proto; 272 memset(eth_hdr(skb)->h_source, 0, ETH_ALEN); 273 memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN); 274 275 /* add datagram */ 276 memcpy(skb_put(skb, len), buf, len); 277 278 /* map MBIM session to VLAN */ 279 if (tci) 280 vlan_put_tag(skb, htons(ETH_P_8021Q), tci); 281 err: 282 return skb; 283 } 284 285 static int cdc_mbim_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) 286 { 287 struct sk_buff *skb; 288 struct cdc_mbim_state *info = (void *)&dev->data; 289 struct cdc_ncm_ctx *ctx = info->ctx; 290 int len; 291 int nframes; 292 int x; 293 int offset; 294 struct usb_cdc_ncm_ndp16 *ndp16; 295 struct usb_cdc_ncm_dpe16 *dpe16; 296 int ndpoffset; 297 int loopcount = 50; /* arbitrary max preventing infinite loop */ 298 u8 *c; 299 u16 tci; 300 301 ndpoffset = cdc_ncm_rx_verify_nth16(ctx, skb_in); 302 if (ndpoffset < 0) 303 goto error; 304 305 next_ndp: 306 nframes = cdc_ncm_rx_verify_ndp16(skb_in, ndpoffset); 307 if (nframes < 0) 308 goto error; 309 310 ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset); 311 312 switch (ndp16->dwSignature & cpu_to_le32(0x00ffffff)) { 313 case cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN): 314 c = (u8 *)&ndp16->dwSignature; 315 tci = c[3]; 316 break; 317 case cpu_to_le32(USB_CDC_MBIM_NDP16_DSS_SIGN): 318 c = (u8 *)&ndp16->dwSignature; 319 tci = c[3] + 256; 320 break; 321 default: 322 netif_dbg(dev, rx_err, dev->net, 323 "unsupported NDP signature <0x%08x>\n", 324 le32_to_cpu(ndp16->dwSignature)); 325 goto err_ndp; 326 327 } 328 329 dpe16 = ndp16->dpe16; 330 for (x = 0; x < nframes; x++, dpe16++) { 331 offset = le16_to_cpu(dpe16->wDatagramIndex); 332 len = le16_to_cpu(dpe16->wDatagramLength); 333 334 /* 335 * CDC NCM ch. 3.7 336 * All entries after first NULL entry are to be ignored 337 */ 338 if ((offset == 0) || (len == 0)) { 339 if (!x) 340 goto err_ndp; /* empty NTB */ 341 break; 342 } 343 344 /* sanity checking */ 345 if (((offset + len) > skb_in->len) || (len > ctx->rx_max)) { 346 netif_dbg(dev, rx_err, dev->net, 347 "invalid frame detected (ignored) offset[%u]=%u, length=%u, skb=%p\n", 348 x, offset, len, skb_in); 349 if (!x) 350 goto err_ndp; 351 break; 352 } else { 353 skb = cdc_mbim_process_dgram(dev, skb_in->data + offset, len, tci); 354 if (!skb) 355 goto error; 356 usbnet_skb_return(dev, skb); 357 } 358 } 359 err_ndp: 360 /* are there more NDPs to process? */ 361 ndpoffset = le16_to_cpu(ndp16->wNextNdpIndex); 362 if (ndpoffset && loopcount--) 363 goto next_ndp; 364 365 return 1; 366 error: 367 return 0; 368 } 369 370 static int cdc_mbim_suspend(struct usb_interface *intf, pm_message_t message) 371 { 372 int ret = -ENODEV; 373 struct usbnet *dev = usb_get_intfdata(intf); 374 struct cdc_mbim_state *info = (void *)&dev->data; 375 struct cdc_ncm_ctx *ctx = info->ctx; 376 377 if (!ctx) 378 goto error; 379 380 /* 381 * Both usbnet_suspend() and subdriver->suspend() MUST return 0 382 * in system sleep context, otherwise, the resume callback has 383 * to recover device from previous suspend failure. 384 */ 385 ret = usbnet_suspend(intf, message); 386 if (ret < 0) 387 goto error; 388 389 if (intf == ctx->control && info->subdriver && info->subdriver->suspend) 390 ret = info->subdriver->suspend(intf, message); 391 if (ret < 0) 392 usbnet_resume(intf); 393 394 error: 395 return ret; 396 } 397 398 static int cdc_mbim_resume(struct usb_interface *intf) 399 { 400 int ret = 0; 401 struct usbnet *dev = usb_get_intfdata(intf); 402 struct cdc_mbim_state *info = (void *)&dev->data; 403 struct cdc_ncm_ctx *ctx = info->ctx; 404 bool callsub = (intf == ctx->control && info->subdriver && info->subdriver->resume); 405 406 if (callsub) 407 ret = info->subdriver->resume(intf); 408 if (ret < 0) 409 goto err; 410 ret = usbnet_resume(intf); 411 if (ret < 0 && callsub) 412 info->subdriver->suspend(intf, PMSG_SUSPEND); 413 err: 414 return ret; 415 } 416 417 static const struct driver_info cdc_mbim_info = { 418 .description = "CDC MBIM", 419 .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN, 420 .bind = cdc_mbim_bind, 421 .unbind = cdc_mbim_unbind, 422 .manage_power = cdc_mbim_manage_power, 423 .rx_fixup = cdc_mbim_rx_fixup, 424 .tx_fixup = cdc_mbim_tx_fixup, 425 }; 426 427 /* MBIM and NCM devices should not need a ZLP after NTBs with 428 * dwNtbOutMaxSize length. Nevertheless, a number of devices from 429 * different vendor IDs will fail unless we send ZLPs, forcing us 430 * to make this the default. 431 * 432 * This default may cause a performance penalty for spec conforming 433 * devices wanting to take advantage of optimizations possible without 434 * ZLPs. A whitelist is added in an attempt to avoid this for devices 435 * known to conform to the MBIM specification. 436 * 437 * All known devices supporting NCM compatibility mode are also 438 * conforming to the NCM and MBIM specifications. For this reason, the 439 * NCM subclass entry is also in the ZLP whitelist. 440 */ 441 static const struct driver_info cdc_mbim_info_zlp = { 442 .description = "CDC MBIM", 443 .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN | FLAG_SEND_ZLP, 444 .bind = cdc_mbim_bind, 445 .unbind = cdc_mbim_unbind, 446 .manage_power = cdc_mbim_manage_power, 447 .rx_fixup = cdc_mbim_rx_fixup, 448 .tx_fixup = cdc_mbim_tx_fixup, 449 }; 450 451 static const struct usb_device_id mbim_devs[] = { 452 /* This duplicate NCM entry is intentional. MBIM devices can 453 * be disguised as NCM by default, and this is necessary to 454 * allow us to bind the correct driver_info to such devices. 455 * 456 * bind() will sort out this for us, selecting the correct 457 * entry and reject the other 458 */ 459 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), 460 .driver_info = (unsigned long)&cdc_mbim_info, 461 }, 462 /* ZLP conformance whitelist: All Ericsson MBIM devices */ 463 { USB_VENDOR_AND_INTERFACE_INFO(0x0bdb, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), 464 .driver_info = (unsigned long)&cdc_mbim_info, 465 }, 466 /* default entry */ 467 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), 468 .driver_info = (unsigned long)&cdc_mbim_info_zlp, 469 }, 470 { 471 }, 472 }; 473 MODULE_DEVICE_TABLE(usb, mbim_devs); 474 475 static struct usb_driver cdc_mbim_driver = { 476 .name = "cdc_mbim", 477 .id_table = mbim_devs, 478 .probe = usbnet_probe, 479 .disconnect = usbnet_disconnect, 480 .suspend = cdc_mbim_suspend, 481 .resume = cdc_mbim_resume, 482 .reset_resume = cdc_mbim_resume, 483 .supports_autosuspend = 1, 484 .disable_hub_initiated_lpm = 1, 485 }; 486 module_usb_driver(cdc_mbim_driver); 487 488 MODULE_AUTHOR("Greg Suarez <gsuarez@smithmicro.com>"); 489 MODULE_AUTHOR("Bjørn Mork <bjorn@mork.no>"); 490 MODULE_DESCRIPTION("USB CDC MBIM host driver"); 491 MODULE_LICENSE("GPL"); 492