1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Original copyright (c) 2016 genua mbH (OpenBSD version) 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 * Copyright (c) 2022 ADISTA SAS (re-write for FreeBSD) 19 * 20 * Re-write for FreeBSD by Pierre Pronchery <pierre@defora.net> 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions are met: 24 * 25 * - Redistributions of source code must retain the above copyright notice, 26 * this list of conditions and the following disclaimer. 27 * - Redistributions in binary form must reproduce the above copyright notice, 28 * this list of conditions and the following disclaimer in the documentation 29 * and/or other materials provided with the distribution. 30 * - Neither the name of the copyright holder nor the names of its contributors 31 * may be used to endorse or promote products derived from this software 32 * without specific prior written permission. 33 * 34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 35 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 37 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 38 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 39 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 40 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 41 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 42 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 44 * POSSIBILITY OF SUCH DAMAGE. 45 * 46 * $NetBSD: if_umb.c,v 1.5 2018/09/20 09:45:16 khorben Exp $ 47 * $OpenBSD: if_umb.c,v 1.18 2018/02/19 08:59:52 mpi Exp $ 48 */ 49 50 /* 51 * Mobile Broadband Interface Model specification: 52 * http://www.usb.org/developers/docs/devclass_docs/MBIM10Errata1_073013.zip 53 * Compliance testing guide 54 * http://www.usb.org/developers/docs/devclass_docs/MBIM-Compliance-1.0.pdf 55 */ 56 57 #include <sys/param.h> 58 #include <sys/module.h> 59 #include <sys/endian.h> 60 #include <sys/kernel.h> 61 #include <sys/mbuf.h> 62 #include <sys/priv.h> 63 #include <sys/socket.h> 64 #include <sys/sockio.h> 65 #include <sys/systm.h> 66 #include <sys/syslog.h> 67 #include <sys/kernel.h> 68 #include <sys/queue.h> 69 70 #include <sys/conf.h> 71 #include <sys/bus.h> 72 #include <sys/mutex.h> 73 #include <sys/condvar.h> 74 #include <sys/taskqueue.h> 75 76 #include <machine/_inttypes.h> 77 78 #include <net/bpf.h> 79 #include <net/if.h> 80 #include <net/if_media.h> 81 #include <net/if_types.h> 82 #include <net/if_var.h> 83 #include <net/netisr.h> 84 #include <net/route.h> 85 86 #include <netinet/in.h> 87 #include <netinet/in_var.h> 88 #include <netinet/ip.h> 89 90 #include <dev/usb/usb.h> 91 #include <dev/usb/usb_cdc.h> 92 #include <dev/usb/usbdi.h> 93 #include <dev/usb/usb_device.h> 94 #include <dev/usb/usb_process.h> 95 #include <dev/usb/usbdi_util.h> 96 #include "usb_if.h" 97 98 #include "mbim.h" 99 #include "if_umbreg.h" 100 101 MALLOC_DECLARE(M_MBIM_CID_CONNECT); 102 MALLOC_DEFINE(M_MBIM_CID_CONNECT, "mbim_cid_connect", 103 "Connection parameters for MBIM"); 104 105 #ifdef UMB_DEBUG 106 #define DPRINTF(x...) \ 107 do { if (umb_debug) log(LOG_DEBUG, x); } while (0) 108 109 #define DPRINTFN(n, x...) \ 110 do { if (umb_debug >= (n)) log(LOG_DEBUG, x); } while (0) 111 112 #define DDUMPN(n, b, l) \ 113 do { \ 114 if (umb_debug >= (n)) \ 115 umb_dump((b), (l)); \ 116 } while (0) 117 118 const int umb_debug = 1; 119 static char *umb_uuid2str(uint8_t [MBIM_UUID_LEN]); 120 static void umb_dump(void *, int); 121 122 #else 123 #define DPRINTF(x...) do { } while (0) 124 #define DPRINTFN(n, x...) do { } while (0) 125 #define DDUMPN(n, b, l) do { } while (0) 126 #endif 127 128 #define DEVNAM(sc) device_get_nameunit((sc)->sc_dev) 129 130 /* 131 * State change timeout 132 */ 133 #define UMB_STATE_CHANGE_TIMEOUT 30 134 135 /* 136 * State change flags 137 */ 138 #define UMB_NS_DONT_DROP 0x0001 /* do not drop below current state */ 139 #define UMB_NS_DONT_RAISE 0x0002 /* do not raise below current state */ 140 141 /* 142 * Diagnostic macros 143 */ 144 const struct umb_valdescr umb_regstates[] = MBIM_REGSTATE_DESCRIPTIONS; 145 const struct umb_valdescr umb_dataclasses[] = MBIM_DATACLASS_DESCRIPTIONS; 146 const struct umb_valdescr umb_simstate[] = MBIM_SIMSTATE_DESCRIPTIONS; 147 const struct umb_valdescr umb_messages[] = MBIM_MESSAGES_DESCRIPTIONS; 148 const struct umb_valdescr umb_status[] = MBIM_STATUS_DESCRIPTIONS; 149 const struct umb_valdescr umb_cids[] = MBIM_CID_DESCRIPTIONS; 150 const struct umb_valdescr umb_pktstate[] = MBIM_PKTSRV_STATE_DESCRIPTIONS; 151 const struct umb_valdescr umb_actstate[] = MBIM_ACTIVATION_STATE_DESCRIPTIONS; 152 const struct umb_valdescr umb_error[] = MBIM_ERROR_DESCRIPTIONS; 153 const struct umb_valdescr umb_pintype[] = MBIM_PINTYPE_DESCRIPTIONS; 154 const struct umb_valdescr umb_istate[] = UMB_INTERNAL_STATE_DESCRIPTIONS; 155 156 #define umb_regstate(c) umb_val2descr(umb_regstates, (c)) 157 #define umb_dataclass(c) umb_val2descr(umb_dataclasses, (c)) 158 #define umb_simstate(s) umb_val2descr(umb_simstate, (s)) 159 #define umb_request2str(m) umb_val2descr(umb_messages, (m)) 160 #define umb_status2str(s) umb_val2descr(umb_status, (s)) 161 #define umb_cid2str(c) umb_val2descr(umb_cids, (c)) 162 #define umb_packet_state(s) umb_val2descr(umb_pktstate, (s)) 163 #define umb_activation(s) umb_val2descr(umb_actstate, (s)) 164 #define umb_error2str(e) umb_val2descr(umb_error, (e)) 165 #define umb_pin_type(t) umb_val2descr(umb_pintype, (t)) 166 #define umb_istate(s) umb_val2descr(umb_istate, (s)) 167 168 static device_probe_t umb_probe; 169 static device_attach_t umb_attach; 170 static device_detach_t umb_detach; 171 static device_suspend_t umb_suspend; 172 static device_resume_t umb_resume; 173 static void umb_attach_task(struct usb_proc_msg *); 174 static usb_handle_request_t umb_handle_request; 175 static int umb_deactivate(device_t); 176 static void umb_ncm_setup(struct umb_softc *, struct usb_config *); 177 static void umb_close_bulkpipes(struct umb_softc *); 178 static int umb_ioctl(if_t , u_long, caddr_t); 179 static void umb_init(void *); 180 #ifdef DEV_NETMAP 181 static void umb_input(if_t , struct mbuf *); 182 #endif 183 static int umb_output(if_t , struct mbuf *, 184 const struct sockaddr *, struct route *); 185 static void umb_start(if_t ); 186 static void umb_start_task(struct usb_proc_msg *); 187 #if 0 188 static void umb_watchdog(if_t ); 189 #endif 190 static void umb_statechg_timeout(void *); 191 192 static int umb_mediachange(if_t ); 193 static void umb_mediastatus(if_t , struct ifmediareq *); 194 195 static void umb_add_task(struct umb_softc *sc, usb_proc_callback_t, 196 struct usb_proc_msg *, struct usb_proc_msg *, int); 197 static void umb_newstate(struct umb_softc *, enum umb_state, int); 198 static void umb_state_task(struct usb_proc_msg *); 199 static void umb_up(struct umb_softc *); 200 static void umb_down(struct umb_softc *, int); 201 202 static void umb_get_response_task(struct usb_proc_msg *); 203 204 static void umb_decode_response(struct umb_softc *, void *, int); 205 static void umb_handle_indicate_status_msg(struct umb_softc *, void *, 206 int); 207 static void umb_handle_opendone_msg(struct umb_softc *, void *, int); 208 static void umb_handle_closedone_msg(struct umb_softc *, void *, int); 209 static int umb_decode_register_state(struct umb_softc *, void *, int); 210 static int umb_decode_devices_caps(struct umb_softc *, void *, int); 211 static int umb_decode_subscriber_status(struct umb_softc *, void *, int); 212 static int umb_decode_radio_state(struct umb_softc *, void *, int); 213 static int umb_decode_pin(struct umb_softc *, void *, int); 214 static int umb_decode_packet_service(struct umb_softc *, void *, int); 215 static int umb_decode_signal_state(struct umb_softc *, void *, int); 216 static int umb_decode_connect_info(struct umb_softc *, void *, int); 217 static int umb_decode_ip_configuration(struct umb_softc *, void *, int); 218 static void umb_rx(struct umb_softc *); 219 static usb_callback_t umb_rxeof; 220 static void umb_rxflush(struct umb_softc *); 221 static int umb_encap(struct umb_softc *, struct mbuf *, struct usb_xfer *); 222 static usb_callback_t umb_txeof; 223 static void umb_txflush(struct umb_softc *); 224 static void umb_decap(struct umb_softc *, struct usb_xfer *, int); 225 226 static usb_error_t umb_send_encap_command(struct umb_softc *, void *, int); 227 static int umb_get_encap_response(struct umb_softc *, void *, int *); 228 static void umb_ctrl_msg(struct umb_softc *, uint32_t, void *, int); 229 230 static void umb_open(struct umb_softc *); 231 static void umb_close(struct umb_softc *); 232 233 static int umb_setpin(struct umb_softc *, int, int, void *, int, void *, 234 int); 235 static void umb_setdataclass(struct umb_softc *); 236 static void umb_radio(struct umb_softc *, int); 237 static void umb_allocate_cid(struct umb_softc *); 238 static void umb_send_fcc_auth(struct umb_softc *); 239 static void umb_packet_service(struct umb_softc *, int); 240 static void umb_connect(struct umb_softc *); 241 static void umb_disconnect(struct umb_softc *); 242 static void umb_send_connect(struct umb_softc *, int); 243 244 static void umb_qry_ipconfig(struct umb_softc *); 245 static void umb_cmd(struct umb_softc *, int, int, const void *, int); 246 static void umb_cmd1(struct umb_softc *, int, int, const void *, int, uint8_t *); 247 static void umb_command_done(struct umb_softc *, void *, int); 248 static void umb_decode_cid(struct umb_softc *, uint32_t, void *, int); 249 static void umb_decode_qmi(struct umb_softc *, uint8_t *, int); 250 251 static usb_callback_t umb_intr; 252 253 static char *umb_ntop(struct sockaddr *); 254 255 static const int umb_xfer_tout = USB_DEFAULT_TIMEOUT; 256 257 static uint8_t umb_uuid_basic_connect[] = MBIM_UUID_BASIC_CONNECT; 258 static uint8_t umb_uuid_context_internet[] = MBIM_UUID_CONTEXT_INTERNET; 259 static uint8_t umb_uuid_qmi_mbim[] = MBIM_UUID_QMI_MBIM; 260 static uint32_t umb_session_id = 0; 261 262 static const struct usb_config umb_config[UMB_N_TRANSFER] = { 263 [UMB_INTR_RX] = { 264 .type = UE_INTERRUPT, 265 .endpoint = UE_ADDR_ANY, 266 .direction = UE_DIR_IN, 267 .if_index = 1, 268 .callback = umb_intr, 269 .bufsize = sizeof (struct usb_cdc_notification), 270 .flags = {.pipe_bof = 1,.short_xfer_ok = 1}, 271 .usb_mode = USB_MODE_HOST, 272 }, 273 [UMB_BULK_RX] = { 274 .type = UE_BULK, 275 .endpoint = UE_ADDR_ANY, 276 .direction = UE_DIR_IN, 277 .if_index = 0, 278 .callback = umb_rxeof, 279 .bufsize = 8 * 1024, 280 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,.ext_buffer = 1}, 281 .usb_mode = USB_MODE_HOST, 282 }, 283 [UMB_BULK_TX] = { 284 .type = UE_BULK, 285 .endpoint = UE_ADDR_ANY, 286 .direction = UE_DIR_OUT, 287 .if_index = 0, 288 .callback = umb_txeof, 289 .bufsize = 8 * 1024, 290 .flags = {.pipe_bof = 1,.force_short_xfer = 1,.ext_buffer = 1}, 291 .timeout = umb_xfer_tout, 292 .usb_mode = USB_MODE_HOST, 293 }, 294 }; 295 296 static device_method_t umb_methods[] = { 297 /* USB interface */ 298 DEVMETHOD(usb_handle_request, umb_handle_request), 299 300 /* Device interface */ 301 DEVMETHOD(device_probe, umb_probe), 302 DEVMETHOD(device_attach, umb_attach), 303 DEVMETHOD(device_detach, umb_detach), 304 DEVMETHOD(device_suspend, umb_suspend), 305 DEVMETHOD(device_resume, umb_resume), 306 307 DEVMETHOD_END 308 }; 309 310 static driver_t umb_driver = { 311 .name = "umb", 312 .methods = umb_methods, 313 .size = sizeof (struct umb_softc), 314 }; 315 316 MALLOC_DEFINE(M_USB_UMB, "USB UMB", "USB MBIM driver"); 317 318 const int umb_delay = 4000; 319 320 /* 321 * These devices require an "FCC Authentication" command. 322 */ 323 #ifndef USB_VENDOR_SIERRA 324 # define USB_VENDOR_SIERRA 0x1199 325 #endif 326 #ifndef USB_PRODUCT_SIERRA_EM7455 327 # define USB_PRODUCT_SIERRA_EM7455 0x9079 328 #endif 329 const struct usb_device_id umb_fccauth_devs[] = { 330 { 331 .match_flag_vendor = 1, 332 .match_flag_product = 1, 333 .idVendor = USB_VENDOR_SIERRA, 334 .idProduct = USB_PRODUCT_SIERRA_EM7455 335 } 336 }; 337 338 static const uint8_t umb_qmi_alloc_cid[] = { 339 0x01, 340 0x0f, 0x00, /* len */ 341 0x00, /* QMUX flags */ 342 0x00, /* service "ctl" */ 343 0x00, /* CID */ 344 0x00, /* QMI flags */ 345 0x01, /* transaction */ 346 0x22, 0x00, /* msg "Allocate CID" */ 347 0x04, 0x00, /* TLV len */ 348 0x01, 0x01, 0x00, 0x02 /* TLV */ 349 }; 350 351 static const uint8_t umb_qmi_fcc_auth[] = { 352 0x01, 353 0x0c, 0x00, /* len */ 354 0x00, /* QMUX flags */ 355 0x02, /* service "dms" */ 356 #define UMB_QMI_CID_OFFS 5 357 0x00, /* CID (filled in later) */ 358 0x00, /* QMI flags */ 359 0x01, 0x00, /* transaction */ 360 0x5f, 0x55, /* msg "Send FCC Authentication" */ 361 0x00, 0x00 /* TLV len */ 362 }; 363 364 static int 365 umb_probe(device_t dev) 366 { 367 struct usb_attach_arg *uaa = device_get_ivars(dev); 368 usb_interface_descriptor_t *id; 369 370 if (uaa->usb_mode != USB_MODE_HOST) 371 return (ENXIO); 372 if ((id = usbd_get_interface_descriptor(uaa->iface)) == NULL) 373 return (ENXIO); 374 375 /* 376 * If this function implements NCM, check if alternate setting 377 * 1 implements MBIM. 378 */ 379 if (id->bInterfaceClass == UICLASS_CDC && 380 id->bInterfaceSubClass == 381 UISUBCLASS_NETWORK_CONTROL_MODEL) { 382 id = usbd_get_interface_descriptor( 383 usbd_get_iface(uaa->device, 384 uaa->info.bIfaceIndex + 1)); 385 if (id == NULL || id->bAlternateSetting != 1) 386 return (ENXIO); 387 } 388 389 #ifndef UISUBCLASS_MOBILE_BROADBAND_INTERFACE_MODEL 390 # define UISUBCLASS_MOBILE_BROADBAND_INTERFACE_MODEL 14 391 #endif 392 if (id->bInterfaceClass == UICLASS_CDC && 393 id->bInterfaceSubClass == 394 UISUBCLASS_MOBILE_BROADBAND_INTERFACE_MODEL && 395 id->bInterfaceProtocol == 0) 396 return (BUS_PROBE_SPECIFIC); 397 398 return (ENXIO); 399 } 400 401 static int 402 umb_attach(device_t dev) 403 { 404 struct umb_softc *sc = device_get_softc(dev); 405 struct usb_attach_arg *uaa = device_get_ivars(dev); 406 struct usb_config config[UMB_N_TRANSFER]; 407 int v; 408 const struct usb_cdc_union_descriptor *ud; 409 const struct mbim_descriptor *md; 410 int i; 411 usb_interface_descriptor_t *id; 412 struct usb_interface *iface; 413 int data_ifaceno = -1; 414 usb_error_t error; 415 416 sc->sc_dev = dev; 417 sc->sc_udev = uaa->device; 418 419 memcpy(config, umb_config, sizeof (config)); 420 421 device_set_usb_desc(dev); 422 423 sc->sc_ctrl_ifaceno = uaa->info.bIfaceNum; 424 425 mtx_init(&sc->sc_mutex, device_get_nameunit(dev), NULL, MTX_DEF); 426 427 /* 428 * Some MBIM hardware does not provide the mandatory CDC Union 429 * Descriptor, so we also look at matching Interface 430 * Association Descriptors to find out the MBIM Data Interface 431 * number. 432 */ 433 sc->sc_ver_maj = sc->sc_ver_min = -1; 434 sc->sc_maxpktlen = MBIM_MAXSEGSZ_MINVAL; 435 id = usbd_get_interface_descriptor(uaa->iface); 436 437 ud = usbd_find_descriptor(sc->sc_udev, id, uaa->info.bIfaceIndex, 438 UDESC_CS_INTERFACE, 0xff, UDESCSUB_CDC_UNION, 0xff); 439 if (ud != NULL) { 440 data_ifaceno = ud->bSlaveInterface[0]; 441 } 442 443 md = usbd_find_descriptor(sc->sc_udev, id, uaa->info.bIfaceIndex, 444 UDESC_CS_INTERFACE, 0xff, UDESCSUB_MBIM, 0xff); 445 if (md != NULL) { 446 v = UGETW(md->bcdMBIMVersion); 447 sc->sc_ver_maj = MBIM_VER_MAJOR(v); 448 sc->sc_ver_min = MBIM_VER_MINOR(v); 449 sc->sc_ctrl_len = UGETW(md->wMaxControlMessage); 450 /* Never trust a USB device! Could try to exploit us */ 451 if (sc->sc_ctrl_len < MBIM_CTRLMSG_MINLEN || 452 sc->sc_ctrl_len > MBIM_CTRLMSG_MAXLEN) { 453 DPRINTF("control message len %d out of " 454 "bounds [%d .. %d]\n", 455 sc->sc_ctrl_len, MBIM_CTRLMSG_MINLEN, 456 MBIM_CTRLMSG_MAXLEN); 457 /* continue anyway */ 458 } 459 sc->sc_maxpktlen = UGETW(md->wMaxSegmentSize); 460 DPRINTFN(2, "ctrl_len=%d, maxpktlen=%d, cap=0x%x\n", 461 sc->sc_ctrl_len, sc->sc_maxpktlen, 462 md->bmNetworkCapabilities); 463 } 464 if (sc->sc_ver_maj < 0) { 465 device_printf(dev, "error: missing MBIM descriptor\n"); 466 goto fail; 467 } 468 469 device_printf(dev, "version %d.%d\n", sc->sc_ver_maj, 470 sc->sc_ver_min); 471 472 if (usbd_lookup_id_by_uaa(umb_fccauth_devs, sizeof (umb_fccauth_devs), 473 uaa)) { 474 sc->sc_flags |= UMBFLG_FCC_AUTH_REQUIRED; 475 sc->sc_cid = -1; 476 } 477 478 for (i = 0; i < sc->sc_udev->ifaces_max; i++) { 479 iface = usbd_get_iface(sc->sc_udev, i); 480 id = usbd_get_interface_descriptor(iface); 481 if (id == NULL) 482 break; 483 484 if (id->bInterfaceNumber == data_ifaceno) { 485 sc->sc_data_iface = iface; 486 sc->sc_ifaces_index[0] = i; 487 sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex; 488 break; 489 } 490 } 491 if (sc->sc_data_iface == NULL) { 492 device_printf(dev, "error: no data interface found\n"); 493 goto fail; 494 } 495 496 /* 497 * If this is a combined NCM/MBIM function, switch to 498 * alternate setting one to enable MBIM. 499 */ 500 id = usbd_get_interface_descriptor(uaa->iface); 501 if (id != NULL && id->bInterfaceClass == UICLASS_CDC && 502 id->bInterfaceSubClass == UISUBCLASS_NETWORK_CONTROL_MODEL) { 503 device_printf(sc->sc_dev, "combined NCM/MBIM\n"); 504 error = usbd_req_set_alt_interface_no(sc->sc_udev, 505 NULL, uaa->info.bIfaceIndex, 1); 506 if (error != USB_ERR_NORMAL_COMPLETION) { 507 device_printf(dev, "error: Could not switch to" 508 " alternate setting for MBIM\n"); 509 goto fail; 510 } 511 sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex + 1; 512 } 513 514 if (usb_proc_create(&sc->sc_taskqueue, &sc->sc_mutex, 515 device_get_nameunit(sc->sc_dev), 516 USB_PRI_MED) != 0) 517 goto fail; 518 519 DPRINTFN(2, "ctrl-ifno#%d: data-ifno#%d\n", sc->sc_ctrl_ifaceno, 520 data_ifaceno); 521 522 usb_callout_init_mtx(&sc->sc_statechg_timer, &sc->sc_mutex, 0); 523 524 umb_ncm_setup(sc, config); 525 DPRINTFN(2, "%s: rx/tx size %d/%d\n", DEVNAM(sc), 526 sc->sc_rx_bufsz, sc->sc_tx_bufsz); 527 528 sc->sc_rx_buf = malloc(sc->sc_rx_bufsz, M_DEVBUF, M_WAITOK); 529 sc->sc_tx_buf = malloc(sc->sc_tx_bufsz, M_DEVBUF, M_WAITOK); 530 531 for (i = 0; i != 32; i++) { 532 error = usbd_set_alt_interface_index(sc->sc_udev, 533 sc->sc_ifaces_index[0], i); 534 if (error) 535 break; 536 537 error = usbd_transfer_setup(sc->sc_udev, sc->sc_ifaces_index, 538 sc->sc_xfer, config, UMB_N_TRANSFER, 539 sc, &sc->sc_mutex); 540 if (error == USB_ERR_NORMAL_COMPLETION) 541 break; 542 } 543 if (error || (i == 32)) { 544 device_printf(sc->sc_dev, "error: failed to setup xfers\n"); 545 goto fail; 546 } 547 548 sc->sc_resp_buf = malloc(sc->sc_ctrl_len, M_DEVBUF, M_WAITOK); 549 sc->sc_ctrl_msg = malloc(sc->sc_ctrl_len, M_DEVBUF, M_WAITOK); 550 551 sc->sc_info.regstate = MBIM_REGSTATE_UNKNOWN; 552 sc->sc_info.pin_attempts_left = UMB_VALUE_UNKNOWN; 553 sc->sc_info.rssi = UMB_VALUE_UNKNOWN; 554 sc->sc_info.ber = UMB_VALUE_UNKNOWN; 555 556 /* defer attaching the interface */ 557 mtx_lock(&sc->sc_mutex); 558 umb_add_task(sc, umb_attach_task, 559 &sc->sc_proc_attach_task[0].hdr, 560 &sc->sc_proc_attach_task[1].hdr, 0); 561 mtx_unlock(&sc->sc_mutex); 562 563 return (0); 564 565 fail: 566 umb_detach(sc->sc_dev); 567 return (ENXIO); 568 } 569 570 static void 571 umb_attach_task(struct usb_proc_msg *msg) 572 { 573 struct umb_task *task = (struct umb_task *)msg; 574 struct umb_softc *sc = task->sc; 575 if_t ifp; 576 577 mtx_unlock(&sc->sc_mutex); 578 579 CURVNET_SET_QUIET(vnet0); 580 581 /* initialize the interface */ 582 sc->sc_if = ifp = if_alloc(IFT_MBIM); 583 if_initname(ifp, "umb", device_get_unit(sc->sc_dev)); 584 585 if_setsoftc(ifp, sc); 586 if_setflags(ifp, IFF_SIMPLEX | IFF_MULTICAST | IFF_POINTOPOINT); 587 if_setioctlfn(ifp, umb_ioctl); 588 #ifdef DEV_NETMAP 589 if_setinputfn(ifp, umb_input); 590 #endif 591 if_setoutputfn(ifp, umb_output); 592 if_setstartfn(ifp, umb_start); 593 if_setinitfn(ifp, umb_init); 594 595 #if 0 596 if_setwatchdog(ifp, umb_watchdog); 597 #endif 598 if_link_state_change(ifp, LINK_STATE_DOWN); 599 ifmedia_init(&sc->sc_im, 0, umb_mediachange, umb_mediastatus); 600 ifmedia_add(&sc->sc_im, IFM_NONE | IFM_AUTO, 0, NULL); 601 602 if_setifheaderlen(ifp, sizeof (struct ncm_header16) + 603 sizeof (struct ncm_pointer16)); /* XXX - IFAPI */ 604 /* XXX hard-coded atm */ 605 if_setmtu(ifp, MIN(2048, sc->sc_maxpktlen)); 606 if_setsendqlen(ifp, ifqmaxlen); 607 if_setsendqready(ifp); 608 609 /* attach the interface */ 610 if_attach(ifp); 611 bpfattach(ifp, DLT_RAW, 0); 612 613 sc->sc_attached = 1; 614 615 CURVNET_RESTORE(); 616 617 umb_init(sc); 618 mtx_lock(&sc->sc_mutex); 619 } 620 621 static int 622 umb_detach(device_t dev) 623 { 624 struct umb_softc *sc = device_get_softc(dev); 625 if_t ifp = GET_IFP(sc); 626 627 usb_proc_drain(&sc->sc_taskqueue); 628 629 mtx_lock(&sc->sc_mutex); 630 if (ifp != NULL && (if_getdrvflags(ifp) & IFF_DRV_RUNNING)) 631 umb_down(sc, 1); 632 umb_close(sc); 633 mtx_unlock(&sc->sc_mutex); 634 635 usbd_transfer_unsetup(sc->sc_xfer, UMB_N_TRANSFER); 636 637 free(sc->sc_tx_buf, M_DEVBUF); 638 free(sc->sc_rx_buf, M_DEVBUF); 639 640 usb_callout_drain(&sc->sc_statechg_timer); 641 642 usb_proc_free(&sc->sc_taskqueue); 643 644 mtx_destroy(&sc->sc_mutex); 645 646 free(sc->sc_ctrl_msg, M_DEVBUF); 647 free(sc->sc_resp_buf, M_DEVBUF); 648 649 if (ifp != NULL && if_getsoftc(ifp)) { 650 ifmedia_removeall(&sc->sc_im); 651 } 652 if (sc->sc_attached) { 653 bpfdetach(ifp); 654 if_detach(ifp); 655 if_free(ifp); 656 sc->sc_if = NULL; 657 } 658 659 return 0; 660 } 661 662 static void 663 umb_ncm_setup(struct umb_softc *sc, struct usb_config * config) 664 { 665 usb_device_request_t req; 666 struct ncm_ntb_parameters np; 667 usb_error_t error; 668 669 /* Query NTB tranfers sizes */ 670 req.bmRequestType = UT_READ_CLASS_INTERFACE; 671 req.bRequest = NCM_GET_NTB_PARAMETERS; 672 USETW(req.wValue, 0); 673 USETW(req.wIndex, sc->sc_ctrl_ifaceno); 674 USETW(req.wLength, sizeof (np)); 675 mtx_lock(&sc->sc_mutex); 676 error = usbd_do_request(sc->sc_udev, &sc->sc_mutex, &req, &np); 677 mtx_unlock(&sc->sc_mutex); 678 if (error == USB_ERR_NORMAL_COMPLETION && 679 UGETW(np.wLength) == sizeof (np)) { 680 config[UMB_BULK_RX].bufsize = UGETDW(np.dwNtbInMaxSize); 681 config[UMB_BULK_TX].bufsize = UGETDW(np.dwNtbOutMaxSize); 682 } 683 sc->sc_rx_bufsz = config[UMB_BULK_RX].bufsize; 684 sc->sc_tx_bufsz = config[UMB_BULK_TX].bufsize; 685 } 686 687 static int 688 umb_handle_request(device_t dev, 689 const void *preq, void **pptr, uint16_t *plen, 690 uint16_t offset, uint8_t *pstate) 691 { 692 /* FIXME really implement */ 693 694 return (ENXIO); 695 } 696 697 static int 698 umb_suspend(device_t dev) 699 { 700 device_printf(dev, "Suspending\n"); 701 return (0); 702 } 703 704 static int 705 umb_resume(device_t dev) 706 { 707 device_printf(dev, "Resuming\n"); 708 return (0); 709 } 710 711 static int 712 umb_deactivate(device_t dev) 713 { 714 struct umb_softc *sc = device_get_softc(dev); 715 if_t ifp = GET_IFP(sc); 716 717 if (ifp != NULL) { 718 if_dead(ifp); 719 } 720 sc->sc_dying = 1; 721 return 0; 722 } 723 724 static void 725 umb_close_bulkpipes(struct umb_softc *sc) 726 { 727 if_t ifp = GET_IFP(sc); 728 729 if_setdrvflagbits(ifp, 0, (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)); 730 731 umb_rxflush(sc); 732 umb_txflush(sc); 733 734 usbd_transfer_stop(sc->sc_xfer[UMB_BULK_RX]); 735 usbd_transfer_stop(sc->sc_xfer[UMB_BULK_TX]); 736 } 737 738 static int 739 umb_ioctl(if_t ifp, u_long cmd, caddr_t data) 740 { 741 struct umb_softc *sc = if_getsoftc(ifp); 742 struct in_ifaddr *ia = (struct in_ifaddr *)data; 743 struct ifreq *ifr = (struct ifreq *)data; 744 int error = 0; 745 struct umb_parameter mp; 746 747 if (sc->sc_dying) 748 return EIO; 749 750 switch (cmd) { 751 case SIOCSIFADDR: 752 switch (ia->ia_ifa.ifa_addr->sa_family) { 753 case AF_INET: 754 break; 755 #ifdef INET6 756 case AF_INET6: 757 break; 758 #endif /* INET6 */ 759 default: 760 error = EAFNOSUPPORT; 761 break; 762 } 763 break; 764 case SIOCSIFFLAGS: 765 mtx_lock(&sc->sc_mutex); 766 umb_add_task(sc, umb_state_task, 767 &sc->sc_proc_state_task[0].hdr, 768 &sc->sc_proc_state_task[1].hdr, 1); 769 mtx_unlock(&sc->sc_mutex); 770 break; 771 case SIOCGUMBINFO: 772 error = copyout(&sc->sc_info, ifr->ifr_ifru.ifru_data, 773 sizeof (sc->sc_info)); 774 break; 775 case SIOCSUMBPARAM: 776 error = priv_check(curthread, PRIV_NET_SETIFPHYS); 777 if (error) 778 break; 779 780 if ((error = copyin(ifr->ifr_ifru.ifru_data, &mp, sizeof (mp))) != 0) 781 break; 782 783 if ((error = umb_setpin(sc, mp.op, mp.is_puk, mp.pin, mp.pinlen, 784 mp.newpin, mp.newpinlen)) != 0) 785 break; 786 787 if (mp.apnlen < 0 || mp.apnlen > sizeof (sc->sc_info.apn)) { 788 error = EINVAL; 789 break; 790 } 791 sc->sc_roaming = mp.roaming ? 1 : 0; 792 memset(sc->sc_info.apn, 0, sizeof (sc->sc_info.apn)); 793 memcpy(sc->sc_info.apn, mp.apn, mp.apnlen); 794 sc->sc_info.apnlen = mp.apnlen; 795 memset(sc->sc_info.username, 0, sizeof (sc->sc_info.username)); 796 memcpy(sc->sc_info.username, mp.username, mp.usernamelen); 797 sc->sc_info.usernamelen = mp.usernamelen; 798 memset(sc->sc_info.password, 0, sizeof (sc->sc_info.password)); 799 memcpy(sc->sc_info.password, mp.password, mp.passwordlen); 800 sc->sc_info.passwordlen = mp.passwordlen; 801 sc->sc_info.preferredclasses = mp.preferredclasses; 802 umb_setdataclass(sc); 803 break; 804 case SIOCGUMBPARAM: 805 memset(&mp, 0, sizeof (mp)); 806 memcpy(mp.apn, sc->sc_info.apn, sc->sc_info.apnlen); 807 mp.apnlen = sc->sc_info.apnlen; 808 mp.roaming = sc->sc_roaming; 809 mp.preferredclasses = sc->sc_info.preferredclasses; 810 error = copyout(&mp, ifr->ifr_ifru.ifru_data, sizeof (mp)); 811 break; 812 case SIOCSIFMTU: 813 /* Does this include the NCM headers and tail? */ 814 if (ifr->ifr_mtu > if_getmtu(ifp)) { 815 error = EINVAL; 816 break; 817 } 818 if_setmtu(ifp, ifr->ifr_mtu); 819 break; 820 case SIOCAIFADDR: 821 case SIOCSIFDSTADDR: 822 case SIOCADDMULTI: 823 case SIOCDELMULTI: 824 break; 825 case SIOCGIFMEDIA: 826 error = ifmedia_ioctl(ifp, ifr, &sc->sc_im, cmd); 827 break; 828 default: 829 error = EINVAL; 830 break; 831 } 832 return (error); 833 } 834 835 static void 836 umb_init(void *arg) 837 { 838 struct umb_softc *sc = arg; 839 840 mtx_lock(&sc->sc_mutex); 841 umb_add_task(sc, umb_start_task, 842 &sc->sc_proc_start_task[0].hdr, 843 &sc->sc_proc_start_task[1].hdr, 0); 844 mtx_unlock(&sc->sc_mutex); 845 } 846 847 static void 848 umb_input(if_t ifp, struct mbuf *m) 849 { 850 struct mbuf *mn; 851 struct epoch_tracker et; 852 853 while (m) { 854 mn = m->m_nextpkt; 855 m->m_nextpkt = NULL; 856 857 NET_EPOCH_ENTER(et); 858 BPF_MTAP(ifp, m); 859 860 CURVNET_SET_QUIET(if_getvnet(ifp)); 861 862 netisr_dispatch(NETISR_IP, m); 863 m = mn; 864 865 CURVNET_RESTORE(); 866 NET_EPOCH_EXIT(et); 867 } 868 } 869 870 static int 871 umb_output(if_t ifp, struct mbuf *m, const struct sockaddr *dst, 872 struct route *rtp) 873 { 874 int error; 875 876 DPRINTFN(10, "%s: enter\n", __func__); 877 878 switch (dst->sa_family) { 879 #ifdef INET6 880 case AF_INET6: 881 /* fall through */ 882 #endif 883 case AF_INET: 884 break; 885 886 /* silently drop dhclient packets */ 887 case AF_UNSPEC: 888 m_freem(m); 889 return (0); 890 891 /* drop other packet types */ 892 default: 893 m_freem(m); 894 return (EAFNOSUPPORT); 895 } 896 897 /* 898 * Queue message on interface, and start output if interface 899 * not yet active. 900 */ 901 error = if_transmit(ifp, m); 902 if (error) { 903 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 904 return (ENOBUFS); 905 } 906 907 return (0); 908 } 909 910 static void 911 umb_start(if_t ifp) 912 { 913 struct umb_softc *sc = if_getsoftc(ifp); 914 915 if (sc->sc_dying || !(if_getdrvflags(ifp) & IFF_DRV_RUNNING)) 916 return; 917 918 mtx_lock(&sc->sc_mutex); 919 usbd_transfer_start(sc->sc_xfer[UMB_BULK_TX]); 920 mtx_unlock(&sc->sc_mutex); 921 } 922 923 static void 924 umb_start_task(struct usb_proc_msg *msg) 925 { 926 struct umb_task *task = (struct umb_task *)msg; 927 struct umb_softc *sc = task->sc; 928 if_t ifp = GET_IFP(sc); 929 930 DPRINTF("%s()\n", __func__); 931 932 mtx_assert(&sc->sc_mutex, MA_OWNED); 933 934 if_setdrvflagbits(ifp, IFF_DRV_RUNNING, 0); 935 936 /* start interrupt transfer */ 937 usbd_transfer_start(sc->sc_xfer[UMB_INTR_RX]); 938 939 umb_open(sc); 940 } 941 942 #if 0 943 static void 944 umb_watchdog(if_t ifp) 945 { 946 struct umb_softc *sc = if_getsoftc(ifp); 947 948 if (sc->sc_dying) 949 return; 950 951 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 952 device_printf(sc->sc_dev, "watchdog timeout\n"); 953 usbd_transfer_drain(sc->sc_xfer[UMB_BULK_TX]); 954 return; 955 } 956 #endif 957 958 static void 959 umb_statechg_timeout(void *arg) 960 { 961 struct umb_softc *sc = arg; 962 if_t ifp = GET_IFP(sc); 963 964 mtx_assert(&sc->sc_mutex, MA_OWNED); 965 966 if (sc->sc_info.regstate != MBIM_REGSTATE_ROAMING || sc->sc_roaming) 967 if (if_getflags(ifp) & IFF_DEBUG) 968 log(LOG_DEBUG, "%s: state change timeout\n", 969 DEVNAM(sc)); 970 971 umb_add_task(sc, umb_state_task, 972 &sc->sc_proc_state_task[0].hdr, 973 &sc->sc_proc_state_task[1].hdr, 0); 974 } 975 976 static int 977 umb_mediachange(if_t ifp) 978 { 979 return 0; 980 } 981 982 static void 983 umb_mediastatus(if_t ifp, struct ifmediareq * imr) 984 { 985 switch (if_getlinkstate(ifp)) { 986 case LINK_STATE_UP: 987 imr->ifm_status = IFM_AVALID | IFM_ACTIVE; 988 break; 989 case LINK_STATE_DOWN: 990 imr->ifm_status = IFM_AVALID; 991 break; 992 default: 993 imr->ifm_status = 0; 994 break; 995 } 996 } 997 998 static void 999 umb_add_task(struct umb_softc *sc, usb_proc_callback_t callback, 1000 struct usb_proc_msg *t0, struct usb_proc_msg *t1, int sync) 1001 { 1002 struct umb_task * task; 1003 1004 mtx_assert(&sc->sc_mutex, MA_OWNED); 1005 1006 if (usb_proc_is_gone(&sc->sc_taskqueue)) { 1007 return; 1008 } 1009 1010 task = usb_proc_msignal(&sc->sc_taskqueue, t0, t1); 1011 1012 task->hdr.pm_callback = callback; 1013 task->sc = sc; 1014 1015 if (sync) { 1016 usb_proc_mwait(&sc->sc_taskqueue, t0, t1); 1017 } 1018 } 1019 1020 static void 1021 umb_newstate(struct umb_softc *sc, enum umb_state newstate, int flags) 1022 { 1023 if_t ifp = GET_IFP(sc); 1024 1025 if (newstate == sc->sc_state) 1026 return; 1027 if (((flags & UMB_NS_DONT_DROP) && newstate < sc->sc_state) || 1028 ((flags & UMB_NS_DONT_RAISE) && newstate > sc->sc_state)) 1029 return; 1030 if (if_getflags(ifp) & IFF_DEBUG) 1031 log(LOG_DEBUG, "%s: state going %s from '%s' to '%s'\n", 1032 DEVNAM(sc), newstate > sc->sc_state ? "up" : "down", 1033 umb_istate(sc->sc_state), umb_istate(newstate)); 1034 sc->sc_state = newstate; 1035 umb_add_task(sc, umb_state_task, 1036 &sc->sc_proc_state_task[0].hdr, 1037 &sc->sc_proc_state_task[1].hdr, 0); 1038 } 1039 1040 static void 1041 umb_state_task(struct usb_proc_msg *msg) 1042 { 1043 struct umb_task *task = (struct umb_task *)msg; 1044 struct umb_softc *sc = task->sc; 1045 if_t ifp = GET_IFP(sc); 1046 struct ifreq ifr; 1047 int state; 1048 1049 DPRINTF("%s()\n", __func__); 1050 1051 if (sc->sc_info.regstate == MBIM_REGSTATE_ROAMING && !sc->sc_roaming) { 1052 /* 1053 * Query the registration state until we're with the home 1054 * network again. 1055 */ 1056 umb_cmd(sc, MBIM_CID_REGISTER_STATE, MBIM_CMDOP_QRY, NULL, 0); 1057 return; 1058 } 1059 1060 if (if_getflags(ifp) & IFF_UP) 1061 umb_up(sc); 1062 else 1063 umb_down(sc, 0); 1064 1065 state = (sc->sc_state == UMB_S_UP) ? LINK_STATE_UP : LINK_STATE_DOWN; 1066 if (if_getlinkstate(ifp) != state) { 1067 if (if_getflags(ifp) & IFF_DEBUG) 1068 log(LOG_DEBUG, "%s: link state changed from %s to %s\n", 1069 DEVNAM(sc), 1070 (if_getlinkstate(ifp) == LINK_STATE_UP) 1071 ? "up" : "down", 1072 (state == LINK_STATE_UP) ? "up" : "down"); 1073 if_link_state_change(ifp, state); /* XXX - IFAPI */ 1074 if (state != LINK_STATE_UP) { 1075 /* 1076 * Purge any existing addresses 1077 */ 1078 memset(sc->sc_info.ipv4dns, 0, 1079 sizeof (sc->sc_info.ipv4dns)); 1080 mtx_unlock(&sc->sc_mutex); 1081 CURVNET_SET_QUIET(if_getvnet(ifp)); 1082 if (in_control(NULL, SIOCGIFADDR, (caddr_t)&ifr, ifp, 1083 curthread) == 0 && 1084 satosin(&ifr.ifr_addr)->sin_addr.s_addr != 1085 INADDR_ANY) { 1086 in_control(NULL, SIOCDIFADDR, (caddr_t)&ifr, 1087 ifp, curthread); 1088 } 1089 CURVNET_RESTORE(); 1090 mtx_lock(&sc->sc_mutex); 1091 } 1092 if_link_state_change(ifp, state); 1093 } 1094 } 1095 1096 static void 1097 umb_up(struct umb_softc *sc) 1098 { 1099 if_t ifp = GET_IFP(sc); 1100 1101 switch (sc->sc_state) { 1102 case UMB_S_DOWN: 1103 DPRINTF("init: opening ...\n"); 1104 umb_open(sc); 1105 break; 1106 case UMB_S_OPEN: 1107 if (sc->sc_flags & UMBFLG_FCC_AUTH_REQUIRED) { 1108 if (sc->sc_cid == -1) { 1109 DPRINTF("init: allocating CID ...\n"); 1110 umb_allocate_cid(sc); 1111 break; 1112 } else 1113 umb_newstate(sc, UMB_S_CID, UMB_NS_DONT_DROP); 1114 } else { 1115 DPRINTF("init: turning radio on ...\n"); 1116 umb_radio(sc, 1); 1117 break; 1118 } 1119 /*FALLTHROUGH*/ 1120 case UMB_S_CID: 1121 DPRINTF("init: sending FCC auth ...\n"); 1122 umb_send_fcc_auth(sc); 1123 break; 1124 case UMB_S_RADIO: 1125 DPRINTF("init: checking SIM state ...\n"); 1126 umb_cmd(sc, MBIM_CID_SUBSCRIBER_READY_STATUS, MBIM_CMDOP_QRY, 1127 NULL, 0); 1128 break; 1129 case UMB_S_SIMREADY: 1130 DPRINTF("init: attaching ...\n"); 1131 umb_packet_service(sc, 1); 1132 break; 1133 case UMB_S_ATTACHED: 1134 sc->sc_tx_seq = 0; 1135 DPRINTF("init: connecting ...\n"); 1136 umb_connect(sc); 1137 break; 1138 case UMB_S_CONNECTED: 1139 DPRINTF("init: getting IP config ...\n"); 1140 umb_qry_ipconfig(sc); 1141 break; 1142 case UMB_S_UP: 1143 DPRINTF("init: reached state UP\n"); 1144 if (!(if_getflags(ifp) & IFF_DRV_RUNNING)) { 1145 if_setdrvflagbits(ifp, IFF_DRV_RUNNING, 0); 1146 if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE); 1147 umb_rx(sc); 1148 } 1149 break; 1150 } 1151 if (sc->sc_state < UMB_S_UP) 1152 usb_callout_reset(&sc->sc_statechg_timer, 1153 UMB_STATE_CHANGE_TIMEOUT * hz, umb_statechg_timeout, sc); 1154 else { 1155 usb_callout_stop(&sc->sc_statechg_timer); 1156 } 1157 return; 1158 } 1159 1160 static void 1161 umb_down(struct umb_softc *sc, int force) 1162 { 1163 umb_close_bulkpipes(sc); 1164 1165 switch (sc->sc_state) { 1166 case UMB_S_UP: 1167 case UMB_S_CONNECTED: 1168 DPRINTF("stop: disconnecting ...\n"); 1169 umb_disconnect(sc); 1170 if (!force) 1171 break; 1172 /*FALLTHROUGH*/ 1173 case UMB_S_ATTACHED: 1174 DPRINTF("stop: detaching ...\n"); 1175 umb_packet_service(sc, 0); 1176 if (!force) 1177 break; 1178 /*FALLTHROUGH*/ 1179 case UMB_S_SIMREADY: 1180 case UMB_S_RADIO: 1181 DPRINTF("stop: turning radio off ...\n"); 1182 umb_radio(sc, 0); 1183 if (!force) 1184 break; 1185 /*FALLTHROUGH*/ 1186 case UMB_S_CID: 1187 case UMB_S_OPEN: 1188 case UMB_S_DOWN: 1189 /* Do not close the device */ 1190 DPRINTF("stop: reached state DOWN\n"); 1191 break; 1192 } 1193 if (force) 1194 sc->sc_state = UMB_S_OPEN; 1195 1196 if (sc->sc_state > UMB_S_OPEN) 1197 usb_callout_reset(&sc->sc_statechg_timer, 1198 UMB_STATE_CHANGE_TIMEOUT * hz, umb_statechg_timeout, sc); 1199 else 1200 usb_callout_stop(&sc->sc_statechg_timer); 1201 } 1202 1203 static void 1204 umb_get_response_task(struct usb_proc_msg *msg) 1205 { 1206 struct umb_task *task = (struct umb_task *)msg; 1207 struct umb_softc *sc = task->sc; 1208 int len; 1209 1210 DPRINTF("%s()\n", __func__); 1211 /* 1212 * Function is required to send on RESPONSE_AVAILABLE notification for 1213 * each encapsulated response that is to be processed by the host. 1214 * But of course, we can receive multiple notifications before the 1215 * response task is run. 1216 */ 1217 while (sc->sc_nresp > 0) { 1218 --sc->sc_nresp; 1219 len = sc->sc_ctrl_len; 1220 if (umb_get_encap_response(sc, sc->sc_resp_buf, &len)) 1221 umb_decode_response(sc, sc->sc_resp_buf, len); 1222 } 1223 } 1224 1225 static void 1226 umb_decode_response(struct umb_softc *sc, void *response, int len) 1227 { 1228 struct mbim_msghdr *hdr = response; 1229 struct mbim_fragmented_msg_hdr *fraghdr; 1230 uint32_t type; 1231 1232 DPRINTFN(3, "got response: len %d\n", len); 1233 DDUMPN(4, response, len); 1234 1235 if (len < sizeof (*hdr) || le32toh(hdr->len) != len) { 1236 /* 1237 * We should probably cancel a transaction, but since the 1238 * message is too short, we cannot decode the transaction 1239 * id (tid) and hence don't know, whom to cancel. Must wait 1240 * for the timeout. 1241 */ 1242 DPRINTF("received short response (len %d)\n", 1243 len); 1244 return; 1245 } 1246 1247 /* 1248 * XXX FIXME: if message is fragmented, store it until last frag 1249 * is received and then re-assemble all fragments. 1250 */ 1251 type = le32toh(hdr->type); 1252 switch (type) { 1253 case MBIM_INDICATE_STATUS_MSG: 1254 case MBIM_COMMAND_DONE: 1255 fraghdr = response; 1256 if (le32toh(fraghdr->frag.nfrag) != 1) { 1257 DPRINTF("discarding fragmented messages\n"); 1258 return; 1259 } 1260 break; 1261 default: 1262 break; 1263 } 1264 1265 DPRINTF("<- rcv %s (tid %u)\n", umb_request2str(type), 1266 le32toh(hdr->tid)); 1267 switch (type) { 1268 case MBIM_FUNCTION_ERROR_MSG: 1269 case MBIM_HOST_ERROR_MSG: 1270 { 1271 struct mbim_f2h_hosterr *e; 1272 int err; 1273 1274 if (len >= sizeof (*e)) { 1275 e = response; 1276 err = le32toh(e->err); 1277 1278 DPRINTF("%s message, error %s (tid %u)\n", 1279 umb_request2str(type), 1280 umb_error2str(err), le32toh(hdr->tid)); 1281 if (err == MBIM_ERROR_NOT_OPENED) 1282 umb_newstate(sc, UMB_S_DOWN, 0); 1283 } 1284 break; 1285 } 1286 case MBIM_INDICATE_STATUS_MSG: 1287 umb_handle_indicate_status_msg(sc, response, len); 1288 break; 1289 case MBIM_OPEN_DONE: 1290 umb_handle_opendone_msg(sc, response, len); 1291 break; 1292 case MBIM_CLOSE_DONE: 1293 umb_handle_closedone_msg(sc, response, len); 1294 break; 1295 case MBIM_COMMAND_DONE: 1296 umb_command_done(sc, response, len); 1297 break; 1298 default: 1299 DPRINTF("discard message %s\n", 1300 umb_request2str(type)); 1301 break; 1302 } 1303 } 1304 1305 static void 1306 umb_handle_indicate_status_msg(struct umb_softc *sc, void *data, int len) 1307 { 1308 struct mbim_f2h_indicate_status *m = data; 1309 uint32_t infolen; 1310 uint32_t cid; 1311 1312 if (len < sizeof (*m)) { 1313 DPRINTF("discard short %s message\n", 1314 umb_request2str(le32toh(m->hdr.type))); 1315 return; 1316 } 1317 if (memcmp(m->devid, umb_uuid_basic_connect, sizeof (m->devid))) { 1318 DPRINTF("discard %s message for other UUID '%s'\n", 1319 umb_request2str(le32toh(m->hdr.type)), 1320 umb_uuid2str(m->devid)); 1321 return; 1322 } 1323 infolen = le32toh(m->infolen); 1324 if (len < sizeof (*m) + infolen) { 1325 DPRINTF("discard truncated %s message (want %d, got %d)\n", 1326 umb_request2str(le32toh(m->hdr.type)), 1327 (int)sizeof (*m) + infolen, len); 1328 return; 1329 } 1330 1331 cid = le32toh(m->cid); 1332 DPRINTF("indicate %s status\n", umb_cid2str(cid)); 1333 umb_decode_cid(sc, cid, m->info, infolen); 1334 } 1335 1336 static void 1337 umb_handle_opendone_msg(struct umb_softc *sc, void *data, int len) 1338 { 1339 struct mbim_f2h_openclosedone *resp = data; 1340 if_t ifp = GET_IFP(sc); 1341 uint32_t status; 1342 1343 status = le32toh(resp->status); 1344 if (status == MBIM_STATUS_SUCCESS) { 1345 if (sc->sc_maxsessions == 0) { 1346 umb_cmd(sc, MBIM_CID_DEVICE_CAPS, MBIM_CMDOP_QRY, NULL, 1347 0); 1348 umb_cmd(sc, MBIM_CID_PIN, MBIM_CMDOP_QRY, NULL, 0); 1349 umb_cmd(sc, MBIM_CID_REGISTER_STATE, MBIM_CMDOP_QRY, 1350 NULL, 0); 1351 } 1352 umb_newstate(sc, UMB_S_OPEN, UMB_NS_DONT_DROP); 1353 } else if (if_getflags(ifp) & IFF_DEBUG) 1354 log(LOG_ERR, "%s: open error: %s\n", DEVNAM(sc), 1355 umb_status2str(status)); 1356 return; 1357 } 1358 1359 static void 1360 umb_handle_closedone_msg(struct umb_softc *sc, void *data, int len) 1361 { 1362 struct mbim_f2h_openclosedone *resp = data; 1363 uint32_t status; 1364 1365 status = le32toh(resp->status); 1366 if (status == MBIM_STATUS_SUCCESS) 1367 umb_newstate(sc, UMB_S_DOWN, 0); 1368 else 1369 DPRINTF("close error: %s\n", 1370 umb_status2str(status)); 1371 return; 1372 } 1373 1374 static inline void 1375 umb_getinfobuf(char *in, int inlen, uint32_t offs, uint32_t sz, 1376 void *out, size_t outlen) 1377 { 1378 offs = le32toh(offs); 1379 sz = le32toh(sz); 1380 if (inlen >= offs + sz) { 1381 memset(out, 0, outlen); 1382 memcpy(out, in + offs, MIN(sz, outlen)); 1383 } 1384 } 1385 1386 static inline int 1387 umb_padding(void *data, int len, size_t sz) 1388 { 1389 char *p = data; 1390 int np = 0; 1391 1392 while (len < sz && (len % 4) != 0) { 1393 *p++ = '\0'; 1394 len++; 1395 np++; 1396 } 1397 return np; 1398 } 1399 1400 static inline int 1401 umb_addstr(void *buf, size_t bufsz, int *offs, void *str, int slen, 1402 uint32_t *offsmember, uint32_t *sizemember) 1403 { 1404 if (*offs + slen > bufsz) 1405 return 0; 1406 1407 *sizemember = htole32((uint32_t)slen); 1408 if (slen && str) { 1409 *offsmember = htole32((uint32_t)*offs); 1410 memcpy((char *)buf + *offs, str, slen); 1411 *offs += slen; 1412 *offs += umb_padding(buf, *offs, bufsz); 1413 } else 1414 *offsmember = htole32(0); 1415 return 1; 1416 } 1417 1418 static void 1419 umb_in_len2mask(struct in_addr *mask, int len) 1420 { 1421 int i; 1422 u_char *p; 1423 1424 p = (u_char *)mask; 1425 memset(mask, 0, sizeof (*mask)); 1426 for (i = 0; i < len / 8; i++) 1427 p[i] = 0xff; 1428 if (len % 8) 1429 p[i] = (0xff00 >> (len % 8)) & 0xff; 1430 } 1431 1432 static int 1433 umb_decode_register_state(struct umb_softc *sc, void *data, int len) 1434 { 1435 struct mbim_cid_registration_state_info *rs = data; 1436 if_t ifp = GET_IFP(sc); 1437 1438 if (len < sizeof (*rs)) 1439 return 0; 1440 sc->sc_info.nwerror = le32toh(rs->nwerror); 1441 sc->sc_info.regstate = le32toh(rs->regstate); 1442 sc->sc_info.regmode = le32toh(rs->regmode); 1443 sc->sc_info.cellclass = le32toh(rs->curcellclass); 1444 1445 /* XXX should we remember the provider_id? */ 1446 umb_getinfobuf(data, len, rs->provname_offs, rs->provname_size, 1447 sc->sc_info.provider, sizeof (sc->sc_info.provider)); 1448 umb_getinfobuf(data, len, rs->roamingtxt_offs, rs->roamingtxt_size, 1449 sc->sc_info.roamingtxt, sizeof (sc->sc_info.roamingtxt)); 1450 1451 DPRINTFN(2, "%s, availclass 0x%x, class 0x%x, regmode %d\n", 1452 umb_regstate(sc->sc_info.regstate), 1453 le32toh(rs->availclasses), sc->sc_info.cellclass, 1454 sc->sc_info.regmode); 1455 1456 if (sc->sc_info.regstate == MBIM_REGSTATE_ROAMING && 1457 !sc->sc_roaming && 1458 sc->sc_info.activation == MBIM_ACTIVATION_STATE_ACTIVATED) { 1459 if (if_getflags(ifp) & IFF_DEBUG) 1460 log(LOG_INFO, 1461 "%s: disconnecting from roaming network\n", 1462 DEVNAM(sc)); 1463 umb_disconnect(sc); 1464 } 1465 return 1; 1466 } 1467 1468 static int 1469 umb_decode_devices_caps(struct umb_softc *sc, void *data, int len) 1470 { 1471 struct mbim_cid_device_caps *dc = data; 1472 1473 if (len < sizeof (*dc)) 1474 return 0; 1475 sc->sc_maxsessions = le32toh(dc->max_sessions); 1476 sc->sc_info.supportedclasses = le32toh(dc->dataclass); 1477 umb_getinfobuf(data, len, dc->devid_offs, dc->devid_size, 1478 sc->sc_info.devid, sizeof (sc->sc_info.devid)); 1479 umb_getinfobuf(data, len, dc->fwinfo_offs, dc->fwinfo_size, 1480 sc->sc_info.fwinfo, sizeof (sc->sc_info.fwinfo)); 1481 umb_getinfobuf(data, len, dc->hwinfo_offs, dc->hwinfo_size, 1482 sc->sc_info.hwinfo, sizeof (sc->sc_info.hwinfo)); 1483 DPRINTFN(2, "max sessions %d, supported classes 0x%x\n", 1484 sc->sc_maxsessions, sc->sc_info.supportedclasses); 1485 return 1; 1486 } 1487 1488 static int 1489 umb_decode_subscriber_status(struct umb_softc *sc, void *data, int len) 1490 { 1491 struct mbim_cid_subscriber_ready_info *si = data; 1492 if_t ifp = GET_IFP(sc); 1493 int npn; 1494 1495 if (len < sizeof (*si)) 1496 return 0; 1497 sc->sc_info.sim_state = le32toh(si->ready); 1498 1499 umb_getinfobuf(data, len, si->sid_offs, si->sid_size, 1500 sc->sc_info.sid, sizeof (sc->sc_info.sid)); 1501 umb_getinfobuf(data, len, si->icc_offs, si->icc_size, 1502 sc->sc_info.iccid, sizeof (sc->sc_info.iccid)); 1503 1504 npn = le32toh(si->no_pn); 1505 if (npn > 0) 1506 umb_getinfobuf(data, len, si->pn[0].offs, si->pn[0].size, 1507 sc->sc_info.pn, sizeof (sc->sc_info.pn)); 1508 else 1509 memset(sc->sc_info.pn, 0, sizeof (sc->sc_info.pn)); 1510 1511 if (sc->sc_info.sim_state == MBIM_SIMSTATE_LOCKED) 1512 sc->sc_info.pin_state = UMB_PIN_REQUIRED; 1513 if (if_getflags(ifp) & IFF_DEBUG) 1514 log(LOG_INFO, "%s: SIM %s\n", DEVNAM(sc), 1515 umb_simstate(sc->sc_info.sim_state)); 1516 if (sc->sc_info.sim_state == MBIM_SIMSTATE_INITIALIZED) 1517 umb_newstate(sc, UMB_S_SIMREADY, UMB_NS_DONT_DROP); 1518 return 1; 1519 } 1520 1521 static int 1522 umb_decode_radio_state(struct umb_softc *sc, void *data, int len) 1523 { 1524 struct mbim_cid_radio_state_info *rs = data; 1525 if_t ifp = GET_IFP(sc); 1526 1527 if (len < sizeof (*rs)) 1528 return 0; 1529 1530 sc->sc_info.hw_radio_on = 1531 (le32toh(rs->hw_state) == MBIM_RADIO_STATE_ON) ? 1 : 0; 1532 sc->sc_info.sw_radio_on = 1533 (le32toh(rs->sw_state) == MBIM_RADIO_STATE_ON) ? 1 : 0; 1534 if (!sc->sc_info.hw_radio_on) { 1535 device_printf(sc->sc_dev, "radio is disabled by hardware switch\n"); 1536 /* 1537 * XXX do we need a time to poll the state of the rfkill switch 1538 * or will the device send an unsolicited notification 1539 * in case the state changes? 1540 */ 1541 umb_newstate(sc, UMB_S_OPEN, 0); 1542 } else if (!sc->sc_info.sw_radio_on) { 1543 if (if_getflags(ifp) & IFF_DEBUG) 1544 log(LOG_INFO, "%s: radio is off\n", DEVNAM(sc)); 1545 umb_newstate(sc, UMB_S_OPEN, 0); 1546 } else 1547 umb_newstate(sc, UMB_S_RADIO, UMB_NS_DONT_DROP); 1548 return 1; 1549 } 1550 1551 static int 1552 umb_decode_pin(struct umb_softc *sc, void *data, int len) 1553 { 1554 struct mbim_cid_pin_info *pi = data; 1555 if_t ifp = GET_IFP(sc); 1556 uint32_t attempts_left; 1557 1558 if (len < sizeof (*pi)) 1559 return 0; 1560 1561 attempts_left = le32toh(pi->remaining_attempts); 1562 if (attempts_left != 0xffffffff) 1563 sc->sc_info.pin_attempts_left = attempts_left; 1564 1565 switch (le32toh(pi->state)) { 1566 case MBIM_PIN_STATE_UNLOCKED: 1567 sc->sc_info.pin_state = UMB_PIN_UNLOCKED; 1568 break; 1569 case MBIM_PIN_STATE_LOCKED: 1570 switch (le32toh(pi->type)) { 1571 case MBIM_PIN_TYPE_PIN1: 1572 sc->sc_info.pin_state = UMB_PIN_REQUIRED; 1573 break; 1574 case MBIM_PIN_TYPE_PUK1: 1575 sc->sc_info.pin_state = UMB_PUK_REQUIRED; 1576 break; 1577 case MBIM_PIN_TYPE_PIN2: 1578 case MBIM_PIN_TYPE_PUK2: 1579 /* Assume that PIN1 was accepted */ 1580 sc->sc_info.pin_state = UMB_PIN_UNLOCKED; 1581 break; 1582 } 1583 break; 1584 } 1585 if (if_getflags(ifp) & IFF_DEBUG) 1586 log(LOG_INFO, "%s: %s state %s (%d attempts left)\n", 1587 DEVNAM(sc), umb_pin_type(le32toh(pi->type)), 1588 (le32toh(pi->state) == MBIM_PIN_STATE_UNLOCKED) ? 1589 "unlocked" : "locked", 1590 le32toh(pi->remaining_attempts)); 1591 1592 /* 1593 * In case the PIN was set after IFF_UP, retrigger the state machine 1594 */ 1595 umb_add_task(sc, umb_state_task, 1596 &sc->sc_proc_state_task[0].hdr, 1597 &sc->sc_proc_state_task[1].hdr, 0); 1598 return 1; 1599 } 1600 1601 static int 1602 umb_decode_packet_service(struct umb_softc *sc, void *data, int len) 1603 { 1604 struct mbim_cid_packet_service_info *psi = data; 1605 int state, highestclass; 1606 uint64_t up_speed, down_speed; 1607 if_t ifp = GET_IFP(sc); 1608 1609 if (len < sizeof (*psi)) 1610 return 0; 1611 1612 sc->sc_info.nwerror = le32toh(psi->nwerror); 1613 state = le32toh(psi->state); 1614 highestclass = le32toh(psi->highest_dataclass); 1615 up_speed = le64toh(psi->uplink_speed); 1616 down_speed = le64toh(psi->downlink_speed); 1617 if (sc->sc_info.packetstate != state || 1618 sc->sc_info.uplink_speed != up_speed || 1619 sc->sc_info.downlink_speed != down_speed) { 1620 if (if_getflags(ifp) & IFF_DEBUG) { 1621 log(LOG_INFO, "%s: packet service ", DEVNAM(sc)); 1622 if (sc->sc_info.packetstate != state) 1623 log(LOG_INFO, "changed from %s to ", 1624 umb_packet_state(sc->sc_info.packetstate)); 1625 log(LOG_INFO, "%s, class %s, speed: %" PRIu64 " up / %" PRIu64 " down\n", 1626 umb_packet_state(state), 1627 umb_dataclass(highestclass), up_speed, down_speed); 1628 } 1629 } 1630 sc->sc_info.packetstate = state; 1631 sc->sc_info.highestclass = highestclass; 1632 sc->sc_info.uplink_speed = up_speed; 1633 sc->sc_info.downlink_speed = down_speed; 1634 1635 if (sc->sc_info.regmode == MBIM_REGMODE_AUTOMATIC) { 1636 /* 1637 * For devices using automatic registration mode, just proceed, 1638 * once registration has completed. 1639 */ 1640 if (if_getflags(ifp) & IFF_UP) { 1641 switch (sc->sc_info.regstate) { 1642 case MBIM_REGSTATE_HOME: 1643 case MBIM_REGSTATE_ROAMING: 1644 case MBIM_REGSTATE_PARTNER: 1645 umb_newstate(sc, UMB_S_ATTACHED, 1646 UMB_NS_DONT_DROP); 1647 break; 1648 default: 1649 break; 1650 } 1651 } else 1652 umb_newstate(sc, UMB_S_SIMREADY, UMB_NS_DONT_RAISE); 1653 } else switch (sc->sc_info.packetstate) { 1654 case MBIM_PKTSERVICE_STATE_ATTACHED: 1655 umb_newstate(sc, UMB_S_ATTACHED, UMB_NS_DONT_DROP); 1656 break; 1657 case MBIM_PKTSERVICE_STATE_DETACHED: 1658 umb_newstate(sc, UMB_S_SIMREADY, UMB_NS_DONT_RAISE); 1659 break; 1660 } 1661 return 1; 1662 } 1663 1664 static int 1665 umb_decode_signal_state(struct umb_softc *sc, void *data, int len) 1666 { 1667 struct mbim_cid_signal_state *ss = data; 1668 if_t ifp = GET_IFP(sc); 1669 int rssi; 1670 1671 if (len < sizeof (*ss)) 1672 return 0; 1673 1674 if (le32toh(ss->rssi) == 99) 1675 rssi = UMB_VALUE_UNKNOWN; 1676 else { 1677 rssi = -113 + 2 * le32toh(ss->rssi); 1678 if ((if_getflags(ifp) & IFF_DEBUG) && sc->sc_info.rssi != rssi && 1679 sc->sc_state >= UMB_S_CONNECTED) 1680 log(LOG_INFO, "%s: rssi %d dBm\n", DEVNAM(sc), rssi); 1681 } 1682 sc->sc_info.rssi = rssi; 1683 sc->sc_info.ber = le32toh(ss->err_rate); 1684 if (sc->sc_info.ber == -99) 1685 sc->sc_info.ber = UMB_VALUE_UNKNOWN; 1686 return 1; 1687 } 1688 1689 static int 1690 umb_decode_connect_info(struct umb_softc *sc, void *data, int len) 1691 { 1692 struct mbim_cid_connect_info *ci = data; 1693 if_t ifp = GET_IFP(sc); 1694 int act; 1695 1696 if (len < sizeof (*ci)) 1697 return 0; 1698 1699 if (le32toh(ci->sessionid) != umb_session_id) { 1700 DPRINTF("discard connection info for session %u\n", 1701 le32toh(ci->sessionid)); 1702 return 1; 1703 } 1704 if (memcmp(ci->context, umb_uuid_context_internet, 1705 sizeof (ci->context))) { 1706 DPRINTF("discard connection info for other context\n"); 1707 return 1; 1708 } 1709 act = le32toh(ci->activation); 1710 if (sc->sc_info.activation != act) { 1711 if (if_getflags(ifp) & IFF_DEBUG) 1712 log(LOG_INFO, "%s: connection %s\n", DEVNAM(sc), 1713 umb_activation(act)); 1714 if ((if_getflags(ifp) & IFF_DEBUG) && 1715 le32toh(ci->iptype) != MBIM_CONTEXT_IPTYPE_DEFAULT && 1716 le32toh(ci->iptype) != MBIM_CONTEXT_IPTYPE_IPV4) 1717 log(LOG_DEBUG, "%s: got iptype %d connection\n", 1718 DEVNAM(sc), le32toh(ci->iptype)); 1719 1720 sc->sc_info.activation = act; 1721 sc->sc_info.nwerror = le32toh(ci->nwerror); 1722 1723 if (sc->sc_info.activation == MBIM_ACTIVATION_STATE_ACTIVATED) 1724 umb_newstate(sc, UMB_S_CONNECTED, UMB_NS_DONT_DROP); 1725 else if (sc->sc_info.activation == 1726 MBIM_ACTIVATION_STATE_DEACTIVATED) 1727 umb_newstate(sc, UMB_S_ATTACHED, 0); 1728 /* else: other states are purely transitional */ 1729 } 1730 return 1; 1731 } 1732 1733 static int 1734 umb_add_inet_config(struct umb_softc *sc, struct in_addr ip, u_int prefixlen, 1735 struct in_addr gw) 1736 { 1737 if_t ifp = GET_IFP(sc); 1738 struct in_aliasreq ifra; 1739 struct sockaddr_in *sin; 1740 int rv; 1741 1742 memset(&ifra, 0, sizeof (ifra)); 1743 sin = (struct sockaddr_in *)&ifra.ifra_addr; 1744 sin->sin_family = AF_INET; 1745 sin->sin_len = sizeof (*sin); 1746 sin->sin_addr = ip; 1747 1748 sin = (struct sockaddr_in *)&ifra.ifra_dstaddr; 1749 sin->sin_family = AF_INET; 1750 sin->sin_len = sizeof (*sin); 1751 sin->sin_addr = gw; 1752 1753 sin = (struct sockaddr_in *)&ifra.ifra_mask; 1754 sin->sin_family = AF_INET; 1755 sin->sin_len = sizeof (*sin); 1756 umb_in_len2mask(&sin->sin_addr, prefixlen); 1757 1758 mtx_unlock(&sc->sc_mutex); 1759 CURVNET_SET_QUIET(if_getvnet(ifp)); 1760 rv = in_control(NULL, SIOCAIFADDR, (caddr_t)&ifra, ifp, curthread); 1761 CURVNET_RESTORE(); 1762 mtx_lock(&sc->sc_mutex); 1763 if (rv != 0) { 1764 device_printf(sc->sc_dev, "unable to set IPv4 address, error %d\n", 1765 rv); 1766 return rv; 1767 } 1768 1769 if (if_getflags(ifp) & IFF_DEBUG) 1770 log(LOG_INFO, "%s: IPv4 addr %s, mask %s, " 1771 "gateway %s\n", DEVNAM(sc), 1772 umb_ntop(sintosa(&ifra.ifra_addr)), 1773 umb_ntop(sintosa(&ifra.ifra_mask)), 1774 umb_ntop(sintosa(&ifra.ifra_dstaddr))); 1775 1776 return 0; 1777 } 1778 1779 static int 1780 umb_decode_ip_configuration(struct umb_softc *sc, void *data, int len) 1781 { 1782 struct mbim_cid_ip_configuration_info *ic = data; 1783 if_t ifp = GET_IFP(sc); 1784 uint32_t avail_v4; 1785 uint32_t val; 1786 int n, i; 1787 int off; 1788 struct mbim_cid_ipv4_element ipv4elem; 1789 struct in_addr addr, gw; 1790 int state = -1; 1791 int rv; 1792 1793 if (len < sizeof (*ic)) 1794 return 0; 1795 if (le32toh(ic->sessionid) != umb_session_id) { 1796 DPRINTF("ignore IP configuration for session id %d\n", 1797 le32toh(ic->sessionid)); 1798 return 0; 1799 } 1800 1801 /* 1802 * IPv4 configuration 1803 */ 1804 avail_v4 = le32toh(ic->ipv4_available); 1805 if ((avail_v4 & (MBIM_IPCONF_HAS_ADDRINFO | MBIM_IPCONF_HAS_GWINFO)) == 1806 (MBIM_IPCONF_HAS_ADDRINFO | MBIM_IPCONF_HAS_GWINFO)) { 1807 n = le32toh(ic->ipv4_naddr); 1808 off = le32toh(ic->ipv4_addroffs); 1809 1810 if (n == 0 || off + sizeof (ipv4elem) > len) 1811 goto tryv6; 1812 if (n != 1 && if_getflags(ifp) & IFF_DEBUG) 1813 log(LOG_INFO, "%s: more than one IPv4 addr: %d\n", 1814 DEVNAM(sc), n); 1815 1816 /* Only pick the first one */ 1817 memcpy(&ipv4elem, (char *)data + off, sizeof (ipv4elem)); 1818 ipv4elem.prefixlen = le32toh(ipv4elem.prefixlen); 1819 addr.s_addr = ipv4elem.addr; 1820 1821 off = le32toh(ic->ipv4_gwoffs); 1822 if (off + sizeof (gw) > len) 1823 goto done; 1824 memcpy(&gw, (char *)data + off, sizeof (gw)); 1825 1826 rv = umb_add_inet_config(sc, addr, ipv4elem.prefixlen, gw); 1827 if (rv == 0) 1828 state = UMB_S_UP; 1829 } 1830 1831 memset(sc->sc_info.ipv4dns, 0, sizeof (sc->sc_info.ipv4dns)); 1832 if (avail_v4 & MBIM_IPCONF_HAS_DNSINFO) { 1833 n = le32toh(ic->ipv4_ndnssrv); 1834 off = le32toh(ic->ipv4_dnssrvoffs); 1835 i = 0; 1836 while (n-- > 0) { 1837 if (off + sizeof (addr) > len) 1838 break; 1839 memcpy(&addr, (char *)data + off, sizeof(addr)); 1840 if (i < UMB_MAX_DNSSRV) 1841 sc->sc_info.ipv4dns[i++] = addr; 1842 off += sizeof(addr); 1843 } 1844 } 1845 1846 if ((avail_v4 & MBIM_IPCONF_HAS_MTUINFO)) { 1847 val = le32toh(ic->ipv4_mtu); 1848 if (if_getmtu(ifp) != val && val <= sc->sc_maxpktlen) { 1849 if_setmtu(ifp, val); 1850 if (if_getmtu(ifp) > val) 1851 if_setmtu(ifp, val); 1852 if (if_getflags(ifp) & IFF_DEBUG) 1853 log(LOG_INFO, "%s: MTU %d\n", DEVNAM(sc), val); 1854 } 1855 } 1856 1857 avail_v4 = le32toh(ic->ipv6_available); 1858 if ((if_getflags(ifp) & IFF_DEBUG) && avail_v4 & MBIM_IPCONF_HAS_ADDRINFO) { 1859 /* XXX FIXME: IPv6 configuration missing */ 1860 log(LOG_INFO, "%s: ignoring IPv6 configuration\n", DEVNAM(sc)); 1861 } 1862 if (state != -1) 1863 umb_newstate(sc, state, 0); 1864 1865 tryv6: 1866 done: 1867 return 1; 1868 } 1869 1870 static void 1871 umb_rx(struct umb_softc *sc) 1872 { 1873 mtx_assert(&sc->sc_mutex, MA_OWNED); 1874 1875 usbd_transfer_start(sc->sc_xfer[UMB_BULK_RX]); 1876 } 1877 1878 static void 1879 umb_rxeof(struct usb_xfer *xfer, usb_error_t status) 1880 { 1881 struct umb_softc *sc = usbd_xfer_softc(xfer); 1882 if_t ifp = GET_IFP(sc); 1883 int actlen; 1884 int aframes; 1885 int i; 1886 1887 DPRINTF("%s(%u): state=%u\n", __func__, status, USB_GET_STATE(xfer)); 1888 1889 mtx_assert(&sc->sc_mutex, MA_OWNED); 1890 1891 usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL); 1892 1893 switch (USB_GET_STATE(xfer)) { 1894 case USB_ST_TRANSFERRED: 1895 DPRINTF("received %u bytes in %u frames\n", actlen, aframes); 1896 1897 if (actlen == 0) { 1898 if (sc->sc_rx_nerr >= 4) 1899 /* throttle transfers */ 1900 usbd_xfer_set_interval(xfer, 500); 1901 else 1902 sc->sc_rx_nerr++; 1903 } 1904 else { 1905 /* disable throttling */ 1906 usbd_xfer_set_interval(xfer, 0); 1907 sc->sc_rx_nerr = 0; 1908 } 1909 1910 for(i = 0; i < aframes; i++) { 1911 umb_decap(sc, xfer, i); 1912 } 1913 1914 /* fall through */ 1915 case USB_ST_SETUP: 1916 usbd_xfer_set_frame_data(xfer, 0, sc->sc_rx_buf, 1917 sc->sc_rx_bufsz); 1918 usbd_xfer_set_frames(xfer, 1); 1919 usbd_transfer_submit(xfer); 1920 1921 umb_rxflush(sc); 1922 break; 1923 default: 1924 DPRINTF("rx error: %s\n", usbd_errstr(status)); 1925 1926 /* disable throttling */ 1927 usbd_xfer_set_interval(xfer, 0); 1928 1929 if (status != USB_ERR_CANCELLED) { 1930 /* try to clear stall first */ 1931 usbd_xfer_set_stall(xfer); 1932 usbd_xfer_set_frames(xfer, 0); 1933 usbd_transfer_submit(xfer); 1934 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 1935 } 1936 else if (++sc->sc_rx_nerr > 100) { 1937 log(LOG_ERR, "%s: too many rx errors, disabling\n", 1938 DEVNAM(sc)); 1939 umb_deactivate(sc->sc_dev); 1940 } 1941 break; 1942 } 1943 } 1944 1945 static void 1946 umb_rxflush(struct umb_softc *sc) 1947 { 1948 if_t ifp = GET_IFP(sc); 1949 struct mbuf *m; 1950 1951 mtx_assert(&sc->sc_mutex, MA_OWNED); 1952 1953 for (;;) { 1954 _IF_DEQUEUE(&sc->sc_rx_queue, m); 1955 if (m == NULL) 1956 break; 1957 1958 /* 1959 * The USB xfer has been resubmitted so it's safe to unlock now. 1960 */ 1961 mtx_unlock(&sc->sc_mutex); 1962 CURVNET_SET_QUIET(if_getvnet(ifp)); 1963 if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) 1964 if_input(ifp, m); 1965 else 1966 m_freem(m); 1967 CURVNET_RESTORE(); 1968 mtx_lock(&sc->sc_mutex); 1969 } 1970 } 1971 1972 static int 1973 umb_encap(struct umb_softc *sc, struct mbuf *m, struct usb_xfer *xfer) 1974 { 1975 struct ncm_header16 *hdr; 1976 struct ncm_pointer16 *ptr; 1977 int len; 1978 1979 KASSERT(sc->sc_tx_m == NULL, 1980 ("Assertion failed in umb_encap()")); 1981 1982 /* All size constraints have been validated by the caller! */ 1983 hdr = (struct ncm_header16 *)sc->sc_tx_buf; 1984 ptr = (struct ncm_pointer16 *)(hdr + 1); 1985 1986 USETDW(hdr->dwSignature, NCM_HDR16_SIG); 1987 USETW(hdr->wHeaderLength, sizeof (*hdr)); 1988 USETW(hdr->wSequence, sc->sc_tx_seq); 1989 sc->sc_tx_seq++; 1990 USETW(hdr->wNdpIndex, sizeof (*hdr)); 1991 1992 len = m->m_pkthdr.len; 1993 USETDW(ptr->dwSignature, MBIM_NCM_NTH16_SIG(umb_session_id)); 1994 USETW(ptr->wLength, sizeof (*ptr)); 1995 USETW(ptr->wNextNdpIndex, 0); 1996 USETW(ptr->dgram[0].wDatagramIndex, MBIM_HDR16_LEN); 1997 USETW(ptr->dgram[0].wDatagramLen, len); 1998 USETW(ptr->dgram[1].wDatagramIndex, 0); 1999 USETW(ptr->dgram[1].wDatagramLen, 0); 2000 2001 KASSERT(len + MBIM_HDR16_LEN <= sc->sc_tx_bufsz, 2002 ("Assertion failed in umb_encap()")); 2003 m_copydata(m, 0, len, (char *)(ptr + 1)); 2004 sc->sc_tx_m = m; 2005 len += MBIM_HDR16_LEN; 2006 USETW(hdr->wBlockLength, len); 2007 2008 usbd_xfer_set_frame_data(xfer, 0, sc->sc_tx_buf, len); 2009 usbd_xfer_set_interval(xfer, 0); 2010 usbd_xfer_set_frames(xfer, 1); 2011 2012 DPRINTFN(3, "%s: encap %d bytes\n", DEVNAM(sc), len); 2013 DDUMPN(5, sc->sc_tx_buf, len); 2014 return 0; 2015 } 2016 2017 static void 2018 umb_txeof(struct usb_xfer *xfer, usb_error_t status) 2019 { 2020 struct umb_softc *sc = usbd_xfer_softc(xfer); 2021 if_t ifp = GET_IFP(sc); 2022 struct mbuf *m; 2023 2024 DPRINTF("%s(%u) state=%u\n", __func__, status, USB_GET_STATE(xfer)); 2025 2026 mtx_assert(&sc->sc_mutex, MA_OWNED); 2027 2028 switch (USB_GET_STATE(xfer)) { 2029 case USB_ST_TRANSFERRED: 2030 if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE); 2031 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 2032 2033 umb_txflush(sc); 2034 2035 /* fall through */ 2036 case USB_ST_SETUP: 2037 tr_setup: 2038 if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0) 2039 break; 2040 2041 m = if_dequeue(ifp); /* XXX - IFAPI */ 2042 if (m == NULL) 2043 break; 2044 2045 if (umb_encap(sc, m, xfer)) { 2046 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 2047 umb_txflush(sc); 2048 break; 2049 } 2050 2051 BPF_MTAP(ifp, m); 2052 2053 if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0); 2054 usbd_transfer_submit(xfer); 2055 2056 break; 2057 2058 default: 2059 umb_txflush(sc); 2060 2061 /* count output errors */ 2062 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 2063 DPRINTF("tx error: %s\n", 2064 usbd_errstr(status)); 2065 2066 if (status != USB_ERR_CANCELLED) { 2067 /* try to clear stall first */ 2068 usbd_xfer_set_stall(xfer); 2069 goto tr_setup; 2070 } 2071 break; 2072 } 2073 } 2074 2075 static void 2076 umb_txflush(struct umb_softc *sc) 2077 { 2078 mtx_assert(&sc->sc_mutex, MA_OWNED); 2079 2080 if (sc->sc_tx_m != NULL) { 2081 m_freem(sc->sc_tx_m); 2082 sc->sc_tx_m = NULL; 2083 } 2084 } 2085 2086 static void 2087 umb_decap(struct umb_softc *sc, struct usb_xfer *xfer, int frame) 2088 { 2089 if_t ifp = GET_IFP(sc); 2090 char *buf; 2091 int len; 2092 char *dp; 2093 struct ncm_header16 *hdr16; 2094 struct ncm_header32 *hdr32; 2095 struct ncm_pointer16 *ptr16; 2096 struct ncm_pointer16_dgram *dgram16; 2097 struct ncm_pointer32_dgram *dgram32; 2098 uint32_t hsig, psig; 2099 int hlen, blen; 2100 int ptrlen, ptroff, dgentryoff; 2101 uint32_t doff, dlen; 2102 struct mbuf *m; 2103 2104 usbd_xfer_frame_data(xfer, frame, (void **)&buf, &len); 2105 DPRINTFN(4, "recv %d bytes\n", len); 2106 DDUMPN(5, buf, len); 2107 if (len < sizeof (*hdr16)) 2108 goto toosmall; 2109 2110 hdr16 = (struct ncm_header16 *)buf; 2111 hsig = UGETDW(hdr16->dwSignature); 2112 hlen = UGETW(hdr16->wHeaderLength); 2113 if (len < hlen) 2114 goto toosmall; 2115 if (len > sc->sc_rx_bufsz) { 2116 DPRINTF("packet too large (%d)\n", len); 2117 goto fail; 2118 } 2119 switch (hsig) { 2120 case NCM_HDR16_SIG: 2121 blen = UGETW(hdr16->wBlockLength); 2122 ptroff = UGETW(hdr16->wNdpIndex); 2123 if (hlen != sizeof (*hdr16)) { 2124 DPRINTF("%s: bad header len %d for NTH16 (exp %zu)\n", 2125 DEVNAM(sc), hlen, sizeof (*hdr16)); 2126 goto fail; 2127 } 2128 break; 2129 case NCM_HDR32_SIG: 2130 hdr32 = (struct ncm_header32 *)hdr16; 2131 blen = UGETDW(hdr32->dwBlockLength); 2132 ptroff = UGETDW(hdr32->dwNdpIndex); 2133 if (hlen != sizeof (*hdr32)) { 2134 DPRINTF("%s: bad header len %d for NTH32 (exp %zu)\n", 2135 DEVNAM(sc), hlen, sizeof (*hdr32)); 2136 goto fail; 2137 } 2138 break; 2139 default: 2140 DPRINTF("%s: unsupported NCM header signature (0x%08x)\n", 2141 DEVNAM(sc), hsig); 2142 goto fail; 2143 } 2144 if (len < blen) { 2145 DPRINTF("%s: bad NTB len (%d) for %d bytes of data\n", 2146 DEVNAM(sc), blen, len); 2147 goto fail; 2148 } 2149 2150 ptr16 = (struct ncm_pointer16 *)(buf + ptroff); 2151 psig = UGETDW(ptr16->dwSignature); 2152 ptrlen = UGETW(ptr16->wLength); 2153 if (len < ptrlen + ptroff) 2154 goto toosmall; 2155 if (!MBIM_NCM_NTH16_ISISG(psig) && !MBIM_NCM_NTH32_ISISG(psig)) { 2156 DPRINTF("%s: unsupported NCM pointer signature (0x%08x)\n", 2157 DEVNAM(sc), psig); 2158 goto fail; 2159 } 2160 2161 switch (hsig) { 2162 case NCM_HDR16_SIG: 2163 dgentryoff = offsetof(struct ncm_pointer16, dgram); 2164 break; 2165 case NCM_HDR32_SIG: 2166 dgentryoff = offsetof(struct ncm_pointer32, dgram); 2167 break; 2168 default: 2169 goto fail; 2170 } 2171 2172 while (dgentryoff < ptrlen) { 2173 switch (hsig) { 2174 case NCM_HDR16_SIG: 2175 if (ptroff + dgentryoff < sizeof (*dgram16)) 2176 goto done; 2177 dgram16 = (struct ncm_pointer16_dgram *) 2178 (buf + ptroff + dgentryoff); 2179 dgentryoff += sizeof (*dgram16); 2180 dlen = UGETW(dgram16->wDatagramLen); 2181 doff = UGETW(dgram16->wDatagramIndex); 2182 break; 2183 case NCM_HDR32_SIG: 2184 if (ptroff + dgentryoff < sizeof (*dgram32)) 2185 goto done; 2186 dgram32 = (struct ncm_pointer32_dgram *) 2187 (buf + ptroff + dgentryoff); 2188 dgentryoff += sizeof (*dgram32); 2189 dlen = UGETDW(dgram32->dwDatagramLen); 2190 doff = UGETDW(dgram32->dwDatagramIndex); 2191 break; 2192 default: 2193 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 2194 goto done; 2195 } 2196 2197 /* Terminating zero entry */ 2198 if (dlen == 0 || doff == 0) 2199 break; 2200 if (len < dlen + doff) { 2201 /* Skip giant datagram but continue processing */ 2202 DPRINTF("%s: datagram too large (%d @ off %d)\n", 2203 DEVNAM(sc), dlen, doff); 2204 continue; 2205 } 2206 2207 dp = buf + doff; 2208 DPRINTFN(3, "%s: decap %d bytes\n", DEVNAM(sc), dlen); 2209 m = m_devget(dp, dlen, 0, ifp, NULL); 2210 if (m == NULL) { 2211 if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); 2212 continue; 2213 } 2214 2215 /* enqueue for later when the lock can be released */ 2216 _IF_ENQUEUE(&sc->sc_rx_queue, m); 2217 2218 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); 2219 2220 } 2221 done: 2222 sc->sc_rx_nerr = 0; 2223 return; 2224 toosmall: 2225 DPRINTF("%s: packet too small (%d)\n", DEVNAM(sc), len); 2226 fail: 2227 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 2228 } 2229 2230 static usb_error_t 2231 umb_send_encap_command(struct umb_softc *sc, void *data, int len) 2232 { 2233 usb_device_request_t req; 2234 2235 if (len > sc->sc_ctrl_len) 2236 return USB_ERR_INVAL; 2237 2238 /* XXX FIXME: if (total len > sc->sc_ctrl_len) => must fragment */ 2239 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 2240 req.bRequest = UCDC_SEND_ENCAPSULATED_COMMAND; 2241 USETW(req.wValue, 0); 2242 USETW(req.wIndex, sc->sc_ctrl_ifaceno); 2243 USETW(req.wLength, len); 2244 mtx_unlock(&sc->sc_mutex); 2245 DELAY(umb_delay); 2246 mtx_lock(&sc->sc_mutex); 2247 return usbd_do_request_flags(sc->sc_udev, &sc->sc_mutex, &req, data, 0, 2248 NULL, umb_xfer_tout); 2249 } 2250 2251 static int 2252 umb_get_encap_response(struct umb_softc *sc, void *buf, int *len) 2253 { 2254 usb_device_request_t req; 2255 usb_error_t err; 2256 uint16_t l = *len; 2257 2258 req.bmRequestType = UT_READ_CLASS_INTERFACE; 2259 req.bRequest = UCDC_GET_ENCAPSULATED_RESPONSE; 2260 USETW(req.wValue, 0); 2261 USETW(req.wIndex, sc->sc_ctrl_ifaceno); 2262 USETW(req.wLength, l); 2263 /* XXX FIXME: re-assemble fragments */ 2264 2265 mtx_unlock(&sc->sc_mutex); 2266 DELAY(umb_delay); 2267 mtx_lock(&sc->sc_mutex); 2268 err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mutex, &req, buf, 2269 USB_SHORT_XFER_OK, &l, umb_xfer_tout); 2270 if (err == USB_ERR_NORMAL_COMPLETION) { 2271 *len = l; 2272 return 1; 2273 } 2274 DPRINTF("ctrl recv: %s\n", usbd_errstr(err)); 2275 return 0; 2276 } 2277 2278 static void 2279 umb_ctrl_msg(struct umb_softc *sc, uint32_t req, void *data, int len) 2280 { 2281 if_t ifp = GET_IFP(sc); 2282 uint32_t tid; 2283 struct mbim_msghdr *hdr = data; 2284 usb_error_t err; 2285 2286 if (sc->sc_dying) 2287 return; 2288 if (len < sizeof (*hdr)) 2289 return; 2290 tid = ++sc->sc_tid; 2291 2292 hdr->type = htole32(req); 2293 hdr->len = htole32(len); 2294 hdr->tid = htole32(tid); 2295 2296 #ifdef UMB_DEBUG 2297 if (umb_debug) { 2298 const char *op, *str; 2299 if (req == MBIM_COMMAND_MSG) { 2300 struct mbim_h2f_cmd *c = data; 2301 if (le32toh(c->op) == MBIM_CMDOP_SET) 2302 op = "set"; 2303 else 2304 op = "qry"; 2305 str = umb_cid2str(le32toh(c->cid)); 2306 } else { 2307 op = "snd"; 2308 str = umb_request2str(req); 2309 } 2310 DPRINTF("-> %s %s (tid %u)\n", op, str, tid); 2311 } 2312 #endif 2313 err = umb_send_encap_command(sc, data, len); 2314 if (err != USB_ERR_NORMAL_COMPLETION) { 2315 if (if_getflags(ifp) & IFF_DEBUG) 2316 log(LOG_ERR, "%s: send %s msg (tid %u) failed: %s\n", 2317 DEVNAM(sc), umb_request2str(req), tid, 2318 usbd_errstr(err)); 2319 2320 /* will affect other transactions, too */ 2321 usbd_transfer_stop(sc->sc_xfer[UMB_INTR_RX]); 2322 } else { 2323 DPRINTFN(2, "sent %s (tid %u)\n", 2324 umb_request2str(req), tid); 2325 DDUMPN(3, data, len); 2326 } 2327 return; 2328 } 2329 2330 static void 2331 umb_open(struct umb_softc *sc) 2332 { 2333 struct mbim_h2f_openmsg msg; 2334 2335 memset(&msg, 0, sizeof (msg)); 2336 msg.maxlen = htole32(sc->sc_ctrl_len); 2337 umb_ctrl_msg(sc, MBIM_OPEN_MSG, &msg, sizeof (msg)); 2338 return; 2339 } 2340 2341 static void 2342 umb_close(struct umb_softc *sc) 2343 { 2344 struct mbim_h2f_closemsg msg; 2345 2346 memset(&msg, 0, sizeof (msg)); 2347 umb_ctrl_msg(sc, MBIM_CLOSE_MSG, &msg, sizeof (msg)); 2348 } 2349 2350 static int 2351 umb_setpin(struct umb_softc *sc, int op, int is_puk, void *pin, int pinlen, 2352 void *newpin, int newpinlen) 2353 { 2354 struct mbim_cid_pin cp; 2355 int off; 2356 2357 if (pinlen == 0) 2358 return 0; 2359 if (pinlen < 0 || pinlen > MBIM_PIN_MAXLEN || 2360 newpinlen < 0 || newpinlen > MBIM_PIN_MAXLEN || 2361 op < 0 || op > MBIM_PIN_OP_CHANGE || 2362 (is_puk && op != MBIM_PIN_OP_ENTER)) 2363 return EINVAL; 2364 2365 memset(&cp, 0, sizeof (cp)); 2366 cp.type = htole32(is_puk ? MBIM_PIN_TYPE_PUK1 : MBIM_PIN_TYPE_PIN1); 2367 2368 off = offsetof(struct mbim_cid_pin, data); 2369 if (!umb_addstr(&cp, sizeof (cp), &off, pin, pinlen, 2370 &cp.pin_offs, &cp.pin_size)) 2371 return EINVAL; 2372 2373 cp.op = htole32(op); 2374 if (newpinlen) { 2375 if (!umb_addstr(&cp, sizeof (cp), &off, newpin, newpinlen, 2376 &cp.newpin_offs, &cp.newpin_size)) 2377 return EINVAL; 2378 } else { 2379 if ((op == MBIM_PIN_OP_CHANGE) || is_puk) 2380 return EINVAL; 2381 if (!umb_addstr(&cp, sizeof (cp), &off, NULL, 0, 2382 &cp.newpin_offs, &cp.newpin_size)) 2383 return EINVAL; 2384 } 2385 mtx_lock(&sc->sc_mutex); 2386 umb_cmd(sc, MBIM_CID_PIN, MBIM_CMDOP_SET, &cp, off); 2387 mtx_unlock(&sc->sc_mutex); 2388 return 0; 2389 } 2390 2391 static void 2392 umb_setdataclass(struct umb_softc *sc) 2393 { 2394 struct mbim_cid_registration_state rs; 2395 uint32_t classes; 2396 2397 if (sc->sc_info.supportedclasses == MBIM_DATACLASS_NONE) 2398 return; 2399 2400 memset(&rs, 0, sizeof (rs)); 2401 rs.regaction = htole32(MBIM_REGACTION_AUTOMATIC); 2402 classes = sc->sc_info.supportedclasses; 2403 if (sc->sc_info.preferredclasses != MBIM_DATACLASS_NONE) 2404 classes &= sc->sc_info.preferredclasses; 2405 rs.data_class = htole32(classes); 2406 mtx_lock(&sc->sc_mutex); 2407 umb_cmd(sc, MBIM_CID_REGISTER_STATE, MBIM_CMDOP_SET, &rs, sizeof (rs)); 2408 mtx_unlock(&sc->sc_mutex); 2409 } 2410 2411 static void 2412 umb_radio(struct umb_softc *sc, int on) 2413 { 2414 struct mbim_cid_radio_state s; 2415 2416 DPRINTF("set radio %s\n", on ? "on" : "off"); 2417 memset(&s, 0, sizeof (s)); 2418 s.state = htole32(on ? MBIM_RADIO_STATE_ON : MBIM_RADIO_STATE_OFF); 2419 umb_cmd(sc, MBIM_CID_RADIO_STATE, MBIM_CMDOP_SET, &s, sizeof (s)); 2420 } 2421 2422 static void 2423 umb_allocate_cid(struct umb_softc *sc) 2424 { 2425 umb_cmd1(sc, MBIM_CID_DEVICE_CAPS, MBIM_CMDOP_SET, 2426 umb_qmi_alloc_cid, sizeof (umb_qmi_alloc_cid), umb_uuid_qmi_mbim); 2427 } 2428 2429 static void 2430 umb_send_fcc_auth(struct umb_softc *sc) 2431 { 2432 uint8_t fccauth[sizeof (umb_qmi_fcc_auth)]; 2433 2434 if (sc->sc_cid == -1) { 2435 DPRINTF("missing CID, cannot send FCC auth\n"); 2436 umb_allocate_cid(sc); 2437 return; 2438 } 2439 memcpy(fccauth, umb_qmi_fcc_auth, sizeof (fccauth)); 2440 fccauth[UMB_QMI_CID_OFFS] = sc->sc_cid; 2441 umb_cmd1(sc, MBIM_CID_DEVICE_CAPS, MBIM_CMDOP_SET, 2442 fccauth, sizeof (fccauth), umb_uuid_qmi_mbim); 2443 } 2444 2445 static void 2446 umb_packet_service(struct umb_softc *sc, int attach) 2447 { 2448 struct mbim_cid_packet_service s; 2449 2450 DPRINTF("%s packet service\n", 2451 attach ? "attach" : "detach"); 2452 memset(&s, 0, sizeof (s)); 2453 s.action = htole32(attach ? 2454 MBIM_PKTSERVICE_ACTION_ATTACH : MBIM_PKTSERVICE_ACTION_DETACH); 2455 umb_cmd(sc, MBIM_CID_PACKET_SERVICE, MBIM_CMDOP_SET, &s, sizeof (s)); 2456 } 2457 2458 static void 2459 umb_connect(struct umb_softc *sc) 2460 { 2461 if_t ifp = GET_IFP(sc); 2462 2463 if (sc->sc_info.regstate == MBIM_REGSTATE_ROAMING && !sc->sc_roaming) { 2464 log(LOG_INFO, "%s: connection disabled in roaming network\n", 2465 DEVNAM(sc)); 2466 return; 2467 } 2468 if (if_getflags(ifp) & IFF_DEBUG) 2469 log(LOG_DEBUG, "%s: connecting ...\n", DEVNAM(sc)); 2470 umb_send_connect(sc, MBIM_CONNECT_ACTIVATE); 2471 } 2472 2473 static void 2474 umb_disconnect(struct umb_softc *sc) 2475 { 2476 if_t ifp = GET_IFP(sc); 2477 2478 if (if_getflags(ifp) & IFF_DEBUG) 2479 log(LOG_DEBUG, "%s: disconnecting ...\n", DEVNAM(sc)); 2480 umb_send_connect(sc, MBIM_CONNECT_DEACTIVATE); 2481 } 2482 2483 static void 2484 umb_send_connect(struct umb_softc *sc, int command) 2485 { 2486 struct mbim_cid_connect *c; 2487 int off; 2488 2489 /* Too large for the stack */ 2490 mtx_unlock(&sc->sc_mutex); 2491 c = malloc(sizeof (*c), M_MBIM_CID_CONNECT, M_WAITOK | M_ZERO); 2492 mtx_lock(&sc->sc_mutex); 2493 c->sessionid = htole32(umb_session_id); 2494 c->command = htole32(command); 2495 off = offsetof(struct mbim_cid_connect, data); 2496 if (!umb_addstr(c, sizeof (*c), &off, sc->sc_info.apn, 2497 sc->sc_info.apnlen, &c->access_offs, &c->access_size)) 2498 goto done; 2499 if (!umb_addstr(c, sizeof (*c), &off, sc->sc_info.username, 2500 sc->sc_info.usernamelen, &c->user_offs, &c->user_size)) 2501 goto done; 2502 if (!umb_addstr(c, sizeof (*c), &off, sc->sc_info.password, 2503 sc->sc_info.passwordlen, &c->passwd_offs, &c->passwd_size)) 2504 goto done; 2505 c->authprot = htole32(MBIM_AUTHPROT_NONE); 2506 c->compression = htole32(MBIM_COMPRESSION_NONE); 2507 c->iptype = htole32(MBIM_CONTEXT_IPTYPE_IPV4); 2508 memcpy(c->context, umb_uuid_context_internet, sizeof (c->context)); 2509 umb_cmd(sc, MBIM_CID_CONNECT, MBIM_CMDOP_SET, c, off); 2510 done: 2511 free(c, M_MBIM_CID_CONNECT); 2512 return; 2513 } 2514 2515 static void 2516 umb_qry_ipconfig(struct umb_softc *sc) 2517 { 2518 struct mbim_cid_ip_configuration_info ipc; 2519 2520 memset(&ipc, 0, sizeof (ipc)); 2521 ipc.sessionid = htole32(umb_session_id); 2522 umb_cmd(sc, MBIM_CID_IP_CONFIGURATION, MBIM_CMDOP_QRY, 2523 &ipc, sizeof (ipc)); 2524 } 2525 2526 static void 2527 umb_cmd(struct umb_softc *sc, int cid, int op, const void *data, int len) 2528 { 2529 umb_cmd1(sc, cid, op, data, len, umb_uuid_basic_connect); 2530 } 2531 2532 static void 2533 umb_cmd1(struct umb_softc *sc, int cid, int op, const void *data, int len, 2534 uint8_t *uuid) 2535 { 2536 struct mbim_h2f_cmd *cmd; 2537 int totlen; 2538 2539 /* XXX FIXME support sending fragments */ 2540 if (sizeof (*cmd) + len > sc->sc_ctrl_len) { 2541 DPRINTF("set %s msg too long: cannot send\n", 2542 umb_cid2str(cid)); 2543 return; 2544 } 2545 cmd = sc->sc_ctrl_msg; 2546 memset(cmd, 0, sizeof (*cmd)); 2547 cmd->frag.nfrag = htole32(1); 2548 memcpy(cmd->devid, uuid, sizeof (cmd->devid)); 2549 cmd->cid = htole32(cid); 2550 cmd->op = htole32(op); 2551 cmd->infolen = htole32(len); 2552 totlen = sizeof (*cmd); 2553 if (len > 0) { 2554 memcpy(cmd + 1, data, len); 2555 totlen += len; 2556 } 2557 umb_ctrl_msg(sc, MBIM_COMMAND_MSG, cmd, totlen); 2558 } 2559 2560 static void 2561 umb_command_done(struct umb_softc *sc, void *data, int len) 2562 { 2563 struct mbim_f2h_cmddone *cmd = data; 2564 if_t ifp = GET_IFP(sc); 2565 uint32_t status; 2566 uint32_t cid; 2567 uint32_t infolen; 2568 int qmimsg = 0; 2569 2570 if (len < sizeof (*cmd)) { 2571 DPRINTF("discard short %s message\n", 2572 umb_request2str(le32toh(cmd->hdr.type))); 2573 return; 2574 } 2575 cid = le32toh(cmd->cid); 2576 if (memcmp(cmd->devid, umb_uuid_basic_connect, sizeof (cmd->devid))) { 2577 if (memcmp(cmd->devid, umb_uuid_qmi_mbim, 2578 sizeof (cmd->devid))) { 2579 DPRINTF("discard %s message for other UUID '%s'\n", 2580 umb_request2str(le32toh(cmd->hdr.type)), 2581 umb_uuid2str(cmd->devid)); 2582 return; 2583 } else 2584 qmimsg = 1; 2585 } 2586 2587 status = le32toh(cmd->status); 2588 switch (status) { 2589 case MBIM_STATUS_SUCCESS: 2590 break; 2591 case MBIM_STATUS_NOT_INITIALIZED: 2592 if (if_getflags(ifp) & IFF_DEBUG) 2593 log(LOG_ERR, "%s: SIM not initialized (PIN missing)\n", 2594 DEVNAM(sc)); 2595 return; 2596 case MBIM_STATUS_PIN_REQUIRED: 2597 sc->sc_info.pin_state = UMB_PIN_REQUIRED; 2598 /*FALLTHROUGH*/ 2599 default: 2600 if (if_getflags(ifp) & IFF_DEBUG) 2601 log(LOG_ERR, "%s: set/qry %s failed: %s\n", DEVNAM(sc), 2602 umb_cid2str(cid), umb_status2str(status)); 2603 return; 2604 } 2605 2606 infolen = le32toh(cmd->infolen); 2607 if (len < sizeof (*cmd) + infolen) { 2608 DPRINTF("discard truncated %s message (want %d, got %d)\n", 2609 umb_cid2str(cid), 2610 (int)sizeof (*cmd) + infolen, len); 2611 return; 2612 } 2613 if (qmimsg) { 2614 if (sc->sc_flags & UMBFLG_FCC_AUTH_REQUIRED) 2615 umb_decode_qmi(sc, cmd->info, infolen); 2616 } else { 2617 DPRINTFN(2, "set/qry %s done\n", 2618 umb_cid2str(cid)); 2619 umb_decode_cid(sc, cid, cmd->info, infolen); 2620 } 2621 } 2622 2623 static void 2624 umb_decode_cid(struct umb_softc *sc, uint32_t cid, void *data, int len) 2625 { 2626 int ok = 1; 2627 2628 switch (cid) { 2629 case MBIM_CID_DEVICE_CAPS: 2630 ok = umb_decode_devices_caps(sc, data, len); 2631 break; 2632 case MBIM_CID_SUBSCRIBER_READY_STATUS: 2633 ok = umb_decode_subscriber_status(sc, data, len); 2634 break; 2635 case MBIM_CID_RADIO_STATE: 2636 ok = umb_decode_radio_state(sc, data, len); 2637 break; 2638 case MBIM_CID_PIN: 2639 ok = umb_decode_pin(sc, data, len); 2640 break; 2641 case MBIM_CID_REGISTER_STATE: 2642 ok = umb_decode_register_state(sc, data, len); 2643 break; 2644 case MBIM_CID_PACKET_SERVICE: 2645 ok = umb_decode_packet_service(sc, data, len); 2646 break; 2647 case MBIM_CID_SIGNAL_STATE: 2648 ok = umb_decode_signal_state(sc, data, len); 2649 break; 2650 case MBIM_CID_CONNECT: 2651 ok = umb_decode_connect_info(sc, data, len); 2652 break; 2653 case MBIM_CID_IP_CONFIGURATION: 2654 ok = umb_decode_ip_configuration(sc, data, len); 2655 break; 2656 default: 2657 /* 2658 * Note: the above list is incomplete and only contains 2659 * mandatory CIDs from the BASIC_CONNECT set. 2660 * So alternate values are not unusual. 2661 */ 2662 DPRINTFN(4, "ignore %s\n", umb_cid2str(cid)); 2663 break; 2664 } 2665 if (!ok) 2666 DPRINTF("discard %s with bad info length %d\n", 2667 umb_cid2str(cid), len); 2668 return; 2669 } 2670 2671 static void 2672 umb_decode_qmi(struct umb_softc *sc, uint8_t *data, int len) 2673 { 2674 uint8_t srv; 2675 uint16_t msg, tlvlen; 2676 uint32_t val; 2677 2678 #define UMB_QMI_QMUXLEN 6 2679 if (len < UMB_QMI_QMUXLEN) 2680 goto tooshort; 2681 2682 srv = data[4]; 2683 data += UMB_QMI_QMUXLEN; 2684 len -= UMB_QMI_QMUXLEN; 2685 2686 #define UMB_GET16(p) ((uint16_t)*p | (uint16_t)*(p + 1) << 8) 2687 #define UMB_GET32(p) ((uint32_t)*p | (uint32_t)*(p + 1) << 8 | \ 2688 (uint32_t)*(p + 2) << 16 |(uint32_t)*(p + 3) << 24) 2689 switch (srv) { 2690 case 0: /* ctl */ 2691 #define UMB_QMI_CTLLEN 6 2692 if (len < UMB_QMI_CTLLEN) 2693 goto tooshort; 2694 msg = UMB_GET16(&data[2]); 2695 tlvlen = UMB_GET16(&data[4]); 2696 data += UMB_QMI_CTLLEN; 2697 len -= UMB_QMI_CTLLEN; 2698 break; 2699 case 2: /* dms */ 2700 #define UMB_QMI_DMSLEN 7 2701 if (len < UMB_QMI_DMSLEN) 2702 goto tooshort; 2703 msg = UMB_GET16(&data[3]); 2704 tlvlen = UMB_GET16(&data[5]); 2705 data += UMB_QMI_DMSLEN; 2706 len -= UMB_QMI_DMSLEN; 2707 break; 2708 default: 2709 DPRINTF("discard QMI message for unknown service type %d\n", 2710 srv); 2711 return; 2712 } 2713 2714 if (len < tlvlen) 2715 goto tooshort; 2716 2717 #define UMB_QMI_TLVLEN 3 2718 while (len > 0) { 2719 if (len < UMB_QMI_TLVLEN) 2720 goto tooshort; 2721 tlvlen = UMB_GET16(&data[1]); 2722 if (len < UMB_QMI_TLVLEN + tlvlen) 2723 goto tooshort; 2724 switch (data[0]) { 2725 case 1: /* allocation info */ 2726 if (msg == 0x0022) { /* Allocate CID */ 2727 if (tlvlen != 2 || data[3] != 2) /* dms */ 2728 break; 2729 sc->sc_cid = data[4]; 2730 DPRINTF("QMI CID %d allocated\n", 2731 sc->sc_cid); 2732 umb_newstate(sc, UMB_S_CID, UMB_NS_DONT_DROP); 2733 } 2734 break; 2735 case 2: /* response */ 2736 if (tlvlen != sizeof (val)) 2737 break; 2738 val = UMB_GET32(&data[3]); 2739 switch (msg) { 2740 case 0x0022: /* Allocate CID */ 2741 if (val != 0) { 2742 log(LOG_ERR, "%s: allocation of QMI CID" 2743 " failed, error 0x%x\n", DEVNAM(sc), 2744 val); 2745 /* XXX how to proceed? */ 2746 return; 2747 } 2748 break; 2749 case 0x555f: /* Send FCC Authentication */ 2750 if (val == 0) 2751 DPRINTF("%s: send FCC " 2752 "Authentication succeeded\n", 2753 DEVNAM(sc)); 2754 else if (val == 0x001a0001) 2755 DPRINTF("%s: FCC Authentication " 2756 "not required\n", DEVNAM(sc)); 2757 else 2758 log(LOG_INFO, "%s: send FCC " 2759 "Authentication failed, " 2760 "error 0x%x\n", DEVNAM(sc), val); 2761 2762 /* FCC Auth is needed only once after power-on*/ 2763 sc->sc_flags &= ~UMBFLG_FCC_AUTH_REQUIRED; 2764 2765 /* Try to proceed anyway */ 2766 DPRINTF("init: turning radio on ...\n"); 2767 umb_radio(sc, 1); 2768 break; 2769 default: 2770 break; 2771 } 2772 break; 2773 default: 2774 break; 2775 } 2776 data += UMB_QMI_TLVLEN + tlvlen; 2777 len -= UMB_QMI_TLVLEN + tlvlen; 2778 } 2779 return; 2780 2781 tooshort: 2782 DPRINTF("discard short QMI message\n"); 2783 return; 2784 } 2785 2786 static void 2787 umb_intr(struct usb_xfer *xfer, usb_error_t status) 2788 { 2789 struct umb_softc *sc = usbd_xfer_softc(xfer); 2790 struct usb_cdc_notification notification; 2791 struct usb_page_cache *pc; 2792 if_t ifp = GET_IFP(sc); 2793 int total_len; 2794 2795 mtx_assert(&sc->sc_mutex, MA_OWNED); 2796 2797 /* FIXME use actlen or total_len? */ 2798 usbd_xfer_status(xfer, &total_len, NULL, NULL, NULL); 2799 2800 switch (USB_GET_STATE(xfer)) { 2801 case USB_ST_TRANSFERRED: 2802 DPRINTF("Received %d bytes\n", total_len); 2803 2804 if (total_len < UCDC_NOTIFICATION_LENGTH) { 2805 DPRINTF("short notification (%d<%d)\n", 2806 total_len, UCDC_NOTIFICATION_LENGTH); 2807 return; 2808 } 2809 2810 pc = usbd_xfer_get_frame(xfer, 0); 2811 usbd_copy_out(pc, 0, ¬ification, sizeof (notification)); 2812 2813 if (notification.bmRequestType != UCDC_NOTIFICATION) { 2814 DPRINTF("unexpected notification (type=0x%02x)\n", 2815 notification.bmRequestType); 2816 return; 2817 } 2818 2819 switch (notification.bNotification) { 2820 case UCDC_N_NETWORK_CONNECTION: 2821 if (if_getflags(ifp) & IFF_DEBUG) 2822 log(LOG_DEBUG, "%s: network %sconnected\n", 2823 DEVNAM(sc), 2824 UGETW(notification.wValue) 2825 ? "" : "dis"); 2826 break; 2827 case UCDC_N_RESPONSE_AVAILABLE: 2828 DPRINTFN(2, "umb_intr: response available\n"); 2829 ++sc->sc_nresp; 2830 umb_add_task(sc, umb_get_response_task, 2831 &sc->sc_proc_get_response_task[0].hdr, 2832 &sc->sc_proc_get_response_task[1].hdr, 2833 0); 2834 break; 2835 case UCDC_N_CONNECTION_SPEED_CHANGE: 2836 DPRINTFN(2, "umb_intr: connection speed changed\n"); 2837 break; 2838 default: 2839 DPRINTF("unexpected notification (0x%02x)\n", 2840 notification.bNotification); 2841 break; 2842 } 2843 /* fallthrough */ 2844 case USB_ST_SETUP: 2845 tr_setup: 2846 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); 2847 usbd_transfer_submit(xfer); 2848 break; 2849 default: 2850 if (status != USB_ERR_CANCELLED) { 2851 /* start clear stall */ 2852 usbd_xfer_set_stall(xfer); 2853 goto tr_setup; 2854 } 2855 break; 2856 } 2857 } 2858 2859 /* 2860 * Diagnostic routines 2861 */ 2862 static char * 2863 umb_ntop(struct sockaddr *sa) 2864 { 2865 #define NUMBUFS 4 2866 static char astr[NUMBUFS][INET_ADDRSTRLEN]; 2867 static unsigned nbuf = 0; 2868 char *s; 2869 2870 s = astr[nbuf++]; 2871 if (nbuf >= NUMBUFS) 2872 nbuf = 0; 2873 2874 switch (sa->sa_family) { 2875 case AF_INET: 2876 default: 2877 inet_ntop(AF_INET, &satosin(sa)->sin_addr, s, sizeof (astr[0])); 2878 break; 2879 case AF_INET6: 2880 inet_ntop(AF_INET6, &satosin6(sa)->sin6_addr, s, 2881 sizeof (astr[0])); 2882 break; 2883 } 2884 return s; 2885 } 2886 2887 #ifdef UMB_DEBUG 2888 static char * 2889 umb_uuid2str(uint8_t uuid[MBIM_UUID_LEN]) 2890 { 2891 static char uuidstr[2 * MBIM_UUID_LEN + 5]; 2892 2893 #define UUID_BFMT "%02X" 2894 #define UUID_SEP "-" 2895 snprintf(uuidstr, sizeof (uuidstr), 2896 UUID_BFMT UUID_BFMT UUID_BFMT UUID_BFMT UUID_SEP 2897 UUID_BFMT UUID_BFMT UUID_SEP 2898 UUID_BFMT UUID_BFMT UUID_SEP 2899 UUID_BFMT UUID_BFMT UUID_SEP 2900 UUID_BFMT UUID_BFMT UUID_BFMT UUID_BFMT UUID_BFMT UUID_BFMT, 2901 uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], 2902 uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11], 2903 uuid[12], uuid[13], uuid[14], uuid[15]); 2904 return uuidstr; 2905 } 2906 2907 static void 2908 umb_dump(void *buf, int len) 2909 { 2910 int i = 0; 2911 uint8_t *c = buf; 2912 2913 if (len == 0) 2914 return; 2915 while (i < len) { 2916 if ((i % 16) == 0) { 2917 if (i > 0) 2918 log(LOG_DEBUG, "\n"); 2919 log(LOG_DEBUG, "%4d: ", i); 2920 } 2921 log(LOG_DEBUG, " %02x", *c); 2922 c++; 2923 i++; 2924 } 2925 log(LOG_DEBUG, "\n"); 2926 } 2927 #endif /* UMB_DEBUG */ 2928 2929 DRIVER_MODULE(umb, uhub, umb_driver, NULL, NULL); 2930 MODULE_DEPEND(umb, usb, 1, 1, 1); 2931