[PATCH 5/5] Introduce cached beacon.

Max Filippov jcmvbkbc at gmail.com
Fri Jan 9 17:17:44 EET 2009


Introduce cached beacon.
Submit beacon on op_config_interface.
Add function to cancel frame TX.

Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
---
 stlc45xx.c |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 stlc45xx.h |    2 +
 2 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/stlc45xx.c b/stlc45xx.c
index 1105b8a..c7668ec 100644
--- a/stlc45xx.c
+++ b/stlc45xx.c
@@ -991,6 +991,8 @@ static void stlc45xx_flush_queues(struct stlc45xx *stlc)
 		stlc45xx_txbuffer_free(stlc, entry);
 	}
 
+	stlc->cached_beacon = NULL;
+
 	WARN_ON(!list_empty(&stlc->tx_sent));
 
 	while (!list_empty(&stlc->tx_pending)) {
@@ -1196,6 +1198,9 @@ static int stlc45xx_rx_txack(struct stlc45xx *stlc, struct sk_buff *skb)
 
 	list_del(&entry->tx_list);
 
+	if (entry == stlc->cached_beacon)
+		stlc->cached_beacon = NULL;
+
 	if (0 == stlc45xx_check_txsent(stlc))
 		/* there are no pending frames with limited lifetime,
 		 * we can stop the tx timeout timer */
@@ -2020,6 +2025,52 @@ static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable)
 	kfree(control);
 }
 
+static int stlc45xx_tx_cancel(struct stlc45xx *stlc,
+	struct txbuffer *entry)
+{
+	struct s_lm_control *control;
+	struct s_lmo_txcancel *txc;
+	size_t len;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	len = sizeof(*control) + sizeof(*txc);
+	control = kzalloc(len, GFP_KERNEL);
+	txc = (struct s_lmo_txcancel *) (control + 1);
+
+	control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
+	control->length = sizeof(*txc);
+	control->oid = LM_OID_TXCANCEL;
+
+	txc->address[0] = entry->start;
+
+	stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
+
+	kfree(control);
+	return 0;
+}
+
+static int stlc45xx_tx_beacon(struct ieee80211_hw *hw,
+					struct ieee80211_vif *vif)
+{
+	struct stlc45xx *stlc = hw->priv;
+	struct sk_buff *beacon;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	if (stlc->cached_beacon) {
+		stlc45xx_tx_cancel(stlc, stlc->cached_beacon);
+		msleep(10);
+	}
+
+	beacon = ieee80211_beacon_get(hw, vif);
+	if (!beacon)
+		return -ENOMEM;
+
+	return stlc45xx_alloc_and_tx_frame(stlc, beacon, &stlc->cached_beacon,
+		/*LM_OUT_TIMESTAMP*/0, LM_QUEUE_BEACON, false);
+}
+
 static void stlc45xx_tx_set_flags(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
 		struct s_lm_data_out *data)
 {
@@ -2264,8 +2315,17 @@ static int stlc45xx_op_config_interface(struct ieee80211_hw *hw,
 
 	mutex_lock(&stlc->mutex);
 
-	memcpy(stlc->bssid, conf->bssid, ETH_ALEN);
-	stlc45xx_tx_setup(stlc);
+	if (conf->changed & IEEE80211_IFCC_BSSID) {
+		memcpy(stlc->bssid, conf->bssid, ETH_ALEN);
+		stlc45xx_tx_setup(stlc);
+	}
+
+	if (conf->changed & IEEE80211_IFCC_BEACON) {
+		stlc45xx_debug(DEBUG_FUNC, "BEACON!");
+		stlc45xx_tx_scan(stlc);
+		stlc45xx_tx_beacon(hw,vif);
+		stlc45xx_tx_edcf(stlc);
+	}
 
 	mutex_unlock(&stlc->mutex);
 
diff --git a/stlc45xx.h b/stlc45xx.h
index acc0558..b56db3f 100644
--- a/stlc45xx.h
+++ b/stlc45xx.h
@@ -280,6 +280,8 @@ struct stlc45xx {
 	bool associated;
 	int aid;
 	bool pspolling;
+
+	struct txbuffer *cached_beacon;
 };
 
 
-- 
1.5.4.3


More information about the stlc45xx-devel mailing list