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) -----BEGIN PGP SIGNATURE----- iQIcBAABCgAGBQJWcAbmAAoJEGt7eEactAAd9Z8P/igt1Xe7sFzRq5pi5+hXKMdp +jaDQsp0SSc2W53puXhMOqfC6zyD7zl41gRv/u7XCq/FHNInkmzDRz7LcXPQV1CR yUxxUTDBZ1nIk9a5uDI9nWuBDh6wlHG0FGl1Ud5bRHcZnPUntO2hk9863rWbTwbJ a+jgP41o41keQll1DogWQtzK7MyaH5h8CaLtKE9cklzZlKz6Arc5beCVRGBV/Iy6 rfe8OzA/nJLjunAvnRt+XfQYxkSroffTvrqw4j2Eb4PrWr/eFMTGojzx1qaHIM2S vZrd3O95KDF0fapsQimJDlkiktHhC1Dyc4AP+pKVOimzFazV6IHw6dmHz1QqvQ+7 fRR/5bvIUtiRgOwvWSxPzbrw8xEogaZP0O2lEsL5IeOeCgOl5SMdcYqqwZaBU3b6 igAMIeMJ5fg7rhLEHregR32V7Ykk7x5cSXK4uXIq5FlNOzHKE5oY8J4PU9Uwn5/w v22ikTDBOBAelSYTlzNsWHggJ4yKtvGlO4vwpqcOlPG/uroPRbS/mYgjlrtLCBcX XWS6mksVNKrb5nmCEd0GxmOp7ZlMXt4Ut8hE8e0eL1jcghs1rJ59z2Xf9zZDfSDN hVmkzS2UPcQwnpwk6UtNsv3RyxgI57ekZx30wrz+U0gvcW25Nf67NnVCspApvy09 IWu1FPVST14NX+ibsKsf =z3WR -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
4d4f37910b
|
@ -1169,8 +1169,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
||||||
* rc isn't initialized here yet, so ignore it
|
* rc isn't initialized here yet, so ignore it
|
||||||
*/
|
*/
|
||||||
__ieee80211_vht_handle_opmode(sdata, sta,
|
__ieee80211_vht_handle_opmode(sdata, sta,
|
||||||
params->opmode_notif,
|
params->opmode_notif, band);
|
||||||
band, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ieee80211_vif_is_mesh(&sdata->vif))
|
if (ieee80211_vif_is_mesh(&sdata->vif))
|
||||||
|
|
|
@ -1709,10 +1709,10 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta);
|
||||||
void ieee80211_sta_set_rx_nss(struct sta_info *sta);
|
void ieee80211_sta_set_rx_nss(struct sta_info *sta);
|
||||||
u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
||||||
struct sta_info *sta, u8 opmode,
|
struct sta_info *sta, u8 opmode,
|
||||||
enum ieee80211_band band, bool nss_only);
|
enum ieee80211_band band);
|
||||||
void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
||||||
struct sta_info *sta, u8 opmode,
|
struct sta_info *sta, u8 opmode,
|
||||||
enum ieee80211_band band, bool nss_only);
|
enum ieee80211_band band);
|
||||||
void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,
|
void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,
|
||||||
struct ieee80211_sta_vht_cap *vht_cap);
|
struct ieee80211_sta_vht_cap *vht_cap);
|
||||||
void ieee80211_get_vht_mask_from_cap(__le16 vht_cap,
|
void ieee80211_get_vht_mask_from_cap(__le16 vht_cap,
|
||||||
|
|
|
@ -1379,21 +1379,26 @@ static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
|
||||||
*/
|
*/
|
||||||
if (has_80211h_pwr &&
|
if (has_80211h_pwr &&
|
||||||
(!has_cisco_pwr || pwr_level_80211h <= pwr_level_cisco)) {
|
(!has_cisco_pwr || pwr_level_80211h <= pwr_level_cisco)) {
|
||||||
|
new_ap_level = pwr_level_80211h;
|
||||||
|
|
||||||
|
if (sdata->ap_power_level == new_ap_level)
|
||||||
|
return 0;
|
||||||
|
|
||||||
sdata_dbg(sdata,
|
sdata_dbg(sdata,
|
||||||
"Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n",
|
"Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n",
|
||||||
pwr_level_80211h, chan_pwr, pwr_reduction_80211h,
|
pwr_level_80211h, chan_pwr, pwr_reduction_80211h,
|
||||||
sdata->u.mgd.bssid);
|
sdata->u.mgd.bssid);
|
||||||
new_ap_level = pwr_level_80211h;
|
|
||||||
} else { /* has_cisco_pwr is always true here. */
|
} else { /* has_cisco_pwr is always true here. */
|
||||||
|
new_ap_level = pwr_level_cisco;
|
||||||
|
|
||||||
|
if (sdata->ap_power_level == new_ap_level)
|
||||||
|
return 0;
|
||||||
|
|
||||||
sdata_dbg(sdata,
|
sdata_dbg(sdata,
|
||||||
"Limiting TX power to %d dBm as advertised by %pM\n",
|
"Limiting TX power to %d dBm as advertised by %pM\n",
|
||||||
pwr_level_cisco, sdata->u.mgd.bssid);
|
pwr_level_cisco, sdata->u.mgd.bssid);
|
||||||
new_ap_level = pwr_level_cisco;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdata->ap_power_level == new_ap_level)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
sdata->ap_power_level = new_ap_level;
|
sdata->ap_power_level = new_ap_level;
|
||||||
if (__ieee80211_recalc_txpower(sdata))
|
if (__ieee80211_recalc_txpower(sdata))
|
||||||
return BSS_CHANGED_TXPOWER;
|
return BSS_CHANGED_TXPOWER;
|
||||||
|
@ -3575,7 +3580,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
||||||
|
|
||||||
if (sta && elems.opmode_notif)
|
if (sta && elems.opmode_notif)
|
||||||
ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif,
|
ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif,
|
||||||
rx_status->band, true);
|
rx_status->band);
|
||||||
mutex_unlock(&local->sta_mtx);
|
mutex_unlock(&local->sta_mtx);
|
||||||
|
|
||||||
changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt,
|
changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt,
|
||||||
|
|
|
@ -2736,8 +2736,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
||||||
opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode;
|
opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode;
|
||||||
|
|
||||||
ieee80211_vht_handle_opmode(rx->sdata, rx->sta,
|
ieee80211_vht_handle_opmode(rx->sdata, rx->sta,
|
||||||
opmode, status->band,
|
opmode, status->band);
|
||||||
false);
|
|
||||||
goto handled;
|
goto handled;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1641,6 +1641,29 @@ void ieee80211_stop_device(struct ieee80211_local *local)
|
||||||
drv_stop(local);
|
drv_stop(local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ieee80211_flush_completed_scan(struct ieee80211_local *local,
|
||||||
|
bool aborted)
|
||||||
|
{
|
||||||
|
/* It's possible that we don't handle the scan completion in
|
||||||
|
* time during suspend, so if it's still marked as completed
|
||||||
|
* here, queue the work and flush it to clean things up.
|
||||||
|
* Instead of calling the worker function directly here, we
|
||||||
|
* really queue it to avoid potential races with other flows
|
||||||
|
* scheduling the same work.
|
||||||
|
*/
|
||||||
|
if (test_bit(SCAN_COMPLETED, &local->scanning)) {
|
||||||
|
/* If coming from reconfiguration failure, abort the scan so
|
||||||
|
* we don't attempt to continue a partial HW scan - which is
|
||||||
|
* possible otherwise if (e.g.) the 2.4 GHz portion was the
|
||||||
|
* completed scan, and a 5 GHz portion is still pending.
|
||||||
|
*/
|
||||||
|
if (aborted)
|
||||||
|
set_bit(SCAN_ABORTED, &local->scanning);
|
||||||
|
ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
|
||||||
|
flush_delayed_work(&local->scan_work);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
|
static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
|
||||||
{
|
{
|
||||||
struct ieee80211_sub_if_data *sdata;
|
struct ieee80211_sub_if_data *sdata;
|
||||||
|
@ -1660,6 +1683,8 @@ static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
|
||||||
local->suspended = false;
|
local->suspended = false;
|
||||||
local->in_reconfig = false;
|
local->in_reconfig = false;
|
||||||
|
|
||||||
|
ieee80211_flush_completed_scan(local, true);
|
||||||
|
|
||||||
/* scheduled scan clearly can't be running any more, but tell
|
/* scheduled scan clearly can't be running any more, but tell
|
||||||
* cfg80211 and clear local state
|
* cfg80211 and clear local state
|
||||||
*/
|
*/
|
||||||
|
@ -1698,6 +1723,27 @@ static void ieee80211_assign_chanctx(struct ieee80211_local *local,
|
||||||
mutex_unlock(&local->chanctx_mtx);
|
mutex_unlock(&local->chanctx_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ieee80211_reconfig_stations(struct ieee80211_sub_if_data *sdata)
|
||||||
|
{
|
||||||
|
struct ieee80211_local *local = sdata->local;
|
||||||
|
struct sta_info *sta;
|
||||||
|
|
||||||
|
/* add STAs back */
|
||||||
|
mutex_lock(&local->sta_mtx);
|
||||||
|
list_for_each_entry(sta, &local->sta_list, list) {
|
||||||
|
enum ieee80211_sta_state state;
|
||||||
|
|
||||||
|
if (!sta->uploaded || sta->sdata != sdata)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (state = IEEE80211_STA_NOTEXIST;
|
||||||
|
state < sta->sta_state; state++)
|
||||||
|
WARN_ON(drv_sta_state(local, sta->sdata, sta, state,
|
||||||
|
state + 1));
|
||||||
|
}
|
||||||
|
mutex_unlock(&local->sta_mtx);
|
||||||
|
}
|
||||||
|
|
||||||
int ieee80211_reconfig(struct ieee80211_local *local)
|
int ieee80211_reconfig(struct ieee80211_local *local)
|
||||||
{
|
{
|
||||||
struct ieee80211_hw *hw = &local->hw;
|
struct ieee80211_hw *hw = &local->hw;
|
||||||
|
@ -1833,50 +1879,11 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
||||||
WARN_ON(drv_add_chanctx(local, ctx));
|
WARN_ON(drv_add_chanctx(local, ctx));
|
||||||
mutex_unlock(&local->chanctx_mtx);
|
mutex_unlock(&local->chanctx_mtx);
|
||||||
|
|
||||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
|
||||||
if (!ieee80211_sdata_running(sdata))
|
|
||||||
continue;
|
|
||||||
ieee80211_assign_chanctx(local, sdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
sdata = rtnl_dereference(local->monitor_sdata);
|
sdata = rtnl_dereference(local->monitor_sdata);
|
||||||
if (sdata && ieee80211_sdata_running(sdata))
|
if (sdata && ieee80211_sdata_running(sdata))
|
||||||
ieee80211_assign_chanctx(local, sdata);
|
ieee80211_assign_chanctx(local, sdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add STAs back */
|
|
||||||
mutex_lock(&local->sta_mtx);
|
|
||||||
list_for_each_entry(sta, &local->sta_list, list) {
|
|
||||||
enum ieee80211_sta_state state;
|
|
||||||
|
|
||||||
if (!sta->uploaded)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* AP-mode stations will be added later */
|
|
||||||
if (sta->sdata->vif.type == NL80211_IFTYPE_AP)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (state = IEEE80211_STA_NOTEXIST;
|
|
||||||
state < sta->sta_state; state++)
|
|
||||||
WARN_ON(drv_sta_state(local, sta->sdata, sta, state,
|
|
||||||
state + 1));
|
|
||||||
}
|
|
||||||
mutex_unlock(&local->sta_mtx);
|
|
||||||
|
|
||||||
/* reconfigure tx conf */
|
|
||||||
if (hw->queues >= IEEE80211_NUM_ACS) {
|
|
||||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
|
|
||||||
sdata->vif.type == NL80211_IFTYPE_MONITOR ||
|
|
||||||
!ieee80211_sdata_running(sdata))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (i = 0; i < IEEE80211_NUM_ACS; i++)
|
|
||||||
drv_conf_tx(local, sdata, i,
|
|
||||||
&sdata->tx_conf[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reconfigure hardware */
|
/* reconfigure hardware */
|
||||||
ieee80211_hw_config(local, ~0);
|
ieee80211_hw_config(local, ~0);
|
||||||
|
|
||||||
|
@ -1889,6 +1896,22 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
||||||
if (!ieee80211_sdata_running(sdata))
|
if (!ieee80211_sdata_running(sdata))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
ieee80211_assign_chanctx(local, sdata);
|
||||||
|
|
||||||
|
switch (sdata->vif.type) {
|
||||||
|
case NL80211_IFTYPE_AP_VLAN:
|
||||||
|
case NL80211_IFTYPE_MONITOR:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ieee80211_reconfig_stations(sdata);
|
||||||
|
/* fall through */
|
||||||
|
case NL80211_IFTYPE_AP: /* AP stations are handled later */
|
||||||
|
for (i = 0; i < IEEE80211_NUM_ACS; i++)
|
||||||
|
drv_conf_tx(local, sdata, i,
|
||||||
|
&sdata->tx_conf[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* common change flags for all interface types */
|
/* common change flags for all interface types */
|
||||||
changed = BSS_CHANGED_ERP_CTS_PROT |
|
changed = BSS_CHANGED_ERP_CTS_PROT |
|
||||||
BSS_CHANGED_ERP_PREAMBLE |
|
BSS_CHANGED_ERP_PREAMBLE |
|
||||||
|
@ -2074,17 +2097,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
||||||
mb();
|
mb();
|
||||||
local->resuming = false;
|
local->resuming = false;
|
||||||
|
|
||||||
/* It's possible that we don't handle the scan completion in
|
ieee80211_flush_completed_scan(local, false);
|
||||||
* time during suspend, so if it's still marked as completed
|
|
||||||
* here, queue the work and flush it to clean things up.
|
|
||||||
* Instead of calling the worker function directly here, we
|
|
||||||
* really queue it to avoid potential races with other flows
|
|
||||||
* scheduling the same work.
|
|
||||||
*/
|
|
||||||
if (test_bit(SCAN_COMPLETED, &local->scanning)) {
|
|
||||||
ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
|
|
||||||
flush_delayed_work(&local->scan_work);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (local->open_count && !reconfig_due_to_wowlan)
|
if (local->open_count && !reconfig_due_to_wowlan)
|
||||||
drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND);
|
drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND);
|
||||||
|
|
|
@ -378,7 +378,7 @@ void ieee80211_sta_set_rx_nss(struct sta_info *sta)
|
||||||
|
|
||||||
u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
||||||
struct sta_info *sta, u8 opmode,
|
struct sta_info *sta, u8 opmode,
|
||||||
enum ieee80211_band band, bool nss_only)
|
enum ieee80211_band band)
|
||||||
{
|
{
|
||||||
struct ieee80211_local *local = sdata->local;
|
struct ieee80211_local *local = sdata->local;
|
||||||
struct ieee80211_supported_band *sband;
|
struct ieee80211_supported_band *sband;
|
||||||
|
@ -401,9 +401,6 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
||||||
changed |= IEEE80211_RC_NSS_CHANGED;
|
changed |= IEEE80211_RC_NSS_CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nss_only)
|
|
||||||
return changed;
|
|
||||||
|
|
||||||
switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) {
|
switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) {
|
||||||
case IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ:
|
case IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ:
|
||||||
sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_20;
|
sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_20;
|
||||||
|
@ -430,13 +427,12 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
||||||
|
|
||||||
void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
||||||
struct sta_info *sta, u8 opmode,
|
struct sta_info *sta, u8 opmode,
|
||||||
enum ieee80211_band band, bool nss_only)
|
enum ieee80211_band band)
|
||||||
{
|
{
|
||||||
struct ieee80211_local *local = sdata->local;
|
struct ieee80211_local *local = sdata->local;
|
||||||
struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
|
struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
|
||||||
|
|
||||||
u32 changed = __ieee80211_vht_handle_opmode(sdata, sta, opmode,
|
u32 changed = __ieee80211_vht_handle_opmode(sdata, sta, opmode, band);
|
||||||
band, nss_only);
|
|
||||||
|
|
||||||
if (changed > 0)
|
if (changed > 0)
|
||||||
rate_control_rate_update(local, sband, sta, changed);
|
rate_control_rate_update(local, sband, sta, changed);
|
||||||
|
|
|
@ -49,7 +49,6 @@
|
||||||
struct rfkill {
|
struct rfkill {
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
|
|
||||||
const char *name;
|
|
||||||
enum rfkill_type type;
|
enum rfkill_type type;
|
||||||
|
|
||||||
unsigned long state;
|
unsigned long state;
|
||||||
|
@ -73,6 +72,7 @@ struct rfkill {
|
||||||
struct delayed_work poll_work;
|
struct delayed_work poll_work;
|
||||||
struct work_struct uevent_work;
|
struct work_struct uevent_work;
|
||||||
struct work_struct sync_work;
|
struct work_struct sync_work;
|
||||||
|
char name[];
|
||||||
};
|
};
|
||||||
#define to_rfkill(d) container_of(d, struct rfkill, dev)
|
#define to_rfkill(d) container_of(d, struct rfkill, dev)
|
||||||
|
|
||||||
|
@ -876,14 +876,14 @@ struct rfkill * __must_check rfkill_alloc(const char *name,
|
||||||
if (WARN_ON(type == RFKILL_TYPE_ALL || type >= NUM_RFKILL_TYPES))
|
if (WARN_ON(type == RFKILL_TYPE_ALL || type >= NUM_RFKILL_TYPES))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL);
|
rfkill = kzalloc(sizeof(*rfkill) + strlen(name) + 1, GFP_KERNEL);
|
||||||
if (!rfkill)
|
if (!rfkill)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
spin_lock_init(&rfkill->lock);
|
spin_lock_init(&rfkill->lock);
|
||||||
INIT_LIST_HEAD(&rfkill->node);
|
INIT_LIST_HEAD(&rfkill->node);
|
||||||
rfkill->type = type;
|
rfkill->type = type;
|
||||||
rfkill->name = name;
|
strcpy(rfkill->name, name);
|
||||||
rfkill->ops = ops;
|
rfkill->ops = ops;
|
||||||
rfkill->data = ops_data;
|
rfkill->data = ops_data;
|
||||||
|
|
||||||
|
|
|
@ -7941,8 +7941,10 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
|
||||||
if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
|
if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
|
||||||
if (!(rdev->wiphy.features &
|
if (!(rdev->wiphy.features &
|
||||||
NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) ||
|
NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) ||
|
||||||
!(rdev->wiphy.features & NL80211_FEATURE_QUIET))
|
!(rdev->wiphy.features & NL80211_FEATURE_QUIET)) {
|
||||||
|
kzfree(connkeys);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
connect.flags |= ASSOC_REQ_USE_RRM;
|
connect.flags |= ASSOC_REQ_USE_RRM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9503,6 +9505,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
|
||||||
if (new_triggers.tcp && new_triggers.tcp->sock)
|
if (new_triggers.tcp && new_triggers.tcp->sock)
|
||||||
sock_release(new_triggers.tcp->sock);
|
sock_release(new_triggers.tcp->sock);
|
||||||
kfree(new_triggers.tcp);
|
kfree(new_triggers.tcp);
|
||||||
|
kfree(new_triggers.nd_config);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3029,6 +3029,7 @@ int set_regdom(const struct ieee80211_regdomain *rd,
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WARN(1, "invalid initiator %d\n", lr->initiator);
|
WARN(1, "invalid initiator %d\n", lr->initiator);
|
||||||
|
kfree(rd);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3221,8 +3222,10 @@ int __init regulatory_init(void)
|
||||||
/* We always try to get an update for the static regdomain */
|
/* We always try to get an update for the static regdomain */
|
||||||
err = regulatory_hint_core(cfg80211_world_regdom->alpha2);
|
err = regulatory_hint_core(cfg80211_world_regdom->alpha2);
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err == -ENOMEM)
|
if (err == -ENOMEM) {
|
||||||
|
platform_device_unregister(reg_pdev);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* N.B. kobject_uevent_env() can fail mainly for when we're out
|
* N.B. kobject_uevent_env() can fail mainly for when we're out
|
||||||
* memory which is handled and propagated appropriately above
|
* memory which is handled and propagated appropriately above
|
||||||
|
|
Loading…
Reference in New Issue