Kalle Valo says: ==================== wireless fixes for v5.18 Second set of fixes for v5.18 and hopefully the last one. We have a new iwlwifi maintainer, a fix to rfkill ioctl interface and important fixes to both stack and two drivers. * tag 'wireless-2022-05-11' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless: rfkill: uapi: fix RFKILL_IOCTL_MAX_SIZE ioctl request definition nl80211: fix locking in nl80211_set_tx_bitrate_mask() mac80211_hwsim: call ieee80211_tx_prepare_skb under RCU protection mac80211_hwsim: fix RCU protected chanctx access mailmap: update Kalle Valo's email mac80211: Reset MBSSID parameters upon connection cfg80211: retrieve S1G operating channel number nl80211: validate S1G channel width mac80211: fix rx reordering with non explicit / psmp ack policy ath11k: reduce the wait time of 11d scan and hw scan while add interface MAINTAINERS: update iwlwifi driver maintainer iwlwifi: iwl-dbg: Use del_timer_sync() before freeing ====================
Unified · Split
| @@ -204,6 +204,7 @@ Juha Yrjola <at solidboot.com> · 203 unmodified lines | ||
| 204 | 204 | Juha Yrjola <juha.yrjola@nokia.com> |
| 205 | 205 | Juha Yrjola <juha.yrjola@solidboot.com> |
| 206 | 206 | Julien Thierry <julien.thierry.kdev@gmail.com> <julien.thierry@arm.com> |
| 207 | +Kalle Valo <kvalo@kernel.org> <kvalo@codeaurora.org> | |
| 207 | 208 | Kalyan Thota <quic_kalyant@quicinc.com> <kalyan_t@codeaurora.org> |
| 208 | 209 | Kay Sievers <kay.sievers@vrfy.org> |
| 209 | 210 | Kees Cook <keescook@chromium.org> <kees.cook@canonical.com> |
| @@ -10132,7 +10132,7 @@ S: Supported · 10131 unmodified lines | ||
| 10132 | 10132 | F: drivers/net/wireless/intel/iwlegacy/ |
| 10133 | 10133 | |
| 10134 | 10134 | INTEL WIRELESS WIFI LINK (iwlwifi) |
| 10135 | −M: Luca Coelho <luciano.coelho@intel.com> | |
| 10135 | +M: Gregory Greenman <gregory.greenman@intel.com> | |
| 10136 | 10136 | L: linux-wireless@vger.kernel.org |
| 10137 | 10137 | S: Supported |
| 10138 | 10138 | W: https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi |
| @@ -1288,6 +1288,7 @@ static void ath11k_core_restart(struct work_struct *work) · 1287 unmodified lines | ||
| 1288 | 1288 | |
| 1289 | 1289 | ieee80211_stop_queues(ar->hw); |
| 1290 | 1290 | ath11k_mac_drain_tx(ar); |
| 1291 | + complete(&ar->completed_11d_scan); | |
| 1291 | 1292 | complete(&ar->scan.started); |
| 1292 | 1293 | complete(&ar->scan.completed); |
| 1293 | 1294 | complete(&ar->peer_assoc_done); |
| @@ -38,6 +38,8 @@ · 37 unmodified lines | ||
| 38 | 38 | |
| 39 | 39 | extern unsigned int ath11k_frame_mode; |
| 40 | 40 | |
| 41 | +#define ATH11K_SCAN_TIMEOUT_HZ (20 * HZ) | |
| 42 | + | |
| 41 | 43 | #define ATH11K_MON_TIMER_INTERVAL 10 |
| 42 | 44 | |
| 43 | 45 | enum ath11k_supported_bw { |
| @@ -189,6 +191,12 @@ enum ath11k_scan_state { · 145 unmodified lines | ||
| 189 | 191 | ATH11K_SCAN_ABORTING, |
| 190 | 192 | }; |
| 191 | 193 | |
| 194 | +enum ath11k_11d_state { | |
| 195 | + ATH11K_11D_IDLE, | |
| 196 | + ATH11K_11D_PREPARING, | |
| 197 | + ATH11K_11D_RUNNING, | |
| 198 | +}; | |
| 199 | + | |
| 192 | 200 | enum ath11k_dev_flags { |
| 193 | 201 | ATH11K_CAC_RUNNING, |
| 194 | 202 | ATH11K_FLAG_CORE_REGISTERED, |
| @@ -607,9 +615,8 @@ struct ath11k { · 412 unmodified lines | ||
| 607 | 615 | bool dfs_block_radar_events; |
| 608 | 616 | struct ath11k_thermal thermal; |
| 609 | 617 | u32 vdev_id_11d_scan; |
| 610 | − struct completion finish_11d_scan; | |
| 611 | − struct completion finish_11d_ch_list; | |
| 612 | − bool pending_11d; | |
| 618 | + struct completion completed_11d_scan; | |
| 619 | + enum ath11k_11d_state state_11d; | |
| 613 | 620 | bool regdom_set_by_user; |
| 614 | 621 | int hw_rate_code; |
| 615 | 622 | u8 twt_enabled; |
| @@ -3601,26 +3601,6 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw, · 3600 unmodified lines | ||
| 3601 | 3601 | if (ret) |
| 3602 | 3602 | goto exit; |
| 3603 | 3603 | |
| 3604 | − /* Currently the pending_11d=true only happened 1 time while | |
| 3605 | − * wlan interface up in ath11k_mac_11d_scan_start(), it is called by | |
| 3606 | − * ath11k_mac_op_add_interface(), after wlan interface up, | |
| 3607 | − * pending_11d=false always. | |
| 3608 | − * If remove below wait, it always happened scan fail and lead connect | |
| 3609 | − * fail while wlan interface up, because it has a 11d scan which is running | |
| 3610 | − * in firmware, and lead this scan failed. | |
| 3611 | − */ | |
| 3612 | − if (ar->pending_11d) { | |
| 3613 | − long time_left; | |
| 3614 | − unsigned long timeout = 5 * HZ; | |
| 3615 | − | |
| 3616 | − if (ar->supports_6ghz) | |
| 3617 | − timeout += 5 * HZ; | |
| 3618 | − | |
| 3619 | − time_left = wait_for_completion_timeout(&ar->finish_11d_ch_list, timeout); | |
| 3620 | − ath11k_dbg(ar->ab, ATH11K_DBG_MAC, | |
| 3621 | − "mac wait 11d channel list time left %ld\n", time_left); | |
| 3622 | − } | |
| 3623 | − | |
| 3624 | 3604 | memset(&arg, 0, sizeof(arg)); |
| 3625 | 3605 | ath11k_wmi_start_scan_init(ar, &arg); |
| 3626 | 3606 | arg.vdev_id = arvif->vdev_id; |
| @@ -3686,6 +3666,10 @@ exit: · 59 unmodified lines | ||
| 3686 | 3666 | kfree(arg.extraie.ptr); |
| 3687 | 3667 | |
| 3688 | 3668 | mutex_unlock(&ar->conf_mutex); |
| 3669 | + | |
| 3670 | + if (ar->state_11d == ATH11K_11D_PREPARING) | |
| 3671 | + ath11k_mac_11d_scan_start(ar, arvif->vdev_id); | |
| 3672 | + | |
| 3689 | 3673 | return ret; |
| 3690 | 3674 | } |
| 3691 | 3675 | |
| @@ -5814,7 +5798,7 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw) · 2122 unmodified lines | ||
| 5814 | 5798 | |
| 5815 | 5799 | /* TODO: Do we need to enable ANI? */ |
| 5816 | 5800 | |
| 5817 | − ath11k_reg_update_chan_list(ar); | |
| 5801 | + ath11k_reg_update_chan_list(ar, false); | |
| 5818 | 5802 | |
| 5819 | 5803 | ar->num_started_vdevs = 0; |
| 5820 | 5804 | ar->num_created_vdevs = 0; |
| @@ -5881,6 +5865,11 @@ static void ath11k_mac_op_stop(struct ieee80211_hw *hw) · 60 unmodified lines | ||
| 5881 | 5865 | cancel_work_sync(&ar->ab->update_11d_work); |
| 5882 | 5866 | cancel_work_sync(&ar->ab->rfkill_work); |
| 5883 | 5867 | |
| 5868 | + if (ar->state_11d == ATH11K_11D_PREPARING) { | |
| 5869 | + ar->state_11d = ATH11K_11D_IDLE; | |
| 5870 | + complete(&ar->completed_11d_scan); | |
| 5871 | + } | |
| 5872 | + | |
| 5884 | 5873 | spin_lock_bh(&ar->data_lock); |
| 5885 | 5874 | list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) { |
| 5886 | 5875 | list_del(&ppdu_stats->list); |
| @@ -6051,7 +6040,7 @@ static bool ath11k_mac_vif_ap_active_any(struct ath11k_base *ab) · 164 unmodified lines | ||
| 6051 | 6040 | return false; |
| 6052 | 6041 | } |
| 6053 | 6042 | |
| 6054 | −void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id, bool wait) | |
| 6043 | +void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id) | |
| 6055 | 6044 | { |
| 6056 | 6045 | struct wmi_11d_scan_start_params param; |
| 6057 | 6046 | int ret; |
| @@ -6079,28 +6068,22 @@ void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id, bool wait) · 21 unmodified lines | ||
| 6079 | 6068 | |
| 6080 | 6069 | ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac start 11d scan\n"); |
| 6081 | 6070 | |
| 6082 | − if (wait) | |
| 6083 | − reinit_completion(&ar->finish_11d_scan); | |
| 6084 | − | |
| 6085 | 6071 | ret = ath11k_wmi_send_11d_scan_start_cmd(ar, ¶m); |
| 6086 | 6072 | if (ret) { |
| 6087 | 6073 | ath11k_warn(ar->ab, "failed to start 11d scan vdev %d ret: %d\n", |
| 6088 | 6074 | vdev_id, ret); |
| 6089 | 6075 | } else { |
| 6090 | 6076 | ar->vdev_id_11d_scan = vdev_id; |
| 6091 | − if (wait) { | |
| 6092 | − ar->pending_11d = true; | |
| 6093 | − ret = wait_for_completion_timeout(&ar->finish_11d_scan, | |
| 6094 | − 5 * HZ); | |
| 6095 | − ath11k_dbg(ar->ab, ATH11K_DBG_MAC, | |
| 6096 | − "mac 11d scan left time %d\n", ret); | |
| 6097 | − | |
| 6098 | − if (!ret) | |
| 6099 | − ar->pending_11d = false; | |
| 6100 | − } | |
| 6077 | + if (ar->state_11d == ATH11K_11D_PREPARING) | |
| 6078 | + ar->state_11d = ATH11K_11D_RUNNING; | |
| 6101 | 6079 | } |
| 6102 | 6080 | |
| 6103 | 6081 | fin: |
| 6082 | + if (ar->state_11d == ATH11K_11D_PREPARING) { | |
| 6083 | + ar->state_11d = ATH11K_11D_IDLE; | |
| 6084 | + complete(&ar->completed_11d_scan); | |
| 6085 | + } | |
| 6086 | + | |
| 6104 | 6087 | mutex_unlock(&ar->ab->vdev_id_11d_lock); |
| 6105 | 6088 | } |
| 6106 | 6089 | |
| @@ -6123,12 +6106,15 @@ void ath11k_mac_11d_scan_stop(struct ath11k *ar) · 16 unmodified lines | ||
| 6123 | 6106 | vdev_id = ar->vdev_id_11d_scan; |
| 6124 | 6107 | |
| 6125 | 6108 | ret = ath11k_wmi_send_11d_scan_stop_cmd(ar, vdev_id); |
| 6126 | − if (ret) | |
| 6109 | + if (ret) { | |
| 6127 | 6110 | ath11k_warn(ar->ab, |
| 6128 | 6111 | "failed to stopt 11d scan vdev %d ret: %d\n", |
| 6129 | 6112 | vdev_id, ret); |
| 6130 | − else | |
| 6113 | + } else { | |
| 6131 | 6114 | ar->vdev_id_11d_scan = ATH11K_11D_INVALID_VDEV_ID; |
| 6115 | + ar->state_11d = ATH11K_11D_IDLE; | |
| 6116 | + complete(&ar->completed_11d_scan); | |
| 6117 | + } | |
| 6132 | 6118 | } |
| 6133 | 6119 | mutex_unlock(&ar->ab->vdev_id_11d_lock); |
| 6134 | 6120 | } |
| @@ -6324,8 +6310,10 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, · 189 unmodified lines | ||
| 6324 | 6310 | goto err_peer_del; |
| 6325 | 6311 | } |
| 6326 | 6312 | |
| 6327 | − ath11k_mac_11d_scan_start(ar, arvif->vdev_id, true); | |
| 6328 | − | |
| 6313 | + if (test_bit(WMI_TLV_SERVICE_11D_OFFLOAD, ab->wmi_ab.svc_map)) { | |
| 6314 | + reinit_completion(&ar->completed_11d_scan); | |
| 6315 | + ar->state_11d = ATH11K_11D_PREPARING; | |
| 6316 | + } | |
| 6329 | 6317 | break; |
| 6330 | 6318 | case WMI_VDEV_TYPE_MONITOR: |
| 6331 | 6319 | set_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); |
| @@ -7190,7 +7178,7 @@ ath11k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, · 858 unmodified lines | ||
| 7190 | 7178 | } |
| 7191 | 7179 | |
| 7192 | 7180 | if (arvif->vdev_type == WMI_VDEV_TYPE_STA) |
| 7193 | − ath11k_mac_11d_scan_start(ar, arvif->vdev_id, false); | |
| 7181 | + ath11k_mac_11d_scan_start(ar, arvif->vdev_id); | |
| 7194 | 7182 | |
| 7195 | 7183 | mutex_unlock(&ar->conf_mutex); |
| 7196 | 7184 | } |
| @@ -8671,8 +8659,7 @@ int ath11k_mac_allocate(struct ath11k_base *ab) · 1474 unmodified lines | ||
| 8671 | 8659 | ar->monitor_vdev_id = -1; |
| 8672 | 8660 | clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); |
| 8673 | 8661 | ar->vdev_id_11d_scan = ATH11K_11D_INVALID_VDEV_ID; |
| 8674 | − init_completion(&ar->finish_11d_scan); | |
| 8675 | − init_completion(&ar->finish_11d_ch_list); | |
| 8662 | + init_completion(&ar->completed_11d_scan); | |
| 8676 | 8663 | } |
| 8677 | 8664 | |
| 8678 | 8665 | return 0; |
| @@ -130,7 +130,7 @@ extern const struct htt_rx_ring_tlv_filter ath11k_mac_mon_status_filter_default; · 129 unmodified lines | ||
| 130 | 130 | #define ATH11K_SCAN_11D_INTERVAL 600000 |
| 131 | 131 | #define ATH11K_11D_INVALID_VDEV_ID 0xFFFF |
| 132 | 132 | |
| 133 | −void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id, bool wait); | |
| 133 | +void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id); | |
| 134 | 134 | void ath11k_mac_11d_scan_stop(struct ath11k *ar); |
| 135 | 135 | void ath11k_mac_11d_scan_stop_all(struct ath11k_base *ab); |
| 136 | 136 | |
| @@ -102,7 +102,7 @@ ath11k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) · 101 unmodified lines | ||
| 102 | 102 | ar->regdom_set_by_user = true; |
| 103 | 103 | } |
| 104 | 104 | |
| 105 | −int ath11k_reg_update_chan_list(struct ath11k *ar) | |
| 105 | +int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait) | |
| 106 | 106 | { |
| 107 | 107 | struct ieee80211_supported_band **bands; |
| 108 | 108 | struct scan_chan_list_params *params; |
| @@ -111,7 +111,32 @@ int ath11k_reg_update_chan_list(struct ath11k *ar) · 2 unmodified lines | ||
| 111 | 111 | struct channel_param *ch; |
| 112 | 112 | enum nl80211_band band; |
| 113 | 113 | int num_channels = 0; |
| 114 | − int i, ret; | |
| 114 | + int i, ret, left; | |
| 115 | + | |
| 116 | + if (wait && ar->state_11d != ATH11K_11D_IDLE) { | |
| 117 | + left = wait_for_completion_timeout(&ar->completed_11d_scan, | |
| 118 | + ATH11K_SCAN_TIMEOUT_HZ); | |
| 119 | + if (!left) { | |
| 120 | + ath11k_dbg(ar->ab, ATH11K_DBG_REG, | |
| 121 | + "failed to receive 11d scan complete: timed out\n"); | |
| 122 | + ar->state_11d = ATH11K_11D_IDLE; | |
| 123 | + } | |
| 124 | + ath11k_dbg(ar->ab, ATH11K_DBG_REG, | |
| 125 | + "reg 11d scan wait left time %d\n", left); | |
| 126 | + } | |
| 127 | + | |
| 128 | + if (wait && | |
| 129 | + (ar->scan.state == ATH11K_SCAN_STARTING || | |
| 130 | + ar->scan.state == ATH11K_SCAN_RUNNING)) { | |
| 131 | + left = wait_for_completion_timeout(&ar->scan.completed, | |
| 132 | + ATH11K_SCAN_TIMEOUT_HZ); | |
| 133 | + if (!left) | |
| 134 | + ath11k_dbg(ar->ab, ATH11K_DBG_REG, | |
| 135 | + "failed to receive hw scan complete: timed out\n"); | |
| 136 | + | |
| 137 | + ath11k_dbg(ar->ab, ATH11K_DBG_REG, | |
| 138 | + "reg hw scan wait left time %d\n", left); | |
| 139 | + } | |
| 115 | 140 | |
| 116 | 141 | bands = hw->wiphy->bands; |
| 117 | 142 | for (band = 0; band < NUM_NL80211_BANDS; band++) { |
| @@ -193,11 +218,6 @@ int ath11k_reg_update_chan_list(struct ath11k *ar) · 75 unmodified lines | ||
| 193 | 218 | ret = ath11k_wmi_send_scan_chan_list_cmd(ar, params); |
| 194 | 219 | kfree(params); |
| 195 | 220 | |
| 196 | − if (ar->pending_11d) { | |
| 197 | − complete(&ar->finish_11d_ch_list); | |
| 198 | − ar->pending_11d = false; | |
| 199 | − } | |
| 200 | − | |
| 201 | 221 | return ret; |
| 202 | 222 | } |
| 203 | 223 | |
| @@ -263,15 +283,8 @@ int ath11k_regd_update(struct ath11k *ar) · 59 unmodified lines | ||
| 263 | 283 | goto err; |
| 264 | 284 | } |
| 265 | 285 | |
| 266 | − if (ar->pending_11d) | |
| 267 | − complete(&ar->finish_11d_scan); | |
| 268 | − | |
| 269 | 286 | rtnl_lock(); |
| 270 | 287 | wiphy_lock(ar->hw->wiphy); |
| 271 | − | |
| 272 | − if (ar->pending_11d) | |
| 273 | − reinit_completion(&ar->finish_11d_ch_list); | |
| 274 | − | |
| 275 | 288 | ret = regulatory_set_wiphy_regd_sync(ar->hw->wiphy, regd_copy); |
| 276 | 289 | wiphy_unlock(ar->hw->wiphy); |
| 277 | 290 | rtnl_unlock(); |
| @@ -282,7 +295,7 @@ int ath11k_regd_update(struct ath11k *ar) · 4 unmodified lines | ||
| 282 | 295 | goto err; |
| 283 | 296 | |
| 284 | 297 | if (ar->state == ATH11K_STATE_ON) { |
| 285 | − ret = ath11k_reg_update_chan_list(ar); | |
| 298 | + ret = ath11k_reg_update_chan_list(ar, true); | |
| 286 | 299 | if (ret) |
| 287 | 300 | goto err; |
| 288 | 301 | } |
| @@ -32,5 +32,5 @@ struct ieee80211_regdomain * · 31 unmodified lines | ||
| 32 | 32 | ath11k_reg_build_regd(struct ath11k_base *ab, |
| 33 | 33 | struct cur_regulatory_info *reg_info, bool intersect); |
| 34 | 34 | int ath11k_regd_update(struct ath11k *ar); |
| 35 | −int ath11k_reg_update_chan_list(struct ath11k *ar); | |
| 35 | +int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait); | |
| 36 | 36 | #endif |
| @@ -2015,7 +2015,10 @@ void ath11k_wmi_start_scan_init(struct ath11k *ar, · 2014 unmodified lines | ||
| 2015 | 2015 | { |
| 2016 | 2016 | /* setup commonly used values */ |
| 2017 | 2017 | arg->scan_req_id = 1; |
| 2018 | − arg->scan_priority = WMI_SCAN_PRIORITY_LOW; | |
| 2018 | + if (ar->state_11d == ATH11K_11D_PREPARING) | |
| 2019 | + arg->scan_priority = WMI_SCAN_PRIORITY_MEDIUM; | |
| 2020 | + else | |
| 2021 | + arg->scan_priority = WMI_SCAN_PRIORITY_LOW; | |
| 2019 | 2022 | arg->dwell_time_active = 50; |
| 2020 | 2023 | arg->dwell_time_active_2g = 0; |
| 2021 | 2024 | arg->dwell_time_passive = 150; |
| @@ -6350,8 +6353,10 @@ static void ath11k_wmi_op_ep_tx_credits(struct ath11k_base *ab) · 4328 unmodified lines | ||
| 6350 | 6353 | static int ath11k_reg_11d_new_cc_event(struct ath11k_base *ab, struct sk_buff *skb) |
| 6351 | 6354 | { |
| 6352 | 6355 | const struct wmi_11d_new_cc_ev *ev; |
| 6356 | + struct ath11k *ar; | |
| 6357 | + struct ath11k_pdev *pdev; | |
| 6353 | 6358 | const void **tb; |
| 6354 | − int ret; | |
| 6359 | + int ret, i; | |
| 6355 | 6360 | |
| 6356 | 6361 | tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); |
| 6357 | 6362 | if (IS_ERR(tb)) { |
| @@ -6377,6 +6382,13 @@ static int ath11k_reg_11d_new_cc_event(struct ath11k_base *ab, struct sk_buff *s · 19 unmodified lines | ||
| 6377 | 6382 | |
| 6378 | 6383 | kfree(tb); |
| 6379 | 6384 | |
| 6385 | + for (i = 0; i < ab->num_radios; i++) { | |
| 6386 | + pdev = &ab->pdevs[i]; | |
| 6387 | + ar = pdev->ar; | |
| 6388 | + ar->state_11d = ATH11K_11D_IDLE; | |
| 6389 | + complete(&ar->completed_11d_scan); | |
| 6390 | + } | |
| 6391 | + | |
| 6380 | 6392 | queue_work(ab->workqueue, &ab->update_11d_work); |
| 6381 | 6393 | |
| 6382 | 6394 | return 0; |
| @@ -371,7 +371,7 @@ void iwl_dbg_tlv_del_timers(struct iwl_trans *trans) · 370 unmodified lines | ||
| 371 | 371 | struct iwl_dbg_tlv_timer_node *node, *tmp; |
| 372 | 372 | |
| 373 | 373 | list_for_each_entry_safe(node, tmp, timer_list, list) { |
| 374 | − del_timer(&node->timer); | |
| 374 | + del_timer_sync(&node->timer); | |
| 375 | 375 | list_del(&node->list); |
| 376 | 376 | kfree(node); |
| 377 | 377 | } |
| @@ -2202,11 +2202,14 @@ mac80211_hwsim_sta_rc_update(struct ieee80211_hw *hw, · 2201 unmodified lines | ||
| 2202 | 2202 | if (!data->use_chanctx) { |
| 2203 | 2203 | confbw = data->bw; |
| 2204 | 2204 | } else { |
| 2205 | − struct ieee80211_chanctx_conf *chanctx_conf = | |
| 2206 | − rcu_dereference(vif->chanctx_conf); | |
| 2205 | + struct ieee80211_chanctx_conf *chanctx_conf; | |
| 2206 | + | |
| 2207 | + rcu_read_lock(); | |
| 2208 | + chanctx_conf = rcu_dereference(vif->chanctx_conf); | |
| 2207 | 2209 | |
| 2208 | 2210 | if (!WARN_ON(!chanctx_conf)) |
| 2209 | 2211 | confbw = chanctx_conf->def.width; |
| 2212 | + rcu_read_unlock(); | |
| 2210 | 2213 | } |
| 2211 | 2214 | |
| 2212 | 2215 | WARN(bw > hwsim_get_chanwidth(confbw), |
| @@ -2475,11 +2478,13 @@ static void hw_scan_work(struct work_struct *work) · 262 unmodified lines | ||
| 2475 | 2478 | if (req->ie_len) |
| 2476 | 2479 | skb_put_data(probe, req->ie, req->ie_len); |
| 2477 | 2480 | |
| 2481 | + rcu_read_lock(); | |
| 2478 | 2482 | if (!ieee80211_tx_prepare_skb(hwsim->hw, |
| 2479 | 2483 | hwsim->hw_scan_vif, |
| 2480 | 2484 | probe, |
| 2481 | 2485 | hwsim->tmp_chan->band, |
| 2482 | 2486 | NULL)) { |
| 2487 | + rcu_read_unlock(); | |
| 2483 | 2488 | kfree_skb(probe); |
| 2484 | 2489 | continue; |
| 2485 | 2490 | } |
| @@ -2487,6 +2492,7 @@ static void hw_scan_work(struct work_struct *work) · 1 unmodified line | ||
| 2487 | 2492 | local_bh_disable(); |
| 2488 | 2493 | mac80211_hwsim_tx_frame(hwsim->hw, probe, |
| 2489 | 2494 | hwsim->tmp_chan); |
| 2495 | + rcu_read_unlock(); | |
| 2490 | 2496 | local_bh_enable(); |
| 2491 | 2497 | } |
| 2492 | 2498 | } |
| @@ -184,7 +184,7 @@ struct rfkill_event_ext { · 183 unmodified lines | ||
| 184 | 184 | #define RFKILL_IOC_NOINPUT 1 |
| 185 | 185 | #define RFKILL_IOCTL_NOINPUT _IO(RFKILL_IOC_MAGIC, RFKILL_IOC_NOINPUT) |
| 186 | 186 | #define RFKILL_IOC_MAX_SIZE 2 |
| 187 | −#define RFKILL_IOCTL_MAX_SIZE _IOW(RFKILL_IOC_MAGIC, RFKILL_IOC_EXT_SIZE, __u32) | |
| 187 | +#define RFKILL_IOCTL_MAX_SIZE _IOW(RFKILL_IOC_MAGIC, RFKILL_IOC_MAX_SIZE, __u32) | |
| 188 | 188 | |
| 189 | 189 | /* and that's all userspace gets */ |
| 190 | 190 | |
| @@ -3657,6 +3657,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, · 3656 unmodified lines | ||
| 3657 | 3657 | cbss->transmitted_bss->bssid); |
| 3658 | 3658 | bss_conf->bssid_indicator = cbss->max_bssid_indicator; |
| 3659 | 3659 | bss_conf->bssid_index = cbss->bssid_index; |
| 3660 | + } else { | |
| 3661 | + bss_conf->nontransmitted = false; | |
| 3662 | + memset(bss_conf->transmitter_bssid, 0, | |
| 3663 | + sizeof(bss_conf->transmitter_bssid)); | |
| 3664 | + bss_conf->bssid_indicator = 0; | |
| 3665 | + bss_conf->bssid_index = 0; | |
| 3660 | 3666 | } |
| 3661 | 3667 | |
| 3662 | 3668 | /* |
| @@ -1405,8 +1405,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx, · 1404 unmodified lines | ||
| 1405 | 1405 | goto dont_reorder; |
| 1406 | 1406 | |
| 1407 | 1407 | /* not part of a BA session */ |
| 1408 | − if (ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK && | |
| 1409 | − ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_NORMAL) | |
| 1408 | + if (ack_policy == IEEE80211_QOS_CTL_ACK_POLICY_NOACK) | |
| 1410 | 1409 | goto dont_reorder; |
| 1411 | 1410 | |
| 1412 | 1411 | /* new, potentially un-ordered, ampdu frame - process it */ |
| @@ -3173,6 +3173,15 @@ int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, · 3172 unmodified lines | ||
| 3173 | 3173 | } else if (attrs[NL80211_ATTR_CHANNEL_WIDTH]) { |
| 3174 | 3174 | chandef->width = |
| 3175 | 3175 | nla_get_u32(attrs[NL80211_ATTR_CHANNEL_WIDTH]); |
| 3176 | + if (chandef->chan->band == NL80211_BAND_S1GHZ) { | |
| 3177 | + /* User input error for channel width doesn't match channel */ | |
| 3178 | + if (chandef->width != ieee80211_s1g_channel_width(chandef->chan)) { | |
| 3179 | + NL_SET_ERR_MSG_ATTR(extack, | |
| 3180 | + attrs[NL80211_ATTR_CHANNEL_WIDTH], | |
| 3181 | + "bad channel width"); | |
| 3182 | + return -EINVAL; | |
| 3183 | + } | |
| 3184 | + } | |
| 3176 | 3185 | if (attrs[NL80211_ATTR_CENTER_FREQ1]) { |
| 3177 | 3186 | chandef->center_freq1 = |
| 3178 | 3187 | nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1]); |
| @@ -11657,18 +11666,23 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, · 8478 unmodified lines | ||
| 11657 | 11666 | struct cfg80211_bitrate_mask mask; |
| 11658 | 11667 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
| 11659 | 11668 | struct net_device *dev = info->user_ptr[1]; |
| 11669 | + struct wireless_dev *wdev = dev->ieee80211_ptr; | |
| 11660 | 11670 | int err; |
| 11661 | 11671 | |
| 11662 | 11672 | if (!rdev->ops->set_bitrate_mask) |
| 11663 | 11673 | return -EOPNOTSUPP; |
| 11664 | 11674 | |
| 11675 | + wdev_lock(wdev); | |
| 11665 | 11676 | err = nl80211_parse_tx_bitrate_mask(info, info->attrs, |
| 11666 | 11677 | NL80211_ATTR_TX_RATES, &mask, |
| 11667 | 11678 | dev, true); |
| 11668 | 11679 | if (err) |
| 11669 | − return err; | |
| 11680 | + goto out; | |
| 11670 | 11681 | |
| 11671 | − return rdev_set_bitrate_mask(rdev, dev, NULL, &mask); | |
| 11682 | + err = rdev_set_bitrate_mask(rdev, dev, NULL, &mask); | |
| 11683 | +out: | |
| 11684 | + wdev_unlock(wdev); | |
| 11685 | + return err; | |
| 11672 | 11686 | } |
| 11673 | 11687 | |
| 11674 | 11688 | static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) |
| @@ -1829,7 +1829,7 @@ int cfg80211_get_ies_channel_number(const u8 *ie, size_t ielen, · 1828 unmodified lines | ||
| 1829 | 1829 | if (tmp && tmp->datalen >= sizeof(struct ieee80211_s1g_oper_ie)) { |
| 1830 | 1830 | struct ieee80211_s1g_oper_ie *s1gop = (void *)tmp->data; |
| 1831 | 1831 | |
| 1832 | − return s1gop->primary_ch; | |
| 1832 | + return s1gop->oper_ch; | |
| 1833 | 1833 | } |
| 1834 | 1834 | } else { |
| 1835 | 1835 | tmp = cfg80211_find_elem(WLAN_EID_DS_PARAMS, ie, ielen); |