linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] Allow the user to define suspend mode
@ 2012-01-09  8:36 rmani
  2012-01-09  8:36 ` [PATCH 1/8] ath6kl: Rename modparam variable suspend_cutpower to suspend_mode rmani
                   ` (8 more replies)
  0 siblings, 9 replies; 13+ messages in thread
From: rmani @ 2012-01-09  8:36 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, ath6kl-devel, Raja Mani

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

This series of patch enables the user to specify the suspend mode 
via module parameter (suspend_mode) while doing insmod of the driver.

   To select Cut Power mode:
      insmod ath6kl_sdio.ko suspend_mode = 1

   To select Deep Sleep mode:
      insmod ath6kl_sdio.ko suspend_mode = 2

   To select WOW suspend mode:
      insmod ath6kl_sdio.ko suspend_mode = 3

Existing module param 'suspend_cutpower' variable is renamed to 
'suspend_mode' for this purspose.

Dynamic suspend mode selection logic based on the host SDIO 
host controller is removed in ath6kl_sdio_suspend(). 
Now, ath6kl_sdio_suspend() will react based on the module 
parameter 'suspend_mode'.

Additionally, If the user doesn't provide any WOW patterns, 
the default WOW patterns will be configured while going to 
WOW suspend mode.

Please provide your comments on this patch series.

Raja Mani (8):
  ath6kl: Rename modparam variable suspend_cutpower to suspend_mode
  ath6kl: Re-architect suspend mode handling in ath6kl_sdio_suspend()
  ath6kl: Add a new func to configure default WOW patterns for AP mode
  ath6kl: Add a new func to config default WOW patterns for non AP mode
  ath6kl: Move WOW patterns config code to a separate function.
  ath6kl: Configure WOW patterns while going to wow_suspend
  ath6kl: Removed unused ATH6KL_CONF_SUSPEND_CUTPOWER macro
  ath6kl: Return a proper error code when not in connected state

 drivers/net/wireless/ath/ath6kl/cfg80211.c |  222 +++++++++++++++++++++++-----
 drivers/net/wireless/ath/ath6kl/core.h     |    2 +-
 drivers/net/wireless/ath/ath6kl/init.c     |   11 +-
 drivers/net/wireless/ath/ath6kl/sdio.c     |  105 ++++++++-----
 4 files changed, 258 insertions(+), 82 deletions(-)


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

* [PATCH 1/8] ath6kl: Rename modparam variable suspend_cutpower to suspend_mode
  2012-01-09  8:36 [PATCH 0/8] Allow the user to define suspend mode rmani
@ 2012-01-09  8:36 ` rmani
  2012-01-09 19:20   ` Kalle Valo
  2012-01-09  8:36 ` [PATCH 2/8] ath6kl: Re-architect suspend mode handling in ath6kl_sdio_suspend() rmani
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 13+ messages in thread
From: rmani @ 2012-01-09  8:36 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, ath6kl-devel, Raja Mani

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

suspend_cutpower was introduced to force cut power mode when
system goes to suspend state. Now, generic module parameter
is required to specify suspend mode including DEEP SLEEP and WOW
while doing insmod. Renaming existing module parameter variable
suspend_cutpower would be sufficient to meet this requirement.

suspend_mode can take any one of three suspend state,
   1) cut power
   2) deep sleep
   3) wow

For invalid value other than above mode, cut power mode will be
selected.

To avoid externing mod parameter suspend_mode, new variable
ar->suspend_mode is added to have copy of mod param variable
and will be in sdio.c in the following patches.

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

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index c095faf..be61fc3 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -590,6 +590,7 @@ struct ath6kl {
 	} hw;
 
 	u16 conf_flags;
+	u8 suspend_mode;
 	wait_queue_head_t event_wq;
 	struct ath6kl_mbox_info mbox_info;
 
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index a481b6a..feff095 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -27,12 +27,12 @@
 
 unsigned int debug_mask;
 static unsigned int testmode;
-static bool suspend_cutpower;
+static unsigned char suspend_mode;
 static unsigned int uart_debug;
 
 module_param(debug_mask, uint, 0644);
 module_param(testmode, uint, 0644);
-module_param(suspend_cutpower, bool, 0444);
+module_param(suspend_mode, byte, 0644);
 module_param(uart_debug, uint, 0644);
 
 static const struct ath6kl_hw hw_list[] = {
@@ -1676,8 +1676,11 @@ int ath6kl_core_init(struct ath6kl *ar)
 	ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
 			 ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
 
-	if (suspend_cutpower)
-		ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER;
+	if (suspend_mode < WLAN_POWER_STATE_CUT_PWR ||
+	    suspend_mode > WLAN_POWER_STATE_WOW)
+		ar->suspend_mode = WLAN_POWER_STATE_CUT_PWR;
+	else
+		ar->suspend_mode = suspend_mode;
 
 	ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
 			    WIPHY_FLAG_HAVE_AP_SME |
-- 
1.7.1


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

* [PATCH 2/8] ath6kl: Re-architect suspend mode handling in ath6kl_sdio_suspend()
  2012-01-09  8:36 [PATCH 0/8] Allow the user to define suspend mode rmani
  2012-01-09  8:36 ` [PATCH 1/8] ath6kl: Rename modparam variable suspend_cutpower to suspend_mode rmani
@ 2012-01-09  8:36 ` rmani
  2012-01-09 19:30   ` Kalle Valo
  2012-01-09  8:36 ` [PATCH 3/8] ath6kl: Add a new func to configure default WOW patterns for AP mode rmani
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 13+ messages in thread
From: rmani @ 2012-01-09  8:36 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, ath6kl-devel, Raja Mani

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

Dynamic suspend mode selection logic based on the host sdio
controller capability (MMC_PM_KEEP_POWER and MMC_PM_WAKE_SDIO_IRQ)
is completely removed.

Now, ath6kl_sdio_suspend() func will react based on the suspend mode
specified at the time of loading the driver (via module parameter
suspend_mode).

Additionally, new logic is added to have backup retry.
In other words, If the driver fails to enter into either
WOW (or) DEEP SLEEP mode, it would give a try in CUT POWER mode.

Signed-off-by: Raja Mani <rmani@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/sdio.c |  105 ++++++++++++++++++++------------
 1 files changed, 66 insertions(+), 39 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 278a9f3..9eae745 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -787,66 +787,93 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 	struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
 	struct sdio_func *func = ar_sdio->func;
 	mmc_pm_flag_t flags;
-	int ret;
+	unsigned char pmode_to_try;
+	int ret = -EINVAL;
 
 	flags = sdio_get_host_pm_caps(func);
 
 	ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio suspend pm_caps 0x%x\n", flags);
 
-	if (!(flags & MMC_PM_KEEP_POWER) ||
-	    (ar->conf_flags & ATH6KL_CONF_SUSPEND_CUTPOWER)) {
-		/* as host doesn't support keep power we need to cut power */
-		return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER,
-					       NULL);
-	}
-
-	ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
-	if (ret) {
-		printk(KERN_ERR "ath6kl: set sdio pm flags failed: %d\n",
-		       ret);
-		return ret;
-	}
+	/* Schedule scan uses WOW internally */
+	pmode_to_try = (ar->state == ATH6KL_STATE_SCHED_SCAN) ?
+			WLAN_POWER_STATE_WOW : ar->suspend_mode;
+retry:
+	switch (pmode_to_try) {
+	case WLAN_POWER_STATE_CUT_PWR:
+		ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER,
+					      NULL);
+		break;
 
-	if (!(flags & MMC_PM_WAKE_SDIO_IRQ))
-		goto deepsleep;
+	case WLAN_POWER_STATE_DEEP_SLEEP:
+		/* Try cut power if deep sleep suspend fails */
+		pmode_to_try = WLAN_POWER_STATE_CUT_PWR;
 
-	/* sdio irq wakes up host */
+		if (!(flags & MMC_PM_KEEP_POWER))
+			goto retry;
 
-	if (ar->state == ATH6KL_STATE_SCHED_SCAN) {
-		ret =  ath6kl_cfg80211_suspend(ar,
-					       ATH6KL_CFG_SUSPEND_SCHED_SCAN,
-					       NULL);
+		ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
 		if (ret) {
-			ath6kl_warn("Schedule scan suspend failed: %d", ret);
-			return ret;
+			ath6kl_warn("failed to set sdio keep power flag: %d\n",
+				     ret);
+			goto retry;
 		}
 
-		ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
+		ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP,
+					      NULL);
 		if (ret)
-			ath6kl_warn("set sdio wake irq flag failed: %d\n", ret);
+			goto retry;
 
-		return ret;
-	}
+		break;
 
-	if (wow) {
+	case WLAN_POWER_STATE_WOW:
+		/* Try cut power if wow suspend fails */
+		pmode_to_try = WLAN_POWER_STATE_CUT_PWR;
+
+		if (!(flags & MMC_PM_KEEP_POWER) ||
+		    !(flags & MMC_PM_WAKE_SDIO_IRQ))
+			goto retry;
+
+		ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+		if (ret) {
+			ath6kl_warn("failed to set sdio keep power flag: %d\n",
+				     ret);
+			goto retry;
+		}
+
+		ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
+		if (ret) {
+			ath6kl_warn("failed to set sdio wake irq flag: %d\n",
+				     ret);
+			goto retry;
+		}
 		/*
 		 * The host sdio controller is capable of keep power and
-		 * sdio irq wake up at this point. It's fine to continue
-		 * wow suspend operation.
+		 * sdio irq wake up at this point.
 		 */
-		ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow);
-		if (ret)
-			return ret;
-
-		ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
+		if (ar->state == ATH6KL_STATE_SCHED_SCAN) {
+			ath6kl_dbg(ATH6KL_DBG_SUSPEND,
+				  "sched scan is in progress\n");
+			ret =  ath6kl_cfg80211_suspend(ar,
+						ATH6KL_CFG_SUSPEND_SCHED_SCAN,
+						NULL);
+			if (ret)
+				ath6kl_warn("schedule scan suspend failed: %d",
+					    ret);
+		} else
+			ret = ath6kl_cfg80211_suspend(ar,
+					ATH6KL_CFG_SUSPEND_WOW, wow);
 		if (ret)
-			ath6kl_err("set sdio wake irq flag failed: %d\n", ret);
+			goto retry;
+		break;
 
-		return ret;
+	default:
+		/* We shouldn't be here. */
+		WARN_ON(1);
+		break;
 	}
 
-deepsleep:
-	return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, NULL);
+	return ret;
+
 }
 
 static int ath6kl_sdio_resume(struct ath6kl *ar)
-- 
1.7.1


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

* [PATCH 3/8] ath6kl: Add a new func to configure default WOW patterns for AP mode
  2012-01-09  8:36 [PATCH 0/8] Allow the user to define suspend mode rmani
  2012-01-09  8:36 ` [PATCH 1/8] ath6kl: Rename modparam variable suspend_cutpower to suspend_mode rmani
  2012-01-09  8:36 ` [PATCH 2/8] ath6kl: Re-architect suspend mode handling in ath6kl_sdio_suspend() rmani
@ 2012-01-09  8:36 ` rmani
  2012-01-09  8:36 ` [PATCH 4/8] ath6kl: Add a new func to config default WOW patterns for non " rmani
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: rmani @ 2012-01-09  8:36 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, ath6kl-devel, Raja Mani

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

ath6kl_ap_add_default_wow_patterns() is added to configure the below
default patterns when the system enters into WOW suspend in AP mode.

  * Unicast IP, EAPOL-like and ARP packet pattern
  * ARP packet pattern
  * mDNS/SSDP/LLMNR pattern
  * DHCP broadcast pattern

This will be called from ath6kl_wow_suspend() func.

Signed-off-by: Raja Mani <rmani@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c |   77 ++++++++++++++++++++++++++++
 1 files changed, 77 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 2a166cc..deba99c 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1727,6 +1727,83 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
 	return 0;
 }
 
+static int ath6kl_ap_add_default_wow_patterns(struct ath6kl *ar,
+		struct ath6kl_vif *vif)
+{
+	static u8 unicst_pattern[] = { 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 };
+	static u8 unicst_mask[] = { 0x01, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f };
+	u8 unicst_offset = 0;
+	static u8 arp_pattern[] = { 0x08, 0x06 };
+	static u8 arp_mask[] = { 0xff, 0xff };
+	u8 arp_offset = 20;
+	static u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
+	static u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
+	u8 discvr_offset = 38;
+	static u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x43 /* port 67 */ };
+	static u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0xff, 0xff /* port 67 */ };
+	u8 dhcp_offset = 0;
+	int ret;
+
+	/* Setup unicast IP, EAPOL-like and ARP pkt pattern */
+	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+			vif->fw_vif_idx, WOW_LIST_ID,
+			sizeof(unicst_pattern), unicst_offset,
+			unicst_pattern, unicst_mask);
+	if (ret) {
+		ath6kl_err("failed to add WOW unicast IP pattern\n");
+		return ret;
+	}
+
+	/* Setup all ARP pkt pattern */
+	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+			vif->fw_vif_idx, WOW_LIST_ID,
+			sizeof(arp_pattern), arp_offset,
+			arp_pattern, arp_mask);
+	if (ret) {
+		ath6kl_err("failed to add WOW ARP pattern\n");
+		return ret;
+	}
+
+	/*
+	 * Setup multicast pattern for mDNS 224.0.0.251,
+	 * SSDP 239.255.255.250 and LLMNR  224.0.0.252
+	 */
+	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+			vif->fw_vif_idx, WOW_LIST_ID,
+			sizeof(discvr_pattern), discvr_offset,
+			discvr_pattern, discvr_mask);
+	if (ret) {
+		ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
+		return ret;
+	}
+
+	/* Setup all DHCP broadcast pkt pattern */
+	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+			vif->fw_vif_idx, WOW_LIST_ID,
+			sizeof(dhcp_pattern), dhcp_offset,
+			dhcp_pattern, dhcp_mask);
+	if (ret) {
+		ath6kl_err("failed to add WOW DHCP broadcast pattern\n");
+		return ret;
+	}
+
+	return 0;
+}
+
 static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 {
 	struct in_device *in_dev;
-- 
1.7.1


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

* [PATCH 4/8] ath6kl: Add a new func to config default WOW patterns for non AP mode
  2012-01-09  8:36 [PATCH 0/8] Allow the user to define suspend mode rmani
                   ` (2 preceding siblings ...)
  2012-01-09  8:36 ` [PATCH 3/8] ath6kl: Add a new func to configure default WOW patterns for AP mode rmani
@ 2012-01-09  8:36 ` rmani
  2012-01-09  8:36 ` [PATCH 5/8] ath6kl: Move WOW patterns config code to a separate function rmani
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: rmani @ 2012-01-09  8:36 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, ath6kl-devel, Raja Mani

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

ath6kl_non_ap_add_default_wow_patterns() is added to configure the below
default patterns when the system enters into WOW suspend in non AP mode.

  * Unicast packet pattern
  * mDNS/SSDP/LLMNR pattern

This func will be called from ath6kl_wow_suspend().

Signed-off-by: Raja Mani <rmani@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c |   40 ++++++++++++++++++++++++++++
 1 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index deba99c..65e4609 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1804,6 +1804,46 @@ static int ath6kl_ap_add_default_wow_patterns(struct ath6kl *ar,
 	return 0;
 }
 
+static int ath6kl_non_ap_add_default_wow_patterns(struct ath6kl *ar,
+						     struct ath6kl_vif *vif)
+{
+	struct net_device *ndev = vif->ndev;
+	static u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
+	static u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
+	u8 discvr_offset = 38;
+	u8 mac_mask[ETH_ALEN];
+	int ret;
+
+	/* Setup unicast pkt pattern */
+	memset(mac_mask, 0xff, ETH_ALEN);
+	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+				vif->fw_vif_idx, WOW_LIST_ID,
+				ETH_ALEN, 0, ndev->dev_addr,
+				mac_mask);
+	if (ret) {
+		ath6kl_err("failed to add WOW unicast pattern\n");
+		return ret;
+	}
+
+	/*
+	 * Setup multicast pattern for mDNS 224.0.0.251,
+	 * SSDP 239.255.255.250 and LLMNR 224.0.0.252
+	 */
+	if ((ndev->flags & IFF_ALLMULTI) ||
+	    (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) {
+		ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+				vif->fw_vif_idx, WOW_LIST_ID,
+				sizeof(discvr_pattern), discvr_offset,
+				discvr_pattern, discvr_mask);
+		if (ret) {
+			ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 {
 	struct in_device *in_dev;
-- 
1.7.1


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

* [PATCH 5/8] ath6kl: Move WOW patterns config code to a separate function.
  2012-01-09  8:36 [PATCH 0/8] Allow the user to define suspend mode rmani
                   ` (3 preceding siblings ...)
  2012-01-09  8:36 ` [PATCH 4/8] ath6kl: Add a new func to config default WOW patterns for non " rmani
@ 2012-01-09  8:36 ` rmani
  2012-01-09  8:36 ` [PATCH 6/8] ath6kl: Configure WOW patterns while going to wow_suspend rmani
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: rmani @ 2012-01-09  8:36 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, ath6kl-devel, Raja Mani

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

Move the user provided WOW patterns configuration code
from ath6kl_wow_suspend() to a separate function called
ath6kl_add_usr_wow_patterns().

It gives more modularity to the existing code.

Signed-off-by: Raja Mani <rmani@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c |  108 +++++++++++++++------------
 1 files changed, 60 insertions(+), 48 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 65e4609..347c5a4 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1727,6 +1727,64 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
 	return 0;
 }
 
+static int ath6kl_add_usr_wow_patterns(struct ath6kl *ar,
+				       struct ath6kl_vif *vif,
+				       struct cfg80211_wowlan *wow,
+				       u32 *filter)
+{
+	int ret, pos;
+	u8 mask[WOW_MASK_SIZE];
+	u16 i;
+
+	/* Configure the patterns that we received from the user. */
+	for (i = 0; i < wow->n_patterns; i++) {
+
+		/*
+		 * Convert given nl80211 specific mask value to equivalent
+		 * driver specific mask value and send it to the chip along
+		 * with patterns. For example, If the mask value defined in
+		 * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
+		 * then equivalent driver specific mask value is
+		 * "0xFF 0x00 0xFF 0x00".
+		 */
+		memset(&mask, 0, sizeof(mask));
+		for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
+			if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
+				mask[pos] = 0xFF;
+		}
+		/*
+		 * Note: Pattern's offset is not passed as part of wowlan
+		 * parameter from CFG layer. So it's always passed as ZERO
+		 * to the firmware. It means, given WOW patterns are always
+		 * matched from the first byte of received pkt in the firmware.
+		 */
+		ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+					vif->fw_vif_idx, WOW_LIST_ID,
+					wow->patterns[i].pattern_len,
+					0 /* pattern offset */,
+					wow->patterns[i].pattern, mask);
+		if (ret)
+			return ret;
+	}
+
+	if (wow->disconnect)
+		*filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
+
+	if (wow->magic_pkt)
+		*filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
+
+	if (wow->gtk_rekey_failure)
+		*filter |= WOW_FILTER_OPTION_GTK_ERROR;
+
+	if (wow->eap_identity_req)
+		*filter |= WOW_FILTER_OPTION_EAP_REQ;
+
+	if (wow->four_way_handshake)
+		*filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
+
+	return 0;
+}
+
 static int ath6kl_ap_add_default_wow_patterns(struct ath6kl *ar,
 		struct ath6kl_vif *vif)
 {
@@ -1849,10 +1907,10 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 	struct in_device *in_dev;
 	struct in_ifaddr *ifa;
 	struct ath6kl_vif *vif;
-	int ret, pos, left;
+	int ret, left;
 	u32 filter = 0;
 	u16 i;
-	u8 mask[WOW_MASK_SIZE], index = 0;
+	u8 index = 0;
 	__be32 ips[MAX_IP_ADDRS];
 
 	vif = ath6kl_vif_first(ar);
@@ -1869,37 +1927,6 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 	for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
 		ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
 					       WOW_LIST_ID, i);
-	/* Configure new WOW patterns */
-	for (i = 0; i < wow->n_patterns; i++) {
-
-		/*
-		 * Convert given nl80211 specific mask value to equivalent
-		 * driver specific mask value and send it to the chip along
-		 * with patterns. For example, If the mask value defined in
-		 * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
-		 * then equivalent driver specific mask value is
-		 * "0xFF 0x00 0xFF 0x00".
-		 */
-		memset(&mask, 0, sizeof(mask));
-		for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
-			if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
-				mask[pos] = 0xFF;
-		}
-		/*
-		 * Note: Pattern's offset is not passed as part of wowlan
-		 * parameter from CFG layer. So it's always passed as ZERO
-		 * to the firmware. It means, given WOW patterns are always
-		 * matched from the first byte of received pkt in the firmware.
-		 */
-		ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
-					vif->fw_vif_idx, WOW_LIST_ID,
-					wow->patterns[i].pattern_len,
-					0 /* pattern offset */,
-					wow->patterns[i].pattern, mask);
-		if (ret)
-			return ret;
-	}
-
 	/* Setup own IP addr for ARP agent. */
 	in_dev = __in_dev_get_rtnl(vif->ndev);
 	if (!in_dev)
@@ -1927,21 +1954,6 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 	}
 
 skip_arp:
-	if (wow->disconnect)
-		filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
-
-	if (wow->magic_pkt)
-		filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
-
-	if (wow->gtk_rekey_failure)
-		filter |= WOW_FILTER_OPTION_GTK_ERROR;
-
-	if (wow->eap_identity_req)
-		filter |= WOW_FILTER_OPTION_EAP_REQ;
-
-	if (wow->four_way_handshake)
-		filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
-
 	ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
 					  ATH6KL_WOW_MODE_ENABLE,
 					  filter,
-- 
1.7.1


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

* [PATCH 6/8] ath6kl: Configure WOW patterns while going to wow_suspend
  2012-01-09  8:36 [PATCH 0/8] Allow the user to define suspend mode rmani
                   ` (4 preceding siblings ...)
  2012-01-09  8:36 ` [PATCH 5/8] ath6kl: Move WOW patterns config code to a separate function rmani
@ 2012-01-09  8:36 ` rmani
  2012-01-09  8:36 ` [PATCH 7/8] ath6kl: Removed unused ATH6KL_CONF_SUSPEND_CUTPOWER macro rmani
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: rmani @ 2012-01-09  8:36 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, ath6kl-devel, Raja Mani

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

First preference is given to the user configured WOW patterns.
If the user doesn't configure any patterns (for ex, via iw command),
the default patterns will be configured while going to WOW suspend.

Make use of ath6kl_ap_add_default_wow_patterns() and
ath6kl_non_ap_add_default_wow_patterns() func to configure
default WOW patterns.

Additionally, new conditional check is added to make sure user
configured pattern count is within the limit (WOW_MAX_FILTERS_PER_LIST).

Signed-off-by: Raja Mani <rmani@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 347c5a4..a8880af 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1923,10 +1923,27 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 	if (!test_bit(CONNECTED, &vif->flags))
 		return -EINVAL;
 
+	if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
+		return -EINVAL;
+
 	/* Clear existing WOW patterns */
 	for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
 		ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
 					       WOW_LIST_ID, i);
+	/*
+	 * Skip the default WOW pattern configuration if the driver
+	 * receives any WOW patterns from the user.
+	 */
+	if (wow)
+		ret = ath6kl_add_usr_wow_patterns(ar, vif, wow, &filter);
+	else if (vif->nw_type == AP_NETWORK)
+		ret = ath6kl_ap_add_default_wow_patterns(ar, vif);
+	else
+		ret = ath6kl_non_ap_add_default_wow_patterns(ar, vif);
+
+	if (ret)
+		return ret;
+
 	/* Setup own IP addr for ARP agent. */
 	in_dev = __in_dev_get_rtnl(vif->ndev);
 	if (!in_dev)
-- 
1.7.1


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

* [PATCH 7/8] ath6kl: Removed unused ATH6KL_CONF_SUSPEND_CUTPOWER macro
  2012-01-09  8:36 [PATCH 0/8] Allow the user to define suspend mode rmani
                   ` (5 preceding siblings ...)
  2012-01-09  8:36 ` [PATCH 6/8] ath6kl: Configure WOW patterns while going to wow_suspend rmani
@ 2012-01-09  8:36 ` rmani
  2012-01-09 19:45   ` Kalle Valo
  2012-01-09  8:36 ` [PATCH 8/8] ath6kl: Return a proper error code when not in connected state rmani
  2012-01-09 17:52 ` [PATCH 0/8] Allow the user to define suspend mode Kalle Valo
  8 siblings, 1 reply; 13+ messages in thread
From: rmani @ 2012-01-09  8:36 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, ath6kl-devel, Raja Mani

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

Title says everything.

Signed-off-by: Raja Mani <rmani@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/core.h |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index be61fc3..b6b756b 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -188,7 +188,6 @@ struct ath6kl_fw_ie {
 #define ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN  BIT(1)
 #define ATH6KL_CONF_ENABLE_11N			BIT(2)
 #define ATH6KL_CONF_ENABLE_TX_BURST		BIT(3)
-#define ATH6KL_CONF_SUSPEND_CUTPOWER		BIT(4)
 
 enum wlan_low_pwr_state {
 	WLAN_POWER_STATE_ON,
-- 
1.7.1


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

* [PATCH 8/8] ath6kl: Return a proper error code when not in connected state
  2012-01-09  8:36 [PATCH 0/8] Allow the user to define suspend mode rmani
                   ` (6 preceding siblings ...)
  2012-01-09  8:36 ` [PATCH 7/8] ath6kl: Removed unused ATH6KL_CONF_SUSPEND_CUTPOWER macro rmani
@ 2012-01-09  8:36 ` rmani
  2012-01-09 17:52 ` [PATCH 0/8] Allow the user to define suspend mode Kalle Valo
  8 siblings, 0 replies; 13+ messages in thread
From: rmani @ 2012-01-09  8:36 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, ath6kl-devel, Raja Mani

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

Error code ENOTCONN is more suitable than EINVAL to report
when the driver is not in connected state in ath6kl_wow_suspend().

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

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index a8880af..a5929b3 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1921,7 +1921,7 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 		return -EIO;
 
 	if (!test_bit(CONNECTED, &vif->flags))
-		return -EINVAL;
+		return -ENOTCONN;
 
 	if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
 		return -EINVAL;
-- 
1.7.1


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

* Re: [PATCH 0/8] Allow the user to define suspend mode
  2012-01-09  8:36 [PATCH 0/8] Allow the user to define suspend mode rmani
                   ` (7 preceding siblings ...)
  2012-01-09  8:36 ` [PATCH 8/8] ath6kl: Return a proper error code when not in connected state rmani
@ 2012-01-09 17:52 ` Kalle Valo
  8 siblings, 0 replies; 13+ messages in thread
From: Kalle Valo @ 2012-01-09 17:52 UTC (permalink / raw)
  To: rmani; +Cc: linux-wireless, ath6kl-devel, John W. Linville, Johannes Berg

On 01/09/2012 10:36 AM, rmani@qca.qualcomm.com wrote:

> This series of patch enables the user to specify the suspend mode 
> via module parameter (suspend_mode) while doing insmod of the driver.
> 
>    To select Cut Power mode:
>       insmod ath6kl_sdio.ko suspend_mode = 1
> 
>    To select Deep Sleep mode:
>       insmod ath6kl_sdio.ko suspend_mode = 2
> 
>    To select WOW suspend mode:
>       insmod ath6kl_sdio.ko suspend_mode = 3
> 
> Existing module param 'suspend_cutpower' variable is renamed to 
> 'suspend_mode' for this purspose.

I'm not sure about this one. In a way this makes sense so that user can
force the particular suspend mode, but on the other hand I'm not sure if
this is a bit too much.

J&J (John and Johannes), what do you think? Is this acceptable?

Kalle

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

* Re: [PATCH 1/8] ath6kl: Rename modparam variable suspend_cutpower to suspend_mode
  2012-01-09  8:36 ` [PATCH 1/8] ath6kl: Rename modparam variable suspend_cutpower to suspend_mode rmani
@ 2012-01-09 19:20   ` Kalle Valo
  0 siblings, 0 replies; 13+ messages in thread
From: Kalle Valo @ 2012-01-09 19:20 UTC (permalink / raw)
  To: rmani; +Cc: linux-wireless, ath6kl-devel

On 01/09/2012 10:36 AM, rmani@qca.qualcomm.com wrote:
> From: Raja Mani <rmani@qca.qualcomm.com>
> 
> suspend_cutpower was introduced to force cut power mode when
> system goes to suspend state. Now, generic module parameter
> is required to specify suspend mode including DEEP SLEEP and WOW
> while doing insmod. Renaming existing module parameter variable
> suspend_cutpower would be sufficient to meet this requirement.
> 
> suspend_mode can take any one of three suspend state,
>    1) cut power
>    2) deep sleep
>    3) wow
> 
> For invalid value other than above mode, cut power mode will be
> selected.
> 
> To avoid externing mod parameter suspend_mode, new variable
> ar->suspend_mode is added to have copy of mod param variable
> and will be in sdio.c in the following patches.
> 
> Signed-off-by: Raja Mani <rmani@qca.qualcomm.com>

I think this patch needs to be folded with something else, maybe with
patch 2?

Kalle

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

* Re: [PATCH 2/8] ath6kl: Re-architect suspend mode handling in ath6kl_sdio_suspend()
  2012-01-09  8:36 ` [PATCH 2/8] ath6kl: Re-architect suspend mode handling in ath6kl_sdio_suspend() rmani
@ 2012-01-09 19:30   ` Kalle Valo
  0 siblings, 0 replies; 13+ messages in thread
