Introduction
This guide describes how to configure and enable Automatic Channel Selection (ACS) using hostapd on the MediaTek MT320 platform running Linux under the mt76 driver architecture.
This guide was done using the Ezurio Tungsten 510 SMARC SOM platform. This came with the optional Sona MT320 m.2 1420 solder-down module with two MHF4L antenna ports (453-00176) installed. This guide will also work with the m.2 1420 RF trace variant (453-00177) or the m.2 2230 variant (453-00178) connected to a MediaTek EVK.
Requirements
- Tungsten510 SMARC with MT320 (T510_SMARC_SOM_8r16e_MT320_2M)
- Universal SMARC Carrier Board Kit (SMARC_CAR)
- Development PC with Yocto build environment
- Terminal Software to communicate with the SOM
- Wireless network to confirm ACS is working
- Wireless client to confirm that ACS is working
Initial Setup
Please follow this guide to setup the yocto environment and download the code and setup the environment: https://www.ezurio.com/documentation/yocto-scarthgap-v25-1-release-for-tungsten-platforms#section-4
Note: You can stop after you setup the environment for building
ACS Setup
What is ACS
Automatic Channel Selection (ACS) is a function inside of hostapd that will scan all the available channels in a given frequency band and pick the best channel to operate on.
How ACS works
When channel=0 or acs_num_scans is specified in hostapd.conf, hostapd requests channel survey data from the kernel via nl80211. It evaluates noise floor, channel busy time, and receive time across all allowed frequencies to calculate a channel interference matrix before selecting the optimal channel.
Building Yocto Image
Driver Changes
It is possible that hostapd may fail to complete the ACS scan sequence, cycling continuously with the following error:
ACS: Survey analysis failed
ACS: Failed to start
wlan0: Interface initialization failedThe upstream mt76 driver calculates noise floor data (SURVEY_INFO_NOISE_DBM) conditionally based on internal MAC status registers (state->noise). This may evaluate as false during background channel scanning for all the channels. When hostapd receives survey results missing the SURVEY_INFO_NOISE_DBM flag, it discards the channel evaluation data as invalid and ACS will fail.
To ensure hostapd consistently receives valid telemetry during the survey scan, we inject a fallback noise floor directly before the survey structure is committed back to the netlink interface.
Source Location
File: drivers/net/wireless/mediatek/mt76/mac80211.c
Function: mt76_get_survey()
Patch Modification
Apply the following fallback logic inside mac80211.c:
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -1002,6 +1002,10 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx,
survey->time_busy = div_u64(state->cc_busy, 1000);
survey->time_rx = div_u64(state->cc_rx, 1000);
survey->time = div_u64(state->cc_active, 1000);
+ /* Force fallback noise floor if driver fails to populate SURVEY_INFO_NOISE_DBM */
+ survey->noise = -95;
+ survey->filled |= SURVEY_INFO_NOISE_DBM;
spin_lock_bh(&dev->cc_lock);
survey->time_bss_rx = div_u64(state->cc_bss_rx, 1000);
survey->time_tx = div_u64(state->cc_tx, 1000);Yocto Build System Integration
To ensure this patch persists across clean builds, add it to your custom kernel meta-layer.
- Save the patch as 0001-mt76-mac80211-inject-fallback-acs-noise-floor.patch inside your kernel recipe directory: meta-your-custom-layer/recipes-kernel/linux/files/
- Append your local kernel recipe (linux-mtk_%.bbappend):
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += " \
file://0001-mt76-mac80211-inject-fallback-acs-noise-floor.patch \
"Now from this guide: https://www.ezurio.com/documentation/yocto-scarthgap-v25-1-release-for-tungsten-platforms#section-4 you can start at the section that starts "Finally, set the Tungsten MACHINE"... within the Build Procedure chapter.
Note: Replace MACHINE=tungsten-700-smarc with MACHINE = "tungsten-510-smarc"
Flashing the SOM
Once the image has finished building, you can follow these instructions to flash the image to your SOM:
Connect from your machine a serial-to-USB adapter to the "SERIAL" header and a USB-C cable to "J25" on the carrier board.
First you need to enter fastboot mode from U-Boot prompt:
=> fastboot 0If you are unable to get into fastboot mode from U-Boot, you can follow the this blog to recover your Tungsten platform.
Flash the images:
Flash bl2.img to mmc0boot0 partition:
~/Tungsten-Yocto$ fastboot flash mmc0boot0 bl2.imgFlash wic.img to mmc0 partition:
~/Tungsten-Yocto$ fastboot flash mmc0 rity-*-image-tungsten-*-smarc.wicNote: Ensure u-boot-tools or fastboot on the host PC has permission to write to mmc0. Replace the wildcard * with your specific build timestamp or image name.Verification and Testing
ACS Configuration
This is a basic configuration of hostapd with ACS. It is located in /etc/hostapd-acs.conf
# --- Basic Hardware Config ---
interface=wlan0
driver=nl80211
ssid=MT320-ACS-Test
hw_mode=a
#
# # --- The ACS Trigger ---
channel=0
#
# # --- Regulatory Setting ---
country_code=USStop background processes
systemctl stop NetworkManager wpa_supplicant connman 2>/dev/null
killall NetworkManager wpa_supplicant connman 2>/dev/null
# Cycle the interface to reset driver state
ip link set wlan0 down
ip link set wlan0 upLaunch hostapd
Launch hostapd in debug mode:
hostapd -B /etc/hostapd-acs.confNote: You can launch hostapd -dd /etc/hostapd-acs.conf (without -B) to watch the ACS channel survey calculation in real-time before daemonizing.Confirmation
Confirm successful completion by using the iw command:
root@tungsten-510-smarc:/etc# iw dev
phy#0
Interface wlan0
ifindex 4
wdev 0x1
addr e8:cb:f5:00:01:8e
ssid MT320-ACS-Test
type AP
channel 36 (5180 MHz), width: 20 MHz (no HT), center1: 5180 MHz
txpower 3.00 dBm
multicast TXQ:
qsz-byt qsz-pkt flows drops marks overlmt hashcol tx-bytes tx-packets
0 0 0 0 0 0 0 0 0
root@tungsten-510-smarc:/etc#/filters:background_color(white)/2024-03/Sona%20MT320%20Family%281%29.png)