mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00
mac80211: update upstream patches
This commit is contained in:
parent
be770de958
commit
384e5abd02
@ -299,14 +299,14 @@ endef
|
||||
define KernelPackage/rsi91x
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
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
|
||||
endef
|
||||
|
||||
define KernelPackage/rsi91x-usb
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
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
|
||||
AUTOLOAD:=$(call AutoProbe,rsi_usb)
|
||||
endef
|
||||
|
@ -113,7 +113,7 @@ detect_mac80211() {
|
||||
set wireless.radio${devidx}.hwmode=11${mode_band}
|
||||
${dev_id}
|
||||
${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}.device=radio${devidx}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
@ -232,7 +232,14 @@
|
||||
+ 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);
|
||||
+ if (t & data->bootstrap_ref)
|
||||
+ pdata->is_clk_25mhz = false;
|
||||
@ -252,7 +259,7 @@
|
||||
static int ath_ahb_probe(struct platform_device *pdev)
|
||||
{
|
||||
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;
|
||||
struct ath_hw *ah;
|
||||
char hw_name[64];
|
||||
@ -270,7 +277,7 @@
|
||||
|
||||
if (!dev_get_platdata(&pdev->dev)) {
|
||||
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->irq = irq;
|
||||
|
||||
@ -288,7 +295,7 @@
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to initialize device\n");
|
||||
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);
|
||||
ieee80211_free_hw(sc->hw);
|
||||
}
|
||||
@ -298,7 +305,7 @@
|
||||
|
||||
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,
|
||||
.driver = {
|
||||
.name = "ath9k",
|
||||
|
@ -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;
|
||||
}
|
@ -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 = {
|
@ -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;
|
@ -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);
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
@ -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,
|
@ -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);
|
@ -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.
|
||||
*/
|
@ -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);
|
@ -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;
|
@ -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) },
|
@ -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)
|
@ -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) {
|
@ -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));
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
@ -57,7 +57,7 @@
|
||||
struct rt2800_ops {
|
||||
u32 (*register_read)(struct rt2x00_dev *rt2x00dev,
|
||||
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;
|
||||
|
||||
@ -105,7 +105,7 @@
|
||||
.drv_init_registers = rt2800mmio_init_registers,
|
||||
--- a/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_PS_AUTOWAKE,
|
||||
REQUIRE_DELAYED_RFKILL,
|
||||
@ -113,7 +113,7 @@
|
||||
|
||||
/*
|
||||
* Capabilities
|
||||
@@ -977,6 +978,11 @@ struct rt2x00_dev {
|
||||
@@ -982,6 +983,11 @@ struct rt2x00_dev {
|
||||
const struct firmware *fw;
|
||||
|
||||
/*
|
||||
@ -127,7 +127,7 @@
|
||||
DECLARE_KFIFO_PTR(txstatus_fifo, u32);
|
||||
--- a/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_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
|
||||
|
||||
@ -138,7 +138,7 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
kfree(rt2x00dev->drv_data);
|
||||
|
@ -12,7 +12,7 @@
|
||||
#endif /* _RT2X00_PLATFORM_H */
|
||||
--- a/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 i;
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
num_rates += 4;
|
||||
--- a/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;
|
||||
#define SUPPORT_BAND_2GHZ 0x00000001
|
||||
#define SUPPORT_BAND_5GHZ 0x00000002
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/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)
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/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;
|
||||
unsigned int num_rates;
|
||||
unsigned int i;
|
||||
|
@ -13,7 +13,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
|
||||
--- a/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);
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "rt2x00.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_qual, LED_TYPE_QUALITY);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/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->max = rt2x00dev->ops->max_ap_intf;
|
||||
|
@ -30,7 +30,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
|
||||
* EEPROM LNA
|
||||
--- a/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);
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
|
||||
bbp = rt2800_bbp_read(rt2x00dev, 4);
|
||||
rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
|
||||
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);
|
||||
|
||||
@ -86,7 +86,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
|
||||
if (rt2x00_get_field16(eeprom,
|
||||
EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352))
|
||||
__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);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/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);
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
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, 17, 0x7C);
|
||||
|
||||
@ -69,7 +69,7 @@
|
||||
}
|
||||
--- a/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);
|
||||
void rt2800_gain_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);
|
||||
--- a/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);
|
||||
void (*gain_calibration) (struct rt2x00_dev *rt2x00dev);
|
||||
void (*vco_calibration) (struct rt2x00_dev *rt2x00dev);
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/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);
|
||||
|
||||
@ -161,7 +161,7 @@
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
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, 17, 0x7C);
|
||||
|
||||
@ -171,7 +171,7 @@
|
||||
rt2800_bw_filter_calibration(rt2x00dev, false);
|
||||
--- a/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_vco_calibration(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);
|
||||
--- a/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 (*vco_calibration) (struct rt2x00_dev *rt2x00dev);
|
||||
void (*rf_self_txdc_cal) (struct rt2x00_dev *rt2x00dev);
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/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);
|
||||
|
||||
@ -72,7 +72,7 @@
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
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_rf_self_txdc_cal(rt2x00dev);
|
||||
@ -82,7 +82,7 @@
|
||||
}
|
||||
--- a/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);
|
||||
int rt2800_calcrcalibrationcode(struct rt2x00_dev *rt2x00dev, int d1, int d2);
|
||||
void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev);
|
||||
@ -92,7 +92,7 @@
|
||||
void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
|
||||
--- a/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);
|
||||
int (*calcrcalibrationcode) (struct rt2x00_dev *rt2x00dev, int d1, int d2);
|
||||
void (*r_calibration) (struct rt2x00_dev *rt2x00dev);
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/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);
|
||||
|
||||
@ -387,7 +387,7 @@
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
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_bw_filter_calibration(rt2x00dev, true);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, false);
|
||||
@ -397,7 +397,7 @@
|
||||
static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
||||
--- a/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);
|
||||
void rt2800_r_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);
|
||||
--- a/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);
|
||||
void (*r_calibration) (struct rt2x00_dev *rt2x00dev);
|
||||
void (*rxdcoc_calibration) (struct rt2x00_dev *rt2x00dev);
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/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);
|
||||
|
||||
@ -955,7 +955,7 @@
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
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_bw_filter_calibration(rt2x00dev, true);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, false);
|
||||
@ -982,7 +982,7 @@
|
||||
|
||||
/* RT2800 driver data structure */
|
||||
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_rxdcoc_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);
|
||||
--- a/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 (*rxdcoc_calibration) (struct rt2x00_dev *rt2x00dev);
|
||||
void (*rxiq_calibration) (struct rt2x00_dev *rt2x00dev);
|
||||
|
@ -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;
|
@ -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);
|
@ -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,"
|
Loading…
Reference in New Issue
Block a user