I have this stuff around quite a while now, but since patrick@ asked me repeatedly, I think it is time to share this now.
This is a patch that adds support for the "Mobile Broadband Interface Model" (MBIM) from http://www.usb.org/. It allows to attach UMTS/LTE USB devices as a network interface. I'm not asking for OKs at this time, but hope that some people will give it test. I tested with two different Sierra Wireless modules (EM8805, MC8305) and each one behaved a little bit different. In order to configure the network interface, this is what you do: # ifconfig mbim0 pin 1234 apn internet.t-mobile # ifconfig mbim0 inet 0.0.0.1 0.0.0.2 # route delete default # route add -ifp mbim0 default 0.0.0.2 # ifconfig mbim0 up The mbim interface is a point-to-point type interface and will update the default route, once it is registered in the network. To get extended information on the interface use: # ifconfig mbim0 devinfo The patch comes in 4 parts. This is the first part that provides some changes required to the rest of the kernel. Esp. the change in uhub.c may be needed: some modules appear at the usb bus just to detach themselves again and then reappear shortly after. After patching, please do a # cd /sys/dev/usb # make to rebuild usbdevs.h and usbdevs_data.h. In case of problems, please add option MBIM_DEBUG to generic and set the variable 'mbim_debug'. Have fun, Gerhard Index: sys/dev/usb/uhub.c =================================================================== RCS file: /cvs/src/sys/dev/usb/uhub.c,v retrieving revision 1.88 diff -u -p -u -p -r1.88 uhub.c --- sys/dev/usb/uhub.c 29 Nov 2015 16:30:48 -0000 1.88 +++ sys/dev/usb/uhub.c 23 May 2016 09:50:08 -0000 @@ -523,7 +523,9 @@ uhub_port_connect(struct uhub_softc *sc, { struct usbd_port *up = &sc->sc_hub->hub->ports[port-1]; int speed; + int retry = 1; +again: /* We have a connect status change, handle it. */ usbd_clear_port_feature(sc->sc_hub, port, UHF_C_PORT_CONNECTION); @@ -613,6 +615,11 @@ uhub_port_connect(struct uhub_softc *sc, * some other serious problem. Since we cannot leave * at 0 we have to disable the port instead. */ + if (retry--) { + printf("%s: port %d: retrying\n", DEVNAME(sc), port); + goto again; + } + printf("%s: device problem, disabling port %d\n", DEVNAME(sc), port); usbd_clear_port_feature(sc->sc_hub, port, UHF_PORT_ENABLE); Index: sys/dev/usb/usb.h =================================================================== RCS file: /cvs/src/sys/dev/usb/usb.h,v retrieving revision 1.54 diff -u -p -u -p -r1.54 usb.h --- sys/dev/usb/usb.h 28 Feb 2016 17:57:50 -0000 1.54 +++ sys/dev/usb/usb.h 23 May 2016 09:50:08 -0000 @@ -508,6 +508,7 @@ typedef struct usb_port_status usb_port_ #define UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6 #define UISUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7 #define UISUBCLASS_MOBILE_DIRECT_LINE_MODEL 10 +#define UISUBCLASS_MOBILE_BROADBAND_INTERFACE_MODEL 14 #define UIPROTO_CDC_AT 1 #define UICLASS_HID 0x03 @@ -545,6 +546,7 @@ typedef struct usb_port_status usb_port_ #define UICLASS_CDC_DATA 0x0a #define UISUBCLASS_DATA 0 +#define UIPROTO_DATA_MBIM 0x02 /* MBIM */ #define UIPROTO_DATA_ISDNBRI 0x30 /* Physical iface */ #define UIPROTO_DATA_HDLC 0x31 /* HDLC */ #define UIPROTO_DATA_TRANSPARENT 0x32 /* Transparent */ Index: sys/dev/usb/usbdevs =================================================================== RCS file: /cvs/src/sys/dev/usb/usbdevs,v retrieving revision 1.664 diff -u -p -u -p -r1.664 usbdevs --- sys/dev/usb/usbdevs 20 May 2016 02:04:24 -0000 1.664 +++ sys/dev/usb/usbdevs 23 May 2016 09:50:08 -0000 @@ -3832,7 +3832,9 @@ product SIERRA AC881U 0x6856 881U product SIERRA AC885U 0x6880 885U product SIERRA C01SW 0x6890 C01SW product SIERRA USB305 0x68a3 USB305 +product SIERRA MC8305 0x9011 MC8305 product SIERRA MC8355 0x9013 MC8355 +product SIERRA EM8805 0x9041 EM8805 product SIERRA AIRCARD_770S 0x9053 Aircard 770S /* Sigmatel products */ Index: sys/net/if_types.h =================================================================== RCS file: /cvs/src/sys/net/if_types.h,v retrieving revision 1.20 diff -u -p -u -p -r1.20 if_types.h --- sys/net/if_types.h 7 Mar 2016 19:33:26 -0000 1.20 +++ sys/net/if_types.h 23 May 2016 09:50:09 -0000 @@ -268,5 +268,6 @@ #define IFT_CARP 0xf7 /* Common Address Redundancy Protocol */ #define IFT_BLUETOOTH 0xf8 /* Bluetooth */ #define IFT_PFLOW 0xf9 /* pflow */ +#define IFT_MBIM 0xfa /* Mobile Broadband Interface Model */ #endif /* _NET_IF_TYPES_H_ */ Index: sys/netinet/in.c =================================================================== RCS file: /cvs/src/sys/netinet/in.c,v retrieving revision 1.127 diff -u -p -u -p -r1.127 in.c --- sys/netinet/in.c 18 Apr 2016 06:43:51 -0000 1.127 +++ sys/netinet/in.c 23 May 2016 09:50:09 -0000 @@ -83,7 +83,6 @@ void in_socktrim(struct sockaddr_in *); -void in_len2mask(struct in_addr *, int); int in_lifaddr_ioctl(struct socket *, u_long, caddr_t, struct ifnet *); Index: sys/netinet/in.h =================================================================== RCS file: /cvs/src/sys/netinet/in.h,v retrieving revision 1.115 diff -u -p -u -p -r1.115 in.h --- sys/netinet/in.h 20 Oct 2015 20:22:42 -0000 1.115 +++ sys/netinet/in.h 23 May 2016 09:50:09 -0000 @@ -791,6 +791,7 @@ extern struct in_addr zeroin_addr; struct mbuf; +void in_purgeaddr(struct ifaddr *); int in_broadcast(struct in_addr, u_int); int in_canforward(struct in_addr); int in_cksum(struct mbuf *, int); @@ -798,6 +799,7 @@ int in4_cksum(struct mbuf *, u_int8_t void in_proto_cksum_out(struct mbuf *, struct ifnet *); void in_ifdetach(struct ifnet *); int in_mask2len(struct in_addr *); +void in_len2mask(struct in_addr *, int); char *inet_ntoa(struct in_addr); int inet_nat64(int, const void *, void *, const void *, u_int8_t); Index: sys/sys/sockio.h =================================================================== RCS file: /cvs/src/sys/sys/sockio.h,v retrieving revision 1.63 diff -u -p -u -p -r1.63 sockio.h --- sys/sys/sockio.h 2 Mar 2016 00:00:16 -0000 1.63 +++ sys/sys/sockio.h 23 May 2016 09:50:09 -0000 @@ -203,6 +203,10 @@ #define SIOCGIFPARENT _IOWR('i', 179, struct if_parent) /* get parent if */ #define SIOCDIFPARENT _IOW('i', 180, struct ifreq) /* del parent if */ +#define SIOCGMBIMINFO _IOWR('i', 190, struct ifreq) /* get MBIM info */ +#define SIOCSMBIMPARAM _IOW('i', 191, struct ifreq) /* set MBIM param */ +#define SIOCGMBIMPARAM _IOWR('i', 192, struct ifreq) /* get MBIM param */ + #define SIOCSVH _IOWR('i', 245, struct ifreq) /* set carp param */ #define SIOCGVH _IOWR('i', 246, struct ifreq) /* get carp param */
