wireless: remove struct regdom hinting
The code needs to be split out and cleaned up, so as a first step remove the capability, to add it back in a subsequent patch as a separate function. Also remove the publically facing return value of the function and the wiphy argument. A number of internal functions go from being generic helpers to just being used for alpha2 setting. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
d2372b3152
commit
be3d48106c
6 changed files with 36 additions and 88 deletions
|
@ -131,11 +131,13 @@ are expected to do this during initialization.
|
||||||
|
|
||||||
r = zd_reg2alpha2(mac->regdomain, alpha2);
|
r = zd_reg2alpha2(mac->regdomain, alpha2);
|
||||||
if (!r)
|
if (!r)
|
||||||
regulatory_hint(hw->wiphy, alpha2, NULL);
|
regulatory_hint(hw->wiphy, alpha2);
|
||||||
|
|
||||||
Example code - drivers providing a built in regulatory domain:
|
Example code - drivers providing a built in regulatory domain:
|
||||||
--------------------------------------------------------------
|
--------------------------------------------------------------
|
||||||
|
|
||||||
|
[NOTE: This API is not currently available, it can be added when required]
|
||||||
|
|
||||||
If you have regulatory information you can obtain from your
|
If you have regulatory information you can obtain from your
|
||||||
driver and you *need* to use this we let you build a regulatory domain
|
driver and you *need* to use this we let you build a regulatory domain
|
||||||
structure and pass it to the wireless core. To do this you should
|
structure and pass it to the wireless core. To do this you should
|
||||||
|
@ -182,6 +184,7 @@ Then in some part of your code after your wiphy has been registered:
|
||||||
memcpy(rd, &mydriver_jp_regdom, sizeof(struct ieee80211_regdomain));
|
memcpy(rd, &mydriver_jp_regdom, sizeof(struct ieee80211_regdomain));
|
||||||
|
|
||||||
for (i=0; i < num_rules; i++)
|
for (i=0; i < num_rules; i++)
|
||||||
memcpy(&rd->reg_rules[i], &mydriver_jp_regdom.reg_rules[i],
|
memcpy(&rd->reg_rules[i],
|
||||||
sizeof(struct ieee80211_reg_rule));
|
&mydriver_jp_regdom.reg_rules[i],
|
||||||
return regulatory_hint(hw->wiphy, NULL, rd);
|
sizeof(struct ieee80211_reg_rule));
|
||||||
|
regulatory_struct_hint(rd);
|
||||||
|
|
|
@ -171,7 +171,7 @@ int zd_mac_init_hw(struct ieee80211_hw *hw)
|
||||||
|
|
||||||
r = zd_reg2alpha2(mac->regdomain, alpha2);
|
r = zd_reg2alpha2(mac->regdomain, alpha2);
|
||||||
if (!r)
|
if (!r)
|
||||||
regulatory_hint(hw->wiphy, alpha2, NULL);
|
regulatory_hint(hw->wiphy, alpha2);
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
disable_int:
|
disable_int:
|
||||||
|
|
|
@ -342,34 +342,19 @@ ieee80211_get_channel(struct wiphy *wiphy, int freq)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* regulatory_hint - driver hint to the wireless core a regulatory domain
|
* regulatory_hint - driver hint to the wireless core a regulatory domain
|
||||||
* @wiphy: the driver's very own &struct wiphy
|
* @wiphy: the wireless device giving the hint (used only for reporting
|
||||||
|
* conflicts)
|
||||||
* @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain
|
* @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain
|
||||||
* should be in. If @rd is set this should be NULL. Note that if you
|
* should be in. If @rd is set this should be NULL. Note that if you
|
||||||
* set this to NULL you should still set rd->alpha2 to some accepted
|
* set this to NULL you should still set rd->alpha2 to some accepted
|
||||||
* alpha2.
|
* alpha2.
|
||||||
* @rd: a complete regulatory domain provided by the driver. If passed
|
|
||||||
* the driver does not need to worry about freeing it.
|
|
||||||
*
|
*
|
||||||
* Wireless drivers can use this function to hint to the wireless core
|
* Wireless drivers can use this function to hint to the wireless core
|
||||||
* what it believes should be the current regulatory domain by
|
* what it believes should be the current regulatory domain by
|
||||||
* giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory
|
* giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory
|
||||||
* domain should be in or by providing a completely build regulatory domain.
|
* domain should be in or by providing a completely build regulatory domain.
|
||||||
* If the driver provides an ISO/IEC 3166 alpha2 userspace will be queried
|
* If the driver provides an ISO/IEC 3166 alpha2 userspace will be queried
|
||||||
* for a regulatory domain structure for the respective country. If
|
* for a regulatory domain structure for the respective country.
|
||||||
* a regulatory domain is build and passed you should set the alpha2
|
|
||||||
* if possible, otherwise set it to the special value of "99" which tells
|
|
||||||
* the wireless core it is unknown.
|
|
||||||
*
|
|
||||||
* Returns -EALREADY if *a regulatory domain* has already been set. Note that
|
|
||||||
* this could be by another driver. It is safe for drivers to continue if
|
|
||||||
* -EALREADY is returned, if drivers are not capable of world roaming they
|
|
||||||
* should not register more channels than they support. Right now we only
|
|
||||||
* support listening to the first driver hint. If the driver is capable
|
|
||||||
* of world roaming but wants to respect its own EEPROM mappings for
|
|
||||||
* specific regulatory domains it should register the @reg_notifier callback
|
|
||||||
* on the &struct wiphy. Returns 0 if the hint went through fine or through an
|
|
||||||
* intersection operation. Otherwise a standard error code is returned.
|
|
||||||
*/
|
*/
|
||||||
extern int regulatory_hint(struct wiphy *wiphy,
|
extern void regulatory_hint(struct wiphy *wiphy, const char *alpha2);
|
||||||
const char *alpha2, struct ieee80211_regdomain *rd);
|
|
||||||
#endif /* __NET_WIRELESS_H */
|
#endif /* __NET_WIRELESS_H */
|
||||||
|
|
|
@ -1695,7 +1695,7 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
#endif
|
#endif
|
||||||
mutex_lock(&cfg80211_drv_mutex);
|
mutex_lock(&cfg80211_drv_mutex);
|
||||||
r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, NULL);
|
r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data);
|
||||||
mutex_unlock(&cfg80211_drv_mutex);
|
mutex_unlock(&cfg80211_drv_mutex);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,10 @@
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "reg.h"
|
#include "reg.h"
|
||||||
|
|
||||||
/* 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_COUNTRY_IE or _DRIVER
|
||||||
|
*/
|
||||||
struct regulatory_request {
|
struct regulatory_request {
|
||||||
struct wiphy *wiphy;
|
struct wiphy *wiphy;
|
||||||
enum reg_set_by initiator;
|
enum reg_set_by initiator;
|
||||||
|
@ -298,7 +301,7 @@ static int call_crda(const char *alpha2)
|
||||||
/* This has the logic which determines when a new request
|
/* This has the logic which determines when a new request
|
||||||
* should be ignored. */
|
* should be ignored. */
|
||||||
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)
|
const char *alpha2)
|
||||||
{
|
{
|
||||||
/* All initial requests are respected */
|
/* All initial requests are respected */
|
||||||
if (!last_request)
|
if (!last_request)
|
||||||
|
@ -343,22 +346,8 @@ 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 == REGDOM_SET_BY_DRIVER) {
|
if (last_request->initiator == REGDOM_SET_BY_DRIVER)
|
||||||
/* Two separate drivers hinting different things,
|
|
||||||
* this is possible if you have two devices present
|
|
||||||
* on a system with different EEPROM regulatory
|
|
||||||
* readings. XXX: Do intersection, we support only
|
|
||||||
* the first regulatory hint for now */
|
|
||||||
if (last_request->wiphy != wiphy)
|
|
||||||
return -EALREADY;
|
|
||||||
if (rd)
|
|
||||||
return -EALREADY;
|
|
||||||
/* Driver should not be trying to hint different
|
|
||||||
* regulatory domains! */
|
|
||||||
BUG_ON(!alpha2_equal(alpha2,
|
|
||||||
cfg80211_regdomain->alpha2));
|
|
||||||
return -EALREADY;
|
return -EALREADY;
|
||||||
}
|
|
||||||
if (last_request->initiator == REGDOM_SET_BY_CORE)
|
if (last_request->initiator == REGDOM_SET_BY_CORE)
|
||||||
return 0;
|
return 0;
|
||||||
/* XXX: Handle intersection, and add the
|
/* XXX: Handle intersection, and add the
|
||||||
|
@ -557,40 +546,32 @@ void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby)
|
||||||
|
|
||||||
/* Caller must hold &cfg80211_drv_mutex */
|
/* Caller must hold &cfg80211_drv_mutex */
|
||||||
int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
|
int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
|
||||||
const char *alpha2, struct ieee80211_regdomain *rd)
|
const char *alpha2)
|
||||||
{
|
{
|
||||||
struct regulatory_request *request;
|
struct regulatory_request *request;
|
||||||
char *rd_alpha2;
|
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
r = ignore_request(wiphy, set_by, (char *) alpha2, rd);
|
r = ignore_request(wiphy, set_by, alpha2);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (rd)
|
|
||||||
rd_alpha2 = rd->alpha2;
|
|
||||||
else
|
|
||||||
rd_alpha2 = (char *) alpha2;
|
|
||||||
|
|
||||||
switch (set_by) {
|
switch (set_by) {
|
||||||
case REGDOM_SET_BY_CORE:
|
case REGDOM_SET_BY_CORE:
|
||||||
case REGDOM_SET_BY_COUNTRY_IE:
|
case REGDOM_SET_BY_COUNTRY_IE:
|
||||||
case REGDOM_SET_BY_DRIVER:
|
case REGDOM_SET_BY_DRIVER:
|
||||||
case REGDOM_SET_BY_USER:
|
case REGDOM_SET_BY_USER:
|
||||||
request = kzalloc(sizeof(struct regulatory_request),
|
request = kzalloc(sizeof(struct regulatory_request),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!request)
|
if (!request)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
request->alpha2[0] = rd_alpha2[0];
|
request->alpha2[0] = alpha2[0];
|
||||||
request->alpha2[1] = rd_alpha2[1];
|
request->alpha2[1] = alpha2[1];
|
||||||
request->initiator = set_by;
|
request->initiator = set_by;
|
||||||
request->wiphy = wiphy;
|
request->wiphy = wiphy;
|
||||||
|
|
||||||
kfree(last_request);
|
kfree(last_request);
|
||||||
last_request = request;
|
last_request = request;
|
||||||
if (rd)
|
|
||||||
break;
|
|
||||||
r = call_crda(alpha2);
|
r = call_crda(alpha2);
|
||||||
#ifndef CONFIG_WIRELESS_OLD_REGULATORY
|
#ifndef CONFIG_WIRELESS_OLD_REGULATORY
|
||||||
if (r)
|
if (r)
|
||||||
|
@ -605,25 +586,13 @@ int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int regulatory_hint(struct wiphy *wiphy, const char *alpha2,
|
void regulatory_hint(struct wiphy *wiphy, const char *alpha2)
|
||||||
struct ieee80211_regdomain *rd)
|
|
||||||
{
|
{
|
||||||
int r;
|
BUG_ON(!alpha2);
|
||||||
BUG_ON(!rd && !alpha2);
|
|
||||||
|
|
||||||
mutex_lock(&cfg80211_drv_mutex);
|
mutex_lock(&cfg80211_drv_mutex);
|
||||||
|
__regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER, alpha2);
|
||||||
r = __regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER, alpha2, rd);
|
|
||||||
if (r || !rd)
|
|
||||||
goto unlock_and_exit;
|
|
||||||
|
|
||||||
/* If the driver passed a regulatory domain we skipped asking
|
|
||||||
* userspace for one so we can now go ahead and set it */
|
|
||||||
r = set_regdom(rd);
|
|
||||||
|
|
||||||
unlock_and_exit:
|
|
||||||
mutex_unlock(&cfg80211_drv_mutex);
|
mutex_unlock(&cfg80211_drv_mutex);
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(regulatory_hint);
|
EXPORT_SYMBOL(regulatory_hint);
|
||||||
|
|
||||||
|
@ -792,11 +761,11 @@ int regulatory_init(void)
|
||||||
* that is not a valid ISO / IEC 3166 alpha2 */
|
* that is not a valid ISO / IEC 3166 alpha2 */
|
||||||
if (ieee80211_regdom[0] != 'E' || ieee80211_regdom[1] != 'U')
|
if (ieee80211_regdom[0] != 'E' || ieee80211_regdom[1] != 'U')
|
||||||
err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE,
|
err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE,
|
||||||
ieee80211_regdom, NULL);
|
ieee80211_regdom);
|
||||||
#else
|
#else
|
||||||
cfg80211_regdomain = cfg80211_world_regdom;
|
cfg80211_regdomain = cfg80211_world_regdom;
|
||||||
|
|
||||||
err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE, "00", NULL);
|
err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE, "00");
|
||||||
if (err)
|
if (err)
|
||||||
printk(KERN_ERR "cfg80211: calling CRDA failed - "
|
printk(KERN_ERR "cfg80211: calling CRDA failed - "
|
||||||
"unable to update world regulatory domain, "
|
"unable to update world regulatory domain, "
|
||||||
|
|
|
@ -11,30 +11,21 @@ int set_regdom(const struct ieee80211_regdomain *rd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __regulatory_hint - hint to the wireless core a regulatory domain
|
* __regulatory_hint - hint to the wireless core a regulatory domain
|
||||||
* @wiphy: if a driver is providing the hint this is the driver's very
|
* @wiphy: if the hint comes from country information from an AP, this
|
||||||
* own &struct wiphy
|
* is required to be set to the wiphy that received the information
|
||||||
* @alpha2: the ISO/IEC 3166 alpha2 being claimed the regulatory domain
|
* @alpha2: the ISO/IEC 3166 alpha2 being claimed the regulatory domain
|
||||||
* should be in. If @rd is set this should be NULL
|
* should be in.
|
||||||
* @rd: a complete regulatory domain, if passed the caller need not worry
|
|
||||||
* about freeing it
|
|
||||||
*
|
*
|
||||||
* The Wireless subsystem can use this function to hint to the wireless core
|
* The Wireless subsystem can use this function to hint to the wireless core
|
||||||
* what it believes should be the current regulatory domain by
|
* what it believes should be the current regulatory domain by
|
||||||
* giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory
|
* giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory
|
||||||
* domain should be in or by providing a completely build regulatory domain.
|
* domain should be in.
|
||||||
*
|
*
|
||||||
* Returns -EALREADY if *a regulatory domain* has already been set. Note that
|
* Returns zero if all went fine, %-EALREADY if a regulatory domain had
|
||||||
* this could be by another driver. It is safe for drivers to continue if
|
* already been set or other standard error codes.
|
||||||
* -EALREADY is returned, if drivers are not capable of world roaming they
|
|
||||||
* should not register more channels than they support. Right now we only
|
|
||||||
* support listening to the first driver hint. If the driver is capable
|
|
||||||
* of world roaming but wants to respect its own EEPROM mappings for
|
|
||||||
* specific regulatory domains it should register the @reg_notifier callback
|
|
||||||
* on the &struct wiphy. Returns 0 if the hint went through fine or through an
|
|
||||||
* intersection operation. Otherwise a standard error code is returned.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
extern int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
|
extern int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
|
||||||
const char *alpha2, struct ieee80211_regdomain *rd);
|
const char *alpha2);
|
||||||
|
|
||||||
#endif /* __NET_WIRELESS_REG_H */
|
#endif /* __NET_WIRELESS_REG_H */
|
||||||
|
|
Loading…
Reference in a new issue