mm6108->FGH100M-H -> wm6108 ->wm1302(pi hat)->RPi5 over SPI

I am trying to get Halow working with these hardware setup over SPI

  • Raspberry Pi 5
  • Seeed WM1302 pi hat
  • Seeed WM6108 mini PCI card (with Quectel FGH100M-H and mm6108)

Software packages used:

  • OS: Raspberry Linux
  • Kernel version: 6.12.47 (stable_20250916)
  • Morse rpi-linux patch 6.12.21
  • Morse driver 1.16.x
  • Morse firmware: mm6108.bin and bcd_fgh100mhaamd.bin

I found useful information from these:

did the followings

  1. patched the kernel source with Morse rpi-linux - manually resolved a few conflicts
  2. configured the kernel with necessary flags for CRYPTO
  3. built Image, modules, dtbs with .config and System.map
  4. built Morse driver (morse.ko and 80211ah.ko) against the patched kernel
  5. download firmware *bin files
  6. wrote the dts, compiled

My DTS: morse-mm610x-spi-overlay.dts

/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709", "brcm,bcm2711"; 

    fragment@0 {
        target = <&spi0>;
        __overlay__ {
            pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
            cs-gpios = <&gpio 8 1>;
            #address-cells = <1>;
            #size-cells = <0>;
            status = "okay";

            mm6108: mm6108@0 {
                compatible = "morse,mm610x-spi";
                reg = <0>; /* CE0 */
                reset-gpios = <&gpio 17 1>;
                power-gpios = <&gpio 23 0>,
                                <&gpio 24 0>;
                spi-irq-gpios = <&gpio 5 0>;
                spi-max-frequency = <10000000>;
                status = "okay";
            };
            spidev@1 { reg = <1>; status = "disabled"; };
            spidev@2 { reg = <2>; status = "disabled"; };
        };
    };
    fragment@1 {
            target = <&gpio>;
            __overlay__ {
                    spi0_pins: spi0_pins {
                            brcm,pins     = <9 10 11>;
                            brcm,function = <4  4  4>;
                            brcm,pull     = <2  2  2>; 
                    };
                    spi0_cs_pins: spi0_cs_pins {
                            brcm,pins     = <8>;
                            brcm,function = <1>;
                            brcm,pull     = <2>;
                    };

                    mm6108_pins: mm6108_pins {
                            brcm,pins       = <17 23 24>;
                            brcm,function   = <1 1 1>;
                            brcm,pull       = <0 0 0>;
                    };
            };
    };
};

Then I deployed them to the SDcard running on RPi 5, created symbolic link to bcf_boardtype_0801.bin.

After reboot. I got these SPI errors “chip select 0 already in use”

[    2.226925] rp1-firmware rp1_firmware: RP1 Firmware version eb39cfd516f8c90628aa9d91f52370aade5d0a55
[    2.229240] spi spi0.0: chipselect 0 already in use
[    2.229249] spi_master spi0: spi_device register error /axi/pcie@1000120000/rp1/spi@50000/spidev@0
[    2.229256] spi_master spi0: Failed to create SPI device for /axi/pcie@1000120000/rp1/spi@50000/spidev@0

and the driver didn’t load

[    9.892319] dot11ah: loading out-of-tree module taints kernel.
[    9.893016] Morse Micro Dot11ah driver registration. Version 0-rel_1_16_4_2025_Sep_18
[   10.185262] morse micro driver registration. Version 0-rel_1_16_4_2025_Sep_18
[   10.185706] morse_spi spi0.0: morse_spi_probe: failed to init SPI with CMD63 (ret:-61)
[   10.185719] morse_spi_probe failed. The driver has not been loaded!
[   10.185721] morse_spi spi0.0: probe with driver morse_spi failed with error -61

My config.txt has these lines, and my DTBO has lines to disable spidev@

dtoverlay=spi0-0cs
dtoverlay=morse-mm610x-spi-overlay

Can someone help me get pass this issue? Thanks

NOTE: I followed Yourself’s repo and blacklisted morse, morse_spi, dot11ah from autostart.

Okay, a quick update. I was able to disable the kernel pre-defined generic spidev device. Now, I no longer see the chip select 0 already in use error.

The next hurdle is morse_spi_probe failed to init SPI with CMD63

[    9.855297] morse micro driver registration. Version 0-rel_1_16_4_2025_Sep_18
[    9.857211] morse_spi spi0.0: morse_spi_probe: failed to init SPI with CMD63 (ret:-61)
[    9.857225] morse_spi_probe failed. The driver has not been loaded!
[    9.857228] morse_spi spi0.0: probe with driver morse_spi failed with error -61

