* [PATCH ath-next v3] wifi: ath12k: advertise interface MAC address pool
@ 2026-09-21 17:30 Vitor Soares
2026-09-22 6:13 ` Kang Yang
2026-09-22 6:47 ` Baochen Qiang
0 siblings, 2 replies; 4+ messages in thread
From: Vitor Soares @ 2026-09-21 17:30 UTC (permalink / raw)
To: Jeff Johnson
Cc: Vitor Soares, linux-wireless, ath12k, linux-kernel,
baochen.qiang, kang.yang
From: Vitor Soares <vitor.soares@toradex.com>
ath12k supports creating vdevs with addresses provided by mac80211.
Userspace can already make concurrent interfaces work by explicitly
assigning different locally administered addresses.
However, ath12k does not advertise an address list, so when a second
interface is created without an explicit address, mac80211 has nothing
to pick from and falls back to the permanent address. If the first
interface is already running with that address, bringing up the second
one fails with -ENOTUNIQ.
As in ath11k, provide a list of usable addresses so
ieee80211_assign_perm_addr() can hand each new interface an unused one.
Keep the first entry as the wiphy's permanent MAC address. Generate the
remaining entries as locally administered variants by changing only the
upper nibble of the first octet, which naturally limits the pool to 16
unique addresses.
The cfg80211 definition of wiphy->addresses does not specify where the
addresses must come from. Some ath12k platforms use it as an interface
MAC address pool, while others use it for firmware-provided per-radio
addresses. Gate the generated address pool behind
advertise_iface_mac_pool and enable it for WCN7850 and QCC2072.
Other platforms keep the existing behavior.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
Assisted-by: LLM
Signed-off-by: Vitor Soares <vitor.soares@toradex.com>
---
v3:
- Rename host_alloc_iface_mac to advertise_iface_mac_pool.
- Clear wiphy->addresses and wiphy->n_addresses during cleanup.
- Drop the single-radio check and rely on hw_params gating.
- Enable the generated interface MAC pool for WCN7850 and QCC2072
(QCC2072 compile-tested only).
- Follow kernel block comment style.
- Link for v2: https://lore.kernel.org/all/20260915152815.254016-2-ivitro@gmail.com/
v2:
- Gate generated interface MAC address list behind hw_params
host_alloc_iface_mac, as suggested by Kang Yang.
- Enable it only for WCN7850, the only part available for testing here.
- Add Assisted-by: tag.
- Link for v1: https://lore.kernel.org/all/20260902082219.3010793-2-ivitro@gmail.com/
---
drivers/net/wireless/ath/ath12k/hw.h | 1 +
drivers/net/wireless/ath/ath12k/mac.c | 48 ++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/wifi7/hw.c | 6 +++
3 files changed, 55 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h
index e790de5737db..c58db8482aa4 100644
--- a/drivers/net/wireless/ath/ath12k/hw.h
+++ b/drivers/net/wireless/ath/ath12k/hw.h
@@ -238,6 +238,7 @@ struct ath12k_hw_params {
} client;
bool host_alloc_ml_id;
+ bool advertise_iface_mac_pool;
};
struct ath12k_hw_ops {
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index d4116ba0da08..46f5f338f44c 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -14743,6 +14743,50 @@ static void ath12k_mac_cleanup_unregister(struct ath12k *ar)
kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
}
+static void ath12k_mac_cleanup_mac_address_list(struct ath12k_hw *ah)
+{
+ kfree(ah->hw->wiphy->addresses);
+ ah->hw->wiphy->addresses = NULL;
+ ah->hw->wiphy->n_addresses = 0;
+}
+
+static void ath12k_mac_setup_mac_address_list(struct ath12k_hw *ah,
+ const u8 *mac_addr)
+{
+ struct mac_address *addresses;
+ struct ath12k *ar;
+ u16 n_addresses;
+ int i;
+
+ ar = ath12k_ah_to_ar(ah, 0);
+ if (!ar->ab->hw_params->advertise_iface_mac_pool)
+ return;
+
+ /*
+ * Only the upper nibble of the first octet is varied, so at most 16
+ * addresses can be derived from one base.
+ */
+ n_addresses = min_t(u16, TARGET_NUM_VDEVS(ar->ab), 16);
+ if (n_addresses <= 1)
+ return;
+
+ addresses = kzalloc_objs(*addresses, n_addresses);
+ if (!addresses)
+ return;
+
+ ether_addr_copy(addresses[0].addr, mac_addr);
+ for (i = 1; i < n_addresses; i++) {
+ ether_addr_copy(addresses[i].addr, mac_addr);
+ /* set Local Administered Address bit */
+ addresses[i].addr[0] |= 0x2;
+
+ addresses[i].addr[0] += i << 4;
+ }
+
+ ah->hw->wiphy->addresses = addresses;
+ ah->hw->wiphy->n_addresses = n_addresses;
+}
+
static void ath12k_mac_hw_unregister(struct ath12k_hw *ah)
{
struct ieee80211_hw *hw = ah->hw;
@@ -14762,6 +14806,7 @@ static void ath12k_mac_hw_unregister(struct ath12k_hw *ah)
ath12k_mac_cleanup_unregister(ar);
ath12k_mac_cleanup_iface_combinations(ah);
+ ath12k_mac_cleanup_mac_address_list(ah);
SET_IEEE80211_DEV(hw, NULL);
}
@@ -14878,6 +14923,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
wiphy->available_antennas_tx = antennas_tx;
SET_IEEE80211_PERM_ADDR(hw, mac_addr);
+ ath12k_mac_setup_mac_address_list(ah, mac_addr);
SET_IEEE80211_DEV(hw, ab->dev);
ret = ath12k_mac_setup_iface_combinations(ah);
@@ -15120,6 +15166,8 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
ath12k_mac_cleanup_unregister(ar);
}
+ ath12k_mac_cleanup_mac_address_list(ah);
+
SET_IEEE80211_DEV(hw, NULL);
return ret;
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
index ae8df80928b0..ad362244ed9b 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
@@ -445,6 +445,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
},
.host_alloc_ml_id = true,
+ .advertise_iface_mac_pool = false,
},
{
.name = "wcn7850 hw2.0",
@@ -539,6 +540,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
},
.host_alloc_ml_id = false,
+ .advertise_iface_mac_pool = true,
},
{
.name = "qcn9274 hw2.0",
@@ -629,6 +631,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
},
.host_alloc_ml_id = true,
+ .advertise_iface_mac_pool = false,
},
{
.name = "ipq5332 hw1.0",
@@ -713,6 +716,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
},
.host_alloc_ml_id = true,
+ .advertise_iface_mac_pool = false,
},
{
.name = "qcc2072 hw1.0",
@@ -808,6 +812,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
},
.host_alloc_ml_id = false,
+ .advertise_iface_mac_pool = true,
},
{
.name = "ipq5424 hw1.0",
@@ -895,6 +900,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
},
.host_alloc_ml_id = true,
+ .advertise_iface_mac_pool = false,
},
};
--
2.55.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH ath-next v3] wifi: ath12k: advertise interface MAC address pool
2026-09-21 17:30 [PATCH ath-next v3] wifi: ath12k: advertise interface MAC address pool Vitor Soares
@ 2026-09-22 6:13 ` Kang Yang
2026-09-22 9:29 ` Vitor Soares
2026-09-22 6:47 ` Baochen Qiang
1 sibling, 1 reply; 4+ messages in thread
From: Kang Yang @ 2026-09-22 6:13 UTC (permalink / raw)
To: Vitor Soares, Jeff Johnson
Cc: Vitor Soares, linux-wireless, ath12k, linux-kernel, baochen.qiang
On 9/22/2026 1:30 AM, Vitor Soares wrote:
> From: Vitor Soares <vitor.soares@toradex.com>
>
> ath12k supports creating vdevs with addresses provided by mac80211.
> Userspace can already make concurrent interfaces work by explicitly
> assigning different locally administered addresses.
>
> However, ath12k does not advertise an address list, so when a second
> interface is created without an explicit address, mac80211 has nothing
> to pick from and falls back to the permanent address. If the first
> interface is already running with that address, bringing up the second
> one fails with -ENOTUNIQ.
>
> As in ath11k, provide a list of usable addresses so
> ieee80211_assign_perm_addr() can hand each new interface an unused one.
> Keep the first entry as the wiphy's permanent MAC address. Generate the
> remaining entries as locally administered variants by changing only the
> upper nibble of the first octet, which naturally limits the pool to 16
> unique addresses.
>
> The cfg80211 definition of wiphy->addresses does not specify where the
> addresses must come from. Some ath12k platforms use it as an interface
> MAC address pool, while others use it for firmware-provided per-radio
> addresses. Gate the generated address pool behind
> advertise_iface_mac_pool and enable it for WCN7850 and QCC2072.
>
> Other platforms keep the existing behavior.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
>
I just did test on QCC2072:
root@yk-Mayan:/home/yk# sudo iw dev wlo1 interface add wlo2 type station
root@yk-Mayan:/home/yk# sudo iw dev wlo1 interface add wlo3 type station
phy#0
Interface wlo3
ifindex 6
wdev 0x3
addr 22:03:7f:12:be:cd
type managed
Interface wlo2
ifindex 5
wdev 0x2
addr 12:03:7f:12:be:cd
type managed
Interface wlo1
ifindex 4
wdev 0x1
addr 00:03:7f:12:be:cd
type managed
Tested-on: QCC2072 hw1.0 PCI
WLAN.COL.1.0.c2-00074-QCACOLSWPL_V1_TO_SILICONZ-1
> Assisted-by: LLM
> Signed-off-by: Vitor Soares <vitor.soares@toradex.com>
> ---
> v3:
> - Rename host_alloc_iface_mac to advertise_iface_mac_pool.
> - Clear wiphy->addresses and wiphy->n_addresses during cleanup.
> - Drop the single-radio check and rely on hw_params gating.
> - Enable the generated interface MAC pool for WCN7850 and QCC2072
> (QCC2072 compile-tested only).
> - Follow kernel block comment style.
> - Link for v2: https://lore.kernel.org/all/20260915152815.254016-2-ivitro@gmail.com/
>
> v2:
> - Gate generated interface MAC address list behind hw_params
> host_alloc_iface_mac, as suggested by Kang Yang.
> - Enable it only for WCN7850, the only part available for testing here.
> - Add Assisted-by: tag.
> - Link for v1: https://lore.kernel.org/all/20260902082219.3010793-2-ivitro@gmail.com/
> ---
> drivers/net/wireless/ath/ath12k/hw.h | 1 +
> drivers/net/wireless/ath/ath12k/mac.c | 48 ++++++++++++++++++++++
> drivers/net/wireless/ath/ath12k/wifi7/hw.c | 6 +++
> 3 files changed, 55 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h
> index e790de5737db..c58db8482aa4 100644
> --- a/drivers/net/wireless/ath/ath12k/hw.h
> +++ b/drivers/net/wireless/ath/ath12k/hw.h
> @@ -238,6 +238,7 @@ struct ath12k_hw_params {
> } client;
>
> bool host_alloc_ml_id;
> + bool advertise_iface_mac_pool;
> };
>
> struct ath12k_hw_ops {
> diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
> index d4116ba0da08..46f5f338f44c 100644
> --- a/drivers/net/wireless/ath/ath12k/mac.c
> +++ b/drivers/net/wireless/ath/ath12k/mac.c
> @@ -14743,6 +14743,50 @@ static void ath12k_mac_cleanup_unregister(struct ath12k *ar)
> kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
> }
>
> +static void ath12k_mac_cleanup_mac_address_list(struct ath12k_hw *ah)
> +{
> + kfree(ah->hw->wiphy->addresses);
> + ah->hw->wiphy->addresses = NULL;
> + ah->hw->wiphy->n_addresses = 0;
> +}
> +
> +static void ath12k_mac_setup_mac_address_list(struct ath12k_hw *ah,
> + const u8 *mac_addr)
> +{
> + struct mac_address *addresses;
> + struct ath12k *ar;
> + u16 n_addresses;
> + int i;
> +
> + ar = ath12k_ah_to_ar(ah, 0);
> + if (!ar->ab->hw_params->advertise_iface_mac_pool)
> + return;
> +
> + /*
> + * Only the upper nibble of the first octet is varied, so at most 16
> + * addresses can be derived from one base.
> + */
> + n_addresses = min_t(u16, TARGET_NUM_VDEVS(ar->ab), 16);
> + if (n_addresses <= 1)
> + return;
> +
> + addresses = kzalloc_objs(*addresses, n_addresses);
> + if (!addresses)
> + return;
> +
> + ether_addr_copy(addresses[0].addr, mac_addr);
> + for (i = 1; i < n_addresses; i++) {
> + ether_addr_copy(addresses[i].addr, mac_addr);
> + /* set Local Administered Address bit */
> + addresses[i].addr[0] |= 0x2;
> +
> + addresses[i].addr[0] += i << 4;
> + }
> +
> + ah->hw->wiphy->addresses = addresses;
> + ah->hw->wiphy->n_addresses = n_addresses;
> +}
> +
> static void ath12k_mac_hw_unregister(struct ath12k_hw *ah)
> {
> struct ieee80211_hw *hw = ah->hw;
> @@ -14762,6 +14806,7 @@ static void ath12k_mac_hw_unregister(struct ath12k_hw *ah)
> ath12k_mac_cleanup_unregister(ar);
>
> ath12k_mac_cleanup_iface_combinations(ah);
> + ath12k_mac_cleanup_mac_address_list(ah);
>
> SET_IEEE80211_DEV(hw, NULL);
> }
> @@ -14878,6 +14923,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
> wiphy->available_antennas_tx = antennas_tx;
>
> SET_IEEE80211_PERM_ADDR(hw, mac_addr);
> + ath12k_mac_setup_mac_address_list(ah, mac_addr);
> SET_IEEE80211_DEV(hw, ab->dev);
>
> ret = ath12k_mac_setup_iface_combinations(ah);
> @@ -15120,6 +15166,8 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
> ath12k_mac_cleanup_unregister(ar);
> }
>
> + ath12k_mac_cleanup_mac_address_list(ah);
> +
> SET_IEEE80211_DEV(hw, NULL);
>
> return ret;
> diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
> index ae8df80928b0..ad362244ed9b 100644
> --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c
> +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
> @@ -445,6 +445,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
> },
>
> .host_alloc_ml_id = true,
> + .advertise_iface_mac_pool = false,
> },
> {
> .name = "wcn7850 hw2.0",
> @@ -539,6 +540,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
> },
>
> .host_alloc_ml_id = false,
> + .advertise_iface_mac_pool = true,
> },
> {
> .name = "qcn9274 hw2.0",
> @@ -629,6 +631,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
> },
>
> .host_alloc_ml_id = true,
> + .advertise_iface_mac_pool = false,
> },
> {
> .name = "ipq5332 hw1.0",
> @@ -713,6 +716,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
> },
>
> .host_alloc_ml_id = true,
> + .advertise_iface_mac_pool = false,
> },
> {
> .name = "qcc2072 hw1.0",
> @@ -808,6 +812,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
> },
>
> .host_alloc_ml_id = false,
> + .advertise_iface_mac_pool = true,
> },
> {
> .name = "ipq5424 hw1.0",
> @@ -895,6 +900,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
> },
>
> .host_alloc_ml_id = true,
> + .advertise_iface_mac_pool = false,
> },
> };
>
LGTM, Baochen/jeff do you have any comments?
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH ath-next v3] wifi: ath12k: advertise interface MAC address pool
2026-09-21 17:30 [PATCH ath-next v3] wifi: ath12k: advertise interface MAC address pool Vitor Soares
2026-09-22 6:13 ` Kang Yang
@ 2026-09-22 6:47 ` Baochen Qiang
1 sibling, 0 replies; 4+ messages in thread
From: Baochen Qiang @ 2026-09-22 6:47 UTC (permalink / raw)
To: Vitor Soares, Jeff Johnson
Cc: Vitor Soares, linux-wireless, ath12k, linux-kernel, kang.yang
On 9/22/2026 1:30 AM, Vitor Soares wrote:
> From: Vitor Soares <vitor.soares@toradex.com>
>
> ath12k supports creating vdevs with addresses provided by mac80211.
> Userspace can already make concurrent interfaces work by explicitly
> assigning different locally administered addresses.
>
> However, ath12k does not advertise an address list, so when a second
> interface is created without an explicit address, mac80211 has nothing
> to pick from and falls back to the permanent address. If the first
> interface is already running with that address, bringing up the second
> one fails with -ENOTUNIQ.
>
> As in ath11k, provide a list of usable addresses so
> ieee80211_assign_perm_addr() can hand each new interface an unused one.
> Keep the first entry as the wiphy's permanent MAC address. Generate the
> remaining entries as locally administered variants by changing only the
> upper nibble of the first octet, which naturally limits the pool to 16
> unique addresses.
>
> The cfg80211 definition of wiphy->addresses does not specify where the
> addresses must come from. Some ath12k platforms use it as an interface
> MAC address pool, while others use it for firmware-provided per-radio
> addresses. Gate the generated address pool behind
> advertise_iface_mac_pool and enable it for WCN7850 and QCC2072.
>
> Other platforms keep the existing behavior.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
>
> Assisted-by: LLM
> Signed-off-by: Vitor Soares <vitor.soares@toradex.com>
> ---
> v3:
> - Rename host_alloc_iface_mac to advertise_iface_mac_pool.
> - Clear wiphy->addresses and wiphy->n_addresses during cleanup.
> - Drop the single-radio check and rely on hw_params gating.
> - Enable the generated interface MAC pool for WCN7850 and QCC2072
> (QCC2072 compile-tested only).
> - Follow kernel block comment style.
> - Link for v2: https://lore.kernel.org/all/20260915152815.254016-2-ivitro@gmail.com/
>
> v2:
> - Gate generated interface MAC address list behind hw_params
> host_alloc_iface_mac, as suggested by Kang Yang.
> - Enable it only for WCN7850, the only part available for testing here.
> - Add Assisted-by: tag.
> - Link for v1: https://lore.kernel.org/all/20260902082219.3010793-2-ivitro@gmail.com/
> ---
> drivers/net/wireless/ath/ath12k/hw.h | 1 +
> drivers/net/wireless/ath/ath12k/mac.c | 48 ++++++++++++++++++++++
> drivers/net/wireless/ath/ath12k/wifi7/hw.c | 6 +++
> 3 files changed, 55 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h
> index e790de5737db..c58db8482aa4 100644
> --- a/drivers/net/wireless/ath/ath12k/hw.h
> +++ b/drivers/net/wireless/ath/ath12k/hw.h
> @@ -238,6 +238,7 @@ struct ath12k_hw_params {
> } client;
>
> bool host_alloc_ml_id;
> + bool advertise_iface_mac_pool;
> };
>
> struct ath12k_hw_ops {
> diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
> index d4116ba0da08..46f5f338f44c 100644
> --- a/drivers/net/wireless/ath/ath12k/mac.c
> +++ b/drivers/net/wireless/ath/ath12k/mac.c
> @@ -14743,6 +14743,50 @@ static void ath12k_mac_cleanup_unregister(struct ath12k *ar)
> kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
> }
>
> +static void ath12k_mac_cleanup_mac_address_list(struct ath12k_hw *ah)
> +{
> + kfree(ah->hw->wiphy->addresses);
> + ah->hw->wiphy->addresses = NULL;
> + ah->hw->wiphy->n_addresses = 0;
> +}
> +
> +static void ath12k_mac_setup_mac_address_list(struct ath12k_hw *ah,
> + const u8 *mac_addr)
> +{
> + struct mac_address *addresses;
> + struct ath12k *ar;
> + u16 n_addresses;
> + int i;
> +
> + ar = ath12k_ah_to_ar(ah, 0);
> + if (!ar->ab->hw_params->advertise_iface_mac_pool)
> + return;
commit message does not describe why only the first radio is checked. From previous
revision I know the purpose is to enable only WCN7850/QCC2072. Better to describe it in
commit message, as well as leaving a comment here.
> +
> + /*
> + * Only the upper nibble of the first octet is varied, so at most 16
> + * addresses can be derived from one base.
> + */
> + n_addresses = min_t(u16, TARGET_NUM_VDEVS(ar->ab), 16);
> + if (n_addresses <= 1)
> + return;
> +
> + addresses = kzalloc_objs(*addresses, n_addresses);
> + if (!addresses)
> + return;
> +
> + ether_addr_copy(addresses[0].addr, mac_addr);
> + for (i = 1; i < n_addresses; i++) {
> + ether_addr_copy(addresses[i].addr, mac_addr);
> + /* set Local Administered Address bit */
> + addresses[i].addr[0] |= 0x2;
> +
> + addresses[i].addr[0] += i << 4;
> + }
> +
> + ah->hw->wiphy->addresses = addresses;
> + ah->hw->wiphy->n_addresses = n_addresses;
> +}
> +
> static void ath12k_mac_hw_unregister(struct ath12k_hw *ah)
> {
> struct ieee80211_hw *hw = ah->hw;
> @@ -14762,6 +14806,7 @@ static void ath12k_mac_hw_unregister(struct ath12k_hw *ah)
> ath12k_mac_cleanup_unregister(ar);
>
> ath12k_mac_cleanup_iface_combinations(ah);
> + ath12k_mac_cleanup_mac_address_list(ah);
>
> SET_IEEE80211_DEV(hw, NULL);
> }
> @@ -14878,6 +14923,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
> wiphy->available_antennas_tx = antennas_tx;
>
> SET_IEEE80211_PERM_ADDR(hw, mac_addr);
> + ath12k_mac_setup_mac_address_list(ah, mac_addr);
> SET_IEEE80211_DEV(hw, ab->dev);
>
> ret = ath12k_mac_setup_iface_combinations(ah);
> @@ -15120,6 +15166,8 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
> ath12k_mac_cleanup_unregister(ar);
> }
>
> + ath12k_mac_cleanup_mac_address_list(ah);
> +
> SET_IEEE80211_DEV(hw, NULL);
>
> return ret;
> diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
> index ae8df80928b0..ad362244ed9b 100644
> --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c
> +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
> @@ -445,6 +445,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
> },
>
> .host_alloc_ml_id = true,
> + .advertise_iface_mac_pool = false,
> },
> {
> .name = "wcn7850 hw2.0",
> @@ -539,6 +540,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
> },
>
> .host_alloc_ml_id = false,
> + .advertise_iface_mac_pool = true,
> },
> {
> .name = "qcn9274 hw2.0",
> @@ -629,6 +631,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
> },
>
> .host_alloc_ml_id = true,
> + .advertise_iface_mac_pool = false,
> },
> {
> .name = "ipq5332 hw1.0",
> @@ -713,6 +716,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
> },
>
> .host_alloc_ml_id = true,
> + .advertise_iface_mac_pool = false,
> },
> {
> .name = "qcc2072 hw1.0",
> @@ -808,6 +812,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
> },
>
> .host_alloc_ml_id = false,
> + .advertise_iface_mac_pool = true,
> },
> {
> .name = "ipq5424 hw1.0",
> @@ -895,6 +900,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
> },
>
> .host_alloc_ml_id = true,
> + .advertise_iface_mac_pool = false,
> },
> };
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH ath-next v3] wifi: ath12k: advertise interface MAC address pool
2026-09-22 6:13 ` Kang Yang
@ 2026-09-22 9:29 ` Vitor Soares
0 siblings, 0 replies; 4+ messages in thread
From: Vitor Soares @ 2026-09-22 9:29 UTC (permalink / raw)
To: Kang Yang, Jeff Johnson
Cc: Vitor Soares, linux-wireless, ath12k, linux-kernel, baochen.qiang
On Tue, 2026-09-22 at 14:13 +0800, Kang Yang wrote:
>
>
> On 9/22/2026 1:30 AM, Vitor Soares wrote:
> > From: Vitor Soares <vitor.soares@toradex.com>
> >
> > ath12k supports creating vdevs with addresses provided by mac80211.
> > Userspace can already make concurrent interfaces work by explicitly
> > assigning different locally administered addresses.
> >
> > However, ath12k does not advertise an address list, so when a second
> > interface is created without an explicit address, mac80211 has nothing
> > to pick from and falls back to the permanent address. If the first
> > interface is already running with that address, bringing up the second
> > one fails with -ENOTUNIQ.
> >
> > As in ath11k, provide a list of usable addresses so
> > ieee80211_assign_perm_addr() can hand each new interface an unused one.
> > Keep the first entry as the wiphy's permanent MAC address. Generate the
> > remaining entries as locally administered variants by changing only the
> > upper nibble of the first octet, which naturally limits the pool to 16
> > unique addresses.
> >
> > The cfg80211 definition of wiphy->addresses does not specify where the
> > addresses must come from. Some ath12k platforms use it as an interface
> > MAC address pool, while others use it for firmware-provided per-radio
> > addresses. Gate the generated address pool behind
> > advertise_iface_mac_pool and enable it for WCN7850 and QCC2072.
> >
> > Other platforms keep the existing behavior.
> >
> > Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-
> > QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
> >
>
>
>
> I just did test on QCC2072:
>
> root@yk-Mayan:/home/yk# sudo iw dev wlo1 interface add wlo2 type station
> root@yk-Mayan:/home/yk# sudo iw dev wlo1 interface add wlo3 type station
> phy#0
> Interface wlo3
> ifindex 6
> wdev 0x3
> addr 22:03:7f:12:be:cd
> type managed
>
> Interface wlo2
> ifindex 5
> wdev 0x2
> addr 12:03:7f:12:be:cd
> type managed
>
> Interface wlo1
> ifindex 4
> wdev 0x1
> addr 00:03:7f:12:be:cd
> type managed
>
>
>
>
> Tested-on: QCC2072 hw1.0 PCI
> WLAN.COL.1.0.c2-00074-QCACOLSWPL_V1_TO_SILICONZ-1
>
Thanks for testing this on QCC2072.
I've added the QCC2072 Tested-on line for v4. Could you reply with your Tested-
by so I can pick it up?
Best regards,
Vitor
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-09-22 9:29 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-21 17:30 [PATCH ath-next v3] wifi: ath12k: advertise interface MAC address pool Vitor Soares
2026-09-22 6:13 ` Kang Yang
2026-09-22 9:29 ` Vitor Soares
2026-09-22 6:47 ` Baochen Qiang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®