| From d10be7604c55c961bd06a2e4aaeff1baf4fda24a Mon Sep 17 00:00:00 2001 |
| From: Lorenzo Bianconi <lorenzo@kernel.org> |
| Date: Wed, 24 May 2023 16:39:32 +0200 |
| Subject: [PATCH] sync to master codebase |
| |
| --- |
| Makefile | 2 +- |
| dma.c | 6 + |
| mac80211.c | 6 + |
| mt76.h | 106 ++++++- |
| mt7603/init.c | 2 - |
| mt7603/mac.c | 22 +- |
| mt7603/main.c | 20 +- |
| mt7603/mt7603.h | 4 - |
| mt7615/init.c | 4 +- |
| mt7615/mac.c | 30 +- |
| mt7615/main.c | 49 +++- |
| mt7615/mt7615.h | 4 - |
| mt7615/regs.h | 9 + |
| mt76_connac.h | 10 +- |
| mt76_connac2_mac.h | 4 +- |
| mt76_connac3_mac.c | 182 ++++++++++++ |
| mt76_connac3_mac.h | 325 +++++++++++++++++++++ |
| mt76_connac_mac.c | 109 ++++++- |
| mt76_connac_mcu.c | 3 + |
| mt76_connac_mcu.h | 6 +- |
| mt76x02_util.c | 13 - |
| mt7915/debugfs.c | 128 ++++---- |
| mt7915/dma.c | 148 +++++----- |
| mt7915/init.c | 12 +- |
| mt7915/mac.c | 192 +++++------- |
| mt7915/mac.h | 7 +- |
| mt7915/main.c | 184 +++++++++--- |
| mt7915/mcu.c | 119 +++++++- |
| mt7915/mmio.c | 34 +-- |
| mt7915/mt7915.h | 74 +---- |
| mt7915/regs.h | 3 + |
| mt7915/soc.c | 53 ++-- |
| mt7921/debugfs.c | 2 +- |
| mt7921/dma.c | 10 +- |
| mt7921/init.c | 72 ++++- |
| mt7921/mac.c | 118 +++----- |
| mt7921/main.c | 42 ++- |
| mt7921/mcu.c | 25 +- |
| mt7921/mt7921.h | 43 +-- |
| mt7921/pci.c | 10 +- |
| mt7921/pci_mac.c | 16 +- |
| mt7921/regs.h | 1 - |
| mt7921/usb.c | 3 + |
| mt7996/debugfs.c | 4 +- |
| mt7996/dma.c | 83 +++--- |
| mt7996/init.c | 5 +- |
| mt7996/mac.c | 317 +++++--------------- |
| mt7996/mac.h | 315 +------------------- |
| mt7996/main.c | 114 +++++--- |
| mt7996/mcu.c | 182 +++++++++--- |
| mt7996/mcu.h | 17 ++ |
| mt7996/mt7996.h | 80 +---- |
| mt7996/pci.c | 1 + |
| mt7996/regs.h | 21 +- |
| tx.c | 16 +- |
| 59 files changed, 1908 insertions(+), 1459 deletions(-) |
| create mode 100644 mt76_connac3_mac.c |
| create mode 100644 mt76_connac3_mac.h |
| |
| diff --git a/Makefile b/Makefile |
| index 9c287cf4..f9b94280 100644 |
| --- a/Makefile |
| +++ b/Makefile |
| @@ -28,7 +28,7 @@ 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 |
| |
| obj-$(CONFIG_MT76x0_COMMON) += mt76x0/ |
| obj-$(CONFIG_MT76x2_COMMON) += mt76x2/ |
| diff --git a/dma.c b/dma.c |
| index 465190eb..05d9ab3c 100644 |
| --- a/dma.c |
| +++ b/dma.c |
| @@ -466,6 +466,9 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q, |
| struct mt76_queue_buf buf = {}; |
| dma_addr_t addr; |
| |
| + if (test_bit(MT76_MCU_RESET, &dev->phy.state)) |
| + goto error; |
| + |
| if (q->queued + 1 >= q->ndesc - 1) |
| goto error; |
| |
| @@ -507,6 +510,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q, |
| dma_addr_t addr; |
| u8 *txwi; |
| |
| + if (test_bit(MT76_RESET, &dev->phy.state)) |
| + goto free_skb; |
| + |
| t = mt76_get_txwi(dev); |
| if (!t) |
| goto free_skb; |
| diff --git a/mac80211.c b/mac80211.c |
| index 2c4a5290..85407387 100644 |
| --- a/mac80211.c |
| +++ b/mac80211.c |
| @@ -76,6 +76,7 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = { |
| CHAN5G(165, 5825), |
| CHAN5G(169, 5845), |
| CHAN5G(173, 5865), |
| + CHAN5G(177, 5885), |
| }; |
| |
| static const struct ieee80211_channel mt76_channels_6ghz[] = { |
| @@ -660,6 +661,8 @@ mt76_alloc_device(struct device *pdev, unsigned int size, |
| idr_init(&dev->rx_token); |
| |
| INIT_LIST_HEAD(&dev->wcid_list); |
| + INIT_LIST_HEAD(&dev->sta_poll_list); |
| + spin_lock_init(&dev->sta_poll_lock); |
| |
| INIT_LIST_HEAD(&dev->txwi_cache); |
| INIT_LIST_HEAD(&dev->rxwi_cache); |
| @@ -1738,6 +1741,9 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi, |
| for (i = 0; i < (eht ? 14 : 12); i++) |
| data[ei++] += stats->tx_mcs[i]; |
| |
| + for (i = 0; i < 4; i++) |
| + data[ei++] += stats->tx_nss[i]; |
| + |
| wi->worker_stat_count = ei - wi->initial_stat_idx; |
| } |
| EXPORT_SYMBOL_GPL(mt76_ethtool_worker); |
| diff --git a/mt76.h b/mt76.h |
| index 8b4635e9..034ab90c 100644 |
| --- a/mt76.h |
| +++ b/mt76.h |
| @@ -277,7 +277,7 @@ struct mt76_sta_stats { |
| u64 tx_mcs[16]; /* mcs idx */ |
| u64 tx_bytes; |
| /* WED TX */ |
| - u32 tx_packets; |
| + u32 tx_packets; /* unit: MSDU */ |
| u32 tx_retries; |
| u32 tx_failed; |
| /* WED RX */ |
| @@ -316,6 +316,7 @@ struct mt76_wcid { |
| int inactive_count; |
| |
| struct rate_info rate; |
| + unsigned long ampdu_state; |
| |
| u16 idx; |
| u8 hw_key_idx; |
| @@ -336,6 +337,8 @@ struct mt76_wcid { |
| struct idr pktid; |
| |
| struct mt76_sta_stats stats; |
| + |
| + struct list_head poll_list; |
| }; |
| |
| struct mt76_txq { |
| @@ -692,6 +695,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 { |
| @@ -813,6 +819,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; |
| @@ -847,6 +856,101 @@ struct mt76_dev { |
| }; |
| }; |
| |
| +/* per-phy stats. */ |
| +struct mt76_mib_stats { |
| + u32 ack_fail_cnt; |
| + u32 fcs_err_cnt; |
| + u32 rts_cnt; |
| + u32 rts_retries_cnt; |
| + u32 ba_miss_cnt; |
| + u32 tx_bf_cnt; |
| + u32 tx_mu_bf_cnt; |
| + u32 tx_mu_mpdu_cnt; |
| + u32 tx_mu_acked_mpdu_cnt; |
| + u32 tx_su_acked_mpdu_cnt; |
| + u32 tx_bf_ibf_ppdu_cnt; |
| + u32 tx_bf_ebf_ppdu_cnt; |
| + |
| + u32 tx_bf_rx_fb_all_cnt; |
| + u32 tx_bf_rx_fb_eht_cnt; |
| + u32 tx_bf_rx_fb_he_cnt; |
| + u32 tx_bf_rx_fb_vht_cnt; |
| + u32 tx_bf_rx_fb_ht_cnt; |
| + |
| + u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */ |
| + u32 tx_bf_rx_fb_nc_cnt; |
| + u32 tx_bf_rx_fb_nr_cnt; |
| + u32 tx_bf_fb_cpl_cnt; |
| + u32 tx_bf_fb_trig_cnt; |
| + |
| + u32 tx_ampdu_cnt; |
| + u32 tx_stop_q_empty_cnt; |
| + u32 tx_mpdu_attempts_cnt; |
| + u32 tx_mpdu_success_cnt; |
| + u32 tx_pkt_ebf_cnt; |
| + u32 tx_pkt_ibf_cnt; |
| + |
| + u32 tx_rwp_fail_cnt; |
| + u32 tx_rwp_need_cnt; |
| + |
| + /* rx stats */ |
| + u32 rx_fifo_full_cnt; |
| + u32 channel_idle_cnt; |
| + u32 primary_cca_busy_time; |
| + u32 secondary_cca_busy_time; |
| + u32 primary_energy_detect_time; |
| + u32 cck_mdrdy_time; |
| + u32 ofdm_mdrdy_time; |
| + u32 green_mdrdy_time; |
| + u32 rx_vector_mismatch_cnt; |
| + u32 rx_delimiter_fail_cnt; |
| + u32 rx_mrdy_cnt; |
| + u32 rx_len_mismatch_cnt; |
| + u32 rx_mpdu_cnt; |
| + u32 rx_ampdu_cnt; |
| + u32 rx_ampdu_bytes_cnt; |
| + u32 rx_ampdu_valid_subframe_cnt; |
| + u32 rx_ampdu_valid_subframe_bytes_cnt; |
| + u32 rx_pfdrop_cnt; |
| + u32 rx_vec_queue_overflow_drop_cnt; |
| + u32 rx_ba_cnt; |
| + |
| + u32 tx_amsdu[8]; |
| + u32 tx_amsdu_cnt; |
| + |
| + /* mcu_muru_stats */ |
| + u32 dl_cck_cnt; |
| + u32 dl_ofdm_cnt; |
| + u32 dl_htmix_cnt; |
| + u32 dl_htgf_cnt; |
| + u32 dl_vht_su_cnt; |
| + u32 dl_vht_2mu_cnt; |
| + u32 dl_vht_3mu_cnt; |
| + u32 dl_vht_4mu_cnt; |
| + u32 dl_he_su_cnt; |
| + u32 dl_he_ext_su_cnt; |
| + u32 dl_he_2ru_cnt; |
| + u32 dl_he_2mu_cnt; |
| + u32 dl_he_3ru_cnt; |
| + u32 dl_he_3mu_cnt; |
| + u32 dl_he_4ru_cnt; |
| + u32 dl_he_4mu_cnt; |
| + u32 dl_he_5to8ru_cnt; |
| + u32 dl_he_9to16ru_cnt; |
| + u32 dl_he_gtr16ru_cnt; |
| + |
| + u32 ul_hetrig_su_cnt; |
| + u32 ul_hetrig_2ru_cnt; |
| + u32 ul_hetrig_3ru_cnt; |
| + u32 ul_hetrig_4ru_cnt; |
| + u32 ul_hetrig_5to8ru_cnt; |
| + u32 ul_hetrig_9to16ru_cnt; |
| + u32 ul_hetrig_gtr16ru_cnt; |
| + u32 ul_hetrig_2mu_cnt; |
| + u32 ul_hetrig_3mu_cnt; |
| + u32 ul_hetrig_4mu_cnt; |
| +}; |
| + |
| struct mt76_power_limits { |
| s8 cck[4]; |
| s8 ofdm[8]; |
| diff --git a/mt7603/init.c b/mt7603/init.c |
| index 9a2e632d..0762de3c 100644 |
| --- a/mt7603/init.c |
| +++ b/mt7603/init.c |
| @@ -500,8 +500,6 @@ int mt7603_register_device(struct mt7603_dev *dev) |
| bus_ops->rmw = mt7603_rmw; |
| dev->mt76.bus = bus_ops; |
| |
| - INIT_LIST_HEAD(&dev->sta_poll_list); |
| - spin_lock_init(&dev->sta_poll_lock); |
| spin_lock_init(&dev->ps_lock); |
| |
| INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7603_mac_work); |
| diff --git a/mt7603/mac.c b/mt7603/mac.c |
| index 12e0af52..de11557e 100644 |
| --- a/mt7603/mac.c |
| +++ b/mt7603/mac.c |
| @@ -412,16 +412,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 +1267,10 @@ void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data) |
| msta = container_of(wcid, struct mt7603_sta, wcid); |
| sta = wcid_to_sta(wcid); |
| |
| - if (list_empty(&msta->poll_list)) { |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - list_add_tail(&msta->poll_list, &dev->sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + if (list_empty(&msta->wcid.poll_list)) { |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| } |
| |
| if (mt7603_mac_add_txs_skb(dev, msta, pid, txs_data)) |
| diff --git a/mt7603/main.c b/mt7603/main.c |
| index 1b1358c6..1d489341 100644 |
| --- a/mt7603/main.c |
| +++ b/mt7603/main.c |
| @@ -66,7 +66,7 @@ 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; |
| mt76_packet_id_init(&mvif->sta.wcid); |
| @@ -100,10 +100,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,7 +351,7 @@ 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; |
| @@ -388,10 +388,10 @@ mt7603_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
| mt7603_filter_tx(dev, wcid->idx, true); |
| spin_unlock_bh(&dev->ps_lock); |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (!list_empty(&msta->poll_list)) |
| - list_del_init(&msta->poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&mdev->sta_poll_lock); |
| + if (!list_empty(&msta->wcid.poll_list)) |
| + list_del_init(&msta->wcid.poll_list); |
| + spin_unlock_bh(&mdev->sta_poll_lock); |
| |
| mt7603_wtbl_clear(dev, wcid->idx); |
| } |
| diff --git a/mt7603/mt7603.h b/mt7603/mt7603.h |
| index 7c3be596..354b1898 100644 |
| --- a/mt7603/mt7603.h |
| +++ b/mt7603/mt7603.h |
| @@ -64,7 +64,6 @@ struct mt7603_sta { |
| |
| struct mt7603_vif *vif; |
| |
| - struct list_head poll_list; |
| u32 tx_airtime_ac[4]; |
| |
| struct sk_buff_head psq; |
| @@ -110,9 +109,6 @@ struct mt7603_dev { |
| |
| u32 rxfilter; |
| |
| - struct list_head sta_poll_list; |
| - spinlock_t sta_poll_lock; |
| - |
| struct mt7603_sta global_sta; |
| |
| u32 agc0, agc3; |
| diff --git a/mt7615/init.c b/mt7615/init.c |
| index 621e69f0..18a50ccf 100644 |
| --- a/mt7615/init.c |
| +++ b/mt7615/init.c |
| @@ -397,6 +397,8 @@ mt7615_init_wiphy(struct ieee80211_hw *hw) |
| wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL); |
| wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS); |
| wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); |
| + if (!is_mt7622(&phy->dev->mt76)) |
| + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER); |
| |
| ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); |
| ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN); |
| @@ -626,8 +628,6 @@ void mt7615_init_device(struct mt7615_dev *dev) |
| INIT_DELAYED_WORK(&dev->coredump.work, mt7615_coredump_work); |
| skb_queue_head_init(&dev->phy.scan_event_list); |
| skb_queue_head_init(&dev->coredump.msg_list); |
| - INIT_LIST_HEAD(&dev->sta_poll_list); |
| - spin_lock_init(&dev->sta_poll_lock); |
| init_waitqueue_head(&dev->reset_wait); |
| init_waitqueue_head(&dev->phy.roc_wait); |
| |
| diff --git a/mt7615/mac.c b/mt7615/mac.c |
| index da1d17b7..7ba78983 100644 |
| --- a/mt7615/mac.c |
| +++ b/mt7615/mac.c |
| @@ -387,10 +387,11 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb) |
| struct mt7615_sta *msta; |
| |
| msta = container_of(status->wcid, struct mt7615_sta, wcid); |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (list_empty(&msta->poll_list)) |
| - list_add_tail(&msta->poll_list, &dev->sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + if (list_empty(&msta->wcid.poll_list)) |
| + list_add_tail(&msta->wcid.poll_list, |
| + &dev->mt76.sta_poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| } |
| |
| if (mt76_is_mmio(&dev->mt76) && (rxd0 & csum_mask) == csum_mask && |
| @@ -905,16 +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); |
| - list_del_init(&msta->poll_list); |
| + wcid.poll_list); |
| + |
| + 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; |
| |
| @@ -1511,10 +1515,10 @@ static void mt7615_mac_add_txs(struct mt7615_dev *dev, void *data) |
| msta = container_of(wcid, struct mt7615_sta, wcid); |
| sta = wcid_to_sta(wcid); |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (list_empty(&msta->poll_list)) |
| - list_add_tail(&msta->poll_list, &dev->sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + if (list_empty(&msta->wcid.poll_list)) |
| + list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| if (mt7615_mac_add_txs_skb(dev, msta, pid, txs_data)) |
| goto out; |
| diff --git a/mt7615/main.c b/mt7615/main.c |
| index dadb13f2..200b1752 100644 |
| --- a/mt7615/main.c |
| +++ b/mt7615/main.c |
| @@ -222,7 +222,7 @@ static int mt7615_add_interface(struct ieee80211_hw *hw, |
| |
| idx = MT7615_WTBL_RESERVED - mvif->mt76.idx; |
| |
| - INIT_LIST_HEAD(&mvif->sta.poll_list); |
| + INIT_LIST_HEAD(&mvif->sta.wcid.poll_list); |
| mvif->sta.wcid.idx = idx; |
| mvif->sta.wcid.phy_idx = mvif->mt76.band_idx; |
| mvif->sta.wcid.hw_key_idx = -1; |
| @@ -274,10 +274,10 @@ static void mt7615_remove_interface(struct ieee80211_hw *hw, |
| |
| mt7615_mutex_release(dev); |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (!list_empty(&msta->poll_list)) |
| - list_del_init(&msta->poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + if (!list_empty(&msta->wcid.poll_list)) |
| + list_del_init(&msta->wcid.poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| mt76_packet_id_flush(&dev->mt76, &mvif->sta.wcid); |
| } |
| @@ -552,6 +552,32 @@ static void mt7615_configure_filter(struct ieee80211_hw *hw, |
| mt7615_mutex_release(dev); |
| } |
| |
| +static void |
| +mt7615_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| + struct ieee80211_bss_conf *info) |
| +{ |
| + struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv; |
| + struct mt7615_dev *dev = mt7615_hw_dev(hw); |
| + u8 i, band = mvif->mt76.band_idx; |
| + u32 *mu; |
| + |
| + mu = (u32 *)info->mu_group.membership; |
| + for (i = 0; i < WLAN_MEMBERSHIP_LEN / sizeof(*mu); i++) { |
| + if (is_mt7663(&dev->mt76)) |
| + mt76_wr(dev, MT7663_WF_PHY_GID_TAB_VLD(band, i), mu[i]); |
| + else |
| + mt76_wr(dev, MT_WF_PHY_GID_TAB_VLD(band, i), mu[i]); |
| + } |
| + |
| + mu = (u32 *)info->mu_group.position; |
| + for (i = 0; i < WLAN_USER_POSITION_LEN / sizeof(*mu); i++) { |
| + if (is_mt7663(&dev->mt76)) |
| + mt76_wr(dev, MT7663_WF_PHY_GID_TAB_POS(band, i), mu[i]); |
| + else |
| + mt76_wr(dev, MT_WF_PHY_GID_TAB_POS(band, i), mu[i]); |
| + } |
| +} |
| + |
| static void mt7615_bss_info_changed(struct ieee80211_hw *hw, |
| struct ieee80211_vif *vif, |
| struct ieee80211_bss_conf *info, |
| @@ -600,6 +626,9 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw, |
| if (changed & BSS_CHANGED_ASSOC) |
| mt7615_mac_set_beacon_filter(phy, vif, vif->cfg.assoc); |
| |
| + if (changed & BSS_CHANGED_MU_GROUPS) |
| + mt7615_update_mu_group(hw, vif, info); |
| + |
| mt7615_mutex_release(dev); |
| } |
| |
| @@ -628,7 +657,7 @@ int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
| if (idx < 0) |
| return -ENOSPC; |
| |
| - INIT_LIST_HEAD(&msta->poll_list); |
| + INIT_LIST_HEAD(&msta->wcid.poll_list); |
| msta->vif = mvif; |
| msta->wcid.sta = 1; |
| msta->wcid.idx = idx; |
| @@ -676,10 +705,10 @@ void mt7615_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
| if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) |
| mt7615_mcu_add_bss_info(phy, vif, sta, false); |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (!list_empty(&msta->poll_list)) |
| - list_del_init(&msta->poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&mdev->sta_poll_lock); |
| + if (!list_empty(&msta->wcid.poll_list)) |
| + list_del_init(&msta->wcid.poll_list); |
| + spin_unlock_bh(&mdev->sta_poll_lock); |
| |
| mt76_connac_power_save_sched(phy->mt76, &dev->pm); |
| } |
| diff --git a/mt7615/mt7615.h b/mt7615/mt7615.h |
| index 582d1b5b..a20322aa 100644 |
| --- a/mt7615/mt7615.h |
| +++ b/mt7615/mt7615.h |
| @@ -125,7 +125,6 @@ struct mt7615_sta { |
| |
| struct mt7615_vif *vif; |
| |
| - struct list_head poll_list; |
| u32 airtime_ac[8]; |
| |
| struct ieee80211_tx_rate rates[4]; |
| @@ -262,9 +261,6 @@ struct mt7615_dev { |
| wait_queue_head_t reset_wait; |
| u32 reset_state; |
| |
| - struct list_head sta_poll_list; |
| - spinlock_t sta_poll_lock; |
| - |
| struct { |
| u8 n_pulses; |
| u32 period; |
| diff --git a/mt7615/regs.h b/mt7615/regs.h |
| index 7cecb22c..806b3887 100644 |
| --- a/mt7615/regs.h |
| +++ b/mt7615/regs.h |
| @@ -212,6 +212,15 @@ enum mt7615_reg_base { |
| |
| #define MT7663_WF_PHY_R0_PHYCTRL_STS5(_phy) MT_WF_PHY(0x0224 + ((_phy) << 12)) |
| |
| +#define MT_WF_PHY_GID_TAB_VLD(_phy, i) MT_WF_PHY(0x0254 + (i) * 4 + \ |
| + ((_phy) << 9)) |
| +#define MT7663_WF_PHY_GID_TAB_VLD(_phy, i) MT_WF_PHY(0x0254 + (i) * 4 + \ |
| + ((_phy) << 12)) |
| +#define MT_WF_PHY_GID_TAB_POS(_phy, i) MT_WF_PHY(0x025c + (i) * 4 + \ |
| + ((_phy) << 9)) |
| +#define MT7663_WF_PHY_GID_TAB_POS(_phy, i) MT_WF_PHY(0x025c + (i) * 4 + \ |
| + ((_phy) << 12)) |
| + |
| #define MT_WF_PHY_MIN_PRI_PWR(_phy) MT_WF_PHY((_phy) ? 0x084 : 0x229c) |
| #define MT_WF_PHY_PD_OFDM_MASK(_phy) ((_phy) ? GENMASK(24, 16) : \ |
| GENMASK(28, 20)) |
| diff --git a/mt76_connac.h b/mt76_connac.h |
| index 77ca8f05..22878f08 100644 |
| --- a/mt76_connac.h |
| +++ b/mt76_connac.h |
| @@ -419,5 +419,13 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev, |
| struct mt76_rx_status *status, |
| struct ieee80211_supported_band *sband, |
| __le32 *rxv, u8 *mode); |
| - |
| +void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi); |
| +void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t, |
| + struct ieee80211_sta *sta, |
| + struct list_head *free_list); |
| +void mt76_connac2_tx_token_put(struct mt76_dev *dev); |
| + |
| +/* connac3 */ |
| +void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, |
| + u8 mode); |
| #endif /* __MT76_CONNAC_H */ |
| diff --git a/mt76_connac2_mac.h b/mt76_connac2_mac.h |
| index a5ec0f63..bd2a9246 100644 |
| --- a/mt76_connac2_mac.h |
| +++ b/mt76_connac2_mac.h |
| @@ -34,7 +34,7 @@ enum { |
| |
| #define MT_TX_FREE_MSDU_CNT GENMASK(9, 0) |
| #define MT_TX_FREE_WLAN_ID GENMASK(23, 14) |
| -#define MT_TX_FREE_LATENCY GENMASK(12, 0) |
| +#define MT_TX_FREE_COUNT GENMASK(12, 0) |
| /* 0: success, others: dropped */ |
| #define MT_TX_FREE_STATUS GENMASK(14, 13) |
| #define MT_TX_FREE_MSDU_ID GENMASK(30, 16) |
| @@ -173,7 +173,7 @@ enum { |
| #define MT_TXS5_MPDU_TX_CNT GENMASK(31, 23) |
| |
| #define MT_TXS6_MPDU_FAIL_CNT GENMASK(31, 23) |
| - |
| +#define MT_TXS7_MPDU_RETRY_BYTE GENMASK(22, 0) |
| #define MT_TXS7_MPDU_RETRY_CNT GENMASK(31, 23) |
| |
| /* RXD DW0 */ |
| diff --git a/mt76_connac3_mac.c b/mt76_connac3_mac.c |
| new file mode 100644 |
| index 00000000..73e9f283 |
| --- /dev/null |
| +++ b/mt76_connac3_mac.c |
| @@ -0,0 +1,182 @@ |
| +// SPDX-License-Identifier: ISC |
| +/* Copyright (C) 2023 MediaTek Inc. */ |
| + |
| +#include "mt76_connac.h" |
| +#include "mt76_connac3_mac.h" |
| +#include "dma.h" |
| + |
| +#define HE_BITS(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_##f) |
| +#define HE_PREP(f, m, v) le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\ |
| + IEEE80211_RADIOTAP_HE_##f) |
| + |
| +static void |
| +mt76_connac3_mac_decode_he_radiotap_ru(struct mt76_rx_status *status, |
| + struct ieee80211_radiotap_he *he, |
| + __le32 *rxv) |
| +{ |
| + u32 ru = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC), offs = 0; |
| + |
| + status->bw = RATE_INFO_BW_HE_RU; |
| + |
| + switch (ru) { |
| + case 0 ... 36: |
| + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26; |
| + offs = ru; |
| + break; |
| + case 37 ... 52: |
| + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52; |
| + offs = ru - 37; |
| + break; |
| + case 53 ... 60: |
| + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; |
| + offs = ru - 53; |
| + break; |
| + case 61 ... 64: |
| + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242; |
| + offs = ru - 61; |
| + break; |
| + case 65 ... 66: |
| + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484; |
| + offs = ru - 65; |
| + break; |
| + case 67: |
| + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996; |
| + break; |
| + case 68: |
| + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; |
| + break; |
| + } |
| + |
| + he->data1 |= HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); |
| + he->data2 |= HE_BITS(DATA2_RU_OFFSET_KNOWN) | |
| + le16_encode_bits(offs, |
| + IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); |
| +} |
| + |
| +#define MU_PREP(f, v) le16_encode_bits(v, IEEE80211_RADIOTAP_HE_MU_##f) |
| +static void |
| +mt76_connac3_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32 *rxv) |
| +{ |
| + struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; |
| + static const struct ieee80211_radiotap_he_mu mu_known = { |
| + .flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) | |
| + HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) | |
| + HE_BITS(MU_FLAGS1_CH1_RU_KNOWN) | |
| + HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN), |
| + .flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN), |
| + }; |
| + struct ieee80211_radiotap_he_mu *he_mu; |
| + |
| + status->flag |= RX_FLAG_RADIOTAP_HE_MU; |
| + |
| + he_mu = skb_push(skb, sizeof(mu_known)); |
| + memcpy(he_mu, &mu_known, sizeof(mu_known)); |
| + |
| + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status->rate_idx); |
| + if (status->he_dcm) |
| + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status->he_dcm); |
| + |
| + he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) | |
| + MU_PREP(FLAGS2_SIG_B_SYMS_USERS, |
| + le32_get_bits(rxv[4], MT_CRXV_HE_NUM_USER)); |
| + |
| + he_mu->ru_ch1[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU0) & 0xff; |
| + |
| + if (status->bw >= RATE_INFO_BW_40) { |
| + he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN); |
| + he_mu->ru_ch2[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU1) & 0xff; |
| + } |
| + |
| + if (status->bw >= RATE_INFO_BW_80) { |
| + u32 ru_h, ru_l; |
| + |
| + he_mu->ru_ch1[1] = le32_get_bits(rxv[16], MT_CRXV_HE_RU2) & 0xff; |
| + |
| + ru_l = le32_get_bits(rxv[16], MT_CRXV_HE_RU3_L); |
| + ru_h = le32_get_bits(rxv[17], MT_CRXV_HE_RU3_H) & 0x7; |
| + he_mu->ru_ch2[1] = (u8)(ru_l | ru_h << 4); |
| + } |
| +} |
| + |
| +void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, |
| + u8 mode) |
| +{ |
| + struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; |
| + static const struct ieee80211_radiotap_he known = { |
| + .data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) | |
| + HE_BITS(DATA1_DATA_DCM_KNOWN) | |
| + HE_BITS(DATA1_STBC_KNOWN) | |
| + HE_BITS(DATA1_CODING_KNOWN) | |
| + HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) | |
| + HE_BITS(DATA1_DOPPLER_KNOWN) | |
| + HE_BITS(DATA1_SPTL_REUSE_KNOWN) | |
| + HE_BITS(DATA1_BSS_COLOR_KNOWN), |
| + .data2 = HE_BITS(DATA2_GI_KNOWN) | |
| + HE_BITS(DATA2_TXBF_KNOWN) | |
| + HE_BITS(DATA2_PE_DISAMBIG_KNOWN) | |
| + HE_BITS(DATA2_TXOP_KNOWN), |
| + }; |
| + u32 ltf_size = le32_get_bits(rxv[4], MT_CRXV_HE_LTF_SIZE) + 1; |
| + struct ieee80211_radiotap_he *he; |
| + |
| + status->flag |= RX_FLAG_RADIOTAP_HE; |
| + |
| + he = skb_push(skb, sizeof(known)); |
| + memcpy(he, &known, sizeof(known)); |
| + |
| + he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[9]) | |
| + HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[4]); |
| + he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[13]); |
| + he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[5]) | |
| + le16_encode_bits(ltf_size, |
| + IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE); |
| + if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF) |
| + he->data5 |= HE_BITS(DATA5_TXBF); |
| + he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[9]) | |
| + HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[9]); |
| + |
| + switch (mode) { |
| + case MT_PHY_TYPE_HE_SU: |
| + he->data1 |= HE_BITS(DATA1_FORMAT_SU) | |
| + HE_BITS(DATA1_UL_DL_KNOWN) | |
| + HE_BITS(DATA1_BEAM_CHANGE_KNOWN) | |
| + HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); |
| + |
| + he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[8]) | |
| + HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]); |
| + break; |
| + case MT_PHY_TYPE_HE_EXT_SU: |
| + he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) | |
| + HE_BITS(DATA1_UL_DL_KNOWN) | |
| + HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); |
| + |
| + he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]); |
| + break; |
| + case MT_PHY_TYPE_HE_MU: |
| + he->data1 |= HE_BITS(DATA1_FORMAT_MU) | |
| + HE_BITS(DATA1_UL_DL_KNOWN); |
| + |
| + he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]); |
| + he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[8]); |
| + |
| + mt76_connac3_mac_decode_he_radiotap_ru(status, he, rxv); |
| + mt76_connac3_mac_decode_he_mu_radiotap(skb, rxv); |
| + break; |
| + case MT_PHY_TYPE_HE_TB: |
| + he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) | |
| + HE_BITS(DATA1_SPTL_REUSE2_KNOWN) | |
| + HE_BITS(DATA1_SPTL_REUSE3_KNOWN) | |
| + HE_BITS(DATA1_SPTL_REUSE4_KNOWN); |
| + |
| + he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, rxv[13]) | |
| + HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, rxv[13]) | |
| + HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, rxv[13]) | |
| + HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, rxv[13]); |
| + |
| + mt76_connac3_mac_decode_he_radiotap_ru(status, he, rxv); |
| + break; |
| + default: |
| + break; |
| + } |
| +} |
| +EXPORT_SYMBOL_GPL(mt76_connac3_mac_decode_he_radiotap); |
| diff --git a/mt76_connac3_mac.h b/mt76_connac3_mac.h |
| new file mode 100644 |
| index 00000000..6663a0b4 |
| --- /dev/null |
| +++ b/mt76_connac3_mac.h |
| @@ -0,0 +1,325 @@ |
| +/* SPDX-License-Identifier: ISC */ |
| +/* Copyright (C) 2023 MediaTek Inc. */ |
| + |
| +#ifndef __MT76_CONNAC3_MAC_H |
| +#define __MT76_CONNAC3_MAC_H |
| + |
| +#define MT_CT_PARSE_LEN 72 |
| +#define MT_CT_DMA_BUF_NUM 2 |
| + |
| +#define MT_RXD0_LENGTH GENMASK(15, 0) |
| +#define MT_RXD0_PKT_FLAG GENMASK(19, 16) |
| +#define MT_RXD0_PKT_TYPE GENMASK(31, 27) |
| + |
| +#define MT_RXD0_MESH BIT(18) |
| +#define MT_RXD0_MHCP BIT(19) |
| +#define MT_RXD0_NORMAL_ETH_TYPE_OFS GENMASK(22, 16) |
| +#define MT_RXD0_NORMAL_IP_SUM BIT(23) |
| +#define MT_RXD0_NORMAL_UDP_TCP_SUM BIT(24) |
| + |
| +#define MT_RXD0_SW_PKT_TYPE_MASK GENMASK(31, 16) |
| +#define MT_RXD0_SW_PKT_TYPE_MAP 0x380F |
| +#define MT_RXD0_SW_PKT_TYPE_FRAME 0x3801 |
| + |
| +/* RXD DW1 */ |
| +#define MT_RXD1_NORMAL_WLAN_IDX GENMASK(11, 0) |
| +#define MT_RXD1_NORMAL_GROUP_1 BIT(16) |
| +#define MT_RXD1_NORMAL_GROUP_2 BIT(17) |
| +#define MT_RXD1_NORMAL_GROUP_3 BIT(18) |
| +#define MT_RXD1_NORMAL_GROUP_4 BIT(19) |
| +#define MT_RXD1_NORMAL_GROUP_5 BIT(20) |
| +#define MT_RXD1_NORMAL_KEY_ID GENMASK(22, 21) |
| +#define MT_RXD1_NORMAL_CM BIT(23) |
| +#define MT_RXD1_NORMAL_CLM BIT(24) |
| +#define MT_RXD1_NORMAL_ICV_ERR BIT(25) |
| +#define MT_RXD1_NORMAL_TKIP_MIC_ERR BIT(26) |
| +#define MT_RXD1_NORMAL_BAND_IDX GENMASK(28, 27) |
| +#define MT_RXD1_NORMAL_SPP_EN BIT(29) |
| +#define MT_RXD1_NORMAL_ADD_OM BIT(30) |
| +#define MT_RXD1_NORMAL_SEC_DONE BIT(31) |
| + |
| +/* RXD DW2 */ |
| +#define MT_RXD2_NORMAL_BSSID GENMASK(5, 0) |
| +#define MT_RXD2_NORMAL_MAC_HDR_LEN GENMASK(12, 8) |
| +#define MT_RXD2_NORMAL_HDR_TRANS BIT(7) |
| +#define MT_RXD2_NORMAL_HDR_OFFSET GENMASK(15, 13) |
| +#define MT_RXD2_NORMAL_SEC_MODE GENMASK(20, 16) |
| +#define MT_RXD2_NORMAL_MU_BAR BIT(21) |
| +#define MT_RXD2_NORMAL_SW_BIT BIT(22) |
| +#define MT_RXD2_NORMAL_AMSDU_ERR BIT(23) |
| +#define MT_RXD2_NORMAL_MAX_LEN_ERROR BIT(24) |
| +#define MT_RXD2_NORMAL_HDR_TRANS_ERROR BIT(25) |
| +#define MT_RXD2_NORMAL_INT_FRAME BIT(26) |
| +#define MT_RXD2_NORMAL_FRAG BIT(27) |
| +#define MT_RXD2_NORMAL_NULL_FRAME BIT(28) |
| +#define MT_RXD2_NORMAL_NDATA BIT(29) |
| +#define MT_RXD2_NORMAL_NON_AMPDU BIT(30) |
| +#define MT_RXD2_NORMAL_BF_REPORT BIT(31) |
| + |
| +/* RXD DW3 */ |
| +#define MT_RXD3_NORMAL_RXV_SEQ GENMASK(7, 0) |
| +#define MT_RXD3_NORMAL_CH_FREQ GENMASK(15, 8) |
| +#define MT_RXD3_NORMAL_ADDR_TYPE GENMASK(17, 16) |
| +#define MT_RXD3_NORMAL_U2M BIT(0) |
| +#define MT_RXD3_NORMAL_HTC_VLD BIT(18) |
| +#define MT_RXD3_NORMAL_BEACON_MC BIT(20) |
| +#define MT_RXD3_NORMAL_BEACON_UC BIT(21) |
| +#define MT_RXD3_NORMAL_CO_ANT BIT(22) |
| +#define MT_RXD3_NORMAL_FCS_ERR BIT(24) |
| +#define MT_RXD3_NORMAL_VLAN2ETH BIT(31) |
| + |
| +/* RXD DW4 */ |
| +#define MT_RXD4_NORMAL_PAYLOAD_FORMAT GENMASK(1, 0) |
| +#define MT_RXD4_FIRST_AMSDU_FRAME GENMASK(1, 0) |
| +#define MT_RXD4_MID_AMSDU_FRAME BIT(1) |
| +#define MT_RXD4_LAST_AMSDU_FRAME BIT(0) |
| + |
| +#define MT_RXV_HDR_BAND_IDX BIT(24) |
| + |
| +/* RXD GROUP4 */ |
| +#define MT_RXD8_FRAME_CONTROL GENMASK(15, 0) |
| + |
| +#define MT_RXD10_SEQ_CTRL GENMASK(15, 0) |
| +#define MT_RXD10_QOS_CTL GENMASK(31, 16) |
| + |
| +#define MT_RXD11_HT_CONTROL GENMASK(31, 0) |
| + |
| +/* P-RXV */ |
| +#define MT_PRXV_TX_RATE GENMASK(6, 0) |
| +#define MT_PRXV_TX_DCM BIT(4) |
| +#define MT_PRXV_TX_ER_SU_106T BIT(5) |
| +#define MT_PRXV_NSTS GENMASK(10, 7) |
| +#define MT_PRXV_TXBF BIT(11) |
| +#define MT_PRXV_HT_AD_CODE BIT(12) |
| +#define MT_PRXV_HE_RU_ALLOC GENMASK(30, 22) |
| +#define MT_PRXV_RCPI3 GENMASK(31, 24) |
| +#define MT_PRXV_RCPI2 GENMASK(23, 16) |
| +#define MT_PRXV_RCPI1 GENMASK(15, 8) |
| +#define MT_PRXV_RCPI0 GENMASK(7, 0) |
| +#define MT_PRXV_HT_SHORT_GI GENMASK(4, 3) |
| +#define MT_PRXV_HT_STBC GENMASK(10, 9) |
| +#define MT_PRXV_TX_MODE GENMASK(14, 11) |
| +#define MT_PRXV_FRAME_MODE GENMASK(2, 0) |
| +#define MT_PRXV_DCM BIT(5) |
| + |
| +/* C-RXV */ |
| +#define MT_CRXV_HE_NUM_USER GENMASK(26, 20) |
| +#define MT_CRXV_HE_LTF_SIZE GENMASK(28, 27) |
| +#define MT_CRXV_HE_LDPC_EXT_SYM BIT(30) |
| + |
| +#define MT_CRXV_HE_PE_DISAMBIG BIT(1) |
| +#define MT_CRXV_HE_UPLINK BIT(2) |
| + |
| +#define MT_CRXV_HE_MU_AID GENMASK(27, 17) |
| +#define MT_CRXV_HE_BEAM_CHNG BIT(29) |
| + |
| +#define MT_CRXV_HE_DOPPLER BIT(0) |
| +#define MT_CRXV_HE_BSS_COLOR GENMASK(15, 10) |
| +#define MT_CRXV_HE_TXOP_DUR GENMASK(19, 17) |
| + |
| +#define MT_CRXV_HE_SR_MASK GENMASK(11, 8) |
| +#define MT_CRXV_HE_SR1_MASK GENMASK(16, 12) |
| +#define MT_CRXV_HE_SR2_MASK GENMASK(20, 17) |
| +#define MT_CRXV_HE_SR3_MASK GENMASK(24, 21) |
| + |
| +#define MT_CRXV_HE_RU0 GENMASK(8, 0) |
| +#define MT_CRXV_HE_RU1 GENMASK(17, 9) |
| +#define MT_CRXV_HE_RU2 GENMASK(26, 18) |
| +#define MT_CRXV_HE_RU3_L GENMASK(31, 27) |
| +#define MT_CRXV_HE_RU3_H GENMASK(3, 0) |
| + |
| +enum tx_header_format { |
| + MT_HDR_FORMAT_802_3, |
| + MT_HDR_FORMAT_CMD, |
| + MT_HDR_FORMAT_802_11, |
| + MT_HDR_FORMAT_802_11_EXT, |
| +}; |
| + |
| +enum tx_pkt_type { |
| + MT_TX_TYPE_CT, |
| + MT_TX_TYPE_SF, |
| + MT_TX_TYPE_CMD, |
| + MT_TX_TYPE_FW, |
| +}; |
| + |
| +enum tx_port_idx { |
| + MT_TX_PORT_IDX_LMAC, |
| + MT_TX_PORT_IDX_MCU |
| +}; |
| + |
| +enum tx_mcu_port_q_idx { |
| + MT_TX_MCU_PORT_RX_Q0 = 0x20, |
| + MT_TX_MCU_PORT_RX_Q1, |
| + MT_TX_MCU_PORT_RX_Q2, |
| + MT_TX_MCU_PORT_RX_Q3, |
| + MT_TX_MCU_PORT_RX_FWDL = 0x3e |
| +}; |
| + |
| +enum tx_mgnt_type { |
| + MT_TX_NORMAL, |
| + MT_TX_TIMING, |
| + MT_TX_ADDBA, |
| +}; |
| + |
| +#define MT_CT_INFO_APPLY_TXD BIT(0) |
| +#define MT_CT_INFO_COPY_HOST_TXD_ALL BIT(1) |
| +#define MT_CT_INFO_MGMT_FRAME BIT(2) |
| +#define MT_CT_INFO_NONE_CIPHER_FRAME BIT(3) |
| +#define MT_CT_INFO_HSR2_TX BIT(4) |
| +#define MT_CT_INFO_FROM_HOST BIT(7) |
| + |
| +#define MT_TXD_SIZE (8 * 4) |
| + |
| +#define MT_TXD0_Q_IDX GENMASK(31, 25) |
| +#define MT_TXD0_PKT_FMT GENMASK(24, 23) |
| +#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16) |
| +#define MT_TXD0_TX_BYTES GENMASK(15, 0) |
| + |
| +#define MT_TXD1_FIXED_RATE BIT(31) |
| +#define MT_TXD1_OWN_MAC GENMASK(30, 25) |
| +#define MT_TXD1_TID GENMASK(24, 21) |
| +#define MT_TXD1_BIP BIT(24) |
| +#define MT_TXD1_ETH_802_3 BIT(20) |
| +#define MT_TXD1_HDR_INFO GENMASK(20, 16) |
| +#define MT_TXD1_HDR_FORMAT GENMASK(15, 14) |
| +#define MT_TXD1_TGID GENMASK(13, 12) |
| +#define MT_TXD1_WLAN_IDX GENMASK(11, 0) |
| + |
| +#define MT_TXD2_POWER_OFFSET GENMASK(31, 26) |
| +#define MT_TXD2_MAX_TX_TIME GENMASK(25, 16) |
| +#define MT_TXD2_FRAG GENMASK(15, 14) |
| +#define MT_TXD2_HTC_VLD BIT(13) |
| +#define MT_TXD2_DURATION BIT(12) |
| +#define MT_TXD2_HDR_PAD GENMASK(11, 10) |
| +#define MT_TXD2_RTS BIT(9) |
| +#define MT_TXD2_OWN_MAC_MAP BIT(8) |
| +#define MT_TXD2_BF_TYPE GENMASK(6, 7) |
| +#define MT_TXD2_FRAME_TYPE GENMASK(5, 4) |
| +#define MT_TXD2_SUB_TYPE GENMASK(3, 0) |
| + |
| +#define MT_TXD3_SN_VALID BIT(31) |
| +#define MT_TXD3_PN_VALID BIT(30) |
| +#define MT_TXD3_SW_POWER_MGMT BIT(29) |
| +#define MT_TXD3_BA_DISABLE BIT(28) |
| +#define MT_TXD3_SEQ GENMASK(27, 16) |
| +#define MT_TXD3_REM_TX_COUNT GENMASK(15, 11) |
| +#define MT_TXD3_TX_COUNT GENMASK(10, 6) |
| +#define MT_TXD3_HW_AMSDU BIT(5) |
| +#define MT_TXD3_BCM BIT(4) |
| +#define MT_TXD3_EEOSP BIT(3) |
| +#define MT_TXD3_EMRD BIT(2) |
| +#define MT_TXD3_PROTECT_FRAME BIT(1) |
| +#define MT_TXD3_NO_ACK BIT(0) |
| + |
| +#define MT_TXD4_PN_LOW GENMASK(31, 0) |
| + |
| +#define MT_TXD5_PN_HIGH GENMASK(31, 16) |
| +#define MT_TXD5_FL BIT(15) |
| +#define MT_TXD5_BYPASS_TBB BIT(14) |
| +#define MT_TXD5_BYPASS_RBB BIT(13) |
| +#define MT_TXD5_BSS_COLOR_ZERO BIT(12) |
| +#define MT_TXD5_TX_STATUS_HOST BIT(10) |
| +#define MT_TXD5_TX_STATUS_MCU BIT(9) |
| +#define MT_TXD5_TX_STATUS_FMT BIT(8) |
| +#define MT_TXD5_PID GENMASK(7, 0) |
| + |
| +#define MT_TXD6_TX_SRC GENMASK(31, 30) |
| +#define MT_TXD6_VTA BIT(28) |
| +#define MT_TXD6_BW GENMASK(25, 22) |
| +#define MT_TXD6_TX_RATE GENMASK(21, 16) |
| +#define MT_TXD6_TIMESTAMP_OFS_EN BIT(15) |
| +#define MT_TXD6_TIMESTAMP_OFS_IDX GENMASK(14, 10) |
| +#define MT_TXD6_MSDU_CNT GENMASK(9, 4) |
| +#define MT_TXD6_DIS_MAT BIT(3) |
| +#define MT_TXD6_DAS BIT(2) |
| +#define MT_TXD6_AMSDU_CAP BIT(1) |
| + |
| +#define MT_TXD7_TXD_LEN GENMASK(31, 30) |
| +#define MT_TXD7_IP_SUM BIT(29) |
| +#define MT_TXD7_DROP_BY_SDO BIT(28) |
| +#define MT_TXD7_MAC_TXD BIT(27) |
| +#define MT_TXD7_CTXD BIT(26) |
| +#define MT_TXD7_CTXD_CNT GENMASK(25, 22) |
| +#define MT_TXD7_UDP_TCP_SUM BIT(15) |
| +#define MT_TXD7_TX_TIME GENMASK(9, 0) |
| + |
| +#define MT_TX_RATE_STBC BIT(14) |
| +#define MT_TX_RATE_NSS GENMASK(13, 10) |
| +#define MT_TX_RATE_MODE GENMASK(9, 6) |
| +#define MT_TX_RATE_SU_EXT_TONE BIT(5) |
| +#define MT_TX_RATE_DCM BIT(4) |
| +/* VHT/HE only use bits 0-3 */ |
| +#define MT_TX_RATE_IDX GENMASK(5, 0) |
| + |
| +#define MT_TXFREE0_PKT_TYPE GENMASK(31, 27) |
| +#define MT_TXFREE0_MSDU_CNT GENMASK(25, 16) |
| +#define MT_TXFREE0_RX_BYTE GENMASK(15, 0) |
| + |
| +#define MT_TXFREE1_VER GENMASK(18, 16) |
| + |
| +#define MT_TXFREE_INFO_PAIR BIT(31) |
| +#define MT_TXFREE_INFO_HEADER BIT(30) |
| +#define MT_TXFREE_INFO_WLAN_ID GENMASK(23, 12) |
| +#define MT_TXFREE_INFO_MSDU_ID GENMASK(14, 0) |
| +#define MT_TXFREE_INFO_COUNT GENMASK(27, 24) |
| +#define MT_TXFREE_INFO_STAT GENMASK(29, 28) |
| + |
| +#define MT_TXS0_BW GENMASK(31, 29) |
| +#define MT_TXS0_TID GENMASK(28, 26) |
| +#define MT_TXS0_AMPDU BIT(25) |
| +#define MT_TXS0_TXS_FORMAT GENMASK(24, 23) |
| +#define MT_TXS0_BA_ERROR BIT(22) |
| +#define MT_TXS0_PS_FLAG BIT(21) |
| +#define MT_TXS0_TXOP_TIMEOUT BIT(20) |
| +#define MT_TXS0_BIP_ERROR BIT(19) |
| + |
| +#define MT_TXS0_QUEUE_TIMEOUT BIT(18) |
| +#define MT_TXS0_RTS_TIMEOUT BIT(17) |
| +#define MT_TXS0_ACK_TIMEOUT BIT(16) |
| +#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16) |
| + |
| +#define MT_TXS0_TX_STATUS_HOST BIT(15) |
| +#define MT_TXS0_TX_STATUS_MCU BIT(14) |
| +#define MT_TXS0_TX_RATE GENMASK(13, 0) |
| + |
| +#define MT_TXS1_SEQNO GENMASK(31, 20) |
| +#define MT_TXS1_RESP_RATE GENMASK(19, 16) |
| +#define MT_TXS1_RXV_SEQNO GENMASK(15, 8) |
| +#define MT_TXS1_TX_POWER_DBM GENMASK(7, 0) |
| + |
| +#define MT_TXS2_BF_STATUS GENMASK(31, 30) |
| +#define MT_TXS2_BAND GENMASK(29, 28) |
| +#define MT_TXS2_WCID GENMASK(27, 16) |
| +#define MT_TXS2_TX_DELAY GENMASK(15, 0) |
| + |
| +#define MT_TXS3_PID GENMASK(31, 24) |
| +#define MT_TXS3_RATE_STBC BIT(7) |
| +#define MT_TXS3_FIXED_RATE BIT(6) |
| +#define MT_TXS3_SRC GENMASK(5, 4) |
| +#define MT_TXS3_SHARED_ANTENNA BIT(3) |
| +#define MT_TXS3_LAST_TX_RATE GENMASK(2, 0) |
| + |
| +#define MT_TXS4_TIMESTAMP GENMASK(31, 0) |
| + |
| +#define MT_TXS5_F0_FINAL_MPDU BIT(31) |
| +#define MT_TXS5_F0_QOS BIT(30) |
| +#define MT_TXS5_F0_TX_COUNT GENMASK(29, 25) |
| +#define MT_TXS5_F0_FRONT_TIME GENMASK(24, 0) |
| +#define MT_TXS5_F1_MPDU_TX_COUNT GENMASK(31, 24) |
| +#define MT_TXS5_F1_MPDU_TX_BYTES GENMASK(23, 0) |
| + |
| +#define MT_TXS6_F0_NOISE_3 GENMASK(31, 24) |
| +#define MT_TXS6_F0_NOISE_2 GENMASK(23, 16) |
| +#define MT_TXS6_F0_NOISE_1 GENMASK(15, 8) |
| +#define MT_TXS6_F0_NOISE_0 GENMASK(7, 0) |
| +#define MT_TXS6_F1_MPDU_FAIL_COUNT GENMASK(31, 24) |
| +#define MT_TXS6_F1_MPDU_FAIL_BYTES GENMASK(23, 0) |
| + |
| +#define MT_TXS7_F0_RCPI_3 GENMASK(31, 24) |
| +#define MT_TXS7_F0_RCPI_2 GENMASK(23, 16) |
| +#define MT_TXS7_F0_RCPI_1 GENMASK(15, 8) |
| +#define MT_TXS7_F0_RCPI_0 GENMASK(7, 0) |
| +#define MT_TXS7_F1_MPDU_RETRY_COUNT GENMASK(31, 24) |
| +#define MT_TXS7_F1_MPDU_RETRY_BYTES GENMASK(23, 0) |
| + |
| +#endif /* __MT76_CONNAC3_MAC_H */ |
| diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c |
| index ee0fbfcd..ee5177fd 100644 |
| --- a/mt76_connac_mac.c |
| +++ b/mt76_connac_mac.c |
| @@ -495,6 +495,7 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, |
| BSS_CHANGED_BEACON_ENABLED)); |
| bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | |
| BSS_CHANGED_FILS_DISCOVERY)); |
| + bool amsdu_en = wcid->amsdu; |
| |
| if (vif) { |
| struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; |
| @@ -521,9 +522,9 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, |
| q_idx = wmm_idx * MT76_CONNAC_MAX_WMM_SETS + |
| mt76_connac_lmac_mapping(skb_get_queue_mapping(skb)); |
| |
| - /* counting non-offloading skbs */ |
| - wcid->stats.tx_bytes += skb->len; |
| - wcid->stats.tx_packets++; |
| + /* mt7915 WA only counts WED path */ |
| + if (is_mt7915(dev) && mtk_wed_device_active(&dev->mmio.wed)) |
| + wcid->stats.tx_packets++; |
| } |
| |
| val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) | |
| @@ -554,12 +555,14 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, |
| txwi[4] = 0; |
| |
| val = FIELD_PREP(MT_TXD5_PID, pid); |
| - if (pid >= MT_PACKET_ID_FIRST) |
| + if (pid >= MT_PACKET_ID_FIRST) { |
| val |= MT_TXD5_TX_STATUS_HOST; |
| + amsdu_en = amsdu_en && !is_mt7921(dev); |
| + } |
| |
| txwi[5] = cpu_to_le32(val); |
| txwi[6] = 0; |
| - txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0; |
| + txwi[7] = amsdu_en ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0; |
| |
| if (is_8023) |
| mt76_connac2_mac_write_txwi_8023(txwi, skb, wcid); |
| @@ -606,11 +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); |
| - stats->tx_packets += |
| - le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_CNT); |
| + le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) - |
| + le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE); |
| stats->tx_failed += |
| le32_get_bits(txs_data[6], MT_TXS6_MPDU_FAIL_CNT); |
| stats->tx_retries += |
| @@ -728,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); |
| } |
| @@ -1111,3 +1112,85 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev, |
| return 0; |
| } |
| EXPORT_SYMBOL_GPL(mt76_connac2_mac_fill_rx_rate); |
| + |
| +void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) |
| +{ |
| + struct mt76_wcid *wcid; |
| + u16 fc, tid; |
| + u32 val; |
| + |
| + if (!sta || |
| + !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he)) |
| + return; |
| + |
| + tid = le32_get_bits(txwi[1], MT_TXD1_TID); |
| + if (tid >= 6) /* skip VO queue */ |
| + return; |
| + |
| + val = le32_to_cpu(txwi[2]); |
| + fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 | |
| + FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4; |
| + if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA))) |
| + return; |
| + |
| + wcid = (struct mt76_wcid *)sta->drv_priv; |
| + if (!test_and_set_bit(tid, &wcid->ampdu_state)) |
| + ieee80211_start_tx_ba_session(sta, tid, 0); |
| +} |
| +EXPORT_SYMBOL_GPL(mt76_connac2_tx_check_aggr); |
| + |
| +void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t, |
| + struct ieee80211_sta *sta, |
| + struct list_head *free_list) |
| +{ |
| + struct mt76_wcid *wcid; |
| + __le32 *txwi; |
| + u16 wcid_idx; |
| + |
| + mt76_connac_txp_skb_unmap(dev, t); |
| + if (!t->skb) |
| + goto out; |
| + |
| + txwi = (__le32 *)mt76_get_txwi_ptr(dev, t); |
| + if (sta) { |
| + wcid = (struct mt76_wcid *)sta->drv_priv; |
| + wcid_idx = wcid->idx; |
| + } else { |
| + wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX); |
| + wcid = rcu_dereference(dev->wcid[wcid_idx]); |
| + |
| + if (wcid && wcid->sta) { |
| + sta = container_of((void *)wcid, struct ieee80211_sta, |
| + drv_priv); |
| + spin_lock_bh(&dev->sta_poll_lock); |
| + if (list_empty(&wcid->poll_list)) |
| + list_add_tail(&wcid->poll_list, |
| + &dev->sta_poll_list); |
| + spin_unlock_bh(&dev->sta_poll_lock); |
| + } |
| + } |
| + |
| + if (sta && likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE))) |
| + mt76_connac2_tx_check_aggr(sta, txwi); |
| + |
| + __mt76_tx_complete_skb(dev, wcid_idx, t->skb, free_list); |
| +out: |
| + t->skb = NULL; |
| + mt76_put_txwi(dev, t); |
| +} |
| +EXPORT_SYMBOL_GPL(mt76_connac2_txwi_free); |
| + |
| +void mt76_connac2_tx_token_put(struct mt76_dev *dev) |
| +{ |
| + struct mt76_txwi_cache *txwi; |
| + int id; |
| + |
| + spin_lock_bh(&dev->token_lock); |
| + idr_for_each_entry(&dev->token, txwi, id) { |
| + mt76_connac2_txwi_free(dev, txwi, NULL, NULL); |
| + dev->token_count--; |
| + } |
| + spin_unlock_bh(&dev->token_lock); |
| + idr_destroy(&dev->token); |
| +} |
| +EXPORT_SYMBOL_GPL(mt76_connac2_tx_token_put); |
| diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c |
| index 46f69aa8..0f0a519f 100644 |
| --- a/mt76_connac_mcu.c |
| +++ b/mt76_connac_mcu.c |
| @@ -1221,6 +1221,9 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv); |
| |
| int mt76_connac_mcu_sta_wed_update(struct mt76_dev *dev, struct sk_buff *skb) |
| { |
| + if (!mt76_is_mmio(dev)) |
| + return 0; |
| + |
| if (!mtk_wed_device_active(&dev->mmio.wed)) |
| return 0; |
| |
| diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h |
| index 91d98eff..fe729bbf 100644 |
| --- a/mt76_connac_mcu.h |
| +++ b/mt76_connac_mcu.h |
| @@ -22,6 +22,7 @@ |
| |
| #define FW_START_OVERRIDE BIT(0) |
| #define FW_START_WORKING_PDA_CR4 BIT(2) |
| +#define FW_START_WORKING_PDA_DSP BIT(3) |
| |
| #define PATCH_SEC_NOT_SUPPORT GENMASK(31, 0) |
| #define PATCH_SEC_TYPE_MASK GENMASK(15, 0) |
| @@ -518,7 +519,8 @@ struct sta_rec_muru { |
| u8 uo_ra; |
| u8 he_2x996_tone; |
| u8 rx_t_frame_11ac; |
| - u8 rsv[3]; |
| + u8 rx_ctrl_frame_to_mbss; |
| + u8 rsv[2]; |
| } ofdma_ul; |
| |
| struct { |
| @@ -998,6 +1000,7 @@ enum { |
| MCU_EXT_EVENT_ASSERT_DUMP = 0x23, |
| MCU_EXT_EVENT_RDD_REPORT = 0x3a, |
| MCU_EXT_EVENT_CSA_NOTIFY = 0x4f, |
| + MCU_EXT_EVENT_WA_TX_STAT = 0x74, |
| MCU_EXT_EVENT_BCC_NOTIFY = 0x75, |
| MCU_EXT_EVENT_MURU_CTRL = 0x9f, |
| }; |
| @@ -1287,6 +1290,7 @@ enum { |
| UNI_BSS_INFO_UAPSD = 19, |
| UNI_BSS_INFO_PS = 21, |
| UNI_BSS_INFO_BCNFT = 22, |
| + UNI_BSS_INFO_IFS_TIME = 23, |
| UNI_BSS_INFO_OFFLOAD = 25, |
| UNI_BSS_INFO_MLD = 26, |
| }; |
| diff --git a/mt76x02_util.c b/mt76x02_util.c |
| index dcbb5c60..a9b77083 100644 |
| --- a/mt76x02_util.c |
| +++ b/mt76x02_util.c |
| @@ -413,12 +413,9 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
| struct mt76x02_sta *msta; |
| struct mt76_wcid *wcid; |
| int idx = key->keyidx; |
| - int ret; |
| |
| /* fall back to sw encryption for unsupported ciphers */ |
| switch (key->cipher) { |
| - case WLAN_CIPHER_SUITE_WEP40: |
| - case WLAN_CIPHER_SUITE_WEP104: |
| case WLAN_CIPHER_SUITE_TKIP: |
| case WLAN_CIPHER_SUITE_CCMP: |
| break; |
| @@ -471,16 +468,6 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
| } |
| mt76_wcid_key_setup(&dev->mt76, wcid, key); |
| |
| - if (!msta) { |
| - if (key || wcid->hw_key_idx == idx) { |
| - ret = mt76x02_mac_wcid_set_key(dev, wcid->idx, key); |
| - if (ret) |
| - return ret; |
| - } |
| - |
| - return mt76x02_mac_shared_key_setup(dev, mvif->idx, idx, key); |
| - } |
| - |
| return mt76x02_mac_wcid_set_key(dev, msta->wcid.idx, key); |
| } |
| EXPORT_SYMBOL_GPL(mt76x02_set_key); |
| diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c |
| index 879884ea..6c3696c8 100644 |
| --- a/mt7915/debugfs.c |
| +++ b/mt7915/debugfs.c |
| @@ -251,7 +251,6 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) |
| { |
| struct mt7915_phy *phy = file->private; |
| struct mt7915_dev *dev = phy->dev; |
| - struct mt7915_mcu_muru_stats mu_stats = {}; |
| static const char * const dl_non_he_type[] = { |
| "CCK", "OFDM", "HT MIX", "HT GF", |
| "VHT SU", "VHT 2MU", "VHT 3MU", "VHT 4MU" |
| @@ -275,7 +274,7 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) |
| |
| mutex_lock(&dev->mt76.mutex); |
| |
| - ret = mt7915_mcu_muru_debug_get(phy, &mu_stats); |
| + ret = mt7915_mcu_muru_debug_get(phy); |
| if (ret) |
| goto exit; |
| |
| @@ -285,14 +284,13 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) |
| for (i = 0; i < 5; i++) |
| seq_printf(file, "%8s | ", dl_non_he_type[i]); |
| |
| -#define __dl_u32(s) le32_to_cpu(mu_stats.dl.s) |
| seq_puts(file, "\nTotal Count:"); |
| seq_printf(file, "%8u | %8u | %8u | %8u | %8u | ", |
| - __dl_u32(cck_cnt), |
| - __dl_u32(ofdm_cnt), |
| - __dl_u32(htmix_cnt), |
| - __dl_u32(htgf_cnt), |
| - __dl_u32(vht_su_cnt)); |
| + phy->mib.dl_cck_cnt, |
| + phy->mib.dl_ofdm_cnt, |
| + phy->mib.dl_htmix_cnt, |
| + phy->mib.dl_htgf_cnt, |
| + phy->mib.dl_vht_su_cnt); |
| |
| seq_puts(file, "\nDownlink MU-MIMO\nData Type: "); |
| |
| @@ -301,23 +299,23 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) |
| |
| seq_puts(file, "\nTotal Count:"); |
| seq_printf(file, "%8u | %8u | %8u | ", |
| - __dl_u32(vht_2mu_cnt), |
| - __dl_u32(vht_3mu_cnt), |
| - __dl_u32(vht_4mu_cnt)); |
| + phy->mib.dl_vht_2mu_cnt, |
| + phy->mib.dl_vht_3mu_cnt, |
| + phy->mib.dl_vht_4mu_cnt); |
| |
| - sub_total_cnt = __dl_u32(vht_2mu_cnt) + |
| - __dl_u32(vht_3mu_cnt) + |
| - __dl_u32(vht_4mu_cnt); |
| + sub_total_cnt = phy->mib.dl_vht_2mu_cnt + |
| + phy->mib.dl_vht_3mu_cnt + |
| + phy->mib.dl_vht_4mu_cnt; |
| |
| seq_printf(file, "\nTotal non-HE MU-MIMO DL PPDU count: %lld", |
| sub_total_cnt); |
| |
| total_ppdu_cnt = sub_total_cnt + |
| - __dl_u32(cck_cnt) + |
| - __dl_u32(ofdm_cnt) + |
| - __dl_u32(htmix_cnt) + |
| - __dl_u32(htgf_cnt) + |
| - __dl_u32(vht_su_cnt); |
| + phy->mib.dl_cck_cnt + |
| + phy->mib.dl_ofdm_cnt + |
| + phy->mib.dl_htmix_cnt + |
| + phy->mib.dl_htgf_cnt + |
| + phy->mib.dl_vht_su_cnt; |
| |
| seq_printf(file, "\nAll non-HE DL PPDU count: %lld", total_ppdu_cnt); |
| |
| @@ -329,8 +327,7 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) |
| |
| seq_puts(file, "\nTotal Count:"); |
| seq_printf(file, "%8u | %8u | ", |
| - __dl_u32(he_su_cnt), |
| - __dl_u32(he_ext_su_cnt)); |
| + phy->mib.dl_he_su_cnt, phy->mib.dl_he_ext_su_cnt); |
| |
| seq_puts(file, "\nDownlink MU-MIMO\nData Type: "); |
| |
| @@ -339,9 +336,8 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) |
| |
| seq_puts(file, "\nTotal Count:"); |
| seq_printf(file, "%8u | %8u | %8u | ", |
| - __dl_u32(he_2mu_cnt), |
| - __dl_u32(he_3mu_cnt), |
| - __dl_u32(he_4mu_cnt)); |
| + phy->mib.dl_he_2mu_cnt, phy->mib.dl_he_3mu_cnt, |
| + phy->mib.dl_he_4mu_cnt); |
| |
| seq_puts(file, "\nDownlink OFDMA\nData Type: "); |
| |
| @@ -350,37 +346,35 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) |
| |
| seq_puts(file, "\nTotal Count:"); |
| seq_printf(file, "%8u | %8u | %8u | %8u | %9u | %8u | ", |
| - __dl_u32(he_2ru_cnt), |
| - __dl_u32(he_3ru_cnt), |
| - __dl_u32(he_4ru_cnt), |
| - __dl_u32(he_5to8ru_cnt), |
| - __dl_u32(he_9to16ru_cnt), |
| - __dl_u32(he_gtr16ru_cnt)); |
| - |
| - sub_total_cnt = __dl_u32(he_2mu_cnt) + |
| - __dl_u32(he_3mu_cnt) + |
| - __dl_u32(he_4mu_cnt); |
| + phy->mib.dl_he_2ru_cnt, |
| + phy->mib.dl_he_3ru_cnt, |
| + phy->mib.dl_he_4ru_cnt, |
| + phy->mib.dl_he_5to8ru_cnt, |
| + phy->mib.dl_he_9to16ru_cnt, |
| + phy->mib.dl_he_gtr16ru_cnt); |
| + |
| + sub_total_cnt = phy->mib.dl_he_2mu_cnt + |
| + phy->mib.dl_he_3mu_cnt + |
| + phy->mib.dl_he_4mu_cnt; |
| total_ppdu_cnt = sub_total_cnt; |
| |
| seq_printf(file, "\nTotal HE MU-MIMO DL PPDU count: %lld", |
| sub_total_cnt); |
| |
| - sub_total_cnt = __dl_u32(he_2ru_cnt) + |
| - __dl_u32(he_3ru_cnt) + |
| - __dl_u32(he_4ru_cnt) + |
| - __dl_u32(he_5to8ru_cnt) + |
| - __dl_u32(he_9to16ru_cnt) + |
| - __dl_u32(he_gtr16ru_cnt); |
| + sub_total_cnt = phy->mib.dl_he_2ru_cnt + |
| + phy->mib.dl_he_3ru_cnt + |
| + phy->mib.dl_he_4ru_cnt + |
| + phy->mib.dl_he_5to8ru_cnt + |
| + phy->mib.dl_he_9to16ru_cnt + |
| + phy->mib.dl_he_gtr16ru_cnt; |
| total_ppdu_cnt += sub_total_cnt; |
| |
| seq_printf(file, "\nTotal HE OFDMA DL PPDU count: %lld", |
| sub_total_cnt); |
| |
| - total_ppdu_cnt += __dl_u32(he_su_cnt) + |
| - __dl_u32(he_ext_su_cnt); |
| + total_ppdu_cnt += phy->mib.dl_he_su_cnt + phy->mib.dl_he_ext_su_cnt; |
| |
| seq_printf(file, "\nAll HE DL PPDU count: %lld", total_ppdu_cnt); |
| -#undef __dl_u32 |
| |
| /* HE Uplink */ |
| seq_puts(file, "\n\nUplink"); |
| @@ -389,12 +383,11 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) |
| for (i = 0; i < 3; i++) |
| seq_printf(file, "%8s | ", ul_he_type[i]); |
| |
| -#define __ul_u32(s) le32_to_cpu(mu_stats.ul.s) |
| seq_puts(file, "\nTotal Count:"); |
| seq_printf(file, "%8u | %8u | %8u | ", |
| - __ul_u32(hetrig_2mu_cnt), |
| - __ul_u32(hetrig_3mu_cnt), |
| - __ul_u32(hetrig_4mu_cnt)); |
| + phy->mib.ul_hetrig_2mu_cnt, |
| + phy->mib.ul_hetrig_3mu_cnt, |
| + phy->mib.ul_hetrig_4mu_cnt); |
| |
| seq_puts(file, "\nTrigger-based Uplink OFDMA\nData Type: "); |
| |
| @@ -403,37 +396,36 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data) |
| |
| seq_puts(file, "\nTotal Count:"); |
| seq_printf(file, "%8u | %8u | %8u | %8u | %8u | %9u | %7u | ", |
| - __ul_u32(hetrig_su_cnt), |
| - __ul_u32(hetrig_2ru_cnt), |
| - __ul_u32(hetrig_3ru_cnt), |
| - __ul_u32(hetrig_4ru_cnt), |
| - __ul_u32(hetrig_5to8ru_cnt), |
| - __ul_u32(hetrig_9to16ru_cnt), |
| - __ul_u32(hetrig_gtr16ru_cnt)); |
| - |
| - sub_total_cnt = __ul_u32(hetrig_2mu_cnt) + |
| - __ul_u32(hetrig_3mu_cnt) + |
| - __ul_u32(hetrig_4mu_cnt); |
| + phy->mib.ul_hetrig_su_cnt, |
| + phy->mib.ul_hetrig_2ru_cnt, |
| + phy->mib.ul_hetrig_3ru_cnt, |
| + phy->mib.ul_hetrig_4ru_cnt, |
| + phy->mib.ul_hetrig_5to8ru_cnt, |
| + phy->mib.ul_hetrig_9to16ru_cnt, |
| + phy->mib.ul_hetrig_gtr16ru_cnt); |
| + |
| + sub_total_cnt = phy->mib.ul_hetrig_2mu_cnt + |
| + phy->mib.ul_hetrig_3mu_cnt + |
| + phy->mib.ul_hetrig_4mu_cnt; |
| total_ppdu_cnt = sub_total_cnt; |
| |
| seq_printf(file, "\nTotal HE MU-MIMO UL TB PPDU count: %lld", |
| sub_total_cnt); |
| |
| - sub_total_cnt = __ul_u32(hetrig_2ru_cnt) + |
| - __ul_u32(hetrig_3ru_cnt) + |
| - __ul_u32(hetrig_4ru_cnt) + |
| - __ul_u32(hetrig_5to8ru_cnt) + |
| - __ul_u32(hetrig_9to16ru_cnt) + |
| - __ul_u32(hetrig_gtr16ru_cnt); |
| + sub_total_cnt = phy->mib.ul_hetrig_2ru_cnt + |
| + phy->mib.ul_hetrig_3ru_cnt + |
| + phy->mib.ul_hetrig_4ru_cnt + |
| + phy->mib.ul_hetrig_5to8ru_cnt + |
| + phy->mib.ul_hetrig_9to16ru_cnt + |
| + phy->mib.ul_hetrig_gtr16ru_cnt; |
| total_ppdu_cnt += sub_total_cnt; |
| |
| seq_printf(file, "\nTotal HE OFDMA UL TB PPDU count: %lld", |
| sub_total_cnt); |
| |
| - total_ppdu_cnt += __ul_u32(hetrig_su_cnt); |
| + total_ppdu_cnt += phy->mib.ul_hetrig_su_cnt; |
| |
| seq_printf(file, "\nAll HE UL TB PPDU count: %lld\n", total_ppdu_cnt); |
| -#undef __ul_u32 |
| |
| exit: |
| mutex_unlock(&dev->mt76.mutex); |
| @@ -719,10 +711,10 @@ mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy, |
| static void |
| mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s) |
| { |
| + struct mt76_mib_stats *mib = &phy->mib; |
| static const char * const bw[] = { |
| "BW20", "BW40", "BW80", "BW160" |
| }; |
| - struct mib_stats *mib = &phy->mib; |
| |
| /* Tx Beamformer monitor */ |
| seq_puts(s, "\nTx Beamformer applied PPDU counts: "); |
| @@ -768,7 +760,7 @@ mt7915_tx_stats_show(struct seq_file *file, void *data) |
| { |
| struct mt7915_phy *phy = file->private; |
| struct mt7915_dev *dev = phy->dev; |
| - struct mib_stats *mib = &phy->mib; |
| + struct mt76_mib_stats *mib = &phy->mib; |
| int i; |
| |
| mutex_lock(&dev->mt76.mutex); |
| diff --git a/mt7915/dma.c b/mt7915/dma.c |
| index 86a93ded..59a44d79 100644 |
| --- a/mt7915/dma.c |
| +++ b/mt7915/dma.c |
| @@ -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_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); |
| - } |
| - |
| - 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) |
| @@ -560,7 +576,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2) |
| mt7915_poll_tx); |
| napi_enable(&dev->mt76.tx_napi); |
| |
| - mt7915_dma_enable(dev); |
| + mt7915_dma_enable(dev, false); |
| |
| return 0; |
| } |
| @@ -642,7 +658,7 @@ int mt7915_dma_reset(struct mt7915_dev *dev, bool force) |
| mt76_rmw(dev, MT_WFDMA0_EXT0_CFG, MT_WFDMA0_EXT0_RXWB_KEEP, |
| MT_WFDMA0_EXT0_RXWB_KEEP); |
| |
| - mt7915_dma_enable(dev); |
| + mt7915_dma_enable(dev, !force); |
| |
| return 0; |
| } |
| diff --git a/mt7915/init.c b/mt7915/init.c |
| index f85f7d39..e156a3c2 100644 |
| --- a/mt7915/init.c |
| +++ b/mt7915/init.c |
| @@ -505,6 +505,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 |
| @@ -587,6 +593,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); |
| @@ -1164,7 +1172,7 @@ 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); |
| |
| @@ -1183,9 +1191,7 @@ int mt7915_register_device(struct mt7915_dev *dev) |
| INIT_WORK(&dev->rc_work, mt7915_mac_sta_rc_work); |
| INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7915_mac_work); |
| INIT_LIST_HEAD(&dev->sta_rc_list); |
| - INIT_LIST_HEAD(&dev->sta_poll_list); |
| INIT_LIST_HEAD(&dev->twt_list); |
| - spin_lock_init(&dev->sta_poll_lock); |
| |
| init_waitqueue_head(&dev->reset_wait); |
| INIT_WORK(&dev->reset_work, mt7915_mac_reset_work); |
| diff --git a/mt7915/mac.c b/mt7915/mac.c |
| index fb6bab87..b8b0c0fd 100644 |
| --- a/mt7915/mac.c |
| +++ b/mt7915/mac.c |
| @@ -105,9 +105,9 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev) |
| LIST_HEAD(sta_poll_list); |
| int i; |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - list_splice_init(&dev->sta_poll_list, &sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| rcu_read_lock(); |
| |
| @@ -118,15 +118,15 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev) |
| s8 rssi[4]; |
| u8 bw; |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| if (list_empty(&sta_poll_list)) { |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| break; |
| } |
| msta = list_first_entry(&sta_poll_list, |
| - struct mt7915_sta, poll_list); |
| - list_del_init(&msta->poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + struct mt7915_sta, wcid.poll_list); |
| + list_del_init(&msta->wcid.poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| idx = msta->wcid.idx; |
| |
| @@ -326,10 +326,11 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb, |
| |
| if (status->wcid) { |
| msta = container_of(status->wcid, struct mt7915_sta, wcid); |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (list_empty(&msta->poll_list)) |
| - list_add_tail(&msta->poll_list, &dev->sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + if (list_empty(&msta->wcid.poll_list)) |
| + list_add_tail(&msta->wcid.poll_list, |
| + &dev->mt76.sta_poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| } |
| |
| status->freq = mphy->chandef.chan->center_freq; |
| @@ -841,74 +842,6 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id) |
| return MT_TXD_SIZE + sizeof(*txp); |
| } |
| |
| -static void |
| -mt7915_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) |
| -{ |
| - struct mt7915_sta *msta; |
| - u16 fc, tid; |
| - u32 val; |
| - |
| - if (!sta || !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he)) |
| - return; |
| - |
| - tid = le32_get_bits(txwi[1], MT_TXD1_TID); |
| - if (tid >= 6) /* skip VO queue */ |
| - return; |
| - |
| - val = le32_to_cpu(txwi[2]); |
| - fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 | |
| - FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4; |
| - if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA))) |
| - return; |
| - |
| - msta = (struct mt7915_sta *)sta->drv_priv; |
| - if (!test_and_set_bit(tid, &msta->ampdu_state)) |
| - ieee80211_start_tx_ba_session(sta, tid, 0); |
| -} |
| - |
| -static void |
| -mt7915_txwi_free(struct mt7915_dev *dev, struct mt76_txwi_cache *t, |
| - struct ieee80211_sta *sta, struct list_head *free_list) |
| -{ |
| - struct mt76_dev *mdev = &dev->mt76; |
| - struct mt7915_sta *msta; |
| - struct mt76_wcid *wcid; |
| - __le32 *txwi; |
| - u16 wcid_idx; |
| - |
| - mt76_connac_txp_skb_unmap(mdev, t); |
| - if (!t->skb) |
| - goto out; |
| - |
| - txwi = (__le32 *)mt76_get_txwi_ptr(mdev, t); |
| - if (sta) { |
| - wcid = (struct mt76_wcid *)sta->drv_priv; |
| - wcid_idx = wcid->idx; |
| - } else { |
| - wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX); |
| - wcid = rcu_dereference(dev->mt76.wcid[wcid_idx]); |
| - |
| - if (wcid && wcid->sta) { |
| - msta = container_of(wcid, struct mt7915_sta, wcid); |
| - sta = container_of((void *)msta, struct ieee80211_sta, |
| - drv_priv); |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (list_empty(&msta->poll_list)) |
| - list_add_tail(&msta->poll_list, &dev->sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| - } |
| - } |
| - |
| - if (sta && likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE))) |
| - mt7915_tx_check_aggr(sta, txwi); |
| - |
| - __mt76_tx_complete_skb(mdev, wcid_idx, t->skb, free_list); |
| - |
| -out: |
| - t->skb = NULL; |
| - mt76_put_txwi(mdev, t); |
| -} |
| - |
| static void |
| mt7915_mac_tx_free_prepare(struct mt7915_dev *dev) |
| { |
| @@ -951,6 +884,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len) |
| struct mt76_dev *mdev = &dev->mt76; |
| struct mt76_txwi_cache *txwi; |
| struct ieee80211_sta *sta = NULL; |
| + struct mt76_wcid *wcid = NULL; |
| LIST_HEAD(free_list); |
| void *end = data + len; |
| bool v3, wake = false; |
| @@ -977,7 +911,6 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len) |
| info = le32_to_cpu(*cur_info); |
| if (info & MT_TX_FREE_PAIR) { |
| struct mt7915_sta *msta; |
| - struct mt76_wcid *wcid; |
| u16 idx; |
| |
| idx = FIELD_GET(MT_TX_FREE_WLAN_ID, info); |
| @@ -987,14 +920,33 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len) |
| continue; |
| |
| msta = container_of(wcid, struct mt7915_sta, wcid); |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (list_empty(&msta->poll_list)) |
| - list_add_tail(&msta->poll_list, &dev->sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&mdev->sta_poll_lock); |
| + if (list_empty(&msta->wcid.poll_list)) |
| + list_add_tail(&msta->wcid.poll_list, |
| + &mdev->sta_poll_list); |
| + spin_unlock_bh(&mdev->sta_poll_lock); |
| continue; |
| } |
| |
| - if (v3 && (info & MT_TX_FREE_MPDU_HEADER)) |
| + if (!mtk_wed_device_active(&mdev->mmio.wed) && wcid) { |
| + u32 tx_retries = 0, tx_failed = 0; |
| + |
| + if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3)) { |
| + tx_retries = |
| + FIELD_GET(MT_TX_FREE_COUNT_V3, info) - 1; |
| + tx_failed = tx_retries + |
| + !!FIELD_GET(MT_TX_FREE_STAT_V3, info); |
| + } else if (!v3 && (info & MT_TX_FREE_MPDU_HEADER)) { |
| + tx_retries = |
| + FIELD_GET(MT_TX_FREE_COUNT, info) - 1; |
| + tx_failed = tx_retries + |
| + !!FIELD_GET(MT_TX_FREE_STAT, info); |
| + } |
| + wcid->stats.tx_retries += tx_retries; |
| + wcid->stats.tx_failed += tx_failed; |
| + } |
| + |
| + if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3)) |
| continue; |
| |
| for (i = 0; i < 1 + v3; i++) { |
| @@ -1010,7 +962,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len) |
| if (!txwi) |
| continue; |
| |
| - mt7915_txwi_free(dev, txwi, sta, &free_list); |
| + mt76_connac2_txwi_free(mdev, txwi, sta, &free_list); |
| } |
| } |
| |
| @@ -1042,7 +994,7 @@ mt7915_mac_tx_free_v0(struct mt7915_dev *dev, void *data, int len) |
| if (!txwi) |
| continue; |
| |
| - mt7915_txwi_free(dev, txwi, NULL, &free_list); |
| + mt76_connac2_txwi_free(mdev, txwi, NULL, &free_list); |
| } |
| |
| mt7915_mac_tx_free_done(dev, &free_list, wake); |
| @@ -1081,10 +1033,10 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data) |
| if (!wcid->sta) |
| goto out; |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (list_empty(&msta->poll_list)) |
| - list_add_tail(&msta->poll_list, &dev->sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + if (list_empty(&msta->wcid.poll_list)) |
| + list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| out: |
| rcu_read_unlock(); |
| @@ -1357,20 +1309,6 @@ mt7915_update_beacons(struct mt7915_dev *dev) |
| mt7915_update_vif_beacon, mphy_ext->hw); |
| } |
| |
| -void mt7915_tx_token_put(struct mt7915_dev *dev) |
| -{ |
| - struct mt76_txwi_cache *txwi; |
| - int id; |
| - |
| - spin_lock_bh(&dev->mt76.token_lock); |
| - idr_for_each_entry(&dev->mt76.token, txwi, id) { |
| - mt7915_txwi_free(dev, txwi, NULL, NULL); |
| - dev->mt76.token_count--; |
| - } |
| - spin_unlock_bh(&dev->mt76.token_lock); |
| - idr_destroy(&dev->mt76.token); |
| -} |
| - |
| static int |
| mt7915_mac_restart(struct mt7915_dev *dev) |
| { |
| @@ -1389,8 +1327,12 @@ mt7915_mac_restart(struct mt7915_dev *dev) |
| |
| if (dev_is_pci(mdev->dev)) { |
| mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0); |
| - if (dev->hif2) |
| - mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0x0); |
| + if (dev->hif2) { |
| + if (is_mt7915(mdev)) |
| + mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0x0); |
| + else |
| + mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE_MT7916, 0x0); |
| + } |
| } |
| |
| set_bit(MT76_RESET, &dev->mphy.state); |
| @@ -1415,7 +1357,7 @@ mt7915_mac_restart(struct mt7915_dev *dev) |
| napi_disable(&dev->mt76.tx_napi); |
| |
| /* token reinit */ |
| - mt7915_tx_token_put(dev); |
| + mt76_connac2_tx_token_put(&dev->mt76); |
| idr_init(&dev->mt76.token); |
| |
| mt7915_dma_reset(dev, true); |
| @@ -1440,8 +1382,12 @@ mt7915_mac_restart(struct mt7915_dev *dev) |
| } |
| if (dev_is_pci(mdev->dev)) { |
| mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); |
| - if (dev->hif2) |
| - mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff); |
| + if (dev->hif2) { |
| + if (is_mt7915(mdev)) |
| + mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff); |
| + else |
| + mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE_MT7916, 0xff); |
| + } |
| } |
| |
| /* load firmware */ |
| @@ -1604,13 +1550,19 @@ void mt7915_mac_reset_work(struct work_struct *work) |
| if (mt7915_wait_reset_state(dev, MT_MCU_CMD_RESET_DONE)) { |
| mt7915_dma_reset(dev, false); |
| |
| - mt7915_tx_token_put(dev); |
| + mt76_connac2_tx_token_put(&dev->mt76); |
| idr_init(&dev->mt76.token); |
| |
| mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_DMA_INIT); |
| mt7915_wait_reset_state(dev, MT_MCU_CMD_RECOVERY_DONE); |
| } |
| |
| + mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE); |
| + mt7915_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE); |
| + |
| + /* enable DMA Tx/Rx and interrupt */ |
| + mt7915_dma_start(dev, false, false); |
| + |
| clear_bit(MT76_MCU_RESET, &dev->mphy.state); |
| clear_bit(MT76_RESET, &dev->mphy.state); |
| if (phy2) |
| @@ -1625,9 +1577,6 @@ void mt7915_mac_reset_work(struct work_struct *work) |
| |
| tasklet_schedule(&dev->mt76.irq_tasklet); |
| |
| - mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE); |
| - mt7915_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE); |
| - |
| mt76_worker_enable(&dev->mt76.tx_worker); |
| |
| local_bh_disable(); |
| @@ -1747,8 +1696,8 @@ void mt7915_reset(struct mt7915_dev *dev) |
| |
| void mt7915_mac_update_stats(struct mt7915_phy *phy) |
| { |
| + struct mt76_mib_stats *mib = &phy->mib; |
| struct mt7915_dev *dev = phy->dev; |
| - struct mib_stats *mib = &phy->mib; |
| int i, aggr0 = 0, aggr1, cnt; |
| u8 band = phy->mt76->band_idx; |
| u32 val; |
| @@ -2010,7 +1959,7 @@ void mt7915_mac_sta_rc_work(struct work_struct *work) |
| u32 changed; |
| LIST_HEAD(list); |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| list_splice_init(&dev->sta_rc_list, &list); |
| |
| while (!list_empty(&list)) { |
| @@ -2018,7 +1967,7 @@ void mt7915_mac_sta_rc_work(struct work_struct *work) |
| list_del_init(&msta->rc_list); |
| changed = msta->changed; |
| msta->changed = 0; |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| sta = container_of((void *)msta, struct ieee80211_sta, drv_priv); |
| vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv); |
| @@ -2031,10 +1980,10 @@ void mt7915_mac_sta_rc_work(struct work_struct *work) |
| if (changed & IEEE80211_RC_SMPS_CHANGED) |
| mt7915_mcu_add_smps(dev, vif, sta); |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| } |
| |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| } |
| |
| void mt7915_mac_work(struct work_struct *work) |
| @@ -2054,6 +2003,9 @@ void mt7915_mac_work(struct work_struct *work) |
| |
| mt7915_mac_update_stats(phy); |
| mt7915_mac_severe_check(phy); |
| + |
| + if (phy->dev->muru_debug) |
| + mt7915_mcu_muru_debug_get(phy); |
| } |
| |
| mutex_unlock(&mphy->dev->mutex); |
| diff --git a/mt7915/mac.h b/mt7915/mac.h |
| index ce94f87e..448b1b38 100644 |
| --- a/mt7915/mac.h |
| +++ b/mt7915/mac.h |
| @@ -9,7 +9,12 @@ |
| #define MT_TX_FREE_VER GENMASK(18, 16) |
| #define MT_TX_FREE_MSDU_CNT_V0 GENMASK(6, 0) |
| /* 0: success, others: dropped */ |
| -#define MT_TX_FREE_MPDU_HEADER BIT(30) |
| +#define MT_TX_FREE_COUNT GENMASK(12, 0) |
| +#define MT_TX_FREE_COUNT_V3 GENMASK(27, 24) |
| +#define MT_TX_FREE_STAT GENMASK(14, 13) |
| +#define MT_TX_FREE_STAT_V3 GENMASK(29, 28) |
| +#define MT_TX_FREE_MPDU_HEADER BIT(15) |
| +#define MT_TX_FREE_MPDU_HEADER_V3 BIT(30) |
| #define MT_TX_FREE_MSDU_ID_V3 GENMASK(14, 0) |
| |
| #define MT_TXS5_F0_FINAL_MPDU BIT(31) |
| diff --git a/mt7915/main.c b/mt7915/main.c |
| index 8ce7b1c5..ca5631f5 100644 |
| --- a/mt7915/main.c |
| +++ b/mt7915/main.c |
| @@ -248,7 +248,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, |
| idx = MT7915_WTBL_RESERVED - mvif->mt76.idx; |
| |
| INIT_LIST_HEAD(&mvif->sta.rc_list); |
| - INIT_LIST_HEAD(&mvif->sta.poll_list); |
| + INIT_LIST_HEAD(&mvif->sta.wcid.poll_list); |
| mvif->sta.wcid.idx = idx; |
| mvif->sta.wcid.phy_idx = ext_phy; |
| mvif->sta.wcid.hw_key_idx = -1; |
| @@ -308,10 +308,10 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw, |
| phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx); |
| mutex_unlock(&dev->mt76.mutex); |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (!list_empty(&msta->poll_list)) |
| - list_del_init(&msta->poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + if (!list_empty(&msta->wcid.poll_list)) |
| + list_del_init(&msta->wcid.poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| mt76_packet_id_flush(&dev->mt76, &msta->wcid); |
| } |
| @@ -629,11 +629,6 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, |
| } |
| } |
| |
| - if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) { |
| - mt7915_mcu_add_bss_info(phy, vif, true); |
| - mt7915_mcu_add_sta(dev, vif, NULL, true); |
| - } |
| - |
| /* ensure that enable txcmd_mode after bss_info */ |
| if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED)) |
| mt7915_mcu_set_tx(dev, vif); |
| @@ -653,6 +648,37 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, |
| mutex_unlock(&dev->mt76.mutex); |
| } |
| |
| +static int |
| +mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| + struct ieee80211_bss_conf *link_conf) |
| +{ |
| + struct mt7915_phy *phy = mt7915_hw_phy(hw); |
| + struct mt7915_dev *dev = mt7915_hw_dev(hw); |
| + int err; |
| + |
| + mutex_lock(&dev->mt76.mutex); |
| + |
| + err = mt7915_mcu_add_bss_info(phy, vif, true); |
| + if (err) |
| + goto out; |
| + err = mt7915_mcu_add_sta(dev, vif, NULL, true); |
| +out: |
| + mutex_unlock(&dev->mt76.mutex); |
| + |
| + return err; |
| +} |
| + |
| +static void |
| +mt7915_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| + struct ieee80211_bss_conf *link_conf) |
| +{ |
| + struct mt7915_dev *dev = mt7915_hw_dev(hw); |
| + |
| + mutex_lock(&dev->mt76.mutex); |
| + mt7915_mcu_add_sta(dev, vif, NULL, false); |
| + mutex_unlock(&dev->mt76.mutex); |
| +} |
| + |
| static void |
| mt7915_channel_switch_beacon(struct ieee80211_hw *hw, |
| struct ieee80211_vif *vif, |
| @@ -679,7 +705,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
| return -ENOSPC; |
| |
| INIT_LIST_HEAD(&msta->rc_list); |
| - INIT_LIST_HEAD(&msta->poll_list); |
| + INIT_LIST_HEAD(&msta->wcid.poll_list); |
| msta->vif = mvif; |
| msta->wcid.sta = 1; |
| msta->wcid.idx = idx; |
| @@ -714,12 +740,12 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
| for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++) |
| mt7915_mac_twt_teardown_flow(dev, msta, i); |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (!list_empty(&msta->poll_list)) |
| - list_del_init(&msta->poll_list); |
| + spin_lock_bh(&mdev->sta_poll_lock); |
| + if (!list_empty(&msta->wcid.poll_list)) |
| + list_del_init(&msta->wcid.poll_list); |
| if (!list_empty(&msta->rc_list)) |
| list_del_init(&msta->rc_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_unlock_bh(&mdev->sta_poll_lock); |
| } |
| |
| static void mt7915_tx(struct ieee80211_hw *hw, |
| @@ -801,16 +827,16 @@ mt7915_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| case IEEE80211_AMPDU_TX_STOP_FLUSH: |
| case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: |
| mtxq->aggr = false; |
| - clear_bit(tid, &msta->ampdu_state); |
| + clear_bit(tid, &msta->wcid.ampdu_state); |
| ret = mt7915_mcu_add_tx_ba(dev, params, false); |
| break; |
| case IEEE80211_AMPDU_TX_START: |
| - set_bit(tid, &msta->ampdu_state); |
| + set_bit(tid, &msta->wcid.ampdu_state); |
| ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; |
| break; |
| case IEEE80211_AMPDU_TX_STOP_CONT: |
| mtxq->aggr = false; |
| - clear_bit(tid, &msta->ampdu_state); |
| + clear_bit(tid, &msta->wcid.ampdu_state); |
| ret = mt7915_mcu_add_tx_ba(dev, params, false); |
| ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
| break; |
| @@ -842,7 +868,7 @@ mt7915_get_stats(struct ieee80211_hw *hw, |
| { |
| struct mt7915_phy *phy = mt7915_hw_phy(hw); |
| struct mt7915_dev *dev = mt7915_hw_dev(hw); |
| - struct mib_stats *mib = &phy->mib; |
| + struct mt76_mib_stats *mib = &phy->mib; |
| |
| mutex_lock(&dev->mt76.mutex); |
| |
| @@ -1019,21 +1045,20 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, |
| sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE); |
| } |
| |
| - if (!txrate->legacy && !txrate->flags) |
| - return; |
| - |
| - if (txrate->legacy) { |
| - sinfo->txrate.legacy = txrate->legacy; |
| - } else { |
| - sinfo->txrate.mcs = txrate->mcs; |
| - sinfo->txrate.nss = txrate->nss; |
| - sinfo->txrate.bw = txrate->bw; |
| - sinfo->txrate.he_gi = txrate->he_gi; |
| - sinfo->txrate.he_dcm = txrate->he_dcm; |
| - sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc; |
| + if (txrate->legacy || txrate->flags) { |
| + if (txrate->legacy) { |
| + sinfo->txrate.legacy = txrate->legacy; |
| + } else { |
| + sinfo->txrate.mcs = txrate->mcs; |
| + sinfo->txrate.nss = txrate->nss; |
| + sinfo->txrate.bw = txrate->bw; |
| + sinfo->txrate.he_gi = txrate->he_gi; |
| + sinfo->txrate.he_dcm = txrate->he_dcm; |
| + sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc; |
| + } |
| + sinfo->txrate.flags = txrate->flags; |
| + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); |
| } |
| - sinfo->txrate.flags = txrate->flags; |
| - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); |
| |
| /* offloading flows bypass networking stack, so driver counts and |
| * reports sta statistics via NL80211_STA_INFO when WED is active. |
| @@ -1042,14 +1067,10 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, |
| sinfo->tx_bytes = msta->wcid.stats.tx_bytes; |
| sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64); |
| |
| - sinfo->tx_packets = msta->wcid.stats.tx_packets; |
| - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); |
| - |
| - sinfo->tx_failed = msta->wcid.stats.tx_failed; |
| - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); |
| - |
| - sinfo->tx_retries = msta->wcid.stats.tx_retries; |
| - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); |
| + if (!mt7915_mcu_wed_wa_tx_stats(phy->dev, msta->wcid.idx)) { |
| + sinfo->tx_packets = msta->wcid.stats.tx_packets; |
| + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); |
| + } |
| |
| if (mtk_wed_get_rx_capa(&phy->dev->mt76.mmio.wed)) { |
| sinfo->rx_bytes = msta->wcid.stats.rx_bytes; |
| @@ -1060,6 +1081,12 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, |
| } |
| } |
| |
| + sinfo->tx_failed = msta->wcid.stats.tx_failed; |
| + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); |
| + |
| + sinfo->tx_retries = msta->wcid.stats.tx_retries; |
| + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); |
| + |
| sinfo->ack_signal = (s8)msta->ack_signal; |
| sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL); |
| |
| @@ -1073,11 +1100,11 @@ static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta) |
| struct mt7915_dev *dev = msta->vif->phy->dev; |
| u32 *changed = data; |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| msta->changed |= *changed; |
| if (list_empty(&msta->rc_list)) |
| list_add_tail(&msta->rc_list, &dev->sta_rc_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| } |
| |
| static void mt7915_sta_rc_update(struct ieee80211_hw *hw, |
| @@ -1253,6 +1280,38 @@ static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = { |
| "rx_vec_queue_overflow_drop_cnt", |
| "rx_ba_cnt", |
| |
| + /* muru mu-mimo and ofdma related stats */ |
| + "dl_cck_cnt", |
| + "dl_ofdm_cnt", |
| + "dl_htmix_cnt", |
| + "dl_htgf_cnt", |
| + "dl_vht_su_cnt", |
| + "dl_vht_2mu_cnt", |
| + "dl_vht_3mu_cnt", |
| + "dl_vht_4mu_cnt", |
| + "dl_he_su_cnt", |
| + "dl_he_ext_su_cnt", |
| + "dl_he_2ru_cnt", |
| + "dl_he_2mu_cnt", |
| + "dl_he_3ru_cnt", |
| + "dl_he_3mu_cnt", |
| + "dl_he_4ru_cnt", |
| + "dl_he_4mu_cnt", |
| + "dl_he_5to8ru_cnt", |
| + "dl_he_9to16ru_cnt", |
| + "dl_he_gtr16ru_cnt", |
| + |
| + "ul_hetrig_su_cnt", |
| + "ul_hetrig_2ru_cnt", |
| + "ul_hetrig_3ru_cnt", |
| + "ul_hetrig_4ru_cnt", |
| + "ul_hetrig_5to8ru_cnt", |
| + "ul_hetrig_9to16ru_cnt", |
| + "ul_hetrig_gtr16ru_cnt", |
| + "ul_hetrig_2mu_cnt", |
| + "ul_hetrig_3mu_cnt", |
| + "ul_hetrig_4mu_cnt", |
| + |
| /* per vif counters */ |
| "v_tx_mode_cck", |
| "v_tx_mode_ofdm", |
| @@ -1279,6 +1338,10 @@ static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = { |
| "v_tx_mcs_9", |
| "v_tx_mcs_10", |
| "v_tx_mcs_11", |
| + "v_tx_nss_1", |
| + "v_tx_nss_2", |
| + "v_tx_nss_3", |
| + "v_tx_nss_4", |
| }; |
| |
| #define MT7915_SSTATS_LEN ARRAY_SIZE(mt7915_gstrings_stats) |
| @@ -1326,11 +1389,11 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw, |
| struct mt7915_dev *dev = mt7915_hw_dev(hw); |
| struct mt7915_phy *phy = mt7915_hw_phy(hw); |
| struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; |
| + struct mt76_mib_stats *mib = &phy->mib; |
| struct mt76_ethtool_worker_info wi = { |
| .data = data, |
| .idx = mvif->mt76.idx, |
| }; |
| - struct mib_stats *mib = &phy->mib; |
| /* See mt7915_ampdu_stat_read_phy, etc */ |
| int i, ei = 0, stats_size; |
| |
| @@ -1403,6 +1466,37 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw, |
| data[ei++] = mib->rx_vec_queue_overflow_drop_cnt; |
| data[ei++] = mib->rx_ba_cnt; |
| |
| + data[ei++] = mib->dl_cck_cnt; |
| + data[ei++] = mib->dl_ofdm_cnt; |
| + data[ei++] = mib->dl_htmix_cnt; |
| + data[ei++] = mib->dl_htgf_cnt; |
| + data[ei++] = mib->dl_vht_su_cnt; |
| + data[ei++] = mib->dl_vht_2mu_cnt; |
| + data[ei++] = mib->dl_vht_3mu_cnt; |
| + data[ei++] = mib->dl_vht_4mu_cnt; |
| + data[ei++] = mib->dl_he_su_cnt; |
| + data[ei++] = mib->dl_he_ext_su_cnt; |
| + data[ei++] = mib->dl_he_2ru_cnt; |
| + data[ei++] = mib->dl_he_2mu_cnt; |
| + data[ei++] = mib->dl_he_3ru_cnt; |
| + data[ei++] = mib->dl_he_3mu_cnt; |
| + data[ei++] = mib->dl_he_4ru_cnt; |
| + data[ei++] = mib->dl_he_4mu_cnt; |
| + data[ei++] = mib->dl_he_5to8ru_cnt; |
| + data[ei++] = mib->dl_he_9to16ru_cnt; |
| + data[ei++] = mib->dl_he_gtr16ru_cnt; |
| + |
| + data[ei++] = mib->ul_hetrig_su_cnt; |
| + data[ei++] = mib->ul_hetrig_2ru_cnt; |
| + data[ei++] = mib->ul_hetrig_3ru_cnt; |
| + data[ei++] = mib->ul_hetrig_4ru_cnt; |
| + data[ei++] = mib->ul_hetrig_5to8ru_cnt; |
| + data[ei++] = mib->ul_hetrig_9to16ru_cnt; |
| + data[ei++] = mib->ul_hetrig_gtr16ru_cnt; |
| + data[ei++] = mib->ul_hetrig_2mu_cnt; |
| + data[ei++] = mib->ul_hetrig_3mu_cnt; |
| + data[ei++] = mib->ul_hetrig_4mu_cnt; |
| + |
| /* Add values for all stations owned by this vif */ |
| wi.initial_stat_idx = ei; |
| ieee80211_iterate_stations_atomic(hw, mt7915_ethtool_worker, &wi); |
| @@ -1540,6 +1634,8 @@ const struct ieee80211_ops mt7915_ops = { |
| .conf_tx = mt7915_conf_tx, |
| .configure_filter = mt7915_configure_filter, |
| .bss_info_changed = mt7915_bss_info_changed, |
| + .start_ap = mt7915_start_ap, |
| + .stop_ap = mt7915_stop_ap, |
| .sta_add = mt7915_sta_add, |
| .sta_remove = mt7915_sta_remove, |
| .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove, |
| diff --git a/mt7915/mcu.c b/mt7915/mcu.c |
| index aa706ff6..71eeb54a 100644 |
| --- a/mt7915/mcu.c |
| +++ b/mt7915/mcu.c |
| @@ -167,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)) { |
| @@ -277,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) && |
| @@ -398,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); |
| @@ -2115,12 +2119,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 { |
| @@ -2136,7 +2139,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; |
| @@ -3736,6 +3775,62 @@ int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev, |
| &req, sizeof(req), true); |
| } |
| |
| +int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wlan_idx) |
| +{ |
| + struct { |
| + __le32 cmd; |
| + __le32 num; |
| + __le32 __rsv; |
| + __le16 wlan_idx; |
| + } req = { |
| + .cmd = cpu_to_le32(0x15), |
| + .num = cpu_to_le32(1), |
| + .wlan_idx = cpu_to_le16(wlan_idx), |
| + }; |
| + struct mt7915_mcu_wa_tx_stat { |
| + __le16 wlan_idx; |
| + u8 __rsv[2]; |
| + |
| + /* tx_bytes is deprecated since WA byte counter uses u32, |
| + * which easily leads to overflow. |
| + */ |
| + __le32 tx_bytes; |
| + __le32 tx_packets; |
| + } *res; |
| + struct mt76_wcid *wcid; |
| + struct sk_buff *skb; |
| + int ret; |
| + |
| + ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WA_PARAM_CMD(QUERY), |
| + &req, sizeof(req), true, &skb); |
| + if (ret) |
| + return ret; |
| + |
| + if (!is_mt7915(&dev->mt76)) |
| + skb_pull(skb, 4); |
| + |
| + res = (struct mt7915_mcu_wa_tx_stat *)skb->data; |
| + |
| + if (le16_to_cpu(res->wlan_idx) != wlan_idx) { |
| + ret = -EINVAL; |
| + goto out; |
| + } |
| + |
| + rcu_read_lock(); |
| + |
| + wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]); |
| + if (wcid) |
| + wcid->stats.tx_packets += le32_to_cpu(res->tx_packets); |
| + else |
| + ret = -EINVAL; |
| + |
| + rcu_read_unlock(); |
| +out: |
| + dev_kfree_skb(skb); |
| + |
| + return ret; |
| +} |
| + |
| int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set) |
| { |
| struct { |
| diff --git a/mt7915/mmio.c b/mt7915/mmio.c |
| index 984b5f60..fc7ace63 100644 |
| --- a/mt7915/mmio.c |
| +++ b/mt7915/mmio.c |
| @@ -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) |
| @@ -1064,7 +1038,7 @@ static int __init mt7915_init(void) |
| goto error_pci; |
| |
| if (IS_ENABLED(CONFIG_MT798X_WMAC)) { |
| - ret = platform_driver_register(&mt7986_wmac_driver); |
| + ret = platform_driver_register(&mt798x_wmac_driver); |
| if (ret) |
| goto error_wmac; |
| } |
| @@ -1082,7 +1056,7 @@ error_pci: |
| static void __exit mt7915_exit(void) |
| { |
| if (IS_ENABLED(CONFIG_MT798X_WMAC)) |
| - platform_driver_unregister(&mt7986_wmac_driver); |
| + platform_driver_unregister(&mt798x_wmac_driver); |
| |
| pci_unregister_driver(&mt7915_pci_driver); |
| pci_unregister_driver(&mt7915_hif_driver); |
| diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h |
| index 103cd0d7..0c7226b8 100644 |
| --- a/mt7915/mt7915.h |
| +++ b/mt7915/mt7915.h |
| @@ -136,7 +136,6 @@ struct mt7915_sta { |
| |
| struct mt7915_vif *vif; |
| |
| - struct list_head poll_list; |
| struct list_head rc_list; |
| u32 airtime_ac[8]; |
| |
| @@ -145,7 +144,6 @@ struct mt7915_sta { |
| |
| unsigned long changed; |
| unsigned long jiffies; |
| - unsigned long ampdu_state; |
| struct mt76_connac_sta_key_conf bip; |
| |
| struct { |
| @@ -164,67 +162,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; |
| @@ -270,7 +207,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 |
| @@ -335,9 +272,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; |
| |
| @@ -437,7 +372,7 @@ 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_MT798X_WMAC |
| int mt7986_wmac_enable(struct mt7915_dev *dev); |
| @@ -472,6 +407,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); |
| @@ -545,6 +481,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); |
| @@ -618,7 +555,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); |
| @@ -629,7 +565,7 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy); |
| void mt7915_set_stream_vht_txbf_caps(struct mt7915_phy *phy); |
| void mt7915_update_channel(struct mt76_phy *mphy); |
| int mt7915_mcu_muru_debug_set(struct mt7915_dev *dev, bool enable); |
| -int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy, void *ms); |
| +int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy); |
| int mt7915_mcu_wed_enable_rx_stats(struct mt7915_dev *dev); |
| int mt7915_init_debugfs(struct mt7915_phy *phy); |
| void mt7915_debugfs_rx_fw_monitor(struct mt7915_dev *dev, const void *data, int len); |
| diff --git a/mt7915/regs.h b/mt7915/regs.h |
| index 374677f7..588cd87e 100644 |
| --- a/mt7915/regs.h |
| +++ b/mt7915/regs.h |
| @@ -145,6 +145,9 @@ enum offs_rev { |
| #define MT_PLE_BASE 0x820c0000 |
| #define MT_PLE(ofs) (MT_PLE_BASE + (ofs)) |
| |
| +#define MT_PLE_HOST_RPT0 MT_PLE(0x030) |
| +#define MT_PLE_HOST_RPT0_TX_LATENCY BIT(3) |
| + |
| #define MT_FL_Q_EMPTY MT_PLE(__OFFS(PLE_FL_Q_EMPTY)) |
| #define MT_FL_Q0_CTRL MT_PLE(__OFFS(PLE_FL_Q_CTRL)) |
| #define MT_FL_Q2_CTRL MT_PLE(__OFFS(PLE_FL_Q_CTRL) + 0x8) |
| diff --git a/mt7915/soc.c b/mt7915/soc.c |
| index fffe3623..1f23e60f 100644 |
| --- a/mt7915/soc.c |
| +++ b/mt7915/soc.c |
| @@ -174,10 +174,11 @@ static u8 mt798x_wmac_check_adie_type(struct mt7915_dev *dev) |
| { |
| u32 val; |
| |
| + /* Only DBDC A-die is used with MT7981 */ |
| if (is_mt7981(&dev->mt76)) |
| return ADIE_DBDC; |
| - else |
| - val = readl(dev->sku + MT_TOP_POS_SKU); |
| + |
| + val = readl(dev->sku + MT_TOP_POS_SKU); |
| |
| return FIELD_GET(MT_TOP_POS_SKU_ADIE_DBDC_MASK, val); |
| } |
| @@ -268,10 +269,14 @@ static int mt798x_wmac_coninfra_check(struct mt7915_dev *dev) |
| u32 cur; |
| u32 con_infra_version; |
| |
| - if (is_mt7981(&dev->mt76)) |
| + if (is_mt7981(&dev->mt76)) { |
| con_infra_version = MT7981_CON_INFRA_VERSION; |
| - if (is_mt7986(&dev->mt76)) |
| + } else if (is_mt7986(&dev->mt76)) { |
| con_infra_version = MT7986_CON_INFRA_VERSION; |
| + } else { |
| + WARN_ON(1); |
| + return -EINVAL; |
| + } |
| |
| return read_poll_timeout(mt76_rr, cur, (cur == con_infra_version), |
| USEC_PER_MSEC, 50 * USEC_PER_MSEC, |
| @@ -308,12 +313,9 @@ static int mt798x_wmac_coninfra_setup(struct mt7915_dev *dev) |
| MT_TOP_MCU_EMI_BASE_MASK, val); |
| |
| if (is_mt7981(&dev->mt76)) { |
| - /* TODO: mt7981: unsure if we need this at all |
| - * This base could be also valid for the mt7986 */ |
| mt76_rmw_field(dev, MT_TOP_WF_AP_PERI_BASE, |
| MT_TOP_WF_AP_PERI_BASE_MASK, 0x300d0000 >> 16); |
| |
| - /* TODO: mt7986: replace by efuse reserved region? */ |
| mt76_rmw_field(dev, MT_TOP_EFUSE_BASE, |
| MT_TOP_EFUSE_BASE_MASK, 0x11f20000 >> 16); |
| } |
| @@ -519,10 +521,14 @@ static int mt798x_wmac_adie_patch_7976(struct mt7915_dev *dev, u8 adie) |
| rg_xo_01 = 0x1d59080f; |
| rg_xo_03 = 0x34c00fe0; |
| } else { |
| - if (is_mt7981(&dev->mt76)) |
| + if (is_mt7981(&dev->mt76)) { |
| rg_xo_01 = 0x1959c80f; |
| - else if (is_mt7986(&dev->mt76)) |
| + } else if (is_mt7986(&dev->mt76)) { |
| rg_xo_01 = 0x1959f80f; |
| + } else { |
| + WARN_ON(1); |
| + return -EINVAL; |
| + } |
| rg_xo_03 = 0x34d00fe0; |
| } |
| |
| @@ -644,10 +650,15 @@ static int mt7986_wmac_adie_patch_7975(struct mt7915_dev *dev, u8 adie) |
| return ret; |
| |
| /* turn on SX0 LTBUF */ |
| - if (is_mt7981(&dev->mt76)) |
| + if (is_mt7981(&dev->mt76)) { |
| ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000007); |
| - else if (is_mt7986(&dev->mt76)) |
| + } else if (is_mt7986(&dev->mt76)) { |
| ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000002); |
| + } else { |
| + WARN_ON(1); |
| + return -EINVAL; |
| + } |
| + |
| if (ret) |
| return ret; |
| |
| @@ -784,7 +795,6 @@ mt7986_wmac_afe_cal(struct mt7915_dev *dev, u8 adie, bool dbdc, u32 adie_type) |
| MT_AFE_RG_WBG_EN_WPLL_UP_MASK, 0x1); |
| usleep_range(60, 100); |
| |
| - /* TODO: mt7981: sets also bit WF4, but mt7986 doesn't need/allow this? */ |
| txcal = (MT_AFE_RG_WBG_EN_TXCAL_BT | |
| MT_AFE_RG_WBG_EN_TXCAL_WF0 | |
| MT_AFE_RG_WBG_EN_TXCAL_WF1 | |
| @@ -930,7 +940,6 @@ static int mt7986_wmac_wm_enable(struct mt7915_dev *dev, bool enable) |
| { |
| u32 cur; |
| |
| - /* TODO: check if this is really needed or should be also used for mt7981 */ |
| if (is_mt7986(&dev->mt76)) |
| mt76_wr(dev, MT_CONNINFRA_SKU_DEC_ADDR, 0); |
| |
| @@ -1217,7 +1226,7 @@ static int mt798x_wmac_init(struct mt7915_dev *dev) |
| return 0; |
| } |
| |
| -static int mt7986_wmac_probe(struct platform_device *pdev) |
| +static int mt798x_wmac_probe(struct platform_device *pdev) |
| { |
| void __iomem *mem_base; |
| struct mt7915_dev *dev; |
| @@ -1277,7 +1286,7 @@ free_device: |
| return ret; |
| } |
| |
| -static int mt7986_wmac_remove(struct platform_device *pdev) |
| +static int mt798x_wmac_remove(struct platform_device *pdev) |
| { |
| struct mt7915_dev *dev = platform_get_drvdata(pdev); |
| |
| @@ -1286,21 +1295,21 @@ static int mt7986_wmac_remove(struct platform_device *pdev) |
| return 0; |
| } |
| |
| -static const struct of_device_id mt7986_wmac_of_match[] = { |
| +static const struct of_device_id mt798x_wmac_of_match[] = { |
| { .compatible = "mediatek,mt7981-wmac", .data = (u32 *)0x7981 }, |
| { .compatible = "mediatek,mt7986-wmac", .data = (u32 *)0x7986 }, |
| {}, |
| }; |
| |
| -MODULE_DEVICE_TABLE(of, mt7986_wmac_of_match); |
| +MODULE_DEVICE_TABLE(of, mt798x_wmac_of_match); |
| |
| -struct platform_driver mt7986_wmac_driver = { |
| +struct platform_driver mt798x_wmac_driver = { |
| .driver = { |
| - .name = "mt7986-wmac", |
| - .of_match_table = mt7986_wmac_of_match, |
| + .name = "mt798x-wmac", |
| + .of_match_table = mt798x_wmac_of_match, |
| }, |
| - .probe = mt7986_wmac_probe, |
| - .remove = mt7986_wmac_remove, |
| + .probe = mt798x_wmac_probe, |
| + .remove = mt798x_wmac_remove, |
| }; |
| |
| MODULE_FIRMWARE(MT7986_FIRMWARE_WA); |
| diff --git a/mt7921/debugfs.c b/mt7921/debugfs.c |
| index d6b6edba..d6c66e77 100644 |
| --- a/mt7921/debugfs.c |
| +++ b/mt7921/debugfs.c |
| @@ -95,7 +95,7 @@ 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; |
| + struct mt76_mib_stats *mib = &phy->mib; |
| int i; |
| |
| mt7921_mutex_acquire(dev); |
| diff --git a/mt7921/dma.c b/mt7921/dma.c |
| index 73d8dc14..4153cd6c 100644 |
| --- a/mt7921/dma.c |
| +++ b/mt7921/dma.c |
| @@ -74,9 +74,9 @@ static int mt7921_dma_disable(struct mt7921_dev *dev, bool force) |
| MT_WFDMA0_GLO_CFG_OMIT_RX_INFO | |
| MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); |
| |
| - if (!mt76_poll(dev, MT_WFDMA0_GLO_CFG, |
| - MT_WFDMA0_GLO_CFG_TX_DMA_BUSY | |
| - MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000)) |
| + if (!mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG, |
| + MT_WFDMA0_GLO_CFG_TX_DMA_BUSY | |
| + MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1)) |
| return -ETIMEDOUT; |
| |
| /* disable dmashdl */ |
| @@ -231,10 +231,6 @@ int mt7921_dma_init(struct mt7921_dev *dev) |
| if (ret) |
| return ret; |
| |
| - ret = mt7921_wfsys_reset(dev); |
| - if (ret) |
| - return ret; |
| - |
| /* init tx queue */ |
| ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7921_TXQ_BAND0, |
| MT7921_TX_RING_SIZE, |
| diff --git a/mt7921/init.c b/mt7921/init.c |
| index e929f6eb..94b7cdfd 100644 |
| --- a/mt7921/init.c |
| +++ b/mt7921/init.c |
| @@ -2,6 +2,9 @@ |
| /* Copyright (C) 2020 MediaTek Inc. */ |
| |
| #include <linux/etherdevice.h> |
| +#include <linux/hwmon.h> |
| +#include <linux/hwmon-sysfs.h> |
| +#include <linux/thermal.h> |
| #include <linux/firmware.h> |
| #include "mt7921.h" |
| #include "../mt76_connac2_mac.h" |
| @@ -51,6 +54,57 @@ static const struct ieee80211_iface_combination if_comb_chanctx[] = { |
| } |
| }; |
| |
| +static ssize_t mt7921_thermal_temp_show(struct device *dev, |
| + struct device_attribute *attr, |
| + char *buf) |
| +{ |
| + switch (to_sensor_dev_attr(attr)->index) { |
| + case 0: { |
| + struct mt7921_phy *phy = dev_get_drvdata(dev); |
| + struct mt7921_dev *mdev = phy->dev; |
| + int temperature; |
| + |
| + mt7921_mutex_acquire(mdev); |
| + temperature = mt7921_mcu_get_temperature(phy); |
| + mt7921_mutex_release(mdev); |
| + |
| + if (temperature < 0) |
| + return temperature; |
| + /* display in millidegree Celsius */ |
| + return sprintf(buf, "%u\n", temperature * 1000); |
| + } |
| + default: |
| + return -EINVAL; |
| + } |
| +} |
| +static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7921_thermal_temp, 0); |
| + |
| +static struct attribute *mt7921_hwmon_attrs[] = { |
| + &sensor_dev_attr_temp1_input.dev_attr.attr, |
| + NULL, |
| +}; |
| +ATTRIBUTE_GROUPS(mt7921_hwmon); |
| + |
| +static int mt7921_thermal_init(struct mt7921_phy *phy) |
| +{ |
| + struct wiphy *wiphy = phy->mt76->hw->wiphy; |
| + struct device *hwmon; |
| + const char *name; |
| + |
| + if (!IS_REACHABLE(CONFIG_HWMON)) |
| + return 0; |
| + |
| + name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7921_%s", |
| + wiphy_name(wiphy)); |
| + |
| + hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy, |
| + mt7921_hwmon_groups); |
| + if (IS_ERR(hwmon)) |
| + return PTR_ERR(hwmon); |
| + |
| + return 0; |
| +} |
| + |
| static void |
| mt7921_regd_notifier(struct wiphy *wiphy, |
| struct regulatory_request *request) |
| @@ -113,7 +167,8 @@ mt7921_init_wiphy(struct ieee80211_hw *hw) |
| wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID; |
| wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH; |
| wiphy->max_sched_scan_reqs = 1; |
| - wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; |
| + wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH | |
| + WIPHY_FLAG_SPLIT_SCAN_6GHZ; |
| wiphy->reg_notifier = mt7921_regd_notifier; |
| |
| wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR | |
| @@ -176,12 +231,12 @@ mt7921_mac_init_band(struct mt7921_dev *dev, u8 band) |
| static u8 |
| mt7921_get_offload_capability(struct device *dev, const char *fw_wm) |
| { |
| - struct mt7921_fw_features *features = NULL; |
| const struct mt76_connac2_fw_trailer *hdr; |
| struct mt7921_realease_info *rel_info; |
| const struct firmware *fw; |
| int ret, i, offset = 0; |
| const u8 *data, *end; |
| + u8 offload_caps = 0; |
| |
| ret = request_firmware(&fw, fw_wm, dev); |
| if (ret) |
| @@ -213,7 +268,10 @@ mt7921_get_offload_capability(struct device *dev, const char *fw_wm) |
| data += sizeof(*rel_info); |
| |
| if (rel_info->tag == MT7921_FW_TAG_FEATURE) { |
| + struct mt7921_fw_features *features; |
| + |
| features = (struct mt7921_fw_features *)data; |
| + offload_caps = features->data; |
| break; |
| } |
| |
| @@ -223,7 +281,7 @@ mt7921_get_offload_capability(struct device *dev, const char *fw_wm) |
| out: |
| release_firmware(fw); |
| |
| - return features ? features->data : 0; |
| + return offload_caps; |
| } |
| |
| struct ieee80211_ops * |
| @@ -359,6 +417,12 @@ static void mt7921_init_work(struct work_struct *work) |
| return; |
| } |
| |
| + ret = mt7921_thermal_init(&dev->phy); |
| + if (ret) { |
| + dev_err(dev->mt76.dev, "thermal init failed\n"); |
| + return; |
| + } |
| + |
| /* we support chip reset now */ |
| dev->hw_init_done = true; |
| |
| @@ -392,8 +456,6 @@ int mt7921_register_device(struct mt7921_dev *dev) |
| #endif |
| skb_queue_head_init(&dev->phy.scan_event_list); |
| skb_queue_head_init(&dev->coredump.msg_list); |
| - INIT_LIST_HEAD(&dev->sta_poll_list); |
| - spin_lock_init(&dev->sta_poll_lock); |
| |
| INIT_WORK(&dev->reset_work, mt7921_mac_reset_work); |
| INIT_WORK(&dev->init_work, mt7921_init_work); |
| diff --git a/mt7921/mac.c b/mt7921/mac.c |
| index 1675bf52..368f9271 100644 |
| --- a/mt7921/mac.c |
| +++ b/mt7921/mac.c |
| @@ -52,7 +52,7 @@ bool mt7921_mac_wtbl_update(struct mt7921_dev *dev, int idx, u32 mask) |
| 0, 5000); |
| } |
| |
| -void mt7921_mac_sta_poll(struct mt7921_dev *dev) |
| +static void mt7921_mac_sta_poll(struct mt7921_dev *dev) |
| { |
| static const u8 ac_to_tid[] = { |
| [IEEE80211_AC_BE] = 0, |
| @@ -68,9 +68,9 @@ void mt7921_mac_sta_poll(struct mt7921_dev *dev) |
| s8 rssi[4]; |
| int i; |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - list_splice_init(&dev->sta_poll_list, &sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| while (true) { |
| bool clear = false; |
| @@ -78,15 +78,15 @@ void mt7921_mac_sta_poll(struct mt7921_dev *dev) |
| u16 idx; |
| u8 bw; |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| if (list_empty(&sta_poll_list)) { |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| break; |
| } |
| msta = list_first_entry(&sta_poll_list, |
| - struct mt7921_sta, poll_list); |
| - list_del_init(&msta->poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + struct mt7921_sta, wcid.poll_list); |
| + list_del_init(&msta->wcid.poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| idx = msta->wcid.idx; |
| addr = mt7921_mac_wtbl_lmac_addr(idx, MT_WTBL_AC0_CTT_OFFSET); |
| @@ -183,7 +183,6 @@ void mt7921_mac_sta_poll(struct mt7921_dev *dev) |
| ewma_avg_signal_add(&msta->avg_ack_signal, -msta->ack_signal); |
| } |
| } |
| -EXPORT_SYMBOL_GPL(mt7921_mac_sta_poll); |
| |
| static void |
| mt7921_get_status_freq_info(struct mt7921_dev *dev, struct mt76_phy *mphy, |
| @@ -281,10 +280,11 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) |
| |
| if (status->wcid) { |
| msta = container_of(status->wcid, struct mt7921_sta, wcid); |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (list_empty(&msta->poll_list)) |
| - list_add_tail(&msta->poll_list, &dev->sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + if (list_empty(&msta->wcid.poll_list)) |
| + list_add_tail(&msta->wcid.poll_list, |
| + &dev->mt76.sta_poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| } |
| |
| mt7921_get_status_freq_info(dev, mphy, status, chfreq); |
| @@ -511,30 +511,6 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) |
| return 0; |
| } |
| |
| -static void mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) |
| -{ |
| - struct mt7921_sta *msta; |
| - u16 fc, tid; |
| - u32 val; |
| - |
| - if (!sta || !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he)) |
| - return; |
| - |
| - tid = le32_get_bits(txwi[1], MT_TXD1_TID); |
| - if (tid >= 6) /* skip VO queue */ |
| - return; |
| - |
| - val = le32_to_cpu(txwi[2]); |
| - fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 | |
| - FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4; |
| - if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA))) |
| - return; |
| - |
| - msta = (struct mt7921_sta *)sta->drv_priv; |
| - if (!test_and_set_bit(tid, &msta->ampdu_state)) |
| - ieee80211_start_tx_ba_session(sta, tid, 0); |
| -} |
| - |
| void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data) |
| { |
| struct mt7921_sta *msta = NULL; |
| @@ -567,46 +543,15 @@ void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data) |
| if (!wcid->sta) |
| goto out; |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (list_empty(&msta->poll_list)) |
| - list_add_tail(&msta->poll_list, &dev->sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + if (list_empty(&msta->wcid.poll_list)) |
| + list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| out: |
| rcu_read_unlock(); |
| } |
| |
| -void mt7921_txwi_free(struct mt7921_dev *dev, struct mt76_txwi_cache *t, |
| - struct ieee80211_sta *sta, bool clear_status, |
| - struct list_head *free_list) |
| -{ |
| - struct mt76_dev *mdev = &dev->mt76; |
| - __le32 *txwi; |
| - u16 wcid_idx; |
| - |
| - mt76_connac_txp_skb_unmap(mdev, t); |
| - if (!t->skb) |
| - goto out; |
| - |
| - txwi = (__le32 *)mt76_get_txwi_ptr(mdev, t); |
| - if (sta) { |
| - struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv; |
| - |
| - if (likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE))) |
| - mt7921_tx_check_aggr(sta, txwi); |
| - |
| - wcid_idx = wcid->idx; |
| - } else { |
| - wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX); |
| - } |
| - |
| - __mt76_tx_complete_skb(mdev, wcid_idx, t->skb, free_list); |
| -out: |
| - t->skb = NULL; |
| - mt76_put_txwi(mdev, t); |
| -} |
| -EXPORT_SYMBOL_GPL(mt7921_txwi_free); |
| - |
| static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len) |
| { |
| struct mt76_connac_tx_free *free = data; |
| @@ -614,6 +559,7 @@ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len) |
| struct mt76_dev *mdev = &dev->mt76; |
| struct mt76_txwi_cache *txwi; |
| struct ieee80211_sta *sta = NULL; |
| + struct mt76_wcid *wcid = NULL; |
| struct sk_buff *skb, *tmp; |
| void *end = data + len; |
| LIST_HEAD(free_list); |
| @@ -637,7 +583,6 @@ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len) |
| */ |
| if (info & MT_TX_FREE_PAIR) { |
| struct mt7921_sta *msta; |
| - struct mt76_wcid *wcid; |
| u16 idx; |
| |
| count++; |
| @@ -648,21 +593,28 @@ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len) |
| continue; |
| |
| msta = container_of(wcid, struct mt7921_sta, wcid); |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (list_empty(&msta->poll_list)) |
| - list_add_tail(&msta->poll_list, &dev->sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&mdev->sta_poll_lock); |
| + if (list_empty(&msta->wcid.poll_list)) |
| + list_add_tail(&msta->wcid.poll_list, |
| + &mdev->sta_poll_list); |
| + spin_unlock_bh(&mdev->sta_poll_lock); |
| continue; |
| } |
| |
| msdu = FIELD_GET(MT_TX_FREE_MSDU_ID, info); |
| stat = FIELD_GET(MT_TX_FREE_STATUS, info); |
| |
| + if (wcid) { |
| + wcid->stats.tx_retries += |
| + FIELD_GET(MT_TX_FREE_COUNT, info) - 1; |
| + wcid->stats.tx_failed += !!stat; |
| + } |
| + |
| txwi = mt76_token_release(mdev, msdu, &wake); |
| if (!txwi) |
| continue; |
| |
| - mt7921_txwi_free(dev, txwi, sta, stat, &free_list); |
| + mt76_connac2_txwi_free(mdev, txwi, sta, &free_list); |
| } |
| |
| if (wake) |
| @@ -952,8 +904,8 @@ EXPORT_SYMBOL_GPL(mt7921_reset); |
| |
| void mt7921_mac_update_mib_stats(struct mt7921_phy *phy) |
| { |
| + struct mt76_mib_stats *mib = &phy->mib; |
| struct mt7921_dev *dev = phy->dev; |
| - struct mib_stats *mib = &phy->mib; |
| int i, aggr0 = 0, aggr1; |
| u32 val; |
| |
| @@ -1180,6 +1132,10 @@ int mt7921_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, |
| if (unlikely(tx_info->skb->len <= ETH_HLEN)) |
| return -EINVAL; |
| |
| + err = skb_cow_head(skb, MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE); |
| + if (err) |
| + return err; |
| + |
| if (!wcid) |
| wcid = &dev->mt76.global_wcid; |
| |
| @@ -1224,7 +1180,7 @@ void mt7921_usb_sdio_tx_complete_skb(struct mt76_dev *mdev, |
| sta = wcid_to_sta(wcid); |
| |
| if (sta && likely(e->skb->protocol != cpu_to_be16(ETH_P_PAE))) |
| - mt7921_tx_check_aggr(sta, txwi); |
| + mt76_connac2_tx_check_aggr(sta, txwi); |
| |
| skb_pull(e->skb, headroom); |
| mt76_tx_complete_skb(mdev, e->wcid, e->skb); |
| diff --git a/mt7921/main.c b/mt7921/main.c |
| index 3b6adb29..87067ac3 100644 |
| --- a/mt7921/main.c |
| +++ b/mt7921/main.c |
| @@ -313,7 +313,7 @@ static int mt7921_add_interface(struct ieee80211_hw *hw, |
| |
| idx = MT7921_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; |
| @@ -357,10 +357,10 @@ static void mt7921_remove_interface(struct ieee80211_hw *hw, |
| phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx); |
| mt7921_mutex_release(dev); |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (!list_empty(&msta->poll_list)) |
| - list_del_init(&msta->poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + if (!list_empty(&msta->wcid.poll_list)) |
| + list_del_init(&msta->wcid.poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| mt76_packet_id_flush(&dev->mt76, &msta->wcid); |
| } |
| @@ -764,7 +764,7 @@ int mt7921_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; |
| @@ -842,10 +842,10 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
| mvif->ctx); |
| } |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (!list_empty(&msta->poll_list)) |
| - list_del_init(&msta->poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + if (!list_empty(&msta->wcid.poll_list)) |
| + list_del_init(&msta->wcid.poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| mt76_connac_power_save_sched(&dev->mphy, &dev->pm); |
| } |
| @@ -954,16 +954,16 @@ mt7921_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| case IEEE80211_AMPDU_TX_STOP_FLUSH: |
| case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: |
| mtxq->aggr = false; |
| - clear_bit(tid, &msta->ampdu_state); |
| + clear_bit(tid, &msta->wcid.ampdu_state); |
| mt7921_mcu_uni_tx_ba(dev, params, false); |
| break; |
| case IEEE80211_AMPDU_TX_START: |
| - set_bit(tid, &msta->ampdu_state); |
| + set_bit(tid, &msta->wcid.ampdu_state); |
| ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; |
| break; |
| case IEEE80211_AMPDU_TX_STOP_CONT: |
| mtxq->aggr = false; |
| - clear_bit(tid, &msta->ampdu_state); |
| + clear_bit(tid, &msta->wcid.ampdu_state); |
| mt7921_mcu_uni_tx_ba(dev, params, false); |
| ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
| break; |
| @@ -995,7 +995,7 @@ mt7921_get_stats(struct ieee80211_hw *hw, |
| struct ieee80211_low_level_stats *stats) |
| { |
| struct mt7921_phy *phy = mt7921_hw_phy(hw); |
| - struct mib_stats *mib = &phy->mib; |
| + struct mt76_mib_stats *mib = &phy->mib; |
| |
| mt7921_mutex_acquire(phy->dev); |
| |
| @@ -1077,6 +1077,10 @@ static const char mt7921_gstrings_stats[][ETH_GSTRING_LEN] = { |
| "v_tx_mcs_9", |
| "v_tx_mcs_10", |
| "v_tx_mcs_11", |
| + "v_tx_nss_1", |
| + "v_tx_nss_2", |
| + "v_tx_nss_3", |
| + "v_tx_nss_4", |
| }; |
| |
| static void |
| @@ -1133,7 +1137,7 @@ void mt7921_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| int stats_size = ARRAY_SIZE(mt7921_gstrings_stats); |
| struct mt7921_phy *phy = mt7921_hw_phy(hw); |
| struct mt7921_dev *dev = phy->dev; |
| - struct mib_stats *mib = &phy->mib; |
| + struct mt76_mib_stats *mib = &phy->mib; |
| struct mt76_ethtool_worker_info wi = { |
| .data = data, |
| .idx = mvif->mt76.idx, |
| @@ -1363,7 +1367,7 @@ mt7921_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) |
| return -EINVAL; |
| |
| if ((BIT(hweight8(tx_ant)) - 1) != tx_ant) |
| - tx_ant = BIT(ffs(tx_ant) - 1) - 1; |
| + return -EINVAL; |
| |
| mt7921_mutex_acquire(dev); |
| |
| @@ -1399,6 +1403,12 @@ static void mt7921_sta_statistics(struct ieee80211_hw *hw, |
| sinfo->txrate.he_dcm = txrate->he_dcm; |
| sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc; |
| } |
| + sinfo->tx_failed = msta->wcid.stats.tx_failed; |
| + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); |
| + |
| + sinfo->tx_retries = msta->wcid.stats.tx_retries; |
| + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); |
| + |
| sinfo->txrate.flags = txrate->flags; |
| sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); |
| |
| diff --git a/mt7921/mcu.c b/mt7921/mcu.c |
| index c69ce6df..a0ad18c7 100644 |
| --- a/mt7921/mcu.c |
| +++ b/mt7921/mcu.c |
| @@ -476,12 +476,6 @@ static int mt7921_load_firmware(struct mt7921_dev *dev) |
| { |
| int ret; |
| |
| - ret = mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY); |
| - if (ret && mt76_is_mmio(&dev->mt76)) { |
| - dev_dbg(dev->mt76.dev, "Firmware is already download\n"); |
| - goto fw_loaded; |
| - } |
| - |
| ret = mt76_connac2_load_patch(&dev->mt76, mt7921_patch_name(dev)); |
| if (ret) |
| return ret; |
| @@ -504,8 +498,6 @@ static int mt7921_load_firmware(struct mt7921_dev *dev) |
| return -EIO; |
| } |
| |
| -fw_loaded: |
| - |
| #ifdef CONFIG_PM |
| dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support; |
| #endif /* CONFIG_PM */ |
| @@ -1313,6 +1305,23 @@ int mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2, |
| return 0; |
| } |
| |
| +int mt7921_mcu_get_temperature(struct mt7921_phy *phy) |
| +{ |
| + struct mt7921_dev *dev = phy->dev; |
| + struct { |
| + u8 ctrl_id; |
| + u8 action; |
| + u8 band_idx; |
| + u8 rsv[5]; |
| + } req = { |
| + .ctrl_id = THERMAL_SENSOR_TEMP_QUERY, |
| + .band_idx = phy->mt76->band_idx, |
| + }; |
| + |
| + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(THERMAL_CTRL), &req, |
| + sizeof(req), true); |
| +} |
| + |
| int mt7921_mcu_set_rxfilter(struct mt7921_dev *dev, u32 fif, |
| u8 bit_op, u32 bit_map) |
| { |
| diff --git a/mt7921/mt7921.h b/mt7921/mt7921.h |
| index 149acb16..ec987965 100644 |
| --- a/mt7921/mt7921.h |
| +++ b/mt7921/mt7921.h |
| @@ -19,7 +19,6 @@ |
| #define MT7921_PM_TIMEOUT (HZ / 12) |
| #define MT7921_HW_SCAN_TIMEOUT (HZ / 10) |
| #define MT7921_WATCHDOG_TIME (HZ / 4) |
| -#define MT7921_RESET_TIMEOUT (30 * HZ) |
| |
| #define MT7921_TX_RING_SIZE 2048 |
| #define MT7921_TX_MCU_RING_SIZE 256 |
| @@ -151,14 +150,12 @@ struct mt7921_sta { |
| |
| struct mt7921_vif *vif; |
| |
| - struct list_head poll_list; |
| u32 airtime_ac[8]; |
| |
| int ack_signal; |
| struct ewma_avg_signal avg_ack_signal; |
| |
| unsigned long last_txs; |
| - unsigned long ampdu_state; |
| |
| struct mt76_connac_sta_key_conf bip; |
| }; |
| @@ -179,35 +176,6 @@ struct mt7921_vif { |
| struct ieee80211_chanctx_conf *ctx; |
| }; |
| |
| -struct mib_stats { |
| - u32 ack_fail_cnt; |
| - u32 fcs_err_cnt; |
| - u32 rts_cnt; |
| - u32 rts_retries_cnt; |
| - u32 ba_miss_cnt; |
| - |
| - u32 tx_bf_ibf_ppdu_cnt; |
| - u32 tx_bf_ebf_ppdu_cnt; |
| - u32 tx_bf_rx_fb_all_cnt; |
| - u32 tx_bf_rx_fb_he_cnt; |
| - u32 tx_bf_rx_fb_vht_cnt; |
| - u32 tx_bf_rx_fb_ht_cnt; |
| - |
| - u32 tx_ampdu_cnt; |
| - u32 tx_mpdu_attempts_cnt; |
| - u32 tx_mpdu_success_cnt; |
| - u32 tx_pkt_ebf_cnt; |
| - u32 tx_pkt_ibf_cnt; |
| - |
| - u32 rx_mpdu_cnt; |
| - u32 rx_ampdu_cnt; |
| - u32 rx_ampdu_bytes_cnt; |
| - u32 rx_ba_cnt; |
| - |
| - u32 tx_amsdu[8]; |
| - u32 tx_amsdu_cnt; |
| -}; |
| - |
| enum { |
| MT7921_CLC_POWER, |
| MT7921_CLC_CHAN, |
| @@ -247,7 +215,7 @@ struct mt7921_phy { |
| u32 rx_ampdu_ts; |
| u32 ampdu_ref; |
| |
| - struct mib_stats mib; |
| + struct mt76_mib_stats mib; |
| |
| u8 sta_work_count; |
| |
| @@ -304,9 +272,6 @@ struct mt7921_dev { |
| bool hw_init_done:1; |
| bool fw_assert:1; |
| |
| - struct list_head sta_poll_list; |
| - spinlock_t sta_poll_lock; |
| - |
| struct work_struct init_work; |
| |
| u8 fw_debug; |
| @@ -477,7 +442,6 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, |
| struct mt76_tx_info *tx_info); |
| |
| void mt7921_tx_worker(struct mt76_worker *w); |
| -void mt7921_tx_token_put(struct mt7921_dev *dev); |
| bool mt7921_rx_check(struct mt76_dev *mdev, void *data, int len); |
| void mt7921_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, |
| struct sk_buff *skb, u32 *info); |
| @@ -510,10 +474,6 @@ int mt7921_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| void *data, int len); |
| int mt7921_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, |
| struct netlink_callback *cb, void *data, int len); |
| -void mt7921_txwi_free(struct mt7921_dev *dev, struct mt76_txwi_cache *t, |
| - struct ieee80211_sta *sta, bool clear_status, |
| - struct list_head *free_list); |
| -void mt7921_mac_sta_poll(struct mt7921_dev *dev); |
| int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd, |
| struct sk_buff *skb, int seq); |
| |
| @@ -540,6 +500,7 @@ int mt7921_mcu_set_sniffer(struct mt7921_dev *dev, struct ieee80211_vif *vif, |
| bool enable); |
| int mt7921_mcu_config_sniffer(struct mt7921_vif *vif, |
| struct ieee80211_chanctx_conf *ctx); |
| +int mt7921_mcu_get_temperature(struct mt7921_phy *phy); |
| |
| int mt7921_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, |
| enum mt76_txq_id qid, struct mt76_wcid *wcid, |
| diff --git a/mt7921/pci.c b/mt7921/pci.c |
| index 1c727870..7c8bf719 100644 |
| --- a/mt7921/pci.c |
| +++ b/mt7921/pci.c |
| @@ -115,7 +115,7 @@ static void mt7921e_unregister_device(struct mt7921_dev *dev) |
| cancel_work_sync(&pm->wake_work); |
| cancel_work_sync(&dev->reset_work); |
| |
| - mt7921_tx_token_put(dev); |
| + mt76_connac2_tx_token_put(&dev->mt76); |
| __mt7921_mcu_drv_pmctrl(dev); |
| mt7921_dma_cleanup(dev); |
| mt7921_wfsys_reset(dev); |
| @@ -325,6 +325,10 @@ static int mt7921_pci_probe(struct pci_dev *pdev, |
| bus_ops->rmw = mt7921_rmw; |
| dev->mt76.bus = bus_ops; |
| |
| + ret = mt7921e_mcu_fw_pmctrl(dev); |
| + if (ret) |
| + goto err_free_dev; |
| + |
| ret = __mt7921e_mcu_drv_pmctrl(dev); |
| if (ret) |
| goto err_free_dev; |
| @@ -333,6 +337,10 @@ static int mt7921_pci_probe(struct pci_dev *pdev, |
| (mt7921_l1_rr(dev, MT_HW_REV) & 0xff); |
| dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev); |
| |
| + ret = mt7921_wfsys_reset(dev); |
| + if (ret) |
| + goto err_free_dev; |
| + |
| mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0); |
| |
| mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); |
| diff --git a/mt7921/pci_mac.c b/mt7921/pci_mac.c |
| index 6053a255..978c90a0 100644 |
| --- a/mt7921/pci_mac.c |
| +++ b/mt7921/pci_mac.c |
| @@ -53,20 +53,6 @@ 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 i, err; |
| @@ -91,7 +77,7 @@ 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); |
| diff --git a/mt7921/regs.h b/mt7921/regs.h |
| index e52977ff..b1801425 100644 |
| --- a/mt7921/regs.h |
| +++ b/mt7921/regs.h |
| @@ -158,7 +158,6 @@ |
| |
| #define MT_MIB_MB_SDR0(_band, n) MT_WF_MIB(_band, 0x100 + ((n) << 4)) |
| #define MT_MIB_RTS_RETRIES_COUNT_MASK GENMASK(31, 16) |
| -#define MT_MIB_RTS_COUNT_MASK GENMASK(15, 0) |
| |
| #define MT_MIB_MB_BSDR0(_band) MT_WF_MIB(_band, 0x688) |
| #define MT_MIB_RTS_COUNT_MASK GENMASK(15, 0) |
| diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c |
| index 513ab4ba..4d40ec7f 100644 |
| --- a/mt7996/debugfs.c |
| +++ b/mt7996/debugfs.c |
| @@ -474,10 +474,10 @@ mt7996_ampdu_stat_read_phy(struct mt7996_phy *phy, struct seq_file *file) |
| static void |
| mt7996_txbf_stat_read_phy(struct mt7996_phy *phy, struct seq_file *s) |
| { |
| + struct mt76_mib_stats *mib = &phy->mib; |
| static const char * const bw[] = { |
| "BW20", "BW40", "BW80", "BW160" |
| }; |
| - struct mib_stats *mib = &phy->mib; |
| |
| /* Tx Beamformer monitor */ |
| seq_puts(s, "\nTx Beamformer applied PPDU counts: "); |
| @@ -523,7 +523,7 @@ mt7996_tx_stats_show(struct seq_file *file, void *data) |
| { |
| struct mt7996_phy *phy = file->private; |
| struct mt7996_dev *dev = phy->dev; |
| - struct mib_stats *mib = &phy->mib; |
| + struct mt76_mib_stats *mib = &phy->mib; |
| int i; |
| u32 attempts, success, per; |
| |
| diff --git a/mt7996/dma.c b/mt7996/dma.c |
| index 53414346..586e247a 100644 |
| --- a/mt7996/dma.c |
| +++ b/mt7996/dma.c |
| @@ -128,11 +128,55 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset) |
| } |
| } |
| |
| -static int mt7996_dma_enable(struct mt7996_dev *dev) |
| +void mt7996_dma_start(struct mt7996_dev *dev, bool reset) |
| { |
| u32 hif1_ofs = 0; |
| u32 irq_mask; |
| |
| + if (dev->hif2) |
| + hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); |
| + |
| + /* enable WFDMA Tx/Rx */ |
| + if (!reset) { |
| + mt76_set(dev, MT_WFDMA0_GLO_CFG, |
| + MT_WFDMA0_GLO_CFG_TX_DMA_EN | |
| + MT_WFDMA0_GLO_CFG_RX_DMA_EN | |
| + MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | |
| + MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); |
| + |
| + if (dev->hif2) |
| + mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs, |
| + MT_WFDMA0_GLO_CFG_TX_DMA_EN | |
| + MT_WFDMA0_GLO_CFG_RX_DMA_EN | |
| + MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | |
| + MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); |
| + } |
| + |
| + /* enable interrupts for TX/RX rings */ |
| + irq_mask = MT_INT_MCU_CMD; |
| + if (reset) |
| + goto done; |
| + |
| + irq_mask = MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU; |
| + |
| + if (!dev->mphy.band_idx) |
| + irq_mask |= MT_INT_BAND0_RX_DONE; |
| + |
| + if (dev->dbdc_support) |
| + irq_mask |= MT_INT_BAND1_RX_DONE; |
| + |
| + if (dev->tbtc_support) |
| + irq_mask |= MT_INT_BAND2_RX_DONE; |
| + |
| +done: |
| + mt7996_irq_enable(dev, irq_mask); |
| + mt7996_irq_disable(dev, 0); |
| +} |
| + |
| +static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset) |
| +{ |
| + u32 hif1_ofs = 0; |
| + |
| if (dev->hif2) |
| hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); |
| |
| @@ -170,13 +214,6 @@ static int mt7996_dma_enable(struct mt7996_dev *dev) |
| mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC, |
| MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000); |
| |
| - /* set WFDMA Tx/Rx */ |
| - mt76_set(dev, MT_WFDMA0_GLO_CFG, |
| - MT_WFDMA0_GLO_CFG_TX_DMA_EN | |
| - MT_WFDMA0_GLO_CFG_RX_DMA_EN | |
| - MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | |
| - MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); |
| - |
| /* GLO_CFG_EXT0 */ |
| mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0, |
| WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD | |
| @@ -187,12 +224,6 @@ static int mt7996_dma_enable(struct mt7996_dev *dev) |
| WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE); |
| |
| if (dev->hif2) { |
| - mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs, |
| - MT_WFDMA0_GLO_CFG_TX_DMA_EN | |
| - MT_WFDMA0_GLO_CFG_RX_DMA_EN | |
| - MT_WFDMA0_GLO_CFG_OMIT_TX_INFO | |
| - MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); |
| - |
| /* GLO_CFG_EXT0 */ |
| mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs, |
| WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD | |
| @@ -216,23 +247,7 @@ static int mt7996_dma_enable(struct mt7996_dev *dev) |
| /* TODO: redirect rx ring6 interrupt to pcie0 for wed function */ |
| } |
| |
| - /* enable interrupts for TX/RX rings */ |
| - irq_mask = MT_INT_RX_DONE_MCU | |
| - MT_INT_TX_DONE_MCU | |
| - MT_INT_MCU_CMD; |
| - |
| - if (!dev->mphy.band_idx) |
| - irq_mask |= MT_INT_BAND0_RX_DONE; |
| - |
| - if (dev->dbdc_support) |
| - irq_mask |= MT_INT_BAND1_RX_DONE; |
| - |
| - if (dev->tbtc_support) |
| - irq_mask |= MT_INT_BAND2_RX_DONE; |
| - |
| - mt7996_irq_enable(dev, irq_mask); |
| - |
| - return 0; |
| + mt7996_dma_start(dev, reset); |
| } |
| |
| int mt7996_dma_init(struct mt7996_dev *dev) |
| @@ -293,7 +308,7 @@ int mt7996_dma_init(struct mt7996_dev *dev) |
| /* event from WA */ |
| ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA], |
| MT_RXQ_ID(MT_RXQ_MCU_WA), |
| - MT7996_RX_MCU_RING_SIZE, |
| + MT7996_RX_MCU_RING_SIZE_WA, |
| MT_RX_BUF_SIZE, |
| MT_RXQ_RING_BASE(MT_RXQ_MCU_WA)); |
| if (ret) |
| @@ -347,7 +362,7 @@ int mt7996_dma_init(struct mt7996_dev *dev) |
| mt7996_poll_tx); |
| napi_enable(&dev->mt76.tx_napi); |
| |
| - mt7996_dma_enable(dev); |
| + mt7996_dma_enable(dev, false); |
| |
| return 0; |
| } |
| @@ -413,7 +428,7 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force) |
| mt76_for_each_q_rx(&dev->mt76, i) |
| mt76_queue_rx_reset(dev, i); |
| |
| - mt7996_dma_enable(dev); |
| + mt7996_dma_enable(dev, !force); |
| } |
| |
| void mt7996_dma_cleanup(struct mt7996_dev *dev) |
| diff --git a/mt7996/init.c b/mt7996/init.c |
| index f1b48cdd..e297e7cb 100644 |
| --- a/mt7996/init.c |
| +++ b/mt7996/init.c |
| @@ -183,6 +183,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw) |
| wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_DISCOVERY); |
| wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); |
| wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); |
| + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER); |
| |
| if (!mdev->dev->of_node || |
| !of_property_read_bool(mdev->dev->of_node, |
| @@ -217,6 +218,8 @@ mt7996_init_wiphy(struct ieee80211_hw *hw) |
| IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; |
| phy->mt76->sband_5g.sband.ht_cap.ampdu_density = |
| IEEE80211_HT_MPDU_DENSITY_1; |
| + |
| + ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); |
| } |
| |
| mt76_set_stream_caps(phy->mt76, true); |
| @@ -853,9 +856,7 @@ int mt7996_register_device(struct mt7996_dev *dev) |
| INIT_WORK(&dev->rc_work, mt7996_mac_sta_rc_work); |
| INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7996_mac_work); |
| INIT_LIST_HEAD(&dev->sta_rc_list); |
| - INIT_LIST_HEAD(&dev->sta_poll_list); |
| INIT_LIST_HEAD(&dev->twt_list); |
| - spin_lock_init(&dev->sta_poll_lock); |
| |
| init_waitqueue_head(&dev->reset_wait); |
| INIT_WORK(&dev->reset_work, mt7996_mac_reset_work); |
| diff --git a/mt7996/mac.c b/mt7996/mac.c |
| index 0d51090d..17dd531e 100644 |
| --- a/mt7996/mac.c |
| +++ b/mt7996/mac.c |
| @@ -13,10 +13,6 @@ |
| |
| #define to_rssi(field, rcpi) ((FIELD_GET(field, rcpi) - 220) / 2) |
| |
| -#define HE_BITS(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_##f) |
| -#define HE_PREP(f, m, v) le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\ |
| - IEEE80211_RADIOTAP_HE_##f) |
| - |
| static const struct mt7996_dfs_radar_spec etsi_radar_specs = { |
| .pulse_th = { 110, -10, -80, 40, 5200, 128, 5200 }, |
| .radar_pattern = { |
| @@ -111,9 +107,9 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev) |
| LIST_HEAD(sta_poll_list); |
| int i; |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - list_splice_init(&dev->sta_poll_list, &sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| rcu_read_lock(); |
| |
| @@ -124,15 +120,15 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev) |
| s8 rssi[4]; |
| u8 bw; |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| if (list_empty(&sta_poll_list)) { |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| break; |
| } |
| msta = list_first_entry(&sta_poll_list, |
| - struct mt7996_sta, poll_list); |
| - list_del_init(&msta->poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + struct mt7996_sta, wcid.poll_list); |
| + list_del_init(&msta->wcid.poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| idx = msta->wcid.idx; |
| |
| @@ -263,180 +259,6 @@ void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev, |
| mt76_wr(dev, MT_WTBL_ITCR, ctrl); |
| } |
| |
| -static void |
| -mt7996_mac_decode_he_radiotap_ru(struct mt76_rx_status *status, |
| - struct ieee80211_radiotap_he *he, |
| - __le32 *rxv) |
| -{ |
| - u32 ru, offs = 0; |
| - |
| - ru = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC); |
| - |
| - status->bw = RATE_INFO_BW_HE_RU; |
| - |
| - switch (ru) { |
| - case 0 ... 36: |
| - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26; |
| - offs = ru; |
| - break; |
| - case 37 ... 52: |
| - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52; |
| - offs = ru - 37; |
| - break; |
| - case 53 ... 60: |
| - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; |
| - offs = ru - 53; |
| - break; |
| - case 61 ... 64: |
| - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242; |
| - offs = ru - 61; |
| - break; |
| - case 65 ... 66: |
| - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484; |
| - offs = ru - 65; |
| - break; |
| - case 67: |
| - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996; |
| - break; |
| - case 68: |
| - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; |
| - break; |
| - } |
| - |
| - he->data1 |= HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); |
| - he->data2 |= HE_BITS(DATA2_RU_OFFSET_KNOWN) | |
| - le16_encode_bits(offs, |
| - IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); |
| -} |
| - |
| -static void |
| -mt7996_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32 *rxv) |
| -{ |
| - struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; |
| - static const struct ieee80211_radiotap_he_mu mu_known = { |
| - .flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) | |
| - HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) | |
| - HE_BITS(MU_FLAGS1_CH1_RU_KNOWN) | |
| - HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN), |
| - .flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN), |
| - }; |
| - struct ieee80211_radiotap_he_mu *he_mu = NULL; |
| - |
| - status->flag |= RX_FLAG_RADIOTAP_HE_MU; |
| - |
| - he_mu = skb_push(skb, sizeof(mu_known)); |
| - memcpy(he_mu, &mu_known, sizeof(mu_known)); |
| - |
| -#define MU_PREP(f, v) le16_encode_bits(v, IEEE80211_RADIOTAP_HE_MU_##f) |
| - |
| - he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status->rate_idx); |
| - if (status->he_dcm) |
| - he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status->he_dcm); |
| - |
| - he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) | |
| - MU_PREP(FLAGS2_SIG_B_SYMS_USERS, |
| - le32_get_bits(rxv[4], MT_CRXV_HE_NUM_USER)); |
| - |
| - he_mu->ru_ch1[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU0) & 0xff; |
| - |
| - if (status->bw >= RATE_INFO_BW_40) { |
| - he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN); |
| - he_mu->ru_ch2[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU1) & 0xff; |
| - } |
| - |
| - if (status->bw >= RATE_INFO_BW_80) { |
| - u32 ru_h, ru_l; |
| - |
| - he_mu->ru_ch1[1] = le32_get_bits(rxv[16], MT_CRXV_HE_RU2) & 0xff; |
| - |
| - ru_l = le32_get_bits(rxv[16], MT_CRXV_HE_RU3_L); |
| - ru_h = le32_get_bits(rxv[17], MT_CRXV_HE_RU3_H) & 0x7; |
| - he_mu->ru_ch2[1] = (u8)(ru_l | ru_h << 4); |
| - } |
| -} |
| - |
| -static void |
| -mt7996_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u8 mode) |
| -{ |
| - struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; |
| - static const struct ieee80211_radiotap_he known = { |
| - .data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) | |
| - HE_BITS(DATA1_DATA_DCM_KNOWN) | |
| - HE_BITS(DATA1_STBC_KNOWN) | |
| - HE_BITS(DATA1_CODING_KNOWN) | |
| - HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) | |
| - HE_BITS(DATA1_DOPPLER_KNOWN) | |
| - HE_BITS(DATA1_SPTL_REUSE_KNOWN) | |
| - HE_BITS(DATA1_BSS_COLOR_KNOWN), |
| - .data2 = HE_BITS(DATA2_GI_KNOWN) | |
| - HE_BITS(DATA2_TXBF_KNOWN) | |
| - HE_BITS(DATA2_PE_DISAMBIG_KNOWN) | |
| - HE_BITS(DATA2_TXOP_KNOWN), |
| - }; |
| - struct ieee80211_radiotap_he *he = NULL; |
| - u32 ltf_size = le32_get_bits(rxv[4], MT_CRXV_HE_LTF_SIZE) + 1; |
| - |
| - status->flag |= RX_FLAG_RADIOTAP_HE; |
| - |
| - he = skb_push(skb, sizeof(known)); |
| - memcpy(he, &known, sizeof(known)); |
| - |
| - he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[9]) | |
| - HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[4]); |
| - he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[13]); |
| - he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[5]) | |
| - le16_encode_bits(ltf_size, |
| - IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE); |
| - if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF) |
| - he->data5 |= HE_BITS(DATA5_TXBF); |
| - he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[9]) | |
| - HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[9]); |
| - |
| - switch (mode) { |
| - case MT_PHY_TYPE_HE_SU: |
| - he->data1 |= HE_BITS(DATA1_FORMAT_SU) | |
| - HE_BITS(DATA1_UL_DL_KNOWN) | |
| - HE_BITS(DATA1_BEAM_CHANGE_KNOWN) | |
| - HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); |
| - |
| - he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[8]) | |
| - HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]); |
| - break; |
| - case MT_PHY_TYPE_HE_EXT_SU: |
| - he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) | |
| - HE_BITS(DATA1_UL_DL_KNOWN) | |
| - HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); |
| - |
| - he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]); |
| - break; |
| - case MT_PHY_TYPE_HE_MU: |
| - he->data1 |= HE_BITS(DATA1_FORMAT_MU) | |
| - HE_BITS(DATA1_UL_DL_KNOWN); |
| - |
| - he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]); |
| - he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[8]); |
| - |
| - mt7996_mac_decode_he_radiotap_ru(status, he, rxv); |
| - mt7996_mac_decode_he_mu_radiotap(skb, rxv); |
| - break; |
| - case MT_PHY_TYPE_HE_TB: |
| - he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) | |
| - HE_BITS(DATA1_SPTL_REUSE2_KNOWN) | |
| - HE_BITS(DATA1_SPTL_REUSE3_KNOWN) | |
| - HE_BITS(DATA1_SPTL_REUSE4_KNOWN); |
| - |
| - he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, rxv[13]) | |
| - HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, rxv[13]) | |
| - HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, rxv[13]) | |
| - HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, rxv[13]); |
| - |
| - mt7996_mac_decode_he_radiotap_ru(status, he, rxv); |
| - break; |
| - default: |
| - break; |
| - } |
| -} |
| - |
| /* The HW does not translate the mac header to 802.3 for mesh point */ |
| static int mt7996_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap) |
| { |
| @@ -680,10 +502,11 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb) |
| struct mt7996_sta *msta; |
| |
| msta = container_of(status->wcid, struct mt7996_sta, wcid); |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (list_empty(&msta->poll_list)) |
| - list_add_tail(&msta->poll_list, &dev->sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + if (list_empty(&msta->wcid.poll_list)) |
| + list_add_tail(&msta->wcid.poll_list, |
| + &dev->mt76.sta_poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| } |
| |
| status->freq = mphy->chandef.chan->center_freq; |
| @@ -835,14 +658,19 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb) |
| skb_pull(skb, hdr_gap); |
| if (!hdr_trans && status->amsdu && !(ieee80211_has_a4(fc) && is_mesh)) { |
| pad_start = ieee80211_get_hdrlen_from_skb(skb); |
| - } else if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_HDR_TRANS_ERROR) && |
| - get_unaligned_be16(skb->data + pad_start) == ETH_P_8021Q) { |
| + } else if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_HDR_TRANS_ERROR)) { |
| /* When header translation failure is indicated, |
| * the hardware will insert an extra 2-byte field |
| * containing the data length after the protocol |
| - * type field. |
| + * type field. This happens either when the LLC-SNAP |
| + * pattern did not match, or if a VLAN header was |
| + * detected. |
| */ |
| - pad_start = 16; |
| + pad_start = 12; |
| + if (get_unaligned_be16(skb->data + pad_start) == ETH_P_8021Q) |
| + pad_start += 4; |
| + else |
| + pad_start = 0; |
| } |
| |
| if (pad_start) { |
| @@ -880,7 +708,7 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb) |
| } |
| |
| if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023)) |
| - mt7996_mac_decode_he_radiotap(skb, rxv, mode); |
| + mt76_connac3_mac_decode_he_radiotap(skb, rxv, mode); |
| |
| if (!status->wcid || !ieee80211_is_data_qos(fc)) |
| return 0; |
| @@ -1003,7 +831,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi, |
| { |
| struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| struct ieee80211_vif *vif = info->control.vif; |
| - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| + struct mt76_vif *mvif; |
| struct mt76_phy *mphy = &dev->mphy; |
| u8 band_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2; |
| u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0; |
| @@ -1015,10 +843,11 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi, |
| bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | |
| BSS_CHANGED_FILS_DISCOVERY)); |
| |
| - if (vif) { |
| - omac_idx = mvif->mt76.omac_idx; |
| - wmm_idx = mvif->mt76.wmm_idx; |
| - band_idx = mvif->mt76.band_idx; |
| + mvif = vif ? (struct mt76_vif *)vif->drv_priv : NULL; |
| + if (mvif) { |
| + omac_idx = mvif->omac_idx; |
| + wmm_idx = mvif->wmm_idx; |
| + band_idx = mvif->band_idx; |
| } |
| |
| mphy = mt76_dev_phy(&dev->mt76, band_idx); |
| @@ -1083,14 +912,18 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi, |
| struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| bool mcast = ieee80211_is_data(hdr->frame_control) && |
| is_multicast_ether_addr(hdr->addr1); |
| - u8 idx = mvif->basic_rates_idx; |
| + u8 idx = MT7996_BASIC_RATES_TBL; |
| |
| - if (mcast && mvif->mcast_rates_idx) |
| - idx = mvif->mcast_rates_idx; |
| - else if (beacon && mvif->beacon_rates_idx) |
| - idx = mvif->beacon_rates_idx; |
| + if (mvif) { |
| + if (mcast && mvif->mcast_rates_idx) |
| + idx = mvif->mcast_rates_idx; |
| + else if (beacon && mvif->beacon_rates_idx) |
| + idx = mvif->beacon_rates_idx; |
| + else |
| + idx = mvif->basic_rates_idx; |
| + } |
| |
| - txwi[6] |= FIELD_PREP(MT_TXD6_TX_RATE, idx); |
| + txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE, idx)); |
| txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE); |
| } |
| } |
| @@ -1200,7 +1033,7 @@ mt7996_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) |
| return; |
| |
| msta = (struct mt7996_sta *)sta->drv_priv; |
| - if (!test_and_set_bit(tid, &msta->ampdu_state)) |
| + if (!test_and_set_bit(tid, &msta->wcid.ampdu_state)) |
| ieee80211_start_tx_ba_session(sta, tid, 0); |
| } |
| |
| @@ -1288,10 +1121,11 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len) |
| continue; |
| |
| msta = container_of(wcid, struct mt7996_sta, wcid); |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (list_empty(&msta->poll_list)) |
| - list_add_tail(&msta->poll_list, &dev->sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&mdev->sta_poll_lock); |
| + if (list_empty(&msta->wcid.poll_list)) |
| + list_add_tail(&msta->wcid.poll_list, |
| + &mdev->sta_poll_list); |
| + spin_unlock_bh(&mdev->sta_poll_lock); |
| continue; |
| } |
| |
| @@ -1326,9 +1160,10 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len) |
| } |
| |
| static bool |
| -mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid, int pid, |
| - __le32 *txs_data, struct mt76_sta_stats *stats) |
| +mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid, |
| + int pid, __le32 *txs_data) |
| { |
| + struct mt76_sta_stats *stats = &wcid->stats; |
| struct ieee80211_supported_band *sband; |
| struct mt76_dev *mdev = &dev->mt76; |
| struct mt76_phy *mphy; |
| @@ -1490,15 +1325,15 @@ static void mt7996_mac_add_txs(struct mt7996_dev *dev, void *data) |
| |
| msta = container_of(wcid, struct mt7996_sta, wcid); |
| |
| - mt7996_mac_add_txs_skb(dev, wcid, pid, txs_data, &msta->stats); |
| + mt7996_mac_add_txs_skb(dev, wcid, pid, txs_data); |
| |
| if (!wcid->sta) |
| goto out; |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (list_empty(&msta->poll_list)) |
| - list_add_tail(&msta->poll_list, &dev->sta_poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + if (list_empty(&msta->wcid.poll_list)) |
| + list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| out: |
| rcu_read_unlock(); |
| @@ -1611,20 +1446,19 @@ void mt7996_mac_reset_counters(struct mt7996_phy *phy) |
| mt7996_mcu_get_chan_mib_info(phy, true); |
| } |
| |
| -void mt7996_mac_set_timing(struct mt7996_phy *phy) |
| +void mt7996_mac_set_coverage_class(struct mt7996_phy *phy) |
| { |
| s16 coverage_class = phy->coverage_class; |
| struct mt7996_dev *dev = phy->dev; |
| struct mt7996_phy *phy2 = mt7996_phy2(dev); |
| struct mt7996_phy *phy3 = mt7996_phy3(dev); |
| - u32 val, reg_offset; |
| + u32 reg_offset; |
| u32 cck = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 231) | |
| FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48); |
| u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) | |
| FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28); |
| u8 band_idx = phy->mt76->band_idx; |
| int offset; |
| - bool a_band = !(phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ); |
| |
| if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state)) |
| return; |
| @@ -1637,34 +1471,12 @@ void mt7996_mac_set_timing(struct mt7996_phy *phy) |
| coverage_class = max_t(s16, coverage_class, |
| phy3->coverage_class); |
| |
| - mt76_set(dev, MT_ARB_SCR(band_idx), |
| - MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE); |
| - udelay(1); |
| - |
| offset = 3 * coverage_class; |
| reg_offset = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, offset) | |
| FIELD_PREP(MT_TIMEOUT_VAL_CCA, offset); |
| |
| mt76_wr(dev, MT_TMAC_CDTR(band_idx), cck + reg_offset); |
| mt76_wr(dev, MT_TMAC_ODTR(band_idx), ofdm + reg_offset); |
| - mt76_wr(dev, MT_TMAC_ICR0(band_idx), |
| - FIELD_PREP(MT_IFS_EIFS_OFDM, a_band ? 84 : 78) | |
| - FIELD_PREP(MT_IFS_RIFS, 2) | |
| - FIELD_PREP(MT_IFS_SIFS, 10) | |
| - FIELD_PREP(MT_IFS_SLOT, phy->slottime)); |
| - |
| - if (!a_band) |
| - mt76_wr(dev, MT_TMAC_ICR1(band_idx), |
| - FIELD_PREP(MT_IFS_EIFS_CCK, 314)); |
| - |
| - if (phy->slottime < 20 || a_band) |
| - val = MT7996_CFEND_RATE_DEFAULT; |
| - else |
| - val = MT7996_CFEND_RATE_11B; |
| - |
| - mt76_rmw_field(dev, MT_RATE_HRCR0(band_idx), MT_RATE_HRCR0_CFEND_RATE, val); |
| - mt76_clear(dev, MT_ARB_SCR(band_idx), |
| - MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE); |
| } |
| |
| void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band) |
| @@ -2048,6 +1860,12 @@ void mt7996_mac_reset_work(struct work_struct *work) |
| mt7996_wait_reset_state(dev, MT_MCU_CMD_RECOVERY_DONE); |
| } |
| |
| + mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE); |
| + mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE); |
| + |
| + /* enable DMA Tx/Tx and interrupt */ |
| + mt7996_dma_start(dev, false); |
| + |
| clear_bit(MT76_MCU_RESET, &dev->mphy.state); |
| clear_bit(MT76_RESET, &dev->mphy.state); |
| if (phy2) |
| @@ -2064,9 +1882,6 @@ void mt7996_mac_reset_work(struct work_struct *work) |
| |
| tasklet_schedule(&dev->mt76.irq_tasklet); |
| |
| - mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE); |
| - mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE); |
| - |
| mt76_worker_enable(&dev->mt76.tx_worker); |
| |
| local_bh_disable(); |
| @@ -2193,8 +2008,8 @@ void mt7996_reset(struct mt7996_dev *dev) |
| |
| void mt7996_mac_update_stats(struct mt7996_phy *phy) |
| { |
| + struct mt76_mib_stats *mib = &phy->mib; |
| struct mt7996_dev *dev = phy->dev; |
| - struct mib_stats *mib = &phy->mib; |
| u8 band_idx = phy->mt76->band_idx; |
| u32 cnt; |
| int i; |
| @@ -2341,7 +2156,7 @@ void mt7996_mac_sta_rc_work(struct work_struct *work) |
| u32 changed; |
| LIST_HEAD(list); |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| list_splice_init(&dev->sta_rc_list, &list); |
| |
| while (!list_empty(&list)) { |
| @@ -2349,7 +2164,7 @@ void mt7996_mac_sta_rc_work(struct work_struct *work) |
| list_del_init(&msta->rc_list); |
| changed = msta->changed; |
| msta->changed = 0; |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| sta = container_of((void *)msta, struct ieee80211_sta, drv_priv); |
| vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv); |
| @@ -2361,10 +2176,10 @@ void mt7996_mac_sta_rc_work(struct work_struct *work) |
| |
| /* TODO: smps change */ |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| } |
| |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| } |
| |
| void mt7996_mac_work(struct work_struct *work) |
| diff --git a/mt7996/mac.h b/mt7996/mac.h |
| index bc4e6c55..e629324a 100644 |
| --- a/mt7996/mac.h |
| +++ b/mt7996/mac.h |
| @@ -6,320 +6,7 @@ |
| #ifndef __MT7996_MAC_H |
| #define __MT7996_MAC_H |
| |
| -#define MT_CT_PARSE_LEN 72 |
| -#define MT_CT_DMA_BUF_NUM 2 |
| - |
| -#define MT_RXD0_LENGTH GENMASK(15, 0) |
| -#define MT_RXD0_PKT_TYPE GENMASK(31, 27) |
| - |
| -#define MT_RXD0_MESH BIT(18) |
| -#define MT_RXD0_MHCP BIT(19) |
| -#define MT_RXD0_NORMAL_ETH_TYPE_OFS GENMASK(22, 16) |
| -#define MT_RXD0_NORMAL_IP_SUM BIT(23) |
| -#define MT_RXD0_NORMAL_UDP_TCP_SUM BIT(24) |
| - |
| -#define MT_RXD0_SW_PKT_TYPE_MASK GENMASK(31, 16) |
| -#define MT_RXD0_SW_PKT_TYPE_MAP 0x380F |
| -#define MT_RXD0_SW_PKT_TYPE_FRAME 0x3801 |
| - |
| -/* RXD DW1 */ |
| -#define MT_RXD1_NORMAL_WLAN_IDX GENMASK(11, 0) |
| -#define MT_RXD1_NORMAL_GROUP_1 BIT(16) |
| -#define MT_RXD1_NORMAL_GROUP_2 BIT(17) |
| -#define MT_RXD1_NORMAL_GROUP_3 BIT(18) |
| -#define MT_RXD1_NORMAL_GROUP_4 BIT(19) |
| -#define MT_RXD1_NORMAL_GROUP_5 BIT(20) |
| -#define MT_RXD1_NORMAL_KEY_ID GENMASK(22, 21) |
| -#define MT_RXD1_NORMAL_CM BIT(23) |
| -#define MT_RXD1_NORMAL_CLM BIT(24) |
| -#define MT_RXD1_NORMAL_ICV_ERR BIT(25) |
| -#define MT_RXD1_NORMAL_TKIP_MIC_ERR BIT(26) |
| -#define MT_RXD1_NORMAL_BAND_IDX GENMASK(28, 27) |
| -#define MT_RXD1_NORMAL_SPP_EN BIT(29) |
| -#define MT_RXD1_NORMAL_ADD_OM BIT(30) |
| -#define MT_RXD1_NORMAL_SEC_DONE BIT(31) |
| - |
| -/* RXD DW2 */ |
| -#define MT_RXD2_NORMAL_BSSID GENMASK(5, 0) |
| -#define MT_RXD2_NORMAL_MAC_HDR_LEN GENMASK(12, 8) |
| -#define MT_RXD2_NORMAL_HDR_TRANS BIT(7) |
| -#define MT_RXD2_NORMAL_HDR_OFFSET GENMASK(15, 13) |
| -#define MT_RXD2_NORMAL_SEC_MODE GENMASK(20, 16) |
| -#define MT_RXD2_NORMAL_MU_BAR BIT(21) |
| -#define MT_RXD2_NORMAL_SW_BIT BIT(22) |
| -#define MT_RXD2_NORMAL_AMSDU_ERR BIT(23) |
| -#define MT_RXD2_NORMAL_MAX_LEN_ERROR BIT(24) |
| -#define MT_RXD2_NORMAL_HDR_TRANS_ERROR BIT(25) |
| -#define MT_RXD2_NORMAL_INT_FRAME BIT(26) |
| -#define MT_RXD2_NORMAL_FRAG BIT(27) |
| -#define MT_RXD2_NORMAL_NULL_FRAME BIT(28) |
| -#define MT_RXD2_NORMAL_NDATA BIT(29) |
| -#define MT_RXD2_NORMAL_NON_AMPDU BIT(30) |
| -#define MT_RXD2_NORMAL_BF_REPORT BIT(31) |
| - |
| -/* RXD DW3 */ |
| -#define MT_RXD3_NORMAL_RXV_SEQ GENMASK(7, 0) |
| -#define MT_RXD3_NORMAL_CH_FREQ GENMASK(15, 8) |
| -#define MT_RXD3_NORMAL_ADDR_TYPE GENMASK(17, 16) |
| -#define MT_RXD3_NORMAL_U2M BIT(0) |
| -#define MT_RXD3_NORMAL_HTC_VLD BIT(18) |
| -#define MT_RXD3_NORMAL_BEACON_MC BIT(20) |
| -#define MT_RXD3_NORMAL_BEACON_UC BIT(21) |
| -#define MT_RXD3_NORMAL_CO_ANT BIT(22) |
| -#define MT_RXD3_NORMAL_FCS_ERR BIT(24) |
| -#define MT_RXD3_NORMAL_VLAN2ETH BIT(31) |
| - |
| -/* RXD DW4 */ |
| -#define MT_RXD4_NORMAL_PAYLOAD_FORMAT GENMASK(1, 0) |
| -#define MT_RXD4_FIRST_AMSDU_FRAME GENMASK(1, 0) |
| -#define MT_RXD4_MID_AMSDU_FRAME BIT(1) |
| -#define MT_RXD4_LAST_AMSDU_FRAME BIT(0) |
| - |
| -#define MT_RXV_HDR_BAND_IDX BIT(24) |
| - |
| -/* RXD GROUP4 */ |
| -#define MT_RXD8_FRAME_CONTROL GENMASK(15, 0) |
| - |
| -#define MT_RXD10_SEQ_CTRL GENMASK(15, 0) |
| -#define MT_RXD10_QOS_CTL GENMASK(31, 16) |
| - |
| -#define MT_RXD11_HT_CONTROL GENMASK(31, 0) |
| - |
| -/* P-RXV */ |
| -#define MT_PRXV_TX_RATE GENMASK(6, 0) |
| -#define MT_PRXV_TX_DCM BIT(4) |
| -#define MT_PRXV_TX_ER_SU_106T BIT(5) |
| -#define MT_PRXV_NSTS GENMASK(10, 7) |
| -#define MT_PRXV_TXBF BIT(11) |
| -#define MT_PRXV_HT_AD_CODE BIT(12) |
| -#define MT_PRXV_HE_RU_ALLOC GENMASK(30, 22) |
| -#define MT_PRXV_RCPI3 GENMASK(31, 24) |
| -#define MT_PRXV_RCPI2 GENMASK(23, 16) |
| -#define MT_PRXV_RCPI1 GENMASK(15, 8) |
| -#define MT_PRXV_RCPI0 GENMASK(7, 0) |
| -#define MT_PRXV_HT_SHORT_GI GENMASK(4, 3) |
| -#define MT_PRXV_HT_STBC GENMASK(10, 9) |
| -#define MT_PRXV_TX_MODE GENMASK(14, 11) |
| -#define MT_PRXV_FRAME_MODE GENMASK(2, 0) |
| -#define MT_PRXV_DCM BIT(5) |
| - |
| -/* C-RXV */ |
| -#define MT_CRXV_HE_NUM_USER GENMASK(26, 20) |
| -#define MT_CRXV_HE_LTF_SIZE GENMASK(28, 27) |
| -#define MT_CRXV_HE_LDPC_EXT_SYM BIT(30) |
| - |
| -#define MT_CRXV_HE_PE_DISAMBIG BIT(1) |
| -#define MT_CRXV_HE_UPLINK BIT(2) |
| - |
| -#define MT_CRXV_HE_MU_AID GENMASK(27, 17) |
| -#define MT_CRXV_HE_BEAM_CHNG BIT(29) |
| - |
| -#define MT_CRXV_HE_DOPPLER BIT(0) |
| -#define MT_CRXV_HE_BSS_COLOR GENMASK(15, 10) |
| -#define MT_CRXV_HE_TXOP_DUR GENMASK(19, 17) |
| - |
| -#define MT_CRXV_HE_SR_MASK GENMASK(11, 8) |
| -#define MT_CRXV_HE_SR1_MASK GENMASK(16, 12) |
| -#define MT_CRXV_HE_SR2_MASK GENMASK(20, 17) |
| -#define MT_CRXV_HE_SR3_MASK GENMASK(24, 21) |
| - |
| -#define MT_CRXV_HE_RU0 GENMASK(8, 0) |
| -#define MT_CRXV_HE_RU1 GENMASK(17, 9) |
| -#define MT_CRXV_HE_RU2 GENMASK(26, 18) |
| -#define MT_CRXV_HE_RU3_L GENMASK(31, 27) |
| -#define MT_CRXV_HE_RU3_H GENMASK(3, 0) |
| - |
| -enum tx_header_format { |
| - MT_HDR_FORMAT_802_3, |
| - MT_HDR_FORMAT_CMD, |
| - MT_HDR_FORMAT_802_11, |
| - MT_HDR_FORMAT_802_11_EXT, |
| -}; |
| - |
| -enum tx_pkt_type { |
| - MT_TX_TYPE_CT, |
| - MT_TX_TYPE_SF, |
| - MT_TX_TYPE_CMD, |
| - MT_TX_TYPE_FW, |
| -}; |
| - |
| -enum tx_port_idx { |
| - MT_TX_PORT_IDX_LMAC, |
| - MT_TX_PORT_IDX_MCU |
| -}; |
| - |
| -enum tx_mcu_port_q_idx { |
| - MT_TX_MCU_PORT_RX_Q0 = 0x20, |
| - MT_TX_MCU_PORT_RX_Q1, |
| - MT_TX_MCU_PORT_RX_Q2, |
| - MT_TX_MCU_PORT_RX_Q3, |
| - MT_TX_MCU_PORT_RX_FWDL = 0x3e |
| -}; |
| - |
| -enum tx_mgnt_type { |
| - MT_TX_NORMAL, |
| - MT_TX_TIMING, |
| - MT_TX_ADDBA, |
| -}; |
| - |
| -#define MT_CT_INFO_APPLY_TXD BIT(0) |
| -#define MT_CT_INFO_COPY_HOST_TXD_ALL BIT(1) |
| -#define MT_CT_INFO_MGMT_FRAME BIT(2) |
| -#define MT_CT_INFO_NONE_CIPHER_FRAME BIT(3) |
| -#define MT_CT_INFO_HSR2_TX BIT(4) |
| -#define MT_CT_INFO_FROM_HOST BIT(7) |
| - |
| -#define MT_TXD_SIZE (8 * 4) |
| - |
| -#define MT_TXD0_Q_IDX GENMASK(31, 25) |
| -#define MT_TXD0_PKT_FMT GENMASK(24, 23) |
| -#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16) |
| -#define MT_TXD0_TX_BYTES GENMASK(15, 0) |
| - |
| -#define MT_TXD1_FIXED_RATE BIT(31) |
| -#define MT_TXD1_OWN_MAC GENMASK(30, 25) |
| -#define MT_TXD1_TID GENMASK(24, 21) |
| -#define MT_TXD1_BIP BIT(24) |
| -#define MT_TXD1_ETH_802_3 BIT(20) |
| -#define MT_TXD1_HDR_INFO GENMASK(20, 16) |
| -#define MT_TXD1_HDR_FORMAT GENMASK(15, 14) |
| -#define MT_TXD1_TGID GENMASK(13, 12) |
| -#define MT_TXD1_WLAN_IDX GENMASK(11, 0) |
| - |
| -#define MT_TXD2_POWER_OFFSET GENMASK(31, 26) |
| -#define MT_TXD2_MAX_TX_TIME GENMASK(25, 16) |
| -#define MT_TXD2_FRAG GENMASK(15, 14) |
| -#define MT_TXD2_HTC_VLD BIT(13) |
| -#define MT_TXD2_DURATION BIT(12) |
| -#define MT_TXD2_HDR_PAD GENMASK(11, 10) |
| -#define MT_TXD2_RTS BIT(9) |
| -#define MT_TXD2_OWN_MAC_MAP BIT(8) |
| -#define MT_TXD2_BF_TYPE GENMASK(6, 7) |
| -#define MT_TXD2_FRAME_TYPE GENMASK(5, 4) |
| -#define MT_TXD2_SUB_TYPE GENMASK(3, 0) |
| - |
| -#define MT_TXD3_SN_VALID BIT(31) |
| -#define MT_TXD3_PN_VALID BIT(30) |
| -#define MT_TXD3_SW_POWER_MGMT BIT(29) |
| -#define MT_TXD3_BA_DISABLE BIT(28) |
| -#define MT_TXD3_SEQ GENMASK(27, 16) |
| -#define MT_TXD3_REM_TX_COUNT GENMASK(15, 11) |
| -#define MT_TXD3_TX_COUNT GENMASK(10, 6) |
| -#define MT_TXD3_HW_AMSDU BIT(5) |
| -#define MT_TXD3_BCM BIT(4) |
| -#define MT_TXD3_EEOSP BIT(3) |
| -#define MT_TXD3_EMRD BIT(2) |
| -#define MT_TXD3_PROTECT_FRAME BIT(1) |
| -#define MT_TXD3_NO_ACK BIT(0) |
| - |
| -#define MT_TXD4_PN_LOW GENMASK(31, 0) |
| - |
| -#define MT_TXD5_PN_HIGH GENMASK(31, 16) |
| -#define MT_TXD5_FL BIT(15) |
| -#define MT_TXD5_BYPASS_TBB BIT(14) |
| -#define MT_TXD5_BYPASS_RBB BIT(13) |
| -#define MT_TXD5_BSS_COLOR_ZERO BIT(12) |
| -#define MT_TXD5_TX_STATUS_HOST BIT(10) |
| -#define MT_TXD5_TX_STATUS_MCU BIT(9) |
| -#define MT_TXD5_TX_STATUS_FMT BIT(8) |
| -#define MT_TXD5_PID GENMASK(7, 0) |
| - |
| -#define MT_TXD6_TX_SRC GENMASK(31, 30) |
| -#define MT_TXD6_VTA BIT(28) |
| -#define MT_TXD6_BW GENMASK(25, 22) |
| -#define MT_TXD6_TX_RATE GENMASK(21, 16) |
| -#define MT_TXD6_TIMESTAMP_OFS_EN BIT(15) |
| -#define MT_TXD6_TIMESTAMP_OFS_IDX GENMASK(14, 10) |
| -#define MT_TXD6_MSDU_CNT GENMASK(9, 4) |
| -#define MT_TXD6_DIS_MAT BIT(3) |
| -#define MT_TXD6_DAS BIT(2) |
| -#define MT_TXD6_AMSDU_CAP BIT(1) |
| - |
| -#define MT_TXD7_TXD_LEN GENMASK(31, 30) |
| -#define MT_TXD7_IP_SUM BIT(29) |
| -#define MT_TXD7_DROP_BY_SDO BIT(28) |
| -#define MT_TXD7_MAC_TXD BIT(27) |
| -#define MT_TXD7_CTXD BIT(26) |
| -#define MT_TXD7_CTXD_CNT GENMASK(25, 22) |
| -#define MT_TXD7_UDP_TCP_SUM BIT(15) |
| -#define MT_TXD7_TX_TIME GENMASK(9, 0) |
| - |
| -#define MT_TX_RATE_STBC BIT(14) |
| -#define MT_TX_RATE_NSS GENMASK(13, 10) |
| -#define MT_TX_RATE_MODE GENMASK(9, 6) |
| -#define MT_TX_RATE_SU_EXT_TONE BIT(5) |
| -#define MT_TX_RATE_DCM BIT(4) |
| -/* VHT/HE only use bits 0-3 */ |
| -#define MT_TX_RATE_IDX GENMASK(5, 0) |
| - |
| -#define MT_TXFREE0_PKT_TYPE GENMASK(31, 27) |
| -#define MT_TXFREE0_MSDU_CNT GENMASK(25, 16) |
| -#define MT_TXFREE0_RX_BYTE GENMASK(15, 0) |
| - |
| -#define MT_TXFREE1_VER GENMASK(18, 16) |
| - |
| -#define MT_TXFREE_INFO_PAIR BIT(31) |
| -#define MT_TXFREE_INFO_HEADER BIT(30) |
| -#define MT_TXFREE_INFO_WLAN_ID GENMASK(23, 12) |
| -#define MT_TXFREE_INFO_MSDU_ID GENMASK(14, 0) |
| - |
| -#define MT_TXS0_BW GENMASK(31, 29) |
| -#define MT_TXS0_TID GENMASK(28, 26) |
| -#define MT_TXS0_AMPDU BIT(25) |
| -#define MT_TXS0_TXS_FORMAT GENMASK(24, 23) |
| -#define MT_TXS0_BA_ERROR BIT(22) |
| -#define MT_TXS0_PS_FLAG BIT(21) |
| -#define MT_TXS0_TXOP_TIMEOUT BIT(20) |
| -#define MT_TXS0_BIP_ERROR BIT(19) |
| - |
| -#define MT_TXS0_QUEUE_TIMEOUT BIT(18) |
| -#define MT_TXS0_RTS_TIMEOUT BIT(17) |
| -#define MT_TXS0_ACK_TIMEOUT BIT(16) |
| -#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16) |
| - |
| -#define MT_TXS0_TX_STATUS_HOST BIT(15) |
| -#define MT_TXS0_TX_STATUS_MCU BIT(14) |
| -#define MT_TXS0_TX_RATE GENMASK(13, 0) |
| - |
| -#define MT_TXS1_SEQNO GENMASK(31, 20) |
| -#define MT_TXS1_RESP_RATE GENMASK(19, 16) |
| -#define MT_TXS1_RXV_SEQNO GENMASK(15, 8) |
| -#define MT_TXS1_TX_POWER_DBM GENMASK(7, 0) |
| - |
| -#define MT_TXS2_BF_STATUS GENMASK(31, 30) |
| -#define MT_TXS2_BAND GENMASK(29, 28) |
| -#define MT_TXS2_WCID GENMASK(27, 16) |
| -#define MT_TXS2_TX_DELAY GENMASK(15, 0) |
| - |
| -#define MT_TXS3_PID GENMASK(31, 24) |
| -#define MT_TXS3_RATE_STBC BIT(7) |
| -#define MT_TXS3_FIXED_RATE BIT(6) |
| -#define MT_TXS3_SRC GENMASK(5, 4) |
| -#define MT_TXS3_SHARED_ANTENNA BIT(3) |
| -#define MT_TXS3_LAST_TX_RATE GENMASK(2, 0) |
| - |
| -#define MT_TXS4_TIMESTAMP GENMASK(31, 0) |
| - |
| -#define MT_TXS5_F0_FINAL_MPDU BIT(31) |
| -#define MT_TXS5_F0_QOS BIT(30) |
| -#define MT_TXS5_F0_TX_COUNT GENMASK(29, 25) |
| -#define MT_TXS5_F0_FRONT_TIME GENMASK(24, 0) |
| -#define MT_TXS5_F1_MPDU_TX_COUNT GENMASK(31, 24) |
| -#define MT_TXS5_F1_MPDU_TX_BYTES GENMASK(23, 0) |
| - |
| -#define MT_TXS6_F0_NOISE_3 GENMASK(31, 24) |
| -#define MT_TXS6_F0_NOISE_2 GENMASK(23, 16) |
| -#define MT_TXS6_F0_NOISE_1 GENMASK(15, 8) |
| -#define MT_TXS6_F0_NOISE_0 GENMASK(7, 0) |
| -#define MT_TXS6_F1_MPDU_FAIL_COUNT GENMASK(31, 24) |
| -#define MT_TXS6_F1_MPDU_FAIL_BYTES GENMASK(23, 0) |
| - |
| -#define MT_TXS7_F0_RCPI_3 GENMASK(31, 24) |
| -#define MT_TXS7_F0_RCPI_2 GENMASK(23, 16) |
| -#define MT_TXS7_F0_RCPI_1 GENMASK(15, 8) |
| -#define MT_TXS7_F0_RCPI_0 GENMASK(7, 0) |
| -#define MT_TXS7_F1_MPDU_RETRY_COUNT GENMASK(31, 24) |
| -#define MT_TXS7_F1_MPDU_RETRY_BYTES GENMASK(23, 0) |
| +#include "../mt76_connac3_mac.h" |
| |
| struct mt7996_dfs_pulse { |
| u32 max_width; /* us */ |
| diff --git a/mt7996/main.c b/mt7996/main.c |
| index f306e9c5..c3a479dc 100644 |
| --- a/mt7996/main.c |
| +++ b/mt7996/main.c |
| @@ -43,6 +43,10 @@ int mt7996_run(struct ieee80211_hw *hw) |
| if (ret) |
| goto out; |
| |
| + ret = mt7996_mcu_set_radio_en(phy, true); |
| + if (ret) |
| + goto out; |
| + |
| ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_RX_PATH); |
| if (ret) |
| goto out; |
| @@ -82,6 +86,8 @@ static void mt7996_stop(struct ieee80211_hw *hw) |
| |
| mutex_lock(&dev->mt76.mutex); |
| |
| + mt7996_mcu_set_radio_en(phy, false); |
| + |
| clear_bit(MT76_STATE_RUNNING, &phy->mt76->state); |
| |
| mutex_unlock(&dev->mt76.mutex); |
| @@ -190,17 +196,13 @@ static int mt7996_add_interface(struct ieee80211_hw *hw, |
| if (ret) |
| goto out; |
| |
| - ret = mt7996_mcu_set_radio_en(phy, true); |
| - if (ret) |
| - goto out; |
| - |
| dev->mt76.vif_mask |= BIT_ULL(mvif->mt76.idx); |
| phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx); |
| |
| idx = MT7996_WTBL_RESERVED - mvif->mt76.idx; |
| |
| INIT_LIST_HEAD(&mvif->sta.rc_list); |
| - INIT_LIST_HEAD(&mvif->sta.poll_list); |
| + INIT_LIST_HEAD(&mvif->sta.wcid.poll_list); |
| mvif->sta.wcid.idx = idx; |
| mvif->sta.wcid.phy_idx = band_idx; |
| mvif->sta.wcid.hw_key_idx = -1; |
| @@ -221,9 +223,9 @@ static int mt7996_add_interface(struct ieee80211_hw *hw, |
| vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR; |
| |
| if (phy->mt76->chandef.chan->band != NL80211_BAND_2GHZ) |
| - mvif->basic_rates_idx = MT7996_BASIC_RATES_TBL + 4; |
| + mvif->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL + 4; |
| else |
| - mvif->basic_rates_idx = MT7996_BASIC_RATES_TBL; |
| + mvif->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL; |
| |
| mt7996_init_bitrate_mask(vif); |
| |
| @@ -253,7 +255,6 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw, |
| phy->monitor_vif = NULL; |
| |
| mt7996_mcu_add_dev_info(phy, vif, false); |
| - mt7996_mcu_set_radio_en(phy, false); |
| |
| rcu_assign_pointer(dev->mt76.wcid[idx], NULL); |
| |
| @@ -262,10 +263,10 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw, |
| phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx); |
| mutex_unlock(&dev->mt76.mutex); |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (!list_empty(&msta->poll_list)) |
| - list_del_init(&msta->poll_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| + if (!list_empty(&msta->wcid.poll_list)) |
| + list_del_init(&msta->wcid.poll_list); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| |
| mt76_packet_id_flush(&dev->mt76, &msta->wcid); |
| } |
| @@ -286,7 +287,6 @@ int mt7996_set_channel(struct mt7996_phy *phy) |
| if (ret) |
| goto out; |
| |
| - mt7996_mac_set_timing(phy); |
| ret = mt7996_dfs_init_radar_detector(phy); |
| mt7996_mac_cca_stats_reset(phy); |
| |
| @@ -505,7 +505,7 @@ static u8 |
| mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| bool beacon, bool mcast) |
| { |
| - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| + struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; |
| struct mt76_phy *mphy = hw->priv; |
| u16 rate; |
| u8 i, idx, ht; |
| @@ -517,7 +517,7 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| struct mt7996_dev *dev = mt7996_hw_dev(hw); |
| |
| /* must odd index */ |
| - idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->mt76.idx % 20); |
| + idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->idx % 20); |
| mt7996_mac_set_fixed_rate_table(dev, idx, rate); |
| return idx; |
| } |
| @@ -530,12 +530,32 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| return mvif->basic_rates_idx; |
| } |
| |
| +static void |
| +mt7996_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| + struct ieee80211_bss_conf *info) |
| +{ |
| + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| + struct mt7996_dev *dev = mt7996_hw_dev(hw); |
| + u8 band = mvif->mt76.band_idx; |
| + u32 *mu; |
| + |
| + mu = (u32 *)info->mu_group.membership; |
| + mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_VLD0(band), mu[0]); |
| + mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_VLD1(band), mu[1]); |
| + |
| + mu = (u32 *)info->mu_group.position; |
| + mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS0(band), mu[0]); |
| + mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS1(band), mu[1]); |
| + mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS2(band), mu[2]); |
| + mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS3(band), mu[3]); |
| +} |
| + |
| static void mt7996_bss_info_changed(struct ieee80211_hw *hw, |
| struct ieee80211_vif *vif, |
| struct ieee80211_bss_conf *info, |
| u64 changed) |
| { |
| - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| + struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; |
| struct mt7996_phy *phy = mt7996_hw_phy(hw); |
| struct mt7996_dev *dev = mt7996_hw_dev(hw); |
| |
| @@ -563,7 +583,7 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw, |
| |
| if (slottime != phy->slottime) { |
| phy->slottime = slottime; |
| - mt7996_mac_set_timing(phy); |
| + mt7996_mcu_set_timing(phy, vif); |
| } |
| } |
| |
| @@ -602,6 +622,9 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw, |
| changed & BSS_CHANGED_FILS_DISCOVERY) |
| mt7996_mcu_beacon_inband_discov(dev, vif, changed); |
| |
| + if (changed & BSS_CHANGED_MU_GROUPS) |
| + mt7996_update_mu_group(hw, vif, info); |
| + |
| mutex_unlock(&dev->mt76.mutex); |
| } |
| |
| @@ -631,7 +654,7 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
| return -ENOSPC; |
| |
| INIT_LIST_HEAD(&msta->rc_list); |
| - INIT_LIST_HEAD(&msta->poll_list); |
| + INIT_LIST_HEAD(&msta->wcid.poll_list); |
| msta->vif = mvif; |
| msta->wcid.sta = 1; |
| msta->wcid.idx = idx; |
| @@ -666,12 +689,12 @@ void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
| for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++) |
| mt7996_mac_twt_teardown_flow(dev, msta, i); |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| - if (!list_empty(&msta->poll_list)) |
| - list_del_init(&msta->poll_list); |
| + spin_lock_bh(&mdev->sta_poll_lock); |
| + if (!list_empty(&msta->wcid.poll_list)) |
| + list_del_init(&msta->wcid.poll_list); |
| if (!list_empty(&msta->rc_list)) |
| list_del_init(&msta->rc_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_unlock_bh(&mdev->sta_poll_lock); |
| } |
| |
| static void mt7996_tx(struct ieee80211_hw *hw, |
| @@ -751,16 +774,16 @@ mt7996_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| case IEEE80211_AMPDU_TX_STOP_FLUSH: |
| case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: |
| mtxq->aggr = false; |
| - clear_bit(tid, &msta->ampdu_state); |
| + clear_bit(tid, &msta->wcid.ampdu_state); |
| ret = mt7996_mcu_add_tx_ba(dev, params, false); |
| break; |
| case IEEE80211_AMPDU_TX_START: |
| - set_bit(tid, &msta->ampdu_state); |
| + set_bit(tid, &msta->wcid.ampdu_state); |
| ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; |
| break; |
| case IEEE80211_AMPDU_TX_STOP_CONT: |
| mtxq->aggr = false; |
| - clear_bit(tid, &msta->ampdu_state); |
| + clear_bit(tid, &msta->wcid.ampdu_state); |
| ret = mt7996_mcu_add_tx_ba(dev, params, false); |
| ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
| break; |
| @@ -792,7 +815,7 @@ mt7996_get_stats(struct ieee80211_hw *hw, |
| { |
| struct mt7996_phy *phy = mt7996_hw_phy(hw); |
| struct mt7996_dev *dev = mt7996_hw_dev(hw); |
| - struct mib_stats *mib = &phy->mib; |
| + struct mt76_mib_stats *mib = &phy->mib; |
| |
| mutex_lock(&dev->mt76.mutex); |
| |
| @@ -903,7 +926,7 @@ mt7996_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) |
| |
| mutex_lock(&dev->mt76.mutex); |
| phy->coverage_class = max_t(s16, coverage_class, 0); |
| - mt7996_mac_set_timing(phy); |
| + mt7996_mac_set_coverage_class(phy); |
| mutex_unlock(&dev->mt76.mutex); |
| } |
| |
| @@ -952,18 +975,19 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw, |
| struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; |
| struct rate_info *txrate = &msta->wcid.rate; |
| |
| - if (!txrate->legacy && !txrate->flags) |
| - return; |
| - |
| - if (txrate->legacy) { |
| - sinfo->txrate.legacy = txrate->legacy; |
| - } else { |
| - sinfo->txrate.mcs = txrate->mcs; |
| - sinfo->txrate.nss = txrate->nss; |
| - sinfo->txrate.bw = txrate->bw; |
| - sinfo->txrate.he_gi = txrate->he_gi; |
| - sinfo->txrate.he_dcm = txrate->he_dcm; |
| - sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc; |
| + if (txrate->legacy || txrate->flags) { |
| + if (txrate->legacy) { |
| + sinfo->txrate.legacy = txrate->legacy; |
| + } else { |
| + sinfo->txrate.mcs = txrate->mcs; |
| + sinfo->txrate.nss = txrate->nss; |
| + sinfo->txrate.bw = txrate->bw; |
| + sinfo->txrate.he_gi = txrate->he_gi; |
| + sinfo->txrate.he_dcm = txrate->he_dcm; |
| + sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc; |
| + } |
| + sinfo->txrate.flags = txrate->flags; |
| + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); |
| } |
| sinfo->txrate.flags = txrate->flags; |
| sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); |
| @@ -981,11 +1005,11 @@ static void mt7996_sta_rc_work(void *data, struct ieee80211_sta *sta) |
| struct mt7996_dev *dev = msta->vif->phy->dev; |
| u32 *changed = data; |
| |
| - spin_lock_bh(&dev->sta_poll_lock); |
| + spin_lock_bh(&dev->mt76.sta_poll_lock); |
| msta->changed |= *changed; |
| if (list_empty(&msta->rc_list)) |
| list_add_tail(&msta->rc_list, &dev->sta_rc_list); |
| - spin_unlock_bh(&dev->sta_poll_lock); |
| + spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| } |
| |
| static void mt7996_sta_rc_update(struct ieee80211_hw *hw, |
| @@ -1153,6 +1177,10 @@ static const char mt7996_gstrings_stats[][ETH_GSTRING_LEN] = { |
| "v_tx_mcs_11", |
| "v_tx_mcs_12", |
| "v_tx_mcs_13", |
| + "v_tx_nss_1", |
| + "v_tx_nss_2", |
| + "v_tx_nss_3", |
| + "v_tx_nss_4", |
| }; |
| |
| #define MT7996_SSTATS_LEN ARRAY_SIZE(mt7996_gstrings_stats) |
| @@ -1186,7 +1214,7 @@ static void mt7996_ethtool_worker(void *wi_data, struct ieee80211_sta *sta) |
| if (msta->vif->mt76.idx != wi->idx) |
| return; |
| |
| - mt76_ethtool_worker(wi, &msta->stats, true); |
| + mt76_ethtool_worker(wi, &msta->wcid.stats, true); |
| } |
| |
| static |
| @@ -1197,11 +1225,11 @@ void mt7996_get_et_stats(struct ieee80211_hw *hw, |
| struct mt7996_dev *dev = mt7996_hw_dev(hw); |
| struct mt7996_phy *phy = mt7996_hw_phy(hw); |
| struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| + struct mt76_mib_stats *mib = &phy->mib; |
| struct mt76_ethtool_worker_info wi = { |
| .data = data, |
| .idx = mvif->mt76.idx, |
| }; |
| - struct mib_stats *mib = &phy->mib; |
| /* See mt7996_ampdu_stat_read_phy, etc */ |
| int i, ei = 0; |
| |
| diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
| index 88e2f9d0..4a30db49 100644 |
| --- a/mt7996/mcu.c |
| +++ b/mt7996/mcu.c |
| @@ -339,7 +339,11 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb) |
| if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys)) |
| return; |
| |
| - mphy = dev->mt76.phys[r->band_idx]; |
| + if (dev->rdd2_phy && r->band_idx == MT_RX_SEL2) |
| + mphy = dev->rdd2_phy->mt76; |
| + else |
| + mphy = dev->mt76.phys[r->band_idx]; |
| + |
| if (!mphy) |
| return; |
| |
| @@ -600,7 +604,7 @@ static void |
| mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, |
| struct mt7996_phy *phy) |
| { |
| - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| + struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; |
| struct bss_rate_tlv *bmc; |
| struct cfg80211_chan_def *chandef = &phy->mt76->chandef; |
| enum nl80211_band band = chandef->chan->band; |
| @@ -701,6 +705,34 @@ mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif, |
| sizeof(req), true); |
| } |
| |
| +static void |
| +mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct ieee80211_vif *vif) |
| +{ |
| + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| + struct mt7996_phy *phy = mvif->phy; |
| + struct bss_ifs_time_tlv *ifs_time; |
| + struct tlv *tlv; |
| + bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ; |
| + |
| + tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_IFS_TIME, sizeof(*ifs_time)); |
| + |
| + ifs_time = (struct bss_ifs_time_tlv *)tlv; |
| + ifs_time->slot_valid = true; |
| + ifs_time->sifs_valid = true; |
| + ifs_time->rifs_valid = true; |
| + ifs_time->eifs_valid = true; |
| + |
| + ifs_time->slot_time = cpu_to_le16(phy->slottime); |
| + ifs_time->sifs_time = cpu_to_le16(10); |
| + ifs_time->rifs_time = cpu_to_le16(2); |
| + ifs_time->eifs_time = cpu_to_le16(is_2ghz ? 78 : 84); |
| + |
| + if (is_2ghz) { |
| + ifs_time->eifs_cck_valid = true; |
| + ifs_time->eifs_cck_time = cpu_to_le16(314); |
| + } |
| +} |
| + |
| static int |
| mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, |
| struct ieee80211_vif *vif, |
| @@ -712,6 +744,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, |
| struct cfg80211_chan_def *chandef = &phy->chandef; |
| struct mt76_connac_bss_basic_tlv *bss; |
| u32 type = CONNECTION_INFRA_AP; |
| + u16 sta_wlan_idx = wlan_idx; |
| struct tlv *tlv; |
| int idx; |
| |
| @@ -731,7 +764,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, |
| struct mt76_wcid *wcid; |
| |
| wcid = (struct mt76_wcid *)sta->drv_priv; |
| - wlan_idx = wcid->idx; |
| + sta_wlan_idx = wcid->idx; |
| } |
| rcu_read_unlock(); |
| } |
| @@ -751,7 +784,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, |
| bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int); |
| bss->dtim_period = vif->bss_conf.dtim_period; |
| bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx); |
| - bss->sta_idx = cpu_to_le16(wlan_idx); |
| + bss->sta_idx = cpu_to_le16(sta_wlan_idx); |
| bss->conn_type = cpu_to_le32(type); |
| bss->omac_idx = mvif->omac_idx; |
| bss->band_idx = mvif->band_idx; |
| @@ -825,6 +858,7 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy, |
| mt7996_mcu_bss_bmc_tlv(skb, vif, phy); |
| mt7996_mcu_bss_ra_tlv(skb, vif, phy); |
| mt7996_mcu_bss_txcmd_tlv(skb, true); |
| + mt7996_mcu_bss_ifs_timing_tlv(skb, vif); |
| |
| if (vif->bss_conf.he_support) |
| mt7996_mcu_bss_he_tlv(skb, vif, phy); |
| @@ -837,6 +871,23 @@ out: |
| MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); |
| } |
| |
| +int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif) |
| +{ |
| + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| + struct mt7996_dev *dev = phy->dev; |
| + struct sk_buff *skb; |
| + |
| + skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, |
| + MT7996_BSS_UPDATE_MAX_SIZE); |
| + if (IS_ERR(skb)) |
| + return PTR_ERR(skb); |
| + |
| + mt7996_mcu_bss_ifs_timing_tlv(skb, vif); |
| + |
| + return mt76_mcu_skb_send_msg(&dev->mt76, skb, |
| + MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); |
| +} |
| + |
| static int |
| mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif, |
| struct ieee80211_ampdu_params *params, |
| @@ -1050,6 +1101,59 @@ mt7996_mcu_sta_amsdu_tlv(struct mt7996_dev *dev, struct sk_buff *skb, |
| } |
| } |
| |
| +static void |
| +mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb, |
| + struct ieee80211_vif *vif, struct ieee80211_sta *sta) |
| +{ |
| + struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem; |
| + struct sta_rec_muru *muru; |
| + struct tlv *tlv; |
| + |
| + if (vif->type != NL80211_IFTYPE_STATION && |
| + vif->type != NL80211_IFTYPE_AP) |
| + return; |
| + |
| + tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_MURU, sizeof(*muru)); |
| + |
| + muru = (struct sta_rec_muru *)tlv; |
| + muru->cfg.mimo_dl_en = vif->bss_conf.eht_mu_beamformer || |
| + vif->bss_conf.he_mu_beamformer || |
| + vif->bss_conf.vht_mu_beamformer || |
| + vif->bss_conf.vht_mu_beamformee; |
| + muru->cfg.ofdma_dl_en = true; |
| + |
| + if (sta->deflink.vht_cap.vht_supported) |
| + muru->mimo_dl.vht_mu_bfee = |
| + !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE); |
| + |
| + if (!sta->deflink.he_cap.has_he) |
| + return; |
| + |
| + muru->mimo_dl.partial_bw_dl_mimo = |
| + HE_PHY(CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO, elem->phy_cap_info[6]); |
| + |
| + muru->mimo_ul.full_ul_mimo = |
| + HE_PHY(CAP2_UL_MU_FULL_MU_MIMO, elem->phy_cap_info[2]); |
| + muru->mimo_ul.partial_ul_mimo = |
| + HE_PHY(CAP2_UL_MU_PARTIAL_MU_MIMO, elem->phy_cap_info[2]); |
| + |
| + muru->ofdma_dl.punc_pream_rx = |
| + HE_PHY(CAP1_PREAMBLE_PUNC_RX_MASK, elem->phy_cap_info[1]); |
| + muru->ofdma_dl.he_20m_in_40m_2g = |
| + HE_PHY(CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G, elem->phy_cap_info[8]); |
| + muru->ofdma_dl.he_20m_in_160m = |
| + HE_PHY(CAP8_20MHZ_IN_160MHZ_HE_PPDU, elem->phy_cap_info[8]); |
| + muru->ofdma_dl.he_80m_in_160m = |
| + HE_PHY(CAP8_80MHZ_IN_160MHZ_HE_PPDU, elem->phy_cap_info[8]); |
| + |
| + muru->ofdma_ul.t_frame_dur = |
| + HE_MAC(CAP1_TF_MAC_PAD_DUR_MASK, elem->mac_cap_info[1]); |
| + muru->ofdma_ul.mu_cascading = |
| + HE_MAC(CAP2_MU_CASCADING, elem->mac_cap_info[2]); |
| + muru->ofdma_ul.uo_ra = |
| + HE_MAC(CAP3_OFDMA_RA, elem->mac_cap_info[3]); |
| +} |
| + |
| static inline bool |
| mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif, |
| struct ieee80211_sta *sta, bool bfee) |
| @@ -1727,7 +1831,8 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif, |
| mt7996_mcu_sta_he_6g_tlv(skb, sta); |
| /* starec eht */ |
| mt7996_mcu_sta_eht_tlv(skb, sta); |
| - /* TODO: starec muru */ |
| + /* starec muru */ |
| + mt7996_mcu_sta_muru_tlv(dev, skb, vif, sta); |
| /* starec bfee */ |
| mt7996_mcu_sta_bfee_tlv(dev, skb, vif, sta); |
| /* starec hdr trans */ |
| @@ -2155,7 +2260,7 @@ out: |
| static int |
| mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev, |
| const struct mt7996_fw_trailer *hdr, |
| - const u8 *data, bool is_wa) |
| + const u8 *data, enum mt7996_ram_type type) |
| { |
| int i, offset = 0; |
| u32 override = 0, option = 0; |
| @@ -2167,8 +2272,10 @@ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev, |
| |
| region = (const struct mt7996_fw_region *)((const u8 *)hdr - |
| (hdr->n_region - i) * sizeof(*region)); |
| + /* DSP and WA use same mode */ |
| mode = mt76_connac_mcu_gen_dl_mode(&dev->mt76, |
| - region->feature_set, is_wa); |
| + region->feature_set, |
| + type != MT7996_RAM_TYPE_WM); |
| len = le32_to_cpu(region->len); |
| addr = le32_to_cpu(region->addr); |
| |
| @@ -2195,19 +2302,22 @@ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev, |
| if (override) |
| option |= FW_START_OVERRIDE; |
| |
| - if (is_wa) |
| + if (type == MT7996_RAM_TYPE_WA) |
| option |= FW_START_WORKING_PDA_CR4; |
| + else if (type == MT7996_RAM_TYPE_DSP) |
| + option |= FW_START_WORKING_PDA_DSP; |
| |
| return mt76_connac_mcu_start_firmware(&dev->mt76, override, option); |
| } |
| |
| -static int mt7996_load_ram(struct mt7996_dev *dev) |
| +static int __mt7996_load_ram(struct mt7996_dev *dev, const char *fw_type, |
| + const char *fw_file, enum mt7996_ram_type ram_type) |
| { |
| const struct mt7996_fw_trailer *hdr; |
| const struct firmware *fw; |
| int ret; |
| |
| - ret = request_firmware(&fw, MT7996_FIRMWARE_WM, dev->mt76.dev); |
| + ret = request_firmware(&fw, fw_file, dev->mt76.dev); |
| if (ret) |
| return ret; |
| |
| @@ -2217,37 +2327,13 @@ static int mt7996_load_ram(struct mt7996_dev *dev) |
| goto out; |
| } |
| |
| - hdr = (const struct mt7996_fw_trailer *)(fw->data + fw->size - sizeof(*hdr)); |
| + hdr = (const void *)(fw->data + fw->size - sizeof(*hdr)); |
| + dev_info(dev->mt76.dev, "%s Firmware Version: %.10s, Build Time: %.15s\n", |
| + fw_type, hdr->fw_ver, hdr->build_date); |
| |
| - dev_info(dev->mt76.dev, "WM Firmware Version: %.10s, Build Time: %.15s\n", |
| - hdr->fw_ver, hdr->build_date); |
| - |
| - ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, false); |
| + ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, ram_type); |
| if (ret) { |
| - dev_err(dev->mt76.dev, "Failed to start WM firmware\n"); |
| - goto out; |
| - } |
| - |
| - release_firmware(fw); |
| - |
| - ret = request_firmware(&fw, MT7996_FIRMWARE_WA, dev->mt76.dev); |
| - if (ret) |
| - return ret; |
| - |
| - if (!fw || !fw->data || fw->size < sizeof(*hdr)) { |
| - dev_err(dev->mt76.dev, "Invalid firmware\n"); |
| - ret = -EINVAL; |
| - goto out; |
| - } |
| - |
| - hdr = (const struct mt7996_fw_trailer *)(fw->data + fw->size - sizeof(*hdr)); |
| - |
| - dev_info(dev->mt76.dev, "WA Firmware Version: %.10s, Build Time: %.15s\n", |
| - hdr->fw_ver, hdr->build_date); |
| - |
| - ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, true); |
| - if (ret) { |
| - dev_err(dev->mt76.dev, "Failed to start WA firmware\n"); |
| + dev_err(dev->mt76.dev, "Failed to start %s firmware\n", fw_type); |
| goto out; |
| } |
| |
| @@ -2261,6 +2347,24 @@ out: |
| return ret; |
| } |
| |
| +static int mt7996_load_ram(struct mt7996_dev *dev) |
| +{ |
| + int ret; |
| + |
| + ret = __mt7996_load_ram(dev, "WM", MT7996_FIRMWARE_WM, |
| + MT7996_RAM_TYPE_WM); |
| + if (ret) |
| + return ret; |
| + |
| + ret = __mt7996_load_ram(dev, "DSP", MT7996_FIRMWARE_DSP, |
| + MT7996_RAM_TYPE_DSP); |
| + if (ret) |
| + return ret; |
| + |
| + return __mt7996_load_ram(dev, "WA", MT7996_FIRMWARE_WA, |
| + MT7996_RAM_TYPE_WA); |
| +} |
| + |
| static int |
| mt7996_firmware_state(struct mt7996_dev *dev, bool wa) |
| { |
| diff --git a/mt7996/mcu.h b/mt7996/mcu.h |
| index d7075a4d..078f8285 100644 |
| --- a/mt7996/mcu.h |
| +++ b/mt7996/mcu.h |
| @@ -317,6 +317,22 @@ struct bss_sec_tlv { |
| u8 __rsv2[1]; |
| } __packed; |
| |
| +struct bss_ifs_time_tlv { |
| + __le16 tag; |
| + __le16 len; |
| + u8 slot_valid; |
| + u8 sifs_valid; |
| + u8 rifs_valid; |
| + u8 eifs_valid; |
| + __le16 slot_time; |
| + __le16 sifs_time; |
| + __le16 rifs_time; |
| + __le16 eifs_time; |
| + u8 eifs_cck_valid; |
| + u8 rsv; |
| + __le16 eifs_cck_time; |
| +} __packed; |
| + |
| struct bss_power_save { |
| __le16 tag; |
| __le16 len; |
| @@ -552,6 +568,7 @@ enum { |
| sizeof(struct bss_txcmd_tlv) + \ |
| sizeof(struct bss_power_save) + \ |
| sizeof(struct bss_sec_tlv) + \ |
| + sizeof(struct bss_ifs_time_tlv) + \ |
| sizeof(struct bss_mld_tlv)) |
| |
| #define MT7996_STA_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \ |
| diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h |
| index 4d7dcb95..726c222e 100644 |
| --- a/mt7996/mt7996.h |
| +++ b/mt7996/mt7996.h |
| @@ -26,15 +26,17 @@ |
| |
| #define MT7996_RX_RING_SIZE 1536 |
| #define MT7996_RX_MCU_RING_SIZE 512 |
| +#define MT7996_RX_MCU_RING_SIZE_WA 1024 |
| |
| #define MT7996_FIRMWARE_WA "mediatek/mt7996/mt7996_wa.bin" |
| #define MT7996_FIRMWARE_WM "mediatek/mt7996/mt7996_wm.bin" |
| +#define MT7996_FIRMWARE_DSP "mediatek/mt7996/mt7996_dsp.bin" |
| #define MT7996_ROM_PATCH "mediatek/mt7996/mt7996_rom_patch.bin" |
| |
| #define MT7996_EEPROM_DEFAULT "mediatek/mt7996/mt7996_eeprom.bin" |
| #define MT7996_EEPROM_SIZE 7680 |
| #define MT7996_EEPROM_BLOCK_SIZE 16 |
| -#define MT7996_TOKEN_SIZE 8192 |
| +#define MT7996_TOKEN_SIZE 16384 |
| |
| #define MT7996_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */ |
| #define MT7996_CFEND_RATE_11B 0x03 /* 11B LP, 11M */ |
| @@ -52,6 +54,12 @@ struct mt7996_sta; |
| struct mt7996_dfs_pulse; |
| struct mt7996_dfs_pattern; |
| |
| +enum mt7996_ram_type { |
| + MT7996_RAM_TYPE_WM, |
| + MT7996_RAM_TYPE_WA, |
| + MT7996_RAM_TYPE_DSP, |
| +}; |
| + |
| enum mt7996_txq_id { |
| MT7996_TXQ_FWDL = 16, |
| MT7996_TXQ_MCU_WM, |
| @@ -95,7 +103,6 @@ struct mt7996_sta { |
| |
| struct mt7996_vif *vif; |
| |
| - struct list_head poll_list; |
| struct list_head rc_list; |
| u32 airtime_ac[8]; |
| |
| @@ -104,9 +111,6 @@ struct mt7996_sta { |
| |
| unsigned long changed; |
| unsigned long jiffies; |
| - unsigned long ampdu_state; |
| - |
| - struct mt76_sta_stats stats; |
| |
| struct mt76_connac_sta_key_conf bip; |
| |
| @@ -124,64 +128,6 @@ struct mt7996_vif { |
| |
| struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; |
| struct cfg80211_bitrate_mask bitrate_mask; |
| - |
| - u8 basic_rates_idx; |
| - u8 mcast_rates_idx; |
| - u8 beacon_rates_idx; |
| -}; |
| - |
| -/* per-phy stats. */ |
| -struct mib_stats { |
| - u32 ack_fail_cnt; |
| - u32 fcs_err_cnt; |
| - u32 rts_cnt; |
| - u32 rts_retries_cnt; |
| - u32 ba_miss_cnt; |
| - u32 tx_mu_bf_cnt; |
| - u32 tx_mu_mpdu_cnt; |
| - u32 tx_mu_acked_mpdu_cnt; |
| - u32 tx_su_acked_mpdu_cnt; |
| - u32 tx_bf_ibf_ppdu_cnt; |
| - u32 tx_bf_ebf_ppdu_cnt; |
| - |
| - u32 tx_bf_rx_fb_all_cnt; |
| - u32 tx_bf_rx_fb_eht_cnt; |
| - u32 tx_bf_rx_fb_he_cnt; |
| - u32 tx_bf_rx_fb_vht_cnt; |
| - u32 tx_bf_rx_fb_ht_cnt; |
| - |
| - u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */ |
| - u32 tx_bf_rx_fb_nc_cnt; |
| - u32 tx_bf_rx_fb_nr_cnt; |
| - u32 tx_bf_fb_cpl_cnt; |
| - u32 tx_bf_fb_trig_cnt; |
| - |
| - u32 tx_ampdu_cnt; |
| - u32 tx_stop_q_empty_cnt; |
| - u32 tx_mpdu_attempts_cnt; |
| - u32 tx_mpdu_success_cnt; |
| - /* BF counter is PPDU-based, so remove MPDU-based BF counter */ |
| - |
| - u32 tx_rwp_fail_cnt; |
| - u32 tx_rwp_need_cnt; |
| - |
| - /* rx stats */ |
| - u32 rx_fifo_full_cnt; |
| - u32 channel_idle_cnt; |
| - u32 rx_vector_mismatch_cnt; |
| - u32 rx_delimiter_fail_cnt; |
| - u32 rx_len_mismatch_cnt; |
| - u32 rx_mpdu_cnt; |
| - u32 rx_ampdu_cnt; |
| - u32 rx_ampdu_bytes_cnt; |
| - u32 rx_ampdu_valid_subframe_cnt; |
| - u32 rx_ampdu_valid_subframe_bytes_cnt; |
| - u32 rx_pfdrop_cnt; |
| - u32 rx_vec_queue_overflow_drop_cnt; |
| - u32 rx_ba_cnt; |
| - |
| - u32 tx_amsdu[8]; |
| - u32 tx_amsdu_cnt; |
| }; |
| |
| /* crash-dump */ |
| @@ -222,7 +168,7 @@ struct mt7996_phy { |
| u32 rx_ampdu_ts; |
| u32 ampdu_ref; |
| |
| - struct mib_stats mib; |
| + struct mt76_mib_stats mib; |
| struct mt76_channel_state state_ts; |
| }; |
| |
| @@ -272,9 +218,7 @@ struct mt7996_dev { |
| #endif |
| |
| struct list_head sta_rc_list; |
| - struct list_head sta_poll_list; |
| struct list_head twt_list; |
| - spinlock_t sta_poll_lock; |
| |
| u32 hw_pattern; |
| |
| @@ -405,6 +349,7 @@ int mt7996_dma_init(struct mt7996_dev *dev); |
| void mt7996_dma_reset(struct mt7996_dev *dev, bool force); |
| void mt7996_dma_prefetch(struct mt7996_dev *dev); |
| void mt7996_dma_cleanup(struct mt7996_dev *dev); |
| +void mt7996_dma_start(struct mt7996_dev *dev, bool reset); |
| void mt7996_init_txpower(struct mt7996_dev *dev, |
| struct ieee80211_supported_band *sband); |
| int mt7996_txbf_init(struct mt7996_dev *dev); |
| @@ -456,6 +401,7 @@ int mt7996_mcu_set_radar_th(struct mt7996_dev *dev, int index, |
| const struct mt7996_dfs_pattern *pattern); |
| int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable); |
| int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val); |
| +int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif); |
| int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch); |
| int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index, |
| u8 rx_sel, u8 val); |
| @@ -519,7 +465,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi, |
| struct sk_buff *skb, struct mt76_wcid *wcid, |
| struct ieee80211_key_conf *key, int pid, |
| enum mt76_txq_id qid, u32 changed); |
| -void mt7996_mac_set_timing(struct mt7996_phy *phy); |
| +void mt7996_mac_set_coverage_class(struct mt7996_phy *phy); |
| int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
| struct ieee80211_sta *sta); |
| void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
| diff --git a/mt7996/pci.c b/mt7996/pci.c |
| index 64aee3fb..c5301050 100644 |
| --- a/mt7996/pci.c |
| +++ b/mt7996/pci.c |
| @@ -219,4 +219,5 @@ MODULE_DEVICE_TABLE(pci, mt7996_pci_device_table); |
| MODULE_DEVICE_TABLE(pci, mt7996_hif_device_table); |
| MODULE_FIRMWARE(MT7996_FIRMWARE_WA); |
| MODULE_FIRMWARE(MT7996_FIRMWARE_WM); |
| +MODULE_FIRMWARE(MT7996_FIRMWARE_DSP); |
| MODULE_FIRMWARE(MT7996_ROM_PATCH); |
| diff --git a/mt7996/regs.h b/mt7996/regs.h |
| index d1d3d154..97beab92 100644 |
| --- a/mt7996/regs.h |
| +++ b/mt7996/regs.h |
| @@ -557,22 +557,29 @@ enum base_rev { |
| |
| #define MT_PCIE1_MAC_INT_ENABLE MT_PCIE1_MAC(0x188) |
| |
| +/* PHYRX CSD */ |
| +#define MT_WF_PHYRX_CSD_BASE 0x83000000 |
| +#define MT_WF_PHYRX_CSD(_band, _wf, ofs) (MT_WF_PHYRX_CSD_BASE + \ |
| + ((_band) << 20) + \ |
| + ((_wf) << 16) + (ofs)) |
| +#define MT_WF_PHYRX_CSD_IRPI(_band, _wf) MT_WF_PHYRX_CSD(_band, _wf, 0x1000) |
| + |
| /* PHYRX CTRL */ |
| #define MT_WF_PHYRX_BAND_BASE 0x83080000 |
| #define MT_WF_PHYRX_BAND(_band, ofs) (MT_WF_PHYRX_BAND_BASE + \ |
| ((_band) << 20) + (ofs)) |
| |
| +#define MT_WF_PHYRX_BAND_GID_TAB_VLD0(_band) MT_WF_PHYRX_BAND(_band, 0x1054) |
| +#define MT_WF_PHYRX_BAND_GID_TAB_VLD1(_band) MT_WF_PHYRX_BAND(_band, 0x1058) |
| +#define MT_WF_PHYRX_BAND_GID_TAB_POS0(_band) MT_WF_PHYRX_BAND(_band, 0x105c) |
| +#define MT_WF_PHYRX_BAND_GID_TAB_POS1(_band) MT_WF_PHYRX_BAND(_band, 0x1060) |
| +#define MT_WF_PHYRX_BAND_GID_TAB_POS2(_band) MT_WF_PHYRX_BAND(_band, 0x1064) |
| +#define MT_WF_PHYRX_BAND_GID_TAB_POS3(_band) MT_WF_PHYRX_BAND(_band, 0x1068) |
| + |
| #define MT_WF_PHYRX_BAND_RX_CTRL1(_band) MT_WF_PHYRX_BAND(_band, 0x2004) |
| #define MT_WF_PHYRX_BAND_RX_CTRL1_IPI_EN GENMASK(2, 0) |
| #define MT_WF_PHYRX_BAND_RX_CTRL1_STSCNT_EN GENMASK(11, 9) |
| |
| -/* PHYRX CSD */ |
| -#define MT_WF_PHYRX_CSD_BASE 0x83000000 |
| -#define MT_WF_PHYRX_CSD(_band, _wf, ofs) (MT_WF_PHYRX_CSD_BASE + \ |
| - ((_band) << 20) + \ |
| - ((_wf) << 16) + (ofs)) |
| -#define MT_WF_PHYRX_CSD_IRPI(_band, _wf) MT_WF_PHYRX_CSD(_band, _wf, 0x1000) |
| - |
| /* PHYRX CSD BAND */ |
| #define MT_WF_PHYRX_CSD_BAND_RXTD12(_band) MT_WF_PHYRX_BAND(_band, 0x8230) |
| #define MT_WF_PHYRX_CSD_BAND_RXTD12_IRPI_SW_CLR_ONLY BIT(18) |
| diff --git a/tx.c b/tx.c |
| index 72b3ec71..6cc26cc6 100644 |
| --- a/tx.c |
| +++ b/tx.c |
| @@ -121,6 +121,7 @@ int |
| mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, |
| struct sk_buff *skb) |
| { |
| + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| struct mt76_tx_cb *cb = mt76_tx_skb_cb(skb); |
| int pid; |
| @@ -134,8 +135,14 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, |
| return MT_PACKET_ID_NO_ACK; |
| |
| if (!(info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS | |
| - IEEE80211_TX_CTL_RATE_CTRL_PROBE))) |
| + IEEE80211_TX_CTL_RATE_CTRL_PROBE))) { |
| + if (mtk_wed_device_active(&dev->mmio.wed) && |
| + ((info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) || |
| + ieee80211_is_data(hdr->frame_control))) |
| + return MT_PACKET_ID_WED; |
| + |
| return MT_PACKET_ID_NO_SKB; |
| + } |
| |
| spin_lock_bh(&dev->status_lock); |
| |
| @@ -263,8 +270,15 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff * |
| #endif |
| |
| if (cb->pktid < MT_PACKET_ID_FIRST) { |
| + struct ieee80211_rate_status rs = {}; |
| + |
| hw = mt76_tx_status_get_hw(dev, skb); |
| status.sta = wcid_to_sta(wcid); |
| + if (status.sta && (wcid->rate.flags || wcid->rate.legacy)) { |
| + rs.rate_idx = wcid->rate; |
| + status.rates = &rs; |
| + status.n_rates = 1; |
| + } |
| spin_lock_bh(&dev->rx_lock); |
| ieee80211_tx_status_ext(hw, &status); |
| spin_unlock_bh(&dev->rx_lock); |
| -- |
| 2.18.0 |
| |