[PATCH v2 2/5] Add the power save control framework and debugfs entry

dreamfly281 at gmail.com dreamfly281 at gmail.com
Mon Jul 8 12:43:25 EDT 2013


From: Yanbo Li <yanbol at qti.qualcomm.com>

The patch add the power save framework which will be extended for
system power control relative function, especialy for power save.
It also add the debugfs entry for manual control the BMPS for debug

Signed-off-by: Yanbo Li <yanbol at qti.qualcomm.com>
---
 Makefile  |    1 +
 debug.c   |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 debug.h   |    1 +
 main.c    |    4 +++-
 pmc.c     |   42 ++++++++++++++++++++++++++++++++++++++++++
 pmc.h     |   35 +++++++++++++++++++++++++++++++++++
 wcn36xx.h |    4 ++++
 7 files changed, 146 insertions(+), 1 deletion(-)
 create mode 100644 pmc.c
 create mode 100644 pmc.h

diff --git a/Makefile b/Makefile
index 12c6d23..0cd44f9 100644
--- a/Makefile
+++ b/Makefile
@@ -10,6 +10,7 @@ ifneq ($(KERNELRELEASE),)
 				dxe.o \
 				txrx.o \
 				smd.o \
+				pmc.o \
 				debug.o
 
 	obj-m := wcn36xx.o
diff --git a/debug.c b/debug.c
index a54f15d..6698166 100644
--- a/debug.c
+++ b/debug.c
@@ -23,6 +23,64 @@
 #include <linux/uaccess.h>
 #include "wcn36xx.h"
 #include "debug.h"
+#include "pmc.h"
+
+static int wcn36xx_debugfs_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+static ssize_t read_file_bool_bmps(struct file *file, char __user *user_buf,
+				   size_t count, loff_t *ppos)
+{
+	struct wcn36xx *wcn = file->private_data;
+	char buf[3];
+
+	if (wcn->pw_state == WCN36XX_BMPS)
+		buf[0] = '1';
+	else
+		buf[0] = '0';
+	buf[1] = '\n';
+	buf[2] = 0x00;
+	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
+}
+
+static ssize_t write_file_bool_bmps(struct file *file,
+				    const char __user *user_buf,
+				    size_t count, loff_t *ppos)
+{
+	struct wcn36xx *wcn = file->private_data;
+	struct ieee80211_vif *vif = container_of((void *)wcn->current_vif,
+						 struct ieee80211_vif,
+						 drv_priv);
+	char buf[32];
+	int buf_size;
+
+	buf_size = min(count, (sizeof(buf)-1));
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+
+	switch (buf[0]) {
+	case 'y':
+	case 'Y':
+	case '1':
+		wcn36xx_pmc_enter_bmps_state(wcn, vif->bss_conf.sync_tsf);
+		break;
+	case 'n':
+	case 'N':
+	case '0':
+		wcn36xx_pmc_exit_bmps_state(wcn);
+		break;
+	}
+
+	return count;
+}
+
+static const struct file_operations fops_wcn36xx_bmps = {
+	.open  =       wcn36xx_debugfs_open,
+	.read  =       read_file_bool_bmps,
+	.write =       write_file_bool_bmps,
+};
 
 #define ADD_FILE_BOOL(name, mode, fop, priv_data)		\
 	do {							\
@@ -48,6 +106,8 @@ void wcn36xx_debugfs_init(struct wcn36xx *wcn)
 		wcn36xx_warn("Create the debugfs failed");
 		dfs->rootdir = NULL;
 	}
+	ADD_FILE_BOOL(bmps_switcher, S_IRUSR | S_IWUSR,
+		      &fops_wcn36xx_bmps, wcn);
 }
 
 void wcn36xx_debugfs_exit(struct wcn36xx *wcn)
