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) 32af8d2af5SLorenzo Bianconi #define MT_QFLAG_WED_TYPE GENMASK(4, 2) 33af8d2af5SLorenzo Bianconi #define MT_QFLAG_WED BIT(5) 34950d0abbSBo Jiao #define MT_QFLAG_WED_RRO BIT(6) 35950d0abbSBo Jiao #define MT_QFLAG_WED_RRO_EN BIT(7) 36f68d6762SFelix Fietkau 37f68d6762SFelix Fietkau #define __MT_WED_Q(_type, _n) (MT_QFLAG_WED | \ 38f68d6762SFelix Fietkau FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \ 39f68d6762SFelix Fietkau FIELD_PREP(MT_QFLAG_WED_RING, _n)) 40950d0abbSBo Jiao #define __MT_WED_RRO_Q(_type, _n) (MT_QFLAG_WED_RRO | __MT_WED_Q(_type, _n)) 41950d0abbSBo Jiao 42f68d6762SFelix Fietkau #define MT_WED_Q_TX(_n) __MT_WED_Q(MT76_WED_Q_TX, _n) 43cd372b8cSLorenzo Bianconi #define MT_WED_Q_RX(_n) __MT_WED_Q(MT76_WED_Q_RX, _n) 44f68d6762SFelix Fietkau #define MT_WED_Q_TXFREE __MT_WED_Q(MT76_WED_Q_TXFREE, 0) 45950d0abbSBo Jiao #define MT_WED_RRO_Q_DATA(_n) __MT_WED_RRO_Q(MT76_WED_RRO_Q_DATA, _n) 46950d0abbSBo Jiao #define MT_WED_RRO_Q_MSDU_PG(_n) __MT_WED_RRO_Q(MT76_WED_RRO_Q_MSDU_PG, _n) 47950d0abbSBo Jiao #define MT_WED_RRO_Q_IND __MT_WED_RRO_Q(MT76_WED_RRO_Q_IND, 0) 48f68d6762SFelix Fietkau 4917f1de56SFelix Fietkau struct mt76_dev; 5096747a51SFelix Fietkau struct mt76_phy; 51469d4818SLorenzo Bianconi struct mt76_wcid; 523ad08509SLorenzo Bianconi struct mt76s_intr; 5317f1de56SFelix Fietkau 546da5a291SStanislaw Gruszka struct mt76_reg_pair { 556da5a291SStanislaw Gruszka u32 reg; 566da5a291SStanislaw Gruszka u32 value; 576da5a291SStanislaw Gruszka }; 586da5a291SStanislaw Gruszka 59c50479faSStanislaw Gruszka enum mt76_bus_type { 60c50479faSStanislaw Gruszka MT76_BUS_MMIO, 61c50479faSStanislaw Gruszka MT76_BUS_USB, 62d39b52e3SSean Wang MT76_BUS_SDIO, 63c50479faSStanislaw Gruszka }; 64c50479faSStanislaw Gruszka 65f68d6762SFelix Fietkau enum mt76_wed_type { 66f68d6762SFelix Fietkau MT76_WED_Q_TX, 67f68d6762SFelix Fietkau MT76_WED_Q_TXFREE, 68cd372b8cSLorenzo Bianconi MT76_WED_Q_RX, 69950d0abbSBo Jiao MT76_WED_RRO_Q_DATA, 70950d0abbSBo Jiao MT76_WED_RRO_Q_MSDU_PG, 71950d0abbSBo Jiao MT76_WED_RRO_Q_IND, 72f68d6762SFelix Fietkau }; 73f68d6762SFelix Fietkau 7417f1de56SFelix Fietkau struct mt76_bus_ops { 7517f1de56SFelix Fietkau u32 (*rr)(struct mt76_dev *dev, u32 offset); 7617f1de56SFelix Fietkau void (*wr)(struct mt76_dev *dev, u32 offset, u32 val); 7717f1de56SFelix Fietkau u32 (*rmw)(struct mt76_dev *dev, u32 offset, u32 mask, u32 val); 7835e4ebeaSLorenzo Bianconi void (*write_copy)(struct mt76_dev *dev, u32 offset, const void *data, 7935e4ebeaSLorenzo Bianconi int len); 8035e4ebeaSLorenzo Bianconi void (*read_copy)(struct mt76_dev *dev, u32 offset, void *data, 8117f1de56SFelix Fietkau int len); 826da5a291SStanislaw Gruszka int (*wr_rp)(struct mt76_dev *dev, u32 base, 836da5a291SStanislaw Gruszka const struct mt76_reg_pair *rp, int len); 846da5a291SStanislaw Gruszka int (*rd_rp)(struct mt76_dev *dev, u32 base, 856da5a291SStanislaw Gruszka struct mt76_reg_pair *rp, int len); 86c50479faSStanislaw Gruszka enum mt76_bus_type type; 8717f1de56SFelix Fietkau }; 8817f1de56SFelix Fietkau 8961c51a74SLorenzo Bianconi #define mt76_is_usb(dev) ((dev)->bus->type == MT76_BUS_USB) 9061c51a74SLorenzo Bianconi #define mt76_is_mmio(dev) ((dev)->bus->type == MT76_BUS_MMIO) 91d39b52e3SSean Wang #define mt76_is_sdio(dev) ((dev)->bus->type == MT76_BUS_SDIO) 92c50479faSStanislaw Gruszka 9317f1de56SFelix Fietkau enum mt76_txq_id { 9417f1de56SFelix Fietkau MT_TXQ_VO = IEEE80211_AC_VO, 9517f1de56SFelix Fietkau MT_TXQ_VI = IEEE80211_AC_VI, 9617f1de56SFelix Fietkau MT_TXQ_BE = IEEE80211_AC_BE, 9717f1de56SFelix Fietkau MT_TXQ_BK = IEEE80211_AC_BK, 9817f1de56SFelix Fietkau MT_TXQ_PSD, 9917f1de56SFelix Fietkau MT_TXQ_BEACON, 10017f1de56SFelix Fietkau MT_TXQ_CAB, 10117f1de56SFelix Fietkau __MT_TXQ_MAX 10217f1de56SFelix Fietkau }; 10317f1de56SFelix Fietkau 104b1cb42adSLorenzo Bianconi enum mt76_mcuq_id { 105e637763bSLorenzo Bianconi MT_MCUQ_WM, 106e637763bSLorenzo Bianconi MT_MCUQ_WA, 107e637763bSLorenzo Bianconi MT_MCUQ_FWDL, 108b1cb42adSLorenzo Bianconi __MT_MCUQ_MAX 109b1cb42adSLorenzo Bianconi }; 110b1cb42adSLorenzo Bianconi 11117f1de56SFelix Fietkau enum mt76_rxq_id { 11217f1de56SFelix Fietkau MT_RXQ_MAIN, 11317f1de56SFelix Fietkau MT_RXQ_MCU, 114d3377b78SRyder Lee MT_RXQ_MCU_WA, 115fc8f841bSLorenzo Bianconi MT_RXQ_BAND1, 116fc8f841bSLorenzo Bianconi MT_RXQ_BAND1_WA, 117f9b627f1SBo Jiao MT_RXQ_MAIN_WA, 118fc8f841bSLorenzo Bianconi MT_RXQ_BAND2, 119fc8f841bSLorenzo Bianconi MT_RXQ_BAND2_WA, 12083eafc92SSujuan Chen MT_RXQ_RRO_BAND0, 12183eafc92SSujuan Chen MT_RXQ_RRO_BAND1, 12283eafc92SSujuan Chen MT_RXQ_RRO_BAND2, 12383eafc92SSujuan Chen MT_RXQ_MSDU_PAGE_BAND0, 12483eafc92SSujuan Chen MT_RXQ_MSDU_PAGE_BAND1, 12583eafc92SSujuan Chen MT_RXQ_MSDU_PAGE_BAND2, 12683eafc92SSujuan Chen MT_RXQ_TXFREE_BAND0, 12783eafc92SSujuan Chen MT_RXQ_TXFREE_BAND1, 12883eafc92SSujuan Chen MT_RXQ_TXFREE_BAND2, 12983eafc92SSujuan Chen MT_RXQ_RRO_IND, 13017f1de56SFelix Fietkau __MT_RXQ_MAX 13117f1de56SFelix Fietkau }; 13217f1de56SFelix Fietkau 133dc44c45cSLorenzo Bianconi enum mt76_band_id { 134dc44c45cSLorenzo Bianconi MT_BAND0, 135dc44c45cSLorenzo Bianconi MT_BAND1, 136dc44c45cSLorenzo Bianconi MT_BAND2, 137dc44c45cSLorenzo Bianconi __MT_MAX_BAND 138dc44c45cSLorenzo Bianconi }; 139dc44c45cSLorenzo Bianconi 140c368362cSRyder Lee enum mt76_cipher_type { 141c368362cSRyder Lee MT_CIPHER_NONE, 142c368362cSRyder Lee MT_CIPHER_WEP40, 143c368362cSRyder Lee MT_CIPHER_TKIP, 144c368362cSRyder Lee MT_CIPHER_TKIP_NO_MIC, 145c368362cSRyder Lee MT_CIPHER_AES_CCMP, 146c368362cSRyder Lee MT_CIPHER_WEP104, 147c368362cSRyder Lee MT_CIPHER_BIP_CMAC_128, 148c368362cSRyder Lee MT_CIPHER_WEP128, 149c368362cSRyder Lee MT_CIPHER_WAPI, 150c368362cSRyder Lee MT_CIPHER_CCMP_CCX, 151c368362cSRyder Lee MT_CIPHER_CCMP_256, 152c368362cSRyder Lee MT_CIPHER_GCMP, 153c368362cSRyder Lee MT_CIPHER_GCMP_256, 154c368362cSRyder Lee }; 155c368362cSRyder Lee 1563f306448SFelix Fietkau enum mt76_dfs_state { 1573f306448SFelix Fietkau MT_DFS_STATE_UNKNOWN, 1583f306448SFelix Fietkau MT_DFS_STATE_DISABLED, 1593f306448SFelix Fietkau MT_DFS_STATE_CAC, 1603f306448SFelix Fietkau MT_DFS_STATE_ACTIVE, 1613f306448SFelix Fietkau }; 1623f306448SFelix Fietkau 16317f1de56SFelix Fietkau struct mt76_queue_buf { 16417f1de56SFelix Fietkau dma_addr_t addr; 165c3778443SFelix Fietkau u16 len:15, 166c3778443SFelix Fietkau skip_unmap:1; 16717f1de56SFelix Fietkau }; 16817f1de56SFelix Fietkau 169b5903c47SLorenzo Bianconi struct mt76_tx_info { 170b5903c47SLorenzo Bianconi struct mt76_queue_buf buf[32]; 171cfaae9e6SLorenzo Bianconi struct sk_buff *skb; 172b5903c47SLorenzo Bianconi int nbuf; 173b5903c47SLorenzo Bianconi u32 info; 174b5903c47SLorenzo Bianconi }; 175b5903c47SLorenzo Bianconi 17617f1de56SFelix Fietkau struct mt76_queue_entry { 17717f1de56SFelix Fietkau union { 17817f1de56SFelix Fietkau void *buf; 17917f1de56SFelix Fietkau struct sk_buff *skb; 18017f1de56SFelix Fietkau }; 181b40b15e1SLorenzo Bianconi union { 18217f1de56SFelix Fietkau struct mt76_txwi_cache *txwi; 183d7d4ea9aSStanislaw Gruszka struct urb *urb; 184d39b52e3SSean Wang int buf_sz; 185b40b15e1SLorenzo Bianconi }; 1864920a3a1SSujuan Chen dma_addr_t dma_addr[2]; 18775d4bf1fSFelix Fietkau u16 dma_len[2]; 188e1378e52SFelix Fietkau u16 wcid; 1897bd0650bSLorenzo Bianconi bool skip_buf0:1; 19027d5c528SFelix Fietkau bool skip_buf1:1; 1917bd0650bSLorenzo Bianconi bool done:1; 19217f1de56SFelix Fietkau }; 19317f1de56SFelix Fietkau 19417f1de56SFelix Fietkau struct mt76_queue_regs { 19517f1de56SFelix Fietkau u32 desc_base; 19617f1de56SFelix Fietkau u32 ring_size; 19717f1de56SFelix Fietkau u32 cpu_idx; 19817f1de56SFelix Fietkau u32 dma_idx; 19917f1de56SFelix Fietkau } __packed __aligned(4); 20017f1de56SFelix Fietkau 20117f1de56SFelix Fietkau struct mt76_queue { 20217f1de56SFelix Fietkau struct mt76_queue_regs __iomem *regs; 20317f1de56SFelix Fietkau 20417f1de56SFelix Fietkau spinlock_t lock; 2059716ef04SFelix Fietkau spinlock_t cleanup_lock; 20617f1de56SFelix Fietkau struct mt76_queue_entry *entry; 207950d0abbSBo Jiao struct mt76_rro_desc *rro_desc; 20817f1de56SFelix Fietkau struct mt76_desc *desc; 20917f1de56SFelix Fietkau 210b40b15e1SLorenzo Bianconi u16 first; 21117f1de56SFelix Fietkau u16 head; 21217f1de56SFelix Fietkau u16 tail; 2135304bf3bSLorenzo Bianconi u8 hw_idx; 2145304bf3bSLorenzo Bianconi u8 ep; 21517f1de56SFelix Fietkau int ndesc; 21617f1de56SFelix Fietkau int queued; 21717f1de56SFelix Fietkau int buf_size; 218cd44bc40SLorenzo Bianconi bool stopped; 21990d494c9SFelix Fietkau bool blocked; 22017f1de56SFelix Fietkau 22117f1de56SFelix Fietkau u8 buf_offset; 222950d0abbSBo Jiao u16 flags; 223f68d6762SFelix Fietkau 2242e420b88SLorenzo Bianconi struct mtk_wed_device *wed; 225f68d6762SFelix Fietkau u32 wed_regs; 22617f1de56SFelix Fietkau 22717f1de56SFelix Fietkau dma_addr_t desc_dma; 22817f1de56SFelix Fietkau struct sk_buff *rx_head; 2292f5c3c77SLorenzo Bianconi struct page_pool *page_pool; 23017f1de56SFelix Fietkau }; 23117f1de56SFelix Fietkau 232db0f04f3SLorenzo Bianconi struct mt76_mcu_ops { 2333688c18bSFelix Fietkau unsigned int max_retry; 234bb31a80eSLorenzo Bianconi u32 headroom; 235bb31a80eSLorenzo Bianconi u32 tailroom; 236bb31a80eSLorenzo Bianconi 237a74d6336SStanislaw Gruszka int (*mcu_send_msg)(struct mt76_dev *dev, int cmd, const void *data, 238a74d6336SStanislaw Gruszka int len, bool wait_resp); 2393688c18bSFelix Fietkau int (*mcu_skb_prepare_msg)(struct mt76_dev *dev, struct sk_buff *skb, 2403688c18bSFelix Fietkau int cmd, int *seq); 241f4d45fe2SLorenzo Bianconi int (*mcu_skb_send_msg)(struct mt76_dev *dev, struct sk_buff *skb, 242e452c6ebSFelix Fietkau int cmd, int *seq); 243f320d812SFelix Fietkau int (*mcu_parse_response)(struct mt76_dev *dev, int cmd, 244f320d812SFelix Fietkau struct sk_buff *skb, int seq); 245d39b52e3SSean Wang u32 (*mcu_rr)(struct mt76_dev *dev, u32 offset); 246d39b52e3SSean Wang void (*mcu_wr)(struct mt76_dev *dev, u32 offset, u32 val); 2476da5a291SStanislaw Gruszka int (*mcu_wr_rp)(struct mt76_dev *dev, u32 base, 2486da5a291SStanislaw Gruszka const struct mt76_reg_pair *rp, int len); 2496da5a291SStanislaw Gruszka int (*mcu_rd_rp)(struct mt76_dev *dev, u32 base, 2506da5a291SStanislaw Gruszka struct mt76_reg_pair *rp, int len); 25100496042SFelix Fietkau int (*mcu_restart)(struct mt76_dev *dev); 252db0f04f3SLorenzo Bianconi }; 253db0f04f3SLorenzo Bianconi 25417f1de56SFelix Fietkau struct mt76_queue_ops { 255cb8ed33dSLorenzo Bianconi int (*init)(struct mt76_dev *dev, 256cb8ed33dSLorenzo Bianconi int (*poll)(struct napi_struct *napi, int budget)); 25717f1de56SFelix Fietkau 258b1bfbe70SLorenzo Bianconi int (*alloc)(struct mt76_dev *dev, struct mt76_queue *q, 259b1bfbe70SLorenzo Bianconi int idx, int n_desc, int bufsize, 260b1bfbe70SLorenzo Bianconi u32 ring_base); 26117f1de56SFelix Fietkau 2625d581c33SFelix Fietkau int (*tx_queue_skb)(struct mt76_phy *phy, struct mt76_queue *q, 263d08295f5SFelix Fietkau enum mt76_txq_id qid, struct sk_buff *skb, 264d08295f5SFelix Fietkau struct mt76_wcid *wcid, struct ieee80211_sta *sta); 265469d4818SLorenzo Bianconi 266d95093a1SLorenzo Bianconi int (*tx_queue_skb_raw)(struct mt76_dev *dev, struct mt76_queue *q, 2675ed31128SLorenzo Bianconi struct sk_buff *skb, u32 tx_info); 2685ed31128SLorenzo Bianconi 26917f1de56SFelix Fietkau void *(*dequeue)(struct mt76_dev *dev, struct mt76_queue *q, bool flush, 27017f1de56SFelix Fietkau int *len, u32 *info, bool *more); 27117f1de56SFelix Fietkau 27217f1de56SFelix Fietkau void (*rx_reset)(struct mt76_dev *dev, enum mt76_rxq_id qid); 27317f1de56SFelix Fietkau 274e5655492SLorenzo Bianconi void (*tx_cleanup)(struct mt76_dev *dev, struct mt76_queue *q, 27517f1de56SFelix Fietkau bool flush); 27617f1de56SFelix Fietkau 277c001df97SLorenzo Bianconi void (*rx_cleanup)(struct mt76_dev *dev, struct mt76_queue *q); 278c001df97SLorenzo Bianconi 27917f1de56SFelix Fietkau void (*kick)(struct mt76_dev *dev, struct mt76_queue *q); 2803990465dSLorenzo Bianconi 2813990465dSLorenzo Bianconi void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q); 28217f1de56SFelix Fietkau }; 28317f1de56SFelix Fietkau 284dc877523SRyder Lee enum mt76_phy_type { 285dc877523SRyder Lee MT_PHY_TYPE_CCK, 286dc877523SRyder Lee MT_PHY_TYPE_OFDM, 287dc877523SRyder Lee MT_PHY_TYPE_HT, 288dc877523SRyder Lee MT_PHY_TYPE_HT_GF, 289dc877523SRyder Lee MT_PHY_TYPE_VHT, 290dc877523SRyder Lee MT_PHY_TYPE_HE_SU = 8, 291dc877523SRyder Lee MT_PHY_TYPE_HE_EXT_SU, 292dc877523SRyder Lee MT_PHY_TYPE_HE_TB, 293dc877523SRyder Lee MT_PHY_TYPE_HE_MU, 294c2eccffdSShayne Chen MT_PHY_TYPE_EHT_SU = 13, 295c2eccffdSShayne Chen MT_PHY_TYPE_EHT_TRIG, 296c2eccffdSShayne Chen MT_PHY_TYPE_EHT_MU, 297c2eccffdSShayne Chen __MT_PHY_TYPE_MAX, 298dc877523SRyder Lee }; 299dc877523SRyder Lee 300dc877523SRyder Lee struct mt76_sta_stats { 301c2eccffdSShayne Chen u64 tx_mode[__MT_PHY_TYPE_MAX]; 302731425f3SShayne Chen u64 tx_bw[5]; /* 20, 40, 80, 160, 320 */ 303dc877523SRyder Lee u64 tx_nss[4]; /* 1, 2, 3, 4 */ 304dc877523SRyder Lee u64 tx_mcs[16]; /* mcs idx */ 30543eaa368SRyder Lee u64 tx_bytes; 306c6cde7b7SSujuan Chen /* WED TX */ 307161a7528SPeter Chiu u32 tx_packets; /* unit: MSDU */ 30843eaa368SRyder Lee u32 tx_retries; 30943eaa368SRyder Lee u32 tx_failed; 310c6cde7b7SSujuan Chen /* WED RX */ 311c6cde7b7SSujuan Chen u64 rx_bytes; 312c6cde7b7SSujuan Chen u32 rx_packets; 313c6cde7b7SSujuan Chen u32 rx_errors; 314c6cde7b7SSujuan Chen u32 rx_drops; 315dc877523SRyder Lee }; 316dc877523SRyder Lee 317d71ef286SFelix Fietkau enum mt76_wcid_flags { 318d71ef286SFelix Fietkau MT_WCID_FLAG_CHECK_PS, 319d71ef286SFelix Fietkau MT_WCID_FLAG_PS, 320e151d71eSFelix Fietkau MT_WCID_FLAG_4ADDR, 32190e3abf0SFelix Fietkau MT_WCID_FLAG_HDR_TRANS, 322d71ef286SFelix Fietkau }; 323d71ef286SFelix Fietkau 3246b733f7cSShayne Chen #define MT76_N_WCIDS 1088 32536404c06SStanislaw Gruszka 326e394b575SFelix Fietkau /* stored in ieee80211_tx_info::hw_queue */ 327a062f001SLorenzo Bianconi #define MT_TX_HW_QUEUE_PHY GENMASK(3, 2) 328e394b575SFelix Fietkau 329ef13edc0SFelix Fietkau DECLARE_EWMA(signal, 10, 8); 330ef13edc0SFelix Fietkau 331db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_RATE GENMASK(15, 0) 332db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_NSS GENMASK(17, 16) 333db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_TXPWR_ADJ GENMASK(25, 18) 334db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_SET BIT(31) 335db9f11d3SFelix Fietkau 33617f1de56SFelix Fietkau struct mt76_wcid { 337aee5b8cfSFelix Fietkau struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS]; 338aee5b8cfSFelix Fietkau 339e1378e52SFelix Fietkau atomic_t non_aql_packets; 340d71ef286SFelix Fietkau unsigned long flags; 341d71ef286SFelix Fietkau 342ef13edc0SFelix Fietkau struct ewma_signal rssi; 343ef13edc0SFelix Fietkau int inactive_count; 344ef13edc0SFelix Fietkau 3459908d98aSRyder Lee struct rate_info rate; 346ef591d74SLorenzo Bianconi unsigned long ampdu_state; 3479908d98aSRyder Lee 34849e649c3SRyder Lee u16 idx; 34917f1de56SFelix Fietkau u8 hw_key_idx; 350730d6d0dSFelix Fietkau u8 hw_key_idx2; 35117f1de56SFelix Fietkau 3529c68a57bSFelix Fietkau u8 sta:1; 35333eb14f1SFelix Fietkau u8 sta_disabled:1; 354b443e55fSRyder Lee u8 amsdu:1; 355a1a99d7bSLorenzo Bianconi u8 phy_idx:2; 35600e1ca0cSSean Wang u8 link_id:4; 3574f0f33d2SSean Wang bool link_valid; 3589c68a57bSFelix Fietkau 35930ce7f44SFelix Fietkau u8 rx_check_pn; 360a1b0bbd4SXing Song u8 rx_key_pn[IEEE80211_NUM_TIDS + 1][6]; 36101cfc1b4SLorenzo Bianconi u16 cipher; 36230ce7f44SFelix Fietkau 363db9f11d3SFelix Fietkau u32 tx_info; 36423405236SFelix Fietkau bool sw_iv; 36588046b2cSFelix Fietkau 3660335c034SFelix Fietkau struct list_head tx_list; 3670335c034SFelix Fietkau struct sk_buff_head tx_pending; 3680b3be9d1SFelix Fietkau struct sk_buff_head tx_offchannel; 3690335c034SFelix Fietkau 370bd1e3e7bSLorenzo Bianconi struct list_head list; 371bd1e3e7bSLorenzo Bianconi struct idr pktid; 372dc877523SRyder Lee 373dc877523SRyder Lee struct mt76_sta_stats stats; 374b73e1d92SLorenzo Bianconi 375b73e1d92SLorenzo Bianconi struct list_head poll_list; 376b1d21403SSean Wang 377b1d21403SSean Wang struct mt76_wcid *def_wcid; 37817f1de56SFelix Fietkau }; 37917f1de56SFelix Fietkau 38017f1de56SFelix Fietkau struct mt76_txq { 38151fb1278SFelix Fietkau u16 wcid; 38217f1de56SFelix Fietkau 38317f1de56SFelix Fietkau u16 agg_ssn; 38417f1de56SFelix Fietkau bool send_bar; 38517f1de56SFelix Fietkau bool aggr; 38617f1de56SFelix Fietkau }; 38717f1de56SFelix Fietkau 388950d0abbSBo Jiao struct mt76_wed_rro_ind { 389950d0abbSBo Jiao u32 se_id : 12; 390950d0abbSBo Jiao u32 rsv : 4; 391950d0abbSBo Jiao u32 start_sn : 12; 392950d0abbSBo Jiao u32 ind_reason : 4; 393950d0abbSBo Jiao u32 ind_cnt : 13; 394950d0abbSBo Jiao u32 win_sz : 3; 395950d0abbSBo Jiao u32 rsv2 : 13; 396950d0abbSBo Jiao u32 magic_cnt : 3; 397950d0abbSBo Jiao }; 398950d0abbSBo Jiao 39917f1de56SFelix Fietkau struct mt76_txwi_cache { 40017f1de56SFelix Fietkau struct list_head list; 401f3950a41SLorenzo Bianconi dma_addr_t dma_addr; 4026ca66722SLorenzo Bianconi 4032666beceSSujuan Chen union { 4046ca66722SLorenzo Bianconi struct sk_buff *skb; 4052666beceSSujuan Chen void *ptr; 4062666beceSSujuan Chen }; 40717f1de56SFelix Fietkau }; 40817f1de56SFelix Fietkau 409aee5b8cfSFelix Fietkau struct mt76_rx_tid { 410aee5b8cfSFelix Fietkau struct rcu_head rcu_head; 411aee5b8cfSFelix Fietkau 412aee5b8cfSFelix Fietkau struct mt76_dev *dev; 413aee5b8cfSFelix Fietkau 414aee5b8cfSFelix Fietkau spinlock_t lock; 415aee5b8cfSFelix Fietkau struct delayed_work reorder_work; 416aee5b8cfSFelix Fietkau 417a5d028d6SLorenzo Bianconi u16 id; 418aee5b8cfSFelix Fietkau u16 head; 4197c4f744dSRyder Lee u16 size; 4207c4f744dSRyder Lee u16 nframes; 421aee5b8cfSFelix Fietkau 422e7ec563eSMarkus Theil u8 num; 423e7ec563eSMarkus Theil 424aee5b8cfSFelix Fietkau u8 started:1, stopped:1, timer_pending:1; 425aee5b8cfSFelix Fietkau 426bd94d501SKees Cook struct sk_buff *reorder_buf[] __counted_by(size); 427aee5b8cfSFelix Fietkau }; 428aee5b8cfSFelix Fietkau 42988046b2cSFelix Fietkau #define MT_TX_CB_DMA_DONE BIT(0) 43088046b2cSFelix Fietkau #define MT_TX_CB_TXS_DONE BIT(1) 43188046b2cSFelix Fietkau #define MT_TX_CB_TXS_FAILED BIT(2) 43288046b2cSFelix Fietkau 4338548c6ebSFelix Fietkau #define MT_PACKET_ID_MASK GENMASK(6, 0) 434013b2dffSFelix Fietkau #define MT_PACKET_ID_NO_ACK 0 435013b2dffSFelix Fietkau #define MT_PACKET_ID_NO_SKB 1 43643eaa368SRyder Lee #define MT_PACKET_ID_WED 2 43743eaa368SRyder Lee #define MT_PACKET_ID_FIRST 3 4388548c6ebSFelix Fietkau #define MT_PACKET_ID_HAS_RATE BIT(7) 439c4a784e3SLorenzo Bianconi /* This is timer for when to give up when waiting for TXS callback, 440c4a784e3SLorenzo Bianconi * with starting time being the time at which the DMA_DONE callback 441c4a784e3SLorenzo Bianconi * was seen (so, we know packet was processed then, it should not take 442c4a784e3SLorenzo Bianconi * long after that for firmware to send the TXS callback if it is going 443c4a784e3SLorenzo Bianconi * to do so.) 444c4a784e3SLorenzo Bianconi */ 445c4a784e3SLorenzo Bianconi #define MT_TX_STATUS_SKB_TIMEOUT (HZ / 4) 44688046b2cSFelix Fietkau 44788046b2cSFelix Fietkau struct mt76_tx_cb { 44888046b2cSFelix Fietkau unsigned long jiffies; 44949e649c3SRyder Lee u16 wcid; 45088046b2cSFelix Fietkau u8 pktid; 45188046b2cSFelix Fietkau u8 flags; 45288046b2cSFelix Fietkau }; 45388046b2cSFelix Fietkau 45417f1de56SFelix Fietkau enum { 45517f1de56SFelix Fietkau MT76_STATE_INITIALIZED, 45641130c32SLorenzo Bianconi MT76_STATE_REGISTERED, 45717f1de56SFelix Fietkau MT76_STATE_RUNNING, 45887e022deSStanislaw Gruszka MT76_STATE_MCU_RUNNING, 45917f1de56SFelix Fietkau MT76_SCANNING, 460fcdfc29eSLorenzo Bianconi MT76_HW_SCANNING, 46120305f98SLorenzo Bianconi MT76_HW_SCHED_SCANNING, 462fd6c2dfaSFelix Fietkau MT76_RESTART, 46317f1de56SFelix Fietkau MT76_RESET, 46461c4fa72SFelix Fietkau MT76_MCU_RESET, 465b40b15e1SLorenzo Bianconi MT76_REMOVED, 466b40b15e1SLorenzo Bianconi MT76_READING_STATS, 467eb99cc95SLorenzo Bianconi MT76_STATE_POWER_OFF, 468c6bf2010SLorenzo Bianconi MT76_STATE_SUSPEND, 4697307f296SLorenzo Bianconi MT76_STATE_ROC, 47008523a2aSLorenzo Bianconi MT76_STATE_PM, 47136b7fce1SLorenzo Bianconi MT76_STATE_WED_RESET, 47217f1de56SFelix Fietkau }; 47317f1de56SFelix Fietkau 47417b0f68aSFelix Fietkau enum mt76_sta_event { 47517b0f68aSFelix Fietkau MT76_STA_EVENT_ASSOC, 47617b0f68aSFelix Fietkau MT76_STA_EVENT_AUTHORIZE, 47717b0f68aSFelix Fietkau MT76_STA_EVENT_DISASSOC, 47817b0f68aSFelix Fietkau }; 47917b0f68aSFelix Fietkau 48017f1de56SFelix Fietkau struct mt76_hw_cap { 48117f1de56SFelix Fietkau bool has_2ghz; 48217f1de56SFelix Fietkau bool has_5ghz; 483f7d2958cSLorenzo Bianconi bool has_6ghz; 48417f1de56SFelix Fietkau }; 48517f1de56SFelix Fietkau 4869ec0b821SFelix Fietkau #define MT_DRV_TXWI_NO_FREE BIT(0) 4879ec0b821SFelix Fietkau #define MT_DRV_TX_ALIGNED4_SKBS BIT(1) 4885ce09c1aSFelix Fietkau #define MT_DRV_SW_RX_AIRTIME BIT(2) 48994d4d076SLorenzo Bianconi #define MT_DRV_RX_DMA_HDR BIT(3) 490d3c82998SLorenzo Bianconi #define MT_DRV_HW_MGMT_TXQ BIT(4) 4915b0fb852SBen Greear #define MT_DRV_AMSDU_OFFLOAD BIT(5) 4926ca66722SLorenzo Bianconi 49317f1de56SFelix Fietkau struct mt76_driver_ops { 4949ec0b821SFelix Fietkau u32 drv_flags; 495ea565833SFelix Fietkau u32 survey_flags; 49617f1de56SFelix Fietkau u16 txwi_size; 497d089692bSLorenzo Bianconi u16 token_size; 49822b980baSFelix Fietkau u8 mcs_rates; 49917f1de56SFelix Fietkau 500c560b137SRyder Lee void (*update_survey)(struct mt76_phy *phy); 501f4fdd771SFelix Fietkau int (*set_channel)(struct mt76_phy *phy); 50217f1de56SFelix Fietkau 50317f1de56SFelix Fietkau int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr, 504cfaae9e6SLorenzo Bianconi enum mt76_txq_id qid, struct mt76_wcid *wcid, 505b5903c47SLorenzo Bianconi struct ieee80211_sta *sta, 506b5903c47SLorenzo Bianconi struct mt76_tx_info *tx_info); 50717f1de56SFelix Fietkau 508d80e52c7SFelix Fietkau void (*tx_complete_skb)(struct mt76_dev *dev, 509e226ba2eSLorenzo Bianconi struct mt76_queue_entry *e); 51017f1de56SFelix Fietkau 511b40b15e1SLorenzo Bianconi bool (*tx_status_data)(struct mt76_dev *dev, u8 *update); 512b40b15e1SLorenzo Bianconi 513fbe50d9aSFelix Fietkau bool (*rx_check)(struct mt76_dev *dev, void *data, int len); 514fbe50d9aSFelix Fietkau 51517f1de56SFelix Fietkau void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q, 516c3137942SSujuan Chen struct sk_buff *skb, u32 *info); 51717f1de56SFelix Fietkau 51817f1de56SFelix Fietkau void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q); 519d71ef286SFelix Fietkau 520d71ef286SFelix Fietkau void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta, 521d71ef286SFelix Fietkau bool ps); 522e28487eaSFelix Fietkau 523e28487eaSFelix Fietkau int (*sta_add)(struct mt76_dev *dev, struct ieee80211_vif *vif, 524e28487eaSFelix Fietkau struct ieee80211_sta *sta); 525e28487eaSFelix Fietkau 52617b0f68aSFelix Fietkau int (*sta_event)(struct mt76_dev *dev, struct ieee80211_vif *vif, 52717b0f68aSFelix Fietkau struct ieee80211_sta *sta, enum mt76_sta_event ev); 5289c193de5SFelix Fietkau 529e28487eaSFelix Fietkau void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif, 530e28487eaSFelix Fietkau struct ieee80211_sta *sta); 53117f1de56SFelix Fietkau }; 53217f1de56SFelix Fietkau 53317f1de56SFelix Fietkau struct mt76_channel_state { 53417f1de56SFelix Fietkau u64 cc_active; 53517f1de56SFelix Fietkau u64 cc_busy; 5366bfa6e38SLorenzo Bianconi u64 cc_rx; 5375ce09c1aSFelix Fietkau u64 cc_bss_rx; 538ea565833SFelix Fietkau u64 cc_tx; 539e5051965SFelix Fietkau 540e5051965SFelix Fietkau s8 noise; 54117f1de56SFelix Fietkau }; 54217f1de56SFelix Fietkau 54317f1de56SFelix Fietkau struct mt76_sband { 54417f1de56SFelix Fietkau struct ieee80211_supported_band sband; 54517f1de56SFelix Fietkau struct mt76_channel_state *chan; 54617f1de56SFelix Fietkau }; 54717f1de56SFelix Fietkau 548b40b15e1SLorenzo Bianconi /* addr req mask */ 549b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_EEPROM BIT(31) 550b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_CFG BIT(30) 551b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_MASK (MT_VEND_TYPE_EEPROM | MT_VEND_TYPE_CFG) 552b40b15e1SLorenzo Bianconi 553b40b15e1SLorenzo Bianconi #define MT_VEND_ADDR(type, n) (MT_VEND_TYPE_##type | (n)) 554b40b15e1SLorenzo Bianconi enum mt_vendor_req { 555b40b15e1SLorenzo Bianconi MT_VEND_DEV_MODE = 0x1, 556b40b15e1SLorenzo Bianconi MT_VEND_WRITE = 0x2, 5571e816c65SLorenzo Bianconi MT_VEND_POWER_ON = 0x4, 558b40b15e1SLorenzo Bianconi MT_VEND_MULTI_WRITE = 0x6, 559b40b15e1SLorenzo Bianconi MT_VEND_MULTI_READ = 0x7, 560b40b15e1SLorenzo Bianconi MT_VEND_READ_EEPROM = 0x9, 561b40b15e1SLorenzo Bianconi MT_VEND_WRITE_FCE = 0x42, 562b40b15e1SLorenzo Bianconi MT_VEND_WRITE_CFG = 0x46, 563b40b15e1SLorenzo Bianconi MT_VEND_READ_CFG = 0x47, 5641e816c65SLorenzo Bianconi MT_VEND_READ_EXT = 0x63, 5651e816c65SLorenzo Bianconi MT_VEND_WRITE_EXT = 0x66, 566d0846f08SSean Wang MT_VEND_FEATURE_SET = 0x91, 567b40b15e1SLorenzo Bianconi }; 568b40b15e1SLorenzo Bianconi 569b40b15e1SLorenzo Bianconi enum mt76u_in_ep { 570b40b15e1SLorenzo Bianconi MT_EP_IN_PKT_RX, 571b40b15e1SLorenzo Bianconi MT_EP_IN_CMD_RESP, 572b40b15e1SLorenzo Bianconi __MT_EP_IN_MAX, 573b40b15e1SLorenzo Bianconi }; 574b40b15e1SLorenzo Bianconi 575b40b15e1SLorenzo Bianconi enum mt76u_out_ep { 576b40b15e1SLorenzo Bianconi MT_EP_OUT_INBAND_CMD, 577b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_BE, 57823cb16d2SLorenzo Bianconi MT_EP_OUT_AC_BK, 579b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_VI, 580b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_VO, 581b40b15e1SLorenzo Bianconi MT_EP_OUT_HCCA, 582b40b15e1SLorenzo Bianconi __MT_EP_OUT_MAX, 583b40b15e1SLorenzo Bianconi }; 584b40b15e1SLorenzo Bianconi 58509872957SLorenzo Bianconi struct mt76_mcu { 58609872957SLorenzo Bianconi struct mutex mutex; 58709872957SLorenzo Bianconi u32 msg_seq; 588e452c6ebSFelix Fietkau int timeout; 58909872957SLorenzo Bianconi 59009872957SLorenzo Bianconi struct sk_buff_head res_q; 59109872957SLorenzo Bianconi wait_queue_head_t wait; 59209872957SLorenzo Bianconi }; 59309872957SLorenzo Bianconi 59414663f0cSLorenzo Bianconi #define MT_TX_SG_MAX_SIZE 8 595972c5981SSean Wang #define MT_RX_SG_MAX_SIZE 4 596b40b15e1SLorenzo Bianconi #define MT_NUM_TX_ENTRIES 256 597b40b15e1SLorenzo Bianconi #define MT_NUM_RX_ENTRIES 128 598b40b15e1SLorenzo Bianconi #define MCU_RESP_URB_SIZE 1024 599b40b15e1SLorenzo Bianconi struct mt76_usb { 600b40b15e1SLorenzo Bianconi struct mutex usb_ctrl_mtx; 601a6bfb6d1SStanislaw Gruszka u8 *data; 602a6bfb6d1SStanislaw Gruszka u16 data_len; 603b40b15e1SLorenzo Bianconi 6049daf27e6SLorenzo Bianconi struct mt76_worker status_worker; 605be83a7e2SLorenzo Bianconi struct mt76_worker rx_worker; 6069daf27e6SLorenzo Bianconi 607284efb47SLorenzo Bianconi struct work_struct stat_work; 608b40b15e1SLorenzo Bianconi 609b40b15e1SLorenzo Bianconi u8 out_ep[__MT_EP_OUT_MAX]; 610b40b15e1SLorenzo Bianconi u8 in_ep[__MT_EP_IN_MAX]; 61163a7de5dSLorenzo Bianconi bool sg_en; 612b40b15e1SLorenzo Bianconi 613b40b15e1SLorenzo Bianconi struct mt76u_mcu { 614a18a494fSStanislaw Gruszka u8 *data; 615851ab66eSLorenzo Bianconi /* multiple reads */ 616851ab66eSLorenzo Bianconi struct mt76_reg_pair *rp; 617851ab66eSLorenzo Bianconi int rp_len; 618851ab66eSLorenzo Bianconi u32 base; 619b40b15e1SLorenzo Bianconi } mcu; 620b40b15e1SLorenzo Bianconi }; 621b40b15e1SLorenzo Bianconi 622bf08d585SSean Wang #define MT76S_XMIT_BUF_SZ 0x3fe00 623b1460bb4SDeren Wu #define MT76S_NUM_TX_ENTRIES 256 624b1460bb4SDeren Wu #define MT76S_NUM_RX_ENTRIES 512 625d39b52e3SSean Wang struct mt76_sdio { 626fefb584dSLorenzo Bianconi struct mt76_worker txrx_worker; 6276a618acbSLorenzo Bianconi struct mt76_worker status_worker; 6286a618acbSLorenzo Bianconi struct mt76_worker net_worker; 62992184eaeSWang Zhao struct mt76_worker stat_worker; 630974327a4SLorenzo Bianconi 631bf08d585SSean Wang u8 *xmit_buf; 632bf08d585SSean Wang u32 xmit_buf_sz; 6331522ff73SLorenzo Bianconi 634d39b52e3SSean Wang struct sdio_func *func; 635b4964908SSean Wang void *intr_data; 636dacf0acfSSean Wang u8 hw_ver; 637ca74b9b9SSean Wang wait_queue_head_t wait; 638d39b52e3SSean Wang 639fbce6136SLeon Yen int pse_mcu_quota_max; 640d39b52e3SSean Wang struct { 641d39b52e3SSean Wang int pse_data_quota; 642d39b52e3SSean Wang int ple_data_quota; 643d39b52e3SSean Wang int pse_mcu_quota; 6448c94f0e6SSean Wang int pse_page_size; 645d39b52e3SSean Wang int deficit; 646d39b52e3SSean Wang } sched; 6473ad08509SLorenzo Bianconi 6483ad08509SLorenzo Bianconi int (*parse_irq)(struct mt76_dev *dev, struct mt76s_intr *intr); 649d39b52e3SSean Wang }; 650d39b52e3SSean Wang 651f7bbb80fSLorenzo Bianconi struct mt76_mmio { 65227db1ad1SLorenzo Bianconi void __iomem *regs; 653957068c2SLorenzo Bianconi spinlock_t irq_lock; 654957068c2SLorenzo Bianconi u32 irqmask; 655f68d6762SFelix Fietkau 656f68d6762SFelix Fietkau struct mtk_wed_device wed; 65783eafc92SSujuan Chen struct mtk_wed_device wed_hif2; 65836b7fce1SLorenzo Bianconi struct completion wed_reset; 65936b7fce1SLorenzo Bianconi struct completion wed_reset_complete; 660f7bbb80fSLorenzo Bianconi }; 661f7bbb80fSLorenzo Bianconi 6625ce09c1aSFelix Fietkau struct mt76_rx_status { 6635ce09c1aSFelix Fietkau union { 6645ce09c1aSFelix Fietkau struct mt76_wcid *wcid; 66549e649c3SRyder Lee u16 wcid_idx; 6665ce09c1aSFelix Fietkau }; 6675ce09c1aSFelix Fietkau 6680fda6d7bSRyder Lee u32 reorder_time; 6695ce09c1aSFelix Fietkau 6705ce09c1aSFelix Fietkau u32 ampdu_ref; 6710fda6d7bSRyder Lee u32 timestamp; 6725ce09c1aSFelix Fietkau 6735ce09c1aSFelix Fietkau u8 iv[6]; 6745ce09c1aSFelix Fietkau 675128c9b7dSLorenzo Bianconi u8 phy_idx:2; 6765ce09c1aSFelix Fietkau u8 aggr:1; 677e195dad1SFelix Fietkau u8 qos_ctl; 6785ce09c1aSFelix Fietkau u16 seqno; 6795ce09c1aSFelix Fietkau 6805ce09c1aSFelix Fietkau u16 freq; 6815ce09c1aSFelix Fietkau u32 flag; 6825ce09c1aSFelix Fietkau u8 enc_flags; 683021af945SShayne Chen u8 encoding:3, bw:4; 684021af945SShayne Chen union { 685021af945SShayne Chen struct { 686021af945SShayne Chen u8 he_ru:3; 687021af945SShayne Chen u8 he_gi:2; 688021af945SShayne Chen u8 he_dcm:1; 689021af945SShayne Chen }; 690021af945SShayne Chen struct { 691021af945SShayne Chen u8 ru:4; 692021af945SShayne Chen u8 gi:2; 693021af945SShayne Chen } eht; 694021af945SShayne Chen }; 695021af945SShayne Chen 696cc4b3c13SLorenzo Bianconi u8 amsdu:1, first_amsdu:1, last_amsdu:1; 6975ce09c1aSFelix Fietkau u8 rate_idx; 698021af945SShayne Chen u8 nss:5, band:3; 6995ce09c1aSFelix Fietkau s8 signal; 7005ce09c1aSFelix Fietkau u8 chains; 7015ce09c1aSFelix Fietkau s8 chain_signal[IEEE80211_MAX_CHAINS]; 7025ce09c1aSFelix Fietkau }; 7035ce09c1aSFelix Fietkau 704502604f5SYN Chen struct mt76_freq_range_power { 705502604f5SYN Chen const struct cfg80211_sar_freq_ranges *range; 706502604f5SYN Chen s8 power; 707502604f5SYN Chen }; 708502604f5SYN Chen 709f0efa862SFelix Fietkau struct mt76_testmode_ops { 710c918c74dSShayne Chen int (*set_state)(struct mt76_phy *phy, enum mt76_testmode_state state); 711c918c74dSShayne Chen int (*set_params)(struct mt76_phy *phy, struct nlattr **tb, 712f0efa862SFelix Fietkau enum mt76_testmode_state new_state); 713c918c74dSShayne Chen int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg); 714f0efa862SFelix Fietkau }; 715f0efa862SFelix Fietkau 716f0efa862SFelix Fietkau struct mt76_testmode_data { 717f0efa862SFelix Fietkau enum mt76_testmode_state state; 718f0efa862SFelix Fietkau 719f0efa862SFelix Fietkau u32 param_set[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)]; 720f0efa862SFelix Fietkau struct sk_buff *tx_skb; 721f0efa862SFelix Fietkau 722f0efa862SFelix Fietkau u32 tx_count; 7232601dda8SShayne Chen u16 tx_mpdu_len; 724f0efa862SFelix Fietkau 725f0efa862SFelix Fietkau u8 tx_rate_mode; 726f0efa862SFelix Fietkau u8 tx_rate_idx; 727f0efa862SFelix Fietkau u8 tx_rate_nss; 728f0efa862SFelix Fietkau u8 tx_rate_sgi; 729f0efa862SFelix Fietkau u8 tx_rate_ldpc; 7307f54c742SShayne Chen u8 tx_rate_stbc; 7311a38c2f5SShayne Chen u8 tx_ltf; 732f0efa862SFelix Fietkau 733f0efa862SFelix Fietkau u8 tx_antenna_mask; 734fdc9c18eSShayne Chen u8 tx_spe_idx; 735f0efa862SFelix Fietkau 736b8cbdb97SShayne Chen u8 tx_duty_cycle; 737b8cbdb97SShayne Chen u32 tx_time; 738b8cbdb97SShayne Chen u32 tx_ipg; 739b8cbdb97SShayne Chen 740f0efa862SFelix Fietkau u32 freq_offset; 741f0efa862SFelix Fietkau 742f0efa862SFelix Fietkau u8 tx_power[4]; 743f0efa862SFelix Fietkau u8 tx_power_control; 744f0efa862SFelix Fietkau 745c40b42c2SShayne Chen u8 addr[3][ETH_ALEN]; 746c40b42c2SShayne Chen 747f0efa862SFelix Fietkau u32 tx_pending; 748f0efa862SFelix Fietkau u32 tx_queued; 749ba459094SShayne Chen u16 tx_queued_limit; 750f0efa862SFelix Fietkau u32 tx_done; 751f0efa862SFelix Fietkau struct { 752f0efa862SFelix Fietkau u64 packets[__MT_RXQ_MAX]; 753f0efa862SFelix Fietkau u64 fcs_error[__MT_RXQ_MAX]; 754f0efa862SFelix Fietkau } rx_stats; 755f0efa862SFelix Fietkau }; 756f0efa862SFelix Fietkau 75785d96704SLorenzo Bianconi struct mt76_vif { 75885d96704SLorenzo Bianconi u8 idx; 75985d96704SLorenzo Bianconi u8 omac_idx; 76085d96704SLorenzo Bianconi u8 band_idx; 76185d96704SLorenzo Bianconi u8 wmm_idx; 76285d96704SLorenzo Bianconi u8 scan_seq_num; 7635ea3d983SFelix Fietkau u8 cipher; 7640cb065b9SLorenzo Bianconi u8 basic_rates_idx; 7650cb065b9SLorenzo Bianconi u8 mcast_rates_idx; 7660cb065b9SLorenzo Bianconi u8 beacon_rates_idx; 767f5020655SSean Wang struct ieee80211_chanctx_conf *ctx; 768*31083e38SFelix Fietkau struct mt76_wcid *wcid; 76985d96704SLorenzo Bianconi }; 77085d96704SLorenzo Bianconi 771ac24dd35SFelix Fietkau struct mt76_phy { 772ac24dd35SFelix Fietkau struct ieee80211_hw *hw; 773ac24dd35SFelix Fietkau struct mt76_dev *dev; 774a3d01038SFelix Fietkau void *priv; 77596747a51SFelix Fietkau 776011849e0SFelix Fietkau unsigned long state; 777*31083e38SFelix Fietkau unsigned int num_sta; 778dc44c45cSLorenzo Bianconi u8 band_idx; 779011849e0SFelix Fietkau 7800335c034SFelix Fietkau spinlock_t tx_lock; 7810335c034SFelix Fietkau struct list_head tx_list; 78291990519SLorenzo Bianconi struct mt76_queue *q_tx[__MT_TXQ_MAX]; 78391990519SLorenzo Bianconi 78496747a51SFelix Fietkau struct cfg80211_chan_def chandef; 785*31083e38SFelix Fietkau struct cfg80211_chan_def main_chandef; 786f4fdd771SFelix Fietkau bool offchannel; 78796747a51SFelix Fietkau 78896747a51SFelix Fietkau struct mt76_channel_state *chan_state; 7893f306448SFelix Fietkau enum mt76_dfs_state dfs_state; 79096747a51SFelix Fietkau ktime_t survey_time; 79196747a51SFelix Fietkau 792d107501aSLorenzo Bianconi u32 aggr_stats[32]; 793d107501aSLorenzo Bianconi 79448dbce5cSLorenzo Bianconi struct mt76_hw_cap cap; 79596747a51SFelix Fietkau struct mt76_sband sband_2g; 79696747a51SFelix Fietkau struct mt76_sband sband_5g; 797cee3fd29SLorenzo Bianconi struct mt76_sband sband_6g; 798beaaeb6bSFelix Fietkau 79998df2baeSLorenzo Bianconi u8 macaddr[ETH_ALEN]; 80098df2baeSLorenzo Bianconi 801beaaeb6bSFelix Fietkau int txpower_cur; 802beaaeb6bSFelix Fietkau u8 antenna_mask; 803b9027e08SLorenzo Bianconi u16 chainmask; 804c918c74dSShayne Chen 805c918c74dSShayne Chen #ifdef CONFIG_NL80211_TESTMODE 806c918c74dSShayne Chen struct mt76_testmode_data test; 807c918c74dSShayne Chen #endif 808a782f8bfSLorenzo Bianconi 809a782f8bfSLorenzo Bianconi struct delayed_work mac_work; 810a782f8bfSLorenzo Bianconi u8 mac_work_count; 811cc4b3c13SLorenzo Bianconi 812cc4b3c13SLorenzo Bianconi struct { 813cc4b3c13SLorenzo Bianconi struct sk_buff *head; 814cc4b3c13SLorenzo Bianconi struct sk_buff **tail; 815cc4b3c13SLorenzo Bianconi u16 seqno; 816cc4b3c13SLorenzo Bianconi } rx_amsdu[__MT_RXQ_MAX]; 817502604f5SYN Chen 818502604f5SYN Chen struct mt76_freq_range_power *frp; 8193abd46ddSLorenzo Bianconi 8203abd46ddSLorenzo Bianconi struct { 8213abd46ddSLorenzo Bianconi struct led_classdev cdev; 8223abd46ddSLorenzo Bianconi char name[32]; 8233abd46ddSLorenzo Bianconi bool al; 8243abd46ddSLorenzo Bianconi u8 pin; 8253abd46ddSLorenzo Bianconi } leds; 826ac24dd35SFelix Fietkau }; 827ac24dd35SFelix Fietkau 82817f1de56SFelix Fietkau struct mt76_dev { 829ac24dd35SFelix Fietkau struct mt76_phy phy; /* must be first */ 830dc44c45cSLorenzo Bianconi struct mt76_phy *phys[__MT_MAX_BAND]; 831bfc394ddSFelix Fietkau 83217f1de56SFelix Fietkau struct ieee80211_hw *hw; 83317f1de56SFelix Fietkau 8342666beceSSujuan Chen spinlock_t wed_lock; 83517f1de56SFelix Fietkau spinlock_t lock; 83617f1de56SFelix Fietkau spinlock_t cc_lock; 837108a4861SStanislaw Gruszka 8385ce09c1aSFelix Fietkau u32 cur_cc_bss_rx; 8395ce09c1aSFelix Fietkau 8405ce09c1aSFelix Fietkau struct mt76_rx_status rx_ampdu_status; 8415ce09c1aSFelix Fietkau u32 rx_ampdu_len; 8425ce09c1aSFelix Fietkau u32 rx_ampdu_ref; 8435ce09c1aSFelix Fietkau 844108a4861SStanislaw Gruszka struct mutex mutex; 845108a4861SStanislaw Gruszka 84617f1de56SFelix Fietkau const struct mt76_bus_ops *bus; 84717f1de56SFelix Fietkau const struct mt76_driver_ops *drv; 848db0f04f3SLorenzo Bianconi const struct mt76_mcu_ops *mcu_ops; 84917f1de56SFelix Fietkau struct device *dev; 850d1ddc536SFelix Fietkau struct device *dma_dev; 85117f1de56SFelix Fietkau 85209872957SLorenzo Bianconi struct mt76_mcu mcu; 85309872957SLorenzo Bianconi 85408f116c9SBreno Leitao struct net_device *napi_dev; 85508f116c9SBreno Leitao struct net_device *tx_napi_dev; 856c3d7c82aSFelix Fietkau spinlock_t rx_lock; 85717f1de56SFelix Fietkau struct napi_struct napi[__MT_RXQ_MAX]; 85817f1de56SFelix Fietkau struct sk_buff_head rx_skb[__MT_RXQ_MAX]; 859ec193b41SLorenzo Bianconi struct tasklet_struct irq_tasklet; 86017f1de56SFelix Fietkau 86117f1de56SFelix Fietkau struct list_head txwi_cache; 8622666beceSSujuan Chen struct list_head rxwi_cache; 863b1cb42adSLorenzo Bianconi struct mt76_queue *q_mcu[__MT_MCUQ_MAX]; 86417f1de56SFelix Fietkau struct mt76_queue q_rx[__MT_RXQ_MAX]; 86517f1de56SFelix Fietkau const struct mt76_queue_ops *queue_ops; 866c1e0d2beSLorenzo Bianconi int tx_dma_idx[4]; 86717f1de56SFelix Fietkau 868781eef5bSFelix Fietkau struct mt76_worker tx_worker; 8698402650aSLorenzo Bianconi struct napi_struct tx_napi; 870a33b8ab8SFelix Fietkau 871b17aff33SLorenzo Bianconi spinlock_t token_lock; 872b17aff33SLorenzo Bianconi struct idr token; 873f68d6762SFelix Fietkau u16 wed_token_count; 87461b5156bSFelix Fietkau u16 token_count; 87561b5156bSFelix Fietkau u16 token_size; 876b17aff33SLorenzo Bianconi 8772666beceSSujuan Chen spinlock_t rx_token_lock; 8782666beceSSujuan Chen struct idr rx_token; 8792666beceSSujuan Chen u16 rx_token_size; 8802666beceSSujuan Chen 88126e40d4cSFelix Fietkau wait_queue_head_t tx_wait; 882c34f1005SLorenzo Bianconi /* spinclock used to protect wcid pktid linked list */ 883c34f1005SLorenzo Bianconi spinlock_t status_lock; 88426e40d4cSFelix Fietkau 8855e616ad2SFelix Fietkau u32 wcid_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; 8865e616ad2SFelix Fietkau u32 wcid_phy_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; 88736404c06SStanislaw Gruszka 888b619e013SEvelyn Tsai u64 vif_mask; 8892ab33b8dSFelix Fietkau 89036404c06SStanislaw Gruszka struct mt76_wcid global_wcid; 89136404c06SStanislaw Gruszka struct mt76_wcid __rcu *wcid[MT76_N_WCIDS]; 892bd1e3e7bSLorenzo Bianconi struct list_head wcid_list; 89336404c06SStanislaw Gruszka 894fbba711cSLorenzo Bianconi struct list_head sta_poll_list; 895fbba711cSLorenzo Bianconi spinlock_t sta_poll_lock; 896fbba711cSLorenzo Bianconi 89717f1de56SFelix Fietkau u32 rev; 89817f1de56SFelix Fietkau 899dc6057f4SLorenzo Bianconi struct tasklet_struct pre_tbtt_tasklet; 9003041c445SLorenzo Bianconi int beacon_int; 901c8a04d98SLorenzo Bianconi u8 beacon_mask; 9023041c445SLorenzo Bianconi 90317f1de56SFelix Fietkau struct debugfs_blob_wrapper eeprom; 90417f1de56SFelix Fietkau struct debugfs_blob_wrapper otp; 90517f1de56SFelix Fietkau 9065b257371SLorenzo Bianconi char alpha2[3]; 907d8b8890dSLorenzo Bianconi enum nl80211_dfs_regions region; 908d8b8890dSLorenzo Bianconi 90917f1de56SFelix Fietkau u32 debugfs_reg; 91017f1de56SFelix Fietkau 911e7173858SFelix Fietkau u8 csa_complete; 912e7173858SFelix Fietkau 913108a4861SStanislaw Gruszka u32 rxfilter; 914108a4861SStanislaw Gruszka 915*31083e38SFelix Fietkau struct delayed_work scan_work; 916*31083e38SFelix Fietkau struct { 917*31083e38SFelix Fietkau struct cfg80211_scan_request *req; 918*31083e38SFelix Fietkau struct ieee80211_channel *chan; 919*31083e38SFelix Fietkau struct ieee80211_vif *vif; 920*31083e38SFelix Fietkau struct mt76_phy *phy; 921*31083e38SFelix Fietkau int chan_idx; 922*31083e38SFelix Fietkau } scan; 923*31083e38SFelix Fietkau 924f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 925f0efa862SFelix Fietkau const struct mt76_testmode_ops *test_ops; 926e7a6a044SShayne Chen struct { 927e7a6a044SShayne Chen const char *name; 928e7a6a044SShayne Chen u32 offset; 929e7a6a044SShayne Chen } test_mtd; 930f0efa862SFelix Fietkau #endif 931a86f1d01SLorenzo Bianconi struct workqueue_struct *wq; 932a86f1d01SLorenzo Bianconi 933f7bbb80fSLorenzo Bianconi union { 934f7bbb80fSLorenzo Bianconi struct mt76_mmio mmio; 935b40b15e1SLorenzo Bianconi struct mt76_usb usb; 936d39b52e3SSean Wang struct mt76_sdio sdio; 93717f1de56SFelix Fietkau }; 938f7bbb80fSLorenzo Bianconi }; 93917f1de56SFelix Fietkau 9407f03a563SLorenzo Bianconi /* per-phy stats. */ 9417f03a563SLorenzo Bianconi struct mt76_mib_stats { 9427f03a563SLorenzo Bianconi u32 ack_fail_cnt; 9437f03a563SLorenzo Bianconi u32 fcs_err_cnt; 9447f03a563SLorenzo Bianconi u32 rts_cnt; 9457f03a563SLorenzo Bianconi u32 rts_retries_cnt; 9467f03a563SLorenzo Bianconi u32 ba_miss_cnt; 9477f03a563SLorenzo Bianconi u32 tx_bf_cnt; 9487f03a563SLorenzo Bianconi u32 tx_mu_bf_cnt; 9497f03a563SLorenzo Bianconi u32 tx_mu_mpdu_cnt; 9507f03a563SLorenzo Bianconi u32 tx_mu_acked_mpdu_cnt; 9517f03a563SLorenzo Bianconi u32 tx_su_acked_mpdu_cnt; 9527f03a563SLorenzo Bianconi u32 tx_bf_ibf_ppdu_cnt; 9537f03a563SLorenzo Bianconi u32 tx_bf_ebf_ppdu_cnt; 9547f03a563SLorenzo Bianconi 9557f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_all_cnt; 9567f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_eht_cnt; 9577f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_he_cnt; 9587f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_vht_cnt; 9597f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_ht_cnt; 9607f03a563SLorenzo Bianconi 9617f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */ 9627f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_nc_cnt; 9637f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_nr_cnt; 9647f03a563SLorenzo Bianconi u32 tx_bf_fb_cpl_cnt; 9657f03a563SLorenzo Bianconi u32 tx_bf_fb_trig_cnt; 9667f03a563SLorenzo Bianconi 9677f03a563SLorenzo Bianconi u32 tx_ampdu_cnt; 9687f03a563SLorenzo Bianconi u32 tx_stop_q_empty_cnt; 9697f03a563SLorenzo Bianconi u32 tx_mpdu_attempts_cnt; 9707f03a563SLorenzo Bianconi u32 tx_mpdu_success_cnt; 9717f03a563SLorenzo Bianconi u32 tx_pkt_ebf_cnt; 9727f03a563SLorenzo Bianconi u32 tx_pkt_ibf_cnt; 9737f03a563SLorenzo Bianconi 9747f03a563SLorenzo Bianconi u32 tx_rwp_fail_cnt; 9757f03a563SLorenzo Bianconi u32 tx_rwp_need_cnt; 9767f03a563SLorenzo Bianconi 9777f03a563SLorenzo Bianconi /* rx stats */ 9787f03a563SLorenzo Bianconi u32 rx_fifo_full_cnt; 9797f03a563SLorenzo Bianconi u32 channel_idle_cnt; 9807f03a563SLorenzo Bianconi u32 primary_cca_busy_time; 9817f03a563SLorenzo Bianconi u32 secondary_cca_busy_time; 9827f03a563SLorenzo Bianconi u32 primary_energy_detect_time; 9837f03a563SLorenzo Bianconi u32 cck_mdrdy_time; 9847f03a563SLorenzo Bianconi u32 ofdm_mdrdy_time; 9857f03a563SLorenzo Bianconi u32 green_mdrdy_time; 9867f03a563SLorenzo Bianconi u32 rx_vector_mismatch_cnt; 9877f03a563SLorenzo Bianconi u32 rx_delimiter_fail_cnt; 9887f03a563SLorenzo Bianconi u32 rx_mrdy_cnt; 9897f03a563SLorenzo Bianconi u32 rx_len_mismatch_cnt; 9907f03a563SLorenzo Bianconi u32 rx_mpdu_cnt; 9917f03a563SLorenzo Bianconi u32 rx_ampdu_cnt; 9927f03a563SLorenzo Bianconi u32 rx_ampdu_bytes_cnt; 9937f03a563SLorenzo Bianconi u32 rx_ampdu_valid_subframe_cnt; 9947f03a563SLorenzo Bianconi u32 rx_ampdu_valid_subframe_bytes_cnt; 9957f03a563SLorenzo Bianconi u32 rx_pfdrop_cnt; 9967f03a563SLorenzo Bianconi u32 rx_vec_queue_overflow_drop_cnt; 9977f03a563SLorenzo Bianconi u32 rx_ba_cnt; 9987f03a563SLorenzo Bianconi 9997f03a563SLorenzo Bianconi u32 tx_amsdu[8]; 10007f03a563SLorenzo Bianconi u32 tx_amsdu_cnt; 10011258c156SRyder Lee 10021258c156SRyder Lee /* mcu_muru_stats */ 10031258c156SRyder Lee u32 dl_cck_cnt; 10041258c156SRyder Lee u32 dl_ofdm_cnt; 10051258c156SRyder Lee u32 dl_htmix_cnt; 10061258c156SRyder Lee u32 dl_htgf_cnt; 10071258c156SRyder Lee u32 dl_vht_su_cnt; 10081258c156SRyder Lee u32 dl_vht_2mu_cnt; 10091258c156SRyder Lee u32 dl_vht_3mu_cnt; 10101258c156SRyder Lee u32 dl_vht_4mu_cnt; 10111258c156SRyder Lee u32 dl_he_su_cnt; 10121258c156SRyder Lee u32 dl_he_ext_su_cnt; 10131258c156SRyder Lee u32 dl_he_2ru_cnt; 10141258c156SRyder Lee u32 dl_he_2mu_cnt; 10151258c156SRyder Lee u32 dl_he_3ru_cnt; 10161258c156SRyder Lee u32 dl_he_3mu_cnt; 10171258c156SRyder Lee u32 dl_he_4ru_cnt; 10181258c156SRyder Lee u32 dl_he_4mu_cnt; 10191258c156SRyder Lee u32 dl_he_5to8ru_cnt; 10201258c156SRyder Lee u32 dl_he_9to16ru_cnt; 10211258c156SRyder Lee u32 dl_he_gtr16ru_cnt; 10221258c156SRyder Lee 10231258c156SRyder Lee u32 ul_hetrig_su_cnt; 10241258c156SRyder Lee u32 ul_hetrig_2ru_cnt; 10251258c156SRyder Lee u32 ul_hetrig_3ru_cnt; 10261258c156SRyder Lee u32 ul_hetrig_4ru_cnt; 10271258c156SRyder Lee u32 ul_hetrig_5to8ru_cnt; 10281258c156SRyder Lee u32 ul_hetrig_9to16ru_cnt; 10291258c156SRyder Lee u32 ul_hetrig_gtr16ru_cnt; 10301258c156SRyder Lee u32 ul_hetrig_2mu_cnt; 10311258c156SRyder Lee u32 ul_hetrig_3mu_cnt; 10321258c156SRyder Lee u32 ul_hetrig_4mu_cnt; 10337f03a563SLorenzo Bianconi }; 10347f03a563SLorenzo Bianconi 103522b980baSFelix Fietkau struct mt76_power_limits { 103622b980baSFelix Fietkau s8 cck[4]; 103722b980baSFelix Fietkau s8 ofdm[8]; 103822b980baSFelix Fietkau s8 mcs[4][10]; 1039a9627d99SShayne Chen s8 ru[7][12]; 1040975cd4d6SDeren Wu s8 eht[16][16]; 104122b980baSFelix Fietkau }; 104222b980baSFelix Fietkau 104354ae98ffSLorenzo Bianconi struct mt76_ethtool_worker_info { 104454ae98ffSLorenzo Bianconi u64 *data; 104554ae98ffSLorenzo Bianconi int idx; 104654ae98ffSLorenzo Bianconi int initial_stat_idx; 104754ae98ffSLorenzo Bianconi int worker_stat_count; 104854ae98ffSLorenzo Bianconi int sta_count; 104954ae98ffSLorenzo Bianconi }; 105054ae98ffSLorenzo Bianconi 105154b8fdebSLorenzo Bianconi #define CCK_RATE(_idx, _rate) { \ 105254b8fdebSLorenzo Bianconi .bitrate = _rate, \ 105354b8fdebSLorenzo Bianconi .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ 105454b8fdebSLorenzo Bianconi .hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \ 105554b8fdebSLorenzo Bianconi .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + _idx), \ 105654b8fdebSLorenzo Bianconi } 105754b8fdebSLorenzo Bianconi 105854b8fdebSLorenzo Bianconi #define OFDM_RATE(_idx, _rate) { \ 105954b8fdebSLorenzo Bianconi .bitrate = _rate, \ 106054b8fdebSLorenzo Bianconi .hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 106154b8fdebSLorenzo Bianconi .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 106254b8fdebSLorenzo Bianconi } 106354b8fdebSLorenzo Bianconi 106454b8fdebSLorenzo Bianconi extern struct ieee80211_rate mt76_rates[12]; 106554b8fdebSLorenzo Bianconi 1066d4131273SStanislaw Gruszka #define __mt76_rr(dev, ...) (dev)->bus->rr((dev), __VA_ARGS__) 1067d4131273SStanislaw Gruszka #define __mt76_wr(dev, ...) (dev)->bus->wr((dev), __VA_ARGS__) 1068d4131273SStanislaw Gruszka #define __mt76_rmw(dev, ...) (dev)->bus->rmw((dev), __VA_ARGS__) 106935e4ebeaSLorenzo Bianconi #define __mt76_wr_copy(dev, ...) (dev)->bus->write_copy((dev), __VA_ARGS__) 107035e4ebeaSLorenzo Bianconi #define __mt76_rr_copy(dev, ...) (dev)->bus->read_copy((dev), __VA_ARGS__) 1071d4131273SStanislaw Gruszka 107222c575c4SStanislaw Gruszka #define __mt76_set(dev, offset, val) __mt76_rmw(dev, offset, 0, val) 107322c575c4SStanislaw Gruszka #define __mt76_clear(dev, offset, val) __mt76_rmw(dev, offset, val, 0) 107422c575c4SStanislaw Gruszka 107517f1de56SFelix Fietkau #define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__) 107617f1de56SFelix Fietkau #define mt76_wr(dev, ...) (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__) 107717f1de56SFelix Fietkau #define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__) 107835e4ebeaSLorenzo Bianconi #define mt76_wr_copy(dev, ...) (dev)->mt76.bus->write_copy(&((dev)->mt76), __VA_ARGS__) 107935e4ebeaSLorenzo Bianconi #define mt76_rr_copy(dev, ...) (dev)->mt76.bus->read_copy(&((dev)->mt76), __VA_ARGS__) 10806da5a291SStanislaw Gruszka #define mt76_wr_rp(dev, ...) (dev)->mt76.bus->wr_rp(&((dev)->mt76), __VA_ARGS__) 10816da5a291SStanislaw Gruszka #define mt76_rd_rp(dev, ...) (dev)->mt76.bus->rd_rp(&((dev)->mt76), __VA_ARGS__) 108217f1de56SFelix Fietkau 1083f4d45fe2SLorenzo Bianconi 1084e2c2fd0fSLorenzo Bianconi #define mt76_mcu_restart(dev, ...) (dev)->mt76.mcu_ops->mcu_restart(&((dev)->mt76)) 1085db0f04f3SLorenzo Bianconi 108617f1de56SFelix Fietkau #define mt76_set(dev, offset, val) mt76_rmw(dev, offset, 0, val) 108717f1de56SFelix Fietkau #define mt76_clear(dev, offset, val) mt76_rmw(dev, offset, val, 0) 108817f1de56SFelix Fietkau 108917f1de56SFelix Fietkau #define mt76_get_field(_dev, _reg, _field) \ 109017f1de56SFelix Fietkau FIELD_GET(_field, mt76_rr(dev, _reg)) 109117f1de56SFelix Fietkau 109217f1de56SFelix Fietkau #define mt76_rmw_field(_dev, _reg, _field, _val) \ 109317f1de56SFelix Fietkau mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) 109417f1de56SFelix Fietkau 109546436b5eSStanislaw Gruszka #define __mt76_rmw_field(_dev, _reg, _field, _val) \ 109646436b5eSStanislaw Gruszka __mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) 109746436b5eSStanislaw Gruszka 1098ac24dd35SFelix Fietkau #define mt76_hw(dev) (dev)->mphy.hw 109917f1de56SFelix Fietkau 110017f1de56SFelix Fietkau bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, 110117f1de56SFelix Fietkau int timeout); 110217f1de56SFelix Fietkau 110317f1de56SFelix Fietkau #define mt76_poll(dev, ...) __mt76_poll(&((dev)->mt76), __VA_ARGS__) 110417f1de56SFelix Fietkau 110535effe6cSDeren Wu bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, 110635effe6cSDeren Wu int timeout, int kick); 110735effe6cSDeren Wu #define __mt76_poll_msec(...) ____mt76_poll_msec(__VA_ARGS__, 10) 110835effe6cSDeren Wu #define mt76_poll_msec(dev, ...) ____mt76_poll_msec(&((dev)->mt76), __VA_ARGS__, 10) 110935effe6cSDeren Wu #define mt76_poll_msec_tick(dev, ...) ____mt76_poll_msec(&((dev)->mt76), __VA_ARGS__) 111017f1de56SFelix Fietkau 111117f1de56SFelix Fietkau void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs); 1112f37f0550SLorenzo Bianconi void mt76_pci_disable_aspm(struct pci_dev *pdev); 1113d53ab629SMichael Lo bool mt76_pci_aspm_supported(struct pci_dev *pdev); 111417f1de56SFelix Fietkau 111517f1de56SFelix Fietkau static inline u16 mt76_chip(struct mt76_dev *dev) 111617f1de56SFelix Fietkau { 111717f1de56SFelix Fietkau return dev->rev >> 16; 111817f1de56SFelix Fietkau } 111917f1de56SFelix Fietkau 112017f1de56SFelix Fietkau static inline u16 mt76_rev(struct mt76_dev *dev) 112117f1de56SFelix Fietkau { 112217f1de56SFelix Fietkau return dev->rev & 0xffff; 112317f1de56SFelix Fietkau } 112417f1de56SFelix Fietkau 11258a7386e7SLorenzo Bianconi void mt76_wed_release_rx_buf(struct mtk_wed_device *wed); 11268a7386e7SLorenzo Bianconi void mt76_wed_offload_disable(struct mtk_wed_device *wed); 11278a7386e7SLorenzo Bianconi void mt76_wed_reset_complete(struct mtk_wed_device *wed); 11288a7386e7SLorenzo Bianconi void mt76_wed_dma_reset(struct mt76_dev *dev); 11298a7386e7SLorenzo Bianconi int mt76_wed_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 11308a7386e7SLorenzo Bianconi struct net_device *netdev, enum tc_setup_type type, 11318a7386e7SLorenzo Bianconi void *type_data); 1132b92158a8SLorenzo Bianconi #ifdef CONFIG_NET_MEDIATEK_SOC_WED 11338a7386e7SLorenzo Bianconi u32 mt76_wed_init_rx_buf(struct mtk_wed_device *wed, int size); 11348a7386e7SLorenzo Bianconi int mt76_wed_offload_enable(struct mtk_wed_device *wed); 11358a7386e7SLorenzo Bianconi int mt76_wed_dma_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset); 11368a7386e7SLorenzo Bianconi #else 11378a7386e7SLorenzo Bianconi static inline u32 mt76_wed_init_rx_buf(struct mtk_wed_device *wed, int size) 11388a7386e7SLorenzo Bianconi { 11398a7386e7SLorenzo Bianconi return 0; 11408a7386e7SLorenzo Bianconi } 11418a7386e7SLorenzo Bianconi 11428a7386e7SLorenzo Bianconi static inline int mt76_wed_offload_enable(struct mtk_wed_device *wed) 11438a7386e7SLorenzo Bianconi { 11448a7386e7SLorenzo Bianconi return 0; 11458a7386e7SLorenzo Bianconi } 11468a7386e7SLorenzo Bianconi 11478a7386e7SLorenzo Bianconi static inline int mt76_wed_dma_setup(struct mt76_dev *dev, struct mt76_queue *q, 11488a7386e7SLorenzo Bianconi bool reset) 11498a7386e7SLorenzo Bianconi { 11508a7386e7SLorenzo Bianconi return 0; 11518a7386e7SLorenzo Bianconi } 1152b92158a8SLorenzo Bianconi #endif /* CONFIG_NET_MEDIATEK_SOC_WED */ 1153b92158a8SLorenzo Bianconi 115417f1de56SFelix Fietkau #define mt76xx_chip(dev) mt76_chip(&((dev)->mt76)) 115517f1de56SFelix Fietkau #define mt76xx_rev(dev) mt76_rev(&((dev)->mt76)) 115617f1de56SFelix Fietkau 1157cb8ed33dSLorenzo Bianconi #define mt76_init_queues(dev, ...) (dev)->mt76.queue_ops->init(&((dev)->mt76), __VA_ARGS__) 1158a23fde09SLorenzo Bianconi #define mt76_queue_alloc(dev, ...) (dev)->mt76.queue_ops->alloc(&((dev)->mt76), __VA_ARGS__) 11595ed31128SLorenzo Bianconi #define mt76_tx_queue_skb_raw(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb_raw(&((dev)->mt76), __VA_ARGS__) 11605d581c33SFelix Fietkau #define mt76_tx_queue_skb(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb(&((dev)->mphy), __VA_ARGS__) 116117f1de56SFelix Fietkau #define mt76_queue_rx_reset(dev, ...) (dev)->mt76.queue_ops->rx_reset(&((dev)->mt76), __VA_ARGS__) 116217f1de56SFelix Fietkau #define mt76_queue_tx_cleanup(dev, ...) (dev)->mt76.queue_ops->tx_cleanup(&((dev)->mt76), __VA_ARGS__) 1163c001df97SLorenzo Bianconi #define mt76_queue_rx_cleanup(dev, ...) (dev)->mt76.queue_ops->rx_cleanup(&((dev)->mt76), __VA_ARGS__) 116417f1de56SFelix Fietkau #define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__) 11653990465dSLorenzo Bianconi #define mt76_queue_reset(dev, ...) (dev)->mt76.queue_ops->reset_q(&((dev)->mt76), __VA_ARGS__) 116617f1de56SFelix Fietkau 1167f473b42aSFelix Fietkau #define mt76_for_each_q_rx(dev, i) \ 1168b3ad9d6aSBo Jiao for (i = 0; i < ARRAY_SIZE((dev)->q_rx); i++) \ 1169b3ad9d6aSBo Jiao if ((dev)->q_rx[i].ndesc) 1170f473b42aSFelix Fietkau 1171c0f7b25aSLorenzo Bianconi struct mt76_dev *mt76_alloc_device(struct device *pdev, unsigned int size, 1172c0f7b25aSLorenzo Bianconi const struct ieee80211_ops *ops, 1173c0f7b25aSLorenzo Bianconi const struct mt76_driver_ops *drv_ops); 117417f1de56SFelix Fietkau int mt76_register_device(struct mt76_dev *dev, bool vht, 117517f1de56SFelix Fietkau struct ieee80211_rate *rates, int n_rates); 117617f1de56SFelix Fietkau void mt76_unregister_device(struct mt76_dev *dev); 1177def34a2fSLorenzo Bianconi void mt76_free_device(struct mt76_dev *dev); 1178c89d3625SFelix Fietkau void mt76_unregister_phy(struct mt76_phy *phy); 1179c89d3625SFelix Fietkau 1180c89d3625SFelix Fietkau struct mt76_phy *mt76_alloc_phy(struct mt76_dev *dev, unsigned int size, 1181dc44c45cSLorenzo Bianconi const struct ieee80211_ops *ops, 1182dc44c45cSLorenzo Bianconi u8 band_idx); 1183db78a791SLorenzo Bianconi int mt76_register_phy(struct mt76_phy *phy, bool vht, 1184db78a791SLorenzo Bianconi struct ieee80211_rate *rates, int n_rates); 118517f1de56SFelix Fietkau 11863263039dSLorenzo Bianconi struct dentry *mt76_register_debugfs_fops(struct mt76_phy *phy, 1187f6e1f598SLorenzo Bianconi const struct file_operations *ops); 1188f6e1f598SLorenzo Bianconi static inline struct dentry *mt76_register_debugfs(struct mt76_dev *dev) 1189f6e1f598SLorenzo Bianconi { 11903263039dSLorenzo Bianconi return mt76_register_debugfs_fops(&dev->phy, NULL); 1191f6e1f598SLorenzo Bianconi } 1192f6e1f598SLorenzo Bianconi 11930b82a8e8SLorenzo Bianconi int mt76_queues_read(struct seq_file *s, void *data); 11948f410a8bSLorenzo Bianconi void mt76_seq_puts_array(struct seq_file *file, const char *str, 11958f410a8bSLorenzo Bianconi s8 *val, int len); 119617f1de56SFelix Fietkau 119717f1de56SFelix Fietkau int mt76_eeprom_init(struct mt76_dev *dev, int len); 119898df2baeSLorenzo Bianconi void mt76_eeprom_override(struct mt76_phy *phy); 1199a6342c31SChristian Marangi int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len); 1200a1f57685SChristian Marangi int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep, 1201a1f57685SChristian Marangi const char *cell_name, int len); 120217f1de56SFelix Fietkau 1203b1cb42adSLorenzo Bianconi struct mt76_queue * 1204b1cb42adSLorenzo Bianconi mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc, 12052e420b88SLorenzo Bianconi int ring_base, void *wed, u32 flags); 1206b1cb42adSLorenzo Bianconi static inline int mt76_init_tx_queue(struct mt76_phy *phy, int qid, int idx, 12072e420b88SLorenzo Bianconi int n_desc, int ring_base, void *wed, 12082e420b88SLorenzo Bianconi u32 flags) 1209b1cb42adSLorenzo Bianconi { 1210b1cb42adSLorenzo Bianconi struct mt76_queue *q; 1211b1cb42adSLorenzo Bianconi 12122e420b88SLorenzo Bianconi q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base, wed, flags); 1213b1cb42adSLorenzo Bianconi if (IS_ERR(q)) 1214b1cb42adSLorenzo Bianconi return PTR_ERR(q); 1215b1cb42adSLorenzo Bianconi 121691990519SLorenzo Bianconi phy->q_tx[qid] = q; 1217b1cb42adSLorenzo Bianconi 1218b1cb42adSLorenzo Bianconi return 0; 1219b1cb42adSLorenzo Bianconi } 1220b1cb42adSLorenzo Bianconi 1221b1cb42adSLorenzo Bianconi static inline int mt76_init_mcu_queue(struct mt76_dev *dev, int qid, int idx, 1222b1cb42adSLorenzo Bianconi int n_desc, int ring_base) 1223b1cb42adSLorenzo Bianconi { 1224b1cb42adSLorenzo Bianconi struct mt76_queue *q; 1225b1cb42adSLorenzo Bianconi 12262e420b88SLorenzo Bianconi q = mt76_init_queue(dev, qid, idx, n_desc, ring_base, NULL, 0); 1227b1cb42adSLorenzo Bianconi if (IS_ERR(q)) 1228b1cb42adSLorenzo Bianconi return PTR_ERR(q); 1229b1cb42adSLorenzo Bianconi 1230b1cb42adSLorenzo Bianconi dev->q_mcu[qid] = q; 1231b1cb42adSLorenzo Bianconi 1232b1cb42adSLorenzo Bianconi return 0; 1233b1cb42adSLorenzo Bianconi } 1234b671da33SLorenzo Bianconi 1235011849e0SFelix Fietkau static inline struct mt76_phy * 1236128c9b7dSLorenzo Bianconi mt76_dev_phy(struct mt76_dev *dev, u8 phy_idx) 1237011849e0SFelix Fietkau { 1238dc44c45cSLorenzo Bianconi if ((phy_idx == MT_BAND1 && dev->phys[phy_idx]) || 1239dc44c45cSLorenzo Bianconi (phy_idx == MT_BAND2 && dev->phys[phy_idx])) 1240dc44c45cSLorenzo Bianconi return dev->phys[phy_idx]; 1241128c9b7dSLorenzo Bianconi 1242011849e0SFelix Fietkau return &dev->phy; 1243011849e0SFelix Fietkau } 1244011849e0SFelix Fietkau 1245bfc394ddSFelix Fietkau static inline struct ieee80211_hw * 1246128c9b7dSLorenzo Bianconi mt76_phy_hw(struct mt76_dev *dev, u8 phy_idx) 1247bfc394ddSFelix Fietkau { 1248128c9b7dSLorenzo Bianconi return mt76_dev_phy(dev, phy_idx)->hw; 1249bfc394ddSFelix Fietkau } 1250bfc394ddSFelix Fietkau 1251f3950a41SLorenzo Bianconi static inline u8 * 1252f3950a41SLorenzo Bianconi mt76_get_txwi_ptr(struct mt76_dev *dev, struct mt76_txwi_cache *t) 1253f3950a41SLorenzo Bianconi { 1254f3950a41SLorenzo Bianconi return (u8 *)t - dev->drv->txwi_size; 1255f3950a41SLorenzo Bianconi } 1256f3950a41SLorenzo Bianconi 1257ee8aa945SLorenzo Bianconi /* increment with wrap-around */ 1258ee8aa945SLorenzo Bianconi static inline int mt76_incr(int val, int size) 1259ee8aa945SLorenzo Bianconi { 1260ee8aa945SLorenzo Bianconi return (val + 1) & (size - 1); 1261ee8aa945SLorenzo Bianconi } 1262ee8aa945SLorenzo Bianconi 1263ee8aa945SLorenzo Bianconi /* decrement with wrap-around */ 1264ee8aa945SLorenzo Bianconi static inline int mt76_decr(int val, int size) 1265ee8aa945SLorenzo Bianconi { 1266ee8aa945SLorenzo Bianconi return (val - 1) & (size - 1); 1267ee8aa945SLorenzo Bianconi } 1268ee8aa945SLorenzo Bianconi 12691d0496c6SStanislaw Gruszka u8 mt76_ac_to_hwq(u8 ac); 1270b40b15e1SLorenzo Bianconi 127117f1de56SFelix Fietkau static inline struct ieee80211_txq * 127217f1de56SFelix Fietkau mtxq_to_txq(struct mt76_txq *mtxq) 127317f1de56SFelix Fietkau { 127417f1de56SFelix Fietkau void *ptr = mtxq; 127517f1de56SFelix Fietkau 127617f1de56SFelix Fietkau return container_of(ptr, struct ieee80211_txq, drv_priv); 127717f1de56SFelix Fietkau } 127817f1de56SFelix Fietkau 12799c68a57bSFelix Fietkau static inline struct ieee80211_sta * 12809c68a57bSFelix Fietkau wcid_to_sta(struct mt76_wcid *wcid) 12819c68a57bSFelix Fietkau { 12829c68a57bSFelix Fietkau void *ptr = wcid; 12839c68a57bSFelix Fietkau 12849c68a57bSFelix Fietkau if (!wcid || !wcid->sta) 12859c68a57bSFelix Fietkau return NULL; 12869c68a57bSFelix Fietkau 1287b1d21403SSean Wang if (wcid->def_wcid) 1288b1d21403SSean Wang ptr = wcid->def_wcid; 1289b1d21403SSean Wang 12909c68a57bSFelix Fietkau return container_of(ptr, struct ieee80211_sta, drv_priv); 12919c68a57bSFelix Fietkau } 12929c68a57bSFelix Fietkau 129388046b2cSFelix Fietkau static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb) 129488046b2cSFelix Fietkau { 129588046b2cSFelix Fietkau BUILD_BUG_ON(sizeof(struct mt76_tx_cb) > 129688046b2cSFelix Fietkau sizeof(IEEE80211_SKB_CB(skb)->status.status_driver_data)); 129788046b2cSFelix Fietkau return ((void *)IEEE80211_SKB_CB(skb)->status.status_driver_data); 129888046b2cSFelix Fietkau } 129988046b2cSFelix Fietkau 130077ae1d5eSRyder Lee static inline void *mt76_skb_get_hdr(struct sk_buff *skb) 130177ae1d5eSRyder Lee { 130277ae1d5eSRyder Lee struct mt76_rx_status mstat; 130377ae1d5eSRyder Lee u8 *data = skb->data; 130477ae1d5eSRyder Lee 130577ae1d5eSRyder Lee /* Alignment concerns */ 130677ae1d5eSRyder Lee BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he) % 4); 130777ae1d5eSRyder Lee BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he_mu) % 4); 130877ae1d5eSRyder Lee 130977ae1d5eSRyder Lee mstat = *((struct mt76_rx_status *)skb->cb); 131077ae1d5eSRyder Lee 131177ae1d5eSRyder Lee if (mstat.flag & RX_FLAG_RADIOTAP_HE) 131277ae1d5eSRyder Lee data += sizeof(struct ieee80211_radiotap_he); 131377ae1d5eSRyder Lee if (mstat.flag & RX_FLAG_RADIOTAP_HE_MU) 131477ae1d5eSRyder Lee data += sizeof(struct ieee80211_radiotap_he_mu); 131577ae1d5eSRyder Lee 131677ae1d5eSRyder Lee return data; 131777ae1d5eSRyder Lee } 131877ae1d5eSRyder Lee 13193bb45b5fSLorenzo Bianconi static inline void mt76_insert_hdr_pad(struct sk_buff *skb) 13203bb45b5fSLorenzo Bianconi { 13213bb45b5fSLorenzo Bianconi int len = ieee80211_get_hdrlen_from_skb(skb); 13223bb45b5fSLorenzo Bianconi 13233bb45b5fSLorenzo Bianconi if (len % 4 == 0) 13243bb45b5fSLorenzo Bianconi return; 13253bb45b5fSLorenzo Bianconi 13263bb45b5fSLorenzo Bianconi skb_push(skb, 2); 13273bb45b5fSLorenzo Bianconi memmove(skb->data, skb->data + 2, len); 13283bb45b5fSLorenzo Bianconi 13293bb45b5fSLorenzo Bianconi skb->data[len] = 0; 13303bb45b5fSLorenzo Bianconi skb->data[len + 1] = 0; 13313bb45b5fSLorenzo Bianconi } 13323bb45b5fSLorenzo Bianconi 13338548c6ebSFelix Fietkau static inline bool mt76_is_skb_pktid(u8 pktid) 13348548c6ebSFelix Fietkau { 13358548c6ebSFelix Fietkau if (pktid & MT_PACKET_ID_HAS_RATE) 13368548c6ebSFelix Fietkau return false; 13378548c6ebSFelix Fietkau 13388548c6ebSFelix Fietkau return pktid >= MT_PACKET_ID_FIRST; 13398548c6ebSFelix Fietkau } 13408548c6ebSFelix Fietkau 134107cda406SFelix Fietkau static inline u8 mt76_tx_power_nss_delta(u8 nss) 134207cda406SFelix Fietkau { 134307cda406SFelix Fietkau static const u8 nss_delta[4] = { 0, 6, 9, 12 }; 134403dd0d49SDeren Wu u8 idx = nss - 1; 134507cda406SFelix Fietkau 134603dd0d49SDeren Wu return (idx < ARRAY_SIZE(nss_delta)) ? nss_delta[idx] : 0; 134707cda406SFelix Fietkau } 134807cda406SFelix Fietkau 1349c918c74dSShayne Chen static inline bool mt76_testmode_enabled(struct mt76_phy *phy) 1350f0efa862SFelix Fietkau { 1351f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 1352c918c74dSShayne Chen return phy->test.state != MT76_TM_STATE_OFF; 1353c918c74dSShayne Chen #else 1354c918c74dSShayne Chen return false; 1355c918c74dSShayne Chen #endif 1356c918c74dSShayne Chen } 1357c918c74dSShayne Chen 1358c918c74dSShayne Chen static inline bool mt76_is_testmode_skb(struct mt76_dev *dev, 1359c918c74dSShayne Chen struct sk_buff *skb, 1360c918c74dSShayne Chen struct ieee80211_hw **hw) 1361c918c74dSShayne Chen { 1362c918c74dSShayne Chen #ifdef CONFIG_NL80211_TESTMODE 1363dc44c45cSLorenzo Bianconi int i; 1364dc44c45cSLorenzo Bianconi 1365dc44c45cSLorenzo Bianconi for (i = 0; i < ARRAY_SIZE(dev->phys); i++) { 1366dc44c45cSLorenzo Bianconi struct mt76_phy *phy = dev->phys[i]; 1367dc44c45cSLorenzo Bianconi 1368dc44c45cSLorenzo Bianconi if (phy && skb == phy->test.tx_skb) { 1369dc44c45cSLorenzo Bianconi *hw = dev->phys[i]->hw; 1370c918c74dSShayne Chen return true; 1371dc44c45cSLorenzo Bianconi } 1372dc44c45cSLorenzo Bianconi } 1373dc44c45cSLorenzo Bianconi return false; 1374f0efa862SFelix Fietkau #else 1375f0efa862SFelix Fietkau return false; 1376f0efa862SFelix Fietkau #endif 1377f0efa862SFelix Fietkau } 1378f0efa862SFelix Fietkau 137917f1de56SFelix Fietkau void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb); 13809fba6d07SFelix Fietkau void mt76_tx(struct mt76_phy *dev, struct ieee80211_sta *sta, 138117f1de56SFelix Fietkau struct mt76_wcid *wcid, struct sk_buff *skb); 138217f1de56SFelix Fietkau void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq); 138391990519SLorenzo Bianconi void mt76_stop_tx_queues(struct mt76_phy *phy, struct ieee80211_sta *sta, 138417f1de56SFelix Fietkau bool send_bar); 1385c50d105aSFelix Fietkau void mt76_tx_check_agg_ssn(struct ieee80211_sta *sta, struct sk_buff *skb); 13869fba6d07SFelix Fietkau void mt76_txq_schedule(struct mt76_phy *phy, enum mt76_txq_id qid); 13879fba6d07SFelix Fietkau void mt76_txq_schedule_all(struct mt76_phy *phy); 1388335e97acSLorenzo Bianconi void mt76_tx_worker_run(struct mt76_dev *dev); 1389781eef5bSFelix Fietkau void mt76_tx_worker(struct mt76_worker *w); 139017f1de56SFelix Fietkau void mt76_release_buffered_frames(struct ieee80211_hw *hw, 139117f1de56SFelix Fietkau struct ieee80211_sta *sta, 139217f1de56SFelix Fietkau u16 tids, int nframes, 139317f1de56SFelix Fietkau enum ieee80211_frame_release_type reason, 139417f1de56SFelix Fietkau bool more_data); 13955a95ca41SFelix Fietkau bool mt76_has_tx_pending(struct mt76_phy *phy); 1396f4fdd771SFelix Fietkau int mt76_update_channel(struct mt76_phy *phy); 1397c560b137SRyder Lee void mt76_update_survey(struct mt76_phy *phy); 139804414240SLorenzo Bianconi void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time); 139917f1de56SFelix Fietkau int mt76_get_survey(struct ieee80211_hw *hw, int idx, 140017f1de56SFelix Fietkau struct survey_info *survey); 1401a71b648eSRyder Lee int mt76_rx_signal(u8 chain_mask, s8 *chain_signal); 1402bb3e3fecSRyder Lee void mt76_set_stream_caps(struct mt76_phy *phy, bool vht); 140317f1de56SFelix Fietkau 1404aee5b8cfSFelix Fietkau int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid, 14057c4f744dSRyder Lee u16 ssn, u16 size); 1406aee5b8cfSFelix Fietkau void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid); 1407aee5b8cfSFelix Fietkau 140830ce7f44SFelix Fietkau void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, 140930ce7f44SFelix Fietkau struct ieee80211_key_conf *key); 141079d1c94cSFelix Fietkau 141179d1c94cSFelix Fietkau void mt76_tx_status_lock(struct mt76_dev *dev, struct sk_buff_head *list) 1412c34f1005SLorenzo Bianconi __acquires(&dev->status_lock); 141379d1c94cSFelix Fietkau void mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list) 1414c34f1005SLorenzo Bianconi __releases(&dev->status_lock); 141579d1c94cSFelix Fietkau 141688046b2cSFelix Fietkau int mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, 141788046b2cSFelix Fietkau struct sk_buff *skb); 141888046b2cSFelix Fietkau struct sk_buff *mt76_tx_status_skb_get(struct mt76_dev *dev, 141979d1c94cSFelix Fietkau struct mt76_wcid *wcid, int pktid, 142079d1c94cSFelix Fietkau struct sk_buff_head *list); 142179d1c94cSFelix Fietkau void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb, 142279d1c94cSFelix Fietkau struct sk_buff_head *list); 14230fe88644SFelix Fietkau void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb, 14240fe88644SFelix Fietkau struct list_head *free_list); 14250fe88644SFelix Fietkau static inline void 14260fe88644SFelix Fietkau mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb) 14270fe88644SFelix Fietkau { 14280fe88644SFelix Fietkau __mt76_tx_complete_skb(dev, wcid, skb, NULL); 14290fe88644SFelix Fietkau } 14300fe88644SFelix Fietkau 1431c02f86eeSLorenzo Bianconi void mt76_tx_status_check(struct mt76_dev *dev, bool flush); 1432e28487eaSFelix Fietkau int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1433e28487eaSFelix Fietkau struct ieee80211_sta *sta, 1434e28487eaSFelix Fietkau enum ieee80211_sta_state old_state, 1435e28487eaSFelix Fietkau enum ieee80211_sta_state new_state); 1436*31083e38SFelix Fietkau void __mt76_sta_remove(struct mt76_phy *phy, struct ieee80211_vif *vif, 143713f61dfcSLorenzo Bianconi struct ieee80211_sta *sta); 143843ba1922SFelix Fietkau void mt76_sta_pre_rcu_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 143943ba1922SFelix Fietkau struct ieee80211_sta *sta); 144030ce7f44SFelix Fietkau 14418af63fedSFelix Fietkau int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy); 1442ef13edc0SFelix Fietkau 14439313faacSFelix Fietkau int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 144424dab555SRameshkumar Sundaram unsigned int link_id, int *dbm); 1445b3cb885eSLorenzo Bianconi int mt76_init_sar_power(struct ieee80211_hw *hw, 1446b3cb885eSLorenzo Bianconi const struct cfg80211_sar_specs *sar); 1447b3cb885eSLorenzo Bianconi int mt76_get_sar_power(struct mt76_phy *phy, 1448b3cb885eSLorenzo Bianconi struct ieee80211_channel *chan, 1449b3cb885eSLorenzo Bianconi int power); 14509313faacSFelix Fietkau 1451e7173858SFelix Fietkau void mt76_csa_check(struct mt76_dev *dev); 1452e7173858SFelix Fietkau void mt76_csa_finish(struct mt76_dev *dev); 1453e7173858SFelix Fietkau 1454e49c76d4SLorenzo Bianconi int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 145587d53103SStanislaw Gruszka int mt76_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set); 1456eadfd98fSLorenzo Bianconi void mt76_insert_ccmp_hdr(struct sk_buff *skb, u8 key_id); 1457d2679d65SLorenzo Bianconi int mt76_get_rate(struct mt76_dev *dev, 1458d2679d65SLorenzo Bianconi struct ieee80211_supported_band *sband, 1459d2679d65SLorenzo Bianconi int idx, bool cck); 1460*31083e38SFelix Fietkau int mt76_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1461*31083e38SFelix Fietkau struct ieee80211_scan_request *hw_req); 1462*31083e38SFelix Fietkau void mt76_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif); 14638b8ab5c2SLorenzo Bianconi void mt76_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 14648b8ab5c2SLorenzo Bianconi const u8 *mac); 14658b8ab5c2SLorenzo Bianconi void mt76_sw_scan_complete(struct ieee80211_hw *hw, 14668b8ab5c2SLorenzo Bianconi struct ieee80211_vif *vif); 14673f306448SFelix Fietkau enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy); 1468f0efa862SFelix Fietkau int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1469f0efa862SFelix Fietkau void *data, int len); 1470f0efa862SFelix Fietkau int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, 1471f0efa862SFelix Fietkau struct netlink_callback *cb, void *data, int len); 1472c918c74dSShayne Chen int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state); 14732601dda8SShayne Chen int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len); 1474f0efa862SFelix Fietkau 1475c918c74dSShayne Chen static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable) 1476f0efa862SFelix Fietkau { 1477f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 1478f0efa862SFelix Fietkau enum mt76_testmode_state state = MT76_TM_STATE_IDLE; 1479f0efa862SFelix Fietkau 1480c918c74dSShayne Chen if (disable || phy->test.state == MT76_TM_STATE_OFF) 1481f0efa862SFelix Fietkau state = MT76_TM_STATE_OFF; 1482f0efa862SFelix Fietkau 1483c918c74dSShayne Chen mt76_testmode_set_state(phy, state); 1484f0efa862SFelix Fietkau #endif 1485f0efa862SFelix Fietkau } 1486f0efa862SFelix Fietkau 148787d53103SStanislaw Gruszka 148817f1de56SFelix Fietkau /* internal */ 1489e394b575SFelix Fietkau static inline struct ieee80211_hw * 1490e394b575SFelix Fietkau mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb) 1491e394b575SFelix Fietkau { 1492e394b575SFelix Fietkau struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1493a062f001SLorenzo Bianconi u8 phy_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2; 1494a062f001SLorenzo Bianconi struct ieee80211_hw *hw = mt76_phy_hw(dev, phy_idx); 1495e394b575SFelix Fietkau 1496a062f001SLorenzo Bianconi info->hw_queue &= ~MT_TX_HW_QUEUE_PHY; 1497e394b575SFelix Fietkau 1498e394b575SFelix Fietkau return hw; 1499e394b575SFelix Fietkau } 1500e394b575SFelix Fietkau 150117f1de56SFelix Fietkau void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); 15022666beceSSujuan Chen void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); 15032666beceSSujuan Chen struct mt76_txwi_cache *mt76_get_rxwi(struct mt76_dev *dev); 1504a97a467aSSujuan Chen void mt76_free_pending_rxwi(struct mt76_dev *dev); 15059d9d738bSFelix Fietkau void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, 150681e850efSLorenzo Bianconi struct napi_struct *napi); 150781e850efSLorenzo Bianconi void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q, 150881e850efSLorenzo Bianconi struct napi_struct *napi); 1509aee5b8cfSFelix Fietkau void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames); 1510c918c74dSShayne Chen void mt76_testmode_tx_pending(struct mt76_phy *phy); 1511fe5b5ab5SFelix Fietkau void mt76_queue_tx_complete(struct mt76_dev *dev, struct mt76_queue *q, 1512fe5b5ab5SFelix Fietkau struct mt76_queue_entry *e); 1513f4fdd771SFelix Fietkau int mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef, 1514f4fdd771SFelix Fietkau bool offchannel); 1515*31083e38SFelix Fietkau void mt76_scan_work(struct work_struct *work); 1516*31083e38SFelix Fietkau void mt76_abort_scan(struct mt76_dev *dev); 151717f1de56SFelix Fietkau 1518b40b15e1SLorenzo Bianconi /* usb */ 1519b40b15e1SLorenzo Bianconi static inline bool mt76u_urb_error(struct urb *urb) 1520b40b15e1SLorenzo Bianconi { 1521b40b15e1SLorenzo Bianconi return urb->status && 1522b40b15e1SLorenzo Bianconi urb->status != -ECONNRESET && 1523b40b15e1SLorenzo Bianconi urb->status != -ESHUTDOWN && 1524b40b15e1SLorenzo Bianconi urb->status != -ENOENT; 1525b40b15e1SLorenzo Bianconi } 1526b40b15e1SLorenzo Bianconi 15275de4db8fSStanislaw Gruszka static inline int 1528b63aa031SStanislaw Gruszka mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len, 15293bcd979cSLorenzo Bianconi int timeout, int ep) 15305de4db8fSStanislaw Gruszka { 153180df01f4SLorenzo Bianconi struct usb_interface *uintf = to_usb_interface(dev->dev); 153280df01f4SLorenzo Bianconi struct usb_device *udev = interface_to_usbdev(uintf); 15335de4db8fSStanislaw Gruszka struct mt76_usb *usb = &dev->usb; 15345de4db8fSStanislaw Gruszka unsigned int pipe; 15355de4db8fSStanislaw Gruszka 1536b63aa031SStanislaw Gruszka if (actual_len) 15373bcd979cSLorenzo Bianconi pipe = usb_rcvbulkpipe(udev, usb->in_ep[ep]); 1538b63aa031SStanislaw Gruszka else 15393bcd979cSLorenzo Bianconi pipe = usb_sndbulkpipe(udev, usb->out_ep[ep]); 1540b63aa031SStanislaw Gruszka 1541b63aa031SStanislaw Gruszka return usb_bulk_msg(udev, pipe, data, len, actual_len, timeout); 15425de4db8fSStanislaw Gruszka } 15435de4db8fSStanislaw Gruszka 1544192ad406SLorenzo Bianconi void mt76_ethtool_page_pool_stats(struct mt76_dev *dev, u64 *data, int *index); 154554ae98ffSLorenzo Bianconi void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi, 1546731425f3SShayne Chen struct mt76_sta_stats *stats, bool eht); 1547e98e6df6SLorenzo Bianconi int mt76_skb_adjust_pad(struct sk_buff *skb, int pad); 15486cb596baSLorenzo Bianconi int __mt76u_vendor_request(struct mt76_dev *dev, u8 req, u8 req_type, 15496cb596baSLorenzo Bianconi u16 val, u16 offset, void *buf, size_t len); 1550b40b15e1SLorenzo Bianconi int mt76u_vendor_request(struct mt76_dev *dev, u8 req, 1551b40b15e1SLorenzo Bianconi u8 req_type, u16 val, u16 offset, 1552b40b15e1SLorenzo Bianconi void *buf, size_t len); 1553b40b15e1SLorenzo Bianconi void mt76u_single_wr(struct mt76_dev *dev, const u8 req, 1554b40b15e1SLorenzo Bianconi const u16 offset, const u32 val); 15556cb596baSLorenzo Bianconi void mt76u_read_copy(struct mt76_dev *dev, u32 offset, 15566cb596baSLorenzo Bianconi void *data, int len); 15576cb596baSLorenzo Bianconi u32 ___mt76u_rr(struct mt76_dev *dev, u8 req, u8 req_type, u32 addr); 15586cb596baSLorenzo Bianconi void ___mt76u_wr(struct mt76_dev *dev, u8 req, u8 req_type, 15596cb596baSLorenzo Bianconi u32 addr, u32 val); 15606cb596baSLorenzo Bianconi int __mt76u_init(struct mt76_dev *dev, struct usb_interface *intf, 15616cb596baSLorenzo Bianconi struct mt76_bus_ops *ops); 15626cb596baSLorenzo Bianconi int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf); 156394e1cfa8SLorenzo Bianconi int mt76u_alloc_mcu_queue(struct mt76_dev *dev); 1564b40b15e1SLorenzo Bianconi int mt76u_alloc_queues(struct mt76_dev *dev); 156539d501d9SStanislaw Gruszka void mt76u_stop_tx(struct mt76_dev *dev); 156639d501d9SStanislaw Gruszka void mt76u_stop_rx(struct mt76_dev *dev); 156739d501d9SStanislaw Gruszka int mt76u_resume_rx(struct mt76_dev *dev); 1568b40b15e1SLorenzo Bianconi void mt76u_queues_deinit(struct mt76_dev *dev); 1569b40b15e1SLorenzo Bianconi 1570d39b52e3SSean Wang int mt76s_init(struct mt76_dev *dev, struct sdio_func *func, 1571d39b52e3SSean Wang const struct mt76_bus_ops *bus_ops); 1572d512b008SLorenzo Bianconi int mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid); 1573d512b008SLorenzo Bianconi int mt76s_alloc_tx(struct mt76_dev *dev); 1574d39b52e3SSean Wang void mt76s_deinit(struct mt76_dev *dev); 1575764dee47SLorenzo Bianconi void mt76s_sdio_irq(struct sdio_func *func); 1576764dee47SLorenzo Bianconi void mt76s_txrx_worker(struct mt76_sdio *sdio); 1577ca74b9b9SSean Wang bool mt76s_txqs_empty(struct mt76_dev *dev); 1578dacf0acfSSean Wang int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, 1579dacf0acfSSean Wang int hw_ver); 1580764dee47SLorenzo Bianconi u32 mt76s_rr(struct mt76_dev *dev, u32 offset); 1581764dee47SLorenzo Bianconi void mt76s_wr(struct mt76_dev *dev, u32 offset, u32 val); 1582764dee47SLorenzo Bianconi u32 mt76s_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val); 1583764dee47SLorenzo Bianconi u32 mt76s_read_pcr(struct mt76_dev *dev); 1584764dee47SLorenzo Bianconi void mt76s_write_copy(struct mt76_dev *dev, u32 offset, 1585764dee47SLorenzo Bianconi const void *data, int len); 1586764dee47SLorenzo Bianconi void mt76s_read_copy(struct mt76_dev *dev, u32 offset, 1587764dee47SLorenzo Bianconi void *data, int len); 1588764dee47SLorenzo Bianconi int mt76s_wr_rp(struct mt76_dev *dev, u32 base, 1589764dee47SLorenzo Bianconi const struct mt76_reg_pair *data, 1590764dee47SLorenzo Bianconi int len); 1591764dee47SLorenzo Bianconi int mt76s_rd_rp(struct mt76_dev *dev, u32 base, 1592764dee47SLorenzo Bianconi struct mt76_reg_pair *data, int len); 1593d39b52e3SSean Wang 15949df0fab9SLorenzo Bianconi struct sk_buff * 1595a0a2034eSLorenzo Bianconi __mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, 1596b146f238SLorenzo Bianconi int len, int data_len, gfp_t gfp); 1597a0a2034eSLorenzo Bianconi static inline struct sk_buff * 1598bb31a80eSLorenzo Bianconi mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, 1599a0a2034eSLorenzo Bianconi int data_len) 1600a0a2034eSLorenzo Bianconi { 1601b146f238SLorenzo Bianconi return __mt76_mcu_msg_alloc(dev, data, data_len, data_len, GFP_KERNEL); 1602a0a2034eSLorenzo Bianconi } 1603a0a2034eSLorenzo Bianconi 1604c07a49d4SLorenzo Bianconi void mt76_mcu_rx_event(struct mt76_dev *dev, struct sk_buff *skb); 1605680abb25SLorenzo Bianconi struct sk_buff *mt76_mcu_get_response(struct mt76_dev *dev, 1606680abb25SLorenzo Bianconi unsigned long expires); 1607ae5ad627SFelix Fietkau int mt76_mcu_send_and_get_msg(struct mt76_dev *dev, int cmd, const void *data, 1608ae5ad627SFelix Fietkau int len, bool wait_resp, struct sk_buff **ret); 1609ae5ad627SFelix Fietkau int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, 1610ae5ad627SFelix Fietkau int cmd, bool wait_resp, struct sk_buff **ret); 1611215a2efaSLorenzo Bianconi int __mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data, 1612215a2efaSLorenzo Bianconi int len, int max_len); 1613215a2efaSLorenzo Bianconi static inline int 1614215a2efaSLorenzo Bianconi mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data, 1615215a2efaSLorenzo Bianconi int len) 1616215a2efaSLorenzo Bianconi { 16175b8f1840SSean Wang int max_len = 4096 - dev->mcu_ops->headroom; 16185b8f1840SSean Wang 16195b8f1840SSean Wang return __mt76_mcu_send_firmware(dev, cmd, data, len, max_len); 1620215a2efaSLorenzo Bianconi } 1621215a2efaSLorenzo Bianconi 1622ae5ad627SFelix Fietkau static inline int 1623ae5ad627SFelix Fietkau mt76_mcu_send_msg(struct mt76_dev *dev, int cmd, const void *data, int len, 1624ae5ad627SFelix Fietkau bool wait_resp) 1625ae5ad627SFelix Fietkau { 1626ae5ad627SFelix Fietkau return mt76_mcu_send_and_get_msg(dev, cmd, data, len, wait_resp, NULL); 1627ae5ad627SFelix Fietkau } 1628ae5ad627SFelix Fietkau 1629ae5ad627SFelix Fietkau static inline int 1630ae5ad627SFelix Fietkau mt76_mcu_skb_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, 1631ae5ad627SFelix Fietkau bool wait_resp) 1632ae5ad627SFelix Fietkau { 1633ae5ad627SFelix Fietkau return mt76_mcu_skb_send_and_get_msg(dev, skb, cmd, wait_resp, NULL); 1634ae5ad627SFelix Fietkau } 16359df0fab9SLorenzo Bianconi 16369220f695SLorenzo Bianconi void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set); 16379220f695SLorenzo Bianconi 163809382d8fSMing Yen Hsieh struct device_node * 163909382d8fSMing Yen Hsieh mt76_find_power_limits_node(struct mt76_dev *dev); 164009382d8fSMing Yen Hsieh struct device_node * 164109382d8fSMing Yen Hsieh mt76_find_channel_node(struct device_node *np, struct ieee80211_channel *chan); 164209382d8fSMing Yen Hsieh 164322b980baSFelix Fietkau s8 mt76_get_rate_power_limits(struct mt76_phy *phy, 164422b980baSFelix Fietkau struct ieee80211_channel *chan, 164522b980baSFelix Fietkau struct mt76_power_limits *dest, 164622b980baSFelix Fietkau s8 target_power); 164722b980baSFelix Fietkau 16483c37da57SLorenzo Bianconi static inline bool mt76_queue_is_rx(struct mt76_dev *dev, struct mt76_queue *q) 16493c37da57SLorenzo Bianconi { 16503c37da57SLorenzo Bianconi int i; 16513c37da57SLorenzo Bianconi 16523c37da57SLorenzo Bianconi for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) { 16533c37da57SLorenzo Bianconi if (q == &dev->q_rx[i]) 16543c37da57SLorenzo Bianconi return true; 16553c37da57SLorenzo Bianconi } 16563c37da57SLorenzo Bianconi 16573c37da57SLorenzo Bianconi return false; 16583c37da57SLorenzo Bianconi } 16593c37da57SLorenzo Bianconi 1660132d74d3SLorenzo Bianconi static inline bool mt76_queue_is_wed_tx_free(struct mt76_queue *q) 1661132d74d3SLorenzo Bianconi { 1662132d74d3SLorenzo Bianconi return (q->flags & MT_QFLAG_WED) && 1663132d74d3SLorenzo Bianconi FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_TXFREE; 1664132d74d3SLorenzo Bianconi } 1665132d74d3SLorenzo Bianconi 1666950d0abbSBo Jiao static inline bool mt76_queue_is_wed_rro(struct mt76_queue *q) 1667950d0abbSBo Jiao { 1668950d0abbSBo Jiao return q->flags & MT_QFLAG_WED_RRO; 1669950d0abbSBo Jiao } 1670950d0abbSBo Jiao 1671950d0abbSBo Jiao static inline bool mt76_queue_is_wed_rro_ind(struct mt76_queue *q) 1672950d0abbSBo Jiao { 1673950d0abbSBo Jiao return mt76_queue_is_wed_rro(q) && 1674950d0abbSBo Jiao FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_IND; 1675950d0abbSBo Jiao } 1676950d0abbSBo Jiao 1677950d0abbSBo Jiao static inline bool mt76_queue_is_wed_rro_data(struct mt76_queue *q) 1678950d0abbSBo Jiao { 1679950d0abbSBo Jiao return mt76_queue_is_wed_rro(q) && 1680950d0abbSBo Jiao (FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_DATA || 1681950d0abbSBo Jiao FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_MSDU_PG); 1682950d0abbSBo Jiao } 1683950d0abbSBo Jiao 168458bcd4edSLorenzo Bianconi static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q) 168558bcd4edSLorenzo Bianconi { 1686950d0abbSBo Jiao if (!(q->flags & MT_QFLAG_WED)) 1687950d0abbSBo Jiao return false; 1688950d0abbSBo Jiao 1689950d0abbSBo Jiao return FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX || 1690950d0abbSBo Jiao mt76_queue_is_wed_rro_ind(q) || mt76_queue_is_wed_rro_data(q); 1691950d0abbSBo Jiao 169258bcd4edSLorenzo Bianconi } 169358bcd4edSLorenzo Bianconi 1694d089692bSLorenzo Bianconi struct mt76_txwi_cache * 1695d089692bSLorenzo Bianconi mt76_token_release(struct mt76_dev *dev, int token, bool *wake); 1696d089692bSLorenzo Bianconi int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi); 1697d089692bSLorenzo Bianconi void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked); 16982666beceSSujuan Chen struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token); 16992666beceSSujuan Chen int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr, 17002666beceSSujuan Chen struct mt76_txwi_cache *r, dma_addr_t phys); 17012f5c3c77SLorenzo Bianconi int mt76_create_page_pool(struct mt76_dev *dev, struct mt76_queue *q); 17022f5c3c77SLorenzo Bianconi static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct) 17032f5c3c77SLorenzo Bianconi { 17042f5c3c77SLorenzo Bianconi struct page *page = virt_to_head_page(buf); 17052f5c3c77SLorenzo Bianconi 17062f5c3c77SLorenzo Bianconi page_pool_put_full_page(page->pp, page, allow_direct); 17072f5c3c77SLorenzo Bianconi } 17082f5c3c77SLorenzo Bianconi 17092f5c3c77SLorenzo Bianconi static inline void * 17102f5c3c77SLorenzo Bianconi mt76_get_page_pool_buf(struct mt76_queue *q, u32 *offset, u32 size) 17112f5c3c77SLorenzo Bianconi { 17122f5c3c77SLorenzo Bianconi struct page *page; 17132f5c3c77SLorenzo Bianconi 17142f5c3c77SLorenzo Bianconi page = page_pool_dev_alloc_frag(q->page_pool, offset, size); 17152f5c3c77SLorenzo Bianconi if (!page) 17162f5c3c77SLorenzo Bianconi return NULL; 17172f5c3c77SLorenzo Bianconi 17182f5c3c77SLorenzo Bianconi return page_address(page) + *offset; 17192f5c3c77SLorenzo Bianconi } 1720d089692bSLorenzo Bianconi 1721d089692bSLorenzo Bianconi static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked) 1722d089692bSLorenzo Bianconi { 1723d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1724d089692bSLorenzo Bianconi __mt76_set_tx_blocked(dev, blocked); 1725d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1726d089692bSLorenzo Bianconi } 1727d089692bSLorenzo Bianconi 1728d089692bSLorenzo Bianconi static inline int 1729d089692bSLorenzo Bianconi mt76_token_get(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi) 1730d089692bSLorenzo Bianconi { 1731d089692bSLorenzo Bianconi int token; 1732d089692bSLorenzo Bianconi 1733d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 173461b5156bSFelix Fietkau token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC); 1735d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1736d089692bSLorenzo Bianconi 1737d089692bSLorenzo Bianconi return token; 1738d089692bSLorenzo Bianconi } 1739d089692bSLorenzo Bianconi 1740d089692bSLorenzo Bianconi static inline struct mt76_txwi_cache * 1741d089692bSLorenzo Bianconi mt76_token_put(struct mt76_dev *dev, int token) 1742d089692bSLorenzo Bianconi { 1743d089692bSLorenzo Bianconi struct mt76_txwi_cache *txwi; 1744d089692bSLorenzo Bianconi 1745d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1746d089692bSLorenzo Bianconi txwi = idr_remove(&dev->token, token); 1747d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1748d089692bSLorenzo Bianconi 1749d089692bSLorenzo Bianconi return txwi; 1750d089692bSLorenzo Bianconi } 175190052b84SLorenzo Bianconi 17520335c034SFelix Fietkau void mt76_wcid_init(struct mt76_wcid *wcid); 17530335c034SFelix Fietkau void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid); 1754387ab042SFelix Fietkau void mt76_wcid_add_poll(struct mt76_dev *dev, struct mt76_wcid *wcid); 1755bd1e3e7bSLorenzo Bianconi 175617f1de56SFelix Fietkau #endif 1757