diff options
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt76x0')
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x0/dma.h | 126 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c | 55 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x0/main.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x0/pci.c | 49 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x0/pci_mcu.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x0/phy.c | 311 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c | 7 |
11 files changed, 272 insertions, 320 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/dma.h b/drivers/net/wireless/mediatek/mt76/mt76x0/dma.h deleted file mode 100644 index 891ce1c3461f..000000000000 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/dma.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org> - * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __MT76X0U_DMA_H -#define __MT76X0U_DMA_H - -#include <asm/unaligned.h> -#include <linux/skbuff.h> - -#define MT_DMA_HDR_LEN 4 -#define MT_RX_INFO_LEN 4 -#define MT_FCE_INFO_LEN 4 -#define MT_DMA_HDRS (MT_DMA_HDR_LEN + MT_RX_INFO_LEN) - -/* Common Tx DMA descriptor fields */ -#define MT_TXD_INFO_LEN GENMASK(15, 0) -#define MT_TXD_INFO_D_PORT GENMASK(29, 27) -#define MT_TXD_INFO_TYPE GENMASK(31, 30) - -/* Tx DMA MCU command specific flags */ -#define MT_TXD_CMD_SEQ GENMASK(19, 16) -#define MT_TXD_CMD_TYPE GENMASK(26, 20) - -enum mt76_msg_port { - WLAN_PORT, - CPU_RX_PORT, - CPU_TX_PORT, - HOST_PORT, - VIRTUAL_CPU_RX_PORT, - VIRTUAL_CPU_TX_PORT, - DISCARD, -}; - -enum mt76_info_type { - DMA_PACKET, - DMA_COMMAND, -}; - -/* Tx DMA packet specific flags */ -#define MT_TXD_PKT_INFO_NEXT_VLD BIT(16) -#define MT_TXD_PKT_INFO_TX_BURST BIT(17) -#define MT_TXD_PKT_INFO_80211 BIT(19) -#define MT_TXD_PKT_INFO_TSO BIT(20) -#define MT_TXD_PKT_INFO_CSO BIT(21) -#define MT_TXD_PKT_INFO_WIV BIT(24) -#define MT_TXD_PKT_INFO_QSEL GENMASK(26, 25) - -enum mt76_qsel { - MT_QSEL_MGMT, - MT_QSEL_HCCA, - MT_QSEL_EDCA, - MT_QSEL_EDCA_2, -}; - - -static inline int mt76x0_dma_skb_wrap(struct sk_buff *skb, - enum mt76_msg_port d_port, - enum mt76_info_type type, u32 flags) -{ - u32 info; - - /* Buffer layout: - * | 4B | xfer len | pad | 4B | - * | TXINFO | pkt/cmd | zero pad to 4B | zero | - * - * length field of TXINFO should be set to 'xfer len'. - */ - - info = flags | - FIELD_PREP(MT_TXD_INFO_LEN, round_up(skb->len, 4)) | - FIELD_PREP(MT_TXD_INFO_D_PORT, d_port) | - FIELD_PREP(MT_TXD_INFO_TYPE, type); - - put_unaligned_le32(info, skb_push(skb, sizeof(info))); - return skb_put_padto(skb, round_up(skb->len, 4) + 4); -} - -static inline int -mt76x0_dma_skb_wrap_pkt(struct sk_buff *skb, enum mt76_qsel qsel, u32 flags) -{ - flags |= FIELD_PREP(MT_TXD_PKT_INFO_QSEL, qsel); - return mt76x0_dma_skb_wrap(skb, WLAN_PORT, DMA_PACKET, flags); -} - -/* Common Rx DMA descriptor fields */ -#define MT_RXD_INFO_LEN GENMASK(13, 0) -#define MT_RXD_INFO_PCIE_INTR BIT(24) -#define MT_RXD_INFO_QSEL GENMASK(26, 25) -#define MT_RXD_INFO_PORT GENMASK(29, 27) -#define MT_RXD_INFO_TYPE GENMASK(31, 30) - -/* Rx DMA packet specific flags */ -#define MT_RXD_PKT_INFO_UDP_ERR BIT(16) -#define MT_RXD_PKT_INFO_TCP_ERR BIT(17) -#define MT_RXD_PKT_INFO_IP_ERR BIT(18) -#define MT_RXD_PKT_INFO_PKT_80211 BIT(19) -#define MT_RXD_PKT_INFO_L3L4_DONE BIT(20) -#define MT_RXD_PKT_INFO_MAC_LEN GENMASK(23, 21) - -/* Rx DMA MCU command specific flags */ -#define MT_RXD_CMD_INFO_SELF_GEN BIT(15) -#define MT_RXD_CMD_INFO_CMD_SEQ GENMASK(19, 16) -#define MT_RXD_CMD_INFO_EVT_TYPE GENMASK(23, 20) - -enum mt76_evt_type { - CMD_DONE, - CMD_ERROR, - CMD_RETRY, - EVENT_PWR_RSP, - EVENT_WOW_RSP, - EVENT_CARRIER_DETECT_RSP, - EVENT_DFS_DETECT_RSP, -}; - -#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c index 5735038c0e2d..ab4fd6e0f23a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c @@ -31,8 +31,8 @@ mt76x0_efuse_physical_size_check(struct mt76x02_dev *dev) int ret, i; u32 start = 0, end = 0, cnt_free; - ret = mt76x02_get_efuse_data(&dev->mt76, MT_EE_USAGE_MAP_START, - data, sizeof(data), MT_EE_PHYSICAL_READ); + ret = mt76x02_get_efuse_data(dev, MT_EE_USAGE_MAP_START, data, + sizeof(data), MT_EE_PHYSICAL_READ); if (ret) return ret; @@ -55,10 +55,10 @@ mt76x0_efuse_physical_size_check(struct mt76x02_dev *dev) static void mt76x0_set_chip_cap(struct mt76x02_dev *dev) { - u16 nic_conf0 = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_0); - u16 nic_conf1 = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_1); + u16 nic_conf0 = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0); + u16 nic_conf1 = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1); - mt76x02_eeprom_parse_hw_cap(&dev->mt76); + mt76x02_eeprom_parse_hw_cap(dev); dev_dbg(dev->mt76.dev, "2GHz %d 5GHz %d\n", dev->mt76.cap.has_2ghz, dev->mt76.cap.has_5ghz); @@ -86,7 +86,7 @@ static void mt76x0_set_temp_offset(struct mt76x02_dev *dev) { u8 val; - val = mt76x02_eeprom_get(&dev->mt76, MT_EE_2G_TARGET_POWER) >> 8; + val = mt76x02_eeprom_get(dev, MT_EE_2G_TARGET_POWER) >> 8; if (mt76x02_field_valid(val)) dev->cal.rx.temp_offset = mt76x02_sign_extend(val, 8); else @@ -98,12 +98,12 @@ static void mt76x0_set_freq_offset(struct mt76x02_dev *dev) struct mt76x02_rx_freq_cal *caldata = &dev->cal.rx; u8 val; - val = mt76x02_eeprom_get(&dev->mt76, MT_EE_FREQ_OFFSET); + val = mt76x02_eeprom_get(dev, MT_EE_FREQ_OFFSET); if (!mt76x02_field_valid(val)) val = 0; caldata->freq_offset = val; - val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TSSI_BOUND4) >> 8; + val = mt76x02_eeprom_get(dev, MT_EE_TSSI_BOUND4) >> 8; if (!mt76x02_field_valid(val)) val = 0; @@ -118,10 +118,8 @@ void mt76x0_read_rx_gain(struct mt76x02_dev *dev) u16 rssi_offset; int i; - mt76x02_get_rx_gain(&dev->mt76, chan->band, &rssi_offset, - &lna_2g, lna_5g); - caldata->lna_gain = mt76x02_get_lna_gain(&dev->mt76, &lna_2g, - lna_5g, chan); + mt76x02_get_rx_gain(dev, chan->band, &rssi_offset, &lna_2g, lna_5g); + caldata->lna_gain = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan); for (i = 0; i < ARRAY_SIZE(caldata->rssi_offset); i++) { val = rssi_offset >> (8 * i); @@ -132,12 +130,12 @@ void mt76x0_read_rx_gain(struct mt76x02_dev *dev) } } -static s8 mt76x0_get_delta(struct mt76_dev *dev) +static s8 mt76x0_get_delta(struct mt76x02_dev *dev) { - struct cfg80211_chan_def *chandef = &dev->chandef; + struct cfg80211_chan_def *chandef = &dev->mt76.chandef; u8 val; - if (mt76x02_tssi_enabled(dev)) + if (mt76x0_tssi_enabled(dev)) return 0; if (chandef->width == NL80211_CHAN_WIDTH_80) { @@ -162,54 +160,54 @@ void mt76x0_get_tx_power_per_rate(struct mt76x02_dev *dev) struct ieee80211_channel *chan = dev->mt76.chandef.chan; bool is_2ghz = chan->band == NL80211_BAND_2GHZ; struct mt76_rate_power *t = &dev->mt76.rate_power; - s8 delta = mt76x0_get_delta(&dev->mt76); + s8 delta = mt76x0_get_delta(dev); u16 val, addr; memset(t, 0, sizeof(*t)); /* cck 1M, 2M, 5.5M, 11M */ - val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_BYRATE_BASE); + val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_BYRATE_BASE); t->cck[0] = t->cck[1] = s6_to_s8(val); t->cck[2] = t->cck[3] = s6_to_s8(val >> 8); /* ofdm 6M, 9M, 12M, 18M */ addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 2 : 0x120; - val = mt76x02_eeprom_get(&dev->mt76, addr); + val = mt76x02_eeprom_get(dev, addr); t->ofdm[0] = t->ofdm[1] = s6_to_s8(val); t->ofdm[2] = t->ofdm[3] = s6_to_s8(val >> 8); /* ofdm 24M, 36M, 48M, 54M */ addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 4 : 0x122; - val = mt76x02_eeprom_get(&dev->mt76, addr); + val = mt76x02_eeprom_get(dev, addr); t->ofdm[4] = t->ofdm[5] = s6_to_s8(val); t->ofdm[6] = t->ofdm[7] = s6_to_s8(val >> 8); /* ht-vht mcs 1ss 0, 1, 2, 3 */ addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 6 : 0x124; - val = mt76x02_eeprom_get(&dev->mt76, addr); + val = mt76x02_eeprom_get(dev, addr); t->ht[0] = t->ht[1] = t->vht[0] = t->vht[1] = s6_to_s8(val); t->ht[2] = t->ht[3] = t->vht[2] = t->vht[3] = s6_to_s8(val >> 8); /* ht-vht mcs 1ss 4, 5, 6 */ addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 8 : 0x126; - val = mt76x02_eeprom_get(&dev->mt76, addr); + val = mt76x02_eeprom_get(dev, addr); t->ht[4] = t->ht[5] = t->vht[4] = t->vht[5] = s6_to_s8(val); t->ht[6] = t->vht[6] = s6_to_s8(val >> 8); /* ht-vht mcs 1ss 0, 1, 2, 3 stbc */ addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 14 : 0xec; - val = mt76x02_eeprom_get(&dev->mt76, addr); + val = mt76x02_eeprom_get(dev, addr); t->stbc[0] = t->stbc[1] = s6_to_s8(val); t->stbc[2] = t->stbc[3] = s6_to_s8(val >> 8); /* ht-vht mcs 1ss 4, 5, 6 stbc */ addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 16 : 0xee; - val = mt76x02_eeprom_get(&dev->mt76, addr); + val = mt76x02_eeprom_get(dev, addr); t->stbc[4] = t->stbc[5] = s6_to_s8(val); t->stbc[6] = t->stbc[7] = s6_to_s8(val >> 8); /* vht mcs 8, 9 5GHz */ - val = mt76x02_eeprom_get(&dev->mt76, 0x132); + val = mt76x02_eeprom_get(dev, 0x132); t->vht[7] = s6_to_s8(val); t->vht[8] = s6_to_s8(val >> 8); @@ -266,7 +264,7 @@ void mt76x0_get_power_info(struct mt76x02_dev *dev, u8 *info) addr = MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE + 2 + offset; } - data = mt76x02_eeprom_get(&dev->mt76, addr); + data = mt76x02_eeprom_get(dev, addr); info[0] = data; if (!info[0] || info[0] > 0x3f) @@ -312,7 +310,7 @@ static int mt76x0_load_eeprom(struct mt76x02_dev *dev) if (found < 0) return found; - return mt76x02_get_efuse_data(&dev->mt76, 0, dev->mt76.eeprom.data, + return mt76x02_get_efuse_data(dev, 0, dev->mt76.eeprom.data, MT76X0_EEPROM_SIZE, MT_EE_READ); } @@ -326,7 +324,7 @@ int mt76x0_eeprom_init(struct mt76x02_dev *dev) if (err < 0) return err; - data = mt76x02_eeprom_get(&dev->mt76, MT_EE_VERSION); + data = mt76x02_eeprom_get(dev, MT_EE_VERSION); version = data >> 8; fae = data; @@ -337,8 +335,7 @@ int mt76x0_eeprom_init(struct mt76x02_dev *dev) dev_info(dev->mt76.dev, "EEPROM ver:%02hhx fae:%02hhx\n", version, fae); - mt76x02_mac_setaddr(&dev->mt76, - dev->mt76.eeprom.data + MT_EE_MAC_ADDR); + mt76x02_mac_setaddr(dev, dev->mt76.eeprom.data + MT_EE_MAC_ADDR); mt76x0_set_chip_cap(dev); mt76x0_set_freq_offset(dev); mt76x0_set_temp_offset(dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h index 40fd4e61769b..ee9ade9f3c8b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.h @@ -37,4 +37,10 @@ static inline s8 s6_to_s8(u32 val) return ret; } +static inline bool mt76x0_tssi_enabled(struct mt76x02_dev *dev) +{ + return (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) & + MT_EE_NIC_CONF_1_TX_ALC_EN); +} + #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c index ee2b8e885608..4a9408801260 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c @@ -138,7 +138,7 @@ static void mt76x0_init_mac_registers(struct mt76x02_dev *dev) RANDOM_WRITE(dev, common_mac_reg_table); - mt76x02_set_beacon_offsets(&dev->mt76); + mt76x02_set_beacon_offsets(dev); /* Enable PBF and MAC clock SYS_CTRL[11:10] = 0x3 */ RANDOM_WRITE(dev, mt76x0_mac_reg_table); @@ -280,7 +280,7 @@ int mt76x0_init_hardware(struct mt76x02_dev *dev) return -ETIMEDOUT; mt76x0_reset_csr_bbp(dev); - ret = mt76x02_mcu_function_select(&dev->mt76, Q_SELECT, 1, false); + ret = mt76x02_mcu_function_select(dev, Q_SELECT, 1, false); if (ret) return ret; @@ -368,7 +368,10 @@ int mt76x0_register_device(struct mt76x02_dev *dev) hw->max_rates = 1; hw->max_report_rates = 7; hw->max_rate_tries = 1; - hw->extra_tx_headroom = sizeof(struct mt76x02_txwi) + 4 + 2; + hw->extra_tx_headroom = 2; + if (mt76_is_usb(dev)) + hw->extra_tx_headroom += sizeof(struct mt76x02_txwi) + + MT_DMA_HDR_LEN; hw->sta_data_size = sizeof(struct mt76x02_sta); hw->vif_data_size = sizeof(struct mt76x02_vif); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c index c9cd0254a979..9273d2d2764a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c @@ -16,6 +16,20 @@ #include <linux/etherdevice.h> #include "mt76x0.h" +static int +mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef) +{ + int ret; + + cancel_delayed_work_sync(&dev->cal_work); + + mt76_set_channel(&dev->mt76); + ret = mt76x0_phy_set_channel(dev, chandef); + mt76_txq_schedule_all(&dev->mt76); + + return ret; +} + int mt76x0_config(struct ieee80211_hw *hw, u32 changed) { struct mt76x02_dev *dev = hw->priv; @@ -25,7 +39,7 @@ int mt76x0_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { ieee80211_stop_queues(hw); - ret = mt76x0_phy_set_channel(dev, &hw->conf.chandef); + ret = mt76x0_set_channel(dev, &hw->conf.chandef); ieee80211_wake_queues(hw); } @@ -114,8 +128,6 @@ void mt76x0_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct mt76x02_dev *dev = hw->priv; - cancel_delayed_work_sync(&dev->cal_work); - mt76x0_agc_save(dev); set_bit(MT76_SCANNING, &dev->mt76.state); } EXPORT_SYMBOL_GPL(mt76x0_sw_scan); @@ -125,11 +137,7 @@ void mt76x0_sw_scan_complete(struct ieee80211_hw *hw, { struct mt76x02_dev *dev = hw->priv; - mt76x0_agc_restore(dev); clear_bit(MT76_SCANNING, &dev->mt76.state); - - ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work, - MT_CALIBRATE_INTERVAL); } EXPORT_SYMBOL_GPL(mt76x0_sw_scan_complete); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h index b66e70f6cd89..3b34e1d2769f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mcu.h @@ -39,6 +39,9 @@ enum mcu_calibrate { MCU_CAL_TXDCOC, MCU_CAL_RX_GROUP_DELAY, MCU_CAL_TX_GROUP_DELAY, + MCU_CAL_VCO, + MCU_CAL_NO_SIGNAL = 0xfe, + MCU_CAL_FULL = 0xff, }; int mt76x0e_mcu_init(struct mt76x02_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h index 1bff2be45a13..2187bafaf2e9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/mt76x0.h @@ -66,12 +66,11 @@ int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 value); /* PHY */ void mt76x0_phy_init(struct mt76x02_dev *dev); int mt76x0_wait_bbp_ready(struct mt76x02_dev *dev); -void mt76x0_agc_save(struct mt76x02_dev *dev); -void mt76x0_agc_restore(struct mt76x02_dev *dev); int mt76x0_phy_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef); void mt76x0_phy_recalibrate_after_assoc(struct mt76x02_dev *dev); void mt76x0_phy_set_txpower(struct mt76x02_dev *dev); +void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool power_on); /* MAC */ void mt76x0_mac_work(struct work_struct *work); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c index 87997cddf0d6..522c86059bcb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c @@ -28,6 +28,7 @@ static int mt76x0e_start(struct ieee80211_hw *hw) mutex_lock(&dev->mt76.mutex); mt76x02_mac_start(dev); + mt76x0_phy_calibrate(dev, true); ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mac_work, MT_CALIBRATE_INTERVAL); ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work, @@ -71,10 +72,19 @@ static const struct ieee80211_ops mt76x0e_ops = { .tx = mt76x02_tx, .start = mt76x0e_start, .stop = mt76x0e_stop, - .config = mt76x0_config, .add_interface = mt76x02_add_interface, .remove_interface = mt76x02_remove_interface, + .config = mt76x0_config, .configure_filter = mt76x02_configure_filter, + .sta_add = mt76x02_sta_add, + .sta_remove = mt76x02_sta_remove, + .set_key = mt76x02_set_key, + .conf_tx = mt76x02_conf_tx, + .sw_scan_start = mt76x0_sw_scan, + .sw_scan_complete = mt76x0_sw_scan_complete, + .ampdu_action = mt76x02_ampdu_action, + .sta_rate_tbl_update = mt76x02_sta_rate_tbl_update, + .wake_tx_queue = mt76_wake_tx_queue, }; static int mt76x0e_register_device(struct mt76x02_dev *dev) @@ -102,28 +112,34 @@ static int mt76x0e_register_device(struct mt76x02_dev *dev) u16 val; mt76_clear(dev, MT_COEXCFG0, BIT(0)); - val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_0); - if (val & MT_EE_NIC_CONF_0_PA_IO_CURRENT) { - u32 data; - - /* set external external PA I/O - * current to 16mA - */ - data = mt76_rr(dev, 0x11c); - val |= 0xc03; - mt76_wr(dev, 0x11c, val); - } + + val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0); + if (!(val & MT_EE_NIC_CONF_0_PA_IO_CURRENT)) + mt76_set(dev, MT_XO_CTRL7, 0xc03); } mt76_clear(dev, 0x110, BIT(9)); mt76_set(dev, MT_MAX_LEN_CFG, BIT(13)); + err = mt76x0_register_device(dev); + if (err < 0) + return err; + + set_bit(MT76_STATE_INITIALIZED, &dev->mt76.state); + return 0; } static int mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + static const struct mt76_driver_ops drv_ops = { + .txwi_size = sizeof(struct mt76x02_txwi), + .tx_prepare_skb = mt76x02_tx_prepare_skb, + .tx_complete_skb = mt76x02_tx_complete_skb, + .rx_skb = mt76x02_queue_rx_skb, + .rx_poll_complete = mt76x02_rx_poll_complete, + }; struct mt76x02_dev *dev; int ret; @@ -141,7 +157,7 @@ mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (ret) return ret; - dev = mt76x0_alloc_device(&pdev->dev, NULL, &mt76x0e_ops); + dev = mt76x0_alloc_device(&pdev->dev, &drv_ops, &mt76x0e_ops); if (!dev) return -ENOMEM; @@ -150,6 +166,11 @@ mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id) dev->mt76.rev = mt76_rr(dev, MT_ASIC_VERSION); dev_info(dev->mt76.dev, "ASIC revision: %08x\n", dev->mt76.rev); + ret = devm_request_irq(dev->mt76.dev, pdev->irq, mt76x02_irq_handler, + IRQF_SHARED, KBUILD_MODNAME, dev); + if (ret) + goto error; + ret = mt76x0e_register_device(dev); if (ret < 0) goto error; @@ -167,7 +188,7 @@ static void mt76x0e_cleanup(struct mt76x02_dev *dev) mt76x0_chip_onoff(dev, false, false); mt76x0e_stop_hw(dev); mt76x02_dma_cleanup(dev); - mt76x02_mcu_cleanup(&dev->mt76); + mt76x02_mcu_cleanup(dev); } static void diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/pci_mcu.c index 6c66656c21f4..569861289aa5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci_mcu.c @@ -116,6 +116,7 @@ static int mt76x0e_load_firmware(struct mt76x02_dev *dev) goto out; } + mt76x02_set_ethtool_fwver(dev, hdr); dev_dbg(dev->mt76.dev, "Firmware running!\n"); out: diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c index 4850a2db18d7..cf024950e0ed 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c @@ -14,6 +14,9 @@ * GNU General Public License for more details. */ +#include <linux/kernel.h> +#include <linux/etherdevice.h> + #include "mt76x0.h" #include "mcu.h" #include "eeprom.h" @@ -23,8 +26,6 @@ #include "initvals_phy.h" #include "../mt76x02_phy.h" -#include <linux/etherdevice.h> - static int mt76x0_rf_csr_wr(struct mt76x02_dev *dev, u32 offset, u8 value) { @@ -37,7 +38,7 @@ mt76x0_rf_csr_wr(struct mt76x02_dev *dev, u32 offset, u8 value) bank = MT_RF_BANK(offset); reg = MT_RF_REG(offset); - if (WARN_ON_ONCE(reg > 64) || WARN_ON_ONCE(bank) > 8) + if (WARN_ON_ONCE(reg > 127) || WARN_ON_ONCE(bank > 8)) return -EINVAL; mutex_lock(&dev->phy_mutex); @@ -76,7 +77,7 @@ static int mt76x0_rf_csr_rr(struct mt76x02_dev *dev, u32 offset) bank = MT_RF_BANK(offset); reg = MT_RF_REG(offset); - if (WARN_ON_ONCE(reg > 64) || WARN_ON_ONCE(bank) > 8) + if (WARN_ON_ONCE(reg > 127) || WARN_ON_ONCE(bank > 8)) return -EINVAL; mutex_lock(&dev->phy_mutex); @@ -111,15 +112,16 @@ out: static int rf_wr(struct mt76x02_dev *dev, u32 offset, u8 val) { - if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mt76.state)) { + if (mt76_is_usb(dev)) { struct mt76_reg_pair pair = { .reg = offset, .value = val, }; + WARN_ON_ONCE(!test_bit(MT76_STATE_MCU_RUNNING, + &dev->mt76.state)); return mt76_wr_rp(dev, MT_MCU_MEMMAP_RF, &pair, 1); } else { - WARN_ON_ONCE(1); return mt76x0_rf_csr_wr(dev, offset, val); } } @@ -130,15 +132,16 @@ rf_rr(struct mt76x02_dev *dev, u32 offset) int ret; u32 val; - if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mt76.state)) { + if (mt76_is_usb(dev)) { struct mt76_reg_pair pair = { .reg = offset, }; + WARN_ON_ONCE(!test_bit(MT76_STATE_MCU_RUNNING, + &dev->mt76.state)); ret = mt76_rd_rp(dev, MT_MCU_MEMMAP_RF, &pair, 1); val = pair.value; } else { - WARN_ON_ONCE(1); ret = val = mt76x0_rf_csr_rr(dev, offset); } @@ -175,9 +178,22 @@ rf_clear(struct mt76x02_dev *dev, u32 offset, u8 mask) } #endif -#define RF_RANDOM_WRITE(dev, tab) \ - mt76_wr_rp(dev, MT_MCU_MEMMAP_RF, \ - tab, ARRAY_SIZE(tab)) +static void +mt76x0_rf_csr_wr_rp(struct mt76x02_dev *dev, const struct mt76_reg_pair *data, + int n) +{ + while (n-- > 0) { + mt76x0_rf_csr_wr(dev, data->reg, data->value); + data++; + } +} + +#define RF_RANDOM_WRITE(dev, tab) do { \ + if (mt76_is_mmio(dev)) \ + mt76x0_rf_csr_wr_rp(dev, tab, ARRAY_SIZE(tab)); \ + else \ + mt76_wr_rp(dev, MT_MCU_MEMMAP_RF, tab, ARRAY_SIZE(tab));\ +} while (0) int mt76x0_wait_bbp_ready(struct mt76x02_dev *dev) { @@ -186,7 +202,6 @@ int mt76x0_wait_bbp_ready(struct mt76x02_dev *dev) do { val = mt76_rr(dev, MT_BBP(CORE, 0)); - printk("BBP version %08x\n", val); if (val && ~val) break; } while (--i); @@ -196,36 +211,10 @@ int mt76x0_wait_bbp_ready(struct mt76x02_dev *dev) return -EIO; } + dev_dbg(dev->mt76.dev, "BBP version %08x\n", val); return 0; } -static void -mt76x0_bbp_set_ctrlch(struct mt76x02_dev *dev, enum nl80211_chan_width width, - u8 ctrl) -{ - int core_val, agc_val; - - switch (width) { - case NL80211_CHAN_WIDTH_80: - core_val = 3; - agc_val = 7; - break; - case NL80211_CHAN_WIDTH_40: - core_val = 2; - agc_val = 3; - break; - default: - core_val = 0; - agc_val = 1; - break; - } - - mt76_rmw_field(dev, MT_BBP(CORE, 1), MT_BBP_CORE_R1_BW, core_val); - mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_BW, agc_val); - mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_CTRL_CHAN, ctrl); - mt76_rmw_field(dev, MT_BBP(TXBE, 0), MT_BBP_TXBE_R0_CTRL_CHAN, ctrl); -} - static void mt76x0_vco_cal(struct mt76x02_dev *dev, u8 channel) { u8 val; @@ -283,13 +272,6 @@ static void mt76x0_vco_cal(struct mt76x02_dev *dev, u8 channel) } static void -mt76x0_mac_set_ctrlch(struct mt76x02_dev *dev, bool primary_upper) -{ - mt76_rmw_field(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_UPPER_40M, - primary_upper); -} - -static void mt76x0_phy_set_band(struct mt76x02_dev *dev, enum nl80211_band band) { switch (band) { @@ -299,9 +281,6 @@ mt76x0_phy_set_band(struct mt76x02_dev *dev, enum nl80211_band band) rf_wr(dev, MT_RF(5, 0), 0x45); rf_wr(dev, MT_RF(6, 0), 0x44); - mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G); - mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G); - mt76_wr(dev, MT_TX_ALC_VGA3, 0x00050007); mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x003E0002); break; @@ -311,9 +290,6 @@ mt76x0_phy_set_band(struct mt76x02_dev *dev, enum nl80211_band band) rf_wr(dev, MT_RF(5, 0), 0x44); rf_wr(dev, MT_RF(6, 0), 0x45); - mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G); - mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G); - mt76_wr(dev, MT_TX_ALC_VGA3, 0x00000005); mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x01010102); break; @@ -475,7 +451,7 @@ mt76x0_phy_set_chan_rf_params(struct mt76x02_dev *dev, u8 channel, u16 rf_bw_ban mt76_wr(dev, MT_RF_MISC, mac_reg); band = (rf_band & RF_G_BAND) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; - if (mt76x02_ext_pa_enabled(&dev->mt76, band)) { + if (mt76x02_ext_pa_enabled(dev, band)) { /* MT_RF_MISC (offset: 0x0518) [2]1'b1: enable external A band PA, 1'b0: disable external A band PA @@ -514,7 +490,7 @@ mt76x0_phy_set_chan_rf_params(struct mt76x02_dev *dev, u8 channel, u16 rf_bw_ban } static void -mt76x0_phy_set_chan_bbp_params(struct mt76x02_dev *dev, u8 channel, u16 rf_bw_band) +mt76x0_phy_set_chan_bbp_params(struct mt76x02_dev *dev, u16 rf_bw_band) { int i; @@ -587,7 +563,7 @@ mt76x0_bbp_set_bw(struct mt76x02_dev *dev, enum nl80211_chan_width width) return ; } - mt76x02_mcu_function_select(&dev->mt76, BW_SETTING, bw, false); + mt76x02_mcu_function_select(dev, BW_SETTING, bw, false); } void mt76x0_phy_set_txpower(struct mt76x02_dev *dev) @@ -603,8 +579,50 @@ void mt76x0_phy_set_txpower(struct mt76x02_dev *dev) dev->mt76.txpower_cur = mt76x02_get_max_rate_power(t); mt76x02_add_rate_power_offset(t, -info[0]); - mt76x02_phy_set_txpower(&dev->mt76, info[0], info[1]); + mt76x02_phy_set_txpower(dev, info[0], info[1]); +} + +void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool power_on) +{ + struct ieee80211_channel *chan = dev->mt76.chandef.chan; + u32 val, tx_alc, reg_val; + + if (power_on) { + mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0, false); + mt76x02_mcu_calibrate(dev, MCU_CAL_VCO, chan->hw_value, + false); + usleep_range(10, 20); + /* XXX: tssi */ + } + + tx_alc = mt76_rr(dev, MT_TX_ALC_CFG_0); + mt76_wr(dev, MT_TX_ALC_CFG_0, 0); + usleep_range(500, 700); + + reg_val = mt76_rr(dev, MT_BBP(IBI, 9)); + mt76_wr(dev, MT_BBP(IBI, 9), 0xffffff7e); + + if (chan->band == NL80211_BAND_5GHZ) { + if (chan->hw_value < 100) + val = 0x701; + else if (chan->hw_value < 140) + val = 0x801; + else + val = 0x901; + } else { + val = 0x600; + } + + mt76x02_mcu_calibrate(dev, MCU_CAL_FULL, val, false); + msleep(350); + mt76x02_mcu_calibrate(dev, MCU_CAL_LC, 1, false); + usleep_range(15000, 20000); + + mt76_wr(dev, MT_BBP(IBI, 9), reg_val); + mt76_wr(dev, MT_TX_ALC_CFG_0, tx_alc); + mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1, false); } +EXPORT_SYMBOL_GPL(mt76x0_phy_calibrate); int mt76x0_phy_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef) @@ -665,9 +683,19 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev, break; } - mt76x0_bbp_set_bw(dev, chandef->width); - mt76x0_bbp_set_ctrlch(dev, chandef->width, ch_group_index); - mt76x0_mac_set_ctrlch(dev, ch_group_index & 1); + if (mt76_is_usb(dev)) { + mt76x0_bbp_set_bw(dev, chandef->width); + } else { + if (chandef->width == NL80211_CHAN_WIDTH_80 || + chandef->width == NL80211_CHAN_WIDTH_40) + val = 0x201; + else + val = 0x601; + mt76_wr(dev, MT_TX_SW_CFG0, val); + } + 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, @@ -680,7 +708,6 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev, mt76x0_phy_set_band(dev, chandef->chan->band); mt76x0_phy_set_chan_rf_params(dev, channel, rf_bw_band); - mt76x0_read_rx_gain(dev); /* set Japan Tx filter at channel 14 */ val = mt76_rr(dev, MT_BBP(CORE, 1)); @@ -690,17 +717,27 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev, val &= ~0x20; mt76_wr(dev, MT_BBP(CORE, 1), val); - mt76x0_phy_set_chan_bbp_params(dev, channel, rf_bw_band); + mt76x0_read_rx_gain(dev); + mt76x0_phy_set_chan_bbp_params(dev, rf_bw_band); + mt76x02_init_agc_gain(dev); - /* Vendor driver don't do it */ - /* mt76x0_phy_set_tx_power(dev, channel, rf_bw_band); */ + if (mt76_is_usb(dev)) { + mt76x0_vco_cal(dev, channel); + } else { + /* enable vco */ + rf_set(dev, MT_RF(0, 4), BIT(7)); + } - mt76x0_vco_cal(dev, channel); if (scan) - mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, 1, false); + return 0; + if (mt76_is_mmio(dev)) + mt76x0_phy_calibrate(dev, false); mt76x0_phy_set_txpower(dev); + ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work, + MT_CALIBRATE_INTERVAL); + return 0; } @@ -710,7 +747,7 @@ void mt76x0_phy_recalibrate_after_assoc(struct mt76x02_dev *dev) u8 channel = dev->mt76.chandef.chan->hw_value; int is_5ghz = (dev->mt76.chandef.chan->band == NL80211_BAND_5GHZ) ? 1 : 0; - mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_R, 0, false); + mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0, false); mt76x0_vco_cal(dev, channel); @@ -718,109 +755,113 @@ void mt76x0_phy_recalibrate_after_assoc(struct mt76x02_dev *dev) mt76_wr(dev, MT_TX_ALC_CFG_0, 0); usleep_range(500, 700); - reg_val = mt76_rr(dev, 0x2124); - reg_val &= 0xffffff7e; - mt76_wr(dev, 0x2124, reg_val); + reg_val = mt76_rr(dev, MT_BBP(IBI, 9)); + mt76_wr(dev, MT_BBP(IBI, 9), 0xffffff7e); - mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, 0, false); + mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, 0, false); - mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LC, is_5ghz, false); - mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LOFT, is_5ghz, false); - mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TXIQ, is_5ghz, false); - mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_GROUP_DELAY, - is_5ghz, false); - mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXIQ, is_5ghz, false); - mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RX_GROUP_DELAY, - is_5ghz, false); + mt76x02_mcu_calibrate(dev, MCU_CAL_LC, is_5ghz, false); + mt76x02_mcu_calibrate(dev, MCU_CAL_LOFT, is_5ghz, false); + mt76x02_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz, false); + mt76x02_mcu_calibrate(dev, MCU_CAL_TX_GROUP_DELAY, is_5ghz, false); + mt76x02_mcu_calibrate(dev, MCU_CAL_RXIQ, is_5ghz, false); + mt76x02_mcu_calibrate(dev, MCU_CAL_RX_GROUP_DELAY, is_5ghz, false); - mt76_wr(dev, 0x2124, reg_val); + mt76_wr(dev, MT_BBP(IBI, 9), reg_val); mt76_wr(dev, MT_TX_ALC_CFG_0, tx_alc); msleep(100); - mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, 1, false); -} - -void mt76x0_agc_save(struct mt76x02_dev *dev) -{ - /* Only one RX path */ - dev->agc_save = FIELD_GET(MT_BBP_AGC_GAIN, mt76_rr(dev, MT_BBP(AGC, 8))); -} - -void mt76x0_agc_restore(struct mt76x02_dev *dev) -{ - mt76_rmw_field(dev, MT_BBP(AGC, 8), MT_BBP_AGC_GAIN, dev->agc_save); + mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1, false); } static void mt76x0_temp_sensor(struct mt76x02_dev *dev) { u8 rf_b7_73, rf_b0_66, rf_b0_67; - int cycle, temp; - u32 val; - s32 sval; + s8 val; rf_b7_73 = rf_rr(dev, MT_RF(7, 73)); rf_b0_66 = rf_rr(dev, MT_RF(0, 66)); - rf_b0_67 = rf_rr(dev, MT_RF(0, 73)); + rf_b0_67 = rf_rr(dev, MT_RF(0, 67)); rf_wr(dev, MT_RF(7, 73), 0x02); rf_wr(dev, MT_RF(0, 66), 0x23); - rf_wr(dev, MT_RF(0, 73), 0x01); + rf_wr(dev, MT_RF(0, 67), 0x01); mt76_wr(dev, MT_BBP(CORE, 34), 0x00080055); - for (cycle = 0; cycle < 2000; cycle++) { - val = mt76_rr(dev, MT_BBP(CORE, 34)); - if (!(val & 0x10)) - break; - udelay(3); - } - - if (cycle >= 2000) { - val &= 0x10; - mt76_wr(dev, MT_BBP(CORE, 34), val); + if (!mt76_poll(dev, MT_BBP(CORE, 34), BIT(4), 0, 2000)) { + mt76_clear(dev, MT_BBP(CORE, 34), BIT(4)); goto done; } - sval = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff; - if (!(sval & 0x80)) - sval &= 0x7f; /* Positive */ - else - sval |= 0xffffff00; /* Negative */ + val = mt76_rr(dev, MT_BBP(CORE, 35)); + val = (35 * (val - dev->cal.rx.temp_offset)) / 10 + 25; - temp = (35 * (sval - dev->cal.rx.temp_offset)) / 10 + 25; + if (abs(val - dev->cal.temp_vco) > 20) { + mt76x02_mcu_calibrate(dev, MCU_CAL_VCO, + dev->mt76.chandef.chan->hw_value, + false); + dev->cal.temp_vco = val; + } + if (abs(val - dev->cal.temp) > 30) { + mt76x0_phy_calibrate(dev, false); + dev->cal.temp = val; + } done: rf_wr(dev, MT_RF(7, 73), rf_b7_73); rf_wr(dev, MT_RF(0, 66), rf_b0_66); - rf_wr(dev, MT_RF(0, 73), rf_b0_67); + rf_wr(dev, MT_RF(0, 67), rf_b0_67); } -static void mt76x0_dynamic_vga_tuning(struct mt76x02_dev *dev) +static void mt76x0_phy_set_gain_val(struct mt76x02_dev *dev) { - struct cfg80211_chan_def *chandef = &dev->mt76.chandef; - u32 val, init_vga; - int avg_rssi; - - init_vga = chandef->chan->band == NL80211_BAND_5GHZ ? 0x54 : 0x4E; - avg_rssi = mt76x02_phy_get_min_avg_rssi(&dev->mt76); - if (avg_rssi > -60) - init_vga -= 0x20; - else if (avg_rssi > -70) - init_vga -= 0x10; - - val = mt76_rr(dev, MT_BBP(AGC, 8)); - val &= 0xFFFF80FF; - val |= init_vga << 8; - mt76_wr(dev, MT_BBP(AGC,8), val); + u8 gain = dev->cal.agc_gain_cur[0] - dev->cal.agc_gain_adjust; + u32 val = 0x122c << 16 | 0xf2; + + mt76_wr(dev, MT_BBP(AGC, 8), + val | FIELD_PREP(MT_BBP_AGC_GAIN, gain)); +} + +static void +mt76x0_phy_update_channel_gain(struct mt76x02_dev *dev) +{ + bool gain_change; + u8 gain_delta; + int low_gain; + + 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)) + mt76x0_phy_set_gain_val(dev); + return; + } + + dev->cal.agc_gain_adjust = (low_gain == 2) ? 0 : 10; + gain_delta = (low_gain == 2) ? 10 : 0; + + dev->cal.agc_gain_cur[0] = dev->cal.agc_gain_init[0] - gain_delta; + mt76x0_phy_set_gain_val(dev); + + /* clear false CCA counters */ + mt76_rr(dev, MT_RX_STAT_1); } -static void mt76x0_phy_calibrate(struct work_struct *work) +static void mt76x0_phy_calibration_work(struct work_struct *work) { struct mt76x02_dev *dev = container_of(work, struct mt76x02_dev, cal_work.work); - mt76x0_dynamic_vga_tuning(dev); - mt76x0_temp_sensor(dev); + mt76x0_phy_update_channel_gain(dev); + if (!mt76x0_tssi_enabled(dev)) + mt76x0_temp_sensor(dev); ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work, MT_CALIBRATE_INTERVAL); @@ -881,9 +922,9 @@ static void mt76x0_rf_init(struct mt76x02_dev *dev) void mt76x0_phy_init(struct mt76x02_dev *dev) { - INIT_DELAYED_WORK(&dev->cal_work, mt76x0_phy_calibrate); + INIT_DELAYED_WORK(&dev->cal_work, mt76x0_phy_calibration_work); mt76x0_rf_init(dev); - mt76x02_phy_set_rxpath(&dev->mt76); - mt76x02_phy_set_txdac(&dev->mt76); + mt76x02_phy_set_rxpath(dev); + mt76x02_phy_set_txdac(dev); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c index fb6fa1fa5548..a9f14d5149d1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c @@ -40,8 +40,7 @@ mt76x0u_upload_firmware(struct mt76x02_dev *dev, ilm_len = le32_to_cpu(hdr->ilm_len) - MT_MCU_IVB_SIZE; dev_dbg(dev->mt76.dev, "loading FW - ILM %u + IVB %u\n", ilm_len, MT_MCU_IVB_SIZE); - err = mt76x02u_mcu_fw_send_data(&dev->mt76, - fw_payload + MT_MCU_IVB_SIZE, + err = mt76x02u_mcu_fw_send_data(dev, fw_payload + MT_MCU_IVB_SIZE, ilm_len, MCU_FW_URB_MAX_PAYLOAD, MT_MCU_IVB_SIZE); if (err) @@ -49,7 +48,7 @@ mt76x0u_upload_firmware(struct mt76x02_dev *dev, dlm_len = le32_to_cpu(hdr->dlm_len); dev_dbg(dev->mt76.dev, "loading FW - DLM %u\n", dlm_len); - err = mt76x02u_mcu_fw_send_data(&dev->mt76, + err = mt76x02u_mcu_fw_send_data(dev, fw_payload + le32_to_cpu(hdr->ilm_len), dlm_len, MCU_FW_URB_MAX_PAYLOAD, MT_MCU_DLM_OFFSET); @@ -121,7 +120,7 @@ static int mt76x0u_load_firmware(struct mt76x02_dev *dev) mt76_set(dev, MT_USB_DMA_CFG, (MT_USB_DMA_CFG_RX_BULK_EN | MT_USB_DMA_CFG_TX_BULK_EN) | FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20)); - mt76x02u_mcu_fw_reset(&dev->mt76); + mt76x02u_mcu_fw_reset(dev); usleep_range(5000, 6000); /* mt76x0_rmw(dev, MT_PBF_CFG, 0, (MT_PBF_CFG_TX0Q_EN | |