diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-09-29 10:04:36 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-30 15:57:19 -0400 |
commit | c2c98fdeb5c897499644eb247285c8e3dacc6450 (patch) | |
tree | aaa9c0f8dd16ab896308470e21a0813041094670 /net/mac80211/tx.c | |
parent | deeaee197b0fa694ba6c8f02cdb57b3be7115b4f (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.c | 68 |
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))) { |