* [PATCH 2/9] mt76: fix threshold for gain adjustment
2018-06-21 9:17 [PATCH 1/9] mt76: fix beacon timer drift Felix Fietkau
@ 2018-06-21 9:17 ` Felix Fietkau
2018-06-21 9:17 ` [PATCH 3/9] mt76: fix swapped values for RXO-18 in gain control Felix Fietkau
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Felix Fietkau @ 2018-06-21 9:17 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo
The gain should be reduced only for very strong connections, not for mid
range.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/mt76x2_phy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
index c1c38ca3330a..4ed6641c3a32 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
@@ -530,7 +530,7 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
else
mt76_wr(dev, MT_BBP(RXO, 14), 0x00560423);
- if (low_gain) {
+ if (low_gain == 2) {
mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a991);
mt76_wr(dev, MT_BBP(AGC, 35), 0x08080808);
mt76_wr(dev, MT_BBP(AGC, 37), 0x08080808);
--
2.17.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/9] mt76: fix swapped values for RXO-18 in gain control
2018-06-21 9:17 [PATCH 1/9] mt76: fix beacon timer drift Felix Fietkau
2018-06-21 9:17 ` [PATCH 2/9] mt76: fix threshold for gain adjustment Felix Fietkau
@ 2018-06-21 9:17 ` Felix Fietkau
2018-06-21 9:17 ` [PATCH 4/9] mt76: adjust AGC control register 26 based on gain for VHT80 Felix Fietkau
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Felix Fietkau @ 2018-06-21 9:17 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo
The lowest bit should be set to 0 only for strong links, not for weak
ones.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/mt76x2_phy.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
index 4ed6641c3a32..a510f116d52a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
@@ -531,7 +531,7 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
mt76_wr(dev, MT_BBP(RXO, 14), 0x00560423);
if (low_gain == 2) {
- mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a991);
+ mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a990);
mt76_wr(dev, MT_BBP(AGC, 35), 0x08080808);
mt76_wr(dev, MT_BBP(AGC, 37), 0x08080808);
if (mt76x2_has_ext_lna(dev))
@@ -539,7 +539,7 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
else
gain_delta = 14;
} else {
- mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a990);
+ mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a991);
if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80)
mt76_wr(dev, MT_BBP(AGC, 35), 0x10101014);
else
--
2.17.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/9] mt76: adjust AGC control register 26 based on gain for VHT80
2018-06-21 9:17 [PATCH 1/9] mt76: fix beacon timer drift Felix Fietkau
2018-06-21 9:17 ` [PATCH 2/9] mt76: fix threshold for gain adjustment Felix Fietkau
2018-06-21 9:17 ` [PATCH 3/9] mt76: fix swapped values for RXO-18 in gain control Felix Fietkau
@ 2018-06-21 9:17 ` Felix Fietkau
2018-06-21 9:17 ` [PATCH 5/9] mt76: clear false CCA counters after changing gain settings Felix Fietkau
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Felix Fietkau @ 2018-06-21 9:17 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo
Use values based on the vendor driver
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/mt76x2_phy.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
index a510f116d52a..a2c3f0e35f86 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
@@ -525,10 +525,17 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
dev->cal.low_gain = low_gain;
- if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80)
+ if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80) {
mt76_wr(dev, MT_BBP(RXO, 14), 0x00560211);
- else
+ val = mt76_rr(dev, MT_BBP(AGC, 26)) & ~0xf;
+ if (low_gain == 2)
+ val |= 0x3;
+ else
+ val |= 0x5;
+ mt76_wr(dev, MT_BBP(AGC, 26), val);
+ } else {
mt76_wr(dev, MT_BBP(RXO, 14), 0x00560423);
+ }
if (low_gain == 2) {
mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a990);
--
2.17.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/9] mt76: clear false CCA counters after changing gain settings
2018-06-21 9:17 [PATCH 1/9] mt76: fix beacon timer drift Felix Fietkau
` (2 preceding siblings ...)
2018-06-21 9:17 ` [PATCH 4/9] mt76: adjust AGC control register 26 based on gain for VHT80 Felix Fietkau
@ 2018-06-21 9:17 ` Felix Fietkau
2018-06-21 9:17 ` [PATCH 6/9] mt76: fix variable gain adjustment range Felix Fietkau
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Felix Fietkau @ 2018-06-21 9:17 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo
They will be read on the next calibration step without gain change and
must not count earlier events
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/mt76x2_phy.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
index a2c3f0e35f86..51fd7ddfa8f5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
@@ -559,6 +559,9 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
dev->cal.agc_gain_cur[1] = gain[1] - gain_delta;
dev->cal.agc_gain_adjust = 0;
mt76x2_phy_set_gain_val(dev);
+
+ /* clear false CCA counters */
+ mt76_rr(dev, MT_RX_STAT_1);
}
int mt76x2_phy_set_channel(struct mt76x2_dev *dev,
--
2.17.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/9] mt76: fix variable gain adjustment range
2018-06-21 9:17 [PATCH 1/9] mt76: fix beacon timer drift Felix Fietkau
` (3 preceding siblings ...)
2018-06-21 9:17 ` [PATCH 5/9] mt76: clear false CCA counters after changing gain settings Felix Fietkau
@ 2018-06-21 9:17 ` Felix Fietkau
2018-06-21 9:17 ` [PATCH 7/9] mt76: add a debugfs file to dump agc calibration information Felix Fietkau
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Felix Fietkau @ 2018-06-21 9:17 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo
The range should only be limited to 4 for really weak signals, for all
other gain settings the range is 16.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/mt76x2_phy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
index 51fd7ddfa8f5..9c7b19ce73f2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
@@ -485,7 +485,7 @@ static void
mt76x2_phy_adjust_vga_gain(struct mt76x2_dev *dev)
{
u32 false_cca;
- u8 limit = dev->cal.low_gain > 1 ? 4 : 16;
+ u8 limit = dev->cal.low_gain > 0 ? 16 : 4;
false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS, mt76_rr(dev, MT_RX_STAT_1));
if (false_cca > 800 && dev->cal.agc_gain_adjust < limit)
--
2.17.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 7/9] mt76: add a debugfs file to dump agc calibration information
2018-06-21 9:17 [PATCH 1/9] mt76: fix beacon timer drift Felix Fietkau
` (4 preceding siblings ...)
2018-06-21 9:17 ` [PATCH 6/9] mt76: fix variable gain adjustment range Felix Fietkau
@ 2018-06-21 9:17 ` Felix Fietkau
2018-06-21 9:18 ` [PATCH 8/9] mt76: track ewma rssi for gain adjustment per station Felix Fietkau
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Felix Fietkau @ 2018-06-21 9:17 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo
Useful for debugging gain adjustment issues triggered by signal strength
changes.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/mt76x2.h | 1 +
.../net/wireless/mediatek/mt76/mt76x2_debugfs.c | 14 ++++++++++++++
drivers/net/wireless/mediatek/mt76/mt76x2_phy.c | 1 +
3 files changed, 16 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h
index 06ca5a77dfdf..21de1168076d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h
@@ -72,6 +72,7 @@ struct mt76x2_calibration {
int avg_rssi[MT_MAX_CHAINS];
int avg_rssi_all;
+ u16 false_cca;
s8 agc_gain_adjust;
s8 low_gain;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c b/drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c
index 955ea3e692dd..3f86e01049f3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c
@@ -115,6 +115,18 @@ static const struct file_operations fops_dfs_stat = {
.release = single_release,
};
+static int read_agc(struct seq_file *file, void *data)
+{
+ struct mt76x2_dev *dev = dev_get_drvdata(file->private);
+
+ seq_printf(file, "avg_rssi: %d\n", dev->cal.avg_rssi_all);
+ seq_printf(file, "low_gain: %d\n", dev->cal.low_gain);
+ seq_printf(file, "false_cca: %d\n", dev->cal.false_cca);
+ seq_printf(file, "agc_gain_adjust: %d\n", dev->cal.agc_gain_adjust);
+
+ return 0;
+}
+
void mt76x2_init_debugfs(struct mt76x2_dev *dev)
{
struct dentry *dir;
@@ -130,4 +142,6 @@ void mt76x2_init_debugfs(struct mt76x2_dev *dev)
debugfs_create_file("dfs_stats", 0400, dir, dev, &fops_dfs_stat);
debugfs_create_devm_seqfile(dev->mt76.dev, "txpower", dir,
read_txpower);
+
+ debugfs_create_devm_seqfile(dev->mt76.dev, "agc", dir, read_agc);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
index 9c7b19ce73f2..94943aeb249d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
@@ -488,6 +488,7 @@ mt76x2_phy_adjust_vga_gain(struct mt76x2_dev *dev)
u8 limit = dev->cal.low_gain > 0 ? 16 : 4;
false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS, mt76_rr(dev, MT_RX_STAT_1));
+ dev->cal.false_cca = false_cca;
if (false_cca > 800 && dev->cal.agc_gain_adjust < limit)
dev->cal.agc_gain_adjust += 2;
else if (false_cca < 10 && dev->cal.agc_gain_adjust > 0)
--
2.17.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 8/9] mt76: track ewma rssi for gain adjustment per station
2018-06-21 9:17 [PATCH 1/9] mt76: fix beacon timer drift Felix Fietkau
` (5 preceding siblings ...)
2018-06-21 9:17 ` [PATCH 7/9] mt76: add a debugfs file to dump agc calibration information Felix Fietkau
@ 2018-06-21 9:18 ` Felix Fietkau
2018-06-21 9:18 ` [PATCH 9/9] mt76: improve gain adjustment in noisy environments Felix Fietkau
2018-06-27 16:16 ` [1/9] mt76: fix beacon timer drift Kalle Valo
8 siblings, 0 replies; 10+ messages in thread
From: Felix Fietkau @ 2018-06-21 9:18 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo
This preserves more sensitivity when weak stations are active and avoids
counting signal measurements from other unrelated networks
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/mt76x2.h | 10 +++-
.../net/wireless/mediatek/mt76/mt76x2_mac.c | 33 ++++++++---
.../net/wireless/mediatek/mt76/mt76x2_main.c | 2 +
.../net/wireless/mediatek/mt76/mt76x2_phy.c | 58 ++++++++++++++++---
4 files changed, 83 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h
index 21de1168076d..71fcfa44fb2e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h
@@ -27,6 +27,7 @@
#include <linux/mutex.h>
#include <linux/bitops.h>
#include <linux/kfifo.h>
+#include <linux/average.h>
#define MT7662_FIRMWARE "mt7662.bin"
#define MT7662_ROM_PATCH "mt7662_rom_patch.bin"
@@ -47,6 +48,8 @@
#include "mt76x2_mac.h"
#include "mt76x2_dfs.h"
+DECLARE_EWMA(signal, 10, 8)
+
struct mt76x2_mcu {
struct mutex mutex;
@@ -69,10 +72,8 @@ struct mt76x2_calibration {
u8 agc_gain_init[MT_MAX_CHAINS];
u8 agc_gain_cur[MT_MAX_CHAINS];
- int avg_rssi[MT_MAX_CHAINS];
- int avg_rssi_all;
-
u16 false_cca;
+ s8 avg_rssi_all;
s8 agc_gain_adjust;
s8 low_gain;
@@ -153,6 +154,9 @@ struct mt76x2_sta {
struct mt76x2_vif *vif;
struct mt76x2_tx_status status;
int n_frames;
+
+ struct ewma_signal rssi;
+ int inactive_count;
};
static inline bool is_mt7612(struct mt76x2_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
index b49aea4da2d6..f34b4d6413e3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
@@ -269,21 +269,31 @@ static void mt76x2_remove_hdr_pad(struct sk_buff *skb, int len)
skb_pull(skb, len);
}
-static struct mt76_wcid *
-mt76x2_rx_get_sta_wcid(struct mt76x2_dev *dev, u8 idx, bool unicast)
+static struct mt76x2_sta *
+mt76x2_rx_get_sta(struct mt76x2_dev *dev, u8 idx)
{
- struct mt76x2_sta *sta;
struct mt76_wcid *wcid;
if (idx >= ARRAY_SIZE(dev->wcid))
return NULL;
wcid = rcu_dereference(dev->wcid[idx]);
- if (unicast || !wcid)
- return wcid;
+ if (!wcid)
+ return NULL;
- sta = container_of(wcid, struct mt76x2_sta, wcid);
- return &sta->vif->group_wcid;
+ return container_of(wcid, struct mt76x2_sta, wcid);
+}
+
+static struct mt76_wcid *
+mt76x2_rx_get_sta_wcid(struct mt76x2_dev *dev, struct mt76x2_sta *sta, bool unicast)
+{
+ if (!sta)
+ return NULL;
+
+ if (unicast)
+ return &sta->wcid;
+ else
+ return &sta->vif->group_wcid;
}
int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
@@ -291,6 +301,7 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
{
struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
struct mt76x2_rxwi *rxwi = rxi;
+ struct mt76x2_sta *sta;
u32 rxinfo = le32_to_cpu(rxwi->rxinfo);
u32 ctl = le32_to_cpu(rxwi->ctl);
u16 rate = le16_to_cpu(rxwi->rate);
@@ -315,7 +326,8 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
}
wcid = FIELD_GET(MT_RXWI_CTL_WCID, ctl);
- status->wcid = mt76x2_rx_get_sta_wcid(dev, wcid, unicast);
+ sta = mt76x2_rx_get_sta(dev, wcid);
+ status->wcid = mt76x2_rx_get_sta_wcid(dev, sta, unicast);
len = FIELD_GET(MT_RXWI_CTL_MPDU_LEN, ctl);
pn_len = FIELD_GET(MT_RXINFO_PN_LEN, rxinfo);
@@ -361,6 +373,11 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
status->tid = FIELD_GET(MT_RXWI_TID, tid_sn);
status->seqno = FIELD_GET(MT_RXWI_SN, tid_sn);
+ if (sta) {
+ ewma_signal_add(&sta->rssi, status->signal);
+ sta->inactive_count = 0;
+ }
+
return mt76x2_mac_process_rate(status, rate);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
index e4e41faf6739..3c0ebe6d231c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
@@ -294,6 +294,8 @@ mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (vif->type == NL80211_IFTYPE_AP)
set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags);
+ ewma_signal_init(&msta->rssi);
+
rcu_assign_pointer(dev->wcid[idx], &msta->wcid);
out:
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
index 94943aeb249d..14aedc3ef731 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
@@ -499,22 +499,62 @@ mt76x2_phy_adjust_vga_gain(struct mt76x2_dev *dev)
mt76x2_phy_set_gain_val(dev);
}
+static int
+mt76x2_phy_get_min_avg_rssi(struct mt76x2_dev *dev)
+{
+ struct mt76x2_sta *sta;
+ struct mt76_wcid *wcid;
+ int i, j, min_rssi = 0;
+ s8 cur_rssi;
+
+ local_bh_disable();
+ rcu_read_lock();
+
+ for (i = 0; i < ARRAY_SIZE(dev->wcid_mask); i++) {
+ unsigned long mask = dev->wcid_mask[i];
+
+ if (!mask)
+ continue;
+
+ for (j = i * BITS_PER_LONG; mask; j++, mask >>= 1) {
+ if (!(mask & 1))
+ continue;
+
+ wcid = rcu_dereference(dev->wcid[j]);
+ if (!wcid)
+ continue;
+
+ sta = container_of(wcid, struct mt76x2_sta, wcid);
+ spin_lock(&dev->mt76.rx_lock);
+ if (sta->inactive_count++ < 5)
+ cur_rssi = ewma_signal_read(&sta->rssi);
+ else
+ cur_rssi = 0;
+ spin_unlock(&dev->mt76.rx_lock);
+
+ if (cur_rssi < min_rssi)
+ min_rssi = cur_rssi;
+ }
+ }
+
+ rcu_read_unlock();
+ local_bh_enable();
+
+ if (!min_rssi)
+ return -75;
+
+ return min_rssi;
+}
+
static void
mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
{
- u32 val = mt76_rr(dev, MT_BBP(AGC, 20));
- int rssi0 = (s8) FIELD_GET(MT_BBP_AGC20_RSSI0, val);
- int rssi1 = (s8) FIELD_GET(MT_BBP_AGC20_RSSI1, val);
u8 *gain = dev->cal.agc_gain_init;
u8 gain_delta;
int low_gain;
+ u32 val;
- dev->cal.avg_rssi[0] = (dev->cal.avg_rssi[0] * 15) / 16 +
- (rssi0 << 8) / 16;
- dev->cal.avg_rssi[1] = (dev->cal.avg_rssi[1] * 15) / 16 +
- (rssi1 << 8) / 16;
- dev->cal.avg_rssi_all = (dev->cal.avg_rssi[0] +
- dev->cal.avg_rssi[1]) / 512;
+ dev->cal.avg_rssi_all = mt76x2_phy_get_min_avg_rssi(dev);
low_gain = (dev->cal.avg_rssi_all > mt76x2_get_rssi_gain_thresh(dev)) +
(dev->cal.avg_rssi_all > mt76x2_get_low_rssi_gain_thresh(dev));
--
2.17.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 9/9] mt76: improve gain adjustment in noisy environments
2018-06-21 9:17 [PATCH 1/9] mt76: fix beacon timer drift Felix Fietkau
` (6 preceding siblings ...)
2018-06-21 9:18 ` [PATCH 8/9] mt76: track ewma rssi for gain adjustment per station Felix Fietkau
@ 2018-06-21 9:18 ` Felix Fietkau
2018-06-27 16:16 ` [1/9] mt76: fix beacon timer drift Kalle Valo
8 siblings, 0 replies; 10+ messages in thread
From: Felix Fietkau @ 2018-06-21 9:18 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo
When switching between low gain (high RSSI) and high gain settings, it
can take a few seconds to adjust to the current environment.
This can lead to short periods of time with extreme packet loss.
When switching from low_gain=1 to low_gain=2, start with the same gain
adjustment value instead of the lowest to avoid spikes of huge numbers
of false CCA events
Also avoid resetting adjustment values on switching between low_gain
values 0 and 1, since it affects only the upper limit of vga adjustment
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
.../net/wireless/mediatek/mt76/mt76x2_phy.c | 26 ++++++++++++-------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
index 14aedc3ef731..20ffa6a40d39 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
@@ -491,7 +491,8 @@ mt76x2_phy_adjust_vga_gain(struct mt76x2_dev *dev)
dev->cal.false_cca = false_cca;
if (false_cca > 800 && dev->cal.agc_gain_adjust < limit)
dev->cal.agc_gain_adjust += 2;
- else if (false_cca < 10 && dev->cal.agc_gain_adjust > 0)
+ else if ((false_cca < 10 && dev->cal.agc_gain_adjust > 0) ||
+ (dev->cal.agc_gain_adjust >= limit && false_cca < 500))
dev->cal.agc_gain_adjust -= 2;
else
return;
@@ -550,7 +551,8 @@ static void
mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
{
u8 *gain = dev->cal.agc_gain_init;
- u8 gain_delta;
+ u8 low_gain_delta, gain_delta;
+ bool gain_change;
int low_gain;
u32 val;
@@ -559,13 +561,14 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
low_gain = (dev->cal.avg_rssi_all > mt76x2_get_rssi_gain_thresh(dev)) +
(dev->cal.avg_rssi_all > mt76x2_get_low_rssi_gain_thresh(dev));
- if (dev->cal.low_gain == low_gain) {
+ gain_change = (dev->cal.low_gain & 2) ^ (low_gain & 2);
+ dev->cal.low_gain = low_gain;
+
+ if (!gain_change) {
mt76x2_phy_adjust_vga_gain(dev);
return;
}
- dev->cal.low_gain = low_gain;
-
if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80) {
mt76_wr(dev, MT_BBP(RXO, 14), 0x00560211);
val = mt76_rr(dev, MT_BBP(AGC, 26)) & ~0xf;
@@ -578,14 +581,17 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
mt76_wr(dev, MT_BBP(RXO, 14), 0x00560423);
}
+ if (mt76x2_has_ext_lna(dev))
+ low_gain_delta = 10;
+ else
+ low_gain_delta = 14;
+
if (low_gain == 2) {
mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a990);
mt76_wr(dev, MT_BBP(AGC, 35), 0x08080808);
mt76_wr(dev, MT_BBP(AGC, 37), 0x08080808);
- if (mt76x2_has_ext_lna(dev))
- gain_delta = 10;
- else
- gain_delta = 14;
+ gain_delta = low_gain_delta;
+ dev->cal.agc_gain_adjust = 0;
} else {
mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a991);
if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80)
@@ -594,11 +600,11 @@ mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
mt76_wr(dev, MT_BBP(AGC, 35), 0x11111116);
mt76_wr(dev, MT_BBP(AGC, 37), 0x2121262C);
gain_delta = 0;
+ dev->cal.agc_gain_adjust = low_gain_delta;
}
dev->cal.agc_gain_cur[0] = gain[0] - gain_delta;
dev->cal.agc_gain_cur[1] = gain[1] - gain_delta;
- dev->cal.agc_gain_adjust = 0;
mt76x2_phy_set_gain_val(dev);
/* clear false CCA counters */
--
2.17.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [1/9] mt76: fix beacon timer drift
2018-06-21 9:17 [PATCH 1/9] mt76: fix beacon timer drift Felix Fietkau
` (7 preceding siblings ...)
2018-06-21 9:18 ` [PATCH 9/9] mt76: improve gain adjustment in noisy environments Felix Fietkau
@ 2018-06-27 16:16 ` Kalle Valo
8 siblings, 0 replies; 10+ messages in thread
From: Kalle Valo @ 2018-06-27 16:16 UTC (permalink / raw)
To: Felix Fietkau; +Cc: linux-wireless
Felix Fietkau <nbd@nbd.name> wrote:
> The beacon timer drifts by 1 microsecond every TBTT. After 20 minutes
> with a beacon interval of 100, the drift will be almost 12 ms, enough to
> cause weird issues for devices in powersave mode.
>
> Since the beacon timer is configured in units of 1/16 TU (64 us), we
> need to adjust it once every 64 beacons and only for one beacon.
>
> Signed-off-by: Felix Fietkau <nbd@nbd.name>
9 patches applied to wireless-drivers-next.git, thanks.
aea38272920c mt76: fix beacon timer drift
9afef0fddaa1 mt76: fix threshold for gain adjustment
6cdb9614a818 mt76: fix swapped values for RXO-18 in gain control
929211687197 mt76: adjust AGC control register 26 based on gain for VHT80
fa967b586031 mt76: clear false CCA counters after changing gain settings
8e31f0d35a88 mt76: fix variable gain adjustment range
108ec4dafd61 mt76: add a debugfs file to dump agc calibration information
32e49efe0f15 mt76: track ewma rssi for gain adjustment per station
c3ae2103e069 mt76: improve gain adjustment in noisy environments
--
https://patchwork.kernel.org/patch/10479537/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply [flat|nested] 10+ messages in thread