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> 1817f1de56SFelix Fietkau #include "util.h" 19f0efa862SFelix Fietkau #include "testmode.h" 2017f1de56SFelix Fietkau 2117f1de56SFelix Fietkau #define MT_MCU_RING_SIZE 32 2217f1de56SFelix Fietkau #define MT_RX_BUF_SIZE 2048 23123bc712SDeren Wu #define MT_SKB_HEAD_LEN 256 2417f1de56SFelix Fietkau 25e1378e52SFelix Fietkau #define MT_MAX_NON_AQL_PKT 16 26e1378e52SFelix Fietkau #define MT_TXQ_FREE_THR 32 27e1378e52SFelix Fietkau 28d089692bSLorenzo Bianconi #define MT76_TOKEN_FREE_THR 64 29d089692bSLorenzo Bianconi 30f68d6762SFelix Fietkau #define MT_QFLAG_WED_RING GENMASK(1, 0) 31f68d6762SFelix Fietkau #define MT_QFLAG_WED_TYPE GENMASK(3, 2) 32f68d6762SFelix Fietkau #define MT_QFLAG_WED BIT(4) 33f68d6762SFelix Fietkau 34f68d6762SFelix Fietkau #define __MT_WED_Q(_type, _n) (MT_QFLAG_WED | \ 35f68d6762SFelix Fietkau FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \ 36f68d6762SFelix Fietkau FIELD_PREP(MT_QFLAG_WED_RING, _n)) 37f68d6762SFelix Fietkau #define MT_WED_Q_TX(_n) __MT_WED_Q(MT76_WED_Q_TX, _n) 38cd372b8cSLorenzo Bianconi #define MT_WED_Q_RX(_n) __MT_WED_Q(MT76_WED_Q_RX, _n) 39f68d6762SFelix Fietkau #define MT_WED_Q_TXFREE __MT_WED_Q(MT76_WED_Q_TXFREE, 0) 40f68d6762SFelix Fietkau 4117f1de56SFelix Fietkau struct mt76_dev; 4296747a51SFelix Fietkau struct mt76_phy; 43469d4818SLorenzo Bianconi struct mt76_wcid; 443ad08509SLorenzo Bianconi struct mt76s_intr; 4517f1de56SFelix Fietkau 466da5a291SStanislaw Gruszka struct mt76_reg_pair { 476da5a291SStanislaw Gruszka u32 reg; 486da5a291SStanislaw Gruszka u32 value; 496da5a291SStanislaw Gruszka }; 506da5a291SStanislaw Gruszka 51c50479faSStanislaw Gruszka enum mt76_bus_type { 52c50479faSStanislaw Gruszka MT76_BUS_MMIO, 53c50479faSStanislaw Gruszka MT76_BUS_USB, 54d39b52e3SSean Wang MT76_BUS_SDIO, 55c50479faSStanislaw Gruszka }; 56c50479faSStanislaw Gruszka 57f68d6762SFelix Fietkau enum mt76_wed_type { 58f68d6762SFelix Fietkau MT76_WED_Q_TX, 59f68d6762SFelix Fietkau MT76_WED_Q_TXFREE, 60cd372b8cSLorenzo Bianconi MT76_WED_Q_RX, 61f68d6762SFelix Fietkau }; 62f68d6762SFelix Fietkau 6317f1de56SFelix Fietkau struct mt76_bus_ops { 6417f1de56SFelix Fietkau u32 (*rr)(struct mt76_dev *dev, u32 offset); 6517f1de56SFelix Fietkau void (*wr)(struct mt76_dev *dev, u32 offset, u32 val); 6617f1de56SFelix Fietkau u32 (*rmw)(struct mt76_dev *dev, u32 offset, u32 mask, u32 val); 6735e4ebeaSLorenzo Bianconi void (*write_copy)(struct mt76_dev *dev, u32 offset, const void *data, 6835e4ebeaSLorenzo Bianconi int len); 6935e4ebeaSLorenzo Bianconi void (*read_copy)(struct mt76_dev *dev, u32 offset, void *data, 7017f1de56SFelix Fietkau int len); 716da5a291SStanislaw Gruszka int (*wr_rp)(struct mt76_dev *dev, u32 base, 726da5a291SStanislaw Gruszka const struct mt76_reg_pair *rp, int len); 736da5a291SStanislaw Gruszka int (*rd_rp)(struct mt76_dev *dev, u32 base, 746da5a291SStanislaw Gruszka struct mt76_reg_pair *rp, int len); 75c50479faSStanislaw Gruszka enum mt76_bus_type type; 7617f1de56SFelix Fietkau }; 7717f1de56SFelix Fietkau 7861c51a74SLorenzo Bianconi #define mt76_is_usb(dev) ((dev)->bus->type == MT76_BUS_USB) 7961c51a74SLorenzo Bianconi #define mt76_is_mmio(dev) ((dev)->bus->type == MT76_BUS_MMIO) 80d39b52e3SSean Wang #define mt76_is_sdio(dev) ((dev)->bus->type == MT76_BUS_SDIO) 81c50479faSStanislaw Gruszka 8217f1de56SFelix Fietkau enum mt76_txq_id { 8317f1de56SFelix Fietkau MT_TXQ_VO = IEEE80211_AC_VO, 8417f1de56SFelix Fietkau MT_TXQ_VI = IEEE80211_AC_VI, 8517f1de56SFelix Fietkau MT_TXQ_BE = IEEE80211_AC_BE, 8617f1de56SFelix Fietkau MT_TXQ_BK = IEEE80211_AC_BK, 8717f1de56SFelix Fietkau MT_TXQ_PSD, 8817f1de56SFelix Fietkau MT_TXQ_BEACON, 8917f1de56SFelix Fietkau MT_TXQ_CAB, 9017f1de56SFelix Fietkau __MT_TXQ_MAX 9117f1de56SFelix Fietkau }; 9217f1de56SFelix Fietkau 93b1cb42adSLorenzo Bianconi enum mt76_mcuq_id { 94e637763bSLorenzo Bianconi MT_MCUQ_WM, 95e637763bSLorenzo Bianconi MT_MCUQ_WA, 96e637763bSLorenzo Bianconi MT_MCUQ_FWDL, 97b1cb42adSLorenzo Bianconi __MT_MCUQ_MAX 98b1cb42adSLorenzo Bianconi }; 99b1cb42adSLorenzo Bianconi 10017f1de56SFelix Fietkau enum mt76_rxq_id { 10117f1de56SFelix Fietkau MT_RXQ_MAIN, 10217f1de56SFelix Fietkau MT_RXQ_MCU, 103d3377b78SRyder Lee MT_RXQ_MCU_WA, 104fc8f841bSLorenzo Bianconi MT_RXQ_BAND1, 105fc8f841bSLorenzo Bianconi MT_RXQ_BAND1_WA, 106f9b627f1SBo Jiao MT_RXQ_MAIN_WA, 107fc8f841bSLorenzo Bianconi MT_RXQ_BAND2, 108fc8f841bSLorenzo Bianconi MT_RXQ_BAND2_WA, 10917f1de56SFelix Fietkau __MT_RXQ_MAX 11017f1de56SFelix Fietkau }; 11117f1de56SFelix Fietkau 112dc44c45cSLorenzo Bianconi enum mt76_band_id { 113dc44c45cSLorenzo Bianconi MT_BAND0, 114dc44c45cSLorenzo Bianconi MT_BAND1, 115dc44c45cSLorenzo Bianconi MT_BAND2, 116dc44c45cSLorenzo Bianconi __MT_MAX_BAND 117dc44c45cSLorenzo Bianconi }; 118dc44c45cSLorenzo Bianconi 119c368362cSRyder Lee enum mt76_cipher_type { 120c368362cSRyder Lee MT_CIPHER_NONE, 121c368362cSRyder Lee MT_CIPHER_WEP40, 122c368362cSRyder Lee MT_CIPHER_TKIP, 123c368362cSRyder Lee MT_CIPHER_TKIP_NO_MIC, 124c368362cSRyder Lee MT_CIPHER_AES_CCMP, 125c368362cSRyder Lee MT_CIPHER_WEP104, 126c368362cSRyder Lee MT_CIPHER_BIP_CMAC_128, 127c368362cSRyder Lee MT_CIPHER_WEP128, 128c368362cSRyder Lee MT_CIPHER_WAPI, 129c368362cSRyder Lee MT_CIPHER_CCMP_CCX, 130c368362cSRyder Lee MT_CIPHER_CCMP_256, 131c368362cSRyder Lee MT_CIPHER_GCMP, 132c368362cSRyder Lee MT_CIPHER_GCMP_256, 133c368362cSRyder Lee }; 134c368362cSRyder Lee 1353f306448SFelix Fietkau enum mt76_dfs_state { 1363f306448SFelix Fietkau MT_DFS_STATE_UNKNOWN, 1373f306448SFelix Fietkau MT_DFS_STATE_DISABLED, 1383f306448SFelix Fietkau MT_DFS_STATE_CAC, 1393f306448SFelix Fietkau MT_DFS_STATE_ACTIVE, 1403f306448SFelix Fietkau }; 1413f306448SFelix Fietkau 14217f1de56SFelix Fietkau struct mt76_queue_buf { 14317f1de56SFelix Fietkau dma_addr_t addr; 14427d5c528SFelix Fietkau u16 len; 14527d5c528SFelix Fietkau bool skip_unmap; 14617f1de56SFelix Fietkau }; 14717f1de56SFelix Fietkau 148b5903c47SLorenzo Bianconi struct mt76_tx_info { 149b5903c47SLorenzo Bianconi struct mt76_queue_buf buf[32]; 150cfaae9e6SLorenzo Bianconi struct sk_buff *skb; 151b5903c47SLorenzo Bianconi int nbuf; 152b5903c47SLorenzo Bianconi u32 info; 153b5903c47SLorenzo Bianconi }; 154b5903c47SLorenzo Bianconi 15517f1de56SFelix Fietkau struct mt76_queue_entry { 15617f1de56SFelix Fietkau union { 15717f1de56SFelix Fietkau void *buf; 15817f1de56SFelix Fietkau struct sk_buff *skb; 15917f1de56SFelix Fietkau }; 160b40b15e1SLorenzo Bianconi union { 16117f1de56SFelix Fietkau struct mt76_txwi_cache *txwi; 162d7d4ea9aSStanislaw Gruszka struct urb *urb; 163d39b52e3SSean Wang int buf_sz; 164b40b15e1SLorenzo Bianconi }; 16575d4bf1fSFelix Fietkau u32 dma_addr[2]; 16675d4bf1fSFelix Fietkau u16 dma_len[2]; 167e1378e52SFelix Fietkau u16 wcid; 1687bd0650bSLorenzo Bianconi bool skip_buf0:1; 16927d5c528SFelix Fietkau bool skip_buf1:1; 1707bd0650bSLorenzo Bianconi bool done:1; 17117f1de56SFelix Fietkau }; 17217f1de56SFelix Fietkau 17317f1de56SFelix Fietkau struct mt76_queue_regs { 17417f1de56SFelix Fietkau u32 desc_base; 17517f1de56SFelix Fietkau u32 ring_size; 17617f1de56SFelix Fietkau u32 cpu_idx; 17717f1de56SFelix Fietkau u32 dma_idx; 17817f1de56SFelix Fietkau } __packed __aligned(4); 17917f1de56SFelix Fietkau 18017f1de56SFelix Fietkau struct mt76_queue { 18117f1de56SFelix Fietkau struct mt76_queue_regs __iomem *regs; 18217f1de56SFelix Fietkau 18317f1de56SFelix Fietkau spinlock_t lock; 1849716ef04SFelix Fietkau spinlock_t cleanup_lock; 18517f1de56SFelix Fietkau struct mt76_queue_entry *entry; 18617f1de56SFelix Fietkau struct mt76_desc *desc; 18717f1de56SFelix Fietkau 188b40b15e1SLorenzo Bianconi u16 first; 18917f1de56SFelix Fietkau u16 head; 19017f1de56SFelix Fietkau u16 tail; 19117f1de56SFelix Fietkau int ndesc; 19217f1de56SFelix Fietkau int queued; 19317f1de56SFelix Fietkau int buf_size; 194cd44bc40SLorenzo Bianconi bool stopped; 19590d494c9SFelix Fietkau bool blocked; 19617f1de56SFelix Fietkau 19717f1de56SFelix Fietkau u8 buf_offset; 19817f1de56SFelix Fietkau u8 hw_idx; 199f68d6762SFelix Fietkau u8 flags; 200f68d6762SFelix Fietkau 201f68d6762SFelix Fietkau u32 wed_regs; 20217f1de56SFelix Fietkau 20317f1de56SFelix Fietkau dma_addr_t desc_dma; 20417f1de56SFelix Fietkau struct sk_buff *rx_head; 205c12128ceSFelix Fietkau struct page_frag_cache rx_page; 20617f1de56SFelix Fietkau }; 20717f1de56SFelix Fietkau 208db0f04f3SLorenzo Bianconi struct mt76_mcu_ops { 209bb31a80eSLorenzo Bianconi u32 headroom; 210bb31a80eSLorenzo Bianconi u32 tailroom; 211bb31a80eSLorenzo Bianconi 212a74d6336SStanislaw Gruszka int (*mcu_send_msg)(struct mt76_dev *dev, int cmd, const void *data, 213a74d6336SStanislaw Gruszka int len, bool wait_resp); 214f4d45fe2SLorenzo Bianconi int (*mcu_skb_send_msg)(struct mt76_dev *dev, struct sk_buff *skb, 215e452c6ebSFelix Fietkau int cmd, int *seq); 216f320d812SFelix Fietkau int (*mcu_parse_response)(struct mt76_dev *dev, int cmd, 217f320d812SFelix Fietkau struct sk_buff *skb, int seq); 218d39b52e3SSean Wang u32 (*mcu_rr)(struct mt76_dev *dev, u32 offset); 219d39b52e3SSean Wang void (*mcu_wr)(struct mt76_dev *dev, u32 offset, u32 val); 2206da5a291SStanislaw Gruszka int (*mcu_wr_rp)(struct mt76_dev *dev, u32 base, 2216da5a291SStanislaw Gruszka const struct mt76_reg_pair *rp, int len); 2226da5a291SStanislaw Gruszka int (*mcu_rd_rp)(struct mt76_dev *dev, u32 base, 2236da5a291SStanislaw Gruszka struct mt76_reg_pair *rp, int len); 22400496042SFelix Fietkau int (*mcu_restart)(struct mt76_dev *dev); 225db0f04f3SLorenzo Bianconi }; 226db0f04f3SLorenzo Bianconi 22717f1de56SFelix Fietkau struct mt76_queue_ops { 228cb8ed33dSLorenzo Bianconi int (*init)(struct mt76_dev *dev, 229cb8ed33dSLorenzo Bianconi int (*poll)(struct napi_struct *napi, int budget)); 23017f1de56SFelix Fietkau 231b1bfbe70SLorenzo Bianconi int (*alloc)(struct mt76_dev *dev, struct mt76_queue *q, 232b1bfbe70SLorenzo Bianconi int idx, int n_desc, int bufsize, 233b1bfbe70SLorenzo Bianconi u32 ring_base); 23417f1de56SFelix Fietkau 23589870594SLorenzo Bianconi int (*tx_queue_skb)(struct mt76_dev *dev, struct mt76_queue *q, 236d08295f5SFelix Fietkau enum mt76_txq_id qid, struct sk_buff *skb, 237d08295f5SFelix Fietkau struct mt76_wcid *wcid, struct ieee80211_sta *sta); 238469d4818SLorenzo Bianconi 239d95093a1SLorenzo Bianconi int (*tx_queue_skb_raw)(struct mt76_dev *dev, struct mt76_queue *q, 2405ed31128SLorenzo Bianconi struct sk_buff *skb, u32 tx_info); 2415ed31128SLorenzo Bianconi 24217f1de56SFelix Fietkau void *(*dequeue)(struct mt76_dev *dev, struct mt76_queue *q, bool flush, 24317f1de56SFelix Fietkau int *len, u32 *info, bool *more); 24417f1de56SFelix Fietkau 24517f1de56SFelix Fietkau void (*rx_reset)(struct mt76_dev *dev, enum mt76_rxq_id qid); 24617f1de56SFelix Fietkau 247e5655492SLorenzo Bianconi void (*tx_cleanup)(struct mt76_dev *dev, struct mt76_queue *q, 24817f1de56SFelix Fietkau bool flush); 24917f1de56SFelix Fietkau 250c001df97SLorenzo Bianconi void (*rx_cleanup)(struct mt76_dev *dev, struct mt76_queue *q); 251c001df97SLorenzo Bianconi 25217f1de56SFelix Fietkau void (*kick)(struct mt76_dev *dev, struct mt76_queue *q); 2533990465dSLorenzo Bianconi 2543990465dSLorenzo Bianconi void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q); 25517f1de56SFelix Fietkau }; 25617f1de56SFelix Fietkau 257dc877523SRyder Lee enum mt76_phy_type { 258dc877523SRyder Lee MT_PHY_TYPE_CCK, 259dc877523SRyder Lee MT_PHY_TYPE_OFDM, 260dc877523SRyder Lee MT_PHY_TYPE_HT, 261dc877523SRyder Lee MT_PHY_TYPE_HT_GF, 262dc877523SRyder Lee MT_PHY_TYPE_VHT, 263dc877523SRyder Lee MT_PHY_TYPE_HE_SU = 8, 264dc877523SRyder Lee MT_PHY_TYPE_HE_EXT_SU, 265dc877523SRyder Lee MT_PHY_TYPE_HE_TB, 266dc877523SRyder Lee MT_PHY_TYPE_HE_MU, 267dc877523SRyder Lee __MT_PHY_TYPE_HE_MAX, 268dc877523SRyder Lee }; 269dc877523SRyder Lee 270dc877523SRyder Lee struct mt76_sta_stats { 271dc877523SRyder Lee u64 tx_mode[__MT_PHY_TYPE_HE_MAX]; 272dc877523SRyder Lee u64 tx_bw[4]; /* 20, 40, 80, 160 */ 273dc877523SRyder Lee u64 tx_nss[4]; /* 1, 2, 3, 4 */ 274dc877523SRyder Lee u64 tx_mcs[16]; /* mcs idx */ 27543eaa368SRyder Lee u64 tx_bytes; 27643eaa368SRyder Lee u32 tx_packets; 27743eaa368SRyder Lee u32 tx_retries; 27843eaa368SRyder Lee u32 tx_failed; 279dc877523SRyder Lee }; 280dc877523SRyder Lee 281d71ef286SFelix Fietkau enum mt76_wcid_flags { 282d71ef286SFelix Fietkau MT_WCID_FLAG_CHECK_PS, 283d71ef286SFelix Fietkau MT_WCID_FLAG_PS, 284e151d71eSFelix Fietkau MT_WCID_FLAG_4ADDR, 28590e3abf0SFelix Fietkau MT_WCID_FLAG_HDR_TRANS, 286d71ef286SFelix Fietkau }; 287d71ef286SFelix Fietkau 288b37d0c97SBo Jiao #define MT76_N_WCIDS 544 28936404c06SStanislaw Gruszka 290e394b575SFelix Fietkau /* stored in ieee80211_tx_info::hw_queue */ 291a062f001SLorenzo Bianconi #define MT_TX_HW_QUEUE_PHY GENMASK(3, 2) 292e394b575SFelix Fietkau 293ef13edc0SFelix Fietkau DECLARE_EWMA(signal, 10, 8); 294ef13edc0SFelix Fietkau 295db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_RATE GENMASK(15, 0) 296db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_NSS GENMASK(17, 16) 297db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_TXPWR_ADJ GENMASK(25, 18) 298db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_SET BIT(31) 299db9f11d3SFelix Fietkau 30017f1de56SFelix Fietkau struct mt76_wcid { 301aee5b8cfSFelix Fietkau struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS]; 302aee5b8cfSFelix Fietkau 303e1378e52SFelix Fietkau atomic_t non_aql_packets; 304d71ef286SFelix Fietkau unsigned long flags; 305d71ef286SFelix Fietkau 306ef13edc0SFelix Fietkau struct ewma_signal rssi; 307ef13edc0SFelix Fietkau int inactive_count; 308ef13edc0SFelix Fietkau 3099908d98aSRyder Lee struct rate_info rate; 3109908d98aSRyder Lee 31149e649c3SRyder Lee u16 idx; 31217f1de56SFelix Fietkau u8 hw_key_idx; 313730d6d0dSFelix Fietkau u8 hw_key_idx2; 31417f1de56SFelix Fietkau 3159c68a57bSFelix Fietkau u8 sta:1; 316b443e55fSRyder Lee u8 amsdu:1; 317a1a99d7bSLorenzo Bianconi u8 phy_idx:2; 3189c68a57bSFelix Fietkau 31930ce7f44SFelix Fietkau u8 rx_check_pn; 320a1b0bbd4SXing Song u8 rx_key_pn[IEEE80211_NUM_TIDS + 1][6]; 32101cfc1b4SLorenzo Bianconi u16 cipher; 32230ce7f44SFelix Fietkau 323db9f11d3SFelix Fietkau u32 tx_info; 32423405236SFelix Fietkau bool sw_iv; 32588046b2cSFelix Fietkau 326bd1e3e7bSLorenzo Bianconi struct list_head list; 327bd1e3e7bSLorenzo Bianconi struct idr pktid; 328dc877523SRyder Lee 329dc877523SRyder Lee struct mt76_sta_stats stats; 33017f1de56SFelix Fietkau }; 33117f1de56SFelix Fietkau 33217f1de56SFelix Fietkau struct mt76_txq { 33351fb1278SFelix Fietkau u16 wcid; 33417f1de56SFelix Fietkau 33517f1de56SFelix Fietkau u16 agg_ssn; 33617f1de56SFelix Fietkau bool send_bar; 33717f1de56SFelix Fietkau bool aggr; 33817f1de56SFelix Fietkau }; 33917f1de56SFelix Fietkau 34017f1de56SFelix Fietkau struct mt76_txwi_cache { 34117f1de56SFelix Fietkau struct list_head list; 342f3950a41SLorenzo Bianconi dma_addr_t dma_addr; 3436ca66722SLorenzo Bianconi 3442666beceSSujuan Chen union { 3456ca66722SLorenzo Bianconi struct sk_buff *skb; 3462666beceSSujuan Chen void *ptr; 3472666beceSSujuan Chen }; 34817f1de56SFelix Fietkau }; 34917f1de56SFelix Fietkau 350aee5b8cfSFelix Fietkau struct mt76_rx_tid { 351aee5b8cfSFelix Fietkau struct rcu_head rcu_head; 352aee5b8cfSFelix Fietkau 353aee5b8cfSFelix Fietkau struct mt76_dev *dev; 354aee5b8cfSFelix Fietkau 355aee5b8cfSFelix Fietkau spinlock_t lock; 356aee5b8cfSFelix Fietkau struct delayed_work reorder_work; 357aee5b8cfSFelix Fietkau 358aee5b8cfSFelix Fietkau u16 head; 3597c4f744dSRyder Lee u16 size; 3607c4f744dSRyder Lee u16 nframes; 361aee5b8cfSFelix Fietkau 362e7ec563eSMarkus Theil u8 num; 363e7ec563eSMarkus Theil 364aee5b8cfSFelix Fietkau u8 started:1, stopped:1, timer_pending:1; 365aee5b8cfSFelix Fietkau 366aee5b8cfSFelix Fietkau struct sk_buff *reorder_buf[]; 367aee5b8cfSFelix Fietkau }; 368aee5b8cfSFelix Fietkau 36988046b2cSFelix Fietkau #define MT_TX_CB_DMA_DONE BIT(0) 37088046b2cSFelix Fietkau #define MT_TX_CB_TXS_DONE BIT(1) 37188046b2cSFelix Fietkau #define MT_TX_CB_TXS_FAILED BIT(2) 37288046b2cSFelix Fietkau 3738548c6ebSFelix Fietkau #define MT_PACKET_ID_MASK GENMASK(6, 0) 374013b2dffSFelix Fietkau #define MT_PACKET_ID_NO_ACK 0 375013b2dffSFelix Fietkau #define MT_PACKET_ID_NO_SKB 1 37643eaa368SRyder Lee #define MT_PACKET_ID_WED 2 37743eaa368SRyder Lee #define MT_PACKET_ID_FIRST 3 3788548c6ebSFelix Fietkau #define MT_PACKET_ID_HAS_RATE BIT(7) 379c4a784e3SLorenzo Bianconi /* This is timer for when to give up when waiting for TXS callback, 380c4a784e3SLorenzo Bianconi * with starting time being the time at which the DMA_DONE callback 381c4a784e3SLorenzo Bianconi * was seen (so, we know packet was processed then, it should not take 382c4a784e3SLorenzo Bianconi * long after that for firmware to send the TXS callback if it is going 383c4a784e3SLorenzo Bianconi * to do so.) 384c4a784e3SLorenzo Bianconi */ 385c4a784e3SLorenzo Bianconi #define MT_TX_STATUS_SKB_TIMEOUT (HZ / 4) 38688046b2cSFelix Fietkau 38788046b2cSFelix Fietkau struct mt76_tx_cb { 38888046b2cSFelix Fietkau unsigned long jiffies; 38949e649c3SRyder Lee u16 wcid; 39088046b2cSFelix Fietkau u8 pktid; 39188046b2cSFelix Fietkau u8 flags; 39288046b2cSFelix Fietkau }; 39388046b2cSFelix Fietkau 39417f1de56SFelix Fietkau enum { 39517f1de56SFelix Fietkau MT76_STATE_INITIALIZED, 39617f1de56SFelix Fietkau MT76_STATE_RUNNING, 39787e022deSStanislaw Gruszka MT76_STATE_MCU_RUNNING, 39817f1de56SFelix Fietkau MT76_SCANNING, 399fcdfc29eSLorenzo Bianconi MT76_HW_SCANNING, 40020305f98SLorenzo Bianconi MT76_HW_SCHED_SCANNING, 401fd6c2dfaSFelix Fietkau MT76_RESTART, 40217f1de56SFelix Fietkau MT76_RESET, 40361c4fa72SFelix Fietkau MT76_MCU_RESET, 404b40b15e1SLorenzo Bianconi MT76_REMOVED, 405b40b15e1SLorenzo Bianconi MT76_READING_STATS, 406eb99cc95SLorenzo Bianconi MT76_STATE_POWER_OFF, 407c6bf2010SLorenzo Bianconi MT76_STATE_SUSPEND, 4087307f296SLorenzo Bianconi MT76_STATE_ROC, 40908523a2aSLorenzo Bianconi MT76_STATE_PM, 41017f1de56SFelix Fietkau }; 41117f1de56SFelix Fietkau 41217f1de56SFelix Fietkau struct mt76_hw_cap { 41317f1de56SFelix Fietkau bool has_2ghz; 41417f1de56SFelix Fietkau bool has_5ghz; 415f7d2958cSLorenzo Bianconi bool has_6ghz; 41617f1de56SFelix Fietkau }; 41717f1de56SFelix Fietkau 4189ec0b821SFelix Fietkau #define MT_DRV_TXWI_NO_FREE BIT(0) 4199ec0b821SFelix Fietkau #define MT_DRV_TX_ALIGNED4_SKBS BIT(1) 4205ce09c1aSFelix Fietkau #define MT_DRV_SW_RX_AIRTIME BIT(2) 42194d4d076SLorenzo Bianconi #define MT_DRV_RX_DMA_HDR BIT(3) 422d3c82998SLorenzo Bianconi #define MT_DRV_HW_MGMT_TXQ BIT(4) 4235b0fb852SBen Greear #define MT_DRV_AMSDU_OFFLOAD BIT(5) 4246ca66722SLorenzo Bianconi 42517f1de56SFelix Fietkau struct mt76_driver_ops { 4269ec0b821SFelix Fietkau u32 drv_flags; 427ea565833SFelix Fietkau u32 survey_flags; 42817f1de56SFelix Fietkau u16 txwi_size; 429d089692bSLorenzo Bianconi u16 token_size; 43022b980baSFelix Fietkau u8 mcs_rates; 43117f1de56SFelix Fietkau 432c560b137SRyder Lee void (*update_survey)(struct mt76_phy *phy); 43317f1de56SFelix Fietkau 43417f1de56SFelix Fietkau int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr, 435cfaae9e6SLorenzo Bianconi enum mt76_txq_id qid, struct mt76_wcid *wcid, 436b5903c47SLorenzo Bianconi struct ieee80211_sta *sta, 437b5903c47SLorenzo Bianconi struct mt76_tx_info *tx_info); 43817f1de56SFelix Fietkau 439d80e52c7SFelix Fietkau void (*tx_complete_skb)(struct mt76_dev *dev, 440e226ba2eSLorenzo Bianconi struct mt76_queue_entry *e); 44117f1de56SFelix Fietkau 442b40b15e1SLorenzo Bianconi bool (*tx_status_data)(struct mt76_dev *dev, u8 *update); 443b40b15e1SLorenzo Bianconi 444fbe50d9aSFelix Fietkau bool (*rx_check)(struct mt76_dev *dev, void *data, int len); 445fbe50d9aSFelix Fietkau 44617f1de56SFelix Fietkau void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q, 447*c3137942SSujuan Chen struct sk_buff *skb, u32 *info); 44817f1de56SFelix Fietkau 44917f1de56SFelix Fietkau void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q); 450d71ef286SFelix Fietkau 451d71ef286SFelix Fietkau void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta, 452d71ef286SFelix Fietkau bool ps); 453e28487eaSFelix Fietkau 454e28487eaSFelix Fietkau int (*sta_add)(struct mt76_dev *dev, struct ieee80211_vif *vif, 455e28487eaSFelix Fietkau struct ieee80211_sta *sta); 456e28487eaSFelix Fietkau 4579c193de5SFelix Fietkau void (*sta_assoc)(struct mt76_dev *dev, struct ieee80211_vif *vif, 4589c193de5SFelix Fietkau struct ieee80211_sta *sta); 4599c193de5SFelix Fietkau 460e28487eaSFelix Fietkau void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif, 461e28487eaSFelix Fietkau struct ieee80211_sta *sta); 46217f1de56SFelix Fietkau }; 46317f1de56SFelix Fietkau 46417f1de56SFelix Fietkau struct mt76_channel_state { 46517f1de56SFelix Fietkau u64 cc_active; 46617f1de56SFelix Fietkau u64 cc_busy; 4676bfa6e38SLorenzo Bianconi u64 cc_rx; 4685ce09c1aSFelix Fietkau u64 cc_bss_rx; 469ea565833SFelix Fietkau u64 cc_tx; 470e5051965SFelix Fietkau 471e5051965SFelix Fietkau s8 noise; 47217f1de56SFelix Fietkau }; 47317f1de56SFelix Fietkau 47417f1de56SFelix Fietkau struct mt76_sband { 47517f1de56SFelix Fietkau struct ieee80211_supported_band sband; 47617f1de56SFelix Fietkau struct mt76_channel_state *chan; 47717f1de56SFelix Fietkau }; 47817f1de56SFelix Fietkau 479b40b15e1SLorenzo Bianconi /* addr req mask */ 480b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_EEPROM BIT(31) 481b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_CFG BIT(30) 482b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_MASK (MT_VEND_TYPE_EEPROM | MT_VEND_TYPE_CFG) 483b40b15e1SLorenzo Bianconi 484b40b15e1SLorenzo Bianconi #define MT_VEND_ADDR(type, n) (MT_VEND_TYPE_##type | (n)) 485b40b15e1SLorenzo Bianconi enum mt_vendor_req { 486b40b15e1SLorenzo Bianconi MT_VEND_DEV_MODE = 0x1, 487b40b15e1SLorenzo Bianconi MT_VEND_WRITE = 0x2, 4881e816c65SLorenzo Bianconi MT_VEND_POWER_ON = 0x4, 489b40b15e1SLorenzo Bianconi MT_VEND_MULTI_WRITE = 0x6, 490b40b15e1SLorenzo Bianconi MT_VEND_MULTI_READ = 0x7, 491b40b15e1SLorenzo Bianconi MT_VEND_READ_EEPROM = 0x9, 492b40b15e1SLorenzo Bianconi MT_VEND_WRITE_FCE = 0x42, 493b40b15e1SLorenzo Bianconi MT_VEND_WRITE_CFG = 0x46, 494b40b15e1SLorenzo Bianconi MT_VEND_READ_CFG = 0x47, 4951e816c65SLorenzo Bianconi MT_VEND_READ_EXT = 0x63, 4961e816c65SLorenzo Bianconi MT_VEND_WRITE_EXT = 0x66, 497d0846f08SSean Wang MT_VEND_FEATURE_SET = 0x91, 498b40b15e1SLorenzo Bianconi }; 499b40b15e1SLorenzo Bianconi 500b40b15e1SLorenzo Bianconi enum mt76u_in_ep { 501b40b15e1SLorenzo Bianconi MT_EP_IN_PKT_RX, 502b40b15e1SLorenzo Bianconi MT_EP_IN_CMD_RESP, 503b40b15e1SLorenzo Bianconi __MT_EP_IN_MAX, 504b40b15e1SLorenzo Bianconi }; 505b40b15e1SLorenzo Bianconi 506b40b15e1SLorenzo Bianconi enum mt76u_out_ep { 507b40b15e1SLorenzo Bianconi MT_EP_OUT_INBAND_CMD, 508b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_BE, 50923cb16d2SLorenzo Bianconi MT_EP_OUT_AC_BK, 510b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_VI, 511b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_VO, 512b40b15e1SLorenzo Bianconi MT_EP_OUT_HCCA, 513b40b15e1SLorenzo Bianconi __MT_EP_OUT_MAX, 514b40b15e1SLorenzo Bianconi }; 515b40b15e1SLorenzo Bianconi 51609872957SLorenzo Bianconi struct mt76_mcu { 51709872957SLorenzo Bianconi struct mutex mutex; 51809872957SLorenzo Bianconi u32 msg_seq; 519e452c6ebSFelix Fietkau int timeout; 52009872957SLorenzo Bianconi 52109872957SLorenzo Bianconi struct sk_buff_head res_q; 52209872957SLorenzo Bianconi wait_queue_head_t wait; 52309872957SLorenzo Bianconi }; 52409872957SLorenzo Bianconi 52514663f0cSLorenzo Bianconi #define MT_TX_SG_MAX_SIZE 8 526972c5981SSean Wang #define MT_RX_SG_MAX_SIZE 4 527b40b15e1SLorenzo Bianconi #define MT_NUM_TX_ENTRIES 256 528b40b15e1SLorenzo Bianconi #define MT_NUM_RX_ENTRIES 128 529b40b15e1SLorenzo Bianconi #define MCU_RESP_URB_SIZE 1024 530b40b15e1SLorenzo Bianconi struct mt76_usb { 531b40b15e1SLorenzo Bianconi struct mutex usb_ctrl_mtx; 532a6bfb6d1SStanislaw Gruszka u8 *data; 533a6bfb6d1SStanislaw Gruszka u16 data_len; 534b40b15e1SLorenzo Bianconi 5359daf27e6SLorenzo Bianconi struct mt76_worker status_worker; 536be83a7e2SLorenzo Bianconi struct mt76_worker rx_worker; 5379daf27e6SLorenzo Bianconi 538284efb47SLorenzo Bianconi struct work_struct stat_work; 539b40b15e1SLorenzo Bianconi 540b40b15e1SLorenzo Bianconi u8 out_ep[__MT_EP_OUT_MAX]; 541b40b15e1SLorenzo Bianconi u8 in_ep[__MT_EP_IN_MAX]; 54263a7de5dSLorenzo Bianconi bool sg_en; 543b40b15e1SLorenzo Bianconi 544b40b15e1SLorenzo Bianconi struct mt76u_mcu { 545a18a494fSStanislaw Gruszka u8 *data; 546851ab66eSLorenzo Bianconi /* multiple reads */ 547851ab66eSLorenzo Bianconi struct mt76_reg_pair *rp; 548851ab66eSLorenzo Bianconi int rp_len; 549851ab66eSLorenzo Bianconi u32 base; 550b40b15e1SLorenzo Bianconi } mcu; 551b40b15e1SLorenzo Bianconi }; 552b40b15e1SLorenzo Bianconi 553bf08d585SSean Wang #define MT76S_XMIT_BUF_SZ 0x3fe00 554b1460bb4SDeren Wu #define MT76S_NUM_TX_ENTRIES 256 555b1460bb4SDeren Wu #define MT76S_NUM_RX_ENTRIES 512 556d39b52e3SSean Wang struct mt76_sdio { 557fefb584dSLorenzo Bianconi struct mt76_worker txrx_worker; 5586a618acbSLorenzo Bianconi struct mt76_worker status_worker; 5596a618acbSLorenzo Bianconi struct mt76_worker net_worker; 5606a618acbSLorenzo Bianconi 561d74fda4cSLorenzo Bianconi struct work_struct stat_work; 562974327a4SLorenzo Bianconi 563bf08d585SSean Wang u8 *xmit_buf; 564bf08d585SSean Wang u32 xmit_buf_sz; 5651522ff73SLorenzo Bianconi 566d39b52e3SSean Wang struct sdio_func *func; 567b4964908SSean Wang void *intr_data; 568dacf0acfSSean Wang u8 hw_ver; 569ca74b9b9SSean Wang wait_queue_head_t wait; 570d39b52e3SSean Wang 571d39b52e3SSean Wang struct { 572d39b52e3SSean Wang int pse_data_quota; 573d39b52e3SSean Wang int ple_data_quota; 574d39b52e3SSean Wang int pse_mcu_quota; 5758c94f0e6SSean Wang int pse_page_size; 576d39b52e3SSean Wang int deficit; 577d39b52e3SSean Wang } sched; 5783ad08509SLorenzo Bianconi 5793ad08509SLorenzo Bianconi int (*parse_irq)(struct mt76_dev *dev, struct mt76s_intr *intr); 580d39b52e3SSean Wang }; 581d39b52e3SSean Wang 582f7bbb80fSLorenzo Bianconi struct mt76_mmio { 58327db1ad1SLorenzo Bianconi void __iomem *regs; 584957068c2SLorenzo Bianconi spinlock_t irq_lock; 585957068c2SLorenzo Bianconi u32 irqmask; 586f68d6762SFelix Fietkau 587f68d6762SFelix Fietkau struct mtk_wed_device wed; 588f7bbb80fSLorenzo Bianconi }; 589f7bbb80fSLorenzo Bianconi 5905ce09c1aSFelix Fietkau struct mt76_rx_status { 5915ce09c1aSFelix Fietkau union { 5925ce09c1aSFelix Fietkau struct mt76_wcid *wcid; 59349e649c3SRyder Lee u16 wcid_idx; 5945ce09c1aSFelix Fietkau }; 5955ce09c1aSFelix Fietkau 5960fda6d7bSRyder Lee u32 reorder_time; 5975ce09c1aSFelix Fietkau 5985ce09c1aSFelix Fietkau u32 ampdu_ref; 5990fda6d7bSRyder Lee u32 timestamp; 6005ce09c1aSFelix Fietkau 6015ce09c1aSFelix Fietkau u8 iv[6]; 6025ce09c1aSFelix Fietkau 603128c9b7dSLorenzo Bianconi u8 phy_idx:2; 6045ce09c1aSFelix Fietkau u8 aggr:1; 605e195dad1SFelix Fietkau u8 qos_ctl; 6065ce09c1aSFelix Fietkau u16 seqno; 6075ce09c1aSFelix Fietkau 6085ce09c1aSFelix Fietkau u16 freq; 6095ce09c1aSFelix Fietkau u32 flag; 6105ce09c1aSFelix Fietkau u8 enc_flags; 611af4a2f2fSRyder Lee u8 encoding:2, bw:3, he_ru:3; 612af4a2f2fSRyder Lee u8 he_gi:2, he_dcm:1; 613cc4b3c13SLorenzo Bianconi u8 amsdu:1, first_amsdu:1, last_amsdu:1; 6145ce09c1aSFelix Fietkau u8 rate_idx; 6155ce09c1aSFelix Fietkau u8 nss; 6165ce09c1aSFelix Fietkau u8 band; 6175ce09c1aSFelix Fietkau s8 signal; 6185ce09c1aSFelix Fietkau u8 chains; 6195ce09c1aSFelix Fietkau s8 chain_signal[IEEE80211_MAX_CHAINS]; 6205ce09c1aSFelix Fietkau }; 6215ce09c1aSFelix Fietkau 622502604f5SYN Chen struct mt76_freq_range_power { 623502604f5SYN Chen const struct cfg80211_sar_freq_ranges *range; 624502604f5SYN Chen s8 power; 625502604f5SYN Chen }; 626502604f5SYN Chen 627f0efa862SFelix Fietkau struct mt76_testmode_ops { 628c918c74dSShayne Chen int (*set_state)(struct mt76_phy *phy, enum mt76_testmode_state state); 629c918c74dSShayne Chen int (*set_params)(struct mt76_phy *phy, struct nlattr **tb, 630f0efa862SFelix Fietkau enum mt76_testmode_state new_state); 631c918c74dSShayne Chen int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg); 632f0efa862SFelix Fietkau }; 633f0efa862SFelix Fietkau 634f0efa862SFelix Fietkau struct mt76_testmode_data { 635f0efa862SFelix Fietkau enum mt76_testmode_state state; 636f0efa862SFelix Fietkau 637f0efa862SFelix Fietkau u32 param_set[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)]; 638f0efa862SFelix Fietkau struct sk_buff *tx_skb; 639f0efa862SFelix Fietkau 640f0efa862SFelix Fietkau u32 tx_count; 6412601dda8SShayne Chen u16 tx_mpdu_len; 642f0efa862SFelix Fietkau 643f0efa862SFelix Fietkau u8 tx_rate_mode; 644f0efa862SFelix Fietkau u8 tx_rate_idx; 645f0efa862SFelix Fietkau u8 tx_rate_nss; 646f0efa862SFelix Fietkau u8 tx_rate_sgi; 647f0efa862SFelix Fietkau u8 tx_rate_ldpc; 6487f54c742SShayne Chen u8 tx_rate_stbc; 6491a38c2f5SShayne Chen u8 tx_ltf; 650f0efa862SFelix Fietkau 651f0efa862SFelix Fietkau u8 tx_antenna_mask; 652fdc9c18eSShayne Chen u8 tx_spe_idx; 653f0efa862SFelix Fietkau 654b8cbdb97SShayne Chen u8 tx_duty_cycle; 655b8cbdb97SShayne Chen u32 tx_time; 656b8cbdb97SShayne Chen u32 tx_ipg; 657b8cbdb97SShayne Chen 658f0efa862SFelix Fietkau u32 freq_offset; 659f0efa862SFelix Fietkau 660f0efa862SFelix Fietkau u8 tx_power[4]; 661f0efa862SFelix Fietkau u8 tx_power_control; 662f0efa862SFelix Fietkau 663c40b42c2SShayne Chen u8 addr[3][ETH_ALEN]; 664c40b42c2SShayne Chen 665f0efa862SFelix Fietkau u32 tx_pending; 666f0efa862SFelix Fietkau u32 tx_queued; 667ba459094SShayne Chen u16 tx_queued_limit; 668f0efa862SFelix Fietkau u32 tx_done; 669f0efa862SFelix Fietkau struct { 670f0efa862SFelix Fietkau u64 packets[__MT_RXQ_MAX]; 671f0efa862SFelix Fietkau u64 fcs_error[__MT_RXQ_MAX]; 672f0efa862SFelix Fietkau } rx_stats; 673f0efa862SFelix Fietkau }; 674f0efa862SFelix Fietkau 67585d96704SLorenzo Bianconi struct mt76_vif { 67685d96704SLorenzo Bianconi u8 idx; 67785d96704SLorenzo Bianconi u8 omac_idx; 67885d96704SLorenzo Bianconi u8 band_idx; 67985d96704SLorenzo Bianconi u8 wmm_idx; 68085d96704SLorenzo Bianconi u8 scan_seq_num; 6815ea3d983SFelix Fietkau u8 cipher; 68285d96704SLorenzo Bianconi }; 68385d96704SLorenzo Bianconi 684ac24dd35SFelix Fietkau struct mt76_phy { 685ac24dd35SFelix Fietkau struct ieee80211_hw *hw; 686ac24dd35SFelix Fietkau struct mt76_dev *dev; 687a3d01038SFelix Fietkau void *priv; 68896747a51SFelix Fietkau 689011849e0SFelix Fietkau unsigned long state; 690dc44c45cSLorenzo Bianconi u8 band_idx; 691011849e0SFelix Fietkau 69291990519SLorenzo Bianconi struct mt76_queue *q_tx[__MT_TXQ_MAX]; 69391990519SLorenzo Bianconi 69496747a51SFelix Fietkau struct cfg80211_chan_def chandef; 69596747a51SFelix Fietkau struct ieee80211_channel *main_chan; 69696747a51SFelix Fietkau 69796747a51SFelix Fietkau struct mt76_channel_state *chan_state; 6983f306448SFelix Fietkau enum mt76_dfs_state dfs_state; 69996747a51SFelix Fietkau ktime_t survey_time; 70096747a51SFelix Fietkau 701d107501aSLorenzo Bianconi u32 aggr_stats[32]; 702d107501aSLorenzo Bianconi 70348dbce5cSLorenzo Bianconi struct mt76_hw_cap cap; 70496747a51SFelix Fietkau struct mt76_sband sband_2g; 70596747a51SFelix Fietkau struct mt76_sband sband_5g; 706cee3fd29SLorenzo Bianconi struct mt76_sband sband_6g; 707beaaeb6bSFelix Fietkau 70898df2baeSLorenzo Bianconi u8 macaddr[ETH_ALEN]; 70998df2baeSLorenzo Bianconi 710beaaeb6bSFelix Fietkau int txpower_cur; 711beaaeb6bSFelix Fietkau u8 antenna_mask; 712b9027e08SLorenzo Bianconi u16 chainmask; 713c918c74dSShayne Chen 714c918c74dSShayne Chen #ifdef CONFIG_NL80211_TESTMODE 715c918c74dSShayne Chen struct mt76_testmode_data test; 716c918c74dSShayne Chen #endif 717a782f8bfSLorenzo Bianconi 718a782f8bfSLorenzo Bianconi struct delayed_work mac_work; 719a782f8bfSLorenzo Bianconi u8 mac_work_count; 720cc4b3c13SLorenzo Bianconi 721cc4b3c13SLorenzo Bianconi struct { 722cc4b3c13SLorenzo Bianconi struct sk_buff *head; 723cc4b3c13SLorenzo Bianconi struct sk_buff **tail; 724cc4b3c13SLorenzo Bianconi u16 seqno; 725cc4b3c13SLorenzo Bianconi } rx_amsdu[__MT_RXQ_MAX]; 726502604f5SYN Chen 727502604f5SYN Chen struct mt76_freq_range_power *frp; 728ac24dd35SFelix Fietkau }; 729ac24dd35SFelix Fietkau 73017f1de56SFelix Fietkau struct mt76_dev { 731ac24dd35SFelix Fietkau struct mt76_phy phy; /* must be first */ 732dc44c45cSLorenzo Bianconi struct mt76_phy *phys[__MT_MAX_BAND]; 733bfc394ddSFelix Fietkau 73417f1de56SFelix Fietkau struct ieee80211_hw *hw; 73517f1de56SFelix Fietkau 7362666beceSSujuan Chen spinlock_t wed_lock; 73717f1de56SFelix Fietkau spinlock_t lock; 73817f1de56SFelix Fietkau spinlock_t cc_lock; 739108a4861SStanislaw Gruszka 7405ce09c1aSFelix Fietkau u32 cur_cc_bss_rx; 7415ce09c1aSFelix Fietkau 7425ce09c1aSFelix Fietkau struct mt76_rx_status rx_ampdu_status; 7435ce09c1aSFelix Fietkau u32 rx_ampdu_len; 7445ce09c1aSFelix Fietkau u32 rx_ampdu_ref; 7455ce09c1aSFelix Fietkau 746108a4861SStanislaw Gruszka struct mutex mutex; 747108a4861SStanislaw Gruszka 74817f1de56SFelix Fietkau const struct mt76_bus_ops *bus; 74917f1de56SFelix Fietkau const struct mt76_driver_ops *drv; 750db0f04f3SLorenzo Bianconi const struct mt76_mcu_ops *mcu_ops; 75117f1de56SFelix Fietkau struct device *dev; 752d1ddc536SFelix Fietkau struct device *dma_dev; 75317f1de56SFelix Fietkau 75409872957SLorenzo Bianconi struct mt76_mcu mcu; 75509872957SLorenzo Bianconi 75617f1de56SFelix Fietkau struct net_device napi_dev; 757aa40528aSFelix Fietkau struct net_device tx_napi_dev; 758c3d7c82aSFelix Fietkau spinlock_t rx_lock; 75917f1de56SFelix Fietkau struct napi_struct napi[__MT_RXQ_MAX]; 76017f1de56SFelix Fietkau struct sk_buff_head rx_skb[__MT_RXQ_MAX]; 76117f1de56SFelix Fietkau 76217f1de56SFelix Fietkau struct list_head txwi_cache; 7632666beceSSujuan Chen struct list_head rxwi_cache; 764b1cb42adSLorenzo Bianconi struct mt76_queue *q_mcu[__MT_MCUQ_MAX]; 76517f1de56SFelix Fietkau struct mt76_queue q_rx[__MT_RXQ_MAX]; 76617f1de56SFelix Fietkau const struct mt76_queue_ops *queue_ops; 767c1e0d2beSLorenzo Bianconi int tx_dma_idx[4]; 76817f1de56SFelix Fietkau 769781eef5bSFelix Fietkau struct mt76_worker tx_worker; 7708402650aSLorenzo Bianconi struct napi_struct tx_napi; 771a33b8ab8SFelix Fietkau 772b17aff33SLorenzo Bianconi spinlock_t token_lock; 773b17aff33SLorenzo Bianconi struct idr token; 774f68d6762SFelix Fietkau u16 wed_token_count; 77561b5156bSFelix Fietkau u16 token_count; 77661b5156bSFelix Fietkau u16 token_size; 777b17aff33SLorenzo Bianconi 7782666beceSSujuan Chen spinlock_t rx_token_lock; 7792666beceSSujuan Chen struct idr rx_token; 7802666beceSSujuan Chen u16 rx_token_size; 7812666beceSSujuan Chen 78226e40d4cSFelix Fietkau wait_queue_head_t tx_wait; 783c34f1005SLorenzo Bianconi /* spinclock used to protect wcid pktid linked list */ 784c34f1005SLorenzo Bianconi spinlock_t status_lock; 78526e40d4cSFelix Fietkau 7865e616ad2SFelix Fietkau u32 wcid_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; 7875e616ad2SFelix Fietkau u32 wcid_phy_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; 78836404c06SStanislaw Gruszka 789b619e013SEvelyn Tsai u64 vif_mask; 7902ab33b8dSFelix Fietkau 79136404c06SStanislaw Gruszka struct mt76_wcid global_wcid; 79236404c06SStanislaw Gruszka struct mt76_wcid __rcu *wcid[MT76_N_WCIDS]; 793bd1e3e7bSLorenzo Bianconi struct list_head wcid_list; 79436404c06SStanislaw Gruszka 79517f1de56SFelix Fietkau u32 rev; 79617f1de56SFelix Fietkau 797dc6057f4SLorenzo Bianconi struct tasklet_struct pre_tbtt_tasklet; 7983041c445SLorenzo Bianconi int beacon_int; 799c8a04d98SLorenzo Bianconi u8 beacon_mask; 8003041c445SLorenzo Bianconi 80117f1de56SFelix Fietkau struct debugfs_blob_wrapper eeprom; 80217f1de56SFelix Fietkau struct debugfs_blob_wrapper otp; 80317f1de56SFelix Fietkau 8045b257371SLorenzo Bianconi char alpha2[3]; 805d8b8890dSLorenzo Bianconi enum nl80211_dfs_regions region; 806d8b8890dSLorenzo Bianconi 80717f1de56SFelix Fietkau u32 debugfs_reg; 80817f1de56SFelix Fietkau 80917f1de56SFelix Fietkau struct led_classdev led_cdev; 81017f1de56SFelix Fietkau char led_name[32]; 81117f1de56SFelix Fietkau bool led_al; 81217f1de56SFelix Fietkau u8 led_pin; 813b40b15e1SLorenzo Bianconi 814e7173858SFelix Fietkau u8 csa_complete; 815e7173858SFelix Fietkau 816108a4861SStanislaw Gruszka u32 rxfilter; 817108a4861SStanislaw Gruszka 818f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 819f0efa862SFelix Fietkau const struct mt76_testmode_ops *test_ops; 820e7a6a044SShayne Chen struct { 821e7a6a044SShayne Chen const char *name; 822e7a6a044SShayne Chen u32 offset; 823e7a6a044SShayne Chen } test_mtd; 824f0efa862SFelix Fietkau #endif 825a86f1d01SLorenzo Bianconi struct workqueue_struct *wq; 826a86f1d01SLorenzo Bianconi 827f7bbb80fSLorenzo Bianconi union { 828f7bbb80fSLorenzo Bianconi struct mt76_mmio mmio; 829b40b15e1SLorenzo Bianconi struct mt76_usb usb; 830d39b52e3SSean Wang struct mt76_sdio sdio; 83117f1de56SFelix Fietkau }; 832f7bbb80fSLorenzo Bianconi }; 83317f1de56SFelix Fietkau 83422b980baSFelix Fietkau struct mt76_power_limits { 83522b980baSFelix Fietkau s8 cck[4]; 83622b980baSFelix Fietkau s8 ofdm[8]; 83722b980baSFelix Fietkau s8 mcs[4][10]; 838a9627d99SShayne Chen s8 ru[7][12]; 83922b980baSFelix Fietkau }; 84022b980baSFelix Fietkau 84154ae98ffSLorenzo Bianconi struct mt76_ethtool_worker_info { 84254ae98ffSLorenzo Bianconi u64 *data; 84354ae98ffSLorenzo Bianconi int idx; 84454ae98ffSLorenzo Bianconi int initial_stat_idx; 84554ae98ffSLorenzo Bianconi int worker_stat_count; 84654ae98ffSLorenzo Bianconi int sta_count; 84754ae98ffSLorenzo Bianconi }; 84854ae98ffSLorenzo Bianconi 84954b8fdebSLorenzo Bianconi #define CCK_RATE(_idx, _rate) { \ 85054b8fdebSLorenzo Bianconi .bitrate = _rate, \ 85154b8fdebSLorenzo Bianconi .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ 85254b8fdebSLorenzo Bianconi .hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \ 85354b8fdebSLorenzo Bianconi .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + _idx), \ 85454b8fdebSLorenzo Bianconi } 85554b8fdebSLorenzo Bianconi 85654b8fdebSLorenzo Bianconi #define OFDM_RATE(_idx, _rate) { \ 85754b8fdebSLorenzo Bianconi .bitrate = _rate, \ 85854b8fdebSLorenzo Bianconi .hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 85954b8fdebSLorenzo Bianconi .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 86054b8fdebSLorenzo Bianconi } 86154b8fdebSLorenzo Bianconi 86254b8fdebSLorenzo Bianconi extern struct ieee80211_rate mt76_rates[12]; 86354b8fdebSLorenzo Bianconi 864d4131273SStanislaw Gruszka #define __mt76_rr(dev, ...) (dev)->bus->rr((dev), __VA_ARGS__) 865d4131273SStanislaw Gruszka #define __mt76_wr(dev, ...) (dev)->bus->wr((dev), __VA_ARGS__) 866d4131273SStanislaw Gruszka #define __mt76_rmw(dev, ...) (dev)->bus->rmw((dev), __VA_ARGS__) 86735e4ebeaSLorenzo Bianconi #define __mt76_wr_copy(dev, ...) (dev)->bus->write_copy((dev), __VA_ARGS__) 86835e4ebeaSLorenzo Bianconi #define __mt76_rr_copy(dev, ...) (dev)->bus->read_copy((dev), __VA_ARGS__) 869d4131273SStanislaw Gruszka 87022c575c4SStanislaw Gruszka #define __mt76_set(dev, offset, val) __mt76_rmw(dev, offset, 0, val) 87122c575c4SStanislaw Gruszka #define __mt76_clear(dev, offset, val) __mt76_rmw(dev, offset, val, 0) 87222c575c4SStanislaw Gruszka 87317f1de56SFelix Fietkau #define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__) 87417f1de56SFelix Fietkau #define mt76_wr(dev, ...) (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__) 87517f1de56SFelix Fietkau #define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__) 87635e4ebeaSLorenzo Bianconi #define mt76_wr_copy(dev, ...) (dev)->mt76.bus->write_copy(&((dev)->mt76), __VA_ARGS__) 87735e4ebeaSLorenzo Bianconi #define mt76_rr_copy(dev, ...) (dev)->mt76.bus->read_copy(&((dev)->mt76), __VA_ARGS__) 8786da5a291SStanislaw Gruszka #define mt76_wr_rp(dev, ...) (dev)->mt76.bus->wr_rp(&((dev)->mt76), __VA_ARGS__) 8796da5a291SStanislaw Gruszka #define mt76_rd_rp(dev, ...) (dev)->mt76.bus->rd_rp(&((dev)->mt76), __VA_ARGS__) 88017f1de56SFelix Fietkau 881f4d45fe2SLorenzo Bianconi 882e2c2fd0fSLorenzo Bianconi #define mt76_mcu_restart(dev, ...) (dev)->mt76.mcu_ops->mcu_restart(&((dev)->mt76)) 883e2c2fd0fSLorenzo Bianconi #define __mt76_mcu_restart(dev, ...) (dev)->mcu_ops->mcu_restart((dev)) 884db0f04f3SLorenzo Bianconi 88517f1de56SFelix Fietkau #define mt76_set(dev, offset, val) mt76_rmw(dev, offset, 0, val) 88617f1de56SFelix Fietkau #define mt76_clear(dev, offset, val) mt76_rmw(dev, offset, val, 0) 88717f1de56SFelix Fietkau 88817f1de56SFelix Fietkau #define mt76_get_field(_dev, _reg, _field) \ 88917f1de56SFelix Fietkau FIELD_GET(_field, mt76_rr(dev, _reg)) 89017f1de56SFelix Fietkau 89117f1de56SFelix Fietkau #define mt76_rmw_field(_dev, _reg, _field, _val) \ 89217f1de56SFelix Fietkau mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) 89317f1de56SFelix Fietkau 89446436b5eSStanislaw Gruszka #define __mt76_rmw_field(_dev, _reg, _field, _val) \ 89546436b5eSStanislaw Gruszka __mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) 89646436b5eSStanislaw Gruszka 897ac24dd35SFelix Fietkau #define mt76_hw(dev) (dev)->mphy.hw 89817f1de56SFelix Fietkau 89917f1de56SFelix Fietkau bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, 90017f1de56SFelix Fietkau int timeout); 90117f1de56SFelix Fietkau 90217f1de56SFelix Fietkau #define mt76_poll(dev, ...) __mt76_poll(&((dev)->mt76), __VA_ARGS__) 90317f1de56SFelix Fietkau 90417f1de56SFelix Fietkau bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, 90517f1de56SFelix Fietkau int timeout); 90617f1de56SFelix Fietkau 90717f1de56SFelix Fietkau #define mt76_poll_msec(dev, ...) __mt76_poll_msec(&((dev)->mt76), __VA_ARGS__) 90817f1de56SFelix Fietkau 90917f1de56SFelix Fietkau void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs); 910f37f0550SLorenzo Bianconi void mt76_pci_disable_aspm(struct pci_dev *pdev); 91117f1de56SFelix Fietkau 91217f1de56SFelix Fietkau static inline u16 mt76_chip(struct mt76_dev *dev) 91317f1de56SFelix Fietkau { 91417f1de56SFelix Fietkau return dev->rev >> 16; 91517f1de56SFelix Fietkau } 91617f1de56SFelix Fietkau 91717f1de56SFelix Fietkau static inline u16 mt76_rev(struct mt76_dev *dev) 91817f1de56SFelix Fietkau { 91917f1de56SFelix Fietkau return dev->rev & 0xffff; 92017f1de56SFelix Fietkau } 92117f1de56SFelix Fietkau 92217f1de56SFelix Fietkau #define mt76xx_chip(dev) mt76_chip(&((dev)->mt76)) 92317f1de56SFelix Fietkau #define mt76xx_rev(dev) mt76_rev(&((dev)->mt76)) 92417f1de56SFelix Fietkau 925cb8ed33dSLorenzo Bianconi #define mt76_init_queues(dev, ...) (dev)->mt76.queue_ops->init(&((dev)->mt76), __VA_ARGS__) 926a23fde09SLorenzo Bianconi #define mt76_queue_alloc(dev, ...) (dev)->mt76.queue_ops->alloc(&((dev)->mt76), __VA_ARGS__) 9275ed31128SLorenzo Bianconi #define mt76_tx_queue_skb_raw(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb_raw(&((dev)->mt76), __VA_ARGS__) 928eb9ca7ecSLorenzo Bianconi #define mt76_tx_queue_skb(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb(&((dev)->mt76), __VA_ARGS__) 92917f1de56SFelix Fietkau #define mt76_queue_rx_reset(dev, ...) (dev)->mt76.queue_ops->rx_reset(&((dev)->mt76), __VA_ARGS__) 93017f1de56SFelix Fietkau #define mt76_queue_tx_cleanup(dev, ...) (dev)->mt76.queue_ops->tx_cleanup(&((dev)->mt76), __VA_ARGS__) 931c001df97SLorenzo Bianconi #define mt76_queue_rx_cleanup(dev, ...) (dev)->mt76.queue_ops->rx_cleanup(&((dev)->mt76), __VA_ARGS__) 93217f1de56SFelix Fietkau #define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__) 9333990465dSLorenzo Bianconi #define mt76_queue_reset(dev, ...) (dev)->mt76.queue_ops->reset_q(&((dev)->mt76), __VA_ARGS__) 93417f1de56SFelix Fietkau 935f473b42aSFelix Fietkau #define mt76_for_each_q_rx(dev, i) \ 936b3ad9d6aSBo Jiao for (i = 0; i < ARRAY_SIZE((dev)->q_rx); i++) \ 937b3ad9d6aSBo Jiao if ((dev)->q_rx[i].ndesc) 938f473b42aSFelix Fietkau 939c0f7b25aSLorenzo Bianconi struct mt76_dev *mt76_alloc_device(struct device *pdev, unsigned int size, 940c0f7b25aSLorenzo Bianconi const struct ieee80211_ops *ops, 941c0f7b25aSLorenzo Bianconi const struct mt76_driver_ops *drv_ops); 94217f1de56SFelix Fietkau int mt76_register_device(struct mt76_dev *dev, bool vht, 94317f1de56SFelix Fietkau struct ieee80211_rate *rates, int n_rates); 94417f1de56SFelix Fietkau void mt76_unregister_device(struct mt76_dev *dev); 945def34a2fSLorenzo Bianconi void mt76_free_device(struct mt76_dev *dev); 946c89d3625SFelix Fietkau void mt76_unregister_phy(struct mt76_phy *phy); 947c89d3625SFelix Fietkau 948c89d3625SFelix Fietkau struct mt76_phy *mt76_alloc_phy(struct mt76_dev *dev, unsigned int size, 949dc44c45cSLorenzo Bianconi const struct ieee80211_ops *ops, 950dc44c45cSLorenzo Bianconi u8 band_idx); 951db78a791SLorenzo Bianconi int mt76_register_phy(struct mt76_phy *phy, bool vht, 952db78a791SLorenzo Bianconi struct ieee80211_rate *rates, int n_rates); 95317f1de56SFelix Fietkau 9543263039dSLorenzo Bianconi struct dentry *mt76_register_debugfs_fops(struct mt76_phy *phy, 955f6e1f598SLorenzo Bianconi const struct file_operations *ops); 956f6e1f598SLorenzo Bianconi static inline struct dentry *mt76_register_debugfs(struct mt76_dev *dev) 957f6e1f598SLorenzo Bianconi { 9583263039dSLorenzo Bianconi return mt76_register_debugfs_fops(&dev->phy, NULL); 959f6e1f598SLorenzo Bianconi } 960f6e1f598SLorenzo Bianconi 9610b82a8e8SLorenzo Bianconi int mt76_queues_read(struct seq_file *s, void *data); 9628f410a8bSLorenzo Bianconi void mt76_seq_puts_array(struct seq_file *file, const char *str, 9638f410a8bSLorenzo Bianconi s8 *val, int len); 96417f1de56SFelix Fietkau 96517f1de56SFelix Fietkau int mt76_eeprom_init(struct mt76_dev *dev, int len); 96698df2baeSLorenzo Bianconi void mt76_eeprom_override(struct mt76_phy *phy); 967495184acSRyder Lee int mt76_get_of_eeprom(struct mt76_dev *dev, void *data, int offset, int len); 96817f1de56SFelix Fietkau 969b1cb42adSLorenzo Bianconi struct mt76_queue * 970b1cb42adSLorenzo Bianconi mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc, 971f68d6762SFelix Fietkau int ring_base, u32 flags); 97233920b2bSRyder Lee u16 mt76_calculate_default_rate(struct mt76_phy *phy, int rateidx); 973b1cb42adSLorenzo Bianconi static inline int mt76_init_tx_queue(struct mt76_phy *phy, int qid, int idx, 974f68d6762SFelix Fietkau int n_desc, int ring_base, u32 flags) 975b1cb42adSLorenzo Bianconi { 976b1cb42adSLorenzo Bianconi struct mt76_queue *q; 977b1cb42adSLorenzo Bianconi 978f68d6762SFelix Fietkau q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base, flags); 979b1cb42adSLorenzo Bianconi if (IS_ERR(q)) 980b1cb42adSLorenzo Bianconi return PTR_ERR(q); 981b1cb42adSLorenzo Bianconi 98291990519SLorenzo Bianconi phy->q_tx[qid] = q; 983b1cb42adSLorenzo Bianconi 984b1cb42adSLorenzo Bianconi return 0; 985b1cb42adSLorenzo Bianconi } 986b1cb42adSLorenzo Bianconi 987b1cb42adSLorenzo Bianconi static inline int mt76_init_mcu_queue(struct mt76_dev *dev, int qid, int idx, 988b1cb42adSLorenzo Bianconi int n_desc, int ring_base) 989b1cb42adSLorenzo Bianconi { 990b1cb42adSLorenzo Bianconi struct mt76_queue *q; 991b1cb42adSLorenzo Bianconi 992f68d6762SFelix Fietkau q = mt76_init_queue(dev, qid, idx, n_desc, ring_base, 0); 993b1cb42adSLorenzo Bianconi if (IS_ERR(q)) 994b1cb42adSLorenzo Bianconi return PTR_ERR(q); 995b1cb42adSLorenzo Bianconi 996b1cb42adSLorenzo Bianconi dev->q_mcu[qid] = q; 997b1cb42adSLorenzo Bianconi 998b1cb42adSLorenzo Bianconi return 0; 999b1cb42adSLorenzo Bianconi } 1000b671da33SLorenzo Bianconi 1001011849e0SFelix Fietkau static inline struct mt76_phy * 1002128c9b7dSLorenzo Bianconi mt76_dev_phy(struct mt76_dev *dev, u8 phy_idx) 1003011849e0SFelix Fietkau { 1004dc44c45cSLorenzo Bianconi if ((phy_idx == MT_BAND1 && dev->phys[phy_idx]) || 1005dc44c45cSLorenzo Bianconi (phy_idx == MT_BAND2 && dev->phys[phy_idx])) 1006dc44c45cSLorenzo Bianconi return dev->phys[phy_idx]; 1007128c9b7dSLorenzo Bianconi 1008011849e0SFelix Fietkau return &dev->phy; 1009011849e0SFelix Fietkau } 1010011849e0SFelix Fietkau 1011bfc394ddSFelix Fietkau static inline struct ieee80211_hw * 1012128c9b7dSLorenzo Bianconi mt76_phy_hw(struct mt76_dev *dev, u8 phy_idx) 1013bfc394ddSFelix Fietkau { 1014128c9b7dSLorenzo Bianconi return mt76_dev_phy(dev, phy_idx)->hw; 1015bfc394ddSFelix Fietkau } 1016bfc394ddSFelix Fietkau 1017f3950a41SLorenzo Bianconi static inline u8 * 1018f3950a41SLorenzo Bianconi mt76_get_txwi_ptr(struct mt76_dev *dev, struct mt76_txwi_cache *t) 1019f3950a41SLorenzo Bianconi { 1020f3950a41SLorenzo Bianconi return (u8 *)t - dev->drv->txwi_size; 1021f3950a41SLorenzo Bianconi } 1022f3950a41SLorenzo Bianconi 1023ee8aa945SLorenzo Bianconi /* increment with wrap-around */ 1024ee8aa945SLorenzo Bianconi static inline int mt76_incr(int val, int size) 1025ee8aa945SLorenzo Bianconi { 1026ee8aa945SLorenzo Bianconi return (val + 1) & (size - 1); 1027ee8aa945SLorenzo Bianconi } 1028ee8aa945SLorenzo Bianconi 1029ee8aa945SLorenzo Bianconi /* decrement with wrap-around */ 1030ee8aa945SLorenzo Bianconi static inline int mt76_decr(int val, int size) 1031ee8aa945SLorenzo Bianconi { 1032ee8aa945SLorenzo Bianconi return (val - 1) & (size - 1); 1033ee8aa945SLorenzo Bianconi } 1034ee8aa945SLorenzo Bianconi 10351d0496c6SStanislaw Gruszka u8 mt76_ac_to_hwq(u8 ac); 1036b40b15e1SLorenzo Bianconi 103717f1de56SFelix Fietkau static inline struct ieee80211_txq * 103817f1de56SFelix Fietkau mtxq_to_txq(struct mt76_txq *mtxq) 103917f1de56SFelix Fietkau { 104017f1de56SFelix Fietkau void *ptr = mtxq; 104117f1de56SFelix Fietkau 104217f1de56SFelix Fietkau return container_of(ptr, struct ieee80211_txq, drv_priv); 104317f1de56SFelix Fietkau } 104417f1de56SFelix Fietkau 10459c68a57bSFelix Fietkau static inline struct ieee80211_sta * 10469c68a57bSFelix Fietkau wcid_to_sta(struct mt76_wcid *wcid) 10479c68a57bSFelix Fietkau { 10489c68a57bSFelix Fietkau void *ptr = wcid; 10499c68a57bSFelix Fietkau 10509c68a57bSFelix Fietkau if (!wcid || !wcid->sta) 10519c68a57bSFelix Fietkau return NULL; 10529c68a57bSFelix Fietkau 10539c68a57bSFelix Fietkau return container_of(ptr, struct ieee80211_sta, drv_priv); 10549c68a57bSFelix Fietkau } 10559c68a57bSFelix Fietkau 105688046b2cSFelix Fietkau static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb) 105788046b2cSFelix Fietkau { 105888046b2cSFelix Fietkau BUILD_BUG_ON(sizeof(struct mt76_tx_cb) > 105988046b2cSFelix Fietkau sizeof(IEEE80211_SKB_CB(skb)->status.status_driver_data)); 106088046b2cSFelix Fietkau return ((void *)IEEE80211_SKB_CB(skb)->status.status_driver_data); 106188046b2cSFelix Fietkau } 106288046b2cSFelix Fietkau 106377ae1d5eSRyder Lee static inline void *mt76_skb_get_hdr(struct sk_buff *skb) 106477ae1d5eSRyder Lee { 106577ae1d5eSRyder Lee struct mt76_rx_status mstat; 106677ae1d5eSRyder Lee u8 *data = skb->data; 106777ae1d5eSRyder Lee 106877ae1d5eSRyder Lee /* Alignment concerns */ 106977ae1d5eSRyder Lee BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he) % 4); 107077ae1d5eSRyder Lee BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he_mu) % 4); 107177ae1d5eSRyder Lee 107277ae1d5eSRyder Lee mstat = *((struct mt76_rx_status *)skb->cb); 107377ae1d5eSRyder Lee 107477ae1d5eSRyder Lee if (mstat.flag & RX_FLAG_RADIOTAP_HE) 107577ae1d5eSRyder Lee data += sizeof(struct ieee80211_radiotap_he); 107677ae1d5eSRyder Lee if (mstat.flag & RX_FLAG_RADIOTAP_HE_MU) 107777ae1d5eSRyder Lee data += sizeof(struct ieee80211_radiotap_he_mu); 107877ae1d5eSRyder Lee 107977ae1d5eSRyder Lee return data; 108077ae1d5eSRyder Lee } 108177ae1d5eSRyder Lee 10823bb45b5fSLorenzo Bianconi static inline void mt76_insert_hdr_pad(struct sk_buff *skb) 10833bb45b5fSLorenzo Bianconi { 10843bb45b5fSLorenzo Bianconi int len = ieee80211_get_hdrlen_from_skb(skb); 10853bb45b5fSLorenzo Bianconi 10863bb45b5fSLorenzo Bianconi if (len % 4 == 0) 10873bb45b5fSLorenzo Bianconi return; 10883bb45b5fSLorenzo Bianconi 10893bb45b5fSLorenzo Bianconi skb_push(skb, 2); 10903bb45b5fSLorenzo Bianconi memmove(skb->data, skb->data + 2, len); 10913bb45b5fSLorenzo Bianconi 10923bb45b5fSLorenzo Bianconi skb->data[len] = 0; 10933bb45b5fSLorenzo Bianconi skb->data[len + 1] = 0; 10943bb45b5fSLorenzo Bianconi } 10953bb45b5fSLorenzo Bianconi 10968548c6ebSFelix Fietkau static inline bool mt76_is_skb_pktid(u8 pktid) 10978548c6ebSFelix Fietkau { 10988548c6ebSFelix Fietkau if (pktid & MT_PACKET_ID_HAS_RATE) 10998548c6ebSFelix Fietkau return false; 11008548c6ebSFelix Fietkau 11018548c6ebSFelix Fietkau return pktid >= MT_PACKET_ID_FIRST; 11028548c6ebSFelix Fietkau } 11038548c6ebSFelix Fietkau 110407cda406SFelix Fietkau static inline u8 mt76_tx_power_nss_delta(u8 nss) 110507cda406SFelix Fietkau { 110607cda406SFelix Fietkau static const u8 nss_delta[4] = { 0, 6, 9, 12 }; 110707cda406SFelix Fietkau 110807cda406SFelix Fietkau return nss_delta[nss - 1]; 110907cda406SFelix Fietkau } 111007cda406SFelix Fietkau 1111c918c74dSShayne Chen static inline bool mt76_testmode_enabled(struct mt76_phy *phy) 1112f0efa862SFelix Fietkau { 1113f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 1114c918c74dSShayne Chen return phy->test.state != MT76_TM_STATE_OFF; 1115c918c74dSShayne Chen #else 1116c918c74dSShayne Chen return false; 1117c918c74dSShayne Chen #endif 1118c918c74dSShayne Chen } 1119c918c74dSShayne Chen 1120c918c74dSShayne Chen static inline bool mt76_is_testmode_skb(struct mt76_dev *dev, 1121c918c74dSShayne Chen struct sk_buff *skb, 1122c918c74dSShayne Chen struct ieee80211_hw **hw) 1123c918c74dSShayne Chen { 1124c918c74dSShayne Chen #ifdef CONFIG_NL80211_TESTMODE 1125dc44c45cSLorenzo Bianconi int i; 1126dc44c45cSLorenzo Bianconi 1127dc44c45cSLorenzo Bianconi for (i = 0; i < ARRAY_SIZE(dev->phys); i++) { 1128dc44c45cSLorenzo Bianconi struct mt76_phy *phy = dev->phys[i]; 1129dc44c45cSLorenzo Bianconi 1130dc44c45cSLorenzo Bianconi if (phy && skb == phy->test.tx_skb) { 1131dc44c45cSLorenzo Bianconi *hw = dev->phys[i]->hw; 1132c918c74dSShayne Chen return true; 1133dc44c45cSLorenzo Bianconi } 1134dc44c45cSLorenzo Bianconi } 1135dc44c45cSLorenzo Bianconi return false; 1136f0efa862SFelix Fietkau #else 1137f0efa862SFelix Fietkau return false; 1138f0efa862SFelix Fietkau #endif 1139f0efa862SFelix Fietkau } 1140f0efa862SFelix Fietkau 114117f1de56SFelix Fietkau void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb); 11429fba6d07SFelix Fietkau void mt76_tx(struct mt76_phy *dev, struct ieee80211_sta *sta, 114317f1de56SFelix Fietkau struct mt76_wcid *wcid, struct sk_buff *skb); 114417f1de56SFelix Fietkau void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq); 114591990519SLorenzo Bianconi void mt76_stop_tx_queues(struct mt76_phy *phy, struct ieee80211_sta *sta, 114617f1de56SFelix Fietkau bool send_bar); 1147c50d105aSFelix Fietkau void mt76_tx_check_agg_ssn(struct ieee80211_sta *sta, struct sk_buff *skb); 11489fba6d07SFelix Fietkau void mt76_txq_schedule(struct mt76_phy *phy, enum mt76_txq_id qid); 11499fba6d07SFelix Fietkau void mt76_txq_schedule_all(struct mt76_phy *phy); 1150335e97acSLorenzo Bianconi void mt76_tx_worker_run(struct mt76_dev *dev); 1151781eef5bSFelix Fietkau void mt76_tx_worker(struct mt76_worker *w); 115217f1de56SFelix Fietkau void mt76_release_buffered_frames(struct ieee80211_hw *hw, 115317f1de56SFelix Fietkau struct ieee80211_sta *sta, 115417f1de56SFelix Fietkau u16 tids, int nframes, 115517f1de56SFelix Fietkau enum ieee80211_frame_release_type reason, 115617f1de56SFelix Fietkau bool more_data); 11575a95ca41SFelix Fietkau bool mt76_has_tx_pending(struct mt76_phy *phy); 115896747a51SFelix Fietkau void mt76_set_channel(struct mt76_phy *phy); 1159c560b137SRyder Lee void mt76_update_survey(struct mt76_phy *phy); 116004414240SLorenzo Bianconi void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time); 116117f1de56SFelix Fietkau int mt76_get_survey(struct ieee80211_hw *hw, int idx, 116217f1de56SFelix Fietkau struct survey_info *survey); 1163a71b648eSRyder Lee int mt76_rx_signal(u8 chain_mask, s8 *chain_signal); 1164bb3e3fecSRyder Lee void mt76_set_stream_caps(struct mt76_phy *phy, bool vht); 116517f1de56SFelix Fietkau 1166aee5b8cfSFelix Fietkau int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid, 11677c4f744dSRyder Lee u16 ssn, u16 size); 1168aee5b8cfSFelix Fietkau void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid); 1169aee5b8cfSFelix Fietkau 117030ce7f44SFelix Fietkau void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, 117130ce7f44SFelix Fietkau struct ieee80211_key_conf *key); 117279d1c94cSFelix Fietkau 117379d1c94cSFelix Fietkau void mt76_tx_status_lock(struct mt76_dev *dev, struct sk_buff_head *list) 1174c34f1005SLorenzo Bianconi __acquires(&dev->status_lock); 117579d1c94cSFelix Fietkau void mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list) 1176c34f1005SLorenzo Bianconi __releases(&dev->status_lock); 117779d1c94cSFelix Fietkau 117888046b2cSFelix Fietkau int mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, 117988046b2cSFelix Fietkau struct sk_buff *skb); 118088046b2cSFelix Fietkau struct sk_buff *mt76_tx_status_skb_get(struct mt76_dev *dev, 118179d1c94cSFelix Fietkau struct mt76_wcid *wcid, int pktid, 118279d1c94cSFelix Fietkau struct sk_buff_head *list); 118379d1c94cSFelix Fietkau void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb, 118479d1c94cSFelix Fietkau struct sk_buff_head *list); 11850fe88644SFelix Fietkau void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb, 11860fe88644SFelix Fietkau struct list_head *free_list); 11870fe88644SFelix Fietkau static inline void 11880fe88644SFelix Fietkau mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb) 11890fe88644SFelix Fietkau { 11900fe88644SFelix Fietkau __mt76_tx_complete_skb(dev, wcid, skb, NULL); 11910fe88644SFelix Fietkau } 11920fe88644SFelix Fietkau 1193c02f86eeSLorenzo Bianconi void mt76_tx_status_check(struct mt76_dev *dev, bool flush); 1194e28487eaSFelix Fietkau int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1195e28487eaSFelix Fietkau struct ieee80211_sta *sta, 1196e28487eaSFelix Fietkau enum ieee80211_sta_state old_state, 1197e28487eaSFelix Fietkau enum ieee80211_sta_state new_state); 119813f61dfcSLorenzo Bianconi void __mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif, 119913f61dfcSLorenzo Bianconi struct ieee80211_sta *sta); 120043ba1922SFelix Fietkau void mt76_sta_pre_rcu_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 120143ba1922SFelix Fietkau struct ieee80211_sta *sta); 120230ce7f44SFelix Fietkau 12038af63fedSFelix Fietkau int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy); 1204ef13edc0SFelix Fietkau 12059313faacSFelix Fietkau int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 12069313faacSFelix Fietkau int *dbm); 1207b3cb885eSLorenzo Bianconi int mt76_init_sar_power(struct ieee80211_hw *hw, 1208b3cb885eSLorenzo Bianconi const struct cfg80211_sar_specs *sar); 1209b3cb885eSLorenzo Bianconi int mt76_get_sar_power(struct mt76_phy *phy, 1210b3cb885eSLorenzo Bianconi struct ieee80211_channel *chan, 1211b3cb885eSLorenzo Bianconi int power); 12129313faacSFelix Fietkau 1213e7173858SFelix Fietkau void mt76_csa_check(struct mt76_dev *dev); 1214e7173858SFelix Fietkau void mt76_csa_finish(struct mt76_dev *dev); 1215e7173858SFelix Fietkau 1216e49c76d4SLorenzo Bianconi int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 121787d53103SStanislaw Gruszka int mt76_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set); 1218eadfd98fSLorenzo Bianconi void mt76_insert_ccmp_hdr(struct sk_buff *skb, u8 key_id); 1219d2679d65SLorenzo Bianconi int mt76_get_rate(struct mt76_dev *dev, 1220d2679d65SLorenzo Bianconi struct ieee80211_supported_band *sband, 1221d2679d65SLorenzo Bianconi int idx, bool cck); 12228b8ab5c2SLorenzo Bianconi void mt76_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 12238b8ab5c2SLorenzo Bianconi const u8 *mac); 12248b8ab5c2SLorenzo Bianconi void mt76_sw_scan_complete(struct ieee80211_hw *hw, 12258b8ab5c2SLorenzo Bianconi struct ieee80211_vif *vif); 12263f306448SFelix Fietkau enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy); 1227f0efa862SFelix Fietkau int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1228f0efa862SFelix Fietkau void *data, int len); 1229f0efa862SFelix Fietkau int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, 1230f0efa862SFelix Fietkau struct netlink_callback *cb, void *data, int len); 1231c918c74dSShayne Chen int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state); 12322601dda8SShayne Chen int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len); 1233f0efa862SFelix Fietkau 1234c918c74dSShayne Chen static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable) 1235f0efa862SFelix Fietkau { 1236f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 1237f0efa862SFelix Fietkau enum mt76_testmode_state state = MT76_TM_STATE_IDLE; 1238f0efa862SFelix Fietkau 1239c918c74dSShayne Chen if (disable || phy->test.state == MT76_TM_STATE_OFF) 1240f0efa862SFelix Fietkau state = MT76_TM_STATE_OFF; 1241f0efa862SFelix Fietkau 1242c918c74dSShayne Chen mt76_testmode_set_state(phy, state); 1243f0efa862SFelix Fietkau #endif 1244f0efa862SFelix Fietkau } 1245f0efa862SFelix Fietkau 124687d53103SStanislaw Gruszka 124717f1de56SFelix Fietkau /* internal */ 1248e394b575SFelix Fietkau static inline struct ieee80211_hw * 1249e394b575SFelix Fietkau mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb) 1250e394b575SFelix Fietkau { 1251e394b575SFelix Fietkau struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1252a062f001SLorenzo Bianconi u8 phy_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2; 1253a062f001SLorenzo Bianconi struct ieee80211_hw *hw = mt76_phy_hw(dev, phy_idx); 1254e394b575SFelix Fietkau 1255a062f001SLorenzo Bianconi info->hw_queue &= ~MT_TX_HW_QUEUE_PHY; 1256e394b575SFelix Fietkau 1257e394b575SFelix Fietkau return hw; 1258e394b575SFelix Fietkau } 1259e394b575SFelix Fietkau 126017f1de56SFelix Fietkau void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); 12612666beceSSujuan Chen void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); 12622666beceSSujuan Chen struct mt76_txwi_cache *mt76_get_rxwi(struct mt76_dev *dev); 12639d9d738bSFelix Fietkau void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, 126481e850efSLorenzo Bianconi struct napi_struct *napi); 126581e850efSLorenzo Bianconi void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q, 126681e850efSLorenzo Bianconi struct napi_struct *napi); 1267aee5b8cfSFelix Fietkau void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames); 1268c918c74dSShayne Chen void mt76_testmode_tx_pending(struct mt76_phy *phy); 1269fe5b5ab5SFelix Fietkau void mt76_queue_tx_complete(struct mt76_dev *dev, struct mt76_queue *q, 1270fe5b5ab5SFelix Fietkau struct mt76_queue_entry *e); 127117f1de56SFelix Fietkau 1272b40b15e1SLorenzo Bianconi /* usb */ 1273b40b15e1SLorenzo Bianconi static inline bool mt76u_urb_error(struct urb *urb) 1274b40b15e1SLorenzo Bianconi { 1275b40b15e1SLorenzo Bianconi return urb->status && 1276b40b15e1SLorenzo Bianconi urb->status != -ECONNRESET && 1277b40b15e1SLorenzo Bianconi urb->status != -ESHUTDOWN && 1278b40b15e1SLorenzo Bianconi urb->status != -ENOENT; 1279b40b15e1SLorenzo Bianconi } 1280b40b15e1SLorenzo Bianconi 1281b40b15e1SLorenzo Bianconi /* Map hardware queues to usb endpoints */ 1282b40b15e1SLorenzo Bianconi static inline u8 q2ep(u8 qid) 1283b40b15e1SLorenzo Bianconi { 1284b40b15e1SLorenzo Bianconi /* TODO: take management packets to queue 5 */ 1285b40b15e1SLorenzo Bianconi return qid + 1; 1286b40b15e1SLorenzo Bianconi } 1287b40b15e1SLorenzo Bianconi 12885de4db8fSStanislaw Gruszka static inline int 1289b63aa031SStanislaw Gruszka mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len, 12903bcd979cSLorenzo Bianconi int timeout, int ep) 12915de4db8fSStanislaw Gruszka { 129280df01f4SLorenzo Bianconi struct usb_interface *uintf = to_usb_interface(dev->dev); 129380df01f4SLorenzo Bianconi struct usb_device *udev = interface_to_usbdev(uintf); 12945de4db8fSStanislaw Gruszka struct mt76_usb *usb = &dev->usb; 12955de4db8fSStanislaw Gruszka unsigned int pipe; 12965de4db8fSStanislaw Gruszka 1297b63aa031SStanislaw Gruszka if (actual_len) 12983bcd979cSLorenzo Bianconi pipe = usb_rcvbulkpipe(udev, usb->in_ep[ep]); 1299b63aa031SStanislaw Gruszka else 13003bcd979cSLorenzo Bianconi pipe = usb_sndbulkpipe(udev, usb->out_ep[ep]); 1301b63aa031SStanislaw Gruszka 1302b63aa031SStanislaw Gruszka return usb_bulk_msg(udev, pipe, data, len, actual_len, timeout); 13035de4db8fSStanislaw Gruszka } 13045de4db8fSStanislaw Gruszka 130554ae98ffSLorenzo Bianconi void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi, 130654ae98ffSLorenzo Bianconi struct mt76_sta_stats *stats); 1307e98e6df6SLorenzo Bianconi int mt76_skb_adjust_pad(struct sk_buff *skb, int pad); 13086cb596baSLorenzo Bianconi int __mt76u_vendor_request(struct mt76_dev *dev, u8 req, u8 req_type, 13096cb596baSLorenzo Bianconi u16 val, u16 offset, void *buf, size_t len); 1310b40b15e1SLorenzo Bianconi int mt76u_vendor_request(struct mt76_dev *dev, u8 req, 1311b40b15e1SLorenzo Bianconi u8 req_type, u16 val, u16 offset, 1312b40b15e1SLorenzo Bianconi void *buf, size_t len); 1313b40b15e1SLorenzo Bianconi void mt76u_single_wr(struct mt76_dev *dev, const u8 req, 1314b40b15e1SLorenzo Bianconi const u16 offset, const u32 val); 13156cb596baSLorenzo Bianconi void mt76u_read_copy(struct mt76_dev *dev, u32 offset, 13166cb596baSLorenzo Bianconi void *data, int len); 13176cb596baSLorenzo Bianconi u32 ___mt76u_rr(struct mt76_dev *dev, u8 req, u8 req_type, u32 addr); 13186cb596baSLorenzo Bianconi void ___mt76u_wr(struct mt76_dev *dev, u8 req, u8 req_type, 13196cb596baSLorenzo Bianconi u32 addr, u32 val); 13206cb596baSLorenzo Bianconi int __mt76u_init(struct mt76_dev *dev, struct usb_interface *intf, 13216cb596baSLorenzo Bianconi struct mt76_bus_ops *ops); 13226cb596baSLorenzo Bianconi int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf); 132394e1cfa8SLorenzo Bianconi int mt76u_alloc_mcu_queue(struct mt76_dev *dev); 1324b40b15e1SLorenzo Bianconi int mt76u_alloc_queues(struct mt76_dev *dev); 132539d501d9SStanislaw Gruszka void mt76u_stop_tx(struct mt76_dev *dev); 132639d501d9SStanislaw Gruszka void mt76u_stop_rx(struct mt76_dev *dev); 132739d501d9SStanislaw Gruszka int mt76u_resume_rx(struct mt76_dev *dev); 1328b40b15e1SLorenzo Bianconi void mt76u_queues_deinit(struct mt76_dev *dev); 1329b40b15e1SLorenzo Bianconi 1330d39b52e3SSean Wang int mt76s_init(struct mt76_dev *dev, struct sdio_func *func, 1331d39b52e3SSean Wang const struct mt76_bus_ops *bus_ops); 1332d512b008SLorenzo Bianconi int mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid); 1333d512b008SLorenzo Bianconi int mt76s_alloc_tx(struct mt76_dev *dev); 1334d39b52e3SSean Wang void mt76s_deinit(struct mt76_dev *dev); 1335764dee47SLorenzo Bianconi void mt76s_sdio_irq(struct sdio_func *func); 1336764dee47SLorenzo Bianconi void mt76s_txrx_worker(struct mt76_sdio *sdio); 1337ca74b9b9SSean Wang bool mt76s_txqs_empty(struct mt76_dev *dev); 1338dacf0acfSSean Wang int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, 1339dacf0acfSSean Wang int hw_ver); 1340764dee47SLorenzo Bianconi u32 mt76s_rr(struct mt76_dev *dev, u32 offset); 1341764dee47SLorenzo Bianconi void mt76s_wr(struct mt76_dev *dev, u32 offset, u32 val); 1342764dee47SLorenzo Bianconi u32 mt76s_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val); 1343764dee47SLorenzo Bianconi u32 mt76s_read_pcr(struct mt76_dev *dev); 1344764dee47SLorenzo Bianconi void mt76s_write_copy(struct mt76_dev *dev, u32 offset, 1345764dee47SLorenzo Bianconi const void *data, int len); 1346764dee47SLorenzo Bianconi void mt76s_read_copy(struct mt76_dev *dev, u32 offset, 1347764dee47SLorenzo Bianconi void *data, int len); 1348764dee47SLorenzo Bianconi int mt76s_wr_rp(struct mt76_dev *dev, u32 base, 1349764dee47SLorenzo Bianconi const struct mt76_reg_pair *data, 1350764dee47SLorenzo Bianconi int len); 1351764dee47SLorenzo Bianconi int mt76s_rd_rp(struct mt76_dev *dev, u32 base, 1352764dee47SLorenzo Bianconi struct mt76_reg_pair *data, int len); 1353d39b52e3SSean Wang 13549df0fab9SLorenzo Bianconi struct sk_buff * 1355a0a2034eSLorenzo Bianconi __mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, 1356b146f238SLorenzo Bianconi int len, int data_len, gfp_t gfp); 1357a0a2034eSLorenzo Bianconi static inline struct sk_buff * 1358bb31a80eSLorenzo Bianconi mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, 1359a0a2034eSLorenzo Bianconi int data_len) 1360a0a2034eSLorenzo Bianconi { 1361b146f238SLorenzo Bianconi return __mt76_mcu_msg_alloc(dev, data, data_len, data_len, GFP_KERNEL); 1362a0a2034eSLorenzo Bianconi } 1363a0a2034eSLorenzo Bianconi 1364c07a49d4SLorenzo Bianconi void mt76_mcu_rx_event(struct mt76_dev *dev, struct sk_buff *skb); 1365680abb25SLorenzo Bianconi struct sk_buff *mt76_mcu_get_response(struct mt76_dev *dev, 1366680abb25SLorenzo Bianconi unsigned long expires); 1367ae5ad627SFelix Fietkau int mt76_mcu_send_and_get_msg(struct mt76_dev *dev, int cmd, const void *data, 1368ae5ad627SFelix Fietkau int len, bool wait_resp, struct sk_buff **ret); 1369ae5ad627SFelix Fietkau int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, 1370ae5ad627SFelix Fietkau int cmd, bool wait_resp, struct sk_buff **ret); 1371215a2efaSLorenzo Bianconi int __mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data, 1372215a2efaSLorenzo Bianconi int len, int max_len); 1373215a2efaSLorenzo Bianconi static inline int 1374215a2efaSLorenzo Bianconi mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data, 1375215a2efaSLorenzo Bianconi int len) 1376215a2efaSLorenzo Bianconi { 13775b8f1840SSean Wang int max_len = 4096 - dev->mcu_ops->headroom; 13785b8f1840SSean Wang 13795b8f1840SSean Wang return __mt76_mcu_send_firmware(dev, cmd, data, len, max_len); 1380215a2efaSLorenzo Bianconi } 1381215a2efaSLorenzo Bianconi 1382ae5ad627SFelix Fietkau static inline int 1383ae5ad627SFelix Fietkau mt76_mcu_send_msg(struct mt76_dev *dev, int cmd, const void *data, int len, 1384ae5ad627SFelix Fietkau bool wait_resp) 1385ae5ad627SFelix Fietkau { 1386ae5ad627SFelix Fietkau return mt76_mcu_send_and_get_msg(dev, cmd, data, len, wait_resp, NULL); 1387ae5ad627SFelix Fietkau } 1388ae5ad627SFelix Fietkau 1389ae5ad627SFelix Fietkau static inline int 1390ae5ad627SFelix Fietkau mt76_mcu_skb_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, 1391ae5ad627SFelix Fietkau bool wait_resp) 1392ae5ad627SFelix Fietkau { 1393ae5ad627SFelix Fietkau return mt76_mcu_skb_send_and_get_msg(dev, skb, cmd, wait_resp, NULL); 1394ae5ad627SFelix Fietkau } 13959df0fab9SLorenzo Bianconi 13969220f695SLorenzo Bianconi void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set); 13979220f695SLorenzo Bianconi 139822b980baSFelix Fietkau s8 mt76_get_rate_power_limits(struct mt76_phy *phy, 139922b980baSFelix Fietkau struct ieee80211_channel *chan, 140022b980baSFelix Fietkau struct mt76_power_limits *dest, 140122b980baSFelix Fietkau s8 target_power); 140222b980baSFelix Fietkau 1403d089692bSLorenzo Bianconi struct mt76_txwi_cache * 1404d089692bSLorenzo Bianconi mt76_token_release(struct mt76_dev *dev, int token, bool *wake); 1405d089692bSLorenzo Bianconi int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi); 1406d089692bSLorenzo Bianconi void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked); 14072666beceSSujuan Chen struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token); 14082666beceSSujuan Chen int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr, 14092666beceSSujuan Chen struct mt76_txwi_cache *r, dma_addr_t phys); 1410d089692bSLorenzo Bianconi 1411d089692bSLorenzo Bianconi static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked) 1412d089692bSLorenzo Bianconi { 1413d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1414d089692bSLorenzo Bianconi __mt76_set_tx_blocked(dev, blocked); 1415d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1416d089692bSLorenzo Bianconi } 1417d089692bSLorenzo Bianconi 1418d089692bSLorenzo Bianconi static inline int 1419d089692bSLorenzo Bianconi mt76_token_get(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi) 1420d089692bSLorenzo Bianconi { 1421d089692bSLorenzo Bianconi int token; 1422d089692bSLorenzo Bianconi 1423d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 142461b5156bSFelix Fietkau token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC); 1425d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1426d089692bSLorenzo Bianconi 1427d089692bSLorenzo Bianconi return token; 1428d089692bSLorenzo Bianconi } 1429d089692bSLorenzo Bianconi 1430d089692bSLorenzo Bianconi static inline struct mt76_txwi_cache * 1431d089692bSLorenzo Bianconi mt76_token_put(struct mt76_dev *dev, int token) 1432d089692bSLorenzo Bianconi { 1433d089692bSLorenzo Bianconi struct mt76_txwi_cache *txwi; 1434d089692bSLorenzo Bianconi 1435d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1436d089692bSLorenzo Bianconi txwi = idr_remove(&dev->token, token); 1437d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1438d089692bSLorenzo Bianconi 1439d089692bSLorenzo Bianconi return txwi; 1440d089692bSLorenzo Bianconi } 144190052b84SLorenzo Bianconi 1442bd1e3e7bSLorenzo Bianconi static inline void mt76_packet_id_init(struct mt76_wcid *wcid) 144390052b84SLorenzo Bianconi { 1444bd1e3e7bSLorenzo Bianconi INIT_LIST_HEAD(&wcid->list); 1445bd1e3e7bSLorenzo Bianconi idr_init(&wcid->pktid); 144690052b84SLorenzo Bianconi } 1447bd1e3e7bSLorenzo Bianconi 1448bd1e3e7bSLorenzo Bianconi static inline void 1449bd1e3e7bSLorenzo Bianconi mt76_packet_id_flush(struct mt76_dev *dev, struct mt76_wcid *wcid) 1450bd1e3e7bSLorenzo Bianconi { 1451bd1e3e7bSLorenzo Bianconi struct sk_buff_head list; 1452bd1e3e7bSLorenzo Bianconi 1453bd1e3e7bSLorenzo Bianconi mt76_tx_status_lock(dev, &list); 1454bd1e3e7bSLorenzo Bianconi mt76_tx_status_skb_get(dev, wcid, -1, &list); 1455bd1e3e7bSLorenzo Bianconi mt76_tx_status_unlock(dev, &list); 1456bd1e3e7bSLorenzo Bianconi 1457bd1e3e7bSLorenzo Bianconi idr_destroy(&wcid->pktid); 1458bd1e3e7bSLorenzo Bianconi } 1459bd1e3e7bSLorenzo Bianconi 146017f1de56SFelix Fietkau #endif 1461