Commit 6b1ad5a3 authored by David S. Miller's avatar David S. Miller

Merge tag 'mac80211-for-davem-2020-06-08' of...

Merge tag 'mac80211-for-davem-2020-06-08' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211

Johannes Berg says:

====================
Just a small update:
 * fix the deadlock on rfkill/wireless removal that a few
   people reported
 * fix an uninitialized variable
 * update wiki URLs
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents af7b4801 59d4bfc1
...@@ -101,6 +101,6 @@ interface), along the following lines::: ...@@ -101,6 +101,6 @@ interface), along the following lines:::
You can also find a link to a complete inject application here: You can also find a link to a complete inject application here:
http://wireless.kernel.org/en/users/Documentation/packetspammer https://wireless.wiki.kernel.org/en/users/Documentation/packetspammer
Andy Green <andy@warmcat.com> Andy Green <andy@warmcat.com>
...@@ -9,7 +9,7 @@ regulatory infrastructure works. ...@@ -9,7 +9,7 @@ regulatory infrastructure works.
More up to date information can be obtained at the project's web page: More up to date information can be obtained at the project's web page:
http://wireless.kernel.org/en/developers/Regulatory https://wireless.wiki.kernel.org/en/developers/Regulatory
Keeping regulatory domains in userspace Keeping regulatory domains in userspace
--------------------------------------- ---------------------------------------
...@@ -37,7 +37,7 @@ expected regulatory domains will be respected by the kernel. ...@@ -37,7 +37,7 @@ expected regulatory domains will be respected by the kernel.
A currently available userspace agent which can accomplish this A currently available userspace agent which can accomplish this
is CRDA - central regulatory domain agent. Its documented here: is CRDA - central regulatory domain agent. Its documented here:
http://wireless.kernel.org/en/developers/Regulatory/CRDA https://wireless.wiki.kernel.org/en/developers/Regulatory/CRDA
Essentially the kernel will send a udev event when it knows Essentially the kernel will send a udev event when it knows
it needs a new regulatory domain. A udev rule can be put in place it needs a new regulatory domain. A udev rule can be put in place
...@@ -58,7 +58,7 @@ Who asks for regulatory domains? ...@@ -58,7 +58,7 @@ Who asks for regulatory domains?
Users can use iw: Users can use iw:
http://wireless.kernel.org/en/users/Documentation/iw https://wireless.wiki.kernel.org/en/users/Documentation/iw
An example:: An example::
......
...@@ -5075,7 +5075,8 @@ struct cfg80211_cqm_config; ...@@ -5075,7 +5075,8 @@ struct cfg80211_cqm_config;
* by cfg80211 on change_interface * by cfg80211 on change_interface
* @mgmt_registrations: list of registrations for management frames * @mgmt_registrations: list of registrations for management frames
* @mgmt_registrations_lock: lock for the list * @mgmt_registrations_lock: lock for the list
* @mgmt_registrations_update_wk: update work to defer from atomic context * @mgmt_registrations_need_update: mgmt registrations were updated,
* need to propagate the update to the driver
* @mtx: mutex used to lock data in this struct, may be used by drivers * @mtx: mutex used to lock data in this struct, may be used by drivers
* and some API functions require it held * and some API functions require it held
* @beacon_interval: beacon interval used on this device for transmitting * @beacon_interval: beacon interval used on this device for transmitting
...@@ -5121,7 +5122,7 @@ struct wireless_dev { ...@@ -5121,7 +5122,7 @@ struct wireless_dev {
struct list_head mgmt_registrations; struct list_head mgmt_registrations;
spinlock_t mgmt_registrations_lock; spinlock_t mgmt_registrations_lock;
struct work_struct mgmt_registrations_update_wk; u8 mgmt_registrations_need_update:1;
struct mutex mtx; struct mutex mtx;
......
...@@ -794,7 +794,7 @@ ...@@ -794,7 +794,7 @@
* various triggers. These triggers can be configured through this * various triggers. These triggers can be configured through this
* command with the %NL80211_ATTR_WOWLAN_TRIGGERS attribute. For * command with the %NL80211_ATTR_WOWLAN_TRIGGERS attribute. For
* more background information, see * more background information, see
* http://wireless.kernel.org/en/users/Documentation/WoWLAN. * https://wireless.wiki.kernel.org/en/users/Documentation/WoWLAN.
* The @NL80211_CMD_SET_WOWLAN command can also be used as a notification * The @NL80211_CMD_SET_WOWLAN command can also be used as a notification
* from the driver reporting the wakeup reason. In this case, the * from the driver reporting the wakeup reason. In this case, the
* @NL80211_ATTR_WOWLAN_TRIGGERS attribute will contain the reason * @NL80211_ATTR_WOWLAN_TRIGGERS attribute will contain the reason
......
...@@ -167,6 +167,8 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, ...@@ -167,6 +167,8 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
ret = IEEE80211_STA_DISABLE_HT | ret = IEEE80211_STA_DISABLE_HT |
IEEE80211_STA_DISABLE_VHT | IEEE80211_STA_DISABLE_VHT |
IEEE80211_STA_DISABLE_HE; IEEE80211_STA_DISABLE_HE;
else
ret = 0;
vht_chandef = *chandef; vht_chandef = *chandef;
goto out; goto out;
} }
......
...@@ -4694,7 +4694,7 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta, ...@@ -4694,7 +4694,7 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
* rate_idx is MCS index, which can be [0-76] * rate_idx is MCS index, which can be [0-76]
* as documented on: * as documented on:
* *
* http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n * https://wireless.wiki.kernel.org/en/developers/Documentation/ieee80211/802.11n
* *
* Anything else would be some sort of driver or * Anything else would be some sort of driver or
* hardware error. The driver should catch hardware * hardware error. The driver should catch hardware
......
...@@ -31,7 +31,7 @@ config CFG80211 ...@@ -31,7 +31,7 @@ config CFG80211
For more information refer to documentation on the wireless wiki: For more information refer to documentation on the wireless wiki:
http://wireless.kernel.org/en/developers/Documentation/cfg80211 https://wireless.wiki.kernel.org/en/developers/Documentation/cfg80211
When built as a module it will be called cfg80211. When built as a module it will be called cfg80211.
......
...@@ -497,6 +497,8 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, ...@@ -497,6 +497,8 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
INIT_WORK(&rdev->propagate_radar_detect_wk, INIT_WORK(&rdev->propagate_radar_detect_wk,
cfg80211_propagate_radar_detect_wk); cfg80211_propagate_radar_detect_wk);
INIT_WORK(&rdev->propagate_cac_done_wk, cfg80211_propagate_cac_done_wk); INIT_WORK(&rdev->propagate_cac_done_wk, cfg80211_propagate_cac_done_wk);
INIT_WORK(&rdev->mgmt_registrations_update_wk,
cfg80211_mgmt_registrations_update_wk);
#ifdef CONFIG_CFG80211_DEFAULT_PS #ifdef CONFIG_CFG80211_DEFAULT_PS
rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
...@@ -1047,6 +1049,7 @@ void wiphy_unregister(struct wiphy *wiphy) ...@@ -1047,6 +1049,7 @@ void wiphy_unregister(struct wiphy *wiphy)
flush_work(&rdev->sched_scan_stop_wk); flush_work(&rdev->sched_scan_stop_wk);
flush_work(&rdev->propagate_radar_detect_wk); flush_work(&rdev->propagate_radar_detect_wk);
flush_work(&rdev->propagate_cac_done_wk); flush_work(&rdev->propagate_cac_done_wk);
flush_work(&rdev->mgmt_registrations_update_wk);
#ifdef CONFIG_PM #ifdef CONFIG_PM
if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup)
...@@ -1108,7 +1111,6 @@ static void __cfg80211_unregister_wdev(struct wireless_dev *wdev, bool sync) ...@@ -1108,7 +1111,6 @@ static void __cfg80211_unregister_wdev(struct wireless_dev *wdev, bool sync)
rdev->devlist_generation++; rdev->devlist_generation++;
cfg80211_mlme_purge_registrations(wdev); cfg80211_mlme_purge_registrations(wdev);
flush_work(&wdev->mgmt_registrations_update_wk);
switch (wdev->iftype) { switch (wdev->iftype) {
case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_P2P_DEVICE:
...@@ -1253,8 +1255,6 @@ void cfg80211_init_wdev(struct cfg80211_registered_device *rdev, ...@@ -1253,8 +1255,6 @@ void cfg80211_init_wdev(struct cfg80211_registered_device *rdev,
spin_lock_init(&wdev->event_lock); spin_lock_init(&wdev->event_lock);
INIT_LIST_HEAD(&wdev->mgmt_registrations); INIT_LIST_HEAD(&wdev->mgmt_registrations);
spin_lock_init(&wdev->mgmt_registrations_lock); spin_lock_init(&wdev->mgmt_registrations_lock);
INIT_WORK(&wdev->mgmt_registrations_update_wk,
cfg80211_mgmt_registrations_update_wk);
INIT_LIST_HEAD(&wdev->pmsr_list); INIT_LIST_HEAD(&wdev->pmsr_list);
spin_lock_init(&wdev->pmsr_lock); spin_lock_init(&wdev->pmsr_lock);
INIT_WORK(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk); INIT_WORK(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);
......
...@@ -99,6 +99,8 @@ struct cfg80211_registered_device { ...@@ -99,6 +99,8 @@ struct cfg80211_registered_device {
struct cfg80211_chan_def cac_done_chandef; struct cfg80211_chan_def cac_done_chandef;
struct work_struct propagate_cac_done_wk; struct work_struct propagate_cac_done_wk;
struct work_struct mgmt_registrations_update_wk;
/* must be last because of the way we do wiphy_priv(), /* must be last because of the way we do wiphy_priv(),
* and it should at least be aligned to NETDEV_ALIGN */ * and it should at least be aligned to NETDEV_ALIGN */
struct wiphy wiphy __aligned(NETDEV_ALIGN); struct wiphy wiphy __aligned(NETDEV_ALIGN);
......
...@@ -440,9 +440,15 @@ static void cfg80211_mgmt_registrations_update(struct wireless_dev *wdev) ...@@ -440,9 +440,15 @@ static void cfg80211_mgmt_registrations_update(struct wireless_dev *wdev)
ASSERT_RTNL(); ASSERT_RTNL();
spin_lock_bh(&wdev->mgmt_registrations_lock);
if (!wdev->mgmt_registrations_need_update) {
spin_unlock_bh(&wdev->mgmt_registrations_lock);
return;
}
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(tmp, &rdev->wiphy.wdev_list, list) { list_for_each_entry_rcu(tmp, &rdev->wiphy.wdev_list, list) {
list_for_each_entry_rcu(reg, &tmp->mgmt_registrations, list) { list_for_each_entry(reg, &tmp->mgmt_registrations, list) {
u32 mask = BIT(le16_to_cpu(reg->frame_type) >> 4); u32 mask = BIT(le16_to_cpu(reg->frame_type) >> 4);
u32 mcast_mask = 0; u32 mcast_mask = 0;
...@@ -460,16 +466,23 @@ static void cfg80211_mgmt_registrations_update(struct wireless_dev *wdev) ...@@ -460,16 +466,23 @@ static void cfg80211_mgmt_registrations_update(struct wireless_dev *wdev)
} }
rcu_read_unlock(); rcu_read_unlock();
wdev->mgmt_registrations_need_update = 0;
spin_unlock_bh(&wdev->mgmt_registrations_lock);
rdev_update_mgmt_frame_registrations(rdev, wdev, &upd); rdev_update_mgmt_frame_registrations(rdev, wdev, &upd);
} }
void cfg80211_mgmt_registrations_update_wk(struct work_struct *wk) void cfg80211_mgmt_registrations_update_wk(struct work_struct *wk)
{ {
struct wireless_dev *wdev = container_of(wk, struct wireless_dev, struct cfg80211_registered_device *rdev;
mgmt_registrations_update_wk); struct wireless_dev *wdev;
rdev = container_of(wk, struct cfg80211_registered_device,
mgmt_registrations_update_wk);
rtnl_lock(); rtnl_lock();
cfg80211_mgmt_registrations_update(wdev); list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
cfg80211_mgmt_registrations_update(wdev);
rtnl_unlock(); rtnl_unlock();
} }
...@@ -557,6 +570,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid, ...@@ -557,6 +570,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
nreg->multicast_rx = multicast_rx; nreg->multicast_rx = multicast_rx;
list_add(&nreg->list, &wdev->mgmt_registrations); list_add(&nreg->list, &wdev->mgmt_registrations);
} }
wdev->mgmt_registrations_need_update = 1;
spin_unlock_bh(&wdev->mgmt_registrations_lock); spin_unlock_bh(&wdev->mgmt_registrations_lock);
cfg80211_mgmt_registrations_update(wdev); cfg80211_mgmt_registrations_update(wdev);
...@@ -585,7 +599,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid) ...@@ -585,7 +599,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
list_del(&reg->list); list_del(&reg->list);
kfree(reg); kfree(reg);
schedule_work(&wdev->mgmt_registrations_update_wk); wdev->mgmt_registrations_need_update = 1;
schedule_work(&rdev->mgmt_registrations_update_wk);
} }
spin_unlock_bh(&wdev->mgmt_registrations_lock); spin_unlock_bh(&wdev->mgmt_registrations_lock);
...@@ -608,6 +623,7 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) ...@@ -608,6 +623,7 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
list_del(&reg->list); list_del(&reg->list);
kfree(reg); kfree(reg);
} }
wdev->mgmt_registrations_need_update = 1;
spin_unlock_bh(&wdev->mgmt_registrations_lock); spin_unlock_bh(&wdev->mgmt_registrations_lock);
cfg80211_mgmt_registrations_update(wdev); cfg80211_mgmt_registrations_update(wdev);
......
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