ath9k: change the BSSID mask calculation to fix setting arbitrary MAC address on...
[openwrt/openwrt.git] / package / mac80211 / patches / 300-pending_work.patch
index a4bfb99b422e3a1c4f5015eddc19cf6e0f7519a7..37f127ede3fdcf74e1854c7a5549791d3e8c898b 100644 (file)
  
        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
  
                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.