diff options
author | David S. Miller <davem@davemloft.net> | 2015-12-16 18:33:38 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-12-16 18:33:38 -0500 |
commit | 4d4f37910b8a120e9cf5a436256db84295437ac7 (patch) | |
tree | a197af9b3f0eaaee43b8e268640178ae9d41a350 /net | |
parent | 79aa05a24f01bcb0cfbac3deea4f12d9b4f64ba9 (diff) | |
parent | cf1e05c63642ce65821a6277adfc2157f7334c9d (diff) |
Merge tag 'mac80211-for-davem-2015-12-15' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
Johannes Berg says:
====================
Another set of fixes:
* memory leak fixes (from Ola)
* operating mode notification spec compliance fix (from Eyal)
* copy rfkill names in case pointer becomes invalid (myself)
* two hardware restart fixes (myself)
* get rid of "limiting TX power" log spam (myself)
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/cfg.c | 3 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 4 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 17 | ||||
-rw-r--r-- | net/mac80211/rx.c | 3 | ||||
-rw-r--r-- | net/mac80211/util.c | 113 | ||||
-rw-r--r-- | net/mac80211/vht.c | 10 | ||||
-rw-r--r-- | net/rfkill/core.c | 6 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 5 | ||||
-rw-r--r-- | net/wireless/reg.c | 5 |
9 files changed, 92 insertions, 74 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index da471eef07bb..c12f348138ac 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1169,8 +1169,7 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
1169 | * rc isn't initialized here yet, so ignore it | 1169 | * rc isn't initialized here yet, so ignore it |
1170 | */ | 1170 | */ |
1171 | __ieee80211_vht_handle_opmode(sdata, sta, | 1171 | __ieee80211_vht_handle_opmode(sdata, sta, |
1172 | params->opmode_notif, | 1172 | params->opmode_notif, band); |
1173 | band, false); | ||
1174 | } | 1173 | } |
1175 | 1174 | ||
1176 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 1175 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index d832bd59236b..5322b4c71630 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1709,10 +1709,10 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta); | |||
1709 | void ieee80211_sta_set_rx_nss(struct sta_info *sta); | 1709 | void ieee80211_sta_set_rx_nss(struct sta_info *sta); |
1710 | u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, | 1710 | u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, |
1711 | struct sta_info *sta, u8 opmode, | 1711 | struct sta_info *sta, u8 opmode, |
1712 | enum ieee80211_band band, bool nss_only); | 1712 | enum ieee80211_band band); |
1713 | void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, | 1713 | void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, |
1714 | struct sta_info *sta, u8 opmode, | 1714 | struct sta_info *sta, u8 opmode, |
1715 | enum ieee80211_band band, bool nss_only); | 1715 | enum ieee80211_band band); |
1716 | void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata, | 1716 | void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata, |
1717 | struct ieee80211_sta_vht_cap *vht_cap); | 1717 | struct ieee80211_sta_vht_cap *vht_cap); |
1718 | void ieee80211_get_vht_mask_from_cap(__le16 vht_cap, | 1718 | void ieee80211_get_vht_mask_from_cap(__le16 vht_cap, |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b140cc6651f4..3aa04344942b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1379,21 +1379,26 @@ static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, | |||
1379 | */ | 1379 | */ |
1380 | if (has_80211h_pwr && | 1380 | if (has_80211h_pwr && |
1381 | (!has_cisco_pwr || pwr_level_80211h <= pwr_level_cisco)) { | 1381 | (!has_cisco_pwr || pwr_level_80211h <= pwr_level_cisco)) { |
1382 | new_ap_level = pwr_level_80211h; | ||
1383 | |||
1384 | if (sdata->ap_power_level == new_ap_level) | ||
1385 | return 0; | ||
1386 | |||
1382 | sdata_dbg(sdata, | 1387 | sdata_dbg(sdata, |
1383 | "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n", | 1388 | "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n", |
1384 | pwr_level_80211h, chan_pwr, pwr_reduction_80211h, | 1389 | pwr_level_80211h, chan_pwr, pwr_reduction_80211h, |
1385 | sdata->u.mgd.bssid); | 1390 | sdata->u.mgd.bssid); |
1386 | new_ap_level = pwr_level_80211h; | ||
1387 | } else { /* has_cisco_pwr is always true here. */ | 1391 | } else { /* has_cisco_pwr is always true here. */ |
1392 | new_ap_level = pwr_level_cisco; | ||
1393 | |||
1394 | if (sdata->ap_power_level == new_ap_level) | ||
1395 | return 0; | ||
1396 | |||
1388 | sdata_dbg(sdata, | 1397 | sdata_dbg(sdata, |
1389 | "Limiting TX power to %d dBm as advertised by %pM\n", | 1398 | "Limiting TX power to %d dBm as advertised by %pM\n", |
1390 | pwr_level_cisco, sdata->u.mgd.bssid); | 1399 | pwr_level_cisco, sdata->u.mgd.bssid); |
1391 | new_ap_level = pwr_level_cisco; | ||
1392 | } | 1400 | } |
1393 | 1401 | ||
1394 | if (sdata->ap_power_level == new_ap_level) | ||
1395 | return 0; | ||
1396 | |||
1397 | sdata->ap_power_level = new_ap_level; | 1402 | sdata->ap_power_level = new_ap_level; |
1398 | if (__ieee80211_recalc_txpower(sdata)) | 1403 | if (__ieee80211_recalc_txpower(sdata)) |
1399 | return BSS_CHANGED_TXPOWER; | 1404 | return BSS_CHANGED_TXPOWER; |
@@ -3575,7 +3580,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3575 | 3580 | ||
3576 | if (sta && elems.opmode_notif) | 3581 | if (sta && elems.opmode_notif) |
3577 | ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif, | 3582 | ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif, |
3578 | rx_status->band, true); | 3583 | rx_status->band); |
3579 | mutex_unlock(&local->sta_mtx); | 3584 | mutex_unlock(&local->sta_mtx); |
3580 | 3585 | ||
3581 | changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt, | 3586 | changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt, |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 8bae5de0dc44..82af407fea7a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -2736,8 +2736,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2736 | opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode; | 2736 | opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode; |
2737 | 2737 | ||
2738 | ieee80211_vht_handle_opmode(rx->sdata, rx->sta, | 2738 | ieee80211_vht_handle_opmode(rx->sdata, rx->sta, |
2739 | opmode, status->band, | 2739 | opmode, status->band); |
2740 | false); | ||
2741 | goto handled; | 2740 | goto handled; |
2742 | } | 2741 | } |
2743 | default: | 2742 | default: |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 74058020b7d6..33344f5a66a8 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1641,6 +1641,29 @@ void ieee80211_stop_device(struct ieee80211_local *local) | |||
1641 | drv_stop(local); | 1641 | drv_stop(local); |
1642 | } | 1642 | } |
1643 | 1643 | ||
1644 | static void ieee80211_flush_completed_scan(struct ieee80211_local *local, | ||
1645 | bool aborted) | ||
1646 | { | ||
1647 | /* It's possible that we don't handle the scan completion in | ||
1648 | * time during suspend, so if it's still marked as completed | ||
1649 | * here, queue the work and flush it to clean things up. | ||
1650 | * Instead of calling the worker function directly here, we | ||
1651 | * really queue it to avoid potential races with other flows | ||
1652 | * scheduling the same work. | ||
1653 | */ | ||
1654 | if (test_bit(SCAN_COMPLETED, &local->scanning)) { | ||
1655 | /* If coming from reconfiguration failure, abort the scan so | ||
1656 | * we don't attempt to continue a partial HW scan - which is | ||
1657 | * possible otherwise if (e.g.) the 2.4 GHz portion was the | ||
1658 | * completed scan, and a 5 GHz portion is still pending. | ||
1659 | */ | ||
1660 | if (aborted) | ||
1661 | set_bit(SCAN_ABORTED, &local->scanning); | ||
1662 | ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); | ||
1663 | flush_delayed_work(&local->scan_work); | ||
1664 | } | ||
1665 | } | ||
1666 | |||
1644 | static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local) | 1667 | static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local) |
1645 | { | 1668 | { |
1646 | struct ieee80211_sub_if_data *sdata; | 1669 | struct ieee80211_sub_if_data *sdata; |
@@ -1660,6 +1683,8 @@ static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local) | |||
1660 | local->suspended = false; | 1683 | local->suspended = false; |
1661 | local->in_reconfig = false; | 1684 | local->in_reconfig = false; |
1662 | 1685 | ||
1686 | ieee80211_flush_completed_scan(local, true); | ||
1687 | |||
1663 | /* scheduled scan clearly can't be running any more, but tell | 1688 | /* scheduled scan clearly can't be running any more, but tell |
1664 | * cfg80211 and clear local state | 1689 | * cfg80211 and clear local state |
1665 | */ | 1690 | */ |
@@ -1698,6 +1723,27 @@ static void ieee80211_assign_chanctx(struct ieee80211_local *local, | |||
1698 | mutex_unlock(&local->chanctx_mtx); | 1723 | mutex_unlock(&local->chanctx_mtx); |
1699 | } | 1724 | } |
1700 | 1725 | ||
1726 | static void ieee80211_reconfig_stations(struct ieee80211_sub_if_data *sdata) | ||
1727 | { | ||
1728 | struct ieee80211_local *local = sdata->local; | ||
1729 | struct sta_info *sta; | ||
1730 | |||
1731 | /* add STAs back */ | ||
1732 | mutex_lock(&local->sta_mtx); | ||
1733 | list_for_each_entry(sta, &local->sta_list, list) { | ||
1734 | enum ieee80211_sta_state state; | ||
1735 | |||
1736 | if (!sta->uploaded || sta->sdata != sdata) | ||
1737 | continue; | ||
1738 | |||
1739 | for (state = IEEE80211_STA_NOTEXIST; | ||
1740 | state < sta->sta_state; state++) | ||
1741 | WARN_ON(drv_sta_state(local, sta->sdata, sta, state, | ||
1742 | state + 1)); | ||
1743 | } | ||
1744 | mutex_unlock(&local->sta_mtx); | ||
1745 | } | ||
1746 | |||
1701 | int ieee80211_reconfig(struct ieee80211_local *local) | 1747 | int ieee80211_reconfig(struct ieee80211_local *local) |
1702 | { | 1748 | { |
1703 | struct ieee80211_hw *hw = &local->hw; | 1749 | struct ieee80211_hw *hw = &local->hw; |
@@ -1833,50 +1879,11 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1833 | WARN_ON(drv_add_chanctx(local, ctx)); | 1879 | WARN_ON(drv_add_chanctx(local, ctx)); |
1834 | mutex_unlock(&local->chanctx_mtx); | 1880 | mutex_unlock(&local->chanctx_mtx); |
1835 | 1881 | ||
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); | 1882 | sdata = rtnl_dereference(local->monitor_sdata); |
1843 | if (sdata && ieee80211_sdata_running(sdata)) | 1883 | if (sdata && ieee80211_sdata_running(sdata)) |
1844 | ieee80211_assign_chanctx(local, sdata); | 1884 | ieee80211_assign_chanctx(local, sdata); |
1845 | } | 1885 | } |
1846 | 1886 | ||
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 */ | 1887 | /* reconfigure hardware */ |
1881 | ieee80211_hw_config(local, ~0); | 1888 | ieee80211_hw_config(local, ~0); |
1882 | 1889 | ||
@@ -1889,6 +1896,22 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1889 | if (!ieee80211_sdata_running(sdata)) | 1896 | if (!ieee80211_sdata_running(sdata)) |
1890 | continue; | 1897 | continue; |
1891 | 1898 | ||
1899 | ieee80211_assign_chanctx(local, sdata); | ||
1900 | |||
1901 | switch (sdata->vif.type) { | ||
1902 | case NL80211_IFTYPE_AP_VLAN: | ||
1903 | case NL80211_IFTYPE_MONITOR: | ||
1904 | break; | ||
1905 | default: | ||
1906 | ieee80211_reconfig_stations(sdata); | ||
1907 | /* fall through */ | ||
1908 | case NL80211_IFTYPE_AP: /* AP stations are handled later */ | ||
1909 | for (i = 0; i < IEEE80211_NUM_ACS; i++) | ||
1910 | drv_conf_tx(local, sdata, i, | ||
1911 | &sdata->tx_conf[i]); | ||
1912 | break; | ||
1913 | } | ||
1914 | |||
1892 | /* common change flags for all interface types */ | 1915 | /* common change flags for all interface types */ |
1893 | changed = BSS_CHANGED_ERP_CTS_PROT | | 1916 | changed = BSS_CHANGED_ERP_CTS_PROT | |
1894 | BSS_CHANGED_ERP_PREAMBLE | | 1917 | BSS_CHANGED_ERP_PREAMBLE | |
@@ -2074,17 +2097,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
2074 | mb(); | 2097 | mb(); |
2075 | local->resuming = false; | 2098 | local->resuming = false; |
2076 | 2099 | ||
2077 | /* It's possible that we don't handle the scan completion in | 2100 | 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 | 2101 | ||
2089 | if (local->open_count && !reconfig_due_to_wowlan) | 2102 | if (local->open_count && !reconfig_due_to_wowlan) |
2090 | drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND); | 2103 | drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND); |
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index ff1c798921a6..c38b2f07a919 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c | |||
@@ -378,7 +378,7 @@ void ieee80211_sta_set_rx_nss(struct sta_info *sta) | |||
378 | 378 | ||
379 | u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, | 379 | u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, |
380 | struct sta_info *sta, u8 opmode, | 380 | struct sta_info *sta, u8 opmode, |
381 | enum ieee80211_band band, bool nss_only) | 381 | enum ieee80211_band band) |
382 | { | 382 | { |
383 | struct ieee80211_local *local = sdata->local; | 383 | struct ieee80211_local *local = sdata->local; |
384 | struct ieee80211_supported_band *sband; | 384 | struct ieee80211_supported_band *sband; |
@@ -401,9 +401,6 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, | |||
401 | changed |= IEEE80211_RC_NSS_CHANGED; | 401 | changed |= IEEE80211_RC_NSS_CHANGED; |
402 | } | 402 | } |
403 | 403 | ||
404 | if (nss_only) | ||
405 | return changed; | ||
406 | |||
407 | switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) { | 404 | switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) { |
408 | case IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ: | 405 | case IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ: |
409 | sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_20; | 406 | sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_20; |
@@ -430,13 +427,12 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, | |||
430 | 427 | ||
431 | void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, | 428 | void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, |
432 | struct sta_info *sta, u8 opmode, | 429 | struct sta_info *sta, u8 opmode, |
433 | enum ieee80211_band band, bool nss_only) | 430 | enum ieee80211_band band) |
434 | { | 431 | { |
435 | struct ieee80211_local *local = sdata->local; | 432 | struct ieee80211_local *local = sdata->local; |
436 | struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; | 433 | struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; |
437 | 434 | ||
438 | u32 changed = __ieee80211_vht_handle_opmode(sdata, sta, opmode, | 435 | u32 changed = __ieee80211_vht_handle_opmode(sdata, sta, opmode, band); |
439 | band, nss_only); | ||
440 | 436 | ||
441 | if (changed > 0) | 437 | if (changed > 0) |
442 | rate_control_rate_update(local, sband, sta, changed); | 438 | rate_control_rate_update(local, sband, sta, changed); |
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index b41e9ea2ffff..f53bf3b6558b 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
@@ -49,7 +49,6 @@ | |||
49 | struct rfkill { | 49 | struct rfkill { |
50 | spinlock_t lock; | 50 | spinlock_t lock; |
51 | 51 | ||
52 | const char *name; | ||
53 | enum rfkill_type type; | 52 | enum rfkill_type type; |
54 | 53 | ||
55 | unsigned long state; | 54 | unsigned long state; |
@@ -73,6 +72,7 @@ struct rfkill { | |||
73 | struct delayed_work poll_work; | 72 | struct delayed_work poll_work; |
74 | struct work_struct uevent_work; | 73 | struct work_struct uevent_work; |
75 | struct work_struct sync_work; | 74 | struct work_struct sync_work; |
75 | char name[]; | ||
76 | }; | 76 | }; |
77 | #define to_rfkill(d) container_of(d, struct rfkill, dev) | 77 | #define to_rfkill(d) container_of(d, struct rfkill, dev) |
78 | 78 | ||
@@ -876,14 +876,14 @@ struct rfkill * __must_check rfkill_alloc(const char *name, | |||
876 | if (WARN_ON(type == RFKILL_TYPE_ALL || type >= NUM_RFKILL_TYPES)) | 876 | if (WARN_ON(type == RFKILL_TYPE_ALL || type >= NUM_RFKILL_TYPES)) |
877 | return NULL; | 877 | return NULL; |
878 | 878 | ||
879 | rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL); | 879 | rfkill = kzalloc(sizeof(*rfkill) + strlen(name) + 1, GFP_KERNEL); |
880 | if (!rfkill) | 880 | if (!rfkill) |
881 | return NULL; | 881 | return NULL; |
882 | 882 | ||
883 | spin_lock_init(&rfkill->lock); | 883 | spin_lock_init(&rfkill->lock); |
884 | INIT_LIST_HEAD(&rfkill->node); | 884 | INIT_LIST_HEAD(&rfkill->node); |
885 | rfkill->type = type; | 885 | rfkill->type = type; |
886 | rfkill->name = name; | 886 | strcpy(rfkill->name, name); |
887 | rfkill->ops = ops; | 887 | rfkill->ops = ops; |
888 | rfkill->data = ops_data; | 888 | rfkill->data = ops_data; |
889 | 889 | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c71e274c810a..75b0d23ee882 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -7941,8 +7941,10 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | |||
7941 | if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) { | 7941 | if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) { |
7942 | if (!(rdev->wiphy.features & | 7942 | if (!(rdev->wiphy.features & |
7943 | NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) || | 7943 | NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) || |
7944 | !(rdev->wiphy.features & NL80211_FEATURE_QUIET)) | 7944 | !(rdev->wiphy.features & NL80211_FEATURE_QUIET)) { |
7945 | kzfree(connkeys); | ||
7945 | return -EINVAL; | 7946 | return -EINVAL; |
7947 | } | ||
7946 | connect.flags |= ASSOC_REQ_USE_RRM; | 7948 | connect.flags |= ASSOC_REQ_USE_RRM; |
7947 | } | 7949 | } |
7948 | 7950 | ||
@@ -9503,6 +9505,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
9503 | if (new_triggers.tcp && new_triggers.tcp->sock) | 9505 | if (new_triggers.tcp && new_triggers.tcp->sock) |
9504 | sock_release(new_triggers.tcp->sock); | 9506 | sock_release(new_triggers.tcp->sock); |
9505 | kfree(new_triggers.tcp); | 9507 | kfree(new_triggers.tcp); |
9508 | kfree(new_triggers.nd_config); | ||
9506 | return err; | 9509 | return err; |
9507 | } | 9510 | } |
9508 | #endif | 9511 | #endif |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 2e8d6f39ed56..06d050da0d94 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -3029,6 +3029,7 @@ int set_regdom(const struct ieee80211_regdomain *rd, | |||
3029 | break; | 3029 | break; |
3030 | default: | 3030 | default: |
3031 | WARN(1, "invalid initiator %d\n", lr->initiator); | 3031 | WARN(1, "invalid initiator %d\n", lr->initiator); |
3032 | kfree(rd); | ||
3032 | return -EINVAL; | 3033 | return -EINVAL; |
3033 | } | 3034 | } |
3034 | 3035 | ||
@@ -3221,8 +3222,10 @@ int __init regulatory_init(void) | |||
3221 | /* We always try to get an update for the static regdomain */ | 3222 | /* We always try to get an update for the static regdomain */ |
3222 | err = regulatory_hint_core(cfg80211_world_regdom->alpha2); | 3223 | err = regulatory_hint_core(cfg80211_world_regdom->alpha2); |
3223 | if (err) { | 3224 | if (err) { |
3224 | if (err == -ENOMEM) | 3225 | if (err == -ENOMEM) { |
3226 | platform_device_unregister(reg_pdev); | ||
3225 | return err; | 3227 | return err; |
3228 | } | ||
3226 | /* | 3229 | /* |
3227 | * N.B. kobject_uevent_env() can fail mainly for when we're out | 3230 | * N.B. kobject_uevent_env() can fail mainly for when we're out |
3228 | * memory which is handled and propagated appropriately above | 3231 | * memory which is handled and propagated appropriately above |