aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/xmit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/xmit.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c111
1 files changed, 96 insertions, 15 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 3cea3f76e373..e9e99f730ca8 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -357,6 +357,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
357 struct ath_frame_info *fi; 357 struct ath_frame_info *fi;
358 int nframes; 358 int nframes;
359 u8 tidno; 359 u8 tidno;
360 bool clear_filter;
360 361
361 skb = bf->bf_mpdu; 362 skb = bf->bf_mpdu;
362 hdr = (struct ieee80211_hdr *)skb->data; 363 hdr = (struct ieee80211_hdr *)skb->data;
@@ -441,22 +442,24 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
441 /* transmit completion */ 442 /* transmit completion */
442 acked_cnt++; 443 acked_cnt++;
443 } else { 444 } else {
444 if (!(tid->state & AGGR_CLEANUP) && retry) { 445 if ((tid->state & AGGR_CLEANUP) || !retry) {
445 if (fi->retries < ATH_MAX_SW_RETRIES) {
446 ath_tx_set_retry(sc, txq, bf->bf_mpdu);
447 txpending = 1;
448 } else {
449 bf->bf_state.bf_type |= BUF_XRETRY;
450 txfail = 1;
451 sendbar = 1;
452 txfail_cnt++;
453 }
454 } else {
455 /* 446 /*
456 * cleanup in progress, just fail 447 * cleanup in progress, just fail
457 * the un-acked sub-frames 448 * the un-acked sub-frames
458 */ 449 */
459 txfail = 1; 450 txfail = 1;
451 } else if (fi->retries < ATH_MAX_SW_RETRIES) {
452 if (!(ts->ts_status & ATH9K_TXERR_FILT) ||
453 !an->sleeping)
454 ath_tx_set_retry(sc, txq, bf->bf_mpdu);
455
456 clear_filter = true;
457 txpending = 1;
458 } else {
459 bf->bf_state.bf_type |= BUF_XRETRY;
460 txfail = 1;
461 sendbar = 1;
462 txfail_cnt++;
460 } 463 }
461 } 464 }
462 465
@@ -496,6 +499,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
496 !txfail, sendbar); 499 !txfail, sendbar);
497 } else { 500 } else {
498 /* retry the un-acked ones */ 501 /* retry the un-acked ones */
502 ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false);
499 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { 503 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) {
500 if (bf->bf_next == NULL && bf_last->bf_stale) { 504 if (bf->bf_next == NULL && bf_last->bf_stale) {
501 struct ath_buf *tbf; 505 struct ath_buf *tbf;
@@ -546,7 +550,12 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
546 550
547 /* prepend un-acked frames to the beginning of the pending frame queue */ 551 /* prepend un-acked frames to the beginning of the pending frame queue */
548 if (!list_empty(&bf_pending)) { 552 if (!list_empty(&bf_pending)) {
553 if (an->sleeping)
554 ieee80211_sta_set_tim(sta);
555
549 spin_lock_bh(&txq->axq_lock); 556 spin_lock_bh(&txq->axq_lock);
557 if (clear_filter)
558 tid->ac->clear_ps_filter = true;
550 list_splice(&bf_pending, &tid->buf_q); 559 list_splice(&bf_pending, &tid->buf_q);
551 ath_tx_queue_tid(txq, tid); 560 ath_tx_queue_tid(txq, tid);
552 spin_unlock_bh(&txq->axq_lock); 561 spin_unlock_bh(&txq->axq_lock);
@@ -816,6 +825,11 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
816 bf = list_first_entry(&bf_q, struct ath_buf, list); 825 bf = list_first_entry(&bf_q, struct ath_buf, list);
817 bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); 826 bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
818 827
828 if (tid->ac->clear_ps_filter) {
829 tid->ac->clear_ps_filter = false;
830 ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true);
831 }
832
819 /* if only one frame, send as non-aggregate */ 833 /* if only one frame, send as non-aggregate */
820 if (bf == bf->bf_lastbf) { 834 if (bf == bf->bf_lastbf) {
821 fi = get_frame_info(bf->bf_mpdu); 835 fi = get_frame_info(bf->bf_mpdu);
@@ -896,6 +910,67 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
896 ath_tx_flush_tid(sc, txtid); 910 ath_tx_flush_tid(sc, txtid);
897} 911}
898 912
913bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an)
914{
915 struct ath_atx_tid *tid;
916 struct ath_atx_ac *ac;
917 struct ath_txq *txq;
918 bool buffered = false;
919 int tidno;
920
921 for (tidno = 0, tid = &an->tid[tidno];
922 tidno < WME_NUM_TID; tidno++, tid++) {
923
924 if (!tid->sched)
925 continue;
926
927 ac = tid->ac;
928 txq = ac->txq;
929
930 spin_lock_bh(&txq->axq_lock);
931
932 if (!list_empty(&tid->buf_q))
933 buffered = true;
934
935 tid->sched = false;
936 list_del(&tid->list);
937
938 if (ac->sched) {
939 ac->sched = false;
940 list_del(&ac->list);
941 }
942
943 spin_unlock_bh(&txq->axq_lock);
944 }
945
946 return buffered;
947}
948
949void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
950{
951 struct ath_atx_tid *tid;
952 struct ath_atx_ac *ac;
953 struct ath_txq *txq;
954 int tidno;
955
956 for (tidno = 0, tid = &an->tid[tidno];
957 tidno < WME_NUM_TID; tidno++, tid++) {
958
959 ac = tid->ac;
960 txq = ac->txq;
961
962 spin_lock_bh(&txq->axq_lock);
963 ac->clear_ps_filter = true;
964
965 if (!list_empty(&tid->buf_q) && !tid->paused) {
966 ath_tx_queue_tid(txq, tid);
967 ath_txq_schedule(sc, txq);
968 }
969
970 spin_unlock_bh(&txq->axq_lock);
971 }
972}
973
899void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) 974void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
900{ 975{
901 struct ath_atx_tid *txtid; 976 struct ath_atx_tid *txtid;
@@ -1451,7 +1526,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
1451 struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; 1526 struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
1452 struct ieee80211_hdr *hdr; 1527 struct ieee80211_hdr *hdr;
1453 struct ath_frame_info *fi = get_frame_info(skb); 1528 struct ath_frame_info *fi = get_frame_info(skb);
1454 struct ath_node *an; 1529 struct ath_node *an = NULL;
1455 struct ath_atx_tid *tid; 1530 struct ath_atx_tid *tid;
1456 enum ath9k_key_type keytype; 1531 enum ath9k_key_type keytype;
1457 u16 seqno = 0; 1532 u16 seqno = 0;
@@ -1459,11 +1534,13 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
1459 1534
1460 keytype = ath9k_cmn_get_hw_crypto_keytype(skb); 1535 keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
1461 1536
1537 if (sta)
1538 an = (struct ath_node *) sta->drv_priv;
1539
1462 hdr = (struct ieee80211_hdr *)skb->data; 1540 hdr = (struct ieee80211_hdr *)skb->data;
1463 if (sta && ieee80211_is_data_qos(hdr->frame_control) && 1541 if (an && ieee80211_is_data_qos(hdr->frame_control) &&
1464 conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) { 1542 conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) {
1465 1543
1466 an = (struct ath_node *) sta->drv_priv;
1467 tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; 1544 tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
1468 1545
1469 /* 1546 /*
@@ -1479,6 +1556,8 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
1479 memset(fi, 0, sizeof(*fi)); 1556 memset(fi, 0, sizeof(*fi));
1480 if (hw_key) 1557 if (hw_key)
1481 fi->keyix = hw_key->hw_key_idx; 1558 fi->keyix = hw_key->hw_key_idx;
1559 else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0)
1560 fi->keyix = an->ps_key;
1482 else 1561 else
1483 fi->keyix = ATH9K_TXKEYIX_INVALID; 1562 fi->keyix = ATH9K_TXKEYIX_INVALID;
1484 fi->keytype = keytype; 1563 fi->keytype = keytype;
@@ -1491,7 +1570,6 @@ static int setup_tx_flags(struct sk_buff *skb)
1491 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1570 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1492 int flags = 0; 1571 int flags = 0;
1493 1572
1494 flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
1495 flags |= ATH9K_TXDESC_INTREQ; 1573 flags |= ATH9K_TXDESC_INTREQ;
1496 1574
1497 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) 1575 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
@@ -1754,6 +1832,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
1754 if (txctl->paprd) 1832 if (txctl->paprd)
1755 bf->bf_state.bfs_paprd_timestamp = jiffies; 1833 bf->bf_state.bfs_paprd_timestamp = jiffies;
1756 1834
1835 if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
1836 ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true);
1837
1757 ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); 1838 ath_tx_send_normal(sc, txctl->txq, tid, &bf_head);
1758 } 1839 }
1759 1840