* [PATCH v3 95/97] ath9k: Enable TXOK and TXERR interrupts for TX EDMA
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan
In-Reply-To: <1271367582-992-1-git-send-email-lrodriguez@atheros.com>
From: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
drivers/net/wireless/ath/ath9k/xmit.c | 15 ++++++++++-----
1 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 90e629f..cac178a 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -886,11 +886,16 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
* The UAPSD queue is an exception, since we take a desc-
* based intr on the EOSP frames.
*/
- if (qtype == ATH9K_TX_QUEUE_UAPSD)
- qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
- else
- qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
- TXQ_FLAG_TXDESCINT_ENABLE;
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+ qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE |
+ TXQ_FLAG_TXERRINT_ENABLE;
+ } else {
+ if (qtype == ATH9K_TX_QUEUE_UAPSD)
+ qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
+ else
+ qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
+ TXQ_FLAG_TXDESCINT_ENABLE;
+ }
qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi);
if (qnum == -1) {
/*
--
1.6.3.3
^ permalink raw reply related
* [PATCH v3 96/97] ath9k_hw: Abort rx if hw is not coming out of full sleep in reset
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan
In-Reply-To: <1271367582-992-1-git-send-email-lrodriguez@atheros.com>
From: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
drivers/net/wireless/ath/ath9k/hw.c | 7 +++++++
drivers/net/wireless/ath/ath9k/mac.c | 8 ++++++++
drivers/net/wireless/ath/ath9k/mac.h | 1 +
3 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 44077cb..b9921e9 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1138,6 +1138,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ah->txchainmask = common->tx_chainmask;
ah->rxchainmask = common->rx_chainmask;
+ if (!ah->chip_fullsleep) {
+ ath9k_hw_abortpcurecv(ah);
+ if (!ath9k_hw_stopdmarecv(ah))
+ ath_print(common, ATH_DBG_XMIT,
+ "Failed to stop receive dma\n");
+ }
+
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
return -EIO;
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index c003baf..b54e857 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -747,6 +747,14 @@ void ath9k_hw_stoppcurecv(struct ath_hw *ah)
}
EXPORT_SYMBOL(ath9k_hw_stoppcurecv);
+void ath9k_hw_abortpcurecv(struct ath_hw *ah)
+{
+ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
+
+ ath9k_hw_disable_mib_counters(ah);
+}
+EXPORT_SYMBOL(ath9k_hw_abortpcurecv);
+
bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
{
#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 346d84a..68eb8d0 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -711,6 +711,7 @@ bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
void ath9k_hw_startpcureceive(struct ath_hw *ah);
void ath9k_hw_stoppcurecv(struct ath_hw *ah);
+void ath9k_hw_abortpcurecv(struct ath_hw *ah);
bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
int ath9k_hw_beaconq_setup(struct ath_hw *ah);
--
1.6.3.3
^ permalink raw reply related
* [PATCH v3 91/97] ath9k: Add Tx EDMA support
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
To: linville
Cc: linux-wireless, Vasanthakumar Thiagarajan, Luis R. Rodriguez,
Felix Fietkau
In-Reply-To: <1271367582-992-1-git-send-email-lrodriguez@atheros.com>
From: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 6 +
drivers/net/wireless/ath/ath9k/main.c | 8 +-
drivers/net/wireless/ath/ath9k/xmit.c | 264 +++++++++++++++++++++++++-------
3 files changed, 218 insertions(+), 60 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 2d3e42a..fbb7dec 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -190,6 +190,7 @@ enum ATH_AGGR_STATUS {
ATH_AGGR_LIMITED,
};
+#define ATH_TXFIFO_DEPTH 8
struct ath_txq {
u32 axq_qnum;
u32 *axq_link;
@@ -199,6 +200,10 @@ struct ath_txq {
bool stopped;
bool axq_tx_inprogress;
struct list_head axq_acq;
+ struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
+ struct list_head txq_fifo_pending;
+ u8 txq_headidx;
+ u8 txq_tailidx;
};
#define AGGR_CLEANUP BIT(1)
@@ -268,6 +273,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath_tx_control *txctl);
void ath_tx_tasklet(struct ath_softc *sc);
+void ath_tx_edma_tasklet(struct ath_softc *sc);
void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 92f6fdc..1f4ea74 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -429,8 +429,12 @@ void ath9k_tasklet(unsigned long data)
spin_unlock_bh(&sc->rx.rxflushlock);
}
- if (status & ATH9K_INT_TX)
- ath_tx_tasklet(sc);
+ if (status & ATH9K_INT_TX) {
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+ ath_tx_edma_tasklet(sc);
+ else
+ ath_tx_tasklet(sc);
+ }
if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
/*
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index f9f7445..c2b4503 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -92,7 +92,6 @@ static int ath_max_4ms_framelen[3][16] = {
}
};
-
/*********************/
/* Aggregation logic */
/*********************/
@@ -379,7 +378,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
}
}
- if (bf_next == NULL) {
+ if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
+ bf_next == NULL) {
/*
* Make sure the last desc is reclaimed if it
* not a holding desc.
@@ -413,36 +413,43 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
!txfail, sendbar);
} else {
/* retry the un-acked ones */
- if (bf->bf_next == NULL && bf_last->bf_stale) {
- struct ath_buf *tbf;
-
- tbf = ath_clone_txbuf(sc, bf_last);
- /*
- * Update tx baw and complete the frame with
- * failed status if we run out of tx buf
- */
- if (!tbf) {
- spin_lock_bh(&txq->axq_lock);
- ath_tx_update_baw(sc, tid,
- bf->bf_seqno);
- spin_unlock_bh(&txq->axq_lock);
-
- bf->bf_state.bf_type |= BUF_XRETRY;
- ath_tx_rc_status(bf, ts, nbad,
- 0, false);
- ath_tx_complete_buf(sc, bf, txq,
- &bf_head, ts, 0, 0);
- break;
+ if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) {
+ if (bf->bf_next == NULL && bf_last->bf_stale) {
+ struct ath_buf *tbf;
+
+ tbf = ath_clone_txbuf(sc, bf_last);
+ /*
+ * Update tx baw and complete the
+ * frame with failed status if we
+ * run out of tx buf.
+ */
+ if (!tbf) {
+ spin_lock_bh(&txq->axq_lock);
+ ath_tx_update_baw(sc, tid,
+ bf->bf_seqno);
+ spin_unlock_bh(&txq->axq_lock);
+
+ bf->bf_state.bf_type |=
+ BUF_XRETRY;
+ ath_tx_rc_status(bf, ts, nbad,
+ 0, false);
+ ath_tx_complete_buf(sc, bf, txq,
+ &bf_head,
+ ts, 0, 0);
+ break;
+ }
+
+ ath9k_hw_cleartxdesc(sc->sc_ah,
+ tbf->bf_desc);
+ list_add_tail(&tbf->list, &bf_head);
+ } else {
+ /*
+ * Clear descriptor status words for
+ * software retry
+ */
+ ath9k_hw_cleartxdesc(sc->sc_ah,
+ bf->bf_desc);
}
-
- ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc);
- list_add_tail(&tbf->list, &bf_head);
- } else {
- /*
- * Clear descriptor status words for
- * software retry
- */
- ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc);
}
/*
@@ -855,7 +862,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_tx_queue_info qi;
- int qnum;
+ int qnum, i;
memset(&qi, 0, sizeof(qi));
qi.tqi_subtype = subtype;
@@ -910,6 +917,11 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
txq->axq_depth = 0;
txq->axq_tx_inprogress = false;
sc->tx.txqsetup |= 1<<qnum;
+
+ txq->txq_headidx = txq->txq_tailidx = 0;
+ for (i = 0; i < ATH_TXFIFO_DEPTH; i++)
+ INIT_LIST_HEAD(&txq->txq_fifo[i]);
+ INIT_LIST_HEAD(&txq->txq_fifo_pending);
}
return &sc->tx.txq[qnum];
}
@@ -1042,30 +1054,49 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
for (;;) {
spin_lock_bh(&txq->axq_lock);
- if (list_empty(&txq->axq_q)) {
- txq->axq_link = NULL;
- spin_unlock_bh(&txq->axq_lock);
- break;
- }
-
- bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+ if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
+ txq->txq_headidx = txq->txq_tailidx = 0;
+ spin_unlock_bh(&txq->axq_lock);
+ break;
+ } else {
+ bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
+ struct ath_buf, list);
+ }
+ } else {
+ if (list_empty(&txq->axq_q)) {
+ txq->axq_link = NULL;
+ spin_unlock_bh(&txq->axq_lock);
+ break;
+ }
+ bf = list_first_entry(&txq->axq_q, struct ath_buf,
+ list);
- if (bf->bf_stale) {
- list_del(&bf->list);
- spin_unlock_bh(&txq->axq_lock);
+ if (bf->bf_stale) {
+ list_del(&bf->list);
+ spin_unlock_bh(&txq->axq_lock);
- spin_lock_bh(&sc->tx.txbuflock);
- list_add_tail(&bf->list, &sc->tx.txbuf);
- spin_unlock_bh(&sc->tx.txbuflock);
- continue;
+ spin_lock_bh(&sc->tx.txbuflock);
+ list_add_tail(&bf->list, &sc->tx.txbuf);
+ spin_unlock_bh(&sc->tx.txbuflock);
+ continue;
+ }
}
lastbf = bf->bf_lastbf;
if (!retry_tx)
lastbf->bf_tx_aborted = true;
- /* remove ath_buf's of the same mpdu from txq */
- list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+ list_cut_position(&bf_head,
+ &txq->txq_fifo[txq->txq_tailidx],
+ &lastbf->list);
+ INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
+ } else {
+ /* remove ath_buf's of the same mpdu from txq */
+ list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
+ }
+
txq->axq_depth--;
spin_unlock_bh(&txq->axq_lock);
@@ -1088,6 +1119,27 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
spin_unlock_bh(&txq->axq_lock);
}
}
+
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+ spin_lock_bh(&txq->axq_lock);
+ while (!list_empty(&txq->txq_fifo_pending)) {
+ bf = list_first_entry(&txq->txq_fifo_pending,
+ struct ath_buf, list);
+ list_cut_position(&bf_head,
+ &txq->txq_fifo_pending,
+ &bf->bf_lastbf->list);
+ spin_unlock_bh(&txq->axq_lock);
+
+ if (bf_isampdu(bf))
+ ath_tx_complete_aggr(sc, txq, bf, &bf_head,
+ &ts, 0);
+ else
+ ath_tx_complete_buf(sc, bf, txq, &bf_head,
+ &ts, 0, 0);
+ spin_lock_bh(&txq->axq_lock);
+ }
+ spin_unlock_bh(&txq->axq_lock);
+ }
}
void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
@@ -1225,25 +1277,47 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
bf = list_first_entry(head, struct ath_buf, list);
- list_splice_tail_init(head, &txq->axq_q);
- txq->axq_depth++;
-
ath_print(common, ATH_DBG_QUEUE,
"qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
- if (txq->axq_link == NULL) {
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+ if (txq->axq_depth >= ATH_TXFIFO_DEPTH) {
+ list_splice_tail_init(head, &txq->txq_fifo_pending);
+ return;
+ }
+ if (!list_empty(&txq->txq_fifo[txq->txq_headidx]))
+ ath_print(common, ATH_DBG_XMIT,
+ "Initializing tx fifo %d which "
+ "is non-empty\n",
+ txq->txq_headidx);
+ INIT_LIST_HEAD(&txq->txq_fifo[txq->txq_headidx]);
+ list_splice_init(head, &txq->txq_fifo[txq->txq_headidx]);
+ INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH);
ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
ath_print(common, ATH_DBG_XMIT,
"TXDP[%u] = %llx (%p)\n",
txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
} else {
- *txq->axq_link = bf->bf_daddr;
- ath_print(common, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
- txq->axq_qnum, txq->axq_link,
- ito64(bf->bf_daddr), bf->bf_desc);
+ list_splice_tail_init(head, &txq->axq_q);
+
+ if (txq->axq_link == NULL) {
+ ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
+ ath_print(common, ATH_DBG_XMIT,
+ "TXDP[%u] = %llx (%p)\n",
+ txq->axq_qnum, ito64(bf->bf_daddr),
+ bf->bf_desc);
+ } else {
+ *txq->axq_link = bf->bf_daddr;
+ ath_print(common, ATH_DBG_XMIT,
+ "link[%u] (%p)=%llx (%p)\n",
+ txq->axq_qnum, txq->axq_link,
+ ito64(bf->bf_daddr), bf->bf_desc);
+ }
+ ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc,
+ &txq->axq_link);
+ ath9k_hw_txstart(ah, txq->axq_qnum);
}
- ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc, &txq->axq_link);
- ath9k_hw_txstart(ah, txq->axq_qnum);
+ txq->axq_depth++;
}
static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
@@ -2140,6 +2214,80 @@ void ath_tx_tasklet(struct ath_softc *sc)
}
}
+void ath_tx_edma_tasklet(struct ath_softc *sc)
+{
+ struct ath_tx_status txs;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_txq *txq;
+ struct ath_buf *bf, *lastbf;
+ struct list_head bf_head;
+ int status;
+ int txok;
+
+ for (;;) {
+ status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
+ if (status == -EINPROGRESS)
+ break;
+ if (status == -EIO) {
+ ath_print(common, ATH_DBG_XMIT,
+ "Error processing tx status\n");
+ break;
+ }
+
+ /* Skip beacon completions */
+ if (txs.qid == sc->beacon.beaconq)
+ continue;
+
+ txq = &sc->tx.txq[txs.qid];
+
+ spin_lock_bh(&txq->axq_lock);
+ if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) {
+ spin_unlock_bh(&txq->axq_lock);
+ return;
+ }
+
+ bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx],
+ struct ath_buf, list);
+ lastbf = bf->bf_lastbf;
+
+ INIT_LIST_HEAD(&bf_head);
+ list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx],
+ &lastbf->list);
+ INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
+ txq->axq_depth--;
+ txq->axq_tx_inprogress = false;
+ spin_unlock_bh(&txq->axq_lock);
+
+ txok = !(txs.ts_status & ATH9K_TXERR_MASK);
+
+ if (!bf_isampdu(bf)) {
+ bf->bf_retries = txs.ts_longretry;
+ if (txs.ts_status & ATH9K_TXERR_XRETRY)
+ bf->bf_state.bf_type |= BUF_XRETRY;
+ ath_tx_rc_status(bf, &txs, 0, txok, true);
+ }
+
+ if (bf_isampdu(bf))
+ ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok);
+ else
+ ath_tx_complete_buf(sc, bf, txq, &bf_head,
+ &txs, txok, 0);
+
+ spin_lock_bh(&txq->axq_lock);
+ if (!list_empty(&txq->txq_fifo_pending)) {
+ INIT_LIST_HEAD(&bf_head);
+ bf = list_first_entry(&txq->txq_fifo_pending,
+ struct ath_buf, list);
+ list_cut_position(&bf_head, &txq->txq_fifo_pending,
+ &bf->bf_lastbf->list);
+ ath_tx_txqaddbuf(sc, txq, &bf_head);
+ } else if (sc->sc_flags & SC_OP_TXAGGR)
+ ath_txq_schedule(sc, txq);
+ spin_unlock_bh(&txq->axq_lock);
+ }
+}
+
/*****************/
/* Init, Cleanup */
/*****************/
--
1.6.3.3
^ permalink raw reply related
* [PATCH v3 88/97] ath9k: Setup appropriate tx desc for regular dma and edma
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan
In-Reply-To: <1271367582-992-1-git-send-email-lrodriguez@atheros.com>
From: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 2 +-
drivers/net/wireless/ath/ath9k/init.c | 26 ++++++++++++++++----------
drivers/net/wireless/ath/ath9k/recv.c | 2 +-
drivers/net/wireless/ath/ath9k/xmit.c | 4 ++--
4 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index a11d830..f67be52 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -123,7 +123,7 @@ struct ath_descdma {
int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
struct list_head *head, const char *name,
- int nbuf, int ndesc);
+ int nbuf, int ndesc, bool is_tx);
void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
struct list_head *head);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 9779646..299ec05 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -235,31 +235,37 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
*/
int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
struct list_head *head, const char *name,
- int nbuf, int ndesc)
+ int nbuf, int ndesc, bool is_tx)
{
#define DS2PHYS(_dd, _ds) \
((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ath_desc *ds;
+ u8 *ds;
struct ath_buf *bf;
- int i, bsize, error;
+ int i, bsize, error, desc_len;
ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
name, nbuf, ndesc);
INIT_LIST_HEAD(head);
+
+ if (is_tx)
+ desc_len = sc->sc_ah->caps.tx_desc_len;
+ else
+ desc_len = sizeof(struct ath_desc);
+
/* ath_desc must be a multiple of DWORDs */
- if ((sizeof(struct ath_desc) % 4) != 0) {
+ if ((desc_len % 4) != 0) {
ath_print(common, ATH_DBG_FATAL,
"ath_desc not DWORD aligned\n");
- BUG_ON((sizeof(struct ath_desc) % 4) != 0);
+ BUG_ON((desc_len % 4) != 0);
error = -ENOMEM;
goto fail;
}
- dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
+ dd->dd_desc_len = desc_len * nbuf * ndesc;
/*
* Need additional DMA memory because we can't use
@@ -272,7 +278,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
u32 dma_len;
while (ndesc_skipped) {
- dma_len = ndesc_skipped * sizeof(struct ath_desc);
+ dma_len = ndesc_skipped * desc_len;
dd->dd_desc_len += dma_len;
ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
@@ -286,7 +292,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
error = -ENOMEM;
goto fail;
}
- ds = dd->dd_desc;
+ ds = (u8 *) dd->dd_desc;
ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
name, ds, (u32) dd->dd_desc_len,
ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
@@ -300,7 +306,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
}
dd->dd_bufptr = bf;
- for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
+ for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
bf->bf_desc = ds;
bf->bf_daddr = DS2PHYS(dd, ds);
@@ -316,7 +322,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
((caddr_t) dd->dd_desc +
dd->dd_desc_len));
- ds += ndesc;
+ ds += (desc_len * ndesc);
bf->bf_desc = ds;
bf->bf_daddr = DS2PHYS(dd, ds);
}
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index cb4995c..ac60c4e 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -325,7 +325,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
/* Initialize rx descriptors */
error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
- "rx", nbufs, 1);
+ "rx", nbufs, 1, 0);
if (error != 0) {
ath_print(common, ATH_DBG_FATAL,
"failed to allocate rx descriptors: %d\n",
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 7dae199..c32da05 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2152,7 +2152,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
spin_lock_init(&sc->tx.txbuflock);
error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
- "tx", nbufs, 1);
+ "tx", nbufs, 1, 1);
if (error != 0) {
ath_print(common, ATH_DBG_FATAL,
"Failed to allocate tx descriptors: %d\n", error);
@@ -2160,7 +2160,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
}
error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
- "beacon", ATH_BCBUF, 1);
+ "beacon", ATH_BCBUF, 1, 0);
if (error != 0) {
ath_print(common, ATH_DBG_FATAL,
"Failed to allocate beacon descriptors: %d\n", error);
--
1.6.3.3
^ permalink raw reply related
* [PATCH v3 93/97] ath9k_hw: add LDPC support for AR9003
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1271367582-992-1-git-send-email-lrodriguez@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath9k/ar9003_mac.c | 3 ++-
drivers/net/wireless/ath/ath9k/hw.c | 2 +-
drivers/net/wireless/ath/ath9k/hw.h | 1 +
drivers/net/wireless/ath/ath9k/mac.h | 2 ++
4 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 582c880..7d111fb 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -330,7 +330,8 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
| (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
| (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
- ads->ctl17 = SM(keyType, AR_EncrType);
+ ads->ctl17 = SM(keyType, AR_EncrType) |
+ (flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0);
ads->ctl18 = 0;
ads->ctl19 = AR_Not_Sounding;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 4092090..44077cb 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2089,7 +2089,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
}
if (AR_SREV_9300_20_OR_LATER(ah)) {
- pCap->hw_caps |= ATH9K_HW_CAP_EDMA;
+ pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_LDPC;
pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH;
pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH;
pCap->rx_status_len = sizeof(struct ar9003_rxs);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 9d3796a..7ce5420 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -179,6 +179,7 @@ enum ath9k_hw_caps {
ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(16),
ATH9K_HW_CAP_EDMA = BIT(17),
ATH9K_HW_CAP_RAC_SUPPORTED = BIT(18),
+ ATH9K_HW_CAP_LDPC = BIT(19),
};
enum ath9k_capability_type {
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index b591dc2..346d84a 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -264,6 +264,7 @@ struct ath_desc {
#define ATH9K_TXDESC_VMF 0x0100
#define ATH9K_TXDESC_FRAG_IS_ON 0x0200
#define ATH9K_TXDESC_LOWRXCHAIN 0x0400
+#define ATH9K_TXDESC_LDPC 0x00010000
#define ATH9K_RXDESC_INTREQ 0x0020
@@ -413,6 +414,7 @@ struct ar5416_desc {
#define AR_EncrType 0x0c000000
#define AR_EncrType_S 26
#define AR_TxCtlRsvd61 0xf0000000
+#define AR_LDPC 0x80000000
#define AR_2040_0 0x00000001
#define AR_GI0 0x00000002
--
1.6.3.3
^ permalink raw reply related
* [PATCH v3 97/97] ath9k_hw: add the PCI ID for the first AR9300 device
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1271367582-992-1-git-send-email-lrodriguez@atheros.com>
The first AR9003 hardware family device supported is the
AR9300, which has the vendor:device id 168c:0030
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath9k/pci.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 1ec836c..257b10b 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -28,6 +28,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
{ PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
{ PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
{ PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
+ { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
{ 0 }
};
--
1.6.3.3
^ permalink raw reply related
* [PATCH v3 89/97] ath9k: Initialize and configure tx status for EDMA
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan
In-Reply-To: <1271367582-992-1-git-send-email-lrodriguez@atheros.com>
From: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Also add a function to clean up tx status ring.
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 6 +++-
drivers/net/wireless/ath/ath9k/hw.c | 1 +
drivers/net/wireless/ath/ath9k/hw.h | 1 +
drivers/net/wireless/ath/ath9k/xmit.c | 46 +++++++++++++++++++++++++++++++-
4 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index f67be52..2d3e42a 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -114,8 +114,10 @@ enum buffer_type {
#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
+#define ATH_TXSTATUS_RING_SIZE 64
+
struct ath_descdma {
- struct ath_desc *dd_desc;
+ void *dd_desc;
dma_addr_t dd_desc_paddr;
u32 dd_desc_len;
struct ath_buf *dd_bufptr;
@@ -515,6 +517,8 @@ struct ath_softc {
struct ath_beacon_config cur_beacon_conf;
struct delayed_work tx_complete_work;
struct ath_btcoex btcoex;
+
+ struct ath_descdma txsdma;
};
struct ath_wiphy {
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 1f06ac0..4092090 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2094,6 +2094,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH;
pCap->rx_status_len = sizeof(struct ar9003_rxs);
pCap->tx_desc_len = sizeof(struct ar9003_txc);
+ pCap->txs_len = sizeof(struct ar9003_txs);
} else {
pCap->tx_desc_len = sizeof(struct ath_desc);
}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index b711ec2..9d3796a 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -209,6 +209,7 @@ struct ath9k_hw_capabilities {
u8 rx_lp_qdepth;
u8 rx_status_len;
u8 tx_desc_len;
+ u8 txs_len;
};
struct ath9k_ops_config {
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index c32da05..f9f7445 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2144,6 +2144,41 @@ void ath_tx_tasklet(struct ath_softc *sc)
/* Init, Cleanup */
/*****************/
+static int ath_txstatus_setup(struct ath_softc *sc, int size)
+{
+ struct ath_descdma *dd = &sc->txsdma;
+ u8 txs_len = sc->sc_ah->caps.txs_len;
+
+ dd->dd_desc_len = size * txs_len;
+ dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
+ &dd->dd_desc_paddr, GFP_KERNEL);
+ if (!dd->dd_desc)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int ath_tx_edma_init(struct ath_softc *sc)
+{
+ int err;
+
+ err = ath_txstatus_setup(sc, ATH_TXSTATUS_RING_SIZE);
+ if (!err)
+ ath9k_hw_setup_statusring(sc->sc_ah, sc->txsdma.dd_desc,
+ sc->txsdma.dd_desc_paddr,
+ ATH_TXSTATUS_RING_SIZE);
+
+ return err;
+}
+
+static void ath_tx_edma_cleanup(struct ath_softc *sc)
+{
+ struct ath_descdma *dd = &sc->txsdma;
+
+ dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+ dd->dd_desc_paddr);
+}
+
int ath_tx_init(struct ath_softc *sc, int nbufs)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -2160,7 +2195,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
}
error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
- "beacon", ATH_BCBUF, 1, 0);
+ "beacon", ATH_BCBUF, 1, 1);
if (error != 0) {
ath_print(common, ATH_DBG_FATAL,
"Failed to allocate beacon descriptors: %d\n", error);
@@ -2169,6 +2204,12 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+ error = ath_tx_edma_init(sc);
+ if (error)
+ goto err;
+ }
+
err:
if (error != 0)
ath_tx_cleanup(sc);
@@ -2183,6 +2224,9 @@ void ath_tx_cleanup(struct ath_softc *sc)
if (sc->tx.txdma.dd_desc_len != 0)
ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
+
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+ ath_tx_edma_cleanup(sc);
}
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
--
1.6.3.3
^ permalink raw reply related
* [PATCH v3 94/97] ath9k: add LDPC support
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1271367582-992-1-git-send-email-lrodriguez@atheros.com>
LDPC is enabled by the rate control if the its determined
that the target peer supports LDPC. We would have already
intersected the HT capabilities so if our peer supports
LDPC so do we.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath9k/init.c | 3 +++
drivers/net/wireless/ath/ath9k/rc.c | 9 +++++++++
drivers/net/wireless/ath/ath9k/xmit.c | 14 ++++++++++----
3 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 299ec05..ca6e781 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -191,6 +191,9 @@ static void setup_ht_cap(struct ath_softc *sc,
IEEE80211_HT_CAP_SGI_40 |
IEEE80211_HT_CAP_DSSSCCK40;
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
+ ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
+
ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index ee81291..bf3ad7a 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -691,6 +691,15 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
rate_table = sc->cur_rate_table;
rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
+ /*
+ * If we're in HT mode and both us and our peer supports LDPC.
+ * We don't need to check our own device's capabilities as our own
+ * ht capabilities would have already been intersected with our peer's.
+ */
+ if (conf_is_ht(&sc->hw->conf) &&
+ (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING))
+ tx_info->flags |= IEEE80211_TX_CTL_LDPC;
+
if (is_probe) {
/* set one try for probe rates. For the
* probes don't enable rts */
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index c2b4503..90e629f 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1483,8 +1483,7 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb,
INCR(tid->seq_next, IEEE80211_SEQ_MAX);
}
-static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
- struct ath_txq *txq)
+static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc)
{
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
int flags = 0;
@@ -1495,6 +1494,9 @@ static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
flags |= ATH9K_TXDESC_NOACK;
+ if (use_ldpc)
+ flags |= ATH9K_TXDESC_LDPC;
+
return flags;
}
@@ -1646,6 +1648,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
int hdrlen;
__le16 fc;
int padpos, padsize;
+ bool use_ldpc = false;
tx_info->pad[0] = 0;
switch (txctl->frame_type) {
@@ -1672,10 +1675,13 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
bf->bf_frmlen -= padsize;
}
- if (conf_is_ht(&hw->conf))
+ if (conf_is_ht(&hw->conf)) {
bf->bf_state.bf_type |= BUF_HT;
+ if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
+ use_ldpc = true;
+ }
- bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
+ bf->bf_flags = setup_tx_flags(skb, use_ldpc);
bf->bf_keytype = get_hw_crypto_keytype(skb);
if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
--
1.6.3.3
^ permalink raw reply related
* [PATCH v3 92/97] mac80211: add LDPC control flag
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1271367582-992-1-git-send-email-lrodriguez@atheros.com>
LDPC will be enabled through the rate control algorithm
for each buffer the the tx_info flags.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
include/net/mac80211.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index dcf3c5f..75056dd 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -274,6 +274,7 @@ struct ieee80211_bss_conf {
* @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211
* MLME command (internal to mac80211 to figure out whether to send TX
* status to user space)
+ * @IEEE80211_TX_CTL_LDPC: tells the driver to use LDPC for this frame
*/
enum mac80211_tx_control_flags {
IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
@@ -297,6 +298,7 @@ enum mac80211_tx_control_flags {
IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19),
IEEE80211_TX_INTFL_HAS_RADIOTAP = BIT(20),
IEEE80211_TX_INTFL_NL80211_FRAME_TX = BIT(21),
+ IEEE80211_TX_CTL_LDPC = BIT(22),
};
/**
--
1.6.3.3
^ permalink raw reply related
* [PATCH v3 87/97] ath9k_hw: set cwmin and cwmax to 0 for for AR9003 upon txq reset
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1271367582-992-1-git-send-email-lrodriguez@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath9k/mac.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 44ea43a..c003baf 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -533,6 +533,12 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
| AR_D_MISC_BEACON_USE
| AR_D_MISC_POST_FR_BKOFF_DIS);
+ /* cwmin and cwmax should be 0 for beacon queue */
+ if (AR_SREV_9300_20_OR_LATER(ah)) {
+ REG_WRITE(ah, AR_DLCL_IFS(q), SM(0, AR_D_LCL_IFS_CWMIN)
+ | SM(0, AR_D_LCL_IFS_CWMAX)
+ | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
+ }
break;
case ATH9K_TX_QUEUE_CAB:
REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
--
1.6.3.3
^ permalink raw reply related
* [PATCH v3 90/97] ath9k_hw: Compute pointer checksum over the link descriptor
From: Luis R. Rodriguez @ 2010-04-15 21:39 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Vasanthakumar Thiagarajan, Felix Fietkau
In-Reply-To: <1271367582-992-1-git-send-email-lrodriguez@atheros.com>
From: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
drivers/net/wireless/ath/ath9k/ar9003_mac.c | 36 +++++++++++++++-----------
1 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 1a8c1ba..582c880 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -21,14 +21,33 @@ static void ar9003_hw_rx_enable(struct ath_hw *hw)
REG_WRITE(hw, AR_CR, 0);
}
+static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
+{
+ int checksum;
+
+ checksum = ads->info + ads->link
+ + ads->data0 + ads->ctl3
+ + ads->data1 + ads->ctl5
+ + ads->data2 + ads->ctl7
+ + ads->data3 + ads->ctl9;
+
+ return ((checksum & 0xffff) + (checksum >> 16)) & AR_TxPtrChkSum;
+}
+
static void ar9003_hw_set_desc_link(void *ds, u32 ds_link)
{
- ((struct ar9003_txc *) ds)->link = ds_link;
+ struct ar9003_txc *ads = ds;
+
+ ads->link = ds_link;
+ ads->ctl10 &= ~AR_TxPtrChkSum;
+ ads->ctl10 |= ar9003_calc_ptr_chksum(ads);
}
static void ar9003_hw_get_desc_link(void *ds, u32 **ds_link)
{
- *ds_link = &((struct ar9003_txc *) ds)->link;
+ struct ar9003_txc *ads = ds;
+
+ *ds_link = &ads->link;
}
static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
@@ -168,19 +187,6 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
return true;
}
-static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
-{
- int checksum;
-
- checksum = ads->info + ads->link
- + ads->data0 + ads->ctl3
- + ads->data1 + ads->ctl5
- + ads->data2 + ads->ctl7
- + ads->data3 + ads->ctl9;
-
- return ((checksum & 0xffff) + (checksum >> 16)) & AR_TxPtrChkSum;
-}
-
static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
bool is_firstseg, bool is_lastseg,
const void *ds0, dma_addr_t buf_addr,
--
1.6.3.3
^ permalink raw reply related
* [PATCH] ath5k/ath9k: Fix 64 bits TSF reads
From: Benoit Papillault @ 2010-04-15 22:07 UTC (permalink / raw)
To: lrodriguez
Cc: ath5k-devel, ath9k-devel, linux-wireless, derek,
Benoit Papillault
According to tests, both TSF lower and upper registers kept counting, so
the higher part could have been updated after the lower part has been
read, as shown in the following log where the upper part is read first
and the lower part next.
tsf = {00000003-fffffffd}
tsf = {00000003-00000001}
tsf = {00000004-0000000b}
This patch corrects this by checking that the upper part has not been
changed while the lower part was read. It has been tested in an IBSS
network where artifical IBSS merges have been done in order to trigger
hundreds of rollover for the TSF lower part.
It follows the logic mentionned by Derek, with only 2 register reads
needed at each additional steps instead of 3 (the minimum number of
register reads is still 3).
Signed-off-by: Benoit Papillault <benoit.papillault@free.fr>
---
drivers/net/wireless/ath/ath5k/pcu.c | 31 +++++++++++++++++++++++++++++--
drivers/net/wireless/ath/ath9k/hw.c | 19 +++++++++++++++----
2 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 710870e..35ac13e 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -496,6 +496,8 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
* Beacon control *
\****************/
+#define ATH5K_MAX_TSF_READ 10
+
/**
* ath5k_hw_get_tsf64 - Get the full 64bit TSF
*
@@ -505,10 +507,35 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
*/
u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
{
- u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+ u32 tsf_lower, tsf_upper1, tsf_upper2;
+ int i;
+
+ /*
+ * While reading TSF upper and then lower part, the clock is still
+ * counting (or jumping in case of IBSS merge) so we might get
+ * inconsistent values. To avoid this, we read the upper part again
+ * and check it has not been changed. We make the hypothesis that a
+ * maximum of 3 changes can happens in a row (we use 10 as a safe
+ * value).
+ *
+ * Impact on performance is pretty small, since in most cases, only
+ * 3 register reads are needed.
+ */
+
+ tsf_upper1 = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+ for (i = 0; i < ATH5K_MAX_TSF_READ; i++) {
+ tsf_lower = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
+ tsf_upper2 = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+ if (tsf_upper2 == tsf_upper1)
+ break;
+ tsf_upper1 = tsf_upper2;
+ }
+
+ WARN_ON( i == ATH5K_MAX_TSF_READ );
+
ATH5K_TRACE(ah->ah_sc);
- return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
+ return (((u64)tsf_upper1 << 32) | tsf_lower);
}
/**
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 0945452..370e5ed 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -3606,14 +3606,25 @@ void ath9k_hw_write_associd(struct ath_hw *ah)
}
EXPORT_SYMBOL(ath9k_hw_write_associd);
+#define ATH9K_MAX_TSF_READ 10
+
u64 ath9k_hw_gettsf64(struct ath_hw *ah)
{
- u64 tsf;
+ u32 tsf_lower, tsf_upper1, tsf_upper2;
+ int i;
+
+ tsf_upper1 = REG_READ(ah, AR_TSF_U32);
+ for (i = 0; i < ATH9K_MAX_TSF_READ; i++) {
+ tsf_lower = REG_READ(ah, AR_TSF_L32);
+ tsf_upper2 = REG_READ(ah, AR_TSF_U32);
+ if (tsf_upper2 == tsf_upper1)
+ break;
+ tsf_upper1 = tsf_upper2;
+ }
- tsf = REG_READ(ah, AR_TSF_U32);
- tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
+ WARN_ON( i == ATH9K_MAX_TSF_READ );
- return tsf;
+ return (((u64)tsf_upper1 << 32) | tsf_lower);
}
EXPORT_SYMBOL(ath9k_hw_gettsf64);
--
1.5.6.5
^ permalink raw reply related
* Re: Lockup inside of stop_machine() during modprobe aes (was Re: Another AR5008 hang)
From: Andrew Morton @ 2010-04-15 21:22 UTC (permalink / raw)
To: Ben Gamari; +Cc: Johannes Berg, linux-kernel, linux-wireless, ath9k, Herbert Xu
In-Reply-To: <4bbb7896.48c3f10a.30b9.365b@mx.google.com>
On Tue, 06 Apr 2010 11:08:22 -0700 (PDT) Ben Gamari <bgamari.foss@gmail.com> wrote:
>
> ...
>
> I just built 2.6.34-rc3 with the appropriate fixes for the ACPI thermal lockdep
> issues and have attached the dmesg output of the crash below. It appears that
> modprobe is freezing with a few locks held while inserting aes.ko. In
> particular, it seems that the kernel is deadlocking inside of stop_machine()
> while flushing workqueues.
>
> ...
>
My guess would be that ieee80211 is calling crypto->request_module()
under rtnl_lock, and the fact that rtnl_lock is held is causing
modprobe->stop_machine to not complete.
> P.S. I am now quite certain that I was mistaken in saying that 2.6.33 was
> affected. This seems to just be a 2.6.34 issue.
OK, thanks, I'll ask Rafael and Maciej to track this as a post-2.6.33
regression, probably wireless.
^ permalink raw reply
* Re: Lockup inside of stop_machine() during modprobe aes (was Re: Another AR5008 hang)
From: Ben Gamari @ 2010-04-16 1:15 UTC (permalink / raw)
To: Andrew Morton
Cc: Johannes Berg, linux-kernel, linux-wireless, ath9k, Herbert Xu
In-Reply-To: <20100415172205.c1e57636.akpm@linux-foundation.org>
On Thu, 15 Apr 2010 17:22:05 -0400, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Tue, 06 Apr 2010 11:08:22 -0700 (PDT) Ben Gamari <bgamari.foss@gmail.com> wrote:
> > ...
> > In particular, it seems that the kernel is deadlocking inside of
> > stop_machine() while flushing workqueues.
> > ...
>
> My guess would be that ieee80211 is calling crypto->request_module()
> under rtnl_lock, and the fact that rtnl_lock is held is causing
> modprobe->stop_machine to not complete.
>
> > P.S. I am now quite certain that I was mistaken in saying that 2.6.33 was
> > affected. This seems to just be a 2.6.34 issue.
>
> OK, thanks, I'll ask Rafael and Maciej to track this as a post-2.6.33
> regression, probably wireless.
Thanks!
- Ben
^ permalink raw reply
* [PATCH 1/2] iwmc3200wifi: Fix sparse warnings
From: Zhu Yi @ 2010-04-16 1:28 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Samuel Ortiz, Zhu Yi
From: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
---
drivers/net/wireless/iwmc3200wifi/rx.c | 3 ++-
drivers/net/wireless/iwmc3200wifi/trace.h | 4 ++--
drivers/net/wireless/iwmc3200wifi/tx.c | 4 ++--
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index ad53987..e1184de 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -431,7 +431,8 @@ static int iwm_ntf_rx_ticket(struct iwm_priv *iwm, u8 *buf,
return PTR_ERR(ticket_node);
IWM_DBG_RX(iwm, DBG, "TICKET %s(%d)\n",
- ticket->action == IWM_RX_TICKET_RELEASE ?
+ __le16_to_cpu(ticket->action) ==
+ IWM_RX_TICKET_RELEASE ?
"RELEASE" : "DROP",
ticket->id);
spin_lock(&iwm->ticket_lock);
diff --git a/drivers/net/wireless/iwmc3200wifi/trace.h b/drivers/net/wireless/iwmc3200wifi/trace.h
index 320e54f..abb4805 100644
--- a/drivers/net/wireless/iwmc3200wifi/trace.h
+++ b/drivers/net/wireless/iwmc3200wifi/trace.h
@@ -76,7 +76,7 @@ TRACE_EVENT(iwm_tx_wifi_cmd,
IWM_ASSIGN;
__entry->opcode = hdr->sw_hdr.cmd.cmd;
__entry->lmac = 0;
- __entry->seq = hdr->sw_hdr.cmd.seq_num;
+ __entry->seq = __le16_to_cpu(hdr->sw_hdr.cmd.seq_num);
__entry->resp = GET_VAL8(hdr->sw_hdr.cmd.flags, UMAC_DEV_CMD_FLAGS_RESP_REQ);
__entry->color = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_TX_STA_COLOR);
__entry->eot = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_OUT_CMD_EOT);
@@ -123,7 +123,7 @@ TRACE_EVENT(iwm_tx_packets,
__entry->ra_tid = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_RATID);
__entry->credit_group = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_CREDIT_GRP);
__entry->color = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_TX_STA_COLOR);
- __entry->seq = hdr->sw_hdr.cmd.seq_num;
+ __entry->seq = __le16_to_cpu(hdr->sw_hdr.cmd.seq_num);
__entry->npkt = 1;
__entry->bytes = len;
diff --git a/drivers/net/wireless/iwmc3200wifi/tx.c b/drivers/net/wireless/iwmc3200wifi/tx.c
index 9537cdb..3216621 100644
--- a/drivers/net/wireless/iwmc3200wifi/tx.c
+++ b/drivers/net/wireless/iwmc3200wifi/tx.c
@@ -302,8 +302,8 @@ void iwm_tx_credit_init_pools(struct iwm_priv *iwm,
#define IWM_UDMA_HDR_LEN sizeof(struct iwm_umac_wifi_out_hdr)
-static int iwm_tx_build_packet(struct iwm_priv *iwm, struct sk_buff *skb,
- int pool_id, u8 *buf)
+static __le16 iwm_tx_build_packet(struct iwm_priv *iwm, struct sk_buff *skb,
+ int pool_id, u8 *buf)
{
struct iwm_umac_wifi_out_hdr *hdr = (struct iwm_umac_wifi_out_hdr *)buf;
struct iwm_udma_wifi_cmd udma_cmd;
--
1.6.3.3
^ permalink raw reply related
* [PATCH 2/2] iwmc3200wifi: check sparse endianness annotations
From: Zhu Yi @ 2010-04-16 1:28 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Samuel Ortiz, Zhu Yi
In-Reply-To: <1271381324-21044-1-git-send-email-yi.zhu@intel.com>
From: Samuel Ortiz <sameo@linux.intel.com>
Add -D__CHECK_ENDIAN__ to driver ccflags so that sparse will
always check endianness by default.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
---
drivers/net/wireless/iwmc3200wifi/Makefile | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/iwmc3200wifi/Makefile b/drivers/net/wireless/iwmc3200wifi/Makefile
index aeed5cd..cdc7e07 100644
--- a/drivers/net/wireless/iwmc3200wifi/Makefile
+++ b/drivers/net/wireless/iwmc3200wifi/Makefile
@@ -6,3 +6,5 @@ iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o
iwmc3200wifi-$(CONFIG_IWM_TRACING) += trace.o
CFLAGS_trace.o := -I$(src)
+
+ccflags-y += -D__CHECK_ENDIAN__
--
1.6.3.3
^ permalink raw reply related
* Re: [ath9k-devel] On ath9k debugfs, having trouble recompiling and inserting only ath9k
From: Rakesh Kumar @ 2010-04-16 1:46 UTC (permalink / raw)
To: Pavel Roskin; +Cc: ath9k-devel, linux-wireless
In-Reply-To: <1271108966.15194.4.camel@mj>
> Maybe /sys/kernel/debug/ath9k is already present. You may want to
> reboot to "fix" it.
Yeah, it was due to the order of delete entry calls. I had included
one more debugfs u8 entry which was being deleted after the
directory's entry and thus not being deleted at all and on the next
run it would cause trouble on creation. Thanks.
--
Rakesh
^ permalink raw reply
* Re: [PATCH v2] wl1251: register platform_device to pass board data
From: Kalle Valo @ 2010-04-16 5:03 UTC (permalink / raw)
To: Grazvydas Ignotas; +Cc: John W. Linville, linux-wireless
In-Reply-To: <1271345003-15453-1-git-send-email-notasas@gmail.com>
Grazvydas Ignotas <notasas@gmail.com> writes:
> wl1251 is embedded chip that can be connected using SDIO bus, and is not
> an actual SDIO card. For this reason there is a need to pass some board
> specific data, like 'EEPROM is attached' flag or power control callback.
>
> However currently there is no way to pass this data through SDIO subsystem,
> so this patch registers dummy platform_device to allow that, until we
> have a better solution to this.
Looks very good now, thanks a lot for doing this.
> Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
Acked-by: Kalle Valo <kvalo@adurom.com>
--
Kalle Valo
^ permalink raw reply
* Re: [RFC PATCHv2 1/2] mac80211: Determine dynamic PS timeout based on ps-qos network latency
From: Kalle Valo @ 2010-04-16 5:17 UTC (permalink / raw)
To: Juuso Oikarinen; +Cc: linux-wireless
In-Reply-To: <1271228079-27321-2-git-send-email-juuso.oikarinen@nokia.com>
Juuso Oikarinen <juuso.oikarinen@nokia.com> writes:
> Determine the dynamic PS timeout based on the configured ps-qos network
> latency. For backwards wext compatibility, allow the dynamic PS timeout
> configured by the cfg80211 to overrule the automatically determined value.
Thanks. I took a quick look, but I haven't tested this yet myself.
> + timeout = local->hw.conf.dynamic_ps_forced_timeout;
> + if (timeout < 0) {
> + if (latency <= 50000)
> + timeout = 300;
> + else if (latency <= 2000000000)
> + timeout = 100;
> + else
> + timeout = 0;
> + }
> + local->hw.conf.dynamic_ps_timeout = timeout;
What will be the timeout value when there are no pm_qos requirements
from user space applications? Do you know what will be the default
latency value in that case?
I'm mostly worried about timeout 0 case, for example I suspect ath9k
is broken with that value.
Also does this patch change the default value of dynamic ps timeout?
--
Kalle Valo
^ permalink raw reply
* Re: [RFC PATCHv2 1/2] mac80211: Determine dynamic PS timeout based on ps-qos network latency
From: Juuso Oikarinen @ 2010-04-16 5:29 UTC (permalink / raw)
To: ext Kalle Valo; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <87eiigm0vu.fsf@purkki.valot.fi>
Hi,
On Fri, 2010-04-16 at 07:17 +0200, ext Kalle Valo wrote:
> Juuso Oikarinen <juuso.oikarinen@nokia.com> writes:
>
> > Determine the dynamic PS timeout based on the configured ps-qos network
> > latency. For backwards wext compatibility, allow the dynamic PS timeout
> > configured by the cfg80211 to overrule the automatically determined value.
>
> Thanks. I took a quick look, but I haven't tested this yet myself.
>
> > + timeout = local->hw.conf.dynamic_ps_forced_timeout;
> > + if (timeout < 0) {
> > + if (latency <= 50000)
> > + timeout = 300;
> > + else if (latency <= 2000000000)
> > + timeout = 100;
> > + else
> > + timeout = 0;
> > + }
> > + local->hw.conf.dynamic_ps_timeout = timeout;
>
> What will be the timeout value when there are no pm_qos requirements
> from user space applications? Do you know what will be the default
> latency value in that case?
Yes, the default value is 2000000000 (2000 seconds, ugh.) Hence the
value in the if statement for 100ms.
> I'm mostly worried about timeout 0 case, for example I suspect ath9k
> is broken with that value.
>
> Also does this patch change the default value of dynamic ps timeout?
>
No, the current default does not change. As the default value for the
latency is 2000s, we will, by default, get a timeout of 100ms.
-Juuso
^ permalink raw reply
* Re: [RFC PATCHv2 1/2] mac80211: Determine dynamic PS timeout based on ps-qos network latency
From: Kalle Valo @ 2010-04-16 6:10 UTC (permalink / raw)
To: Juuso Oikarinen; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1271395747.6205.23.camel@wimaxnb.nmp.nokia.com>
Juuso Oikarinen <juuso.oikarinen@nokia.com> writes:
> Hi,
Moi,
>> > + timeout = local->hw.conf.dynamic_ps_forced_timeout;
>> > + if (timeout < 0) {
>> > + if (latency <= 50000)
>> > + timeout = 300;
>> > + else if (latency <= 2000000000)
>> > + timeout = 100;
>> > + else
>> > + timeout = 0;
>> > + }
>> > + local->hw.conf.dynamic_ps_timeout = timeout;
>>
>> What will be the timeout value when there are no pm_qos requirements
>> from user space applications? Do you know what will be the default
>> latency value in that case?
>
> Yes, the default value is 2000000000 (2000 seconds, ugh.) Hence the
> value in the if statement for 100ms.
Ah, now I understand better.
And ugh indeed, having a default of 2000 seconds for latency is very
awkward. I would have preferred to have a magic value denoting (like
-1 or something) that user space doesn't care. But I guess we have to
live with this :/
Maybe at some point we can talk with QoS framework about this.
>> I'm mostly worried about timeout 0 case, for example I suspect ath9k
>> is broken with that value.
>>
>> Also does this patch change the default value of dynamic ps timeout?
>>
>
> No, the current default does not change. As the default value for the
> latency is 2000s, we will, by default, get a timeout of 100ms.
Excellent. Thank you for explaining these.
>From my point of view these patches look good and I have nothing to
complain.
(I hope Juuso didn't hit his head when falling off from his chair when
reading this.)
--
Kalle Valo
^ permalink raw reply
* [PATCH PING] ssb patches for SPROM location
From: Rafał Miłecki @ 2010-04-16 6:20 UTC (permalink / raw)
To: linux-wireless, John W. Linville
John, I posted some time ago following patches:
[RFT][PATCH] ssb: Look for SPROM at different offset on higher rev CC
[PATCH 1/2] ssb: Use relative offsets for SPROM
[PATCH 2/2] ssb: Fix order of definitions and some text space indents
while Michael has some doubts about "ssb: Look for SPROM at different
offset on higher rev CC" I explained to him that what he does not like
was fixed in next 2 posted patches.
AFAIR you got some device with this recently-discovered location of
SPROM. Could you test my set if it makes your card working? If so,
could you take that patches to your tree?
--
Rafał
^ permalink raw reply
* Re: [RFC PATCHv2 1/2] mac80211: Determine dynamic PS timeout based on ps-qos network latency
From: Juuso Oikarinen @ 2010-04-16 6:17 UTC (permalink / raw)
To: ext Kalle Valo; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <87aat4lygg.fsf@purkki.valot.fi>
On Fri, 2010-04-16 at 08:10 +0200, ext Kalle Valo wrote:
> Maybe at some point we can talk with QoS framework about this.
>
> >> I'm mostly worried about timeout 0 case, for example I suspect ath9k
> >> is broken with that value.
> >>
> >> Also does this patch change the default value of dynamic ps timeout?
> >>
> >
> > No, the current default does not change. As the default value for the
> > latency is 2000s, we will, by default, get a timeout of 100ms.
>
> Excellent. Thank you for explaining these.
>
> From my point of view these patches look good and I have nothing to
> complain.
You're definitely getting soft. I will stretch my luck by submitting a
v3 with one more latency range, giving a dynamic PS timeout of 50 ms.
> (I hope Juuso didn't hit his head when falling off from his chair when
> reading this.)
>
*ouch*
-Juuso
^ permalink raw reply
* [PATCH 00/10] ath9k_htc updates
From: Sujith @ 2010-04-16 6:23 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
John,
This series contains all the pending patches
for ath9k_htc, rebased over Luis' latest series.
Sujith
Sujith (10):
ath9k_htc: Cleanup beacon configuration
ath: Add buffered register write operations
ath9k_htc: Implement multiple register write support
ath9k_hw: Add macros for multiple register writes
ath9k_hw: Relocate Opmode initialization
ath9k_hw: Use buffered register writes
ath9k_htc: Remove GPIO set on unload
ath9k_htc: Add dropped SKB count to debugfs
ath9k_htc: Handle WMI timeouts properly
ath9k_htc: Fix sparse endian warnings
drivers/net/wireless/ath/ath.h | 14 +++-
drivers/net/wireless/ath/ath9k/ani.c | 23 +++++
drivers/net/wireless/ath/ath9k/ar5008_phy.c | 28 ++++++
drivers/net/wireless/ath/ath9k/ar9002_calib.c | 5 +
drivers/net/wireless/ath/ath9k/ar9002_hw.c | 7 ++-
drivers/net/wireless/ath/ath9k/ar9002_phy.c | 5 +
drivers/net/wireless/ath/ath9k/eeprom_4k.c | 10 ++
drivers/net/wireless/ath/ath9k/hif_usb.c | 13 ++-
drivers/net/wireless/ath/ath9k/htc.h | 19 ++--
drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 29 +++----
drivers/net/wireless/ath/ath9k/htc_drv_init.c | 104 ++++++++++++++++++++++-
drivers/net/wireless/ath/ath9k/htc_drv_main.c | 20 +++--
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 11 +--
drivers/net/wireless/ath/ath9k/htc_hst.c | 8 +-
drivers/net/wireless/ath/ath9k/htc_hst.h | 24 +++---
drivers/net/wireless/ath/ath9k/hw.c | 79 ++++++++++++++++--
drivers/net/wireless/ath/ath9k/hw.h | 18 ++++
drivers/net/wireless/ath/ath9k/mac.c | 27 ++++++
drivers/net/wireless/ath/ath9k/mac.h | 10 +-
drivers/net/wireless/ath/ath9k/wmi.c | 16 +++-
drivers/net/wireless/ath/ath9k/wmi.h | 19 ++++-
21 files changed, 407 insertions(+), 82 deletions(-)
^ permalink raw reply
* [PATCH 01/10] ath9k_htc: Cleanup beacon configuration
From: Sujith @ 2010-04-16 6:23 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
This patch cleans up beacon configuration,
removing a redundant interface type check
and updating beacon interval in the correct place.
Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
---
drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 23 +++++++++--------------
drivers/net/wireless/ath/ath9k/htc_drv_main.c | 2 +-
2 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index 5e21f4d..d104028 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -244,25 +244,20 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
struct ieee80211_vif *vif)
{
struct ath_common *common = ath9k_hw_common(priv->ah);
- enum nl80211_iftype iftype;
struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
+ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
- if (vif) {
- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
- iftype = vif->type;
- cur_conf->beacon_interval = bss_conf->beacon_int;
- cur_conf->dtim_period = bss_conf->dtim_period;
- cur_conf->listen_interval = 1;
- cur_conf->dtim_count = 1;
- cur_conf->bmiss_timeout =
- ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
- } else
- iftype = priv->ah->opmode;
-
+ cur_conf->beacon_interval = bss_conf->beacon_int;
if (cur_conf->beacon_interval == 0)
cur_conf->beacon_interval = 100;
- switch (iftype) {
+ cur_conf->dtim_period = bss_conf->dtim_period;
+ cur_conf->listen_interval = 1;
+ cur_conf->dtim_count = 1;
+ cur_conf->bmiss_timeout =
+ ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
+
+ switch (vif->type) {
case NL80211_IFTYPE_STATION:
ath9k_htc_beacon_config_sta(priv, cur_conf);
break;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index eb7722b..08a4a58 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1687,7 +1687,7 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
spin_unlock_bh(&priv->beacon_lock);
priv->op_flags |= OP_FULL_RESET;
if (priv->op_flags & OP_ASSOCIATED)
- ath9k_htc_beacon_config(priv, NULL);
+ ath9k_htc_beacon_config(priv, priv->vif);
ath_start_ani(priv);
mutex_unlock(&priv->mutex);
ath9k_htc_ps_restore(priv);
--
1.7.0.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox