| From f1b8ee35fec4a070b7760a99709fc98f237c2b86 Mon Sep 17 00:00:00 2001 |
| From: Stanislaw Gruszka <sgruszka@redhat.com> |
| Date: Thu, 1 Nov 2018 16:35:01 +0100 |
| Subject: mt76x02: run calibration after scanning |
| |
| From: Stanislaw Gruszka <sgruszka@redhat.com> |
| |
| commit f1b8ee35fec4a070b7760a99709fc98f237c2b86 upstream. |
| |
| If we are associated and scanning is performed, sw_scan_complete callback |
| is done after we get back to operating channel, so we do not perform |
| queue cal work. Fix this queue cal work from sw_scan_complete(). |
| |
| On mt76x0 we have to restore gain in MT_BBP(AGC, 8) register after |
| scanning, as it was multiple times modified by channel switch code. |
| So queue cal work without any delay to set AGC gain value. |
| |
| Similar like in mt76x2 init AGC gain only when set operating channel |
| and just check before queuing cal work in sw_scan_complete() if |
| initialization was already done. |
| |
| Fixes: bbd10586f0df ("mt76x0: phy: do not run calibration during channel switch") |
| Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> |
| Signed-off-by: Felix Fietkau <nbd@nbd.name> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| |
| --- |
| drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 3 +++ |
| drivers/net/wireless/mediatek/mt76/mt76x0/phy.c | 2 +- |
| drivers/net/wireless/mediatek/mt76/mt76x02.h | 1 + |
| drivers/net/wireless/mediatek/mt76/mt76x02_phy.c | 1 + |
| drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c | 3 +++ |
| 5 files changed, 9 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c |
| +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c |
| @@ -138,6 +138,9 @@ void mt76x0_sw_scan_complete(struct ieee |
| struct mt76x02_dev *dev = hw->priv; |
| |
| clear_bit(MT76_SCANNING, &dev->mt76.state); |
| + |
| + if (dev->cal.gain_init_done) |
| + ieee80211_queue_delayed_work(hw, &dev->cal_work, 0); |
| } |
| EXPORT_SYMBOL_GPL(mt76x0_sw_scan_complete); |
| |
| --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c |
| +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c |
| @@ -720,7 +720,6 @@ int mt76x0_phy_set_channel(struct mt76x0 |
| |
| mt76x0_read_rx_gain(dev); |
| mt76x0_phy_set_chan_bbp_params(dev, rf_bw_band); |
| - mt76x02_init_agc_gain(dev); |
| |
| if (mt76_is_usb(dev)) { |
| mt76x0_vco_cal(dev, channel); |
| @@ -732,6 +731,7 @@ int mt76x0_phy_set_channel(struct mt76x0 |
| if (scan) |
| return 0; |
| |
| + mt76x02_init_agc_gain(dev); |
| if (mt76_is_mmio(dev)) |
| mt76x0_phy_calibrate(dev, false); |
| mt76x0_phy_set_txpower(dev); |
| --- a/drivers/net/wireless/mediatek/mt76/mt76x02.h |
| +++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h |
| @@ -63,6 +63,7 @@ struct mt76x02_calibration { |
| bool tssi_comp_pending; |
| bool dpd_cal_done; |
| bool channel_cal_done; |
| + bool gain_init_done; |
| }; |
| |
| struct mt76x02_dev { |
| --- a/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c |
| +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_phy.c |
| @@ -254,5 +254,6 @@ void mt76x02_init_agc_gain(struct mt76x0 |
| memcpy(dev->cal.agc_gain_cur, dev->cal.agc_gain_init, |
| sizeof(dev->cal.agc_gain_cur)); |
| dev->cal.low_gain = -1; |
| + dev->cal.gain_init_done = true; |
| } |
| EXPORT_SYMBOL_GPL(mt76x02_init_agc_gain); |
| --- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c |
| +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c |
| @@ -156,6 +156,9 @@ mt76x2u_sw_scan_complete(struct ieee8021 |
| struct mt76x02_dev *dev = hw->priv; |
| |
| clear_bit(MT76_SCANNING, &dev->mt76.state); |
| + |
| + if (dev->cal.gain_init_done) |
| + ieee80211_queue_delayed_work(hw, &dev->cal_work, 0); |
| } |
| |
| const struct ieee80211_ops mt76x2u_ops = { |