aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath9k/htc_hst.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/htc_hst.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c47
1 files changed, 42 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index 1b90ed8795c..a0ff5b63705 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -14,6 +14,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "htc.h"
static int htc_issue_send(struct htc_target *target, struct sk_buff* skb,
@@ -342,6 +344,8 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv,
skb, htc_hdr->endpoint_id,
txok);
+ } else {
+ kfree_skb(skb);
}
}
@@ -354,6 +358,36 @@ ret:
kfree_skb(skb);
}
+static void ath9k_htc_fw_panic_report(struct htc_target *htc_handle,
+ struct sk_buff *skb)
+{
+ uint32_t *pattern = (uint32_t *)skb->data;
+
+ switch (*pattern) {
+ case 0x33221199:
+ {
+ struct htc_panic_bad_vaddr *htc_panic;
+ htc_panic = (struct htc_panic_bad_vaddr *) skb->data;
+ dev_err(htc_handle->dev, "ath: firmware panic! "
+ "exccause: 0x%08x; pc: 0x%08x; badvaddr: 0x%08x.\n",
+ htc_panic->exccause, htc_panic->pc,
+ htc_panic->badvaddr);
+ break;
+ }
+ case 0x33221299:
+ {
+ struct htc_panic_bad_epid *htc_panic;
+ htc_panic = (struct htc_panic_bad_epid *) skb->data;
+ dev_err(htc_handle->dev, "ath: firmware panic! "
+ "bad epid: 0x%08x\n", htc_panic->epid);
+ break;
+ }
+ default:
+ dev_err(htc_handle->dev, "ath: uknown panic pattern!\n");
+ break;
+ }
+}
+
/*
* HTC Messages are handled directly here and the obtained SKB
* is freed.
@@ -375,6 +409,12 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
htc_hdr = (struct htc_frame_hdr *) skb->data;
epid = htc_hdr->endpoint_id;
+ if (epid == 0x99) {
+ ath9k_htc_fw_panic_report(htc_handle, skb);
+ kfree_skb(skb);
+ return;
+ }
+
if (epid >= ENDPOINT_MAX) {
if (pipe_id != USB_REG_IN_PIPE)
dev_kfree_skb_any(skb);
@@ -431,11 +471,8 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle,
struct htc_target *target;
target = kzalloc(sizeof(struct htc_target), GFP_KERNEL);
- if (!target) {
- printk(KERN_ERR "Unable to allocate memory for"
- "target device\n");
+ if (!target)
return NULL;
- }
init_completion(&target->target_wait);
init_completion(&target->cmd_wait);
@@ -464,7 +501,7 @@ int ath9k_htc_hw_init(struct htc_target *target,
char *product, u32 drv_info)
{
if (ath9k_htc_probe_device(target, dev, devid, product, drv_info)) {
- printk(KERN_ERR "Failed to initialize the device\n");
+ pr_err("Failed to initialize the device\n");
return -ENODEV;
}