Re: brcmfmac: AP+STA on one PHY reassigns STA MAC to AP MAC and breaks concurrent operation

Stephen C Goodman <[email protected]> Wed, 5 Aug 2026 09:47:42 +0000
Newsgroups org.kernel.vger.linux-wireless,dev.linux.lists.brcm80211
Message-ID <GVYP280MB10566292972656C67802C7B79DD32@GVYP280MB1056.SWEP280.PROD.OUTLOOK.COM>
I ran additional tests and found results that may help.=0A=
=0A=
## Summary=0A=
=0A=
There appear to be two related failures:=0A=
=0A=
1. A MAC address configured for the station using OpenWrt=0A=
   "option macaddr" is ignored. The station continues using the=0A=
   primary/default address.=0A=
=0A=
2. When the AP and station are enabled concurrently, the station can=0A=
   take the AP interface's MAC address. Both interfaces then have the=0A=
   same address, the AP fails to remain active, and the station either=0A=
   fails to connect or connects only momentarily.=0A=
=0A=
The only method that reliably changes the station MAC is:=0A=
=0A=
ip link set dev phy0-sta0 address <STA_MAC>=0A=
=0A=
This works even without bringing the interface down first.=0A=
=0A=
When I bring both interfaces down, assign different MAC addresses, and=0A=
bring them up again, the addresses shown by Linux become different.=0A=
However, the interfaces then enter a repeated failure cycle: the=0A=
station connects for approximately one second and disconnects, while=0A=
phy0-ap0 appears for approximately one second and disappears again.=0A=
=0A=
## Expected behavior=0A=
=0A=
The MAC address supplied for each interface should either:=0A=
=0A=
1. be applied to that interface, or=0A=
2. be rejected with a clear error if the firmware cannot support it.=0A=
=0A=
A supported one-STA plus one-AP combination should remain operational=0A=
with distinct, valid local-unicast addresses. The driver should not=0A=
silently assign the AP address to the station or repeatedly recreate=0A=
and remove interfaces.=0A=
=0A=
## Reproduction=0A=
=0A=
1. Configure only a station on radio0 and give it an explicit MAC:=0A=
=0A=
config wifi-iface 'sta'=0A=
option device 'radio0'=0A=
option mode 'sta'=0A=
option network 'wwan'=0A=
option ssid '<redacted>'=0A=
option encryption '<redacted>'=0A=
option key '<redacted>'=0A=
option macaddr '<STA_MAC>'=0A=
=0A=
2. Reload Wi-Fi.=0A=
=0A=
3. Check phy0-sta0:=0A=
=0A=
ip link show dev phy0-sta0=0A=
=0A=
The configured STA_MAC is not applied. The station uses the=0A=
primary/default radio address instead.=0A=
=0A=
4. Configure and enable an AP on the same PHY with another address:=0A=
=0A=
config wifi-iface 'ap'=0A=
option device 'radio0'=0A=
option mode 'ap'=0A=
option network 'lan'=0A=
option ssid '<redacted>'=0A=
option encryption '<redacted>'=0A=
option key '<redacted>'=0A=
option macaddr '<AP_MAC>'=0A=
=0A=
The radio is configured so the AP and station can use the same channel;=0A=
automatic channel selection was used during this test.=0A=
=0A=
5. Reload Wi-Fi and check both interfaces:=0A=
=0A=
ip link show dev phy0-sta0=0A=
ip link show dev phy0-ap0=0A=
iw dev=0A=
=0A=
The station takes AP_MAC, so phy0-sta0 and phy0-ap0 can show the same=0A=
MAC address. The AP then fails to remain operational.=0A=
=0A=
If another AP configuration is enabled with a different address, the=0A=
station can instead take that AP's address.=0A=
=0A=
## Manual MAC-address test=0A=
=0A=
The following changes the station MAC successfully:=0A=
=0A=
ip link set dev phy0-sta0 address <STA_MAC>=0A=
=0A=
I also tested forcing both interfaces to restart with distinct=0A=
addresses:=0A=
=0A=
ip link set dev phy0-sta0 down=0A=
ip link set dev phy0-sta0 address <STA_MAC>=0A=
ip link set dev phy0-sta0 up=0A=
=0A=
ip link set dev phy0-ap0 down=0A=
ip link set dev phy0-ap0 address <AP_MAC>=0A=
ip link set dev phy0-ap0 up=0A=
=0A=
Linux then shows two distinct addresses, but AP+STA operation becomes=0A=
unstable and enters a repeated add/remove cycle.=0A=
=0A=
No interface was manually created with "iw phy interface add", and no=0A=
separate manual hostapd instance was used for the log below.=0A=
=0A=
## Relevant log excerpt=0A=
=0A=
br-lan: port 6(phy0-ap0) entered forwarding state=0A=
ieee80211 phy0: brcmf_cfg80211_add_iface: iface validation failed: err=3D-1=
6=0A=
br-lan: port 6(phy0-ap0) entered disabled state=0A=
brcmfmac 0000:01:00.0 phy0-ap0: left allmulticast mode=0A=
brcmfmac 0000:01:00.0 phy0-ap0: left promiscuous mode=0A=
br-lan: port 6(phy0-ap0) entered disabled state=0A=
br-lan: port 6(phy0-ap0) entered blocking state=0A=
br-lan: port 6(phy0-ap0) entered disabled state=0A=
brcmfmac 0000:01:00.0 phy0-ap0: entered allmulticast mode=0A=
brcmfmac 0000:01:00.0 phy0-ap0: entered promiscuous mode=0A=
ieee80211 phy0: brcmf_link_down: WLC_DISASSOC failed (-52)=0A=
br-lan: port 6(phy0-ap0) entered forwarding state=0A=
ieee80211 phy0: brcmf_cfg80211_add_iface: iface validation failed: err=3D-1=
6=0A=
=0A=
This sequence repeats approximately once per second.=0A=
=0A=
## Code-path observations=0A=
=0A=
The observed difference between OpenWrt configuration and "ip link"=0A=
appears consistent with the current brcmfmac code paths.=0A=
=0A=
OpenWrt's wireless scripts place the configured address in the nl80211=0A=
request as "req.mac". When a pre-existing wireless device is reused,=0A=
this request is sent using NL80211_CMD_SET_INTERFACE.=0A=
=0A=
In brcmfmac, brcmf_cfg80211_change_iface() receives:=0A=
=0A=
struct vif_params *params=0A=
=0A=
but does not appear to use params->macaddr.=0A=
=0A=
This could explain why a configured address is ignored when the primary=0A=
or reusable interface becomes phy0-sta0.=0A=
=0A=
There is another asymmetry in brcmf_apsta_add_vif():=0A=
=0A=
* For NL80211_IFTYPE_STATION, params->macaddr is passed to=0A=
  brcmf_cfg80211_request_sta_if().=0A=
