]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - net/mac80211/tx.c
mac80211: optimise station flags
[mirror_ubuntu-artful-kernel.git] / net / mac80211 / tx.c
index 5bf91c43c88c546ebbbce4fa2ea021b4b6f8ba40..7699e666457f43f50648e3ae6b0f1bb36f37f26e 100644 (file)
@@ -253,7 +253,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
 
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
-       u32 sta_flags;
+       bool assoc = false;
 
        if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
                return TX_CONTINUE;
@@ -284,10 +284,11 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
        if (tx->flags & IEEE80211_TX_PS_BUFFERED)
                return TX_CONTINUE;
 
-       sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0;
+       if (tx->sta)
+               assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC);
 
        if (likely(tx->flags & IEEE80211_TX_UNICAST)) {
-               if (unlikely(!(sta_flags & WLAN_STA_ASSOC) &&
+               if (unlikely(!assoc &&
                             tx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
                             ieee80211_is_data(hdr->frame_control))) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -427,7 +428,7 @@ static int ieee80211_use_mfp(__le16 fc, struct sta_info *sta,
        if (!ieee80211_is_mgmt(fc))
                return 0;
 
-       if (sta == NULL || !test_sta_flags(sta, WLAN_STA_MFP))
+       if (sta == NULL || !test_sta_flag(sta, WLAN_STA_MFP))
                return 0;
 
        if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *)
@@ -444,7 +445,6 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
        struct ieee80211_local *local = tx->local;
-       u32 staflags;
 
        if (unlikely(!sta ||
                     ieee80211_is_probe_resp(hdr->frame_control) ||
@@ -453,9 +453,8 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
                     ieee80211_is_reassoc_resp(hdr->frame_control)))
                return TX_CONTINUE;
 
-       staflags = get_sta_flags(sta);
-
-       if (unlikely((staflags & (WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) &&
+       if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) ||
+                     test_sta_flag(sta, WLAN_STA_PS_DRIVER)) &&
                     !(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE))) {
                int ac = skb_get_queue_mapping(tx->skb);
 
@@ -496,7 +495,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
                return TX_QUEUED;
        }
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
-       else if (unlikely(staflags & WLAN_STA_PS_STA)) {
+       else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) {
                printk(KERN_DEBUG
                       "%s: STA %pM in PS mode, but polling/in SP -> send frame\n",
                       tx->sdata->name, sta->sta.addr);
@@ -557,7 +556,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
                 !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
                 (!ieee80211_is_robust_mgmt_frame(hdr) ||
                  (ieee80211_is_action(hdr->frame_control) &&
-                  tx->sta && test_sta_flags(tx->sta, WLAN_STA_MFP)))) {
+                  tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP)))) {
                I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
                return TX_DROP;
        } else
@@ -616,7 +615,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
        u32 len;
        bool inval = false, rts = false, short_preamble = false;
        struct ieee80211_tx_rate_control txrc;
-       u32 sta_flags;
+       bool assoc = false;
 
        memset(&txrc, 0, sizeof(txrc));
 
@@ -652,17 +651,17 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
         */
        if (tx->sdata->vif.bss_conf.use_short_preamble &&
            (ieee80211_is_data(hdr->frame_control) ||
-            (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
+            (tx->sta && test_sta_flag(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
                txrc.short_preamble = short_preamble = true;
 
-       sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0;
+       if (tx->sta)
+               assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC);
 
        /*
         * Lets not bother rate control if we're associated and cannot
         * talk to the sta. This should not happen.
         */
-       if (WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) &&
-                (sta_flags & WLAN_STA_ASSOC) &&
+       if (WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) && assoc &&
                 !rate_usable_index_exists(sband, &tx->sta->sta),
                 "%s: Dropped data frame as no usable bitrate found while "
                 "scanning and associated. Target station: "
@@ -1278,7 +1277,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
 
        if (!tx->sta)
                info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
-       else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT))
+       else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT))
                info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
 
        hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -1728,7 +1727,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
        int encaps_len, skip_header_bytes;
        int nh_pos, h_pos;
        struct sta_info *sta = NULL;
