diff options
| -rw-r--r-- | net/mac80211/cfg.c | 12 | ||||
| -rw-r--r-- | net/mac80211/ieee80211_i.h | 6 | ||||
| -rw-r--r-- | net/mac80211/mesh_hwmp.c | 5 | ||||
| -rw-r--r-- | net/mac80211/offchannel.c | 19 | ||||
| -rw-r--r-- | net/mac80211/scan.c | 15 | ||||
| -rw-r--r-- | net/mac80211/tx.c | 9 |
6 files changed, 35 insertions, 31 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 47e0aca614b7..516fbc96feff 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -164,7 +164,17 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
| 164 | sta = sta_info_get(sdata, mac_addr); | 164 | sta = sta_info_get(sdata, mac_addr); |
| 165 | else | 165 | else |
| 166 | sta = sta_info_get_bss(sdata, mac_addr); | 166 | sta = sta_info_get_bss(sdata, mac_addr); |
| 167 | if (!sta) { | 167 | /* |
| 168 | * The ASSOC test makes sure the driver is ready to | ||
| 169 | * receive the key. When wpa_supplicant has roamed | ||
| 170 | * using FT, it attempts to set the key before | ||
| 171 | * association has completed, this rejects that attempt | ||
| 172 | * so it will set the key again after assocation. | ||
| 173 | * | ||
| 174 | * TODO: accept the key if we have a station entry and | ||
| 175 | * add it to the device after the station. | ||
| 176 | */ | ||
| 177 | if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) { | ||
| 168 | ieee80211_key_free(sdata->local, key); | 178 | ieee80211_key_free(sdata->local, key); |
| 169 | err = -ENOENT; | 179 | err = -ENOENT; |
| 170 | goto out_unlock; | 180 | goto out_unlock; |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8563b9a5cac3..2ed065c09562 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -1358,10 +1358,8 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata); | |||
| 1358 | void ieee80211_sched_scan_stopped_work(struct work_struct *work); | 1358 | void ieee80211_sched_scan_stopped_work(struct work_struct *work); |
| 1359 | 1359 | ||
| 1360 | /* off-channel helpers */ | 1360 | /* off-channel helpers */ |
| 1361 | void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | 1361 | void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local); |
| 1362 | bool offchannel_ps_enable); | 1362 | void ieee80211_offchannel_return(struct ieee80211_local *local); |
| 1363 | void ieee80211_offchannel_return(struct ieee80211_local *local, | ||
| 1364 | bool offchannel_ps_disable); | ||
| 1365 | void ieee80211_roc_setup(struct ieee80211_local *local); | 1363 | void ieee80211_roc_setup(struct ieee80211_local *local); |
| 1366 | void ieee80211_start_next_roc(struct ieee80211_local *local); | 1364 | void ieee80211_start_next_roc(struct ieee80211_local *local); |
| 1367 | void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); | 1365 | void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 47aeee2d8db1..2659e428b80c 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
| @@ -215,6 +215,7 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata, | |||
| 215 | skb->priority = 7; | 215 | skb->priority = 7; |
| 216 | 216 | ||
| 217 | info->control.vif = &sdata->vif; | 217 | info->control.vif = &sdata->vif; |
| 218 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | ||
| 218 | ieee80211_set_qos_hdr(sdata, skb); | 219 | ieee80211_set_qos_hdr(sdata, skb); |
| 219 | } | 220 | } |
| 220 | 221 | ||
| @@ -246,11 +247,13 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, | |||
| 246 | return -EAGAIN; | 247 | return -EAGAIN; |
| 247 | 248 | ||
| 248 | skb = dev_alloc_skb(local->tx_headroom + | 249 | skb = dev_alloc_skb(local->tx_headroom + |
| 250 | IEEE80211_ENCRYPT_HEADROOM + | ||
| 251 | IEEE80211_ENCRYPT_TAILROOM + | ||
| 249 | hdr_len + | 252 | hdr_len + |
| 250 | 2 + 15 /* PERR IE */); | 253 | 2 + 15 /* PERR IE */); |
| 251 | if (!skb) | 254 | if (!skb) |
| 252 | return -1; | 255 | return -1; |
| 253 | skb_reserve(skb, local->tx_headroom); | 256 | skb_reserve(skb, local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM); |
| 254 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); | 257 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); |
| 255 | memset(mgmt, 0, hdr_len); | 258 | memset(mgmt, 0, hdr_len); |
| 256 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 259 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index a5379aea7d09..a3ad4c3c80a3 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
| @@ -102,8 +102,7 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata) | |||
| 102 | ieee80211_sta_reset_conn_monitor(sdata); | 102 | ieee80211_sta_reset_conn_monitor(sdata); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | 105 | void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local) |
| 106 | bool offchannel_ps_enable) | ||
| 107 | { | 106 | { |
| 108 | struct ieee80211_sub_if_data *sdata; | 107 | struct ieee80211_sub_if_data *sdata; |
| 109 | 108 | ||
| @@ -134,8 +133,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | |||
| 134 | 133 | ||
| 135 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { | 134 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
| 136 | netif_tx_stop_all_queues(sdata->dev); | 135 | netif_tx_stop_all_queues(sdata->dev); |
| 137 | if (offchannel_ps_enable && | 136 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
| 138 | (sdata->vif.type == NL80211_IFTYPE_STATION) && | ||
| 139 | sdata->u.mgd.associated) | 137 | sdata->u.mgd.associated) |
| 140 | ieee80211_offchannel_ps_enable(sdata); | 138 | ieee80211_offchannel_ps_enable(sdata); |
| 141 | } | 139 | } |
| @@ -143,8 +141,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | |||
| 143 | mutex_unlock(&local->iflist_mtx); | 141 | mutex_unlock(&local->iflist_mtx); |
| 144 | } | 142 | } |
| 145 | 143 | ||
| 146 | void ieee80211_offchannel_return(struct ieee80211_local *local, | 144 | void ieee80211_offchannel_return(struct ieee80211_local *local) |
| 147 | bool offchannel_ps_disable) | ||
| 148 | { | 145 | { |
| 149 | struct ieee80211_sub_if_data *sdata; | 146 | struct ieee80211_sub_if_data *sdata; |
| 150 | 147 | ||
| @@ -163,11 +160,9 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, | |||
| 163 | continue; | 160 | continue; |
| 164 | 161 | ||
| 165 | /* Tell AP we're back */ | 162 | /* Tell AP we're back */ |
| 166 | if (offchannel_ps_disable && | 163 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
| 167 | sdata->vif.type == NL80211_IFTYPE_STATION) { | 164 | sdata->u.mgd.associated) |
| 168 | if (sdata->u.mgd.associated) | 165 | ieee80211_offchannel_ps_disable(sdata); |
| 169 | ieee80211_offchannel_ps_disable(sdata); | ||
| 170 | } | ||
| 171 | 166 | ||
| 172 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { | 167 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
| 173 | /* | 168 | /* |
| @@ -385,7 +380,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
| 385 | local->tmp_channel = NULL; | 380 | local->tmp_channel = NULL; |
| 386 | ieee80211_hw_config(local, 0); | 381 | ieee80211_hw_config(local, 0); |
| 387 | 382 | ||
| 388 | ieee80211_offchannel_return(local, true); | 383 | ieee80211_offchannel_return(local); |
| 389 | } | 384 | } |
| 390 | 385 | ||
| 391 | ieee80211_recalc_idle(local); | 386 | ieee80211_recalc_idle(local); |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index d59fc6818b1c..bf82e69d0601 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
| @@ -292,7 +292,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
| 292 | if (!was_hw_scan) { | 292 | if (!was_hw_scan) { |
| 293 | ieee80211_configure_filter(local); | 293 | ieee80211_configure_filter(local); |
| 294 | drv_sw_scan_complete(local); | 294 | drv_sw_scan_complete(local); |
| 295 | ieee80211_offchannel_return(local, true); | 295 | ieee80211_offchannel_return(local); |
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | ieee80211_recalc_idle(local); | 298 | ieee80211_recalc_idle(local); |
| @@ -341,7 +341,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
| 341 | local->next_scan_state = SCAN_DECISION; | 341 | local->next_scan_state = SCAN_DECISION; |
| 342 | local->scan_channel_idx = 0; | 342 | local->scan_channel_idx = 0; |
| 343 | 343 | ||
| 344 | ieee80211_offchannel_stop_vifs(local, true); | 344 | ieee80211_offchannel_stop_vifs(local); |
| 345 | 345 | ||
| 346 | ieee80211_configure_filter(local); | 346 | ieee80211_configure_filter(local); |
| 347 | 347 | ||
| @@ -678,12 +678,8 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local, | |||
| 678 | local->scan_channel = NULL; | 678 | local->scan_channel = NULL; |
| 679 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 679 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
| 680 | 680 | ||
| 681 | /* | 681 | /* disable PS */ |
| 682 | * Re-enable vifs and beaconing. Leave PS | 682 | ieee80211_offchannel_return(local); |
| 683 | * in off-channel state..will put that back | ||
| 684 | * on-channel at the end of scanning. | ||
| 685 | */ | ||
| 686 | ieee80211_offchannel_return(local, false); | ||
| 687 | 683 | ||
| 688 | *next_delay = HZ / 5; | 684 | *next_delay = HZ / 5; |
| 689 | /* afterwards, resume scan & go to next channel */ | 685 | /* afterwards, resume scan & go to next channel */ |
| @@ -693,8 +689,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local, | |||
| 693 | static void ieee80211_scan_state_resume(struct ieee80211_local *local, | 689 | static void ieee80211_scan_state_resume(struct ieee80211_local *local, |
| 694 | unsigned long *next_delay) | 690 | unsigned long *next_delay) |
| 695 | { | 691 | { |
| 696 | /* PS already is in off-channel mode */ | 692 | ieee80211_offchannel_stop_vifs(local); |
| 697 | ieee80211_offchannel_stop_vifs(local, false); | ||
| 698 | 693 | ||
| 699 | if (local->ops->flush) { | 694 | if (local->ops->flush) { |
| 700 | drv_flush(local, false); | 695 | drv_flush(local, false); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index e9eadc40c09c..467c1d1b66f2 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -1673,10 +1673,13 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
| 1673 | chanctx_conf = | 1673 | chanctx_conf = |
| 1674 | rcu_dereference(tmp_sdata->vif.chanctx_conf); | 1674 | rcu_dereference(tmp_sdata->vif.chanctx_conf); |
| 1675 | } | 1675 | } |
| 1676 | if (!chanctx_conf) | ||
| 1677 | goto fail_rcu; | ||
| 1678 | 1676 | ||
| 1679 | chan = chanctx_conf->def.chan; | 1677 | if (chanctx_conf) |
| 1678 | chan = chanctx_conf->def.chan; | ||
| 1679 | else if (!local->use_chanctx) | ||
| 1680 | chan = local->_oper_channel; | ||
| 1681 | else | ||
| 1682 | goto fail_rcu; | ||
| 1680 | 1683 | ||
| 1681 | /* | 1684 | /* |
| 1682 | * Frame injection is not allowed if beaconing is not allowed | 1685 | * Frame injection is not allowed if beaconing is not allowed |
