mac80211: update to wireless-testing 2015-07-21
authorFelix Fietkau <nbd@openwrt.org>
Wed, 22 Jul 2015 12:45:03 +0000 (12:45 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Wed, 22 Jul 2015 12:45:03 +0000 (12:45 +0000)
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
SVN-Revision: 46436

30 files changed:
package/kernel/mac80211/Makefile
package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch
package/kernel/mac80211/patches/210-ap_scan.patch [deleted file]
package/kernel/mac80211/patches/301-ath9k-limit-retries-for-powersave-response-frames.patch [new file with mode: 0644]
package/kernel/mac80211/patches/301-ath9k_hw-fix-device-ID-check-for-AR956x.patch [deleted file]
package/kernel/mac80211/patches/302-ath-DFS-limit-number-of-potential-PRI-sequences.patch [deleted file]
package/kernel/mac80211/patches/302-ath10k-Delay-device-access-after-cold-reset.patch [new file with mode: 0644]
package/kernel/mac80211/patches/303-ath9k-DFS-consider-ext_channel-pulses-only-in-HT40-m.patch [deleted file]
package/kernel/mac80211/patches/303-ath9k-add-fast-xmit-support.patch [new file with mode: 0644]
package/kernel/mac80211/patches/304-ath9k-DFS-add-pulse-chirp-detection-for-FCC.patch [deleted file]
package/kernel/mac80211/patches/304-ath9k-remove-struct-ath_atx_ac.patch [new file with mode: 0644]
package/kernel/mac80211/patches/305-ath9k-make-DMA-stop-related-messages-debug-only.patch [deleted file]
package/kernel/mac80211/patches/305-ath9k-remove-the-sched-field-in-struct-ath_atx_tid.patch [new file with mode: 0644]
package/kernel/mac80211/patches/306-ath9k-limit-retries-for-powersave-response-frames.patch [deleted file]
package/kernel/mac80211/patches/306-mac80211-Deinline-rate_control_rate_init-rate_contro.patch [new file with mode: 0644]
package/kernel/mac80211/patches/307-ath10k-Delay-device-access-after-cold-reset.patch [deleted file]
package/kernel/mac80211/patches/307-mac80211-Deinline-drv_sta_state.patch [new file with mode: 0644]
package/kernel/mac80211/patches/308-ath9k-Fix-NF-CCA-limits-for-AR9287-and-AR9227.patch [new file with mode: 0644]
package/kernel/mac80211/patches/308-cfg80211-use-RTNL-locked-reg_can_beacon-for-IR-relax.patch [deleted file]
package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch
package/kernel/mac80211/patches/501-ath9k_ahb_init.patch
package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch
package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch
package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
package/kernel/mac80211/patches/863-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch [deleted file]
package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch
package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch

index cc98fb7d4885a008479800d2fb6c68a1257d1195..4a6b418e6c580c43467c302ac38713a366be2cd7 100644 (file)
@@ -10,11 +10,11 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=mac80211
 
-PKG_VERSION:=2015-06-22
+PKG_VERSION:=2015-07-21
 PKG_RELEASE:=1
 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
 PKG_BACKPORT_VERSION:=
-PKG_MD5SUM:=352b2b46d36a72aadc96161a3cefdb1c
+PKG_MD5SUM:=ec529acfb9c942daf8116e5cff47c999
 
 PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
index d85b81336806511eef8fce86f07f072ba8eef929..4fbab23c723e4267dbbac5c472ed2c466b38bdbf 100644 (file)
@@ -1,6 +1,6 @@
 --- a/.local-symbols
 +++ b/.local-symbols
-@@ -448,43 +448,6 @@ USB_CDC_PHONET=
+@@ -449,43 +449,6 @@ USB_CDC_PHONET=
  USB_IPHETH=
  USB_SIERRA_NET=
  USB_VL600=
index 55a1ccd9079a3b0c30a47d4dfd6a7be3a4117882..07dde5481cb4c9f9810a3a1113ed3751ae659be0 100644 (file)
@@ -1,3 +1,14 @@
+--- a/net/mac80211/Kconfig
++++ b/net/mac80211/Kconfig
+@@ -5,8 +5,6 @@ config MAC80211
+       depends on CRYPTO
+       depends on CRYPTO_ARC4
+       depends on CRYPTO_AES
+-      select BPAUTO_CRYPTO_CCM
+-      depends on CRYPTO_GCM
+       depends on CRC32
+       select BPAUTO_AVERAGE
+       ---help---
 --- a/net/mac80211/Makefile
 +++ b/net/mac80211/Makefile
 @@ -15,9 +15,7 @@ mac80211-y := \
        cfg.o \
        ethtool.o \
        rx.o \
---- a/net/mac80211/aes_gcm.h
-+++ b/net/mac80211/aes_gcm.h
-@@ -11,12 +11,28 @@
- #include <linux/crypto.h>
--void ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
--                             u8 *data, size_t data_len, u8 *mic);
--int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
--                            u8 *data, size_t data_len, u8 *mic);
--struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
--                                                      size_t key_len);
--void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm);
-+static inline void
-+ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
-+                        u8 *data, size_t data_len, u8 *mic)
-+{
-+}
-+
-+static inline int
-+ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
-+                        u8 *data, size_t data_len, u8 *mic)
-+{
-+    return -EOPNOTSUPP;
-+}
-+
-+static inline struct crypto_aead *
-+ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len)
-+{
-+    return NULL;
-+}
-+
-+static inline void
-+ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
-+{
-+}
- #endif /* AES_GCM_H */
---- a/net/mac80211/aes_gmac.h
-+++ b/net/mac80211/aes_gmac.h
-@@ -11,10 +11,22 @@
- #include <linux/crypto.h>
--struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
--                                               size_t key_len);
--int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
--                     const u8 *data, size_t data_len, u8 *mic);
--void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm);
-+static inline struct crypto_aead *
-+ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len)
-+{
-+      return NULL;
-+}
-+
-+static inline int
-+ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
-+                 const u8 *data, size_t data_len, u8 *mic)
-+{
-+      return -EOPNOTSUPP;
-+}
-+
-+static inline void
-+ieee80211_aes_gmac_key_free(struct crypto_aead *tfm)
-+{
-+}
- #endif /* AES_GMAC_H */
 --- a/net/mac80211/aes_ccm.c
 +++ b/net/mac80211/aes_ccm.c
-@@ -19,86 +19,126 @@
+@@ -13,89 +13,132 @@
+ #include <linux/types.h>
+ #include <linux/err.h>
+ #include <crypto/aead.h>
++#include <crypto/aes.h>
+ #include <net/mac80211.h>
  #include "key.h"
  #include "aes_ccm.h"
  
 -void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+-                             u8 *data, size_t data_len, u8 *mic,
+-                             size_t mic_len)
 +static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0,
 +                          u8 *a, u8 *b)
-+{
+ {
+-      struct scatterlist sg[3];
 +      int i;
 +
 +      crypto_cipher_encrypt_one(tfm, b, b_0);
 +      for (i = 0; i < AES_BLOCK_SIZE; i++)
 +              aad[i] ^= b[i];
 +      crypto_cipher_encrypt_one(tfm, a, aad);
-+
+-      char aead_req_data[sizeof(struct aead_request) +
+-                         crypto_aead_reqsize(tfm)]
+-              __aligned(__alignof__(struct aead_request));
+-      struct aead_request *aead_req = (void *) aead_req_data;
 +      /* Mask out bits from auth-only-b_0 */
 +      b_0[0] &= 0x07;
-+
+-      memset(aead_req, 0, sizeof(aead_req_data));
 +      /* S_0 is used to encrypt T (= MIC) */
 +      b_0[14] = 0;
 +      b_0[15] = 0;
 +      crypto_cipher_encrypt_one(tfm, s_0, b_0);
 +}
-+
-+
+-      sg_init_table(sg, 3);
+-      sg_set_buf(&sg[0], &aad[2], be16_to_cpup((__be16 *)aad));
+-      sg_set_buf(&sg[1], data, data_len);
+-      sg_set_buf(&sg[2], mic, mic_len);
+-      aead_request_set_tfm(aead_req, tfm);
+-      aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
+-      aead_request_set_ad(aead_req, sg[0].length);
 +void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
-                              u8 *data, size_t data_len, u8 *mic,
-                              size_t mic_len)
- {
--      struct scatterlist assoc, pt, ct[2];
++                             u8 *data, size_t data_len, u8 *mic,
++                             size_t mic_len)
++{
 +      int i, j, last_len, num_blocks;
 +      u8 b[AES_BLOCK_SIZE];
 +      u8 s_0[AES_BLOCK_SIZE];
 +                      *cpos++ = *pos++ ^ e[i];
 +      }
  
--      char aead_req_data[sizeof(struct aead_request) +
--                         crypto_aead_reqsize(tfm)]
--              __aligned(__alignof__(struct aead_request));
--      struct aead_request *aead_req = (void *) aead_req_data;
--
--      memset(aead_req, 0, sizeof(aead_req_data));
--
--      sg_init_one(&pt, data, data_len);
--      sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
--      sg_init_table(ct, 2);
--      sg_set_buf(&ct[0], data, data_len);
--      sg_set_buf(&ct[1], mic, mic_len);
--
--      aead_request_set_tfm(aead_req, tfm);
--      aead_request_set_assoc(aead_req, &assoc, assoc.length);
--      aead_request_set_crypt(aead_req, &pt, ct, data_len, b_0);
--
 -      crypto_aead_encrypt(aead_req);
 +      for (i = 0; i < mic_len; i++)
 +              mic[i] = b[i] ^ s_0[i];
                              u8 *data, size_t data_len, u8 *mic,
                              size_t mic_len)
  {
--      struct scatterlist assoc, pt, ct[2];
+-      struct scatterlist sg[3];
 -      char aead_req_data[sizeof(struct aead_request) +
 -                         crypto_aead_reqsize(tfm)]
 -              __aligned(__alignof__(struct aead_request));
 -
 -      memset(aead_req, 0, sizeof(aead_req_data));
 -
--      sg_init_one(&pt, data, data_len);
--      sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
--      sg_init_table(ct, 2);
--      sg_set_buf(&ct[0], data, data_len);
--      sg_set_buf(&ct[1], mic, mic_len);
+-      sg_init_table(sg, 3);
+-      sg_set_buf(&sg[0], &aad[2], be16_to_cpup((__be16 *)aad));
+-      sg_set_buf(&sg[1], data, data_len);
+-      sg_set_buf(&sg[2], mic, mic_len);
 -
 -      aead_request_set_tfm(aead_req, tfm);
--      aead_request_set_assoc(aead_req, &assoc, assoc.length);
--      aead_request_set_crypt(aead_req, ct, &pt, data_len + mic_len, b_0);
+-      aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
+-      aead_request_set_ad(aead_req, sg[0].length);
 +      int i, j, last_len, num_blocks;
 +      u8 *pos, *cpos;
 +      u8 a[AES_BLOCK_SIZE];
 -      crypto_free_aead(tfm);
 +      crypto_free_cipher(tfm);
  }
+--- a/net/mac80211/aes_ccm.h
++++ b/net/mac80211/aes_ccm.h
+@@ -12,15 +12,15 @@
+ #include <linux/crypto.h>
+-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
+-                                                  size_t key_len,
+-                                                  size_t mic_len);
+-void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
++struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
++                                                    size_t key_len,
++                                                    size_t mic_len);
++void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
+                              u8 *data, size_t data_len, u8 *mic,
+                              size_t mic_len);
+-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
++int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
+                             u8 *data, size_t data_len, u8 *mic,
+                             size_t mic_len);
+-void ieee80211_aes_key_free(struct crypto_aead *tfm);
++void ieee80211_aes_key_free(struct crypto_cipher *tfm);
+ #endif /* AES_CCM_H */
+--- a/net/mac80211/aes_gcm.h
++++ b/net/mac80211/aes_gcm.h
+@@ -11,12 +11,28 @@
+ #include <linux/crypto.h>
+-void ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
+-                             u8 *data, size_t data_len, u8 *mic);
+-int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
+-                            u8 *data, size_t data_len, u8 *mic);
+-struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
+-                                                      size_t key_len);
+-void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm);
++static inline void
++ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
++                        u8 *data, size_t data_len, u8 *mic)
++{
++}
++
++static inline int
++ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
++                        u8 *data, size_t data_len, u8 *mic)
++{
++    return -EOPNOTSUPP;
++}
++
++static inline struct crypto_aead *
++ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len)
++{
++    return NULL;
++}
++
++static inline void
++ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
++{
++}
+ #endif /* AES_GCM_H */
+--- a/net/mac80211/aes_gmac.h
++++ b/net/mac80211/aes_gmac.h
+@@ -11,10 +11,22 @@
+ #include <linux/crypto.h>
+-struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
+-                                               size_t key_len);
+-int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
+-                     const u8 *data, size_t data_len, u8 *mic);
+-void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm);
++static inline struct crypto_aead *
++ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len)
++{
++      return NULL;
++}
++
++static inline int
++ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
++                 const u8 *data, size_t data_len, u8 *mic)
++{
++      return -EOPNOTSUPP;
++}
++
++static inline void
++ieee80211_aes_gmac_key_free(struct crypto_aead *tfm)
++{
++}
+ #endif /* AES_GMAC_H */
 --- a/net/mac80211/key.h
 +++ b/net/mac80211/key.h
 @@ -84,7 +84,7 @@ struct ieee80211_key {
  
                        if (ieee80211_aes_ccm_decrypt(
                                    key->u.ccmp.tfm, b_0, aad,
---- a/net/mac80211/aes_ccm.h
-+++ b/net/mac80211/aes_ccm.h
-@@ -12,15 +12,15 @@
- #include <linux/crypto.h>
--struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
--                                                  size_t key_len,
--                                                  size_t mic_len);
--void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
-+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
-+                                                    size_t key_len,
-+                                                    size_t mic_len);
-+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
-                              u8 *data, size_t data_len, u8 *mic,
-                              size_t mic_len);
--int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
-+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
-                             u8 *data, size_t data_len, u8 *mic,
-                             size_t mic_len);
--void ieee80211_aes_key_free(struct crypto_aead *tfm);
-+void ieee80211_aes_key_free(struct crypto_cipher *tfm);
- #endif /* AES_CCM_H */
---- a/net/mac80211/Kconfig
-+++ b/net/mac80211/Kconfig
-@@ -5,8 +5,6 @@ config MAC80211
-       depends on CRYPTO
-       depends on CRYPTO_ARC4
-       depends on CRYPTO_AES
--      select BPAUTO_CRYPTO_CCM
--      depends on CRYPTO_GCM
-       depends on CRC32
-       select BPAUTO_AVERAGE
-       ---help---
diff --git a/package/kernel/mac80211/patches/210-ap_scan.patch b/package/kernel/mac80211/patches/210-ap_scan.patch
deleted file mode 100644 (file)
index 29f05c4..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -2008,7 +2008,7 @@ static int ieee80211_scan(struct wiphy *
-                * the  frames sent while scanning on other channel will be
-                * lost)
-                */
--              if (sdata->u.ap.beacon &&
-+              if (0 && sdata->u.ap.beacon &&
-                   (!(wiphy->features & NL80211_FEATURE_AP_SCAN) ||
-                    !(req->flags & NL80211_SCAN_FLAG_AP)))
-                       return -EOPNOTSUPP;
diff --git a/package/kernel/mac80211/patches/301-ath9k-limit-retries-for-powersave-response-frames.patch b/package/kernel/mac80211/patches/301-ath9k-limit-retries-for-powersave-response-frames.patch
new file mode 100644 (file)
index 0000000..4faac0d
--- /dev/null
@@ -0,0 +1,121 @@
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Thu, 2 Jul 2015 15:20:56 +0200
+Subject: [PATCH] ath9k: limit retries for powersave response frames
+
+In some cases, the channel might be busy enough that an ath9k AP's
+response to PS-Poll frames might be too slow and the station has already
+gone to sleep. To avoid wasting too much airtime on this, limit the
+number of retries on such frames and ensure that no sample rate gets
+used.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -147,10 +147,25 @@ static void ath_send_bar(struct ath_atx_
+ }
+ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+-                        struct ath_buf *bf)
++                        struct ath_buf *bf, bool ps)
+ {
++      struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu);
++
++      if (ps) {
++              /* Clear the first rate to avoid using a sample rate for PS frames */
++              info->control.rates[0].idx = -1;
++              info->control.rates[0].count = 0;
++      }
++
+       ieee80211_get_tx_rates(vif, sta, bf->bf_mpdu, bf->rates,
+                              ARRAY_SIZE(bf->rates));
++      if (!ps)
++              return;
++
++      if (bf->rates[0].count > 2)
++              bf->rates[0].count = 2;
++
++      bf->rates[1].idx = -1;
+ }
+ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
+@@ -1430,7 +1445,7 @@ ath_tx_form_burst(struct ath_softc *sc,
+               if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
+                       break;
+-              ath_set_rates(tid->an->vif, tid->an->sta, bf);
++              ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
+       } while (1);
+ }
+@@ -1461,7 +1476,7 @@ static bool ath_tx_sched_aggr(struct ath
+               return false;
+       }
+-      ath_set_rates(tid->an->vif, tid->an->sta, bf);
++      ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
+       if (aggr)
+               last = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf,
+                                       tid_q, &aggr_len);
+@@ -1653,7 +1668,7 @@ void ath9k_release_buffered_frames(struc
+                       __skb_unlink(bf->bf_mpdu, tid_q);
+                       list_add_tail(&bf->list, &bf_q);
+-                      ath_set_rates(tid->an->vif, tid->an->sta, bf);
++                      ath_set_rates(tid->an->vif, tid->an->sta, bf, true);
+                       if (bf_isampdu(bf)) {
+                               ath_tx_addto_baw(sc, tid, bf);
+                               bf->bf_state.bf_type &= ~BUF_AGGR;
+@@ -2318,7 +2333,7 @@ int ath_tx_start(struct ieee80211_hw *hw
+       struct ath_txq *txq = txctl->txq;
+       struct ath_atx_tid *tid = NULL;
+       struct ath_buf *bf;
+-      bool queue, skip_uapsd = false, ps_resp;
++      bool queue, ps_resp;
+       int q, ret;
+       if (vif)
+@@ -2365,13 +2380,13 @@ int ath_tx_start(struct ieee80211_hw *hw
+               if (!txctl->an)
+                       txctl->an = &avp->mcast_node;
+               queue = true;
+-              skip_uapsd = true;
++              ps_resp = false;
+       }
+       if (txctl->an && queue)
+               tid = ath_get_skb_tid(sc, txctl->an, skb);
+-      if (!skip_uapsd && ps_resp) {
++      if (ps_resp) {
+               ath_txq_unlock(sc, txq);
+               txq = sc->tx.uapsdq;
+               ath_txq_lock(sc, txq);
+@@ -2409,7 +2424,7 @@ int ath_tx_start(struct ieee80211_hw *hw
+       if (txctl->paprd)
+               bf->bf_state.bfs_paprd_timestamp = jiffies;
+-      ath_set_rates(vif, sta, bf);
++      ath_set_rates(vif, sta, bf, ps_resp);
+       ath_tx_send_normal(sc, txq, tid, skb);
+ out:
+@@ -2448,7 +2463,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw
+                       break;
+               bf->bf_lastbf = bf;
+-              ath_set_rates(vif, NULL, bf);
++              ath_set_rates(vif, NULL, bf, false);
+               ath_buf_set_rate(sc, bf, &info, fi->framelen, false);
+               duration += info.rates[0].PktDuration;
+               if (bf_tail)
+@@ -2968,7 +2983,7 @@ int ath9k_tx99_send(struct ath_softc *sc
+               return -EINVAL;
+       }
+-      ath_set_rates(sc->tx99_vif, NULL, bf);
++      ath_set_rates(sc->tx99_vif, NULL, bf, false);
+       ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, bf->bf_daddr);
+       ath9k_hw_tx99_start(sc->sc_ah, txctl->txq->axq_qnum);
diff --git a/package/kernel/mac80211/patches/301-ath9k_hw-fix-device-ID-check-for-AR956x.patch b/package/kernel/mac80211/patches/301-ath9k_hw-fix-device-ID-check-for-AR956x.patch
deleted file mode 100644 (file)
index 5998be8..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Sun, 21 Jun 2015 19:45:59 +0200
-Subject: [PATCH] ath9k_hw: fix device ID check for AR956x
-
-Because of the missing return, the macVersion value was being
-overwritten with an invalid register read
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -279,6 +279,7 @@ static void ath9k_hw_read_revisions(stru
-               return;
-       case AR9300_DEVID_QCA956X:
-               ah->hw_version.macVersion = AR_SREV_VERSION_9561;
-+              return;
-       }
-       val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
-@@ -3169,6 +3170,7 @@ static struct {
-       { AR_SREV_VERSION_9550,         "9550" },
-       { AR_SREV_VERSION_9565,         "9565" },
-       { AR_SREV_VERSION_9531,         "9531" },
-+      { AR_SREV_VERSION_9561,         "956X" },
- };
- /* For devices with external radios */
diff --git a/package/kernel/mac80211/patches/302-ath-DFS-limit-number-of-potential-PRI-sequences.patch b/package/kernel/mac80211/patches/302-ath-DFS-limit-number-of-potential-PRI-sequences.patch
deleted file mode 100644 (file)
index e403e6a..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
-Date: Tue, 16 Jun 2015 10:34:03 +0200
-Subject: [PATCH] ath: DFS - limit number of potential PRI sequences
-
-In the PRI detector, after the current radar pulse
-has been checked agains existing PRI sequences, it
-is considered as part of a new potential sequence.
-
-Previously, the condition to accept a new sequence
-was to have at least the same number of pulses as
-the longest matching sequence. This was wrong,
-since it led to duplicates of PRI sequences.
-
-This patch changes the acceptance criteria for new
-potential sequences from 'at least' to 'more than'
-the longest existing.
-
-Detection performance remains unaffected, while
-the number of PRI sequences accounted at runtime
-(and with it CPU load) is reduced by up to 50%.
-
-Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
----
-
---- a/drivers/net/wireless/ath/dfs_pri_detector.c
-+++ b/drivers/net/wireless/ath/dfs_pri_detector.c
-@@ -273,7 +273,7 @@ static bool pseq_handler_create_sequence
-                               tmp_false_count++;
-                       }
-               }
--              if (ps.count < min_count)
-+              if (ps.count <= min_count)
-                       /* did not reach minimum count, drop sequence */
-                       continue;
diff --git a/package/kernel/mac80211/patches/302-ath10k-Delay-device-access-after-cold-reset.patch b/package/kernel/mac80211/patches/302-ath10k-Delay-device-access-after-cold-reset.patch
new file mode 100644 (file)
index 0000000..820aa9a
--- /dev/null
@@ -0,0 +1,56 @@
+From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+Date: Fri, 3 Jul 2015 11:45:42 +0530
+Subject: [PATCH] ath10k: Delay device access after cold reset
+
+It is observed that during cold reset pcie access right
+after a write operation to SOC_GLOBAL_RESET_ADDRESS causes
+Data Bus Error and system hard lockup. The reason
+for bus error is that pcie needs some time to get
+back to stable state for any transaction during cold reset. Add
+delay of 20 msecs after write of SOC_GLOBAL_RESET_ADDRESS
+to fix this issue.
+
+Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/pci.c
++++ b/drivers/net/wireless/ath/ath10k/pci.c
+@@ -2761,7 +2761,6 @@ static int ath10k_pci_wait_for_target_in
+ static int ath10k_pci_cold_reset(struct ath10k *ar)
+ {
+-      int i;
+       u32 val;
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cold reset\n");
+@@ -2777,23 +2776,18 @@ static int ath10k_pci_cold_reset(struct
+       val |= 1;
+       ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
+-      for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
+-              if (ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) &
+-                                        RTC_STATE_COLD_RESET_MASK)
+-                      break;
+-              msleep(1);
+-      }
++      /* After writing into SOC_GLOBAL_RESET to put device into
++       * reset and pulling out of reset pcie may not be stable
++       * for any immediate pcie register access and cause bus error,
++       * add delay before any pcie access request to fix this issue.
++       */
++      msleep(20);
+       /* Pull Target, including PCIe, out of RESET. */
+       val &= ~1;
+       ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
+-      for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
+-              if (!(ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) &
+-                                          RTC_STATE_COLD_RESET_MASK))
+-                      break;
+-              msleep(1);
+-      }
++      msleep(20);
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cold reset complete\n");
diff --git a/package/kernel/mac80211/patches/303-ath9k-DFS-consider-ext_channel-pulses-only-in-HT40-m.patch b/package/kernel/mac80211/patches/303-ath9k-DFS-consider-ext_channel-pulses-only-in-HT40-m.patch
deleted file mode 100644 (file)
index 07f5e3b..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
-Date: Tue, 16 Jun 2015 11:46:42 +0200
-Subject: [PATCH] ath9k: DFS - consider ext_channel pulses only in HT40
- mode
-
-The chip reports radar pulses on extension channel
-even if operating in HT20 mode. This patch adds a
-sanity check for HT40 mode before it feeds pulses
-on extension channel to the pattern detector.
-
-Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
----
-
---- a/drivers/net/wireless/ath/ath9k/dfs.c
-+++ b/drivers/net/wireless/ath/ath9k/dfs.c
-@@ -198,7 +198,8 @@ void ath9k_dfs_process_phyerr(struct ath
-       sc->dfs_prev_pulse_ts = pe.ts;
-       if (ard.pulse_bw_info & PRI_CH_RADAR_FOUND)
-               ath9k_dfs_process_radar_pulse(sc, &pe);
--      if (ard.pulse_bw_info & EXT_CH_RADAR_FOUND) {
-+      if (IS_CHAN_HT40(ah->curchan) &&
-+          ard.pulse_bw_info & EXT_CH_RADAR_FOUND) {
-               pe.freq += IS_CHAN_HT40PLUS(ah->curchan) ? 20 : -20;
-               ath9k_dfs_process_radar_pulse(sc, &pe);
-       }
diff --git a/package/kernel/mac80211/patches/303-ath9k-add-fast-xmit-support.patch b/package/kernel/mac80211/patches/303-ath9k-add-fast-xmit-support.patch
new file mode 100644 (file)
index 0000000..139015c
--- /dev/null
@@ -0,0 +1,17 @@
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Mon, 11 May 2015 18:35:20 +0200
+Subject: [PATCH] ath9k: add fast-xmit support
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -826,6 +826,7 @@ static void ath9k_set_hw_capab(struct at
+       ieee80211_hw_set(hw, SIGNAL_DBM);
+       ieee80211_hw_set(hw, RX_INCLUDES_FCS);
+       ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
++      ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
+       if (ath9k_ps_enable)
+               ieee80211_hw_set(hw, SUPPORTS_PS);
diff --git a/package/kernel/mac80211/patches/304-ath9k-DFS-add-pulse-chirp-detection-for-FCC.patch b/package/kernel/mac80211/patches/304-ath9k-DFS-add-pulse-chirp-detection-for-FCC.patch
deleted file mode 100644 (file)
index 3437f13..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
-Date: Tue, 16 Jun 2015 12:52:16 +0200
-Subject: [PATCH] ath9k: DFS - add pulse chirp detection for FCC
-
-FCC long pulse radar (type 5) requires pulses to be
-checked for chirping. This patch implements chirp
-detection based on the FFT data provided for long
-pulses.
-
-A chirp is detected when a set of criteria defined
-by FCC pulse characteristics is met, including
-* have at least 4 FFT samples
-* max_bin index moves equidistantly between samples
-* the gradient is within defined range
-
-The chirp detection has been tested with reference
-radar generating devices and proved to work reliably.
-
-Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
----
-
---- a/drivers/net/wireless/ath/ath9k/dfs.c
-+++ b/drivers/net/wireless/ath/ath9k/dfs.c
-@@ -30,6 +30,157 @@ struct ath_radar_data {
-       u8 pulse_length_pri;
- };
-+/**** begin: CHIRP ************************************************************/
-+
-+/* min and max gradients for defined FCC chirping pulses, given by
-+ * - 20MHz chirp width over a pulse width of  50us
-+ * -  5MHz chirp width over a pulse width of 100us
-+ */
-+static const int BIN_DELTA_MIN                = 1;
-+static const int BIN_DELTA_MAX                = 10;
-+
-+/* we need at least 3 deltas / 4 samples for a reliable chirp detection */
-+#define NUM_DIFFS 3
-+static const int FFT_NUM_SAMPLES      = (NUM_DIFFS + 1);
-+
-+/* Threshold for difference of delta peaks */
-+static const int MAX_DIFF             = 2;
-+
-+/* width range to be checked for chirping */
-+static const int MIN_CHIRP_PULSE_WIDTH        = 20;
-+static const int MAX_CHIRP_PULSE_WIDTH        = 110;
-+
-+struct ath9k_dfs_fft_20 {
-+      u8 bin[28];
-+      u8 lower_bins[3];
-+} __packed;
-+struct ath9k_dfs_fft_40 {
-+      u8 bin[64];
-+      u8 lower_bins[3];
-+      u8 upper_bins[3];
-+} __packed;
-+
-+static inline int fft_max_index(u8 *bins)
-+{
-+      return (bins[2] & 0xfc) >> 2;
-+}
-+static inline int fft_max_magnitude(u8 *bins)
-+{
-+      return (bins[0] & 0xc0) >> 6 | bins[1] << 2 | (bins[2] & 0x03) << 10;
-+}
-+static inline u8 fft_bitmap_weight(u8 *bins)
-+{
-+      return bins[0] & 0x3f;
-+}
-+
-+static int ath9k_get_max_index_ht40(struct ath9k_dfs_fft_40 *fft,
-+                                  bool is_ctl, bool is_ext)
-+{
-+      const int DFS_UPPER_BIN_OFFSET = 64;
-+      /* if detected radar on both channels, select the significant one */
-+      if (is_ctl && is_ext) {
-+              /* first check wether channels have 'strong' bins */
-+              is_ctl = fft_bitmap_weight(fft->lower_bins) != 0;
-+              is_ext = fft_bitmap_weight(fft->upper_bins) != 0;
-+
-+              /* if still unclear, take higher magnitude */
-+              if (is_ctl && is_ext) {
-+                      int mag_lower = fft_max_magnitude(fft->lower_bins);
-+                      int mag_upper = fft_max_magnitude(fft->upper_bins);
-+                      if (mag_upper > mag_lower)
-+                              is_ctl = false;
-+                      else
-+                              is_ext = false;
-+              }
-+      }
-+      if (is_ctl)
-+              return fft_max_index(fft->lower_bins);
-+      return fft_max_index(fft->upper_bins) + DFS_UPPER_BIN_OFFSET;
-+}
-+static bool ath9k_check_chirping(struct ath_softc *sc, u8 *data,
-+                               int datalen, bool is_ctl, bool is_ext)
-+{
-+      int i;
-+      int max_bin[FFT_NUM_SAMPLES];
-+      struct ath_hw *ah = sc->sc_ah;
-+      struct ath_common *common = ath9k_hw_common(ah);
-+      int prev_delta;
-+
-+      if (IS_CHAN_HT40(ah->curchan)) {
-+              struct ath9k_dfs_fft_40 *fft = (struct ath9k_dfs_fft_40 *) data;
-+              int num_fft_packets = datalen / sizeof(*fft);
-+              if (num_fft_packets == 0)
-+                      return false;
-+
-+              ath_dbg(common, DFS, "HT40: datalen=%d, num_fft_packets=%d\n",
-+                      datalen, num_fft_packets);
-+              if (num_fft_packets < (FFT_NUM_SAMPLES)) {
-+                      ath_dbg(common, DFS, "not enough packets for chirp\n");
-+                      return false;
-+              }
-+              /* HW sometimes adds 2 garbage bytes in front of FFT samples */
-+              if ((datalen % sizeof(*fft)) == 2) {
-+                      fft = (struct ath9k_dfs_fft_40 *) (data + 2);
-+                      ath_dbg(common, DFS, "fixing datalen by 2\n");
-+              }
-+              if (IS_CHAN_HT40MINUS(ah->curchan)) {
-+                      int temp = is_ctl;
-+                      is_ctl = is_ext;
-+                      is_ext = temp;
-+              }
-+              for (i = 0; i < FFT_NUM_SAMPLES; i++)
-+                      max_bin[i] = ath9k_get_max_index_ht40(fft + i, is_ctl,
-+                                                            is_ext);
-+      } else {
-+              struct ath9k_dfs_fft_20 *fft = (struct ath9k_dfs_fft_20 *) data;
-+              int num_fft_packets = datalen / sizeof(*fft);
-+              if (num_fft_packets == 0)
-+                      return false;
-+              ath_dbg(common, DFS, "HT20: datalen=%d, num_fft_packets=%d\n",
-+                      datalen, num_fft_packets);
-+              if (num_fft_packets < (FFT_NUM_SAMPLES)) {
-+                      ath_dbg(common, DFS, "not enough packets for chirp\n");
-+                      return false;
-+              }
-+              /* in ht20, this is a 6-bit signed number => shift it to 0 */
-+              for (i = 0; i < FFT_NUM_SAMPLES; i++)
-+                      max_bin[i] = fft_max_index(fft[i].lower_bins) ^ 0x20;
-+      }
-+      ath_dbg(common, DFS, "bin_max = [%d, %d, %d, %d]\n",
-+              max_bin[0], max_bin[1], max_bin[2], max_bin[3]);
-+
-+      /* Check for chirp attributes within specs
-+       * a) delta of adjacent max_bins is within range
-+       * b) delta of adjacent deltas are within tolerance
-+       */
-+      prev_delta = 0;
-+      for (i = 0; i < NUM_DIFFS; i++) {
-+              int ddelta = -1;
-+              int delta = max_bin[i + 1] - max_bin[i];
-+
-+              /* ensure gradient is within valid range */
-+              if (abs(delta) < BIN_DELTA_MIN || abs(delta) > BIN_DELTA_MAX) {
-+                      ath_dbg(common, DFS, "CHIRP: invalid delta %d "
-+                              "in sample %d\n", delta, i);
-+                      return false;
-+              }
-+              if (i == 0)
-+                      goto done;
-+              ddelta = delta - prev_delta;
-+              if (abs(ddelta) > MAX_DIFF) {
-+                      ath_dbg(common, DFS, "CHIRP: ddelta %d too high\n",
-+                              ddelta);
-+                      return false;
-+              }
-+done:
-+              ath_dbg(common, DFS, "CHIRP - %d: delta=%d, ddelta=%d\n",
-+                      i, delta, ddelta);
-+              prev_delta = delta;
-+      }
-+      return true;
-+}
-+/**** end: CHIRP **************************************************************/
-+
- /* convert pulse duration to usecs, considering clock mode */
- static u32 dur_to_usecs(struct ath_hw *ah, u32 dur)
- {
-@@ -113,12 +264,6 @@ ath9k_postprocess_radar_event(struct ath
-               return false;
-       }
--      /*
--       * TODO: check chirping pulses
--       *       checks for chirping are dependent on the DFS regulatory domain
--       *       used, which is yet TBD
--       */
--
-       /* convert duration to usecs */
-       pe->width = dur_to_usecs(sc->sc_ah, dur);
-       pe->rssi = rssi;
-@@ -190,6 +335,16 @@ void ath9k_dfs_process_phyerr(struct ath
-       if (!ath9k_postprocess_radar_event(sc, &ard, &pe))
-               return;
-+      if (pe.width > MIN_CHIRP_PULSE_WIDTH &&
-+          pe.width < MAX_CHIRP_PULSE_WIDTH) {
-+              bool is_ctl = !!(ard.pulse_bw_info & PRI_CH_RADAR_FOUND);
-+              bool is_ext = !!(ard.pulse_bw_info & EXT_CH_RADAR_FOUND);
-+              int clen = datalen - 3;
-+              pe.chirp = ath9k_check_chirping(sc, data, clen, is_ctl, is_ext);
-+      } else {
-+              pe.chirp = false;
-+      }
-+
-       ath_dbg(common, DFS,
-               "ath9k_dfs_process_phyerr: type=%d, freq=%d, ts=%llu, "
-               "width=%d, rssi=%d, delta_ts=%llu\n",
diff --git a/package/kernel/mac80211/patches/304-ath9k-remove-struct-ath_atx_ac.patch b/package/kernel/mac80211/patches/304-ath9k-remove-struct-ath_atx_ac.patch
new file mode 100644 (file)
index 0000000..9f04276
--- /dev/null
@@ -0,0 +1,385 @@
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Sat, 4 Apr 2015 18:39:06 +0200
+Subject: [PATCH] ath9k: remove struct ath_atx_ac
+
+struct ath_atx_ac contains a list of active TIDs belonging to one WMM AC.
+This patch changes the code to track active station TIDs in the txq directly.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -173,14 +173,6 @@ struct ath_txq {
+       struct sk_buff_head complete_q;
+ };
+-struct ath_atx_ac {
+-      struct ath_txq *txq;
+-      struct list_head list;
+-      struct list_head tid_q;
+-      bool clear_ps_filter;
+-      bool sched;
+-};
+-
+ struct ath_frame_info {
+       struct ath_buf *bf;
+       u16 framelen;
+@@ -243,7 +235,7 @@ struct ath_atx_tid {
+       struct sk_buff_head buf_q;
+       struct sk_buff_head retry_q;
+       struct ath_node *an;
+-      struct ath_atx_ac *ac;
++      struct ath_txq *txq;
+       unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
+       u16 seq_start;
+       u16 seq_next;
+@@ -255,6 +247,7 @@ struct ath_atx_tid {
+       s8 bar_index;
+       bool sched;
+       bool active;
++      bool clear_ps_filter;
+ };
+ struct ath_node {
+@@ -262,7 +255,6 @@ struct ath_node {
+       struct ieee80211_sta *sta; /* station struct we're part of */
+       struct ieee80211_vif *vif; /* interface with which we're associated */
+       struct ath_atx_tid tid[IEEE80211_NUM_TIDS];
+-      struct ath_atx_ac ac[IEEE80211_NUM_ACS];
+       u16 maxampdu;
+       u8 mpdudensity;
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -106,7 +106,6 @@ void ath_txq_unlock_complete(struct ath_
+ static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq,
+                            struct ath_atx_tid *tid)
+ {
+-      struct ath_atx_ac *ac = tid->ac;
+       struct list_head *list;
+       struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv;
+       struct ath_chanctx *ctx = avp->chanctx;
+@@ -118,15 +117,8 @@ static void ath_tx_queue_tid(struct ath_
+               return;
+       tid->sched = true;
+-      list_add_tail(&tid->list, &ac->tid_q);
+-
+-      if (ac->sched)
+-              return;
+-
+-      ac->sched = true;
+-
+       list = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
+-      list_add_tail(&ac->list, list);
++      list_add_tail(&tid->list, list);
+ }
+ static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
+@@ -223,7 +215,7 @@ static struct sk_buff *ath_tid_dequeue(s
+ static void
+ ath_tx_tid_change_state(struct ath_softc *sc, struct ath_atx_tid *tid)
+ {
+-      struct ath_txq *txq = tid->ac->txq;
++      struct ath_txq *txq = tid->txq;
+       struct ieee80211_tx_info *tx_info;
+       struct sk_buff *skb, *tskb;
+       struct ath_buf *bf;
+@@ -252,7 +244,7 @@ ath_tx_tid_change_state(struct ath_softc
+ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+ {
+-      struct ath_txq *txq = tid->ac->txq;
++      struct ath_txq *txq = tid->txq;
+       struct sk_buff *skb;
+       struct ath_buf *bf;
+       struct list_head bf_head;
+@@ -659,7 +651,7 @@ static void ath_tx_complete_aggr(struct
+                       ath_tx_queue_tid(sc, txq, tid);
+                       if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
+-                              tid->ac->clear_ps_filter = true;
++                              tid->clear_ps_filter = true;
+               }
+       }
+@@ -749,7 +741,7 @@ static u32 ath_lookup_rate(struct ath_so
+       struct ieee80211_tx_rate *rates;
+       u32 max_4ms_framelen, frmlen;
+       u16 aggr_limit, bt_aggr_limit, legacy = 0;
+-      int q = tid->ac->txq->mac80211_qnum;
++      int q = tid->txq->mac80211_qnum;
+       int i;
+       skb = bf->bf_mpdu;
+@@ -1486,8 +1478,8 @@ static bool ath_tx_sched_aggr(struct ath
+       if (list_empty(&bf_q))
+               return false;
+-      if (tid->ac->clear_ps_filter || tid->an->no_ps_filter) {
+-              tid->ac->clear_ps_filter = false;
++      if (tid->clear_ps_filter || tid->an->no_ps_filter) {
++              tid->clear_ps_filter = false;
+               tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
+       }
+@@ -1506,7 +1498,7 @@ int ath_tx_aggr_start(struct ath_softc *
+       an = (struct ath_node *)sta->drv_priv;
+       txtid = ATH_AN_2_TID(an, tid);
+-      txq = txtid->ac->txq;
++      txq = txtid->txq;
+       ath_txq_lock(sc, txq);
+@@ -1540,7 +1532,7 @@ void ath_tx_aggr_stop(struct ath_softc *
+ {
+       struct ath_node *an = (struct ath_node *)sta->drv_priv;
+       struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
+-      struct ath_txq *txq = txtid->ac->txq;
++      struct ath_txq *txq = txtid->txq;
+       ath_txq_lock(sc, txq);
+       txtid->active = false;
+@@ -1553,7 +1545,6 @@ void ath_tx_aggr_sleep(struct ieee80211_
+                      struct ath_node *an)
+ {
+       struct ath_atx_tid *tid;
+-      struct ath_atx_ac *ac;
+       struct ath_txq *txq;
+       bool buffered;
+       int tidno;
+@@ -1561,8 +1552,7 @@ void ath_tx_aggr_sleep(struct ieee80211_
+       for (tidno = 0, tid = &an->tid[tidno];
+            tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
+-              ac = tid->ac;
+-              txq = ac->txq;
++              txq = tid->txq;
+               ath_txq_lock(sc, txq);
+@@ -1576,11 +1566,6 @@ void ath_tx_aggr_sleep(struct ieee80211_
+               tid->sched = false;
+               list_del(&tid->list);
+-              if (ac->sched) {
+-                      ac->sched = false;
+-                      list_del(&ac->list);
+-              }
+-
+               ath_txq_unlock(sc, txq);
+               ieee80211_sta_set_buffered(sta, tidno, buffered);
+@@ -1590,18 +1575,16 @@ void ath_tx_aggr_sleep(struct ieee80211_
+ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
+ {
+       struct ath_atx_tid *tid;
+-      struct ath_atx_ac *ac;
+       struct ath_txq *txq;
+       int tidno;
+       for (tidno = 0, tid = &an->tid[tidno];
+            tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
+-              ac = tid->ac;
+-              txq = ac->txq;
++              txq = tid->txq;
+               ath_txq_lock(sc, txq);
+-              ac->clear_ps_filter = true;
++              tid->clear_ps_filter = true;
+               if (ath_tid_has_buffered(tid)) {
+                       ath_tx_queue_tid(sc, txq, tid);
+@@ -1621,7 +1604,7 @@ void ath_tx_aggr_resume(struct ath_softc
+       an = (struct ath_node *)sta->drv_priv;
+       tid = ATH_AN_2_TID(an, tidno);
+-      txq = tid->ac->txq;
++      txq = tid->txq;
+       ath_txq_lock(sc, txq);
+@@ -1660,7 +1643,7 @@ void ath9k_release_buffered_frames(struc
+               tid = ATH_AN_2_TID(an, i);
+-              ath_txq_lock(sc, tid->ac->txq);
++              ath_txq_lock(sc, tid->txq);
+               while (nframes > 0) {
+                       bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid, &tid_q);
+                       if (!bf)
+@@ -1684,7 +1667,7 @@ void ath9k_release_buffered_frames(struc
+                       if (an->sta && !ath_tid_has_buffered(tid))
+                               ieee80211_sta_set_buffered(an->sta, i, false);
+               }
+-              ath_txq_unlock_complete(sc, tid->ac->txq);
++              ath_txq_unlock_complete(sc, tid->txq);
+       }
+       if (list_empty(&bf_q))
+@@ -1933,9 +1916,8 @@ void ath_tx_cleanupq(struct ath_softc *s
+ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
+ {
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+-      struct ath_atx_ac *ac, *last_ac;
+       struct ath_atx_tid *tid, *last_tid;
+-      struct list_head *ac_list;
++      struct list_head *tid_list;
+       bool sent = false;
+       if (txq->mac80211_qnum < 0)
+@@ -1945,63 +1927,46 @@ void ath_txq_schedule(struct ath_softc *
+               return;
+       spin_lock_bh(&sc->chan_lock);
+-      ac_list = &sc->cur_chan->acq[txq->mac80211_qnum];
++      tid_list = &sc->cur_chan->acq[txq->mac80211_qnum];
+-      if (list_empty(ac_list)) {
++      if (list_empty(tid_list)) {
+               spin_unlock_bh(&sc->chan_lock);
+               return;
+       }
+       rcu_read_lock();
+-      last_ac = list_entry(ac_list->prev, struct ath_atx_ac, list);
+-      while (!list_empty(ac_list)) {
++      last_tid = list_entry(tid_list->prev, struct ath_atx_tid, list);
++      while (!list_empty(tid_list)) {
+               bool stop = false;
+               if (sc->cur_chan->stopped)
+                       break;
+-              ac = list_first_entry(ac_list, struct ath_atx_ac, list);
+-              last_tid = list_entry(ac->tid_q.prev, struct ath_atx_tid, list);
+-              list_del(&ac->list);
+-              ac->sched = false;
+-
+-              while (!list_empty(&ac->tid_q)) {
+-
+-                      tid = list_first_entry(&ac->tid_q, struct ath_atx_tid,
+-                                             list);
+-                      list_del(&tid->list);
+-                      tid->sched = false;
+-
+-                      if (ath_tx_sched_aggr(sc, txq, tid, &stop))
+-                              sent = true;
+-
+-                      /*
+-                       * add tid to round-robin queue if more frames
+-                       * are pending for the tid
+-                       */
+-                      if (ath_tid_has_buffered(tid))
+-                              ath_tx_queue_tid(sc, txq, tid);
++              tid = list_first_entry(tid_list, struct ath_atx_tid, list);
++              list_del(&tid->list);
++              tid->sched = false;
+-                      if (stop || tid == last_tid)
+-                              break;
+-              }
++              if (ath_tx_sched_aggr(sc, txq, tid, &stop))
++                      sent = true;
+-              if (!list_empty(&ac->tid_q) && !ac->sched) {
+-                      ac->sched = true;
+-                      list_add_tail(&ac->list, ac_list);
+-              }
++              /*
++               * add tid to round-robin queue if more frames
++               * are pending for the tid
++               */
++              if (ath_tid_has_buffered(tid))
++                      ath_tx_queue_tid(sc, txq, tid);
+               if (stop)
+                       break;
+-              if (ac == last_ac) {
++              if (tid == last_tid) {
+                       if (!sent)
+                               break;
+                       sent = false;
+-                      last_ac = list_entry(ac_list->prev,
+-                                           struct ath_atx_ac, list);
++                      last_tid = list_entry(tid_list->prev,
++                                            struct ath_atx_tid, list);
+               }
+       }
+@@ -2391,10 +2356,10 @@ int ath_tx_start(struct ieee80211_hw *hw
+               txq = sc->tx.uapsdq;
+               ath_txq_lock(sc, txq);
+       } else if (txctl->an && queue) {
+-              WARN_ON(tid->ac->txq != txctl->txq);
++              WARN_ON(tid->txq != txctl->txq);
+               if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
+-                      tid->ac->clear_ps_filter = true;
++                      tid->clear_ps_filter = true;
+               /*
+                * Add this frame to software queue for scheduling later
+@@ -2888,7 +2853,6 @@ int ath_tx_init(struct ath_softc *sc, in
+ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
+ {
+       struct ath_atx_tid *tid;
+-      struct ath_atx_ac *ac;
+       int tidno, acno;
+       for (tidno = 0, tid = &an->tid[tidno];
+@@ -2901,24 +2865,16 @@ void ath_tx_node_init(struct ath_softc *
+               tid->baw_head  = tid->baw_tail = 0;
+               tid->sched     = false;
+               tid->active        = false;
++              tid->clear_ps_filter = true;
+               __skb_queue_head_init(&tid->buf_q);
+               __skb_queue_head_init(&tid->retry_q);
+               acno = TID_TO_WME_AC(tidno);
+-              tid->ac = &an->ac[acno];
+-      }
+-
+-      for (acno = 0, ac = &an->ac[acno];
+-           acno < IEEE80211_NUM_ACS; acno++, ac++) {
+-              ac->sched    = false;
+-              ac->clear_ps_filter = true;
+-              ac->txq = sc->tx.txq_map[acno];
+-              INIT_LIST_HEAD(&ac->tid_q);
++              tid->txq = sc->tx.txq_map[acno];
+       }
+ }
+ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
+ {
+-      struct ath_atx_ac *ac;
+       struct ath_atx_tid *tid;
+       struct ath_txq *txq;
+       int tidno;
+@@ -2926,8 +2882,7 @@ void ath_tx_node_cleanup(struct ath_soft
+       for (tidno = 0, tid = &an->tid[tidno];
+            tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
+-              ac = tid->ac;
+-              txq = ac->txq;
++              txq = tid->txq;
+               ath_txq_lock(sc, txq);
+@@ -2936,11 +2891,6 @@ void ath_tx_node_cleanup(struct ath_soft
+                       tid->sched = false;
+               }
+-              if (ac->sched) {
+-                      list_del(&ac->list);
+-                      tid->ac->sched = false;
+-              }
+-
+               ath_tid_drain(sc, txq, tid);
+               tid->active = false;
diff --git a/package/kernel/mac80211/patches/305-ath9k-make-DMA-stop-related-messages-debug-only.patch b/package/kernel/mac80211/patches/305-ath9k-make-DMA-stop-related-messages-debug-only.patch
deleted file mode 100644 (file)
index c4f394d..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Thu, 2 Jul 2015 13:35:05 +0200
-Subject: [PATCH] ath9k: make DMA stop related messages debug-only
-
-A long time ago, ath9k had issues during reset where the DMA engine
-would stay active and could potentially corrupt memory.
-To debug those issues, the driver would print warnings whenever they
-occur.
-
-Nowadays, these issues are gone and the primary cause of these messages
-is if the MAC is stuck during reset or busy processing a long
-transmission. This is fairly harmless, yet these messages continue to
-worry users.
-
-To reduce the number of bogus bug reports, turn these messages into
-debug messages and count their occurence in the "reset" debugfs file.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -765,6 +765,8 @@ static int read_file_reset(struct seq_fi
-               [RESET_TYPE_BEACON_STUCK] = "Stuck Beacon",
-               [RESET_TYPE_MCI] = "MCI Reset",
-               [RESET_TYPE_CALIBRATION] = "Calibration error",
-+              [RESET_TX_DMA_ERROR] = "Tx DMA stop error",
-+              [RESET_RX_DMA_ERROR] = "Rx DMA stop error",
-       };
-       int i;
---- a/drivers/net/wireless/ath/ath9k/debug.h
-+++ b/drivers/net/wireless/ath/ath9k/debug.h
-@@ -50,6 +50,8 @@ enum ath_reset_type {
-       RESET_TYPE_BEACON_STUCK,
-       RESET_TYPE_MCI,
-       RESET_TYPE_CALIBRATION,
-+      RESET_TX_DMA_ERROR,
-+      RESET_RX_DMA_ERROR,
-       __RESET_TYPE_MAX
- };
---- a/drivers/net/wireless/ath/ath9k/recv.c
-+++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -491,10 +491,9 @@ bool ath_stoprecv(struct ath_softc *sc)
-       if (!(ah->ah_flags & AH_UNPLUGGED) &&
-           unlikely(!stopped)) {
--              ath_err(ath9k_hw_common(sc->sc_ah),
--                      "Could not stop RX, we could be "
--                      "confusing the DMA engine when we start RX up\n");
--              ATH_DBG_WARN_ON_ONCE(!stopped);
-+              ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
-+                      "Failed to stop Rx DMA\n");
-+              RESET_STAT_INC(sc, RESET_RX_DMA_ERROR);
-       }
-       return stopped && !reset;
- }
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -1883,8 +1883,11 @@ bool ath_drain_all_txq(struct ath_softc
-                       npend |= BIT(i);
-       }
--      if (npend)
--              ath_err(common, "Failed to stop TX DMA, queues=0x%03x!\n", npend);
-+      if (npend) {
-+              RESET_STAT_INC(sc, RESET_TX_DMA_ERROR);
-+              ath_dbg(common, RESET,
-+                      "Failed to stop TX DMA, queues=0x%03x!\n", npend);
-+      }
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-               if (!ATH_TXQ_SETUP(sc, i))
diff --git a/package/kernel/mac80211/patches/305-ath9k-remove-the-sched-field-in-struct-ath_atx_tid.patch b/package/kernel/mac80211/patches/305-ath9k-remove-the-sched-field-in-struct-ath_atx_tid.patch
new file mode 100644 (file)
index 0000000..ec860dc
--- /dev/null
@@ -0,0 +1,90 @@
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Sat, 4 Apr 2015 18:42:33 +0200
+Subject: [PATCH] ath9k: remove the sched field in struct ath_atx_tid
+
+Use list_empty(&tid->list) instead
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -245,7 +245,6 @@ struct ath_atx_tid {
+       int baw_tail;   /* next unused tx buffer slot */
+       s8 bar_index;
+-      bool sched;
+       bool active;
+       bool clear_ps_filter;
+ };
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -113,12 +113,9 @@ static void ath_tx_queue_tid(struct ath_
+       if (!ctx)
+               return;
+-      if (tid->sched)
+-              return;
+-
+-      tid->sched = true;
+       list = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
+-      list_add_tail(&tid->list, list);
++      if (list_empty(&tid->list))
++              list_add_tail(&tid->list, list);
+ }
+ static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
+@@ -1556,15 +1553,14 @@ void ath_tx_aggr_sleep(struct ieee80211_
+               ath_txq_lock(sc, txq);
+-              if (!tid->sched) {
++              if (list_empty(&tid->list)) {
+                       ath_txq_unlock(sc, txq);
+                       continue;
+               }
+               buffered = ath_tid_has_buffered(tid);
+-              tid->sched = false;
+-              list_del(&tid->list);
++              list_del_init(&tid->list);
+               ath_txq_unlock(sc, txq);
+@@ -1944,8 +1940,7 @@ void ath_txq_schedule(struct ath_softc *
+                       break;
+               tid = list_first_entry(tid_list, struct ath_atx_tid, list);
+-              list_del(&tid->list);
+-              tid->sched = false;
++              list_del_init(&tid->list);
+               if (ath_tx_sched_aggr(sc, txq, tid, &stop))
+                       sent = true;
+@@ -2863,11 +2858,11 @@ void ath_tx_node_init(struct ath_softc *
+               tid->seq_start = tid->seq_next = 0;
+               tid->baw_size  = WME_MAX_BA;
+               tid->baw_head  = tid->baw_tail = 0;
+-              tid->sched     = false;
+               tid->active        = false;
+               tid->clear_ps_filter = true;
+               __skb_queue_head_init(&tid->buf_q);
+               __skb_queue_head_init(&tid->retry_q);
++              INIT_LIST_HEAD(&tid->list);
+               acno = TID_TO_WME_AC(tidno);
+               tid->txq = sc->tx.txq_map[acno];
+       }
+@@ -2886,10 +2881,8 @@ void ath_tx_node_cleanup(struct ath_soft
+               ath_txq_lock(sc, txq);
+-              if (tid->sched) {
+-                      list_del(&tid->list);
+-                      tid->sched = false;
+-              }
++              if (!list_empty(&tid->list))
++                      list_del_init(&tid->list);
+               ath_tid_drain(sc, txq, tid);
+               tid->active = false;
diff --git a/package/kernel/mac80211/patches/306-ath9k-limit-retries-for-powersave-response-frames.patch b/package/kernel/mac80211/patches/306-ath9k-limit-retries-for-powersave-response-frames.patch
deleted file mode 100644 (file)
index 4faac0d..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Thu, 2 Jul 2015 15:20:56 +0200
-Subject: [PATCH] ath9k: limit retries for powersave response frames
-
-In some cases, the channel might be busy enough that an ath9k AP's
-response to PS-Poll frames might be too slow and the station has already
-gone to sleep. To avoid wasting too much airtime on this, limit the
-number of retries on such frames and ensure that no sample rate gets
-used.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -147,10 +147,25 @@ static void ath_send_bar(struct ath_atx_
- }
- static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
--                        struct ath_buf *bf)
-+                        struct ath_buf *bf, bool ps)
- {
-+      struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu);
-+
-+      if (ps) {
-+              /* Clear the first rate to avoid using a sample rate for PS frames */
-+              info->control.rates[0].idx = -1;
-+              info->control.rates[0].count = 0;
-+      }
-+
-       ieee80211_get_tx_rates(vif, sta, bf->bf_mpdu, bf->rates,
-                              ARRAY_SIZE(bf->rates));
-+      if (!ps)
-+              return;
-+
-+      if (bf->rates[0].count > 2)
-+              bf->rates[0].count = 2;
-+
-+      bf->rates[1].idx = -1;
- }
- static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
-@@ -1430,7 +1445,7 @@ ath_tx_form_burst(struct ath_softc *sc,
-               if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
-                       break;
--              ath_set_rates(tid->an->vif, tid->an->sta, bf);
-+              ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
-       } while (1);
- }
-@@ -1461,7 +1476,7 @@ static bool ath_tx_sched_aggr(struct ath
-               return false;
-       }
--      ath_set_rates(tid->an->vif, tid->an->sta, bf);
-+      ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
-       if (aggr)
-               last = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf,
-                                       tid_q, &aggr_len);
-@@ -1653,7 +1668,7 @@ void ath9k_release_buffered_frames(struc
-                       __skb_unlink(bf->bf_mpdu, tid_q);
-                       list_add_tail(&bf->list, &bf_q);
--                      ath_set_rates(tid->an->vif, tid->an->sta, bf);
-+                      ath_set_rates(tid->an->vif, tid->an->sta, bf, true);
-                       if (bf_isampdu(bf)) {
-                               ath_tx_addto_baw(sc, tid, bf);
-                               bf->bf_state.bf_type &= ~BUF_AGGR;
-@@ -2318,7 +2333,7 @@ int ath_tx_start(struct ieee80211_hw *hw
-       struct ath_txq *txq = txctl->txq;
-       struct ath_atx_tid *tid = NULL;
-       struct ath_buf *bf;
--      bool queue, skip_uapsd = false, ps_resp;
-+      bool queue, ps_resp;
-       int q, ret;
-       if (vif)
-@@ -2365,13 +2380,13 @@ int ath_tx_start(struct ieee80211_hw *hw
-               if (!txctl->an)
-                       txctl->an = &avp->mcast_node;
-               queue = true;
--              skip_uapsd = true;
-+              ps_resp = false;
-       }
-       if (txctl->an && queue)
-               tid = ath_get_skb_tid(sc, txctl->an, skb);
--      if (!skip_uapsd && ps_resp) {
-+      if (ps_resp) {
-               ath_txq_unlock(sc, txq);
-               txq = sc->tx.uapsdq;
-               ath_txq_lock(sc, txq);
-@@ -2409,7 +2424,7 @@ int ath_tx_start(struct ieee80211_hw *hw
-       if (txctl->paprd)
-               bf->bf_state.bfs_paprd_timestamp = jiffies;
--      ath_set_rates(vif, sta, bf);
-+      ath_set_rates(vif, sta, bf, ps_resp);
-       ath_tx_send_normal(sc, txq, tid, skb);
- out:
-@@ -2448,7 +2463,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw
-                       break;
-               bf->bf_lastbf = bf;
--              ath_set_rates(vif, NULL, bf);
-+              ath_set_rates(vif, NULL, bf, false);
-               ath_buf_set_rate(sc, bf, &info, fi->framelen, false);
-               duration += info.rates[0].PktDuration;
-               if (bf_tail)
-@@ -2968,7 +2983,7 @@ int ath9k_tx99_send(struct ath_softc *sc
-               return -EINVAL;
-       }
--      ath_set_rates(sc->tx99_vif, NULL, bf);
-+      ath_set_rates(sc->tx99_vif, NULL, bf, false);
-       ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, bf->bf_daddr);
-       ath9k_hw_tx99_start(sc->sc_ah, txctl->txq->axq_qnum);
diff --git a/package/kernel/mac80211/patches/306-mac80211-Deinline-rate_control_rate_init-rate_contro.patch b/package/kernel/mac80211/patches/306-mac80211-Deinline-rate_control_rate_init-rate_contro.patch
new file mode 100644 (file)
index 0000000..928c93b
--- /dev/null
@@ -0,0 +1,161 @@
+From: Denys Vlasenko <dvlasenk@redhat.com>
+Date: Wed, 15 Jul 2015 14:56:06 +0200
+Subject: [PATCH] mac80211: Deinline rate_control_rate_init,
+ rate_control_rate_update
+
+With this .config: http://busybox.net/~vda/kernel_config,
+after deinlining these functions have sizes and callsite counts
+as follows:
+
+rate_control_rate_init: 554 bytes, 8 calls
+rate_control_rate_update: 1596 bytes, 5 calls
+
+Total size reduction: about 11 kbytes.
+
+Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
+CC: John Linville <linville@tuxdriver.com>
+CC: Michal Kazior <michal.kazior@tieto.com>
+CC: Johannes Berg <johannes.berg@intel.com>
+Cc: linux-wireless@vger.kernel.org
+Cc: netdev@vger.kernel.org
+CC: linux-kernel@vger.kernel.org
+---
+
+--- a/net/mac80211/rate.c
++++ b/net/mac80211/rate.c
+@@ -29,6 +29,65 @@ module_param(ieee80211_default_rc_algo,
+ MODULE_PARM_DESC(ieee80211_default_rc_algo,
+                "Default rate control algorithm for mac80211 to use");
++void rate_control_rate_init(struct sta_info *sta)
++{
++      struct ieee80211_local *local = sta->sdata->local;
++      struct rate_control_ref *ref = sta->rate_ctrl;
++      struct ieee80211_sta *ista = &sta->sta;
++      void *priv_sta = sta->rate_ctrl_priv;
++      struct ieee80211_supported_band *sband;
++      struct ieee80211_chanctx_conf *chanctx_conf;
++
++      ieee80211_sta_set_rx_nss(sta);
++
++      if (!ref)
++              return;
++
++      rcu_read_lock();
++
++      chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
++      if (WARN_ON(!chanctx_conf)) {
++              rcu_read_unlock();
++              return;
++      }
++
++      sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
++
++      spin_lock_bh(&sta->rate_ctrl_lock);
++      ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista,
++                          priv_sta);
++      spin_unlock_bh(&sta->rate_ctrl_lock);
++      rcu_read_unlock();
++      set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
++}
++
++void rate_control_rate_update(struct ieee80211_local *local,
++                                  struct ieee80211_supported_band *sband,
++                                  struct sta_info *sta, u32 changed)
++{
++      struct rate_control_ref *ref = local->rate_ctrl;
++      struct ieee80211_sta *ista = &sta->sta;
++      void *priv_sta = sta->rate_ctrl_priv;
++      struct ieee80211_chanctx_conf *chanctx_conf;
++
++      if (ref && ref->ops->rate_update) {
++              rcu_read_lock();
++
++              chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
++              if (WARN_ON(!chanctx_conf)) {
++                      rcu_read_unlock();
++                      return;
++              }
++
++              spin_lock_bh(&sta->rate_ctrl_lock);
++              ref->ops->rate_update(ref->priv, sband, &chanctx_conf->def,
++                                    ista, priv_sta, changed);
++              spin_unlock_bh(&sta->rate_ctrl_lock);
++              rcu_read_unlock();
++      }
++      drv_sta_rc_update(local, sta->sdata, &sta->sta, changed);
++}
++
+ int ieee80211_rate_control_register(const struct rate_control_ops *ops)
+ {
+       struct rate_control_alg *alg;
+--- a/net/mac80211/rate.h
++++ b/net/mac80211/rate.h
+@@ -71,64 +71,10 @@ rate_control_tx_status_noskb(struct ieee
+       spin_unlock_bh(&sta->rate_ctrl_lock);
+ }
+-static inline void rate_control_rate_init(struct sta_info *sta)
+-{
+-      struct ieee80211_local *local = sta->sdata->local;
+-      struct rate_control_ref *ref = sta->rate_ctrl;
+-      struct ieee80211_sta *ista = &sta->sta;
+-      void *priv_sta = sta->rate_ctrl_priv;
+-      struct ieee80211_supported_band *sband;
+-      struct ieee80211_chanctx_conf *chanctx_conf;
+-
+-      ieee80211_sta_set_rx_nss(sta);
+-
+-      if (!ref)
+-              return;
+-
+-      rcu_read_lock();
+-
+-      chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
+-      if (WARN_ON(!chanctx_conf)) {
+-              rcu_read_unlock();
+-              return;
+-      }
+-
+-      sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
+-
+-      spin_lock_bh(&sta->rate_ctrl_lock);
+-      ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista,
+-                          priv_sta);
+-      spin_unlock_bh(&sta->rate_ctrl_lock);
+-      rcu_read_unlock();
+-      set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
+-}
+-
+-static inline void rate_control_rate_update(struct ieee80211_local *local,
++void rate_control_rate_init(struct sta_info *sta);
++void rate_control_rate_update(struct ieee80211_local *local,
+                                   struct ieee80211_supported_band *sband,
+-                                  struct sta_info *sta, u32 changed)
+-{
+-      struct rate_control_ref *ref = local->rate_ctrl;
+-      struct ieee80211_sta *ista = &sta->sta;
+-      void *priv_sta = sta->rate_ctrl_priv;
+-      struct ieee80211_chanctx_conf *chanctx_conf;
+-
+-      if (ref && ref->ops->rate_update) {
+-              rcu_read_lock();
+-
+-              chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
+-              if (WARN_ON(!chanctx_conf)) {
+-                      rcu_read_unlock();
+-                      return;
+-              }
+-
+-              spin_lock_bh(&sta->rate_ctrl_lock);
+-              ref->ops->rate_update(ref->priv, sband, &chanctx_conf->def,
+-                                    ista, priv_sta, changed);
+-              spin_unlock_bh(&sta->rate_ctrl_lock);
+-              rcu_read_unlock();
+-      }
+-      drv_sta_rc_update(local, sta->sdata, &sta->sta, changed);
+-}
++                                  struct sta_info *sta, u32 changed);
+ static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
+                                          struct sta_info *sta, gfp_t gfp)
diff --git a/package/kernel/mac80211/patches/307-ath10k-Delay-device-access-after-cold-reset.patch b/package/kernel/mac80211/patches/307-ath10k-Delay-device-access-after-cold-reset.patch
deleted file mode 100644 (file)
index 51998c2..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
-Date: Fri, 3 Jul 2015 11:45:42 +0530
-Subject: [PATCH] ath10k: Delay device access after cold reset
-
-It is observed that during cold reset pcie access right
-after a write operation to SOC_GLOBAL_RESET_ADDRESS causes
-Data Bus Error and system hard lockup. The reason
-for bus error is that pcie needs some time to get
-back to stable state for any transaction during cold reset. Add
-delay of 20 msecs after write of SOC_GLOBAL_RESET_ADDRESS
-to fix this issue.
-
-Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
----
-
---- a/drivers/net/wireless/ath/ath10k/pci.c
-+++ b/drivers/net/wireless/ath/ath10k/pci.c
-@@ -2602,7 +2602,6 @@ static int ath10k_pci_wait_for_target_in
- static int ath10k_pci_cold_reset(struct ath10k *ar)
- {
--      int i;
-       u32 val;
-       ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cold reset\n");
-@@ -2618,23 +2617,18 @@ static int ath10k_pci_cold_reset(struct
-       val |= 1;
-       ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
--      for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
--              if (ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) &
--                                        RTC_STATE_COLD_RESET_MASK)
--                      break;
--              msleep(1);
--      }
-+      /* After writing into SOC_GLOBAL_RESET to put device into
-+       * reset and pulling out of reset pcie may not be stable
-+       * for any immediate pcie register access and cause bus error,
-+       * add delay before any pcie access request to fix this issue.
-+       */
-+      msleep(20);
-       /* Pull Target, including PCIe, out of RESET. */
-       val &= ~1;
-       ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
--      for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
--              if (!(ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) &
--                                          RTC_STATE_COLD_RESET_MASK))
--                      break;
--              msleep(1);
--      }
-+      msleep(20);
-       ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cold reset complete\n");
diff --git a/package/kernel/mac80211/patches/307-mac80211-Deinline-drv_sta_state.patch b/package/kernel/mac80211/patches/307-mac80211-Deinline-drv_sta_state.patch
new file mode 100644 (file)
index 0000000..474c409
--- /dev/null
@@ -0,0 +1,116 @@
+From: Denys Vlasenko <dvlasenk@redhat.com>
+Date: Wed, 15 Jul 2015 14:56:05 +0200
+Subject: [PATCH] mac80211: Deinline drv_sta_state
+
+With this .config: http://busybox.net/~vda/kernel_config,
+after deinlining the function size is 3132 bytes and there are
+7 callsites.
+
+Total size reduction: about 20 kbytes.
+
+Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
+CC: John Linville <linville@tuxdriver.com>
+CC: Michal Kazior <michal.kazior@tieto.com>
+Cc: Johannes Berg <johannes.berg@intel.com>
+Cc: linux-wireless@vger.kernel.org
+Cc: netdev@vger.kernel.org
+CC: linux-kernel@vger.kernel.org
+---
+ create mode 100644 net/mac80211/driver-ops.c
+
+--- a/net/mac80211/Makefile
++++ b/net/mac80211/Makefile
+@@ -3,6 +3,7 @@ obj-$(CPTCFG_MAC80211) += mac80211.o
+ # mac80211 objects
+ mac80211-y := \
+       main.o status.o \
++      driver-ops.o \
+       sta_info.o \
+       wep.o \
+       wpa.o \
+--- /dev/null
++++ b/net/mac80211/driver-ops.c
+@@ -0,0 +1,41 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <net/mac80211.h>
++#include "ieee80211_i.h"
++#include "trace.h"
++#include "driver-ops.h"
++
++__must_check
++int drv_sta_state(struct ieee80211_local *local,
++                struct ieee80211_sub_if_data *sdata,
++                struct sta_info *sta,
++                enum ieee80211_sta_state old_state,
++                enum ieee80211_sta_state new_state)
++{
++      int ret = 0;
++
++      might_sleep();
++
++      sdata = get_bss_sdata(sdata);
++      if (!check_sdata_in_driver(sdata))
++              return -EIO;
++
++      trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state);
++      if (local->ops->sta_state) {
++              ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta,
++                                          old_state, new_state);
++      } else if (old_state == IEEE80211_STA_AUTH &&
++                 new_state == IEEE80211_STA_ASSOC) {
++              ret = drv_sta_add(local, sdata, &sta->sta);
++              if (ret == 0)
++                      sta->uploaded = true;
++      } else if (old_state == IEEE80211_STA_ASSOC &&
++                 new_state == IEEE80211_STA_AUTH) {
++              drv_sta_remove(local, sdata, &sta->sta);
++      }
++      trace_drv_return_int(local, ret);
++      return ret;
++}
+--- a/net/mac80211/driver-ops.h
++++ b/net/mac80211/driver-ops.h
+@@ -573,37 +573,12 @@ static inline void drv_sta_pre_rcu_remov
+       trace_drv_return_void(local);
+ }
+-static inline __must_check
++__must_check
+ int drv_sta_state(struct ieee80211_local *local,
+                 struct ieee80211_sub_if_data *sdata,
+                 struct sta_info *sta,
+                 enum ieee80211_sta_state old_state,
+-                enum ieee80211_sta_state new_state)
+-{
+-      int ret = 0;
+-
+-      might_sleep();
+-
+-      sdata = get_bss_sdata(sdata);
+-      if (!check_sdata_in_driver(sdata))
+-              return -EIO;
+-
+-      trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state);
+-      if (local->ops->sta_state) {
+-              ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta,
+-                                          old_state, new_state);
+-      } else if (old_state == IEEE80211_STA_AUTH &&
+-                 new_state == IEEE80211_STA_ASSOC) {
+-              ret = drv_sta_add(local, sdata, &sta->sta);
+-              if (ret == 0)
+-                      sta->uploaded = true;
+-      } else if (old_state == IEEE80211_STA_ASSOC &&
+-                 new_state == IEEE80211_STA_AUTH) {
+-              drv_sta_remove(local, sdata, &sta->sta);
+-      }
+-      trace_drv_return_int(local, ret);
+-      return ret;
+-}
++                enum ieee80211_sta_state new_state);
+ static inline void drv_sta_rc_update(struct ieee80211_local *local,
+                                    struct ieee80211_sub_if_data *sdata,
diff --git a/package/kernel/mac80211/patches/308-ath9k-Fix-NF-CCA-limits-for-AR9287-and-AR9227.patch b/package/kernel/mac80211/patches/308-ath9k-Fix-NF-CCA-limits-for-AR9287-and-AR9227.patch
new file mode 100644 (file)
index 0000000..1a3a9d4
--- /dev/null
@@ -0,0 +1,30 @@
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Date: Wed, 22 Jul 2015 10:42:43 +0200
+Subject: [PATCH] ath9k: Fix NF CCA limits for AR9287 and AR9227
+
+The FreeBSD driver [0] uses the same 2G values as for the AR9280 chips.
+Using the same values in ath9k results in much better throughput for me.
+
+Before this patch I had a huge amount of packet loss (sometimes up to
+40%) and the max transfer speed was somewhere around 5Mbit/s. With this
+patch applied I have zero packet loss and ten times the throughput.
+My device uses a AR9227 which is the PCI variant of the AR9287.
+
+[0] http://bxr.su/FreeBSD/sys/dev/ath/ath_hal/ar9002/ar9287.h
+
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
++++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+@@ -610,8 +610,8 @@
+ #define AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ      -127
+ #define AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ      -116
+-#define AR_PHY_CCA_NOM_VAL_9287_2GHZ           -120
++#define AR_PHY_CCA_NOM_VAL_9287_2GHZ           -112
+ #define AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ    -127
+-#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ    -110
++#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ    -97
+ #endif
diff --git a/package/kernel/mac80211/patches/308-cfg80211-use-RTNL-locked-reg_can_beacon-for-IR-relax.patch b/package/kernel/mac80211/patches/308-cfg80211-use-RTNL-locked-reg_can_beacon-for-IR-relax.patch
deleted file mode 100644 (file)
index d2a1cdc..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-From: Arik Nemtsov <arik@wizery.com>
-Date: Wed, 8 Jul 2015 15:41:44 +0300
-Subject: [PATCH] cfg80211: use RTNL locked reg_can_beacon for IR-relaxation
-
-The RTNL is required to check for IR-relaxation conditions that allow
-more channels to beacon. Export an RTNL locked version of reg_can_beacon
-and use it where possible in AP/STA interface type flows, where
-IR-relaxation may be applicable.
-
-Fixes: 06f207fc5418 ("cfg80211: change GO_CONCURRENT to IR_CONCURRENT for STA")
-Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
-Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
----
-
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -4871,6 +4871,23 @@ bool cfg80211_reg_can_beacon(struct wiph
-                            struct cfg80211_chan_def *chandef,
-                            enum nl80211_iftype iftype);
-+/**
-+ * cfg80211_reg_can_beacon_relax - check if beaconing is allowed with relaxation
-+ * @wiphy: the wiphy
-+ * @chandef: the channel definition
-+ * @iftype: interface type
-+ *
-+ * Return: %true if there is no secondary channel or the secondary channel(s)
-+ * can be used for beaconing (i.e. is not a radar channel etc.). This version
-+ * also checks if IR-relaxation conditions apply, to allow beaconing under
-+ * more permissive conditions.
-+ *
-+ * Requires the RTNL to be held.
-+ */
-+bool cfg80211_reg_can_beacon_relax(struct wiphy *wiphy,
-+                                 struct cfg80211_chan_def *chandef,
-+                                 enum nl80211_iftype iftype);
-+
- /*
-  * cfg80211_ch_switch_notify - update wdev channel and notify userspace
-  * @dev: the device which switched channels
---- a/net/mac80211/tdls.c
-+++ b/net/mac80211/tdls.c
-@@ -69,6 +69,7 @@ ieee80211_tdls_add_subband(struct ieee80
-       struct ieee80211_channel *ch;
-       struct cfg80211_chan_def chandef;
-       int i, subband_start;
-+      struct wiphy *wiphy = sdata->local->hw.wiphy;
-       for (i = start; i <= end; i += spacing) {
-               if (!ch_cnt)
-@@ -79,9 +80,8 @@ ieee80211_tdls_add_subband(struct ieee80
-                       /* we will be active on the channel */
-                       cfg80211_chandef_create(&chandef, ch,
-                                               NL80211_CHAN_NO_HT);
--                      if (cfg80211_reg_can_beacon(sdata->local->hw.wiphy,
--                                                  &chandef,
--                                                  sdata->wdev.iftype)) {
-+                      if (cfg80211_reg_can_beacon_relax(wiphy, &chandef,
-+                                                        sdata->wdev.iftype)) {
-                               ch_cnt++;
-                               /*
-                                * check if the next channel is also part of
---- a/net/wireless/chan.c
-+++ b/net/wireless/chan.c
-@@ -797,23 +797,18 @@ static bool cfg80211_ir_permissive_chan(
-       return false;
- }
--bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
--                           struct cfg80211_chan_def *chandef,
--                           enum nl80211_iftype iftype)
-+static bool _cfg80211_reg_can_beacon(struct wiphy *wiphy,
-+                                   struct cfg80211_chan_def *chandef,
-+                                   enum nl80211_iftype iftype,
-+                                   bool check_no_ir)
- {
-       bool res;
-       u32 prohibited_flags = IEEE80211_CHAN_DISABLED |
-                              IEEE80211_CHAN_RADAR;
--      trace_cfg80211_reg_can_beacon(wiphy, chandef, iftype);
-+      trace_cfg80211_reg_can_beacon(wiphy, chandef, iftype, check_no_ir);
--      /*
--       * Under certain conditions suggested by some regulatory bodies a
--       * GO/STA can IR on channels marked with IEEE80211_NO_IR. Set this flag
--       * only if such relaxations are not enabled and the conditions are not
--       * met.
--       */
--      if (!cfg80211_ir_permissive_chan(wiphy, iftype, chandef->chan))
-+      if (check_no_ir)
-               prohibited_flags |= IEEE80211_CHAN_NO_IR;
-       if (cfg80211_chandef_dfs_required(wiphy, chandef, iftype) > 0 &&
-@@ -827,8 +822,36 @@ bool cfg80211_reg_can_beacon(struct wiph
-       trace_cfg80211_return_bool(res);
-       return res;
- }
-+
-+bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
-+                           struct cfg80211_chan_def *chandef,
-+                           enum nl80211_iftype iftype)
-+{
-+      return _cfg80211_reg_can_beacon(wiphy, chandef, iftype, true);
-+}
- EXPORT_SYMBOL(cfg80211_reg_can_beacon);
-+bool cfg80211_reg_can_beacon_relax(struct wiphy *wiphy,
-+                                 struct cfg80211_chan_def *chandef,
-+                                 enum nl80211_iftype iftype)
-+{
-+      bool check_no_ir;
-+
-+      ASSERT_RTNL();
-+
-+      /*
-+       * Under certain conditions suggested by some regulatory bodies a
-+       * GO/STA can IR on channels marked with IEEE80211_NO_IR. Set this flag
-+       * only if such relaxations are not enabled and the conditions are not
-+       * met.
-+       */
-+      check_no_ir = !cfg80211_ir_permissive_chan(wiphy, iftype,
-+                                                 chandef->chan);
-+
-+      return _cfg80211_reg_can_beacon(wiphy, chandef, iftype, check_no_ir);
-+}
-+EXPORT_SYMBOL(cfg80211_reg_can_beacon_relax);
-+
- int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
-                                struct cfg80211_chan_def *chandef)
- {
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -2007,7 +2007,8 @@ static int __nl80211_set_channel(struct
-       switch (iftype) {
-       case NL80211_IFTYPE_AP:
-       case NL80211_IFTYPE_P2P_GO:
--              if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef, iftype)) {
-+              if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
-+                                                 iftype)) {
-                       result = -EINVAL;
-                       break;
-               }
-@@ -3408,8 +3409,8 @@ static int nl80211_start_ap(struct sk_bu
-       } else if (!nl80211_get_ap_channel(rdev, &params))
-               return -EINVAL;
--      if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef,
--                                   wdev->iftype))
-+      if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
-+                                         wdev->iftype))
-               return -EINVAL;
-       if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
-@@ -6500,8 +6501,8 @@ skip_beacons:
-       if (err)
-               return err;
--      if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef,
--                                   wdev->iftype))
-+      if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
-+                                         wdev->iftype))
-               return -EINVAL;
-       err = cfg80211_chandef_dfs_required(wdev->wiphy,
-@@ -10188,7 +10189,8 @@ static int nl80211_tdls_channel_switch(s
-               return -EINVAL;
-       /* we will be active on the TDLS link */
--      if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef, wdev->iftype))
-+      if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
-+                                         wdev->iftype))
-               return -EINVAL;
-       /* don't allow switching to DFS channels */
---- a/net/wireless/reg.c
-+++ b/net/wireless/reg.c
-@@ -1589,7 +1589,7 @@ static bool reg_wdev_chan_valid(struct w
-       case NL80211_IFTYPE_AP:
-       case NL80211_IFTYPE_P2P_GO:
-       case NL80211_IFTYPE_ADHOC:
--              return cfg80211_reg_can_beacon(wiphy, &chandef, iftype);
-+              return cfg80211_reg_can_beacon_relax(wiphy, &chandef, iftype);
-       case NL80211_IFTYPE_STATION:
-       case NL80211_IFTYPE_P2P_CLIENT:
-               return cfg80211_chandef_usable(wiphy, &chandef,
---- a/net/wireless/trace.h
-+++ b/net/wireless/trace.h
-@@ -2358,20 +2358,23 @@ TRACE_EVENT(cfg80211_cqm_rssi_notify,
- TRACE_EVENT(cfg80211_reg_can_beacon,
-       TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef,
--               enum nl80211_iftype iftype),
--      TP_ARGS(wiphy, chandef, iftype),
-+               enum nl80211_iftype iftype, bool check_no_ir),
-+      TP_ARGS(wiphy, chandef, iftype, check_no_ir),
-       TP_STRUCT__entry(
-               WIPHY_ENTRY
-               CHAN_DEF_ENTRY
-               __field(enum nl80211_iftype, iftype)
-+              __field(bool, check_no_ir)
-       ),
-       TP_fast_assign(
-               WIPHY_ASSIGN;
-               CHAN_DEF_ASSIGN(chandef);
-               __entry->iftype = iftype;
-+              __entry->check_no_ir = check_no_ir;
-       ),
--      TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT ", iftype=%d",
--                WIPHY_PR_ARG, CHAN_DEF_PR_ARG, __entry->iftype)
-+      TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT ", iftype=%d check_no_ir=%s",
-+                WIPHY_PR_ARG, CHAN_DEF_PR_ARG, __entry->iftype,
-+                BOOL_TO_STR(__entry->check_no_ir))
- );
- TRACE_EVENT(cfg80211_chandef_dfs_required,
index c70f6c4009ec2d2d41097a57b5868223f4c688a3..8b52ac35291512c4a363d749f97878e30c2491d1 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net/wireless/reg.c
 +++ b/net/wireless/reg.c
-@@ -2391,6 +2391,8 @@ void regulatory_hint_country_ie(struct w
+@@ -2390,6 +2390,8 @@ void regulatory_hint_country_ie(struct w
        enum environment_cap env = ENVIRON_ANY;
        struct regulatory_request *request = NULL, *lr;
  
@@ -9,7 +9,7 @@
        /* IE len must be evenly divisible by 2 */
        if (country_ie_len & 0x01)
                return;
-@@ -2597,6 +2599,7 @@ static void restore_regulatory_settings(
+@@ -2596,6 +2598,7 @@ static void restore_regulatory_settings(
  
  void regulatory_hint_disconnect(void)
  {
index 1825d77b7f83e4a5cf5922ba6fd314a4c8704759..b4e9762969b139bb67393bda8f5afbfcd797f42a 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -1030,23 +1030,23 @@ static int __init ath9k_init(void)
+@@ -1031,23 +1031,23 @@ static int __init ath9k_init(void)
  {
        int error;
  
index d4104f0e9354cde2eb7b1885c2f052254b8d830c..6766111dfd3e43b2251a0248f256e97f8d5cbffa 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -87,7 +87,7 @@ int ath_descdma_setup(struct ath_softc *
+@@ -88,7 +88,7 @@ int ath_descdma_setup(struct ath_softc *
                (_l) &= ((_sz) - 1);            \
        } while (0)
  
index 829c572d274e87436d61f461d263f49c0d0e186f..99bf7e86c0705ac1c1a3a137e902e81ab1b0beeb 100644 (file)
@@ -8,7 +8,7 @@
   *
   * @set_wds_peer: set the WDS peer for a WDS interface
   *
-@@ -2577,6 +2578,7 @@ struct cfg80211_ops {
+@@ -2576,6 +2577,7 @@ struct cfg80211_ops {
                                enum nl80211_tx_power_setting type, int mbm);
        int     (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
                                int *dbm);
index 2f0a6366f37b2b72097069cd3072882f4e1b1d0f..8aab45aa30352437270fe1301b38b6c2624eceee 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -814,6 +814,9 @@ static inline int ath9k_dump_btcoex(stru
+@@ -806,6 +806,9 @@ static inline int ath9k_dump_btcoex(stru
  void ath_init_leds(struct ath_softc *sc);
  void ath_deinit_leds(struct ath_softc *sc);
  void ath_fill_led_pin(struct ath_softc *sc);
@@ -10,7 +10,7 @@
  #else
  static inline void ath_init_leds(struct ath_softc *sc)
  {
-@@ -953,6 +956,13 @@ void ath_ant_comb_scan(struct ath_softc
+@@ -945,6 +948,13 @@ void ath_ant_comb_scan(struct ath_softc
  
  #define ATH9K_NUM_CHANCTX  2 /* supports 2 operating channels */
  
@@ -24,7 +24,7 @@
  struct ath_softc {
        struct ieee80211_hw *hw;
        struct device *dev;
-@@ -1004,9 +1014,8 @@ struct ath_softc {
+@@ -996,9 +1006,8 @@ struct ath_softc {
        spinlock_t chan_lock;
  
  #ifdef CPTCFG_MAC80211_LEDS
  void ath_fill_led_pin(struct ath_softc *sc)
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -942,7 +942,7 @@ int ath9k_init_device(u16 devid, struct
+@@ -943,7 +943,7 @@ int ath9k_init_device(u16 devid, struct
  
  #ifdef CPTCFG_MAC80211_LEDS
        /* must be initialized before ieee80211_register_hw */
index c6afffa317271c3d8b7ecd97e89c78f70b19207b..49b636742451bb044455b3c7e0acb651214d57ba 100644 (file)
@@ -65,7 +65,7 @@
  }
  
  static const struct ieee80211_iface_limit if_limits[] = {
-@@ -902,6 +903,18 @@ static void ath9k_set_hw_capab(struct at
+@@ -903,6 +904,18 @@ static void ath9k_set_hw_capab(struct at
        SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
  }
  
@@ -84,7 +84,7 @@
  int ath9k_init_device(u16 devid, struct ath_softc *sc,
                    const struct ath_bus_ops *bus_ops)
  {
-@@ -947,6 +960,8 @@ int ath9k_init_device(u16 devid, struct
+@@ -948,6 +961,8 @@ int ath9k_init_device(u16 devid, struct
                ARRAY_SIZE(ath9k_tpt_blink));
  #endif
  
index 997d5501e42d0004334ad07df3b31ee89a69722f..44b629f656ccd42a5661e1af67196ebe7e6dac98 100644 (file)
@@ -1,6 +1,6 @@
 --- a/.local-symbols
 +++ b/.local-symbols
-@@ -311,6 +311,7 @@ RT2X00_LIB_FIRMWARE=
+@@ -312,6 +312,7 @@ RT2X00_LIB_FIRMWARE=
  RT2X00_LIB_CRYPTO=
  RT2X00_LIB_LEDS=
  RT2X00_LIB_DEBUGFS=
diff --git a/package/kernel/mac80211/patches/863-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch b/package/kernel/mac80211/patches/863-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch
deleted file mode 100644 (file)
index 32989eb..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Thu, 9 Jul 2015 16:53:30 +0200
-Subject: [PATCH] brcmfmac: set wiphy's addresses to provide valid MACs
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Broadcom's firmware requires every BSS to use MAC address with unique
-last few bits. The amount of bits may depend on a particular firmware,
-it was verified to be 2 for BCM43602 one.
-If this condition won't be fulfilled firmware will reject such MAC:
-brcmfmac: _brcmf_set_mac_address: Setting cur_etheraddr failed, -52
-
-We don't want to simply set addr_mask as it would also disallow using
-locally administrated bit. Instead let's build a list of addresses
-manually enabling 0x2 bit for extra interfaces.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
-
---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-@@ -5813,6 +5813,7 @@ static void brcmf_wiphy_wowl_params(stru
- static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
- {
-+      struct brcmf_pub *drvr = ifp->drvr;
-       struct ieee80211_supported_band *band;
-       __le32 bandlist[3];
-       u32 n_bands;
-@@ -5826,6 +5827,19 @@ static int brcmf_setup_wiphy(struct wiph
-       if (err)
-               return err;
-+      for (i = 0; i < wiphy->iface_combinations->max_interfaces &&
-+           i < ARRAY_SIZE(drvr->addresses); i++) {
-+              u8 *addr = drvr->addresses[i].addr;
-+
-+              memcpy(addr, drvr->mac, ETH_ALEN);
-+              if (i) {
-+                      addr[0] |= BIT(1);
-+                      addr[ETH_ALEN - 1] ^= i;
-+              }
-+      }
-+      wiphy->addresses = drvr->addresses;
-+      wiphy->n_addresses = i;
-+
-       wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-       wiphy->cipher_suites = __wl_cipher_suites;
-       wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
---- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
-+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
-@@ -21,6 +21,7 @@
- #ifndef BRCMFMAC_CORE_H
- #define BRCMFMAC_CORE_H
-+#include <net/cfg80211.h>
- #include "fweh.h"
- #define TOE_TX_CSUM_OL                0x00000001
-@@ -118,6 +119,8 @@ struct brcmf_pub {
-       /* Multicast data packets sent to dongle */
-       unsigned long tx_multicast;
-+      struct mac_address addresses[BRCMF_MAX_IFS];
-+
-       struct brcmf_if *iflist[BRCMF_MAX_IFS];
-       struct mutex proto_block;
index 43b2448ff22c470739fd20734323b8ebba2bee8a..93196e13ba271e781472b0b08e42ad2a35d6cf67 100644 (file)
@@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
 
 --- a/drivers/net/wireless/ath/ath10k/core.c
 +++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -1417,6 +1417,16 @@ int ath10k_core_register(struct ath10k *
+@@ -1520,6 +1520,16 @@ int ath10k_core_register(struct ath10k *
        ar->chip_id = chip_id;
        queue_work(ar->workqueue, &ar->register_work);
  
index bacb3a5dc37bf8068ae48f1b81cda54247b817f2..34910a02fc573c8f9e8b806d61f75619eeaed80d 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath10k/mac.c
 +++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -6756,6 +6756,21 @@ struct ath10k_vif *ath10k_get_arvif(stru
+@@ -6804,6 +6804,21 @@ struct ath10k_vif *ath10k_get_arvif(stru
        return arvif_iter.arvif;
  }
  
@@ -22,7 +22,7 @@
  int ath10k_mac_register(struct ath10k *ar)
  {
        static const u32 cipher_suites[] = {
-@@ -6971,6 +6986,12 @@ int ath10k_mac_register(struct ath10k *a
+@@ -7025,6 +7040,12 @@ int ath10k_mac_register(struct ath10k *a
        ar->hw->wiphy->cipher_suites = cipher_suites;
        ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);