| From foo@baz Tue Jan 29 11:19:20 CET 2019 |
| From: Stanislaw Gruszka <sgruszka@redhat.com> |
| Date: Tue, 22 Jan 2019 13:38:36 +0100 |
| Subject: mt76x0: antenna select corrections |
| To: stable@vger.kernel.org |
| Cc: Felix Fietkau <nbd@nbd.name>, linux-wireless@vger.kernel.org, Lorenzo Bianconi <lorenzo.bianconi@redhat.com> |
| Message-ID: <1548160717-4059-7-git-send-email-sgruszka@redhat.com> |
| |
| From: Stanislaw Gruszka <sgruszka@redhat.com> |
| |
| commit ef442b73b6bc36b5499e1983611abb46e6337975 upstream. |
| |
| Update mt76x0_phy_ant_select() to conform vendor driver, most notably |
| add dual antenna mode support, read configuration from EEPROM and |
| move ant select out of channel config to init phase. Plus small MT7630E |
| quirk for MT_CMB_CTRL register which vendor driver dedicated to this |
| chip do. |
| |
| This make MT7630E workable with mt76x0e driver and do not cause any |
| problems on MT7610U for me. |
| |
| Acked-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> |
| Signed-off-by: Felix Fietkau <nbd@nbd.name> |
| Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/wireless/mediatek/mt76/mt76x0/phy.c | 52 +++++++++++++++----- |
| drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h | 10 +-- |
| 2 files changed, 44 insertions(+), 18 deletions(-) |
| |
| --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c |
| +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c |
| @@ -518,21 +518,47 @@ mt76x0_phy_set_chan_bbp_params(struct mt |
| |
| static void mt76x0_ant_select(struct mt76x02_dev *dev) |
| { |
| - struct ieee80211_channel *chan = dev->mt76.chandef.chan; |
| - |
| - /* single antenna mode */ |
| - if (chan->band == NL80211_BAND_2GHZ) { |
| - mt76_rmw(dev, MT_COEXCFG3, |
| - BIT(5) | BIT(4) | BIT(3) | BIT(2), BIT(1)); |
| - mt76_rmw(dev, MT_WLAN_FUN_CTRL, BIT(5), BIT(6)); |
| + u16 ee_ant = mt76x02_eeprom_get(dev, MT_EE_ANTENNA); |
| + u16 nic_conf2 = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_2); |
| + u32 wlan, coex3, cmb; |
| + bool ant_div; |
| + |
| + wlan = mt76_rr(dev, MT_WLAN_FUN_CTRL); |
| + cmb = mt76_rr(dev, MT_CMB_CTRL); |
| + coex3 = mt76_rr(dev, MT_COEXCFG3); |
| + |
| + cmb &= ~(BIT(14) | BIT(12)); |
| + wlan &= ~(BIT(6) | BIT(5)); |
| + coex3 &= ~GENMASK(5, 2); |
| + |
| + if (ee_ant & MT_EE_ANTENNA_DUAL) { |
| + /* dual antenna mode */ |
| + ant_div = !(nic_conf2 & MT_EE_NIC_CONF_2_ANT_OPT) && |
| + (nic_conf2 & MT_EE_NIC_CONF_2_ANT_DIV); |
| + if (ant_div) |
| + cmb |= BIT(12); |
| + else |
| + coex3 |= BIT(4); |
| + coex3 |= BIT(3); |
| + if (dev->mt76.cap.has_2ghz) |
| + wlan |= BIT(6); |
| } else { |
| - mt76_rmw(dev, MT_COEXCFG3, BIT(5) | BIT(2), |
| - BIT(4) | BIT(3)); |
| - mt76_clear(dev, MT_WLAN_FUN_CTRL, |
| - BIT(6) | BIT(5)); |
| + /* sigle antenna mode */ |
| + if (dev->mt76.cap.has_5ghz) { |
| + coex3 |= BIT(3) | BIT(4); |
| + } else { |
| + wlan |= BIT(6); |
| + coex3 |= BIT(1); |
| + } |
| } |
| - mt76_clear(dev, MT_CMB_CTRL, BIT(14) | BIT(12)); |
| + |
| + if (is_mt7630(dev)) |
| + cmb |= BIT(14) | BIT(11); |
| + |
| + mt76_wr(dev, MT_WLAN_FUN_CTRL, wlan); |
| + mt76_wr(dev, MT_CMB_CTRL, cmb); |
| mt76_clear(dev, MT_COEXCFG0, BIT(2)); |
| + mt76_wr(dev, MT_COEXCFG3, coex3); |
| } |
| |
| static void |
| @@ -700,7 +726,6 @@ int mt76x0_phy_set_channel(struct mt76x0 |
| mt76x02_phy_set_bw(dev, chandef->width, ch_group_index); |
| mt76x02_phy_set_band(dev, chandef->chan->band, |
| ch_group_index & 1); |
| - mt76x0_ant_select(dev); |
| |
| mt76_rmw(dev, MT_EXT_CCA_CFG, |
| (MT_EXT_CCA_CFG_CCA0 | |
| @@ -927,6 +952,7 @@ void mt76x0_phy_init(struct mt76x02_dev |
| { |
| INIT_DELAYED_WORK(&dev->cal_work, mt76x0_phy_calibration_work); |
| |
| + mt76x0_ant_select(dev); |
| mt76x0_rf_init(dev); |
| mt76x02_phy_set_rxpath(dev); |
| mt76x02_phy_set_txdac(dev); |
| --- a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h |
| +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h |
| @@ -25,6 +25,7 @@ enum mt76x02_eeprom_field { |
| MT_EE_VERSION = 0x002, |
| MT_EE_MAC_ADDR = 0x004, |
| MT_EE_PCI_ID = 0x00A, |
| + MT_EE_ANTENNA = 0x022, |
| MT_EE_NIC_CONF_0 = 0x034, |
| MT_EE_NIC_CONF_1 = 0x036, |
| MT_EE_COUNTRY_REGION_5GHZ = 0x038, |
| @@ -104,6 +105,8 @@ enum mt76x02_eeprom_field { |
| __MT_EE_MAX |
| }; |
| |
| +#define MT_EE_ANTENNA_DUAL BIT(15) |
| + |
| #define MT_EE_NIC_CONF_0_RX_PATH GENMASK(3, 0) |
| #define MT_EE_NIC_CONF_0_TX_PATH GENMASK(7, 4) |
| #define MT_EE_NIC_CONF_0_PA_TYPE GENMASK(9, 8) |
| @@ -118,12 +121,9 @@ enum mt76x02_eeprom_field { |
| #define MT_EE_NIC_CONF_1_LNA_EXT_5G BIT(3) |
| #define MT_EE_NIC_CONF_1_TX_ALC_EN BIT(13) |
| |
| -#define MT_EE_NIC_CONF_2_RX_STREAM GENMASK(3, 0) |
| -#define MT_EE_NIC_CONF_2_TX_STREAM GENMASK(7, 4) |
| -#define MT_EE_NIC_CONF_2_HW_ANTDIV BIT(8) |
| +#define MT_EE_NIC_CONF_2_ANT_OPT BIT(3) |
| +#define MT_EE_NIC_CONF_2_ANT_DIV BIT(4) |
| #define MT_EE_NIC_CONF_2_XTAL_OPTION GENMASK(10, 9) |
| -#define MT_EE_NIC_CONF_2_TEMP_DISABLE BIT(11) |
| -#define MT_EE_NIC_CONF_2_COEX_METHOD GENMASK(15, 13) |
| |
| #define MT_EFUSE_USAGE_MAP_SIZE (MT_EE_USAGE_MAP_END - \ |
| MT_EE_USAGE_MAP_START + 1) |