aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2015-01-24 05:14:47 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2015-01-27 08:50:50 -0500
commit04de6c6ce612ad159d44572b6ed566e57ecefcab (patch)
tree89fac868dea93ae40d468a20130cc982ff5e28bd /drivers/net/wireless/ath
parent6d48161678dcbeb1ac1736aaf11d10c55ed9a314 (diff)
ath10k: implement diag data container event
Some firmware revisions may report this event as part of their diagnostics. This avoids `unknown event` warnings and adds tracing for the event. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath10k/trace.h41
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c68
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.h19
3 files changed, 128 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h
index b289378b6e3e..1c541f73370d 100644
--- a/drivers/net/wireless/ath/ath10k/trace.h
+++ b/drivers/net/wireless/ath/ath10k/trace.h
@@ -453,6 +453,47 @@ TRACE_EVENT(ath10k_htt_rx_desc,
453 ) 453 )
454); 454);
455 455
456TRACE_EVENT(ath10k_wmi_diag_container,
457 TP_PROTO(struct ath10k *ar,
458 u8 type,
459 u32 timestamp,
460 u32 code,
461 u16 len,
462 const void *data),
463
464 TP_ARGS(ar, type, timestamp, code, len, data),
465
466 TP_STRUCT__entry(
467 __string(device, dev_name(ar->dev))
468 __string(driver, dev_driver_string(ar->dev))
469 __field(u8, type)
470 __field(u32, timestamp)
471 __field(u32, code)
472 __field(u16, len)
473 __dynamic_array(u8, data, len)
474 ),
475
476 TP_fast_assign(
477 __assign_str(device, dev_name(ar->dev));
478 __assign_str(driver, dev_driver_string(ar->dev));
479 __entry->type = type;
480 __entry->timestamp = timestamp;
481 __entry->code = code;
482 __entry->len = len;
483 memcpy(__get_dynamic_array(data), data, len);
484 ),
485
486 TP_printk(
487 "%s %s diag container type %hhu timestamp %u code %u len %d",
488 __get_str(driver),
489 __get_str(device),
490 __entry->type,
491 __entry->timestamp,
492 __entry->code,
493 __entry->len
494 )
495);
496
456#endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/ 497#endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/
457 498
458/* we don't want to use include/trace/events */ 499/* we don't want to use include/trace/events */
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 6f34fc7d663e..56cd51d0ac93 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -60,6 +60,8 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = {
60 = { .min_len = sizeof(struct wmi_tlv_rdy_ev) }, 60 = { .min_len = sizeof(struct wmi_tlv_rdy_ev) },
61 [WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT] 61 [WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT]
62 = { .min_len = sizeof(struct wmi_tlv_bcn_tx_status_ev) }, 62 = { .min_len = sizeof(struct wmi_tlv_bcn_tx_status_ev) },
63 [WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT]
64 = { .min_len = sizeof(struct wmi_tlv_diag_data_ev) },
63}; 65};
64 66
65static int 67static int
@@ -203,6 +205,69 @@ static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar,
203 return 0; 205 return 0;
204} 206}
205 207
208static int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar,
209 struct sk_buff *skb)
210{
211 const void **tb;
212 const struct wmi_tlv_diag_data_ev *ev;
213 const struct wmi_tlv_diag_item *item;
214 const void *data;
215 int ret, num_items, len;
216
217 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
218 if (IS_ERR(tb)) {
219 ret = PTR_ERR(tb);
220 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
221 return ret;
222 }
223
224 ev = tb[WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT];
225 data = tb[WMI_TLV_TAG_ARRAY_BYTE];
226 if (!ev || !data) {
227 kfree(tb);
228 return -EPROTO;
229 }
230
231 num_items = __le32_to_cpu(ev->num_items);
232 len = ath10k_wmi_tlv_len(data);
233
234 while (num_items--) {
235 if (len == 0)
236 break;
237 if (len < sizeof(*item)) {
238 ath10k_warn(ar, "failed to parse diag data: can't fit item header\n");
239 break;
240 }
241
242 item = data;
243
244 if (len < sizeof(*item) + __le16_to_cpu(item->len)) {
245 ath10k_warn(ar, "failed to parse diag data: item is too long\n");
246 break;
247 }
248
249 trace_ath10k_wmi_diag_container(ar,
250 item->type,
251 __le32_to_cpu(item->timestamp),
252 __le32_to_cpu(item->code),
253 __le16_to_cpu(item->len),
254 item->payload);
255
256 len -= sizeof(*item);
257 len -= roundup(__le16_to_cpu(item->len), 4);
258
259 data += sizeof(*item);
260 data += roundup(__le16_to_cpu(item->len), 4);
261 }
262
263 if (num_items != -1 || len != 0)
264 ath10k_warn(ar, "failed to parse diag data event: num_items %d len %d\n",
265 num_items, len);
266
267 kfree(tb);
268 return 0;
269}
270
206/***********/ 271/***********/
207/* TLV ops */ 272/* TLV ops */
208/***********/ 273/***********/
@@ -318,6 +383,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
318 case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID: 383 case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID:
319 ath10k_wmi_tlv_event_bcn_tx_status(ar, skb); 384 ath10k_wmi_tlv_event_bcn_tx_status(ar, skb);
320 break; 385 break;
386 case WMI_TLV_DIAG_DATA_CONTAINER_EVENTID:
387 ath10k_wmi_tlv_event_diag_data(ar, skb);
388 break;
321 default: 389 default:
322 ath10k_warn(ar, "Unknown eventid: %d\n", id); 390 ath10k_warn(ar, "Unknown eventid: %d\n", id);
323 break; 391 break;
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
index eb02290075a7..87db762ac1a2 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -1409,6 +1409,25 @@ struct wmi_tlv_p2p_go_bcn_ie {
1409 __le32 ie_len; 1409 __le32 ie_len;
1410} __packed; 1410} __packed;
1411 1411
1412enum wmi_tlv_diag_item_type {
1413 WMI_TLV_DIAG_ITEM_TYPE_FW_EVENT,
1414 WMI_TLV_DIAG_ITEM_TYPE_FW_LOG,
1415 WMI_TLV_DIAG_ITEM_TYPE_FW_DEBUG_MSG,
1416};
1417
1418struct wmi_tlv_diag_item {
1419 u8 type;
1420 u8 reserved;
1421 __le16 len;
1422 __le32 timestamp;
1423 __le32 code;
1424 u8 payload[0];
1425} __packed;
1426
1427struct wmi_tlv_diag_data_ev {
1428 __le32 num_items;
1429} __packed;
1430
1412void ath10k_wmi_tlv_attach(struct ath10k *ar); 1431void ath10k_wmi_tlv_attach(struct ath10k *ar);
1413 1432
1414#endif 1433#endif