From 1c3652a5732879263aeebe606ca7af9e66fe0b2f Mon Sep 17 00:00:00 2001
From: Vivek Natarajan <vnatarajan@atheros.com>
Date: Mon, 5 Apr 2010 14:48:06 +0530
Subject: [PATCH] ath9k_htc: Configure the beacon timers once the scan is
 completed.

Signed-off-by: Vivek Natarajan <vnatarajan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
 drivers/net/wireless/ath/ath9k/htc.h          | 12 +++++-
 .../net/wireless/ath/ath9k/htc_drv_beacon.c   | 41 +++++++++++++------
 drivers/net/wireless/ath/ath9k/htc_drv_main.c |  6 ++-
 3 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 0160e83f8fb6..78213fc71b09 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -309,6 +309,14 @@ struct ath_led {
 	int brightness;
 };
 
+struct htc_beacon_config {
+	u16 beacon_interval;
+	u16 listen_interval;
+	u16 dtim_period;
+	u16 bmiss_timeout;
+	u8 dtim_count;
+};
+
 #define OP_INVALID        BIT(0)
 #define OP_SCANNING       BIT(1)
 #define OP_FULL_RESET     BIT(2)
@@ -353,6 +361,7 @@ struct ath9k_htc_priv {
 	spinlock_t tx_lock;
 
 	struct ieee80211_vif *vif;
+	struct htc_beacon_config cur_beacon_conf;
 	unsigned int rxfilter;
 	struct tasklet_struct wmi_tasklet;
 	struct tasklet_struct rx_tasklet;
@@ -394,8 +403,7 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
 }
 
 void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
-			     struct ieee80211_vif *vif,
-			     struct ieee80211_bss_conf *bss_conf);
+			     struct ieee80211_vif *vif);
 void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending);
 void ath9k_htc_beacon_update(struct ath9k_htc_priv *priv,
 			     struct ieee80211_vif *vif);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index 25f5b5377bac..5e21f4d92ff5 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -19,7 +19,7 @@
 #define FUDGE 2
 
 static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
-					struct ieee80211_bss_conf *bss_conf)
+					struct htc_beacon_config *bss_conf)
 {
 	struct ath_common *common = ath9k_hw_common(priv->ah);
 	struct ath9k_beacon_state bs;
@@ -34,8 +34,8 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
 
 	memset(&bs, 0, sizeof(bs));
 
-	intval = bss_conf->beacon_int & ATH9K_BEACON_PERIOD;
-	bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_int);
+	intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
+	bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_interval);
 
 	/*
 	 * Setup dtim and cfp parameters according to
@@ -138,7 +138,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
 }
 
 static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
-					  struct ieee80211_bss_conf *bss_conf)
+					  struct htc_beacon_config *bss_conf)
 {
 	struct ath_common *common = ath9k_hw_common(priv->ah);
 	enum ath9k_int imask = 0;
@@ -146,7 +146,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
 	int ret;
 	u8 cmd_rsp;
 
-	intval = bss_conf->beacon_int & ATH9K_BEACON_PERIOD;
+	intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
 	nexttbtt = intval;
 	intval |= ATH9K_BEACON_ENA;
 	if (priv->op_flags & OP_ENABLE_BEACON)
@@ -154,7 +154,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
 
 	ath_print(common, ATH_DBG_BEACON,
 		  "IBSS Beacon config, intval: %d, imask: 0x%x\n",
-		  bss_conf->beacon_int, imask);
+		  bss_conf->beacon_interval, imask);
 
 	WMI_CMD(WMI_DISABLE_INTR_CMDID);
 	ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
@@ -239,18 +239,35 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending)
 	spin_unlock_bh(&priv->beacon_lock);
 }
 
+
 void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
-			     struct ieee80211_vif *vif,
-			     struct ieee80211_bss_conf *bss_conf)
+			     struct ieee80211_vif *vif)
 {
 	struct ath_common *common = ath9k_hw_common(priv->ah);
-
-	switch (vif->type) {
+	enum nl80211_iftype iftype;
+	struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
+
+	if (vif) {
+		struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+		iftype = vif->type;
+		cur_conf->beacon_interval = bss_conf->beacon_int;
+		cur_conf->dtim_period = bss_conf->dtim_period;
+		cur_conf->listen_interval = 1;
+		cur_conf->dtim_count = 1;
+		cur_conf->bmiss_timeout =
+			ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
+	} else
+		iftype = priv->ah->opmode;
+
+	if (cur_conf->beacon_interval == 0)
+		cur_conf->beacon_interval = 100;
+
+	switch (iftype) {
 	case NL80211_IFTYPE_STATION:
-		ath9k_htc_beacon_config_sta(priv, bss_conf);
+		ath9k_htc_beacon_config_sta(priv, cur_conf);
 		break;
 	case NL80211_IFTYPE_ADHOC:
-		ath9k_htc_beacon_config_adhoc(priv, bss_conf);
+		ath9k_htc_beacon_config_adhoc(priv, cur_conf);
 		break;
 	default:
 		ath_print(common, ATH_DBG_CONFIG,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index e04452f888e0..eb7722b2cfcc 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1549,7 +1549,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
 	    ((changed & BSS_CHANGED_BEACON_ENABLED) &&
 	    bss_conf->enable_beacon)) {
 		priv->op_flags |= OP_ENABLE_BEACON;
-		ath9k_htc_beacon_config(priv, vif, bss_conf);
+		ath9k_htc_beacon_config(priv, vif);
 	}
 
 	if (changed & BSS_CHANGED_BEACON)
@@ -1558,7 +1558,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
 	if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
 	    !bss_conf->enable_beacon) {
 		priv->op_flags &= ~OP_ENABLE_BEACON;
-		ath9k_htc_beacon_config(priv, vif, bss_conf);
+		ath9k_htc_beacon_config(priv, vif);
 	}
 
 	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
@@ -1686,6 +1686,8 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
 	priv->op_flags &= ~OP_SCANNING;
 	spin_unlock_bh(&priv->beacon_lock);
 	priv->op_flags |= OP_FULL_RESET;
+	if (priv->op_flags & OP_ASSOCIATED)
+		ath9k_htc_beacon_config(priv, NULL);
 	ath_start_ani(priv);
 	mutex_unlock(&priv->mutex);
 	ath9k_htc_ps_restore(priv);
-- 
GitLab