Tutorial to setup mlo/mld for wifi 7 be cards in openwrt

Hi, is there turotial how to setup MLO/MLD in latest opnewrt trunk if there is one wifi card phy0 with two diff band’s?

via gui,uci or manual:-)
some hints to do it my self?
thnx

Isn't this the same question as the one you posted 4 mo ago in Setting up MLO/MLD ends up in " Name not unique on network" ?

I think it’s a valid question. I have a Banana Pi BPI-R4 that I would like how to configure to use MLO. The snippet I could find to enable it, just crash the 2.4 and 6GHz networks.

So a how-to to enable since now it’s getting support in the main branch, would be nice.

1 Like

So does openwrt supports MLO configuration for any Wifi 7 ax card(s)?

I'm trying to set up an MLO AP using two MT7925E cards.
However, hostapd outputs MLD: Not supported by the driver and it doesn't work properly.
Is it possible to perform MLO using two MT7925E cards?

root@OpenWrt:~# cat /etc/config/wireless 

config wifi-device 'radio0'
	option type 'mac80211'
	option path 'a40000000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0'
	option band '6g'
	option channel '1'
	option htmode 'EHT160'
	option country 'JP'
	option cell_density '0'

config wifi-device 'radio1'
	option type 'mac80211'
	option path 'a40400000.pcie/pci0001:10/0001:10:00.0/0001:11:00.0'
	option band '6g'
	option channel '33'
	option htmode 'EHT160'
	option country 'JP'
	option cell_density '0'

config wifi-iface 'default_mlo'
	list device 'radio0'
	list device 'radio1'
	option network 'lan'
	option mode 'ap'
	option ssid 'OpenWrt-MLO'
	option encryption 'sae'
	option key 'OpenWrt-MLO'
	option ocv '0'
	option mlo '1'

root@OpenWrt:~# logread | grep hostapd
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Set MLD config: [ "ap-mld0" ]
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Add MLD interface ap-mld0
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Reload all interfaces
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Set new config for phy phy1:
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Remove MLD interface ap-mld0
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Set new config for phy phy1: /var/run/hostapd-phy1.conf
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Create MLD interface ap-mld0 on phy phy1, radio mask: 0
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Restart interface for phy phy1
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Configuration file: <inline> (phy phy1) --> new PHY
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Configuration file: Reading configuration file '<inline>'
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Enabling beacon protection as IEEE 802.11be is enabled for this BSS
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Configuration file: Reading configuration file '<inline>'
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Enabling beacon protection as IEEE 802.11be is enabled for this BSS
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: MLD: Not supported by the driver
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: nl80211: deinit ifname=ap-mld0 disabled_11b_rates=0
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: ap-mld0: CTRL-EVENT-TERMINATING
Fri Oct  3 02:50:09 2025 daemon.err hostapd: hostapd_free_hapd_data: Interface ap-mld0 wasn't started
Fri Oct  3 02:50:09 2025 daemon.err hostapd: rmdir[ctrl_interface=/var/run/hostapd]: Permission denied
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: hostapd.add_iface failed for phy phy1 ifname=ap-mld0
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Set new config for phy phy2:
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Set new config for phy phy2: /var/run/hostapd-phy2.conf
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Restart interface for phy phy2
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Configuration file: <inline> (phy phy2) --> new PHY
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Configuration file: Reading configuration file '<inline>'
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Enabling beacon protection as IEEE 802.11be is enabled for this BSS
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Configuration file: Reading configuration file '<inline>'
Fri Oct  3 02:50:09 2025 daemon.notice hostapd: Enabling beacon protection as IEEE 802.11be is enabled for this BSS
Fri Oct  3 02:50:10 2025 daemon.notice hostapd: MLD: Not supported by the driver
Fri Oct  3 02:50:10 2025 daemon.notice hostapd: nl80211: deinit ifname=ap-mld0 disabled_11b_rates=0
Fri Oct  3 02:50:10 2025 daemon.notice hostapd: ap-mld0: CTRL-EVENT-TERMINATING
Fri Oct  3 02:50:10 2025 daemon.err hostapd: hostapd_free_hapd_data: Interface ap-mld0 wasn't started
Fri Oct  3 02:50:10 2025 daemon.err hostapd: rmdir[ctrl_interface=/var/run/hostapd]: Permission denied
Fri Oct  3 02:50:10 2025 daemon.notice hostapd: hostapd.add_iface failed for phy phy2 ifname=ap-mld0

I also got the same output for the ath12k driver…

The kmod-mt7925-firmware version (20231227093232) may be too old to support MLO.

Firmware versions 20250526152947a and later seem to include something for MLO, but this leads to a kernel oops.

[   15.306695] ------------[ cut here ]------------
[   15.307108] WARNING: CPU: 4 PID: 1221 at target-aarch64_generic_musl/linux-rockchip_armv8/mt76-2025.11.06~eb567bc7/mt7925/mcu.c:1345 mt7925_mcu_set_mlo_roc+0x280/0x2bc [mt7925_common]
[   15.308535] Modules linked in: rtw89_8852be(O) rtw89_8852b(O) rtw89_8852b_common(O) pppoe ppp_async nft_fib_inet nf_flow_table_inet mt7925e(O) mt7925_common(O) rtw89_pci(O) rtw89_core(O) pppox ppp_generic nft_reject_ipv6 nft_reject_ipv4 nft_reject_inet nft_reject nft_redir nft_quota nft_numgen nft_nat nft_masq nft_log nft_limit nft_hash nft_flow_offload nft_fib_ipv6 nft_fib_ipv4 nft_fib nft_ct nft_chain_nat nf_tables nf_nat nf_flow_table nf_conntrack mt792x_lib(O) mt76_connac_lib(O) mt76(O) mac80211(O) cfg80211(O) slhc nfnetlink nf_reject_ipv6 nf_reject_ipv4 nf_log_syslog nf_defrag_ipv6 nf_defrag_ipv4 crc_ccitt compat(O) pwm_fan sha512_generic sha512_arm64 seqiv sha3_generic jitterentropy_rng drbg hmac geniv rng cmac r8169 ahci libahci libata gpio_button_hotplug(O)
[   15.314492] CPU: 4 UID: 101 PID: 1221 Comm: hostapd Tainted: G           O       6.12.57 #0
[   15.315221] Tainted: [O]=OOT_MODULE
[   15.315527] Hardware name: Radxa ROCK 5 ITX (DT)
[   15.315929] pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   15.316537] pc : mt7925_mcu_set_mlo_roc+0x280/0x2bc [mt7925_common]
[   15.317085] lr : mt7925_mcu_set_mlo_roc+0x78/0x2bc [mt7925_common]
[   15.317624] sp : ffff8000859ab270
[   15.317914] x29: ffff8000859ab270 x28: ffff000108c89080 x27: ffff0001087ca140
[   15.318538] x26: ffff8000859ab440 x25: ffff000103e4ba80 x24: 0000000000000001
[   15.319163] x23: 0000000000000005 x22: ffff0001087c9b98 x21: ffff0001087ca040
[   15.319786] x20: ffff8000859ab2d8 x19: 0000000000000003 x18: 00000000ffffffff
[   15.320409] x17: 000000040044ffff x16: 000000b2b5503510 x15: 0000000000000000
[   15.321032] x14: ffff00010086ac40 x13: ffff000101294a80 x12: 000000003464d91d
[   15.321655] x11: 00000000000000c0 x10: 0000000000000940 x9 : ffff8000859ab0d0
[   15.322279] x8 : 0000000000000003 x7 : 0000000000000003 x6 : ffff0001087ca040
[   15.322902] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
[   15.323525] x2 : 0000000000000001 x1 : ffff8000859ab2f0 x0 : 0000000000000001
[   15.324148] Call trace:
[   15.324361]  mt7925_mcu_set_mlo_roc+0x280/0x2bc [mt7925_common]
[   15.324879]  mt7925_roc_abort_sync+0x9ac/0x27c0 [mt7925_common]
[   15.325398]  mt7925_mac_sta_event+0xa84/0x11bc [mt7925_common]
[   15.325908]  drv_change_vif_links+0xc4/0x1a8 [mac80211]
[   15.326380]  ieee80211_link_stop+0x630/0x7c0 [mac80211]
[   15.326848]  ieee80211_vif_set_links+0x20/0x50 [mac80211]
[   15.327331]  ieee80211_obss_color_collision_notify+0x16c4/0x1be8 [mac80211]
[   15.327949]  __cfg80211_send_event_skb+0x2550/0x25a0 [cfg80211]
[   15.328473]  genl_family_rcv_msg_doit+0xb0/0x120
[   15.328883]  genl_rcv_msg+0x1b8/0x250
[   15.329207]  netlink_rcv_skb+0x60/0x130
[   15.329545]  genl_rcv+0x38/0x50
[   15.329823]  netlink_unicast+0x20c/0x304
[   15.330169]  netlink_sendmsg+0x174/0x37c
[   15.330515]  ____sys_sendmsg+0x1cc/0x27c
[   15.330862]  ___sys_sendmsg+0x80/0xc8
[   15.331185]  __sys_sendmsg+0x48/0xb0
[   15.331502]  __arm64_sys_sendmsg+0x24/0x30
[   15.331862]  invoke_syscall.constprop.0+0x50/0xe0
[   15.332276]  do_el0_svc+0x40/0xe0
[   15.332569]  el0_svc+0x30/0x134
[   15.332847]  el0t_64_sync_handler+0x120/0x12c
[   15.333229]  el0t_64_sync+0x178/0x17c
[   15.333549] ---[ end trace 0000000000000000 ]---

what is youl MLO openwrt config or even hostpad configs from filesystem? can you share?

openwrt config: Tutorial to setup mlo/mld for wifi 7 be cards in openwrt - #5 by RadxaNaoki

hostapd config:

root@OpenWrt:~# ls /run/
config.md5            hostapd-ap-mld0.psk   run
dnsmasq               hostapd-ap-mld0.vlan  ubus
dropbear.main.pid     hostapd-phy0.conf     udhcpc-br-lan.pid
fw4.lock              hostapd-phy1.conf     wdev-phy0.json
fw4.state             lock                  wdev-phy1.json
hostapd               rpcd                  wpa_supplicant

root@OpenWrt:~# cat /run/hostapd-phy0.conf 
driver=nl80211
logger_syslog=127
logger_syslog_level=2
logger_stdout=127
logger_stdout_level=2
country_code=JP
ieee80211h=1
ieee80211d=1
spectrum_mgmt_required=0
beacon_int=100
noscan=0
rssi_reject_assoc_rssi=0
rssi_ignore_probe_request=0
acs_exclude_dfs=0
min_tx_power=0
hw_mode=a
channel=1
op_class=134
he_bss_color=128
he_spr_sr_control=3
ieee80211ax=1
he_oper_chwidth=2
he_oper_centr_freq_seg0_idx=15
he_su_beamformer=0
he_su_beamformee=0
he_mu_beamformer=0
he_twt_required=0
he_default_pe_duration=4
he_rts_threshold=1023
he_mu_edca_qos_info_param_count=0
he_mu_edca_qos_info_q_ack=0
he_mu_edca_qos_info_queue_request=0
he_mu_edca_qos_info_txop_request=0
he_mu_edca_ac_be_aifsn=8
he_mu_edca_ac_be_aci=0
he_mu_edca_ac_be_ecwmin=9
he_mu_edca_ac_be_ecwmax=10
he_mu_edca_ac_be_timer=255
he_mu_edca_ac_bk_aifsn=15
he_mu_edca_ac_bk_aci=1
he_mu_edca_ac_bk_ecwmin=9
he_mu_edca_ac_bk_ecwmax=10
he_mu_edca_ac_bk_timer=255
he_mu_edca_ac_vi_ecwmin=5
he_mu_edca_ac_vi_ecwmax=7
he_mu_edca_ac_vi_aifsn=5
he_mu_edca_ac_vi_aci=2
he_mu_edca_ac_vi_timer=255
he_mu_edca_ac_vo_aifsn=5
he_mu_edca_ac_vo_aci=3
he_mu_edca_ac_vo_ecwmin=5
he_mu_edca_ac_vo_ecwmax=7
he_mu_edca_ac_vo_timer=255
ieee80211be=1
eht_oper_chwidth=2
eht_oper_centr_freq_seg0_idx=15
he_6ghz_reg_pwr_type=0
stationary_ap=1
mbssid=0

#num_global_macaddr=1

# Setup interface: ap-mld0
interface=ap-mld0
bssid=c0:bf:be:05:fa:b0
ssid2="OpenWrt-MLO"
ctrl_interface=/var/run/hostapd
ap_isolate=0
bss_load_update_period=60
chan_util_avg_period=600
disassoc_low_ack=1
skip_inactivity_poll=0
ignore_broadcast_ssid=0
uapsd_advertisement_enabled=1
utf8_ssid=1
bridge=br-lan
snoop_iface=br-lan
ocv=0
preamble=1
qos_map_set=0,0,2,16,1,1,255,255,18,22,24,38,40,40,44,46,48,56
dtim_period=2
wmm_enabled=1
sae_require_mfp=1
sae_pwe=2
wpa_passphrase=OpenWrt-MLO
wpa_psk_file=/var/run/hostapd-ap-mld0.psk
dynamic_vlan=0
wpa_disable_eapol_key_retries=0
wpa=2
wpa_pairwise=CCMP
rrm_neighbor_report=1
rrm_beacon_report=1
rnr=1
vlan_file=/var/run/hostapd-ap-mld0.vlan
ieee80211w=2
group_mgmt_cipher=AES-128-CMAC
okc=1
wpa_key_mgmt=SAE
rsn_override_key_mgmt=SAE
rsn_override_pairwise=GCMP-256 CCMP
rsn_override_mfp=2
rsn_override_key_mgmt_2=SAE
rsn_override_pairwise_2=GCMP-256 CCMP
rsn_override_mfp_2=2
mld_ap=1
mld_link_id=-1
#default_macaddr

