Skip to content

Instantly share code, notes, and snippets.

@mleinart
Last active September 20, 2024 17:18
Show Gist options
  • Save mleinart/d14ec6fe5787017307f34c208602d804 to your computer and use it in GitHub Desktop.
Save mleinart/d14ec6fe5787017307f34c208602d804 to your computer and use it in GitHub Desktop.
Flashing Carrier configuration and updated firmware to a Sierra MC7355

Overview

The Sierra MC7355 can run configurations for several North American carriers. These cards are easy to find on eBay and notable for their support for the Sprint LTE network. Unless you're luck out, you may find you need to flash a new carrier configuration onto the card you purchased before using it.

Notes

These procedures are specific to the setup I had to perform this on. Most notably, the only system I had with a mini-PCI-e slot was the target pfSense system, a PCengines APU1d with no VGA port (serial console only). If you're able to obtain a USB-to-mini-PCI-e adapter, performing this flash will likely be much easier (perhaps even allowing you to use Windows in a VM).

System: PCengines APU1d Live USB: FreeBSD (i386 memstick installer) Live USB: Arch linux Modem: Sierra MC7355, with Panasonic SKU (1101888) Also used: Null modem adapter with USB-to-serial plugged into a spare machine Two USB sticks

Procedure

Inspection: FreeBSD

For this step, we need to access the modem's USB Serial interface. This will allow us to use modem AT Commands to inspect the current configuration and turn off MBIM mode which prevents the modem from being discovered in Linux. Since Linux wont (AFAICT) recognize the modem in this state, we need to rely on FreeBSD's u3g driver.

Boot into FreeBSD

Write the FreeBSD installer image to a spare USB stick and boot. Serial console should work out of box (speed: 115200). Go with the default multi-user boot and select the LiveCD option.

Connect to your modem

First, verify your modem was found:

# dmesg | less

Look for something like this:

u3g0: <vendor 0x1199 MC7355, class 0/0, rev 2.00/0.06, addr 3> on usbus1
u3g0: Found 4 ports.

The driver will create four USB-serial ports

# ls /dev/cuaU*[0-9]
/dev/cuaU0.0    /dev/cuaU0.1    /dev/cuaU0.2    /dev/cuaU0.3

The port for AT commands is usually on cuaU0.1 or cuaU0.2. Try an AT command with each, pressing ~. to exit the session

# cu -l /dev/cuaU0.1
Connected
AT
OK

Note: if you see the OK but AT isn't echoed to your screen, enter ATE to turn echo on

Checking Carrier and preparing for Linux

Enter password-protected mode

Some of the AT commands we need require us to be in password-protected mode. The default password for these modems is A710

AT!ENTERCND="A710"
OK

Inspect the current carrier configuration

Before proceeding, we need to check the current carrier to see whether we really need to do a flash

AT!GOBIIMPREF?
!GOBIIMPREF:
 preferred fw version: 01.08.16.05
 preferred carrier name: VZW
 preferred config name: VZW_000.036_000
 current fw version: 01.08.16.05
 current carrier name: VZW
 current config name: VZW_000.036_000

OK

In this case, I want Sprint. Let's see if a Sprint config is loaded that we can choose:

AT!PRIID?
PRI Part Number: 9902812
Revision: 01.07

Carrier PRI: 9999999_9902266_SWI9X15C_01.08.16.05_00_VZW_000.036_000

If our preferred carrier appeared here, we could switch to it with this command (note how the string above maps to the three fields):

AT!GOBIIMPREF="01.08.16.05","VZW","VZW_000.036_000"

Since it doesn't map, we'll need to continue

Configure USB interface

We need to ensure no MBIM interface is enabled for Linux to see our modem correctly. First, check the current setting:

AT!UDUSBCOMP?
!UDUSBCOMP: 14

OK

List the settings to see what this maps to:

AT!UDUSBCOMP=?
0  - reserved                                     NOT SUPPORTED
1  - DM   AT                                      SUPPORTED
2  - reserved                                     NOT SUPPORTED
3  - reserved                                     NOT SUPPORTED
4  - reserved                                     NOT SUPPORTED
5  - reserved                                     NOT SUPPORTED
6  - DM   NMEA  AT    QMI                         SUPPORTED
7  - DM   NMEA  AT    RMNET1 RMNET2 RMNET3        SUPPORTED
8  - DM   NMEA  AT    MBIM                        SUPPORTED
9  - MBIM                                         SUPPORTED
10 - NMEA MBIM                                    SUPPORTED
11 - DM   MBIM                                    SUPPORTED
12 - DM   NMEA  MBIM                              SUPPORTED
13 - Config1: comp6    Config2: comp8             NOT SUPPORTED
14 - Config1: comp6    Config2: comp9             SUPPORTED
15 - Config1: comp6    Config2: comp10            NOT SUPPORTED
16 - Config1: comp6    Config2: comp11            NOT SUPPORTED
17 - Config1: comp6    Config2: comp12            NOT SUPPORTED
18 - Config1: comp7    Config2: comp8             NOT SUPPORTED
19 - Config1: comp7    Config2: comp9             SUPPORTED
20 - Config1: comp7    Config2: comp10            NOT SUPPORTED
21 - Config1: comp7    Config2: comp11            NOT SUPPORTED
22 - Config1: comp7    Config2: comp12            NOT SUPPORTED

