xref: /freebsd/sys/dev/usb/net/if_umb.c (revision 82c41c9ffc42b8e95eabae7cdc4e0bfbbcad51fb)
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
umb_probe(device_t dev)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
umb_attach(device_t dev)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
umb_attach_task(struct usb_proc_msg * msg)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
umb_detach(device_t dev)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
umb_ncm_setup(struct umb_softc * sc,struct usb_config * config)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
umb_handle_request(device_t dev,const void * preq,void ** pptr,uint16_t * plen,uint16_t offset,uint8_t * pstate)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
umb_suspend(device_t dev)698 umb_suspend(device_t dev)
699 {
700 	device_printf(dev, "Suspending\n");
701 	return (0);
702 }
703 
704 static int
umb_resume(device_t dev)705 umb_resume(device_t dev)
706 {
707 	device_printf(dev, "Resuming\n");
708 	return (0);
709 }
710 
711 static int
umb_deactivate(device_t dev)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
umb_close_bulkpipes(struct umb_softc * sc)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
umb_ioctl(if_t ifp,u_long cmd,caddr_t data)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
umb_init(void * arg)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
umb_input(if_t ifp,struct mbuf * m)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
umb_output(if_t ifp,struct mbuf * m,const struct sockaddr * dst,struct route * rtp)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
umb_start(if_t ifp)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
umb_start_task(struct usb_proc_msg * msg)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
umb_statechg_timeout(void * arg)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
umb_mediachange(if_t ifp)977 umb_mediachange(if_t  ifp)
978 {
979 	return 0;
980 }
981 
982 static void
umb_mediastatus(if_t ifp,struct ifmediareq * imr)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
umb_add_task(struct umb_softc * sc,usb_proc_callback_t callback,struct usb_proc_msg * t0,struct usb_proc_msg * t1,int sync)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
umb_newstate(struct umb_softc * sc,enum umb_state newstate,int flags)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
umb_state_task(struct usb_proc_msg * msg)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
umb_up(struct umb_softc * sc)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
umb_down(struct umb_softc * sc,int force)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
umb_get_response_task(struct usb_proc_msg * msg)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
umb_decode_response(struct umb_softc * sc,void * response,int len)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
umb_handle_indicate_status_msg(struct umb_softc * sc,void * data,int len)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
umb_handle_opendone_msg(struct umb_softc * sc,void * data,int len)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
umb_handle_closedone_msg(struct umb_softc * sc,void * data,int len)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
umb_getinfobuf(char * in,int inlen,uint32_t offs,uint32_t sz,void * out,size_t outlen)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 	memset(out, 0, outlen);
1381 	if ((uint64_t)inlen >= (uint64_t)offs + (uint64_t)sz)
1382 		memcpy(out, in + offs, MIN(sz, outlen));
1383 }
1384 
1385 static inline int
umb_padding(void * data,int len,size_t sz)1386 umb_padding(void *data, int len, size_t sz)
1387 {
1388 	char *p = data;
1389 	int np = 0;
1390 
1391 	while (len < sz && (len % 4) != 0) {
1392 		*p++ = '\0';
1393 		len++;
1394 		np++;
1395 	}
1396 	return np;
1397 }
1398 
1399 static inline int
umb_addstr(void * buf,size_t bufsz,int * offs,void * str,int slen,uint32_t * offsmember,uint32_t * sizemember)1400 umb_addstr(void *buf, size_t bufsz, int *offs, void *str, int slen,
1401     uint32_t *offsmember, uint32_t *sizemember)
1402 {
1403 	if (*offs + slen > bufsz)
1404 		return 0;
1405 
1406 	*sizemember = htole32((uint32_t)slen);
1407 	if (slen && str) {
1408 		*offsmember = htole32((uint32_t)*offs);
1409 		memcpy((char *)buf + *offs, str, slen);
1410 		*offs += slen;
1411 		*offs += umb_padding(buf, *offs, bufsz);
1412 	} else
1413 		*offsmember = htole32(0);
1414 	return 1;
1415 }
1416 
1417 static void
umb_in_len2mask(struct in_addr * mask,int len)1418 umb_in_len2mask(struct in_addr *mask, int len)
1419 {
1420 	int i;
1421 	u_char *p;
1422 
1423 	p = (u_char *)mask;
1424 	memset(mask, 0, sizeof (*mask));
1425 	for (i = 0; i < len / 8; i++)
1426 		p[i] = 0xff;
1427 	if (len % 8)
1428 		p[i] = (0xff00 >> (len % 8)) & 0xff;
1429 }
1430 
1431 static int
umb_decode_register_state(struct umb_softc * sc,void * data,int len)1432 umb_decode_register_state(struct umb_softc *sc, void *data, int len)
1433 {
1434 	struct mbim_cid_registration_state_info *rs = data;
1435 	if_t ifp = GET_IFP(sc);
1436 
1437 	if (len < sizeof (*rs))
1438 		return 0;
1439 	sc->sc_info.nwerror = le32toh(rs->nwerror);
1440 	sc->sc_info.regstate = le32toh(rs->regstate);
1441 	sc->sc_info.regmode = le32toh(rs->regmode);
1442 	sc->sc_info.cellclass = le32toh(rs->curcellclass);
1443 
1444 	/* XXX should we remember the provider_id? */
1445 	umb_getinfobuf(data, len, rs->provname_offs, rs->provname_size,
1446 	    sc->sc_info.provider, sizeof (sc->sc_info.provider));
1447 	umb_getinfobuf(data, len, rs->roamingtxt_offs, rs->roamingtxt_size,
1448 	    sc->sc_info.roamingtxt, sizeof (sc->sc_info.roamingtxt));
1449 
1450 	DPRINTFN(2, "%s, availclass 0x%x, class 0x%x, regmode %d\n",
1451 	    umb_regstate(sc->sc_info.regstate),
1452 	    le32toh(rs->availclasses), sc->sc_info.cellclass,
1453 	    sc->sc_info.regmode);
1454 
1455 	if (sc->sc_info.regstate == MBIM_REGSTATE_ROAMING &&
1456 	    !sc->sc_roaming &&
1457 	    sc->sc_info.activation == MBIM_ACTIVATION_STATE_ACTIVATED) {
1458 		if (if_getflags(ifp) & IFF_DEBUG)
1459 			log(LOG_INFO,
1460 			    "%s: disconnecting from roaming network\n",
1461 			    DEVNAM(sc));
1462 		umb_disconnect(sc);
1463 	}
1464 	return 1;
1465 }
1466 
1467 static int
umb_decode_devices_caps(struct umb_softc * sc,void * data,int len)1468 umb_decode_devices_caps(struct umb_softc *sc, void *data, int len)
1469 {
1470 	struct mbim_cid_device_caps *dc = data;
1471 
1472 	if (len < sizeof (*dc))
1473 		return 0;
1474 	sc->sc_maxsessions = le32toh(dc->max_sessions);
1475 	sc->sc_info.supportedclasses = le32toh(dc->dataclass);
1476 	umb_getinfobuf(data, len, dc->devid_offs, dc->devid_size,
1477 	    sc->sc_info.devid, sizeof (sc->sc_info.devid));
1478 	umb_getinfobuf(data, len, dc->fwinfo_offs, dc->fwinfo_size,
1479 	    sc->sc_info.fwinfo, sizeof (sc->sc_info.fwinfo));
1480 	umb_getinfobuf(data, len, dc->hwinfo_offs, dc->hwinfo_size,
1481 	    sc->sc_info.hwinfo, sizeof (sc->sc_info.hwinfo));
1482 	DPRINTFN(2, "max sessions %d, supported classes 0x%x\n",
1483 	    sc->sc_maxsessions, sc->sc_info.supportedclasses);
1484 	return 1;
1485 }
1486 
1487 static int
umb_decode_subscriber_status(struct umb_softc * sc,void * data,int len)1488 umb_decode_subscriber_status(struct umb_softc *sc, void *data, int len)
1489 {
1490 	struct mbim_cid_subscriber_ready_info *si = data;
1491 	if_t ifp = GET_IFP(sc);
1492 	int	npn;
1493 
1494 	if (len < sizeof (*si))
1495 		return 0;
1496 	sc->sc_info.sim_state = le32toh(si->ready);
1497 
1498 	umb_getinfobuf(data, len, si->sid_offs, si->sid_size,
1499 	    sc->sc_info.sid, sizeof (sc->sc_info.sid));
1500 	umb_getinfobuf(data, len, si->icc_offs, si->icc_size,
1501 	    sc->sc_info.iccid, sizeof (sc->sc_info.iccid));
1502 
1503 	npn = le32toh(si->no_pn);
1504 	if (npn > 0)
1505 		umb_getinfobuf(data, len, si->pn[0].offs, si->pn[0].size,
1506 		    sc->sc_info.pn, sizeof (sc->sc_info.pn));
1507 	else
1508 		memset(sc->sc_info.pn, 0, sizeof (sc->sc_info.pn));
1509 
1510 	if (sc->sc_info.sim_state == MBIM_SIMSTATE_LOCKED)
1511 		sc->sc_info.pin_state = UMB_PIN_REQUIRED;
1512 	if (if_getflags(ifp) & IFF_DEBUG)
1513 		log(LOG_INFO, "%s: SIM %s\n", DEVNAM(sc),
1514 		    umb_simstate(sc->sc_info.sim_state));
1515 	if (sc->sc_info.sim_state == MBIM_SIMSTATE_INITIALIZED)
1516 		umb_newstate(sc, UMB_S_SIMREADY, UMB_NS_DONT_DROP);
1517 	return 1;
1518 }
1519 
1520 static int
umb_decode_radio_state(struct umb_softc * sc,void * data,int len)1521 umb_decode_radio_state(struct umb_softc *sc, void *data, int len)
1522 {
1523 	struct mbim_cid_radio_state_info *rs = data;
1524 	if_t ifp = GET_IFP(sc);
1525 
1526 	if (len < sizeof (*rs))
1527 		return 0;
1528 
1529 	sc->sc_info.hw_radio_on =
1530 	    (le32toh(rs->hw_state) == MBIM_RADIO_STATE_ON) ? 1 : 0;
1531 	sc->sc_info.sw_radio_on =
1532 	    (le32toh(rs->sw_state) == MBIM_RADIO_STATE_ON) ? 1 : 0;
1533 	if (!sc->sc_info.hw_radio_on) {
1534 		device_printf(sc->sc_dev, "radio is disabled by hardware switch\n");
1535 		/*
1536 		 * XXX do we need a time to poll the state of the rfkill switch
1537 		 *	or will the device send an unsolicited notification
1538 		 *	in case the state changes?
1539 		 */
1540 		umb_newstate(sc, UMB_S_OPEN, 0);
1541 	} else if (!sc->sc_info.sw_radio_on) {
1542 		if (if_getflags(ifp) & IFF_DEBUG)
1543 			log(LOG_INFO, "%s: radio is off\n", DEVNAM(sc));
1544 		umb_newstate(sc, UMB_S_OPEN, 0);
1545 	} else
1546 		umb_newstate(sc, UMB_S_RADIO, UMB_NS_DONT_DROP);
1547 	return 1;
1548 }
1549 
1550 static int
umb_decode_pin(struct umb_softc * sc,void * data,int len)1551 umb_decode_pin(struct umb_softc *sc, void *data, int len)
1552 {
1553 	struct mbim_cid_pin_info *pi = data;
1554 	if_t ifp = GET_IFP(sc);
1555 	uint32_t	attempts_left;
1556 
1557 	if (len < sizeof (*pi))
1558 		return 0;
1559 
1560 	attempts_left = le32toh(pi->remaining_attempts);
1561 	if (attempts_left != 0xffffffff)
1562 		sc->sc_info.pin_attempts_left = attempts_left;
1563 
1564 	switch (le32toh(pi->state)) {
1565 	case MBIM_PIN_STATE_UNLOCKED:
1566 		sc->sc_info.pin_state = UMB_PIN_UNLOCKED;
1567 		break;
1568 	case MBIM_PIN_STATE_LOCKED:
1569 		switch (le32toh(pi->type)) {
1570 		case MBIM_PIN_TYPE_PIN1:
1571 			sc->sc_info.pin_state = UMB_PIN_REQUIRED;
1572 			break;
1573 		case MBIM_PIN_TYPE_PUK1:
1574 			sc->sc_info.pin_state = UMB_PUK_REQUIRED;
1575 			break;
1576 		case MBIM_PIN_TYPE_PIN2:
1577 		case MBIM_PIN_TYPE_PUK2:
1578 			/* Assume that PIN1 was accepted */
1579 			sc->sc_info.pin_state = UMB_PIN_UNLOCKED;
1580 			break;
1581 		}
1582 		break;
1583 	}
1584 	if (if_getflags(ifp) & IFF_DEBUG)
1585 		log(LOG_INFO, "%s: %s state %s (%d attempts left)\n",
1586 		    DEVNAM(sc), umb_pin_type(le32toh(pi->type)),
1587 		    (le32toh(pi->state) == MBIM_PIN_STATE_UNLOCKED) ?
1588 			"unlocked" : "locked",
1589 		    le32toh(pi->remaining_attempts));
1590 
1591 	/*
1592 	 * In case the PIN was set after IFF_UP, retrigger the state machine
1593 	 */
1594 	umb_add_task(sc, umb_state_task,
1595 			&sc->sc_proc_state_task[0].hdr,
1596 			&sc->sc_proc_state_task[1].hdr, 0);
1597 	return 1;
1598 }
1599 
1600 static int
umb_decode_packet_service(struct umb_softc * sc,void * data,int len)1601 umb_decode_packet_service(struct umb_softc *sc, void *data, int len)
1602 {
1603 	struct mbim_cid_packet_service_info *psi = data;
1604 	int	 state, highestclass;
1605 	uint64_t up_speed, down_speed;
1606 	if_t ifp = GET_IFP(sc);
1607 
1608 	if (len < sizeof (*psi))
1609 		return 0;
1610 
1611 	sc->sc_info.nwerror = le32toh(psi->nwerror);
1612 	state = le32toh(psi->state);
1613 	highestclass = le32toh(psi->highest_dataclass);
1614 	up_speed = le64toh(psi->uplink_speed);
1615 	down_speed = le64toh(psi->downlink_speed);
1616 	if (sc->sc_info.packetstate  != state ||
1617 	    sc->sc_info.uplink_speed != up_speed ||
1618 	    sc->sc_info.downlink_speed != down_speed) {
1619 		if (if_getflags(ifp) & IFF_DEBUG) {
1620 			log(LOG_INFO, "%s: packet service ", DEVNAM(sc));
1621 			if (sc->sc_info.packetstate  != state)
1622 				log(LOG_INFO, "changed from %s to ",
1623 				    umb_packet_state(sc->sc_info.packetstate));
1624 			log(LOG_INFO, "%s, class %s, speed: %" PRIu64 " up / %" PRIu64 " down\n",
1625 			    umb_packet_state(state),
1626 			    umb_dataclass(highestclass), up_speed, down_speed);
1627 		}
1628 	}
1629 	sc->sc_info.packetstate = state;
1630 	sc->sc_info.highestclass = highestclass;
1631 	sc->sc_info.uplink_speed = up_speed;
1632 	sc->sc_info.downlink_speed = down_speed;
1633 
1634 	if (sc->sc_info.regmode == MBIM_REGMODE_AUTOMATIC) {
1635 		/*
1636 		 * For devices using automatic registration mode, just proceed,
1637 		 * once registration has completed.
1638 		 */
1639 		if (if_getflags(ifp) & IFF_UP) {
1640 			switch (sc->sc_info.regstate) {
1641 			case MBIM_REGSTATE_HOME:
1642 			case MBIM_REGSTATE_ROAMING:
1643 			case MBIM_REGSTATE_PARTNER:
1644 				umb_newstate(sc, UMB_S_ATTACHED,
1645 				    UMB_NS_DONT_DROP);
1646 				break;
1647 			default:
1648 				break;
1649 			}
1650 		} else
1651 			umb_newstate(sc, UMB_S_SIMREADY, UMB_NS_DONT_RAISE);
1652 	} else switch (sc->sc_info.packetstate) {
1653 	case MBIM_PKTSERVICE_STATE_ATTACHED:
1654 		umb_newstate(sc, UMB_S_ATTACHED, UMB_NS_DONT_DROP);
1655 		break;
1656 	case MBIM_PKTSERVICE_STATE_DETACHED:
1657 		umb_newstate(sc, UMB_S_SIMREADY, UMB_NS_DONT_RAISE);
1658 		break;
1659 	}
1660 	return 1;
1661 }
1662 
1663 static int
umb_decode_signal_state(struct umb_softc * sc,void * data,int len)1664 umb_decode_signal_state(struct umb_softc *sc, void *data, int len)
1665 {
1666 	struct mbim_cid_signal_state *ss = data;
1667 	if_t ifp = GET_IFP(sc);
1668 	int	 rssi;
1669 
1670 	if (len < sizeof (*ss))
1671 		return 0;
1672 
1673 	if (le32toh(ss->rssi) == 99)
1674 		rssi = UMB_VALUE_UNKNOWN;
1675 	else {
1676 		rssi = -113 + 2 * le32toh(ss->rssi);
1677 		if ((if_getflags(ifp) & IFF_DEBUG) && sc->sc_info.rssi != rssi &&
1678 		    sc->sc_state >= UMB_S_CONNECTED)
1679 			log(LOG_INFO, "%s: rssi %d dBm\n", DEVNAM(sc), rssi);
1680 	}
1681 	sc->sc_info.rssi = rssi;
1682 	sc->sc_info.ber = le32toh(ss->err_rate);
1683 	if (sc->sc_info.ber == -99)
1684 		sc->sc_info.ber = UMB_VALUE_UNKNOWN;
1685 	return 1;
1686 }
1687 
1688 static int
umb_decode_connect_info(struct umb_softc * sc,void * data,int len)1689 umb_decode_connect_info(struct umb_softc *sc, void *data, int len)
1690 {
1691 	struct mbim_cid_connect_info *ci = data;
1692 	if_t ifp = GET_IFP(sc);
1693 	int	 act;
1694 
1695 	if (len < sizeof (*ci))
1696 		return 0;
1697 
1698 	if (le32toh(ci->sessionid) != umb_session_id) {
1699 		DPRINTF("discard connection info for session %u\n",
1700 		    le32toh(ci->sessionid));
1701 		return 1;
1702 	}
1703 	if (memcmp(ci->context, umb_uuid_context_internet,
1704 	    sizeof (ci->context))) {
1705 		DPRINTF("discard connection info for other context\n");
1706 		return 1;
1707 	}
1708 	act = le32toh(ci->activation);
1709 	if (sc->sc_info.activation != act) {
1710 		if (if_getflags(ifp) & IFF_DEBUG)
1711 			log(LOG_INFO, "%s: connection %s\n", DEVNAM(sc),
1712 			    umb_activation(act));
1713 		if ((if_getflags(ifp) & IFF_DEBUG) &&
1714 		    le32toh(ci->iptype) != MBIM_CONTEXT_IPTYPE_DEFAULT &&
1715 		    le32toh(ci->iptype) != MBIM_CONTEXT_IPTYPE_IPV4)
1716 			log(LOG_DEBUG, "%s: got iptype %d connection\n",
1717 			    DEVNAM(sc), le32toh(ci->iptype));
1718 
1719 		sc->sc_info.activation = act;
1720 		sc->sc_info.nwerror = le32toh(ci->nwerror);
1721 
1722 		if (sc->sc_info.activation == MBIM_ACTIVATION_STATE_ACTIVATED)
1723 			umb_newstate(sc, UMB_S_CONNECTED, UMB_NS_DONT_DROP);
1724 		else if (sc->sc_info.activation ==
1725 		    MBIM_ACTIVATION_STATE_DEACTIVATED)
1726 			umb_newstate(sc, UMB_S_ATTACHED, 0);
1727 		/* else: other states are purely transitional */
1728 	}
1729 	return 1;
1730 }
1731 
1732 static int
umb_add_inet_config(struct umb_softc * sc,struct in_addr ip,u_int prefixlen,struct in_addr gw)1733 umb_add_inet_config(struct umb_softc *sc, struct in_addr ip, u_int prefixlen,
1734     struct in_addr gw)
1735 {
1736 	if_t ifp = GET_IFP(sc);
1737 	struct in_aliasreq ifra;
1738 	struct sockaddr_in *sin;
1739 	int	 rv;
1740 
1741 	memset(&ifra, 0, sizeof (ifra));
1742 	sin = (struct sockaddr_in *)&ifra.ifra_addr;
1743 	sin->sin_family = AF_INET;
1744 	sin->sin_len = sizeof (*sin);
1745 	sin->sin_addr = ip;
1746 
1747 	sin = (struct sockaddr_in *)&ifra.ifra_dstaddr;
1748 	sin->sin_family = AF_INET;
1749 	sin->sin_len = sizeof (*sin);
1750 	sin->sin_addr = gw;
1751 
1752 	sin = (struct sockaddr_in *)&ifra.ifra_mask;
1753 	sin->sin_family = AF_INET;
1754 	sin->sin_len = sizeof (*sin);
1755 	umb_in_len2mask(&sin->sin_addr,
1756 	    MIN(prefixlen, sizeof (struct in_addr) * 8));
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
umb_decode_ip_configuration(struct umb_softc * sc,void * data,int len)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
umb_rx(struct umb_softc * sc)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
umb_rxeof(struct usb_xfer * xfer,usb_error_t status)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
umb_rxflush(struct umb_softc * sc)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
umb_encap(struct umb_softc * sc,struct mbuf * m,struct usb_xfer * xfer)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
umb_txeof(struct usb_xfer * xfer,usb_error_t status)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
umb_txflush(struct umb_softc * sc)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
umb_decap(struct umb_softc * sc,struct usb_xfer * xfer,int frame)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 	if (len < ptroff)
2151 		goto toosmall;
2152 	ptr16 = (struct ncm_pointer16 *)(buf + ptroff);
2153 	psig = UGETDW(ptr16->dwSignature);
2154 	ptrlen = UGETW(ptr16->wLength);
2155 	if ((uint64_t)len < (uint64_t)ptrlen + (uint64_t)ptroff)
2156 		goto toosmall;
2157 	if (!MBIM_NCM_NTH16_ISISG(psig) && !MBIM_NCM_NTH32_ISISG(psig)) {
2158 		DPRINTF("%s: unsupported NCM pointer signature (0x%08x)\n",
2159 		    DEVNAM(sc), psig);
2160 		goto fail;
2161 	}
2162 
2163 	switch (hsig) {
2164 	case NCM_HDR16_SIG:
2165 		dgentryoff = offsetof(struct ncm_pointer16, dgram);
2166 		break;
2167 	case NCM_HDR32_SIG:
2168 		dgentryoff = offsetof(struct ncm_pointer32, dgram);
2169 		break;
2170 	default:
2171 		goto fail;
2172 	}
2173 
2174 	while (dgentryoff < ptrlen) {
2175 		switch (hsig) {
2176 		case NCM_HDR16_SIG:
2177 			if (ptroff + dgentryoff < sizeof (*dgram16))
2178 				goto done;
2179 			dgram16 = (struct ncm_pointer16_dgram *)
2180 			    (buf + ptroff + dgentryoff);
2181 			dgentryoff += sizeof (*dgram16);
2182 			dlen = UGETW(dgram16->wDatagramLen);
2183 			doff = UGETW(dgram16->wDatagramIndex);
2184 			break;
2185 		case NCM_HDR32_SIG:
2186 			if (ptroff + dgentryoff < sizeof (*dgram32))
2187 				goto done;
2188 			dgram32 = (struct ncm_pointer32_dgram *)
2189 			    (buf + ptroff + dgentryoff);
2190 			dgentryoff += sizeof (*dgram32);
2191 			dlen = UGETDW(dgram32->dwDatagramLen);
2192 			doff = UGETDW(dgram32->dwDatagramIndex);
2193 			break;
2194 		default:
2195 			if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
2196 			goto done;
2197 		}
2198 
2199 		/* Terminating zero entry */
2200 		if (dlen == 0 || doff == 0)
2201 			break;
2202 		if ((uint64_t)len < (uint64_t)dlen + (uint64_t)doff) {
2203 			/* Skip giant datagram but continue processing */
2204 			DPRINTF("%s: datagram too large (%d @ off %d)\n",
2205 			    DEVNAM(sc), dlen, doff);
2206 			continue;
2207 		}
2208 
2209 		dp = buf + doff;
2210 		DPRINTFN(3, "%s: decap %d bytes\n", DEVNAM(sc), dlen);
2211 		m = m_devget(dp, dlen, 0, ifp, NULL);
2212 		if (m == NULL) {
2213 			if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
2214 			continue;
2215 		}
2216 
2217 		/* enqueue for later when the lock can be released */
2218 		_IF_ENQUEUE(&sc->sc_rx_queue, m);
2219 
2220 		if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
2221 
2222 	}
2223 done:
2224 	sc->sc_rx_nerr = 0;
2225 	return;
2226 toosmall:
2227 	DPRINTF("%s: packet too small (%d)\n", DEVNAM(sc), len);
2228 fail:
2229 	if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
2230 }
2231 
2232 static usb_error_t
umb_send_encap_command(struct umb_softc * sc,void * data,int len)2233 umb_send_encap_command(struct umb_softc *sc, void *data, int len)
2234 {
2235 	usb_device_request_t req;
2236 
2237 	if (len > sc->sc_ctrl_len)
2238 		return USB_ERR_INVAL;
2239 
2240 	/* XXX FIXME: if (total len > sc->sc_ctrl_len) => must fragment */
2241 	req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
2242 	req.bRequest = UCDC_SEND_ENCAPSULATED_COMMAND;
2243 	USETW(req.wValue, 0);
2244 	USETW(req.wIndex, sc->sc_ctrl_ifaceno);
2245 	USETW(req.wLength, len);
2246 	mtx_unlock(&sc->sc_mutex);
2247 	DELAY(umb_delay);
2248 	mtx_lock(&sc->sc_mutex);
2249 	return usbd_do_request_flags(sc->sc_udev, &sc->sc_mutex, &req, data, 0,
2250 			NULL, umb_xfer_tout);
2251 }
2252 
2253 static int
umb_get_encap_response(struct umb_softc * sc,void * buf,int * len)2254 umb_get_encap_response(struct umb_softc *sc, void *buf, int *len)
2255 {
2256 	usb_device_request_t req;
2257 	usb_error_t err;
2258 	uint16_t l = *len;
2259 
2260 	req.bmRequestType = UT_READ_CLASS_INTERFACE;
2261 	req.bRequest = UCDC_GET_ENCAPSULATED_RESPONSE;
2262 	USETW(req.wValue, 0);
2263 	USETW(req.wIndex, sc->sc_ctrl_ifaceno);
2264 	USETW(req.wLength, l);
2265 	/* XXX FIXME: re-assemble fragments */
2266 
2267 	mtx_unlock(&sc->sc_mutex);
2268 	DELAY(umb_delay);
2269 	mtx_lock(&sc->sc_mutex);
2270 	err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mutex, &req, buf,
2271 			USB_SHORT_XFER_OK, &l, umb_xfer_tout);
2272 	if (err == USB_ERR_NORMAL_COMPLETION) {
2273 		*len = l;
2274 		return 1;
2275 	}
2276 	DPRINTF("ctrl recv: %s\n", usbd_errstr(err));
2277 	return 0;
2278 }
2279 
2280 static void
umb_ctrl_msg(struct umb_softc * sc,uint32_t req,void * data,int len)2281 umb_ctrl_msg(struct umb_softc *sc, uint32_t req, void *data, int len)
2282 {
2283 	if_t ifp = GET_IFP(sc);
2284 	uint32_t tid;
2285 	struct mbim_msghdr *hdr = data;
2286 	usb_error_t err;
2287 
2288 	if (sc->sc_dying)
2289 		return;
2290 	if (len < sizeof (*hdr))
2291 		return;
2292 	tid = ++sc->sc_tid;
2293 
2294 	hdr->type = htole32(req);
2295 	hdr->len = htole32(len);
2296 	hdr->tid = htole32(tid);
2297 
2298 #ifdef UMB_DEBUG
2299 	if (umb_debug) {
2300 		const char *op, *str;
2301 		if (req == MBIM_COMMAND_MSG) {
2302 			struct mbim_h2f_cmd *c = data;
2303 			if (le32toh(c->op) == MBIM_CMDOP_SET)
2304 				op = "set";
2305 			else
2306 				op = "qry";
2307 			str = umb_cid2str(le32toh(c->cid));
2308 		} else {
2309 			op = "snd";
2310 			str = umb_request2str(req);
2311 		}
2312 		DPRINTF("-> %s %s (tid %u)\n", op, str, tid);
2313 	}
2314 #endif
2315 	err = umb_send_encap_command(sc, data, len);
2316 	if (err != USB_ERR_NORMAL_COMPLETION) {
2317 		if (if_getflags(ifp) & IFF_DEBUG)
2318 			log(LOG_ERR, "%s: send %s msg (tid %u) failed: %s\n",
2319 			    DEVNAM(sc), umb_request2str(req), tid,
2320 			    usbd_errstr(err));
2321 
2322 		/* will affect other transactions, too */
2323 		usbd_transfer_stop(sc->sc_xfer[UMB_INTR_RX]);
2324 	} else {
2325 		DPRINTFN(2, "sent %s (tid %u)\n",
2326 		    umb_request2str(req), tid);
2327 		DDUMPN(3, data, len);
2328 	}
2329 	return;
2330 }
2331 
2332 static void
umb_open(struct umb_softc * sc)2333 umb_open(struct umb_softc *sc)
2334 {
2335 	struct mbim_h2f_openmsg msg;
2336 
2337 	memset(&msg, 0, sizeof (msg));
2338 	msg.maxlen = htole32(sc->sc_ctrl_len);
2339 	umb_ctrl_msg(sc, MBIM_OPEN_MSG, &msg, sizeof (msg));
2340 	return;
2341 }
2342 
2343 static void
umb_close(struct umb_softc * sc)2344 umb_close(struct umb_softc *sc)
2345 {
2346 	struct mbim_h2f_closemsg msg;
2347 
2348 	memset(&msg, 0, sizeof (msg));
2349 	umb_ctrl_msg(sc, MBIM_CLOSE_MSG, &msg, sizeof (msg));
2350 }
2351 
2352 static int
umb_setpin(struct umb_softc * sc,int op,int is_puk,void * pin,int pinlen,void * newpin,int newpinlen)2353 umb_setpin(struct umb_softc *sc, int op, int is_puk, void *pin, int pinlen,
2354     void *newpin, int newpinlen)
2355 {
2356 	struct mbim_cid_pin cp;
2357 	int	 off;
2358 
2359 	if (pinlen == 0)
2360 		return 0;
2361 	if (pinlen < 0 || pinlen > MBIM_PIN_MAXLEN ||
2362 	    newpinlen < 0 || newpinlen > MBIM_PIN_MAXLEN ||
2363 	    op < 0 || op > MBIM_PIN_OP_CHANGE ||
2364 	    (is_puk && op != MBIM_PIN_OP_ENTER))
2365 		return EINVAL;
2366 
2367 	memset(&cp, 0, sizeof (cp));
2368 	cp.type = htole32(is_puk ? MBIM_PIN_TYPE_PUK1 : MBIM_PIN_TYPE_PIN1);
2369 
2370 	off = offsetof(struct mbim_cid_pin, data);
2371 	if (!umb_addstr(&cp, sizeof (cp), &off, pin, pinlen,
2372 	    &cp.pin_offs, &cp.pin_size))
2373 		return EINVAL;
2374 
2375 	cp.op  = htole32(op);
2376 	if (newpinlen) {
2377 		if (!umb_addstr(&cp, sizeof (cp), &off, newpin, newpinlen,
2378 		    &cp.newpin_offs, &cp.newpin_size))
2379 			return EINVAL;
2380 	} else {
2381 		if ((op == MBIM_PIN_OP_CHANGE) || is_puk)
2382 			return EINVAL;
2383 		if (!umb_addstr(&cp, sizeof (cp), &off, NULL, 0,
2384 		    &cp.newpin_offs, &cp.newpin_size))
2385 			return EINVAL;
2386 	}
2387 	mtx_lock(&sc->sc_mutex);
2388 	umb_cmd(sc, MBIM_CID_PIN, MBIM_CMDOP_SET, &cp, off);
2389 	mtx_unlock(&sc->sc_mutex);
2390 	return 0;
2391 }
2392 
2393 static void
umb_setdataclass(struct umb_softc * sc)2394 umb_setdataclass(struct umb_softc *sc)
2395 {
2396 	struct mbim_cid_registration_state rs;
2397 	uint32_t	 classes;
2398 
2399 	if (sc->sc_info.supportedclasses == MBIM_DATACLASS_NONE)
2400 		return;
2401 
2402 	memset(&rs, 0, sizeof (rs));
2403 	rs.regaction = htole32(MBIM_REGACTION_AUTOMATIC);
2404 	classes = sc->sc_info.supportedclasses;
2405 	if (sc->sc_info.preferredclasses != MBIM_DATACLASS_NONE)
2406 		classes &= sc->sc_info.preferredclasses;
2407 	rs.data_class = htole32(classes);
2408 	mtx_lock(&sc->sc_mutex);
2409 	umb_cmd(sc, MBIM_CID_REGISTER_STATE, MBIM_CMDOP_SET, &rs, sizeof (rs));
2410 	mtx_unlock(&sc->sc_mutex);
2411 }
2412 
2413 static void
umb_radio(struct umb_softc * sc,int on)2414 umb_radio(struct umb_softc *sc, int on)
2415 {
2416 	struct mbim_cid_radio_state s;
2417 
2418 	DPRINTF("set radio %s\n", on ? "on" : "off");
2419 	memset(&s, 0, sizeof (s));
2420 	s.state = htole32(on ? MBIM_RADIO_STATE_ON : MBIM_RADIO_STATE_OFF);
2421 	umb_cmd(sc, MBIM_CID_RADIO_STATE, MBIM_CMDOP_SET, &s, sizeof (s));
2422 }
2423 
2424 static void
umb_allocate_cid(struct umb_softc * sc)2425 umb_allocate_cid(struct umb_softc *sc)
2426 {
2427 	umb_cmd1(sc, MBIM_CID_DEVICE_CAPS, MBIM_CMDOP_SET,
2428 	    umb_qmi_alloc_cid, sizeof (umb_qmi_alloc_cid), umb_uuid_qmi_mbim);
2429 }
2430 
2431 static void
umb_send_fcc_auth(struct umb_softc * sc)2432 umb_send_fcc_auth(struct umb_softc *sc)
2433 {
2434 	uint8_t	 fccauth[sizeof (umb_qmi_fcc_auth)];
2435 
2436 	if (sc->sc_cid == -1) {
2437 		DPRINTF("missing CID, cannot send FCC auth\n");
2438 		umb_allocate_cid(sc);
2439 		return;
2440 	}
2441 	memcpy(fccauth, umb_qmi_fcc_auth, sizeof (fccauth));
2442 	fccauth[UMB_QMI_CID_OFFS] = sc->sc_cid;
2443 	umb_cmd1(sc, MBIM_CID_DEVICE_CAPS, MBIM_CMDOP_SET,
2444 	    fccauth, sizeof (fccauth), umb_uuid_qmi_mbim);
2445 }
2446 
2447 static void
umb_packet_service(struct umb_softc * sc,int attach)2448 umb_packet_service(struct umb_softc *sc, int attach)
2449 {
2450 	struct mbim_cid_packet_service	s;
2451 
2452 	DPRINTF("%s packet service\n",
2453 	    attach ? "attach" : "detach");
2454 	memset(&s, 0, sizeof (s));
2455 	s.action = htole32(attach ?
2456 	    MBIM_PKTSERVICE_ACTION_ATTACH : MBIM_PKTSERVICE_ACTION_DETACH);
2457 	umb_cmd(sc, MBIM_CID_PACKET_SERVICE, MBIM_CMDOP_SET, &s, sizeof (s));
2458 }
2459 
2460 static void
umb_connect(struct umb_softc * sc)2461 umb_connect(struct umb_softc *sc)
2462 {
2463 	if_t ifp = GET_IFP(sc);
2464 
2465 	if (sc->sc_info.regstate == MBIM_REGSTATE_ROAMING && !sc->sc_roaming) {
2466 		log(LOG_INFO, "%s: connection disabled in roaming network\n",
2467 		    DEVNAM(sc));
2468 		return;
2469 	}
2470 	if (if_getflags(ifp) & IFF_DEBUG)
2471 		log(LOG_DEBUG, "%s: connecting ...\n", DEVNAM(sc));
2472 	umb_send_connect(sc, MBIM_CONNECT_ACTIVATE);
2473 }
2474 
2475 static void
umb_disconnect(struct umb_softc * sc)2476 umb_disconnect(struct umb_softc *sc)
2477 {
2478 	if_t ifp = GET_IFP(sc);
2479 
2480 	if (if_getflags(ifp) & IFF_DEBUG)
2481 		log(LOG_DEBUG, "%s: disconnecting ...\n", DEVNAM(sc));
2482 	umb_send_connect(sc, MBIM_CONNECT_DEACTIVATE);
2483 }
2484 
2485 static void
umb_send_connect(struct umb_softc * sc,int command)2486 umb_send_connect(struct umb_softc *sc, int command)
2487 {
2488 	struct mbim_cid_connect *c;
2489 	int	 off;
2490 
2491 	/* Too large for the stack */
2492 	mtx_unlock(&sc->sc_mutex);
2493 	c = malloc(sizeof (*c), M_MBIM_CID_CONNECT, M_WAITOK | M_ZERO);
2494 	mtx_lock(&sc->sc_mutex);
2495 	c->sessionid = htole32(umb_session_id);
2496 	c->command = htole32(command);
2497 	off = offsetof(struct mbim_cid_connect, data);
2498 	if (!umb_addstr(c, sizeof (*c), &off, sc->sc_info.apn,
2499 	    sc->sc_info.apnlen, &c->access_offs, &c->access_size))
2500 		goto done;
2501 	if (!umb_addstr(c, sizeof (*c), &off, sc->sc_info.username,
2502 	    sc->sc_info.usernamelen, &c->user_offs, &c->user_size))
2503 		goto done;
2504 	if (!umb_addstr(c, sizeof (*c), &off, sc->sc_info.password,
2505 	    sc->sc_info.passwordlen, &c->passwd_offs, &c->passwd_size))
2506 		goto done;
2507 	c->authprot = htole32(MBIM_AUTHPROT_NONE);
2508 	c->compression = htole32(MBIM_COMPRESSION_NONE);
2509 	c->iptype = htole32(MBIM_CONTEXT_IPTYPE_IPV4);
2510 	memcpy(c->context, umb_uuid_context_internet, sizeof (c->context));
2511 	umb_cmd(sc, MBIM_CID_CONNECT, MBIM_CMDOP_SET, c, off);
2512 done:
2513 	free(c, M_MBIM_CID_CONNECT);
2514 	return;
2515 }
2516 
2517 static void
umb_qry_ipconfig(struct umb_softc * sc)2518 umb_qry_ipconfig(struct umb_softc *sc)
2519 {
2520 	struct mbim_cid_ip_configuration_info ipc;
2521 
2522 	memset(&ipc, 0, sizeof (ipc));
2523 	ipc.sessionid = htole32(umb_session_id);
2524 	umb_cmd(sc, MBIM_CID_IP_CONFIGURATION, MBIM_CMDOP_QRY,
2525 	    &ipc, sizeof (ipc));
2526 }
2527 
2528 static void
umb_cmd(struct umb_softc * sc,int cid,int op,const void * data,int len)2529 umb_cmd(struct umb_softc *sc, int cid, int op, const void *data, int len)
2530 {
2531 	umb_cmd1(sc, cid, op, data, len, umb_uuid_basic_connect);
2532 }
2533 
2534 static void
umb_cmd1(struct umb_softc * sc,int cid,int op,const void * data,int len,uint8_t * uuid)2535 umb_cmd1(struct umb_softc *sc, int cid, int op, const void *data, int len,
2536     uint8_t *uuid)
2537 {
2538 	struct mbim_h2f_cmd *cmd;
2539 	int	totlen;
2540 
2541 	/* XXX FIXME support sending fragments */
2542 	if (sizeof (*cmd) + len > sc->sc_ctrl_len) {
2543 		DPRINTF("set %s msg too long: cannot send\n",
2544 		    umb_cid2str(cid));
2545 		return;
2546 	}
2547 	cmd = sc->sc_ctrl_msg;
2548 	memset(cmd, 0, sizeof (*cmd));
2549 	cmd->frag.nfrag = htole32(1);
2550 	memcpy(cmd->devid, uuid, sizeof (cmd->devid));
2551 	cmd->cid = htole32(cid);
2552 	cmd->op = htole32(op);
2553 	cmd->infolen = htole32(len);
2554 	totlen = sizeof (*cmd);
2555 	if (len > 0) {
2556 		memcpy(cmd + 1, data, len);
2557 		totlen += len;
2558 	}
2559 	umb_ctrl_msg(sc, MBIM_COMMAND_MSG, cmd, totlen);
2560 }
2561 
2562 static void
umb_command_done(struct umb_softc * sc,void * data,int len)2563 umb_command_done(struct umb_softc *sc, void *data, int len)
2564 {
2565 	struct mbim_f2h_cmddone *cmd = data;
2566 	if_t ifp = GET_IFP(sc);
2567 	uint32_t status;
2568 	uint32_t cid;
2569 	uint32_t infolen;
2570 	int	 qmimsg = 0;
2571 
2572 	if (len < sizeof (*cmd)) {
2573 		DPRINTF("discard short %s message\n",
2574 		    umb_request2str(le32toh(cmd->hdr.type)));
2575 		return;
2576 	}
2577 	cid = le32toh(cmd->cid);
2578 	if (memcmp(cmd->devid, umb_uuid_basic_connect, sizeof (cmd->devid))) {
2579 		if (memcmp(cmd->devid, umb_uuid_qmi_mbim,
2580 		    sizeof (cmd->devid))) {
2581 			DPRINTF("discard %s message for other UUID '%s'\n",
2582 			    umb_request2str(le32toh(cmd->hdr.type)),
2583 			    umb_uuid2str(cmd->devid));
2584 			return;
2585 		} else
2586 			qmimsg = 1;
2587 	}
2588 
2589 	status = le32toh(cmd->status);
2590 	switch (status) {
2591 	case MBIM_STATUS_SUCCESS:
2592 		break;
2593 	case MBIM_STATUS_NOT_INITIALIZED:
2594 		if (if_getflags(ifp) & IFF_DEBUG)
2595 			log(LOG_ERR, "%s: SIM not initialized (PIN missing)\n",
2596 			    DEVNAM(sc));
2597 		return;
2598 	case MBIM_STATUS_PIN_REQUIRED:
2599 		sc->sc_info.pin_state = UMB_PIN_REQUIRED;
2600 		/*FALLTHROUGH*/
2601 	default:
2602 		if (if_getflags(ifp) & IFF_DEBUG)
2603 			log(LOG_ERR, "%s: set/qry %s failed: %s\n", DEVNAM(sc),
2604 			    umb_cid2str(cid), umb_status2str(status));
2605 		return;
2606 	}
2607 
2608 	infolen = le32toh(cmd->infolen);
2609 	if (len < sizeof (*cmd) + infolen) {
2610 		DPRINTF("discard truncated %s message (want %d, got %d)\n",
2611 		    umb_cid2str(cid),
2612 		    (int)sizeof (*cmd) + infolen, len);
2613 		return;
2614 	}
2615 	if (qmimsg) {
2616 		if (sc->sc_flags & UMBFLG_FCC_AUTH_REQUIRED)
2617 			umb_decode_qmi(sc, cmd->info, infolen);
2618 	} else {
2619 		DPRINTFN(2, "set/qry %s done\n",
2620 		    umb_cid2str(cid));
2621 		umb_decode_cid(sc, cid, cmd->info, infolen);
2622 	}
2623 }
2624 
2625 static void
umb_decode_cid(struct umb_softc * sc,uint32_t cid,void * data,int len)2626 umb_decode_cid(struct umb_softc *sc, uint32_t cid, void *data, int len)
2627 {
2628 	int	 ok = 1;
2629 
2630 	switch (cid) {
2631 	case MBIM_CID_DEVICE_CAPS:
2632 		ok = umb_decode_devices_caps(sc, data, len);
2633 		break;
2634 	case MBIM_CID_SUBSCRIBER_READY_STATUS:
2635 		ok = umb_decode_subscriber_status(sc, data, len);
2636 		break;
2637 	case MBIM_CID_RADIO_STATE:
2638 		ok = umb_decode_radio_state(sc, data, len);
2639 		break;
2640 	case MBIM_CID_PIN:
2641 		ok = umb_decode_pin(sc, data, len);
2642 		break;
2643 	case MBIM_CID_REGISTER_STATE:
2644 		ok = umb_decode_register_state(sc, data, len);
2645 		break;
2646 	case MBIM_CID_PACKET_SERVICE:
2647 		ok = umb_decode_packet_service(sc, data, len);
2648 		break;
2649 	case MBIM_CID_SIGNAL_STATE:
2650 		ok = umb_decode_signal_state(sc, data, len);
2651 		break;
2652 	case MBIM_CID_CONNECT:
2653 		ok = umb_decode_connect_info(sc, data, len);
2654 		break;
2655 	case MBIM_CID_IP_CONFIGURATION:
2656 		ok = umb_decode_ip_configuration(sc, data, len);
2657 		break;
2658 	default:
2659 		/*
2660 		 * Note: the above list is incomplete and only contains
2661 		 *	mandatory CIDs from the BASIC_CONNECT set.
2662 		 *	So alternate values are not unusual.
2663 		 */
2664 		DPRINTFN(4, "ignore %s\n", umb_cid2str(cid));
2665 		break;
2666 	}
2667 	if (!ok)
2668 		DPRINTF("discard %s with bad info length %d\n",
2669 		    umb_cid2str(cid), len);
2670 	return;
2671 }
2672 
2673 static void
umb_decode_qmi(struct umb_softc * sc,uint8_t * data,int len)2674 umb_decode_qmi(struct umb_softc *sc, uint8_t *data, int len)
2675 {
2676 	uint8_t	srv;
2677 	uint16_t msg, tlvlen;
2678 	uint32_t val;
2679 
2680 #define UMB_QMI_QMUXLEN		6
2681 	if (len < UMB_QMI_QMUXLEN)
2682 		goto tooshort;
2683 
2684 	srv = data[4];
2685 	data += UMB_QMI_QMUXLEN;
2686 	len -= UMB_QMI_QMUXLEN;
2687 
2688 #define UMB_GET16(p)	((uint16_t)*p | (uint16_t)*(p + 1) << 8)
2689 #define UMB_GET32(p)	((uint32_t)*p | (uint32_t)*(p + 1) << 8 | \
2690 			    (uint32_t)*(p + 2) << 16 |(uint32_t)*(p + 3) << 24)
2691 	switch (srv) {
2692 	case 0:	/* ctl */
2693 #define UMB_QMI_CTLLEN		6
2694 		if (len < UMB_QMI_CTLLEN)
2695 			goto tooshort;
2696 		msg = UMB_GET16(&data[2]);
2697 		tlvlen = UMB_GET16(&data[4]);
2698 		data += UMB_QMI_CTLLEN;
2699 		len -= UMB_QMI_CTLLEN;
2700 		break;
2701 	case 2:	/* dms  */
2702 #define UMB_QMI_DMSLEN		7
2703 		if (len < UMB_QMI_DMSLEN)
2704 			goto tooshort;
2705 		msg = UMB_GET16(&data[3]);
2706 		tlvlen = UMB_GET16(&data[5]);
2707 		data += UMB_QMI_DMSLEN;
2708 		len -= UMB_QMI_DMSLEN;
2709 		break;
2710 	default:
2711 		DPRINTF("discard QMI message for unknown service type %d\n",
2712 		    srv);
2713 		return;
2714 	}
2715 
2716 	if (len < tlvlen)
2717 		goto tooshort;
2718 
2719 #define UMB_QMI_TLVLEN		3
2720 	while (len > 0) {
2721 		if (len < UMB_QMI_TLVLEN)
2722 			goto tooshort;
2723 		tlvlen = UMB_GET16(&data[1]);
2724 		if (len < UMB_QMI_TLVLEN + tlvlen)
2725 			goto tooshort;
2726 		switch (data[0]) {
2727 		case 1:	/* allocation info */
2728 			if (msg == 0x0022) {	/* Allocate CID */
2729 				if (tlvlen != 2 || data[3] != 2) /* dms */
2730 					break;
2731 				sc->sc_cid = data[4];
2732 				DPRINTF("QMI CID %d allocated\n",
2733 				    sc->sc_cid);
2734 				umb_newstate(sc, UMB_S_CID, UMB_NS_DONT_DROP);
2735 			}
2736 			break;
2737 		case 2:	/* response */
2738 			if (tlvlen != sizeof (val))
2739 				break;
2740 			val = UMB_GET32(&data[3]);
2741 			switch (msg) {
2742 			case 0x0022:	/* Allocate CID */
2743 				if (val != 0) {
2744 					log(LOG_ERR, "%s: allocation of QMI CID"
2745 					    " failed, error 0x%x\n", DEVNAM(sc),
2746 					    val);
2747 					/* XXX how to proceed? */
2748 					return;
2749 				}
2750 				break;
2751 			case 0x555f:	/* Send FCC Authentication */
2752 				if (val == 0)
2753 					DPRINTF("%s: send FCC "
2754 					    "Authentication succeeded\n",
2755 					    DEVNAM(sc));
2756 				else if (val == 0x001a0001)
2757 					DPRINTF("%s: FCC Authentication "
2758 					    "not required\n", DEVNAM(sc));
2759 				else
2760 					log(LOG_INFO, "%s: send FCC "
2761 					    "Authentication failed, "
2762 					    "error 0x%x\n", DEVNAM(sc), val);
2763 
2764 				/* FCC Auth is needed only once after power-on*/
2765 				sc->sc_flags &= ~UMBFLG_FCC_AUTH_REQUIRED;
2766 
2767 				/* Try to proceed anyway */
2768 				DPRINTF("init: turning radio on ...\n");
2769 				umb_radio(sc, 1);
2770 				break;
2771 			default:
2772 				break;
2773 			}
2774 			break;
2775 		default:
2776 			break;
2777 		}
2778 		data += UMB_QMI_TLVLEN + tlvlen;
2779 		len -= UMB_QMI_TLVLEN + tlvlen;
2780 	}
2781 	return;
2782 
2783 tooshort:
2784 	DPRINTF("discard short QMI message\n");
2785 	return;
2786 }
2787 
2788 static void
umb_intr(struct usb_xfer * xfer,usb_error_t status)2789 umb_intr(struct usb_xfer *xfer, usb_error_t status)
2790 {
2791 	struct umb_softc *sc = usbd_xfer_softc(xfer);
2792 	struct usb_cdc_notification notification;
2793 	struct usb_page_cache *pc;
2794 	if_t ifp = GET_IFP(sc);
2795 	int	 total_len;
2796 
2797 	mtx_assert(&sc->sc_mutex, MA_OWNED);
2798 
2799 	/* FIXME use actlen or total_len? */
2800 	usbd_xfer_status(xfer, &total_len, NULL, NULL, NULL);
2801 
2802 	switch (USB_GET_STATE(xfer)) {
2803 	case USB_ST_TRANSFERRED:
2804 		DPRINTF("Received %d bytes\n", total_len);
2805 
2806 		if (total_len < UCDC_NOTIFICATION_LENGTH) {
2807 			DPRINTF("short notification (%d<%d)\n",
2808 					total_len, UCDC_NOTIFICATION_LENGTH);
2809 			return;
2810 		}
2811 
2812 		pc = usbd_xfer_get_frame(xfer, 0);
2813 		usbd_copy_out(pc, 0, &notification, sizeof (notification));
2814 
2815 		if (notification.bmRequestType != UCDC_NOTIFICATION) {
2816 			DPRINTF("unexpected notification (type=0x%02x)\n",
2817 					notification.bmRequestType);
2818 			return;
2819 		}
2820 
2821 		switch (notification.bNotification) {
2822 		case UCDC_N_NETWORK_CONNECTION:
2823 			if (if_getflags(ifp) & IFF_DEBUG)
2824 				log(LOG_DEBUG, "%s: network %sconnected\n",
2825 						DEVNAM(sc),
2826 						UGETW(notification.wValue)
2827 						? "" : "dis");
2828 			break;
2829 		case UCDC_N_RESPONSE_AVAILABLE:
2830 			DPRINTFN(2, "umb_intr: response available\n");
2831 			++sc->sc_nresp;
2832 			umb_add_task(sc, umb_get_response_task,
2833 					&sc->sc_proc_get_response_task[0].hdr,
2834 					&sc->sc_proc_get_response_task[1].hdr,
2835 					0);
2836 			break;
2837 		case UCDC_N_CONNECTION_SPEED_CHANGE:
2838 			DPRINTFN(2, "umb_intr: connection speed changed\n");
2839 			break;
2840 		default:
2841 			DPRINTF("unexpected notification (0x%02x)\n",
2842 					notification.bNotification);
2843 			break;
2844 		}
2845 		/* fallthrough */
2846 	case USB_ST_SETUP:
2847 tr_setup:
2848 		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
2849 		usbd_transfer_submit(xfer);
2850 		break;
2851 	default:
2852 		if (status != USB_ERR_CANCELLED) {
2853 			/* start clear stall */
2854 			usbd_xfer_set_stall(xfer);
2855 			goto tr_setup;
2856 		}
2857 		break;
2858 	}
2859 }
2860 
2861 /*
2862  * Diagnostic routines
2863  */
2864 static char *
umb_ntop(struct sockaddr * sa)2865 umb_ntop(struct sockaddr *sa)
2866 {
2867 #define NUMBUFS		4
2868 	static char astr[NUMBUFS][INET_ADDRSTRLEN];
2869 	static unsigned nbuf = 0;
2870 	char	*s;
2871 
2872 	s = astr[nbuf++];
2873 	if (nbuf >= NUMBUFS)
2874 		nbuf = 0;
2875 
2876 	switch (sa->sa_family) {
2877 	case AF_INET:
2878 	default:
2879 		inet_ntop(AF_INET, &satosin(sa)->sin_addr, s, sizeof (astr[0]));
2880 		break;
2881 	case AF_INET6:
2882 		inet_ntop(AF_INET6, &satosin6(sa)->sin6_addr, s,
2883 		    sizeof (astr[0]));
2884 		break;
2885 	}
2886 	return s;
2887 }
2888 
2889 #ifdef UMB_DEBUG
2890 static char *
umb_uuid2str(uint8_t uuid[MBIM_UUID_LEN])2891 umb_uuid2str(uint8_t uuid[MBIM_UUID_LEN])
2892 {
2893 	static char uuidstr[2 * MBIM_UUID_LEN + 5];
2894 
2895 #define UUID_BFMT	"%02X"
2896 #define UUID_SEP	"-"
2897 	snprintf(uuidstr, sizeof (uuidstr),
2898 	    UUID_BFMT UUID_BFMT UUID_BFMT UUID_BFMT UUID_SEP
2899 	    UUID_BFMT UUID_BFMT UUID_SEP
2900 	    UUID_BFMT UUID_BFMT UUID_SEP
2901 	    UUID_BFMT UUID_BFMT UUID_SEP
2902 	    UUID_BFMT UUID_BFMT UUID_BFMT UUID_BFMT UUID_BFMT UUID_BFMT,
2903 	    uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5],
2904 	    uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11],
2905 	    uuid[12], uuid[13], uuid[14], uuid[15]);
2906 	return uuidstr;
2907 }
2908 
2909 static void
umb_dump(void * buf,int len)2910 umb_dump(void *buf, int len)
2911 {
2912 	int	 i = 0;
2913 	uint8_t	*c = buf;
2914 
2915 	if (len == 0)
2916 		return;
2917 	while (i < len) {
2918 		if ((i % 16) == 0) {
2919 			if (i > 0)
2920 				log(LOG_DEBUG, "\n");
2921 			log(LOG_DEBUG, "%4d:  ", i);
2922 		}
2923 		log(LOG_DEBUG, " %02x", *c);
2924 		c++;
2925 		i++;
2926 	}
2927 	log(LOG_DEBUG, "\n");
2928 }
2929 #endif /* UMB_DEBUG */
2930 
2931 DRIVER_MODULE(umb, uhub, umb_driver, NULL, NULL);
2932 MODULE_DEPEND(umb, usb, 1, 1, 1);
2933