mt7603: add dynamic sensitivity tuning based on false CCA events

This reduces sensitivity in cases where it could help throughput/stability.

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2018-12-05 18:26:20 +01:00
parent fea7ad804e
commit 9d009be68d
6 changed files with 161 additions and 0 deletions
+14
View File
@@ -43,6 +43,18 @@ mt7603_reset_read(struct seq_file *s, void *data)
return 0;
}
static int
mt7603_radio_read(struct seq_file *s, void *data)
{
struct mt7603_dev *dev = dev_get_drvdata(s->private);
seq_printf(s, "Sensitivity: %d\n", dev->sensitivity);
seq_printf(s, "False CCA: ofdm=%d cck=%d\n",
dev->false_cca_ofdm, dev->false_cca_cck);
return 0;
}
void mt7603_init_debugfs(struct mt7603_dev *dev)
{
struct dentry *dir;
@@ -54,4 +66,6 @@ void mt7603_init_debugfs(struct mt7603_dev *dev)
debugfs_create_u32("reset_test", 0600, dir, &dev->reset_test);
debugfs_create_devm_seqfile(dev->mt76.dev, "reset", dir,
mt7603_reset_read);
debugfs_create_devm_seqfile(dev->mt76.dev, "radio", dir,
mt7603_radio_read);
}
+3
View File
@@ -151,6 +151,9 @@ mt7603_phy_init(struct mt7603_dev *dev)
mt76_rmw_field(dev, MT_TMAC_TCR, MT_TMAC_TCR_TX_STREAMS,
tx_chains);
dev->agc0 = mt76_rr(dev, MT_AGC(0));
dev->agc3 = mt76_rr(dev, MT_AGC(3));
}
static void
+117
View File
@@ -1570,6 +1570,115 @@ mt7603_edcca_check(struct mt7603_dev *dev)
dev->ed_trigger = -MT7603_EDCCA_BLOCK_TH;
}
void mt7603_cca_stats_reset(struct mt7603_dev *dev)
{
mt76_set(dev, MT_PHYCTRL(2), MT_PHYCTRL_2_STATUS_RESET);
mt76_clear(dev, MT_PHYCTRL(2), MT_PHYCTRL_2_STATUS_RESET);
mt76_set(dev, MT_PHYCTRL(2), MT_PHYCTRL_2_STATUS_EN);
}
static void
mt7603_adjust_sensitivity(struct mt7603_dev *dev)
{
u32 agc0 = dev->agc0, agc3 = dev->agc3;
u32 adj;
if (!dev->sensitivity || dev->sensitivity < -100) {
dev->sensitivity = 0;
} else if (dev->sensitivity <= -84) {
adj = 7 + (dev->sensitivity + 92) / 2;
agc0 = 0x56f0076f;
agc0 |= adj << 12;
agc0 |= adj << 16;
agc3 = 0x81d0d5e3;
} else if (dev->sensitivity <= -72) {
adj = 7 + (dev->sensitivity + 80) / 2;
agc0 = 0x6af0006f;
agc0 |= adj << 8;
agc0 |= adj << 12;
agc0 |= adj << 16;
agc3 = 0x8181d5e3;
} else {
if (dev->sensitivity > -54)
dev->sensitivity = -54;
adj = 7 + (dev->sensitivity + 80) / 2;
agc0 = 0x7ff0000f;
agc0 |= adj << 4;
agc0 |= adj << 8;
agc0 |= adj << 12;
agc0 |= adj << 16;
agc3 = 0x818181e3;
}
mt76_wr(dev, MT_AGC(0), agc0);
mt76_wr(dev, MT_AGC1(0), agc0);
mt76_wr(dev, MT_AGC(3), agc3);
mt76_wr(dev, MT_AGC1(3), agc3);
}
static void
mt7603_false_cca_check(struct mt7603_dev *dev)
{
int pd_cck, pd_ofdm, mdrdy_cck, mdrdy_ofdm;
int false_cca;
int min_signal;
u32 val;
val = mt76_rr(dev, MT_PHYCTRL_STAT_PD);
pd_cck = FIELD_GET(MT_PHYCTRL_STAT_PD_CCK, val);
pd_ofdm = FIELD_GET(MT_PHYCTRL_STAT_PD_OFDM, val);
val = mt76_rr(dev, MT_PHYCTRL_STAT_MDRDY);
mdrdy_cck = FIELD_GET(MT_PHYCTRL_STAT_MDRDY_CCK, val);
mdrdy_ofdm = FIELD_GET(MT_PHYCTRL_STAT_MDRDY_OFDM, val);
dev->false_cca_ofdm = pd_ofdm - mdrdy_ofdm;
dev->false_cca_cck = pd_cck - mdrdy_cck;
mt7603_cca_stats_reset(dev);
min_signal = mt76_get_min_avg_rssi(&dev->mt76);
if (!min_signal) {
dev->sensitivity = 0;
dev->last_cca_adj = jiffies;
goto out;
}
min_signal -= 15;
false_cca = dev->false_cca_ofdm + dev->false_cca_cck;
if (false_cca > 600) {
if (!dev->sensitivity)
dev->sensitivity = -92;
else
dev->sensitivity += 2;
dev->last_cca_adj = jiffies;
} else if (false_cca < 100 ||
time_after(jiffies, dev->last_cca_adj + 10 * HZ)) {
dev->last_cca_adj = jiffies;
if (!dev->sensitivity)
goto out;
dev->sensitivity -= 2;
}
if (dev->sensitivity && dev->sensitivity > min_signal) {
dev->sensitivity = min_signal;
dev->last_cca_adj = jiffies;
}
out:
mt7603_adjust_sensitivity(dev);
}
void mt7603_mac_work(struct work_struct *work)
{
struct mt7603_dev *dev = container_of(work, struct mt7603_dev,
@@ -1580,9 +1689,13 @@ void mt7603_mac_work(struct work_struct *work)
mutex_lock(&dev->mt76.mutex);
dev->mac_work_count++;
mt7603_update_channel(&dev->mt76);
mt7603_edcca_check(dev);
if (dev->mac_work_count == 10)
mt7603_false_cca_check(dev);
if (mt7603_watchdog_check(dev, &dev->rx_pse_check,
RESET_CAUSE_RX_PSE_BUSY,
mt7603_rx_pse_busy) ||
@@ -1611,8 +1724,12 @@ void mt7603_mac_work(struct work_struct *work)
dev->rx_dma_idx = ~0;
memset(dev->tx_dma_idx, 0xff, sizeof(dev->tx_dma_idx));
reset = true;
dev->mac_work_count = 0;
}
if (dev->mac_work_count >= 10)
dev->mac_work_count = 0;
mutex_unlock(&dev->mt76.mutex);
if (reset)
+1
View File
@@ -198,6 +198,7 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def)
mt76_set(dev, MT_MIB_CTL,
MT_MIB_CTL_CCA_NAV_TX | MT_MIB_CTL_PSCCA_TIME);
mt76_rr(dev, MT_MIB_STAT_PSCCA);
mt7603_cca_stats_reset(dev);
dev->survey_time = ktime_get_boottime();
+9
View File
@@ -111,6 +111,10 @@ struct mt7603_dev {
struct mt7603_sta global_sta;
u32 agc0, agc3;
u32 false_cca_ofdm, false_cca_cck;
unsigned long last_cca_adj;
u8 rssi_offset[3];
u8 slottime;
@@ -124,6 +128,8 @@ struct mt7603_dev {
spinlock_t ps_lock;
u8 mac_work_count;
u8 mcu_running;
u8 ed_monitor;
@@ -131,6 +137,8 @@ struct mt7603_dev {
u8 ed_strict_mode;
u8 ed_strong_signal;
s8 sensitivity;
u8 beacon_mask;
u8 beacon_check;
@@ -250,5 +258,6 @@ void mt7603_pre_tbtt_tasklet(unsigned long arg);
void mt7603_update_channel(struct mt76_dev *mdev);
void mt7603_edcca_set_strict(struct mt7603_dev *dev, bool val);
void mt7603_cca_stats_reset(struct mt7603_dev *dev);
#endif
+17
View File
@@ -150,6 +150,9 @@
#define MT_AGC_BASE MT_WF_PHY(0x500)
#define MT_AGC(n) (MT_AGC_BASE + ((n) * 4))
#define MT_AGC1_BASE MT_WF_PHY(0x1500)
#define MT_AGC1(n) (MT_AGC1_BASE + ((n) * 4))
#define MT_AGC_41_RSSI_0 GENMASK(23, 16)
#define MT_AGC_41_RSSI_1 GENMASK(7, 0)
@@ -168,6 +171,20 @@
((phy) * MT_WF_PHY_OFFSET) + \
((n) * 4))
#define MT_PHYCTRL_BASE MT_WF_PHY(0x4100)
#define MT_PHYCTRL(n) (MT_PHYCTRL_BASE + ((n) * 4))
#define MT_PHYCTRL_2_STATUS_RESET BIT(6)
#define MT_PHYCTRL_2_STATUS_EN BIT(7)
#define MT_PHYCTRL_STAT_PD MT_PHYCTRL(3)
#define MT_PHYCTRL_STAT_PD_OFDM GENMASK(31, 16)
#define MT_PHYCTRL_STAT_PD_CCK GENMASK(15, 0)
#define MT_PHYCTRL_STAT_MDRDY MT_PHYCTRL(8)
#define MT_PHYCTRL_STAT_MDRDY_OFDM GENMASK(31, 16)
#define MT_PHYCTRL_STAT_MDRDY_CCK GENMASK(15, 0)
#define MT_WF_AGG_BASE 0x21200
#define MT_WF_AGG(ofs) (MT_WF_AGG_BASE + (ofs))