wil6210: implement skb Tx status reporting
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Sun, 25 Jan 2015 08:52:49 +0000 (10:52 +0200)
committerKalle Valo <kvalo@codeaurora.org>
Thu, 29 Jan 2015 07:54:46 +0000 (09:54 +0200)
Implement Tx status reporting using skb_complete_wifi_ack().

Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ath/wil6210/cfg80211.c
drivers/net/wireless/ath/wil6210/txrx.c

index 6b7664d20d2efb2345e94a29312bc2f54eafb7dc..f65da91e1af8ba84411a1dbab72d564f5c0a6057 100644 (file)
@@ -858,6 +858,7 @@ static void wil_wiphy_init(struct wiphy *wiphy)
        wiphy->cipher_suites = wil_cipher_suites;
        wiphy->n_cipher_suites = ARRAY_SIZE(wil_cipher_suites);
        wiphy->mgmt_stypes = wil_mgmt_stypes;
+       wiphy->features |= NL80211_FEATURE_SK_TX_STATUS;
 }
 
 struct wireless_dev *wil_cfg80211_init(struct device *dev)
index b58ee52e1860852f717d6cb91dce40b64be3cb94..0499ebcdeff514ea24724b7dba7664f3e726726e 100644 (file)
@@ -1121,6 +1121,22 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        return NET_XMIT_DROP;
 }
 
+static inline bool wil_need_txstat(struct sk_buff *skb)
+{
+       struct ethhdr *eth = (void *)skb->data;
+
+       return is_unicast_ether_addr(eth->h_dest) && skb->sk &&
+              (skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS);
+}
+
+static inline void wil_consume_skb(struct sk_buff *skb, bool acked)
+{
+       if (unlikely(wil_need_txstat(skb)))
+               skb_complete_wifi_ack(skb, acked);
+       else
+               acked ? dev_consume_skb_any(skb) : dev_kfree_skb_any(skb);
+}
+
 /**
  * Clean up transmitted skb's from the Tx VRING
  *
@@ -1199,8 +1215,7 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
                                        ndev->stats.tx_errors++;
                                        stats->tx_errors++;
                                }
-
-                               dev_kfree_skb_any(skb);
+                               wil_consume_skb(skb, d->dma.error == 0);
                        }
                        memset(ctx, 0, sizeof(*ctx));
                        /* There is no need to touch HW descriptor: