diff options
author | Sujith Manoharan <Sujith.Manoharan@atheros.com> | 2011-04-13 01:53:34 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-04-13 15:22:26 -0400 |
commit | 7d547eb4bb664c5a6b7c8790c2ecb0aec5d15385 (patch) | |
tree | 3a4b7627fa9c6e0e98b0948723eb2458c83e2f5f /drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |
parent | 2493a547ee81e6daca812d5dd7cf9357aebc379b (diff) |
ath9k_htc: Handle buffered frames in AP mode
Use the CAB endpoint to send buffered multicast or
broadcast frames after each SWBA event.
Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/htc_drv_beacon.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 7aafd2179398..c96779c24296 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |||
@@ -272,6 +272,48 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, | |||
272 | dev_kfree_skb_any(skb); | 272 | dev_kfree_skb_any(skb); |
273 | } | 273 | } |
274 | 274 | ||
275 | static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, | ||
276 | int slot) | ||
277 | { | ||
278 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
279 | struct ieee80211_vif *vif; | ||
280 | struct sk_buff *skb; | ||
281 | struct ieee80211_hdr *hdr; | ||
282 | int padpos, padsize, ret; | ||
283 | |||
284 | spin_lock_bh(&priv->beacon_lock); | ||
285 | |||
286 | vif = priv->cur_beacon_conf.bslot[slot]; | ||
287 | |||
288 | skb = ieee80211_get_buffered_bc(priv->hw, vif); | ||
289 | |||
290 | while(skb) { | ||
291 | hdr = (struct ieee80211_hdr *) skb->data; | ||
292 | |||
293 | padpos = ath9k_cmn_padpos(hdr->frame_control); | ||
294 | padsize = padpos & 3; | ||
295 | if (padsize && skb->len > padpos) { | ||
296 | if (skb_headroom(skb) < padsize) { | ||
297 | dev_kfree_skb_any(skb); | ||
298 | goto next; | ||
299 | } | ||
300 | skb_push(skb, padsize); | ||
301 | memmove(skb->data, skb->data + padsize, padpos); | ||
302 | } | ||
303 | |||
304 | ret = ath9k_htc_tx_start(priv, skb, true); | ||
305 | if (ret != 0) { | ||
306 | ath_dbg(common, ATH_DBG_FATAL, | ||
307 | "Failed to send CAB frame\n"); | ||
308 | dev_kfree_skb_any(skb); | ||
309 | } | ||
310 | next: | ||
311 | skb = ieee80211_get_buffered_bc(priv->hw, vif); | ||
312 | } | ||
313 | |||
314 | spin_unlock_bh(&priv->beacon_lock); | ||
315 | } | ||
316 | |||
275 | static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, | 317 | static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, |
276 | int slot) | 318 | int slot) |
277 | { | 319 | { |
@@ -390,6 +432,7 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv) | |||
390 | } | 432 | } |
391 | spin_unlock_bh(&priv->beacon_lock); | 433 | spin_unlock_bh(&priv->beacon_lock); |
392 | 434 | ||
435 | ath9k_htc_send_buffered(priv, slot); | ||
393 | ath9k_htc_send_beacon(priv, slot); | 436 | ath9k_htc_send_beacon(priv, slot); |
394 | } | 437 | } |
395 | 438 | ||