Commit a0ac8061 authored by Felix Fietkau's avatar Felix Fietkau

mt76: mt76x02: reduce false positives in ED/CCA tx blocking

Full tx blocking (as opposed to CCA blocking) should only happen if there
is a continuous non-802.11 signal above the energy detect threshold.
Unfortunately the ED/CCA counter can't detect that, as it also counts 802.11
signals as busy.

Similar to the vendor code, implement a learning mode that waits until the AGC
gain has already been adjusted to the lowest value (due to false CCA events),
and the number of false CCA events still remains high, and the blocking
threshold is exceeded for more than 5 seconds.
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 3fd0824a
......@@ -51,6 +51,7 @@ struct mt76x02_calibration {
u16 false_cca;
s8 avg_rssi_all;
s8 agc_gain_adjust;
s8 agc_lowest_gain;
s8 low_gain;
s8 temp_vco;
......@@ -114,8 +115,10 @@ struct mt76x02_dev {
struct mt76x02_dfs_pattern_detector dfs_pd;
/* edcca monitor */
unsigned long ed_trigger_timeout;
bool ed_tx_blocked;
bool ed_monitor;
u8 ed_monitor_learning;
u8 ed_trigger;
u8 ed_silent;
ktime_t ed_time;
......
......@@ -960,6 +960,7 @@ void mt76x02_edcca_init(struct mt76x02_dev *dev, bool enable)
}
}
mt76x02_edcca_tx_enable(dev, true);
dev->ed_monitor_learning = true;
/* clear previous CCA timer value */
mt76_rr(dev, MT_ED_CCA_TIMER);
......@@ -969,6 +970,10 @@ EXPORT_SYMBOL_GPL(mt76x02_edcca_init);
#define MT_EDCCA_TH 92
#define MT_EDCCA_BLOCK_TH 2
#define MT_EDCCA_LEARN_TH 50
#define MT_EDCCA_LEARN_CCA 180
#define MT_EDCCA_LEARN_TIMEOUT (20 * HZ)
static void mt76x02_edcca_check(struct mt76x02_dev *dev)
{
ktime_t cur_time;
......@@ -991,11 +996,23 @@ static void mt76x02_edcca_check(struct mt76x02_dev *dev)
dev->ed_trigger = 0;
}
if (dev->ed_trigger > MT_EDCCA_BLOCK_TH &&
!dev->ed_tx_blocked)
if (dev->cal.agc_lowest_gain &&
dev->cal.false_cca > MT_EDCCA_LEARN_CCA &&
dev->ed_trigger > MT_EDCCA_LEARN_TH) {
dev->ed_monitor_learning = false;
dev->ed_trigger_timeout = jiffies + 20 * HZ;
} else if (!dev->ed_monitor_learning &&
time_is_after_jiffies(dev->ed_trigger_timeout)) {
dev->ed_monitor_learning = true;
mt76x02_edcca_tx_enable(dev, true);
}
if (dev->ed_monitor_learning)
return;
if (dev->ed_trigger > MT_EDCCA_BLOCK_TH && !dev->ed_tx_blocked)
mt76x02_edcca_tx_enable(dev, false);
else if (dev->ed_silent > MT_EDCCA_BLOCK_TH &&
dev->ed_tx_blocked)
else if (dev->ed_silent > MT_EDCCA_BLOCK_TH && dev->ed_tx_blocked)
mt76x02_edcca_tx_enable(dev, true);
}
......
......@@ -194,6 +194,8 @@ bool mt76x02_phy_adjust_vga_gain(struct mt76x02_dev *dev)
ret = true;
}
dev->cal.agc_lowest_gain = dev->cal.agc_gain_adjust >= limit;
return ret;
}
EXPORT_SYMBOL_GPL(mt76x02_phy_adjust_vga_gain);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment