From d2426509608ab2a65dd2f266e5f6d28cc8cdfe18 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 17 Dec 2017 11:44:47 +0100 Subject: [PATCH] Revert "mt76x2: remove MAC address limitation for multi-vif setups" This reverts commit 170f3341c6dca1d6815ddf875eecbf66d6fb6a4d. --- mt76x2.h | 1 - mt76x2_init.c | 2 -- mt76x2_mac.c | 27 ++++----------------------- mt76x2_mac.h | 1 - mt76x2_main.c | 30 ++++++++++++++++++------------ mt76x2_regs.h | 8 -------- 6 files changed, 22 insertions(+), 47 deletions(-) diff --git a/mt76x2.h b/mt76x2.h index a993cc09..a12dfce8 100644 --- a/mt76x2.h +++ b/mt76x2.h @@ -90,7 +90,6 @@ struct mt76x2_dev { const u16 *beacon_offsets; unsigned long wcid_mask[128 / BITS_PER_LONG]; - unsigned long vif_mask; int txpower_conf; int txpower_cur; diff --git a/mt76x2_init.c b/mt76x2_init.c index cdd9f6aa..f48c9733 100644 --- a/mt76x2_init.c +++ b/mt76x2_init.c @@ -279,8 +279,6 @@ int mt76x2_mac_reset(struct mt76x2_dev *dev, bool hard) FIELD_PREP(MT_MAC_BSSID_DW1_MBSS_MODE, 3) | /* 8 beacons */ MT_MAC_BSSID_DW1_MBSS_LOCAL_BIT); - mt76_set(dev, MT_MAC_ADDR_EXT_CTL, MT_MAC_ADDR_EXT_CTL_EN); - /* Fire a pre-TBTT interrupt 8 ms before TBTT */ mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_PRE_TBTT, 8 << 4); diff --git a/mt76x2_mac.c b/mt76x2_mac.c index 60cee4ab..a7416a01 100644 --- a/mt76x2_mac.c +++ b/mt76x2_mac.c @@ -22,29 +22,10 @@ void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr) { - u32 lo = 0, hi = 0; - - if (addr) { - lo = get_unaligned_le32(addr); - hi = get_unaligned_le16(addr + 4); - hi |= MT_MAC_APC_BSSID0_H_EN; - } - - mt76_wr(dev, MT_MAC_APC_BSSID_L(idx), lo); - mt76_wr(dev, MT_MAC_APC_BSSID_H(idx), hi); -} - -void mt76x2_mac_set_ext_mac(struct mt76x2_dev *dev, u8 idx, const u8 *addr) -{ - u32 lo = 0, hi = 0; - - if (addr) { - lo = get_unaligned_le32(addr); - hi = get_unaligned_le16(addr + 4); - } - - mt76_wr(dev, MT_MAC_ADDR_EXT_L(idx), lo); - mt76_wr(dev, MT_MAC_ADDR_EXT_H(idx), hi); + idx &= 7; + mt76_wr(dev, MT_MAC_APC_BSSID_L(idx), get_unaligned_le32(addr)); + mt76_rmw_field(dev, MT_MAC_APC_BSSID_H(idx), MT_MAC_APC_BSSID_H_ADDR, + get_unaligned_le16(addr + 4)); } static int diff --git a/mt76x2_mac.h b/mt76x2_mac.h index a993c383..8a8a25e3 100644 --- a/mt76x2_mac.h +++ b/mt76x2_mac.h @@ -162,7 +162,6 @@ int mt76x2_mac_start(struct mt76x2_dev *dev); void mt76x2_mac_stop(struct mt76x2_dev *dev, bool force); void mt76x2_mac_resume(struct mt76x2_dev *dev); void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr); -void mt76x2_mac_set_ext_mac(struct mt76x2_dev *dev, u8 idx, const u8 *addr); int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, void *rxi); diff --git a/mt76x2_main.c b/mt76x2_main.c index 1331564b..1bc66d75 100644 --- a/mt76x2_main.c +++ b/mt76x2_main.c @@ -82,16 +82,27 @@ mt76x2_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt76x2_dev *dev = hw->priv; struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; - unsigned int idx; + unsigned int idx = 0; int ret = 0; - idx = ffs(~dev->vif_mask); - if (!idx || idx > 8) - return -ENOSPC; + if (vif->addr[0] & BIT(1)) + idx = 1 + (((dev->mt76.macaddr[0] ^ vif->addr[0]) >> 2) & 7); - idx--; - dev->vif_mask |= BIT(idx); - mt76x2_mac_set_ext_mac(dev, idx, vif->addr); + /* + * Client mode typically only has one configurable BSSID register, + * which is used for bssidx=0. This is linked to the MAC address. + * Since mac80211 allows changing interface types, and we cannot + * force the use of the primary MAC address for a station mode + * interface, we need some other way of configuring a per-interface + * remote BSSID. + * The hardware provides an AP-Client feature, where bssidx 0-7 are + * used for AP mode and bssidx 8-15 for client mode. + * We shift the station interface bss index by 8 to force the + * hardware to recognize the BSSID. + * The resulting bssidx mismatch for unicast frames is ignored by hw. + */ + if (vif->type == NL80211_IFTYPE_STATION) + idx += 8; mvif->idx = idx; mvif->group_wcid.idx = 254 - idx; @@ -104,13 +115,8 @@ mt76x2_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) static void mt76x2_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct mt76x2_vif *mvif = (struct mt76x2_vif *)vif->drv_priv; struct mt76x2_dev *dev = hw->priv; - int idx = mvif->idx; - mt76x2_mac_set_bssid(dev, mvif->idx, NULL); - mt76x2_mac_set_ext_mac(dev, idx, NULL); - dev->vif_mask &= ~BIT(idx); mt76_txq_remove(&dev->mt76, vif->txq); } diff --git a/mt76x2_regs.h b/mt76x2_regs.h index 95c1e955..ce3ab85c 100644 --- a/mt76x2_regs.h +++ b/mt76x2_regs.h @@ -438,14 +438,6 @@ #define MT_TX_SW_CFG3 0x1478 -#define MT_MAC_ADDR_EXT_CTL 0x147c -#define MT_MAC_ADDR_EXT_CTL_EN BIT(0) - -#define MT_MAC_ADDR_EXT_BASE 0x1480 -#define MT_MAC_ADDR_EXT_L(_n) (MT_MAC_ADDR_EXT_BASE + ((_n) * 8)) -#define MT_MAC_ADDR_EXT_H(_n) (MT_MAC_ADDR_EXT_BASE + ((_n) * 8 + 4)) -#define MT_MAC_ADDR_EXT_H_MASK GENMASK(15, 0) - #define MT_PN_PAD_MODE 0x150c #define MT_TXOP_HLDR_ET 0x1608