mac80211: update upstream patches

This commit is contained in:
LEAN-ESX 2019-11-11 20:28:16 -08:00
parent be770de958
commit 384e5abd02
35 changed files with 2243 additions and 44 deletions

View File

@ -299,14 +299,14 @@ endef
define KernelPackage/rsi91x define KernelPackage/rsi91x
$(call KernelPackage/mac80211/Default) $(call KernelPackage/mac80211/Default)
TITLE:=Redpine Signals Inc 91x WLAN driver support TITLE:=Redpine Signals Inc 91x WLAN driver support
DEPENDS+= +kmod-mac80211 +rs9113-firmware DEPENDS+= +kmod-mac80211 +rs9113-firmware +@DRIVER_11N_SUPPORT
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_91x.ko FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_91x.ko
endef endef
define KernelPackage/rsi91x-usb define KernelPackage/rsi91x-usb
$(call KernelPackage/mac80211/Default) $(call KernelPackage/mac80211/Default)
TITLE:=Redpine Signals USB bus support TITLE:=Redpine Signals USB bus support
DEPENDS+= +kmod-mac80211 +kmod-usb2 +kmod-rsi91x +rs9113-firmware DEPENDS+=@USB_SUPPORT +kmod-usb-core +kmod-mac80211 +kmod-rsi91x +rs9113-firmware
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_usb.ko FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_usb.ko
AUTOLOAD:=$(call AutoProbe,rsi_usb) AUTOLOAD:=$(call AutoProbe,rsi_usb)
endef endef

View File

@ -113,7 +113,7 @@ detect_mac80211() {
set wireless.radio${devidx}.hwmode=11${mode_band} set wireless.radio${devidx}.hwmode=11${mode_band}
${dev_id} ${dev_id}
${ht_capab} ${ht_capab}
set wireless.radio${devidx}.disabled=1 set wireless.radio${devidx}.disabled=0
set wireless.default_radio${devidx}=wifi-iface set wireless.default_radio${devidx}=wifi-iface
set wireless.default_radio${devidx}.device=radio${devidx} set wireless.default_radio${devidx}.device=radio${devidx}

View File

@ -16,7 +16,7 @@
static const struct platform_device_id ath9k_platform_id_table[] = { static const struct platform_device_id ath9k_platform_id_table[] = {
{ {
@@ -69,6 +77,235 @@ static const struct ath_bus_ops ath_ahb_ @@ -69,6 +77,242 @@ static const struct ath_bus_ops ath_ahb_
.eeprom_read = ath_ahb_eeprom_read, .eeprom_read = ath_ahb_eeprom_read,
}; };
@ -232,7 +232,14 @@
+ pdata->external_reset = data->wmac_reset; + pdata->external_reset = data->wmac_reset;
+ } + }
+ +
+ if (data->bootstrap_reg && data->bootstrap_ref) { + if (data->dev_id == AR9300_DEVID_AR953X) {
+ /*
+ * QCA953x only supports 25MHz refclk.
+ * Some vendors have an invalid bootstrap option
+ * set, which would break the WMAC here.
+ */
+ pdata->is_clk_25mhz = true;
+ } else if (data->bootstrap_reg && data->bootstrap_ref) {
+ u32 t = ath79_reset_rr(data->bootstrap_reg); + u32 t = ath79_reset_rr(data->bootstrap_reg);
+ if (t & data->bootstrap_ref) + if (t & data->bootstrap_ref)
+ pdata->is_clk_25mhz = false; + pdata->is_clk_25mhz = false;
@ -252,7 +259,7 @@
static int ath_ahb_probe(struct platform_device *pdev) static int ath_ahb_probe(struct platform_device *pdev)
{ {
void __iomem *mem; void __iomem *mem;
@@ -80,6 +317,17 @@ static int ath_ahb_probe(struct platform @@ -80,6 +324,17 @@ static int ath_ahb_probe(struct platform
int ret = 0; int ret = 0;
struct ath_hw *ah; struct ath_hw *ah;
char hw_name[64]; char hw_name[64];
@ -270,7 +277,7 @@
if (!dev_get_platdata(&pdev->dev)) { if (!dev_get_platdata(&pdev->dev)) {
dev_err(&pdev->dev, "no platform data specified\n"); dev_err(&pdev->dev, "no platform data specified\n");
@@ -122,13 +370,16 @@ static int ath_ahb_probe(struct platform @@ -122,13 +377,16 @@ static int ath_ahb_probe(struct platform
sc->mem = mem; sc->mem = mem;
sc->irq = irq; sc->irq = irq;
@ -288,7 +295,7 @@
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to initialize device\n"); dev_err(&pdev->dev, "failed to initialize device\n");
goto err_irq; goto err_irq;
@@ -159,6 +410,9 @@ static int ath_ahb_remove(struct platfor @@ -159,6 +417,9 @@ static int ath_ahb_remove(struct platfor
free_irq(sc->irq, sc); free_irq(sc->irq, sc);
ieee80211_free_hw(sc->hw); ieee80211_free_hw(sc->hw);
} }
@ -298,7 +305,7 @@
return 0; return 0;
} }
@@ -168,6 +422,9 @@ static struct platform_driver ath_ahb_dr @@ -168,6 +429,9 @@ static struct platform_driver ath_ahb_dr
.remove = ath_ahb_remove, .remove = ath_ahb_remove,
.driver = { .driver = {
.name = "ath9k", .name = "ath9k",

View File

@ -0,0 +1,56 @@
From 9f3e3323e9966d9f21bea0c81b1acb36c0e15cec Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Sat, 15 Jun 2019 12:00:54 +0200
Subject: [PATCH 01/15] rt2x00: allow to specify watchdog interval
Allow subdriver to change watchdog interval by intialize
link->watchdog_interval value before rt2x00link_register().
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 +
drivers/net/wireless/ralink/rt2x00/rt2x00link.c | 13 +++++++++----
2 files changed, 10 insertions(+), 4 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -336,6 +336,7 @@ struct link {
* to bring the device/driver back into the desired state.
*/
struct delayed_work watchdog_work;
+ unsigned int watchdog_interval;
/*
* Work structure for scheduling periodic AGC adjustments.
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00link.c
@@ -398,7 +398,7 @@ void rt2x00link_start_watchdog(struct rt
rt2x00dev->ops->lib->watchdog)
ieee80211_queue_delayed_work(rt2x00dev->hw,
&link->watchdog_work,
- WATCHDOG_INTERVAL);
+ link->watchdog_interval);
}
void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev)
@@ -424,11 +424,16 @@ static void rt2x00link_watchdog(struct w
if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
ieee80211_queue_delayed_work(rt2x00dev->hw,
&link->watchdog_work,
- WATCHDOG_INTERVAL);
+ link->watchdog_interval);
}
void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
{
- INIT_DELAYED_WORK(&rt2x00dev->link.watchdog_work, rt2x00link_watchdog);
- INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner);
+ struct link *link = &rt2x00dev->link;
+
+ INIT_DELAYED_WORK(&link->work, rt2x00link_tuner);
+ INIT_DELAYED_WORK(&link->watchdog_work, rt2x00link_watchdog);
+
+ if (link->watchdog_interval == 0)
+ link->watchdog_interval = WATCHDOG_INTERVAL;
}

View File

@ -0,0 +1,144 @@
From 2034afe4db4a2a4f22541d7f7b426e38d2093d38 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Sat, 15 Jun 2019 12:00:55 +0200
Subject: [PATCH 02/15] rt2800: add helpers for reading dma done index
For mmio we do not properlly trace dma done Q_INDEX_DMA_DONE index
for TX queues. That would require implementing INT_SOURCE_CSR_*_DMA_DONE
interrupts, what is rather not worth to do due to adding extra
CPU load (small but still somewhat not necessary otherwise).
We can just read TX DMA done indexes from registers directly. What
will be used by watchdog.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../net/wireless/ralink/rt2x00/rt2800lib.h | 8 +++++
.../net/wireless/ralink/rt2x00/rt2800mmio.c | 31 +++++++++++++++++++
.../net/wireless/ralink/rt2x00/rt2800mmio.h | 2 ++
.../net/wireless/ralink/rt2x00/rt2800pci.c | 1 +
.../net/wireless/ralink/rt2x00/rt2800soc.c | 1 +
.../net/wireless/ralink/rt2x00/rt2800usb.c | 9 ++++++
6 files changed, 52 insertions(+)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
@@ -76,6 +76,7 @@ struct rt2800_ops {
const u8 *data, const size_t len);
int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
__le32 *(*drv_get_txwi)(struct queue_entry *entry);
+ unsigned int (*drv_get_dma_done)(struct data_queue *queue);
};
static inline u32 rt2800_register_read(struct rt2x00_dev *rt2x00dev,
@@ -177,6 +178,13 @@ static inline __le32 *rt2800_drv_get_txw
return rt2800ops->drv_get_txwi(entry);
}
+static inline unsigned int rt2800_drv_get_dma_done(struct data_queue *queue)
+{
+ const struct rt2800_ops *rt2800ops = queue->rt2x00dev->ops->drv;
+
+ return rt2800ops->drv_get_dma_done(queue);
+}
+
void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
const u8 command, const u8 token,
const u8 arg0, const u8 arg1);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
@@ -36,6 +36,37 @@
#include "rt2800lib.h"
#include "rt2800mmio.h"
+unsigned int rt2800mmio_get_dma_done(struct data_queue *queue)
+{
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+ struct queue_entry *entry;
+ int idx, qid;
+
+ switch (queue->qid) {
+ case QID_AC_VO:
+ case QID_AC_VI:
+ case QID_AC_BE:
+ case QID_AC_BK:
+ qid = queue->qid;
+ idx = rt2x00mmio_register_read(rt2x00dev, TX_DTX_IDX(qid));
+ break;
+ case QID_MGMT:
+ idx = rt2x00mmio_register_read(rt2x00dev, TX_DTX_IDX(5));
+ break;
+ case QID_RX:
+ entry = rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE);
+ idx = entry->entry_idx;
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ idx = 0;
+ break;
+ }
+
+ return idx;
+}
+EXPORT_SYMBOL_GPL(rt2800mmio_get_dma_done);
+
/*
* TX descriptor initialization
*/
--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h
@@ -126,6 +126,8 @@
#define RXD_W3_PLCP_SIGNAL FIELD32(0x00020000)
#define RXD_W3_PLCP_RSSI FIELD32(0x00040000)
+unsigned int rt2800mmio_get_dma_done(struct data_queue *queue);
+
/* TX descriptor initialization */
__le32 *rt2800mmio_get_txwi(struct queue_entry *entry);
void rt2800mmio_write_tx_desc(struct queue_entry *entry,
--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
@@ -337,6 +337,7 @@ static const struct rt2800_ops rt2800pci
.drv_write_firmware = rt2800pci_write_firmware,
.drv_init_registers = rt2800mmio_init_registers,
.drv_get_txwi = rt2800mmio_get_txwi,
+ .drv_get_dma_done = rt2800mmio_get_dma_done,
};
static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
@@ -183,6 +183,7 @@ static const struct rt2800_ops rt2800soc
.drv_write_firmware = rt2800soc_write_firmware,
.drv_init_registers = rt2800mmio_init_registers,
.drv_get_txwi = rt2800mmio_get_txwi,
+ .drv_get_dma_done = rt2800mmio_get_dma_done,
};
static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = {
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
@@ -390,6 +390,14 @@ static int rt2800usb_set_device_state(st
return retval;
}
+static unsigned int rt2800usb_get_dma_done(struct data_queue *queue)
+{
+ struct queue_entry *entry;
+
+ entry = rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE);
+ return entry->entry_idx;
+}
+
/*
* TX descriptor initialization
*/
@@ -672,6 +680,7 @@ static const struct rt2800_ops rt2800usb
.drv_write_firmware = rt2800usb_write_firmware,
.drv_init_registers = rt2800usb_init_registers,
.drv_get_txwi = rt2800usb_get_txwi,
+ .drv_get_dma_done = rt2800usb_get_dma_done,
};
static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {

View File

@ -0,0 +1,158 @@
From 759c5b599cf4ddb3b56e66d459b1bf0fe2724fb8 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Sat, 15 Jun 2019 12:00:56 +0200
Subject: [PATCH 03/15] rt2800: initial watchdog implementation
Add watchdog for rt2800 devices. For now it only detect hung
and print error.
[Note: I verified that printing messages from process context is
fine on MT7620 (WT3020) platform that have problem when printk
is called from interrupt context].
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../net/wireless/ralink/rt2x00/rt2800lib.c | 56 +++++++++++++++++++
.../net/wireless/ralink/rt2x00/rt2800lib.h | 2 +
.../net/wireless/ralink/rt2x00/rt2800pci.c | 1 +
.../net/wireless/ralink/rt2x00/rt2800soc.c | 1 +
.../net/wireless/ralink/rt2x00/rt2800usb.c | 1 +
.../net/wireless/ralink/rt2x00/rt2x00queue.h | 6 ++
6 files changed, 67 insertions(+)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -1223,6 +1223,60 @@ void rt2800_txdone_nostatus(struct rt2x0
}
EXPORT_SYMBOL_GPL(rt2800_txdone_nostatus);
+static int rt2800_check_hung(struct data_queue *queue)
+{
+ unsigned int cur_idx = rt2800_drv_get_dma_done(queue);
+
+ if (queue->wd_idx != cur_idx)
+ queue->wd_count = 0;
+ else
+ queue->wd_count++;
+
+ return queue->wd_count > 16;
+}
+
+void rt2800_watchdog(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue;
+ bool hung_tx = false;
+ bool hung_rx = false;
+
+ if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags))
+ return;
+
+ queue_for_each(rt2x00dev, queue) {
+ switch (queue->qid) {
+ case QID_AC_VO:
+ case QID_AC_VI:
+ case QID_AC_BE:
+ case QID_AC_BK:
+ case QID_MGMT:
+ if (rt2x00queue_empty(queue))
+ continue;
+ hung_tx = rt2800_check_hung(queue);
+ break;
+ case QID_RX:
+ /* For station mode we should reactive at least
+ * beacons. TODO: need to find good way detect
+ * RX hung for AP mode.
+ */
+ if (rt2x00dev->intf_sta_count == 0)
+ continue;
+ hung_rx = rt2800_check_hung(queue);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (hung_tx)
+ rt2x00_warn(rt2x00dev, "Watchdog TX hung detected\n");
+
+ if (hung_rx)
+ rt2x00_warn(rt2x00dev, "Watchdog RX hung detected\n");
+}
+EXPORT_SYMBOL_GPL(rt2800_watchdog);
+
static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
unsigned int index)
{
@@ -10222,6 +10276,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
__set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags);
}
+ rt2x00dev->link.watchdog_interval = msecs_to_jiffies(100);
+
/*
* Set the rssi offset.
*/
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
@@ -208,6 +208,8 @@ void rt2800_txdone_nostatus(struct rt2x0
bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev);
bool rt2800_txstatus_pending(struct rt2x00_dev *rt2x00dev);
+void rt2800_watchdog(struct rt2x00_dev *rt2x00dev);
+
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
void rt2800_clear_beacon(struct queue_entry *entry);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
@@ -362,6 +362,7 @@ static const struct rt2x00lib_ops rt2800
.link_tuner = rt2800_link_tuner,
.gain_calibration = rt2800_gain_calibration,
.vco_calibration = rt2800_vco_calibration,
+ .watchdog = rt2800_watchdog,
.start_queue = rt2800mmio_start_queue,
.kick_queue = rt2800mmio_kick_queue,
.stop_queue = rt2800mmio_stop_queue,
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
@@ -208,6 +208,7 @@ static const struct rt2x00lib_ops rt2800
.link_tuner = rt2800_link_tuner,
.gain_calibration = rt2800_gain_calibration,
.vco_calibration = rt2800_vco_calibration,
+ .watchdog = rt2800_watchdog,
.start_queue = rt2800mmio_start_queue,
.kick_queue = rt2800mmio_kick_queue,
.stop_queue = rt2800mmio_stop_queue,
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
@@ -698,6 +698,7 @@ static const struct rt2x00lib_ops rt2800
.link_tuner = rt2800_link_tuner,
.gain_calibration = rt2800_gain_calibration,
.vco_calibration = rt2800_vco_calibration,
+ .watchdog = rt2800_watchdog,
.start_queue = rt2800usb_start_queue,
.kick_queue = rt2x00usb_kick_queue,
.stop_queue = rt2800usb_stop_queue,
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
@@ -446,6 +446,9 @@ enum data_queue_flags {
* @length: Number of frames in queue.
* @index: Index pointers to entry positions in the queue,
* use &enum queue_index to get a specific index field.
+ * @wd_count: watchdog counter number of times entry does change
+ * in the queue
+ * @wd_idx: index of queue entry saved by watchdog
* @txop: maximum burst time.
* @aifs: The aifs value for outgoing frames (field ignored in RX queue).
* @cw_min: The cw min value for outgoing frames (field ignored in RX queue).
@@ -473,6 +476,9 @@ struct data_queue {
unsigned short length;
unsigned short index[Q_INDEX_MAX];
+ unsigned short wd_count;
+ unsigned int wd_idx;
+
unsigned short txop;
unsigned short aifs;
unsigned short cw_min;

View File

@ -0,0 +1,96 @@
From 09db3b000619b38d504e1fff66efed33dfacb6c0 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Sat, 15 Jun 2019 12:00:57 +0200
Subject: [PATCH 04/15] rt2800: add pre_reset_hw callback
Add routine to cleanup interfaces data before hw reset as
ieee80211_restart_hw() will do setup interfaces again.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../net/wireless/ralink/rt2x00/rt2800lib.c | 19 +++++++++++++++++++
.../net/wireless/ralink/rt2x00/rt2800lib.h | 1 +
.../net/wireless/ralink/rt2x00/rt2800pci.c | 1 +
.../net/wireless/ralink/rt2x00/rt2800soc.c | 1 +
.../net/wireless/ralink/rt2x00/rt2800usb.c | 1 +
drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 +
6 files changed, 24 insertions(+)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -1854,6 +1854,25 @@ int rt2800_sta_remove(struct ieee80211_h
}
EXPORT_SYMBOL_GPL(rt2800_sta_remove);
+void rt2800_pre_reset_hw(struct rt2x00_dev *rt2x00dev)
+{
+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+ struct data_queue *queue = rt2x00dev->bcn;
+ struct queue_entry *entry;
+ int i, wcid;
+
+ for (wcid = WCID_START; wcid < WCID_END; wcid++) {
+ drv_data->wcid_to_sta[wcid - WCID_START] = NULL;
+ __clear_bit(wcid - WCID_START, drv_data->sta_ids);
+ }
+
+ for (i = 0; i < queue->limit; i++) {
+ entry = &queue->entries[i];
+ clear_bit(ENTRY_BCN_ASSIGNED, &entry->flags);
+ }
+}
+EXPORT_SYMBOL_GPL(rt2800_pre_reset_hw);
+
void rt2800_config_filter(struct rt2x00_dev *rt2x00dev,
const unsigned int filter_flags)
{
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
@@ -268,5 +268,6 @@ void rt2800_disable_wpdma(struct rt2x00_
void rt2800_get_txwi_rxwi_size(struct rt2x00_dev *rt2x00dev,
unsigned short *txwi_size,
unsigned short *rxwi_size);
+void rt2800_pre_reset_hw(struct rt2x00_dev *rt2x00dev);
#endif /* RT2800LIB_H */
--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
@@ -379,6 +379,7 @@ static const struct rt2x00lib_ops rt2800
.config_erp = rt2800_config_erp,
.config_ant = rt2800_config_ant,
.config = rt2800_config,
+ .pre_reset_hw = rt2800_pre_reset_hw,
};
static const struct rt2x00_ops rt2800pci_ops = {
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
@@ -225,6 +225,7 @@ static const struct rt2x00lib_ops rt2800
.config_erp = rt2800_config_erp,
.config_ant = rt2800_config_ant,
.config = rt2800_config,
+ .pre_reset_hw = rt2800_pre_reset_hw,
};
static const struct rt2x00_ops rt2800soc_ops = {
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
@@ -717,6 +717,7 @@ static const struct rt2x00lib_ops rt2800
.config_erp = rt2800_config_erp,
.config_ant = rt2800_config_ant,
.config = rt2800_config,
+ .pre_reset_hw = rt2800_pre_reset_hw,
};
static void rt2800usb_queue_init(struct data_queue *queue)
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -627,6 +627,7 @@ struct rt2x00lib_ops {
void (*config) (struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
const unsigned int changed_flags);
+ void (*pre_reset_hw) (struct rt2x00_dev *rt2x00dev);
int (*sta_add) (struct rt2x00_dev *rt2x00dev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);

View File

@ -0,0 +1,51 @@
From 710e6cc1595e25378c4b9977f7a8b4ad4a72a109 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Sat, 15 Jun 2019 12:00:58 +0200
Subject: [PATCH 05/15] rt2800: do not nullify initialization vector data
If we restart hw we should keep existing IV (initialization vector)
otherwise HW encryption will be broken after restart.
Also fix some coding style issues on the way.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -1658,14 +1658,15 @@ static void rt2800_config_wcid_attr_ciph
offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
- memset(&iveiv_entry, 0, sizeof(iveiv_entry));
+ rt2800_register_multiread(rt2x00dev, offset,
+ &iveiv_entry, sizeof(iveiv_entry));
if ((crypto->cipher == CIPHER_TKIP) ||
(crypto->cipher == CIPHER_TKIP_NO_MIC) ||
(crypto->cipher == CIPHER_AES))
iveiv_entry.iv[3] |= 0x20;
iveiv_entry.iv[3] |= key->keyidx << 6;
rt2800_register_multiwrite(rt2x00dev, offset,
- &iveiv_entry, sizeof(iveiv_entry));
+ &iveiv_entry, sizeof(iveiv_entry));
}
int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
@@ -6090,13 +6091,11 @@ static int rt2800_init_registers(struct
* ASIC will keep garbage value after boot, clear encryption keys.
*/
for (i = 0; i < 4; i++)
- rt2800_register_write(rt2x00dev,
- SHARED_KEY_MODE_ENTRY(i), 0);
+ rt2800_register_write(rt2x00dev, SHARED_KEY_MODE_ENTRY(i), 0);
for (i = 0; i < 256; i++) {
rt2800_config_wcid(rt2x00dev, NULL, i);
rt2800_delete_wcid_attr(rt2x00dev, i);
- rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
}
/*

View File

@ -0,0 +1,151 @@
From e403fa31ed71e87de8e5991e23406b8377c9c894 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Sat, 15 Jun 2019 12:00:59 +0200
Subject: [PATCH 06/15] rt2x00: add restart hw
Add ieee80211_restart_hw() to watchdog and debugfs file for testing
if restart works as expected.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../net/wireless/ralink/rt2x00/rt2800lib.c | 4 +++
drivers/net/wireless/ralink/rt2x00/rt2x00.h | 7 ++++
.../net/wireless/ralink/rt2x00/rt2x00debug.c | 35 +++++++++++++++++++
.../net/wireless/ralink/rt2x00/rt2x00dev.c | 10 ++++--
4 files changed, 54 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -1274,6 +1274,9 @@ void rt2800_watchdog(struct rt2x00_dev *
if (hung_rx)
rt2x00_warn(rt2x00dev, "Watchdog RX hung detected\n");
+
+ if (hung_tx || hung_rx)
+ ieee80211_restart_hw(rt2x00dev->hw);
}
EXPORT_SYMBOL_GPL(rt2800_watchdog);
@@ -10294,6 +10297,7 @@ int rt2800_probe_hw(struct rt2x00_dev *r
__set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags);
}
+ __set_bit(CAPABILITY_RESTART_HW, &rt2x00dev->cap_flags);
rt2x00dev->link.watchdog_interval = msecs_to_jiffies(100);
/*
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -723,6 +723,7 @@ enum rt2x00_capability_flags {
CAPABILITY_VCO_RECALIBRATION,
CAPABILITY_EXTERNAL_PA_TX0,
CAPABILITY_EXTERNAL_PA_TX1,
+ CAPABILITY_RESTART_HW,
};
/*
@@ -1279,6 +1280,12 @@ rt2x00_has_cap_vco_recalibration(struct
return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_VCO_RECALIBRATION);
}
+static inline bool
+rt2x00_has_cap_restart_hw(struct rt2x00_dev *rt2x00dev)
+{
+ return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_RESTART_HW);
+}
+
/**
* rt2x00queue_map_txskb - Map a skb into DMA for TX purposes.
* @entry: Pointer to &struct queue_entry
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
@@ -63,6 +63,7 @@ struct rt2x00debug_intf {
* - chipset file
* - device state flags file
* - device capability flags file
+ * - hardware restart file
* - register folder
* - csr offset/value files
* - eeprom offset/value files
@@ -79,6 +80,7 @@ struct rt2x00debug_intf {
struct dentry *chipset_entry;
struct dentry *dev_flags;
struct dentry *cap_flags;
+ struct dentry *restart_hw;
struct dentry *register_folder;
struct dentry *csr_off_entry;
struct dentry *csr_val_entry;
@@ -577,6 +579,34 @@ static const struct file_operations rt2x
.llseek = default_llseek,
};
+static ssize_t rt2x00debug_write_restart_hw(struct file *file,
+ const char __user *buf,
+ size_t length,
+ loff_t *offset)
+{
+ struct rt2x00debug_intf *intf = file->private_data;
+ struct rt2x00_dev *rt2x00dev = intf->rt2x00dev;
+ static unsigned long last_reset;
+
+ if (!rt2x00_has_cap_restart_hw(rt2x00dev))
+ return -EOPNOTSUPP;
+
+ if (time_before(jiffies, last_reset + msecs_to_jiffies(2000)))
+ return -EBUSY;
+
+ last_reset = jiffies;
+
+ ieee80211_restart_hw(rt2x00dev->hw);
+ return length;
+}
+
+static const struct file_operations rt2x00debug_restart_hw = {
+ .owner = THIS_MODULE,
+ .write = rt2x00debug_write_restart_hw,
+ .open = simple_open,
+ .llseek = generic_file_llseek,
+};
+
static struct dentry *rt2x00debug_create_file_driver(const char *name,
struct rt2x00debug_intf
*intf,
@@ -672,6 +702,10 @@ void rt2x00debug_register(struct rt2x00_
intf->driver_folder, intf,
&rt2x00debug_fop_cap_flags);
+ intf->restart_hw = debugfs_create_file("restart_hw", 0200,
+ intf->driver_folder, intf,
+ &rt2x00debug_restart_hw);
+
intf->register_folder =
debugfs_create_dir("register", intf->driver_folder);
@@ -753,6 +787,7 @@ void rt2x00debug_deregister(struct rt2x0
debugfs_remove(intf->csr_off_entry);
debugfs_remove(intf->register_folder);
debugfs_remove(intf->dev_flags);
+ debugfs_remove(intf->restart_hw);
debugfs_remove(intf->cap_flags);
debugfs_remove(intf->chipset_entry);
debugfs_remove(intf->driver_entry);
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1269,8 +1269,14 @@ int rt2x00lib_start(struct rt2x00_dev *r
{
int retval;
- if (test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
- return 0;
+ if (test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) {
+ /*
+ * This is special case for ieee80211_restart_hw(), otherwise
+ * mac80211 never call start() two times in row without stop();
+ */
+ rt2x00dev->ops->lib->pre_reset_hw(rt2x00dev);
+ rt2x00lib_stop(rt2x00dev);
+ }
/*
* If this is the first interface which is added,

View File

@ -0,0 +1,71 @@
From 0f47aeeada2a1fe296258eab9a08ced258009481 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Sat, 15 Jun 2019 12:01:00 +0200
Subject: [PATCH 07/15] rt2800: do not enable watchdog by default
Make watchdog disabled by default and add module parameter to enable it.
User will have to create file in /etc/modprobe.d/ with
options rt2800lib watchdog=1
to enable the watchdog or load "rt2800lib watchdog=1" module manually
before loading rt2800{soc,pci,usb} module.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 12 ++++++++++--
drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 +
drivers/net/wireless/ralink/rt2x00/rt2x00link.c | 2 +-
3 files changed, 12 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -41,6 +41,10 @@
#include "rt2800lib.h"
#include "rt2800.h"
+static bool modparam_watchdog;
+module_param_named(watchdog, modparam_watchdog, bool, S_IRUGO);
+MODULE_PARM_DESC(watchdog, "Enable watchdog to detect tx/rx hangs and reset hardware if detected");
+
/*
* Register access.
* All access to the CSR registers will go through the methods
@@ -10297,8 +10301,12 @@ int rt2800_probe_hw(struct rt2x00_dev *r
__set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags);
}
- __set_bit(CAPABILITY_RESTART_HW, &rt2x00dev->cap_flags);
- rt2x00dev->link.watchdog_interval = msecs_to_jiffies(100);
+ if (modparam_watchdog) {
+ __set_bit(CAPABILITY_RESTART_HW, &rt2x00dev->cap_flags);
+ rt2x00dev->link.watchdog_interval = msecs_to_jiffies(100);
+ } else {
+ rt2x00dev->link.watchdog_disabled = true;
+ }
/*
* Set the rssi offset.
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -337,6 +337,7 @@ struct link {
*/
struct delayed_work watchdog_work;
unsigned int watchdog_interval;
+ bool watchdog_disabled;
/*
* Work structure for scheduling periodic AGC adjustments.
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00link.c
@@ -395,7 +395,7 @@ void rt2x00link_start_watchdog(struct rt
struct link *link = &rt2x00dev->link;
if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
- rt2x00dev->ops->lib->watchdog)
+ rt2x00dev->ops->lib->watchdog && !link->watchdog_disabled)
ieee80211_queue_delayed_work(rt2x00dev->hw,
&link->watchdog_work,
link->watchdog_interval);

View File

@ -0,0 +1,67 @@
From 41a531ffa4c5aeb062f892227c00fabb3b4a9c91 Mon Sep 17 00:00:00 2001
From: Soeren Moch <smoch@web.de>
Date: Mon, 1 Jul 2019 12:53:13 +0200
Subject: [PATCH 08/15] rt2x00usb: fix rx queue hang
Since commit ed194d136769 ("usb: core: remove local_irq_save() around
->complete() handler") the handler rt2x00usb_interrupt_rxdone() is
not running with interrupts disabled anymore. So this completion handler
is not guaranteed to run completely before workqueue processing starts
for the same queue entry.
Be sure to set all other flags in the entry correctly before marking
this entry ready for workqueue processing. This way we cannot miss error
conditions that need to be signalled from the completion handler to the
worker thread.
Note that rt2x00usb_work_rxdone() processes all available entries, not
only such for which queue_work() was called.
This patch is similar to what commit df71c9cfceea ("rt2x00: fix order
of entry flags modification") did for TX processing.
This fixes a regression on a RT5370 based wifi stick in AP mode, which
suddenly stopped data transmission after some period of heavy load. Also
stopping the hanging hostapd resulted in the error message "ieee80211
phy0: rt2x00queue_flush_queue: Warning - Queue 14 failed to flush".
Other operation modes are probably affected as well, this just was
the used testcase.
Fixes: ed194d136769 ("usb: core: remove local_irq_save() around ->complete() handler")
Cc: stable@vger.kernel.org # 4.20+
Signed-off-by: Soeren Moch <smoch@web.de>
Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
@@ -383,15 +383,10 @@ static void rt2x00usb_interrupt_rxdone(s
struct queue_entry *entry = (struct queue_entry *)urb->context;
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
return;
/*
- * Report the frame as DMA done
- */
- rt2x00lib_dmadone(entry);
-
- /*
* Check if the received data is simply too small
* to be actually valid, or if the urb is signaling
* a problem.
@@ -400,6 +395,11 @@ static void rt2x00usb_interrupt_rxdone(s
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
/*
+ * Report the frame as DMA done
+ */
+ rt2x00lib_dmadone(entry);
+
+ /*
* Schedule the delayed work for reading the RX status
* from the device.
*/

View File

@ -0,0 +1,51 @@
From 3b902fa811cf6bf7f9ad0ffb77d0a133e0b3bd61 Mon Sep 17 00:00:00 2001
From: Soeren Moch <smoch@web.de>
Date: Mon, 1 Jul 2019 12:53:14 +0200
Subject: [PATCH 09/15] rt2x00usb: remove unnecessary rx flag checks
In contrast to the TX path, there is no need to separately read the transfer
status from the device after receiving RX data. Consequently, there is no
real STATUS_PENDING RX processing queue entry state.
Remove the unnecessary ENTRY_DATA_STATUS_PENDING flag checks from the RX path.
Also remove the misleading comment about reading RX status from device.
Suggested-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Soeren Moch <smoch@web.de>
Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
@@ -360,8 +360,7 @@ static void rt2x00usb_work_rxdone(struct
while (!rt2x00queue_empty(rt2x00dev->rx)) {
entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE);
- if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
- !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
+ if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
break;
/*
@@ -400,8 +399,7 @@ static void rt2x00usb_interrupt_rxdone(s
rt2x00lib_dmadone(entry);
/*
- * Schedule the delayed work for reading the RX status
- * from the device.
+ * Schedule the delayed work for processing RX data
*/
queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work);
}
@@ -413,8 +411,7 @@ static bool rt2x00usb_kick_rx_entry(stru
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
int status;
- if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
- test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
+ if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
return false;
rt2x00lib_dmastart(entry);

View File

@ -0,0 +1,248 @@
From 1dc244064c47d6df7925ca0895f8365e68d3abd1 Mon Sep 17 00:00:00 2001
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: Wed, 3 Jul 2019 13:39:56 +0200
Subject: [PATCH 10/15] rt2x00: no need to check return value of debugfs_create
functions
When calling debugfs functions, there is no need to ever check the
return value. The function can work or not, but the code logic should
never do something different based on this.
Because we don't need to save the individual debugfs files and
directories, remove the local storage of them and just remove the entire
debugfs directory in a single call, making things a lot simpler.
Cc: Stanislaw Gruszka <sgruszka@redhat.com>
Cc: Helmut Schaa <helmut.schaa@googlemail.com>
Cc: Kalle Valo <kvalo@codeaurora.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../net/wireless/ralink/rt2x00/rt2x00debug.c | 136 +++++-------------
1 file changed, 35 insertions(+), 101 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
@@ -76,26 +76,6 @@ struct rt2x00debug_intf {
* - crypto stats file
*/
struct dentry *driver_folder;
- struct dentry *driver_entry;
- struct dentry *chipset_entry;
- struct dentry *dev_flags;
- struct dentry *cap_flags;
- struct dentry *restart_hw;
- struct dentry *register_folder;
- struct dentry *csr_off_entry;
- struct dentry *csr_val_entry;
- struct dentry *eeprom_off_entry;
- struct dentry *eeprom_val_entry;
- struct dentry *bbp_off_entry;
- struct dentry *bbp_val_entry;
- struct dentry *rf_off_entry;
- struct dentry *rf_val_entry;
- struct dentry *rfcsr_off_entry;
- struct dentry *rfcsr_val_entry;
- struct dentry *queue_folder;
- struct dentry *queue_frame_dump_entry;
- struct dentry *queue_stats_entry;
- struct dentry *crypto_stats_entry;
/*
* The frame dump file only allows a single reader,
@@ -607,39 +587,34 @@ static const struct file_operations rt2x
.llseek = generic_file_llseek,
};
-static struct dentry *rt2x00debug_create_file_driver(const char *name,
- struct rt2x00debug_intf
- *intf,
- struct debugfs_blob_wrapper
- *blob)
+static void rt2x00debug_create_file_driver(const char *name,
+ struct rt2x00debug_intf *intf,
+ struct debugfs_blob_wrapper *blob)
{
char *data;
data = kzalloc(3 * MAX_LINE_LENGTH, GFP_KERNEL);
if (!data)
- return NULL;
+ return;
blob->data = data;
data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name);
data += sprintf(data, "version:\t%s\n", DRV_VERSION);
blob->size = strlen(blob->data);
- return debugfs_create_blob(name, 0400, intf->driver_folder, blob);
+ debugfs_create_blob(name, 0400, intf->driver_folder, blob);
}
-static struct dentry *rt2x00debug_create_file_chipset(const char *name,
- struct rt2x00debug_intf
- *intf,
- struct
- debugfs_blob_wrapper
- *blob)
+static void rt2x00debug_create_file_chipset(const char *name,
+ struct rt2x00debug_intf *intf,
+ struct debugfs_blob_wrapper *blob)
{
const struct rt2x00debug *debug = intf->debug;
char *data;
data = kzalloc(9 * MAX_LINE_LENGTH, GFP_KERNEL);
if (!data)
- return NULL;
+ return;
blob->data = data;
data += sprintf(data, "rt chip:\t%04x\n", intf->rt2x00dev->chip.rt);
@@ -665,13 +640,15 @@ static struct dentry *rt2x00debug_create
blob->size = strlen(blob->data);
- return debugfs_create_blob(name, 0400, intf->driver_folder, blob);
+ debugfs_create_blob(name, 0400, intf->driver_folder, blob);
}
void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
{
const struct rt2x00debug *debug = rt2x00dev->ops->debugfs;
struct rt2x00debug_intf *intf;
+ struct dentry *queue_folder;
+ struct dentry *register_folder;
intf = kzalloc(sizeof(struct rt2x00debug_intf), GFP_KERNEL);
if (!intf) {
@@ -687,43 +664,27 @@ void rt2x00debug_register(struct rt2x00_
debugfs_create_dir(intf->rt2x00dev->ops->name,
rt2x00dev->hw->wiphy->debugfsdir);
- intf->driver_entry =
- rt2x00debug_create_file_driver("driver", intf, &intf->driver_blob);
-
- intf->chipset_entry =
- rt2x00debug_create_file_chipset("chipset",
- intf, &intf->chipset_blob);
-
- intf->dev_flags = debugfs_create_file("dev_flags", 0400,
- intf->driver_folder, intf,
- &rt2x00debug_fop_dev_flags);
-
- intf->cap_flags = debugfs_create_file("cap_flags", 0400,
- intf->driver_folder, intf,
- &rt2x00debug_fop_cap_flags);
-
- intf->restart_hw = debugfs_create_file("restart_hw", 0200,
- intf->driver_folder, intf,
- &rt2x00debug_restart_hw);
+ rt2x00debug_create_file_driver("driver", intf, &intf->driver_blob);
+ rt2x00debug_create_file_chipset("chipset", intf, &intf->chipset_blob);
+ debugfs_create_file("dev_flags", 0400, intf->driver_folder, intf,
+ &rt2x00debug_fop_dev_flags);
+ debugfs_create_file("cap_flags", 0400, intf->driver_folder, intf,
+ &rt2x00debug_fop_cap_flags);
+ debugfs_create_file("restart_hw", 0200, intf->driver_folder, intf,
+ &rt2x00debug_restart_hw);
- intf->register_folder =
- debugfs_create_dir("register", intf->driver_folder);
+ register_folder = debugfs_create_dir("register", intf->driver_folder);
#define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name) \
({ \
if (debug->__name.read) { \
- (__intf)->__name##_off_entry = \
- debugfs_create_u32(__stringify(__name) "_offset", \
- 0600, \
- (__intf)->register_folder, \
- &(__intf)->offset_##__name); \
+ debugfs_create_u32(__stringify(__name) "_offset", 0600, \
+ register_folder, \
+ &(__intf)->offset_##__name); \
\
- (__intf)->__name##_val_entry = \
- debugfs_create_file(__stringify(__name) "_value", \
- 0600, \
- (__intf)->register_folder, \
- (__intf), \
- &rt2x00debug_fop_##__name); \
+ debugfs_create_file(__stringify(__name) "_value", 0600, \
+ register_folder, (__intf), \
+ &rt2x00debug_fop_##__name); \
} \
})
@@ -735,26 +696,21 @@ void rt2x00debug_register(struct rt2x00_
#undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY
- intf->queue_folder =
- debugfs_create_dir("queue", intf->driver_folder);
+ queue_folder = debugfs_create_dir("queue", intf->driver_folder);
- intf->queue_frame_dump_entry =
- debugfs_create_file("dump", 0400, intf->queue_folder,
- intf, &rt2x00debug_fop_queue_dump);
+ debugfs_create_file("dump", 0400, queue_folder, intf,
+ &rt2x00debug_fop_queue_dump);
skb_queue_head_init(&intf->frame_dump_skbqueue);
init_waitqueue_head(&intf->frame_dump_waitqueue);
- intf->queue_stats_entry =
- debugfs_create_file("queue", 0400, intf->queue_folder,
- intf, &rt2x00debug_fop_queue_stats);
+ debugfs_create_file("queue", 0400, queue_folder, intf,
+ &rt2x00debug_fop_queue_stats);
#ifdef CPTCFG_RT2X00_LIB_CRYPTO
if (rt2x00_has_cap_hw_crypto(rt2x00dev))
- intf->crypto_stats_entry =
- debugfs_create_file("crypto", 0444, intf->queue_folder,
- intf,
- &rt2x00debug_fop_crypto_stats);
+ debugfs_create_file("crypto", 0444, queue_folder, intf,
+ &rt2x00debug_fop_crypto_stats);
#endif
return;
@@ -769,31 +725,7 @@ void rt2x00debug_deregister(struct rt2x0
skb_queue_purge(&intf->frame_dump_skbqueue);
-#ifdef CPTCFG_RT2X00_LIB_CRYPTO
- debugfs_remove(intf->crypto_stats_entry);
-#endif
- debugfs_remove(intf->queue_stats_entry);
- debugfs_remove(intf->queue_frame_dump_entry);
- debugfs_remove(intf->queue_folder);
- debugfs_remove(intf->rfcsr_val_entry);
- debugfs_remove(intf->rfcsr_off_entry);
- debugfs_remove(intf->rf_val_entry);
- debugfs_remove(intf->rf_off_entry);
- debugfs_remove(intf->bbp_val_entry);
- debugfs_remove(intf->bbp_off_entry);
- debugfs_remove(intf->eeprom_val_entry);
- debugfs_remove(intf->eeprom_off_entry);
- debugfs_remove(intf->csr_val_entry);
- debugfs_remove(intf->csr_off_entry);
- debugfs_remove(intf->register_folder);
- debugfs_remove(intf->dev_flags);
- debugfs_remove(intf->restart_hw);
- debugfs_remove(intf->cap_flags);
- debugfs_remove(intf->chipset_entry);
- debugfs_remove(intf->driver_entry);
- debugfs_remove(intf->driver_folder);
- kfree(intf->chipset_blob.data);
- kfree(intf->driver_blob.data);
+ debugfs_remove_recursive(intf->driver_folder);
kfree(intf);
rt2x00dev->debugfs_intf = NULL;

View File

@ -0,0 +1,29 @@
From 706f0182b1add0fc41a8c40662f659b7426f0629 Mon Sep 17 00:00:00 2001
From: Masanari Iida <standby24x7@gmail.com>
Date: Sun, 28 Jul 2019 23:07:42 +0900
Subject: [PATCH 11/15] rt2800usb: Add new rt2800usb device PLANEX GW-USMicroN
This patch add a device ID for PLANEX GW-USMicroN.
Without this patch, I had to echo the device IDs in order to
recognize the device.
# lsusb |grep PLANEX
Bus 002 Device 005: ID 2019:ed14 PLANEX GW-USMicroN
Signed-off-by: Masanari Iida <standby24x7@gmail.com>
Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/ralink/rt2x00/rt2800usb.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
@@ -1097,6 +1097,7 @@ static const struct usb_device_id rt2800
{ USB_DEVICE(0x0846, 0x9013) },
{ USB_DEVICE(0x0846, 0x9019) },
/* Planex */
+ { USB_DEVICE(0x2019, 0xed14) },
{ USB_DEVICE(0x2019, 0xed19) },
/* Ralink */
{ USB_DEVICE(0x148f, 0x3573) },

View File

@ -0,0 +1,102 @@
From 95844124385eae4bd9ca5f9514a0fc33d561ac3c Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Mon, 19 Aug 2019 13:20:07 +0200
Subject: [PATCH 12/15] rt2x00: clear IV's on start to fix AP mode regression
To do not brake HW restart we should keep initialization vectors data.
I assumed that on start the data is already initialized to zeros, but
that not true on some scenarios and we should clear it. So add
additional flag to check if we are under HW restart and clear IV's
data if we are not.
Patch fixes AP mode regression.
Reported-and-tested-by: Emil Karlson <jekarl@iki.fi>
Fixes: 710e6cc1595e ("rt2800: do not nullify initialization vector data")
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 9 +++++++++
drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 +
drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 13 ++++++++-----
3 files changed, 18 insertions(+), 5 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -6106,6 +6106,15 @@ static int rt2800_init_registers(struct
}
/*
+ * Clear encryption initialization vectors on start, but keep them
+ * for watchdog reset. Otherwise we will have wrong IVs and not be
+ * able to keep connections after reset.
+ */
+ if (!test_bit(DEVICE_STATE_RESET, &rt2x00dev->flags))
+ for (i = 0; i < 256; i++)
+ rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
+
+ /*
* Clear all beacons
*/
for (i = 0; i < 8; i++)
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -669,6 +669,7 @@ enum rt2x00_state_flags {
DEVICE_STATE_ENABLED_RADIO,
DEVICE_STATE_SCANNING,
DEVICE_STATE_FLUSHING,
+ DEVICE_STATE_RESET,
/*
* Driver configuration
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1267,13 +1267,14 @@ static int rt2x00lib_initialize(struct r
int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
{
- int retval;
+ int retval = 0;
if (test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) {
/*
* This is special case for ieee80211_restart_hw(), otherwise
* mac80211 never call start() two times in row without stop();
*/
+ set_bit(DEVICE_STATE_RESET, &rt2x00dev->flags);
rt2x00dev->ops->lib->pre_reset_hw(rt2x00dev);
rt2x00lib_stop(rt2x00dev);
}
@@ -1284,14 +1285,14 @@ int rt2x00lib_start(struct rt2x00_dev *r
*/
retval = rt2x00lib_load_firmware(rt2x00dev);
if (retval)
- return retval;
+ goto out;
/*
* Initialize the device.
*/
retval = rt2x00lib_initialize(rt2x00dev);
if (retval)
- return retval;
+ goto out;
rt2x00dev->intf_ap_count = 0;
rt2x00dev->intf_sta_count = 0;
@@ -1300,11 +1301,13 @@ int rt2x00lib_start(struct rt2x00_dev *r
/* Enable the radio */
retval = rt2x00lib_enable_radio(rt2x00dev);
if (retval)
- return retval;
+ goto out;
set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags);
- return 0;
+out:
+ clear_bit(DEVICE_STATE_RESET, &rt2x00dev->flags);
+ return retval;
}
void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev)

View File

@ -0,0 +1,40 @@
From 567a9b766b47caffe4b1bf74823e7bc18532d875 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Fri, 23 Aug 2019 09:09:56 +0200
Subject: [PATCH 13/15] rt2x00: do not set IEEE80211_TX_STAT_AMPDU_NO_BACK on
tx status
According to documentation IEEE80211_TX_STAT_AMPDU_NO_BACK is suppose
to be used when we do not recive BA (BlockAck). However on rt2x00 we
use it when remote station fail to decode one or more subframes within
AMPDU (some bits are not set in BlockAck bitmap). Setting the flag result
in sent of BAR (BlockAck Request) frame and this might result of abuse
of BA session, since remote station can sent BA with incorrect
sequence numbers after receiving BAR. This problem is visible especially
when connecting two rt2800 devices.
Previously I observed some performance benefits when using the flag
when connecting with iwlwifi devices. But currently possibly due
to reacent changes in rt2x00 removing the flag has no effect on
those test cases.
So remove the IEEE80211_TX_STAT_AMPDU_NO_BACK.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 3 ---
1 file changed, 3 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -382,9 +382,6 @@ static void rt2x00lib_fill_tx_status(str
IEEE80211_TX_CTL_AMPDU;
tx_info->status.ampdu_len = 1;
tx_info->status.ampdu_ack_len = success ? 1 : 0;
-
- if (!success)
- tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
}
if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {

View File

@ -0,0 +1,46 @@
From 14d5e14c8a6c257eb322ddeb294ac4c243a7d2e1 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Fri, 23 Aug 2019 14:48:03 +0200
Subject: [PATCH 14/15] rt2x00: clear up IV's on key removal
After looking at code I realized that my previous fix
95844124385e ("rt2x00: clear IV's on start to fix AP mode regression")
was incomplete. We can still have wrong IV's after re-keyring.
To fix that, clear up IV's also on key removal.
Fixes: 710e6cc1595e ("rt2800: do not nullify initialization vector data")
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
tested-by: Emil Karlson <jekarl@iki.fi>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../net/wireless/ralink/rt2x00/rt2800lib.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -1665,13 +1665,18 @@ static void rt2800_config_wcid_attr_ciph
offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
- rt2800_register_multiread(rt2x00dev, offset,
- &iveiv_entry, sizeof(iveiv_entry));
- if ((crypto->cipher == CIPHER_TKIP) ||
- (crypto->cipher == CIPHER_TKIP_NO_MIC) ||
- (crypto->cipher == CIPHER_AES))
- iveiv_entry.iv[3] |= 0x20;
- iveiv_entry.iv[3] |= key->keyidx << 6;
+ if (crypto->cmd == SET_KEY) {
+ rt2800_register_multiread(rt2x00dev, offset,
+ &iveiv_entry, sizeof(iveiv_entry));
+ if ((crypto->cipher == CIPHER_TKIP) ||
+ (crypto->cipher == CIPHER_TKIP_NO_MIC) ||
+ (crypto->cipher == CIPHER_AES))
+ iveiv_entry.iv[3] |= 0x20;
+ iveiv_entry.iv[3] |= key->keyidx << 6;
+ } else {
+ memset(&iveiv_entry, 0, sizeof(iveiv_entry));
+ }
+
rt2800_register_multiwrite(rt2x00dev, offset,
&iveiv_entry, sizeof(iveiv_entry));
}

View File

@ -0,0 +1,61 @@
From 13fa451568ab9e8b3074ef741477c7938c713c42 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Thu, 29 Aug 2019 13:29:59 +0200
Subject: [PATCH 15/15] Revert "rt2800: enable TX_PIN_CFG_LNA_PE_ bits per
band"
This reverts commit 9ad3b55654455258a9463384edb40077439d879f.
As reported by Sergey:
"I got some problem after upgrade kernel to 5.2 version (debian testing
linux-image-5.2.0-2-amd64). 5Ghz client stopped to see AP.
Some tests with 1metre distance between client-AP: 2.4Ghz -22dBm, for
5Ghz - 53dBm !, for longer distance (8m + walls) 2.4 - 61dBm, 5Ghz not
visible."
It was identified that rx signal level degradation was caused by
9ad3b5565445 ("rt2800: enable TX_PIN_CFG_LNA_PE_ bits per band").
So revert this commit.
Cc: <stable@vger.kernel.org> # v5.1+
Reported-and-tested-by: Sergey Maranchuk <slav0nic0@gmail.com>
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -4253,24 +4253,18 @@ static void rt2800_config_channel(struct
switch (rt2x00dev->default_ant.rx_chain_num) {
case 3:
/* Turn on tertiary LNAs */
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN,
- rf->channel > 14);
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN,
- rf->channel <= 14);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN, 1);
/* fall-through */
case 2:
/* Turn on secondary LNAs */
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN,
- rf->channel > 14);
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN,
- rf->channel <= 14);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1);
/* fall-through */
case 1:
/* Turn on primary LNAs */
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN,
- rf->channel > 14);
- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN,
- rf->channel <= 14);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1);
+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
break;
}

View File

@ -0,0 +1,88 @@
From patchwork Sat Nov 2 17:47:01 2019
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
X-Patchwork-Id: 11224189
X-Patchwork-Delegate: kvalo@adurom.com
Return-Path: <SRS0=CgQo=Y2=vger.kernel.org=linux-wireless-owner@kernel.org>
Date: Sat, 2 Nov 2019 18:47:01 +0100
From: Daniel Golle <daniel@makrotopia.org>
To: Stanislaw Gruszka <sgruszka@redhat.com>
Cc: linux-wireless@vger.kernel.org, Roman Yeryomin <roman@advem.lv>,
wbob <wbob@jify.de>
Subject: [PATCH v2] rt2800: remove errornous duplicate condition
Message-ID: <20191102174701.GA1489@makrotopia.org>
References: <20191102154639.GA4589@redhat.com>
MIME-Version: 1.0
Content-Disposition: inline
In-Reply-To: <20191102154639.GA4589@redhat.com>
User-Agent: Mutt/1.12.2 (2019-09-21)
Sender: linux-wireless-owner@vger.kernel.org
Precedence: bulk
List-ID: <linux-wireless.vger.kernel.org>
X-Mailing-List: linux-wireless@vger.kernel.org
On 2019-10-28 06:07, wbob wrote:
> Hello Roman,
>
> while reading around drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> I stumbled on what I think is an edit of yours made in error in march
> 2017:
>
> https://github.com/torvalds/linux/commit/41977e86#diff-dae5dc10da180f3b055809a48118e18aR5281
>
> RT6352 in line 5281 should not have been introduced as the "else if"
> below line 5291 can then not take effect for a RT6352 device. Another
> possibility is for line 5291 to be not for RT6352, but this seems
> very unlikely. Are you able to clarify still after this substantial time?
>
> 5277: static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
> ...
> 5279: } else if (rt2x00_rt(rt2x00dev, RT5390) ||
> 5280: rt2x00_rt(rt2x00dev, RT5392) ||
> 5281: rt2x00_rt(rt2x00dev, RT6352)) {
> ...
> 5291: } else if (rt2x00_rt(rt2x00dev, RT6352)) {
> ...
Hence remove errornous line 5281 to make the driver actually
execute the correct initialization routine for MT7620 chips.
As it was requested by Stanislaw Gruszka remove setting values of
MIMO_PS_CFG and TX_PIN_CFG. MIMO_PS_CFG is responsible for MIMO
power-safe mode (which is disabled), hence we can drop setting it.
TX_PIN_CFG is set correctly in other functions, and as setting this
value breaks some devices, rather don't set it here during init, but
only modify it later on.
Fixes: 41977e86c984 ("rt2x00: add support for MT7620")
Reported-by: wbob <wbob@jify.de>
Reported-by: Roman Yeryomin <roman@advem.lv>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -5850,8 +5850,7 @@ static int rt2800_init_registers(struct
rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21);
rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40);
} else if (rt2x00_rt(rt2x00dev, RT5390) ||
- rt2x00_rt(rt2x00dev, RT5392) ||
- rt2x00_rt(rt2x00dev, RT6352)) {
+ rt2x00_rt(rt2x00dev, RT5392)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
@@ -5865,8 +5864,6 @@ static int rt2800_init_registers(struct
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000);
rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
- rt2800_register_write(rt2x00dev, MIMO_PS_CFG, 0x00000002);
- rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x00150F0F);
rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000);
rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0);
rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0);

