diff options
author | Kalle Valo <kvalo@kernel.org> | 2023-08-02 12:36:37 +0300 |
---|---|---|
committer | Kalle Valo <kvalo@kernel.org> | 2023-08-02 12:36:37 +0300 |
commit | 111d5c4797c0f0314de8ef68b50259798ef3a127 (patch) | |
tree | c6a34d5876df16e1f23e993e8788f992314baf81 | |
parent | f5343efdf5b5d66844ce041e5dcd585ee5697747 (diff) | |
parent | 6c0570bc21ec2073890aa252c8420ca7bec402e4 (diff) | |
download | linux-111d5c4797c0f0314de8ef68b50259798ef3a127.tar.xz |
Merge tag 'mt76-for-kvalo-2023-07-31' of https://github.com/nbd168/wireless
mt76 patches for 6.6
* fixes
* preparation for mt7925 support
* mt7981 support
84 files changed, 5752 insertions, 4827 deletions
diff --git a/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml b/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml index 67b63f119f64..252207adbc54 100644 --- a/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml +++ b/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml @@ -28,6 +28,7 @@ properties: - mediatek,mt76 - mediatek,mt7628-wmac - mediatek,mt7622-wmac + - mediatek,mt7981-wmac - mediatek,mt7986-wmac reg: @@ -71,6 +72,14 @@ properties: ieee80211-freq-limit: true + nvmem-cells: + items: + - description: NVMEM cell with EEPROM + + nvmem-cell-names: + items: + - const: eeprom + mediatek,eeprom-data: $ref: /schemas/types.yaml#/definitions/uint32-array description: @@ -84,6 +93,7 @@ properties: - description: offset containing EEPROM data description: Phandle to a MTD partition + offset containing EEPROM data + deprecated: true big-endian: $ref: /schemas/types.yaml#/definitions/flag @@ -258,7 +268,8 @@ examples: interrupt-parent = <&cpuintc>; interrupts = <6>; - mediatek,mtd-eeprom = <&factory 0x0>; + nvmem-cells = <&eeprom>; + nvmem-cell-names = "eeprom"; }; - | diff --git a/drivers/net/wireless/mediatek/mt76/Kconfig b/drivers/net/wireless/mediatek/mt76/Kconfig index 18152c16c36f..7eb1b0b63d11 100644 --- a/drivers/net/wireless/mediatek/mt76/Kconfig +++ b/drivers/net/wireless/mediatek/mt76/Kconfig @@ -29,6 +29,14 @@ config MT76_CONNAC_LIB tristate select MT76_CORE +config MT792x_LIB + tristate + select MT76_CONNAC_LIB + +config MT792x_USB + tristate + select MT76_USB + source "drivers/net/wireless/mediatek/mt76/mt76x0/Kconfig" source "drivers/net/wireless/mediatek/mt76/mt76x2/Kconfig" source "drivers/net/wireless/mediatek/mt76/mt7603/Kconfig" diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile index 84c99b7e57f9..85c4799be954 100644 --- a/drivers/net/wireless/mediatek/mt76/Makefile +++ b/drivers/net/wireless/mediatek/mt76/Makefile @@ -5,6 +5,8 @@ obj-$(CONFIG_MT76_SDIO) += mt76-sdio.o obj-$(CONFIG_MT76x02_LIB) += mt76x02-lib.o obj-$(CONFIG_MT76x02_USB) += mt76x02-usb.o obj-$(CONFIG_MT76_CONNAC_LIB) += mt76-connac-lib.o +obj-$(CONFIG_MT792x_LIB) += mt792x-lib.o +obj-$(CONFIG_MT792x_USB) += mt792x-usb.o mt76-y := \ mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o \ @@ -19,6 +21,7 @@ mt76-sdio-y := sdio.o sdio_txrx.o CFLAGS_trace.o := -I$(src) CFLAGS_usb_trace.o := -I$(src) CFLAGS_mt76x02_trace.o := -I$(src) +CFLAGS_mt792x_trace.o := -I$(src) mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \ mt76x02_eeprom.o mt76x02_phy.o mt76x02_mmio.o \ @@ -27,7 +30,12 @@ mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \ mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o -mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o +mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o mt76_connac3_mac.o + +mt792x-lib-y := mt792x_core.o mt792x_mac.o mt792x_trace.o \ + mt792x_debugfs.o mt792x_dma.o +mt792x-lib-$(CONFIG_ACPI) += mt792x_acpi_sar.o +mt792x-usb-y := mt792x_usb.o obj-$(CONFIG_MT76x0_COMMON) += mt76x0/ obj-$(CONFIG_MT76x2_COMMON) += mt76x2/ diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index 465190ebaf1c..05d9ab3ce819 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -466,6 +466,9 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q, struct mt76_queue_buf buf = {}; dma_addr_t addr; + if (test_bit(MT76_MCU_RESET, &dev->phy.state)) + goto error; + if (q->queued + 1 >= q->ndesc - 1) goto error; @@ -507,6 +510,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q, dma_addr_t addr; u8 *txwi; + if (test_bit(MT76_RESET, &dev->phy.state)) + goto free_skb; + t = mt76_get_txwi(dev); if (!t) goto free_skb; diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c index dce851d42e08..36564930aef1 100644 --- a/drivers/net/wireless/mediatek/mt76/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c @@ -6,34 +6,39 @@ #include <linux/of_net.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> +#include <linux/nvmem-consumer.h> #include <linux/etherdevice.h> #include "mt76.h" -int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len) +static int mt76_get_of_eeprom_data(struct mt76_dev *dev, void *eep, int len) { -#if defined(CONFIG_OF) && defined(CONFIG_MTD) struct device_node *np = dev->dev->of_node; - struct mtd_info *mtd; - const __be32 *list; const void *data; - const char *part; - phandle phandle; int size; - size_t retlen; - int ret; - if (!np) + data = of_get_property(np, "mediatek,eeprom-data", &size); + if (!data) return -ENOENT; - data = of_get_property(np, "mediatek,eeprom-data", &size); - if (data) { - if (size > len) - return -EINVAL; + if (size > len) + return -EINVAL; - memcpy(eep, data, size); + memcpy(eep, data, size); - return 0; - } + return 0; +} + +static int mt76_get_of_epprom_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len) +{ +#ifdef CONFIG_MTD + struct device_node *np = dev->dev->of_node; + struct mtd_info *mtd; + const __be32 *list; + const char *part; + phandle phandle; + size_t retlen; + int size; + int ret; list = of_get_property(np, "mediatek,mtd-eeprom", &size); if (!list) @@ -100,6 +105,56 @@ out_put_node: return -ENOENT; #endif } + +static int mt76_get_of_epprom_from_nvmem(struct mt76_dev *dev, void *eep, int len) +{ + struct device_node *np = dev->dev->of_node; + struct nvmem_cell *cell; + const void *data; + size_t retlen; + int ret = 0; + + cell = of_nvmem_cell_get(np, "eeprom"); + if (IS_ERR(cell)) + return PTR_ERR(cell); + + data = nvmem_cell_read(cell, &retlen); + nvmem_cell_put(cell); + + if (IS_ERR(data)) + return PTR_ERR(data); + + if (retlen < len) { + ret = -EINVAL; + goto exit; + } + + memcpy(eep, data, len); + +exit: + kfree(data); + + return ret; +} + +int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len) +{ + struct device_node *np = dev->dev->of_node; + int ret; + + if (!np) + return -ENOENT; + + ret = mt76_get_of_eeprom_data(dev, eep, len); + if (!ret) + return 0; + + ret = mt76_get_of_epprom_from_mtd(dev, eep, offset, len); + if (!ret) + return 0; + + return mt76_get_of_epprom_from_nvmem(dev, eep, len); +} EXPORT_SYMBOL_GPL(mt76_get_of_eeprom); void diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 467afef98ba2..c0ff36a98bed 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -76,6 +76,7 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = { CHAN5G(165, 5825), CHAN5G(169, 5845), CHAN5G(173, 5865), + CHAN5G(177, 5885), }; static const struct ieee80211_channel mt76_channels_6ghz[] = { @@ -660,6 +661,8 @@ mt76_alloc_device(struct device *pdev, unsigned int size, idr_init(&dev->rx_token); INIT_LIST_HEAD(&dev->wcid_list); + INIT_LIST_HEAD(&dev->sta_poll_list); + spin_lock_init(&dev->sta_poll_lock); INIT_LIST_HEAD(&dev->txwi_cache); INIT_LIST_HEAD(&dev->rxwi_cache); @@ -1743,6 +1746,9 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi, for (i = 0; i < (eht ? 14 : 12); i++) data[ei++] += stats->tx_mcs[i]; + for (i = 0; i < 4; i++) + data[ei++] += stats->tx_nss[i]; + wi->worker_stat_count = ei - wi->initial_stat_idx; } EXPORT_SYMBOL_GPL(mt76_ethtool_worker); diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 6b07b8fafec2..878087257ea7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -277,7 +277,7 @@ struct mt76_sta_stats { u64 tx_mcs[16]; /* mcs idx */ u64 tx_bytes; /* WED TX */ - u32 tx_packets; + u32 tx_packets; /* unit: MSDU */ u32 tx_retries; u32 tx_failed; /* WED RX */ @@ -316,6 +316,7 @@ struct mt76_wcid { int inactive_count; struct rate_info rate; + unsigned long ampdu_state; u16 idx; u8 hw_key_idx; @@ -336,6 +337,8 @@ struct mt76_wcid { struct idr pktid; struct mt76_sta_stats stats; + + struct list_head poll_list; }; struct mt76_txq { @@ -702,6 +705,9 @@ struct mt76_vif { u8 wmm_idx; u8 scan_seq_num; u8 cipher; + u8 basic_rates_idx; + u8 mcast_rates_idx; + u8 beacon_rates_idx; }; struct mt76_phy { @@ -823,6 +829,9 @@ struct mt76_dev { struct mt76_wcid __rcu *wcid[MT76_N_WCIDS]; struct list_head wcid_list; + struct list_head sta_poll_list; + spinlock_t sta_poll_lock; + u32 rev; struct tasklet_struct pre_tbtt_tasklet; @@ -857,6 +866,101 @@ struct mt76_dev { }; }; +/* per-phy stats. */ +struct mt76_mib_stats { + u32 ack_fail_cnt; + u32 fcs_err_cnt; + u32 rts_cnt; + u32 rts_retries_cnt; + u32 ba_miss_cnt; + u32 tx_bf_cnt; + u32 tx_mu_bf_cnt; + u32 tx_mu_mpdu_cnt; + u32 tx_mu_acked_mpdu_cnt; + u32 tx_su_acked_mpdu_cnt; + u32 tx_bf_ibf_ppdu_cnt; + u32 tx_bf_ebf_ppdu_cnt; + + u32 tx_bf_rx_fb_all_cnt; + u32 tx_bf_rx_fb_eht_cnt; + u32 tx_bf_rx_fb_he_cnt; + u32 tx_bf_rx_fb_vht_cnt; + u32 tx_bf_rx_fb_ht_cnt; + + u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */ + u32 tx_bf_rx_fb_nc_cnt; + u32 tx_bf_rx_fb_nr_cnt; + u32 tx_bf_fb_cpl_cnt; + u32 tx_bf_fb_trig_cnt; + + u32 tx_ampdu_cnt; + u32 tx_stop_q_empty_cnt; + u32 tx_mpdu_attempts_cnt; + u32 tx_mpdu_success_cnt; + u32 tx_pkt_ebf_cnt; + u32 tx_pkt_ibf_cnt; + + u32 tx_rwp_fail_cnt; + u32 tx_rwp_need_cnt; + + /* rx stats */ + u32 rx_fifo_full_cnt; + u32 channel_idle_cnt; + u32 primary_cca_busy_time; + u32 secondary_cca_busy_time; + u32 primary_energy_detect_time; + u32 cck_mdrdy_time; + u32 ofdm_mdrdy_time; + u32 green_mdrdy_time; + u32 rx_vector_mismatch_cnt; + u32 rx_delimiter_fail_cnt; + u32 rx_mrdy_cnt; + u32 rx_len_mismatch_cnt; + u32 rx_mpdu_cnt; + u32 rx_ampdu_cnt; + u32 rx_ampdu_bytes_cnt; + u32 rx_ampdu_valid_subframe_cnt; + u32 rx_ampdu_valid_subframe_bytes_cnt; + u32 rx_pfdrop_cnt; + u32 rx_vec_queue_overflow_drop_cnt; + u32 rx_ba_cnt; + + u32 tx_amsdu[8]; + u32 tx_amsdu_cnt; + + /* mcu_muru_stats */ + u32 dl_cck_cnt; + u32 dl_ofdm_cnt; + u32 dl_htmix_cnt; + u32 dl_htgf_cnt; + u32 dl_vht_su_cnt; + u32 dl_vht_2mu_cnt; + u32 dl_vht_3mu_cnt; + u32 dl_vht_4mu_cnt; + u32 dl_he_su_cnt; + u32 dl_he_ext_su_cnt; + u32 dl_he_2ru_cnt; + u32 dl_he_2mu_cnt; + u32 dl_he_3ru_cnt; + u32 dl_he_3mu_cnt; + u32 dl_he_4ru_cnt; + u32 dl_he_4mu_cnt; + u32 dl_he_5to8ru_cnt; + u32 dl_he_9to16ru_cnt; + u32 dl_he_gtr16ru_cnt; + + u32 ul_hetrig_su_cnt; + u32 ul_hetrig_2ru_cnt; + u32 ul_hetrig_3ru_cnt; + u32 ul_hetrig_4ru_cnt; + u32 ul_hetrig_5to8ru_cnt; + u32 ul_hetrig_9to16ru_cnt; + u32 ul_hetrig_gtr16ru_cnt; + u32 ul_hetrig_2mu_cnt; + u32 ul_hetrig_3mu_cnt; + u32 ul_hetrig_4mu_cnt; +}; + struct mt76_power_limits { s8 cck[4]; s8 ofdm[8]; diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c index b65b0a88c1de..888678732f29 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c @@ -161,7 +161,8 @@ void mt7603_beacon_set_timer(struct mt7603_dev *dev, int idx, int intval) return; } - dev->mt76.beacon_int = intval; + if (intval) + dev->mt76.beacon_int = intval; mt76_wr(dev, MT_TBTT, FIELD_PREP(MT_TBTT_PERIOD, intval) | MT_TBTT_CAL_ENABLE); diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/init.c b/drivers/net/wireless/mediatek/mt76/mt7603/init.c index 9a2e632d577a..0762de3ce5ac 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/init.c @@ -500,8 +500,6 @@ int mt7603_register_device(struct mt7603_dev *dev) bus_ops->rmw = mt7603_rmw; dev->mt76.bus = bus_ops; - INIT_LIST_HEAD(&dev->sta_poll_list); - spin_lock_init(&dev->sta_poll_lock); spin_lock_init(&dev->ps_lock); INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7603_mac_work); diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c index 12e0af52082a..99ae080502d8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c @@ -178,8 +178,9 @@ mt7603_wtbl_set_skip_tx(struct mt7603_dev *dev, int idx, bool enabled) mt76_wr(dev, addr + 3 * 4, val); } -void mt7603_filter_tx(struct mt7603_dev *dev, int idx, bool abort) +void mt7603_filter_tx(struct mt7603_dev *dev, int mac_idx, int idx, bool abort) { + u32 flush_mask; int i, port, queue; if (abort) { @@ -195,6 +196,18 @@ void mt7603_filter_tx(struct mt7603_dev *dev, int idx, bool abort) mt76_wr(dev, MT_TX_ABORT, MT_TX_ABORT_EN | FIELD_PREP(MT_TX_ABORT_WCID, idx)); + flush_mask = MT_WF_ARB_TX_FLUSH_AC0 | + MT_WF_ARB_TX_FLUSH_AC1 | + MT_WF_ARB_TX_FLUSH_AC2 | + MT_WF_ARB_TX_FLUSH_AC3; + flush_mask <<= mac_idx; + + mt76_wr(dev, MT_WF_ARB_TX_FLUSH_0, flush_mask); + mt76_poll(dev, MT_WF_ARB_TX_FLUSH_0, flush_mask, 0, 20000); + mt76_wr(dev, MT_WF_ARB_TX_START_0, flush_mask); + + mt76_wr(dev, MT_TX_ABORT, 0); + for (i = 0; i < 4; i++) { mt76_wr(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY | FIELD_PREP(MT_DMA_FQCR0_TARGET_WCID, idx) | @@ -202,13 +215,11 @@ void mt7603_filter_tx(struct mt7603_dev *dev, int idx, bool abort) FIELD_PREP(MT_DMA_FQCR0_DEST_PORT_ID, port) | FIELD_PREP(MT_DMA_FQCR0_DEST_QUEUE_ID, queue)); - mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 15000); + mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000); } WARN_ON_ONCE(mt76_rr(dev, MT_DMA_FQCR0) & MT_DMA_FQCR0_BUSY); - mt76_wr(dev, MT_TX_ABORT, 0); - mt7603_wtbl_set_skip_tx(dev, idx, false); } @@ -245,7 +256,7 @@ void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta, mt76_poll(dev, MT_PSE_RTA, MT_PSE_RTA_BUSY, 0, 5000); if (enabled) - mt7603_filter_tx(dev, idx, false); + mt7603_filter_tx(dev, sta->vif->idx, idx, false); addr = mt7603_wtbl1_addr(idx); mt76_set(dev, MT_WTBL1_OR, MT_WTBL1_OR_PSM_WRITE); @@ -412,16 +423,16 @@ void mt7603_mac_sta_poll(struct mt7603_dev *dev) while (1) { bool clear = false; - spin_lock_bh(&dev->sta_poll_lock); - if (list_empty(&dev->sta_poll_list)) { - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (list_empty(&dev->mt76.sta_poll_list)) { + spin_unlock_bh(&dev->mt76.sta_poll_lock); break; } - msta = list_first_entry(&dev->sta_poll_list, struct mt7603_sta, - poll_list); - list_del_init(&msta->poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + msta = list_first_entry(&dev->mt76.sta_poll_list, + struct mt7603_sta, wcid.poll_list); + list_del_init(&msta->wcid.poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); addr = mt7603_wtbl4_addr(msta->wcid.idx); for (i = 0; i < 4; i++) { @@ -1267,10 +1278,10 @@ void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data) msta = container_of(wcid, struct mt7603_sta, wcid); sta = wcid_to_sta(wcid); - if (list_empty(&msta->poll_list)) { - spin_lock_bh(&dev->sta_poll_lock); - list_add_tail(&msta->poll_list, &dev->sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + if (list_empty(&msta->wcid.poll_list)) { + spin_lock_bh(&dev->mt76.sta_poll_lock); + list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); } if (mt7603_mac_add_txs_skb(dev, msta, pid, txs_data)) diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c index 1b1358c6bb46..c213fd2a5216 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c @@ -66,9 +66,10 @@ mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) idx = MT7603_WTBL_RESERVED - 1 - mvif->idx; dev->mt76.vif_mask |= BIT_ULL(mvif->idx); - INIT_LIST_HEAD(&mvif->sta.poll_list); + INIT_LIST_HEAD(&mvif->sta.wcid.poll_list); mvif->sta.wcid.idx = idx; mvif->sta.wcid.hw_key_idx = -1; + mvif->sta.vif = mvif; mt76_packet_id_init(&mvif->sta.wcid); eth_broadcast_addr(bc_addr); @@ -100,10 +101,10 @@ mt7603_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) rcu_assign_pointer(dev->mt76.wcid[idx], NULL); - spin_lock_bh(&dev->sta_poll_lock); - if (!list_empty(&msta->poll_list)) - list_del_init(&msta->poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (!list_empty(&msta->wcid.poll_list)) + list_del_init(&msta->wcid.poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); mutex_lock(&dev->mt76.mutex); dev->mt76.vif_mask &= ~BIT_ULL(mvif->idx); @@ -351,12 +352,13 @@ mt7603_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, if (idx < 0) return -ENOSPC; - INIT_LIST_HEAD(&msta->poll_list); + INIT_LIST_HEAD(&msta->wcid.poll_list); __skb_queue_head_init(&msta->psq); msta->ps = ~0; msta->smps = ~0; msta->wcid.sta = 1; msta->wcid.idx = idx; + msta->vif = mvif; mt7603_wtbl_init(dev, idx, mvif->idx, sta->addr); mt7603_wtbl_set_ps(dev, msta, false); @@ -380,18 +382,19 @@ mt7603_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76); + struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv; struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv; struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv; spin_lock_bh(&dev->ps_lock); __skb_queue_purge(&msta->psq); - mt7603_filter_tx(dev, wcid->idx, true); + mt7603_filter_tx(dev, mvif->idx, wcid->idx, true); spin_unlock_bh(&dev->ps_lock); - spin_lock_bh(&dev->sta_poll_lock); - if (!list_empty(&msta->poll_list)) - list_del_init(&msta->poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&mdev->sta_poll_lock); + if (!list_empty(&msta->wcid.poll_list)) + list_del_init(&msta->wcid.poll_list); + spin_unlock_bh(&mdev->sta_poll_lock); mt7603_wtbl_clear(dev, wcid->idx); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h index 7c3be596da09..9e58df7042ad 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h +++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h @@ -64,7 +64,6 @@ struct mt7603_sta { struct mt7603_vif *vif; - struct list_head poll_list; u32 tx_airtime_ac[4]; struct sk_buff_head psq; @@ -110,9 +109,6 @@ struct mt7603_dev { u32 rxfilter; - struct list_head sta_poll_list; - spinlock_t sta_poll_lock; - struct mt7603_sta global_sta; u32 agc0, agc3; @@ -234,7 +230,7 @@ void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta, bool enabled); void mt7603_wtbl_set_smps(struct mt7603_dev *dev, struct mt7603_sta *sta, bool enabled); -void mt7603_filter_tx(struct mt7603_dev *dev, int idx, bool abort); +void mt7603_filter_tx(struct mt7603_dev *dev, int mac_idx, int idx, bool abort); int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, enum mt76_txq_id qid, struct mt76_wcid *wcid, diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/regs.h b/drivers/net/wireless/mediatek/mt76/mt7603/regs.h index 3b901090b29c..a39c9a0fcb1c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7603/regs.h @@ -309,6 +309,13 @@ enum { #define MT_WF_ARB_TX_STOP_0 MT_WF_ARB(0x110) #define MT_WF_ARB_TX_STOP_1 MT_WF_ARB(0x114) +#define MT_WF_ARB_TX_FLUSH_AC0 BIT(0) +#define MT_WF_ARB_TX_FLUSH_AC1 BIT(5) +#define MT_WF_ARB_TX_FLUSH_AC2 BIT(10) +#define MT_WF_ARB_TX_FLUSH_AC3 BIT(16) +#define MT_WF_ARB_TX_FLUSH_AC4 BIT(21) +#define MT_WF_ARB_TX_FLUSH_AC5 BIT(26) + #define MT_WF_ARB_BCN_START MT_WF_ARB(0x118) #define MT_WF_ARB_BCN_START_BSSn(n) BIT(0 + (n)) #define MT_WF_ARB_BCN_START_T_PRE_TTTT BIT(10) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c index 621e69f07e3c..18a50ccff106 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c @@ -397,6 +397,8 @@ mt7615_init_wiphy(struct ieee80211_hw *hw) wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL); wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS); wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); + if (!is_mt7622(&phy->dev->mt76)) + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER); ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN); @@ -626,8 +628,6 @@ void mt7615_init_device(struct mt7615_dev *dev) INIT_DELAYED_WORK(&dev->coredump.work, mt7615_coredump_work); skb_queue_head_init(&dev->phy.scan_event_list); skb_queue_head_init(&dev->coredump.msg_list); - INIT_LIST_HEAD(&dev->sta_poll_list); - spin_lock_init(&dev->sta_poll_lock); init_waitqueue_head(&dev->reset_wait); init_waitqueue_head(&dev->phy.roc_wait); diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c index 64002484ccad..7ba789834e8d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c @@ -387,10 +387,11 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb) struct mt7615_sta *msta; msta = container_of(status->wcid, struct mt7615_sta, wcid); - spin_lock_bh(&dev->sta_poll_lock); - if (list_empty(&msta->poll_list)) - list_add_tail(&msta->poll_list, &dev->sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (list_empty(&msta->wcid.poll_list)) + list_add_tail(&msta->wcid.poll_list, + &dev->mt76.sta_poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); } if (mt76_is_mmio(&dev->mt76) && (rxd0 & csum_mask) == csum_mask && @@ -905,19 +906,19 @@ void mt7615_mac_sta_poll(struct mt7615_dev *dev) int i; INIT_LIST_HEAD(&sta_poll_list); - spin_lock_bh(&dev->sta_poll_lock); - list_splice_init(&dev->sta_poll_list, &sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); while (!list_empty(&sta_poll_list)) { bool clear = false; msta = list_first_entry(&sta_poll_list, struct mt7615_sta, - poll_list); + wcid.poll_list); - spin_lock_bh(&dev->sta_poll_lock); - list_del_init(&msta->poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + list_del_init(&msta->wcid.poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); addr = mt7615_mac_wtbl_addr(dev, msta->wcid.idx) + 19 * 4; @@ -1514,10 +1515,10 @@ static void mt7615_mac_add_txs(struct mt7615_dev *dev, void *data) msta = container_of(wcid, struct mt7615_sta, wcid); sta = wcid_to_sta(wcid); - spin_lock_bh(&dev->sta_poll_lock); - if (list_empty(&msta->poll_list)) - list_add_tail(&msta->poll_list, &dev->sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (list_empty(&msta->wcid.poll_list)) + list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); if (mt7615_mac_add_txs_skb(dev, msta, pid, txs_data)) goto out; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index dadb13f2ca09..200b1752ca77 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -222,7 +222,7 @@ static int mt7615_add_interface(struct ieee80211_hw *hw, idx = MT7615_WTBL_RESERVED - mvif->mt76.idx; - INIT_LIST_HEAD(&mvif->sta.poll_list); + INIT_LIST_HEAD(&mvif->sta.wcid.poll_list); mvif->sta.wcid.idx = idx; mvif->sta.wcid.phy_idx = mvif->mt76.band_idx; mvif->sta.wcid.hw_key_idx = -1; @@ -274,10 +274,10 @@ static void mt7615_remove_interface(struct ieee80211_hw *hw, mt7615_mutex_release(dev); - spin_lock_bh(&dev->sta_poll_lock); - if (!list_empty(&msta->poll_list)) - list_del_init(&msta->poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (!list_empty(&msta->wcid.poll_list)) + list_del_init(&msta->wcid.poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); mt76_packet_id_flush(&dev->mt76, &mvif->sta.wcid); } @@ -552,6 +552,32 @@ static void mt7615_configure_filter(struct ieee80211_hw *hw, mt7615_mutex_release(dev); } +static void +mt7615_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info) +{ + struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv; + struct mt7615_dev *dev = mt7615_hw_dev(hw); + u8 i, band = mvif->mt76.band_idx; + u32 *mu; + + mu = (u32 *)info->mu_group.membership; + for (i = 0; i < WLAN_MEMBERSHIP_LEN / sizeof(*mu); i++) { + if (is_mt7663(&dev->mt76)) + mt76_wr(dev, MT7663_WF_PHY_GID_TAB_VLD(band, i), mu[i]); + else + mt76_wr(dev, MT_WF_PHY_GID_TAB_VLD(band, i), mu[i]); + } + + mu = (u32 *)info->mu_group.position; + for (i = 0; i < WLAN_USER_POSITION_LEN / sizeof(*mu); i++) { + if (is_mt7663(&dev->mt76)) + mt76_wr(dev, MT7663_WF_PHY_GID_TAB_POS(band, i), mu[i]); + else + mt76_wr(dev, MT_WF_PHY_GID_TAB_POS(band, i), mu[i]); + } +} + static void mt7615_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, @@ -600,6 +626,9 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ASSOC) mt7615_mac_set_beacon_filter(phy, vif, vif->cfg.assoc); + if (changed & BSS_CHANGED_MU_GROUPS) + mt7615_update_mu_group(hw, vif, info); + mt7615_mutex_release(dev); } @@ -628,7 +657,7 @@ int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, if (idx < 0) return -ENOSPC; - INIT_LIST_HEAD(&msta->poll_list); + INIT_LIST_HEAD(&msta->wcid.poll_list); msta->vif = mvif; msta->wcid.sta = 1; msta->wcid.idx = idx; @@ -676,10 +705,10 @@ void mt7615_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) mt7615_mcu_add_bss_info(phy, vif, sta, false); - spin_lock_bh(&dev->sta_poll_lock); - if (!list_empty(&msta->poll_list)) - list_del_init(&msta->poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&mdev->sta_poll_lock); + if (!list_empty(&msta->wcid.poll_list)) + list_del_init(&msta->wcid.poll_list); + spin_unlock_bh(&mdev->sta_poll_lock); mt76_connac_power_save_sched(phy->mt76, &dev->pm); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h index 582d1b5b7cb3..a20322aae967 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h @@ -125,7 +125,6 @@ struct mt7615_sta { struct mt7615_vif *vif; - struct list_head poll_list; u32 airtime_ac[8]; struct ieee80211_tx_rate rates[4]; @@ -262,9 +261,6 @@ struct mt7615_dev { wait_queue_head_t reset_wait; u32 reset_state; - struct list_head sta_poll_list; - spinlock_t sta_poll_lock; - struct { u8 n_pulses; u32 period; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/regs.h b/drivers/net/wireless/mediatek/mt76/mt7615/regs.h index 7cecb22c569e..806b3887c541 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/regs.h @@ -212,6 +212,15 @@ enum mt7615_reg_base { #define MT7663_WF_PHY_R0_PHYCTRL_STS5(_phy) MT_WF_PHY(0x0224 + ((_phy) << 12)) +#define MT_WF_PHY_GID_TAB_VLD(_phy, i) MT_WF_PHY(0x0254 + (i) * 4 + \ + ((_phy) << 9)) +#define MT7663_WF_PHY_GID_TAB_VLD(_phy, i) MT_WF_PHY(0x0254 + (i) * 4 + \ + ((_phy) << 12)) +#define MT_WF_PHY_GID_TAB_POS(_phy, i) MT_WF_PHY(0x025c + (i) * 4 + \ + ((_phy) << 9)) +#define MT7663_WF_PHY_GID_TAB_POS(_phy, i) MT_WF_PHY(0x025c + (i) * 4 + \ + ((_phy) << 12)) + #define MT_WF_PHY_MIN_PRI_PWR(_phy) MT_WF_PHY((_phy) ? 0x084 : 0x229c) #define MT_WF_PHY_PD_OFDM_MASK(_phy) ((_phy) ? GENMASK(24, 16) : \ GENMASK(28, 20)) diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h index 15653b274f83..22878f088804 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h @@ -197,11 +197,21 @@ static inline bool is_mt7916(struct mt76_dev *dev) return mt76_chip(dev) == 0x7906; } +static inline bool is_mt7981(struct mt76_dev *dev) +{ + return mt76_chip(dev) == 0x7981; +} + static inline bool is_mt7986(struct mt76_dev *dev) { return mt76_chip(dev) == 0x7986; } +static inline bool is_mt798x(struct mt76_dev *dev) +{ + return is_mt7981(dev) || is_mt7986(dev); +} + static inline bool is_mt7996(struct mt76_dev *dev) { return mt76_chip(dev) == 0x7990; @@ -409,5 +419,13 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev, struct mt76_rx_status *status, struct ieee80211_supported_band *sband, __le32 *rxv, u8 *mode); - +void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi); +void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t, + struct ieee80211_sta *sta, + struct list_head *free_list); +void mt76_connac2_tx_token_put(struct mt76_dev *dev); + +/* connac3 */ +void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, + u8 mode); #endif /* __MT76_CONNAC_H */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac2_mac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac2_mac.h index fabf637bdf7f..bd2a92467a97 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac2_mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac2_mac.h @@ -34,7 +34,7 @@ enum { #define MT_TX_FREE_MSDU_CNT GENMASK(9, 0) #define MT_TX_FREE_WLAN_ID GENMASK(23, 14) -#define MT_TX_FREE_LATENCY GENMASK(12, 0) +#define MT_TX_FREE_COUNT GENMASK(12, 0) /* 0: success, others: dropped */ #define MT_TX_FREE_STATUS GENMASK(14, 13) #define MT_TX_FREE_MSDU_ID GENMASK(30, 16) diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file mode 100644 index 000000000000..73e9f283d0ae --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2023 MediaTek Inc. */ + +#include "mt76_connac.h" +#include "mt76_connac3_mac.h" +#include "dma.h" + +#define HE_BITS(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_##f) +#define HE_PREP(f, m, v) le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\ + IEEE80211_RADIOTAP_HE_##f) + +static void +mt76_connac3_mac_decode_he_radiotap_ru(struct mt76_rx_status *status, + struct ieee80211_radiotap_he *he, + __le32 *rxv) +{ + u32 ru = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC), offs = 0; + + status->bw = RATE_INFO_BW_HE_RU; + + switch (ru) { + case 0 ... 36: + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26; + offs = ru; + break; + case 37 ... 52: + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52; + offs = ru - 37; + break; + case 53 ... 60: + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; + offs = ru - 53; + break; + case 61 ... 64: + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242; + offs = ru - 61; + break; + case 65 ... 66: + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484; + offs = ru - 65; + break; + case 67: + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996; + break; + case 68: + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; + break; + } + + he->data1 |= HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); + he->data2 |= HE_BITS(DATA2_RU_OFFSET_KNOWN) | + le16_encode_bits(offs, + IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); +} + +#define MU_PREP(f, v) le16_encode_bits(v, IEEE80211_RADIOTAP_HE_MU_##f) +static void +mt76_connac3_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32 *rxv) +{ + struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; + static const struct ieee80211_radiotap_he_mu mu_known = { + .flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) | + HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) | + HE_BITS(MU_FLAGS1_CH1_RU_KNOWN) | + HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN), + .flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN), + }; + struct ieee80211_radiotap_he_mu *he_mu; + + status->flag |= RX_FLAG_RADIOTAP_HE_MU; + + he_mu = skb_push(skb, sizeof(mu_known)); + memcpy(he_mu, &mu_known, sizeof(mu_known)); + + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status->rate_idx); + if (status->he_dcm) + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status->he_dcm); + + he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) | + MU_PREP(FLAGS2_SIG_B_SYMS_USERS, + le32_get_bits(rxv[4], MT_CRXV_HE_NUM_USER)); + + he_mu->ru_ch1[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU0) & 0xff; + + if (status->bw >= RATE_INFO_BW_40) { + he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN); + he_mu->ru_ch2[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU1) & 0xff; + } + + if (status->bw >= RATE_INFO_BW_80) { + u32 ru_h, ru_l; + + he_mu->ru_ch1[1] = le32_get_bits(rxv[16], MT_CRXV_HE_RU2) & 0xff; + + ru_l = le32_get_bits(rxv[16], MT_CRXV_HE_RU3_L); + ru_h = le32_get_bits(rxv[17], MT_CRXV_HE_RU3_H) & 0x7; + he_mu->ru_ch2[1] = (u8)(ru_l | ru_h << 4); + } +} + +void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, + u8 mode) +{ + struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; + static const struct ieee80211_radiotap_he known = { + .data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) | + HE_BITS(DATA1_DATA_DCM_KNOWN) | + HE_BITS(DATA1_STBC_KNOWN) | + HE_BITS(DATA1_CODING_KNOWN) | + HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) | + HE_BITS(DATA1_DOPPLER_KNOWN) | + HE_BITS(DATA1_SPTL_REUSE_KNOWN) | + HE_BITS(DATA1_BSS_COLOR_KNOWN), + .data2 = HE_BITS(DATA2_GI_KNOWN) | + HE_BITS(DATA2_TXBF_KNOWN) | + HE_BITS(DATA2_PE_DISAMBIG_KNOWN) | + HE_BITS(DATA2_TXOP_KNOWN), + }; + u32 ltf_size = le32_get_bits(rxv[4], MT_CRXV_HE_LTF_SIZE) + 1; + struct ieee80211_radiotap_he *he; + + status->flag |= RX_FLAG_RADIOTAP_HE; + + he = skb_push(skb, sizeof(known)); + memcpy(he, &known, sizeof(known)); + + he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[9]) | + HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[4]); + he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[13]); + he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[5]) | + le16_encode_bits(ltf_size, + IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE); + if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF) + he->data5 |= HE_BITS(DATA5_TXBF); + he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[9]) | + HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[9]); + + switch (mode) { + case MT_PHY_TYPE_HE_SU: + he->data1 |= HE_BITS(DATA1_FORMAT_SU) | + HE_BITS(DATA1_UL_DL_KNOWN) | + HE_BITS(DATA1_BEAM_CHANGE_KNOWN) | + HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); + + he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[8]) | + HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]); + break; + case MT_PHY_TYPE_HE_EXT_SU: + he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) | + HE_BITS(DATA1_UL_DL_KNOWN) | + HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); + + he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]); + break; + case MT_PHY_TYPE_HE_MU: + he->data1 |= HE_BITS(DATA1_FORMAT_MU) | + HE_BITS(DATA1_UL_DL_KNOWN); + + he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]); + he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[8]); + + mt76_connac3_mac_decode_he_radiotap_ru(status, he, rxv); + mt76_connac3_mac_decode_he_mu_radiotap(skb, rxv); + break; + case MT_PHY_TYPE_HE_TB: + he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) | + HE_BITS(DATA1_SPTL_REUSE2_KNOWN) | + HE_BITS(DATA1_SPTL_REUSE3_KNOWN) | + HE_BITS(DATA1_SPTL_REUSE4_KNOWN); + + he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, rxv[13]) | + HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, rxv[13]) | + HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, rxv[13]) | + HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, rxv[13]); + + mt76_connac3_mac_decode_he_radiotap_ru(status, he, rxv); + break; + default: + break; + } +} +EXPORT_SYMBOL_GPL(mt76_connac3_mac_decode_he_radiotap); diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h new file mode 100644 index 000000000000..68ca0844cbbf --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h @@ -0,0 +1,339 @@ +/* SPDX-License-Identifier: ISC */ +/* Copyright (C) 2023 MediaTek Inc. */ + +#ifndef __MT76_CONNAC3_MAC_H +#define __MT76_CONNAC3_MAC_H + +enum { + MT_CTX0, + MT_HIF0 = 0x0, + + MT_LMAC_AC00 = 0x0, + MT_LMAC_AC01, + MT_LMAC_AC02, + MT_LMAC_AC03, + MT_LMAC_ALTX0 = 0x10, + MT_LMAC_BMC0, + MT_LMAC_BCN0, + MT_LMAC_PSMP0, +}; + +#define MT_CT_PARSE_LEN 72 +#define MT_CT_DMA_BUF_NUM 2 + +#define MT_RXD0_LENGTH GENMASK(15, 0) +#define MT_RXD0_PKT_FLAG GENMASK(19, 16) +#define MT_RXD0_PKT_TYPE GENMASK(31, 27) + +#define MT_RXD0_MESH BIT(18) +#define MT_RXD0_MHCP BIT(19) +#define MT_RXD0_NORMAL_ETH_TYPE_OFS GENMASK(22, 16) +#define MT_RXD0_NORMAL_IP_SUM BIT(23) +#define MT_RXD0_NORMAL_UDP_TCP_SUM BIT(24) + +#define MT_RXD0_SW_PKT_TYPE_MASK GENMASK(31, 16) +#define MT_RXD0_SW_PKT_TYPE_MAP 0x380F +#define MT_RXD0_SW_PKT_TYPE_FRAME 0x3801 + +/* RXD DW1 */ +#define MT_RXD1_NORMAL_WLAN_IDX GENMASK(11, 0) +#define MT_RXD1_NORMAL_GROUP_1 BIT(16) +#define MT_RXD1_NORMAL_GROUP_2 BIT(17) +#define MT_RXD1_NORMAL_GROUP_3 BIT(18) +#define MT_RXD1_NORMAL_GROUP_4 BIT(19) +#define MT_RXD1_NORMAL_GROUP_5 BIT(20) +#define MT_RXD1_NORMAL_KEY_ID GENMASK(22, 21) +#define MT_RXD1_NORMAL_CM BIT(23) +#define MT_RXD1_NORMAL_CLM BIT(24) +#define MT_RXD1_NORMAL_ICV_ERR BIT(25) +#define MT_RXD1_NORMAL_TKIP_MIC_ERR BIT(26) +#define MT_RXD1_NORMAL_BAND_IDX GENMASK(28, 27) +#define MT_RXD1_NORMAL_SPP_EN BIT(29) +#define MT_RXD1_NORMAL_ADD_OM BIT(30) +#define MT_RXD1_NORMAL_SEC_DONE BIT(31) + +/* RXD DW2 */ +#define MT_RXD2_NORMAL_BSSID GENMASK(5, 0) +#define MT_RXD2_NORMAL_MAC_HDR_LEN GENMASK(12, 8) +#define MT_RXD2_NORMAL_HDR_TRANS BIT(7) +#define MT_RXD2_NORMAL_HDR_OFFSET GENMASK(15, 13) +#define MT_RXD2_NORMAL_SEC_MODE GENMASK(20, 16) +#define MT_RXD2_NORMAL_MU_BAR BIT(21) +#define MT_RXD2_NORMAL_SW_BIT BIT(22) +#define MT_RXD2_NORMAL_AMSDU_ERR BIT(23) +#define MT_RXD2_NORMAL_MAX_LEN_ERROR BIT(24) +#define MT_RXD2_NORMAL_HDR_TRANS_ERROR BIT(25) +#define MT_RXD2_NORMAL_INT_FRAME BIT(26) +#define MT_RXD2_NORMAL_FRAG BIT(27) +#define MT_RXD2_NORMAL_NULL_FRAME BIT(28) +#define MT_RXD2_NORMAL_NDATA BIT(29) +#define MT_RXD2_NORMAL_NON_AMPDU BIT(30) +#define MT_RXD2_NORMAL_BF_REPORT BIT(31) + +/* RXD DW3 */ +#define MT_RXD3_NORMAL_RXV_SEQ GENMASK(7, 0) +#define MT_RXD3_NORMAL_CH_FREQ GENMASK(15, 8) +#define MT_RXD3_NORMAL_ADDR_TYPE GENMASK(17, 16) +#define MT_RXD3_NORMAL_U2M BIT(0) +#define MT_RXD3_NORMAL_HTC_VLD BIT(18) +#define MT_RXD3_NORMAL_BEACON_MC BIT(20) +#define MT_RXD3_NORMAL_BEACON_UC BIT(21) +#define MT_RXD3_NORMAL_CO_ANT BIT(22) +#define MT_RXD3_NORMAL_FCS_ERR BIT(24) +#define MT_RXD3_NORMAL_VLAN2ETH BIT(31) + +/* RXD DW4 */ +#define MT_RXD4_NORMAL_PAYLOAD_FORMAT GENMASK(1, 0) +#define MT_RXD4_FIRST_AMSDU_FRAME GENMASK(1, 0) +#define MT_RXD4_MID_AMSDU_FRAME BIT(1) +#define MT_RXD4_LAST_AMSDU_FRAME BIT(0) + +#define MT_RXV_HDR_BAND_IDX BIT(24) + +/* RXD GROUP4 */ +#define MT_RXD8_FRAME_CONTROL GENMASK(15, 0) + +#define MT_RXD10_SEQ_CTRL GENMASK(15, 0) +#define MT_RXD10_QOS_CTL GENMASK(31, 16) + +#define MT_RXD11_HT_CONTROL GENMASK(31, 0) + +/* P-RXV */ +#define MT_PRXV_TX_RATE GENMASK(6, 0) +#define MT_PRXV_TX_DCM BIT(4) +#define MT_PRXV_TX_ER_SU_106T BIT(5) +#define MT_PRXV_NSTS GENMASK(10, 7) +#define MT_PRXV_TXBF BIT(11) +#define MT_PRXV_HT_AD_CODE BIT(12) +#define MT_PRXV_HE_RU_ALLOC GENMASK(30, 22) +#define MT_PRXV_RCPI3 GENMASK(31, 24) +#define MT_PRXV_RCPI2 GENMASK(23, 16) +#define MT_PRXV_RCPI1 GENMASK(15, 8) +#define MT_PRXV_RCPI0 GENMASK(7, 0) +#define MT_PRXV_HT_SHORT_GI GENMASK(4, 3) +#define MT_PRXV_HT_STBC GENMASK(10, 9) +#define MT_PRXV_TX_MODE GENMASK(14, 11) +#define MT_PRXV_FRAME_MODE GENMASK(2, 0) +#define MT_PRXV_DCM BIT(5) + +/* C-RXV */ +#define MT_CRXV_HE_NUM_USER GENMASK(26, 20) +#define MT_CRXV_HE_LTF_SIZE GENMASK(28, 27) +#define MT_CRXV_HE_LDPC_EXT_SYM BIT(30) + +#define MT_CRXV_HE_PE_DISAMBIG BIT(1) +#define MT_CRXV_HE_UPLINK BIT(2) + +#define MT_CRXV_HE_MU_AID GENMASK(27, 17) +#define MT_CRXV_HE_BEAM_CHNG BIT(29) + +#define MT_CRXV_HE_DOPPLER BIT(0) +#define MT_CRXV_HE_BSS_COLOR GENMASK(15, 10) +#define MT_CRXV_HE_TXOP_DUR GENMASK(19, 17) + +#define MT_CRXV_HE_SR_MASK GENMASK(11, 8) +#define MT_CRXV_HE_SR1_MASK GENMASK(16, 12) +#define MT_CRXV_HE_SR2_MASK GENMASK(20, 17) +#define MT_CRXV_HE_SR3_MASK GENMASK(24, 21) + +#define MT_CRXV_HE_RU0 GENMASK(8, 0) +#define MT_CRXV_HE_RU1 GENMASK(17, 9) +#define MT_CRXV_HE_RU2 GENMASK(26, 18) +#define MT_CRXV_HE_RU3_L GENMASK(31, 27) +#define MT_CRXV_HE_RU3_H GENMASK(3, 0) + +enum tx_header_format { + MT_HDR_FORMAT_802_3, + MT_HDR_FORMAT_CMD, + MT_HDR_FORMAT_802_11, + MT_HDR_FORMAT_802_11_EXT, +}; + +enum tx_pkt_type { + MT_TX_TYPE_CT, + MT_TX_TYPE_SF, + MT_TX_TYPE_CMD, + MT_TX_TYPE_FW, +}; + +enum tx_port_idx { + MT_TX_PORT_IDX_LMAC, + MT_TX_PORT_IDX_MCU +}; + +enum tx_mcu_port_q_idx { + MT_TX_MCU_PORT_RX_Q0 = 0x20, + MT_TX_MCU_PORT_RX_Q1, + MT_TX_MCU_PORT_RX_Q2, + MT_TX_MCU_PORT_RX_Q3, + MT_TX_MCU_PORT_RX_FWDL = 0x3e +}; + +enum tx_mgnt_type { + MT_TX_NORMAL, + MT_TX_TIMING, + MT_TX_ADDBA, +}; + +#define MT_CT_INFO_APPLY_TXD BIT(0) +#define MT_CT_INFO_COPY_HOST_TXD_ALL BIT(1) +#define MT_CT_INFO_MGMT_FRAME BIT(2) +#define MT_CT_INFO_NONE_CIPHER_FRAME BIT(3) +#define MT_CT_INFO_HSR2_TX BIT(4) +#define MT_CT_INFO_FROM_HOST BIT(7) + +#define MT_TXD_SIZE (8 * 4) + +#define MT_TXD0_Q_IDX GENMASK(31, 25) +#define MT_TXD0_PKT_FMT GENMASK(24, 23) +#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16) +#define MT_TXD0_TX_BYTES GENMASK(15, 0) + +#define MT_TXD1_FIXED_RATE BIT(31) +#define MT_TXD1_OWN_MAC GENMASK(30, 25) +#define MT_TXD1_TID GENMASK(24, 21) +#define MT_TXD1_BIP BIT(24) +#define MT_TXD1_ETH_802_3 BIT(20) +#define MT_TXD1_HDR_INFO GENMASK(20, 16) +#define MT_TXD1_HDR_FORMAT GENMASK(15, 14) +#define MT_TXD1_TGID GENMASK(13, 12) +#define MT_TXD1_WLAN_IDX GENMASK(11, 0) + +#define MT_TXD2_POWER_OFFSET GENMASK(31, 26) +#define MT_TXD2_MAX_TX_TIME GENMASK(25, 16) +#define MT_TXD2_FRAG GENMASK(15, 14) +#define MT_TXD2_HTC_VLD BIT(13) +#define MT_TXD2_DURATION BIT(12) +#define MT_TXD2_HDR_PAD GENMASK(11, 10) +#define MT_TXD2_RTS BIT(9) +#define MT_TXD2_OWN_MAC_MAP BIT(8) +#define MT_TXD2_BF_TYPE GENMASK(6, 7) +#define MT_TXD2_FRAME_TYPE GENMASK(5, 4) +#define MT_TXD2_SUB_TYPE GENMASK(3, 0) + +#define MT_TXD3_SN_VALID BIT(31) +#define MT_TXD3_PN_VALID BIT(30) +#define MT_TXD3_SW_POWER_MGMT BIT(29) +#define MT_TXD3_BA_DISABLE BIT(28) +#define MT_TXD3_SEQ GENMASK(27, 16) +#define MT_TXD3_REM_TX_COUNT GENMASK(15, 11) +#define MT_TXD3_TX_COUNT GENMASK(10, 6) +#define MT_TXD3_HW_AMSDU BIT(5) +#define MT_TXD3_BCM BIT(4) +#define MT_TXD3_EEOSP BIT(3) +#define MT_TXD3_EMRD BIT(2) +#define MT_TXD3_PROTECT_FRAME BIT(1) +#define MT_TXD3_NO_ACK BIT(0) + +#define MT_TXD4_PN_LOW GENMASK(31, 0) + +#define MT_TXD5_PN_HIGH GENMASK(31, 16) +#define MT_TXD5_FL BIT(15) +#define MT_TXD5_BYPASS_TBB BIT(14) +#define MT_TXD5_BYPASS_RBB BIT(13) +#define MT_TXD5_BSS_COLOR_ZERO BIT(12) +#define MT_TXD5_TX_STATUS_HOST BIT(10) +#define MT_TXD5_TX_STATUS_MCU BIT(9) +#define MT_TXD5_TX_STATUS_FMT BIT(8) +#define MT_TXD5_PID GENMASK(7, 0) + +#define MT_TXD6_TX_SRC GENMASK(31, 30) +#define MT_TXD6_VTA BIT(28) +#define MT_TXD6_BW GENMASK(25, 22) +#define MT_TXD6_TX_RATE GENMASK(21, 16) +#define MT_TXD6_TIMESTAMP_OFS_EN BIT(15) +#define MT_TXD6_TIMESTAMP_OFS_IDX GENMASK(14, 10) +#define MT_TXD6_MSDU_CNT GENMASK(9, 4) +#define MT_TXD6_DIS_MAT BIT(3) +#define MT_TXD6_DAS BIT(2) +#define MT_TXD6_AMSDU_CAP BIT(1) + +#define MT_TXD7_TXD_LEN GENMASK(31, 30) +#define MT_TXD7_IP_SUM BIT(29) +#define MT_TXD7_DROP_BY_SDO BIT(28) +#define MT_TXD7_MAC_TXD BIT(27) +#define MT_TXD7_CTXD BIT(26) +#define MT_TXD7_CTXD_CNT GENMASK(25, 22) +#define MT_TXD7_UDP_TCP_SUM BIT(15) +#define MT_TXD7_TX_TIME GENMASK(9, 0) + +#define MT_TX_RATE_STBC BIT(14) +#define MT_TX_RATE_NSS GENMASK(13, 10) +#define MT_TX_RATE_MODE GENMASK(9, 6) +#define MT_TX_RATE_SU_EXT_TONE BIT(5) +#define MT_TX_RATE_DCM BIT(4) +/* VHT/HE only use bits 0-3 */ +#define MT_TX_RATE_IDX GENMASK(5, 0) + +#define MT_TXFREE0_PKT_TYPE GENMASK(31, 27) +#define MT_TXFREE0_MSDU_CNT GENMASK(25, 16) +#define MT_TXFREE0_RX_BYTE GENMASK(15, 0) + +#define MT_TXFREE1_VER GENMASK(18, 16) + +#define MT_TXFREE_INFO_PAIR BIT(31) +#define MT_TXFREE_INFO_HEADER BIT(30) +#define MT_TXFREE_INFO_WLAN_ID GENMASK(23, 12) +#define MT_TXFREE_INFO_MSDU_ID GENMASK(14, 0) +#define MT_TXFREE_INFO_COUNT GENMASK(27, 24) +#define MT_TXFREE_INFO_STAT GENMASK(29, 28) + +#define MT_TXS0_BW GENMASK(31, 29) +#define MT_TXS0_TID GENMASK(28, 26) +#define MT_TXS0_AMPDU BIT(25) +#define MT_TXS0_TXS_FORMAT GENMASK(24, 23) +#define MT_TXS0_BA_ERROR BIT(22) +#define MT_TXS0_PS_FLAG BIT(21) +#define MT_TXS0_TXOP_TIMEOUT BIT(20) +#define MT_TXS0_BIP_ERROR BIT(19) + +#define MT_TXS0_QUEUE_TIMEOUT BIT(18) +#define MT_TXS0_RTS_TIMEOUT BIT(17) +#define MT_TXS0_ACK_TIMEOUT BIT(16) +#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16) + +#define MT_TXS0_TX_STATUS_HOST BIT(15) +#define MT_TXS0_TX_STATUS_MCU BIT(14) +#define MT_TXS0_TX_RATE GENMASK(13, 0) + +#define MT_TXS1_SEQNO GENMASK(31, 20) +#define MT_TXS1_RESP_RATE GENMASK(19, 16) +#define MT_TXS1_RXV_SEQNO GENMASK(15, 8) +#define MT_TXS1_TX_POWER_DBM GENMASK(7, 0) + +#define MT_TXS2_BF_STATUS GENMASK(31, 30) +#define MT_TXS2_BAND GENMASK(29, 28) +#define MT_TXS2_WCID GENMASK(27, 16) +#define MT_TXS2_TX_DELAY GENMASK(15, 0) + +#define MT_TXS3_PID GENMASK(31, 24) +#define MT_TXS3_RATE_STBC BIT(7) +#define MT_TXS3_FIXED_RATE BIT(6) +#define MT_TXS3_SRC GENMASK(5, 4) +#define MT_TXS3_SHARED_ANTENNA BIT(3) +#define MT_TXS3_LAST_TX_RATE GENMASK(2, 0) + +#define MT_TXS4_TIMESTAMP GENMASK(31, 0) + +#define MT_TXS5_F0_FINAL_MPDU BIT(31) +#define MT_TXS5_F0_QOS BIT(30) +#define MT_TXS5_F0_TX_COUNT GENMASK(29, 25) +#define MT_TXS5_F0_FRONT_TIME GENMASK(24, 0) +#define MT_TXS5_F1_MPDU_TX_COUNT GENMASK(31, 24) +#define MT_TXS5_F1_MPDU_TX_BYTES GENMASK(23, 0) + +#define MT_TXS6_F0_NOISE_3 GENMASK(31, 24) +#define MT_TXS6_F0_NOISE_2 GENMASK(23, 16) +#define MT_TXS6_F0_NOISE_1 GENMASK(15, 8) +#define MT_TXS6_F0_NOISE_0 GENMASK(7, 0) +#define MT_TXS6_F1_MPDU_FAIL_COUNT GENMASK(31, 24) +#define MT_TXS6_F1_MPDU_FAIL_BYTES GENMASK(23, 0) + +#define MT_TXS7_F0_RCPI_3 GENMASK(31, 24) +#define MT_TXS7_F0_RCPI_2 GENMASK(23, 16) +#define MT_TXS7_F0_RCPI_1 GENMASK(15, 8) +#define MT_TXS7_F0_RCPI_0 GENMASK(7, 0) +#define MT_TXS7_F1_MPDU_RETRY_COUNT GENMASK(31, 24) +#define MT_TXS7_F1_MPDU_RETRY_BYTES GENMASK(23, 0) + +#endif /* __MT76_CONNAC3_MAC_H */ diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c index d39a3cc5e381..ee5177fd6dde 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c @@ -495,6 +495,7 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, BSS_CHANGED_BEACON_ENABLED)); bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | BSS_CHANGED_FILS_DISCOVERY)); + bool amsdu_en = wcid->amsdu; if (vif) { struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; @@ -521,9 +522,9 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, q_idx = wmm_idx * MT76_CONNAC_MAX_WMM_SETS + mt76_connac_lmac_mapping(skb_get_queue_mapping(skb)); - /* counting non-offloading skbs */ - wcid->stats.tx_bytes += skb->len; - wcid->stats.tx_packets++; + /* mt7915 WA only counts WED path */ + if (is_mt7915(dev) && mtk_wed_device_active(&dev->mmio.wed)) + wcid->stats.tx_packets++; } val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) | @@ -554,12 +555,14 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, txwi[4] = 0; val = FIELD_PREP(MT_TXD5_PID, pid); - if (pid >= MT_PACKET_ID_FIRST) + if (pid >= MT_PACKET_ID_FIRST) { val |= MT_TXD5_TX_STATUS_HOST; + amsdu_en = amsdu_en && !is_mt7921(dev); + } txwi[5] = cpu_to_le32(val); txwi[6] = 0; - txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0; + txwi[7] = amsdu_en ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0; if (is_8023) mt76_connac2_mac_write_txwi_8023(txwi, skb, wcid); @@ -606,12 +609,11 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid, txs = le32_to_cpu(txs_data[0]); /* PPDU based reporting */ - if (FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) { + if (mtk_wed_device_active(&dev->mmio.wed) && + FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) { stats->tx_bytes += le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) - le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE); - stats->tx_packets += - le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_CNT); stats->tx_failed += le32_get_bits(txs_data[6], MT_TXS6_MPDU_FAIL_CNT); stats->tx_retries += @@ -729,17 +731,15 @@ bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid, skb = mt76_tx_status_skb_get(dev, wcid, pid, &list); if (skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - bool noacked = !(info->flags & IEEE80211_TX_STAT_ACK); if (!(le32_to_cpu(txs_data[0]) & MT_TXS0_ACK_ERROR_MASK)) info->flags |= IEEE80211_TX_STAT_ACK; info->status.ampdu_len = 1; - info->status.ampdu_ack_len = !noacked; + info->status.ampdu_ack_len = + !!(info->flags & IEEE80211_TX_STAT_ACK); info->status.rates[0].idx = -1; - wcid->stats.tx_failed += noacked; - mt76_connac2_mac_fill_txs(dev, wcid, txs_data); mt76_tx_status_skb_done(dev, skb, &list); } @@ -1112,3 +1112,85 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev, return 0; } EXPORT_SYMBOL_GPL(mt76_connac2_mac_fill_rx_rate); + +void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) +{ + struct mt76_wcid *wcid; + u16 fc, tid; + u32 val; + + if (!sta || + !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he)) + return; + + tid = le32_get_bits(txwi[1], MT_TXD1_TID); + if (tid >= 6) /* skip VO queue */ + return; + + val = le32_to_cpu(txwi[2]); + fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 | + FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4; + if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA))) + return; + + wcid = (struct mt76_wcid *)sta->drv_priv; + if (!test_and_set_bit(tid, &wcid->ampdu_state)) + ieee80211_start_tx_ba_session(sta, tid, 0); +} +EXPORT_SYMBOL_GPL(mt76_connac2_tx_check_aggr); + +void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t, + struct ieee80211_sta *sta, + struct list_head *free_list) +{ + struct mt76_wcid *wcid; + __le32 *txwi; + u16 wcid_idx; + + mt76_connac_txp_skb_unmap(dev, t); + if (!t->skb) + goto out; + + txwi = (__le32 *)mt76_get_txwi_ptr(dev, t); + if (sta) { + wcid = (struct mt76_wcid *)sta->drv_priv; + wcid_idx = wcid->idx; + } else { + wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX); + wcid = rcu_dereference(dev->wcid[wcid_idx]); + + if (wcid && wcid->sta) { + sta = container_of((void *)wcid, struct ieee80211_sta, + drv_priv); + spin_lock_bh(&dev->sta_poll_lock); + if (list_empty(&wcid->poll_list)) + list_add_tail(&wcid->poll_list, + &dev->sta_poll_list); + spin_unlock_bh(&dev->sta_poll_lock); + } + } + + if (sta && likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE))) + mt76_connac2_tx_check_aggr(sta, txwi); + + __mt76_tx_complete_skb(dev, wcid_idx, t->skb, free_list); +out: + t->skb = NULL; + mt76_put_txwi(dev, t); +} +EXPORT_SYMBOL_GPL(mt76_connac2_txwi_free); + +void mt76_connac2_tx_token_put(struct mt76_dev *dev) +{ + struct mt76_txwi_cache *txwi; + int id; + + spin_lock_bh(&dev->token_lock); + idr_for_each_entry(&dev->token, txwi, id) { + mt76_connac2_txwi_free(dev, txwi, NULL, NULL); + dev->token_count--; + } + spin_unlock_bh(&dev->token_lock); + idr_destroy(&dev->token); +} +EXPORT_SYMBOL_GPL(mt76_connac2_tx_token_put); diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h index ca1ce97a6d2f..4543e5bf0482 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h @@ -22,6 +22,7 @@ #define FW_START_OVERRIDE BIT(0) #define FW_START_WORKING_PDA_CR4 BIT(2) +#define FW_START_WORKING_PDA_DSP BIT(3) #define PATCH_SEC_NOT_SUPPORT GENMASK(31, 0) #define PATCH_SEC_TYPE_MASK GENMASK(15, 0) @@ -518,7 +519,8 @@ struct sta_rec_muru { u8 uo_ra; u8 he_2x996_tone; u8 rx_t_frame_11ac; - u8 rsv[3]; + u8 rx_ctrl_frame_to_mbss; + u8 rsv[2]; } ofdma_ul; struct { @@ -998,6 +1000,7 @@ enum { MCU_EXT_EVENT_ASSERT_DUMP = 0x23, MCU_EXT_EVENT_RDD_REPORT = 0x3a, MCU_EXT_EVENT_CSA_NOTIFY = 0x4f, + MCU_EXT_EVENT_WA_TX_STAT = 0x74, MCU_EXT_EVENT_BCC_NOTIFY = 0x75, MCU_EXT_EVENT_MURU_CTRL = 0x9f, }; @@ -1287,6 +1290,7 @@ enum { UNI_BSS_INFO_UAPSD = 19, UNI_BSS_INFO_PS = 21, UNI_BSS_INFO_BCNFT = 22, + UNI_BSS_INFO_IFS_TIME = 23, UNI_BSS_INFO_OFFLOAD = 25, UNI_BSS_INFO_MLD = 26, }; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c index 3e41d809ade3..d5db6ffd6d36 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -853,7 +853,8 @@ int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb, if (WARN_ON_ONCE(len > skb->len)) return -EINVAL; - pskb_trim(skb, len); + if (pskb_trim(skb, len)) + return -EINVAL; status->chains = BIT(0); signal = mt76x02_mac_get_rssi(dev, rxwi->rssi[0], 0); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/Kconfig b/drivers/net/wireless/mediatek/mt76/mt7915/Kconfig index d710726d47bf..896ec38c23d9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/Kconfig +++ b/drivers/net/wireless/mediatek/mt76/mt7915/Kconfig @@ -14,12 +14,12 @@ config MT7915E To compile this driver as a module, choose M here. -config MT7986_WMAC - bool "MT7986 (SoC) WMAC support" +config MT798X_WMAC + bool "MT798x (SoC) WMAC support" depends on MT7915E depends on ARCH_MEDIATEK || COMPILE_TEST select REGMAP help - This adds support for the built-in WMAC on MT7986 SoC device + This adds support for the built-in WMAC on MT7981 and MT7986 SoC device which has the same feature set as a MT7915, but enables 6E support. diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/Makefile b/drivers/net/wireless/mediatek/mt76/mt7915/Makefile index 797ae49805c3..e0ca638c91a5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/Makefile +++ b/drivers/net/wireless/mediatek/mt76/mt7915/Makefile @@ -6,5 +6,5 @@ mt7915e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \ debugfs.o mmio.o mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o -mt7915e-$(CONFIG_MT7986_WMAC) += soc.o +mt7915e-$(CONFIG_MT798X_WMAC) += soc.o mt7915e-$(CONFIG_DEV_COREDUMP) += coredump.o diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/coredump.c b/drivers/net/wireless/mediatek/mt76/mt7915/coredump.c index d097a56dd33d..5daf2258dfe6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/coredump.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/coredump.c @@ -52,7 +52,7 @@ static const struct mt7915_mem_region mt7916_mem_regions[] = { }, }; -static const struct mt7915_mem_region mt7986_mem_regions[] = { +static const struct mt7915_mem_region mt798x_mem_regions[] = { { .start = 0x00800000, .len = 0x0005ffff, @@ -92,9 +92,10 @@ mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u32 *num) case 0x7915: *num = ARRAY_SIZE(mt7915_mem_regions); return &mt7915_mem_regions[0]; + case 0x7981: case 0x7986: - *num = ARRAY_SIZE(mt7986_mem_regions); - return &mt7986_mem_regions[0]; + *num = ARRAY_SIZE(mt798x_mem_regions); + return &mt798x_mem_regions[0]; case 0x7916: *num = ARRAY_SIZE(mt7916_mem_regions); return &mt7916_mem_regions[0]; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c index 879884ead660..6c3696c8c700 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c @@ -251,7 +251,6 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) { struct mt7915_phy *phy = file->private; struct mt7915_dev *dev = phy->dev; - struct mt7915_mcu_muru_stats mu_stats = {}; static const char * const dl_non_he_type[] = { "CCK", "OFDM", "HT MIX", "HT GF", "VHT SU", "VHT 2MU", "VHT 3MU", "VHT 4MU" @@ -275,7 +274,7 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) mutex_lock(&dev->mt76.mutex); - ret = mt7915_mcu_muru_debug_get(phy, &mu_stats); + ret = mt7915_mcu_muru_debug_get(phy); if (ret) goto exit; @@ -285,14 +284,13 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) for (i = 0; i < 5; i++) seq_printf(file, "%8s | ", dl_non_he_type[i]); -#define __dl_u32(s) le32_to_cpu(mu_stats.dl.s) seq_puts(file, "\nTotal Count:"); seq_printf(file, "%8u | %8u | %8u | %8u | %8u | ", - __dl_u32(cck_cnt), - __dl_u32(ofdm_cnt), - __dl_u32(htmix_cnt), - __dl_u32(htgf_cnt), - __dl_u32(vht_su_cnt)); + phy->mib.dl_cck_cnt, + phy->mib.dl_ofdm_cnt, + phy->mib.dl_htmix_cnt, + phy->mib.dl_htgf_cnt, + phy->mib.dl_vht_su_cnt); seq_puts(file, "\nDownlink MU-MIMO\nData Type: "); @@ -301,23 +299,23 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) seq_puts(file, "\nTotal Count:"); seq_printf(file, "%8u | %8u | %8u | ", - __dl_u32(vht_2mu_cnt), - __dl_u32(vht_3mu_cnt), - __dl_u32(vht_4mu_cnt)); + phy->mib.dl_vht_2mu_cnt, + phy->mib.dl_vht_3mu_cnt, + phy->mib.dl_vht_4mu_cnt); - sub_total_cnt = __dl_u32(vht_2mu_cnt) + - __dl_u32(vht_3mu_cnt) + - __dl_u32(vht_4mu_cnt); + sub_total_cnt = phy->mib.dl_vht_2mu_cnt + + phy->mib.dl_vht_3mu_cnt + + phy->mib.dl_vht_4mu_cnt; seq_printf(file, "\nTotal non-HE MU-MIMO DL PPDU count: %lld", sub_total_cnt); total_ppdu_cnt = sub_total_cnt + - __dl_u32(cck_cnt) + - __dl_u32(ofdm_cnt) + - __dl_u32(htmix_cnt) + - __dl_u32(htgf_cnt) + - __dl_u32(vht_su_cnt); + phy->mib.dl_cck_cnt + + phy->mib.dl_ofdm_cnt + + phy->mib.dl_htmix_cnt + + phy->mib.dl_htgf_cnt + + phy->mib.dl_vht_su_cnt; seq_printf(file, "\nAll non-HE DL PPDU count: %lld", total_ppdu_cnt); @@ -329,8 +327,7 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) seq_puts(file, "\nTotal Count:"); seq_printf(file, "%8u | %8u | ", - __dl_u32(he_su_cnt), - __dl_u32(he_ext_su_cnt)); + phy->mib.dl_he_su_cnt, phy->mib.dl_he_ext_su_cnt); seq_puts(file, "\nDownlink MU-MIMO\nData Type: "); @@ -339,9 +336,8 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) seq_puts(file, "\nTotal Count:"); seq_printf(file, "%8u | %8u | %8u | ", - __dl_u32(he_2mu_cnt), - __dl_u32(he_3mu_cnt), - __dl_u32(he_4mu_cnt)); + phy->mib.dl_he_2mu_cnt, phy->mib.dl_he_3mu_cnt, + phy->mib.dl_he_4mu_cnt); seq_puts(file, "\nDownlink OFDMA\nData Type: "); @@ -350,37 +346,35 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) seq_puts(file, "\nTotal Count:"); seq_printf(file, "%8u | %8u | %8u | %8u | %9u | %8u | ", - __dl_u32(he_2ru_cnt), - __dl_u32(he_3ru_cnt), - __dl_u32(he_4ru_cnt), - __dl_u32(he_5to8ru_cnt), - __dl_u32(he_9to16ru_cnt), - __dl_u32(he_gtr16ru_cnt)); - - sub_total_cnt = __dl_u32(he_2mu_cnt) + - __dl_u32(he_3mu_cnt) + - __dl_u32(he_4mu_cnt); + phy->mib.dl_he_2ru_cnt, + phy->mib.dl_he_3ru_cnt, + phy->mib.dl_he_4ru_cnt, + phy->mib.dl_he_5to8ru_cnt, + phy->mib.dl_he_9to16ru_cnt, + phy->mib.dl_he_gtr16ru_cnt); + + sub_total_cnt = phy->mib.dl_he_2mu_cnt + + phy->mib.dl_he_3mu_cnt + + phy->mib.dl_he_4mu_cnt; total_ppdu_cnt = sub_total_cnt; seq_printf(file, "\nTotal HE MU-MIMO DL PPDU count: %lld", sub_total_cnt); - sub_total_cnt = __dl_u32(he_2ru_cnt) + - __dl_u32(he_3ru_cnt) + - __dl_u32(he_4ru_cnt) + - __dl_u32(he_5to8ru_cnt) + - __dl_u32(he_9to16ru_cnt) + - __dl_u32(he_gtr16ru_cnt); + sub_total_cnt = phy->mib.dl_he_2ru_cnt + + phy->mib.dl_he_3ru_cnt + + phy->mib.dl_he_4ru_cnt + + phy->mib.dl_he_5to8ru_cnt + + phy->mib.dl_he_9to16ru_cnt + + phy->mib.dl_he_gtr16ru_cnt; total_ppdu_cnt += sub_total_cnt; seq_printf(file, "\nTotal HE OFDMA DL PPDU count: %lld", sub_total_cnt); - total_ppdu_cnt += __dl_u32(he_su_cnt) + - __dl_u32(he_ext_su_cnt); + total_ppdu_cnt += phy->mib.dl_he_su_cnt + phy->mib.dl_he_ext_su_cnt; seq_printf(file, "\nAll HE DL PPDU count: %lld", total_ppdu_cnt); -#undef __dl_u32 /* HE Uplink */ seq_puts(file, "\n\nUplink"); @@ -389,12 +383,11 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) for (i = 0; i < 3; i++) seq_printf(file, "%8s | ", ul_he_type[i]); -#define __ul_u32(s) le32_to_cpu(mu_stats.ul.s) seq_puts(file, "\nTotal Count:"); seq_printf(file, "%8u | %8u | %8u | ", - __ul_u32(hetrig_2mu_cnt), - __ul_u32(hetrig_3mu_cnt), - __ul_u32(hetrig_4mu_cnt)); + phy->mib.ul_hetrig_2mu_cnt, + phy->mib.ul_hetrig_3mu_cnt, + phy->mib.ul_hetrig_4mu_cnt); seq_puts(file, "\nTrigger-based Uplink OFDMA\nData Type: "); @@ -403,37 +396,36 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) seq_puts(file, "\nTotal Count:"); seq_printf(file, "%8u | %8u | %8u | %8u | %8u | %9u | %7u | ", - __ul_u32(hetrig_su_cnt), - __ul_u32(hetrig_2ru_cnt), - __ul_u32(hetrig_3ru_cnt), - __ul_u32(hetrig_4ru_cnt), - __ul_u32(hetrig_5to8ru_cnt), - __ul_u32(hetrig_9to16ru_cnt), - __ul_u32(hetrig_gtr16ru_cnt)); - - sub_total_cnt = __ul_u32(hetrig_2mu_cnt) + - __ul_u32(hetrig_3mu_cnt) + - __ul_u32(hetrig_4mu_cnt); + phy->mib.ul_hetrig_su_cnt, + phy->mib.ul_hetrig_2ru_cnt, + phy->mib.ul_hetrig_3ru_cnt, + phy->mib.ul_hetrig_4ru_cnt, + phy->mib.ul_hetrig_5to8ru_cnt, + phy->mib.ul_hetrig_9to16ru_cnt, + phy->mib.ul_hetrig_gtr16ru_cnt); + + sub_total_cnt = phy->mib.ul_hetrig_2mu_cnt + + phy->mib.ul_hetrig_3mu_cnt + + phy->mib.ul_hetrig_4mu_cnt; total_ppdu_cnt = sub_total_cnt; seq_printf(file, "\nTotal HE MU-MIMO UL TB PPDU count: %lld", sub_total_cnt); - sub_total_cnt = __ul_u32(hetrig_2ru_cnt) + - __ul_u32(hetrig_3ru_cnt) + - __ul_u32(hetrig_4ru_cnt) + - __ul_u32(hetrig_5to8ru_cnt) + - __ul_u32(hetrig_9to16ru_cnt) + - __ul_u32(hetrig_gtr16ru_cnt); + sub_total_cnt = phy->mib.ul_hetrig_2ru_cnt + + phy->mib.ul_hetrig_3ru_cnt + + phy->mib.ul_hetrig_4ru_cnt + + phy->mib.ul_hetrig_5to8ru_cnt + + phy->mib.ul_hetrig_9to16ru_cnt + + phy->mib.ul_hetrig_gtr16ru_cnt; total_ppdu_cnt += sub_total_cnt; seq_printf(file, "\nTotal HE OFDMA UL TB PPDU count: %lld", sub_total_cnt); - total_ppdu_cnt += __ul_u32(hetrig_su_cnt); + total_ppdu_cnt += phy->mib.ul_hetrig_su_cnt; seq_printf(file, "\nAll HE UL TB PPDU count: %lld\n", total_ppdu_cnt); -#undef __ul_u32 exit: mutex_unlock(&dev->mt76.mutex); @@ -719,10 +711,10 @@ mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy, static void mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s) { + struct mt76_mib_stats *mib = &phy->mib; static const char * const bw[] = { "BW20", "BW40", "BW80", "BW160" }; - struct mib_stats *mib = &phy->mib; /* Tx Beamformer monitor */ seq_puts(s, "\nTx Beamformer applied PPDU counts: "); @@ -768,7 +760,7 @@ mt7915_tx_stats_show(struct seq_file *file, void *data) { struct mt7915_phy *phy = file->private; struct mt7915_dev *dev = phy->dev; - struct mib_stats *mib = &phy->mib; + struct mt76_mib_stats *mib = &phy->mib; int i; mutex_lock(&dev->mt76.mutex); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/dma.c b/drivers/net/wireless/mediatek/mt76/mt7915/dma.c index 43a5456d4b97..59a44d79aaed 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/dma.c @@ -11,7 +11,7 @@ mt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc, int ring_base struct mt7915_dev *dev = phy->dev; if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) { - if (is_mt7986(&dev->mt76)) + if (is_mt798x(&dev->mt76)) ring_base += MT_TXQ_ID(0) * MT_RING_SIZE; else ring_base = MT_WED_TX_RING_BASE; @@ -250,7 +250,7 @@ static void mt7915_dma_disable(struct mt7915_dev *dev, bool rst) } } -static int mt7915_dma_enable(struct mt7915_dev *dev) +int mt7915_dma_start(struct mt7915_dev *dev, bool reset, bool wed_reset) { struct mt76_dev *mdev = &dev->mt76; u32 hif1_ofs = 0; @@ -259,6 +259,84 @@ static int mt7915_dma_enable(struct mt7915_dev *dev) if (dev->hif2) hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); + /* enable wpdma tx/rx */ + if (!reset) { + mt76_set(dev, MT_WFDMA0_GLO_CFG, + MT_WFDMA0_GLO_CFG_TX_DMA_EN | + MT_WFDMA0_GLO_CFG_RX_DMA_EN | + MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | + MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); + + if (is_mt7915(mdev)) + mt76_set(dev, MT_WFDMA1_GLO_CFG, + MT_WFDMA1_GLO_CFG_TX_DMA_EN | + MT_WFDMA1_GLO_CFG_RX_DMA_EN | + MT_WFDMA1_GLO_CFG_OMIT_TX_INFO | + MT_WFDMA1_GLO_CFG_OMIT_RX_INFO); + + if (dev->hif2) { + mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs, + MT_WFDMA0_GLO_CFG_TX_DMA_EN | + MT_WFDMA0_GLO_CFG_RX_DMA_EN | + MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | + MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); + + if (is_mt7915(mdev)) + mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs, + MT_WFDMA1_GLO_CFG_TX_DMA_EN | + MT_WFDMA1_GLO_CFG_RX_DMA_EN | + MT_WFDMA1_GLO_CFG_OMIT_TX_INFO | + MT_WFDMA1_GLO_CFG_OMIT_RX_INFO); + + mt76_set(dev, MT_WFDMA_HOST_CONFIG, + MT_WFDMA_HOST_CONFIG_PDMA_BAND); + } + } + + /* enable interrupts for TX/RX rings */ + irq_mask = MT_INT_RX_DONE_MCU | + MT_INT_TX_DONE_MCU | + MT_INT_MCU_CMD; + + if (!dev->phy.mt76->band_idx) + irq_mask |= MT_INT_BAND0_RX_DONE; + + if (dev->dbdc_support || dev->phy.mt76->band_idx) + irq_mask |= MT_INT_BAND1_RX_DONE; + + if (mtk_wed_device_active(&dev->mt76.mmio.wed) && wed_reset) { + u32 wed_irq_mask = irq_mask; + int ret; + + wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1; + if (!is_mt798x(&dev->mt76)) + mt76_wr(dev, MT_INT_WED_MASK_CSR, wed_irq_mask); + else + mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask); + + ret = mt7915_mcu_wed_enable_rx_stats(dev); + if (ret) + return ret; + + mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask); + } + + irq_mask = reset ? MT_INT_MCU_CMD : irq_mask; + + mt7915_irq_enable(dev, irq_mask); + mt7915_irq_disable(dev, 0); + + return 0; +} + +static int mt7915_dma_enable(struct mt7915_dev *dev, bool reset) +{ + struct mt76_dev *mdev = &dev->mt76; + u32 hif1_ofs = 0; + + if (dev->hif2) + hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); + /* reset dma idx */ mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0); if (is_mt7915(mdev)) @@ -322,69 +400,7 @@ static int mt7915_dma_enable(struct mt7915_dev *dev) mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC, MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000); - /* set WFDMA Tx/Rx */ - mt76_set(dev, MT_WFDMA0_GLO_CFG, - MT_WFDMA0_GLO_CFG_TX_DMA_EN | - MT_WFDMA0_GLO_CFG_RX_DMA_EN | - MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | - MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); - - if (is_mt7915(mdev)) - mt76_set(dev, MT_WFDMA1_GLO_CFG, - MT_WFDMA1_GLO_CFG_TX_DMA_EN | - MT_WFDMA1_GLO_CFG_RX_DMA_EN | - MT_WFDMA1_GLO_CFG_OMIT_TX_INFO | - MT_WFDMA1_GLO_CFG_OMIT_RX_INFO); - - if (dev->hif2) { - mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs, - MT_WFDMA0_GLO_CFG_TX_DMA_EN | - MT_WFDMA0_GLO_CFG_RX_DMA_EN | - MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | - MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); - - if (is_mt7915(mdev)) - mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs, - MT_WFDMA1_GLO_CFG_TX_DMA_EN | - MT_WFDMA1_GLO_CFG_RX_DMA_EN | - MT_WFDMA1_GLO_CFG_OMIT_TX_INFO | - MT_WFDMA1_GLO_CFG_OMIT_RX_INFO); - - mt76_set(dev, MT_WFDMA_HOST_CONFIG, - MT_WFDMA_HOST_CONFIG_PDMA_BAND); - } - - /* enable interrupts for TX/RX rings */ - irq_mask = MT_INT_RX_DONE_MCU | - MT_INT_TX_DONE_MCU | - MT_INT_MCU_CMD; - - if (!dev->phy.mt76->band_idx) - irq_mask |= MT_INT_BAND0_RX_DONE; - - if (dev->dbdc_support || dev->phy.mt76->band_idx) - irq_mask |= MT_INT_BAND1_RX_DONE; - - if (mtk_wed_device_active(&dev->mt76.mmio.wed)) { - u32 wed_irq_mask = irq_mask; - int ret; - - wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1; - if (!is_mt7986(&dev->mt76)) - mt76_wr(dev, MT_INT_WED_MASK_CSR, wed_irq_mask); - else - mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask); - - ret = mt7915_mcu_wed_enable_rx_stats(dev); - if (ret) - return ret; - - mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask); - } - - mt7915_irq_enable(dev, irq_mask); - - return 0; + return mt7915_dma_start(dev, reset, true); } int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2) @@ -404,7 +420,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2) mt7915_dma_disable(dev, true); if (mtk_wed_device_active(&mdev->mmio.wed)) { - if (!is_mt7986(mdev)) { + if (!is_mt798x(mdev)) { u8 wed_control_rx1 = is_mt7915(mdev) ? 1 : 2; mt76_set(dev, MT_WFDMA_HOST_CONFIG, @@ -560,7 +576,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2) mt7915_poll_tx); napi_enable(&dev->mt76.tx_napi); - mt7915_dma_enable(dev); + mt7915_dma_enable(dev, false); return 0; } @@ -642,7 +658,7 @@ int mt7915_dma_reset(struct mt7915_dev *dev, bool force) mt76_rmw(dev, MT_WFDMA0_EXT0_CFG, MT_WFDMA0_EXT0_RXWB_KEEP, MT_WFDMA0_EXT0_RXWB_KEEP); - mt7915_dma_enable(dev); + mt7915_dma_enable(dev, !force); return 0; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c index a79628933948..76be7308460b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c @@ -39,6 +39,8 @@ static int mt7915_check_eeprom(struct mt7915_dev *dev) return CHECK_EEPROM_ERR(is_mt7915(&dev->mt76)); case 0x7916: return CHECK_EEPROM_ERR(is_mt7916(&dev->mt76)); + case 0x7981: + return CHECK_EEPROM_ERR(is_mt7981(&dev->mt76)); case 0x7986: return CHECK_EEPROM_ERR(is_mt7986(&dev->mt76)); default: @@ -52,6 +54,9 @@ static char *mt7915_eeprom_name(struct mt7915_dev *dev) case 0x7915: return dev->dbdc_support ? MT7915_EEPROM_DEFAULT_DBDC : MT7915_EEPROM_DEFAULT; + case 0x7981: + /* mt7981 only supports mt7976 and only in DBDC mode */ + return MT7981_EEPROM_MT7976_DEFAULT_DBDC; case 0x7986: switch (mt7915_check_adie(dev, true)) { case MT7976_ONE_ADIE_DBDC: @@ -215,7 +220,7 @@ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev, eeprom[MT_EE_WIFI_CONF + 2 + band]); } - if (!is_mt7986(&dev->mt76)) + if (!is_mt798x(&dev->mt76)) nss_max = 2; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index aec47de35f53..35fdf4f98d80 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -415,7 +415,6 @@ mt7915_init_wiphy(struct mt7915_phy *phy) if (!dev->dbdc_support) vht_cap->cap |= IEEE80211_VHT_CAP_SHORT_GI_160 | - IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ | FIELD_PREP(IEEE80211_VHT_CAP_EXT_NSS_BW_MASK, 1); } else { vht_cap->cap |= @@ -500,6 +499,12 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band) set = FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_MODE, 0) | FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_PARAM, 0x3); mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set); + + /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than + * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set. + */ + if (mtk_wed_device_active(&dev->mt76.mmio.wed)) + mt76_set(dev, MT_AGG_ACR4(band), MT_AGG_ACR_PPDU_TXS2H); } static void @@ -582,6 +587,8 @@ void mt7915_mac_init(struct mt7915_dev *dev) if (!is_mt7915(&dev->mt76)) mt76_clear(dev, MT_MDP_DCR2, MT_MDP_DCR2_RX_TRANS_SHORT); + else + mt76_clear(dev, MT_PLE_HOST_RPT0, MT_PLE_HOST_RPT0_TX_LATENCY); /* enable hardware de-agg */ mt76_set(dev, MT_MDP_DCR0, MT_MDP_DCR0_DAMSDU_EN); @@ -733,7 +740,7 @@ void mt7915_wfsys_reset(struct mt7915_dev *dev) mt76_clear(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE); msleep(100); - } else if (is_mt7986(&dev->mt76)) { + } else if (is_mt798x(&dev->mt76)) { mt7986_wmac_disable(dev); msleep(20); @@ -754,7 +761,7 @@ static bool mt7915_band_config(struct mt7915_dev *dev) dev->phy.mt76->band_idx = 0; - if (is_mt7986(&dev->mt76)) { + if (is_mt798x(&dev->mt76)) { u32 sku = mt7915_check_adie(dev, true); /* @@ -1159,11 +1166,11 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev) static void mt7915_stop_hardware(struct mt7915_dev *dev) { mt7915_mcu_exit(dev); - mt7915_tx_token_put(dev); + mt76_connac2_tx_token_put(&dev->mt76); mt7915_dma_cleanup(dev); tasklet_disable(&dev->mt76.irq_tasklet); - if (is_mt7986(&dev->mt76)) + if (is_mt798x(&dev->mt76)) mt7986_wmac_disable(dev); } @@ -1178,9 +1185,7 @@ int mt7915_register_device(struct mt7915_dev *dev) INIT_WORK(&dev->rc_work, mt7915_mac_sta_rc_work); INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7915_mac_work); INIT_LIST_HEAD(&dev->sta_rc_list); - INIT_LIST_HEAD(&dev->sta_poll_list); INIT_LIST_HEAD(&dev->twt_list); - spin_lock_init(&dev->sta_poll_lock); init_waitqueue_head(&dev->reset_wait); INIT_WORK(&dev->reset_work, mt7915_mac_reset_work); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index 7df8d95fc3fb..b8b0c0fda752 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -105,9 +105,9 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev) LIST_HEAD(sta_poll_list); int i; - spin_lock_bh(&dev->sta_poll_lock); - list_splice_init(&dev->sta_poll_list, &sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); rcu_read_lock(); @@ -118,15 +118,15 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev) s8 rssi[4]; u8 bw; - spin_lock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); if (list_empty(&sta_poll_list)) { - spin_unlock_bh(&dev->sta_poll_lock); + spin_unlock_bh(&dev->mt76.sta_poll_lock); break; } msta = list_first_entry(&sta_poll_list, - struct mt7915_sta, poll_list); - list_del_init(&msta->poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + struct mt7915_sta, wcid.poll_list); + list_del_init(&msta->wcid.poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); idx = msta->wcid.idx; @@ -326,10 +326,11 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb, if (status->wcid) { msta = container_of(status->wcid, struct mt7915_sta, wcid); - spin_lock_bh(&dev->sta_poll_lock); - if (list_empty(&msta->poll_list)) - list_add_tail(&msta->poll_list, &dev->sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (list_empty(&msta->wcid.poll_list)) + list_add_tail(&msta->wcid.poll_list, + &dev->mt76.sta_poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); } status->freq = mphy->chandef.chan->center_freq; @@ -842,74 +843,6 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id) } static void -mt7915_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) -{ - struct mt7915_sta *msta; - u16 fc, tid; - u32 val; - - if (!sta || !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he)) - return; - - tid = le32_get_bits(txwi[1], MT_TXD1_TID); - if (tid >= 6) /* skip VO queue */ - return; - - val = le32_to_cpu(txwi[2]); - fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 | - FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4; - if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA))) - return; - - msta = (struct mt7915_sta *)sta->drv_priv; - if (!test_and_set_bit(tid, &msta->ampdu_state)) - ieee80211_start_tx_ba_session(sta, tid, 0); -} - -static void -mt7915_txwi_free(struct mt7915_dev *dev, struct mt76_txwi_cache *t, - struct ieee80211_sta *sta, struct list_head *free_list) -{ - struct mt76_dev *mdev = &dev->mt76; - struct mt7915_sta *msta; - struct mt76_wcid *wcid; - __le32 *txwi; - u16 wcid_idx; - - mt76_connac_txp_skb_unmap(mdev, t); - if (!t->skb) - goto out; - - txwi = (__le32 *)mt76_get_txwi_ptr(mdev, t); - if (sta) { - wcid = (struct mt76_wcid *)sta->drv_priv; - wcid_idx = wcid->idx; - } else { - wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX); - wcid = rcu_dereference(dev->mt76.wcid[wcid_idx]); - - if (wcid && wcid->sta) { - msta = container_of(wcid, struct mt7915_sta, wcid); - sta = container_of((void *)msta, struct ieee80211_sta, - drv_priv); - spin_lock_bh(&dev->sta_poll_lock); - if (list_empty(&msta->poll_list)) - list_add_tail(&msta->poll_list, &dev->sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); - } - } - - if (sta && likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE))) - mt7915_tx_check_aggr(sta, txwi); - - __mt76_tx_complete_skb(mdev, wcid_idx, t->skb, free_list); - -out: - t->skb = NULL; - mt76_put_txwi(mdev, t); -} - -static void mt7915_mac_tx_free_prepare(struct mt7915_dev *dev) { struct mt76_dev *mdev = &dev->mt76; @@ -951,6 +884,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len) struct mt76_dev *mdev = &dev->mt76; struct mt76_txwi_cache *txwi; struct ieee80211_sta *sta = NULL; + struct mt76_wcid *wcid = NULL; LIST_HEAD(free_list); void *end = data + len; bool v3, wake = false; @@ -977,7 +911,6 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len) info = le32_to_cpu(*cur_info); if (info & MT_TX_FREE_PAIR) { struct mt7915_sta *msta; - struct mt76_wcid *wcid; u16 idx; idx = FIELD_GET(MT_TX_FREE_WLAN_ID, info); @@ -987,14 +920,33 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len) continue; msta = container_of(wcid, struct mt7915_sta, wcid); - spin_lock_bh(&dev->sta_poll_lock); - if (list_empty(&msta->poll_list)) - list_add_tail(&msta->poll_list, &dev->sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&mdev->sta_poll_lock); + if (list_empty(&msta->wcid.poll_list)) + list_add_tail(&msta->wcid.poll_list, + &mdev->sta_poll_list); + spin_unlock_bh(&mdev->sta_poll_lock); continue; } - if (v3 && (info & MT_TX_FREE_MPDU_HEADER)) + if (!mtk_wed_device_active(&mdev->mmio.wed) && wcid) { + u32 tx_retries = 0, tx_failed = 0; + + if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3)) { + tx_retries = + FIELD_GET(MT_TX_FREE_COUNT_V3, info) - 1; + tx_failed = tx_retries + + !!FIELD_GET(MT_TX_FREE_STAT_V3, info); + } else if (!v3 && (info & MT_TX_FREE_MPDU_HEADER)) { + tx_retries = + FIELD_GET(MT_TX_FREE_COUNT, info) - 1; + tx_failed = tx_retries + + !!FIELD_GET(MT_TX_FREE_STAT, info); + } + wcid->stats.tx_retries += tx_retries; + wcid->stats.tx_failed += tx_failed; + } + + if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3)) continue; for (i = 0; i < 1 + v3; i++) { @@ -1010,7 +962,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len) if (!txwi) continue; - mt7915_txwi_free(dev, txwi, sta, &free_list); + mt76_connac2_txwi_free(mdev, txwi, sta, &free_list); } } @@ -1042,7 +994,7 @@ mt7915_mac_tx_free_v0(struct mt7915_dev *dev, void *data, int len) if (!txwi) continue; - mt7915_txwi_free(dev, txwi, NULL, &free_list); + mt76_connac2_txwi_free(mdev, txwi, NULL, &free_list); } mt7915_mac_tx_free_done(dev, &free_list, wake); @@ -1081,10 +1033,10 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data) if (!wcid->sta) goto out; - spin_lock_bh(&dev->sta_poll_lock); - if (list_empty(&msta->poll_list)) - list_add_tail(&msta->poll_list, &dev->sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (list_empty(&msta->wcid.poll_list)) + list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); out: rcu_read_unlock(); @@ -1357,20 +1309,6 @@ mt7915_update_beacons(struct mt7915_dev *dev) mt7915_update_vif_beacon, mphy_ext->hw); } -void mt7915_tx_token_put(struct mt7915_dev *dev) -{ - struct mt76_txwi_cache *txwi; - int id; - - spin_lock_bh(&dev->mt76.token_lock); - idr_for_each_entry(&dev->mt76.token, txwi, id) { - mt7915_txwi_free(dev, txwi, NULL, NULL); - dev->mt76.token_count--; - } - spin_unlock_bh(&dev->mt76.token_lock); - idr_destroy(&dev->mt76.token); -} - static int mt7915_mac_restart(struct mt7915_dev *dev) { @@ -1389,8 +1327,12 @@ mt7915_mac_restart(struct mt7915_dev *dev) if (dev_is_pci(mdev->dev)) { mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0); - if (dev->hif2) - mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0x0); + if (dev->hif2) { + if (is_mt7915(mdev)) + mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0x0); + else + mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE_MT7916, 0x0); + } } set_bit(MT76_RESET, &dev->mphy.state); @@ -1415,7 +1357,7 @@ mt7915_mac_restart(struct mt7915_dev *dev) napi_disable(&dev->mt76.tx_napi); /* token reinit */ - mt7915_tx_token_put(dev); + mt76_connac2_tx_token_put(&dev->mt76); idr_init(&dev->mt76.token); mt7915_dma_reset(dev, true); @@ -1440,8 +1382,12 @@ mt7915_mac_restart(struct mt7915_dev *dev) } if (dev_is_pci(mdev->dev)) { mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); - if (dev->hif2) - mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff); + if (dev->hif2) { + if (is_mt7915(mdev)) + mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff); + else + mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE_MT7916, 0xff); + } } /* load firmware */ @@ -1576,7 +1522,7 @@ void mt7915_mac_reset_work(struct work_struct *work) if (mtk_wed_device_active(&dev->mt76.mmio.wed)) { mtk_wed_device_stop(&dev->mt76.mmio.wed); - if (!is_mt7986(&dev->mt76)) + if (!is_mt798x(&dev->mt76)) mt76_wr(dev, MT_INT_WED_MASK_CSR, 0); } @@ -1604,13 +1550,19 @@ void mt7915_mac_reset_work(struct work_struct *work) if (mt7915_wait_reset_state(dev, MT_MCU_CMD_RESET_DONE)) { mt7915_dma_reset(dev, false); - mt7915_tx_token_put(dev); + mt76_connac2_tx_token_put(&dev->mt76); idr_init(&dev->mt76.token); mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_DMA_INIT); mt7915_wait_reset_state(dev, MT_MCU_CMD_RECOVERY_DONE); } + mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE); + mt7915_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE); + + /* enable DMA Tx/Rx and interrupt */ + mt7915_dma_start(dev, false, false); + clear_bit(MT76_MCU_RESET, &dev->mphy.state); clear_bit(MT76_RESET, &dev->mphy.state); if (phy2) @@ -1625,9 +1577,6 @@ void mt7915_mac_reset_work(struct work_struct *work) tasklet_schedule(&dev->mt76.irq_tasklet); - mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE); - mt7915_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE); - mt76_worker_enable(&dev->mt76.tx_worker); local_bh_disable(); @@ -1747,8 +1696,8 @@ void mt7915_reset(struct mt7915_dev *dev) void mt7915_mac_update_stats(struct mt7915_phy *phy) { + struct mt76_mib_stats *mib = &phy->mib; struct mt7915_dev *dev = phy->dev; - struct mib_stats *mib = &phy->mib; int i, aggr0 = 0, aggr1, cnt; u8 band = phy->mt76->band_idx; u32 val; @@ -2010,7 +1959,7 @@ void mt7915_mac_sta_rc_work(struct work_struct *work) u32 changed; LIST_HEAD(list); - spin_lock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); list_splice_init(&dev->sta_rc_list, &list); while (!list_empty(&list)) { @@ -2018,7 +1967,7 @@ void mt7915_mac_sta_rc_work(struct work_struct *work) list_del_init(&msta->rc_list); changed = msta->changed; msta->changed = 0; - spin_unlock_bh(&dev->sta_poll_lock); + spin_unlock_bh(&dev->mt76.sta_poll_lock); sta = container_of((void *)msta, struct ieee80211_sta, drv_priv); vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv); @@ -2031,10 +1980,10 @@ void mt7915_mac_sta_rc_work(struct work_struct *work) if (changed & IEEE80211_RC_SMPS_CHANGED) mt7915_mcu_add_smps(dev, vif, sta); - spin_lock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); } - spin_unlock_bh(&dev->sta_poll_lock); + spin_unlock_bh(&dev->mt76.sta_poll_lock); } void mt7915_mac_work(struct work_struct *work) @@ -2054,6 +2003,9 @@ void mt7915_mac_work(struct work_struct *work) mt7915_mac_update_stats(phy); mt7915_mac_severe_check(phy); + + if (phy->dev->muru_debug) + mt7915_mcu_muru_debug_get(phy); } mutex_unlock(&mphy->dev->mutex); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h index ce94f87e2042..448b1b380190 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h @@ -9,7 +9,12 @@ #define MT_TX_FREE_VER GENMASK(18, 16) #define MT_TX_FREE_MSDU_CNT_V0 GENMASK(6, 0) /* 0: success, others: dropped */ -#define MT_TX_FREE_MPDU_HEADER BIT(30) +#define MT_TX_FREE_COUNT GENMASK(12, 0) +#define MT_TX_FREE_COUNT_V3 GENMASK(27, 24) +#define MT_TX_FREE_STAT GENMASK(14, 13) +#define MT_TX_FREE_STAT_V3 GENMASK(29, 28) +#define MT_TX_FREE_MPDU_HEADER BIT(15) +#define MT_TX_FREE_MPDU_HEADER_V3 BIT(30) #define MT_TX_FREE_MSDU_ID_V3 GENMASK(14, 0) #define MT_TXS5_F0_FINAL_MPDU BIT(31) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index 1b361199c061..8ebbf186fab2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -248,7 +248,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, idx = MT7915_WTBL_RESERVED - mvif->mt76.idx; INIT_LIST_HEAD(&mvif->sta.rc_list); - INIT_LIST_HEAD(&mvif->sta.poll_list); + INIT_LIST_HEAD(&mvif->sta.wcid.poll_list); mvif->sta.wcid.idx = idx; mvif->sta.wcid.phy_idx = ext_phy; mvif->sta.wcid.hw_key_idx = -1; @@ -269,6 +269,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR; mt7915_init_bitrate_mask(vif); + memset(&mvif->cap, -1, sizeof(mvif->cap)); mt7915_mcu_add_bss_info(phy, vif, true); mt7915_mcu_add_sta(dev, vif, NULL, true); @@ -308,10 +309,10 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw, phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx); mutex_unlock(&dev->mt76.mutex); - spin_lock_bh(&dev->sta_poll_lock); - if (!list_empty(&msta->poll_list)) - list_del_init(&msta->poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (!list_empty(&msta->wcid.poll_list)) + list_del_init(&msta->wcid.poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); mt76_packet_id_flush(&dev->mt76, &msta->wcid); } @@ -470,7 +471,8 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed) ieee80211_wake_queues(hw); } - if (changed & IEEE80211_CONF_CHANGE_POWER) { + if (changed & (IEEE80211_CONF_CHANGE_POWER | + IEEE80211_CONF_CHANGE_CHANNEL)) { ret = mt7915_mcu_set_txpower_sku(phy); if (ret) return ret; @@ -599,6 +601,7 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, { struct mt7915_phy *phy = mt7915_hw_phy(hw); struct mt7915_dev *dev = mt7915_hw_dev(hw); + int set_bss_info = -1, set_sta = -1; mutex_lock(&dev->mt76.mutex); @@ -607,15 +610,18 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, * and then peer references bss_info_rfch to set bandwidth cap. */ if (changed & BSS_CHANGED_BSSID && - vif->type == NL80211_IFTYPE_STATION) { - bool join = !is_zero_ether_addr(info->bssid); - - mt7915_mcu_add_bss_info(phy, vif, join); - mt7915_mcu_add_sta(dev, vif, NULL, join); - } - + vif->type == NL80211_IFTYPE_STATION) + set_bss_info = set_sta = !is_zero_ether_addr(info->bssid); if (changed & BSS_CHANGED_ASSOC) - mt7915_mcu_add_bss_info(phy, vif, vif->cfg.assoc); + set_bss_info = vif->cfg.assoc; + if (changed & BSS_CHANGED_BEACON_ENABLED && + vif->type != NL80211_IFTYPE_AP) + set_bss_info = set_sta = info->enable_beacon; + + if (set_bss_info == 1) + mt7915_mcu_add_bss_info(phy, vif, true); + if (set_sta == 1) + mt7915_mcu_add_sta(dev, vif, NULL, true); if (changed & BSS_CHANGED_ERP_CTS_PROT) mt7915_mac_enable_rtscts(dev, vif, info->use_cts_prot); @@ -629,11 +635,6 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, } } - if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) { - mt7915_mcu_add_bss_info(phy, vif, true); - mt7915_mcu_add_sta(dev, vif, NULL, true); - } - /* ensure that enable txcmd_mode after bss_info */ if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED)) mt7915_mcu_set_tx(dev, vif); @@ -650,6 +651,62 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, BSS_CHANGED_FILS_DISCOVERY)) mt7915_mcu_add_beacon(hw, vif, info->enable_beacon, changed); + if (set_bss_info == 0) + mt7915_mcu_add_bss_info(phy, vif, false); + if (set_sta == 0) + mt7915_mcu_add_sta(dev, vif, NULL, false); + + mutex_unlock(&dev->mt76.mutex); +} + +static void +mt7915_vif_check_caps(struct mt7915_phy *phy, struct ieee80211_vif *vif) +{ + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + struct mt7915_vif_cap *vc = &mvif->cap; + + vc->ht_ldpc = vif->bss_conf.ht_ldpc; + vc->vht_ldpc = vif->bss_conf.vht_ldpc; + vc->vht_su_ebfer = vif->bss_conf.vht_su_beamformer; + vc->vht_su_ebfee = vif->bss_conf.vht_su_beamformee; + vc->vht_mu_ebfer = vif->bss_conf.vht_mu_beamformer; + vc->vht_mu_ebfee = vif->bss_conf.vht_mu_beamformee; + vc->he_ldpc = vif->bss_conf.he_ldpc; + vc->he_su_ebfer = vif->bss_conf.he_su_beamformer; + vc->he_su_ebfee = vif->bss_conf.he_su_beamformee; + vc->he_mu_ebfer = vif->bss_conf.he_mu_beamformer; +} + +static int +mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) +{ + struct mt7915_phy *phy = mt7915_hw_phy(hw); + struct mt7915_dev *dev = mt7915_hw_dev(hw); + int err; + + mutex_lock(&dev->mt76.mutex); + + mt7915_vif_check_caps(phy, vif); + + err = mt7915_mcu_add_bss_info(phy, vif, true); + if (err) + goto out; + err = mt7915_mcu_add_sta(dev, vif, NULL, true); +out: + mutex_unlock(&dev->mt76.mutex); + + return err; +} + +static void +mt7915_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) +{ + struct mt7915_dev *dev = mt7915_hw_dev(hw); + + mutex_lock(&dev->mt76.mutex); + mt7915_mcu_add_sta(dev, vif, NULL, false); mutex_unlock(&dev->mt76.mutex); } @@ -679,7 +736,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, return -ENOSPC; INIT_LIST_HEAD(&msta->rc_list); - INIT_LIST_HEAD(&msta->poll_list); + INIT_LIST_HEAD(&msta->wcid.poll_list); msta->vif = mvif; msta->wcid.sta = 1; msta->wcid.idx = idx; @@ -714,12 +771,12 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++) mt7915_mac_twt_teardown_flow(dev, msta, i); - spin_lock_bh(&dev->sta_poll_lock); - if (!list_empty(&msta->poll_list)) - list_del_init(&msta->poll_list); + spin_lock_bh(&mdev->sta_poll_lock); + if (!list_empty(&msta->wcid.poll_list)) + list_del_init(&msta->wcid.poll_list); if (!list_empty(&msta->rc_list)) list_del_init(&msta->rc_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_unlock_bh(&mdev->sta_poll_lock); } static void mt7915_tx(struct ieee80211_hw *hw, @@ -801,16 +858,16 @@ mt7915_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: mtxq->aggr = false; - clear_bit(tid, &msta->ampdu_state); + clear_bit(tid, &msta->wcid.ampdu_state); ret = mt7915_mcu_add_tx_ba(dev, params, false); break; case IEEE80211_AMPDU_TX_START: - set_bit(tid, &msta->ampdu_state); + set_bit(tid, &msta->wcid.ampdu_state); ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; break; case IEEE80211_AMPDU_TX_STOP_CONT: mtxq->aggr = false; - clear_bit(tid, &msta->ampdu_state); + clear_bit(tid, &msta->wcid.ampdu_state); ret = mt7915_mcu_add_tx_ba(dev, params, false); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; @@ -842,7 +899,7 @@ mt7915_get_stats(struct ieee80211_hw *hw, { struct mt7915_phy *phy = mt7915_hw_phy(hw); struct mt7915_dev *dev = mt7915_hw_dev(hw); - struct mib_stats *mib = &phy->mib; + struct mt76_mib_stats *mib = &phy->mib; mutex_lock(&dev->mt76.mutex); @@ -1019,21 +1076,20 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE); } - if (!txrate->legacy && !txrate->flags) - return; - - if (txrate->legacy) { - sinfo->txrate.legacy = txrate->legacy; - } else { - sinfo->txrate.mcs = txrate->mcs; - sinfo->txrate.nss = txrate->nss; - sinfo->txrate.bw = txrate->bw; - sinfo->txrate.he_gi = txrate->he_gi; - sinfo->txrate.he_dcm = txrate->he_dcm; - sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc; + if (txrate->legacy || txrate->flags) { + if (txrate->legacy) { + sinfo->txrate.legacy = txrate->legacy; + } else { + sinfo->txrate.mcs = txrate->mcs; + sinfo->txrate.nss = txrate->nss; + sinfo->txrate.bw = txrate->bw; + sinfo->txrate.he_gi = txrate->he_gi; + sinfo->txrate.he_dcm = txrate->he_dcm; + sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc; + } + sinfo->txrate.flags = txrate->flags; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } - sinfo->txrate.flags = txrate->flags; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); /* offloading flows bypass networking stack, so driver counts and * reports sta statistics via NL80211_STA_INFO when WED is active. @@ -1042,14 +1098,10 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, sinfo->tx_bytes = msta->wcid.stats.tx_bytes; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64); - sinfo->tx_packets = msta->wcid.stats.tx_packets; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); - - sinfo->tx_failed = msta->wcid.stats.tx_failed; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); - - sinfo->tx_retries = msta->wcid.stats.tx_retries; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); + if (!mt7915_mcu_wed_wa_tx_stats(phy->dev, msta->wcid.idx)) { + sinfo->tx_packets = msta->wcid.stats.tx_packets; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); + } if (mtk_wed_get_rx_capa(&phy->dev->mt76.mmio.wed)) { sinfo->rx_bytes = msta->wcid.stats.rx_bytes; @@ -1060,6 +1112,12 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, } } + sinfo->tx_failed = msta->wcid.stats.tx_failed; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); + + sinfo->tx_retries = msta->wcid.stats.tx_retries; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); + sinfo->ack_signal = (s8)msta->ack_signal; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL); @@ -1073,11 +1131,11 @@ static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta) struct mt7915_dev *dev = msta->vif->phy->dev; u32 *changed = data; - spin_lock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); msta->changed |= *changed; if (list_empty(&msta->rc_list)) list_add_tail(&msta->rc_list, &dev->sta_rc_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_unlock_bh(&dev->mt76.sta_poll_lock); } static void mt7915_sta_rc_update(struct ieee80211_hw *hw, @@ -1253,6 +1311,38 @@ static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = { "rx_vec_queue_overflow_drop_cnt", "rx_ba_cnt", + /* muru mu-mimo and ofdma related stats */ + "dl_cck_cnt", + "dl_ofdm_cnt", + "dl_htmix_cnt", + "dl_htgf_cnt", + "dl_vht_su_cnt", + "dl_vht_2mu_cnt", + "dl_vht_3mu_cnt", + "dl_vht_4mu_cnt", + "dl_he_su_cnt", + "dl_he_ext_su_cnt", + "dl_he_2ru_cnt", + "dl_he_2mu_cnt", + "dl_he_3ru_cnt", + "dl_he_3mu_cnt", + "dl_he_4ru_cnt", + "dl_he_4mu_cnt", + "dl_he_5to8ru_cnt", + "dl_he_9to16ru_cnt", + "dl_he_gtr16ru_cnt", + + "ul_hetrig_su_cnt", + "ul_hetrig_2ru_cnt", + "ul_hetrig_3ru_cnt", + "ul_hetrig_4ru_cnt", + "ul_hetrig_5to8ru_cnt", + "ul_hetrig_9to16ru_cnt", + "ul_hetrig_gtr16ru_cnt", + "ul_hetrig_2mu_cnt", + "ul_hetrig_3mu_cnt", + "ul_hetrig_4mu_cnt", + /* per vif counters */ "v_tx_mode_cck", "v_tx_mode_ofdm", @@ -1279,6 +1369,10 @@ static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = { "v_tx_mcs_9", "v_tx_mcs_10", "v_tx_mcs_11", + "v_tx_nss_1", + "v_tx_nss_2", + "v_tx_nss_3", + "v_tx_nss_4", }; #define MT7915_SSTATS_LEN ARRAY_SIZE(mt7915_gstrings_stats) @@ -1326,11 +1420,11 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw, struct mt7915_dev *dev = mt7915_hw_dev(hw); struct mt7915_phy *phy = mt7915_hw_phy(hw); struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + struct mt76_mib_stats *mib = &phy->mib; struct mt76_ethtool_worker_info wi = { .data = data, .idx = mvif->mt76.idx, }; - struct mib_stats *mib = &phy->mib; /* See mt7915_ampdu_stat_read_phy, etc */ int i, ei = 0, stats_size; @@ -1403,6 +1497,37 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw, data[ei++] = mib->rx_vec_queue_overflow_drop_cnt; data[ei++] = mib->rx_ba_cnt; + data[ei++] = mib->dl_cck_cnt; + data[ei++] = mib->dl_ofdm_cnt; + data[ei++] = mib->dl_htmix_cnt; + data[ei++] = mib->dl_htgf_cnt; + data[ei++] = mib->dl_vht_su_cnt; + data[ei++] = mib->dl_vht_2mu_cnt; + data[ei++] = mib->dl_vht_3mu_cnt; + data[ei++] = mib->dl_vht_4mu_cnt; + data[ei++] = mib->dl_he_su_cnt; + data[ei++] = mib->dl_he_ext_su_cnt; + data[ei++] = mib->dl_he_2ru_cnt; + data[ei++] = mib->dl_he_2mu_cnt; + data[ei++] = mib->dl_he_3ru_cnt; + data[ei++] = mib->dl_he_3mu_cnt; + data[ei++] = mib->dl_he_4ru_cnt; + data[ei++] = mib->dl_he_4mu_cnt; + data[ei++] = mib->dl_he_5to8ru_cnt; + data[ei++] = mib->dl_he_9to16ru_cnt; + data[ei++] = mib->dl_he_gtr16ru_cnt; + + data[ei++] = mib->ul_hetrig_su_cnt; + data[ei++] = mib->ul_hetrig_2ru_cnt; + data[ei++] = mib->ul_hetrig_3ru_cnt; + data[ei++] = mib->ul_hetrig_4ru_cnt; + data[ei++] = mib->ul_hetrig_5to8ru_cnt; + data[ei++] = mib->ul_hetrig_9to16ru_cnt; + data[ei++] = mib->ul_hetrig_gtr16ru_cnt; + data[ei++] = mib->ul_hetrig_2mu_cnt; + data[ei++] = mib->ul_hetrig_3mu_cnt; + data[ei++] = mib->ul_hetrig_4mu_cnt; + /* Add values for all stations owned by this vif */ wi.initial_stat_idx = ei; ieee80211_iterate_stations_atomic(hw, mt7915_ethtool_worker, &wi); @@ -1526,6 +1651,8 @@ const struct ieee80211_ops mt7915_ops = { .conf_tx = mt7915_conf_tx, .configure_filter = mt7915_configure_filter, .bss_info_changed = mt7915_bss_info_changed, + .start_ap = mt7915_start_ap, + .stop_ap = mt7915_stop_ap, .sta_add = mt7915_sta_add, .sta_remove = mt7915_sta_remove, .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove, diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 9fcb22fa1f97..50ae7bf3af91 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -13,6 +13,9 @@ case 0x7915: \ _fw = MT7915_##name; \ break; \ + case 0x7981: \ + _fw = MT7981_##name; \ + break; \ case 0x7986: \ _fw = MT7986_##name##__VA_ARGS__; \ break; \ @@ -164,7 +167,9 @@ mt7915_mcu_parse_response(struct mt76_dev *mdev, int cmd, } rxd = (struct mt76_connac2_mcu_rxd *)skb->data; - if (seq != rxd->seq) + if (seq != rxd->seq && + !(rxd->eid == MCU_CMD_EXT_CID && + rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT)) return -EAGAIN; if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) { @@ -274,7 +279,7 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb) r = (struct mt7915_mcu_rdd_report *)skb->data; - if (r->band_idx > MT_BAND1) + if (r->band_idx > MT_RX_SEL2) return; if ((r->band_idx && !dev->phy.mt76->band_idx) && @@ -395,12 +400,14 @@ void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb) struct mt76_connac2_mcu_rxd *rxd; rxd = (struct mt76_connac2_mcu_rxd *)skb->data; - if (rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT || - rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST || - rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP || - rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC || - rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY || - !rxd->seq) + if ((rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT || + rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST || + rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP || + rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC || + rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY || + !rxd->seq) && + !(rxd->eid == MCU_CMD_EXT_CID && + rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT)) mt7915_mcu_rx_unsolicited_event(dev, skb); else mt76_mcu_rx_event(&dev->mt76, skb); @@ -706,6 +713,7 @@ static void mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta, struct ieee80211_vif *vif) { + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem; struct ieee80211_he_mcs_nss_supp mcs_map; struct sta_rec_he *he; @@ -739,7 +747,7 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta, IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G)) cap |= STA_REC_HE_CAP_BW20_RU242_SUPPORT; - if (vif->bss_conf.he_ldpc && + if (mvif->cap.he_ldpc && (elem->phy_cap_info[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)) cap |= STA_REC_HE_CAP_LDPC; @@ -848,6 +856,7 @@ static void mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb, struct ieee80211_sta *sta, struct ieee80211_vif *vif) { + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem; struct sta_rec_muru *muru; struct tlv *tlv; @@ -860,9 +869,9 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb, muru = (struct sta_rec_muru *)tlv; - muru->cfg.mimo_dl_en = vif->bss_conf.he_mu_beamformer || - vif->bss_conf.vht_mu_beamformer || - vif->bss_conf.vht_mu_beamformee; + muru->cfg.mimo_dl_en = mvif->cap.he_mu_ebfer || + mvif->cap.vht_mu_ebfer || + mvif->cap.vht_mu_ebfee; if (!is_mt7915(&dev->mt76)) muru->cfg.mimo_ul_en = true; muru->cfg.ofdma_dl_en = true; @@ -995,8 +1004,8 @@ mt7915_mcu_sta_wtbl_tlv(struct mt7915_dev *dev, struct sk_buff *skb, mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, wcid, tlv, wtbl_hdr); if (sta) mt76_connac_mcu_wtbl_ht_tlv(&dev->mt76, skb, sta, tlv, - wtbl_hdr, vif->bss_conf.ht_ldpc, - vif->bss_conf.vht_ldpc); + wtbl_hdr, mvif->cap.ht_ldpc, + mvif->cap.vht_ldpc); return 0; } @@ -1005,6 +1014,7 @@ static inline bool mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif, struct ieee80211_sta *sta, bool bfee) { + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; int tx_ant = hweight8(phy->mt76->chainmask) - 1; if (vif->type != NL80211_IFTYPE_STATION && @@ -1018,10 +1028,10 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif, struct ieee80211_he_cap_elem *pe = &sta->deflink.he_cap.he_cap_elem; if (bfee) - return vif->bss_conf.he_su_beamformee && + return mvif->cap.he_su_ebfee && HE_PHY(CAP3_SU_BEAMFORMER, pe->phy_cap_info[3]); else - return vif->bss_conf.he_su_beamformer && + return mvif->cap.he_su_ebfer && HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]); } @@ -1029,10 +1039,10 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif, u32 cap = sta->deflink.vht_cap.cap; if (bfee) - return vif->bss_conf.vht_su_beamformee && + return mvif->cap.vht_su_ebfee && (cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE); else - return vif->bss_conf.vht_su_beamformer && + return mvif->cap.vht_su_ebfer && (cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE); } @@ -1527,7 +1537,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, cap |= STA_CAP_TX_STBC; if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) cap |= STA_CAP_RX_STBC; - if (vif->bss_conf.ht_ldpc && + if (mvif->cap.ht_ldpc && (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)) cap |= STA_CAP_LDPC; @@ -1553,7 +1563,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, cap |= STA_CAP_VHT_TX_STBC; if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_1) cap |= STA_CAP_VHT_RX_STBC; - if (vif->bss_conf.vht_ldpc && + if (mvif->cap.vht_ldpc && (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)) cap |= STA_CAP_VHT_LDPC; @@ -2112,12 +2122,11 @@ int mt7915_mcu_muru_debug_set(struct mt7915_dev *dev, bool enabled) sizeof(data), false); } -int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy, void *ms) +int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy) { struct mt7915_dev *dev = phy->dev; struct sk_buff *skb; - struct mt7915_mcu_muru_stats *mu_stats = - (struct mt7915_mcu_muru_stats *)ms; + struct mt7915_mcu_muru_stats *mu_stats; int ret; struct { @@ -2133,7 +2142,43 @@ int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy, void *ms) if (ret) return ret; - memcpy(mu_stats, skb->data, sizeof(struct mt7915_mcu_muru_stats)); + mu_stats = (struct mt7915_mcu_muru_stats *)(skb->data); + + /* accumulate stats, these are clear-on-read */ +#define __dl_u32(s) phy->mib.dl_##s += le32_to_cpu(mu_stats->dl.s) +#define __ul_u32(s) phy->mib.ul_##s += le32_to_cpu(mu_stats->ul.s) + __dl_u32(cck_cnt); + __dl_u32(ofdm_cnt); + __dl_u32(htmix_cnt); + __dl_u32(htgf_cnt); + __dl_u32(vht_su_cnt); + __dl_u32(vht_2mu_cnt); + __dl_u32(vht_3mu_cnt); + __dl_u32(vht_4mu_cnt); + __dl_u32(he_su_cnt); + __dl_u32(he_2ru_cnt); + __dl_u32(he_2mu_cnt); + __dl_u32(he_3ru_cnt); + __dl_u32(he_3mu_cnt); + __dl_u32(he_4ru_cnt); + __dl_u32(he_4mu_cnt); + __dl_u32(he_5to8ru_cnt); + __dl_u32(he_9to16ru_cnt); + __dl_u32(he_gtr16ru_cnt); + + __ul_u32(hetrig_su_cnt); + __ul_u32(hetrig_2ru_cnt); + __ul_u32(hetrig_3ru_cnt); + __ul_u32(hetrig_4ru_cnt); + __ul_u32(hetrig_5to8ru_cnt); + __ul_u32(hetrig_9to16ru_cnt); + __ul_u32(hetrig_gtr16ru_cnt); + __ul_u32(hetrig_2mu_cnt); + __ul_u32(hetrig_3mu_cnt); + __ul_u32(hetrig_4mu_cnt); +#undef __dl_u32 +#undef __ul_u32 + dev_kfree_skb(skb); return 0; @@ -2993,7 +3038,7 @@ int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch) } ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD(GET_MIB_INFO), - req, sizeof(req), true, &skb); + req, len * sizeof(req[0]), true, &skb); if (ret) return ret; @@ -3733,6 +3778,62 @@ int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev, &req, sizeof(req), true); } +int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wlan_idx) +{ + struct { + __le32 cmd; + __le32 num; + __le32 __rsv; + __le16 wlan_idx; + } req = { + .cmd = cpu_to_le32(0x15), + .num = cpu_to_le32(1), + .wlan_idx = cpu_to_le16(wlan_idx), + }; + struct mt7915_mcu_wa_tx_stat { + __le16 wlan_idx; + u8 __rsv[2]; + + /* tx_bytes is deprecated since WA byte counter uses u32, + * which easily leads to overflow. + */ + __le32 tx_bytes; + __le32 tx_packets; + } *res; + struct mt76_wcid *wcid; + struct sk_buff *skb; + int ret; + + ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WA_PARAM_CMD(QUERY), + &req, sizeof(req), true, &skb); + if (ret) + return ret; + + if (!is_mt7915(&dev->mt76)) + skb_pull(skb, 4); + + res = (struct mt7915_mcu_wa_tx_stat *)skb->data; + + if (le16_to_cpu(res->wlan_idx) != wlan_idx) { + ret = -EINVAL; + goto out; + } + + rcu_read_lock(); + + wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]); + if (wcid) + wcid->stats.tx_packets += le32_to_cpu(res->tx_packets); + else + ret = -EINVAL; + + rcu_read_unlock(); +out: + dev_kfree_skb(skb); + + return ret; +} + int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set) { struct { diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c index 45f3558bf31c..fc7ace638ce8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c @@ -417,7 +417,7 @@ static u32 mt7915_reg_map_l1(struct mt7915_dev *dev, u32 addr) u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, addr); u32 l1_remap; - if (is_mt7986(&dev->mt76)) + if (is_mt798x(&dev->mt76)) return MT_CONN_INFRA_OFFSET(addr); l1_remap = is_mt7915(&dev->mt76) ? @@ -447,7 +447,7 @@ static u32 mt7915_reg_map_l2(struct mt7915_dev *dev, u32 addr) /* use read to push write */ dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L2); } else { - u32 ofs = is_mt7986(&dev->mt76) ? 0x400000 : 0; + u32 ofs = is_mt798x(&dev->mt76) ? 0x400000 : 0; offset = FIELD_GET(MT_HIF_REMAP_L2_OFFSET_MT7916, addr); base = FIELD_GET(MT_HIF_REMAP_L2_BASE_MT7916, addr); @@ -545,8 +545,6 @@ static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val) static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed) { struct mt7915_dev *dev; - struct mt7915_phy *phy; - int ret; dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed); @@ -554,43 +552,19 @@ static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed) dev->mt76.token_size = wed->wlan.token_start; spin_unlock_bh(&dev->mt76.token_lock); - ret = wait_event_timeout(dev->mt76.tx_wait, - !dev->mt76.wed_token_count, HZ); - if (!ret) - return -EAGAIN; - - phy = &dev->phy; - mt76_set(dev, MT_AGG_ACR4(phy->mt76->band_idx), MT_AGG_ACR_PPDU_TXS2H); - - phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL; - if (phy) - mt76_set(dev, MT_AGG_ACR4(phy->mt76->band_idx), - MT_AGG_ACR_PPDU_TXS2H); - - return 0; + return !wait_event_timeout(dev->mt76.tx_wait, + !dev->mt76.wed_token_count, HZ); } static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed) { struct mt7915_dev *dev; - struct mt7915_phy *phy; dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed); spin_lock_bh(&dev->mt76.token_lock); dev->mt76.token_size = MT7915_TOKEN_SIZE; spin_unlock_bh(&dev->mt76.token_lock); - - /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than - * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set. - */ - phy = &dev->phy; - mt76_clear(dev, MT_AGG_ACR4(phy->mt76->band_idx), MT_AGG_ACR_PPDU_TXS2H); - - phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL; - if (phy) - mt76_clear(dev, MT_AGG_ACR4(phy->mt76->band_idx), - MT_AGG_ACR_PPDU_TXS2H); } static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed) @@ -785,7 +759,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, wed->wlan.nbuf = MT7915_HW_TOKEN_SIZE; wed->wlan.tx_tbit[0] = is_mt7915(&dev->mt76) ? 4 : 30; wed->wlan.tx_tbit[1] = is_mt7915(&dev->mt76) ? 5 : 31; - wed->wlan.txfree_tbit = is_mt7986(&dev->mt76) ? 2 : 1; + wed->wlan.txfree_tbit = is_mt798x(&dev->mt76) ? 2 : 1; wed->wlan.token_start = MT7915_TOKEN_SIZE - wed->wlan.nbuf; wed->wlan.wcid_512 = !is_mt7915(&dev->mt76); @@ -795,7 +769,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, if (is_mt7915(&dev->mt76)) { wed->wlan.rx_tbit[0] = 16; wed->wlan.rx_tbit[1] = 17; - } else if (is_mt7986(&dev->mt76)) { + } else if (is_mt798x(&dev->mt76)) { wed->wlan.rx_tbit[0] = 22; wed->wlan.rx_tbit[1] = 23; } else { @@ -853,6 +827,7 @@ static int mt7915_mmio_init(struct mt76_dev *mdev, dev->reg.map = mt7916_reg_map; dev->reg.map_size = ARRAY_SIZE(mt7916_reg_map); break; + case 0x7981: case 0x7986: dev->reg.reg_rev = mt7986_reg; dev->reg.offs_rev = mt7916_offs; @@ -1062,8 +1037,8 @@ static int __init mt7915_init(void) if (ret) goto error_pci; - if (IS_ENABLED(CONFIG_MT7986_WMAC)) { - ret = platform_driver_register(&mt7986_wmac_driver); + if (IS_ENABLED(CONFIG_MT798X_WMAC)) { + ret = platform_driver_register(&mt798x_wmac_driver); if (ret) goto error_wmac; } @@ -1080,8 +1055,8 @@ error_pci: static void __exit mt7915_exit(void) { - if (IS_ENABLED(CONFIG_MT7986_WMAC)) - platform_driver_unregister(&mt7986_wmac_driver); + if (IS_ENABLED(CONFIG_MT798X_WMAC)) + platform_driver_unregister(&mt798x_wmac_driver); pci_unregister_driver(&mt7915_pci_driver); pci_unregister_driver(&mt7915_hif_driver); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index b3ead3530740..0456e56f6348 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -34,6 +34,10 @@ #define MT7916_FIRMWARE_WM "mediatek/mt7916_wm.bin" #define MT7916_ROM_PATCH "mediatek/mt7916_rom_patch.bin" +#define MT7981_FIRMWARE_WA "mediatek/mt7981_wa.bin" +#define MT7981_FIRMWARE_WM "mediatek/mt7981_wm.bin" +#define MT7981_ROM_PATCH "mediatek/mt7981_rom_patch.bin" + #define MT7986_FIRMWARE_WA "mediatek/mt7986_wa.bin" #define MT7986_FIRMWARE_WM "mediatek/mt7986_wm.bin" #define MT7986_FIRMWARE_WM_MT7975 "mediatek/mt7986_wm_mt7975.bin" @@ -43,6 +47,9 @@ #define MT7915_EEPROM_DEFAULT "mediatek/mt7915_eeprom.bin" #define MT7915_EEPROM_DEFAULT_DBDC "mediatek/mt7915_eeprom_dbdc.bin" #define MT7916_EEPROM_DEFAULT "mediatek/mt7916_eeprom.bin" + +#define MT7981_EEPROM_MT7976_DEFAULT_DBDC "mediatek/mt7981_eeprom_mt7976_dbdc.bin" + #define MT7986_EEPROM_MT7975_DEFAULT "mediatek/mt7986_eeprom_mt7975.bin" #define MT7986_EEPROM_MT7975_DUAL_DEFAULT "mediatek/mt7986_eeprom_mt7975_dual.bin" #define MT7986_EEPROM_MT7976_DEFAULT "mediatek/mt7986_eeprom_mt7976.bin" @@ -129,7 +136,6 @@ struct mt7915_sta { struct mt7915_vif *vif; - struct list_head poll_list; struct list_head rc_list; u32 airtime_ac[8]; @@ -138,7 +144,6 @@ struct mt7915_sta { unsigned long changed; unsigned long jiffies; - unsigned long ampdu_state; struct mt76_connac_sta_key_conf bip; struct { @@ -147,9 +152,23 @@ struct mt7915_sta { } twt; }; +struct mt7915_vif_cap { + bool ht_ldpc:1; + bool vht_ldpc:1; + bool he_ldpc:1; + bool vht_su_ebfer:1; + bool vht_su_ebfee:1; + bool vht_mu_ebfer:1; + bool vht_mu_ebfee:1; + bool he_su_ebfer:1; + bool he_su_ebfee:1; + bool he_mu_ebfer:1; +}; + struct mt7915_vif { struct mt76_vif mt76; /* must be first */ + struct mt7915_vif_cap cap; struct mt7915_sta sta; struct mt7915_phy *phy; @@ -157,67 +176,6 @@ struct mt7915_vif { struct cfg80211_bitrate_mask bitrate_mask; }; -/* per-phy stats. */ -struct mib_stats { - u32 ack_fail_cnt; - u32 fcs_err_cnt; - u32 rts_cnt; - u32 rts_retries_cnt; - u32 ba_miss_cnt; - u32 tx_bf_cnt; - u32 tx_mu_mpdu_cnt; - u32 tx_mu_acked_mpdu_cnt; - u32 tx_su_acked_mpdu_cnt; - u32 tx_bf_ibf_ppdu_cnt; - u32 tx_bf_ebf_ppdu_cnt; - - u32 tx_bf_rx_fb_all_cnt; - u32 tx_bf_rx_fb_he_cnt; - u32 tx_bf_rx_fb_vht_cnt; - u32 tx_bf_rx_fb_ht_cnt; - - u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */ - u32 tx_bf_rx_fb_nc_cnt; - u32 tx_bf_rx_fb_nr_cnt; - u32 tx_bf_fb_cpl_cnt; - u32 tx_bf_fb_trig_cnt; - - u32 tx_ampdu_cnt; - u32 tx_stop_q_empty_cnt; - u32 tx_mpdu_attempts_cnt; - u32 tx_mpdu_success_cnt; - u32 tx_pkt_ebf_cnt; - u32 tx_pkt_ibf_cnt; - - u32 tx_rwp_fail_cnt; - u32 tx_rwp_need_cnt; - - /* rx stats */ - u32 rx_fifo_full_cnt; - u32 channel_idle_cnt; - u32 primary_cca_busy_time; - u32 secondary_cca_busy_time; - u32 primary_energy_detect_time; - u32 cck_mdrdy_time; - u32 ofdm_mdrdy_time; - u32 green_mdrdy_time; - u32 rx_vector_mismatch_cnt; - u32 rx_delimiter_fail_cnt; - u32 rx_mrdy_cnt; - u32 rx_len_mismatch_cnt; - u32 rx_mpdu_cnt; - u32 rx_ampdu_cnt; - u32 rx_ampdu_bytes_cnt; - u32 rx_ampdu_valid_subframe_cnt; - u32 rx_ampdu_valid_subframe_bytes_cnt; - u32 rx_pfdrop_cnt; - u32 rx_vec_queue_overflow_drop_cnt; - u32 rx_ba_cnt; - - u32 tx_amsdu[8]; - u32 tx_amsdu_cnt; -}; - /* crash-dump */ struct mt7915_crash_data { guid_t guid; @@ -263,7 +221,7 @@ struct mt7915_phy { u32 rx_ampdu_ts; u32 ampdu_ref; - struct mib_stats mib; + struct mt76_mib_stats mib; struct mt76_channel_state state_ts; #ifdef CONFIG_NL80211_TESTMODE @@ -328,9 +286,7 @@ struct mt7915_dev { #endif struct list_head sta_rc_list; - struct list_head sta_poll_list; struct list_head twt_list; - spinlock_t sta_poll_lock; u32 hw_pattern; @@ -420,8 +376,7 @@ mt7915_ext_phy(struct mt7915_dev *dev) static inline u32 mt7915_check_adie(struct mt7915_dev *dev, bool sku) { u32 mask = sku ? MT_CONNINFRA_SKU_MASK : MT_ADIE_TYPE_MASK; - - if (!is_mt7986(&dev->mt76)) + if (!is_mt798x(&dev->mt76)) return 0; return mt76_rr(dev, MT_CONNINFRA_SKU_DEC_ADDR) & mask; @@ -431,9 +386,9 @@ extern const struct ieee80211_ops mt7915_ops; extern const struct mt76_testmode_ops mt7915_testmode_ops; extern struct pci_driver mt7915_pci_driver; extern struct pci_driver mt7915_hif_driver; -extern struct platform_driver mt7986_wmac_driver; +extern struct platform_driver mt798x_wmac_driver; -#ifdef CONFIG_MT7986_WMAC +#ifdef CONFIG_MT798X_WMAC int mt7986_wmac_enable(struct mt7915_dev *dev); void mt7986_wmac_disable(struct mt7915_dev *dev); #else @@ -466,6 +421,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2); void mt7915_dma_prefetch(struct mt7915_dev *dev); void mt7915_dma_cleanup(struct mt7915_dev *dev); int mt7915_dma_reset(struct mt7915_dev *dev, bool force); +int mt7915_dma_start(struct mt7915_dev *dev, bool reset, bool wed_reset); int mt7915_txbf_init(struct mt7915_dev *dev); void mt7915_init_txpower(struct mt7915_dev *dev, struct ieee80211_supported_band *sband); @@ -539,6 +495,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct rate_info *rate); int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy, struct cfg80211_chan_def *chandef); +int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wcid); int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set); int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3); int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl); @@ -612,7 +569,6 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, enum mt76_txq_id qid, struct mt76_wcid *wcid, struct ieee80211_sta *sta, struct mt76_tx_info *tx_info); -void mt7915_tx_token_put(struct mt7915_dev *dev); void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, struct sk_buff *skb, u32 *info); bool mt7915_rx_check(struct mt76_dev *mdev, void *data, int len); @@ -623,7 +579,7 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy); void mt7915_set_stream_vht_txbf_caps(struct mt7915_phy *phy); void mt7915_update_channel(struct mt76_phy *mphy); int mt7915_mcu_muru_debug_set(struct mt7915_dev *dev, bool enable); -int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy, void *ms); +int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy); int mt7915_mcu_wed_enable_rx_stats(struct mt7915_dev *dev); int mt7915_init_debugfs(struct mt7915_phy *phy); void mt7915_debugfs_rx_fw_monitor(struct mt7915_dev *dev, const void *data, int len); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h index c8e478a55081..588cd87e24e9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h @@ -145,6 +145,9 @@ enum offs_rev { #define MT_PLE_BASE 0x820c0000 #define MT_PLE(ofs) (MT_PLE_BASE + (ofs)) +#define MT_PLE_HOST_RPT0 MT_PLE(0x030) +#define MT_PLE_HOST_RPT0_TX_LATENCY BIT(3) + #define MT_FL_Q_EMPTY MT_PLE(__OFFS(PLE_FL_Q_EMPTY)) #define MT_FL_Q0_CTRL MT_PLE(__OFFS(PLE_FL_Q_CTRL)) #define MT_FL_Q2_CTRL MT_PLE(__OFFS(PLE_FL_Q_CTRL) + 0x8) @@ -871,7 +874,12 @@ enum offs_rev { #define MT_AFE_RG_WBG_EN_WPLL_UP_MASK BIT(20) #define MT_AFE_RG_WBG_EN_PLL_UP_MASK (MT_AFE_RG_WBG_EN_BPLL_UP_MASK | \ MT_AFE_RG_WBG_EN_WPLL_UP_MASK) -#define MT_AFE_RG_WBG_EN_TXCAL_MASK GENMASK(21, 17) +#define MT_AFE_RG_WBG_EN_TXCAL_WF4 BIT(29) +#define MT_AFE_RG_WBG_EN_TXCAL_BT BIT(21) +#define MT_AFE_RG_WBG_EN_TXCAL_WF3 BIT(20) +#define MT_AFE_RG_WBG_EN_TXCAL_WF2 BIT(19) +#define MT_AFE_RG_WBG_EN_TXCAL_WF1 BIT(18) +#define MT_AFE_RG_WBG_EN_TXCAL_WF0 BIT(17) #define MT_ADIE_SLP_CTRL_BASE(_band) (0x18005000 + ((_band) << 19)) #define MT_ADIE_SLP_CTRL(_band, ofs) (MT_ADIE_SLP_CTRL_BASE(_band) + (ofs)) @@ -1096,6 +1104,12 @@ enum offs_rev { #define MT_TOP_MCU_EMI_BASE MT_TOP(0x1c4) #define MT_TOP_MCU_EMI_BASE_MASK GENMASK(19, 0) +#define MT_TOP_WF_AP_PERI_BASE MT_TOP(0x1c8) +#define MT_TOP_WF_AP_PERI_BASE_MASK GENMASK(19, 0) + +#define MT_TOP_EFUSE_BASE MT_TOP(0x1cc) +#define MT_TOP_EFUSE_BASE_MASK GENMASK(19, 0) + #define MT_TOP_CONN_INFRA_WAKEUP MT_TOP(0x1a0) #define MT_TOP_CONN_INFRA_WAKEUP_MASK BIT(0) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/soc.c b/drivers/net/wireless/mediatek/mt76/mt7915/soc.c index 701a27ffa4c2..37348b208736 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/soc.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/soc.c @@ -15,6 +15,9 @@ #include "mt7915.h" +#define MT7981_CON_INFRA_VERSION 0x02090000 +#define MT7986_CON_INFRA_VERSION 0x02070000 + /* INFRACFG */ #define MT_INFRACFG_CONN2AP_SLPPROT 0x0d0 #define MT_INFRACFG_AP2CONN_SLPPROT 0x0d4 @@ -166,10 +169,14 @@ static u32 mt76_wmac_rmw(void __iomem *base, u32 offset, u32 mask, u32 val) return val; } -static u8 mt7986_wmac_check_adie_type(struct mt7915_dev *dev) +static u8 mt798x_wmac_check_adie_type(struct mt7915_dev *dev) { u32 val; + /* Only DBDC A-die is used with MT7981 */ + if (is_mt7981(&dev->mt76)) + return ADIE_DBDC; + val = readl(dev->sku + MT_TOP_POS_SKU); return FIELD_GET(MT_TOP_POS_SKU_ADIE_DBDC_MASK, val); @@ -194,7 +201,7 @@ static int mt7986_wmac_gpio_setup(struct mt7915_dev *dev) int ret; u8 type; - type = mt7986_wmac_check_adie_type(dev); + type = mt798x_wmac_check_adie_type(dev); pinctrl = devm_pinctrl_get(dev->mt76.dev); if (IS_ERR(pinctrl)) return PTR_ERR(pinctrl); @@ -256,16 +263,26 @@ static int mt7986_wmac_consys_lockup(struct mt7915_dev *dev, bool enable) return 0; } -static int mt7986_wmac_coninfra_check(struct mt7915_dev *dev) +static int mt798x_wmac_coninfra_check(struct mt7915_dev *dev) { u32 cur; + u32 con_infra_version; + + if (is_mt7981(&dev->mt76)) { + con_infra_version = MT7981_CON_INFRA_VERSION; + } else if (is_mt7986(&dev->mt76)) { + con_infra_version = MT7986_CON_INFRA_VERSION; + } else { + WARN_ON(1); + return -EINVAL; + } - return read_poll_timeout(mt76_rr, cur, (cur == 0x02070000), + return read_poll_timeout(mt76_rr, cur, (cur == con_infra_version), USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, dev, MT_CONN_INFRA_BASE); } -static int mt7986_wmac_coninfra_setup(struct mt7915_dev *dev) +static int mt798x_wmac_coninfra_setup(struct mt7915_dev *dev) { struct device *pdev = dev->mt76.dev; struct reserved_mem *rmem; @@ -283,15 +300,25 @@ static int mt7986_wmac_coninfra_setup(struct mt7915_dev *dev) val = (rmem->base >> 16) & MT_TOP_MCU_EMI_BASE_MASK; - /* Set conninfra subsys PLL check */ - mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS, - MT_INFRA_CKGEN_BUS_RDY_SEL_MASK, 0x1); - mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS, - MT_INFRA_CKGEN_BUS_RDY_SEL_MASK, 0x1); + if (is_mt7986(&dev->mt76)) { + /* Set conninfra subsys PLL check */ + mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS, + MT_INFRA_CKGEN_BUS_RDY_SEL_MASK, 0x1); + mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS, + MT_INFRA_CKGEN_BUS_RDY_SEL_MASK, 0x1); + } mt76_rmw_field(dev, MT_TOP_MCU_EMI_BASE, MT_TOP_MCU_EMI_BASE_MASK, val); + if (is_mt7981(&dev->mt76)) { + mt76_rmw_field(dev, MT_TOP_WF_AP_PERI_BASE, + MT_TOP_WF_AP_PERI_BASE_MASK, 0x300d0000 >> 16); + + mt76_rmw_field(dev, MT_TOP_EFUSE_BASE, + MT_TOP_EFUSE_BASE_MASK, 0x11f20000 >> 16); + } + mt76_wr(dev, MT_INFRA_BUS_EMI_START, rmem->base); mt76_wr(dev, MT_INFRA_BUS_EMI_END, rmem->size); @@ -304,15 +331,18 @@ static int mt7986_wmac_coninfra_setup(struct mt7915_dev *dev) return 0; } -static int mt7986_wmac_sku_setup(struct mt7915_dev *dev, u32 *adie_type) +static int mt798x_wmac_sku_setup(struct mt7915_dev *dev, u32 *adie_type) { int ret; - u32 adie_main, adie_ext; + u32 adie_main = 0, adie_ext = 0; mt76_rmw_field(dev, MT_CONN_INFRA_ADIE_RESET, MT_CONN_INFRA_ADIE1_RESET_MASK, 0x1); - mt76_rmw_field(dev, MT_CONN_INFRA_ADIE_RESET, - MT_CONN_INFRA_ADIE2_RESET_MASK, 0x1); + + if (is_mt7986(&dev->mt76)) { + mt76_rmw_field(dev, MT_CONN_INFRA_ADIE_RESET, + MT_CONN_INFRA_ADIE2_RESET_MASK, 0x1); + } mt76_wmac_spi_lock(dev); @@ -320,9 +350,11 @@ static int mt7986_wmac_sku_setup(struct mt7915_dev *dev, u32 *adie_type) if (ret) goto out; - ret = mt76_wmac_spi_read(dev, 1, MT_ADIE_CHIP_ID, &adie_ext); - if (ret) - goto out; + if (is_mt7986(&dev->mt76)) { + ret = mt76_wmac_spi_read(dev, 1, MT_ADIE_CHIP_ID, &adie_ext); + if (ret) + goto out; + } *adie_type = FIELD_GET(MT_ADIE_CHIP_ID_MASK, adie_main) | (MT_ADIE_CHIP_ID_MASK & adie_ext); @@ -469,7 +501,7 @@ static int mt7986_wmac_adie_xtal_trim_7976(struct mt7915_dev *dev, u8 adie) return ret; } -static int mt7986_wmac_adie_patch_7976(struct mt7915_dev *dev, u8 adie) +static int mt798x_wmac_adie_patch_7976(struct mt7915_dev *dev, u8 adie) { u32 id, version, rg_xo_01, rg_xo_03; int ret; @@ -488,7 +520,14 @@ static int mt7986_wmac_adie_patch_7976(struct mt7915_dev *dev, u8 adie) rg_xo_01 = 0x1d59080f; rg_xo_03 = 0x34c00fe0; } else { - rg_xo_01 = 0x1959f80f; + if (is_mt7981(&dev->mt76)) { + rg_xo_01 = 0x1959c80f; + } else if (is_mt7986(&dev->mt76)) { + rg_xo_01 = 0x1959f80f; + } else { + WARN_ON(1); + return -EINVAL; + } rg_xo_03 = 0x34d00fe0; } @@ -610,7 +649,15 @@ static int mt7986_wmac_adie_patch_7975(struct mt7915_dev *dev, u8 adie) return ret; /* turn on SX0 LTBUF */ - ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000002); + if (is_mt7981(&dev->mt76)) { + ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000007); + } else if (is_mt7986(&dev->mt76)) { + ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000002); + } else { + WARN_ON(1); + return -EINVAL; + } + if (ret) return ret; @@ -657,7 +704,10 @@ static int mt7986_wmac_adie_patch_7975(struct mt7915_dev *dev, u8 adie) return ret; /* set CKB driving and filter */ - return mt76_wmac_spi_write(dev, adie, 0x2c8, 0x00000072); + if (is_mt7986(&dev->mt76)) + return mt76_wmac_spi_write(dev, adie, 0x2c8, 0x00000072); + + return ret; } static int mt7986_wmac_adie_cfg(struct mt7915_dev *dev, u8 adie, u32 adie_type) @@ -685,7 +735,7 @@ static int mt7986_wmac_adie_cfg(struct mt7915_dev *dev, u8 adie, u32 adie_type) ret = mt7986_wmac_adie_patch_7975(dev, adie); } else if (is_7976(dev, adie, adie_type)) { - if (mt7986_wmac_check_adie_type(dev) == ADIE_DBDC) { + if (mt798x_wmac_check_adie_type(dev) == ADIE_DBDC) { ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_WRI_CK_SEL, 0x1c); if (ret) @@ -700,7 +750,7 @@ static int mt7986_wmac_adie_cfg(struct mt7915_dev *dev, u8 adie, u32 adie_type) if (ret) goto out; - ret = mt7986_wmac_adie_patch_7976(dev, adie); + ret = mt798x_wmac_adie_patch_7976(dev, adie); } out: mt76_wmac_spi_unlock(dev); @@ -713,6 +763,7 @@ mt7986_wmac_afe_cal(struct mt7915_dev *dev, u8 adie, bool dbdc, u32 adie_type) { int ret; u8 idx; + u32 txcal; mt76_wmac_spi_lock(dev); if (is_7975(dev, adie, adie_type)) @@ -743,12 +794,18 @@ mt7986_wmac_afe_cal(struct mt7915_dev *dev, u8 adie, bool dbdc, u32 adie_type) MT_AFE_RG_WBG_EN_WPLL_UP_MASK, 0x1); usleep_range(60, 100); - mt76_rmw_field(dev, MT_AFE_DIG_EN_01(idx), - MT_AFE_RG_WBG_EN_TXCAL_MASK, 0x1f); + txcal = (MT_AFE_RG_WBG_EN_TXCAL_BT | + MT_AFE_RG_WBG_EN_TXCAL_WF0 | + MT_AFE_RG_WBG_EN_TXCAL_WF1 | + MT_AFE_RG_WBG_EN_TXCAL_WF2 | + MT_AFE_RG_WBG_EN_TXCAL_WF3); + if (is_mt7981(&dev->mt76)) + txcal |= MT_AFE_RG_WBG_EN_TXCAL_WF4; + + mt76_set(dev, MT_AFE_DIG_EN_01(idx), txcal); usleep_range(800, 1000); - mt76_rmw(dev, MT_AFE_DIG_EN_01(idx), - MT_AFE_RG_WBG_EN_TXCAL_MASK, 0x0); + mt76_clear(dev, MT_AFE_DIG_EN_01(idx), txcal); mt76_rmw(dev, MT_AFE_DIG_EN_03(idx), MT_AFE_RG_WBG_EN_PLL_UP_MASK, 0x0); @@ -805,7 +862,7 @@ static int mt7986_wmac_bus_timeout(struct mt7915_dev *dev) mt76_rmw_field(dev, MT_INFRA_BUS_ON_TIMEOUT, MT_INFRA_BUS_TIMEOUT_EN_MASK, 0xf); - return mt7986_wmac_coninfra_check(dev); + return mt798x_wmac_coninfra_check(dev); } static void mt7986_wmac_clock_enable(struct mt7915_dev *dev, u32 adie_type) @@ -875,14 +932,15 @@ static int mt7986_wmac_top_wfsys_wakeup(struct mt7915_dev *dev, bool enable) if (!enable) return 0; - return mt7986_wmac_coninfra_check(dev); + return mt798x_wmac_coninfra_check(dev); } static int mt7986_wmac_wm_enable(struct mt7915_dev *dev, bool enable) { u32 cur; - mt76_wr(dev, MT_CONNINFRA_SKU_DEC_ADDR, 0); + if (is_mt7986(&dev->mt76)) + mt76_wr(dev, MT_CONNINFRA_SKU_DEC_ADDR, 0); mt76_rmw_field(dev, MT7986_TOP_WM_RESET, MT7986_TOP_WM_RESET_MASK, enable); @@ -1005,7 +1063,7 @@ mt7986_wmac_adie_setup(struct mt7915_dev *dev, u8 adie, u32 adie_type) if (ret) return ret; - if (!adie && (mt7986_wmac_check_adie_type(dev) == ADIE_DBDC)) + if (!adie && (mt798x_wmac_check_adie_type(dev) == ADIE_DBDC)) ret = mt7986_wmac_afe_cal(dev, adie, true, adie_type); return ret; @@ -1060,15 +1118,15 @@ int mt7986_wmac_enable(struct mt7915_dev *dev) if (ret) return ret; - ret = mt7986_wmac_coninfra_check(dev); + ret = mt798x_wmac_coninfra_check(dev); if (ret) return ret; - ret = mt7986_wmac_coninfra_setup(dev); + ret = mt798x_wmac_coninfra_setup(dev); if (ret) return ret; - ret = mt7986_wmac_sku_setup(dev, &adie_type); + ret = mt798x_wmac_sku_setup(dev, &adie_type); if (ret) return ret; @@ -1076,9 +1134,12 @@ int mt7986_wmac_enable(struct mt7915_dev *dev) if (ret) return ret; - ret = mt7986_wmac_adie_setup(dev, 1, adie_type); - if (ret) - return ret; + /* mt7981 doesn't support a second a-die */ + if (is_mt7986(&dev->mt76)) { + ret = mt7986_wmac_adie_setup(dev, 1, adie_type); + if (ret) + return ret; + } ret = mt7986_wmac_subsys_powerup(dev, adie_type); if (ret) @@ -1131,7 +1192,7 @@ void mt7986_wmac_disable(struct mt7915_dev *dev) mt7986_wmac_consys_reset(dev, false); } -static int mt7986_wmac_init(struct mt7915_dev *dev) +static int mt798x_wmac_init(struct mt7915_dev *dev) { struct device *pdev = dev->mt76.dev; struct platform_device *pfdev = to_platform_device(pdev); @@ -1164,7 +1225,7 @@ static int mt7986_wmac_init(struct mt7915_dev *dev) return 0; } -static int mt7986_wmac_probe(struct platform_device *pdev) +static int mt798x_wmac_probe(struct platform_device *pdev) { void __iomem *mem_base; struct mt7915_dev *dev; @@ -1202,7 +1263,7 @@ static int mt7986_wmac_probe(struct platform_device *pdev) if (ret) goto free_device; - ret = mt7986_wmac_init(dev); + ret = mt798x_wmac_init(dev); if (ret) goto free_irq; @@ -1224,7 +1285,7 @@ free_device: return ret; } -static int mt7986_wmac_remove(struct platform_device *pdev) +static int mt798x_wmac_remove(struct platform_device *pdev) { struct mt7915_dev *dev = platform_get_drvdata(pdev); @@ -1233,20 +1294,21 @@ static int mt7986_wmac_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id mt7986_wmac_of_match[] = { +static const struct of_device_id mt798x_wmac_of_match[] = { + { .compatible = "mediatek,mt7981-wmac", .data = (u32 *)0x7981 }, { .compatible = "mediatek,mt7986-wmac", .data = (u32 *)0x7986 }, {}, }; -MODULE_DEVICE_TABLE(of, mt7986_wmac_of_match); +MODULE_DEVICE_TABLE(of, mt798x_wmac_of_match); -struct platform_driver mt7986_wmac_driver = { +struct platform_driver mt798x_wmac_driver = { .driver = { - .name = "mt7986-wmac", - .of_match_table = mt7986_wmac_of_match, + .name = "mt798x-wmac", + .of_match_table = mt798x_wmac_of_match, }, - .probe = mt7986_wmac_probe, - .remove = mt7986_wmac_remove, + .probe = mt798x_wmac_probe, + .remove = mt798x_wmac_remove, }; MODULE_FIRMWARE(MT7986_FIRMWARE_WA); @@ -1254,3 +1316,7 @@ MODULE_FIRMWARE(MT7986_FIRMWARE_WM); MODULE_FIRMWARE(MT7986_FIRMWARE_WM_MT7975); MODULE_FIRMWARE(MT7986_ROM_PATCH); MODULE_FIRMWARE(MT7986_ROM_PATCH_MT7975); + +MODULE_FIRMWARE(MT7981_FIRMWARE_WA); +MODULE_FIRMWARE(MT7981_FIRMWARE_WM); +MODULE_FIRMWARE(MT7981_ROM_PATCH); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/Kconfig b/drivers/net/wireless/mediatek/mt76/mt7921/Kconfig index adff2d7350b5..7ed51e057857 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/Kconfig +++ b/drivers/net/wireless/mediatek/mt76/mt7921/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: ISC config MT7921_COMMON tristate - select MT76_CONNAC_LIB + select MT792x_LIB select WANT_DEV_COREDUMP config MT7921E @@ -27,7 +27,7 @@ config MT7921S config MT7921U tristate "MediaTek MT7921U (USB) support" - select MT76_USB + select MT792x_USB select MT7921_COMMON depends on MAC80211 depends on USB diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/Makefile b/drivers/net/wireless/mediatek/mt76/mt7921/Makefile index e5d2d2e131a2..849be9e848e0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/Makefile +++ b/drivers/net/wireless/mediatek/mt76/mt7921/Makefile @@ -5,11 +5,8 @@ obj-$(CONFIG_MT7921E) += mt7921e.o obj-$(CONFIG_MT7921S) += mt7921s.o obj-$(CONFIG_MT7921U) += mt7921u.o -CFLAGS_trace.o := -I$(src) - -mt7921-common-y := mac.o mcu.o main.o init.o debugfs.o trace.o +mt7921-common-y := mac.o mcu.o main.o init.o debugfs.o mt7921-common-$(CONFIG_NL80211_TESTMODE) += testmode.o -mt7921-common-$(CONFIG_ACPI) += acpi_sar.o -mt7921e-y := pci.o pci_mac.o pci_mcu.o dma.o +mt7921e-y := pci.o pci_mac.o pci_mcu.o mt7921s-y := sdio.o sdio_mac.o sdio_mcu.o -mt7921u-y := usb.o usb_mac.o +mt7921u-y := usb.o diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h deleted file mode 100644 index 6f2c4a572572..000000000000 --- a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h +++ /dev/null @@ -1,105 +0,0 @@ -/* SPDX-License-Identifier: ISC */ -/* Copyright (C) 2022 MediaTek Inc. */ - -#ifndef __MT7921_ACPI_SAR_H -#define __MT7921_ACPI_SAR_H - -#define MT7921_ASAR_MIN_DYN 1 -#define MT7921_ASAR_MAX_DYN 8 -#define MT7921_ASAR_MIN_GEO 3 -#define MT7921_ASAR_MAX_GEO 8 -#define MT7921_ASAR_MIN_FG 8 - -#define MT7921_ACPI_MTCL "MTCL" -#define MT7921_ACPI_MTDS "MTDS" -#define MT7921_ACPI_MTGS "MTGS" -#define MT7921_ACPI_MTFG "MTFG" - -struct mt7921_asar_dyn_limit { - u8 idx; - u8 frp[5]; -} __packed; - -struct mt7921_asar_dyn { - u8 names[4]; - u8 enable; - u8 nr_tbl; - DECLARE_FLEX_ARRAY(struct mt7921_asar_dyn_limit, tbl); -} __packed; - -struct mt7921_asar_dyn_limit_v2 { - u8 idx; - u8 frp[11]; -} __packed; - -struct mt7921_asar_dyn_v2 { - u8 names[4]; - u8 enable; - u8 rsvd; - u8 nr_tbl; - DECLARE_FLEX_ARRAY(struct mt7921_asar_dyn_limit_v2, tbl); -} __packed; - -struct mt7921_asar_geo_band { - u8 pwr; - u8 offset; -} __packed; - -struct mt7921_asar_geo_limit { - u8 idx; - /* 0:2G, 1:5G */ - struct mt7921_asar_geo_band band[2]; -} __packed; - -struct mt7921_asar_geo { - u8 names[4]; - u8 version; - u8 nr_tbl; - DECLARE_FLEX_ARRAY(struct mt7921_asar_geo_limit, tbl); -} __packed; - -struct mt7921_asar_geo_limit_v2 { - u8 idx; - /* 0:2G, 1:5G, 2:6G */ - struct mt7921_asar_geo_band band[3]; -} __packed; - -struct mt7921_asar_geo_v2 { - u8 names[4]; - u8 version; - u8 rsvd; - u8 nr_tbl; - DECLARE_FLEX_ARRAY(struct mt7921_asar_geo_limit_v2, tbl); -} __packed; - -struct mt7921_asar_cl { - u8 names[4]; - u8 version; - u8 mode_6g; - u8 cl6g[6]; -} __packed; - -struct mt7921_asar_fg { - u8 names[4]; - u8 version; - u8 rsvd; - u8 nr_flag; - u8 rsvd1; - u8 flag[]; -} __packed; - -struct mt7921_acpi_sar { - u8 ver; - union { - struct mt7921_asar_dyn *dyn; - struct mt7921_asar_dyn_v2 *dyn_v2; - }; - union { - struct mt7921_asar_geo *geo; - struct mt7921_asar_geo_v2 *geo_v2; - }; - struct mt7921_asar_cl *countrylist; - struct mt7921_asar_fg *fg; -}; - -#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c index d6b6edba2fec..616b66a3fde2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c @@ -6,11 +6,11 @@ static int mt7921_reg_set(void *data, u64 val) { - struct mt7921_dev *dev = data; + struct mt792x_dev *dev = data; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); mt76_wr(dev, dev->mt76.debugfs_reg, val); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return 0; } @@ -18,11 +18,11 @@ mt7921_reg_set(void *data, u64 val) static int mt7921_reg_get(void *data, u64 *val) { - struct mt7921_dev *dev = data; + struct mt792x_dev *dev = data; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); *val = mt76_rr(dev, dev->mt76.debugfs_reg); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return 0; } @@ -32,14 +32,14 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mt7921_reg_get, mt7921_reg_set, static int mt7921_fw_debug_set(void *data, u64 val) { - struct mt7921_dev *dev = data; + struct mt792x_dev *dev = data; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); dev->fw_debug = (u8)val; mt7921_mcu_fw_log_2_host(dev, dev->fw_debug); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return 0; } @@ -47,7 +47,7 @@ mt7921_fw_debug_set(void *data, u64 val) static int mt7921_fw_debug_get(void *data, u64 *val) { - struct mt7921_dev *dev = data; + struct mt792x_dev *dev = data; *val = dev->fw_debug; @@ -57,128 +57,7 @@ mt7921_fw_debug_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7921_fw_debug_get, mt7921_fw_debug_set, "%lld\n"); -static void -mt7921_ampdu_stat_read_phy(struct mt7921_phy *phy, - struct seq_file *file) -{ - struct mt7921_dev *dev = file->private; - int bound[15], range[4], i; - - if (!phy) - return; - - mt7921_mac_update_mib_stats(phy); - - /* Tx ampdu stat */ - for (i = 0; i < ARRAY_SIZE(range); i++) - range[i] = mt76_rr(dev, MT_MIB_ARNG(0, i)); - - for (i = 0; i < ARRAY_SIZE(bound); i++) - bound[i] = MT_MIB_ARNCR_RANGE(range[i / 4], i % 4) + 1; - - seq_printf(file, "\nPhy0\n"); - - seq_printf(file, "Length: %8d | ", bound[0]); - for (i = 0; i < ARRAY_SIZE(bound) - 1; i++) - seq_printf(file, "%3d %3d | ", bound[i] + 1, bound[i + 1]); - - seq_puts(file, "\nCount: "); - for (i = 0; i < ARRAY_SIZE(bound); i++) - seq_printf(file, "%8d | ", phy->mt76->aggr_stats[i]); - seq_puts(file, "\n"); - - seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt); -} - -static int -mt7921_tx_stats_show(struct seq_file *file, void *data) -{ - struct mt7921_dev *dev = file->private; - struct mt7921_phy *phy = &dev->phy; - struct mib_stats *mib = &phy->mib; - int i; - - mt7921_mutex_acquire(dev); - - mt7921_ampdu_stat_read_phy(phy, file); - - seq_puts(file, "Tx MSDU stat:\n"); - for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++) { - seq_printf(file, "AMSDU pack count of %d MSDU in TXD: %8d ", - i + 1, mib->tx_amsdu[i]); - if (mib->tx_amsdu_cnt) - seq_printf(file, "(%3d%%)\n", - mib->tx_amsdu[i] * 100 / mib->tx_amsdu_cnt); - else - seq_puts(file, "\n"); - } - - mt7921_mutex_release(dev); - - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(mt7921_tx_stats); - -static int -mt7921_queues_acq(struct seq_file *s, void *data) -{ - struct mt7921_dev *dev = dev_get_drvdata(s->private); - int i; - - mt7921_mutex_acquire(dev); - - for (i = 0; i < 4; i++) { - u32 ctrl, val, qlen = 0; - int j; - - val = mt76_rr(dev, MT_PLE_AC_QEMPTY(i)); - ctrl = BIT(31) | BIT(11) | (i << 24); - - for (j = 0; j < 32; j++) { - if (val & BIT(j)) - continue; - - mt76_wr(dev, MT_PLE_FL_Q0_CTRL, ctrl | j); - qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL, - GENMASK(11, 0)); - } - seq_printf(s, "AC%d: queued=%d\n", i, qlen); - } - - mt7921_mutex_release(dev); - - return 0; -} - -static int -mt7921_queues_read(struct seq_file *s, void *data) -{ - struct mt7921_dev *dev = dev_get_drvdata(s->private); - struct { - struct mt76_queue *q; - char *queue; - } queue_map[] = { - { dev->mphy.q_tx[MT_TXQ_BE], "WFDMA0" }, - { dev->mt76.q_mcu[MT_MCUQ_WM], "MCUWM" }, - { dev->mt76.q_mcu[MT_MCUQ_FWDL], "MCUFWQ" }, - }; - int i; - - for (i = 0; i < ARRAY_SIZE(queue_map); i++) { - struct mt76_queue *q = queue_map[i].q; - - if (!q) - continue; - - seq_printf(s, - "%s: queued=%d head=%d tail=%d\n", - queue_map[i].queue, q->queued, q->head, - q->tail); - } - - return 0; -} +DEFINE_SHOW_ATTRIBUTE(mt792x_tx_stats); static void mt7921_seq_puts_array(struct seq_file *file, const char *str, @@ -211,13 +90,13 @@ mt7921_seq_puts_array(struct seq_file *file, const char *str, static int mt7921_txpwr(struct seq_file *s, void *data) { - struct mt7921_dev *dev = dev_get_drvdata(s->private); + struct mt792x_dev *dev = dev_get_drvdata(s->private); struct mt7921_txpwr txpwr; int ret; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); ret = mt7921_get_txpwr_info(dev, &txpwr); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); if (ret) return ret; @@ -263,7 +142,7 @@ mt7921_txpwr(struct seq_file *s, void *data) static int mt7921_pm_set(void *data, u64 val) { - struct mt7921_dev *dev = data; + struct mt792x_dev *dev = data; struct mt76_connac_pm *pm = &dev->pm; if (mt76_is_usb(&dev->mt76)) @@ -296,7 +175,7 @@ out: static int mt7921_pm_get(void *data, u64 *val) { - struct mt7921_dev *dev = data; + struct mt792x_dev *dev = data; *val = dev->pm.enable_user; @@ -308,7 +187,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7921_pm_get, mt7921_pm_set, "%lld\n"); static int mt7921_deep_sleep_set(void *data, u64 val) { - struct mt7921_dev *dev = data; + struct mt792x_dev *dev = data; struct mt76_connac_pm *pm = &dev->pm; bool monitor = !!(dev->mphy.hw->conf.flags & IEEE80211_CONF_MONITOR); bool enable = !!val; @@ -316,7 +195,7 @@ mt7921_deep_sleep_set(void *data, u64 val) if (mt76_is_usb(&dev->mt76)) return -EOPNOTSUPP; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); if (pm->ds_enable_user == enable) goto out; @@ -324,7 +203,7 @@ mt7921_deep_sleep_set(void *data, u64 val) pm->ds_enable = enable && !monitor; mt76_connac_mcu_set_deep_sleep(&dev->mt76, pm->ds_enable); out: - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return 0; } @@ -332,7 +211,7 @@ out: static int mt7921_deep_sleep_get(void *data, u64 *val) { - struct mt7921_dev *dev = data; + struct mt792x_dev *dev = data; *val = dev->pm.ds_enable_user; @@ -342,67 +221,24 @@ mt7921_deep_sleep_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(fops_ds, mt7921_deep_sleep_get, mt7921_deep_sleep_set, "%lld\n"); -static int -mt7921_pm_stats(struct seq_file *s, void *data) -{ - struct mt7921_dev *dev = dev_get_drvdata(s->private); - struct mt76_connac_pm *pm = &dev->pm; - - unsigned long awake_time = pm->stats.awake_time; - unsigned long doze_time = pm->stats.doze_time; - - if (!test_bit(MT76_STATE_PM, &dev->mphy.state)) - awake_time += jiffies - pm->stats.last_wake_event; - else - doze_time += jiffies - pm->stats.last_doze_event; - - seq_printf(s, "awake time: %14u\ndoze time: %15u\n", - jiffies_to_msecs(awake_time), - jiffies_to_msecs(doze_time)); - - seq_printf(s, "low power wakes: %9d\n", pm->stats.lp_wake); - - return 0; -} - -static int -mt7921_pm_idle_timeout_set(void *data, u64 val) -{ - struct mt7921_dev *dev = data; - - dev->pm.idle_timeout = msecs_to_jiffies(val); - - return 0; -} - -static int -mt7921_pm_idle_timeout_get(void *data, u64 *val) -{ - struct mt7921_dev *dev = data; - - *val = jiffies_to_msecs(dev->pm.idle_timeout); - - return 0; -} - -DEFINE_DEBUGFS_ATTRIBUTE(fops_pm_idle_timeout, mt7921_pm_idle_timeout_get, - mt7921_pm_idle_timeout_set, "%lld\n"); +DEFINE_DEBUGFS_ATTRIBUTE(fops_pm_idle_timeout, mt792x_pm_idle_timeout_get, + mt792x_pm_idle_timeout_set, "%lld\n"); static int mt7921_chip_reset(void *data, u64 val) { - struct mt7921_dev *dev = data; + struct mt792x_dev *dev = data; int ret = 0; switch (val) { case 1: /* Reset wifisys directly. */ - mt7921_reset(&dev->mt76); + mt792x_reset(&dev->mt76); break; default: /* Collect the core dump before reset wifisys. */ - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); ret = mt76_connac_mcu_chip_config(&dev->mt76); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); break; } @@ -414,7 +250,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_reset, NULL, mt7921_chip_reset, "%lld\n"); static int mt7921s_sched_quota_read(struct seq_file *s, void *data) { - struct mt7921_dev *dev = dev_get_drvdata(s->private); + struct mt792x_dev *dev = dev_get_drvdata(s->private); struct mt76_sdio *sdio = &dev->mt76.sdio; seq_printf(s, "pse_data_quota\t%d\n", sdio->sched.pse_data_quota); @@ -425,7 +261,7 @@ mt7921s_sched_quota_read(struct seq_file *s, void *data) return 0; } -int mt7921_init_debugfs(struct mt7921_dev *dev) +int mt7921_init_debugfs(struct mt792x_dev *dev) { struct dentry *dir; @@ -435,23 +271,23 @@ int mt7921_init_debugfs(struct mt7921_dev *dev) if (mt76_is_mmio(&dev->mt76)) debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", - dir, mt7921_queues_read); + dir, mt792x_queues_read); else debugfs_create_devm_seqfile(dev->mt76.dev, "xmit-queues", dir, mt76_queues_read); debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir, - mt7921_queues_acq); + mt792x_queues_acq); debugfs_create_devm_seqfile(dev->mt76.dev, "txpower_sku", dir, mt7921_txpwr); - debugfs_create_file("tx_stats", 0400, dir, dev, &mt7921_tx_stats_fops); + debugfs_create_file("tx_stats", 0400, dir, dev, &mt792x_tx_stats_fops); debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug); debugfs_create_file("runtime-pm", 0600, dir, dev, &fops_pm); debugfs_create_file("idle-timeout", 0600, dir, dev, &fops_pm_idle_timeout); debugfs_create_file("chip_reset", 0600, dir, dev, &fops_reset); debugfs_create_devm_seqfile(dev->mt76.dev, "runtime_pm_stats", dir, - mt7921_pm_stats); + mt792x_pm_stats); debugfs_create_file("deep-sleep", 0600, dir, dev, &fops_ds); if (mt76_is_sdio(&dev->mt76)) debugfs_create_devm_seqfile(dev->mt76.dev, "sched-quota", dir, diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c index bf1da9fddfab..ff63f37f67d9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -2,259 +2,84 @@ /* Copyright (C) 2020 MediaTek Inc. */ #include <linux/etherdevice.h> +#include <linux/hwmon.h> +#include <linux/hwmon-sysfs.h> +#include <linux/thermal.h> #include <linux/firmware.h> #include "mt7921.h" #include "../mt76_connac2_mac.h" #include "mcu.h" -static const struct ieee80211_iface_limit if_limits[] = { - { - .max = MT7921_MAX_INTERFACES, - .types = BIT(NL80211_IFTYPE_STATION) - }, - { - .max = 1, - .types = BIT(NL80211_IFTYPE_AP) +static ssize_t mt7921_thermal_temp_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + switch (to_sensor_dev_attr(attr)->index) { + case 0: { + struct mt792x_phy *phy = dev_get_drvdata(dev); + struct mt792x_dev *mdev = phy->dev; + int temperature; + + mt792x_mutex_acquire(mdev); + temperature = mt7921_mcu_get_temperature(phy); + mt792x_mutex_release(mdev); + + if (temperature < 0) + return temperature; + /* display in millidegree Celsius */ + return sprintf(buf, "%u\n", temperature * 1000); } -}; + default: + return -EINVAL; + } +} +static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7921_thermal_temp, 0); -static const struct ieee80211_iface_combination if_comb[] = { - { - .limits = if_limits, - .n_limits = ARRAY_SIZE(if_limits), - .max_interfaces = MT7921_MAX_INTERFACES, - .num_different_channels = 1, - .beacon_int_infra_match = true, - }, +static struct attribute *mt7921_hwmon_attrs[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + NULL, }; +ATTRIBUTE_GROUPS(mt7921_hwmon); -static const struct ieee80211_iface_limit if_limits_chanctx[] = { - { - .max = 2, - .types = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_P2P_CLIENT) - }, - { - .max = 1, - .types = BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_P2P_GO) - } -}; +static int mt7921_thermal_init(struct mt792x_phy *phy) +{ + struct wiphy *wiphy = phy->mt76->hw->wiphy; + struct device *hwmon; + const char *name; -static const struct ieee80211_iface_combination if_comb_chanctx[] = { - { - .limits = if_limits_chanctx, - .n_limits = ARRAY_SIZE(if_limits_chanctx), - .max_interfaces = 2, - .num_different_channels = 2, - .beacon_int_infra_match = false, - } -}; + if (!IS_REACHABLE(CONFIG_HWMON)) + return 0; + + name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7921_%s", + wiphy_name(wiphy)); + + hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy, + mt7921_hwmon_groups); + if (IS_ERR(hwmon)) + return PTR_ERR(hwmon); + + return 0; +} static void mt7921_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request) { struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2)); dev->mt76.region = request->dfs_region; dev->country_ie_env = request->country_ie_env; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); mt7921_mcu_set_clc(dev, request->alpha2, request->country_ie_env); mt76_connac_mcu_set_channel_domain(hw->priv); mt7921_set_tx_sar_pwr(hw, NULL); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); } -static int -mt7921_init_wiphy(struct ieee80211_hw *hw) -{ - struct mt7921_phy *phy = mt7921_hw_phy(hw); - struct mt7921_dev *dev = phy->dev; - struct wiphy *wiphy = hw->wiphy; - - hw->queues = 4; - hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE; - hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE; - hw->netdev_features = NETIF_F_RXCSUM; - - hw->radiotap_timestamp.units_pos = - IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US; - - phy->slottime = 9; - - hw->sta_data_size = sizeof(struct mt7921_sta); - hw->vif_data_size = sizeof(struct mt7921_vif); - - if (dev->fw_features & MT7921_FW_CAP_CNM) { - wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; - wiphy->iface_combinations = if_comb_chanctx; - wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_chanctx); - } else { - wiphy->flags &= ~WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; - wiphy->iface_combinations = if_comb; - wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); - } - wiphy->flags &= ~(WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_4ADDR_AP | - WIPHY_FLAG_4ADDR_STATION); - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_P2P_GO); - wiphy->max_remain_on_channel_duration = 5000; - wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN; - wiphy->max_scan_ssids = 4; - wiphy->max_sched_scan_plan_interval = - MT76_CONNAC_MAX_TIME_SCHED_SCAN_INTERVAL; - wiphy->max_sched_scan_ie_len = IEEE80211_MAX_DATA_LEN; - wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID; - wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH; - wiphy->max_sched_scan_reqs = 1; - wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; - wiphy->reg_notifier = mt7921_regd_notifier; - - wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR | - NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; - wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL); - wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_LEGACY); - wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT); - wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT); - wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE); - wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); - wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); - - ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); - ieee80211_hw_set(hw, HAS_RATE_CONTROL); - ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD); - ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD); - ieee80211_hw_set(hw, WANT_MONITOR_VIF); - ieee80211_hw_set(hw, SUPPORTS_PS); - ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); - ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); - ieee80211_hw_set(hw, CONNECTION_MONITOR); - - if (dev->pm.enable) - ieee80211_hw_set(hw, CONNECTION_MONITOR); - - hw->max_tx_fragments = 4; - - return 0; -} - -static void -mt7921_mac_init_band(struct mt7921_dev *dev, u8 band) -{ - u32 mask, set; - - mt76_rmw_field(dev, MT_TMAC_CTCR0(band), - MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f); - mt76_set(dev, MT_TMAC_CTCR0(band), - MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN | - MT_TMAC_CTCR0_INS_DDLMT_EN); - - mt76_set(dev, MT_WF_RMAC_MIB_TIME0(band), MT_WF_RMAC_MIB_RXTIME_EN); - mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(band), MT_WF_RMAC_MIB_RXTIME_EN); - - /* enable MIB tx-rx time reporting */ - mt76_set(dev, MT_MIB_SCR1(band), MT_MIB_TXDUR_EN); - mt76_set(dev, MT_MIB_SCR1(band), MT_MIB_RXDUR_EN); - - mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_MAX_RX_LEN, 1536); - /* disable rx rate report by default due to hw issues */ - mt76_clear(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN); - - /* filter out non-resp frames and get instantaneous signal reporting */ - mask = MT_WTBLOFF_TOP_RSCR_RCPI_MODE | MT_WTBLOFF_TOP_RSCR_RCPI_PARAM; - set = FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_MODE, 0) | - FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_PARAM, 0x3); - mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set); -} - -static u8 -mt7921_get_offload_capability(struct device *dev, const char *fw_wm) -{ - const struct mt76_connac2_fw_trailer *hdr; - struct mt7921_realease_info *rel_info; - const struct firmware *fw; - int ret, i, offset = 0; - const u8 *data, *end; - u8 offload_caps = 0; - - ret = request_firmware(&fw, fw_wm, dev); - if (ret) - return ret; - - if (!fw || !fw->data || fw->size < sizeof(*hdr)) { - dev_err(dev, "Invalid firmware\n"); - goto out; - } - - data = fw->data; - hdr = (const void *)(fw->data + fw->size - sizeof(*hdr)); - - for (i = 0; i < hdr->n_region; i++) { - const struct mt76_connac2_fw_region *region; - - region = (const void *)((const u8 *)hdr - - (hdr->n_region - i) * sizeof(*region)); - offset += le32_to_cpu(region->len); - } - - data += offset + 16; - rel_info = (struct mt7921_realease_info *)data; - data += sizeof(*rel_info); - end = data + le16_to_cpu(rel_info->len); - - while (data < end) { - rel_info = (struct mt7921_realease_info *)data; - data += sizeof(*rel_info); - - if (rel_info->tag == MT7921_FW_TAG_FEATURE) { - struct mt7921_fw_features *features; - - features = (struct mt7921_fw_features *)data; - offload_caps = features->data; - break; - } - - data += le16_to_cpu(rel_info->len) + rel_info->pad_len; - } - -out: - release_firmware(fw); - - return offload_caps; -} - -struct ieee80211_ops * -mt7921_get_mac80211_ops(struct device *dev, void *drv_data, u8 *fw_features) -{ - struct ieee80211_ops *ops; - - ops = devm_kmemdup(dev, &mt7921_ops, sizeof(mt7921_ops), GFP_KERNEL); - if (!ops) - return NULL; - - *fw_features = mt7921_get_offload_capability(dev, drv_data); - if (!(*fw_features & MT7921_FW_CAP_CNM)) { - ops->remain_on_channel = NULL; - ops->cancel_remain_on_channel = NULL; - ops->add_chanctx = NULL; - ops->remove_chanctx = NULL; - ops->change_chanctx = NULL; - ops->assign_vif_chanctx = NULL; - ops->unassign_vif_chanctx = NULL; - ops->mgd_prepare_tx = NULL; - ops->mgd_complete_tx = NULL; - } - return ops; -} -EXPORT_SYMBOL_GPL(mt7921_get_mac80211_ops); - -int mt7921_mac_init(struct mt7921_dev *dev) +int mt7921_mac_init(struct mt792x_dev *dev) { int i; @@ -264,17 +89,17 @@ int mt7921_mac_init(struct mt7921_dev *dev) /* enable hardware rx header translation */ mt76_set(dev, MT_MDP_DCR0, MT_MDP_DCR0_RX_HDR_TRANS_EN); - for (i = 0; i < MT7921_WTBL_SIZE; i++) + for (i = 0; i < MT792x_WTBL_SIZE; i++) mt7921_mac_wtbl_update(dev, i, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); for (i = 0; i < 2; i++) - mt7921_mac_init_band(dev, i); + mt792x_mac_init_band(dev, i); return mt76_connac_mcu_set_rts_thresh(&dev->mt76, 0x92b, 0); } EXPORT_SYMBOL_GPL(mt7921_mac_init); -static int __mt7921_init_hardware(struct mt7921_dev *dev) +static int __mt7921_init_hardware(struct mt792x_dev *dev) { int ret; @@ -282,7 +107,7 @@ static int __mt7921_init_hardware(struct mt7921_dev *dev) * which should be set before firmware download stage. */ mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE); - ret = mt7921_mcu_init(dev); + ret = mt792x_mcu_init(dev); if (ret) goto out; @@ -297,21 +122,21 @@ out: return ret; } -static int mt7921_init_hardware(struct mt7921_dev *dev) +static int mt7921_init_hardware(struct mt792x_dev *dev) { int ret, i; set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state); - for (i = 0; i < MT7921_MCU_INIT_RETRY_COUNT; i++) { + for (i = 0; i < MT792x_MCU_INIT_RETRY_COUNT; i++) { ret = __mt7921_init_hardware(dev); if (!ret) break; - mt7921_init_reset(dev); + mt792x_init_reset(dev); } - if (i == MT7921_MCU_INIT_RETRY_COUNT) { + if (i == MT792x_MCU_INIT_RETRY_COUNT) { dev_err(dev->mt76.dev, "hardware init failed\n"); return ret; } @@ -319,26 +144,9 @@ static int mt7921_init_hardware(struct mt7921_dev *dev) return 0; } -static int mt7921_init_wcid(struct mt7921_dev *dev) -{ - int idx; - - /* Beacon and mgmt frames should occupy wcid 0 */ - idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7921_WTBL_STA - 1); - if (idx) - return -ENOSPC; - - dev->mt76.global_wcid.idx = idx; - dev->mt76.global_wcid.hw_key_idx = -1; - dev->mt76.global_wcid.tx_info |= MT_WCID_TX_INFO_SET; - rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid); - - return 0; -} - static void mt7921_init_work(struct work_struct *work) { - struct mt7921_dev *dev = container_of(work, struct mt7921_dev, + struct mt792x_dev *dev = container_of(work, struct mt792x_dev, init_work); int ret; @@ -362,13 +170,19 @@ static void mt7921_init_work(struct work_struct *work) return; } + ret = mt7921_thermal_init(&dev->phy); + if (ret) { + dev_err(dev->mt76.dev, "thermal init failed\n"); + return; + } + /* we support chip reset now */ dev->hw_init_done = true; mt76_connac_mcu_set_deep_sleep(&dev->mt76, dev->pm.ds_enable); } -int mt7921_register_device(struct mt7921_dev *dev) +int mt7921_register_device(struct mt792x_dev *dev) { struct ieee80211_hw *hw = mt76_hw(dev); int ret; @@ -376,17 +190,17 @@ int mt7921_register_device(struct mt7921_dev *dev) dev->phy.dev = dev; dev->phy.mt76 = &dev->mt76.phy; dev->mt76.phy.priv = &dev->phy; - dev->mt76.tx_worker.fn = mt7921_tx_worker; + dev->mt76.tx_worker.fn = mt792x_tx_worker; - INIT_DELAYED_WORK(&dev->pm.ps_work, mt7921_pm_power_save_work); - INIT_WORK(&dev->pm.wake_work, mt7921_pm_wake_work); + INIT_DELAYED_WORK(&dev->pm.ps_work, mt792x_pm_power_save_work); + INIT_WORK(&dev->pm.wake_work, mt792x_pm_wake_work); spin_lock_init(&dev->pm.wake.lock); mutex_init(&dev->pm.mutex); init_waitqueue_head(&dev->pm.wait); if (mt76_is_sdio(&dev->mt76)) init_waitqueue_head(&dev->mt76.sdio.wait); spin_lock_init(&dev->pm.txq_lock); - INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7921_mac_work); + INIT_DELAYED_WORK(&dev->mphy.mac_work, mt792x_mac_work); INIT_DELAYED_WORK(&dev->phy.scan_work, mt7921_scan_work); INIT_DELAYED_WORK(&dev->coredump.work, mt7921_coredump_work); #if IS_ENABLED(CONFIG_IPV6) @@ -395,17 +209,15 @@ int mt7921_register_device(struct mt7921_dev *dev) #endif skb_queue_head_init(&dev->phy.scan_event_list); skb_queue_head_init(&dev->coredump.msg_list); - INIT_LIST_HEAD(&dev->sta_poll_list); - spin_lock_init(&dev->sta_poll_lock); INIT_WORK(&dev->reset_work, mt7921_mac_reset_work); INIT_WORK(&dev->init_work, mt7921_init_work); INIT_WORK(&dev->phy.roc_work, mt7921_roc_work); - timer_setup(&dev->phy.roc_timer, mt7921_roc_timer, 0); + timer_setup(&dev->phy.roc_timer, mt792x_roc_timer, 0); init_waitqueue_head(&dev->phy.roc_wait); - dev->pm.idle_timeout = MT7921_PM_TIMEOUT; + dev->pm.idle_timeout = MT792x_PM_TIMEOUT; dev->pm.stats.last_wake_event = jiffies; dev->pm.stats.last_doze_event = jiffies; if (!mt76_is_usb(&dev->mt76)) { @@ -418,16 +230,17 @@ int mt7921_register_device(struct mt7921_dev *dev) if (!mt76_is_mmio(&dev->mt76)) hw->extra_tx_headroom += MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE; - mt7921_init_acpi_sar(dev); + mt792x_init_acpi_sar(dev); - ret = mt7921_init_wcid(dev); + ret = mt792x_init_wcid(dev); if (ret) return ret; - ret = mt7921_init_wiphy(hw); + ret = mt792x_init_wiphy(hw); if (ret) return ret; + hw->wiphy->reg_notifier = mt7921_regd_notifier; dev->mphy.sband_2g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING | IEEE80211_HT_CAP_MAX_AMSDU; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index 1675bf520481..21f937454229 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -15,35 +15,7 @@ #define MT_WTBL_AC0_CTT_OFFSET 20 -static u32 mt7921_mac_wtbl_lmac_addr(int idx, u8 offset) -{ - return MT_WTBL_LMAC_OFFS(idx, 0) + offset * 4; -} - -static struct mt76_wcid *mt7921_rx_get_wcid(struct mt7921_dev *dev, - u16 idx, bool unicast) -{ - struct mt7921_sta *sta; - struct mt76_wcid *wcid; - - if (idx >= ARRAY_SIZE(dev->mt76.wcid)) - return NULL; - - wcid = rcu_dereference(dev->mt76.wcid[idx]); - if (unicast || !wcid) - return wcid; - - if (!wcid->sta) - return NULL; - - sta = container_of(wcid, struct mt7921_sta, wcid); - if (!sta->vif) - return NULL; - - return &sta->vif->sta.wcid; -} - -bool mt7921_mac_wtbl_update(struct mt7921_dev *dev, int idx, u32 mask) +bool mt7921_mac_wtbl_update(struct mt792x_dev *dev, int idx, u32 mask) { mt76_rmw(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_WLAN_IDX, FIELD_PREP(MT_WTBL_UPDATE_WLAN_IDX, idx) | mask); @@ -52,7 +24,12 @@ bool mt7921_mac_wtbl_update(struct mt7921_dev *dev, int idx, u32 mask) 0, 5000); } -void mt7921_mac_sta_poll(struct mt7921_dev *dev) +static u32 mt7921_mac_wtbl_lmac_addr(int idx, u8 offset) +{ + return MT_WTBL_LMAC_OFFS(idx, 0) + offset * 4; +} + +static void mt7921_mac_sta_poll(struct mt792x_dev *dev) { static const u8 ac_to_tid[] = { [IEEE80211_AC_BE] = 0, @@ -61,16 +38,16 @@ void mt7921_mac_sta_poll(struct mt7921_dev *dev) [IEEE80211_AC_VO] = 6 }; struct ieee80211_sta *sta; - struct mt7921_sta *msta; + struct mt792x_sta *msta; u32 tx_time[IEEE80211_NUM_ACS], rx_time[IEEE80211_NUM_ACS]; LIST_HEAD(sta_poll_list); struct rate_info *rate; s8 rssi[4]; int i; - spin_lock_bh(&dev->sta_poll_lock); - list_splice_init(&dev->sta_poll_list, &sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); while (true) { bool clear = false; @@ -78,15 +55,15 @@ void mt7921_mac_sta_poll(struct mt7921_dev *dev) u16 idx; u8 bw; - spin_lock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); if (list_empty(&sta_poll_list)) { - spin_unlock_bh(&dev->sta_poll_lock); + spin_unlock_bh(&dev->mt76.sta_poll_lock); break; } msta = list_first_entry(&sta_poll_list, - struct mt7921_sta, poll_list); - list_del_init(&msta->poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + struct mt792x_sta, wcid.poll_list); + list_del_init(&msta->wcid.poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); idx = msta->wcid.idx; addr = mt7921_mac_wtbl_lmac_addr(idx, MT_WTBL_AC0_CTT_OFFSET); @@ -183,56 +160,9 @@ void mt7921_mac_sta_poll(struct mt7921_dev *dev) ewma_avg_signal_add(&msta->avg_ack_signal, -msta->ack_signal); } } -EXPORT_SYMBOL_GPL(mt7921_mac_sta_poll); - -static void -mt7921_get_status_freq_info(struct mt7921_dev *dev, struct mt76_phy *mphy, - struct mt76_rx_status *status, u8 chfreq) -{ - if (chfreq > 180) { - status->band = NL80211_BAND_6GHZ; - chfreq = (chfreq - 181) * 4 + 1; - } else if (chfreq > 14) { - status->band = NL80211_BAND_5GHZ; - } else { - status->band = NL80211_BAND_2GHZ; - } - status->freq = ieee80211_channel_to_frequency(chfreq, status->band); -} - -static void -mt7921_mac_rssi_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) -{ - struct sk_buff *skb = priv; - struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb); - - if (status->signal > 0) - return; - - if (!ether_addr_equal(vif->addr, hdr->addr1)) - return; - - ewma_rssi_add(&mvif->rssi, -status->signal); -} - -static void -mt7921_mac_assoc_rssi(struct mt7921_dev *dev, struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb); - - if (!ieee80211_is_assoc_resp(hdr->frame_control) && - !ieee80211_is_auth(hdr->frame_control)) - return; - - ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev), - IEEE80211_IFACE_ITER_RESUME_ALL, - mt7921_mac_rssi_iter, skb); -} static int -mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) +mt7921_mac_fill_rx(struct mt792x_dev *dev, struct sk_buff *skb) { u32 csum_mask = MT_RXD0_NORMAL_IP_SUM | MT_RXD0_NORMAL_UDP_TCP_SUM; struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; @@ -241,7 +171,7 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) u16 hdr_gap; __le32 *rxv = NULL, *rxd = (__le32 *)skb->data; struct mt76_phy *mphy = &dev->mt76.phy; - struct mt7921_phy *phy = &dev->phy; + struct mt792x_phy *phy = &dev->phy; struct ieee80211_supported_band *sband; u32 csum_status = *(u32 *)skb->cb; u32 rxd0 = le32_to_cpu(rxd[0]); @@ -249,7 +179,7 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) u32 rxd2 = le32_to_cpu(rxd[2]); u32 rxd3 = le32_to_cpu(rxd[3]); u32 rxd4 = le32_to_cpu(rxd[4]); - struct mt7921_sta *msta = NULL; + struct mt792x_sta *msta = NULL; u16 seq_ctrl = 0; __le16 fc = 0; u8 mode = 0; @@ -277,17 +207,18 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) chfreq = FIELD_GET(MT_RXD3_NORMAL_CH_FREQ, rxd3); unicast = FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) == MT_RXD3_NORMAL_U2M; idx = FIELD_GET(MT_RXD1_NORMAL_WLAN_IDX, rxd1); - status->wcid = mt7921_rx_get_wcid(dev, idx, unicast); + status->wcid = mt792x_rx_get_wcid(dev, idx, unicast); if (status->wcid) { - msta = container_of(status->wcid, struct mt7921_sta, wcid); - spin_lock_bh(&dev->sta_poll_lock); - if (list_empty(&msta->poll_list)) - list_add_tail(&msta->poll_list, &dev->sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + msta = container_of(status->wcid, struct mt792x_sta, wcid); + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (list_empty(&msta->wcid.poll_list)) + list_add_tail(&msta->wcid.poll_list, + &dev->mt76.sta_poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); } - mt7921_get_status_freq_info(dev, mphy, status, chfreq); + mt792x_get_status_freq_info(status, chfreq); switch (status->band) { case NL80211_BAND_5GHZ: @@ -496,7 +427,7 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) status->flag |= RX_FLAG_8023; } - mt7921_mac_assoc_rssi(dev, skb); + mt792x_mac_assoc_rssi(dev, skb); if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023)) mt76_connac2_mac_decode_he_radiotap(&dev->mt76, skb, rxv, mode); @@ -511,33 +442,9 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) return 0; } -static void mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) +void mt7921_mac_add_txs(struct mt792x_dev *dev, void *data) { - struct mt7921_sta *msta; - u16 fc, tid; - u32 val; - - if (!sta || !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he)) - return; - - tid = le32_get_bits(txwi[1], MT_TXD1_TID); - if (tid >= 6) /* skip VO queue */ - return; - - val = le32_to_cpu(txwi[2]); - fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 | - FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4; - if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA))) - return; - - msta = (struct mt7921_sta *)sta->drv_priv; - if (!test_and_set_bit(tid, &msta->ampdu_state)) - ieee80211_start_tx_ba_session(sta, tid, 0); -} - -void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data) -{ - struct mt7921_sta *msta = NULL; + struct mt792x_sta *msta = NULL; struct mt76_wcid *wcid; __le32 *txs_data = data; u16 wcidx; @@ -552,7 +459,7 @@ void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data) if (pid < MT_PACKET_ID_FIRST) return; - if (wcidx >= MT7921_WTBL_SIZE) + if (wcidx >= MT792x_WTBL_SIZE) return; rcu_read_lock(); @@ -561,59 +468,29 @@ void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data) if (!wcid) goto out; - msta = container_of(wcid, struct mt7921_sta, wcid); + msta = container_of(wcid, struct mt792x_sta, wcid); mt76_connac2_mac_add_txs_skb(&dev->mt76, wcid, pid, txs_data); if (!wcid->sta) goto out; - spin_lock_bh(&dev->sta_poll_lock); - if (list_empty(&msta->poll_list)) - list_add_tail(&msta->poll_list, &dev->sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (list_empty(&msta->wcid.poll_list)) + list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); out: rcu_read_unlock(); } -void mt7921_txwi_free(struct mt7921_dev *dev, struct mt76_txwi_cache *t, - struct ieee80211_sta *sta, bool clear_status, - struct list_head *free_list) -{ - struct mt76_dev *mdev = &dev->mt76; - __le32 *txwi; - u16 wcid_idx; - - mt76_connac_txp_skb_unmap(mdev, t); - if (!t->skb) - goto out; - - txwi = (__le32 *)mt76_get_txwi_ptr(mdev, t); - if (sta) { - struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv; - - if (likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE))) - mt7921_tx_check_aggr(sta, txwi); - - wcid_idx = wcid->idx; - } else { - wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX); - } - - __mt76_tx_complete_skb(mdev, wcid_idx, t->skb, free_list); -out: - t->skb = NULL; - mt76_put_txwi(mdev, t); -} -EXPORT_SYMBOL_GPL(mt7921_txwi_free); - -static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len) +static void mt7921_mac_tx_free(struct mt792x_dev *dev, void *data, int len) { struct mt76_connac_tx_free *free = data; __le32 *tx_info = (__le32 *)(data + sizeof(*free)); struct mt76_dev *mdev = &dev->mt76; struct mt76_txwi_cache *txwi; struct ieee80211_sta *sta = NULL; + struct mt76_wcid *wcid = NULL; struct sk_buff *skb, *tmp; void *end = data + len; LIST_HEAD(free_list); @@ -636,8 +513,7 @@ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len) * 1'b0: msdu_id with the same 'wcid pair' as above. */ if (info & MT_TX_FREE_PAIR) { - struct mt7921_sta *msta; - struct mt76_wcid *wcid; + struct mt792x_sta *msta; u16 idx; count++; @@ -647,22 +523,29 @@ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len) if (!sta) continue; - msta = container_of(wcid, struct mt7921_sta, wcid); - spin_lock_bh(&dev->sta_poll_lock); - if (list_empty(&msta->poll_list)) - list_add_tail(&msta->poll_list, &dev->sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + msta = container_of(wcid, struct mt792x_sta, wcid); + spin_lock_bh(&mdev->sta_poll_lock); + if (list_empty(&msta->wcid.poll_list)) + list_add_tail(&msta->wcid.poll_list, + &mdev->sta_poll_list); + spin_unlock_bh(&mdev->sta_poll_lock); continue; } msdu = FIELD_GET(MT_TX_FREE_MSDU_ID, info); stat = FIELD_GET(MT_TX_FREE_STATUS, info); + if (wcid) { + wcid->stats.tx_retries += + FIELD_GET(MT_TX_FREE_COUNT, info) - 1; + wcid->stats.tx_failed += !!stat; + } + txwi = mt76_token_release(mdev, msdu, &wake); if (!txwi) continue; - mt7921_txwi_free(dev, txwi, sta, stat, &free_list); + mt76_connac2_txwi_free(mdev, txwi, sta, &free_list); } if (wake) @@ -682,7 +565,7 @@ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len) bool mt7921_rx_check(struct mt76_dev *mdev, void *data, int len) { - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); __le32 *rxd = (__le32 *)data; __le32 *end = (__le32 *)&rxd[len / 4]; enum rx_pkt_type type; @@ -707,7 +590,7 @@ EXPORT_SYMBOL_GPL(mt7921_rx_check); void mt7921_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, struct sk_buff *skb, u32 *info) { - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); __le32 *rxd = (__le32 *)skb->data; __le32 *end = (__le32 *)&skb->data[skb->len]; enum rx_pkt_type type; @@ -747,128 +630,12 @@ void mt7921_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, } EXPORT_SYMBOL_GPL(mt7921_queue_rx_skb); -void mt7921_mac_reset_counters(struct mt7921_phy *phy) -{ - struct mt7921_dev *dev = phy->dev; - int i; - - for (i = 0; i < 4; i++) { - mt76_rr(dev, MT_TX_AGG_CNT(0, i)); - mt76_rr(dev, MT_TX_AGG_CNT2(0, i)); - } - - dev->mt76.phy.survey_time = ktime_get_boottime(); - memset(phy->mt76->aggr_stats, 0, sizeof(phy->mt76->aggr_stats)); - - /* reset airtime counters */ - mt76_rr(dev, MT_MIB_SDR9(0)); - mt76_rr(dev, MT_MIB_SDR36(0)); - mt76_rr(dev, MT_MIB_SDR37(0)); - - mt76_set(dev, MT_WF_RMAC_MIB_TIME0(0), MT_WF_RMAC_MIB_RXTIME_CLR); - mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(0), MT_WF_RMAC_MIB_RXTIME_CLR); -} - -void mt7921_mac_set_timing(struct mt7921_phy *phy) -{ - s16 coverage_class = phy->coverage_class; - struct mt7921_dev *dev = phy->dev; - u32 val, reg_offset; - u32 cck = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 231) | - FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48); - u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) | - FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28); - bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ; - int sifs = is_2ghz ? 10 : 16, offset; - - if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state)) - return; - - mt76_set(dev, MT_ARB_SCR(0), - MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE); - udelay(1); - - offset = 3 * coverage_class; - reg_offset = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, offset) | - FIELD_PREP(MT_TIMEOUT_VAL_CCA, offset); - - mt76_wr(dev, MT_TMAC_CDTR(0), cck + reg_offset); - mt76_wr(dev, MT_TMAC_ODTR(0), ofdm + reg_offset); - mt76_wr(dev, MT_TMAC_ICR0(0), - FIELD_PREP(MT_IFS_EIFS, 360) | - FIELD_PREP(MT_IFS_RIFS, 2) | - FIELD_PREP(MT_IFS_SIFS, sifs) | - FIELD_PREP(MT_IFS_SLOT, phy->slottime)); - - if (phy->slottime < 20 || !is_2ghz) - val = MT7921_CFEND_RATE_DEFAULT; - else - val = MT7921_CFEND_RATE_11B; - - mt76_rmw_field(dev, MT_AGG_ACR0(0), MT_AGG_ACR_CFEND_RATE, val); - mt76_clear(dev, MT_ARB_SCR(0), - MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE); -} - -static u8 -mt7921_phy_get_nf(struct mt7921_phy *phy, int idx) -{ - return 0; -} - -static void -mt7921_phy_update_channel(struct mt76_phy *mphy, int idx) -{ - struct mt7921_dev *dev = container_of(mphy->dev, struct mt7921_dev, mt76); - struct mt7921_phy *phy = (struct mt7921_phy *)mphy->priv; - struct mt76_channel_state *state; - u64 busy_time, tx_time, rx_time, obss_time; - int nf; - - busy_time = mt76_get_field(dev, MT_MIB_SDR9(idx), - MT_MIB_SDR9_BUSY_MASK); - tx_time = mt76_get_field(dev, MT_MIB_SDR36(idx), - MT_MIB_SDR36_TXTIME_MASK); - rx_time = mt76_get_field(dev, MT_MIB_SDR37(idx), - MT_MIB_SDR37_RXTIME_MASK); - obss_time = mt76_get_field(dev, MT_WF_RMAC_MIB_AIRTIME14(idx), - MT_MIB_OBSSTIME_MASK); - - nf = mt7921_phy_get_nf(phy, idx); - if (!phy->noise) - phy->noise = nf << 4; - else if (nf) - phy->noise += nf - (phy->noise >> 4); - - state = mphy->chan_state; - state->cc_busy += busy_time; - state->cc_tx += tx_time; - state->cc_rx += rx_time + obss_time; - state->cc_bss_rx += rx_time; - state->noise = -(phy->noise >> 4); -} - -void mt7921_update_channel(struct mt76_phy *mphy) -{ - struct mt7921_dev *dev = container_of(mphy->dev, struct mt7921_dev, mt76); - - if (mt76_connac_pm_wake(mphy, &dev->pm)) - return; - - mt7921_phy_update_channel(mphy, 0); - /* reset obss airtime */ - mt76_set(dev, MT_WF_RMAC_MIB_TIME0(0), MT_WF_RMAC_MIB_RXTIME_CLR); - - mt76_connac_power_save_sched(mphy, &dev->pm); -} -EXPORT_SYMBOL_GPL(mt7921_update_channel); - static void mt7921_vif_connect_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_dev *dev = mvif->phy->dev; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_dev *dev = mvif->phy->dev; struct ieee80211_hw *hw = mt76_hw(dev); if (vif->type == NL80211_IFTYPE_STATION) @@ -889,7 +656,7 @@ mt7921_vif_connect_iter(void *priv, u8 *mac, /* system error recovery */ void mt7921_mac_reset_work(struct work_struct *work) { - struct mt7921_dev *dev = container_of(work, struct mt7921_dev, + struct mt792x_dev *dev = container_of(work, struct mt792x_dev, reset_work); struct ieee80211_hw *hw = mt76_hw(dev); struct mt76_connac_pm *pm = &dev->pm; @@ -905,7 +672,7 @@ void mt7921_mac_reset_work(struct work_struct *work) for (i = 0; i < 10; i++) { mutex_lock(&dev->mt76.mutex); - ret = mt7921_dev_reset(dev); + ret = mt792x_dev_reset(dev); mutex_unlock(&dev->mt76.mutex); if (!ret) @@ -932,185 +699,12 @@ void mt7921_mac_reset_work(struct work_struct *work) mt76_connac_power_save_sched(&dev->mt76.phy, pm); } -void mt7921_reset(struct mt76_dev *mdev) -{ - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); - struct mt76_connac_pm *pm = &dev->pm; - - if (!dev->hw_init_done) - return; - - if (dev->hw_full_reset) - return; - - if (pm->suspended) - return; - - queue_work(dev->mt76.wq, &dev->reset_work); -} -EXPORT_SYMBOL_GPL(mt7921_reset); - -void mt7921_mac_update_mib_stats(struct mt7921_phy *phy) -{ - struct mt7921_dev *dev = phy->dev; - struct mib_stats *mib = &phy->mib; - int i, aggr0 = 0, aggr1; - u32 val; - - mib->fcs_err_cnt += mt76_get_field(dev, MT_MIB_SDR3(0), - MT_MIB_SDR3_FCS_ERR_MASK); - mib->ack_fail_cnt += mt76_get_field(dev, MT_MIB_MB_BSDR3(0), - MT_MIB_ACK_FAIL_COUNT_MASK); - mib->ba_miss_cnt += mt76_get_field(dev, MT_MIB_MB_BSDR2(0), - MT_MIB_BA_FAIL_COUNT_MASK); - mib->rts_cnt += mt76_get_field(dev, MT_MIB_MB_BSDR0(0), - MT_MIB_RTS_COUNT_MASK); - mib->rts_retries_cnt += mt76_get_field(dev, MT_MIB_MB_BSDR1(0), - MT_MIB_RTS_FAIL_COUNT_MASK); - - mib->tx_ampdu_cnt += mt76_rr(dev, MT_MIB_SDR12(0)); - mib->tx_mpdu_attempts_cnt += mt76_rr(dev, MT_MIB_SDR14(0)); - mib->tx_mpdu_success_cnt += mt76_rr(dev, MT_MIB_SDR15(0)); - - val = mt76_rr(dev, MT_MIB_SDR32(0)); - mib->tx_pkt_ebf_cnt += FIELD_GET(MT_MIB_SDR9_EBF_CNT_MASK, val); - mib->tx_pkt_ibf_cnt += FIELD_GET(MT_MIB_SDR9_IBF_CNT_MASK, val); - - val = mt76_rr(dev, MT_ETBF_TX_APP_CNT(0)); - mib->tx_bf_ibf_ppdu_cnt += FIELD_GET(MT_ETBF_TX_IBF_CNT, val); - mib->tx_bf_ebf_ppdu_cnt += FIELD_GET(MT_ETBF_TX_EBF_CNT, val); - - val = mt76_rr(dev, MT_ETBF_RX_FB_CNT(0)); - mib->tx_bf_rx_fb_all_cnt += FIELD_GET(MT_ETBF_RX_FB_ALL, val); - mib->tx_bf_rx_fb_he_cnt += FIELD_GET(MT_ETBF_RX_FB_HE, val); - mib->tx_bf_rx_fb_vht_cnt += FIELD_GET(MT_ETBF_RX_FB_VHT, val); - mib->tx_bf_rx_fb_ht_cnt += FIELD_GET(MT_ETBF_RX_FB_HT, val); - - mib->rx_mpdu_cnt += mt76_rr(dev, MT_MIB_SDR5(0)); - mib->rx_ampdu_cnt += mt76_rr(dev, MT_MIB_SDR22(0)); - mib->rx_ampdu_bytes_cnt += mt76_rr(dev, MT_MIB_SDR23(0)); - mib->rx_ba_cnt += mt76_rr(dev, MT_MIB_SDR31(0)); - - for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++) { - val = mt76_rr(dev, MT_PLE_AMSDU_PACK_MSDU_CNT(i)); - mib->tx_amsdu[i] += val; - mib->tx_amsdu_cnt += val; - } - - for (i = 0, aggr1 = aggr0 + 8; i < 4; i++) { - u32 val2; - - val = mt76_rr(dev, MT_TX_AGG_CNT(0, i)); - val2 = mt76_rr(dev, MT_TX_AGG_CNT2(0, i)); - - phy->mt76->aggr_stats[aggr0++] += val & 0xffff; - phy->mt76->aggr_stats[aggr0++] += val >> 16; - phy->mt76->aggr_stats[aggr1++] += val2 & 0xffff; - phy->mt76->aggr_stats[aggr1++] += val2 >> 16; - } -} - -void mt7921_mac_work(struct work_struct *work) -{ - struct mt7921_phy *phy; - struct mt76_phy *mphy; - - mphy = (struct mt76_phy *)container_of(work, struct mt76_phy, - mac_work.work); - phy = mphy->priv; - - mt7921_mutex_acquire(phy->dev); - - mt76_update_survey(mphy); - if (++mphy->mac_work_count == 2) { - mphy->mac_work_count = 0; - - mt7921_mac_update_mib_stats(phy); - } - - mt7921_mutex_release(phy->dev); - - mt76_tx_status_check(mphy->dev, false); - ieee80211_queue_delayed_work(phy->mt76->hw, &mphy->mac_work, - MT7921_WATCHDOG_TIME); -} - -void mt7921_pm_wake_work(struct work_struct *work) -{ - struct mt7921_dev *dev; - struct mt76_phy *mphy; - - dev = (struct mt7921_dev *)container_of(work, struct mt7921_dev, - pm.wake_work); - mphy = dev->phy.mt76; - - if (!mt7921_mcu_drv_pmctrl(dev)) { - struct mt76_dev *mdev = &dev->mt76; - int i; - - if (mt76_is_sdio(mdev)) { - mt76_connac_pm_dequeue_skbs(mphy, &dev->pm); - mt76_worker_schedule(&mdev->sdio.txrx_worker); - } else { - local_bh_disable(); - mt76_for_each_q_rx(mdev, i) - napi_schedule(&mdev->napi[i]); - local_bh_enable(); - mt76_connac_pm_dequeue_skbs(mphy, &dev->pm); - mt76_connac_tx_cleanup(mdev); - } - if (test_bit(MT76_STATE_RUNNING, &mphy->state)) - ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work, - MT7921_WATCHDOG_TIME); - } - - ieee80211_wake_queues(mphy->hw); - wake_up(&dev->pm.wait); -} - -void mt7921_pm_power_save_work(struct work_struct *work) -{ - struct mt7921_dev *dev; - unsigned long delta; - struct mt76_phy *mphy; - - dev = (struct mt7921_dev *)container_of(work, struct mt7921_dev, - pm.ps_work.work); - mphy = dev->phy.mt76; - - delta = dev->pm.idle_timeout; - if (test_bit(MT76_HW_SCANNING, &mphy->state) || - test_bit(MT76_HW_SCHED_SCANNING, &mphy->state) || - dev->fw_assert) - goto out; - - if (mutex_is_locked(&dev->mt76.mutex)) - /* if mt76 mutex is held we should not put the device - * to sleep since we are currently accessing device - * register map. We need to wait for the next power_save - * trigger. - */ - goto out; - - if (time_is_after_jiffies(dev->pm.last_activity + delta)) { - delta = dev->pm.last_activity + delta - jiffies; - goto out; - } - - if (!mt7921_mcu_fw_pmctrl(dev)) { - cancel_delayed_work_sync(&mphy->mac_work); - return; - } -out: - queue_delayed_work(dev->mt76.wq, &dev->pm.ps_work, delta); -} - void mt7921_coredump_work(struct work_struct *work) { - struct mt7921_dev *dev; + struct mt792x_dev *dev; char *dump, *data; - dev = (struct mt7921_dev *)container_of(work, struct mt7921_dev, + dev = (struct mt792x_dev *)container_of(work, struct mt792x_dev, coredump.work.work); if (time_is_after_jiffies(dev->coredump.last_activity + @@ -1149,12 +743,12 @@ void mt7921_coredump_work(struct work_struct *work) dev_coredumpv(dev->mt76.dev, dump, MT76_CONNAC_COREDUMP_SZ, GFP_KERNEL); - mt7921_reset(&dev->mt76); + mt792x_reset(&dev->mt76); } /* usb_sdio */ static void -mt7921_usb_sdio_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid, +mt7921_usb_sdio_write_txwi(struct mt792x_dev *dev, struct mt76_wcid *wcid, enum mt76_txq_id qid, struct ieee80211_sta *sta, struct ieee80211_key_conf *key, int pid, struct sk_buff *skb) @@ -1171,7 +765,7 @@ int mt7921_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, struct ieee80211_sta *sta, struct mt76_tx_info *tx_info) { - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb); struct ieee80211_key_conf *key = info->control.hw_key; struct sk_buff *skb = tx_info->skb; @@ -1180,11 +774,15 @@ int mt7921_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, if (unlikely(tx_info->skb->len <= ETH_HLEN)) return -EINVAL; + err = skb_cow_head(skb, MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE); + if (err) + return err; + if (!wcid) wcid = &dev->mt76.global_wcid; if (sta) { - struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv; + struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv; if (time_after(jiffies, msta->last_txs + HZ / 4)) { info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; @@ -1224,7 +822,7 @@ void mt7921_usb_sdio_tx_complete_skb(struct mt76_dev *mdev, sta = wcid_to_sta(wcid); if (sta && likely(e->skb->protocol != cpu_to_be16(ETH_P_PAE))) - mt7921_tx_check_aggr(sta, txwi); + mt76_connac2_tx_check_aggr(sta, txwi); skb_pull(e->skb, headroom); mt76_tx_complete_skb(mdev, e->wcid, e->skb); @@ -1233,11 +831,11 @@ EXPORT_SYMBOL_GPL(mt7921_usb_sdio_tx_complete_skb); bool mt7921_usb_sdio_tx_status_data(struct mt76_dev *mdev, u8 *update) { - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); mt7921_mac_sta_poll(dev); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return false; } @@ -1246,8 +844,8 @@ EXPORT_SYMBOL_GPL(mt7921_usb_sdio_tx_status_data); #if IS_ENABLED(CONFIG_IPV6) void mt7921_set_ipv6_ns_work(struct work_struct *work) { - struct mt7921_dev *dev = container_of(work, struct mt7921_dev, - ipv6_ns_work); + struct mt792x_dev *dev = container_of(work, struct mt792x_dev, + ipv6_ns_work); struct sk_buff *skb; int ret = 0; @@ -1257,10 +855,10 @@ void mt7921_set_ipv6_ns_work(struct work_struct *work) if (!skb) break; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); ret = mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_UNI_CMD(OFFLOAD), true); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); } while (!ret); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index 3b6adb29cbef..0844d28b3223 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -10,7 +10,7 @@ #include "mcu.h" static int -mt7921_init_he_caps(struct mt7921_phy *phy, enum nl80211_band band, +mt7921_init_he_caps(struct mt792x_phy *phy, enum nl80211_band band, struct ieee80211_sband_iftype_data *data) { int i, idx = 0; @@ -185,7 +185,7 @@ mt7921_init_he_caps(struct mt7921_phy *phy, enum nl80211_band band, return idx; } -void mt7921_set_stream_he_caps(struct mt7921_phy *phy) +void mt7921_set_stream_he_caps(struct mt792x_phy *phy) { struct ieee80211_sband_iftype_data *data; struct ieee80211_supported_band *band; @@ -219,7 +219,7 @@ void mt7921_set_stream_he_caps(struct mt7921_phy *phy) } } -int __mt7921_start(struct mt7921_phy *phy) +int __mt7921_start(struct mt792x_phy *phy) { struct mt76_phy *mphy = phy->mt76; int err; @@ -240,11 +240,11 @@ int __mt7921_start(struct mt7921_phy *phy) if (err) return err; - mt7921_mac_reset_counters(phy); + mt792x_mac_reset_counters(phy); set_bit(MT76_STATE_RUNNING, &mphy->state); ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work, - MT7921_WATCHDOG_TIME); + MT792x_WATCHDOG_TIME); return 0; } @@ -252,20 +252,20 @@ EXPORT_SYMBOL_GPL(__mt7921_start); static int mt7921_start(struct ieee80211_hw *hw) { - struct mt7921_phy *phy = mt7921_hw_phy(hw); + struct mt792x_phy *phy = mt792x_hw_phy(hw); int err; - mt7921_mutex_acquire(phy->dev); + mt792x_mutex_acquire(phy->dev); err = __mt7921_start(phy); - mt7921_mutex_release(phy->dev); + mt792x_mutex_release(phy->dev); return err; } void mt7921_stop(struct ieee80211_hw *hw) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); - struct mt7921_phy *phy = mt7921_hw_phy(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt792x_phy *phy = mt792x_hw_phy(hw); cancel_delayed_work_sync(&phy->mt76->mac_work); @@ -274,26 +274,26 @@ void mt7921_stop(struct ieee80211_hw *hw) cancel_work_sync(&dev->reset_work); mt76_connac_free_pending_tx_skbs(&dev->pm, NULL); - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); clear_bit(MT76_STATE_RUNNING, &phy->mt76->state); mt76_connac_mcu_set_mac_enable(&dev->mt76, 0, false, false); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); } EXPORT_SYMBOL_GPL(mt7921_stop); -static int mt7921_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +static int +mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_dev *dev = mt7921_hw_dev(hw); - struct mt7921_phy *phy = mt7921_hw_phy(hw); + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt792x_phy *phy = mt792x_hw_phy(hw); struct mt76_txq *mtxq; int idx, ret = 0; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); mvif->mt76.idx = __ffs64(~dev->mt76.vif_mask); - if (mvif->mt76.idx >= MT7921_MAX_INTERFACES) { + if (mvif->mt76.idx >= MT792x_MAX_INTERFACES) { ret = -ENOSPC; goto out; } @@ -311,9 +311,9 @@ static int mt7921_add_interface(struct ieee80211_hw *hw, dev->mt76.vif_mask |= BIT_ULL(mvif->mt76.idx); phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx); - idx = MT7921_WTBL_RESERVED - mvif->mt76.idx; + idx = MT792x_WTBL_RESERVED - mvif->mt76.idx; - INIT_LIST_HEAD(&mvif->sta.poll_list); + INIT_LIST_HEAD(&mvif->sta.wcid.poll_list); mvif->sta.wcid.idx = idx; mvif->sta.wcid.phy_idx = mvif->mt76.band_idx; mvif->sta.wcid.hw_key_idx = -1; @@ -333,89 +333,55 @@ static int mt7921_add_interface(struct ieee80211_hw *hw, vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; out: - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return ret; } -static void mt7921_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_sta *msta = &mvif->sta; - struct mt7921_dev *dev = mt7921_hw_dev(hw); - struct mt7921_phy *phy = mt7921_hw_phy(hw); - int idx = msta->wcid.idx; - - mt7921_mutex_acquire(dev); - mt76_connac_free_pending_tx_skbs(&dev->pm, &msta->wcid); - mt76_connac_mcu_uni_add_dev(&dev->mphy, vif, &mvif->sta.wcid, false); - - rcu_assign_pointer(dev->mt76.wcid[idx], NULL); - - dev->mt76.vif_mask &= ~BIT_ULL(mvif->mt76.idx); - phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx); - mt7921_mutex_release(dev); - - spin_lock_bh(&dev->sta_poll_lock); - if (!list_empty(&msta->poll_list)) - list_del_init(&msta->poll_list); - spin_unlock_bh(&dev->sta_poll_lock); - - mt76_packet_id_flush(&dev->mt76, &msta->wcid); -} - static void mt7921_roc_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_phy *phy = priv; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_phy *phy = priv; mt7921_mcu_abort_roc(phy, mvif, phy->roc_token_id); } void mt7921_roc_work(struct work_struct *work) { - struct mt7921_phy *phy; + struct mt792x_phy *phy; - phy = (struct mt7921_phy *)container_of(work, struct mt7921_phy, + phy = (struct mt792x_phy *)container_of(work, struct mt792x_phy, roc_work); if (!test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state)) return; - mt7921_mutex_acquire(phy->dev); + mt792x_mutex_acquire(phy->dev); ieee80211_iterate_active_interfaces(phy->mt76->hw, IEEE80211_IFACE_ITER_RESUME_ALL, mt7921_roc_iter, phy); - mt7921_mutex_release(phy->dev); + mt792x_mutex_release(phy->dev); ieee80211_remain_on_channel_expired(phy->mt76->hw); } -void mt7921_roc_timer(struct timer_list *timer) -{ - struct mt7921_phy *phy = from_timer(phy, timer, roc_timer); - - ieee80211_queue_work(phy->mt76->hw, &phy->roc_work); -} - -static int mt7921_abort_roc(struct mt7921_phy *phy, struct mt7921_vif *vif) +static int mt7921_abort_roc(struct mt792x_phy *phy, struct mt792x_vif *vif) { int err = 0; del_timer_sync(&phy->roc_timer); cancel_work_sync(&phy->roc_work); - mt7921_mutex_acquire(phy->dev); + mt792x_mutex_acquire(phy->dev); if (test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state)) err = mt7921_mcu_abort_roc(phy, vif, phy->roc_token_id); - mt7921_mutex_release(phy->dev); + mt792x_mutex_release(phy->dev); return err; } -static int mt7921_set_roc(struct mt7921_phy *phy, - struct mt7921_vif *vif, +static int mt7921_set_roc(struct mt792x_phy *phy, + struct mt792x_vif *vif, struct ieee80211_channel *chan, int duration, enum mt7921_roc_req type) @@ -450,13 +416,13 @@ static int mt7921_remain_on_channel(struct ieee80211_hw *hw, int duration, enum ieee80211_roc_type type) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_phy *phy = mt7921_hw_phy(hw); + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_phy *phy = mt792x_hw_phy(hw); int err; - mt7921_mutex_acquire(phy->dev); + mt792x_mutex_acquire(phy->dev); err = mt7921_set_roc(phy, mvif, chan, duration, MT7921_ROC_REQ_ROC); - mt7921_mutex_release(phy->dev); + mt792x_mutex_release(phy->dev); return err; } @@ -464,20 +430,20 @@ static int mt7921_remain_on_channel(struct ieee80211_hw *hw, static int mt7921_cancel_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_phy *phy = mt7921_hw_phy(hw); + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_phy *phy = mt792x_hw_phy(hw); return mt7921_abort_roc(phy, mvif); } -static int mt7921_set_channel(struct mt7921_phy *phy) +static int mt7921_set_channel(struct mt792x_phy *phy) { - struct mt7921_dev *dev = phy->dev; + struct mt792x_dev *dev = phy->dev; int ret; cancel_delayed_work_sync(&phy->mt76->mac_work); - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); set_bit(MT76_RESET, &phy->mt76->state); mt76_set_channel(phy->mt76); @@ -486,18 +452,18 @@ static int mt7921_set_channel(struct mt7921_phy *phy) if (ret) goto out; - mt7921_mac_set_timing(phy); + mt792x_mac_set_timeing(phy); - mt7921_mac_reset_counters(phy); + mt792x_mac_reset_counters(phy); phy->noise = 0; out: clear_bit(MT76_RESET, &phy->mt76->state); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); mt76_worker_schedule(&dev->mt76.tx_worker); ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mt76->mac_work, - MT7921_WATCHDOG_TIME); + MT792x_WATCHDOG_TIME); return ret; } @@ -506,9 +472,9 @@ static int mt7921_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_sta *msta = sta ? (struct mt7921_sta *)sta->drv_priv : + struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_sta *msta = sta ? (struct mt792x_sta *)sta->drv_priv : &mvif->sta; struct mt76_wcid *wcid = &msta->wcid; u8 *wcid_keyidx = &wcid->hw_key_idx; @@ -546,7 +512,7 @@ static int mt7921_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); if (cmd == SET_KEY) { *wcid_keyidx = idx; @@ -570,7 +536,7 @@ static int mt7921_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, key, MCU_UNI_CMD(STA_REC_UPDATE), &mvif->wep_sta->wcid, cmd); out: - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return err; } @@ -578,7 +544,7 @@ out: static void mt7921_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) { - struct mt7921_dev *dev = priv; + struct mt792x_dev *dev = priv; struct ieee80211_hw *hw = mt76_hw(dev); bool pm_enable = dev->pm.enable; int err; @@ -599,7 +565,7 @@ mt7921_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) static void mt7921_sniffer_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) { - struct mt7921_dev *dev = priv; + struct mt792x_dev *dev = priv; struct ieee80211_hw *hw = mt76_hw(dev); struct mt76_connac_pm *pm = &dev->pm; bool monitor = !!(hw->conf.flags & IEEE80211_CONF_MONITOR); @@ -614,7 +580,7 @@ mt7921_sniffer_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) mt7921_mcu_set_beacon_filter(dev, vif, false); } -void mt7921_set_runtime_pm(struct mt7921_dev *dev) +void mt7921_set_runtime_pm(struct mt792x_dev *dev) { struct ieee80211_hw *hw = mt76_hw(dev); struct mt76_connac_pm *pm = &dev->pm; @@ -630,8 +596,8 @@ void mt7921_set_runtime_pm(struct mt7921_dev *dev) static int mt7921_config(struct ieee80211_hw *hw, u32 changed) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); - struct mt7921_phy *phy = mt7921_hw_phy(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt792x_phy *phy = mt792x_hw_phy(hw); int ret = 0; if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { @@ -642,7 +608,7 @@ static int mt7921_config(struct ieee80211_hw *hw, u32 changed) ieee80211_wake_queues(hw); } - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); if (changed & IEEE80211_CONF_CHANGE_POWER) { ret = mt7921_set_tx_sar_pwr(hw, NULL); @@ -657,25 +623,11 @@ static int mt7921_config(struct ieee80211_hw *hw, u32 changed) } out: - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return ret; } -static int -mt7921_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - unsigned int link_id, u16 queue, - const struct ieee80211_tx_queue_params *params) -{ - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - - /* no need to update right away, we'll get BSS_CHANGED_QOS */ - queue = mt76_connac_lmac_mapping(queue); - mvif->queue_params[queue] = *params; - - return 0; -} - static void mt7921_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, @@ -686,7 +638,7 @@ static void mt7921_configure_filter(struct ieee80211_hw *hw, #define MT7921_FILTER_OTHER_BSS BIT(6) #define MT7921_FILTER_ENABLE BIT(31) - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); u32 flags = MT7921_FILTER_ENABLE; #define MT7921_FILTER(_fif, _type) do { \ @@ -698,9 +650,9 @@ static void mt7921_configure_filter(struct ieee80211_hw *hw, MT7921_FILTER(FIF_CONTROL, CONTROL); MT7921_FILTER(FIF_OTHER_BSS, OTHER_BSS); - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); mt7921_mcu_set_rxfilter(dev, flags, 0, 0); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); *total_flags &= (FIF_OTHER_BSS | FIF_FCSFAIL | FIF_CONTROL); } @@ -710,17 +662,17 @@ static void mt7921_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_bss_conf *info, u64 changed) { - struct mt7921_phy *phy = mt7921_hw_phy(hw); - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_phy *phy = mt792x_hw_phy(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); if (changed & BSS_CHANGED_ERP_SLOT) { int slottime = info->use_short_slot ? 9 : 20; if (slottime != phy->slottime) { phy->slottime = slottime; - mt7921_mac_set_timing(phy); + mt792x_mac_set_timeing(phy); } } @@ -743,28 +695,28 @@ static void mt7921_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ARP_FILTER) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; mt76_connac_mcu_update_arp_filter(&dev->mt76, &mvif->mt76, info); } - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); } int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); - struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv; - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); + struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; int ret, idx; - idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7921_WTBL_STA - 1); + idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT792x_WTBL_STA - 1); if (idx < 0) return -ENOSPC; - INIT_LIST_HEAD(&msta->poll_list); + INIT_LIST_HEAD(&msta->wcid.poll_list); msta->vif = mvif; msta->wcid.sta = 1; msta->wcid.idx = idx; @@ -796,11 +748,11 @@ EXPORT_SYMBOL_GPL(mt7921_mac_sta_add); void mt7921_mac_sta_assoc(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); - struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv; - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); + struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) mt76_connac_mcu_uni_add_bss(&dev->mphy, vif, &mvif->sta.wcid, @@ -814,15 +766,15 @@ void mt7921_mac_sta_assoc(struct mt76_dev *mdev, struct ieee80211_vif *vif, mt7921_mcu_sta_update(dev, sta, vif, true, MT76_STA_INFO_STATE_ASSOC); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); } EXPORT_SYMBOL_GPL(mt7921_mac_sta_assoc); void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); - struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv; + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); + struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv; mt76_connac_free_pending_tx_skbs(&dev->pm, &msta->wcid); mt76_connac_pm_wake(&dev->mphy, &dev->pm); @@ -832,7 +784,7 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); if (vif->type == NL80211_IFTYPE_STATION) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; mvif->wep_sta = NULL; ewma_rssi_init(&mvif->rssi); @@ -842,76 +794,22 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, mvif->ctx); } - spin_lock_bh(&dev->sta_poll_lock); - if (!list_empty(&msta->poll_list)) - list_del_init(&msta->poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (!list_empty(&msta->wcid.poll_list)) + list_del_init(&msta->wcid.poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); mt76_connac_power_save_sched(&dev->mphy, &dev->pm); } EXPORT_SYMBOL_GPL(mt7921_mac_sta_remove); -void mt7921_tx_worker(struct mt76_worker *w) -{ - struct mt7921_dev *dev = container_of(w, struct mt7921_dev, - mt76.tx_worker); - - if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) { - queue_work(dev->mt76.wq, &dev->pm.wake_work); - return; - } - - mt76_txq_schedule_all(&dev->mphy); - mt76_connac_pm_unref(&dev->mphy, &dev->pm); -} - -static void mt7921_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) -{ - struct mt7921_dev *dev = mt7921_hw_dev(hw); - struct mt76_phy *mphy = hw->priv; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_vif *vif = info->control.vif; - struct mt76_wcid *wcid = &dev->mt76.global_wcid; - int qid; - - if (control->sta) { - struct mt7921_sta *sta; - - sta = (struct mt7921_sta *)control->sta->drv_priv; - wcid = &sta->wcid; - } - - if (vif && !control->sta) { - struct mt7921_vif *mvif; - - mvif = (struct mt7921_vif *)vif->drv_priv; - wcid = &mvif->sta.wcid; - } - - if (mt76_connac_pm_ref(mphy, &dev->pm)) { - mt76_tx(mphy, control->sta, wcid, skb); - mt76_connac_pm_unref(mphy, &dev->pm); - return; - } - - qid = skb_get_queue_mapping(skb); - if (qid >= MT_TXQ_PSD) { - qid = IEEE80211_AC_BE; - skb_set_queue_mapping(skb, qid); - } - - mt76_connac_pm_queue_skb(hw, &dev->pm, wcid, skb); -} - static int mt7921_set_rts_threshold(struct ieee80211_hw *hw, u32 val) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); mt76_connac_mcu_set_rts_thresh(&dev->mt76, val, 0); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return 0; } @@ -921,10 +819,10 @@ mt7921_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_ampdu_params *params) { enum ieee80211_ampdu_mlme_action action = params->action; - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); struct ieee80211_sta *sta = params->sta; struct ieee80211_txq *txq = sta->txq[params->tid]; - struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv; + struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv; u16 tid = params->tid; u16 ssn = params->ssn; struct mt76_txq *mtxq; @@ -935,7 +833,7 @@ mt7921_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mtxq = (struct mt76_txq *)txq->drv_priv; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); switch (action) { case IEEE80211_AMPDU_RX_START: mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, ssn, @@ -954,21 +852,21 @@ mt7921_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: mtxq->aggr = false; - clear_bit(tid, &msta->ampdu_state); + clear_bit(tid, &msta->wcid.ampdu_state); mt7921_mcu_uni_tx_ba(dev, params, false); break; case IEEE80211_AMPDU_TX_START: - set_bit(tid, &msta->ampdu_state); + set_bit(tid, &msta->wcid.ampdu_state); ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; break; case IEEE80211_AMPDU_TX_STOP_CONT: mtxq->aggr = false; - clear_bit(tid, &msta->ampdu_state); + clear_bit(tid, &msta->wcid.ampdu_state); mt7921_mcu_uni_tx_ba(dev, params, false); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; } - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return ret; } @@ -979,289 +877,22 @@ static int mt7921_sta_state(struct ieee80211_hw *hw, enum ieee80211_sta_state old_state, enum ieee80211_sta_state new_state) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); if (dev->pm.ds_enable) { - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); mt76_connac_sta_state_dp(&dev->mt76, old_state, new_state); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); } return mt76_sta_state(hw, vif, sta, old_state, new_state); } -static int -mt7921_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats) -{ - struct mt7921_phy *phy = mt7921_hw_phy(hw); - struct mib_stats *mib = &phy->mib; - - mt7921_mutex_acquire(phy->dev); - - stats->dot11RTSSuccessCount = mib->rts_cnt; - stats->dot11RTSFailureCount = mib->rts_retries_cnt; - stats->dot11FCSErrorCount = mib->fcs_err_cnt; - stats->dot11ACKFailureCount = mib->ack_fail_cnt; - - mt7921_mutex_release(phy->dev); - - return 0; -} - -static const char mt7921_gstrings_stats[][ETH_GSTRING_LEN] = { - /* tx counters */ - "tx_ampdu_cnt", - "tx_mpdu_attempts", - "tx_mpdu_success", - "tx_pkt_ebf_cnt", - "tx_pkt_ibf_cnt", - "tx_ampdu_len:0-1", - "tx_ampdu_len:2-10", - "tx_ampdu_len:11-19", - "tx_ampdu_len:20-28", - "tx_ampdu_len:29-37", - "tx_ampdu_len:38-46", - "tx_ampdu_len:47-55", - "tx_ampdu_len:56-79", - "tx_ampdu_len:80-103", - "tx_ampdu_len:104-127", - "tx_ampdu_len:128-151", - "tx_ampdu_len:152-175", - "tx_ampdu_len:176-199", - "tx_ampdu_len:200-223", - "tx_ampdu_len:224-247", - "ba_miss_count", - "tx_beamformer_ppdu_iBF", - "tx_beamformer_ppdu_eBF", - "tx_beamformer_rx_feedback_all", - "tx_beamformer_rx_feedback_he", - "tx_beamformer_rx_feedback_vht", - "tx_beamformer_rx_feedback_ht", - "tx_msdu_pack_1", - "tx_msdu_pack_2", - "tx_msdu_pack_3", - "tx_msdu_pack_4", - "tx_msdu_pack_5", - "tx_msdu_pack_6", - "tx_msdu_pack_7", - "tx_msdu_pack_8", - /* rx counters */ - "rx_mpdu_cnt", - "rx_ampdu_cnt", - "rx_ampdu_bytes_cnt", - "rx_ba_cnt", - /* per vif counters */ - "v_tx_mode_cck", - "v_tx_mode_ofdm", - "v_tx_mode_ht", - "v_tx_mode_ht_gf", - "v_tx_mode_vht", - "v_tx_mode_he_su", - "v_tx_mode_he_ext_su", - "v_tx_mode_he_tb", - "v_tx_mode_he_mu", - "v_tx_bw_20", - "v_tx_bw_40", - "v_tx_bw_80", - "v_tx_bw_160", - "v_tx_mcs_0", - "v_tx_mcs_1", - "v_tx_mcs_2", - "v_tx_mcs_3", - "v_tx_mcs_4", - "v_tx_mcs_5", - "v_tx_mcs_6", - "v_tx_mcs_7", - "v_tx_mcs_8", - "v_tx_mcs_9", - "v_tx_mcs_10", - "v_tx_mcs_11", -}; - -static void -mt7921_get_et_strings(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - u32 sset, u8 *data) -{ - struct mt7921_dev *dev = mt7921_hw_dev(hw); - - if (sset != ETH_SS_STATS) - return; - - memcpy(data, *mt7921_gstrings_stats, sizeof(mt7921_gstrings_stats)); - - if (mt76_is_sdio(&dev->mt76)) - return; - - data += sizeof(mt7921_gstrings_stats); - page_pool_ethtool_stats_get_strings(data); -} - -static int -mt7921_get_et_sset_count(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - int sset) -{ - struct mt7921_dev *dev = mt7921_hw_dev(hw); - - if (sset != ETH_SS_STATS) - return 0; - - if (mt76_is_sdio(&dev->mt76)) - return ARRAY_SIZE(mt7921_gstrings_stats); - - return ARRAY_SIZE(mt7921_gstrings_stats) + - page_pool_ethtool_stats_get_count(); -} - -static void -mt7921_ethtool_worker(void *wi_data, struct ieee80211_sta *sta) -{ - struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv; - struct mt76_ethtool_worker_info *wi = wi_data; - - if (msta->vif->mt76.idx != wi->idx) - return; - - mt76_ethtool_worker(wi, &msta->wcid.stats, false); -} - -static -void mt7921_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ethtool_stats *stats, u64 *data) -{ - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - int stats_size = ARRAY_SIZE(mt7921_gstrings_stats); - struct mt7921_phy *phy = mt7921_hw_phy(hw); - struct mt7921_dev *dev = phy->dev; - struct mib_stats *mib = &phy->mib; - struct mt76_ethtool_worker_info wi = { - .data = data, - .idx = mvif->mt76.idx, - }; - int i, ei = 0; - - mt7921_mutex_acquire(dev); - - mt7921_mac_update_mib_stats(phy); - - data[ei++] = mib->tx_ampdu_cnt; - data[ei++] = mib->tx_mpdu_attempts_cnt; - data[ei++] = mib->tx_mpdu_success_cnt; - data[ei++] = mib->tx_pkt_ebf_cnt; - data[ei++] = mib->tx_pkt_ibf_cnt; - - /* Tx ampdu stat */ - for (i = 0; i < 15; i++) - data[ei++] = phy->mt76->aggr_stats[i]; - - data[ei++] = phy->mib.ba_miss_cnt; - - /* Tx Beamformer monitor */ - data[ei++] = mib->tx_bf_ibf_ppdu_cnt; - data[ei++] = mib->tx_bf_ebf_ppdu_cnt; - - /* Tx Beamformer Rx feedback monitor */ - data[ei++] = mib->tx_bf_rx_fb_all_cnt; - data[ei++] = mib->tx_bf_rx_fb_he_cnt; - data[ei++] = mib->tx_bf_rx_fb_vht_cnt; - data[ei++] = mib->tx_bf_rx_fb_ht_cnt; - - /* Tx amsdu info (pack-count histogram) */ - for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++) - data[ei++] = mib->tx_amsdu[i]; - - /* rx counters */ - data[ei++] = mib->rx_mpdu_cnt; - data[ei++] = mib->rx_ampdu_cnt; - data[ei++] = mib->rx_ampdu_bytes_cnt; - data[ei++] = mib->rx_ba_cnt; - - /* Add values for all stations owned by this vif */ - wi.initial_stat_idx = ei; - ieee80211_iterate_stations_atomic(hw, mt7921_ethtool_worker, &wi); - - mt7921_mutex_release(dev); - - if (!wi.sta_count) - return; - - ei += wi.worker_stat_count; - - if (!mt76_is_sdio(&dev->mt76)) { - mt76_ethtool_page_pool_stats(&dev->mt76, &data[ei], &ei); - stats_size += page_pool_ethtool_stats_get_count(); - } - - if (ei != stats_size) - dev_err(dev->mt76.dev, "ei: %d SSTATS_LEN: %d", ei, stats_size); -} - -static u64 -mt7921_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_dev *dev = mt7921_hw_dev(hw); - u8 omac_idx = mvif->mt76.omac_idx; - union { - u64 t64; - u32 t32[2]; - } tsf; - u16 n; - - mt7921_mutex_acquire(dev); - - n = omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : omac_idx; - /* TSF software read */ - mt76_set(dev, MT_LPON_TCR(0, n), MT_LPON_TCR_SW_MODE); - tsf.t32[0] = mt76_rr(dev, MT_LPON_UTTR0(0)); - tsf.t32[1] = mt76_rr(dev, MT_LPON_UTTR1(0)); - - mt7921_mutex_release(dev); - - return tsf.t64; -} - -static void -mt7921_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - u64 timestamp) -{ - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_dev *dev = mt7921_hw_dev(hw); - u8 omac_idx = mvif->mt76.omac_idx; - union { - u64 t64; - u32 t32[2]; - } tsf = { .t64 = timestamp, }; - u16 n; - - mt7921_mutex_acquire(dev); - - n = omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : omac_idx; - mt76_wr(dev, MT_LPON_UTTR0(0), tsf.t32[0]); - mt76_wr(dev, MT_LPON_UTTR1(0), tsf.t32[1]); - /* TSF software overwrite */ - mt76_set(dev, MT_LPON_TCR(0, n), MT_LPON_TCR_SW_WRITE); - - mt7921_mutex_release(dev); -} - -static void -mt7921_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) -{ - struct mt7921_phy *phy = mt7921_hw_phy(hw); - struct mt7921_dev *dev = phy->dev; - - mt7921_mutex_acquire(dev); - phy->coverage_class = max_t(s16, coverage_class, 0); - mt7921_mac_set_timing(phy); - mt7921_mutex_release(dev); -} - void mt7921_scan_work(struct work_struct *work) { - struct mt7921_phy *phy; + struct mt792x_phy *phy; - phy = (struct mt7921_phy *)container_of(work, struct mt7921_phy, + phy = (struct mt792x_phy *)container_of(work, struct mt792x_phy, scan_work.work); while (true) { @@ -1294,13 +925,13 @@ static int mt7921_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_scan_request *req) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); struct mt76_phy *mphy = hw->priv; int err; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); err = mt76_connac_mcu_hw_scan(mphy, vif, req); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return err; } @@ -1308,12 +939,12 @@ mt7921_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, static void mt7921_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); struct mt76_phy *mphy = hw->priv; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); mt76_connac_mcu_cancel_hw_scan(mphy, vif); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); } static int @@ -1321,11 +952,11 @@ mt7921_start_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_sched_scan_request *req, struct ieee80211_scan_ies *ies) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); struct mt76_phy *mphy = hw->priv; int err; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); err = mt76_connac_mcu_sched_scan_req(mphy, vif, req); if (err < 0) @@ -1333,7 +964,7 @@ mt7921_start_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, err = mt76_connac_mcu_sched_scan_enable(mphy, vif, true); out: - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return err; } @@ -1341,13 +972,13 @@ out: static int mt7921_stop_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); struct mt76_phy *mphy = hw->priv; int err; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); err = mt76_connac_mcu_sched_scan_enable(mphy, vif, false); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return err; } @@ -1355,17 +986,17 @@ mt7921_stop_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif) static int mt7921_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); - struct mt7921_phy *phy = mt7921_hw_phy(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt792x_phy *phy = mt792x_hw_phy(hw); int max_nss = hweight8(hw->wiphy->available_antennas_tx); if (!tx_ant || tx_ant != rx_ant || ffs(tx_ant) > max_nss) return -EINVAL; if ((BIT(hweight8(tx_ant)) - 1) != tx_ant) - tx_ant = BIT(ffs(tx_ant) - 1) - 1; + return -EINVAL; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); phy->mt76->antenna_mask = tx_ant; phy->mt76->chainmask = tx_ant; @@ -1373,48 +1004,17 @@ mt7921_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) mt76_set_stream_caps(phy->mt76, true); mt7921_set_stream_he_caps(phy); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return 0; } -static void mt7921_sta_statistics(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct station_info *sinfo) -{ - struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv; - struct rate_info *txrate = &msta->wcid.rate; - - if (!txrate->legacy && !txrate->flags) - return; - - if (txrate->legacy) { - sinfo->txrate.legacy = txrate->legacy; - } else { - sinfo->txrate.mcs = txrate->mcs; - sinfo->txrate.nss = txrate->nss; - sinfo->txrate.bw = txrate->bw; - sinfo->txrate.he_gi = txrate->he_gi; - sinfo->txrate.he_dcm = txrate->he_dcm; - sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc; - } - sinfo->txrate.flags = txrate->flags; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); - - sinfo->ack_signal = (s8)msta->ack_signal; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL); - - sinfo->avg_ack_signal = -(s8)ewma_avg_signal_read(&msta->avg_ack_signal); - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG); -} - #ifdef CONFIG_PM static int mt7921_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); - struct mt7921_phy *phy = mt7921_hw_phy(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt792x_phy *phy = mt792x_hw_phy(hw); cancel_delayed_work_sync(&phy->scan_work); cancel_delayed_work_sync(&phy->mt76->mac_work); @@ -1422,7 +1022,7 @@ static int mt7921_suspend(struct ieee80211_hw *hw, cancel_delayed_work_sync(&dev->pm.ps_work); mt76_connac_free_pending_tx_skbs(&dev->pm, NULL); - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); clear_bit(MT76_STATE_RUNNING, &phy->mt76->state); ieee80211_iterate_active_interfaces(hw, @@ -1430,17 +1030,17 @@ static int mt7921_suspend(struct ieee80211_hw *hw, mt7921_mcu_set_suspend_iter, &dev->mphy); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return 0; } static int mt7921_resume(struct ieee80211_hw *hw) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); - struct mt7921_phy *phy = mt7921_hw_phy(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt792x_phy *phy = mt792x_hw_phy(hw); - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); set_bit(MT76_STATE_RUNNING, &phy->mt76->state); ieee80211_iterate_active_interfaces(hw, @@ -1449,51 +1049,34 @@ static int mt7921_resume(struct ieee80211_hw *hw) &dev->mphy); ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work, - MT7921_WATCHDOG_TIME); + MT792x_WATCHDOG_TIME); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return 0; } -static void mt7921_set_wakeup(struct ieee80211_hw *hw, bool enabled) -{ - struct mt7921_dev *dev = mt7921_hw_dev(hw); - struct mt76_dev *mdev = &dev->mt76; - - device_set_wakeup_enable(mdev->dev, enabled); -} - static void mt7921_set_rekey_data(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_gtk_rekey_data *data) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); mt76_connac_mcu_update_gtk_rekey(hw, vif, data); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); } #endif /* CONFIG_PM */ -static void mt7921_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - u32 queues, bool drop) -{ - struct mt7921_dev *dev = mt7921_hw_dev(hw); - - wait_event_timeout(dev->mt76.tx_wait, !mt76_has_tx_pending(&dev->mphy), - HZ / 2); -} - static void mt7921_sta_set_decap_offload(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, bool enabled) { - struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv; - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv; + struct mt792x_dev *dev = mt792x_hw_dev(hw); - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); if (enabled) set_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags); @@ -1503,7 +1086,7 @@ static void mt7921_sta_set_decap_offload(struct ieee80211_hw *hw, mt76_connac_mcu_sta_update_hdr_trans(&dev->mt76, vif, &msta->wcid, MCU_UNI_CMD(STA_REC_UPDATE)); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); } #if IS_ENABLED(CONFIG_IPV6) @@ -1511,8 +1094,8 @@ static void mt7921_ipv6_addr_change(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct inet6_dev *idev) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_dev *dev = mvif->phy->dev; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_dev *dev = mvif->phy->dev; struct inet6_ifaddr *ifa; struct in6_addr ns_addrs[IEEE80211_BSS_ARP_ADDR_LIST_LEN]; struct sk_buff *skb; @@ -1570,28 +1153,25 @@ int mt7921_set_tx_sar_pwr(struct ieee80211_hw *hw, const struct cfg80211_sar_specs *sar) { struct mt76_phy *mphy = hw->priv; - int err; if (sar) { - err = mt76_init_sar_power(hw, sar); + int err = mt76_init_sar_power(hw, sar); + if (err) return err; } + mt792x_init_acpi_sar_power(mt792x_hw_phy(hw), !sar); - mt7921_init_acpi_sar_power(mt7921_hw_phy(hw), !sar); - - err = mt76_connac_mcu_set_rate_txpower(mphy); - - return err; + return mt76_connac_mcu_set_rate_txpower(mphy); } static int mt7921_set_sar_specs(struct ieee80211_hw *hw, const struct cfg80211_sar_specs *sar) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); int err; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); err = mt7921_mcu_set_clc(dev, dev->mt76.alpha2, dev->country_ie_env); if (err < 0) @@ -1599,7 +1179,7 @@ static int mt7921_set_sar_specs(struct ieee80211_hw *hw, err = mt7921_set_tx_sar_pwr(hw, sar); out: - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return err; } @@ -1609,23 +1189,23 @@ mt7921_channel_switch_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_chan_def *chandef) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); mt7921_mcu_uni_add_beacon_offload(dev, hw, vif, true); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); } static int mt7921_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_phy *phy = mt7921_hw_phy(hw); - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_phy *phy = mt792x_hw_phy(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); int err; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); err = mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, true, mvif->ctx); @@ -1639,7 +1219,7 @@ mt7921_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, err = mt7921_mcu_sta_update(dev, NULL, vif, true, MT76_STA_INFO_STATE_NONE); out: - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); return err; } @@ -1648,12 +1228,12 @@ static void mt7921_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_phy *phy = mt7921_hw_phy(hw); - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_phy *phy = mt792x_hw_phy(hw); + struct mt792x_dev *dev = mt792x_hw_dev(hw); int err; - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); err = mt7921_mcu_set_bss_pm(dev, vif, false); if (err) @@ -1663,7 +1243,7 @@ mt7921_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mvif->ctx); out: - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); } static int @@ -1682,7 +1262,7 @@ mt7921_remove_chanctx(struct ieee80211_hw *hw, static void mt7921_ctx_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; struct ieee80211_chanctx_conf *ctx = priv; if (ctx != mvif->ctx) @@ -1699,77 +1279,47 @@ mt7921_change_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx, u32 changed) { - struct mt7921_phy *phy = mt7921_hw_phy(hw); + struct mt792x_phy *phy = mt792x_hw_phy(hw); - mt7921_mutex_acquire(phy->dev); + mt792x_mutex_acquire(phy->dev); ieee80211_iterate_active_interfaces(phy->mt76->hw, IEEE80211_IFACE_ITER_ACTIVE, mt7921_ctx_iter, ctx); - mt7921_mutex_release(phy->dev); -} - -static int -mt7921_assign_vif_chanctx(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *link_conf, - struct ieee80211_chanctx_conf *ctx) -{ - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_dev *dev = mt7921_hw_dev(hw); - - mutex_lock(&dev->mt76.mutex); - mvif->ctx = ctx; - mutex_unlock(&dev->mt76.mutex); - - return 0; -} - -static void -mt7921_unassign_vif_chanctx(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *link_conf, - struct ieee80211_chanctx_conf *ctx) -{ - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_dev *dev = mt7921_hw_dev(hw); - - mutex_lock(&dev->mt76.mutex); - mvif->ctx = NULL; - mutex_unlock(&dev->mt76.mutex); + mt792x_mutex_release(phy->dev); } static void mt7921_mgd_prepare_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_prep_tx_info *info) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - struct mt7921_dev *dev = mt7921_hw_dev(hw); + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_dev *dev = mt792x_hw_dev(hw); u16 duration = info->duration ? info->duration : jiffies_to_msecs(HZ); - mt7921_mutex_acquire(dev); + mt792x_mutex_acquire(dev); mt7921_set_roc(mvif->phy, mvif, mvif->ctx->def.chan, duration, MT7921_ROC_REQ_JOIN); - mt7921_mutex_release(dev); + mt792x_mutex_release(dev); } static void mt7921_mgd_complete_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_prep_tx_info *info) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; mt7921_abort_roc(mvif->phy, mvif); } const struct ieee80211_ops mt7921_ops = { - .tx = mt7921_tx, + .tx = mt792x_tx, .start = mt7921_start, .stop = mt7921_stop, .add_interface = mt7921_add_interface, - .remove_interface = mt7921_remove_interface, + .remove_interface = mt792x_remove_interface, .config = mt7921_config, - .conf_tx = mt7921_conf_tx, + .conf_tx = mt792x_conf_tx, .configure_filter = mt7921_configure_filter, .bss_info_changed = mt7921_bss_info_changed, .start_ap = mt7921_start_ap, @@ -1787,19 +1337,19 @@ const struct ieee80211_ops mt7921_ops = { .release_buffered_frames = mt76_release_buffered_frames, .channel_switch_beacon = mt7921_channel_switch_beacon, .get_txpower = mt76_get_txpower, - .get_stats = mt7921_get_stats, - .get_et_sset_count = mt7921_get_et_sset_count, - .get_et_strings = mt7921_get_et_strings, - .get_et_stats = mt7921_get_et_stats, - .get_tsf = mt7921_get_tsf, - .set_tsf = mt7921_set_tsf, + .get_stats = mt792x_get_stats, + .get_et_sset_count = mt792x_get_et_sset_count, + .get_et_strings = mt792x_get_et_strings, + .get_et_stats = mt792x_get_et_stats, + .get_tsf = mt792x_get_tsf, + .set_tsf = mt792x_set_tsf, .get_survey = mt76_get_survey, .get_antenna = mt76_get_antenna, .set_antenna = mt7921_set_antenna, - .set_coverage_class = mt7921_set_coverage_class, + .set_coverage_class = mt792x_set_coverage_class, .hw_scan = mt7921_hw_scan, .cancel_hw_scan = mt7921_cancel_hw_scan, - .sta_statistics = mt7921_sta_statistics, + .sta_statistics = mt792x_sta_statistics, .sched_scan_start = mt7921_start_sched_scan, .sched_scan_stop = mt7921_stop_sched_scan, CFG80211_TESTMODE_CMD(mt7921_testmode_cmd) @@ -1807,18 +1357,18 @@ const struct ieee80211_ops mt7921_ops = { #ifdef CONFIG_PM .suspend = mt7921_suspend, .resume = mt7921_resume, - .set_wakeup = mt7921_set_wakeup, + .set_wakeup = mt792x_set_wakeup, .set_rekey_data = mt7921_set_rekey_data, #endif /* CONFIG_PM */ - .flush = mt7921_flush, + .flush = mt792x_flush, .set_sar_specs = mt7921_set_sar_specs, .remain_on_channel = mt7921_remain_on_channel, .cancel_remain_on_channel = mt7921_cancel_remain_on_channel, .add_chanctx = mt7921_add_chanctx, .remove_chanctx = mt7921_remove_chanctx, .change_chanctx = mt7921_change_chanctx, - .assign_vif_chanctx = mt7921_assign_vif_chanctx, - .unassign_vif_chanctx = mt7921_unassign_vif_chanctx, + .assign_vif_chanctx = mt792x_assign_vif_chanctx, + .unassign_vif_chanctx = mt792x_unassign_vif_chanctx, .mgd_prepare_tx = mt7921_mgd_prepare_tx, .mgd_complete_tx = mt7921_mgd_complete_tx, }; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index f55caa00ac69..90c93970acab 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -4,9 +4,9 @@ #include <linux/fs.h> #include <linux/firmware.h> #include "mt7921.h" -#include "mt7921_trace.h" #include "mcu.h" #include "../mt76_connac2_mac.h" +#include "../mt792x_trace.h" #define MT_STA_BFER BIT(0) #define MT_STA_BFEE BIT(1) @@ -25,7 +25,7 @@ int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd, if (!skb) { dev_err(mdev->dev, "Message %08x (seq %d) timeout\n", cmd, seq); - mt7921_reset(mdev); + mt792x_reset(mdev); return -ETIMEDOUT; } @@ -69,7 +69,7 @@ int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd, } EXPORT_SYMBOL_GPL(mt7921_mcu_parse_response); -static int mt7921_mcu_read_eeprom(struct mt7921_dev *dev, u32 offset, u8 *val) +static int mt7921_mcu_read_eeprom(struct mt792x_dev *dev, u32 offset, u8 *val) { struct mt7921_mcu_eeprom_info *res, req = { .addr = cpu_to_le32(round_down(offset, @@ -96,7 +96,7 @@ static int mt7921_mcu_set_ipv6_ns_filter(struct mt76_dev *dev, struct ieee80211_vif *vif, bool suspend) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; struct { struct { u8 bss_idx; @@ -134,7 +134,7 @@ void mt7921_mcu_set_suspend_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) #endif /* CONFIG_PM */ static void -mt7921_mcu_uni_roc_event(struct mt7921_dev *dev, struct sk_buff *skb) +mt7921_mcu_uni_roc_event(struct mt792x_dev *dev, struct sk_buff *skb) { struct mt7921_roc_grant_tlv *grant; struct mt76_connac2_mcu_rxd *rxd; @@ -157,17 +157,17 @@ mt7921_mcu_uni_roc_event(struct mt7921_dev *dev, struct sk_buff *skb) } static void -mt7921_mcu_scan_event(struct mt7921_dev *dev, struct sk_buff *skb) +mt7921_mcu_scan_event(struct mt792x_dev *dev, struct sk_buff *skb) { struct mt76_phy *mphy = &dev->mt76.phy; - struct mt7921_phy *phy = (struct mt7921_phy *)mphy->priv; + struct mt792x_phy *phy = (struct mt792x_phy *)mphy->priv; spin_lock_bh(&dev->mt76.lock); __skb_queue_tail(&phy->scan_event_list, skb); spin_unlock_bh(&dev->mt76.lock); ieee80211_queue_delayed_work(mphy->hw, &phy->scan_work, - MT7921_HW_SCAN_TIMEOUT); + MT792x_HW_SCAN_TIMEOUT); } static void @@ -188,7 +188,7 @@ mt7921_mcu_connection_loss_iter(void *priv, u8 *mac, } static void -mt7921_mcu_connection_loss_event(struct mt7921_dev *dev, struct sk_buff *skb) +mt7921_mcu_connection_loss_event(struct mt792x_dev *dev, struct sk_buff *skb) { struct mt76_connac_beacon_loss_event *event; struct mt76_phy *mphy = &dev->mt76.phy; @@ -202,7 +202,7 @@ mt7921_mcu_connection_loss_event(struct mt7921_dev *dev, struct sk_buff *skb) } static void -mt7921_mcu_debug_msg_event(struct mt7921_dev *dev, struct sk_buff *skb) +mt7921_mcu_debug_msg_event(struct mt792x_dev *dev, struct sk_buff *skb) { struct mt7921_debug_msg { __le16 id; @@ -229,7 +229,7 @@ mt7921_mcu_debug_msg_event(struct mt7921_dev *dev, struct sk_buff *skb) } static void -mt7921_mcu_low_power_event(struct mt7921_dev *dev, struct sk_buff *skb) +mt7921_mcu_low_power_event(struct mt792x_dev *dev, struct sk_buff *skb) { struct mt7921_mcu_lp_event { u8 state; @@ -243,7 +243,7 @@ mt7921_mcu_low_power_event(struct mt7921_dev *dev, struct sk_buff *skb) } static void -mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb) +mt7921_mcu_tx_done_event(struct mt792x_dev *dev, struct sk_buff *skb) { struct mt7921_mcu_tx_done_event *event; @@ -254,7 +254,7 @@ mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb) } static void -mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb) +mt7921_mcu_rx_unsolicited_event(struct mt792x_dev *dev, struct sk_buff *skb) { struct mt76_connac2_mcu_rxd *rxd; @@ -288,7 +288,7 @@ mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb) } static void -mt7921_mcu_uni_rx_unsolicited_event(struct mt7921_dev *dev, +mt7921_mcu_uni_rx_unsolicited_event(struct mt792x_dev *dev, struct sk_buff *skb) { struct mt76_connac2_mcu_rxd *rxd; @@ -305,7 +305,7 @@ mt7921_mcu_uni_rx_unsolicited_event(struct mt7921_dev *dev, dev_kfree_skb(skb); } -void mt7921_mcu_rx_event(struct mt7921_dev *dev, struct sk_buff *skb) +void mt7921_mcu_rx_event(struct mt792x_dev *dev, struct sk_buff *skb) { struct mt76_connac2_mcu_rxd *rxd; @@ -339,11 +339,11 @@ void mt7921_mcu_rx_event(struct mt7921_dev *dev, struct sk_buff *skb) } /** starec & wtbl **/ -int mt7921_mcu_uni_tx_ba(struct mt7921_dev *dev, +int mt7921_mcu_uni_tx_ba(struct mt792x_dev *dev, struct ieee80211_ampdu_params *params, bool enable) { - struct mt7921_sta *msta = (struct mt7921_sta *)params->sta->drv_priv; + struct mt792x_sta *msta = (struct mt792x_sta *)params->sta->drv_priv; if (enable && !params->amsdu) msta->wcid.amsdu = false; @@ -353,48 +353,24 @@ int mt7921_mcu_uni_tx_ba(struct mt7921_dev *dev, enable, true); } -int mt7921_mcu_uni_rx_ba(struct mt7921_dev *dev, +int mt7921_mcu_uni_rx_ba(struct mt792x_dev *dev, struct ieee80211_ampdu_params *params, bool enable) { - struct mt7921_sta *msta = (struct mt7921_sta *)params->sta->drv_priv; + struct mt792x_sta *msta = (struct mt792x_sta *)params->sta->drv_priv; return mt76_connac_mcu_sta_ba(&dev->mt76, &msta->vif->mt76, params, MCU_UNI_CMD(STA_REC_UPDATE), enable, false); } -static char *mt7921_patch_name(struct mt7921_dev *dev) -{ - char *ret; - - if (is_mt7922(&dev->mt76)) - ret = MT7922_ROM_PATCH; - else - ret = MT7921_ROM_PATCH; - - return ret; -} - -static char *mt7921_ram_name(struct mt7921_dev *dev) -{ - char *ret; - - if (is_mt7922(&dev->mt76)) - ret = MT7922_FIRMWARE_WM; - else - ret = MT7921_FIRMWARE_WM; - - return ret; -} - -static int mt7921_load_clc(struct mt7921_dev *dev, const char *fw_name) +static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name) { const struct mt76_connac2_fw_trailer *hdr; const struct mt76_connac2_fw_region *region; const struct mt7921_clc *clc; struct mt76_dev *mdev = &dev->mt76; - struct mt7921_phy *phy = &dev->phy; + struct mt792x_phy *phy = &dev->phy; const struct firmware *fw; int ret, i, len, offset = 0; u8 *clc_base = NULL, hw_encap = 0; @@ -472,42 +448,7 @@ out: return ret; } -static int mt7921_load_firmware(struct mt7921_dev *dev) -{ - int ret; - - ret = mt76_connac2_load_patch(&dev->mt76, mt7921_patch_name(dev)); - if (ret) - return ret; - - if (mt76_is_sdio(&dev->mt76)) { - /* activate again */ - ret = __mt7921_mcu_fw_pmctrl(dev); - if (!ret) - ret = __mt7921_mcu_drv_pmctrl(dev); - } - - ret = mt76_connac2_load_ram(&dev->mt76, mt7921_ram_name(dev), NULL); - if (ret) - return ret; - - if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY, - MT_TOP_MISC2_FW_N9_RDY, 1500)) { - dev_err(dev->mt76.dev, "Timeout for initializing firmware\n"); - - return -EIO; - } - -#ifdef CONFIG_PM - dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support; -#endif /* CONFIG_PM */ - - dev_dbg(dev->mt76.dev, "Firmware init done\n"); - - return 0; -} - -int mt7921_mcu_fw_log_2_host(struct mt7921_dev *dev, u8 ctrl) +int mt7921_mcu_fw_log_2_host(struct mt792x_dev *dev, u8 ctrl) { struct { u8 ctrl_val; @@ -520,11 +461,11 @@ int mt7921_mcu_fw_log_2_host(struct mt7921_dev *dev, u8 ctrl) &data, sizeof(data), false); } -int mt7921_run_firmware(struct mt7921_dev *dev) +int mt7921_run_firmware(struct mt792x_dev *dev) { int err; - err = mt7921_load_firmware(dev); + err = mt792x_load_firmware(dev); if (err) return err; @@ -533,7 +474,7 @@ int mt7921_run_firmware(struct mt7921_dev *dev) return err; set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); - err = mt7921_load_clc(dev, mt7921_ram_name(dev)); + err = mt7921_load_clc(dev, mt792x_ram_name(dev)); if (err) return err; @@ -541,9 +482,9 @@ int mt7921_run_firmware(struct mt7921_dev *dev) } EXPORT_SYMBOL_GPL(mt7921_run_firmware); -int mt7921_mcu_set_tx(struct mt7921_dev *dev, struct ieee80211_vif *vif) +int mt7921_mcu_set_tx(struct mt792x_dev *dev, struct ieee80211_vif *vif) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; struct edca { __le16 cw_min; __le16 cw_max; @@ -635,12 +576,12 @@ int mt7921_mcu_set_tx(struct mt7921_dev *dev, struct ieee80211_vif *vif) &req_mu, sizeof(req_mu), false); } -int mt7921_mcu_set_roc(struct mt7921_phy *phy, struct mt7921_vif *vif, +int mt7921_mcu_set_roc(struct mt792x_phy *phy, struct mt792x_vif *vif, struct ieee80211_channel *chan, int duration, enum mt7921_roc_req type, u8 token_id) { int center_ch = ieee80211_frequency_to_channel(chan->center_freq); - struct mt7921_dev *dev = phy->dev; + struct mt792x_dev *dev = phy->dev; struct { struct { u8 rsv[4]; @@ -702,10 +643,10 @@ int mt7921_mcu_set_roc(struct mt7921_phy *phy, struct mt7921_vif *vif, &req, sizeof(req), false); } -int mt7921_mcu_abort_roc(struct mt7921_phy *phy, struct mt7921_vif *vif, +int mt7921_mcu_abort_roc(struct mt792x_phy *phy, struct mt792x_vif *vif, u8 token_id) { - struct mt7921_dev *dev = phy->dev; + struct mt792x_dev *dev = phy->dev; struct { struct { u8 rsv[4]; @@ -732,9 +673,9 @@ int mt7921_mcu_abort_roc(struct mt7921_phy *phy, struct mt7921_vif *vif, &req, sizeof(req), false); } -int mt7921_mcu_set_chan_info(struct mt7921_phy *phy, int cmd) +int mt7921_mcu_set_chan_info(struct mt792x_phy *phy, int cmd) { - struct mt7921_dev *dev = phy->dev; + struct mt792x_dev *dev = phy->dev; struct cfg80211_chan_def *chandef = &phy->mt76->chandef; int freq1 = chandef->center_freq1; struct { @@ -791,7 +732,7 @@ int mt7921_mcu_set_chan_info(struct mt7921_phy *phy, int cmd) return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), true); } -int mt7921_mcu_set_eeprom(struct mt7921_dev *dev) +int mt7921_mcu_set_eeprom(struct mt792x_dev *dev) { struct req_hdr { u8 buffer_mode; @@ -807,9 +748,9 @@ int mt7921_mcu_set_eeprom(struct mt7921_dev *dev) } EXPORT_SYMBOL_GPL(mt7921_mcu_set_eeprom); -int mt7921_mcu_uni_bss_ps(struct mt7921_dev *dev, struct ieee80211_vif *vif) +int mt7921_mcu_uni_bss_ps(struct mt792x_dev *dev, struct ieee80211_vif *vif) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; struct { struct { u8 bss_idx; @@ -845,10 +786,10 @@ int mt7921_mcu_uni_bss_ps(struct mt7921_dev *dev, struct ieee80211_vif *vif) } static int -mt7921_mcu_uni_bss_bcnft(struct mt7921_dev *dev, struct ieee80211_vif *vif, +mt7921_mcu_uni_bss_bcnft(struct mt792x_dev *dev, struct ieee80211_vif *vif, bool enable) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; struct { struct { u8 bss_idx; @@ -881,10 +822,10 @@ mt7921_mcu_uni_bss_bcnft(struct mt7921_dev *dev, struct ieee80211_vif *vif, } int -mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif, +mt7921_mcu_set_bss_pm(struct mt792x_dev *dev, struct ieee80211_vif *vif, bool enable) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; struct { u8 bss_idx; u8 dtim_period; @@ -918,11 +859,11 @@ mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif, &req, sizeof(req), false); } -int mt7921_mcu_sta_update(struct mt7921_dev *dev, struct ieee80211_sta *sta, +int mt7921_mcu_sta_update(struct mt792x_dev *dev, struct ieee80211_sta *sta, struct ieee80211_vif *vif, bool enable, enum mt76_sta_info_state state) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; int rssi = -ewma_rssi_read(&mvif->rssi); struct mt76_sta_cmd_info info = { .sta = sta, @@ -933,60 +874,16 @@ int mt7921_mcu_sta_update(struct mt7921_dev *dev, struct ieee80211_sta *sta, .offload_fw = true, .rcpi = to_rcpi(rssi), }; - struct mt7921_sta *msta; + struct mt792x_sta *msta; - msta = sta ? (struct mt7921_sta *)sta->drv_priv : NULL; + msta = sta ? (struct mt792x_sta *)sta->drv_priv : NULL; info.wcid = msta ? &msta->wcid : &mvif->sta.wcid; info.newly = msta ? state != MT76_STA_INFO_STATE_ASSOC : true; return mt76_connac_mcu_sta_cmd(&dev->mphy, &info); } -int mt7921_mcu_drv_pmctrl(struct mt7921_dev *dev) -{ - struct mt76_phy *mphy = &dev->mt76.phy; - struct mt76_connac_pm *pm = &dev->pm; - int err = 0; - - mutex_lock(&pm->mutex); - - if (!test_bit(MT76_STATE_PM, &mphy->state)) - goto out; - - err = __mt7921_mcu_drv_pmctrl(dev); -out: - mutex_unlock(&pm->mutex); - - if (err) - mt7921_reset(&dev->mt76); - - return err; -} -EXPORT_SYMBOL_GPL(mt7921_mcu_drv_pmctrl); - -int mt7921_mcu_fw_pmctrl(struct mt7921_dev *dev) -{ - struct mt76_phy *mphy = &dev->mt76.phy; - struct mt76_connac_pm *pm = &dev->pm; - int err = 0; - - mutex_lock(&pm->mutex); - - if (mt76_connac_skip_fw_pmctrl(mphy, pm)) - goto out; - - err = __mt7921_mcu_fw_pmctrl(dev); -out: - mutex_unlock(&pm->mutex); - - if (err) - mt7921_reset(&dev->mt76); - - return err; -} -EXPORT_SYMBOL_GPL(mt7921_mcu_fw_pmctrl); - -int mt7921_mcu_set_beacon_filter(struct mt7921_dev *dev, +int mt7921_mcu_set_beacon_filter(struct mt792x_dev *dev, struct ieee80211_vif *vif, bool enable) { @@ -1021,7 +918,7 @@ int mt7921_mcu_set_beacon_filter(struct mt7921_dev *dev, return 0; } -int mt7921_get_txpwr_info(struct mt7921_dev *dev, struct mt7921_txpwr *txpwr) +int mt7921_get_txpwr_info(struct mt792x_dev *dev, struct mt7921_txpwr *txpwr) { struct mt7921_txpwr_event *event; struct mt7921_txpwr_req req = { @@ -1044,7 +941,7 @@ int mt7921_get_txpwr_info(struct mt7921_dev *dev, struct mt7921_txpwr *txpwr) return 0; } -int mt7921_mcu_set_sniffer(struct mt7921_dev *dev, struct ieee80211_vif *vif, +int mt7921_mcu_set_sniffer(struct mt792x_dev *dev, struct ieee80211_vif *vif, bool enable) { struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; @@ -1074,7 +971,7 @@ int mt7921_mcu_set_sniffer(struct mt7921_dev *dev, struct ieee80211_vif *vif, true); } -int mt7921_mcu_config_sniffer(struct mt7921_vif *vif, +int mt7921_mcu_config_sniffer(struct mt792x_vif *vif, struct ieee80211_chanctx_conf *ctx) { struct cfg80211_chan_def *chandef = &ctx->def; @@ -1143,12 +1040,12 @@ int mt7921_mcu_config_sniffer(struct mt7921_vif *vif, } int -mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev, +mt7921_mcu_uni_add_beacon_offload(struct mt792x_dev *dev, struct ieee80211_hw *hw, struct ieee80211_vif *vif, bool enable) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; struct mt76_wcid *wcid = &dev->mt76.global_wcid; struct ieee80211_mutable_offsets offs; struct { @@ -1221,7 +1118,7 @@ mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev, } static -int __mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2, +int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2, enum environment_cap env_cap, struct mt7921_clc *clc, u8 idx) @@ -1241,7 +1138,7 @@ int __mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2, } __packed req = { .idx = idx, .env = env_cap, - .acpi_conf = mt7921_acpi_get_flags(&dev->phy), + .acpi_conf = mt792x_acpi_get_flags(&dev->phy), }; int ret, valid_cnt = 0; u8 i, *pos; @@ -1283,10 +1180,10 @@ int __mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2, return 0; } -int mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2, +int mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2, enum environment_cap env_cap) { - struct mt7921_phy *phy = (struct mt7921_phy *)&dev->phy; + struct mt792x_phy *phy = (struct mt792x_phy *)&dev->phy; int i, ret; /* submit all clc config */ @@ -1305,7 +1202,24 @@ int mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2, return 0; } -int mt7921_mcu_set_rxfilter(struct mt7921_dev *dev, u32 fif, +int mt7921_mcu_get_temperature(struct mt792x_phy *phy) +{ + struct mt792x_dev *dev = phy->dev; + struct { + u8 ctrl_id; + u8 action; + u8 band_idx; + u8 rsv[5]; + } req = { + .ctrl_id = THERMAL_SENSOR_TEMP_QUERY, + .band_idx = phy->mt76->band_idx, + }; + + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(THERMAL_CTRL), &req, + sizeof(req), true); +} + +int mt7921_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif, u8 bit_op, u32 bit_map) { struct { diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index 149acb1662d5..87dd06855f68 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -4,22 +4,8 @@ #ifndef __MT7921_H #define __MT7921_H -#include <linux/interrupt.h> -#include <linux/ktime.h> -#include "../mt76_connac_mcu.h" +#include "../mt792x.h" #include "regs.h" -#include "acpi_sar.h" - -#define MT7921_MAX_INTERFACES 4 -#define MT7921_WTBL_SIZE 20 -#define MT7921_WTBL_RESERVED (MT7921_WTBL_SIZE - 1) -#define MT7921_WTBL_STA (MT7921_WTBL_RESERVED - \ - MT7921_MAX_INTERFACES) - -#define MT7921_PM_TIMEOUT (HZ / 12) -#define MT7921_HW_SCAN_TIMEOUT (HZ / 10) -#define MT7921_WATCHDOG_TIME (HZ / 4) -#define MT7921_RESET_TIMEOUT (30 * HZ) #define MT7921_TX_RING_SIZE 2048 #define MT7921_TX_MCU_RING_SIZE 256 @@ -28,27 +14,11 @@ #define MT7921_RX_RING_SIZE 1536 #define MT7921_RX_MCU_RING_SIZE 512 -#define MT7921_DRV_OWN_RETRY_COUNT 10 -#define MT7921_MCU_INIT_RETRY_COUNT 10 -#define MT7921_WFSYS_INIT_RETRY_COUNT 2 - -#define MT7921_FW_TAG_FEATURE 4 -#define MT7921_FW_CAP_CNM BIT(7) - -#define MT7921_FIRMWARE_WM "mediatek/WIFI_RAM_CODE_MT7961_1.bin" -#define MT7921_ROM_PATCH "mediatek/WIFI_MT7961_patch_mcu_1_2_hdr.bin" - -#define MT7922_FIRMWARE_WM "mediatek/WIFI_RAM_CODE_MT7922_1.bin" -#define MT7922_ROM_PATCH "mediatek/WIFI_MT7922_patch_mcu_1_1_hdr.bin" - #define MT7921_EEPROM_SIZE 3584 #define MT7921_TOKEN_SIZE 8192 #define MT7921_EEPROM_BLOCK_SIZE 16 -#define MT7921_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */ -#define MT7921_CFEND_RATE_11B 0x03 /* 11B LP, 11M */ - #define MT7921_SKU_RATE_NUM 161 #define MT7921_SKU_MAX_DELTA_IDX MT7921_SKU_RATE_NUM #define MT7921_SKU_TABLE_SIZE (MT7921_SKU_RATE_NUM + 1) @@ -128,9 +98,6 @@ struct mt7921_sdio_intr { #define to_rssi(field, rxv) ((FIELD_GET(field, rxv) - 220) / 2) #define to_rcpi(rssi) (2 * (rssi) + 220) -struct mt7921_vif; -struct mt7921_sta; - enum mt7921_txq_id { MT7921_TXQ_BAND0, MT7921_TXQ_BAND1, @@ -144,70 +111,6 @@ enum mt7921_rxq_id { MT7921_RXQ_MCU_WM = 0, }; -DECLARE_EWMA(avg_signal, 10, 8) - -struct mt7921_sta { - struct mt76_wcid wcid; /* must be first */ - - struct mt7921_vif *vif; - - struct list_head poll_list; - u32 airtime_ac[8]; - - int ack_signal; - struct ewma_avg_signal avg_ack_signal; - - unsigned long last_txs; - unsigned long ampdu_state; - - struct mt76_connac_sta_key_conf bip; -}; - -DECLARE_EWMA(rssi, 10, 8); - -struct mt7921_vif { - struct mt76_vif mt76; /* must be first */ - - struct mt7921_sta sta; - struct mt7921_sta *wep_sta; - - struct mt7921_phy *phy; - - struct ewma_rssi rssi; - - struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; - struct ieee80211_chanctx_conf *ctx; -}; - -struct mib_stats { - u32 ack_fail_cnt; - u32 fcs_err_cnt; - u32 rts_cnt; - u32 rts_retries_cnt; - u32 ba_miss_cnt; - - u32 tx_bf_ibf_ppdu_cnt; - u32 tx_bf_ebf_ppdu_cnt; - u32 tx_bf_rx_fb_all_cnt; - u32 tx_bf_rx_fb_he_cnt; - u32 tx_bf_rx_fb_vht_cnt; - u32 tx_bf_rx_fb_ht_cnt; - - u32 tx_ampdu_cnt; - u32 tx_mpdu_attempts_cnt; - u32 tx_mpdu_success_cnt; - u32 tx_pkt_ebf_cnt; - u32 tx_pkt_ibf_cnt; - - u32 rx_mpdu_cnt; - u32 rx_ampdu_cnt; - u32 rx_ampdu_bytes_cnt; - u32 rx_ba_cnt; - - u32 tx_amsdu[8]; - u32 tx_amsdu_cnt; -}; - enum { MT7921_CLC_POWER, MT7921_CLC_CHAN, @@ -231,41 +134,6 @@ struct mt7921_clc { u8 data[]; } __packed; -struct mt7921_phy { - struct mt76_phy *mt76; - struct mt7921_dev *dev; - - struct ieee80211_sband_iftype_data iftype[NUM_NL80211_BANDS][NUM_NL80211_IFTYPES]; - - u64 omac_mask; - - u16 noise; - - s16 coverage_class; - u8 slottime; - - u32 rx_ampdu_ts; - u32 ampdu_ref; - - struct mib_stats mib; - - u8 sta_work_count; - - struct sk_buff_head scan_event_list; - struct delayed_work scan_work; -#ifdef CONFIG_ACPI - struct mt7921_acpi_sar *acpisar; -#endif - - struct mt7921_clc *clc[MT7921_CLC_MAX_NUM]; - - struct work_struct roc_work; - struct timer_list roc_timer; - wait_queue_head_t roc_wait; - u8 roc_token_id; - bool roc_grant; -}; - enum mt7921_eeprom_field { MT_EE_CHIP_ID = 0x000, MT_EE_VERSION = 0x002, @@ -277,52 +145,6 @@ enum mt7921_eeprom_field { #define MT_EE_HW_TYPE_ENCAP BIT(0) -#define mt7921_init_reset(dev) ((dev)->hif_ops->init_reset(dev)) -#define mt7921_dev_reset(dev) ((dev)->hif_ops->reset(dev)) -#define mt7921_mcu_init(dev) ((dev)->hif_ops->mcu_init(dev)) -#define __mt7921_mcu_drv_pmctrl(dev) ((dev)->hif_ops->drv_own(dev)) -#define __mt7921_mcu_fw_pmctrl(dev) ((dev)->hif_ops->fw_own(dev)) -struct mt7921_hif_ops { - int (*init_reset)(struct mt7921_dev *dev); - int (*reset)(struct mt7921_dev *dev); - int (*mcu_init)(struct mt7921_dev *dev); - int (*drv_own)(struct mt7921_dev *dev); - int (*fw_own)(struct mt7921_dev *dev); -}; - -struct mt7921_dev { - union { /* must be first */ - struct mt76_dev mt76; - struct mt76_phy mphy; - }; - - const struct mt76_bus_ops *bus_ops; - struct mt7921_phy phy; - - struct work_struct reset_work; - bool hw_full_reset:1; - bool hw_init_done:1; - bool fw_assert:1; - - struct list_head sta_poll_list; - spinlock_t sta_poll_lock; - - struct work_struct init_work; - - u8 fw_debug; - u8 fw_features; - - struct mt76_connac_pm pm; - struct mt76_connac_coredump coredump; - const struct mt7921_hif_ops *hif_ops; - - struct work_struct ipv6_ns_work; - /* IPv6 addresses for WoWLAN */ - struct sk_buff_head ipv6_ns_list; - - enum environment_cap country_ie_env; -}; - enum { TXPWR_USER, TXPWR_EEPROM, @@ -353,56 +175,31 @@ struct mt7921_txpwr { } data[TXPWR_MAX_NUM]; }; -static inline struct mt7921_phy * -mt7921_hw_phy(struct ieee80211_hw *hw) -{ - struct mt76_phy *phy = hw->priv; - - return phy->priv; -} - -static inline struct mt7921_dev * -mt7921_hw_dev(struct ieee80211_hw *hw) -{ - struct mt76_phy *phy = hw->priv; - - return container_of(phy->dev, struct mt7921_dev, mt76); -} - -#define mt7921_mutex_acquire(dev) \ - mt76_connac_mutex_acquire(&(dev)->mt76, &(dev)->pm) -#define mt7921_mutex_release(dev) \ - mt76_connac_mutex_release(&(dev)->mt76, &(dev)->pm) - extern const struct ieee80211_ops mt7921_ops; -u32 mt7921_reg_map(struct mt7921_dev *dev, u32 addr); - -int __mt7921_start(struct mt7921_phy *phy); -int mt7921_register_device(struct mt7921_dev *dev); -void mt7921_unregister_device(struct mt7921_dev *dev); -int mt7921_dma_init(struct mt7921_dev *dev); -int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force); -int mt7921_wpdma_reinit_cond(struct mt7921_dev *dev); -void mt7921_dma_cleanup(struct mt7921_dev *dev); -int mt7921_run_firmware(struct mt7921_dev *dev); -int mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif, +u32 mt7921_reg_map(struct mt792x_dev *dev, u32 addr); + +int __mt7921_start(struct mt792x_phy *phy); +int mt7921_register_device(struct mt792x_dev *dev); +void mt7921_unregister_device(struct mt792x_dev *dev); +int mt7921_run_firmware(struct mt792x_dev *dev); +int mt7921_mcu_set_bss_pm(struct mt792x_dev *dev, struct ieee80211_vif *vif, bool enable); -int mt7921_mcu_sta_update(struct mt7921_dev *dev, struct ieee80211_sta *sta, +int mt7921_mcu_sta_update(struct mt792x_dev *dev, struct ieee80211_sta *sta, struct ieee80211_vif *vif, bool enable, enum mt76_sta_info_state state); -int mt7921_mcu_set_chan_info(struct mt7921_phy *phy, int cmd); -int mt7921_mcu_set_tx(struct mt7921_dev *dev, struct ieee80211_vif *vif); -int mt7921_mcu_set_eeprom(struct mt7921_dev *dev); -int mt7921_mcu_get_rx_rate(struct mt7921_phy *phy, struct ieee80211_vif *vif, +int mt7921_mcu_set_chan_info(struct mt792x_phy *phy, int cmd); +int mt7921_mcu_set_tx(struct mt792x_dev *dev, struct ieee80211_vif *vif); +int mt7921_mcu_set_eeprom(struct mt792x_dev *dev); +int mt7921_mcu_get_rx_rate(struct mt792x_phy *phy, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct rate_info *rate); -int mt7921_mcu_fw_log_2_host(struct mt7921_dev *dev, u8 ctrl); -void mt7921_mcu_rx_event(struct mt7921_dev *dev, struct sk_buff *skb); -int mt7921_mcu_set_rxfilter(struct mt7921_dev *dev, u32 fif, +int mt7921_mcu_fw_log_2_host(struct mt792x_dev *dev, u8 ctrl); +void mt7921_mcu_rx_event(struct mt792x_dev *dev, struct sk_buff *skb); +int mt7921_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif, u8 bit_op, u32 bit_map); static inline u32 -mt7921_reg_map_l1(struct mt7921_dev *dev, u32 addr) +mt7921_reg_map_l1(struct mt792x_dev *dev, u32 addr) { u32 offset = FIELD_GET(MT_HIF_REMAP_L1_OFFSET, addr); u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, addr); @@ -415,19 +212,19 @@ mt7921_reg_map_l1(struct mt7921_dev *dev, u32 addr) } static inline u32 -mt7921_l1_rr(struct mt7921_dev *dev, u32 addr) +mt7921_l1_rr(struct mt792x_dev *dev, u32 addr) { return mt76_rr(dev, mt7921_reg_map_l1(dev, addr)); } static inline void -mt7921_l1_wr(struct mt7921_dev *dev, u32 addr, u32 val) +mt7921_l1_wr(struct mt792x_dev *dev, u32 addr, u32 val) { mt76_wr(dev, mt7921_reg_map_l1(dev, addr), val); } static inline u32 -mt7921_l1_rmw(struct mt7921_dev *dev, u32 addr, u32 mask, u32 val) +mt7921_l1_rmw(struct mt792x_dev *dev, u32 addr, u32 mask, u32 val) { val |= mt7921_l1_rr(dev, addr) & ~mask; mt7921_l1_wr(dev, addr, val); @@ -438,13 +235,8 @@ mt7921_l1_rmw(struct mt7921_dev *dev, u32 addr, u32 mask, u32 val) #define mt7921_l1_set(dev, addr, val) mt7921_l1_rmw(dev, addr, 0, val) #define mt7921_l1_clear(dev, addr, val) mt7921_l1_rmw(dev, addr, val, 0) -static inline bool mt7921_dma_need_reinit(struct mt7921_dev *dev) -{ - return !mt76_get_field(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT); -} - static inline void -mt7921_skb_add_usb_sdio_hdr(struct mt7921_dev *dev, struct sk_buff *skb, +mt7921_skb_add_usb_sdio_hdr(struct mt792x_dev *dev, struct sk_buff *skb, int type) { u32 hdr, len; @@ -457,89 +249,69 @@ mt7921_skb_add_usb_sdio_hdr(struct mt7921_dev *dev, struct sk_buff *skb, } void mt7921_stop(struct ieee80211_hw *hw); -int mt7921_mac_init(struct mt7921_dev *dev); -bool mt7921_mac_wtbl_update(struct mt7921_dev *dev, int idx, u32 mask); -void mt7921_mac_reset_counters(struct mt7921_phy *phy); -void mt7921_mac_set_timing(struct mt7921_phy *phy); +int mt7921_mac_init(struct mt792x_dev *dev); +bool mt7921_mac_wtbl_update(struct mt792x_dev *dev, int idx, u32 mask); int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); void mt7921_mac_sta_assoc(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); -void mt7921_mac_work(struct work_struct *work); void mt7921_mac_reset_work(struct work_struct *work); -void mt7921_mac_update_mib_stats(struct mt7921_phy *phy); -void mt7921_reset(struct mt76_dev *mdev); int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, enum mt76_txq_id qid, struct mt76_wcid *wcid, struct ieee80211_sta *sta, struct mt76_tx_info *tx_info); -void mt7921_tx_worker(struct mt76_worker *w); -void mt7921_tx_token_put(struct mt7921_dev *dev); bool mt7921_rx_check(struct mt76_dev *mdev, void *data, int len); void mt7921_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, struct sk_buff *skb, u32 *info); void mt7921_stats_work(struct work_struct *work); -void mt7921_set_stream_he_caps(struct mt7921_phy *phy); -void mt7921_update_channel(struct mt76_phy *mphy); -int mt7921_init_debugfs(struct mt7921_dev *dev); +void mt7921_set_stream_he_caps(struct mt792x_phy *phy); +int mt7921_init_debugfs(struct mt792x_dev *dev); -int mt7921_mcu_set_beacon_filter(struct mt7921_dev *dev, +int mt7921_mcu_set_beacon_filter(struct mt792x_dev *dev, struct ieee80211_vif *vif, bool enable); -int mt7921_mcu_uni_tx_ba(struct mt7921_dev *dev, +int mt7921_mcu_uni_tx_ba(struct mt792x_dev *dev, struct ieee80211_ampdu_params *params, bool enable); -int mt7921_mcu_uni_rx_ba(struct mt7921_dev *dev, +int mt7921_mcu_uni_rx_ba(struct mt792x_dev *dev, struct ieee80211_ampdu_params *params, bool enable); void mt7921_scan_work(struct work_struct *work); void mt7921_roc_work(struct work_struct *work); -void mt7921_roc_timer(struct timer_list *timer); -int mt7921_mcu_uni_bss_ps(struct mt7921_dev *dev, struct ieee80211_vif *vif); -int mt7921_mcu_drv_pmctrl(struct mt7921_dev *dev); -int mt7921_mcu_fw_pmctrl(struct mt7921_dev *dev); -void mt7921_pm_wake_work(struct work_struct *work); -void mt7921_pm_power_save_work(struct work_struct *work); +int mt7921_mcu_uni_bss_ps(struct mt792x_dev *dev, struct ieee80211_vif *vif); void mt7921_coredump_work(struct work_struct *work); -int mt7921_wfsys_reset(struct mt7921_dev *dev); -int mt7921_get_txpwr_info(struct mt7921_dev *dev, struct mt7921_txpwr *txpwr); +int mt7921_get_txpwr_info(struct mt792x_dev *dev, struct mt7921_txpwr *txpwr); int mt7921_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void *data, int len); int mt7921_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, struct netlink_callback *cb, void *data, int len); -void mt7921_txwi_free(struct mt7921_dev *dev, struct mt76_txwi_cache *t, - struct ieee80211_sta *sta, bool clear_status, - struct list_head *free_list); -void mt7921_mac_sta_poll(struct mt7921_dev *dev); int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd, struct sk_buff *skb, int seq); -int mt7921e_driver_own(struct mt7921_dev *dev); -int mt7921e_mac_reset(struct mt7921_dev *dev); -int mt7921e_mcu_init(struct mt7921_dev *dev); -int mt7921s_wfsys_reset(struct mt7921_dev *dev); -int mt7921s_mac_reset(struct mt7921_dev *dev); -int mt7921s_init_reset(struct mt7921_dev *dev); -int __mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev); -int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev); -int mt7921e_mcu_fw_pmctrl(struct mt7921_dev *dev); - -int mt7921s_mcu_init(struct mt7921_dev *dev); -int mt7921s_mcu_drv_pmctrl(struct mt7921_dev *dev); -int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev); -void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data); -void mt7921_set_runtime_pm(struct mt7921_dev *dev); +int mt7921e_driver_own(struct mt792x_dev *dev); +int mt7921e_mac_reset(struct mt792x_dev *dev); +int mt7921e_mcu_init(struct mt792x_dev *dev); +int mt7921s_wfsys_reset(struct mt792x_dev *dev); +int mt7921s_mac_reset(struct mt792x_dev *dev); +int mt7921s_init_reset(struct mt792x_dev *dev); + +int mt7921s_mcu_init(struct mt792x_dev *dev); +int mt7921s_mcu_drv_pmctrl(struct mt792x_dev *dev); +int mt7921s_mcu_fw_pmctrl(struct mt792x_dev *dev); +void mt7921_mac_add_txs(struct mt792x_dev *dev, void *data); +void mt7921_set_runtime_pm(struct mt792x_dev *dev); void mt7921_mcu_set_suspend_iter(void *priv, u8 *mac, struct ieee80211_vif *vif); void mt7921_set_ipv6_ns_work(struct work_struct *work); -int mt7921_mcu_set_sniffer(struct mt7921_dev *dev, struct ieee80211_vif *vif, +int mt7921_mcu_set_sniffer(struct mt792x_dev *dev, struct ieee80211_vif *vif, bool enable); -int mt7921_mcu_config_sniffer(struct mt7921_vif *vif, +int mt7921_mcu_config_sniffer(struct mt792x_vif *vif, struct ieee80211_chanctx_conf *ctx); +int mt7921_mcu_get_temperature(struct mt792x_phy *phy); int mt7921_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, enum mt76_txq_id qid, struct mt76_wcid *wcid, @@ -550,51 +322,18 @@ void mt7921_usb_sdio_tx_complete_skb(struct mt76_dev *mdev, bool mt7921_usb_sdio_tx_status_data(struct mt76_dev *mdev, u8 *update); /* usb */ -#define MT_USB_TYPE_VENDOR (USB_TYPE_VENDOR | 0x1f) -#define MT_USB_TYPE_UHW_VENDOR (USB_TYPE_VENDOR | 0x1e) - -int mt7921u_mcu_power_on(struct mt7921_dev *dev); -int mt7921u_wfsys_reset(struct mt7921_dev *dev); -int mt7921u_dma_init(struct mt7921_dev *dev, bool resume); -int mt7921u_init_reset(struct mt7921_dev *dev); -int mt7921u_mac_reset(struct mt7921_dev *dev); -int mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev, +int mt7921_mcu_uni_add_beacon_offload(struct mt792x_dev *dev, struct ieee80211_hw *hw, struct ieee80211_vif *vif, bool enable); -#ifdef CONFIG_ACPI -int mt7921_init_acpi_sar(struct mt7921_dev *dev); -int mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default); -u8 mt7921_acpi_get_flags(struct mt7921_phy *phy); -#else -static inline int -mt7921_init_acpi_sar(struct mt7921_dev *dev) -{ - return 0; -} - -static inline int -mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default) -{ - return 0; -} - -static inline u8 -mt7921_acpi_get_flags(struct mt7921_phy *phy) -{ - return 0; -} -#endif int mt7921_set_tx_sar_pwr(struct ieee80211_hw *hw, const struct cfg80211_sar_specs *sar); -int mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2, +int mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2, enum environment_cap env_cap); -int mt7921_mcu_set_roc(struct mt7921_phy *phy, struct mt7921_vif *vif, +int mt7921_mcu_set_roc(struct mt792x_phy *phy, struct mt792x_vif *vif, struct ieee80211_channel *chan, int duration, enum mt7921_roc_req type, u8 token_id); -int mt7921_mcu_abort_roc(struct mt7921_phy *phy, struct mt7921_vif *vif, +int mt7921_mcu_abort_roc(struct mt792x_phy *phy, struct mt792x_vif *vif, u8 token_id); -struct ieee80211_ops *mt7921_get_mac80211_ops(struct device *dev, - void *drv_data, u8 *fw_features); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c index 95610a117d2f..3dda84a93717 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c @@ -9,8 +9,8 @@ #include "mt7921.h" #include "../mt76_connac2_mac.h" +#include "../dma.h" #include "mcu.h" -#include "../trace.h" static const struct pci_device_id mt7921_pci_device_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7961), @@ -28,81 +28,12 @@ static bool mt7921_disable_aspm; module_param_named(disable_aspm, mt7921_disable_aspm, bool, 0644); MODULE_PARM_DESC(disable_aspm, "disable PCI ASPM support"); -static void -mt7921_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q) +static int mt7921e_init_reset(struct mt792x_dev *dev) { - if (q == MT_RXQ_MAIN) - mt76_connac_irq_enable(mdev, MT_INT_RX_DONE_DATA); - else if (q == MT_RXQ_MCU_WA) - mt76_connac_irq_enable(mdev, MT_INT_RX_DONE_WM2); - else - mt76_connac_irq_enable(mdev, MT_INT_RX_DONE_WM); + return mt792x_wpdma_reset(dev, true); } -static irqreturn_t mt7921_irq_handler(int irq, void *dev_instance) -{ - struct mt7921_dev *dev = dev_instance; - - mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0); - - if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state)) - return IRQ_NONE; - - tasklet_schedule(&dev->mt76.irq_tasklet); - - return IRQ_HANDLED; -} - -static void mt7921_irq_tasklet(unsigned long data) -{ - struct mt7921_dev *dev = (struct mt7921_dev *)data; - u32 intr, mask = 0; - - mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0); - - intr = mt76_rr(dev, MT_WFDMA0_HOST_INT_STA); - intr &= dev->mt76.mmio.irqmask; - mt76_wr(dev, MT_WFDMA0_HOST_INT_STA, intr); - - trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask); - - mask |= intr & MT_INT_RX_DONE_ALL; - if (intr & MT_INT_TX_DONE_MCU) - mask |= MT_INT_TX_DONE_MCU; - - if (intr & MT_INT_MCU_CMD) { - u32 intr_sw; - - intr_sw = mt76_rr(dev, MT_MCU_CMD); - /* ack MCU2HOST_SW_INT_STA */ - mt76_wr(dev, MT_MCU_CMD, intr_sw); - if (intr_sw & MT_MCU_CMD_WAKE_RX_PCIE) { - mask |= MT_INT_RX_DONE_DATA; - intr |= MT_INT_RX_DONE_DATA; - } - } - - mt76_set_irq_mask(&dev->mt76, MT_WFDMA0_HOST_INT_ENA, mask, 0); - - if (intr & MT_INT_TX_DONE_ALL) - napi_schedule(&dev->mt76.tx_napi); - - if (intr & MT_INT_RX_DONE_WM) - napi_schedule(&dev->mt76.napi[MT_RXQ_MCU]); - - if (intr & MT_INT_RX_DONE_WM2) - napi_schedule(&dev->mt76.napi[MT_RXQ_MCU_WA]); - - if (intr & MT_INT_RX_DONE_DATA) - napi_schedule(&dev->mt76.napi[MT_RXQ_MAIN]); -} - -static int mt7921e_init_reset(struct mt7921_dev *dev) -{ - return mt7921_wpdma_reset(dev, true); -} - -static void mt7921e_unregister_device(struct mt7921_dev *dev) +static void mt7921e_unregister_device(struct mt792x_dev *dev) { int i; struct mt76_connac_pm *pm = &dev->pm; @@ -115,16 +46,16 @@ static void mt7921e_unregister_device(struct mt7921_dev *dev) cancel_work_sync(&pm->wake_work); cancel_work_sync(&dev->reset_work); - mt7921_tx_token_put(dev); - __mt7921_mcu_drv_pmctrl(dev); - mt7921_dma_cleanup(dev); - mt7921_wfsys_reset(dev); + mt76_connac2_tx_token_put(&dev->mt76); + __mt792x_mcu_drv_pmctrl(dev); + mt792x_dma_cleanup(dev); + mt792x_wfsys_reset(dev); skb_queue_purge(&dev->mt76.mcu.res_q); tasklet_disable(&dev->mt76.irq_tasklet); } -static u32 __mt7921_reg_addr(struct mt7921_dev *dev, u32 addr) +static u32 __mt7921_reg_addr(struct mt792x_dev *dev, u32 addr) { static const struct mt76_connac_reg_map fixed_map[] = { { 0x820d0000, 0x30000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */ @@ -203,7 +134,7 @@ static u32 __mt7921_reg_addr(struct mt7921_dev *dev, u32 addr) static u32 mt7921_rr(struct mt76_dev *mdev, u32 offset) { - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); u32 addr = __mt7921_reg_addr(dev, offset); return dev->bus_ops->rr(mdev, addr); @@ -211,7 +142,7 @@ static u32 mt7921_rr(struct mt76_dev *mdev, u32 offset) static void mt7921_wr(struct mt76_dev *mdev, u32 offset, u32 val) { - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); u32 addr = __mt7921_reg_addr(dev, offset); dev->bus_ops->wr(mdev, addr, val); @@ -219,12 +150,77 @@ static void mt7921_wr(struct mt76_dev *mdev, u32 offset, u32 val) static u32 mt7921_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val) { - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); u32 addr = __mt7921_reg_addr(dev, offset); return dev->bus_ops->rmw(mdev, addr, mask, val); } +static int mt7921_dma_init(struct mt792x_dev *dev) +{ + int ret; + + mt76_dma_attach(&dev->mt76); + + ret = mt792x_dma_disable(dev, true); + if (ret) + return ret; + + /* init tx queue */ + ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7921_TXQ_BAND0, + MT7921_TX_RING_SIZE, + MT_TX_RING_BASE, 0); + if (ret) + return ret; + + mt76_wr(dev, MT_WFDMA0_TX_RING0_EXT_CTRL, 0x4); + + /* command to WM */ + ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT7921_TXQ_MCU_WM, + MT7921_TX_MCU_RING_SIZE, MT_TX_RING_BASE); + if (ret) + return ret; + + /* firmware download */ + ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL, MT7921_TXQ_FWDL, + MT7921_TX_FWDL_RING_SIZE, MT_TX_RING_BASE); + if (ret) + return ret; + + /* event from WM before firmware download */ + ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU], + MT7921_RXQ_MCU_WM, + MT7921_RX_MCU_RING_SIZE, + MT_RX_BUF_SIZE, MT_RX_EVENT_RING_BASE); + if (ret) + return ret; + + /* Change mcu queue after firmware download */ + ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA], + MT7921_RXQ_MCU_WM, + MT7921_RX_MCU_RING_SIZE, + MT_RX_BUF_SIZE, MT_WFDMA0(0x540)); + if (ret) + return ret; + + /* rx data */ + ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], + MT7921_RXQ_BAND0, MT7921_RX_RING_SIZE, + MT_RX_BUF_SIZE, MT_RX_DATA_RING_BASE); + if (ret) + return ret; + + ret = mt76_init_queues(dev, mt792x_poll_rx); + if (ret < 0) + return ret; + + netif_napi_add_tx(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, + mt792x_poll_tx); + napi_enable(&dev->mt76.tx_napi); + + return mt792x_dma_enable(dev); +} + static int mt7921_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -241,22 +237,34 @@ static int mt7921_pci_probe(struct pci_dev *pdev, .tx_complete_skb = mt76_connac_tx_complete_skb, .rx_check = mt7921_rx_check, .rx_skb = mt7921_queue_rx_skb, - .rx_poll_complete = mt7921_rx_poll_complete, + .rx_poll_complete = mt792x_rx_poll_complete, .sta_add = mt7921_mac_sta_add, .sta_assoc = mt7921_mac_sta_assoc, .sta_remove = mt7921_mac_sta_remove, - .update_survey = mt7921_update_channel, + .update_survey = mt792x_update_channel, }; - static const struct mt7921_hif_ops mt7921_pcie_ops = { + static const struct mt792x_hif_ops mt7921_pcie_ops = { .init_reset = mt7921e_init_reset, .reset = mt7921e_mac_reset, .mcu_init = mt7921e_mcu_init, - .drv_own = mt7921e_mcu_drv_pmctrl, - .fw_own = mt7921e_mcu_fw_pmctrl, + .drv_own = mt792xe_mcu_drv_pmctrl, + .fw_own = mt792xe_mcu_fw_pmctrl, + }; + static const struct mt792x_irq_map irq_map = { + .host_irq_enable = MT_WFDMA0_HOST_INT_ENA, + .tx = { + .all_complete_mask = MT_INT_TX_DONE_ALL, + .mcu_complete_mask = MT_INT_TX_DONE_MCU, + }, + .rx = { + .data_complete_mask = MT_INT_RX_DONE_DATA, + .wm_complete_mask = MT_INT_RX_DONE_WM, + .wm2_complete_mask = MT_INT_RX_DONE_WM2, + }, }; struct ieee80211_ops *ops; struct mt76_bus_ops *bus_ops; - struct mt7921_dev *dev; + struct mt792x_dev *dev; struct mt76_dev *mdev; u8 features; int ret; @@ -288,8 +296,8 @@ static int mt7921_pci_probe(struct pci_dev *pdev, if (mt7921_disable_aspm) mt76_pci_disable_aspm(pdev); - ops = mt7921_get_mac80211_ops(&pdev->dev, (void *)id->driver_data, - &features); + ops = mt792x_get_mac80211_ops(&pdev->dev, &mt7921_ops, + (void *)id->driver_data, &features); if (!ops) { ret = -ENOMEM; goto err_free_pci_vec; @@ -303,11 +311,12 @@ static int mt7921_pci_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, mdev); - dev = container_of(mdev, struct mt7921_dev, mt76); + dev = container_of(mdev, struct mt792x_dev, mt76); dev->fw_features = features; dev->hif_ops = &mt7921_pcie_ops; + dev->irq_map = &irq_map; mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]); - tasklet_init(&mdev->irq_tasklet, mt7921_irq_tasklet, (unsigned long)dev); + tasklet_init(&mdev->irq_tasklet, mt792x_irq_tasklet, (unsigned long)dev); dev->phy.dev = dev; dev->phy.mt76 = &dev->mt76.phy; @@ -325,11 +334,11 @@ static int mt7921_pci_probe(struct pci_dev *pdev, bus_ops->rmw = mt7921_rmw; dev->mt76.bus = bus_ops; - ret = mt7921e_mcu_fw_pmctrl(dev); + ret = mt792xe_mcu_fw_pmctrl(dev); if (ret) goto err_free_dev; - ret = __mt7921e_mcu_drv_pmctrl(dev); + ret = __mt792xe_mcu_drv_pmctrl(dev); if (ret) goto err_free_dev; @@ -337,15 +346,15 @@ static int mt7921_pci_probe(struct pci_dev *pdev, (mt7921_l1_rr(dev, MT_HW_REV) & 0xff); dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev); - ret = mt7921_wfsys_reset(dev); + ret = mt792x_wfsys_reset(dev); if (ret) goto err_free_dev; - mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0); + mt76_wr(dev, irq_map.host_irq_enable, 0); mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); - ret = devm_request_irq(mdev->dev, pdev->irq, mt7921_irq_handler, + ret = devm_request_irq(mdev->dev, pdev->irq, mt792x_irq_handler, IRQF_SHARED, KBUILD_MODNAME, dev); if (ret) goto err_free_dev; @@ -373,7 +382,7 @@ err_free_pci_vec: static void mt7921_pci_remove(struct pci_dev *pdev) { struct mt76_dev *mdev = pci_get_drvdata(pdev); - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); mt7921e_unregister_device(dev); devm_free_irq(&pdev->dev, pdev->irq, dev); @@ -385,7 +394,7 @@ static int mt7921_pci_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct mt76_dev *mdev = pci_get_drvdata(pdev); - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); struct mt76_connac_pm *pm = &dev->pm; int i, err; @@ -394,7 +403,7 @@ static int mt7921_pci_suspend(struct device *device) cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); - err = mt7921_mcu_drv_pmctrl(dev); + err = mt792x_mcu_drv_pmctrl(dev); if (err < 0) goto restore_suspend; @@ -424,12 +433,12 @@ static int mt7921_pci_suspend(struct device *device) MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN); /* disable interrupt */ - mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0); + mt76_wr(dev, dev->irq_map->host_irq_enable, 0); mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0); synchronize_irq(pdev->irq); tasklet_kill(&mdev->irq_tasklet); - err = mt7921_mcu_fw_pmctrl(dev); + err = mt792x_mcu_fw_pmctrl(dev); if (err) goto restore_napi; @@ -450,7 +459,7 @@ restore_suspend: pm->suspended = false; if (err < 0) - mt7921_reset(&dev->mt76); + mt792x_reset(&dev->mt76); return err; } @@ -459,21 +468,21 @@ static int mt7921_pci_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct mt76_dev *mdev = pci_get_drvdata(pdev); - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); struct mt76_connac_pm *pm = &dev->pm; int i, err; - err = mt7921_mcu_drv_pmctrl(dev); + err = mt792x_mcu_drv_pmctrl(dev); if (err < 0) goto failed; - mt7921_wpdma_reinit_cond(dev); + mt792x_wpdma_reinit_cond(dev); /* enable interrupt */ mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); mt76_connac_irq_enable(&dev->mt76, - MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL | - MT_INT_MCU_CMD); + dev->irq_map->tx.all_complete_mask | + MT_INT_RX_DONE_ALL | MT_INT_MCU_CMD); mt76_set(dev, MT_MCU2HOST_SW_INT_ENA, MT_MCU_CMD_WAKE_RX_PCIE); /* put dma enabled */ @@ -500,7 +509,7 @@ failed: pm->suspended = false; if (err < 0) - mt7921_reset(&dev->mt76); + mt792x_reset(&dev->mt76); return err; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c index 6053a2556c20..e7a995e7e70a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c @@ -10,7 +10,7 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, struct ieee80211_sta *sta, struct mt76_tx_info *tx_info) { - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb); struct ieee80211_key_conf *key = info->control.hw_key; struct mt76_connac_hw_txp *txp; @@ -32,7 +32,7 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, return id; if (sta) { - struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv; + struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv; if (time_after(jiffies, msta->last_txs + HZ / 4)) { info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; @@ -53,29 +53,15 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, return 0; } -void mt7921_tx_token_put(struct mt7921_dev *dev) -{ - struct mt76_txwi_cache *txwi; - int id; - - spin_lock_bh(&dev->mt76.token_lock); - idr_for_each_entry(&dev->mt76.token, txwi, id) { - mt7921_txwi_free(dev, txwi, NULL, false, NULL); - dev->mt76.token_count--; - } - spin_unlock_bh(&dev->mt76.token_lock); - idr_destroy(&dev->mt76.token); -} - -int mt7921e_mac_reset(struct mt7921_dev *dev) +int mt7921e_mac_reset(struct mt792x_dev *dev) { int i, err; - mt7921e_mcu_drv_pmctrl(dev); + mt792xe_mcu_drv_pmctrl(dev); mt76_connac_free_pending_tx_skbs(&dev->pm, NULL); - mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0); + mt76_wr(dev, dev->irq_map->host_irq_enable, 0); mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0); set_bit(MT76_RESET, &dev->mphy.state); @@ -91,10 +77,10 @@ int mt7921e_mac_reset(struct mt7921_dev *dev) napi_disable(&dev->mt76.napi[MT_RXQ_MCU_WA]); napi_disable(&dev->mt76.tx_napi); - mt7921_tx_token_put(dev); + mt76_connac2_tx_token_put(&dev->mt76); idr_init(&dev->mt76.token); - mt7921_wpdma_reset(dev, true); + mt792x_wpdma_reset(dev, true); local_bh_disable(); mt76_for_each_q_rx(&dev->mt76, i) { @@ -106,9 +92,9 @@ int mt7921e_mac_reset(struct mt7921_dev *dev) dev->fw_assert = false; clear_bit(MT76_MCU_RESET, &dev->mphy.state); - mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, - MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL | - MT_INT_MCU_CMD); + mt76_wr(dev, dev->irq_map->host_irq_enable, + dev->irq_map->tx.all_complete_mask | + MT_INT_RX_DONE_ALL | MT_INT_MCU_CMD); mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); err = mt7921e_driver_own(dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c index 1aefbb6cf0ab..4cf1f2f0f968 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c @@ -4,7 +4,7 @@ #include "mt7921.h" #include "mcu.h" -int mt7921e_driver_own(struct mt7921_dev *dev) +int mt7921e_driver_own(struct mt792x_dev *dev) { u32 reg = mt7921_reg_map_l1(dev, MT_TOP_LPCR_HOST_BAND0); @@ -22,7 +22,7 @@ static int mt7921_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, int cmd, int *seq) { - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); enum mt76_mcuq_id txq = MT_MCUQ_WM; int ret; @@ -38,7 +38,7 @@ mt7921_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[txq], skb, 0); } -int mt7921e_mcu_init(struct mt7921_dev *dev) +int mt7921e_mcu_init(struct mt792x_dev *dev) { static const struct mt76_mcu_ops mt7921_mcu_ops = { .headroom = sizeof(struct mt76_connac2_mcu_txd), @@ -61,68 +61,3 @@ int mt7921e_mcu_init(struct mt7921_dev *dev) return err; } - -int __mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev) -{ - int i, err = 0; - - for (i = 0; i < MT7921_DRV_OWN_RETRY_COUNT; i++) { - mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_CLR_OWN); - if (mt76_poll_msec_tick(dev, MT_CONN_ON_LPCTL, - PCIE_LPCR_HOST_OWN_SYNC, 0, 50, 1)) - break; - } - - if (i == MT7921_DRV_OWN_RETRY_COUNT) { - dev_err(dev->mt76.dev, "driver own failed\n"); - err = -EIO; - } - - return err; -} - -int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev) -{ - struct mt76_phy *mphy = &dev->mt76.phy; - struct mt76_connac_pm *pm = &dev->pm; - int err; - - err = __mt7921e_mcu_drv_pmctrl(dev); - if (err < 0) - goto out; - - mt7921_wpdma_reinit_cond(dev); - clear_bit(MT76_STATE_PM, &mphy->state); - - pm->stats.last_wake_event = jiffies; - pm->stats.doze_time += pm->stats.last_wake_event - - pm->stats.last_doze_event; -out: - return err; -} - -int mt7921e_mcu_fw_pmctrl(struct mt7921_dev *dev) -{ - struct mt76_phy *mphy = &dev->mt76.phy; - struct mt76_connac_pm *pm = &dev->pm; - int i; - - for (i = 0; i < MT7921_DRV_OWN_RETRY_COUNT; i++) { - mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_SET_OWN); - if (mt76_poll_msec_tick(dev, MT_CONN_ON_LPCTL, - PCIE_LPCR_HOST_OWN_SYNC, 4, 50, 1)) - break; - } - - if (i == MT7921_DRV_OWN_RETRY_COUNT) { - dev_err(dev->mt76.dev, "firmware own failed\n"); - clear_bit(MT76_STATE_PM, &mphy->state); - return -EIO; - } - - pm->stats.last_doze_event = jiffies; - pm->stats.awake_time += pm->stats.last_doze_event - - pm->stats.last_wake_event; - - return 0; -} diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/regs.h b/drivers/net/wireless/mediatek/mt76/mt7921/regs.h index e52977ff3349..43427a3a48af 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/regs.h @@ -4,26 +4,7 @@ #ifndef __MT7921_REGS_H #define __MT7921_REGS_H -/* MCU WFDMA1 */ -#define MT_MCU_WFDMA1_BASE 0x3000 -#define MT_MCU_WFDMA1(ofs) (MT_MCU_WFDMA1_BASE + (ofs)) - -#define MT_MCU_INT_EVENT MT_MCU_WFDMA1(0x108) -#define MT_MCU_INT_EVENT_DMA_STOPPED BIT(0) -#define MT_MCU_INT_EVENT_DMA_INIT BIT(1) -#define MT_MCU_INT_EVENT_SER_TRIGGER BIT(2) -#define MT_MCU_INT_EVENT_RESET_DONE BIT(3) - -#define MT_PLE_BASE 0x820c0000 -#define MT_PLE(ofs) (MT_PLE_BASE + (ofs)) - -#define MT_PLE_FL_Q0_CTRL MT_PLE(0x3e0) -#define MT_PLE_FL_Q1_CTRL MT_PLE(0x3e4) -#define MT_PLE_FL_Q2_CTRL MT_PLE(0x3e8) -#define MT_PLE_FL_Q3_CTRL MT_PLE(0x3ec) - -#define MT_PLE_AC_QEMPTY(_n) MT_PLE(0x500 + 0x40 * (_n)) -#define MT_PLE_AMSDU_PACK_MSDU_CNT(n) MT_PLE(0x10e0 + ((n) << 2)) +#include "../mt792x_regs.h" #define MT_MDP_BASE 0x820cd000 #define MT_MDP(ofs) (MT_MDP_BASE + (ofs)) @@ -47,280 +28,7 @@ #define MT_MDP_TO_HIF 0 #define MT_MDP_TO_WM 1 -/* TMAC: band 0(0x21000), band 1(0xa1000) */ -#define MT_WF_TMAC_BASE(_band) ((_band) ? 0x820f4000 : 0x820e4000) -#define MT_WF_TMAC(_band, ofs) (MT_WF_TMAC_BASE(_band) + (ofs)) - -#define MT_TMAC_TCR0(_band) MT_WF_TMAC(_band, 0) -#define MT_TMAC_TCR0_TBTT_STOP_CTRL BIT(25) - -#define MT_TMAC_CDTR(_band) MT_WF_TMAC(_band, 0x090) -#define MT_TMAC_ODTR(_band) MT_WF_TMAC(_band, 0x094) -#define MT_TIMEOUT_VAL_PLCP GENMASK(15, 0) -#define MT_TIMEOUT_VAL_CCA GENMASK(31, 16) - -#define MT_TMAC_ICR0(_band) MT_WF_TMAC(_band, 0x0a4) -#define MT_IFS_EIFS GENMASK(8, 0) -#define MT_IFS_RIFS GENMASK(14, 10) -#define MT_IFS_SIFS GENMASK(22, 16) -#define MT_IFS_SLOT GENMASK(30, 24) - -#define MT_TMAC_CTCR0(_band) MT_WF_TMAC(_band, 0x0f4) -#define MT_TMAC_CTCR0_INS_DDLMT_REFTIME GENMASK(5, 0) -#define MT_TMAC_CTCR0_INS_DDLMT_EN BIT(17) -#define MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN BIT(18) - -#define MT_TMAC_TRCR0(_band) MT_WF_TMAC(_band, 0x09c) -#define MT_TMAC_TFCR0(_band) MT_WF_TMAC(_band, 0x1e0) - -#define MT_WF_DMA_BASE(_band) ((_band) ? 0x820f7000 : 0x820e7000) -#define MT_WF_DMA(_band, ofs) (MT_WF_DMA_BASE(_band) + (ofs)) - -#define MT_DMA_DCR0(_band) MT_WF_DMA(_band, 0x000) -#define MT_DMA_DCR0_MAX_RX_LEN GENMASK(15, 3) -#define MT_DMA_DCR0_RXD_G5_EN BIT(23) - -/* WTBLOFF TOP: band 0(0x820e9000),band 1(0x820f9000) */ -#define MT_WTBLOFF_TOP_BASE(_band) ((_band) ? 0x820f9000 : 0x820e9000) -#define MT_WTBLOFF_TOP(_band, ofs) (MT_WTBLOFF_TOP_BASE(_band) + (ofs)) - -#define MT_WTBLOFF_TOP_RSCR(_band) MT_WTBLOFF_TOP(_band, 0x008) -#define MT_WTBLOFF_TOP_RSCR_RCPI_MODE GENMASK(31, 30) -#define MT_WTBLOFF_TOP_RSCR_RCPI_PARAM GENMASK(25, 24) - -/* LPON: band 0(0x24200), band 1(0xa4200) */ -#define MT_WF_LPON_BASE(_band) ((_band) ? 0x820fb000 : 0x820eb000) -#define MT_WF_LPON(_band, ofs) (MT_WF_LPON_BASE(_band) + (ofs)) - -#define MT_LPON_UTTR0(_band) MT_WF_LPON(_band, 0x080) -#define MT_LPON_UTTR1(_band) MT_WF_LPON(_band, 0x084) - -#define MT_LPON_TCR(_band, n) MT_WF_LPON(_band, 0x0a8 + (n) * 4) -#define MT_LPON_TCR_SW_MODE GENMASK(1, 0) -#define MT_LPON_TCR_SW_WRITE BIT(0) - -/* ETBF: band 0(0x24000), band 1(0xa4000) */ -#define MT_WF_ETBF_BASE(_band) ((_band) ? 0x820fa000 : 0x820ea000) -#define MT_WF_ETBF(_band, ofs) (MT_WF_ETBF_BASE(_band) + (ofs)) - -#define MT_ETBF_TX_APP_CNT(_band) MT_WF_ETBF(_band, 0x150) -#define MT_ETBF_TX_IBF_CNT GENMASK(31, 16) -#define MT_ETBF_TX_EBF_CNT GENMASK(15, 0) - -#define MT_ETBF_RX_FB_CNT(_band) MT_WF_ETBF(_band, 0x158) -#define MT_ETBF_RX_FB_ALL GENMASK(31, 24) -#define MT_ETBF_RX_FB_HE GENMASK(23, 16) -#define MT_ETBF_RX_FB_VHT GENMASK(15, 8) -#define MT_ETBF_RX_FB_HT GENMASK(7, 0) - -/* MIB: band 0(0x24800), band 1(0xa4800) */ -#define MT_WF_MIB_BASE(_band) ((_band) ? 0x820fd000 : 0x820ed000) -#define MT_WF_MIB(_band, ofs) (MT_WF_MIB_BASE(_band) + (ofs)) - -#define MT_MIB_SCR1(_band) MT_WF_MIB(_band, 0x004) -#define MT_MIB_TXDUR_EN BIT(8) -#define MT_MIB_RXDUR_EN BIT(9) - -#define MT_MIB_SDR3(_band) MT_WF_MIB(_band, 0x698) -#define MT_MIB_SDR3_FCS_ERR_MASK GENMASK(31, 16) - -#define MT_MIB_SDR5(_band) MT_WF_MIB(_band, 0x780) - -#define MT_MIB_SDR9(_band) MT_WF_MIB(_band, 0x02c) -#define MT_MIB_SDR9_BUSY_MASK GENMASK(23, 0) - -#define MT_MIB_SDR12(_band) MT_WF_MIB(_band, 0x558) -#define MT_MIB_SDR14(_band) MT_WF_MIB(_band, 0x564) -#define MT_MIB_SDR15(_band) MT_WF_MIB(_band, 0x568) - -#define MT_MIB_SDR16(_band) MT_WF_MIB(_band, 0x048) -#define MT_MIB_SDR16_BUSY_MASK GENMASK(23, 0) - -#define MT_MIB_SDR22(_band) MT_WF_MIB(_band, 0x770) -#define MT_MIB_SDR23(_band) MT_WF_MIB(_band, 0x774) -#define MT_MIB_SDR31(_band) MT_WF_MIB(_band, 0x55c) - -#define MT_MIB_SDR32(_band) MT_WF_MIB(_band, 0x7a8) -#define MT_MIB_SDR9_IBF_CNT_MASK GENMASK(31, 16) -#define MT_MIB_SDR9_EBF_CNT_MASK GENMASK(15, 0) - -#define MT_MIB_SDR34(_band) MT_WF_MIB(_band, 0x090) -#define MT_MIB_MU_BF_TX_CNT GENMASK(15, 0) - -#define MT_MIB_SDR36(_band) MT_WF_MIB(_band, 0x054) -#define MT_MIB_SDR36_TXTIME_MASK GENMASK(23, 0) -#define MT_MIB_SDR37(_band) MT_WF_MIB(_band, 0x058) -#define MT_MIB_SDR37_RXTIME_MASK GENMASK(23, 0) - -#define MT_MIB_DR8(_band) MT_WF_MIB(_band, 0x0c0) -#define MT_MIB_DR9(_band) MT_WF_MIB(_band, 0x0c4) -#define MT_MIB_DR11(_band) MT_WF_MIB(_band, 0x0cc) - -#define MT_MIB_MB_SDR0(_band, n) MT_WF_MIB(_band, 0x100 + ((n) << 4)) -#define MT_MIB_RTS_RETRIES_COUNT_MASK GENMASK(31, 16) -#define MT_MIB_RTS_COUNT_MASK GENMASK(15, 0) - -#define MT_MIB_MB_BSDR0(_band) MT_WF_MIB(_band, 0x688) -#define MT_MIB_RTS_COUNT_MASK GENMASK(15, 0) -#define MT_MIB_MB_BSDR1(_band) MT_WF_MIB(_band, 0x690) -#define MT_MIB_RTS_FAIL_COUNT_MASK GENMASK(15, 0) -#define MT_MIB_MB_BSDR2(_band) MT_WF_MIB(_band, 0x518) -#define MT_MIB_BA_FAIL_COUNT_MASK GENMASK(15, 0) -#define MT_MIB_MB_BSDR3(_band) MT_WF_MIB(_band, 0x520) -#define MT_MIB_ACK_FAIL_COUNT_MASK GENMASK(15, 0) - -#define MT_MIB_MB_SDR2(_band, n) MT_WF_MIB(_band, 0x108 + ((n) << 4)) -#define MT_MIB_FRAME_RETRIES_COUNT_MASK GENMASK(15, 0) - -#define MT_TX_AGG_CNT(_band, n) MT_WF_MIB(_band, 0x7dc + ((n) << 2)) -#define MT_TX_AGG_CNT2(_band, n) MT_WF_MIB(_band, 0x7ec + ((n) << 2)) -#define MT_MIB_ARNG(_band, n) MT_WF_MIB(_band, 0x0b0 + ((n) << 2)) -#define MT_MIB_ARNCR_RANGE(val, n) (((val) >> ((n) << 3)) & GENMASK(7, 0)) - -#define MT_WTBLON_TOP_BASE 0x820d4000 -#define MT_WTBLON_TOP(ofs) (MT_WTBLON_TOP_BASE + (ofs)) -#define MT_WTBLON_TOP_WDUCR MT_WTBLON_TOP(0x200) -#define MT_WTBLON_TOP_WDUCR_GROUP GENMASK(2, 0) - -#define MT_WTBL_UPDATE MT_WTBLON_TOP(0x230) -#define MT_WTBL_UPDATE_WLAN_IDX GENMASK(9, 0) -#define MT_WTBL_UPDATE_ADM_COUNT_CLEAR BIT(12) -#define MT_WTBL_UPDATE_BUSY BIT(31) - -#define MT_WTBL_BASE 0x820d8000 -#define MT_WTBL_LMAC_ID GENMASK(14, 8) -#define MT_WTBL_LMAC_DW GENMASK(7, 2) -#define MT_WTBL_LMAC_OFFS(_id, _dw) (MT_WTBL_BASE | \ - FIELD_PREP(MT_WTBL_LMAC_ID, _id) | \ - FIELD_PREP(MT_WTBL_LMAC_DW, _dw)) - -/* AGG: band 0(0x20800), band 1(0xa0800) */ -#define MT_WF_AGG_BASE(_band) ((_band) ? 0x820f2000 : 0x820e2000) -#define MT_WF_AGG(_band, ofs) (MT_WF_AGG_BASE(_band) + (ofs)) - -#define MT_AGG_AWSCR0(_band, _n) MT_WF_AGG(_band, 0x05c + (_n) * 4) -#define MT_AGG_PCR0(_band, _n) MT_WF_AGG(_band, 0x06c + (_n) * 4) -#define MT_AGG_PCR0_MM_PROT BIT(0) -#define MT_AGG_PCR0_GF_PROT BIT(1) -#define MT_AGG_PCR0_BW20_PROT BIT(2) -#define MT_AGG_PCR0_BW40_PROT BIT(4) -#define MT_AGG_PCR0_BW80_PROT BIT(6) -#define MT_AGG_PCR0_ERP_PROT GENMASK(12, 8) -#define MT_AGG_PCR0_VHT_PROT BIT(13) -#define MT_AGG_PCR0_PTA_WIN_DIS BIT(15) - -#define MT_AGG_PCR1_RTS0_NUM_THRES GENMASK(31, 23) -#define MT_AGG_PCR1_RTS0_LEN_THRES GENMASK(19, 0) - -#define MT_AGG_ACR0(_band) MT_WF_AGG(_band, 0x084) -#define MT_AGG_ACR_CFEND_RATE GENMASK(13, 0) -#define MT_AGG_ACR_BAR_RATE GENMASK(29, 16) - -#define MT_AGG_MRCR(_band) MT_WF_AGG(_band, 0x098) -#define MT_AGG_MRCR_BAR_CNT_LIMIT GENMASK(15, 12) -#define MT_AGG_MRCR_LAST_RTS_CTS_RN BIT(6) -#define MT_AGG_MRCR_RTS_FAIL_LIMIT GENMASK(11, 7) -#define MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT GENMASK(28, 24) - -#define MT_AGG_ATCR1(_band) MT_WF_AGG(_band, 0x0f0) -#define MT_AGG_ATCR3(_band) MT_WF_AGG(_band, 0x0f4) - -/* ARB: band 0(0x20c00), band 1(0xa0c00) */ -#define MT_WF_ARB_BASE(_band) ((_band) ? 0x820f3000 : 0x820e3000) -#define MT_WF_ARB(_band, ofs) (MT_WF_ARB_BASE(_band) + (ofs)) - -#define MT_ARB_SCR(_band) MT_WF_ARB(_band, 0x080) -#define MT_ARB_SCR_TX_DISABLE BIT(8) -#define MT_ARB_SCR_RX_DISABLE BIT(9) - -#define MT_ARB_DRNGR0(_band, _n) MT_WF_ARB(_band, 0x194 + (_n) * 4) - -/* RMAC: band 0(0x21400), band 1(0xa1400) */ -#define MT_WF_RMAC_BASE(_band) ((_band) ? 0x820f5000 : 0x820e5000) -#define MT_WF_RMAC(_band, ofs) (MT_WF_RMAC_BASE(_band) + (ofs)) - -#define MT_WF_RFCR(_band) MT_WF_RMAC(_band, 0x000) -#define MT_WF_RFCR_DROP_STBC_MULTI BIT(0) -#define MT_WF_RFCR_DROP_FCSFAIL BIT(1) -#define MT_WF_RFCR_DROP_VERSION BIT(3) -#define MT_WF_RFCR_DROP_PROBEREQ BIT(4) -#define MT_WF_RFCR_DROP_MCAST BIT(5) -#define MT_WF_RFCR_DROP_BCAST BIT(6) -#define MT_WF_RFCR_DROP_MCAST_FILTERED BIT(7) -#define MT_WF_RFCR_DROP_A3_MAC BIT(8) -#define MT_WF_RFCR_DROP_A3_BSSID BIT(9) -#define MT_WF_RFCR_DROP_A2_BSSID BIT(10) -#define MT_WF_RFCR_DROP_OTHER_BEACON BIT(11) -#define MT_WF_RFCR_DROP_FRAME_REPORT BIT(12) -#define MT_WF_RFCR_DROP_CTL_RSV BIT(13) -#define MT_WF_RFCR_DROP_CTS BIT(14) -#define MT_WF_RFCR_DROP_RTS BIT(15) -#define MT_WF_RFCR_DROP_DUPLICATE BIT(16) -#define MT_WF_RFCR_DROP_OTHER_BSS BIT(17) -#define MT_WF_RFCR_DROP_OTHER_UC BIT(18) -#define MT_WF_RFCR_DROP_OTHER_TIM BIT(19) -#define MT_WF_RFCR_DROP_NDPA BIT(20) -#define MT_WF_RFCR_DROP_UNWANTED_CTL BIT(21) - -#define MT_WF_RFCR1(_band) MT_WF_RMAC(_band, 0x004) -#define MT_WF_RFCR1_DROP_ACK BIT(4) -#define MT_WF_RFCR1_DROP_BF_POLL BIT(5) -#define MT_WF_RFCR1_DROP_BA BIT(6) -#define MT_WF_RFCR1_DROP_CFEND BIT(7) -#define MT_WF_RFCR1_DROP_CFACK BIT(8) - -#define MT_WF_RMAC_MIB_TIME0(_band) MT_WF_RMAC(_band, 0x03c4) -#define MT_WF_RMAC_MIB_RXTIME_CLR BIT(31) -#define MT_WF_RMAC_MIB_RXTIME_EN BIT(30) - -#define MT_WF_RMAC_MIB_AIRTIME14(_band) MT_WF_RMAC(_band, 0x03b8) -#define MT_MIB_OBSSTIME_MASK GENMASK(23, 0) -#define MT_WF_RMAC_MIB_AIRTIME0(_band) MT_WF_RMAC(_band, 0x0380) - -/* WFDMA0 */ -#define MT_WFDMA0_BASE 0xd4000 -#define MT_WFDMA0(ofs) (MT_WFDMA0_BASE + (ofs)) - -#define MT_WFDMA0_RST MT_WFDMA0(0x100) -#define MT_WFDMA0_RST_LOGIC_RST BIT(4) -#define MT_WFDMA0_RST_DMASHDL_ALL_RST BIT(5) - -#define MT_WFDMA0_BUSY_ENA MT_WFDMA0(0x13c) -#define MT_WFDMA0_BUSY_ENA_TX_FIFO0 BIT(0) -#define MT_WFDMA0_BUSY_ENA_TX_FIFO1 BIT(1) -#define MT_WFDMA0_BUSY_ENA_RX_FIFO BIT(2) - -#define MT_MCU_CMD MT_WFDMA0(0x1f0) -#define MT_MCU_CMD_WAKE_RX_PCIE BIT(0) -#define MT_MCU_CMD_STOP_DMA_FW_RELOAD BIT(1) -#define MT_MCU_CMD_STOP_DMA BIT(2) -#define MT_MCU_CMD_RESET_DONE BIT(3) -#define MT_MCU_CMD_RECOVERY_DONE BIT(4) -#define MT_MCU_CMD_NORMAL_STATE BIT(5) -#define MT_MCU_CMD_ERROR_MASK GENMASK(5, 1) - -#define MT_MCU2HOST_SW_INT_ENA MT_WFDMA0(0x1f4) - -#define MT_WFDMA0_HOST_INT_STA MT_WFDMA0(0x200) -#define HOST_RX_DONE_INT_STS0 BIT(0) /* Rx mcu */ -#define HOST_RX_DONE_INT_STS2 BIT(2) /* Rx data */ -#define HOST_RX_DONE_INT_STS4 BIT(22) /* Rx mcu after fw downloaded */ -#define HOST_TX_DONE_INT_STS16 BIT(26) -#define HOST_TX_DONE_INT_STS17 BIT(27) /* MCU tx done*/ - #define MT_WFDMA0_HOST_INT_ENA MT_WFDMA0(0x204) -#define HOST_RX_DONE_INT_ENA0 BIT(0) -#define HOST_RX_DONE_INT_ENA1 BIT(1) -#define HOST_RX_DONE_INT_ENA2 BIT(2) -#define HOST_RX_DONE_INT_ENA3 BIT(3) -#define HOST_TX_DONE_INT_ENA0 BIT(4) -#define HOST_TX_DONE_INT_ENA1 BIT(5) -#define HOST_TX_DONE_INT_ENA2 BIT(6) -#define HOST_TX_DONE_INT_ENA3 BIT(7) -#define HOST_TX_DONE_INT_ENA4 BIT(8) -#define HOST_TX_DONE_INT_ENA5 BIT(9) -#define HOST_TX_DONE_INT_ENA6 BIT(10) -#define HOST_TX_DONE_INT_ENA7 BIT(11) #define HOST_TX_DONE_INT_ENA8 BIT(12) #define HOST_TX_DONE_INT_ENA9 BIT(13) #define HOST_TX_DONE_INT_ENA10 BIT(14) @@ -328,14 +36,10 @@ #define HOST_TX_DONE_INT_ENA12 BIT(16) #define HOST_TX_DONE_INT_ENA13 BIT(17) #define HOST_TX_DONE_INT_ENA14 BIT(18) -#define HOST_RX_COHERENT_EN BIT(20) -#define HOST_TX_COHERENT_EN BIT(21) #define HOST_RX_DONE_INT_ENA4 BIT(22) #define HOST_RX_DONE_INT_ENA5 BIT(23) #define HOST_TX_DONE_INT_ENA16 BIT(26) #define HOST_TX_DONE_INT_ENA17 BIT(27) -#define MCU2HOST_SW_INT_ENA BIT(29) -#define HOST_TX_DONE_INT_ENA18 BIT(30) /* WFDMA interrupt */ #define MT_INT_RX_DONE_DATA HOST_RX_DONE_INT_ENA2 @@ -347,7 +51,6 @@ #define MT_INT_TX_DONE_MCU_WM HOST_TX_DONE_INT_ENA17 #define MT_INT_TX_DONE_FWDL HOST_TX_DONE_INT_ENA16 #define MT_INT_TX_DONE_BAND0 HOST_TX_DONE_INT_ENA0 -#define MT_INT_MCU_CMD MCU2HOST_SW_INT_ENA #define MT_INT_TX_DONE_MCU (MT_INT_TX_DONE_MCU_WM | \ MT_INT_TX_DONE_FWDL) @@ -355,56 +58,8 @@ MT_INT_TX_DONE_BAND0 | \ GENMASK(18, 4)) -#define MT_WFDMA0_GLO_CFG MT_WFDMA0(0x208) -#define MT_WFDMA0_GLO_CFG_TX_DMA_EN BIT(0) -#define MT_WFDMA0_GLO_CFG_TX_DMA_BUSY BIT(1) -#define MT_WFDMA0_GLO_CFG_RX_DMA_EN BIT(2) -#define MT_WFDMA0_GLO_CFG_RX_DMA_BUSY BIT(3) -#define MT_WFDMA0_GLO_CFG_TX_WB_DDONE BIT(6) -#define MT_WFDMA0_GLO_CFG_FW_DWLD_BYPASS_DMASHDL BIT(9) -#define MT_WFDMA0_GLO_CFG_FIFO_LITTLE_ENDIAN BIT(12) -#define MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN BIT(15) -#define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2 BIT(21) -#define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO BIT(27) -#define MT_WFDMA0_GLO_CFG_OMIT_TX_INFO BIT(28) -#define MT_WFDMA0_GLO_CFG_CLK_GAT_DIS BIT(30) - -#define MT_WFDMA0_RST_DTX_PTR MT_WFDMA0(0x20c) -#define MT_WFDMA0_GLO_CFG_EXT0 MT_WFDMA0(0x2b0) -#define MT_WFDMA0_CSR_TX_DMASHDL_ENABLE BIT(6) -#define MT_WFDMA0_PRI_DLY_INT_CFG0 MT_WFDMA0(0x2f0) - #define MT_RX_DATA_RING_BASE MT_WFDMA0(0x520) -#define MT_WFDMA0_TX_RING0_EXT_CTRL MT_WFDMA0(0x600) -#define MT_WFDMA0_TX_RING1_EXT_CTRL MT_WFDMA0(0x604) -#define MT_WFDMA0_TX_RING2_EXT_CTRL MT_WFDMA0(0x608) -#define MT_WFDMA0_TX_RING3_EXT_CTRL MT_WFDMA0(0x60c) -#define MT_WFDMA0_TX_RING4_EXT_CTRL MT_WFDMA0(0x610) -#define MT_WFDMA0_TX_RING5_EXT_CTRL MT_WFDMA0(0x614) -#define MT_WFDMA0_TX_RING6_EXT_CTRL MT_WFDMA0(0x618) -#define MT_WFDMA0_TX_RING16_EXT_CTRL MT_WFDMA0(0x640) -#define MT_WFDMA0_TX_RING17_EXT_CTRL MT_WFDMA0(0x644) - -#define MT_WPDMA0_MAX_CNT_MASK GENMASK(7, 0) -#define MT_WPDMA0_BASE_PTR_MASK GENMASK(31, 16) - -#define MT_WFDMA0_RX_RING0_EXT_CTRL MT_WFDMA0(0x680) -#define MT_WFDMA0_RX_RING1_EXT_CTRL MT_WFDMA0(0x684) -#define MT_WFDMA0_RX_RING2_EXT_CTRL MT_WFDMA0(0x688) -#define MT_WFDMA0_RX_RING3_EXT_CTRL MT_WFDMA0(0x68c) -#define MT_WFDMA0_RX_RING4_EXT_CTRL MT_WFDMA0(0x690) -#define MT_WFDMA0_RX_RING5_EXT_CTRL MT_WFDMA0(0x694) - -#define MT_TX_RING_BASE MT_WFDMA0(0x300) -#define MT_RX_EVENT_RING_BASE MT_WFDMA0(0x500) - -/* WFDMA CSR */ -#define MT_WFDMA_EXT_CSR_BASE 0xd7000 -#define MT_WFDMA_EXT_CSR(ofs) (MT_WFDMA_EXT_CSR_BASE + (ofs)) -#define MT_WFDMA_EXT_CSR_HIF_MISC MT_WFDMA_EXT_CSR(0x44) -#define MT_WFDMA_EXT_CSR_HIF_MISC_BUSY BIT(0) - #define MT_INFRA_CFG_BASE 0xfe000 #define MT_INFRA(ofs) (MT_INFRA_CFG_BASE + (ofs)) @@ -414,121 +69,13 @@ #define MT_HIF_REMAP_L1_BASE GENMASK(31, 16) #define MT_HIF_REMAP_BASE_L1 0x40000 -#define MT_SWDEF_BASE 0x41f200 -#define MT_SWDEF(ofs) (MT_SWDEF_BASE + (ofs)) -#define MT_SWDEF_MODE MT_SWDEF(0x3c) -#define MT_SWDEF_NORMAL_MODE 0 -#define MT_SWDEF_ICAP_MODE 1 -#define MT_SWDEF_SPECTRUM_MODE 2 - -#define MT_TOP_BASE 0x18060000 -#define MT_TOP(ofs) (MT_TOP_BASE + (ofs)) - -#define MT_TOP_LPCR_HOST_BAND0 MT_TOP(0x10) -#define MT_TOP_LPCR_HOST_FW_OWN BIT(0) -#define MT_TOP_LPCR_HOST_DRV_OWN BIT(1) - -#define MT_TOP_MISC MT_TOP(0xf0) -#define MT_TOP_MISC_FW_STATE GENMASK(2, 0) - -#define MT_MCU_WPDMA0_BASE 0x54000000 -#define MT_MCU_WPDMA0(ofs) (MT_MCU_WPDMA0_BASE + (ofs)) - -#define MT_WFDMA_DUMMY_CR MT_MCU_WPDMA0(0x120) -#define MT_WFDMA_NEED_REINIT BIT(1) - -#define MT_CBTOP_RGU(ofs) (0x70002000 + (ofs)) -#define MT_CBTOP_RGU_WF_SUBSYS_RST MT_CBTOP_RGU(0x600) -#define MT_CBTOP_RGU_WF_SUBSYS_RST_WF_WHOLE_PATH BIT(0) - -#define MT_HW_BOUND 0x70010020 -#define MT_HW_CHIPID 0x70010200 -#define MT_HW_REV 0x70010204 - -#define MT_PCIE_MAC_BASE 0x10000 -#define MT_PCIE_MAC(ofs) (MT_PCIE_MAC_BASE + (ofs)) -#define MT_PCIE_MAC_INT_ENABLE MT_PCIE_MAC(0x188) -#define MT_PCIE_MAC_PM MT_PCIE_MAC(0x194) -#define MT_PCIE_MAC_PM_L0S_DIS BIT(8) - -#define MT_DMA_SHDL(ofs) (0x7c026000 + (ofs)) -#define MT_DMASHDL_SW_CONTROL MT_DMA_SHDL(0x004) -#define MT_DMASHDL_DMASHDL_BYPASS BIT(28) -#define MT_DMASHDL_OPTIONAL MT_DMA_SHDL(0x008) -#define MT_DMASHDL_PAGE MT_DMA_SHDL(0x00c) -#define MT_DMASHDL_GROUP_SEQ_ORDER BIT(16) -#define MT_DMASHDL_REFILL MT_DMA_SHDL(0x010) -#define MT_DMASHDL_REFILL_MASK GENMASK(31, 16) -#define MT_DMASHDL_PKT_MAX_SIZE MT_DMA_SHDL(0x01c) -#define MT_DMASHDL_PKT_MAX_SIZE_PLE GENMASK(11, 0) -#define MT_DMASHDL_PKT_MAX_SIZE_PSE GENMASK(27, 16) - -#define MT_DMASHDL_GROUP_QUOTA(_n) MT_DMA_SHDL(0x020 + ((_n) << 2)) -#define MT_DMASHDL_GROUP_QUOTA_MIN GENMASK(11, 0) -#define MT_DMASHDL_GROUP_QUOTA_MAX GENMASK(27, 16) - -#define MT_DMASHDL_Q_MAP(_n) MT_DMA_SHDL(0x060 + ((_n) << 2)) -#define MT_DMASHDL_Q_MAP_MASK GENMASK(3, 0) -#define MT_DMASHDL_Q_MAP_SHIFT(_n) (4 * ((_n) % 8)) - -#define MT_DMASHDL_SCHED_SET(_n) MT_DMA_SHDL(0x070 + ((_n) << 2)) - -#define MT_WFDMA_HOST_CONFIG 0x7c027030 -#define MT_WFDMA_HOST_CONFIG_USB_RXEVT_EP4_EN BIT(6) - -#define MT_UMAC(ofs) (0x74000000 + (ofs)) -#define MT_UDMA_TX_QSEL MT_UMAC(0x008) -#define MT_FW_DL_EN BIT(3) - -#define MT_UDMA_WLCFG_1 MT_UMAC(0x00c) -#define MT_WL_RX_AGG_PKT_LMT GENMASK(7, 0) -#define MT_WL_TX_TMOUT_LMT GENMASK(27, 8) - -#define MT_UDMA_WLCFG_0 MT_UMAC(0x18) -#define MT_WL_RX_AGG_TO GENMASK(7, 0) -#define MT_WL_RX_AGG_LMT GENMASK(15, 8) -#define MT_WL_TX_TMOUT_FUNC_EN BIT(16) -#define MT_WL_TX_DPH_CHK_EN BIT(17) -#define MT_WL_RX_MPSZ_PAD0 BIT(18) -#define MT_WL_RX_FLUSH BIT(19) -#define MT_TICK_1US_EN BIT(20) -#define MT_WL_RX_AGG_EN BIT(21) -#define MT_WL_RX_EN BIT(22) -#define MT_WL_TX_EN BIT(23) -#define MT_WL_RX_BUSY BIT(30) -#define MT_WL_TX_BUSY BIT(31) - -#define MT_UDMA_CONN_INFRA_STATUS MT_UMAC(0xa20) -#define MT_UDMA_CONN_WFSYS_INIT_DONE BIT(22) -#define MT_UDMA_CONN_INFRA_STATUS_SEL MT_UMAC(0xa24) - -#define MT_SSUSB_EPCTL_CSR(ofs) (0x74011800 + (ofs)) -#define MT_SSUSB_EPCTL_CSR_EP_RST_OPT MT_SSUSB_EPCTL_CSR(0x090) - -#define MT_UWFDMA0(ofs) (0x7c024000 + (ofs)) -#define MT_UWFDMA0_GLO_CFG MT_UWFDMA0(0x208) -#define MT_UWFDMA0_GLO_CFG_EXT0 MT_UWFDMA0(0x2b0) -#define MT_UWFDMA0_TX_RING_EXT_CTRL(_n) MT_UWFDMA0(0x600 + ((_n) << 2)) - -#define MT_CONN_STATUS 0x7c053c10 -#define MT_WIFI_PATCH_DL_STATE BIT(0) - -#define MT_CONN_ON_LPCTL 0x7c060010 -#define PCIE_LPCR_HOST_OWN_SYNC BIT(2) -#define PCIE_LPCR_HOST_CLR_OWN BIT(1) -#define PCIE_LPCR_HOST_SET_OWN BIT(0) - #define MT_WFSYS_SW_RST_B 0x18000140 -#define WFSYS_SW_RST_B BIT(0) -#define WFSYS_SW_INIT_DONE BIT(4) -#define MT_CONN_ON_MISC 0x7c0600f0 -#define MT_TOP_MISC2_FW_PWR_ON BIT(0) -#define MT_TOP_MISC2_FW_N9_RDY GENMASK(1, 0) +#define MT_WTBLON_TOP_WDUCR MT_WTBLON_TOP(0x200) +#define MT_WTBLON_TOP_WDUCR_GROUP GENMASK(2, 0) -#define MT_WF_SW_DEF_CR(ofs) (0x401a00 + (ofs)) -#define MT_WF_SW_DEF_CR_USB_MCU_EVENT MT_WF_SW_DEF_CR(0x028) -#define MT_WF_SW_SER_TRIGGER_SUSPEND BIT(6) -#define MT_WF_SW_SER_DONE_SUSPEND BIT(7) +#define MT_WTBL_UPDATE MT_WTBLON_TOP(0x230) +#define MT_WTBL_UPDATE_WLAN_IDX GENMASK(9, 0) +#define MT_WTBL_UPDATE_ADM_COUNT_CLEAR BIT(12) #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c index a77a309c0d60..dc1beb76df3e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c @@ -27,7 +27,7 @@ static void mt7921s_txrx_worker(struct mt76_worker *w) struct mt76_sdio *sdio = container_of(w, struct mt76_sdio, txrx_worker); struct mt76_dev *mdev = container_of(sdio, struct mt76_dev, sdio); - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) { queue_work(mdev->wq, &dev->pm.wake_work); @@ -38,7 +38,7 @@ static void mt7921s_txrx_worker(struct mt76_worker *w) mt76_connac_pm_unref(&dev->mphy, &dev->pm); } -static void mt7921s_unregister_device(struct mt7921_dev *dev) +static void mt7921s_unregister_device(struct mt792x_dev *dev) { struct mt76_connac_pm *pm = &dev->pm; @@ -102,7 +102,7 @@ static int mt7921s_probe(struct sdio_func *func, .sta_add = mt7921_mac_sta_add, .sta_assoc = mt7921_mac_sta_assoc, .sta_remove = mt7921_mac_sta_remove, - .update_survey = mt7921_update_channel, + .update_survey = mt792x_update_channel, }; static const struct mt76_bus_ops mt7921s_ops = { .rr = mt76s_rr, @@ -114,7 +114,7 @@ static int mt7921s_probe(struct sdio_func *func, .rd_rp = mt76s_rd_rp, .type = MT76_BUS_SDIO, }; - static const struct mt7921_hif_ops mt7921_sdio_ops = { + static const struct mt792x_hif_ops mt7921_sdio_ops = { .init_reset = mt7921s_init_reset, .reset = mt7921s_mac_reset, .mcu_init = mt7921s_mcu_init, @@ -122,13 +122,13 @@ static int mt7921s_probe(struct sdio_func *func, .fw_own = mt7921s_mcu_fw_pmctrl, }; struct ieee80211_ops *ops; - struct mt7921_dev *dev; + struct mt792x_dev *dev; struct mt76_dev *mdev; u8 features; int ret; - ops = mt7921_get_mac80211_ops(&func->dev, (void *)id->driver_data, - &features); + ops = mt792x_get_mac80211_ops(&func->dev, &mt7921_ops, + (void *)id->driver_data, &features); if (!ops) return -ENOMEM; @@ -136,7 +136,7 @@ static int mt7921s_probe(struct sdio_func *func, if (!mdev) return -ENOMEM; - dev = container_of(mdev, struct mt7921_dev, mt76); + dev = container_of(mdev, struct mt792x_dev, mt76); dev->fw_features = features; dev->hif_ops = &mt7921_sdio_ops; sdio_set_drvdata(func, dev); @@ -196,7 +196,7 @@ error: static void mt7921s_remove(struct sdio_func *func) { - struct mt7921_dev *dev = sdio_get_drvdata(func); + struct mt792x_dev *dev = sdio_get_drvdata(func); mt7921s_unregister_device(dev); } @@ -204,7 +204,7 @@ static void mt7921s_remove(struct sdio_func *func) static int mt7921s_suspend(struct device *__dev) { struct sdio_func *func = dev_to_sdio_func(__dev); - struct mt7921_dev *dev = sdio_get_drvdata(func); + struct mt792x_dev *dev = sdio_get_drvdata(func); struct mt76_connac_pm *pm = &dev->pm; struct mt76_dev *mdev = &dev->mt76; int err; @@ -216,7 +216,7 @@ static int mt7921s_suspend(struct device *__dev) cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); - err = mt7921_mcu_drv_pmctrl(dev); + err = mt792x_mcu_drv_pmctrl(dev); if (err < 0) goto restore_suspend; @@ -244,7 +244,7 @@ static int mt7921s_suspend(struct device *__dev) mt76_worker_disable(&mdev->sdio.txrx_worker); mt76_worker_disable(&mdev->sdio.net_worker); - err = mt7921_mcu_fw_pmctrl(dev); + err = mt792x_mcu_fw_pmctrl(dev); if (err) goto restore_txrx_worker; @@ -269,7 +269,7 @@ restore_suspend: pm->suspended = false; if (err < 0) - mt7921_reset(&dev->mt76); + mt792x_reset(&dev->mt76); return err; } @@ -277,14 +277,14 @@ restore_suspend: static int mt7921s_resume(struct device *__dev) { struct sdio_func *func = dev_to_sdio_func(__dev); - struct mt7921_dev *dev = sdio_get_drvdata(func); + struct mt792x_dev *dev = sdio_get_drvdata(func); struct mt76_connac_pm *pm = &dev->pm; struct mt76_dev *mdev = &dev->mt76; int err; clear_bit(MT76_STATE_SUSPEND, &mdev->phy.state); - err = mt7921_mcu_drv_pmctrl(dev); + err = mt792x_mcu_drv_pmctrl(dev); if (err < 0) goto failed; @@ -302,7 +302,7 @@ failed: pm->suspended = false; if (err < 0) - mt7921_reset(&dev->mt76); + mt792x_reset(&dev->mt76); return err; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c index cff9925c41ea..8edd0291c128 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c @@ -30,7 +30,7 @@ static u32 mt7921s_read_whcr(struct mt76_dev *dev) return sdio_readl(dev->sdio.func, MCR_WHCR, NULL); } -int mt7921s_wfsys_reset(struct mt7921_dev *dev) +int mt7921s_wfsys_reset(struct mt792x_dev *dev) { struct mt76_sdio *sdio = &dev->mt76.sdio; u32 val, status; @@ -71,7 +71,7 @@ int mt7921s_wfsys_reset(struct mt7921_dev *dev) return 0; } -int mt7921s_init_reset(struct mt7921_dev *dev) +int mt7921s_init_reset(struct mt792x_dev *dev) { set_bit(MT76_MCU_RESET, &dev->mphy.state); @@ -91,7 +91,7 @@ int mt7921s_init_reset(struct mt7921_dev *dev) return 0; } -int mt7921s_mac_reset(struct mt7921_dev *dev) +int mt7921s_mac_reset(struct mt792x_dev *dev) { int err; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c index 177679ce1c80..310eeca024ad 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c @@ -16,14 +16,14 @@ static int mt7921s_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, int cmd, int *seq) { - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); enum mt7921_sdio_pkt_type type = MT7921_SDIO_CMD; enum mt76_mcuq_id txq = MT_MCUQ_WM; int ret, pad; /* We just return in case firmware assertion to avoid blocking the * common workqueue to run, for example, the coredump work might be - * blocked by mt7921_mac_work that is excuting register access via sdio + * blocked by mt792x_mac_work that is excuting register access via sdio * bus. */ if (dev->fw_assert) @@ -51,14 +51,14 @@ mt7921s_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, return ret; } -static u32 mt7921s_read_rm3r(struct mt7921_dev *dev) +static u32 mt7921s_read_rm3r(struct mt792x_dev *dev) { struct mt76_sdio *sdio = &dev->mt76.sdio; return sdio_readl(sdio->func, MCR_D2HRM3R, NULL); } -static u32 mt7921s_clear_rm3r_drv_own(struct mt7921_dev *dev) +static u32 mt7921s_clear_rm3r_drv_own(struct mt792x_dev *dev) { struct mt76_sdio *sdio = &dev->mt76.sdio; u32 val; @@ -71,7 +71,7 @@ static u32 mt7921s_clear_rm3r_drv_own(struct mt7921_dev *dev) return val; } -int mt7921s_mcu_init(struct mt7921_dev *dev) +int mt7921s_mcu_init(struct mt792x_dev *dev) { static const struct mt76_mcu_ops mt7921s_mcu_ops = { .headroom = MT_SDIO_HDR_SIZE + @@ -97,7 +97,7 @@ int mt7921s_mcu_init(struct mt7921_dev *dev) return 0; } -int mt7921s_mcu_drv_pmctrl(struct mt7921_dev *dev) +int mt7921s_mcu_drv_pmctrl(struct mt792x_dev *dev) { struct sdio_func *func = dev->mt76.sdio.func; struct mt76_phy *mphy = &dev->mt76.phy; @@ -133,7 +133,7 @@ int mt7921s_mcu_drv_pmctrl(struct mt7921_dev *dev) return 0; } -int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev) +int mt7921s_mcu_fw_pmctrl(struct mt792x_dev *dev) { struct sdio_func *func = dev->mt76.sdio.func; struct mt76_phy *mphy = &dev->mt76.phy; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/testmode.c b/drivers/net/wireless/mediatek/mt76/mt7921/testmode.c index 7f408212e716..e838d93477c1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/testmode.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/testmode.c @@ -31,7 +31,7 @@ static const struct nla_policy mt7921_tm_policy[NUM_MT7921_TM_ATTRS] = { }; static int -mt7921_tm_set(struct mt7921_dev *dev, struct mt7921_tm_cmd *req) +mt7921_tm_set(struct mt792x_dev *dev, struct mt7921_tm_cmd *req) { struct mt7921_rftest_cmd cmd = { .action = req->action, @@ -57,7 +57,7 @@ mt7921_tm_set(struct mt7921_dev *dev, struct mt7921_tm_cmd *req) pm->enable = false; cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); - __mt7921_mcu_drv_pmctrl(dev); + __mt792x_mcu_drv_pmctrl(dev); phy->test.state = MT76_TM_STATE_ON; } @@ -82,7 +82,7 @@ out: } static int -mt7921_tm_query(struct mt7921_dev *dev, struct mt7921_tm_cmd *req, +mt7921_tm_query(struct mt792x_dev *dev, struct mt7921_tm_cmd *req, struct mt7921_tm_evt *evt_resp) { struct mt7921_rftest_cmd cmd = { @@ -113,7 +113,7 @@ int mt7921_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct nlattr *tb[NUM_MT76_TM_ATTRS]; struct mt76_phy *mphy = hw->priv; - struct mt7921_phy *phy = mphy->priv; + struct mt792x_phy *phy = mphy->priv; int err; if (!test_bit(MT76_STATE_RUNNING, &mphy->state) || @@ -150,7 +150,7 @@ int mt7921_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, { struct nlattr *tb[NUM_MT76_TM_ATTRS]; struct mt76_phy *mphy = hw->priv; - struct mt7921_phy *phy = mphy->priv; + struct mt792x_phy *phy = mphy->priv; int err; if (!test_bit(MT76_STATE_RUNNING, &mphy->state) || diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/trace.c b/drivers/net/wireless/mediatek/mt76/mt7921/trace.c deleted file mode 100644 index 4dc3c7b89ebd..000000000000 --- a/drivers/net/wireless/mediatek/mt76/mt7921/trace.c +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: ISC -/* - * Copyright (C) 2021 Lorenzo Bianconi <lorenzo@kernel.org> - */ - -#include <linux/module.h> - -#ifndef __CHECKER__ -#define CREATE_TRACE_POINTS -#include "mt7921_trace.h" - -#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c index 1f302c430339..59cd3d98bf90 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c @@ -24,88 +24,11 @@ static const struct usb_device_id mt7921u_device_table[] = { { }, }; -static u32 mt7921u_rr(struct mt76_dev *dev, u32 addr) -{ - u32 ret; - - mutex_lock(&dev->usb.usb_ctrl_mtx); - ret = ___mt76u_rr(dev, MT_VEND_READ_EXT, - USB_DIR_IN | MT_USB_TYPE_VENDOR, addr); - mutex_unlock(&dev->usb.usb_ctrl_mtx); - - return ret; -} - -static void mt7921u_wr(struct mt76_dev *dev, u32 addr, u32 val) -{ - mutex_lock(&dev->usb.usb_ctrl_mtx); - ___mt76u_wr(dev, MT_VEND_WRITE_EXT, - USB_DIR_OUT | MT_USB_TYPE_VENDOR, addr, val); - mutex_unlock(&dev->usb.usb_ctrl_mtx); -} - -static u32 mt7921u_rmw(struct mt76_dev *dev, u32 addr, - u32 mask, u32 val) -{ - mutex_lock(&dev->usb.usb_ctrl_mtx); - val |= ___mt76u_rr(dev, MT_VEND_READ_EXT, - USB_DIR_IN | MT_USB_TYPE_VENDOR, addr) & ~mask; - ___mt76u_wr(dev, MT_VEND_WRITE_EXT, - USB_DIR_OUT | MT_USB_TYPE_VENDOR, addr, val); - mutex_unlock(&dev->usb.usb_ctrl_mtx); - - return val; -} - -static void mt7921u_copy(struct mt76_dev *dev, u32 offset, - const void *data, int len) -{ - struct mt76_usb *usb = &dev->usb; - int ret, i = 0, batch_len; - const u8 *val = data; - - len = round_up(len, 4); - - mutex_lock(&usb->usb_ctrl_mtx); - while (i < len) { - batch_len = min_t(int, usb->data_len, len - i); - memcpy(usb->data, val + i, batch_len); - ret = __mt76u_vendor_request(dev, MT_VEND_WRITE_EXT, - USB_DIR_OUT | MT_USB_TYPE_VENDOR, - (offset + i) >> 16, offset + i, - usb->data, batch_len); - if (ret < 0) - break; - - i += batch_len; - } - mutex_unlock(&usb->usb_ctrl_mtx); -} - -int mt7921u_mcu_power_on(struct mt7921_dev *dev) -{ - int ret; - - ret = mt76u_vendor_request(&dev->mt76, MT_VEND_POWER_ON, - USB_DIR_OUT | MT_USB_TYPE_VENDOR, - 0x0, 0x1, NULL, 0); - if (ret) - return ret; - - if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_PWR_ON, - MT_TOP_MISC2_FW_PWR_ON, 500)) { - dev_err(dev->mt76.dev, "Timeout for power on\n"); - ret = -EIO; - } - - return ret; -} - static int mt7921u_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, int cmd, int *seq) { - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); u32 pad, ep; int ret; @@ -131,7 +54,7 @@ mt7921u_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, return ret; } -static int mt7921u_mcu_init(struct mt7921_dev *dev) +static int mt7921u_mcu_init(struct mt792x_dev *dev) { static const struct mt76_mcu_ops mcu_ops = { .headroom = MT_SDIO_HDR_SIZE + @@ -155,20 +78,69 @@ static int mt7921u_mcu_init(struct mt7921_dev *dev) return 0; } -static void mt7921u_stop(struct ieee80211_hw *hw) +static int mt7921u_mac_reset(struct mt792x_dev *dev) { - struct mt7921_dev *dev = mt7921_hw_dev(hw); + int err; + + mt76_txq_schedule_all(&dev->mphy); + mt76_worker_disable(&dev->mt76.tx_worker); + set_bit(MT76_RESET, &dev->mphy.state); + set_bit(MT76_MCU_RESET, &dev->mphy.state); + + wake_up(&dev->mt76.mcu.wait); + skb_queue_purge(&dev->mt76.mcu.res_q); + + mt76u_stop_rx(&dev->mt76); mt76u_stop_tx(&dev->mt76); - mt7921_stop(hw); + + mt792xu_wfsys_reset(dev); + + clear_bit(MT76_MCU_RESET, &dev->mphy.state); + err = mt76u_resume_rx(&dev->mt76); + if (err) + goto out; + + err = mt792xu_mcu_power_on(dev); + if (err) + goto out; + + err = mt792xu_dma_init(dev, false); + if (err) + goto out; + + mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE); + mt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN); + + err = mt7921_run_firmware(dev); + if (err) + goto out; + + mt76_clear(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN); + + err = mt7921_mcu_set_eeprom(dev); + if (err) + goto out; + + err = mt7921_mac_init(dev); + if (err) + goto out; + + err = __mt7921_start(&dev->phy); +out: + clear_bit(MT76_RESET, &dev->mphy.state); + + mt76_worker_enable(&dev->mt76.tx_worker); + + return err; } -static void mt7921u_cleanup(struct mt7921_dev *dev) +static void mt7921u_stop(struct ieee80211_hw *hw) { - clear_bit(MT76_STATE_INITIALIZED, &dev->mphy.state); - mt7921u_wfsys_reset(dev); - skb_queue_purge(&dev->mt76.mcu.res_q); - mt76u_queues_deinit(&dev->mt76); + struct mt792x_dev *dev = mt792x_hw_dev(hw); + + mt76u_stop_tx(&dev->mt76); + mt7921_stop(hw); } static int mt7921u_probe(struct usb_interface *usb_intf, @@ -189,31 +161,31 @@ static int mt7921u_probe(struct usb_interface *usb_intf, .sta_add = mt7921_mac_sta_add, .sta_assoc = mt7921_mac_sta_assoc, .sta_remove = mt7921_mac_sta_remove, - .update_survey = mt7921_update_channel, + .update_survey = mt792x_update_channel, }; - static const struct mt7921_hif_ops hif_ops = { + static const struct mt792x_hif_ops hif_ops = { .mcu_init = mt7921u_mcu_init, - .init_reset = mt7921u_init_reset, + .init_reset = mt792xu_init_reset, .reset = mt7921u_mac_reset, }; static struct mt76_bus_ops bus_ops = { - .rr = mt7921u_rr, - .wr = mt7921u_wr, - .rmw = mt7921u_rmw, + .rr = mt792xu_rr, + .wr = mt792xu_wr, + .rmw = mt792xu_rmw, .read_copy = mt76u_read_copy, - .write_copy = mt7921u_copy, + .write_copy = mt792xu_copy, .type = MT76_BUS_USB, }; struct usb_device *udev = interface_to_usbdev(usb_intf); struct ieee80211_ops *ops; struct ieee80211_hw *hw; - struct mt7921_dev *dev; + struct mt792x_dev *dev; struct mt76_dev *mdev; u8 features; int ret; - ops = mt7921_get_mac80211_ops(&usb_intf->dev, (void *)id->driver_info, - &features); + ops = mt792x_get_mac80211_ops(&usb_intf->dev, &mt7921_ops, + (void *)id->driver_info, &features); if (!ops) return -ENOMEM; @@ -222,7 +194,7 @@ static int mt7921u_probe(struct usb_interface *usb_intf, if (!mdev) return -ENOMEM; - dev = container_of(mdev, struct mt7921_dev, mt76); + dev = container_of(mdev, struct mt792x_dev, mt76); dev->fw_features = features; dev->hif_ops = &hif_ops; @@ -240,12 +212,12 @@ static int mt7921u_probe(struct usb_interface *usb_intf, dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev); if (mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY)) { - ret = mt7921u_wfsys_reset(dev); + ret = mt792xu_wfsys_reset(dev); if (ret) goto error; } - ret = mt7921u_mcu_power_on(dev); + ret = mt792xu_mcu_power_on(dev); if (ret) goto error; @@ -257,7 +229,7 @@ static int mt7921u_probe(struct usb_interface *usb_intf, if (ret) goto error; - ret = mt7921u_dma_init(dev, false); + ret = mt792xu_dma_init(dev, false); if (ret) goto error; @@ -282,27 +254,10 @@ error: return ret; } -static void mt7921u_disconnect(struct usb_interface *usb_intf) -{ - struct mt7921_dev *dev = usb_get_intfdata(usb_intf); - - cancel_work_sync(&dev->init_work); - if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state)) - return; - - mt76_unregister_device(&dev->mt76); - mt7921u_cleanup(dev); - - usb_set_intfdata(usb_intf, NULL); - usb_put_dev(interface_to_usbdev(usb_intf)); - - mt76_free_device(&dev->mt76); -} - #ifdef CONFIG_PM static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state) { - struct mt7921_dev *dev = usb_get_intfdata(intf); + struct mt792x_dev *dev = usb_get_intfdata(intf); struct mt76_connac_pm *pm = &dev->pm; int err; @@ -322,14 +277,14 @@ failed: pm->suspended = false; if (err < 0) - mt7921_reset(&dev->mt76); + mt792x_reset(&dev->mt76); return err; } static int mt7921u_resume(struct usb_interface *intf) { - struct mt7921_dev *dev = usb_get_intfdata(intf); + struct mt792x_dev *dev = usb_get_intfdata(intf); struct mt76_connac_pm *pm = &dev->pm; bool reinit = true; int err, i; @@ -349,8 +304,8 @@ static int mt7921u_resume(struct usb_interface *intf) msleep(20); } - if (reinit || mt7921_dma_need_reinit(dev)) { - err = mt7921u_dma_init(dev, true); + if (reinit || mt792x_dma_need_reinit(dev)) { + err = mt792xu_dma_init(dev, true); if (err) goto failed; } @@ -364,7 +319,7 @@ failed: pm->suspended = false; if (err < 0) - mt7921_reset(&dev->mt76); + mt792x_reset(&dev->mt76); return err; } @@ -378,7 +333,7 @@ static struct usb_driver mt7921u_driver = { .name = KBUILD_MODNAME, .id_table = mt7921u_device_table, .probe = mt7921u_probe, - .disconnect = mt7921u_disconnect, + .disconnect = mt792xu_disconnect, #ifdef CONFIG_PM .suspend = mt7921u_suspend, .resume = mt7921u_resume, diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb_mac.c deleted file mode 100644 index 50eb6e7fd6b5..000000000000 --- a/drivers/net/wireless/mediatek/mt76/mt7921/usb_mac.c +++ /dev/null @@ -1,255 +0,0 @@ -// SPDX-License-Identifier: ISC -/* Copyright (C) 2022 MediaTek Inc. - * - * Author: Lorenzo Bianconi <lorenzo@kernel.org> - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/usb.h> - -#include "mt7921.h" -#include "mcu.h" -#include "../mt76_connac2_mac.h" - -static u32 mt7921u_uhw_rr(struct mt76_dev *dev, u32 addr) -{ - u32 ret; - - mutex_lock(&dev->usb.usb_ctrl_mtx); - ret = ___mt76u_rr(dev, MT_VEND_DEV_MODE, - USB_DIR_IN | MT_USB_TYPE_UHW_VENDOR, addr); - mutex_unlock(&dev->usb.usb_ctrl_mtx); - - return ret; -} - -static void mt7921u_uhw_wr(struct mt76_dev *dev, u32 addr, u32 val) -{ - mutex_lock(&dev->usb.usb_ctrl_mtx); - ___mt76u_wr(dev, MT_VEND_WRITE, - USB_DIR_OUT | MT_USB_TYPE_UHW_VENDOR, addr, val); - mutex_unlock(&dev->usb.usb_ctrl_mtx); -} - -static void mt7921u_dma_prefetch(struct mt7921_dev *dev) -{ - mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(0), - MT_WPDMA0_MAX_CNT_MASK, 4); - mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(0), - MT_WPDMA0_BASE_PTR_MASK, 0x80); - - mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(1), - MT_WPDMA0_MAX_CNT_MASK, 4); - mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(1), - MT_WPDMA0_BASE_PTR_MASK, 0xc0); - - mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(2), - MT_WPDMA0_MAX_CNT_MASK, 4); - mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(2), - MT_WPDMA0_BASE_PTR_MASK, 0x100); - - mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(3), - MT_WPDMA0_MAX_CNT_MASK, 4); - mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(3), - MT_WPDMA0_BASE_PTR_MASK, 0x140); - - mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(4), - MT_WPDMA0_MAX_CNT_MASK, 4); - mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(4), - MT_WPDMA0_BASE_PTR_MASK, 0x180); - - mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(16), - MT_WPDMA0_MAX_CNT_MASK, 4); - mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(16), - MT_WPDMA0_BASE_PTR_MASK, 0x280); - - mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(17), - MT_WPDMA0_MAX_CNT_MASK, 4); - mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(17), - MT_WPDMA0_BASE_PTR_MASK, 0x2c0); -} - -static void mt7921u_wfdma_init(struct mt7921_dev *dev) -{ - mt7921u_dma_prefetch(dev); - - mt76_clear(dev, MT_UWFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_OMIT_RX_INFO); - mt76_set(dev, MT_UWFDMA0_GLO_CFG, - MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | - MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2 | - MT_WFDMA0_GLO_CFG_FW_DWLD_BYPASS_DMASHDL | - MT_WFDMA0_GLO_CFG_TX_DMA_EN | - MT_WFDMA0_GLO_CFG_RX_DMA_EN); - - /* disable dmashdl */ - mt76_clear(dev, MT_UWFDMA0_GLO_CFG_EXT0, - MT_WFDMA0_CSR_TX_DMASHDL_ENABLE); - mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS); - - mt76_set(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT); -} - -static int mt7921u_dma_rx_evt_ep4(struct mt7921_dev *dev) -{ - if (!mt76_poll(dev, MT_UWFDMA0_GLO_CFG, - MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000)) - return -ETIMEDOUT; - - mt76_clear(dev, MT_UWFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_RX_DMA_EN); - mt76_set(dev, MT_WFDMA_HOST_CONFIG, - MT_WFDMA_HOST_CONFIG_USB_RXEVT_EP4_EN); - mt76_set(dev, MT_UWFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_RX_DMA_EN); - - return 0; -} - -static void mt7921u_epctl_rst_opt(struct mt7921_dev *dev, bool reset) -{ - u32 val; - - /* usb endpoint reset opt - * bits[4,9]: out blk ep 4-9 - * bits[20,21]: in blk ep 4-5 - * bits[22]: in int ep 6 - */ - val = mt7921u_uhw_rr(&dev->mt76, MT_SSUSB_EPCTL_CSR_EP_RST_OPT); - if (reset) - val |= GENMASK(9, 4) | GENMASK(22, 20); - else - val &= ~(GENMASK(9, 4) | GENMASK(22, 20)); - mt7921u_uhw_wr(&dev->mt76, MT_SSUSB_EPCTL_CSR_EP_RST_OPT, val); -} - -int mt7921u_dma_init(struct mt7921_dev *dev, bool resume) -{ - int err; - - mt7921u_wfdma_init(dev); - - mt76_clear(dev, MT_UDMA_WLCFG_0, MT_WL_RX_FLUSH); - - mt76_set(dev, MT_UDMA_WLCFG_0, - MT_WL_RX_EN | MT_WL_TX_EN | - MT_WL_RX_MPSZ_PAD0 | MT_TICK_1US_EN); - mt76_clear(dev, MT_UDMA_WLCFG_0, - MT_WL_RX_AGG_TO | MT_WL_RX_AGG_LMT); - mt76_clear(dev, MT_UDMA_WLCFG_1, MT_WL_RX_AGG_PKT_LMT); - - if (resume) - return 0; - - err = mt7921u_dma_rx_evt_ep4(dev); - if (err) - return err; - - mt7921u_epctl_rst_opt(dev, false); - - return 0; -} - -int mt7921u_wfsys_reset(struct mt7921_dev *dev) -{ - u32 val; - int i; - - mt7921u_epctl_rst_opt(dev, false); - - val = mt7921u_uhw_rr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST); - val |= MT_CBTOP_RGU_WF_SUBSYS_RST_WF_WHOLE_PATH; - mt7921u_uhw_wr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST, val); - - usleep_range(10, 20); - - val = mt7921u_uhw_rr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST); - val &= ~MT_CBTOP_RGU_WF_SUBSYS_RST_WF_WHOLE_PATH; - mt7921u_uhw_wr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST, val); - - mt7921u_uhw_wr(&dev->mt76, MT_UDMA_CONN_INFRA_STATUS_SEL, 0); - for (i = 0; i < MT7921_WFSYS_INIT_RETRY_COUNT; i++) { - val = mt7921u_uhw_rr(&dev->mt76, MT_UDMA_CONN_INFRA_STATUS); - if (val & MT_UDMA_CONN_WFSYS_INIT_DONE) - break; - - msleep(100); - } - - if (i == MT7921_WFSYS_INIT_RETRY_COUNT) - return -ETIMEDOUT; - - return 0; -} - -int mt7921u_init_reset(struct mt7921_dev *dev) -{ - set_bit(MT76_RESET, &dev->mphy.state); - - wake_up(&dev->mt76.mcu.wait); - skb_queue_purge(&dev->mt76.mcu.res_q); - - mt76u_stop_rx(&dev->mt76); - mt76u_stop_tx(&dev->mt76); - - mt7921u_wfsys_reset(dev); - - clear_bit(MT76_RESET, &dev->mphy.state); - - return mt76u_resume_rx(&dev->mt76); -} - -int mt7921u_mac_reset(struct mt7921_dev *dev) -{ - int err; - - mt76_txq_schedule_all(&dev->mphy); - mt76_worker_disable(&dev->mt76.tx_worker); - - set_bit(MT76_RESET, &dev->mphy.state); - set_bit(MT76_MCU_RESET, &dev->mphy.state); - - wake_up(&dev->mt76.mcu.wait); - skb_queue_purge(&dev->mt76.mcu.res_q); - - mt76u_stop_rx(&dev->mt76); - mt76u_stop_tx(&dev->mt76); - - mt7921u_wfsys_reset(dev); - - clear_bit(MT76_MCU_RESET, &dev->mphy.state); - err = mt76u_resume_rx(&dev->mt76); - if (err) - goto out; - - err = mt7921u_mcu_power_on(dev); - if (err) - goto out; - - err = mt7921u_dma_init(dev, false); - if (err) - goto out; - - mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE); - mt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN); - - err = mt7921_run_firmware(dev); - if (err) - goto out; - - mt76_clear(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN); - - err = mt7921_mcu_set_eeprom(dev); - if (err) - goto out; - - err = mt7921_mac_init(dev); - if (err) - goto out; - - err = __mt7921_start(&dev->phy); -out: - clear_bit(MT76_RESET, &dev->mphy.state); - - mt76_worker_enable(&dev->mt76.tx_worker); - - return err; -} diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h new file mode 100644 index 000000000000..5d5ab8630041 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt792x.h @@ -0,0 +1,367 @@ +/* SPDX-License-Identifier: ISC */ +/* Copyright (C) 2023 MediaTek Inc. */ + +#ifndef __MT792X_H +#define __MT792X_H + +#include <linux/interrupt.h> +#include <linux/ktime.h> + +#include "mt76_connac_mcu.h" +#include "mt792x_regs.h" +#include "mt792x_acpi_sar.h" + +#define MT792x_PM_TIMEOUT (HZ / 12) +#define MT792x_HW_SCAN_TIMEOUT (HZ / 10) + +#define MT792x_MAX_INTERFACES 4 +#define MT792x_WTBL_SIZE 20 +#define MT792x_WTBL_RESERVED (MT792x_WTBL_SIZE - 1) +#define MT792x_WTBL_STA (MT792x_WTBL_RESERVED - MT792x_MAX_INTERFACES) + +#define MT792x_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */ +#define MT792x_CFEND_RATE_11B 0x03 /* 11B LP, 11M */ + +#define MT792x_FW_TAG_FEATURE 4 +#define MT792x_FW_CAP_CNM BIT(7) + +/* NOTE: used to map mt76_rates. idx may change if firmware expands table */ +#define MT792x_BASIC_RATES_TBL 11 + +#define MT792x_WATCHDOG_TIME (HZ / 4) + +#define MT792x_DRV_OWN_RETRY_COUNT 10 +#define MT792x_MCU_INIT_RETRY_COUNT 10 +#define MT792x_WFSYS_INIT_RETRY_COUNT 2 + +#define MT7921_FIRMWARE_WM "mediatek/WIFI_RAM_CODE_MT7961_1.bin" +#define MT7922_FIRMWARE_WM "mediatek/WIFI_RAM_CODE_MT7922_1.bin" + +#define MT7921_ROM_PATCH "mediatek/WIFI_MT7961_patch_mcu_1_2_hdr.bin" +#define MT7922_ROM_PATCH "mediatek/WIFI_MT7922_patch_mcu_1_1_hdr.bin" + +struct mt792x_vif; +struct mt792x_sta; + +struct mt792x_realease_info { + __le16 len; + u8 pad_len; + u8 tag; +} __packed; + +struct mt792x_fw_features { + u8 segment; + u8 data; + u8 rsv[14]; +} __packed; + +enum { + MT792x_CLC_POWER, + MT792x_CLC_CHAN, + MT792x_CLC_MAX_NUM, +}; + +DECLARE_EWMA(avg_signal, 10, 8) + +struct mt792x_sta { + struct mt76_wcid wcid; /* must be first */ + + struct mt792x_vif *vif; + + u32 airtime_ac[8]; + + int ack_signal; + struct ewma_avg_signal avg_ack_signal; + + unsigned long last_txs; + + struct mt76_connac_sta_key_conf bip; +}; + +DECLARE_EWMA(rssi, 10, 8); + +struct mt792x_vif { + struct mt76_vif mt76; /* must be first */ + + struct mt792x_sta sta; + struct mt792x_sta *wep_sta; + + struct mt792x_phy *phy; + + struct ewma_rssi rssi; + + struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; + struct ieee80211_chanctx_conf *ctx; +}; + +struct mt792x_phy { + struct mt76_phy *mt76; + struct mt792x_dev *dev; + + struct ieee80211_sband_iftype_data iftype[NUM_NL80211_BANDS][NUM_NL80211_IFTYPES]; + + u64 omac_mask; + + u16 noise; + + s16 coverage_class; + u8 slottime; + + u32 rx_ampdu_ts; + u32 ampdu_ref; + + struct mt76_mib_stats mib; + + u8 sta_work_count; + + struct sk_buff_head scan_event_list; + struct delayed_work scan_work; +#ifdef CONFIG_ACPI + void *acpisar; +#endif + void *clc[MT792x_CLC_MAX_NUM]; + + struct work_struct roc_work; + struct timer_list roc_timer; + wait_queue_head_t roc_wait; + u8 roc_token_id; + bool roc_grant; +}; + +struct mt792x_irq_map { + u32 host_irq_enable; + struct { + u32 all_complete_mask; + u32 mcu_complete_mask; + } tx; + struct { + u32 data_complete_mask; + u32 wm_complete_mask; + u32 wm2_complete_mask; + } rx; +}; + +#define mt792x_init_reset(dev) ((dev)->hif_ops->init_reset(dev)) +#define mt792x_dev_reset(dev) ((dev)->hif_ops->reset(dev)) +#define mt792x_mcu_init(dev) ((dev)->hif_ops->mcu_init(dev)) +#define __mt792x_mcu_drv_pmctrl(dev) ((dev)->hif_ops->drv_own(dev)) +#define __mt792x_mcu_fw_pmctrl(dev) ((dev)->hif_ops->fw_own(dev)) + +struct mt792x_hif_ops { + int (*init_reset)(struct mt792x_dev *dev); + int (*reset)(struct mt792x_dev *dev); + int (*mcu_init)(struct mt792x_dev *dev); + int (*drv_own)(struct mt792x_dev *dev); + int (*fw_own)(struct mt792x_dev *dev); +}; + +struct mt792x_dev { + union { /* must be first */ + struct mt76_dev mt76; + struct mt76_phy mphy; + }; + + const struct mt76_bus_ops *bus_ops; + struct mt792x_phy phy; + + struct work_struct reset_work; + bool hw_full_reset:1; + bool hw_init_done:1; + bool fw_assert:1; + bool has_eht:1; + + struct work_struct init_work; + + u8 fw_debug; + u8 fw_features; + + struct mt76_connac_pm pm; + struct mt76_connac_coredump coredump; + const struct mt792x_hif_ops *hif_ops; + const struct mt792x_irq_map *irq_map; + + struct work_struct ipv6_ns_work; + /* IPv6 addresses for WoWLAN */ + struct sk_buff_head ipv6_ns_list; + + enum environment_cap country_ie_env; + u32 backup_l1; + u32 backup_l2; +}; + +static inline struct mt792x_dev * +mt792x_hw_dev(struct ieee80211_hw *hw) +{ + struct mt76_phy *phy = hw->priv; + + return container_of(phy->dev, struct mt792x_dev, mt76); +} + +static inline struct mt792x_phy * +mt792x_hw_phy(struct ieee80211_hw *hw) +{ + struct mt76_phy *phy = hw->priv; + + return phy->priv; +} + +static inline void +mt792x_get_status_freq_info(struct mt76_rx_status *status, u8 chfreq) +{ + if (chfreq > 180) { + status->band = NL80211_BAND_6GHZ; + chfreq = (chfreq - 181) * 4 + 1; + } else if (chfreq > 14) { + status->band = NL80211_BAND_5GHZ; + } else { + status->band = NL80211_BAND_2GHZ; + } + status->freq = ieee80211_channel_to_frequency(chfreq, status->band); +} + +static inline bool mt792x_dma_need_reinit(struct mt792x_dev *dev) +{ + return !mt76_get_field(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT); +} + +#define mt792x_mutex_acquire(dev) \ + mt76_connac_mutex_acquire(&(dev)->mt76, &(dev)->pm) +#define mt792x_mutex_release(dev) \ + mt76_connac_mutex_release(&(dev)->mt76, &(dev)->pm) + +void mt792x_pm_wake_work(struct work_struct *work); +void mt792x_pm_power_save_work(struct work_struct *work); +void mt792x_reset(struct mt76_dev *mdev); +void mt792x_update_channel(struct mt76_phy *mphy); +void mt792x_mac_reset_counters(struct mt792x_phy *phy); +void mt792x_mac_init_band(struct mt792x_dev *dev, u8 band); +void mt792x_mac_assoc_rssi(struct mt792x_dev *dev, struct sk_buff *skb); +struct mt76_wcid *mt792x_rx_get_wcid(struct mt792x_dev *dev, u16 idx, + bool unicast); +void mt792x_mac_update_mib_stats(struct mt792x_phy *phy); +void mt792x_mac_set_timeing(struct mt792x_phy *phy); +void mt792x_mac_work(struct work_struct *work); +void mt792x_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +void mt792x_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, + struct sk_buff *skb); +int mt792x_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + unsigned int link_id, u16 queue, + const struct ieee80211_tx_queue_params *params); +int mt792x_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats); +u64 mt792x_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +void mt792x_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u64 timestamp); +void mt792x_tx_worker(struct mt76_worker *w); +void mt792x_roc_timer(struct timer_list *timer); +void mt792x_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u32 queues, bool drop); +int mt792x_assign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *ctx); +void mt792x_unassign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *ctx); +void mt792x_set_wakeup(struct ieee80211_hw *hw, bool enabled); +void mt792x_get_et_strings(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u32 sset, u8 *data); +int mt792x_get_et_sset_count(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + int sset); +void mt792x_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ethtool_stats *stats, u64 *data); +void mt792x_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct station_info *sinfo); +void mt792x_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class); +void mt792x_dma_cleanup(struct mt792x_dev *dev); +int mt792x_dma_enable(struct mt792x_dev *dev); +int mt792x_wpdma_reset(struct mt792x_dev *dev, bool force); +int mt792x_wpdma_reinit_cond(struct mt792x_dev *dev); +int mt792x_dma_disable(struct mt792x_dev *dev, bool force); +irqreturn_t mt792x_irq_handler(int irq, void *dev_instance); +void mt792x_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q); +int mt792x_poll_tx(struct napi_struct *napi, int budget); +int mt792x_poll_rx(struct napi_struct *napi, int budget); +void mt792x_irq_tasklet(unsigned long data); +int mt792x_wfsys_reset(struct mt792x_dev *dev); +int mt792x_tx_stats_show(struct seq_file *file, void *data); +int mt792x_queues_acq(struct seq_file *s, void *data); +int mt792x_queues_read(struct seq_file *s, void *data); +int mt792x_pm_stats(struct seq_file *s, void *data); +int mt792x_pm_idle_timeout_set(void *data, u64 val); +int mt792x_pm_idle_timeout_get(void *data, u64 *val); +int mt792x_init_wiphy(struct ieee80211_hw *hw); +struct ieee80211_ops * +mt792x_get_mac80211_ops(struct device *dev, + const struct ieee80211_ops *mac80211_ops, + void *drv_data, u8 *fw_features); +int mt792x_init_wcid(struct mt792x_dev *dev); +int mt792x_mcu_drv_pmctrl(struct mt792x_dev *dev); +int mt792x_mcu_fw_pmctrl(struct mt792x_dev *dev); + +static inline char *mt792x_ram_name(struct mt792x_dev *dev) +{ + switch (mt76_chip(&dev->mt76)) { + case 0x7922: + return MT7922_FIRMWARE_WM; + default: + return MT7921_FIRMWARE_WM; + } +} + +static inline char *mt792x_patch_name(struct mt792x_dev *dev) +{ + switch (mt76_chip(&dev->mt76)) { + case 0x7922: + return MT7922_ROM_PATCH; + default: + return MT7921_ROM_PATCH; + } +} + +int mt792x_load_firmware(struct mt792x_dev *dev); + +/* usb */ +#define MT_USB_TYPE_VENDOR (USB_TYPE_VENDOR | 0x1f) +#define MT_USB_TYPE_UHW_VENDOR (USB_TYPE_VENDOR | 0x1e) +int mt792xu_dma_init(struct mt792x_dev *dev, bool resume); +int mt792xu_mcu_power_on(struct mt792x_dev *dev); +int mt792xu_wfsys_reset(struct mt792x_dev *dev); +int mt792xu_init_reset(struct mt792x_dev *dev); +u32 mt792xu_rr(struct mt76_dev *dev, u32 addr); +void mt792xu_wr(struct mt76_dev *dev, u32 addr, u32 val); +u32 mt792xu_rmw(struct mt76_dev *dev, u32 addr, u32 mask, u32 val); +void mt792xu_copy(struct mt76_dev *dev, u32 offset, const void *data, int len); +void mt792xu_disconnect(struct usb_interface *usb_intf); + +int __mt792xe_mcu_drv_pmctrl(struct mt792x_dev *dev); +int mt792xe_mcu_drv_pmctrl(struct mt792x_dev *dev); +int mt792xe_mcu_fw_pmctrl(struct mt792x_dev *dev); + +#ifdef CONFIG_ACPI +int mt792x_init_acpi_sar(struct mt792x_dev *dev); +int mt792x_init_acpi_sar_power(struct mt792x_phy *phy, bool set_default); +u8 mt792x_acpi_get_flags(struct mt792x_phy *phy); +#else +static inline int mt792x_init_acpi_sar(struct mt792x_dev *dev) +{ + return 0; +} + +static inline int mt792x_init_acpi_sar_power(struct mt792x_phy *phy, + bool set_default) +{ + return 0; +} + +static inline u8 mt792x_acpi_get_flags(struct mt792x_phy *phy) +{ + return 0; +} +#endif + +#endif /* __MT7925_H */ diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c index 48dd0decac5d..303c0f5c9c66 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c +++ b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c @@ -1,15 +1,15 @@ // SPDX-License-Identifier: ISC -/* Copyright (C) 2022 MediaTek Inc. */ +/* Copyright (C) 2023 MediaTek Inc. */ #include <linux/acpi.h> -#include "mt7921.h" +#include "mt792x.h" static int -mt7921_acpi_read(struct mt7921_dev *dev, u8 *method, u8 **tbl, u32 *len) +mt792x_acpi_read(struct mt792x_dev *dev, u8 *method, u8 **tbl, u32 *len) { struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *sar_root, *sar_unit; struct mt76_dev *mdev = &dev->mt76; + union acpi_object *sar_root; acpi_handle root, handle; acpi_status status; u32 i = 0; @@ -45,18 +45,20 @@ mt7921_acpi_read(struct mt7921_dev *dev, u8 *method, u8 **tbl, u32 *len) goto free; } } + if (len) *len = sar_root->package.count; for (i = 0; i < sar_root->package.count; i++) { - sar_unit = &sar_root->package.elements[i]; + union acpi_object *sar_unit = &sar_root->package.elements[i]; if (sar_unit->type != ACPI_TYPE_INTEGER) break; + *(*tbl + i) = (u8)sar_unit->integer.value; } - ret = (i == sar_root->package.count) ? 0 : -EINVAL; + ret = i == sar_root->package.count ? 0 : -EINVAL; free: kfree(sar_root); @@ -64,36 +66,37 @@ free: } /* MTCL : Country List Table for 6G band */ -static int -mt7921_asar_acpi_read_mtcl(struct mt7921_dev *dev, u8 **table, u8 *version) +static void +mt792x_asar_acpi_read_mtcl(struct mt792x_dev *dev, u8 **table, u8 *version) { - *version = (mt7921_acpi_read(dev, MT7921_ACPI_MTCL, table, NULL) < 0) - ? 1 : 2; - return 0; + if (mt792x_acpi_read(dev, MT792x_ACPI_MTCL, table, NULL) < 0) + *version = 1; + else + *version = 2; } /* MTDS : Dynamic SAR Power Table */ static int -mt7921_asar_acpi_read_mtds(struct mt7921_dev *dev, u8 **table, u8 version) +mt792x_asar_acpi_read_mtds(struct mt792x_dev *dev, u8 **table, u8 version) { int len, ret, sarlen, prelen, tblcnt; bool enable; - ret = mt7921_acpi_read(dev, MT7921_ACPI_MTDS, table, &len); + ret = mt792x_acpi_read(dev, MT792x_ACPI_MTDS, table, &len); if (ret) return ret; /* Table content validation */ switch (version) { case 1: - enable = ((struct mt7921_asar_dyn *)*table)->enable; - sarlen = sizeof(struct mt7921_asar_dyn_limit); - prelen = sizeof(struct mt7921_asar_dyn); + enable = ((struct mt792x_asar_dyn *)*table)->enable; + sarlen = sizeof(struct mt792x_asar_dyn_limit); + prelen = sizeof(struct mt792x_asar_dyn); break; case 2: - enable = ((struct mt7921_asar_dyn_v2 *)*table)->enable; - sarlen = sizeof(struct mt7921_asar_dyn_limit_v2); - prelen = sizeof(struct mt7921_asar_dyn_v2); + enable = ((struct mt792x_asar_dyn_v2 *)*table)->enable; + sarlen = sizeof(struct mt792x_asar_dyn_limit_v2); + prelen = sizeof(struct mt792x_asar_dyn_v2); break; default: return -EINVAL; @@ -101,88 +104,89 @@ mt7921_asar_acpi_read_mtds(struct mt7921_dev *dev, u8 **table, u8 version) tblcnt = (len - prelen) / sarlen; if (!enable || - tblcnt > MT7921_ASAR_MAX_DYN || tblcnt < MT7921_ASAR_MIN_DYN) - ret = -EINVAL; + tblcnt > MT792x_ASAR_MAX_DYN || tblcnt < MT792x_ASAR_MIN_DYN) + return -EINVAL; - return ret; + return 0; } /* MTGS : Geo SAR Power Table */ static int -mt7921_asar_acpi_read_mtgs(struct mt7921_dev *dev, u8 **table, u8 version) +mt792x_asar_acpi_read_mtgs(struct mt792x_dev *dev, u8 **table, u8 version) { - int len, ret = 0, sarlen, prelen, tblcnt; + int len, ret, sarlen, prelen, tblcnt; - ret = mt7921_acpi_read(dev, MT7921_ACPI_MTGS, table, &len); + ret = mt792x_acpi_read(dev, MT792x_ACPI_MTGS, table, &len); if (ret) return ret; /* Table content validation */ switch (version) { case 1: - sarlen = sizeof(struct mt7921_asar_geo_limit); - prelen = sizeof(struct mt7921_asar_geo); + sarlen = sizeof(struct mt792x_asar_geo_limit); + prelen = sizeof(struct mt792x_asar_geo); break; case 2: - sarlen = sizeof(struct mt7921_asar_geo_limit_v2); - prelen = sizeof(struct mt7921_asar_geo_v2); + sarlen = sizeof(struct mt792x_asar_geo_limit_v2); + prelen = sizeof(struct mt792x_asar_geo_v2); break; default: return -EINVAL; } tblcnt = (len - prelen) / sarlen; - if (tblcnt > MT7921_ASAR_MAX_GEO || tblcnt < MT7921_ASAR_MIN_GEO) - ret = -EINVAL; + if (tblcnt > MT792x_ASAR_MAX_GEO || tblcnt < MT792x_ASAR_MIN_GEO) + return -EINVAL; - return ret; + return 0; } /* MTFG : Flag Table */ static int -mt7921_asar_acpi_read_mtfg(struct mt7921_dev *dev, u8 **table) +mt792x_asar_acpi_read_mtfg(struct mt792x_dev *dev, u8 **table) { int len, ret; - ret = mt7921_acpi_read(dev, MT7921_ACPI_MTFG, table, &len); + ret = mt792x_acpi_read(dev, MT792x_ACPI_MTFG, table, &len); if (ret) return ret; - if (len < MT7921_ASAR_MIN_FG) - ret = -EINVAL; + if (len < MT792x_ASAR_MIN_FG) + return -EINVAL; - return ret; + return 0; } -int mt7921_init_acpi_sar(struct mt7921_dev *dev) +int mt792x_init_acpi_sar(struct mt792x_dev *dev) { - struct mt7921_acpi_sar *asar; + struct mt792x_acpi_sar *asar; int ret; asar = devm_kzalloc(dev->mt76.dev, sizeof(*asar), GFP_KERNEL); if (!asar) return -ENOMEM; - mt7921_asar_acpi_read_mtcl(dev, (u8 **)&asar->countrylist, &asar->ver); + mt792x_asar_acpi_read_mtcl(dev, (u8 **)&asar->countrylist, &asar->ver); /* MTDS is mandatory. Return error if table is invalid */ - ret = mt7921_asar_acpi_read_mtds(dev, (u8 **)&asar->dyn, asar->ver); + ret = mt792x_asar_acpi_read_mtds(dev, (u8 **)&asar->dyn, asar->ver); if (ret) { devm_kfree(dev->mt76.dev, asar->dyn); devm_kfree(dev->mt76.dev, asar->countrylist); devm_kfree(dev->mt76.dev, asar); + return ret; } /* MTGS is optional */ - ret = mt7921_asar_acpi_read_mtgs(dev, (u8 **)&asar->geo, asar->ver); + ret = mt792x_asar_acpi_read_mtgs(dev, (u8 **)&asar->geo, asar->ver); if (ret) { devm_kfree(dev->mt76.dev, asar->geo); asar->geo = NULL; } /* MTFG is optional */ - ret = mt7921_asar_acpi_read_mtfg(dev, (u8 **)&asar->fg); + ret = mt792x_asar_acpi_read_mtfg(dev, (u8 **)&asar->fg); if (ret) { devm_kfree(dev->mt76.dev, asar->fg); asar->fg = NULL; @@ -191,13 +195,14 @@ int mt7921_init_acpi_sar(struct mt7921_dev *dev) return 0; } +EXPORT_SYMBOL_GPL(mt792x_init_acpi_sar); static s8 -mt7921_asar_get_geo_pwr(struct mt7921_phy *phy, +mt792x_asar_get_geo_pwr(struct mt792x_phy *phy, enum nl80211_band band, s8 dyn_power) { - struct mt7921_acpi_sar *asar = phy->acpisar; - struct mt7921_asar_geo_band *band_pwr; + struct mt792x_acpi_sar *asar = phy->acpisar; + struct mt792x_asar_geo_band *band_pwr; s8 geo_power; u8 idx, max; @@ -248,12 +253,12 @@ mt7921_asar_get_geo_pwr(struct mt7921_phy *phy, } static s8 -mt7921_asar_range_pwr(struct mt7921_phy *phy, +mt792x_asar_range_pwr(struct mt792x_phy *phy, const struct cfg80211_sar_freq_ranges *range, u8 idx) { const struct cfg80211_sar_capa *capa = phy->mt76->hw->wiphy->sar_capa; - struct mt7921_acpi_sar *asar = phy->acpisar; + struct mt792x_acpi_sar *asar = phy->acpisar; u8 *limit, band, max; if (!capa) @@ -277,10 +282,10 @@ mt7921_asar_range_pwr(struct mt7921_phy *phy, else band = NL80211_BAND_2GHZ; - return mt7921_asar_get_geo_pwr(phy, band, limit[idx]); + return mt792x_asar_get_geo_pwr(phy, band, limit[idx]); } -int mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default) +int mt792x_init_acpi_sar_power(struct mt792x_phy *phy, bool set_default) { const struct cfg80211_sar_capa *capa = phy->mt76->hw->wiphy->sar_capa; int i; @@ -300,41 +305,46 @@ int mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default) continue; frp->power = min_t(s8, set_default ? 127 : frp->power, - mt7921_asar_range_pwr(phy, frp->range, i)); + mt792x_asar_range_pwr(phy, frp->range, i)); } return 0; } +EXPORT_SYMBOL_GPL(mt792x_init_acpi_sar_power); -u8 mt7921_acpi_get_flags(struct mt7921_phy *phy) +u8 mt792x_acpi_get_flags(struct mt792x_phy *phy) { - struct mt7921_asar_fg *fg; + struct mt792x_acpi_sar *acpisar = phy->acpisar; + struct mt792x_asar_fg *fg; struct { u8 acpi_idx; u8 chip_idx; } map[] = { - {1, 1}, - {4, 2}, + { 1, 1 }, + { 4, 2 }, }; u8 flags = BIT(0); int i, j; - if (!phy->acpisar) + if (!acpisar) return 0; - fg = phy->acpisar->fg; + fg = acpisar->fg; if (!fg) return flags; /* pickup necessary settings per device and * translate the index of bitmap for chip command. */ - for (i = 0; i < fg->nr_flag; i++) - for (j = 0; j < ARRAY_SIZE(map); j++) + for (i = 0; i < fg->nr_flag; i++) { + for (j = 0; j < ARRAY_SIZE(map); j++) { if (fg->flag[i] == map[j].acpi_idx) { flags |= BIT(map[j].chip_idx); break; } + } + } return flags; } +EXPORT_SYMBOL_GPL(mt792x_acpi_get_flags); diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h new file mode 100644 index 000000000000..d6d332e863ba --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: ISC */ +/* Copyright (C) 2023 MediaTek Inc. */ + +#ifndef __MT7921_ACPI_SAR_H +#define __MT7921_ACPI_SAR_H + +#define MT792x_ASAR_MIN_DYN 1 +#define MT792x_ASAR_MAX_DYN 8 +#define MT792x_ASAR_MIN_GEO 3 +#define MT792x_ASAR_MAX_GEO 8 +#define MT792x_ASAR_MIN_FG 8 + +#define MT792x_ACPI_MTCL "MTCL" +#define MT792x_ACPI_MTDS "MTDS" +#define MT792x_ACPI_MTGS "MTGS" +#define MT792x_ACPI_MTFG "MTFG" + +struct mt792x_asar_dyn_limit { + u8 idx; + u8 frp[5]; +} __packed; + +struct mt792x_asar_dyn { + u8 names[4]; + u8 enable; + u8 nr_tbl; + DECLARE_FLEX_ARRAY(struct mt792x_asar_dyn_limit, tbl); +} __packed; + +struct mt792x_asar_dyn_limit_v2 { + u8 idx; + u8 frp[11]; +} __packed; + +struct mt792x_asar_dyn_v2 { + u8 names[4]; + u8 enable; + u8 rsvd; + u8 nr_tbl; + DECLARE_FLEX_ARRAY(struct mt792x_asar_dyn_limit_v2, tbl); +} __packed; + +struct mt792x_asar_geo_band { + u8 pwr; + u8 offset; +} __packed; + +struct mt792x_asar_geo_limit { + u8 idx; + /* 0:2G, 1:5G */ + struct mt792x_asar_geo_band band[2]; +} __packed; + +struct mt792x_asar_geo { + u8 names[4]; + u8 version; + u8 nr_tbl; + DECLARE_FLEX_ARRAY(struct mt792x_asar_geo_limit, tbl); +} __packed; + +struct mt792x_asar_geo_limit_v2 { + u8 idx; + /* 0:2G, 1:5G, 2:6G */ + struct mt792x_asar_geo_band band[3]; +} __packed; + +struct mt792x_asar_geo_v2 { + u8 names[4]; + u8 version; + u8 rsvd; + u8 nr_tbl; + DECLARE_FLEX_ARRAY(struct mt792x_asar_geo_limit_v2, tbl); +} __packed; + +struct mt792x_asar_cl { + u8 names[4]; + u8 version; + u8 mode_6g; + u8 cl6g[6]; +} __packed; + +struct mt792x_asar_fg { + u8 names[4]; + u8 version; + u8 rsvd; + u8 nr_flag; + u8 rsvd1; + u8 flag[]; +} __packed; + +struct mt792x_acpi_sar { + u8 ver; + union { + struct mt792x_asar_dyn *dyn; + struct mt792x_asar_dyn_v2 *dyn_v2; + }; + union { + struct mt792x_asar_geo *geo; + struct mt792x_asar_geo_v2 *geo_v2; + }; + struct mt792x_asar_cl *countrylist; + struct mt792x_asar_fg *fg; +}; + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c new file mode 100644 index 000000000000..46be7f996c7e --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c @@ -0,0 +1,844 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2023 MediaTek Inc. */ + +#include <linux/module.h> +#include <linux/firmware.h> + +#include "mt792x.h" +#include "dma.h" + +static const struct ieee80211_iface_limit if_limits[] = { + { + .max = MT792x_MAX_INTERFACES, + .types = BIT(NL80211_IFTYPE_STATION) + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_AP) + } +}; + +static const struct ieee80211_iface_combination if_comb[] = { + { + .limits = if_limits, + .n_limits = ARRAY_SIZE(if_limits), + .max_interfaces = MT792x_MAX_INTERFACES, + .num_different_channels = 1, + .beacon_int_infra_match = true, + }, +}; + +static const struct ieee80211_iface_limit if_limits_chanctx[] = { + { + .max = 2, + .types = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_P2P_CLIENT) + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_GO) + } +}; + +static const struct ieee80211_iface_combination if_comb_chanctx[] = { + { + .limits = if_limits_chanctx, + .n_limits = ARRAY_SIZE(if_limits_chanctx), + .max_interfaces = 2, + .num_different_channels = 2, + .beacon_int_infra_match = false, + } +}; + +void mt792x_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt76_phy *mphy = hw->priv; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_vif *vif = info->control.vif; + struct mt76_wcid *wcid = &dev->mt76.global_wcid; + int qid; + + if (control->sta) { + struct mt792x_sta *sta; + + sta = (struct mt792x_sta *)control->sta->drv_priv; + wcid = &sta->wcid; + } + + if (vif && !control->sta) { + struct mt792x_vif *mvif; + + mvif = (struct mt792x_vif *)vif->drv_priv; + wcid = &mvif->sta.wcid; + } + + if (mt76_connac_pm_ref(mphy, &dev->pm)) { + mt76_tx(mphy, control->sta, wcid, skb); + mt76_connac_pm_unref(mphy, &dev->pm); + return; + } + + qid = skb_get_queue_mapping(skb); + if (qid >= MT_TXQ_PSD) { + qid = IEEE80211_AC_BE; + skb_set_queue_mapping(skb, qid); + } + + mt76_connac_pm_queue_skb(hw, &dev->pm, wcid, skb); +} +EXPORT_SYMBOL_GPL(mt792x_tx); + +void mt792x_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_sta *msta = &mvif->sta; + struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt792x_phy *phy = mt792x_hw_phy(hw); + int idx = msta->wcid.idx; + + mt792x_mutex_acquire(dev); + mt76_connac_free_pending_tx_skbs(&dev->pm, &msta->wcid); + mt76_connac_mcu_uni_add_dev(&dev->mphy, vif, &mvif->sta.wcid, false); + + rcu_assign_pointer(dev->mt76.wcid[idx], NULL); + + dev->mt76.vif_mask &= ~BIT_ULL(mvif->mt76.idx); + phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx); + mt792x_mutex_release(dev); + + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (!list_empty(&msta->wcid.poll_list)) + list_del_init(&msta->wcid.poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); + + mt76_packet_id_flush(&dev->mt76, &msta->wcid); +} +EXPORT_SYMBOL_GPL(mt792x_remove_interface); + +int mt792x_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + unsigned int link_id, u16 queue, + const struct ieee80211_tx_queue_params *params) +{ + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + + /* no need to update right away, we'll get BSS_CHANGED_QOS */ + queue = mt76_connac_lmac_mapping(queue); + mvif->queue_params[queue] = *params; + + return 0; +} +EXPORT_SYMBOL_GPL(mt792x_conf_tx); + +int mt792x_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats) +{ + struct mt792x_phy *phy = mt792x_hw_phy(hw); + struct mt76_mib_stats *mib = &phy->mib; + + mt792x_mutex_acquire(phy->dev); + + stats->dot11RTSSuccessCount = mib->rts_cnt; + stats->dot11RTSFailureCount = mib->rts_retries_cnt; + stats->dot11FCSErrorCount = mib->fcs_err_cnt; + stats->dot11ACKFailureCount = mib->ack_fail_cnt; + + mt792x_mutex_release(phy->dev); + + return 0; +} +EXPORT_SYMBOL_GPL(mt792x_get_stats); + +u64 mt792x_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_dev *dev = mt792x_hw_dev(hw); + u8 omac_idx = mvif->mt76.omac_idx; + union { + u64 t64; + u32 t32[2]; + } tsf; + u16 n; + + mt792x_mutex_acquire(dev); + + n = omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : omac_idx; + /* TSF software read */ + mt76_set(dev, MT_LPON_TCR(0, n), MT_LPON_TCR_SW_MODE); + tsf.t32[0] = mt76_rr(dev, MT_LPON_UTTR0(0)); + tsf.t32[1] = mt76_rr(dev, MT_LPON_UTTR1(0)); + + mt792x_mutex_release(dev); + + return tsf.t64; +} +EXPORT_SYMBOL_GPL(mt792x_get_tsf); + +void mt792x_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u64 timestamp) +{ + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_dev *dev = mt792x_hw_dev(hw); + u8 omac_idx = mvif->mt76.omac_idx; + union { + u64 t64; + u32 t32[2]; + } tsf = { .t64 = timestamp, }; + u16 n; + + mt792x_mutex_acquire(dev); + + n = omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : omac_idx; + mt76_wr(dev, MT_LPON_UTTR0(0), tsf.t32[0]); + mt76_wr(dev, MT_LPON_UTTR1(0), tsf.t32[1]); + /* TSF software overwrite */ + mt76_set(dev, MT_LPON_TCR(0, n), MT_LPON_TCR_SW_WRITE); + + mt792x_mutex_release(dev); +} +EXPORT_SYMBOL_GPL(mt792x_set_tsf); + +void mt792x_tx_worker(struct mt76_worker *w) +{ + struct mt792x_dev *dev = container_of(w, struct mt792x_dev, + mt76.tx_worker); + + if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) { + queue_work(dev->mt76.wq, &dev->pm.wake_work); + return; + } + + mt76_txq_schedule_all(&dev->mphy); + mt76_connac_pm_unref(&dev->mphy, &dev->pm); +} +EXPORT_SYMBOL_GPL(mt792x_tx_worker); + +void mt792x_roc_timer(struct timer_list *timer) +{ + struct mt792x_phy *phy = from_timer(phy, timer, roc_timer); + + ieee80211_queue_work(phy->mt76->hw, &phy->roc_work); +} +EXPORT_SYMBOL_GPL(mt792x_roc_timer); + +void mt792x_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u32 queues, bool drop) +{ + struct mt792x_dev *dev = mt792x_hw_dev(hw); + + wait_event_timeout(dev->mt76.tx_wait, + !mt76_has_tx_pending(&dev->mphy), HZ / 2); +} +EXPORT_SYMBOL_GPL(mt792x_flush); + +int mt792x_assign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *ctx) +{ + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_dev *dev = mt792x_hw_dev(hw); + + mutex_lock(&dev->mt76.mutex); + mvif->ctx = ctx; + mutex_unlock(&dev->mt76.mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(mt792x_assign_vif_chanctx); + +void mt792x_unassign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *ctx) +{ + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct mt792x_dev *dev = mt792x_hw_dev(hw); + + mutex_lock(&dev->mt76.mutex); + mvif->ctx = NULL; + mutex_unlock(&dev->mt76.mutex); +} +EXPORT_SYMBOL_GPL(mt792x_unassign_vif_chanctx); + +void mt792x_set_wakeup(struct ieee80211_hw *hw, bool enabled) +{ + struct mt792x_dev *dev = mt792x_hw_dev(hw); + struct mt76_dev *mdev = &dev->mt76; + + device_set_wakeup_enable(mdev->dev, enabled); +} +EXPORT_SYMBOL_GPL(mt792x_set_wakeup); + +static const char mt792x_gstrings_stats[][ETH_GSTRING_LEN] = { + /* tx counters */ + "tx_ampdu_cnt", + "tx_mpdu_attempts", + "tx_mpdu_success", + "tx_pkt_ebf_cnt", + "tx_pkt_ibf_cnt", + "tx_ampdu_len:0-1", + "tx_ampdu_len:2-10", + "tx_ampdu_len:11-19", + "tx_ampdu_len:20-28", + "tx_ampdu_len:29-37", + "tx_ampdu_len:38-46", + "tx_ampdu_len:47-55", + "tx_ampdu_len:56-79", + "tx_ampdu_len:80-103", + "tx_ampdu_len:104-127", + "tx_ampdu_len:128-151", + "tx_ampdu_len:152-175", + "tx_ampdu_len:176-199", + "tx_ampdu_len:200-223", + "tx_ampdu_len:224-247", + "ba_miss_count", + "tx_beamformer_ppdu_iBF", + "tx_beamformer_ppdu_eBF", + "tx_beamformer_rx_feedback_all", + "tx_beamformer_rx_feedback_he", + "tx_beamformer_rx_feedback_vht", + "tx_beamformer_rx_feedback_ht", + "tx_msdu_pack_1", + "tx_msdu_pack_2", + "tx_msdu_pack_3", + "tx_msdu_pack_4", + "tx_msdu_pack_5", + "tx_msdu_pack_6", + "tx_msdu_pack_7", + "tx_msdu_pack_8", + /* rx counters */ + "rx_mpdu_cnt", + "rx_ampdu_cnt", + "rx_ampdu_bytes_cnt", + "rx_ba_cnt", + /* per vif counters */ + "v_tx_mode_cck", + "v_tx_mode_ofdm", + "v_tx_mode_ht", + "v_tx_mode_ht_gf", + "v_tx_mode_vht", + "v_tx_mode_he_su", + "v_tx_mode_he_ext_su", + "v_tx_mode_he_tb", + "v_tx_mode_he_mu", + "v_tx_mode_eht_su", + "v_tx_mode_eht_trig", + "v_tx_mode_eht_mu", + "v_tx_bw_20", + "v_tx_bw_40", + "v_tx_bw_80", + "v_tx_bw_160", + "v_tx_mcs_0", + "v_tx_mcs_1", + "v_tx_mcs_2", + "v_tx_mcs_3", + "v_tx_mcs_4", + "v_tx_mcs_5", + "v_tx_mcs_6", + "v_tx_mcs_7", + "v_tx_mcs_8", + "v_tx_mcs_9", + "v_tx_mcs_10", + "v_tx_mcs_11", + "v_tx_mcs_12", + "v_tx_mcs_13", + "v_tx_nss_1", + "v_tx_nss_2", + "v_tx_nss_3", + "v_tx_nss_4", +}; + +void mt792x_get_et_strings(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u32 sset, u8 *data) +{ + if (sset != ETH_SS_STATS) + return; + + memcpy(data, *mt792x_gstrings_stats, sizeof(mt792x_gstrings_stats)); + + data += sizeof(mt792x_gstrings_stats); + page_pool_ethtool_stats_get_strings(data); +} +EXPORT_SYMBOL_GPL(mt792x_get_et_strings); + +int mt792x_get_et_sset_count(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + int sset) +{ + if (sset != ETH_SS_STATS) + return 0; + + return ARRAY_SIZE(mt792x_gstrings_stats) + + page_pool_ethtool_stats_get_count(); +} +EXPORT_SYMBOL_GPL(mt792x_get_et_sset_count); + +static void +mt792x_ethtool_worker(void *wi_data, struct ieee80211_sta *sta) +{ + struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv; + struct mt76_ethtool_worker_info *wi = wi_data; + + if (msta->vif->mt76.idx != wi->idx) + return; + + mt76_ethtool_worker(wi, &msta->wcid.stats, true); +} + +void mt792x_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ethtool_stats *stats, u64 *data) +{ + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + int stats_size = ARRAY_SIZE(mt792x_gstrings_stats); + struct mt792x_phy *phy = mt792x_hw_phy(hw); + struct mt792x_dev *dev = phy->dev; + struct mt76_mib_stats *mib = &phy->mib; + struct mt76_ethtool_worker_info wi = { + .data = data, + .idx = mvif->mt76.idx, + }; + int i, ei = 0; + + mt792x_mutex_acquire(dev); + + mt792x_mac_update_mib_stats(phy); + + data[ei++] = mib->tx_ampdu_cnt; + data[ei++] = mib->tx_mpdu_attempts_cnt; + data[ei++] = mib->tx_mpdu_success_cnt; + data[ei++] = mib->tx_pkt_ebf_cnt; + data[ei++] = mib->tx_pkt_ibf_cnt; + + /* Tx ampdu stat */ + for (i = 0; i < 15; i++) + data[ei++] = phy->mt76->aggr_stats[i]; + + data[ei++] = phy->mib.ba_miss_cnt; + + /* Tx Beamformer monitor */ + data[ei++] = mib->tx_bf_ibf_ppdu_cnt; + data[ei++] = mib->tx_bf_ebf_ppdu_cnt; + + /* Tx Beamformer Rx feedback monitor */ + data[ei++] = mib->tx_bf_rx_fb_all_cnt; + data[ei++] = mib->tx_bf_rx_fb_he_cnt; + data[ei++] = mib->tx_bf_rx_fb_vht_cnt; + data[ei++] = mib->tx_bf_rx_fb_ht_cnt; + + /* Tx amsdu info (pack-count histogram) */ + for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++) + data[ei++] = mib->tx_amsdu[i]; + + /* rx counters */ + data[ei++] = mib->rx_mpdu_cnt; + data[ei++] = mib->rx_ampdu_cnt; + data[ei++] = mib->rx_ampdu_bytes_cnt; + data[ei++] = mib->rx_ba_cnt; + + /* Add values for all stations owned by this vif */ + wi.initial_stat_idx = ei; + ieee80211_iterate_stations_atomic(hw, mt792x_ethtool_worker, &wi); + + mt792x_mutex_release(dev); + + if (!wi.sta_count) + return; + + ei += wi.worker_stat_count; + + mt76_ethtool_page_pool_stats(&dev->mt76, &data[ei], &ei); + stats_size += page_pool_ethtool_stats_get_count(); + + if (ei != stats_size) + dev_err(dev->mt76.dev, "ei: %d SSTATS_LEN: %d", ei, + stats_size); +} +EXPORT_SYMBOL_GPL(mt792x_get_et_stats); + +void mt792x_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct station_info *sinfo) +{ + struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv; + struct rate_info *txrate = &msta->wcid.rate; + + if (!txrate->legacy && !txrate->flags) + return; + + if (txrate->legacy) { + sinfo->txrate.legacy = txrate->legacy; + } else { + sinfo->txrate.mcs = txrate->mcs; + sinfo->txrate.nss = txrate->nss; + sinfo->txrate.bw = txrate->bw; + sinfo->txrate.he_gi = txrate->he_gi; + sinfo->txrate.he_dcm = txrate->he_dcm; + sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc; + } + sinfo->tx_failed = msta->wcid.stats.tx_failed; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); + + sinfo->tx_retries = msta->wcid.stats.tx_retries; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); + + sinfo->txrate.flags = txrate->flags; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); + + sinfo->ack_signal = (s8)msta->ack_signal; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL); + + sinfo->avg_ack_signal = -(s8)ewma_avg_signal_read(&msta->avg_ack_signal); + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG); +} +EXPORT_SYMBOL_GPL(mt792x_sta_statistics); + +void mt792x_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) +{ + struct mt792x_phy *phy = mt792x_hw_phy(hw); + struct mt792x_dev *dev = phy->dev; + + mt792x_mutex_acquire(dev); + + phy->coverage_class = max_t(s16, coverage_class, 0); + mt792x_mac_set_timeing(phy); + + mt792x_mutex_release(dev); +} +EXPORT_SYMBOL_GPL(mt792x_set_coverage_class); + +int mt792x_init_wiphy(struct ieee80211_hw *hw) +{ + struct mt792x_phy *phy = mt792x_hw_phy(hw); + struct mt792x_dev *dev = phy->dev; + struct wiphy *wiphy = hw->wiphy; + + hw->queues = 4; + if (dev->has_eht) { + hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_EHT; + hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_EHT; + } else { + hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE; + hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE; + } + hw->netdev_features = NETIF_F_RXCSUM; + + hw->radiotap_timestamp.units_pos = + IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US; + + phy->slottime = 9; + + hw->sta_data_size = sizeof(struct mt792x_sta); + hw->vif_data_size = sizeof(struct mt792x_vif); + + if (dev->fw_features & MT792x_FW_CAP_CNM) { + wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; + wiphy->iface_combinations = if_comb_chanctx; + wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_chanctx); + } else { + wiphy->flags &= ~WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; + wiphy->iface_combinations = if_comb; + wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); + } + wiphy->flags &= ~(WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_4ADDR_AP | + WIPHY_FLAG_4ADDR_STATION); + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO); + wiphy->max_remain_on_channel_duration = 5000; + wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN; + wiphy->max_scan_ssids = 4; + wiphy->max_sched_scan_plan_interval = + MT76_CONNAC_MAX_TIME_SCHED_SCAN_INTERVAL; + wiphy->max_sched_scan_ie_len = IEEE80211_MAX_DATA_LEN; + wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID; + wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH; + wiphy->max_sched_scan_reqs = 1; + wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH | + WIPHY_FLAG_SPLIT_SCAN_6GHZ; + + wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR | + NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL); + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_LEGACY); + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT); + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT); + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE); + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); + + ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); + ieee80211_hw_set(hw, HAS_RATE_CONTROL); + ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD); + ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD); + ieee80211_hw_set(hw, WANT_MONITOR_VIF); + ieee80211_hw_set(hw, SUPPORTS_PS); + ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); + ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); + ieee80211_hw_set(hw, CONNECTION_MONITOR); + + if (dev->pm.enable) + ieee80211_hw_set(hw, CONNECTION_MONITOR); + + hw->max_tx_fragments = 4; + + return 0; +} +EXPORT_SYMBOL_GPL(mt792x_init_wiphy); + +static u8 +mt792x_get_offload_capability(struct device *dev, const char *fw_wm) +{ + const struct mt76_connac2_fw_trailer *hdr; + struct mt792x_realease_info *rel_info; + const struct firmware *fw; + int ret, i, offset = 0; + const u8 *data, *end; + u8 offload_caps = 0; + + ret = request_firmware(&fw, fw_wm, dev); + if (ret) + return ret; + + if (!fw || !fw->data || fw->size < sizeof(*hdr)) { + dev_err(dev, "Invalid firmware\n"); + goto out; + } + + data = fw->data; + hdr = (const void *)(fw->data + fw->size - sizeof(*hdr)); + + for (i = 0; i < hdr->n_region; i++) { + const struct mt76_connac2_fw_region *region; + + region = (const void *)((const u8 *)hdr - + (hdr->n_region - i) * sizeof(*region)); + offset += le32_to_cpu(region->len); + } + + data += offset + 16; + rel_info = (struct mt792x_realease_info *)data; + data += sizeof(*rel_info); + end = data + le16_to_cpu(rel_info->len); + + while (data < end) { + rel_info = (struct mt792x_realease_info *)data; + data += sizeof(*rel_info); + + if (rel_info->tag == MT792x_FW_TAG_FEATURE) { + struct mt792x_fw_features *features; + + features = (struct mt792x_fw_features *)data; + offload_caps = features->data; + break; + } + + data += le16_to_cpu(rel_info->len) + rel_info->pad_len; + } + +out: + release_firmware(fw); + + return offload_caps; +} + +struct ieee80211_ops * +mt792x_get_mac80211_ops(struct device *dev, + const struct ieee80211_ops *mac80211_ops, + void *drv_data, u8 *fw_features) +{ + struct ieee80211_ops *ops; + + ops = devm_kmemdup(dev, mac80211_ops, sizeof(struct ieee80211_ops), + GFP_KERNEL); + if (!ops) + return NULL; + + *fw_features = mt792x_get_offload_capability(dev, drv_data); + if (!(*fw_features & MT792x_FW_CAP_CNM)) { + ops->remain_on_channel = NULL; + ops->cancel_remain_on_channel = NULL; + ops->add_chanctx = NULL; + ops->remove_chanctx = NULL; + ops->change_chanctx = NULL; + ops->assign_vif_chanctx = NULL; + ops->unassign_vif_chanctx = NULL; + ops->mgd_prepare_tx = NULL; + ops->mgd_complete_tx = NULL; + } + return ops; +} +EXPORT_SYMBOL_GPL(mt792x_get_mac80211_ops); + +int mt792x_init_wcid(struct mt792x_dev *dev) +{ + int idx; + + /* Beacon and mgmt frames should occupy wcid 0 */ + idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT792x_WTBL_STA - 1); + if (idx) + return -ENOSPC; + + dev->mt76.global_wcid.idx = idx; + dev->mt76.global_wcid.hw_key_idx = -1; + dev->mt76.global_wcid.tx_info |= MT_WCID_TX_INFO_SET; + rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid); + + return 0; +} +EXPORT_SYMBOL_GPL(mt792x_init_wcid); + +int mt792x_mcu_drv_pmctrl(struct mt792x_dev *dev) +{ + struct mt76_phy *mphy = &dev->mt76.phy; + struct mt76_connac_pm *pm = &dev->pm; + int err = 0; + + mutex_lock(&pm->mutex); + + if (!test_bit(MT76_STATE_PM, &mphy->state)) + goto out; + + err = __mt792x_mcu_drv_pmctrl(dev); +out: + mutex_unlock(&pm->mutex); + + if (err) + mt792x_reset(&dev->mt76); + + return err; +} +EXPORT_SYMBOL_GPL(mt792x_mcu_drv_pmctrl); + +int mt792x_mcu_fw_pmctrl(struct mt792x_dev *dev) +{ + struct mt76_phy *mphy = &dev->mt76.phy; + struct mt76_connac_pm *pm = &dev->pm; + int err = 0; + + mutex_lock(&pm->mutex); + + if (mt76_connac_skip_fw_pmctrl(mphy, pm)) + goto out; + + err = __mt792x_mcu_fw_pmctrl(dev); +out: + mutex_unlock(&pm->mutex); + + if (err) + mt792x_reset(&dev->mt76); + + return err; +} +EXPORT_SYMBOL_GPL(mt792x_mcu_fw_pmctrl); + +int __mt792xe_mcu_drv_pmctrl(struct mt792x_dev *dev) +{ + int i, err = 0; + + for (i = 0; i < MT792x_DRV_OWN_RETRY_COUNT; i++) { + mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_CLR_OWN); + if (mt76_poll_msec_tick(dev, MT_CONN_ON_LPCTL, + PCIE_LPCR_HOST_OWN_SYNC, 0, 50, 1)) + break; + } + + if (i == MT792x_DRV_OWN_RETRY_COUNT) { + dev_err(dev->mt76.dev, "driver own failed\n"); + err = -EIO; + } + + return err; +} +EXPORT_SYMBOL_GPL(__mt792xe_mcu_drv_pmctrl); + +int mt792xe_mcu_drv_pmctrl(struct mt792x_dev *dev) +{ + struct mt76_phy *mphy = &dev->mt76.phy; + struct mt76_connac_pm *pm = &dev->pm; + int err; + + err = __mt792xe_mcu_drv_pmctrl(dev); + if (err < 0) + goto out; + + mt792x_wpdma_reinit_cond(dev); + clear_bit(MT76_STATE_PM, &mphy->state); + + pm->stats.last_wake_event = jiffies; + pm->stats.doze_time += pm->stats.last_wake_event - + pm->stats.last_doze_event; +out: + return err; +} +EXPORT_SYMBOL_GPL(mt792xe_mcu_drv_pmctrl); + +int mt792xe_mcu_fw_pmctrl(struct mt792x_dev *dev) +{ + struct mt76_phy *mphy = &dev->mt76.phy; + struct mt76_connac_pm *pm = &dev->pm; + int i; + + for (i = 0; i < MT792x_DRV_OWN_RETRY_COUNT; i++) { + mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_SET_OWN); + if (mt76_poll_msec_tick(dev, MT_CONN_ON_LPCTL, + PCIE_LPCR_HOST_OWN_SYNC, 4, 50, 1)) + break; + } + + if (i == MT792x_DRV_OWN_RETRY_COUNT) { + dev_err(dev->mt76.dev, "firmware own failed\n"); + clear_bit(MT76_STATE_PM, &mphy->state); + return -EIO; + } + + pm->stats.last_doze_event = jiffies; + pm->stats.awake_time += pm->stats.last_doze_event - + pm->stats.last_wake_event; + + return 0; +} +EXPORT_SYMBOL_GPL(mt792xe_mcu_fw_pmctrl); + +int mt792x_load_firmware(struct mt792x_dev *dev) +{ + int ret; + + ret = mt76_connac2_load_patch(&dev->mt76, mt792x_patch_name(dev)); + if (ret) + return ret; + + if (mt76_is_sdio(&dev->mt76)) { + /* activate again */ + ret = __mt792x_mcu_fw_pmctrl(dev); + if (!ret) + ret = __mt792x_mcu_drv_pmctrl(dev); + } + + ret = mt76_connac2_load_ram(&dev->mt76, mt792x_ram_name(dev), NULL); + if (ret) + return ret; + + if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY, + MT_TOP_MISC2_FW_N9_RDY, 1500)) { + dev_err(dev->mt76.dev, "Timeout for initializing firmware\n"); + + return -EIO; + } + +#ifdef CONFIG_PM + dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support; +#endif /* CONFIG_PM */ + + dev_dbg(dev->mt76.dev, "Firmware init done\n"); + + return 0; +} +EXPORT_SYMBOL_GPL(mt792x_load_firmware); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_debugfs.c b/drivers/net/wireless/mediatek/mt76/mt792x_debugfs.c new file mode 100644 index 000000000000..9858d9a93851 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt792x_debugfs.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2023 MediaTek Inc. */ + +#include "mt792x.h" + +static void +mt792x_ampdu_stat_read_phy(struct mt792x_phy *phy, + struct seq_file *file) +{ + struct mt792x_dev *dev = file->private; + int bound[15], range[4], i; + + if (!phy) + return; + + mt792x_mac_update_mib_stats(phy); + + /* Tx ampdu stat */ + for (i = 0; i < ARRAY_SIZE(range); i++) + range[i] = mt76_rr(dev, MT_MIB_ARNG(0, i)); + + for (i = 0; i < ARRAY_SIZE(bound); i++) + bound[i] = MT_MIB_ARNCR_RANGE(range[i / 4], i % 4) + 1; + + seq_puts(file, "\nPhy0\n"); + + seq_printf(file, "Length: %8d | ", bound[0]); + for (i = 0; i < ARRAY_SIZE(bound) - 1; i++) + seq_printf(file, "%3d %3d | ", bound[i] + 1, bound[i + 1]); + + seq_puts(file, "\nCount: "); + for (i = 0; i < ARRAY_SIZE(bound); i++) + seq_printf(file, "%8d | ", phy->mt76->aggr_stats[i]); + seq_puts(file, "\n"); + + seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt); +} + +int mt792x_tx_stats_show(struct seq_file *file, void *data) +{ + struct mt792x_dev *dev = file->private; + struct mt792x_phy *phy = &dev->phy; + struct mt76_mib_stats *mib = &phy->mib; + int i; + + mt792x_mutex_acquire(dev); + + mt792x_ampdu_stat_read_phy(phy, file); + + seq_puts(file, "Tx MSDU stat:\n"); + for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++) { + seq_printf(file, "AMSDU pack count of %d MSDU in TXD: %8d ", + i + 1, mib->tx_amsdu[i]); + if (mib->tx_amsdu_cnt) + seq_printf(file, "(%3d%%)\n", + mib->tx_amsdu[i] * 100 / mib->tx_amsdu_cnt); + else + seq_puts(file, "\n"); + } + + mt792x_mutex_release(dev); + + return 0; +} +EXPORT_SYMBOL_GPL(mt792x_tx_stats_show); + +int mt792x_queues_acq(struct seq_file *s, void *data) +{ + struct mt792x_dev *dev = dev_get_drvdata(s->private); + int i; + + mt792x_mutex_acquire(dev); + + for (i = 0; i < 4; i++) { + u32 ctrl, val, qlen = 0; + int j; + + val = mt76_rr(dev, MT_PLE_AC_QEMPTY(i)); + ctrl = BIT(31) | BIT(11) | (i << 24); + + for (j = 0; j < 32; j++) { + if (val & BIT(j)) + continue; + + mt76_wr(dev, MT_PLE_FL_Q0_CTRL, ctrl | j); + qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL, + GENMASK(11, 0)); + } + seq_printf(s, "AC%d: queued=%d\n", i, qlen); + } + + mt792x_mutex_release(dev); + + return 0; +} +EXPORT_SYMBOL_GPL(mt792x_queues_acq); + +int mt792x_queues_read(struct seq_file *s, void *data) +{ + struct mt792x_dev *dev = dev_get_drvdata(s->private); + struct { + struct mt76_queue *q; + char *queue; + } queue_map[] = { + { dev->mphy.q_tx[MT_TXQ_BE], "WFDMA0" }, + { dev->mt76.q_mcu[MT_MCUQ_WM], "MCUWM" }, + { dev->mt76.q_mcu[MT_MCUQ_FWDL], "MCUFWQ" }, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(queue_map); i++) { + struct mt76_queue *q = queue_map[i].q; + + if (!q) + continue; + + seq_printf(s, + "%s: queued=%d head=%d tail=%d\n", + queue_map[i].queue, q->queued, q->head, + q->tail); + } + + return 0; +} +EXPORT_SYMBOL_GPL(mt792x_queues_read); + +int mt792x_pm_stats(struct seq_file *s, void *data) +{ + struct mt792x_dev *dev = dev_get_drvdata(s->private); + struct mt76_connac_pm *pm = &dev->pm; + + unsigned long awake_time = pm->stats.awake_time; + unsigned long doze_time = pm->stats.doze_time; + + if (!test_bit(MT76_STATE_PM, &dev->mphy.state)) + awake_time += jiffies - pm->stats.last_wake_event; + else + doze_time += jiffies - pm->stats.last_doze_event; + + seq_printf(s, "awake time: %14u\ndoze time: %15u\n", + jiffies_to_msecs(awake_time), + jiffies_to_msecs(doze_time)); + + seq_printf(s, "low power wakes: %9d\n", pm->stats.lp_wake); + + return 0; +} +EXPORT_SYMBOL_GPL(mt792x_pm_stats); + +int mt792x_pm_idle_timeout_set(void *data, u64 val) +{ + struct mt792x_dev *dev = data; + + dev->pm.idle_timeout = msecs_to_jiffies(val); + + return 0; +} +EXPORT_SYMBOL_GPL(mt792x_pm_idle_timeout_set); + +int mt792x_pm_idle_timeout_get(void *data, u64 *val) +{ + struct mt792x_dev *dev = data; + + *val = jiffies_to_msecs(dev->pm.idle_timeout); + + return 0; +} +EXPORT_SYMBOL_GPL(mt792x_pm_idle_timeout_get); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c index 4153cd6c2a01..a3dbd3865b2f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c @@ -1,52 +1,93 @@ // SPDX-License-Identifier: ISC -/* Copyright (C) 2020 MediaTek Inc. */ +/* Copyright (C) 2023 MediaTek Inc. */ -#include "mt7921.h" -#include "../dma.h" -#include "../mt76_connac2_mac.h" +#include <linux/module.h> +#include <linux/firmware.h> -static int mt7921_poll_tx(struct napi_struct *napi, int budget) +#include "mt792x.h" +#include "dma.h" +#include "trace.h" + +irqreturn_t mt792x_irq_handler(int irq, void *dev_instance) { - struct mt7921_dev *dev; + struct mt792x_dev *dev = dev_instance; - dev = container_of(napi, struct mt7921_dev, mt76.tx_napi); + mt76_wr(dev, dev->irq_map->host_irq_enable, 0); - if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) { - napi_complete(napi); - queue_work(dev->mt76.wq, &dev->pm.wake_work); - return 0; - } + if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state)) + return IRQ_NONE; - mt76_connac_tx_cleanup(&dev->mt76); - if (napi_complete(napi)) - mt76_connac_irq_enable(&dev->mt76, MT_INT_TX_DONE_ALL); - mt76_connac_pm_unref(&dev->mphy, &dev->pm); + tasklet_schedule(&dev->mt76.irq_tasklet); - return 0; + return IRQ_HANDLED; } +EXPORT_SYMBOL_GPL(mt792x_irq_handler); -static int mt7921_poll_rx(struct napi_struct *napi, int budget) +void mt792x_irq_tasklet(unsigned long data) { - struct mt7921_dev *dev; - int done; + struct mt792x_dev *dev = (struct mt792x_dev *)data; + const struct mt792x_irq_map *irq_map = dev->irq_map; + u32 intr, mask = 0; - dev = container_of(napi->dev, struct mt7921_dev, mt76.napi_dev); + mt76_wr(dev, irq_map->host_irq_enable, 0); - if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) { - napi_complete(napi); - queue_work(dev->mt76.wq, &dev->pm.wake_work); - return 0; + intr = mt76_rr(dev, MT_WFDMA0_HOST_INT_STA); + intr &= dev->mt76.mmio.irqmask; + mt76_wr(dev, MT_WFDMA0_HOST_INT_STA, intr); + + trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask); + + mask |= intr & (irq_map->rx.data_complete_mask | + irq_map->rx.wm_complete_mask | + irq_map->rx.wm2_complete_mask); + if (intr & dev->irq_map->tx.mcu_complete_mask) + mask |= dev->irq_map->tx.mcu_complete_mask; + + if (intr & MT_INT_MCU_CMD) { + u32 intr_sw; + + intr_sw = mt76_rr(dev, MT_MCU_CMD); + /* ack MCU2HOST_SW_INT_STA */ + mt76_wr(dev, MT_MCU_CMD, intr_sw); + if (intr_sw & MT_MCU_CMD_WAKE_RX_PCIE) { + mask |= irq_map->rx.data_complete_mask; + intr |= irq_map->rx.data_complete_mask; + } } - done = mt76_dma_rx_poll(napi, budget); - mt76_connac_pm_unref(&dev->mphy, &dev->pm); - return done; + mt76_set_irq_mask(&dev->mt76, irq_map->host_irq_enable, mask, 0); + + if (intr & dev->irq_map->tx.all_complete_mask) + napi_schedule(&dev->mt76.tx_napi); + + if (intr & irq_map->rx.wm_complete_mask) + napi_schedule(&dev->mt76.napi[MT_RXQ_MCU]); + + if (intr & irq_map->rx.wm2_complete_mask) + napi_schedule(&dev->mt76.napi[MT_RXQ_MCU_WA]); + + if (intr & irq_map->rx.data_complete_mask) + napi_schedule(&dev->mt76.napi[MT_RXQ_MAIN]); } +EXPORT_SYMBOL_GPL(mt792x_irq_tasklet); -static void mt7921_dma_prefetch(struct mt7921_dev *dev) +void mt792x_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q) { -#define PREFETCH(base, depth) ((base) << 16 | (depth)) + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); + const struct mt792x_irq_map *irq_map = dev->irq_map; + + if (q == MT_RXQ_MAIN) + mt76_connac_irq_enable(mdev, irq_map->rx.data_complete_mask); + else if (q == MT_RXQ_MCU_WA) + mt76_connac_irq_enable(mdev, irq_map->rx.wm2_complete_mask); + else + mt76_connac_irq_enable(mdev, irq_map->rx.wm_complete_mask); +} +EXPORT_SYMBOL_GPL(mt792x_rx_poll_complete); +#define PREFETCH(base, depth) ((base) << 16 | (depth)) +static void mt792x_dma_prefetch(struct mt792x_dev *dev) +{ mt76_wr(dev, MT_WFDMA0_RX_RING0_EXT_CTRL, PREFETCH(0x0, 0x4)); mt76_wr(dev, MT_WFDMA0_RX_RING2_EXT_CTRL, PREFETCH(0x40, 0x4)); mt76_wr(dev, MT_WFDMA0_RX_RING3_EXT_CTRL, PREFETCH(0x80, 0x4)); @@ -64,44 +105,10 @@ static void mt7921_dma_prefetch(struct mt7921_dev *dev) mt76_wr(dev, MT_WFDMA0_TX_RING17_EXT_CTRL, PREFETCH(0x380, 0x4)); } -static int mt7921_dma_disable(struct mt7921_dev *dev, bool force) -{ - /* disable WFDMA0 */ - mt76_clear(dev, MT_WFDMA0_GLO_CFG, - MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN | - MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN | - MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | - MT_WFDMA0_GLO_CFG_OMIT_RX_INFO | - MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); - - if (!mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG, - MT_WFDMA0_GLO_CFG_TX_DMA_BUSY | - MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1)) - return -ETIMEDOUT; - - /* disable dmashdl */ - mt76_clear(dev, MT_WFDMA0_GLO_CFG_EXT0, - MT_WFDMA0_CSR_TX_DMASHDL_ENABLE); - mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS); - - if (force) { - /* reset */ - mt76_clear(dev, MT_WFDMA0_RST, - MT_WFDMA0_RST_DMASHDL_ALL_RST | - MT_WFDMA0_RST_LOGIC_RST); - - mt76_set(dev, MT_WFDMA0_RST, - MT_WFDMA0_RST_DMASHDL_ALL_RST | - MT_WFDMA0_RST_LOGIC_RST); - } - - return 0; -} - -static int mt7921_dma_enable(struct mt7921_dev *dev) +int mt792x_dma_enable(struct mt792x_dev *dev) { /* configure perfetch settings */ - mt7921_dma_prefetch(dev); + mt792x_dma_prefetch(dev); /* reset dma idx */ mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0); @@ -124,18 +131,23 @@ static int mt7921_dma_enable(struct mt7921_dev *dev) /* enable interrupts for TX/RX rings */ mt76_connac_irq_enable(&dev->mt76, - MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL | + dev->irq_map->tx.all_complete_mask | + dev->irq_map->rx.data_complete_mask | + dev->irq_map->rx.wm2_complete_mask | + dev->irq_map->rx.wm_complete_mask | MT_INT_MCU_CMD); mt76_set(dev, MT_MCU2HOST_SW_INT_ENA, MT_MCU_CMD_WAKE_RX_PCIE); return 0; } +EXPORT_SYMBOL_GPL(mt792x_dma_enable); -static int mt7921_dma_reset(struct mt7921_dev *dev, bool force) +static int +mt792x_dma_reset(struct mt792x_dev *dev, bool force) { int i, err; - err = mt7921_dma_disable(dev, force); + err = mt792x_dma_disable(dev, force); if (err) return err; @@ -151,23 +163,10 @@ static int mt7921_dma_reset(struct mt7921_dev *dev, bool force) mt76_tx_status_check(&dev->mt76, true); - return mt7921_dma_enable(dev); -} - -int mt7921_wfsys_reset(struct mt7921_dev *dev) -{ - mt76_clear(dev, MT_WFSYS_SW_RST_B, WFSYS_SW_RST_B); - msleep(50); - mt76_set(dev, MT_WFSYS_SW_RST_B, WFSYS_SW_RST_B); - - if (!__mt76_poll_msec(&dev->mt76, MT_WFSYS_SW_RST_B, - WFSYS_SW_INIT_DONE, WFSYS_SW_INIT_DONE, 500)) - return -ETIMEDOUT; - - return 0; + return mt792x_dma_enable(dev); } -int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force) +int mt792x_wpdma_reset(struct mt792x_dev *dev, bool force) { int i, err; @@ -182,11 +181,11 @@ int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force) mt76_queue_rx_cleanup(dev, &dev->mt76.q_rx[i]); if (force) { - err = mt7921_wfsys_reset(dev); + err = mt792x_wfsys_reset(dev); if (err) return err; } - err = mt7921_dma_reset(dev, force); + err = mt792x_dma_reset(dev, force); if (err) return err; @@ -195,19 +194,20 @@ int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force) return 0; } +EXPORT_SYMBOL_GPL(mt792x_wpdma_reset); -int mt7921_wpdma_reinit_cond(struct mt7921_dev *dev) +int mt792x_wpdma_reinit_cond(struct mt792x_dev *dev) { struct mt76_connac_pm *pm = &dev->pm; int err; /* check if the wpdma must be reinitialized */ - if (mt7921_dma_need_reinit(dev)) { + if (mt792x_dma_need_reinit(dev)) { /* disable interrutpts */ - mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0); + mt76_wr(dev, dev->irq_map->host_irq_enable, 0); mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0); - err = mt7921_wpdma_reset(dev, false); + err = mt792x_wpdma_reset(dev, false); if (err) { dev_err(dev->mt76.dev, "wpdma reset failed\n"); return err; @@ -220,73 +220,44 @@ int mt7921_wpdma_reinit_cond(struct mt7921_dev *dev) return 0; } +EXPORT_SYMBOL_GPL(mt792x_wpdma_reinit_cond); -int mt7921_dma_init(struct mt7921_dev *dev) +int mt792x_dma_disable(struct mt792x_dev *dev, bool force) { - int ret; - - mt76_dma_attach(&dev->mt76); - - ret = mt7921_dma_disable(dev, true); - if (ret) - return ret; - - /* init tx queue */ - ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7921_TXQ_BAND0, - MT7921_TX_RING_SIZE, - MT_TX_RING_BASE, 0); - if (ret) - return ret; - - mt76_wr(dev, MT_WFDMA0_TX_RING0_EXT_CTRL, 0x4); - - /* command to WM */ - ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT7921_TXQ_MCU_WM, - MT7921_TX_MCU_RING_SIZE, MT_TX_RING_BASE); - if (ret) - return ret; - - /* firmware download */ - ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL, MT7921_TXQ_FWDL, - MT7921_TX_FWDL_RING_SIZE, MT_TX_RING_BASE); - if (ret) - return ret; - - /* event from WM before firmware download */ - ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU], - MT7921_RXQ_MCU_WM, - MT7921_RX_MCU_RING_SIZE, - MT_RX_BUF_SIZE, MT_RX_EVENT_RING_BASE); - if (ret) - return ret; - - /* Change mcu queue after firmware download */ - ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA], - MT7921_RXQ_MCU_WM, - MT7921_RX_MCU_RING_SIZE, - MT_RX_BUF_SIZE, MT_WFDMA0(0x540)); - if (ret) - return ret; - - /* rx data */ - ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], - MT7921_RXQ_BAND0, MT7921_RX_RING_SIZE, - MT_RX_BUF_SIZE, MT_RX_DATA_RING_BASE); - if (ret) - return ret; - - ret = mt76_init_queues(dev, mt7921_poll_rx); - if (ret < 0) - return ret; - - netif_napi_add_tx(&dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, - mt7921_poll_tx); - napi_enable(&dev->mt76.tx_napi); - - return mt7921_dma_enable(dev); + /* disable WFDMA0 */ + mt76_clear(dev, MT_WFDMA0_GLO_CFG, + MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN | + MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN | + MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | + MT_WFDMA0_GLO_CFG_OMIT_RX_INFO | + MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); + + if (!mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG, + MT_WFDMA0_GLO_CFG_TX_DMA_BUSY | + MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1)) + return -ETIMEDOUT; + + /* disable dmashdl */ + mt76_clear(dev, MT_WFDMA0_GLO_CFG_EXT0, + MT_WFDMA0_CSR_TX_DMASHDL_ENABLE); + mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS); + + if (force) { + /* reset */ + mt76_clear(dev, MT_WFDMA0_RST, + MT_WFDMA0_RST_DMASHDL_ALL_RST | + MT_WFDMA0_RST_LOGIC_RST); + + mt76_set(dev, MT_WFDMA0_RST, + MT_WFDMA0_RST_DMASHDL_ALL_RST | + MT_WFDMA0_RST_LOGIC_RST); + } + + return 0; } +EXPORT_SYMBOL_GPL(mt792x_dma_disable); -void mt7921_dma_cleanup(struct mt7921_dev *dev) +void mt792x_dma_cleanup(struct mt792x_dev *dev) { /* disable */ mt76_clear(dev, MT_WFDMA0_GLO_CFG, @@ -312,3 +283,62 @@ void mt7921_dma_cleanup(struct mt7921_dev *dev) mt76_dma_cleanup(&dev->mt76); } +EXPORT_SYMBOL_GPL(mt792x_dma_cleanup); + +int mt792x_poll_tx(struct napi_struct *napi, int budget) +{ + struct mt792x_dev *dev; + + dev = container_of(napi, struct mt792x_dev, mt76.tx_napi); + + if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) { + napi_complete(napi); + queue_work(dev->mt76.wq, &dev->pm.wake_work); + return 0; + } + + mt76_connac_tx_cleanup(&dev->mt76); + if (napi_complete(napi)) + mt76_connac_irq_enable(&dev->mt76, + dev->irq_map->tx.all_complete_mask); + mt76_connac_pm_unref(&dev->mphy, &dev->pm); + + return 0; +} +EXPORT_SYMBOL_GPL(mt792x_poll_tx); + +int mt792x_poll_rx(struct napi_struct *napi, int budget) +{ + struct mt792x_dev *dev; + int done; + + dev = container_of(napi->dev, struct mt792x_dev, mt76.napi_dev); + + if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) { + napi_complete(napi); + queue_work(dev->mt76.wq, &dev->pm.wake_work); + return 0; + } + done = mt76_dma_rx_poll(napi, budget); + mt76_connac_pm_unref(&dev->mphy, &dev->pm); + + return done; +} +EXPORT_SYMBOL_GPL(mt792x_poll_rx); + +int mt792x_wfsys_reset(struct mt792x_dev *dev) +{ + u32 addr = is_mt7921(&dev->mt76) ? 0x18000140 : 0x7c000140; + + mt76_clear(dev, addr, WFSYS_SW_RST_B); + msleep(50); + mt76_set(dev, addr, WFSYS_SW_RST_B); + + if (!__mt76_poll_msec(&dev->mt76, addr, WFSYS_SW_INIT_DONE, + WFSYS_SW_INIT_DONE, 500)) + return -ETIMEDOUT; + + return 0; +} +EXPORT_SYMBOL_GPL(mt792x_wfsys_reset); + diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_mac.c b/drivers/net/wireless/mediatek/mt76/mt792x_mac.c new file mode 100644 index 000000000000..5d1f8229fdc1 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt792x_mac.c @@ -0,0 +1,385 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2023 MediaTek Inc. */ + +#include <linux/module.h> + +#include "mt792x.h" +#include "mt792x_regs.h" + +void mt792x_mac_work(struct work_struct *work) +{ + struct mt792x_phy *phy; + struct mt76_phy *mphy; + + mphy = (struct mt76_phy *)container_of(work, struct mt76_phy, + mac_work.work); + phy = mphy->priv; + + mt792x_mutex_acquire(phy->dev); + + mt76_update_survey(mphy); + if (++mphy->mac_work_count == 2) { + mphy->mac_work_count = 0; + + mt792x_mac_update_mib_stats(phy); + } + + mt792x_mutex_release(phy->dev); + + mt76_tx_status_check(mphy->dev, false); + ieee80211_queue_delayed_work(phy->mt76->hw, &mphy->mac_work, + MT792x_WATCHDOG_TIME); +} +EXPORT_SYMBOL_GPL(mt792x_mac_work); + +void mt792x_mac_set_timeing(struct mt792x_phy *phy) +{ + s16 coverage_class = phy->coverage_class; + struct mt792x_dev *dev = phy->dev; + u32 val, reg_offset; + u32 cck = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 231) | + FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48); + u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) | + FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28); + bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ; + int sifs = is_2ghz ? 10 : 16, offset; + + if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state)) + return; + + mt76_set(dev, MT_ARB_SCR(0), + MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE); + udelay(1); + + offset = 3 * coverage_class; + reg_offset = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, offset) | + FIELD_PREP(MT_TIMEOUT_VAL_CCA, offset); + + mt76_wr(dev, MT_TMAC_CDTR(0), cck + reg_offset); + mt76_wr(dev, MT_TMAC_ODTR(0), ofdm + reg_offset); + mt76_wr(dev, MT_TMAC_ICR0(0), + FIELD_PREP(MT_IFS_EIFS, 360) | + FIELD_PREP(MT_IFS_RIFS, 2) | + FIELD_PREP(MT_IFS_SIFS, sifs) | + FIELD_PREP(MT_IFS_SLOT, phy->slottime)); + + if (phy->slottime < 20 || !is_2ghz) + val = MT792x_CFEND_RATE_DEFAULT; + else + val = MT792x_CFEND_RATE_11B; + + mt76_rmw_field(dev, MT_AGG_ACR0(0), MT_AGG_ACR_CFEND_RATE, val); + mt76_clear(dev, MT_ARB_SCR(0), + MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE); +} +EXPORT_SYMBOL_GPL(mt792x_mac_set_timeing); + +void mt792x_mac_update_mib_stats(struct mt792x_phy *phy) +{ + struct mt76_mib_stats *mib = &phy->mib; + struct mt792x_dev *dev = phy->dev; + int i, aggr0 = 0, aggr1; + u32 val; + + mib->fcs_err_cnt += mt76_get_field(dev, MT_MIB_SDR3(0), + MT_MIB_SDR3_FCS_ERR_MASK); + mib->ack_fail_cnt += mt76_get_field(dev, MT_MIB_MB_BSDR3(0), + MT_MIB_ACK_FAIL_COUNT_MASK); + mib->ba_miss_cnt += mt76_get_field(dev, MT_MIB_MB_BSDR2(0), + MT_MIB_BA_FAIL_COUNT_MASK); + mib->rts_cnt += mt76_get_field(dev, MT_MIB_MB_BSDR0(0), + MT_MIB_RTS_COUNT_MASK); + mib->rts_retries_cnt += mt76_get_field(dev, MT_MIB_MB_BSDR1(0), + MT_MIB_RTS_FAIL_COUNT_MASK); + + mib->tx_ampdu_cnt += mt76_rr(dev, MT_MIB_SDR12(0)); + mib->tx_mpdu_attempts_cnt += mt76_rr(dev, MT_MIB_SDR14(0)); + mib->tx_mpdu_success_cnt += mt76_rr(dev, MT_MIB_SDR15(0)); + + val = mt76_rr(dev, MT_MIB_SDR32(0)); + mib->tx_pkt_ebf_cnt += FIELD_GET(MT_MIB_SDR9_EBF_CNT_MASK, val); + mib->tx_pkt_ibf_cnt += FIELD_GET(MT_MIB_SDR9_IBF_CNT_MASK, val); + + val = mt76_rr(dev, MT_ETBF_TX_APP_CNT(0)); + mib->tx_bf_ibf_ppdu_cnt += FIELD_GET(MT_ETBF_TX_IBF_CNT, val); + mib->tx_bf_ebf_ppdu_cnt += FIELD_GET(MT_ETBF_TX_EBF_CNT, val); + + val = mt76_rr(dev, MT_ETBF_RX_FB_CNT(0)); + mib->tx_bf_rx_fb_all_cnt += FIELD_GET(MT_ETBF_RX_FB_ALL, val); + mib->tx_bf_rx_fb_he_cnt += FIELD_GET(MT_ETBF_RX_FB_HE, val); + mib->tx_bf_rx_fb_vht_cnt += FIELD_GET(MT_ETBF_RX_FB_VHT, val); + mib->tx_bf_rx_fb_ht_cnt += FIELD_GET(MT_ETBF_RX_FB_HT, val); + + mib->rx_mpdu_cnt += mt76_rr(dev, MT_MIB_SDR5(0)); + mib->rx_ampdu_cnt += mt76_rr(dev, MT_MIB_SDR22(0)); + mib->rx_ampdu_bytes_cnt += mt76_rr(dev, MT_MIB_SDR23(0)); + mib->rx_ba_cnt += mt76_rr(dev, MT_MIB_SDR31(0)); + + for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++) { + val = mt76_rr(dev, MT_PLE_AMSDU_PACK_MSDU_CNT(i)); + mib->tx_amsdu[i] += val; + mib->tx_amsdu_cnt += val; + } + + for (i = 0, aggr1 = aggr0 + 8; i < 4; i++) { + u32 val2; + + val = mt76_rr(dev, MT_TX_AGG_CNT(0, i)); + val2 = mt76_rr(dev, MT_TX_AGG_CNT2(0, i)); + + phy->mt76->aggr_stats[aggr0++] += val & 0xffff; + phy->mt76->aggr_stats[aggr0++] += val >> 16; + phy->mt76->aggr_stats[aggr1++] += val2 & 0xffff; + phy->mt76->aggr_stats[aggr1++] += val2 >> 16; + } +} +EXPORT_SYMBOL_GPL(mt792x_mac_update_mib_stats); + +struct mt76_wcid *mt792x_rx_get_wcid(struct mt792x_dev *dev, u16 idx, + bool unicast) +{ + struct mt792x_sta *sta; + struct mt76_wcid *wcid; + + if (idx >= ARRAY_SIZE(dev->mt76.wcid)) + return NULL; + + wcid = rcu_dereference(dev->mt76.wcid[idx]); + if (unicast || !wcid) + return wcid; + + if (!wcid->sta) + return NULL; + + sta = container_of(wcid, struct mt792x_sta, wcid); + if (!sta->vif) + return NULL; + + return &sta->vif->sta.wcid; +} +EXPORT_SYMBOL_GPL(mt792x_rx_get_wcid); + +static void +mt792x_mac_rssi_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) +{ + struct sk_buff *skb = priv; + struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; + struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv; + struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb); + + if (status->signal > 0) + return; + + if (!ether_addr_equal(vif->addr, hdr->addr1)) + return; + + ewma_rssi_add(&mvif->rssi, -status->signal); +} + +void mt792x_mac_assoc_rssi(struct mt792x_dev *dev, struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb); + + if (!ieee80211_is_assoc_resp(hdr->frame_control) && + !ieee80211_is_auth(hdr->frame_control)) + return; + + ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev), + IEEE80211_IFACE_ITER_RESUME_ALL, + mt792x_mac_rssi_iter, skb); +} +EXPORT_SYMBOL_GPL(mt792x_mac_assoc_rssi); + +void mt792x_mac_reset_counters(struct mt792x_phy *phy) +{ + struct mt792x_dev *dev = phy->dev; + int i; + + for (i = 0; i < 4; i++) { + mt76_rr(dev, MT_TX_AGG_CNT(0, i)); + mt76_rr(dev, MT_TX_AGG_CNT2(0, i)); + } + + dev->mt76.phy.survey_time = ktime_get_boottime(); + memset(phy->mt76->aggr_stats, 0, sizeof(phy->mt76->aggr_stats)); + + /* reset airtime counters */ + mt76_rr(dev, MT_MIB_SDR9(0)); + mt76_rr(dev, MT_MIB_SDR36(0)); + mt76_rr(dev, MT_MIB_SDR37(0)); + + mt76_set(dev, MT_WF_RMAC_MIB_TIME0(0), MT_WF_RMAC_MIB_RXTIME_CLR); + mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(0), MT_WF_RMAC_MIB_RXTIME_CLR); +} +EXPORT_SYMBOL_GPL(mt792x_mac_reset_counters); + +static u8 +mt792x_phy_get_nf(struct mt792x_phy *phy, int idx) +{ + return 0; +} + +static void +mt792x_phy_update_channel(struct mt76_phy *mphy, int idx) +{ + struct mt792x_dev *dev = container_of(mphy->dev, struct mt792x_dev, mt76); + struct mt792x_phy *phy = (struct mt792x_phy *)mphy->priv; + struct mt76_channel_state *state; + u64 busy_time, tx_time, rx_time, obss_time; + int nf; + + busy_time = mt76_get_field(dev, MT_MIB_SDR9(idx), + MT_MIB_SDR9_BUSY_MASK); + tx_time = mt76_get_field(dev, MT_MIB_SDR36(idx), + MT_MIB_SDR36_TXTIME_MASK); + rx_time = mt76_get_field(dev, MT_MIB_SDR37(idx), + MT_MIB_SDR37_RXTIME_MASK); + obss_time = mt76_get_field(dev, MT_WF_RMAC_MIB_AIRTIME14(idx), + MT_MIB_OBSSTIME_MASK); + + nf = mt792x_phy_get_nf(phy, idx); + if (!phy->noise) + phy->noise = nf << 4; + else if (nf) + phy->noise += nf - (phy->noise >> 4); + + state = mphy->chan_state; + state->cc_busy += busy_time; + state->cc_tx += tx_time; + state->cc_rx += rx_time + obss_time; + state->cc_bss_rx += rx_time; + state->noise = -(phy->noise >> 4); +} + +void mt792x_update_channel(struct mt76_phy *mphy) +{ + struct mt792x_dev *dev = container_of(mphy->dev, struct mt792x_dev, mt76); + + if (mt76_connac_pm_wake(mphy, &dev->pm)) + return; + + mt792x_phy_update_channel(mphy, 0); + /* reset obss airtime */ + mt76_set(dev, MT_WF_RMAC_MIB_TIME0(0), MT_WF_RMAC_MIB_RXTIME_CLR); + mt76_connac_power_save_sched(mphy, &dev->pm); +} +EXPORT_SYMBOL_GPL(mt792x_update_channel); + +void mt792x_reset(struct mt76_dev *mdev) +{ + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); + struct mt76_connac_pm *pm = &dev->pm; + + if (!dev->hw_init_done) + return; + + if (dev->hw_full_reset) + return; + + if (pm->suspended) + return; + + queue_work(dev->mt76.wq, &dev->reset_work); +} +EXPORT_SYMBOL_GPL(mt792x_reset); + +void mt792x_mac_init_band(struct mt792x_dev *dev, u8 band) +{ + u32 mask, set; + + mt76_rmw_field(dev, MT_TMAC_CTCR0(band), + MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f); + mt76_set(dev, MT_TMAC_CTCR0(band), + MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN | + MT_TMAC_CTCR0_INS_DDLMT_EN); + + mt76_set(dev, MT_WF_RMAC_MIB_TIME0(band), MT_WF_RMAC_MIB_RXTIME_EN); + mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(band), MT_WF_RMAC_MIB_RXTIME_EN); + + /* enable MIB tx-rx time reporting */ + mt76_set(dev, MT_MIB_SCR1(band), MT_MIB_TXDUR_EN); + mt76_set(dev, MT_MIB_SCR1(band), MT_MIB_RXDUR_EN); + + mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_MAX_RX_LEN, 1536); + /* disable rx rate report by default due to hw issues */ + mt76_clear(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN); + + /* filter out non-resp frames and get instantaneous signal reporting */ + mask = MT_WTBLOFF_TOP_RSCR_RCPI_MODE | MT_WTBLOFF_TOP_RSCR_RCPI_PARAM; + set = FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_MODE, 0) | + FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_PARAM, 0x3); + mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set); +} +EXPORT_SYMBOL_GPL(mt792x_mac_init_band); + +void mt792x_pm_wake_work(struct work_struct *work) +{ + struct mt792x_dev *dev; + struct mt76_phy *mphy; + + dev = (struct mt792x_dev *)container_of(work, struct mt792x_dev, + pm.wake_work); + mphy = dev->phy.mt76; + + if (!mt792x_mcu_drv_pmctrl(dev)) { + struct mt76_dev *mdev = &dev->mt76; + int i; + + if (mt76_is_sdio(mdev)) { + mt76_connac_pm_dequeue_skbs(mphy, &dev->pm); + mt76_worker_schedule(&mdev->sdio.txrx_worker); + } else { + local_bh_disable(); + mt76_for_each_q_rx(mdev, i) + napi_schedule(&mdev->napi[i]); + local_bh_enable(); + mt76_connac_pm_dequeue_skbs(mphy, &dev->pm); + mt76_connac_tx_cleanup(mdev); + } + if (test_bit(MT76_STATE_RUNNING, &mphy->state)) + ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work, + MT792x_WATCHDOG_TIME); + } + + ieee80211_wake_queues(mphy->hw); + wake_up(&dev->pm.wait); +} +EXPORT_SYMBOL_GPL(mt792x_pm_wake_work); + +void mt792x_pm_power_save_work(struct work_struct *work) +{ + struct mt792x_dev *dev; + unsigned long delta; + struct mt76_phy *mphy; + + dev = (struct mt792x_dev *)container_of(work, struct mt792x_dev, + pm.ps_work.work); + mphy = dev->phy.mt76; + + delta = dev->pm.idle_timeout; + if (test_bit(MT76_HW_SCANNING, &mphy->state) || + test_bit(MT76_HW_SCHED_SCANNING, &mphy->state) || + dev->fw_assert) + goto out; + + if (mutex_is_locked(&dev->mt76.mutex)) + /* if mt76 mutex is held we should not put the device + * to sleep since we are currently accessing device + * register map. We need to wait for the next power_save + * trigger. + */ + goto out; + + if (time_is_after_jiffies(dev->pm.last_activity + delta)) { + delta = dev->pm.last_activity + delta - jiffies; + goto out; + } + + if (!mt792x_mcu_fw_pmctrl(dev)) { + cancel_delayed_work_sync(&mphy->mac_work); + return; + } +out: + queue_delayed_work(dev->mt76.wq, &dev->pm.ps_work, delta); +} +EXPORT_SYMBOL_GPL(mt792x_pm_power_save_work); diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_regs.h b/drivers/net/wireless/mediatek/mt76/mt792x_regs.h new file mode 100644 index 000000000000..a99af23e4b56 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt792x_regs.h @@ -0,0 +1,479 @@ +/* SPDX-License-Identifier: ISC */ +/* Copyright (C) 2023 MediaTek Inc. */ + +#ifndef __MT792X_REGS_H +#define __MT792X_REGS_H + +/* MCU WFDMA1 */ +#define MT_MCU_WFDMA1_BASE 0x3000 +#define MT_MCU_WFDMA1(ofs) (MT_MCU_WFDMA1_BASE + (ofs)) + +#define MT_MCU_INT_EVENT MT_MCU_WFDMA1(0x108) +#define MT_MCU_INT_EVENT_DMA_STOPPED BIT(0) +#define MT_MCU_INT_EVENT_DMA_INIT BIT(1) +#define MT_MCU_INT_EVENT_SER_TRIGGER BIT(2) +#define MT_MCU_INT_EVENT_RESET_DONE BIT(3) + +#define MT_PLE_BASE 0x820c0000 +#define MT_PLE(ofs) (MT_PLE_BASE + (ofs)) + +#define MT_PLE_FL_Q0_CTRL MT_PLE(0x3e0) +#define MT_PLE_FL_Q1_CTRL MT_PLE(0x3e4) +#define MT_PLE_FL_Q2_CTRL MT_PLE(0x3e8) +#define MT_PLE_FL_Q3_CTRL MT_PLE(0x3ec) + +#define MT_PLE_AC_QEMPTY(_n) MT_PLE(0x500 + 0x40 * (_n)) +#define MT_PLE_AMSDU_PACK_MSDU_CNT(n) MT_PLE(0x10e0 + ((n) << 2)) + +/* TMAC: band 0(0x21000), band 1(0xa1000) */ +#define MT_WF_TMAC_BASE(_band) ((_band) ? 0x820f4000 : 0x820e4000) +#define MT_WF_TMAC(_band, ofs) (MT_WF_TMAC_BASE(_band) + (ofs)) + +#define MT_TMAC_TCR0(_band) MT_WF_TMAC(_band, 0) +#define MT_TMAC_TCR0_TBTT_STOP_CTRL BIT(25) + +#define MT_TMAC_CDTR(_band) MT_WF_TMAC(_band, 0x090) +#define MT_TMAC_ODTR(_band) MT_WF_TMAC(_band, 0x094) +#define MT_TIMEOUT_VAL_PLCP GENMASK(15, 0) +#define MT_TIMEOUT_VAL_CCA GENMASK(31, 16) + +#define MT_TMAC_ICR0(_band) MT_WF_TMAC(_band, 0x0a4) +#define MT_IFS_EIFS GENMASK(8, 0) +#define MT_IFS_RIFS GENMASK(14, 10) +#define MT_IFS_SIFS GENMASK(22, 16) +#define MT_IFS_SLOT GENMASK(30, 24) + +#define MT_TMAC_CTCR0(_band) MT_WF_TMAC(_band, 0x0f4) +#define MT_TMAC_CTCR0_INS_DDLMT_REFTIME GENMASK(5, 0) +#define MT_TMAC_CTCR0_INS_DDLMT_EN BIT(17) +#define MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN BIT(18) + +#define MT_TMAC_TRCR0(_band) MT_WF_TMAC(_band, 0x09c) +#define MT_TMAC_TFCR0(_band) MT_WF_TMAC(_band, 0x1e0) + +#define MT_WF_DMA_BASE(_band) ((_band) ? 0x820f7000 : 0x820e7000) +#define MT_WF_DMA(_band, ofs) (MT_WF_DMA_BASE(_band) + (ofs)) + +#define MT_DMA_DCR0(_band) MT_WF_DMA(_band, 0x000) +#define MT_DMA_DCR0_MAX_RX_LEN GENMASK(15, 3) +#define MT_DMA_DCR0_RXD_G5_EN BIT(23) + +/* WTBLOFF TOP: band 0(0x820e9000),band 1(0x820f9000) */ +#define MT_WTBLOFF_TOP_BASE(_band) ((_band) ? 0x820f9000 : 0x820e9000) +#define MT_WTBLOFF_TOP(_band, ofs) (MT_WTBLOFF_TOP_BASE(_band) + (ofs)) + +#define MT_WTBLOFF_TOP_RSCR(_band) MT_WTBLOFF_TOP(_band, 0x008) +#define MT_WTBLOFF_TOP_RSCR_RCPI_MODE GENMASK(31, 30) +#define MT_WTBLOFF_TOP_RSCR_RCPI_PARAM GENMASK(25, 24) + +/* LPON: band 0(0x24200), band 1(0xa4200) */ +#define MT_WF_LPON_BASE(_band) ((_band) ? 0x820fb000 : 0x820eb000) +#define MT_WF_LPON(_band, ofs) (MT_WF_LPON_BASE(_band) + (ofs)) + +#define MT_LPON_UTTR0(_band) MT_WF_LPON(_band, 0x080) +#define MT_LPON_UTTR1(_band) MT_WF_LPON(_band, 0x084) + +#define MT_LPON_TCR(_band, n) MT_WF_LPON(_band, 0x0a8 + (n) * 4) +#define MT_LPON_TCR_SW_MODE GENMASK(1, 0) +#define MT_LPON_TCR_SW_WRITE BIT(0) + +/* ETBF: band 0(0x24000), band 1(0xa4000) */ +#define MT_WF_ETBF_BASE(_band) ((_band) ? 0x820fa000 : 0x820ea000) +#define MT_WF_ETBF(_band, ofs) (MT_WF_ETBF_BASE(_band) + (ofs)) + +#define MT_ETBF_TX_APP_CNT(_band) MT_WF_ETBF(_band, 0x150) +#define MT_ETBF_TX_IBF_CNT GENMASK(31, 16) +#define MT_ETBF_TX_EBF_CNT GENMASK(15, 0) + +#define MT_ETBF_RX_FB_CNT(_band) MT_WF_ETBF(_band, 0x158) +#define MT_ETBF_RX_FB_ALL GENMASK(31, 24) +#define MT_ETBF_RX_FB_HE GENMASK(23, 16) +#define MT_ETBF_RX_FB_VHT GENMASK(15, 8) +#define MT_ETBF_RX_FB_HT GENMASK(7, 0) + +/* MIB: band 0(0x24800), band 1(0xa4800) */ +#define MT_WF_MIB_BASE(_band) ((_band) ? 0x820fd000 : 0x820ed000) +#define MT_WF_MIB(_band, ofs) (MT_WF_MIB_BASE(_band) + (ofs)) + +#define MT_MIB_SCR1(_band) MT_WF_MIB(_band, 0x004) +#define MT_MIB_TXDUR_EN BIT(8) +#define MT_MIB_RXDUR_EN BIT(9) + +#define MT_MIB_SDR3(_band) MT_WF_MIB(_band, 0x698) +#define MT_MIB_SDR3_FCS_ERR_MASK GENMASK(31, 16) + +#define MT_MIB_SDR5(_band) MT_WF_MIB(_band, 0x780) + +#define MT_MIB_SDR9(_band) MT_WF_MIB(_band, 0x02c) +#define MT_MIB_SDR9_BUSY_MASK GENMASK(23, 0) + +#define MT_MIB_SDR12(_band) MT_WF_MIB(_band, 0x558) +#define MT_MIB_SDR14(_band) MT_WF_MIB(_band, 0x564) +#define MT_MIB_SDR15(_band) MT_WF_MIB(_band, 0x568) + +#define MT_MIB_SDR16(_band) MT_WF_MIB(_band, 0x048) +#define MT_MIB_SDR16_BUSY_MASK GENMASK(23, 0) + +#define MT_MIB_SDR22(_band) MT_WF_MIB(_band, 0x770) +#define MT_MIB_SDR23(_band) MT_WF_MIB(_band, 0x774) +#define MT_MIB_SDR31(_band) MT_WF_MIB(_band, 0x55c) + +#define MT_MIB_SDR32(_band) MT_WF_MIB(_band, 0x7a8) +#define MT_MIB_SDR9_IBF_CNT_MASK GENMASK(31, 16) +#define MT_MIB_SDR9_EBF_CNT_MASK GENMASK(15, 0) + +#define MT_MIB_SDR34(_band) MT_WF_MIB(_band, 0x090) +#define MT_MIB_MU_BF_TX_CNT GENMASK(15, 0) + +#define MT_MIB_SDR36(_band) MT_WF_MIB(_band, 0x054) +#define MT_MIB_SDR36_TXTIME_MASK GENMASK(23, 0) +#define MT_MIB_SDR37(_band) MT_WF_MIB(_band, 0x058) +#define MT_MIB_SDR37_RXTIME_MASK GENMASK(23, 0) + +#define MT_MIB_DR8(_band) MT_WF_MIB(_band, 0x0c0) +#define MT_MIB_DR9(_band) MT_WF_MIB(_band, 0x0c4) +#define MT_MIB_DR11(_band) MT_WF_MIB(_band, 0x0cc) + +#define MT_MIB_MB_SDR0(_band, n) MT_WF_MIB(_band, 0x100 + ((n) << 4)) +#define MT_MIB_RTS_RETRIES_COUNT_MASK GENMASK(31, 16) + +#define MT_MIB_MB_BSDR0(_band) MT_WF_MIB(_band, 0x688) +#define MT_MIB_RTS_COUNT_MASK GENMASK(15, 0) +#define MT_MIB_MB_BSDR1(_band) MT_WF_MIB(_band, 0x690) +#define MT_MIB_RTS_FAIL_COUNT_MASK GENMASK(15, 0) +#define MT_MIB_MB_BSDR2(_band) MT_WF_MIB(_band, 0x518) +#define MT_MIB_BA_FAIL_COUNT_MASK GENMASK(15, 0) +#define MT_MIB_MB_BSDR3(_band) MT_WF_MIB(_band, 0x520) +#define MT_MIB_ACK_FAIL_COUNT_MASK GENMASK(15, 0) + +#define MT_MIB_MB_SDR2(_band, n) MT_WF_MIB(_band, 0x108 + ((n) << 4)) +#define MT_MIB_FRAME_RETRIES_COUNT_MASK GENMASK(15, 0) + +#define MT_TX_AGG_CNT(_band, n) MT_WF_MIB(_band, 0x7dc + ((n) << 2)) +#define MT_TX_AGG_CNT2(_band, n) MT_WF_MIB(_band, 0x7ec + ((n) << 2)) +#define MT_MIB_ARNG(_band, n) MT_WF_MIB(_band, 0x0b0 + ((n) << 2)) +#define MT_MIB_ARNCR_RANGE(val, n) (((val) >> ((n) << 3)) & GENMASK(7, 0)) + +#define MT_WTBLON_TOP_BASE 0x820d4000 +#define MT_WTBLON_TOP(ofs) (MT_WTBLON_TOP_BASE + (ofs)) + +#define MT_WTBL_UPDATE_BUSY BIT(31) + +#define MT_WTBL_ITCR MT_WTBLON_TOP(0x3b0) +#define MT_WTBL_ITCR_WR BIT(16) +#define MT_WTBL_ITCR_EXEC BIT(31) +#define MT_WTBL_ITDR0 MT_WTBLON_TOP(0x3b8) +#define MT_WTBL_ITDR1 MT_WTBLON_TOP(0x3bc) +#define MT_WTBL_SPE_IDX_SEL BIT(6) + +#define MT_WTBL_BASE 0x820d8000 +#define MT_WTBL_LMAC_ID GENMASK(14, 8) +#define MT_WTBL_LMAC_DW GENMASK(7, 2) +#define MT_WTBL_LMAC_OFFS(_id, _dw) (MT_WTBL_BASE | \ + FIELD_PREP(MT_WTBL_LMAC_ID, _id) | \ + FIELD_PREP(MT_WTBL_LMAC_DW, _dw)) + +/* AGG: band 0(0x20800), band 1(0xa0800) */ +#define MT_WF_AGG_BASE(_band) ((_band) ? 0x820f2000 : 0x820e2000) +#define MT_WF_AGG(_band, ofs) (MT_WF_AGG_BASE(_band) + (ofs)) + +#define MT_AGG_AWSCR0(_band, _n) MT_WF_AGG(_band, 0x05c + (_n) * 4) +#define MT_AGG_PCR0(_band, _n) MT_WF_AGG(_band, 0x06c + (_n) * 4) +#define MT_AGG_PCR0_MM_PROT BIT(0) +#define MT_AGG_PCR0_GF_PROT BIT(1) +#define MT_AGG_PCR0_BW20_PROT BIT(2) +#define MT_AGG_PCR0_BW40_PROT BIT(4) +#define MT_AGG_PCR0_BW80_PROT BIT(6) +#define MT_AGG_PCR0_ERP_PROT GENMASK(12, 8) +#define MT_AGG_PCR0_VHT_PROT BIT(13) +#define MT_AGG_PCR0_PTA_WIN_DIS BIT(15) + +#define MT_AGG_PCR1_RTS0_NUM_THRES GENMASK(31, 23) +#define MT_AGG_PCR1_RTS0_LEN_THRES GENMASK(19, 0) + +#define MT_AGG_ACR0(_band) MT_WF_AGG(_band, 0x084) +#define MT_AGG_ACR_CFEND_RATE GENMASK(13, 0) +#define MT_AGG_ACR_BAR_RATE GENMASK(29, 16) + +#define MT_AGG_MRCR(_band) MT_WF_AGG(_band, 0x098) +#define MT_AGG_MRCR_BAR_CNT_LIMIT GENMASK(15, 12) +#define MT_AGG_MRCR_LAST_RTS_CTS_RN BIT(6) +#define MT_AGG_MRCR_RTS_FAIL_LIMIT GENMASK(11, 7) +#define MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT GENMASK(28, 24) + +#define MT_AGG_ATCR1(_band) MT_WF_AGG(_band, 0x0f0) +#define MT_AGG_ATCR3(_band) MT_WF_AGG(_band, 0x0f4) + +/* ARB: band 0(0x20c00), band 1(0xa0c00) */ +#define MT_WF_ARB_BASE(_band) ((_band) ? 0x820f3000 : 0x820e3000) +#define MT_WF_ARB(_band, ofs) (MT_WF_ARB_BASE(_band) + (ofs)) + +#define MT_ARB_SCR(_band) MT_WF_ARB(_band, 0x080) +#define MT_ARB_SCR_TX_DISABLE BIT(8) +#define MT_ARB_SCR_RX_DISABLE BIT(9) + +#define MT_ARB_DRNGR0(_band, _n) MT_WF_ARB(_band, 0x194 + (_n) * 4) + +/* RMAC: band 0(0x21400), band 1(0xa1400) */ +#define MT_WF_RMAC_BASE(_band) ((_band) ? 0x820f5000 : 0x820e5000) +#define MT_WF_RMAC(_band, ofs) (MT_WF_RMAC_BASE(_band) + (ofs)) + +#define MT_WF_RFCR(_band) MT_WF_RMAC(_band, 0x000) +#define MT_WF_RFCR_DROP_STBC_MULTI BIT(0) +#define MT_WF_RFCR_DROP_FCSFAIL BIT(1) +#define MT_WF_RFCR_DROP_VERSION BIT(3) +#define MT_WF_RFCR_DROP_PROBEREQ BIT(4) +#define MT_WF_RFCR_DROP_MCAST BIT(5) +#define MT_WF_RFCR_DROP_BCAST BIT(6) +#define MT_WF_RFCR_DROP_MCAST_FILTERED BIT(7) +#define MT_WF_RFCR_DROP_A3_MAC BIT(8) +#define MT_WF_RFCR_DROP_A3_BSSID BIT(9) +#define MT_WF_RFCR_DROP_A2_BSSID BIT(10) +#define MT_WF_RFCR_DROP_OTHER_BEACON BIT(11) +#define MT_WF_RFCR_DROP_FRAME_REPORT BIT(12) +#define MT_WF_RFCR_DROP_CTL_RSV BIT(13) +#define MT_WF_RFCR_DROP_CTS BIT(14) +#define MT_WF_RFCR_DROP_RTS BIT(15) +#define MT_WF_RFCR_DROP_DUPLICATE BIT(16) +#define MT_WF_RFCR_DROP_OTHER_BSS BIT(17) +#define MT_WF_RFCR_DROP_OTHER_UC BIT(18) +#define MT_WF_RFCR_DROP_OTHER_TIM BIT(19) +#define MT_WF_RFCR_DROP_NDPA BIT(20) +#define MT_WF_RFCR_DROP_UNWANTED_CTL BIT(21) + +#define MT_WF_RFCR1(_band) MT_WF_RMAC(_band, 0x004) +#define MT_WF_RFCR1_DROP_ACK BIT(4) +#define MT_WF_RFCR1_DROP_BF_POLL BIT(5) +#define MT_WF_RFCR1_DROP_BA BIT(6) +#define MT_WF_RFCR1_DROP_CFEND BIT(7) +#define MT_WF_RFCR1_DROP_CFACK BIT(8) + +#define MT_WF_RMAC_MIB_TIME0(_band) MT_WF_RMAC(_band, 0x03c4) +#define MT_WF_RMAC_MIB_RXTIME_CLR BIT(31) +#define MT_WF_RMAC_MIB_RXTIME_EN BIT(30) + +#define MT_WF_RMAC_MIB_AIRTIME14(_band) MT_WF_RMAC(_band, 0x03b8) +#define MT_MIB_OBSSTIME_MASK GENMASK(23, 0) +#define MT_WF_RMAC_MIB_AIRTIME0(_band) MT_WF_RMAC(_band, 0x0380) + +/* WFDMA0 */ +#define MT_WFDMA0_BASE 0xd4000 +#define MT_WFDMA0(ofs) (MT_WFDMA0_BASE + (ofs)) + +#define MT_WFDMA0_RST MT_WFDMA0(0x100) +#define MT_WFDMA0_RST_LOGIC_RST BIT(4) +#define MT_WFDMA0_RST_DMASHDL_ALL_RST BIT(5) + +#define MT_WFDMA0_BUSY_ENA MT_WFDMA0(0x13c) +#define MT_WFDMA0_BUSY_ENA_TX_FIFO0 BIT(0) +#define MT_WFDMA0_BUSY_ENA_TX_FIFO1 BIT(1) +#define MT_WFDMA0_BUSY_ENA_RX_FIFO BIT(2) + +#define MT_MCU_CMD MT_WFDMA0(0x1f0) +#define MT_MCU_CMD_WAKE_RX_PCIE BIT(0) +#define MT_MCU_CMD_STOP_DMA_FW_RELOAD BIT(1) +#define MT_MCU_CMD_STOP_DMA BIT(2) +#define MT_MCU_CMD_RESET_DONE BIT(3) +#define MT_MCU_CMD_RECOVERY_DONE BIT(4) +#define MT_MCU_CMD_NORMAL_STATE BIT(5) +#define MT_MCU_CMD_ERROR_MASK GENMASK(5, 1) + +#define MT_MCU2HOST_SW_INT_ENA MT_WFDMA0(0x1f4) + +#define MT_WFDMA0_HOST_INT_STA MT_WFDMA0(0x200) +#define HOST_RX_DONE_INT_STS0 BIT(0) /* Rx mcu */ +#define HOST_RX_DONE_INT_STS2 BIT(2) /* Rx data */ +#define HOST_RX_DONE_INT_STS4 BIT(22) /* Rx mcu after fw downloaded */ +#define HOST_TX_DONE_INT_STS16 BIT(26) +#define HOST_TX_DONE_INT_STS17 BIT(27) /* MCU tx done*/ + +#define MT_WFDMA0_GLO_CFG MT_WFDMA0(0x208) +#define MT_WFDMA0_GLO_CFG_TX_DMA_EN BIT(0) +#define MT_WFDMA0_GLO_CFG_TX_DMA_BUSY BIT(1) +#define MT_WFDMA0_GLO_CFG_RX_DMA_EN BIT(2) +#define MT_WFDMA0_GLO_CFG_RX_DMA_BUSY BIT(3) +#define MT_WFDMA0_GLO_CFG_TX_WB_DDONE BIT(6) +#define MT_WFDMA0_GLO_CFG_FW_DWLD_BYPASS_DMASHDL BIT(9) +#define MT_WFDMA0_GLO_CFG_FIFO_LITTLE_ENDIAN BIT(12) +#define MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN BIT(15) +#define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2 BIT(21) +#define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO BIT(27) +#define MT_WFDMA0_GLO_CFG_OMIT_TX_INFO BIT(28) +#define MT_WFDMA0_GLO_CFG_CLK_GAT_DIS BIT(30) + +#define HOST_RX_DONE_INT_ENA0 BIT(0) +#define HOST_RX_DONE_INT_ENA1 BIT(1) +#define HOST_RX_DONE_INT_ENA2 BIT(2) +#define HOST_RX_DONE_INT_ENA3 BIT(3) +#define HOST_TX_DONE_INT_ENA0 BIT(4) +#define HOST_TX_DONE_INT_ENA1 BIT(5) +#define HOST_TX_DONE_INT_ENA2 BIT(6) +#define HOST_TX_DONE_INT_ENA3 BIT(7) +#define HOST_TX_DONE_INT_ENA4 BIT(8) +#define HOST_TX_DONE_INT_ENA5 BIT(9) +#define HOST_TX_DONE_INT_ENA6 BIT(10) +#define HOST_TX_DONE_INT_ENA7 BIT(11) +#define HOST_RX_COHERENT_EN BIT(20) +#define HOST_TX_COHERENT_EN BIT(21) +#define MCU2HOST_SW_INT_ENA BIT(29) +#define HOST_TX_DONE_INT_ENA18 BIT(30) + +#define MT_INT_MCU_CMD MCU2HOST_SW_INT_ENA + +#define MT_WFDMA0_RST_DTX_PTR MT_WFDMA0(0x20c) +#define MT_WFDMA0_RST_DRX_PTR MT_WFDMA0(0x280) +#define MT_WFDMA0_GLO_CFG_EXT0 MT_WFDMA0(0x2b0) +#define MT_WFDMA0_CSR_TX_DMASHDL_ENABLE BIT(6) +#define MT_WFDMA0_PRI_DLY_INT_CFG0 MT_WFDMA0(0x2f0) + +#define MT_WFDMA0_TX_RING0_EXT_CTRL MT_WFDMA0(0x600) +#define MT_WFDMA0_TX_RING1_EXT_CTRL MT_WFDMA0(0x604) +#define MT_WFDMA0_TX_RING2_EXT_CTRL MT_WFDMA0(0x608) +#define MT_WFDMA0_TX_RING3_EXT_CTRL MT_WFDMA0(0x60c) +#define MT_WFDMA0_TX_RING4_EXT_CTRL MT_WFDMA0(0x610) +#define MT_WFDMA0_TX_RING5_EXT_CTRL MT_WFDMA0(0x614) +#define MT_WFDMA0_TX_RING6_EXT_CTRL MT_WFDMA0(0x618) +#define MT_WFDMA0_TX_RING15_EXT_CTRL MT_WFDMA0(0x63c) +#define MT_WFDMA0_TX_RING16_EXT_CTRL MT_WFDMA0(0x640) +#define MT_WFDMA0_TX_RING17_EXT_CTRL MT_WFDMA0(0x644) + +#define MT_WPDMA0_MAX_CNT_MASK GENMASK(7, 0) +#define MT_WPDMA0_BASE_PTR_MASK GENMASK(31, 16) + +#define MT_WFDMA0_RX_RING0_EXT_CTRL MT_WFDMA0(0x680) +#define MT_WFDMA0_RX_RING1_EXT_CTRL MT_WFDMA0(0x684) +#define MT_WFDMA0_RX_RING2_EXT_CTRL MT_WFDMA0(0x688) +#define MT_WFDMA0_RX_RING3_EXT_CTRL MT_WFDMA0(0x68c) +#define MT_WFDMA0_RX_RING4_EXT_CTRL MT_WFDMA0(0x690) +#define MT_WFDMA0_RX_RING5_EXT_CTRL MT_WFDMA0(0x694) +#define MT_WFDMA0_RX_RING6_EXT_CTRL MT_WFDMA0(0x698) +#define MT_WFDMA0_RX_RING7_EXT_CTRL MT_WFDMA0(0x69c) + +#define MT_TX_RING_BASE MT_WFDMA0(0x300) +#define MT_RX_EVENT_RING_BASE MT_WFDMA0(0x500) + +/* WFDMA CSR */ +#define MT_WFDMA_EXT_CSR_BASE 0xd7000 +#define MT_WFDMA_EXT_CSR(ofs) (MT_WFDMA_EXT_CSR_BASE + (ofs)) +#define MT_WFDMA_EXT_CSR_HIF_MISC MT_WFDMA_EXT_CSR(0x44) +#define MT_WFDMA_EXT_CSR_HIF_MISC_BUSY BIT(0) + +#define MT_SWDEF_BASE 0x41f200 +#define MT_SWDEF(ofs) (MT_SWDEF_BASE + (ofs)) +#define MT_SWDEF_MODE MT_SWDEF(0x3c) +#define MT_SWDEF_NORMAL_MODE 0 +#define MT_SWDEF_ICAP_MODE 1 +#define MT_SWDEF_SPECTRUM_MODE 2 + +#define MT_TOP_BASE 0x18060000 +#define MT_TOP(ofs) (MT_TOP_BASE + (ofs)) + +#define MT_TOP_LPCR_HOST_BAND0 MT_TOP(0x10) +#define MT_TOP_LPCR_HOST_FW_OWN BIT(0) +#define MT_TOP_LPCR_HOST_DRV_OWN BIT(1) + +#define MT_TOP_MISC MT_TOP(0xf0) +#define MT_TOP_MISC_FW_STATE GENMASK(2, 0) + +#define MT_MCU_WPDMA0_BASE 0x54000000 +#define MT_MCU_WPDMA0(ofs) (MT_MCU_WPDMA0_BASE + (ofs)) + +#define MT_WFDMA_DUMMY_CR MT_MCU_WPDMA0(0x120) +#define MT_WFDMA_NEED_REINIT BIT(1) + +#define MT_CBTOP_RGU(ofs) (0x70002000 + (ofs)) +#define MT_CBTOP_RGU_WF_SUBSYS_RST MT_CBTOP_RGU(0x600) +#define MT_CBTOP_RGU_WF_SUBSYS_RST_WF_WHOLE_PATH BIT(0) + +#define MT_HW_BOUND 0x70010020 +#define MT_HW_CHIPID 0x70010200 +#define MT_HW_REV 0x70010204 + +#define MT_PCIE_MAC_BASE 0x10000 +#define MT_PCIE_MAC(ofs) (MT_PCIE_MAC_BASE + (ofs)) +#define MT_PCIE_MAC_INT_ENABLE MT_PCIE_MAC(0x188) +#define MT_PCIE_MAC_PM MT_PCIE_MAC(0x194) +#define MT_PCIE_MAC_PM_L0S_DIS BIT(8) + +#define MT_DMA_SHDL(ofs) (0x7c026000 + (ofs)) +#define MT_DMASHDL_SW_CONTROL MT_DMA_SHDL(0x004) +#define MT_DMASHDL_DMASHDL_BYPASS BIT(28) +#define MT_DMASHDL_OPTIONAL MT_DMA_SHDL(0x008) +#define MT_DMASHDL_PAGE MT_DMA_SHDL(0x00c) +#define MT_DMASHDL_GROUP_SEQ_ORDER BIT(16) +#define MT_DMASHDL_REFILL MT_DMA_SHDL(0x010) +#define MT_DMASHDL_REFILL_MASK GENMASK(31, 16) +#define MT_DMASHDL_PKT_MAX_SIZE MT_DMA_SHDL(0x01c) +#define MT_DMASHDL_PKT_MAX_SIZE_PLE GENMASK(11, 0) +#define MT_DMASHDL_PKT_MAX_SIZE_PSE GENMASK(27, 16) + +#define MT_DMASHDL_GROUP_QUOTA(_n) MT_DMA_SHDL(0x020 + ((_n) << 2)) +#define MT_DMASHDL_GROUP_QUOTA_MIN GENMASK(11, 0) +#define MT_DMASHDL_GROUP_QUOTA_MAX GENMASK(27, 16) + +#define MT_DMASHDL_Q_MAP(_n) MT_DMA_SHDL(0x060 + ((_n) << 2)) +#define MT_DMASHDL_Q_MAP_MASK GENMASK(3, 0) +#define MT_DMASHDL_Q_MAP_SHIFT(_n) (4 * ((_n) % 8)) + +#define MT_DMASHDL_SCHED_SET(_n) MT_DMA_SHDL(0x070 + ((_n) << 2)) + +#define MT_WFDMA_HOST_CONFIG 0x7c027030 +#define MT_WFDMA_HOST_CONFIG_USB_RXEVT_EP4_EN BIT(6) + +#define MT_UMAC(ofs) (0x74000000 + (ofs)) +#define MT_UDMA_TX_QSEL MT_UMAC(0x008) +#define MT_FW_DL_EN BIT(3) + +#define MT_UDMA_WLCFG_1 MT_UMAC(0x00c) +#define MT_WL_RX_AGG_PKT_LMT GENMASK(7, 0) +#define MT_WL_TX_TMOUT_LMT GENMASK(27, 8) + +#define MT_UDMA_WLCFG_0 MT_UMAC(0x18) +#define MT_WL_RX_AGG_TO GENMASK(7, 0) +#define MT_WL_RX_AGG_LMT GENMASK(15, 8) +#define MT_WL_TX_TMOUT_FUNC_EN BIT(16) +#define MT_WL_TX_DPH_CHK_EN BIT(17) +#define MT_WL_RX_MPSZ_PAD0 BIT(18) +#define MT_WL_RX_FLUSH BIT(19) +#define MT_TICK_1US_EN BIT(20) +#define MT_WL_RX_AGG_EN BIT(21) +#define MT_WL_RX_EN BIT(22) +#define MT_WL_TX_EN BIT(23) +#define MT_WL_RX_BUSY BIT(30) +#define MT_WL_TX_BUSY BIT(31) + +#define MT_UDMA_CONN_INFRA_STATUS MT_UMAC(0xa20) +#define MT_UDMA_CONN_WFSYS_INIT_DONE BIT(22) +#define MT_UDMA_CONN_INFRA_STATUS_SEL MT_UMAC(0xa24) + +#define MT_SSUSB_EPCTL_CSR(ofs) (0x74011800 + (ofs)) +#define MT_SSUSB_EPCTL_CSR_EP_RST_OPT MT_SSUSB_EPCTL_CSR(0x090) + +#define MT_UWFDMA0(ofs) (0x7c024000 + (ofs)) +#define MT_UWFDMA0_GLO_CFG MT_UWFDMA0(0x208) +#define MT_UWFDMA0_GLO_CFG_EXT0 MT_UWFDMA0(0x2b0) +#define MT_UWFDMA0_GLO_CFG_EXT1 MT_UWFDMA0(0x2b4) +#define MT_UWFDMA0_TX_RING_EXT_CTRL(_n) MT_UWFDMA0(0x600 + ((_n) << 2)) + +#define MT_CONN_STATUS 0x7c053c10 +#define MT_WIFI_PATCH_DL_STATE BIT(0) + +#define MT_CONN_ON_LPCTL 0x7c060010 +#define PCIE_LPCR_HOST_SET_OWN BIT(0) +#define PCIE_LPCR_HOST_CLR_OWN BIT(1) +#define PCIE_LPCR_HOST_OWN_SYNC BIT(2) + +#define MT_CONN_ON_MISC 0x7c0600f0 +#define MT_TOP_MISC2_FW_PWR_ON BIT(0) +#define MT_TOP_MISC2_FW_N9_ON BIT(1) +#define MT_TOP_MISC2_FW_N9_RDY GENMASK(1, 0) + +#define MT_WF_SW_DEF_CR(ofs) (0x401a00 + (ofs)) +#define MT_WF_SW_DEF_CR_USB_MCU_EVENT MT_WF_SW_DEF_CR(0x028) +#define MT_WF_SW_SER_TRIGGER_SUSPEND BIT(6) +#define MT_WF_SW_SER_DONE_SUSPEND BIT(7) + +#define WFSYS_SW_RST_B BIT(0) +#define WFSYS_SW_INIT_DONE BIT(4) + +#endif /* __MT792X_REGS_H */ diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_trace.c b/drivers/net/wireless/mediatek/mt76/mt792x_trace.c new file mode 100644 index 000000000000..b6f284fb929d --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt792x_trace.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: ISC +/* + * Copyright (C) 2023 Lorenzo Bianconi <lorenzo@kernel.org> + */ + +#include <linux/module.h> + +#ifndef __CHECKER__ +#define CREATE_TRACE_POINTS +#include "mt792x_trace.h" + +EXPORT_TRACEPOINT_SYMBOL_GPL(lp_event); + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921_trace.h b/drivers/net/wireless/mediatek/mt76/mt792x_trace.h index 9bc4db67f352..61f2aa260656 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921_trace.h +++ b/drivers/net/wireless/mediatek/mt76/mt792x_trace.h @@ -1,27 +1,27 @@ /* SPDX-License-Identifier: ISC */ /* - * Copyright (C) 2021 Lorenzo Bianconi <lorenzo@kernel.org> + * Copyright (C) 2023 Lorenzo Bianconi <lorenzo@kernel.org> */ -#if !defined(__MT7921_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) -#define __MT7921_TRACE_H +#if !defined(__MT792X_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define __MT792X_TRACE_H #include <linux/tracepoint.h> -#include "mt7921.h" +#include "mt792x.h" #undef TRACE_SYSTEM -#define TRACE_SYSTEM mt7921 +#define TRACE_SYSTEM mt792x #define MAXNAME 32 #define DEV_ENTRY __array(char, wiphy_name, 32) -#define DEV_ASSIGN strlcpy(__entry->wiphy_name, \ +#define DEV_ASSIGN strscpy(__entry->wiphy_name, \ wiphy_name(mt76_hw(dev)->wiphy), MAXNAME) #define DEV_PR_FMT "%s" #define DEV_PR_ARG __entry->wiphy_name #define LP_STATE_PR_ARG __entry->lp_state ? "lp ready" : "lp not ready" TRACE_EVENT(lp_event, - TP_PROTO(struct mt7921_dev *dev, u8 lp_state), + TP_PROTO(struct mt792x_dev *dev, u8 lp_state), TP_ARGS(dev, lp_state), @@ -46,6 +46,6 @@ TRACE_EVENT(lp_event, #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH . #undef TRACE_INCLUDE_FILE -#define TRACE_INCLUDE_FILE mt7921_trace +#define TRACE_INCLUDE_FILE mt792x_trace #include <trace/define_trace.h> diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_usb.c b/drivers/net/wireless/mediatek/mt76/mt792x_usb.c new file mode 100644 index 000000000000..20e7f9c7c88c --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt792x_usb.c @@ -0,0 +1,309 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2023 MediaTek Inc. + * + * Author: Lorenzo Bianconi <lorenzo@kernel.org> + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/usb.h> + +#include "mt792x.h" +#include "mt76_connac2_mac.h" + +u32 mt792xu_rr(struct mt76_dev *dev, u32 addr) +{ + u32 ret; + + mutex_lock(&dev->usb.usb_ctrl_mtx); + ret = ___mt76u_rr(dev, MT_VEND_READ_EXT, + USB_DIR_IN | MT_USB_TYPE_VENDOR, addr); + mutex_unlock(&dev->usb.usb_ctrl_mtx); + + return ret; +} +EXPORT_SYMBOL_GPL(mt792xu_rr); + +void mt792xu_wr(struct mt76_dev *dev, u32 addr, u32 val) +{ + mutex_lock(&dev->usb.usb_ctrl_mtx); + ___mt76u_wr(dev, MT_VEND_WRITE_EXT, + USB_DIR_OUT | MT_USB_TYPE_VENDOR, addr, val); + mutex_unlock(&dev->usb.usb_ctrl_mtx); +} +EXPORT_SYMBOL_GPL(mt792xu_wr); + +u32 mt792xu_rmw(struct mt76_dev *dev, u32 addr, u32 mask, u32 val) +{ + mutex_lock(&dev->usb.usb_ctrl_mtx); + val |= ___mt76u_rr(dev, MT_VEND_READ_EXT, + USB_DIR_IN | MT_USB_TYPE_VENDOR, addr) & ~mask; + ___mt76u_wr(dev, MT_VEND_WRITE_EXT, + USB_DIR_OUT | MT_USB_TYPE_VENDOR, addr, val); + mutex_unlock(&dev->usb.usb_ctrl_mtx); + + return val; +} +EXPORT_SYMBOL_GPL(mt792xu_rmw); + +void mt792xu_copy(struct mt76_dev *dev, u32 offset, const void *data, int len) +{ + struct mt76_usb *usb = &dev->usb; + int ret, i = 0, batch_len; + const u8 *val = data; + + len = round_up(len, 4); + + mutex_lock(&usb->usb_ctrl_mtx); + while (i < len) { + batch_len = min_t(int, usb->data_len, len - i); + memcpy(usb->data, val + i, batch_len); + ret = __mt76u_vendor_request(dev, MT_VEND_WRITE_EXT, + USB_DIR_OUT | MT_USB_TYPE_VENDOR, + (offset + i) >> 16, offset + i, + usb->data, batch_len); + if (ret < 0) + break; + + i += batch_len; + } + mutex_unlock(&usb->usb_ctrl_mtx); +} +EXPORT_SYMBOL_GPL(mt792xu_copy); + +int mt792xu_mcu_power_on(struct mt792x_dev *dev) +{ + int ret; + + ret = mt76u_vendor_request(&dev->mt76, MT_VEND_POWER_ON, + USB_DIR_OUT | MT_USB_TYPE_VENDOR, + 0x0, 0x1, NULL, 0); + if (ret) + return ret; + + if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_PWR_ON, + MT_TOP_MISC2_FW_PWR_ON, 500)) { + dev_err(dev->mt76.dev, "Timeout for power on\n"); + ret = -EIO; + } + + return ret; +} +EXPORT_SYMBOL_GPL(mt792xu_mcu_power_on); + +static void mt792xu_cleanup(struct mt792x_dev *dev) +{ + clear_bit(MT76_STATE_INITIALIZED, &dev->mphy.state); + mt792xu_wfsys_reset(dev); + skb_queue_purge(&dev->mt76.mcu.res_q); + mt76u_queues_deinit(&dev->mt76); +} + +static u32 mt792xu_uhw_rr(struct mt76_dev *dev, u32 addr) +{ + u32 ret; + + mutex_lock(&dev->usb.usb_ctrl_mtx); + ret = ___mt76u_rr(dev, MT_VEND_DEV_MODE, + USB_DIR_IN | MT_USB_TYPE_UHW_VENDOR, addr); + mutex_unlock(&dev->usb.usb_ctrl_mtx); + + return ret; +} + +static void mt792xu_uhw_wr(struct mt76_dev *dev, u32 addr, u32 val) +{ + mutex_lock(&dev->usb.usb_ctrl_mtx); + ___mt76u_wr(dev, MT_VEND_WRITE, + USB_DIR_OUT | MT_USB_TYPE_UHW_VENDOR, addr, val); + mutex_unlock(&dev->usb.usb_ctrl_mtx); +} + +static void mt792xu_dma_prefetch(struct mt792x_dev *dev) +{ + mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(0), + MT_WPDMA0_MAX_CNT_MASK, 4); + mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(0), + MT_WPDMA0_BASE_PTR_MASK, 0x80); + + mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(1), + MT_WPDMA0_MAX_CNT_MASK, 4); + mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(1), + MT_WPDMA0_BASE_PTR_MASK, 0xc0); + + mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(2), + MT_WPDMA0_MAX_CNT_MASK, 4); + mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(2), + MT_WPDMA0_BASE_PTR_MASK, 0x100); + + mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(3), + MT_WPDMA0_MAX_CNT_MASK, 4); + mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(3), + MT_WPDMA0_BASE_PTR_MASK, 0x140); + + mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(4), + MT_WPDMA0_MAX_CNT_MASK, 4); + mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(4), + MT_WPDMA0_BASE_PTR_MASK, 0x180); + + mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(16), + MT_WPDMA0_MAX_CNT_MASK, 4); + mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(16), + MT_WPDMA0_BASE_PTR_MASK, 0x280); + + mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(17), + MT_WPDMA0_MAX_CNT_MASK, 4); + mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(17), + MT_WPDMA0_BASE_PTR_MASK, 0x2c0); +} + +static void mt792xu_wfdma_init(struct mt792x_dev *dev) +{ + mt792xu_dma_prefetch(dev); + + mt76_clear(dev, MT_UWFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_OMIT_RX_INFO); + mt76_set(dev, MT_UWFDMA0_GLO_CFG, + MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | + MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2 | + MT_WFDMA0_GLO_CFG_FW_DWLD_BYPASS_DMASHDL | + MT_WFDMA0_GLO_CFG_TX_DMA_EN | + MT_WFDMA0_GLO_CFG_RX_DMA_EN); + + /* disable dmashdl */ + mt76_clear(dev, MT_UWFDMA0_GLO_CFG_EXT0, + MT_WFDMA0_CSR_TX_DMASHDL_ENABLE); + mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS); + + mt76_set(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT); +} + +static int mt792xu_dma_rx_evt_ep4(struct mt792x_dev *dev) +{ + if (!mt76_poll(dev, MT_UWFDMA0_GLO_CFG, + MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000)) + return -ETIMEDOUT; + + mt76_clear(dev, MT_UWFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_RX_DMA_EN); + mt76_set(dev, MT_WFDMA_HOST_CONFIG, + MT_WFDMA_HOST_CONFIG_USB_RXEVT_EP4_EN); + mt76_set(dev, MT_UWFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_RX_DMA_EN); + + return 0; +} + +static void mt792xu_epctl_rst_opt(struct mt792x_dev *dev, bool reset) +{ + u32 val; + + /* usb endpoint reset opt + * bits[4,9]: out blk ep 4-9 + * bits[20,21]: in blk ep 4-5 + * bits[22]: in int ep 6 + */ + val = mt792xu_uhw_rr(&dev->mt76, MT_SSUSB_EPCTL_CSR_EP_RST_OPT); + if (reset) + val |= GENMASK(9, 4) | GENMASK(22, 20); + else + val &= ~(GENMASK(9, 4) | GENMASK(22, 20)); + mt792xu_uhw_wr(&dev->mt76, MT_SSUSB_EPCTL_CSR_EP_RST_OPT, val); +} + +int mt792xu_dma_init(struct mt792x_dev *dev, bool resume) +{ + int err; + + mt792xu_wfdma_init(dev); + + mt76_clear(dev, MT_UDMA_WLCFG_0, MT_WL_RX_FLUSH); + + mt76_set(dev, MT_UDMA_WLCFG_0, + MT_WL_RX_EN | MT_WL_TX_EN | + MT_WL_RX_MPSZ_PAD0 | MT_TICK_1US_EN); + mt76_clear(dev, MT_UDMA_WLCFG_0, + MT_WL_RX_AGG_TO | MT_WL_RX_AGG_LMT); + mt76_clear(dev, MT_UDMA_WLCFG_1, MT_WL_RX_AGG_PKT_LMT); + + if (resume) + return 0; + + err = mt792xu_dma_rx_evt_ep4(dev); + if (err) + return err; + + mt792xu_epctl_rst_opt(dev, false); + + return 0; +} +EXPORT_SYMBOL_GPL(mt792xu_dma_init); + +int mt792xu_wfsys_reset(struct mt792x_dev *dev) +{ + u32 val; + int i; + + mt792xu_epctl_rst_opt(dev, false); + + val = mt792xu_uhw_rr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST); + val |= MT_CBTOP_RGU_WF_SUBSYS_RST_WF_WHOLE_PATH; + mt792xu_uhw_wr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST, val); + + usleep_range(10, 20); + + val = mt792xu_uhw_rr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST); + val &= ~MT_CBTOP_RGU_WF_SUBSYS_RST_WF_WHOLE_PATH; + mt792xu_uhw_wr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST, val); + + mt792xu_uhw_wr(&dev->mt76, MT_UDMA_CONN_INFRA_STATUS_SEL, 0); + for (i = 0; i < MT792x_WFSYS_INIT_RETRY_COUNT; i++) { + val = mt792xu_uhw_rr(&dev->mt76, MT_UDMA_CONN_INFRA_STATUS); + if (val & MT_UDMA_CONN_WFSYS_INIT_DONE) + break; + + msleep(100); + } + + if (i == MT792x_WFSYS_INIT_RETRY_COUNT) + return -ETIMEDOUT; + + return 0; +} +EXPORT_SYMBOL_GPL(mt792xu_wfsys_reset); + +int mt792xu_init_reset(struct mt792x_dev *dev) +{ + set_bit(MT76_RESET, &dev->mphy.state); + + wake_up(&dev->mt76.mcu.wait); + skb_queue_purge(&dev->mt76.mcu.res_q); + + mt76u_stop_rx(&dev->mt76); + mt76u_stop_tx(&dev->mt76); + + mt792xu_wfsys_reset(dev); + + clear_bit(MT76_RESET, &dev->mphy.state); + + return mt76u_resume_rx(&dev->mt76); +} +EXPORT_SYMBOL_GPL(mt792xu_init_reset); + +void mt792xu_disconnect(struct usb_interface *usb_intf) +{ + struct mt792x_dev *dev = usb_get_intfdata(usb_intf); + + cancel_work_sync(&dev->init_work); + if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state)) + return; + + mt76_unregister_device(&dev->mt76); + mt792xu_cleanup(dev); + + usb_set_intfdata(usb_intf, NULL); + usb_put_dev(interface_to_usbdev(usb_intf)); + + mt76_free_device(&dev->mt76); +} +EXPORT_SYMBOL_GPL(mt792xu_disconnect); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c index 513ab4ba41c9..4d40ec7ff57f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c @@ -474,10 +474,10 @@ mt7996_ampdu_stat_read_phy(struct mt7996_phy *phy, struct seq_file *file) static void mt7996_txbf_stat_read_phy(struct mt7996_phy *phy, struct seq_file *s) { + struct mt76_mib_stats *mib = &phy->mib; static const char * const bw[] = { "BW20", "BW40", "BW80", "BW160" }; - struct mib_stats *mib = &phy->mib; /* Tx Beamformer monitor */ seq_puts(s, "\nTx Beamformer applied PPDU counts: "); @@ -523,7 +523,7 @@ mt7996_tx_stats_show(struct seq_file *file, void *data) { struct mt7996_phy *phy = file->private; struct mt7996_dev *dev = phy->dev; - struct mib_stats *mib = &phy->mib; + struct mt76_mib_stats *mib = &phy->mib; int i; u32 attempts, success, per; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c index 534143465d9b..586e247a1e06 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c @@ -128,7 +128,7 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset) } } -static int mt7996_dma_enable(struct mt7996_dev *dev) +void mt7996_dma_start(struct mt7996_dev *dev, bool reset) { u32 hif1_ofs = 0; u32 irq_mask; @@ -136,6 +136,50 @@ static int mt7996_dma_enable(struct mt7996_dev *dev) if (dev->hif2) hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); + /* enable WFDMA Tx/Rx */ + if (!reset) { + mt76_set(dev, MT_WFDMA0_GLO_CFG, + MT_WFDMA0_GLO_CFG_TX_DMA_EN | + MT_WFDMA0_GLO_CFG_RX_DMA_EN | + MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | + MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); + + if (dev->hif2) + mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs, + MT_WFDMA0_GLO_CFG_TX_DMA_EN | + MT_WFDMA0_GLO_CFG_RX_DMA_EN | + MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | + MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); + } + + /* enable interrupts for TX/RX rings */ + irq_mask = MT_INT_MCU_CMD; + if (reset) + goto done; + + irq_mask = MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU; + + if (!dev->mphy.band_idx) + irq_mask |= MT_INT_BAND0_RX_DONE; + + if (dev->dbdc_support) + irq_mask |= MT_INT_BAND1_RX_DONE; + + if (dev->tbtc_support) + irq_mask |= MT_INT_BAND2_RX_DONE; + +done: + mt7996_irq_enable(dev, irq_mask); + mt7996_irq_disable(dev, 0); +} + +static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset) +{ + u32 hif1_ofs = 0; + + if (dev->hif2) + hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); + /* reset dma idx */ mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0); if (dev->hif2) @@ -170,13 +214,6 @@ static int mt7996_dma_enable(struct mt7996_dev *dev) mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC, MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000); - /* set WFDMA Tx/Rx */ - mt76_set(dev, MT_WFDMA0_GLO_CFG, - MT_WFDMA0_GLO_CFG_TX_DMA_EN | - MT_WFDMA0_GLO_CFG_RX_DMA_EN | - MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | - MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); - /* GLO_CFG_EXT0 */ mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0, WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD | @@ -187,12 +224,6 @@ static int mt7996_dma_enable(struct mt7996_dev *dev) WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE); if (dev->hif2) { - mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs, - MT_WFDMA0_GLO_CFG_TX_DMA_EN | - MT_WFDMA0_GLO_CFG_RX_DMA_EN | - MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | - MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); - /* GLO_CFG_EXT0 */ mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs, WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD | @@ -216,23 +247,7 @@ static int mt7996_dma_enable(struct mt7996_dev *dev) /* TODO: redirect rx ring6 interrupt to pcie0 for wed function */ } - /* enable interrupts for TX/RX rings */ - irq_mask = MT_INT_RX_DONE_MCU | - MT_INT_TX_DONE_MCU | - MT_INT_MCU_CMD; - - if (!dev->mphy.band_idx) - irq_mask |= MT_INT_BAND0_RX_DONE; - - if (dev->dbdc_support) - irq_mask |= MT_INT_BAND1_RX_DONE; - - if (dev->tbtc_support) - irq_mask |= MT_INT_BAND2_RX_DONE; - - mt7996_irq_enable(dev, irq_mask); - - return 0; + mt7996_dma_start(dev, reset); } int mt7996_dma_init(struct mt7996_dev *dev) @@ -293,7 +308,7 @@ int mt7996_dma_init(struct mt7996_dev *dev) /* event from WA */ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA], MT_RXQ_ID(MT_RXQ_MCU_WA), - MT7996_RX_MCU_RING_SIZE, + MT7996_RX_MCU_RING_SIZE_WA, MT_RX_BUF_SIZE, MT_RXQ_RING_BASE(MT_RXQ_MCU_WA)); if (ret) @@ -347,7 +362,7 @@ int mt7996_dma_init(struct mt7996_dev *dev) mt7996_poll_tx); napi_enable(&dev->mt76.tx_napi); - mt7996_dma_enable(dev); + mt7996_dma_enable(dev, false); return 0; } @@ -413,7 +428,7 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force) mt76_for_each_q_rx(&dev->mt76, i) mt76_queue_rx_reset(dev, i); - mt7996_dma_enable(dev); + mt7996_dma_enable(dev, !force); } void mt7996_dma_cleanup(struct mt7996_dev *dev) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c index 5c980534f611..26e03b28935f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c @@ -184,6 +184,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw) wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_DISCOVERY); wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER); if (!mdev->dev->of_node || !of_property_read_bool(mdev->dev->of_node, @@ -218,6 +219,8 @@ mt7996_init_wiphy(struct ieee80211_hw *hw) IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; phy->mt76->sband_5g.sband.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_1; + + ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); } mt76_set_stream_caps(phy->mt76, true); @@ -854,9 +857,7 @@ int mt7996_register_device(struct mt7996_dev *dev) INIT_WORK(&dev->rc_work, mt7996_mac_sta_rc_work); INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7996_mac_work); INIT_LIST_HEAD(&dev->sta_rc_list); - INIT_LIST_HEAD(&dev->sta_poll_list); INIT_LIST_HEAD(&dev->twt_list); - spin_lock_init(&dev->sta_poll_lock); init_waitqueue_head(&dev->reset_wait); INIT_WORK(&dev->reset_work, mt7996_mac_reset_work); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c index 9b0f6053e0fa..ac8759febe48 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c @@ -13,10 +13,6 @@ #define to_rssi(field, rcpi) ((FIELD_GET(field, rcpi) - 220) / 2) -#define HE_BITS(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_##f) -#define HE_PREP(f, m, v) le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\ - IEEE80211_RADIOTAP_HE_##f) - static const struct mt7996_dfs_radar_spec etsi_radar_specs = { .pulse_th = { 110, -10, -80, 40, 5200, 128, 5200 }, .radar_pattern = { @@ -111,9 +107,9 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev) LIST_HEAD(sta_poll_list); int i; - spin_lock_bh(&dev->sta_poll_lock); - list_splice_init(&dev->sta_poll_list, &sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); rcu_read_lock(); @@ -124,15 +120,15 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev) s8 rssi[4]; u8 bw; - spin_lock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); if (list_empty(&sta_poll_list)) { - spin_unlock_bh(&dev->sta_poll_lock); + spin_unlock_bh(&dev->mt76.sta_poll_lock); break; } msta = list_first_entry(&sta_poll_list, - struct mt7996_sta, poll_list); - list_del_init(&msta->poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + struct mt7996_sta, wcid.poll_list); + list_del_init(&msta->wcid.poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); idx = msta->wcid.idx; @@ -263,180 +259,6 @@ void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev, mt76_wr(dev, MT_WTBL_ITCR, ctrl); } -static void -mt7996_mac_decode_he_radiotap_ru(struct mt76_rx_status *status, - struct ieee80211_radiotap_he *he, - __le32 *rxv) -{ - u32 ru, offs = 0; - - ru = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC); - - status->bw = RATE_INFO_BW_HE_RU; - - switch (ru) { - case 0 ... 36: - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26; - offs = ru; - break; - case 37 ... 52: - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52; - offs = ru - 37; - break; - case 53 ... 60: - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; - offs = ru - 53; - break; - case 61 ... 64: - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242; - offs = ru - 61; - break; - case 65 ... 66: - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484; - offs = ru - 65; - break; - case 67: - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996; - break; - case 68: - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; - break; - } - - he->data1 |= HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); - he->data2 |= HE_BITS(DATA2_RU_OFFSET_KNOWN) | - le16_encode_bits(offs, - IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); -} - -static void -mt7996_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32 *rxv) -{ - struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; - static const struct ieee80211_radiotap_he_mu mu_known = { - .flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) | - HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) | - HE_BITS(MU_FLAGS1_CH1_RU_KNOWN) | - HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN), - .flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN), - }; - struct ieee80211_radiotap_he_mu *he_mu = NULL; - - status->flag |= RX_FLAG_RADIOTAP_HE_MU; - - he_mu = skb_push(skb, sizeof(mu_known)); - memcpy(he_mu, &mu_known, sizeof(mu_known)); - -#define MU_PREP(f, v) le16_encode_bits(v, IEEE80211_RADIOTAP_HE_MU_##f) - - he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status->rate_idx); - if (status->he_dcm) - he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status->he_dcm); - - he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) | - MU_PREP(FLAGS2_SIG_B_SYMS_USERS, - le32_get_bits(rxv[4], MT_CRXV_HE_NUM_USER)); - - he_mu->ru_ch1[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU0) & 0xff; - - if (status->bw >= RATE_INFO_BW_40) { - he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN); - he_mu->ru_ch2[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU1) & 0xff; - } - - if (status->bw >= RATE_INFO_BW_80) { - u32 ru_h, ru_l; - - he_mu->ru_ch1[1] = le32_get_bits(rxv[16], MT_CRXV_HE_RU2) & 0xff; - - ru_l = le32_get_bits(rxv[16], MT_CRXV_HE_RU3_L); - ru_h = le32_get_bits(rxv[17], MT_CRXV_HE_RU3_H) & 0x7; - he_mu->ru_ch2[1] = (u8)(ru_l | ru_h << 4); - } -} - -static void -mt7996_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u8 mode) -{ - struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; - static const struct ieee80211_radiotap_he known = { - .data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) | - HE_BITS(DATA1_DATA_DCM_KNOWN) | - HE_BITS(DATA1_STBC_KNOWN) | - HE_BITS(DATA1_CODING_KNOWN) | - HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) | - HE_BITS(DATA1_DOPPLER_KNOWN) | - HE_BITS(DATA1_SPTL_REUSE_KNOWN) | - HE_BITS(DATA1_BSS_COLOR_KNOWN), - .data2 = HE_BITS(DATA2_GI_KNOWN) | - HE_BITS(DATA2_TXBF_KNOWN) | - HE_BITS(DATA2_PE_DISAMBIG_KNOWN) | - HE_BITS(DATA2_TXOP_KNOWN), - }; - struct ieee80211_radiotap_he *he = NULL; - u32 ltf_size = le32_get_bits(rxv[4], MT_CRXV_HE_LTF_SIZE) + 1; - - status->flag |= RX_FLAG_RADIOTAP_HE; - - he = skb_push(skb, sizeof(known)); - memcpy(he, &known, sizeof(known)); - - he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[9]) | - HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[4]); - he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[13]); - he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[5]) | - le16_encode_bits(ltf_size, - IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE); - if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF) - he->data5 |= HE_BITS(DATA5_TXBF); - he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[9]) | - HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[9]); - - switch (mode) { - case MT_PHY_TYPE_HE_SU: - he->data1 |= HE_BITS(DATA1_FORMAT_SU) | - HE_BITS(DATA1_UL_DL_KNOWN) | - HE_BITS(DATA1_BEAM_CHANGE_KNOWN) | - HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); - - he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[8]) | - HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]); - break; - case MT_PHY_TYPE_HE_EXT_SU: - he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) | - HE_BITS(DATA1_UL_DL_KNOWN) | - HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); - - he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]); - break; - case MT_PHY_TYPE_HE_MU: - he->data1 |= HE_BITS(DATA1_FORMAT_MU) | - HE_BITS(DATA1_UL_DL_KNOWN); - - he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]); - he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[8]); - - mt7996_mac_decode_he_radiotap_ru(status, he, rxv); - mt7996_mac_decode_he_mu_radiotap(skb, rxv); - break; - case MT_PHY_TYPE_HE_TB: - he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) | - HE_BITS(DATA1_SPTL_REUSE2_KNOWN) | - HE_BITS(DATA1_SPTL_REUSE3_KNOWN) | - HE_BITS(DATA1_SPTL_REUSE4_KNOWN); - - he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, rxv[13]) | - HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, rxv[13]) | - HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, rxv[13]) | - HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, rxv[13]); - - mt7996_mac_decode_he_radiotap_ru(status, he, rxv); - break; - default: - break; - } -} - /* The HW does not translate the mac header to 802.3 for mesh point */ static int mt7996_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap) { @@ -681,10 +503,11 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb) struct mt7996_sta *msta; msta = container_of(status->wcid, struct mt7996_sta, wcid); - spin_lock_bh(&dev->sta_poll_lock); - if (list_empty(&msta->poll_list)) - list_add_tail(&msta->poll_list, &dev->sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (list_empty(&msta->wcid.poll_list)) + list_add_tail(&msta->wcid.poll_list, + &dev->mt76.sta_poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); } status->freq = mphy->chandef.chan->center_freq; @@ -836,14 +659,19 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb) skb_pull(skb, hdr_gap); if (!hdr_trans && status->amsdu && !(ieee80211_has_a4(fc) && is_mesh)) { pad_start = ieee80211_get_hdrlen_from_skb(skb); - } else if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_HDR_TRANS_ERROR) && - get_unaligned_be16(skb->data + pad_start) == ETH_P_8021Q) { + } else if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_HDR_TRANS_ERROR)) { /* When header translation failure is indicated, * the hardware will insert an extra 2-byte field * containing the data length after the protocol - * type field. + * type field. This happens either when the LLC-SNAP + * pattern did not match, or if a VLAN header was + * detected. */ - pad_start = 16; + pad_start = 12; + if (get_unaligned_be16(skb->data + pad_start) == ETH_P_8021Q) + pad_start += 4; + else + pad_start = 0; } if (pad_start) { @@ -881,7 +709,7 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb) } if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023)) - mt7996_mac_decode_he_radiotap(skb, rxv, mode); + mt76_connac3_mac_decode_he_radiotap(skb, rxv, mode); if (!status->wcid || !ieee80211_is_data_qos(fc)) return 0; @@ -1007,7 +835,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi, u8 band_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2; u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0; bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP; - struct mt7996_vif *mvif; + struct mt76_vif *mvif; u16 tx_count = 15; u32 val; bool beacon = !!(changed & (BSS_CHANGED_BEACON | @@ -1015,11 +843,11 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi, bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | BSS_CHANGED_FILS_DISCOVERY)); - mvif = vif ? (struct mt7996_vif *)vif->drv_priv : NULL; + mvif = vif ? (struct mt76_vif *)vif->drv_priv : NULL; if (mvif) { - omac_idx = mvif->mt76.omac_idx; - wmm_idx = mvif->mt76.wmm_idx; - band_idx = mvif->mt76.band_idx; + omac_idx = mvif->omac_idx; + wmm_idx = mvif->wmm_idx; + band_idx = mvif->band_idx; } if (inband_disc) { @@ -1198,7 +1026,7 @@ mt7996_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) return; msta = (struct mt7996_sta *)sta->drv_priv; - if (!test_and_set_bit(tid, &msta->ampdu_state)) + if (!test_and_set_bit(tid, &msta->wcid.ampdu_state)) ieee80211_start_tx_ba_session(sta, tid, 0); } @@ -1286,10 +1114,11 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len) continue; msta = container_of(wcid, struct mt7996_sta, wcid); - spin_lock_bh(&dev->sta_poll_lock); - if (list_empty(&msta->poll_list)) - list_add_tail(&msta->poll_list, &dev->sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&mdev->sta_poll_lock); + if (list_empty(&msta->wcid.poll_list)) + list_add_tail(&msta->wcid.poll_list, + &mdev->sta_poll_list); + spin_unlock_bh(&mdev->sta_poll_lock); continue; } @@ -1324,9 +1153,10 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len) } static bool -mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid, int pid, - __le32 *txs_data, struct mt76_sta_stats *stats) +mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid, + int pid, __le32 *txs_data) { + struct mt76_sta_stats *stats = &wcid->stats; struct ieee80211_supported_band *sband; struct mt76_dev *mdev = &dev->mt76; struct mt76_phy *mphy; @@ -1488,15 +1318,15 @@ static void mt7996_mac_add_txs(struct mt7996_dev *dev, void *data) msta = container_of(wcid, struct mt7996_sta, wcid); - mt7996_mac_add_txs_skb(dev, wcid, pid, txs_data, &msta->stats); + mt7996_mac_add_txs_skb(dev, wcid, pid, txs_data); if (!wcid->sta) goto out; - spin_lock_bh(&dev->sta_poll_lock); - if (list_empty(&msta->poll_list)) - list_add_tail(&msta->poll_list, &dev->sta_poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (list_empty(&msta->wcid.poll_list)) + list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); out: rcu_read_unlock(); @@ -1609,20 +1439,19 @@ void mt7996_mac_reset_counters(struct mt7996_phy *phy) mt7996_mcu_get_chan_mib_info(phy, true); } -void mt7996_mac_set_timing(struct mt7996_phy *phy) +void mt7996_mac_set_coverage_class(struct mt7996_phy *phy) { s16 coverage_class = phy->coverage_class; struct mt7996_dev *dev = phy->dev; struct mt7996_phy *phy2 = mt7996_phy2(dev); struct mt7996_phy *phy3 = mt7996_phy3(dev); - u32 val, reg_offset; + u32 reg_offset; u32 cck = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 231) | FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48); u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) | FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28); u8 band_idx = phy->mt76->band_idx; int offset; - bool a_band = !(phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ); if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state)) return; @@ -1635,34 +1464,12 @@ void mt7996_mac_set_timing(struct mt7996_phy *phy) coverage_class = max_t(s16, coverage_class, phy3->coverage_class); - mt76_set(dev, MT_ARB_SCR(band_idx), - MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE); - udelay(1); - offset = 3 * coverage_class; reg_offset = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, offset) | FIELD_PREP(MT_TIMEOUT_VAL_CCA, offset); mt76_wr(dev, MT_TMAC_CDTR(band_idx), cck + reg_offset); mt76_wr(dev, MT_TMAC_ODTR(band_idx), ofdm + reg_offset); - mt76_wr(dev, MT_TMAC_ICR0(band_idx), - FIELD_PREP(MT_IFS_EIFS_OFDM, a_band ? 84 : 78) | - FIELD_PREP(MT_IFS_RIFS, 2) | - FIELD_PREP(MT_IFS_SIFS, 10) | - FIELD_PREP(MT_IFS_SLOT, phy->slottime)); - - if (!a_band) - mt76_wr(dev, MT_TMAC_ICR1(band_idx), - FIELD_PREP(MT_IFS_EIFS_CCK, 314)); - - if (phy->slottime < 20 || a_band) - val = MT7996_CFEND_RATE_DEFAULT; - else - val = MT7996_CFEND_RATE_11B; - - mt76_rmw_field(dev, MT_RATE_HRCR0(band_idx), MT_RATE_HRCR0_CFEND_RATE, val); - mt76_clear(dev, MT_ARB_SCR(band_idx), - MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE); } void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band) @@ -2046,6 +1853,12 @@ void mt7996_mac_reset_work(struct work_struct *work) mt7996_wait_reset_state(dev, MT_MCU_CMD_RECOVERY_DONE); } + mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE); + mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE); + + /* enable DMA Tx/Tx and interrupt */ + mt7996_dma_start(dev, false); + clear_bit(MT76_MCU_RESET, &dev->mphy.state); clear_bit(MT76_RESET, &dev->mphy.state); if (phy2) @@ -2062,9 +1875,6 @@ void mt7996_mac_reset_work(struct work_struct *work) tasklet_schedule(&dev->mt76.irq_tasklet); - mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE); - mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE); - mt76_worker_enable(&dev->mt76.tx_worker); local_bh_disable(); @@ -2191,8 +2001,8 @@ void mt7996_reset(struct mt7996_dev *dev) void mt7996_mac_update_stats(struct mt7996_phy *phy) { + struct mt76_mib_stats *mib = &phy->mib; struct mt7996_dev *dev = phy->dev; - struct mib_stats *mib = &phy->mib; u8 band_idx = phy->mt76->band_idx; u32 cnt; int i; @@ -2339,7 +2149,7 @@ void mt7996_mac_sta_rc_work(struct work_struct *work) u32 changed; LIST_HEAD(list); - spin_lock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); list_splice_init(&dev->sta_rc_list, &list); while (!list_empty(&list)) { @@ -2347,7 +2157,7 @@ void mt7996_mac_sta_rc_work(struct work_struct *work) list_del_init(&msta->rc_list); changed = msta->changed; msta->changed = 0; - spin_unlock_bh(&dev->sta_poll_lock); + spin_unlock_bh(&dev->mt76.sta_poll_lock); sta = container_of((void *)msta, struct ieee80211_sta, drv_priv); vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv); @@ -2359,10 +2169,10 @@ void mt7996_mac_sta_rc_work(struct work_struct *work) /* TODO: smps change */ - spin_lock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); } - spin_unlock_bh(&dev->sta_poll_lock); + spin_unlock_bh(&dev->mt76.sta_poll_lock); } void mt7996_mac_work(struct work_struct *work) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.h b/drivers/net/wireless/mediatek/mt76/mt7996/mac.h index bc4e6c55373e..e629324a5617 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.h @@ -6,320 +6,7 @@ #ifndef __MT7996_MAC_H #define __MT7996_MAC_H -#define MT_CT_PARSE_LEN 72 -#define MT_CT_DMA_BUF_NUM 2 - -#define MT_RXD0_LENGTH GENMASK(15, 0) -#define MT_RXD0_PKT_TYPE GENMASK(31, 27) - -#define MT_RXD0_MESH BIT(18) -#define MT_RXD0_MHCP BIT(19) -#define MT_RXD0_NORMAL_ETH_TYPE_OFS GENMASK(22, 16) -#define MT_RXD0_NORMAL_IP_SUM BIT(23) -#define MT_RXD0_NORMAL_UDP_TCP_SUM BIT(24) - -#define MT_RXD0_SW_PKT_TYPE_MASK GENMASK(31, 16) -#define MT_RXD0_SW_PKT_TYPE_MAP 0x380F -#define MT_RXD0_SW_PKT_TYPE_FRAME 0x3801 - -/* RXD DW1 */ -#define MT_RXD1_NORMAL_WLAN_IDX GENMASK(11, 0) -#define MT_RXD1_NORMAL_GROUP_1 BIT(16) -#define MT_RXD1_NORMAL_GROUP_2 BIT(17) -#define MT_RXD1_NORMAL_GROUP_3 BIT(18) -#define MT_RXD1_NORMAL_GROUP_4 BIT(19) -#define MT_RXD1_NORMAL_GROUP_5 BIT(20) -#define MT_RXD1_NORMAL_KEY_ID GENMASK(22, 21) -#define MT_RXD1_NORMAL_CM BIT(23) -#define MT_RXD1_NORMAL_CLM BIT(24) -#define MT_RXD1_NORMAL_ICV_ERR BIT(25) -#define MT_RXD1_NORMAL_TKIP_MIC_ERR BIT(26) -#define MT_RXD1_NORMAL_BAND_IDX GENMASK(28, 27) -#define MT_RXD1_NORMAL_SPP_EN BIT(29) -#define MT_RXD1_NORMAL_ADD_OM BIT(30) -#define MT_RXD1_NORMAL_SEC_DONE BIT(31) - -/* RXD DW2 */ -#define MT_RXD2_NORMAL_BSSID GENMASK(5, 0) -#define MT_RXD2_NORMAL_MAC_HDR_LEN GENMASK(12, 8) -#define MT_RXD2_NORMAL_HDR_TRANS BIT(7) -#define MT_RXD2_NORMAL_HDR_OFFSET GENMASK(15, 13) -#define MT_RXD2_NORMAL_SEC_MODE GENMASK(20, 16) -#define MT_RXD2_NORMAL_MU_BAR BIT(21) -#define MT_RXD2_NORMAL_SW_BIT BIT(22) -#define MT_RXD2_NORMAL_AMSDU_ERR BIT(23) -#define MT_RXD2_NORMAL_MAX_LEN_ERROR BIT(24) -#define MT_RXD2_NORMAL_HDR_TRANS_ERROR BIT(25) -#define MT_RXD2_NORMAL_INT_FRAME BIT(26) -#define MT_RXD2_NORMAL_FRAG BIT(27) -#define MT_RXD2_NORMAL_NULL_FRAME BIT(28) -#define MT_RXD2_NORMAL_NDATA BIT(29) -#define MT_RXD2_NORMAL_NON_AMPDU BIT(30) -#define MT_RXD2_NORMAL_BF_REPORT BIT(31) - -/* RXD DW3 */ -#define MT_RXD3_NORMAL_RXV_SEQ GENMASK(7, 0) -#define MT_RXD3_NORMAL_CH_FREQ GENMASK(15, 8) -#define MT_RXD3_NORMAL_ADDR_TYPE GENMASK(17, 16) -#define MT_RXD3_NORMAL_U2M BIT(0) -#define MT_RXD3_NORMAL_HTC_VLD BIT(18) -#define MT_RXD3_NORMAL_BEACON_MC BIT(20) -#define MT_RXD3_NORMAL_BEACON_UC BIT(21) -#define MT_RXD3_NORMAL_CO_ANT BIT(22) -#define MT_RXD3_NORMAL_FCS_ERR BIT(24) -#define MT_RXD3_NORMAL_VLAN2ETH BIT(31) - -/* RXD DW4 */ -#define MT_RXD4_NORMAL_PAYLOAD_FORMAT GENMASK(1, 0) -#define MT_RXD4_FIRST_AMSDU_FRAME GENMASK(1, 0) -#define MT_RXD4_MID_AMSDU_FRAME BIT(1) -#define MT_RXD4_LAST_AMSDU_FRAME BIT(0) - -#define MT_RXV_HDR_BAND_IDX BIT(24) - -/* RXD GROUP4 */ -#define MT_RXD8_FRAME_CONTROL GENMASK(15, 0) - -#define MT_RXD10_SEQ_CTRL GENMASK(15, 0) -#define MT_RXD10_QOS_CTL GENMASK(31, 16) - -#define MT_RXD11_HT_CONTROL GENMASK(31, 0) - -/* P-RXV */ -#define MT_PRXV_TX_RATE GENMASK(6, 0) -#define MT_PRXV_TX_DCM BIT(4) -#define MT_PRXV_TX_ER_SU_106T BIT(5) -#define MT_PRXV_NSTS GENMASK(10, 7) -#define MT_PRXV_TXBF BIT(11) -#define MT_PRXV_HT_AD_CODE BIT(12) -#define MT_PRXV_HE_RU_ALLOC GENMASK(30, 22) -#define MT_PRXV_RCPI3 GENMASK(31, 24) -#define MT_PRXV_RCPI2 GENMASK(23, 16) -#define MT_PRXV_RCPI1 GENMASK(15, 8) -#define MT_PRXV_RCPI0 GENMASK(7, 0) -#define MT_PRXV_HT_SHORT_GI GENMASK(4, 3) -#define MT_PRXV_HT_STBC GENMASK(10, 9) -#define MT_PRXV_TX_MODE GENMASK(14, 11) -#define MT_PRXV_FRAME_MODE GENMASK(2, 0) -#define MT_PRXV_DCM BIT(5) - -/* C-RXV */ -#define MT_CRXV_HE_NUM_USER GENMASK(26, 20) -#define MT_CRXV_HE_LTF_SIZE GENMASK(28, 27) -#define MT_CRXV_HE_LDPC_EXT_SYM BIT(30) - -#define MT_CRXV_HE_PE_DISAMBIG BIT(1) -#define MT_CRXV_HE_UPLINK BIT(2) - -#define MT_CRXV_HE_MU_AID GENMASK(27, 17) -#define MT_CRXV_HE_BEAM_CHNG BIT(29) - -#define MT_CRXV_HE_DOPPLER BIT(0) -#define MT_CRXV_HE_BSS_COLOR GENMASK(15, 10) -#define MT_CRXV_HE_TXOP_DUR GENMASK(19, 17) - -#define MT_CRXV_HE_SR_MASK GENMASK(11, 8) -#define MT_CRXV_HE_SR1_MASK GENMASK(16, 12) -#define MT_CRXV_HE_SR2_MASK GENMASK(20, 17) -#define MT_CRXV_HE_SR3_MASK GENMASK(24, 21) - -#define MT_CRXV_HE_RU0 GENMASK(8, 0) -#define MT_CRXV_HE_RU1 GENMASK(17, 9) -#define MT_CRXV_HE_RU2 GENMASK(26, 18) -#define MT_CRXV_HE_RU3_L GENMASK(31, 27) -#define MT_CRXV_HE_RU3_H GENMASK(3, 0) - -enum tx_header_format { - MT_HDR_FORMAT_802_3, - MT_HDR_FORMAT_CMD, - MT_HDR_FORMAT_802_11, - MT_HDR_FORMAT_802_11_EXT, -}; - -enum tx_pkt_type { - MT_TX_TYPE_CT, - MT_TX_TYPE_SF, - MT_TX_TYPE_CMD, - MT_TX_TYPE_FW, -}; - -enum tx_port_idx { - MT_TX_PORT_IDX_LMAC, - MT_TX_PORT_IDX_MCU -}; - -enum tx_mcu_port_q_idx { - MT_TX_MCU_PORT_RX_Q0 = 0x20, - MT_TX_MCU_PORT_RX_Q1, - MT_TX_MCU_PORT_RX_Q2, - MT_TX_MCU_PORT_RX_Q3, - MT_TX_MCU_PORT_RX_FWDL = 0x3e -}; - -enum tx_mgnt_type { - MT_TX_NORMAL, - MT_TX_TIMING, - MT_TX_ADDBA, -}; - -#define MT_CT_INFO_APPLY_TXD BIT(0) -#define MT_CT_INFO_COPY_HOST_TXD_ALL BIT(1) -#define MT_CT_INFO_MGMT_FRAME BIT(2) -#define MT_CT_INFO_NONE_CIPHER_FRAME BIT(3) -#define MT_CT_INFO_HSR2_TX BIT(4) -#define MT_CT_INFO_FROM_HOST BIT(7) - -#define MT_TXD_SIZE (8 * 4) - -#define MT_TXD0_Q_IDX GENMASK(31, 25) -#define MT_TXD0_PKT_FMT GENMASK(24, 23) -#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16) -#define MT_TXD0_TX_BYTES GENMASK(15, 0) - -#define MT_TXD1_FIXED_RATE BIT(31) -#define MT_TXD1_OWN_MAC GENMASK(30, 25) -#define MT_TXD1_TID GENMASK(24, 21) -#define MT_TXD1_BIP BIT(24) -#define MT_TXD1_ETH_802_3 BIT(20) -#define MT_TXD1_HDR_INFO GENMASK(20, 16) -#define MT_TXD1_HDR_FORMAT GENMASK(15, 14) -#define MT_TXD1_TGID GENMASK(13, 12) -#define MT_TXD1_WLAN_IDX GENMASK(11, 0) - -#define MT_TXD2_POWER_OFFSET GENMASK(31, 26) -#define MT_TXD2_MAX_TX_TIME GENMASK(25, 16) -#define MT_TXD2_FRAG GENMASK(15, 14) -#define MT_TXD2_HTC_VLD BIT(13) -#define MT_TXD2_DURATION BIT(12) -#define MT_TXD2_HDR_PAD GENMASK(11, 10) -#define MT_TXD2_RTS BIT(9) -#define MT_TXD2_OWN_MAC_MAP BIT(8) -#define MT_TXD2_BF_TYPE GENMASK(6, 7) -#define MT_TXD2_FRAME_TYPE GENMASK(5, 4) -#define MT_TXD2_SUB_TYPE GENMASK(3, 0) - -#define MT_TXD3_SN_VALID BIT(31) -#define MT_TXD3_PN_VALID BIT(30) -#define MT_TXD3_SW_POWER_MGMT BIT(29) -#define MT_TXD3_BA_DISABLE BIT(28) -#define MT_TXD3_SEQ GENMASK(27, 16) -#define MT_TXD3_REM_TX_COUNT GENMASK(15, 11) -#define MT_TXD3_TX_COUNT GENMASK(10, 6) -#define MT_TXD3_HW_AMSDU BIT(5) -#define MT_TXD3_BCM BIT(4) -#define MT_TXD3_EEOSP BIT(3) -#define MT_TXD3_EMRD BIT(2) -#define MT_TXD3_PROTECT_FRAME BIT(1) -#define MT_TXD3_NO_ACK BIT(0) - -#define MT_TXD4_PN_LOW GENMASK(31, 0) - -#define MT_TXD5_PN_HIGH GENMASK(31, 16) -#define MT_TXD5_FL BIT(15) -#define MT_TXD5_BYPASS_TBB BIT(14) -#define MT_TXD5_BYPASS_RBB BIT(13) -#define MT_TXD5_BSS_COLOR_ZERO BIT(12) -#define MT_TXD5_TX_STATUS_HOST BIT(10) -#define MT_TXD5_TX_STATUS_MCU BIT(9) -#define MT_TXD5_TX_STATUS_FMT BIT(8) -#define MT_TXD5_PID GENMASK(7, 0) - -#define MT_TXD6_TX_SRC GENMASK(31, 30) -#define MT_TXD6_VTA BIT(28) -#define MT_TXD6_BW GENMASK(25, 22) -#define MT_TXD6_TX_RATE GENMASK(21, 16) -#define MT_TXD6_TIMESTAMP_OFS_EN BIT(15) -#define MT_TXD6_TIMESTAMP_OFS_IDX GENMASK(14, 10) -#define MT_TXD6_MSDU_CNT GENMASK(9, 4) -#define MT_TXD6_DIS_MAT BIT(3) -#define MT_TXD6_DAS BIT(2) -#define MT_TXD6_AMSDU_CAP BIT(1) - -#define MT_TXD7_TXD_LEN GENMASK(31, 30) -#define MT_TXD7_IP_SUM BIT(29) -#define MT_TXD7_DROP_BY_SDO BIT(28) -#define MT_TXD7_MAC_TXD BIT(27) -#define MT_TXD7_CTXD BIT(26) -#define MT_TXD7_CTXD_CNT GENMASK(25, 22) -#define MT_TXD7_UDP_TCP_SUM BIT(15) -#define MT_TXD7_TX_TIME GENMASK(9, 0) - -#define MT_TX_RATE_STBC BIT(14) -#define MT_TX_RATE_NSS GENMASK(13, 10) -#define MT_TX_RATE_MODE GENMASK(9, 6) -#define MT_TX_RATE_SU_EXT_TONE BIT(5) -#define MT_TX_RATE_DCM BIT(4) -/* VHT/HE only use bits 0-3 */ -#define MT_TX_RATE_IDX GENMASK(5, 0) - -#define MT_TXFREE0_PKT_TYPE GENMASK(31, 27) -#define MT_TXFREE0_MSDU_CNT GENMASK(25, 16) -#define MT_TXFREE0_RX_BYTE GENMASK(15, 0) - -#define MT_TXFREE1_VER GENMASK(18, 16) - -#define MT_TXFREE_INFO_PAIR BIT(31) -#define MT_TXFREE_INFO_HEADER BIT(30) -#define MT_TXFREE_INFO_WLAN_ID GENMASK(23, 12) -#define MT_TXFREE_INFO_MSDU_ID GENMASK(14, 0) - -#define MT_TXS0_BW GENMASK(31, 29) -#define MT_TXS0_TID GENMASK(28, 26) -#define MT_TXS0_AMPDU BIT(25) -#define MT_TXS0_TXS_FORMAT GENMASK(24, 23) -#define MT_TXS0_BA_ERROR BIT(22) -#define MT_TXS0_PS_FLAG BIT(21) -#define MT_TXS0_TXOP_TIMEOUT BIT(20) -#define MT_TXS0_BIP_ERROR BIT(19) - -#define MT_TXS0_QUEUE_TIMEOUT BIT(18) -#define MT_TXS0_RTS_TIMEOUT BIT(17) -#define MT_TXS0_ACK_TIMEOUT BIT(16) -#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16) - -#define MT_TXS0_TX_STATUS_HOST BIT(15) -#define MT_TXS0_TX_STATUS_MCU BIT(14) -#define MT_TXS0_TX_RATE GENMASK(13, 0) - -#define MT_TXS1_SEQNO GENMASK(31, 20) -#define MT_TXS1_RESP_RATE GENMASK(19, 16) -#define MT_TXS1_RXV_SEQNO GENMASK(15, 8) -#define MT_TXS1_TX_POWER_DBM GENMASK(7, 0) - -#define MT_TXS2_BF_STATUS GENMASK(31, 30) -#define MT_TXS2_BAND GENMASK(29, 28) -#define MT_TXS2_WCID GENMASK(27, 16) -#define MT_TXS2_TX_DELAY GENMASK(15, 0) - -#define MT_TXS3_PID GENMASK(31, 24) -#define MT_TXS3_RATE_STBC BIT(7) -#define MT_TXS3_FIXED_RATE BIT(6) -#define MT_TXS3_SRC GENMASK(5, 4) -#define MT_TXS3_SHARED_ANTENNA BIT(3) -#define MT_TXS3_LAST_TX_RATE GENMASK(2, 0) - -#define MT_TXS4_TIMESTAMP GENMASK(31, 0) - -#define MT_TXS5_F0_FINAL_MPDU BIT(31) -#define MT_TXS5_F0_QOS BIT(30) -#define MT_TXS5_F0_TX_COUNT GENMASK(29, 25) -#define MT_TXS5_F0_FRONT_TIME GENMASK(24, 0) -#define MT_TXS5_F1_MPDU_TX_COUNT GENMASK(31, 24) -#define MT_TXS5_F1_MPDU_TX_BYTES GENMASK(23, 0) - -#define MT_TXS6_F0_NOISE_3 GENMASK(31, 24) -#define MT_TXS6_F0_NOISE_2 GENMASK(23, 16) -#define MT_TXS6_F0_NOISE_1 GENMASK(15, 8) -#define MT_TXS6_F0_NOISE_0 GENMASK(7, 0) -#define MT_TXS6_F1_MPDU_FAIL_COUNT GENMASK(31, 24) -#define MT_TXS6_F1_MPDU_FAIL_BYTES GENMASK(23, 0) - -#define MT_TXS7_F0_RCPI_3 GENMASK(31, 24) -#define MT_TXS7_F0_RCPI_2 GENMASK(23, 16) -#define MT_TXS7_F0_RCPI_1 GENMASK(15, 8) -#define MT_TXS7_F0_RCPI_0 GENMASK(7, 0) -#define MT_TXS7_F1_MPDU_RETRY_COUNT GENMASK(31, 24) -#define MT_TXS7_F1_MPDU_RETRY_BYTES GENMASK(23, 0) +#include "../mt76_connac3_mac.h" struct mt7996_dfs_pulse { u32 max_width; /* us */ diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index f306e9c50ea3..c3a479dc3f53 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -43,6 +43,10 @@ int mt7996_run(struct ieee80211_hw *hw) if (ret) goto out; + ret = mt7996_mcu_set_radio_en(phy, true); + if (ret) + goto out; + ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_RX_PATH); if (ret) goto out; @@ -82,6 +86,8 @@ static void mt7996_stop(struct ieee80211_hw *hw) mutex_lock(&dev->mt76.mutex); + mt7996_mcu_set_radio_en(phy, false); + clear_bit(MT76_STATE_RUNNING, &phy->mt76->state); mutex_unlock(&dev->mt76.mutex); @@ -190,17 +196,13 @@ static int mt7996_add_interface(struct ieee80211_hw *hw, if (ret) goto out; - ret = mt7996_mcu_set_radio_en(phy, true); - if (ret) - goto out; - dev->mt76.vif_mask |= BIT_ULL(mvif->mt76.idx); phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx); idx = MT7996_WTBL_RESERVED - mvif->mt76.idx; INIT_LIST_HEAD(&mvif->sta.rc_list); - INIT_LIST_HEAD(&mvif->sta.poll_list); + INIT_LIST_HEAD(&mvif->sta.wcid.poll_list); mvif->sta.wcid.idx = idx; mvif->sta.wcid.phy_idx = band_idx; mvif->sta.wcid.hw_key_idx = -1; @@ -221,9 +223,9 @@ static int mt7996_add_interface(struct ieee80211_hw *hw, vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR; if (phy->mt76->chandef.chan->band != NL80211_BAND_2GHZ) - mvif->basic_rates_idx = MT7996_BASIC_RATES_TBL + 4; + mvif->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL + 4; else - mvif->basic_rates_idx = MT7996_BASIC_RATES_TBL; + mvif->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL; mt7996_init_bitrate_mask(vif); @@ -253,7 +255,6 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw, phy->monitor_vif = NULL; mt7996_mcu_add_dev_info(phy, vif, false); - mt7996_mcu_set_radio_en(phy, false); rcu_assign_pointer(dev->mt76.wcid[idx], NULL); @@ -262,10 +263,10 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw, phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx); mutex_unlock(&dev->mt76.mutex); - spin_lock_bh(&dev->sta_poll_lock); - if (!list_empty(&msta->poll_list)) - list_del_init(&msta->poll_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (!list_empty(&msta->wcid.poll_list)) + list_del_init(&msta->wcid.poll_list); + spin_unlock_bh(&dev->mt76.sta_poll_lock); mt76_packet_id_flush(&dev->mt76, &msta->wcid); } @@ -286,7 +287,6 @@ int mt7996_set_channel(struct mt7996_phy *phy) if (ret) goto out; - mt7996_mac_set_timing(phy); ret = mt7996_dfs_init_radar_detector(phy); mt7996_mac_cca_stats_reset(phy); @@ -505,7 +505,7 @@ static u8 mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif, bool beacon, bool mcast) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; struct mt76_phy *mphy = hw->priv; u16 rate; u8 i, idx, ht; @@ -517,7 +517,7 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct mt7996_dev *dev = mt7996_hw_dev(hw); /* must odd index */ - idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->mt76.idx % 20); + idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->idx % 20); mt7996_mac_set_fixed_rate_table(dev, idx, rate); return idx; } @@ -530,12 +530,32 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return mvif->basic_rates_idx; } +static void +mt7996_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info) +{ + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt7996_dev *dev = mt7996_hw_dev(hw); + u8 band = mvif->mt76.band_idx; + u32 *mu; + + mu = (u32 *)info->mu_group.membership; + mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_VLD0(band), mu[0]); + mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_VLD1(band), mu[1]); + + mu = (u32 *)info->mu_group.position; + mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS0(band), mu[0]); + mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS1(band), mu[1]); + mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS2(band), mu[2]); + mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS3(band), mu[3]); +} + static void mt7996_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u64 changed) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; struct mt7996_phy *phy = mt7996_hw_phy(hw); struct mt7996_dev *dev = mt7996_hw_dev(hw); @@ -563,7 +583,7 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw, if (slottime != phy->slottime) { phy->slottime = slottime; - mt7996_mac_set_timing(phy); + mt7996_mcu_set_timing(phy, vif); } } @@ -602,6 +622,9 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw, changed & BSS_CHANGED_FILS_DISCOVERY) mt7996_mcu_beacon_inband_discov(dev, vif, changed); + if (changed & BSS_CHANGED_MU_GROUPS) + mt7996_update_mu_group(hw, vif, info); + mutex_unlock(&dev->mt76.mutex); } @@ -631,7 +654,7 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, return -ENOSPC; INIT_LIST_HEAD(&msta->rc_list); - INIT_LIST_HEAD(&msta->poll_list); + INIT_LIST_HEAD(&msta->wcid.poll_list); msta->vif = mvif; msta->wcid.sta = 1; msta->wcid.idx = idx; @@ -666,12 +689,12 @@ void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++) mt7996_mac_twt_teardown_flow(dev, msta, i); - spin_lock_bh(&dev->sta_poll_lock); - if (!list_empty(&msta->poll_list)) - list_del_init(&msta->poll_list); + spin_lock_bh(&mdev->sta_poll_lock); + if (!list_empty(&msta->wcid.poll_list)) + list_del_init(&msta->wcid.poll_list); if (!list_empty(&msta->rc_list)) list_del_init(&msta->rc_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_unlock_bh(&mdev->sta_poll_lock); } static void mt7996_tx(struct ieee80211_hw *hw, @@ -751,16 +774,16 @@ mt7996_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: mtxq->aggr = false; - clear_bit(tid, &msta->ampdu_state); + clear_bit(tid, &msta->wcid.ampdu_state); ret = mt7996_mcu_add_tx_ba(dev, params, false); break; case IEEE80211_AMPDU_TX_START: - set_bit(tid, &msta->ampdu_state); + set_bit(tid, &msta->wcid.ampdu_state); ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; break; case IEEE80211_AMPDU_TX_STOP_CONT: mtxq->aggr = false; - clear_bit(tid, &msta->ampdu_state); + clear_bit(tid, &msta->wcid.ampdu_state); ret = mt7996_mcu_add_tx_ba(dev, params, false); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; @@ -792,7 +815,7 @@ mt7996_get_stats(struct ieee80211_hw *hw, { struct mt7996_phy *phy = mt7996_hw_phy(hw); struct mt7996_dev *dev = mt7996_hw_dev(hw); - struct mib_stats *mib = &phy->mib; + struct mt76_mib_stats *mib = &phy->mib; mutex_lock(&dev->mt76.mutex); @@ -903,7 +926,7 @@ mt7996_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) mutex_lock(&dev->mt76.mutex); phy->coverage_class = max_t(s16, coverage_class, 0); - mt7996_mac_set_timing(phy); + mt7996_mac_set_coverage_class(phy); mutex_unlock(&dev->mt76.mutex); } @@ -952,18 +975,19 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw, struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; struct rate_info *txrate = &msta->wcid.rate; - if (!txrate->legacy && !txrate->flags) - return; - - if (txrate->legacy) { - sinfo->txrate.legacy = txrate->legacy; - } else { - sinfo->txrate.mcs = txrate->mcs; - sinfo->txrate.nss = txrate->nss; - sinfo->txrate.bw = txrate->bw; - sinfo->txrate.he_gi = txrate->he_gi; - sinfo->txrate.he_dcm = txrate->he_dcm; - sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc; + if (txrate->legacy || txrate->flags) { + if (txrate->legacy) { + sinfo->txrate.legacy = txrate->legacy; + } else { + sinfo->txrate.mcs = txrate->mcs; + sinfo->txrate.nss = txrate->nss; + sinfo->txrate.bw = txrate->bw; + sinfo->txrate.he_gi = txrate->he_gi; + sinfo->txrate.he_dcm = txrate->he_dcm; + sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc; + } + sinfo->txrate.flags = txrate->flags; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } sinfo->txrate.flags = txrate->flags; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); @@ -981,11 +1005,11 @@ static void mt7996_sta_rc_work(void *data, struct ieee80211_sta *sta) struct mt7996_dev *dev = msta->vif->phy->dev; u32 *changed = data; - spin_lock_bh(&dev->sta_poll_lock); + spin_lock_bh(&dev->mt76.sta_poll_lock); msta->changed |= *changed; if (list_empty(&msta->rc_list)) list_add_tail(&msta->rc_list, &dev->sta_rc_list); - spin_unlock_bh(&dev->sta_poll_lock); + spin_unlock_bh(&dev->mt76.sta_poll_lock); } static void mt7996_sta_rc_update(struct ieee80211_hw *hw, @@ -1153,6 +1177,10 @@ static const char mt7996_gstrings_stats[][ETH_GSTRING_LEN] = { "v_tx_mcs_11", "v_tx_mcs_12", "v_tx_mcs_13", + "v_tx_nss_1", + "v_tx_nss_2", + "v_tx_nss_3", + "v_tx_nss_4", }; #define MT7996_SSTATS_LEN ARRAY_SIZE(mt7996_gstrings_stats) @@ -1186,7 +1214,7 @@ static void mt7996_ethtool_worker(void *wi_data, struct ieee80211_sta *sta) if (msta->vif->mt76.idx != wi->idx) return; - mt76_ethtool_worker(wi, &msta->stats, true); + mt76_ethtool_worker(wi, &msta->wcid.stats, true); } static @@ -1197,11 +1225,11 @@ void mt7996_get_et_stats(struct ieee80211_hw *hw, struct mt7996_dev *dev = mt7996_hw_dev(hw); struct mt7996_phy *phy = mt7996_hw_phy(hw); struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt76_mib_stats *mib = &phy->mib; struct mt76_ethtool_worker_info wi = { .data = data, .idx = mvif->mt76.idx, }; - struct mib_stats *mib = &phy->mib; /* See mt7996_ampdu_stat_read_phy, etc */ int i, ei = 0; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index 88e2f9d0e513..4a30db49ef33 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -339,7 +339,11 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb) if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys)) return; - mphy = dev->mt76.phys[r->band_idx]; + if (dev->rdd2_phy && r->band_idx == MT_RX_SEL2) + mphy = dev->rdd2_phy->mt76; + else + mphy = dev->mt76.phys[r->band_idx]; + if (!mphy) return; @@ -600,7 +604,7 @@ static void mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, struct mt7996_phy *phy) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; struct bss_rate_tlv *bmc; struct cfg80211_chan_def *chandef = &phy->mt76->chandef; enum nl80211_band band = chandef->chan->band; @@ -701,6 +705,34 @@ mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif, sizeof(req), true); } +static void +mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct ieee80211_vif *vif) +{ + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt7996_phy *phy = mvif->phy; + struct bss_ifs_time_tlv *ifs_time; + struct tlv *tlv; + bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ; + + tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_IFS_TIME, sizeof(*ifs_time)); + + ifs_time = (struct bss_ifs_time_tlv *)tlv; + ifs_time->slot_valid = true; + ifs_time->sifs_valid = true; + ifs_time->rifs_valid = true; + ifs_time->eifs_valid = true; + + ifs_time->slot_time = cpu_to_le16(phy->slottime); + ifs_time->sifs_time = cpu_to_le16(10); + ifs_time->rifs_time = cpu_to_le16(2); + ifs_time->eifs_time = cpu_to_le16(is_2ghz ? 78 : 84); + + if (is_2ghz) { + ifs_time->eifs_cck_valid = true; + ifs_time->eifs_cck_time = cpu_to_le16(314); + } +} + static int mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, @@ -712,6 +744,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, struct cfg80211_chan_def *chandef = &phy->chandef; struct mt76_connac_bss_basic_tlv *bss; u32 type = CONNECTION_INFRA_AP; + u16 sta_wlan_idx = wlan_idx; struct tlv *tlv; int idx; @@ -731,7 +764,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, struct mt76_wcid *wcid; wcid = (struct mt76_wcid *)sta->drv_priv; - wlan_idx = wcid->idx; + sta_wlan_idx = wcid->idx; } rcu_read_unlock(); } @@ -751,7 +784,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int); bss->dtim_period = vif->bss_conf.dtim_period; bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx); - bss->sta_idx = cpu_to_le16(wlan_idx); + bss->sta_idx = cpu_to_le16(sta_wlan_idx); bss->conn_type = cpu_to_le32(type); bss->omac_idx = mvif->omac_idx; bss->band_idx = mvif->band_idx; @@ -825,6 +858,7 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy, mt7996_mcu_bss_bmc_tlv(skb, vif, phy); mt7996_mcu_bss_ra_tlv(skb, vif, phy); mt7996_mcu_bss_txcmd_tlv(skb, true); + mt7996_mcu_bss_ifs_timing_tlv(skb, vif); if (vif->bss_conf.he_support) mt7996_mcu_bss_he_tlv(skb, vif, phy); @@ -837,6 +871,23 @@ out: MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); } +int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif) +{ + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt7996_dev *dev = phy->dev; + struct sk_buff *skb; + + skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, + MT7996_BSS_UPDATE_MAX_SIZE); + if (IS_ERR(skb)) + return PTR_ERR(skb); + + mt7996_mcu_bss_ifs_timing_tlv(skb, vif); + + return mt76_mcu_skb_send_msg(&dev->mt76, skb, + MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); +} + static int mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif, struct ieee80211_ampdu_params *params, @@ -1050,6 +1101,59 @@ mt7996_mcu_sta_amsdu_tlv(struct mt7996_dev *dev, struct sk_buff *skb, } } +static void +mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb, + struct ieee80211_vif *vif, struct ieee80211_sta *sta) +{ + struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem; + struct sta_rec_muru *muru; + struct tlv *tlv; + + if (vif->type != NL80211_IFTYPE_STATION && + vif->type != NL80211_IFTYPE_AP) + return; + + tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_MURU, sizeof(*muru)); + + muru = (struct sta_rec_muru *)tlv; + muru->cfg.mimo_dl_en = vif->bss_conf.eht_mu_beamformer || + vif->bss_conf.he_mu_beamformer || + vif->bss_conf.vht_mu_beamformer || + vif->bss_conf.vht_mu_beamformee; + muru->cfg.ofdma_dl_en = true; + + if (sta->deflink.vht_cap.vht_supported) + muru->mimo_dl.vht_mu_bfee = + !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE); + + if (!sta->deflink.he_cap.has_he) + return; + + muru->mimo_dl.partial_bw_dl_mimo = + HE_PHY(CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO, elem->phy_cap_info[6]); + + muru->mimo_ul.full_ul_mimo = + HE_PHY(CAP2_UL_MU_FULL_MU_MIMO, elem->phy_cap_info[2]); + muru->mimo_ul.partial_ul_mimo = + HE_PHY(CAP2_UL_MU_PARTIAL_MU_MIMO, elem->phy_cap_info[2]); + + muru->ofdma_dl.punc_pream_rx = + HE_PHY(CAP1_PREAMBLE_PUNC_RX_MASK, elem->phy_cap_info[1]); + muru->ofdma_dl.he_20m_in_40m_2g = + HE_PHY(CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G, elem->phy_cap_info[8]); + muru->ofdma_dl.he_20m_in_160m = + HE_PHY(CAP8_20MHZ_IN_160MHZ_HE_PPDU, elem->phy_cap_info[8]); + muru->ofdma_dl.he_80m_in_160m = + HE_PHY(CAP8_80MHZ_IN_160MHZ_HE_PPDU, elem->phy_cap_info[8]); + + muru->ofdma_ul.t_frame_dur = + HE_MAC(CAP1_TF_MAC_PAD_DUR_MASK, elem->mac_cap_info[1]); + muru->ofdma_ul.mu_cascading = + HE_MAC(CAP2_MU_CASCADING, elem->mac_cap_info[2]); + muru->ofdma_ul.uo_ra = + HE_MAC(CAP3_OFDMA_RA, elem->mac_cap_info[3]); +} + static inline bool mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif, struct ieee80211_sta *sta, bool bfee) @@ -1727,7 +1831,8 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif, mt7996_mcu_sta_he_6g_tlv(skb, sta); /* starec eht */ mt7996_mcu_sta_eht_tlv(skb, sta); - /* TODO: starec muru */ + /* starec muru */ + mt7996_mcu_sta_muru_tlv(dev, skb, vif, sta); /* starec bfee */ mt7996_mcu_sta_bfee_tlv(dev, skb, vif, sta); /* starec hdr trans */ @@ -2155,7 +2260,7 @@ out: static int mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev, const struct mt7996_fw_trailer *hdr, - const u8 *data, bool is_wa) + const u8 *data, enum mt7996_ram_type type) { int i, offset = 0; u32 override = 0, option = 0; @@ -2167,8 +2272,10 @@ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev, region = (const struct mt7996_fw_region *)((const u8 *)hdr - (hdr->n_region - i) * sizeof(*region)); + /* DSP and WA use same mode */ mode = mt76_connac_mcu_gen_dl_mode(&dev->mt76, - region->feature_set, is_wa); + region->feature_set, + type != MT7996_RAM_TYPE_WM); len = le32_to_cpu(region->len); addr = le32_to_cpu(region->addr); @@ -2195,19 +2302,22 @@ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev, if (override) option |= FW_START_OVERRIDE; - if (is_wa) + if (type == MT7996_RAM_TYPE_WA) option |= FW_START_WORKING_PDA_CR4; + else if (type == MT7996_RAM_TYPE_DSP) + option |= FW_START_WORKING_PDA_DSP; return mt76_connac_mcu_start_firmware(&dev->mt76, override, option); } -static int mt7996_load_ram(struct mt7996_dev *dev) +static int __mt7996_load_ram(struct mt7996_dev *dev, const char *fw_type, + const char *fw_file, enum mt7996_ram_type ram_type) { const struct mt7996_fw_trailer *hdr; const struct firmware *fw; int ret; - ret = request_firmware(&fw, MT7996_FIRMWARE_WM, dev->mt76.dev); + ret = request_firmware(&fw, fw_file, dev->mt76.dev); if (ret) return ret; @@ -2217,37 +2327,13 @@ static int mt7996_load_ram(struct mt7996_dev *dev) goto out; } - hdr = (const struct mt7996_fw_trailer *)(fw->data + fw->size - sizeof(*hdr)); + hdr = (const void *)(fw->data + fw->size - sizeof(*hdr)); + dev_info(dev->mt76.dev, "%s Firmware Version: %.10s, Build Time: %.15s\n", + fw_type, hdr->fw_ver, hdr->build_date); - dev_info(dev->mt76.dev, "WM Firmware Version: %.10s, Build Time: %.15s\n", - hdr->fw_ver, hdr->build_date); - - ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, false); + ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, ram_type); if (ret) { - dev_err(dev->mt76.dev, "Failed to start WM firmware\n"); - goto out; - } - - release_firmware(fw); - - ret = request_firmware(&fw, MT7996_FIRMWARE_WA, dev->mt76.dev); - if (ret) - return ret; - - if (!fw || !fw->data || fw->size < sizeof(*hdr)) { - dev_err(dev->mt76.dev, "Invalid firmware\n"); - ret = -EINVAL; - goto out; - } - - hdr = (const struct mt7996_fw_trailer *)(fw->data + fw->size - sizeof(*hdr)); - - dev_info(dev->mt76.dev, "WA Firmware Version: %.10s, Build Time: %.15s\n", - hdr->fw_ver, hdr->build_date); - - ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, true); - if (ret) { - dev_err(dev->mt76.dev, "Failed to start WA firmware\n"); + dev_err(dev->mt76.dev, "Failed to start %s firmware\n", fw_type); goto out; } @@ -2261,6 +2347,24 @@ out: return ret; } +static int mt7996_load_ram(struct mt7996_dev *dev) +{ + int ret; + + ret = __mt7996_load_ram(dev, "WM", MT7996_FIRMWARE_WM, + MT7996_RAM_TYPE_WM); + if (ret) + return ret; + + ret = __mt7996_load_ram(dev, "DSP", MT7996_FIRMWARE_DSP, + MT7996_RAM_TYPE_DSP); + if (ret) + return ret; + + return __mt7996_load_ram(dev, "WA", MT7996_FIRMWARE_WA, + MT7996_RAM_TYPE_WA); +} + static int mt7996_firmware_state(struct mt7996_dev *dev, bool wa) { diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h index d7075a4d0667..078f82858621 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h @@ -317,6 +317,22 @@ struct bss_sec_tlv { u8 __rsv2[1]; } __packed; +struct bss_ifs_time_tlv { + __le16 tag; + __le16 len; + u8 slot_valid; + u8 sifs_valid; + u8 rifs_valid; + u8 eifs_valid; + __le16 slot_time; + __le16 sifs_time; + __le16 rifs_time; + __le16 eifs_time; + u8 eifs_cck_valid; + u8 rsv; + __le16 eifs_cck_time; +} __packed; + struct bss_power_save { __le16 tag; __le16 len; @@ -552,6 +568,7 @@ enum { sizeof(struct bss_txcmd_tlv) + \ sizeof(struct bss_power_save) + \ sizeof(struct bss_sec_tlv) + \ + sizeof(struct bss_ifs_time_tlv) + \ sizeof(struct bss_mld_tlv)) #define MT7996_STA_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \ diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index 4d7dcb95a620..7354e5cf8e67 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -26,15 +26,17 @@ #define MT7996_RX_RING_SIZE 1536 #define MT7996_RX_MCU_RING_SIZE 512 +#define MT7996_RX_MCU_RING_SIZE_WA 1024 #define MT7996_FIRMWARE_WA "mediatek/mt7996/mt7996_wa.bin" #define MT7996_FIRMWARE_WM "mediatek/mt7996/mt7996_wm.bin" +#define MT7996_FIRMWARE_DSP "mediatek/mt7996/mt7996_dsp.bin" #define MT7996_ROM_PATCH "mediatek/mt7996/mt7996_rom_patch.bin" #define MT7996_EEPROM_DEFAULT "mediatek/mt7996/mt7996_eeprom.bin" #define MT7996_EEPROM_SIZE 7680 #define MT7996_EEPROM_BLOCK_SIZE 16 -#define MT7996_TOKEN_SIZE 8192 +#define MT7996_TOKEN_SIZE 16384 #define MT7996_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */ #define MT7996_CFEND_RATE_11B 0x03 /* 11B LP, 11M */ @@ -52,6 +54,12 @@ struct mt7996_sta; struct mt7996_dfs_pulse; struct mt7996_dfs_pattern; +enum mt7996_ram_type { + MT7996_RAM_TYPE_WM, + MT7996_RAM_TYPE_WA, + MT7996_RAM_TYPE_DSP, +}; + enum mt7996_txq_id { MT7996_TXQ_FWDL = 16, MT7996_TXQ_MCU_WM, @@ -95,7 +103,6 @@ struct mt7996_sta { struct mt7996_vif *vif; - struct list_head poll_list; struct list_head rc_list; u32 airtime_ac[8]; @@ -104,9 +111,6 @@ struct mt7996_sta { unsigned long changed; unsigned long jiffies; - unsigned long ampdu_state; - - struct mt76_sta_stats stats; struct mt76_connac_sta_key_conf bip; @@ -124,64 +128,6 @@ struct mt7996_vif { struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; struct cfg80211_bitrate_mask bitrate_mask; - - u8 basic_rates_idx; - u8 mcast_rates_idx; - u8 beacon_rates_idx; -}; - -/* per-phy stats. */ -struct mib_stats { - u32 ack_fail_cnt; - u32 fcs_err_cnt; - u32 rts_cnt; - u32 rts_retries_cnt; - u32 ba_miss_cnt; - u32 tx_mu_bf_cnt; - u32 tx_mu_mpdu_cnt; - u32 tx_mu_acked_mpdu_cnt; - u32 tx_su_acked_mpdu_cnt; - u32 tx_bf_ibf_ppdu_cnt; - u32 tx_bf_ebf_ppdu_cnt; - - u32 tx_bf_rx_fb_all_cnt; - u32 tx_bf_rx_fb_eht_cnt; - u32 tx_bf_rx_fb_he_cnt; - u32 tx_bf_rx_fb_vht_cnt; - u32 tx_bf_rx_fb_ht_cnt; - - u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */ - u32 tx_bf_rx_fb_nc_cnt; - u32 tx_bf_rx_fb_nr_cnt; - u32 tx_bf_fb_cpl_cnt; - u32 tx_bf_fb_trig_cnt; - - u32 tx_ampdu_cnt; - u32 tx_stop_q_empty_cnt; - u32 tx_mpdu_attempts_cnt; - u32 tx_mpdu_success_cnt; - /* BF counter is PPDU-based, so remove MPDU-based BF counter */ - - u32 tx_rwp_fail_cnt; - u32 tx_rwp_need_cnt; - - /* rx stats */ - u32 rx_fifo_full_cnt; - u32 channel_idle_cnt; - u32 rx_vector_mismatch_cnt; - u32 rx_delimiter_fail_cnt; - u32 rx_len_mismatch_cnt; - u32 rx_mpdu_cnt; - u32 rx_ampdu_cnt; - u32 rx_ampdu_bytes_cnt; - u32 rx_ampdu_valid_subframe_cnt; - u32 rx_ampdu_valid_subframe_bytes_cnt; - u32 rx_pfdrop_cnt; - u32 rx_vec_queue_overflow_drop_cnt; - u32 rx_ba_cnt; - - u32 tx_amsdu[8]; - u32 tx_amsdu_cnt; }; /* crash-dump */ @@ -222,7 +168,7 @@ struct mt7996_phy { u32 rx_ampdu_ts; u32 ampdu_ref; - struct mib_stats mib; + struct mt76_mib_stats mib; struct mt76_channel_state state_ts; }; @@ -272,9 +218,7 @@ struct mt7996_dev { #endif struct list_head sta_rc_list; - struct list_head sta_poll_list; struct list_head twt_list; - spinlock_t sta_poll_lock; u32 hw_pattern; @@ -311,20 +255,6 @@ enum { }; enum { - MT_CTX0, - MT_HIF0 = 0x0, - - MT_LMAC_AC00 = 0x0, - MT_LMAC_AC01, - MT_LMAC_AC02, - MT_LMAC_AC03, - MT_LMAC_ALTX0 = 0x10, - MT_LMAC_BMC0, - MT_LMAC_BCN0, - MT_LMAC_PSMP0, -}; - -enum { MT_RX_SEL0, MT_RX_SEL1, MT_RX_SEL2, /* monitor chain */ @@ -405,6 +335,7 @@ int mt7996_dma_init(struct mt7996_dev *dev); void mt7996_dma_reset(struct mt7996_dev *dev, bool force); void mt7996_dma_prefetch(struct mt7996_dev *dev); void mt7996_dma_cleanup(struct mt7996_dev *dev); +void mt7996_dma_start(struct mt7996_dev *dev, bool reset); void mt7996_init_txpower(struct mt7996_dev *dev, struct ieee80211_supported_band *sband); int mt7996_txbf_init(struct mt7996_dev *dev); @@ -456,6 +387,7 @@ int mt7996_mcu_set_radar_th(struct mt7996_dev *dev, int index, const struct mt7996_dfs_pattern *pattern); int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable); int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val); +int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif); int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch); int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index, u8 rx_sel, u8 val); @@ -519,7 +451,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi, struct sk_buff *skb, struct mt76_wcid *wcid, struct ieee80211_key_conf *key, int pid, enum mt76_txq_id qid, u32 changed); -void mt7996_mac_set_timing(struct mt7996_phy *phy); +void mt7996_mac_set_coverage_class(struct mt7996_phy *phy); int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/pci.c b/drivers/net/wireless/mediatek/mt76/mt7996/pci.c index 64aee3fb5445..c5301050ff8b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/pci.c @@ -219,4 +219,5 @@ MODULE_DEVICE_TABLE(pci, mt7996_pci_device_table); MODULE_DEVICE_TABLE(pci, mt7996_hif_device_table); MODULE_FIRMWARE(MT7996_FIRMWARE_WA); MODULE_FIRMWARE(MT7996_FIRMWARE_WM); +MODULE_FIRMWARE(MT7996_FIRMWARE_DSP); MODULE_FIRMWARE(MT7996_ROM_PATCH); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/regs.h b/drivers/net/wireless/mediatek/mt76/mt7996/regs.h index d1d3d154195d..97beab924517 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/regs.h @@ -557,22 +557,29 @@ enum base_rev { #define MT_PCIE1_MAC_INT_ENABLE MT_PCIE1_MAC(0x188) +/* PHYRX CSD */ +#define MT_WF_PHYRX_CSD_BASE 0x83000000 +#define MT_WF_PHYRX_CSD(_band, _wf, ofs) (MT_WF_PHYRX_CSD_BASE + \ + ((_band) << 20) + \ + ((_wf) << 16) + (ofs)) +#define MT_WF_PHYRX_CSD_IRPI(_band, _wf) MT_WF_PHYRX_CSD(_band, _wf, 0x1000) + /* PHYRX CTRL */ #define MT_WF_PHYRX_BAND_BASE 0x83080000 #define MT_WF_PHYRX_BAND(_band, ofs) (MT_WF_PHYRX_BAND_BASE + \ ((_band) << 20) + (ofs)) +#define MT_WF_PHYRX_BAND_GID_TAB_VLD0(_band) MT_WF_PHYRX_BAND(_band, 0x1054) +#define MT_WF_PHYRX_BAND_GID_TAB_VLD1(_band) MT_WF_PHYRX_BAND(_band, 0x1058) +#define MT_WF_PHYRX_BAND_GID_TAB_POS0(_band) MT_WF_PHYRX_BAND(_band, 0x105c) +#define MT_WF_PHYRX_BAND_GID_TAB_POS1(_band) MT_WF_PHYRX_BAND(_band, 0x1060) +#define MT_WF_PHYRX_BAND_GID_TAB_POS2(_band) MT_WF_PHYRX_BAND(_band, 0x1064) +#define MT_WF_PHYRX_BAND_GID_TAB_POS3(_band) MT_WF_PHYRX_BAND(_band, 0x1068) + #define MT_WF_PHYRX_BAND_RX_CTRL1(_band) MT_WF_PHYRX_BAND(_band, 0x2004) #define MT_WF_PHYRX_BAND_RX_CTRL1_IPI_EN GENMASK(2, 0) #define MT_WF_PHYRX_BAND_RX_CTRL1_STSCNT_EN GENMASK(11, 9) -/* PHYRX CSD */ -#define MT_WF_PHYRX_CSD_BASE 0x83000000 -#define MT_WF_PHYRX_CSD(_band, _wf, ofs) (MT_WF_PHYRX_CSD_BASE + \ - ((_band) << 20) + \ - ((_wf) << 16) + (ofs)) -#define MT_WF_PHYRX_CSD_IRPI(_band, _wf) MT_WF_PHYRX_CSD(_band, _wf, 0x1000) - /* PHYRX CSD BAND */ #define MT_WF_PHYRX_CSD_BAND_RXTD12(_band) MT_WF_PHYRX_BAND(_band, 0x8230) #define MT_WF_PHYRX_CSD_BAND_RXTD12_IRPI_SW_CLR_ONLY BIT(18) diff --git a/drivers/net/wireless/mediatek/mt76/testmode.c b/drivers/net/wireless/mediatek/mt76/testmode.c index 0accc71a91c9..4644dace9bb3 100644 --- a/drivers/net/wireless/mediatek/mt76/testmode.c +++ b/drivers/net/wireless/mediatek/mt76/testmode.c @@ -8,6 +8,7 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = { [MT76_TM_ATTR_RESET] = { .type = NLA_FLAG }, [MT76_TM_ATTR_STATE] = { .type = NLA_U8 }, [MT76_TM_ATTR_TX_COUNT] = { .type = NLA_U32 }, + [MT76_TM_ATTR_TX_LENGTH] = { .type = NLA_U32 }, [MT76_TM_ATTR_TX_RATE_MODE] = { .type = NLA_U8 }, [MT76_TM_ATTR_TX_RATE_NSS] = { .type = NLA_U8 }, [MT76_TM_ATTR_TX_RATE_IDX] = { .type = NLA_U8 }, diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c index 72b3ec715e47..6cc26cc6c517 100644 --- a/drivers/net/wireless/mediatek/mt76/tx.c +++ b/drivers/net/wireless/mediatek/mt76/tx.c @@ -121,6 +121,7 @@ int mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, struct sk_buff *skb) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct mt76_tx_cb *cb = mt76_tx_skb_cb(skb); int pid; @@ -134,8 +135,14 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, return MT_PACKET_ID_NO_ACK; if (!(info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS | - IEEE80211_TX_CTL_RATE_CTRL_PROBE))) + IEEE80211_TX_CTL_RATE_CTRL_PROBE))) { + if (mtk_wed_device_active(&dev->mmio.wed) && + ((info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) || + ieee80211_is_data(hdr->frame_control))) + return MT_PACKET_ID_WED; + return MT_PACKET_ID_NO_SKB; + } spin_lock_bh(&dev->status_lock); @@ -263,8 +270,15 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff * #endif if (cb->pktid < MT_PACKET_ID_FIRST) { + struct ieee80211_rate_status rs = {}; + hw = mt76_tx_status_get_hw(dev, skb); status.sta = wcid_to_sta(wcid); + if (status.sta && (wcid->rate.flags || wcid->rate.legacy)) { + rs.rate_idx = wcid->rate; + status.rates = &rs; + status.n_rates = 1; + } spin_lock_bh(&dev->rx_lock); ieee80211_tx_status_ext(hw, &status); spin_unlock_bh(&dev->rx_lock); |