Skip to content

Commit

Permalink
ath10k: implement diag data container event
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Michal Kazior authored and Kalle Valo committed Jan 27, 2015
1 parent 6d48161 commit 04de6c6
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 0 deletions.
41 changes: 41 additions & 0 deletions drivers/net/wireless/ath/ath10k/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,47 @@ TRACE_EVENT(ath10k_htt_rx_desc,
)
);

TRACE_EVENT(ath10k_wmi_diag_container,
TP_PROTO(struct ath10k *ar,
u8 type,
u32 timestamp,
u32 code,
u16 len,
const void *data),

TP_ARGS(ar, type, timestamp, code, len, data),

TP_STRUCT__entry(
__string(device, dev_name(ar->dev))
__string(driver, dev_driver_string(ar->dev))
__field(u8, type)
__field(u32, timestamp)
__field(u32, code)
__field(u16, len)
__dynamic_array(u8, data, len)
),

TP_fast_assign(
__assign_str(device, dev_name(ar->dev));
__assign_str(driver, dev_driver_string(ar->dev));
__entry->type = type;
__entry->timestamp = timestamp;
__entry->code = code;
__entry->len = len;
memcpy(__get_dynamic_array(data), data, len);
),

TP_printk(
"%s %s diag container type %hhu timestamp %u code %u len %d",
__get_str(driver),
__get_str(device),
__entry->type,
__entry->timestamp,
__entry->code,
__entry->len
)
);

#endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/

/* we don't want to use include/trace/events */
Expand Down
68 changes: 68 additions & 0 deletions drivers/net/wireless/ath/ath10k/wmi-tlv.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = {
= { .min_len = sizeof(struct wmi_tlv_rdy_ev) },
[WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT]
= { .min_len = sizeof(struct wmi_tlv_bcn_tx_status_ev) },
[WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT]
= { .min_len = sizeof(struct wmi_tlv_diag_data_ev) },
};

static int
Expand Down Expand Up @@ -203,6 +205,69 @@ static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar,
return 0;
}

static int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar,
struct sk_buff *skb)
{
const void **tb;
const struct wmi_tlv_diag_data_ev *ev;
const struct wmi_tlv_diag_item *item;
const void *data;
int ret, num_items, len;

tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
return ret;
}

ev = tb[WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT];
data = tb[WMI_TLV_TAG_ARRAY_BYTE];
if (!ev || !data) {
kfree(tb);
return -EPROTO;
}

num_items = __le32_to_cpu(ev->num_items);
len = ath10k_wmi_tlv_len(data);

while (num_items--) {
if (len == 0)
break;
if (len < sizeof(*item)) {
ath10k_warn(ar, "failed to parse diag data: can't fit item header\n");
break;
}

item = data;

if (len < sizeof(*item) + __le16_to_cpu(item->len)) {
ath10k_warn(ar, "failed to parse diag data: item is too long\n");
break;
}

trace_ath10k_wmi_diag_container(ar,
item->type,
__le32_to_cpu(item->timestamp),
__le32_to_cpu(item->code),
__le16_to_cpu(item->len),
item->payload);

len -= sizeof(*item);
len -= roundup(__le16_to_cpu(item->len), 4);

data += sizeof(*item);
data += roundup(__le16_to_cpu(item->len), 4);
}

if (num_items != -1 || len != 0)
ath10k_warn(ar, "failed to parse diag data event: num_items %d len %d\n",
num_items, len);

kfree(tb);
return 0;
}

/***********/
/* TLV ops */
/***********/
Expand Down Expand Up @@ -318,6 +383,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID:
ath10k_wmi_tlv_event_bcn_tx_status(ar, skb);
break;
case WMI_TLV_DIAG_DATA_CONTAINER_EVENTID:
ath10k_wmi_tlv_event_diag_data(ar, skb);
break;
default:
ath10k_warn(ar, "Unknown eventid: %d\n", id);
break;
Expand Down
19 changes: 19 additions & 0 deletions drivers/net/wireless/ath/ath10k/wmi-tlv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1409,6 +1409,25 @@ struct wmi_tlv_p2p_go_bcn_ie {
__le32 ie_len;
} __packed;

enum wmi_tlv_diag_item_type {
WMI_TLV_DIAG_ITEM_TYPE_FW_EVENT,
WMI_TLV_DIAG_ITEM_TYPE_FW_LOG,
WMI_TLV_DIAG_ITEM_TYPE_FW_DEBUG_MSG,
};

struct wmi_tlv_diag_item {
u8 type;
u8 reserved;
__le16 len;
__le32 timestamp;
__le32 code;
u8 payload[0];
} __packed;

struct wmi_tlv_diag_data_ev {
__le32 num_items;
} __packed;

void ath10k_wmi_tlv_attach(struct ath10k *ar);

#endif

0 comments on commit 04de6c6

Please sign in to comment.