mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 10:51:27 +00:00
597 lines
20 KiB
Diff
597 lines
20 KiB
Diff
From 06f0ae6ee1707698a11f76a10a7e4e64ce563914 Mon Sep 17 00:00:00 2001
|
|
From: Ramanathan Choodamani <quic_rchoodam@quicinc.com>
|
|
Date: Thu, 15 Jun 2023 10:13:46 -0700
|
|
Subject: [PATCH] ath12k: Clear the flush flags after ce init and add few more
|
|
checks for checking flush flags
|
|
|
|
Usually when work threads carry out the process of
|
|
reconfiguring the chip which was asserted, a lot of other
|
|
things can happen from upper layers, requesting some
|
|
actions especially when the chip is down. Adding a check
|
|
for chip recovery might help at times, but it need not
|
|
always work because of this worker thread async.
|
|
|
|
This change will be checking the chip recovery flag in the mac_op functions.
|
|
If the flag ATH12K_FLAG_CRASH_FLUSH is set then return -ESTUTDOWN.
|
|
|
|
This will ensure, when the restart_work and reset_work threads
|
|
take care of the chip recovery and reset work respectively, they set and
|
|
clear the FLUSH bits at the right places, when the FW is fully down and when
|
|
the FW has been initialized properly and the upper layers such as mac80211
|
|
get failure messages when they send out WMI commands when the chip is
|
|
still down.
|
|
|
|
Also, add BUG_ON, in case SSR fails to recover the chip. This is
|
|
because the chip will not be in UP state and it is better to crash
|
|
the system in this case. The goal here is to keep the system in a
|
|
usable state, when an external event disrupts the recovery
|
|
process.
|
|
|
|
Disable ds link netdev before setting arvif->ar to NULL.
|
|
Ideally it is better to avoid external operations like scan
|
|
which involves kworker threads like vdev_scan_del_wk running parallelly
|
|
with the fw recovery threads, which might lead to unwanted race
|
|
conditions.
|
|
|
|
Use appropriate flags to ensure upper layer initiated scan operations
|
|
are not entertained and do a core halt op after ensuring the already
|
|
triggered scan is either aborted or completed
|
|
|
|
Signed-off-by: Ramanathan Choodamani <quic_rchoodam@quicinc.com>
|
|
Signed-off-by: Sidhanta Sahu <quic_sidhanta@quicinc.com>
|
|
---
|
|
drivers/net/wireless/ath/ath12k/bondif.c | 31 +++++++---
|
|
drivers/net/wireless/ath/ath12k/bondif.h | 8 ++-
|
|
drivers/net/wireless/ath/ath12k/core.c | 16 +++++-
|
|
drivers/net/wireless/ath/ath12k/core.h | 1 +
|
|
drivers/net/wireless/ath/ath12k/htc.c | 2 +
|
|
drivers/net/wireless/ath/ath12k/mac.c | 72 +++++++++++++++++++++---
|
|
drivers/net/wireless/ath/ath12k/mhi.c | 1 +
|
|
drivers/net/wireless/ath/ath12k/pci.c | 2 +
|
|
drivers/net/wireless/ath/ath12k/peer.c | 8 +++
|
|
drivers/net/wireless/ath/ath12k/qmi.c | 1 +
|
|
drivers/net/wireless/ath/ath12k/wmi.c | 5 ++
|
|
11 files changed, 127 insertions(+), 20 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath12k/bondif.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/bondif.c
|
|
@@ -133,8 +133,9 @@ static bool ath12k_stats_update_ppe_vp(s
|
|
return true;
|
|
}
|
|
|
|
-void ath12k_enable_ppe_for_link_netdev(struct ath12k_link_vif *arvif,
|
|
- struct net_device *link_dev)
|
|
+void ath12k_enable_ppe_for_link_netdev(struct ath12k_base *ab,
|
|
+ struct ath12k_link_vif *arvif,
|
|
+ struct net_device *link_dev)
|
|
{
|
|
struct ppe_vp_ai vpai;
|
|
struct ieee80211_ppe_vp_ds_params vp_params = {0};
|
|
@@ -147,6 +148,12 @@ void ath12k_enable_ppe_for_link_netdev(s
|
|
if (!g_bonded_interface_model)
|
|
return;
|
|
|
|
+ if (!arvif->ar) {
|
|
+ ath12k_warn(ab, "failed to enable ds for link id %d \n",
|
|
+ arvif->link_id);
|
|
+ return;
|
|
+ }
|
|
+
|
|
memset(&vpai, 0, sizeof(struct ppe_vp_ai));
|
|
|
|
vpai.type = PPE_VP_TYPE_SW_L2;
|
|
@@ -175,7 +182,7 @@ void ath12k_enable_ppe_for_link_netdev(s
|
|
link_ndev_pvt->ppe_vp_profile_idx = vp_params.ppe_vp_profile_idx;
|
|
link_ndev_pvt->vp_num = ppe_vp_num;
|
|
arvif->ppe_vp_num = ppe_vp_num;
|
|
- ath12k_dbg(arvif->ar->ab, ATH12K_DBG_PPE,
|
|
+ ath12k_dbg(ab, ATH12K_DBG_PPE,
|
|
"Enabling DS index %d vp %d link_id %d %pM core_mask 0x%x\n",
|
|
vp_params.ppe_vp_profile_idx, ppe_vp_num,
|
|
arvif->link_id, arvif->addr, vpai.core_mask);
|
|
@@ -199,7 +206,9 @@ void ath12k_enable_ppe_for_link_netdev(s
|
|
return;
|
|
}
|
|
|
|
-void ath12k_disable_ppe_for_link_netdev(struct ath12k_link_vif *arvif, struct net_device *link_dev)
|
|
+void ath12k_disable_ppe_for_link_netdev(struct ath12k_base *ab,
|
|
+ struct ath12k_link_vif *arvif,
|
|
+ struct net_device *link_dev)
|
|
{
|
|
struct ieee80211_ppe_vp_ds_params vp_params = {0};
|
|
struct ath12k_link_vif_pvt *link_ndev_pvt = NULL;
|
|
@@ -207,6 +216,12 @@ void ath12k_disable_ppe_for_link_netdev(
|
|
if (!g_bonded_interface_model)
|
|
return;
|
|
|
|
+ if (!arvif->ar) {
|
|
+ ath12k_warn(ab, "failed to disable ds for link id %d \n",
|
|
+ arvif->link_id);
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (!arvif->ndev_pvt || !arvif->ndev_pvt->link_ndev) {
|
|
ath12k_err(NULL, "ERR no link dev for this vif to disable DS.\n");
|
|
return;
|
|
@@ -226,7 +241,7 @@ void ath12k_disable_ppe_for_link_netdev(
|
|
ppe_vp_free(arvif->ppe_vp_num);
|
|
}
|
|
|
|
- ath12k_dbg(arvif->ar->ab, ATH12K_DBG_PPE,
|
|
+ ath12k_dbg(ab, ATH12K_DBG_PPE,
|
|
"Destroyed PPE VP port type %d no:%d for dev:%s\n",
|
|
arvif->ppe_vp_type, arvif->ppe_vp_num, link_dev->name);
|
|
arvif->ppe_vp_num = -1;
|
|
--- a/drivers/net/wireless/ath/ath12k/bondif.h
|
|
+++ b/drivers/net/wireless/ath/ath12k/bondif.h
|
|
@@ -14,10 +14,12 @@
|
|
#define ATH12K_PPE_DS_6G_CORE_MASK 0x4
|
|
#define ATH12K_PPE_DS_DEFAULT_CORE_MASK 0x7
|
|
|
|
-void ath12k_disable_ppe_for_link_netdev(struct ath12k_link_vif *arvif,
|
|
+void ath12k_disable_ppe_for_link_netdev(struct ath12k_base *ab,
|
|
+ struct ath12k_link_vif *arvif,
|
|
struct net_device *link_dev);
|
|
-void ath12k_enable_ppe_for_link_netdev(struct ath12k_link_vif *arvif,
|
|
- struct net_device *link_dev);
|
|
+void ath12k_enable_ppe_for_link_netdev(struct ath12k_base *ab,
|
|
+ struct ath12k_link_vif *arvif,
|
|
+ struct net_device *link_dev);
|
|
int ath12k_free_bonddev_for_sfe(struct wireless_dev *wdev,
|
|
struct ieee80211_vif *vif,
|
|
int link_num);
|
|
--- a/drivers/net/wireless/ath/ath12k/core.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/core.c
|
|
@@ -53,6 +53,9 @@ module_param_named(ppe_ds_enable, ath12k
|
|
MODULE_PARM_DESC(ppe_ds_enable, "ppe_ds_enable: 0-disable, 1-enable");
|
|
|
|
static unsigned int ath12k_recovery_mode = ATH12K_MLO_RECOVERY_MODE0;
|
|
+unsigned int ath12k_ssr_failsafe_mode = false;
|
|
+module_param_named(ssr_failsafe_mode, ath12k_ssr_failsafe_mode, uint, 0644);
|
|
+MODULE_PARM_DESC(ssr_failsafe_mode, "ssr failsafe mode: 0-disable, 1-enable");
|
|
|
|
bool ath12k_mgmt_rx_reordering = false;
|
|
module_param_named(mgmt_rx_reorder, ath12k_mgmt_rx_reordering, bool, 0644);
|
|
@@ -1226,6 +1229,8 @@ static int ath12k_core_start(struct ath1
|
|
goto err_reo_cleanup;
|
|
}
|
|
|
|
+ WARN_ON(test_bit(ATH12K_FLAG_WMI_INIT_DONE, &ab->dev_flags));
|
|
+ set_bit(ATH12K_FLAG_WMI_INIT_DONE, &ab->dev_flags);
|
|
/* put hardware to DBS mode */
|
|
if (ab->hw_params->single_pdev_only) {
|
|
ret = ath12k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS);
|
|
@@ -1749,8 +1754,6 @@ static int ath12k_core_reconfigure_on_cr
|
|
if (ret)
|
|
return ret;
|
|
|
|
- clear_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
|
|
-
|
|
ret = ath12k_core_qmi_firmware_ready(ab);
|
|
if (ret)
|
|
goto err_hal_srng_deinit;
|
|
@@ -1861,6 +1864,14 @@ static void ath12k_core_post_reconfigure
|
|
switch (ar->state) {
|
|
case ATH12K_STATE_ON:
|
|
ar->state = ATH12K_STATE_RESTARTING;
|
|
+ if (ar->scan.state == ATH12K_SCAN_RUNNING ||
|
|
+ ar->scan.state == ATH12K_SCAN_STARTING)
|
|
+ ar->scan.state = ATH12K_SCAN_ABORTING;
|
|
+ ath12k_mac_scan_finish(ar);
|
|
+ mutex_unlock(&ar->conf_mutex);
|
|
+ cancel_delayed_work_sync(&ar->scan.timeout);
|
|
+ cancel_work_sync(&ar->scan.vdev_del_wk);
|
|
+ mutex_lock(&ar->conf_mutex);
|
|
ath12k_core_halt(ar);
|
|
break;
|
|
case ATH12K_STATE_OFF:
|
|
@@ -1895,10 +1906,7 @@ void ath12k_core_halt(struct ath12k *ar)
|
|
ar->num_created_vdevs = 0;
|
|
ar->allocated_vdev_map = 0;
|
|
|
|
- ath12k_mac_scan_finish(ar);
|
|
ath12k_mac_peer_cleanup_all(ar);
|
|
- cancel_delayed_work_sync(&ar->scan.timeout);
|
|
- cancel_work_sync(&ar->scan.vdev_del_wk);
|
|
cancel_work_sync(&ar->regd_update_work);
|
|
rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
|
|
synchronize_rcu();
|
|
@@ -1920,6 +1928,12 @@ static void ath12k_core_restart(struct w
|
|
ret = ath12k_core_reconfigure_on_crash(ab);
|
|
if (ret) {
|
|
ath12k_err(ab, "failed to reconfigure driver on crash recovery\n");
|
|
+ /*
|
|
+ * If for any reason, reconfiguration fails, issue bug on for
|
|
+ * Mode 0
|
|
+ */
|
|
+ if (ath12k_ssr_failsafe_mode && ath12k_recovery_mode == ATH12K_MLO_RECOVERY_MODE0)
|
|
+ BUG_ON(1);
|
|
return;
|
|
}
|
|
|
|
@@ -2059,6 +2073,9 @@ static void ath12k_core_reset(struct wor
|
|
*/
|
|
ath12k_warn(ab, "already resetting count %d\n", reset_count);
|
|
|
|
+ if (ath12k_ssr_failsafe_mode && ath12k_recovery_mode == ATH12K_MLO_RECOVERY_MODE0)
|
|
+ BUG_ON(1);
|
|
+
|
|
reinit_completion(&ab->reset_complete);
|
|
time_left = wait_for_completion_timeout(&ab->reset_complete,
|
|
ATH12K_RESET_TIMEOUT_HZ);
|
|
@@ -2118,6 +2135,8 @@ static void ath12k_core_reset(struct wor
|
|
} else if (ab->hif.bus == ATH12K_BUS_AHB) {
|
|
ath12k_coredump_download_ahb(ab);
|
|
}
|
|
+ if (ab->is_qdss_tracing)
|
|
+ ab->is_qdss_tracing = false;
|
|
|
|
/* Incase recovery fails and FW asserts again, this is to prevent invalid operation. */
|
|
if (ag->num_started && ab->fw_recovery_support)
|
|
--- a/drivers/net/wireless/ath/ath12k/core.h
|
|
+++ b/drivers/net/wireless/ath/ath12k/core.h
|
|
@@ -240,6 +240,7 @@ enum ath12k_dev_flags {
|
|
ATH12K_FLAG_HW_GROUP_ATTACHED,
|
|
ATH12K_FLAG_FTM_SEGMENTED,
|
|
ATH12K_FLAG_PPE_DS_ENABLED,
|
|
+ ATH12K_FLAG_WMI_INIT_DONE,
|
|
};
|
|
|
|
enum ath12k_monitor_flags {
|
|
--- a/drivers/net/wireless/ath/ath12k/htc.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/htc.c
|
|
@@ -643,6 +643,8 @@ int ath12k_htc_connect_service(struct at
|
|
|
|
reinit_completion(&htc->ctl_resp);
|
|
|
|
+ if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags))
|
|
+ clear_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
|
|
status = ath12k_htc_send(htc, ATH12K_HTC_EP_0, skb);
|
|
if (status) {
|
|
kfree_skb(skb);
|
|
--- a/drivers/net/wireless/ath/ath12k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/mac.c
|
|
@@ -4714,7 +4714,12 @@ static void ath12k_mac_op_vif_cfg_change
|
|
if (changed & BSS_CHANGED_ASSOC) {
|
|
/* TODO Handle STA ML assoc */
|
|
arvif = &ahvif->deflink;
|
|
+ if (!(arvif && arvif->ar)) {
|
|
+ ath12k_err(NULL, "unable to change vif config\n");
|
|
+ return;
|
|
+ }
|
|
ar = arvif->ar;
|
|
+
|
|
if (vif->cfg.assoc)
|
|
ath12k_bss_assoc(ar, arvif, &vif->bss_conf);
|
|
else
|
|
@@ -4747,6 +4752,15 @@ static void ath12k_mac_op_bss_info_chang
|
|
}
|
|
ar = arvif->ar;
|
|
|
|
+ if (!ar) {
|
|
+ ath12k_info(NULL,
|
|
+ "bss info parameter changes %llx cached to apply after vdev create on channel assign\n",
|
|
+ changed);
|
|
+ ahvif->cache[link_id].bss_conf_changed |= changed;
|
|
+ mutex_unlock(&ah->conf_mutex);
|
|
+ return;
|
|
+ }
|
|
+
|
|
mutex_lock(&ar->conf_mutex);
|
|
|
|
ath12k_mac_bss_info_changed(ar, arvif, info, changed);
|
|
@@ -4784,21 +4798,22 @@ static int ath12k_mac_vdev_delete(struct
|
|
ar->ab->free_vdev_map |= 1LL << arvif->vdev_id;
|
|
spin_unlock_bh(&ar->ab->base_lock);
|
|
|
|
+#ifdef CPTCFG_ATH12K_BONDED_DS_SUPPORT
|
|
+ if (arvif->link_id != ATH12K_DEFAULT_SCAN_LINK && arvif->ndev_pvt) {
|
|
+ ath12k_bond_link_release(arvif);
|
|
+ if (ahvif->vdev_type == WMI_VDEV_TYPE_AP)
|
|
+ ath12k_disable_ppe_for_link_netdev(ar->ab, arvif,
|
|
+ arvif->ndev_pvt->link_ndev);
|
|
+ }
|
|
+#endif
|
|
ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id);
|
|
ar->ab->free_vdev_stats_id_map &= ~(1LL << arvif->vdev_stats_id);
|
|
ar->num_created_vdevs--;
|
|
arvif->ahvif->num_vdev_created--;
|
|
arvif->is_created = false;
|
|
+ arvif->ar = NULL;
|
|
|
|
clean_up:
|
|
-#ifdef CPTCFG_ATH12K_BONDED_DS_SUPPORT
|
|
- if (arvif->link_id != ATH12K_DEFAULT_SCAN_LINK && arvif->ndev_pvt) {
|
|
- ath12k_bond_link_release(arvif);
|
|
- ath12k_disable_ppe_for_link_netdev(arvif, arvif->ndev_pvt->link_ndev);
|
|
- }
|
|
-#endif
|
|
-
|
|
- arvif->ar = NULL;
|
|
spin_lock_bh(&ar->data_lock);
|
|
list_del(&arvif->list);
|
|
spin_unlock_bh(&ar->data_lock);
|
|
@@ -5081,6 +5096,10 @@ static void ath12k_scan_vdev_del_work(st
|
|
struct ath12k_hw *ah = ar->ah;
|
|
struct ath12k_link_vif *arvif;
|
|
|
|
+ if (unlikely(test_bit(ATH12K_FLAG_RECOVERY, &ar->ab->dev_flags)))
|
|
+ return;
|
|
+
|
|
+ mutex_lock(&ah->conf_mutex);
|
|
mutex_lock(&ar->conf_mutex);
|
|
/* scan vdev got deleted already. This can happen when on same vif, new
|
|
* scan request was requested with different frequeny which leads to
|
|
@@ -5095,6 +5114,7 @@ static void ath12k_scan_vdev_del_work(st
|
|
if (!arvif) {
|
|
ath12k_warn(ar->ab, "mac scan vdev del on unknow vdev_id %d\n",
|
|
ar->scan.vdev_id);
|
|
+ mutex_unlock(&ah->conf_mutex);
|
|
return;
|
|
}
|
|
|
|
@@ -5104,15 +5124,14 @@ static void ath12k_scan_vdev_del_work(st
|
|
goto work_complete;
|
|
}
|
|
|
|
- mutex_lock(&ah->conf_mutex);
|
|
ath12k_mac_remove_link_interface(ah->hw, arvif);
|
|
ath12k_mac_unassign_link_vif(arvif);
|
|
- mutex_unlock(&ah->conf_mutex);
|
|
|
|
mutex_lock(&ar->conf_mutex);
|
|
ar->scan.vdev_id = -1;
|
|
work_complete:
|
|
mutex_unlock(&ar->conf_mutex);
|
|
+ mutex_unlock(&ah->conf_mutex);
|
|
}
|
|
|
|
static int ath12k_start_scan(struct ath12k *ar,
|
|
@@ -5178,7 +5197,7 @@ static int ath12k_mac_op_hw_scan(struct
|
|
return -EINVAL;
|
|
}
|
|
|
|
- if (unlikely(test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))) {
|
|
+ if (unlikely(test_bit(ATH12K_FLAG_RECOVERY, &ar->ab->dev_flags))) {
|
|
mutex_unlock(&ah->conf_mutex);
|
|
return -ESHUTDOWN;
|
|
}
|
|
@@ -5206,6 +5225,10 @@ static int ath12k_mac_op_hw_scan(struct
|
|
mutex_unlock(&ah->conf_mutex);
|
|
return -EINVAL;
|
|
} else if (ar != arvif->ar) {
|
|
+ if (!arvif->ar) {
|
|
+ mutex_unlock(&ah->conf_mutex);
|
|
+ return -EINVAL;
|
|
+ }
|
|
mutex_lock(&arvif->ar->conf_mutex);
|
|
if (arvif->ar->scan.vdev_id != -1)
|
|
arvif->ar->scan.vdev_id = -1;
|
|
@@ -5338,6 +5361,11 @@ static void ath12k_mac_op_cancel_hw_scan
|
|
}
|
|
|
|
ar = arvif->ar;
|
|
+ if (!ar) {
|
|
+ mutex_unlock(&ah->conf_mutex);
|
|
+ ath12k_err(NULL, "unable to select device to cancel scan\n");
|
|
+ return;
|
|
+ }
|
|
mutex_unlock(&ah->conf_mutex);
|
|
|
|
mutex_lock(&ar->conf_mutex);
|
|
@@ -5669,6 +5697,17 @@ static int ath12k_mac_op_set_key(struct
|
|
return 0;
|
|
}
|
|
|
|
+ if (!(arvif && arvif->ar)) {
|
|
+ ath12k_err(NULL, "Failed to set key.\n");
|
|
+ mutex_unlock(&ah->conf_mutex);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &arvif->ar->ab->dev_flags)) {
|
|
+ mutex_unlock(&ah->conf_mutex);
|
|
+ return -ESHUTDOWN;
|
|
+ }
|
|
+
|
|
if (sta) {
|
|
ahsta = (struct ath12k_sta *)sta->drv_priv;
|
|
if (sta->mlo) {
|
|
@@ -6595,6 +6634,10 @@ static void ath12k_mac_dec_num_stations(
|
|
struct ath12k_sta *ahsta = arsta->ahsta;
|
|
struct ieee80211_sta *sta;
|
|
|
|
+ if (ar && !ar->num_stations &&
|
|
+ test_bit(ATH12K_FLAG_RECOVERY, &ar->ab->dev_flags))
|
|
+ return;
|
|
+
|
|
sta = container_of((void *)ahsta, struct ieee80211_sta, drv_priv);
|
|
|
|
lockdep_assert_held(&ar->conf_mutex);
|
|
@@ -6950,6 +6993,7 @@ static void ath12k_mac_ml_station_remove
|
|
ar = arvif->ar;
|
|
|
|
mutex_lock(&ar->conf_mutex);
|
|
+
|
|
ath12k_mac_station_post_remove(ar, arvif, arsta);
|
|
mutex_unlock(&ar->conf_mutex);
|
|
|
|
@@ -7160,6 +7204,10 @@ static int ath12k_mac_op_sta_state(struc
|
|
|
|
ret = ath12k_mac_handle_link_sta_state(hw, arvif, arsta,
|
|
old_state, new_state);
|
|
+ if (arvif->ar &&
|
|
+ test_bit(ATH12K_FLAG_RECOVERY, &arvif->ar->ab->dev_flags))
|
|
+ ret = 0;
|
|
+
|
|
mutex_unlock(&ah->conf_mutex);
|
|
return ret;
|
|
}
|
|
@@ -7209,6 +7257,18 @@ static int ath12k_mac_op_sta_state(struc
|
|
ath12k_err(NULL, "unable to move link sta %d of sta %pM from state %d to %d",
|
|
link_id, arsta->addr, old_state, new_state);
|
|
|
|
+ /* If FW recovery is ongoing, no need to move down sta states
|
|
+ * as FW will wake up with a clean slate. Hence we set the
|
|
+ * return value to 0, so that upper layers are not aware
|
|
+ * of the FW being in recovery state.
|
|
+ */
|
|
+ if (old_state > new_state) {
|
|
+ if (!arvif->ar)
|
|
+ continue;
|
|
+ if (test_bit(ATH12K_FLAG_RECOVERY, &arvif->ar->ab->dev_flags))
|
|
+ ret = 0;
|
|
+ }
|
|
+
|
|
if (old_state == IEEE80211_STA_NOTEXIST && new_state == IEEE80211_STA_NONE) {
|
|
|
|
/* Unassign this link sta which couldnt be added to FW and
|
|
@@ -7282,6 +7342,11 @@ static int ath12k_mac_op_change_sta_link
|
|
}
|
|
|
|
ar = arvif->ar;
|
|
+ if (!ar) {
|
|
+ ath12k_err(NULL,
|
|
+ "Failed to get ar to change sta links\n");
|
|
+ continue;
|
|
+ }
|
|
|
|
mutex_lock(&ar->conf_mutex);
|
|
ret = ath12k_mac_station_add(ar, arvif, arsta);
|
|
@@ -7582,6 +7647,10 @@ static int ath12k_mac_op_conf_tx(struct
|
|
mutex_unlock(&ah->conf_mutex);
|
|
|
|
ar = arvif->ar;
|
|
+ if (!ar) {
|
|
+ ath12k_err(NULL, "Failed to config tx\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
|
|
mutex_lock(&ar->conf_mutex);
|
|
ret = ath12k_mac_conf_tx(ar, arvif, ac, params);
|
|
@@ -9886,7 +9955,7 @@ static int ath12k_mac_vdev_create(struct
|
|
arvif->ppe_vp_num = -1;
|
|
}
|
|
else if (link_ndev) {
|
|
- ath12k_enable_ppe_for_link_netdev(arvif,
|
|
+ ath12k_enable_ppe_for_link_netdev(ab, arvif,
|
|
arvif->ndev_pvt->link_ndev);
|
|
ath12k_bond_link_enslave(arvif, arvif->ndev_pvt->link_ndev);
|
|
}
|
|
@@ -10000,6 +10069,7 @@ err_vdev_del:
|
|
spin_unlock_bh(&ar->data_lock);
|
|
|
|
err:
|
|
+ arvif->is_created = false;
|
|
arvif->ar = NULL;
|
|
return ret;
|
|
}
|
|
@@ -12663,6 +12733,14 @@ static int ath12k_mac_op_set_rts_thresho
|
|
}
|
|
|
|
ar = arvif->ar;
|
|
+ if (!ar) {
|
|
+ ath12k_err(NULL,
|
|
+ "Failed to set rts threshold for link: %d\n",
|
|
+ link_id);
|
|
+ mutex_unlock(&ah->conf_mutex);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
ret = ath12k_set_vdev_param_to_all_vifs(ar, param_id, value);
|
|
if (ret) {
|
|
ath12k_warn(ar->ab, "failed to set RTS config for all vdevs of pdev %d",
|
|
@@ -13911,6 +13989,11 @@ static void ath12k_mac_op_sta_statistics
|
|
|
|
/* TODO accumulate link sta stats here? */
|
|
|
|
+ if (!ar) {
|
|
+ ath12k_err(NULL,
|
|
+ "unable to determine sta statistics \n");
|
|
+ return;
|
|
+ }
|
|
sinfo->rx_duration = arsta->rx_duration;
|
|
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION);
|
|
|
|
--- a/drivers/net/wireless/ath/ath12k/mhi.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/mhi.c
|
|
@@ -331,6 +331,7 @@ static void ath12k_mhi_op_status_cb(stru
|
|
break;
|
|
case MHI_CB_EE_RDDM:
|
|
if (!(test_bit(ATH12K_FLAG_UNREGISTERING, &ab->ag->dev_flags))) {
|
|
+ set_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
|
|
set_bit(ATH12K_FLAG_RECOVERY, &ab->dev_flags);
|
|
queue_work(ab->workqueue_aux, &ab->reset_work);
|
|
}
|
|
--- a/drivers/net/wireless/ath/ath12k/pci.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/pci.c
|
|
@@ -1549,6 +1549,8 @@ static void ath12k_pci_shutdown(struct p
|
|
struct ath12k_base *ab = pci_get_drvdata(pdev);
|
|
|
|
set_bit(ATH12K_FLAG_UNREGISTERING, &ab->ag->dev_flags);
|
|
+ if (test_bit(ATH12K_FLAG_RECOVERY, &ab->dev_flags))
|
|
+ return;
|
|
cancel_work_sync(&ab->reset_work);
|
|
ath12k_core_deinit(ab);
|
|
}
|
|
--- a/drivers/net/wireless/ath/ath12k/peer.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/peer.c
|
|
@@ -387,8 +387,13 @@ int ath12k_ml_link_peers_delete(struct a
|
|
|
|
ar = arvif->ar;
|
|
|
|
+ if (!ar)
|
|
+ continue;
|
|
cancel_work_sync(&arsta->update_wk);
|
|
|
|
+ if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags) ||
|
|
+ test_bit(ATH12K_FLAG_RECOVERY, &ar->ab->dev_flags))
|
|
+ continue;
|
|
mutex_lock(&ar->conf_mutex);
|
|
ath12k_dp_peer_cleanup(ar, arvif->vdev_id, arsta->addr);
|
|
|
|
@@ -414,6 +419,12 @@ int ath12k_ml_link_peers_delete(struct a
|
|
|
|
ar = arvif->ar;
|
|
|
|
+ if (!ar)
|
|
+ continue;
|
|
+
|
|
+ if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags) ||
|
|
+ test_bit(ATH12K_FLAG_RECOVERY, &ar->ab->dev_flags))
|
|
+ continue;
|
|
mutex_lock(&ar->conf_mutex);
|
|
ret = ath12k_wait_for_peer_delete_done(ar, arvif->vdev_id, arsta->addr);
|
|
if (ret) {
|
|
--- a/drivers/net/wireless/ath/ath12k/qmi.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
|
|
@@ -5714,6 +5714,7 @@ static void ath12k_qmi_driver_event_work
|
|
break;
|
|
case ATH12K_QMI_EVENT_SERVER_EXIT:
|
|
set_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
|
|
+ clear_bit(ATH12K_FLAG_WMI_INIT_DONE, &ab->dev_flags);
|
|
break;
|
|
case ATH12K_QMI_EVENT_REQUEST_MEM:
|
|
ret = ath12k_qmi_event_mem_request(qmi);
|
|
--- a/drivers/net/wireless/ath/ath12k/wmi.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
|
|
@@ -542,6 +542,10 @@ int ath12k_wmi_cmd_send(struct ath12k_pd
|
|
int ret = -EOPNOTSUPP;
|
|
struct ath12k_base *ab = wmi_sc->ab;
|
|
|
|
+ if (!(test_bit(ATH12K_FLAG_WMI_INIT_DONE, &wmi_sc->ab->dev_flags)) &&
|
|
+ cmd_id != WMI_INIT_CMDID)
|
|
+ return -ESHUTDOWN;
|
|
+
|
|
might_sleep();
|
|
|
|
if (ab->hw_params->credit_flow) {
|
|
@@ -13946,6 +13950,7 @@ void ath12k_wmi_detach(struct ath12k_bas
|
|
for (i = 0; i < ab->htc.wmi_ep_count; i++)
|
|
ath12k_wmi_pdev_detach(ab, i);
|
|
|
|
+ clear_bit(ATH12K_FLAG_WMI_INIT_DONE, &ab->dev_flags);
|
|
ath12k_wmi_free_dbring_caps(ab);
|
|
}
|
|
|