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; 2052f5c3c77SLorenzo Bianconi struct page_pool *page_pool; 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, 267c2eccffdSShayne Chen MT_PHY_TYPE_EHT_SU = 13, 268c2eccffdSShayne Chen MT_PHY_TYPE_EHT_TRIG, 269c2eccffdSShayne Chen MT_PHY_TYPE_EHT_MU, 270c2eccffdSShayne Chen __MT_PHY_TYPE_MAX, 271dc877523SRyder Lee }; 272dc877523SRyder Lee 273dc877523SRyder Lee struct mt76_sta_stats { 274c2eccffdSShayne Chen u64 tx_mode[__MT_PHY_TYPE_MAX]; 275731425f3SShayne Chen u64 tx_bw[5]; /* 20, 40, 80, 160, 320 */ 276dc877523SRyder Lee u64 tx_nss[4]; /* 1, 2, 3, 4 */ 277dc877523SRyder Lee u64 tx_mcs[16]; /* mcs idx */ 27843eaa368SRyder Lee u64 tx_bytes; 279c6cde7b7SSujuan Chen /* WED TX */ 28043eaa368SRyder Lee u32 tx_packets; 28143eaa368SRyder Lee u32 tx_retries; 28243eaa368SRyder Lee u32 tx_failed; 283c6cde7b7SSujuan Chen /* WED RX */ 284c6cde7b7SSujuan Chen u64 rx_bytes; 285c6cde7b7SSujuan Chen u32 rx_packets; 286c6cde7b7SSujuan Chen u32 rx_errors; 287c6cde7b7SSujuan Chen u32 rx_drops; 288dc877523SRyder Lee }; 289dc877523SRyder Lee 290d71ef286SFelix Fietkau enum mt76_wcid_flags { 291d71ef286SFelix Fietkau MT_WCID_FLAG_CHECK_PS, 292d71ef286SFelix Fietkau MT_WCID_FLAG_PS, 293e151d71eSFelix Fietkau MT_WCID_FLAG_4ADDR, 29490e3abf0SFelix Fietkau MT_WCID_FLAG_HDR_TRANS, 295d71ef286SFelix Fietkau }; 296d71ef286SFelix Fietkau 2976b733f7cSShayne Chen #define MT76_N_WCIDS 1088 29836404c06SStanislaw Gruszka 299e394b575SFelix Fietkau /* stored in ieee80211_tx_info::hw_queue */ 300a062f001SLorenzo Bianconi #define MT_TX_HW_QUEUE_PHY GENMASK(3, 2) 301e394b575SFelix Fietkau 302ef13edc0SFelix Fietkau DECLARE_EWMA(signal, 10, 8); 303ef13edc0SFelix Fietkau 304db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_RATE GENMASK(15, 0) 305db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_NSS GENMASK(17, 16) 306db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_TXPWR_ADJ GENMASK(25, 18) 307db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_SET BIT(31) 308db9f11d3SFelix Fietkau 30917f1de56SFelix Fietkau struct mt76_wcid { 310aee5b8cfSFelix Fietkau struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS]; 311aee5b8cfSFelix Fietkau 312e1378e52SFelix Fietkau atomic_t non_aql_packets; 313d71ef286SFelix Fietkau unsigned long flags; 314d71ef286SFelix Fietkau 315ef13edc0SFelix Fietkau struct ewma_signal rssi; 316ef13edc0SFelix Fietkau int inactive_count; 317ef13edc0SFelix Fietkau 3189908d98aSRyder Lee struct rate_info rate; 3199908d98aSRyder Lee 32049e649c3SRyder Lee u16 idx; 32117f1de56SFelix Fietkau u8 hw_key_idx; 322730d6d0dSFelix Fietkau u8 hw_key_idx2; 32317f1de56SFelix Fietkau 3249c68a57bSFelix Fietkau u8 sta:1; 325b443e55fSRyder Lee u8 amsdu:1; 326a1a99d7bSLorenzo Bianconi u8 phy_idx:2; 3279c68a57bSFelix Fietkau 32830ce7f44SFelix Fietkau u8 rx_check_pn; 329a1b0bbd4SXing Song u8 rx_key_pn[IEEE80211_NUM_TIDS + 1][6]; 33001cfc1b4SLorenzo Bianconi u16 cipher; 33130ce7f44SFelix Fietkau 332db9f11d3SFelix Fietkau u32 tx_info; 33323405236SFelix Fietkau bool sw_iv; 33488046b2cSFelix Fietkau 335bd1e3e7bSLorenzo Bianconi struct list_head list; 336bd1e3e7bSLorenzo Bianconi struct idr pktid; 337dc877523SRyder Lee 338dc877523SRyder Lee struct mt76_sta_stats stats; 33917f1de56SFelix Fietkau }; 34017f1de56SFelix Fietkau 34117f1de56SFelix Fietkau struct mt76_txq { 34251fb1278SFelix Fietkau u16 wcid; 34317f1de56SFelix Fietkau 34417f1de56SFelix Fietkau u16 agg_ssn; 34517f1de56SFelix Fietkau bool send_bar; 34617f1de56SFelix Fietkau bool aggr; 34717f1de56SFelix Fietkau }; 34817f1de56SFelix Fietkau 34917f1de56SFelix Fietkau struct mt76_txwi_cache { 35017f1de56SFelix Fietkau struct list_head list; 351f3950a41SLorenzo Bianconi dma_addr_t dma_addr; 3526ca66722SLorenzo Bianconi 3532666beceSSujuan Chen union { 3546ca66722SLorenzo Bianconi struct sk_buff *skb; 3552666beceSSujuan Chen void *ptr; 3562666beceSSujuan Chen }; 35717f1de56SFelix Fietkau }; 35817f1de56SFelix Fietkau 359aee5b8cfSFelix Fietkau struct mt76_rx_tid { 360aee5b8cfSFelix Fietkau struct rcu_head rcu_head; 361aee5b8cfSFelix Fietkau 362aee5b8cfSFelix Fietkau struct mt76_dev *dev; 363aee5b8cfSFelix Fietkau 364aee5b8cfSFelix Fietkau spinlock_t lock; 365aee5b8cfSFelix Fietkau struct delayed_work reorder_work; 366aee5b8cfSFelix Fietkau 367aee5b8cfSFelix Fietkau u16 head; 3687c4f744dSRyder Lee u16 size; 3697c4f744dSRyder Lee u16 nframes; 370aee5b8cfSFelix Fietkau 371e7ec563eSMarkus Theil u8 num; 372e7ec563eSMarkus Theil 373aee5b8cfSFelix Fietkau u8 started:1, stopped:1, timer_pending:1; 374aee5b8cfSFelix Fietkau 375aee5b8cfSFelix Fietkau struct sk_buff *reorder_buf[]; 376aee5b8cfSFelix Fietkau }; 377aee5b8cfSFelix Fietkau 37888046b2cSFelix Fietkau #define MT_TX_CB_DMA_DONE BIT(0) 37988046b2cSFelix Fietkau #define MT_TX_CB_TXS_DONE BIT(1) 38088046b2cSFelix Fietkau #define MT_TX_CB_TXS_FAILED BIT(2) 38188046b2cSFelix Fietkau 3828548c6ebSFelix Fietkau #define MT_PACKET_ID_MASK GENMASK(6, 0) 383013b2dffSFelix Fietkau #define MT_PACKET_ID_NO_ACK 0 384013b2dffSFelix Fietkau #define MT_PACKET_ID_NO_SKB 1 38543eaa368SRyder Lee #define MT_PACKET_ID_WED 2 38643eaa368SRyder Lee #define MT_PACKET_ID_FIRST 3 3878548c6ebSFelix Fietkau #define MT_PACKET_ID_HAS_RATE BIT(7) 388c4a784e3SLorenzo Bianconi /* This is timer for when to give up when waiting for TXS callback, 389c4a784e3SLorenzo Bianconi * with starting time being the time at which the DMA_DONE callback 390c4a784e3SLorenzo Bianconi * was seen (so, we know packet was processed then, it should not take 391c4a784e3SLorenzo Bianconi * long after that for firmware to send the TXS callback if it is going 392c4a784e3SLorenzo Bianconi * to do so.) 393c4a784e3SLorenzo Bianconi */ 394c4a784e3SLorenzo Bianconi #define MT_TX_STATUS_SKB_TIMEOUT (HZ / 4) 39588046b2cSFelix Fietkau 39688046b2cSFelix Fietkau struct mt76_tx_cb { 39788046b2cSFelix Fietkau unsigned long jiffies; 39849e649c3SRyder Lee u16 wcid; 39988046b2cSFelix Fietkau u8 pktid; 40088046b2cSFelix Fietkau u8 flags; 40188046b2cSFelix Fietkau }; 40288046b2cSFelix Fietkau 40317f1de56SFelix Fietkau enum { 40417f1de56SFelix Fietkau MT76_STATE_INITIALIZED, 40517f1de56SFelix Fietkau MT76_STATE_RUNNING, 40687e022deSStanislaw Gruszka MT76_STATE_MCU_RUNNING, 40717f1de56SFelix Fietkau MT76_SCANNING, 408fcdfc29eSLorenzo Bianconi MT76_HW_SCANNING, 40920305f98SLorenzo Bianconi MT76_HW_SCHED_SCANNING, 410fd6c2dfaSFelix Fietkau MT76_RESTART, 41117f1de56SFelix Fietkau MT76_RESET, 41261c4fa72SFelix Fietkau MT76_MCU_RESET, 413b40b15e1SLorenzo Bianconi MT76_REMOVED, 414b40b15e1SLorenzo Bianconi MT76_READING_STATS, 415eb99cc95SLorenzo Bianconi MT76_STATE_POWER_OFF, 416c6bf2010SLorenzo Bianconi MT76_STATE_SUSPEND, 4177307f296SLorenzo Bianconi MT76_STATE_ROC, 41808523a2aSLorenzo Bianconi MT76_STATE_PM, 419*36b7fce1SLorenzo Bianconi MT76_STATE_WED_RESET, 42017f1de56SFelix Fietkau }; 42117f1de56SFelix Fietkau 42217f1de56SFelix Fietkau struct mt76_hw_cap { 42317f1de56SFelix Fietkau bool has_2ghz; 42417f1de56SFelix Fietkau bool has_5ghz; 425f7d2958cSLorenzo Bianconi bool has_6ghz; 42617f1de56SFelix Fietkau }; 42717f1de56SFelix Fietkau 4289ec0b821SFelix Fietkau #define MT_DRV_TXWI_NO_FREE BIT(0) 4299ec0b821SFelix Fietkau #define MT_DRV_TX_ALIGNED4_SKBS BIT(1) 4305ce09c1aSFelix Fietkau #define MT_DRV_SW_RX_AIRTIME BIT(2) 43194d4d076SLorenzo Bianconi #define MT_DRV_RX_DMA_HDR BIT(3) 432d3c82998SLorenzo Bianconi #define MT_DRV_HW_MGMT_TXQ BIT(4) 4335b0fb852SBen Greear #define MT_DRV_AMSDU_OFFLOAD BIT(5) 4346ca66722SLorenzo Bianconi 43517f1de56SFelix Fietkau struct mt76_driver_ops { 4369ec0b821SFelix Fietkau u32 drv_flags; 437ea565833SFelix Fietkau u32 survey_flags; 43817f1de56SFelix Fietkau u16 txwi_size; 439d089692bSLorenzo Bianconi u16 token_size; 44022b980baSFelix Fietkau u8 mcs_rates; 44117f1de56SFelix Fietkau 442c560b137SRyder Lee void (*update_survey)(struct mt76_phy *phy); 44317f1de56SFelix Fietkau 44417f1de56SFelix Fietkau int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr, 445cfaae9e6SLorenzo Bianconi enum mt76_txq_id qid, struct mt76_wcid *wcid, 446b5903c47SLorenzo Bianconi struct ieee80211_sta *sta, 447b5903c47SLorenzo Bianconi struct mt76_tx_info *tx_info); 44817f1de56SFelix Fietkau 449d80e52c7SFelix Fietkau void (*tx_complete_skb)(struct mt76_dev *dev, 450e226ba2eSLorenzo Bianconi struct mt76_queue_entry *e); 45117f1de56SFelix Fietkau 452b40b15e1SLorenzo Bianconi bool (*tx_status_data)(struct mt76_dev *dev, u8 *update); 453b40b15e1SLorenzo Bianconi 454fbe50d9aSFelix Fietkau bool (*rx_check)(struct mt76_dev *dev, void *data, int len); 455fbe50d9aSFelix Fietkau 45617f1de56SFelix Fietkau void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q, 457c3137942SSujuan Chen struct sk_buff *skb, u32 *info); 45817f1de56SFelix Fietkau 45917f1de56SFelix Fietkau void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q); 460d71ef286SFelix Fietkau 461d71ef286SFelix Fietkau void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta, 462d71ef286SFelix Fietkau bool ps); 463e28487eaSFelix Fietkau 464e28487eaSFelix Fietkau int (*sta_add)(struct mt76_dev *dev, struct ieee80211_vif *vif, 465e28487eaSFelix Fietkau struct ieee80211_sta *sta); 466e28487eaSFelix Fietkau 4679c193de5SFelix Fietkau void (*sta_assoc)(struct mt76_dev *dev, struct ieee80211_vif *vif, 4689c193de5SFelix Fietkau struct ieee80211_sta *sta); 4699c193de5SFelix Fietkau 470e28487eaSFelix Fietkau void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif, 471e28487eaSFelix Fietkau struct ieee80211_sta *sta); 47217f1de56SFelix Fietkau }; 47317f1de56SFelix Fietkau 47417f1de56SFelix Fietkau struct mt76_channel_state { 47517f1de56SFelix Fietkau u64 cc_active; 47617f1de56SFelix Fietkau u64 cc_busy; 4776bfa6e38SLorenzo Bianconi u64 cc_rx; 4785ce09c1aSFelix Fietkau u64 cc_bss_rx; 479ea565833SFelix Fietkau u64 cc_tx; 480e5051965SFelix Fietkau 481e5051965SFelix Fietkau s8 noise; 48217f1de56SFelix Fietkau }; 48317f1de56SFelix Fietkau 48417f1de56SFelix Fietkau struct mt76_sband { 48517f1de56SFelix Fietkau struct ieee80211_supported_band sband; 48617f1de56SFelix Fietkau struct mt76_channel_state *chan; 48717f1de56SFelix Fietkau }; 48817f1de56SFelix Fietkau 489b40b15e1SLorenzo Bianconi /* addr req mask */ 490b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_EEPROM BIT(31) 491b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_CFG BIT(30) 492b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_MASK (MT_VEND_TYPE_EEPROM | MT_VEND_TYPE_CFG) 493b40b15e1SLorenzo Bianconi 494b40b15e1SLorenzo Bianconi #define MT_VEND_ADDR(type, n) (MT_VEND_TYPE_##type | (n)) 495b40b15e1SLorenzo Bianconi enum mt_vendor_req { 496b40b15e1SLorenzo Bianconi MT_VEND_DEV_MODE = 0x1, 497b40b15e1SLorenzo Bianconi MT_VEND_WRITE = 0x2, 4981e816c65SLorenzo Bianconi MT_VEND_POWER_ON = 0x4, 499b40b15e1SLorenzo Bianconi MT_VEND_MULTI_WRITE = 0x6, 500b40b15e1SLorenzo Bianconi MT_VEND_MULTI_READ = 0x7, 501b40b15e1SLorenzo Bianconi MT_VEND_READ_EEPROM = 0x9, 502b40b15e1SLorenzo Bianconi MT_VEND_WRITE_FCE = 0x42, 503b40b15e1SLorenzo Bianconi MT_VEND_WRITE_CFG = 0x46, 504b40b15e1SLorenzo Bianconi MT_VEND_READ_CFG = 0x47, 5051e816c65SLorenzo Bianconi MT_VEND_READ_EXT = 0x63, 5061e816c65SLorenzo Bianconi MT_VEND_WRITE_EXT = 0x66, 507d0846f08SSean Wang MT_VEND_FEATURE_SET = 0x91, 508b40b15e1SLorenzo Bianconi }; 509b40b15e1SLorenzo Bianconi 510b40b15e1SLorenzo Bianconi enum mt76u_in_ep { 511b40b15e1SLorenzo Bianconi MT_EP_IN_PKT_RX, 512b40b15e1SLorenzo Bianconi MT_EP_IN_CMD_RESP, 513b40b15e1SLorenzo Bianconi __MT_EP_IN_MAX, 514b40b15e1SLorenzo Bianconi }; 515b40b15e1SLorenzo Bianconi 516b40b15e1SLorenzo Bianconi enum mt76u_out_ep { 517b40b15e1SLorenzo Bianconi MT_EP_OUT_INBAND_CMD, 518b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_BE, 51923cb16d2SLorenzo Bianconi MT_EP_OUT_AC_BK, 520b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_VI, 521b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_VO, 522b40b15e1SLorenzo Bianconi MT_EP_OUT_HCCA, 523b40b15e1SLorenzo Bianconi __MT_EP_OUT_MAX, 524b40b15e1SLorenzo Bianconi }; 525b40b15e1SLorenzo Bianconi 52609872957SLorenzo Bianconi struct mt76_mcu { 52709872957SLorenzo Bianconi struct mutex mutex; 52809872957SLorenzo Bianconi u32 msg_seq; 529e452c6ebSFelix Fietkau int timeout; 53009872957SLorenzo Bianconi 53109872957SLorenzo Bianconi struct sk_buff_head res_q; 53209872957SLorenzo Bianconi wait_queue_head_t wait; 53309872957SLorenzo Bianconi }; 53409872957SLorenzo Bianconi 53514663f0cSLorenzo Bianconi #define MT_TX_SG_MAX_SIZE 8 536972c5981SSean Wang #define MT_RX_SG_MAX_SIZE 4 537b40b15e1SLorenzo Bianconi #define MT_NUM_TX_ENTRIES 256 538b40b15e1SLorenzo Bianconi #define MT_NUM_RX_ENTRIES 128 539b40b15e1SLorenzo Bianconi #define MCU_RESP_URB_SIZE 1024 540b40b15e1SLorenzo Bianconi struct mt76_usb { 541b40b15e1SLorenzo Bianconi struct mutex usb_ctrl_mtx; 542a6bfb6d1SStanislaw Gruszka u8 *data; 543a6bfb6d1SStanislaw Gruszka u16 data_len; 544b40b15e1SLorenzo Bianconi 5459daf27e6SLorenzo Bianconi struct mt76_worker status_worker; 546be83a7e2SLorenzo Bianconi struct mt76_worker rx_worker; 5479daf27e6SLorenzo Bianconi 548284efb47SLorenzo Bianconi struct work_struct stat_work; 549b40b15e1SLorenzo Bianconi 550b40b15e1SLorenzo Bianconi u8 out_ep[__MT_EP_OUT_MAX]; 551b40b15e1SLorenzo Bianconi u8 in_ep[__MT_EP_IN_MAX]; 55263a7de5dSLorenzo Bianconi bool sg_en; 553b40b15e1SLorenzo Bianconi 554b40b15e1SLorenzo Bianconi struct mt76u_mcu { 555a18a494fSStanislaw Gruszka u8 *data; 556851ab66eSLorenzo Bianconi /* multiple reads */ 557851ab66eSLorenzo Bianconi struct mt76_reg_pair *rp; 558851ab66eSLorenzo Bianconi int rp_len; 559851ab66eSLorenzo Bianconi u32 base; 560b40b15e1SLorenzo Bianconi } mcu; 561b40b15e1SLorenzo Bianconi }; 562b40b15e1SLorenzo Bianconi 563bf08d585SSean Wang #define MT76S_XMIT_BUF_SZ 0x3fe00 564b1460bb4SDeren Wu #define MT76S_NUM_TX_ENTRIES 256 565b1460bb4SDeren Wu #define MT76S_NUM_RX_ENTRIES 512 566d39b52e3SSean Wang struct mt76_sdio { 567fefb584dSLorenzo Bianconi struct mt76_worker txrx_worker; 5686a618acbSLorenzo Bianconi struct mt76_worker status_worker; 5696a618acbSLorenzo Bianconi struct mt76_worker net_worker; 5706a618acbSLorenzo Bianconi 571d74fda4cSLorenzo Bianconi struct work_struct stat_work; 572974327a4SLorenzo Bianconi 573bf08d585SSean Wang u8 *xmit_buf; 574bf08d585SSean Wang u32 xmit_buf_sz; 5751522ff73SLorenzo Bianconi 576d39b52e3SSean Wang struct sdio_func *func; 577b4964908SSean Wang void *intr_data; 578dacf0acfSSean Wang u8 hw_ver; 579ca74b9b9SSean Wang wait_queue_head_t wait; 580d39b52e3SSean Wang 581d39b52e3SSean Wang struct { 582d39b52e3SSean Wang int pse_data_quota; 583d39b52e3SSean Wang int ple_data_quota; 584d39b52e3SSean Wang int pse_mcu_quota; 5858c94f0e6SSean Wang int pse_page_size; 586d39b52e3SSean Wang int deficit; 587d39b52e3SSean Wang } sched; 5883ad08509SLorenzo Bianconi 5893ad08509SLorenzo Bianconi int (*parse_irq)(struct mt76_dev *dev, struct mt76s_intr *intr); 590d39b52e3SSean Wang }; 591d39b52e3SSean Wang 592f7bbb80fSLorenzo Bianconi struct mt76_mmio { 59327db1ad1SLorenzo Bianconi void __iomem *regs; 594957068c2SLorenzo Bianconi spinlock_t irq_lock; 595957068c2SLorenzo Bianconi u32 irqmask; 596f68d6762SFelix Fietkau 597f68d6762SFelix Fietkau struct mtk_wed_device wed; 598*36b7fce1SLorenzo Bianconi struct completion wed_reset; 599*36b7fce1SLorenzo Bianconi struct completion wed_reset_complete; 600f7bbb80fSLorenzo Bianconi }; 601f7bbb80fSLorenzo Bianconi 6025ce09c1aSFelix Fietkau struct mt76_rx_status { 6035ce09c1aSFelix Fietkau union { 6045ce09c1aSFelix Fietkau struct mt76_wcid *wcid; 60549e649c3SRyder Lee u16 wcid_idx; 6065ce09c1aSFelix Fietkau }; 6075ce09c1aSFelix Fietkau 6080fda6d7bSRyder Lee u32 reorder_time; 6095ce09c1aSFelix Fietkau 6105ce09c1aSFelix Fietkau u32 ampdu_ref; 6110fda6d7bSRyder Lee u32 timestamp; 6125ce09c1aSFelix Fietkau 6135ce09c1aSFelix Fietkau u8 iv[6]; 6145ce09c1aSFelix Fietkau 615128c9b7dSLorenzo Bianconi u8 phy_idx:2; 6165ce09c1aSFelix Fietkau u8 aggr:1; 617e195dad1SFelix Fietkau u8 qos_ctl; 6185ce09c1aSFelix Fietkau u16 seqno; 6195ce09c1aSFelix Fietkau 6205ce09c1aSFelix Fietkau u16 freq; 6215ce09c1aSFelix Fietkau u32 flag; 6225ce09c1aSFelix Fietkau u8 enc_flags; 623af4a2f2fSRyder Lee u8 encoding:2, bw:3, he_ru:3; 624af4a2f2fSRyder Lee u8 he_gi:2, he_dcm:1; 625cc4b3c13SLorenzo Bianconi u8 amsdu:1, first_amsdu:1, last_amsdu:1; 6265ce09c1aSFelix Fietkau u8 rate_idx; 6275ce09c1aSFelix Fietkau u8 nss; 6285ce09c1aSFelix Fietkau u8 band; 6295ce09c1aSFelix Fietkau s8 signal; 6305ce09c1aSFelix Fietkau u8 chains; 6315ce09c1aSFelix Fietkau s8 chain_signal[IEEE80211_MAX_CHAINS]; 6325ce09c1aSFelix Fietkau }; 6335ce09c1aSFelix Fietkau 634502604f5SYN Chen struct mt76_freq_range_power { 635502604f5SYN Chen const struct cfg80211_sar_freq_ranges *range; 636502604f5SYN Chen s8 power; 637502604f5SYN Chen }; 638502604f5SYN Chen 639f0efa862SFelix Fietkau struct mt76_testmode_ops { 640c918c74dSShayne Chen int (*set_state)(struct mt76_phy *phy, enum mt76_testmode_state state); 641c918c74dSShayne Chen int (*set_params)(struct mt76_phy *phy, struct nlattr **tb, 642f0efa862SFelix Fietkau enum mt76_testmode_state new_state); 643c918c74dSShayne Chen int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg); 644f0efa862SFelix Fietkau }; 645f0efa862SFelix Fietkau 646f0efa862SFelix Fietkau struct mt76_testmode_data { 647f0efa862SFelix Fietkau enum mt76_testmode_state state; 648f0efa862SFelix Fietkau 649f0efa862SFelix Fietkau u32 param_set[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)]; 650f0efa862SFelix Fietkau struct sk_buff *tx_skb; 651f0efa862SFelix Fietkau 652f0efa862SFelix Fietkau u32 tx_count; 6532601dda8SShayne Chen u16 tx_mpdu_len; 654f0efa862SFelix Fietkau 655f0efa862SFelix Fietkau u8 tx_rate_mode; 656f0efa862SFelix Fietkau u8 tx_rate_idx; 657f0efa862SFelix Fietkau u8 tx_rate_nss; 658f0efa862SFelix Fietkau u8 tx_rate_sgi; 659f0efa862SFelix Fietkau u8 tx_rate_ldpc; 6607f54c742SShayne Chen u8 tx_rate_stbc; 6611a38c2f5SShayne Chen u8 tx_ltf; 662f0efa862SFelix Fietkau 663f0efa862SFelix Fietkau u8 tx_antenna_mask; 664fdc9c18eSShayne Chen u8 tx_spe_idx; 665f0efa862SFelix Fietkau 666b8cbdb97SShayne Chen u8 tx_duty_cycle; 667b8cbdb97SShayne Chen u32 tx_time; 668b8cbdb97SShayne Chen u32 tx_ipg; 669b8cbdb97SShayne Chen 670f0efa862SFelix Fietkau u32 freq_offset; 671f0efa862SFelix Fietkau 672f0efa862SFelix Fietkau u8 tx_power[4]; 673f0efa862SFelix Fietkau u8 tx_power_control; 674f0efa862SFelix Fietkau 675c40b42c2SShayne Chen u8 addr[3][ETH_ALEN]; 676c40b42c2SShayne Chen 677f0efa862SFelix Fietkau u32 tx_pending; 678f0efa862SFelix Fietkau u32 tx_queued; 679ba459094SShayne Chen u16 tx_queued_limit; 680f0efa862SFelix Fietkau u32 tx_done; 681f0efa862SFelix Fietkau struct { 682f0efa862SFelix Fietkau u64 packets[__MT_RXQ_MAX]; 683f0efa862SFelix Fietkau u64 fcs_error[__MT_RXQ_MAX]; 684f0efa862SFelix Fietkau } rx_stats; 685f0efa862SFelix Fietkau }; 686f0efa862SFelix Fietkau 68785d96704SLorenzo Bianconi struct mt76_vif { 68885d96704SLorenzo Bianconi u8 idx; 68985d96704SLorenzo Bianconi u8 omac_idx; 69085d96704SLorenzo Bianconi u8 band_idx; 69185d96704SLorenzo Bianconi u8 wmm_idx; 69285d96704SLorenzo Bianconi u8 scan_seq_num; 6935ea3d983SFelix Fietkau u8 cipher; 69485d96704SLorenzo Bianconi }; 69585d96704SLorenzo Bianconi 696ac24dd35SFelix Fietkau struct mt76_phy { 697ac24dd35SFelix Fietkau struct ieee80211_hw *hw; 698ac24dd35SFelix Fietkau struct mt76_dev *dev; 699a3d01038SFelix Fietkau void *priv; 70096747a51SFelix Fietkau 701011849e0SFelix Fietkau unsigned long state; 702dc44c45cSLorenzo Bianconi u8 band_idx; 703011849e0SFelix Fietkau 70491990519SLorenzo Bianconi struct mt76_queue *q_tx[__MT_TXQ_MAX]; 70591990519SLorenzo Bianconi 70696747a51SFelix Fietkau struct cfg80211_chan_def chandef; 70796747a51SFelix Fietkau struct ieee80211_channel *main_chan; 70896747a51SFelix Fietkau 70996747a51SFelix Fietkau struct mt76_channel_state *chan_state; 7103f306448SFelix Fietkau enum mt76_dfs_state dfs_state; 71196747a51SFelix Fietkau ktime_t survey_time; 71296747a51SFelix Fietkau 713d107501aSLorenzo Bianconi u32 aggr_stats[32]; 714d107501aSLorenzo Bianconi 71548dbce5cSLorenzo Bianconi struct mt76_hw_cap cap; 71696747a51SFelix Fietkau struct mt76_sband sband_2g; 71796747a51SFelix Fietkau struct mt76_sband sband_5g; 718cee3fd29SLorenzo Bianconi struct mt76_sband sband_6g; 719beaaeb6bSFelix Fietkau 72098df2baeSLorenzo Bianconi u8 macaddr[ETH_ALEN]; 72198df2baeSLorenzo Bianconi 722beaaeb6bSFelix Fietkau int txpower_cur; 723beaaeb6bSFelix Fietkau u8 antenna_mask; 724b9027e08SLorenzo Bianconi u16 chainmask; 725c918c74dSShayne Chen 726c918c74dSShayne Chen #ifdef CONFIG_NL80211_TESTMODE 727c918c74dSShayne Chen struct mt76_testmode_data test; 728c918c74dSShayne Chen #endif 729a782f8bfSLorenzo Bianconi 730a782f8bfSLorenzo Bianconi struct delayed_work mac_work; 731a782f8bfSLorenzo Bianconi u8 mac_work_count; 732cc4b3c13SLorenzo Bianconi 733cc4b3c13SLorenzo Bianconi struct { 734cc4b3c13SLorenzo Bianconi struct sk_buff *head; 735cc4b3c13SLorenzo Bianconi struct sk_buff **tail; 736cc4b3c13SLorenzo Bianconi u16 seqno; 737cc4b3c13SLorenzo Bianconi } rx_amsdu[__MT_RXQ_MAX]; 738502604f5SYN Chen 739502604f5SYN Chen struct mt76_freq_range_power *frp; 7403abd46ddSLorenzo Bianconi 7413abd46ddSLorenzo Bianconi struct { 7423abd46ddSLorenzo Bianconi struct led_classdev cdev; 7433abd46ddSLorenzo Bianconi char name[32]; 7443abd46ddSLorenzo Bianconi bool al; 7453abd46ddSLorenzo Bianconi u8 pin; 7463abd46ddSLorenzo Bianconi } leds; 747ac24dd35SFelix Fietkau }; 748ac24dd35SFelix Fietkau 74917f1de56SFelix Fietkau struct mt76_dev { 750ac24dd35SFelix Fietkau struct mt76_phy phy; /* must be first */ 751dc44c45cSLorenzo Bianconi struct mt76_phy *phys[__MT_MAX_BAND]; 752bfc394ddSFelix Fietkau 75317f1de56SFelix Fietkau struct ieee80211_hw *hw; 75417f1de56SFelix Fietkau 7552666beceSSujuan Chen spinlock_t wed_lock; 75617f1de56SFelix Fietkau spinlock_t lock; 75717f1de56SFelix Fietkau spinlock_t cc_lock; 758108a4861SStanislaw Gruszka 7595ce09c1aSFelix Fietkau u32 cur_cc_bss_rx; 7605ce09c1aSFelix Fietkau 7615ce09c1aSFelix Fietkau struct mt76_rx_status rx_ampdu_status; 7625ce09c1aSFelix Fietkau u32 rx_ampdu_len; 7635ce09c1aSFelix Fietkau u32 rx_ampdu_ref; 7645ce09c1aSFelix Fietkau 765108a4861SStanislaw Gruszka struct mutex mutex; 766108a4861SStanislaw Gruszka 76717f1de56SFelix Fietkau const struct mt76_bus_ops *bus; 76817f1de56SFelix Fietkau const struct mt76_driver_ops *drv; 769db0f04f3SLorenzo Bianconi const struct mt76_mcu_ops *mcu_ops; 77017f1de56SFelix Fietkau struct device *dev; 771d1ddc536SFelix Fietkau struct device *dma_dev; 77217f1de56SFelix Fietkau 77309872957SLorenzo Bianconi struct mt76_mcu mcu; 77409872957SLorenzo Bianconi 77517f1de56SFelix Fietkau struct net_device napi_dev; 776aa40528aSFelix Fietkau struct net_device tx_napi_dev; 777c3d7c82aSFelix Fietkau spinlock_t rx_lock; 77817f1de56SFelix Fietkau struct napi_struct napi[__MT_RXQ_MAX]; 77917f1de56SFelix Fietkau struct sk_buff_head rx_skb[__MT_RXQ_MAX]; 78017f1de56SFelix Fietkau 78117f1de56SFelix Fietkau struct list_head txwi_cache; 7822666beceSSujuan Chen struct list_head rxwi_cache; 783b1cb42adSLorenzo Bianconi struct mt76_queue *q_mcu[__MT_MCUQ_MAX]; 78417f1de56SFelix Fietkau struct mt76_queue q_rx[__MT_RXQ_MAX]; 78517f1de56SFelix Fietkau const struct mt76_queue_ops *queue_ops; 786c1e0d2beSLorenzo Bianconi int tx_dma_idx[4]; 78717f1de56SFelix Fietkau 788781eef5bSFelix Fietkau struct mt76_worker tx_worker; 7898402650aSLorenzo Bianconi struct napi_struct tx_napi; 790a33b8ab8SFelix Fietkau 791b17aff33SLorenzo Bianconi spinlock_t token_lock; 792b17aff33SLorenzo Bianconi struct idr token; 793f68d6762SFelix Fietkau u16 wed_token_count; 79461b5156bSFelix Fietkau u16 token_count; 79561b5156bSFelix Fietkau u16 token_size; 796b17aff33SLorenzo Bianconi 7972666beceSSujuan Chen spinlock_t rx_token_lock; 7982666beceSSujuan Chen struct idr rx_token; 7992666beceSSujuan Chen u16 rx_token_size; 8002666beceSSujuan Chen 80126e40d4cSFelix Fietkau wait_queue_head_t tx_wait; 802c34f1005SLorenzo Bianconi /* spinclock used to protect wcid pktid linked list */ 803c34f1005SLorenzo Bianconi spinlock_t status_lock; 80426e40d4cSFelix Fietkau 8055e616ad2SFelix Fietkau u32 wcid_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; 8065e616ad2SFelix Fietkau u32 wcid_phy_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; 80736404c06SStanislaw Gruszka 808b619e013SEvelyn Tsai u64 vif_mask; 8092ab33b8dSFelix Fietkau 81036404c06SStanislaw Gruszka struct mt76_wcid global_wcid; 81136404c06SStanislaw Gruszka struct mt76_wcid __rcu *wcid[MT76_N_WCIDS]; 812bd1e3e7bSLorenzo Bianconi struct list_head wcid_list; 81336404c06SStanislaw Gruszka 81417f1de56SFelix Fietkau u32 rev; 81517f1de56SFelix Fietkau 816dc6057f4SLorenzo Bianconi struct tasklet_struct pre_tbtt_tasklet; 8173041c445SLorenzo Bianconi int beacon_int; 818c8a04d98SLorenzo Bianconi u8 beacon_mask; 8193041c445SLorenzo Bianconi 82017f1de56SFelix Fietkau struct debugfs_blob_wrapper eeprom; 82117f1de56SFelix Fietkau struct debugfs_blob_wrapper otp; 82217f1de56SFelix Fietkau 8235b257371SLorenzo Bianconi char alpha2[3]; 824d8b8890dSLorenzo Bianconi enum nl80211_dfs_regions region; 825d8b8890dSLorenzo Bianconi 82617f1de56SFelix Fietkau u32 debugfs_reg; 82717f1de56SFelix Fietkau 828e7173858SFelix Fietkau u8 csa_complete; 829e7173858SFelix Fietkau 830108a4861SStanislaw Gruszka u32 rxfilter; 831108a4861SStanislaw Gruszka 832f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 833f0efa862SFelix Fietkau const struct mt76_testmode_ops *test_ops; 834e7a6a044SShayne Chen struct { 835e7a6a044SShayne Chen const char *name; 836e7a6a044SShayne Chen u32 offset; 837e7a6a044SShayne Chen } test_mtd; 838f0efa862SFelix Fietkau #endif 839a86f1d01SLorenzo Bianconi struct workqueue_struct *wq; 840a86f1d01SLorenzo Bianconi 841f7bbb80fSLorenzo Bianconi union { 842f7bbb80fSLorenzo Bianconi struct mt76_mmio mmio; 843b40b15e1SLorenzo Bianconi struct mt76_usb usb; 844d39b52e3SSean Wang struct mt76_sdio sdio; 84517f1de56SFelix Fietkau }; 846f7bbb80fSLorenzo Bianconi }; 84717f1de56SFelix Fietkau 84822b980baSFelix Fietkau struct mt76_power_limits { 84922b980baSFelix Fietkau s8 cck[4]; 85022b980baSFelix Fietkau s8 ofdm[8]; 85122b980baSFelix Fietkau s8 mcs[4][10]; 852a9627d99SShayne Chen s8 ru[7][12]; 85322b980baSFelix Fietkau }; 85422b980baSFelix Fietkau 85554ae98ffSLorenzo Bianconi struct mt76_ethtool_worker_info { 85654ae98ffSLorenzo Bianconi u64 *data; 85754ae98ffSLorenzo Bianconi int idx; 85854ae98ffSLorenzo Bianconi int initial_stat_idx; 85954ae98ffSLorenzo Bianconi int worker_stat_count; 86054ae98ffSLorenzo Bianconi int sta_count; 86154ae98ffSLorenzo Bianconi }; 86254ae98ffSLorenzo Bianconi 86354b8fdebSLorenzo Bianconi #define CCK_RATE(_idx, _rate) { \ 86454b8fdebSLorenzo Bianconi .bitrate = _rate, \ 86554b8fdebSLorenzo Bianconi .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ 86654b8fdebSLorenzo Bianconi .hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \ 86754b8fdebSLorenzo Bianconi .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + _idx), \ 86854b8fdebSLorenzo Bianconi } 86954b8fdebSLorenzo Bianconi 87054b8fdebSLorenzo Bianconi #define OFDM_RATE(_idx, _rate) { \ 87154b8fdebSLorenzo Bianconi .bitrate = _rate, \ 87254b8fdebSLorenzo Bianconi .hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 87354b8fdebSLorenzo Bianconi .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 87454b8fdebSLorenzo Bianconi } 87554b8fdebSLorenzo Bianconi 87654b8fdebSLorenzo Bianconi extern struct ieee80211_rate mt76_rates[12]; 87754b8fdebSLorenzo Bianconi 878d4131273SStanislaw Gruszka #define __mt76_rr(dev, ...) (dev)->bus->rr((dev), __VA_ARGS__) 879d4131273SStanislaw Gruszka #define __mt76_wr(dev, ...) (dev)->bus->wr((dev), __VA_ARGS__) 880d4131273SStanislaw Gruszka #define __mt76_rmw(dev, ...) (dev)->bus->rmw((dev), __VA_ARGS__) 88135e4ebeaSLorenzo Bianconi #define __mt76_wr_copy(dev, ...) (dev)->bus->write_copy((dev), __VA_ARGS__) 88235e4ebeaSLorenzo Bianconi #define __mt76_rr_copy(dev, ...) (dev)->bus->read_copy((dev), __VA_ARGS__) 883d4131273SStanislaw Gruszka 88422c575c4SStanislaw Gruszka #define __mt76_set(dev, offset, val) __mt76_rmw(dev, offset, 0, val) 88522c575c4SStanislaw Gruszka #define __mt76_clear(dev, offset, val) __mt76_rmw(dev, offset, val, 0) 88622c575c4SStanislaw Gruszka 88717f1de56SFelix Fietkau #define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__) 88817f1de56SFelix Fietkau #define mt76_wr(dev, ...) (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__) 88917f1de56SFelix Fietkau #define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__) 89035e4ebeaSLorenzo Bianconi #define mt76_wr_copy(dev, ...) (dev)->mt76.bus->write_copy(&((dev)->mt76), __VA_ARGS__) 89135e4ebeaSLorenzo Bianconi #define mt76_rr_copy(dev, ...) (dev)->mt76.bus->read_copy(&((dev)->mt76), __VA_ARGS__) 8926da5a291SStanislaw Gruszka #define mt76_wr_rp(dev, ...) (dev)->mt76.bus->wr_rp(&((dev)->mt76), __VA_ARGS__) 8936da5a291SStanislaw Gruszka #define mt76_rd_rp(dev, ...) (dev)->mt76.bus->rd_rp(&((dev)->mt76), __VA_ARGS__) 89417f1de56SFelix Fietkau 895f4d45fe2SLorenzo Bianconi 896e2c2fd0fSLorenzo Bianconi #define mt76_mcu_restart(dev, ...) (dev)->mt76.mcu_ops->mcu_restart(&((dev)->mt76)) 897db0f04f3SLorenzo Bianconi 89817f1de56SFelix Fietkau #define mt76_set(dev, offset, val) mt76_rmw(dev, offset, 0, val) 89917f1de56SFelix Fietkau #define mt76_clear(dev, offset, val) mt76_rmw(dev, offset, val, 0) 90017f1de56SFelix Fietkau 90117f1de56SFelix Fietkau #define mt76_get_field(_dev, _reg, _field) \ 90217f1de56SFelix Fietkau FIELD_GET(_field, mt76_rr(dev, _reg)) 90317f1de56SFelix Fietkau 90417f1de56SFelix Fietkau #define mt76_rmw_field(_dev, _reg, _field, _val) \ 90517f1de56SFelix Fietkau mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) 90617f1de56SFelix Fietkau 90746436b5eSStanislaw Gruszka #define __mt76_rmw_field(_dev, _reg, _field, _val) \ 90846436b5eSStanislaw Gruszka __mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) 90946436b5eSStanislaw Gruszka 910ac24dd35SFelix Fietkau #define mt76_hw(dev) (dev)->mphy.hw 91117f1de56SFelix Fietkau 91217f1de56SFelix Fietkau bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, 91317f1de56SFelix Fietkau int timeout); 91417f1de56SFelix Fietkau 91517f1de56SFelix Fietkau #define mt76_poll(dev, ...) __mt76_poll(&((dev)->mt76), __VA_ARGS__) 91617f1de56SFelix Fietkau 91735effe6cSDeren Wu bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, 91835effe6cSDeren Wu int timeout, int kick); 91935effe6cSDeren Wu #define __mt76_poll_msec(...) ____mt76_poll_msec(__VA_ARGS__, 10) 92035effe6cSDeren Wu #define mt76_poll_msec(dev, ...) ____mt76_poll_msec(&((dev)->mt76), __VA_ARGS__, 10) 92135effe6cSDeren Wu #define mt76_poll_msec_tick(dev, ...) ____mt76_poll_msec(&((dev)->mt76), __VA_ARGS__) 92217f1de56SFelix Fietkau 92317f1de56SFelix Fietkau void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs); 924f37f0550SLorenzo Bianconi void mt76_pci_disable_aspm(struct pci_dev *pdev); 92517f1de56SFelix Fietkau 92617f1de56SFelix Fietkau static inline u16 mt76_chip(struct mt76_dev *dev) 92717f1de56SFelix Fietkau { 92817f1de56SFelix Fietkau return dev->rev >> 16; 92917f1de56SFelix Fietkau } 93017f1de56SFelix Fietkau 93117f1de56SFelix Fietkau static inline u16 mt76_rev(struct mt76_dev *dev) 93217f1de56SFelix Fietkau { 93317f1de56SFelix Fietkau return dev->rev & 0xffff; 93417f1de56SFelix Fietkau } 93517f1de56SFelix Fietkau 93617f1de56SFelix Fietkau #define mt76xx_chip(dev) mt76_chip(&((dev)->mt76)) 93717f1de56SFelix Fietkau #define mt76xx_rev(dev) mt76_rev(&((dev)->mt76)) 93817f1de56SFelix Fietkau 939cb8ed33dSLorenzo Bianconi #define mt76_init_queues(dev, ...) (dev)->mt76.queue_ops->init(&((dev)->mt76), __VA_ARGS__) 940a23fde09SLorenzo Bianconi #define mt76_queue_alloc(dev, ...) (dev)->mt76.queue_ops->alloc(&((dev)->mt76), __VA_ARGS__) 9415ed31128SLorenzo Bianconi #define mt76_tx_queue_skb_raw(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb_raw(&((dev)->mt76), __VA_ARGS__) 942eb9ca7ecSLorenzo Bianconi #define mt76_tx_queue_skb(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb(&((dev)->mt76), __VA_ARGS__) 94317f1de56SFelix Fietkau #define mt76_queue_rx_reset(dev, ...) (dev)->mt76.queue_ops->rx_reset(&((dev)->mt76), __VA_ARGS__) 94417f1de56SFelix Fietkau #define mt76_queue_tx_cleanup(dev, ...) (dev)->mt76.queue_ops->tx_cleanup(&((dev)->mt76), __VA_ARGS__) 945c001df97SLorenzo Bianconi #define mt76_queue_rx_cleanup(dev, ...) (dev)->mt76.queue_ops->rx_cleanup(&((dev)->mt76), __VA_ARGS__) 94617f1de56SFelix Fietkau #define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__) 9473990465dSLorenzo Bianconi #define mt76_queue_reset(dev, ...) (dev)->mt76.queue_ops->reset_q(&((dev)->mt76), __VA_ARGS__) 94817f1de56SFelix Fietkau 949f473b42aSFelix Fietkau #define mt76_for_each_q_rx(dev, i) \ 950b3ad9d6aSBo Jiao for (i = 0; i < ARRAY_SIZE((dev)->q_rx); i++) \ 951b3ad9d6aSBo Jiao if ((dev)->q_rx[i].ndesc) 952f473b42aSFelix Fietkau 953c0f7b25aSLorenzo Bianconi struct mt76_dev *mt76_alloc_device(struct device *pdev, unsigned int size, 954c0f7b25aSLorenzo Bianconi const struct ieee80211_ops *ops, 955c0f7b25aSLorenzo Bianconi const struct mt76_driver_ops *drv_ops); 95617f1de56SFelix Fietkau int mt76_register_device(struct mt76_dev *dev, bool vht, 95717f1de56SFelix Fietkau struct ieee80211_rate *rates, int n_rates); 95817f1de56SFelix Fietkau void mt76_unregister_device(struct mt76_dev *dev); 959def34a2fSLorenzo Bianconi void mt76_free_device(struct mt76_dev *dev); 960c89d3625SFelix Fietkau void mt76_unregister_phy(struct mt76_phy *phy); 961c89d3625SFelix Fietkau 962c89d3625SFelix Fietkau struct mt76_phy *mt76_alloc_phy(struct mt76_dev *dev, unsigned int size, 963dc44c45cSLorenzo Bianconi const struct ieee80211_ops *ops, 964dc44c45cSLorenzo Bianconi u8 band_idx); 965db78a791SLorenzo Bianconi int mt76_register_phy(struct mt76_phy *phy, bool vht, 966db78a791SLorenzo Bianconi struct ieee80211_rate *rates, int n_rates); 96717f1de56SFelix Fietkau 9683263039dSLorenzo Bianconi struct dentry *mt76_register_debugfs_fops(struct mt76_phy *phy, 969f6e1f598SLorenzo Bianconi const struct file_operations *ops); 970f6e1f598SLorenzo Bianconi static inline struct dentry *mt76_register_debugfs(struct mt76_dev *dev) 971f6e1f598SLorenzo Bianconi { 9723263039dSLorenzo Bianconi return mt76_register_debugfs_fops(&dev->phy, NULL); 973f6e1f598SLorenzo Bianconi } 974f6e1f598SLorenzo Bianconi 9750b82a8e8SLorenzo Bianconi int mt76_queues_read(struct seq_file *s, void *data); 9768f410a8bSLorenzo Bianconi void mt76_seq_puts_array(struct seq_file *file, const char *str, 9778f410a8bSLorenzo Bianconi s8 *val, int len); 97817f1de56SFelix Fietkau 97917f1de56SFelix Fietkau int mt76_eeprom_init(struct mt76_dev *dev, int len); 98098df2baeSLorenzo Bianconi void mt76_eeprom_override(struct mt76_phy *phy); 981495184acSRyder Lee int mt76_get_of_eeprom(struct mt76_dev *dev, void *data, int offset, int len); 98217f1de56SFelix Fietkau 983b1cb42adSLorenzo Bianconi struct mt76_queue * 984b1cb42adSLorenzo Bianconi mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc, 985f68d6762SFelix Fietkau int ring_base, u32 flags); 98633920b2bSRyder Lee u16 mt76_calculate_default_rate(struct mt76_phy *phy, int rateidx); 987b1cb42adSLorenzo Bianconi static inline int mt76_init_tx_queue(struct mt76_phy *phy, int qid, int idx, 988f68d6762SFelix Fietkau int n_desc, int ring_base, u32 flags) 989b1cb42adSLorenzo Bianconi { 990b1cb42adSLorenzo Bianconi struct mt76_queue *q; 991b1cb42adSLorenzo Bianconi 992f68d6762SFelix Fietkau q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base, flags); 993b1cb42adSLorenzo Bianconi if (IS_ERR(q)) 994b1cb42adSLorenzo Bianconi return PTR_ERR(q); 995b1cb42adSLorenzo Bianconi 99691990519SLorenzo Bianconi phy->q_tx[qid] = q; 997b1cb42adSLorenzo Bianconi 998b1cb42adSLorenzo Bianconi return 0; 999b1cb42adSLorenzo Bianconi } 1000b1cb42adSLorenzo Bianconi 1001b1cb42adSLorenzo Bianconi static inline int mt76_init_mcu_queue(struct mt76_dev *dev, int qid, int idx, 1002b1cb42adSLorenzo Bianconi int n_desc, int ring_base) 1003b1cb42adSLorenzo Bianconi { 1004b1cb42adSLorenzo Bianconi struct mt76_queue *q; 1005b1cb42adSLorenzo Bianconi 1006f68d6762SFelix Fietkau q = mt76_init_queue(dev, qid, idx, n_desc, ring_base, 0); 1007b1cb42adSLorenzo Bianconi if (IS_ERR(q)) 1008b1cb42adSLorenzo Bianconi return PTR_ERR(q); 1009b1cb42adSLorenzo Bianconi 1010b1cb42adSLorenzo Bianconi dev->q_mcu[qid] = q; 1011b1cb42adSLorenzo Bianconi 1012b1cb42adSLorenzo Bianconi return 0; 1013b1cb42adSLorenzo Bianconi } 1014b671da33SLorenzo Bianconi 1015011849e0SFelix Fietkau static inline struct mt76_phy * 1016128c9b7dSLorenzo Bianconi mt76_dev_phy(struct mt76_dev *dev, u8 phy_idx) 1017011849e0SFelix Fietkau { 1018dc44c45cSLorenzo Bianconi if ((phy_idx == MT_BAND1 && dev->phys[phy_idx]) || 1019dc44c45cSLorenzo Bianconi (phy_idx == MT_BAND2 && dev->phys[phy_idx])) 1020dc44c45cSLorenzo Bianconi return dev->phys[phy_idx]; 1021128c9b7dSLorenzo Bianconi 1022011849e0SFelix Fietkau return &dev->phy; 1023011849e0SFelix Fietkau } 1024011849e0SFelix Fietkau 1025bfc394ddSFelix Fietkau static inline struct ieee80211_hw * 1026128c9b7dSLorenzo Bianconi mt76_phy_hw(struct mt76_dev *dev, u8 phy_idx) 1027bfc394ddSFelix Fietkau { 1028128c9b7dSLorenzo Bianconi return mt76_dev_phy(dev, phy_idx)->hw; 1029bfc394ddSFelix Fietkau } 1030bfc394ddSFelix Fietkau 1031f3950a41SLorenzo Bianconi static inline u8 * 1032f3950a41SLorenzo Bianconi mt76_get_txwi_ptr(struct mt76_dev *dev, struct mt76_txwi_cache *t) 1033f3950a41SLorenzo Bianconi { 1034f3950a41SLorenzo Bianconi return (u8 *)t - dev->drv->txwi_size; 1035f3950a41SLorenzo Bianconi } 1036f3950a41SLorenzo Bianconi 1037ee8aa945SLorenzo Bianconi /* increment with wrap-around */ 1038ee8aa945SLorenzo Bianconi static inline int mt76_incr(int val, int size) 1039ee8aa945SLorenzo Bianconi { 1040ee8aa945SLorenzo Bianconi return (val + 1) & (size - 1); 1041ee8aa945SLorenzo Bianconi } 1042ee8aa945SLorenzo Bianconi 1043ee8aa945SLorenzo Bianconi /* decrement with wrap-around */ 1044ee8aa945SLorenzo Bianconi static inline int mt76_decr(int val, int size) 1045ee8aa945SLorenzo Bianconi { 1046ee8aa945SLorenzo Bianconi return (val - 1) & (size - 1); 1047ee8aa945SLorenzo Bianconi } 1048ee8aa945SLorenzo Bianconi 10491d0496c6SStanislaw Gruszka u8 mt76_ac_to_hwq(u8 ac); 1050b40b15e1SLorenzo Bianconi 105117f1de56SFelix Fietkau static inline struct ieee80211_txq * 105217f1de56SFelix Fietkau mtxq_to_txq(struct mt76_txq *mtxq) 105317f1de56SFelix Fietkau { 105417f1de56SFelix Fietkau void *ptr = mtxq; 105517f1de56SFelix Fietkau 105617f1de56SFelix Fietkau return container_of(ptr, struct ieee80211_txq, drv_priv); 105717f1de56SFelix Fietkau } 105817f1de56SFelix Fietkau 10599c68a57bSFelix Fietkau static inline struct ieee80211_sta * 10609c68a57bSFelix Fietkau wcid_to_sta(struct mt76_wcid *wcid) 10619c68a57bSFelix Fietkau { 10629c68a57bSFelix Fietkau void *ptr = wcid; 10639c68a57bSFelix Fietkau 10649c68a57bSFelix Fietkau if (!wcid || !wcid->sta) 10659c68a57bSFelix Fietkau return NULL; 10669c68a57bSFelix Fietkau 10679c68a57bSFelix Fietkau return container_of(ptr, struct ieee80211_sta, drv_priv); 10689c68a57bSFelix Fietkau } 10699c68a57bSFelix Fietkau 107088046b2cSFelix Fietkau static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb) 107188046b2cSFelix Fietkau { 107288046b2cSFelix Fietkau BUILD_BUG_ON(sizeof(struct mt76_tx_cb) > 107388046b2cSFelix Fietkau sizeof(IEEE80211_SKB_CB(skb)->status.status_driver_data)); 107488046b2cSFelix Fietkau return ((void *)IEEE80211_SKB_CB(skb)->status.status_driver_data); 107588046b2cSFelix Fietkau } 107688046b2cSFelix Fietkau 107777ae1d5eSRyder Lee static inline void *mt76_skb_get_hdr(struct sk_buff *skb) 107877ae1d5eSRyder Lee { 107977ae1d5eSRyder Lee struct mt76_rx_status mstat; 108077ae1d5eSRyder Lee u8 *data = skb->data; 108177ae1d5eSRyder Lee 108277ae1d5eSRyder Lee /* Alignment concerns */ 108377ae1d5eSRyder Lee BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he) % 4); 108477ae1d5eSRyder Lee BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he_mu) % 4); 108577ae1d5eSRyder Lee 108677ae1d5eSRyder Lee mstat = *((struct mt76_rx_status *)skb->cb); 108777ae1d5eSRyder Lee 108877ae1d5eSRyder Lee if (mstat.flag & RX_FLAG_RADIOTAP_HE) 108977ae1d5eSRyder Lee data += sizeof(struct ieee80211_radiotap_he); 109077ae1d5eSRyder Lee if (mstat.flag & RX_FLAG_RADIOTAP_HE_MU) 109177ae1d5eSRyder Lee data += sizeof(struct ieee80211_radiotap_he_mu); 109277ae1d5eSRyder Lee 109377ae1d5eSRyder Lee return data; 109477ae1d5eSRyder Lee } 109577ae1d5eSRyder Lee 10963bb45b5fSLorenzo Bianconi static inline void mt76_insert_hdr_pad(struct sk_buff *skb) 10973bb45b5fSLorenzo Bianconi { 10983bb45b5fSLorenzo Bianconi int len = ieee80211_get_hdrlen_from_skb(skb); 10993bb45b5fSLorenzo Bianconi 11003bb45b5fSLorenzo Bianconi if (len % 4 == 0) 11013bb45b5fSLorenzo Bianconi return; 11023bb45b5fSLorenzo Bianconi 11033bb45b5fSLorenzo Bianconi skb_push(skb, 2); 11043bb45b5fSLorenzo Bianconi memmove(skb->data, skb->data + 2, len); 11053bb45b5fSLorenzo Bianconi 11063bb45b5fSLorenzo Bianconi skb->data[len] = 0; 11073bb45b5fSLorenzo Bianconi skb->data[len + 1] = 0; 11083bb45b5fSLorenzo Bianconi } 11093bb45b5fSLorenzo Bianconi 11108548c6ebSFelix Fietkau static inline bool mt76_is_skb_pktid(u8 pktid) 11118548c6ebSFelix Fietkau { 11128548c6ebSFelix Fietkau if (pktid & MT_PACKET_ID_HAS_RATE) 11138548c6ebSFelix Fietkau return false; 11148548c6ebSFelix Fietkau 11158548c6ebSFelix Fietkau return pktid >= MT_PACKET_ID_FIRST; 11168548c6ebSFelix Fietkau } 11178548c6ebSFelix Fietkau 111807cda406SFelix Fietkau static inline u8 mt76_tx_power_nss_delta(u8 nss) 111907cda406SFelix Fietkau { 112007cda406SFelix Fietkau static const u8 nss_delta[4] = { 0, 6, 9, 12 }; 112103dd0d49SDeren Wu u8 idx = nss - 1; 112207cda406SFelix Fietkau 112303dd0d49SDeren Wu return (idx < ARRAY_SIZE(nss_delta)) ? nss_delta[idx] : 0; 112407cda406SFelix Fietkau } 112507cda406SFelix Fietkau 1126c918c74dSShayne Chen static inline bool mt76_testmode_enabled(struct mt76_phy *phy) 1127f0efa862SFelix Fietkau { 1128f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 1129c918c74dSShayne Chen return phy->test.state != MT76_TM_STATE_OFF; 1130c918c74dSShayne Chen #else 1131c918c74dSShayne Chen return false; 1132c918c74dSShayne Chen #endif 1133c918c74dSShayne Chen } 1134c918c74dSShayne Chen 1135c918c74dSShayne Chen static inline bool mt76_is_testmode_skb(struct mt76_dev *dev, 1136c918c74dSShayne Chen struct sk_buff *skb, 1137c918c74dSShayne Chen struct ieee80211_hw **hw) 1138c918c74dSShayne Chen { 1139c918c74dSShayne Chen #ifdef CONFIG_NL80211_TESTMODE 1140dc44c45cSLorenzo Bianconi int i; 1141dc44c45cSLorenzo Bianconi 1142dc44c45cSLorenzo Bianconi for (i = 0; i < ARRAY_SIZE(dev->phys); i++) { 1143dc44c45cSLorenzo Bianconi struct mt76_phy *phy = dev->phys[i]; 1144dc44c45cSLorenzo Bianconi 1145dc44c45cSLorenzo Bianconi if (phy && skb == phy->test.tx_skb) { 1146dc44c45cSLorenzo Bianconi *hw = dev->phys[i]->hw; 1147c918c74dSShayne Chen return true; 1148dc44c45cSLorenzo Bianconi } 1149dc44c45cSLorenzo Bianconi } 1150dc44c45cSLorenzo Bianconi return false; 1151f0efa862SFelix Fietkau #else 1152f0efa862SFelix Fietkau return false; 1153f0efa862SFelix Fietkau #endif 1154f0efa862SFelix Fietkau } 1155f0efa862SFelix Fietkau 115617f1de56SFelix Fietkau void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb); 11579fba6d07SFelix Fietkau void mt76_tx(struct mt76_phy *dev, struct ieee80211_sta *sta, 115817f1de56SFelix Fietkau struct mt76_wcid *wcid, struct sk_buff *skb); 115917f1de56SFelix Fietkau void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq); 116091990519SLorenzo Bianconi void mt76_stop_tx_queues(struct mt76_phy *phy, struct ieee80211_sta *sta, 116117f1de56SFelix Fietkau bool send_bar); 1162c50d105aSFelix Fietkau void mt76_tx_check_agg_ssn(struct ieee80211_sta *sta, struct sk_buff *skb); 11639fba6d07SFelix Fietkau void mt76_txq_schedule(struct mt76_phy *phy, enum mt76_txq_id qid); 11649fba6d07SFelix Fietkau void mt76_txq_schedule_all(struct mt76_phy *phy); 1165335e97acSLorenzo Bianconi void mt76_tx_worker_run(struct mt76_dev *dev); 1166781eef5bSFelix Fietkau void mt76_tx_worker(struct mt76_worker *w); 116717f1de56SFelix Fietkau void mt76_release_buffered_frames(struct ieee80211_hw *hw, 116817f1de56SFelix Fietkau struct ieee80211_sta *sta, 116917f1de56SFelix Fietkau u16 tids, int nframes, 117017f1de56SFelix Fietkau enum ieee80211_frame_release_type reason, 117117f1de56SFelix Fietkau bool more_data); 11725a95ca41SFelix Fietkau bool mt76_has_tx_pending(struct mt76_phy *phy); 117396747a51SFelix Fietkau void mt76_set_channel(struct mt76_phy *phy); 1174c560b137SRyder Lee void mt76_update_survey(struct mt76_phy *phy); 117504414240SLorenzo Bianconi void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time); 117617f1de56SFelix Fietkau int mt76_get_survey(struct ieee80211_hw *hw, int idx, 117717f1de56SFelix Fietkau struct survey_info *survey); 1178a71b648eSRyder Lee int mt76_rx_signal(u8 chain_mask, s8 *chain_signal); 1179bb3e3fecSRyder Lee void mt76_set_stream_caps(struct mt76_phy *phy, bool vht); 118017f1de56SFelix Fietkau 1181aee5b8cfSFelix Fietkau int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid, 11827c4f744dSRyder Lee u16 ssn, u16 size); 1183aee5b8cfSFelix Fietkau void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid); 1184aee5b8cfSFelix Fietkau 118530ce7f44SFelix Fietkau void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, 118630ce7f44SFelix Fietkau struct ieee80211_key_conf *key); 118779d1c94cSFelix Fietkau 118879d1c94cSFelix Fietkau void mt76_tx_status_lock(struct mt76_dev *dev, struct sk_buff_head *list) 1189c34f1005SLorenzo Bianconi __acquires(&dev->status_lock); 119079d1c94cSFelix Fietkau void mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list) 1191c34f1005SLorenzo Bianconi __releases(&dev->status_lock); 119279d1c94cSFelix Fietkau 119388046b2cSFelix Fietkau int mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, 119488046b2cSFelix Fietkau struct sk_buff *skb); 119588046b2cSFelix Fietkau struct sk_buff *mt76_tx_status_skb_get(struct mt76_dev *dev, 119679d1c94cSFelix Fietkau struct mt76_wcid *wcid, int pktid, 119779d1c94cSFelix Fietkau struct sk_buff_head *list); 119879d1c94cSFelix Fietkau void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb, 119979d1c94cSFelix Fietkau struct sk_buff_head *list); 12000fe88644SFelix Fietkau void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb, 12010fe88644SFelix Fietkau struct list_head *free_list); 12020fe88644SFelix Fietkau static inline void 12030fe88644SFelix Fietkau mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb) 12040fe88644SFelix Fietkau { 12050fe88644SFelix Fietkau __mt76_tx_complete_skb(dev, wcid, skb, NULL); 12060fe88644SFelix Fietkau } 12070fe88644SFelix Fietkau 1208c02f86eeSLorenzo Bianconi void mt76_tx_status_check(struct mt76_dev *dev, bool flush); 1209e28487eaSFelix Fietkau int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1210e28487eaSFelix Fietkau struct ieee80211_sta *sta, 1211e28487eaSFelix Fietkau enum ieee80211_sta_state old_state, 1212e28487eaSFelix Fietkau enum ieee80211_sta_state new_state); 121313f61dfcSLorenzo Bianconi void __mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif, 121413f61dfcSLorenzo Bianconi struct ieee80211_sta *sta); 121543ba1922SFelix Fietkau void mt76_sta_pre_rcu_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 121643ba1922SFelix Fietkau struct ieee80211_sta *sta); 121730ce7f44SFelix Fietkau 12188af63fedSFelix Fietkau int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy); 1219ef13edc0SFelix Fietkau 12209313faacSFelix Fietkau int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 12219313faacSFelix Fietkau int *dbm); 1222b3cb885eSLorenzo Bianconi int mt76_init_sar_power(struct ieee80211_hw *hw, 1223b3cb885eSLorenzo Bianconi const struct cfg80211_sar_specs *sar); 1224b3cb885eSLorenzo Bianconi int mt76_get_sar_power(struct mt76_phy *phy, 1225b3cb885eSLorenzo Bianconi struct ieee80211_channel *chan, 1226b3cb885eSLorenzo Bianconi int power); 12279313faacSFelix Fietkau 1228e7173858SFelix Fietkau void mt76_csa_check(struct mt76_dev *dev); 1229e7173858SFelix Fietkau void mt76_csa_finish(struct mt76_dev *dev); 1230e7173858SFelix Fietkau 1231e49c76d4SLorenzo Bianconi int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 123287d53103SStanislaw Gruszka int mt76_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set); 1233eadfd98fSLorenzo Bianconi void mt76_insert_ccmp_hdr(struct sk_buff *skb, u8 key_id); 1234d2679d65SLorenzo Bianconi int mt76_get_rate(struct mt76_dev *dev, 1235d2679d65SLorenzo Bianconi struct ieee80211_supported_band *sband, 1236d2679d65SLorenzo Bianconi int idx, bool cck); 12378b8ab5c2SLorenzo Bianconi void mt76_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 12388b8ab5c2SLorenzo Bianconi const u8 *mac); 12398b8ab5c2SLorenzo Bianconi void mt76_sw_scan_complete(struct ieee80211_hw *hw, 12408b8ab5c2SLorenzo Bianconi struct ieee80211_vif *vif); 12413f306448SFelix Fietkau enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy); 1242f0efa862SFelix Fietkau int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1243f0efa862SFelix Fietkau void *data, int len); 1244f0efa862SFelix Fietkau int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, 1245f0efa862SFelix Fietkau struct netlink_callback *cb, void *data, int len); 1246c918c74dSShayne Chen int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state); 12472601dda8SShayne Chen int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len); 1248f0efa862SFelix Fietkau 1249c918c74dSShayne Chen static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable) 1250f0efa862SFelix Fietkau { 1251f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 1252f0efa862SFelix Fietkau enum mt76_testmode_state state = MT76_TM_STATE_IDLE; 1253f0efa862SFelix Fietkau 1254c918c74dSShayne Chen if (disable || phy->test.state == MT76_TM_STATE_OFF) 1255f0efa862SFelix Fietkau state = MT76_TM_STATE_OFF; 1256f0efa862SFelix Fietkau 1257c918c74dSShayne Chen mt76_testmode_set_state(phy, state); 1258f0efa862SFelix Fietkau #endif 1259f0efa862SFelix Fietkau } 1260f0efa862SFelix Fietkau 126187d53103SStanislaw Gruszka 126217f1de56SFelix Fietkau /* internal */ 1263e394b575SFelix Fietkau static inline struct ieee80211_hw * 1264e394b575SFelix Fietkau mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb) 1265e394b575SFelix Fietkau { 1266e394b575SFelix Fietkau struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1267a062f001SLorenzo Bianconi u8 phy_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2; 1268a062f001SLorenzo Bianconi struct ieee80211_hw *hw = mt76_phy_hw(dev, phy_idx); 1269e394b575SFelix Fietkau 1270a062f001SLorenzo Bianconi info->hw_queue &= ~MT_TX_HW_QUEUE_PHY; 1271e394b575SFelix Fietkau 1272e394b575SFelix Fietkau return hw; 1273e394b575SFelix Fietkau } 1274e394b575SFelix Fietkau 127517f1de56SFelix Fietkau void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); 12762666beceSSujuan Chen void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); 12772666beceSSujuan Chen struct mt76_txwi_cache *mt76_get_rxwi(struct mt76_dev *dev); 1278a97a467aSSujuan Chen void mt76_free_pending_rxwi(struct mt76_dev *dev); 12799d9d738bSFelix Fietkau void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, 128081e850efSLorenzo Bianconi struct napi_struct *napi); 128181e850efSLorenzo Bianconi void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q, 128281e850efSLorenzo Bianconi struct napi_struct *napi); 1283aee5b8cfSFelix Fietkau void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames); 1284c918c74dSShayne Chen void mt76_testmode_tx_pending(struct mt76_phy *phy); 1285fe5b5ab5SFelix Fietkau void mt76_queue_tx_complete(struct mt76_dev *dev, struct mt76_queue *q, 1286fe5b5ab5SFelix Fietkau struct mt76_queue_entry *e); 128717f1de56SFelix Fietkau 1288b40b15e1SLorenzo Bianconi /* usb */ 1289b40b15e1SLorenzo Bianconi static inline bool mt76u_urb_error(struct urb *urb) 1290b40b15e1SLorenzo Bianconi { 1291b40b15e1SLorenzo Bianconi return urb->status && 1292b40b15e1SLorenzo Bianconi urb->status != -ECONNRESET && 1293b40b15e1SLorenzo Bianconi urb->status != -ESHUTDOWN && 1294b40b15e1SLorenzo Bianconi urb->status != -ENOENT; 1295b40b15e1SLorenzo Bianconi } 1296b40b15e1SLorenzo Bianconi 1297b40b15e1SLorenzo Bianconi /* Map hardware queues to usb endpoints */ 1298b40b15e1SLorenzo Bianconi static inline u8 q2ep(u8 qid) 1299b40b15e1SLorenzo Bianconi { 1300b40b15e1SLorenzo Bianconi /* TODO: take management packets to queue 5 */ 1301b40b15e1SLorenzo Bianconi return qid + 1; 1302b40b15e1SLorenzo Bianconi } 1303b40b15e1SLorenzo Bianconi 13045de4db8fSStanislaw Gruszka static inline int 1305b63aa031SStanislaw Gruszka mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len, 13063bcd979cSLorenzo Bianconi int timeout, int ep) 13075de4db8fSStanislaw Gruszka { 130880df01f4SLorenzo Bianconi struct usb_interface *uintf = to_usb_interface(dev->dev); 130980df01f4SLorenzo Bianconi struct usb_device *udev = interface_to_usbdev(uintf); 13105de4db8fSStanislaw Gruszka struct mt76_usb *usb = &dev->usb; 13115de4db8fSStanislaw Gruszka unsigned int pipe; 13125de4db8fSStanislaw Gruszka 1313b63aa031SStanislaw Gruszka if (actual_len) 13143bcd979cSLorenzo Bianconi pipe = usb_rcvbulkpipe(udev, usb->in_ep[ep]); 1315b63aa031SStanislaw Gruszka else 13163bcd979cSLorenzo Bianconi pipe = usb_sndbulkpipe(udev, usb->out_ep[ep]); 1317b63aa031SStanislaw Gruszka 1318b63aa031SStanislaw Gruszka return usb_bulk_msg(udev, pipe, data, len, actual_len, timeout); 13195de4db8fSStanislaw Gruszka } 13205de4db8fSStanislaw Gruszka 1321192ad406SLorenzo Bianconi void mt76_ethtool_page_pool_stats(struct mt76_dev *dev, u64 *data, int *index); 132254ae98ffSLorenzo Bianconi void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi, 1323731425f3SShayne Chen struct mt76_sta_stats *stats, bool eht); 1324e98e6df6SLorenzo Bianconi int mt76_skb_adjust_pad(struct sk_buff *skb, int pad); 13256cb596baSLorenzo Bianconi int __mt76u_vendor_request(struct mt76_dev *dev, u8 req, u8 req_type, 13266cb596baSLorenzo Bianconi u16 val, u16 offset, void *buf, size_t len); 1327b40b15e1SLorenzo Bianconi int mt76u_vendor_request(struct mt76_dev *dev, u8 req, 1328b40b15e1SLorenzo Bianconi u8 req_type, u16 val, u16 offset, 1329b40b15e1SLorenzo Bianconi void *buf, size_t len); 1330b40b15e1SLorenzo Bianconi void mt76u_single_wr(struct mt76_dev *dev, const u8 req, 1331b40b15e1SLorenzo Bianconi const u16 offset, const u32 val); 13326cb596baSLorenzo Bianconi void mt76u_read_copy(struct mt76_dev *dev, u32 offset, 13336cb596baSLorenzo Bianconi void *data, int len); 13346cb596baSLorenzo Bianconi u32 ___mt76u_rr(struct mt76_dev *dev, u8 req, u8 req_type, u32 addr); 13356cb596baSLorenzo Bianconi void ___mt76u_wr(struct mt76_dev *dev, u8 req, u8 req_type, 13366cb596baSLorenzo Bianconi u32 addr, u32 val); 13376cb596baSLorenzo Bianconi int __mt76u_init(struct mt76_dev *dev, struct usb_interface *intf, 13386cb596baSLorenzo Bianconi struct mt76_bus_ops *ops); 13396cb596baSLorenzo Bianconi int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf); 134094e1cfa8SLorenzo Bianconi int mt76u_alloc_mcu_queue(struct mt76_dev *dev); 1341b40b15e1SLorenzo Bianconi int mt76u_alloc_queues(struct mt76_dev *dev); 134239d501d9SStanislaw Gruszka void mt76u_stop_tx(struct mt76_dev *dev); 134339d501d9SStanislaw Gruszka void mt76u_stop_rx(struct mt76_dev *dev); 134439d501d9SStanislaw Gruszka int mt76u_resume_rx(struct mt76_dev *dev); 1345b40b15e1SLorenzo Bianconi void mt76u_queues_deinit(struct mt76_dev *dev); 1346b40b15e1SLorenzo Bianconi 1347d39b52e3SSean Wang int mt76s_init(struct mt76_dev *dev, struct sdio_func *func, 1348d39b52e3SSean Wang const struct mt76_bus_ops *bus_ops); 1349d512b008SLorenzo Bianconi int mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid); 1350d512b008SLorenzo Bianconi int mt76s_alloc_tx(struct mt76_dev *dev); 1351d39b52e3SSean Wang void mt76s_deinit(struct mt76_dev *dev); 1352764dee47SLorenzo Bianconi void mt76s_sdio_irq(struct sdio_func *func); 1353764dee47SLorenzo Bianconi void mt76s_txrx_worker(struct mt76_sdio *sdio); 1354ca74b9b9SSean Wang bool mt76s_txqs_empty(struct mt76_dev *dev); 1355dacf0acfSSean Wang int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, 1356dacf0acfSSean Wang int hw_ver); 1357764dee47SLorenzo Bianconi u32 mt76s_rr(struct mt76_dev *dev, u32 offset); 1358764dee47SLorenzo Bianconi void mt76s_wr(struct mt76_dev *dev, u32 offset, u32 val); 1359764dee47SLorenzo Bianconi u32 mt76s_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val); 1360764dee47SLorenzo Bianconi u32 mt76s_read_pcr(struct mt76_dev *dev); 1361764dee47SLorenzo Bianconi void mt76s_write_copy(struct mt76_dev *dev, u32 offset, 1362764dee47SLorenzo Bianconi const void *data, int len); 1363764dee47SLorenzo Bianconi void mt76s_read_copy(struct mt76_dev *dev, u32 offset, 1364764dee47SLorenzo Bianconi void *data, int len); 1365764dee47SLorenzo Bianconi int mt76s_wr_rp(struct mt76_dev *dev, u32 base, 1366764dee47SLorenzo Bianconi const struct mt76_reg_pair *data, 1367764dee47SLorenzo Bianconi int len); 1368764dee47SLorenzo Bianconi int mt76s_rd_rp(struct mt76_dev *dev, u32 base, 1369764dee47SLorenzo Bianconi struct mt76_reg_pair *data, int len); 1370d39b52e3SSean Wang 13719df0fab9SLorenzo Bianconi struct sk_buff * 1372a0a2034eSLorenzo Bianconi __mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, 1373b146f238SLorenzo Bianconi int len, int data_len, gfp_t gfp); 1374a0a2034eSLorenzo Bianconi static inline struct sk_buff * 1375bb31a80eSLorenzo Bianconi mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, 1376a0a2034eSLorenzo Bianconi int data_len) 1377a0a2034eSLorenzo Bianconi { 1378b146f238SLorenzo Bianconi return __mt76_mcu_msg_alloc(dev, data, data_len, data_len, GFP_KERNEL); 1379a0a2034eSLorenzo Bianconi } 1380a0a2034eSLorenzo Bianconi 1381c07a49d4SLorenzo Bianconi void mt76_mcu_rx_event(struct mt76_dev *dev, struct sk_buff *skb); 1382680abb25SLorenzo Bianconi struct sk_buff *mt76_mcu_get_response(struct mt76_dev *dev, 1383680abb25SLorenzo Bianconi unsigned long expires); 1384ae5ad627SFelix Fietkau int mt76_mcu_send_and_get_msg(struct mt76_dev *dev, int cmd, const void *data, 1385ae5ad627SFelix Fietkau int len, bool wait_resp, struct sk_buff **ret); 1386ae5ad627SFelix Fietkau int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, 1387ae5ad627SFelix Fietkau int cmd, bool wait_resp, struct sk_buff **ret); 1388215a2efaSLorenzo Bianconi int __mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data, 1389215a2efaSLorenzo Bianconi int len, int max_len); 1390215a2efaSLorenzo Bianconi static inline int 1391215a2efaSLorenzo Bianconi mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data, 1392215a2efaSLorenzo Bianconi int len) 1393215a2efaSLorenzo Bianconi { 13945b8f1840SSean Wang int max_len = 4096 - dev->mcu_ops->headroom; 13955b8f1840SSean Wang 13965b8f1840SSean Wang return __mt76_mcu_send_firmware(dev, cmd, data, len, max_len); 1397215a2efaSLorenzo Bianconi } 1398215a2efaSLorenzo Bianconi 1399ae5ad627SFelix Fietkau static inline int 1400ae5ad627SFelix Fietkau mt76_mcu_send_msg(struct mt76_dev *dev, int cmd, const void *data, int len, 1401ae5ad627SFelix Fietkau bool wait_resp) 1402ae5ad627SFelix Fietkau { 1403ae5ad627SFelix Fietkau return mt76_mcu_send_and_get_msg(dev, cmd, data, len, wait_resp, NULL); 1404ae5ad627SFelix Fietkau } 1405ae5ad627SFelix Fietkau 1406ae5ad627SFelix Fietkau static inline int 1407ae5ad627SFelix Fietkau mt76_mcu_skb_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, 1408ae5ad627SFelix Fietkau bool wait_resp) 1409ae5ad627SFelix Fietkau { 1410ae5ad627SFelix Fietkau return mt76_mcu_skb_send_and_get_msg(dev, skb, cmd, wait_resp, NULL); 1411ae5ad627SFelix Fietkau } 14129df0fab9SLorenzo Bianconi 14139220f695SLorenzo Bianconi void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set); 14149220f695SLorenzo Bianconi 141522b980baSFelix Fietkau s8 mt76_get_rate_power_limits(struct mt76_phy *phy, 141622b980baSFelix Fietkau struct ieee80211_channel *chan, 141722b980baSFelix Fietkau struct mt76_power_limits *dest, 141822b980baSFelix Fietkau s8 target_power); 141922b980baSFelix Fietkau 142058bcd4edSLorenzo Bianconi static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q) 142158bcd4edSLorenzo Bianconi { 142258bcd4edSLorenzo Bianconi return (q->flags & MT_QFLAG_WED) && 142358bcd4edSLorenzo Bianconi FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX; 142458bcd4edSLorenzo Bianconi } 142558bcd4edSLorenzo Bianconi 1426d089692bSLorenzo Bianconi struct mt76_txwi_cache * 1427d089692bSLorenzo Bianconi mt76_token_release(struct mt76_dev *dev, int token, bool *wake); 1428d089692bSLorenzo Bianconi int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi); 1429d089692bSLorenzo Bianconi void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked); 14302666beceSSujuan Chen struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token); 14312666beceSSujuan Chen int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr, 14322666beceSSujuan Chen struct mt76_txwi_cache *r, dma_addr_t phys); 14332f5c3c77SLorenzo Bianconi int mt76_create_page_pool(struct mt76_dev *dev, struct mt76_queue *q); 14342f5c3c77SLorenzo Bianconi static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct) 14352f5c3c77SLorenzo Bianconi { 14362f5c3c77SLorenzo Bianconi struct page *page = virt_to_head_page(buf); 14372f5c3c77SLorenzo Bianconi 14382f5c3c77SLorenzo Bianconi page_pool_put_full_page(page->pp, page, allow_direct); 14392f5c3c77SLorenzo Bianconi } 14402f5c3c77SLorenzo Bianconi 14412f5c3c77SLorenzo Bianconi static inline void * 14422f5c3c77SLorenzo Bianconi mt76_get_page_pool_buf(struct mt76_queue *q, u32 *offset, u32 size) 14432f5c3c77SLorenzo Bianconi { 14442f5c3c77SLorenzo Bianconi struct page *page; 14452f5c3c77SLorenzo Bianconi 14462f5c3c77SLorenzo Bianconi page = page_pool_dev_alloc_frag(q->page_pool, offset, size); 14472f5c3c77SLorenzo Bianconi if (!page) 14482f5c3c77SLorenzo Bianconi return NULL; 14492f5c3c77SLorenzo Bianconi 14502f5c3c77SLorenzo Bianconi return page_address(page) + *offset; 14512f5c3c77SLorenzo Bianconi } 1452d089692bSLorenzo Bianconi 1453d089692bSLorenzo Bianconi static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked) 1454d089692bSLorenzo Bianconi { 1455d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1456d089692bSLorenzo Bianconi __mt76_set_tx_blocked(dev, blocked); 1457d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1458d089692bSLorenzo Bianconi } 1459d089692bSLorenzo Bianconi 1460d089692bSLorenzo Bianconi static inline int 1461d089692bSLorenzo Bianconi mt76_token_get(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi) 1462d089692bSLorenzo Bianconi { 1463d089692bSLorenzo Bianconi int token; 1464d089692bSLorenzo Bianconi 1465d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 146661b5156bSFelix Fietkau token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC); 1467d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1468d089692bSLorenzo Bianconi 1469d089692bSLorenzo Bianconi return token; 1470d089692bSLorenzo Bianconi } 1471d089692bSLorenzo Bianconi 1472d089692bSLorenzo Bianconi static inline struct mt76_txwi_cache * 1473d089692bSLorenzo Bianconi mt76_token_put(struct mt76_dev *dev, int token) 1474d089692bSLorenzo Bianconi { 1475d089692bSLorenzo Bianconi struct mt76_txwi_cache *txwi; 1476d089692bSLorenzo Bianconi 1477d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1478d089692bSLorenzo Bianconi txwi = idr_remove(&dev->token, token); 1479d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1480d089692bSLorenzo Bianconi 1481d089692bSLorenzo Bianconi return txwi; 1482d089692bSLorenzo Bianconi } 148390052b84SLorenzo Bianconi 1484bd1e3e7bSLorenzo Bianconi static inline void mt76_packet_id_init(struct mt76_wcid *wcid) 148590052b84SLorenzo Bianconi { 1486bd1e3e7bSLorenzo Bianconi INIT_LIST_HEAD(&wcid->list); 1487bd1e3e7bSLorenzo Bianconi idr_init(&wcid->pktid); 148890052b84SLorenzo Bianconi } 1489bd1e3e7bSLorenzo Bianconi 1490bd1e3e7bSLorenzo Bianconi static inline void 1491bd1e3e7bSLorenzo Bianconi mt76_packet_id_flush(struct mt76_dev *dev, struct mt76_wcid *wcid) 1492bd1e3e7bSLorenzo Bianconi { 1493bd1e3e7bSLorenzo Bianconi struct sk_buff_head list; 1494bd1e3e7bSLorenzo Bianconi 1495bd1e3e7bSLorenzo Bianconi mt76_tx_status_lock(dev, &list); 1496bd1e3e7bSLorenzo Bianconi mt76_tx_status_skb_get(dev, wcid, -1, &list); 1497bd1e3e7bSLorenzo Bianconi mt76_tx_status_unlock(dev, &list); 1498bd1e3e7bSLorenzo Bianconi 1499bd1e3e7bSLorenzo Bianconi idr_destroy(&wcid->pktid); 1500bd1e3e7bSLorenzo Bianconi } 1501bd1e3e7bSLorenzo Bianconi 150217f1de56SFelix Fietkau #endif 1503