View File

@ -57,7 +57,7 @@
struct rt2800_ops { struct rt2800_ops {
u32 (*register_read)(struct rt2x00_dev *rt2x00dev, u32 (*register_read)(struct rt2x00_dev *rt2x00dev,
const unsigned int offset); const unsigned int offset);
@@ -145,6 +147,15 @@ static inline int rt2800_read_eeprom(str @@ -146,6 +148,15 @@ static inline int rt2800_read_eeprom(str
{ {
const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
@ -105,7 +105,7 @@
.drv_init_registers = rt2800mmio_init_registers, .drv_init_registers = rt2800mmio_init_registers,
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -702,6 +702,7 @@ enum rt2x00_capability_flags { @@ -706,6 +706,7 @@ enum rt2x00_capability_flags {
REQUIRE_HT_TX_DESC, REQUIRE_HT_TX_DESC,
REQUIRE_PS_AUTOWAKE, REQUIRE_PS_AUTOWAKE,
REQUIRE_DELAYED_RFKILL, REQUIRE_DELAYED_RFKILL,
@ -113,7 +113,7 @@
/* /*
* Capabilities * Capabilities
@@ -977,6 +978,11 @@ struct rt2x00_dev { @@ -982,6 +983,11 @@ struct rt2x00_dev {
const struct firmware *fw; const struct firmware *fw;
/* /*
@ -127,7 +127,7 @@
DECLARE_KFIFO_PTR(txstatus_fifo, u32); DECLARE_KFIFO_PTR(txstatus_fifo, u32);
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1423,6 +1423,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de @@ -1429,6 +1429,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
@ -138,7 +138,7 @@
/* /*
* Let the driver probe the device to detect the capabilities. * Let the driver probe the device to detect the capabilities.
*/ */
@@ -1566,6 +1570,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ @@ -1572,6 +1576,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
* Free the driver data. * Free the driver data.
*/ */
kfree(rt2x00dev->drv_data); kfree(rt2x00dev->drv_data);

View File

@ -12,7 +12,7 @@
#endif /* _RT2X00_PLATFORM_H */ #endif /* _RT2X00_PLATFORM_H */
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1026,6 +1026,22 @@ static int rt2x00lib_probe_hw_modes(stru @@ -1023,6 +1023,22 @@ static int rt2x00lib_probe_hw_modes(stru
unsigned int num_rates; unsigned int num_rates;
unsigned int i; unsigned int i;
@ -37,7 +37,7 @@
num_rates += 4; num_rates += 4;
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -409,6 +409,7 @@ struct hw_mode_spec { @@ -411,6 +411,7 @@ struct hw_mode_spec {
unsigned int supported_bands; unsigned int supported_bands;
#define SUPPORT_BAND_2GHZ 0x00000001 #define SUPPORT_BAND_2GHZ 0x00000001
#define SUPPORT_BAND_5GHZ 0x00000002 #define SUPPORT_BAND_5GHZ 0x00000002

View File

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1004,8 +1004,13 @@ static void rt2x00lib_rate(struct ieee80 @@ -1001,8 +1001,13 @@ static void rt2x00lib_rate(struct ieee80
void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr)
{ {

View File

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1030,6 +1030,16 @@ static int rt2x00lib_probe_hw_modes(stru @@ -1027,6 +1027,16 @@ static int rt2x00lib_probe_hw_modes(stru
struct ieee80211_rate *rates; struct ieee80211_rate *rates;
unsigned int num_rates; unsigned int num_rates;
unsigned int i; unsigned int i;

View File

@ -13,7 +13,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c --- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
@@ -232,10 +232,17 @@ static int rt2800soc_probe(struct platfo @@ -235,10 +235,17 @@ static int rt2800soc_probe(struct platfo
return rt2x00soc_probe(pdev, &rt2800soc_ops); return rt2x00soc_probe(pdev, &rt2800soc_ops);
} }

View File

@ -8,7 +8,7 @@
#include "rt2x00.h" #include "rt2x00.h"
#include "rt2800lib.h" #include "rt2800lib.h"
@@ -9458,6 +9459,17 @@ static int rt2800_init_eeprom(struct rt2 @@ -9542,6 +9543,17 @@ static int rt2800_init_eeprom(struct rt2
rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);

View File

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -1361,7 +1361,7 @@ static inline void rt2x00lib_set_if_comb @@ -1367,7 +1367,7 @@ static inline void rt2x00lib_set_if_comb
*/ */
if_limit = &rt2x00dev->if_limits_ap; if_limit = &rt2x00dev->if_limits_ap;
if_limit->max = rt2x00dev->ops->max_ap_intf; if_limit->max = rt2x00dev->ops->max_ap_intf;

View File

@ -30,7 +30,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
* EEPROM LNA * EEPROM LNA
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -4290,6 +4290,45 @@ static void rt2800_config_channel(struct @@ -4370,6 +4370,45 @@ static void rt2800_config_channel(struct
rt2800_iq_calibrate(rt2x00dev, rf->channel); rt2800_iq_calibrate(rt2x00dev, rf->channel);
} }
@ -76,7 +76,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
bbp = rt2800_bbp_read(rt2x00dev, 4); bbp = rt2800_bbp_read(rt2x00dev, 4);
rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf)); rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
rt2800_bbp_write(rt2x00dev, 4, bbp); rt2800_bbp_write(rt2x00dev, 4, bbp);
@@ -9487,7 +9526,8 @@ static int rt2800_init_eeprom(struct rt2 @@ -9571,7 +9610,8 @@ static int rt2800_init_eeprom(struct rt2
*/ */
eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1); eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1);
@ -86,7 +86,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
if (rt2x00_get_field16(eeprom, if (rt2x00_get_field16(eeprom,
EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352)) EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352))
__set_bit(CAPABILITY_EXTERNAL_PA_TX0, __set_bit(CAPABILITY_EXTERNAL_PA_TX0,
@@ -9498,6 +9538,18 @@ static int rt2800_init_eeprom(struct rt2 @@ -9582,6 +9622,18 @@ static int rt2800_init_eeprom(struct rt2
&rt2x00dev->cap_flags); &rt2x00dev->cap_flags);
} }

View File

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -8349,6 +8349,58 @@ static void rt2800_init_rfcsr_5592(struc @@ -8433,6 +8433,58 @@ static void rt2800_init_rfcsr_5592(struc
rt2800_led_open_drain_enable(rt2x00dev); rt2800_led_open_drain_enable(rt2x00dev);
} }
@ -59,7 +59,7 @@
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
bool set_bw, bool is_ht40) bool set_bw, bool is_ht40)
{ {
@@ -8956,6 +9008,7 @@ static void rt2800_init_rfcsr_6352(struc @@ -9040,6 +9092,7 @@ static void rt2800_init_rfcsr_6352(struc
rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
@ -69,7 +69,7 @@
} }
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
@@ -243,6 +243,7 @@ void rt2800_link_tuner(struct rt2x00_dev @@ -253,6 +253,7 @@ void rt2800_link_tuner(struct rt2x00_dev
const u32 count); const u32 count);
void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev);
void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev);
@ -79,7 +79,7 @@
void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -572,6 +572,7 @@ struct rt2x00lib_ops { @@ -574,6 +574,7 @@ struct rt2x00lib_ops {
struct link_qual *qual, const u32 count); struct link_qual *qual, const u32 count);
void (*gain_calibration) (struct rt2x00_dev *rt2x00dev); void (*gain_calibration) (struct rt2x00_dev *rt2x00dev);
void (*vco_calibration) (struct rt2x00_dev *rt2x00dev); void (*vco_calibration) (struct rt2x00_dev *rt2x00dev);

View File

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -8401,6 +8401,160 @@ void rt2800_rf_self_txdc_cal(struct rt2x @@ -8485,6 +8485,160 @@ void rt2800_rf_self_txdc_cal(struct rt2x
} }
EXPORT_SYMBOL_GPL(rt2800_rf_self_txdc_cal); EXPORT_SYMBOL_GPL(rt2800_rf_self_txdc_cal);
@ -161,7 +161,7 @@
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
bool set_bw, bool is_ht40) bool set_bw, bool is_ht40)
{ {
@@ -9008,6 +9162,7 @@ static void rt2800_init_rfcsr_6352(struc @@ -9092,6 +9246,7 @@ static void rt2800_init_rfcsr_6352(struc
rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
@ -171,7 +171,7 @@
rt2800_bw_filter_calibration(rt2x00dev, false); rt2800_bw_filter_calibration(rt2x00dev, false);
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
@@ -244,6 +244,8 @@ void rt2800_link_tuner(struct rt2x00_dev @@ -254,6 +254,8 @@ void rt2800_link_tuner(struct rt2x00_dev
void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev);
void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev);
void rt2800_rf_self_txdc_cal(struct rt2x00_dev *rt2x00dev); void rt2800_rf_self_txdc_cal(struct rt2x00_dev *rt2x00dev);
@ -182,7 +182,7 @@
void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -573,6 +573,8 @@ struct rt2x00lib_ops { @@ -575,6 +575,8 @@ struct rt2x00lib_ops {
void (*gain_calibration) (struct rt2x00_dev *rt2x00dev); void (*gain_calibration) (struct rt2x00_dev *rt2x00dev);
void (*vco_calibration) (struct rt2x00_dev *rt2x00dev); void (*vco_calibration) (struct rt2x00_dev *rt2x00dev);
void (*rf_self_txdc_cal) (struct rt2x00_dev *rt2x00dev); void (*rf_self_txdc_cal) (struct rt2x00_dev *rt2x00dev);

View File

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -8555,6 +8555,71 @@ void rt2800_r_calibration(struct rt2x00_ @@ -8639,6 +8639,71 @@ void rt2800_r_calibration(struct rt2x00_
} }
EXPORT_SYMBOL_GPL(rt2800_r_calibration); EXPORT_SYMBOL_GPL(rt2800_r_calibration);
@ -72,7 +72,7 @@
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
bool set_bw, bool is_ht40) bool set_bw, bool is_ht40)
{ {
@@ -9164,6 +9229,7 @@ static void rt2800_init_rfcsr_6352(struc @@ -9248,6 +9313,7 @@ static void rt2800_init_rfcsr_6352(struc
rt2800_r_calibration(rt2x00dev); rt2800_r_calibration(rt2x00dev);
rt2800_rf_self_txdc_cal(rt2x00dev); rt2800_rf_self_txdc_cal(rt2x00dev);
@ -82,7 +82,7 @@
} }
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
@@ -246,6 +246,7 @@ void rt2800_vco_calibration(struct rt2x0 @@ -256,6 +256,7 @@ void rt2800_vco_calibration(struct rt2x0
void rt2800_rf_self_txdc_cal(struct rt2x00_dev *rt2x00dev); void rt2800_rf_self_txdc_cal(struct rt2x00_dev *rt2x00dev);
int rt2800_calcrcalibrationcode(struct rt2x00_dev *rt2x00dev, int d1, int d2); int rt2800_calcrcalibrationcode(struct rt2x00_dev *rt2x00dev, int d1, int d2);
void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev);
@ -92,7 +92,7 @@
void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -575,6 +575,7 @@ struct rt2x00lib_ops { @@ -577,6 +577,7 @@ struct rt2x00lib_ops {
void (*rf_self_txdc_cal) (struct rt2x00_dev *rt2x00dev); void (*rf_self_txdc_cal) (struct rt2x00_dev *rt2x00dev);
int (*calcrcalibrationcode) (struct rt2x00_dev *rt2x00dev, int d1, int d2); int (*calcrcalibrationcode) (struct rt2x00_dev *rt2x00dev, int d1, int d2);
void (*r_calibration) (struct rt2x00_dev *rt2x00dev); void (*r_calibration) (struct rt2x00_dev *rt2x00dev);

View File

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -8620,6 +8620,386 @@ void rt2800_rxdcoc_calibration(struct rt @@ -8704,6 +8704,386 @@ void rt2800_rxdcoc_calibration(struct rt
} }
EXPORT_SYMBOL_GPL(rt2800_rxdcoc_calibration); EXPORT_SYMBOL_GPL(rt2800_rxdcoc_calibration);
@ -387,7 +387,7 @@
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
bool set_bw, bool is_ht40) bool set_bw, bool is_ht40)
{ {
@@ -9232,6 +9612,7 @@ static void rt2800_init_rfcsr_6352(struc @@ -9316,6 +9696,7 @@ static void rt2800_init_rfcsr_6352(struc
rt2800_rxdcoc_calibration(rt2x00dev); rt2800_rxdcoc_calibration(rt2x00dev);
rt2800_bw_filter_calibration(rt2x00dev, true); rt2800_bw_filter_calibration(rt2x00dev, true);
rt2800_bw_filter_calibration(rt2x00dev, false); rt2800_bw_filter_calibration(rt2x00dev, false);
@ -397,7 +397,7 @@
static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
@@ -247,6 +247,7 @@ void rt2800_rf_self_txdc_cal(struct rt2x @@ -257,6 +257,7 @@ void rt2800_rf_self_txdc_cal(struct rt2x
int rt2800_calcrcalibrationcode(struct rt2x00_dev *rt2x00dev, int d1, int d2); int rt2800_calcrcalibrationcode(struct rt2x00_dev *rt2x00dev, int d1, int d2);
void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev);
void rt2800_rxdcoc_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_rxdcoc_calibration(struct rt2x00_dev *rt2x00dev);
@ -407,7 +407,7 @@
void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -576,6 +576,7 @@ struct rt2x00lib_ops { @@ -578,6 +578,7 @@ struct rt2x00lib_ops {
int (*calcrcalibrationcode) (struct rt2x00_dev *rt2x00dev, int d1, int d2); int (*calcrcalibrationcode) (struct rt2x00_dev *rt2x00dev, int d1, int d2);
void (*r_calibration) (struct rt2x00_dev *rt2x00dev); void (*r_calibration) (struct rt2x00_dev *rt2x00dev);
void (*rxdcoc_calibration) (struct rt2x00_dev *rt2x00dev); void (*rxdcoc_calibration) (struct rt2x00_dev *rt2x00dev);

View File

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -9000,6 +9000,954 @@ restore_value: @@ -9084,6 +9084,954 @@ restore_value:
} }
EXPORT_SYMBOL_GPL(rt2800_rxiq_calibration); EXPORT_SYMBOL_GPL(rt2800_rxiq_calibration);
@ -955,7 +955,7 @@
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
bool set_bw, bool is_ht40) bool set_bw, bool is_ht40)
{ {
@@ -9612,6 +10560,7 @@ static void rt2800_init_rfcsr_6352(struc @@ -9696,6 +10644,7 @@ static void rt2800_init_rfcsr_6352(struc
rt2800_rxdcoc_calibration(rt2x00dev); rt2800_rxdcoc_calibration(rt2x00dev);
rt2800_bw_filter_calibration(rt2x00dev, true); rt2800_bw_filter_calibration(rt2x00dev, true);
rt2800_bw_filter_calibration(rt2x00dev, false); rt2800_bw_filter_calibration(rt2x00dev, false);
@ -982,7 +982,7 @@
/* RT2800 driver data structure */ /* RT2800 driver data structure */
struct rt2800_drv_data { struct rt2800_drv_data {
@@ -248,6 +258,7 @@ int rt2800_calcrcalibrationcode(struct r @@ -258,6 +268,7 @@ int rt2800_calcrcalibrationcode(struct r
void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev);
void rt2800_rxdcoc_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_rxdcoc_calibration(struct rt2x00_dev *rt2x00dev);
void rt2800_rxiq_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_rxiq_calibration(struct rt2x00_dev *rt2x00dev);
@ -992,7 +992,7 @@
void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -577,6 +577,7 @@ struct rt2x00lib_ops { @@ -579,6 +579,7 @@ struct rt2x00lib_ops {
void (*r_calibration) (struct rt2x00_dev *rt2x00dev); void (*r_calibration) (struct rt2x00_dev *rt2x00dev);
void (*rxdcoc_calibration) (struct rt2x00_dev *rt2x00dev); void (*rxdcoc_calibration) (struct rt2x00_dev *rt2x00dev);
void (*rxiq_calibration) (struct rt2x00_dev *rt2x00dev); void (*rxiq_calibration) (struct rt2x00_dev *rt2x00dev);

View File

@ -0,0 +1,61 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Sat, 28 Sep 2019 15:44:06 +0200
Subject: [PATCH] mac80211: minstrel: remove divisions in tx status path
Use a slightly different threshold for downgrading spatial streams to
make it easier to calculate without divisions.
Slightly reduces CPU overhead.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -295,8 +295,7 @@ minstrel_tx_status(void *priv, struct ie
if (mi->sample_deferred > 0)
mi->sample_deferred--;
- if (time_after(jiffies, mi->last_stats_update +
- (mp->update_interval * HZ) / 1000))
+ if (time_after(jiffies, mi->last_stats_update + mp->update_interval))
minstrel_update_stats(mp, mi);
}
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -937,23 +937,21 @@ minstrel_ht_tx_status(void *priv, struct
*/
rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]);
if (rate->attempts > 30 &&
- MINSTREL_FRAC(rate->success, rate->attempts) <
- MINSTREL_FRAC(20, 100)) {
+ rate->success < rate->attempts / 4) {
minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true);
update = true;
}
rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]);
if (rate2->attempts > 30 &&
- MINSTREL_FRAC(rate2->success, rate2->attempts) <
- MINSTREL_FRAC(20, 100)) {
+ rate2->success < rate2->attempts / 4) {
minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false);
update = true;
}
}
if (time_after(jiffies, mi->last_stats_update +
- (mp->update_interval / 2 * HZ) / 1000)) {
+ mp->update_interval / 2)) {
update = true;
minstrel_ht_update_stats(mp, mi, true);
}
@@ -1640,7 +1638,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h
mp->has_mrr = true;
mp->hw = hw;
- mp->update_interval = 100;
+ mp->update_interval = HZ / 10;
#ifdef CPTCFG_MAC80211_DEBUGFS
mp->fixed_rate_idx = (u32) -1;

View File

@ -0,0 +1,235 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Sat, 28 Sep 2019 15:46:06 +0200
Subject: [PATCH] mac80211: minstrel_ht: replace rate stats ewma with a
better moving average
Rate success probability usually fluctuates a lot under normal conditions.
With a simple EWMA, noise and fluctuation can be reduced by increasing the
window length, but that comes at the cost of introducing lag on sudden
changes.
This change replaces the EWMA implementation with a moving average that's
designed to significantly reduce lag while keeping a bigger window size
by being better at filtering out noise.
It is only slightly more expensive than the simple EWMA and still avoids
divisions in its calculation.
The algorithm is adapted from an implementation intended for a completely
different field (stock market trading), where the tradeoff of lag vs
noise filtering is equally important.
The algorithm works in the same way as the "smoothing filter" from
http://www.stockspotter.com/files/PredictiveIndicators.pdf adapted for
fixed-point math with some constants, using only addition, bit shifts
and multiplication
To better make use of the filtering and bigger window size, the update
interval is cut in half.
For testing, the algorithm can be reverted to the older one via debugfs
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -157,14 +157,18 @@ minstrel_update_rates(struct minstrel_pr
* Recalculate statistics and counters of a given rate
*/
void
-minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs)
+minstrel_calc_rate_stats(struct minstrel_priv *mp,
+ struct minstrel_rate_stats *mrs)
{
unsigned int cur_prob;
if (unlikely(mrs->attempts > 0)) {
mrs->sample_skipped = 0;
cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
- if (unlikely(!mrs->att_hist)) {
+ if (mp->new_avg) {
+ mrs->prob_ewma = minstrel_filter_avg_add(&mrs->avg,
+ cur_prob);
+ } else if (unlikely(!mrs->att_hist)) {
mrs->prob_ewma = cur_prob;
} else {
/* update exponential weighted moving variance */
@@ -206,7 +210,7 @@ minstrel_update_stats(struct minstrel_pr
struct minstrel_rate_stats *tmp_mrs = &mi->r[tmp_prob_rate].stats;
/* Update statistics of success probability per rate */
- minstrel_calc_rate_stats(mrs);
+ minstrel_calc_rate_stats(mp, mrs);
/* Sample less often below the 10% chance of success.
* Sample less often above the 95% chance of success. */
@@ -295,7 +299,8 @@ minstrel_tx_status(void *priv, struct ie
if (mi->sample_deferred > 0)
mi->sample_deferred--;
- if (time_after(jiffies, mi->last_stats_update + mp->update_interval))
+ if (time_after(jiffies, mi->last_stats_update +
+ mp->update_interval / (mp->new_avg ? 2 : 1)))
minstrel_update_stats(mp, mi);
}
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -22,6 +22,21 @@
#define MAX_THR_RATES 4
/*
+ * Coefficients for moving average with noise filter (period=16),
+ * scaled by 10 bits
+ *
+ * a1 = exp(-pi * sqrt(2) / period)
+ * coeff2 = 2 * a1 * cos(sqrt(2) * 2 * pi / period)
+ * coeff3 = -sqr(a1)
+ * coeff1 = 1 - coeff2 - coeff3
+ */
+#define MINSTREL_AVG_COEFF1 (MINSTREL_FRAC(1, 1) - \
+ MINSTREL_AVG_COEFF2 - \
+ MINSTREL_AVG_COEFF3)
+#define MINSTREL_AVG_COEFF2 0x00001499
+#define MINSTREL_AVG_COEFF3 -0x0000092e
+
+/*
* Perform EWMA (Exponentially Weighted Moving Average) calculation
*/
static inline int
@@ -48,6 +63,41 @@ minstrel_ewmv(int old_ewmv, int cur_prob
return weight * (old_ewmv + MINSTREL_TRUNC(diff * incr)) / EWMA_DIV;
}
+struct minstrel_avg_ctx {
+ s32 prev[2];
+};
+
+static inline int minstrel_filter_avg_add(struct minstrel_avg_ctx *ctx, s32 in)
+{
+ s32 out_1 = ctx->prev[0];
+ s32 out_2 = ctx->prev[1];
+ s32 val;
+
+ if (!in)
+ in += 1;
+
+ if (!out_1) {
+ val = out_1 = in;
+ goto out;
+ }
+
+ val = MINSTREL_AVG_COEFF1 * in;
+ val += MINSTREL_AVG_COEFF2 * out_1;
+ val += MINSTREL_AVG_COEFF3 * out_2;
+ val >>= MINSTREL_SCALE;
+
+ if (val > 1 << MINSTREL_SCALE)
+ val = 1 << MINSTREL_SCALE;
+ if (val < 0)
+ val = 1;
+
+out:
+ ctx->prev[1] = out_1;
+ ctx->prev[0] = val;
+
+ return val;
+}
+
struct minstrel_rate_stats {
/* current / last sampling period attempts/success counters */
u16 attempts, last_attempts;
@@ -56,6 +106,8 @@ struct minstrel_rate_stats {
/* total attempts/success counters */
u32 att_hist, succ_hist;
+ struct minstrel_avg_ctx avg;
+
/* statistis of packet delivery probability
* prob_ewma - exponential weighted moving average of prob
* prob_ewmsd - exp. weighted moving standard deviation of prob */
@@ -114,6 +166,7 @@ struct minstrel_sta_info {
struct minstrel_priv {
struct ieee80211_hw *hw;
bool has_mrr;
+ bool new_avg;
u32 sample_switch;
unsigned int cw_min;
unsigned int cw_max;
@@ -153,7 +206,8 @@ extern const struct rate_control_ops mac
void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
/* Recalculate success probabilities and counters for a given rate using EWMA */
-void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs);
+void minstrel_calc_rate_stats(struct minstrel_priv *mp,
+ struct minstrel_rate_stats *mrs);
int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma);
/* debugfs */
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -704,7 +704,7 @@ minstrel_ht_update_stats(struct minstrel
mrs = &mg->rates[i];
mrs->retry_updated = false;
- minstrel_calc_rate_stats(mrs);
+ minstrel_calc_rate_stats(mp, mrs);
cur_prob = mrs->prob_ewma;
if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0)
@@ -740,6 +740,8 @@ minstrel_ht_update_stats(struct minstrel
/* try to sample all available rates during each interval */
mi->sample_count *= 8;
+ if (mp->new_avg)
+ mi->sample_count /= 2;
if (sample)
minstrel_ht_rate_sample_switch(mp, mi);
@@ -856,6 +858,7 @@ minstrel_ht_tx_status(void *priv, struct
struct ieee80211_tx_rate *ar = info->status.rates;
struct minstrel_rate_stats *rate, *rate2, *rate_sample = NULL;
struct minstrel_priv *mp = priv;
+ u32 update_interval = mp->update_interval / 2;
bool last, update = false;
bool sample_status = false;
int i;
@@ -910,6 +913,10 @@ minstrel_ht_tx_status(void *priv, struct
switch (mi->sample_mode) {
case MINSTREL_SAMPLE_IDLE:
+ if (mp->new_avg &&
+ (mp->hw->max_rates > 1 ||
+ mi->total_packets_cur < SAMPLE_SWITCH_THR))
+ update_interval /= 2;
break;
case MINSTREL_SAMPLE_ACTIVE:
@@ -950,8 +957,7 @@ minstrel_ht_tx_status(void *priv, struct
}
}
- if (time_after(jiffies, mi->last_stats_update +
- mp->update_interval / 2)) {
+ if (time_after(jiffies, mi->last_stats_update + update_interval)) {
update = true;
minstrel_ht_update_stats(mp, mi, true);
}
@@ -1639,6 +1645,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h
mp->hw = hw;
mp->update_interval = HZ / 10;
+ mp->new_avg = true;
#ifdef CPTCFG_MAC80211_DEBUGFS
mp->fixed_rate_idx = (u32) -1;
@@ -1646,6 +1653,8 @@ minstrel_ht_alloc(struct ieee80211_hw *h
&mp->fixed_rate_idx);
debugfs_create_u32("sample_switch", S_IRUGO | S_IWUSR, debugfsdir,
&mp->sample_switch);
+ debugfs_create_bool("new_avg", S_IRUGO | S_IWUSR, debugfsdir,
+ &mp->new_avg);
#endif
minstrel_ht_init_cck_rates(mp);

View File

@ -0,0 +1,437 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Tue, 8 Oct 2019 18:54:46 +0200
Subject: [PATCH] mac80211: minstrel_ht: rename prob_ewma to prob_avg, use it
for the new average
Reduces per-rate data structure size
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -70,7 +70,7 @@ rix_to_ndx(struct minstrel_sta_info *mi,
}
/* return current EMWA throughput */
-int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma)
+int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_avg)
{
int usecs;
@@ -79,13 +79,13 @@ int minstrel_get_tp_avg(struct minstrel_
usecs = 1000000;
/* reset thr. below 10% success */
- if (mr->stats.prob_ewma < MINSTREL_FRAC(10, 100))
+ if (mr->stats.prob_avg < MINSTREL_FRAC(10, 100))
return 0;
- if (prob_ewma > MINSTREL_FRAC(90, 100))
+ if (prob_avg > MINSTREL_FRAC(90, 100))
return MINSTREL_TRUNC(100000 * (MINSTREL_FRAC(90, 100) / usecs));
else
- return MINSTREL_TRUNC(100000 * (prob_ewma / usecs));
+ return MINSTREL_TRUNC(100000 * (prob_avg / usecs));
}
/* find & sort topmost throughput rates */
@@ -98,8 +98,8 @@ minstrel_sort_best_tp_rates(struct minst
for (j = MAX_THR_RATES; j > 0; --j) {
tmp_mrs = &mi->r[tp_list[j - 1]].stats;
- if (minstrel_get_tp_avg(&mi->r[i], cur_mrs->prob_ewma) <=
- minstrel_get_tp_avg(&mi->r[tp_list[j - 1]], tmp_mrs->prob_ewma))
+ if (minstrel_get_tp_avg(&mi->r[i], cur_mrs->prob_avg) <=
+ minstrel_get_tp_avg(&mi->r[tp_list[j - 1]], tmp_mrs->prob_avg))
break;
}
@@ -166,21 +166,21 @@ minstrel_calc_rate_stats(struct minstrel
mrs->sample_skipped = 0;
cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
if (mp->new_avg) {
- mrs->prob_ewma = minstrel_filter_avg_add(&mrs->avg,
- cur_prob);
+ minstrel_filter_avg_add(&mrs->prob_avg,
+ &mrs->prob_avg_1, cur_prob);
} else if (unlikely(!mrs->att_hist)) {
- mrs->prob_ewma = cur_prob;
+ mrs->prob_avg = cur_prob;
} else {
/* update exponential weighted moving variance */
mrs->prob_ewmv = minstrel_ewmv(mrs->prob_ewmv,
cur_prob,
- mrs->prob_ewma,
+ mrs->prob_avg,
EWMA_LEVEL);
/*update exponential weighted moving avarage */
- mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma,
- cur_prob,
- EWMA_LEVEL);
+ mrs->prob_avg = minstrel_ewma(mrs->prob_avg,
+ cur_prob,
+ EWMA_LEVEL);
}
mrs->att_hist += mrs->attempts;
mrs->succ_hist += mrs->success;
@@ -214,8 +214,8 @@ minstrel_update_stats(struct minstrel_pr
/* Sample less often below the 10% chance of success.
* Sample less often above the 95% chance of success. */
- if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) ||
- mrs->prob_ewma < MINSTREL_FRAC(10, 100)) {
+ if (mrs->prob_avg > MINSTREL_FRAC(95, 100) ||
+ mrs->prob_avg < MINSTREL_FRAC(10, 100)) {
mr->adjusted_retry_count = mrs->retry_count >> 1;
if (mr->adjusted_retry_count > 2)
mr->adjusted_retry_count = 2;
@@ -235,14 +235,14 @@ minstrel_update_stats(struct minstrel_pr
* choose the maximum throughput rate as max_prob_rate
* (2) if all success probabilities < 95%, the rate with
* highest success probability is chosen as max_prob_rate */
- if (mrs->prob_ewma >= MINSTREL_FRAC(95, 100)) {
- tmp_cur_tp = minstrel_get_tp_avg(mr, mrs->prob_ewma);
+ if (mrs->prob_avg >= MINSTREL_FRAC(95, 100)) {
+ tmp_cur_tp = minstrel_get_tp_avg(mr, mrs->prob_avg);
tmp_prob_tp = minstrel_get_tp_avg(&mi->r[tmp_prob_rate],
- tmp_mrs->prob_ewma);
+ tmp_mrs->prob_avg);
if (tmp_cur_tp >= tmp_prob_tp)
tmp_prob_rate = i;
} else {
- if (mrs->prob_ewma >= tmp_mrs->prob_ewma)
+ if (mrs->prob_avg >= tmp_mrs->prob_avg)
tmp_prob_rate = i;
}
}
@@ -436,7 +436,7 @@ minstrel_get_rate(void *priv, struct iee
* has a probability of >95%, we shouldn't be attempting
* to use it, as this only wastes precious airtime */
if (!mrr_capable &&
- (mi->r[ndx].stats.prob_ewma > MINSTREL_FRAC(95, 100)))
+ (mi->r[ndx].stats.prob_avg > MINSTREL_FRAC(95, 100)))
return;
mi->prev_sample = true;
@@ -587,7 +587,7 @@ static u32 minstrel_get_expected_through
* computing cur_tp
*/
tmp_mrs = &mi->r[idx].stats;
- tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_ewma) * 10;
+ tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_avg) * 10;
tmp_cur_tp = tmp_cur_tp * 1200 * 8 / 1024;
return tmp_cur_tp;
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -63,14 +63,10 @@ minstrel_ewmv(int old_ewmv, int cur_prob
return weight * (old_ewmv + MINSTREL_TRUNC(diff * incr)) / EWMA_DIV;
}
-struct minstrel_avg_ctx {
- s32 prev[2];
-};
-
-static inline int minstrel_filter_avg_add(struct minstrel_avg_ctx *ctx, s32 in)
+static inline int minstrel_filter_avg_add(u16 *prev_1, u16 *prev_2, s32 in)
{
- s32 out_1 = ctx->prev[0];
- s32 out_2 = ctx->prev[1];
+ s32 out_1 = *prev_1;
+ s32 out_2 = *prev_2;
s32 val;
if (!in)
@@ -92,8 +88,8 @@ static inline int minstrel_filter_avg_ad
val = 1;
out:
- ctx->prev[1] = out_1;
- ctx->prev[0] = val;
+ *prev_2 = out_1;
+ *prev_1 = val;
return val;
}
@@ -106,14 +102,15 @@ struct minstrel_rate_stats {
/* total attempts/success counters */
u32 att_hist, succ_hist;
- struct minstrel_avg_ctx avg;
-
/* statistis of packet delivery probability
* prob_ewma - exponential weighted moving average of prob
* prob_ewmsd - exp. weighted moving standard deviation of prob */
- u16 prob_ewma;
u16 prob_ewmv;
+ /* prob_avg - moving average of prob */
+ u16 prob_avg;
+ u16 prob_avg_1;
+
/* maximum retry counts */
u8 retry_count;
u8 retry_count_rtscts;
@@ -208,7 +205,7 @@ void minstrel_add_sta_debugfs(void *priv
/* Recalculate success probabilities and counters for a given rate using EWMA */
void minstrel_calc_rate_stats(struct minstrel_priv *mp,
struct minstrel_rate_stats *mrs);
-int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma);
+int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_avg);
/* debugfs */
int minstrel_stats_open(struct inode *inode, struct file *file);
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -91,8 +91,9 @@ minstrel_stats_open(struct inode *inode,
p += sprintf(p, "%6u ", mr->perfect_tx_time);
tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
- tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
- eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
+ tp_avg = minstrel_get_tp_avg(mr, mrs->prob_avg);
+ eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000);
+
prob_ewmsd = minstrel_get_ewmsd10(mrs);
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u"
@@ -151,8 +152,8 @@ minstrel_stats_csv_open(struct inode *in
p += sprintf(p, "%u,",mr->perfect_tx_time);
tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
- tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
- eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
+ tp_avg = minstrel_get_tp_avg(mr, mrs->prob_avg);
+ eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000);
prob_ewmsd = minstrel_get_ewmsd10(mrs);
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u,"
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -313,12 +313,12 @@ minstrel_ht_avg_ampdu_len(struct minstre
*/
int
minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate,
- int prob_ewma)
+ int prob_avg)
{
unsigned int nsecs = 0;
/* do not account throughput if sucess prob is below 10% */
- if (prob_ewma < MINSTREL_FRAC(10, 100))
+ if (prob_avg < MINSTREL_FRAC(10, 100))
return 0;
if (group != MINSTREL_CCK_GROUP)
@@ -332,11 +332,11 @@ minstrel_ht_get_tp_avg(struct minstrel_h
* account for collision related packet error rate fluctuation
* (prob is scaled - see MINSTREL_FRAC above)
*/
- if (prob_ewma > MINSTREL_FRAC(90, 100))
+ if (prob_avg > MINSTREL_FRAC(90, 100))
return MINSTREL_TRUNC(100000 * ((MINSTREL_FRAC(90, 100) * 1000)
/ nsecs));
else
- return MINSTREL_TRUNC(100000 * ((prob_ewma * 1000) / nsecs));
+ return MINSTREL_TRUNC(100000 * ((prob_avg * 1000) / nsecs));
}
/*
@@ -356,13 +356,13 @@ minstrel_ht_sort_best_tp_rates(struct mi
cur_group = index / MCS_GROUP_RATES;
cur_idx = index % MCS_GROUP_RATES;
- cur_prob = mi->groups[cur_group].rates[cur_idx].prob_ewma;
+ cur_prob = mi->groups[cur_group].rates[cur_idx].prob_avg;
cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, cur_prob);
do {
tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx,
tmp_prob);
if (cur_tp_avg < tmp_tp_avg ||
@@ -399,7 +399,7 @@ minstrel_ht_set_best_prob_rate(struct mi
tmp_group = mi->max_prob_rate / MCS_GROUP_RATES;
tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES;
- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
/* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from
@@ -411,11 +411,11 @@ minstrel_ht_set_best_prob_rate(struct mi
max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES;
max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
- max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_ewma;
+ max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg;
- if (mrs->prob_ewma > MINSTREL_FRAC(75, 100)) {
+ if (mrs->prob_avg > MINSTREL_FRAC(75, 100)) {
cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx,
- mrs->prob_ewma);
+ mrs->prob_avg);
if (cur_tp_avg > tmp_tp_avg)
mi->max_prob_rate = index;
@@ -425,9 +425,9 @@ minstrel_ht_set_best_prob_rate(struct mi
if (cur_tp_avg > max_gpr_tp_avg)
mg->max_group_prob_rate = index;
} else {
- if (mrs->prob_ewma > tmp_prob)
+ if (mrs->prob_avg > tmp_prob)
mi->max_prob_rate = index;
- if (mrs->prob_ewma > max_gpr_prob)
+ if (mrs->prob_avg > max_gpr_prob)
mg->max_group_prob_rate = index;
}
}
@@ -449,12 +449,12 @@ minstrel_ht_assign_best_tp_rates(struct
tmp_group = tmp_cck_tp_rate[0] / MCS_GROUP_RATES;
tmp_idx = tmp_cck_tp_rate[0] % MCS_GROUP_RATES;
- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
tmp_cck_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
tmp_group = tmp_mcs_tp_rate[0] / MCS_GROUP_RATES;
tmp_idx = tmp_mcs_tp_rate[0] % MCS_GROUP_RATES;
- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
if (tmp_cck_tp_rate && tmp_cck_tp > tmp_mcs_tp) {
@@ -485,7 +485,7 @@ minstrel_ht_prob_rate_reduce_streams(str
continue;
tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
- tmp_prob = mi->groups[group].rates[tmp_idx].prob_ewma;
+ tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg;
if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) &&
(minstrel_mcs_groups[group].streams < tmp_max_streams)) {
@@ -590,7 +590,7 @@ minstrel_ht_rate_sample_switch(struct mi
* If that fails, look again for a rate that is at least as fast
*/
mrs = minstrel_get_ratestats(mi, mi->max_tp_rate[0]);
- faster_rate = mrs->prob_ewma > MINSTREL_FRAC(75, 100);
+ faster_rate = mrs->prob_avg > MINSTREL_FRAC(75, 100);
minstrel_ht_find_probe_rates(mi, rates, &n_rates, faster_rate);
if (!n_rates && faster_rate)
minstrel_ht_find_probe_rates(mi, rates, &n_rates, false);
@@ -705,7 +705,7 @@ minstrel_ht_update_stats(struct minstrel
mrs = &mg->rates[i];
mrs->retry_updated = false;
minstrel_calc_rate_stats(mp, mrs);
- cur_prob = mrs->prob_ewma;
+ cur_prob = mrs->prob_avg;
if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0)
continue;
@@ -979,7 +979,7 @@ minstrel_calc_retransmit(struct minstrel
unsigned int overhead = 0, overhead_rtscts = 0;
mrs = minstrel_get_ratestats(mi, index);
- if (mrs->prob_ewma < MINSTREL_FRAC(1, 10)) {
+ if (mrs->prob_avg < MINSTREL_FRAC(1, 10)) {
mrs->retry_count = 1;
mrs->retry_count_rtscts = 1;
return;
@@ -1036,7 +1036,7 @@ minstrel_ht_set_rate(struct minstrel_pri
if (!mrs->retry_updated)
minstrel_calc_retransmit(mp, mi, index);
- if (mrs->prob_ewma < MINSTREL_FRAC(20, 100) || !mrs->retry_count) {
+ if (mrs->prob_avg < MINSTREL_FRAC(20, 100) || !mrs->retry_count) {
ratetbl->rate[offset].count = 2;
ratetbl->rate[offset].count_rts = 2;
ratetbl->rate[offset].count_cts = 2;
@@ -1070,11 +1070,11 @@ minstrel_ht_set_rate(struct minstrel_pri
}
static inline int
-minstrel_ht_get_prob_ewma(struct minstrel_ht_sta *mi, int rate)
+minstrel_ht_get_prob_avg(struct minstrel_ht_sta *mi, int rate)
{
int group = rate / MCS_GROUP_RATES;
rate %= MCS_GROUP_RATES;
- return mi->groups[group].rates[rate].prob_ewma;
+ return mi->groups[group].rates[rate].prob_avg;
}
static int
@@ -1086,7 +1086,7 @@ minstrel_ht_get_max_amsdu_len(struct min
unsigned int duration;
/* Disable A-MSDU if max_prob_rate is bad */
- if (mi->groups[group].rates[rate].prob_ewma < MINSTREL_FRAC(50, 100))
+ if (mi->groups[group].rates[rate].prob_avg < MINSTREL_FRAC(50, 100))
return 1;
duration = g->duration[rate];
@@ -1109,7 +1109,7 @@ minstrel_ht_get_max_amsdu_len(struct min
* data packet size
*/
if (duration > MCS_DURATION(1, 0, 260) ||
- (minstrel_ht_get_prob_ewma(mi, mi->max_tp_rate[0]) <
+ (minstrel_ht_get_prob_avg(mi, mi->max_tp_rate[0]) <
MINSTREL_FRAC(75, 100)))
return 3200;
@@ -1216,7 +1216,7 @@ minstrel_get_sample_rate(struct minstrel
* rate, to avoid wasting airtime.
*/
sample_dur = minstrel_get_duration(sample_idx);
- if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) ||
+ if (mrs->prob_avg > MINSTREL_FRAC(95, 100) ||
minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur)
return -1;
@@ -1679,7 +1679,7 @@ static u32 minstrel_ht_get_expected_thro
i = mi->max_tp_rate[0] / MCS_GROUP_RATES;
j = mi->max_tp_rate[0] % MCS_GROUP_RATES;
- prob = mi->groups[i].rates[j].prob_ewma;
+ prob = mi->groups[i].rates[j].prob_avg;
/* convert tp_avg from pkt per second in kbps */
tp_avg = minstrel_ht_get_tp_avg(mi, i, j, prob) * 10;
--- a/net/mac80211/rc80211_minstrel_ht.h
+++ b/net/mac80211/rc80211_minstrel_ht.h
@@ -122,6 +122,6 @@ struct minstrel_ht_sta_priv {
void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
int minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate,
- int prob_ewma);
+ int prob_avg);
#endif
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
@@ -102,8 +102,8 @@ minstrel_ht_stats_dump(struct minstrel_h
p += sprintf(p, "%6u ", tx_time);
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
- tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
- eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
+ tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_avg);
+ eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000);
prob_ewmsd = minstrel_get_ewmsd10(mrs);
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u"
@@ -250,8 +250,8 @@ minstrel_ht_stats_csv_dump(struct minstr
p += sprintf(p, "%u,", tx_time);
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
- tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
- eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
+ tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_avg);
+ eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000);
prob_ewmsd = minstrel_get_ewmsd10(mrs);
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,"