aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaja Mani <rmani@qca.qualcomm.com>2012-01-30 06:43:11 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2012-01-30 14:22:55 -0500
commit081c7a84e969453716e2a7bd315417067c3643ad (patch)
tree69121a0003fbc1d8395e8ab95b3ff82d62bacaaa
parentd91e8eee046e0d4ae7a8a585616b5ce800f54568 (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.c15
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h1
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c17
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h2
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
456struct ath6kl_vif { 457struct 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 */
2594static 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
2593int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, 2605int 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,