Commit d446a20f authored by Felix Fietkau's avatar Felix Fietkau

mt76: mt7615: add multiple wiphy support for smart carrier sense

Use per-phy radio stats and tuning registers
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent fdd2e570
...@@ -74,15 +74,28 @@ static const struct file_operations fops_ampdu_stat = { ...@@ -74,15 +74,28 @@ static const struct file_operations fops_ampdu_stat = {
.release = single_release, .release = single_release,
}; };
static void
mt7615_radio_read_phy(struct mt7615_phy *phy, struct seq_file *s)
{
struct mt7615_dev *dev = dev_get_drvdata(s->private);
bool ext_phy = phy != &dev->phy;
if (!phy)
return;
seq_printf(s, "Radio %d sensitivity: ofdm=%d cck=%d\n", ext_phy,
phy->ofdm_sensitivity, phy->cck_sensitivity);
seq_printf(s, "Radio %d false CCA: ofdm=%d cck=%d\n", ext_phy,
phy->false_cca_ofdm, phy->false_cca_cck);
}
static int static int
mt7615_radio_read(struct seq_file *s, void *data) mt7615_radio_read(struct seq_file *s, void *data)
{ {
struct mt7615_dev *dev = dev_get_drvdata(s->private); struct mt7615_dev *dev = dev_get_drvdata(s->private);
seq_printf(s, "Sensitivity: ofdm=%d cck=%d\n", mt7615_radio_read_phy(&dev->phy, s);
dev->ofdm_sensitivity, dev->cck_sensitivity); mt7615_radio_read_phy(mt7615_ext_phy(dev), s);
seq_printf(s, "False CCA: ofdm=%d cck=%d\n",
dev->false_cca_ofdm, dev->false_cca_cck);
return 0; return 0;
} }
......
...@@ -1234,38 +1234,46 @@ void mt7615_mac_tx_free(struct mt7615_dev *dev, struct sk_buff *skb) ...@@ -1234,38 +1234,46 @@ void mt7615_mac_tx_free(struct mt7615_dev *dev, struct sk_buff *skb)
} }
static void static void
mt7615_mac_set_default_sensitivity(struct mt7615_dev *dev) mt7615_mac_set_default_sensitivity(struct mt7615_phy *phy)
{ {
struct mt7615_dev *dev = phy->dev;
bool ext_phy = phy != &dev->phy;
if (!ext_phy) {
mt76_rmw(dev, MT_WF_PHY_B0_MIN_PRI_PWR, mt76_rmw(dev, MT_WF_PHY_B0_MIN_PRI_PWR,
MT_WF_PHY_B0_PD_OFDM_MASK, MT_WF_PHY_B0_PD_OFDM_MASK,
MT_WF_PHY_B0_PD_OFDM(0x13c)); MT_WF_PHY_B0_PD_OFDM(0x13c));
mt76_rmw(dev, MT_WF_PHY_B1_MIN_PRI_PWR,
MT_WF_PHY_B1_PD_OFDM_MASK,
MT_WF_PHY_B1_PD_OFDM(0x13c));
mt76_rmw(dev, MT_WF_PHY_B0_RXTD_CCK_PD, mt76_rmw(dev, MT_WF_PHY_B0_RXTD_CCK_PD,
MT_WF_PHY_B0_PD_CCK_MASK, MT_WF_PHY_B0_PD_CCK_MASK,
MT_WF_PHY_B0_PD_CCK(0x92)); MT_WF_PHY_B0_PD_CCK(0x92));
} else {
mt76_rmw(dev, MT_WF_PHY_B1_MIN_PRI_PWR,
MT_WF_PHY_B1_PD_OFDM_MASK,
MT_WF_PHY_B1_PD_OFDM(0x13c));
mt76_rmw(dev, MT_WF_PHY_B1_RXTD_CCK_PD, mt76_rmw(dev, MT_WF_PHY_B1_RXTD_CCK_PD,
MT_WF_PHY_B1_PD_CCK_MASK, MT_WF_PHY_B1_PD_CCK_MASK,
MT_WF_PHY_B1_PD_CCK(0x92)); MT_WF_PHY_B1_PD_CCK(0x92));
}
dev->ofdm_sensitivity = -98; phy->ofdm_sensitivity = -98;
dev->cck_sensitivity = -110; phy->cck_sensitivity = -110;
dev->last_cca_adj = jiffies; phy->last_cca_adj = jiffies;
} }
void mt7615_mac_set_scs(struct mt7615_dev *dev, bool enable) void mt7615_mac_set_scs(struct mt7615_dev *dev, bool enable)
{ {
struct mt7615_phy *ext_phy;
mutex_lock(&dev->mt76.mutex); mutex_lock(&dev->mt76.mutex);
if (dev->scs_en == enable) if (dev->scs_en == enable)
goto out; goto out;
if (enable) { if (enable) {
/* DBDC not supported */
mt76_set(dev, MT_WF_PHY_B0_MIN_PRI_PWR, mt76_set(dev, MT_WF_PHY_B0_MIN_PRI_PWR,
MT_WF_PHY_B0_PD_BLK); MT_WF_PHY_B0_PD_BLK);
mt76_set(dev, MT_WF_PHY_B1_MIN_PRI_PWR,
MT_WF_PHY_B1_PD_BLK);
if (is_mt7622(&dev->mt76)) { if (is_mt7622(&dev->mt76)) {
mt76_set(dev, MT_MIB_M0_MISC_CR, 0x7 << 8); mt76_set(dev, MT_MIB_M0_MISC_CR, 0x7 << 8);
mt76_set(dev, MT_MIB_M0_MISC_CR, 0x7); mt76_set(dev, MT_MIB_M0_MISC_CR, 0x7);
...@@ -1277,33 +1285,43 @@ void mt7615_mac_set_scs(struct mt7615_dev *dev, bool enable) ...@@ -1277,33 +1285,43 @@ void mt7615_mac_set_scs(struct mt7615_dev *dev, bool enable)
MT_WF_PHY_B1_PD_BLK); MT_WF_PHY_B1_PD_BLK);
} }
mt7615_mac_set_default_sensitivity(dev); mt7615_mac_set_default_sensitivity(&dev->phy);
ext_phy = mt7615_ext_phy(dev);
if (ext_phy)
mt7615_mac_set_default_sensitivity(ext_phy);
dev->scs_en = enable; dev->scs_en = enable;
out: out:
mutex_unlock(&dev->mt76.mutex); mutex_unlock(&dev->mt76.mutex);
} }
void mt7615_mac_cca_stats_reset(struct mt7615_dev *dev) void mt7615_mac_cca_stats_reset(struct mt7615_phy *phy)
{ {
mt76_clear(dev, MT_WF_PHY_R0_B0_PHYMUX_5, GENMASK(22, 20)); struct mt7615_dev *dev = phy->dev;
mt76_set(dev, MT_WF_PHY_R0_B0_PHYMUX_5, BIT(22) | BIT(20)); bool ext_phy = phy != &dev->phy;
u32 reg = MT_WF_PHY_R0_PHYMUX_5(ext_phy);
mt76_clear(dev, reg, GENMASK(22, 20));
mt76_set(dev, reg, BIT(22) | BIT(20));
} }
static void static void
mt7615_mac_adjust_sensitivity(struct mt7615_dev *dev, mt7615_mac_adjust_sensitivity(struct mt7615_phy *phy,
u32 rts_err_rate, bool ofdm) u32 rts_err_rate, bool ofdm)
{ {
int false_cca = ofdm ? dev->false_cca_ofdm : dev->false_cca_cck; struct mt7615_dev *dev = phy->dev;
int false_cca = ofdm ? phy->false_cca_ofdm : phy->false_cca_cck;
bool ext_phy = phy != &dev->phy;
u16 def_th = ofdm ? -98 : -110; u16 def_th = ofdm ? -98 : -110;
bool update = false; bool update = false;
s8 *sensitivity; s8 *sensitivity;
int signal; int signal;
sensitivity = ofdm ? &dev->ofdm_sensitivity : &dev->cck_sensitivity; sensitivity = ofdm ? &phy->ofdm_sensitivity : &phy->cck_sensitivity;
signal = mt76_get_min_avg_rssi(&dev->mt76, false); signal = mt76_get_min_avg_rssi(&dev->mt76, ext_phy);
if (!signal) { if (!signal) {
mt7615_mac_set_default_sensitivity(dev); mt7615_mac_set_default_sensitivity(phy);
return; return;
} }
...@@ -1338,29 +1356,37 @@ mt7615_mac_adjust_sensitivity(struct mt7615_dev *dev, ...@@ -1338,29 +1356,37 @@ mt7615_mac_adjust_sensitivity(struct mt7615_dev *dev,
u16 val; u16 val;
if (ofdm) { if (ofdm) {
/* DBDC not supported */
val = *sensitivity * 2 + 512; val = *sensitivity * 2 + 512;
if (!ext_phy)
mt76_rmw(dev, MT_WF_PHY_B0_MIN_PRI_PWR, mt76_rmw(dev, MT_WF_PHY_B0_MIN_PRI_PWR,
MT_WF_PHY_B0_PD_OFDM_MASK, MT_WF_PHY_B0_PD_OFDM_MASK,
MT_WF_PHY_B0_PD_OFDM(val)); MT_WF_PHY_B0_PD_OFDM(val));
else
mt76_rmw(dev, MT_WF_PHY_B1_MIN_PRI_PWR,
MT_WF_PHY_B1_PD_OFDM_MASK,
MT_WF_PHY_B1_PD_OFDM(val));
} else { } else {
val = *sensitivity + 256; val = *sensitivity + 256;
if (!ext_phy)
mt76_rmw(dev, MT_WF_PHY_B0_RXTD_CCK_PD, mt76_rmw(dev, MT_WF_PHY_B0_RXTD_CCK_PD,
MT_WF_PHY_B0_PD_CCK_MASK, MT_WF_PHY_B0_PD_CCK_MASK,
MT_WF_PHY_B0_PD_CCK(val)); MT_WF_PHY_B0_PD_CCK(val));
else
mt76_rmw(dev, MT_WF_PHY_B1_RXTD_CCK_PD, mt76_rmw(dev, MT_WF_PHY_B1_RXTD_CCK_PD,
MT_WF_PHY_B1_PD_CCK_MASK, MT_WF_PHY_B1_PD_CCK_MASK,
MT_WF_PHY_B1_PD_CCK(val)); MT_WF_PHY_B1_PD_CCK(val));
} }
dev->last_cca_adj = jiffies; phy->last_cca_adj = jiffies;
} }
} }
static void static void
mt7615_mac_scs_check(struct mt7615_dev *dev) mt7615_mac_scs_check(struct mt7615_phy *phy)
{ {
struct mt7615_dev *dev = phy->dev;
u32 val, rts_cnt = 0, rts_retries_cnt = 0, rts_err_rate = 0; u32 val, rts_cnt = 0, rts_retries_cnt = 0, rts_err_rate = 0;
u32 mdrdy_cck, mdrdy_ofdm, pd_cck, pd_ofdm; u32 mdrdy_cck, mdrdy_ofdm, pd_cck, pd_ofdm;
bool ext_phy = phy != &dev->phy;
int i; int i;
if (!dev->scs_en) if (!dev->scs_en)
...@@ -1369,7 +1395,7 @@ mt7615_mac_scs_check(struct mt7615_dev *dev) ...@@ -1369,7 +1395,7 @@ mt7615_mac_scs_check(struct mt7615_dev *dev)
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
u32 data; u32 data;
val = mt76_rr(dev, MT_MIB_MB_SDR0(i)); val = mt76_rr(dev, MT_MIB_MB_SDR(ext_phy, i));
data = FIELD_GET(MT_MIB_RTS_RETRIES_COUNT_MASK, val); data = FIELD_GET(MT_MIB_RTS_RETRIES_COUNT_MASK, val);
if (data > rts_retries_cnt) { if (data > rts_retries_cnt) {
rts_cnt = FIELD_GET(MT_MIB_RTS_COUNT_MASK, val); rts_cnt = FIELD_GET(MT_MIB_RTS_COUNT_MASK, val);
...@@ -1377,29 +1403,29 @@ mt7615_mac_scs_check(struct mt7615_dev *dev) ...@@ -1377,29 +1403,29 @@ mt7615_mac_scs_check(struct mt7615_dev *dev)
} }
} }
val = mt76_rr(dev, MT_WF_PHY_R0_B0_PHYCTRL_STS0); val = mt76_rr(dev, MT_WF_PHY_R0_PHYCTRL_STS0(ext_phy));
pd_cck = FIELD_GET(MT_WF_PHYCTRL_STAT_PD_CCK, val); pd_cck = FIELD_GET(MT_WF_PHYCTRL_STAT_PD_CCK, val);
pd_ofdm = FIELD_GET(MT_WF_PHYCTRL_STAT_PD_OFDM, val); pd_ofdm = FIELD_GET(MT_WF_PHYCTRL_STAT_PD_OFDM, val);
val = mt76_rr(dev, MT_WF_PHY_R0_B0_PHYCTRL_STS5); val = mt76_rr(dev, MT_WF_PHY_R0_PHYCTRL_STS5(ext_phy));
mdrdy_cck = FIELD_GET(MT_WF_PHYCTRL_STAT_MDRDY_CCK, val); mdrdy_cck = FIELD_GET(MT_WF_PHYCTRL_STAT_MDRDY_CCK, val);
mdrdy_ofdm = FIELD_GET(MT_WF_PHYCTRL_STAT_MDRDY_OFDM, val); mdrdy_ofdm = FIELD_GET(MT_WF_PHYCTRL_STAT_MDRDY_OFDM, val);
dev->false_cca_ofdm = pd_ofdm - mdrdy_ofdm; phy->false_cca_ofdm = pd_ofdm - mdrdy_ofdm;
dev->false_cca_cck = pd_cck - mdrdy_cck; phy->false_cca_cck = pd_cck - mdrdy_cck;
mt7615_mac_cca_stats_reset(dev); mt7615_mac_cca_stats_reset(phy);
if (rts_cnt + rts_retries_cnt) if (rts_cnt + rts_retries_cnt)
rts_err_rate = MT_FRAC(rts_retries_cnt, rts_err_rate = MT_FRAC(rts_retries_cnt,
rts_cnt + rts_retries_cnt); rts_cnt + rts_retries_cnt);
/* cck */ /* cck */
mt7615_mac_adjust_sensitivity(dev, rts_err_rate, false); mt7615_mac_adjust_sensitivity(phy, rts_err_rate, false);
/* ofdm */ /* ofdm */
mt7615_mac_adjust_sensitivity(dev, rts_err_rate, true); mt7615_mac_adjust_sensitivity(phy, rts_err_rate, true);
if (time_after(jiffies, dev->last_cca_adj + 10 * HZ)) if (time_after(jiffies, phy->last_cca_adj + 10 * HZ))
mt7615_mac_set_default_sensitivity(dev); mt7615_mac_set_default_sensitivity(phy);
} }
static void static void
...@@ -1440,6 +1466,7 @@ void mt7615_update_channel(struct mt76_dev *mdev) ...@@ -1440,6 +1466,7 @@ void mt7615_update_channel(struct mt76_dev *mdev)
void mt7615_mac_work(struct work_struct *work) void mt7615_mac_work(struct work_struct *work)
{ {
struct mt7615_dev *dev; struct mt7615_dev *dev;
struct mt7615_phy *ext_phy;
int i, idx; int i, idx;
dev = (struct mt7615_dev *)container_of(work, struct mt76_dev, dev = (struct mt7615_dev *)container_of(work, struct mt76_dev,
...@@ -1448,7 +1475,12 @@ void mt7615_mac_work(struct work_struct *work) ...@@ -1448,7 +1475,12 @@ void mt7615_mac_work(struct work_struct *work)
mutex_lock(&dev->mt76.mutex); mutex_lock(&dev->mt76.mutex);
mt76_update_survey(&dev->mt76); mt76_update_survey(&dev->mt76);
if (++dev->mac_work_count == 5) { if (++dev->mac_work_count == 5) {
mt7615_mac_scs_check(dev); ext_phy = mt7615_ext_phy(dev);
mt7615_mac_scs_check(&dev->phy);
if (ext_phy)
mt7615_mac_scs_check(ext_phy);
dev->mac_work_count = 0; dev->mac_work_count = 0;
} }
......
...@@ -194,7 +194,7 @@ static int mt7615_set_channel(struct mt7615_phy *phy) ...@@ -194,7 +194,7 @@ static int mt7615_set_channel(struct mt7615_phy *phy)
goto out; goto out;
ret = mt7615_dfs_init_radar_detector(dev); ret = mt7615_dfs_init_radar_detector(dev);
mt7615_mac_cca_stats_reset(dev); mt7615_mac_cca_stats_reset(phy);
mt7615_mac_reset_counters(dev); mt7615_mac_reset_counters(dev);
......
...@@ -84,6 +84,11 @@ struct mt7615_phy { ...@@ -84,6 +84,11 @@ struct mt7615_phy {
struct mt7615_dev *dev; struct mt7615_dev *dev;
u32 rxfilter; u32 rxfilter;
unsigned long last_cca_adj;
int false_cca_ofdm, false_cca_cck;
s8 ofdm_sensitivity;
s8 cck_sensitivity;
}; };
struct mt7615_dev { struct mt7615_dev {
...@@ -112,11 +117,7 @@ struct mt7615_dev { ...@@ -112,11 +117,7 @@ struct mt7615_dev {
u32 hw_pattern; u32 hw_pattern;
int dfs_state; int dfs_state;
int false_cca_ofdm, false_cca_cck;
unsigned long last_cca_adj;
u8 mac_work_count; u8 mac_work_count;
s8 ofdm_sensitivity;
s8 cck_sensitivity;
bool scs_en; bool scs_en;
spinlock_t token_lock; spinlock_t token_lock;
...@@ -280,7 +281,7 @@ static inline void mt7615_irq_disable(struct mt7615_dev *dev, u32 mask) ...@@ -280,7 +281,7 @@ static inline void mt7615_irq_disable(struct mt7615_dev *dev, u32 mask)
void mt7615_update_channel(struct mt76_dev *mdev); void mt7615_update_channel(struct mt76_dev *mdev);
bool mt7615_mac_wtbl_update(struct mt7615_dev *dev, int idx, u32 mask); bool mt7615_mac_wtbl_update(struct mt7615_dev *dev, int idx, u32 mask);
void mt7615_mac_reset_counters(struct mt7615_dev *dev); void mt7615_mac_reset_counters(struct mt7615_dev *dev);
void mt7615_mac_cca_stats_reset(struct mt7615_dev *dev); void mt7615_mac_cca_stats_reset(struct mt7615_phy *phy);
void mt7615_mac_set_scs(struct mt7615_dev *dev, bool enable); void mt7615_mac_set_scs(struct mt7615_dev *dev, bool enable);
void mt7615_mac_sta_poll(struct mt7615_dev *dev); void mt7615_mac_sta_poll(struct mt7615_dev *dev);
int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi, int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
......
...@@ -84,13 +84,13 @@ ...@@ -84,13 +84,13 @@
#define MT_WF_PHY_WF2_RFCTRL0 MT_WF_PHY(0x1900) #define MT_WF_PHY_WF2_RFCTRL0 MT_WF_PHY(0x1900)
#define MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN BIT(9) #define MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN BIT(9)
#define MT_WF_PHY_R0_B0_PHYMUX_5 MT_WF_PHY(0x0614) #define MT_WF_PHY_R0_PHYMUX_5(_phy) MT_WF_PHY(0x0614 + ((_phy) << 9))
#define MT_WF_PHY_R0_B0_PHYCTRL_STS0 MT_WF_PHY(0x020c) #define MT_WF_PHY_R0_PHYCTRL_STS0(_phy) MT_WF_PHY(0x020c + ((_phy) << 9))
#define MT_WF_PHYCTRL_STAT_PD_OFDM GENMASK(31, 16) #define MT_WF_PHYCTRL_STAT_PD_OFDM GENMASK(31, 16)
#define MT_WF_PHYCTRL_STAT_PD_CCK GENMASK(15, 0) #define MT_WF_PHYCTRL_STAT_PD_CCK GENMASK(15, 0)
#define MT_WF_PHY_R0_B0_PHYCTRL_STS5 MT_WF_PHY(0x0220) #define MT_WF_PHY_R0_PHYCTRL_STS5(_phy) MT_WF_PHY(0x0220 + ((_phy) << 9))
#define MT_WF_PHYCTRL_STAT_MDRDY_OFDM GENMASK(31, 16) #define MT_WF_PHYCTRL_STAT_MDRDY_OFDM GENMASK(31, 16)
#define MT_WF_PHYCTRL_STAT_MDRDY_CCK GENMASK(15, 0) #define MT_WF_PHYCTRL_STAT_MDRDY_CCK GENMASK(15, 0)
...@@ -295,7 +295,8 @@ ...@@ -295,7 +295,8 @@
#define MT_WF_MIB(ofs) (MT_WF_MIB_BASE + (ofs)) #define MT_WF_MIB(ofs) (MT_WF_MIB_BASE + (ofs))
#define MT_MIB_M0_MISC_CR MT_WF_MIB(0x00c) #define MT_MIB_M0_MISC_CR MT_WF_MIB(0x00c)
#define MT_MIB_MB_SDR0(n) MT_WF_MIB(0x100 + ((n) << 4)) #define MT_MIB_MB_SDR(_band, n) MT_WF_MIB(0x100 + ((_band) << 9) + \
((n) << 4))
#define MT_MIB_RTS_RETRIES_COUNT_MASK GENMASK(31, 16) #define MT_MIB_RTS_RETRIES_COUNT_MASK GENMASK(31, 16)
#define MT_MIB_RTS_COUNT_MASK GENMASK(15, 0) #define MT_MIB_RTS_COUNT_MASK GENMASK(15, 0)
......
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