diff --git a/debug.h b/debug.h
index f74e582..8afb673 100644
--- a/debug.h
+++ b/debug.h
@@ -31,6 +31,7 @@ struct wcn36xx_dfs_file {
 
 struct wcn36xx_dfs_entry {
 	struct dentry *rootdir;
+	struct wcn36xx_dfs_file file_bmps_switcher;
 };
 
 void wcn36xx_debugfs_init(struct wcn36xx *wcn);
diff --git a/main.c b/main.c
index 92de751..61a4efe 100644
--- a/main.c
+++ b/main.c
@@ -241,6 +241,7 @@ static int wcn36xx_start(struct ieee80211_hw *hw)
 		wcn36xx_error("DXE init failed");
 		goto out_smd_stop;
 	}
+	wcn36xx_pmc_init(wcn);
 	wcn36xx_debugfs_init(wcn);
 	return 0;
 
@@ -487,6 +488,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
 	struct sk_buff *skb = NULL;
 	u16 tim_off, tim_len;
 	enum wcn36xx_hal_link_state link_state;
+
 	wcn->current_vif = (struct wcn36xx_vif *)vif->drv_priv;
 
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss info changed vif %p changed 0x%08x",
@@ -715,7 +717,7 @@ static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow)
 	mutex_lock(&wcn->pm_mutex);
 	/* Enter BMPS only in connected state */
 	if (wcn->aid > 0)
-		wcn36xx_smd_enter_bmps(wcn, vif->bss_conf.sync_tsf);
+		wcn36xx_pmc_enter_bmps_state(wcn, vif->bss_conf.sync_tsf);
 	wcn->is_suspended = true;
 	wcn->is_con_lost_pending = false;
 
diff --git a/pmc.c b/pmc.c
new file mode 100644
index 0000000..8108239
--- /dev/null
+++ b/pmc.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * Licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "wcn36xx.h"
+
+int wcn36xx_pmc_init(struct wcn36xx *wcn)
+{
+	wcn->pw_state = WCN36XX_FULL_POWER;
+	return 0;
+}
+
+int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn, u64 tsf)
+{
+	/* TODO: Make sure the TX chain clean */
+	wcn36xx_smd_enter_bmps(wcn, tsf);
+	wcn->pw_state = WCN36XX_BMPS;
+	return 0;
+}
+
+int wcn36xx_pmc_exit_bmps_state(struct wcn36xx *wcn)
+{
+	wcn36xx_smd_exit_bmps(wcn);
+	wcn->pw_state = WCN36XX_FULL_POWER;
+	return 0;
+}
diff --git a/pmc.h b/pmc.h
new file mode 100644
index 0000000..47ff1ea
--- /dev/null
+++ b/pmc.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * Licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef _WCN36XX_PMC_H_
+#define _WCN36XX_PMC_H_
+
+struct wcn36xx;
+
+enum wcn36xx_power_state {
+	WCN36XX_FULL_POWER,
+	WCN36XX_BMPS
+};
+
+int wcn36xx_pmc_init(struct wcn36xx *wcn);
+int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn, u64 tbtt);
+int wcn36xx_pmc_exit_bmps_state(struct wcn36xx *wcn);
+int wcn36xx_enable_keep_alive_null_packet(struct wcn36xx *wcn);
+#endif	/* _WCN36XX_PMC_H_ */
diff --git a/wcn36xx.h b/wcn36xx.h
index c84ee81..8bf0c86 100644
--- a/wcn36xx.h
+++ b/wcn36xx.h
@@ -29,6 +29,7 @@
 #include "smd.h"
 #include "txrx.h"
 #include "dxe.h"
+#include "pmc.h"
 #include "debug.h"
 
 #define DRIVER_PREFIX "wcn36xx: "
@@ -171,6 +172,9 @@ struct wcn36xx {
 
 	struct sk_buff		*tx_ack_skb;
 
+	/* Power management */
+	enum wcn36xx_power_state     pw_state;
+
 	/* Debug file system entry */
 	struct wcn36xx_dfs_entry    dfs;
 };
-- 
1.7.9.5




More information about the wcn36xx mailing list