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, 267*c2eccffdSShayne Chen MT_PHY_TYPE_EHT_SU = 13, 268*c2eccffdSShayne Chen MT_PHY_TYPE_EHT_TRIG, 269*c2eccffdSShayne Chen MT_PHY_TYPE_EHT_MU, 270*c2eccffdSShayne Chen __MT_PHY_TYPE_MAX, 271dc877523SRyder Lee }; 272dc877523SRyder Lee 273dc877523SRyder Lee struct mt76_sta_stats { 274*c2eccffdSShayne Chen u64 tx_mode[__MT_PHY_TYPE_MAX]; 275dc877523SRyder Lee u64 tx_bw[4]; /* 20, 40, 80, 160 */ 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 297b37d0c97SBo Jiao #define MT76_N_WCIDS 544 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, 41917f1de56SFelix Fietkau }; 42017f1de56SFelix Fietkau 42117f1de56SFelix Fietkau struct mt76_hw_cap { 42217f1de56SFelix Fietkau bool has_2ghz; 42317f1de56SFelix Fietkau bool has_5ghz; 424f7d2958cSLorenzo Bianconi bool has_6ghz; 42517f1de56SFelix Fietkau }; 42617f1de56SFelix Fietkau 4279ec0b821SFelix Fietkau #define MT_DRV_TXWI_NO_FREE BIT(0) 4289ec0b821SFelix Fietkau #define MT_DRV_TX_ALIGNED4_SKBS BIT(1) 4295ce09c1aSFelix Fietkau #define MT_DRV_SW_RX_AIRTIME BIT(2) 43094d4d076SLorenzo Bianconi #define MT_DRV_RX_DMA_HDR BIT(3) 431d3c82998SLorenzo Bianconi #define MT_DRV_HW_MGMT_TXQ BIT(4) 4325b0fb852SBen Greear #define MT_DRV_AMSDU_OFFLOAD BIT(5) 4336ca66722SLorenzo Bianconi 43417f1de56SFelix Fietkau struct mt76_driver_ops { 4359ec0b821SFelix Fietkau u32 drv_flags; 436ea565833SFelix Fietkau u32 survey_flags; 43717f1de56SFelix Fietkau u16 txwi_size; 438d089692bSLorenzo Bianconi u16 token_size; 43922b980baSFelix Fietkau u8 mcs_rates; 44017f1de56SFelix Fietkau 441c560b137SRyder Lee void (*update_survey)(struct mt76_phy *phy); 44217f1de56SFelix Fietkau 44317f1de56SFelix Fietkau int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr, 444cfaae9e6SLorenzo Bianconi enum mt76_txq_id qid, struct mt76_wcid *wcid, 445b5903c47SLorenzo Bianconi struct ieee80211_sta *sta, 446b5903c47SLorenzo Bianconi struct mt76_tx_info *tx_info); 44717f1de56SFelix Fietkau 448d80e52c7SFelix Fietkau void (*tx_complete_skb)(struct mt76_dev *dev, 449e226ba2eSLorenzo Bianconi struct mt76_queue_entry *e); 45017f1de56SFelix Fietkau 451b40b15e1SLorenzo Bianconi bool (*tx_status_data)(struct mt76_dev *dev, u8 *update); 452b40b15e1SLorenzo Bianconi 453fbe50d9aSFelix Fietkau bool (*rx_check)(struct mt76_dev *dev, void *data, int len); 454fbe50d9aSFelix Fietkau 45517f1de56SFelix Fietkau void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q, 456c3137942SSujuan Chen struct sk_buff *skb, u32 *info); 45717f1de56SFelix Fietkau 45817f1de56SFelix Fietkau void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q); 459d71ef286SFelix Fietkau 460d71ef286SFelix Fietkau void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta, 461d71ef286SFelix Fietkau bool ps); 462e28487eaSFelix Fietkau 463e28487eaSFelix Fietkau int (*sta_add)(struct mt76_dev *dev, struct ieee80211_vif *vif, 464e28487eaSFelix Fietkau struct ieee80211_sta *sta); 465e28487eaSFelix Fietkau 4669c193de5SFelix Fietkau void (*sta_assoc)(struct mt76_dev *dev, struct ieee80211_vif *vif, 4679c193de5SFelix Fietkau struct ieee80211_sta *sta); 4689c193de5SFelix Fietkau 469e28487eaSFelix Fietkau void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif, 470e28487eaSFelix Fietkau struct ieee80211_sta *sta); 47117f1de56SFelix Fietkau }; 47217f1de56SFelix Fietkau 47317f1de56SFelix Fietkau struct mt76_channel_state { 47417f1de56SFelix Fietkau u64 cc_active; 47517f1de56SFelix Fietkau u64 cc_busy; 4766bfa6e38SLorenzo Bianconi u64 cc_rx; 4775ce09c1aSFelix Fietkau u64 cc_bss_rx; 478ea565833SFelix Fietkau u64 cc_tx; 479e5051965SFelix Fietkau 480e5051965SFelix Fietkau s8 noise; 48117f1de56SFelix Fietkau }; 48217f1de56SFelix Fietkau 48317f1de56SFelix Fietkau struct mt76_sband { 48417f1de56SFelix Fietkau struct ieee80211_supported_band sband; 48517f1de56SFelix Fietkau struct mt76_channel_state *chan; 48617f1de56SFelix Fietkau }; 48717f1de56SFelix Fietkau 488b40b15e1SLorenzo Bianconi /* addr req mask */ 489b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_EEPROM BIT(31) 490b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_CFG BIT(30) 491b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_MASK (MT_VEND_TYPE_EEPROM | MT_VEND_TYPE_CFG) 492b40b15e1SLorenzo Bianconi 493b40b15e1SLorenzo Bianconi #define MT_VEND_ADDR(type, n) (MT_VEND_TYPE_##type | (n)) 494b40b15e1SLorenzo Bianconi enum mt_vendor_req { 495b40b15e1SLorenzo Bianconi MT_VEND_DEV_MODE = 0x1, 496b40b15e1SLorenzo Bianconi MT_VEND_WRITE = 0x2, 4971e816c65SLorenzo Bianconi MT_VEND_POWER_ON = 0x4, 498b40b15e1SLorenzo Bianconi MT_VEND_MULTI_WRITE = 0x6, 499b40b15e1SLorenzo Bianconi MT_VEND_MULTI_READ = 0x7, 500b40b15e1SLorenzo Bianconi MT_VEND_READ_EEPROM = 0x9, 501b40b15e1SLorenzo Bianconi MT_VEND_WRITE_FCE = 0x42, 502b40b15e1SLorenzo Bianconi MT_VEND_WRITE_CFG = 0x46, 503b40b15e1SLorenzo Bianconi MT_VEND_READ_CFG = 0x47, 5041e816c65SLorenzo Bianconi MT_VEND_READ_EXT = 0x63, 5051e816c65SLorenzo Bianconi MT_VEND_WRITE_EXT = 0x66, 506d0846f08SSean Wang MT_VEND_FEATURE_SET = 0x91, 507b40b15e1SLorenzo Bianconi }; 508b40b15e1SLorenzo Bianconi 509b40b15e1SLorenzo Bianconi enum mt76u_in_ep { 510b40b15e1SLorenzo Bianconi MT_EP_IN_PKT_RX, 511b40b15e1SLorenzo Bianconi MT_EP_IN_CMD_RESP, 512b40b15e1SLorenzo Bianconi __MT_EP_IN_MAX, 513b40b15e1SLorenzo Bianconi }; 514b40b15e1SLorenzo Bianconi 515b40b15e1SLorenzo Bianconi enum mt76u_out_ep { 516b40b15e1SLorenzo Bianconi MT_EP_OUT_INBAND_CMD, 517b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_BE, 51823cb16d2SLorenzo Bianconi MT_EP_OUT_AC_BK, 519b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_VI, 520b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_VO, 521b40b15e1SLorenzo Bianconi MT_EP_OUT_HCCA, 522b40b15e1SLorenzo Bianconi __MT_EP_OUT_MAX, 523b40b15e1SLorenzo Bianconi }; 524b40b15e1SLorenzo Bianconi 52509872957SLorenzo Bianconi struct mt76_mcu { 52609872957SLorenzo Bianconi struct mutex mutex; 52709872957SLorenzo Bianconi u32 msg_seq; 528e452c6ebSFelix Fietkau int timeout; 52909872957SLorenzo Bianconi 53009872957SLorenzo Bianconi struct sk_buff_head res_q; 53109872957SLorenzo Bianconi wait_queue_head_t wait; 53209872957SLorenzo Bianconi }; 53309872957SLorenzo Bianconi 53414663f0cSLorenzo Bianconi #define MT_TX_SG_MAX_SIZE 8 535972c5981SSean Wang #define MT_RX_SG_MAX_SIZE 4 536b40b15e1SLorenzo Bianconi #define MT_NUM_TX_ENTRIES 256 537b40b15e1SLorenzo Bianconi #define MT_NUM_RX_ENTRIES 128 538b40b15e1SLorenzo Bianconi #define MCU_RESP_URB_SIZE 1024 539b40b15e1SLorenzo Bianconi struct mt76_usb { 540b40b15e1SLorenzo Bianconi struct mutex usb_ctrl_mtx; 541a6bfb6d1SStanislaw Gruszka u8 *data; 542a6bfb6d1SStanislaw Gruszka u16 data_len; 543b40b15e1SLorenzo Bianconi 5449daf27e6SLorenzo Bianconi struct mt76_worker status_worker; 545be83a7e2SLorenzo Bianconi struct mt76_worker rx_worker; 5469daf27e6SLorenzo Bianconi 547284efb47SLorenzo Bianconi struct work_struct stat_work; 548b40b15e1SLorenzo Bianconi 549b40b15e1SLorenzo Bianconi u8 out_ep[__MT_EP_OUT_MAX]; 550b40b15e1SLorenzo Bianconi u8 in_ep[__MT_EP_IN_MAX]; 55163a7de5dSLorenzo Bianconi bool sg_en; 552b40b15e1SLorenzo Bianconi 553b40b15e1SLorenzo Bianconi struct mt76u_mcu { 554a18a494fSStanislaw Gruszka u8 *data; 555851ab66eSLorenzo Bianconi /* multiple reads */ 556851ab66eSLorenzo Bianconi struct mt76_reg_pair *rp; 557851ab66eSLorenzo Bianconi int rp_len; 558851ab66eSLorenzo Bianconi u32 base; 559b40b15e1SLorenzo Bianconi } mcu; 560b40b15e1SLorenzo Bianconi }; 561b40b15e1SLorenzo Bianconi 562bf08d585SSean Wang #define MT76S_XMIT_BUF_SZ 0x3fe00 563b1460bb4SDeren Wu #define MT76S_NUM_TX_ENTRIES 256 564b1460bb4SDeren Wu #define MT76S_NUM_RX_ENTRIES 512 565d39b52e3SSean Wang struct mt76_sdio { 566fefb584dSLorenzo Bianconi struct mt76_worker txrx_worker; 5676a618acbSLorenzo Bianconi struct mt76_worker status_worker; 5686a618acbSLorenzo Bianconi struct mt76_worker net_worker; 5696a618acbSLorenzo Bianconi 570d74fda4cSLorenzo Bianconi struct work_struct stat_work; 571974327a4SLorenzo Bianconi 572bf08d585SSean Wang u8 *xmit_buf; 573bf08d585SSean Wang u32 xmit_buf_sz; 5741522ff73SLorenzo Bianconi 575d39b52e3SSean Wang struct sdio_func *func; 576b4964908SSean Wang void *intr_data; 577dacf0acfSSean Wang u8 hw_ver; 578ca74b9b9SSean Wang wait_queue_head_t wait; 579d39b52e3SSean Wang 580d39b52e3SSean Wang struct { 581d39b52e3SSean Wang int pse_data_quota; 582d39b52e3SSean Wang int ple_data_quota; 583d39b52e3SSean Wang int pse_mcu_quota; 5848c94f0e6SSean Wang int pse_page_size; 585d39b52e3SSean Wang int deficit; 586d39b52e3SSean Wang } sched; 5873ad08509SLorenzo Bianconi 5883ad08509SLorenzo Bianconi int (*parse_irq)(struct mt76_dev *dev, struct mt76s_intr *intr); 589d39b52e3SSean Wang }; 590d39b52e3SSean Wang 591f7bbb80fSLorenzo Bianconi struct mt76_mmio { 59227db1ad1SLorenzo Bianconi void __iomem *regs; 593957068c2SLorenzo Bianconi spinlock_t irq_lock; 594957068c2SLorenzo Bianconi u32 irqmask; 595f68d6762SFelix Fietkau 596f68d6762SFelix Fietkau struct mtk_wed_device wed; 597f7bbb80fSLorenzo Bianconi }; 598f7bbb80fSLorenzo Bianconi 5995ce09c1aSFelix Fietkau struct mt76_rx_status { 6005ce09c1aSFelix Fietkau union { 6015ce09c1aSFelix Fietkau struct mt76_wcid *wcid; 60249e649c3SRyder Lee u16 wcid_idx; 6035ce09c1aSFelix Fietkau }; 6045ce09c1aSFelix Fietkau 6050fda6d7bSRyder Lee u32 reorder_time; 6065ce09c1aSFelix Fietkau 6075ce09c1aSFelix Fietkau u32 ampdu_ref; 6080fda6d7bSRyder Lee u32 timestamp; 6095ce09c1aSFelix Fietkau 6105ce09c1aSFelix Fietkau u8 iv[6]; 6115ce09c1aSFelix Fietkau 612128c9b7dSLorenzo Bianconi u8 phy_idx:2; 6135ce09c1aSFelix Fietkau u8 aggr:1; 614e195dad1SFelix Fietkau u8 qos_ctl; 6155ce09c1aSFelix Fietkau u16 seqno; 6165ce09c1aSFelix Fietkau 6175ce09c1aSFelix Fietkau u16 freq; 6185ce09c1aSFelix Fietkau u32 flag; 6195ce09c1aSFelix Fietkau u8 enc_flags; 620af4a2f2fSRyder Lee u8 encoding:2, bw:3, he_ru:3; 621af4a2f2fSRyder Lee u8 he_gi:2, he_dcm:1; 622cc4b3c13SLorenzo Bianconi u8 amsdu:1, first_amsdu:1, last_amsdu:1; 6235ce09c1aSFelix Fietkau u8 rate_idx; 6245ce09c1aSFelix Fietkau u8 nss; 6255ce09c1aSFelix Fietkau u8 band; 6265ce09c1aSFelix Fietkau s8 signal; 6275ce09c1aSFelix Fietkau u8 chains; 6285ce09c1aSFelix Fietkau s8 chain_signal[IEEE80211_MAX_CHAINS]; 6295ce09c1aSFelix Fietkau }; 6305ce09c1aSFelix Fietkau 631502604f5SYN Chen struct mt76_freq_range_power { 632502604f5SYN Chen const struct cfg80211_sar_freq_ranges *range; 633502604f5SYN Chen s8 power; 634502604f5SYN Chen }; 635502604f5SYN Chen 636f0efa862SFelix Fietkau struct mt76_testmode_ops { 637c918c74dSShayne Chen int (*set_state)(struct mt76_phy *phy, enum mt76_testmode_state state); 638c918c74dSShayne Chen int (*set_params)(struct mt76_phy *phy, struct nlattr **tb, 639f0efa862SFelix Fietkau enum mt76_testmode_state new_state); 640c918c74dSShayne Chen int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg); 641f0efa862SFelix Fietkau }; 642f0efa862SFelix Fietkau 643f0efa862SFelix Fietkau struct mt76_testmode_data { 644f0efa862SFelix Fietkau enum mt76_testmode_state state; 645f0efa862SFelix Fietkau 646f0efa862SFelix Fietkau u32 param_set[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)]; 647f0efa862SFelix Fietkau struct sk_buff *tx_skb; 648f0efa862SFelix Fietkau 649f0efa862SFelix Fietkau u32 tx_count; 6502601dda8SShayne Chen u16 tx_mpdu_len; 651f0efa862SFelix Fietkau 652f0efa862SFelix Fietkau u8 tx_rate_mode; 653f0efa862SFelix Fietkau u8 tx_rate_idx; 654f0efa862SFelix Fietkau u8 tx_rate_nss; 655f0efa862SFelix Fietkau u8 tx_rate_sgi; 656f0efa862SFelix Fietkau u8 tx_rate_ldpc; 6577f54c742SShayne Chen u8 tx_rate_stbc; 6581a38c2f5SShayne Chen u8 tx_ltf; 659f0efa862SFelix Fietkau 660f0efa862SFelix Fietkau u8 tx_antenna_mask; 661fdc9c18eSShayne Chen u8 tx_spe_idx; 662f0efa862SFelix Fietkau 663b8cbdb97SShayne Chen u8 tx_duty_cycle; 664b8cbdb97SShayne Chen u32 tx_time; 665b8cbdb97SShayne Chen u32 tx_ipg; 666b8cbdb97SShayne Chen 667f0efa862SFelix Fietkau u32 freq_offset; 668f0efa862SFelix Fietkau 669f0efa862SFelix Fietkau u8 tx_power[4]; 670f0efa862SFelix Fietkau u8 tx_power_control; 671f0efa862SFelix Fietkau 672c40b42c2SShayne Chen u8 addr[3][ETH_ALEN]; 673c40b42c2SShayne Chen 674f0efa862SFelix Fietkau u32 tx_pending; 675f0efa862SFelix Fietkau u32 tx_queued; 676ba459094SShayne Chen u16 tx_queued_limit; 677f0efa862SFelix Fietkau u32 tx_done; 678f0efa862SFelix Fietkau struct { 679f0efa862SFelix Fietkau u64 packets[__MT_RXQ_MAX]; 680f0efa862SFelix Fietkau u64 fcs_error[__MT_RXQ_MAX]; 681f0efa862SFelix Fietkau } rx_stats; 682f0efa862SFelix Fietkau }; 683f0efa862SFelix Fietkau 68485d96704SLorenzo Bianconi struct mt76_vif { 68585d96704SLorenzo Bianconi u8 idx; 68685d96704SLorenzo Bianconi u8 omac_idx; 68785d96704SLorenzo Bianconi u8 band_idx; 68885d96704SLorenzo Bianconi u8 wmm_idx; 68985d96704SLorenzo Bianconi u8 scan_seq_num; 6905ea3d983SFelix Fietkau u8 cipher; 69185d96704SLorenzo Bianconi }; 69285d96704SLorenzo Bianconi 693ac24dd35SFelix Fietkau struct mt76_phy { 694ac24dd35SFelix Fietkau struct ieee80211_hw *hw; 695ac24dd35SFelix Fietkau struct mt76_dev *dev; 696a3d01038SFelix Fietkau void *priv; 69796747a51SFelix Fietkau 698011849e0SFelix Fietkau unsigned long state; 699dc44c45cSLorenzo Bianconi u8 band_idx; 700011849e0SFelix Fietkau 70191990519SLorenzo Bianconi struct mt76_queue *q_tx[__MT_TXQ_MAX]; 70291990519SLorenzo Bianconi 70396747a51SFelix Fietkau struct cfg80211_chan_def chandef; 70496747a51SFelix Fietkau struct ieee80211_channel *main_chan; 70596747a51SFelix Fietkau 70696747a51SFelix Fietkau struct mt76_channel_state *chan_state; 7073f306448SFelix Fietkau enum mt76_dfs_state dfs_state; 70896747a51SFelix Fietkau ktime_t survey_time; 70996747a51SFelix Fietkau 710d107501aSLorenzo Bianconi u32 aggr_stats[32]; 711d107501aSLorenzo Bianconi 71248dbce5cSLorenzo Bianconi struct mt76_hw_cap cap; 71396747a51SFelix Fietkau struct mt76_sband sband_2g; 71496747a51SFelix Fietkau struct mt76_sband sband_5g; 715cee3fd29SLorenzo Bianconi struct mt76_sband sband_6g; 716beaaeb6bSFelix Fietkau 71798df2baeSLorenzo Bianconi u8 macaddr[ETH_ALEN]; 71898df2baeSLorenzo Bianconi 719beaaeb6bSFelix Fietkau int txpower_cur; 720beaaeb6bSFelix Fietkau u8 antenna_mask; 721b9027e08SLorenzo Bianconi u16 chainmask; 722c918c74dSShayne Chen 723c918c74dSShayne Chen #ifdef CONFIG_NL80211_TESTMODE 724c918c74dSShayne Chen struct mt76_testmode_data test; 725c918c74dSShayne Chen #endif 726a782f8bfSLorenzo Bianconi 727a782f8bfSLorenzo Bianconi struct delayed_work mac_work; 728a782f8bfSLorenzo Bianconi u8 mac_work_count; 729cc4b3c13SLorenzo Bianconi 730cc4b3c13SLorenzo Bianconi struct { 731cc4b3c13SLorenzo Bianconi struct sk_buff *head; 732cc4b3c13SLorenzo Bianconi struct sk_buff **tail; 733cc4b3c13SLorenzo Bianconi u16 seqno; 734cc4b3c13SLorenzo Bianconi } rx_amsdu[__MT_RXQ_MAX]; 735502604f5SYN Chen 736502604f5SYN Chen struct mt76_freq_range_power *frp; 7373abd46ddSLorenzo Bianconi 7383abd46ddSLorenzo Bianconi struct { 7393abd46ddSLorenzo Bianconi struct led_classdev cdev; 7403abd46ddSLorenzo Bianconi char name[32]; 7413abd46ddSLorenzo Bianconi bool al; 7423abd46ddSLorenzo Bianconi u8 pin; 7433abd46ddSLorenzo Bianconi } leds; 744ac24dd35SFelix Fietkau }; 745ac24dd35SFelix Fietkau 74617f1de56SFelix Fietkau struct mt76_dev { 747ac24dd35SFelix Fietkau struct mt76_phy phy; /* must be first */ 748dc44c45cSLorenzo Bianconi struct mt76_phy *phys[__MT_MAX_BAND]; 749bfc394ddSFelix Fietkau 75017f1de56SFelix Fietkau struct ieee80211_hw *hw; 75117f1de56SFelix Fietkau 7522666beceSSujuan Chen spinlock_t wed_lock; 75317f1de56SFelix Fietkau spinlock_t lock; 75417f1de56SFelix Fietkau spinlock_t cc_lock; 755108a4861SStanislaw Gruszka 7565ce09c1aSFelix Fietkau u32 cur_cc_bss_rx; 7575ce09c1aSFelix Fietkau 7585ce09c1aSFelix Fietkau struct mt76_rx_status rx_ampdu_status; 7595ce09c1aSFelix Fietkau u32 rx_ampdu_len; 7605ce09c1aSFelix Fietkau u32 rx_ampdu_ref; 7615ce09c1aSFelix Fietkau 762108a4861SStanislaw Gruszka struct mutex mutex; 763108a4861SStanislaw Gruszka 76417f1de56SFelix Fietkau const struct mt76_bus_ops *bus; 76517f1de56SFelix Fietkau const struct mt76_driver_ops *drv; 766db0f04f3SLorenzo Bianconi const struct mt76_mcu_ops *mcu_ops; 76717f1de56SFelix Fietkau struct device *dev; 768d1ddc536SFelix Fietkau struct device *dma_dev; 76917f1de56SFelix Fietkau 77009872957SLorenzo Bianconi struct mt76_mcu mcu; 77109872957SLorenzo Bianconi 77217f1de56SFelix Fietkau struct net_device napi_dev; 773aa40528aSFelix Fietkau struct net_device tx_napi_dev; 774c3d7c82aSFelix Fietkau spinlock_t rx_lock; 77517f1de56SFelix Fietkau struct napi_struct napi[__MT_RXQ_MAX]; 77617f1de56SFelix Fietkau struct sk_buff_head rx_skb[__MT_RXQ_MAX]; 77717f1de56SFelix Fietkau 77817f1de56SFelix Fietkau struct list_head txwi_cache; 7792666beceSSujuan Chen struct list_head rxwi_cache; 780b1cb42adSLorenzo Bianconi struct mt76_queue *q_mcu[__MT_MCUQ_MAX]; 78117f1de56SFelix Fietkau struct mt76_queue q_rx[__MT_RXQ_MAX]; 78217f1de56SFelix Fietkau const struct mt76_queue_ops *queue_ops; 783c1e0d2beSLorenzo Bianconi int tx_dma_idx[4]; 78417f1de56SFelix Fietkau 785781eef5bSFelix Fietkau struct mt76_worker tx_worker; 7868402650aSLorenzo Bianconi struct napi_struct tx_napi; 787a33b8ab8SFelix Fietkau 788b17aff33SLorenzo Bianconi spinlock_t token_lock; 789b17aff33SLorenzo Bianconi struct idr token; 790f68d6762SFelix Fietkau u16 wed_token_count; 79161b5156bSFelix Fietkau u16 token_count; 79261b5156bSFelix Fietkau u16 token_size; 793b17aff33SLorenzo Bianconi 7942666beceSSujuan Chen spinlock_t rx_token_lock; 7952666beceSSujuan Chen struct idr rx_token; 7962666beceSSujuan Chen u16 rx_token_size; 7972666beceSSujuan Chen 79826e40d4cSFelix Fietkau wait_queue_head_t tx_wait; 799c34f1005SLorenzo Bianconi /* spinclock used to protect wcid pktid linked list */ 800c34f1005SLorenzo Bianconi spinlock_t status_lock; 80126e40d4cSFelix Fietkau 8025e616ad2SFelix Fietkau u32 wcid_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; 8035e616ad2SFelix Fietkau u32 wcid_phy_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; 80436404c06SStanislaw Gruszka 805b619e013SEvelyn Tsai u64 vif_mask; 8062ab33b8dSFelix Fietkau 80736404c06SStanislaw Gruszka struct mt76_wcid global_wcid; 80836404c06SStanislaw Gruszka struct mt76_wcid __rcu *wcid[MT76_N_WCIDS]; 809bd1e3e7bSLorenzo Bianconi struct list_head wcid_list; 81036404c06SStanislaw Gruszka 81117f1de56SFelix Fietkau u32 rev; 81217f1de56SFelix Fietkau 813dc6057f4SLorenzo Bianconi struct tasklet_struct pre_tbtt_tasklet; 8143041c445SLorenzo Bianconi int beacon_int; 815c8a04d98SLorenzo Bianconi u8 beacon_mask; 8163041c445SLorenzo Bianconi 81717f1de56SFelix Fietkau struct debugfs_blob_wrapper eeprom; 81817f1de56SFelix Fietkau struct debugfs_blob_wrapper otp; 81917f1de56SFelix Fietkau 8205b257371SLorenzo Bianconi char alpha2[3]; 821d8b8890dSLorenzo Bianconi enum nl80211_dfs_regions region; 822d8b8890dSLorenzo Bianconi 82317f1de56SFelix Fietkau u32 debugfs_reg; 82417f1de56SFelix Fietkau 825e7173858SFelix Fietkau u8 csa_complete; 826e7173858SFelix Fietkau 827108a4861SStanislaw Gruszka u32 rxfilter; 828108a4861SStanislaw Gruszka 829f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 830f0efa862SFelix Fietkau const struct mt76_testmode_ops *test_ops; 831e7a6a044SShayne Chen struct { 832e7a6a044SShayne Chen const char *name; 833e7a6a044SShayne Chen u32 offset; 834e7a6a044SShayne Chen } test_mtd; 835f0efa862SFelix Fietkau #endif 836a86f1d01SLorenzo Bianconi struct workqueue_struct *wq; 837a86f1d01SLorenzo Bianconi 838f7bbb80fSLorenzo Bianconi union { 839f7bbb80fSLorenzo Bianconi struct mt76_mmio mmio; 840b40b15e1SLorenzo Bianconi struct mt76_usb usb; 841d39b52e3SSean Wang struct mt76_sdio sdio; 84217f1de56SFelix Fietkau }; 843f7bbb80fSLorenzo Bianconi }; 84417f1de56SFelix Fietkau 84522b980baSFelix Fietkau struct mt76_power_limits { 84622b980baSFelix Fietkau s8 cck[4]; 84722b980baSFelix Fietkau s8 ofdm[8]; 84822b980baSFelix Fietkau s8 mcs[4][10]; 849a9627d99SShayne Chen s8 ru[7][12]; 85022b980baSFelix Fietkau }; 85122b980baSFelix Fietkau 85254ae98ffSLorenzo Bianconi struct mt76_ethtool_worker_info { 85354ae98ffSLorenzo Bianconi u64 *data; 85454ae98ffSLorenzo Bianconi int idx; 85554ae98ffSLorenzo Bianconi int initial_stat_idx; 85654ae98ffSLorenzo Bianconi int worker_stat_count; 85754ae98ffSLorenzo Bianconi int sta_count; 85854ae98ffSLorenzo Bianconi }; 85954ae98ffSLorenzo Bianconi 86054b8fdebSLorenzo Bianconi #define CCK_RATE(_idx, _rate) { \ 86154b8fdebSLorenzo Bianconi .bitrate = _rate, \ 86254b8fdebSLorenzo Bianconi .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ 86354b8fdebSLorenzo Bianconi .hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \ 86454b8fdebSLorenzo Bianconi .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + _idx), \ 86554b8fdebSLorenzo Bianconi } 86654b8fdebSLorenzo Bianconi 86754b8fdebSLorenzo Bianconi #define OFDM_RATE(_idx, _rate) { \ 86854b8fdebSLorenzo Bianconi .bitrate = _rate, \ 86954b8fdebSLorenzo Bianconi .hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 87054b8fdebSLorenzo Bianconi .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 87154b8fdebSLorenzo Bianconi } 87254b8fdebSLorenzo Bianconi 87354b8fdebSLorenzo Bianconi extern struct ieee80211_rate mt76_rates[12]; 87454b8fdebSLorenzo Bianconi 875d4131273SStanislaw Gruszka #define __mt76_rr(dev, ...) (dev)->bus->rr((dev), __VA_ARGS__) 876d4131273SStanislaw Gruszka #define __mt76_wr(dev, ...) (dev)->bus->wr((dev), __VA_ARGS__) 877d4131273SStanislaw Gruszka #define __mt76_rmw(dev, ...) (dev)->bus->rmw((dev), __VA_ARGS__) 87835e4ebeaSLorenzo Bianconi #define __mt76_wr_copy(dev, ...) (dev)->bus->write_copy((dev), __VA_ARGS__) 87935e4ebeaSLorenzo Bianconi #define __mt76_rr_copy(dev, ...) (dev)->bus->read_copy((dev), __VA_ARGS__) 880d4131273SStanislaw Gruszka 88122c575c4SStanislaw Gruszka #define __mt76_set(dev, offset, val) __mt76_rmw(dev, offset, 0, val) 88222c575c4SStanislaw Gruszka #define __mt76_clear(dev, offset, val) __mt76_rmw(dev, offset, val, 0) 88322c575c4SStanislaw Gruszka 88417f1de56SFelix Fietkau #define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__) 88517f1de56SFelix Fietkau #define mt76_wr(dev, ...) (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__) 88617f1de56SFelix Fietkau #define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__) 88735e4ebeaSLorenzo Bianconi #define mt76_wr_copy(dev, ...) (dev)->mt76.bus->write_copy(&((dev)->mt76), __VA_ARGS__) 88835e4ebeaSLorenzo Bianconi #define mt76_rr_copy(dev, ...) (dev)->mt76.bus->read_copy(&((dev)->mt76), __VA_ARGS__) 8896da5a291SStanislaw Gruszka #define mt76_wr_rp(dev, ...) (dev)->mt76.bus->wr_rp(&((dev)->mt76), __VA_ARGS__) 8906da5a291SStanislaw Gruszka #define mt76_rd_rp(dev, ...) (dev)->mt76.bus->rd_rp(&((dev)->mt76), __VA_ARGS__) 89117f1de56SFelix Fietkau 892f4d45fe2SLorenzo Bianconi 893e2c2fd0fSLorenzo Bianconi #define mt76_mcu_restart(dev, ...) (dev)->mt76.mcu_ops->mcu_restart(&((dev)->mt76)) 894db0f04f3SLorenzo Bianconi 89517f1de56SFelix Fietkau #define mt76_set(dev, offset, val) mt76_rmw(dev, offset, 0, val) 89617f1de56SFelix Fietkau #define mt76_clear(dev, offset, val) mt76_rmw(dev, offset, val, 0) 89717f1de56SFelix Fietkau 89817f1de56SFelix Fietkau #define mt76_get_field(_dev, _reg, _field) \ 89917f1de56SFelix Fietkau FIELD_GET(_field, mt76_rr(dev, _reg)) 90017f1de56SFelix Fietkau 90117f1de56SFelix Fietkau #define mt76_rmw_field(_dev, _reg, _field, _val) \ 90217f1de56SFelix Fietkau mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) 90317f1de56SFelix Fietkau 90446436b5eSStanislaw Gruszka #define __mt76_rmw_field(_dev, _reg, _field, _val) \ 90546436b5eSStanislaw Gruszka __mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) 90646436b5eSStanislaw Gruszka 907ac24dd35SFelix Fietkau #define mt76_hw(dev) (dev)->mphy.hw 90817f1de56SFelix Fietkau 90917f1de56SFelix Fietkau bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, 91017f1de56SFelix Fietkau int timeout); 91117f1de56SFelix Fietkau 91217f1de56SFelix Fietkau #define mt76_poll(dev, ...) __mt76_poll(&((dev)->mt76), __VA_ARGS__) 91317f1de56SFelix Fietkau 91435effe6cSDeren Wu bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, 91535effe6cSDeren Wu int timeout, int kick); 91635effe6cSDeren Wu #define __mt76_poll_msec(...) ____mt76_poll_msec(__VA_ARGS__, 10) 91735effe6cSDeren Wu #define mt76_poll_msec(dev, ...) ____mt76_poll_msec(&((dev)->mt76), __VA_ARGS__, 10) 91835effe6cSDeren Wu #define mt76_poll_msec_tick(dev, ...) ____mt76_poll_msec(&((dev)->mt76), __VA_ARGS__) 91917f1de56SFelix Fietkau 92017f1de56SFelix Fietkau void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs); 921f37f0550SLorenzo Bianconi void mt76_pci_disable_aspm(struct pci_dev *pdev); 92217f1de56SFelix Fietkau 92317f1de56SFelix Fietkau static inline u16 mt76_chip(struct mt76_dev *dev) 92417f1de56SFelix Fietkau { 92517f1de56SFelix Fietkau return dev->rev >> 16; 92617f1de56SFelix Fietkau } 92717f1de56SFelix Fietkau 92817f1de56SFelix Fietkau static inline u16 mt76_rev(struct mt76_dev *dev) 92917f1de56SFelix Fietkau { 93017f1de56SFelix Fietkau return dev->rev & 0xffff; 93117f1de56SFelix Fietkau } 93217f1de56SFelix Fietkau 93317f1de56SFelix Fietkau #define mt76xx_chip(dev) mt76_chip(&((dev)->mt76)) 93417f1de56SFelix Fietkau #define mt76xx_rev(dev) mt76_rev(&((dev)->mt76)) 93517f1de56SFelix Fietkau 936cb8ed33dSLorenzo Bianconi #define mt76_init_queues(dev, ...) (dev)->mt76.queue_ops->init(&((dev)->mt76), __VA_ARGS__) 937a23fde09SLorenzo Bianconi #define mt76_queue_alloc(dev, ...) (dev)->mt76.queue_ops->alloc(&((dev)->mt76), __VA_ARGS__) 9385ed31128SLorenzo Bianconi #define mt76_tx_queue_skb_raw(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb_raw(&((dev)->mt76), __VA_ARGS__) 939eb9ca7ecSLorenzo Bianconi #define mt76_tx_queue_skb(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb(&((dev)->mt76), __VA_ARGS__) 94017f1de56SFelix Fietkau #define mt76_queue_rx_reset(dev, ...) (dev)->mt76.queue_ops->rx_reset(&((dev)->mt76), __VA_ARGS__) 94117f1de56SFelix Fietkau #define mt76_queue_tx_cleanup(dev, ...) (dev)->mt76.queue_ops->tx_cleanup(&((dev)->mt76), __VA_ARGS__) 942c001df97SLorenzo Bianconi #define mt76_queue_rx_cleanup(dev, ...) (dev)->mt76.queue_ops->rx_cleanup(&((dev)->mt76), __VA_ARGS__) 94317f1de56SFelix Fietkau #define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__) 9443990465dSLorenzo Bianconi #define mt76_queue_reset(dev, ...) (dev)->mt76.queue_ops->reset_q(&((dev)->mt76), __VA_ARGS__) 94517f1de56SFelix Fietkau 946f473b42aSFelix Fietkau #define mt76_for_each_q_rx(dev, i) \ 947b3ad9d6aSBo Jiao for (i = 0; i < ARRAY_SIZE((dev)->q_rx); i++) \ 948b3ad9d6aSBo Jiao if ((dev)->q_rx[i].ndesc) 949f473b42aSFelix Fietkau 950c0f7b25aSLorenzo Bianconi struct mt76_dev *mt76_alloc_device(struct device *pdev, unsigned int size, 951c0f7b25aSLorenzo Bianconi const struct ieee80211_ops *ops, 952c0f7b25aSLorenzo Bianconi const struct mt76_driver_ops *drv_ops); 95317f1de56SFelix Fietkau int mt76_register_device(struct mt76_dev *dev, bool vht, 95417f1de56SFelix Fietkau struct ieee80211_rate *rates, int n_rates); 95517f1de56SFelix Fietkau void mt76_unregister_device(struct mt76_dev *dev); 956def34a2fSLorenzo Bianconi void mt76_free_device(struct mt76_dev *dev); 957c89d3625SFelix Fietkau void mt76_unregister_phy(struct mt76_phy *phy); 958c89d3625SFelix Fietkau 959c89d3625SFelix Fietkau struct mt76_phy *mt76_alloc_phy(struct mt76_dev *dev, unsigned int size, 960dc44c45cSLorenzo Bianconi const struct ieee80211_ops *ops, 961dc44c45cSLorenzo Bianconi u8 band_idx); 962db78a791SLorenzo Bianconi int mt76_register_phy(struct mt76_phy *phy, bool vht, 963db78a791SLorenzo Bianconi struct ieee80211_rate *rates, int n_rates); 96417f1de56SFelix Fietkau 9653263039dSLorenzo Bianconi struct dentry *mt76_register_debugfs_fops(struct mt76_phy *phy, 966f6e1f598SLorenzo Bianconi const struct file_operations *ops); 967f6e1f598SLorenzo Bianconi static inline struct dentry *mt76_register_debugfs(struct mt76_dev *dev) 968f6e1f598SLorenzo Bianconi { 9693263039dSLorenzo Bianconi return mt76_register_debugfs_fops(&dev->phy, NULL); 970f6e1f598SLorenzo Bianconi } 971f6e1f598SLorenzo Bianconi 9720b82a8e8SLorenzo Bianconi int mt76_queues_read(struct seq_file *s, void *data); 9738f410a8bSLorenzo Bianconi void mt76_seq_puts_array(struct seq_file *file, const char *str, 9748f410a8bSLorenzo Bianconi s8 *val, int len); 97517f1de56SFelix Fietkau 97617f1de56SFelix Fietkau int mt76_eeprom_init(struct mt76_dev *dev, int len); 97798df2baeSLorenzo Bianconi void mt76_eeprom_override(struct mt76_phy *phy); 978495184acSRyder Lee int mt76_get_of_eeprom(struct mt76_dev *dev, void *data, int offset, int len); 97917f1de56SFelix Fietkau 980b1cb42adSLorenzo Bianconi struct mt76_queue * 981b1cb42adSLorenzo Bianconi mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc, 982f68d6762SFelix Fietkau int ring_base, u32 flags); 98333920b2bSRyder Lee u16 mt76_calculate_default_rate(struct mt76_phy *phy, int rateidx); 984b1cb42adSLorenzo Bianconi static inline int mt76_init_tx_queue(struct mt76_phy *phy, int qid, int idx, 985f68d6762SFelix Fietkau int n_desc, int ring_base, u32 flags) 986b1cb42adSLorenzo Bianconi { 987b1cb42adSLorenzo Bianconi struct mt76_queue *q; 988b1cb42adSLorenzo Bianconi 989f68d6762SFelix Fietkau q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base, flags); 990b1cb42adSLorenzo Bianconi if (IS_ERR(q)) 991b1cb42adSLorenzo Bianconi return PTR_ERR(q); 992b1cb42adSLorenzo Bianconi 99391990519SLorenzo Bianconi phy->q_tx[qid] = q; 994b1cb42adSLorenzo Bianconi 995b1cb42adSLorenzo Bianconi return 0; 996b1cb42adSLorenzo Bianconi } 997b1cb42adSLorenzo Bianconi 998b1cb42adSLorenzo Bianconi static inline int mt76_init_mcu_queue(struct mt76_dev *dev, int qid, int idx, 999b1cb42adSLorenzo Bianconi int n_desc, int ring_base) 1000b1cb42adSLorenzo Bianconi { 1001b1cb42adSLorenzo Bianconi struct mt76_queue *q; 1002b1cb42adSLorenzo Bianconi 1003f68d6762SFelix Fietkau q = mt76_init_queue(dev, qid, idx, n_desc, ring_base, 0); 1004b1cb42adSLorenzo Bianconi if (IS_ERR(q)) 1005b1cb42adSLorenzo Bianconi return PTR_ERR(q); 1006b1cb42adSLorenzo Bianconi 1007b1cb42adSLorenzo Bianconi dev->q_mcu[qid] = q; 1008b1cb42adSLorenzo Bianconi 1009b1cb42adSLorenzo Bianconi return 0; 1010b1cb42adSLorenzo Bianconi } 1011b671da33SLorenzo Bianconi 1012011849e0SFelix Fietkau static inline struct mt76_phy * 1013128c9b7dSLorenzo Bianconi mt76_dev_phy(struct mt76_dev *dev, u8 phy_idx) 1014011849e0SFelix Fietkau { 1015dc44c45cSLorenzo Bianconi if ((phy_idx == MT_BAND1 && dev->phys[phy_idx]) || 1016dc44c45cSLorenzo Bianconi (phy_idx == MT_BAND2 && dev->phys[phy_idx])) 1017dc44c45cSLorenzo Bianconi return dev->phys[phy_idx]; 1018128c9b7dSLorenzo Bianconi 1019011849e0SFelix Fietkau return &dev->phy; 1020011849e0SFelix Fietkau } 1021011849e0SFelix Fietkau 1022bfc394ddSFelix Fietkau static inline struct ieee80211_hw * 1023128c9b7dSLorenzo Bianconi mt76_phy_hw(struct mt76_dev *dev, u8 phy_idx) 1024bfc394ddSFelix Fietkau { 1025128c9b7dSLorenzo Bianconi return mt76_dev_phy(dev, phy_idx)->hw; 1026bfc394ddSFelix Fietkau } 1027bfc394ddSFelix Fietkau 1028f3950a41SLorenzo Bianconi static inline u8 * 1029f3950a41SLorenzo Bianconi mt76_get_txwi_ptr(struct mt76_dev *dev, struct mt76_txwi_cache *t) 1030f3950a41SLorenzo Bianconi { 1031f3950a41SLorenzo Bianconi return (u8 *)t - dev->drv->txwi_size; 1032f3950a41SLorenzo Bianconi } 1033f3950a41SLorenzo Bianconi 1034ee8aa945SLorenzo Bianconi /* increment with wrap-around */ 1035ee8aa945SLorenzo Bianconi static inline int mt76_incr(int val, int size) 1036ee8aa945SLorenzo Bianconi { 1037ee8aa945SLorenzo Bianconi return (val + 1) & (size - 1); 1038ee8aa945SLorenzo Bianconi } 1039ee8aa945SLorenzo Bianconi 1040ee8aa945SLorenzo Bianconi /* decrement with wrap-around */ 1041ee8aa945SLorenzo Bianconi static inline int mt76_decr(int val, int size) 1042ee8aa945SLorenzo Bianconi { 1043ee8aa945SLorenzo Bianconi return (val - 1) & (size - 1); 1044ee8aa945SLorenzo Bianconi } 1045ee8aa945SLorenzo Bianconi 10461d0496c6SStanislaw Gruszka u8 mt76_ac_to_hwq(u8 ac); 1047b40b15e1SLorenzo Bianconi 104817f1de56SFelix Fietkau static inline struct ieee80211_txq * 104917f1de56SFelix Fietkau mtxq_to_txq(struct mt76_txq *mtxq) 105017f1de56SFelix Fietkau { 105117f1de56SFelix Fietkau void *ptr = mtxq; 105217f1de56SFelix Fietkau 105317f1de56SFelix Fietkau return container_of(ptr, struct ieee80211_txq, drv_priv); 105417f1de56SFelix Fietkau } 105517f1de56SFelix Fietkau 10569c68a57bSFelix Fietkau static inline struct ieee80211_sta * 10579c68a57bSFelix Fietkau wcid_to_sta(struct mt76_wcid *wcid) 10589c68a57bSFelix Fietkau { 10599c68a57bSFelix Fietkau void *ptr = wcid; 10609c68a57bSFelix Fietkau 10619c68a57bSFelix Fietkau if (!wcid || !wcid->sta) 10629c68a57bSFelix Fietkau return NULL; 10639c68a57bSFelix Fietkau 10649c68a57bSFelix Fietkau return container_of(ptr, struct ieee80211_sta, drv_priv); 10659c68a57bSFelix Fietkau } 10669c68a57bSFelix Fietkau 106788046b2cSFelix Fietkau static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb) 106888046b2cSFelix Fietkau { 106988046b2cSFelix Fietkau BUILD_BUG_ON(sizeof(struct mt76_tx_cb) > 107088046b2cSFelix Fietkau sizeof(IEEE80211_SKB_CB(skb)->status.status_driver_data)); 107188046b2cSFelix Fietkau return ((void *)IEEE80211_SKB_CB(skb)->status.status_driver_data); 107288046b2cSFelix Fietkau } 107388046b2cSFelix Fietkau 107477ae1d5eSRyder Lee static inline void *mt76_skb_get_hdr(struct sk_buff *skb) 107577ae1d5eSRyder Lee { 107677ae1d5eSRyder Lee struct mt76_rx_status mstat; 107777ae1d5eSRyder Lee u8 *data = skb->data; 107877ae1d5eSRyder Lee 107977ae1d5eSRyder Lee /* Alignment concerns */ 108077ae1d5eSRyder Lee BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he) % 4); 108177ae1d5eSRyder Lee BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he_mu) % 4); 108277ae1d5eSRyder Lee 108377ae1d5eSRyder Lee mstat = *((struct mt76_rx_status *)skb->cb); 108477ae1d5eSRyder Lee 108577ae1d5eSRyder Lee if (mstat.flag & RX_FLAG_RADIOTAP_HE) 108677ae1d5eSRyder Lee data += sizeof(struct ieee80211_radiotap_he); 108777ae1d5eSRyder Lee if (mstat.flag & RX_FLAG_RADIOTAP_HE_MU) 108877ae1d5eSRyder Lee data += sizeof(struct ieee80211_radiotap_he_mu); 108977ae1d5eSRyder Lee 109077ae1d5eSRyder Lee return data; 109177ae1d5eSRyder Lee } 109277ae1d5eSRyder Lee 10933bb45b5fSLorenzo Bianconi static inline void mt76_insert_hdr_pad(struct sk_buff *skb) 10943bb45b5fSLorenzo Bianconi { 10953bb45b5fSLorenzo Bianconi int len = ieee80211_get_hdrlen_from_skb(skb); 10963bb45b5fSLorenzo Bianconi 10973bb45b5fSLorenzo Bianconi if (len % 4 == 0) 10983bb45b5fSLorenzo Bianconi return; 10993bb45b5fSLorenzo Bianconi 11003bb45b5fSLorenzo Bianconi skb_push(skb, 2); 11013bb45b5fSLorenzo Bianconi memmove(skb->data, skb->data + 2, len); 11023bb45b5fSLorenzo Bianconi 11033bb45b5fSLorenzo Bianconi skb->data[len] = 0; 11043bb45b5fSLorenzo Bianconi skb->data[len + 1] = 0; 11053bb45b5fSLorenzo Bianconi } 11063bb45b5fSLorenzo Bianconi 11078548c6ebSFelix Fietkau static inline bool mt76_is_skb_pktid(u8 pktid) 11088548c6ebSFelix Fietkau { 11098548c6ebSFelix Fietkau if (pktid & MT_PACKET_ID_HAS_RATE) 11108548c6ebSFelix Fietkau return false; 11118548c6ebSFelix Fietkau 11128548c6ebSFelix Fietkau return pktid >= MT_PACKET_ID_FIRST; 11138548c6ebSFelix Fietkau } 11148548c6ebSFelix Fietkau 111507cda406SFelix Fietkau static inline u8 mt76_tx_power_nss_delta(u8 nss) 111607cda406SFelix Fietkau { 111707cda406SFelix Fietkau static const u8 nss_delta[4] = { 0, 6, 9, 12 }; 111803dd0d49SDeren Wu u8 idx = nss - 1; 111907cda406SFelix Fietkau 112003dd0d49SDeren Wu return (idx < ARRAY_SIZE(nss_delta)) ? nss_delta[idx] : 0; 112107cda406SFelix Fietkau } 112207cda406SFelix Fietkau 1123c918c74dSShayne Chen static inline bool mt76_testmode_enabled(struct mt76_phy *phy) 1124f0efa862SFelix Fietkau { 1125f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 1126c918c74dSShayne Chen return phy->test.state != MT76_TM_STATE_OFF; 1127c918c74dSShayne Chen #else 1128c918c74dSShayne Chen return false; 1129c918c74dSShayne Chen #endif 1130c918c74dSShayne Chen } 1131c918c74dSShayne Chen 1132c918c74dSShayne Chen static inline bool mt76_is_testmode_skb(struct mt76_dev *dev, 1133c918c74dSShayne Chen struct sk_buff *skb, 1134c918c74dSShayne Chen struct ieee80211_hw **hw) 1135c918c74dSShayne Chen { 1136c918c74dSShayne Chen #ifdef CONFIG_NL80211_TESTMODE 1137dc44c45cSLorenzo Bianconi int i; 1138dc44c45cSLorenzo Bianconi 1139dc44c45cSLorenzo Bianconi for (i = 0; i < ARRAY_SIZE(dev->phys); i++) { 1140dc44c45cSLorenzo Bianconi struct mt76_phy *phy = dev->phys[i]; 1141dc44c45cSLorenzo Bianconi 1142dc44c45cSLorenzo Bianconi if (phy && skb == phy->test.tx_skb) { 1143dc44c45cSLorenzo Bianconi *hw = dev->phys[i]->hw; 1144c918c74dSShayne Chen return true; 1145dc44c45cSLorenzo Bianconi } 1146dc44c45cSLorenzo Bianconi } 1147dc44c45cSLorenzo Bianconi return false; 1148f0efa862SFelix Fietkau #else 1149f0efa862SFelix Fietkau return false; 1150f0efa862SFelix Fietkau #endif 1151f0efa862SFelix Fietkau } 1152f0efa862SFelix Fietkau 115317f1de56SFelix Fietkau void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb); 11549fba6d07SFelix Fietkau void mt76_tx(struct mt76_phy *dev, struct ieee80211_sta *sta, 115517f1de56SFelix Fietkau struct mt76_wcid *wcid, struct sk_buff *skb); 115617f1de56SFelix Fietkau void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq); 115791990519SLorenzo Bianconi void mt76_stop_tx_queues(struct mt76_phy *phy, struct ieee80211_sta *sta, 115817f1de56SFelix Fietkau bool send_bar); 1159c50d105aSFelix Fietkau void mt76_tx_check_agg_ssn(struct ieee80211_sta *sta, struct sk_buff *skb); 11609fba6d07SFelix Fietkau void mt76_txq_schedule(struct mt76_phy *phy, enum mt76_txq_id qid); 11619fba6d07SFelix Fietkau void mt76_txq_schedule_all(struct mt76_phy *phy); 1162335e97acSLorenzo Bianconi void mt76_tx_worker_run(struct mt76_dev *dev); 1163781eef5bSFelix Fietkau void mt76_tx_worker(struct mt76_worker *w); 116417f1de56SFelix Fietkau void mt76_release_buffered_frames(struct ieee80211_hw *hw, 116517f1de56SFelix Fietkau struct ieee80211_sta *sta, 116617f1de56SFelix Fietkau u16 tids, int nframes, 116717f1de56SFelix Fietkau enum ieee80211_frame_release_type reason, 116817f1de56SFelix Fietkau bool more_data); 11695a95ca41SFelix Fietkau bool mt76_has_tx_pending(struct mt76_phy *phy); 117096747a51SFelix Fietkau void mt76_set_channel(struct mt76_phy *phy); 1171c560b137SRyder Lee void mt76_update_survey(struct mt76_phy *phy); 117204414240SLorenzo Bianconi void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time); 117317f1de56SFelix Fietkau int mt76_get_survey(struct ieee80211_hw *hw, int idx, 117417f1de56SFelix Fietkau struct survey_info *survey); 1175a71b648eSRyder Lee int mt76_rx_signal(u8 chain_mask, s8 *chain_signal); 1176bb3e3fecSRyder Lee void mt76_set_stream_caps(struct mt76_phy *phy, bool vht); 117717f1de56SFelix Fietkau 1178aee5b8cfSFelix Fietkau int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid, 11797c4f744dSRyder Lee u16 ssn, u16 size); 1180aee5b8cfSFelix Fietkau void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid); 1181aee5b8cfSFelix Fietkau 118230ce7f44SFelix Fietkau void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, 118330ce7f44SFelix Fietkau struct ieee80211_key_conf *key); 118479d1c94cSFelix Fietkau 118579d1c94cSFelix Fietkau void mt76_tx_status_lock(struct mt76_dev *dev, struct sk_buff_head *list) 1186c34f1005SLorenzo Bianconi __acquires(&dev->status_lock); 118779d1c94cSFelix Fietkau void mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list) 1188c34f1005SLorenzo Bianconi __releases(&dev->status_lock); 118979d1c94cSFelix Fietkau 119088046b2cSFelix Fietkau int mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, 119188046b2cSFelix Fietkau struct sk_buff *skb); 119288046b2cSFelix Fietkau struct sk_buff *mt76_tx_status_skb_get(struct mt76_dev *dev, 119379d1c94cSFelix Fietkau struct mt76_wcid *wcid, int pktid, 119479d1c94cSFelix Fietkau struct sk_buff_head *list); 119579d1c94cSFelix Fietkau void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb, 119679d1c94cSFelix Fietkau struct sk_buff_head *list); 11970fe88644SFelix Fietkau void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb, 11980fe88644SFelix Fietkau struct list_head *free_list); 11990fe88644SFelix Fietkau static inline void 12000fe88644SFelix Fietkau mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb) 12010fe88644SFelix Fietkau { 12020fe88644SFelix Fietkau __mt76_tx_complete_skb(dev, wcid, skb, NULL); 12030fe88644SFelix Fietkau } 12040fe88644SFelix Fietkau 1205c02f86eeSLorenzo Bianconi void mt76_tx_status_check(struct mt76_dev *dev, bool flush); 1206e28487eaSFelix Fietkau int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1207e28487eaSFelix Fietkau struct ieee80211_sta *sta, 1208e28487eaSFelix Fietkau enum ieee80211_sta_state old_state, 1209e28487eaSFelix Fietkau enum ieee80211_sta_state new_state); 121013f61dfcSLorenzo Bianconi void __mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif, 121113f61dfcSLorenzo Bianconi struct ieee80211_sta *sta); 121243ba1922SFelix Fietkau void mt76_sta_pre_rcu_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 121343ba1922SFelix Fietkau struct ieee80211_sta *sta); 121430ce7f44SFelix Fietkau 12158af63fedSFelix Fietkau int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy); 1216ef13edc0SFelix Fietkau 12179313faacSFelix Fietkau int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 12189313faacSFelix Fietkau int *dbm); 1219b3cb885eSLorenzo Bianconi int mt76_init_sar_power(struct ieee80211_hw *hw, 1220b3cb885eSLorenzo Bianconi const struct cfg80211_sar_specs *sar); 1221b3cb885eSLorenzo Bianconi int mt76_get_sar_power(struct mt76_phy *phy, 1222b3cb885eSLorenzo Bianconi struct ieee80211_channel *chan, 1223b3cb885eSLorenzo Bianconi int power); 12249313faacSFelix Fietkau 1225e7173858SFelix Fietkau void mt76_csa_check(struct mt76_dev *dev); 1226e7173858SFelix Fietkau void mt76_csa_finish(struct mt76_dev *dev); 1227e7173858SFelix Fietkau 1228e49c76d4SLorenzo Bianconi int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 122987d53103SStanislaw Gruszka int mt76_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set); 1230eadfd98fSLorenzo Bianconi void mt76_insert_ccmp_hdr(struct sk_buff *skb, u8 key_id); 1231d2679d65SLorenzo Bianconi int mt76_get_rate(struct mt76_dev *dev, 1232d2679d65SLorenzo Bianconi struct ieee80211_supported_band *sband, 1233d2679d65SLorenzo Bianconi int idx, bool cck); 12348b8ab5c2SLorenzo Bianconi void mt76_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 12358b8ab5c2SLorenzo Bianconi const u8 *mac); 12368b8ab5c2SLorenzo Bianconi void mt76_sw_scan_complete(struct ieee80211_hw *hw, 12378b8ab5c2SLorenzo Bianconi struct ieee80211_vif *vif); 12383f306448SFelix Fietkau enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy); 1239f0efa862SFelix Fietkau int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1240f0efa862SFelix Fietkau void *data, int len); 1241f0efa862SFelix Fietkau int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, 1242f0efa862SFelix Fietkau struct netlink_callback *cb, void *data, int len); 1243c918c74dSShayne Chen int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state); 12442601dda8SShayne Chen int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len); 1245f0efa862SFelix Fietkau 1246c918c74dSShayne Chen static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable) 1247f0efa862SFelix Fietkau { 1248f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 1249f0efa862SFelix Fietkau enum mt76_testmode_state state = MT76_TM_STATE_IDLE; 1250f0efa862SFelix Fietkau 1251c918c74dSShayne Chen if (disable || phy->test.state == MT76_TM_STATE_OFF) 1252f0efa862SFelix Fietkau state = MT76_TM_STATE_OFF; 1253f0efa862SFelix Fietkau 1254c918c74dSShayne Chen mt76_testmode_set_state(phy, state); 1255f0efa862SFelix Fietkau #endif 1256f0efa862SFelix Fietkau } 1257f0efa862SFelix Fietkau 125887d53103SStanislaw Gruszka 125917f1de56SFelix Fietkau /* internal */ 1260e394b575SFelix Fietkau static inline struct ieee80211_hw * 1261e394b575SFelix Fietkau mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb) 1262e394b575SFelix Fietkau { 1263e394b575SFelix Fietkau struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1264a062f001SLorenzo Bianconi u8 phy_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2; 1265a062f001SLorenzo Bianconi struct ieee80211_hw *hw = mt76_phy_hw(dev, phy_idx); 1266e394b575SFelix Fietkau 1267a062f001SLorenzo Bianconi info->hw_queue &= ~MT_TX_HW_QUEUE_PHY; 1268e394b575SFelix Fietkau 1269e394b575SFelix Fietkau return hw; 1270e394b575SFelix Fietkau } 1271e394b575SFelix Fietkau 127217f1de56SFelix Fietkau void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); 12732666beceSSujuan Chen void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); 12742666beceSSujuan Chen struct mt76_txwi_cache *mt76_get_rxwi(struct mt76_dev *dev); 1275a97a467aSSujuan Chen void mt76_free_pending_rxwi(struct mt76_dev *dev); 12769d9d738bSFelix Fietkau void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, 127781e850efSLorenzo Bianconi struct napi_struct *napi); 127881e850efSLorenzo Bianconi void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q, 127981e850efSLorenzo Bianconi struct napi_struct *napi); 1280aee5b8cfSFelix Fietkau void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames); 1281c918c74dSShayne Chen void mt76_testmode_tx_pending(struct mt76_phy *phy); 1282fe5b5ab5SFelix Fietkau void mt76_queue_tx_complete(struct mt76_dev *dev, struct mt76_queue *q, 1283fe5b5ab5SFelix Fietkau struct mt76_queue_entry *e); 128417f1de56SFelix Fietkau 1285b40b15e1SLorenzo Bianconi /* usb */ 1286b40b15e1SLorenzo Bianconi static inline bool mt76u_urb_error(struct urb *urb) 1287b40b15e1SLorenzo Bianconi { 1288b40b15e1SLorenzo Bianconi return urb->status && 1289b40b15e1SLorenzo Bianconi urb->status != -ECONNRESET && 1290b40b15e1SLorenzo Bianconi urb->status != -ESHUTDOWN && 1291b40b15e1SLorenzo Bianconi urb->status != -ENOENT; 1292b40b15e1SLorenzo Bianconi } 1293b40b15e1SLorenzo Bianconi 1294b40b15e1SLorenzo Bianconi /* Map hardware queues to usb endpoints */ 1295b40b15e1SLorenzo Bianconi static inline u8 q2ep(u8 qid) 1296b40b15e1SLorenzo Bianconi { 1297b40b15e1SLorenzo Bianconi /* TODO: take management packets to queue 5 */ 1298b40b15e1SLorenzo Bianconi return qid + 1; 1299b40b15e1SLorenzo Bianconi } 1300b40b15e1SLorenzo Bianconi 13015de4db8fSStanislaw Gruszka static inline int 1302b63aa031SStanislaw Gruszka mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len, 13033bcd979cSLorenzo Bianconi int timeout, int ep) 13045de4db8fSStanislaw Gruszka { 130580df01f4SLorenzo Bianconi struct usb_interface *uintf = to_usb_interface(dev->dev); 130680df01f4SLorenzo Bianconi struct usb_device *udev = interface_to_usbdev(uintf); 13075de4db8fSStanislaw Gruszka struct mt76_usb *usb = &dev->usb; 13085de4db8fSStanislaw Gruszka unsigned int pipe; 13095de4db8fSStanislaw Gruszka 1310b63aa031SStanislaw Gruszka if (actual_len) 13113bcd979cSLorenzo Bianconi pipe = usb_rcvbulkpipe(udev, usb->in_ep[ep]); 1312b63aa031SStanislaw Gruszka else 13133bcd979cSLorenzo Bianconi pipe = usb_sndbulkpipe(udev, usb->out_ep[ep]); 1314b63aa031SStanislaw Gruszka 1315b63aa031SStanislaw Gruszka return usb_bulk_msg(udev, pipe, data, len, actual_len, timeout); 13165de4db8fSStanislaw Gruszka } 13175de4db8fSStanislaw Gruszka 1318192ad406SLorenzo Bianconi void mt76_ethtool_page_pool_stats(struct mt76_dev *dev, u64 *data, int *index); 131954ae98ffSLorenzo Bianconi void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi, 132054ae98ffSLorenzo Bianconi struct mt76_sta_stats *stats); 1321e98e6df6SLorenzo Bianconi int mt76_skb_adjust_pad(struct sk_buff *skb, int pad); 13226cb596baSLorenzo Bianconi int __mt76u_vendor_request(struct mt76_dev *dev, u8 req, u8 req_type, 13236cb596baSLorenzo Bianconi u16 val, u16 offset, void *buf, size_t len); 1324b40b15e1SLorenzo Bianconi int mt76u_vendor_request(struct mt76_dev *dev, u8 req, 1325b40b15e1SLorenzo Bianconi u8 req_type, u16 val, u16 offset, 1326b40b15e1SLorenzo Bianconi void *buf, size_t len); 1327b40b15e1SLorenzo Bianconi void mt76u_single_wr(struct mt76_dev *dev, const u8 req, 1328b40b15e1SLorenzo Bianconi const u16 offset, const u32 val); 13296cb596baSLorenzo Bianconi void mt76u_read_copy(struct mt76_dev *dev, u32 offset, 13306cb596baSLorenzo Bianconi void *data, int len); 13316cb596baSLorenzo Bianconi u32 ___mt76u_rr(struct mt76_dev *dev, u8 req, u8 req_type, u32 addr); 13326cb596baSLorenzo Bianconi void ___mt76u_wr(struct mt76_dev *dev, u8 req, u8 req_type, 13336cb596baSLorenzo Bianconi u32 addr, u32 val); 13346cb596baSLorenzo Bianconi int __mt76u_init(struct mt76_dev *dev, struct usb_interface *intf, 13356cb596baSLorenzo Bianconi struct mt76_bus_ops *ops); 13366cb596baSLorenzo Bianconi int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf); 133794e1cfa8SLorenzo Bianconi int mt76u_alloc_mcu_queue(struct mt76_dev *dev); 1338b40b15e1SLorenzo Bianconi int mt76u_alloc_queues(struct mt76_dev *dev); 133939d501d9SStanislaw Gruszka void mt76u_stop_tx(struct mt76_dev *dev); 134039d501d9SStanislaw Gruszka void mt76u_stop_rx(struct mt76_dev *dev); 134139d501d9SStanislaw Gruszka int mt76u_resume_rx(struct mt76_dev *dev); 1342b40b15e1SLorenzo Bianconi void mt76u_queues_deinit(struct mt76_dev *dev); 1343b40b15e1SLorenzo Bianconi 1344d39b52e3SSean Wang int mt76s_init(struct mt76_dev *dev, struct sdio_func *func, 1345d39b52e3SSean Wang const struct mt76_bus_ops *bus_ops); 1346d512b008SLorenzo Bianconi int mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid); 1347d512b008SLorenzo Bianconi int mt76s_alloc_tx(struct mt76_dev *dev); 1348d39b52e3SSean Wang void mt76s_deinit(struct mt76_dev *dev); 1349764dee47SLorenzo Bianconi void mt76s_sdio_irq(struct sdio_func *func); 1350764dee47SLorenzo Bianconi void mt76s_txrx_worker(struct mt76_sdio *sdio); 1351ca74b9b9SSean Wang bool mt76s_txqs_empty(struct mt76_dev *dev); 1352dacf0acfSSean Wang int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, 1353dacf0acfSSean Wang int hw_ver); 1354764dee47SLorenzo Bianconi u32 mt76s_rr(struct mt76_dev *dev, u32 offset); 1355764dee47SLorenzo Bianconi void mt76s_wr(struct mt76_dev *dev, u32 offset, u32 val); 1356764dee47SLorenzo Bianconi u32 mt76s_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val); 1357764dee47SLorenzo Bianconi u32 mt76s_read_pcr(struct mt76_dev *dev); 1358764dee47SLorenzo Bianconi void mt76s_write_copy(struct mt76_dev *dev, u32 offset, 1359764dee47SLorenzo Bianconi const void *data, int len); 1360764dee47SLorenzo Bianconi void mt76s_read_copy(struct mt76_dev *dev, u32 offset, 1361764dee47SLorenzo Bianconi void *data, int len); 1362764dee47SLorenzo Bianconi int mt76s_wr_rp(struct mt76_dev *dev, u32 base, 1363764dee47SLorenzo Bianconi const struct mt76_reg_pair *data, 1364764dee47SLorenzo Bianconi int len); 1365764dee47SLorenzo Bianconi int mt76s_rd_rp(struct mt76_dev *dev, u32 base, 1366764dee47SLorenzo Bianconi struct mt76_reg_pair *data, int len); 1367d39b52e3SSean Wang 13689df0fab9SLorenzo Bianconi struct sk_buff * 1369a0a2034eSLorenzo Bianconi __mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, 1370b146f238SLorenzo Bianconi int len, int data_len, gfp_t gfp); 1371a0a2034eSLorenzo Bianconi static inline struct sk_buff * 1372bb31a80eSLorenzo Bianconi mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, 1373a0a2034eSLorenzo Bianconi int data_len) 1374a0a2034eSLorenzo Bianconi { 1375b146f238SLorenzo Bianconi return __mt76_mcu_msg_alloc(dev, data, data_len, data_len, GFP_KERNEL); 1376a0a2034eSLorenzo Bianconi } 1377a0a2034eSLorenzo Bianconi 1378c07a49d4SLorenzo Bianconi void mt76_mcu_rx_event(struct mt76_dev *dev, struct sk_buff *skb); 1379680abb25SLorenzo Bianconi struct sk_buff *mt76_mcu_get_response(struct mt76_dev *dev, 1380680abb25SLorenzo Bianconi unsigned long expires); 1381ae5ad627SFelix Fietkau int mt76_mcu_send_and_get_msg(struct mt76_dev *dev, int cmd, const void *data, 1382ae5ad627SFelix Fietkau int len, bool wait_resp, struct sk_buff **ret); 1383ae5ad627SFelix Fietkau int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, 1384ae5ad627SFelix Fietkau int cmd, bool wait_resp, struct sk_buff **ret); 1385215a2efaSLorenzo Bianconi int __mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data, 1386215a2efaSLorenzo Bianconi int len, int max_len); 1387215a2efaSLorenzo Bianconi static inline int 1388215a2efaSLorenzo Bianconi mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data, 1389215a2efaSLorenzo Bianconi int len) 1390215a2efaSLorenzo Bianconi { 13915b8f1840SSean Wang int max_len = 4096 - dev->mcu_ops->headroom; 13925b8f1840SSean Wang 13935b8f1840SSean Wang return __mt76_mcu_send_firmware(dev, cmd, data, len, max_len); 1394215a2efaSLorenzo Bianconi } 1395215a2efaSLorenzo Bianconi 1396ae5ad627SFelix Fietkau static inline int 1397ae5ad627SFelix Fietkau mt76_mcu_send_msg(struct mt76_dev *dev, int cmd, const void *data, int len, 1398ae5ad627SFelix Fietkau bool wait_resp) 1399ae5ad627SFelix Fietkau { 1400ae5ad627SFelix Fietkau return mt76_mcu_send_and_get_msg(dev, cmd, data, len, wait_resp, NULL); 1401ae5ad627SFelix Fietkau } 1402ae5ad627SFelix Fietkau 1403ae5ad627SFelix Fietkau static inline int 1404ae5ad627SFelix Fietkau mt76_mcu_skb_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, 1405ae5ad627SFelix Fietkau bool wait_resp) 1406ae5ad627SFelix Fietkau { 1407ae5ad627SFelix Fietkau return mt76_mcu_skb_send_and_get_msg(dev, skb, cmd, wait_resp, NULL); 1408ae5ad627SFelix Fietkau } 14099df0fab9SLorenzo Bianconi 14109220f695SLorenzo Bianconi void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set); 14119220f695SLorenzo Bianconi 141222b980baSFelix Fietkau s8 mt76_get_rate_power_limits(struct mt76_phy *phy, 141322b980baSFelix Fietkau struct ieee80211_channel *chan, 141422b980baSFelix Fietkau struct mt76_power_limits *dest, 141522b980baSFelix Fietkau s8 target_power); 141622b980baSFelix Fietkau 141758bcd4edSLorenzo Bianconi static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q) 141858bcd4edSLorenzo Bianconi { 141958bcd4edSLorenzo Bianconi return (q->flags & MT_QFLAG_WED) && 142058bcd4edSLorenzo Bianconi FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX; 142158bcd4edSLorenzo Bianconi } 142258bcd4edSLorenzo Bianconi 1423d089692bSLorenzo Bianconi struct mt76_txwi_cache * 1424d089692bSLorenzo Bianconi mt76_token_release(struct mt76_dev *dev, int token, bool *wake); 1425d089692bSLorenzo Bianconi int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi); 1426d089692bSLorenzo Bianconi void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked); 14272666beceSSujuan Chen struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token); 14282666beceSSujuan Chen int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr, 14292666beceSSujuan Chen struct mt76_txwi_cache *r, dma_addr_t phys); 14302f5c3c77SLorenzo Bianconi int mt76_create_page_pool(struct mt76_dev *dev, struct mt76_queue *q); 14312f5c3c77SLorenzo Bianconi static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct) 14322f5c3c77SLorenzo Bianconi { 14332f5c3c77SLorenzo Bianconi struct page *page = virt_to_head_page(buf); 14342f5c3c77SLorenzo Bianconi 14352f5c3c77SLorenzo Bianconi page_pool_put_full_page(page->pp, page, allow_direct); 14362f5c3c77SLorenzo Bianconi } 14372f5c3c77SLorenzo Bianconi 14382f5c3c77SLorenzo Bianconi static inline void * 14392f5c3c77SLorenzo Bianconi mt76_get_page_pool_buf(struct mt76_queue *q, u32 *offset, u32 size) 14402f5c3c77SLorenzo Bianconi { 14412f5c3c77SLorenzo Bianconi struct page *page; 14422f5c3c77SLorenzo Bianconi 14432f5c3c77SLorenzo Bianconi page = page_pool_dev_alloc_frag(q->page_pool, offset, size); 14442f5c3c77SLorenzo Bianconi if (!page) 14452f5c3c77SLorenzo Bianconi return NULL; 14462f5c3c77SLorenzo Bianconi 14472f5c3c77SLorenzo Bianconi return page_address(page) + *offset; 14482f5c3c77SLorenzo Bianconi } 1449d089692bSLorenzo Bianconi 1450d089692bSLorenzo Bianconi static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked) 1451d089692bSLorenzo Bianconi { 1452d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1453d089692bSLorenzo Bianconi __mt76_set_tx_blocked(dev, blocked); 1454d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1455d089692bSLorenzo Bianconi } 1456d089692bSLorenzo Bianconi 1457d089692bSLorenzo Bianconi static inline int 1458d089692bSLorenzo Bianconi mt76_token_get(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi) 1459d089692bSLorenzo Bianconi { 1460d089692bSLorenzo Bianconi int token; 1461d089692bSLorenzo Bianconi 1462d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 146361b5156bSFelix Fietkau token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC); 1464d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1465d089692bSLorenzo Bianconi 1466d089692bSLorenzo Bianconi return token; 1467d089692bSLorenzo Bianconi } 1468d089692bSLorenzo Bianconi 1469d089692bSLorenzo Bianconi static inline struct mt76_txwi_cache * 1470d089692bSLorenzo Bianconi mt76_token_put(struct mt76_dev *dev, int token) 1471d089692bSLorenzo Bianconi { 1472d089692bSLorenzo Bianconi struct mt76_txwi_cache *txwi; 1473d089692bSLorenzo Bianconi 1474d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1475d089692bSLorenzo Bianconi txwi = idr_remove(&dev->token, token); 1476d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1477d089692bSLorenzo Bianconi 1478d089692bSLorenzo Bianconi return txwi; 1479d089692bSLorenzo Bianconi } 148090052b84SLorenzo Bianconi 1481bd1e3e7bSLorenzo Bianconi static inline void mt76_packet_id_init(struct mt76_wcid *wcid) 148290052b84SLorenzo Bianconi { 1483bd1e3e7bSLorenzo Bianconi INIT_LIST_HEAD(&wcid->list); 1484bd1e3e7bSLorenzo Bianconi idr_init(&wcid->pktid); 148590052b84SLorenzo Bianconi } 1486bd1e3e7bSLorenzo Bianconi 1487bd1e3e7bSLorenzo Bianconi static inline void 1488bd1e3e7bSLorenzo Bianconi mt76_packet_id_flush(struct mt76_dev *dev, struct mt76_wcid *wcid) 1489bd1e3e7bSLorenzo Bianconi { 1490bd1e3e7bSLorenzo Bianconi struct sk_buff_head list; 1491bd1e3e7bSLorenzo Bianconi 1492bd1e3e7bSLorenzo Bianconi mt76_tx_status_lock(dev, &list); 1493bd1e3e7bSLorenzo Bianconi mt76_tx_status_skb_get(dev, wcid, -1, &list); 1494bd1e3e7bSLorenzo Bianconi mt76_tx_status_unlock(dev, &list); 1495bd1e3e7bSLorenzo Bianconi 1496bd1e3e7bSLorenzo Bianconi idr_destroy(&wcid->pktid); 1497bd1e3e7bSLorenzo Bianconi } 1498bd1e3e7bSLorenzo Bianconi 149917f1de56SFelix Fietkau #endif 1500