This is a port of the corresponding change from the qcserial.c driver distributed as part of the 9X50 SDK, tested and augmented via investigation of author's own EM7565 device. The "MBIM USBIF" configurations correspond to the `AT!USBCOMP=1,1,xxx` on-device USB composition setting. When activated, the VID:PID resets to 1199:90b1 ("application" mode) + 1199:90b0 ("boot" mode, i.e. QDL). The "PCIE USBIF" configurations correspond to the `AT!USBCOMP=1,2,xxx` on-device USB composition setting. Similarly, when activated, VID:PID resets to 1199:90c3 ("application" mode) + 1199:90c2 ("boot" mode). The existing 1199:9091 and 1199:9090 VID:PID pairs correspond to the "Legacy/Generic" configuration, activated by the `AT!USBCOMP=1,3,xxx` on-device USB composition setting. The supported interfaces and their numbers in both these configurations were confirmed by manual testing. Additional available interfaces (not claimed by the qcserial driver, such as ADB) found by investigation were documented in the comments for posterity. The "MBIM USBIF" and "PCIE USBIF" labels come from on-device help: ---8<--- AT!USBCOMP=? !USBCOMP: AT!USBCOMP=<Config Index>,<Config Type>,<Interface bitmask> <Config Index> - configuration index to which the composition applies, should be 1 <Config Type> - 1:MBIM USBIF, 2:PCIE USBIF, 3:Legacy-Generic, 4:RNDIS <Interface bitmask> - DIAG - 0x00000001, NMEA - 0x00000004, MODEM - 0x00000008, RMNET0 - 0x00000100, MBIM - 0x00001000, e.g. 10D - diag, nmea, modem, rmnet interfaces enabled 1009 - diag, modem, mbim interfaces enabled The default configuration is: at!usbcomp=1,3,10F OK ---8<--- Additionally, a fourth PID pair (1199:90c1, 1199:90c0) has been extracted from on-device help: ---8<--- AT!USBPID=? APP BOOT 9091, 9090 90B1, 90B0 90C1, 90C0 OK ---8<--- It is not clear which configuration it corresponds to, but it is included in the patch for completeness. Signed-off-by: Ivan Shapovalov <intelfx@xxxxxxxxxxxx> --- drivers/usb/serial/qcserial.c | 73 +++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 13c664317a05..c7167242e235 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -26,12 +26,18 @@ enum qcserial_layouts { QCSERIAL_G1K = 1, /* Gobi 1000 */ QCSERIAL_SWI = 2, /* Sierra Wireless */ QCSERIAL_HWI = 3, /* Huawei */ + QCSERIAL_SWI_9X50_MBIM = 4, /* Sierra Wireless 9x50 "MBIM USBIF" */ + QCSERIAL_SWI_9X50_PCIE = 5, /* Sierra Wireless 9x50 "PCIE USBIF" */ }; #define DEVICE_G1K(v, p) \ USB_DEVICE(v, p), .driver_info = QCSERIAL_G1K #define DEVICE_SWI(v, p) \ USB_DEVICE(v, p), .driver_info = QCSERIAL_SWI +#define DEVICE_SWI_9X50_PCIE(v, p) \ + USB_DEVICE(v, p), .driver_info = QCSERIAL_SWI_9X50_PCIE +#define DEVICE_SWI_9X50_MBIM(v, p) \ + USB_DEVICE(v, p), .driver_info = QCSERIAL_SWI_9X50_MBIM #define DEVICE_HWI(v, p) \ USB_DEVICE(v, p), .driver_info = QCSERIAL_HWI @@ -165,6 +171,12 @@ static const struct usb_device_id id_table[] = { {DEVICE_SWI(0x1199, 0x907b)}, /* Sierra Wireless EM74xx */ {DEVICE_SWI(0x1199, 0x9090)}, /* Sierra Wireless EM7565 QDL */ {DEVICE_SWI(0x1199, 0x9091)}, /* Sierra Wireless EM7565 */ + {DEVICE_SWI(0x1199, 0x90B0)}, /* Sierra Wireless EM7565 QDL */ + {DEVICE_SWI_9X50_MBIM(0x1199, 0x90B1)}, /* Sierra Wireless EM7565 "MBIM USBIF" */ + {DEVICE_SWI(0x1199, 0x90c0)}, /* Sierra Wireless EM7565 QDL */ + {DEVICE_SWI_9X50_PCIE(0x1199, 0x90c1)}, /* Sierra Wireless EM7565 (unknown configuration, found in on-device AT command help) */ + {DEVICE_SWI(0x1199, 0x90c2)}, /* Sierra Wireless EM7565 QDL */ + {DEVICE_SWI_9X50_PCIE(0x1199, 0x90c3)}, /* Sierra Wireless EM7565 "PCIE USBIF" */ {DEVICE_SWI(0x1199, 0x90d2)}, /* Sierra Wireless EM9191 QDL */ {DEVICE_SWI(0x1199, 0x90e4)}, /* Sierra Wireless EM86xx QDL*/ {DEVICE_SWI(0x1199, 0x90e5)}, /* Sierra Wireless EM86xx */ @@ -345,9 +357,11 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) /* * Sierra Wireless layout: * 0: DM/DIAG (use libqcdm from ModemManager for communication) + * 1: ADB * 2: NMEA * 3: AT-capable modem port * 8: QMI/net + * 12, 13: MBIM */ switch (ifnum) { case 0: @@ -403,6 +417,65 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) intf->desc.bInterfaceProtocol); } break; + case QCSERIAL_SWI_9X50_MBIM: + /* + * Sierra Wireless 9X50 "MBIM USBIF" layout: + * 0, 1: MBIM + * 2: AT-capable modem port + * 3: NMEA + * 4: DM + * 7: ADB + */ + switch (ifnum) { + case 2: + dev_dbg(dev, "Modem port found\n"); + sendsetup = true; + break; + case 3: + dev_dbg(dev, "NMEA GPS interface found\n"); + sendsetup = true; + break; + case 4: + dev_dbg(dev, "DM/DIAG interface found\n"); + break; + default: + /* don't claim any unsupported interface */ + altsetting = -1; + break; + } + break; + case QCSERIAL_SWI_9X50_PCIE: + /* + * Sierra Wireless 9X50 "PCIE USBIF" layout: + * 0: AT-capable modem port + * 1: NMEA + * 2: DM + * 5: ADB + * No other interfaces possible, presumably this configuration + * means that data exchange is happening via PCIe (but we are + * not making this an error). + */ + switch (ifnum) { + case 0: + dev_dbg(dev, "Modem port found\n"); + sendsetup = true; + break; + case 1: + dev_dbg(dev, "NMEA GPS interface found\n"); + sendsetup = true; + break; + case 2: + dev_dbg(dev, "DM/DIAG interface found\n"); + break; + default: + dev_err(dev, + "unexpected interface for PCIE-USBIF layout type: %u\n", + (unsigned)ifnum); + /* don't claim any unsupported interface */ + altsetting = -1; + break; + } + break; default: dev_err(dev, "unsupported device layout type: %lu\n", id->driver_info); -- 2.47.0.5.gd823fa0eac