@@ -537,6 +537,7 @@ int wiphy_register(struct wiphy *wiphy)
}
/* set up regulatory info */
+ wiphy_regulatory_register(wiphy);
regulatory_update(wiphy, NL80211_REGDOM_SET_BY_CORE);
list_add_rcu(&rdev->list, &cfg80211_rdev_list);
@@ -97,9 +97,16 @@ const struct ieee80211_regdomain *cfg80211_regdomain;
* - cfg80211_world_regdom
* - cfg80211_regdom
* - last_request
+ * - 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
+ */
+static int reg_num_devs_support_basehint;
+
static inline void assert_reg_lock(void)
{
lockdep_assert_held(®_mutex);
@@ -934,6 +941,9 @@ bool reg_last_request_cell_base(void)
/* Core specific check */
static int reg_ignore_cell_hint(struct regulatory_request *pending_request)
{
+ if (!reg_num_devs_support_basehint)
+ return -EOPNOTSUPP;
+
if (reg_request_cell_base(last_request)) {
if (!regdom_changes(pending_request->alpha2))
return -EALREADY;
@@ -2365,6 +2375,18 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
}
#endif /* CONFIG_HOTPLUG */
+void wiphy_regulatory_register(struct wiphy *wiphy)
+{
+ assert_cfg80211_lock();
+
+ mutex_lock(®_mutex);
+
+ if (!reg_dev_ignore_cell_hint(wiphy))
+ reg_num_devs_support_basehint++;
+
+ mutex_unlock(®_mutex);
+}
+
/* Caller must hold cfg80211_mutex */
void reg_device_remove(struct wiphy *wiphy)
{
@@ -2374,6 +2396,9 @@ void reg_device_remove(struct wiphy *wiphy)
mutex_lock(®_mutex);
+ if (!reg_dev_ignore_cell_hint(wiphy))
+ reg_num_devs_support_basehint--;
+
kfree(wiphy->regd);
if (last_request)
@@ -26,6 +26,7 @@ int regulatory_hint_user(const char *alpha2,
enum nl80211_user_reg_hint_type user_reg_hint_type);
int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env);
+void wiphy_regulatory_register(struct wiphy *wiphy);
void reg_device_remove(struct wiphy *wiphy);
int __init regulatory_init(void);