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

Commit 6c616f70 authored by Ahmad Masri's avatar Ahmad Masri
Browse files

wil6210: support VR mode



Allow wil6210 to configure the system in Virtual Reality (VR) mode.
When system 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 it will drop packets when the
transmit queue is full.

New sysfs "vr_enable" can be used by user space to enable VR mode.
WMI_VR_CFG_CMDID is used to configure the FW into VR mode.

Change-Id: If9e0a5eb3323f1479d76b259c848310508e7009c
Signed-off-by: default avatarAhmad Masri <amasri@codeaurora.org>
parent 923d9dbf
Loading
Loading
Loading
Loading
+44 −1
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@
#define WAIT_FOR_HALP_VOTE_MS 100
#define WAIT_FOR_SCAN_ABORT_MS 1000
#define WIL_BOARD_FILE_MAX_NAMELEN 128
#define WIL6210_ITR_VR_RX_MAX_BURST_DURATION (5) /* usec */
#define WIL6210_VR_TX_RING_ORDER 7

bool debug_fw; /* = false; */
module_param(debug_fw, bool, 0444);
@@ -1146,6 +1148,43 @@ 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;
		mtu_max = TXRX_BUF_LEN_DEFAULT - WIL_MAX_MPDU_OVERHEAD;
		rx_large_buf = 0;
		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;
	mtu_max = WIL_MAX_ETH_MTU;
	rx_large_buf = 1;
	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 */
@@ -1322,7 +1361,6 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
	clear_bit(wil_status_resetting, wil->status);

	if (load_fw) {
		wil_configure_interrupt_moderation(wil);
		wil_unmask_irq(wil);

		/* we just started MAC, wait for FW ready */
@@ -1337,6 +1375,11 @@ 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_configure_interrupt_moderation(wil);
		wil_collect_fw_info(wil);

		if (wil->ps_profile != WMI_PS_PROFILE_TYPE_DEFAULT)
+8 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014,2017 Qualcomm Atheros, Inc.
 * Copyright (c) 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
@@ -64,6 +65,13 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime)
		goto out;
	/* for STA-like interface, don't runtime suspend */
	case NL80211_IFTYPE_STATION:
		if (test_bit(wil_status_fwconnected, wil->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_status_fwconnecting, wil->status)) {
			wil_dbg_pm(wil, "Delay suspend when connecting\n");
+57 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 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
@@ -268,6 +269,61 @@ static DEVICE_ATTR(fst_link_loss, 0644,
		   wil_fst_link_loss_sysfs_show,
		   wil_fst_link_loss_sysfs_store);

static ssize_t
wil_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
wil_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(vr_profile, 0644,
		   wil_vr_profile_show,
		   wil_vr_profile_store);

static ssize_t
wil_snr_thresh_sysfs_show(struct device *dev, struct device_attribute *attr,
			  char *buf)
@@ -311,6 +367,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
};

+1 −1
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ bool rx_large_buf;
module_param(rx_large_buf, bool, 0444);
MODULE_PARM_DESC(rx_large_buf, " allocate 8KB RX buffers, default - no");

static bool drop_if_ring_full;
bool drop_if_ring_full;
module_param(drop_if_ring_full, bool, 0444);
MODULE_PARM_DESC(drop_if_ring_full,
		 " drop Tx packets in case tx ring is full");
+9 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ extern bool rx_align_2;
extern bool rx_large_buf;
extern bool debug_fw;
extern bool disable_ap_sme;
extern bool drop_if_ring_full;

#define WIL_NAME "wil6210"

@@ -813,6 +814,9 @@ struct wil6210_priv {
		short direct;
	} snr_thresh;

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

	int fw_calib_result;
	/* current reg domain configured in kernel */
	char regdomain[3]; /* alpha2 */
@@ -958,6 +962,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, 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);
@@ -1125,6 +1130,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_priv *wil);
void wil_ftm_deinit(struct wil6210_priv *wil);
void wil_ftm_stop_operations(struct wil6210_priv *wil);
Loading