From 38f7cf174310d9ecd994a192ce8ff38e163af451 Mon Sep 17 00:00:00 2001 From: Dedy Lansky Date: Wed, 4 Dec 2019 10:07:46 +0200 Subject: [PATCH] wil6210: support FCC board file Driver already supports China specific board file. Extend this to support list of countries that follow FCC rules. Upon reg domain change, use appropriate (default, CN or FCC) board file. Change-Id: Ia62977fdb1b1da6b985909d7e8dfa239c124e9a0 Signed-off-by: Dedy Lansky Signed-off-by: Lior David Signed-off-by: Alexei Avshalom Lazar --- drivers/net/wireless/ath/wil6210/cfg80211.c | 59 +++++++++++++++++---- drivers/net/wireless/ath/wil6210/main.c | 8 +-- drivers/net/wireless/ath/wil6210/wil6210.h | 4 +- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 40a331735f9e..4d8ac6ee0f7b 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -14,7 +14,8 @@ #include "fw.h" #define WIL_MAX_ROC_DURATION_MS 5000 -#define CTRY_CHINA "CN" +#define WIL_BRD_SUFFIX_CN "CN" +#define WIL_BRD_SUFFIX_FCC "FCC" #define WIL_EDMG_CHANNEL_9_SUBCHANNELS (BIT(0) | BIT(1)) #define WIL_EDMG_CHANNEL_10_SUBCHANNELS (BIT(1) | BIT(2)) @@ -102,6 +103,25 @@ static int wil_tx_cb_mode_to_n_bonded(u8 cb_mode) } } +struct wil_regd_2_brd_suffix { + const char regdomain[3]; /* alpha2 */ + const char *brd_suffix; +}; + +static struct wil_regd_2_brd_suffix wil_regd_2_brd_suffix_map[] = { + {"BO", WIL_BRD_SUFFIX_FCC}, + {"CN", WIL_BRD_SUFFIX_CN}, + {"EC", WIL_BRD_SUFFIX_FCC}, + {"GU", WIL_BRD_SUFFIX_FCC}, + {"HN", WIL_BRD_SUFFIX_FCC}, + {"JM", WIL_BRD_SUFFIX_FCC}, + {"MX", WIL_BRD_SUFFIX_FCC}, + {"NI", WIL_BRD_SUFFIX_FCC}, + {"PY", WIL_BRD_SUFFIX_FCC}, + {"TT", WIL_BRD_SUFFIX_FCC}, + {"US", WIL_BRD_SUFFIX_FCC}, +}; + enum wil_nl_60g_cmd_type { NL_60G_CMD_FW_WMI, NL_60G_CMD_DEBUG, @@ -2716,24 +2736,43 @@ wil_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev, return 0; } +static void wil_get_brd_reg_suffix(struct wil6210_priv *wil, + const u8 *new_regdomain, + char *brd_reg_suffix, size_t len) +{ + int i; + struct wil_regd_2_brd_suffix *entry; + + for (i = 0; i < ARRAY_SIZE(wil_regd_2_brd_suffix_map); i++) { + entry = &wil_regd_2_brd_suffix_map[i]; + if (!memcmp(entry->regdomain, new_regdomain, 2)) { + strlcpy(brd_reg_suffix, entry->brd_suffix, len); + return; + } + } + + /* regdomain not found in our map, set suffix to none */ + brd_reg_suffix[0] = '\0'; +} + static int wil_switch_board_file(struct wil6210_priv *wil, const u8 *new_regdomain) { int rc = 0; + char brd_reg_suffix[WIL_BRD_SUFFIX_LEN]; if (!country_specific_board_file) return 0; - if (memcmp(wil->regdomain, CTRY_CHINA, 2) == 0) { - wil_info(wil, "moving out of China reg domain, use default board file\n"); - wil->board_file_country[0] = '\0'; - } else if (memcmp(new_regdomain, CTRY_CHINA, 2) == 0) { - wil_info(wil, "moving into China reg domain, use country specific board file\n"); - strlcpy(wil->board_file_country, CTRY_CHINA, - sizeof(wil->board_file_country)); - } else { + wil_get_brd_reg_suffix(wil, new_regdomain, brd_reg_suffix, + sizeof(brd_reg_suffix)); + if (!strcmp(wil->board_file_reg_suffix, brd_reg_suffix)) return 0; - } + + wil_info(wil, "switch board file suffix '%s' => '%s'\n", + wil->board_file_reg_suffix, brd_reg_suffix); + strlcpy(wil->board_file_reg_suffix, brd_reg_suffix, + sizeof(wil->board_file_reg_suffix)); /* need to switch board file - reset the device */ diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 8b1baa7b35db..d4fb0ecf5bd7 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -1309,19 +1309,19 @@ void wil_get_board_file(struct wil6210_priv *wil, char *buf, size_t len) board_file = WIL_BOARD_FILE_NAME; } - if (wil->board_file_country[0] == '\0') { + if (wil->board_file_reg_suffix[0] == '\0') { strlcpy(buf, board_file, len); return; } /* use country specific board file */ - if (len < strlen(board_file) + 4 /* for _XX and terminating null */) + if (len < strlen(board_file) + 1 + WIL_BRD_SUFFIX_LEN) /* 1 for '_' */ return; ext = strrchr(board_file, '.'); prefix_len = (ext ? ext - board_file : strlen(board_file)); - snprintf(buf, len, "%.*s_%.2s", - prefix_len, board_file, wil->board_file_country); + snprintf(buf, len, "%.*s_%.3s", + prefix_len, board_file, wil->board_file_reg_suffix); if (ext) strlcat(buf, ext, len); } diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 34e994f43a52..1b7230d68235 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -59,6 +59,8 @@ union wil_tx_desc; */ #define WIL_MAX_VIFS 4 +#define WIL_BRD_SUFFIX_LEN 4 /* max 3 letters + terminating null */ + /** * extract bits [@b0:@b1] (inclusive) from the value @x * it should be @b0 <= @b1, or result is incorrect @@ -934,7 +936,7 @@ struct wil6210_priv { const char *hw_name; const char *wil_fw_name; char *board_file; - char board_file_country[3]; /* alpha2 */ + char board_file_reg_suffix[WIL_BRD_SUFFIX_LEN]; /* empty or CN or FCC */ u32 num_of_brd_entries; struct wil_brd_info *brd_info; DECLARE_BITMAP(hw_capa, hw_capa_last);