@@ -1435,10 +1435,8 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
return ret;
}
-static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
+static void ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
{
- int ret;
-
mutex_lock(&ab->core_lock);
ath11k_thermal_unregister(ab);
ath11k_hif_irq_disable(ab);
@@ -1450,27 +1448,8 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
mutex_unlock(&ab->core_lock);
ath11k_dp_free(ab);
- ath11k_hal_srng_deinit(ab);
ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS(ab))) - 1;
-
- ret = ath11k_hal_srng_init(ab);
- if (ret)
- return ret;
-
- clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
-
- ret = ath11k_core_qmi_firmware_ready(ab);
- if (ret)
- goto err_hal_srng_deinit;
-
- clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
-
- return 0;
-
-err_hal_srng_deinit:
- ath11k_hal_srng_deinit(ab);
- return ret;
}
void ath11k_core_halt(struct ath11k *ar)
@@ -1608,22 +1587,10 @@ static void ath11k_core_post_reconfigure_recovery(struct ath11k_base *ab)
static void ath11k_core_restart(struct work_struct *work)
{
struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work);
- int ret;
-
- if (!ab->is_reset)
- ath11k_core_pre_reconfigure_recovery(ab);
-
- ret = ath11k_core_reconfigure_on_crash(ab);
- if (ret) {
- ath11k_err(ab, "failed to reconfigure driver on crash recovery\n");
- return;
- }
-
- if (ab->is_reset)
- complete_all(&ab->reconfigure_complete);
- if (!ab->is_reset)
- ath11k_core_post_reconfigure_recovery(ab);
+ ath11k_core_pre_reconfigure_recovery(ab);
+ ath11k_core_reconfigure_on_crash(ab);
+ ath11k_core_post_reconfigure_recovery(ab);
}
static void ath11k_core_reset(struct work_struct *work)
@@ -1677,18 +1644,6 @@ static void ath11k_core_reset(struct work_struct *work)
ab->is_reset = true;
atomic_set(&ab->recovery_count, 0);
- reinit_completion(&ab->recovery_start);
- atomic_set(&ab->recovery_start_count, 0);
-
- ath11k_core_pre_reconfigure_recovery(ab);
-
- reinit_completion(&ab->reconfigure_complete);
- ath11k_core_post_reconfigure_recovery(ab);
-
- ath11k_dbg(ab, ATH11K_DBG_BOOT, "waiting recovery start...\n");
-
- time_left = wait_for_completion_timeout(&ab->recovery_start,
- ATH11K_RECOVER_START_TIMEOUT_HZ);
ath11k_hif_power_down(ab);
ath11k_hif_power_up(ab);
@@ -1796,8 +1751,6 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
spin_lock_init(&ab->base_lock);
mutex_init(&ab->vdev_id_11d_lock);
init_completion(&ab->reset_complete);
- init_completion(&ab->reconfigure_complete);
- init_completion(&ab->recovery_start);
INIT_LIST_HEAD(&ab->peers);
init_waitqueue_head(&ab->peer_mapping_wq);
@@ -1823,5 +1776,37 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
}
EXPORT_SYMBOL(ath11k_core_alloc);
+int ath11k_core_start_device(struct ath11k_base *ab)
+{
+ int ret;
+
+ if (!test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags))
+ return 0;
+
+ ath11k_hal_srng_deinit(ab);
+
+ ret = ath11k_hal_srng_init(ab);
+ if (ret) {
+ ath11k_err(ab, "failed to init srng: %d\n", ret);
+ return ret;
+ }
+
+ clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
+
+ ret = ath11k_core_qmi_firmware_ready(ab);
+ if (ret) {
+ ath11k_err(ab, "failed to init core: %d\n", ret);
+ goto err_hal_srng_deinit;
+ }
+
+ clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
+
+ return 0;
+
+err_hal_srng_deinit:
+ ath11k_hal_srng_deinit(ab);
+ return ret;
+}
+
MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards.");
MODULE_LICENSE("Dual BSD/GPL");
@@ -60,8 +60,6 @@ extern unsigned int ath11k_frame_mode;
#define ATH11K_RESET_MAX_FAIL_COUNT_FIRST 3
#define ATH11K_RESET_MAX_FAIL_COUNT_FINAL 5
#define ATH11K_RESET_FAIL_TIMEOUT_HZ (20 * HZ)
-#define ATH11K_RECONFIGURE_TIMEOUT_HZ (10 * HZ)
-#define ATH11K_RECOVER_START_TIMEOUT_HZ (20 * HZ)
enum ath11k_supported_bw {
ATH11K_BW_20 = 0,
@@ -913,11 +911,8 @@ struct ath11k_base {
struct work_struct reset_work;
atomic_t reset_count;
atomic_t recovery_count;
- atomic_t recovery_start_count;
bool is_reset;
struct completion reset_complete;
- struct completion reconfigure_complete;
- struct completion recovery_start;
/* continuous recovery fail count */
atomic_t fail_cont_count;
unsigned long reset_fail_timeout;
@@ -1140,6 +1135,7 @@ int ath11k_core_check_smbios(struct ath11k_base *ab);
void ath11k_core_halt(struct ath11k *ar);
int ath11k_core_resume(struct ath11k_base *ab);
int ath11k_core_suspend(struct ath11k_base *ab);
+int ath11k_core_start_device(struct ath11k_base *ab);
const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
const char *filename);
@@ -5696,27 +5696,6 @@ static int ath11k_mac_config_mon_status_default(struct ath11k *ar, bool enable)
return ret;
}
-static void ath11k_mac_wait_reconfigure(struct ath11k_base *ab)
-{
- int recovery_start_count;
-
- if (!ab->is_reset)
- return;
-
- recovery_start_count = atomic_inc_return(&ab->recovery_start_count);
- ath11k_dbg(ab, ATH11K_DBG_MAC, "recovery start count %d\n", recovery_start_count);
-
- if (recovery_start_count == ab->num_radios) {
- complete(&ab->recovery_start);
- ath11k_dbg(ab, ATH11K_DBG_MAC, "recovery started success\n");
- }
-
- ath11k_dbg(ab, ATH11K_DBG_MAC, "waiting reconfigure...\n");
-
- wait_for_completion_timeout(&ab->reconfigure_complete,
- ATH11K_RECONFIGURE_TIMEOUT_HZ);
-}
-
static int ath11k_mac_op_start(struct ieee80211_hw *hw)
{
struct ath11k *ar = hw->priv;
@@ -5725,6 +5704,13 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw)
int ret;
ath11k_mac_drain_tx(ar);
+
+ ret = ath11k_core_start_device(ab);
+ if (ret) {
+ ath11k_err(ab, "failed to start device : %d\n", ret);
+ return ret;
+ }
+
mutex_lock(&ar->conf_mutex);
switch (ar->state) {
@@ -5733,7 +5719,6 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw)
break;
case ATH11K_STATE_RESTARTING:
ar->state = ATH11K_STATE_RESTARTED;
- ath11k_mac_wait_reconfigure(ab);
break;
case ATH11K_STATE_RESTARTED:
case ATH11K_STATE_WEDGED:
Currently during recovery, hardware is re-initialized as part of ath11k_core_reconfigure_on_crash(). In order to enable low power mode support in the driver, it is required to move the hardware re-initialization logic to ath11k_ops.start() hook. Since ath11k_ops.start() hook is called during WiFi ON/resume and also during hardware recovery, it is better to defer the hardware initialization to ath11k_ops.start() in the case of hardware recovery. This will help ensure that there is only path for the initialization of the hardware across different scenarios. A future patch will add the support of initializing the hardware from start() hook in WiFi ON/resume cases as well. Commit 38194f3a605e ("ath11k: add synchronization operation between reconfigure of mac80211 and ath11k_base") introduced a similar change that applies just to QCA6390/WCN6855 to defer the initialization of the hardware during recovery by using wait logic. This is no more needed and therefore remove it. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Signed-off-by: Manikanta Pubbisetty <quic_mpubbise@quicinc.com> --- drivers/net/wireless/ath/ath11k/core.c | 87 +++++++++++--------------- drivers/net/wireless/ath/ath11k/core.h | 6 +- drivers/net/wireless/ath/ath11k/mac.c | 29 +++------ 3 files changed, 44 insertions(+), 78 deletions(-)