summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath10k
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2015-01-13 16:30:10 +0200
committerKalle Valo <kvalo@qca.qualcomm.com>2015-01-15 12:30:00 +0200
commit6bf1206289115c277cfa569f570a97ada345a2d5 (patch)
tree25b7249aee702acd91d306719a295955af8ad136 /drivers/net/wireless/ath/ath10k
parenta4031afbdc7bfdf26b98b160a5fca05b9cf38140 (diff)
ath10k: implement new beacon tx status event
This event is delivered to host by firmware if it supports beacon templates only. 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/ath10k')
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c50
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.h12
2 files changed, 62 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 57d2b50c1f0..67138a69bb4 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -58,6 +58,8 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = {
= { .min_len = sizeof(struct wlan_host_mem_req) },
[WMI_TLV_TAG_STRUCT_READY_EVENT]
= { .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) },
};
static int
@@ -156,6 +158,51 @@ static u16 ath10k_wmi_tlv_len(const void *ptr)
return __le16_to_cpu((((const struct wmi_tlv *)ptr) - 1)->len);
}
+/**************/
+/* TLV events */
+/**************/
+static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar,
+ struct sk_buff *skb)
+{
+ const void **tb;
+ const struct wmi_tlv_bcn_tx_status_ev *ev;
+ u32 vdev_id, tx_status;
+ int ret;
+
+ 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_OFFLOAD_BCN_TX_STATUS_EVENT];
+ if (!ev) {
+ kfree(tb);
+ return -EPROTO;
+ }
+
+ tx_status = __le32_to_cpu(ev->tx_status);
+ vdev_id = __le32_to_cpu(ev->vdev_id);
+
+ switch (tx_status) {
+ case WMI_TLV_BCN_TX_STATUS_OK:
+ break;
+ case WMI_TLV_BCN_TX_STATUS_XRETRY:
+ case WMI_TLV_BCN_TX_STATUS_DROP:
+ case WMI_TLV_BCN_TX_STATUS_FILTERED:
+ /* FIXME: It's probably worth telling mac80211 to stop the
+ * interface as it is crippled.
+ */
+ ath10k_warn(ar, "received bcn tmpl tx status on vdev %i: %d",
+ vdev_id, tx_status);
+ break;
+ }
+
+ kfree(tb);
+ return 0;
+}
+
/***********/
/* TLV ops */
/***********/
@@ -268,6 +315,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
case WMI_TLV_READY_EVENTID:
ath10k_wmi_event_ready(ar, skb);
break;
+ case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID:
+ ath10k_wmi_tlv_event_bcn_tx_status(ar, skb);
+ break;
default:
ath10k_warn(ar, "Unknown eventid: %d\n", id);
break;
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
index 54ffa120cd6..ee19353ce65 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -1375,6 +1375,18 @@ struct wmi_tlv_pktlog_disable {
__le32 reserved;
} __packed;
+enum wmi_tlv_bcn_tx_status {
+ WMI_TLV_BCN_TX_STATUS_OK,
+ WMI_TLV_BCN_TX_STATUS_XRETRY,
+ WMI_TLV_BCN_TX_STATUS_DROP,
+ WMI_TLV_BCN_TX_STATUS_FILTERED,
+};
+
+struct wmi_tlv_bcn_tx_status_ev {
+ __le32 vdev_id;
+ __le32 tx_status;
+} __packed;
+
void ath10k_wmi_tlv_attach(struct ath10k *ar);
#endif