Commit ead0ad16 authored by John W. Linville's avatar John W. Linville
parents cb4ec37d 8680451f
...@@ -164,7 +164,17 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, ...@@ -164,7 +164,17 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
sta = sta_info_get(sdata, mac_addr); sta = sta_info_get(sdata, mac_addr);
else else
sta = sta_info_get_bss(sdata, mac_addr); sta = sta_info_get_bss(sdata, mac_addr);
if (!sta) { /*
* The ASSOC test makes sure the driver is ready to
* receive the key. When wpa_supplicant has roamed
* using FT, it attempts to set the key before
* association has completed, this rejects that attempt
* so it will set the key again after assocation.
*
* TODO: accept the key if we have a station entry and
* add it to the device after the station.
*/
if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) {
ieee80211_key_free(sdata->local, key); ieee80211_key_free(sdata->local, key);
err = -ENOENT; err = -ENOENT;
goto out_unlock; goto out_unlock;
......
...@@ -1358,10 +1358,8 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata); ...@@ -1358,10 +1358,8 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata);
void ieee80211_sched_scan_stopped_work(struct work_struct *work); void ieee80211_sched_scan_stopped_work(struct work_struct *work);
/* off-channel helpers */ /* off-channel helpers */
void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local);
bool offchannel_ps_enable); void ieee80211_offchannel_return(struct ieee80211_local *local);
void ieee80211_offchannel_return(struct ieee80211_local *local,
bool offchannel_ps_disable);
void ieee80211_roc_setup(struct ieee80211_local *local); void ieee80211_roc_setup(struct ieee80211_local *local);
void ieee80211_start_next_roc(struct ieee80211_local *local); void ieee80211_start_next_roc(struct ieee80211_local *local);
void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata);
......
...@@ -215,6 +215,7 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata, ...@@ -215,6 +215,7 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata,
skb->priority = 7; skb->priority = 7;
info->control.vif = &sdata->vif; info->control.vif = &sdata->vif;
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
ieee80211_set_qos_hdr(sdata, skb); ieee80211_set_qos_hdr(sdata, skb);
} }
...@@ -246,11 +247,13 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, ...@@ -246,11 +247,13 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
return -EAGAIN; return -EAGAIN;
skb = dev_alloc_skb(local->tx_headroom + skb = dev_alloc_skb(local->tx_headroom +
IEEE80211_ENCRYPT_HEADROOM +
IEEE80211_ENCRYPT_TAILROOM +
hdr_len + hdr_len +
2 + 15 /* PERR IE */); 2 + 15 /* PERR IE */);
if (!skb) if (!skb)
return -1; return -1;
skb_reserve(skb, local->tx_headroom); skb_reserve(skb, local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM);
mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
memset(mgmt, 0, hdr_len); memset(mgmt, 0, hdr_len);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
......
...@@ -102,8 +102,7 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata) ...@@ -102,8 +102,7 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
ieee80211_sta_reset_conn_monitor(sdata); ieee80211_sta_reset_conn_monitor(sdata);
} }
void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
bool offchannel_ps_enable)
{ {
struct ieee80211_sub_if_data *sdata; struct ieee80211_sub_if_data *sdata;
...@@ -134,8 +133,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, ...@@ -134,8 +133,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
netif_tx_stop_all_queues(sdata->dev); netif_tx_stop_all_queues(sdata->dev);
if (offchannel_ps_enable && if (sdata->vif.type == NL80211_IFTYPE_STATION &&
(sdata->vif.type == NL80211_IFTYPE_STATION) &&
sdata->u.mgd.associated) sdata->u.mgd.associated)
ieee80211_offchannel_ps_enable(sdata); ieee80211_offchannel_ps_enable(sdata);
} }
...@@ -143,8 +141,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, ...@@ -143,8 +141,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
mutex_unlock(&local->iflist_mtx); mutex_unlock(&local->iflist_mtx);
} }
void ieee80211_offchannel_return(struct ieee80211_local *local, void ieee80211_offchannel_return(struct ieee80211_local *local)
bool offchannel_ps_disable)
{ {
struct ieee80211_sub_if_data *sdata; struct ieee80211_sub_if_data *sdata;
...@@ -163,11 +160,9 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, ...@@ -163,11 +160,9 @@ void ieee80211_offchannel_return(struct ieee80211_local *local,
continue; continue;
/* Tell AP we're back */ /* Tell AP we're back */
if (offchannel_ps_disable && if (sdata->vif.type == NL80211_IFTYPE_STATION &&
sdata->vif.type == NL80211_IFTYPE_STATION) { sdata->u.mgd.associated)
if (sdata->u.mgd.associated) ieee80211_offchannel_ps_disable(sdata);
ieee80211_offchannel_ps_disable(sdata);
}
if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
/* /*
...@@ -385,7 +380,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) ...@@ -385,7 +380,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
local->tmp_channel = NULL; local->tmp_channel = NULL;
ieee80211_hw_config(local, 0); ieee80211_hw_config(local, 0);
ieee80211_offchannel_return(local, true); ieee80211_offchannel_return(local);
} }
ieee80211_recalc_idle(local); ieee80211_recalc_idle(local);
......
...@@ -292,7 +292,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, ...@@ -292,7 +292,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
if (!was_hw_scan) { if (!was_hw_scan) {
ieee80211_configure_filter(local); ieee80211_configure_filter(local);
drv_sw_scan_complete(local); drv_sw_scan_complete(local);
ieee80211_offchannel_return(local, true); ieee80211_offchannel_return(local);
} }
ieee80211_recalc_idle(local); ieee80211_recalc_idle(local);
...@@ -341,7 +341,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) ...@@ -341,7 +341,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
local->next_scan_state = SCAN_DECISION; local->next_scan_state = SCAN_DECISION;
local->scan_channel_idx = 0; local->scan_channel_idx = 0;
ieee80211_offchannel_stop_vifs(local, true); ieee80211_offchannel_stop_vifs(local);
ieee80211_configure_filter(local); ieee80211_configure_filter(local);
...@@ -678,12 +678,8 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local, ...@@ -678,12 +678,8 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
local->scan_channel = NULL; local->scan_channel = NULL;
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
/* /* disable PS */
* Re-enable vifs and beaconing. Leave PS ieee80211_offchannel_return(local);
* in off-channel state..will put that back
* on-channel at the end of scanning.
*/
ieee80211_offchannel_return(local, false);
*next_delay = HZ / 5; *next_delay = HZ / 5;
/* afterwards, resume scan & go to next channel */ /* afterwards, resume scan & go to next channel */
...@@ -693,8 +689,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local, ...@@ -693,8 +689,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
static void ieee80211_scan_state_resume(struct ieee80211_local *local, static void ieee80211_scan_state_resume(struct ieee80211_local *local,
unsigned long *next_delay) unsigned long *next_delay)
{ {
/* PS already is in off-channel mode */ ieee80211_offchannel_stop_vifs(local);
ieee80211_offchannel_stop_vifs(local, false);
if (local->ops->flush) { if (local->ops->flush) {
drv_flush(local, false); drv_flush(local, false);
......
...@@ -1673,10 +1673,13 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, ...@@ -1673,10 +1673,13 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
chanctx_conf = chanctx_conf =
rcu_dereference(tmp_sdata->vif.chanctx_conf); rcu_dereference(tmp_sdata->vif.chanctx_conf);
} }
if (!chanctx_conf)
goto fail_rcu;
chan = chanctx_conf->def.chan; if (chanctx_conf)
chan = chanctx_conf->def.chan;
else if (!local->use_chanctx)
chan = local->_oper_channel;
else
goto fail_rcu;
/* /*
* Frame injection is not allowed if beaconing is not allowed * Frame injection is not allowed if beaconing is not allowed
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment