aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/xmit.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2011-09-14 15:24:18 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-09-16 16:45:37 -0400
commit38dad7ba60475618d873fe703e7ef564a963fd1f (patch)
treea9394c3af29a00a61b0bf1fe8bdc024d008c2322 /drivers/net/wireless/ath/ath9k/xmit.c
parent399c64895d206b16c704827d0a71b7467e441c94 (diff)
ath9k: move ath_buf_set_rate to remove a forward declaration
Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/xmit.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c283
1 files changed, 141 insertions, 142 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 48ac9ff01ac0..485c0a3a9ce1 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -56,7 +56,6 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
56 struct ath_tx_status *ts, int txok, int sendbar); 56 struct ath_tx_status *ts, int txok, int sendbar);
57static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, 57static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
58 struct list_head *head, bool internal); 58 struct list_head *head, bool internal);
59static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len);
60static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, 59static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
61 struct ath_tx_status *ts, int nframes, int nbad, 60 struct ath_tx_status *ts, int nframes, int nbad,
62 int txok, bool update_rc); 61 int txok, bool update_rc);
@@ -845,6 +844,147 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
845#undef PADBYTES 844#undef PADBYTES
846} 845}
847 846
847/*
848 * rix - rate index
849 * pktlen - total bytes (delims + data + fcs + pads + pad delims)
850 * width - 0 for 20 MHz, 1 for 40 MHz
851 * half_gi - to use 4us v/s 3.6 us for symbol time
852 */
853static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen,
854 int width, int half_gi, bool shortPreamble)
855{
856 u32 nbits, nsymbits, duration, nsymbols;
857 int streams;
858
859 /* find number of symbols: PLCP + data */
860 streams = HT_RC_2_STREAMS(rix);
861 nbits = (pktlen << 3) + OFDM_PLCP_BITS;
862 nsymbits = bits_per_symbol[rix % 8][width] * streams;
863 nsymbols = (nbits + nsymbits - 1) / nsymbits;
864
865 if (!half_gi)
866 duration = SYMBOL_TIME(nsymbols);
867 else
868 duration = SYMBOL_TIME_HALFGI(nsymbols);
869
870 /* addup duration for legacy/ht training and signal fields */
871 duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
872
873 return duration;
874}
875
876static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
877{
878 struct ath_hw *ah = sc->sc_ah;
879 struct ath9k_11n_rate_series series[4];
880 struct sk_buff *skb;
881 struct ieee80211_tx_info *tx_info;
882 struct ieee80211_tx_rate *rates;
883 const struct ieee80211_rate *rate;
884 struct ieee80211_hdr *hdr;
885 int i, flags = 0;
886 u8 rix = 0, ctsrate = 0;
887 bool is_pspoll;
888
889 memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
890
891 skb = bf->bf_mpdu;
892 tx_info = IEEE80211_SKB_CB(skb);
893 rates = tx_info->control.rates;
894 hdr = (struct ieee80211_hdr *)skb->data;
895 is_pspoll = ieee80211_is_pspoll(hdr->frame_control);
896
897 /*
898 * We check if Short Preamble is needed for the CTS rate by
899 * checking the BSS's global flag.
900 * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
901 */
902 rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info);
903 ctsrate = rate->hw_value;
904 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
905 ctsrate |= rate->hw_value_short;
906
907 for (i = 0; i < 4; i++) {
908 bool is_40, is_sgi, is_sp;
909 int phy;
910
911 if (!rates[i].count || (rates[i].idx < 0))
912 continue;
913
914 rix = rates[i].idx;
915 series[i].Tries = rates[i].count;
916
917 if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
918 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
919 flags |= ATH9K_TXDESC_RTSENA;
920 } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
921 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
922 flags |= ATH9K_TXDESC_CTSENA;
923 }
924
925 if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
926 series[i].RateFlags |= ATH9K_RATESERIES_2040;
927 if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
928 series[i].RateFlags |= ATH9K_RATESERIES_HALFGI;
929
930 is_sgi = !!(rates[i].flags & IEEE80211_TX_RC_SHORT_GI);
931 is_40 = !!(rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH);
932 is_sp = !!(rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
933
934 if (rates[i].flags & IEEE80211_TX_RC_MCS) {
935 /* MCS rates */
936 series[i].Rate = rix | 0x80;
937 series[i].ChSel = ath_txchainmask_reduction(sc,
938 ah->txchainmask, series[i].Rate);
939 series[i].PktDuration = ath_pkt_duration(sc, rix, len,
940 is_40, is_sgi, is_sp);
941 if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
942 series[i].RateFlags |= ATH9K_RATESERIES_STBC;
943 continue;
944 }
945
946 /* legacy rates */
947 if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
948 !(rate->flags & IEEE80211_RATE_ERP_G))
949 phy = WLAN_RC_PHY_CCK;
950 else
951 phy = WLAN_RC_PHY_OFDM;
952
953 rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx];
954 series[i].Rate = rate->hw_value;
955 if (rate->hw_value_short) {
956 if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
957 series[i].Rate |= rate->hw_value_short;
958 } else {
959 is_sp = false;
960 }
961
962 if (bf->bf_state.bfs_paprd)
963 series[i].ChSel = ah->txchainmask;
964 else
965 series[i].ChSel = ath_txchainmask_reduction(sc,
966 ah->txchainmask, series[i].Rate);
967
968 series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
969 phy, rate->bitrate * 100, len, rix, is_sp);
970 }
971
972 /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
973 if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit))
974 flags &= ~ATH9K_TXDESC_RTSENA;
975
976 /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */
977 if (flags & ATH9K_TXDESC_RTSENA)
978 flags &= ~ATH9K_TXDESC_CTSENA;
979
980 /* set dur_update_en for l-sig computation except for PS-Poll frames */
981 ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
982 bf->bf_lastbf->bf_desc,
983 !is_pspoll, ctsrate,
984 0, series, 4, flags);
985
986}
987
848static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, int len) 988static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, int len)
849{ 989{
850 struct ath_hw *ah = sc->sc_ah; 990 struct ath_hw *ah = sc->sc_ah;
@@ -1613,35 +1753,6 @@ static int setup_tx_flags(struct sk_buff *skb)
1613 return flags; 1753 return flags;
1614} 1754}
1615 1755
1616/*
1617 * rix - rate index
1618 * pktlen - total bytes (delims + data + fcs + pads + pad delims)
1619 * width - 0 for 20 MHz, 1 for 40 MHz
1620 * half_gi - to use 4us v/s 3.6 us for symbol time
1621 */
1622static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen,
1623 int width, int half_gi, bool shortPreamble)
1624{
1625 u32 nbits, nsymbits, duration, nsymbols;
1626 int streams;
1627
1628 /* find number of symbols: PLCP + data */
1629 streams = HT_RC_2_STREAMS(rix);
1630 nbits = (pktlen << 3) + OFDM_PLCP_BITS;
1631 nsymbits = bits_per_symbol[rix % 8][width] * streams;
1632 nsymbols = (nbits + nsymbits - 1) / nsymbits;
1633
1634 if (!half_gi)
1635 duration = SYMBOL_TIME(nsymbols);
1636 else
1637 duration = SYMBOL_TIME_HALFGI(nsymbols);
1638
1639 /* addup duration for legacy/ht training and signal fields */
1640 duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
1641
1642 return duration;
1643}
1644
1645u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) 1756u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
1646{ 1757{
1647 struct ath_hw *ah = sc->sc_ah; 1758 struct ath_hw *ah = sc->sc_ah;
@@ -1654,118 +1765,6 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
1654 return chainmask; 1765 return chainmask;
1655} 1766}
1656 1767
1657static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
1658{
1659 struct ath_hw *ah = sc->sc_ah;
1660 struct ath9k_11n_rate_series series[4];
1661 struct sk_buff *skb;
1662 struct ieee80211_tx_info *tx_info;
1663 struct ieee80211_tx_rate *rates;
1664 const struct ieee80211_rate *rate;
1665 struct ieee80211_hdr *hdr;
1666 int i, flags = 0;
1667 u8 rix = 0, ctsrate = 0;
1668 bool is_pspoll;
1669
1670 memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
1671
1672 skb = bf->bf_mpdu;
1673 tx_info = IEEE80211_SKB_CB(skb);
1674 rates = tx_info->control.rates;
1675 hdr = (struct ieee80211_hdr *)skb->data;
1676 is_pspoll = ieee80211_is_pspoll(hdr->frame_control);
1677
1678 /*
1679 * We check if Short Preamble is needed for the CTS rate by
1680 * checking the BSS's global flag.
1681 * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
1682 */
1683 rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info);
1684 ctsrate = rate->hw_value;
1685 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
1686 ctsrate |= rate->hw_value_short;
1687
1688 for (i = 0; i < 4; i++) {
1689 bool is_40, is_sgi, is_sp;
1690 int phy;
1691
1692 if (!rates[i].count || (rates[i].idx < 0))
1693 continue;
1694
1695 rix = rates[i].idx;
1696 series[i].Tries = rates[i].count;
1697
1698 if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
1699 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
1700 flags |= ATH9K_TXDESC_RTSENA;
1701 } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
1702 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
1703 flags |= ATH9K_TXDESC_CTSENA;
1704 }
1705
1706 if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1707 series[i].RateFlags |= ATH9K_RATESERIES_2040;
1708 if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
1709 series[i].RateFlags |= ATH9K_RATESERIES_HALFGI;
1710
1711 is_sgi = !!(rates[i].flags & IEEE80211_TX_RC_SHORT_GI);
1712 is_40 = !!(rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH);
1713 is_sp = !!(rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
1714
1715 if (rates[i].flags & IEEE80211_TX_RC_MCS) {
1716 /* MCS rates */
1717 series[i].Rate = rix | 0x80;
1718 series[i].ChSel = ath_txchainmask_reduction(sc,
1719 ah->txchainmask, series[i].Rate);
1720 series[i].PktDuration = ath_pkt_duration(sc, rix, len,
1721 is_40, is_sgi, is_sp);
1722 if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
1723 series[i].RateFlags |= ATH9K_RATESERIES_STBC;
1724 continue;
1725 }
1726
1727 /* legacy rates */
1728 if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
1729 !(rate->flags & IEEE80211_RATE_ERP_G))
1730 phy = WLAN_RC_PHY_CCK;
1731 else
1732 phy = WLAN_RC_PHY_OFDM;
1733
1734 rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx];
1735 series[i].Rate = rate->hw_value;
1736 if (rate->hw_value_short) {
1737 if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1738 series[i].Rate |= rate->hw_value_short;
1739 } else {
1740 is_sp = false;
1741 }
1742
1743 if (bf->bf_state.bfs_paprd)
1744 series[i].ChSel = ah->txchainmask;
1745 else
1746 series[i].ChSel = ath_txchainmask_reduction(sc,
1747 ah->txchainmask, series[i].Rate);
1748
1749 series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
1750 phy, rate->bitrate * 100, len, rix, is_sp);
1751 }
1752
1753 /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
1754 if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit))
1755 flags &= ~ATH9K_TXDESC_RTSENA;
1756
1757 /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */
1758 if (flags & ATH9K_TXDESC_RTSENA)
1759 flags &= ~ATH9K_TXDESC_CTSENA;
1760
1761 /* set dur_update_en for l-sig computation except for PS-Poll frames */
1762 ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
1763 bf->bf_lastbf->bf_desc,
1764 !is_pspoll, ctsrate,
1765 0, series, 4, flags);
1766
1767}
1768
1769/* 1768/*
1770 * Assign a descriptor (and sequence number if necessary, 1769 * Assign a descriptor (and sequence number if necessary,
1771 * and map buffer for DMA. Frees skb on error 1770 * and map buffer for DMA. Frees skb on error