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

Commit 02ead738 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "wil6210: use country specific board file upon reg domain change"

parents 388b1977 5c3afc51
Loading
Loading
Loading
Loading
+65 −0
Original line number Original line Diff line number Diff line
@@ -21,11 +21,16 @@
#include "ftm.h"
#include "ftm.h"


#define WIL_MAX_ROC_DURATION_MS 5000
#define WIL_MAX_ROC_DURATION_MS 5000
#define CTRY_CHINA "CN"


bool disable_ap_sme;
bool disable_ap_sme;
module_param(disable_ap_sme, bool, 0444);
module_param(disable_ap_sme, bool, 0444);
MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME");
MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME");


static bool country_specific_board_file;
module_param(country_specific_board_file, bool, 0444);
MODULE_PARM_DESC(country_specific_board_file, " switch board file upon regulatory domain change (Default: false)");

static bool ignore_reg_hints = true;
static bool ignore_reg_hints = true;
module_param(ignore_reg_hints, bool, 0444);
module_param(ignore_reg_hints, bool, 0444);
MODULE_PARM_DESC(ignore_reg_hints, " Ignore OTA regulatory hints (Default: true)");
MODULE_PARM_DESC(ignore_reg_hints, " Ignore OTA regulatory hints (Default: true)");
@@ -1984,6 +1989,64 @@ wil_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev)
	return 0;
	return 0;
}
}


static int wil_switch_board_file(struct wil6210_priv *wil,
				 const u8 *new_regdomain)
{
	int rc = 0;

	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 {
		return 0;
	}

	/* need to switch board file - reset the device */

	mutex_lock(&wil->mutex);

	if (!netif_running(wil_to_ndev(wil)) || wil_is_recovery_blocked(wil))
		/* new board file will be used in next FW load */
		goto out;

	__wil_down(wil);
	rc = __wil_up(wil);

out:
	mutex_unlock(&wil->mutex);
	return rc;
}

static void wil_cfg80211_reg_notify(struct wiphy *wiphy,
				    struct regulatory_request *request)
{
	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
	int rc;

	wil_info(wil, "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n",
		 request->alpha2[0], request->alpha2[1],
		 request->intersect ? " intersect" : "",
		 request->processed ? " processed" : "",
		 request->initiator, request->user_reg_hint_type);

	if (memcmp(wil->regdomain, request->alpha2, 2) == 0)
		/* reg domain did not change */
		return;

	rc = wil_switch_board_file(wil, request->alpha2);
	if (rc)
		wil_err(wil, "switch board file failed %d\n", rc);

	memcpy(wil->regdomain, request->alpha2, 2);
}

static struct cfg80211_ops wil_cfg80211_ops = {
static struct cfg80211_ops wil_cfg80211_ops = {
	.add_virtual_intf = wil_cfg80211_add_iface,
	.add_virtual_intf = wil_cfg80211_add_iface,
	.del_virtual_intf = wil_cfg80211_del_iface,
	.del_virtual_intf = wil_cfg80211_del_iface,
@@ -2055,6 +2118,8 @@ static void wil_wiphy_init(struct wiphy *wiphy)
	wiphy->mgmt_stypes = wil_mgmt_stypes;
	wiphy->mgmt_stypes = wil_mgmt_stypes;
	wiphy->features |= NL80211_FEATURE_SK_TX_STATUS;
	wiphy->features |= NL80211_FEATURE_SK_TX_STATUS;


	wiphy->reg_notifier = wil_cfg80211_reg_notify;

	wiphy->n_vendor_commands = ARRAY_SIZE(wil_nl80211_vendor_commands);
	wiphy->n_vendor_commands = ARRAY_SIZE(wil_nl80211_vendor_commands);
	wiphy->vendor_commands = wil_nl80211_vendor_commands;
	wiphy->vendor_commands = wil_nl80211_vendor_commands;
	wiphy->vendor_events = wil_nl80211_vendor_events;
	wiphy->vendor_events = wil_nl80211_vendor_events;
+32 −5
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@


#define WAIT_FOR_HALP_VOTE_MS 100
#define WAIT_FOR_HALP_VOTE_MS 100
#define WAIT_FOR_SCAN_ABORT_MS 1000
#define WAIT_FOR_SCAN_ABORT_MS 1000
#define WIL_BOARD_FILE_MAX_NAMELEN 128


bool debug_fw; /* = false; */
bool debug_fw; /* = false; */
module_param(debug_fw, bool, 0444);
module_param(debug_fw, bool, 0444);
@@ -946,6 +947,30 @@ void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
	le32_to_cpus(&r->head);
	le32_to_cpus(&r->head);
}
}