It looks like: Error -61 translates to “No data available” or “Connection refused”. This error is returned by the kernel driver when it sends an initial command (CMD63) to the physical chip over the SPI bus, but the chip does not respond at all.

I am pretty sure the pin layout table I have is correct. Any ideas what I did wrong?

Hey @salvage4703

Have a quick look at Build Thread: HaLow for Raspberry Pi OS. I have a bit towards the bottom about this exact configuration. Your devicetree looks the same to me though.

Have you physically power cycled the device (reconnected the power) or just soft booted? Unfortunately most of our deployments use a reset script to toggle the reset line on boot. If that’s not run, on warmboots you will see these errors.
If this is the problem, I can provide a driver patch so you don’t need the reset script :slight_smile:

Hi, I still cannot bring up the driver after following your post. Could you kindly provide a driver patch? Thank you very much. I will update to provide the messages and a short paragaph on what I have done.

Can you confirm if the device is showing the same error after a cold boot? The patch won’t help if you are still seeing the same error on a cold boot.

@ajudge I was able to follow your post to bring up the driver. Thank you very much for the detailed guidance.

I’m trying to set up a basic HaLow AP/STA connection following the application note guidelines. I followed the section 7 of the app note, installed the hostapd and wpa_supplicant, started the hostapd on one set of hardware, and wpa_supplicant on the other. The AP appears to start successfully with hostapd_s1g, but no beacons are being transmitted and the station cannot see the AP in scans.

Hardware & Setup x2:

  • Platform: Raspberry Pi 5
  • Pi Hat: Seeed Studio WM1302
  • PCIe Halow card: Seed Studio WM6108
  • Morse Module: Quectel FGH100MHAAMD
  • Kernel: 6.12.25-v8-16k-morse+ (custom build)
  • Driver Version: morse-rel_1_16_4_2025_Sep_18
  • Firmware: mm6108.bin
  • BCF: bcf_fgh100mhaamd.bin
  • Hostap Version: 1.16
  • Country: AU

Symptoms

On AP (node1):

  1. hostapd_s1g starts successfully:
Operating Frequency: 924000 kHz
Operating BW: 8 MHz
Primary BW: 2 MHz
wlan1: AP-ENABLED

  1. Interface shows correct AP mode:
$ sudo iw dev wlan1 info
Interface wlan1
    type AP
    ssid MorseMicro
    channel 149 (5745 MHz), width: 160 MHz, center1: 5815 MHz

  1. BUT TX counters remain at zero:
$ ip -s link show wlan1
TX: bytes packets errors dropped carrier collsns
         0       0      0       0       0       0

  1. morse_cli commands fail:
$ morse_cli -i wlan1 stats -m
NL80211, code -1: Error callback called
NL80211, code -28: Failed to rcvmsgs
Command failed with error code -28

$ morse_cli -i wlan1 channel -a
Failed to get channel frequency
Command failed with error code -28

On Station:

  1. Scans return 0 BSSes:
$ sudo iw dev wlan1 scan
(returns empty - no APs found)

$ sudo wpa_cli -p /var/run/wpa_supplicant_s1g -i wlan1 scan_results
bssid / frequency / signal level / flags / ssid
(empty)

  1. wpa_supplicant debug shows:
nl80211: Received scan results (0 BSSes)
wlan1: No suitable network found

Configuration Files

hostapd.conf:

ctrl_interface=/var/run/hostapd_s1g
interface=wlan1
driver=nl80211
hw_mode=a
ieee80211ah=1
channel=44
op_class=71
country_code=AU
s1g_prim_chwidth=1
s1g_prim_1mhz_chan_index=0
ssid=MorseMicro
beacon_int=100
dtim_period=1
ap_max_inactivity=65536
s1g_capab=[SHORT-GI-ALL]
wpa=2
wpa_key_mgmt=SAE
rsn_pairwise=CCMP
sae_password=12345678
ieee80211w=2
wnm_sleep_mode=1
sae_pwe=1

wpa_supplicant.conf:

ctrl_interface=/var/run/wpa_supplicant_s1g
pmf=2
sae_pwe=1

network={
    ssid="MorseMicro"
    key_mgmt=SAE
    pairwise=CCMP
    psk="12345678"
}

Driver Status

$ lsmod | grep morse
morse                 442368  0
dot11ah               114688  1 morse
crc7                   49152  1 morse
mac80211             1097728  1 morse

$ dmesg | grep morse | grep -i country
morse_spi spi0.0: Country code AE is not supported
morse_spi spi0.0: Failed to set regulatory to country AE, staying in AU
morse_spi spi0.0:     country                                 : AU

