| | 1 | [[PageOutline]] |
| | 2 | |
| | 3 | = GW16167 M.2 E-Key 802.11ah (!HaLow) radio |
| | 4 | |
| | 5 | [[Image(gw16159.jpg,300px)]] |
| | 6 | |
| | 7 | |
| | 8 | The GW16167 M.2 E-Key Sub-1GHz 802.11ah radio uses the !MorseMicro MM8108 chip. |
| | 9 | |
| | 10 | '''NOTE: The GW16167 requires an M.2 E-Key socket with USB. This may require an adapter for the Venice SBCs''' |
| | 11 | |
| | 12 | View the [https://www.gateworks.com/products/mini-pcie-expansion-cards/gw16159-802-11ah-halow-wifi-m2-card/ GW16167 Product Page] for pricing and specifications |
| | 13 | |
| | 14 | 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. |
| | 15 | |
| | 16 | The radio communicates over the USB bus |
| | 17 | |
| | 18 | Datasheets: |
| | 19 | * [https://www.morsemicro.com/resources/datasheets/modules/MM8108-MF15457_Data_Sheet.pdf MorseMicro MM8108 Datasheet] |
| | 20 | |
| | 21 | |
| | 22 | |
| | 23 | !WiFi Details: |
| | 24 | * !WiFi !HaLow 802.11ah 850-950MHz bands 1/2/4/8MHz channel width 26dBm max output power and 43.3Mbps theoretical maximum transmission rate |
| | 25 | |
| | 26 | |
| | 27 | Software Details: |
| | 28 | * Required software: |
| | 29 | * Out-of-tree kernel driver: https://github.com/Gateworks/morse_driver/tree/gateworks-venice (forked from https://github.com/MorseMicro/morse_driver.git) |
| | 30 | * Firmware: https://github.com/MorseMicro/morse-firmware.git |
| | 31 | * Required CLI app: https://github.com/MorseMicro/morse_cli.git |
| | 32 | * Custom version of hostapd/wpa_supplicant: https://github.com/MorseMicro/hostap |
| | 33 | |
| | 34 | == M.2 Pinout |
| | 35 | |
| | 36 | Gateworks follows the wider M.2 spec for E-Key signalling. |
| | 37 | |
| | 38 | M.2 Pin Details: |
| | 39 | * M2.2: 3.3VDC |
| | 40 | * M2.3: USB+ |
| | 41 | * M2.4: 3.3VDC |
| | 42 | * M2.5: USB- |
| | 43 | * M2.56: W_DISABLE1# routed to the RESET_N pin of the SX_SDMAH with a 200k pu to VDD_3P3 |
| | 44 | * M2.54: W_DISABLE2# routed to the WAKE pin of the SX_SDMAH with a 10k pu to VDD_3P3 |
| | 45 | * M2.72: 3.3VDC |
| | 46 | * M2.74: 3.3VDC |
| | 47 | * M.2 various pins GND, per M.2 E-Key Spec (such as 1,7, 33,39,45,51,57,63,69,75) |
| | 48 | |
| | 49 | |
| | 50 | == Antenna |
| | 51 | |
| | 52 | The antenna port is MMCX, 50 ohms impedance. |
| | 53 | |
| | 54 | The antenna type should be a rod and a +3.4dBi and 50 ohms impedance. |
| | 55 | |
| | 56 | To maintain the FCC cert from MorseMicro module, a certified antenna needs to be used. |
| | 57 | |
| | 58 | The certified antenna is a Kyocera X9000984-4GDSMB , Gateworks PN GW10156 |
| | 59 | * Sold here: [https://shop.gateworks.com/index.php?route=product/product&product_id=253&search=gw10156 Gateworks Shop] |
| | 60 | |
| | 61 | Note, a pigtail, MMCX to SMA will be needed with the above antenna. This is the [https://shop.gateworks.com/index.php?route=product/product&product_id=59&search=sma Gateworks GW10074 Pigtail Cable] |
| | 62 | |
| | 63 | == Certifications |
| | 64 | |
| | 65 | The MM8108-MF15457 from MorseMicro has modular certifications at the following: |
| | 66 | * FCC Part 15 |
| | 67 | |
| | 68 | Note, these certifications are only with the MorseMicro recommended antennas. |
| | 69 | |
| | 70 | 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. |
| | 71 | |
| | 72 | === Europe Use |
| | 73 | |
| | 74 | EU restrictions: |
| | 75 | * Channels: 1 MHz and 2 Mhz channels only |
| | 76 | * Duty cycle: 10% for AP, 2.8% for STA (measure over an hour). Can transmit for 360 seconds every hour as an AP, 100 seconds per hour as STA |
| | 77 | * Power: |
| | 78 | * 16.13 dBm EIRP for non audio video |
| | 79 | * 12 dBm EIRP without duty cycling requirement for certain audio & video applications (EU Decision 2022/180) |
| | 80 | |
| | 81 | Notes: |
| | 82 | 1. The firmware will try to spread transmissions out across the hour |
| | 83 | 2. There is a burst mode too that allows full throughput up to duty cycle. Caveat, on AP there is a slight reduction to allow for beacons across the hour |
| | 84 | 3. Setting the country code as EU or UK in firmware (config store), will impose these restrictions. A One time programmable fuse can also be set to ensure compliance. |
| | 85 | |
| | 86 | == Software |
| | 87 | |
| | 88 | === Pre-Built Software Images |
| | 89 | The mm8108 driver is supported in our latest pre-built images: |
| | 90 | * [https://dev.gateworks.com/venice/images/noble-venice.img.gz noble-venice.img.gz] (see [http://trac.gateworks.com/wiki/venice/firmware#disk-images compressed-disk-image]) |
| | 91 | * [https://dev.gateworks.com/venice/kernel/linux-venice.tar.xz linux-venice.tar.xz Kernel tarball] (see [http://trac.gateworks.com/wiki/linux/kernel#install kernel-tarball install]) |
| | 92 | * OpenWrt - See [#openwrt] |
| | 93 | |
| | 94 | === Driver |
| | 95 | The mm8108 on the GW16167 is supported by the open-source out-of-tree Linux kernel driver from !MorseMicro. This driver is included in the Gateworks Ubuntu pre-built images and the below instructions are only for if building is needed. |
| | 96 | |
| | 97 | Building with the Gateworks Venice BSP: |
| | 98 | 1. Add a 'custom_kernel_mm6108' script |
| | 99 | {{{#!bash |
| | 100 | cat <<\EOF > custom_kernel_mm6108 |
| | 101 | #!/bin/bash -e |
| | 102 | |
| | 103 | DIR=$PWD/mm610x |
| | 104 | OUTDIR=$DIR/out |
| | 105 | DESTDIR=$2 |
| | 106 | |
| | 107 | MORSE_VER=1.12.4 |
| | 108 | LIBNL_VER=libnl3_11_0 |
| | 109 | OPENSSL_VER=openssl-3.4.0 |
| | 110 | COUNTRY=US |
| | 111 | mkdir -p $DESTDIR/usr/sbin |
| | 112 | mkdir -p $DESTDIR/etc/modprobe.d |
| | 113 | mkdir -p $DIR |
| | 114 | cd $DIR |
| | 115 | |
| | 116 | # get repos of what we will build |
| | 117 | [ -d morse_driver ] || git clone --recurse-submodules https://github.com/Gateworks/morse_driver.git -b gateworks-venice |
| | 118 | [ -d libnl ] || git clone https://github.com/thom311/libnl.git -b $LIBNL_VER |
| | 119 | [ -d openssl ] || git clone https://github.com/openssl/openssl.git -b $OPENSSL_VER |
| | 120 | [ -d hostap ] || git clone https://github.com/MorseMicro/hostap.git -b $MORSE_VER |
| | 121 | [ -d morse_cli ] || git clone https://github.com/MorseMicro/morse_cli.git -b $MORSE_VER |
| | 122 | |
| | 123 | echo "Building mm6108 driver..." |
| | 124 | ARGS="KERNEL_SRC=$1 \ |
| | 125 | CONFIG_MORSE_SDIO=y \ |
| | 126 | CONFIG_MORSE_USER_ACCESS=y \ |
| | 127 | CONFIG_MORSE_VENDOR_COMMAND=y \ |
| | 128 | CONFIG_MORSE_SDIO_ALIGNMENT=4 \ |
| | 129 | CONFIG_MORSE_POWERSAVE_MODE=0 \ |
| | 130 | CONFIG_MORSE_COUNTRY=$COUNTRY \ |
| | 131 | CONFIG_MORSE_RC=y \ |
| | 132 | CONFIG_WLAN_VENDOR_MORSE=m" |
| | 133 | make -C morse_driver $ARGS |
| | 134 | make -C morse_driver $ARGS INSTALL_MOD_PATH=$2 modules_install |
| | 135 | |
| | 136 | # firmware: |
| | 137 | # - mm6108 firmware |
| | 138 | # - board configuration file (BCF) that provides driver with calibration constants and chip gpio config |
| | 139 | echo "Copying mm6108 firmware..." |
| | 140 | mkdir -p $2/lib/firmware/morse |
| | 141 | wget http://dev.gateworks.com/firmware/gw16159/mm6108.bin -O $2/lib/firmware/morse/mm6108.bin |
| | 142 | wget http://dev.gateworks.com/firmware/gw16159/LICENSE -O $2/lib/firmware/morse/LICENSE |
| | 143 | wget "http://dev.gateworks.com/firmware/gw16159/HY103760XB_SX-SDMAH-R2(US)_20240807_5V0.bin" -O $2/lib/firmware/morse/bcf_sxsdmah_fem5p0.bin |
| | 144 | |
| | 145 | [ -d $OUTDIR/include/libnl3 ] || { |
| | 146 | cd libnl |
| | 147 | ./autogen.sh |
| | 148 | ./configure --host=$ARCH CC=${CROSS_COMPILE}gcc --prefix=$OUTDIR --disable-shared |
| | 149 | make clean |
| | 150 | make -j32 |
| | 151 | make install |
| | 152 | cd .. |
| | 153 | } |
| | 154 | |
| | 155 | [ -d $OUTDIR/include/openssl ] || { |
| | 156 | cd openssl |
| | 157 | ./Configure linux-generic32 no-shared no-dso no-async -DL_ENDIAN --prefix=$OUTDIR --openssldir=$OUTDIR |
| | 158 | # needed no-async to build latest openssl against uclib |
| | 159 | make -j32 \ |
| | 160 | CC=${CROSS_COMPILE}gcc \ |
| | 161 | RANLIB=${CROSS_COMPILE}ranlib \ |
| | 162 | LD=${CROSS_COMPILE}ld \ |
| | 163 | MAKEDEPPROG=${CROSS_COMPILE}gcc \ |
| | 164 | PROCESSOR=ARM |
| | 165 | #make install # installs man pages too |
| | 166 | make install_sw |
| | 167 | cd .. |
| | 168 | } |
| | 169 | |
| | 170 | # wpa_supplicant |
| | 171 | [ -r hostap/wpa_supplicant/wpa_supplicant_s1g.bin ] || { |
| | 172 | cp hostap/wpa_supplicant/defconfig hostap/wpa_supplicant/.config |
| | 173 | make -C hostap/wpa_supplicant/ clean |
| | 174 | CFLAGS="-I $OUTDIR/include/libnl3 -I $OUTDIR/include" \ |
| | 175 | LDFLAGS="-L $OUTDIR/lib/ --static" \ |
| | 176 | DESTDIR="$OUTDIR/sbin" \ |
| | 177 | BINDIR=/usr/sbin \ |
| | 178 | LIBS="-lnl-3 -lm -lpthread -lcrypto -lssl" \ |
| | 179 | CC=${CROSS_COMPILE}gcc \ |
| | 180 | make -j32 -C hostap/wpa_supplicant/ CONFIG_MESH=y |
| | 181 | } |
| | 182 | cp hostap/wpa_supplicant/{wpa_supplicant_s1g,wpa_cli_s1g,wpa_passphrase_s1g} $DESTDIR/usr/sbin/ |
| | 183 | |
| | 184 | # hosapd |
| | 185 | [ -r hostap/hostapd/hostapd_s1g.bin ] || { |
| | 186 | cp hostap/hostapd/defconfig hostap/hostapd/.config |
| | 187 | make -C hostap/hostapd/ clean |
| | 188 | CFLAGS="-I $OUTDIR/include/libnl3 -I $OUTDIR/include" \ |
| | 189 | LDFLAGS="-L $OUTDIR/lib/ --static" \ |
| | 190 | DESTDIR="$OUTDIR/sbin" \ |
| | 191 | BINDIR=/usr/sbin \ |
| | 192 | LIBS="-lnl-3 -lm -lpthread -lcrypto -lssl" \ |
| | 193 | CC=${CROSS_COMPILE}gcc \ |
| | 194 | make -j32 -C hostap/hostapd/ |
| | 195 | } |
| | 196 | cp hostap/hostapd/{hostapd_s1g,hostapd_cli_s1g} $DESTDIR/usr/sbin/ |
| | 197 | |
| | 198 | # morse_cli |
| | 199 | [ -r morse_cli/morse_cli.bin ] || { |
| | 200 | make -C morse_cli clean |
| | 201 | CFLAGS="-I $OUTDIR/include/libnl3 -I $OUTDIR/include" \ |
| | 202 | LDFLAGS="-L $OUTDIR/lib/ --static" \ |
| | 203 | CC=${CROSS_COMPILE}gcc \ |
| | 204 | make \ |
| | 205 | CONFIG_MORSE_TRANS_NL80211=1 \ |
| | 206 | CONFIG_MORSE_STATIC=1 \ |
| | 207 | -j32 -C morse_cli |
| | 208 | } |
| | 209 | cp morse_cli/morse_cli $DESTDIR/usr/sbin/ |
| | 210 | |
| | 211 | # module parameters |
| | 212 | echo "options morse country=$COUNTRY enable_ext_xtal_init=1 bcf=bcf_sxsdmah_fem5p0.bin" > $DESTDIR/etc/modprobe.d/morse.conf |
| | 213 | EOF |
| | 214 | chmod +x custom_kernel_mm6108 |
| | 215 | }}} |
| | 216 | 3. rebuild the ubuntu-image: |
| | 217 | {{{#!bash |
| | 218 | source ./setup-environment |
| | 219 | make ubuntu-image |
| | 220 | }}} |
| | 221 | |
| | 222 | Module Parameters: |
| | 223 | - There are a number of module parameters supported by morse.ko however the required ones for the GW16167 are: |
| | 224 | * country=US |
| | 225 | * enable_ext_xtal_init=1 |
| | 226 | * bcf=bcf_sxsdmah_fem5p0.bin |
| | 227 | - These can be placed in /etc/modprobe..d such as: |
| | 228 | {{{#!bash |
| | 229 | echo "options morse country=US enable_ext_xtal_init=1 bcf=bcf_sxsdmah_fem5p0.bin" > /etc/modprobe.d/morse.conf |
| | 230 | }}} |
| | 231 | |
| | 232 | |
| | 233 | |
| | 234 | === hostapd and wpa_supplicant |
| | 235 | !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. |
| | 236 | |
| | 237 | |
| | 238 | === morse_cli |
| | 239 | 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. |
| | 240 | |
| | 241 | Examples: |
| | 242 | {{{#!bash |
| | 243 | # make sure interface is up |
| | 244 | ifconfig wlan0 up |
| | 245 | # morse_cli --interface=wlan0 hw_version |
| | 246 | HW Version: MM6108-A1 |
| | 247 | # morse_cli --interface=wlan0 version |
| | 248 | Morse_cli Version: rel_1_12_5_2024_Jul_25-4-g3541610 |
| | 249 | FW Version: rel_1_12_4_2024_Jun_11 |
| | 250 | # morse_cli channel |
| | 251 | Full Channel Information |
| | 252 | Operating Frequency: 916000 kHz |
| | 253 | Operating BW: 8 MHz |
| | 254 | Primary BW: 2 MHz |
| | 255 | Primary Channel Index: 0 |
| | 256 | }}} |
| | 257 | - note if not specified the interface defaults to wlan0 |
| | 258 | |
| | 259 | [=#kernel-patches] |
| | 260 | === Kernel Patches |
| | 261 | There is a small set of kernel patches from !MorseMicro which may improve the experience for 802.11ah for specific use cases. Gateworks has found these patches to be unnecessary for most use cases including AP, STA, and 802.11s MESH. These patches from !MorseMicro exist for several LTS kernels at https://github.com/MorseMicro/linux |
| | 262 | |
| | 263 | Here is an evaluation of the various patches for a 6.6 kernel: |
| | 264 | * [https://github.com/MorseMicro/linux/commit/69283c181040406bd9d594e47e38542343983f84 mac80211: implement support for thin LMAC S1G NDP block acknowledgements] |
| | 265 | - this is necessary if you are using the think LMAC firmware (which we have found no documentation on) |
| | 266 | * [https://github.com/MorseMicro/linux/commit/f948c7ac54c73e605791f576067cb11ce229e080 mac80211: Mesh support] |
| | 267 | - MESH improvements |
| | 268 | * [https://github.com/MorseMicro/linux/commit/3804ca8ec2675fbfe96c6f7fded7f91918d8887c mac80211: IBSS bridge support] |
| | 269 | - this is necessary if you are using the old IBSS/Adhoc mode in a bridge (not required for 802.11S MESH) |
| | 270 | * [https://github.com/MorseMicro/linux/commit/8d5f1b326eb7c6f4812894c2b362abc245dec949 mac80211: tx s1g AP ecsa support] |
| | 271 | - powersave enhancement |
| | 272 | * [https://github.com/MorseMicro/linux/commit/77cd2d08f1cec39e3c8b2fea734772a73ac89ca9 mac80211: mlme s1g ecsa support] |
| | 273 | - powersave enhancement |
| | 274 | |
| | 275 | A basic AP/station !HaLow network without powersave requirements or extended channel switch will function without these patches. |
| | 276 | |
| | 277 | It has been reported that with these kernel patches have not caused any noticeable obvious issues with other mac80211 radios |
| | 278 | |
| | 279 | |
| | 280 | |
| | 281 | |
| | 282 | [=#openwrt] |
| | 283 | === OpenWrt |
| | 284 | Support has been added for the GW16167 to the Gateworks OpenWrt packages for the 24.10 branch: |
| | 285 | * https://github.com/Gateworks/gw-openwrt-packages/tree/24.10/gateworks/gw16159 |
| | 286 | |
| | 287 | The morse_driver and morse-fw packages are required and included in the pre-built Gateworks OpenWrt image for venice: https://dev.gateworks.com/venice/images/openwrt-venice.img.gz |
| | 288 | |
| | 289 | OpenWrt will recognize the interface as a generic 5Ghz radio and allow you to configure it as an AP or a STA. OpenWrt does not understand that the channels map to the sub-1GHz band. The bandwidths will map as follows: |
| | 290 | - 20MHz = 1MHz sub-1G |
| | 291 | - 40MHz = 2MHz sub-1G |
| | 292 | - 80MHz = 4MHz sub-1G |
| | 293 | - 160MHz = 8MHz sub-1G |
| | 294 | |
| | 295 | Please note that !WiFi interfaces do not appear in /sys/class/net in OpenWrt. |
| | 296 | |
| | 297 | For testing !HaLow AP/STA/Mesh, Gateworks currently recommends avoiding the OpenWrt UCI layer for configuration of the interface, as it is not yet fully compatible with all features (i.e. WPA3 setup) out-of-the-box. Instead, a reliable approach is to have UCI not configure the !HaLow radio/interface, and manually set it up via the s1g tools (```wpa_supplicant_s1g```, ```hostapd_s1g```), explained in the [#configuration-(ap,-sta,-mesh) Configuration] section below. This route still allows for UCI / LuCI GUI to be used to configure other interfaces, bridges, etc. depending on your intended goal. |
| | 298 | |
| | 299 | {{{#!bash |
| | 300 | # Disable UCI’s wifi control for radio0 (gw16167) |
| | 301 | uci set wireless.radio0.disabled='1' |
| | 302 | uci commit wireless |
| | 303 | # Potentially setup firewall zones here |
| | 304 | |
| | 305 | # Setup interface manually |
| | 306 | # i.e. |
| | 307 | iw phy phy0 interface add wlan0 type managed |
| | 308 | ifconfig wlan0 up |
| | 309 | # For quick testing, allow incoming traffic |
| | 310 | /etc/init.d/firewall stop |
| | 311 | |
| | 312 | # Now bring up network with hostapd_s1g or wpa_supplicant_s1g |
| | 313 | }}} |
| | 314 | |
| | 315 | **Note**: By default, the OpenWrt firewall will block incoming data from wlan0 as /etc/config/firewall does not assign it into a zone. For testing, you can stop and disable the firewall, or configure it properly according to the [https://openwrt.org/docs/guide-user/firewall/firewall_configuration OpenWrt firewall documentation]. |
| | 316 | |
| | 317 | [=#channels] |
| | 318 | == Channel Mapping |
| | 319 | The !HaLow channels are mapped to standard 802.11 channels: |
| | 320 | * US |
| | 321 | ||= S1G Op Class =||= Global Op Class =||= Channel Bandwidth =||= Channel Number =||= Center Frequency =|| |
| | 322 | || 1 || 68 || 1 || 1 || 902.5 || |
| | 323 | || 1 || 68 || 1 || 3 || 903.5 || |
| | 324 | || 1 || 68 || 1 || 5 || 904.5 || |
| | 325 | || 1 || 68 || 1 || 7 || 905.5 || |
| | 326 | || 1 || 68 || 1 || 9 || 906.5 || |
| | 327 | || 1 || 68 || 1 || 11 || 907.5 || |
| | 328 | || 1 || 68 || 1 || 13 || 908.5 || |
| | 329 | || 1 || 68 || 1 || 15 || 909.5 || |
| | 330 | || 1 || 68 || 1 || 17 || 910.5 || |
| | 331 | || 1 || 68 || 1 || 19 || 911.5 || |
| | 332 | || 1 || 68 || 1 || 21 || 912.5 || |
| | 333 | || 1 || 68 || 1 || 23 || 913.5 || |
| | 334 | || 1 || 68 || 1 || 25 || 914.5 || |
| | 335 | || 1 || 68 || 1 || 27 || 915.5 || |
| | 336 | || 1 || 68 || 1 || 29 || 916.5 || |
| | 337 | || 1 || 68 || 1 || 31 || 917.5 || |
| | 338 | || 1 || 68 || 1 || 33 || 918.5 || |
| | 339 | || 1 || 68 || 1 || 35 || 919.5 || |
| | 340 | || 1 || 68 || 1 || 37 || 920.5 || |
| | 341 | || 1 || 68 || 1 || 39 || 921.5 || |
| | 342 | || 1 || 68 || 1 || 41 || 922.5 || |
| | 343 | || 1 || 68 || 1 || 43 || 923.5 || |
| | 344 | || 1 || 68 || 1 || 45 || 924.5 || |
| | 345 | || 1 || 68 || 1 || 47 || 925.5 || |
| | 346 | || 1 || 68 || 1 || 49 || 926.5 || |
| | 347 | || 1 || 68 || 1 || 51 || 927.5 || |
| | 348 | || 2 || 69 || 2 || 2 || 903.0 || |
| | 349 | || 2 || 69 || 2 || 6 || 905.0 || |
| | 350 | || 2 || 69 || 2 || 10 || 907.0 || |
| | 351 | || 2 || 69 || 2 || 14 || 909.0 || |
| | 352 | || 2 || 69 || 2 || 18 || 911.0 || |
| | 353 | || 2 || 69 || 2 || 22 || 913.0 || |
| | 354 | || 2 || 69 || 2 || 26 || 915.0 || |
| | 355 | || 2 || 69 || 2 || 30 || 917.0 || |
| | 356 | || 2 || 69 || 2 || 34 || 919.0 || |
| | 357 | || 2 || 69 || 2 || 38 || 921.0 || |
| | 358 | || 2 || 69 || 2 || 42 || 923.0 || |
| | 359 | || 2 || 69 || 2 || 46 || 925.0 || |
| | 360 | || 2 || 69 || 2 || 50 || 927.0 || |
| | 361 | || 2 || 70 || 4 || 8 || 906.0 || |
| | 362 | || 2 || 70 || 4 || 16 || 910.0 || |
| | 363 | || 2 || 70 || 4 || 24 || 914.0 || |
| | 364 | || 2 || 70 || 4 || 32 || 918.0 || |
| | 365 | || 2 || 70 || 4 || 40 || 922.0 || |
| | 366 | || 2 || 70 || 4 || 48 || 926.0 || |
| | 367 | || 2 || 71 || 8 || 12 || 908.0 || |
| | 368 | || 2 || 71 || 8 || 28 || 916.0 || |
| | 369 | || 2 || 71 || 8 || 44 || 924.0^^^1^^^ || |
| | 370 | 1. 924MHz is disabled in mm6108 firmware due to noise exceeding specification |
| | 371 | |
| | 372 | |
| | 373 | == Configuration (AP, STA, Mesh) |
| | 374 | The changes made by !MorseMicro to hostap add a number of parameters to hostapd.conf: |
| | 375 | * ieee80211ah: IEEE 802.11ah (S1G) supported |
| | 376 | * s1g_prim_chwidth: Sub-1 GHz primary channel bandwidth |
| | 377 | * s1g_prim_1mhz_chan_index: Sub-1 GHz primary 1MHz channel index |
| | 378 | * s1g_capab: S1G capabilities (list of flags) |
| | 379 | * s1g_traveling_pilots: Sub-1 Ghz traveling pilots |
| | 380 | * s1g_bss_color: Sub-1 GHz BSS color (0-7). |
| | 381 | * s1g_max_mpdu: Sub-1 GHz MPDU maximum length |
| | 382 | * s1g_ampdu: Sub-1 GHz A-MPDU support |
| | 383 | * s1g_max_ampdu_len_exp: Sub-1 GHz A-MPDU length exponent |
| | 384 | * s1g_basic_mcs_nss_set: Sub-1 GHz basic NSS/MCS support |
| | 385 | |
| | 386 | For documentation on these refer to the code: |
| | 387 | * [https://github.com/MorseMicro/hostap/blob/v1.14/hostapd/hostapd_s1g.conf hostapd_s1g.conf] |
| | 388 | * [https://github.com/MorseMicro/hostap/blob/v1.14/hostapd_s1g_configuration.md hostapd_s1g_configuration] |
| | 389 | |
| | 390 | |
| | 391 | Below are examples for configuring WPA2/WPA3 AP + STA, along with WPA3 Mesh. |
| | 392 | |
| | 393 | === AP & STA |
| | 394 | * Infrastructure mode using WPA2: |
| | 395 | - AP: |
| | 396 | {{{#!bash |
| | 397 | cat << EOF > hostapd_s1g_wpa2.conf |
| | 398 | interface=wlan0 |
| | 399 | logger_syslog=-1 |
| | 400 | logger_syslog_level=2 |
| | 401 | logger_stdout=-1 |
| | 402 | logger_stdout_level=2 |
| | 403 | ctrl_interface=/var/run/hostapd |
| | 404 | ctrl_interface_group=0 |
| | 405 | ssid=HaLow-WPA2 |
| | 406 | country_code=US |
| | 407 | hw_mode=a |
| | 408 | beacon_int=100 |
| | 409 | dtim_period=2 |
| | 410 | max_num_sta=255 |
| | 411 | rts_threshold=-1 |
| | 412 | fragm_threshold=-1 |
| | 413 | macaddr_acl=0 |
| | 414 | auth_algs=3 |
| | 415 | ignore_broadcast_ssid=0 |
| | 416 | wmm_enabled=1 |
| | 417 | wmm_ac_bk_cwmin=4 |
| | 418 | wmm_ac_bk_cwmax=10 |
| | 419 | wmm_ac_bk_aifs=7 |
| | 420 | wmm_ac_bk_txop_limit=0 |
| | 421 | wmm_ac_bk_acm=0 |
| | 422 | wmm_ac_be_aifs=3 |
| | 423 | wmm_ac_be_cwmin=4 |
| | 424 | wmm_ac_be_cwmax=10 |
| | 425 | wmm_ac_be_txop_limit=0 |
| | 426 | wmm_ac_be_acm=0 |
| | 427 | wmm_ac_vi_aifs=2 |
| | 428 | wmm_ac_vi_cwmin=3 |
| | 429 | wmm_ac_vi_cwmax=4 |
| | 430 | wmm_ac_vi_txop_limit=94 |
| | 431 | wmm_ac_vi_acm=0 |
| | 432 | wmm_ac_vo_aifs=2 |
| | 433 | wmm_ac_vo_cwmin=2 |
| | 434 | wmm_ac_vo_cwmax=3 |
| | 435 | wmm_ac_vo_txop_limit=47 |
| | 436 | wmm_ac_vo_acm=0 |
| | 437 | ieee80211ah=1 |
| | 438 | s1g_prim_chwidth=1 |
| | 439 | s1g_prim_1mhz_chan_index=0 |
| | 440 | s1g_capab=[SHORT-GI-ALL] |
| | 441 | eapol_key_index_workaround=0 |
| | 442 | own_ip_addr=127.0.0.1 |
| | 443 | #918.5MHz@1 |
| | 444 | #channel=33 |
| | 445 | #op_class=68 |
| | 446 | #907MHz@2 |
| | 447 | #channel=10 |
| | 448 | #op_class=69 |
| | 449 | #922Mhz@4 |
| | 450 | #channel=40 |
| | 451 | #op_class=70 |
| | 452 | #916MHz@8 |
| | 453 | channel=28 |
| | 454 | op_class=71 |
| | 455 | # WPA2 security |
| | 456 | wpa=2 |
| | 457 | wpa_passphrase=strongpassword123 |
| | 458 | wpa_key_mgmt=WPA-PSK |
| | 459 | wpa_pairwise=TKIP |
| | 460 | rsn_pairwise=CCMP |
| | 461 | EOF |
| | 462 | hostapd_s1g ./hostapd_s1g_wpa2.conf -B |
| | 463 | ifconfig wlan0 192.168.1.1 |
| | 464 | iperf3 -s |
| | 465 | }}} |
| | 466 | * STA: |
| | 467 | {{{#!bash |
| | 468 | #wpa_passphrase generates WPA2 wpa_supplicant configuration |
| | 469 | wpa_passphrase_s1g HaLow-WPA2 strongpassword123 > wpa_supplicant_s1g.conf |
| | 470 | #ensure wlan0 interface is up |
| | 471 | ifconfig wlan0 up |
| | 472 | #Start wpa_supplicant_s1g, send to background (replace & with -d for debug) |
| | 473 | wpa_supplicant_s1g -i wlan0 -c ./wpa_supplicant_s1g.conf & |
| | 474 | #assign static IP; DHCP is not part of this example |
| | 475 | ifconfig wlan0 192.168.1.128 |
| | 476 | iperf3 -c 192.168.1.1 |
| | 477 | }}} |
| | 478 | |
| | 479 | * Infrastructure mode using WPA3: |
| | 480 | * AP: |
| | 481 | {{{#!bash |
| | 482 | cat << EOF > hostapd_s1g_wpa3.conf |
| | 483 | interface=wlan0 |
| | 484 | logger_syslog=-1 |
| | 485 | logger_syslog_level=2 |
| | 486 | logger_stdout=-1 |
| | 487 | logger_stdout_level=2 |
| | 488 | ctrl_interface=/var/run/hostapd |
| | 489 | ctrl_interface_group=0 |
| | 490 | ssid=HaLow-WPA3 |
| | 491 | country_code=US |
| | 492 | hw_mode=a |
| | 493 | beacon_int=100 |
| | 494 | dtim_period=2 |
| | 495 | max_num_sta=255 |
| | 496 | rts_threshold=-1 |
| | 497 | fragm_threshold=-1 |
| | 498 | macaddr_acl=0 |
| | 499 | auth_algs=3 |
| | 500 | ignore_broadcast_ssid=0 |
| | 501 | wmm_enabled=1 |
| | 502 | wmm_ac_bk_cwmin=4 |
| | 503 | wmm_ac_bk_cwmax=10 |
| | 504 | wmm_ac_bk_aifs=7 |
| | 505 | wmm_ac_bk_txop_limit=0 |
| | 506 | wmm_ac_bk_acm=0 |
| | 507 | wmm_ac_be_aifs=3 |
| | 508 | wmm_ac_be_cwmin=4 |
| | 509 | wmm_ac_be_cwmax=10 |
| | 510 | wmm_ac_be_txop_limit=0 |
| | 511 | wmm_ac_be_acm=0 |
| | 512 | wmm_ac_vi_aifs=2 |
| | 513 | wmm_ac_vi_cwmin=3 |
| | 514 | wmm_ac_vi_cwmax=4 |
| | 515 | wmm_ac_vi_txop_limit=94 |
| | 516 | wmm_ac_vi_acm=0 |
| | 517 | wmm_ac_vo_aifs=2 |
| | 518 | wmm_ac_vo_cwmin=2 |
| | 519 | wmm_ac_vo_cwmax=3 |
| | 520 | wmm_ac_vo_txop_limit=47 |
| | 521 | wmm_ac_vo_acm=0 |
| | 522 | ieee80211ah=1 |
| | 523 | s1g_prim_chwidth=1 |
| | 524 | s1g_prim_1mhz_chan_index=0 |
| | 525 | s1g_capab=[SHORT-GI-ALL] |
| | 526 | eapol_key_index_workaround=0 |
| | 527 | own_ip_addr=127.0.0.1 |
| | 528 | channel=28 |
| | 529 | op_class=71 |
| | 530 | #WPA3 / SAE configuration |
| | 531 | wpa=2 |
| | 532 | wpa_key_mgmt=SAE |
| | 533 | ieee80211w=2 |
| | 534 | sae_pwe=2 |
| | 535 | rsn_pairwise=CCMP |
| | 536 | sae_password=HalowDemo123 |
| | 537 | EOF |
| | 538 | #Start the AP with configuration in background. |
| | 539 | #For quick (foreground) debugging, remove the -B flag |
| | 540 | hostapd_s1g ./hostapd_s1g_wpa3.conf -B |
| | 541 | #Configure static IP |
| | 542 | ifconfig wlan0 192.168.1.1 |
| | 543 | #Start iperf3 server for connection testing |
| | 544 | iperf3 -s |
| | 545 | }}} |
| | 546 | * STA: |
| | 547 | {{{#!bash |
| | 548 | #wpa_passphrase_s1g is only to create WPA2 configurations; create conf manually |
| | 549 | cat << EOF > wpa_supplicant_s1g_wpa3.conf |
| | 550 | update_config=1 |
| | 551 | |
| | 552 | pmf=2 |
| | 553 | sae_pwe=1 |
| | 554 | network={ |
| | 555 | ssid="HaLow-WPA3" |
| | 556 | key_mgmt=SAE |
| | 557 | pairwise=CCMP |
| | 558 | psk="strongpassword123" |
| | 559 | } |
| | 560 | EOF |
| | 561 | |
| | 562 | #Ensure interface is up |
| | 563 | ifconfig wlan0 up |
| | 564 | #Start wpa_supplicant_s1g, send to background (replace & with -d for debug) |
| | 565 | wpa_supplicant_s1g -i wlan0 -c ./wpa_supplicant_s1g_wpa3.conf & |
| | 566 | #Configure static IP, as dhcp is not present in example. |
| | 567 | ifconfig wlan0 192.168.1.128 |
| | 568 | iperf3 -c 192.168.1.1 |
| | 569 | }}} |
| | 570 | |
| | 571 | === Mesh |
| | 572 | * 802.11s Mesh using WPA3: |
| | 573 | {{{#!bash |
| | 574 | cat << EOF > wpa_supplicant_s1g.conf |
| | 575 | country=US |
| | 576 | ctrl_interface=/var/run/wpa_supplicant_s1g |
| | 577 | sae_pwe=1 |
| | 578 | |
| | 579 | max_peer_links=10 |
| | 580 | mesh_fwding=1 |
| | 581 | network={ |
| | 582 | ssid="HaLow-WPA3-Mesh" |
| | 583 | key_mgmt=SAE |
| | 584 | mode=5 |
| | 585 | # 8MHz width at 916MHz |
| | 586 | channel=28 |
| | 587 | op_class=71 |
| | 588 | country="US" |
| | 589 | s1g_prim_chwidth=1 |
| | 590 | s1g_prim_1mhz_chan_index=3 |
| | 591 | mesh_rssi_threshold=-85 |
| | 592 | sae_password="strongpassword123" |
| | 593 | pairwise=CCMP |
| | 594 | ieee80211w=2 |
| | 595 | beacon_int=1000 |
| | 596 | } |
| | 597 | EOF |
| | 598 | ifconfig wlan0 up |
| | 599 | wpa_supplicant_s1g -iwlan0 -c wpa_supplicant_s1g.conf & |
| | 600 | }}} |
| | 601 | |
| | 602 | * Note: wpa_supplicant_s1g automatically configures the interface type from 'managed' to 'mesh point' when configured for mesh. It is cleaner practice and recommended for production systems, to setup the interface as a mesh point explicitly. |
| | 603 | {{{#!bash |
| | 604 | #optional: delete wlan0 interface |
| | 605 | iw dev wlan0 del |
| | 606 | iw phy phy0 interface add mesh0 type mp |
| | 607 | |
| | 608 | #morse_cli sanity check |
| | 609 | #morse_cli requires interface to talk to the driver; ensure interface is up |
| | 610 | ifconfig mesh0 up |
| | 611 | #morse_cli defaults to wlan0, so to use it we need to manually state -i mesh0 |
| | 612 | morse_cli -i mesh0 version |
| | 613 | }}} |
| | 614 | |
| | 615 | |
| | 616 | More information on mesh and 802.11s can be found on our [https://trac.gateworks.com/wiki/wireless/wifi/mesh mesh networks] wiki page. |
| | 617 | |
| | 618 | [=#performance] |
| | 619 | == Performance |
| | 620 | The MM8108 supports: |
| | 621 | * Spacial Streams: 1 |
| | 622 | * Channel bandwidths: 1/2/4/8 MHz |
| | 623 | * Modulation and Coding Schemes: MCS 0-9 (1/2/4/8 Mhz); MCS 10 (1Mhz only) |
| | 624 | * Data rates up to 43.3Mbps (MCS 9, 64-QAM, 8 Mhz channel, 4 us GI) |
| | 625 | |
| | 626 | 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. |
| | 627 | |
| | 628 | 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: |
| | 629 | - 1 MHz: 24 data subcarriers. |
| | 630 | - 2 MHz: 52 data subcarriers. |
| | 631 | - 4 MHz: 108 data subcarriers. |
| | 632 | - 8 MHz: 234 data subcarriers. |
| | 633 | |
| | 634 | The PHY rate is calculated as: PHY Rate = (Number of Data Subcarriers) × (Bits per Subcarrier) × (Coding Rate) × (Symbols per Second) × (Number of Spatial Streams): |
| | 635 | - Data Subcarriers: |
| | 636 | * 1 MHz: 24 data subcarriers. |
| | 637 | * 2 MHz: 52 data subcarriers. |
| | 638 | * 4 MHz: 108 data subcarriers. |
| | 639 | * 8 MHz: 234 data subcarriers. |
| | 640 | - Bits per Subcarier and Coding Rate: Depends on MCS index |
| | 641 | - Symbols per Second: |
| | 642 | * Long GI (8us): 4 us data + 4 us GI: 125,000 symbols/s |
| | 643 | * Short GI (4us): 4 us data + 0 us GI: 250,000 symbols/s |
| | 644 | - Spatial Streams: 1 (common for IoT devices). |
| | 645 | |
| | 646 | |
| | 647 | |
| | 648 | |
| | 649 | 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. |
| | 650 | |
| | 651 | Actual throughput will be less taking into account overhead, congestion, and RF factors. To examine your link you can use the following: |
| | 652 | * examine the rate control stats: |
| | 653 | {{{#!bash |
| | 654 | cat /sys/kernel/debug/ieee80211/phy0/morse/mmrc_table |
| | 655 | }}} |
| | 656 | * examine your link status (RSSI and MCS info): |
| | 657 | - AP: |
| | 658 | {{{#!bash |
| | 659 | iw dev wlan0 station dump |
| | 660 | }}} |
| | 661 | - STA: |
| | 662 | {{{#!bash |
| | 663 | iw dev wlan0 link |
| | 664 | }}} |
| | 665 | |
| | 666 | The rate control stats {{{/sys/kernel/debug/ieee80211/phy0/morse/mmrc_table}}} will provide statistics from the Morse S1G TX Rate rate control algorithm: |
| | 667 | - each line represents stats for a given channel bandwidth, guard band interval, and MCS index |
| | 668 | - the 'rate_sel' column uses the following definitions: |
| | 669 | * A : Highest throughput |
| | 670 | * B : 2nd highest throughput |
| | 671 | * C : baseline throughput |
| | 672 | * P : Maximum delivery probability |
| | 673 | * L : Used for additional lookarounds when traffic is very low |
| | 674 | |
| | 675 | 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. |
| | 676 | |
| | 677 | |
| | 678 | |
| | 679 | == Transmit Power |
| | 680 | |
| | 681 | It allows up to 26dBm at specific frequencies, bandwidth and MCS rate as noted in the table below. |
| | 682 | |
| | 683 | |
| | 684 | |