diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-11-14 09:20:12 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-11-17 16:19:27 -0500 |
commit | 04caf863750bc7e042d1e8d57e5ce9d6326ab435 (patch) | |
tree | ac98c29809ce992bbd22a34b0f52be4abe35bde0 /drivers | |
parent | 71a3bf3e94b745467fc4c3451a294910f0369555 (diff) |
ath9k: more tx setup cleanups
- remove the BUF_HT flag, and instead check for IEEE80211_TX_CTL_AMPDU
before calling ath_tx_send_ampdu.
- remove a few unused variables
- calculate frame length before adding the frame padding
- merge the misnamed ath_tx_start_dma function into ath_tx_start
- remove an unused argument for assign_aggr_tid_seqno
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 129 |
2 files changed, 59 insertions, 74 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 711100793081..d12123a6576b 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -86,7 +86,6 @@ struct ath_config { | |||
86 | /** | 86 | /** |
87 | * enum buffer_type - Buffer type flags | 87 | * enum buffer_type - Buffer type flags |
88 | * | 88 | * |
89 | * @BUF_HT: Send this buffer using HT capabilities | ||
90 | * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX) | 89 | * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX) |
91 | * @BUF_AGGR: Indicates whether the buffer can be aggregated | 90 | * @BUF_AGGR: Indicates whether the buffer can be aggregated |
92 | * (used in aggregation scheduling) | 91 | * (used in aggregation scheduling) |
@@ -94,7 +93,6 @@ struct ath_config { | |||
94 | * @BUF_XRETRY: To denote excessive retries of the buffer | 93 | * @BUF_XRETRY: To denote excessive retries of the buffer |
95 | */ | 94 | */ |
96 | enum buffer_type { | 95 | enum buffer_type { |
97 | BUF_HT = BIT(1), | ||
98 | BUF_AMPDU = BIT(2), | 96 | BUF_AMPDU = BIT(2), |
99 | BUF_AGGR = BIT(3), | 97 | BUF_AGGR = BIT(3), |
100 | BUF_RETRY = BIT(4), | 98 | BUF_RETRY = BIT(4), |
@@ -102,7 +100,6 @@ enum buffer_type { | |||
102 | }; | 100 | }; |
103 | 101 | ||
104 | #define bf_retries bf_state.bfs_retries | 102 | #define bf_retries bf_state.bfs_retries |
105 | #define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT) | ||
106 | #define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) | 103 | #define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) |
107 | #define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR) | 104 | #define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR) |
108 | #define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY) | 105 | #define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY) |
@@ -265,6 +262,7 @@ struct ath_tx_control { | |||
265 | struct ath_txq *txq; | 262 | struct ath_txq *txq; |
266 | int if_id; | 263 | int if_id; |
267 | enum ath9k_internal_frame_type frame_type; | 264 | enum ath9k_internal_frame_type frame_type; |
265 | int frmlen; | ||
268 | u8 paprd; | 266 | u8 paprd; |
269 | }; | 267 | }; |
270 | 268 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index f3f0d1c6ad0a..5eeffaea551e 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1344,13 +1344,11 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
1344 | } | 1344 | } |
1345 | 1345 | ||
1346 | static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | 1346 | static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, |
1347 | struct list_head *bf_head, | 1347 | struct ath_buf *bf, struct ath_tx_control *txctl) |
1348 | struct ath_tx_control *txctl, int frmlen) | ||
1349 | { | 1348 | { |
1350 | struct ath_buf *bf; | 1349 | struct list_head bf_head; |
1351 | u16 bf_seqno; | 1350 | u16 bf_seqno; |
1352 | 1351 | ||
1353 | bf = list_first_entry(bf_head, struct ath_buf, list); | ||
1354 | bf->bf_state.bf_type |= BUF_AMPDU; | 1352 | bf->bf_state.bf_type |= BUF_AMPDU; |
1355 | TX_STAT_INC(txctl->txq->axq_qnum, a_queued); | 1353 | TX_STAT_INC(txctl->txq->axq_qnum, a_queued); |
1356 | bf_seqno = ath_frame_seqno(bf->bf_mpdu); | 1354 | bf_seqno = ath_frame_seqno(bf->bf_mpdu); |
@@ -1369,19 +1367,22 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
1369 | * Add this frame to software queue for scheduling later | 1367 | * Add this frame to software queue for scheduling later |
1370 | * for aggregation. | 1368 | * for aggregation. |
1371 | */ | 1369 | */ |
1372 | list_move_tail(&bf->list, &tid->buf_q); | 1370 | list_add_tail(&bf->list, &tid->buf_q); |
1373 | ath_tx_queue_tid(txctl->txq, tid); | 1371 | ath_tx_queue_tid(txctl->txq, tid); |
1374 | return; | 1372 | return; |
1375 | } | 1373 | } |
1376 | 1374 | ||
1375 | INIT_LIST_HEAD(&bf_head); | ||
1376 | list_add(&bf->list, &bf_head); | ||
1377 | |||
1377 | /* Add sub-frame to BAW */ | 1378 | /* Add sub-frame to BAW */ |
1378 | if (!bf_isretried(bf)) | 1379 | if (!bf_isretried(bf)) |
1379 | ath_tx_addto_baw(sc, tid, bf_seqno); | 1380 | ath_tx_addto_baw(sc, tid, bf_seqno); |
1380 | 1381 | ||
1381 | /* Queue to h/w without aggregation */ | 1382 | /* Queue to h/w without aggregation */ |
1382 | bf->bf_lastbf = bf; | 1383 | bf->bf_lastbf = bf; |
1383 | ath_buf_set_rate(sc, bf, frmlen); | 1384 | ath_buf_set_rate(sc, bf, txctl->frmlen); |
1384 | ath_tx_txqaddbuf(sc, txctl->txq, bf_head); | 1385 | ath_tx_txqaddbuf(sc, txctl->txq, &bf_head); |
1385 | } | 1386 | } |
1386 | 1387 | ||
1387 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | 1388 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, |
@@ -1426,8 +1427,7 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) | |||
1426 | return htype; | 1427 | return htype; |
1427 | } | 1428 | } |
1428 | 1429 | ||
1429 | static void assign_aggr_tid_seqno(struct sk_buff *skb, | 1430 | static void assign_aggr_tid_seqno(struct sk_buff *skb) |
1430 | struct ath_buf *bf) | ||
1431 | { | 1431 | { |
1432 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1432 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1433 | struct ieee80211_hdr *hdr; | 1433 | struct ieee80211_hdr *hdr; |
@@ -1608,15 +1608,20 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) | |||
1608 | } | 1608 | } |
1609 | 1609 | ||
1610 | static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, | 1610 | static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, |
1611 | struct sk_buff *skb) | 1611 | struct ath_txq *txq, |
1612 | struct sk_buff *skb, int frmlen) | ||
1612 | { | 1613 | { |
1613 | struct ath_wiphy *aphy = hw->priv; | 1614 | struct ath_wiphy *aphy = hw->priv; |
1614 | struct ath_softc *sc = aphy->sc; | 1615 | struct ath_softc *sc = aphy->sc; |
1616 | struct ath_hw *ah = sc->sc_ah; | ||
1615 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1617 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1616 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1618 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1619 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb; | ||
1617 | struct ath_buf *bf; | 1620 | struct ath_buf *bf; |
1618 | int hdrlen; | 1621 | struct ath_desc *ds; |
1619 | __le16 fc; | 1622 | enum ath9k_key_type keytype; |
1623 | u32 keyix; | ||
1624 | int frm_type; | ||
1620 | 1625 | ||
1621 | bf = ath_tx_get_buffer(sc); | 1626 | bf = ath_tx_get_buffer(sc); |
1622 | if (!bf) { | 1627 | if (!bf) { |
@@ -1624,21 +1629,14 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, | |||
1624 | return NULL; | 1629 | return NULL; |
1625 | } | 1630 | } |
1626 | 1631 | ||
1627 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
1628 | fc = hdr->frame_control; | ||
1629 | |||
1630 | ATH_TXBUF_RESET(bf); | 1632 | ATH_TXBUF_RESET(bf); |
1631 | 1633 | ||
1632 | bf->aphy = aphy; | 1634 | if (ieee80211_is_data_qos(hdr->frame_control) && |
1633 | 1635 | conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) | |
1634 | if (ieee80211_is_data_qos(fc) && conf_is_ht(&hw->conf)) { | 1636 | assign_aggr_tid_seqno(skb); |
1635 | bf->bf_state.bf_type |= BUF_HT; | ||
1636 | if (sc->sc_flags & SC_OP_TXAGGR) | ||
1637 | assign_aggr_tid_seqno(skb, bf); | ||
1638 | } | ||
1639 | 1637 | ||
1638 | bf->aphy = aphy; | ||
1640 | bf->bf_flags = setup_tx_flags(skb); | 1639 | bf->bf_flags = setup_tx_flags(skb); |
1641 | |||
1642 | bf->bf_mpdu = skb; | 1640 | bf->bf_mpdu = skb; |
1643 | 1641 | ||
1644 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, | 1642 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, |
@@ -1652,33 +1650,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, | |||
1652 | return NULL; | 1650 | return NULL; |
1653 | } | 1651 | } |
1654 | 1652 | ||
1655 | return bf; | ||
1656 | } | ||
1657 | |||
1658 | /* FIXME: tx power */ | ||
1659 | static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | ||
1660 | struct ath_tx_control *txctl) | ||
1661 | { | ||
1662 | struct sk_buff *skb = bf->bf_mpdu; | ||
1663 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1664 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1665 | struct ath_node *an = NULL; | ||
1666 | struct list_head bf_head; | ||
1667 | struct ath_desc *ds; | ||
1668 | struct ath_atx_tid *tid; | ||
1669 | struct ath_hw *ah = sc->sc_ah; | ||
1670 | enum ath9k_key_type keytype; | ||
1671 | u32 keyix; | ||
1672 | int frm_type; | ||
1673 | __le16 fc; | ||
1674 | u8 tidno; | ||
1675 | int frmlen; | ||
1676 | |||
1677 | frm_type = get_hw_packet_type(skb); | 1653 | frm_type = get_hw_packet_type(skb); |
1678 | fc = hdr->frame_control; | ||
1679 | |||
1680 | INIT_LIST_HEAD(&bf_head); | ||
1681 | list_add_tail(&bf->list, &bf_head); | ||
1682 | 1654 | ||
1683 | ds = bf->bf_desc; | 1655 | ds = bf->bf_desc; |
1684 | ath9k_hw_set_desc_link(ah, ds, 0); | 1656 | ath9k_hw_set_desc_link(ah, ds, 0); |
@@ -1689,7 +1661,6 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
1689 | else | 1661 | else |
1690 | keyix = ATH9K_TXKEYIX_INVALID; | 1662 | keyix = ATH9K_TXKEYIX_INVALID; |
1691 | 1663 | ||
1692 | frmlen = ath_frame_len(bf->bf_mpdu); | ||
1693 | ath9k_hw_set11n_txdesc(ah, ds, frmlen, frm_type, MAX_RATE_POWER, | 1664 | ath9k_hw_set11n_txdesc(ah, ds, frmlen, frm_type, MAX_RATE_POWER, |
1694 | keyix, keytype, bf->bf_flags); | 1665 | keyix, keytype, bf->bf_flags); |
1695 | 1666 | ||
@@ -1699,40 +1670,50 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
1699 | true, /* last segment */ | 1670 | true, /* last segment */ |
1700 | ds, /* first descriptor */ | 1671 | ds, /* first descriptor */ |
1701 | bf->bf_buf_addr, | 1672 | bf->bf_buf_addr, |
1702 | txctl->txq->axq_qnum); | 1673 | txq->axq_qnum); |
1674 | |||
1675 | |||
1676 | return bf; | ||
1677 | } | ||
1678 | |||
1679 | /* FIXME: tx power */ | ||
1680 | static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | ||
1681 | struct ath_tx_control *txctl) | ||
1682 | { | ||
1683 | struct sk_buff *skb = bf->bf_mpdu; | ||
1684 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1685 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1686 | struct ath_node *an = NULL; | ||
1687 | struct list_head bf_head; | ||
1688 | struct ath_atx_tid *tid; | ||
1689 | u8 tidno; | ||
1703 | 1690 | ||
1704 | spin_lock_bh(&txctl->txq->axq_lock); | 1691 | spin_lock_bh(&txctl->txq->axq_lock); |
1705 | 1692 | ||
1706 | if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) && | 1693 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tx_info->control.sta) { |
1707 | tx_info->control.sta) { | ||
1708 | an = (struct ath_node *)tx_info->control.sta->drv_priv; | 1694 | an = (struct ath_node *)tx_info->control.sta->drv_priv; |
1709 | tidno = ieee80211_get_qos_ctl(hdr)[0] & | 1695 | tidno = ieee80211_get_qos_ctl(hdr)[0] & |
1710 | IEEE80211_QOS_CTL_TID_MASK; | 1696 | IEEE80211_QOS_CTL_TID_MASK; |
1711 | tid = ATH_AN_2_TID(an, tidno); | 1697 | tid = ATH_AN_2_TID(an, tidno); |
1712 | 1698 | ||
1713 | |||
1714 | WARN_ON(tid->ac->txq != txctl->txq); | 1699 | WARN_ON(tid->ac->txq != txctl->txq); |
1715 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | 1700 | /* |
1716 | /* | 1701 | * Try aggregation if it's a unicast data frame |
1717 | * Try aggregation if it's a unicast data frame | 1702 | * and the destination is HT capable. |
1718 | * and the destination is HT capable. | 1703 | */ |
1719 | */ | 1704 | ath_tx_send_ampdu(sc, tid, bf, txctl); |
1720 | ath_tx_send_ampdu(sc, tid, &bf_head, txctl, frmlen); | ||
1721 | } else { | ||
1722 | /* | ||
1723 | * Send this frame as regular when ADDBA | ||
1724 | * exchange is neither complete nor pending. | ||
1725 | */ | ||
1726 | ath_tx_send_normal(sc, txctl->txq, tid, &bf_head, frmlen); | ||
1727 | } | ||
1728 | } else { | 1705 | } else { |
1706 | INIT_LIST_HEAD(&bf_head); | ||
1707 | list_add_tail(&bf->list, &bf_head); | ||
1708 | |||
1729 | bf->bf_state.bfs_ftype = txctl->frame_type; | 1709 | bf->bf_state.bfs_ftype = txctl->frame_type; |
1730 | bf->bf_state.bfs_paprd = txctl->paprd; | 1710 | bf->bf_state.bfs_paprd = txctl->paprd; |
1731 | 1711 | ||
1732 | if (bf->bf_state.bfs_paprd) | 1712 | if (bf->bf_state.bfs_paprd) |
1733 | ar9003_hw_set_paprd_txdesc(ah, ds, bf->bf_state.bfs_paprd); | 1713 | ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc, |
1714 | bf->bf_state.bfs_paprd); | ||
1734 | 1715 | ||
1735 | ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head, frmlen); | 1716 | ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head, txctl->frmlen); |
1736 | } | 1717 | } |
1737 | 1718 | ||
1738 | spin_unlock_bh(&txctl->txq->axq_lock); | 1719 | spin_unlock_bh(&txctl->txq->axq_lock); |
@@ -1749,8 +1730,14 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1749 | struct ath_txq *txq = txctl->txq; | 1730 | struct ath_txq *txq = txctl->txq; |
1750 | struct ath_buf *bf; | 1731 | struct ath_buf *bf; |
1751 | int padpos, padsize; | 1732 | int padpos, padsize; |
1733 | int frmlen = skb->len + FCS_LEN; | ||
1752 | int q; | 1734 | int q; |
1753 | 1735 | ||
1736 | if (info->control.hw_key) | ||
1737 | frmlen += info->control.hw_key->icv_len; | ||
1738 | |||
1739 | txctl->frmlen = frmlen; | ||
1740 | |||
1754 | /* | 1741 | /* |
1755 | * As a temporary workaround, assign seq# here; this will likely need | 1742 | * As a temporary workaround, assign seq# here; this will likely need |
1756 | * to be cleaned up to work better with Beacon transmission and virtual | 1743 | * to be cleaned up to work better with Beacon transmission and virtual |
@@ -1774,7 +1761,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1774 | memmove(skb->data, skb->data + padsize, padpos); | 1761 | memmove(skb->data, skb->data + padsize, padpos); |
1775 | } | 1762 | } |
1776 | 1763 | ||
1777 | bf = ath_tx_setup_buffer(hw, skb); | 1764 | bf = ath_tx_setup_buffer(hw, txctl->txq, skb, frmlen); |
1778 | if (unlikely(!bf)) | 1765 | if (unlikely(!bf)) |
1779 | return -ENOMEM; | 1766 | return -ENOMEM; |
1780 | 1767 | ||