2014-08-19 08:22:23

by Tomasz Bursztyka

[permalink] [raw]
Subject: [PATCH cfg80211 v2] wireless: core: Reorder wiphy_register() notifications relevantly

Currently it can send regulatory domain change notification before any
NEW_WIPHY notification. Moreover, if rfill_register() fails, calling
wiphy_unregister() will send a DEL_WIPHY though no NEW_WIPHY had been
sent previously.

Thus reordering so it properly notifies NEW_WIPHY before any other.

Signed-off-by: Tomasz Bursztyka <[email protected]>
---

Reusing "registered" marker to know whether it sent NEW_WIPHY yet or not.
Thus if wiphy_unregister() is called du to rfkill registration failure, it
won't send DEL_WIPHY.

net/wireless/core.c | 33 +++++++++++++++++++--------------
1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/net/wireless/core.c b/net/wireless/core.c
index afee5e0..08162e8 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -635,6 +635,21 @@ int wiphy_register(struct wiphy *wiphy)
if (IS_ERR(rdev->wiphy.debugfsdir))
rdev->wiphy.debugfsdir = NULL;

+ cfg80211_debugfs_rdev_add(rdev);
+ rtnl_unlock();
+
+ res = rfkill_register(rdev->rfkill);
+ if (res) {
+ rfkill_destroy(rdev->rfkill);
+ rdev->rfkill = NULL;
+ wiphy_unregister(&rdev->wiphy);
+ return res;
+ }
+
+ rtnl_lock();
+
+ nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);
+
if (wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) {
struct regulatory_request request;

@@ -646,21 +661,9 @@ int wiphy_register(struct wiphy *wiphy)
nl80211_send_reg_change_event(&request);
}

- cfg80211_debugfs_rdev_add(rdev);
-
rdev->wiphy.registered = true;
rtnl_unlock();

- res = rfkill_register(rdev->rfkill);
- if (res) {
- rfkill_destroy(rdev->rfkill);
- rdev->rfkill = NULL;
- wiphy_unregister(&rdev->wiphy);
- return res;
- }
-
- nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);
-
return 0;
}
EXPORT_SYMBOL(wiphy_register);
@@ -699,8 +702,10 @@ void wiphy_unregister(struct wiphy *wiphy)
rfkill_unregister(rdev->rfkill);

rtnl_lock();
- nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY);
- rdev->wiphy.registered = false;
+ if (rdev->wiphy.registered) {
+ nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY);
+ rdev->wiphy.registered = false;
+ }

WARN_ON(!list_empty(&rdev->wdev_list));

--
1.8.5.5