aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-09-29 10:04:36 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-09-30 15:57:19 -0400
commitc2c98fdeb5c897499644eb247285c8e3dacc6450 (patch)
treeaaa9c0f8dd16ab896308470e21a0813041094670 /net/mac80211/tx.c
parentdeeaee197b0fa694ba6c8f02cdb57b3be7115b4f (diff)
mac80211: optimise station flags
The flaglock in struct sta_info has long been something that I wanted to get rid of, this finally does the conversion to atomic bitops. The conversion itself is straight-forward in most places, a few things needed to change a bit since we can no longer use multiple bits at the same time. On x86-64, this is a fairly significant code size reduction: text data bss dec hex 427861 23648 1008 452517 6e7a5 before 425383 23648 976 450007 6ddd7 after Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c68
1 files changed, 38 insertions, 30 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 5bf91c43c88c..7699e666457f 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -253,7 +253,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
253 253
254 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 254 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
255 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 255 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
256 u32 sta_flags; 256 bool assoc = false;
257 257
258 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) 258 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
259 return TX_CONTINUE; 259 return TX_CONTINUE;
@@ -284,10 +284,11 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
284 if (tx->flags & IEEE80211_TX_PS_BUFFERED) 284 if (tx->flags & IEEE80211_TX_PS_BUFFERED)
285 return TX_CONTINUE; 285 return TX_CONTINUE;
286 286
287 sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0; 287 if (tx->sta)
288 assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC);
288 289
289 if (likely(tx->flags & IEEE80211_TX_UNICAST)) { 290 if (likely(tx->flags & IEEE80211_TX_UNICAST)) {
290 if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && 291 if (unlikely(!assoc &&
291 tx->sdata->vif.type != NL80211_IFTYPE_ADHOC && 292 tx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
292 ieee80211_is_data(hdr->frame_control))) { 293 ieee80211_is_data(hdr->frame_control))) {
293#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 294#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -427,7 +428,7 @@ static int ieee80211_use_mfp(__le16 fc, struct sta_info *sta,
427 if (!ieee80211_is_mgmt(fc)) 428 if (!ieee80211_is_mgmt(fc))
428 return 0; 429 return 0;
429 430
430 if (sta == NULL || !test_sta_flags(sta, WLAN_STA_MFP)) 431 if (sta == NULL || !test_sta_flag(sta, WLAN_STA_MFP))
431 return 0; 432 return 0;
432 433
433 if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) 434 if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *)
@@ -444,7 +445,6 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
444 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 445 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
445 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 446 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
446 struct ieee80211_local *local = tx->local; 447 struct ieee80211_local *local = tx->local;
447 u32 staflags;
448 448
449 if (unlikely(!sta || 449 if (unlikely(!sta ||
450 ieee80211_is_probe_resp(hdr->frame_control) || 450 ieee80211_is_probe_resp(hdr->frame_control) ||
@@ -453,9 +453,8 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
453 ieee80211_is_reassoc_resp(hdr->frame_control))) 453 ieee80211_is_reassoc_resp(hdr->frame_control)))
454 return TX_CONTINUE; 454 return TX_CONTINUE;
455 455
456 staflags = get_sta_flags(sta); 456 if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) ||
457 457 test_sta_flag(sta, WLAN_STA_PS_DRIVER)) &&
458 if (unlikely((staflags & (WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) &&
459 !(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE))) { 458 !(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE))) {
460 int ac = skb_get_queue_mapping(tx->skb); 459 int ac = skb_get_queue_mapping(tx->skb);
461 460
@@ -496,7 +495,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
496 return TX_QUEUED; 495 return TX_QUEUED;
497 } 496 }
498#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 497#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
499 else if (unlikely(staflags & WLAN_STA_PS_STA)) { 498 else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) {
500 printk(KERN_DEBUG 499 printk(KERN_DEBUG
501 "%s: STA %pM in PS mode, but polling/in SP -> send frame\n", 500 "%s: STA %pM in PS mode, but polling/in SP -> send frame\n",
502 tx->sdata->name, sta->sta.addr); 501 tx->sdata->name, sta->sta.addr);
@@ -557,7 +556,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
557 !(info->flags & IEEE80211_TX_CTL_INJECTED) && 556 !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
558 (!ieee80211_is_robust_mgmt_frame(hdr) || 557 (!ieee80211_is_robust_mgmt_frame(hdr) ||
559 (ieee80211_is_action(hdr->frame_control) && 558 (ieee80211_is_action(hdr->frame_control) &&
560 tx->sta && test_sta_flags(tx->sta, WLAN_STA_MFP)))) { 559 tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP)))) {
561 I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); 560 I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
562 return TX_DROP; 561 return TX_DROP;
563 } else 562 } else
@@ -616,7 +615,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
616 u32 len; 615 u32 len;
617 bool inval = false, rts = false, short_preamble = false; 616 bool inval = false, rts = false, short_preamble = false;
618 struct ieee80211_tx_rate_control txrc; 617 struct ieee80211_tx_rate_control txrc;
619 u32 sta_flags; 618 bool assoc = false;
620 619
621 memset(&txrc, 0, sizeof(txrc)); 620 memset(&txrc, 0, sizeof(txrc));
622 621
@@ -652,17 +651,17 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
652 */ 651 */
653 if (tx->sdata->vif.bss_conf.use_short_preamble && 652 if (tx->sdata->vif.bss_conf.use_short_preamble &&
654 (ieee80211_is_data(hdr->frame_control) || 653 (ieee80211_is_data(hdr->frame_control) ||
655 (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) 654 (tx->sta && test_sta_flag(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
656 txrc.short_preamble = short_preamble = true; 655 txrc.short_preamble = short_preamble = true;
657 656
658 sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0; 657 if (tx->sta)
658 assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC);
659 659
660 /* 660 /*
661 * Lets not bother rate control if we're associated and cannot 661 * Lets not bother rate control if we're associated and cannot
662 * talk to the sta. This should not happen. 662 * talk to the sta. This should not happen.
663 */ 663 */
664 if (WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) && 664 if (WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) && assoc &&
665 (sta_flags & WLAN_STA_ASSOC) &&
666 !rate_usable_index_exists(sband, &tx->sta->sta), 665 !rate_usable_index_exists(sband, &tx->sta->sta),
667 "%s: Dropped data frame as no usable bitrate found while " 666 "%s: Dropped data frame as no usable bitrate found while "
668 "scanning and associated. Target station: " 667 "scanning and associated. Target station: "
@@ -1278,7 +1277,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1278 1277
1279 if (!tx->sta) 1278 if (!tx->sta)
1280 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; 1279 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
1281 else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT)) 1280 else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT))
1282 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; 1281 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
1283 1282
1284 hdrlen = ieee80211_hdrlen(hdr->frame_control); 1283 hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -1728,7 +1727,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1728 int encaps_len, skip_header_bytes; 1727 int encaps_len, skip_header_bytes;
1729 int nh_pos, h_pos; 1728 int nh_pos, h_pos;
1730 struct sta_info *sta = NULL; 1729 struct sta_info *sta = NULL;
1731 u32 sta_flags = 0; 1730 bool wme_sta = false, authorized = false, tdls_auth = false;
1732 struct sk_buff *tmp_skb; 1731 struct sk_buff *tmp_skb;
1733 bool tdls_direct = false; 1732 bool tdls_direct = false;
1734 1733
@@ -1754,7 +1753,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1754 memcpy(hdr.addr3, skb->data, ETH_ALEN); 1753 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1755 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); 1754 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1756 hdrlen = 30; 1755 hdrlen = 30;
1757 sta_flags = get_sta_flags(sta); 1756 authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
1757 wme_sta = test_sta_flag(sta, WLAN_STA_WME);
1758 } 1758 }
1759 rcu_read_unlock(); 1759 rcu_read_unlock();
1760 if (sta) 1760 if (sta)
@@ -1843,10 +1843,19 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1843#endif 1843#endif
1844 case NL80211_IFTYPE_STATION: 1844 case NL80211_IFTYPE_STATION:
1845 if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) { 1845 if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
1846 bool tdls_peer = false;
1847
1846 rcu_read_lock(); 1848 rcu_read_lock();
1847 sta = sta_info_get(sdata, skb->data); 1849 sta = sta_info_get(sdata, skb->data);
1848 if (sta) 1850 if (sta) {
1849 sta_flags = get_sta_flags(sta); 1851 authorized = test_sta_flag(sta,
1852 WLAN_STA_AUTHORIZED);
1853 wme_sta = test_sta_flag(sta, WLAN_STA_WME);
1854 tdls_peer = test_sta_flag(sta,
1855 WLAN_STA_TDLS_PEER);
1856 tdls_auth = test_sta_flag(sta,
1857 WLAN_STA_TDLS_PEER_AUTH);
1858 }
1850 rcu_read_unlock(); 1859 rcu_read_unlock();
1851 1860
1852 /* 1861 /*
@@ -1854,16 +1863,14 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1854 * directly. Otherwise, allow TDLS setup frames 1863 * directly. Otherwise, allow TDLS setup frames
1855 * to be transmitted indirectly. 1864 * to be transmitted indirectly.
1856 */ 1865 */
1857 tdls_direct = 1866 tdls_direct = tdls_peer && (tdls_auth ||
1858 (sta_flags & WLAN_STA_TDLS_PEER) &&
1859 ((sta_flags & WLAN_STA_TDLS_PEER_AUTH) ||
1860 !(ethertype == ETH_P_TDLS && skb->len > 14 && 1867 !(ethertype == ETH_P_TDLS && skb->len > 14 &&
1861 skb->data[14] == WLAN_TDLS_SNAP_RFTYPE)); 1868 skb->data[14] == WLAN_TDLS_SNAP_RFTYPE));
1862 } 1869 }
1863 1870
1864 if (tdls_direct) { 1871 if (tdls_direct) {
1865 /* link during setup - throw out frames to peer */ 1872 /* link during setup - throw out frames to peer */
1866 if (!(sta_flags & WLAN_STA_TDLS_PEER_AUTH)) { 1873 if (!tdls_auth) {
1867 ret = NETDEV_TX_OK; 1874 ret = NETDEV_TX_OK;
1868 goto fail; 1875 goto fail;
1869 } 1876 }
@@ -1912,17 +1919,19 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1912 if (!is_multicast_ether_addr(hdr.addr1)) { 1919 if (!is_multicast_ether_addr(hdr.addr1)) {
1913 rcu_read_lock(); 1920 rcu_read_lock();
1914 sta = sta_info_get(sdata, hdr.addr1); 1921 sta = sta_info_get(sdata, hdr.addr1);
1915 if (sta) 1922 if (sta) {
1916 sta_flags = get_sta_flags(sta); 1923 authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
1924 wme_sta = test_sta_flag(sta, WLAN_STA_WME);
1925 }
1917 rcu_read_unlock(); 1926 rcu_read_unlock();
1918 } 1927 }
1919 1928
1920 /* For mesh, the use of the QoS header is mandatory */ 1929 /* For mesh, the use of the QoS header is mandatory */
1921 if (ieee80211_vif_is_mesh(&sdata->vif)) 1930 if (ieee80211_vif_is_mesh(&sdata->vif))
1922 sta_flags |= WLAN_STA_WME; 1931 wme_sta = true;
1923 1932
1924 /* receiver and we are QoS enabled, use a QoS type frame */ 1933 /* receiver and we are QoS enabled, use a QoS type frame */
1925 if ((sta_flags & WLAN_STA_WME) && local->hw.queues >= 4) { 1934 if (wme_sta && local->hw.queues >= 4) {
1926 fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); 1935 fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
1927 hdrlen += 2; 1936 hdrlen += 2;
1928 } 1937 }
@@ -1932,8 +1941,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1932 * EAPOL frames from the local station. 1941 * EAPOL frames from the local station.
1933 */ 1942 */
1934 if (!ieee80211_vif_is_mesh(&sdata->vif) && 1943 if (!ieee80211_vif_is_mesh(&sdata->vif) &&
1935 unlikely(!is_multicast_ether_addr(hdr.addr1) && 1944 unlikely(!is_multicast_ether_addr(hdr.addr1) && !authorized &&
1936 !(sta_flags & WLAN_STA_AUTHORIZED) &&
1937 !(cpu_to_be16(ethertype) == sdata->control_port_protocol && 1945 !(cpu_to_be16(ethertype) == sdata->control_port_protocol &&
1938 compare_ether_addr(sdata->vif.addr, 1946 compare_ether_addr(sdata->vif.addr,
1939 skb->data + ETH_ALEN) == 0))) { 1947 skb->data + ETH_ALEN) == 0))) {