10e3d6777SRyder Lee /* SPDX-License-Identifier: ISC */ 217f1de56SFelix Fietkau /* 317f1de56SFelix Fietkau * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 417f1de56SFelix Fietkau */ 517f1de56SFelix Fietkau 617f1de56SFelix Fietkau #ifndef __MT76_H 717f1de56SFelix Fietkau #define __MT76_H 817f1de56SFelix Fietkau 917f1de56SFelix Fietkau #include <linux/kernel.h> 1017f1de56SFelix Fietkau #include <linux/io.h> 1117f1de56SFelix Fietkau #include <linux/spinlock.h> 1217f1de56SFelix Fietkau #include <linux/skbuff.h> 1317f1de56SFelix Fietkau #include <linux/leds.h> 14b40b15e1SLorenzo Bianconi #include <linux/usb.h> 15ef13edc0SFelix Fietkau #include <linux/average.h> 16f68d6762SFelix Fietkau #include <linux/soc/mediatek/mtk_wed.h> 1717f1de56SFelix Fietkau #include <net/mac80211.h> 18a9ca9f9cSYunsheng Lin #include <net/page_pool/helpers.h> 1917f1de56SFelix Fietkau #include "util.h" 20f0efa862SFelix Fietkau #include "testmode.h" 2117f1de56SFelix Fietkau 2217f1de56SFelix Fietkau #define MT_MCU_RING_SIZE 32 2317f1de56SFelix Fietkau #define MT_RX_BUF_SIZE 2048 24123bc712SDeren Wu #define MT_SKB_HEAD_LEN 256 2517f1de56SFelix Fietkau 26e1378e52SFelix Fietkau #define MT_MAX_NON_AQL_PKT 16 27e1378e52SFelix Fietkau #define MT_TXQ_FREE_THR 32 28e1378e52SFelix Fietkau 29d089692bSLorenzo Bianconi #define MT76_TOKEN_FREE_THR 64 30d089692bSLorenzo Bianconi 31f68d6762SFelix Fietkau #define MT_QFLAG_WED_RING GENMASK(1, 0) 32f68d6762SFelix Fietkau #define MT_QFLAG_WED_TYPE GENMASK(3, 2) 33f68d6762SFelix Fietkau #define MT_QFLAG_WED BIT(4) 34f68d6762SFelix Fietkau 35f68d6762SFelix Fietkau #define __MT_WED_Q(_type, _n) (MT_QFLAG_WED | \ 36f68d6762SFelix Fietkau FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \ 37f68d6762SFelix Fietkau FIELD_PREP(MT_QFLAG_WED_RING, _n)) 38f68d6762SFelix Fietkau #define MT_WED_Q_TX(_n) __MT_WED_Q(MT76_WED_Q_TX, _n) 39cd372b8cSLorenzo Bianconi #define MT_WED_Q_RX(_n) __MT_WED_Q(MT76_WED_Q_RX, _n) 40f68d6762SFelix Fietkau #define MT_WED_Q_TXFREE __MT_WED_Q(MT76_WED_Q_TXFREE, 0) 41f68d6762SFelix Fietkau 4217f1de56SFelix Fietkau struct mt76_dev; 4396747a51SFelix Fietkau struct mt76_phy; 44469d4818SLorenzo Bianconi struct mt76_wcid; 453ad08509SLorenzo Bianconi struct mt76s_intr; 4617f1de56SFelix Fietkau 476da5a291SStanislaw Gruszka struct mt76_reg_pair { 486da5a291SStanislaw Gruszka u32 reg; 496da5a291SStanislaw Gruszka u32 value; 506da5a291SStanislaw Gruszka }; 516da5a291SStanislaw Gruszka 52c50479faSStanislaw Gruszka enum mt76_bus_type { 53c50479faSStanislaw Gruszka MT76_BUS_MMIO, 54c50479faSStanislaw Gruszka MT76_BUS_USB, 55d39b52e3SSean Wang MT76_BUS_SDIO, 56c50479faSStanislaw Gruszka }; 57c50479faSStanislaw Gruszka 58f68d6762SFelix Fietkau enum mt76_wed_type { 59f68d6762SFelix Fietkau MT76_WED_Q_TX, 60f68d6762SFelix Fietkau MT76_WED_Q_TXFREE, 61cd372b8cSLorenzo Bianconi MT76_WED_Q_RX, 62f68d6762SFelix Fietkau }; 63f68d6762SFelix Fietkau 6417f1de56SFelix Fietkau struct mt76_bus_ops { 6517f1de56SFelix Fietkau u32 (*rr)(struct mt76_dev *dev, u32 offset); 6617f1de56SFelix Fietkau void (*wr)(struct mt76_dev *dev, u32 offset, u32 val); 6717f1de56SFelix Fietkau u32 (*rmw)(struct mt76_dev *dev, u32 offset, u32 mask, u32 val); 6835e4ebeaSLorenzo Bianconi void (*write_copy)(struct mt76_dev *dev, u32 offset, const void *data, 6935e4ebeaSLorenzo Bianconi int len); 7035e4ebeaSLorenzo Bianconi void (*read_copy)(struct mt76_dev *dev, u32 offset, void *data, 7117f1de56SFelix Fietkau int len); 726da5a291SStanislaw Gruszka int (*wr_rp)(struct mt76_dev *dev, u32 base, 736da5a291SStanislaw Gruszka const struct mt76_reg_pair *rp, int len); 746da5a291SStanislaw Gruszka int (*rd_rp)(struct mt76_dev *dev, u32 base, 756da5a291SStanislaw Gruszka struct mt76_reg_pair *rp, int len); 76c50479faSStanislaw Gruszka enum mt76_bus_type type; 7717f1de56SFelix Fietkau }; 7817f1de56SFelix Fietkau 7961c51a74SLorenzo Bianconi #define mt76_is_usb(dev) ((dev)->bus->type == MT76_BUS_USB) 8061c51a74SLorenzo Bianconi #define mt76_is_mmio(dev) ((dev)->bus->type == MT76_BUS_MMIO) 81d39b52e3SSean Wang #define mt76_is_sdio(dev) ((dev)->bus->type == MT76_BUS_SDIO) 82c50479faSStanislaw Gruszka 8317f1de56SFelix Fietkau enum mt76_txq_id { 8417f1de56SFelix Fietkau MT_TXQ_VO = IEEE80211_AC_VO, 8517f1de56SFelix Fietkau MT_TXQ_VI = IEEE80211_AC_VI, 8617f1de56SFelix Fietkau MT_TXQ_BE = IEEE80211_AC_BE, 8717f1de56SFelix Fietkau MT_TXQ_BK = IEEE80211_AC_BK, 8817f1de56SFelix Fietkau MT_TXQ_PSD, 8917f1de56SFelix Fietkau MT_TXQ_BEACON, 9017f1de56SFelix Fietkau MT_TXQ_CAB, 9117f1de56SFelix Fietkau __MT_TXQ_MAX 9217f1de56SFelix Fietkau }; 9317f1de56SFelix Fietkau 94b1cb42adSLorenzo Bianconi enum mt76_mcuq_id { 95e637763bSLorenzo Bianconi MT_MCUQ_WM, 96e637763bSLorenzo Bianconi MT_MCUQ_WA, 97e637763bSLorenzo Bianconi MT_MCUQ_FWDL, 98b1cb42adSLorenzo Bianconi __MT_MCUQ_MAX 99b1cb42adSLorenzo Bianconi }; 100b1cb42adSLorenzo Bianconi 10117f1de56SFelix Fietkau enum mt76_rxq_id { 10217f1de56SFelix Fietkau MT_RXQ_MAIN, 10317f1de56SFelix Fietkau MT_RXQ_MCU, 104d3377b78SRyder Lee MT_RXQ_MCU_WA, 105fc8f841bSLorenzo Bianconi MT_RXQ_BAND1, 106fc8f841bSLorenzo Bianconi MT_RXQ_BAND1_WA, 107f9b627f1SBo Jiao MT_RXQ_MAIN_WA, 108fc8f841bSLorenzo Bianconi MT_RXQ_BAND2, 109fc8f841bSLorenzo Bianconi MT_RXQ_BAND2_WA, 11017f1de56SFelix Fietkau __MT_RXQ_MAX 11117f1de56SFelix Fietkau }; 11217f1de56SFelix Fietkau 113dc44c45cSLorenzo Bianconi enum mt76_band_id { 114dc44c45cSLorenzo Bianconi MT_BAND0, 115dc44c45cSLorenzo Bianconi MT_BAND1, 116dc44c45cSLorenzo Bianconi MT_BAND2, 117dc44c45cSLorenzo Bianconi __MT_MAX_BAND 118dc44c45cSLorenzo Bianconi }; 119dc44c45cSLorenzo Bianconi 120c368362cSRyder Lee enum mt76_cipher_type { 121c368362cSRyder Lee MT_CIPHER_NONE, 122c368362cSRyder Lee MT_CIPHER_WEP40, 123c368362cSRyder Lee MT_CIPHER_TKIP, 124c368362cSRyder Lee MT_CIPHER_TKIP_NO_MIC, 125c368362cSRyder Lee MT_CIPHER_AES_CCMP, 126c368362cSRyder Lee MT_CIPHER_WEP104, 127c368362cSRyder Lee MT_CIPHER_BIP_CMAC_128, 128c368362cSRyder Lee MT_CIPHER_WEP128, 129c368362cSRyder Lee MT_CIPHER_WAPI, 130c368362cSRyder Lee MT_CIPHER_CCMP_CCX, 131c368362cSRyder Lee MT_CIPHER_CCMP_256, 132c368362cSRyder Lee MT_CIPHER_GCMP, 133c368362cSRyder Lee MT_CIPHER_GCMP_256, 134c368362cSRyder Lee }; 135c368362cSRyder Lee 1363f306448SFelix Fietkau enum mt76_dfs_state { 1373f306448SFelix Fietkau MT_DFS_STATE_UNKNOWN, 1383f306448SFelix Fietkau MT_DFS_STATE_DISABLED, 1393f306448SFelix Fietkau MT_DFS_STATE_CAC, 1403f306448SFelix Fietkau MT_DFS_STATE_ACTIVE, 1413f306448SFelix Fietkau }; 1423f306448SFelix Fietkau 14317f1de56SFelix Fietkau struct mt76_queue_buf { 14417f1de56SFelix Fietkau dma_addr_t addr; 14527d5c528SFelix Fietkau u16 len; 14627d5c528SFelix Fietkau bool skip_unmap; 14717f1de56SFelix Fietkau }; 14817f1de56SFelix Fietkau 149b5903c47SLorenzo Bianconi struct mt76_tx_info { 150b5903c47SLorenzo Bianconi struct mt76_queue_buf buf[32]; 151cfaae9e6SLorenzo Bianconi struct sk_buff *skb; 152b5903c47SLorenzo Bianconi int nbuf; 153b5903c47SLorenzo Bianconi u32 info; 154b5903c47SLorenzo Bianconi }; 155b5903c47SLorenzo Bianconi 15617f1de56SFelix Fietkau struct mt76_queue_entry { 15717f1de56SFelix Fietkau union { 15817f1de56SFelix Fietkau void *buf; 15917f1de56SFelix Fietkau struct sk_buff *skb; 16017f1de56SFelix Fietkau }; 161b40b15e1SLorenzo Bianconi union { 16217f1de56SFelix Fietkau struct mt76_txwi_cache *txwi; 163d7d4ea9aSStanislaw Gruszka struct urb *urb; 164d39b52e3SSean Wang int buf_sz; 165b40b15e1SLorenzo Bianconi }; 16675d4bf1fSFelix Fietkau u32 dma_addr[2]; 16775d4bf1fSFelix Fietkau u16 dma_len[2]; 168e1378e52SFelix Fietkau u16 wcid; 1697bd0650bSLorenzo Bianconi bool skip_buf0:1; 17027d5c528SFelix Fietkau bool skip_buf1:1; 1717bd0650bSLorenzo Bianconi bool done:1; 17217f1de56SFelix Fietkau }; 17317f1de56SFelix Fietkau 17417f1de56SFelix Fietkau struct mt76_queue_regs { 17517f1de56SFelix Fietkau u32 desc_base; 17617f1de56SFelix Fietkau u32 ring_size; 17717f1de56SFelix Fietkau u32 cpu_idx; 17817f1de56SFelix Fietkau u32 dma_idx; 17917f1de56SFelix Fietkau } __packed __aligned(4); 18017f1de56SFelix Fietkau 18117f1de56SFelix Fietkau struct mt76_queue { 18217f1de56SFelix Fietkau struct mt76_queue_regs __iomem *regs; 18317f1de56SFelix Fietkau 18417f1de56SFelix Fietkau spinlock_t lock; 1859716ef04SFelix Fietkau spinlock_t cleanup_lock; 18617f1de56SFelix Fietkau struct mt76_queue_entry *entry; 18717f1de56SFelix Fietkau struct mt76_desc *desc; 18817f1de56SFelix Fietkau 189b40b15e1SLorenzo Bianconi u16 first; 19017f1de56SFelix Fietkau u16 head; 19117f1de56SFelix Fietkau u16 tail; 19217f1de56SFelix Fietkau int ndesc; 19317f1de56SFelix Fietkau int queued; 19417f1de56SFelix Fietkau int buf_size; 195cd44bc40SLorenzo Bianconi bool stopped; 19690d494c9SFelix Fietkau bool blocked; 19717f1de56SFelix Fietkau 19817f1de56SFelix Fietkau u8 buf_offset; 19917f1de56SFelix Fietkau u8 hw_idx; 200f68d6762SFelix Fietkau u8 flags; 201f68d6762SFelix Fietkau 202f68d6762SFelix Fietkau u32 wed_regs; 20317f1de56SFelix Fietkau 20417f1de56SFelix Fietkau dma_addr_t desc_dma; 20517f1de56SFelix Fietkau struct sk_buff *rx_head; 2062f5c3c77SLorenzo Bianconi struct page_pool *page_pool; 20717f1de56SFelix Fietkau }; 20817f1de56SFelix Fietkau 209db0f04f3SLorenzo Bianconi struct mt76_mcu_ops { 210bb31a80eSLorenzo Bianconi u32 headroom; 211bb31a80eSLorenzo Bianconi u32 tailroom; 212bb31a80eSLorenzo Bianconi 213a74d6336SStanislaw Gruszka int (*mcu_send_msg)(struct mt76_dev *dev, int cmd, const void *data, 214a74d6336SStanislaw Gruszka int len, bool wait_resp); 215f4d45fe2SLorenzo Bianconi int (*mcu_skb_send_msg)(struct mt76_dev *dev, struct sk_buff *skb, 216e452c6ebSFelix Fietkau int cmd, int *seq); 217f320d812SFelix Fietkau int (*mcu_parse_response)(struct mt76_dev *dev, int cmd, 218f320d812SFelix Fietkau struct sk_buff *skb, int seq); 219d39b52e3SSean Wang u32 (*mcu_rr)(struct mt76_dev *dev, u32 offset); 220d39b52e3SSean Wang void (*mcu_wr)(struct mt76_dev *dev, u32 offset, u32 val); 2216da5a291SStanislaw Gruszka int (*mcu_wr_rp)(struct mt76_dev *dev, u32 base, 2226da5a291SStanislaw Gruszka const struct mt76_reg_pair *rp, int len); 2236da5a291SStanislaw Gruszka int (*mcu_rd_rp)(struct mt76_dev *dev, u32 base, 2246da5a291SStanislaw Gruszka struct mt76_reg_pair *rp, int len); 22500496042SFelix Fietkau int (*mcu_restart)(struct mt76_dev *dev); 226db0f04f3SLorenzo Bianconi }; 227db0f04f3SLorenzo Bianconi 22817f1de56SFelix Fietkau struct mt76_queue_ops { 229cb8ed33dSLorenzo Bianconi int (*init)(struct mt76_dev *dev, 230cb8ed33dSLorenzo Bianconi int (*poll)(struct napi_struct *napi, int budget)); 23117f1de56SFelix Fietkau 232b1bfbe70SLorenzo Bianconi int (*alloc)(struct mt76_dev *dev, struct mt76_queue *q, 233b1bfbe70SLorenzo Bianconi int idx, int n_desc, int bufsize, 234b1bfbe70SLorenzo Bianconi u32 ring_base); 23517f1de56SFelix Fietkau 23689870594SLorenzo Bianconi int (*tx_queue_skb)(struct mt76_dev *dev, struct mt76_queue *q, 237d08295f5SFelix Fietkau enum mt76_txq_id qid, struct sk_buff *skb, 238d08295f5SFelix Fietkau struct mt76_wcid *wcid, struct ieee80211_sta *sta); 239469d4818SLorenzo Bianconi 240d95093a1SLorenzo Bianconi int (*tx_queue_skb_raw)(struct mt76_dev *dev, struct mt76_queue *q, 2415ed31128SLorenzo Bianconi struct sk_buff *skb, u32 tx_info); 2425ed31128SLorenzo Bianconi 24317f1de56SFelix Fietkau void *(*dequeue)(struct mt76_dev *dev, struct mt76_queue *q, bool flush, 24417f1de56SFelix Fietkau int *len, u32 *info, bool *more); 24517f1de56SFelix Fietkau 24617f1de56SFelix Fietkau void (*rx_reset)(struct mt76_dev *dev, enum mt76_rxq_id qid); 24717f1de56SFelix Fietkau 248e5655492SLorenzo Bianconi void (*tx_cleanup)(struct mt76_dev *dev, struct mt76_queue *q, 24917f1de56SFelix Fietkau bool flush); 25017f1de56SFelix Fietkau 251c001df97SLorenzo Bianconi void (*rx_cleanup)(struct mt76_dev *dev, struct mt76_queue *q); 252c001df97SLorenzo Bianconi 25317f1de56SFelix Fietkau void (*kick)(struct mt76_dev *dev, struct mt76_queue *q); 2543990465dSLorenzo Bianconi 2553990465dSLorenzo Bianconi void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q); 25617f1de56SFelix Fietkau }; 25717f1de56SFelix Fietkau 258dc877523SRyder Lee enum mt76_phy_type { 259dc877523SRyder Lee MT_PHY_TYPE_CCK, 260dc877523SRyder Lee MT_PHY_TYPE_OFDM, 261dc877523SRyder Lee MT_PHY_TYPE_HT, 262dc877523SRyder Lee MT_PHY_TYPE_HT_GF, 263dc877523SRyder Lee MT_PHY_TYPE_VHT, 264dc877523SRyder Lee MT_PHY_TYPE_HE_SU = 8, 265dc877523SRyder Lee MT_PHY_TYPE_HE_EXT_SU, 266dc877523SRyder Lee MT_PHY_TYPE_HE_TB, 267dc877523SRyder Lee MT_PHY_TYPE_HE_MU, 268c2eccffdSShayne Chen MT_PHY_TYPE_EHT_SU = 13, 269c2eccffdSShayne Chen MT_PHY_TYPE_EHT_TRIG, 270c2eccffdSShayne Chen MT_PHY_TYPE_EHT_MU, 271c2eccffdSShayne Chen __MT_PHY_TYPE_MAX, 272dc877523SRyder Lee }; 273dc877523SRyder Lee 274dc877523SRyder Lee struct mt76_sta_stats { 275c2eccffdSShayne Chen u64 tx_mode[__MT_PHY_TYPE_MAX]; 276731425f3SShayne Chen u64 tx_bw[5]; /* 20, 40, 80, 160, 320 */ 277dc877523SRyder Lee u64 tx_nss[4]; /* 1, 2, 3, 4 */ 278dc877523SRyder Lee u64 tx_mcs[16]; /* mcs idx */ 27943eaa368SRyder Lee u64 tx_bytes; 280c6cde7b7SSujuan Chen /* WED TX */ 281161a7528SPeter Chiu u32 tx_packets; /* unit: MSDU */ 28243eaa368SRyder Lee u32 tx_retries; 28343eaa368SRyder Lee u32 tx_failed; 284c6cde7b7SSujuan Chen /* WED RX */ 285c6cde7b7SSujuan Chen u64 rx_bytes; 286c6cde7b7SSujuan Chen u32 rx_packets; 287c6cde7b7SSujuan Chen u32 rx_errors; 288c6cde7b7SSujuan Chen u32 rx_drops; 289dc877523SRyder Lee }; 290dc877523SRyder Lee 291d71ef286SFelix Fietkau enum mt76_wcid_flags { 292d71ef286SFelix Fietkau MT_WCID_FLAG_CHECK_PS, 293d71ef286SFelix Fietkau MT_WCID_FLAG_PS, 294e151d71eSFelix Fietkau MT_WCID_FLAG_4ADDR, 29590e3abf0SFelix Fietkau MT_WCID_FLAG_HDR_TRANS, 296d71ef286SFelix Fietkau }; 297d71ef286SFelix Fietkau 2986b733f7cSShayne Chen #define MT76_N_WCIDS 1088 29936404c06SStanislaw Gruszka 300e394b575SFelix Fietkau /* stored in ieee80211_tx_info::hw_queue */ 301a062f001SLorenzo Bianconi #define MT_TX_HW_QUEUE_PHY GENMASK(3, 2) 302e394b575SFelix Fietkau 303ef13edc0SFelix Fietkau DECLARE_EWMA(signal, 10, 8); 304ef13edc0SFelix Fietkau 305db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_RATE GENMASK(15, 0) 306db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_NSS GENMASK(17, 16) 307db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_TXPWR_ADJ GENMASK(25, 18) 308db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_SET BIT(31) 309db9f11d3SFelix Fietkau 31017f1de56SFelix Fietkau struct mt76_wcid { 311aee5b8cfSFelix Fietkau struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS]; 312aee5b8cfSFelix Fietkau 313e1378e52SFelix Fietkau atomic_t non_aql_packets; 314d71ef286SFelix Fietkau unsigned long flags; 315d71ef286SFelix Fietkau 316ef13edc0SFelix Fietkau struct ewma_signal rssi; 317ef13edc0SFelix Fietkau int inactive_count; 318ef13edc0SFelix Fietkau 3199908d98aSRyder Lee struct rate_info rate; 320ef591d74SLorenzo Bianconi unsigned long ampdu_state; 3219908d98aSRyder Lee 32249e649c3SRyder Lee u16 idx; 32317f1de56SFelix Fietkau u8 hw_key_idx; 324730d6d0dSFelix Fietkau u8 hw_key_idx2; 32517f1de56SFelix Fietkau 3269c68a57bSFelix Fietkau u8 sta:1; 327b443e55fSRyder Lee u8 amsdu:1; 328a1a99d7bSLorenzo Bianconi u8 phy_idx:2; 3299c68a57bSFelix Fietkau 33030ce7f44SFelix Fietkau u8 rx_check_pn; 331a1b0bbd4SXing Song u8 rx_key_pn[IEEE80211_NUM_TIDS + 1][6]; 33201cfc1b4SLorenzo Bianconi u16 cipher; 33330ce7f44SFelix Fietkau 334db9f11d3SFelix Fietkau u32 tx_info; 33523405236SFelix Fietkau bool sw_iv; 33688046b2cSFelix Fietkau 3370335c034SFelix Fietkau struct list_head tx_list; 3380335c034SFelix Fietkau struct sk_buff_head tx_pending; 3390335c034SFelix Fietkau 340bd1e3e7bSLorenzo Bianconi struct list_head list; 341bd1e3e7bSLorenzo Bianconi struct idr pktid; 342dc877523SRyder Lee 343dc877523SRyder Lee struct mt76_sta_stats stats; 344b73e1d92SLorenzo Bianconi 345b73e1d92SLorenzo Bianconi struct list_head poll_list; 34617f1de56SFelix Fietkau }; 34717f1de56SFelix Fietkau 34817f1de56SFelix Fietkau struct mt76_txq { 34951fb1278SFelix Fietkau u16 wcid; 35017f1de56SFelix Fietkau 35117f1de56SFelix Fietkau u16 agg_ssn; 35217f1de56SFelix Fietkau bool send_bar; 35317f1de56SFelix Fietkau bool aggr; 35417f1de56SFelix Fietkau }; 35517f1de56SFelix Fietkau 35617f1de56SFelix Fietkau struct mt76_txwi_cache { 35717f1de56SFelix Fietkau struct list_head list; 358f3950a41SLorenzo Bianconi dma_addr_t dma_addr; 3596ca66722SLorenzo Bianconi 3602666beceSSujuan Chen union { 3616ca66722SLorenzo Bianconi struct sk_buff *skb; 3622666beceSSujuan Chen void *ptr; 3632666beceSSujuan Chen }; 36417f1de56SFelix Fietkau }; 36517f1de56SFelix Fietkau 366aee5b8cfSFelix Fietkau struct mt76_rx_tid { 367aee5b8cfSFelix Fietkau struct rcu_head rcu_head; 368aee5b8cfSFelix Fietkau 369aee5b8cfSFelix Fietkau struct mt76_dev *dev; 370aee5b8cfSFelix Fietkau 371aee5b8cfSFelix Fietkau spinlock_t lock; 372aee5b8cfSFelix Fietkau struct delayed_work reorder_work; 373aee5b8cfSFelix Fietkau 374aee5b8cfSFelix Fietkau u16 head; 3757c4f744dSRyder Lee u16 size; 3767c4f744dSRyder Lee u16 nframes; 377aee5b8cfSFelix Fietkau 378e7ec563eSMarkus Theil u8 num; 379e7ec563eSMarkus Theil 380aee5b8cfSFelix Fietkau u8 started:1, stopped:1, timer_pending:1; 381aee5b8cfSFelix Fietkau 382aee5b8cfSFelix Fietkau struct sk_buff *reorder_buf[]; 383aee5b8cfSFelix Fietkau }; 384aee5b8cfSFelix Fietkau 38588046b2cSFelix Fietkau #define MT_TX_CB_DMA_DONE BIT(0) 38688046b2cSFelix Fietkau #define MT_TX_CB_TXS_DONE BIT(1) 38788046b2cSFelix Fietkau #define MT_TX_CB_TXS_FAILED BIT(2) 38888046b2cSFelix Fietkau 3898548c6ebSFelix Fietkau #define MT_PACKET_ID_MASK GENMASK(6, 0) 390013b2dffSFelix Fietkau #define MT_PACKET_ID_NO_ACK 0 391013b2dffSFelix Fietkau #define MT_PACKET_ID_NO_SKB 1 39243eaa368SRyder Lee #define MT_PACKET_ID_WED 2 39343eaa368SRyder Lee #define MT_PACKET_ID_FIRST 3 3948548c6ebSFelix Fietkau #define MT_PACKET_ID_HAS_RATE BIT(7) 395c4a784e3SLorenzo Bianconi /* This is timer for when to give up when waiting for TXS callback, 396c4a784e3SLorenzo Bianconi * with starting time being the time at which the DMA_DONE callback 397c4a784e3SLorenzo Bianconi * was seen (so, we know packet was processed then, it should not take 398c4a784e3SLorenzo Bianconi * long after that for firmware to send the TXS callback if it is going 399c4a784e3SLorenzo Bianconi * to do so.) 400c4a784e3SLorenzo Bianconi */ 401c4a784e3SLorenzo Bianconi #define MT_TX_STATUS_SKB_TIMEOUT (HZ / 4) 40288046b2cSFelix Fietkau 40388046b2cSFelix Fietkau struct mt76_tx_cb { 40488046b2cSFelix Fietkau unsigned long jiffies; 40549e649c3SRyder Lee u16 wcid; 40688046b2cSFelix Fietkau u8 pktid; 40788046b2cSFelix Fietkau u8 flags; 40888046b2cSFelix Fietkau }; 40988046b2cSFelix Fietkau 41017f1de56SFelix Fietkau enum { 41117f1de56SFelix Fietkau MT76_STATE_INITIALIZED, 41241130c32SLorenzo Bianconi MT76_STATE_REGISTERED, 41317f1de56SFelix Fietkau MT76_STATE_RUNNING, 41487e022deSStanislaw Gruszka MT76_STATE_MCU_RUNNING, 41517f1de56SFelix Fietkau MT76_SCANNING, 416fcdfc29eSLorenzo Bianconi MT76_HW_SCANNING, 41720305f98SLorenzo Bianconi MT76_HW_SCHED_SCANNING, 418fd6c2dfaSFelix Fietkau MT76_RESTART, 41917f1de56SFelix Fietkau MT76_RESET, 42061c4fa72SFelix Fietkau MT76_MCU_RESET, 421b40b15e1SLorenzo Bianconi MT76_REMOVED, 422b40b15e1SLorenzo Bianconi MT76_READING_STATS, 423eb99cc95SLorenzo Bianconi MT76_STATE_POWER_OFF, 424c6bf2010SLorenzo Bianconi MT76_STATE_SUSPEND, 4257307f296SLorenzo Bianconi MT76_STATE_ROC, 42608523a2aSLorenzo Bianconi MT76_STATE_PM, 42736b7fce1SLorenzo Bianconi MT76_STATE_WED_RESET, 42817f1de56SFelix Fietkau }; 42917f1de56SFelix Fietkau 43017f1de56SFelix Fietkau struct mt76_hw_cap { 43117f1de56SFelix Fietkau bool has_2ghz; 43217f1de56SFelix Fietkau bool has_5ghz; 433f7d2958cSLorenzo Bianconi bool has_6ghz; 43417f1de56SFelix Fietkau }; 43517f1de56SFelix Fietkau 4369ec0b821SFelix Fietkau #define MT_DRV_TXWI_NO_FREE BIT(0) 4379ec0b821SFelix Fietkau #define MT_DRV_TX_ALIGNED4_SKBS BIT(1) 4385ce09c1aSFelix Fietkau #define MT_DRV_SW_RX_AIRTIME BIT(2) 43994d4d076SLorenzo Bianconi #define MT_DRV_RX_DMA_HDR BIT(3) 440d3c82998SLorenzo Bianconi #define MT_DRV_HW_MGMT_TXQ BIT(4) 4415b0fb852SBen Greear #define MT_DRV_AMSDU_OFFLOAD BIT(5) 4426ca66722SLorenzo Bianconi 44317f1de56SFelix Fietkau struct mt76_driver_ops { 4449ec0b821SFelix Fietkau u32 drv_flags; 445ea565833SFelix Fietkau u32 survey_flags; 44617f1de56SFelix Fietkau u16 txwi_size; 447d089692bSLorenzo Bianconi u16 token_size; 44822b980baSFelix Fietkau u8 mcs_rates; 44917f1de56SFelix Fietkau 450c560b137SRyder Lee void (*update_survey)(struct mt76_phy *phy); 45117f1de56SFelix Fietkau 45217f1de56SFelix Fietkau int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr, 453cfaae9e6SLorenzo Bianconi enum mt76_txq_id qid, struct mt76_wcid *wcid, 454b5903c47SLorenzo Bianconi struct ieee80211_sta *sta, 455b5903c47SLorenzo Bianconi struct mt76_tx_info *tx_info); 45617f1de56SFelix Fietkau 457d80e52c7SFelix Fietkau void (*tx_complete_skb)(struct mt76_dev *dev, 458e226ba2eSLorenzo Bianconi struct mt76_queue_entry *e); 45917f1de56SFelix Fietkau 460b40b15e1SLorenzo Bianconi bool (*tx_status_data)(struct mt76_dev *dev, u8 *update); 461b40b15e1SLorenzo Bianconi 462fbe50d9aSFelix Fietkau bool (*rx_check)(struct mt76_dev *dev, void *data, int len); 463fbe50d9aSFelix Fietkau 46417f1de56SFelix Fietkau void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q, 465c3137942SSujuan Chen struct sk_buff *skb, u32 *info); 46617f1de56SFelix Fietkau 46717f1de56SFelix Fietkau void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q); 468d71ef286SFelix Fietkau 469d71ef286SFelix Fietkau void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta, 470d71ef286SFelix Fietkau bool ps); 471e28487eaSFelix Fietkau 472e28487eaSFelix Fietkau int (*sta_add)(struct mt76_dev *dev, struct ieee80211_vif *vif, 473e28487eaSFelix Fietkau struct ieee80211_sta *sta); 474e28487eaSFelix Fietkau 4759c193de5SFelix Fietkau void (*sta_assoc)(struct mt76_dev *dev, struct ieee80211_vif *vif, 4769c193de5SFelix Fietkau struct ieee80211_sta *sta); 4779c193de5SFelix Fietkau 478e28487eaSFelix Fietkau void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif, 479e28487eaSFelix Fietkau struct ieee80211_sta *sta); 48017f1de56SFelix Fietkau }; 48117f1de56SFelix Fietkau 48217f1de56SFelix Fietkau struct mt76_channel_state { 48317f1de56SFelix Fietkau u64 cc_active; 48417f1de56SFelix Fietkau u64 cc_busy; 4856bfa6e38SLorenzo Bianconi u64 cc_rx; 4865ce09c1aSFelix Fietkau u64 cc_bss_rx; 487ea565833SFelix Fietkau u64 cc_tx; 488e5051965SFelix Fietkau 489e5051965SFelix Fietkau s8 noise; 49017f1de56SFelix Fietkau }; 49117f1de56SFelix Fietkau 49217f1de56SFelix Fietkau struct mt76_sband { 49317f1de56SFelix Fietkau struct ieee80211_supported_band sband; 49417f1de56SFelix Fietkau struct mt76_channel_state *chan; 49517f1de56SFelix Fietkau }; 49617f1de56SFelix Fietkau 497b40b15e1SLorenzo Bianconi /* addr req mask */ 498b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_EEPROM BIT(31) 499b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_CFG BIT(30) 500b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_MASK (MT_VEND_TYPE_EEPROM | MT_VEND_TYPE_CFG) 501b40b15e1SLorenzo Bianconi 502b40b15e1SLorenzo Bianconi #define MT_VEND_ADDR(type, n) (MT_VEND_TYPE_##type | (n)) 503b40b15e1SLorenzo Bianconi enum mt_vendor_req { 504b40b15e1SLorenzo Bianconi MT_VEND_DEV_MODE = 0x1, 505b40b15e1SLorenzo Bianconi MT_VEND_WRITE = 0x2, 5061e816c65SLorenzo Bianconi MT_VEND_POWER_ON = 0x4, 507b40b15e1SLorenzo Bianconi MT_VEND_MULTI_WRITE = 0x6, 508b40b15e1SLorenzo Bianconi MT_VEND_MULTI_READ = 0x7, 509b40b15e1SLorenzo Bianconi MT_VEND_READ_EEPROM = 0x9, 510b40b15e1SLorenzo Bianconi MT_VEND_WRITE_FCE = 0x42, 511b40b15e1SLorenzo Bianconi MT_VEND_WRITE_CFG = 0x46, 512b40b15e1SLorenzo Bianconi MT_VEND_READ_CFG = 0x47, 5131e816c65SLorenzo Bianconi MT_VEND_READ_EXT = 0x63, 5141e816c65SLorenzo Bianconi MT_VEND_WRITE_EXT = 0x66, 515d0846f08SSean Wang MT_VEND_FEATURE_SET = 0x91, 516b40b15e1SLorenzo Bianconi }; 517b40b15e1SLorenzo Bianconi 518b40b15e1SLorenzo Bianconi enum mt76u_in_ep { 519b40b15e1SLorenzo Bianconi MT_EP_IN_PKT_RX, 520b40b15e1SLorenzo Bianconi MT_EP_IN_CMD_RESP, 521b40b15e1SLorenzo Bianconi __MT_EP_IN_MAX, 522b40b15e1SLorenzo Bianconi }; 523b40b15e1SLorenzo Bianconi 524b40b15e1SLorenzo Bianconi enum mt76u_out_ep { 525b40b15e1SLorenzo Bianconi MT_EP_OUT_INBAND_CMD, 526b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_BE, 52723cb16d2SLorenzo Bianconi MT_EP_OUT_AC_BK, 528b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_VI, 529b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_VO, 530b40b15e1SLorenzo Bianconi MT_EP_OUT_HCCA, 531b40b15e1SLorenzo Bianconi __MT_EP_OUT_MAX, 532b40b15e1SLorenzo Bianconi }; 533b40b15e1SLorenzo Bianconi 53409872957SLorenzo Bianconi struct mt76_mcu { 53509872957SLorenzo Bianconi struct mutex mutex; 53609872957SLorenzo Bianconi u32 msg_seq; 537e452c6ebSFelix Fietkau int timeout; 53809872957SLorenzo Bianconi 53909872957SLorenzo Bianconi struct sk_buff_head res_q; 54009872957SLorenzo Bianconi wait_queue_head_t wait; 54109872957SLorenzo Bianconi }; 54209872957SLorenzo Bianconi 54314663f0cSLorenzo Bianconi #define MT_TX_SG_MAX_SIZE 8 544972c5981SSean Wang #define MT_RX_SG_MAX_SIZE 4 545b40b15e1SLorenzo Bianconi #define MT_NUM_TX_ENTRIES 256 546b40b15e1SLorenzo Bianconi #define MT_NUM_RX_ENTRIES 128 547b40b15e1SLorenzo Bianconi #define MCU_RESP_URB_SIZE 1024 548b40b15e1SLorenzo Bianconi struct mt76_usb { 549b40b15e1SLorenzo Bianconi struct mutex usb_ctrl_mtx; 550a6bfb6d1SStanislaw Gruszka u8 *data; 551a6bfb6d1SStanislaw Gruszka u16 data_len; 552b40b15e1SLorenzo Bianconi 5539daf27e6SLorenzo Bianconi struct mt76_worker status_worker; 554be83a7e2SLorenzo Bianconi struct mt76_worker rx_worker; 5559daf27e6SLorenzo Bianconi 556284efb47SLorenzo Bianconi struct work_struct stat_work; 557b40b15e1SLorenzo Bianconi 558b40b15e1SLorenzo Bianconi u8 out_ep[__MT_EP_OUT_MAX]; 559b40b15e1SLorenzo Bianconi u8 in_ep[__MT_EP_IN_MAX]; 56063a7de5dSLorenzo Bianconi bool sg_en; 561b40b15e1SLorenzo Bianconi 562b40b15e1SLorenzo Bianconi struct mt76u_mcu { 563a18a494fSStanislaw Gruszka u8 *data; 564851ab66eSLorenzo Bianconi /* multiple reads */ 565851ab66eSLorenzo Bianconi struct mt76_reg_pair *rp; 566851ab66eSLorenzo Bianconi int rp_len; 567851ab66eSLorenzo Bianconi u32 base; 568b40b15e1SLorenzo Bianconi } mcu; 569b40b15e1SLorenzo Bianconi }; 570b40b15e1SLorenzo Bianconi 571bf08d585SSean Wang #define MT76S_XMIT_BUF_SZ 0x3fe00 572b1460bb4SDeren Wu #define MT76S_NUM_TX_ENTRIES 256 573b1460bb4SDeren Wu #define MT76S_NUM_RX_ENTRIES 512 574d39b52e3SSean Wang struct mt76_sdio { 575fefb584dSLorenzo Bianconi struct mt76_worker txrx_worker; 5766a618acbSLorenzo Bianconi struct mt76_worker status_worker; 5776a618acbSLorenzo Bianconi struct mt76_worker net_worker; 5786a618acbSLorenzo Bianconi 579d74fda4cSLorenzo Bianconi struct work_struct stat_work; 580974327a4SLorenzo Bianconi 581bf08d585SSean Wang u8 *xmit_buf; 582bf08d585SSean Wang u32 xmit_buf_sz; 5831522ff73SLorenzo Bianconi 584d39b52e3SSean Wang struct sdio_func *func; 585b4964908SSean Wang void *intr_data; 586dacf0acfSSean Wang u8 hw_ver; 587ca74b9b9SSean Wang wait_queue_head_t wait; 588d39b52e3SSean Wang 589d39b52e3SSean Wang struct { 590d39b52e3SSean Wang int pse_data_quota; 591d39b52e3SSean Wang int ple_data_quota; 592d39b52e3SSean Wang int pse_mcu_quota; 5938c94f0e6SSean Wang int pse_page_size; 594d39b52e3SSean Wang int deficit; 595d39b52e3SSean Wang } sched; 5963ad08509SLorenzo Bianconi 5973ad08509SLorenzo Bianconi int (*parse_irq)(struct mt76_dev *dev, struct mt76s_intr *intr); 598d39b52e3SSean Wang }; 599d39b52e3SSean Wang 600f7bbb80fSLorenzo Bianconi struct mt76_mmio { 60127db1ad1SLorenzo Bianconi void __iomem *regs; 602957068c2SLorenzo Bianconi spinlock_t irq_lock; 603957068c2SLorenzo Bianconi u32 irqmask; 604f68d6762SFelix Fietkau 605f68d6762SFelix Fietkau struct mtk_wed_device wed; 60636b7fce1SLorenzo Bianconi struct completion wed_reset; 60736b7fce1SLorenzo Bianconi struct completion wed_reset_complete; 608f7bbb80fSLorenzo Bianconi }; 609f7bbb80fSLorenzo Bianconi 6105ce09c1aSFelix Fietkau struct mt76_rx_status { 6115ce09c1aSFelix Fietkau union { 6125ce09c1aSFelix Fietkau struct mt76_wcid *wcid; 61349e649c3SRyder Lee u16 wcid_idx; 6145ce09c1aSFelix Fietkau }; 6155ce09c1aSFelix Fietkau 6160fda6d7bSRyder Lee u32 reorder_time; 6175ce09c1aSFelix Fietkau 6185ce09c1aSFelix Fietkau u32 ampdu_ref; 6190fda6d7bSRyder Lee u32 timestamp; 6205ce09c1aSFelix Fietkau 6215ce09c1aSFelix Fietkau u8 iv[6]; 6225ce09c1aSFelix Fietkau 623128c9b7dSLorenzo Bianconi u8 phy_idx:2; 6245ce09c1aSFelix Fietkau u8 aggr:1; 625e195dad1SFelix Fietkau u8 qos_ctl; 6265ce09c1aSFelix Fietkau u16 seqno; 6275ce09c1aSFelix Fietkau 6285ce09c1aSFelix Fietkau u16 freq; 6295ce09c1aSFelix Fietkau u32 flag; 6305ce09c1aSFelix Fietkau u8 enc_flags; 631021af945SShayne Chen u8 encoding:3, bw:4; 632021af945SShayne Chen union { 633021af945SShayne Chen struct { 634021af945SShayne Chen u8 he_ru:3; 635021af945SShayne Chen u8 he_gi:2; 636021af945SShayne Chen u8 he_dcm:1; 637021af945SShayne Chen }; 638021af945SShayne Chen struct { 639021af945SShayne Chen u8 ru:4; 640021af945SShayne Chen u8 gi:2; 641021af945SShayne Chen } eht; 642021af945SShayne Chen }; 643021af945SShayne Chen 644cc4b3c13SLorenzo Bianconi u8 amsdu:1, first_amsdu:1, last_amsdu:1; 6455ce09c1aSFelix Fietkau u8 rate_idx; 646021af945SShayne Chen u8 nss:5, band:3; 6475ce09c1aSFelix Fietkau s8 signal; 6485ce09c1aSFelix Fietkau u8 chains; 6495ce09c1aSFelix Fietkau s8 chain_signal[IEEE80211_MAX_CHAINS]; 6505ce09c1aSFelix Fietkau }; 6515ce09c1aSFelix Fietkau 652502604f5SYN Chen struct mt76_freq_range_power { 653502604f5SYN Chen const struct cfg80211_sar_freq_ranges *range; 654502604f5SYN Chen s8 power; 655502604f5SYN Chen }; 656502604f5SYN Chen 657f0efa862SFelix Fietkau struct mt76_testmode_ops { 658c918c74dSShayne Chen int (*set_state)(struct mt76_phy *phy, enum mt76_testmode_state state); 659c918c74dSShayne Chen int (*set_params)(struct mt76_phy *phy, struct nlattr **tb, 660f0efa862SFelix Fietkau enum mt76_testmode_state new_state); 661c918c74dSShayne Chen int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg); 662f0efa862SFelix Fietkau }; 663f0efa862SFelix Fietkau 664f0efa862SFelix Fietkau struct mt76_testmode_data { 665f0efa862SFelix Fietkau enum mt76_testmode_state state; 666f0efa862SFelix Fietkau 667f0efa862SFelix Fietkau u32 param_set[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)]; 668f0efa862SFelix Fietkau struct sk_buff *tx_skb; 669f0efa862SFelix Fietkau 670f0efa862SFelix Fietkau u32 tx_count; 6712601dda8SShayne Chen u16 tx_mpdu_len; 672f0efa862SFelix Fietkau 673f0efa862SFelix Fietkau u8 tx_rate_mode; 674f0efa862SFelix Fietkau u8 tx_rate_idx; 675f0efa862SFelix Fietkau u8 tx_rate_nss; 676f0efa862SFelix Fietkau u8 tx_rate_sgi; 677f0efa862SFelix Fietkau u8 tx_rate_ldpc; 6787f54c742SShayne Chen u8 tx_rate_stbc; 6791a38c2f5SShayne Chen u8 tx_ltf; 680f0efa862SFelix Fietkau 681f0efa862SFelix Fietkau u8 tx_antenna_mask; 682fdc9c18eSShayne Chen u8 tx_spe_idx; 683f0efa862SFelix Fietkau 684b8cbdb97SShayne Chen u8 tx_duty_cycle; 685b8cbdb97SShayne Chen u32 tx_time; 686b8cbdb97SShayne Chen u32 tx_ipg; 687b8cbdb97SShayne Chen 688f0efa862SFelix Fietkau u32 freq_offset; 689f0efa862SFelix Fietkau 690f0efa862SFelix Fietkau u8 tx_power[4]; 691f0efa862SFelix Fietkau u8 tx_power_control; 692f0efa862SFelix Fietkau 693c40b42c2SShayne Chen u8 addr[3][ETH_ALEN]; 694c40b42c2SShayne Chen 695f0efa862SFelix Fietkau u32 tx_pending; 696f0efa862SFelix Fietkau u32 tx_queued; 697ba459094SShayne Chen u16 tx_queued_limit; 698f0efa862SFelix Fietkau u32 tx_done; 699f0efa862SFelix Fietkau struct { 700f0efa862SFelix Fietkau u64 packets[__MT_RXQ_MAX]; 701f0efa862SFelix Fietkau u64 fcs_error[__MT_RXQ_MAX]; 702f0efa862SFelix Fietkau } rx_stats; 703f0efa862SFelix Fietkau }; 704f0efa862SFelix Fietkau 70585d96704SLorenzo Bianconi struct mt76_vif { 70685d96704SLorenzo Bianconi u8 idx; 70785d96704SLorenzo Bianconi u8 omac_idx; 70885d96704SLorenzo Bianconi u8 band_idx; 70985d96704SLorenzo Bianconi u8 wmm_idx; 71085d96704SLorenzo Bianconi u8 scan_seq_num; 7115ea3d983SFelix Fietkau u8 cipher; 7120cb065b9SLorenzo Bianconi u8 basic_rates_idx; 7130cb065b9SLorenzo Bianconi u8 mcast_rates_idx; 7140cb065b9SLorenzo Bianconi u8 beacon_rates_idx; 71585d96704SLorenzo Bianconi }; 71685d96704SLorenzo Bianconi 717ac24dd35SFelix Fietkau struct mt76_phy { 718ac24dd35SFelix Fietkau struct ieee80211_hw *hw; 719ac24dd35SFelix Fietkau struct mt76_dev *dev; 720a3d01038SFelix Fietkau void *priv; 72196747a51SFelix Fietkau 722011849e0SFelix Fietkau unsigned long state; 723dc44c45cSLorenzo Bianconi u8 band_idx; 724011849e0SFelix Fietkau 7250335c034SFelix Fietkau spinlock_t tx_lock; 7260335c034SFelix Fietkau struct list_head tx_list; 72791990519SLorenzo Bianconi struct mt76_queue *q_tx[__MT_TXQ_MAX]; 72891990519SLorenzo Bianconi 72996747a51SFelix Fietkau struct cfg80211_chan_def chandef; 73096747a51SFelix Fietkau struct ieee80211_channel *main_chan; 73196747a51SFelix Fietkau 73296747a51SFelix Fietkau struct mt76_channel_state *chan_state; 7333f306448SFelix Fietkau enum mt76_dfs_state dfs_state; 73496747a51SFelix Fietkau ktime_t survey_time; 73596747a51SFelix Fietkau 736d107501aSLorenzo Bianconi u32 aggr_stats[32]; 737d107501aSLorenzo Bianconi 73848dbce5cSLorenzo Bianconi struct mt76_hw_cap cap; 73996747a51SFelix Fietkau struct mt76_sband sband_2g; 74096747a51SFelix Fietkau struct mt76_sband sband_5g; 741cee3fd29SLorenzo Bianconi struct mt76_sband sband_6g; 742beaaeb6bSFelix Fietkau 74398df2baeSLorenzo Bianconi u8 macaddr[ETH_ALEN]; 74498df2baeSLorenzo Bianconi 745beaaeb6bSFelix Fietkau int txpower_cur; 746beaaeb6bSFelix Fietkau u8 antenna_mask; 747b9027e08SLorenzo Bianconi u16 chainmask; 748c918c74dSShayne Chen 749c918c74dSShayne Chen #ifdef CONFIG_NL80211_TESTMODE 750c918c74dSShayne Chen struct mt76_testmode_data test; 751c918c74dSShayne Chen #endif 752a782f8bfSLorenzo Bianconi 753a782f8bfSLorenzo Bianconi struct delayed_work mac_work; 754a782f8bfSLorenzo Bianconi u8 mac_work_count; 755cc4b3c13SLorenzo Bianconi 756cc4b3c13SLorenzo Bianconi struct { 757cc4b3c13SLorenzo Bianconi struct sk_buff *head; 758cc4b3c13SLorenzo Bianconi struct sk_buff **tail; 759cc4b3c13SLorenzo Bianconi u16 seqno; 760cc4b3c13SLorenzo Bianconi } rx_amsdu[__MT_RXQ_MAX]; 761502604f5SYN Chen 762502604f5SYN Chen struct mt76_freq_range_power *frp; 7633abd46ddSLorenzo Bianconi 7643abd46ddSLorenzo Bianconi struct { 7653abd46ddSLorenzo Bianconi struct led_classdev cdev; 7663abd46ddSLorenzo Bianconi char name[32]; 7673abd46ddSLorenzo Bianconi bool al; 7683abd46ddSLorenzo Bianconi u8 pin; 7693abd46ddSLorenzo Bianconi } leds; 770ac24dd35SFelix Fietkau }; 771ac24dd35SFelix Fietkau 77217f1de56SFelix Fietkau struct mt76_dev { 773ac24dd35SFelix Fietkau struct mt76_phy phy; /* must be first */ 774dc44c45cSLorenzo Bianconi struct mt76_phy *phys[__MT_MAX_BAND]; 775bfc394ddSFelix Fietkau 77617f1de56SFelix Fietkau struct ieee80211_hw *hw; 77717f1de56SFelix Fietkau 7782666beceSSujuan Chen spinlock_t wed_lock; 77917f1de56SFelix Fietkau spinlock_t lock; 78017f1de56SFelix Fietkau spinlock_t cc_lock; 781108a4861SStanislaw Gruszka 7825ce09c1aSFelix Fietkau u32 cur_cc_bss_rx; 7835ce09c1aSFelix Fietkau 7845ce09c1aSFelix Fietkau struct mt76_rx_status rx_ampdu_status; 7855ce09c1aSFelix Fietkau u32 rx_ampdu_len; 7865ce09c1aSFelix Fietkau u32 rx_ampdu_ref; 7875ce09c1aSFelix Fietkau 788108a4861SStanislaw Gruszka struct mutex mutex; 789108a4861SStanislaw Gruszka 79017f1de56SFelix Fietkau const struct mt76_bus_ops *bus; 79117f1de56SFelix Fietkau const struct mt76_driver_ops *drv; 792db0f04f3SLorenzo Bianconi const struct mt76_mcu_ops *mcu_ops; 79317f1de56SFelix Fietkau struct device *dev; 794d1ddc536SFelix Fietkau struct device *dma_dev; 79517f1de56SFelix Fietkau 79609872957SLorenzo Bianconi struct mt76_mcu mcu; 79709872957SLorenzo Bianconi 79817f1de56SFelix Fietkau struct net_device napi_dev; 799aa40528aSFelix Fietkau struct net_device tx_napi_dev; 800c3d7c82aSFelix Fietkau spinlock_t rx_lock; 80117f1de56SFelix Fietkau struct napi_struct napi[__MT_RXQ_MAX]; 80217f1de56SFelix Fietkau struct sk_buff_head rx_skb[__MT_RXQ_MAX]; 803ec193b41SLorenzo Bianconi struct tasklet_struct irq_tasklet; 80417f1de56SFelix Fietkau 80517f1de56SFelix Fietkau struct list_head txwi_cache; 8062666beceSSujuan Chen struct list_head rxwi_cache; 807b1cb42adSLorenzo Bianconi struct mt76_queue *q_mcu[__MT_MCUQ_MAX]; 80817f1de56SFelix Fietkau struct mt76_queue q_rx[__MT_RXQ_MAX]; 80917f1de56SFelix Fietkau const struct mt76_queue_ops *queue_ops; 810c1e0d2beSLorenzo Bianconi int tx_dma_idx[4]; 81117f1de56SFelix Fietkau 812781eef5bSFelix Fietkau struct mt76_worker tx_worker; 8138402650aSLorenzo Bianconi struct napi_struct tx_napi; 814a33b8ab8SFelix Fietkau 815b17aff33SLorenzo Bianconi spinlock_t token_lock; 816b17aff33SLorenzo Bianconi struct idr token; 817f68d6762SFelix Fietkau u16 wed_token_count; 81861b5156bSFelix Fietkau u16 token_count; 81961b5156bSFelix Fietkau u16 token_size; 820b17aff33SLorenzo Bianconi 8212666beceSSujuan Chen spinlock_t rx_token_lock; 8222666beceSSujuan Chen struct idr rx_token; 8232666beceSSujuan Chen u16 rx_token_size; 8242666beceSSujuan Chen 82526e40d4cSFelix Fietkau wait_queue_head_t tx_wait; 826c34f1005SLorenzo Bianconi /* spinclock used to protect wcid pktid linked list */ 827c34f1005SLorenzo Bianconi spinlock_t status_lock; 82826e40d4cSFelix Fietkau 8295e616ad2SFelix Fietkau u32 wcid_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; 8305e616ad2SFelix Fietkau u32 wcid_phy_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; 83136404c06SStanislaw Gruszka 832b619e013SEvelyn Tsai u64 vif_mask; 8332ab33b8dSFelix Fietkau 83436404c06SStanislaw Gruszka struct mt76_wcid global_wcid; 83536404c06SStanislaw Gruszka struct mt76_wcid __rcu *wcid[MT76_N_WCIDS]; 836bd1e3e7bSLorenzo Bianconi struct list_head wcid_list; 83736404c06SStanislaw Gruszka 838fbba711cSLorenzo Bianconi struct list_head sta_poll_list; 839fbba711cSLorenzo Bianconi spinlock_t sta_poll_lock; 840fbba711cSLorenzo Bianconi 84117f1de56SFelix Fietkau u32 rev; 84217f1de56SFelix Fietkau 843dc6057f4SLorenzo Bianconi struct tasklet_struct pre_tbtt_tasklet; 8443041c445SLorenzo Bianconi int beacon_int; 845c8a04d98SLorenzo Bianconi u8 beacon_mask; 8463041c445SLorenzo Bianconi 84717f1de56SFelix Fietkau struct debugfs_blob_wrapper eeprom; 84817f1de56SFelix Fietkau struct debugfs_blob_wrapper otp; 84917f1de56SFelix Fietkau 8505b257371SLorenzo Bianconi char alpha2[3]; 851d8b8890dSLorenzo Bianconi enum nl80211_dfs_regions region; 852d8b8890dSLorenzo Bianconi 85317f1de56SFelix Fietkau u32 debugfs_reg; 85417f1de56SFelix Fietkau 855e7173858SFelix Fietkau u8 csa_complete; 856e7173858SFelix Fietkau 857108a4861SStanislaw Gruszka u32 rxfilter; 858108a4861SStanislaw Gruszka 859f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 860f0efa862SFelix Fietkau const struct mt76_testmode_ops *test_ops; 861e7a6a044SShayne Chen struct { 862e7a6a044SShayne Chen const char *name; 863e7a6a044SShayne Chen u32 offset; 864e7a6a044SShayne Chen } test_mtd; 865f0efa862SFelix Fietkau #endif 866a86f1d01SLorenzo Bianconi struct workqueue_struct *wq; 867a86f1d01SLorenzo Bianconi 868f7bbb80fSLorenzo Bianconi union { 869f7bbb80fSLorenzo Bianconi struct mt76_mmio mmio; 870b40b15e1SLorenzo Bianconi struct mt76_usb usb; 871d39b52e3SSean Wang struct mt76_sdio sdio; 87217f1de56SFelix Fietkau }; 873f7bbb80fSLorenzo Bianconi }; 87417f1de56SFelix Fietkau 8757f03a563SLorenzo Bianconi /* per-phy stats. */ 8767f03a563SLorenzo Bianconi struct mt76_mib_stats { 8777f03a563SLorenzo Bianconi u32 ack_fail_cnt; 8787f03a563SLorenzo Bianconi u32 fcs_err_cnt; 8797f03a563SLorenzo Bianconi u32 rts_cnt; 8807f03a563SLorenzo Bianconi u32 rts_retries_cnt; 8817f03a563SLorenzo Bianconi u32 ba_miss_cnt; 8827f03a563SLorenzo Bianconi u32 tx_bf_cnt; 8837f03a563SLorenzo Bianconi u32 tx_mu_bf_cnt; 8847f03a563SLorenzo Bianconi u32 tx_mu_mpdu_cnt; 8857f03a563SLorenzo Bianconi u32 tx_mu_acked_mpdu_cnt; 8867f03a563SLorenzo Bianconi u32 tx_su_acked_mpdu_cnt; 8877f03a563SLorenzo Bianconi u32 tx_bf_ibf_ppdu_cnt; 8887f03a563SLorenzo Bianconi u32 tx_bf_ebf_ppdu_cnt; 8897f03a563SLorenzo Bianconi 8907f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_all_cnt; 8917f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_eht_cnt; 8927f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_he_cnt; 8937f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_vht_cnt; 8947f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_ht_cnt; 8957f03a563SLorenzo Bianconi 8967f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */ 8977f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_nc_cnt; 8987f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_nr_cnt; 8997f03a563SLorenzo Bianconi u32 tx_bf_fb_cpl_cnt; 9007f03a563SLorenzo Bianconi u32 tx_bf_fb_trig_cnt; 9017f03a563SLorenzo Bianconi 9027f03a563SLorenzo Bianconi u32 tx_ampdu_cnt; 9037f03a563SLorenzo Bianconi u32 tx_stop_q_empty_cnt; 9047f03a563SLorenzo Bianconi u32 tx_mpdu_attempts_cnt; 9057f03a563SLorenzo Bianconi u32 tx_mpdu_success_cnt; 9067f03a563SLorenzo Bianconi u32 tx_pkt_ebf_cnt; 9077f03a563SLorenzo Bianconi u32 tx_pkt_ibf_cnt; 9087f03a563SLorenzo Bianconi 9097f03a563SLorenzo Bianconi u32 tx_rwp_fail_cnt; 9107f03a563SLorenzo Bianconi u32 tx_rwp_need_cnt; 9117f03a563SLorenzo Bianconi 9127f03a563SLorenzo Bianconi /* rx stats */ 9137f03a563SLorenzo Bianconi u32 rx_fifo_full_cnt; 9147f03a563SLorenzo Bianconi u32 channel_idle_cnt; 9157f03a563SLorenzo Bianconi u32 primary_cca_busy_time; 9167f03a563SLorenzo Bianconi u32 secondary_cca_busy_time; 9177f03a563SLorenzo Bianconi u32 primary_energy_detect_time; 9187f03a563SLorenzo Bianconi u32 cck_mdrdy_time; 9197f03a563SLorenzo Bianconi u32 ofdm_mdrdy_time; 9207f03a563SLorenzo Bianconi u32 green_mdrdy_time; 9217f03a563SLorenzo Bianconi u32 rx_vector_mismatch_cnt; 9227f03a563SLorenzo Bianconi u32 rx_delimiter_fail_cnt; 9237f03a563SLorenzo Bianconi u32 rx_mrdy_cnt; 9247f03a563SLorenzo Bianconi u32 rx_len_mismatch_cnt; 9257f03a563SLorenzo Bianconi u32 rx_mpdu_cnt; 9267f03a563SLorenzo Bianconi u32 rx_ampdu_cnt; 9277f03a563SLorenzo Bianconi u32 rx_ampdu_bytes_cnt; 9287f03a563SLorenzo Bianconi u32 rx_ampdu_valid_subframe_cnt; 9297f03a563SLorenzo Bianconi u32 rx_ampdu_valid_subframe_bytes_cnt; 9307f03a563SLorenzo Bianconi u32 rx_pfdrop_cnt; 9317f03a563SLorenzo Bianconi u32 rx_vec_queue_overflow_drop_cnt; 9327f03a563SLorenzo Bianconi u32 rx_ba_cnt; 9337f03a563SLorenzo Bianconi 9347f03a563SLorenzo Bianconi u32 tx_amsdu[8]; 9357f03a563SLorenzo Bianconi u32 tx_amsdu_cnt; 9361258c156SRyder Lee 9371258c156SRyder Lee /* mcu_muru_stats */ 9381258c156SRyder Lee u32 dl_cck_cnt; 9391258c156SRyder Lee u32 dl_ofdm_cnt; 9401258c156SRyder Lee u32 dl_htmix_cnt; 9411258c156SRyder Lee u32 dl_htgf_cnt; 9421258c156SRyder Lee u32 dl_vht_su_cnt; 9431258c156SRyder Lee u32 dl_vht_2mu_cnt; 9441258c156SRyder Lee u32 dl_vht_3mu_cnt; 9451258c156SRyder Lee u32 dl_vht_4mu_cnt; 9461258c156SRyder Lee u32 dl_he_su_cnt; 9471258c156SRyder Lee u32 dl_he_ext_su_cnt; 9481258c156SRyder Lee u32 dl_he_2ru_cnt; 9491258c156SRyder Lee u32 dl_he_2mu_cnt; 9501258c156SRyder Lee u32 dl_he_3ru_cnt; 9511258c156SRyder Lee u32 dl_he_3mu_cnt; 9521258c156SRyder Lee u32 dl_he_4ru_cnt; 9531258c156SRyder Lee u32 dl_he_4mu_cnt; 9541258c156SRyder Lee u32 dl_he_5to8ru_cnt; 9551258c156SRyder Lee u32 dl_he_9to16ru_cnt; 9561258c156SRyder Lee u32 dl_he_gtr16ru_cnt; 9571258c156SRyder Lee 9581258c156SRyder Lee u32 ul_hetrig_su_cnt; 9591258c156SRyder Lee u32 ul_hetrig_2ru_cnt; 9601258c156SRyder Lee u32 ul_hetrig_3ru_cnt; 9611258c156SRyder Lee u32 ul_hetrig_4ru_cnt; 9621258c156SRyder Lee u32 ul_hetrig_5to8ru_cnt; 9631258c156SRyder Lee u32 ul_hetrig_9to16ru_cnt; 9641258c156SRyder Lee u32 ul_hetrig_gtr16ru_cnt; 9651258c156SRyder Lee u32 ul_hetrig_2mu_cnt; 9661258c156SRyder Lee u32 ul_hetrig_3mu_cnt; 9671258c156SRyder Lee u32 ul_hetrig_4mu_cnt; 9687f03a563SLorenzo Bianconi }; 9697f03a563SLorenzo Bianconi 97022b980baSFelix Fietkau struct mt76_power_limits { 97122b980baSFelix Fietkau s8 cck[4]; 97222b980baSFelix Fietkau s8 ofdm[8]; 97322b980baSFelix Fietkau s8 mcs[4][10]; 974a9627d99SShayne Chen s8 ru[7][12]; 975975cd4d6SDeren Wu s8 eht[16][16]; 97622b980baSFelix Fietkau }; 97722b980baSFelix Fietkau 97854ae98ffSLorenzo Bianconi struct mt76_ethtool_worker_info { 97954ae98ffSLorenzo Bianconi u64 *data; 98054ae98ffSLorenzo Bianconi int idx; 98154ae98ffSLorenzo Bianconi int initial_stat_idx; 98254ae98ffSLorenzo Bianconi int worker_stat_count; 98354ae98ffSLorenzo Bianconi int sta_count; 98454ae98ffSLorenzo Bianconi }; 98554ae98ffSLorenzo Bianconi 98654b8fdebSLorenzo Bianconi #define CCK_RATE(_idx, _rate) { \ 98754b8fdebSLorenzo Bianconi .bitrate = _rate, \ 98854b8fdebSLorenzo Bianconi .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ 98954b8fdebSLorenzo Bianconi .hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \ 99054b8fdebSLorenzo Bianconi .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + _idx), \ 99154b8fdebSLorenzo Bianconi } 99254b8fdebSLorenzo Bianconi 99354b8fdebSLorenzo Bianconi #define OFDM_RATE(_idx, _rate) { \ 99454b8fdebSLorenzo Bianconi .bitrate = _rate, \ 99554b8fdebSLorenzo Bianconi .hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 99654b8fdebSLorenzo Bianconi .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 99754b8fdebSLorenzo Bianconi } 99854b8fdebSLorenzo Bianconi 99954b8fdebSLorenzo Bianconi extern struct ieee80211_rate mt76_rates[12]; 100054b8fdebSLorenzo Bianconi 1001d4131273SStanislaw Gruszka #define __mt76_rr(dev, ...) (dev)->bus->rr((dev), __VA_ARGS__) 1002d4131273SStanislaw Gruszka #define __mt76_wr(dev, ...) (dev)->bus->wr((dev), __VA_ARGS__) 1003d4131273SStanislaw Gruszka #define __mt76_rmw(dev, ...) (dev)->bus->rmw((dev), __VA_ARGS__) 100435e4ebeaSLorenzo Bianconi #define __mt76_wr_copy(dev, ...) (dev)->bus->write_copy((dev), __VA_ARGS__) 100535e4ebeaSLorenzo Bianconi #define __mt76_rr_copy(dev, ...) (dev)->bus->read_copy((dev), __VA_ARGS__) 1006d4131273SStanislaw Gruszka 100722c575c4SStanislaw Gruszka #define __mt76_set(dev, offset, val) __mt76_rmw(dev, offset, 0, val) 100822c575c4SStanislaw Gruszka #define __mt76_clear(dev, offset, val) __mt76_rmw(dev, offset, val, 0) 100922c575c4SStanislaw Gruszka 101017f1de56SFelix Fietkau #define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__) 101117f1de56SFelix Fietkau #define mt76_wr(dev, ...) (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__) 101217f1de56SFelix Fietkau #define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__) 101335e4ebeaSLorenzo Bianconi #define mt76_wr_copy(dev, ...) (dev)->mt76.bus->write_copy(&((dev)->mt76), __VA_ARGS__) 101435e4ebeaSLorenzo Bianconi #define mt76_rr_copy(dev, ...) (dev)->mt76.bus->read_copy(&((dev)->mt76), __VA_ARGS__) 10156da5a291SStanislaw Gruszka #define mt76_wr_rp(dev, ...) (dev)->mt76.bus->wr_rp(&((dev)->mt76), __VA_ARGS__) 10166da5a291SStanislaw Gruszka #define mt76_rd_rp(dev, ...) (dev)->mt76.bus->rd_rp(&((dev)->mt76), __VA_ARGS__) 101717f1de56SFelix Fietkau 1018f4d45fe2SLorenzo Bianconi 1019e2c2fd0fSLorenzo Bianconi #define mt76_mcu_restart(dev, ...) (dev)->mt76.mcu_ops->mcu_restart(&((dev)->mt76)) 1020db0f04f3SLorenzo Bianconi 102117f1de56SFelix Fietkau #define mt76_set(dev, offset, val) mt76_rmw(dev, offset, 0, val) 102217f1de56SFelix Fietkau #define mt76_clear(dev, offset, val) mt76_rmw(dev, offset, val, 0) 102317f1de56SFelix Fietkau 102417f1de56SFelix Fietkau #define mt76_get_field(_dev, _reg, _field) \ 102517f1de56SFelix Fietkau FIELD_GET(_field, mt76_rr(dev, _reg)) 102617f1de56SFelix Fietkau 102717f1de56SFelix Fietkau #define mt76_rmw_field(_dev, _reg, _field, _val) \ 102817f1de56SFelix Fietkau mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) 102917f1de56SFelix Fietkau 103046436b5eSStanislaw Gruszka #define __mt76_rmw_field(_dev, _reg, _field, _val) \ 103146436b5eSStanislaw Gruszka __mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) 103246436b5eSStanislaw Gruszka 1033ac24dd35SFelix Fietkau #define mt76_hw(dev) (dev)->mphy.hw 103417f1de56SFelix Fietkau 103517f1de56SFelix Fietkau bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, 103617f1de56SFelix Fietkau int timeout); 103717f1de56SFelix Fietkau 103817f1de56SFelix Fietkau #define mt76_poll(dev, ...) __mt76_poll(&((dev)->mt76), __VA_ARGS__) 103917f1de56SFelix Fietkau 104035effe6cSDeren Wu bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, 104135effe6cSDeren Wu int timeout, int kick); 104235effe6cSDeren Wu #define __mt76_poll_msec(...) ____mt76_poll_msec(__VA_ARGS__, 10) 104335effe6cSDeren Wu #define mt76_poll_msec(dev, ...) ____mt76_poll_msec(&((dev)->mt76), __VA_ARGS__, 10) 104435effe6cSDeren Wu #define mt76_poll_msec_tick(dev, ...) ____mt76_poll_msec(&((dev)->mt76), __VA_ARGS__) 104517f1de56SFelix Fietkau 104617f1de56SFelix Fietkau void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs); 1047f37f0550SLorenzo Bianconi void mt76_pci_disable_aspm(struct pci_dev *pdev); 104817f1de56SFelix Fietkau 104917f1de56SFelix Fietkau static inline u16 mt76_chip(struct mt76_dev *dev) 105017f1de56SFelix Fietkau { 105117f1de56SFelix Fietkau return dev->rev >> 16; 105217f1de56SFelix Fietkau } 105317f1de56SFelix Fietkau 105417f1de56SFelix Fietkau static inline u16 mt76_rev(struct mt76_dev *dev) 105517f1de56SFelix Fietkau { 105617f1de56SFelix Fietkau return dev->rev & 0xffff; 105717f1de56SFelix Fietkau } 105817f1de56SFelix Fietkau 105917f1de56SFelix Fietkau #define mt76xx_chip(dev) mt76_chip(&((dev)->mt76)) 106017f1de56SFelix Fietkau #define mt76xx_rev(dev) mt76_rev(&((dev)->mt76)) 106117f1de56SFelix Fietkau 1062cb8ed33dSLorenzo Bianconi #define mt76_init_queues(dev, ...) (dev)->mt76.queue_ops->init(&((dev)->mt76), __VA_ARGS__) 1063a23fde09SLorenzo Bianconi #define mt76_queue_alloc(dev, ...) (dev)->mt76.queue_ops->alloc(&((dev)->mt76), __VA_ARGS__) 10645ed31128SLorenzo Bianconi #define mt76_tx_queue_skb_raw(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb_raw(&((dev)->mt76), __VA_ARGS__) 1065eb9ca7ecSLorenzo Bianconi #define mt76_tx_queue_skb(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb(&((dev)->mt76), __VA_ARGS__) 106617f1de56SFelix Fietkau #define mt76_queue_rx_reset(dev, ...) (dev)->mt76.queue_ops->rx_reset(&((dev)->mt76), __VA_ARGS__) 106717f1de56SFelix Fietkau #define mt76_queue_tx_cleanup(dev, ...) (dev)->mt76.queue_ops->tx_cleanup(&((dev)->mt76), __VA_ARGS__) 1068c001df97SLorenzo Bianconi #define mt76_queue_rx_cleanup(dev, ...) (dev)->mt76.queue_ops->rx_cleanup(&((dev)->mt76), __VA_ARGS__) 106917f1de56SFelix Fietkau #define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__) 10703990465dSLorenzo Bianconi #define mt76_queue_reset(dev, ...) (dev)->mt76.queue_ops->reset_q(&((dev)->mt76), __VA_ARGS__) 107117f1de56SFelix Fietkau 1072f473b42aSFelix Fietkau #define mt76_for_each_q_rx(dev, i) \ 1073b3ad9d6aSBo Jiao for (i = 0; i < ARRAY_SIZE((dev)->q_rx); i++) \ 1074b3ad9d6aSBo Jiao if ((dev)->q_rx[i].ndesc) 1075f473b42aSFelix Fietkau 1076c0f7b25aSLorenzo Bianconi struct mt76_dev *mt76_alloc_device(struct device *pdev, unsigned int size, 1077c0f7b25aSLorenzo Bianconi const struct ieee80211_ops *ops, 1078c0f7b25aSLorenzo Bianconi const struct mt76_driver_ops *drv_ops); 107917f1de56SFelix Fietkau int mt76_register_device(struct mt76_dev *dev, bool vht, 108017f1de56SFelix Fietkau struct ieee80211_rate *rates, int n_rates); 108117f1de56SFelix Fietkau void mt76_unregister_device(struct mt76_dev *dev); 1082def34a2fSLorenzo Bianconi void mt76_free_device(struct mt76_dev *dev); 1083c89d3625SFelix Fietkau void mt76_unregister_phy(struct mt76_phy *phy); 1084c89d3625SFelix Fietkau 1085c89d3625SFelix Fietkau struct mt76_phy *mt76_alloc_phy(struct mt76_dev *dev, unsigned int size, 1086dc44c45cSLorenzo Bianconi const struct ieee80211_ops *ops, 1087dc44c45cSLorenzo Bianconi u8 band_idx); 1088db78a791SLorenzo Bianconi int mt76_register_phy(struct mt76_phy *phy, bool vht, 1089db78a791SLorenzo Bianconi struct ieee80211_rate *rates, int n_rates); 109017f1de56SFelix Fietkau 10913263039dSLorenzo Bianconi struct dentry *mt76_register_debugfs_fops(struct mt76_phy *phy, 1092f6e1f598SLorenzo Bianconi const struct file_operations *ops); 1093f6e1f598SLorenzo Bianconi static inline struct dentry *mt76_register_debugfs(struct mt76_dev *dev) 1094f6e1f598SLorenzo Bianconi { 10953263039dSLorenzo Bianconi return mt76_register_debugfs_fops(&dev->phy, NULL); 1096f6e1f598SLorenzo Bianconi } 1097f6e1f598SLorenzo Bianconi 10980b82a8e8SLorenzo Bianconi int mt76_queues_read(struct seq_file *s, void *data); 10998f410a8bSLorenzo Bianconi void mt76_seq_puts_array(struct seq_file *file, const char *str, 11008f410a8bSLorenzo Bianconi s8 *val, int len); 110117f1de56SFelix Fietkau 110217f1de56SFelix Fietkau int mt76_eeprom_init(struct mt76_dev *dev, int len); 110398df2baeSLorenzo Bianconi void mt76_eeprom_override(struct mt76_phy *phy); 1104495184acSRyder Lee int mt76_get_of_eeprom(struct mt76_dev *dev, void *data, int offset, int len); 110517f1de56SFelix Fietkau 1106b1cb42adSLorenzo Bianconi struct mt76_queue * 1107b1cb42adSLorenzo Bianconi mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc, 1108f68d6762SFelix Fietkau int ring_base, u32 flags); 110933920b2bSRyder Lee u16 mt76_calculate_default_rate(struct mt76_phy *phy, int rateidx); 1110b1cb42adSLorenzo Bianconi static inline int mt76_init_tx_queue(struct mt76_phy *phy, int qid, int idx, 1111f68d6762SFelix Fietkau int n_desc, int ring_base, u32 flags) 1112b1cb42adSLorenzo Bianconi { 1113b1cb42adSLorenzo Bianconi struct mt76_queue *q; 1114b1cb42adSLorenzo Bianconi 1115f68d6762SFelix Fietkau q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base, flags); 1116b1cb42adSLorenzo Bianconi if (IS_ERR(q)) 1117b1cb42adSLorenzo Bianconi return PTR_ERR(q); 1118b1cb42adSLorenzo Bianconi 111991990519SLorenzo Bianconi phy->q_tx[qid] = q; 1120b1cb42adSLorenzo Bianconi 1121b1cb42adSLorenzo Bianconi return 0; 1122b1cb42adSLorenzo Bianconi } 1123b1cb42adSLorenzo Bianconi 1124b1cb42adSLorenzo Bianconi static inline int mt76_init_mcu_queue(struct mt76_dev *dev, int qid, int idx, 1125b1cb42adSLorenzo Bianconi int n_desc, int ring_base) 1126b1cb42adSLorenzo Bianconi { 1127b1cb42adSLorenzo Bianconi struct mt76_queue *q; 1128b1cb42adSLorenzo Bianconi 1129f68d6762SFelix Fietkau q = mt76_init_queue(dev, qid, idx, n_desc, ring_base, 0); 1130b1cb42adSLorenzo Bianconi if (IS_ERR(q)) 1131b1cb42adSLorenzo Bianconi return PTR_ERR(q); 1132b1cb42adSLorenzo Bianconi 1133b1cb42adSLorenzo Bianconi dev->q_mcu[qid] = q; 1134b1cb42adSLorenzo Bianconi 1135b1cb42adSLorenzo Bianconi return 0; 1136b1cb42adSLorenzo Bianconi } 1137b671da33SLorenzo Bianconi 1138011849e0SFelix Fietkau static inline struct mt76_phy * 1139128c9b7dSLorenzo Bianconi mt76_dev_phy(struct mt76_dev *dev, u8 phy_idx) 1140011849e0SFelix Fietkau { 1141dc44c45cSLorenzo Bianconi if ((phy_idx == MT_BAND1 && dev->phys[phy_idx]) || 1142dc44c45cSLorenzo Bianconi (phy_idx == MT_BAND2 && dev->phys[phy_idx])) 1143dc44c45cSLorenzo Bianconi return dev->phys[phy_idx]; 1144128c9b7dSLorenzo Bianconi 1145011849e0SFelix Fietkau return &dev->phy; 1146011849e0SFelix Fietkau } 1147011849e0SFelix Fietkau 1148bfc394ddSFelix Fietkau static inline struct ieee80211_hw * 1149128c9b7dSLorenzo Bianconi mt76_phy_hw(struct mt76_dev *dev, u8 phy_idx) 1150bfc394ddSFelix Fietkau { 1151128c9b7dSLorenzo Bianconi return mt76_dev_phy(dev, phy_idx)->hw; 1152bfc394ddSFelix Fietkau } 1153bfc394ddSFelix Fietkau 1154f3950a41SLorenzo Bianconi static inline u8 * 1155f3950a41SLorenzo Bianconi mt76_get_txwi_ptr(struct mt76_dev *dev, struct mt76_txwi_cache *t) 1156f3950a41SLorenzo Bianconi { 1157f3950a41SLorenzo Bianconi return (u8 *)t - dev->drv->txwi_size; 1158f3950a41SLorenzo Bianconi } 1159f3950a41SLorenzo Bianconi 1160ee8aa945SLorenzo Bianconi /* increment with wrap-around */ 1161ee8aa945SLorenzo Bianconi static inline int mt76_incr(int val, int size) 1162ee8aa945SLorenzo Bianconi { 1163ee8aa945SLorenzo Bianconi return (val + 1) & (size - 1); 1164ee8aa945SLorenzo Bianconi } 1165ee8aa945SLorenzo Bianconi 1166ee8aa945SLorenzo Bianconi /* decrement with wrap-around */ 1167ee8aa945SLorenzo Bianconi static inline int mt76_decr(int val, int size) 1168ee8aa945SLorenzo Bianconi { 1169ee8aa945SLorenzo Bianconi return (val - 1) & (size - 1); 1170ee8aa945SLorenzo Bianconi } 1171ee8aa945SLorenzo Bianconi 11721d0496c6SStanislaw Gruszka u8 mt76_ac_to_hwq(u8 ac); 1173b40b15e1SLorenzo Bianconi 117417f1de56SFelix Fietkau static inline struct ieee80211_txq * 117517f1de56SFelix Fietkau mtxq_to_txq(struct mt76_txq *mtxq) 117617f1de56SFelix Fietkau { 117717f1de56SFelix Fietkau void *ptr = mtxq; 117817f1de56SFelix Fietkau 117917f1de56SFelix Fietkau return container_of(ptr, struct ieee80211_txq, drv_priv); 118017f1de56SFelix Fietkau } 118117f1de56SFelix Fietkau 11829c68a57bSFelix Fietkau static inline struct ieee80211_sta * 11839c68a57bSFelix Fietkau wcid_to_sta(struct mt76_wcid *wcid) 11849c68a57bSFelix Fietkau { 11859c68a57bSFelix Fietkau void *ptr = wcid; 11869c68a57bSFelix Fietkau 11879c68a57bSFelix Fietkau if (!wcid || !wcid->sta) 11889c68a57bSFelix Fietkau return NULL; 11899c68a57bSFelix Fietkau 11909c68a57bSFelix Fietkau return container_of(ptr, struct ieee80211_sta, drv_priv); 11919c68a57bSFelix Fietkau } 11929c68a57bSFelix Fietkau 119388046b2cSFelix Fietkau static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb) 119488046b2cSFelix Fietkau { 119588046b2cSFelix Fietkau BUILD_BUG_ON(sizeof(struct mt76_tx_cb) > 119688046b2cSFelix Fietkau sizeof(IEEE80211_SKB_CB(skb)->status.status_driver_data)); 119788046b2cSFelix Fietkau return ((void *)IEEE80211_SKB_CB(skb)->status.status_driver_data); 119888046b2cSFelix Fietkau } 119988046b2cSFelix Fietkau 120077ae1d5eSRyder Lee static inline void *mt76_skb_get_hdr(struct sk_buff *skb) 120177ae1d5eSRyder Lee { 120277ae1d5eSRyder Lee struct mt76_rx_status mstat; 120377ae1d5eSRyder Lee u8 *data = skb->data; 120477ae1d5eSRyder Lee 120577ae1d5eSRyder Lee /* Alignment concerns */ 120677ae1d5eSRyder Lee BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he) % 4); 120777ae1d5eSRyder Lee BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he_mu) % 4); 120877ae1d5eSRyder Lee 120977ae1d5eSRyder Lee mstat = *((struct mt76_rx_status *)skb->cb); 121077ae1d5eSRyder Lee 121177ae1d5eSRyder Lee if (mstat.flag & RX_FLAG_RADIOTAP_HE) 121277ae1d5eSRyder Lee data += sizeof(struct ieee80211_radiotap_he); 121377ae1d5eSRyder Lee if (mstat.flag & RX_FLAG_RADIOTAP_HE_MU) 121477ae1d5eSRyder Lee data += sizeof(struct ieee80211_radiotap_he_mu); 121577ae1d5eSRyder Lee 121677ae1d5eSRyder Lee return data; 121777ae1d5eSRyder Lee } 121877ae1d5eSRyder Lee 12193bb45b5fSLorenzo Bianconi static inline void mt76_insert_hdr_pad(struct sk_buff *skb) 12203bb45b5fSLorenzo Bianconi { 12213bb45b5fSLorenzo Bianconi int len = ieee80211_get_hdrlen_from_skb(skb); 12223bb45b5fSLorenzo Bianconi 12233bb45b5fSLorenzo Bianconi if (len % 4 == 0) 12243bb45b5fSLorenzo Bianconi return; 12253bb45b5fSLorenzo Bianconi 12263bb45b5fSLorenzo Bianconi skb_push(skb, 2); 12273bb45b5fSLorenzo Bianconi memmove(skb->data, skb->data + 2, len); 12283bb45b5fSLorenzo Bianconi 12293bb45b5fSLorenzo Bianconi skb->data[len] = 0; 12303bb45b5fSLorenzo Bianconi skb->data[len + 1] = 0; 12313bb45b5fSLorenzo Bianconi } 12323bb45b5fSLorenzo Bianconi 12338548c6ebSFelix Fietkau static inline bool mt76_is_skb_pktid(u8 pktid) 12348548c6ebSFelix Fietkau { 12358548c6ebSFelix Fietkau if (pktid & MT_PACKET_ID_HAS_RATE) 12368548c6ebSFelix Fietkau return false; 12378548c6ebSFelix Fietkau 12388548c6ebSFelix Fietkau return pktid >= MT_PACKET_ID_FIRST; 12398548c6ebSFelix Fietkau } 12408548c6ebSFelix Fietkau 124107cda406SFelix Fietkau static inline u8 mt76_tx_power_nss_delta(u8 nss) 124207cda406SFelix Fietkau { 124307cda406SFelix Fietkau static const u8 nss_delta[4] = { 0, 6, 9, 12 }; 124403dd0d49SDeren Wu u8 idx = nss - 1; 124507cda406SFelix Fietkau 124603dd0d49SDeren Wu return (idx < ARRAY_SIZE(nss_delta)) ? nss_delta[idx] : 0; 124707cda406SFelix Fietkau } 124807cda406SFelix Fietkau 1249c918c74dSShayne Chen static inline bool mt76_testmode_enabled(struct mt76_phy *phy) 1250f0efa862SFelix Fietkau { 1251f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 1252c918c74dSShayne Chen return phy->test.state != MT76_TM_STATE_OFF; 1253c918c74dSShayne Chen #else 1254c918c74dSShayne Chen return false; 1255c918c74dSShayne Chen #endif 1256c918c74dSShayne Chen } 1257c918c74dSShayne Chen 1258c918c74dSShayne Chen static inline bool mt76_is_testmode_skb(struct mt76_dev *dev, 1259c918c74dSShayne Chen struct sk_buff *skb, 1260c918c74dSShayne Chen struct ieee80211_hw **hw) 1261c918c74dSShayne Chen { 1262c918c74dSShayne Chen #ifdef CONFIG_NL80211_TESTMODE 1263dc44c45cSLorenzo Bianconi int i; 1264dc44c45cSLorenzo Bianconi 1265dc44c45cSLorenzo Bianconi for (i = 0; i < ARRAY_SIZE(dev->phys); i++) { 1266dc44c45cSLorenzo Bianconi struct mt76_phy *phy = dev->phys[i]; 1267dc44c45cSLorenzo Bianconi 1268dc44c45cSLorenzo Bianconi if (phy && skb == phy->test.tx_skb) { 1269dc44c45cSLorenzo Bianconi *hw = dev->phys[i]->hw; 1270c918c74dSShayne Chen return true; 1271dc44c45cSLorenzo Bianconi } 1272dc44c45cSLorenzo Bianconi } 1273dc44c45cSLorenzo Bianconi return false; 1274f0efa862SFelix Fietkau #else 1275f0efa862SFelix Fietkau return false; 1276f0efa862SFelix Fietkau #endif 1277f0efa862SFelix Fietkau } 1278f0efa862SFelix Fietkau 127917f1de56SFelix Fietkau void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb); 12809fba6d07SFelix Fietkau void mt76_tx(struct mt76_phy *dev, struct ieee80211_sta *sta, 128117f1de56SFelix Fietkau struct mt76_wcid *wcid, struct sk_buff *skb); 128217f1de56SFelix Fietkau void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq); 128391990519SLorenzo Bianconi void mt76_stop_tx_queues(struct mt76_phy *phy, struct ieee80211_sta *sta, 128417f1de56SFelix Fietkau bool send_bar); 1285c50d105aSFelix Fietkau void mt76_tx_check_agg_ssn(struct ieee80211_sta *sta, struct sk_buff *skb); 12869fba6d07SFelix Fietkau void mt76_txq_schedule(struct mt76_phy *phy, enum mt76_txq_id qid); 12879fba6d07SFelix Fietkau void mt76_txq_schedule_all(struct mt76_phy *phy); 1288335e97acSLorenzo Bianconi void mt76_tx_worker_run(struct mt76_dev *dev); 1289781eef5bSFelix Fietkau void mt76_tx_worker(struct mt76_worker *w); 129017f1de56SFelix Fietkau void mt76_release_buffered_frames(struct ieee80211_hw *hw, 129117f1de56SFelix Fietkau struct ieee80211_sta *sta, 129217f1de56SFelix Fietkau u16 tids, int nframes, 129317f1de56SFelix Fietkau enum ieee80211_frame_release_type reason, 129417f1de56SFelix Fietkau bool more_data); 12955a95ca41SFelix Fietkau bool mt76_has_tx_pending(struct mt76_phy *phy); 129696747a51SFelix Fietkau void mt76_set_channel(struct mt76_phy *phy); 1297c560b137SRyder Lee void mt76_update_survey(struct mt76_phy *phy); 129804414240SLorenzo Bianconi void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time); 129917f1de56SFelix Fietkau int mt76_get_survey(struct ieee80211_hw *hw, int idx, 130017f1de56SFelix Fietkau struct survey_info *survey); 1301a71b648eSRyder Lee int mt76_rx_signal(u8 chain_mask, s8 *chain_signal); 1302bb3e3fecSRyder Lee void mt76_set_stream_caps(struct mt76_phy *phy, bool vht); 130317f1de56SFelix Fietkau 1304aee5b8cfSFelix Fietkau int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid, 13057c4f744dSRyder Lee u16 ssn, u16 size); 1306aee5b8cfSFelix Fietkau void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid); 1307aee5b8cfSFelix Fietkau 130830ce7f44SFelix Fietkau void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, 130930ce7f44SFelix Fietkau struct ieee80211_key_conf *key); 131079d1c94cSFelix Fietkau 131179d1c94cSFelix Fietkau void mt76_tx_status_lock(struct mt76_dev *dev, struct sk_buff_head *list) 1312c34f1005SLorenzo Bianconi __acquires(&dev->status_lock); 131379d1c94cSFelix Fietkau void mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list) 1314c34f1005SLorenzo Bianconi __releases(&dev->status_lock); 131579d1c94cSFelix Fietkau 131688046b2cSFelix Fietkau int mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, 131788046b2cSFelix Fietkau struct sk_buff *skb); 131888046b2cSFelix Fietkau struct sk_buff *mt76_tx_status_skb_get(struct mt76_dev *dev, 131979d1c94cSFelix Fietkau struct mt76_wcid *wcid, int pktid, 132079d1c94cSFelix Fietkau struct sk_buff_head *list); 132179d1c94cSFelix Fietkau void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb, 132279d1c94cSFelix Fietkau struct sk_buff_head *list); 13230fe88644SFelix Fietkau void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb, 13240fe88644SFelix Fietkau struct list_head *free_list); 13250fe88644SFelix Fietkau static inline void 13260fe88644SFelix Fietkau mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb) 13270fe88644SFelix Fietkau { 13280fe88644SFelix Fietkau __mt76_tx_complete_skb(dev, wcid, skb, NULL); 13290fe88644SFelix Fietkau } 13300fe88644SFelix Fietkau 1331c02f86eeSLorenzo Bianconi void mt76_tx_status_check(struct mt76_dev *dev, bool flush); 1332e28487eaSFelix Fietkau int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1333e28487eaSFelix Fietkau struct ieee80211_sta *sta, 1334e28487eaSFelix Fietkau enum ieee80211_sta_state old_state, 1335e28487eaSFelix Fietkau enum ieee80211_sta_state new_state); 133613f61dfcSLorenzo Bianconi void __mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif, 133713f61dfcSLorenzo Bianconi struct ieee80211_sta *sta); 133843ba1922SFelix Fietkau void mt76_sta_pre_rcu_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 133943ba1922SFelix Fietkau struct ieee80211_sta *sta); 134030ce7f44SFelix Fietkau 13418af63fedSFelix Fietkau int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy); 1342ef13edc0SFelix Fietkau 13439313faacSFelix Fietkau int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 13449313faacSFelix Fietkau int *dbm); 1345b3cb885eSLorenzo Bianconi int mt76_init_sar_power(struct ieee80211_hw *hw, 1346b3cb885eSLorenzo Bianconi const struct cfg80211_sar_specs *sar); 1347b3cb885eSLorenzo Bianconi int mt76_get_sar_power(struct mt76_phy *phy, 1348b3cb885eSLorenzo Bianconi struct ieee80211_channel *chan, 1349b3cb885eSLorenzo Bianconi int power); 13509313faacSFelix Fietkau 1351e7173858SFelix Fietkau void mt76_csa_check(struct mt76_dev *dev); 1352e7173858SFelix Fietkau void mt76_csa_finish(struct mt76_dev *dev); 1353e7173858SFelix Fietkau 1354e49c76d4SLorenzo Bianconi int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 135587d53103SStanislaw Gruszka int mt76_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set); 1356eadfd98fSLorenzo Bianconi void mt76_insert_ccmp_hdr(struct sk_buff *skb, u8 key_id); 1357d2679d65SLorenzo Bianconi int mt76_get_rate(struct mt76_dev *dev, 1358d2679d65SLorenzo Bianconi struct ieee80211_supported_band *sband, 1359d2679d65SLorenzo Bianconi int idx, bool cck); 13608b8ab5c2SLorenzo Bianconi void mt76_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 13618b8ab5c2SLorenzo Bianconi const u8 *mac); 13628b8ab5c2SLorenzo Bianconi void mt76_sw_scan_complete(struct ieee80211_hw *hw, 13638b8ab5c2SLorenzo Bianconi struct ieee80211_vif *vif); 13643f306448SFelix Fietkau enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy); 1365f0efa862SFelix Fietkau int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1366f0efa862SFelix Fietkau void *data, int len); 1367f0efa862SFelix Fietkau int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, 1368f0efa862SFelix Fietkau struct netlink_callback *cb, void *data, int len); 1369c918c74dSShayne Chen int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state); 13702601dda8SShayne Chen int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len); 1371f0efa862SFelix Fietkau 1372c918c74dSShayne Chen static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable) 1373f0efa862SFelix Fietkau { 1374f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 1375f0efa862SFelix Fietkau enum mt76_testmode_state state = MT76_TM_STATE_IDLE; 1376f0efa862SFelix Fietkau 1377c918c74dSShayne Chen if (disable || phy->test.state == MT76_TM_STATE_OFF) 1378f0efa862SFelix Fietkau state = MT76_TM_STATE_OFF; 1379f0efa862SFelix Fietkau 1380c918c74dSShayne Chen mt76_testmode_set_state(phy, state); 1381f0efa862SFelix Fietkau #endif 1382f0efa862SFelix Fietkau } 1383f0efa862SFelix Fietkau 138487d53103SStanislaw Gruszka 138517f1de56SFelix Fietkau /* internal */ 1386e394b575SFelix Fietkau static inline struct ieee80211_hw * 1387e394b575SFelix Fietkau mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb) 1388e394b575SFelix Fietkau { 1389e394b575SFelix Fietkau struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1390a062f001SLorenzo Bianconi u8 phy_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2; 1391a062f001SLorenzo Bianconi struct ieee80211_hw *hw = mt76_phy_hw(dev, phy_idx); 1392e394b575SFelix Fietkau 1393a062f001SLorenzo Bianconi info->hw_queue &= ~MT_TX_HW_QUEUE_PHY; 1394e394b575SFelix Fietkau 1395e394b575SFelix Fietkau return hw; 1396e394b575SFelix Fietkau } 1397e394b575SFelix Fietkau 139817f1de56SFelix Fietkau void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); 13992666beceSSujuan Chen void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); 14002666beceSSujuan Chen struct mt76_txwi_cache *mt76_get_rxwi(struct mt76_dev *dev); 1401a97a467aSSujuan Chen void mt76_free_pending_rxwi(struct mt76_dev *dev); 14029d9d738bSFelix Fietkau void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, 140381e850efSLorenzo Bianconi struct napi_struct *napi); 140481e850efSLorenzo Bianconi void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q, 140581e850efSLorenzo Bianconi struct napi_struct *napi); 1406aee5b8cfSFelix Fietkau void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames); 1407c918c74dSShayne Chen void mt76_testmode_tx_pending(struct mt76_phy *phy); 1408fe5b5ab5SFelix Fietkau void mt76_queue_tx_complete(struct mt76_dev *dev, struct mt76_queue *q, 1409fe5b5ab5SFelix Fietkau struct mt76_queue_entry *e); 141017f1de56SFelix Fietkau 1411b40b15e1SLorenzo Bianconi /* usb */ 1412b40b15e1SLorenzo Bianconi static inline bool mt76u_urb_error(struct urb *urb) 1413b40b15e1SLorenzo Bianconi { 1414b40b15e1SLorenzo Bianconi return urb->status && 1415b40b15e1SLorenzo Bianconi urb->status != -ECONNRESET && 1416b40b15e1SLorenzo Bianconi urb->status != -ESHUTDOWN && 1417b40b15e1SLorenzo Bianconi urb->status != -ENOENT; 1418b40b15e1SLorenzo Bianconi } 1419b40b15e1SLorenzo Bianconi 1420b40b15e1SLorenzo Bianconi /* Map hardware queues to usb endpoints */ 1421b40b15e1SLorenzo Bianconi static inline u8 q2ep(u8 qid) 1422b40b15e1SLorenzo Bianconi { 1423b40b15e1SLorenzo Bianconi /* TODO: take management packets to queue 5 */ 1424b40b15e1SLorenzo Bianconi return qid + 1; 1425b40b15e1SLorenzo Bianconi } 1426b40b15e1SLorenzo Bianconi 14275de4db8fSStanislaw Gruszka static inline int 1428b63aa031SStanislaw Gruszka mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len, 14293bcd979cSLorenzo Bianconi int timeout, int ep) 14305de4db8fSStanislaw Gruszka { 143180df01f4SLorenzo Bianconi struct usb_interface *uintf = to_usb_interface(dev->dev); 143280df01f4SLorenzo Bianconi struct usb_device *udev = interface_to_usbdev(uintf); 14335de4db8fSStanislaw Gruszka struct mt76_usb *usb = &dev->usb; 14345de4db8fSStanislaw Gruszka unsigned int pipe; 14355de4db8fSStanislaw Gruszka 1436b63aa031SStanislaw Gruszka if (actual_len) 14373bcd979cSLorenzo Bianconi pipe = usb_rcvbulkpipe(udev, usb->in_ep[ep]); 1438b63aa031SStanislaw Gruszka else 14393bcd979cSLorenzo Bianconi pipe = usb_sndbulkpipe(udev, usb->out_ep[ep]); 1440b63aa031SStanislaw Gruszka 1441b63aa031SStanislaw Gruszka return usb_bulk_msg(udev, pipe, data, len, actual_len, timeout); 14425de4db8fSStanislaw Gruszka } 14435de4db8fSStanislaw Gruszka 1444192ad406SLorenzo Bianconi void mt76_ethtool_page_pool_stats(struct mt76_dev *dev, u64 *data, int *index); 144554ae98ffSLorenzo Bianconi void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi, 1446731425f3SShayne Chen struct mt76_sta_stats *stats, bool eht); 1447e98e6df6SLorenzo Bianconi int mt76_skb_adjust_pad(struct sk_buff *skb, int pad); 14486cb596baSLorenzo Bianconi int __mt76u_vendor_request(struct mt76_dev *dev, u8 req, u8 req_type, 14496cb596baSLorenzo Bianconi u16 val, u16 offset, void *buf, size_t len); 1450b40b15e1SLorenzo Bianconi int mt76u_vendor_request(struct mt76_dev *dev, u8 req, 1451b40b15e1SLorenzo Bianconi u8 req_type, u16 val, u16 offset, 1452b40b15e1SLorenzo Bianconi void *buf, size_t len); 1453b40b15e1SLorenzo Bianconi void mt76u_single_wr(struct mt76_dev *dev, const u8 req, 1454b40b15e1SLorenzo Bianconi const u16 offset, const u32 val); 14556cb596baSLorenzo Bianconi void mt76u_read_copy(struct mt76_dev *dev, u32 offset, 14566cb596baSLorenzo Bianconi void *data, int len); 14576cb596baSLorenzo Bianconi u32 ___mt76u_rr(struct mt76_dev *dev, u8 req, u8 req_type, u32 addr); 14586cb596baSLorenzo Bianconi void ___mt76u_wr(struct mt76_dev *dev, u8 req, u8 req_type, 14596cb596baSLorenzo Bianconi u32 addr, u32 val); 14606cb596baSLorenzo Bianconi int __mt76u_init(struct mt76_dev *dev, struct usb_interface *intf, 14616cb596baSLorenzo Bianconi struct mt76_bus_ops *ops); 14626cb596baSLorenzo Bianconi int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf); 146394e1cfa8SLorenzo Bianconi int mt76u_alloc_mcu_queue(struct mt76_dev *dev); 1464b40b15e1SLorenzo Bianconi int mt76u_alloc_queues(struct mt76_dev *dev); 146539d501d9SStanislaw Gruszka void mt76u_stop_tx(struct mt76_dev *dev); 146639d501d9SStanislaw Gruszka void mt76u_stop_rx(struct mt76_dev *dev); 146739d501d9SStanislaw Gruszka int mt76u_resume_rx(struct mt76_dev *dev); 1468b40b15e1SLorenzo Bianconi void mt76u_queues_deinit(struct mt76_dev *dev); 1469b40b15e1SLorenzo Bianconi 1470d39b52e3SSean Wang int mt76s_init(struct mt76_dev *dev, struct sdio_func *func, 1471d39b52e3SSean Wang const struct mt76_bus_ops *bus_ops); 1472d512b008SLorenzo Bianconi int mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid); 1473d512b008SLorenzo Bianconi int mt76s_alloc_tx(struct mt76_dev *dev); 1474d39b52e3SSean Wang void mt76s_deinit(struct mt76_dev *dev); 1475764dee47SLorenzo Bianconi void mt76s_sdio_irq(struct sdio_func *func); 1476764dee47SLorenzo Bianconi void mt76s_txrx_worker(struct mt76_sdio *sdio); 1477ca74b9b9SSean Wang bool mt76s_txqs_empty(struct mt76_dev *dev); 1478dacf0acfSSean Wang int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, 1479dacf0acfSSean Wang int hw_ver); 1480764dee47SLorenzo Bianconi u32 mt76s_rr(struct mt76_dev *dev, u32 offset); 1481764dee47SLorenzo Bianconi void mt76s_wr(struct mt76_dev *dev, u32 offset, u32 val); 1482764dee47SLorenzo Bianconi u32 mt76s_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val); 1483764dee47SLorenzo Bianconi u32 mt76s_read_pcr(struct mt76_dev *dev); 1484764dee47SLorenzo Bianconi void mt76s_write_copy(struct mt76_dev *dev, u32 offset, 1485764dee47SLorenzo Bianconi const void *data, int len); 1486764dee47SLorenzo Bianconi void mt76s_read_copy(struct mt76_dev *dev, u32 offset, 1487764dee47SLorenzo Bianconi void *data, int len); 1488764dee47SLorenzo Bianconi int mt76s_wr_rp(struct mt76_dev *dev, u32 base, 1489764dee47SLorenzo Bianconi const struct mt76_reg_pair *data, 1490764dee47SLorenzo Bianconi int len); 1491764dee47SLorenzo Bianconi int mt76s_rd_rp(struct mt76_dev *dev, u32 base, 1492764dee47SLorenzo Bianconi struct mt76_reg_pair *data, int len); 1493d39b52e3SSean Wang 14949df0fab9SLorenzo Bianconi struct sk_buff * 1495a0a2034eSLorenzo Bianconi __mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, 1496b146f238SLorenzo Bianconi int len, int data_len, gfp_t gfp); 1497a0a2034eSLorenzo Bianconi static inline struct sk_buff * 1498bb31a80eSLorenzo Bianconi mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, 1499a0a2034eSLorenzo Bianconi int data_len) 1500a0a2034eSLorenzo Bianconi { 1501b146f238SLorenzo Bianconi return __mt76_mcu_msg_alloc(dev, data, data_len, data_len, GFP_KERNEL); 1502a0a2034eSLorenzo Bianconi } 1503a0a2034eSLorenzo Bianconi 1504c07a49d4SLorenzo Bianconi void mt76_mcu_rx_event(struct mt76_dev *dev, struct sk_buff *skb); 1505680abb25SLorenzo Bianconi struct sk_buff *mt76_mcu_get_response(struct mt76_dev *dev, 1506680abb25SLorenzo Bianconi unsigned long expires); 1507ae5ad627SFelix Fietkau int mt76_mcu_send_and_get_msg(struct mt76_dev *dev, int cmd, const void *data, 1508ae5ad627SFelix Fietkau int len, bool wait_resp, struct sk_buff **ret); 1509ae5ad627SFelix Fietkau int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, 1510ae5ad627SFelix Fietkau int cmd, bool wait_resp, struct sk_buff **ret); 1511215a2efaSLorenzo Bianconi int __mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data, 1512215a2efaSLorenzo Bianconi int len, int max_len); 1513215a2efaSLorenzo Bianconi static inline int 1514215a2efaSLorenzo Bianconi mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data, 1515215a2efaSLorenzo Bianconi int len) 1516215a2efaSLorenzo Bianconi { 15175b8f1840SSean Wang int max_len = 4096 - dev->mcu_ops->headroom; 15185b8f1840SSean Wang 15195b8f1840SSean Wang return __mt76_mcu_send_firmware(dev, cmd, data, len, max_len); 1520215a2efaSLorenzo Bianconi } 1521215a2efaSLorenzo Bianconi 1522ae5ad627SFelix Fietkau static inline int 1523ae5ad627SFelix Fietkau mt76_mcu_send_msg(struct mt76_dev *dev, int cmd, const void *data, int len, 1524ae5ad627SFelix Fietkau bool wait_resp) 1525ae5ad627SFelix Fietkau { 1526ae5ad627SFelix Fietkau return mt76_mcu_send_and_get_msg(dev, cmd, data, len, wait_resp, NULL); 1527ae5ad627SFelix Fietkau } 1528ae5ad627SFelix Fietkau 1529ae5ad627SFelix Fietkau static inline int 1530ae5ad627SFelix Fietkau mt76_mcu_skb_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, 1531ae5ad627SFelix Fietkau bool wait_resp) 1532ae5ad627SFelix Fietkau { 1533ae5ad627SFelix Fietkau return mt76_mcu_skb_send_and_get_msg(dev, skb, cmd, wait_resp, NULL); 1534ae5ad627SFelix Fietkau } 15359df0fab9SLorenzo Bianconi 15369220f695SLorenzo Bianconi void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set); 15379220f695SLorenzo Bianconi 153822b980baSFelix Fietkau s8 mt76_get_rate_power_limits(struct mt76_phy *phy, 153922b980baSFelix Fietkau struct ieee80211_channel *chan, 154022b980baSFelix Fietkau struct mt76_power_limits *dest, 154122b980baSFelix Fietkau s8 target_power); 154222b980baSFelix Fietkau 154358bcd4edSLorenzo Bianconi static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q) 154458bcd4edSLorenzo Bianconi { 154558bcd4edSLorenzo Bianconi return (q->flags & MT_QFLAG_WED) && 154658bcd4edSLorenzo Bianconi FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX; 154758bcd4edSLorenzo Bianconi } 154858bcd4edSLorenzo Bianconi 1549d089692bSLorenzo Bianconi struct mt76_txwi_cache * 1550d089692bSLorenzo Bianconi mt76_token_release(struct mt76_dev *dev, int token, bool *wake); 1551d089692bSLorenzo Bianconi int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi); 1552d089692bSLorenzo Bianconi void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked); 15532666beceSSujuan Chen struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token); 15542666beceSSujuan Chen int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr, 15552666beceSSujuan Chen struct mt76_txwi_cache *r, dma_addr_t phys); 15562f5c3c77SLorenzo Bianconi int mt76_create_page_pool(struct mt76_dev *dev, struct mt76_queue *q); 15572f5c3c77SLorenzo Bianconi static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct) 15582f5c3c77SLorenzo Bianconi { 15592f5c3c77SLorenzo Bianconi struct page *page = virt_to_head_page(buf); 15602f5c3c77SLorenzo Bianconi 15612f5c3c77SLorenzo Bianconi page_pool_put_full_page(page->pp, page, allow_direct); 15622f5c3c77SLorenzo Bianconi } 15632f5c3c77SLorenzo Bianconi 15642f5c3c77SLorenzo Bianconi static inline void * 15652f5c3c77SLorenzo Bianconi mt76_get_page_pool_buf(struct mt76_queue *q, u32 *offset, u32 size) 15662f5c3c77SLorenzo Bianconi { 15672f5c3c77SLorenzo Bianconi struct page *page; 15682f5c3c77SLorenzo Bianconi 15692f5c3c77SLorenzo Bianconi page = page_pool_dev_alloc_frag(q->page_pool, offset, size); 15702f5c3c77SLorenzo Bianconi if (!page) 15712f5c3c77SLorenzo Bianconi return NULL; 15722f5c3c77SLorenzo Bianconi 15732f5c3c77SLorenzo Bianconi return page_address(page) + *offset; 15742f5c3c77SLorenzo Bianconi } 1575d089692bSLorenzo Bianconi 1576d089692bSLorenzo Bianconi static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked) 1577d089692bSLorenzo Bianconi { 1578d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1579d089692bSLorenzo Bianconi __mt76_set_tx_blocked(dev, blocked); 1580d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1581d089692bSLorenzo Bianconi } 1582d089692bSLorenzo Bianconi 1583d089692bSLorenzo Bianconi static inline int 1584d089692bSLorenzo Bianconi mt76_token_get(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi) 1585d089692bSLorenzo Bianconi { 1586d089692bSLorenzo Bianconi int token; 1587d089692bSLorenzo Bianconi 1588d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 158961b5156bSFelix Fietkau token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC); 1590d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1591d089692bSLorenzo Bianconi 1592d089692bSLorenzo Bianconi return token; 1593d089692bSLorenzo Bianconi } 1594d089692bSLorenzo Bianconi 1595d089692bSLorenzo Bianconi static inline struct mt76_txwi_cache * 1596d089692bSLorenzo Bianconi mt76_token_put(struct mt76_dev *dev, int token) 1597d089692bSLorenzo Bianconi { 1598d089692bSLorenzo Bianconi struct mt76_txwi_cache *txwi; 1599d089692bSLorenzo Bianconi 1600d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1601d089692bSLorenzo Bianconi txwi = idr_remove(&dev->token, token); 1602d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1603d089692bSLorenzo Bianconi 1604d089692bSLorenzo Bianconi return txwi; 1605d089692bSLorenzo Bianconi } 160690052b84SLorenzo Bianconi 16070335c034SFelix Fietkau void mt76_wcid_init(struct mt76_wcid *wcid); 16080335c034SFelix Fietkau void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid); 1609bd1e3e7bSLorenzo Bianconi 161017f1de56SFelix Fietkau #endif 1611