From f51c69ff1b5b21489ef00d23a293328009facc1e Mon Sep 17 00:00:00 2001 From: Alexei Avshalom Lazar Date: Wed, 4 Dec 2019 09:58:16 +0200 Subject: [PATCH 1/2] wil6210: force EDMG channel through debugfs Force EDMG (Enhanced Directional Multi-Gigabit) channel through debugfs for debugging channel bonding feature. Usage: echo > force_edmg_channel When force_edmg_channel is set, it will be used in connect and PCP start commands. Change-Id: Ia1e12cb8cf730dbb448fae47b40dfa11053567d0 Signed-off-by: Alexei Avshalom Lazar Signed-off-by: Maya Erez [liord@codeaurora.org: fix merge conflicts, SPDX license] Signed-off-by: Lior David --- drivers/net/wireless/ath/wil6210/cfg80211.c | 10 +++++++++ drivers/net/wireless/ath/wil6210/debugfs.c | 14 ++----------- drivers/net/wireless/ath/wil6210/wil6210.h | 4 ++++ drivers/net/wireless/ath/wil6210/wmi.c | 23 +++++++++++++++++++-- 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 05b25f43f2b5..40a331735f9e 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -1510,6 +1510,16 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, if (rc < 0) return rc; + if (test_bit(WMI_FW_CAPABILITY_CHANNEL_BONDING, wil->fw_capabilities)) + if (wil->force_edmg_channel) { + rc = wil_spec2wmi_ch(wil->force_edmg_channel, + &conn.edmg_channel); + if (rc) + wil_err(wil, + "wmi channel for channel %d not found", + wil->force_edmg_channel); + } + ether_addr_copy(conn.bssid, bss->bssid); ether_addr_copy(conn.dst_mac, bss->bssid); diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index 304b4d4e506a..243714136d30 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: ISC /* * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include @@ -2454,6 +2443,7 @@ static const struct dbg_off dbg_wil_off[] = { WIL_FIELD(tx_status_ring_order, 0644, doff_u32), WIL_FIELD(rx_buff_id_count, 0644, doff_u32), WIL_FIELD(amsdu_en, 0644, doff_u8), + WIL_FIELD(force_edmg_channel, 0644, doff_u8), {}, }; diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 74ec64e4bf53..34e994f43a52 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -1017,6 +1017,7 @@ struct wil6210_priv { u8 wakeup_trigger; struct wil_suspend_stats suspend_stats; struct wil_debugfs_data dbg_data; + u8 force_edmg_channel; bool tx_latency; /* collect TX latency measurements */ size_t tx_latency_res; /* bin resolution in usec */ @@ -1469,6 +1470,9 @@ int wil_wmi2spec_ch(u8 wmi_ch, u8 *spec_ch); int wil_spec2wmi_ch(u8 spec_ch, u8 *wmi_ch); void wil_update_supported_bands(struct wil6210_priv *wil); +int wil_wmi2spec_ch(u8 wmi_ch, u8 *spec_ch); +int wil_spec2wmi_ch(u8 spec_ch, u8 *wmi_ch); + int reverse_memcmp(const void *cs, const void *ct, size_t count); /* WMI for enhanced DMA */ diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 4898c4503059..4a5e5fb3e8f6 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -974,6 +974,7 @@ static void wmi_evt_connect(struct wil6210_vif *vif, int id, void *d, int len) struct wireless_dev *wdev = vif_to_wdev(vif); struct wmi_connect_event *evt = d; int ch; /* channel number */ + u8 spec_ch = 0; /* spec channel number */ struct station_info *sinfo; u8 *assoc_req_ie, *assoc_resp_ie; size_t assoc_req_ielen, assoc_resp_ielen; @@ -1001,8 +1002,16 @@ static void wmi_evt_connect(struct wil6210_vif *vif, int id, void *d, int len) } ch = evt->channel + 1; - wil_info(wil, "Connect %pM channel [%d] cid %d aid %d\n", - evt->bssid, ch, evt->cid, evt->aid); + if (evt->edmg_channel && + test_bit(WMI_FW_CAPABILITY_CHANNEL_BONDING, wil->fw_capabilities)) + wil_wmi2spec_ch(evt->edmg_channel, &spec_ch); + if (spec_ch) + wil_info(wil, "Connect %pM EDMG channel [%d] primary channel [%d] cid %d aid %d\n", + evt->bssid, spec_ch, ch, evt->cid, evt->aid); + else + wil_info(wil, "Connect %pM channel [%d] cid %d aid %d\n", + evt->bssid, ch, evt->cid, evt->aid); + wil_hex_dump_wmi("connect AI : ", DUMP_PREFIX_OFFSET, 16, 1, evt->assoc_info, len - sizeof(*evt), true); @@ -2247,6 +2256,16 @@ int wmi_pcp_start(struct wil6210_vif *vif, int bi, u8 wmi_nettype, .evt = {.status = WMI_FW_STATUS_FAILURE}, }; + if (test_bit(WMI_FW_CAPABILITY_CHANNEL_BONDING, wil->fw_capabilities)) + if (wil->force_edmg_channel) { + rc = wil_spec2wmi_ch(wil->force_edmg_channel, + &cmd.edmg_channel); + if (rc) + wil_err(wil, + "wmi channel for channel %d not found", + wil->force_edmg_channel); + } + if (!vif->privacy) cmd.disable_sec = 1; From 38f7cf174310d9ecd994a192ce8ff38e163af451 Mon Sep 17 00:00:00 2001 From: Dedy Lansky Date: Wed, 4 Dec 2019 10:07:46 +0200 Subject: [PATCH 2/2] 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);