aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-11-14 09:20:12 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-11-17 16:19:27 -0500
commit04caf863750bc7e042d1e8d57e5ce9d6326ab435 (patch)
treeac98c29809ce992bbd22a34b0f52be4abe35bde0 /drivers
parent71a3bf3e94b745467fc4c3451a294910f0369555 (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.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c129
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 */
96enum buffer_type { 95enum 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
1346static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, 1346static 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
1387static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, 1388static 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
1429static void assign_aggr_tid_seqno(struct sk_buff *skb, 1430static 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
1610static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, 1610static 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 */
1659static 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 */
1680static 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