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

Commit 081c7a84 authored by Raja Mani's avatar Raja Mani Committed by Kalle Valo
Browse files

ath6kl: Wait for host sleep mode cmd processed event during WOW suspend



For every WMI_SET_HOST_SLEEP_MODE_CMDID command (send from the host),
the firmware sends WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID as
an acknowledgement to the host.

In order to being sync with the firmware, the host has to wait for
WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENT event before going to
the suspend state. This patch ensures ath6kl_wow_suspend() waits
until it gets this event after sending set host sleep mode command.

This patch adds,
 * New command WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID in
   WMI event table.
 * New WMI function ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx()
   to process the event.
 * New flag HOST_SLEEP_MODE_CMD_PROCESSED in VIF flags to record
   the arrival of the event.

Signed-off-by: default avatarRaja Mani <rmani@qca.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent d91e8eee
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -1975,11 +1975,26 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
	if (ret)
		return ret;

	clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);

	ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
						 ATH6KL_HOST_MODE_ASLEEP);
	if (ret)
		return ret;

	left = wait_event_interruptible_timeout(ar->event_wq,
			test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags),
			WMI_TIMEOUT);
	if (left == 0) {
		ath6kl_warn("timeout, didn't get host sleep cmd "
			    "processed event\n");
		ret = -ETIMEDOUT;
	} else if (left < 0) {
		ath6kl_warn("error while waiting for host sleep cmd "
			    "processed event %d\n", left);
		ret = left;
	}

	if (ar->tx_pending[ar->ctrl_ep]) {
		left = wait_event_interruptible_timeout(ar->event_wq,
				ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT);
+1 −0
Original line number Diff line number Diff line
@@ -451,6 +451,7 @@ enum ath6kl_vif_state {
	DTIM_PERIOD_AVAIL,
	WLAN_ENABLED,
	STATS_UPDATE_PEND,
	HOST_SLEEP_MODE_CMD_PROCESSED,
};

struct ath6kl_vif {
+17 −0
Original line number Diff line number Diff line
@@ -2590,6 +2590,18 @@ int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
	return ret;
}

/* This command has zero length payload */
static int ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(struct wmi *wmi,
						      struct ath6kl_vif *vif)
{
	struct ath6kl *ar = wmi->parent_dev;

	set_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
	wake_up(&ar->event_wq);

	return 0;
}

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)
@@ -3556,6 +3568,11 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
		ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n");
		ret = ath6kl_wmi_tx_complete_event_rx(datap, len);
		break;
	case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID:
		ath6kl_dbg(ATH6KL_DBG_WMI,
			   "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID");
		ret = ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif);
		break;
	case WMI_REMAIN_ON_CHNL_EVENTID:
		ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n");
		ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif);
+2 −0
Original line number Diff line number Diff line
@@ -1357,6 +1357,8 @@ enum wmi_event_id {
	WMI_P2P_START_SDPD_EVENTID,
	WMI_P2P_SDPD_RX_EVENTID,

	WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID = 0x1047,

	WMI_THIN_RESERVED_START_EVENTID = 0x8000,
	/* Events in this range are reserved for thinmode */
	WMI_THIN_RESERVED_END_EVENTID = 0x8fff,