From fce041beb03f93c7a771f0b4b6c45bb71ef90901 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 19 May 2011 12:20:25 +0200 Subject: ath9k: unify edma and non-edma tx code, improve tx fifo handling EDMA based chips (AR9380+) have 8 Tx FIFO slots, which are used to fix the tx queue start/stop race conditions which have to be worked around for earlier chips by keeping the last descriptor in the queue. The current code stores all frames that do not fit onto the 8 FIFO slots in a separate list. Whenever a FIFO slot is freed up, the next frame (or A-MPDU) from the pending queue gets moved to that slot. This process is not only inefficient, but also unnecessary. The code can be improved visibly by keeping the pending queue fully linked, and moving the contents of the entire queue to a FIFO slot as it becomes available. This patch makes the necessary changes for that and also merges some code that was duplicated for EDMA vs non-EDMA. It changes txq->axq_link to point to the last descriptor instead of the link pointer, so that ath9k_hw_set_desc_link can be used, which works on all chips. With this patch, a small performance increase for non-aggregated traffic was observed on AR9380 based embedded hardware. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net/wireless/ath/ath9k/debug.c') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index d55ffd7d4bd..202399d4fe1 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -587,7 +587,6 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PRQLE("axq_q empty: ", axq_q); PRQLE("axq_acq empty: ", axq_acq); - PRQLE("txq_fifo_pending: ", txq_fifo_pending); for (i = 0; i < ATH_TXFIFO_DEPTH; i++) { snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i); PRQLE(tmp, txq_fifo[i]); -- cgit v1.2.3-70-g09d2 From 05c0be2f7f10404e5b3bc4105f9206096e9b8767 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Thu, 26 May 2011 10:56:15 +0530 Subject: ath9k: Add a debug entry to start/stop ANI this helps the user to start/stop ANI dynamically. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 1 + drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/debug.c | 52 ++++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/init.c | 2 +- drivers/net/wireless/ath/ath9k/main.c | 33 +++++++++++++++------ 5 files changed, 79 insertions(+), 10 deletions(-) (limited to 'drivers/net/wireless/ath/ath9k/debug.c') diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 7cf4317a2a8..17c4b56c387 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -161,6 +161,7 @@ struct ath_common { const struct ath_bus_ops *bus_ops; bool btcoex_enabled; + bool disable_ani; }; struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 4cc78449ed9..3bf1d83ab41 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -427,6 +427,7 @@ void ath_hw_check(struct work_struct *work); void ath_hw_pll_work(struct work_struct *work); void ath_paprd_calibrate(struct work_struct *work); void ath_ani_calibrate(unsigned long data); +void ath_start_ani(struct ath_common *common); /**********/ /* BTCOEX */ diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 202399d4fe1..7230d6578b1 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -176,6 +176,56 @@ static const struct file_operations fops_rx_chainmask = { .llseek = default_llseek, }; +static ssize_t read_file_disable_ani(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath_softc *sc = file->private_data; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + char buf[32]; + unsigned int len; + + len = sprintf(buf, "%d\n", common->disable_ani); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t write_file_disable_ani(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath_softc *sc = file->private_data; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + unsigned long disable_ani; + char buf[32]; + ssize_t len; + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EFAULT; + + buf[len] = '\0'; + if (strict_strtoul(buf, 0, &disable_ani)) + return -EINVAL; + + common->disable_ani = !!disable_ani; + + if (disable_ani) { + sc->sc_flags &= ~SC_OP_ANI_RUN; + del_timer_sync(&common->ani.timer); + } else { + sc->sc_flags |= SC_OP_ANI_RUN; + ath_start_ani(common); + } + + return count; +} + +static const struct file_operations fops_disable_ani = { + .read = read_file_disable_ani, + .write = write_file_disable_ani, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; static ssize_t read_file_dma(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -1159,6 +1209,8 @@ int ath9k_init_debug(struct ath_hw *ah) sc->debug.debugfs_phy, sc, &fops_rx_chainmask); debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_tx_chainmask); + debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR, + sc->debug.debugfs_phy, sc, &fops_disable_ani); debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_regidx); debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 45c585a337e..d4b166cfdf6 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -519,7 +519,6 @@ static void ath9k_init_misc(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); int i = 0; - setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); sc->config.txpowlimit = ATH_TXPOWER_MAX; @@ -585,6 +584,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, common->priv = sc; common->debug_mask = ath9k_debug; common->btcoex_enabled = ath9k_btcoex_enable == 1; + common->disable_ani = false; spin_lock_init(&common->cc_lock); spin_lock_init(&sc->sc_serial_rw); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 5cf2dc3c65f..7f945333e2d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -134,7 +134,7 @@ void ath9k_ps_restore(struct ath_softc *sc) spin_unlock_irqrestore(&sc->sc_pm_lock, flags); } -static void ath_start_ani(struct ath_common *common) +void ath_start_ani(struct ath_common *common) { struct ath_hw *ah = common->ah; unsigned long timestamp = jiffies_to_msecs(jiffies); @@ -300,7 +300,8 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, ath_set_beacon(sc); ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); - ath_start_ani(common); + if (!common->disable_ani) + ath_start_ani(common); } ps_restore: @@ -968,6 +969,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) sc->hw_busy_count = 0; /* Stop ANI */ + del_timer_sync(&common->ani.timer); ath9k_ps_wakeup(sc); @@ -1017,7 +1019,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) spin_unlock_bh(&sc->sc_pcu_lock); /* Start ANI */ - ath_start_ani(common); + if (!common->disable_ani) + ath_start_ani(common); + ath9k_ps_restore(sc); return r; @@ -1408,8 +1412,12 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, /* Set up ANI */ if (iter_data.naps > 0) { sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; - sc->sc_flags |= SC_OP_ANI_RUN; - ath_start_ani(common); + + if (!common->disable_ani) { + sc->sc_flags |= SC_OP_ANI_RUN; + ath_start_ani(common); + } + } else { sc->sc_flags &= ~SC_OP_ANI_RUN; del_timer_sync(&common->ani.timer); @@ -1973,8 +1981,11 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) sc->last_rssi = ATH_RSSI_DUMMY_MARKER; sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; - sc->sc_flags |= SC_OP_ANI_RUN; - ath_start_ani(common); + if (!common->disable_ani) { + sc->sc_flags |= SC_OP_ANI_RUN; + ath_start_ani(common); + } + } } @@ -2043,8 +2054,12 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, if (bss_conf->ibss_joined) { sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; - sc->sc_flags |= SC_OP_ANI_RUN; - ath_start_ani(common); + + if (!common->disable_ani) { + sc->sc_flags |= SC_OP_ANI_RUN; + ath_start_ani(common); + } + } else { sc->sc_flags &= ~SC_OP_ANI_RUN; del_timer_sync(&common->ani.timer); -- cgit v1.2.3-70-g09d2 From 5a6f78afdabeb8b8e0811547fb98813323abf888 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 31 May 2011 21:21:41 +0200 Subject: ath9k: show excessive-retry MPDUs in debugfs Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 6 +++++- drivers/net/wireless/ath/ath9k/debug.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath/ath9k/debug.c') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 7230d6578b1..22d3a26e684 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -600,6 +600,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("MPDUs Queued: ", queued); PR("MPDUs Completed: ", completed); + PR("MPDUs XRetried: ", xretries); PR("Aggregates: ", a_aggr); PR("AMPDUs Queued HW:", a_queued_hw); PR("AMPDUs Queued SW:", a_queued_sw); @@ -856,7 +857,10 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, else TX_STAT_INC(qnum, a_completed); } else { - TX_STAT_INC(qnum, completed); + if (bf_isxretried(bf)) + TX_STAT_INC(qnum, xretries); + else + TX_STAT_INC(qnum, completed); } if (ts->ts_status & ATH9K_TXERR_FIFO) diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 8ce6ad80f4e..4a04510e111 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -116,6 +116,7 @@ struct ath_tx_stats { u32 tx_bytes_all; u32 queued; u32 completed; + u32 xretries; u32 a_aggr; u32 a_queued_hw; u32 a_queued_sw; -- cgit v1.2.3-70-g09d2