Change EM7355 PIDs (for pfSense/FreeBSD compat)?

Hi folks,

I’m trying to get an EM7355 card to play nicely with pfSense (which is built upon FreeBSD 10.3), but I’m getting nowhere and would hugely appreciate any pointers. At this point, I suspect I just need to change the PID of the card to get FreeBSD to recognize it and assign a serial port, but I’m having trouble getting there.

The EM7355 I started out with (0x1199/0x901e) wasn’t recognized by pfSense or Centos 7, and even Windows 7 didn’t like any of the drivers I used (starting with Sierra Wireless official, progressing to shady 3rd party ‘driver manager’ sites, and even modifying inf files). At no point was there a working serial port provided to any of the OSes, so even if I wanted to issue AT commands to change PIDs, I was SOL. Because this device was an import of questionable origin, I figured I should cut my losses and find another EM7355.

Next I obtained a Lenovo (FRU04X6038) EM7355 (0x1199/0x901f). This fared no better under pfSense (latest release, 2.3.1_1) or Centos 7 (neither picked it up in a way which I could talk to it, serial or otherwise), though under Windows (now at Win 10) the drivers obtained from Sierra Wireless did pick up the card. Still, the COM ports didn’t respond to any commands (trying multiple speeds, etc.), nor did the Sierra Wireless Watcher software (likely an older version) acknowledge the card. I next tried it in a Lenovo laptop (Win 7) in which the card was supposedly compatible (e.g. no BIOS restriction). The first time around, the laptop booted up, I installed Lenovo’s drivers, and things seemed like they were going in the right direction. However, upon a required “new software” restart, the laptop refused to boot (BIOS restriction) due to what it now claimed was an incompatible card. No idea why it was okay with it at first, but now it was complaining.

I’m pulling my hair out here! I’d be hugely grateful if someone had some experience with these cards and could give me some pointers on where to turn next (that keeps my existing pfSense router and doesn’t involve spending $$$ on a Cradlepoint or similar!).

Tl;dr: EM7355 (0x1199/0x901f) needs a different VID/PID; can’t load up card to make the change.

Thank you!

So I guess you have seen this thread:
forum.pfsense.org/index.php?topic=96468.0
and want to do the same?

The real fix would be to add the appropriate driver support in FreeBSD/pfSense. But that method should also work if you rather want to modify the modem… But is is not very community friendly IMHO. If some of the earlier “fixers” had taken the time to fix the drivers instead, then the rest of you wouldn’t have to continue to do such odd hacks.

Well, I don’t use FreeBSD so I don’t care much :wink:

CentOS is not the best choice of Linux distro when you need the latest and greatest hardware support. Their extreme stability requirements force them to use an outdated kernel version. They do a great job on security support for that, but the drivers are mostly the same as the original what-is-it-now? 2.6.32?

But I note that 0x901e is still unknown in the latest kernels, which means that we haven’t seen that PID before. It could be that we have only seen it in MBIM mode, in which case we don’t care about the PID. Do you have any further details, like the output of “lsusb -vd 1199:901e” (from any Linux version)?

This is very interesting! Did the modem change PID, or did it fail the BIOS test with the exact same VID/PID as before?

A long shot probably, but you wouldn’t happen to have more details about the modem state before and after? “lsusb -vd VID:PID” would be great, but anything which would describe the USB descriptor layout would be nice. There are usually a few messages printed in the kernel log for example. Those can be used to recreate some parts of the layout.

I am really curious about this case, which is highly relevant to other Lenovo users. The BIOS whitelisting used to be VID:PID based, and if that has changed then it is good to know before someone bricks their laptop (not permanently of course, but for many users it willl be nearly impossible to remove an internal modem to make the laptop boot again).

If your current composition includes an AT command functions, then you should be able to fix this by temporarily adding the VID:PID to the option driver and then use the recipe from the pfsense forum:

modprobe option
echo 1199 901f  >/sys/bus/usb-serial/drivers/option1/new_id 
... find out which ttyUSBx is speaking AT and do what you want there

You got it. I specifically got the idea from Jim Thompson, one of the lead pfSense developers, who recommended the device (via a reddit thread). However, I did stumble across the above post when trying to make these cards work.

Indeed. If I can figure it out, I’d consider submitting a patch.

Best I can do for now is give you this FreeBSD output:

ugen0.3: <Sierra Wireless EM7355 Qualcomm GobiTM 4G LTEHSPA+EVDO Sierra Wireless, Incorporated>, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (2mA)

  bLength = 0x0012
  bDescriptorType = 0x0001
  bcdUSB = 0x0200
  bDeviceClass = 0x0000  <Probed by interface class>
  bDeviceSubClass = 0x0000
  bDeviceProtocol = 0x0000
  bMaxPacketSize0 = 0x0040
  idVendor = 0x1199
  idProduct = 0x901e
  bcdDevice = 0x0000
  iManufacturer = 0x0001  <Sierra Wireless, Incorporated>
  iProduct = 0x0002  <Sierra Wireless EM7355 Qualcomm Gobi(TM) 4G LTE/HSPA+/EVDO>
  iSerialNumber = 0x0000  <no string>
  bNumConfigurations = 0x0001

=====================================================================


 Configuration index 0

    bLength = 0x0009
    bDescriptorType = 0x0002
    wTotalLength = 0x0020
    bNumInterfaces = 0x0001
    bConfigurationValue = 0x0001
    iConfiguration = 0x0000  <no string>
    bmAttributes = 0x0080
    bMaxPower = 0x0001

    Interface 0
      bLength = 0x0009
      bDescriptorType = 0x0004
      bInterfaceNumber = 0x0000
      bAlternateSetting = 0x0000
      bNumEndpoints = 0x0002
      bInterfaceClass = 0x00ff  <Vendor specific>
      bInterfaceSubClass = 0x00ff
      bInterfaceProtocol = 0x00ff
      iInterface = 0x0000  <no string>

     Endpoint 0
        bLength = 0x0007
        bDescriptorType = 0x0005
        bEndpointAddress = 0x0081  <IN>
        bmAttributes = 0x0002  <BULK>
        wMaxPacketSize = 0x0200
        bInterval = 0x0000
        bRefresh = 0x0000
        bSynchAddress = 0x0000

     Endpoint 1
        bLength = 0x0007
        bDescriptorType = 0x0005
        bEndpointAddress = 0x0001  <OUT>
        bmAttributes = 0x0002  <BULK>
        wMaxPacketSize = 0x0200
        bInterval = 0x0000
        bRefresh = 0x0000
        bSynchAddress = 0x0000

I’m not sure. I have only two devices which can accept the device, the pfSense box (via m.2 to mini pci-e adapter) and the Lenovo laptop. It’s a pain to take down the pfSense box (no router = no internet), and now the laptop won’t boot with it. The laptop was my last try – I put things on hold for a couple week once that happened, but I guess I’m going to have to take down the router and put the card back in to see what’s up.

This is the only info I have from the 0x901f card, again from under FreeBSD:

ugen0.4: <Sierra Wireless EM7355 Qualcomm GobiTM 4G LTEHSPA+EVDO Sierra Wireless, Incorporated>, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (500mA)

  bLength = 0x0012
  bDescriptorType = 0x0001
  bcdUSB = 0x0200
  bDeviceClass = 0x0000  <Probed by interface class>
  bDeviceSubClass = 0x0000
  bDeviceProtocol = 0x0000
  bMaxPacketSize0 = 0x0040
  idVendor = 0x1199
  idProduct = 0x901f
  bcdDevice = 0x0006
  iManufacturer = 0x0001  <Sierra Wireless, Incorporated>
  iProduct = 0x0002  <Sierra Wireless EM7355 Qualcomm Gobi(TM) 4G LTE/HSPA+/EVDO>
  iSerialNumber = 0x0003  <retrieving string failed>
  bNumConfigurations = 0x0002

This is from before I put the card in the Lenovo laptop. If you think it’d be valuable, let me know and I’ll retrieve the the “after” info as well.

I’m going to give this another shot. It’s been forever since I played with modprobe, etc. Part of my problem is that I don’t yet understand the difference between MBIM vs QMI, etc., and what pfSense wants to see. Makes me miss my old Hayes Smartmodem…

Thanks for the tips and the interest in the thread! Much appreciated!

That’s great! Thanks. It explains a lot. This modem is stuck in bootloader mode for some reason. I assume 901e and 901f are a matching pair of boot and application PIDs. That fits the usual pattern.

It’s difficult to say how you should fix this without knowing why the modem is stuck there. But it could be a failed firmware upgrade. Try restarting the firmware upgrade and see if that fixes the problem. The firmware upgrade tool should detect the modem as already being in “boot and hold” mode, and should continue from there. Hopefully.

There could also be other things being wrong here, but chances are good that a fresh firmware upgrade will reset it whatever the problem is.

I see. If the problem persists and you need a way to connect the modem to some other PC, then a miniPCIe <-> USB adapter will help. Or m.2 <-> USB, of course, but those are harder to come by and usually more expensive.

Good. Even without the rest of this, the bNumConfigurations == 2 tells us that this modem is in application mode and that it is configured for both QMI and MBIM. Because that’s the only possible dual config option for these modems.

It would be nice to know if “after” has the same PID. I wonder if this problem is related to the first PID problem: Maybe the Lenovo BIOS whitelist includes 901f but not 901e? That would make any firmware upgrade a catastrophe, so it would be insane. But insanity seems to be a requirement for BIOS enigneers, so it isn’t that unlikely…

If that indeed is the problem, then it should be fixed by finishing the upgrade in some other host (without the whitelisting BIOS).

I’m afraid this won’t do any good with the 901e modem. It is in bootloader mode, which means that it expects one of the odd Qualcomm serial protocols which are so secret that we don’t even know what their official names are supposed to be. You have DLOAD, Streaming DLOAD protocol (SDP), QDL, DMSS, SAHARA and probably more. The firmware upgrade tools should recognize some of these and switch to whatever protocol it wants (SDP probably).

MBIM and QMI are both protocols for synchronous IP packet transport over USB, each with an embedded management protocol. MBIM has the most complex framing, multiplexing and aggregating both IP packets and other data in the same frame. QMI (or RMNET which probably is more correct - again: Qualcomm doesn’t say, so we guess) sends raw IP packets or raw ethernet (IP/ARP only) frames, with an optional QoS header. The MBIM management protocol is well defined but very limited. It is easily extended with vendor specific extensions though. The QMI management protocol is a multiplex of subsystem commands for every possibly baseband system, with a large number of different requests for each system. There is no public docs for most of it. The Sierra QMI SDK implements a lot. The open source QMI tools implements the most basic parts.

The reasons for both of these protocol are simple:

  1. using async framing for IP packets on the USB link is inefficient and completely unnecessary. It has always been a hack to make cellular packet modems look like traditional phone line modems. Higher speeds made sync framing necessary.
  2. cellular modems need more/other configuration and management requests than traditional modems. Extending the AT command set is one possible solution which has been, and still is, in use. But a lot of this is dealing with structured data, and converting it to and from an ascii text representation is both inefficent and error prone. Structured management protocols like QMI or MBIM solved that problem.