From df7af9317b9fd9532497351288ff5697fe88e40d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 7 Jun 2016 13:27:26 +0200 Subject: [PATCH] ath10k: merge some pending stability fixes Signed-off-by: Felix Fietkau --- ...rx-compl-task-is-stopped-when-cleani.patch | 21 +++ ...e-peer_map-references-are-cleaned-up.patch | 60 ++++++++ ...10k-Clean-up-peer-when-sta-goes-away.patch | 32 ++++ ...e-duplicate-and-unused-rx-rate-flags.patch | 66 ++++++++ ...-w-rates-for-QCA99X0-and-newer-chips.patch | 141 ++++++++++++++++++ ...21-ath10k_init_devices_synchronously.patch | 2 +- .../930-ath10k_add_tpt_led_trigger.patch | 4 +- .../patches/936-ath10k_skip_otp_check.patch | 6 +- 8 files changed, 326 insertions(+), 6 deletions(-) create mode 100644 package/kernel/mac80211/patches/305-ath10k-Ensure-txrx-compl-task-is-stopped-when-cleani.patch create mode 100644 package/kernel/mac80211/patches/306-ath10k-Ensure-peer_map-references-are-cleaned-up.patch create mode 100644 package/kernel/mac80211/patches/307-ath10k-Clean-up-peer-when-sta-goes-away.patch create mode 100644 package/kernel/mac80211/patches/308-ath10k-remove-duplicate-and-unused-rx-rate-flags.patch create mode 100644 package/kernel/mac80211/patches/309-ath10k-fix-CCK-h-w-rates-for-QCA99X0-and-newer-chips.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 index 00000000000..73accd866b9 --- /dev/null +++ b/package/kernel/mac80211/patches/305-ath10k-Ensure-txrx-compl-task-is-stopped-when-cleani.patch @@ -0,0 +1,21 @@ +From: Ben Greear +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 +--- + +--- 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 index 00000000000..2979b4b57e5 --- /dev/null +++ b/package/kernel/mac80211/patches/306-ath10k-Ensure-peer_map-references-are-cleaned-up.patch @@ -0,0 +1,60 @@ +From: Ben Greear +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 +--- + +--- 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 index 00000000000..f814ae71873 --- /dev/null +++ b/package/kernel/mac80211/patches/307-ath10k-Clean-up-peer-when-sta-goes-away.patch @@ -0,0 +1,32 @@ +From: Ben Greear +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 +--- + +--- 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 index 00000000000..7c5c5bef7ae --- /dev/null +++ b/package/kernel/mac80211/patches/308-ath10k-remove-duplicate-and-unused-rx-rate-flags.patch @@ -0,0 +1,66 @@ +From: Mohammed Shafi Shajakhan +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 +--- + +--- 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 index 00000000000..50ebfcef04a --- /dev/null +++ b/package/kernel/mac80211/patches/309-ath10k-fix-CCK-h-w-rates-for-QCA99X0-and-newer-chips.patch @@ -0,0 +1,141 @@ +From: Mohammed Shafi Shajakhan +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 +--- + +--- 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; + } 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 6a904ec7ce6..9322b455681 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 --- 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); 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 60b5b1be0c5..92ed7a0d9a6 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 -@@ -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); diff --git a/package/kernel/mac80211/patches/936-ath10k_skip_otp_check.patch b/package/kernel/mac80211/patches/936-ath10k_skip_otp_check.patch index 39aba41df4d..9a7e81ba7d5 100644 --- a/package/kernel/mac80211/patches/936-ath10k_skip_otp_check.patch +++ b/package/kernel/mac80211/patches/936-ath10k_skip_otp_check.patch @@ -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); } -- 2.30.2