diff options
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 126 |
1 files changed, 79 insertions, 47 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 9bd9faac3c3c..0fbadd8b983c 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -38,16 +38,6 @@ | |||
38 | 38 | ||
39 | /* misc utils */ | 39 | /* misc utils */ |
40 | 40 | ||
41 | static inline void ieee80211_include_sequence(struct ieee80211_sub_if_data *sdata, | ||
42 | struct ieee80211_hdr *hdr) | ||
43 | { | ||
44 | /* Set the sequence number for this frame. */ | ||
45 | hdr->seq_ctrl = cpu_to_le16(sdata->sequence); | ||
46 | |||
47 | /* Increase the sequence number. */ | ||
48 | sdata->sequence = (sdata->sequence + 0x10) & IEEE80211_SCTL_SEQ; | ||
49 | } | ||
50 | |||
51 | #ifdef CONFIG_MAC80211_LOWTX_FRAME_DUMP | 41 | #ifdef CONFIG_MAC80211_LOWTX_FRAME_DUMP |
52 | static void ieee80211_dump_frame(const char *ifname, const char *title, | 42 | static void ieee80211_dump_frame(const char *ifname, const char *title, |
53 | const struct sk_buff *skb) | 43 | const struct sk_buff *skb) |
@@ -274,17 +264,6 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
274 | return TX_CONTINUE; | 264 | return TX_CONTINUE; |
275 | } | 265 | } |
276 | 266 | ||
277 | static ieee80211_tx_result debug_noinline | ||
278 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | ||
279 | { | ||
280 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | ||
281 | |||
282 | if (ieee80211_hdrlen(hdr->frame_control) >= 24) | ||
283 | ieee80211_include_sequence(tx->sdata, hdr); | ||
284 | |||
285 | return TX_CONTINUE; | ||
286 | } | ||
287 | |||
288 | /* This function is called whenever the AP is about to exceed the maximum limit | 267 | /* This function is called whenever the AP is about to exceed the maximum limit |
289 | * of buffered frames for power saving STAs. This situation should not really | 268 | * of buffered frames for power saving STAs. This situation should not really |
290 | * happen often during normal operation, so dropping the oldest buffered packet | 269 | * happen often during normal operation, so dropping the oldest buffered packet |
@@ -303,8 +282,7 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
303 | 282 | ||
304 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 283 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
305 | struct ieee80211_if_ap *ap; | 284 | struct ieee80211_if_ap *ap; |
306 | if (sdata->dev == local->mdev || | 285 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP) |
307 | sdata->vif.type != IEEE80211_IF_TYPE_AP) | ||
308 | continue; | 286 | continue; |
309 | ap = &sdata->u.ap; | 287 | ap = &sdata->u.ap; |
310 | skb = skb_dequeue(&ap->ps_bc_buf); | 288 | skb = skb_dequeue(&ap->ps_bc_buf); |
@@ -346,8 +324,12 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
346 | * This is done either by the hardware or us. | 324 | * This is done either by the hardware or us. |
347 | */ | 325 | */ |
348 | 326 | ||
349 | /* not AP/IBSS or ordered frame */ | 327 | /* powersaving STAs only in AP/VLAN mode */ |
350 | if (!tx->sdata->bss || (tx->fc & IEEE80211_FCTL_ORDER)) | 328 | if (!tx->sdata->bss) |
329 | return TX_CONTINUE; | ||
330 | |||
331 | /* no buffering for ordered frames */ | ||
332 | if (tx->fc & IEEE80211_FCTL_ORDER) | ||
351 | return TX_CONTINUE; | 333 | return TX_CONTINUE; |
352 | 334 | ||
353 | /* no stations in PS mode */ | 335 | /* no stations in PS mode */ |
@@ -639,6 +621,49 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | |||
639 | } | 621 | } |
640 | 622 | ||
641 | static ieee80211_tx_result debug_noinline | 623 | static ieee80211_tx_result debug_noinline |
624 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | ||
625 | { | ||
626 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
627 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | ||
628 | u16 *seq; | ||
629 | u8 *qc; | ||
630 | int tid; | ||
631 | |||
632 | /* only for injected frames */ | ||
633 | if (unlikely(ieee80211_is_ctl(hdr->frame_control))) | ||
634 | return TX_CONTINUE; | ||
635 | |||
636 | if (ieee80211_hdrlen(hdr->frame_control) < 24) | ||
637 | return TX_CONTINUE; | ||
638 | |||
639 | if (!ieee80211_is_data_qos(hdr->frame_control)) { | ||
640 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | ||
641 | return TX_CONTINUE; | ||
642 | } | ||
643 | |||
644 | /* | ||
645 | * This should be true for injected/management frames only, for | ||
646 | * management frames we have set the IEEE80211_TX_CTL_ASSIGN_SEQ | ||
647 | * above since they are not QoS-data frames. | ||
648 | */ | ||
649 | if (!tx->sta) | ||
650 | return TX_CONTINUE; | ||
651 | |||
652 | /* include per-STA, per-TID sequence counter */ | ||
653 | |||
654 | qc = ieee80211_get_qos_ctl(hdr); | ||
655 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; | ||
656 | seq = &tx->sta->tid_seq[tid]; | ||
657 | |||
658 | hdr->seq_ctrl = cpu_to_le16(*seq); | ||
659 | |||
660 | /* Increase the sequence number. */ | ||
661 | *seq = (*seq + 0x10) & IEEE80211_SCTL_SEQ; | ||
662 | |||
663 | return TX_CONTINUE; | ||
664 | } | ||
665 | |||
666 | static ieee80211_tx_result debug_noinline | ||
642 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | 667 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) |
643 | { | 668 | { |
644 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 669 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
@@ -1107,12 +1132,12 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1107 | goto txh_done; | 1132 | goto txh_done; |
1108 | 1133 | ||
1109 | CALL_TXH(ieee80211_tx_h_check_assoc) | 1134 | CALL_TXH(ieee80211_tx_h_check_assoc) |
1110 | CALL_TXH(ieee80211_tx_h_sequence) | ||
1111 | CALL_TXH(ieee80211_tx_h_ps_buf) | 1135 | CALL_TXH(ieee80211_tx_h_ps_buf) |
1112 | CALL_TXH(ieee80211_tx_h_select_key) | 1136 | CALL_TXH(ieee80211_tx_h_select_key) |
1113 | CALL_TXH(ieee80211_tx_h_michael_mic_add) | 1137 | CALL_TXH(ieee80211_tx_h_michael_mic_add) |
1114 | CALL_TXH(ieee80211_tx_h_rate_ctrl) | 1138 | CALL_TXH(ieee80211_tx_h_rate_ctrl) |
1115 | CALL_TXH(ieee80211_tx_h_misc) | 1139 | CALL_TXH(ieee80211_tx_h_misc) |
1140 | CALL_TXH(ieee80211_tx_h_sequence) | ||
1116 | CALL_TXH(ieee80211_tx_h_fragment) | 1141 | CALL_TXH(ieee80211_tx_h_fragment) |
1117 | /* handlers after fragment must be aware of tx info fragmentation! */ | 1142 | /* handlers after fragment must be aware of tx info fragmentation! */ |
1118 | CALL_TXH(ieee80211_tx_h_encrypt) | 1143 | CALL_TXH(ieee80211_tx_h_encrypt) |
@@ -1785,17 +1810,17 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1785 | struct ieee80211_vif *vif) | 1810 | struct ieee80211_vif *vif) |
1786 | { | 1811 | { |
1787 | struct ieee80211_local *local = hw_to_local(hw); | 1812 | struct ieee80211_local *local = hw_to_local(hw); |
1788 | struct sk_buff *skb; | 1813 | struct sk_buff *skb = NULL; |
1789 | struct ieee80211_tx_info *info; | 1814 | struct ieee80211_tx_info *info; |
1790 | struct net_device *bdev; | 1815 | struct net_device *bdev; |
1791 | struct ieee80211_sub_if_data *sdata = NULL; | 1816 | struct ieee80211_sub_if_data *sdata = NULL; |
1792 | struct ieee80211_if_ap *ap = NULL; | 1817 | struct ieee80211_if_ap *ap = NULL; |
1818 | struct ieee80211_if_sta *ifsta = NULL; | ||
1793 | struct rate_selection rsel; | 1819 | struct rate_selection rsel; |
1794 | struct beacon_data *beacon; | 1820 | struct beacon_data *beacon; |
1795 | struct ieee80211_supported_band *sband; | 1821 | struct ieee80211_supported_band *sband; |
1796 | struct ieee80211_mgmt *mgmt; | 1822 | struct ieee80211_mgmt *mgmt; |
1797 | int *num_beacons; | 1823 | int *num_beacons; |
1798 | bool err = true; | ||
1799 | enum ieee80211_band band = local->hw.conf.channel->band; | 1824 | enum ieee80211_band band = local->hw.conf.channel->band; |
1800 | u8 *pos; | 1825 | u8 *pos; |
1801 | 1826 | ||
@@ -1824,9 +1849,6 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1824 | memcpy(skb_put(skb, beacon->head_len), beacon->head, | 1849 | memcpy(skb_put(skb, beacon->head_len), beacon->head, |
1825 | beacon->head_len); | 1850 | beacon->head_len); |
1826 | 1851 | ||
1827 | ieee80211_include_sequence(sdata, | ||
1828 | (struct ieee80211_hdr *)skb->data); | ||
1829 | |||
1830 | /* | 1852 | /* |
1831 | * Not very nice, but we want to allow the driver to call | 1853 | * Not very nice, but we want to allow the driver to call |
1832 | * ieee80211_beacon_get() as a response to the set_tim() | 1854 | * ieee80211_beacon_get() as a response to the set_tim() |
@@ -1849,9 +1871,24 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1849 | beacon->tail, beacon->tail_len); | 1871 | beacon->tail, beacon->tail_len); |
1850 | 1872 | ||
1851 | num_beacons = &ap->num_beacons; | 1873 | num_beacons = &ap->num_beacons; |
1874 | } else | ||
1875 | goto out; | ||
1876 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | ||
1877 | struct ieee80211_hdr *hdr; | ||
1878 | ifsta = &sdata->u.sta; | ||
1852 | 1879 | ||
1853 | err = false; | 1880 | if (!ifsta->probe_resp) |
1854 | } | 1881 | goto out; |
1882 | |||
1883 | skb = skb_copy(ifsta->probe_resp, GFP_ATOMIC); | ||
1884 | if (!skb) | ||
1885 | goto out; | ||
1886 | |||
1887 | hdr = (struct ieee80211_hdr *) skb->data; | ||
1888 | hdr->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
1889 | IEEE80211_STYPE_BEACON); | ||
1890 | |||
1891 | num_beacons = &ifsta->num_beacons; | ||
1855 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | 1892 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
1856 | /* headroom, head length, tail length and maximum TIM length */ | 1893 | /* headroom, head length, tail length and maximum TIM length */ |
1857 | skb = dev_alloc_skb(local->tx_headroom + 400); | 1894 | skb = dev_alloc_skb(local->tx_headroom + 400); |
@@ -1878,17 +1915,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1878 | mesh_mgmt_ies_add(skb, sdata->dev); | 1915 | mesh_mgmt_ies_add(skb, sdata->dev); |
1879 | 1916 | ||
1880 | num_beacons = &sdata->u.sta.num_beacons; | 1917 | num_beacons = &sdata->u.sta.num_beacons; |
1881 | 1918 | } else { | |
1882 | err = false; | 1919 | WARN_ON(1); |
1883 | } | ||
1884 | |||
1885 | if (err) { | ||
1886 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
1887 | if (net_ratelimit()) | ||
1888 | printk(KERN_DEBUG "no beacon data avail for %s\n", | ||
1889 | bdev->name); | ||
1890 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | ||
1891 | skb = NULL; | ||
1892 | goto out; | 1920 | goto out; |
1893 | } | 1921 | } |
1894 | 1922 | ||
@@ -1910,14 +1938,18 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1910 | 1938 | ||
1911 | info->control.vif = vif; | 1939 | info->control.vif = vif; |
1912 | info->tx_rate_idx = rsel.rate_idx; | 1940 | info->tx_rate_idx = rsel.rate_idx; |
1941 | |||
1942 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
1943 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | ||
1944 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | ||
1945 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | ||
1913 | if (sdata->bss_conf.use_short_preamble && | 1946 | if (sdata->bss_conf.use_short_preamble && |
1914 | sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) | 1947 | sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) |
1915 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; | 1948 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; |
1949 | |||
1916 | info->antenna_sel_tx = local->hw.conf.antenna_sel_tx; | 1950 | info->antenna_sel_tx = local->hw.conf.antenna_sel_tx; |
1917 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
1918 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | ||
1919 | info->control.retry_limit = 1; | 1951 | info->control.retry_limit = 1; |
1920 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | 1952 | |
1921 | (*num_beacons)++; | 1953 | (*num_beacons)++; |
1922 | out: | 1954 | out: |
1923 | rcu_read_unlock(); | 1955 | rcu_read_unlock(); |