/* construct actual board file name to use */
void wil_get_board_file(struct wil6210_priv *wil, char *buf, size_t len)
{
	const char *board_file = WIL_BOARD_FILE_NAME;
	const char *ext;
	int prefix_len;

	if (wil->board_file_country[0] == '\0') {
		strlcpy(buf, board_file, len);
		return;
	}

	/* use country specific board file */
	if (len < strlen(board_file) + 4 /* for _XX and terminating null */)
		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);
	if (ext)
		strlcat(buf, ext, len);
}

static int wil_get_bl_info(struct wil6210_priv *wil)
static int wil_get_bl_info(struct wil6210_priv *wil)
{
{
	struct net_device *ndev = wil_to_ndev(wil);
	struct net_device *ndev = wil_to_ndev(wil);
@@ -1260,8 +1285,12 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)


	wil_set_oob_mode(wil, oob_mode);
	wil_set_oob_mode(wil, oob_mode);
	if (load_fw) {
	if (load_fw) {
		char board_file[WIL_BOARD_FILE_MAX_NAMELEN];

		board_file[0] = '\0';
		wil_get_board_file(wil, board_file, sizeof(board_file));
		wil_info(wil, "Use firmware <%s> + board <%s>\n",
		wil_info(wil, "Use firmware <%s> + board <%s>\n",
			 wil->wil_fw_name, WIL_BOARD_FILE_NAME);
			 wil->wil_fw_name, board_file);


		if (!no_flash)
		if (!no_flash)
			wil_bl_prepare_halt(wil);
			wil_bl_prepare_halt(wil);
@@ -1273,11 +1302,9 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
		if (rc)
		if (rc)
			goto out;
			goto out;
		if (wil->brd_file_addr)
		if (wil->brd_file_addr)
			rc = wil_request_board(wil, WIL_BOARD_FILE_NAME);
			rc = wil_request_board(wil, board_file);
		else
		else
			rc = wil_request_firmware(wil,
			rc = wil_request_firmware(wil, board_file, true);
						  WIL_BOARD_FILE_NAME,
						  true);
		if (rc)
		if (rc)
			goto out;
			goto out;


+5 −0
Original line number Original line Diff line number Diff line
@@ -683,6 +683,7 @@ struct wil6210_priv {
	const char *hw_name;
	const char *hw_name;
	const char *wil_fw_name;
	const char *wil_fw_name;
	char *board_file;
	char *board_file;
	char board_file_country[3]; /* alpha2 */
	u32 brd_file_addr;
	u32 brd_file_addr;
	u32 brd_file_max_size;
	u32 brd_file_max_size;
	DECLARE_BITMAP(hw_capa, hw_capa_last);
	DECLARE_BITMAP(hw_capa, hw_capa_last);
@@ -796,6 +797,8 @@ struct wil6210_priv {
	} snr_thresh;
	} snr_thresh;


	int fw_calib_result;
	int fw_calib_result;
	/* current reg domain configured in kernel */
	char regdomain[3]; /* alpha2 */


#ifdef CONFIG_PM
#ifdef CONFIG_PM
	struct notifier_block pm_notify;
	struct notifier_block pm_notify;
@@ -873,6 +876,8 @@ static inline void wil_c(struct wil6210_priv *wil, u32 reg, u32 val)
	wil_w(wil, reg, wil_r(wil, reg) & ~val);
	wil_w(wil, reg, wil_r(wil, reg) & ~val);
}
}


void wil_get_board_file(struct wil6210_priv *wil, char *buf, size_t len);

#if defined(CONFIG_DYNAMIC_DEBUG)
#if defined(CONFIG_DYNAMIC_DEBUG)
#define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize,	\
#define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize,	\
			  groupsize, buf, len, ascii)		\
			  groupsize, buf, len, ascii)		\