|
|
|
@ -358,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. |
|
|
|
@ -379,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); |
|
|
|
|