aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorSujith Manoharan <Sujith.Manoharan@atheros.com>2011-04-13 01:55:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-13 15:24:03 -0400
commitf2820f4583b233827f10d91adea70225e196d852 (patch)
tree1ed1a0c97f1960ed402c3723c258cea50916dea9 /drivers/net/wireless
parent2c5d57f004673a9c8658e20b1fa3f992b5a10f70 (diff)
ath9k_htc: Use helper functions for TX processing
Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c137
1 files changed, 73 insertions, 64 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index ee5b3e281cd3..944440c84c49 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -325,8 +325,8 @@ send:
325 return htc_send(priv->htc, skb); 325 return htc_send(priv->htc, skb);
326} 326}
327 327
328static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, 328static inline bool __ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
329 struct ath9k_htc_sta *ista, u8 tid) 329 struct ath9k_htc_sta *ista, u8 tid)
330{ 330{
331 bool ret = false; 331 bool ret = false;
332 332
@@ -338,89 +338,98 @@ static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
338 return ret; 338 return ret;
339} 339}
340 340
341void ath9k_tx_tasklet(unsigned long data) 341static void ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
342 struct ieee80211_vif *vif,
343 struct sk_buff *skb)
342{ 344{
343 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
344 struct ath9k_htc_tx_ctl *tx_ctl;
345 struct ieee80211_vif *vif;
346 struct ieee80211_sta *sta; 345 struct ieee80211_sta *sta;
347 struct ieee80211_hdr *hdr; 346 struct ieee80211_hdr *hdr;
348 struct ieee80211_tx_info *tx_info;
349 struct sk_buff *skb = NULL;
350 __le16 fc; 347 __le16 fc;
351 bool txok;
352 int slot;
353 348
354 while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { 349 hdr = (struct ieee80211_hdr *) skb->data;
350 fc = hdr->frame_control;
355 351
356 slot = strip_drv_header(priv, skb); 352 rcu_read_lock();
357 if (slot < 0) {
358 dev_kfree_skb_any(skb);
359 continue;
360 }
361 353
362 tx_ctl = HTC_SKB_CB(skb); 354 sta = ieee80211_find_sta(vif, hdr->addr1);
363 hdr = (struct ieee80211_hdr *) skb->data; 355 if (!sta) {
364 fc = hdr->frame_control; 356 rcu_read_unlock();
365 tx_info = IEEE80211_SKB_CB(skb); 357 return;
366 vif = tx_info->control.vif; 358 }
367 txok = tx_ctl->txok;
368 359
369 memset(&tx_info->status, 0, sizeof(tx_info->status)); 360 if (sta && conf_is_ht(&priv->hw->conf) &&
361 !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
362 if (ieee80211_is_data_qos(fc)) {
363 u8 *qc, tid;
364 struct ath9k_htc_sta *ista;
370 365
371 /* 366 qc = ieee80211_get_qos_ctl(hdr);
372 * URB submission failed for this frame, it never reached 367 tid = qc[0] & 0xf;
373 * the target. 368 ista = (struct ath9k_htc_sta *)sta->drv_priv;
374 */ 369 if (__ath9k_htc_check_tx_aggr(priv, ista, tid)) {
375 if (!txok) 370 ieee80211_start_tx_ba_session(sta, tid, 0);
376 goto send_mac80211; 371 spin_lock_bh(&priv->tx.tx_lock);
372 ista->tid_state[tid] = AGGR_PROGRESS;
373 spin_unlock_bh(&priv->tx.tx_lock);
374 }
375 }
376 }
377 377
378 tx_info->flags |= IEEE80211_TX_STAT_ACK; 378 rcu_read_unlock();
379}
379 380
380 if (!vif) 381static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
381 goto send_mac80211; 382 struct sk_buff *skb)
383{
384 struct ieee80211_vif *vif;
385 struct ath9k_htc_tx_ctl *tx_ctl;
386 struct ieee80211_tx_info *tx_info;
387 bool txok;
388 int slot;
382 389
383 rcu_read_lock(); 390 slot = strip_drv_header(priv, skb);
391 if (slot < 0) {
392 dev_kfree_skb_any(skb);
393 return;
394 }
384 395
385 sta = ieee80211_find_sta(vif, hdr->addr1); 396 tx_ctl = HTC_SKB_CB(skb);
386 if (!sta) { 397 txok = tx_ctl->txok;
387 rcu_read_unlock(); 398 tx_info = IEEE80211_SKB_CB(skb);
388 goto send_mac80211; 399 vif = tx_info->control.vif;
389 }
390 400
391 /* Check if we need to start aggregation */ 401 memset(&tx_info->status, 0, sizeof(tx_info->status));
392 402
393 if (sta && conf_is_ht(&priv->hw->conf) && 403 /*
394 !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { 404 * URB submission failed for this frame, it never reached
395 if (ieee80211_is_data_qos(fc)) { 405 * the target.
396 u8 *qc, tid; 406 */
397 struct ath9k_htc_sta *ista; 407 if (!txok || !vif)
408 goto send_mac80211;
398 409
399 qc = ieee80211_get_qos_ctl(hdr); 410 tx_info->flags |= IEEE80211_TX_STAT_ACK;
400 tid = qc[0] & 0xf;
401 ista = (struct ath9k_htc_sta *)sta->drv_priv;
402 411
403 if (ath9k_htc_check_tx_aggr(priv, ista, tid)) { 412 ath9k_htc_check_tx_aggr(priv, vif, skb);
404 ieee80211_start_tx_ba_session(sta, tid, 0);
405 spin_lock_bh(&priv->tx.tx_lock);
406 ista->tid_state[tid] = AGGR_PROGRESS;
407 spin_unlock_bh(&priv->tx.tx_lock);
408 }
409 }
410 }
411 413
412 rcu_read_unlock(); 414send_mac80211:
415 spin_lock_bh(&priv->tx.tx_lock);
416 if (WARN_ON(--priv->tx.queued_cnt < 0))
417 priv->tx.queued_cnt = 0;
418 spin_unlock_bh(&priv->tx.tx_lock);
413 419
414 send_mac80211: 420 ath9k_htc_tx_clear_slot(priv, slot);
415 spin_lock_bh(&priv->tx.tx_lock); 421
416 if (WARN_ON(--priv->tx.queued_cnt < 0)) 422 /* Send status to mac80211 */
417 priv->tx.queued_cnt = 0; 423 ieee80211_tx_status(priv->hw, skb);
418 spin_unlock_bh(&priv->tx.tx_lock); 424}
419 425
420 ath9k_htc_tx_clear_slot(priv, slot); 426void ath9k_tx_tasklet(unsigned long data)
427{
428 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
429 struct sk_buff *skb = NULL;
421 430
422 /* Send status to mac80211 */ 431 while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) {
423 ieee80211_tx_status(priv->hw, skb); 432 ath9k_htc_tx_process(priv, skb);
424 } 433 }
425 434
426 /* Wake TX queues if needed */ 435 /* Wake TX queues if needed */