diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/iface.c | 1 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 1 | ||||
-rw-r--r-- | net/mac80211/tx.c | 79 |
4 files changed, 52 insertions, 31 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 934c3ef4f0bc..cbea0154ee3a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -419,8 +419,6 @@ struct ieee80211_sub_if_data { | |||
419 | */ | 419 | */ |
420 | u64 basic_rates; | 420 | u64 basic_rates; |
421 | 421 | ||
422 | u16 sequence; | ||
423 | |||
424 | /* Fragment table for host-based reassembly */ | 422 | /* Fragment table for host-based reassembly */ |
425 | struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; | 423 | struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; |
426 | unsigned int fragment_next; | 424 | unsigned int fragment_next; |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 2e3adcb3ce23..610ed1d9893a 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -162,7 +162,6 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
162 | /* reset some values that shouldn't be kept across type changes */ | 162 | /* reset some values that shouldn't be kept across type changes */ |
163 | sdata->basic_rates = 0; | 163 | sdata->basic_rates = 0; |
164 | sdata->drop_unencrypted = 0; | 164 | sdata->drop_unencrypted = 0; |
165 | sdata->sequence = 0; | ||
166 | 165 | ||
167 | return 0; | 166 | return 0; |
168 | } | 167 | } |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 94311dcfe043..109db787ccb7 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -285,6 +285,7 @@ struct sta_info { | |||
285 | unsigned long tx_fragments; | 285 | unsigned long tx_fragments; |
286 | int txrate_idx; | 286 | int txrate_idx; |
287 | int last_txrate_idx; | 287 | int last_txrate_idx; |
288 | u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; | ||
288 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | 289 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS |
289 | unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES]; | 290 | unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES]; |
290 | #endif | 291 | #endif |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 8843416e1460..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 |
@@ -642,6 +621,49 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | |||
642 | } | 621 | } |
643 | 622 | ||
644 | 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 | ||
645 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | 667 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) |
646 | { | 668 | { |
647 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 669 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
@@ -1110,12 +1132,12 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1110 | goto txh_done; | 1132 | goto txh_done; |
1111 | 1133 | ||
1112 | CALL_TXH(ieee80211_tx_h_check_assoc) | 1134 | CALL_TXH(ieee80211_tx_h_check_assoc) |
1113 | CALL_TXH(ieee80211_tx_h_sequence) | ||
1114 | CALL_TXH(ieee80211_tx_h_ps_buf) | 1135 | CALL_TXH(ieee80211_tx_h_ps_buf) |
1115 | CALL_TXH(ieee80211_tx_h_select_key) | 1136 | CALL_TXH(ieee80211_tx_h_select_key) |
1116 | CALL_TXH(ieee80211_tx_h_michael_mic_add) | 1137 | CALL_TXH(ieee80211_tx_h_michael_mic_add) |
1117 | CALL_TXH(ieee80211_tx_h_rate_ctrl) | 1138 | CALL_TXH(ieee80211_tx_h_rate_ctrl) |
1118 | CALL_TXH(ieee80211_tx_h_misc) | 1139 | CALL_TXH(ieee80211_tx_h_misc) |
1140 | CALL_TXH(ieee80211_tx_h_sequence) | ||
1119 | CALL_TXH(ieee80211_tx_h_fragment) | 1141 | CALL_TXH(ieee80211_tx_h_fragment) |
1120 | /* handlers after fragment must be aware of tx info fragmentation! */ | 1142 | /* handlers after fragment must be aware of tx info fragmentation! */ |
1121 | CALL_TXH(ieee80211_tx_h_encrypt) | 1143 | CALL_TXH(ieee80211_tx_h_encrypt) |
@@ -1827,9 +1849,6 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1827 | memcpy(skb_put(skb, beacon->head_len), beacon->head, | 1849 | memcpy(skb_put(skb, beacon->head_len), beacon->head, |
1828 | beacon->head_len); | 1850 | beacon->head_len); |
1829 | 1851 | ||
1830 | ieee80211_include_sequence(sdata, | ||
1831 | (struct ieee80211_hdr *)skb->data); | ||
1832 | |||
1833 | /* | 1852 | /* |
1834 | * 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 |
1835 | * ieee80211_beacon_get() as a response to the set_tim() | 1854 | * ieee80211_beacon_get() as a response to the set_tim() |
@@ -1919,14 +1938,18 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1919 | 1938 | ||
1920 | info->control.vif = vif; | 1939 | info->control.vif = vif; |
1921 | 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; | ||
1922 | if (sdata->bss_conf.use_short_preamble && | 1946 | if (sdata->bss_conf.use_short_preamble && |
1923 | sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) | 1947 | sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) |
1924 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; | 1948 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; |
1949 | |||
1925 | info->antenna_sel_tx = local->hw.conf.antenna_sel_tx; | 1950 | info->antenna_sel_tx = local->hw.conf.antenna_sel_tx; |
1926 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
1927 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | ||
1928 | info->control.retry_limit = 1; | 1951 | info->control.retry_limit = 1; |
1929 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | 1952 | |
1930 | (*num_beacons)++; | 1953 | (*num_beacons)++; |
1931 | out: | 1954 | out: |
1932 | rcu_read_unlock(); | 1955 | rcu_read_unlock(); |