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