1 /* $OpenBSD: if_umb.c,v 1.46 2021/07/04 19:22:31 sthen Exp $ */ 2 3 /* 4 * Copyright (c) 2016 genua mbH 5 * All rights reserved. 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* 21 * Mobile Broadband Interface Model specification: 22 * https://www.usb.org/sites/default/files/MBIM10Errata1_073013.zip 23 * Compliance testing guide 24 * https://www.usb.org/sites/default/files/MBIM-Compliance-1.0.pdf 25 */ 26 #include "bpfilter.h" 27 28 #include <sys/param.h> 29 #include <sys/mbuf.h> 30 #include <sys/socket.h> 31 #include <sys/systm.h> 32 #include <sys/syslog.h> 33 34 #if NBPFILTER > 0 35 #include <net/bpf.h> 36 #endif 37 #include <net/if.h> 38 #include <net/if_var.h> 39 #include <net/if_types.h> 40 #include <net/route.h> 41 42 #include <netinet/in.h> 43 #include <netinet/in_var.h> 44 #include <netinet/ip.h> 45 46 #ifdef INET6 47 #include <netinet/ip6.h> 48 #include <netinet6/in6_var.h> 49 #include <netinet6/ip6_var.h> 50 #include <netinet6/in6_ifattach.h> 51 #include <netinet6/nd6.h> 52 #endif 53 54 #include <machine/bus.h> 55 56 #include <dev/usb/usb.h> 57 #include <dev/usb/usbdi.h> 58 #include <dev/usb/usbdivar.h> 59 #include <dev/usb/usbdi_util.h> 60 #include <dev/usb/usbdevs.h> 61 #include <dev/usb/usbcdc.h> 62 63 #include <dev/usb/mbim.h> 64 #include <dev/usb/if_umb.h> 65 66 #ifdef UMB_DEBUG 67 #define DPRINTF(x...) \ 68 do { if (umb_debug) log(LOG_DEBUG, x); } while (0) 69 70 #define DPRINTFN(n, x...) \ 71 do { if (umb_debug >= (n)) log(LOG_DEBUG, x); } while (0) 72 73 #define DDUMPN(n, b, l) \ 74 do { \ 75 if (umb_debug >= (n)) \ 76 umb_dump((b), (l)); \ 77 } while (0) 78 79 int umb_debug = 0; 80 char *umb_uuid2str(uint8_t [MBIM_UUID_LEN]); 81 void umb_dump(void *, int); 82 83 #else 84 #define DPRINTF(x...) do { } while (0) 85 #define DPRINTFN(n, x...) do { } while (0) 86 #define DDUMPN(n, b, l) do { } while (0) 87 #endif 88 89 #define DEVNAM(sc) (((struct umb_softc *)(sc))->sc_dev.dv_xname) 90 91 /* 92 * State change timeout 93 */ 94 #define UMB_STATE_CHANGE_TIMEOUT 30 95 96 /* 97 * State change flags 98 */ 99 #define UMB_NS_DONT_DROP 0x0001 /* do not drop below current state */ 100 #define UMB_NS_DONT_RAISE 0x0002 /* do not raise below current state */ 101 102 /* 103 * Diagnostic macros 104 */ 105 const struct umb_valdescr umb_regstates[] = MBIM_REGSTATE_DESCRIPTIONS; 106 const struct umb_valdescr umb_dataclasses[] = MBIM_DATACLASS_DESCRIPTIONS; 107 const struct umb_valdescr umb_simstate[] = MBIM_SIMSTATE_DESCRIPTIONS; 108 const struct umb_valdescr umb_messages[] = MBIM_MESSAGES_DESCRIPTIONS; 109 const struct umb_valdescr umb_status[] = MBIM_STATUS_DESCRIPTIONS; 110 const struct umb_valdescr umb_cids[] = MBIM_CID_DESCRIPTIONS; 111 const struct umb_valdescr umb_pktstate[] = MBIM_PKTSRV_STATE_DESCRIPTIONS; 112 const struct umb_valdescr umb_actstate[] = MBIM_ACTIVATION_STATE_DESCRIPTIONS; 113 const struct umb_valdescr umb_error[] = MBIM_ERROR_DESCRIPTIONS; 114 const struct umb_valdescr umb_pintype[] = MBIM_PINTYPE_DESCRIPTIONS; 115 const struct umb_valdescr umb_istate[] = UMB_INTERNAL_STATE_DESCRIPTIONS; 116 117 #define umb_regstate(c) umb_val2descr(umb_regstates, (c)) 118 #define umb_dataclass(c) umb_val2descr(umb_dataclasses, (c)) 119 #define umb_simstate(s) umb_val2descr(umb_simstate, (s)) 120 #define umb_request2str(m) umb_val2descr(umb_messages, (m)) 121 #define umb_status2str(s) umb_val2descr(umb_status, (s)) 122 #define umb_cid2str(c) umb_val2descr(umb_cids, (c)) 123 #define umb_packet_state(s) umb_val2descr(umb_pktstate, (s)) 124 #define umb_activation(s) umb_val2descr(umb_actstate, (s)) 125 #define umb_error2str(e) umb_val2descr(umb_error, (e)) 126 #define umb_pin_type(t) umb_val2descr(umb_pintype, (t)) 127 #define umb_istate(s) umb_val2descr(umb_istate, (s)) 128 129 int umb_match(struct device *, void *, void *); 130 void umb_attach(struct device *, struct device *, void *); 131 int umb_detach(struct device *, int); 132 void umb_ncm_setup(struct umb_softc *); 133 void umb_ncm_setup_format(struct umb_softc *); 134 int umb_alloc_xfers(struct umb_softc *); 135 void umb_free_xfers(struct umb_softc *); 136 int umb_alloc_bulkpipes(struct umb_softc *); 137 void umb_close_bulkpipes(struct umb_softc *); 138 int umb_ioctl(struct ifnet *, u_long, caddr_t); 139 int umb_output(struct ifnet *, struct mbuf *, struct sockaddr *, 140 struct rtentry *); 141 void umb_input(struct ifnet *, struct mbuf *); 142 void umb_start(struct ifnet *); 143 void umb_rtrequest(struct ifnet *, int, struct rtentry *); 144 void umb_watchdog(struct ifnet *); 145 void umb_statechg_timeout(void *); 146 147 void umb_newstate(struct umb_softc *, enum umb_state, int); 148 void umb_state_task(void *); 149 void umb_up(struct umb_softc *); 150 void umb_down(struct umb_softc *, int); 151 152 void umb_get_response_task(void *); 153 154 void umb_decode_response(struct umb_softc *, void *, int); 155 void umb_handle_indicate_status_msg(struct umb_softc *, void *, 156 int); 157 void umb_handle_opendone_msg(struct umb_softc *, void *, int); 158 void umb_handle_closedone_msg(struct umb_softc *, void *, int); 159 int umb_decode_register_state(struct umb_softc *, void *, int); 160 int umb_decode_devices_caps(struct umb_softc *, void *, int); 161 int umb_decode_subscriber_status(struct umb_softc *, void *, int); 162 int umb_decode_radio_state(struct umb_softc *, void *, int); 163 int umb_decode_pin(struct umb_softc *, void *, int); 164 int umb_decode_packet_service(struct umb_softc *, void *, int); 165 int umb_decode_signal_state(struct umb_softc *, void *, int); 166 int umb_decode_connect_info(struct umb_softc *, void *, int); 167 void umb_clear_addr(struct umb_softc *); 168 int umb_add_inet_config(struct umb_softc *, struct in_addr, u_int, 169 struct in_addr); 170 int umb_add_inet6_config(struct umb_softc *, struct in6_addr *, 171 u_int, struct in6_addr *); 172 void umb_send_inet_proposal(struct umb_softc *, int); 173 int umb_decode_ip_configuration(struct umb_softc *, void *, int); 174 void umb_rx(struct umb_softc *); 175 void umb_rxeof(struct usbd_xfer *, void *, usbd_status); 176 int umb_encap(struct umb_softc *, int); 177 void umb_txeof(struct usbd_xfer *, void *, usbd_status); 178 void umb_decap(struct umb_softc *, struct usbd_xfer *); 179 180 usbd_status umb_send_encap_command(struct umb_softc *, void *, int); 181 int umb_get_encap_response(struct umb_softc *, void *, int *); 182 void umb_ctrl_msg(struct umb_softc *, uint32_t, void *, int); 183 184 void umb_open(struct umb_softc *); 185 void umb_close(struct umb_softc *); 186 187 int umb_setpin(struct umb_softc *, int, int, void *, int, void *, 188 int); 189 void umb_setdataclass(struct umb_softc *); 190 void umb_radio(struct umb_softc *, int); 191 void umb_allocate_cid(struct umb_softc *); 192 void umb_send_fcc_auth(struct umb_softc *); 193 void umb_packet_service(struct umb_softc *, int); 194 void umb_connect(struct umb_softc *); 195 void umb_disconnect(struct umb_softc *); 196 void umb_send_connect(struct umb_softc *, int); 197 198 void umb_qry_ipconfig(struct umb_softc *); 199 void umb_cmd(struct umb_softc *, int, int, void *, int); 200 void umb_cmd1(struct umb_softc *, int, int, void *, int, uint8_t *); 201 void umb_command_done(struct umb_softc *, void *, int); 202 void umb_decode_cid(struct umb_softc *, uint32_t, void *, int); 203 void umb_decode_qmi(struct umb_softc *, uint8_t *, int); 204 205 void umb_intr(struct usbd_xfer *, void *, usbd_status); 206 207 int umb_xfer_tout = USBD_DEFAULT_TIMEOUT; 208 209 uint8_t umb_uuid_basic_connect[] = MBIM_UUID_BASIC_CONNECT; 210 uint8_t umb_uuid_context_internet[] = MBIM_UUID_CONTEXT_INTERNET; 211 uint8_t umb_uuid_qmi_mbim[] = MBIM_UUID_QMI_MBIM; 212 uint32_t umb_session_id = 0; 213 214 struct cfdriver umb_cd = { 215 NULL, "umb", DV_IFNET 216 }; 217 218 const struct cfattach umb_ca = { 219 sizeof (struct umb_softc), 220 umb_match, 221 umb_attach, 222 umb_detach, 223 NULL, 224 }; 225 226 int umb_delay = 4000; 227 228 struct umb_quirk { 229 struct usb_devno dev; 230 u_int32_t umb_flags; 231 int umb_confno; 232 int umb_match; 233 }; 234 const struct umb_quirk umb_quirks[] = { 235 { { USB_VENDOR_DELL, USB_PRODUCT_DELL_DW5821E }, 236 0, 237 2, 238 UMATCH_VENDOR_PRODUCT 239 }, 240 241 { { USB_VENDOR_QUECTEL, USB_PRODUCT_QUECTEL_EC25 }, 242 0, 243 1, 244 UMATCH_VENDOR_PRODUCT 245 }, 246 247 248 { { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_ME906S }, 249 UMBFLG_NDP_AT_END, 250 3, 251 UMATCH_VENDOR_PRODUCT 252 }, 253 254 { { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM7455 }, 255 UMBFLG_FCC_AUTH_REQUIRED, 256 0, 257 0 258 }, 259 }; 260 261 #define umb_lookup(vid, pid) \ 262 ((const struct umb_quirk *)usb_lookup(umb_quirks, vid, pid)) 263 264 uint8_t umb_qmi_alloc_cid[] = { 265 0x01, 266 0x0f, 0x00, /* len */ 267 0x00, /* QMUX flags */ 268 0x00, /* service "ctl" */ 269 0x00, /* CID */ 270 0x00, /* QMI flags */ 271 0x01, /* transaction */ 272 0x22, 0x00, /* msg "Allocate CID" */ 273 0x04, 0x00, /* TLV len */ 274 0x01, 0x01, 0x00, 0x02 /* TLV */ 275 }; 276 277 uint8_t umb_qmi_fcc_auth[] = { 278 0x01, 279 0x0c, 0x00, /* len */ 280 0x00, /* QMUX flags */ 281 0x02, /* service "dms" */ 282 #define UMB_QMI_CID_OFFS 5 283 0x00, /* CID (filled in later) */ 284 0x00, /* QMI flags */ 285 0x01, 0x00, /* transaction */ 286 0x5f, 0x55, /* msg "Send FCC Authentication" */ 287 0x00, 0x00 /* TLV len */ 288 }; 289 290 int 291 umb_match(struct device *parent, void *match, void *aux) 292 { 293 struct usb_attach_arg *uaa = aux; 294 const struct umb_quirk *quirk; 295 usb_interface_descriptor_t *id; 296 297 quirk = umb_lookup(uaa->vendor, uaa->product); 298 if (quirk != NULL && quirk->umb_match) 299 return (quirk->umb_match); 300 if (!uaa->iface) 301 return UMATCH_NONE; 302 if ((id = usbd_get_interface_descriptor(uaa->iface)) == NULL) 303 return UMATCH_NONE; 304 305 /* 306 * If this function implements NCM, check if alternate setting 307 * 1 implements MBIM. 308 */ 309 if (id->bInterfaceClass == UICLASS_CDC && 310 id->bInterfaceSubClass == 311 UISUBCLASS_NETWORK_CONTROL_MODEL) 312 id = usbd_find_idesc(uaa->device->cdesc, uaa->iface->index, 1); 313 if (id == NULL) 314 return UMATCH_NONE; 315 316 if (id->bInterfaceClass == UICLASS_CDC && 317 id->bInterfaceSubClass == 318 UISUBCLASS_MOBILE_BROADBAND_INTERFACE_MODEL && 319 id->bInterfaceProtocol == 0) 320 return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO; 321 322 return UMATCH_NONE; 323 } 324 325 void 326 umb_attach(struct device *parent, struct device *self, void *aux) 327 { 328 struct umb_softc *sc = (struct umb_softc *)self; 329 struct usb_attach_arg *uaa = aux; 330 const struct umb_quirk *quirk; 331 usbd_status status; 332 struct usbd_desc_iter iter; 333 const usb_descriptor_t *desc; 334 int v; 335 struct usb_cdc_union_descriptor *ud; 336 struct mbim_descriptor *md; 337 int i; 338 int ctrl_ep; 339 usb_interface_descriptor_t *id; 340 usb_config_descriptor_t *cd; 341 usb_endpoint_descriptor_t *ed; 342 usb_interface_assoc_descriptor_t *ad; 343 int current_ifaceno = -1; 344 int data_ifaceno = -1; 345 int altnum; 346 int s; 347 struct ifnet *ifp; 348 349 sc->sc_udev = uaa->device; 350 sc->sc_ctrl_ifaceno = uaa->ifaceno; 351 ml_init(&sc->sc_tx_ml); 352 353 quirk = umb_lookup(uaa->vendor, uaa->product); 354 if (quirk != NULL && quirk->umb_flags) { 355 DPRINTF("%s: setting flags 0x%x from quirk\n", DEVNAM(sc), 356 quirk->umb_flags); 357 sc->sc_flags |= quirk->umb_flags; 358 } 359 360 /* 361 * Normally, MBIM devices are detected by their interface class and 362 * subclass. But for some models that have multiple configurations, it 363 * is better to match by vendor and product id so that we can select 364 * the desired configuration ourselves, e.g. to override a class-based 365 * match to another driver. 366 */ 367 if (uaa->configno < 0) { 368 if (quirk == NULL) { 369 printf("%s: unknown configuration for vid/pid match\n", 370 DEVNAM(sc)); 371 goto fail; 372 } 373 uaa->configno = quirk->umb_confno; 374 DPRINTF("%s: switching to config #%d\n", DEVNAM(sc), 375 uaa->configno); 376 status = usbd_set_config_no(sc->sc_udev, uaa->configno, 1); 377 if (status) { 378 printf("%s: failed to switch to config #%d: %s\n", 379 DEVNAM(sc), uaa->configno, usbd_errstr(status)); 380 goto fail; 381 } 382 usbd_delay_ms(sc->sc_udev, 200); 383 384 /* 385 * Need to do some manual setup that usbd_probe_and_attach() 386 * would do for us otherwise. 387 */ 388 uaa->nifaces = uaa->device->cdesc->bNumInterfaces; 389 for (i = 0; i < uaa->nifaces; i++) { 390 if (usbd_iface_claimed(sc->sc_udev, i)) 391 continue; 392 id = usbd_get_interface_descriptor(&uaa->device->ifaces[i]); 393 if (id != NULL && id->bInterfaceClass == UICLASS_CDC && 394 id->bInterfaceSubClass == 395 UISUBCLASS_MOBILE_BROADBAND_INTERFACE_MODEL) { 396 uaa->iface = &uaa->device->ifaces[i]; 397 uaa->ifaceno = uaa->iface->idesc->bInterfaceNumber; 398 sc->sc_ctrl_ifaceno = uaa->ifaceno; 399 break; 400 } 401 } 402 } 403 404 /* 405 * Some MBIM hardware does not provide the mandatory CDC Union 406 * Descriptor, so we also look at matching Interface 407 * Association Descriptors to find out the MBIM Data Interface 408 * number. 409 */ 410 sc->sc_ver_maj = sc->sc_ver_min = -1; 411 sc->sc_maxpktlen = MBIM_MAXSEGSZ_MINVAL; 412 usbd_desc_iter_init(sc->sc_udev, &iter); 413 while ((desc = usbd_desc_iter_next(&iter))) { 414 if (desc->bDescriptorType == UDESC_IFACE_ASSOC) { 415 ad = (usb_interface_assoc_descriptor_t *)desc; 416 if (ad->bFirstInterface == uaa->ifaceno && 417 ad->bInterfaceCount > 1) 418 data_ifaceno = uaa->ifaceno + 1; 419 continue; 420 } 421 if (desc->bDescriptorType == UDESC_INTERFACE) { 422 id = (usb_interface_descriptor_t *)desc; 423 current_ifaceno = id->bInterfaceNumber; 424 continue; 425 } 426 if (current_ifaceno != uaa->ifaceno) 427 continue; 428 if (desc->bDescriptorType != UDESC_CS_INTERFACE) 429 continue; 430 switch (desc->bDescriptorSubtype) { 431 case UDESCSUB_CDC_UNION: 432 ud = (struct usb_cdc_union_descriptor *)desc; 433 data_ifaceno = ud->bSlaveInterface[0]; 434 break; 435 case UDESCSUB_MBIM: 436 md = (struct mbim_descriptor *)desc; 437 v = UGETW(md->bcdMBIMVersion); 438 sc->sc_ver_maj = MBIM_VER_MAJOR(v); 439 sc->sc_ver_min = MBIM_VER_MINOR(v); 440 sc->sc_ctrl_len = UGETW(md->wMaxControlMessage); 441 /* Never trust a USB device! Could try to exploit us */ 442 if (sc->sc_ctrl_len < MBIM_CTRLMSG_MINLEN || 443 sc->sc_ctrl_len > MBIM_CTRLMSG_MAXLEN) { 444 DPRINTF("%s: control message len %d out of " 445 "bounds [%d .. %d]\n", DEVNAM(sc), 446 sc->sc_ctrl_len, MBIM_CTRLMSG_MINLEN, 447 MBIM_CTRLMSG_MAXLEN); 448 /* cont. anyway */ 449 } 450 sc->sc_maxpktlen = UGETW(md->wMaxSegmentSize); 451 DPRINTFN(2, "%s: ctrl_len=%d, maxpktlen=%d, cap=0x%x\n", 452 DEVNAM(sc), sc->sc_ctrl_len, sc->sc_maxpktlen, 453 md->bmNetworkCapabilities); 454 break; 455 default: 456 break; 457 } 458 } 459 if (sc->sc_ver_maj < 0) { 460 printf("%s: missing MBIM descriptor\n", DEVNAM(sc)); 461 goto fail; 462 } 463 if (sc->sc_flags & UMBFLG_FCC_AUTH_REQUIRED) 464 sc->sc_cid = -1; 465 466 for (i = 0; i < uaa->nifaces; i++) { 467 if (usbd_iface_claimed(sc->sc_udev, i)) 468 continue; 469 id = usbd_get_interface_descriptor(&sc->sc_udev->ifaces[i]); 470 if (id != NULL && id->bInterfaceNumber == data_ifaceno) { 471 sc->sc_data_iface = &sc->sc_udev->ifaces[i]; 472 usbd_claim_iface(sc->sc_udev, i); 473 } 474 } 475 if (sc->sc_data_iface == NULL) { 476 printf("%s: no data interface found\n", DEVNAM(sc)); 477 goto fail; 478 } 479 480 /* 481 * If this is a combined NCM/MBIM function, switch to 482 * alternate setting one to enable MBIM. 483 */ 484 id = usbd_get_interface_descriptor(uaa->iface); 485 if (id->bInterfaceClass == UICLASS_CDC && 486 id->bInterfaceSubClass == 487 UISUBCLASS_NETWORK_CONTROL_MODEL) 488 usbd_set_interface(uaa->iface, 1); 489 490 id = usbd_get_interface_descriptor(uaa->iface); 491 ctrl_ep = -1; 492 for (i = 0; i < id->bNumEndpoints && ctrl_ep == -1; i++) { 493 ed = usbd_interface2endpoint_descriptor(uaa->iface, i); 494 if (ed == NULL) 495 break; 496 if (UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT && 497 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) 498 ctrl_ep = ed->bEndpointAddress; 499 } 500 if (ctrl_ep == -1) { 501 printf("%s: missing interrupt endpoint\n", DEVNAM(sc)); 502 goto fail; 503 } 504 505 /* 506 * For the MBIM Data Interface, select the appropriate 507 * alternate setting by looking for a matching descriptor that 508 * has two endpoints. 509 */ 510 cd = usbd_get_config_descriptor(sc->sc_udev); 511 altnum = usbd_get_no_alts(cd, data_ifaceno); 512 for (i = 0; i < altnum; i++) { 513 id = usbd_find_idesc(cd, sc->sc_data_iface->index, i); 514 if (id == NULL) 515 continue; 516 if (id->bInterfaceClass == UICLASS_CDC_DATA && 517 id->bInterfaceSubClass == UISUBCLASS_DATA && 518 id->bInterfaceProtocol == UIPROTO_DATA_MBIM && 519 id->bNumEndpoints == 2) 520 break; 521 } 522 if (i == altnum || id == NULL) { 523 printf("%s: missing alt setting for interface #%d\n", 524 DEVNAM(sc), data_ifaceno); 525 goto fail; 526 } 527 status = usbd_set_interface(sc->sc_data_iface, i); 528 if (status) { 529 printf("%s: select alt setting %d for interface #%d " 530 "failed: %s\n", DEVNAM(sc), i, data_ifaceno, 531 usbd_errstr(status)); 532 goto fail; 533 } 534 535 id = usbd_get_interface_descriptor(sc->sc_data_iface); 536 sc->sc_rx_ep = sc->sc_tx_ep = -1; 537 for (i = 0; i < id->bNumEndpoints; i++) { 538 if ((ed = usbd_interface2endpoint_descriptor(sc->sc_data_iface, 539 i)) == NULL) 540 break; 541 if (UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK && 542 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) 543 sc->sc_rx_ep = ed->bEndpointAddress; 544 else if (UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK && 545 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) 546 sc->sc_tx_ep = ed->bEndpointAddress; 547 } 548 if (sc->sc_rx_ep == -1 || sc->sc_tx_ep == -1) { 549 printf("%s: missing bulk endpoints\n", DEVNAM(sc)); 550 goto fail; 551 } 552 553 DPRINTFN(2, "%s: ctrl-ifno#%d: ep-ctrl=%d, data-ifno#%d: ep-rx=%d, " 554 "ep-tx=%d\n", DEVNAM(sc), sc->sc_ctrl_ifaceno, 555 UE_GET_ADDR(ctrl_ep), data_ifaceno, 556 UE_GET_ADDR(sc->sc_rx_ep), UE_GET_ADDR(sc->sc_tx_ep)); 557 558 usb_init_task(&sc->sc_umb_task, umb_state_task, sc, 559 USB_TASK_TYPE_GENERIC); 560 usb_init_task(&sc->sc_get_response_task, umb_get_response_task, sc, 561 USB_TASK_TYPE_GENERIC); 562 timeout_set(&sc->sc_statechg_timer, umb_statechg_timeout, sc); 563 564 if (usbd_open_pipe_intr(uaa->iface, ctrl_ep, USBD_SHORT_XFER_OK, 565 &sc->sc_ctrl_pipe, sc, &sc->sc_intr_msg, sizeof (sc->sc_intr_msg), 566 umb_intr, USBD_DEFAULT_INTERVAL)) { 567 printf("%s: failed to open control pipe\n", DEVNAM(sc)); 568 goto fail; 569 } 570 sc->sc_resp_buf = malloc(sc->sc_ctrl_len, M_USBDEV, M_NOWAIT); 571 if (sc->sc_resp_buf == NULL) { 572 printf("%s: allocation of resp buffer failed\n", DEVNAM(sc)); 573 goto fail; 574 } 575 sc->sc_ctrl_msg = malloc(sc->sc_ctrl_len, M_USBDEV, M_NOWAIT); 576 if (sc->sc_ctrl_msg == NULL) { 577 printf("%s: allocation of ctrl msg buffer failed\n", 578 DEVNAM(sc)); 579 goto fail; 580 } 581 582 sc->sc_info.regstate = MBIM_REGSTATE_UNKNOWN; 583 sc->sc_info.pin_attempts_left = UMB_VALUE_UNKNOWN; 584 sc->sc_info.rssi = UMB_VALUE_UNKNOWN; 585 sc->sc_info.ber = UMB_VALUE_UNKNOWN; 586 587 /* Default to 16 bit NTB format. */ 588 sc->sc_ncm_format = NCM_FORMAT_NTB16; 589 umb_ncm_setup(sc); 590 umb_ncm_setup_format(sc); 591 if (sc->sc_ncm_supported_formats == 0) 592 goto fail; 593 DPRINTFN(2, "%s: rx/tx size %d/%d\n", DEVNAM(sc), 594 sc->sc_rx_bufsz, sc->sc_tx_bufsz); 595 596 s = splnet(); 597 ifp = GET_IFP(sc); 598 ifp->if_flags = IFF_SIMPLEX | IFF_MULTICAST | IFF_POINTOPOINT; 599 ifp->if_ioctl = umb_ioctl; 600 ifp->if_start = umb_start; 601 ifp->if_rtrequest = umb_rtrequest; 602 603 ifp->if_watchdog = umb_watchdog; 604 strlcpy(ifp->if_xname, DEVNAM(sc), IFNAMSIZ); 605 ifp->if_link_state = LINK_STATE_DOWN; 606 607 ifp->if_type = IFT_MBIM; 608 ifp->if_priority = IF_WWAN_DEFAULT_PRIORITY; 609 ifp->if_addrlen = 0; 610 ifp->if_hdrlen = sizeof (struct ncm_header16) + 611 sizeof (struct ncm_pointer16); 612 ifp->if_mtu = 1500; /* use a common default */ 613 ifp->if_hardmtu = sc->sc_maxpktlen; 614 ifp->if_input = umb_input; 615 ifp->if_output = umb_output; 616 if_attach(ifp); 617 if_alloc_sadl(ifp); 618 ifp->if_softc = sc; 619 #if NBPFILTER > 0 620 bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(uint32_t)); 621 #endif 622 /* 623 * Open the device now so that we are able to query device information. 624 * XXX maybe close when done? 625 */ 626 umb_open(sc); 627 splx(s); 628 629 DPRINTF("%s: vers %d.%d\n", DEVNAM(sc), sc->sc_ver_maj, sc->sc_ver_min); 630 return; 631 632 fail: 633 usbd_deactivate(sc->sc_udev); 634 return; 635 } 636 637 int 638 umb_detach(struct device *self, int flags) 639 { 640 struct umb_softc *sc = (struct umb_softc *)self; 641 struct ifnet *ifp = GET_IFP(sc); 642 int s; 643 644 s = splnet(); 645 if (ifp->if_flags & IFF_RUNNING) 646 umb_down(sc, 1); 647 umb_close(sc); 648 649 usb_rem_wait_task(sc->sc_udev, &sc->sc_get_response_task); 650 if (timeout_initialized(&sc->sc_statechg_timer)) 651 timeout_del(&sc->sc_statechg_timer); 652 sc->sc_nresp = 0; 653 usb_rem_wait_task(sc->sc_udev, &sc->sc_umb_task); 654 if (sc->sc_ctrl_pipe) { 655 usbd_close_pipe(sc->sc_ctrl_pipe); 656 sc->sc_ctrl_pipe = NULL; 657 } 658 if (sc->sc_ctrl_msg) { 659 free(sc->sc_ctrl_msg, M_USBDEV, sc->sc_ctrl_len); 660 sc->sc_ctrl_msg = NULL; 661 } 662 if (sc->sc_resp_buf) { 663 free(sc->sc_resp_buf, M_USBDEV, sc->sc_ctrl_len); 664 sc->sc_resp_buf = NULL; 665 } 666 if (ifp->if_softc != NULL) { 667 if_detach(ifp); 668 } 669 670 splx(s); 671 return 0; 672 } 673 674 void 675 umb_ncm_setup(struct umb_softc *sc) 676 { 677 usb_device_request_t req; 678 struct ncm_ntb_parameters np; 679 680 /* Query NTB transfer sizes */ 681 req.bmRequestType = UT_READ_CLASS_INTERFACE; 682 req.bRequest = NCM_GET_NTB_PARAMETERS; 683 USETW(req.wValue, 0); 684 USETW(req.wIndex, sc->sc_ctrl_ifaceno); 685 USETW(req.wLength, sizeof (np)); 686 if (usbd_do_request(sc->sc_udev, &req, &np) == USBD_NORMAL_COMPLETION && 687 UGETW(np.wLength) == sizeof (np)) { 688 sc->sc_rx_bufsz = UGETDW(np.dwNtbInMaxSize); 689 sc->sc_tx_bufsz = UGETDW(np.dwNtbOutMaxSize); 690 sc->sc_maxdgram = UGETW(np.wNtbOutMaxDatagrams); 691 sc->sc_align = UGETW(np.wNdpOutAlignment); 692 sc->sc_ndp_div = UGETW(np.wNdpOutDivisor); 693 sc->sc_ndp_remainder = UGETW(np.wNdpOutPayloadRemainder); 694 /* Validate values */ 695 if (!powerof2(sc->sc_align) || sc->sc_align == 0 || 696 sc->sc_align >= sc->sc_tx_bufsz) 697 sc->sc_align = sizeof (uint32_t); 698 if (!powerof2(sc->sc_ndp_div) || sc->sc_ndp_div == 0 || 699 sc->sc_ndp_div >= sc->sc_tx_bufsz) 700 sc->sc_ndp_div = sizeof (uint32_t); 701 if (sc->sc_ndp_remainder >= sc->sc_ndp_div) 702 sc->sc_ndp_remainder = 0; 703 DPRINTF("%s: NCM align=%d div=%d rem=%d\n", DEVNAM(sc), 704 sc->sc_align, sc->sc_ndp_div, sc->sc_ndp_remainder); 705 sc->sc_ncm_supported_formats = UGETW(np.bmNtbFormatsSupported); 706 } else { 707 sc->sc_rx_bufsz = sc->sc_tx_bufsz = 8 * 1024; 708 sc->sc_maxdgram = 0; 709 sc->sc_align = sc->sc_ndp_div = sizeof (uint32_t); 710 sc->sc_ndp_remainder = 0; 711 DPRINTF("%s: align=default div=default rem=default\n", 712 DEVNAM(sc)); 713 sc->sc_ncm_supported_formats = NCM_FORMAT_NTB16_MASK; 714 } 715 } 716 717 void 718 umb_ncm_setup_format(struct umb_softc *sc) 719 { 720 usb_device_request_t req; 721 uWord wFmt; 722 uint16_t fmt; 723 724 assertwaitok(); 725 if (sc->sc_ncm_supported_formats == 0) 726 goto fail; 727 728 /* NCM_GET_NTB_FORMAT is not allowed for 16-bit only devices. */ 729 if (sc->sc_ncm_supported_formats == NCM_FORMAT_NTB16_MASK) { 730 DPRINTF("%s: Only NTB16 format supported.\n", DEVNAM(sc)); 731 sc->sc_ncm_format = NCM_FORMAT_NTB16; 732 return; 733 } 734 735 /* Query NTB FORMAT (16 vs. 32 bit) */ 736 req.bmRequestType = UT_READ_CLASS_INTERFACE; 737 req.bRequest = NCM_GET_NTB_FORMAT; 738 USETW(req.wValue, 0); 739 USETW(req.wIndex, sc->sc_ctrl_ifaceno); 740 USETW(req.wLength, sizeof (wFmt)); 741 if (usbd_do_request(sc->sc_udev, &req, wFmt) != USBD_NORMAL_COMPLETION) 742 goto fail; 743 fmt = UGETW(wFmt); 744 if ((sc->sc_ncm_supported_formats & (1UL << fmt)) == 0) 745 goto fail; 746 if (fmt != NCM_FORMAT_NTB16 && fmt != NCM_FORMAT_NTB32) 747 goto fail; 748 sc->sc_ncm_format = fmt; 749 750 DPRINTF("%s: Using NCM format %d, supported=0x%x\n", 751 DEVNAM(sc), sc->sc_ncm_format, sc->sc_ncm_supported_formats); 752 return; 753 754 fail: 755 DPRINTF("%s: Cannot setup NCM format\n", DEVNAM(sc)); 756 sc->sc_ncm_supported_formats = 0; 757 } 758 759 int 760 umb_alloc_xfers(struct umb_softc *sc) 761 { 762 if (!sc->sc_rx_xfer) { 763 if ((sc->sc_rx_xfer = usbd_alloc_xfer(sc->sc_udev)) != NULL) 764 sc->sc_rx_buf = usbd_alloc_buffer(sc->sc_rx_xfer, 765 sc->sc_rx_bufsz); 766 } 767 if (!sc->sc_tx_xfer) { 768 if ((sc->sc_tx_xfer = usbd_alloc_xfer(sc->sc_udev)) != NULL) 769 sc->sc_tx_buf = usbd_alloc_buffer(sc->sc_tx_xfer, 770 sc->sc_tx_bufsz); 771 } 772 return (sc->sc_rx_buf && sc->sc_tx_buf) ? 1 : 0; 773 } 774 775 void 776 umb_free_xfers(struct umb_softc *sc) 777 { 778 if (sc->sc_rx_xfer) { 779 /* implicit usbd_free_buffer() */ 780 usbd_free_xfer(sc->sc_rx_xfer); 781 sc->sc_rx_xfer = NULL; 782 sc->sc_rx_buf = NULL; 783 } 784 if (sc->sc_tx_xfer) { 785 usbd_free_xfer(sc->sc_tx_xfer); 786 sc->sc_tx_xfer = NULL; 787 sc->sc_tx_buf = NULL; 788 } 789 ml_purge(&sc->sc_tx_ml); 790 } 791 792 int 793 umb_alloc_bulkpipes(struct umb_softc *sc) 794 { 795 struct ifnet *ifp = GET_IFP(sc); 796 797 if (!(ifp->if_flags & IFF_RUNNING)) { 798 if (usbd_open_pipe(sc->sc_data_iface, sc->sc_rx_ep, 799 USBD_EXCLUSIVE_USE, &sc->sc_rx_pipe)) 800 return 0; 801 if (usbd_open_pipe(sc->sc_data_iface, sc->sc_tx_ep, 802 USBD_EXCLUSIVE_USE, &sc->sc_tx_pipe)) 803 return 0; 804 805 ifp->if_flags |= IFF_RUNNING; 806 ifq_clr_oactive(&ifp->if_snd); 807 umb_rx(sc); 808 } 809 return 1; 810 } 811 812 void 813 umb_close_bulkpipes(struct umb_softc *sc) 814 { 815 struct ifnet *ifp = GET_IFP(sc); 816 817 ifp->if_flags &= ~IFF_RUNNING; 818 ifq_clr_oactive(&ifp->if_snd); 819 ifp->if_timer = 0; 820 if (sc->sc_rx_pipe) { 821 usbd_close_pipe(sc->sc_rx_pipe); 822 sc->sc_rx_pipe = NULL; 823 } 824 if (sc->sc_tx_pipe) { 825 usbd_close_pipe(sc->sc_tx_pipe); 826 sc->sc_tx_pipe = NULL; 827 } 828 } 829 830 int 831 umb_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 832 { 833 struct proc *p = curproc; 834 struct umb_softc *sc = ifp->if_softc; 835 struct ifreq *ifr = (struct ifreq *)data; 836 int s, error = 0; 837 struct umb_parameter mp; 838 839 if (usbd_is_dying(sc->sc_udev)) 840 return ENXIO; 841 842 s = splnet(); 843 switch (cmd) { 844 case SIOCSIFFLAGS: 845 usb_add_task(sc->sc_udev, &sc->sc_umb_task); 846 break; 847 case SIOCGUMBINFO: 848 error = copyout(&sc->sc_info, ifr->ifr_data, 849 sizeof (sc->sc_info)); 850 break; 851 case SIOCSUMBPARAM: 852 if ((error = suser(p)) != 0) 853 break; 854 if ((error = copyin(ifr->ifr_data, &mp, sizeof (mp))) != 0) 855 break; 856 857 if ((error = umb_setpin(sc, mp.op, mp.is_puk, mp.pin, mp.pinlen, 858 mp.newpin, mp.newpinlen)) != 0) 859 break; 860 861 if (mp.apnlen < 0 || mp.apnlen > sizeof (sc->sc_info.apn)) { 862 error = EINVAL; 863 break; 864 } 865 sc->sc_roaming = mp.roaming ? 1 : 0; 866 memset(sc->sc_info.apn, 0, sizeof (sc->sc_info.apn)); 867 memcpy(sc->sc_info.apn, mp.apn, mp.apnlen); 868 sc->sc_info.apnlen = mp.apnlen; 869 sc->sc_info.preferredclasses = mp.preferredclasses; 870 umb_setdataclass(sc); 871 break; 872 case SIOCGUMBPARAM: 873 memset(&mp, 0, sizeof (mp)); 874 memcpy(mp.apn, sc->sc_info.apn, sc->sc_info.apnlen); 875 mp.apnlen = sc->sc_info.apnlen; 876 mp.roaming = sc->sc_roaming; 877 mp.preferredclasses = sc->sc_info.preferredclasses; 878 error = copyout(&mp, ifr->ifr_data, sizeof (mp)); 879 break; 880 case SIOCSIFMTU: 881 /* Does this include the NCM headers and tail? */ 882 if (ifr->ifr_mtu > ifp->if_hardmtu) { 883 error = EINVAL; 884 break; 885 } 886 ifp->if_mtu = ifr->ifr_mtu; 887 break; 888 case SIOCSIFADDR: 889 case SIOCAIFADDR: 890 case SIOCSIFDSTADDR: 891 case SIOCADDMULTI: 892 case SIOCDELMULTI: 893 break; 894 default: 895 error = ENOTTY; 896 break; 897 } 898 splx(s); 899 return error; 900 } 901 902 int 903 umb_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 904 struct rtentry *rtp) 905 { 906 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) { 907 m_freem(m); 908 return ENETDOWN; 909 } 910 m->m_pkthdr.ph_family = dst->sa_family; 911 return if_enqueue(ifp, m); 912 } 913 914 void 915 umb_input(struct ifnet *ifp, struct mbuf *m) 916 { 917 uint32_t af; 918 919 if ((ifp->if_flags & IFF_UP) == 0) { 920 m_freem(m); 921 return; 922 } 923 if (m->m_pkthdr.len < sizeof (struct ip) + sizeof(af)) { 924 ifp->if_ierrors++; 925 DPRINTFN(4, "%s: dropping short packet (len %d)\n", __func__, 926 m->m_pkthdr.len); 927 m_freem(m); 928 return; 929 } 930 m->m_pkthdr.ph_rtableid = ifp->if_rdomain; 931 932 /* pop off DLT_LOOP header, no longer needed */ 933 af = *mtod(m, uint32_t *); 934 m_adj(m, sizeof (af)); 935 af = ntohl(af); 936 937 ifp->if_ibytes += m->m_pkthdr.len; 938 switch (af) { 939 case AF_INET: 940 ipv4_input(ifp, m); 941 return; 942 #ifdef INET6 943 case AF_INET6: 944 ipv6_input(ifp, m); 945 return; 946 #endif /* INET6 */ 947 default: 948 ifp->if_ierrors++; 949 DPRINTFN(4, "%s: dropping packet with bad IP version (af %d)\n", 950 __func__, af); 951 m_freem(m); 952 return; 953 } 954 } 955 956 static inline int 957 umb_align(size_t bufsz, int offs, int alignment, int remainder) 958 { 959 size_t m = alignment - 1; 960 int align; 961 962 align = (((size_t)offs + m) & ~m) - alignment + remainder; 963 if (align < offs) 964 align += alignment; 965 if (align > bufsz) 966 align = bufsz; 967 return align - offs; 968 } 969 970 static inline int 971 umb_padding(void *buf, size_t bufsz, int offs, int alignment, int remainder) 972 { 973 int nb; 974 975 nb = umb_align(bufsz, offs, alignment, remainder); 976 if (nb > 0) 977 memset(buf + offs, 0, nb); 978 return nb; 979 } 980 981 void 982 umb_start(struct ifnet *ifp) 983 { 984 struct umb_softc *sc = ifp->if_softc; 985 struct mbuf *m = NULL; 986 int ndgram = 0; 987 int offs, len, mlen; 988 int maxoverhead; 989 990 if (usbd_is_dying(sc->sc_udev) || 991 !(ifp->if_flags & IFF_RUNNING) || 992 ifq_is_oactive(&ifp->if_snd)) 993 return; 994 995 KASSERT(ml_empty(&sc->sc_tx_ml)); 996 997 switch (sc->sc_ncm_format) { 998 case NCM_FORMAT_NTB16: 999 offs = sizeof (struct ncm_header16); 1000 offs += umb_align(sc->sc_tx_bufsz, offs, sc->sc_align, 0); 1001 offs += sizeof (struct ncm_pointer16); 1002 maxoverhead = sizeof (struct ncm_pointer16_dgram); 1003 break; 1004 case NCM_FORMAT_NTB32: 1005 offs = sizeof (struct ncm_header32); 1006 offs += umb_align(sc->sc_tx_bufsz, offs, sc->sc_align, 0); 1007 offs += sizeof (struct ncm_pointer32); 1008 maxoverhead = sizeof (struct ncm_pointer32_dgram); 1009 break; 1010 default: 1011 KASSERT(0); 1012 } 1013 1014 /* 1015 * Overhead for per packet alignment plus packet pointer. Note 1016 * that 'struct ncm_pointer{16,32}' already includes space for 1017 * the terminating zero pointer. 1018 */ 1019 maxoverhead += sc->sc_ndp_div - 1; 1020 1021 len = 0; 1022 while (1) { 1023 m = ifq_deq_begin(&ifp->if_snd); 1024 if (m == NULL) 1025 break; 1026 1027 /* 1028 * Check if mbuf plus required NCM pointer still fits into 1029 * xfer buffers. Assume maximal padding. 1030 */ 1031 mlen = maxoverhead + m->m_pkthdr.len; 1032 if ((sc->sc_maxdgram != 0 && ndgram >= sc->sc_maxdgram) || 1033 (offs + len + mlen > sc->sc_tx_bufsz)) { 1034 ifq_deq_rollback(&ifp->if_snd, m); 1035 break; 1036 } 1037 ifq_deq_commit(&ifp->if_snd, m); 1038 1039 ndgram++; 1040 len += mlen; 1041 ml_enqueue(&sc->sc_tx_ml, m); 1042 1043 #if NBPFILTER > 0 1044 if (ifp->if_bpf) 1045 bpf_mtap_af(ifp->if_bpf, m->m_pkthdr.ph_family, m, 1046 BPF_DIRECTION_OUT); 1047 #endif 1048 } 1049 if (ml_empty(&sc->sc_tx_ml)) 1050 return; 1051 if (umb_encap(sc, ndgram)) { 1052 ifq_set_oactive(&ifp->if_snd); 1053 ifp->if_timer = (2 * umb_xfer_tout) / 1000; 1054 } 1055 } 1056 1057 void 1058 umb_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt) 1059 { 1060 struct umb_softc *sc = ifp->if_softc; 1061 1062 if (req == RTM_PROPOSAL) { 1063 KERNEL_LOCK(); 1064 umb_send_inet_proposal(sc, AF_INET); 1065 #ifdef INET6 1066 umb_send_inet_proposal(sc, AF_INET6); 1067 #endif 1068 KERNEL_UNLOCK(); 1069 return; 1070 } 1071 1072 p2p_rtrequest(ifp, req, rt); 1073 } 1074 1075 1076 void 1077 umb_watchdog(struct ifnet *ifp) 1078 { 1079 struct umb_softc *sc = ifp->if_softc; 1080 1081 if (usbd_is_dying(sc->sc_udev)) 1082 return; 1083 1084 ifp->if_oerrors++; 1085 printf("%s: watchdog timeout\n", DEVNAM(sc)); 1086 usbd_abort_pipe(sc->sc_tx_pipe); 1087 return; 1088 } 1089 1090 void 1091 umb_statechg_timeout(void *arg) 1092 { 1093 struct umb_softc *sc = arg; 1094 struct ifnet *ifp = GET_IFP(sc); 1095 1096 if (sc->sc_info.regstate != MBIM_REGSTATE_ROAMING || sc->sc_roaming) 1097 if (ifp->if_flags & IFF_DEBUG) 1098 log(LOG_DEBUG, "%s: state change timeout\n", 1099 DEVNAM(sc)); 1100 usb_add_task(sc->sc_udev, &sc->sc_umb_task); 1101 } 1102 1103 void 1104 umb_newstate(struct umb_softc *sc, enum umb_state newstate, int flags) 1105 { 1106 struct ifnet *ifp = GET_IFP(sc); 1107 1108 if (newstate == sc->sc_state) 1109 return; 1110 if (((flags & UMB_NS_DONT_DROP) && newstate < sc->sc_state) || 1111 ((flags & UMB_NS_DONT_RAISE) && newstate > sc->sc_state)) 1112 return; 1113 if (ifp->if_flags & IFF_DEBUG) 1114 log(LOG_DEBUG, "%s: state going %s from '%s' to '%s'\n", 1115 DEVNAM(sc), newstate > sc->sc_state ? "up" : "down", 1116 umb_istate(sc->sc_state), umb_istate(newstate)); 1117 sc->sc_state = newstate; 1118 usb_add_task(sc->sc_udev, &sc->sc_umb_task); 1119 } 1120 1121 void 1122 umb_state_task(void *arg) 1123 { 1124 struct umb_softc *sc = arg; 1125 struct ifnet *ifp = GET_IFP(sc); 1126 int s; 1127 int state; 1128 1129 if (sc->sc_info.regstate == MBIM_REGSTATE_ROAMING && !sc->sc_roaming) { 1130 /* 1131 * Query the registration state until we're with the home 1132 * network again. 1133 */ 1134 umb_cmd(sc, MBIM_CID_REGISTER_STATE, MBIM_CMDOP_QRY, NULL, 0); 1135 return; 1136 } 1137 1138 s = splnet(); 1139 if (ifp->if_flags & IFF_UP) 1140 umb_up(sc); 1141 else 1142 umb_down(sc, 0); 1143 1144 state = sc->sc_state == UMB_S_UP ? LINK_STATE_UP : LINK_STATE_DOWN; 1145 if (ifp->if_link_state != state) { 1146 if (ifp->if_flags & IFF_DEBUG) 1147 log(LOG_DEBUG, "%s: link state changed from %s to %s\n", 1148 DEVNAM(sc), 1149 LINK_STATE_IS_UP(ifp->if_link_state) 1150 ? "up" : "down", 1151 LINK_STATE_IS_UP(state) ? "up" : "down"); 1152 ifp->if_link_state = state; 1153 if_link_state_change(ifp); 1154 } 1155 splx(s); 1156 } 1157 1158 void 1159 umb_up(struct umb_softc *sc) 1160 { 1161 splassert(IPL_NET); 1162 1163 switch (sc->sc_state) { 1164 case UMB_S_DOWN: 1165 DPRINTF("%s: init: opening ...\n", DEVNAM(sc)); 1166 umb_open(sc); 1167 break; 1168 case UMB_S_OPEN: 1169 if (sc->sc_flags & UMBFLG_FCC_AUTH_REQUIRED) { 1170 if (sc->sc_cid == -1) { 1171 DPRINTF("%s: init: allocating CID ...\n", 1172 DEVNAM(sc)); 1173 umb_allocate_cid(sc); 1174 break; 1175 } else 1176 umb_newstate(sc, UMB_S_CID, UMB_NS_DONT_DROP); 1177 } else { 1178 DPRINTF("%s: init: turning radio on ...\n", DEVNAM(sc)); 1179 umb_radio(sc, 1); 1180 break; 1181 } 1182 /*FALLTHROUGH*/ 1183 case UMB_S_CID: 1184 DPRINTF("%s: init: sending FCC auth ...\n", DEVNAM(sc)); 1185 umb_send_fcc_auth(sc); 1186 break; 1187 case UMB_S_RADIO: 1188 DPRINTF("%s: init: checking SIM state ...\n", DEVNAM(sc)); 1189 umb_cmd(sc, MBIM_CID_SUBSCRIBER_READY_STATUS, MBIM_CMDOP_QRY, 1190 NULL, 0); 1191 break; 1192 case UMB_S_SIMREADY: 1193 DPRINTF("%s: init: attaching ...\n", DEVNAM(sc)); 1194 umb_packet_service(sc, 1); 1195 break; 1196 case UMB_S_ATTACHED: 1197 sc->sc_tx_seq = 0; 1198 if (!umb_alloc_xfers(sc)) { 1199 umb_free_xfers(sc); 1200 printf("%s: allocation of xfers failed\n", DEVNAM(sc)); 1201 break; 1202 } 1203 DPRINTF("%s: init: connecting ...\n", DEVNAM(sc)); 1204 umb_connect(sc); 1205 break; 1206 case UMB_S_CONNECTED: 1207 DPRINTF("%s: init: getting IP config ...\n", DEVNAM(sc)); 1208 umb_qry_ipconfig(sc); 1209 break; 1210 case UMB_S_UP: 1211 DPRINTF("%s: init: reached state UP\n", DEVNAM(sc)); 1212 if (!umb_alloc_bulkpipes(sc)) { 1213 printf("%s: opening bulk pipes failed\n", DEVNAM(sc)); 1214 umb_down(sc, 1); 1215 } 1216 break; 1217 } 1218 if (sc->sc_state < UMB_S_UP) 1219 timeout_add_sec(&sc->sc_statechg_timer, 1220 UMB_STATE_CHANGE_TIMEOUT); 1221 else 1222 timeout_del(&sc->sc_statechg_timer); 1223 return; 1224 } 1225 1226 void 1227 umb_down(struct umb_softc *sc, int force) 1228 { 1229 splassert(IPL_NET); 1230 1231 umb_close_bulkpipes(sc); 1232 if (sc->sc_state < UMB_S_CONNECTED) 1233 umb_free_xfers(sc); 1234 1235 switch (sc->sc_state) { 1236 case UMB_S_UP: 1237 umb_clear_addr(sc); 1238 /*FALLTHROUGH*/ 1239 case UMB_S_CONNECTED: 1240 DPRINTF("%s: stop: disconnecting ...\n", DEVNAM(sc)); 1241 umb_disconnect(sc); 1242 if (!force) 1243 break; 1244 /*FALLTHROUGH*/ 1245 case UMB_S_ATTACHED: 1246 DPRINTF("%s: stop: detaching ...\n", DEVNAM(sc)); 1247 umb_packet_service(sc, 0); 1248 if (!force) 1249 break; 1250 /*FALLTHROUGH*/ 1251 case UMB_S_SIMREADY: 1252 case UMB_S_RADIO: 1253 DPRINTF("%s: stop: turning radio off ...\n", DEVNAM(sc)); 1254 umb_radio(sc, 0); 1255 if (!force) 1256 break; 1257 /*FALLTHROUGH*/ 1258 case UMB_S_CID: 1259 case UMB_S_OPEN: 1260 case UMB_S_DOWN: 1261 /* Do not close the device */ 1262 DPRINTF("%s: stop: reached state DOWN\n", DEVNAM(sc)); 1263 break; 1264 } 1265 if (force) 1266 sc->sc_state = UMB_S_OPEN; 1267 1268 if (sc->sc_state > UMB_S_OPEN) 1269 timeout_add_sec(&sc->sc_statechg_timer, 1270 UMB_STATE_CHANGE_TIMEOUT); 1271 else 1272 timeout_del(&sc->sc_statechg_timer); 1273 } 1274 1275 void 1276 umb_get_response_task(void *arg) 1277 { 1278 struct umb_softc *sc = arg; 1279 int len; 1280 int s; 1281 1282 /* 1283 * Function is required to send on RESPONSE_AVAILABLE notification for 1284 * each encapsulated response that is to be processed by the host. 1285 * But of course, we can receive multiple notifications before the 1286 * response task is run. 1287 */ 1288 s = splusb(); 1289 while (sc->sc_nresp > 0) { 1290 --sc->sc_nresp; 1291 len = sc->sc_ctrl_len; 1292 if (umb_get_encap_response(sc, sc->sc_resp_buf, &len)) 1293 umb_decode_response(sc, sc->sc_resp_buf, len); 1294 } 1295 splx(s); 1296 } 1297 1298 void 1299 umb_decode_response(struct umb_softc *sc, void *response, int len) 1300 { 1301 struct mbim_msghdr *hdr = response; 1302 struct mbim_fragmented_msg_hdr *fraghdr; 1303 uint32_t type; 1304 uint32_t tid; 1305 1306 DPRINTFN(3, "%s: got response: len %d\n", DEVNAM(sc), len); 1307 DDUMPN(4, response, len); 1308 1309 if (len < sizeof (*hdr) || letoh32(hdr->len) != len) { 1310 /* 1311 * We should probably cancel a transaction, but since the 1312 * message is too short, we cannot decode the transaction 1313 * id (tid) and hence don't know, whom to cancel. Must wait 1314 * for the timeout. 1315 */ 1316 DPRINTF("%s: received short response (len %d)\n", 1317 DEVNAM(sc), len); 1318 return; 1319 } 1320 1321 /* 1322 * XXX FIXME: if message is fragmented, store it until last frag 1323 * is received and then re-assemble all fragments. 1324 */ 1325 type = letoh32(hdr->type); 1326 tid = letoh32(hdr->tid); 1327 switch (type) { 1328 case MBIM_INDICATE_STATUS_MSG: 1329 case MBIM_COMMAND_DONE: 1330 fraghdr = response; 1331 if (letoh32(fraghdr->frag.nfrag) != 1) { 1332 DPRINTF("%s: discarding fragmented messages\n", 1333 DEVNAM(sc)); 1334 return; 1335 } 1336 break; 1337 default: 1338 break; 1339 } 1340 1341 DPRINTF("%s: <- rcv %s (tid %u)\n", DEVNAM(sc), umb_request2str(type), 1342 tid); 1343 switch (type) { 1344 case MBIM_FUNCTION_ERROR_MSG: 1345 case MBIM_HOST_ERROR_MSG: 1346 { 1347 struct mbim_f2h_hosterr *e; 1348 int err; 1349 1350 if (len >= sizeof (*e)) { 1351 e = response; 1352 err = letoh32(e->err); 1353 1354 DPRINTF("%s: %s message, error %s (tid %u)\n", 1355 DEVNAM(sc), umb_request2str(type), 1356 umb_error2str(err), tid); 1357 if (err == MBIM_ERROR_NOT_OPENED) 1358 umb_newstate(sc, UMB_S_DOWN, 0); 1359 } 1360 break; 1361 } 1362 case MBIM_INDICATE_STATUS_MSG: 1363 umb_handle_indicate_status_msg(sc, response, len); 1364 break; 1365 case MBIM_OPEN_DONE: 1366 umb_handle_opendone_msg(sc, response, len); 1367 break; 1368 case MBIM_CLOSE_DONE: 1369 umb_handle_closedone_msg(sc, response, len); 1370 break; 1371 case MBIM_COMMAND_DONE: 1372 umb_command_done(sc, response, len); 1373 break; 1374 default: 1375 DPRINTF("%s: discard message %s\n", DEVNAM(sc), 1376 umb_request2str(type)); 1377 break; 1378 } 1379 } 1380 1381 void 1382 umb_handle_indicate_status_msg(struct umb_softc *sc, void *data, int len) 1383 { 1384 struct mbim_f2h_indicate_status *m = data; 1385 uint32_t infolen; 1386 uint32_t cid; 1387 1388 if (len < sizeof (*m)) { 1389 DPRINTF("%s: discard short %s message\n", DEVNAM(sc), 1390 umb_request2str(letoh32(m->hdr.type))); 1391 return; 1392 } 1393 if (memcmp(m->devid, umb_uuid_basic_connect, sizeof (m->devid))) { 1394 DPRINTF("%s: discard %s message for other UUID '%s'\n", 1395 DEVNAM(sc), umb_request2str(letoh32(m->hdr.type)), 1396 umb_uuid2str(m->devid)); 1397 return; 1398 } 1399 infolen = letoh32(m->infolen); 1400 if (len < sizeof (*m) + infolen) { 1401 DPRINTF("%s: discard truncated %s message (want %d, got %d)\n", 1402 DEVNAM(sc), umb_request2str(letoh32(m->hdr.type)), 1403 (int)sizeof (*m) + infolen, len); 1404 return; 1405 } 1406 1407 cid = letoh32(m->cid); 1408 DPRINTF("%s: indicate %s status\n", DEVNAM(sc), umb_cid2str(cid)); 1409 umb_decode_cid(sc, cid, m->info, infolen); 1410 } 1411 1412 void 1413 umb_handle_opendone_msg(struct umb_softc *sc, void *data, int len) 1414 { 1415 struct mbim_f2h_openclosedone *resp = data; 1416 struct ifnet *ifp = GET_IFP(sc); 1417 uint32_t status; 1418 1419 status = letoh32(resp->status); 1420 if (status == MBIM_STATUS_SUCCESS) { 1421 if (sc->sc_maxsessions == 0) { 1422 umb_cmd(sc, MBIM_CID_DEVICE_CAPS, MBIM_CMDOP_QRY, NULL, 1423 0); 1424 umb_cmd(sc, MBIM_CID_PIN, MBIM_CMDOP_QRY, NULL, 0); 1425 umb_cmd(sc, MBIM_CID_REGISTER_STATE, MBIM_CMDOP_QRY, 1426 NULL, 0); 1427 } 1428 umb_newstate(sc, UMB_S_OPEN, UMB_NS_DONT_DROP); 1429 } else if (ifp->if_flags & IFF_DEBUG) 1430 log(LOG_ERR, "%s: open error: %s\n", DEVNAM(sc), 1431 umb_status2str(status)); 1432 return; 1433 } 1434 1435 void 1436 umb_handle_closedone_msg(struct umb_softc *sc, void *data, int len) 1437 { 1438 struct mbim_f2h_openclosedone *resp = data; 1439 uint32_t status; 1440 1441 status = letoh32(resp->status); 1442 if (status == MBIM_STATUS_SUCCESS) 1443 umb_newstate(sc, UMB_S_DOWN, 0); 1444 else 1445 DPRINTF("%s: close error: %s\n", DEVNAM(sc), 1446 umb_status2str(status)); 1447 return; 1448 } 1449 1450 static inline void 1451 umb_getinfobuf(void *in, int inlen, uint32_t offs, uint32_t sz, 1452 void *out, size_t outlen) 1453 { 1454 offs = letoh32(offs); 1455 sz = letoh32(sz); 1456 if (inlen >= offs + sz) { 1457 memset(out, 0, outlen); 1458 memcpy(out, in + offs, MIN(sz, outlen)); 1459 } 1460 } 1461 1462 static inline int 1463 umb_addstr(void *buf, size_t bufsz, int *offs, void *str, int slen, 1464 uint32_t *offsmember, uint32_t *sizemember) 1465 { 1466 if (*offs + slen > bufsz) 1467 return 0; 1468 1469 *sizemember = htole32((uint32_t)slen); 1470 if (slen && str) { 1471 *offsmember = htole32((uint32_t)*offs); 1472 memcpy(buf + *offs, str, slen); 1473 *offs += slen; 1474 *offs += umb_padding(buf, bufsz, *offs, sizeof (uint32_t), 0); 1475 } else 1476 *offsmember = htole32(0); 1477 return 1; 1478 } 1479 1480 int 1481 umb_decode_register_state(struct umb_softc *sc, void *data, int len) 1482 { 1483 struct mbim_cid_registration_state_info *rs = data; 1484 struct ifnet *ifp = GET_IFP(sc); 1485 1486 if (len < sizeof (*rs)) 1487 return 0; 1488 sc->sc_info.nwerror = letoh32(rs->nwerror); 1489 sc->sc_info.regstate = letoh32(rs->regstate); 1490 sc->sc_info.regmode = letoh32(rs->regmode); 1491 sc->sc_info.cellclass = letoh32(rs->curcellclass); 1492 1493 umb_getinfobuf(data, len, rs->provname_offs, rs->provname_size, 1494 sc->sc_info.provider, sizeof (sc->sc_info.provider)); 1495 umb_getinfobuf(data, len, rs->provid_offs, rs->provid_size, 1496 sc->sc_info.providerid, sizeof (sc->sc_info.providerid)); 1497 umb_getinfobuf(data, len, rs->roamingtxt_offs, rs->roamingtxt_size, 1498 sc->sc_info.roamingtxt, sizeof (sc->sc_info.roamingtxt)); 1499 1500 DPRINTFN(2, "%s: %s, availclass 0x%x, class 0x%x, regmode %d\n", 1501 DEVNAM(sc), umb_regstate(sc->sc_info.regstate), 1502 letoh32(rs->availclasses), sc->sc_info.cellclass, 1503 sc->sc_info.regmode); 1504 1505 if (sc->sc_info.regstate == MBIM_REGSTATE_ROAMING && 1506 !sc->sc_roaming && 1507 sc->sc_info.activation == MBIM_ACTIVATION_STATE_ACTIVATED) { 1508 if (ifp->if_flags & IFF_DEBUG) 1509 log(LOG_INFO, 1510 "%s: disconnecting from roaming network\n", 1511 DEVNAM(sc)); 1512 umb_disconnect(sc); 1513 } 1514 return 1; 1515 } 1516 1517 int 1518 umb_decode_devices_caps(struct umb_softc *sc, void *data, int len) 1519 { 1520 struct mbim_cid_device_caps *dc = data; 1521 1522 if (len < sizeof (*dc)) 1523 return 0; 1524 sc->sc_maxsessions = letoh32(dc->max_sessions); 1525 sc->sc_info.supportedclasses = letoh32(dc->dataclass); 1526 umb_getinfobuf(data, len, dc->devid_offs, dc->devid_size, 1527 sc->sc_info.devid, sizeof (sc->sc_info.devid)); 1528 umb_getinfobuf(data, len, dc->fwinfo_offs, dc->fwinfo_size, 1529 sc->sc_info.fwinfo, sizeof (sc->sc_info.fwinfo)); 1530 umb_getinfobuf(data, len, dc->hwinfo_offs, dc->hwinfo_size, 1531 sc->sc_info.hwinfo, sizeof (sc->sc_info.hwinfo)); 1532 DPRINTFN(2, "%s: max sessions %d, supported classes 0x%x\n", 1533 DEVNAM(sc), sc->sc_maxsessions, sc->sc_info.supportedclasses); 1534 return 1; 1535 } 1536 1537 int 1538 umb_decode_subscriber_status(struct umb_softc *sc, void *data, int len) 1539 { 1540 struct mbim_cid_subscriber_ready_info *si = data; 1541 struct ifnet *ifp = GET_IFP(sc); 1542 int npn; 1543 1544 if (len < sizeof (*si)) 1545 return 0; 1546 sc->sc_info.sim_state = letoh32(si->ready); 1547 1548 umb_getinfobuf(data, len, si->sid_offs, si->sid_size, 1549 sc->sc_info.sid, sizeof (sc->sc_info.sid)); 1550 umb_getinfobuf(data, len, si->icc_offs, si->icc_size, 1551 sc->sc_info.iccid, sizeof (sc->sc_info.iccid)); 1552 1553 npn = letoh32(si->no_pn); 1554 if (npn > 0) 1555 umb_getinfobuf(data, len, si->pn[0].offs, si->pn[0].size, 1556 sc->sc_info.pn, sizeof (sc->sc_info.pn)); 1557 else 1558 memset(sc->sc_info.pn, 0, sizeof (sc->sc_info.pn)); 1559 1560 if (sc->sc_info.sim_state == MBIM_SIMSTATE_LOCKED) 1561 sc->sc_info.pin_state = UMB_PUK_REQUIRED; 1562 if (ifp->if_flags & IFF_DEBUG) 1563 log(LOG_INFO, "%s: SIM %s\n", DEVNAM(sc), 1564 umb_simstate(sc->sc_info.sim_state)); 1565 if (sc->sc_info.sim_state == MBIM_SIMSTATE_INITIALIZED) 1566 umb_newstate(sc, UMB_S_SIMREADY, UMB_NS_DONT_DROP); 1567 return 1; 1568 } 1569 1570 int 1571 umb_decode_radio_state(struct umb_softc *sc, void *data, int len) 1572 { 1573 struct mbim_cid_radio_state_info *rs = data; 1574 struct ifnet *ifp = GET_IFP(sc); 1575 1576 if (len < sizeof (*rs)) 1577 return 0; 1578 1579 sc->sc_info.hw_radio_on = 1580 (letoh32(rs->hw_state) == MBIM_RADIO_STATE_ON) ? 1 : 0; 1581 sc->sc_info.sw_radio_on = 1582 (letoh32(rs->sw_state) == MBIM_RADIO_STATE_ON) ? 1 : 0; 1583 if (!sc->sc_info.hw_radio_on) { 1584 printf("%s: radio is disabled by hardware switch\n", 1585 DEVNAM(sc)); 1586 /* 1587 * XXX do we need a time to poll the state of the rfkill switch 1588 * or will the device send an unsolicited notification 1589 * in case the state changes? 1590 */ 1591 umb_newstate(sc, UMB_S_OPEN, 0); 1592 } else if (!sc->sc_info.sw_radio_on) { 1593 if (ifp->if_flags & IFF_DEBUG) 1594 log(LOG_INFO, "%s: radio is off\n", DEVNAM(sc)); 1595 umb_newstate(sc, UMB_S_OPEN, 0); 1596 } else 1597 umb_newstate(sc, UMB_S_RADIO, UMB_NS_DONT_DROP); 1598 return 1; 1599 } 1600 1601 int 1602 umb_decode_pin(struct umb_softc *sc, void *data, int len) 1603 { 1604 struct mbim_cid_pin_info *pi = data; 1605 struct ifnet *ifp = GET_IFP(sc); 1606 uint32_t attempts_left; 1607 1608 if (len < sizeof (*pi)) 1609 return 0; 1610 1611 attempts_left = letoh32(pi->remaining_attempts); 1612 if (attempts_left != 0xffffffff) 1613 sc->sc_info.pin_attempts_left = attempts_left; 1614 1615 switch (letoh32(pi->state)) { 1616 case MBIM_PIN_STATE_UNLOCKED: 1617 sc->sc_info.pin_state = UMB_PIN_UNLOCKED; 1618 break; 1619 case MBIM_PIN_STATE_LOCKED: 1620 switch (letoh32(pi->type)) { 1621 case MBIM_PIN_TYPE_PIN1: 1622 sc->sc_info.pin_state = UMB_PIN_REQUIRED; 1623 break; 1624 case MBIM_PIN_TYPE_PUK1: 1625 sc->sc_info.pin_state = UMB_PUK_REQUIRED; 1626 break; 1627 case MBIM_PIN_TYPE_PIN2: 1628 case MBIM_PIN_TYPE_PUK2: 1629 /* Assume that PIN1 was accepted */ 1630 sc->sc_info.pin_state = UMB_PIN_UNLOCKED; 1631 break; 1632 } 1633 break; 1634 } 1635 if (ifp->if_flags & IFF_DEBUG) 1636 log(LOG_INFO, "%s: %s state %s (%d attempts left)\n", 1637 DEVNAM(sc), umb_pin_type(letoh32(pi->type)), 1638 (letoh32(pi->state) == MBIM_PIN_STATE_UNLOCKED) ? 1639 "unlocked" : "locked", 1640 letoh32(pi->remaining_attempts)); 1641 1642 /* 1643 * In case the PIN was set after IFF_UP, retrigger the state machine 1644 */ 1645 usb_add_task(sc->sc_udev, &sc->sc_umb_task); 1646 return 1; 1647 } 1648 1649 int 1650 umb_decode_packet_service(struct umb_softc *sc, void *data, int len) 1651 { 1652 struct mbim_cid_packet_service_info *psi = data; 1653 int state, highestclass; 1654 uint64_t up_speed, down_speed; 1655 struct ifnet *ifp = GET_IFP(sc); 1656 1657 if (len < sizeof (*psi)) 1658 return 0; 1659 1660 sc->sc_info.nwerror = letoh32(psi->nwerror); 1661 state = letoh32(psi->state); 1662 highestclass = letoh32(psi->highest_dataclass); 1663 up_speed = letoh64(psi->uplink_speed); 1664 down_speed = letoh64(psi->downlink_speed); 1665 if (sc->sc_info.packetstate != state || 1666 sc->sc_info.uplink_speed != up_speed || 1667 sc->sc_info.downlink_speed != down_speed) { 1668 if (ifp->if_flags & IFF_DEBUG) { 1669 log(LOG_INFO, "%s: packet service ", DEVNAM(sc)); 1670 if (sc->sc_info.packetstate != state) 1671 addlog("changed from %s to ", 1672 umb_packet_state(sc->sc_info.packetstate)); 1673 addlog("%s, class %s, speed: %llu up / %llu down\n", 1674 umb_packet_state(state), 1675 umb_dataclass(highestclass), up_speed, down_speed); 1676 } 1677 } 1678 sc->sc_info.packetstate = state; 1679 sc->sc_info.highestclass = highestclass; 1680 sc->sc_info.uplink_speed = up_speed; 1681 sc->sc_info.downlink_speed = down_speed; 1682 1683 if (sc->sc_info.regmode == MBIM_REGMODE_AUTOMATIC) { 1684 /* 1685 * For devices using automatic registration mode, just proceed, 1686 * once registration has completed. 1687 */ 1688 if (ifp->if_flags & IFF_UP) { 1689 switch (sc->sc_info.regstate) { 1690 case MBIM_REGSTATE_HOME: 1691 case MBIM_REGSTATE_ROAMING: 1692 case MBIM_REGSTATE_PARTNER: 1693 umb_newstate(sc, UMB_S_ATTACHED, 1694 UMB_NS_DONT_DROP); 1695 break; 1696 default: 1697 break; 1698 } 1699 } else 1700 umb_newstate(sc, UMB_S_SIMREADY, UMB_NS_DONT_RAISE); 1701 } else switch (sc->sc_info.packetstate) { 1702 case MBIM_PKTSERVICE_STATE_ATTACHED: 1703 umb_newstate(sc, UMB_S_ATTACHED, UMB_NS_DONT_DROP); 1704 break; 1705 case MBIM_PKTSERVICE_STATE_DETACHED: 1706 umb_newstate(sc, UMB_S_SIMREADY, UMB_NS_DONT_RAISE); 1707 break; 1708 } 1709 return 1; 1710 } 1711 1712 int 1713 umb_decode_signal_state(struct umb_softc *sc, void *data, int len) 1714 { 1715 struct mbim_cid_signal_state *ss = data; 1716 struct ifnet *ifp = GET_IFP(sc); 1717 int rssi; 1718 1719 if (len < sizeof (*ss)) 1720 return 0; 1721 1722 if (letoh32(ss->rssi) == 99) 1723 rssi = UMB_VALUE_UNKNOWN; 1724 else { 1725 rssi = -113 + 2 * letoh32(ss->rssi); 1726 if ((ifp->if_flags & IFF_DEBUG) && sc->sc_info.rssi != rssi && 1727 sc->sc_state >= UMB_S_CONNECTED) 1728 log(LOG_INFO, "%s: rssi %d dBm\n", DEVNAM(sc), rssi); 1729 } 1730 sc->sc_info.rssi = rssi; 1731 sc->sc_info.ber = letoh32(ss->err_rate); 1732 if (sc->sc_info.ber == -99) 1733 sc->sc_info.ber = UMB_VALUE_UNKNOWN; 1734 return 1; 1735 } 1736 1737 int 1738 umb_decode_connect_info(struct umb_softc *sc, void *data, int len) 1739 { 1740 struct mbim_cid_connect_info *ci = data; 1741 struct ifnet *ifp = GET_IFP(sc); 1742 int act; 1743 1744 if (len < sizeof (*ci)) 1745 return 0; 1746 1747 if (letoh32(ci->sessionid) != umb_session_id) { 1748 DPRINTF("%s: discard connection info for session %u\n", 1749 DEVNAM(sc), letoh32(ci->sessionid)); 1750 return 1; 1751 } 1752 if (memcmp(ci->context, umb_uuid_context_internet, 1753 sizeof (ci->context))) { 1754 DPRINTF("%s: discard connection info for other context\n", 1755 DEVNAM(sc)); 1756 return 1; 1757 } 1758 act = letoh32(ci->activation); 1759 if (sc->sc_info.activation != act) { 1760 if (ifp->if_flags & IFF_DEBUG) 1761 log(LOG_INFO, "%s: connection %s\n", DEVNAM(sc), 1762 umb_activation(act)); 1763 1764 sc->sc_info.activation = act; 1765 sc->sc_info.nwerror = letoh32(ci->nwerror); 1766 1767 if (sc->sc_info.activation == MBIM_ACTIVATION_STATE_ACTIVATED) 1768 umb_newstate(sc, UMB_S_CONNECTED, UMB_NS_DONT_DROP); 1769 else if (sc->sc_info.activation == 1770 MBIM_ACTIVATION_STATE_DEACTIVATED) 1771 umb_newstate(sc, UMB_S_ATTACHED, 0); 1772 /* else: other states are purely transitional */ 1773 } 1774 return 1; 1775 } 1776 1777 void 1778 umb_clear_addr(struct umb_softc *sc) 1779 { 1780 struct ifnet *ifp = GET_IFP(sc); 1781 1782 memset(sc->sc_info.ipv4dns, 0, sizeof (sc->sc_info.ipv4dns)); 1783 memset(sc->sc_info.ipv6dns, 0, sizeof (sc->sc_info.ipv6dns)); 1784 umb_send_inet_proposal(sc, AF_INET); 1785 #ifdef INET6 1786 umb_send_inet_proposal(sc, AF_INET6); 1787 #endif 1788 NET_LOCK(); 1789 in_ifdetach(ifp); 1790 #ifdef INET6 1791 in6_ifdetach(ifp); 1792 #endif 1793 NET_UNLOCK(); 1794 } 1795 1796 int 1797 umb_add_inet_config(struct umb_softc *sc, struct in_addr ip, u_int prefixlen, 1798 struct in_addr gw) 1799 { 1800 struct ifnet *ifp = GET_IFP(sc); 1801 struct in_aliasreq ifra; 1802 struct sockaddr_in *sin, default_sin; 1803 struct rt_addrinfo info; 1804 struct rtentry *rt; 1805 int rv; 1806 1807 memset(&ifra, 0, sizeof (ifra)); 1808 sin = &ifra.ifra_addr; 1809 sin->sin_family = AF_INET; 1810 sin->sin_len = sizeof (*sin); 1811 sin->sin_addr = ip; 1812 1813 sin = &ifra.ifra_dstaddr; 1814 sin->sin_family = AF_INET; 1815 sin->sin_len = sizeof (*sin); 1816 sin->sin_addr = gw; 1817 1818 sin = &ifra.ifra_mask; 1819 sin->sin_family = AF_INET; 1820 sin->sin_len = sizeof (*sin); 1821 in_len2mask(&sin->sin_addr, prefixlen); 1822 1823 rv = in_ioctl(SIOCAIFADDR, (caddr_t)&ifra, ifp, 1); 1824 if (rv != 0) { 1825 printf("%s: unable to set IPv4 address, error %d\n", 1826 DEVNAM(ifp->if_softc), rv); 1827 return rv; 1828 } 1829 1830 memset(&default_sin, 0, sizeof(default_sin)); 1831 default_sin.sin_family = AF_INET; 1832 default_sin.sin_len = sizeof (default_sin); 1833 1834 memset(&info, 0, sizeof(info)); 1835 info.rti_flags = RTF_GATEWAY /* maybe | RTF_STATIC */; 1836 info.rti_ifa = ifa_ifwithaddr(sintosa(&ifra.ifra_addr), 1837 ifp->if_rdomain); 1838 info.rti_info[RTAX_DST] = sintosa(&default_sin); 1839 info.rti_info[RTAX_NETMASK] = sintosa(&default_sin); 1840 info.rti_info[RTAX_GATEWAY] = sintosa(&ifra.ifra_dstaddr); 1841 1842 NET_LOCK(); 1843 rv = rtrequest(RTM_ADD, &info, 0, &rt, ifp->if_rdomain); 1844 NET_UNLOCK(); 1845 if (rv) { 1846 printf("%s: unable to set IPv4 default route, " 1847 "error %d\n", DEVNAM(ifp->if_softc), rv); 1848 rtm_miss(RTM_MISS, &info, 0, RTP_NONE, 0, rv, 1849 ifp->if_rdomain); 1850 } else { 1851 /* Inform listeners of the new route */ 1852 rtm_send(rt, RTM_ADD, rv, ifp->if_rdomain); 1853 rtfree(rt); 1854 } 1855 1856 if (ifp->if_flags & IFF_DEBUG) { 1857 char str[3][INET_ADDRSTRLEN]; 1858 log(LOG_INFO, "%s: IPv4 addr %s, mask %s, gateway %s\n", 1859 DEVNAM(ifp->if_softc), 1860 sockaddr_ntop(sintosa(&ifra.ifra_addr), str[0], 1861 sizeof(str[0])), 1862 sockaddr_ntop(sintosa(&ifra.ifra_mask), str[1], 1863 sizeof(str[1])), 1864 sockaddr_ntop(sintosa(&ifra.ifra_dstaddr), str[2], 1865 sizeof(str[2]))); 1866 } 1867 return 0; 1868 } 1869 1870 #ifdef INET6 1871 int 1872 umb_add_inet6_config(struct umb_softc *sc, struct in6_addr *ip, u_int prefixlen, 1873 struct in6_addr *gw) 1874 { 1875 struct ifnet *ifp = GET_IFP(sc); 1876 struct in6_aliasreq ifra; 1877 struct sockaddr_in6 *sin6, default_sin6; 1878 struct rt_addrinfo info; 1879 struct rtentry *rt; 1880 int rv; 1881 1882 memset(&ifra, 0, sizeof (ifra)); 1883 sin6 = &ifra.ifra_addr; 1884 sin6->sin6_family = AF_INET6; 1885 sin6->sin6_len = sizeof (*sin6); 1886 memcpy(&sin6->sin6_addr, ip, sizeof (sin6->sin6_addr)); 1887 1888 sin6 = &ifra.ifra_dstaddr; 1889 sin6->sin6_family = AF_INET6; 1890 sin6->sin6_len = sizeof (*sin6); 1891 memcpy(&sin6->sin6_addr, gw, sizeof (sin6->sin6_addr)); 1892 1893 /* XXX: in6_update_ifa() accepts only 128 bits for P2P interfaces. */ 1894 prefixlen = 128; 1895 1896 sin6 = &ifra.ifra_prefixmask; 1897 sin6->sin6_family = AF_INET6; 1898 sin6->sin6_len = sizeof (*sin6); 1899 in6_prefixlen2mask(&sin6->sin6_addr, prefixlen); 1900 1901 ifra.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; 1902 ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; 1903 1904 rv = in6_ioctl(SIOCAIFADDR_IN6, (caddr_t)&ifra, ifp, 1); 1905 if (rv != 0) { 1906 printf("%s: unable to set IPv6 address, error %d\n", 1907 DEVNAM(ifp->if_softc), rv); 1908 return rv; 1909 } 1910 1911 memset(&default_sin6, 0, sizeof(default_sin6)); 1912 default_sin6.sin6_family = AF_INET6; 1913 default_sin6.sin6_len = sizeof (default_sin6); 1914 1915 memset(&info, 0, sizeof(info)); 1916 info.rti_flags = RTF_GATEWAY /* maybe | RTF_STATIC */; 1917 info.rti_ifa = ifa_ifwithaddr(sin6tosa(&ifra.ifra_addr), 1918 ifp->if_rdomain); 1919 info.rti_info[RTAX_DST] = sin6tosa(&default_sin6); 1920 info.rti_info[RTAX_NETMASK] = sin6tosa(&default_sin6); 1921 info.rti_info[RTAX_GATEWAY] = sin6tosa(&ifra.ifra_dstaddr); 1922 1923 NET_LOCK(); 1924 rv = rtrequest(RTM_ADD, &info, 0, &rt, ifp->if_rdomain); 1925 NET_UNLOCK(); 1926 if (rv) { 1927 printf("%s: unable to set IPv6 default route, " 1928 "error %d\n", DEVNAM(ifp->if_softc), rv); 1929 rtm_miss(RTM_MISS, &info, 0, RTP_NONE, 0, rv, 1930 ifp->if_rdomain); 1931 } else { 1932 /* Inform listeners of the new route */ 1933 rtm_send(rt, RTM_ADD, rv, ifp->if_rdomain); 1934 rtfree(rt); 1935 } 1936 1937 if (ifp->if_flags & IFF_DEBUG) { 1938 char str[3][INET6_ADDRSTRLEN]; 1939 log(LOG_INFO, "%s: IPv6 addr %s, mask %s, gateway %s\n", 1940 DEVNAM(ifp->if_softc), 1941 sockaddr_ntop(sin6tosa(&ifra.ifra_addr), str[0], 1942 sizeof(str[0])), 1943 sockaddr_ntop(sin6tosa(&ifra.ifra_prefixmask), str[1], 1944 sizeof(str[1])), 1945 sockaddr_ntop(sin6tosa(&ifra.ifra_dstaddr), str[2], 1946 sizeof(str[2]))); 1947 } 1948 return 0; 1949 } 1950 #endif 1951 1952 void 1953 umb_send_inet_proposal(struct umb_softc *sc, int af) 1954 { 1955 struct ifnet *ifp = GET_IFP(sc); 1956 struct sockaddr_rtdns rtdns; 1957 struct rt_addrinfo info; 1958 int i, flag = 0; 1959 size_t sz = 0; 1960 1961 memset(&rtdns, 0, sizeof(rtdns)); 1962 memset(&info, 0, sizeof(info)); 1963 1964 for (i = 0; i < UMB_MAX_DNSSRV; i++) { 1965 if (af == AF_INET) { 1966 sz = sizeof (sc->sc_info.ipv4dns[i]); 1967 if (sc->sc_info.ipv4dns[i].s_addr == INADDR_ANY) 1968 break; 1969 memcpy(rtdns.sr_dns + i * sz, &sc->sc_info.ipv4dns[i], 1970 sz); 1971 flag = RTF_UP; 1972 #ifdef INET6 1973 } else if (af == AF_INET6) { 1974 sz = sizeof (sc->sc_info.ipv6dns[i]); 1975 if (IN6_ARE_ADDR_EQUAL(&sc->sc_info.ipv6dns[i], 1976 &in6addr_any)) 1977 break; 1978 memcpy(rtdns.sr_dns + i * sz, &sc->sc_info.ipv6dns[i], 1979 sz); 1980 flag = RTF_UP; 1981 #endif 1982 } 1983 } 1984 rtdns.sr_family = af; 1985 rtdns.sr_len = 2 + i * sz; 1986 info.rti_info[RTAX_DNS] = srtdnstosa(&rtdns); 1987 1988 rtm_proposal(ifp, &info, flag, RTP_PROPOSAL_UMB); 1989 } 1990 1991 int 1992 umb_decode_ip_configuration(struct umb_softc *sc, void *data, int len) 1993 { 1994 struct mbim_cid_ip_configuration_info *ic = data; 1995 struct ifnet *ifp = GET_IFP(sc); 1996 int s; 1997 uint32_t avail_v4; 1998 uint32_t val; 1999 int n, i; 2000 int off; 2001 struct mbim_cid_ipv4_element ipv4elem; 2002 struct in_addr addr, gw; 2003 int state = -1; 2004 int rv; 2005 int hasmtu = 0; 2006 #ifdef INET6 2007 uint32_t avail_v6; 2008 struct mbim_cid_ipv6_element ipv6elem; 2009 struct in6_addr addr6, gw6; 2010 #endif 2011 2012 if (len < sizeof (*ic)) 2013 return 0; 2014 if (letoh32(ic->sessionid) != umb_session_id) { 2015 DPRINTF("%s: ignore IP configration for session id %d\n", 2016 DEVNAM(sc), letoh32(ic->sessionid)); 2017 return 0; 2018 } 2019 s = splnet(); 2020 2021 memset(sc->sc_info.ipv4dns, 0, sizeof (sc->sc_info.ipv4dns)); 2022 memset(sc->sc_info.ipv6dns, 0, sizeof (sc->sc_info.ipv6dns)); 2023 2024 /* 2025 * IPv4 configuation 2026 */ 2027 avail_v4 = letoh32(ic->ipv4_available); 2028 if ((avail_v4 & (MBIM_IPCONF_HAS_ADDRINFO | MBIM_IPCONF_HAS_GWINFO)) == 2029 (MBIM_IPCONF_HAS_ADDRINFO | MBIM_IPCONF_HAS_GWINFO)) { 2030 n = letoh32(ic->ipv4_naddr); 2031 off = letoh32(ic->ipv4_addroffs); 2032 2033 if (n == 0 || off + sizeof (ipv4elem) > len) 2034 goto tryv6; 2035 if (n != 1 && ifp->if_flags & IFF_DEBUG) 2036 log(LOG_INFO, "%s: more than one IPv4 addr: %d\n", 2037 DEVNAM(ifp->if_softc), n); 2038 2039 /* Only pick the first one */ 2040 memcpy(&ipv4elem, data + off, sizeof (ipv4elem)); 2041 ipv4elem.prefixlen = letoh32(ipv4elem.prefixlen); 2042 addr.s_addr = ipv4elem.addr; 2043 2044 off = letoh32(ic->ipv4_gwoffs); 2045 if (off + sizeof (gw) > len) 2046 goto done; 2047 memcpy(&gw, data + off, sizeof(gw)); 2048 2049 rv = umb_add_inet_config(sc, addr, ipv4elem.prefixlen, gw); 2050 if (rv == 0) 2051 state = UMB_S_UP; 2052 2053 } 2054 2055 memset(sc->sc_info.ipv4dns, 0, sizeof (sc->sc_info.ipv4dns)); 2056 if (avail_v4 & MBIM_IPCONF_HAS_DNSINFO) { 2057 n = letoh32(ic->ipv4_ndnssrv); 2058 off = letoh32(ic->ipv4_dnssrvoffs); 2059 i = 0; 2060 while (n-- > 0) { 2061 if (off + sizeof (addr) > len) 2062 break; 2063 memcpy(&addr, data + off, sizeof(addr)); 2064 if (i < UMB_MAX_DNSSRV) 2065 sc->sc_info.ipv4dns[i++] = addr; 2066 off += sizeof(addr); 2067 if (ifp->if_flags & IFF_DEBUG) { 2068 char str[INET_ADDRSTRLEN]; 2069 log(LOG_INFO, "%s: IPv4 nameserver %s\n", 2070 DEVNAM(ifp->if_softc), inet_ntop(AF_INET, 2071 &addr, str, sizeof(str))); 2072 } 2073 } 2074 umb_send_inet_proposal(sc, AF_INET); 2075 } 2076 if ((avail_v4 & MBIM_IPCONF_HAS_MTUINFO)) { 2077 val = letoh32(ic->ipv4_mtu); 2078 if (ifp->if_hardmtu != val && val <= sc->sc_maxpktlen) { 2079 hasmtu = 1; 2080 ifp->if_hardmtu = val; 2081 if (ifp->if_mtu > val) 2082 ifp->if_mtu = val; 2083 } 2084 } 2085 2086 tryv6:; 2087 #ifdef INET6 2088 /* 2089 * IPv6 configuation 2090 */ 2091 avail_v6 = letoh32(ic->ipv6_available); 2092 if (avail_v6 == 0) { 2093 if (ifp->if_flags & IFF_DEBUG) 2094 log(LOG_INFO, "%s: ISP or WWAN module offers no IPv6 " 2095 "support\n", DEVNAM(ifp->if_softc)); 2096 goto done; 2097 } 2098 2099 if ((avail_v6 & (MBIM_IPCONF_HAS_ADDRINFO | MBIM_IPCONF_HAS_GWINFO)) == 2100 (MBIM_IPCONF_HAS_ADDRINFO | MBIM_IPCONF_HAS_GWINFO)) { 2101 n = letoh32(ic->ipv6_naddr); 2102 off = letoh32(ic->ipv6_addroffs); 2103 2104 if (n == 0 || off + sizeof (ipv6elem) > len) 2105 goto done; 2106 if (n != 1 && ifp->if_flags & IFF_DEBUG) 2107 log(LOG_INFO, "%s: more than one IPv6 addr: %d\n", 2108 DEVNAM(ifp->if_softc), n); 2109 2110 /* Only pick the first one */ 2111 memcpy(&ipv6elem, data + off, sizeof (ipv6elem)); 2112 memcpy(&addr6, ipv6elem.addr, sizeof (addr6)); 2113 2114 off = letoh32(ic->ipv6_gwoffs); 2115 if (off + sizeof (gw6) > len) 2116 goto done; 2117 memcpy(&gw6, data + off, sizeof (gw6)); 2118 2119 rv = umb_add_inet6_config(sc, &addr6, ipv6elem.prefixlen, &gw6); 2120 if (rv == 0) 2121 state = UMB_S_UP; 2122 } 2123 2124 if (avail_v6 & MBIM_IPCONF_HAS_DNSINFO) { 2125 n = letoh32(ic->ipv6_ndnssrv); 2126 off = letoh32(ic->ipv6_dnssrvoffs); 2127 i = 0; 2128 while (n-- > 0) { 2129 if (off + sizeof (addr6) > len) 2130 break; 2131 memcpy(&addr6, data + off, sizeof(addr6)); 2132 if (i < UMB_MAX_DNSSRV) 2133 sc->sc_info.ipv6dns[i++] = addr6; 2134 off += sizeof(addr6); 2135 if (ifp->if_flags & IFF_DEBUG) { 2136 char str[INET6_ADDRSTRLEN]; 2137 log(LOG_INFO, "%s: IPv6 nameserver %s\n", 2138 DEVNAM(ifp->if_softc), inet_ntop(AF_INET6, 2139 &addr6, str, sizeof(str))); 2140 } 2141 } 2142 umb_send_inet_proposal(sc, AF_INET6); 2143 } 2144 2145 if ((avail_v6 & MBIM_IPCONF_HAS_MTUINFO)) { 2146 val = letoh32(ic->ipv6_mtu); 2147 if (ifp->if_hardmtu != val && val <= sc->sc_maxpktlen) { 2148 hasmtu = 1; 2149 ifp->if_hardmtu = val; 2150 if (ifp->if_mtu > val) 2151 ifp->if_mtu = val; 2152 } 2153 } 2154 #endif 2155 2156 done: 2157 if (hasmtu && (ifp->if_flags & IFF_DEBUG)) 2158 log(LOG_INFO, "%s: MTU %d\n", DEVNAM(sc), ifp->if_hardmtu); 2159 2160 if (state != -1) 2161 umb_newstate(sc, state, 0); 2162 2163 splx(s); 2164 return 1; 2165 } 2166 2167 void 2168 umb_rx(struct umb_softc *sc) 2169 { 2170 usbd_setup_xfer(sc->sc_rx_xfer, sc->sc_rx_pipe, sc, sc->sc_rx_buf, 2171 sc->sc_rx_bufsz, USBD_SHORT_XFER_OK | USBD_NO_COPY, 2172 USBD_NO_TIMEOUT, umb_rxeof); 2173 usbd_transfer(sc->sc_rx_xfer); 2174 } 2175 2176 void 2177 umb_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 2178 { 2179 struct umb_softc *sc = priv; 2180 struct ifnet *ifp = GET_IFP(sc); 2181 2182 if (usbd_is_dying(sc->sc_udev) || !(ifp->if_flags & IFF_RUNNING)) 2183 return; 2184 2185 if (status != USBD_NORMAL_COMPLETION) { 2186 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 2187 return; 2188 DPRINTF("%s: rx error: %s\n", DEVNAM(sc), usbd_errstr(status)); 2189 if (status == USBD_STALLED) 2190 usbd_clear_endpoint_stall_async(sc->sc_rx_pipe); 2191 if (++sc->sc_rx_nerr > 100) { 2192 log(LOG_ERR, "%s: too many rx errors, disabling\n", 2193 DEVNAM(sc)); 2194 usbd_deactivate(sc->sc_udev); 2195 } 2196 } else { 2197 sc->sc_rx_nerr = 0; 2198 umb_decap(sc, xfer); 2199 } 2200 2201 umb_rx(sc); 2202 return; 2203 } 2204 2205 int 2206 umb_encap(struct umb_softc *sc, int ndgram) 2207 { 2208 struct ncm_header16 *hdr16 = NULL; 2209 struct ncm_header32 *hdr32 = NULL; 2210 struct ncm_pointer16 *ptr16 = NULL; 2211 struct ncm_pointer32 *ptr32 = NULL; 2212 struct ncm_pointer16_dgram *dgram16 = NULL; 2213 struct ncm_pointer32_dgram *dgram32 = NULL; 2214 int offs = 0, plen = 0; 2215 int dgoffs = 0, poffs; 2216 struct mbuf *m; 2217 usbd_status err; 2218 2219 /* All size constraints have been validated by the caller! */ 2220 2221 /* NCM Header */ 2222 switch (sc->sc_ncm_format) { 2223 case NCM_FORMAT_NTB16: 2224 hdr16 = sc->sc_tx_buf; 2225 USETDW(hdr16->dwSignature, NCM_HDR16_SIG); 2226 USETW(hdr16->wHeaderLength, sizeof (*hdr16)); 2227 USETW(hdr16->wSequence, sc->sc_tx_seq); 2228 USETW(hdr16->wBlockLength, 0); 2229 offs = sizeof (*hdr16); 2230 break; 2231 case NCM_FORMAT_NTB32: 2232 hdr32 = sc->sc_tx_buf; 2233 USETDW(hdr32->dwSignature, NCM_HDR32_SIG); 2234 USETW(hdr32->wHeaderLength, sizeof (*hdr32)); 2235 USETW(hdr32->wSequence, sc->sc_tx_seq); 2236 USETDW(hdr32->dwBlockLength, 0); 2237 offs = sizeof (*hdr32); 2238 break; 2239 } 2240 offs += umb_padding(sc->sc_tx_buf, sc->sc_tx_bufsz, offs, 2241 sc->sc_align, 0); 2242 2243 if (sc->sc_flags & UMBFLG_NDP_AT_END) { 2244 dgoffs = offs; 2245 2246 /* 2247 * Calculate space needed for datagrams. 2248 * 2249 * XXX cannot use ml_len(&sc->sc_tx_ml), since it ignores 2250 * the padding requirements. 2251 */ 2252 poffs = dgoffs; 2253 MBUF_LIST_FOREACH(&sc->sc_tx_ml, m) { 2254 poffs += umb_padding(sc->sc_tx_buf, sc->sc_tx_bufsz, 2255 poffs, sc->sc_ndp_div, sc->sc_ndp_remainder); 2256 poffs += m->m_pkthdr.len; 2257 } 2258 poffs += umb_padding(sc->sc_tx_buf, sc->sc_tx_bufsz, 2259 poffs, sc->sc_ndp_div, sc->sc_ndp_remainder); 2260 } else 2261 poffs = offs; 2262 2263 /* NCM Pointer */ 2264 switch (sc->sc_ncm_format) { 2265 case NCM_FORMAT_NTB16: 2266 USETW(hdr16->wNdpIndex, poffs); 2267 ptr16 = (struct ncm_pointer16 *)(sc->sc_tx_buf + poffs); 2268 plen = sizeof(*ptr16) + ndgram * sizeof(*dgram16); 2269 USETDW(ptr16->dwSignature, MBIM_NCM_NTH16_SIG(umb_session_id)); 2270 USETW(ptr16->wLength, plen); 2271 USETW(ptr16->wNextNdpIndex, 0); 2272 dgram16 = ptr16->dgram; 2273 break; 2274 case NCM_FORMAT_NTB32: 2275 USETDW(hdr32->dwNdpIndex, poffs); 2276 ptr32 = (struct ncm_pointer32 *)(sc->sc_tx_buf + poffs); 2277 plen = sizeof(*ptr32) + ndgram * sizeof(*dgram32); 2278 USETDW(ptr32->dwSignature, MBIM_NCM_NTH32_SIG(umb_session_id)); 2279 USETW(ptr32->wLength, plen); 2280 USETW(ptr32->wReserved6, 0); 2281 USETDW(ptr32->dwNextNdpIndex, 0); 2282 USETDW(ptr32->dwReserved12, 0); 2283 dgram32 = ptr32->dgram; 2284 break; 2285 } 2286 2287 if (!(sc->sc_flags & UMBFLG_NDP_AT_END)) 2288 dgoffs = offs + plen; 2289 2290 /* Encap mbufs to NCM dgrams */ 2291 sc->sc_tx_seq++; 2292 while ((m = ml_dequeue(&sc->sc_tx_ml)) != NULL) { 2293 dgoffs += umb_padding(sc->sc_tx_buf, sc->sc_tx_bufsz, dgoffs, 2294 sc->sc_ndp_div, sc->sc_ndp_remainder); 2295 switch (sc->sc_ncm_format) { 2296 case NCM_FORMAT_NTB16: 2297 USETW(dgram16->wDatagramIndex, dgoffs); 2298 USETW(dgram16->wDatagramLen, m->m_pkthdr.len); 2299 dgram16++; 2300 break; 2301 case NCM_FORMAT_NTB32: 2302 USETDW(dgram32->dwDatagramIndex, dgoffs); 2303 USETDW(dgram32->dwDatagramLen, m->m_pkthdr.len); 2304 dgram32++; 2305 break; 2306 } 2307 m_copydata(m, 0, m->m_pkthdr.len, sc->sc_tx_buf + dgoffs); 2308 dgoffs += m->m_pkthdr.len; 2309 m_freem(m); 2310 } 2311 2312 if (sc->sc_flags & UMBFLG_NDP_AT_END) 2313 offs = poffs + plen; 2314 else 2315 offs = dgoffs; 2316 2317 /* Terminating pointer and datagram size */ 2318 switch (sc->sc_ncm_format) { 2319 case NCM_FORMAT_NTB16: 2320 USETW(dgram16->wDatagramIndex, 0); 2321 USETW(dgram16->wDatagramLen, 0); 2322 USETW(hdr16->wBlockLength, offs); 2323 KASSERT(dgram16 - ptr16->dgram == ndgram); 2324 break; 2325 case NCM_FORMAT_NTB32: 2326 USETDW(dgram32->dwDatagramIndex, 0); 2327 USETDW(dgram32->dwDatagramLen, 0); 2328 USETDW(hdr32->dwBlockLength, offs); 2329 KASSERT(dgram32 - ptr32->dgram == ndgram); 2330 break; 2331 } 2332 2333 DPRINTFN(3, "%s: encap %d bytes\n", DEVNAM(sc), offs); 2334 DDUMPN(5, sc->sc_tx_buf, offs); 2335 KASSERT(offs <= sc->sc_tx_bufsz); 2336 2337 usbd_setup_xfer(sc->sc_tx_xfer, sc->sc_tx_pipe, sc, sc->sc_tx_buf, offs, 2338 USBD_FORCE_SHORT_XFER | USBD_NO_COPY, umb_xfer_tout, umb_txeof); 2339 err = usbd_transfer(sc->sc_tx_xfer); 2340 if (err != USBD_IN_PROGRESS) { 2341 DPRINTF("%s: start tx error: %s\n", DEVNAM(sc), 2342 usbd_errstr(err)); 2343 ml_purge(&sc->sc_tx_ml); 2344 return 0; 2345 } 2346 return 1; 2347 } 2348 2349 void 2350 umb_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 2351 { 2352 struct umb_softc *sc = priv; 2353 struct ifnet *ifp = GET_IFP(sc); 2354 int s; 2355 2356 s = splnet(); 2357 ml_purge(&sc->sc_tx_ml); 2358 ifq_clr_oactive(&ifp->if_snd); 2359 ifp->if_timer = 0; 2360 2361 if (status != USBD_NORMAL_COMPLETION) { 2362 if (status != USBD_NOT_STARTED && status != USBD_CANCELLED) { 2363 ifp->if_oerrors++; 2364 DPRINTF("%s: tx error: %s\n", DEVNAM(sc), 2365 usbd_errstr(status)); 2366 if (status == USBD_STALLED) 2367 usbd_clear_endpoint_stall_async(sc->sc_tx_pipe); 2368 } 2369 } 2370 if (ifq_empty(&ifp->if_snd) == 0) 2371 umb_start(ifp); 2372 2373 splx(s); 2374 } 2375 2376 void 2377 umb_decap(struct umb_softc *sc, struct usbd_xfer *xfer) 2378 { 2379 struct ifnet *ifp = GET_IFP(sc); 2380 int s; 2381 void *buf; 2382 uint32_t len, af = 0; 2383 char *dp; 2384 struct ncm_header16 *hdr16; 2385 struct ncm_header32 *hdr32; 2386 struct ncm_pointer16 *ptr16; 2387 struct ncm_pointer16_dgram *dgram16; 2388 struct ncm_pointer32_dgram *dgram32; 2389 uint32_t hsig, psig; 2390 int blen; 2391 int ptrlen, ptroff, dgentryoff; 2392 uint32_t doff, dlen; 2393 struct mbuf_list ml = MBUF_LIST_INITIALIZER(); 2394 struct mbuf *m; 2395 2396 usbd_get_xfer_status(xfer, NULL, &buf, &len, NULL); 2397 DPRINTFN(4, "%s: recv %d bytes\n", DEVNAM(sc), len); 2398 DDUMPN(5, buf, len); 2399 s = splnet(); 2400 if (len < sizeof (*hdr16)) 2401 goto toosmall; 2402 2403 hdr16 = (struct ncm_header16 *)buf; 2404 hsig = UGETDW(hdr16->dwSignature); 2405 2406 switch (hsig) { 2407 case NCM_HDR16_SIG: 2408 blen = UGETW(hdr16->wBlockLength); 2409 ptroff = UGETW(hdr16->wNdpIndex); 2410 if (UGETW(hdr16->wHeaderLength) != sizeof (*hdr16)) { 2411 DPRINTF("%s: bad header len %d for NTH16 (exp %zu)\n", 2412 DEVNAM(sc), UGETW(hdr16->wHeaderLength), 2413 sizeof (*hdr16)); 2414 goto fail; 2415 } 2416 break; 2417 case NCM_HDR32_SIG: 2418 if (len < sizeof (*hdr32)) 2419 goto toosmall; 2420 hdr32 = (struct ncm_header32 *)hdr16; 2421 blen = UGETDW(hdr32->dwBlockLength); 2422 ptroff = UGETDW(hdr32->dwNdpIndex); 2423 if (UGETW(hdr32->wHeaderLength) != sizeof (*hdr32)) { 2424 DPRINTF("%s: bad header len %d for NTH32 (exp %zu)\n", 2425 DEVNAM(sc), UGETW(hdr32->wHeaderLength), 2426 sizeof (*hdr32)); 2427 goto fail; 2428 } 2429 break; 2430 default: 2431 DPRINTF("%s: unsupported NCM header signature (0x%08x)\n", 2432 DEVNAM(sc), hsig); 2433 goto fail; 2434 } 2435 if (blen != 0 && len < blen) { 2436 DPRINTF("%s: bad NTB len (%d) for %d bytes of data\n", 2437 DEVNAM(sc), blen, len); 2438 goto fail; 2439 } 2440 2441 ptr16 = (struct ncm_pointer16 *)(buf + ptroff); 2442 psig = UGETDW(ptr16->dwSignature); 2443 ptrlen = UGETW(ptr16->wLength); 2444 if (len < ptrlen + ptroff) 2445 goto toosmall; 2446 if (!MBIM_NCM_NTH16_ISISG(psig) && !MBIM_NCM_NTH32_ISISG(psig)) { 2447 DPRINTF("%s: unsupported NCM pointer signature (0x%08x)\n", 2448 DEVNAM(sc), psig); 2449 goto fail; 2450 } 2451 2452 switch (hsig) { 2453 case NCM_HDR16_SIG: 2454 dgentryoff = offsetof(struct ncm_pointer16, dgram); 2455 break; 2456 case NCM_HDR32_SIG: 2457 dgentryoff = offsetof(struct ncm_pointer32, dgram); 2458 break; 2459 default: 2460 goto fail; 2461 } 2462 2463 while (dgentryoff < ptrlen) { 2464 switch (hsig) { 2465 case NCM_HDR16_SIG: 2466 if (ptroff + dgentryoff < sizeof (*dgram16)) 2467 goto done; 2468 dgram16 = (struct ncm_pointer16_dgram *) 2469 (buf + ptroff + dgentryoff); 2470 dgentryoff += sizeof (*dgram16); 2471 dlen = UGETW(dgram16->wDatagramLen); 2472 doff = UGETW(dgram16->wDatagramIndex); 2473 break; 2474 case NCM_HDR32_SIG: 2475 if (ptroff + dgentryoff < sizeof (*dgram32)) 2476 goto done; 2477 dgram32 = (struct ncm_pointer32_dgram *) 2478 (buf + ptroff + dgentryoff); 2479 dgentryoff += sizeof (*dgram32); 2480 dlen = UGETDW(dgram32->dwDatagramLen); 2481 doff = UGETDW(dgram32->dwDatagramIndex); 2482 break; 2483 default: 2484 ifp->if_ierrors++; 2485 goto done; 2486 } 2487 2488 /* Terminating zero entry */ 2489 if (dlen == 0 || doff == 0) 2490 break; 2491 if (len < dlen + doff) { 2492 /* Skip giant datagram but continue processing */ 2493 DPRINTF("%s: datagram too large (%d @ off %d)\n", 2494 DEVNAM(sc), dlen, doff); 2495 continue; 2496 } 2497 2498 dp = buf + doff; 2499 DPRINTFN(3, "%s: decap %d bytes\n", DEVNAM(sc), dlen); 2500 m = m_devget(dp, dlen, sizeof(uint32_t)); 2501 if (m == NULL) { 2502 ifp->if_iqdrops++; 2503 continue; 2504 } 2505 m = m_prepend(m, sizeof(uint32_t), M_DONTWAIT); 2506 if (m == NULL) { 2507 ifp->if_iqdrops++; 2508 continue; 2509 } 2510 switch (*dp & 0xf0) { 2511 case 4 << 4: 2512 af = htonl(AF_INET); 2513 break; 2514 case 6 << 4: 2515 af = htonl(AF_INET6); 2516 break; 2517 } 2518 *mtod(m, uint32_t *) = af; 2519 ml_enqueue(&ml, m); 2520 } 2521 done: 2522 if_input(ifp, &ml); 2523 splx(s); 2524 return; 2525 toosmall: 2526 DPRINTF("%s: packet too small (%d)\n", DEVNAM(sc), len); 2527 fail: 2528 ifp->if_ierrors++; 2529 splx(s); 2530 } 2531 2532 usbd_status 2533 umb_send_encap_command(struct umb_softc *sc, void *data, int len) 2534 { 2535 struct usbd_xfer *xfer; 2536 usb_device_request_t req; 2537 char *buf; 2538 2539 if (len > sc->sc_ctrl_len) 2540 return USBD_INVAL; 2541 2542 if ((xfer = usbd_alloc_xfer(sc->sc_udev)) == NULL) 2543 return USBD_NOMEM; 2544 if ((buf = usbd_alloc_buffer(xfer, len)) == NULL) { 2545 usbd_free_xfer(xfer); 2546 return USBD_NOMEM; 2547 } 2548 memcpy(buf, data, len); 2549 2550 /* XXX FIXME: if (total len > sc->sc_ctrl_len) => must fragment */ 2551 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 2552 req.bRequest = UCDC_SEND_ENCAPSULATED_COMMAND; 2553 USETW(req.wValue, 0); 2554 USETW(req.wIndex, sc->sc_ctrl_ifaceno); 2555 USETW(req.wLength, len); 2556 DELAY(umb_delay); 2557 return usbd_request_async(xfer, &req, NULL, NULL); 2558 } 2559 2560 int 2561 umb_get_encap_response(struct umb_softc *sc, void *buf, int *len) 2562 { 2563 usb_device_request_t req; 2564 usbd_status err; 2565 2566 req.bmRequestType = UT_READ_CLASS_INTERFACE; 2567 req.bRequest = UCDC_GET_ENCAPSULATED_RESPONSE; 2568 USETW(req.wValue, 0); 2569 USETW(req.wIndex, sc->sc_ctrl_ifaceno); 2570 USETW(req.wLength, *len); 2571 /* XXX FIXME: re-assemble fragments */ 2572 2573 DELAY(umb_delay); 2574 err = usbd_do_request_flags(sc->sc_udev, &req, buf, USBD_SHORT_XFER_OK, 2575 len, umb_xfer_tout); 2576 if (err == USBD_NORMAL_COMPLETION) 2577 return 1; 2578 DPRINTF("%s: ctrl recv: %s\n", DEVNAM(sc), usbd_errstr(err)); 2579 return 0; 2580 } 2581 2582 void 2583 umb_ctrl_msg(struct umb_softc *sc, uint32_t req, void *data, int len) 2584 { 2585 struct ifnet *ifp = GET_IFP(sc); 2586 uint32_t tid; 2587 struct mbim_msghdr *hdr = data; 2588 usbd_status err; 2589 int s; 2590 2591 assertwaitok(); 2592 if (usbd_is_dying(sc->sc_udev)) 2593 return; 2594 if (len < sizeof (*hdr)) 2595 return; 2596 tid = ++sc->sc_tid; 2597 2598 hdr->type = htole32(req); 2599 hdr->len = htole32(len); 2600 hdr->tid = htole32(tid); 2601 2602 #ifdef UMB_DEBUG 2603 if (umb_debug) { 2604 const char *op, *str; 2605 if (req == MBIM_COMMAND_MSG) { 2606 struct mbim_h2f_cmd *c = data; 2607 if (letoh32(c->op) == MBIM_CMDOP_SET) 2608 op = "set"; 2609 else 2610 op = "qry"; 2611 str = umb_cid2str(letoh32(c->cid)); 2612 } else { 2613 op = "snd"; 2614 str = umb_request2str(req); 2615 } 2616 DPRINTF("%s: -> %s %s (tid %u)\n", DEVNAM(sc), op, str, tid); 2617 } 2618 #endif 2619 s = splusb(); 2620 err = umb_send_encap_command(sc, data, len); 2621 splx(s); 2622 if (err != USBD_NORMAL_COMPLETION) { 2623 if (ifp->if_flags & IFF_DEBUG) 2624 log(LOG_ERR, "%s: send %s msg (tid %u) failed: %s\n", 2625 DEVNAM(sc), umb_request2str(req), tid, 2626 usbd_errstr(err)); 2627 2628 /* will affect other transactions, too */ 2629 usbd_abort_pipe(sc->sc_udev->default_pipe); 2630 } else { 2631 DPRINTFN(2, "%s: sent %s (tid %u)\n", DEVNAM(sc), 2632 umb_request2str(req), tid); 2633 DDUMPN(3, data, len); 2634 } 2635 return; 2636 } 2637 2638 void 2639 umb_open(struct umb_softc *sc) 2640 { 2641 struct mbim_h2f_openmsg msg; 2642 2643 memset(&msg, 0, sizeof (msg)); 2644 msg.maxlen = htole32(sc->sc_ctrl_len); 2645 umb_ctrl_msg(sc, MBIM_OPEN_MSG, &msg, sizeof (msg)); 2646 return; 2647 } 2648 2649 void 2650 umb_close(struct umb_softc *sc) 2651 { 2652 struct mbim_h2f_closemsg msg; 2653 2654 memset(&msg, 0, sizeof (msg)); 2655 umb_ctrl_msg(sc, MBIM_CLOSE_MSG, &msg, sizeof (msg)); 2656 } 2657 2658 int 2659 umb_setpin(struct umb_softc *sc, int op, int is_puk, void *pin, int pinlen, 2660 void *newpin, int newpinlen) 2661 { 2662 struct mbim_cid_pin cp; 2663 int off; 2664 2665 if (pinlen == 0) 2666 return 0; 2667 if (pinlen < 0 || pinlen > MBIM_PIN_MAXLEN || 2668 newpinlen < 0 || newpinlen > MBIM_PIN_MAXLEN || 2669 op < 0 || op > MBIM_PIN_OP_CHANGE || 2670 (is_puk && op != MBIM_PIN_OP_ENTER)) 2671 return EINVAL; 2672 2673 memset(&cp, 0, sizeof (cp)); 2674 cp.type = htole32(is_puk ? MBIM_PIN_TYPE_PUK1 : MBIM_PIN_TYPE_PIN1); 2675 2676 off = offsetof(struct mbim_cid_pin, data); 2677 if (!umb_addstr(&cp, sizeof (cp), &off, pin, pinlen, 2678 &cp.pin_offs, &cp.pin_size)) 2679 return EINVAL; 2680 2681 cp.op = htole32(op); 2682 if (newpinlen) { 2683 if (!umb_addstr(&cp, sizeof (cp), &off, newpin, newpinlen, 2684 &cp.newpin_offs, &cp.newpin_size)) 2685 return EINVAL; 2686 } else { 2687 if ((op == MBIM_PIN_OP_CHANGE) || is_puk) 2688 return EINVAL; 2689 if (!umb_addstr(&cp, sizeof (cp), &off, NULL, 0, 2690 &cp.newpin_offs, &cp.newpin_size)) 2691 return EINVAL; 2692 } 2693 umb_cmd(sc, MBIM_CID_PIN, MBIM_CMDOP_SET, &cp, off); 2694 return 0; 2695 } 2696 2697 void 2698 umb_setdataclass(struct umb_softc *sc) 2699 { 2700 struct mbim_cid_registration_state rs; 2701 uint32_t classes; 2702 2703 if (sc->sc_info.supportedclasses == MBIM_DATACLASS_NONE) 2704 return; 2705 2706 memset(&rs, 0, sizeof (rs)); 2707 rs.regaction = htole32(MBIM_REGACTION_AUTOMATIC); 2708 classes = sc->sc_info.supportedclasses; 2709 if (sc->sc_info.preferredclasses != MBIM_DATACLASS_NONE) 2710 classes &= sc->sc_info.preferredclasses; 2711 rs.data_class = htole32(classes); 2712 umb_cmd(sc, MBIM_CID_REGISTER_STATE, MBIM_CMDOP_SET, &rs, sizeof (rs)); 2713 } 2714 2715 void 2716 umb_radio(struct umb_softc *sc, int on) 2717 { 2718 struct mbim_cid_radio_state s; 2719 2720 DPRINTF("%s: set radio %s\n", DEVNAM(sc), on ? "on" : "off"); 2721 memset(&s, 0, sizeof (s)); 2722 s.state = htole32(on ? MBIM_RADIO_STATE_ON : MBIM_RADIO_STATE_OFF); 2723 umb_cmd(sc, MBIM_CID_RADIO_STATE, MBIM_CMDOP_SET, &s, sizeof (s)); 2724 } 2725 2726 void 2727 umb_allocate_cid(struct umb_softc *sc) 2728 { 2729 umb_cmd1(sc, MBIM_CID_DEVICE_CAPS, MBIM_CMDOP_SET, 2730 umb_qmi_alloc_cid, sizeof (umb_qmi_alloc_cid), umb_uuid_qmi_mbim); 2731 } 2732 2733 void 2734 umb_send_fcc_auth(struct umb_softc *sc) 2735 { 2736 uint8_t fccauth[sizeof (umb_qmi_fcc_auth)]; 2737 2738 if (sc->sc_cid == -1) { 2739 DPRINTF("%s: missing CID, cannot send FCC auth\n", DEVNAM(sc)); 2740 umb_allocate_cid(sc); 2741 return; 2742 } 2743 memcpy(fccauth, umb_qmi_fcc_auth, sizeof (fccauth)); 2744 fccauth[UMB_QMI_CID_OFFS] = sc->sc_cid; 2745 umb_cmd1(sc, MBIM_CID_DEVICE_CAPS, MBIM_CMDOP_SET, 2746 fccauth, sizeof (fccauth), umb_uuid_qmi_mbim); 2747 } 2748 2749 void 2750 umb_packet_service(struct umb_softc *sc, int attach) 2751 { 2752 struct mbim_cid_packet_service s; 2753 2754 DPRINTF("%s: %s packet service\n", DEVNAM(sc), 2755 attach ? "attach" : "detach"); 2756 memset(&s, 0, sizeof (s)); 2757 s.action = htole32(attach ? 2758 MBIM_PKTSERVICE_ACTION_ATTACH : MBIM_PKTSERVICE_ACTION_DETACH); 2759 umb_cmd(sc, MBIM_CID_PACKET_SERVICE, MBIM_CMDOP_SET, &s, sizeof (s)); 2760 } 2761 2762 void 2763 umb_connect(struct umb_softc *sc) 2764 { 2765 struct ifnet *ifp = GET_IFP(sc); 2766 2767 if (sc->sc_info.regstate == MBIM_REGSTATE_ROAMING && !sc->sc_roaming) { 2768 log(LOG_INFO, "%s: connection disabled in roaming network\n", 2769 DEVNAM(sc)); 2770 return; 2771 } 2772 if (ifp->if_flags & IFF_DEBUG) 2773 log(LOG_DEBUG, "%s: connecting ...\n", DEVNAM(sc)); 2774 umb_send_connect(sc, MBIM_CONNECT_ACTIVATE); 2775 } 2776 2777 void 2778 umb_disconnect(struct umb_softc *sc) 2779 { 2780 struct ifnet *ifp = GET_IFP(sc); 2781 2782 if (ifp->if_flags & IFF_DEBUG) 2783 log(LOG_DEBUG, "%s: disconnecting ...\n", DEVNAM(sc)); 2784 umb_send_connect(sc, MBIM_CONNECT_DEACTIVATE); 2785 } 2786 2787 void 2788 umb_send_connect(struct umb_softc *sc, int command) 2789 { 2790 struct mbim_cid_connect *c; 2791 int off; 2792 2793 /* Too large or the stack */ 2794 c = malloc(sizeof (*c), M_USBDEV, M_WAIT|M_ZERO); 2795 c->sessionid = htole32(umb_session_id); 2796 c->command = htole32(command); 2797 off = offsetof(struct mbim_cid_connect, data); 2798 if (!umb_addstr(c, sizeof (*c), &off, sc->sc_info.apn, 2799 sc->sc_info.apnlen, &c->access_offs, &c->access_size)) 2800 goto done; 2801 /* XXX FIXME: support user name and passphrase */ 2802 c->user_offs = htole32(0); 2803 c->user_size = htole32(0); 2804 c->passwd_offs = htole32(0); 2805 c->passwd_size = htole32(0); 2806 c->authprot = htole32(MBIM_AUTHPROT_NONE); 2807 c->compression = htole32(MBIM_COMPRESSION_NONE); 2808 c->iptype = htole32(MBIM_CONTEXT_IPTYPE_IPV4); 2809 #ifdef INET6 2810 /* XXX FIXME: support IPv6-only mode, too */ 2811 if ((sc->sc_flags & UMBFLG_NO_INET6) == 0 && 2812 in6ifa_ifpforlinklocal(GET_IFP(sc), 0) != NULL) 2813 c->iptype = htole32(MBIM_CONTEXT_IPTYPE_IPV4V6); 2814 #endif 2815 memcpy(c->context, umb_uuid_context_internet, sizeof (c->context)); 2816 umb_cmd(sc, MBIM_CID_CONNECT, MBIM_CMDOP_SET, c, off); 2817 done: 2818 free(c, M_USBDEV, sizeof (*c)); 2819 return; 2820 } 2821 2822 void 2823 umb_qry_ipconfig(struct umb_softc *sc) 2824 { 2825 struct mbim_cid_ip_configuration_info ipc; 2826 2827 memset(&ipc, 0, sizeof (ipc)); 2828 ipc.sessionid = htole32(umb_session_id); 2829 umb_cmd(sc, MBIM_CID_IP_CONFIGURATION, MBIM_CMDOP_QRY, 2830 &ipc, sizeof (ipc)); 2831 } 2832 2833 void 2834 umb_cmd(struct umb_softc *sc, int cid, int op, void *data, int len) 2835 { 2836 umb_cmd1(sc, cid, op, data, len, umb_uuid_basic_connect); 2837 } 2838 2839 void 2840 umb_cmd1(struct umb_softc *sc, int cid, int op, void *data, int len, 2841 uint8_t *uuid) 2842 { 2843 struct mbim_h2f_cmd *cmd; 2844 int totlen; 2845 2846 /* XXX FIXME support sending fragments */ 2847 if (sizeof (*cmd) + len > sc->sc_ctrl_len) { 2848 DPRINTF("%s: set %s msg too long: cannot send\n", 2849 DEVNAM(sc), umb_cid2str(cid)); 2850 return; 2851 } 2852 cmd = sc->sc_ctrl_msg; 2853 memset(cmd, 0, sizeof (*cmd)); 2854 cmd->frag.nfrag = htole32(1); 2855 memcpy(cmd->devid, uuid, sizeof (cmd->devid)); 2856 cmd->cid = htole32(cid); 2857 cmd->op = htole32(op); 2858 cmd->infolen = htole32(len); 2859 totlen = sizeof (*cmd); 2860 if (len > 0) { 2861 memcpy(cmd + 1, data, len); 2862 totlen += len; 2863 } 2864 umb_ctrl_msg(sc, MBIM_COMMAND_MSG, cmd, totlen); 2865 } 2866 2867 void 2868 umb_command_done(struct umb_softc *sc, void *data, int len) 2869 { 2870 struct mbim_f2h_cmddone *cmd = data; 2871 struct ifnet *ifp = GET_IFP(sc); 2872 uint32_t status; 2873 uint32_t cid; 2874 uint32_t infolen; 2875 int qmimsg = 0; 2876 2877 if (len < sizeof (*cmd)) { 2878 DPRINTF("%s: discard short %s message\n", DEVNAM(sc), 2879 umb_request2str(letoh32(cmd->hdr.type))); 2880 return; 2881 } 2882 cid = letoh32(cmd->cid); 2883 if (memcmp(cmd->devid, umb_uuid_basic_connect, sizeof (cmd->devid))) { 2884 if (memcmp(cmd->devid, umb_uuid_qmi_mbim, 2885 sizeof (cmd->devid))) { 2886 DPRINTF("%s: discard %s message for other UUID '%s'\n", 2887 DEVNAM(sc), umb_request2str(letoh32(cmd->hdr.type)), 2888 umb_uuid2str(cmd->devid)); 2889 return; 2890 } else 2891 qmimsg = 1; 2892 } 2893 2894 status = letoh32(cmd->status); 2895 switch (status) { 2896 case MBIM_STATUS_SUCCESS: 2897 break; 2898 #ifdef INET6 2899 case MBIM_STATUS_NO_DEVICE_SUPPORT: 2900 if ((cid == MBIM_CID_CONNECT) && 2901 (sc->sc_flags & UMBFLG_NO_INET6) == 0) { 2902 sc->sc_flags |= UMBFLG_NO_INET6; 2903 if (ifp->if_flags & IFF_DEBUG) 2904 log(LOG_ERR, 2905 "%s: device does not support IPv6\n", 2906 DEVNAM(sc)); 2907 } 2908 /* Re-trigger the connect, this time IPv4 only */ 2909 usb_add_task(sc->sc_udev, &sc->sc_umb_task); 2910 return; 2911 #endif 2912 case MBIM_STATUS_NOT_INITIALIZED: 2913 if (ifp->if_flags & IFF_DEBUG) 2914 log(LOG_ERR, "%s: SIM not initialized (PIN missing)\n", 2915 DEVNAM(sc)); 2916 return; 2917 case MBIM_STATUS_PIN_REQUIRED: 2918 sc->sc_info.pin_state = UMB_PIN_REQUIRED; 2919 /*FALLTHROUGH*/ 2920 default: 2921 if (ifp->if_flags & IFF_DEBUG) 2922 log(LOG_ERR, "%s: set/qry %s failed: %s\n", DEVNAM(sc), 2923 umb_cid2str(cid), umb_status2str(status)); 2924 return; 2925 } 2926 2927 infolen = letoh32(cmd->infolen); 2928 if (len < sizeof (*cmd) + infolen) { 2929 DPRINTF("%s: discard truncated %s message (want %d, got %d)\n", 2930 DEVNAM(sc), umb_cid2str(cid), 2931 (int)sizeof (*cmd) + infolen, len); 2932 return; 2933 } 2934 if (qmimsg) { 2935 if (sc->sc_flags & UMBFLG_FCC_AUTH_REQUIRED) 2936 umb_decode_qmi(sc, cmd->info, infolen); 2937 } else { 2938 DPRINTFN(2, "%s: set/qry %s done\n", DEVNAM(sc), 2939 umb_cid2str(cid)); 2940 umb_decode_cid(sc, cid, cmd->info, infolen); 2941 } 2942 } 2943 2944 void 2945 umb_decode_cid(struct umb_softc *sc, uint32_t cid, void *data, int len) 2946 { 2947 int ok = 1; 2948 2949 switch (cid) { 2950 case MBIM_CID_DEVICE_CAPS: 2951 ok = umb_decode_devices_caps(sc, data, len); 2952 break; 2953 case MBIM_CID_SUBSCRIBER_READY_STATUS: 2954 ok = umb_decode_subscriber_status(sc, data, len); 2955 break; 2956 case MBIM_CID_RADIO_STATE: 2957 ok = umb_decode_radio_state(sc, data, len); 2958 break; 2959 case MBIM_CID_PIN: 2960 ok = umb_decode_pin(sc, data, len); 2961 break; 2962 case MBIM_CID_REGISTER_STATE: 2963 ok = umb_decode_register_state(sc, data, len); 2964 break; 2965 case MBIM_CID_PACKET_SERVICE: 2966 ok = umb_decode_packet_service(sc, data, len); 2967 break; 2968 case MBIM_CID_SIGNAL_STATE: 2969 ok = umb_decode_signal_state(sc, data, len); 2970 break; 2971 case MBIM_CID_CONNECT: 2972 ok = umb_decode_connect_info(sc, data, len); 2973 break; 2974 case MBIM_CID_IP_CONFIGURATION: 2975 ok = umb_decode_ip_configuration(sc, data, len); 2976 break; 2977 default: 2978 /* 2979 * Note: the above list is incomplete and only contains 2980 * mandatory CIDs from the BASIC_CONNECT set. 2981 * So alternate values are not unusual. 2982 */ 2983 DPRINTFN(4, "%s: ignore %s\n", DEVNAM(sc), umb_cid2str(cid)); 2984 break; 2985 } 2986 if (!ok) 2987 DPRINTF("%s: discard %s with bad info length %d\n", 2988 DEVNAM(sc), umb_cid2str(cid), len); 2989 return; 2990 } 2991 2992 void 2993 umb_decode_qmi(struct umb_softc *sc, uint8_t *data, int len) 2994 { 2995 uint8_t srv; 2996 uint16_t msg, tlvlen; 2997 uint32_t val; 2998 2999 #define UMB_QMI_QMUXLEN 6 3000 if (len < UMB_QMI_QMUXLEN) 3001 goto tooshort; 3002 3003 srv = data[4]; 3004 data += UMB_QMI_QMUXLEN; 3005 len -= UMB_QMI_QMUXLEN; 3006 3007 #define UMB_GET16(p) ((uint16_t)*p | (uint16_t)*(p + 1) << 8) 3008 #define UMB_GET32(p) ((uint32_t)*p | (uint32_t)*(p + 1) << 8 | \ 3009 (uint32_t)*(p + 2) << 16 |(uint32_t)*(p + 3) << 24) 3010 switch (srv) { 3011 case 0: /* ctl */ 3012 #define UMB_QMI_CTLLEN 6 3013 if (len < UMB_QMI_CTLLEN) 3014 goto tooshort; 3015 msg = UMB_GET16(&data[2]); 3016 tlvlen = UMB_GET16(&data[4]); 3017 data += UMB_QMI_CTLLEN; 3018 len -= UMB_QMI_CTLLEN; 3019 break; 3020 case 2: /* dms */ 3021 #define UMB_QMI_DMSLEN 7 3022 if (len < UMB_QMI_DMSLEN) 3023 goto tooshort; 3024 msg = UMB_GET16(&data[3]); 3025 tlvlen = UMB_GET16(&data[5]); 3026 data += UMB_QMI_DMSLEN; 3027 len -= UMB_QMI_DMSLEN; 3028 break; 3029 default: 3030 DPRINTF("%s: discard QMI message for unknown service type %d\n", 3031 DEVNAM(sc), srv); 3032 return; 3033 } 3034 3035 if (len < tlvlen) 3036 goto tooshort; 3037 3038 #define UMB_QMI_TLVLEN 3 3039 while (len > 0) { 3040 if (len < UMB_QMI_TLVLEN) 3041 goto tooshort; 3042 tlvlen = UMB_GET16(&data[1]); 3043 if (len < UMB_QMI_TLVLEN + tlvlen) 3044 goto tooshort; 3045 switch (data[0]) { 3046 case 1: /* allocation info */ 3047 if (msg == 0x0022) { /* Allocate CID */ 3048 if (tlvlen != 2 || data[3] != 2) /* dms */ 3049 break; 3050 sc->sc_cid = data[4]; 3051 DPRINTF("%s: QMI CID %d allocated\n", 3052 DEVNAM(sc), sc->sc_cid); 3053 umb_newstate(sc, UMB_S_CID, UMB_NS_DONT_DROP); 3054 } 3055 break; 3056 case 2: /* response */ 3057 if (tlvlen != sizeof (val)) 3058 break; 3059 val = UMB_GET32(&data[3]); 3060 switch (msg) { 3061 case 0x0022: /* Allocate CID */ 3062 if (val != 0) { 3063 log(LOG_ERR, "%s: allocation of QMI CID" 3064 " failed, error 0x%x\n", DEVNAM(sc), 3065 val); 3066 /* XXX how to proceed? */ 3067 return; 3068 } 3069 break; 3070 case 0x555f: /* Send FCC Authentication */ 3071 if (val == 0) 3072 DPRINTF("%s: send FCC " 3073 "Authentication succeeded\n", 3074 DEVNAM(sc)); 3075 else if (val == 0x001a0001) 3076 DPRINTF("%s: FCC Authentication " 3077 "not required\n", DEVNAM(sc)); 3078 else 3079 log(LOG_INFO, "%s: send FCC " 3080 "Authentication failed, " 3081 "error 0x%x\n", DEVNAM(sc), val); 3082 3083 /* FCC Auth is needed only once after power-on*/ 3084 sc->sc_flags &= ~UMBFLG_FCC_AUTH_REQUIRED; 3085 3086 /* Try to proceed anyway */ 3087 DPRINTF("%s: init: turning radio on ...\n", 3088 DEVNAM(sc)); 3089 umb_radio(sc, 1); 3090 break; 3091 default: 3092 break; 3093 } 3094 break; 3095 default: 3096 break; 3097 } 3098 data += UMB_QMI_TLVLEN + tlvlen; 3099 len -= UMB_QMI_TLVLEN + tlvlen; 3100 } 3101 return; 3102 3103 tooshort: 3104 DPRINTF("%s: discard short QMI message\n", DEVNAM(sc)); 3105 return; 3106 } 3107 3108 void 3109 umb_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) 3110 { 3111 struct umb_softc *sc = priv; 3112 struct ifnet *ifp = GET_IFP(sc); 3113 int total_len; 3114 3115 if (status != USBD_NORMAL_COMPLETION) { 3116 DPRINTF("%s: notification error: %s\n", DEVNAM(sc), 3117 usbd_errstr(status)); 3118 if (status == USBD_STALLED) 3119 usbd_clear_endpoint_stall_async(sc->sc_ctrl_pipe); 3120 return; 3121 } 3122 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 3123 if (total_len < UCDC_NOTIFICATION_LENGTH) { 3124 DPRINTF("%s: short notification (%d<%d)\n", DEVNAM(sc), 3125 total_len, UCDC_NOTIFICATION_LENGTH); 3126 return; 3127 } 3128 if (sc->sc_intr_msg.bmRequestType != UCDC_NOTIFICATION) { 3129 DPRINTF("%s: unexpected notification (type=0x%02x)\n", 3130 DEVNAM(sc), sc->sc_intr_msg.bmRequestType); 3131 return; 3132 } 3133 3134 switch (sc->sc_intr_msg.bNotification) { 3135 case UCDC_N_NETWORK_CONNECTION: 3136 if (ifp->if_flags & IFF_DEBUG) 3137 log(LOG_DEBUG, "%s: network %sconnected\n", DEVNAM(sc), 3138 UGETW(sc->sc_intr_msg.wValue) ? "" : "dis"); 3139 break; 3140 case UCDC_N_RESPONSE_AVAILABLE: 3141 DPRINTFN(2, "%s: umb_intr: response available\n", DEVNAM(sc)); 3142 ++sc->sc_nresp; 3143 usb_add_task(sc->sc_udev, &sc->sc_get_response_task); 3144 break; 3145 case UCDC_N_CONNECTION_SPEED_CHANGE: 3146 DPRINTFN(2, "%s: umb_intr: connection speed changed\n", 3147 DEVNAM(sc)); 3148 break; 3149 default: 3150 DPRINTF("%s: unexpected notifiation (0x%02x)\n", 3151 DEVNAM(sc), sc->sc_intr_msg.bNotification); 3152 break; 3153 } 3154 } 3155 3156 /* 3157 * Diagnostic routines 3158 */ 3159 #ifdef UMB_DEBUG 3160 char * 3161 umb_uuid2str(uint8_t uuid[MBIM_UUID_LEN]) 3162 { 3163 static char uuidstr[2 * MBIM_UUID_LEN + 5]; 3164 3165 #define UUID_BFMT "%02X" 3166 #define UUID_SEP "-" 3167 snprintf(uuidstr, sizeof (uuidstr), 3168 UUID_BFMT UUID_BFMT UUID_BFMT UUID_BFMT UUID_SEP 3169 UUID_BFMT UUID_BFMT UUID_SEP 3170 UUID_BFMT UUID_BFMT UUID_SEP 3171 UUID_BFMT UUID_BFMT UUID_SEP 3172 UUID_BFMT UUID_BFMT UUID_BFMT UUID_BFMT UUID_BFMT UUID_BFMT, 3173 uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], 3174 uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11], 3175 uuid[12], uuid[13], uuid[14], uuid[15]); 3176 return uuidstr; 3177 } 3178 3179 void 3180 umb_dump(void *buf, int len) 3181 { 3182 int i = 0; 3183 uint8_t *c = buf; 3184 3185 if (len == 0) 3186 return; 3187 while (i < len) { 3188 if ((i % 16) == 0) { 3189 if (i > 0) 3190 addlog("\n"); 3191 log(LOG_DEBUG, "%4d: ", i); 3192 } 3193 addlog(" %02x", *c); 3194 c++; 3195 i++; 3196 } 3197 addlog("\n"); 3198 } 3199 #endif /* UMB_DEBUG */ 3200