Skip to content

Commit 73345fd

Browse files
Hante MeulemanKalle Valo
Hante Meuleman
authored and
Kalle Valo
committed
brcmfmac: Configure country code using device specific settings
Country code configuration in a device is a device specific operation. For this the country code as specified by reg notifier (iso3166 alpha2) needs to be translated to a device specific country locale and revision number. This patch adds this translation and puts a placeholder in the device specific settings where the translation table can be stored. Additional patches will be needed to read these tables from for example device platform data. Reviewed-by: Arend Van Spriel <[email protected]> Reviewed-by: Franky (Zhenhui) Lin <[email protected]> Reviewed-by: Pieter-Paul Giesberts <[email protected]> Signed-off-by: Hante Meuleman <[email protected]> Signed-off-by: Arend van Spriel <[email protected]> Signed-off-by: Kalle Valo <[email protected]>
1 parent 6ea0915 commit 73345fd

File tree

4 files changed

+101
-13
lines changed

4 files changed

+101
-13
lines changed

drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6405,28 +6405,85 @@ int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg,
64056405
vif_event_equals(event, action), timeout);
64066406
}
64076407

6408+
static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
6409+
struct brcmf_fil_country_le *ccreq)
6410+
{
6411+
struct cc_translate *country_codes;
6412+
struct cc_entry *cc;
6413+
s32 found_index;
6414+
int i;
6415+
6416+
country_codes = drvr->settings->country_codes;
6417+
if (!country_codes) {
6418+
brcmf_dbg(TRACE, "No country codes configured for device\n");
6419+
return -EINVAL;
6420+
}
6421+
6422+
if ((alpha2[0] == ccreq->country_abbrev[0]) &&
6423+
(alpha2[1] == ccreq->country_abbrev[1])) {
6424+
brcmf_dbg(TRACE, "Country code already set\n");
6425+
return -EAGAIN;
6426+
}
6427+
6428+
found_index = -1;
6429+
for (i = 0; i < country_codes->table_size; i++) {
6430+
cc = &country_codes->table[i];
6431+
if ((cc->iso3166[0] == '\0') && (found_index == -1))
6432+
found_index = i;
6433+
if ((cc->iso3166[0] == alpha2[0]) &&
6434+
(cc->iso3166[1] == alpha2[1])) {
6435+
found_index = i;
6436+
break;
6437+
}
6438+
}
6439+
if (found_index == -1) {
6440+
brcmf_dbg(TRACE, "No country code match found\n");
6441+
return -EINVAL;
6442+
}
6443+
memset(ccreq, 0, sizeof(*ccreq));
6444+
ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev);
6445+
memcpy(ccreq->ccode, country_codes->table[found_index].cc,
6446+
BRCMF_COUNTRY_BUF_SZ);
6447+
ccreq->country_abbrev[0] = alpha2[0];
6448+
ccreq->country_abbrev[1] = alpha2[1];
6449+
ccreq->country_abbrev[2] = 0;
6450+
6451+
return 0;
6452+
}
6453+
64086454
static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
64096455
struct regulatory_request *req)
64106456
{
64116457
struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
64126458
struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
64136459
struct brcmf_fil_country_le ccreq;
6460+
s32 err;
64146461
int i;
64156462

6416-
brcmf_dbg(TRACE, "enter: initiator=%d, alpha=%c%c\n", req->initiator,
6417-
req->alpha2[0], req->alpha2[1]);
6418-
64196463
/* ignore non-ISO3166 country codes */
64206464
for (i = 0; i < sizeof(req->alpha2); i++)
64216465
if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
6422-
brcmf_err("not a ISO3166 code\n");
6466+
brcmf_err("not a ISO3166 code (0x%02x 0x%02x)\n",
6467+
req->alpha2[0], req->alpha2[1]);
64236468
return;
64246469
}
6425-
memset(&ccreq, 0, sizeof(ccreq));
6426-
ccreq.rev = cpu_to_le32(-1);
6427-
memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2));
6428-
if (brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq))) {
6429-
brcmf_err("firmware rejected country setting\n");
6470+
6471+
brcmf_dbg(TRACE, "Enter: initiator=%d, alpha=%c%c\n", req->initiator,
6472+
req->alpha2[0], req->alpha2[1]);
6473+
6474+
err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
6475+
if (err) {
6476+
brcmf_err("Country code iovar returned err = %d\n", err);
6477+
return;
6478+
}
6479+
6480+
err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq);
6481+
if (err)
6482+
return;
6483+
6484+
err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
6485+
if (err) {
6486+
brcmf_err("Firmware rejected country setting\n");
64306487
return;
64316488
}
64326489
brcmf_setup_wiphybands(wiphy);

drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,8 @@ void brcmf_mp_attach(void)
230230
int brcmf_mp_device_attach(struct brcmf_pub *drvr)
231231
{
232232
drvr->settings = kzalloc(sizeof(*drvr->settings), GFP_ATOMIC);
233-
if (!drvr->settings) {
234-
brcmf_err("Failed to alloca storage space for settings\n");
233+
if (!drvr->settings)
235234
return -ENOMEM;
236-
}
237235

238236
drvr->settings->sdiod_txglomsz = brcmf_sdiod_txglomsz;
239237
drvr->settings->p2p_enable = !!brcmf_p2p_enable;

drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#ifndef BRCMFMAC_COMMON_H
1616
#define BRCMFMAC_COMMON_H
1717

18+
#include "fwil_types.h"
19+
1820
extern const u8 ALLFFMAC[ETH_ALEN];
1921

2022
#define BRCMF_FW_ALTPATH_LEN 256
@@ -38,6 +40,33 @@ struct brcmf_mp_global_t {
3840

3941
extern struct brcmf_mp_global_t brcmf_mp_global;
4042

43+
/**
44+
* struct cc_entry - Struct for translating user space country code (iso3166) to
45+
* firmware country code and revision.
46+
*
47+
* @iso3166: iso3166 alpha 2 country code string.
48+
* @cc: firmware country code string.
49+
* @rev: firmware country code revision.
50+
*/
51+
struct cc_entry {
52+
char iso3166[BRCMF_COUNTRY_BUF_SZ];
53+
char cc[BRCMF_COUNTRY_BUF_SZ];
54+
s32 rev;
55+
};
56+
57+
/**
58+
* struct cc_translate - Struct for translating country codes as set by user
59+
* space to a country code and rev which can be used by
60+
* firmware.
61+
*
62+
* @table_size: number of entries in table (> 0)
63+
* @table: dynamic array of 1 or more elements with translation information.
64+
*/
65+
struct cc_translate {
66+
int table_size;
67+
struct cc_entry table[0];
68+
};
69+
4170
/**
4271
* struct brcmf_mp_device - Device module paramaters.
4372
*
@@ -47,6 +76,7 @@ extern struct brcmf_mp_global_t brcmf_mp_global;
4776
* @feature_disable: Feature_disable bitmask.
4877
* @fcmode: FWS flow control.
4978
* @roamoff: Firmware roaming off?
79+
* @country_codes: If available, pointer to struct for translating country codes
5080
*/
5181
struct brcmf_mp_device {
5282
int sdiod_txglomsz;
@@ -56,6 +86,7 @@ struct brcmf_mp_device {
5686
int fcmode;
5787
bool roamoff;
5888
bool ignore_probe_fail;
89+
struct cc_translate *country_codes;
5990
};
6091

6192
void brcmf_mp_attach(void);

drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@
134134
#define BRCMF_PFN_MAC_OUI_ONLY BIT(0)
135135
#define BRCMF_PFN_SET_MAC_UNASSOC BIT(1)
136136

137+
#define BRCMF_MCSSET_LEN 16
138+
137139
/* join preference types for join_pref iovar */
138140
enum brcmf_join_pref_types {
139141
BRCMF_JOIN_PREF_RSSI = 1,
@@ -279,7 +281,7 @@ struct brcmf_bss_info_le {
279281
__le32 reserved32[1]; /* Reserved for expansion of BSS properties */
280282
u8 flags; /* flags */
281283
u8 reserved[3]; /* Reserved for expansion of BSS properties */
282-
u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
284+
u8 basic_mcs[BRCMF_MCSSET_LEN]; /* 802.11N BSS required MCS set */
283285

284286
__le16 ie_offset; /* offset at which IEs start, from beginning */
285287
__le32 ie_length; /* byte length of Information Elements */

0 commit comments

Comments
 (0)