Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 159128
b: refs/heads/master
c: 164ace3
h: refs/heads/master
v: v3
  • Loading branch information
Senthil Balasubramanian authored and John W. Linville committed Jul 24, 2009
1 parent 9061e35 commit 180fbb5
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: dd8b15b027d96f7097ae9dbaebd822a114a03c34
refs/heads/master: 164ace38536849966ffa377b1b1132993a5a375d
4 changes: 4 additions & 0 deletions trunk/drivers/net/wireless/ath/ath9k/ath9k.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])

#define ATH_TX_COMPLETE_POLL_INT 1000

enum ATH_AGGR_STATUS {
ATH_AGGR_DONE,
ATH_AGGR_BAW_CLOSED,
Expand All @@ -240,6 +242,7 @@ struct ath_txq {
u8 axq_aggr_depth;
u32 axq_totalqueued;
bool stopped;
bool axq_tx_inprogress;
struct ath_buf *axq_linkbuf;

/* first desc of the last descriptor that contains CTS */
Expand Down Expand Up @@ -605,6 +608,7 @@ struct ath_softc {
#endif
struct ath_bus_ops *bus_ops;
struct ath_beacon_config cur_beacon_conf;
struct delayed_work tx_complete_work;
};

struct ath_wiphy {
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1259,6 +1259,7 @@ void ath_detach(struct ath_softc *sc)
ath_deinit_leds(sc);
cancel_work_sync(&sc->chan_work);
cancel_delayed_work_sync(&sc->wiphy_work);
cancel_delayed_work_sync(&sc->tx_complete_work);

for (i = 0; i < sc->num_sec_wiphy; i++) {
struct ath_wiphy *aphy = sc->sec_wiphy[i];
Expand Down Expand Up @@ -1979,6 +1980,8 @@ static int ath9k_start(struct ieee80211_hw *hw)

ieee80211_wake_queues(hw);

queue_delayed_work(sc->hw->workqueue, &sc->tx_complete_work, 0);

mutex_unlock:
mutex_unlock(&sc->mutex);

Expand Down
57 changes: 43 additions & 14 deletions trunk/drivers/net/wireless/ath/ath9k/xmit.c
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
txq->axq_aggr_depth = 0;
txq->axq_totalqueued = 0;
txq->axq_linkbuf = NULL;
txq->axq_tx_inprogress = false;
sc->tx.txqsetup |= 1<<qnum;
}
return &sc->tx.txq[qnum];
Expand Down Expand Up @@ -1023,6 +1024,10 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
}

spin_lock_bh(&txq->axq_lock);
txq->axq_tx_inprogress = false;
spin_unlock_bh(&txq->axq_lock);

/* flush any pending frames if aggregation is enabled */
if (sc->sc_flags & SC_OP_TXAGGR) {
if (!retry_tx) {
Expand Down Expand Up @@ -1103,8 +1108,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
if (tid->paused)
continue;

if ((txq->axq_depth % 2) == 0)
ath_tx_sched_aggr(sc, txq, tid);
ath_tx_sched_aggr(sc, txq, tid);

/*
* add tid to round-robin queue if more frames
Expand Down Expand Up @@ -1947,19 +1951,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
if (bf->bf_stale) {
bf_held = bf;
if (list_is_last(&bf_held->list, &txq->axq_q)) {
txq->axq_link = NULL;
txq->axq_linkbuf = NULL;
spin_unlock_bh(&txq->axq_lock);

/*
* The holding descriptor is the last
* descriptor in queue. It's safe to remove
* the last holding descriptor in BH context.
*/
spin_lock_bh(&sc->tx.txbuflock);
list_move_tail(&bf_held->list, &sc->tx.txbuf);
spin_unlock_bh(&sc->tx.txbuflock);

break;
} else {
bf = list_entry(bf_held->list.next,
Expand Down Expand Up @@ -1996,6 +1988,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
txq->axq_aggr_depth--;

txok = (ds->ds_txstat.ts_status == 0);
txq->axq_tx_inprogress = false;
spin_unlock_bh(&txq->axq_lock);

if (bf_held) {
Expand Down Expand Up @@ -2029,6 +2022,40 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
}
}

void ath_tx_complete_poll_work(struct work_struct *work)
{
struct ath_softc *sc = container_of(work, struct ath_softc,
tx_complete_work.work);
struct ath_txq *txq;
int i;
bool needreset = false;

for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
if (ATH_TXQ_SETUP(sc, i)) {
txq = &sc->tx.txq[i];
spin_lock_bh(&txq->axq_lock);
if (txq->axq_depth) {
if (txq->axq_tx_inprogress) {
needreset = true;
spin_unlock_bh(&txq->axq_lock);
break;
} else {
txq->axq_tx_inprogress = true;
}
}
spin_unlock_bh(&txq->axq_lock);
}

if (needreset) {
DPRINTF(sc, ATH_DBG_RESET, "tx hung, resetting the chip\n");
ath_reset(sc, false);
}

queue_delayed_work(sc->hw->workqueue, &sc->tx_complete_work,
msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT));
}



void ath_tx_tasklet(struct ath_softc *sc)
{
Expand Down Expand Up @@ -2069,6 +2096,8 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
goto err;
}

INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);

err:
if (error != 0)
ath_tx_cleanup(sc);
Expand Down

0 comments on commit 180fbb5

Please sign in to comment.