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

Commit 56a778e1 authored by Lior David's avatar Lior David Committed by Gerrit - the friendly Code Review server
Browse files

wil6210: refresh FW capabilities during interface up



FW capabilities are currently retrieved only during module
initialization, but userspace can replace the firmware while
interface is down, so refresh the FW capabilities when
interface is up (after FW is loaded) to ensure driver
functionality matches the loaded FW.

Change-Id: I880706bee0700b88e6637efd42de2eef4ea0d8b6
Signed-off-by: default avatarLior David <liord@codeaurora.org>
parent 9db9725e
Loading
Loading
Loading
Loading
+8 −13
Original line number Diff line number Diff line
@@ -124,24 +124,19 @@ static int fw_ignore_section(struct wil6210_priv *wil, const void *data,
	return 0;
}

static int fw_handle_comment(struct wil6210_priv *wil, const void *data,
			     size_t size)
{
	wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, data, size, true);

	return 0;
}

static int
fw_handle_capabilities(struct wil6210_priv *wil, const void *data,
fw_handle_comment(struct wil6210_priv *wil, const void *data,
		  size_t size)
{
	const struct wil_fw_record_capabilities *rec = data;
	size_t capa_size;

	if (size < sizeof(*rec) ||
	    le32_to_cpu(rec->magic) != WIL_FW_CAPABILITIES_MAGIC)
	    le32_to_cpu(rec->magic) != WIL_FW_CAPABILITIES_MAGIC) {
		wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1,
				data, size, true);
		return 0;
	}

	capa_size = size - offsetof(struct wil_fw_record_capabilities,
				    capabilities);
@@ -422,7 +417,7 @@ static const struct {
	int (*parse_handler)(struct wil6210_priv *wil, const void *data,
			     size_t size);
} wil_fw_handlers[] = {
	{wil_fw_type_comment, fw_handle_comment, fw_handle_capabilities},
	{wil_fw_type_comment, fw_handle_comment, fw_handle_comment},
	{wil_fw_type_data, fw_handle_data, fw_ignore_section},
	{wil_fw_type_fill, fw_handle_fill, fw_ignore_section},
	/* wil_fw_type_action */
@@ -517,7 +512,7 @@ int wil_request_firmware(struct wil6210_priv *wil, const char *name,

	rc = request_firmware(&fw, name, wil_to_dev(wil));
	if (rc) {
		wil_err_fw(wil, "Failed to load firmware %s\n", name);
		wil_err_fw(wil, "Failed to load firmware %s rc %d\n", name, rc);
		return rc;
	}
	wil_dbg_fw(wil, "Loading <%s>, %zu bytes\n", name, fw->size);
+23 −2
Original line number Diff line number Diff line
@@ -765,6 +765,8 @@ static void wil_collect_fw_info(struct wil6210_priv *wil)
	u8 retry_short;
	int rc;

	wil_refresh_fw_capabilities(wil);

	rc = wmi_get_mgmt_retry(wil, &retry_short);
	if (!rc) {
		wiphy->retry_short = retry_short;
@@ -772,6 +774,25 @@ static void wil_collect_fw_info(struct wil6210_priv *wil)
	}
}

void wil_refresh_fw_capabilities(struct wil6210_priv *wil)
{
	struct wiphy *wiphy = wil_to_wiphy(wil);

	wil->keep_radio_on_during_sleep =
		wil->platform_ops.keep_radio_on_during_sleep &&
		wil->platform_ops.keep_radio_on_during_sleep(
			wil->platform_handle) &&
		test_bit(WMI_FW_CAPABILITY_D3_SUSPEND, wil->fw_capabilities);

	wil_info(wil, "keep_radio_on_during_sleep (%d)\n",
		 wil->keep_radio_on_during_sleep);

	if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING, wil->fw_capabilities))
		wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
	else
		wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
}

void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
{
	le32_to_cpus(&r->base);
@@ -1077,14 +1098,14 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
			return rc;
		}

		wil_collect_fw_info(wil);

		if (wil->ps_profile != WMI_PS_PROFILE_TYPE_DEFAULT)
			wil_ps_update(wil, wil->ps_profile);

		if (wil->tt_data_set)
			wmi_set_tt_cfg(wil, &wil->tt_data);

		wil_collect_fw_info(wil);

		if (wil->platform_ops.notify) {
			rc = wil->platform_ops.notify(wil->platform_handle,
						      WIL_PLATFORM_EVT_FW_RDY);
+2 −13
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
@@ -84,9 +84,7 @@ void wil_set_capabilities(struct wil6210_priv *wil)

	/* extract FW capabilities from file without loading the FW */
	wil_request_firmware(wil, wil->wil_fw_name, false);

	if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING, wil->fw_capabilities))
		wil_to_wiphy(wil)->signal_type = CFG80211_SIGNAL_TYPE_MBM;
	wil_refresh_fw_capabilities(wil);
}

void wil_disable_irq(struct wil6210_priv *wil)
@@ -289,15 +287,6 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
	wil_set_capabilities(wil);
	wil6210_clear_irq(wil);

	wil->keep_radio_on_during_sleep =
		wil->platform_ops.keep_radio_on_during_sleep &&
		wil->platform_ops.keep_radio_on_during_sleep(
			wil->platform_handle) &&
		test_bit(WMI_FW_CAPABILITY_D3_SUSPEND, wil->fw_capabilities);

	wil_info(wil, "keep_radio_on_during_sleep (%d)\n",
		 wil->keep_radio_on_during_sleep);

	/* FW should raise IRQ when ready */
	rc = wil_if_pcie_enable(wil);
	if (rc) {
+1 −0
Original line number Diff line number Diff line
@@ -873,6 +873,7 @@ int wil_up(struct wil6210_priv *wil);
int __wil_up(struct wil6210_priv *wil);
int wil_down(struct wil6210_priv *wil);
int __wil_down(struct wil6210_priv *wil);
void wil_refresh_fw_capabilities(struct wil6210_priv *wil);
void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r);
int wil_find_cid(struct wil6210_priv *wil, const u8 *mac);
void wil_set_ethtoolops(struct net_device *ndev);