ath10k: implement new beacon tx status event
authorMichal Kazior <michal.kazior@tieto.com>
Tue, 13 Jan 2015 14:30:10 +0000 (16:30 +0200)
committerKalle Valo <kvalo@qca.qualcomm.com>
Thu, 15 Jan 2015 10:30:00 +0000 (12:30 +0200)
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>
drivers/net/wireless/ath/ath10k/wmi-tlv.c
drivers/net/wireless/ath/ath10k/wmi-tlv.h

index 57d2b50c1f007a043be541af820ecc09cdb104a8..67138a69bb42955cc2c4cc4a6118048a7237fba4 100644 (file)
@@ -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;
index 54ffa120cd6022dd3feb95a4db3ae38e6edee51e..ee19353ce65ca34ec52b9f4ad497cee076833f23 100644 (file)
@@ -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