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