diff options
-rw-r--r-- | drivers/net/wireless/b43/xmit.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/xmit.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 13 | ||||
-rw-r--r-- | include/net/mac80211.h | 12 | ||||
-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 |
9 files changed, 82 insertions, 34 deletions
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index bf6f6c1ed4c..8d54502222a 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -317,7 +317,8 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
317 | /* MAC control */ | 317 | /* MAC control */ |
318 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | 318 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) |
319 | mac_ctl |= B43_TXH_MAC_ACK; | 319 | mac_ctl |= B43_TXH_MAC_ACK; |
320 | if (!ieee80211_is_pspoll(fctl)) | 320 | /* use hardware sequence counter as the non-TID counter */ |
321 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) | ||
321 | mac_ctl |= B43_TXH_MAC_HWSEQ; | 322 | mac_ctl |= B43_TXH_MAC_HWSEQ; |
322 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | 323 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) |
323 | mac_ctl |= B43_TXH_MAC_STMSDU; | 324 | mac_ctl |= B43_TXH_MAC_STMSDU; |
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index a3540787eb5..e969ed8d412 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
@@ -295,8 +295,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
295 | /* MAC control */ | 295 | /* MAC control */ |
296 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | 296 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) |
297 | mac_ctl |= B43legacy_TX4_MAC_ACK; | 297 | mac_ctl |= B43legacy_TX4_MAC_ACK; |
298 | if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && | 298 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) |
299 | ((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL))) | ||
300 | mac_ctl |= B43legacy_TX4_MAC_HWSEQ; | 299 | mac_ctl |= B43legacy_TX4_MAC_HWSEQ; |
301 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | 300 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) |
302 | mac_ctl |= B43legacy_TX4_MAC_STMSDU; | 301 | mac_ctl |= B43legacy_TX4_MAC_STMSDU; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index f0d7e083d8f..9fab0df18c3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -364,6 +364,8 @@ struct rt2x00_intf { | |||
364 | #define DELAYED_UPDATE_BEACON 0x00000001 | 364 | #define DELAYED_UPDATE_BEACON 0x00000001 |
365 | #define DELAYED_CONFIG_ERP 0x00000002 | 365 | #define DELAYED_CONFIG_ERP 0x00000002 |
366 | #define DELAYED_LED_ASSOC 0x00000004 | 366 | #define DELAYED_LED_ASSOC 0x00000004 |
367 | |||
368 | u16 seqno; | ||
367 | }; | 369 | }; |
368 | 370 | ||
369 | static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) | 371 | static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 16b72d9ca1c..77af1df5d89 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -96,6 +96,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
96 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 96 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
97 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; | 97 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; |
98 | enum data_queue_qid qid = skb_get_queue_mapping(skb); | 98 | enum data_queue_qid qid = skb_get_queue_mapping(skb); |
99 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
99 | struct data_queue *queue; | 100 | struct data_queue *queue; |
100 | u16 frame_control; | 101 | u16 frame_control; |
101 | 102 | ||
@@ -151,6 +152,18 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
151 | } | 152 | } |
152 | } | 153 | } |
153 | 154 | ||
155 | /* | ||
156 | * XXX: This is as wrong as the old mac80211 code was, | ||
157 | * due to beacons not getting sequence numbers assigned | ||
158 | * properly. | ||
159 | */ | ||
160 | if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
161 | if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | ||
162 | intf->seqno += 0x10; | ||
163 | ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
164 | ieee80211hdr->seq_ctrl |= cpu_to_le16(intf->seqno); | ||
165 | } | ||
166 | |||
154 | if (rt2x00queue_write_tx_frame(queue, skb)) { | 167 | if (rt2x00queue_write_tx_frame(queue, skb)) { |
155 | ieee80211_stop_queue(rt2x00dev->hw, qid); | 168 | ieee80211_stop_queue(rt2x00dev->hw, qid); |
156 | return NETDEV_TX_BUSY; | 169 | return NETDEV_TX_BUSY; |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 47c072eab42..1dbd49fc557 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -239,6 +239,17 @@ struct ieee80211_bss_conf { | |||
239 | * is for the whole aggregation. | 239 | * is for the whole aggregation. |
240 | * @IEEE80211_TX_STAT_AMPDU_NO_BACK: no block ack was returned, | 240 | * @IEEE80211_TX_STAT_AMPDU_NO_BACK: no block ack was returned, |
241 | * so consider using block ack request (BAR). | 241 | * so consider using block ack request (BAR). |
242 | * @IEEE80211_TX_CTL_ASSIGN_SEQ: The driver has to assign a sequence | ||
243 | * number to this frame, taking care of not overwriting the fragment | ||
244 | * number and increasing the sequence number only when the | ||
245 | * IEEE80211_TX_CTL_FIRST_FRAGMENT flags is set. mac80211 will properly | ||
246 | * assign sequence numbers to QoS-data frames but cannot do so correctly | ||
247 | * for non-QoS-data and management frames because beacons need them from | ||
248 | * that counter as well and mac80211 cannot guarantee proper sequencing. | ||
249 | * If this flag is set, the driver should instruct the hardware to | ||
250 | * assign a sequence number to the frame or assign one itself. Cf. IEEE | ||
251 | * 802.11-2007 7.1.3.4.1 paragraph 3. This flag will always be set for | ||
252 | * beacons always be clear for frames without a sequence number field. | ||
242 | */ | 253 | */ |
243 | enum mac80211_tx_control_flags { | 254 | enum mac80211_tx_control_flags { |
244 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), | 255 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), |
@@ -265,6 +276,7 @@ enum mac80211_tx_control_flags { | |||
265 | IEEE80211_TX_STAT_ACK = BIT(21), | 276 | IEEE80211_TX_STAT_ACK = BIT(21), |
266 | IEEE80211_TX_STAT_AMPDU = BIT(22), | 277 | IEEE80211_TX_STAT_AMPDU = BIT(22), |
267 | IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(23), | 278 | IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(23), |
279 | IEEE80211_TX_CTL_ASSIGN_SEQ = BIT(24), | ||
268 | }; | 280 | }; |
269 | 281 | ||
270 | 282 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 934c3ef4f0b..cbea0154ee3 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 2e3adcb3ce2..610ed1d9893 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 94311dcfe04..109db787ccb 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 8843416e146..0fbadd8b983 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(); |