aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-03-05 14:52:18 -0500
committerIngo Molnar <mingo@kernel.org>2015-03-05 14:52:18 -0500
commit33ca8a53f262b4af40611bea331b8c87d133af72 (patch)
treed6468c820a556c4915bcb5b761204a0fb19e8225 /net/mac80211/util.c
parentdb2dcb4f91d5fec5c346a82c309187ee821e2495 (diff)
parent13a7a6ac0a11197edcd0f756a035f472b42cdf8b (diff)
Merge tag 'v4.0-rc2' into irq/core, to refresh the tree before applying new changes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c83
1 files changed, 54 insertions, 29 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 974ebe70f5b0..8428f4a95479 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -578,7 +578,7 @@ ieee80211_get_vif_queues(struct ieee80211_local *local,
578 578
579void __ieee80211_flush_queues(struct ieee80211_local *local, 579void __ieee80211_flush_queues(struct ieee80211_local *local,
580 struct ieee80211_sub_if_data *sdata, 580 struct ieee80211_sub_if_data *sdata,
581 unsigned int queues) 581 unsigned int queues, bool drop)
582{ 582{
583 if (!local->ops->flush) 583 if (!local->ops->flush)
584 return; 584 return;
@@ -594,7 +594,7 @@ void __ieee80211_flush_queues(struct ieee80211_local *local,
594 IEEE80211_QUEUE_STOP_REASON_FLUSH, 594 IEEE80211_QUEUE_STOP_REASON_FLUSH,
595 false); 595 false);
596 596
597 drv_flush(local, sdata, queues, false); 597 drv_flush(local, sdata, queues, drop);
598 598
599 ieee80211_wake_queues_by_reason(&local->hw, queues, 599 ieee80211_wake_queues_by_reason(&local->hw, queues,
600 IEEE80211_QUEUE_STOP_REASON_FLUSH, 600 IEEE80211_QUEUE_STOP_REASON_FLUSH,
@@ -602,9 +602,9 @@ void __ieee80211_flush_queues(struct ieee80211_local *local,
602} 602}
603 603
604void ieee80211_flush_queues(struct ieee80211_local *local, 604void ieee80211_flush_queues(struct ieee80211_local *local,
605 struct ieee80211_sub_if_data *sdata) 605 struct ieee80211_sub_if_data *sdata, bool drop)
606{ 606{
607 __ieee80211_flush_queues(local, sdata, 0); 607 __ieee80211_flush_queues(local, sdata, 0, drop);
608} 608}
609 609
610void ieee80211_stop_vif_queues(struct ieee80211_local *local, 610void ieee80211_stop_vif_queues(struct ieee80211_local *local,
@@ -744,16 +744,19 @@ EXPORT_SYMBOL_GPL(wdev_to_ieee80211_vif);
744 744
745/* 745/*
746 * Nothing should have been stuffed into the workqueue during 746 * Nothing should have been stuffed into the workqueue during
747 * the suspend->resume cycle. If this WARN is seen then there 747 * the suspend->resume cycle. Since we can't check each caller
748 * is a bug with either the driver suspend or something in 748 * of this function if we are already quiescing / suspended,
749 * mac80211 stuffing into the workqueue which we haven't yet 749 * check here and don't WARN since this can actually happen when
750 * cleared during mac80211's suspend cycle. 750 * the rx path (for example) is racing against __ieee80211_suspend
751 * and suspending / quiescing was set after the rx path checked
752 * them.
751 */ 753 */
752static bool ieee80211_can_queue_work(struct ieee80211_local *local) 754static bool ieee80211_can_queue_work(struct ieee80211_local *local)
753{ 755{
754 if (WARN(local->suspended && !local->resuming, 756 if (local->quiescing || (local->suspended && !local->resuming)) {
755 "queueing ieee80211 work while going to suspend\n")) 757 pr_warn("queueing ieee80211 work while going to suspend\n");
756 return false; 758 return false;
759 }
757 760
758 return true; 761 return true;
759} 762}
@@ -1470,10 +1473,12 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local,
1470 1473
1471 /* Check if any channel in this sband supports at least 80 MHz */ 1474 /* Check if any channel in this sband supports at least 80 MHz */
1472 for (i = 0; i < sband->n_channels; i++) { 1475 for (i = 0; i < sband->n_channels; i++) {
1473 if (!(sband->channels[i].flags & IEEE80211_CHAN_NO_80MHZ)) { 1476 if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
1474 have_80mhz = true; 1477 IEEE80211_CHAN_NO_80MHZ))
1475 break; 1478 continue;
1476 } 1479
1480 have_80mhz = true;
1481 break;
1477 } 1482 }
1478 1483
1479 if (sband->vht_cap.vht_supported && have_80mhz) { 1484 if (sband->vht_cap.vht_supported && have_80mhz) {
@@ -1735,6 +1740,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1735 struct cfg80211_sched_scan_request *sched_scan_req; 1740 struct cfg80211_sched_scan_request *sched_scan_req;
1736 bool sched_scan_stopped = false; 1741 bool sched_scan_stopped = false;
1737 1742
1743 /* nothing to do if HW shouldn't run */
1744 if (!local->open_count)
1745 goto wake_up;
1746
1738#ifdef CONFIG_PM 1747#ifdef CONFIG_PM
1739 if (local->suspended) 1748 if (local->suspended)
1740 local->resuming = true; 1749 local->resuming = true;
@@ -1756,9 +1765,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1756 reconfig_due_to_wowlan = true; 1765 reconfig_due_to_wowlan = true;
1757 } 1766 }
1758#endif 1767#endif
1759 /* everything else happens only if HW was up & running */
1760 if (!local->open_count)
1761 goto wake_up;
1762 1768
1763 /* 1769 /*
1764 * Upon resume hardware can sometimes be goofy due to 1770 * Upon resume hardware can sometimes be goofy due to
@@ -2042,7 +2048,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
2042 * If this is for hw restart things are still running. 2048 * If this is for hw restart things are still running.
2043 * We may want to change that later, however. 2049 * We may want to change that later, however.
2044 */ 2050 */
2045 if (!local->suspended || reconfig_due_to_wowlan) 2051 if (local->open_count && (!local->suspended || reconfig_due_to_wowlan))
2046 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART); 2052 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART);
2047 2053
2048 if (!local->suspended) 2054 if (!local->suspended)
@@ -2054,7 +2060,19 @@ int ieee80211_reconfig(struct ieee80211_local *local)
2054 mb(); 2060 mb();
2055 local->resuming = false; 2061 local->resuming = false;
2056 2062
2057 if (!reconfig_due_to_wowlan) 2063 /* It's possible that we don't handle the scan completion in
2064 * time during suspend, so if it's still marked as completed
2065 * here, queue the work and flush it to clean things up.
2066 * Instead of calling the worker function directly here, we
2067 * really queue it to avoid potential races with other flows
2068 * scheduling the same work.
2069 */
2070 if (test_bit(SCAN_COMPLETED, &local->scanning)) {
2071 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
2072 flush_delayed_work(&local->scan_work);
2073 }
2074
2075 if (local->open_count && !reconfig_due_to_wowlan)
2058 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND); 2076 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND);
2059 2077
2060 list_for_each_entry(sdata, &local->interfaces, list) { 2078 list_for_each_entry(sdata, &local->interfaces, list) {
@@ -2538,7 +2556,9 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
2538 ri.mcs = status->rate_idx; 2556 ri.mcs = status->rate_idx;
2539 ri.flags |= RATE_INFO_FLAGS_MCS; 2557 ri.flags |= RATE_INFO_FLAGS_MCS;
2540 if (status->flag & RX_FLAG_40MHZ) 2558 if (status->flag & RX_FLAG_40MHZ)
2541 ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 2559 ri.bw = RATE_INFO_BW_40;
2560 else
2561 ri.bw = RATE_INFO_BW_20;
2542 if (status->flag & RX_FLAG_SHORT_GI) 2562 if (status->flag & RX_FLAG_SHORT_GI)
2543 ri.flags |= RATE_INFO_FLAGS_SHORT_GI; 2563 ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
2544 } else if (status->flag & RX_FLAG_VHT) { 2564 } else if (status->flag & RX_FLAG_VHT) {
@@ -2546,13 +2566,13 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
2546 ri.mcs = status->rate_idx; 2566 ri.mcs = status->rate_idx;
2547 ri.nss = status->vht_nss; 2567 ri.nss = status->vht_nss;
2548 if (status->flag & RX_FLAG_40MHZ) 2568 if (status->flag & RX_FLAG_40MHZ)
2549 ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 2569 ri.bw = RATE_INFO_BW_40;
2550 if (status->vht_flag & RX_VHT_FLAG_80MHZ) 2570 else if (status->vht_flag & RX_VHT_FLAG_80MHZ)
2551 ri.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; 2571 ri.bw = RATE_INFO_BW_80;
2552 if (status->vht_flag & RX_VHT_FLAG_80P80MHZ) 2572 else if (status->vht_flag & RX_VHT_FLAG_160MHZ)
2553 ri.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH; 2573 ri.bw = RATE_INFO_BW_160;
2554 if (status->vht_flag & RX_VHT_FLAG_160MHZ) 2574 else
2555 ri.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; 2575 ri.bw = RATE_INFO_BW_20;
2556 if (status->flag & RX_FLAG_SHORT_GI) 2576 if (status->flag & RX_FLAG_SHORT_GI)
2557 ri.flags |= RATE_INFO_FLAGS_SHORT_GI; 2577 ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
2558 } else { 2578 } else {
@@ -2560,10 +2580,15 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
2560 int shift = 0; 2580 int shift = 0;
2561 int bitrate; 2581 int bitrate;
2562 2582
2563 if (status->flag & RX_FLAG_10MHZ) 2583 if (status->flag & RX_FLAG_10MHZ) {
2564 shift = 1; 2584 shift = 1;
2565 if (status->flag & RX_FLAG_5MHZ) 2585 ri.bw = RATE_INFO_BW_10;
2586 } else if (status->flag & RX_FLAG_5MHZ) {
2566 shift = 2; 2587 shift = 2;
2588 ri.bw = RATE_INFO_BW_5;
2589 } else {
2590 ri.bw = RATE_INFO_BW_20;
2591 }
2567 2592
2568 sband = local->hw.wiphy->bands[status->band]; 2593 sband = local->hw.wiphy->bands[status->band];
2569 bitrate = sband->bitrates[status->rate_idx].bitrate; 2594 bitrate = sband->bitrates[status->rate_idx].bitrate;