]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/mac80211/tdls.c
mac80211: set network header in TDLS frames
[karo-tx-linux.git] / net / mac80211 / tdls.c
index 50d0e0660cc44cbcf498359c2ea48038babd1d21..4ea25dec06984792234f4a77edc1e26c157b0662 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2014, Intel Corporation
+ * Copyright 2014  Intel Mobile Communications GmbH
  *
  * This file is GPLv2 as found in COPYING.
  */
@@ -316,8 +317,7 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata,
        }
 
        /* add the QoS param IE if both the peer and we support it */
-       if (local->hw.queues >= IEEE80211_NUM_ACS &&
-           test_sta_flag(sta, WLAN_STA_WME))
+       if (local->hw.queues >= IEEE80211_NUM_ACS && sta->sta.wme)
                ieee80211_tdls_add_wmm_param_ie(sdata, skb);
 
        /* add any custom IEs that go before HT operation */
@@ -412,6 +412,9 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
        tf->ether_type = cpu_to_be16(ETH_P_TDLS);
        tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
 
+       /* network header is after the ethernet header */
+       skb_set_network_header(skb, ETH_HLEN);
+
        switch (action_code) {
        case WLAN_TDLS_SETUP_REQUEST:
                tf->category = WLAN_CATEGORY_TDLS;
@@ -836,6 +839,17 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
                ret = 0;
                break;
        case NL80211_TDLS_DISABLE_LINK:
+               /*
+                * The teardown message in ieee80211_tdls_mgmt_teardown() was
+                * created while the queues were stopped, so it might still be
+                * pending. Before flushing the queues we need to be sure the
+                * message is handled by the tasklet handling pending messages,
+                * otherwise we might start destroying the station before
+                * sending the teardown packet.
+                * Note that this only forces the tasklet to flush pendings -
+                * not to stop the tasklet from rescheduling itself.
+                */
+               tasklet_kill(&local->tx_pending_tasklet);
                /* flush a potentially queued teardown packet */
                ieee80211_flush_queues(local, sdata);