From 31561e8557cd1eeba5806ac9ce820f8323b2201b Mon Sep 17 00:00:00 2001 From: Rakesh Pillai Date: Sat, 12 Dec 2020 00:30:10 +0530 Subject: [PATCH 01/35] ath10k: Fix error handling in case of CE pipe init failure Currently if the copy engine pipe init fails for snoc based chipsets, the rri is not freed. Fix this error handling for copy engine pipe init failure. Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.1-01040-QCAHLSWMTPLZ-1 Fixes: 4945af5b264f ("ath10k: enable SRRI/DRRI support on ddr for WCN3990") Signed-off-by: Rakesh Pillai Reviewed-by: Brian Norris Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1607713210-18320-1-git-send-email-pillair@codeaurora.org --- drivers/net/wireless/ath/ath10k/snoc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c index bf9a8cb713dc..1c3307e3b108 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.c +++ b/drivers/net/wireless/ath/ath10k/snoc.c @@ -1045,12 +1045,13 @@ static int ath10k_snoc_hif_power_up(struct ath10k *ar, ret = ath10k_snoc_init_pipes(ar); if (ret) { ath10k_err(ar, "failed to initialize CE: %d\n", ret); - goto err_wlan_enable; + goto err_free_rri; } return 0; -err_wlan_enable: +err_free_rri: + ath10k_ce_free_rri(ar); ath10k_snoc_wlan_disable(ar); return ret; From 5f1aa93ffa1f36577d0c18e91269f0ffd491e822 Mon Sep 17 00:00:00 2001 From: Rakesh Pillai Date: Sat, 12 Dec 2020 00:30:30 +0530 Subject: [PATCH 02/35] ath10k: Remove voltage regulator votes during wifi disable When the wlan is disabled, i.e when all the interfaces are deleted, voltage regulator votes are not removed. This leads to more power consumption even when wlan is disabled. Move the adding/removing of voltage regulator votes as part of hif power on/off in SNOC targets, so that these voltage regulator votes are there only when wlan is enabled. Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.1-01040-QCAHLSWMTPLZ-1 Signed-off-by: Rakesh Pillai Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1607713230-18382-1-git-send-email-pillair@codeaurora.org --- drivers/net/wireless/ath/ath10k/snoc.c | 92 +++++++++++++------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c index 1c3307e3b108..9b3de8e7bd10 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.c +++ b/drivers/net/wireless/ath/ath10k/snoc.c @@ -1003,6 +1003,39 @@ static int ath10k_snoc_wlan_enable(struct ath10k *ar, NULL); } +static int ath10k_hw_power_on(struct ath10k *ar) +{ + struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); + int ret; + + ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power on\n"); + + ret = regulator_bulk_enable(ar_snoc->num_vregs, ar_snoc->vregs); + if (ret) + return ret; + + ret = clk_bulk_prepare_enable(ar_snoc->num_clks, ar_snoc->clks); + if (ret) + goto vreg_off; + + return ret; + +vreg_off: + regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); + return ret; +} + +static int ath10k_hw_power_off(struct ath10k *ar) +{ + struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); + + ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power off\n"); + + clk_bulk_disable_unprepare(ar_snoc->num_clks, ar_snoc->clks); + + return regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); +} + static void ath10k_snoc_wlan_disable(struct ath10k *ar) { struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); @@ -1024,6 +1057,7 @@ static void ath10k_snoc_hif_power_down(struct ath10k *ar) ath10k_snoc_wlan_disable(ar); ath10k_ce_free_rri(ar); + ath10k_hw_power_off(ar); } static int ath10k_snoc_hif_power_up(struct ath10k *ar, @@ -1034,10 +1068,16 @@ static int ath10k_snoc_hif_power_up(struct ath10k *ar, ath10k_dbg(ar, ATH10K_DBG_SNOC, "%s:WCN3990 driver state = %d\n", __func__, ar->state); + ret = ath10k_hw_power_on(ar); + if (ret) { + ath10k_err(ar, "failed to power on device: %d\n", ret); + return ret; + } + ret = ath10k_snoc_wlan_enable(ar, fw_mode); if (ret) { ath10k_err(ar, "failed to enable wcn3990: %d\n", ret); - return ret; + goto err_hw_power_off; } ath10k_ce_alloc_rri(ar); @@ -1054,6 +1094,9 @@ err_free_rri: ath10k_ce_free_rri(ar); ath10k_snoc_wlan_disable(ar); +err_hw_power_off: + ath10k_hw_power_off(ar); + return ret; } @@ -1370,39 +1413,6 @@ static void ath10k_snoc_release_resource(struct ath10k *ar) ath10k_ce_free_pipe(ar, i); } -static int ath10k_hw_power_on(struct ath10k *ar) -{ - struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); - int ret; - - ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power on\n"); - - ret = regulator_bulk_enable(ar_snoc->num_vregs, ar_snoc->vregs); - if (ret) - return ret; - - ret = clk_bulk_prepare_enable(ar_snoc->num_clks, ar_snoc->clks); - if (ret) - goto vreg_off; - - return ret; - -vreg_off: - regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); - return ret; -} - -static int ath10k_hw_power_off(struct ath10k *ar) -{ - struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); - - ath10k_dbg(ar, ATH10K_DBG_SNOC, "soc power off\n"); - - clk_bulk_disable_unprepare(ar_snoc->num_clks, ar_snoc->clks); - - return regulator_bulk_disable(ar_snoc->num_vregs, ar_snoc->vregs); -} - static void ath10k_msa_dump_memory(struct ath10k *ar, struct ath10k_fw_crash_data *crash_data) { @@ -1712,22 +1722,16 @@ static int ath10k_snoc_probe(struct platform_device *pdev) if (ret) goto err_free_irq; - ret = ath10k_hw_power_on(ar); - if (ret) { - ath10k_err(ar, "failed to power on device: %d\n", ret); - goto err_free_irq; - } - ret = ath10k_setup_msa_resources(ar, msa_size); if (ret) { ath10k_warn(ar, "failed to setup msa resources: %d\n", ret); - goto err_power_off; + goto err_free_irq; } ret = ath10k_fw_init(ar); if (ret) { ath10k_err(ar, "failed to initialize firmware: %d\n", ret); - goto err_power_off; + goto err_free_irq; } ret = ath10k_qmi_init(ar, msa_size); @@ -1743,9 +1747,6 @@ static int ath10k_snoc_probe(struct platform_device *pdev) err_fw_deinit: ath10k_fw_deinit(ar); -err_power_off: - ath10k_hw_power_off(ar); - err_free_irq: ath10k_snoc_free_irq(ar); @@ -1773,7 +1774,6 @@ static int ath10k_snoc_remove(struct platform_device *pdev) set_bit(ATH10K_SNOC_FLAG_UNREGISTERING, &ar_snoc->flags); ath10k_core_unregister(ar); - ath10k_hw_power_off(ar); ath10k_fw_deinit(ar); ath10k_snoc_free_irq(ar); ath10k_snoc_release_resource(ar); From 56c5485c9e444c2e85e11694b6c44f1338fc20fd Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 14 Dec 2020 19:21:14 +0200 Subject: [PATCH 03/35] ath: Use safer key clearing with key cache entries It is possible for there to be pending frames in TXQs with a reference to the key cache entry that is being deleted. If such a key cache entry is cleared, those pending frame in TXQ might get transmitted without proper encryption. It is safer to leave the previously used key into the key cache in such cases. Instead, only clear the MAC address to prevent RX processing from using this key cache entry. This is needed in particularly in AP mode where the TXQs cannot be flushed on station disconnection. This change alone may not be able to address all cases where the key cache entry might get reused for other purposes immediately (the key cache entry should be released for reuse only once the TXQs do not have any remaining references to them), but this makes it less likely to get unprotected frames and the more complete changes may end up being significantly more complex. Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201214172118.18100-2-jouni@codeaurora.org --- drivers/net/wireless/ath/key.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 1816b4e7dc26..59618bb41f6c 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -583,7 +583,16 @@ EXPORT_SYMBOL(ath_key_config); */ void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) { - ath_hw_keyreset(common, key->hw_key_idx); + /* Leave CCMP and TKIP (main key) configured to avoid disabling + * encryption for potentially pending frames already in a TXQ with the + * keyix pointing to this key entry. Instead, only clear the MAC address + * to prevent RX processing from using this key cache entry. + */ + if (test_bit(key->hw_key_idx, common->ccmp_keymap) || + test_bit(key->hw_key_idx, common->tkip_keymap)) + ath_hw_keysetmac(common, key->hw_key_idx, NULL); + else + ath_hw_keyreset(common, key->hw_key_idx); if (key->hw_key_idx < IEEE80211_WEP_NKID) return; From 73488cb2fa3bb1ef9f6cf0d757f76958bd4deaca Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 14 Dec 2020 19:21:15 +0200 Subject: [PATCH 04/35] ath9k: Clear key cache explicitly on disabling hardware Now that ath/key.c may not be explicitly clearing keys from the key cache, clear all key cache entries when disabling hardware to make sure no keys are left behind beyond this point. Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201214172118.18100-3-jouni@codeaurora.org --- drivers/net/wireless/ath/ath9k/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index caebe3fd6869..10b87aa1d289 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -894,6 +894,11 @@ static void ath9k_stop(struct ieee80211_hw *hw) spin_unlock_bh(&sc->sc_pcu_lock); + /* Clear key cache entries explicitly to get rid of any potentially + * remaining keys. + */ + ath9k_cmn_init_crypto(sc->sc_ah); + ath9k_ps_restore(sc); sc->ps_idle = prev_idle; From d2d3e36498dd8e0c83ea99861fac5cf9e8671226 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 14 Dec 2020 19:21:16 +0200 Subject: [PATCH 05/35] ath: Export ath_hw_keysetmac() ath9k is going to use this for safer management of key cache entries. Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201214172118.18100-4-jouni@codeaurora.org --- drivers/net/wireless/ath/ath.h | 1 + drivers/net/wireless/ath/key.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 7a364eca46d6..9d18105c449f 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -203,6 +203,7 @@ int ath_key_config(struct ath_common *common, struct ieee80211_sta *sta, struct ieee80211_key_conf *key); bool ath_hw_keyreset(struct ath_common *common, u16 entry); +bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac); void ath_hw_cycle_counters_update(struct ath_common *common); int32_t ath_hw_get_listen_time(struct ath_common *common); diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 59618bb41f6c..cb266cf3c77c 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -84,8 +84,7 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry) } EXPORT_SYMBOL(ath_hw_keyreset); -static bool ath_hw_keysetmac(struct ath_common *common, - u16 entry, const u8 *mac) +bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac) { u32 macHi, macLo; u32 unicast_flag = AR_KEYTABLE_VALID; @@ -125,6 +124,7 @@ static bool ath_hw_keysetmac(struct ath_common *common, return true; } +EXPORT_SYMBOL(ath_hw_keysetmac); static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, const struct ath_keyval *k, From 144cd24dbc36650a51f7fe3bf1424a1432f1f480 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 14 Dec 2020 19:21:17 +0200 Subject: [PATCH 06/35] ath: Modify ath_key_delete() to not need full key entry tkip_keymap can be used internally to avoid the reference to key->cipher and with this, only the key index value itself is needed. This allows ath_key_delete() call to be postponed to be handled after the upper layer STA and key entry have already been removed. This is needed to make ath9k key cache management safer. Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201214172118.18100-5-jouni@codeaurora.org --- drivers/net/wireless/ath/ath.h | 2 +- drivers/net/wireless/ath/ath5k/mac80211-ops.c | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 2 +- drivers/net/wireless/ath/ath9k/main.c | 5 ++- drivers/net/wireless/ath/key.c | 34 +++++++++---------- 5 files changed, 22 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 9d18105c449f..f083fb9038c3 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -197,7 +197,7 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, bool ath_is_mybeacon(struct ath_common *common, struct ieee80211_hdr *hdr); void ath_hw_setbssidmask(struct ath_common *common); -void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key); +void ath_key_delete(struct ath_common *common, u8 hw_key_idx); int ath_key_config(struct ath_common *common, struct ieee80211_vif *vif, struct ieee80211_sta *sta, diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 8f2719ff463c..532eeac9e83e 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -522,7 +522,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, } break; case DISABLE_KEY: - ath_key_delete(common, key); + ath_key_delete(common, key->hw_key_idx); break; default: ret = -EINVAL; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 2b7832b1c800..72ef319feeda 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1461,7 +1461,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, } break; case DISABLE_KEY: - ath_key_delete(common, key); + ath_key_delete(common, key->hw_key_idx); break; default: ret = -EINVAL; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 10b87aa1d289..bcdf150060f2 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1543,12 +1543,11 @@ static void ath9k_del_ps_key(struct ath_softc *sc, { struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_node *an = (struct ath_node *) sta->drv_priv; - struct ieee80211_key_conf ps_key = { .hw_key_idx = an->ps_key }; if (!an->ps_key) return; - ath_key_delete(common, &ps_key); + ath_key_delete(common, an->ps_key); an->ps_key = 0; an->key_idx[0] = 0; } @@ -1748,7 +1747,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, } break; case DISABLE_KEY: - ath_key_delete(common, key); + ath_key_delete(common, key->hw_key_idx); if (an) { for (i = 0; i < ARRAY_SIZE(an->key_idx); i++) { if (an->key_idx[i] != key->hw_key_idx) diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index cb266cf3c77c..61b59a804e30 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -581,38 +581,38 @@ EXPORT_SYMBOL(ath_key_config); /* * Delete Key. */ -void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) +void ath_key_delete(struct ath_common *common, u8 hw_key_idx) { /* Leave CCMP and TKIP (main key) configured to avoid disabling * encryption for potentially pending frames already in a TXQ with the * keyix pointing to this key entry. Instead, only clear the MAC address * to prevent RX processing from using this key cache entry. */ - if (test_bit(key->hw_key_idx, common->ccmp_keymap) || - test_bit(key->hw_key_idx, common->tkip_keymap)) - ath_hw_keysetmac(common, key->hw_key_idx, NULL); + if (test_bit(hw_key_idx, common->ccmp_keymap) || + test_bit(hw_key_idx, common->tkip_keymap)) + ath_hw_keysetmac(common, hw_key_idx, NULL); else - ath_hw_keyreset(common, key->hw_key_idx); - if (key->hw_key_idx < IEEE80211_WEP_NKID) + ath_hw_keyreset(common, hw_key_idx); + if (hw_key_idx < IEEE80211_WEP_NKID) return; - clear_bit(key->hw_key_idx, common->keymap); - clear_bit(key->hw_key_idx, common->ccmp_keymap); - if (key->cipher != WLAN_CIPHER_SUITE_TKIP) + clear_bit(hw_key_idx, common->keymap); + clear_bit(hw_key_idx, common->ccmp_keymap); + if (!test_bit(hw_key_idx, common->tkip_keymap)) return; - clear_bit(key->hw_key_idx + 64, common->keymap); + clear_bit(hw_key_idx + 64, common->keymap); - clear_bit(key->hw_key_idx, common->tkip_keymap); - clear_bit(key->hw_key_idx + 64, common->tkip_keymap); + clear_bit(hw_key_idx, common->tkip_keymap); + clear_bit(hw_key_idx + 64, common->tkip_keymap); if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { - ath_hw_keyreset(common, key->hw_key_idx + 32); - clear_bit(key->hw_key_idx + 32, common->keymap); - clear_bit(key->hw_key_idx + 64 + 32, common->keymap); + ath_hw_keyreset(common, hw_key_idx + 32); + clear_bit(hw_key_idx + 32, common->keymap); + clear_bit(hw_key_idx + 64 + 32, common->keymap); - clear_bit(key->hw_key_idx + 32, common->tkip_keymap); - clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap); + clear_bit(hw_key_idx + 32, common->tkip_keymap); + clear_bit(hw_key_idx + 64 + 32, common->tkip_keymap); } } EXPORT_SYMBOL(ath_key_delete); From ca2848022c12789685d3fab3227df02b863f9696 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 14 Dec 2020 19:21:18 +0200 Subject: [PATCH 07/35] ath9k: Postpone key cache entry deletion for TXQ frames reference it Do not delete a key cache entry that is still being referenced by pending frames in TXQs. This avoids reuse of the key cache entry while a frame might still be transmitted using it. To avoid having to do any additional operations during the main TX path operations, track pending key cache entries in a new bitmap and check whether any pending entries can be deleted before every new key add/remove operation. Also clear any remaining entries when stopping the interface. Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201214172118.18100-6-jouni@codeaurora.org --- drivers/net/wireless/ath/ath9k/hw.h | 1 + drivers/net/wireless/ath/ath9k/main.c | 87 ++++++++++++++++++++++++++- 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 023599e10dd5..b7b65b1c90e8 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -820,6 +820,7 @@ struct ath_hw { struct ath9k_pacal_info pacal_info; struct ar5416Stats stats; struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; + DECLARE_BITMAP(pending_del_keymap, ATH_KEYMAX); enum ath9k_int imask; u32 imrs2_reg; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index bcdf150060f2..45f6402478b5 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -821,12 +821,80 @@ exit: ieee80211_free_txskb(hw, skb); } +static bool ath9k_txq_list_has_key(struct list_head *txq_list, u32 keyix) +{ + struct ath_buf *bf; + struct ieee80211_tx_info *txinfo; + struct ath_frame_info *fi; + + list_for_each_entry(bf, txq_list, list) { + if (bf->bf_state.stale || !bf->bf_mpdu) + continue; + + txinfo = IEEE80211_SKB_CB(bf->bf_mpdu); + fi = (struct ath_frame_info *)&txinfo->rate_driver_data[0]; + if (fi->keyix == keyix) + return true; + } + + return false; +} + +static bool ath9k_txq_has_key(struct ath_softc *sc, u32 keyix) +{ + struct ath_hw *ah = sc->sc_ah; + int i; + struct ath_txq *txq; + bool key_in_use = false; + + for (i = 0; !key_in_use && i < ATH9K_NUM_TX_QUEUES; i++) { + if (!ATH_TXQ_SETUP(sc, i)) + continue; + txq = &sc->tx.txq[i]; + if (!txq->axq_depth) + continue; + if (!ath9k_hw_numtxpending(ah, txq->axq_qnum)) + continue; + + ath_txq_lock(sc, txq); + key_in_use = ath9k_txq_list_has_key(&txq->axq_q, keyix); + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { + int idx = txq->txq_tailidx; + + while (!key_in_use && + !list_empty(&txq->txq_fifo[idx])) { + key_in_use = ath9k_txq_list_has_key( + &txq->txq_fifo[idx], keyix); + INCR(idx, ATH_TXFIFO_DEPTH); + } + } + ath_txq_unlock(sc, txq); + } + + return key_in_use; +} + +static void ath9k_pending_key_del(struct ath_softc *sc, u8 keyix) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + + if (!test_bit(keyix, ah->pending_del_keymap) || + ath9k_txq_has_key(sc, keyix)) + return; + + /* No more TXQ frames point to this key cache entry, so delete it. */ + clear_bit(keyix, ah->pending_del_keymap); + ath_key_delete(common, keyix); +} + static void ath9k_stop(struct ieee80211_hw *hw) { struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); bool prev_idle; + int i; ath9k_deinit_channel_context(sc); @@ -894,6 +962,9 @@ static void ath9k_stop(struct ieee80211_hw *hw) spin_unlock_bh(&sc->sc_pcu_lock); + for (i = 0; i < ATH_KEYMAX; i++) + ath9k_pending_key_del(sc, i); + /* Clear key cache entries explicitly to get rid of any potentially * remaining keys. */ @@ -1718,6 +1789,12 @@ static int ath9k_set_key(struct ieee80211_hw *hw, if (sta) an = (struct ath_node *)sta->drv_priv; + /* Delete pending key cache entries if no more frames are pointing to + * them in TXQs. + */ + for (i = 0; i < ATH_KEYMAX; i++) + ath9k_pending_key_del(sc, i); + switch (cmd) { case SET_KEY: if (sta) @@ -1747,7 +1824,15 @@ static int ath9k_set_key(struct ieee80211_hw *hw, } break; case DISABLE_KEY: - ath_key_delete(common, key->hw_key_idx); + if (ath9k_txq_has_key(sc, key->hw_key_idx)) { + /* Delay key cache entry deletion until there are no + * remaining TXQ frames pointing to this entry. + */ + set_bit(key->hw_key_idx, sc->sc_ah->pending_del_keymap); + ath_hw_keysetmac(common, key->hw_key_idx, NULL); + } else { + ath_key_delete(common, key->hw_key_idx); + } if (an) { for (i = 0; i < ARRAY_SIZE(an->key_idx); i++) { if (an->key_idx[i] != key->hw_key_idx) From e2f8b74e58cb1560c1399ba94a470b770e858259 Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Tue, 15 Dec 2020 08:35:04 +0200 Subject: [PATCH 08/35] ath10k: prevent deinitializing NAPI twice It happened "Kernel panic - not syncing: hung_task: blocked tasks" when test simulate crash and ifconfig down/rmmod meanwhile. Test steps: 1.Test commands, either can reproduce the hang for PCIe, SDIO and SNOC. echo soft > /sys/kernel/debug/ieee80211/phy0/ath10k/simulate_fw_crash;sleep 0.05;ifconfig wlan0 down echo soft > /sys/kernel/debug/ieee80211/phy0/ath10k/simulate_fw_crash;rmmod ath10k_sdio echo hw-restart > /sys/kernel/debug/ieee80211/phy0/ath10k/simulate_fw_crash;rmmod ath10k_pci 2. dmesg: [ 5622.548630] ath10k_sdio mmc1:0001:1: simulating soft firmware crash [ 5622.655995] ieee80211 phy0: Hardware restart was requested [ 5776.355164] INFO: task shill:1572 blocked for more than 122 seconds. [ 5776.355687] INFO: task kworker/1:2:24437 blocked for more than 122 seconds. [ 5776.359812] Kernel panic - not syncing: hung_task: blocked tasks [ 5776.359836] CPU: 1 PID: 55 Comm: khungtaskd Tainted: G W 4.19.86 #137 [ 5776.359846] Hardware name: MediaTek krane sku176 board (DT) [ 5776.359855] Call trace: [ 5776.359868] dump_backtrace+0x0/0x170 [ 5776.359881] show_stack+0x20/0x2c [ 5776.359896] dump_stack+0xd4/0x10c [ 5776.359916] panic+0x12c/0x29c [ 5776.359937] hung_task_panic+0x0/0x50 [ 5776.359953] kthread+0x120/0x130 [ 5776.359965] ret_from_fork+0x10/0x18 [ 5776.359986] SMP: stopping secondary CPUs [ 5776.360012] Kernel Offset: 0x141ea00000 from 0xffffff8008000000 [ 5776.360026] CPU features: 0x0,2188200c [ 5776.360035] Memory Limit: none command "ifconfig wlan0 down" or "rmmod ath10k_sdio" will be blocked callstack of ifconfig: [<0>] __switch_to+0x120/0x13c [<0>] msleep+0x28/0x38 [<0>] ath10k_sdio_hif_stop+0x24c/0x294 [ath10k_sdio] [<0>] ath10k_core_stop+0x50/0x78 [ath10k_core] [<0>] ath10k_halt+0x120/0x178 [ath10k_core] [<0>] ath10k_stop+0x4c/0x8c [ath10k_core] [<0>] drv_stop+0xe0/0x1e4 [mac80211] [<0>] ieee80211_stop_device+0x48/0x54 [mac80211] [<0>] ieee80211_do_stop+0x678/0x6f8 [mac80211] [<0>] ieee80211_stop+0x20/0x30 [mac80211] [<0>] __dev_close_many+0xb8/0x11c [<0>] __dev_change_flags+0xe0/0x1d0 [<0>] dev_change_flags+0x30/0x6c [<0>] devinet_ioctl+0x370/0x564 [<0>] inet_ioctl+0xdc/0x304 [<0>] sock_do_ioctl+0x50/0x288 [<0>] compat_sock_ioctl+0x1b4/0x1aac [<0>] __se_compat_sys_ioctl+0x100/0x26fc [<0>] __arm64_compat_sys_ioctl+0x20/0x2c [<0>] el0_svc_common+0xa4/0x154 [<0>] el0_svc_compat_handler+0x2c/0x38 [<0>] el0_svc_compat+0x8/0x18 [<0>] 0xffffffffffffffff callstack of rmmod: [<0>] __switch_to+0x120/0x13c [<0>] msleep+0x28/0x38 [<0>] ath10k_sdio_hif_stop+0x294/0x31c [ath10k_sdio] [<0>] ath10k_core_stop+0x50/0x78 [ath10k_core] [<0>] ath10k_halt+0x120/0x178 [ath10k_core] [<0>] ath10k_stop+0x4c/0x8c [ath10k_core] [<0>] drv_stop+0xe0/0x1e4 [mac80211] [<0>] ieee80211_stop_device+0x48/0x54 [mac80211] [<0>] ieee80211_do_stop+0x678/0x6f8 [mac80211] [<0>] ieee80211_stop+0x20/0x30 [mac80211] [<0>] __dev_close_many+0xb8/0x11c [<0>] dev_close_many+0x70/0x100 [<0>] dev_close+0x4c/0x80 [<0>] cfg80211_shutdown_all_interfaces+0x50/0xcc [cfg80211] [<0>] ieee80211_remove_interfaces+0x58/0x1a0 [mac80211] [<0>] ieee80211_unregister_hw+0x40/0x100 [mac80211] [<0>] ath10k_mac_unregister+0x1c/0x44 [ath10k_core] [<0>] ath10k_core_unregister+0x38/0x7c [ath10k_core] [<0>] ath10k_sdio_remove+0x8c/0xd0 [ath10k_sdio] [<0>] sdio_bus_remove+0x48/0x108 [<0>] device_release_driver_internal+0x138/0x1ec [<0>] driver_detach+0x6c/0xa8 [<0>] bus_remove_driver+0x78/0xa8 [<0>] driver_unregister+0x30/0x50 [<0>] sdio_unregister_driver+0x28/0x34 [<0>] cleanup_module+0x14/0x6bc [ath10k_sdio] [<0>] __arm64_sys_delete_module+0x1e0/0x22c [<0>] el0_svc_common+0xa4/0x154 [<0>] el0_svc_compat_handler+0x2c/0x38 [<0>] el0_svc_compat+0x8/0x18 [<0>] 0xffffffffffffffff SNOC: [ 647.156863] Call trace: [ 647.162166] [] __switch_to+0x120/0x13c [ 647.164512] [] __schedule+0x5ec/0x798 [ 647.170062] [] schedule+0x74/0x94 [ 647.175050] [] schedule_timeout+0x314/0x42c [ 647.179874] [] schedule_timeout_uninterruptible+0x34/0x40 [ 647.185780] [] msleep+0x28/0x38 [ 647.192546] [] ath10k_snoc_hif_stop+0x4c/0x1e0 [ath10k_snoc] [ 647.197439] [] ath10k_core_stop+0x50/0x7c [ath10k_core] [ 647.204652] [] ath10k_halt+0x114/0x16c [ath10k_core] [ 647.211420] [] ath10k_stop+0x4c/0x88 [ath10k_core] [ 647.217865] [] drv_stop+0x110/0x244 [mac80211] [ 647.224367] [] ieee80211_stop_device+0x48/0x54 [mac80211] [ 647.230359] [] ieee80211_do_stop+0x6a4/0x73c [mac80211] [ 647.237033] [] ieee80211_stop+0x20/0x30 [mac80211] [ 647.243942] [] __dev_close_many+0xa0/0xfc [ 647.250435] [] dev_close_many+0x70/0x100 [ 647.255651] [] dev_close+0x4c/0x80 [ 647.261244] [] cfg80211_shutdown_all_interfaces+0x44/0xcc [cfg80211] [ 647.266383] [] ieee80211_remove_interfaces+0x58/0x1b4 [mac80211] [ 647.274128] [] ieee80211_unregister_hw+0x50/0x120 [mac80211] [ 647.281659] [] ath10k_mac_unregister+0x1c/0x44 [ath10k_core] [ 647.288839] [] ath10k_core_unregister+0x48/0x90 [ath10k_core] [ 647.296027] [] ath10k_snoc_remove+0x5c/0x150 [ath10k_snoc] [ 647.303229] [] platform_drv_remove+0x28/0x50 [ 647.310517] [] device_release_driver_internal+0x114/0x1b8 [ 647.316257] [] driver_detach+0x6c/0xa8 [ 647.323021] [] bus_remove_driver+0x78/0xa8 [ 647.328571] [] driver_unregister+0x30/0x50 [ 647.334213] [] platform_driver_unregister+0x1c/0x28 [ 647.339876] [] cleanup_module+0x1c/0x120 [ath10k_snoc] [ 647.346196] [] SyS_delete_module+0x1dc/0x22c PCIe: [ 615.392770] rmmod D 0 3523 3458 0x00000080 [ 615.392777] Call Trace: [ 615.392784] __schedule+0x617/0x7d3 [ 615.392791] ? __mod_timer+0x263/0x35c [ 615.392797] schedule+0x62/0x72 [ 615.392803] schedule_timeout+0x8d/0xf3 [ 615.392809] ? run_local_timers+0x6b/0x6b [ 615.392814] msleep+0x1b/0x22 [ 615.392824] ath10k_pci_hif_stop+0x68/0xd6 [ath10k_pci] [ 615.392844] ath10k_core_stop+0x44/0x67 [ath10k_core] [ 615.392859] ath10k_halt+0x102/0x153 [ath10k_core] [ 615.392873] ath10k_stop+0x38/0x75 [ath10k_core] [ 615.392893] drv_stop+0x9a/0x13c [mac80211] [ 615.392915] ieee80211_do_stop+0x772/0x7cd [mac80211] [ 615.392937] ieee80211_stop+0x1a/0x1e [mac80211] [ 615.392945] __dev_close_many+0x9e/0xf0 [ 615.392952] dev_close_many+0x62/0xe8 [ 615.392958] dev_close+0x54/0x7d [ 615.392975] cfg80211_shutdown_all_interfaces+0x6e/0xa5 [cfg80211] [ 615.393021] ieee80211_remove_interfaces+0x52/0x1aa [mac80211] [ 615.393049] ieee80211_unregister_hw+0x54/0x136 [mac80211] [ 615.393068] ath10k_mac_unregister+0x19/0x4a [ath10k_core] [ 615.393091] ath10k_core_unregister+0x39/0x7e [ath10k_core] [ 615.393104] ath10k_pci_remove+0x3d/0x7f [ath10k_pci] [ 615.393117] pci_device_remove+0x41/0xa6 [ 615.393129] device_release_driver_internal+0x123/0x1ec [ 615.393140] driver_detach+0x60/0x90 [ 615.393152] bus_remove_driver+0x72/0x9f [ 615.393164] pci_unregister_driver+0x1e/0x87 [ 615.393177] SyS_delete_module+0x1d7/0x277 [ 615.393188] do_syscall_64+0x6b/0xf7 [ 615.393199] entry_SYSCALL_64_after_hwframe+0x41/0xa6 The test command run simulate_fw_crash firstly and it call into ath10k_sdio_hif_stop from ath10k_core_restart, then napi_disable is called and bit NAPI_STATE_SCHED is set. After that, function ath10k_sdio_hif_stop is called again from ath10k_stop by command "ifconfig wlan0 down" or "rmmod ath10k_sdio", then command blocked. It is blocked by napi_synchronize, napi_disable will set bit with NAPI_STATE_SCHED, and then napi_synchronize will enter dead loop becuase bit NAPI_STATE_SCHED is set by napi_disable. function of napi_synchronize static inline void napi_synchronize(const struct napi_struct *n) { if (IS_ENABLED(CONFIG_SMP)) while (test_bit(NAPI_STATE_SCHED, &n->state)) msleep(1); else barrier(); } function of napi_disable void napi_disable(struct napi_struct *n) { might_sleep(); set_bit(NAPI_STATE_DISABLE, &n->state); while (test_and_set_bit(NAPI_STATE_SCHED, &n->state)) msleep(1); while (test_and_set_bit(NAPI_STATE_NPSVC, &n->state)) msleep(1); hrtimer_cancel(&n->timer); clear_bit(NAPI_STATE_DISABLE, &n->state); } Add flag for it avoid the hang and crash. Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00049 Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00110-QCARMSWP-1 Tested-on: WCN3990 hw1.0 SNOC hw1.0 WLAN.HL.3.1-01307.1-QCAHLSWMTPL-2 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1598617348-2325-1-git-send-email-wgong@codeaurora.org --- drivers/net/wireless/ath/ath10k/ahb.c | 5 ++--- drivers/net/wireless/ath/ath10k/core.c | 25 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/core.h | 5 +++++ drivers/net/wireless/ath/ath10k/pci.c | 7 ++++--- drivers/net/wireless/ath/ath10k/sdio.c | 5 ++--- drivers/net/wireless/ath/ath10k/snoc.c | 6 +++--- 6 files changed, 41 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/ahb.c b/drivers/net/wireless/ath/ath10k/ahb.c index 05a61975c83f..869524852fba 100644 --- a/drivers/net/wireless/ath/ath10k/ahb.c +++ b/drivers/net/wireless/ath/ath10k/ahb.c @@ -626,7 +626,7 @@ static int ath10k_ahb_hif_start(struct ath10k *ar) { ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot ahb hif start\n"); - napi_enable(&ar->napi); + ath10k_core_napi_enable(ar); ath10k_ce_enable_interrupts(ar); ath10k_pci_enable_legacy_irq(ar); @@ -644,8 +644,7 @@ static void ath10k_ahb_hif_stop(struct ath10k *ar) ath10k_ahb_irq_disable(ar); synchronize_irq(ar_ahb->irq); - napi_synchronize(&ar->napi); - napi_disable(&ar->napi); + ath10k_core_napi_sync_disable(ar); ath10k_pci_flush(ar); } diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index eeb6ff6aa2e1..a419ec7130f9 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -2305,6 +2305,31 @@ void ath10k_core_start_recovery(struct ath10k *ar) } EXPORT_SYMBOL(ath10k_core_start_recovery); +void ath10k_core_napi_enable(struct ath10k *ar) +{ + lockdep_assert_held(&ar->conf_mutex); + + if (test_bit(ATH10K_FLAG_NAPI_ENABLED, &ar->dev_flags)) + return; + + napi_enable(&ar->napi); + set_bit(ATH10K_FLAG_NAPI_ENABLED, &ar->dev_flags); +} +EXPORT_SYMBOL(ath10k_core_napi_enable); + +void ath10k_core_napi_sync_disable(struct ath10k *ar) +{ + lockdep_assert_held(&ar->conf_mutex); + + if (!test_bit(ATH10K_FLAG_NAPI_ENABLED, &ar->dev_flags)) + return; + + napi_synchronize(&ar->napi); + napi_disable(&ar->napi); + clear_bit(ATH10K_FLAG_NAPI_ENABLED, &ar->dev_flags); +} +EXPORT_SYMBOL(ath10k_core_napi_sync_disable); + static void ath10k_core_restart(struct work_struct *work) { struct ath10k *ar = container_of(work, struct ath10k, restart_work); diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 51f7e960e297..f4be6bfb2539 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -868,6 +868,9 @@ enum ath10k_dev_flags { /* Indicates that ath10k device is during recovery process and not complete */ ATH10K_FLAG_RESTARTING, + + /* protected by conf_mutex */ + ATH10K_FLAG_NAPI_ENABLED, }; enum ath10k_cal_mode { @@ -1308,6 +1311,8 @@ static inline bool ath10k_peer_stats_enabled(struct ath10k *ar) extern unsigned long ath10k_coredump_mask; +void ath10k_core_napi_sync_disable(struct ath10k *ar); +void ath10k_core_napi_enable(struct ath10k *ar); struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, enum ath10k_bus bus, enum ath10k_hw_rev hw_rev, diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 2328df09875c..e7fde635e0ee 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1958,7 +1958,7 @@ static int ath10k_pci_hif_start(struct ath10k *ar) ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif start\n"); - napi_enable(&ar->napi); + ath10k_core_napi_enable(ar); ath10k_pci_irq_enable(ar); ath10k_pci_rx_post(ar); @@ -2075,8 +2075,9 @@ static void ath10k_pci_hif_stop(struct ath10k *ar) ath10k_pci_irq_disable(ar); ath10k_pci_irq_sync(ar); - napi_synchronize(&ar->napi); - napi_disable(&ar->napi); + + ath10k_core_napi_sync_disable(ar); + cancel_work_sync(&ar_pci->dump_work); /* Most likely the device has HTT Rx ring configured. The only way to diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c index c415090d1f37..b746052737e0 100644 --- a/drivers/net/wireless/ath/ath10k/sdio.c +++ b/drivers/net/wireless/ath/ath10k/sdio.c @@ -1859,7 +1859,7 @@ static int ath10k_sdio_hif_start(struct ath10k *ar) struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar); int ret; - napi_enable(&ar->napi); + ath10k_core_napi_enable(ar); /* Sleep 20 ms before HIF interrupts are disabled. * This will give target plenty of time to process the BMI done @@ -1992,8 +1992,7 @@ static void ath10k_sdio_hif_stop(struct ath10k *ar) spin_unlock_bh(&ar_sdio->wr_async_lock); - napi_synchronize(&ar->napi); - napi_disable(&ar->napi); + ath10k_core_napi_sync_disable(ar); } #ifdef CONFIG_PM diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c index 9b3de8e7bd10..d66593f0950f 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.c +++ b/drivers/net/wireless/ath/ath10k/snoc.c @@ -915,8 +915,7 @@ static void ath10k_snoc_hif_stop(struct ath10k *ar) if (!test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) ath10k_snoc_irq_disable(ar); - napi_synchronize(&ar->napi); - napi_disable(&ar->napi); + ath10k_core_napi_sync_disable(ar); ath10k_snoc_buffer_cleanup(ar); ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif stop\n"); } @@ -926,7 +925,8 @@ static int ath10k_snoc_hif_start(struct ath10k *ar) struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); bitmap_clear(ar_snoc->pending_ce_irqs, 0, CE_COUNT_MAX); - napi_enable(&ar->napi); + + ath10k_core_napi_enable(ar); ath10k_snoc_irq_enable(ar); ath10k_snoc_rx_post(ar); From 562934ada52a5a915d682aae22340ed48b7221b7 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Wed, 16 Dec 2020 20:24:11 +0200 Subject: [PATCH 09/35] ath11k: pci: remove unnecessary mask in ath11k_pci_enable_ltssm() 0x10 is a leftover and unnecessary, GCC_GCC_PCIE_HOT_RST_VAL is already defined to 0x10. No functional changes, compile tested only. Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1608143051-5386-1-git-send-email-kvalo@codeaurora.org --- drivers/net/wireless/ath/ath11k/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index 857647aa57c8..5587a9926cc6 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -328,7 +328,7 @@ static void ath11k_pci_enable_ltssm(struct ath11k_base *ab) ath11k_dbg(ab, ATH11K_DBG_PCI, "pci ltssm 0x%x\n", val); val = ath11k_pci_read32(ab, GCC_GCC_PCIE_HOT_RST); - val |= GCC_GCC_PCIE_HOT_RST_VAL | 0x10; + val |= GCC_GCC_PCIE_HOT_RST_VAL; ath11k_pci_write32(ab, GCC_GCC_PCIE_HOT_RST, val); val = ath11k_pci_read32(ab, GCC_GCC_PCIE_HOT_RST); From abdcd4cbec42fd3fe7e6c2d076360b0bbf62173f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 17 Dec 2020 14:04:32 +0300 Subject: [PATCH 10/35] ath11k: dp: clean up a variable name The "&ar->ab->base_lock" and "&ab->base_lock" locks are the same lock but it's nicer to use the same name consistently everywhere. Signed-off-by: Dan Carpenter Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/X9s7QAHDM2OTIo3a@mwanda --- drivers/net/wireless/ath/ath11k/dp_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 205c0f1a40e9..1b6e663ae784 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -1163,7 +1163,7 @@ int ath11k_dp_peer_rx_pn_replay_config(struct ath11k_vif *arvif, } } - spin_unlock_bh(&ar->ab->base_lock); + spin_unlock_bh(&ab->base_lock); return ret; } From 8873e8f56f74013ecf7aca6d8e66c600dc40ce64 Mon Sep 17 00:00:00 2001 From: Zheng Yongjun Date: Wed, 16 Dec 2020 21:04:42 +0800 Subject: [PATCH 11/35] rtw88: Delete useless kfree code The parameter of kfree function is NULL, so kfree code is useless, delete it. Signed-off-by: Zheng Yongjun Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201216130442.13869-1-zhengyongjun3@huawei.com --- drivers/net/wireless/realtek/rtw88/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index e7c1ae454524..16bacfadeb58 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -1276,7 +1276,6 @@ static void rtw_set_supported_band(struct ieee80211_hw *hw, err_out: rtw_err(rtwdev, "failed to set supported band\n"); - kfree(sband); } static void rtw_unset_supported_band(struct ieee80211_hw *hw, From ac9533d2a637464588c03d1a247567ea95d2bc59 Mon Sep 17 00:00:00 2001 From: Chin-Yen Lee Date: Mon, 28 Dec 2020 16:24:33 +0800 Subject: [PATCH 12/35] rtw88: reduce the log level for failure of tx report Sometimes driver does not get tx report from firmware because wifi environment is too noisy to get ack from AP about a TX frame, or firmware is too busy to report driver in a estimated time. But the condition will not affect wifi function or throughput. So we reduce the log level to rtw_debug instead of scary backtrace. Signed-off-by: Chin-Yen Lee Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201228082433.16431-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c index ca8072177ae3..18ec0088bf41 100644 --- a/drivers/net/wireless/realtek/rtw88/tx.c +++ b/drivers/net/wireless/realtek/rtw88/tx.c @@ -158,7 +158,7 @@ void rtw_tx_report_purge_timer(struct timer_list *t) if (skb_queue_len(&tx_report->queue) == 0) return; - WARN(1, "purge skb(s) not reported by firmware\n"); + rtw_dbg(rtwdev, RTW_DBG_TX, "purge skb(s) not reported by firmware\n"); spin_lock_irqsave(&tx_report->q_lock, flags); skb_queue_purge(&tx_report->queue); From 840105e4f12fa3aa5f5c3c5b42dacb82ab953289 Mon Sep 17 00:00:00 2001 From: Vincent Fann Date: Mon, 28 Dec 2020 16:25:16 +0800 Subject: [PATCH 13/35] rtw88: 8821c: apply CCK PD level which calculates from dynamic mechanism Hal function must follow the value that calculates from dynamic mechanism. Force to set new_lvl to 4 damages receiving ability. System will not able to reconnect to the AP if wifi unexpected disconnecting at this moment. Signed-off-by: Vincent Fann Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201228082516.16488-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/rtw8821c.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c index fbfd85439d1f..74155c999ebb 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c @@ -1022,12 +1022,6 @@ static void rtw8821c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) u8 pd[CCK_PD_LV_MAX] = {3, 7, 13, 13, 13}; u8 cck_n_rx; - if (dm_info->min_rssi > 60) { - new_lvl = 4; - pd[4] = 0x1d; - goto set_cck_pd; - } - rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n", dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl); @@ -1044,7 +1038,6 @@ static void rtw8821c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) dm_info->cck_fa_avg = CCK_FA_AVG_RESET; -set_cck_pd: dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl; rtw_write32_mask(rtwdev, REG_PWRTH, 0x3f0000, pd[new_lvl]); rtw_write32_mask(rtwdev, REG_PWRTH2, 0x1f0000, From 5f782c11569d5703c8ded6913481b55c254512f2 Mon Sep 17 00:00:00 2001 From: Ching-Te Ku Date: Tue, 12 Jan 2021 10:11:35 +0800 Subject: [PATCH 14/35] rtw88: coex: set 4 slot TDMA for BT link and WL busy To protect both of WL/BT performance while BT is under re-link state. 4-slot mode TDMA can make the re-link more sensitive and mitigate the WL throughput drop. Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210112021135.3823-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/coex.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c index 24530cafcba7..ea2be1e25065 100644 --- a/drivers/net/wireless/realtek/rtw88/coex.c +++ b/drivers/net/wireless/realtek/rtw88/coex.c @@ -1607,6 +1607,7 @@ static void rtw_coex_action_bt_relink(struct rtw_dev *rtwdev) struct rtw_efuse *efuse = &rtwdev->efuse; struct rtw_chip_info *chip = rtwdev->chip; u8 table_case, tdma_case; + u32 slot_type = 0; rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); @@ -1618,6 +1619,7 @@ static void rtw_coex_action_bt_relink(struct rtw_dev *rtwdev) table_case = 26; if (coex_stat->bt_hid_exist && coex_stat->bt_profile_num == 1) { + slot_type = TDMA_4SLOT; tdma_case = 20; } else { tdma_case = 20; @@ -1635,7 +1637,7 @@ static void rtw_coex_action_bt_relink(struct rtw_dev *rtwdev) } rtw_coex_table(rtwdev, false, table_case); - rtw_coex_tdma(rtwdev, false, tdma_case); + rtw_coex_tdma(rtwdev, false, tdma_case | slot_type); } static void rtw_coex_action_bt_idle(struct rtw_dev *rtwdev) From d3a78c7a9daa6c5fa8529c53f07a909745cf7d02 Mon Sep 17 00:00:00 2001 From: YANG LI Date: Tue, 12 Jan 2021 17:50:40 +0800 Subject: [PATCH 15/35] rtw88: Simplify bool comparison Fix the following coccicheck warning: ./drivers/net/wireless/realtek/rtw88/debug.c:800:17-23: WARNING: Comparison of 0/1 to bool variable Reported-by: Abaci Robot Signed-off-by: YANG LI Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1610445040-23599-1-git-send-email-abaci-bugfix@linux.alibaba.com --- drivers/net/wireless/realtek/rtw88/debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c index 19fc2d8bf3e9..948cb79050ea 100644 --- a/drivers/net/wireless/realtek/rtw88/debug.c +++ b/drivers/net/wireless/realtek/rtw88/debug.c @@ -800,7 +800,7 @@ static ssize_t rtw_debugfs_set_coex_enable(struct file *filp, } mutex_lock(&rtwdev->mutex); - coex->manual_control = enable == 0; + coex->manual_control = !enable; mutex_unlock(&rtwdev->mutex); return count; From 596c84c49f8a073c4e19acc0d5d9dd4bcc8bb57f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 11 Dec 2020 14:38:35 +0100 Subject: [PATCH 16/35] mwifiex: pcie: Drop bogus __refdata annotation As the Marvell PCIE WiFi-Ex driver does not have any code or data located in initmem, there is no need to annotate the mwifiex_pcie structure with __refdata. Drop the annotation, to avoid suppressing future section warnings. Signed-off-by: Geert Uytterhoeven Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201211133835.2970384-1-geert+renesas@glider.be --- drivers/net/wireless/marvell/mwifiex/pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index 5f0a61b974ee..94228b316df1 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -571,7 +571,7 @@ static SIMPLE_DEV_PM_OPS(mwifiex_pcie_pm_ops, mwifiex_pcie_suspend, #endif /* PCI Device Driver */ -static struct pci_driver __refdata mwifiex_pcie = { +static struct pci_driver mwifiex_pcie = { .name = "mwifiex_pcie", .id_table = mwifiex_ids, .probe = mwifiex_pcie_probe, From e4c748ee4af1b00f390ef802c7d9186474ac0b5f Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 16 Dec 2020 11:58:08 +0000 Subject: [PATCH 17/35] wilc1000: fix spelling mistake in Kconfig "devision" -> "division" There is a spelling mistake in the Kconfig help text. Fix it. Signed-off-by: Colin Ian King Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201216115808.12987-1-colin.king@canonical.com --- drivers/net/wireless/microchip/wilc1000/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/microchip/wilc1000/Kconfig b/drivers/net/wireless/microchip/wilc1000/Kconfig index 80c92e8bf8a5..7f15e42602dd 100644 --- a/drivers/net/wireless/microchip/wilc1000/Kconfig +++ b/drivers/net/wireless/microchip/wilc1000/Kconfig @@ -44,4 +44,4 @@ config WILC1000_HW_OOB_INTR chipset. This OOB interrupt is intended to provide a faster interrupt mechanism for SDIO host controllers that don't support SDIO interrupt. Select this option If the SDIO host controller in your platform - doesn't support SDIO time devision interrupt. + doesn't support SDIO time division interrupt. From f4add10399f9cba42a45ac4b0e0dc5e4943f8546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 14 Dec 2020 11:15:53 +0100 Subject: [PATCH 18/35] brcmfmac: support BCM4365E with 43666 ChipCommon chip ID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds support for the BCM43666/4 which seems to be using the same firmware as BCM4366 (4366c0). I found it in the Netgear R8000P router. Signed-off-by: Rafał Miłecki Acked-by: Arend van Spriel Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201214101553.32097-1-zajec5@gmail.com --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 1 + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 1 + drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 1 + 3 files changed, 3 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c index 5bf11e46fc49..45037decba40 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c @@ -720,6 +720,7 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci) case BRCM_CC_4365_CHIP_ID: case BRCM_CC_4366_CHIP_ID: case BRCM_CC_43664_CHIP_ID: + case BRCM_CC_43666_CHIP_ID: return 0x200000; case BRCM_CC_4359_CHIP_ID: return (ci->pub.chiprev < 9) ? 0x180000 : 0x160000; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index 45bc502fcb34..ad79e3b7e74a 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -77,6 +77,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0x0000000F, 4366B), BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C), BRCMF_FW_ENTRY(BRCM_CC_43664_CHIP_ID, 0xFFFFFFF0, 4366C), + BRCMF_FW_ENTRY(BRCM_CC_43666_CHIP_ID, 0xFFFFFFF0, 4366C), BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), }; diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h index c6c4be05159d..00309b272a0e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h @@ -48,6 +48,7 @@ #define BRCM_CC_4365_CHIP_ID 0x4365 #define BRCM_CC_4366_CHIP_ID 0x4366 #define BRCM_CC_43664_CHIP_ID 43664 +#define BRCM_CC_43666_CHIP_ID 43666 #define BRCM_CC_4371_CHIP_ID 0x4371 #define CY_CC_4373_CHIP_ID 0x4373 #define CY_CC_43012_CHIP_ID 43012 From 0e40dbd56d67a5b01b13f4bfb62b470cd99125cd Mon Sep 17 00:00:00 2001 From: Zhi Han Date: Thu, 17 Dec 2020 17:13:02 +0100 Subject: [PATCH 19/35] mt7601u: process URBs in status EPROTO properly When the usb device being plugged out, before the usb_driver:disconnect called by e.g workqueue, it is possible that some URBs are still in processing, and being marked as EPROTO in host controller. Those URBs should not be scheduled in complete_rx callback function to get further processing. Signed-off-by: Zhi Han Acked-by: Jakub Kicinski Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201217161302.GA12562@E480 --- drivers/net/wireless/mediatek/mt7601u/dma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/mediatek/mt7601u/dma.c b/drivers/net/wireless/mediatek/mt7601u/dma.c index 5f99054f535b..98733c23d408 100644 --- a/drivers/net/wireless/mediatek/mt7601u/dma.c +++ b/drivers/net/wireless/mediatek/mt7601u/dma.c @@ -192,6 +192,7 @@ static void mt7601u_complete_rx(struct urb *urb) case -ECONNRESET: case -ESHUTDOWN: case -ENOENT: + case -EPROTO: return; default: dev_err_ratelimited(dev->dev, "rx urb failed: %d\n", From 1dac51269d0532bd0847f44f1c3ae7fd2851ac7d Mon Sep 17 00:00:00 2001 From: Zhi Han Date: Thu, 17 Dec 2020 17:16:57 +0100 Subject: [PATCH 20/35] mt7601u: check the status of device in calibration When the usb device being plugged out, before ieee80211 gets to know the hw being removed, it gets to know that the association status changed, and thus ask for the device to do the calibration. This causes error as the hw is absent. This can be avoid by checking the status of the device before sending the calibration request to the device. Signed-off-by: Zhi Han Acked-by: Jakub Kicinski Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201217161657.GB12562@E480 --- drivers/net/wireless/mediatek/mt7601u/phy.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt7601u/phy.c b/drivers/net/wireless/mediatek/mt7601u/phy.c index 28db24a2b5e5..8a00f6a75ca9 100644 --- a/drivers/net/wireless/mediatek/mt7601u/phy.c +++ b/drivers/net/wireless/mediatek/mt7601u/phy.c @@ -586,6 +586,9 @@ static void mt7601u_rxdc_cal(struct mt7601u_dev *dev) void mt7601u_phy_recalibrate_after_assoc(struct mt7601u_dev *dev) { + if (test_bit(MT7601U_STATE_REMOVED, &dev->state)) + return; + mt7601u_mcu_calibrate(dev, MCU_CAL_DPD, dev->curr_temp); mt7601u_rxdc_cal(dev); From 0924ba9fbc26860b4b57b424e402d4b16d40cc91 Mon Sep 17 00:00:00 2001 From: Amey Narkhede Date: Mon, 21 Dec 2020 13:27:35 +0530 Subject: [PATCH 21/35] qtnfmac_pcie: Use module_pci_driver Use module_pci_driver for drivers whose init and exit functions only register and unregister, respectively. Signed-off-by: Amey Narkhede Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201221075735.197255-1-ameynarkhede03@gmail.com --- drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c index 0f328ce47fee..5d93c874d666 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c +++ b/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c @@ -480,18 +480,7 @@ static struct pci_driver qtnf_pcie_drv_data = { #endif }; -static int __init qtnf_pcie_register(void) -{ - return pci_register_driver(&qtnf_pcie_drv_data); -} - -static void __exit qtnf_pcie_exit(void) -{ - pci_unregister_driver(&qtnf_pcie_drv_data); -} - -module_init(qtnf_pcie_register); -module_exit(qtnf_pcie_exit); +module_pci_driver(qtnf_pcie_drv_data) MODULE_AUTHOR("Quantenna Communications"); MODULE_DESCRIPTION("Quantenna PCIe bus driver for 802.11 wireless LAN."); From 73c655410181b7fc9a5ff321a5021a684ada99e7 Mon Sep 17 00:00:00 2001 From: Zheng Yongjun Date: Tue, 22 Dec 2020 21:51:13 +0800 Subject: [PATCH 22/35] brcmfmac: Delete useless kfree code A null pointer will be passed to a kfree() call after a kzalloc() call failed. This code is useless. Thus delete the extra function call. A goto statement is also no longer needed. Thus adjust an if branch. Signed-off-by: Zheng Yongjun Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201222135113.20680-1-zhengyongjun3@huawei.com --- .../wireless/broadcom/brcm80211/brcmfmac/firmware.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c index d821a4758f8c..d40104b8df55 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c @@ -319,8 +319,10 @@ static void brcmf_fw_strip_multi_v2(struct nvram_parser *nvp, u16 domain_nr, u8 *nvram; nvram = kzalloc(nvp->nvram_len + 1 + 3 + sizeof(u32), GFP_KERNEL); - if (!nvram) - goto fail; + if (!nvram) { + nvp->nvram_len = 0; + return; + } /* Copy all valid entries, release old nvram and assign new one. * Valid entries are of type pcie/X/Y/ where X = domain_nr and @@ -350,10 +352,6 @@ static void brcmf_fw_strip_multi_v2(struct nvram_parser *nvp, u16 domain_nr, kfree(nvp->nvram); nvp->nvram = nvram; nvp->nvram_len = j; - return; -fail: - kfree(nvram); - nvp->nvram_len = 0; } static void brcmf_fw_add_defaults(struct nvram_parser *nvp) From e862a3e4088070de352fdafe9bd9e3ae0a95a33c Mon Sep 17 00:00:00 2001 From: Luca Pesce Date: Thu, 24 Dec 2020 11:51:59 +0100 Subject: [PATCH 23/35] brcmfmac: clear EAP/association status bits on linkdown events This ensure that previous association attempts do not leave stale statuses on subsequent attempts. This fixes the WARN_ON(!cr->bss)) from __cfg80211_connect_result() when connecting to an AP after a previous connection failure (e.g. where EAP fails due to incorrect psk but association succeeded). In some scenarios, indeed, brcmf_is_linkup() was reporting a link up event too early due to stale BRCMF_VIF_STATUS_ASSOC_SUCCESS bit, thus reporting to cfg80211 a connection result with a zeroed bssid (vif->profile.bssid is still empty), causing the WARN_ON due to the call to cfg80211_get_bss() with the empty bssid. Signed-off-by: Luca Pesce Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1608807119-21785-1-git-send-email-luca.pesce@vimar.com --- .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 0ee421f30aa2..23e6422c2251 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -5611,7 +5611,8 @@ static bool brcmf_is_linkup(struct brcmf_cfg80211_vif *vif, return false; } -static bool brcmf_is_linkdown(const struct brcmf_event_msg *e) +static bool brcmf_is_linkdown(struct brcmf_cfg80211_vif *vif, + const struct brcmf_event_msg *e) { u32 event = e->event_code; u16 flags = e->flags; @@ -5620,6 +5621,8 @@ static bool brcmf_is_linkdown(const struct brcmf_event_msg *e) (event == BRCMF_E_DISASSOC_IND) || ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) { brcmf_dbg(CONN, "Processing link down\n"); + clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state); + clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state); return true; } return false; @@ -6067,7 +6070,7 @@ brcmf_notify_connect_status(struct brcmf_if *ifp, } else brcmf_bss_connect_done(cfg, ndev, e, true); brcmf_net_setcarrier(ifp, true); - } else if (brcmf_is_linkdown(e)) { + } else if (brcmf_is_linkdown(ifp->vif, e)) { brcmf_dbg(CONN, "Linkdown\n"); if (!brcmf_is_ibssmode(ifp->vif) && test_bit(BRCMF_VIF_STATUS_CONNECTED, From 098238e80bed1ea2347e2efb5533f1d0289ae6c3 Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Fri, 25 Dec 2020 15:35:03 +0800 Subject: [PATCH 24/35] wilc1000: use flexible-array member instead of zero-length array Use flexible-array member introduced in C99 instead of zero-length array. Most of zero-length array was already taken care in previous patch [1]. [1]. https://patchwork.kernel.org/patch/11394197/ Signed-off-by: Tian Tao Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1608881703-37060-1-git-send-email-tiantao6@hisilicon.com --- drivers/net/wireless/microchip/wilc1000/fw.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/microchip/wilc1000/fw.h b/drivers/net/wireless/microchip/wilc1000/fw.h index a76e1dea4345..1114530d03e4 100644 --- a/drivers/net/wireless/microchip/wilc1000/fw.h +++ b/drivers/net/wireless/microchip/wilc1000/fw.h @@ -44,20 +44,20 @@ struct wilc_drv_handler { struct wilc_wep_key { u8 index; u8 key_len; - u8 key[0]; + u8 key[]; } __packed; struct wilc_sta_wpa_ptk { u8 mac_addr[ETH_ALEN]; u8 key_len; - u8 key[0]; + u8 key[]; } __packed; struct wilc_ap_wpa_ptk { u8 mac_addr[ETH_ALEN]; u8 index; u8 key_len; - u8 key[0]; + u8 key[]; } __packed; struct wilc_gtk_key { @@ -65,7 +65,7 @@ struct wilc_gtk_key { u8 rsc[8]; u8 index; u8 key_len; - u8 key[0]; + u8 key[]; } __packed; struct wilc_op_mode { From 07ceefa3012f43512e93931980bd3bdf5af96344 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 1 Jan 2021 08:59:55 +0200 Subject: [PATCH 25/35] wlcore: Downgrade exceeded max RX BA sessions to debug We can get the following in the logs every few minutes or so: wlcore: ERROR exceeded max RX BA sessions Let's downgrade the message to a debug message as suggested by the TI support folks at: https://e2e.ti.com/support/wireless-connectivity/wifi/f/968/p/352435/1244754 "The WL127x firmware supports max of 3 BA sessions. It cannot be increased. I think the problem here is the peer trying to initiate a 4th BA session (ADDBA request)." Signed-off-by: Tony Lindgren Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210101065955.63386-1-tony@atomide.com --- drivers/net/wireless/ti/wlcore/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 122c7a4b374f..fb0305d075dd 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5394,7 +5394,7 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw, if (wl->ba_rx_session_count >= wl->ba_rx_session_count_max) { ret = -EBUSY; - wl1271_error("exceeded max RX BA sessions"); + wl1271_debug(DEBUG_RX, "exceeded max RX BA sessions"); break; } From d8cbaa3de403af6a9cf56598171d2c130ef56f0d Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Sun, 10 Jan 2021 17:45:21 +0530 Subject: [PATCH 26/35] rtlwifi: rtl_pci: fix bool comparison in expressions There are certain conditional expressions in rtl_pci, where a boolean variable is compared with true/false, in forms such as (foo == true) or (false != bar), which does not comply with checkpatch.pl (CHECK: BOOL_COMPARISON), according to which boolean variables should be themselves used in the condition, rather than comparing with true/false E.g., in drivers/net/wireless/realtek/rtlwifi/ps.c, "if (find_p2p_ie == true)" can be replaced with "if (find_p2p_ie)" Replace all such expressions with the bool variables appropriately Signed-off-by: Aditya Srivastava Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210110121525.2407-2-yashsri421@gmail.com --- drivers/net/wireless/realtek/rtlwifi/ps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c b/drivers/net/wireless/realtek/rtlwifi/ps.c index f99882255d48..629c03271bde 100644 --- a/drivers/net/wireless/realtek/rtlwifi/ps.c +++ b/drivers/net/wireless/realtek/rtlwifi/ps.c @@ -798,9 +798,9 @@ static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, ie += 3 + noa_len; } - if (find_p2p_ie == true) { + if (find_p2p_ie) { if ((p2pinfo->p2p_ps_mode > P2P_PS_NONE) && - (find_p2p_ps_ie == false)) + (!find_p2p_ps_ie)) rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); } } From f7c76283fc5f532027404a346c69ebd111c92fdc Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Sun, 10 Jan 2021 17:45:22 +0530 Subject: [PATCH 27/35] rtlwifi: rtl8192c-common: fix bool comparison in expressions There are certain conditional expressions in rtl8192c-common, where a boolean variable is compared with true/false, in forms such as (foo == true) or (false != bar), which does not comply with checkpatch.pl (CHECK: BOOL_COMPARISON), according to which boolean variables should be themselves used in the condition, rather than comparing with true/false E.g., in drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c, "else if (initialized == false) {" can be replaced with "else if (!initialized) {" Replace all such expressions with the bool variables appropriately Signed-off-by: Aditya Srivastava Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210110121525.2407-3-yashsri421@gmail.com --- drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c index 265a1a336304..0b6a15c2e5cc 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c @@ -380,7 +380,7 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) initialized = false; dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; return; - } else if (initialized == false) { + } else if (!initialized) { initialized = true; dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; dm_digtable->cur_igvalue = 0x20; @@ -509,7 +509,7 @@ static void rtl92c_dm_dig(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - if (rtlpriv->dm.dm_initialgain_enable == false) + if (!rtlpriv->dm.dm_initialgain_enable) return; if (!(rtlpriv->dm.dm_flag & DYNAMIC_FUNC_DIG)) return; From 64338f0dfd6a3be20453789c6a4b2c7246e2aef8 Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Sun, 10 Jan 2021 17:45:23 +0530 Subject: [PATCH 28/35] rtlwifi: rtl8188ee: fix bool comparison in expressions There are certain conditional expressions in rtl8188ee, where a boolean variable is compared with true/false, in forms such as (foo == true) or (false != bar), which does not comply with checkpatch.pl (CHECK: BOOL_COMPARISON), according to which boolean variables should be themselves used in the condition, rather than comparing with true/false E.g., in drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c, "if (mac->act_scanning == true)" can be replaced with "if (mac->act_scanning)" Replace all such expressions with the bool variables appropriately Signed-off-by: Aditya Srivastava Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210110121525.2407-4-yashsri421@gmail.com --- drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c | 8 ++++---- drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c index d10c14c694da..6f61d6a10627 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c @@ -474,11 +474,11 @@ static void rtl88e_dm_dig(struct ieee80211_hw *hw) u8 dm_dig_max, dm_dig_min; u8 current_igi = dm_dig->cur_igvalue; - if (rtlpriv->dm.dm_initialgain_enable == false) + if (!rtlpriv->dm.dm_initialgain_enable) return; - if (dm_dig->dig_enable_flag == false) + if (!dm_dig->dig_enable_flag) return; - if (mac->act_scanning == true) + if (mac->act_scanning) return; if (mac->link_state >= MAC80211_LINKED) @@ -1637,7 +1637,7 @@ static void rtl88e_dm_fast_ant_training(struct ieee80211_hw *hw) } } - if (bpkt_filter_match == false) { + if (!bpkt_filter_match) { rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N, BIT(16), 0); rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c index bd9160b166c5..861cc663ca93 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c @@ -1269,12 +1269,12 @@ void rtl88ee_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) if (rtlpriv->psc.rfpwr_state != ERFON) return; - if (check_bssid == true) { + if (check_bssid) { reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); _rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(4)); - } else if (check_bssid == false) { + } else if (!check_bssid) { reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); _rtl88ee_set_bcn_ctrl_reg(hw, BIT(4), 0); rtlpriv->cfg->ops->set_hw_reg(hw, From 33ae4623d544f1b76e0f656fa49e431b4503f23b Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Sun, 10 Jan 2021 17:45:24 +0530 Subject: [PATCH 29/35] rtlwifi: rtl8192se: fix bool comparison in expressions There are certain conditional expressions in rtl8192se, where a boolean variable is compared with true/false, in forms such as (foo == true) or (false != bar), which does not comply with checkpatch.pl (CHECK: BOOL_COMPARISON), according to which boolean variables should be themselves used in the condition, rather than comparing with true/false Replace all such expressions with the bool variables appropriately Signed-off-by: Aditya Srivastava Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210110121525.2407-5-yashsri421@gmail.com --- drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c index 47fabce5c235..73a5d8a068fc 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c @@ -458,7 +458,7 @@ static u8 _rtl92se_halset_sysclk(struct ieee80211_hw *hw, u8 data) tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1); bresult = ((tmpvalue & BIT(7)) == (data & BIT(7))); - if ((data & (BIT(6) | BIT(7))) == false) { + if (!(data & (BIT(6) | BIT(7)))) { waitcount = 100; tmpvalue = 0; @@ -1268,7 +1268,7 @@ static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data) tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1); result = ((tmp & BIT(7)) == (data & BIT(7))); - if ((data & (BIT(6) | BIT(7))) == false) { + if (!(data & (BIT(6) | BIT(7)))) { waitcnt = 100; tmp = 0; From 9264cabc12040dacc50f517e872d26d6e3a8a531 Mon Sep 17 00:00:00 2001 From: Aditya Srivastava Date: Sun, 10 Jan 2021 17:45:25 +0530 Subject: [PATCH 30/35] rtlwifi: rtl8821ae: fix bool comparison in expressions There are certain conditional expressions in rtl8821ae, where a boolean variable is compared with true/false, in forms such as (foo == true) or (false != bar), which does not comply with checkpatch.pl (CHECK: BOOL_COMPARISON), according to which boolean variables should be themselves used in the condition, rather than comparing with true/false E.g., in drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c, "if (rtlefuse->autoload_failflag == false)" can be replaced with "if (!rtlefuse->autoload_failflag)" Replace all such expressions with the bool variables appropriately Signed-off-by: Aditya Srivastava Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210110121525.2407-6-yashsri421@gmail.com --- drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c index 372d6f8caf06..e214b9062cc1 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c @@ -1812,7 +1812,7 @@ static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw) return false; } _rtl8821ae_phy_init_tx_power_by_rate(hw); - if (rtlefuse->autoload_failflag == false) { + if (!rtlefuse->autoload_failflag) { rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw, BASEBAND_CONFIG_PHY_REG); } @@ -3980,7 +3980,7 @@ static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path) } } - if (tx0iqkok == false) + if (!tx0iqkok) break; /* TXK fail, Don't do RXK */ if (vdf_enable == 1) { @@ -4090,7 +4090,7 @@ static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path) } } - if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */ + if (!tx0iqkok) { /* If RX mode TXK fail, then take TXK Result */ tx_x0_rxk[cal] = tx_x0[cal]; tx_y0_rxk[cal] = tx_y0[cal]; tx0iqkok = true; @@ -4249,7 +4249,7 @@ static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path) } } - if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */ + if (!tx0iqkok) { /* If RX mode TXK fail, then take TXK Result */ tx_x0_rxk[cal] = tx_x0[cal]; tx_y0_rxk[cal] = tx_y0[cal]; tx0iqkok = true; From 6598f32d9dfe2c5324c9dfd7046929104d390c74 Mon Sep 17 00:00:00 2001 From: Chin-Yen Lee Date: Wed, 13 Jan 2021 09:43:42 +0800 Subject: [PATCH 31/35] rtw88: 8723de: adjust the LTR setting The LTR mechanism enables PCIE Endpoints to report the service latency requirements and CPU will enter appropriate sleep state to save power based on the LTR value. 8723de provides two registers to config the LTR, and the original setting is too short for CPU to ente sleep state. The patch adjust the LTR setting. Signed-off-by: Chin-Yen Lee Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210113014342.3615-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw88/rtw8723d.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c index 9268ea8b6dda..3fdbaf7302c5 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c @@ -60,8 +60,8 @@ static const struct rtw_hw_reg rtw8723d_txagc[] = { #define WLAN_MAX_AGG_NR 0x0A #define WLAN_AMPDU_MAX_TIME 0x1C #define WLAN_ANT_SEL 0x82 -#define WLAN_LTR_IDLE_LAT 0x883C883C -#define WLAN_LTR_ACT_LAT 0x880B880B +#define WLAN_LTR_IDLE_LAT 0x90039003 +#define WLAN_LTR_ACT_LAT 0x883c883c #define WLAN_LTR_CTRL1 0xCB004010 #define WLAN_LTR_CTRL2 0x01233425 From 2a9269b1cdc35e7c341a7e0cf310c4c65c7faeec Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 14 Jan 2021 00:26:26 +0100 Subject: [PATCH 32/35] mt7601u: use ieee80211_rx_list to pass frames to the network stack as a batch Similar to mt76 driver, rely on ieee80211_rx_list in order to improve icache footprint Signed-off-by: Lorenzo Bianconi Acked-by: Jakub Kicinski Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/5c72fa2dda45c1ae3f285af80c02f3db23341d85.1610580222.git.lorenzo@kernel.org --- drivers/net/wireless/mediatek/mt7601u/dma.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt7601u/dma.c b/drivers/net/wireless/mediatek/mt7601u/dma.c index 98733c23d408..46d05f839287 100644 --- a/drivers/net/wireless/mediatek/mt7601u/dma.c +++ b/drivers/net/wireless/mediatek/mt7601u/dma.c @@ -74,7 +74,8 @@ bad_frame: } static void mt7601u_rx_process_seg(struct mt7601u_dev *dev, u8 *data, - u32 seg_len, struct page *p) + u32 seg_len, struct page *p, + struct list_head *list) { struct sk_buff *skb; struct mt7601u_rxwi *rxwi; @@ -104,9 +105,13 @@ static void mt7601u_rx_process_seg(struct mt7601u_dev *dev, u8 *data, if (!skb) return; - spin_lock(&dev->mac_lock); - ieee80211_rx(dev->hw, skb); - spin_unlock(&dev->mac_lock); + local_bh_disable(); + rcu_read_lock(); + + ieee80211_rx_list(dev->hw, NULL, skb, list); + + rcu_read_unlock(); + local_bh_enable(); } static u16 mt7601u_rx_next_seg_len(u8 *data, u32 data_len) @@ -130,6 +135,7 @@ mt7601u_rx_process_entry(struct mt7601u_dev *dev, struct mt7601u_dma_buf_rx *e) u32 seg_len, data_len = e->urb->actual_length; u8 *data = page_address(e->p); struct page *new_p = NULL; + LIST_HEAD(list); int cnt = 0; if (!test_bit(MT7601U_STATE_INITIALIZED, &dev->state)) @@ -140,7 +146,8 @@ mt7601u_rx_process_entry(struct mt7601u_dev *dev, struct mt7601u_dma_buf_rx *e) new_p = dev_alloc_pages(MT_RX_ORDER); while ((seg_len = mt7601u_rx_next_seg_len(data, data_len))) { - mt7601u_rx_process_seg(dev, data, seg_len, new_p ? e->p : NULL); + mt7601u_rx_process_seg(dev, data, seg_len, + new_p ? e->p : NULL, &list); data_len -= seg_len; data += seg_len; @@ -150,6 +157,8 @@ mt7601u_rx_process_entry(struct mt7601u_dev *dev, struct mt7601u_dma_buf_rx *e) if (cnt > 1) trace_mt_rx_dma_aggr(dev, cnt, !!new_p); + netif_receive_skb_list(&list); + if (new_p) { /* we have one extra ref from the allocator */ __free_pages(e->p, MT_RX_ORDER); From cb88d01b67383a095e3f7caeb4cdade5a6cf0417 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 15 Jan 2021 08:56:13 +0200 Subject: [PATCH 33/35] wlcore: Fix command execute failure 19 for wl12xx We can currently get a "command execute failure 19" error on beacon loss if the signal is weak: wlcore: Beacon loss detected. roles:0xff wlcore: Connection loss work (role_id: 0). ... wlcore: ERROR command execute failure 19 ... WARNING: CPU: 0 PID: 1552 at drivers/net/wireless/ti/wlcore/main.c:803 ... (wl12xx_queue_recovery_work.part.0 [wlcore]) (wl12xx_cmd_role_start_sta [wlcore]) (wl1271_op_bss_info_changed [wlcore]) (ieee80211_prep_connection [mac80211]) Error 19 is defined as CMD_STATUS_WRONG_NESTING from the wlcore firmware, and seems to mean that the firmware no longer wants to see the quirk handling for WLCORE_QUIRK_START_STA_FAILS done. This quirk got added with commit 18eab430700d ("wlcore: workaround start_sta problem in wl12xx fw"), and it seems that this already got fixed in the firmware long time ago back in 2012 as wl18xx never had this quirk in place to start with. As we no longer even support firmware that early, to me it seems that it's safe to just drop WLCORE_QUIRK_START_STA_FAILS to fix the error. Looks like earlier firmware got disabled back in 2013 with commit 0e284c074ef9 ("wl12xx: increase minimum singlerole firmware version required"). If it turns out we still need WLCORE_QUIRK_START_STA_FAILS with any firmware that the driver works with, we can simply revert this patch and add extra checks for firmware version used. With this fix wlcore reconnects properly after a beacon loss. Cc: Raz Bouganim Signed-off-by: Tony Lindgren Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210115065613.7731-1-tony@atomide.com --- drivers/net/wireless/ti/wl12xx/main.c | 3 --- drivers/net/wireless/ti/wlcore/main.c | 15 +-------------- drivers/net/wireless/ti/wlcore/wlcore.h | 3 --- 3 files changed, 1 insertion(+), 20 deletions(-) diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 3c9c623bb428..9d7dbfe7fe0c 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -635,7 +635,6 @@ static int wl12xx_identify_chip(struct wl1271 *wl) wl->quirks |= WLCORE_QUIRK_LEGACY_NVS | WLCORE_QUIRK_DUAL_PROBE_TMPL | WLCORE_QUIRK_TKIP_HEADER_SPACE | - WLCORE_QUIRK_START_STA_FAILS | WLCORE_QUIRK_AP_ZERO_SESSION_ID; wl->sr_fw_name = WL127X_FW_NAME_SINGLE; wl->mr_fw_name = WL127X_FW_NAME_MULTI; @@ -659,7 +658,6 @@ static int wl12xx_identify_chip(struct wl1271 *wl) wl->quirks |= WLCORE_QUIRK_LEGACY_NVS | WLCORE_QUIRK_DUAL_PROBE_TMPL | WLCORE_QUIRK_TKIP_HEADER_SPACE | - WLCORE_QUIRK_START_STA_FAILS | WLCORE_QUIRK_AP_ZERO_SESSION_ID; wl->plt_fw_name = WL127X_PLT_FW_NAME; wl->sr_fw_name = WL127X_FW_NAME_SINGLE; @@ -688,7 +686,6 @@ static int wl12xx_identify_chip(struct wl1271 *wl) wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN | WLCORE_QUIRK_DUAL_PROBE_TMPL | WLCORE_QUIRK_TKIP_HEADER_SPACE | - WLCORE_QUIRK_START_STA_FAILS | WLCORE_QUIRK_AP_ZERO_SESSION_ID; wlcore_set_min_fw_ver(wl, WL128X_CHIP_VER, diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index fb0305d075dd..8509b989940c 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -2872,21 +2872,8 @@ static int wlcore_join(struct wl1271 *wl, struct wl12xx_vif *wlvif) if (is_ibss) ret = wl12xx_cmd_role_start_ibss(wl, wlvif); - else { - if (wl->quirks & WLCORE_QUIRK_START_STA_FAILS) { - /* - * TODO: this is an ugly workaround for wl12xx fw - * bug - we are not able to tx/rx after the first - * start_sta, so make dummy start+stop calls, - * and then call start_sta again. - * this should be fixed in the fw. - */ - wl12xx_cmd_role_start_sta(wl, wlvif); - wl12xx_cmd_role_stop_sta(wl, wlvif); - } - + else ret = wl12xx_cmd_role_start_sta(wl, wlvif); - } return ret; } diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index b7821311ac75..81c94d390623 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -547,9 +547,6 @@ wlcore_set_min_fw_ver(struct wl1271 *wl, unsigned int chip, /* Each RX/TX transaction requires an end-of-transaction transfer */ #define WLCORE_QUIRK_END_OF_TRANSACTION BIT(0) -/* the first start_role(sta) sometimes doesn't work on wl12xx */ -#define WLCORE_QUIRK_START_STA_FAILS BIT(1) - /* wl127x and SPI don't support SDIO block size alignment */ #define WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN BIT(2) From f43fcaef87a3ec6e234a20c8606342f33a8bd61d Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 17 Jan 2021 22:46:56 +0100 Subject: [PATCH 34/35] mt7601u: process tx URBs with status EPROTO properly Similar to commit 0e40dbd56d67 ("mt7601u: process URBs in status EPROTO properly"), do not process tx URBs if marked with status set to EPROTO. Signed-off-by: Lorenzo Bianconi Acked-by: Jakub Kicinski Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/72392e8341aa8591c0b9962661a6ca26b1198f32.1610919534.git.lorenzo@kernel.org --- drivers/net/wireless/mediatek/mt7601u/dma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/mediatek/mt7601u/dma.c b/drivers/net/wireless/mediatek/mt7601u/dma.c index 46d05f839287..1342cf77ef14 100644 --- a/drivers/net/wireless/mediatek/mt7601u/dma.c +++ b/drivers/net/wireless/mediatek/mt7601u/dma.c @@ -247,6 +247,7 @@ static void mt7601u_complete_tx(struct urb *urb) case -ECONNRESET: case -ESHUTDOWN: case -ENOENT: + case -EPROTO: return; default: dev_err_ratelimited(dev->dev, "tx urb failed: %d\n", From 4832bb371c4175ffb506a96accbb08ef2b2466e7 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 19 Jan 2021 11:06:21 +0100 Subject: [PATCH 35/35] iwl4965: do not process non-QOS frames on txq->sched_retry path We have already WARN_ON(!qc) for non-QOS frame on txq->sched_retry path, but we continue to process, what makes no sense since tid is not initialized. Non QOS frame should never happen when aggregation is enabled on queue, so do not process that. Patch should fix smatch warning: drivers/net/wireless/intel/iwlegacy/4965-mac.c:2822 il4965_hdl_tx() error: uninitialized symbol 'tid'. Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210119100621.439134-1-stf_xl@wp.pl --- drivers/net/wireless/intel/iwlegacy/4965-mac.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c index 28675a4ad861..98cd06287b43 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c @@ -2813,8 +2813,10 @@ il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) spin_lock_irqsave(&il->sta_lock, flags); if (txq->sched_retry) { const u32 scd_ssn = il4965_get_scd_ssn(tx_resp); - struct il_ht_agg *agg = NULL; - WARN_ON(!qc); + struct il_ht_agg *agg; + + if (WARN_ON(!qc)) + goto out; agg = &il->stations[sta_id].tid[tid].agg; @@ -2830,9 +2832,7 @@ il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) D_TX_REPLY("Retry scheduler reclaim scd_ssn " "%d idx %d\n", scd_ssn, idx); freed = il4965_tx_queue_reclaim(il, txq_id, idx); - if (qc) - il4965_free_tfds_in_queue(il, sta_id, tid, - freed); + il4965_free_tfds_in_queue(il, sta_id, tid, freed); if (il->mac80211_registered && il_queue_space(&txq->q) > txq->q.low_mark && @@ -2862,6 +2862,7 @@ il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) il_queue_space(&txq->q) > txq->q.low_mark) il_wake_queue(il, txq); } +out: if (qc && likely(sta_id != IL_INVALID_STATION)) il4965_txq_check_empty(il, sta_id, tid, txq_id);