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.c120
1 files changed, 68 insertions, 52 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 74058020b7d6..3943d4bf289c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -288,10 +288,13 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
288 if (!test_bit(reason, &local->queue_stop_reasons[queue])) 288 if (!test_bit(reason, &local->queue_stop_reasons[queue]))
289 return; 289 return;
290 290
291 if (!refcounted) 291 if (!refcounted) {
292 local->q_stop_reasons[queue][reason] = 0; 292 local->q_stop_reasons[queue][reason] = 0;
293 else 293 } else {
294 local->q_stop_reasons[queue][reason]--; 294 local->q_stop_reasons[queue][reason]--;
295 if (WARN_ON(local->q_stop_reasons[queue][reason] < 0))
296 local->q_stop_reasons[queue][reason] = 0;
297 }
295 298
296 if (local->q_stop_reasons[queue][reason] == 0) 299 if (local->q_stop_reasons[queue][reason] == 0)
297 __clear_bit(reason, &local->queue_stop_reasons[queue]); 300 __clear_bit(reason, &local->queue_stop_reasons[queue]);
@@ -1641,6 +1644,29 @@ void ieee80211_stop_device(struct ieee80211_local *local)
1641 drv_stop(local); 1644 drv_stop(local);
1642} 1645}
1643 1646
1647static void ieee80211_flush_completed_scan(struct ieee80211_local *local,
1648 bool aborted)
1649{
1650 /* It's possible that we don't handle the scan completion in
1651 * time during suspend, so if it's still marked as completed
1652 * here, queue the work and flush it to clean things up.
1653 * Instead of calling the worker function directly here, we
1654 * really queue it to avoid potential races with other flows
1655 * scheduling the same work.
1656 */
1657 if (test_bit(SCAN_COMPLETED, &local->scanning)) {
1658 /* If coming from reconfiguration failure, abort the scan so
1659 * we don't attempt to continue a partial HW scan - which is
1660 * possible otherwise if (e.g.) the 2.4 GHz portion was the
1661 * completed scan, and a 5 GHz portion is still pending.
1662 */
1663 if (aborted)
1664 set_bit(SCAN_ABORTED, &local->scanning);
1665 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
1666 flush_delayed_work(&local->scan_work);
1667 }
1668}
1669
1644static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local) 1670static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
1645{ 1671{
1646 struct ieee80211_sub_if_data *sdata; 1672 struct ieee80211_sub_if_data *sdata;
@@ -1660,6 +1686,8 @@ static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
1660 local->suspended = false; 1686 local->suspended = false;
1661 local->in_reconfig = false; 1687 local->in_reconfig = false;
1662 1688
1689 ieee80211_flush_completed_scan(local, true);
1690
1663 /* scheduled scan clearly can't be running any more, but tell 1691 /* scheduled scan clearly can't be running any more, but tell
1664 * cfg80211 and clear local state 1692 * cfg80211 and clear local state
1665 */ 1693 */
@@ -1698,6 +1726,27 @@ static void ieee80211_assign_chanctx(struct ieee80211_local *local,
1698 mutex_unlock(&local->chanctx_mtx); 1726 mutex_unlock(&local->chanctx_mtx);
1699} 1727}
1700 1728
1729static void ieee80211_reconfig_stations(struct ieee80211_sub_if_data *sdata)
1730{
1731 struct ieee80211_local *local = sdata->local;
1732 struct sta_info *sta;
1733
1734 /* add STAs back */
1735 mutex_lock(&local->sta_mtx);
1736 list_for_each_entry(sta, &local->sta_list, list) {
1737 enum ieee80211_sta_state state;
1738
1739 if (!sta->uploaded || sta->sdata != sdata)
1740 continue;
1741
1742 for (state = IEEE80211_STA_NOTEXIST;
1743 state < sta->sta_state; state++)
1744 WARN_ON(drv_sta_state(local, sta->sdata, sta, state,
1745 state + 1));
1746 }
1747 mutex_unlock(&local->sta_mtx);
1748}
1749
1701int ieee80211_reconfig(struct ieee80211_local *local) 1750int ieee80211_reconfig(struct ieee80211_local *local)
1702{ 1751{
1703 struct ieee80211_hw *hw = &local->hw; 1752 struct ieee80211_hw *hw = &local->hw;
@@ -1833,50 +1882,11 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1833 WARN_ON(drv_add_chanctx(local, ctx)); 1882 WARN_ON(drv_add_chanctx(local, ctx));
1834 mutex_unlock(&local->chanctx_mtx); 1883 mutex_unlock(&local->chanctx_mtx);
1835 1884
1836 list_for_each_entry(sdata, &local->interfaces, list) {
1837 if (!ieee80211_sdata_running(sdata))
1838 continue;
1839 ieee80211_assign_chanctx(local, sdata);
1840 }
1841
1842 sdata = rtnl_dereference(local->monitor_sdata); 1885 sdata = rtnl_dereference(local->monitor_sdata);
1843 if (sdata && ieee80211_sdata_running(sdata)) 1886 if (sdata && ieee80211_sdata_running(sdata))
1844 ieee80211_assign_chanctx(local, sdata); 1887 ieee80211_assign_chanctx(local, sdata);
1845 } 1888 }
1846 1889
1847 /* add STAs back */
1848 mutex_lock(&local->sta_mtx);
1849 list_for_each_entry(sta, &local->sta_list, list) {
1850 enum ieee80211_sta_state state;
1851
1852 if (!sta->uploaded)
1853 continue;
1854
1855 /* AP-mode stations will be added later */
1856 if (sta->sdata->vif.type == NL80211_IFTYPE_AP)
1857 continue;
1858
1859 for (state = IEEE80211_STA_NOTEXIST;
1860 state < sta->sta_state; state++)
1861 WARN_ON(drv_sta_state(local, sta->sdata, sta, state,
1862 state + 1));
1863 }
1864 mutex_unlock(&local->sta_mtx);
1865
1866 /* reconfigure tx conf */
1867 if (hw->queues >= IEEE80211_NUM_ACS) {
1868 list_for_each_entry(sdata, &local->interfaces, list) {
1869 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
1870 sdata->vif.type == NL80211_IFTYPE_MONITOR ||
1871 !ieee80211_sdata_running(sdata))
1872 continue;
1873
1874 for (i = 0; i < IEEE80211_NUM_ACS; i++)
1875 drv_conf_tx(local, sdata, i,
1876 &sdata->tx_conf[i]);
1877 }
1878 }
1879
1880 /* reconfigure hardware */ 1890 /* reconfigure hardware */
1881 ieee80211_hw_config(local, ~0); 1891 ieee80211_hw_config(local, ~0);
1882 1892
@@ -1889,6 +1899,22 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1889 if (!ieee80211_sdata_running(sdata)) 1899 if (!ieee80211_sdata_running(sdata))
1890 continue; 1900 continue;
1891 1901
1902 ieee80211_assign_chanctx(local, sdata);
1903
1904 switch (sdata->vif.type) {
1905 case NL80211_IFTYPE_AP_VLAN:
1906 case NL80211_IFTYPE_MONITOR:
1907 break;
1908 default:
1909 ieee80211_reconfig_stations(sdata);
1910 /* fall through */
1911 case NL80211_IFTYPE_AP: /* AP stations are handled later */
1912 for (i = 0; i < IEEE80211_NUM_ACS; i++)
1913 drv_conf_tx(local, sdata, i,
1914 &sdata->tx_conf[i]);
1915 break;
1916 }
1917
1892 /* common change flags for all interface types */ 1918 /* common change flags for all interface types */
1893 changed = BSS_CHANGED_ERP_CTS_PROT | 1919 changed = BSS_CHANGED_ERP_CTS_PROT |
1894 BSS_CHANGED_ERP_PREAMBLE | 1920 BSS_CHANGED_ERP_PREAMBLE |
@@ -2074,17 +2100,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
2074 mb(); 2100 mb();
2075 local->resuming = false; 2101 local->resuming = false;
2076 2102
2077 /* It's possible that we don't handle the scan completion in 2103 ieee80211_flush_completed_scan(local, false);
2078 * time during suspend, so if it's still marked as completed
2079 * here, queue the work and flush it to clean things up.
2080 * Instead of calling the worker function directly here, we
2081 * really queue it to avoid potential races with other flows
2082 * scheduling the same work.
2083 */
2084 if (test_bit(SCAN_COMPLETED, &local->scanning)) {
2085 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
2086 flush_delayed_work(&local->scan_work);
2087 }
2088 2104
2089 if (local->open_count && !reconfig_due_to_wowlan) 2105 if (local->open_count && !reconfig_due_to_wowlan)
2090 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND); 2106 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND);