Commit 111d5c47 authored by Kalle Valo's avatar Kalle Valo

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
parents f5343efd 6c0570bc
......@@ -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";
};
- |
......
......@@ -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"
......
......@@ -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/
......
......@@ -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;
......
......@@ -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 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len)
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
......
......@@ -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);
......
......@@ -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];
......
......@@ -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);
......
......@@ -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);
......
......@@ -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))
......
......@@ -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);
}
......
......@@ -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,
......
......@@ -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)
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
}
......
......@@ -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;
......
......@@ -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))
......
......@@ -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 */
......@@ -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)
......
// 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);
This diff is collapsed.
......@@ -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);
......@@ -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,
};
......
......@@ -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);
......
......@@ -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.
......@@ -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
......@@ -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];
......
......@@ -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);
......
......@@ -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,12 +250,90 @@ 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;
u32 irq_mask;
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);
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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)
......
......@@ -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 {
......
......@@ -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 @@ static int __init mt7915_init(void)
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);
......
......@@ -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);
......
......@@ -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)
......
# 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
......
......@@ -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
......@@ -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 @@ mt7921_pm_set(void *data, u64 val)
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 @@ mt7921_deep_sleep_set(void *data, u64 val)
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,
......
......@@ -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);
......
......@@ -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;
}
......@@ -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 @@ static int mt7921s_probe(struct sdio_func *func,
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 @@ static int mt7921s_suspend(struct device *__dev)
pm->suspended = false;
if (err < 0)
mt7921_reset(&dev->mt76);
mt792x_reset(&dev->mt76);
return err;
}
......@@ -277,14 +277,14 @@ static int mt7921s_suspend(struct device *__dev)
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 @@ static int mt7921s_resume(struct device *__dev)
pm->suspended = false;
if (err < 0)
mt7921_reset(&dev->mt76);
mt792x_reset(&dev->mt76);
return err;
}
......
......@@ -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;
......
......@@ -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;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -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);
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment