summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2011-08-14 13:17:38 +0300
committerLuciano Coelho <coelho@ti.com>2011-08-22 12:35:31 +0300
commit04216da393e1f6653cc99a58f2fa48d0dde417c0 (patch)
tree42babcab10cc08aa349f7c1109014623339c7372 /drivers/net/wireless
parentcf42039f33c8c7c12f19390661eb00ba47b96f91 (diff)
wl12xx: AP-mode - prevent Tx to stale/invalid stations
Don't pollute the queues with Tx directed to invalid stations. This can happen during recovery. Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/wl12xx/main.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index a23b394291f..b06ff0b25de 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -779,7 +779,13 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_pkts)
bool wl1271_is_active_sta(struct wl1271 *wl, u8 hlid)
{
- int id = hlid - WL1271_AP_STA_HLID_START;
+ int id;
+
+ /* global/broadcast "stations" are always active */
+ if (hlid < WL1271_AP_STA_HLID_START)
+ return true;
+
+ id = hlid - WL1271_AP_STA_HLID_START;
return test_bit(id, wl->ap_hlid_map);
}
@@ -1493,6 +1499,13 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
/* queue the packet */
if (wl->bss_type == BSS_TYPE_AP_BSS) {
+ if (!wl1271_is_active_sta(wl, hlid)) {
+ wl1271_debug(DEBUG_TX, "DROP skb hlid %d q %d",
+ hlid, q);
+ dev_kfree_skb(skb);
+ goto out;
+ }
+
wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q);
skb_queue_tail(&wl->links[hlid].tx_queue[q], skb);
} else {
@@ -1508,6 +1521,7 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
!test_bit(WL1271_FLAG_TX_PENDING, &wl->flags))
ieee80211_queue_work(wl->hw, &wl->tx_work);
+out:
spin_unlock_irqrestore(&wl->wl_lock, flags);
}
@@ -3695,7 +3709,7 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
}
wl_sta = (struct wl1271_station *)sta->drv_priv;
- __set_bit(id, wl->ap_hlid_map);
+ set_bit(id, wl->ap_hlid_map);
wl_sta->hlid = WL1271_AP_STA_HLID_START + id;
*hlid = wl_sta->hlid;
memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN);
@@ -3709,7 +3723,7 @@ static void wl1271_free_sta(struct wl1271 *wl, u8 hlid)
if (WARN_ON(!test_bit(id, wl->ap_hlid_map)))
return;
- __clear_bit(id, wl->ap_hlid_map);
+ clear_bit(id, wl->ap_hlid_map);
memset(wl->links[hlid].addr, 0, ETH_ALEN);
wl->links[hlid].ba_bitmap = 0;
wl1271_tx_reset_link_queues(wl, hlid);