* For NL80211_IFTYPE_AP, brcmf_cfg80211_request_ap_if() is called=0A=
  without the requested address, and that function generates an=0A=
  address from the primary interface.=0A=
=0A=
In contrast, "ip link set ... address ..." reaches=0A=
brcmf_netdev_set_mac_address(), which calls=0A=
brcmf_c_set_cur_etheraddr(). That path sends the address to the=0A=
firmware and updates the netdev address after the operation succeeds.=0A=
=0A=
The "-16" message also appears to come from interface-combination=0A=
validation before a new interface-create request is sent to firmware.=0A=
Since a STA+AP combination should be valid, perhaps a previous or stale=0A=
VIF remains counted while userspace retries the operation.=0A=
=0A=
## Possible firmware address restriction=0A=
=0A=
On the same hardware, I separately observed that multiple AP interfaces=0A=
work when their first five MAC-address octets are identical and only=0A=
the last octet differs. Arbitrary unrelated AP addresses do not work=0A=
concurrently.=0A=
=0A=
I intend to report that multi-AP behavior separately. However, it may=0A=
be relevant because brcmfmac also constructs its advertised interface=0A=
address list from a common base address and varies the final octet.=0A=
=0A=
This could indicate a firmware address-mask or address-pool restriction.=0A=
Even if that restriction is required by the firmware, it does not=0A=
appear to explain why a requested station address is silently ignored,=0A=
why the station receives an AP address, or why the failure enters an=0A=
endless retry loop.=0A=
=0A=
## Questions=0A=
=0A=
1. Is ignoring params->macaddr in brcmf_cfg80211_change_iface()=0A=
   intentional?=0A=
=0A=
2. Should the driver call brcmf_c_set_cur_etheraddr() when a MAC is=0A=
   supplied while changing/reusing the primary interface?=0A=
=0A=
3. Should brcmf_cfg80211_request_ap_if() receive and validate=0A=
   params->macaddr instead of always generating the AP address?=0A=
=0A=
4. Does the firmware require concurrent VIF addresses to share a=0A=
   particular prefix or address mask?=0A=
=0A=
5. If such a firmware restriction exists, should brcmfmac expose it=0A=
   through wiphy->addr_mask or reject incompatible addresses before=0A=
   interface creation?=0A=
=0A=
=0A=
Best regards,=0A=