All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ath6kl: Check wow state before sending control and data pkt
@ 2012-02-06 13:56 rmani
  2012-02-06 14:14 ` Kalle Valo
  2012-02-06 14:30 ` Kalle Valo
  0 siblings, 2 replies; 6+ messages in thread
From: rmani @ 2012-02-06 13:56 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, ath6kl-devel, Raja Mani

From: Raja Mani <rmani@qca.qualcomm.com>

* TX operation (ctrl tx and data tx) has to be controlled based on
  WOW suspend state. i.e, control packets are allowed to send from
  the host until the suspend state goes ATH6KL_STATE_WOW and
  the data packets are allowed until WOW suspend operation starts.

* Similary, wow resume is NOT allowed if WOW suspend is in progress.

Both of the above scenarios are taken care in this patch.

Signed-off-by: Raja Mani <rmani@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c |   14 ++++++++++++++
 drivers/net/wireless/ath/ath6kl/core.c     |    2 ++
 drivers/net/wireless/ath/ath6kl/core.h     |    7 +++++++
 drivers/net/wireless/ath/ath6kl/txrx.c     |   11 ++++++++++-
 4 files changed, 33 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index d1922d8..11d9670 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1941,6 +1941,8 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 	if (ret)
 		return ret;
 
+	ar->wow_state = ATH6KL_WOW_STATE_SUSPENDING;
+
 	/* Setup own IP addr for ARP agent. */
 	in_dev = __in_dev_get_rtnl(vif->ndev);
 	if (!in_dev)
@@ -2015,10 +2017,15 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
 	struct ath6kl_vif *vif;
 	int ret;
 
+	if (ar->wow_state == ATH6KL_WOW_STATE_NONE)
+		return 0;
+
 	vif = ath6kl_vif_first(ar);
 	if (!vif)
 		return -EIO;
 
+	ar->wow_state = ATH6KL_WOW_STATE_NONE;
+
 	ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
 						 ATH6KL_HOST_MODE_AWAKE);
 	return ret;
@@ -2041,9 +2048,13 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
 		ret = ath6kl_wow_suspend(ar, wow);
 		if (ret) {
 			ath6kl_err("wow suspend failed: %d\n", ret);
+			ar->wow_state = ATH6KL_WOW_STATE_NONE;
 			return ret;
 		}
+
+		ar->wow_state = ATH6KL_WOW_STATE_SUSPENDED;
 		ar->state = ATH6KL_STATE_WOW;
+
 		break;
 
 	case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
@@ -2188,6 +2199,9 @@ static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
  */
 void ath6kl_check_wow_status(struct ath6kl *ar)
 {
+	if (ar->wow_state == ATH6KL_WOW_STATE_SUSPENDING)
+		return;
+
 	if (ar->state == ATH6KL_STATE_WOW)
 		ath6kl_cfg80211_resume(ar);
 }
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c
index 722ca59..b522135 100644
--- a/drivers/net/wireless/ath/ath6kl/core.c
+++ b/drivers/net/wireless/ath/ath6kl/core.c
@@ -154,6 +154,8 @@ int ath6kl_core_init(struct ath6kl *ar)
 	else
 		ar->suspend_mode = 0;
 
+	ar->wow_state = ATH6KL_WOW_STATE_NONE;
+
 	if (uart_debug)
 		ar->conf_flags |= ATH6KL_CONF_UART_DEBUG;
 
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index c4d66e0..182ff01 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -527,11 +527,18 @@ enum ath6kl_state {
 	ATH6KL_STATE_SCHED_SCAN,
 };
 
+enum ath6kl_wow_state {
+	ATH6KL_WOW_STATE_NONE,
+	ATH6KL_WOW_STATE_SUSPENDING,
+	ATH6KL_WOW_STATE_SUSPENDED,
+};
+
 struct ath6kl {
 	struct device *dev;
 	struct wiphy *wiphy;
 
 	enum ath6kl_state state;
+	enum ath6kl_wow_state wow_state;
 	unsigned int testmode;
 
 	struct ath6kl_bmi bmi;
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index a3dc694..53a2894 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -284,6 +284,10 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
 	int status = 0;
 	struct ath6kl_cookie *cookie = NULL;
 
+#ifdef CONFIG_PM
+	if (ar->wow_state == ATH6KL_WOW_STATE_SUSPENDED)
+		return -EACCES;
+#endif
 	spin_lock_bh(&ar->lock);
 
 	ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
@@ -352,7 +356,12 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
 	ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
 		   "%s: skb=0x%p, data=0x%p, len=0x%x\n", __func__,
 		   skb, skb->data, skb->len);
-
+#ifdef CONFIG_PM
+	if (ar->wow_state != ATH6KL_WOW_STATE_NONE) {
+		dev_kfree_skb(skb);
+		return 0;
+	}
+#endif
 	/* If target is not associated */
 	if (!test_bit(CONNECTED, &vif->flags)) {
 		dev_kfree_skb(skb);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-02-08  9:40 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-06 13:56 [PATCH] ath6kl: Check wow state before sending control and data pkt rmani
2012-02-06 14:14 ` Kalle Valo
2012-02-07 10:14   ` Raja Mani
2012-02-07 13:33     ` Kalle Valo
2012-02-08  9:40       ` Raja Mani
2012-02-06 14:30 ` Kalle Valo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.