diff options
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 107 |
1 files changed, 89 insertions, 18 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index cee4884b9d06..fb89e1d0aa03 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -239,7 +239,7 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, | |||
239 | erp = 0; | 239 | erp = 0; |
240 | if (vif) { | 240 | if (vif) { |
241 | sdata = vif_to_sdata(vif); | 241 | sdata = vif_to_sdata(vif); |
242 | short_preamble = sdata->bss_conf.use_short_preamble; | 242 | short_preamble = sdata->vif.bss_conf.use_short_preamble; |
243 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 243 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
244 | erp = rate->flags & IEEE80211_RATE_ERP_G; | 244 | erp = rate->flags & IEEE80211_RATE_ERP_G; |
245 | } | 245 | } |
@@ -272,7 +272,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, | |||
272 | erp = 0; | 272 | erp = 0; |
273 | if (vif) { | 273 | if (vif) { |
274 | sdata = vif_to_sdata(vif); | 274 | sdata = vif_to_sdata(vif); |
275 | short_preamble = sdata->bss_conf.use_short_preamble; | 275 | short_preamble = sdata->vif.bss_conf.use_short_preamble; |
276 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 276 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
277 | erp = rate->flags & IEEE80211_RATE_ERP_G; | 277 | erp = rate->flags & IEEE80211_RATE_ERP_G; |
278 | } | 278 | } |
@@ -312,7 +312,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
312 | erp = 0; | 312 | erp = 0; |
313 | if (vif) { | 313 | if (vif) { |
314 | sdata = vif_to_sdata(vif); | 314 | sdata = vif_to_sdata(vif); |
315 | short_preamble = sdata->bss_conf.use_short_preamble; | 315 | short_preamble = sdata->vif.bss_conf.use_short_preamble; |
316 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 316 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
317 | erp = rate->flags & IEEE80211_RATE_ERP_G; | 317 | erp = rate->flags & IEEE80211_RATE_ERP_G; |
318 | } | 318 | } |
@@ -330,10 +330,20 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
330 | } | 330 | } |
331 | EXPORT_SYMBOL(ieee80211_ctstoself_duration); | 331 | EXPORT_SYMBOL(ieee80211_ctstoself_duration); |
332 | 332 | ||
333 | void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) | 333 | static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, |
334 | enum queue_stop_reason reason) | ||
334 | { | 335 | { |
335 | struct ieee80211_local *local = hw_to_local(hw); | 336 | struct ieee80211_local *local = hw_to_local(hw); |
336 | 337 | ||
338 | /* we don't need to track ampdu queues */ | ||
339 | if (queue < ieee80211_num_regular_queues(hw)) { | ||
340 | __clear_bit(reason, &local->queue_stop_reasons[queue]); | ||
341 | |||
342 | if (local->queue_stop_reasons[queue] != 0) | ||
343 | /* someone still has this queue stopped */ | ||
344 | return; | ||
345 | } | ||
346 | |||
337 | if (test_bit(queue, local->queues_pending)) { | 347 | if (test_bit(queue, local->queues_pending)) { |
338 | set_bit(queue, local->queues_pending_run); | 348 | set_bit(queue, local->queues_pending_run); |
339 | tasklet_schedule(&local->tx_pending_tasklet); | 349 | tasklet_schedule(&local->tx_pending_tasklet); |
@@ -341,22 +351,74 @@ void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) | |||
341 | netif_wake_subqueue(local->mdev, queue); | 351 | netif_wake_subqueue(local->mdev, queue); |
342 | } | 352 | } |
343 | } | 353 | } |
354 | |||
355 | void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, | ||
356 | enum queue_stop_reason reason) | ||
357 | { | ||
358 | struct ieee80211_local *local = hw_to_local(hw); | ||
359 | unsigned long flags; | ||
360 | |||
361 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
362 | __ieee80211_wake_queue(hw, queue, reason); | ||
363 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
364 | } | ||
365 | |||
366 | void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) | ||
367 | { | ||
368 | ieee80211_wake_queue_by_reason(hw, queue, | ||
369 | IEEE80211_QUEUE_STOP_REASON_DRIVER); | ||
370 | } | ||
344 | EXPORT_SYMBOL(ieee80211_wake_queue); | 371 | EXPORT_SYMBOL(ieee80211_wake_queue); |
345 | 372 | ||
346 | void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) | 373 | static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, |
374 | enum queue_stop_reason reason) | ||
347 | { | 375 | { |
348 | struct ieee80211_local *local = hw_to_local(hw); | 376 | struct ieee80211_local *local = hw_to_local(hw); |
349 | 377 | ||
378 | /* we don't need to track ampdu queues */ | ||
379 | if (queue < ieee80211_num_regular_queues(hw)) | ||
380 | __set_bit(reason, &local->queue_stop_reasons[queue]); | ||
381 | |||
350 | netif_stop_subqueue(local->mdev, queue); | 382 | netif_stop_subqueue(local->mdev, queue); |
351 | } | 383 | } |
384 | |||
385 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, | ||
386 | enum queue_stop_reason reason) | ||
387 | { | ||
388 | struct ieee80211_local *local = hw_to_local(hw); | ||
389 | unsigned long flags; | ||
390 | |||
391 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
392 | __ieee80211_stop_queue(hw, queue, reason); | ||
393 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
394 | } | ||
395 | |||
396 | void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) | ||
397 | { | ||
398 | ieee80211_stop_queue_by_reason(hw, queue, | ||
399 | IEEE80211_QUEUE_STOP_REASON_DRIVER); | ||
400 | } | ||
352 | EXPORT_SYMBOL(ieee80211_stop_queue); | 401 | EXPORT_SYMBOL(ieee80211_stop_queue); |
353 | 402 | ||
354 | void ieee80211_stop_queues(struct ieee80211_hw *hw) | 403 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, |
404 | enum queue_stop_reason reason) | ||
355 | { | 405 | { |
406 | struct ieee80211_local *local = hw_to_local(hw); | ||
407 | unsigned long flags; | ||
356 | int i; | 408 | int i; |
357 | 409 | ||
410 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
411 | |||
358 | for (i = 0; i < ieee80211_num_queues(hw); i++) | 412 | for (i = 0; i < ieee80211_num_queues(hw); i++) |
359 | ieee80211_stop_queue(hw, i); | 413 | __ieee80211_stop_queue(hw, i, reason); |
414 | |||
415 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
416 | } | ||
417 | |||
418 | void ieee80211_stop_queues(struct ieee80211_hw *hw) | ||
419 | { | ||
420 | ieee80211_stop_queues_by_reason(hw, | ||
421 | IEEE80211_QUEUE_STOP_REASON_DRIVER); | ||
360 | } | 422 | } |
361 | EXPORT_SYMBOL(ieee80211_stop_queues); | 423 | EXPORT_SYMBOL(ieee80211_stop_queues); |
362 | 424 | ||
@@ -367,12 +429,24 @@ int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue) | |||
367 | } | 429 | } |
368 | EXPORT_SYMBOL(ieee80211_queue_stopped); | 430 | EXPORT_SYMBOL(ieee80211_queue_stopped); |
369 | 431 | ||
370 | void ieee80211_wake_queues(struct ieee80211_hw *hw) | 432 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, |
433 | enum queue_stop_reason reason) | ||
371 | { | 434 | { |
435 | struct ieee80211_local *local = hw_to_local(hw); | ||
436 | unsigned long flags; | ||
372 | int i; | 437 | int i; |
373 | 438 | ||
439 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
440 | |||
374 | for (i = 0; i < hw->queues + hw->ampdu_queues; i++) | 441 | for (i = 0; i < hw->queues + hw->ampdu_queues; i++) |
375 | ieee80211_wake_queue(hw, i); | 442 | __ieee80211_wake_queue(hw, i, reason); |
443 | |||
444 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
445 | } | ||
446 | |||
447 | void ieee80211_wake_queues(struct ieee80211_hw *hw) | ||
448 | { | ||
449 | ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_DRIVER); | ||
376 | } | 450 | } |
377 | EXPORT_SYMBOL(ieee80211_wake_queues); | 451 | EXPORT_SYMBOL(ieee80211_wake_queues); |
378 | 452 | ||
@@ -532,8 +606,8 @@ void ieee802_11_parse_elems(u8 *start, size_t len, | |||
532 | if (elen >= sizeof(struct ieee80211_ht_cap)) | 606 | if (elen >= sizeof(struct ieee80211_ht_cap)) |
533 | elems->ht_cap_elem = (void *)pos; | 607 | elems->ht_cap_elem = (void *)pos; |
534 | break; | 608 | break; |
535 | case WLAN_EID_HT_EXTRA_INFO: | 609 | case WLAN_EID_HT_INFORMATION: |
536 | if (elen >= sizeof(struct ieee80211_ht_addt_info)) | 610 | if (elen >= sizeof(struct ieee80211_ht_info)) |
537 | elems->ht_info_elem = (void *)pos; | 611 | elems->ht_info_elem = (void *)pos; |
538 | break; | 612 | break; |
539 | case WLAN_EID_MESH_ID: | 613 | case WLAN_EID_MESH_ID: |
@@ -638,19 +712,16 @@ int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz) | |||
638 | 712 | ||
639 | if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { | 713 | if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { |
640 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | 714 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && |
641 | chan->flags & IEEE80211_CHAN_NO_IBSS) { | 715 | chan->flags & IEEE80211_CHAN_NO_IBSS) |
642 | printk(KERN_DEBUG "%s: IBSS not allowed on frequency " | ||
643 | "%d MHz\n", sdata->dev->name, chan->center_freq); | ||
644 | return ret; | 716 | return ret; |
645 | } | ||
646 | local->oper_channel = chan; | 717 | local->oper_channel = chan; |
718 | local->oper_channel_type = NL80211_CHAN_NO_HT; | ||
647 | 719 | ||
648 | if (local->sw_scanning || local->hw_scanning) | 720 | if (local->sw_scanning || local->hw_scanning) |
649 | ret = 0; | 721 | ret = 0; |
650 | else | 722 | else |
651 | ret = ieee80211_hw_config(local); | 723 | ret = ieee80211_hw_config( |
652 | 724 | local, IEEE80211_CONF_CHANGE_CHANNEL); | |
653 | rate_control_clear(local); | ||
654 | } | 725 | } |
655 | 726 | ||
656 | return ret; | 727 | return ret; |