Skip to content

Commit

Permalink
wl2xx: AP-mode - prevent Tx to stale/invalid stations
Browse files Browse the repository at this point in the history
Don't pollute the queues with Tx directed to invalid stations. This
can happen during recovery.
  • Loading branch information
ariknem committed Jul 5, 2011
1 parent 5cfd587 commit 2c2caa9
Showing 1 changed file with 17 additions and 3 deletions.
20 changes: 17 additions & 3 deletions drivers/net/wireless/wl12xx/main.c
Expand Up @@ -790,7 +790,13 @@ static void wl1271_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);
}

Expand Down Expand Up @@ -1512,6 +1518,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 {
Expand All @@ -1527,6 +1540,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);
}

Expand Down Expand Up @@ -3751,7 +3765,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);
Expand All @@ -3765,7 +3779,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);
wl1271_tx_reset_link_queues(wl, hlid);
__clear_bit(hlid, &wl->ap_ps_map);
Expand Down

0 comments on commit 2c2caa9

Please sign in to comment.