From: Kalle Valo @ 2012-01-09 19:30 UTC (permalink / raw)
  To: rmani; +Cc: linux-wireless, ath6kl-devel

On 01/09/2012 10:36 AM, rmani@qca.qualcomm.com wrote:
> From: Raja Mani <rmani@qca.qualcomm.com>
> 
> Dynamic suspend mode selection logic based on the host sdio
> controller capability (MMC_PM_KEEP_POWER and MMC_PM_WAKE_SDIO_IRQ)
> is completely removed.

What's the reason for this change? This loses all the automatic
detection we have. I would hope that we could keep the existing
detection capability and use the module parameter to override the
detection logic or something like that.

The driver should be as automatic as possible and the suspend_mode
module parameter should be used to override something.

> Additionally, new logic is added to have backup retry.
> In other words, If the driver fails to enter into either
> WOW (or) DEEP SLEEP mode, it would give a try in CUT POWER mode.

So the function now has a loop. To me that sounds very confusing and
error prone. What's the reason for this?

Kalle

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

* Re: [PATCH 7/8] ath6kl: Removed unused ATH6KL_CONF_SUSPEND_CUTPOWER macro
  2012-01-09  8:36 ` [PATCH 7/8] ath6kl: Removed unused ATH6KL_CONF_SUSPEND_CUTPOWER macro rmani
@ 2012-01-09 19:45   ` Kalle Valo
  0 siblings, 0 replies; 13+ messages in thread
