diff options
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 55 |
2 files changed, 24 insertions, 33 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index eb4cdefda629..5d9a9aabe476 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -211,12 +211,12 @@ struct ath_frame_info { | |||
211 | enum ath9k_key_type keytype; | 211 | enum ath9k_key_type keytype; |
212 | u8 keyix; | 212 | u8 keyix; |
213 | u8 retries; | 213 | u8 retries; |
214 | u16 seqno; | ||
215 | }; | 214 | }; |
216 | 215 | ||
217 | struct ath_buf_state { | 216 | struct ath_buf_state { |
218 | u8 bf_type; | 217 | u8 bf_type; |
219 | u8 bfs_paprd; | 218 | u8 bfs_paprd; |
219 | u16 seqno; | ||
220 | unsigned long bfs_paprd_timestamp; | 220 | unsigned long bfs_paprd_timestamp; |
221 | }; | 221 | }; |
222 | 222 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 34005e11502c..e3eeca98fbba 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -168,7 +168,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | |||
168 | 168 | ||
169 | spin_unlock_bh(&txq->axq_lock); | 169 | spin_unlock_bh(&txq->axq_lock); |
170 | if (fi->retries) { | 170 | if (fi->retries) { |
171 | ath_tx_update_baw(sc, tid, fi->seqno); | 171 | ath_tx_update_baw(sc, tid, bf->bf_state.seqno); |
172 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1); | 172 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1); |
173 | } else { | 173 | } else { |
174 | ath_tx_send_normal(sc, txq, NULL, &bf_head); | 174 | ath_tx_send_normal(sc, txq, NULL, &bf_head); |
@@ -237,7 +237,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, | |||
237 | list_add_tail(&bf->list, &bf_head); | 237 | list_add_tail(&bf->list, &bf_head); |
238 | 238 | ||
239 | if (fi->retries) | 239 | if (fi->retries) |
240 | ath_tx_update_baw(sc, tid, fi->seqno); | 240 | ath_tx_update_baw(sc, tid, bf->bf_state.seqno); |
241 | 241 | ||
242 | spin_unlock(&txq->axq_lock); | 242 | spin_unlock(&txq->axq_lock); |
243 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); | 243 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); |
@@ -327,7 +327,7 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf, | |||
327 | 327 | ||
328 | while (bf) { | 328 | while (bf) { |
329 | fi = get_frame_info(bf->bf_mpdu); | 329 | fi = get_frame_info(bf->bf_mpdu); |
330 | ba_index = ATH_BA_INDEX(seq_st, fi->seqno); | 330 | ba_index = ATH_BA_INDEX(seq_st, bf->bf_state.seqno); |
331 | 331 | ||
332 | (*nframes)++; | 332 | (*nframes)++; |
333 | if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index))) | 333 | if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index))) |
@@ -428,6 +428,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
428 | 428 | ||
429 | ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad); | 429 | ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad); |
430 | while (bf) { | 430 | while (bf) { |
431 | u16 seqno = bf->bf_state.seqno; | ||
432 | |||
431 | txfail = txpending = sendbar = 0; | 433 | txfail = txpending = sendbar = 0; |
432 | bf_next = bf->bf_next; | 434 | bf_next = bf->bf_next; |
433 | 435 | ||
@@ -435,7 +437,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
435 | tx_info = IEEE80211_SKB_CB(skb); | 437 | tx_info = IEEE80211_SKB_CB(skb); |
436 | fi = get_frame_info(skb); | 438 | fi = get_frame_info(skb); |
437 | 439 | ||
438 | if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, fi->seqno))) { | 440 | if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, seqno))) { |
439 | /* transmit completion, subframe is | 441 | /* transmit completion, subframe is |
440 | * acked by block ack */ | 442 | * acked by block ack */ |
441 | acked_cnt++; | 443 | acked_cnt++; |
@@ -479,7 +481,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
479 | * block-ack window | 481 | * block-ack window |
480 | */ | 482 | */ |
481 | spin_lock_bh(&txq->axq_lock); | 483 | spin_lock_bh(&txq->axq_lock); |
482 | ath_tx_update_baw(sc, tid, fi->seqno); | 484 | ath_tx_update_baw(sc, tid, seqno); |
483 | spin_unlock_bh(&txq->axq_lock); | 485 | spin_unlock_bh(&txq->axq_lock); |
484 | 486 | ||
485 | if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { | 487 | if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { |
@@ -507,7 +509,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
507 | */ | 509 | */ |
508 | if (!tbf) { | 510 | if (!tbf) { |
509 | spin_lock_bh(&txq->axq_lock); | 511 | spin_lock_bh(&txq->axq_lock); |
510 | ath_tx_update_baw(sc, tid, fi->seqno); | 512 | ath_tx_update_baw(sc, tid, seqno); |
511 | spin_unlock_bh(&txq->axq_lock); | 513 | spin_unlock_bh(&txq->axq_lock); |
512 | 514 | ||
513 | bf->bf_state.bf_type |= | 515 | bf->bf_state.bf_type |= |
@@ -752,17 +754,19 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
752 | struct ieee80211_tx_info *tx_info; | 754 | struct ieee80211_tx_info *tx_info; |
753 | struct ath_frame_info *fi; | 755 | struct ath_frame_info *fi; |
754 | struct sk_buff *skb; | 756 | struct sk_buff *skb; |
757 | u16 seqno; | ||
755 | 758 | ||
756 | do { | 759 | do { |
757 | skb = skb_peek(&tid->buf_q); | 760 | skb = skb_peek(&tid->buf_q); |
758 | fi = get_frame_info(skb); | 761 | fi = get_frame_info(skb); |
759 | bf = fi->bf; | 762 | bf = fi->bf; |
763 | seqno = bf->bf_state.seqno; | ||
760 | 764 | ||
761 | if (!bf_first) | 765 | if (!bf_first) |
762 | bf_first = bf; | 766 | bf_first = bf; |
763 | 767 | ||
764 | /* do not step over block-ack window */ | 768 | /* do not step over block-ack window */ |
765 | if (!BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno)) { | 769 | if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) { |
766 | status = ATH_AGGR_BAW_CLOSED; | 770 | status = ATH_AGGR_BAW_CLOSED; |
767 | break; | 771 | break; |
768 | } | 772 | } |
@@ -810,7 +814,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
810 | 814 | ||
811 | /* link buffers of this frame to the aggregate */ | 815 | /* link buffers of this frame to the aggregate */ |
812 | if (!fi->retries) | 816 | if (!fi->retries) |
813 | ath_tx_addto_baw(sc, tid, fi->seqno); | 817 | ath_tx_addto_baw(sc, tid, seqno); |
814 | ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim); | 818 | ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim); |
815 | 819 | ||
816 | __skb_unlink(skb, &tid->buf_q); | 820 | __skb_unlink(skb, &tid->buf_q); |
@@ -1434,6 +1438,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
1434 | { | 1438 | { |
1435 | struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); | 1439 | struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); |
1436 | struct list_head bf_head; | 1440 | struct list_head bf_head; |
1441 | u16 seqno = bf->bf_state.seqno; | ||
1437 | 1442 | ||
1438 | bf->bf_state.bf_type |= BUF_AMPDU; | 1443 | bf->bf_state.bf_type |= BUF_AMPDU; |
1439 | 1444 | ||
@@ -1445,7 +1450,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
1445 | * - h/w queue depth exceeds low water mark | 1450 | * - h/w queue depth exceeds low water mark |
1446 | */ | 1451 | */ |
1447 | if (!skb_queue_empty(&tid->buf_q) || tid->paused || | 1452 | if (!skb_queue_empty(&tid->buf_q) || tid->paused || |
1448 | !BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) || | 1453 | !BAW_WITHIN(tid->seq_start, tid->baw_size, seqno) || |
1449 | txctl->txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) { | 1454 | txctl->txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) { |
1450 | /* | 1455 | /* |
1451 | * Add this frame to software queue for scheduling later | 1456 | * Add this frame to software queue for scheduling later |
@@ -1463,7 +1468,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
1463 | 1468 | ||
1464 | /* Add sub-frame to BAW */ | 1469 | /* Add sub-frame to BAW */ |
1465 | if (!fi->retries) | 1470 | if (!fi->retries) |
1466 | ath_tx_addto_baw(sc, tid, fi->seqno); | 1471 | ath_tx_addto_baw(sc, tid, seqno); |
1467 | 1472 | ||
1468 | /* Queue to h/w without aggregation */ | 1473 | /* Queue to h/w without aggregation */ |
1469 | TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw); | 1474 | TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw); |
@@ -1519,39 +1524,19 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) | |||
1519 | static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, | 1524 | static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, |
1520 | int framelen) | 1525 | int framelen) |
1521 | { | 1526 | { |
1522 | struct ath_softc *sc = hw->priv; | ||
1523 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1527 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1524 | struct ieee80211_sta *sta = tx_info->control.sta; | 1528 | struct ieee80211_sta *sta = tx_info->control.sta; |
1525 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; | 1529 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; |
1526 | struct ieee80211_hdr *hdr; | 1530 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1527 | struct ath_frame_info *fi = get_frame_info(skb); | 1531 | struct ath_frame_info *fi = get_frame_info(skb); |
1528 | struct ath_node *an = NULL; | 1532 | struct ath_node *an = NULL; |
1529 | struct ath_atx_tid *tid; | ||
1530 | enum ath9k_key_type keytype; | 1533 | enum ath9k_key_type keytype; |
1531 | u16 seqno = 0; | ||
1532 | u8 tidno; | ||
1533 | 1534 | ||
1534 | keytype = ath9k_cmn_get_hw_crypto_keytype(skb); | 1535 | keytype = ath9k_cmn_get_hw_crypto_keytype(skb); |
1535 | 1536 | ||
1536 | if (sta) | 1537 | if (sta) |
1537 | an = (struct ath_node *) sta->drv_priv; | 1538 | an = (struct ath_node *) sta->drv_priv; |
1538 | 1539 | ||
1539 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1540 | if (an && ieee80211_is_data_qos(hdr->frame_control) && | ||
1541 | conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) { | ||
1542 | |||
1543 | tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
1544 | |||
1545 | /* | ||
1546 | * Override seqno set by upper layer with the one | ||
1547 | * in tx aggregation state. | ||
1548 | */ | ||
1549 | tid = ATH_AN_2_TID(an, tidno); | ||
1550 | seqno = tid->seq_next; | ||
1551 | hdr->seq_ctrl = cpu_to_le16(seqno << IEEE80211_SEQ_SEQ_SHIFT); | ||
1552 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | ||
1553 | } | ||
1554 | |||
1555 | memset(fi, 0, sizeof(*fi)); | 1540 | memset(fi, 0, sizeof(*fi)); |
1556 | if (hw_key) | 1541 | if (hw_key) |
1557 | fi->keyix = hw_key->hw_key_idx; | 1542 | fi->keyix = hw_key->hw_key_idx; |
@@ -1561,7 +1546,6 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1561 | fi->keyix = ATH9K_TXKEYIX_INVALID; | 1546 | fi->keyix = ATH9K_TXKEYIX_INVALID; |
1562 | fi->keytype = keytype; | 1547 | fi->keytype = keytype; |
1563 | fi->framelen = framelen; | 1548 | fi->framelen = framelen; |
1564 | fi->seqno = seqno; | ||
1565 | } | 1549 | } |
1566 | 1550 | ||
1567 | static int setup_tx_flags(struct sk_buff *skb) | 1551 | static int setup_tx_flags(struct sk_buff *skb) |
@@ -1797,6 +1781,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
1797 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1781 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1798 | struct list_head bf_head; | 1782 | struct list_head bf_head; |
1799 | struct ath_atx_tid *tid = NULL; | 1783 | struct ath_atx_tid *tid = NULL; |
1784 | u16 seqno; | ||
1800 | u8 tidno; | 1785 | u8 tidno; |
1801 | 1786 | ||
1802 | spin_lock_bh(&txctl->txq->axq_lock); | 1787 | spin_lock_bh(&txctl->txq->axq_lock); |
@@ -1806,6 +1791,12 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
1806 | IEEE80211_QOS_CTL_TID_MASK; | 1791 | IEEE80211_QOS_CTL_TID_MASK; |
1807 | tid = ATH_AN_2_TID(txctl->an, tidno); | 1792 | tid = ATH_AN_2_TID(txctl->an, tidno); |
1808 | 1793 | ||
1794 | seqno = tid->seq_next; | ||
1795 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); | ||
1796 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | ||
1797 | |||
1798 | bf->bf_state.seqno = seqno; | ||
1799 | |||
1809 | WARN_ON(tid->ac->txq != txctl->txq); | 1800 | WARN_ON(tid->ac->txq != txctl->txq); |
1810 | } | 1801 | } |
1811 | 1802 | ||