OK

In the case above, 14 maps to configs 6 and 9. To do the flash in Linux, we need the AT and QMI interfaces which is 6 but we dont want the MBIM interface in 9.

Caution: ensure you do not set this to an interface without AT - this may lock you out of the modem

Set the USB interface to config number 6:

AT!UDUSBCOMP=6
OK

From here, we should be good to start with the Linux half

Setting up Linux live environment

To complete this we need a live linux environment with a serial console. For this I used an Arch installer. If using Arch, a second USB or system drive will be necessary as the live install's root partition is not big enough for the compile dependencies. If another live distro is chosen, the requirements are:

  • Boots with a serial console (minimum: grub configured on serial console)
  • Ability to compile kernel modules (basic compiler tools, linux headers)

Booting into Arch

Arch's Grub uses port speed 38400 so switch your terminal emulator accordingly

To boot into the live environment, at the Grub boot prompt press TAB and append console=ttyS0,38400 to the kernel commandline as described in the Arch wiki articleWorking with the serial console. Log in as root

Setting up a bigger root partition

We need more space, so plug your 2nd drive in now. In this example, our second drive is /dev/sdc

First, verify you're working with the drive you think you are

# dmesg | tail  # Look for the messages for the drive just plugged in
# fdisk -l /dev/sdc  # Verify the disk size matches expectations

From here we'll be following the Arch Installation Guide up to the Chroot section

  1. Create a new primary partition if one doesn't already exist using fdisk /dev/sdc
  2. Format it: mkfs.ext4 /dev/sdc1
  3. Mount it: mount /dev/sdc1 /mnt
  4. Install base packages: pacstrap /mnt base base-devel linux-headers
  5. Switch into the new root: arch-chroot /mnt

Optionally, you can continue along the installation to make this new USB a persistent bootable system you can use in the future

Removing incompatible drivers

The Sierra modem may be identified by several built-in kernel drivers that are incompatible with the drivers we're about to compile. Remove any of the following modules with modprobe -r <modulename>:

  • qcserial
  • qmi_wwan
  • usb_wwan
  • cdc_mbim
  • cdc_wdm
  • cdc_ncm
  • sierra
  • sierra_net

Compiling Qualcomm Gobi drivers

The software provided by Sierra for flashing this modem requires the Qualcomm Gobi drivers. Sierra calls these the Linux Drivers QMI Software

First, download and unpack the drivers:

# pacman -S wget unzip  # these arent installed by default
# cd /usr/src
src] # wget http://www.downloads.netgear.com/files/aircard/Linux-Support-S2.13N2.25.zip
src] # unzip Linux-Support-S2.13N2.25.zip
src] # mv -v Linux-Support-S2.13N2.25/Linux\ Drivers\ S2.13N2.25/GobiSerial .
src] # mv -v Linux-Support-S2.13N2.25/Linux\ Drivers\ S2.13N2.25/GobiNet .

Next, if you're using a 4.x series Linux kernel you may need this patch to get it to compile

src] # curl https://gist.githubusercontent.com/mleinart/373971d3560fa5814a684de2d9068eba/raw/1bc83506bb9c38d995b8fdcfe1e555c5f4a89528/Sierra-QMIDrivers-fix_compile_errors.diff | patch -p0

Finally, compile and install each driver:

src] # cd GobiSerial
GobiSerial] # make install
GobiSerial] # modprobe GobiSerial
GobiSerial] # cd ..
src] # cd GobiNet
GobiNet] # make install
GobiNet] # modprobe GobiNet

And now verify they found your modem

# dmesg | tail
# ls /dev/qcqmi0
/dev/qcqmi0
# ls /dev/ttyUSB*
/dev/ttyUSB0
/dev/ttyUSB1
/dev/ttyUSB2

Note: Sometimes this modem is finicky in linux - I've had some luck removing the module and re-inserting while the system is running

Flashing a new firmware and carrier config

Firmwares for the MC73XX series are located at the (source.sierrawireless.com site)[http://source.sierrawireless.com/resources/airprime/software/airprime-mc73xx-fw-package-build-4544/] You'll want the SPK version of the package which includes carrier-approved firmware as well as the carrier configs bundled in individual files.

The firmware flashing tool is part of the (Linux QMI SDK Software package)[http://source.sierrawireless.com/resources/airprime/software/linux-qmi-sdk-software-04,-d-,00,-d-,00/] provided by Sierra.

First, extract the Firmwares someplace

# mkdir /usr/src/sierra_firmware
# unzip -d /usr/src/sierra_firmware Build4544-Approved-7355-SPK.zip

Copy the full pathname of the SPK file for the carrier you want. You'll need to paste it in later Now, compile the Image loader tool for the MC7xxx series:

# mkdir SLQ
# cd SLQ
SLQ] # tar zxvf ../SLQS04.00.00.bin.tar.gz
SLQ] # cd SampleApps/MC7xxx_Image_Management
MC7xxx_Image_Management] # make

Finally, execute the tool. If the tool is missing options 1-4, it means the QMI drivers aren't active. Check for /dev/qcqmi0 and see the driver section above.

# ./bin/mc7xxximgmgmthosti686 -s ../../build/bin/hosti686/slqssdk

Running with device in application mode

Please select one of the following options or press <Enter> to exit:
1. Display the information for the executing device image
2. Download a boot loader image to the device
3. Download a firmware image to the device
4. Download an NV item to the device
5. Display the information for a particular spk/cwe image located on the host
6. Display the information for a particular nvu image located on the host
7. Image Switching on MC/EM74xx
8. Get valid fw/pri combination for MC/EM74xx
Option:

Select option 3 and paste the full path to the SPK file Allow the firmware download to complete and your modem should now be active!

Verify your carrier once more

# pacman -S uucp
# cu -l /dev/ttyUSB2 # or ttyUSB1, varies
Connected.
AT
OK
AT!ENTERCND="A710"
OK
AT!GOBIIMPREF?
!GOBIIMPREF:
 preferred fw version:   05.05.63.01
 preferred carrier name: SPRINT
 preferred config name:  SPRINT_005.037_000
 current fw version:     05.05.63.01
 current carrier name:   SPRINT
 current config name:    SPRINT_005.037_000

OK

Success!

Errors

Here are some pasted errors to help Googlers to reach this page

Unpatched GobiSerial compile error

See this gist for a patch: https://gist.github.com/mleinart/373971d3560fa5814a684de2d9068eba

/usr/src/S2.26N2.38/GobiSerial/GobiSerial.c:325:14: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
    .resume = usb_serial_generic_resume,
              ^~~~~~~~~~~~~~~~~~~~~~~~~
/usr/src/S2.26N2.38/GobiSerial/GobiSerial.c:325:14: note: (near initialization for ‘GobiDriver.resume’)
/usr/src/S2.26N2.38/GobiSerial/GobiSerial.c:326:20: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
    .reset_resume = usb_serial_generic_resume,
                     ^~~~~~~~~~~~~~~~~~~~~~~~~
/usr/src/S2.26N2.38/GobiSerial/GobiSerial.c:326:20: note: (near initialization for ‘GobiDriver.reset_resume’)
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:296: /usr/src/S2.26N2.38/GobiSerial/GobiSerial.o] Error 1
make[1]: *** [Makefile:1471: _module_/usr/src/S2.26N2.38/GobiSerial] Error 2
make[1]: Leaving directory '/usr/lib/modules/4.8.6-1-ARCH/build'
make: *** [Makefile:16: all] Error 2

Unpatched GobiNet compile error

See this gist for a patch: https://gist.github.com/mleinart/373971d3560fa5814a684de2d9068eba

/usr/src/S2.26N2.38/GobiNet/GobiUSBNet.c: In function ‘GobiUSBNetStartXmit’:
/usr/src/S2.26N2.38/GobiNet/GobiUSBNet.c:1329:8: error: ‘struct net_device’ has no member named ‘trans_start’; did you mean  mem_start’?
    pNet->trans_start = jiffies;
        ^~
make[2]: *** [scripts/Makefile.build:290: /usr/src/S2.26N2.38/GobiNet/GobiUSBNet.o] Error 1
make[1]: *** [Makefile:1471: _module_/usr/src/S2.26N2.38/GobiNet] Error 2
make[1]: Leaving directory '/usr/lib/modules/4.8.6-1-ARCH/build'
make: *** [Makefile:37: all] Error 2

USB Errors when MBIM mode is enabled in linux

Having an MBIM config (or maybe it's just any multi-config UDUSBCOMP value?) makes Linux USB angry, causing the modem's Serial devices to not work

[  484.038683] usb 3-1.3: config 1 has an invalid interface number: 8 but max is 3
[  484.038693] usb 3-1.3: config 1 has no interface number 1
[  484.039172] usb 3-1.3: config 2 has an invalid interface number: 12 but max is 1
[  484.039181] usb 3-1.3: config 2 has an invalid interface number: 13 but max is 1
[  484.039189] usb 3-1.3: config 2 has an invalid interface number: 13 but max is 1
[  484.039196] usb 3-1.3: config 2 has no interface number 0
[  484.039203] usb 3-1.3: config 2 has no interface number 1
@intelfx
Copy link

intelfx commented Apr 6, 2018

I believe this guide is obsoleted by libqmi package in Arch Linux which includes qmicli and qmi-firmware-update programs that allow you to flash any modem with QMI interface without using proprietary SDKs.

@Crisfole
Copy link

Crisfole commented Nov 1, 2019

If you attempt to compile Gobi* on an even newer kernel you may run into issues with the change in the file struct:

‘struct file’ has no member named ‘f_dentry’; did you mean ‘f_owner

This is specifically in QMIDevice.c

To fix this you can do the following:

# sed -i.bak 's/f_dentry/f_path.dentry/g' /usr/src/GobiNet/QMIDevice.c

This will replace all copies of f_dentry with f_path.dentry in the QMIDevice.c file. It will save a copy of the original in case I was wrong.

After this # make install works correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment