mirror of https://gitee.com/openkylin/linux.git
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: Raja Mani <rmani@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
d91e8eee04
commit
081c7a84e9
|
@ -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);
|
||||
|
|
|
@ -451,6 +451,7 @@ enum ath6kl_vif_state {
|
|||
DTIM_PERIOD_AVAIL,
|
||||
WLAN_ENABLED,
|
||||
STATS_UPDATE_PEND,
|
||||
HOST_SLEEP_MODE_CMD_PROCESSED,
|
||||
};
|
||||
|
||||
struct ath6kl_vif {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue