mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-14 17:06:24 -04:00
mt76x2u: align channel gain logic to mt76x2 one
Update vga tuning algorithm to the one used in mt76x2 driver Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
committed by
Felix Fietkau
parent
cac97ed681
commit
989582e50c
@@ -19,7 +19,6 @@
|
||||
|
||||
void mt76x2_dfs_init_params(struct mt76x02_dev *dev);
|
||||
void mt76x2_dfs_init_detector(struct mt76x02_dev *dev);
|
||||
void mt76x2_dfs_adjust_agc(struct mt76x02_dev *dev);
|
||||
void mt76x2_dfs_set_domain(struct mt76x02_dev *dev,
|
||||
enum nl80211_dfs_regions region);
|
||||
|
||||
|
||||
@@ -98,5 +98,6 @@ void mt76x2_phy_set_txpower_regs(struct mt76x02_dev *dev,
|
||||
void mt76x2_configure_tx_delay(struct mt76x02_dev *dev,
|
||||
enum nl80211_band band, u8 bw);
|
||||
void mt76x2_apply_gain_adj(struct mt76x02_dev *dev);
|
||||
void mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -46,8 +46,6 @@ void mt76x2u_phy_calibrate(struct work_struct *work);
|
||||
void mt76x2u_phy_channel_calibrate(struct mt76x02_dev *dev);
|
||||
|
||||
void mt76x2u_mcu_complete_urb(struct urb *urb);
|
||||
int mt76x2u_mcu_set_dynamic_vga(struct mt76x02_dev *dev, u8 channel, bool ap,
|
||||
bool ext, int rssi, u32 false_cca);
|
||||
int mt76x2u_mcu_init(struct mt76x02_dev *dev);
|
||||
int mt76x2u_mcu_fw_init(struct mt76x02_dev *dev);
|
||||
|
||||
|
||||
@@ -803,27 +803,6 @@ static void mt76x2_dfs_set_bbp_params(struct mt76x02_dev *dev)
|
||||
mt76_wr(dev, 0x212c, 0x0c350001);
|
||||
}
|
||||
|
||||
void mt76x2_dfs_adjust_agc(struct mt76x02_dev *dev)
|
||||
{
|
||||
u32 agc_r8, agc_r4, val_r8, val_r4, dfs_r31;
|
||||
|
||||
agc_r8 = mt76_rr(dev, MT_BBP(AGC, 8));
|
||||
agc_r4 = mt76_rr(dev, MT_BBP(AGC, 4));
|
||||
|
||||
val_r8 = (agc_r8 & 0x00007e00) >> 9;
|
||||
val_r4 = agc_r4 & ~0x1f000000;
|
||||
val_r4 += (((val_r8 + 1) >> 1) << 24);
|
||||
mt76_wr(dev, MT_BBP(AGC, 4), val_r4);
|
||||
|
||||
dfs_r31 = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN, val_r4);
|
||||
dfs_r31 += val_r8;
|
||||
dfs_r31 -= (agc_r8 & 0x00000038) >> 3;
|
||||
dfs_r31 = (dfs_r31 << 16) | 0x00000307;
|
||||
mt76_wr(dev, MT_BBP(DFS, 31), dfs_r31);
|
||||
|
||||
mt76_wr(dev, MT_BBP(DFS, 32), 0x00040071);
|
||||
}
|
||||
|
||||
void mt76x2_dfs_init_params(struct mt76x02_dev *dev)
|
||||
{
|
||||
struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
|
||||
|
||||
@@ -124,96 +124,6 @@ void mt76x2_phy_set_antenna(struct mt76x02_dev *dev)
|
||||
mt76_wr(dev, MT_BBP(AGC, 0), val);
|
||||
}
|
||||
|
||||
static void
|
||||
mt76x2_phy_set_gain_val(struct mt76x02_dev *dev)
|
||||
{
|
||||
u32 val;
|
||||
u8 gain_val[2];
|
||||
|
||||
gain_val[0] = dev->cal.agc_gain_cur[0] - dev->cal.agc_gain_adjust;
|
||||
gain_val[1] = dev->cal.agc_gain_cur[1] - dev->cal.agc_gain_adjust;
|
||||
|
||||
if (dev->mt76.chandef.width >= NL80211_CHAN_WIDTH_40)
|
||||
val = 0x1e42 << 16;
|
||||
else
|
||||
val = 0x1836 << 16;
|
||||
|
||||
val |= 0xf8;
|
||||
|
||||
mt76_wr(dev, MT_BBP(AGC, 8),
|
||||
val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[0]));
|
||||
mt76_wr(dev, MT_BBP(AGC, 9),
|
||||
val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[1]));
|
||||
|
||||
if (dev->mt76.chandef.chan->flags & IEEE80211_CHAN_RADAR)
|
||||
mt76x2_dfs_adjust_agc(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev)
|
||||
{
|
||||
u8 *gain = dev->cal.agc_gain_init;
|
||||
u8 low_gain_delta, gain_delta;
|
||||
bool gain_change;
|
||||
int low_gain;
|
||||
u32 val;
|
||||
|
||||
dev->cal.avg_rssi_all = mt76x02_phy_get_min_avg_rssi(dev);
|
||||
|
||||
low_gain = (dev->cal.avg_rssi_all > mt76x02_get_rssi_gain_thresh(dev)) +
|
||||
(dev->cal.avg_rssi_all > mt76x02_get_low_rssi_gain_thresh(dev));
|
||||
|
||||
gain_change = (dev->cal.low_gain & 2) ^ (low_gain & 2);
|
||||
dev->cal.low_gain = low_gain;
|
||||
|
||||
if (!gain_change) {
|
||||
if (mt76x02_phy_adjust_vga_gain(dev))
|
||||
mt76x2_phy_set_gain_val(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
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 (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);
|
||||
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)
|
||||
mt76_wr(dev, MT_BBP(AGC, 35), 0x10101014);
|
||||
else
|
||||
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;
|
||||
mt76x2_phy_set_gain_val(dev);
|
||||
|
||||
/* clear false CCA counters */
|
||||
mt76_rr(dev, MT_RX_STAT_1);
|
||||
}
|
||||
|
||||
int mt76x2_phy_set_channel(struct mt76x02_dev *dev,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
|
||||
@@ -250,3 +250,114 @@ void mt76x2_phy_tssi_compensate(struct mt76x02_dev *dev, bool wait)
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x2_phy_tssi_compensate);
|
||||
|
||||
static void mt76x2_phy_dfs_adjust_agc(struct mt76x02_dev *dev)
|
||||
{
|
||||
u32 agc_r8, agc_r4, val_r8, val_r4, dfs_r31;
|
||||
|
||||
agc_r8 = mt76_rr(dev, MT_BBP(AGC, 8));
|
||||
agc_r4 = mt76_rr(dev, MT_BBP(AGC, 4));
|
||||
|
||||
val_r8 = (agc_r8 & 0x00007e00) >> 9;
|
||||
val_r4 = agc_r4 & ~0x1f000000;
|
||||
val_r4 += (((val_r8 + 1) >> 1) << 24);
|
||||
mt76_wr(dev, MT_BBP(AGC, 4), val_r4);
|
||||
|
||||
dfs_r31 = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN, val_r4);
|
||||
dfs_r31 += val_r8;
|
||||
dfs_r31 -= (agc_r8 & 0x00000038) >> 3;
|
||||
dfs_r31 = (dfs_r31 << 16) | 0x00000307;
|
||||
mt76_wr(dev, MT_BBP(DFS, 31), dfs_r31);
|
||||
|
||||
mt76_wr(dev, MT_BBP(DFS, 32), 0x00040071);
|
||||
}
|
||||
|
||||
static void
|
||||
mt76x2_phy_set_gain_val(struct mt76x02_dev *dev)
|
||||
{
|
||||
u32 val;
|
||||
u8 gain_val[2];
|
||||
|
||||
gain_val[0] = dev->cal.agc_gain_cur[0] - dev->cal.agc_gain_adjust;
|
||||
gain_val[1] = dev->cal.agc_gain_cur[1] - dev->cal.agc_gain_adjust;
|
||||
|
||||
if (dev->mt76.chandef.width >= NL80211_CHAN_WIDTH_40)
|
||||
val = 0x1e42 << 16;
|
||||
else
|
||||
val = 0x1836 << 16;
|
||||
|
||||
val |= 0xf8;
|
||||
|
||||
mt76_wr(dev, MT_BBP(AGC, 8),
|
||||
val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[0]));
|
||||
mt76_wr(dev, MT_BBP(AGC, 9),
|
||||
val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[1]));
|
||||
|
||||
if (dev->mt76.chandef.chan->flags & IEEE80211_CHAN_RADAR)
|
||||
mt76x2_phy_dfs_adjust_agc(dev);
|
||||
}
|
||||
|
||||
void mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev)
|
||||
{
|
||||
u8 *gain = dev->cal.agc_gain_init;
|
||||
u8 low_gain_delta, gain_delta;
|
||||
bool gain_change;
|
||||
int low_gain;
|
||||
u32 val;
|
||||
|
||||
dev->cal.avg_rssi_all = mt76x02_phy_get_min_avg_rssi(dev);
|
||||
|
||||
low_gain = (dev->cal.avg_rssi_all > mt76x02_get_rssi_gain_thresh(dev)) +
|
||||
(dev->cal.avg_rssi_all > mt76x02_get_low_rssi_gain_thresh(dev));
|
||||
|
||||
gain_change = (dev->cal.low_gain & 2) ^ (low_gain & 2);
|
||||
dev->cal.low_gain = low_gain;
|
||||
|
||||
if (!gain_change) {
|
||||
if (mt76x02_phy_adjust_vga_gain(dev))
|
||||
mt76x2_phy_set_gain_val(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
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 (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);
|
||||
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)
|
||||
mt76_wr(dev, MT_BBP(AGC, 35), 0x10101014);
|
||||
else
|
||||
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;
|
||||
mt76x2_phy_set_gain_val(dev);
|
||||
|
||||
/* clear false CCA counters */
|
||||
mt76_rr(dev, MT_RX_STAT_1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x2_phy_update_channel_gain);
|
||||
|
||||
@@ -29,30 +29,6 @@
|
||||
#define MT76U_MCU_DLM_OFFSET 0x110000
|
||||
#define MT76U_MCU_ROM_PATCH_OFFSET 0x90000
|
||||
|
||||
int mt76x2u_mcu_set_dynamic_vga(struct mt76x02_dev *dev, u8 channel, bool ap,
|
||||
bool ext, int rssi, u32 false_cca)
|
||||
{
|
||||
struct {
|
||||
__le32 channel;
|
||||
__le32 rssi_val;
|
||||
__le32 false_cca_val;
|
||||
} __packed __aligned(4) msg = {
|
||||
.rssi_val = cpu_to_le32(rssi),
|
||||
.false_cca_val = cpu_to_le32(false_cca),
|
||||
};
|
||||
struct sk_buff *skb;
|
||||
u32 val = channel;
|
||||
|
||||
if (ap)
|
||||
val |= BIT(31);
|
||||
if (ext)
|
||||
val |= BIT(30);
|
||||
msg.channel = cpu_to_le32(val);
|
||||
|
||||
skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg));
|
||||
return mt76_mcu_send_msg(dev, skb, CMD_DYNC_VGA_OP, true);
|
||||
}
|
||||
|
||||
static void mt76x2u_mcu_load_ivb(struct mt76x02_dev *dev)
|
||||
{
|
||||
mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE,
|
||||
|
||||
@@ -39,51 +39,13 @@ void mt76x2u_phy_channel_calibrate(struct mt76x02_dev *dev)
|
||||
mt76x2u_mac_resume(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
mt76x2u_phy_update_channel_gain(struct mt76x02_dev *dev)
|
||||
{
|
||||
u8 channel = dev->mt76.chandef.chan->hw_value;
|
||||
int freq, freq1;
|
||||
u32 false_cca;
|
||||
|
||||
freq = dev->mt76.chandef.chan->center_freq;
|
||||
freq1 = dev->mt76.chandef.center_freq1;
|
||||
|
||||
switch (dev->mt76.chandef.width) {
|
||||
case NL80211_CHAN_WIDTH_80: {
|
||||
int ch_group_index;
|
||||
|
||||
ch_group_index = (freq - freq1 + 30) / 20;
|
||||
if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
|
||||
ch_group_index = 0;
|
||||
channel += 6 - ch_group_index * 4;
|
||||
break;
|
||||
}
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
if (freq1 > freq)
|
||||
channel += 2;
|
||||
else
|
||||
channel -= 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
dev->cal.avg_rssi_all = mt76x02_phy_get_min_avg_rssi(dev);
|
||||
false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS,
|
||||
mt76_rr(dev, MT_RX_STAT_1));
|
||||
|
||||
mt76x2u_mcu_set_dynamic_vga(dev, channel, false, false,
|
||||
dev->cal.avg_rssi_all, false_cca);
|
||||
}
|
||||
|
||||
void mt76x2u_phy_calibrate(struct work_struct *work)
|
||||
{
|
||||
struct mt76x02_dev *dev;
|
||||
|
||||
dev = container_of(work, struct mt76x02_dev, cal_work.work);
|
||||
mt76x2_phy_tssi_compensate(dev, false);
|
||||
mt76x2u_phy_update_channel_gain(dev);
|
||||
mt76x2_phy_update_channel_gain(dev);
|
||||
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
|
||||
MT_CALIBRATE_INTERVAL);
|
||||
@@ -202,6 +164,7 @@ int mt76x2u_phy_set_channel(struct mt76x02_dev *dev,
|
||||
if (scan)
|
||||
return 0;
|
||||
|
||||
mt76x02_init_agc_gain(dev);
|
||||
if (mt76x2_tssi_enabled(dev)) {
|
||||
/* init default values for temp compensation */
|
||||
mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP,
|
||||
|
||||
Reference in New Issue
Block a user