aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c107
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}
331EXPORT_SYMBOL(ieee80211_ctstoself_duration); 331EXPORT_SYMBOL(ieee80211_ctstoself_duration);
332 332
333void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) 333static 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
355void 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
366void 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}
344EXPORT_SYMBOL(ieee80211_wake_queue); 371EXPORT_SYMBOL(ieee80211_wake_queue);
345 372
346void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) 373static 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
385void 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
396void 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}
352EXPORT_SYMBOL(ieee80211_stop_queue); 401EXPORT_SYMBOL(ieee80211_stop_queue);
353 402
354void ieee80211_stop_queues(struct ieee80211_hw *hw) 403void 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
418void ieee80211_stop_queues(struct ieee80211_hw *hw)
419{
420 ieee80211_stop_queues_by_reason(hw,
421 IEEE80211_QUEUE_STOP_REASON_DRIVER);
360} 422}
361EXPORT_SYMBOL(ieee80211_stop_queues); 423EXPORT_SYMBOL(ieee80211_stop_queues);
362 424
@@ -367,12 +429,24 @@ int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
367} 429}
368EXPORT_SYMBOL(ieee80211_queue_stopped); 430EXPORT_SYMBOL(ieee80211_queue_stopped);
369 431
370void ieee80211_wake_queues(struct ieee80211_hw *hw) 432void 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
447void ieee80211_wake_queues(struct ieee80211_hw *hw)
448{
449 ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_DRIVER);
376} 450}
377EXPORT_SYMBOL(ieee80211_wake_queues); 451EXPORT_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;