On 03/11/2013 04:41 PM, Kalle Valo wrote:
Julien Massot <jmassot@xxxxxxxxxxxxxxxxxxxxxx> writes:
Julien reported that ar6004 usb device fails to initialise
after host has been rebooted and power is still on for the ar6004 device. He
found out that doing a cold reset fixes the issue.
I wasn't sure what would be the best way to detect if target needs a reset so I
settled on checking a timeout from htc_wait_recv_ctrl_message().
Reported-by: Julien Massot <jmassot@xxxxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Kalle Valo <kvalo@xxxxxxxxxxxxxxxx>
---
This patch fix the issue, now my adapter works after a soft reboot.
The log are also better: (here is what happen on soft reboot)
[ 17.328029] ath6kl: htc pipe control receive timeout!
[ 17.328033] ath6kl: htc wait target timed out, resetting device
[ 17.332178] ath6kl: Failed to start hardware: -110
[ 17.332208] ath6kl: Failed to init ath6kl core: -110
[ 17.332270] ath6kl_usb: probe of 2-1:1.0 failed with error -110
[ 17.332306] usbcore: registered new interface driver ath6kl_usb
[ 19.040315] ath6kl: ar6004 hw 1.3 usb fw 3.5.0.2356\x01 api 3
Oh, I also need to fix that \x01 in the firmware version, the null
termination is incorrect. But this is a separate issue.
Tested-by: Julien Massot <jmassot@xxxxxxxxxxxxxxxxxxxxxx>
Thank you. I add that to the patch.
Kalle,
attached the internally suggested patch with CL explanation, not rebased.
During host crashes or some unexpected reasons causing driver reload
without unload first, the target firmware will fail to upload again
since it never power down or reset by host. We check the host app area
to check target status and reset target if needed.
--
thanks,
shafi
>From 13ca700a2fede518255727446d62eaf59807d182 Mon Sep 17 00:00:00 2001
From: Mohammed Shafi Shajakhan <mohammed@xxxxxxxxxxxxxxxx>
Date: Sun, 3 Mar 2013 00:12:21 +0530
Subject: [PATCH] ath6kl: Reset target if the firmware is already uploaded
Signed-off-by: Mohammed Shafi Shajakhan <mohammed@xxxxxxxxxxxxxxxx>
---
drivers/net/wireless/ath/ath6kl/core.c | 7 +++++++
drivers/net/wireless/ath/ath6kl/core.h | 1 +
drivers/net/wireless/ath/ath6kl/init.c | 17 +++++++++++++++++
3 files changed, 25 insertions(+)
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c
index 47800c2..65d3ed8 100644
--- a/drivers/net/wireless/ath/ath6kl/core.c
+++ b/drivers/net/wireless/ath/ath6kl/core.c
@@ -104,6 +104,13 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
ar->target_type = le32_to_cpu(targ_info.type);
ar->wiphy->hw_version = le32_to_cpu(targ_info.version);
+ if (ath6kl_get_host_app_area(ar)) {
+ ath6kl_err("Firmware already uploaded, reset target\n");
+ ath6kl_reset_device(ar, ar->target_type, true, true);
+ ret = -EAGAIN;
+ goto err_power_off;
+ }
+
ret = ath6kl_init_hw_params(ar);
if (ret)
goto err_power_off;
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index d7202f1..4ccfaec 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -1013,6 +1013,7 @@ int ath6kl_init_hw_start(struct ath6kl *ar);
int ath6kl_init_hw_stop(struct ath6kl *ar);
int ath6kl_init_fetch_firmwares(struct ath6kl *ar);
int ath6kl_init_hw_params(struct ath6kl *ar);
+int ath6kl_get_host_app_area(struct ath6kl *ar);
void ath6kl_check_wow_status(struct ath6kl *ar);
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 6cfd827..ad4e454 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -283,6 +283,23 @@ void ath6kl_init_profile_info(struct ath6kl_vif *vif)
vif->bss_ch = 0;
}
+int ath6kl_get_host_app_area(struct ath6kl *ar)
+{
+ u32 address, data;
+
+ /* Fetch the address of the host_app_area_s
+ * instance in the host interest area */
+ address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_app_host_interest));
+ address = TARG_VTOP(ar->target_type, address);
+
+ if (ath6kl_diag_read32(ar, address, &data))
+ return -EIO;
+
+ address = TARG_VTOP(ar->target_type, data);
+
+ return address;
+}
+
static int ath6kl_set_host_app_area(struct ath6kl *ar)
{
u32 address, data;
--
1.7.9.5