diff options
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 91 |
2 files changed, 57 insertions, 35 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index c016a7ae056e..4eba9577386b 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -213,6 +213,7 @@ struct ath_frame_info { | |||
213 | struct ath_buf_state { | 213 | struct ath_buf_state { |
214 | u8 bf_type; | 214 | u8 bf_type; |
215 | u8 bfs_paprd; | 215 | u8 bfs_paprd; |
216 | u8 ndelim; | ||
216 | u16 seqno; | 217 | u16 seqno; |
217 | unsigned long bfs_paprd_timestamp; | 218 | unsigned long bfs_paprd_timestamp; |
218 | }; | 219 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 54049824bf69..48ac9ff01ac0 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -774,7 +774,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
774 | if (!bf) | 774 | if (!bf) |
775 | continue; | 775 | continue; |
776 | 776 | ||
777 | bf->bf_state.bf_type |= BUF_AMPDU; | 777 | bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR; |
778 | seqno = bf->bf_state.seqno; | 778 | seqno = bf->bf_state.seqno; |
779 | if (!bf_first) | 779 | if (!bf_first) |
780 | bf_first = bf; | 780 | bf_first = bf; |
@@ -824,20 +824,17 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
824 | 824 | ||
825 | nframes++; | 825 | nframes++; |
826 | bf->bf_next = NULL; | 826 | bf->bf_next = NULL; |
827 | ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0); | ||
828 | 827 | ||
829 | /* link buffers of this frame to the aggregate */ | 828 | /* link buffers of this frame to the aggregate */ |
830 | if (!fi->retries) | 829 | if (!fi->retries) |
831 | ath_tx_addto_baw(sc, tid, seqno); | 830 | ath_tx_addto_baw(sc, tid, seqno); |
832 | ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim); | 831 | bf->bf_state.ndelim = ndelim; |
833 | 832 | ||
834 | __skb_unlink(skb, &tid->buf_q); | 833 | __skb_unlink(skb, &tid->buf_q); |
835 | list_add_tail(&bf->list, bf_q); | 834 | list_add_tail(&bf->list, bf_q); |
836 | if (bf_prev) { | 835 | if (bf_prev) |
837 | bf_prev->bf_next = bf; | 836 | bf_prev->bf_next = bf; |
838 | ath9k_hw_set_desc_link(sc->sc_ah, bf_prev->bf_desc, | 837 | |
839 | bf->bf_daddr); | ||
840 | } | ||
841 | bf_prev = bf; | 838 | bf_prev = bf; |
842 | 839 | ||
843 | } while (!skb_queue_empty(&tid->buf_q)); | 840 | } while (!skb_queue_empty(&tid->buf_q)); |
@@ -848,12 +845,50 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
848 | #undef PADBYTES | 845 | #undef PADBYTES |
849 | } | 846 | } |
850 | 847 | ||
848 | static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, int len) | ||
849 | { | ||
850 | struct ath_hw *ah = sc->sc_ah; | ||
851 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); | ||
852 | struct ath_buf *bf_first = bf; | ||
853 | |||
854 | bool aggr = !!(bf->bf_state.bf_type & BUF_AGGR); | ||
855 | bool clrdmask = !!(tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT); | ||
856 | |||
857 | u32 ds_next; | ||
858 | |||
859 | ath_buf_set_rate(sc, bf, len); | ||
860 | |||
861 | while (bf) { | ||
862 | if (bf->bf_next) | ||
863 | ds_next = bf->bf_next->bf_daddr; | ||
864 | else | ||
865 | ds_next = 0; | ||
866 | |||
867 | ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, clrdmask); | ||
868 | if (!aggr) | ||
869 | ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); | ||
870 | else if (!bf->bf_next) | ||
871 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_desc); | ||
872 | else { | ||
873 | if (bf == bf_first) | ||
874 | ath9k_hw_set11n_aggr_first(sc->sc_ah, | ||
875 | bf->bf_desc, len); | ||
876 | |||
877 | ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, | ||
878 | bf->bf_state.ndelim); | ||
879 | } | ||
880 | |||
881 | ath9k_hw_set_desc_link(ah, bf->bf_desc, ds_next); | ||
882 | bf = bf->bf_next; | ||
883 | } | ||
884 | } | ||
885 | |||
851 | static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | 886 | static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, |
852 | struct ath_atx_tid *tid) | 887 | struct ath_atx_tid *tid) |
853 | { | 888 | { |
854 | struct ath_buf *bf; | 889 | struct ath_buf *bf; |
855 | enum ATH_AGGR_STATUS status; | 890 | enum ATH_AGGR_STATUS status; |
856 | struct ath_frame_info *fi; | 891 | struct ieee80211_tx_info *tx_info; |
857 | struct list_head bf_q; | 892 | struct list_head bf_q; |
858 | int aggr_len; | 893 | int aggr_len; |
859 | 894 | ||
@@ -874,34 +909,25 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
874 | 909 | ||
875 | bf = list_first_entry(&bf_q, struct ath_buf, list); | 910 | bf = list_first_entry(&bf_q, struct ath_buf, list); |
876 | bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); | 911 | bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); |
912 | tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); | ||
877 | 913 | ||
878 | if (tid->ac->clear_ps_filter) { | 914 | if (tid->ac->clear_ps_filter) { |
879 | tid->ac->clear_ps_filter = false; | 915 | tid->ac->clear_ps_filter = false; |
880 | ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); | 916 | tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
917 | } else { | ||
918 | tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT; | ||
881 | } | 919 | } |
882 | 920 | ||
883 | /* if only one frame, send as non-aggregate */ | 921 | /* if only one frame, send as non-aggregate */ |
884 | if (bf == bf->bf_lastbf) { | 922 | if (bf == bf->bf_lastbf) { |
885 | fi = get_frame_info(bf->bf_mpdu); | 923 | aggr_len = get_frame_info(bf->bf_mpdu)->framelen; |
886 | 924 | bf->bf_state.bf_type = BUF_AMPDU; | |
887 | bf->bf_state.bf_type &= ~BUF_AGGR; | 925 | } else { |
888 | ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); | 926 | TX_STAT_INC(txq->axq_qnum, a_aggr); |
889 | ath_buf_set_rate(sc, bf, fi->framelen); | ||
890 | ath_tx_txqaddbuf(sc, txq, &bf_q, false); | ||
891 | continue; | ||
892 | } | 927 | } |
893 | 928 | ||
894 | /* setup first desc of aggregate */ | 929 | ath_tx_fill_desc(sc, bf, aggr_len); |
895 | bf->bf_state.bf_type |= BUF_AGGR; | ||
896 | ath_buf_set_rate(sc, bf, aggr_len); | ||
897 | ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, aggr_len); | ||
898 | |||
899 | /* anchor last desc of aggregate */ | ||
900 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); | ||
901 | |||
902 | ath_tx_txqaddbuf(sc, txq, &bf_q, false); | 930 | ath_tx_txqaddbuf(sc, txq, &bf_q, false); |
903 | TX_STAT_INC(txq->axq_qnum, a_aggr); | ||
904 | |||
905 | } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH && | 931 | } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH && |
906 | status != ATH_AGGR_BAW_CLOSED); | 932 | status != ATH_AGGR_BAW_CLOSED); |
907 | } | 933 | } |
@@ -1479,7 +1505,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
1479 | if (!bf) | 1505 | if (!bf) |
1480 | return; | 1506 | return; |
1481 | 1507 | ||
1482 | bf->bf_state.bf_type |= BUF_AMPDU; | 1508 | bf->bf_state.bf_type = BUF_AMPDU; |
1483 | INIT_LIST_HEAD(&bf_head); | 1509 | INIT_LIST_HEAD(&bf_head); |
1484 | list_add(&bf->list, &bf_head); | 1510 | list_add(&bf->list, &bf_head); |
1485 | 1511 | ||
@@ -1489,7 +1515,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
1489 | /* Queue to h/w without aggregation */ | 1515 | /* Queue to h/w without aggregation */ |
1490 | TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw); | 1516 | TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw); |
1491 | bf->bf_lastbf = bf; | 1517 | bf->bf_lastbf = bf; |
1492 | ath_buf_set_rate(sc, bf, fi->framelen); | 1518 | ath_tx_fill_desc(sc, bf, fi->framelen); |
1493 | ath_tx_txqaddbuf(sc, txctl->txq, &bf_head, false); | 1519 | ath_tx_txqaddbuf(sc, txctl->txq, &bf_head, false); |
1494 | } | 1520 | } |
1495 | 1521 | ||
@@ -1509,14 +1535,14 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | |||
1509 | 1535 | ||
1510 | INIT_LIST_HEAD(&bf_head); | 1536 | INIT_LIST_HEAD(&bf_head); |
1511 | list_add_tail(&bf->list, &bf_head); | 1537 | list_add_tail(&bf->list, &bf_head); |
1512 | bf->bf_state.bf_type &= ~BUF_AMPDU; | 1538 | bf->bf_state.bf_type = 0; |
1513 | 1539 | ||
1514 | /* update starting sequence number for subsequent ADDBA request */ | 1540 | /* update starting sequence number for subsequent ADDBA request */ |
1515 | if (tid) | 1541 | if (tid) |
1516 | INCR(tid->seq_start, IEEE80211_SEQ_MAX); | 1542 | INCR(tid->seq_start, IEEE80211_SEQ_MAX); |
1517 | 1543 | ||
1518 | bf->bf_lastbf = bf; | 1544 | bf->bf_lastbf = bf; |
1519 | ath_buf_set_rate(sc, bf, fi->framelen); | 1545 | ath_tx_fill_desc(sc, bf, fi->framelen); |
1520 | ath_tx_txqaddbuf(sc, txq, &bf_head, false); | 1546 | ath_tx_txqaddbuf(sc, txq, &bf_head, false); |
1521 | TX_STAT_INC(txq->axq_qnum, queued); | 1547 | TX_STAT_INC(txq->axq_qnum, queued); |
1522 | } | 1548 | } |
@@ -1790,8 +1816,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, | |||
1790 | frm_type = get_hw_packet_type(skb); | 1816 | frm_type = get_hw_packet_type(skb); |
1791 | 1817 | ||
1792 | ds = bf->bf_desc; | 1818 | ds = bf->bf_desc; |
1793 | ath9k_hw_set_desc_link(ah, ds, 0); | ||
1794 | |||
1795 | ath9k_hw_set11n_txdesc(ah, ds, fi->framelen, frm_type, MAX_RATE_POWER, | 1819 | ath9k_hw_set11n_txdesc(ah, ds, fi->framelen, frm_type, MAX_RATE_POWER, |
1796 | fi->keyix, fi->keytype, bf->bf_flags); | 1820 | fi->keyix, fi->keytype, bf->bf_flags); |
1797 | 1821 | ||
@@ -1852,9 +1876,6 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, | |||
1852 | if (txctl->paprd) | 1876 | if (txctl->paprd) |
1853 | bf->bf_state.bfs_paprd_timestamp = jiffies; | 1877 | bf->bf_state.bfs_paprd_timestamp = jiffies; |
1854 | 1878 | ||
1855 | if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) | ||
1856 | ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); | ||
1857 | |||
1858 | ath_tx_send_normal(sc, txctl->txq, tid, skb); | 1879 | ath_tx_send_normal(sc, txctl->txq, tid, skb); |
1859 | } | 1880 | } |
1860 | 1881 | ||