diff options
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 503 |
1 files changed, 380 insertions, 123 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index eaa4118de988..cfc473e1b050 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -180,6 +180,71 @@ static int inline is_ieee80211_device(struct ieee80211_local *local, | |||
180 | } | 180 | } |
181 | 181 | ||
182 | /* tx handlers */ | 182 | /* tx handlers */ |
183 | static ieee80211_tx_result debug_noinline | ||
184 | ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) | ||
185 | { | ||
186 | struct ieee80211_local *local = tx->local; | ||
187 | struct ieee80211_if_managed *ifmgd; | ||
188 | |||
189 | /* driver doesn't support power save */ | ||
190 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) | ||
191 | return TX_CONTINUE; | ||
192 | |||
193 | /* hardware does dynamic power save */ | ||
194 | if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) | ||
195 | return TX_CONTINUE; | ||
196 | |||
197 | /* dynamic power save disabled */ | ||
198 | if (local->hw.conf.dynamic_ps_timeout <= 0) | ||
199 | return TX_CONTINUE; | ||
200 | |||
201 | /* we are scanning, don't enable power save */ | ||
202 | if (local->scanning) | ||
203 | return TX_CONTINUE; | ||
204 | |||
205 | if (!local->ps_sdata) | ||
206 | return TX_CONTINUE; | ||
207 | |||
208 | /* No point if we're going to suspend */ | ||
209 | if (local->quiescing) | ||
210 | return TX_CONTINUE; | ||
211 | |||
212 | /* dynamic ps is supported only in managed mode */ | ||
213 | if (tx->sdata->vif.type != NL80211_IFTYPE_STATION) | ||
214 | return TX_CONTINUE; | ||
215 | |||
216 | ifmgd = &tx->sdata->u.mgd; | ||
217 | |||
218 | /* | ||
219 | * Don't wakeup from power save if u-apsd is enabled, voip ac has | ||
220 | * u-apsd enabled and the frame is in voip class. This effectively | ||
221 | * means that even if all access categories have u-apsd enabled, in | ||
222 | * practise u-apsd is only used with the voip ac. This is a | ||
223 | * workaround for the case when received voip class packets do not | ||
224 | * have correct qos tag for some reason, due the network or the | ||
225 | * peer application. | ||
226 | * | ||
227 | * Note: local->uapsd_queues access is racy here. If the value is | ||
228 | * changed via debugfs, user needs to reassociate manually to have | ||
229 | * everything in sync. | ||
230 | */ | ||
231 | if ((ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) | ||
232 | && (local->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) | ||
233 | && skb_get_queue_mapping(tx->skb) == 0) | ||
234 | return TX_CONTINUE; | ||
235 | |||
236 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | ||
237 | ieee80211_stop_queues_by_reason(&local->hw, | ||
238 | IEEE80211_QUEUE_STOP_REASON_PS); | ||
239 | ieee80211_queue_work(&local->hw, | ||
240 | &local->dynamic_ps_disable_work); | ||
241 | } | ||
242 | |||
243 | mod_timer(&local->dynamic_ps_timer, jiffies + | ||
244 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); | ||
245 | |||
246 | return TX_CONTINUE; | ||
247 | } | ||
183 | 248 | ||
184 | static ieee80211_tx_result debug_noinline | 249 | static ieee80211_tx_result debug_noinline |
185 | ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | 250 | ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) |
@@ -223,7 +288,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
223 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 288 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
224 | printk(KERN_DEBUG "%s: dropped data frame to not " | 289 | printk(KERN_DEBUG "%s: dropped data frame to not " |
225 | "associated station %pM\n", | 290 | "associated station %pM\n", |
226 | tx->dev->name, hdr->addr1); | 291 | tx->sdata->name, hdr->addr1); |
227 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 292 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
228 | I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); | 293 | I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); |
229 | return TX_DROP; | 294 | return TX_DROP; |
@@ -317,12 +382,11 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
317 | if (!atomic_read(&tx->sdata->bss->num_sta_ps)) | 382 | if (!atomic_read(&tx->sdata->bss->num_sta_ps)) |
318 | return TX_CONTINUE; | 383 | return TX_CONTINUE; |
319 | 384 | ||
320 | /* buffered in hardware */ | 385 | info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; |
321 | if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING)) { | ||
322 | info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; | ||
323 | 386 | ||
387 | /* device releases frame after DTIM beacon */ | ||
388 | if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING)) | ||
324 | return TX_CONTINUE; | 389 | return TX_CONTINUE; |
325 | } | ||
326 | 390 | ||
327 | /* buffered in mac80211 */ | 391 | /* buffered in mac80211 */ |
328 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) | 392 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) |
@@ -332,7 +396,7 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
332 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 396 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
333 | if (net_ratelimit()) | 397 | if (net_ratelimit()) |
334 | printk(KERN_DEBUG "%s: BC TX buffer full - dropping the oldest frame\n", | 398 | printk(KERN_DEBUG "%s: BC TX buffer full - dropping the oldest frame\n", |
335 | tx->dev->name); | 399 | tx->sdata->name); |
336 | #endif | 400 | #endif |
337 | dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); | 401 | dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); |
338 | } else | 402 | } else |
@@ -367,15 +431,16 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
367 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 431 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
368 | u32 staflags; | 432 | u32 staflags; |
369 | 433 | ||
370 | if (unlikely(!sta || ieee80211_is_probe_resp(hdr->frame_control) | 434 | if (unlikely(!sta || |
371 | || ieee80211_is_auth(hdr->frame_control) | 435 | ieee80211_is_probe_resp(hdr->frame_control) || |
372 | || ieee80211_is_assoc_resp(hdr->frame_control) | 436 | ieee80211_is_auth(hdr->frame_control) || |
373 | || ieee80211_is_reassoc_resp(hdr->frame_control))) | 437 | ieee80211_is_assoc_resp(hdr->frame_control) || |
438 | ieee80211_is_reassoc_resp(hdr->frame_control))) | ||
374 | return TX_CONTINUE; | 439 | return TX_CONTINUE; |
375 | 440 | ||
376 | staflags = get_sta_flags(sta); | 441 | staflags = get_sta_flags(sta); |
377 | 442 | ||
378 | if (unlikely((staflags & WLAN_STA_PS) && | 443 | if (unlikely((staflags & (WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) && |
379 | !(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE))) { | 444 | !(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE))) { |
380 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 445 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
381 | printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries " | 446 | printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries " |
@@ -391,15 +456,20 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
391 | if (net_ratelimit()) { | 456 | if (net_ratelimit()) { |
392 | printk(KERN_DEBUG "%s: STA %pM TX " | 457 | printk(KERN_DEBUG "%s: STA %pM TX " |
393 | "buffer full - dropping oldest frame\n", | 458 | "buffer full - dropping oldest frame\n", |
394 | tx->dev->name, sta->sta.addr); | 459 | tx->sdata->name, sta->sta.addr); |
395 | } | 460 | } |
396 | #endif | 461 | #endif |
397 | dev_kfree_skb(old); | 462 | dev_kfree_skb(old); |
398 | } else | 463 | } else |
399 | tx->local->total_ps_buffered++; | 464 | tx->local->total_ps_buffered++; |
400 | 465 | ||
401 | /* Queue frame to be sent after STA sends an PS Poll frame */ | 466 | /* |
402 | if (skb_queue_empty(&sta->ps_tx_buf)) | 467 | * Queue frame to be sent after STA wakes up/polls, |
468 | * but don't set the TIM bit if the driver is blocking | ||
469 | * wakeup or poll response transmissions anyway. | ||
470 | */ | ||
471 | if (skb_queue_empty(&sta->ps_tx_buf) && | ||
472 | !(staflags & WLAN_STA_PS_DRIVER)) | ||
403 | sta_info_set_tim_bit(sta); | 473 | sta_info_set_tim_bit(sta); |
404 | 474 | ||
405 | info->control.jiffies = jiffies; | 475 | info->control.jiffies = jiffies; |
@@ -409,9 +479,9 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
409 | return TX_QUEUED; | 479 | return TX_QUEUED; |
410 | } | 480 | } |
411 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 481 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
412 | else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) { | 482 | else if (unlikely(staflags & WLAN_STA_PS_STA)) { |
413 | printk(KERN_DEBUG "%s: STA %pM in PS mode, but pspoll " | 483 | printk(KERN_DEBUG "%s: STA %pM in PS mode, but pspoll " |
414 | "set -> send frame\n", tx->dev->name, | 484 | "set -> send frame\n", tx->sdata->name, |
415 | sta->sta.addr); | 485 | sta->sta.addr); |
416 | } | 486 | } |
417 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 487 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
@@ -459,6 +529,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
459 | tx->key = NULL; | 529 | tx->key = NULL; |
460 | 530 | ||
461 | if (tx->key) { | 531 | if (tx->key) { |
532 | bool skip_hw = false; | ||
533 | |||
462 | tx->key->tx_rx_count++; | 534 | tx->key->tx_rx_count++; |
463 | /* TODO: add threshold stuff again */ | 535 | /* TODO: add threshold stuff again */ |
464 | 536 | ||
@@ -475,16 +547,32 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
475 | !ieee80211_use_mfp(hdr->frame_control, tx->sta, | 547 | !ieee80211_use_mfp(hdr->frame_control, tx->sta, |
476 | tx->skb)) | 548 | tx->skb)) |
477 | tx->key = NULL; | 549 | tx->key = NULL; |
550 | else | ||
551 | skip_hw = (tx->key->conf.flags & | ||
552 | IEEE80211_KEY_FLAG_SW_MGMT) && | ||
553 | ieee80211_is_mgmt(hdr->frame_control); | ||
478 | break; | 554 | break; |
479 | case ALG_AES_CMAC: | 555 | case ALG_AES_CMAC: |
480 | if (!ieee80211_is_mgmt(hdr->frame_control)) | 556 | if (!ieee80211_is_mgmt(hdr->frame_control)) |
481 | tx->key = NULL; | 557 | tx->key = NULL; |
482 | break; | 558 | break; |
483 | } | 559 | } |
560 | |||
561 | if (!skip_hw && tx->key && | ||
562 | tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | ||
563 | info->control.hw_key = &tx->key->conf; | ||
484 | } | 564 | } |
485 | 565 | ||
486 | if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | 566 | return TX_CONTINUE; |
487 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 567 | } |
568 | |||
569 | static ieee80211_tx_result debug_noinline | ||
570 | ieee80211_tx_h_sta(struct ieee80211_tx_data *tx) | ||
571 | { | ||
572 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
573 | |||
574 | if (tx->sta && tx->sta->uploaded) | ||
575 | info->control.sta = &tx->sta->sta; | ||
488 | 576 | ||
489 | return TX_CONTINUE; | 577 | return TX_CONTINUE; |
490 | } | 578 | } |
@@ -514,7 +602,12 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
514 | txrc.bss_conf = &tx->sdata->vif.bss_conf; | 602 | txrc.bss_conf = &tx->sdata->vif.bss_conf; |
515 | txrc.skb = tx->skb; | 603 | txrc.skb = tx->skb; |
516 | txrc.reported_rate.idx = -1; | 604 | txrc.reported_rate.idx = -1; |
517 | txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx; | 605 | txrc.rate_idx_mask = tx->sdata->rc_rateidx_mask[tx->channel->band]; |
606 | if (txrc.rate_idx_mask == (1 << sband->n_bitrates) - 1) | ||
607 | txrc.max_rate_idx = -1; | ||
608 | else | ||
609 | txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; | ||
610 | txrc.ap = tx->sdata->vif.type == NL80211_IFTYPE_AP; | ||
518 | 611 | ||
519 | /* set up RTS protection if desired */ | 612 | /* set up RTS protection if desired */ |
520 | if (len > tx->local->hw.wiphy->rts_threshold) { | 613 | if (len > tx->local->hw.wiphy->rts_threshold) { |
@@ -544,7 +637,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
544 | "%s: Dropped data frame as no usable bitrate found while " | 637 | "%s: Dropped data frame as no usable bitrate found while " |
545 | "scanning and associated. Target station: " | 638 | "scanning and associated. Target station: " |
546 | "%pM on %d GHz band\n", | 639 | "%pM on %d GHz band\n", |
547 | tx->dev->name, hdr->addr1, | 640 | tx->sdata->name, hdr->addr1, |
548 | tx->channel->band ? 5 : 2)) | 641 | tx->channel->band ? 5 : 2)) |
549 | return TX_DROP; | 642 | return TX_DROP; |
550 | 643 | ||
@@ -659,17 +752,6 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
659 | } | 752 | } |
660 | 753 | ||
661 | static ieee80211_tx_result debug_noinline | 754 | static ieee80211_tx_result debug_noinline |
662 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | ||
663 | { | ||
664 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
665 | |||
666 | if (tx->sta) | ||
667 | info->control.sta = &tx->sta->sta; | ||
668 | |||
669 | return TX_CONTINUE; | ||
670 | } | ||
671 | |||
672 | static ieee80211_tx_result debug_noinline | ||
673 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | 755 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) |
674 | { | 756 | { |
675 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 757 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
@@ -928,7 +1010,8 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
928 | (struct ieee80211_radiotap_header *) skb->data; | 1010 | (struct ieee80211_radiotap_header *) skb->data; |
929 | struct ieee80211_supported_band *sband; | 1011 | struct ieee80211_supported_band *sband; |
930 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1012 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
931 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); | 1013 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len, |
1014 | NULL); | ||
932 | 1015 | ||
933 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 1016 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
934 | 1017 | ||
@@ -964,7 +1047,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
964 | * because it will be recomputed and added | 1047 | * because it will be recomputed and added |
965 | * on transmission | 1048 | * on transmission |
966 | */ | 1049 | */ |
967 | if (skb->len < (iterator.max_length + FCS_LEN)) | 1050 | if (skb->len < (iterator._max_length + FCS_LEN)) |
968 | return false; | 1051 | return false; |
969 | 1052 | ||
970 | skb_trim(skb, skb->len - FCS_LEN); | 1053 | skb_trim(skb, skb->len - FCS_LEN); |
@@ -991,10 +1074,10 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
991 | 1074 | ||
992 | /* | 1075 | /* |
993 | * remove the radiotap header | 1076 | * remove the radiotap header |
994 | * iterator->max_length was sanity-checked against | 1077 | * iterator->_max_length was sanity-checked against |
995 | * skb->len by iterator init | 1078 | * skb->len by iterator init |
996 | */ | 1079 | */ |
997 | skb_pull(skb, iterator.max_length); | 1080 | skb_pull(skb, iterator._max_length); |
998 | 1081 | ||
999 | return true; | 1082 | return true; |
1000 | } | 1083 | } |
@@ -1016,7 +1099,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1016 | 1099 | ||
1017 | memset(tx, 0, sizeof(*tx)); | 1100 | memset(tx, 0, sizeof(*tx)); |
1018 | tx->skb = skb; | 1101 | tx->skb = skb; |
1019 | tx->dev = sdata->dev; /* use original interface */ | ||
1020 | tx->local = local; | 1102 | tx->local = local; |
1021 | tx->sdata = sdata; | 1103 | tx->sdata = sdata; |
1022 | tx->channel = local->hw.conf.channel; | 1104 | tx->channel = local->hw.conf.channel; |
@@ -1027,7 +1109,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1027 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 1109 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
1028 | 1110 | ||
1029 | /* process and remove the injection radiotap header */ | 1111 | /* process and remove the injection radiotap header */ |
1030 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) { | 1112 | if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) { |
1031 | if (!__ieee80211_parse_tx_radiotap(tx, skb)) | 1113 | if (!__ieee80211_parse_tx_radiotap(tx, skb)) |
1032 | return TX_DROP; | 1114 | return TX_DROP; |
1033 | 1115 | ||
@@ -1036,6 +1118,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1036 | * the radiotap header that was present and pre-filled | 1118 | * the radiotap header that was present and pre-filled |
1037 | * 'tx' with tx control information. | 1119 | * 'tx' with tx control information. |
1038 | */ | 1120 | */ |
1121 | info->flags &= ~IEEE80211_TX_INTFL_HAS_RADIOTAP; | ||
1039 | } | 1122 | } |
1040 | 1123 | ||
1041 | /* | 1124 | /* |
@@ -1047,7 +1130,15 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1047 | 1130 | ||
1048 | hdr = (struct ieee80211_hdr *) skb->data; | 1131 | hdr = (struct ieee80211_hdr *) skb->data; |
1049 | 1132 | ||
1050 | tx->sta = sta_info_get(local, hdr->addr1); | 1133 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { |
1134 | tx->sta = rcu_dereference(sdata->u.vlan.sta); | ||
1135 | if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr) | ||
1136 | return TX_DROP; | ||
1137 | } else if (info->flags & IEEE80211_TX_CTL_INJECTED) { | ||
1138 | tx->sta = sta_info_get_bss(sdata, hdr->addr1); | ||
1139 | } | ||
1140 | if (!tx->sta) | ||
1141 | tx->sta = sta_info_get(sdata, hdr->addr1); | ||
1051 | 1142 | ||
1052 | if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && | 1143 | if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && |
1053 | (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) { | 1144 | (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) { |
@@ -1199,25 +1290,34 @@ static int __ieee80211_tx(struct ieee80211_local *local, | |||
1199 | static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | 1290 | static int invoke_tx_handlers(struct ieee80211_tx_data *tx) |
1200 | { | 1291 | { |
1201 | struct sk_buff *skb = tx->skb; | 1292 | struct sk_buff *skb = tx->skb; |
1293 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1202 | ieee80211_tx_result res = TX_DROP; | 1294 | ieee80211_tx_result res = TX_DROP; |
1203 | 1295 | ||
1204 | #define CALL_TXH(txh) \ | 1296 | #define CALL_TXH(txh) \ |
1205 | res = txh(tx); \ | 1297 | do { \ |
1206 | if (res != TX_CONTINUE) \ | 1298 | res = txh(tx); \ |
1299 | if (res != TX_CONTINUE) \ | ||
1300 | goto txh_done; \ | ||
1301 | } while (0) | ||
1302 | |||
1303 | CALL_TXH(ieee80211_tx_h_dynamic_ps); | ||
1304 | CALL_TXH(ieee80211_tx_h_check_assoc); | ||
1305 | CALL_TXH(ieee80211_tx_h_ps_buf); | ||
1306 | CALL_TXH(ieee80211_tx_h_select_key); | ||
1307 | CALL_TXH(ieee80211_tx_h_sta); | ||
1308 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) | ||
1309 | CALL_TXH(ieee80211_tx_h_rate_ctrl); | ||
1310 | |||
1311 | if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION)) | ||
1207 | goto txh_done; | 1312 | goto txh_done; |
1208 | 1313 | ||
1209 | CALL_TXH(ieee80211_tx_h_check_assoc) | 1314 | CALL_TXH(ieee80211_tx_h_michael_mic_add); |
1210 | CALL_TXH(ieee80211_tx_h_ps_buf) | 1315 | CALL_TXH(ieee80211_tx_h_sequence); |
1211 | CALL_TXH(ieee80211_tx_h_select_key) | 1316 | CALL_TXH(ieee80211_tx_h_fragment); |
1212 | CALL_TXH(ieee80211_tx_h_michael_mic_add) | ||
1213 | CALL_TXH(ieee80211_tx_h_rate_ctrl) | ||
1214 | CALL_TXH(ieee80211_tx_h_misc) | ||
1215 | CALL_TXH(ieee80211_tx_h_sequence) | ||
1216 | CALL_TXH(ieee80211_tx_h_fragment) | ||
1217 | /* handlers after fragment must be aware of tx info fragmentation! */ | 1317 | /* handlers after fragment must be aware of tx info fragmentation! */ |
1218 | CALL_TXH(ieee80211_tx_h_stats) | 1318 | CALL_TXH(ieee80211_tx_h_stats); |
1219 | CALL_TXH(ieee80211_tx_h_encrypt) | 1319 | CALL_TXH(ieee80211_tx_h_encrypt); |
1220 | CALL_TXH(ieee80211_tx_h_calculate_duration) | 1320 | CALL_TXH(ieee80211_tx_h_calculate_duration); |
1221 | #undef CALL_TXH | 1321 | #undef CALL_TXH |
1222 | 1322 | ||
1223 | txh_done: | 1323 | txh_done: |
@@ -1397,29 +1497,14 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1397 | int headroom; | 1497 | int headroom; |
1398 | bool may_encrypt; | 1498 | bool may_encrypt; |
1399 | 1499 | ||
1400 | dev_hold(sdata->dev); | 1500 | rcu_read_lock(); |
1401 | |||
1402 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && | ||
1403 | local->hw.conf.dynamic_ps_timeout > 0 && | ||
1404 | !(local->scanning) && local->ps_sdata) { | ||
1405 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | ||
1406 | ieee80211_stop_queues_by_reason(&local->hw, | ||
1407 | IEEE80211_QUEUE_STOP_REASON_PS); | ||
1408 | ieee80211_queue_work(&local->hw, | ||
1409 | &local->dynamic_ps_disable_work); | ||
1410 | } | ||
1411 | |||
1412 | mod_timer(&local->dynamic_ps_timer, jiffies + | ||
1413 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); | ||
1414 | } | ||
1415 | |||
1416 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1417 | 1501 | ||
1418 | if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) { | 1502 | if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) { |
1419 | int hdrlen; | 1503 | int hdrlen; |
1420 | u16 len_rthdr; | 1504 | u16 len_rthdr; |
1421 | 1505 | ||
1422 | info->flags |= IEEE80211_TX_CTL_INJECTED; | 1506 | info->flags |= IEEE80211_TX_CTL_INJECTED | |
1507 | IEEE80211_TX_INTFL_HAS_RADIOTAP; | ||
1423 | 1508 | ||
1424 | len_rthdr = ieee80211_get_radiotap_len(skb->data); | 1509 | len_rthdr = ieee80211_get_radiotap_len(skb->data); |
1425 | hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); | 1510 | hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); |
@@ -1437,22 +1522,18 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1437 | * support we will need a different mechanism. | 1522 | * support we will need a different mechanism. |
1438 | */ | 1523 | */ |
1439 | 1524 | ||
1440 | rcu_read_lock(); | ||
1441 | list_for_each_entry_rcu(tmp_sdata, &local->interfaces, | 1525 | list_for_each_entry_rcu(tmp_sdata, &local->interfaces, |
1442 | list) { | 1526 | list) { |
1443 | if (!netif_running(tmp_sdata->dev)) | 1527 | if (!ieee80211_sdata_running(tmp_sdata)) |
1444 | continue; | 1528 | continue; |
1445 | if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) | 1529 | if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) |
1446 | continue; | 1530 | continue; |
1447 | if (compare_ether_addr(tmp_sdata->dev->dev_addr, | 1531 | if (compare_ether_addr(tmp_sdata->vif.addr, |
1448 | hdr->addr2) == 0) { | 1532 | hdr->addr2) == 0) { |
1449 | dev_hold(tmp_sdata->dev); | ||
1450 | dev_put(sdata->dev); | ||
1451 | sdata = tmp_sdata; | 1533 | sdata = tmp_sdata; |
1452 | break; | 1534 | break; |
1453 | } | 1535 | } |
1454 | } | 1536 | } |
1455 | rcu_read_unlock(); | ||
1456 | } | 1537 | } |
1457 | } | 1538 | } |
1458 | 1539 | ||
@@ -1466,7 +1547,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1466 | 1547 | ||
1467 | if (ieee80211_skb_resize(local, skb, headroom, may_encrypt)) { | 1548 | if (ieee80211_skb_resize(local, skb, headroom, may_encrypt)) { |
1468 | dev_kfree_skb(skb); | 1549 | dev_kfree_skb(skb); |
1469 | dev_put(sdata->dev); | 1550 | rcu_read_unlock(); |
1470 | return; | 1551 | return; |
1471 | } | 1552 | } |
1472 | 1553 | ||
@@ -1477,13 +1558,13 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1477 | !is_multicast_ether_addr(hdr->addr1)) | 1558 | !is_multicast_ether_addr(hdr->addr1)) |
1478 | if (mesh_nexthop_lookup(skb, sdata)) { | 1559 | if (mesh_nexthop_lookup(skb, sdata)) { |
1479 | /* skb queued: don't free */ | 1560 | /* skb queued: don't free */ |
1480 | dev_put(sdata->dev); | 1561 | rcu_read_unlock(); |
1481 | return; | 1562 | return; |
1482 | } | 1563 | } |
1483 | 1564 | ||
1484 | ieee80211_select_queue(local, skb); | 1565 | ieee80211_set_qos_hdr(local, skb); |
1485 | ieee80211_tx(sdata, skb, false); | 1566 | ieee80211_tx(sdata, skb, false); |
1486 | dev_put(sdata->dev); | 1567 | rcu_read_unlock(); |
1487 | } | 1568 | } |
1488 | 1569 | ||
1489 | netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | 1570 | netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, |
@@ -1547,6 +1628,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1547 | 1628 | ||
1548 | memset(info, 0, sizeof(*info)); | 1629 | memset(info, 0, sizeof(*info)); |
1549 | 1630 | ||
1631 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1632 | |||
1550 | /* pass the radiotap header up to xmit */ | 1633 | /* pass the radiotap header up to xmit */ |
1551 | ieee80211_xmit(IEEE80211_DEV_TO_SUB_IF(dev), skb); | 1634 | ieee80211_xmit(IEEE80211_DEV_TO_SUB_IF(dev), skb); |
1552 | return NETDEV_TX_OK; | 1635 | return NETDEV_TX_OK; |
@@ -1585,7 +1668,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1585 | const u8 *encaps_data; | 1668 | const u8 *encaps_data; |
1586 | int encaps_len, skip_header_bytes; | 1669 | int encaps_len, skip_header_bytes; |
1587 | int nh_pos, h_pos; | 1670 | int nh_pos, h_pos; |
1588 | struct sta_info *sta; | 1671 | struct sta_info *sta = NULL; |
1589 | u32 sta_flags = 0; | 1672 | u32 sta_flags = 0; |
1590 | 1673 | ||
1591 | if (unlikely(skb->len < ETH_HLEN)) { | 1674 | if (unlikely(skb->len < ETH_HLEN)) { |
@@ -1602,12 +1685,28 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1602 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); | 1685 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); |
1603 | 1686 | ||
1604 | switch (sdata->vif.type) { | 1687 | switch (sdata->vif.type) { |
1605 | case NL80211_IFTYPE_AP: | ||
1606 | case NL80211_IFTYPE_AP_VLAN: | 1688 | case NL80211_IFTYPE_AP_VLAN: |
1689 | rcu_read_lock(); | ||
1690 | sta = rcu_dereference(sdata->u.vlan.sta); | ||
1691 | if (sta) { | ||
1692 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | ||
1693 | /* RA TA DA SA */ | ||
1694 | memcpy(hdr.addr1, sta->sta.addr, ETH_ALEN); | ||
1695 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); | ||
1696 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | ||
1697 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); | ||
1698 | hdrlen = 30; | ||
1699 | sta_flags = get_sta_flags(sta); | ||
1700 | } | ||
1701 | rcu_read_unlock(); | ||
1702 | if (sta) | ||
1703 | break; | ||
1704 | /* fall through */ | ||
1705 | case NL80211_IFTYPE_AP: | ||
1607 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); | 1706 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); |
1608 | /* DA BSSID SA */ | 1707 | /* DA BSSID SA */ |
1609 | memcpy(hdr.addr1, skb->data, ETH_ALEN); | 1708 | memcpy(hdr.addr1, skb->data, ETH_ALEN); |
1610 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); | 1709 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); |
1611 | memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN); | 1710 | memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN); |
1612 | hdrlen = 24; | 1711 | hdrlen = 24; |
1613 | break; | 1712 | break; |
@@ -1615,7 +1714,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1615 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | 1714 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1616 | /* RA TA DA SA */ | 1715 | /* RA TA DA SA */ |
1617 | memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN); | 1716 | memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN); |
1618 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); | 1717 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); |
1619 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | 1718 | memcpy(hdr.addr3, skb->data, ETH_ALEN); |
1620 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); | 1719 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); |
1621 | hdrlen = 30; | 1720 | hdrlen = 30; |
@@ -1629,8 +1728,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1629 | goto fail; | 1728 | goto fail; |
1630 | } | 1729 | } |
1631 | 1730 | ||
1632 | if (compare_ether_addr(dev->dev_addr, | 1731 | if (compare_ether_addr(sdata->vif.addr, |
1633 | skb->data + ETH_ALEN) == 0) { | 1732 | skb->data + ETH_ALEN) == 0) { |
1634 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, | 1733 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, |
1635 | skb->data, skb->data + ETH_ALEN); | 1734 | skb->data, skb->data + ETH_ALEN); |
1636 | meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, | 1735 | meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, |
@@ -1639,24 +1738,28 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1639 | /* packet from other interface */ | 1738 | /* packet from other interface */ |
1640 | struct mesh_path *mppath; | 1739 | struct mesh_path *mppath; |
1641 | int is_mesh_mcast = 1; | 1740 | int is_mesh_mcast = 1; |
1642 | char *mesh_da; | 1741 | const u8 *mesh_da; |
1643 | 1742 | ||
1644 | rcu_read_lock(); | 1743 | rcu_read_lock(); |
1645 | if (is_multicast_ether_addr(skb->data)) | 1744 | if (is_multicast_ether_addr(skb->data)) |
1646 | /* DA TA mSA AE:SA */ | 1745 | /* DA TA mSA AE:SA */ |
1647 | mesh_da = skb->data; | 1746 | mesh_da = skb->data; |
1648 | else { | 1747 | else { |
1748 | static const u8 bcast[ETH_ALEN] = | ||
1749 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | ||
1750 | |||
1649 | mppath = mpp_path_lookup(skb->data, sdata); | 1751 | mppath = mpp_path_lookup(skb->data, sdata); |
1650 | if (mppath) { | 1752 | if (mppath) { |
1651 | /* RA TA mDA mSA AE:DA SA */ | 1753 | /* RA TA mDA mSA AE:DA SA */ |
1652 | mesh_da = mppath->mpp; | 1754 | mesh_da = mppath->mpp; |
1653 | is_mesh_mcast = 0; | 1755 | is_mesh_mcast = 0; |
1654 | } else | 1756 | } else { |
1655 | /* DA TA mSA AE:SA */ | 1757 | /* DA TA mSA AE:SA */ |
1656 | mesh_da = dev->broadcast; | 1758 | mesh_da = bcast; |
1759 | } | ||
1657 | } | 1760 | } |
1658 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, | 1761 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, |
1659 | mesh_da, dev->dev_addr); | 1762 | mesh_da, sdata->vif.addr); |
1660 | rcu_read_unlock(); | 1763 | rcu_read_unlock(); |
1661 | if (is_mesh_mcast) | 1764 | if (is_mesh_mcast) |
1662 | meshhdrlen = | 1765 | meshhdrlen = |
@@ -1677,12 +1780,21 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1677 | break; | 1780 | break; |
1678 | #endif | 1781 | #endif |
1679 | case NL80211_IFTYPE_STATION: | 1782 | case NL80211_IFTYPE_STATION: |
1680 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS); | ||
1681 | /* BSSID SA DA */ | ||
1682 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); | 1783 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); |
1683 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); | 1784 | if (sdata->u.mgd.use_4addr && ethertype != ETH_P_PAE) { |
1684 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | 1785 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1685 | hdrlen = 24; | 1786 | /* RA TA DA SA */ |
1787 | memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); | ||
1788 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | ||
1789 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); | ||
1790 | hdrlen = 30; | ||
1791 | } else { | ||
1792 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS); | ||
1793 | /* BSSID SA DA */ | ||
1794 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); | ||
1795 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | ||
1796 | hdrlen = 24; | ||
1797 | } | ||
1686 | break; | 1798 | break; |
1687 | case NL80211_IFTYPE_ADHOC: | 1799 | case NL80211_IFTYPE_ADHOC: |
1688 | /* DA SA BSSID */ | 1800 | /* DA SA BSSID */ |
@@ -1703,9 +1815,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1703 | */ | 1815 | */ |
1704 | if (!is_multicast_ether_addr(hdr.addr1)) { | 1816 | if (!is_multicast_ether_addr(hdr.addr1)) { |
1705 | rcu_read_lock(); | 1817 | rcu_read_lock(); |
1706 | sta = sta_info_get(local, hdr.addr1); | 1818 | sta = sta_info_get(sdata, hdr.addr1); |
1707 | /* XXX: in the future, use sdata to look up the sta */ | 1819 | if (sta) |
1708 | if (sta && sta->sdata == sdata) | ||
1709 | sta_flags = get_sta_flags(sta); | 1820 | sta_flags = get_sta_flags(sta); |
1710 | rcu_read_unlock(); | 1821 | rcu_read_unlock(); |
1711 | } | 1822 | } |
@@ -1724,7 +1835,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1724 | unlikely(!is_multicast_ether_addr(hdr.addr1) && | 1835 | unlikely(!is_multicast_ether_addr(hdr.addr1) && |
1725 | !(sta_flags & WLAN_STA_AUTHORIZED) && | 1836 | !(sta_flags & WLAN_STA_AUTHORIZED) && |
1726 | !(ethertype == ETH_P_PAE && | 1837 | !(ethertype == ETH_P_PAE && |
1727 | compare_ether_addr(dev->dev_addr, | 1838 | compare_ether_addr(sdata->vif.addr, |
1728 | skb->data + ETH_ALEN) == 0))) { | 1839 | skb->data + ETH_ALEN) == 0))) { |
1729 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1840 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1730 | if (net_ratelimit()) | 1841 | if (net_ratelimit()) |
@@ -1864,7 +1975,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, | |||
1864 | ieee80211_tx(sdata, skb, true); | 1975 | ieee80211_tx(sdata, skb, true); |
1865 | } else { | 1976 | } else { |
1866 | hdr = (struct ieee80211_hdr *)skb->data; | 1977 | hdr = (struct ieee80211_hdr *)skb->data; |
1867 | sta = sta_info_get(local, hdr->addr1); | 1978 | sta = sta_info_get(sdata, hdr->addr1); |
1868 | 1979 | ||
1869 | ret = __ieee80211_tx(local, &skb, sta, true); | 1980 | ret = __ieee80211_tx(local, &skb, sta, true); |
1870 | if (ret != IEEE80211_TX_OK) | 1981 | if (ret != IEEE80211_TX_OK) |
@@ -1880,6 +1991,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, | |||
1880 | void ieee80211_tx_pending(unsigned long data) | 1991 | void ieee80211_tx_pending(unsigned long data) |
1881 | { | 1992 | { |
1882 | struct ieee80211_local *local = (struct ieee80211_local *)data; | 1993 | struct ieee80211_local *local = (struct ieee80211_local *)data; |
1994 | struct ieee80211_sub_if_data *sdata; | ||
1883 | unsigned long flags; | 1995 | unsigned long flags; |
1884 | int i; | 1996 | int i; |
1885 | bool txok; | 1997 | bool txok; |
@@ -1907,12 +2019,10 @@ void ieee80211_tx_pending(unsigned long data) | |||
1907 | } | 2019 | } |
1908 | 2020 | ||
1909 | sdata = vif_to_sdata(info->control.vif); | 2021 | sdata = vif_to_sdata(info->control.vif); |
1910 | dev_hold(sdata->dev); | ||
1911 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, | 2022 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, |
1912 | flags); | 2023 | flags); |
1913 | 2024 | ||
1914 | txok = ieee80211_tx_pending_skb(local, skb); | 2025 | txok = ieee80211_tx_pending_skb(local, skb); |
1915 | dev_put(sdata->dev); | ||
1916 | if (!txok) | 2026 | if (!txok) |
1917 | __skb_queue_head(&local->pending[i], skb); | 2027 | __skb_queue_head(&local->pending[i], skb); |
1918 | spin_lock_irqsave(&local->queue_stop_reason_lock, | 2028 | spin_lock_irqsave(&local->queue_stop_reason_lock, |
@@ -1920,6 +2030,11 @@ void ieee80211_tx_pending(unsigned long data) | |||
1920 | if (!txok) | 2030 | if (!txok) |
1921 | break; | 2031 | break; |
1922 | } | 2032 | } |
2033 | |||
2034 | if (skb_queue_empty(&local->pending[i])) | ||
2035 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | ||
2036 | netif_tx_wake_queue( | ||
2037 | netdev_get_tx_queue(sdata->dev, i)); | ||
1923 | } | 2038 | } |
1924 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 2039 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
1925 | 2040 | ||
@@ -1990,8 +2105,9 @@ static void ieee80211_beacon_add_tim(struct ieee80211_if_ap *bss, | |||
1990 | } | 2105 | } |
1991 | } | 2106 | } |
1992 | 2107 | ||
1993 | struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | 2108 | struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, |
1994 | struct ieee80211_vif *vif) | 2109 | struct ieee80211_vif *vif, |
2110 | u16 *tim_offset, u16 *tim_length) | ||
1995 | { | 2111 | { |
1996 | struct ieee80211_local *local = hw_to_local(hw); | 2112 | struct ieee80211_local *local = hw_to_local(hw); |
1997 | struct sk_buff *skb = NULL; | 2113 | struct sk_buff *skb = NULL; |
@@ -2001,6 +2117,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
2001 | struct beacon_data *beacon; | 2117 | struct beacon_data *beacon; |
2002 | struct ieee80211_supported_band *sband; | 2118 | struct ieee80211_supported_band *sband; |
2003 | enum ieee80211_band band = local->hw.conf.channel->band; | 2119 | enum ieee80211_band band = local->hw.conf.channel->band; |
2120 | struct ieee80211_tx_rate_control txrc; | ||
2004 | 2121 | ||
2005 | sband = local->hw.wiphy->bands[band]; | 2122 | sband = local->hw.wiphy->bands[band]; |
2006 | 2123 | ||
@@ -2008,6 +2125,11 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
2008 | 2125 | ||
2009 | sdata = vif_to_sdata(vif); | 2126 | sdata = vif_to_sdata(vif); |
2010 | 2127 | ||
2128 | if (tim_offset) | ||
2129 | *tim_offset = 0; | ||
2130 | if (tim_length) | ||
2131 | *tim_length = 0; | ||
2132 | |||
2011 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 2133 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
2012 | ap = &sdata->u.ap; | 2134 | ap = &sdata->u.ap; |
2013 | beacon = rcu_dereference(ap->beacon); | 2135 | beacon = rcu_dereference(ap->beacon); |
@@ -2043,6 +2165,11 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
2043 | spin_unlock_irqrestore(&local->sta_lock, flags); | 2165 | spin_unlock_irqrestore(&local->sta_lock, flags); |
2044 | } | 2166 | } |
2045 | 2167 | ||
2168 | if (tim_offset) | ||
2169 | *tim_offset = beacon->head_len; | ||
2170 | if (tim_length) | ||
2171 | *tim_length = skb->len - beacon->head_len; | ||
2172 | |||
2046 | if (beacon->tail) | 2173 | if (beacon->tail) |
2047 | memcpy(skb_put(skb, beacon->tail_len), | 2174 | memcpy(skb_put(skb, beacon->tail_len), |
2048 | beacon->tail, beacon->tail_len); | 2175 | beacon->tail, beacon->tail_len); |
@@ -2079,8 +2206,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
2079 | mgmt->frame_control = | 2206 | mgmt->frame_control = |
2080 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); | 2207 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); |
2081 | memset(mgmt->da, 0xff, ETH_ALEN); | 2208 | memset(mgmt->da, 0xff, ETH_ALEN); |
2082 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); | 2209 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
2083 | /* BSSID is left zeroed, wildcard value */ | 2210 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); |
2084 | mgmt->u.beacon.beacon_int = | 2211 | mgmt->u.beacon.beacon_int = |
2085 | cpu_to_le16(sdata->vif.bss_conf.beacon_int); | 2212 | cpu_to_le16(sdata->vif.bss_conf.beacon_int); |
2086 | mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */ | 2213 | mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */ |
@@ -2098,28 +2225,160 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
2098 | info = IEEE80211_SKB_CB(skb); | 2225 | info = IEEE80211_SKB_CB(skb); |
2099 | 2226 | ||
2100 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 2227 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
2228 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
2101 | info->band = band; | 2229 | info->band = band; |
2102 | /* | 2230 | |
2103 | * XXX: For now, always use the lowest rate | 2231 | memset(&txrc, 0, sizeof(txrc)); |
2104 | */ | 2232 | txrc.hw = hw; |
2105 | info->control.rates[0].idx = 0; | 2233 | txrc.sband = sband; |
2106 | info->control.rates[0].count = 1; | 2234 | txrc.bss_conf = &sdata->vif.bss_conf; |
2107 | info->control.rates[1].idx = -1; | 2235 | txrc.skb = skb; |
2108 | info->control.rates[2].idx = -1; | 2236 | txrc.reported_rate.idx = -1; |
2109 | info->control.rates[3].idx = -1; | 2237 | txrc.rate_idx_mask = sdata->rc_rateidx_mask[band]; |
2110 | info->control.rates[4].idx = -1; | 2238 | if (txrc.rate_idx_mask == (1 << sband->n_bitrates) - 1) |
2111 | BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5); | 2239 | txrc.max_rate_idx = -1; |
2240 | else | ||
2241 | txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; | ||
2242 | txrc.ap = true; | ||
2243 | rate_control_get_rate(sdata, NULL, &txrc); | ||
2112 | 2244 | ||
2113 | info->control.vif = vif; | 2245 | info->control.vif = vif; |
2114 | 2246 | ||
2115 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
2116 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | 2247 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
2117 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | 2248 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
2118 | out: | 2249 | out: |
2119 | rcu_read_unlock(); | 2250 | rcu_read_unlock(); |
2120 | return skb; | 2251 | return skb; |
2121 | } | 2252 | } |
2122 | EXPORT_SYMBOL(ieee80211_beacon_get); | 2253 | EXPORT_SYMBOL(ieee80211_beacon_get_tim); |
2254 | |||
2255 | struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw, | ||
2256 | struct ieee80211_vif *vif) | ||
2257 | { | ||
2258 | struct ieee80211_sub_if_data *sdata; | ||
2259 | struct ieee80211_if_managed *ifmgd; | ||
2260 | struct ieee80211_pspoll *pspoll; | ||
2261 | struct ieee80211_local *local; | ||
2262 | struct sk_buff *skb; | ||
2263 | |||
2264 | if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) | ||
2265 | return NULL; | ||
2266 | |||
2267 | sdata = vif_to_sdata(vif); | ||
2268 | ifmgd = &sdata->u.mgd; | ||
2269 | local = sdata->local; | ||
2270 | |||
2271 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*pspoll)); | ||
2272 | if (!skb) { | ||
2273 | printk(KERN_DEBUG "%s: failed to allocate buffer for " | ||
2274 | "pspoll template\n", sdata->name); | ||
2275 | return NULL; | ||
2276 | } | ||
2277 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
2278 | |||
2279 | pspoll = (struct ieee80211_pspoll *) skb_put(skb, sizeof(*pspoll)); | ||
2280 | memset(pspoll, 0, sizeof(*pspoll)); | ||
2281 | pspoll->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | | ||
2282 | IEEE80211_STYPE_PSPOLL); | ||
2283 | pspoll->aid = cpu_to_le16(ifmgd->aid); | ||
2284 | |||
2285 | /* aid in PS-Poll has its two MSBs each set to 1 */ | ||
2286 | pspoll->aid |= cpu_to_le16(1 << 15 | 1 << 14); | ||
2287 | |||
2288 | memcpy(pspoll->bssid, ifmgd->bssid, ETH_ALEN); | ||
2289 | memcpy(pspoll->ta, vif->addr, ETH_ALEN); | ||
2290 | |||
2291 | return skb; | ||
2292 | } | ||
2293 | EXPORT_SYMBOL(ieee80211_pspoll_get); | ||
2294 | |||
2295 | struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw, | ||
2296 | struct ieee80211_vif *vif) | ||
2297 | { | ||
2298 | struct ieee80211_hdr_3addr *nullfunc; | ||
2299 | struct ieee80211_sub_if_data *sdata; | ||
2300 | struct ieee80211_if_managed *ifmgd; | ||
2301 | struct ieee80211_local *local; | ||
2302 | struct sk_buff *skb; | ||
2303 | |||
2304 | if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) | ||
2305 | return NULL; | ||
2306 | |||
2307 | sdata = vif_to_sdata(vif); | ||
2308 | ifmgd = &sdata->u.mgd; | ||
2309 | local = sdata->local; | ||
2310 | |||
2311 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*nullfunc)); | ||
2312 | if (!skb) { | ||
2313 | printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc " | ||
2314 | "template\n", sdata->name); | ||
2315 | return NULL; | ||
2316 | } | ||
2317 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
2318 | |||
2319 | nullfunc = (struct ieee80211_hdr_3addr *) skb_put(skb, | ||
2320 | sizeof(*nullfunc)); | ||
2321 | memset(nullfunc, 0, sizeof(*nullfunc)); | ||
2322 | nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | | ||
2323 | IEEE80211_STYPE_NULLFUNC | | ||
2324 | IEEE80211_FCTL_TODS); | ||
2325 | memcpy(nullfunc->addr1, ifmgd->bssid, ETH_ALEN); | ||
2326 | memcpy(nullfunc->addr2, vif->addr, ETH_ALEN); | ||
2327 | memcpy(nullfunc->addr3, ifmgd->bssid, ETH_ALEN); | ||
2328 | |||
2329 | return skb; | ||
2330 | } | ||
2331 | EXPORT_SYMBOL(ieee80211_nullfunc_get); | ||
2332 | |||
2333 | struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw, | ||
2334 | struct ieee80211_vif *vif, | ||
2335 | const u8 *ssid, size_t ssid_len, | ||
2336 | const u8 *ie, size_t ie_len) | ||
2337 | { | ||
2338 | struct ieee80211_sub_if_data *sdata; | ||
2339 | struct ieee80211_local *local; | ||
2340 | struct ieee80211_hdr_3addr *hdr; | ||
2341 | struct sk_buff *skb; | ||
2342 | size_t ie_ssid_len; | ||
2343 | u8 *pos; | ||
2344 | |||
2345 | sdata = vif_to_sdata(vif); | ||
2346 | local = sdata->local; | ||
2347 | ie_ssid_len = 2 + ssid_len; | ||
2348 | |||
2349 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*hdr) + | ||
2350 | ie_ssid_len + ie_len); | ||
2351 | if (!skb) { | ||
2352 | printk(KERN_DEBUG "%s: failed to allocate buffer for probe " | ||
2353 | "request template\n", sdata->name); | ||
2354 | return NULL; | ||
2355 | } | ||
2356 | |||
2357 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
2358 | |||
2359 | hdr = (struct ieee80211_hdr_3addr *) skb_put(skb, sizeof(*hdr)); | ||
2360 | memset(hdr, 0, sizeof(*hdr)); | ||
2361 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
2362 | IEEE80211_STYPE_PROBE_REQ); | ||
2363 | memset(hdr->addr1, 0xff, ETH_ALEN); | ||
2364 | memcpy(hdr->addr2, vif->addr, ETH_ALEN); | ||
2365 | memset(hdr->addr3, 0xff, ETH_ALEN); | ||
2366 | |||
2367 | pos = skb_put(skb, ie_ssid_len); | ||
2368 | *pos++ = WLAN_EID_SSID; | ||
2369 | *pos++ = ssid_len; | ||
2370 | if (ssid) | ||
2371 | memcpy(pos, ssid, ssid_len); | ||
2372 | pos += ssid_len; | ||
2373 | |||
2374 | if (ie) { | ||
2375 | pos = skb_put(skb, ie_len); | ||
2376 | memcpy(pos, ie, ie_len); | ||
2377 | } | ||
2378 | |||
2379 | return skb; | ||
2380 | } | ||
2381 | EXPORT_SYMBOL(ieee80211_probereq_get); | ||
2123 | 2382 | ||
2124 | void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 2383 | void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
2125 | const void *frame, size_t frame_len, | 2384 | const void *frame, size_t frame_len, |
@@ -2214,16 +2473,14 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2214 | } | 2473 | } |
2215 | EXPORT_SYMBOL(ieee80211_get_buffered_bc); | 2474 | EXPORT_SYMBOL(ieee80211_get_buffered_bc); |
2216 | 2475 | ||
2217 | void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, | 2476 | void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) |
2218 | int encrypt) | ||
2219 | { | 2477 | { |
2220 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
2221 | skb_set_mac_header(skb, 0); | 2478 | skb_set_mac_header(skb, 0); |
2222 | skb_set_network_header(skb, 0); | 2479 | skb_set_network_header(skb, 0); |
2223 | skb_set_transport_header(skb, 0); | 2480 | skb_set_transport_header(skb, 0); |
2224 | 2481 | ||
2225 | if (!encrypt) | 2482 | /* send all internal mgmt frames on VO */ |
2226 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 2483 | skb_set_queue_mapping(skb, 0); |
2227 | 2484 | ||
2228 | /* | 2485 | /* |
2229 | * The other path calling ieee80211_xmit is from the tasklet, | 2486 | * The other path calling ieee80211_xmit is from the tasklet, |