summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/hostap/hostap_ap.c
diff options
context:
space:
mode:
authorJouni Malinen <jkmaline@cc.hut.fi>2005-08-14 19:08:39 -0700
committerJeff Garzik <jgarzik@pobox.com>2005-08-14 23:06:26 -0400
commit5bee720fd7fa5ed4eade96058acd3a684da30932 (patch)
tree916d3c4c880c64ba13edc4f890fa3b021be4ded8 /drivers/net/wireless/hostap/hostap_ap.c
parent1e4adbdb3f0348dcf4fce92f1acc7c8386982c17 (diff)
downloadlwn-5bee720fd7fa5ed4eade96058acd3a684da30932.tar.gz
lwn-5bee720fd7fa5ed4eade96058acd3a684da30932.zip
[PATCH] hostap: Fix skb->cb use for TX meta data
Old AP mode code for power saving was using skb->cb for couple of flags before the more generic 802.11 TX code started using the same buffer for struct hostap_skb_tx_data. This resulted in the power save code corrupting the magic value in beginning of the buffer and TX code dropping the power saved packets because of this for the case where STAs send PS-Poll frames with PwrMgmt flag set. This patch modifies the power save code to use the same struct hostap_skb_tx_data as rest of the TX path in order to avoid corrupting the data in skb->cb. In addition, this patch reorders fields in the structure and makes them use smaller types in order to make the structure fit in skb->cb on 64-bit hosts. Signed-off-by: Jouni Malinen <jkmaline@cc.hut.fi> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/wireless/hostap/hostap_ap.c')
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c30
1 files changed, 15 insertions, 15 deletions
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index c9aeefcd7612..550855a91509 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -1840,6 +1840,8 @@ static void ap_handle_dropped_data(local_info_t *local,
static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
struct sk_buff *skb)
{
+ struct hostap_skb_tx_data *meta;
+
if (!(sta->flags & WLAN_STA_PS)) {
/* Station has moved to non-PS mode, so send all buffered
* frames using normal device queue. */
@@ -1849,11 +1851,11 @@ static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
/* add a flag for hostap_handle_sta_tx() to know that this skb should
* be passed through even though STA is using PS */
- memcpy(skb->cb, AP_SKB_CB_MAGIC, AP_SKB_CB_MAGIC_LEN);
- skb->cb[AP_SKB_CB_MAGIC_LEN] = AP_SKB_CB_BUFFERED_FRAME;
+ meta = (struct hostap_skb_tx_data *) skb->cb;
+ meta->flags |= HOSTAP_TX_FLAGS_BUFFERED_FRAME;
if (!skb_queue_empty(&sta->tx_buf)) {
/* indicate to STA that more frames follow */
- skb->cb[AP_SKB_CB_MAGIC_LEN] |= AP_SKB_CB_ADD_MOREDATA;
+ meta->flags |= HOSTAP_TX_FLAGS_ADD_MOREDATA;
}
dev_queue_xmit(skb);
}
@@ -2707,7 +2709,8 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
atomic_inc(&sta->users);
spin_unlock(&local->ap->sta_table_lock);
- if (local->iw_mode == IW_MODE_MASTER && sta == NULL && !meta->wds &&
+ if (local->iw_mode == IW_MODE_MASTER && sta == NULL &&
+ !(meta->flags & HOSTAP_TX_FLAGS_WDS) &&
meta->iface->type != HOSTAP_INTERFACE_MASTER &&
meta->iface->type != HOSTAP_INTERFACE_AP) {
#if 0
@@ -2743,18 +2746,15 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
if (!(sta->flags & WLAN_STA_PS))
goto out;
- if (memcmp(skb->cb, AP_SKB_CB_MAGIC, AP_SKB_CB_MAGIC_LEN) == 0) {
- if (skb->cb[AP_SKB_CB_MAGIC_LEN] & AP_SKB_CB_ADD_MOREDATA) {
- /* indicate to STA that more frames follow */
- hdr->frame_control |=
- __constant_cpu_to_le16(WLAN_FC_MOREDATA);
- }
+ if (meta->flags & HOSTAP_TX_FLAGS_ADD_MOREDATA) {
+ /* indicate to STA that more frames follow */
+ hdr->frame_control |= __constant_cpu_to_le16(WLAN_FC_MOREDATA);
+ }
- if (skb->cb[AP_SKB_CB_MAGIC_LEN] & AP_SKB_CB_BUFFERED_FRAME) {
- /* packet was already buffered and now send due to
- * PS poll, so do not rebuffer it */
- goto out;
- }
+ if (meta->flags & HOSTAP_TX_FLAGS_BUFFERED_FRAME) {
+ /* packet was already buffered and now send due to
+ * PS poll, so do not rebuffer it */
+ goto out;
}
if (skb_queue_len(&sta->tx_buf) >= STA_MAX_TX_BUFFER) {