diff options
Diffstat (limited to 'package/kernel/mac80211/patches')
27 files changed, 957 insertions, 825 deletions
diff --git a/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch b/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch index d85b813..4fbab23 100644 --- a/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch +++ b/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch @@ -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= diff --git a/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch b/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch index 55a1ccd..07dde54 100644 --- a/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch +++ b/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch @@ -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 := \ @@ -10,84 +21,25 @@ 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); @@ -102,22 +54,33 @@ + 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]; @@ -147,23 +110,6 @@ + *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]; @@ -174,7 +120,7 @@ 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)); @@ -185,15 +131,14 @@ - - 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]; @@ -270,6 +215,98 @@ - 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 { @@ -337,38 +374,3 @@ 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 index 29f05c4..0000000 --- a/package/kernel/mac80211/patches/210-ap_scan.patch +++ /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/306-ath9k-limit-retries-for-powersave-response-frames.patch b/package/kernel/mac80211/patches/301-ath9k-limit-retries-for-powersave-response-frames.patch index 4faac0d..4faac0d 100644 --- a/package/kernel/mac80211/patches/306-ath9k-limit-retries-for-powersave-response-frames.patch +++ b/package/kernel/mac80211/patches/301-ath9k-limit-retries-for-powersave-response-frames.patch 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 index 5998be8..0000000 --- a/package/kernel/mac80211/patches/301-ath9k_hw-fix-device-ID-check-for-AR956x.patch +++ /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 index e403e6a..0000000 --- a/package/kernel/mac80211/patches/302-ath-DFS-limit-number-of-potential-PRI-sequences.patch +++ /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/307-ath10k-Delay-device-access-after-cold-reset.patch b/package/kernel/mac80211/patches/302-ath10k-Delay-device-access-after-cold-reset.patch index 51998c2..820aa9a 100644 --- a/package/kernel/mac80211/patches/307-ath10k-Delay-device-access-after-cold-reset.patch +++ b/package/kernel/mac80211/patches/302-ath10k-Delay-device-access-after-cold-reset.patch @@ -15,7 +15,7 @@ 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 +@@ -2761,7 +2761,6 @@ static int ath10k_pci_wait_for_target_in static int ath10k_pci_cold_reset(struct ath10k *ar) { @@ -23,7 +23,7 @@ Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com> u32 val; ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cold reset\n"); -@@ -2618,23 +2617,18 @@ static int ath10k_pci_cold_reset(struct +@@ -2777,23 +2776,18 @@ static int ath10k_pci_cold_reset(struct val |= 1; ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val); 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 index 07f5e3b..0000000 --- a/package/kernel/mac80211/patches/303-ath9k-DFS-consider-ext_channel-pulses-only-in-HT40-m.patch +++ /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 index 0000000..139015c --- /dev/null +++ b/package/kernel/mac80211/patches/303-ath9k-add-fast-xmit-support.patch @@ -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 index 3437f13..0000000 --- a/package/kernel/mac80211/patches/304-ath9k-DFS-add-pulse-chirp-detection-for-FCC.patch +++ /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 index 0000000..9f04276 --- /dev/null +++ b/package/kernel/mac80211/patches/304-ath9k-remove-struct-ath_atx_ac.patch @@ -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 index c4f394d..0000000 --- a/package/kernel/mac80211/patches/305-ath9k-make-DMA-stop-related-messages-debug-only.patch +++ /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 index 0000000..ec860dc --- /dev/null +++ b/package/kernel/mac80211/patches/305-ath9k-remove-the-sched-field-in-struct-ath_atx_tid.patch @@ -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-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 index 0000000..928c93b --- /dev/null +++ b/package/kernel/mac80211/patches/306-mac80211-Deinline-rate_control_rate_init-rate_contro.patch @@ -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-mac80211-Deinline-drv_sta_state.patch b/package/kernel/mac80211/patches/307-mac80211-Deinline-drv_sta_state.patch new file mode 100644 index 0000000..474c409 --- /dev/null +++ b/package/kernel/mac80211/patches/307-mac80211-Deinline-drv_sta_state.patch @@ -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 index 0000000..1a3a9d4 --- /dev/null +++ b/package/kernel/mac80211/patches/308-ath9k-Fix-NF-CCA-limits-for-AR9287-and-AR9227.patch @@ -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 index d2a1cdc..0000000 --- a/package/kernel/mac80211/patches/308-cfg80211-use-RTNL-locked-reg_can_beacon-for-IR-relax.patch +++ /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, ¶ms)) - return -EINVAL; - -- if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef, -- wdev->iftype)) -+ if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, ¶ms.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, ¶ms.chandef, -- wdev->iftype)) -+ if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, ¶ms.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, diff --git a/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch b/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch index c70f6c4..8b52ac3 100644 --- a/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch +++ b/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch @@ -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) { diff --git a/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch index 1825d77..b4e9762 100644 --- a/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch +++ b/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch @@ -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; diff --git a/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch b/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch index d4104f0..6766111 100644 --- a/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch +++ b/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch @@ -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) diff --git a/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch index 829c572..99bf7e8 100644 --- a/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch +++ b/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch @@ -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); diff --git a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch index 2f0a636..8aab45a 100644 --- a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch +++ b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch @@ -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 @@ -165,7 +165,7 @@ 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 */ diff --git a/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch index c6afffa..49b6367 100644 --- a/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch +++ b/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch @@ -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 diff --git a/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch index 997d550..44b629f 100644 --- a/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch +++ b/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch @@ -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 index 32989eb..0000000 --- a/package/kernel/mac80211/patches/863-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch +++ /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; diff --git a/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch index 43b2448..93196e1 100644 --- a/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch +++ b/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch @@ -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); diff --git a/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch index bacb3a5d..34910a0 100644 --- a/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch +++ b/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch @@ -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); |