static void reg_free_request(struct regulatory_request *request)
{
+ if (request == &core_request_world)
+ return;
+
if (request != get_last_request())
kfree(request);
}
}
EXPORT_SYMBOL(reg_initiator_name);
-#ifdef CONFIG_CFG80211_REG_DEBUG
static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
struct ieee80211_channel *chan,
const struct ieee80211_reg_rule *reg_rule)
{
+#ifdef CONFIG_CFG80211_REG_DEBUG
const struct ieee80211_power_rule *power_rule;
const struct ieee80211_freq_range *freq_range;
char max_antenna_gain[32], bw[32];
if (!power_rule->max_antenna_gain)
snprintf(max_antenna_gain, sizeof(max_antenna_gain), "N/A");
else
- snprintf(max_antenna_gain, sizeof(max_antenna_gain), "%d",
+ snprintf(max_antenna_gain, sizeof(max_antenna_gain), "%d mBi",
power_rule->max_antenna_gain);
if (reg_rule->flags & NL80211_RRF_AUTO_BW)
REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n",
chan->center_freq);
- REG_DBG_PRINT("%d KHz - %d KHz @ %s), (%s mBi, %d mBm)\n",
+ REG_DBG_PRINT("(%d KHz - %d KHz @ %s), (%s, %d mBm)\n",
freq_range->start_freq_khz, freq_range->end_freq_khz,
bw, max_antenna_gain,
power_rule->max_eirp);
-}
-#else
-static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
- struct ieee80211_channel *chan,
- const struct ieee80211_reg_rule *reg_rule)
-{
- return;
-}
#endif
+}
/*
* Note that right now we assume the desired channel bandwidth
return !(wiphy->features & NL80211_FEATURE_CELL_BASE_REG_HINTS);
}
#else
-static int reg_ignore_cell_hint(struct regulatory_request *pending_request)
+static enum reg_request_treatment
+reg_ignore_cell_hint(struct regulatory_request *pending_request)
{
return REG_REQ_IGNORE;
}
* The wireless subsystem can use this function to process
* a regulatory request issued by the regulatory core.
*/
-static void reg_process_hint_core(struct regulatory_request *core_request)
+static enum reg_request_treatment
+reg_process_hint_core(struct regulatory_request *core_request)
{
if (reg_query_database(core_request)) {
core_request->intersect = false;
core_request->processed = false;
reg_update_last_request(core_request);
+ return REG_REQ_OK;
}
+
+ return REG_REQ_IGNORE;
}
static enum reg_request_treatment
* The wireless subsystem can use this function to process
* a regulatory request initiated by userspace.
*/
-static void reg_process_hint_user(struct regulatory_request *user_request)
+static enum reg_request_treatment
+reg_process_hint_user(struct regulatory_request *user_request)
{
enum reg_request_treatment treatment;
treatment = __reg_process_hint_user(user_request);
if (treatment == REG_REQ_IGNORE ||
- treatment == REG_REQ_ALREADY_SET) {
- reg_free_request(user_request);
- return;
- }
+ treatment == REG_REQ_ALREADY_SET)
+ return REG_REQ_IGNORE;
user_request->intersect = treatment == REG_REQ_INTERSECT;
user_request->processed = false;
reg_update_last_request(user_request);
user_alpha2[0] = user_request->alpha2[0];
user_alpha2[1] = user_request->alpha2[1];
- } else {
- reg_free_request(user_request);
+ return REG_REQ_OK;
}
+
+ return REG_REQ_IGNORE;
}
static enum reg_request_treatment
case REG_REQ_OK:
break;
case REG_REQ_IGNORE:
- reg_free_request(driver_request);
- return REG_REQ_OK;
+ return REG_REQ_IGNORE;
case REG_REQ_INTERSECT:
case REG_REQ_ALREADY_SET:
regd = reg_copy_regd(get_cfg80211_regdom());
- if (IS_ERR(regd)) {
- reg_free_request(driver_request);
- return REG_REQ_OK;
- }
+ if (IS_ERR(regd))
+ return REG_REQ_IGNORE;
tmp = get_wiphy_regdom(wiphy);
rcu_assign_pointer(wiphy->regd, regd);
return REG_REQ_ALREADY_SET;
}
- if (reg_query_database(driver_request))
+ if (reg_query_database(driver_request)) {
reg_update_last_request(driver_request);
- else
- reg_free_request(driver_request);
+ return REG_REQ_OK;
+ }
- return REG_REQ_OK;
+ return REG_REQ_IGNORE;
}
static enum reg_request_treatment
case REG_REQ_OK:
break;
case REG_REQ_IGNORE:
- return REG_REQ_OK;
+ return REG_REQ_IGNORE;
case REG_REQ_ALREADY_SET:
reg_free_request(country_ie_request);
return REG_REQ_ALREADY_SET;
case REG_REQ_INTERSECT:
- reg_free_request(country_ie_request);
/*
* This doesn't happen yet, not sure we
* ever want to support it for this case.
*/
WARN_ONCE(1, "Unexpected intersection for country IEs");
- return REG_REQ_OK;
+ return REG_REQ_IGNORE;
}
country_ie_request->intersect = false;
country_ie_request->processed = false;
- if (reg_query_database(country_ie_request))
+ if (reg_query_database(country_ie_request)) {
reg_update_last_request(country_ie_request);
- else
- reg_free_request(country_ie_request);
+ return REG_REQ_OK;
+ }
- return REG_REQ_OK;
+ return REG_REQ_IGNORE;
}
/* This processes *all* regulatory hints */
switch (reg_request->initiator) {
case NL80211_REGDOM_SET_BY_CORE:
- reg_process_hint_core(reg_request);
- return;
+ treatment = reg_process_hint_core(reg_request);
+ break;
case NL80211_REGDOM_SET_BY_USER:
- reg_process_hint_user(reg_request);
- return;
+ treatment = reg_process_hint_user(reg_request);
+ break;
case NL80211_REGDOM_SET_BY_DRIVER:
if (!wiphy)
goto out_free;
goto out_free;
}
+ if (treatment == REG_REQ_IGNORE)
+ goto out_free;
+
WARN(treatment != REG_REQ_OK && treatment != REG_REQ_ALREADY_SET,
"unexpected treatment value %d\n", treatment);