[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