From: Kalle Valo @ 2012-01-09 19:45 UTC (permalink / raw)
  To: rmani; +Cc: linux-wireless, ath6kl-devel

On 01/09/2012 10:36 AM, rmani@qca.qualcomm.com wrote:
> From: Raja Mani <rmani@qca.qualcomm.com>
> 
> Title says everything.

You can fold this with patch 1 where you remove the code using this define.

Kalle

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

end of thread, other threads:[~2012-01-09 19:47 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-09  8:36 [PATCH 0/8] Allow the user to define suspend mode rmani
2012-01-09  8:36 ` [PATCH 1/8] ath6kl: Rename modparam variable suspend_cutpower to suspend_mode rmani
2012-01-09 19:20   ` Kalle Valo
2012-01-09  8:36 ` [PATCH 2/8] ath6kl: Re-architect suspend mode handling in ath6kl_sdio_suspend() rmani
2012-01-09 19:30   ` Kalle Valo
2012-01-09  8:36 ` [PATCH 3/8] ath6kl: Add a new func to configure default WOW patterns for AP mode rmani
2012-01-09  8:36 ` [PATCH 4/8] ath6kl: Add a new func to config default WOW patterns for non " rmani
2012-01-09  8:36 ` [PATCH 5/8] ath6kl: Move WOW patterns config code to a separate function rmani
2012-01-09  8:36 ` [PATCH 6/8] ath6kl: Configure WOW patterns while going to wow_suspend rmani
2012-01-09  8:36 ` [PATCH 7/8] ath6kl: Removed unused ATH6KL_CONF_SUSPEND_CUTPOWER macro rmani
2012-01-09 19:45   ` Kalle Valo
2012-01-09  8:36 ` [PATCH 8/8] ath6kl: Return a proper error code when not in connected state rmani
2012-01-09 17:52 ` [PATCH 0/8] Allow the user to define suspend mode Kalle Valo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).