wireless: get rid of pointless request list
We really only need to know the last request at each point in time. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
f3b407fba5
commit
f6037d09e2
@ -44,14 +44,13 @@
|
|||||||
|
|
||||||
/* wiphy is set if this request's initiator is REGDOM_SET_BY_DRIVER */
|
/* wiphy is set if this request's initiator is REGDOM_SET_BY_DRIVER */
|
||||||
struct regulatory_request {
|
struct regulatory_request {
|
||||||
struct list_head list;
|
|
||||||
struct wiphy *wiphy;
|
struct wiphy *wiphy;
|
||||||
int granted;
|
int granted;
|
||||||
enum reg_set_by initiator;
|
enum reg_set_by initiator;
|
||||||
char alpha2[2];
|
char alpha2[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
static LIST_HEAD(regulatory_requests);
|
static struct regulatory_request *last_request;
|
||||||
|
|
||||||
/* To trigger userspace events */
|
/* To trigger userspace events */
|
||||||
static struct platform_device *reg_pdev;
|
static struct platform_device *reg_pdev;
|
||||||
@ -201,7 +200,7 @@ static void reset_regdomains(void)
|
|||||||
* core upon initialization */
|
* core upon initialization */
|
||||||
static void update_world_regdomain(const struct ieee80211_regdomain *rd)
|
static void update_world_regdomain(const struct ieee80211_regdomain *rd)
|
||||||
{
|
{
|
||||||
BUG_ON(list_empty(®ulatory_requests));
|
BUG_ON(!last_request);
|
||||||
|
|
||||||
reset_regdomains();
|
reset_regdomains();
|
||||||
|
|
||||||
@ -302,15 +301,10 @@ static int call_crda(const char *alpha2)
|
|||||||
static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
|
static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
|
||||||
char *alpha2, struct ieee80211_regdomain *rd)
|
char *alpha2, struct ieee80211_regdomain *rd)
|
||||||
{
|
{
|
||||||
struct regulatory_request *last_request = NULL;
|
|
||||||
|
|
||||||
/* All initial requests are respected */
|
/* All initial requests are respected */
|
||||||
if (list_empty(®ulatory_requests))
|
if (!last_request)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
last_request = list_first_entry(®ulatory_requests,
|
|
||||||
struct regulatory_request, list);
|
|
||||||
|
|
||||||
switch (set_by) {
|
switch (set_by) {
|
||||||
case REGDOM_SET_BY_INIT:
|
case REGDOM_SET_BY_INIT:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -320,7 +314,7 @@ static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
|
|||||||
* anyway */
|
* anyway */
|
||||||
return 0;
|
return 0;
|
||||||
case REGDOM_SET_BY_COUNTRY_IE:
|
case REGDOM_SET_BY_COUNTRY_IE:
|
||||||
if (last_request->initiator == set_by) {
|
if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
|
||||||
if (last_request->wiphy != wiphy) {
|
if (last_request->wiphy != wiphy) {
|
||||||
/* Two cards with two APs claiming different
|
/* Two cards with two APs claiming different
|
||||||
* different Country IE alpha2s!
|
* different Country IE alpha2s!
|
||||||
@ -350,7 +344,7 @@ static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
|
|||||||
return 1;
|
return 1;
|
||||||
case REGDOM_SET_BY_DRIVER:
|
case REGDOM_SET_BY_DRIVER:
|
||||||
BUG_ON(!wiphy);
|
BUG_ON(!wiphy);
|
||||||
if (last_request->initiator == set_by) {
|
if (last_request->initiator == REGDOM_SET_BY_DRIVER) {
|
||||||
/* Two separate drivers hinting different things,
|
/* Two separate drivers hinting different things,
|
||||||
* this is possible if you have two devices present
|
* this is possible if you have two devices present
|
||||||
* on a system with different EEPROM regulatory
|
* on a system with different EEPROM regulatory
|
||||||
@ -376,7 +370,7 @@ static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
|
|||||||
return 0;
|
return 0;
|
||||||
return 0;
|
return 0;
|
||||||
case REGDOM_SET_BY_USER:
|
case REGDOM_SET_BY_USER:
|
||||||
if (last_request->initiator == set_by ||
|
if (last_request->initiator == REGDOM_SET_BY_USER ||
|
||||||
last_request->initiator == REGDOM_SET_BY_CORE)
|
last_request->initiator == REGDOM_SET_BY_CORE)
|
||||||
return 0;
|
return 0;
|
||||||
/* Drivers can use their wiphy's reg_notifier()
|
/* Drivers can use their wiphy's reg_notifier()
|
||||||
@ -392,26 +386,13 @@ static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool __reg_is_valid_request(const char *alpha2,
|
|
||||||
struct regulatory_request **request)
|
|
||||||
{
|
|
||||||
struct regulatory_request *req;
|
|
||||||
if (list_empty(®ulatory_requests))
|
|
||||||
return false;
|
|
||||||
list_for_each_entry(req, ®ulatory_requests, list) {
|
|
||||||
if (alpha2_equal(req->alpha2, alpha2)) {
|
|
||||||
*request = req;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Used by nl80211 before kmalloc'ing our regulatory domain */
|
/* Used by nl80211 before kmalloc'ing our regulatory domain */
|
||||||
bool reg_is_valid_request(const char *alpha2)
|
bool reg_is_valid_request(const char *alpha2)
|
||||||
{
|
{
|
||||||
struct regulatory_request *request = NULL;
|
if (!last_request)
|
||||||
return __reg_is_valid_request(alpha2, &request);
|
return false;
|
||||||
|
|
||||||
|
return alpha2_equal(last_request->alpha2, alpha2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity check on a regulatory rule */
|
/* Sanity check on a regulatory rule */
|
||||||
@ -607,7 +588,8 @@ int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
|
|||||||
request->initiator = set_by;
|
request->initiator = set_by;
|
||||||
request->wiphy = wiphy;
|
request->wiphy = wiphy;
|
||||||
|
|
||||||
list_add_tail(&request->list, ®ulatory_requests);
|
kfree(last_request);
|
||||||
|
last_request = request;
|
||||||
if (rd)
|
if (rd)
|
||||||
break;
|
break;
|
||||||
r = call_crda(alpha2);
|
r = call_crda(alpha2);
|
||||||
@ -711,12 +693,10 @@ void print_regdomain_info(const struct ieee80211_regdomain *rd)
|
|||||||
|
|
||||||
static int __set_regdom(const struct ieee80211_regdomain *rd)
|
static int __set_regdom(const struct ieee80211_regdomain *rd)
|
||||||
{
|
{
|
||||||
struct regulatory_request *request = NULL;
|
|
||||||
|
|
||||||
/* Some basic sanity checks first */
|
/* Some basic sanity checks first */
|
||||||
|
|
||||||
if (is_world_regdom(rd->alpha2)) {
|
if (is_world_regdom(rd->alpha2)) {
|
||||||
if (WARN_ON(!__reg_is_valid_request(rd->alpha2, &request)))
|
if (WARN_ON(!reg_is_valid_request(rd->alpha2)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
update_world_regdomain(rd);
|
update_world_regdomain(rd);
|
||||||
return 0;
|
return 0;
|
||||||
@ -726,7 +706,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
|
|||||||
!is_unknown_alpha2(rd->alpha2))
|
!is_unknown_alpha2(rd->alpha2))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (list_empty(®ulatory_requests))
|
if (!last_request)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* allow overriding the static definitions if CRDA is present */
|
/* allow overriding the static definitions if CRDA is present */
|
||||||
@ -739,13 +719,13 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
|
|||||||
* to review or adjust their own settings based on their own
|
* to review or adjust their own settings based on their own
|
||||||
* internal EEPROM data */
|
* internal EEPROM data */
|
||||||
|
|
||||||
if (WARN_ON(!__reg_is_valid_request(rd->alpha2, &request)))
|
if (WARN_ON(!reg_is_valid_request(rd->alpha2)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
reset_regdomains();
|
reset_regdomains();
|
||||||
|
|
||||||
/* Country IE parsing coming soon */
|
/* Country IE parsing coming soon */
|
||||||
switch (request->initiator) {
|
switch (last_request->initiator) {
|
||||||
case REGDOM_SET_BY_CORE:
|
case REGDOM_SET_BY_CORE:
|
||||||
case REGDOM_SET_BY_DRIVER:
|
case REGDOM_SET_BY_DRIVER:
|
||||||
case REGDOM_SET_BY_USER:
|
case REGDOM_SET_BY_USER:
|
||||||
@ -764,7 +744,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
|
|||||||
|
|
||||||
/* Tada! */
|
/* Tada! */
|
||||||
cfg80211_regdomain = rd;
|
cfg80211_regdomain = rd;
|
||||||
request->granted = 1;
|
last_request->granted = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -776,42 +756,18 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
|
|||||||
* the passed rd. Caller must hold cfg80211_drv_mutex */
|
* the passed rd. Caller must hold cfg80211_drv_mutex */
|
||||||
int set_regdom(const struct ieee80211_regdomain *rd)
|
int set_regdom(const struct ieee80211_regdomain *rd)
|
||||||
{
|
{
|
||||||
struct regulatory_request *this_request = NULL, *prev_request = NULL;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!list_empty(®ulatory_requests))
|
|
||||||
prev_request = list_first_entry(®ulatory_requests,
|
|
||||||
struct regulatory_request, list);
|
|
||||||
|
|
||||||
/* Note that this doesn't update the wiphys, this is done below */
|
/* Note that this doesn't update the wiphys, this is done below */
|
||||||
r = __set_regdom(rd);
|
r = __set_regdom(rd);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
BUG_ON((!__reg_is_valid_request(rd->alpha2, &this_request)));
|
|
||||||
|
|
||||||
/* The initial standard core update of the world regulatory domain, no
|
|
||||||
* need to keep that request info around if it didn't fail. */
|
|
||||||
if (is_world_regdom(rd->alpha2) &&
|
|
||||||
this_request->initiator == REGDOM_SET_BY_CORE &&
|
|
||||||
this_request->granted) {
|
|
||||||
list_del(&this_request->list);
|
|
||||||
kfree(this_request);
|
|
||||||
this_request = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove old requests, we only leave behind the last one */
|
|
||||||
if (prev_request) {
|
|
||||||
list_del(&prev_request->list);
|
|
||||||
kfree(prev_request);
|
|
||||||
prev_request = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This would make this whole thing pointless */
|
/* This would make this whole thing pointless */
|
||||||
BUG_ON(rd != cfg80211_regdomain);
|
BUG_ON(rd != cfg80211_regdomain);
|
||||||
|
|
||||||
/* update all wiphys now with the new established regulatory domain */
|
/* update all wiphys now with the new established regulatory domain */
|
||||||
update_all_wiphy_regulatory(this_request->initiator);
|
update_all_wiphy_regulatory(last_request->initiator);
|
||||||
|
|
||||||
print_regdomain(rd);
|
print_regdomain(rd);
|
||||||
|
|
||||||
@ -853,16 +809,12 @@ int regulatory_init(void)
|
|||||||
|
|
||||||
void regulatory_exit(void)
|
void regulatory_exit(void)
|
||||||
{
|
{
|
||||||
struct regulatory_request *req, *req_tmp;
|
|
||||||
|
|
||||||
mutex_lock(&cfg80211_drv_mutex);
|
mutex_lock(&cfg80211_drv_mutex);
|
||||||
|
|
||||||
reset_regdomains();
|
reset_regdomains();
|
||||||
|
|
||||||
list_for_each_entry_safe(req, req_tmp, ®ulatory_requests, list) {
|
kfree(last_request);
|
||||||
list_del(&req->list);
|
|
||||||
kfree(req);
|
|
||||||
}
|
|
||||||
platform_device_unregister(reg_pdev);
|
platform_device_unregister(reg_pdev);
|
||||||
|
|
||||||
mutex_unlock(&cfg80211_drv_mutex);
|
mutex_unlock(&cfg80211_drv_mutex);
|
||||||
|
Loading…
Reference in New Issue
Block a user