.country_ie_env = ENVIRON_ANY,
};
-/* Receipt of information from last regulatory request */
+/*
+ * Receipt of information from last regulatory request,
+ * protected by RTNL (and can be accessed with RCU protection)
+ */
static struct regulatory_request __rcu *last_request =
(void __rcu *)&core_request_world;
* Central wireless core regulatory domains, we only need two,
* the current one and a world regulatory domain in case we have no
* information to give us an alpha2.
+ * (protected by RTNL, can be read under RCU)
*/
const struct ieee80211_regdomain __rcu *cfg80211_regdomain;
-/*
- * Protects static reg.c components:
- * - cfg80211_regdomain (if not used with RCU)
- * - cfg80211_world_regdom
- * - last_request (if not used with RCU)
- * - reg_num_devs_support_basehint
- */
-static DEFINE_MUTEX(reg_mutex);
-
/*
* Number of devices that registered to the core
* that support cellular base station regulatory hints
+ * (protected by RTNL)
*/
static int reg_num_devs_support_basehint;
-static inline void assert_reg_lock(void)
-{
- lockdep_assert_held(®_mutex);
-}
-
static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
{
- return rcu_dereference_protected(cfg80211_regdomain,
- lockdep_is_held(®_mutex));
+ return rtnl_dereference(cfg80211_regdomain);
}
static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy)
{
- return rcu_dereference_protected(wiphy->regd,
- lockdep_is_held(®_mutex));
+ return rtnl_dereference(wiphy->regd);
}
static void rcu_free_regdom(const struct ieee80211_regdomain *r)
static struct regulatory_request *get_last_request(void)
{
- return rcu_dereference_check(last_request,
- lockdep_is_held(®_mutex));
+ return rcu_dereference_rtnl(last_request);
}
/* Used to queue up regulatory hints */
}
};
+/* protected by RTNL */
static const struct ieee80211_regdomain *cfg80211_world_regdom =
&world_regdom;
const struct ieee80211_regdomain *r;
struct regulatory_request *lr;
- assert_reg_lock();
+ ASSERT_RTNL();
r = get_cfg80211_regdom();
bool reg_last_request_cell_base(void)
{
- bool val;
-
- mutex_lock(®_mutex);
- val = reg_request_cell_base(get_last_request());
- mutex_unlock(®_mutex);
-
- return val;
+ return reg_request_cell_base(get_last_request());
}
#ifdef CONFIG_CFG80211_CERTIFICATION_ONUS
* what it believes should be the current regulatory domain.
*
* Returns one of the different reg request treatment values.
- *
- * Caller must hold ®_mutex
*/
static enum reg_request_treatment
__regulatory_hint(struct wiphy *wiphy,
static void reg_todo(struct work_struct *work)
{
rtnl_lock();
- mutex_lock(®_mutex);
reg_process_pending_hints();
reg_process_pending_beacon_hints();
- mutex_unlock(®_mutex);
rtnl_unlock();
}
ASSERT_RTNL();
- mutex_lock(®_mutex);
-
reset_regdomains(true, &world_regdom);
restore_alpha2(alpha2, reset_user);
list_splice_tail_init(&tmp_reg_req_list, ®_requests_list);
spin_unlock(®_requests_lock);
- mutex_unlock(®_mutex);
-
REG_DBG_PRINT("Kicking the queue\n");
schedule_work(®_work);
struct regulatory_request *lr;
int r;
- mutex_lock(®_mutex);
lr = get_last_request();
/* Note that this doesn't update the wiphys, this is done below */
reg_set_request_processed();
kfree(rd);
- goto out;
+ return r;
}
/* This would make this whole thing pointless */
- if (WARN_ON(!lr->intersect && rd != get_cfg80211_regdom())) {
- r = -EINVAL;
- goto out;
- }
+ if (WARN_ON(!lr->intersect && rd != get_cfg80211_regdom()))
+ return -EINVAL;
/* update all wiphys now with the new established regulatory domain */
update_all_wiphy_regulatory(lr->initiator);
reg_set_request_processed();
- out:
- mutex_unlock(®_mutex);
-
- return r;
+ return 0;
}
int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
void wiphy_regulatory_register(struct wiphy *wiphy)
{
- mutex_lock(®_mutex);
-
if (!reg_dev_ignore_cell_hint(wiphy))
reg_num_devs_support_basehint++;
wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
-
- mutex_unlock(®_mutex);
}
void wiphy_regulatory_deregister(struct wiphy *wiphy)
struct wiphy *request_wiphy = NULL;
struct regulatory_request *lr;
- mutex_lock(®_mutex);
lr = get_last_request();
if (!reg_dev_ignore_cell_hint(wiphy))
request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx);
if (!request_wiphy || request_wiphy != wiphy)
- goto out;
+ return;
lr->wiphy_idx = WIPHY_IDX_INVALID;
lr->country_ie_env = ENVIRON_ANY;
-out:
- mutex_unlock(®_mutex);
}
static void reg_timeout_work(struct work_struct *work)
cancel_delayed_work_sync(®_timeout);
/* Lock to suppress warnings */
- mutex_lock(®_mutex);
+ rtnl_lock();
reset_regdomains(true, NULL);
- mutex_unlock(®_mutex);
+ rtnl_unlock();
dev_set_uevent_suppress(®_pdev->dev, true);