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>
This commit is contained in:
parent
2c5a744d43
commit
c428839008
3 changed files with 55 additions and 64 deletions
|
@ -453,8 +453,6 @@ void ath_tx_tasklet(struct ath_softc *sc);
|
||||||
u32 ath_txq_depth(struct ath_softc *sc, int qnum);
|
u32 ath_txq_depth(struct ath_softc *sc, int qnum);
|
||||||
u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum);
|
u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum);
|
||||||
void ath_notify_txq_status(struct ath_softc *sc, u16 queue_depth);
|
void ath_notify_txq_status(struct ath_softc *sc, u16 queue_depth);
|
||||||
void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
|
|
||||||
struct ath_xmit_status *tx_status);
|
|
||||||
void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
|
void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
|
||||||
|
|
||||||
/**********************/
|
/**********************/
|
||||||
|
|
|
@ -341,37 +341,6 @@ void ath_get_beaconconfig(struct ath_softc *sc,
|
||||||
conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
|
conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
|
|
||||||
struct ath_xmit_status *tx_status)
|
|
||||||
{
|
|
||||||
struct ieee80211_hw *hw = sc->hw;
|
|
||||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
|
||||||
struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
|
|
||||||
|
|
||||||
DPRINTF(sc, ATH_DBG_XMIT,
|
|
||||||
"%s: TX complete: skb: %p\n", __func__, skb);
|
|
||||||
|
|
||||||
if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
|
|
||||||
tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
|
|
||||||
kfree(tx_info_priv);
|
|
||||||
tx_info->rate_driver_data[0] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tx_status->flags & ATH_TX_BAR) {
|
|
||||||
tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
|
|
||||||
tx_status->flags &= ~ATH_TX_BAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
|
|
||||||
/* Frame was ACKed */
|
|
||||||
tx_info->flags |= IEEE80211_TX_STAT_ACK;
|
|
||||||
}
|
|
||||||
|
|
||||||
tx_info->status.rates[0].count = tx_status->retries + 1;
|
|
||||||
|
|
||||||
ieee80211_tx_status(hw, skb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************/
|
/********************************/
|
||||||
/* LED functions */
|
/* LED functions */
|
||||||
/********************************/
|
/********************************/
|
||||||
|
|
|
@ -102,6 +102,37 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
|
||||||
ath9k_hw_txstart(ah, txq->axq_qnum);
|
ath9k_hw_txstart(ah, txq->axq_qnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
|
||||||
|
struct ath_xmit_status *tx_status)
|
||||||
|
{
|
||||||
|
struct ieee80211_hw *hw = sc->hw;
|
||||||
|
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||||
|
struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
|
||||||
|
|
||||||
|
DPRINTF(sc, ATH_DBG_XMIT,
|
||||||
|
"%s: TX complete: skb: %p\n", __func__, skb);
|
||||||
|
|
||||||
|
if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
|
||||||
|
tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
|
||||||
|
kfree(tx_info_priv);
|
||||||
|
tx_info->rate_driver_data[0] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tx_status->flags & ATH_TX_BAR) {
|
||||||
|
tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
|
||||||
|
tx_status->flags &= ~ATH_TX_BAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
|
||||||
|
/* Frame was ACKed */
|
||||||
|
tx_info->flags |= IEEE80211_TX_STAT_ACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
tx_info->status.rates[0].count = tx_status->retries + 1;
|
||||||
|
|
||||||
|
ieee80211_tx_status(hw, skb);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if it's okay to send out aggregates */
|
/* Check if it's okay to send out aggregates */
|
||||||
|
|
||||||
static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno)
|
static 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,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, int nbad)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
|
||||||
|
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||||
|
struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
|
||||||
|
|
||||||
|
if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
|
||||||
|
tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
|
||||||
|
|
||||||
|
if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
|
||||||
|
(bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
|
||||||
|
if (bf_isdata(bf)) {
|
||||||
|
memcpy(&tx_info_priv->tx, &ds->ds_txstat,
|
||||||
|
sizeof(tx_info_priv->tx));
|
||||||
|
tx_info_priv->n_frames = bf->bf_nframes;
|
||||||
|
tx_info_priv->n_bad_frames = nbad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Process completed xmit descriptors from the specified queue */
|
/* Process completed xmit descriptors from the specified queue */
|
||||||
|
|
||||||
static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||||
{
|
{
|
||||||
struct ath_hal *ah = sc->sc_ah;
|
struct ath_hal *ah = sc->sc_ah;
|
||||||
struct ath_buf *bf, *lastbf, *bf_held = NULL;
|
struct ath_buf *bf, *lastbf, *bf_held = NULL;
|
||||||
struct list_head bf_head;
|
struct list_head bf_head;
|
||||||
struct ath_desc *ds, *tmp_ds;
|
struct ath_desc *ds;
|
||||||
struct sk_buff *skb;
|
int txok, nbad = 0;
|
||||||
struct ieee80211_tx_info *tx_info;
|
|
||||||
struct ath_tx_info_priv *tx_info_priv;
|
|
||||||
int nacked, txok, nbad = 0, isrifs = 0;
|
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
DPRINTF(sc, ATH_DBG_QUEUE,
|
DPRINTF(sc, ATH_DBG_QUEUE,
|
||||||
|
@ -932,7 +980,6 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||||
txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
|
txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
|
||||||
txq->axq_link);
|
txq->axq_link);
|
||||||
|
|
||||||
nacked = 0;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
spin_lock_bh(&txq->axq_lock);
|
spin_lock_bh(&txq->axq_lock);
|
||||||
if (list_empty(&txq->axq_q)) {
|
if (list_empty(&txq->axq_q)) {
|
||||||
|
@ -1022,30 +1069,8 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||||
} else {
|
} else {
|
||||||
nbad = ath_tx_num_badfrms(sc, bf, txok);
|
nbad = ath_tx_num_badfrms(sc, bf, txok);
|
||||||
}
|
}
|
||||||
skb = bf->bf_mpdu;
|
|
||||||
tx_info = IEEE80211_SKB_CB(skb);
|
|
||||||
|
|
||||||
tx_info_priv =
|
ath_tx_rc_status(bf, ds, nbad);
|
||||||
(struct ath_tx_info_priv *)tx_info->rate_driver_data[0];
|
|
||||||
if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
|
|
||||||
tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
|
|
||||||
if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
|
|
||||||
(bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
|
|
||||||
if (ds->ds_txstat.ts_status == 0)
|
|
||||||
nacked++;
|
|
||||||
|
|
||||||
if (bf_isdata(bf)) {
|
|
||||||
if (isrifs)
|
|
||||||
tmp_ds = bf->bf_rifslast->bf_desc;
|
|
||||||
else
|
|
||||||
tmp_ds = ds;
|
|
||||||
memcpy(&tx_info_priv->tx,
|
|
||||||
&tmp_ds->ds_txstat,
|
|
||||||
sizeof(tx_info_priv->tx));
|
|
||||||
tx_info_priv->n_frames = bf->bf_nframes;
|
|
||||||
tx_info_priv->n_bad_frames = nbad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Complete this transmit unit
|
* Complete this transmit unit
|
||||||
|
@ -1076,7 +1101,6 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||||
ath_txq_schedule(sc, txq);
|
ath_txq_schedule(sc, txq);
|
||||||
spin_unlock_bh(&txq->axq_lock);
|
spin_unlock_bh(&txq->axq_lock);
|
||||||
}
|
}
|
||||||
return nacked;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq)
|
static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq)
|
||||||
|
|
Loading…
Add table
Reference in a new issue