diff options
author | Raja Mani <rmani@qca.qualcomm.com> | 2012-01-30 06:43:11 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2012-01-30 14:22:55 -0500 |
commit | 081c7a84e969453716e2a7bd315417067c3643ad (patch) | |
tree | 69121a0003fbc1d8395e8ab95b3ff82d62bacaaa | |
parent | d91e8eee046e0d4ae7a8a585616b5ce800f54568 (diff) |
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>
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/cfg80211.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/core.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/wmi.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/wmi.h | 2 |
4 files changed, 35 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index e676cfccedfe..1902e2fa1a68 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -1975,11 +1975,26 @@ skip_arp: | |||
1975 | if (ret) | 1975 | if (ret) |
1976 | return ret; | 1976 | return ret; |
1977 | 1977 | ||
1978 | clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags); | ||
1979 | |||
1978 | ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, | 1980 | ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, |
1979 | ATH6KL_HOST_MODE_ASLEEP); | 1981 | ATH6KL_HOST_MODE_ASLEEP); |
1980 | if (ret) | 1982 | if (ret) |
1981 | return ret; | 1983 | return ret; |
1982 | 1984 | ||
1985 | left = wait_event_interruptible_timeout(ar->event_wq, | ||
1986 | test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags), | ||
1987 | WMI_TIMEOUT); | ||
1988 | if (left == 0) { | ||
1989 | ath6kl_warn("timeout, didn't get host sleep cmd " | ||
1990 | "processed event\n"); | ||
1991 | ret = -ETIMEDOUT; | ||
1992 | } else if (left < 0) { | ||
1993 | ath6kl_warn("error while waiting for host sleep cmd " | ||
1994 | "processed event %d\n", left); | ||
1995 | ret = left; | ||
1996 | } | ||
1997 | |||
1983 | if (ar->tx_pending[ar->ctrl_ep]) { | 1998 | if (ar->tx_pending[ar->ctrl_ep]) { |
1984 | left = wait_event_interruptible_timeout(ar->event_wq, | 1999 | left = wait_event_interruptible_timeout(ar->event_wq, |
1985 | ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT); | 2000 | ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT); |
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index ce572c04b924..c4d66e066dc9 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h | |||
@@ -451,6 +451,7 @@ enum ath6kl_vif_state { | |||
451 | DTIM_PERIOD_AVAIL, | 451 | DTIM_PERIOD_AVAIL, |
452 | WLAN_ENABLED, | 452 | WLAN_ENABLED, |
453 | STATS_UPDATE_PEND, | 453 | STATS_UPDATE_PEND, |
454 | HOST_SLEEP_MODE_CMD_PROCESSED, | ||
454 | }; | 455 | }; |
455 | 456 | ||
456 | struct ath6kl_vif { | 457 | struct ath6kl_vif { |
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 9c8e4dfbfa0c..18fa9aa8af92 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
@@ -2590,6 +2590,18 @@ int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, | |||
2590 | return ret; | 2590 | return ret; |
2591 | } | 2591 | } |
2592 | 2592 | ||
2593 | /* This command has zero length payload */ | ||
2594 | static int ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(struct wmi *wmi, | ||
2595 | struct ath6kl_vif *vif) | ||
2596 | { | ||
2597 | struct ath6kl *ar = wmi->parent_dev; | ||
2598 | |||
2599 | set_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags); | ||
2600 | wake_up(&ar->event_wq); | ||
2601 | |||
2602 | return 0; | ||
2603 | } | ||
2604 | |||
2593 | int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, | 2605 | int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, |
2594 | enum ath6kl_wow_mode wow_mode, | 2606 | enum ath6kl_wow_mode wow_mode, |
2595 | u32 filter, u16 host_req_delay) | 2607 | u32 filter, u16 host_req_delay) |
@@ -3556,6 +3568,11 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) | |||
3556 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n"); | 3568 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n"); |
3557 | ret = ath6kl_wmi_tx_complete_event_rx(datap, len); | 3569 | ret = ath6kl_wmi_tx_complete_event_rx(datap, len); |
3558 | break; | 3570 | break; |
3571 | case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID: | ||
3572 | ath6kl_dbg(ATH6KL_DBG_WMI, | ||
3573 | "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID"); | ||
3574 | ret = ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif); | ||
3575 | break; | ||
3559 | case WMI_REMAIN_ON_CHNL_EVENTID: | 3576 | case WMI_REMAIN_ON_CHNL_EVENTID: |
3560 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n"); | 3577 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n"); |
3561 | ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif); | 3578 | ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif); |
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 85698ef2dd88..e7919869725e 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h | |||
@@ -1357,6 +1357,8 @@ enum wmi_event_id { | |||
1357 | WMI_P2P_START_SDPD_EVENTID, | 1357 | WMI_P2P_START_SDPD_EVENTID, |
1358 | WMI_P2P_SDPD_RX_EVENTID, | 1358 | WMI_P2P_SDPD_RX_EVENTID, |
1359 | 1359 | ||
1360 | WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID = 0x1047, | ||
1361 | |||
1360 | WMI_THIN_RESERVED_START_EVENTID = 0x8000, | 1362 | WMI_THIN_RESERVED_START_EVENTID = 0x8000, |
1361 | /* Events in this range are reserved for thinmode */ | 1363 | /* Events in this range are reserved for thinmode */ |
1362 | WMI_THIN_RESERVED_END_EVENTID = 0x8fff, | 1364 | WMI_THIN_RESERVED_END_EVENTID = 0x8fff, |