[[PageOutline]] = GW16159 M.2 E-Key 802.11ah (!HaLow) radio The GW16159 M.2 E-Key Sub-1GHz 802.11ah radio uses the Silex SD-SDMAH module which itself uses the !MorseMicro MM6108 chip. '''NOTE: The GW16159 requires an M.2 E-Key socket with SDIO. For Gateworks this exists only on the VeniceFLEX product family.''' View the [https://www.gateworks.com/products/mini-pcie-expansion-cards/gw16159-802-11ah-halow-wifi-m2-card/ GW16159 Product Page] for pricing and specifications IEEE 802.11ah is a wireless networking protocol published in 2017 called Wi-Fi !HaLow as an amendment of the IEEE 802.11-2007 wireless networking standard. It uses 900 MHz license-exempt bands to provide extended-range Wi-Fi networks, compared to conventional Wi-Fi networks operating in the 2.4 GHz, 5 GHz and 6 GHz bands. It also benefits from lower energy consumption, allowing the creation of large groups of stations or sensors that cooperate to share signals, supporting the concept of the Internet of things (IoT). The protocol's low power consumption competes with Bluetooth, !LoRa, and Zigbee, and has the added benefit of higher data rates and wider coverage range. The radio communicates of the SDIO bus with 3.3V I/O at 50MHz. Datasheets: * [https://www.morsemicro.com/wp-content/uploads/2024/12/MM6108-Data-Sheet-v4.pdf MorseMicro MM6108 Datasheet] * [https://205257.fs1.hubspotusercontent-na1.net/hubfs/205257/SX-SDMAH_R2_Prod_Brochure_EN_v1.pdf SX-SDMAH Product Brief] ([https://www.silextechnology.com/connectivity-solutions/embedded-wireless/sx-sdmah Contact Silex for Datasheet]) M.2 Pin Details: * M2.56 W_DISABLE1# routed to the RESET_N pin of the SX_SDMAH with a 200k pu to VDD_3P3 * M2.54 W_DISABLE2# routed to the WAKE pin of the SX_SDMAH with a 10k pu to VDD_3P3 !WiFi Details: * !WiFi !HaLow 802.11ah 850-950MHz bands 1/2/4/8MHz channel width 21dBm max output power and 32Mbps theoretical maximum transmission rate * SDIO: 0x325b:0x0306 Software Details: * required software: * out-of-tree kernel driver: https://github.com/Gateworks/morse_driver/tree/gateworks-venice (forked from https://github.com/MorseMicro/morse_driver.git) * firmware: https://github.com/MorseMicro/morse_firmware.git * required CLI app: https://github.com/MorseMicro/morse_cli.git * custom version of hostapd/wpa_supplicant: https://github.com/MorseMicro/hostap * kernel patches: https://github.com/Gateworks/linux-venice/tree/v6.6.8-venice-mm6108 == Antenna The antenna port is MHF1 / u.FL x 1, 50 ohms impedance. The antenna type should be a rod and a +3.4dBi and 50 ohms impedance. To maintain the FCC cert from Silex for the SD-SDMAH module, a certified antenna needs to be used. The certified antenna is a Kyocera X9000984-4GDSMB [https://www.digikey.com/en/products/detail/kyocera-avx/X9000984-4GDSMB/13982460 Digi-Key Link] Note, a pigtail, MHF1 to SMA will be needed with the above antenna. This is the [https://shop.gateworks.com/index.php?route=product/product&product_id=42&search=sma Gateworks GW10036 Pigtail Cable] == Certifications The SDMAH from Silex has modular certifications at the following: * FCC Part 15.247 * ID: N6C-SDMAH * ISED RSS-247 * ID: 4908A-SDMAH Note, these certifications are only with the Silex recommended antennas. Note, while the module may be certified, often the final entire product (SBC, power supply, wireless cards, enclosure) have to be put through a final certification. == Software === Pre-built images Currently the mm6108 driver requires the Linux 6.6 kernel and therefore it is not compatible with our Linux 6.12 pre-built images. Gateworks has pre-built images with the mm6108 driver here: * [https://dev.gateworks.com/venice/images/noble-venice-mm6108.img.gz noble-venice-mm6108.img.gz] (see [http://trac.gateworks.com/wiki/venice/firmware#disk-images compressed-disk-image]) * [https://dev.gateworks.com/venice/kernel/linux-venice-mm6108.tar.xz linux-venice-mm6108.tar.xz Kernel tarball] (see [http://trac.gateworks.com/wiki/linux/kernel#install kernel-tarball install]) === Driver The mm6108 on the GW16159 is supported by the open-source out-of-tree Linux kernel driver from !MorseMicro. building with the Gateworks Venice BSP: 1. change the Linux branch to v6.6.8-venice-mm6108 {{{#!bash git -C linux remote update git -C linux checkout v6.6.8-venice-mm6108 }}} 2. add a 'custom_kernel_mm6108' script {{{#!bash cat <<\EOF > custom_kernel_mm6108 #!/bin/bash -e DIR=$PWD/mm610x OUTDIR=$DIR/out DESTDIR=$2 MORSE_VER=1.12.4 LIBNL_VER=libnl3_11_0 OPENSSL_VER=openssl-3.4.0 COUNTRY=US mkdir -p $DESTDIR/usr/sbin mkdir -p $DESTDIR/etc/modprobe.d mkdir -p $DIR cd $DIR # get repos of what we will build [ -d morse_driver ] || git clone --recurse-submodules https://github.com/Gateworks/morse_driver.git -b gateworks-venice [ -d libnl ] || git clone https://github.com/thom311/libnl.git -b $LIBNL_VER [ -d openssl ] || git clone https://github.com/openssl/openssl.git -b $OPENSSL_VER [ -d hostap ] || git clone https://github.com/MorseMicro/hostap.git -b $MORSE_VER [ -d morse_cli ] || git clone https://github.com/MorseMicro/morse_cli.git -b $MORSE_VER echo "Building mm6108 driver..." CONFIG_MORSE_SDIO=y \ CONFIG_MORSE_USER_ACCESS=y \ CONFIG_MORSE_VENDOR_COMMAND=y \ CONFIG_MORSE_SDIO_ALIGNMENT=4 \ CONFIG_MORSE_DEBUGFS=y \ CONFIG_MORSE_IPMON=y \ CONFIG_MORSE_MONITOR=y \ CONFIG_MORSE_POWERSAVE_MODE=0 \ CONFIG_MORSE_COUNTRY=$COUNTRY \ CONFIG_MORSE_RC=y \ CONFIG_WLAN_VENDOR_MORSE=m" make -C morse_driver $ARGS make -C morse_driver $ARGS INSTALL_MOD_PATH=$2 modules_install # firmware: # - mm6108 firmware # - board configuration file (BCF) that provides driver with calibration constants and chip gpio config echo "Copying mm6108 firmware..." mkdir -p $2/lib/firmware/morse wget http://dev.gateworks.com/firmware/gw16159/mm6108.bin -O $2/lib/firmware/morse/mm6108.bin wget http://dev.gateworks.com/firmware/gw16159/LICENSE -O $2/lib/firmware/morse/LICENSE wget "http://dev.gateworks.com/firmware/gw16159/HY103760XB_SX-SDMAH-R2(US)_20240807_5V0.bin" -O $2/lib/firmware/morse/bcf_sx sdmah_fem5p0.bin [ -d $OUTDIR/include/libnl3 ] || { cd libnl ./autogen.sh ./configure --host=$ARCH CC=${CROSS_COMPILE}gcc --prefix=$OUTDIR --disable-shared make clean make -j32 make install cd .. } [ -d $OUTDIR/include/openssl ] || { cd openssl ./Configure linux-generic32 no-shared no-dso no-async -DL_ENDIAN --prefix=$OUTDIR --openssldir=$OUTDIR # needed no-async to build latest openssl against uclib make -j32 \ CC=${CROSS_COMPILE}gcc \ RANLIB=${CROSS_COMPILE}ranlib \ LD=${CROSS_COMPILE}ld \ MAKEDEPPROG=${CROSS_COMPILE}gcc \ PROCESSOR=ARM #make install # installs man pages too make install_sw cd .. } # wpa_supplicant [ -r hostap/wpa_supplicant/wpa_supplicant_s1g.bin ] || { cp hostap/wpa_supplicant/defconfig hostap/wpa_supplicant/.config make -C hostap/wpa_supplicant/ clean CFLAGS="-I $OUTDIR/include/libnl3 -I $OUTDIR/include" \ LDFLAGS="-L $OUTDIR/lib/ --static" \ DESTDIR="$OUTDIR/sbin" \ BINDIR=/usr/sbin \ LIBS="-lnl-3 -lm -lpthread -lcrypto -lssl" \ CC=${CROSS_COMPILE}gcc \ make -j32 -C hostap/wpa_supplicant/ # MORSE_VERSION=rel_1_11_3_2024_Mar_28 } cp hostap/wpa_supplicant/{wpa_supplicant_s1g,wpa_cli_s1g,wpa_passphrase_s1g} $DESTDIR/usr/sbin/ # hosapd [ -r hostap/hostapd/hostapd_s1g.bin ] || { cp hostap/hostapd/defconfig hostap/hostapd/.config make -C hostap/hostapd/ clean CFLAGS="-I $OUTDIR/include/libnl3 -I $OUTDIR/include" \ LDFLAGS="-L $OUTDIR/lib/ --static" \ DESTDIR="$OUTDIR/sbin" \ BINDIR=/usr/sbin \ LIBS="-lnl-3 -lm -lpthread -lcrypto -lssl" \ CC=${CROSS_COMPILE}gcc \ make -j32 -C hostap/hostapd/ # MORSE_VERSION=rel_1_11_3_2024_Mar_28 } cp hostap/hostapd/{hostapd_s1g,hostapd_cli_s1g} $DESTDIR/usr/sbin/ # morse_cli [ -r morse_cli/morse_cli.bin ] || { make -C morse_cli clean CFLAGS="-I $OUTDIR/include/libnl3 -I $OUTDIR/include" \ LDFLAGS="-L $OUTDIR/lib/ --static" \ CC=${CROSS_COMPILE}gcc \ make \ CONFIG_MORSE_TRANS_NL80211=1 \ CONFIG_MORSE_STATIC=1 \ -j32 -C morse_cli } cp morse_cli/morse_cli $DESTDIR/usr/sbin/ # module parameters echo "options morse country=$COUNTRY enable_ext_xtal_init=1 bcf=bcf_sxsdmah_fem5p0.bin" > $DESTDIR/etc/modprobe.d/morse.conf EOF chmod +x custom_kernel_mm6108 }}} 3. rebuild the ubuntu-image: {{{#!bash source ./setup-environment make ubuntu-image }}} Module Parameters: - There are a number of module parameters supported by morse.ko however the required ones for the GW16159 are: * country=US * enable_ext_xtal_init=1 * bcf=bcf_sxsdmah_fem5p0.bin - These can be placed in /etc/modprobe..d such as: {{{#!bash echo "options morse country=US enable_ext_xtal_init=1 bcf=bcf_sxsdmah_fem5p0.bin" > /etc/modprobe.d/morse.conf }}} Kernel Messages: {{{#!bash # dmesg | grep mmc0 [ 1.009160] mmc0: SDHCI controller on 30b40000.mmc [30b40000.mmc] using ADMA [ 1.029119] mmc_sdio_init_card mmc0 quirks=0x0 ocr_card=0x300000 (1.8v=1) [ 1.052784] mmc_sdio_init_card mmc0 setting voltage to 1.8V [ 1.166152] mmc0: new high speed SDIO card at address 0001 # cat /sys/bus/mmc/devices/mmc0:0001/{vendor,device) 0x325b 0x0306 # modprobe mac80211 # modprobe dot11ah [ 37.240328] dot11ah: module verification failed: signature and/or required key missing - tainting kernel [ 37.251882] Morse Micro Dot11ah driver registration. Version 0-rel_1_12_4_2024_Jun_11-6-g63cd0768 # modprobe morse bcf=bcf_default.bin country=US [ 37.285877] morse micro driver registration. Version 0-rel_1_12_4_2024_Jun_11-6-g63cd0768 [ 37.299842] morse_sdio mmc0:0001:1: sdio new func 1 vendor 0x325b device 0x306 block 0x8/0x8 [ 37.308556] morse_sdio mmc0:0001:2: sdio new func 2 vendor 0x325b device 0x306 block 0x200/0x200 [ 37.317515] morse_of_probe MORSE_SDIO_RW_ADDR_BOUNDARY_MASK=0xffff0004 [ 37.324088] morse_sdio mmc0:0001:2: Device node not found [ 37.329517] morse_sdio mmc0:0001:2: No pin configs found, using defaults... [ 37.336503] morse_sdio mmc0:0001:2: mm_wake_gpio=3 mm_ps_async_gpio=7 mm_reset_gpio=5 mm_spi_irq_gpio=0 [ 37.357195] morse_sdio mmc0:0001:2: Loaded firmware from morse/mm6108.bin, size 433044, crc32 0x436ba524 [ 37.367241] morse_sdio mmc0:0001:2: Loaded BCF from morse/bcf_default.bin, size 1127, crc32 0xd9cd0bd3 [ 37.927510] morse_ieee80211_init tx_sk_pacing_shift=7 [ 37.932604] morse_ps_init async_gpio=7 irq=35 [ 37.937046] morse_ps_init request_irq irq=0 ret=35 [ 37.942141] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht' [ 37.956407] morse_sdio mmc0:0001:2: Driver loaded with kernel module parameters [ 37.963794] morse_sdio mmc0:0001:2: enable_1mhz_probes : Y [ 37.971548] morse_sdio mmc0:0001:2: enable_hw_scan : Y [ 37.971558] morse_sdio mmc0:0001:2: enable_pv1 : N [ 37.986917] morse_sdio mmc0:0001:2: enable_page_slicing : N [ 37.994630] morse_sdio mmc0:0001:2: log_modparams_on_boot : Y [ 38.002335] morse_sdio mmc0:0001:2: enable_mcast_at_op_bw : N [ 38.010038] morse_sdio mmc0:0001:2: enable_mcast_whitelist : Y [ 38.017716] morse_sdio mmc0:0001:2: ocs_type : 1 [ 38.025382] morse_sdio mmc0:0001:2: enable_auto_mpsw : Y [ 38.033051] morse_sdio mmc0:0001:2: duty_cycle_probe_retry_threshold : 2500 [ 38.040979] morse_sdio mmc0:0001:2: duty_cycle_mode : 0 [ 38.048646] morse_sdio mmc0:0001:2: enable_auto_duty_cycle : Y [ 38.056313] morse_sdio mmc0:0001:2: dhcpc_lease_update_script : /morse/scripts/dhcpc_update.sh [ 38.066499] morse_sdio mmc0:0001:2: enable_ibss_probe_filtering : Y [ 38.074165] morse_sdio mmc0:0001:2: enable_dhcpc_offload : N [ 38.081837] morse_sdio mmc0:0001:2: enable_arp_offload : N [ 38.089504] morse_sdio mmc0:0001:2: enable_bcn_change_seq_monitor : 0 [ 38.097173] morse_sdio mmc0:0001:2: enable_cac : 0 [ 38.104842] morse_sdio mmc0:0001:2: max_mc_frames : 10 [ 38.112599] morse_sdio mmc0:0001:2: tx_max_power_mbm : 2200 [ 38.120529] morse_sdio mmc0:0001:2: enable_twt : Y [ 38.128193] morse_sdio mmc0:0001:2: enable_mac80211_connection_monitor : N [ 38.135866] morse_sdio mmc0:0001:2: enable_airtime_fairness : N [ 38.143532] morse_sdio mmc0:0001:2: enable_raw : Y [ 38.151198] morse_sdio mmc0:0001:2: max_aggregation_count : 0 [ 38.158863] morse_sdio mmc0:0001:2: max_rate_tries : 1 [ 38.166528] morse_sdio mmc0:0001:2: max_rates : 3 [ 38.174194] morse_sdio mmc0:0001:2: enable_watchdog_reset : N [ 38.181863] morse_sdio mmc0:0001:2: watchdog_interval_secs : 30 [ 38.189615] morse_sdio mmc0:0001:2: enable_watchdog : Y [ 38.197283] morse_sdio mmc0:0001:2: country : US [ 38.205040] morse_sdio mmc0:0001:2: enable_cts_to_self : N [ 38.212707] morse_sdio mmc0:0001:2: enable_rts_8mhz : N [ 38.220374] morse_sdio mmc0:0001:2: enable_trav_pilot : Y [ 38.228038] morse_sdio mmc0:0001:2: enable_sgi_rc : Y [ 38.235701] morse_sdio mmc0:0001:2: enable_mbssid_ie : N [ 38.243371] morse_sdio mmc0:0001:2: virtual_sta_max : 0 [ 38.251035] morse_sdio mmc0:0001:2: thin_lmac : 0 [ 38.258703] morse_sdio mmc0:0001:2: enable_dynamic_ps_offload : Y [ 38.266373] morse_sdio mmc0:0001:2: enable_ps : 2 [ 38.274038] morse_sdio mmc0:0001:2: enable_subbands : 2 [ 38.281707] morse_sdio mmc0:0001:2: enable_survey : Y [ 38.289373] morse_sdio mmc0:0001:2: mcs10_mode : 0 [ 38.297041] morse_sdio mmc0:0001:2: mcs_mask : 1023 [ 38.304966] morse_sdio mmc0:0001:2: no_hwcrypt : 0 [ 38.312630] morse_sdio mmc0:0001:2: enable_ext_xtal_init : Y [ 38.320294] morse_sdio mmc0:0001:2: enable_otp_check : 1 [ 38.327962] morse_sdio mmc0:0001:2: bcf : bcf_default.bin [ 38.336849] morse_sdio mmc0:0001:2: serial : default [ 38.345040] morse_sdio mmc0:0001:2: debug_mask : 8 [ 38.352708] morse_sdio mmc0:0001:2: tx_status_lifetime_ms : 15000 [ 38.360723] morse_sdio mmc0:0001:2: tx_queued_lifetime_ms : 1000 [ 38.368651] morse_sdio mmc0:0001:2: max_txq_len : 32 [ 38.376403] morse_sdio mmc0:0001:2: default_cmd_timeout_ms : 600 [ 38.384242] morse_sdio mmc0:0001:2: enable_short_bcn_as_dtim_override : -1 [ 38.392000] morse_sdio mmc0:0001:2: fw_bin_file : [ 38.399581] morse_sdio mmc0:0001:2: sdio_reset_time : 400 [ 38.407420] morse_sdio mmc0:0001:2: macaddr_suffix : 00:00:00 [ 38.415697] morse_sdio mmc0:0001:2: macaddr_octet : 255 [ 38.423538] morse_sdio mmc0:0001:2: max_total_vendor_ie_bytes : 514 [ 38.431379] morse_sdio mmc0:0001:2: coredump_include : 1 [ 38.439047] morse_sdio mmc0:0001:2: coredump_method : 1 [ 38.446714] morse_sdio mmc0:0001:2: enable_coredump : Y [ 38.454381] morse_sdio mmc0:0001:2: sdio_clk_debugfs : [ 38.461968] morse_sdio mmc0:0001:2: enable_mm_vendor_ie : Y [ 38.475337] uaccess char driver major number is 237 [ 38.481173] morse_io: Device node '/dev/morse_io' created successfully # ls -l /sys/class/net/wlan0 lrwxrwxrwx 1 root root 0 Nov 21 00:59 /sys/class/net/wlan0 -> ../../devices/platform/soc@0/30800000.bus/30b40000.mmc/mmc_host/mmc0/mmc0 :0001/mmc0:0001:2/net/wlan0 }}} === Kernel Patches There is a small set of kernel patches that improve the experience for 802.11ah: * [https://github.com/MorseMicro/linux MorseMicro Linux patches] - 6.6.31: * [https://github.com/MorseMicro/linux/commit/69283c181040406bd9d594e47e38542343983f84 mac80211: implement support for thin LMAC S1G NDP block acknowledgements] * [https://github.com/MorseMicro/linux/commit/f948c7ac54c73e605791f576067cb11ce229e080 mac80211: Mesh support] * [https://github.com/MorseMicro/linux/commit/3804ca8ec2675fbfe96c6f7fded7f91918d8887c mac80211: IBSS bridge support] * [https://github.com/MorseMicro/linux/commit/8d5f1b326eb7c6f4812894c2b362abc245dec949 mac80211: tx s1g AP ecsa support] * [https://github.com/MorseMicro/linux/commit/77cd2d08f1cec39e3c8b2fea734772a73ac89ca9 mac80211: mlme s1g ecsa support] * [https://github.com/Gateworks/linux-venice/tree/v6.6.8-venice-mm6108 Linux v6.6 Gateworks v6.6.8-venice-mm6108] A basic AP/station !HaLow network without powersave requirements or extended channel switch will function without these patches. It has been reported that with these kernel patches have not caused any noticeable obvious issues with other mac80211 radios === hostapd and wpa_supplicant !MorseMicro has a [https://github.com/MorseMicro/hostap/ custom version of hostapd and wpa_supplicant] with support added for 802.11ah. For most of the added configuration options there is no current way to pass them via ieee80211 APIs with nl80211 so instead the configuration is supplied via vendor-specific commands using the {{{morse_cli}}} userspace application. These are typically built as {{{hostapd_s1g}}} and {{{wpa_supplicant_s1g}}} so that they can coexist with the standard tools. === morse_cli The {{{morse_cli}}} userspace application can be used to interact with the driver. It communicates over netlink so the interface must be up before you can talk to it. Much of the functionality is present for {{{hostapd_s1g}}} and {{{wpa_supplicant_s1g}}} to use. Examples: {{{#!bash # make sure interface is up ifconfig wlan0 up # morse_cli --interface=wlan0 hw_version HW Version: MM6108-A1 # morse_cli --interface=wlan0 version Morse_cli Version: rel_1_12_5_2024_Jul_25-4-g3541610 FW Version: rel_1_12_4_2024_Jun_11 # morse_cli channel Full Channel Information Operating Frequency: 916000 kHz Operating BW: 8 MHz Primary BW: 2 MHz Primary Channel Index: 0 }}} - note if not specified the interface defaults to wlan0 [=#channels] == Channel Mapping The !HaLow channels are mapped to standard 802.11 channels: * US ||= S1G Op Class =||= Global Op Class =||= Channel Bandwidth =||= Channel Number =||= Center Frequency =|| || 1 || 68 || 1 || 1 || 902.5 || || 1 || 68 || 1 || 3 || 903.5 || || 1 || 68 || 1 || 5 || 904.5 || || 1 || 68 || 1 || 7 || 905.5 || || 1 || 68 || 1 || 9 || 906.5 || || 1 || 68 || 1 || 11 || 907.5 || || 1 || 68 || 1 || 13 || 908.5 || || 1 || 68 || 1 || 15 || 909.5 || || 1 || 68 || 1 || 17 || 910.5 || || 1 || 68 || 1 || 19 || 911.5 || || 1 || 68 || 1 || 21 || 912.5 || || 1 || 68 || 1 || 23 || 913.5 || || 1 || 68 || 1 || 25 || 914.5 || || 1 || 68 || 1 || 27 || 915.5 || || 1 || 68 || 1 || 29 || 916.5 || || 1 || 68 || 1 || 31 || 917.5 || || 1 || 68 || 1 || 33 || 918.5 || || 1 || 68 || 1 || 35 || 919.5 || || 1 || 68 || 1 || 37 || 920.5 || || 1 || 68 || 1 || 39 || 921.5 || || 1 || 68 || 1 || 41 || 922.5 || || 1 || 68 || 1 || 43 || 923.5 || || 1 || 68 || 1 || 45 || 924.5 || || 1 || 68 || 1 || 47 || 925.5 || || 1 || 68 || 1 || 49 || 926.5 || || 1 || 68 || 1 || 51 || 927.5 || || 2 || 69 || 2 || 2 || 903.0 || || 2 || 69 || 2 || 6 || 905.0 || || 2 || 69 || 2 || 10 || 907.0 || || 2 || 69 || 2 || 14 || 909.0 || || 2 || 69 || 2 || 18 || 911.0 || || 2 || 69 || 2 || 22 || 913.0 || || 2 || 69 || 2 || 26 || 915.0 || || 2 || 69 || 2 || 30 || 917.0 || || 2 || 69 || 2 || 34 || 919.0 || || 2 || 69 || 2 || 38 || 921.0 || || 2 || 69 || 2 || 42 || 923.0 || || 2 || 69 || 2 || 46 || 925.0 || || 2 || 69 || 2 || 50 || 927.0 || || 2 || 70 || 4 || 8 || 906.0 || || 2 || 70 || 4 || 16 || 910.0 || || 2 || 70 || 4 || 24 || 914.0 || || 2 || 70 || 4 || 32 || 918.0 || || 2 || 70 || 4 || 40 || 922.0 || || 2 || 70 || 4 || 48 || 926.0 || || 2 || 71 || 8 || 12 || 908.0 || || 2 || 71 || 8 || 28 || 916.0 || || 2 || 71 || 8 || 44 || 924.0^^^1^^^ || 1. 924MHz is disabled in mm6108 firmware due to noise exceeding specification == Configuration The changes made by !MorseMicro to hostap add a number of parameters to hostapd.conf: * ieee80211ah: IEEE 802.11ah (S1G) supported * s1g_prim_chwidth: Sub-1 GHz primary channel bandwidth * s1g_prim_1mhz_chan_index: Sub-1 GHz primary 1MHz channel index * s1g_capab: S1G capabilities (list of flags) * s1g_traveling_pilots: Sub-1 Ghz traveling pilots * s1g_bss_color: Sub-1 GHz BSS color (0-7). * s1g_max_mpdu: Sub-1 GHz MPDU maximum length * s1g_ampdu: Sub-1 GHz A-MPDU support * s1g_max_ampdu_len_exp: Sub-1 GHz A-MPDU length exponent * s1g_basic_mcs_nss_set: Sub-1 GHz basic NSS/MCS support For documentation on these refer to the code: * [https://github.com/MorseMicro/hostap/blob/v1.14/hostapd/hostapd_s1g.conf hostapd_s1g.conf] * [https://github.com/MorseMicro/hostap/blob/v1.14/hostapd_s1g_configuration.md hostapd_s1g_configuration] Example configurations: * infrastructure mode using WPA2: - AP: {{{#!bash cat << EOF > hostapd_s1g.conf cat hostapd_s1g.conf interface=wlan0 logger_syslog=-1 logger_syslog_level=2 logger_stdout=-1 logger_stdout_level=2 ctrl_interface=/var/run/hostapd ctrl_interface_group=0 ssid=HaLow-WPA2 country_code=US hw_mode=a beacon_int=100 dtim_period=2 max_num_sta=255 rts_threshold=-1 fragm_threshold=-1 macaddr_acl=0 auth_algs=3 ignore_broadcast_ssid=0 wmm_enabled=1 wmm_ac_bk_cwmin=4 wmm_ac_bk_cwmax=10 wmm_ac_bk_aifs=7 wmm_ac_bk_txop_limit=0 wmm_ac_bk_acm=0 wmm_ac_be_aifs=3 wmm_ac_be_cwmin=4 wmm_ac_be_cwmax=10 wmm_ac_be_txop_limit=0 wmm_ac_be_acm=0 wmm_ac_vi_aifs=2 wmm_ac_vi_cwmin=3 wmm_ac_vi_cwmax=4 wmm_ac_vi_txop_limit=94 wmm_ac_vi_acm=0 wmm_ac_vo_aifs=2 wmm_ac_vo_cwmin=2 wmm_ac_vo_cwmax=3 wmm_ac_vo_txop_limit=47 wmm_ac_vo_acm=0 ieee80211ah=1 s1g_prim_chwidth=1 s1g_prim_1mhz_chan_index=0 s1g_capab=[SHORT-GI-ALL] eapol_key_index_workaround=0 own_ip_addr=127.0.0.1 #918.5MHz@1 #channel=33 #op_class=68 #907MHz@2 #channel=10 #op_class=69 #922Mhz@4 #channel=40 #op_class=70 #916MHz@8 channel=28 op_class=71 # WPA2 security wpa=2 wpa_passphrase=strongpassword123 wpa_key_mgmt=WPA-PSK wpa_pairwise=TKIP rsn_pairwise=CCMP EOF hostapd_s1g ./hostapd_s1g.conf -B ifconfig wlan0 192.168.1.1 iperf3 -s }}} * STA: {{{#!bash wpa_passphrase_s1g test strongpassword123 > wpa_supplicant_s1g.conf wpa_supplicant_s1g -iwlan0 -c ./wpa_supplicant_s1g.conf & ifconfig wlan0 192.168.1.128 iperf3 -c 192.168.1.1 }}} [=#performance] == Performance The MM6108 supports: * Spacial Streams: 1 * Channel bandwidths: 1/2/4/8 MHz * Modulation and Coding Schemes: MCS 0-7 (1/2/4 Mhz); MCS 10 (1Mhz only) * Data rates up to 32.5Mbps (MCS 7, 64-QAM, 8 Mhz channel, 4 us GI) Since 802.11ah is designed for low-power, long-range IoT applications, its rates are lower than higher-frequency Wi-Fi standards like 802.11n/ac/ax. 802.11ah uses OFDM with a subcarrier spacing of 31.25 kHz (1/32 µs), scaled down from 802.11ac’s 312.5 kHz to support narrower channels. The number of data subcarriers varies with bandwidth: - 1 MHz: 24 data subcarriers. - 2 MHz: 52 data subcarriers. - 4 MHz: 108 data subcarriers. - 8 MHz: 234 data subcarriers. The PHY rate is calculated as: PHY Rate = (Number of Data Subcarriers) × (Bits per Subcarrier) × (Coding Rate) × (Symbols per Second) × (Number of Spatial Streams): - Data Subcarriers: * 1 MHz: 24 data subcarriers. * 2 MHz: 52 data subcarriers. * 4 MHz: 108 data subcarriers. * 8 MHz: 234 data subcarriers. - Bits per Subcarier and Coding Rate: Depends on MCS index - Symbols per Second: * Long GI (8us): 4 us data + 4 us GI: 125,000 symbols/s * Short GI (4us): 4 us data + 0 us GI: 250,000 symbols/s - Spatial Streams: 1 (common for IoT devices). [=#mcs_table] Calculated max PHY Data Rates per MCS, channel bandwidth, and gaurd interval: ||= MCS ||= Modulation ||= Coding rate ||= 1 MHz channel (Mbps) Long GI / Short GI ||= 2 MHz channel (Mbps) Long GI / Short GI ||= 4 MHz channel (Mbps) Long GI / Short GI ||= 8 MHz channel (Mbps) Long GI / Short GI || || 0 || BPSK || 1/2 || 0.3 / 0.33 || 0.65 / 0.72 || 1.35 / 1.5 || 2.925 / 3.25 || || 1 || QPSK || 1/2 || 0.6 / 0.67 || 1.3 / 1.44 || 2.7 / 3.0 || 5.85 / 6.5 || || 2 || QPSK || 3/4 || 0.9 / 1.0 || 1.95 / 2.17 || 4.05 / 4.5 || 8.775 / 9.75 || || 3 || 16-QAM || 1/2 || 1.2 / 1.33 || 2.6 / 2.89 || 5.4 / 6.0 || 11.7 / 13.0 || || 4 || 16-QAM || 3/4 || 1.8 / 2.0 || 3.9 / 4.33 || 8.1 / 9.0 || 17.55 / 19.5 || || 5 || 64-QAM || 2/3 || 2.4 / 2.67 || 5.2 / 5.78 || 10.8 / 12.0 || 23.4 / 26.0 || || 6 || 64-QAM || 3/4 || 2.7 / 3.0 || 5.85 / 6.5 || 12.15 / 13.5 || 26.3 / 29.3 || || 7 || 64-QAM || 5/6 || 3.0 / 3.34 || 6.5 / 7.22 || 13.5 / 15.0 || 29.3 / 32.5 || || 10 || BPSK || 1/2 || 0.15 / 0.17 || N/A || N/A || N/A || Note that MCS10 is a special case in 802.11ah and is for 1MHz cahnnels only with a repetition mode modulated with BPSK and 1/2 coding rate. This is for ultra-low rate extended range. The repetition doubles robustness but halves throughput. Actual throughput will be less taking into account overhead, congestion, and RF factors. To examine your link you can use the following: * examine the rate control stats: {{{#!bash cat /sys/kernel/debug/ieee80211/phy0/morse/mmrc_table }}} * examine your link status (RSSI and MCS info): - AP: {{{#!bash iw dev wlan0 station dump }}} - STA: {{{#!bash iw dev wlan0 link }}} The rate control stats {{{/sys/kernel/debug/ieee80211/phy0/morse/mmrc_table}}} will provide statistics from the Morse S1G TX Rate rate control algorithm: - each line represents stats for a given channel bandwidth, guard band interval, and MCS index - the 'rate_sel' column uses the following definitions: * A : Highest throughput * B : 2nd highest throughput * C : baseline throughput * P : Maximum delivery probability * L : Used for additional lookarounds when traffic is very low Examining this tells you what MCS rate you are using; if it is not the highest then look at RF characteristics such as antenna, transmit strength, RSSI, and interference. Example: * Using 8MHz Short GI: {{{#!bash # cat /sys/kernel/debug/ieee80211/phy0/morse/mmrc_table | head -n4; cat /sys/kernel/debug/ieee80211/phy0/morse/mmrc_table | grep 8MHz | grep SGI Morse Micro S1G RC Algorithm Statistics: Peer 1c:bc:ec:33:56:4c bw guard evid rate_sel mcs#/ss index airtime TP(max) TP(avg) prob last_rty last_suc last_att tot_suc tot_att mpdu_suc mpdu_fail 8MHz SGI 0 C MCS0 /1 7 3165 0.00 0.00 0 0 0 0 0 0 0 0 8MHz SGI 0 MCS1 /1 15 2122 0.00 0.00 0 0 0 0 0 0 0 0 8MHz SGI 0 MCS2 /1 23 1582 0.00 0.00 0 0 0 0 0 0 0 0 8MHz SGI 0 MCS3 /1 31 1043 0.00 0.00 0 0 0 0 0 0 0 0 8MHz SGI 0 MCS4 /1 39 791 0.00 0.00 0 0 0 0 0 0 0 0 8MHz SGI 0 P MCS5 /1 47 503 0.00 0.00 0 0 0 0 0 0 0 0 8MHz SGI 0 B MCS6 /1 55 395 29.25 29.24 100 0 0 0 81 81 0 0 8MHz SGI 0 A L MCS7 /1 63 323 35.10 32.17 99 0 0 0 214300 218411 0 0 }}} - The above shows the majority of the packets are using MCS7, the highest rate. Gateworks Testing Results: * Infrastructure mode: ||= Channel BW =||= Channel =||= op_class =||= Freq =||= TCP (mbps) =||= UDP (mbps) || || 2MHz || 10 || 69 || 907Mhz || 6 || 6.8 || || 4MHz || 40 || 70 || 922Mhz || 10 || 12 || || 8MHz || 28 || 71 || 916MHz || 19 || 23 || == Transmit Power Gateworks does have the 5V power on the module, allowing up to 26.5dBm at specific frequencies, bandwidth and MCS rate as noted in the table below. [[Image(tx.png)]] == Range Testing HaLow is designed to be a long range wireless radio (several km) working in the Sub-1GHz frequency spectrum. The GW16159 uses the Silex SX-SDMAH module which uses the Morse Micro MM6108. Morse Micro has done some testing with the MM6108 at Joshua Tree National Park, which is close to ideal conditions, and they achieved an impressive 2 Mbps UDP throughput at 15.9km (approximately 10 miles). [https://www.morsemicro.com/2024/09/09/pushing-the-limits-wi-fi-halow-testing-in-joshua-tree-national-park/ reference]