[PATCH 3/3] Add missed beacon support

Eugene Krasnikov k.eugene.e at gmail.com
Tue Jul 2 08:11:10 EDT 2013


In BMPS mode if FW lost connection to AP it will report
WCN36XX_HAL_MISSED_BEACON_IND. Notify mac8021 about connection
lost in this case.

Signed-off-by: Eugene Krasnikov <k.eugene.e at gmail.com>
---
 hal.h     |  2 +-
 main.c    | 17 +++++++++++++++++
 smd.c     | 28 ++++++++++++++++++++++++++++
 wcn36xx.h |  6 ++++++
 4 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/hal.h b/hal.h
index 122e077..83b9f49 100644
--- a/hal.h
+++ b/hal.h
@@ -2956,7 +2956,7 @@ struct wcn36xx_hal_missed_beacon_ind_msg {
 	struct wcn36xx_hal_msg_header header;
 
 	u8 bss_index;
-};
+} __packed;
 
 /* Beacon Filtering data structures */
 
diff --git a/main.c b/main.c
index cf0d270..0cc3e02 100644
--- a/main.c
+++ b/main.c
@@ -725,22 +725,36 @@ static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow)
 						 drv_priv);
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac suspend");
 
+	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);
+	wcn->is_suspended = true;
+	wcn->is_con_lost_pending = false;
 
 	flush_work(&wcn->rx_ready_work);
 	flush_work(&wcn->smd_work);
+	mutex_unlock(&wcn->pm_mutex);
 
 	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");
 
+	wcn->is_suspended = false;
 	if (wcn->aid > 0)
 		wcn36xx_smd_exit_bmps(wcn);
+
+	if (wcn->is_con_lost_pending) {
+		wcn36xx_dbg(WCN36XX_DBG_MAC, "report connection lost");
+		ieee80211_connection_loss(vif);
+	}
+
 	return 0;
 }
 #endif
@@ -929,6 +943,8 @@ static int __init wcn36xx_init(void)
 	wcn->aid = 0;
 	wcn->current_vif = NULL;
 	wcn->is_joining = false;
+
+	mutex_init(&wcn->pm_mutex);
 	wcn->hw->wiphy->n_addresses = ARRAY_SIZE(wcn->addresses);
 	wcn->hw->wiphy->addresses = wcn->addresses;
 
@@ -985,6 +1001,7 @@ static void __exit wcn36xx_exit(void)
 	struct ieee80211_hw *hw = private_hw;
 	struct wcn36xx *wcn = hw->priv;
 
+	mutex_destroy(&wcn->pm_mutex);
 	ieee80211_unregister_hw(hw);
 	destroy_workqueue(wcn->wq);
 	iounmap(wcn->mmio);
diff --git a/smd.c b/smd.c
index c1ab351..ce09563 100644
--- a/smd.c
+++ b/smd.c
@@ -1085,6 +1085,31 @@ static int wcn36xx_smd_tx_compl_ind(struct wcn36xx *wcn, void *buf, size_t len)
 	return 0;
 }
 
+static int wcn36xx_smd_missed_beacon_ind(struct wcn36xx *wcn,
+					 void *buf,
+					 size_t len)
+{
+	struct ieee80211_vif *vif = container_of((void *)wcn->current_vif,
+						 struct ieee80211_vif,
+						 drv_priv);
+	mutex_lock(&wcn->pm_mutex);
+	/*
+	 * In suspended state mac80211 is still sleeping and that means we
+	 * cannot notify it about connection lost. Wait until resume and
+	 * then notify mac80211 about it.
+	 */
+	if (wcn->is_suspended) {
+		wcn36xx_dbg(WCN36XX_DBG_HAL,
+		    "postpone connection lost notification");
+		wcn->is_con_lost_pending = true;
+	} else {
+		wcn36xx_dbg(WCN36XX_DBG_HAL, "beacon missed");
+		ieee80211_connection_loss(vif);
+	}
+	mutex_unlock(&wcn->pm_mutex);
+	return 0;
+}
+
 static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
 {
 	struct wcn36xx_hal_msg_header *msg_header = buf;
@@ -1138,6 +1163,9 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
 	case WCN36XX_HAL_OTA_TX_COMPL_IND:
 		wcn36xx_smd_tx_compl_ind(wcn, buf, len);
 		break;
+	case WCN36XX_HAL_MISSED_BEACON_IND:
+		wcn36xx_smd_missed_beacon_ind(wcn, buf, len);
+		break;
 	default:
 		wcn36xx_error("SMD_EVENT (%d) not supported", msg_header->msg_type);
 	}
diff --git a/wcn36xx.h b/wcn36xx.h
index fd98807..2c72349 100644
--- a/wcn36xx.h
+++ b/wcn36xx.h
@@ -113,6 +113,12 @@ struct wcn36xx {
 	u16			beacon_interval;
 	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.7.11.3




More information about the wcn36xx mailing list