-       u32 sta_flags = 0;
+       bool wme_sta = false, authorized = false, tdls_auth = false;
        struct sk_buff *tmp_skb;
        bool tdls_direct = false;
 
@@ -1754,7 +1753,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                        memcpy(hdr.addr3, skb->data, ETH_ALEN);
                        memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
                        hdrlen = 30;
-                       sta_flags = get_sta_flags(sta);
+                       authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
+                       wme_sta = test_sta_flag(sta, WLAN_STA_WME);
                }
                rcu_read_unlock();
                if (sta)
@@ -1843,10 +1843,19 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 #endif
        case NL80211_IFTYPE_STATION:
                if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
+                       bool tdls_peer = false;
+
                        rcu_read_lock();
                        sta = sta_info_get(sdata, skb->data);
-                       if (sta)
-                               sta_flags = get_sta_flags(sta);
+                       if (sta) {
+                               authorized = test_sta_flag(sta,
+                                                       WLAN_STA_AUTHORIZED);
+                               wme_sta = test_sta_flag(sta, WLAN_STA_WME);
+                               tdls_peer = test_sta_flag(sta,
+                                                        WLAN_STA_TDLS_PEER);
+                               tdls_auth = test_sta_flag(sta,
+                                               WLAN_STA_TDLS_PEER_AUTH);
+                       }
                        rcu_read_unlock();
 
                        /*
@@ -1854,16 +1863,14 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                         * directly. Otherwise, allow TDLS setup frames
                         * to be transmitted indirectly.
                         */
-                       tdls_direct =
-                               (sta_flags & WLAN_STA_TDLS_PEER) &&
-                               ((sta_flags & WLAN_STA_TDLS_PEER_AUTH) ||
+                       tdls_direct = tdls_peer && (tdls_auth ||
                                 !(ethertype == ETH_P_TDLS && skb->len > 14 &&
                                   skb->data[14] == WLAN_TDLS_SNAP_RFTYPE));
                }
 
                if (tdls_direct) {
                        /* link during setup - throw out frames to peer */
-                       if (!(sta_flags & WLAN_STA_TDLS_PEER_AUTH)) {
+                       if (!tdls_auth) {
                                ret = NETDEV_TX_OK;
                                goto fail;
                        }
@@ -1912,17 +1919,19 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
        if (!is_multicast_ether_addr(hdr.addr1)) {
                rcu_read_lock();
                sta = sta_info_get(sdata, hdr.addr1);
-               if (sta)
-                       sta_flags = get_sta_flags(sta);
+               if (sta) {
+                       authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
+                       wme_sta = test_sta_flag(sta, WLAN_STA_WME);
+               }
                rcu_read_unlock();
        }
 
        /* For mesh, the use of the QoS header is mandatory */
        if (ieee80211_vif_is_mesh(&sdata->vif))
-               sta_flags |= WLAN_STA_WME;
+               wme_sta = true;
 
        /* receiver and we are QoS enabled, use a QoS type frame */
-       if ((sta_flags & WLAN_STA_WME) && local->hw.queues >= 4) {
+       if (wme_sta && local->hw.queues >= 4) {
                fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
                hdrlen += 2;
        }
@@ -1932,8 +1941,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
         * EAPOL frames from the local station.
         */
        if (!ieee80211_vif_is_mesh(&sdata->vif) &&
-               unlikely(!is_multicast_ether_addr(hdr.addr1) &&
-                     !(sta_flags & WLAN_STA_AUTHORIZED) &&
+               unlikely(!is_multicast_ether_addr(hdr.addr1) && !authorized &&
                      !(cpu_to_be16(ethertype) == sdata->control_port_protocol &&
                       compare_ether_addr(sdata->vif.addr,
                                          skb->data + ETH_ALEN) == 0))) {