aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
diff options
context:
space:
mode:
authorSujith Manoharan <Sujith.Manoharan@atheros.com>2011-04-13 01:53:34 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-13 15:22:26 -0400
commit7d547eb4bb664c5a6b7c8790c2ecb0aec5d15385 (patch)
tree3a4b7627fa9c6e0e98b0948723eb2458c83e2f5f /drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
parent2493a547ee81e6daca812d5dd7cf9357aebc379b (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.c43
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
275static 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
275static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, 317static 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