mt76: derive a distinct address for bands sharing one MAC

Factory data and device trees can point several bands at a single MAC
address. Publishing it once per band hands the same address to userspace
repeatedly, which then assigns it to more than one BSS.

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2026-08-08 05:35:06 +02:00
parent 03f86e9294
commit 476cac3604
+43
View File
@@ -170,6 +170,47 @@ static int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int len)
return mt76_get_of_data_from_nvmem(dev, eep, "eeprom", len);
}
static bool
mt76_macaddr_taken(struct mt76_phy *phy)
{
struct mt76_dev *dev = phy->dev;
int i;
for (i = 0; i < ARRAY_SIZE(dev->phys); i++) {
struct mt76_phy *other = dev->phys[i];
if (!other || other == phy)
continue;
if (ether_addr_equal(other->macaddr, phy->macaddr))
return true;
}
return false;
}
/* Several bands can end up with one address, either from a device tree node
* shared between them or from factory data that repeats it. Hand out a
* locally administered derivative instead, so that each band keeps an address
* of its own to use as a BSSID.
*/
static void
mt76_macaddr_deduplicate(struct mt76_phy *phy)
{
int i;
if (!mt76_macaddr_taken(phy))
return;
phy->macaddr[0] |= 2;
phy->macaddr[0] ^= BIT(7);
if (phy->band_idx == MT_BAND2)
phy->macaddr[0] ^= BIT(6);
for (i = 0; i < ARRAY_SIZE(phy->dev->phys) && mt76_macaddr_taken(phy); i++)
phy->macaddr[5]++;
}
int
mt76_eeprom_override(struct mt76_phy *phy)
{
@@ -208,6 +249,8 @@ mt76_eeprom_override(struct mt76_phy *phy)
phy->macaddr);
}
mt76_macaddr_deduplicate(phy);
return 0;
}
EXPORT_SYMBOL_GPL(mt76_eeprom_override);