aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k/xmit.c
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2008-11-17 22:39:30 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-11-26 09:47:32 -0500
commitc428839008f6638317a0db102d4e65d631c288a6 (patch)
tree64decdccf35485d1a40ec54bf00c379cd1f0fa01 /drivers/net/wireless/ath9k/xmit.c
parent2c5a744d43a6a08666930906742fbe704739ba6f (diff)
ath9k: Move TX completion routine to xmit.c
Also, use a helper function to setup RC status data when processing completed TX descriptors. Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k/xmit.c')
-rw-r--r--drivers/net/wireless/ath9k/xmit.c88
1 files changed, 56 insertions, 32 deletions
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index 93317ce9ac8a..4c9a03ed8382 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -102,6 +102,37 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
102 ath9k_hw_txstart(ah, txq->axq_qnum); 102 ath9k_hw_txstart(ah, txq->axq_qnum);
103} 103}
104 104
105static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
106 struct ath_xmit_status *tx_status)
107{
108 struct ieee80211_hw *hw = sc->hw;
109 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
110 struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
111
112 DPRINTF(sc, ATH_DBG_XMIT,
113 "%s: TX complete: skb: %p\n", __func__, skb);
114
115 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
116 tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
117 kfree(tx_info_priv);
118 tx_info->rate_driver_data[0] = NULL;
119 }
120
121 if (tx_status->flags & ATH_TX_BAR) {
122 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
123 tx_status->flags &= ~ATH_TX_BAR;
124 }
125
126 if (!(tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
127 /* Frame was ACKed */
128 tx_info->flags |= IEEE80211_TX_STAT_ACK;
129 }
130
131 tx_info->status.rates[0].count = tx_status->retries + 1;
132
133 ieee80211_tx_status(hw, skb);
134}
135
105/* Check if it's okay to send out aggregates */ 136/* Check if it's okay to send out aggregates */
106 137
107static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno) 138static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno)
@@ -913,18 +944,35 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
913 return; 944 return;
914} 945}
915 946
947static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, int nbad)
948{
949 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
950 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
951 struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
952
953 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
954 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
955
956 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
957 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
958 if (bf_isdata(bf)) {
959 memcpy(&tx_info_priv->tx, &ds->ds_txstat,
960 sizeof(tx_info_priv->tx));
961 tx_info_priv->n_frames = bf->bf_nframes;
962 tx_info_priv->n_bad_frames = nbad;
963 }
964 }
965}
966
916/* Process completed xmit descriptors from the specified queue */ 967/* Process completed xmit descriptors from the specified queue */
917 968
918static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) 969static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
919{ 970{
920 struct ath_hal *ah = sc->sc_ah; 971 struct ath_hal *ah = sc->sc_ah;
921 struct ath_buf *bf, *lastbf, *bf_held = NULL; 972 struct ath_buf *bf, *lastbf, *bf_held = NULL;
922 struct list_head bf_head; 973 struct list_head bf_head;
923 struct ath_desc *ds, *tmp_ds; 974 struct ath_desc *ds;
924 struct sk_buff *skb; 975 int txok, nbad = 0;
925 struct ieee80211_tx_info *tx_info;
926 struct ath_tx_info_priv *tx_info_priv;
927 int nacked, txok, nbad = 0, isrifs = 0;
928 int status; 976 int status;
929 977
930 DPRINTF(sc, ATH_DBG_QUEUE, 978 DPRINTF(sc, ATH_DBG_QUEUE,
@@ -932,7 +980,6 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
932 txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), 980 txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
933 txq->axq_link); 981 txq->axq_link);
934 982
935 nacked = 0;
936 for (;;) { 983 for (;;) {
937 spin_lock_bh(&txq->axq_lock); 984 spin_lock_bh(&txq->axq_lock);
938 if (list_empty(&txq->axq_q)) { 985 if (list_empty(&txq->axq_q)) {
@@ -1022,30 +1069,8 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1022 } else { 1069 } else {
1023 nbad = ath_tx_num_badfrms(sc, bf, txok); 1070 nbad = ath_tx_num_badfrms(sc, bf, txok);
1024 } 1071 }
1025 skb = bf->bf_mpdu; 1072
1026 tx_info = IEEE80211_SKB_CB(skb); 1073 ath_tx_rc_status(bf, ds, nbad);
1027
1028 tx_info_priv =
1029 (struct ath_tx_info_priv *)tx_info->rate_driver_data[0];
1030 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
1031 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
1032 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
1033 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
1034 if (ds->ds_txstat.ts_status == 0)
1035 nacked++;
1036
1037 if (bf_isdata(bf)) {
1038 if (isrifs)
1039 tmp_ds = bf->bf_rifslast->bf_desc;
1040 else
1041 tmp_ds = ds;
1042 memcpy(&tx_info_priv->tx,
1043 &tmp_ds->ds_txstat,
1044 sizeof(tx_info_priv->tx));
1045 tx_info_priv->n_frames = bf->bf_nframes;
1046 tx_info_priv->n_bad_frames = nbad;
1047 }
1048 }
1049 1074
1050 /* 1075 /*
1051 * Complete this transmit unit 1076 * Complete this transmit unit
@@ -1076,7 +1101,6 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1076 ath_txq_schedule(sc, txq); 1101 ath_txq_schedule(sc, txq);
1077 spin_unlock_bh(&txq->axq_lock); 1102 spin_unlock_bh(&txq->axq_lock);
1078 } 1103 }
1079 return nacked;
1080} 1104}
1081 1105
1082static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq) 1106static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq)