summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath10k/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/core.c')
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c88
1 files changed, 62 insertions, 26 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index eadb2251991..cee18c89d7f 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -26,6 +26,7 @@
#include "bmi.h"
#include "debug.h"
#include "htt.h"
+#include "testmode.h"
unsigned int ath10k_debug_mask;
static bool uart_print;
@@ -257,21 +258,42 @@ static int ath10k_download_and_run_otp(struct ath10k *ar)
return 0;
}
-static int ath10k_download_fw(struct ath10k *ar)
+static int ath10k_download_fw(struct ath10k *ar, enum ath10k_firmware_mode mode)
{
- u32 address;
+ u32 address, data_len;
+ const char *mode_name;
+ const void *data;
int ret;
address = ar->hw_params.patch_load_addr;
- ret = ath10k_bmi_fast_download(ar, address, ar->firmware_data,
- ar->firmware_len);
+ switch (mode) {
+ case ATH10K_FIRMWARE_MODE_NORMAL:
+ data = ar->firmware_data;
+ data_len = ar->firmware_len;
+ mode_name = "normal";
+ break;
+ case ATH10K_FIRMWARE_MODE_UTF:
+ data = ar->testmode.utf->data;
+ data_len = ar->testmode.utf->size;
+ mode_name = "utf";
+ break;
+ default:
+ ath10k_err(ar, "unknown firmware mode: %d\n", mode);
+ return -EINVAL;
+ }
+
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+ "boot uploading firmware image %p len %d mode %s\n",
+ data, data_len, mode_name);
+
+ ret = ath10k_bmi_fast_download(ar, address, data, data_len);
if (ret) {
- ath10k_err(ar, "could not write fw (%d)\n", ret);
- goto exit;
+ ath10k_err(ar, "failed to download %s firmware: %d\n",
+ mode_name, ret);
+ return ret;
}
-exit:
return ret;
}
@@ -567,7 +589,8 @@ success:
return 0;
}
-static int ath10k_init_download_firmware(struct ath10k *ar)
+static int ath10k_init_download_firmware(struct ath10k *ar,
+ enum ath10k_firmware_mode mode)
{
int ret;
@@ -583,7 +606,7 @@ static int ath10k_init_download_firmware(struct ath10k *ar)
return ret;
}
- ret = ath10k_download_fw(ar);
+ ret = ath10k_download_fw(ar, mode);
if (ret) {
ath10k_err(ar, "failed to download firmware: %d\n", ret);
return ret;
@@ -685,12 +708,15 @@ static void ath10k_core_restart(struct work_struct *work)
case ATH10K_STATE_WEDGED:
ath10k_warn(ar, "device is wedged, will not restart\n");
break;
+ case ATH10K_STATE_UTF:
+ ath10k_warn(ar, "firmware restart in UTF mode not supported\n");
+ break;
}
mutex_unlock(&ar->conf_mutex);
}
-int ath10k_core_start(struct ath10k *ar)
+int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
{
int status;
@@ -703,7 +729,7 @@ int ath10k_core_start(struct ath10k *ar)
goto err;
}
- status = ath10k_init_download_firmware(ar);
+ status = ath10k_init_download_firmware(ar, mode);
if (status)
goto err;
@@ -760,10 +786,12 @@ int ath10k_core_start(struct ath10k *ar)
goto err_hif_stop;
}
- status = ath10k_htt_connect(&ar->htt);
- if (status) {
- ath10k_err(ar, "failed to connect htt (%d)\n", status);
- goto err_hif_stop;
+ if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
+ status = ath10k_htt_connect(&ar->htt);
+ if (status) {
+ ath10k_err(ar, "failed to connect htt (%d)\n", status);
+ goto err_hif_stop;
+ }
}
status = ath10k_wmi_connect(ar);
@@ -778,11 +806,13 @@ int ath10k_core_start(struct ath10k *ar)
goto err_hif_stop;
}
- status = ath10k_wmi_wait_for_service_ready(ar);
- if (status <= 0) {
- ath10k_warn(ar, "wmi service ready event not received");
- status = -ETIMEDOUT;
- goto err_hif_stop;
+ if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
+ status = ath10k_wmi_wait_for_service_ready(ar);
+ if (status <= 0) {
+ ath10k_warn(ar, "wmi service ready event not received");
+ status = -ETIMEDOUT;
+ goto err_hif_stop;
+ }
}
ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n",
@@ -802,10 +832,13 @@ int ath10k_core_start(struct ath10k *ar)
goto err_hif_stop;
}
- status = ath10k_htt_setup(&ar->htt);
- if (status) {
- ath10k_err(ar, "failed to setup htt: %d\n", status);
- goto err_hif_stop;
+ /* we don't care about HTT in UTF mode */
+ if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
+ status = ath10k_htt_setup(&ar->htt);
+ if (status) {
+ ath10k_err(ar, "failed to setup htt: %d\n", status);
+ goto err_hif_stop;
+ }
}
status = ath10k_debug_start(ar);
@@ -861,7 +894,8 @@ void ath10k_core_stop(struct ath10k *ar)
lockdep_assert_held(&ar->conf_mutex);
/* try to suspend target */
- if (ar->state != ATH10K_STATE_RESTARTING)
+ if (ar->state != ATH10K_STATE_RESTARTING &&
+ ar->state != ATH10K_STATE_UTF)
ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
ath10k_debug_stop(ar);
@@ -914,7 +948,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
mutex_lock(&ar->conf_mutex);
- ret = ath10k_core_start(ar);
+ ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
if (ret) {
ath10k_err(ar, "could not init core (%d)\n", ret);
ath10k_core_free_firmware_files(ar);
@@ -1041,6 +1075,8 @@ void ath10k_core_unregister(struct ath10k *ar)
* unhappy about callback failures. */
ath10k_mac_unregister(ar);
+ ath10k_testmode_destroy(ar);
+
ath10k_core_free_firmware_files(ar);
ath10k_debug_unregister(ar);