10e3d6777SRyder Lee /* SPDX-License-Identifier: ISC */ 217f1de56SFelix Fietkau /* 317f1de56SFelix Fietkau * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 417f1de56SFelix Fietkau */ 517f1de56SFelix Fietkau 617f1de56SFelix Fietkau #ifndef __MT76_H 717f1de56SFelix Fietkau #define __MT76_H 817f1de56SFelix Fietkau 917f1de56SFelix Fietkau #include <linux/kernel.h> 1017f1de56SFelix Fietkau #include <linux/io.h> 1117f1de56SFelix Fietkau #include <linux/spinlock.h> 1217f1de56SFelix Fietkau #include <linux/skbuff.h> 1317f1de56SFelix Fietkau #include <linux/leds.h> 14b40b15e1SLorenzo Bianconi #include <linux/usb.h> 15ef13edc0SFelix Fietkau #include <linux/average.h> 16f68d6762SFelix Fietkau #include <linux/soc/mediatek/mtk_wed.h> 1717f1de56SFelix Fietkau #include <net/mac80211.h> 18a9ca9f9cSYunsheng Lin #include <net/page_pool/helpers.h> 1917f1de56SFelix Fietkau #include "util.h" 20f0efa862SFelix Fietkau #include "testmode.h" 2117f1de56SFelix Fietkau 2217f1de56SFelix Fietkau #define MT_MCU_RING_SIZE 32 2317f1de56SFelix Fietkau #define MT_RX_BUF_SIZE 2048 24123bc712SDeren Wu #define MT_SKB_HEAD_LEN 256 2517f1de56SFelix Fietkau 26e1378e52SFelix Fietkau #define MT_MAX_NON_AQL_PKT 16 27e1378e52SFelix Fietkau #define MT_TXQ_FREE_THR 32 28e1378e52SFelix Fietkau 29d089692bSLorenzo Bianconi #define MT76_TOKEN_FREE_THR 64 30d089692bSLorenzo Bianconi 31f68d6762SFelix Fietkau #define MT_QFLAG_WED_RING GENMASK(1, 0) 32af8d2af5SLorenzo Bianconi #define MT_QFLAG_WED_TYPE GENMASK(4, 2) 33af8d2af5SLorenzo Bianconi #define MT_QFLAG_WED BIT(5) 34f68d6762SFelix Fietkau 35f68d6762SFelix Fietkau #define __MT_WED_Q(_type, _n) (MT_QFLAG_WED | \ 36f68d6762SFelix Fietkau FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \ 37f68d6762SFelix Fietkau FIELD_PREP(MT_QFLAG_WED_RING, _n)) 38f68d6762SFelix Fietkau #define MT_WED_Q_TX(_n) __MT_WED_Q(MT76_WED_Q_TX, _n) 39cd372b8cSLorenzo Bianconi #define MT_WED_Q_RX(_n) __MT_WED_Q(MT76_WED_Q_RX, _n) 40f68d6762SFelix Fietkau #define MT_WED_Q_TXFREE __MT_WED_Q(MT76_WED_Q_TXFREE, 0) 41f68d6762SFelix Fietkau 4217f1de56SFelix Fietkau struct mt76_dev; 4396747a51SFelix Fietkau struct mt76_phy; 44469d4818SLorenzo Bianconi struct mt76_wcid; 453ad08509SLorenzo Bianconi struct mt76s_intr; 4617f1de56SFelix Fietkau 476da5a291SStanislaw Gruszka struct mt76_reg_pair { 486da5a291SStanislaw Gruszka u32 reg; 496da5a291SStanislaw Gruszka u32 value; 506da5a291SStanislaw Gruszka }; 516da5a291SStanislaw Gruszka 52c50479faSStanislaw Gruszka enum mt76_bus_type { 53c50479faSStanislaw Gruszka MT76_BUS_MMIO, 54c50479faSStanislaw Gruszka MT76_BUS_USB, 55d39b52e3SSean Wang MT76_BUS_SDIO, 56c50479faSStanislaw Gruszka }; 57c50479faSStanislaw Gruszka 58f68d6762SFelix Fietkau enum mt76_wed_type { 59f68d6762SFelix Fietkau MT76_WED_Q_TX, 60f68d6762SFelix Fietkau MT76_WED_Q_TXFREE, 61cd372b8cSLorenzo Bianconi MT76_WED_Q_RX, 62f68d6762SFelix Fietkau }; 63f68d6762SFelix Fietkau 6417f1de56SFelix Fietkau struct mt76_bus_ops { 6517f1de56SFelix Fietkau u32 (*rr)(struct mt76_dev *dev, u32 offset); 6617f1de56SFelix Fietkau void (*wr)(struct mt76_dev *dev, u32 offset, u32 val); 6717f1de56SFelix Fietkau u32 (*rmw)(struct mt76_dev *dev, u32 offset, u32 mask, u32 val); 6835e4ebeaSLorenzo Bianconi void (*write_copy)(struct mt76_dev *dev, u32 offset, const void *data, 6935e4ebeaSLorenzo Bianconi int len); 7035e4ebeaSLorenzo Bianconi void (*read_copy)(struct mt76_dev *dev, u32 offset, void *data, 7117f1de56SFelix Fietkau int len); 726da5a291SStanislaw Gruszka int (*wr_rp)(struct mt76_dev *dev, u32 base, 736da5a291SStanislaw Gruszka const struct mt76_reg_pair *rp, int len); 746da5a291SStanislaw Gruszka int (*rd_rp)(struct mt76_dev *dev, u32 base, 756da5a291SStanislaw Gruszka struct mt76_reg_pair *rp, int len); 76c50479faSStanislaw Gruszka enum mt76_bus_type type; 7717f1de56SFelix Fietkau }; 7817f1de56SFelix Fietkau 7961c51a74SLorenzo Bianconi #define mt76_is_usb(dev) ((dev)->bus->type == MT76_BUS_USB) 8061c51a74SLorenzo Bianconi #define mt76_is_mmio(dev) ((dev)->bus->type == MT76_BUS_MMIO) 81d39b52e3SSean Wang #define mt76_is_sdio(dev) ((dev)->bus->type == MT76_BUS_SDIO) 82c50479faSStanislaw Gruszka 8317f1de56SFelix Fietkau enum mt76_txq_id { 8417f1de56SFelix Fietkau MT_TXQ_VO = IEEE80211_AC_VO, 8517f1de56SFelix Fietkau MT_TXQ_VI = IEEE80211_AC_VI, 8617f1de56SFelix Fietkau MT_TXQ_BE = IEEE80211_AC_BE, 8717f1de56SFelix Fietkau MT_TXQ_BK = IEEE80211_AC_BK, 8817f1de56SFelix Fietkau MT_TXQ_PSD, 8917f1de56SFelix Fietkau MT_TXQ_BEACON, 9017f1de56SFelix Fietkau MT_TXQ_CAB, 9117f1de56SFelix Fietkau __MT_TXQ_MAX 9217f1de56SFelix Fietkau }; 9317f1de56SFelix Fietkau 94b1cb42adSLorenzo Bianconi enum mt76_mcuq_id { 95e637763bSLorenzo Bianconi MT_MCUQ_WM, 96e637763bSLorenzo Bianconi MT_MCUQ_WA, 97e637763bSLorenzo Bianconi MT_MCUQ_FWDL, 98b1cb42adSLorenzo Bianconi __MT_MCUQ_MAX 99b1cb42adSLorenzo Bianconi }; 100b1cb42adSLorenzo Bianconi 10117f1de56SFelix Fietkau enum mt76_rxq_id { 10217f1de56SFelix Fietkau MT_RXQ_MAIN, 10317f1de56SFelix Fietkau MT_RXQ_MCU, 104d3377b78SRyder Lee MT_RXQ_MCU_WA, 105fc8f841bSLorenzo Bianconi MT_RXQ_BAND1, 106fc8f841bSLorenzo Bianconi MT_RXQ_BAND1_WA, 107f9b627f1SBo Jiao MT_RXQ_MAIN_WA, 108fc8f841bSLorenzo Bianconi MT_RXQ_BAND2, 109fc8f841bSLorenzo Bianconi MT_RXQ_BAND2_WA, 11017f1de56SFelix Fietkau __MT_RXQ_MAX 11117f1de56SFelix Fietkau }; 11217f1de56SFelix Fietkau 113dc44c45cSLorenzo Bianconi enum mt76_band_id { 114dc44c45cSLorenzo Bianconi MT_BAND0, 115dc44c45cSLorenzo Bianconi MT_BAND1, 116dc44c45cSLorenzo Bianconi MT_BAND2, 117dc44c45cSLorenzo Bianconi __MT_MAX_BAND 118dc44c45cSLorenzo Bianconi }; 119dc44c45cSLorenzo Bianconi 120c368362cSRyder Lee enum mt76_cipher_type { 121c368362cSRyder Lee MT_CIPHER_NONE, 122c368362cSRyder Lee MT_CIPHER_WEP40, 123c368362cSRyder Lee MT_CIPHER_TKIP, 124c368362cSRyder Lee MT_CIPHER_TKIP_NO_MIC, 125c368362cSRyder Lee MT_CIPHER_AES_CCMP, 126c368362cSRyder Lee MT_CIPHER_WEP104, 127c368362cSRyder Lee MT_CIPHER_BIP_CMAC_128, 128c368362cSRyder Lee MT_CIPHER_WEP128, 129c368362cSRyder Lee MT_CIPHER_WAPI, 130c368362cSRyder Lee MT_CIPHER_CCMP_CCX, 131c368362cSRyder Lee MT_CIPHER_CCMP_256, 132c368362cSRyder Lee MT_CIPHER_GCMP, 133c368362cSRyder Lee MT_CIPHER_GCMP_256, 134c368362cSRyder Lee }; 135c368362cSRyder Lee 1363f306448SFelix Fietkau enum mt76_dfs_state { 1373f306448SFelix Fietkau MT_DFS_STATE_UNKNOWN, 1383f306448SFelix Fietkau MT_DFS_STATE_DISABLED, 1393f306448SFelix Fietkau MT_DFS_STATE_CAC, 1403f306448SFelix Fietkau MT_DFS_STATE_ACTIVE, 1413f306448SFelix Fietkau }; 1423f306448SFelix Fietkau 14317f1de56SFelix Fietkau struct mt76_queue_buf { 14417f1de56SFelix Fietkau dma_addr_t addr; 14527d5c528SFelix Fietkau u16 len; 14627d5c528SFelix Fietkau bool skip_unmap; 14717f1de56SFelix Fietkau }; 14817f1de56SFelix Fietkau 149b5903c47SLorenzo Bianconi struct mt76_tx_info { 150b5903c47SLorenzo Bianconi struct mt76_queue_buf buf[32]; 151cfaae9e6SLorenzo Bianconi struct sk_buff *skb; 152b5903c47SLorenzo Bianconi int nbuf; 153b5903c47SLorenzo Bianconi u32 info; 154b5903c47SLorenzo Bianconi }; 155b5903c47SLorenzo Bianconi 15617f1de56SFelix Fietkau struct mt76_queue_entry { 15717f1de56SFelix Fietkau union { 15817f1de56SFelix Fietkau void *buf; 15917f1de56SFelix Fietkau struct sk_buff *skb; 16017f1de56SFelix Fietkau }; 161b40b15e1SLorenzo Bianconi union { 16217f1de56SFelix Fietkau struct mt76_txwi_cache *txwi; 163d7d4ea9aSStanislaw Gruszka struct urb *urb; 164d39b52e3SSean Wang int buf_sz; 165b40b15e1SLorenzo Bianconi }; 16675d4bf1fSFelix Fietkau u32 dma_addr[2]; 16775d4bf1fSFelix Fietkau u16 dma_len[2]; 168e1378e52SFelix Fietkau u16 wcid; 1697bd0650bSLorenzo Bianconi bool skip_buf0:1; 17027d5c528SFelix Fietkau bool skip_buf1:1; 1717bd0650bSLorenzo Bianconi bool done:1; 17217f1de56SFelix Fietkau }; 17317f1de56SFelix Fietkau 17417f1de56SFelix Fietkau struct mt76_queue_regs { 17517f1de56SFelix Fietkau u32 desc_base; 17617f1de56SFelix Fietkau u32 ring_size; 17717f1de56SFelix Fietkau u32 cpu_idx; 17817f1de56SFelix Fietkau u32 dma_idx; 17917f1de56SFelix Fietkau } __packed __aligned(4); 18017f1de56SFelix Fietkau 18117f1de56SFelix Fietkau struct mt76_queue { 18217f1de56SFelix Fietkau struct mt76_queue_regs __iomem *regs; 18317f1de56SFelix Fietkau 18417f1de56SFelix Fietkau spinlock_t lock; 1859716ef04SFelix Fietkau spinlock_t cleanup_lock; 18617f1de56SFelix Fietkau struct mt76_queue_entry *entry; 18717f1de56SFelix Fietkau struct mt76_desc *desc; 18817f1de56SFelix Fietkau 189b40b15e1SLorenzo Bianconi u16 first; 19017f1de56SFelix Fietkau u16 head; 19117f1de56SFelix Fietkau u16 tail; 19217f1de56SFelix Fietkau int ndesc; 19317f1de56SFelix Fietkau int queued; 19417f1de56SFelix Fietkau int buf_size; 195cd44bc40SLorenzo Bianconi bool stopped; 19690d494c9SFelix Fietkau bool blocked; 19717f1de56SFelix Fietkau 19817f1de56SFelix Fietkau u8 buf_offset; 19917f1de56SFelix Fietkau u8 hw_idx; 200f68d6762SFelix Fietkau u8 flags; 201f68d6762SFelix Fietkau 2022e420b88SLorenzo Bianconi struct mtk_wed_device *wed; 203f68d6762SFelix Fietkau u32 wed_regs; 20417f1de56SFelix Fietkau 20517f1de56SFelix Fietkau dma_addr_t desc_dma; 20617f1de56SFelix Fietkau struct sk_buff *rx_head; 2072f5c3c77SLorenzo Bianconi struct page_pool *page_pool; 20817f1de56SFelix Fietkau }; 20917f1de56SFelix Fietkau 210db0f04f3SLorenzo Bianconi struct mt76_mcu_ops { 211bb31a80eSLorenzo Bianconi u32 headroom; 212bb31a80eSLorenzo Bianconi u32 tailroom; 213bb31a80eSLorenzo Bianconi 214a74d6336SStanislaw Gruszka int (*mcu_send_msg)(struct mt76_dev *dev, int cmd, const void *data, 215a74d6336SStanislaw Gruszka int len, bool wait_resp); 216f4d45fe2SLorenzo Bianconi int (*mcu_skb_send_msg)(struct mt76_dev *dev, struct sk_buff *skb, 217e452c6ebSFelix Fietkau int cmd, int *seq); 218f320d812SFelix Fietkau int (*mcu_parse_response)(struct mt76_dev *dev, int cmd, 219f320d812SFelix Fietkau struct sk_buff *skb, int seq); 220d39b52e3SSean Wang u32 (*mcu_rr)(struct mt76_dev *dev, u32 offset); 221d39b52e3SSean Wang void (*mcu_wr)(struct mt76_dev *dev, u32 offset, u32 val); 2226da5a291SStanislaw Gruszka int (*mcu_wr_rp)(struct mt76_dev *dev, u32 base, 2236da5a291SStanislaw Gruszka const struct mt76_reg_pair *rp, int len); 2246da5a291SStanislaw Gruszka int (*mcu_rd_rp)(struct mt76_dev *dev, u32 base, 2256da5a291SStanislaw Gruszka struct mt76_reg_pair *rp, int len); 22600496042SFelix Fietkau int (*mcu_restart)(struct mt76_dev *dev); 227db0f04f3SLorenzo Bianconi }; 228db0f04f3SLorenzo Bianconi 22917f1de56SFelix Fietkau struct mt76_queue_ops { 230cb8ed33dSLorenzo Bianconi int (*init)(struct mt76_dev *dev, 231cb8ed33dSLorenzo Bianconi int (*poll)(struct napi_struct *napi, int budget)); 23217f1de56SFelix Fietkau 233b1bfbe70SLorenzo Bianconi int (*alloc)(struct mt76_dev *dev, struct mt76_queue *q, 234b1bfbe70SLorenzo Bianconi int idx, int n_desc, int bufsize, 235b1bfbe70SLorenzo Bianconi u32 ring_base); 23617f1de56SFelix Fietkau 23789870594SLorenzo Bianconi int (*tx_queue_skb)(struct mt76_dev *dev, struct mt76_queue *q, 238d08295f5SFelix Fietkau enum mt76_txq_id qid, struct sk_buff *skb, 239d08295f5SFelix Fietkau struct mt76_wcid *wcid, struct ieee80211_sta *sta); 240469d4818SLorenzo Bianconi 241d95093a1SLorenzo Bianconi int (*tx_queue_skb_raw)(struct mt76_dev *dev, struct mt76_queue *q, 2425ed31128SLorenzo Bianconi struct sk_buff *skb, u32 tx_info); 2435ed31128SLorenzo Bianconi 24417f1de56SFelix Fietkau void *(*dequeue)(struct mt76_dev *dev, struct mt76_queue *q, bool flush, 24517f1de56SFelix Fietkau int *len, u32 *info, bool *more); 24617f1de56SFelix Fietkau 24717f1de56SFelix Fietkau void (*rx_reset)(struct mt76_dev *dev, enum mt76_rxq_id qid); 24817f1de56SFelix Fietkau 249e5655492SLorenzo Bianconi void (*tx_cleanup)(struct mt76_dev *dev, struct mt76_queue *q, 25017f1de56SFelix Fietkau bool flush); 25117f1de56SFelix Fietkau 252c001df97SLorenzo Bianconi void (*rx_cleanup)(struct mt76_dev *dev, struct mt76_queue *q); 253c001df97SLorenzo Bianconi 25417f1de56SFelix Fietkau void (*kick)(struct mt76_dev *dev, struct mt76_queue *q); 2553990465dSLorenzo Bianconi 2563990465dSLorenzo Bianconi void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q); 25717f1de56SFelix Fietkau }; 25817f1de56SFelix Fietkau 259dc877523SRyder Lee enum mt76_phy_type { 260dc877523SRyder Lee MT_PHY_TYPE_CCK, 261dc877523SRyder Lee MT_PHY_TYPE_OFDM, 262dc877523SRyder Lee MT_PHY_TYPE_HT, 263dc877523SRyder Lee MT_PHY_TYPE_HT_GF, 264dc877523SRyder Lee MT_PHY_TYPE_VHT, 265dc877523SRyder Lee MT_PHY_TYPE_HE_SU = 8, 266dc877523SRyder Lee MT_PHY_TYPE_HE_EXT_SU, 267dc877523SRyder Lee MT_PHY_TYPE_HE_TB, 268dc877523SRyder Lee MT_PHY_TYPE_HE_MU, 269c2eccffdSShayne Chen MT_PHY_TYPE_EHT_SU = 13, 270c2eccffdSShayne Chen MT_PHY_TYPE_EHT_TRIG, 271c2eccffdSShayne Chen MT_PHY_TYPE_EHT_MU, 272c2eccffdSShayne Chen __MT_PHY_TYPE_MAX, 273dc877523SRyder Lee }; 274dc877523SRyder Lee 275dc877523SRyder Lee struct mt76_sta_stats { 276c2eccffdSShayne Chen u64 tx_mode[__MT_PHY_TYPE_MAX]; 277731425f3SShayne Chen u64 tx_bw[5]; /* 20, 40, 80, 160, 320 */ 278dc877523SRyder Lee u64 tx_nss[4]; /* 1, 2, 3, 4 */ 279dc877523SRyder Lee u64 tx_mcs[16]; /* mcs idx */ 28043eaa368SRyder Lee u64 tx_bytes; 281c6cde7b7SSujuan Chen /* WED TX */ 282161a7528SPeter Chiu u32 tx_packets; /* unit: MSDU */ 28343eaa368SRyder Lee u32 tx_retries; 28443eaa368SRyder Lee u32 tx_failed; 285c6cde7b7SSujuan Chen /* WED RX */ 286c6cde7b7SSujuan Chen u64 rx_bytes; 287c6cde7b7SSujuan Chen u32 rx_packets; 288c6cde7b7SSujuan Chen u32 rx_errors; 289c6cde7b7SSujuan Chen u32 rx_drops; 290dc877523SRyder Lee }; 291dc877523SRyder Lee 292d71ef286SFelix Fietkau enum mt76_wcid_flags { 293d71ef286SFelix Fietkau MT_WCID_FLAG_CHECK_PS, 294d71ef286SFelix Fietkau MT_WCID_FLAG_PS, 295e151d71eSFelix Fietkau MT_WCID_FLAG_4ADDR, 29690e3abf0SFelix Fietkau MT_WCID_FLAG_HDR_TRANS, 297d71ef286SFelix Fietkau }; 298d71ef286SFelix Fietkau 2996b733f7cSShayne Chen #define MT76_N_WCIDS 1088 30036404c06SStanislaw Gruszka 301e394b575SFelix Fietkau /* stored in ieee80211_tx_info::hw_queue */ 302a062f001SLorenzo Bianconi #define MT_TX_HW_QUEUE_PHY GENMASK(3, 2) 303e394b575SFelix Fietkau 304ef13edc0SFelix Fietkau DECLARE_EWMA(signal, 10, 8); 305ef13edc0SFelix Fietkau 306db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_RATE GENMASK(15, 0) 307db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_NSS GENMASK(17, 16) 308db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_TXPWR_ADJ GENMASK(25, 18) 309db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_SET BIT(31) 310db9f11d3SFelix Fietkau 31117f1de56SFelix Fietkau struct mt76_wcid { 312aee5b8cfSFelix Fietkau struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS]; 313aee5b8cfSFelix Fietkau 314e1378e52SFelix Fietkau atomic_t non_aql_packets; 315d71ef286SFelix Fietkau unsigned long flags; 316d71ef286SFelix Fietkau 317ef13edc0SFelix Fietkau struct ewma_signal rssi; 318ef13edc0SFelix Fietkau int inactive_count; 319ef13edc0SFelix Fietkau 3209908d98aSRyder Lee struct rate_info rate; 321ef591d74SLorenzo Bianconi unsigned long ampdu_state; 3229908d98aSRyder Lee 32349e649c3SRyder Lee u16 idx; 32417f1de56SFelix Fietkau u8 hw_key_idx; 325730d6d0dSFelix Fietkau u8 hw_key_idx2; 32617f1de56SFelix Fietkau 3279c68a57bSFelix Fietkau u8 sta:1; 328b443e55fSRyder Lee u8 amsdu:1; 329a1a99d7bSLorenzo Bianconi u8 phy_idx:2; 3309c68a57bSFelix Fietkau 33130ce7f44SFelix Fietkau u8 rx_check_pn; 332a1b0bbd4SXing Song u8 rx_key_pn[IEEE80211_NUM_TIDS + 1][6]; 33301cfc1b4SLorenzo Bianconi u16 cipher; 33430ce7f44SFelix Fietkau 335db9f11d3SFelix Fietkau u32 tx_info; 33623405236SFelix Fietkau bool sw_iv; 33788046b2cSFelix Fietkau 3380335c034SFelix Fietkau struct list_head tx_list; 3390335c034SFelix Fietkau struct sk_buff_head tx_pending; 3400335c034SFelix Fietkau 341bd1e3e7bSLorenzo Bianconi struct list_head list; 342bd1e3e7bSLorenzo Bianconi struct idr pktid; 343dc877523SRyder Lee 344dc877523SRyder Lee struct mt76_sta_stats stats; 345b73e1d92SLorenzo Bianconi 346b73e1d92SLorenzo Bianconi struct list_head poll_list; 34717f1de56SFelix Fietkau }; 34817f1de56SFelix Fietkau 34917f1de56SFelix Fietkau struct mt76_txq { 35051fb1278SFelix Fietkau u16 wcid; 35117f1de56SFelix Fietkau 35217f1de56SFelix Fietkau u16 agg_ssn; 35317f1de56SFelix Fietkau bool send_bar; 35417f1de56SFelix Fietkau bool aggr; 35517f1de56SFelix Fietkau }; 35617f1de56SFelix Fietkau 35717f1de56SFelix Fietkau struct mt76_txwi_cache { 35817f1de56SFelix Fietkau struct list_head list; 359f3950a41SLorenzo Bianconi dma_addr_t dma_addr; 3606ca66722SLorenzo Bianconi 3612666beceSSujuan Chen union { 3626ca66722SLorenzo Bianconi struct sk_buff *skb; 3632666beceSSujuan Chen void *ptr; 3642666beceSSujuan Chen }; 36517f1de56SFelix Fietkau }; 36617f1de56SFelix Fietkau 367aee5b8cfSFelix Fietkau struct mt76_rx_tid { 368aee5b8cfSFelix Fietkau struct rcu_head rcu_head; 369aee5b8cfSFelix Fietkau 370aee5b8cfSFelix Fietkau struct mt76_dev *dev; 371aee5b8cfSFelix Fietkau 372aee5b8cfSFelix Fietkau spinlock_t lock; 373aee5b8cfSFelix Fietkau struct delayed_work reorder_work; 374aee5b8cfSFelix Fietkau 375aee5b8cfSFelix Fietkau u16 head; 3767c4f744dSRyder Lee u16 size; 3777c4f744dSRyder Lee u16 nframes; 378aee5b8cfSFelix Fietkau 379e7ec563eSMarkus Theil u8 num; 380e7ec563eSMarkus Theil 381aee5b8cfSFelix Fietkau u8 started:1, stopped:1, timer_pending:1; 382aee5b8cfSFelix Fietkau 383bd94d501SKees Cook struct sk_buff *reorder_buf[] __counted_by(size); 384aee5b8cfSFelix Fietkau }; 385aee5b8cfSFelix Fietkau 38688046b2cSFelix Fietkau #define MT_TX_CB_DMA_DONE BIT(0) 38788046b2cSFelix Fietkau #define MT_TX_CB_TXS_DONE BIT(1) 38888046b2cSFelix Fietkau #define MT_TX_CB_TXS_FAILED BIT(2) 38988046b2cSFelix Fietkau 3908548c6ebSFelix Fietkau #define MT_PACKET_ID_MASK GENMASK(6, 0) 391013b2dffSFelix Fietkau #define MT_PACKET_ID_NO_ACK 0 392013b2dffSFelix Fietkau #define MT_PACKET_ID_NO_SKB 1 39343eaa368SRyder Lee #define MT_PACKET_ID_WED 2 39443eaa368SRyder Lee #define MT_PACKET_ID_FIRST 3 3958548c6ebSFelix Fietkau #define MT_PACKET_ID_HAS_RATE BIT(7) 396c4a784e3SLorenzo Bianconi /* This is timer for when to give up when waiting for TXS callback, 397c4a784e3SLorenzo Bianconi * with starting time being the time at which the DMA_DONE callback 398c4a784e3SLorenzo Bianconi * was seen (so, we know packet was processed then, it should not take 399c4a784e3SLorenzo Bianconi * long after that for firmware to send the TXS callback if it is going 400c4a784e3SLorenzo Bianconi * to do so.) 401c4a784e3SLorenzo Bianconi */ 402c4a784e3SLorenzo Bianconi #define MT_TX_STATUS_SKB_TIMEOUT (HZ / 4) 40388046b2cSFelix Fietkau 40488046b2cSFelix Fietkau struct mt76_tx_cb { 40588046b2cSFelix Fietkau unsigned long jiffies; 40649e649c3SRyder Lee u16 wcid; 40788046b2cSFelix Fietkau u8 pktid; 40888046b2cSFelix Fietkau u8 flags; 40988046b2cSFelix Fietkau }; 41088046b2cSFelix Fietkau 41117f1de56SFelix Fietkau enum { 41217f1de56SFelix Fietkau MT76_STATE_INITIALIZED, 41341130c32SLorenzo Bianconi MT76_STATE_REGISTERED, 41417f1de56SFelix Fietkau MT76_STATE_RUNNING, 41587e022deSStanislaw Gruszka MT76_STATE_MCU_RUNNING, 41617f1de56SFelix Fietkau MT76_SCANNING, 417fcdfc29eSLorenzo Bianconi MT76_HW_SCANNING, 41820305f98SLorenzo Bianconi MT76_HW_SCHED_SCANNING, 419fd6c2dfaSFelix Fietkau MT76_RESTART, 42017f1de56SFelix Fietkau MT76_RESET, 42161c4fa72SFelix Fietkau MT76_MCU_RESET, 422b40b15e1SLorenzo Bianconi MT76_REMOVED, 423b40b15e1SLorenzo Bianconi MT76_READING_STATS, 424eb99cc95SLorenzo Bianconi MT76_STATE_POWER_OFF, 425c6bf2010SLorenzo Bianconi MT76_STATE_SUSPEND, 4267307f296SLorenzo Bianconi MT76_STATE_ROC, 42708523a2aSLorenzo Bianconi MT76_STATE_PM, 42836b7fce1SLorenzo Bianconi MT76_STATE_WED_RESET, 42917f1de56SFelix Fietkau }; 43017f1de56SFelix Fietkau 43117f1de56SFelix Fietkau struct mt76_hw_cap { 43217f1de56SFelix Fietkau bool has_2ghz; 43317f1de56SFelix Fietkau bool has_5ghz; 434f7d2958cSLorenzo Bianconi bool has_6ghz; 43517f1de56SFelix Fietkau }; 43617f1de56SFelix Fietkau 4379ec0b821SFelix Fietkau #define MT_DRV_TXWI_NO_FREE BIT(0) 4389ec0b821SFelix Fietkau #define MT_DRV_TX_ALIGNED4_SKBS BIT(1) 4395ce09c1aSFelix Fietkau #define MT_DRV_SW_RX_AIRTIME BIT(2) 44094d4d076SLorenzo Bianconi #define MT_DRV_RX_DMA_HDR BIT(3) 441d3c82998SLorenzo Bianconi #define MT_DRV_HW_MGMT_TXQ BIT(4) 4425b0fb852SBen Greear #define MT_DRV_AMSDU_OFFLOAD BIT(5) 4436ca66722SLorenzo Bianconi 44417f1de56SFelix Fietkau struct mt76_driver_ops { 4459ec0b821SFelix Fietkau u32 drv_flags; 446ea565833SFelix Fietkau u32 survey_flags; 44717f1de56SFelix Fietkau u16 txwi_size; 448d089692bSLorenzo Bianconi u16 token_size; 44922b980baSFelix Fietkau u8 mcs_rates; 45017f1de56SFelix Fietkau 451c560b137SRyder Lee void (*update_survey)(struct mt76_phy *phy); 45217f1de56SFelix Fietkau 45317f1de56SFelix Fietkau int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr, 454cfaae9e6SLorenzo Bianconi enum mt76_txq_id qid, struct mt76_wcid *wcid, 455b5903c47SLorenzo Bianconi struct ieee80211_sta *sta, 456b5903c47SLorenzo Bianconi struct mt76_tx_info *tx_info); 45717f1de56SFelix Fietkau 458d80e52c7SFelix Fietkau void (*tx_complete_skb)(struct mt76_dev *dev, 459e226ba2eSLorenzo Bianconi struct mt76_queue_entry *e); 46017f1de56SFelix Fietkau 461b40b15e1SLorenzo Bianconi bool (*tx_status_data)(struct mt76_dev *dev, u8 *update); 462b40b15e1SLorenzo Bianconi 463fbe50d9aSFelix Fietkau bool (*rx_check)(struct mt76_dev *dev, void *data, int len); 464fbe50d9aSFelix Fietkau 46517f1de56SFelix Fietkau void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q, 466c3137942SSujuan Chen struct sk_buff *skb, u32 *info); 46717f1de56SFelix Fietkau 46817f1de56SFelix Fietkau void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q); 469d71ef286SFelix Fietkau 470d71ef286SFelix Fietkau void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta, 471d71ef286SFelix Fietkau bool ps); 472e28487eaSFelix Fietkau 473e28487eaSFelix Fietkau int (*sta_add)(struct mt76_dev *dev, struct ieee80211_vif *vif, 474e28487eaSFelix Fietkau struct ieee80211_sta *sta); 475e28487eaSFelix Fietkau 4769c193de5SFelix Fietkau void (*sta_assoc)(struct mt76_dev *dev, struct ieee80211_vif *vif, 4779c193de5SFelix Fietkau struct ieee80211_sta *sta); 4789c193de5SFelix Fietkau 479e28487eaSFelix Fietkau void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif, 480e28487eaSFelix Fietkau struct ieee80211_sta *sta); 48117f1de56SFelix Fietkau }; 48217f1de56SFelix Fietkau 48317f1de56SFelix Fietkau struct mt76_channel_state { 48417f1de56SFelix Fietkau u64 cc_active; 48517f1de56SFelix Fietkau u64 cc_busy; 4866bfa6e38SLorenzo Bianconi u64 cc_rx; 4875ce09c1aSFelix Fietkau u64 cc_bss_rx; 488ea565833SFelix Fietkau u64 cc_tx; 489e5051965SFelix Fietkau 490e5051965SFelix Fietkau s8 noise; 49117f1de56SFelix Fietkau }; 49217f1de56SFelix Fietkau 49317f1de56SFelix Fietkau struct mt76_sband { 49417f1de56SFelix Fietkau struct ieee80211_supported_band sband; 49517f1de56SFelix Fietkau struct mt76_channel_state *chan; 49617f1de56SFelix Fietkau }; 49717f1de56SFelix Fietkau 498b40b15e1SLorenzo Bianconi /* addr req mask */ 499b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_EEPROM BIT(31) 500b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_CFG BIT(30) 501b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_MASK (MT_VEND_TYPE_EEPROM | MT_VEND_TYPE_CFG) 502b40b15e1SLorenzo Bianconi 503b40b15e1SLorenzo Bianconi #define MT_VEND_ADDR(type, n) (MT_VEND_TYPE_##type | (n)) 504b40b15e1SLorenzo Bianconi enum mt_vendor_req { 505b40b15e1SLorenzo Bianconi MT_VEND_DEV_MODE = 0x1, 506b40b15e1SLorenzo Bianconi MT_VEND_WRITE = 0x2, 5071e816c65SLorenzo Bianconi MT_VEND_POWER_ON = 0x4, 508b40b15e1SLorenzo Bianconi MT_VEND_MULTI_WRITE = 0x6, 509b40b15e1SLorenzo Bianconi MT_VEND_MULTI_READ = 0x7, 510b40b15e1SLorenzo Bianconi MT_VEND_READ_EEPROM = 0x9, 511b40b15e1SLorenzo Bianconi MT_VEND_WRITE_FCE = 0x42, 512b40b15e1SLorenzo Bianconi MT_VEND_WRITE_CFG = 0x46, 513b40b15e1SLorenzo Bianconi MT_VEND_READ_CFG = 0x47, 5141e816c65SLorenzo Bianconi MT_VEND_READ_EXT = 0x63, 5151e816c65SLorenzo Bianconi MT_VEND_WRITE_EXT = 0x66, 516d0846f08SSean Wang MT_VEND_FEATURE_SET = 0x91, 517b40b15e1SLorenzo Bianconi }; 518b40b15e1SLorenzo Bianconi 519b40b15e1SLorenzo Bianconi enum mt76u_in_ep { 520b40b15e1SLorenzo Bianconi MT_EP_IN_PKT_RX, 521b40b15e1SLorenzo Bianconi MT_EP_IN_CMD_RESP, 522b40b15e1SLorenzo Bianconi __MT_EP_IN_MAX, 523b40b15e1SLorenzo Bianconi }; 524b40b15e1SLorenzo Bianconi 525b40b15e1SLorenzo Bianconi enum mt76u_out_ep { 526b40b15e1SLorenzo Bianconi MT_EP_OUT_INBAND_CMD, 527b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_BE, 52823cb16d2SLorenzo Bianconi MT_EP_OUT_AC_BK, 529b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_VI, 530b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_VO, 531b40b15e1SLorenzo Bianconi MT_EP_OUT_HCCA, 532b40b15e1SLorenzo Bianconi __MT_EP_OUT_MAX, 533b40b15e1SLorenzo Bianconi }; 534b40b15e1SLorenzo Bianconi 53509872957SLorenzo Bianconi struct mt76_mcu { 53609872957SLorenzo Bianconi struct mutex mutex; 53709872957SLorenzo Bianconi u32 msg_seq; 538e452c6ebSFelix Fietkau int timeout; 53909872957SLorenzo Bianconi 54009872957SLorenzo Bianconi struct sk_buff_head res_q; 54109872957SLorenzo Bianconi wait_queue_head_t wait; 54209872957SLorenzo Bianconi }; 54309872957SLorenzo Bianconi 54414663f0cSLorenzo Bianconi #define MT_TX_SG_MAX_SIZE 8 545972c5981SSean Wang #define MT_RX_SG_MAX_SIZE 4 546b40b15e1SLorenzo Bianconi #define MT_NUM_TX_ENTRIES 256 547b40b15e1SLorenzo Bianconi #define MT_NUM_RX_ENTRIES 128 548b40b15e1SLorenzo Bianconi #define MCU_RESP_URB_SIZE 1024 549b40b15e1SLorenzo Bianconi struct mt76_usb { 550b40b15e1SLorenzo Bianconi struct mutex usb_ctrl_mtx; 551a6bfb6d1SStanislaw Gruszka u8 *data; 552a6bfb6d1SStanislaw Gruszka u16 data_len; 553b40b15e1SLorenzo Bianconi 5549daf27e6SLorenzo Bianconi struct mt76_worker status_worker; 555be83a7e2SLorenzo Bianconi struct mt76_worker rx_worker; 5569daf27e6SLorenzo Bianconi 557284efb47SLorenzo Bianconi struct work_struct stat_work; 558b40b15e1SLorenzo Bianconi 559b40b15e1SLorenzo Bianconi u8 out_ep[__MT_EP_OUT_MAX]; 560b40b15e1SLorenzo Bianconi u8 in_ep[__MT_EP_IN_MAX]; 56163a7de5dSLorenzo Bianconi bool sg_en; 562b40b15e1SLorenzo Bianconi 563b40b15e1SLorenzo Bianconi struct mt76u_mcu { 564a18a494fSStanislaw Gruszka u8 *data; 565851ab66eSLorenzo Bianconi /* multiple reads */ 566851ab66eSLorenzo Bianconi struct mt76_reg_pair *rp; 567851ab66eSLorenzo Bianconi int rp_len; 568851ab66eSLorenzo Bianconi u32 base; 569b40b15e1SLorenzo Bianconi } mcu; 570b40b15e1SLorenzo Bianconi }; 571b40b15e1SLorenzo Bianconi 572bf08d585SSean Wang #define MT76S_XMIT_BUF_SZ 0x3fe00 573b1460bb4SDeren Wu #define MT76S_NUM_TX_ENTRIES 256 574b1460bb4SDeren Wu #define MT76S_NUM_RX_ENTRIES 512 575d39b52e3SSean Wang struct mt76_sdio { 576fefb584dSLorenzo Bianconi struct mt76_worker txrx_worker; 5776a618acbSLorenzo Bianconi struct mt76_worker status_worker; 5786a618acbSLorenzo Bianconi struct mt76_worker net_worker; 5796a618acbSLorenzo Bianconi 580d74fda4cSLorenzo Bianconi struct work_struct stat_work; 581974327a4SLorenzo Bianconi 582bf08d585SSean Wang u8 *xmit_buf; 583bf08d585SSean Wang u32 xmit_buf_sz; 5841522ff73SLorenzo Bianconi 585d39b52e3SSean Wang struct sdio_func *func; 586b4964908SSean Wang void *intr_data; 587dacf0acfSSean Wang u8 hw_ver; 588ca74b9b9SSean Wang wait_queue_head_t wait; 589d39b52e3SSean Wang 590d39b52e3SSean Wang struct { 591d39b52e3SSean Wang int pse_data_quota; 592d39b52e3SSean Wang int ple_data_quota; 593d39b52e3SSean Wang int pse_mcu_quota; 5948c94f0e6SSean Wang int pse_page_size; 595d39b52e3SSean Wang int deficit; 596d39b52e3SSean Wang } sched; 5973ad08509SLorenzo Bianconi 5983ad08509SLorenzo Bianconi int (*parse_irq)(struct mt76_dev *dev, struct mt76s_intr *intr); 599d39b52e3SSean Wang }; 600d39b52e3SSean Wang 601f7bbb80fSLorenzo Bianconi struct mt76_mmio { 60227db1ad1SLorenzo Bianconi void __iomem *regs; 603957068c2SLorenzo Bianconi spinlock_t irq_lock; 604957068c2SLorenzo Bianconi u32 irqmask; 605f68d6762SFelix Fietkau 606f68d6762SFelix Fietkau struct mtk_wed_device wed; 60736b7fce1SLorenzo Bianconi struct completion wed_reset; 60836b7fce1SLorenzo Bianconi struct completion wed_reset_complete; 609f7bbb80fSLorenzo Bianconi }; 610f7bbb80fSLorenzo Bianconi 6115ce09c1aSFelix Fietkau struct mt76_rx_status { 6125ce09c1aSFelix Fietkau union { 6135ce09c1aSFelix Fietkau struct mt76_wcid *wcid; 61449e649c3SRyder Lee u16 wcid_idx; 6155ce09c1aSFelix Fietkau }; 6165ce09c1aSFelix Fietkau 6170fda6d7bSRyder Lee u32 reorder_time; 6185ce09c1aSFelix Fietkau 6195ce09c1aSFelix Fietkau u32 ampdu_ref; 6200fda6d7bSRyder Lee u32 timestamp; 6215ce09c1aSFelix Fietkau 6225ce09c1aSFelix Fietkau u8 iv[6]; 6235ce09c1aSFelix Fietkau 624128c9b7dSLorenzo Bianconi u8 phy_idx:2; 6255ce09c1aSFelix Fietkau u8 aggr:1; 626e195dad1SFelix Fietkau u8 qos_ctl; 6275ce09c1aSFelix Fietkau u16 seqno; 6285ce09c1aSFelix Fietkau 6295ce09c1aSFelix Fietkau u16 freq; 6305ce09c1aSFelix Fietkau u32 flag; 6315ce09c1aSFelix Fietkau u8 enc_flags; 632021af945SShayne Chen u8 encoding:3, bw:4; 633021af945SShayne Chen union { 634021af945SShayne Chen struct { 635021af945SShayne Chen u8 he_ru:3; 636021af945SShayne Chen u8 he_gi:2; 637021af945SShayne Chen u8 he_dcm:1; 638021af945SShayne Chen }; 639021af945SShayne Chen struct { 640021af945SShayne Chen u8 ru:4; 641021af945SShayne Chen u8 gi:2; 642021af945SShayne Chen } eht; 643021af945SShayne Chen }; 644021af945SShayne Chen 645cc4b3c13SLorenzo Bianconi u8 amsdu:1, first_amsdu:1, last_amsdu:1; 6465ce09c1aSFelix Fietkau u8 rate_idx; 647021af945SShayne Chen u8 nss:5, band:3; 6485ce09c1aSFelix Fietkau s8 signal; 6495ce09c1aSFelix Fietkau u8 chains; 6505ce09c1aSFelix Fietkau s8 chain_signal[IEEE80211_MAX_CHAINS]; 6515ce09c1aSFelix Fietkau }; 6525ce09c1aSFelix Fietkau 653502604f5SYN Chen struct mt76_freq_range_power { 654502604f5SYN Chen const struct cfg80211_sar_freq_ranges *range; 655502604f5SYN Chen s8 power; 656502604f5SYN Chen }; 657502604f5SYN Chen 658f0efa862SFelix Fietkau struct mt76_testmode_ops { 659c918c74dSShayne Chen int (*set_state)(struct mt76_phy *phy, enum mt76_testmode_state state); 660c918c74dSShayne Chen int (*set_params)(struct mt76_phy *phy, struct nlattr **tb, 661f0efa862SFelix Fietkau enum mt76_testmode_state new_state); 662c918c74dSShayne Chen int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg); 663f0efa862SFelix Fietkau }; 664f0efa862SFelix Fietkau 665f0efa862SFelix Fietkau struct mt76_testmode_data { 666f0efa862SFelix Fietkau enum mt76_testmode_state state; 667f0efa862SFelix Fietkau 668f0efa862SFelix Fietkau u32 param_set[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)]; 669f0efa862SFelix Fietkau struct sk_buff *tx_skb; 670f0efa862SFelix Fietkau 671f0efa862SFelix Fietkau u32 tx_count; 6722601dda8SShayne Chen u16 tx_mpdu_len; 673f0efa862SFelix Fietkau 674f0efa862SFelix Fietkau u8 tx_rate_mode; 675f0efa862SFelix Fietkau u8 tx_rate_idx; 676f0efa862SFelix Fietkau u8 tx_rate_nss; 677f0efa862SFelix Fietkau u8 tx_rate_sgi; 678f0efa862SFelix Fietkau u8 tx_rate_ldpc; 6797f54c742SShayne Chen u8 tx_rate_stbc; 6801a38c2f5SShayne Chen u8 tx_ltf; 681f0efa862SFelix Fietkau 682f0efa862SFelix Fietkau u8 tx_antenna_mask; 683fdc9c18eSShayne Chen u8 tx_spe_idx; 684f0efa862SFelix Fietkau 685b8cbdb97SShayne Chen u8 tx_duty_cycle; 686b8cbdb97SShayne Chen u32 tx_time; 687b8cbdb97SShayne Chen u32 tx_ipg; 688b8cbdb97SShayne Chen 689f0efa862SFelix Fietkau u32 freq_offset; 690f0efa862SFelix Fietkau 691f0efa862SFelix Fietkau u8 tx_power[4]; 692f0efa862SFelix Fietkau u8 tx_power_control; 693f0efa862SFelix Fietkau 694c40b42c2SShayne Chen u8 addr[3][ETH_ALEN]; 695c40b42c2SShayne Chen 696f0efa862SFelix Fietkau u32 tx_pending; 697f0efa862SFelix Fietkau u32 tx_queued; 698ba459094SShayne Chen u16 tx_queued_limit; 699f0efa862SFelix Fietkau u32 tx_done; 700f0efa862SFelix Fietkau struct { 701f0efa862SFelix Fietkau u64 packets[__MT_RXQ_MAX]; 702f0efa862SFelix Fietkau u64 fcs_error[__MT_RXQ_MAX]; 703f0efa862SFelix Fietkau } rx_stats; 704f0efa862SFelix Fietkau }; 705f0efa862SFelix Fietkau 70685d96704SLorenzo Bianconi struct mt76_vif { 70785d96704SLorenzo Bianconi u8 idx; 70885d96704SLorenzo Bianconi u8 omac_idx; 70985d96704SLorenzo Bianconi u8 band_idx; 71085d96704SLorenzo Bianconi u8 wmm_idx; 71185d96704SLorenzo Bianconi u8 scan_seq_num; 7125ea3d983SFelix Fietkau u8 cipher; 7130cb065b9SLorenzo Bianconi u8 basic_rates_idx; 7140cb065b9SLorenzo Bianconi u8 mcast_rates_idx; 7150cb065b9SLorenzo Bianconi u8 beacon_rates_idx; 716f5020655SSean Wang struct ieee80211_chanctx_conf *ctx; 71785d96704SLorenzo Bianconi }; 71885d96704SLorenzo Bianconi 719ac24dd35SFelix Fietkau struct mt76_phy { 720ac24dd35SFelix Fietkau struct ieee80211_hw *hw; 721ac24dd35SFelix Fietkau struct mt76_dev *dev; 722a3d01038SFelix Fietkau void *priv; 72396747a51SFelix Fietkau 724011849e0SFelix Fietkau unsigned long state; 725dc44c45cSLorenzo Bianconi u8 band_idx; 726011849e0SFelix Fietkau 7270335c034SFelix Fietkau spinlock_t tx_lock; 7280335c034SFelix Fietkau struct list_head tx_list; 72991990519SLorenzo Bianconi struct mt76_queue *q_tx[__MT_TXQ_MAX]; 73091990519SLorenzo Bianconi 73196747a51SFelix Fietkau struct cfg80211_chan_def chandef; 73296747a51SFelix Fietkau struct ieee80211_channel *main_chan; 73396747a51SFelix Fietkau 73496747a51SFelix Fietkau struct mt76_channel_state *chan_state; 7353f306448SFelix Fietkau enum mt76_dfs_state dfs_state; 73696747a51SFelix Fietkau ktime_t survey_time; 73796747a51SFelix Fietkau 738d107501aSLorenzo Bianconi u32 aggr_stats[32]; 739d107501aSLorenzo Bianconi 74048dbce5cSLorenzo Bianconi struct mt76_hw_cap cap; 74196747a51SFelix Fietkau struct mt76_sband sband_2g; 74296747a51SFelix Fietkau struct mt76_sband sband_5g; 743cee3fd29SLorenzo Bianconi struct mt76_sband sband_6g; 744beaaeb6bSFelix Fietkau 74598df2baeSLorenzo Bianconi u8 macaddr[ETH_ALEN]; 74698df2baeSLorenzo Bianconi 747beaaeb6bSFelix Fietkau int txpower_cur; 748beaaeb6bSFelix Fietkau u8 antenna_mask; 749b9027e08SLorenzo Bianconi u16 chainmask; 750c918c74dSShayne Chen 751c918c74dSShayne Chen #ifdef CONFIG_NL80211_TESTMODE 752c918c74dSShayne Chen struct mt76_testmode_data test; 753c918c74dSShayne Chen #endif 754a782f8bfSLorenzo Bianconi 755a782f8bfSLorenzo Bianconi struct delayed_work mac_work; 756a782f8bfSLorenzo Bianconi u8 mac_work_count; 757cc4b3c13SLorenzo Bianconi 758cc4b3c13SLorenzo Bianconi struct { 759cc4b3c13SLorenzo Bianconi struct sk_buff *head; 760cc4b3c13SLorenzo Bianconi struct sk_buff **tail; 761cc4b3c13SLorenzo Bianconi u16 seqno; 762cc4b3c13SLorenzo Bianconi } rx_amsdu[__MT_RXQ_MAX]; 763502604f5SYN Chen 764502604f5SYN Chen struct mt76_freq_range_power *frp; 7653abd46ddSLorenzo Bianconi 7663abd46ddSLorenzo Bianconi struct { 7673abd46ddSLorenzo Bianconi struct led_classdev cdev; 7683abd46ddSLorenzo Bianconi char name[32]; 7693abd46ddSLorenzo Bianconi bool al; 7703abd46ddSLorenzo Bianconi u8 pin; 7713abd46ddSLorenzo Bianconi } leds; 772ac24dd35SFelix Fietkau }; 773ac24dd35SFelix Fietkau 77417f1de56SFelix Fietkau struct mt76_dev { 775ac24dd35SFelix Fietkau struct mt76_phy phy; /* must be first */ 776dc44c45cSLorenzo Bianconi struct mt76_phy *phys[__MT_MAX_BAND]; 777bfc394ddSFelix Fietkau 77817f1de56SFelix Fietkau struct ieee80211_hw *hw; 77917f1de56SFelix Fietkau 7802666beceSSujuan Chen spinlock_t wed_lock; 78117f1de56SFelix Fietkau spinlock_t lock; 78217f1de56SFelix Fietkau spinlock_t cc_lock; 783108a4861SStanislaw Gruszka 7845ce09c1aSFelix Fietkau u32 cur_cc_bss_rx; 7855ce09c1aSFelix Fietkau 7865ce09c1aSFelix Fietkau struct mt76_rx_status rx_ampdu_status; 7875ce09c1aSFelix Fietkau u32 rx_ampdu_len; 7885ce09c1aSFelix Fietkau u32 rx_ampdu_ref; 7895ce09c1aSFelix Fietkau 790108a4861SStanislaw Gruszka struct mutex mutex; 791108a4861SStanislaw Gruszka 79217f1de56SFelix Fietkau const struct mt76_bus_ops *bus; 79317f1de56SFelix Fietkau const struct mt76_driver_ops *drv; 794db0f04f3SLorenzo Bianconi const struct mt76_mcu_ops *mcu_ops; 79517f1de56SFelix Fietkau struct device *dev; 796d1ddc536SFelix Fietkau struct device *dma_dev; 79717f1de56SFelix Fietkau 79809872957SLorenzo Bianconi struct mt76_mcu mcu; 79909872957SLorenzo Bianconi 80017f1de56SFelix Fietkau struct net_device napi_dev; 801aa40528aSFelix Fietkau struct net_device tx_napi_dev; 802c3d7c82aSFelix Fietkau spinlock_t rx_lock; 80317f1de56SFelix Fietkau struct napi_struct napi[__MT_RXQ_MAX]; 80417f1de56SFelix Fietkau struct sk_buff_head rx_skb[__MT_RXQ_MAX]; 805ec193b41SLorenzo Bianconi struct tasklet_struct irq_tasklet; 80617f1de56SFelix Fietkau 80717f1de56SFelix Fietkau struct list_head txwi_cache; 8082666beceSSujuan Chen struct list_head rxwi_cache; 809b1cb42adSLorenzo Bianconi struct mt76_queue *q_mcu[__MT_MCUQ_MAX]; 81017f1de56SFelix Fietkau struct mt76_queue q_rx[__MT_RXQ_MAX]; 81117f1de56SFelix Fietkau const struct mt76_queue_ops *queue_ops; 812c1e0d2beSLorenzo Bianconi int tx_dma_idx[4]; 81317f1de56SFelix Fietkau 814781eef5bSFelix Fietkau struct mt76_worker tx_worker; 8158402650aSLorenzo Bianconi struct napi_struct tx_napi; 816a33b8ab8SFelix Fietkau 817b17aff33SLorenzo Bianconi spinlock_t token_lock; 818b17aff33SLorenzo Bianconi struct idr token; 819f68d6762SFelix Fietkau u16 wed_token_count; 82061b5156bSFelix Fietkau u16 token_count; 82161b5156bSFelix Fietkau u16 token_size; 822b17aff33SLorenzo Bianconi 8232666beceSSujuan Chen spinlock_t rx_token_lock; 8242666beceSSujuan Chen struct idr rx_token; 8252666beceSSujuan Chen u16 rx_token_size; 8262666beceSSujuan Chen 82726e40d4cSFelix Fietkau wait_queue_head_t tx_wait; 828c34f1005SLorenzo Bianconi /* spinclock used to protect wcid pktid linked list */ 829c34f1005SLorenzo Bianconi spinlock_t status_lock; 83026e40d4cSFelix Fietkau 8315e616ad2SFelix Fietkau u32 wcid_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; 8325e616ad2SFelix Fietkau u32 wcid_phy_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; 83336404c06SStanislaw Gruszka 834b619e013SEvelyn Tsai u64 vif_mask; 8352ab33b8dSFelix Fietkau 83636404c06SStanislaw Gruszka struct mt76_wcid global_wcid; 83736404c06SStanislaw Gruszka struct mt76_wcid __rcu *wcid[MT76_N_WCIDS]; 838bd1e3e7bSLorenzo Bianconi struct list_head wcid_list; 83936404c06SStanislaw Gruszka 840fbba711cSLorenzo Bianconi struct list_head sta_poll_list; 841fbba711cSLorenzo Bianconi spinlock_t sta_poll_lock; 842fbba711cSLorenzo Bianconi 84317f1de56SFelix Fietkau u32 rev; 84417f1de56SFelix Fietkau 845dc6057f4SLorenzo Bianconi struct tasklet_struct pre_tbtt_tasklet; 8463041c445SLorenzo Bianconi int beacon_int; 847c8a04d98SLorenzo Bianconi u8 beacon_mask; 8483041c445SLorenzo Bianconi 84917f1de56SFelix Fietkau struct debugfs_blob_wrapper eeprom; 85017f1de56SFelix Fietkau struct debugfs_blob_wrapper otp; 85117f1de56SFelix Fietkau 8525b257371SLorenzo Bianconi char alpha2[3]; 853d8b8890dSLorenzo Bianconi enum nl80211_dfs_regions region; 854d8b8890dSLorenzo Bianconi 85517f1de56SFelix Fietkau u32 debugfs_reg; 85617f1de56SFelix Fietkau 857e7173858SFelix Fietkau u8 csa_complete; 858e7173858SFelix Fietkau 859108a4861SStanislaw Gruszka u32 rxfilter; 860108a4861SStanislaw Gruszka 861f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 862f0efa862SFelix Fietkau const struct mt76_testmode_ops *test_ops; 863e7a6a044SShayne Chen struct { 864e7a6a044SShayne Chen const char *name; 865e7a6a044SShayne Chen u32 offset; 866e7a6a044SShayne Chen } test_mtd; 867f0efa862SFelix Fietkau #endif 868a86f1d01SLorenzo Bianconi struct workqueue_struct *wq; 869a86f1d01SLorenzo Bianconi 870f7bbb80fSLorenzo Bianconi union { 871f7bbb80fSLorenzo Bianconi struct mt76_mmio mmio; 872b40b15e1SLorenzo Bianconi struct mt76_usb usb; 873d39b52e3SSean Wang struct mt76_sdio sdio; 87417f1de56SFelix Fietkau }; 875f7bbb80fSLorenzo Bianconi }; 87617f1de56SFelix Fietkau 8777f03a563SLorenzo Bianconi /* per-phy stats. */ 8787f03a563SLorenzo Bianconi struct mt76_mib_stats { 8797f03a563SLorenzo Bianconi u32 ack_fail_cnt; 8807f03a563SLorenzo Bianconi u32 fcs_err_cnt; 8817f03a563SLorenzo Bianconi u32 rts_cnt; 8827f03a563SLorenzo Bianconi u32 rts_retries_cnt; 8837f03a563SLorenzo Bianconi u32 ba_miss_cnt; 8847f03a563SLorenzo Bianconi u32 tx_bf_cnt; 8857f03a563SLorenzo Bianconi u32 tx_mu_bf_cnt; 8867f03a563SLorenzo Bianconi u32 tx_mu_mpdu_cnt; 8877f03a563SLorenzo Bianconi u32 tx_mu_acked_mpdu_cnt; 8887f03a563SLorenzo Bianconi u32 tx_su_acked_mpdu_cnt; 8897f03a563SLorenzo Bianconi u32 tx_bf_ibf_ppdu_cnt; 8907f03a563SLorenzo Bianconi u32 tx_bf_ebf_ppdu_cnt; 8917f03a563SLorenzo Bianconi 8927f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_all_cnt; 8937f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_eht_cnt; 8947f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_he_cnt; 8957f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_vht_cnt; 8967f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_ht_cnt; 8977f03a563SLorenzo Bianconi 8987f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */ 8997f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_nc_cnt; 9007f03a563SLorenzo Bianconi u32 tx_bf_rx_fb_nr_cnt; 9017f03a563SLorenzo Bianconi u32 tx_bf_fb_cpl_cnt; 9027f03a563SLorenzo Bianconi u32 tx_bf_fb_trig_cnt; 9037f03a563SLorenzo Bianconi 9047f03a563SLorenzo Bianconi u32 tx_ampdu_cnt; 9057f03a563SLorenzo Bianconi u32 tx_stop_q_empty_cnt; 9067f03a563SLorenzo Bianconi u32 tx_mpdu_attempts_cnt; 9077f03a563SLorenzo Bianconi u32 tx_mpdu_success_cnt; 9087f03a563SLorenzo Bianconi u32 tx_pkt_ebf_cnt; 9097f03a563SLorenzo Bianconi u32 tx_pkt_ibf_cnt; 9107f03a563SLorenzo Bianconi 9117f03a563SLorenzo Bianconi u32 tx_rwp_fail_cnt; 9127f03a563SLorenzo Bianconi u32 tx_rwp_need_cnt; 9137f03a563SLorenzo Bianconi 9147f03a563SLorenzo Bianconi /* rx stats */ 9157f03a563SLorenzo Bianconi u32 rx_fifo_full_cnt; 9167f03a563SLorenzo Bianconi u32 channel_idle_cnt; 9177f03a563SLorenzo Bianconi u32 primary_cca_busy_time; 9187f03a563SLorenzo Bianconi u32 secondary_cca_busy_time; 9197f03a563SLorenzo Bianconi u32 primary_energy_detect_time; 9207f03a563SLorenzo Bianconi u32 cck_mdrdy_time; 9217f03a563SLorenzo Bianconi u32 ofdm_mdrdy_time; 9227f03a563SLorenzo Bianconi u32 green_mdrdy_time; 9237f03a563SLorenzo Bianconi u32 rx_vector_mismatch_cnt; 9247f03a563SLorenzo Bianconi u32 rx_delimiter_fail_cnt; 9257f03a563SLorenzo Bianconi u32 rx_mrdy_cnt; 9267f03a563SLorenzo Bianconi u32 rx_len_mismatch_cnt; 9277f03a563SLorenzo Bianconi u32 rx_mpdu_cnt; 9287f03a563SLorenzo Bianconi u32 rx_ampdu_cnt; 9297f03a563SLorenzo Bianconi u32 rx_ampdu_bytes_cnt; 9307f03a563SLorenzo Bianconi u32 rx_ampdu_valid_subframe_cnt; 9317f03a563SLorenzo Bianconi u32 rx_ampdu_valid_subframe_bytes_cnt; 9327f03a563SLorenzo Bianconi u32 rx_pfdrop_cnt; 9337f03a563SLorenzo Bianconi u32 rx_vec_queue_overflow_drop_cnt; 9347f03a563SLorenzo Bianconi u32 rx_ba_cnt; 9357f03a563SLorenzo Bianconi 9367f03a563SLorenzo Bianconi u32 tx_amsdu[8]; 9377f03a563SLorenzo Bianconi u32 tx_amsdu_cnt; 9381258c156SRyder Lee 9391258c156SRyder Lee /* mcu_muru_stats */ 9401258c156SRyder Lee u32 dl_cck_cnt; 9411258c156SRyder Lee u32 dl_ofdm_cnt; 9421258c156SRyder Lee u32 dl_htmix_cnt; 9431258c156SRyder Lee u32 dl_htgf_cnt; 9441258c156SRyder Lee u32 dl_vht_su_cnt; 9451258c156SRyder Lee u32 dl_vht_2mu_cnt; 9461258c156SRyder Lee u32 dl_vht_3mu_cnt; 9471258c156SRyder Lee u32 dl_vht_4mu_cnt; 9481258c156SRyder Lee u32 dl_he_su_cnt; 9491258c156SRyder Lee u32 dl_he_ext_su_cnt; 9501258c156SRyder Lee u32 dl_he_2ru_cnt; 9511258c156SRyder Lee u32 dl_he_2mu_cnt; 9521258c156SRyder Lee u32 dl_he_3ru_cnt; 9531258c156SRyder Lee u32 dl_he_3mu_cnt; 9541258c156SRyder Lee u32 dl_he_4ru_cnt; 9551258c156SRyder Lee u32 dl_he_4mu_cnt; 9561258c156SRyder Lee u32 dl_he_5to8ru_cnt; 9571258c156SRyder Lee u32 dl_he_9to16ru_cnt; 9581258c156SRyder Lee u32 dl_he_gtr16ru_cnt; 9591258c156SRyder Lee 9601258c156SRyder Lee u32 ul_hetrig_su_cnt; 9611258c156SRyder Lee u32 ul_hetrig_2ru_cnt; 9621258c156SRyder Lee u32 ul_hetrig_3ru_cnt; 9631258c156SRyder Lee u32 ul_hetrig_4ru_cnt; 9641258c156SRyder Lee u32 ul_hetrig_5to8ru_cnt; 9651258c156SRyder Lee u32 ul_hetrig_9to16ru_cnt; 9661258c156SRyder Lee u32 ul_hetrig_gtr16ru_cnt; 9671258c156SRyder Lee u32 ul_hetrig_2mu_cnt; 9681258c156SRyder Lee u32 ul_hetrig_3mu_cnt; 9691258c156SRyder Lee u32 ul_hetrig_4mu_cnt; 9707f03a563SLorenzo Bianconi }; 9717f03a563SLorenzo Bianconi 97222b980baSFelix Fietkau struct mt76_power_limits { 97322b980baSFelix Fietkau s8 cck[4]; 97422b980baSFelix Fietkau s8 ofdm[8]; 97522b980baSFelix Fietkau s8 mcs[4][10]; 976a9627d99SShayne Chen s8 ru[7][12]; 977975cd4d6SDeren Wu s8 eht[16][16]; 97822b980baSFelix Fietkau }; 97922b980baSFelix Fietkau 98054ae98ffSLorenzo Bianconi struct mt76_ethtool_worker_info { 98154ae98ffSLorenzo Bianconi u64 *data; 98254ae98ffSLorenzo Bianconi int idx; 98354ae98ffSLorenzo Bianconi int initial_stat_idx; 98454ae98ffSLorenzo Bianconi int worker_stat_count; 98554ae98ffSLorenzo Bianconi int sta_count; 98654ae98ffSLorenzo Bianconi }; 98754ae98ffSLorenzo Bianconi 98854b8fdebSLorenzo Bianconi #define CCK_RATE(_idx, _rate) { \ 98954b8fdebSLorenzo Bianconi .bitrate = _rate, \ 99054b8fdebSLorenzo Bianconi .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ 99154b8fdebSLorenzo Bianconi .hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \ 99254b8fdebSLorenzo Bianconi .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + _idx), \ 99354b8fdebSLorenzo Bianconi } 99454b8fdebSLorenzo Bianconi 99554b8fdebSLorenzo Bianconi #define OFDM_RATE(_idx, _rate) { \ 99654b8fdebSLorenzo Bianconi .bitrate = _rate, \ 99754b8fdebSLorenzo Bianconi .hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 99854b8fdebSLorenzo Bianconi .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 99954b8fdebSLorenzo Bianconi } 100054b8fdebSLorenzo Bianconi 100154b8fdebSLorenzo Bianconi extern struct ieee80211_rate mt76_rates[12]; 100254b8fdebSLorenzo Bianconi 1003d4131273SStanislaw Gruszka #define __mt76_rr(dev, ...) (dev)->bus->rr((dev), __VA_ARGS__) 1004d4131273SStanislaw Gruszka #define __mt76_wr(dev, ...) (dev)->bus->wr((dev), __VA_ARGS__) 1005d4131273SStanislaw Gruszka #define __mt76_rmw(dev, ...) (dev)->bus->rmw((dev), __VA_ARGS__) 100635e4ebeaSLorenzo Bianconi #define __mt76_wr_copy(dev, ...) (dev)->bus->write_copy((dev), __VA_ARGS__) 100735e4ebeaSLorenzo Bianconi #define __mt76_rr_copy(dev, ...) (dev)->bus->read_copy((dev), __VA_ARGS__) 1008d4131273SStanislaw Gruszka 100922c575c4SStanislaw Gruszka #define __mt76_set(dev, offset, val) __mt76_rmw(dev, offset, 0, val) 101022c575c4SStanislaw Gruszka #define __mt76_clear(dev, offset, val) __mt76_rmw(dev, offset, val, 0) 101122c575c4SStanislaw Gruszka 101217f1de56SFelix Fietkau #define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__) 101317f1de56SFelix Fietkau #define mt76_wr(dev, ...) (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__) 101417f1de56SFelix Fietkau #define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__) 101535e4ebeaSLorenzo Bianconi #define mt76_wr_copy(dev, ...) (dev)->mt76.bus->write_copy(&((dev)->mt76), __VA_ARGS__) 101635e4ebeaSLorenzo Bianconi #define mt76_rr_copy(dev, ...) (dev)->mt76.bus->read_copy(&((dev)->mt76), __VA_ARGS__) 10176da5a291SStanislaw Gruszka #define mt76_wr_rp(dev, ...) (dev)->mt76.bus->wr_rp(&((dev)->mt76), __VA_ARGS__) 10186da5a291SStanislaw Gruszka #define mt76_rd_rp(dev, ...) (dev)->mt76.bus->rd_rp(&((dev)->mt76), __VA_ARGS__) 101917f1de56SFelix Fietkau 1020f4d45fe2SLorenzo Bianconi 1021e2c2fd0fSLorenzo Bianconi #define mt76_mcu_restart(dev, ...) (dev)->mt76.mcu_ops->mcu_restart(&((dev)->mt76)) 1022db0f04f3SLorenzo Bianconi 102317f1de56SFelix Fietkau #define mt76_set(dev, offset, val) mt76_rmw(dev, offset, 0, val) 102417f1de56SFelix Fietkau #define mt76_clear(dev, offset, val) mt76_rmw(dev, offset, val, 0) 102517f1de56SFelix Fietkau 102617f1de56SFelix Fietkau #define mt76_get_field(_dev, _reg, _field) \ 102717f1de56SFelix Fietkau FIELD_GET(_field, mt76_rr(dev, _reg)) 102817f1de56SFelix Fietkau 102917f1de56SFelix Fietkau #define mt76_rmw_field(_dev, _reg, _field, _val) \ 103017f1de56SFelix Fietkau mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) 103117f1de56SFelix Fietkau 103246436b5eSStanislaw Gruszka #define __mt76_rmw_field(_dev, _reg, _field, _val) \ 103346436b5eSStanislaw Gruszka __mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) 103446436b5eSStanislaw Gruszka 1035ac24dd35SFelix Fietkau #define mt76_hw(dev) (dev)->mphy.hw 103617f1de56SFelix Fietkau 103717f1de56SFelix Fietkau bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, 103817f1de56SFelix Fietkau int timeout); 103917f1de56SFelix Fietkau 104017f1de56SFelix Fietkau #define mt76_poll(dev, ...) __mt76_poll(&((dev)->mt76), __VA_ARGS__) 104117f1de56SFelix Fietkau 104235effe6cSDeren Wu bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, 104335effe6cSDeren Wu int timeout, int kick); 104435effe6cSDeren Wu #define __mt76_poll_msec(...) ____mt76_poll_msec(__VA_ARGS__, 10) 104535effe6cSDeren Wu #define mt76_poll_msec(dev, ...) ____mt76_poll_msec(&((dev)->mt76), __VA_ARGS__, 10) 104635effe6cSDeren Wu #define mt76_poll_msec_tick(dev, ...) ____mt76_poll_msec(&((dev)->mt76), __VA_ARGS__) 104717f1de56SFelix Fietkau 104817f1de56SFelix Fietkau void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs); 1049f37f0550SLorenzo Bianconi void mt76_pci_disable_aspm(struct pci_dev *pdev); 105017f1de56SFelix Fietkau 1051ac465985SLorenzo Bianconi #ifdef CONFIG_NET_MEDIATEK_SOC_WED 1052ac465985SLorenzo Bianconi int mt76_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1053ac465985SLorenzo Bianconi struct net_device *netdev, enum tc_setup_type type, 1054ac465985SLorenzo Bianconi void *type_data); 1055ac465985SLorenzo Bianconi #endif /*CONFIG_NET_MEDIATEK_SOC_WED */ 1056ac465985SLorenzo Bianconi 105717f1de56SFelix Fietkau static inline u16 mt76_chip(struct mt76_dev *dev) 105817f1de56SFelix Fietkau { 105917f1de56SFelix Fietkau return dev->rev >> 16; 106017f1de56SFelix Fietkau } 106117f1de56SFelix Fietkau 106217f1de56SFelix Fietkau static inline u16 mt76_rev(struct mt76_dev *dev) 106317f1de56SFelix Fietkau { 106417f1de56SFelix Fietkau return dev->rev & 0xffff; 106517f1de56SFelix Fietkau } 106617f1de56SFelix Fietkau 1067b92158a8SLorenzo Bianconi #ifdef CONFIG_NET_MEDIATEK_SOC_WED 1068b92158a8SLorenzo Bianconi u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size); 1069b92158a8SLorenzo Bianconi void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed); 10705f60735cSLorenzo Bianconi int mt76_mmio_wed_offload_enable(struct mtk_wed_device *wed); 10715f60735cSLorenzo Bianconi void mt76_mmio_wed_offload_disable(struct mtk_wed_device *wed); 1072b92158a8SLorenzo Bianconi #endif /*CONFIG_NET_MEDIATEK_SOC_WED */ 1073b92158a8SLorenzo Bianconi 107417f1de56SFelix Fietkau #define mt76xx_chip(dev) mt76_chip(&((dev)->mt76)) 107517f1de56SFelix Fietkau #define mt76xx_rev(dev) mt76_rev(&((dev)->mt76)) 107617f1de56SFelix Fietkau 1077cb8ed33dSLorenzo Bianconi #define mt76_init_queues(dev, ...) (dev)->mt76.queue_ops->init(&((dev)->mt76), __VA_ARGS__) 1078a23fde09SLorenzo Bianconi #define mt76_queue_alloc(dev, ...) (dev)->mt76.queue_ops->alloc(&((dev)->mt76), __VA_ARGS__) 10795ed31128SLorenzo Bianconi #define mt76_tx_queue_skb_raw(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb_raw(&((dev)->mt76), __VA_ARGS__) 1080eb9ca7ecSLorenzo Bianconi #define mt76_tx_queue_skb(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb(&((dev)->mt76), __VA_ARGS__) 108117f1de56SFelix Fietkau #define mt76_queue_rx_reset(dev, ...) (dev)->mt76.queue_ops->rx_reset(&((dev)->mt76), __VA_ARGS__) 108217f1de56SFelix Fietkau #define mt76_queue_tx_cleanup(dev, ...) (dev)->mt76.queue_ops->tx_cleanup(&((dev)->mt76), __VA_ARGS__) 1083c001df97SLorenzo Bianconi #define mt76_queue_rx_cleanup(dev, ...) (dev)->mt76.queue_ops->rx_cleanup(&((dev)->mt76), __VA_ARGS__) 108417f1de56SFelix Fietkau #define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__) 10853990465dSLorenzo Bianconi #define mt76_queue_reset(dev, ...) (dev)->mt76.queue_ops->reset_q(&((dev)->mt76), __VA_ARGS__) 108617f1de56SFelix Fietkau 1087f473b42aSFelix Fietkau #define mt76_for_each_q_rx(dev, i) \ 1088b3ad9d6aSBo Jiao for (i = 0; i < ARRAY_SIZE((dev)->q_rx); i++) \ 1089b3ad9d6aSBo Jiao if ((dev)->q_rx[i].ndesc) 1090f473b42aSFelix Fietkau 1091c0f7b25aSLorenzo Bianconi struct mt76_dev *mt76_alloc_device(struct device *pdev, unsigned int size, 1092c0f7b25aSLorenzo Bianconi const struct ieee80211_ops *ops, 1093c0f7b25aSLorenzo Bianconi const struct mt76_driver_ops *drv_ops); 109417f1de56SFelix Fietkau int mt76_register_device(struct mt76_dev *dev, bool vht, 109517f1de56SFelix Fietkau struct ieee80211_rate *rates, int n_rates); 109617f1de56SFelix Fietkau void mt76_unregister_device(struct mt76_dev *dev); 1097def34a2fSLorenzo Bianconi void mt76_free_device(struct mt76_dev *dev); 1098c89d3625SFelix Fietkau void mt76_unregister_phy(struct mt76_phy *phy); 1099c89d3625SFelix Fietkau 1100c89d3625SFelix Fietkau struct mt76_phy *mt76_alloc_phy(struct mt76_dev *dev, unsigned int size, 1101dc44c45cSLorenzo Bianconi const struct ieee80211_ops *ops, 1102dc44c45cSLorenzo Bianconi u8 band_idx); 1103db78a791SLorenzo Bianconi int mt76_register_phy(struct mt76_phy *phy, bool vht, 1104db78a791SLorenzo Bianconi struct ieee80211_rate *rates, int n_rates); 110517f1de56SFelix Fietkau 11063263039dSLorenzo Bianconi struct dentry *mt76_register_debugfs_fops(struct mt76_phy *phy, 1107f6e1f598SLorenzo Bianconi const struct file_operations *ops); 1108f6e1f598SLorenzo Bianconi static inline struct dentry *mt76_register_debugfs(struct mt76_dev *dev) 1109f6e1f598SLorenzo Bianconi { 11103263039dSLorenzo Bianconi return mt76_register_debugfs_fops(&dev->phy, NULL); 1111f6e1f598SLorenzo Bianconi } 1112f6e1f598SLorenzo Bianconi 11130b82a8e8SLorenzo Bianconi int mt76_queues_read(struct seq_file *s, void *data); 11148f410a8bSLorenzo Bianconi void mt76_seq_puts_array(struct seq_file *file, const char *str, 11158f410a8bSLorenzo Bianconi s8 *val, int len); 111617f1de56SFelix Fietkau 111717f1de56SFelix Fietkau int mt76_eeprom_init(struct mt76_dev *dev, int len); 111898df2baeSLorenzo Bianconi void mt76_eeprom_override(struct mt76_phy *phy); 1119a6342c31SChristian Marangi int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len); 1120a1f57685SChristian Marangi int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep, 1121a1f57685SChristian Marangi const char *cell_name, int len); 112217f1de56SFelix Fietkau 1123b1cb42adSLorenzo Bianconi struct mt76_queue * 1124b1cb42adSLorenzo Bianconi mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc, 11252e420b88SLorenzo Bianconi int ring_base, void *wed, u32 flags); 112632b1000dSSean Wang u16 mt76_calculate_default_rate(struct mt76_phy *phy, 112732b1000dSSean Wang struct ieee80211_vif *vif, int rateidx); 1128b1cb42adSLorenzo Bianconi static inline int mt76_init_tx_queue(struct mt76_phy *phy, int qid, int idx, 11292e420b88SLorenzo Bianconi int n_desc, int ring_base, void *wed, 11302e420b88SLorenzo Bianconi u32 flags) 1131b1cb42adSLorenzo Bianconi { 1132b1cb42adSLorenzo Bianconi struct mt76_queue *q; 1133b1cb42adSLorenzo Bianconi 11342e420b88SLorenzo Bianconi q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base, wed, flags); 1135b1cb42adSLorenzo Bianconi if (IS_ERR(q)) 1136b1cb42adSLorenzo Bianconi return PTR_ERR(q); 1137b1cb42adSLorenzo Bianconi 113891990519SLorenzo Bianconi phy->q_tx[qid] = q; 1139b1cb42adSLorenzo Bianconi 1140b1cb42adSLorenzo Bianconi return 0; 1141b1cb42adSLorenzo Bianconi } 1142b1cb42adSLorenzo Bianconi 1143b1cb42adSLorenzo Bianconi static inline int mt76_init_mcu_queue(struct mt76_dev *dev, int qid, int idx, 1144b1cb42adSLorenzo Bianconi int n_desc, int ring_base) 1145b1cb42adSLorenzo Bianconi { 1146b1cb42adSLorenzo Bianconi struct mt76_queue *q; 1147b1cb42adSLorenzo Bianconi 11482e420b88SLorenzo Bianconi q = mt76_init_queue(dev, qid, idx, n_desc, ring_base, NULL, 0); 1149b1cb42adSLorenzo Bianconi if (IS_ERR(q)) 1150b1cb42adSLorenzo Bianconi return PTR_ERR(q); 1151b1cb42adSLorenzo Bianconi 1152b1cb42adSLorenzo Bianconi dev->q_mcu[qid] = q; 1153b1cb42adSLorenzo Bianconi 1154b1cb42adSLorenzo Bianconi return 0; 1155b1cb42adSLorenzo Bianconi } 1156b671da33SLorenzo Bianconi 1157011849e0SFelix Fietkau static inline struct mt76_phy * 1158128c9b7dSLorenzo Bianconi mt76_dev_phy(struct mt76_dev *dev, u8 phy_idx) 1159011849e0SFelix Fietkau { 1160dc44c45cSLorenzo Bianconi if ((phy_idx == MT_BAND1 && dev->phys[phy_idx]) || 1161dc44c45cSLorenzo Bianconi (phy_idx == MT_BAND2 && dev->phys[phy_idx])) 1162dc44c45cSLorenzo Bianconi return dev->phys[phy_idx]; 1163128c9b7dSLorenzo Bianconi 1164011849e0SFelix Fietkau return &dev->phy; 1165011849e0SFelix Fietkau } 1166011849e0SFelix Fietkau 1167bfc394ddSFelix Fietkau static inline struct ieee80211_hw * 1168128c9b7dSLorenzo Bianconi mt76_phy_hw(struct mt76_dev *dev, u8 phy_idx) 1169bfc394ddSFelix Fietkau { 1170128c9b7dSLorenzo Bianconi return mt76_dev_phy(dev, phy_idx)->hw; 1171bfc394ddSFelix Fietkau } 1172bfc394ddSFelix Fietkau 1173f3950a41SLorenzo Bianconi static inline u8 * 1174f3950a41SLorenzo Bianconi mt76_get_txwi_ptr(struct mt76_dev *dev, struct mt76_txwi_cache *t) 1175f3950a41SLorenzo Bianconi { 1176f3950a41SLorenzo Bianconi return (u8 *)t - dev->drv->txwi_size; 1177f3950a41SLorenzo Bianconi } 1178f3950a41SLorenzo Bianconi 1179ee8aa945SLorenzo Bianconi /* increment with wrap-around */ 1180ee8aa945SLorenzo Bianconi static inline int mt76_incr(int val, int size) 1181ee8aa945SLorenzo Bianconi { 1182ee8aa945SLorenzo Bianconi return (val + 1) & (size - 1); 1183ee8aa945SLorenzo Bianconi } 1184ee8aa945SLorenzo Bianconi 1185ee8aa945SLorenzo Bianconi /* decrement with wrap-around */ 1186ee8aa945SLorenzo Bianconi static inline int mt76_decr(int val, int size) 1187ee8aa945SLorenzo Bianconi { 1188ee8aa945SLorenzo Bianconi return (val - 1) & (size - 1); 1189ee8aa945SLorenzo Bianconi } 1190ee8aa945SLorenzo Bianconi 11911d0496c6SStanislaw Gruszka u8 mt76_ac_to_hwq(u8 ac); 1192b40b15e1SLorenzo Bianconi 119317f1de56SFelix Fietkau static inline struct ieee80211_txq * 119417f1de56SFelix Fietkau mtxq_to_txq(struct mt76_txq *mtxq) 119517f1de56SFelix Fietkau { 119617f1de56SFelix Fietkau void *ptr = mtxq; 119717f1de56SFelix Fietkau 119817f1de56SFelix Fietkau return container_of(ptr, struct ieee80211_txq, drv_priv); 119917f1de56SFelix Fietkau } 120017f1de56SFelix Fietkau 12019c68a57bSFelix Fietkau static inline struct ieee80211_sta * 12029c68a57bSFelix Fietkau wcid_to_sta(struct mt76_wcid *wcid) 12039c68a57bSFelix Fietkau { 12049c68a57bSFelix Fietkau void *ptr = wcid; 12059c68a57bSFelix Fietkau 12069c68a57bSFelix Fietkau if (!wcid || !wcid->sta) 12079c68a57bSFelix Fietkau return NULL; 12089c68a57bSFelix Fietkau 12099c68a57bSFelix Fietkau return container_of(ptr, struct ieee80211_sta, drv_priv); 12109c68a57bSFelix Fietkau } 12119c68a57bSFelix Fietkau 121288046b2cSFelix Fietkau static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb) 121388046b2cSFelix Fietkau { 121488046b2cSFelix Fietkau BUILD_BUG_ON(sizeof(struct mt76_tx_cb) > 121588046b2cSFelix Fietkau sizeof(IEEE80211_SKB_CB(skb)->status.status_driver_data)); 121688046b2cSFelix Fietkau return ((void *)IEEE80211_SKB_CB(skb)->status.status_driver_data); 121788046b2cSFelix Fietkau } 121888046b2cSFelix Fietkau 121977ae1d5eSRyder Lee static inline void *mt76_skb_get_hdr(struct sk_buff *skb) 122077ae1d5eSRyder Lee { 122177ae1d5eSRyder Lee struct mt76_rx_status mstat; 122277ae1d5eSRyder Lee u8 *data = skb->data; 122377ae1d5eSRyder Lee 122477ae1d5eSRyder Lee /* Alignment concerns */ 122577ae1d5eSRyder Lee BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he) % 4); 122677ae1d5eSRyder Lee BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he_mu) % 4); 122777ae1d5eSRyder Lee 122877ae1d5eSRyder Lee mstat = *((struct mt76_rx_status *)skb->cb); 122977ae1d5eSRyder Lee 123077ae1d5eSRyder Lee if (mstat.flag & RX_FLAG_RADIOTAP_HE) 123177ae1d5eSRyder Lee data += sizeof(struct ieee80211_radiotap_he); 123277ae1d5eSRyder Lee if (mstat.flag & RX_FLAG_RADIOTAP_HE_MU) 123377ae1d5eSRyder Lee data += sizeof(struct ieee80211_radiotap_he_mu); 123477ae1d5eSRyder Lee 123577ae1d5eSRyder Lee return data; 123677ae1d5eSRyder Lee } 123777ae1d5eSRyder Lee 12383bb45b5fSLorenzo Bianconi static inline void mt76_insert_hdr_pad(struct sk_buff *skb) 12393bb45b5fSLorenzo Bianconi { 12403bb45b5fSLorenzo Bianconi int len = ieee80211_get_hdrlen_from_skb(skb); 12413bb45b5fSLorenzo Bianconi 12423bb45b5fSLorenzo Bianconi if (len % 4 == 0) 12433bb45b5fSLorenzo Bianconi return; 12443bb45b5fSLorenzo Bianconi 12453bb45b5fSLorenzo Bianconi skb_push(skb, 2); 12463bb45b5fSLorenzo Bianconi memmove(skb->data, skb->data + 2, len); 12473bb45b5fSLorenzo Bianconi 12483bb45b5fSLorenzo Bianconi skb->data[len] = 0; 12493bb45b5fSLorenzo Bianconi skb->data[len + 1] = 0; 12503bb45b5fSLorenzo Bianconi } 12513bb45b5fSLorenzo Bianconi 12528548c6ebSFelix Fietkau static inline bool mt76_is_skb_pktid(u8 pktid) 12538548c6ebSFelix Fietkau { 12548548c6ebSFelix Fietkau if (pktid & MT_PACKET_ID_HAS_RATE) 12558548c6ebSFelix Fietkau return false; 12568548c6ebSFelix Fietkau 12578548c6ebSFelix Fietkau return pktid >= MT_PACKET_ID_FIRST; 12588548c6ebSFelix Fietkau } 12598548c6ebSFelix Fietkau 126007cda406SFelix Fietkau static inline u8 mt76_tx_power_nss_delta(u8 nss) 126107cda406SFelix Fietkau { 126207cda406SFelix Fietkau static const u8 nss_delta[4] = { 0, 6, 9, 12 }; 126303dd0d49SDeren Wu u8 idx = nss - 1; 126407cda406SFelix Fietkau 126503dd0d49SDeren Wu return (idx < ARRAY_SIZE(nss_delta)) ? nss_delta[idx] : 0; 126607cda406SFelix Fietkau } 126707cda406SFelix Fietkau 1268c918c74dSShayne Chen static inline bool mt76_testmode_enabled(struct mt76_phy *phy) 1269f0efa862SFelix Fietkau { 1270f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 1271c918c74dSShayne Chen return phy->test.state != MT76_TM_STATE_OFF; 1272c918c74dSShayne Chen #else 1273c918c74dSShayne Chen return false; 1274c918c74dSShayne Chen #endif 1275c918c74dSShayne Chen } 1276c918c74dSShayne Chen 1277c918c74dSShayne Chen static inline bool mt76_is_testmode_skb(struct mt76_dev *dev, 1278c918c74dSShayne Chen struct sk_buff *skb, 1279c918c74dSShayne Chen struct ieee80211_hw **hw) 1280c918c74dSShayne Chen { 1281c918c74dSShayne Chen #ifdef CONFIG_NL80211_TESTMODE 1282dc44c45cSLorenzo Bianconi int i; 1283dc44c45cSLorenzo Bianconi 1284dc44c45cSLorenzo Bianconi for (i = 0; i < ARRAY_SIZE(dev->phys); i++) { 1285dc44c45cSLorenzo Bianconi struct mt76_phy *phy = dev->phys[i]; 1286dc44c45cSLorenzo Bianconi 1287dc44c45cSLorenzo Bianconi if (phy && skb == phy->test.tx_skb) { 1288dc44c45cSLorenzo Bianconi *hw = dev->phys[i]->hw; 1289c918c74dSShayne Chen return true; 1290dc44c45cSLorenzo Bianconi } 1291dc44c45cSLorenzo Bianconi } 1292dc44c45cSLorenzo Bianconi return false; 1293f0efa862SFelix Fietkau #else 1294f0efa862SFelix Fietkau return false; 1295f0efa862SFelix Fietkau #endif 1296f0efa862SFelix Fietkau } 1297f0efa862SFelix Fietkau 129817f1de56SFelix Fietkau void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb); 12999fba6d07SFelix Fietkau void mt76_tx(struct mt76_phy *dev, struct ieee80211_sta *sta, 130017f1de56SFelix Fietkau struct mt76_wcid *wcid, struct sk_buff *skb); 130117f1de56SFelix Fietkau void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq); 130291990519SLorenzo Bianconi void mt76_stop_tx_queues(struct mt76_phy *phy, struct ieee80211_sta *sta, 130317f1de56SFelix Fietkau bool send_bar); 1304c50d105aSFelix Fietkau void mt76_tx_check_agg_ssn(struct ieee80211_sta *sta, struct sk_buff *skb); 13059fba6d07SFelix Fietkau void mt76_txq_schedule(struct mt76_phy *phy, enum mt76_txq_id qid); 13069fba6d07SFelix Fietkau void mt76_txq_schedule_all(struct mt76_phy *phy); 1307335e97acSLorenzo Bianconi void mt76_tx_worker_run(struct mt76_dev *dev); 1308781eef5bSFelix Fietkau void mt76_tx_worker(struct mt76_worker *w); 130917f1de56SFelix Fietkau void mt76_release_buffered_frames(struct ieee80211_hw *hw, 131017f1de56SFelix Fietkau struct ieee80211_sta *sta, 131117f1de56SFelix Fietkau u16 tids, int nframes, 131217f1de56SFelix Fietkau enum ieee80211_frame_release_type reason, 131317f1de56SFelix Fietkau bool more_data); 13145a95ca41SFelix Fietkau bool mt76_has_tx_pending(struct mt76_phy *phy); 131596747a51SFelix Fietkau void mt76_set_channel(struct mt76_phy *phy); 1316c560b137SRyder Lee void mt76_update_survey(struct mt76_phy *phy); 131704414240SLorenzo Bianconi void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time); 131817f1de56SFelix Fietkau int mt76_get_survey(struct ieee80211_hw *hw, int idx, 131917f1de56SFelix Fietkau struct survey_info *survey); 1320a71b648eSRyder Lee int mt76_rx_signal(u8 chain_mask, s8 *chain_signal); 1321bb3e3fecSRyder Lee void mt76_set_stream_caps(struct mt76_phy *phy, bool vht); 132217f1de56SFelix Fietkau 1323aee5b8cfSFelix Fietkau int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid, 13247c4f744dSRyder Lee u16 ssn, u16 size); 1325aee5b8cfSFelix Fietkau void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid); 1326aee5b8cfSFelix Fietkau 132730ce7f44SFelix Fietkau void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, 132830ce7f44SFelix Fietkau struct ieee80211_key_conf *key); 132979d1c94cSFelix Fietkau 133079d1c94cSFelix Fietkau void mt76_tx_status_lock(struct mt76_dev *dev, struct sk_buff_head *list) 1331c34f1005SLorenzo Bianconi __acquires(&dev->status_lock); 133279d1c94cSFelix Fietkau void mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list) 1333c34f1005SLorenzo Bianconi __releases(&dev->status_lock); 133479d1c94cSFelix Fietkau 133588046b2cSFelix Fietkau int mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, 133688046b2cSFelix Fietkau struct sk_buff *skb); 133788046b2cSFelix Fietkau struct sk_buff *mt76_tx_status_skb_get(struct mt76_dev *dev, 133879d1c94cSFelix Fietkau struct mt76_wcid *wcid, int pktid, 133979d1c94cSFelix Fietkau struct sk_buff_head *list); 134079d1c94cSFelix Fietkau void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb, 134179d1c94cSFelix Fietkau struct sk_buff_head *list); 13420fe88644SFelix Fietkau void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb, 13430fe88644SFelix Fietkau struct list_head *free_list); 13440fe88644SFelix Fietkau static inline void 13450fe88644SFelix Fietkau mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb) 13460fe88644SFelix Fietkau { 13470fe88644SFelix Fietkau __mt76_tx_complete_skb(dev, wcid, skb, NULL); 13480fe88644SFelix Fietkau } 13490fe88644SFelix Fietkau 1350c02f86eeSLorenzo Bianconi void mt76_tx_status_check(struct mt76_dev *dev, bool flush); 1351e28487eaSFelix Fietkau int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1352e28487eaSFelix Fietkau struct ieee80211_sta *sta, 1353e28487eaSFelix Fietkau enum ieee80211_sta_state old_state, 1354e28487eaSFelix Fietkau enum ieee80211_sta_state new_state); 135513f61dfcSLorenzo Bianconi void __mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif, 135613f61dfcSLorenzo Bianconi struct ieee80211_sta *sta); 135743ba1922SFelix Fietkau void mt76_sta_pre_rcu_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 135843ba1922SFelix Fietkau struct ieee80211_sta *sta); 135930ce7f44SFelix Fietkau 13608af63fedSFelix Fietkau int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy); 1361ef13edc0SFelix Fietkau 13629313faacSFelix Fietkau int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 13639313faacSFelix Fietkau int *dbm); 1364b3cb885eSLorenzo Bianconi int mt76_init_sar_power(struct ieee80211_hw *hw, 1365b3cb885eSLorenzo Bianconi const struct cfg80211_sar_specs *sar); 1366b3cb885eSLorenzo Bianconi int mt76_get_sar_power(struct mt76_phy *phy, 1367b3cb885eSLorenzo Bianconi struct ieee80211_channel *chan, 1368b3cb885eSLorenzo Bianconi int power); 13699313faacSFelix Fietkau 1370e7173858SFelix Fietkau void mt76_csa_check(struct mt76_dev *dev); 1371e7173858SFelix Fietkau void mt76_csa_finish(struct mt76_dev *dev); 1372e7173858SFelix Fietkau 1373e49c76d4SLorenzo Bianconi int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 137487d53103SStanislaw Gruszka int mt76_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set); 1375eadfd98fSLorenzo Bianconi void mt76_insert_ccmp_hdr(struct sk_buff *skb, u8 key_id); 1376d2679d65SLorenzo Bianconi int mt76_get_rate(struct mt76_dev *dev, 1377d2679d65SLorenzo Bianconi struct ieee80211_supported_band *sband, 1378d2679d65SLorenzo Bianconi int idx, bool cck); 13798b8ab5c2SLorenzo Bianconi void mt76_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 13808b8ab5c2SLorenzo Bianconi const u8 *mac); 13818b8ab5c2SLorenzo Bianconi void mt76_sw_scan_complete(struct ieee80211_hw *hw, 13828b8ab5c2SLorenzo Bianconi struct ieee80211_vif *vif); 13833f306448SFelix Fietkau enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy); 1384f0efa862SFelix Fietkau int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1385f0efa862SFelix Fietkau void *data, int len); 1386f0efa862SFelix Fietkau int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, 1387f0efa862SFelix Fietkau struct netlink_callback *cb, void *data, int len); 1388c918c74dSShayne Chen int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state); 13892601dda8SShayne Chen int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len); 1390f0efa862SFelix Fietkau 1391c918c74dSShayne Chen static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable) 1392f0efa862SFelix Fietkau { 1393f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 1394f0efa862SFelix Fietkau enum mt76_testmode_state state = MT76_TM_STATE_IDLE; 1395f0efa862SFelix Fietkau 1396c918c74dSShayne Chen if (disable || phy->test.state == MT76_TM_STATE_OFF) 1397f0efa862SFelix Fietkau state = MT76_TM_STATE_OFF; 1398f0efa862SFelix Fietkau 1399c918c74dSShayne Chen mt76_testmode_set_state(phy, state); 1400f0efa862SFelix Fietkau #endif 1401f0efa862SFelix Fietkau } 1402f0efa862SFelix Fietkau 140387d53103SStanislaw Gruszka 140417f1de56SFelix Fietkau /* internal */ 1405e394b575SFelix Fietkau static inline struct ieee80211_hw * 1406e394b575SFelix Fietkau mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb) 1407e394b575SFelix Fietkau { 1408e394b575SFelix Fietkau struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1409a062f001SLorenzo Bianconi u8 phy_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2; 1410a062f001SLorenzo Bianconi struct ieee80211_hw *hw = mt76_phy_hw(dev, phy_idx); 1411e394b575SFelix Fietkau 1412a062f001SLorenzo Bianconi info->hw_queue &= ~MT_TX_HW_QUEUE_PHY; 1413e394b575SFelix Fietkau 1414e394b575SFelix Fietkau return hw; 1415e394b575SFelix Fietkau } 1416e394b575SFelix Fietkau 141717f1de56SFelix Fietkau void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); 14182666beceSSujuan Chen void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); 14192666beceSSujuan Chen struct mt76_txwi_cache *mt76_get_rxwi(struct mt76_dev *dev); 1420a97a467aSSujuan Chen void mt76_free_pending_rxwi(struct mt76_dev *dev); 14219d9d738bSFelix Fietkau void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, 142281e850efSLorenzo Bianconi struct napi_struct *napi); 142381e850efSLorenzo Bianconi void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q, 142481e850efSLorenzo Bianconi struct napi_struct *napi); 1425aee5b8cfSFelix Fietkau void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames); 1426c918c74dSShayne Chen void mt76_testmode_tx_pending(struct mt76_phy *phy); 1427fe5b5ab5SFelix Fietkau void mt76_queue_tx_complete(struct mt76_dev *dev, struct mt76_queue *q, 1428fe5b5ab5SFelix Fietkau struct mt76_queue_entry *e); 142917f1de56SFelix Fietkau 1430b40b15e1SLorenzo Bianconi /* usb */ 1431b40b15e1SLorenzo Bianconi static inline bool mt76u_urb_error(struct urb *urb) 1432b40b15e1SLorenzo Bianconi { 1433b40b15e1SLorenzo Bianconi return urb->status && 1434b40b15e1SLorenzo Bianconi urb->status != -ECONNRESET && 1435b40b15e1SLorenzo Bianconi urb->status != -ESHUTDOWN && 1436b40b15e1SLorenzo Bianconi urb->status != -ENOENT; 1437b40b15e1SLorenzo Bianconi } 1438b40b15e1SLorenzo Bianconi 1439b40b15e1SLorenzo Bianconi /* Map hardware queues to usb endpoints */ 1440b40b15e1SLorenzo Bianconi static inline u8 q2ep(u8 qid) 1441b40b15e1SLorenzo Bianconi { 1442b40b15e1SLorenzo Bianconi /* TODO: take management packets to queue 5 */ 1443b40b15e1SLorenzo Bianconi return qid + 1; 1444b40b15e1SLorenzo Bianconi } 1445b40b15e1SLorenzo Bianconi 14465de4db8fSStanislaw Gruszka static inline int 1447b63aa031SStanislaw Gruszka mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len, 14483bcd979cSLorenzo Bianconi int timeout, int ep) 14495de4db8fSStanislaw Gruszka { 145080df01f4SLorenzo Bianconi struct usb_interface *uintf = to_usb_interface(dev->dev); 145180df01f4SLorenzo Bianconi struct usb_device *udev = interface_to_usbdev(uintf); 14525de4db8fSStanislaw Gruszka struct mt76_usb *usb = &dev->usb; 14535de4db8fSStanislaw Gruszka unsigned int pipe; 14545de4db8fSStanislaw Gruszka 1455b63aa031SStanislaw Gruszka if (actual_len) 14563bcd979cSLorenzo Bianconi pipe = usb_rcvbulkpipe(udev, usb->in_ep[ep]); 1457b63aa031SStanislaw Gruszka else 14583bcd979cSLorenzo Bianconi pipe = usb_sndbulkpipe(udev, usb->out_ep[ep]); 1459b63aa031SStanislaw Gruszka 1460b63aa031SStanislaw Gruszka return usb_bulk_msg(udev, pipe, data, len, actual_len, timeout); 14615de4db8fSStanislaw Gruszka } 14625de4db8fSStanislaw Gruszka 1463192ad406SLorenzo Bianconi void mt76_ethtool_page_pool_stats(struct mt76_dev *dev, u64 *data, int *index); 146454ae98ffSLorenzo Bianconi void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi, 1465731425f3SShayne Chen struct mt76_sta_stats *stats, bool eht); 1466e98e6df6SLorenzo Bianconi int mt76_skb_adjust_pad(struct sk_buff *skb, int pad); 14676cb596baSLorenzo Bianconi int __mt76u_vendor_request(struct mt76_dev *dev, u8 req, u8 req_type, 14686cb596baSLorenzo Bianconi u16 val, u16 offset, void *buf, size_t len); 1469b40b15e1SLorenzo Bianconi int mt76u_vendor_request(struct mt76_dev *dev, u8 req, 1470b40b15e1SLorenzo Bianconi u8 req_type, u16 val, u16 offset, 1471b40b15e1SLorenzo Bianconi void *buf, size_t len); 1472b40b15e1SLorenzo Bianconi void mt76u_single_wr(struct mt76_dev *dev, const u8 req, 1473b40b15e1SLorenzo Bianconi const u16 offset, const u32 val); 14746cb596baSLorenzo Bianconi void mt76u_read_copy(struct mt76_dev *dev, u32 offset, 14756cb596baSLorenzo Bianconi void *data, int len); 14766cb596baSLorenzo Bianconi u32 ___mt76u_rr(struct mt76_dev *dev, u8 req, u8 req_type, u32 addr); 14776cb596baSLorenzo Bianconi void ___mt76u_wr(struct mt76_dev *dev, u8 req, u8 req_type, 14786cb596baSLorenzo Bianconi u32 addr, u32 val); 14796cb596baSLorenzo Bianconi int __mt76u_init(struct mt76_dev *dev, struct usb_interface *intf, 14806cb596baSLorenzo Bianconi struct mt76_bus_ops *ops); 14816cb596baSLorenzo Bianconi int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf); 148294e1cfa8SLorenzo Bianconi int mt76u_alloc_mcu_queue(struct mt76_dev *dev); 1483b40b15e1SLorenzo Bianconi int mt76u_alloc_queues(struct mt76_dev *dev); 148439d501d9SStanislaw Gruszka void mt76u_stop_tx(struct mt76_dev *dev); 148539d501d9SStanislaw Gruszka void mt76u_stop_rx(struct mt76_dev *dev); 148639d501d9SStanislaw Gruszka int mt76u_resume_rx(struct mt76_dev *dev); 1487b40b15e1SLorenzo Bianconi void mt76u_queues_deinit(struct mt76_dev *dev); 1488b40b15e1SLorenzo Bianconi 1489d39b52e3SSean Wang int mt76s_init(struct mt76_dev *dev, struct sdio_func *func, 1490d39b52e3SSean Wang const struct mt76_bus_ops *bus_ops); 1491d512b008SLorenzo Bianconi int mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid); 1492d512b008SLorenzo Bianconi int mt76s_alloc_tx(struct mt76_dev *dev); 1493d39b52e3SSean Wang void mt76s_deinit(struct mt76_dev *dev); 1494764dee47SLorenzo Bianconi void mt76s_sdio_irq(struct sdio_func *func); 1495764dee47SLorenzo Bianconi void mt76s_txrx_worker(struct mt76_sdio *sdio); 1496ca74b9b9SSean Wang bool mt76s_txqs_empty(struct mt76_dev *dev); 1497dacf0acfSSean Wang int mt76s_hw_init(struct mt76_dev *dev, struct sdio_func *func, 1498dacf0acfSSean Wang int hw_ver); 1499764dee47SLorenzo Bianconi u32 mt76s_rr(struct mt76_dev *dev, u32 offset); 1500764dee47SLorenzo Bianconi void mt76s_wr(struct mt76_dev *dev, u32 offset, u32 val); 1501764dee47SLorenzo Bianconi u32 mt76s_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val); 1502764dee47SLorenzo Bianconi u32 mt76s_read_pcr(struct mt76_dev *dev); 1503764dee47SLorenzo Bianconi void mt76s_write_copy(struct mt76_dev *dev, u32 offset, 1504764dee47SLorenzo Bianconi const void *data, int len); 1505764dee47SLorenzo Bianconi void mt76s_read_copy(struct mt76_dev *dev, u32 offset, 1506764dee47SLorenzo Bianconi void *data, int len); 1507764dee47SLorenzo Bianconi int mt76s_wr_rp(struct mt76_dev *dev, u32 base, 1508764dee47SLorenzo Bianconi const struct mt76_reg_pair *data, 1509764dee47SLorenzo Bianconi int len); 1510764dee47SLorenzo Bianconi int mt76s_rd_rp(struct mt76_dev *dev, u32 base, 1511764dee47SLorenzo Bianconi struct mt76_reg_pair *data, int len); 1512d39b52e3SSean Wang 15139df0fab9SLorenzo Bianconi struct sk_buff * 1514a0a2034eSLorenzo Bianconi __mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, 1515b146f238SLorenzo Bianconi int len, int data_len, gfp_t gfp); 1516a0a2034eSLorenzo Bianconi static inline struct sk_buff * 1517bb31a80eSLorenzo Bianconi mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, 1518a0a2034eSLorenzo Bianconi int data_len) 1519a0a2034eSLorenzo Bianconi { 1520b146f238SLorenzo Bianconi return __mt76_mcu_msg_alloc(dev, data, data_len, data_len, GFP_KERNEL); 1521a0a2034eSLorenzo Bianconi } 1522a0a2034eSLorenzo Bianconi 1523c07a49d4SLorenzo Bianconi void mt76_mcu_rx_event(struct mt76_dev *dev, struct sk_buff *skb); 1524680abb25SLorenzo Bianconi struct sk_buff *mt76_mcu_get_response(struct mt76_dev *dev, 1525680abb25SLorenzo Bianconi unsigned long expires); 1526ae5ad627SFelix Fietkau int mt76_mcu_send_and_get_msg(struct mt76_dev *dev, int cmd, const void *data, 1527ae5ad627SFelix Fietkau int len, bool wait_resp, struct sk_buff **ret); 1528ae5ad627SFelix Fietkau int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, 1529ae5ad627SFelix Fietkau int cmd, bool wait_resp, struct sk_buff **ret); 1530215a2efaSLorenzo Bianconi int __mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data, 1531215a2efaSLorenzo Bianconi int len, int max_len); 1532215a2efaSLorenzo Bianconi static inline int 1533215a2efaSLorenzo Bianconi mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data, 1534215a2efaSLorenzo Bianconi int len) 1535215a2efaSLorenzo Bianconi { 15365b8f1840SSean Wang int max_len = 4096 - dev->mcu_ops->headroom; 15375b8f1840SSean Wang 15385b8f1840SSean Wang return __mt76_mcu_send_firmware(dev, cmd, data, len, max_len); 1539215a2efaSLorenzo Bianconi } 1540215a2efaSLorenzo Bianconi 1541ae5ad627SFelix Fietkau static inline int 1542ae5ad627SFelix Fietkau mt76_mcu_send_msg(struct mt76_dev *dev, int cmd, const void *data, int len, 1543ae5ad627SFelix Fietkau bool wait_resp) 1544ae5ad627SFelix Fietkau { 1545ae5ad627SFelix Fietkau return mt76_mcu_send_and_get_msg(dev, cmd, data, len, wait_resp, NULL); 1546ae5ad627SFelix Fietkau } 1547ae5ad627SFelix Fietkau 1548ae5ad627SFelix Fietkau static inline int 1549ae5ad627SFelix Fietkau mt76_mcu_skb_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, 1550ae5ad627SFelix Fietkau bool wait_resp) 1551ae5ad627SFelix Fietkau { 1552ae5ad627SFelix Fietkau return mt76_mcu_skb_send_and_get_msg(dev, skb, cmd, wait_resp, NULL); 1553ae5ad627SFelix Fietkau } 15549df0fab9SLorenzo Bianconi 15559220f695SLorenzo Bianconi void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set); 15569220f695SLorenzo Bianconi 155709382d8fSMing Yen Hsieh struct device_node * 155809382d8fSMing Yen Hsieh mt76_find_power_limits_node(struct mt76_dev *dev); 155909382d8fSMing Yen Hsieh struct device_node * 156009382d8fSMing Yen Hsieh mt76_find_channel_node(struct device_node *np, struct ieee80211_channel *chan); 156109382d8fSMing Yen Hsieh 156222b980baSFelix Fietkau s8 mt76_get_rate_power_limits(struct mt76_phy *phy, 156322b980baSFelix Fietkau struct ieee80211_channel *chan, 156422b980baSFelix Fietkau struct mt76_power_limits *dest, 156522b980baSFelix Fietkau s8 target_power); 156622b980baSFelix Fietkau 1567132d74d3SLorenzo Bianconi static inline bool mt76_queue_is_wed_tx_free(struct mt76_queue *q) 1568132d74d3SLorenzo Bianconi { 1569132d74d3SLorenzo Bianconi return (q->flags & MT_QFLAG_WED) && 1570132d74d3SLorenzo Bianconi FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_TXFREE; 1571132d74d3SLorenzo Bianconi } 1572132d74d3SLorenzo Bianconi 157358bcd4edSLorenzo Bianconi static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q) 157458bcd4edSLorenzo Bianconi { 157558bcd4edSLorenzo Bianconi return (q->flags & MT_QFLAG_WED) && 157658bcd4edSLorenzo Bianconi FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX; 157758bcd4edSLorenzo Bianconi } 157858bcd4edSLorenzo Bianconi 1579d089692bSLorenzo Bianconi struct mt76_txwi_cache * 1580d089692bSLorenzo Bianconi mt76_token_release(struct mt76_dev *dev, int token, bool *wake); 1581d089692bSLorenzo Bianconi int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi); 1582d089692bSLorenzo Bianconi void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked); 15832666beceSSujuan Chen struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token); 15842666beceSSujuan Chen int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr, 15852666beceSSujuan Chen struct mt76_txwi_cache *r, dma_addr_t phys); 15862f5c3c77SLorenzo Bianconi int mt76_create_page_pool(struct mt76_dev *dev, struct mt76_queue *q); 15872f5c3c77SLorenzo Bianconi static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct) 15882f5c3c77SLorenzo Bianconi { 15892f5c3c77SLorenzo Bianconi struct page *page = virt_to_head_page(buf); 15902f5c3c77SLorenzo Bianconi 15912f5c3c77SLorenzo Bianconi page_pool_put_full_page(page->pp, page, allow_direct); 15922f5c3c77SLorenzo Bianconi } 15932f5c3c77SLorenzo Bianconi 15942f5c3c77SLorenzo Bianconi static inline void * 15952f5c3c77SLorenzo Bianconi mt76_get_page_pool_buf(struct mt76_queue *q, u32 *offset, u32 size) 15962f5c3c77SLorenzo Bianconi { 15972f5c3c77SLorenzo Bianconi struct page *page; 15982f5c3c77SLorenzo Bianconi 15992f5c3c77SLorenzo Bianconi page = page_pool_dev_alloc_frag(q->page_pool, offset, size); 16002f5c3c77SLorenzo Bianconi if (!page) 16012f5c3c77SLorenzo Bianconi return NULL; 16022f5c3c77SLorenzo Bianconi 16032f5c3c77SLorenzo Bianconi return page_address(page) + *offset; 16042f5c3c77SLorenzo Bianconi } 1605d089692bSLorenzo Bianconi 1606d089692bSLorenzo Bianconi static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked) 1607d089692bSLorenzo Bianconi { 1608d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1609d089692bSLorenzo Bianconi __mt76_set_tx_blocked(dev, blocked); 1610d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1611d089692bSLorenzo Bianconi } 1612d089692bSLorenzo Bianconi 1613d089692bSLorenzo Bianconi static inline int 1614d089692bSLorenzo Bianconi mt76_token_get(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi) 1615d089692bSLorenzo Bianconi { 1616d089692bSLorenzo Bianconi int token; 1617d089692bSLorenzo Bianconi 1618d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 161961b5156bSFelix Fietkau token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC); 1620d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1621d089692bSLorenzo Bianconi 1622d089692bSLorenzo Bianconi return token; 1623d089692bSLorenzo Bianconi } 1624d089692bSLorenzo Bianconi 1625d089692bSLorenzo Bianconi static inline struct mt76_txwi_cache * 1626d089692bSLorenzo Bianconi mt76_token_put(struct mt76_dev *dev, int token) 1627d089692bSLorenzo Bianconi { 1628d089692bSLorenzo Bianconi struct mt76_txwi_cache *txwi; 1629d089692bSLorenzo Bianconi 1630d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1631d089692bSLorenzo Bianconi txwi = idr_remove(&dev->token, token); 1632d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1633d089692bSLorenzo Bianconi 1634d089692bSLorenzo Bianconi return txwi; 1635d089692bSLorenzo Bianconi } 163690052b84SLorenzo Bianconi 16370335c034SFelix Fietkau void mt76_wcid_init(struct mt76_wcid *wcid); 16380335c034SFelix Fietkau void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid); 1639bd1e3e7bSLorenzo Bianconi 164017f1de56SFelix Fietkau #endif 1641