cfg80211: process driver regulatory requests on its own
This makes the code easier to read and follow. Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
0d97a61917
commit
21636c7faa
1 changed files with 86 additions and 17 deletions
|
@ -1338,6 +1338,7 @@ get_reg_request_treatment(struct wiphy *wiphy,
|
||||||
switch (pending_request->initiator) {
|
switch (pending_request->initiator) {
|
||||||
case NL80211_REGDOM_SET_BY_CORE:
|
case NL80211_REGDOM_SET_BY_CORE:
|
||||||
case NL80211_REGDOM_SET_BY_USER:
|
case NL80211_REGDOM_SET_BY_USER:
|
||||||
|
case NL80211_REGDOM_SET_BY_DRIVER:
|
||||||
return REG_REQ_IGNORE;
|
return REG_REQ_IGNORE;
|
||||||
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
|
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
|
||||||
if (reg_request_cell_base(lr)) {
|
if (reg_request_cell_base(lr)) {
|
||||||
|
@ -1372,23 +1373,6 @@ get_reg_request_treatment(struct wiphy *wiphy,
|
||||||
return REG_REQ_ALREADY_SET;
|
return REG_REQ_ALREADY_SET;
|
||||||
}
|
}
|
||||||
return REG_REQ_OK;
|
return REG_REQ_OK;
|
||||||
case NL80211_REGDOM_SET_BY_DRIVER:
|
|
||||||
if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) {
|
|
||||||
if (regdom_changes(pending_request->alpha2))
|
|
||||||
return REG_REQ_OK;
|
|
||||||
return REG_REQ_ALREADY_SET;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This would happen if you unplug and plug your card
|
|
||||||
* back in or if you add a new device for which the previously
|
|
||||||
* loaded card also agrees on the regulatory domain.
|
|
||||||
*/
|
|
||||||
if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
|
|
||||||
!regdom_changes(pending_request->alpha2))
|
|
||||||
return REG_REQ_ALREADY_SET;
|
|
||||||
|
|
||||||
return REG_REQ_INTERSECT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return REG_REQ_IGNORE;
|
return REG_REQ_IGNORE;
|
||||||
|
@ -1514,6 +1498,89 @@ reg_process_hint_user(struct regulatory_request *user_request)
|
||||||
return REG_REQ_OK;
|
return REG_REQ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum reg_request_treatment
|
||||||
|
__reg_process_hint_driver(struct regulatory_request *driver_request)
|
||||||
|
{
|
||||||
|
struct regulatory_request *lr = get_last_request();
|
||||||
|
|
||||||
|
if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) {
|
||||||
|
if (regdom_changes(driver_request->alpha2))
|
||||||
|
return REG_REQ_OK;
|
||||||
|
return REG_REQ_ALREADY_SET;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This would happen if you unplug and plug your card
|
||||||
|
* back in or if you add a new device for which the previously
|
||||||
|
* loaded card also agrees on the regulatory domain.
|
||||||
|
*/
|
||||||
|
if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
|
||||||
|
!regdom_changes(driver_request->alpha2))
|
||||||
|
return REG_REQ_ALREADY_SET;
|
||||||
|
|
||||||
|
return REG_REQ_INTERSECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reg_process_hint_driver - process driver regulatory requests
|
||||||
|
* @driver_request: a pending driver regulatory request
|
||||||
|
*
|
||||||
|
* The wireless subsystem can use this function to process
|
||||||
|
* a regulatory request issued by an 802.11 driver.
|
||||||
|
*
|
||||||
|
* Returns one of the different reg request treatment values.
|
||||||
|
*/
|
||||||
|
static enum reg_request_treatment
|
||||||
|
reg_process_hint_driver(struct wiphy *wiphy,
|
||||||
|
struct regulatory_request *driver_request)
|
||||||
|
{
|
||||||
|
const struct ieee80211_regdomain *regd;
|
||||||
|
enum reg_request_treatment treatment;
|
||||||
|
struct regulatory_request *lr;
|
||||||
|
|
||||||
|
treatment = __reg_process_hint_driver(driver_request);
|
||||||
|
|
||||||
|
switch (treatment) {
|
||||||
|
case REG_REQ_OK:
|
||||||
|
break;
|
||||||
|
case REG_REQ_IGNORE:
|
||||||
|
kfree(driver_request);
|
||||||
|
return treatment;
|
||||||
|
case REG_REQ_INTERSECT:
|
||||||
|
/* fall through */
|
||||||
|
case REG_REQ_ALREADY_SET:
|
||||||
|
regd = reg_copy_regd(get_cfg80211_regdom());
|
||||||
|
if (IS_ERR(regd)) {
|
||||||
|
kfree(driver_request);
|
||||||
|
return REG_REQ_IGNORE;
|
||||||
|
}
|
||||||
|
rcu_assign_pointer(wiphy->regd, regd);
|
||||||
|
}
|
||||||
|
|
||||||
|
lr = get_last_request();
|
||||||
|
if (lr != &core_request_world && lr)
|
||||||
|
kfree_rcu(lr, rcu_head);
|
||||||
|
|
||||||
|
driver_request->intersect = treatment == REG_REQ_INTERSECT;
|
||||||
|
driver_request->processed = false;
|
||||||
|
rcu_assign_pointer(last_request, driver_request);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since CRDA will not be called in this case as we already
|
||||||
|
* have applied the requested regulatory domain before we just
|
||||||
|
* inform userspace we have processed the request
|
||||||
|
*/
|
||||||
|
if (treatment == REG_REQ_ALREADY_SET) {
|
||||||
|
nl80211_send_reg_change_event(driver_request);
|
||||||
|
reg_set_request_processed();
|
||||||
|
return treatment;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (call_crda(driver_request->alpha2))
|
||||||
|
return REG_REQ_IGNORE;
|
||||||
|
return REG_REQ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __regulatory_hint - hint to the wireless core a regulatory domain
|
* __regulatory_hint - hint to the wireless core a regulatory domain
|
||||||
* @wiphy: if the hint comes from country information from an AP, this
|
* @wiphy: if the hint comes from country information from an AP, this
|
||||||
|
@ -1637,6 +1704,8 @@ static void reg_process_hint(struct regulatory_request *reg_request)
|
||||||
schedule_delayed_work(®_timeout, msecs_to_jiffies(3142));
|
schedule_delayed_work(®_timeout, msecs_to_jiffies(3142));
|
||||||
return;
|
return;
|
||||||
case NL80211_REGDOM_SET_BY_DRIVER:
|
case NL80211_REGDOM_SET_BY_DRIVER:
|
||||||
|
treatment = reg_process_hint_driver(wiphy, reg_request);
|
||||||
|
break;
|
||||||
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
|
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
|
||||||
treatment = __regulatory_hint(wiphy, reg_request);
|
treatment = __regulatory_hint(wiphy, reg_request);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Reference in a new issue