Commit 64d47902 authored by David S. Miller's avatar David S. Miller

Merge tag 'mac80211-for-davem-2018-12-05' of...

Merge tag 'mac80211-for-davem-2018-12-05' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211

Johannes Berg:

====================
As it's been a while, we have various fixes for
 * hwsim
 * AP mode (client powersave related)
 * CSA/FTM interaction
 * a busy loop in IE handling
 * and similar
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0fb628f0 312ca38d
...@@ -2884,6 +2884,10 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, ...@@ -2884,6 +2884,10 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
tasklet_hrtimer_init(&data->beacon_timer,
mac80211_hwsim_beacon,
CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
err = ieee80211_register_hw(hw); err = ieee80211_register_hw(hw);
if (err < 0) { if (err < 0) {
pr_debug("mac80211_hwsim: ieee80211_register_hw failed (%d)\n", pr_debug("mac80211_hwsim: ieee80211_register_hw failed (%d)\n",
...@@ -2908,10 +2912,6 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, ...@@ -2908,10 +2912,6 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
data->debugfs, data->debugfs,
data, &hwsim_simulate_radar); data, &hwsim_simulate_radar);
tasklet_hrtimer_init(&data->beacon_timer,
mac80211_hwsim_beacon,
CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
spin_lock_bh(&hwsim_radio_lock); spin_lock_bh(&hwsim_radio_lock);
err = rhashtable_insert_fast(&hwsim_radios_rht, &data->rht, err = rhashtable_insert_fast(&hwsim_radios_rht, &data->rht,
hwsim_rht_params); hwsim_rht_params);
...@@ -3703,16 +3703,16 @@ static int __init init_mac80211_hwsim(void) ...@@ -3703,16 +3703,16 @@ static int __init init_mac80211_hwsim(void)
if (err) if (err)
goto out_unregister_pernet; goto out_unregister_pernet;
err = hwsim_init_netlink();
if (err)
goto out_unregister_driver;
hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim"); hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim");
if (IS_ERR(hwsim_class)) { if (IS_ERR(hwsim_class)) {
err = PTR_ERR(hwsim_class); err = PTR_ERR(hwsim_class);
goto out_unregister_driver; goto out_exit_netlink;
} }
err = hwsim_init_netlink();
if (err < 0)
goto out_unregister_driver;
for (i = 0; i < radios; i++) { for (i = 0; i < radios; i++) {
struct hwsim_new_radio_params param = { 0 }; struct hwsim_new_radio_params param = { 0 };
...@@ -3818,6 +3818,8 @@ static int __init init_mac80211_hwsim(void) ...@@ -3818,6 +3818,8 @@ static int __init init_mac80211_hwsim(void)
free_netdev(hwsim_mon); free_netdev(hwsim_mon);
out_free_radios: out_free_radios:
mac80211_hwsim_free(); mac80211_hwsim_free();
out_exit_netlink:
hwsim_exit_netlink();
out_unregister_driver: out_unregister_driver:
platform_driver_unregister(&mac80211_hwsim_driver); platform_driver_unregister(&mac80211_hwsim_driver);
out_unregister_pernet: out_unregister_pernet:
......
...@@ -2891,7 +2891,7 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon) ...@@ -2891,7 +2891,7 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon)
len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len + len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len +
beacon->proberesp_ies_len + beacon->assocresp_ies_len + beacon->proberesp_ies_len + beacon->assocresp_ies_len +
beacon->probe_resp_len; beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len;
new_beacon = kzalloc(sizeof(*new_beacon) + len, GFP_KERNEL); new_beacon = kzalloc(sizeof(*new_beacon) + len, GFP_KERNEL);
if (!new_beacon) if (!new_beacon)
...@@ -2934,8 +2934,9 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon) ...@@ -2934,8 +2934,9 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon)
memcpy(pos, beacon->probe_resp, beacon->probe_resp_len); memcpy(pos, beacon->probe_resp, beacon->probe_resp_len);
pos += beacon->probe_resp_len; pos += beacon->probe_resp_len;
} }
if (beacon->ftm_responder)
new_beacon->ftm_responder = beacon->ftm_responder; /* might copy -1, meaning no changes requested */
new_beacon->ftm_responder = beacon->ftm_responder;
if (beacon->lci) { if (beacon->lci) {
new_beacon->lci_len = beacon->lci_len; new_beacon->lci_len = beacon->lci_len;
new_beacon->lci = pos; new_beacon->lci = pos;
......
...@@ -1015,6 +1015,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ...@@ -1015,6 +1015,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
if (local->open_count == 0) if (local->open_count == 0)
ieee80211_clear_tx_pending(local); ieee80211_clear_tx_pending(local);
sdata->vif.bss_conf.beacon_int = 0;
/* /*
* If the interface goes down while suspended, presumably because * If the interface goes down while suspended, presumably because
* the device was unplugged and that happens before our resume, * the device was unplugged and that happens before our resume,
......
...@@ -2766,6 +2766,7 @@ static bool ieee80211_mark_sta_auth(struct ieee80211_sub_if_data *sdata, ...@@ -2766,6 +2766,7 @@ static bool ieee80211_mark_sta_auth(struct ieee80211_sub_if_data *sdata,
{ {
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct sta_info *sta; struct sta_info *sta;
bool result = true;
sdata_info(sdata, "authenticated\n"); sdata_info(sdata, "authenticated\n");
ifmgd->auth_data->done = true; ifmgd->auth_data->done = true;
...@@ -2778,15 +2779,18 @@ static bool ieee80211_mark_sta_auth(struct ieee80211_sub_if_data *sdata, ...@@ -2778,15 +2779,18 @@ static bool ieee80211_mark_sta_auth(struct ieee80211_sub_if_data *sdata,
sta = sta_info_get(sdata, bssid); sta = sta_info_get(sdata, bssid);
if (!sta) { if (!sta) {
WARN_ONCE(1, "%s: STA %pM not found", sdata->name, bssid); WARN_ONCE(1, "%s: STA %pM not found", sdata->name, bssid);
return false; result = false;
goto out;
} }
if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) { if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) {
sdata_info(sdata, "failed moving %pM to auth\n", bssid); sdata_info(sdata, "failed moving %pM to auth\n", bssid);
return false; result = false;
goto out;
} }
mutex_unlock(&sdata->local->sta_mtx);
return true; out:
mutex_unlock(&sdata->local->sta_mtx);
return result;
} }
static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
......
...@@ -1403,6 +1403,7 @@ ieee80211_rx_h_check_dup(struct ieee80211_rx_data *rx) ...@@ -1403,6 +1403,7 @@ ieee80211_rx_h_check_dup(struct ieee80211_rx_data *rx)
return RX_CONTINUE; return RX_CONTINUE;
if (ieee80211_is_ctl(hdr->frame_control) || if (ieee80211_is_ctl(hdr->frame_control) ||
ieee80211_is_nullfunc(hdr->frame_control) ||
ieee80211_is_qos_nullfunc(hdr->frame_control) || ieee80211_is_qos_nullfunc(hdr->frame_control) ||
is_multicast_ether_addr(hdr->addr1)) is_multicast_ether_addr(hdr->addr1))
return RX_CONTINUE; return RX_CONTINUE;
...@@ -3063,7 +3064,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) ...@@ -3063,7 +3064,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
cfg80211_sta_opmode_change_notify(sdata->dev, cfg80211_sta_opmode_change_notify(sdata->dev,
rx->sta->addr, rx->sta->addr,
&sta_opmode, &sta_opmode,
GFP_KERNEL); GFP_ATOMIC);
goto handled; goto handled;
} }
case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: { case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: {
...@@ -3100,7 +3101,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) ...@@ -3100,7 +3101,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
cfg80211_sta_opmode_change_notify(sdata->dev, cfg80211_sta_opmode_change_notify(sdata->dev,
rx->sta->addr, rx->sta->addr,
&sta_opmode, &sta_opmode,
GFP_KERNEL); GFP_ATOMIC);
goto handled; goto handled;
} }
default: default:
......
...@@ -964,6 +964,8 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw, ...@@ -964,6 +964,8 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
/* Track when last TDLS packet was ACKed */ /* Track when last TDLS packet was ACKed */
if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH)) if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
sta->status_stats.last_tdls_pkt_time = jiffies; sta->status_stats.last_tdls_pkt_time = jiffies;
} else if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
return;
} else { } else {
ieee80211_lost_packet(sta, info); ieee80211_lost_packet(sta, info);
} }
......
...@@ -439,8 +439,8 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) ...@@ -439,8 +439,8 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
if (ieee80211_hw_check(&tx->local->hw, QUEUE_CONTROL)) if (ieee80211_hw_check(&tx->local->hw, QUEUE_CONTROL))
info->hw_queue = tx->sdata->vif.cab_queue; info->hw_queue = tx->sdata->vif.cab_queue;
/* no stations in PS mode */ /* no stations in PS mode and no buffered packets */
if (!atomic_read(&ps->num_sta_ps)) if (!atomic_read(&ps->num_sta_ps) && skb_queue_empty(&ps->bc_buf))
return TX_CONTINUE; return TX_CONTINUE;
info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
......
...@@ -272,11 +272,11 @@ void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa, ...@@ -272,11 +272,11 @@ void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
p1 = (u8*)(ht_capa); p1 = (u8*)(ht_capa);
p2 = (u8*)(ht_capa_mask); p2 = (u8*)(ht_capa_mask);
for (i = 0; i<sizeof(*ht_capa); i++) for (i = 0; i < sizeof(*ht_capa); i++)
p1[i] &= p2[i]; p1[i] &= p2[i];
} }
/* Do a logical ht_capa &= ht_capa_mask. */ /* Do a logical vht_capa &= vht_capa_mask. */
void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa, void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
const struct ieee80211_vht_cap *vht_capa_mask) const struct ieee80211_vht_cap *vht_capa_mask)
{ {
......
...@@ -7870,6 +7870,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) ...@@ -7870,6 +7870,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
} }
memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
params.beacon_csa.ftm_responder = -1;
if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] || if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
!info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]) !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
......
...@@ -642,11 +642,15 @@ static bool cfg80211_is_all_idle(void) ...@@ -642,11 +642,15 @@ static bool cfg80211_is_all_idle(void)
* All devices must be idle as otherwise if you are actively * All devices must be idle as otherwise if you are actively
* scanning some new beacon hints could be learned and would * scanning some new beacon hints could be learned and would
* count as new regulatory hints. * count as new regulatory hints.
* Also if there is any other active beaconing interface we
* need not issue a disconnect hint and reset any info such
* as chan dfs state, etc.
*/ */
list_for_each_entry(rdev, &cfg80211_rdev_list, list) { list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
wdev_lock(wdev); wdev_lock(wdev);
if (wdev->conn || wdev->current_bss) if (wdev->conn || wdev->current_bss ||
cfg80211_beaconing_iface_active(wdev))
is_all_idle = false; is_all_idle = false;
wdev_unlock(wdev); wdev_unlock(wdev);
} }
...@@ -1171,6 +1175,8 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev, ...@@ -1171,6 +1175,8 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
cfg80211_oper_and_ht_capa(&connect->ht_capa_mask, cfg80211_oper_and_ht_capa(&connect->ht_capa_mask,
rdev->wiphy.ht_capa_mod_mask); rdev->wiphy.ht_capa_mod_mask);
cfg80211_oper_and_vht_capa(&connect->vht_capa_mask,
rdev->wiphy.vht_capa_mod_mask);
if (connkeys && connkeys->def >= 0) { if (connkeys && connkeys->def >= 0) {
int idx; int idx;
......
...@@ -1421,6 +1421,8 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen, ...@@ -1421,6 +1421,8 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen,
ies[pos + ext], ies[pos + ext],
ext == 2)) ext == 2))
pos = skip_ie(ies, ielen, pos); pos = skip_ie(ies, ielen, pos);
else
break;
} }
} else { } else {
pos = skip_ie(ies, ielen, pos); pos = skip_ie(ies, ielen, pos);
......
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