Here is more detailed dmesg output

$ dmesg | grep -i “morse|error|fail” | tail -30
[    3.993528] morse_spi spi0.0:     mcs_mask                                : 1023
[    3.993530] morse_spi spi0.0:     no_hwcrypt                              : N
[    3.993532] morse_spi spi0.0:     enable_ext_xtal_init                    : N
[    3.993533] morse_spi spi0.0:     enable_otp_check                        : Y
[    3.993535] morse_spi spi0.0:     bcf                                     : bcf_fgh100mhaamd.bin
[    3.993536] morse_spi spi0.0:     serial                                  : default
[    3.993538] morse_spi spi0.0:     debug_mask                              : 8
[    3.993540] morse_spi spi0.0:     tx_status_lifetime_ms                   : 15000
[    3.993542] morse_spi spi0.0:     tx_queued_lifetime_ms                   : 1000
[    3.993543] morse_spi spi0.0:     max_txq_len                             : 32
[    3.993545] morse_spi spi0.0:     default_cmd_timeout_ms                  : 600
[    3.993546] morse_spi spi0.0:     reattach_hw                             : N
[    3.993548] morse_spi spi0.0:     hw_reload_after_stop                    : 5
[    3.993550] morse_spi spi0.0:     enable_short_bcn_as_dtim_override       : -1
[    3.993552] morse_spi spi0.0:     fw_bin_file                             :
[    3.993553] morse_spi spi0.0:     sdio_reset_time                         : 400
[    3.993555] morse_spi spi0.0:     macaddr_suffix                          : 00:00:00
[    3.993557] morse_spi spi0.0:     macaddr_octet                           : 255
[    3.993558] morse_spi spi0.0:     max_total_vendor_ie_bytes               : 514
[    3.993560] morse_spi spi0.0:     coredump_include                        : 1
[    3.993562] morse_spi spi0.0:     coredump_method                         : 1
[    3.993563] morse_spi spi0.0:     enable_coredump                         : Y
[    3.993565] morse_spi spi0.0:     spi_use_edge_irq                        : N
[    3.993567] morse_spi spi0.0:     spi_clock_speed                         : 50000000
[    3.993568] morse_spi spi0.0:     enable_mm_vendor_ie                     : Y
[    3.993570] morse_spi spi0.0:     fixed_guard                             : 0
[    3.993571] morse_spi spi0.0:     fixed_ss                                : 1
[    3.993573] morse_spi spi0.0:     fixed_bw                                : 2
[    3.993574] morse_spi spi0.0:     fixed_mcs                               : 4
[    3.993576] morse_spi spi0.0:     enable_fixed_rate                       : N

What I’ve Tried

  1. Verified both nodes have driver loaded correctly
  2. Confirmed firmware and BCF loaded successfully
  3. Checked regulatory domain is set to AU on both nodes
  4. Verified devices are physically close (6 inches apart without antenna)
  5. Restarted hostapd multiple times
  6. Tried manual scans with iw and wpa_supplicant

Based on the symptoms, it seems the firmware is not communicating with userspace applications:

  1. Driver loads successfully - dmesg shows firmware/BCF loaded with correct checksums
  2. hostapd reports success - AP-ENABLED message appears
  3. BUT no actual transmission - TX counters stay at 0, no beacons sent
  4. morse_cli fails with -28 - indicates netlink communication failure between driver and firmware
  5. No response to any commands - firmware appears unresponsive to all control requests

Questions

  1. Is it normal to have hostapd report “AP-ENABLED” but TX counters stay at 0?
  2. Why is morse_cli failing with error -28 (netlink communication failure)?
  3. Is there a firmware initialization step I’m missing?
  4. Are there any debug parameters or test modes I should try?

Any help would be greatly appreciated!

Hi @salvage4703

Apologies for the late reply.

No if hostap has started the AP, it should be beaconing.

I don’t recommend this, having an unloaded output (ie, no antenna connected), can damage the front end. Instead place the units ~1-2m away and use an antenna.

Please share the full dmesg output, after starting hostap. Consider loading the morse module with modparam debug_mask=0xf .

Please also run hostapd_s1g with -vv for extra logging.

If the driver is loading the firmware and BCF, there shouldn’t be anything that you are missing.

If you’re running this on a Raspberry Pi as per the build thread, you might find that NetworkManager is trying to take control of the interface and preventing a secondary application from starting it. Try running nmcli dev status to see if Network Manager is trying to manage your interface. If so, use

nmcli dev set wlan1 managed no

and then try to start hosapd_s1g as normal.

1 Like

Hi @ajudge and community,

I’ve successfully brought up the WM6108 on a Raspberry Pi 5 Rev 1.1 running Ubuntu Server 24.04 LTS and wanted to share my findings and ask for help with a throughput limitation.

hardware:

  • Raspberry Pi 5 Model B Rev 1.1
  • Raspberry Pi 4 B+ (working as intended, no big issues)
  • Seeed WM1302 Pi Hat (one per pi)
  • Seeed WM6108 mini-PCIe (Quectel FGH100MHAAMD) (one per pi)
  • 900 MHz antenna (one per pi)

software:

  • OS: Ubuntu Server 24.04 LTS
  • Kernel: 6.12.25-v8-16k-morse+ (compiled from stable_20250428 + Morse patches)
  • Driver: 0-rel_1_16_4_2025_Sep_18
  • Firmware: mm6108.bin + bcf_fgh100mhaamd.bin
  • hostapd_s1g / wpa_supplicant_s1g: v1.16

currently i have working:

  • wlan1 appears on boot automatically
  • AP/STA association works reliably
  • Ping: 0% packet loss, 45-70ms RTT at close range
  • HaLow link: channel=28, op_class=71 (916 MHz, 8 MHz BW, US)

fixes i required for Pi 5 Ubuntu (not documented afaik):

  1. Target &spi0 (RP1 SPI) NOT &spi10 (BCM2712 boot SPI — wrong controller entirely)
  2. reset-gpios = <&gpio 17 0> flag=0 (active-low), NOT flag=1
  3. Must add rp1 and pcie-brcmstb to initramfs for Ubuntu boot ordering
  4. Must copy bcm2712d0-rpi-5-b.dtb from compiled kernel (Rev 1.1 requires D0 silicon DTB)
  5. Use official pinctrl-0 with rp1_spi0_gpio9, rp1_spi0_cs_gpio7 etc.
  6. Do NOT use spi_clock_speed=1000000 — use the DTS 50MHz or 20MHz

But im facing an issue

TCP throughput from Pi 5 → Pi 4 (Pi 5 as STA, Pi 4 as AP):

  • Average: ~800 Kbps sender over 30 seconds
  • Pattern: 1-2 Mbps bursts alternating with periodic zero-transfer seconds (~every 2-3s)
  • 11-12 TCP retransmits per 30 seconds

e.g:
Connecting to host 10.0.0.1, port 5201
[ 5] local 10.0.0.2 port 59388 connected to 10.0.0.1 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 256 KBytes 2.10 Mbits/sec 0 42.4 KBytes
[ 5] 1.00-2.00 sec 128 KBytes 1.05 Mbits/sec 0 46.7 KBytes
[ 5] 2.00-3.00 sec 128 KBytes 1.05 Mbits/sec 0 50.9 KBytes
[ 5] 3.00-4.00 sec 0.00 Bytes 0.00 bits/sec 1 52.3 KBytes
[ 5] 4.00-5.00 sec 128 KBytes 1.05 Mbits/sec 0 56.6 KBytes
[ 5] 5.00-6.00 sec 128 KBytes 1.05 Mbits/sec 0 59.4 KBytes
[ 5] 6.00-7.00 sec 128 KBytes 1.05 Mbits/sec 0 66.5 KBytes
[ 5] 7.00-8.00 sec 0.00 Bytes 0.00 bits/sec 1 50.9 KBytes
[ 5] 8.00-9.00 sec 256 KBytes 2.10 Mbits/sec 0 59.4 KBytes
[ 5] 9.00-10.00 sec 0.00 Bytes 0.00 bits/sec 2 43.8 KBytes
[ 5] 10.00-11.00 sec 128 KBytes 1.05 Mbits/sec 0 49.5 KBytes
[ 5] 11.00-12.00 sec 0.00 Bytes 0.00 bits/sec 0 52.3 KBytes
[ 5] 12.00-13.00 sec 256 KBytes 2.10 Mbits/sec 2 36.8 KBytes

UDP throughput Pi 5 → Pi 4:

  • Sender: ~1.3 Mbps
  • Receiver: ~837 Kbps with 27% packet loss

e.g:
Connecting to host 10.0.0.1, port 5201
[ 5] local 10.0.0.2 port 54628 connected to 10.0.0.1 port 5201
[ ID] Interval Transfer Bitrate Total Datagrams
[ 5] 0.00-1.00 sec 259 KBytes 2.12 Mbits/sec 184
[ 5] 1.00-2.00 sec 164 KBytes 1.34 Mbits/sec 116
[ 5] 2.00-3.00 sec 157 KBytes 1.29 Mbits/sec 111
[ 5] 3.00-4.00 sec 83.4 KBytes 683 Kbits/sec 59
[ 5] 4.00-5.00 sec 175 KBytes 1.44 Mbits/sec 124

dmesg Under Load:

morse_spi_find_token failed
morse_spi_cmd53_read failed
morse_spi spi0.0: spi: cmd53_write fn=1 0x00006004:4 r=0x100a0002 b=0xffffffff (ret:-71)
morse_spi spi0.0: morse_mac_restart: Core-dump failed (errno:-5)
morse_spi spi0.0: morse_mac_restart: Failed to access HW (errno:-5)
morse_spi spi0.0: morse_mac_restart_work: HW restart failed (errno:-5, count:1)

This happens ~every few seconds under sustained TCP load, causing the periodic gaps.

This is my current wm6108-spi-pi5.dts

/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708",
                 "brcm,bcm2709", "brcm,bcm2711", "brcm,bcm2712";

    fragment@0 {
        target = <&spi0>;
        __overlay__ {
            pinctrl-0 = <&rp1_spi0_gpio9 &rp1_spi0_cs_gpio7
                         &morse_wake &morse_busy &morse_irq &morse_reset>;
            cs-gpios = <&gpio 8 1>;
            #address-cells = <1>;
            #size-cells = <0>;
            status = "okay";

            mm6108: mm6108@0 {
                compatible = "morse,mm610x-spi";
                reg = <0>;
                reset-gpios = <&gpio 17 0>;
                power-gpios = <&gpio 23 0>, <&gpio 24 0>;
                spi-irq-gpios = <&gpio 5 0>;
                spi-max-frequency = <50000000>;
                status = "okay";
            };
            spidev@0 { reg = <0>; status = "disabled"; };
            spidev@1 { reg = <1>; status = "disabled"; };
        };
    };

    fragment@1 {
        target = <&rp1_spi0_cs_gpio7>;
        __overlay__ {
            function = "gpio";
            pins = "gpio8";
            bias-pull-up;
        };
    };

    fragment@2 {
        target = <&gpio>;
        __overlay__ {
            morse_wake: morse_wake {
                function = "gpio";
                pins = "gpio23";
                output-high;
                bias-disable;
            };
            morse_busy: morse_busy {
                function = "gpio";
                pins = "gpio24";
                input;
                bias-pull-down;
            };
            morse_irq: morse_irq {
                function = "gpio";
                pins = "gpio5";
                bias-pull-up;
                input;
            };
            morse_reset: morse_reset {
                function = "gpio";
                pins = "gpio17";
                output-high;
                bias-disable;
            };
        };
    };
};

and this is my morse.conf

options morse bcf=bcf_fgh100mhaamd.bin country=US spi_clock_speed=20000000 enable_ps=0

ive currently tried:

  • spi_clock_speed: 1MHz, 20MHz, 50MHz (50MHz causes harder crashes, 20MHz slightly better)
  • spi_use_edge_irq=1 — no improvement
  • enable_ps=0 — no improvement
  • cs-gpios software CS — no improvement alone
  • Using proper pinctrl-0 with rp1_spi0_gpio9 — wlan1 stable but throughput same

I wanted to ask a couple of questions since i’m hitting a wall here,

  1. @ajudge mentioned a driver patch for warm boot issues. Would that patch also help with the RP1 SPI sustained TX throughput issue on Pi 5?
  2. Is there a known fix for cmd53_write ret:-71 under sustained load on RP1 SPI?
  3. Is there a recommended SPI clock speed for Pi 5 RP1 SPI with WM6108?
  4. Any Pi 5 users achieving >1 Mbps sustained TCP throughput with this setup?

The radio is clearly capable of much more (Pi 4 achieves 19 Mbps TCP per Gateworks). This appears to be a Pi 5 RP1 SPI host interface bottleneck. Any guidance appreciated!

Thanks in adance, and sorry my first post is a bunch of questions hehe, i intend to use Pi5 as a transmitter in moving scenarios.

Hi @boltythedoge

The patch mentioned moves the responsibility of performing a physical chip reset (asserting the reset line) from user space script to the driver itself. It will have no bearing on throughput during normal operation.

I haven’t seen this before in my experiments with the Pi5, but this error could indicate an issue with the bus. It could indicate power supply issues, and the setup I had built was using a lower power module.

A raspberry pi should be able to reach 50MHz spi clock.

With my Pi 5 setup, i was able to achieve higher throughput. This was not the same hardware though as I was using the Morse Micro Raspberry Pi hat which comes inside our EKH01 kit. As the WM6108 is a higher power module, you may be more susceptible to brownouts, as the Pi5 itself is quite power hungry. Check the power supply first.