Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be3d4810 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

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: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent d2372b31
Loading
Loading
Loading
Loading
+7 −4
Original line number Original line Diff line number Diff line
@@ -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],
		       &mydriver_jp_regdom.reg_rules[i],
		       sizeof(struct ieee80211_reg_rule));
		       sizeof(struct ieee80211_reg_rule));
	return regulatory_hint(hw->wiphy, NULL, rd);
	regulatory_struct_hint(rd);
+1 −1
Original line number Original line Diff line number Diff line
@@ -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:
+4 −19
Original line number Original line Diff line number Diff line
@@ -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 */
+1 −1
Original line number Original line Diff line number Diff line
@@ -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;
}
}
+16 −47
Original line number Original line Diff line number Diff line
@@ -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,21 +546,15 @@ 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:
@@ -582,15 +565,13 @@ int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
		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, "
Loading