diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2013-04-16 10:53:02 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2013-04-16 10:53:02 +0000 |
commit | 6f87076d8a98a7c8a77318b4a9fa3149973e4898 (patch) | |
tree | 1968ccd07e80cac75780c54719ef28ee0bbabe33 /package/mac80211/patches/300-pending_work.patch | |
parent | c9eed6a9cd92a244b68cab506a623c404d75ccc0 (diff) |
ath9k: change the BSSID mask calculation to fix setting arbitrary MAC address on interfaces
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@36344 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/mac80211/patches/300-pending_work.patch')
-rw-r--r-- | package/mac80211/patches/300-pending_work.patch | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/package/mac80211/patches/300-pending_work.patch b/package/mac80211/patches/300-pending_work.patch index a4bfb99b42..37f127ede3 100644 --- a/package/mac80211/patches/300-pending_work.patch +++ b/package/mac80211/patches/300-pending_work.patch @@ -607,6 +607,23 @@ if (!ath9k_hw_set_reset_reg(ah, reset_type)) return false; +@@ -1876,13 +1878,12 @@ int ath9k_hw_reset(struct ath_hw *ah, st + + ENABLE_REGWRITE_BUFFER(ah); + +- REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); +- REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4) +- | macStaId1 ++ REG_RMW(ah, AR_STA_ID1, macStaId1 + | AR_STA_ID1_RTS_USE_DEF + | (ah->config. + ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) +- | ah->sta_id1_defaults); ++ | ah->sta_id1_defaults, ++ ~AR_STA_ID1_SADH_MASK); + ath_hw_setbssidmask(common); + REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); + ath9k_hw_write_associd(ah); --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1236,8 +1236,10 @@ static inline void rt2x00lib_set_if_comb @@ -1629,3 +1646,95 @@ p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u " "%3u(%3u) %8llu %8llu\n", +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -657,11 +657,10 @@ enum sc_op_flags { + struct ath_rate_table; + + struct ath9k_vif_iter_data { +- const u8 *hw_macaddr; /* phy's hardware address, set +- * before starting iteration for +- * valid bssid mask. +- */ ++ u8 hw_macaddr[ETH_ALEN]; /* address of the first vif */ + u8 mask[ETH_ALEN]; /* bssid mask */ ++ bool has_hw_macaddr; ++ + int naps; /* number of AP vifs */ + int nmeshes; /* number of mesh vifs */ + int nstations; /* number of station vifs */ +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -835,10 +835,14 @@ static void ath9k_vif_iter(void *data, u + struct ath9k_vif_iter_data *iter_data = data; + int i; + +- if (iter_data->hw_macaddr) ++ if (iter_data->has_hw_macaddr) { + for (i = 0; i < ETH_ALEN; i++) + iter_data->mask[i] &= + ~(iter_data->hw_macaddr[i] ^ mac[i]); ++ } else { ++ memcpy(iter_data->hw_macaddr, mac, ETH_ALEN); ++ iter_data->has_hw_macaddr = true; ++ } + + switch (vif->type) { + case NL80211_IFTYPE_AP: +@@ -887,7 +891,6 @@ void ath9k_calculate_iter_data(struct ie + * together with the BSSID mask when matching addresses. + */ + memset(iter_data, 0, sizeof(*iter_data)); +- iter_data->hw_macaddr = common->macaddr; + memset(&iter_data->mask, 0xff, ETH_ALEN); + + if (vif) +@@ -897,6 +900,8 @@ void ath9k_calculate_iter_data(struct ie + ieee80211_iterate_active_interfaces_atomic( + sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, + ath9k_vif_iter, iter_data); ++ ++ memcpy(common->macaddr, iter_data->hw_macaddr, ETH_ALEN); + } + + /* Called with sc->mutex held. */ +--- a/drivers/net/wireless/ath/ath9k/reg.h ++++ b/drivers/net/wireless/ath/ath9k/reg.h +@@ -1493,9 +1493,6 @@ enum { + #define AR9271_RADIO_RF_RST 0x20 + #define AR9271_GATE_MAC_CTL 0x4000 + +-#define AR_STA_ID0 0x8000 +-#define AR_STA_ID1 0x8004 +-#define AR_STA_ID1_SADH_MASK 0x0000FFFF + #define AR_STA_ID1_STA_AP 0x00010000 + #define AR_STA_ID1_ADHOC 0x00020000 + #define AR_STA_ID1_PWR_SAV 0x00040000 +--- a/drivers/net/wireless/ath/hw.c ++++ b/drivers/net/wireless/ath/hw.c +@@ -118,6 +118,12 @@ + void ath_hw_setbssidmask(struct ath_common *common) + { + void *ah = common->ah; ++ u32 id1; ++ ++ REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); ++ id1 = REG_READ(ah, AR_STA_ID1) & ~AR_STA_ID1_SADH_MASK; ++ id1 |= get_unaligned_le16(common->macaddr + 4); ++ REG_WRITE(ah, AR_STA_ID1, id1); + + REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(common->bssidmask)); + REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(common->bssidmask + 4)); +--- a/drivers/net/wireless/ath/reg.h ++++ b/drivers/net/wireless/ath/reg.h +@@ -23,6 +23,10 @@ + #define AR_MIBC_CMC 0x00000004 + #define AR_MIBC_MCS 0x00000008 + ++#define AR_STA_ID0 0x8000 ++#define AR_STA_ID1 0x8004 ++#define AR_STA_ID1_SADH_MASK 0x0000ffff ++ + /* + * BSSID mask registers. See ath_hw_set_bssid_mask() + * for detailed documentation about these registers. |