[PATCH 6/9] wcn36xx: enter BMPS right after DORA is finished

Eugene Krasnikov k.eugene.e at gmail.com
Fri Sep 6 04:09:18 EDT 2013


This is when wcn36xx can start to save power.

Signed-off-by: Eugene Krasnikov <k.eugene.e at gmail.com>
---
 debug.c   |  6 +++---
 main.c    | 47 +++++++++++++++--------------------------------
 pmc.c     | 35 +++++++++++++++++++++++++++--------
 pmc.h     | 10 ++++++----
 smd.c     | 19 ++++++++++++-------
 smd.h     |  8 +++++---
 wcn36xx.h |  5 -----
 7 files changed, 68 insertions(+), 62 deletions(-)

diff --git a/debug.c b/debug.c
index 91508f3..f23301e 100644
--- a/debug.c
+++ b/debug.c
@@ -67,13 +67,13 @@ static ssize_t write_file_bool_bmps(struct file *file,
 	case 'y':
 	case 'Y':
 	case '1':
-		wcn36xx_enable_keep_alive_null_packet(wcn);
-		wcn36xx_pmc_enter_bmps_state(wcn, vif->bss_conf.sync_tsf);
+		wcn36xx_enable_keep_alive_null_packet(wcn, vif);
+		wcn36xx_pmc_enter_bmps_state(wcn, vif);
 		break;
 	case 'n':
 	case 'N':
 	case '0':
-		wcn36xx_pmc_exit_bmps_state(wcn);
+		wcn36xx_pmc_exit_bmps_state(wcn, vif);
 		break;
 	}
 
diff --git a/main.c b/main.c
index d5cf15d..aaa4176 100644
--- a/main.c
+++ b/main.c
@@ -507,6 +507,17 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
 		wcn->dtim_period = bss_conf->dtim_period;
 	}
 
+	if (changed & BSS_CHANGED_PS) {
+		wcn36xx_dbg(WCN36XX_DBG_MAC,
+			    "mac bss PS set %d\n",
+			    bss_conf->ps);
+		if (bss_conf->ps) {
+			wcn36xx_pmc_enter_bmps_state(wcn, vif);
+		} else {
+			wcn36xx_pmc_exit_bmps_state(wcn, vif);
+		}
+	}
+
 	if (changed & BSS_CHANGED_BSSID) {
 		wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss changed_bssid %pM\n",
 			    bss_conf->bssid);
@@ -656,6 +667,8 @@ static int wcn36xx_add_interface(struct ieee80211_hw *hw,
 {
 	struct wcn36xx *wcn = hw->priv;
 	struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv;
+	wcn->current_vif = vif_priv;
+
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac add interface vif %p type %d\n",
 		    vif, vif->type);
 
@@ -711,47 +724,19 @@ static int wcn36xx_sta_remove(struct ieee80211_hw *hw,
 static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow)
 {
 	struct wcn36xx *wcn = hw->priv;
-	struct ieee80211_vif *vif = container_of((void *)wcn->current_vif,
-						 struct ieee80211_vif,
-						 drv_priv);
-
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac suspend\n");
 
-	mutex_lock(&wcn->pm_mutex);
-
-	/* Enter BMPS only in connected state */
-	if ((wcn->aid > 0) &&
-	    (wcn->pw_state != WCN36XX_BMPS) &&
-	    (NL80211_IFTYPE_STATION == vif->type))
-		wcn36xx_pmc_enter_bmps_state(wcn, vif->bss_conf.sync_tsf);
-
-	wcn->is_suspended = true;
-	wcn->is_con_lost_pending = false;
-
-	mutex_unlock(&wcn->pm_mutex);
-
+	flush_workqueue(wcn->hal_ind_wq);
 	return 0;
 }
 
 static int wcn36xx_resume(struct ieee80211_hw *hw)
 {
 	struct wcn36xx *wcn = hw->priv;
-	struct ieee80211_vif *vif = container_of((void *)wcn->current_vif,
-						 struct ieee80211_vif,
-						 drv_priv);
 
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac resume\n");
 
-	wcn->is_suspended = false;
-
-	if (wcn->pw_state == WCN36XX_BMPS)
-		wcn36xx_pmc_exit_bmps_state(wcn);
-
-	if (wcn->is_con_lost_pending) {
-		wcn36xx_dbg(WCN36XX_DBG_MAC, "report connection lost\n");
-		ieee80211_connection_loss(vif);
-	}
-
+	flush_workqueue(wcn->hal_ind_wq);
 	return 0;
 }
 
@@ -946,7 +931,6 @@ static int wcn36xx_probe(struct platform_device *pdev)
 	wcn->dev = &pdev->dev;
 	wcn->ctrl_ops = pdev->dev.platform_data;
 
-	mutex_init(&wcn->pm_mutex);
 	mutex_init(&wcn->hal_mutex);
 
 	/* Configuring supported rates */
@@ -986,7 +970,6 @@ static int wcn36xx_remove(struct platform_device *pdev)
 	struct wcn36xx *wcn = hw->priv;
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "platform remove\n");
 
-	mutex_destroy(&wcn->pm_mutex);
 	mutex_destroy(&wcn->hal_mutex);
 
 	ieee80211_unregister_hw(hw);
diff --git a/pmc.c b/pmc.c
index f72096e..beffe8b 100644
--- a/pmc.c
+++ b/pmc.c
@@ -24,23 +24,42 @@ int wcn36xx_pmc_init(struct wcn36xx *wcn)
 	return 0;
 }
 
-int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn, u64 tsf)
+int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn,
+				 struct ieee80211_vif *vif)
 {
+	int ret = 0;
 	/* TODO: Make sure the TX chain clean */
-	wcn36xx_smd_enter_bmps(wcn, tsf);
-	wcn->pw_state = WCN36XX_BMPS;
-	return 0;
+	ret = wcn36xx_smd_enter_bmps(wcn, vif);
+	if (!ret) {
+		wcn36xx_dbg(WCN36XX_DBG_PMC, "Entered BMPS\n");
+		wcn->pw_state = WCN36XX_BMPS;
+	} else {
+		/*
+		 * One of the reasons why HW will not enter BMPS is because
+		 * driver is trying to enter bmps before first beacon was
+		 * received just after auth complete
+		 */
+		wcn36xx_err("Can not enter BMPS!\n");
+	}
+	return ret;
 }
 
-int wcn36xx_pmc_exit_bmps_state(struct wcn36xx *wcn)
+int wcn36xx_pmc_exit_bmps_state(struct wcn36xx *wcn,
+				struct ieee80211_vif *vif)
 {
-	wcn36xx_smd_exit_bmps(wcn);
+	if (WCN36XX_BMPS != wcn->pw_state) {
+		wcn36xx_err("Not in BMPS mode, no need to exit from BMPS mode!\n");
+		return -EINVAL;
+	}
+	wcn36xx_smd_exit_bmps(wcn, vif);
 	wcn->pw_state = WCN36XX_FULL_POWER;
 	return 0;
 }
 
-int wcn36xx_enable_keep_alive_null_packet(struct wcn36xx *wcn)
+int wcn36xx_enable_keep_alive_null_packet(struct wcn36xx *wcn,
+					  struct ieee80211_vif *vif)
 {
 	wcn36xx_dbg(WCN36XX_DBG_PMC, "%s\n", __func__);
-	return wcn36xx_smd_keep_alive_req(wcn, WCN36XX_HAL_KEEP_ALIVE_NULL_PKT);
+	return wcn36xx_smd_keep_alive_req(wcn, vif,
+					  WCN36XX_HAL_KEEP_ALIVE_NULL_PKT);
 }
diff --git a/pmc.h b/pmc.h
index b00d425..1f743a9 100644
--- a/pmc.h
+++ b/pmc.h
@@ -25,8 +25,10 @@ enum wcn36xx_power_state {
 };
 
 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);
-int wcn36xx_enable_keep_alive_null_packet(struct wcn36xx *wcn);
+int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn,
+				 struct ieee80211_vif *vif);
+int wcn36xx_pmc_exit_bmps_state(struct wcn36xx *wcn,
+				struct ieee80211_vif *vif);
+int wcn36xx_enable_keep_alive_null_packet(struct wcn36xx *wcn,
+					  struct ieee80211_vif *vif);
 #endif	/* _WCN36XX_PMC_H_ */
diff --git a/smd.c b/smd.c
index 9ebe859..7fdc001 100644
--- a/smd.c
+++ b/smd.c
@@ -1481,16 +1481,17 @@ out:
 	return ret;
 }
 
-int wcn36xx_smd_enter_bmps(struct wcn36xx *wcn, u64 tbtt)
+int wcn36xx_smd_enter_bmps(struct wcn36xx *wcn, struct ieee80211_vif *vif)
 {
 	struct wcn36xx_hal_enter_bmps_req_msg msg_body;
+	struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv;
 	int ret = 0;
 
 	mutex_lock(&wcn->hal_mutex);
 	INIT_HAL_MSG(msg_body, WCN36XX_HAL_ENTER_BMPS_REQ);
 
-	msg_body.bss_index = wcn->current_vif->bss_index;
-	msg_body.tbtt = tbtt;
+	msg_body.bss_index = vif_priv->bss_index;
+	msg_body.tbtt = vif->bss_conf.sync_tsf;
 	msg_body.dtim_period = wcn->dtim_period;
 
 	PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
@@ -1510,15 +1511,16 @@ out:
 	return ret;
 }
 
-int wcn36xx_smd_exit_bmps(struct wcn36xx *wcn)
+int wcn36xx_smd_exit_bmps(struct wcn36xx *wcn, struct ieee80211_vif *vif)
 {
 	struct wcn36xx_hal_enter_bmps_req_msg msg_body;
+	struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv;
 	int ret = 0;
 
 	mutex_lock(&wcn->hal_mutex);
 	INIT_HAL_MSG(msg_body, WCN36XX_HAL_EXIT_BMPS_REQ);
 
-	msg_body.bss_index = wcn->current_vif->bss_index;
+	msg_body.bss_index = vif_priv->bss_index;
 
 	PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
 
@@ -1540,16 +1542,19 @@ out:
 /* Notice: This function should be called after associated, or else it
  * will be invalid
  */
-int wcn36xx_smd_keep_alive_req(struct wcn36xx *wcn, int packet_type)
+int wcn36xx_smd_keep_alive_req(struct wcn36xx *wcn,
+			       struct ieee80211_vif *vif,
+			       int packet_type)
 {
 	struct wcn36xx_hal_keep_alive_req_msg msg_body;
+	struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv;
 	int ret = 0;
 
 	mutex_lock(&wcn->hal_mutex);
 	INIT_HAL_MSG(msg_body, WCN36XX_HAL_KEEP_ALIVE_REQ);
 
 	if (packet_type == WCN36XX_HAL_KEEP_ALIVE_NULL_PKT) {
-		msg_body.bss_index = wcn->current_vif->bss_index;
+		msg_body.bss_index = vif_priv->bss_index;
 		msg_body.packet_type = WCN36XX_HAL_KEEP_ALIVE_NULL_PKT;
 		msg_body.time_period = WCN36XX_KEEP_ALIVE_TIME_PERIOD;
 	} else if (packet_type == WCN36XX_HAL_KEEP_ALIVE_UNSOLICIT_ARP_RSP) {
diff --git a/smd.h b/smd.h
index a58f4c4..df1a021 100644
--- a/smd.h
+++ b/smd.h
@@ -98,9 +98,11 @@ int wcn36xx_smd_remove_stakey(struct wcn36xx *wcn,
 int wcn36xx_smd_remove_bsskey(struct wcn36xx *wcn,
 			      enum ani_ed_type enc_type,
 			      u8 keyidx);
-int wcn36xx_smd_enter_bmps(struct wcn36xx *wcn, u64 tbtt);
-int wcn36xx_smd_exit_bmps(struct wcn36xx *wcn);
-int wcn36xx_smd_keep_alive_req(struct wcn36xx *wcn, int packet_type);
+int wcn36xx_smd_enter_bmps(struct wcn36xx *wcn, struct ieee80211_vif *vif);
+int wcn36xx_smd_exit_bmps(struct wcn36xx *wcn, struct ieee80211_vif *vif);
+int wcn36xx_smd_keep_alive_req(struct wcn36xx *wcn,
+			       struct ieee80211_vif *vif,
+			       int packet_type);
 int wcn36xx_smd_dump_cmd_req(struct wcn36xx *wcn, u32 arg1, u32 arg2,
 			     u32 arg3, u32 arg4, u32 arg5);
 int wcn36xx_smd_feature_caps_exchange(struct wcn36xx *wcn);
diff --git a/wcn36xx.h b/wcn36xx.h
index aac9d6a..242edb6 100644
--- a/wcn36xx.h
+++ b/wcn36xx.h
@@ -166,11 +166,6 @@ struct wcn36xx {
 	u8			dtim_period;
 	enum ani_ed_type	encrypt_type;
 
-	/* WoW related*/
-	struct mutex		pm_mutex;
-	bool			is_suspended;
-	bool			is_con_lost_pending;
-
 	u8			fw_revision;
 	u8			fw_version;
 	u8			fw_minor;
-- 
1.8.2.2




More information about the wcn36xx mailing list