diff options
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt76x2/phy.c')
| -rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x2/phy.c | 80 |
1 files changed, 43 insertions, 37 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c index c9634a774705..a5efa13a892f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "mt76x2.h" @@ -25,7 +14,8 @@ mt76x2_adjust_high_lna_gain(struct mt76x02_dev *dev, int reg, s8 offset) { s8 gain; - gain = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN, mt76_rr(dev, MT_BBP(AGC, reg))); + gain = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN, + mt76_rr(dev, MT_BBP(AGC, reg))); gain -= offset / 2; mt76_rmw_field(dev, MT_BBP(AGC, reg), MT_BBP_AGC_LNA_HIGH_GAIN, gain); } @@ -126,7 +116,7 @@ void mt76x2_phy_set_txpower_regs(struct mt76x02_dev *dev, EXPORT_SYMBOL_GPL(mt76x2_phy_set_txpower_regs); static int -mt76x2_get_min_rate_power(struct mt76_rate_power *r) +mt76x2_get_min_rate_power(struct mt76x02_rate_power *r) { int i; s8 ret = 0; @@ -146,11 +136,11 @@ mt76x2_get_min_rate_power(struct mt76_rate_power *r) void mt76x2_phy_set_txpower(struct mt76x02_dev *dev) { - enum nl80211_chan_width width = dev->mt76.chandef.width; - struct ieee80211_channel *chan = dev->mt76.chandef.chan; + enum nl80211_chan_width width = dev->mphy.chandef.width; + struct ieee80211_channel *chan = dev->mphy.chandef.chan; struct mt76x2_tx_power_info txp; int txp_0, txp_1, delta = 0; - struct mt76_rate_power t = {}; + struct mt76x02_rate_power t = {}; int base_power, gain; mt76x2_get_power_info(dev, &txp, chan); @@ -161,12 +151,12 @@ void mt76x2_phy_set_txpower(struct mt76x02_dev *dev) delta = txp.delta_bw80; mt76x2_get_rate_power(dev, &t, chan); - mt76x02_add_rate_power_offset(&t, txp.chain[0].target_power); - mt76x02_limit_rate_power(&t, dev->mt76.txpower_conf); - dev->mt76.txpower_cur = mt76x02_get_max_rate_power(&t); + mt76x02_add_rate_power_offset(&t, txp.target_power + delta); + mt76x02_limit_rate_power(&t, dev->txpower_conf); + dev->mphy.txpower_cur = mt76x02_get_max_rate_power(&t); base_power = mt76x2_get_min_rate_power(&t); - delta += base_power - txp.chain[0].target_power; + delta = base_power - txp.target_power; txp_0 = txp.chain[0].target_power + txp.chain[0].delta + delta; txp_1 = txp.chain[1].target_power + txp.chain[1].delta + delta; @@ -182,10 +172,10 @@ void mt76x2_phy_set_txpower(struct mt76x02_dev *dev) } mt76x02_add_rate_power_offset(&t, -base_power); - dev->target_power = txp.chain[0].target_power; + dev->target_power = txp.target_power; dev->target_power_delta[0] = txp_0 - txp.chain[0].target_power; dev->target_power_delta[1] = txp_1 - txp.chain[0].target_power; - dev->mt76.rate_power = t; + dev->rate_power = t; mt76x02_phy_set_txpower(dev, txp_0, txp_1); } @@ -212,7 +202,7 @@ EXPORT_SYMBOL_GPL(mt76x2_configure_tx_delay); void mt76x2_phy_tssi_compensate(struct mt76x02_dev *dev) { - struct ieee80211_channel *chan = dev->mt76.chandef.chan; + struct ieee80211_channel *chan = dev->mphy.chandef.chan; struct mt76x2_tx_power_info txp; struct mt76x2_tssi_comp t = {}; @@ -241,7 +231,7 @@ void mt76x2_phy_tssi_compensate(struct mt76x02_dev *dev) t.offset1 = txp.chain[1].tssi_offset; mt76x2_mcu_tssi_comp(dev, &t); - if (t.pa_mode || dev->cal.dpd_cal_done) + if (t.pa_mode || dev->cal.dpd_cal_done || dev->ed_tx_blocked) return; usleep_range(10000, 20000); @@ -260,10 +250,15 @@ mt76x2_phy_set_gain_val(struct mt76x02_dev *dev) 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 = 0x1836 << 16; + if (!mt76x2_has_ext_lna(dev) && + dev->mphy.chandef.width >= NL80211_CHAN_WIDTH_40) val = 0x1e42 << 16; - else - val = 0x1836 << 16; + + if (mt76x2_has_ext_lna(dev) && + dev->mphy.chandef.chan->band == NL80211_BAND_2GHZ && + dev->mphy.chandef.width < NL80211_CHAN_WIDTH_40) + val = 0x0f36 << 16; val |= 0xf8; @@ -272,7 +267,7 @@ mt76x2_phy_set_gain_val(struct mt76x02_dev *dev) 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) + if (dev->mphy.chandef.chan->flags & IEEE80211_CHAN_RADAR) mt76x02_phy_dfs_adjust_agc(dev); } @@ -280,14 +275,17 @@ void mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev) { u8 *gain = dev->cal.agc_gain_init; u8 low_gain_delta, gain_delta; + u32 agc_35, agc_37; bool gain_change; int low_gain; u32 val; - dev->cal.avg_rssi_all = mt76x02_phy_get_min_avg_rssi(dev); + dev->cal.avg_rssi_all = mt76_get_min_avg_rssi(&dev->mt76, 0); + if (!dev->cal.avg_rssi_all) + dev->cal.avg_rssi_all = -75; 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)); + (dev->cal.avg_rssi_all > mt76x02_get_low_rssi_gain_thresh(dev)); gain_change = dev->cal.low_gain < 0 || (dev->cal.low_gain & 2) ^ (low_gain & 2); @@ -299,7 +297,7 @@ void mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev) return; } - if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80) { + if (dev->mphy.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) @@ -316,6 +314,16 @@ void mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev) else low_gain_delta = 14; + agc_37 = 0x2121262c; + if (dev->mphy.chandef.chan->band == NL80211_BAND_2GHZ) + agc_35 = 0x11111516; + else if (low_gain == 2) + agc_35 = agc_37 = 0x08080808; + else if (dev->mphy.chandef.width == NL80211_CHAN_WIDTH_80) + agc_35 = 0x10101014; + else + agc_35 = 0x11111116; + if (low_gain == 2) { mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a990); mt76_wr(dev, MT_BBP(AGC, 35), 0x08080808); @@ -324,15 +332,13 @@ void mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev) 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; } + mt76_wr(dev, MT_BBP(AGC, 35), agc_35); + mt76_wr(dev, MT_BBP(AGC, 37), agc_37); + 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); |