root@OpenWrt:~# cat /run/hostapd-phy1.conf 
driver=nl80211
logger_syslog=127
logger_syslog_level=2
logger_stdout=127
logger_stdout_level=2
country_code=JP
ieee80211h=1
ieee80211d=1
spectrum_mgmt_required=0
beacon_int=100
noscan=0
rssi_reject_assoc_rssi=0
rssi_ignore_probe_request=0
acs_exclude_dfs=0
min_tx_power=0
hw_mode=a
channel=33
op_class=134
he_bss_color=128
he_spr_sr_control=3
ieee80211ax=1
he_oper_chwidth=2
he_oper_centr_freq_seg0_idx=47
he_su_beamformer=0
he_su_beamformee=0
he_mu_beamformer=0
he_twt_required=0
he_default_pe_duration=4
he_rts_threshold=1023
he_mu_edca_qos_info_param_count=0
he_mu_edca_qos_info_q_ack=0
he_mu_edca_qos_info_queue_request=0
he_mu_edca_qos_info_txop_request=0
he_mu_edca_ac_be_aifsn=8
he_mu_edca_ac_be_aci=0
he_mu_edca_ac_be_ecwmin=9
he_mu_edca_ac_be_ecwmax=10
he_mu_edca_ac_be_timer=255
he_mu_edca_ac_bk_aifsn=15
he_mu_edca_ac_bk_aci=1
he_mu_edca_ac_bk_ecwmin=9
he_mu_edca_ac_bk_ecwmax=10
he_mu_edca_ac_bk_timer=255
he_mu_edca_ac_vi_ecwmin=5
he_mu_edca_ac_vi_ecwmax=7
he_mu_edca_ac_vi_aifsn=5
he_mu_edca_ac_vi_aci=2
he_mu_edca_ac_vi_timer=255
he_mu_edca_ac_vo_aifsn=5
he_mu_edca_ac_vo_aci=3
he_mu_edca_ac_vo_ecwmin=5
he_mu_edca_ac_vo_ecwmax=7
he_mu_edca_ac_vo_timer=255
ieee80211be=1
eht_oper_chwidth=2
eht_oper_centr_freq_seg0_idx=47
he_6ghz_reg_pwr_type=0
stationary_ap=1
mbssid=0

#num_global_macaddr=1

# Setup interface: ap-mld0
interface=ap-mld0
bssid=28:d0:43:64:27:ee
ssid2="OpenWrt-MLO"
ctrl_interface=/var/run/hostapd
ap_isolate=0
bss_load_update_period=60
chan_util_avg_period=600
disassoc_low_ack=1
skip_inactivity_poll=0
ignore_broadcast_ssid=0
uapsd_advertisement_enabled=1
utf8_ssid=1
bridge=br-lan
snoop_iface=br-lan
ocv=0
preamble=1
qos_map_set=0,0,2,16,1,1,255,255,18,22,24,38,40,40,44,46,48,56
dtim_period=2
wmm_enabled=1
sae_require_mfp=1
sae_pwe=2
wpa_passphrase=OpenWrt-MLO
wpa_psk_file=/var/run/hostapd-ap-mld0.psk
dynamic_vlan=0
wpa_disable_eapol_key_retries=0
wpa=2
wpa_pairwise=CCMP
rrm_neighbor_report=1
rrm_beacon_report=1
rnr=1
vlan_file=/var/run/hostapd-ap-mld0.vlan
ieee80211w=2
group_mgmt_cipher=AES-128-CMAC
okc=1
wpa_key_mgmt=SAE
rsn_override_key_mgmt=SAE
rsn_override_pairwise=GCMP-256 CCMP
rsn_override_mfp=2
rsn_override_key_mgmt_2=SAE
rsn_override_pairwise_2=GCMP-256 CCMP
rsn_override_mfp_2=2
mld_ap=1
mld_link_id=-1
#default_macaddr
1 Like

should not be diff band for MLO? 2,4/5/6

please show output of :
ip a

It's irrelevant.

20231227093232

root@OpenWrt:/etc/config# ip a
(snip)
7: ap-mld0: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN qlen 1000
    link/ether c0:bf:be:05:fa:b0 brd ff:ff:ff:ff:ff:ff

20251015212927a

root@OpenWrt:~# ip a
(snip)
5: ap-mld0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-lan state UP qlen 1000
    link/ether c0:bf:be:05:fa:b0 brd ff:ff:ff:ff:ff:ff

How is this helpful?