ath10k: merge some pending stability fixes
authorFelix Fietkau <nbd@nbd.name>
Tue, 7 Jun 2016 11:27:26 +0000 (13:27 +0200)
committerFelix Fietkau <nbd@nbd.name>
Sat, 11 Jun 2016 07:51:23 +0000 (09:51 +0200)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/kernel/mac80211/patches/305-ath10k-Ensure-txrx-compl-task-is-stopped-when-cleani.patch [new file with mode: 0644]
package/kernel/mac80211/patches/306-ath10k-Ensure-peer_map-references-are-cleaned-up.patch [new file with mode: 0644]
package/kernel/mac80211/patches/307-ath10k-Clean-up-peer-when-sta-goes-away.patch [new file with mode: 0644]
package/kernel/mac80211/patches/308-ath10k-remove-duplicate-and-unused-rx-rate-flags.patch [new file with mode: 0644]
package/kernel/mac80211/patches/309-ath10k-fix-CCK-h-w-rates-for-QCA99X0-and-newer-chips.patch [new file with mode: 0644]
package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch
package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch
package/kernel/mac80211/patches/936-ath10k_skip_otp_check.patch

diff --git a/package/kernel/mac80211/patches/305-ath10k-Ensure-txrx-compl-task-is-stopped-when-cleani.patch b/package/kernel/mac80211/patches/305-ath10k-Ensure-txrx-compl-task-is-stopped-when-cleani.patch
new file mode 100644 (file)
index 0000000..73accd8
--- /dev/null
@@ -0,0 +1,21 @@
+From: Ben Greear <greearb@candelatech.com>
+Date: Fri, 1 Apr 2016 14:12:08 -0700
+Subject: [PATCH] ath10k: Ensure txrx-compl-task is stopped when cleaning
+ htt-tx.
+
+Otherwise, the txrx-compl-task may access some bad memory?
+
+Signed-off-by: Ben Greear <greearb@candelatech.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
++++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
+@@ -388,6 +388,8 @@ void ath10k_htt_tx_free(struct ath10k_ht
+ {
+       int size;
++      tasklet_kill(&htt->txrx_compl_task);
++
+       idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
+       idr_destroy(&htt->pending_tx);
diff --git a/package/kernel/mac80211/patches/306-ath10k-Ensure-peer_map-references-are-cleaned-up.patch b/package/kernel/mac80211/patches/306-ath10k-Ensure-peer_map-references-are-cleaned-up.patch
new file mode 100644 (file)
index 0000000..2979b4b
--- /dev/null
@@ -0,0 +1,60 @@
+From: Ben Greear <greearb@candelatech.com>
+Date: Fri, 1 Apr 2016 14:12:09 -0700
+Subject: [PATCH] ath10k: Ensure peer_map references are cleaned up.
+
+While debugging OS crashes due to firmware crashes, I enabled
+kasan, and it noticed that peer objects were being used-after-freed.
+
+Looks like there are two places we could be leaving stale references
+in the peer-map, so clean that up.
+
+Signed-off-by: Ben Greear <greearb@candelatech.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -773,6 +773,7 @@ static void ath10k_peer_cleanup(struct a
+ {
+       struct ath10k_peer *peer, *tmp;
+       int peer_id;
++      int i;
+       lockdep_assert_held(&ar->conf_mutex);
+@@ -789,6 +790,17 @@ static void ath10k_peer_cleanup(struct a
+                       ar->peer_map[peer_id] = NULL;
+               }
++              /* Double check that peer is properly un-referenced from
++               * the peer_map
++               */
++              for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
++                      if (ar->peer_map[i] == peer) {
++                              ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %p idx %d)\n",
++                                          peer->addr, peer, i);
++                              ar->peer_map[i] = NULL;
++                      }
++              }
++
+               list_del(&peer->list);
+               kfree(peer);
+               ar->num_peers--;
+@@ -799,6 +811,7 @@ static void ath10k_peer_cleanup(struct a
+ static void ath10k_peer_cleanup_all(struct ath10k *ar)
+ {
+       struct ath10k_peer *peer, *tmp;
++      int i;
+       lockdep_assert_held(&ar->conf_mutex);
+@@ -807,6 +820,10 @@ static void ath10k_peer_cleanup_all(stru
+               list_del(&peer->list);
+               kfree(peer);
+       }
++
++      for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++)
++              ar->peer_map[i] = NULL;
++
+       spin_unlock_bh(&ar->data_lock);
+       ar->num_peers = 0;
diff --git a/package/kernel/mac80211/patches/307-ath10k-Clean-up-peer-when-sta-goes-away.patch b/package/kernel/mac80211/patches/307-ath10k-Clean-up-peer-when-sta-goes-away.patch
new file mode 100644 (file)
index 0000000..f814ae7
--- /dev/null
@@ -0,0 +1,32 @@
+From: Ben Greear <greearb@candelatech.com>
+Date: Fri, 1 Apr 2016 14:12:11 -0700
+Subject: [PATCH] ath10k: Clean up peer when sta goes away.
+
+If WMI and/or firmware has issues removing the peer object,
+then we still need to clean up the peer object in the driver.
+
+Signed-off-by: Ben Greear <greearb@candelatech.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -5949,9 +5949,17 @@ static int ath10k_sta_state(struct ieee8
+                               continue;
+                       if (peer->sta == sta) {
+-                              ath10k_warn(ar, "found sta peer %pM entry on vdev %i after it was supposedly removed\n",
+-                                          sta->addr, arvif->vdev_id);
++                              ath10k_warn(ar, "found sta peer %pM (ptr %p id %d) entry on vdev %i after it was supposedly removed\n",
++                                          sta->addr, peer, i, arvif->vdev_id);
+                               peer->sta = NULL;
++
++                              /* Clean up the peer object as well since we
++                               * must have failed to do this above.
++                               */
++                              list_del(&peer->list);
++                              ar->peer_map[i] = NULL;
++                              kfree(peer);
++                              ar->num_peers--;
+                       }
+               }
+               spin_unlock_bh(&ar->data_lock);
diff --git a/package/kernel/mac80211/patches/308-ath10k-remove-duplicate-and-unused-rx-rate-flags.patch b/package/kernel/mac80211/patches/308-ath10k-remove-duplicate-and-unused-rx-rate-flags.patch
new file mode 100644 (file)
index 0000000..7c5c5be
--- /dev/null
@@ -0,0 +1,66 @@
+From: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
+Date: Thu, 2 Jun 2016 19:54:41 +0530
+Subject: [PATCH] ath10k: remove duplicate and unused rx rate flags
+
+All these flags are not used and their use is completely
+covered by 'ath10k_hw_rate_ofdm', 'ath10k_hw_rate_cck',
+and RX_PPDU_START_RATE_FLAG
+
+Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
++++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
+@@ -656,26 +656,6 @@ struct rx_msdu_end {
+  *            Reserved: HW should fill with zero.  FW should ignore.
+  */
+-#define RX_PPDU_START_SIG_RATE_SELECT_OFDM 0
+-#define RX_PPDU_START_SIG_RATE_SELECT_CCK  1
+-
+-#define RX_PPDU_START_SIG_RATE_OFDM_48 0
+-#define RX_PPDU_START_SIG_RATE_OFDM_24 1
+-#define RX_PPDU_START_SIG_RATE_OFDM_12 2
+-#define RX_PPDU_START_SIG_RATE_OFDM_6  3
+-#define RX_PPDU_START_SIG_RATE_OFDM_54 4
+-#define RX_PPDU_START_SIG_RATE_OFDM_36 5
+-#define RX_PPDU_START_SIG_RATE_OFDM_18 6
+-#define RX_PPDU_START_SIG_RATE_OFDM_9  7
+-
+-#define RX_PPDU_START_SIG_RATE_CCK_LP_11  0
+-#define RX_PPDU_START_SIG_RATE_CCK_LP_5_5 1
+-#define RX_PPDU_START_SIG_RATE_CCK_LP_2   2
+-#define RX_PPDU_START_SIG_RATE_CCK_LP_1   3
+-#define RX_PPDU_START_SIG_RATE_CCK_SP_11  4
+-#define RX_PPDU_START_SIG_RATE_CCK_SP_5_5 5
+-#define RX_PPDU_START_SIG_RATE_CCK_SP_2   6
+-
+ #define HTT_RX_PPDU_START_PREAMBLE_LEGACY        0x04
+ #define HTT_RX_PPDU_START_PREAMBLE_HT            0x08
+ #define HTT_RX_PPDU_START_PREAMBLE_HT_WITH_TXBF  0x09
+@@ -711,25 +691,6 @@ struct rx_msdu_end {
+ /* No idea what this flag means. It seems to be always set in rate. */
+ #define RX_PPDU_START_RATE_FLAG BIT(3)
+-enum rx_ppdu_start_rate {
+-      RX_PPDU_START_RATE_OFDM_48M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_48M,
+-      RX_PPDU_START_RATE_OFDM_24M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_24M,
+-      RX_PPDU_START_RATE_OFDM_12M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_12M,
+-      RX_PPDU_START_RATE_OFDM_6M  = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_6M,
+-      RX_PPDU_START_RATE_OFDM_54M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_54M,
+-      RX_PPDU_START_RATE_OFDM_36M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_36M,
+-      RX_PPDU_START_RATE_OFDM_18M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_18M,
+-      RX_PPDU_START_RATE_OFDM_9M  = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_9M,
+-
+-      RX_PPDU_START_RATE_CCK_LP_11M  = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_LP_11M,
+-      RX_PPDU_START_RATE_CCK_LP_5_5M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_LP_5_5M,
+-      RX_PPDU_START_RATE_CCK_LP_2M   = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_LP_2M,
+-      RX_PPDU_START_RATE_CCK_LP_1M   = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_LP_1M,
+-      RX_PPDU_START_RATE_CCK_SP_11M  = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_SP_11M,
+-      RX_PPDU_START_RATE_CCK_SP_5_5M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_SP_5_5M,
+-      RX_PPDU_START_RATE_CCK_SP_2M   = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_SP_2M,
+-};
+-
+ struct rx_ppdu_start {
+       struct {
+               u8 pri20_mhz;
diff --git a/package/kernel/mac80211/patches/309-ath10k-fix-CCK-h-w-rates-for-QCA99X0-and-newer-chips.patch b/package/kernel/mac80211/patches/309-ath10k-fix-CCK-h-w-rates-for-QCA99X0-and-newer-chips.patch
new file mode 100644 (file)
index 0000000..50ebfce
--- /dev/null
@@ -0,0 +1,141 @@
+From: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
+Date: Thu, 2 Jun 2016 19:54:42 +0530
+Subject: [PATCH] ath10k: fix CCK h/w rates for QCA99X0 and newer chipsets
+
+CCK hardware table mapping from QCA99X0 onwards got revised.
+The CCK hardware rate values are in a proper order wrt. to
+rate and preamble as below
+
+ATH10K_HW_RATE_REV2_CCK_LP_1M = 1,
+ATH10K_HW_RATE_REV2_CCK_LP_2M = 2,
+ATH10K_HW_RATE_REV2_CCK_LP_5_5M = 3,
+ATH10K_HW_RATE_REV2_CCK_LP_11M = 4,
+ATH10K_HW_RATE_REV2_CCK_SP_2M = 5,
+ATH10K_HW_RATE_REV2_CCK_SP_5_5M = 6,
+ATH10K_HW_RATE_REV2_CCK_SP_11M = 7,
+
+This results in reporting of rx frames (with CCK rates)
+totally wrong for QCA99X0, QCA4019. Fix this by having
+separate CCK rate table for these chipsets with rev2 suffix
+and registering the correct rate mapping to mac80211 based on
+the new hw_param (introduced) 'cck_rate_map_rev2' which shall
+be true for any newchipsets from QCA99X0 onwards
+
+Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
+---
+
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -148,6 +148,8 @@ static const struct ath10k_hw_params ath
+               .uart_pin = 7,
+               .otp_exe_param = 0x00000700,
+               .continuous_frag_desc = true,
++              .cck_rate_map_rev2 = true,
++              .cck_rate_map_rev2 = true,
+               .channel_counters_freq_hz = 150000,
+               .max_probe_resp_desc_thres = 24,
+               .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
+@@ -205,6 +207,7 @@ static const struct ath10k_hw_params ath
+               .has_shifted_cc_wraparound = true,
+               .otp_exe_param = 0x0010000,
+               .continuous_frag_desc = true,
++              .cck_rate_map_rev2 = true,
+               .channel_counters_freq_hz = 125000,
+               .max_probe_resp_desc_thres = 24,
+               .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
+--- a/drivers/net/wireless/ath/ath10k/core.h
++++ b/drivers/net/wireless/ath/ath10k/core.h
+@@ -716,6 +716,12 @@ struct ath10k {
+                */
+               bool continuous_frag_desc;
++              /* CCK hardware rate table mapping for the newer chipsets
++               * like QCA99X0, QCA4019 got revised. The CCK h/w rate values
++               * are in a proper order with respect to the rate/preamble
++               */
++              bool cck_rate_map_rev2;
++
+               u32 channel_counters_freq_hz;
+               /* Mgmt tx descriptors threshold for limiting probe response
+--- a/drivers/net/wireless/ath/ath10k/hw.h
++++ b/drivers/net/wireless/ath/ath10k/hw.h
+@@ -315,6 +315,16 @@ enum ath10k_hw_rate_cck {
+       ATH10K_HW_RATE_CCK_SP_2M,
+ };
++enum ath10k_hw_rate_rev2_cck {
++      ATH10K_HW_RATE_REV2_CCK_LP_1M = 1,
++      ATH10K_HW_RATE_REV2_CCK_LP_2M,
++      ATH10K_HW_RATE_REV2_CCK_LP_5_5M,
++      ATH10K_HW_RATE_REV2_CCK_LP_11M,
++      ATH10K_HW_RATE_REV2_CCK_SP_2M,
++      ATH10K_HW_RATE_REV2_CCK_SP_5_5M,
++      ATH10K_HW_RATE_REV2_CCK_SP_11M,
++};
++
+ enum ath10k_hw_4addr_pad {
+       ATH10K_HW_4ADDR_PAD_AFTER,
+       ATH10K_HW_4ADDR_PAD_BEFORE,
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -62,6 +62,32 @@ static struct ieee80211_rate ath10k_rate
+       { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
+ };
++static struct ieee80211_rate ath10k_rates_rev2[] = {
++      { .bitrate = 10,
++        .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_1M },
++      { .bitrate = 20,
++        .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_2M,
++        .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_2M,
++        .flags = IEEE80211_RATE_SHORT_PREAMBLE },
++      { .bitrate = 55,
++        .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_5_5M,
++        .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_5_5M,
++        .flags = IEEE80211_RATE_SHORT_PREAMBLE },
++      { .bitrate = 110,
++        .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_11M,
++        .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_11M,
++        .flags = IEEE80211_RATE_SHORT_PREAMBLE },
++
++      { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
++      { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
++      { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
++      { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
++      { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
++      { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
++      { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
++      { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
++};
++
+ #define ATH10K_MAC_FIRST_OFDM_RATE_IDX 4
+ #define ath10k_a_rates (ath10k_rates + ATH10K_MAC_FIRST_OFDM_RATE_IDX)
+@@ -70,6 +96,9 @@ static struct ieee80211_rate ath10k_rate
+ #define ath10k_g_rates (ath10k_rates + 0)
+ #define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
++#define ath10k_g_rates_rev2 (ath10k_rates_rev2 + 0)
++#define ath10k_g_rates_rev2_size (ARRAY_SIZE(ath10k_rates_rev2))
++
+ static bool ath10k_mac_bitrate_is_cck(int bitrate)
+ {
+       switch (bitrate) {
+@@ -7720,8 +7749,14 @@ int ath10k_mac_register(struct ath10k *a
+               band = &ar->mac.sbands[NL80211_BAND_2GHZ];
+               band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
+               band->channels = channels;
+-              band->n_bitrates = ath10k_g_rates_size;
+-              band->bitrates = ath10k_g_rates;
++
++              if (ar->hw_params.cck_rate_map_rev2) {
++                      band->n_bitrates = ath10k_g_rates_rev2_size;
++                      band->bitrates = ath10k_g_rates_rev2;
++              } else {
++                      band->n_bitrates = ath10k_g_rates_size;
++                      band->bitrates = ath10k_g_rates;
++              }
+               ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
+       }
index 6a904ec..9322b45 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
-@@ -2009,6 +2009,16 @@ int ath10k_core_register(struct ath10k *
+@@ -2012,6 +2012,16 @@ int ath10k_core_register(struct ath10k *
        ar->chip_id = chip_id;
        queue_work(ar->workqueue, &ar->register_work);
  
index 60b5b1b..92ed7a0 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath10k/mac.c
 +++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -7662,6 +7662,21 @@ struct ath10k_vif *ath10k_get_arvif(stru
+@@ -7716,6 +7716,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[] = {
-@@ -7880,6 +7895,12 @@ int ath10k_mac_register(struct ath10k *a
+@@ -7940,6 +7955,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);
  
index 39aba41..9a7e81b 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath10k/core.c
 +++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -1165,9 +1165,6 @@ static int ath10k_core_fetch_firmware_fi
+@@ -1168,9 +1168,6 @@ static int ath10k_core_fetch_firmware_fi
  {
        int ret;
  
@@ -10,7 +10,7 @@
        ar->fw_api = 5;
        ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
  
-@@ -1870,6 +1867,9 @@ static int ath10k_core_probe_fw(struct a
+@@ -1873,6 +1870,9 @@ static int ath10k_core_probe_fw(struct a
                goto err_power_down;
        }
  
@@ -20,7 +20,7 @@
        ret = ath10k_core_fetch_firmware_files(ar);
        if (ret) {
                ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
-@@ -1892,11 +1892,14 @@ static int ath10k_core_probe_fw(struct a
+@@ -1895,11 +1895,14 @@ static int ath10k_core_probe_fw(struct a
                           "could not load pre cal data: %d\n", ret);
        }