Commit 0390bf7a authored by Roland Vossen's avatar Roland Vossen Committed by Greg Kroah-Hartman

staging: brcm80211: removed static function declarations in channel.c

Reported-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarRoland Vossen <rvossen@broadcom.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent d5adafb0
...@@ -29,6 +29,53 @@ ...@@ -29,6 +29,53 @@
brcms_c_valid_channel20_in_band((wlc)->cmi, bandunit, val) brcms_c_valid_channel20_in_band((wlc)->cmi, bandunit, val)
#define VALID_CHANNEL20(wlc, val) brcms_c_valid_channel20((wlc)->cmi, val) #define VALID_CHANNEL20(wlc, val) brcms_c_valid_channel20((wlc)->cmi, val)
/* QDB() macro takes a dB value and converts to a quarter dB value */
#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR)
#define LOCALE_CHAN_01_11 (1<<0)
#define LOCALE_CHAN_12_13 (1<<1)
#define LOCALE_CHAN_14 (1<<2)
#define LOCALE_SET_5G_LOW_JP1 (1<<3) /* 34-48, step 2 */
#define LOCALE_SET_5G_LOW_JP2 (1<<4) /* 34-46, step 4 */
#define LOCALE_SET_5G_LOW1 (1<<5) /* 36-48, step 4 */
#define LOCALE_SET_5G_LOW2 (1<<6) /* 52 */
#define LOCALE_SET_5G_LOW3 (1<<7) /* 56-64, step 4 */
#define LOCALE_SET_5G_MID1 (1<<8) /* 100-116, step 4 */
#define LOCALE_SET_5G_MID2 (1<<9) /* 120-124, step 4 */
#define LOCALE_SET_5G_MID3 (1<<10) /* 128 */
#define LOCALE_SET_5G_HIGH1 (1<<11) /* 132-140, step 4 */
#define LOCALE_SET_5G_HIGH2 (1<<12) /* 149-161, step 4 */
#define LOCALE_SET_5G_HIGH3 (1<<13) /* 165 */
#define LOCALE_CHAN_52_140_ALL (1<<14)
#define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */
#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | \
LOCALE_SET_5G_LOW2 | \
LOCALE_SET_5G_LOW3)
#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3)
#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2)
#define LOCALE_CHAN_100_140 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | \
LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1)
#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3)
#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4
#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | \
LOCALE_CHAN_12_13 | \
LOCALE_CHAN_14)
#define LOCALE_RADAR_SET_NONE 0
#define LOCALE_RADAR_SET_1 1
#define LOCALE_RESTRICTED_NONE 0
#define LOCALE_RESTRICTED_SET_2G_SHORT 1
#define LOCALE_RESTRICTED_CHAN_165 2
#define LOCALE_CHAN_ALL_5G 3
#define LOCALE_RESTRICTED_JAPAN_LEGACY 4
#define LOCALE_RESTRICTED_11D_2G 5
#define LOCALE_RESTRICTED_11D_5G 6
#define LOCALE_RESTRICTED_LOW_HI 7
#define LOCALE_RESTRICTED_12_13_14 8
struct brcms_cm_band { struct brcms_cm_band {
/* struct locale_info flags */ /* struct locale_info flags */
u8 locale_flags; u8 locale_flags;
...@@ -57,58 +104,6 @@ struct brcms_cm_info { ...@@ -57,58 +104,6 @@ struct brcms_cm_info {
struct brcms_chanvec quiet_channels; struct brcms_chanvec quiet_channels;
}; };
static int brcms_c_channels_init(struct brcms_cm_info *wlc_cm,
const struct country_info *country);
static void brcms_c_set_country_common(struct brcms_cm_info *wlc_cm,
const char *country_abbrev,
const char *ccode, uint regrev,
const struct country_info *country);
static int brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm,
const char *ccode);
static int brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm,
const char *country_abbrev,
const char *ccode, int regrev);
static int brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm,
const char *ccode,
char *mapped_ccode, uint *mapped_regrev);
static const struct country_info *
brcms_c_country_lookup_direct(const char *ccode, uint regrev);
static const struct country_info *
brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm,
const char *ccode, char *mapped_ccode,
uint *mapped_regrev);
static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm);
static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm);
static bool brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm,
u16 chspec);
static bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val);
static bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm,
uint bandunit, uint val);
static bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val);
static const struct country_info *
brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode);
static void brcms_c_locale_get_channels(const struct locale_info *locale,
struct brcms_chanvec *valid_channels);
static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx);
static const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx);
static bool brcms_c_japan(struct brcms_c_info *wlc);
static bool brcms_c_japan_ccode(const char *ccode);
static void brcms_c_channel_min_txpower_limits_with_local_constraint(
struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr,
u8 local_constraint_qdbm);
static void brcms_c_locale_add_channels(struct brcms_chanvec *target,
const struct brcms_chanvec *channels);
static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx);
static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx);
/* QDB() macro takes a dB value and converts to a quarter dB value */
#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR)
/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */ /* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */
/* /*
...@@ -200,50 +195,6 @@ static const struct brcms_chanvec restricted_set_12_13_14 = { ...@@ -200,50 +195,6 @@ static const struct brcms_chanvec restricted_set_12_13_14 = {
0x00, 0x00, 0x00, 0x00} 0x00, 0x00, 0x00, 0x00}
}; };
#define LOCALE_CHAN_01_11 (1<<0)
#define LOCALE_CHAN_12_13 (1<<1)
#define LOCALE_CHAN_14 (1<<2)
#define LOCALE_SET_5G_LOW_JP1 (1<<3) /* 34-48, step 2 */
#define LOCALE_SET_5G_LOW_JP2 (1<<4) /* 34-46, step 4 */
#define LOCALE_SET_5G_LOW1 (1<<5) /* 36-48, step 4 */
#define LOCALE_SET_5G_LOW2 (1<<6) /* 52 */
#define LOCALE_SET_5G_LOW3 (1<<7) /* 56-64, step 4 */
#define LOCALE_SET_5G_MID1 (1<<8) /* 100-116, step 4 */
#define LOCALE_SET_5G_MID2 (1<<9) /* 120-124, step 4 */
#define LOCALE_SET_5G_MID3 (1<<10) /* 128 */
#define LOCALE_SET_5G_HIGH1 (1<<11) /* 132-140, step 4 */
#define LOCALE_SET_5G_HIGH2 (1<<12) /* 149-161, step 4 */
#define LOCALE_SET_5G_HIGH3 (1<<13) /* 165 */
#define LOCALE_CHAN_52_140_ALL (1<<14)
#define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */
#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | \
LOCALE_SET_5G_LOW2 | \
LOCALE_SET_5G_LOW3)
#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3)
#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2)
#define LOCALE_CHAN_100_140 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | \
LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1)
#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3)
#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4
#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | \
LOCALE_CHAN_12_13 | \
LOCALE_CHAN_14)
#define LOCALE_RADAR_SET_NONE 0
#define LOCALE_RADAR_SET_1 1
#define LOCALE_RESTRICTED_NONE 0
#define LOCALE_RESTRICTED_SET_2G_SHORT 1
#define LOCALE_RESTRICTED_CHAN_165 2
#define LOCALE_CHAN_ALL_5G 3
#define LOCALE_RESTRICTED_JAPAN_LEGACY 4
#define LOCALE_RESTRICTED_11D_2G 5
#define LOCALE_RESTRICTED_11D_5G 6
#define LOCALE_RESTRICTED_LOW_HI 7
#define LOCALE_RESTRICTED_12_13_14 8
/* global memory to provide working buffer for expanded locale */ /* global memory to provide working buffer for expanded locale */
static const struct brcms_chanvec *g_table_radar_set[] = { static const struct brcms_chanvec *g_table_radar_set[] = {
...@@ -612,316 +563,249 @@ static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx) ...@@ -612,316 +563,249 @@ static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx)
return g_mimo_5g_table[locale_idx]; return g_mimo_5g_table[locale_idx];
} }
struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) static int
brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm, const char *ccode,
char *mapped_ccode, uint *mapped_regrev)
{ {
struct brcms_cm_info *wlc_cm; return false;
char country_abbrev[BRCM_CNTRY_BUF_SZ]; }
const struct country_info *country;
struct brcms_pub *pub = wlc->pub;
char *ccode;
BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC); /* Lookup a country info structure from a null terminated country
if (wlc_cm == NULL) { * abbreviation and regrev directly with no translation.
wiphy_err(wlc->wiphy, "wl%d: %s: out of memory", pub->unit, */
__func__); static const struct country_info *
return NULL; brcms_c_country_lookup_direct(const char *ccode, uint regrev)
} {
wlc_cm->pub = pub; uint size, i;
wlc_cm->wlc = wlc;
wlc->cmi = wlc_cm;
/* store the country code for passing up as a regulatory hint */ /* Should just return 0 for single locale driver. */
ccode = getvar(wlc->pub->vars, "ccode"); /* Keep it this way in case we add more locales. (for now anyway) */
if (ccode)
strncpy(wlc->pub->srom_ccode, ccode, BRCM_CNTRY_BUF_SZ - 1);
/* /*
* internal country information which must match * all other country def arrays are for regrev == 0, so if
* regulatory constraints in firmware * regrev is non-zero, fail
*/ */
memset(country_abbrev, 0, BRCM_CNTRY_BUF_SZ); if (regrev > 0)
strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1); return NULL;
country = brcms_c_country_lookup(wlc, country_abbrev);
/* save default country for exiting 11d regulatory mode */ /* find matched table entry from country code */
strncpy(wlc->country_default, country_abbrev, BRCM_CNTRY_BUF_SZ - 1); size = ARRAY_SIZE(cntry_locales);
for (i = 0; i < size; i++) {
if (strcmp(ccode, cntry_locales[i].abbrev) == 0)
return &cntry_locales[i].country;
}
return NULL;
}
/* initialize autocountry_default to driver default */ static const struct country_info *
strncpy(wlc->autocountry_default, "X2", BRCM_CNTRY_BUF_SZ - 1); brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, const char *ccode,
char *mapped_ccode, uint *mapped_regrev)
{
struct brcms_c_info *wlc = wlc_cm->wlc;
const struct country_info *country;
uint srom_regrev = wlc_cm->srom_regrev;
const char *srom_ccode = wlc_cm->srom_ccode;
int mapped;
brcms_c_set_countrycode(wlc_cm, country_abbrev); /* check for currently supported ccode size */
if (strlen(ccode) > (BRCM_CNTRY_BUF_SZ - 1)) {
wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for "
"match\n", wlc->pub->unit, __func__, ccode);
return NULL;
}
return wlc_cm; /* default mapping is the given ccode and regrev 0 */
} strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ);
*mapped_regrev = 0;
void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm) /* If the desired country code matches the srom country code,
{ * then the mapped country is the srom regulatory rev.
kfree(wlc_cm); * Otherwise look for an aggregate mapping.
} */
if (!strcmp(srom_ccode, ccode)) {
*mapped_regrev = srom_regrev;
mapped = 0;
wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__);
} else {
mapped =
brcms_c_country_aggregate_map(wlc_cm, ccode, mapped_ccode,
mapped_regrev);
}
u8 /* find the matching built-in country definition */
brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm, country = brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
uint bandunit)
{
return wlc_cm->bandstate[bandunit].locale_flags;
}
/* /* if there is not an exact rev match, default to rev zero */
* set the driver's current country and regulatory information using if (country == NULL && *mapped_regrev != 0) {
* a country code as the source. Lookup built in country information *mapped_regrev = 0;
* found with the country code. country =
*/ brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
static int }
brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm, const char *ccode)
{ return country;
char country_abbrev[BRCM_CNTRY_BUF_SZ];
strncpy(country_abbrev, ccode, BRCM_CNTRY_BUF_SZ);
return brcms_c_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1);
} }
static int /* Lookup a country info structure from a null terminated country code
brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm, * The lookup is case sensitive.
const char *country_abbrev, */
const char *ccode, int regrev) static const struct country_info *
brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode)
{ {
const struct country_info *country; const struct country_info *country;
char mapped_ccode[BRCM_CNTRY_BUF_SZ]; char mapped_ccode[BRCM_CNTRY_BUF_SZ];
uint mapped_regrev; uint mapped_regrev;
/* if regrev is -1, lookup the mapped country code, /*
* otherwise use the ccode and regrev directly * map the country code to a built-in country code, regrev, and
* country_info struct
*/ */
if (regrev == -1) { country = brcms_c_countrycode_map(wlc->cmi, ccode, mapped_ccode,
/* &mapped_regrev);
* map the country code to a built-in country
* code, regrev, and country_info
*/
country =
brcms_c_countrycode_map(wlc_cm, ccode, mapped_ccode,
&mapped_regrev);
} else {
/* find the matching built-in country definition */
country = brcms_c_country_lookup_direct(ccode, regrev);
strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ);
mapped_regrev = regrev;
}
if (country == NULL) return country;
return -EINVAL;
/* set the driver state for the country */
brcms_c_set_country_common(wlc_cm, country_abbrev, mapped_ccode,
mapped_regrev, country);
return 0;
} }
/* /*
* set the driver's current country and regulatory information * reset the quiet channels vector to the union
* using a country code as the source. Look up built in country * of the restricted and radar channel sets
* information found with the country code.
*/ */
static void static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm)
brcms_c_set_country_common(struct brcms_cm_info *wlc_cm,
const char *country_abbrev,
const char *ccode, uint regrev,
const struct country_info *country)
{ {
const struct locale_mimo_info *li_mimo;
const struct locale_info *locale;
struct brcms_c_info *wlc = wlc_cm->wlc; struct brcms_c_info *wlc = wlc_cm->wlc;
char prev_country_abbrev[BRCM_CNTRY_BUF_SZ]; uint i, j;
struct brcms_band *band;
const struct brcms_chanvec *chanvec;
/* save current country state */ memset(&wlc_cm->quiet_channels, 0, sizeof(struct brcms_chanvec));
wlc_cm->country = country;
memset(&prev_country_abbrev, 0, BRCM_CNTRY_BUF_SZ); band = wlc->band;
strncpy(prev_country_abbrev, wlc_cm->country_abbrev, for (i = 0; i < NBANDS(wlc);
BRCM_CNTRY_BUF_SZ - 1); i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
strncpy(wlc_cm->country_abbrev, country_abbrev, BRCM_CNTRY_BUF_SZ - 1); /* initialize quiet channels for restricted channels */
strncpy(wlc_cm->ccode, ccode, BRCM_CNTRY_BUF_SZ - 1); chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels;
wlc_cm->regrev = regrev; for (j = 0; j < sizeof(struct brcms_chanvec); j++)
wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j];
/* disable/restore nmode based on country regulations */
li_mimo = brcms_c_get_mimo_2g(country->locale_mimo_2G);
if (li_mimo && (li_mimo->flags & BRCMS_NO_MIMO)) {
brcms_c_set_nmode(wlc, OFF);
wlc->stf->no_cddstbc = true;
} else {
wlc->stf->no_cddstbc = false;
if (N_ENAB(wlc->pub) != wlc->protection->nmode_user)
brcms_c_set_nmode(wlc, wlc->protection->nmode_user);
} }
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
/* set or restore gmode as required by regulatory */
locale = brcms_c_get_locale_2g(country->locale_2G);
if (locale && (locale->flags & BRCMS_NO_OFDM))
brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false);
else
brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
brcms_c_channels_init(wlc_cm, country);
return;
} }
/* Lookup a country info structure from a null terminated country code /* Is the channel valid for the current locale and current band? */
* The lookup is case sensitive. static bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val)
*/
static const struct country_info *
brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode)
{ {
const struct country_info *country; struct brcms_c_info *wlc = wlc_cm->wlc;
char mapped_ccode[BRCM_CNTRY_BUF_SZ];
uint mapped_regrev;
/* return ((val < MAXCHANNEL) &&
* map the country code to a built-in country code, regrev, and isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec,
* country_info struct val));
*/ }
country = brcms_c_countrycode_map(wlc->cmi, ccode, mapped_ccode,
&mapped_regrev);
return country; /* Is the channel valid for the current locale and specified band? */
static bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm,
uint bandunit, uint val)
{
return ((val < MAXCHANNEL)
&& isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val));
} }
static const struct country_info * /* Is the channel valid for the current locale? (but don't consider channels not
brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, const char *ccode, * available due to bandlocking)
char *mapped_ccode, uint *mapped_regrev) */
static bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val)
{ {
struct brcms_c_info *wlc = wlc_cm->wlc; struct brcms_c_info *wlc = wlc_cm->wlc;
const struct country_info *country;
uint srom_regrev = wlc_cm->srom_regrev;
const char *srom_ccode = wlc_cm->srom_ccode;
int mapped;
/* check for currently supported ccode size */
if (strlen(ccode) > (BRCM_CNTRY_BUF_SZ - 1)) {
wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for "
"match\n", wlc->pub->unit, __func__, ccode);
return NULL;
}
/* default mapping is the given ccode and regrev 0 */ return VALID_CHANNEL20(wlc, val) ||
strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ); (!wlc->bandlocked
*mapped_regrev = 0; && VALID_CHANNEL20_IN_BAND(wlc, OTHERBANDUNIT(wlc), val));
}
/* If the desired country code matches the srom country code,
* then the mapped country is the srom regulatory rev.
* Otherwise look for an aggregate mapping.
*/
if (!strcmp(srom_ccode, ccode)) {
*mapped_regrev = srom_regrev;
mapped = 0;
wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__);
} else {
mapped =
brcms_c_country_aggregate_map(wlc_cm, ccode, mapped_ccode,
mapped_regrev);
}
/* find the matching built-in country definition */
country = brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
/* if there is not an exact rev match, default to rev zero */
if (country == NULL && *mapped_regrev != 0) {
*mapped_regrev = 0;
country =
brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
}
return country; /* JP, J1 - J10 are Japan ccodes */
static bool brcms_c_japan_ccode(const char *ccode)
{
return (ccode[0] == 'J' &&
(ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9')));
} }
static int /* Returns true if currently set country is Japan or variant */
brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm, const char *ccode, static bool brcms_c_japan(struct brcms_c_info *wlc)
char *mapped_ccode, uint *mapped_regrev)
{ {
return false; return brcms_c_japan_ccode(wlc->cmi->country_abbrev);
} }
/* Lookup a country info structure from a null terminated country static void
* abbreviation and regrev directly with no translation. brcms_c_channel_min_txpower_limits_with_local_constraint(
*/ struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr,
static const struct country_info * u8 local_constraint_qdbm)
brcms_c_country_lookup_direct(const char *ccode, uint regrev)
{ {
uint size, i; int j;
/* Should just return 0 for single locale driver. */ /* CCK Rates */
/* Keep it this way in case we add more locales. (for now anyway) */ for (j = 0; j < WL_TX_POWER_CCK_NUM; j++)
txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm);
/* /* 20 MHz Legacy OFDM SISO */
* all other country def arrays are for regrev == 0, so if for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++)
* regrev is non-zero, fail txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm);
*/
if (regrev > 0)
return NULL;
/* find matched table entry from country code */ /* 20 MHz Legacy OFDM CDD */
size = ARRAY_SIZE(cntry_locales); for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
for (i = 0; i < size; i++) { txpwr->ofdm_cdd[j] =
if (strcmp(ccode, cntry_locales[i].abbrev) == 0) min(txpwr->ofdm_cdd[j], local_constraint_qdbm);
return &cntry_locales[i].country;
}
return NULL;
}
static int /* 40 MHz Legacy OFDM SISO */
brcms_c_channels_init(struct brcms_cm_info *wlc_cm, for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
const struct country_info *country) txpwr->ofdm_40_siso[j] =
{ min(txpwr->ofdm_40_siso[j], local_constraint_qdbm);
struct brcms_c_info *wlc = wlc_cm->wlc;
uint i, j;
struct brcms_band *band;
const struct locale_info *li;
struct brcms_chanvec sup_chan;
const struct locale_mimo_info *li_mimo;
band = wlc->band; /* 40 MHz Legacy OFDM CDD */
for (i = 0; i < NBANDS(wlc); for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { txpwr->ofdm_40_cdd[j] =
min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm);
li = BAND_5G(band->bandtype) ? /* 20MHz MCS 0-7 SISO */
brcms_c_get_locale_5g(country->locale_5G) : for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
brcms_c_get_locale_2g(country->locale_2G); txpwr->mcs_20_siso[j] =
wlc_cm->bandstate[band->bandunit].locale_flags = li->flags; min(txpwr->mcs_20_siso[j], local_constraint_qdbm);
li_mimo = BAND_5G(band->bandtype) ?
brcms_c_get_mimo_5g(country->locale_mimo_5G) :
brcms_c_get_mimo_2g(country->locale_mimo_2G);
/* merge the mimo non-mimo locale flags */ /* 20MHz MCS 0-7 CDD */
wlc_cm->bandstate[band->bandunit].locale_flags |= for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
li_mimo->flags; txpwr->mcs_20_cdd[j] =
min(txpwr->mcs_20_cdd[j], local_constraint_qdbm);
wlc_cm->bandstate[band->bandunit].restricted_channels = /* 20MHz MCS 0-7 STBC */
g_table_restricted_chan[li->restricted_channels]; for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
wlc_cm->bandstate[band->bandunit].radar_channels = txpwr->mcs_20_stbc[j] =
g_table_radar_set[li->radar_channels]; min(txpwr->mcs_20_stbc[j], local_constraint_qdbm);
/* /* 20MHz MCS 8-15 MIMO */
* set the channel availability, masking out the channels for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
* that may not be supported on this phy. txpwr->mcs_20_mimo[j] =
*/ min(txpwr->mcs_20_mimo[j], local_constraint_qdbm);
wlc_phy_chanspec_band_validch(band->pi, band->bandtype,
&sup_chan);
brcms_c_locale_get_channels(li,
&wlc_cm->bandstate[band->bandunit].
valid_channels);
for (j = 0; j < sizeof(struct brcms_chanvec); j++)
wlc_cm->bandstate[band->bandunit].valid_channels.
vec[j] &= sup_chan.vec[j];
}
brcms_c_quiet_channels_reset(wlc_cm); /* 40MHz MCS 0-7 SISO */
brcms_c_channels_commit(wlc_cm); for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
txpwr->mcs_40_siso[j] =
min(txpwr->mcs_40_siso[j], local_constraint_qdbm);
/* 40MHz MCS 0-7 CDD */
for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
txpwr->mcs_40_cdd[j] =
min(txpwr->mcs_40_cdd[j], local_constraint_qdbm);
/* 40MHz MCS 0-7 STBC */
for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
txpwr->mcs_40_stbc[j] =
min(txpwr->mcs_40_stbc[j], local_constraint_qdbm);
/* 40MHz MCS 8-15 MIMO */
for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
txpwr->mcs_40_mimo[j] =
min(txpwr->mcs_40_mimo[j], local_constraint_qdbm);
/* 40MHz MCS 32 */
txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm);
return 0;
} }
/* Update the radio state (enable/disable) and tx power targets /* Update the radio state (enable/disable) and tx power targets
...@@ -981,145 +865,225 @@ static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm) ...@@ -981,145 +865,225 @@ static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm)
} }
} }
static int
brcms_c_channels_init(struct brcms_cm_info *wlc_cm,
const struct country_info *country)
{
struct brcms_c_info *wlc = wlc_cm->wlc;
uint i, j;
struct brcms_band *band;
const struct locale_info *li;
struct brcms_chanvec sup_chan;
const struct locale_mimo_info *li_mimo;
band = wlc->band;
for (i = 0; i < NBANDS(wlc);
i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
li = BAND_5G(band->bandtype) ?
brcms_c_get_locale_5g(country->locale_5G) :
brcms_c_get_locale_2g(country->locale_2G);
wlc_cm->bandstate[band->bandunit].locale_flags = li->flags;
li_mimo = BAND_5G(band->bandtype) ?
brcms_c_get_mimo_5g(country->locale_mimo_5G) :
brcms_c_get_mimo_2g(country->locale_mimo_2G);
/* merge the mimo non-mimo locale flags */
wlc_cm->bandstate[band->bandunit].locale_flags |=
li_mimo->flags;
wlc_cm->bandstate[band->bandunit].restricted_channels =
g_table_restricted_chan[li->restricted_channels];
wlc_cm->bandstate[band->bandunit].radar_channels =
g_table_radar_set[li->radar_channels];
/*
* set the channel availability, masking out the channels
* that may not be supported on this phy.
*/
wlc_phy_chanspec_band_validch(band->pi, band->bandtype,
&sup_chan);
brcms_c_locale_get_channels(li,
&wlc_cm->bandstate[band->bandunit].
valid_channels);
for (j = 0; j < sizeof(struct brcms_chanvec); j++)
wlc_cm->bandstate[band->bandunit].valid_channels.
vec[j] &= sup_chan.vec[j];
}
brcms_c_quiet_channels_reset(wlc_cm);
brcms_c_channels_commit(wlc_cm);
return 0;
}
/* /*
* reset the quiet channels vector to the union * set the driver's current country and regulatory information
* of the restricted and radar channel sets * using a country code as the source. Look up built in country
* information found with the country code.
*/ */
static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm) static void
brcms_c_set_country_common(struct brcms_cm_info *wlc_cm,
const char *country_abbrev,
const char *ccode, uint regrev,
const struct country_info *country)
{ {
const struct locale_mimo_info *li_mimo;
const struct locale_info *locale;
struct brcms_c_info *wlc = wlc_cm->wlc; struct brcms_c_info *wlc = wlc_cm->wlc;
uint i, j; char prev_country_abbrev[BRCM_CNTRY_BUF_SZ];
struct brcms_band *band;
const struct brcms_chanvec *chanvec;
memset(&wlc_cm->quiet_channels, 0, sizeof(struct brcms_chanvec)); /* save current country state */
wlc_cm->country = country;
band = wlc->band; memset(&prev_country_abbrev, 0, BRCM_CNTRY_BUF_SZ);
for (i = 0; i < NBANDS(wlc); strncpy(prev_country_abbrev, wlc_cm->country_abbrev,
i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { BRCM_CNTRY_BUF_SZ - 1);
/* initialize quiet channels for restricted channels */ strncpy(wlc_cm->country_abbrev, country_abbrev, BRCM_CNTRY_BUF_SZ - 1);
chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels; strncpy(wlc_cm->ccode, ccode, BRCM_CNTRY_BUF_SZ - 1);
for (j = 0; j < sizeof(struct brcms_chanvec); j++) wlc_cm->regrev = regrev;
wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j];
/* disable/restore nmode based on country regulations */
li_mimo = brcms_c_get_mimo_2g(country->locale_mimo_2G);
if (li_mimo && (li_mimo->flags & BRCMS_NO_MIMO)) {
brcms_c_set_nmode(wlc, OFF);
wlc->stf->no_cddstbc = true;
} else {
wlc->stf->no_cddstbc = false;
if (N_ENAB(wlc->pub) != wlc->protection->nmode_user)
brcms_c_set_nmode(wlc, wlc->protection->nmode_user);
} }
}
static bool
brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, u16 chspec)
{
return N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec) ?
(isset(wlc_cm->quiet_channels.vec,
LOWER_20_SB(CHSPEC_CHANNEL(chspec))) ||
isset(wlc_cm->quiet_channels.vec,
UPPER_20_SB(CHSPEC_CHANNEL(chspec)))) :
isset(wlc_cm->quiet_channels.vec, CHSPEC_CHANNEL(chspec));
}
/* Is the channel valid for the current locale? (but don't consider channels not brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
* available due to bandlocking) brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
*/ /* set or restore gmode as required by regulatory */
static bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val) locale = brcms_c_get_locale_2g(country->locale_2G);
{ if (locale && (locale->flags & BRCMS_NO_OFDM))
struct brcms_c_info *wlc = wlc_cm->wlc; brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false);
else
brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
return VALID_CHANNEL20(wlc, val) || brcms_c_channels_init(wlc_cm, country);
(!wlc->bandlocked
&& VALID_CHANNEL20_IN_BAND(wlc, OTHERBANDUNIT(wlc), val));
}
/* Is the channel valid for the current locale and specified band? */ return;
static bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm,
uint bandunit, uint val)
{
return ((val < MAXCHANNEL)
&& isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val));
} }
/* Is the channel valid for the current locale and current band? */ static int
static bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val) brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm,
const char *country_abbrev,
const char *ccode, int regrev)
{ {
struct brcms_c_info *wlc = wlc_cm->wlc; const struct country_info *country;
char mapped_ccode[BRCM_CNTRY_BUF_SZ];
uint mapped_regrev;
return ((val < MAXCHANNEL) && /* if regrev is -1, lookup the mapped country code,
isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec, * otherwise use the ccode and regrev directly
val)); */
} if (regrev == -1) {
/*
* map the country code to a built-in country
* code, regrev, and country_info
*/
country =
brcms_c_countrycode_map(wlc_cm, ccode, mapped_ccode,
&mapped_regrev);
} else {
/* find the matching built-in country definition */
country = brcms_c_country_lookup_direct(ccode, regrev);
strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ);
mapped_regrev = regrev;
}
static void if (country == NULL)
brcms_c_channel_min_txpower_limits_with_local_constraint( return -EINVAL;
struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr,
u8 local_constraint_qdbm)
{
int j;
/* CCK Rates */ /* set the driver state for the country */
for (j = 0; j < WL_TX_POWER_CCK_NUM; j++) brcms_c_set_country_common(wlc_cm, country_abbrev, mapped_ccode,
txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm); mapped_regrev, country);
/* 20 MHz Legacy OFDM SISO */ return 0;
for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++) }
txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm);
/* 20 MHz Legacy OFDM CDD */ /*
for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) * set the driver's current country and regulatory information using
txpwr->ofdm_cdd[j] = * a country code as the source. Lookup built in country information
min(txpwr->ofdm_cdd[j], local_constraint_qdbm); * found with the country code.
*/
static int
brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm, const char *ccode)
{
char country_abbrev[BRCM_CNTRY_BUF_SZ];
strncpy(country_abbrev, ccode, BRCM_CNTRY_BUF_SZ);
return brcms_c_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1);
}
/* 40 MHz Legacy OFDM SISO */ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) {
txpwr->ofdm_40_siso[j] = struct brcms_cm_info *wlc_cm;
min(txpwr->ofdm_40_siso[j], local_constraint_qdbm); char country_abbrev[BRCM_CNTRY_BUF_SZ];
const struct country_info *country;
struct brcms_pub *pub = wlc->pub;
char *ccode;
/* 40 MHz Legacy OFDM CDD */ BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
txpwr->ofdm_40_cdd[j] =
min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm);
/* 20MHz MCS 0-7 SISO */ wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC);
for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) if (wlc_cm == NULL) {
txpwr->mcs_20_siso[j] = wiphy_err(wlc->wiphy, "wl%d: %s: out of memory", pub->unit,
min(txpwr->mcs_20_siso[j], local_constraint_qdbm); __func__);
return NULL;
}
wlc_cm->pub = pub;
wlc_cm->wlc = wlc;
wlc->cmi = wlc_cm;
/* 20MHz MCS 0-7 CDD */ /* store the country code for passing up as a regulatory hint */
for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) ccode = getvar(wlc->pub->vars, "ccode");
txpwr->mcs_20_cdd[j] = if (ccode)
min(txpwr->mcs_20_cdd[j], local_constraint_qdbm); strncpy(wlc->pub->srom_ccode, ccode, BRCM_CNTRY_BUF_SZ - 1);
/* 20MHz MCS 0-7 STBC */ /*
for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) * internal country information which must match
txpwr->mcs_20_stbc[j] = * regulatory constraints in firmware
min(txpwr->mcs_20_stbc[j], local_constraint_qdbm); */
memset(country_abbrev, 0, BRCM_CNTRY_BUF_SZ);
strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1);
country = brcms_c_country_lookup(wlc, country_abbrev);
/* 20MHz MCS 8-15 MIMO */ /* save default country for exiting 11d regulatory mode */
for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++) strncpy(wlc->country_default, country_abbrev, BRCM_CNTRY_BUF_SZ - 1);
txpwr->mcs_20_mimo[j] =
min(txpwr->mcs_20_mimo[j], local_constraint_qdbm);
/* 40MHz MCS 0-7 SISO */ /* initialize autocountry_default to driver default */
for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) strncpy(wlc->autocountry_default, "X2", BRCM_CNTRY_BUF_SZ - 1);
txpwr->mcs_40_siso[j] =
min(txpwr->mcs_40_siso[j], local_constraint_qdbm);
/* 40MHz MCS 0-7 CDD */ brcms_c_set_countrycode(wlc_cm, country_abbrev);
for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
txpwr->mcs_40_cdd[j] =
min(txpwr->mcs_40_cdd[j], local_constraint_qdbm);
/* 40MHz MCS 0-7 STBC */ return wlc_cm;
for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) }
txpwr->mcs_40_stbc[j] =
min(txpwr->mcs_40_stbc[j], local_constraint_qdbm);
/* 40MHz MCS 8-15 MIMO */ void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm)
for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++) {
txpwr->mcs_40_mimo[j] = kfree(wlc_cm);
min(txpwr->mcs_40_mimo[j], local_constraint_qdbm); }
/* 40MHz MCS 32 */ u8
txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm); brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
uint bandunit)
{
return wlc_cm->bandstate[bandunit].locale_flags;
}
static bool
brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, u16 chspec)
{
return N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec) ?
(isset(wlc_cm->quiet_channels.vec,
LOWER_20_SB(CHSPEC_CHANNEL(chspec))) ||
isset(wlc_cm->quiet_channels.vec,
UPPER_20_SB(CHSPEC_CHANNEL(chspec)))) :
isset(wlc_cm->quiet_channels.vec, CHSPEC_CHANNEL(chspec));
} }
void void
...@@ -1471,19 +1435,6 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, ...@@ -1471,19 +1435,6 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec,
return; return;
} }
/* Returns true if currently set country is Japan or variant */
static bool brcms_c_japan(struct brcms_c_info *wlc)
{
return brcms_c_japan_ccode(wlc->cmi->country_abbrev);
}
/* JP, J1 - J10 are Japan ccodes */
static bool brcms_c_japan_ccode(const char *ccode)
{
return (ccode[0] == 'J' &&
(ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9')));
}
/* /*
* Validate the chanspec for this locale, for 40MHZ we need to also * Validate the chanspec for this locale, for 40MHZ we need to also
* check that the sidebands are valid 20MZH channels in this locale * check that the sidebands are valid 20MZH channels in this locale
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment