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

Commit afc1a655 authored by Ahmad Masri's avatar Ahmad Masri
Browse files

wil6210: support VR profiles



Allow wil6210 to configure the system in Virtual Reality (VR) mode.
When system is in VR mode it should have a low latency, and a high
responsive to events in the system. Wil6210 will set the rx interrupt
moderation to lower threshold and will drop packets when the transmit
queue is full.

Disallow changing power save profile while in VR mode.

New sysfs "vr_profile" can be used by userspace to enable and set
VR profile.

WMI_SET_VR_PROFILE_CMDID is used to configure the FW into different
VR profile configurations.

Change-Id: If9e0a5eb3323f1479d76b259c848310508e7009c
Signed-off-by: default avatarAhmad Masri <amasri@codeaurora.org>
Signed-off-by: default avatarDedy Lansky <dlansky@codeaurora.org>
parent 71ba584c
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -2527,6 +2527,10 @@ static int wil_cfg80211_set_power_mgmt(struct wiphy *wiphy,
	struct wil6210_priv *wil = wiphy_to_wil(wiphy);
	enum wmi_ps_profile_type ps_profile;

	if (wil->vr_profile != WMI_VR_PROFILE_DISABLED)
		/* disallow in VR mode */
		return -EINVAL;

	wil_dbg_misc(wil, "enabled=%d, timeout=%d\n",
		     enabled, timeout);

+38 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@
#define WAIT_FOR_SCAN_ABORT_MS 1000
#define WIL_DEFAULT_NUM_RX_STATUS_RINGS 1
#define WIL_BOARD_FILE_MAX_NAMELEN 128
#define WIL6210_ITR_VR_RX_MAX_BURST_DURATION (5) /* usec */
#define WIL6210_VR_TX_RING_ORDER 10

bool debug_fw; /* = false; */
module_param(debug_fw, bool, 0444);
@@ -1562,6 +1564,38 @@ int wil_ps_update(struct wil6210_priv *wil, enum wmi_ps_profile_type ps_profile)
	return rc;
}

int wil_vr_update_profile(struct wil6210_priv *wil, u8 profile)
{
	int rc;

	if (profile == WMI_VR_PROFILE_DISABLED) {
		/* Switch from VR mode to normal (non-VR) mode is not
		 * supported at runtime - it requires FW re-loading.
		 * It is assumed here that FW is not running when VR disable
		 * is requested
		 */
		wil->ps_profile = WMI_PS_PROFILE_TYPE_DEFAULT;
		tx_ring_order = WIL_TX_RING_SIZE_ORDER_DEFAULT;
		drop_if_ring_full = false;
		wil->rx_max_burst_duration =
			WIL6210_ITR_RX_MAX_BURST_DURATION_DEFAULT;

		return 0;
	}

	rc = wmi_set_vr_profile(wil, profile);
	if (rc)
		return rc;

	/* VR default configuration */
	wil->ps_profile = WMI_PS_PROFILE_TYPE_PS_DISABLED;
	tx_ring_order = WIL6210_VR_TX_RING_ORDER;
	drop_if_ring_full = true;
	wil->rx_max_burst_duration = WIL6210_ITR_VR_RX_MAX_BURST_DURATION;

	return 0;
}

static void wil_pre_fw_config(struct wil6210_priv *wil)
{
	/* Mark FW as loaded from host */
@@ -1793,6 +1827,10 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
			return rc;
		}

		/* Update VR mode before configuring interrupt moderation */
		if (wil->vr_profile != WMI_VR_PROFILE_DISABLED)
			wil_vr_update_profile(wil, wil->vr_profile);

		wil->txrx_ops.configure_interrupt_moderation(wil);

		/* Enable OFU rdy valid bug fix, to prevent hang in oful34_rx
+7 −0
Original line number Diff line number Diff line
@@ -51,6 +51,13 @@ wil_can_suspend_vif(struct wil6210_priv *wil, struct wil6210_vif *vif,

	/* for STA-like interface, don't runtime suspend */
	case NL80211_IFTYPE_STATION:
		if (test_bit(wil_vif_fwconnected, vif->status) &&
		    wil->vr_profile != WMI_VR_PROFILE_DISABLED) {
			wil_dbg_pm(wil,
				   "Reject suspend in VR mode when connected\n");
			return false;
		}
		/* fallthrough */
	case NL80211_IFTYPE_P2P_CLIENT:
		if (test_bit(wil_vif_fwconnecting, vif->status)) {
			wil_dbg_pm(wil, "Delay suspend when connecting\n");
+54 −0
Original line number Diff line number Diff line
@@ -297,6 +297,59 @@ fst_link_loss_store(struct device *dev, struct device_attribute *attr,

static DEVICE_ATTR_RW(fst_link_loss);

static ssize_t
vr_profile_show(struct device *dev, struct device_attribute *attr,
		char *buf)
{
	struct wil6210_priv *wil = dev_get_drvdata(dev);
	ssize_t len;

	len = snprintf(buf, PAGE_SIZE, "%s\n",
		       wil_get_vr_profile_name(wil->vr_profile));

	return len;
}

static ssize_t
vr_profile_store(struct device *dev, struct device_attribute *attr,
		 const char *buf, size_t count)
{
	struct wil6210_priv *wil = dev_get_drvdata(dev);
	u8 profile;
	int rc = 0;

	if (kstrtou8(buf, 0, &profile))
		return -EINVAL;

	if (test_bit(wil_status_fwready, wil->status)) {
		wil_err(wil, "Cannot set VR while interface is up\n");
		return -EIO;
	}

	if (profile == wil->vr_profile) {
		wil_info(wil, "Ignore same VR profile %s\n",
			 wil_get_vr_profile_name(wil->vr_profile));
		return count;
	}

	wil_info(wil, "Sysfs: set VR profile to %s\n",
		 wil_get_vr_profile_name(profile));

	/* Enabling of VR mode is done from wil_reset after FW is ready.
	 * Disabling is done from here.
	 */
	if (profile == WMI_VR_PROFILE_DISABLED) {
		rc = wil_vr_update_profile(wil, profile);
		if (rc)
			return rc;
	}
	wil->vr_profile = profile;

	return count;
}

static DEVICE_ATTR_RW(vr_profile);

static ssize_t
snr_thresh_show(struct device *dev, struct device_attribute *attr,
		char *buf)
@@ -339,6 +392,7 @@ static struct attribute *wil6210_sysfs_entries[] = {
	&dev_attr_thermal_throttling.attr,
	&dev_attr_fst_link_loss.attr,
	&dev_attr_snr_thresh.attr,
	&dev_attr_vr_profile.attr,
	NULL
};

+8 −0
Original line number Diff line number Diff line
@@ -1040,6 +1040,9 @@ struct wil6210_priv {
		short direct;
	} snr_thresh;

	/* VR profile, VR is disabled on profile 0 */
	u8 vr_profile;

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

@@ -1234,6 +1237,7 @@ 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, u8 mid, const u8 *mac);
void wil_set_ethtoolops(struct net_device *ndev);
int wil_vr_update_profile(struct wil6210_priv *wil, u8 profile);

struct fw_map *wil_find_fw_mapping(const char *section);
void __iomem *wmi_buffer_block(struct wil6210_priv *wil, __le32 ptr, u32 size);
@@ -1424,6 +1428,10 @@ void wil_halp_unvote(struct wil6210_priv *wil);
void wil6210_set_halp(struct wil6210_priv *wil);
void wil6210_clear_halp(struct wil6210_priv *wil);

int wmi_set_vr_profile(struct wil6210_priv *wil, u8 profile);
const char *
wil_get_vr_profile_name(enum wmi_vr_profile profile);

void wil_ftm_init(struct wil6210_vif *vif);
void wil_ftm_deinit(struct wil6210_vif *vif);
void wil_ftm_stop_operations(struct wil6210_priv *wil);
Loading