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.c137
1 files changed, 73 insertions, 64 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 89a64411b82e..eab0fcb7ded6 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -157,6 +157,13 @@ static void ath_send_bar(struct ath_atx_tid *tid, u16 seqno)
157 seqno << IEEE80211_SEQ_SEQ_SHIFT); 157 seqno << IEEE80211_SEQ_SEQ_SHIFT);
158} 158}
159 159
160static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
161 struct ath_buf *bf)
162{
163 ieee80211_get_tx_rates(vif, sta, bf->bf_mpdu, bf->rates,
164 ARRAY_SIZE(bf->rates));
165}
166
160static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) 167static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
161{ 168{
162 struct ath_txq *txq = tid->ac->txq; 169 struct ath_txq *txq = tid->ac->txq;
@@ -189,6 +196,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
189 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); 196 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
190 sendbar = true; 197 sendbar = true;
191 } else { 198 } else {
199 ath_set_rates(tid->an->vif, tid->an->sta, bf);
192 ath_tx_send_normal(sc, txq, NULL, skb); 200 ath_tx_send_normal(sc, txq, NULL, skb);
193 } 201 }
194 } 202 }
@@ -407,7 +415,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
407 415
408 tx_info = IEEE80211_SKB_CB(skb); 416 tx_info = IEEE80211_SKB_CB(skb);
409 417
410 memcpy(rates, tx_info->control.rates, sizeof(rates)); 418 memcpy(rates, bf->rates, sizeof(rates));
411 419
412 retries = ts->ts_longretry + 1; 420 retries = ts->ts_longretry + 1;
413 for (i = 0; i < ts->ts_rateindex; i++) 421 for (i = 0; i < ts->ts_rateindex; i++)
@@ -516,8 +524,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
516 * not a holding desc. 524 * not a holding desc.
517 */ 525 */
518 INIT_LIST_HEAD(&bf_head); 526 INIT_LIST_HEAD(&bf_head);
519 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) || 527 if (bf_next != NULL || !bf_last->bf_stale)
520 bf_next != NULL || !bf_last->bf_stale)
521 list_move_tail(&bf->list, &bf_head); 528 list_move_tail(&bf->list, &bf_head);
522 529
523 if (!txpending || (tid->state & AGGR_CLEANUP)) { 530 if (!txpending || (tid->state & AGGR_CLEANUP)) {
@@ -537,8 +544,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
537 !txfail); 544 !txfail);
538 } else { 545 } else {
539 /* retry the un-acked ones */ 546 /* retry the un-acked ones */
540 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && 547 if (bf->bf_next == NULL && bf_last->bf_stale) {
541 bf->bf_next == NULL && bf_last->bf_stale) {
542 struct ath_buf *tbf; 548 struct ath_buf *tbf;
543 549
544 tbf = ath_clone_txbuf(sc, bf_last); 550 tbf = ath_clone_txbuf(sc, bf_last);
@@ -738,8 +744,6 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
738 bool first_subfrm) 744 bool first_subfrm)
739{ 745{
740#define FIRST_DESC_NDELIMS 60 746#define FIRST_DESC_NDELIMS 60
741 struct sk_buff *skb = bf->bf_mpdu;
742 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
743 u32 nsymbits, nsymbols; 747 u32 nsymbits, nsymbols;
744 u16 minlen; 748 u16 minlen;
745 u8 flags, rix; 749 u8 flags, rix;
@@ -780,8 +784,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
780 if (tid->an->mpdudensity == 0) 784 if (tid->an->mpdudensity == 0)
781 return ndelim; 785 return ndelim;
782 786
783 rix = tx_info->control.rates[0].idx; 787 rix = bf->rates[0].idx;
784 flags = tx_info->control.rates[0].flags; 788 flags = bf->rates[0].flags;
785 width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0; 789 width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0;
786 half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0; 790 half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0;
787 791
@@ -860,6 +864,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
860 bf_first = bf; 864 bf_first = bf;
861 865
862 if (!rl) { 866 if (!rl) {
867 ath_set_rates(tid->an->vif, tid->an->sta, bf);
863 aggr_limit = ath_lookup_rate(sc, bf, tid); 868 aggr_limit = ath_lookup_rate(sc, bf, tid);
864 rl = 1; 869 rl = 1;
865 } 870 }
@@ -1000,14 +1005,14 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
1000 1005
1001 skb = bf->bf_mpdu; 1006 skb = bf->bf_mpdu;
1002 tx_info = IEEE80211_SKB_CB(skb); 1007 tx_info = IEEE80211_SKB_CB(skb);
1003 rates = tx_info->control.rates; 1008 rates = bf->rates;
1004 hdr = (struct ieee80211_hdr *)skb->data; 1009 hdr = (struct ieee80211_hdr *)skb->data;
1005 1010
1006 /* set dur_update_en for l-sig computation except for PS-Poll frames */ 1011 /* set dur_update_en for l-sig computation except for PS-Poll frames */
1007 info->dur_update = !ieee80211_is_pspoll(hdr->frame_control); 1012 info->dur_update = !ieee80211_is_pspoll(hdr->frame_control);
1008 info->rtscts_rate = fi->rtscts_rate; 1013 info->rtscts_rate = fi->rtscts_rate;
1009 1014
1010 for (i = 0; i < 4; i++) { 1015 for (i = 0; i < ARRAY_SIZE(bf->rates); i++) {
1011 bool is_40, is_sgi, is_sp; 1016 bool is_40, is_sgi, is_sp;
1012 int phy; 1017 int phy;
1013 1018
@@ -1745,6 +1750,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
1745 return; 1750 return;
1746 } 1751 }
1747 1752
1753 ath_set_rates(tid->an->vif, tid->an->sta, bf);
1748 bf->bf_state.bf_type = BUF_AMPDU; 1754 bf->bf_state.bf_type = BUF_AMPDU;
1749 INIT_LIST_HEAD(&bf_head); 1755 INIT_LIST_HEAD(&bf_head);
1750 list_add(&bf->list, &bf_head); 1756 list_add(&bf->list, &bf_head);
@@ -1894,49 +1900,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
1894 return bf; 1900 return bf;
1895} 1901}
1896 1902
1897/* FIXME: tx power */
1898static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
1899 struct ath_tx_control *txctl)
1900{
1901 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1902 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1903 struct ath_atx_tid *tid = NULL;
1904 struct ath_buf *bf;
1905 u8 tidno;
1906
1907 if (txctl->an && ieee80211_is_data_qos(hdr->frame_control)) {
1908 tidno = ieee80211_get_qos_ctl(hdr)[0] &
1909 IEEE80211_QOS_CTL_TID_MASK;
1910 tid = ATH_AN_2_TID(txctl->an, tidno);
1911
1912 WARN_ON(tid->ac->txq != txctl->txq);
1913 }
1914
1915 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
1916 /*
1917 * Try aggregation if it's a unicast data frame
1918 * and the destination is HT capable.
1919 */
1920 ath_tx_send_ampdu(sc, tid, skb, txctl);
1921 } else {
1922 bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
1923 if (!bf) {
1924 if (txctl->paprd)
1925 dev_kfree_skb_any(skb);
1926 else
1927 ieee80211_free_txskb(sc->hw, skb);
1928 return;
1929 }
1930
1931 bf->bf_state.bfs_paprd = txctl->paprd;
1932
1933 if (txctl->paprd)
1934 bf->bf_state.bfs_paprd_timestamp = jiffies;
1935
1936 ath_tx_send_normal(sc, txctl->txq, tid, skb);
1937 }
1938}
1939
1940/* Upon failure caller should free skb */ 1903/* Upon failure caller should free skb */
1941int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, 1904int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1942 struct ath_tx_control *txctl) 1905 struct ath_tx_control *txctl)
@@ -1947,8 +1910,11 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1947 struct ieee80211_vif *vif = info->control.vif; 1910 struct ieee80211_vif *vif = info->control.vif;
1948 struct ath_softc *sc = hw->priv; 1911 struct ath_softc *sc = hw->priv;
1949 struct ath_txq *txq = txctl->txq; 1912 struct ath_txq *txq = txctl->txq;
1913 struct ath_atx_tid *tid = NULL;
1914 struct ath_buf *bf;
1950 int padpos, padsize; 1915 int padpos, padsize;
1951 int frmlen = skb->len + FCS_LEN; 1916 int frmlen = skb->len + FCS_LEN;
1917 u8 tidno;
1952 int q; 1918 int q;
1953 1919
1954 /* NOTE: sta can be NULL according to net/mac80211.h */ 1920 /* NOTE: sta can be NULL according to net/mac80211.h */
@@ -1971,7 +1937,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1971 } 1937 }
1972 1938
1973 /* Add the padding after the header if this is not already done */ 1939 /* Add the padding after the header if this is not already done */
1974 padpos = ath9k_cmn_padpos(hdr->frame_control); 1940 padpos = ieee80211_hdrlen(hdr->frame_control);
1975 padsize = padpos & 3; 1941 padsize = padpos & 3;
1976 if (padsize && skb->len > padpos) { 1942 if (padsize && skb->len > padpos) {
1977 if (skb_headroom(skb) < padsize) 1943 if (skb_headroom(skb) < padsize)
@@ -2004,8 +1970,41 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
2004 txq->stopped = true; 1970 txq->stopped = true;
2005 } 1971 }
2006 1972
2007 ath_tx_start_dma(sc, skb, txctl); 1973 if (txctl->an && ieee80211_is_data_qos(hdr->frame_control)) {
1974 tidno = ieee80211_get_qos_ctl(hdr)[0] &
1975 IEEE80211_QOS_CTL_TID_MASK;
1976 tid = ATH_AN_2_TID(txctl->an, tidno);
1977
1978 WARN_ON(tid->ac->txq != txctl->txq);
1979 }
1980
1981 if ((info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
1982 /*
1983 * Try aggregation if it's a unicast data frame
1984 * and the destination is HT capable.
1985 */
1986 ath_tx_send_ampdu(sc, tid, skb, txctl);
1987 goto out;
1988 }
2008 1989
1990 bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
1991 if (!bf) {
1992 if (txctl->paprd)
1993 dev_kfree_skb_any(skb);
1994 else
1995 ieee80211_free_txskb(sc->hw, skb);
1996 goto out;
1997 }
1998
1999 bf->bf_state.bfs_paprd = txctl->paprd;
2000
2001 if (txctl->paprd)
2002 bf->bf_state.bfs_paprd_timestamp = jiffies;
2003
2004 ath_set_rates(vif, sta, bf);
2005 ath_tx_send_normal(sc, txctl->txq, tid, skb);
2006
2007out:
2009 ath_txq_unlock(sc, txq); 2008 ath_txq_unlock(sc, txq);
2010 2009
2011 return 0; 2010 return 0;
@@ -2033,7 +2032,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
2033 /* Frame was ACKed */ 2032 /* Frame was ACKed */
2034 tx_info->flags |= IEEE80211_TX_STAT_ACK; 2033 tx_info->flags |= IEEE80211_TX_STAT_ACK;
2035 2034
2036 padpos = ath9k_cmn_padpos(hdr->frame_control); 2035 padpos = ieee80211_hdrlen(hdr->frame_control);
2037 padsize = padpos & 3; 2036 padsize = padpos & 3;
2038 if (padsize && skb->len>padpos+padsize) { 2037 if (padsize && skb->len>padpos+padsize) {
2039 /* 2038 /*
@@ -2264,6 +2263,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2264 struct ath_txq *txq; 2263 struct ath_txq *txq;
2265 struct ath_buf *bf, *lastbf; 2264 struct ath_buf *bf, *lastbf;
2266 struct list_head bf_head; 2265 struct list_head bf_head;
2266 struct list_head *fifo_list;
2267 int status; 2267 int status;
2268 2268
2269 for (;;) { 2269 for (;;) {
@@ -2291,20 +2291,24 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2291 2291
2292 TX_STAT_INC(txq->axq_qnum, txprocdesc); 2292 TX_STAT_INC(txq->axq_qnum, txprocdesc);
2293 2293
2294 if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { 2294 fifo_list = &txq->txq_fifo[txq->txq_tailidx];
2295 if (list_empty(fifo_list)) {
2295 ath_txq_unlock(sc, txq); 2296 ath_txq_unlock(sc, txq);
2296 return; 2297 return;
2297 } 2298 }
2298 2299
2299 bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx], 2300 bf = list_first_entry(fifo_list, struct ath_buf, list);
2300 struct ath_buf, list); 2301 if (bf->bf_stale) {
2302 list_del(&bf->list);
2303 ath_tx_return_buffer(sc, bf);
2304 bf = list_first_entry(fifo_list, struct ath_buf, list);
2305 }
2306
2301 lastbf = bf->bf_lastbf; 2307 lastbf = bf->bf_lastbf;
2302 2308
2303 INIT_LIST_HEAD(&bf_head); 2309 INIT_LIST_HEAD(&bf_head);
2304 list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx], 2310 if (list_is_last(&lastbf->list, fifo_list)) {
2305 &lastbf->list); 2311 list_splice_tail_init(fifo_list, &bf_head);
2306
2307 if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
2308 INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); 2312 INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
2309 2313
2310 if (!list_empty(&txq->axq_q)) { 2314 if (!list_empty(&txq->axq_q)) {
@@ -2315,6 +2319,11 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2315 list_splice_tail_init(&txq->axq_q, &bf_q); 2319 list_splice_tail_init(&txq->axq_q, &bf_q);
2316 ath_tx_txqaddbuf(sc, txq, &bf_q, true); 2320 ath_tx_txqaddbuf(sc, txq, &bf_q, true);
2317 } 2321 }
2322 } else {
2323 lastbf->bf_stale = true;
2324 if (bf != lastbf)
2325 list_cut_position(&bf_head, fifo_list,
2326 lastbf->list.prev);
2318 } 2327 }
2319 2328
2320 ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); 2329 ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);