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

Commit 45cf110b authored by Raja Mani's avatar Raja Mani Committed by Kalle Valo
Browse files

ath6kl: Add wmi functions to configure WOW mode and host sleep mode



It will be used in WOW suspend/resume functions to
active/deactivate WOW suspend mode.

Signed-off-by: default avatarRaja Mani <rmani@qca.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent 5c9b4fa1
Loading
Loading
Loading
Loading
+108 −0
Original line number Diff line number Diff line
@@ -2412,6 +2412,114 @@ int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd)
	return ret;
}

static void ath6kl_wmi_relinquish_implicit_pstream_credits(struct wmi *wmi)
{
	u16 active_tsids;
	u8 stream_exist;
	int i;

	/*
	 * Relinquish credits from all implicitly created pstreams
	 * since when we go to sleep. If user created explicit
	 * thinstreams exists with in a fatpipe leave them intact
	 * for the user to delete.
	 */
	spin_lock_bh(&wmi->lock);
	stream_exist = wmi->fat_pipe_exist;
	spin_unlock_bh(&wmi->lock);

	for (i = 0; i < WMM_NUM_AC; i++) {
		if (stream_exist & (1 << i)) {

			/*
			 * FIXME: Is this lock & unlock inside
			 * for loop correct? may need rework.
			 */
			spin_lock_bh(&wmi->lock);
			active_tsids = wmi->stream_exist_for_ac[i];
			spin_unlock_bh(&wmi->lock);

			/*
			 * If there are no user created thin streams
			 * delete the fatpipe
			 */
			if (!active_tsids) {
				stream_exist &= ~(1 << i);
				/*
				 * Indicate inactivity to driver layer for
				 * this fatpipe (pstream)
				 */
				ath6kl_indicate_tx_activity(wmi->parent_dev,
							    i, false);
			}
		}
	}

	/* FIXME: Can we do this assignment without locking ? */
	spin_lock_bh(&wmi->lock);
	wmi->fat_pipe_exist = stream_exist;
	spin_unlock_bh(&wmi->lock);
}

int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
				       enum ath6kl_host_mode host_mode)
{
	struct sk_buff *skb;
	struct wmi_set_host_sleep_mode_cmd *cmd;
	int ret;

	if ((host_mode != ATH6KL_HOST_MODE_ASLEEP) &&
	    (host_mode != ATH6KL_HOST_MODE_AWAKE)) {
		ath6kl_err("invalid host sleep mode: %d\n", host_mode);
		return -EINVAL;
	}

	skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
	if (!skb)
		return -ENOMEM;

	cmd = (struct wmi_set_host_sleep_mode_cmd *) skb->data;

	if (host_mode == ATH6KL_HOST_MODE_ASLEEP) {
		ath6kl_wmi_relinquish_implicit_pstream_credits(wmi);
		cmd->asleep = cpu_to_le32(1);
	} else
		cmd->awake = cpu_to_le32(1);

	ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
				  WMI_SET_HOST_SLEEP_MODE_CMDID,
				  NO_SYNC_WMIFLAG);
	return ret;
}

int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
				enum ath6kl_wow_mode wow_mode,
				u32 filter, u16 host_req_delay)
{
	struct sk_buff *skb;
	struct wmi_set_wow_mode_cmd *cmd;
	int ret;

	if ((wow_mode != ATH6KL_WOW_MODE_ENABLE) &&
	     wow_mode != ATH6KL_WOW_MODE_DISABLE) {
		ath6kl_err("invalid wow mode: %d\n", wow_mode);
		return -EINVAL;
	}

	skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
	if (!skb)
		return -ENOMEM;

	cmd = (struct wmi_set_wow_mode_cmd *) skb->data;
	cmd->enable_wow = cpu_to_le32(wow_mode);
	cmd->filter = cpu_to_le32(filter);
	cmd->host_req_delay = cpu_to_le16(host_req_delay);

	ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_WOW_MODE_CMDID,
				  NO_SYNC_WMIFLAG);
	return ret;
}

int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
				   u8 list_id, u8 filter_size,
				   u8 filter_offset, u8 *filter, u8 *mask)
+41 −0
Original line number Diff line number Diff line
@@ -1818,6 +1818,42 @@ struct wmi_set_ip_cmd {
	__le32 ips[MAX_IP_ADDRS];
} __packed;

enum ath6kl_wow_filters {
	WOW_FILTER_SSID			= BIT(0),
	WOW_FILTER_OPTION_MAGIC_PACKET  = BIT(2),
	WOW_FILTER_OPTION_EAP_REQ	= BIT(3),
	WOW_FILTER_OPTION_PATTERNS	= BIT(4),
	WOW_FILTER_OPTION_OFFLOAD_ARP	= BIT(5),
	WOW_FILTER_OPTION_OFFLOAD_NS	= BIT(6),
	WOW_FILTER_OPTION_OFFLOAD_GTK	= BIT(7),
	WOW_FILTER_OPTION_8021X_4WAYHS	= BIT(8),
	WOW_FILTER_OPTION_NLO_DISCVRY	= BIT(9),
	WOW_FILTER_OPTION_NWK_DISASSOC	= BIT(10),
	WOW_FILTER_OPTION_GTK_ERROR	= BIT(11),
	WOW_FILTER_OPTION_TEST_MODE	= BIT(15),
};

enum ath6kl_host_mode {
	ATH6KL_HOST_MODE_AWAKE,
	ATH6KL_HOST_MODE_ASLEEP,
};

struct wmi_set_host_sleep_mode_cmd {
	__le32 awake;
	__le32 asleep;
} __packed;

enum ath6kl_wow_mode {
	ATH6KL_WOW_MODE_DISABLE,
	ATH6KL_WOW_MODE_ENABLE,
};

struct wmi_set_wow_mode_cmd {
	__le32 enable_wow;
	__le32 filter;
	__le16 host_req_delay;
} __packed;

struct wmi_add_wow_pattern_cmd {
	u8 filter_list_id;
	u8 filter_size;
@@ -2285,6 +2321,11 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);
s32 ath6kl_wmi_get_rate(s8 rate_index);

int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd);
int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
				       enum ath6kl_host_mode host_mode);
int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
				enum ath6kl_wow_mode wow_mode,
				u32 filter, u16 host_req_delay);
int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
				   u8 list_id, u8 filter_size,
				   u8 filter_offset, u8 *filter, u8 *mask);