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> 1617f1de56SFelix Fietkau #include <net/mac80211.h> 1717f1de56SFelix Fietkau #include "util.h" 18f0efa862SFelix Fietkau #include "testmode.h" 1917f1de56SFelix Fietkau 2017f1de56SFelix Fietkau #define MT_MCU_RING_SIZE 32 2117f1de56SFelix Fietkau #define MT_RX_BUF_SIZE 2048 222a92b08bSLorenzo Bianconi #define MT_SKB_HEAD_LEN 128 2317f1de56SFelix Fietkau 24e1378e52SFelix Fietkau #define MT_MAX_NON_AQL_PKT 16 25e1378e52SFelix Fietkau #define MT_TXQ_FREE_THR 32 26e1378e52SFelix Fietkau 27d089692bSLorenzo Bianconi #define MT76_TOKEN_FREE_THR 64 28d089692bSLorenzo Bianconi 2917f1de56SFelix Fietkau struct mt76_dev; 3096747a51SFelix Fietkau struct mt76_phy; 31469d4818SLorenzo Bianconi struct mt76_wcid; 3217f1de56SFelix Fietkau 336da5a291SStanislaw Gruszka struct mt76_reg_pair { 346da5a291SStanislaw Gruszka u32 reg; 356da5a291SStanislaw Gruszka u32 value; 366da5a291SStanislaw Gruszka }; 376da5a291SStanislaw Gruszka 38c50479faSStanislaw Gruszka enum mt76_bus_type { 39c50479faSStanislaw Gruszka MT76_BUS_MMIO, 40c50479faSStanislaw Gruszka MT76_BUS_USB, 41d39b52e3SSean Wang MT76_BUS_SDIO, 42c50479faSStanislaw Gruszka }; 43c50479faSStanislaw Gruszka 4417f1de56SFelix Fietkau struct mt76_bus_ops { 4517f1de56SFelix Fietkau u32 (*rr)(struct mt76_dev *dev, u32 offset); 4617f1de56SFelix Fietkau void (*wr)(struct mt76_dev *dev, u32 offset, u32 val); 4717f1de56SFelix Fietkau u32 (*rmw)(struct mt76_dev *dev, u32 offset, u32 mask, u32 val); 4835e4ebeaSLorenzo Bianconi void (*write_copy)(struct mt76_dev *dev, u32 offset, const void *data, 4935e4ebeaSLorenzo Bianconi int len); 5035e4ebeaSLorenzo Bianconi void (*read_copy)(struct mt76_dev *dev, u32 offset, void *data, 5117f1de56SFelix Fietkau int len); 526da5a291SStanislaw Gruszka int (*wr_rp)(struct mt76_dev *dev, u32 base, 536da5a291SStanislaw Gruszka const struct mt76_reg_pair *rp, int len); 546da5a291SStanislaw Gruszka int (*rd_rp)(struct mt76_dev *dev, u32 base, 556da5a291SStanislaw Gruszka struct mt76_reg_pair *rp, int len); 56c50479faSStanislaw Gruszka enum mt76_bus_type type; 5717f1de56SFelix Fietkau }; 5817f1de56SFelix Fietkau 5961c51a74SLorenzo Bianconi #define mt76_is_usb(dev) ((dev)->bus->type == MT76_BUS_USB) 6061c51a74SLorenzo Bianconi #define mt76_is_mmio(dev) ((dev)->bus->type == MT76_BUS_MMIO) 61d39b52e3SSean Wang #define mt76_is_sdio(dev) ((dev)->bus->type == MT76_BUS_SDIO) 62c50479faSStanislaw Gruszka 6317f1de56SFelix Fietkau enum mt76_txq_id { 6417f1de56SFelix Fietkau MT_TXQ_VO = IEEE80211_AC_VO, 6517f1de56SFelix Fietkau MT_TXQ_VI = IEEE80211_AC_VI, 6617f1de56SFelix Fietkau MT_TXQ_BE = IEEE80211_AC_BE, 6717f1de56SFelix Fietkau MT_TXQ_BK = IEEE80211_AC_BK, 6817f1de56SFelix Fietkau MT_TXQ_PSD, 6917f1de56SFelix Fietkau MT_TXQ_BEACON, 7017f1de56SFelix Fietkau MT_TXQ_CAB, 7117f1de56SFelix Fietkau __MT_TXQ_MAX 7217f1de56SFelix Fietkau }; 7317f1de56SFelix Fietkau 74b1cb42adSLorenzo Bianconi enum mt76_mcuq_id { 75e637763bSLorenzo Bianconi MT_MCUQ_WM, 76e637763bSLorenzo Bianconi MT_MCUQ_WA, 77e637763bSLorenzo Bianconi MT_MCUQ_FWDL, 78b1cb42adSLorenzo Bianconi __MT_MCUQ_MAX 79b1cb42adSLorenzo Bianconi }; 80b1cb42adSLorenzo Bianconi 8117f1de56SFelix Fietkau enum mt76_rxq_id { 8217f1de56SFelix Fietkau MT_RXQ_MAIN, 8317f1de56SFelix Fietkau MT_RXQ_MCU, 84d3377b78SRyder Lee MT_RXQ_MCU_WA, 854c430774SLorenzo Bianconi MT_RXQ_EXT, 8676027f40SFelix Fietkau MT_RXQ_EXT_WA, 8717f1de56SFelix Fietkau __MT_RXQ_MAX 8817f1de56SFelix Fietkau }; 8917f1de56SFelix Fietkau 9017f1de56SFelix Fietkau struct mt76_queue_buf { 9117f1de56SFelix Fietkau dma_addr_t addr; 9227d5c528SFelix Fietkau u16 len; 9327d5c528SFelix Fietkau bool skip_unmap; 9417f1de56SFelix Fietkau }; 9517f1de56SFelix Fietkau 96b5903c47SLorenzo Bianconi struct mt76_tx_info { 97b5903c47SLorenzo Bianconi struct mt76_queue_buf buf[32]; 98cfaae9e6SLorenzo Bianconi struct sk_buff *skb; 99b5903c47SLorenzo Bianconi int nbuf; 100b5903c47SLorenzo Bianconi u32 info; 101b5903c47SLorenzo Bianconi }; 102b5903c47SLorenzo Bianconi 10317f1de56SFelix Fietkau struct mt76_queue_entry { 10417f1de56SFelix Fietkau union { 10517f1de56SFelix Fietkau void *buf; 10617f1de56SFelix Fietkau struct sk_buff *skb; 10717f1de56SFelix Fietkau }; 108b40b15e1SLorenzo Bianconi union { 10917f1de56SFelix Fietkau struct mt76_txwi_cache *txwi; 110d7d4ea9aSStanislaw Gruszka struct urb *urb; 111d39b52e3SSean Wang int buf_sz; 112b40b15e1SLorenzo Bianconi }; 11375d4bf1fSFelix Fietkau u32 dma_addr[2]; 11475d4bf1fSFelix Fietkau u16 dma_len[2]; 115e1378e52SFelix Fietkau u16 wcid; 1167bd0650bSLorenzo Bianconi bool skip_buf0:1; 11727d5c528SFelix Fietkau bool skip_buf1:1; 1187bd0650bSLorenzo Bianconi bool done:1; 11917f1de56SFelix Fietkau }; 12017f1de56SFelix Fietkau 12117f1de56SFelix Fietkau struct mt76_queue_regs { 12217f1de56SFelix Fietkau u32 desc_base; 12317f1de56SFelix Fietkau u32 ring_size; 12417f1de56SFelix Fietkau u32 cpu_idx; 12517f1de56SFelix Fietkau u32 dma_idx; 12617f1de56SFelix Fietkau } __packed __aligned(4); 12717f1de56SFelix Fietkau 12817f1de56SFelix Fietkau struct mt76_queue { 12917f1de56SFelix Fietkau struct mt76_queue_regs __iomem *regs; 13017f1de56SFelix Fietkau 13117f1de56SFelix Fietkau spinlock_t lock; 1329716ef04SFelix Fietkau spinlock_t cleanup_lock; 13317f1de56SFelix Fietkau struct mt76_queue_entry *entry; 13417f1de56SFelix Fietkau struct mt76_desc *desc; 13517f1de56SFelix Fietkau 136b40b15e1SLorenzo Bianconi u16 first; 13717f1de56SFelix Fietkau u16 head; 13817f1de56SFelix Fietkau u16 tail; 13917f1de56SFelix Fietkau int ndesc; 14017f1de56SFelix Fietkau int queued; 14117f1de56SFelix Fietkau int buf_size; 142cd44bc40SLorenzo Bianconi bool stopped; 14390d494c9SFelix Fietkau bool blocked; 14417f1de56SFelix Fietkau 14517f1de56SFelix Fietkau u8 buf_offset; 14617f1de56SFelix Fietkau u8 hw_idx; 147b671da33SLorenzo Bianconi u8 qid; 14817f1de56SFelix Fietkau 14917f1de56SFelix Fietkau dma_addr_t desc_dma; 15017f1de56SFelix Fietkau struct sk_buff *rx_head; 151c12128ceSFelix Fietkau struct page_frag_cache rx_page; 15217f1de56SFelix Fietkau }; 15317f1de56SFelix Fietkau 154db0f04f3SLorenzo Bianconi struct mt76_mcu_ops { 155bb31a80eSLorenzo Bianconi u32 headroom; 156bb31a80eSLorenzo Bianconi u32 tailroom; 157bb31a80eSLorenzo Bianconi 158a74d6336SStanislaw Gruszka int (*mcu_send_msg)(struct mt76_dev *dev, int cmd, const void *data, 159a74d6336SStanislaw Gruszka int len, bool wait_resp); 160f4d45fe2SLorenzo Bianconi int (*mcu_skb_send_msg)(struct mt76_dev *dev, struct sk_buff *skb, 161e452c6ebSFelix Fietkau int cmd, int *seq); 162f320d812SFelix Fietkau int (*mcu_parse_response)(struct mt76_dev *dev, int cmd, 163f320d812SFelix Fietkau struct sk_buff *skb, int seq); 164d39b52e3SSean Wang u32 (*mcu_rr)(struct mt76_dev *dev, u32 offset); 165d39b52e3SSean Wang void (*mcu_wr)(struct mt76_dev *dev, u32 offset, u32 val); 1666da5a291SStanislaw Gruszka int (*mcu_wr_rp)(struct mt76_dev *dev, u32 base, 1676da5a291SStanislaw Gruszka const struct mt76_reg_pair *rp, int len); 1686da5a291SStanislaw Gruszka int (*mcu_rd_rp)(struct mt76_dev *dev, u32 base, 1696da5a291SStanislaw Gruszka struct mt76_reg_pair *rp, int len); 17000496042SFelix Fietkau int (*mcu_restart)(struct mt76_dev *dev); 171db0f04f3SLorenzo Bianconi }; 172db0f04f3SLorenzo Bianconi 17317f1de56SFelix Fietkau struct mt76_queue_ops { 174cb8ed33dSLorenzo Bianconi int (*init)(struct mt76_dev *dev, 175cb8ed33dSLorenzo Bianconi int (*poll)(struct napi_struct *napi, int budget)); 17617f1de56SFelix Fietkau 177b1bfbe70SLorenzo Bianconi int (*alloc)(struct mt76_dev *dev, struct mt76_queue *q, 178b1bfbe70SLorenzo Bianconi int idx, int n_desc, int bufsize, 179b1bfbe70SLorenzo Bianconi u32 ring_base); 18017f1de56SFelix Fietkau 18189870594SLorenzo Bianconi int (*tx_queue_skb)(struct mt76_dev *dev, struct mt76_queue *q, 182469d4818SLorenzo Bianconi struct sk_buff *skb, struct mt76_wcid *wcid, 183469d4818SLorenzo Bianconi struct ieee80211_sta *sta); 184469d4818SLorenzo Bianconi 185d95093a1SLorenzo Bianconi int (*tx_queue_skb_raw)(struct mt76_dev *dev, struct mt76_queue *q, 1865ed31128SLorenzo Bianconi struct sk_buff *skb, u32 tx_info); 1875ed31128SLorenzo Bianconi 18817f1de56SFelix Fietkau void *(*dequeue)(struct mt76_dev *dev, struct mt76_queue *q, bool flush, 18917f1de56SFelix Fietkau int *len, u32 *info, bool *more); 19017f1de56SFelix Fietkau 19117f1de56SFelix Fietkau void (*rx_reset)(struct mt76_dev *dev, enum mt76_rxq_id qid); 19217f1de56SFelix Fietkau 193e5655492SLorenzo Bianconi void (*tx_cleanup)(struct mt76_dev *dev, struct mt76_queue *q, 19417f1de56SFelix Fietkau bool flush); 19517f1de56SFelix Fietkau 196c001df97SLorenzo Bianconi void (*rx_cleanup)(struct mt76_dev *dev, struct mt76_queue *q); 197c001df97SLorenzo Bianconi 19817f1de56SFelix Fietkau void (*kick)(struct mt76_dev *dev, struct mt76_queue *q); 1993990465dSLorenzo Bianconi 2003990465dSLorenzo Bianconi void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q); 20117f1de56SFelix Fietkau }; 20217f1de56SFelix Fietkau 203d71ef286SFelix Fietkau enum mt76_wcid_flags { 204d71ef286SFelix Fietkau MT_WCID_FLAG_CHECK_PS, 205d71ef286SFelix Fietkau MT_WCID_FLAG_PS, 206e151d71eSFelix Fietkau MT_WCID_FLAG_4ADDR, 20790e3abf0SFelix Fietkau MT_WCID_FLAG_HDR_TRANS, 208d71ef286SFelix Fietkau }; 209d71ef286SFelix Fietkau 21049e649c3SRyder Lee #define MT76_N_WCIDS 288 21136404c06SStanislaw Gruszka 212e394b575SFelix Fietkau /* stored in ieee80211_tx_info::hw_queue */ 213e394b575SFelix Fietkau #define MT_TX_HW_QUEUE_EXT_PHY BIT(3) 214e394b575SFelix Fietkau 215ef13edc0SFelix Fietkau DECLARE_EWMA(signal, 10, 8); 216ef13edc0SFelix Fietkau 217db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_RATE GENMASK(15, 0) 218db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_NSS GENMASK(17, 16) 219db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_TXPWR_ADJ GENMASK(25, 18) 220db9f11d3SFelix Fietkau #define MT_WCID_TX_INFO_SET BIT(31) 221db9f11d3SFelix Fietkau 22217f1de56SFelix Fietkau struct mt76_wcid { 223aee5b8cfSFelix Fietkau struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS]; 224aee5b8cfSFelix Fietkau 225e1378e52SFelix Fietkau atomic_t non_aql_packets; 226d71ef286SFelix Fietkau unsigned long flags; 227d71ef286SFelix Fietkau 228ef13edc0SFelix Fietkau struct ewma_signal rssi; 229ef13edc0SFelix Fietkau int inactive_count; 230ef13edc0SFelix Fietkau 23149e649c3SRyder Lee u16 idx; 23217f1de56SFelix Fietkau u8 hw_key_idx; 233730d6d0dSFelix Fietkau u8 hw_key_idx2; 23417f1de56SFelix Fietkau 2359c68a57bSFelix Fietkau u8 sta:1; 236c7d2d631SFelix Fietkau u8 ext_phy:1; 237b443e55fSRyder Lee u8 amsdu:1; 2389c68a57bSFelix Fietkau 23930ce7f44SFelix Fietkau u8 rx_check_pn; 24030ce7f44SFelix Fietkau u8 rx_key_pn[IEEE80211_NUM_TIDS][6]; 24101cfc1b4SLorenzo Bianconi u16 cipher; 24230ce7f44SFelix Fietkau 243db9f11d3SFelix Fietkau u32 tx_info; 24423405236SFelix Fietkau bool sw_iv; 24588046b2cSFelix Fietkau 24688046b2cSFelix Fietkau u8 packet_id; 24717f1de56SFelix Fietkau }; 24817f1de56SFelix Fietkau 24917f1de56SFelix Fietkau struct mt76_txq { 25017f1de56SFelix Fietkau struct mt76_wcid *wcid; 25117f1de56SFelix Fietkau 25217f1de56SFelix Fietkau u16 agg_ssn; 25317f1de56SFelix Fietkau bool send_bar; 25417f1de56SFelix Fietkau bool aggr; 25517f1de56SFelix Fietkau }; 25617f1de56SFelix Fietkau 25717f1de56SFelix Fietkau struct mt76_txwi_cache { 25817f1de56SFelix Fietkau struct list_head list; 259f3950a41SLorenzo Bianconi dma_addr_t dma_addr; 2606ca66722SLorenzo Bianconi 2616ca66722SLorenzo Bianconi struct sk_buff *skb; 26217f1de56SFelix Fietkau }; 26317f1de56SFelix Fietkau 264aee5b8cfSFelix Fietkau struct mt76_rx_tid { 265aee5b8cfSFelix Fietkau struct rcu_head rcu_head; 266aee5b8cfSFelix Fietkau 267aee5b8cfSFelix Fietkau struct mt76_dev *dev; 268aee5b8cfSFelix Fietkau 269aee5b8cfSFelix Fietkau spinlock_t lock; 270aee5b8cfSFelix Fietkau struct delayed_work reorder_work; 271aee5b8cfSFelix Fietkau 272aee5b8cfSFelix Fietkau u16 head; 2737c4f744dSRyder Lee u16 size; 2747c4f744dSRyder Lee u16 nframes; 275aee5b8cfSFelix Fietkau 276e7ec563eSMarkus Theil u8 num; 277e7ec563eSMarkus Theil 278aee5b8cfSFelix Fietkau u8 started:1, stopped:1, timer_pending:1; 279aee5b8cfSFelix Fietkau 280aee5b8cfSFelix Fietkau struct sk_buff *reorder_buf[]; 281aee5b8cfSFelix Fietkau }; 282aee5b8cfSFelix Fietkau 28388046b2cSFelix Fietkau #define MT_TX_CB_DMA_DONE BIT(0) 28488046b2cSFelix Fietkau #define MT_TX_CB_TXS_DONE BIT(1) 28588046b2cSFelix Fietkau #define MT_TX_CB_TXS_FAILED BIT(2) 28688046b2cSFelix Fietkau 2878548c6ebSFelix Fietkau #define MT_PACKET_ID_MASK GENMASK(6, 0) 288013b2dffSFelix Fietkau #define MT_PACKET_ID_NO_ACK 0 289013b2dffSFelix Fietkau #define MT_PACKET_ID_NO_SKB 1 290013b2dffSFelix Fietkau #define MT_PACKET_ID_FIRST 2 2918548c6ebSFelix Fietkau #define MT_PACKET_ID_HAS_RATE BIT(7) 29288046b2cSFelix Fietkau 29388046b2cSFelix Fietkau #define MT_TX_STATUS_SKB_TIMEOUT HZ 29488046b2cSFelix Fietkau 29588046b2cSFelix Fietkau struct mt76_tx_cb { 29688046b2cSFelix Fietkau unsigned long jiffies; 29749e649c3SRyder Lee u16 wcid; 29888046b2cSFelix Fietkau u8 pktid; 29988046b2cSFelix Fietkau u8 flags; 30088046b2cSFelix Fietkau }; 30188046b2cSFelix Fietkau 30217f1de56SFelix Fietkau enum { 30317f1de56SFelix Fietkau MT76_STATE_INITIALIZED, 30417f1de56SFelix Fietkau MT76_STATE_RUNNING, 30587e022deSStanislaw Gruszka MT76_STATE_MCU_RUNNING, 30617f1de56SFelix Fietkau MT76_SCANNING, 307fcdfc29eSLorenzo Bianconi MT76_HW_SCANNING, 30820305f98SLorenzo Bianconi MT76_HW_SCHED_SCANNING, 309fd6c2dfaSFelix Fietkau MT76_RESTART, 31017f1de56SFelix Fietkau MT76_RESET, 31161c4fa72SFelix Fietkau MT76_MCU_RESET, 312b40b15e1SLorenzo Bianconi MT76_REMOVED, 313b40b15e1SLorenzo Bianconi MT76_READING_STATS, 314eb99cc95SLorenzo Bianconi MT76_STATE_POWER_OFF, 315c6bf2010SLorenzo Bianconi MT76_STATE_SUSPEND, 3167307f296SLorenzo Bianconi MT76_STATE_ROC, 31708523a2aSLorenzo Bianconi MT76_STATE_PM, 31817f1de56SFelix Fietkau }; 31917f1de56SFelix Fietkau 32017f1de56SFelix Fietkau struct mt76_hw_cap { 32117f1de56SFelix Fietkau bool has_2ghz; 32217f1de56SFelix Fietkau bool has_5ghz; 323f7d2958cSLorenzo Bianconi bool has_6ghz; 32417f1de56SFelix Fietkau }; 32517f1de56SFelix Fietkau 3269ec0b821SFelix Fietkau #define MT_DRV_TXWI_NO_FREE BIT(0) 3279ec0b821SFelix Fietkau #define MT_DRV_TX_ALIGNED4_SKBS BIT(1) 3285ce09c1aSFelix Fietkau #define MT_DRV_SW_RX_AIRTIME BIT(2) 32994d4d076SLorenzo Bianconi #define MT_DRV_RX_DMA_HDR BIT(3) 330d3c82998SLorenzo Bianconi #define MT_DRV_HW_MGMT_TXQ BIT(4) 331b443e55fSRyder Lee #define MT_DRV_AMSDU_OFFLOAD BIT(5) 3326ca66722SLorenzo Bianconi 33317f1de56SFelix Fietkau struct mt76_driver_ops { 3349ec0b821SFelix Fietkau u32 drv_flags; 335ea565833SFelix Fietkau u32 survey_flags; 33617f1de56SFelix Fietkau u16 txwi_size; 337d089692bSLorenzo Bianconi u16 token_size; 33822b980baSFelix Fietkau u8 mcs_rates; 33917f1de56SFelix Fietkau 34017f1de56SFelix Fietkau void (*update_survey)(struct mt76_dev *dev); 34117f1de56SFelix Fietkau 34217f1de56SFelix Fietkau int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr, 343cfaae9e6SLorenzo Bianconi enum mt76_txq_id qid, struct mt76_wcid *wcid, 344b5903c47SLorenzo Bianconi struct ieee80211_sta *sta, 345b5903c47SLorenzo Bianconi struct mt76_tx_info *tx_info); 34617f1de56SFelix Fietkau 347d80e52c7SFelix Fietkau void (*tx_complete_skb)(struct mt76_dev *dev, 348e226ba2eSLorenzo Bianconi struct mt76_queue_entry *e); 34917f1de56SFelix Fietkau 350b40b15e1SLorenzo Bianconi bool (*tx_status_data)(struct mt76_dev *dev, u8 *update); 351b40b15e1SLorenzo Bianconi 35217f1de56SFelix Fietkau void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q, 35317f1de56SFelix Fietkau struct sk_buff *skb); 35417f1de56SFelix Fietkau 35517f1de56SFelix Fietkau void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q); 356d71ef286SFelix Fietkau 357d71ef286SFelix Fietkau void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta, 358d71ef286SFelix Fietkau bool ps); 359e28487eaSFelix Fietkau 360e28487eaSFelix Fietkau int (*sta_add)(struct mt76_dev *dev, struct ieee80211_vif *vif, 361e28487eaSFelix Fietkau struct ieee80211_sta *sta); 362e28487eaSFelix Fietkau 3639c193de5SFelix Fietkau void (*sta_assoc)(struct mt76_dev *dev, struct ieee80211_vif *vif, 3649c193de5SFelix Fietkau struct ieee80211_sta *sta); 3659c193de5SFelix Fietkau 366e28487eaSFelix Fietkau void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif, 367e28487eaSFelix Fietkau struct ieee80211_sta *sta); 36817f1de56SFelix Fietkau }; 36917f1de56SFelix Fietkau 37017f1de56SFelix Fietkau struct mt76_channel_state { 37117f1de56SFelix Fietkau u64 cc_active; 37217f1de56SFelix Fietkau u64 cc_busy; 3736bfa6e38SLorenzo Bianconi u64 cc_rx; 3745ce09c1aSFelix Fietkau u64 cc_bss_rx; 375ea565833SFelix Fietkau u64 cc_tx; 376e5051965SFelix Fietkau 377e5051965SFelix Fietkau s8 noise; 37817f1de56SFelix Fietkau }; 37917f1de56SFelix Fietkau 38017f1de56SFelix Fietkau struct mt76_sband { 38117f1de56SFelix Fietkau struct ieee80211_supported_band sband; 38217f1de56SFelix Fietkau struct mt76_channel_state *chan; 38317f1de56SFelix Fietkau }; 38417f1de56SFelix Fietkau 385b6862effSLorenzo Bianconi struct mt76_rate_power { 386b6862effSLorenzo Bianconi union { 387b6862effSLorenzo Bianconi struct { 388b6862effSLorenzo Bianconi s8 cck[4]; 389b6862effSLorenzo Bianconi s8 ofdm[8]; 390b6862effSLorenzo Bianconi s8 stbc[10]; 391b6862effSLorenzo Bianconi s8 ht[16]; 392b6862effSLorenzo Bianconi s8 vht[10]; 393b6862effSLorenzo Bianconi }; 394b6862effSLorenzo Bianconi s8 all[48]; 395b6862effSLorenzo Bianconi }; 396b6862effSLorenzo Bianconi }; 397b6862effSLorenzo Bianconi 398b40b15e1SLorenzo Bianconi /* addr req mask */ 399b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_EEPROM BIT(31) 400b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_CFG BIT(30) 401b40b15e1SLorenzo Bianconi #define MT_VEND_TYPE_MASK (MT_VEND_TYPE_EEPROM | MT_VEND_TYPE_CFG) 402b40b15e1SLorenzo Bianconi 403b40b15e1SLorenzo Bianconi #define MT_VEND_ADDR(type, n) (MT_VEND_TYPE_##type | (n)) 404b40b15e1SLorenzo Bianconi enum mt_vendor_req { 405b40b15e1SLorenzo Bianconi MT_VEND_DEV_MODE = 0x1, 406b40b15e1SLorenzo Bianconi MT_VEND_WRITE = 0x2, 4071e816c65SLorenzo Bianconi MT_VEND_POWER_ON = 0x4, 408b40b15e1SLorenzo Bianconi MT_VEND_MULTI_WRITE = 0x6, 409b40b15e1SLorenzo Bianconi MT_VEND_MULTI_READ = 0x7, 410b40b15e1SLorenzo Bianconi MT_VEND_READ_EEPROM = 0x9, 411b40b15e1SLorenzo Bianconi MT_VEND_WRITE_FCE = 0x42, 412b40b15e1SLorenzo Bianconi MT_VEND_WRITE_CFG = 0x46, 413b40b15e1SLorenzo Bianconi MT_VEND_READ_CFG = 0x47, 4141e816c65SLorenzo Bianconi MT_VEND_READ_EXT = 0x63, 4151e816c65SLorenzo Bianconi MT_VEND_WRITE_EXT = 0x66, 416d0846f08SSean Wang MT_VEND_FEATURE_SET = 0x91, 417b40b15e1SLorenzo Bianconi }; 418b40b15e1SLorenzo Bianconi 419b40b15e1SLorenzo Bianconi enum mt76u_in_ep { 420b40b15e1SLorenzo Bianconi MT_EP_IN_PKT_RX, 421b40b15e1SLorenzo Bianconi MT_EP_IN_CMD_RESP, 422b40b15e1SLorenzo Bianconi __MT_EP_IN_MAX, 423b40b15e1SLorenzo Bianconi }; 424b40b15e1SLorenzo Bianconi 425b40b15e1SLorenzo Bianconi enum mt76u_out_ep { 426b40b15e1SLorenzo Bianconi MT_EP_OUT_INBAND_CMD, 427b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_BE, 42823cb16d2SLorenzo Bianconi MT_EP_OUT_AC_BK, 429b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_VI, 430b40b15e1SLorenzo Bianconi MT_EP_OUT_AC_VO, 431b40b15e1SLorenzo Bianconi MT_EP_OUT_HCCA, 432b40b15e1SLorenzo Bianconi __MT_EP_OUT_MAX, 433b40b15e1SLorenzo Bianconi }; 434b40b15e1SLorenzo Bianconi 43509872957SLorenzo Bianconi struct mt76_mcu { 43609872957SLorenzo Bianconi struct mutex mutex; 43709872957SLorenzo Bianconi u32 msg_seq; 438e452c6ebSFelix Fietkau int timeout; 43909872957SLorenzo Bianconi 44009872957SLorenzo Bianconi struct sk_buff_head res_q; 44109872957SLorenzo Bianconi wait_queue_head_t wait; 44209872957SLorenzo Bianconi }; 44309872957SLorenzo Bianconi 44414663f0cSLorenzo Bianconi #define MT_TX_SG_MAX_SIZE 8 445972c5981SSean Wang #define MT_RX_SG_MAX_SIZE 4 446b40b15e1SLorenzo Bianconi #define MT_NUM_TX_ENTRIES 256 447b40b15e1SLorenzo Bianconi #define MT_NUM_RX_ENTRIES 128 448b40b15e1SLorenzo Bianconi #define MCU_RESP_URB_SIZE 1024 449b40b15e1SLorenzo Bianconi struct mt76_usb { 450b40b15e1SLorenzo Bianconi struct mutex usb_ctrl_mtx; 451a6bfb6d1SStanislaw Gruszka u8 *data; 452a6bfb6d1SStanislaw Gruszka u16 data_len; 453b40b15e1SLorenzo Bianconi 4549daf27e6SLorenzo Bianconi struct mt76_worker status_worker; 455be83a7e2SLorenzo Bianconi struct mt76_worker rx_worker; 4569daf27e6SLorenzo Bianconi 457284efb47SLorenzo Bianconi struct work_struct stat_work; 458b40b15e1SLorenzo Bianconi 459b40b15e1SLorenzo Bianconi u8 out_ep[__MT_EP_OUT_MAX]; 460b40b15e1SLorenzo Bianconi u8 in_ep[__MT_EP_IN_MAX]; 46163a7de5dSLorenzo Bianconi bool sg_en; 462b40b15e1SLorenzo Bianconi 463b40b15e1SLorenzo Bianconi struct mt76u_mcu { 464a18a494fSStanislaw Gruszka u8 *data; 465851ab66eSLorenzo Bianconi /* multiple reads */ 466851ab66eSLorenzo Bianconi struct mt76_reg_pair *rp; 467851ab66eSLorenzo Bianconi int rp_len; 468851ab66eSLorenzo Bianconi u32 base; 469851ab66eSLorenzo Bianconi bool burst; 470b40b15e1SLorenzo Bianconi } mcu; 471b40b15e1SLorenzo Bianconi }; 472b40b15e1SLorenzo Bianconi 4731522ff73SLorenzo Bianconi #define MT76S_XMIT_BUF_SZ (16 * PAGE_SIZE) 474d39b52e3SSean Wang struct mt76_sdio { 475fefb584dSLorenzo Bianconi struct mt76_worker txrx_worker; 4766a618acbSLorenzo Bianconi struct mt76_worker status_worker; 4776a618acbSLorenzo Bianconi struct mt76_worker net_worker; 4786a618acbSLorenzo Bianconi 479d74fda4cSLorenzo Bianconi struct work_struct stat_work; 480974327a4SLorenzo Bianconi 481264b7b19SLorenzo Bianconi u8 *xmit_buf[IEEE80211_NUM_ACS + 2]; 4821522ff73SLorenzo Bianconi 483d39b52e3SSean Wang struct sdio_func *func; 484b4964908SSean Wang void *intr_data; 485d39b52e3SSean Wang 486d39b52e3SSean Wang struct { 487d39b52e3SSean Wang int pse_data_quota; 488d39b52e3SSean Wang int ple_data_quota; 489d39b52e3SSean Wang int pse_mcu_quota; 490d39b52e3SSean Wang int deficit; 491d39b52e3SSean Wang } sched; 492d39b52e3SSean Wang }; 493d39b52e3SSean Wang 494f7bbb80fSLorenzo Bianconi struct mt76_mmio { 49527db1ad1SLorenzo Bianconi void __iomem *regs; 496957068c2SLorenzo Bianconi spinlock_t irq_lock; 497957068c2SLorenzo Bianconi u32 irqmask; 498f7bbb80fSLorenzo Bianconi }; 499f7bbb80fSLorenzo Bianconi 5005ce09c1aSFelix Fietkau struct mt76_rx_status { 5015ce09c1aSFelix Fietkau union { 5025ce09c1aSFelix Fietkau struct mt76_wcid *wcid; 50349e649c3SRyder Lee u16 wcid_idx; 5045ce09c1aSFelix Fietkau }; 5055ce09c1aSFelix Fietkau 5060fda6d7bSRyder Lee u32 reorder_time; 5075ce09c1aSFelix Fietkau 5085ce09c1aSFelix Fietkau u32 ampdu_ref; 5090fda6d7bSRyder Lee u32 timestamp; 5105ce09c1aSFelix Fietkau 5115ce09c1aSFelix Fietkau u8 iv[6]; 5125ce09c1aSFelix Fietkau 513bfc394ddSFelix Fietkau u8 ext_phy:1; 5145ce09c1aSFelix Fietkau u8 aggr:1; 515e195dad1SFelix Fietkau u8 qos_ctl; 5165ce09c1aSFelix Fietkau u16 seqno; 5175ce09c1aSFelix Fietkau 5185ce09c1aSFelix Fietkau u16 freq; 5195ce09c1aSFelix Fietkau u32 flag; 5205ce09c1aSFelix Fietkau u8 enc_flags; 521af4a2f2fSRyder Lee u8 encoding:2, bw:3, he_ru:3; 522af4a2f2fSRyder Lee u8 he_gi:2, he_dcm:1; 523cc4b3c13SLorenzo Bianconi u8 amsdu:1, first_amsdu:1, last_amsdu:1; 5245ce09c1aSFelix Fietkau u8 rate_idx; 5255ce09c1aSFelix Fietkau u8 nss; 5265ce09c1aSFelix Fietkau u8 band; 5275ce09c1aSFelix Fietkau s8 signal; 5285ce09c1aSFelix Fietkau u8 chains; 5295ce09c1aSFelix Fietkau s8 chain_signal[IEEE80211_MAX_CHAINS]; 5305ce09c1aSFelix Fietkau }; 5315ce09c1aSFelix Fietkau 532f0efa862SFelix Fietkau struct mt76_testmode_ops { 533c918c74dSShayne Chen int (*set_state)(struct mt76_phy *phy, enum mt76_testmode_state state); 534c918c74dSShayne Chen int (*set_params)(struct mt76_phy *phy, struct nlattr **tb, 535f0efa862SFelix Fietkau enum mt76_testmode_state new_state); 536c918c74dSShayne Chen int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg); 537f0efa862SFelix Fietkau }; 538f0efa862SFelix Fietkau 539f0efa862SFelix Fietkau struct mt76_testmode_data { 540f0efa862SFelix Fietkau enum mt76_testmode_state state; 541f0efa862SFelix Fietkau 542f0efa862SFelix Fietkau u32 param_set[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)]; 543f0efa862SFelix Fietkau struct sk_buff *tx_skb; 544f0efa862SFelix Fietkau 545f0efa862SFelix Fietkau u32 tx_count; 5462601dda8SShayne Chen u16 tx_mpdu_len; 547f0efa862SFelix Fietkau 548f0efa862SFelix Fietkau u8 tx_rate_mode; 549f0efa862SFelix Fietkau u8 tx_rate_idx; 550f0efa862SFelix Fietkau u8 tx_rate_nss; 551f0efa862SFelix Fietkau u8 tx_rate_sgi; 552f0efa862SFelix Fietkau u8 tx_rate_ldpc; 5537f54c742SShayne Chen u8 tx_rate_stbc; 5541a38c2f5SShayne Chen u8 tx_ltf; 555f0efa862SFelix Fietkau 556f0efa862SFelix Fietkau u8 tx_antenna_mask; 557fdc9c18eSShayne Chen u8 tx_spe_idx; 558f0efa862SFelix Fietkau 559b8cbdb97SShayne Chen u8 tx_duty_cycle; 560b8cbdb97SShayne Chen u32 tx_time; 561b8cbdb97SShayne Chen u32 tx_ipg; 562b8cbdb97SShayne Chen 563f0efa862SFelix Fietkau u32 freq_offset; 564f0efa862SFelix Fietkau 565f0efa862SFelix Fietkau u8 tx_power[4]; 566f0efa862SFelix Fietkau u8 tx_power_control; 567f0efa862SFelix Fietkau 568f0efa862SFelix Fietkau u32 tx_pending; 569f0efa862SFelix Fietkau u32 tx_queued; 570ba459094SShayne Chen u16 tx_queued_limit; 571f0efa862SFelix Fietkau u32 tx_done; 572f0efa862SFelix Fietkau struct { 573f0efa862SFelix Fietkau u64 packets[__MT_RXQ_MAX]; 574f0efa862SFelix Fietkau u64 fcs_error[__MT_RXQ_MAX]; 575f0efa862SFelix Fietkau } rx_stats; 576f0efa862SFelix Fietkau }; 577f0efa862SFelix Fietkau 57885d96704SLorenzo Bianconi struct mt76_vif { 57985d96704SLorenzo Bianconi u8 idx; 58085d96704SLorenzo Bianconi u8 omac_idx; 58185d96704SLorenzo Bianconi u8 band_idx; 58285d96704SLorenzo Bianconi u8 wmm_idx; 58385d96704SLorenzo Bianconi u8 scan_seq_num; 58485d96704SLorenzo Bianconi }; 58585d96704SLorenzo Bianconi 586ac24dd35SFelix Fietkau struct mt76_phy { 587ac24dd35SFelix Fietkau struct ieee80211_hw *hw; 588ac24dd35SFelix Fietkau struct mt76_dev *dev; 589a3d01038SFelix Fietkau void *priv; 59096747a51SFelix Fietkau 591011849e0SFelix Fietkau unsigned long state; 592011849e0SFelix Fietkau 59391990519SLorenzo Bianconi struct mt76_queue *q_tx[__MT_TXQ_MAX]; 59491990519SLorenzo Bianconi 59596747a51SFelix Fietkau struct cfg80211_chan_def chandef; 59696747a51SFelix Fietkau struct ieee80211_channel *main_chan; 59796747a51SFelix Fietkau 59896747a51SFelix Fietkau struct mt76_channel_state *chan_state; 59996747a51SFelix Fietkau ktime_t survey_time; 60096747a51SFelix Fietkau 60148dbce5cSLorenzo Bianconi struct mt76_hw_cap cap; 60296747a51SFelix Fietkau struct mt76_sband sband_2g; 60396747a51SFelix Fietkau struct mt76_sband sband_5g; 604beaaeb6bSFelix Fietkau 60598df2baeSLorenzo Bianconi u8 macaddr[ETH_ALEN]; 60698df2baeSLorenzo Bianconi 607beaaeb6bSFelix Fietkau int txpower_cur; 608beaaeb6bSFelix Fietkau u8 antenna_mask; 609b9027e08SLorenzo Bianconi u16 chainmask; 610c918c74dSShayne Chen 611c918c74dSShayne Chen #ifdef CONFIG_NL80211_TESTMODE 612c918c74dSShayne Chen struct mt76_testmode_data test; 613c918c74dSShayne Chen #endif 614a782f8bfSLorenzo Bianconi 615a782f8bfSLorenzo Bianconi struct delayed_work mac_work; 616a782f8bfSLorenzo Bianconi u8 mac_work_count; 617cc4b3c13SLorenzo Bianconi 618cc4b3c13SLorenzo Bianconi struct { 619cc4b3c13SLorenzo Bianconi struct sk_buff *head; 620cc4b3c13SLorenzo Bianconi struct sk_buff **tail; 621cc4b3c13SLorenzo Bianconi u16 seqno; 622cc4b3c13SLorenzo Bianconi } rx_amsdu[__MT_RXQ_MAX]; 623ac24dd35SFelix Fietkau }; 624ac24dd35SFelix Fietkau 62517f1de56SFelix Fietkau struct mt76_dev { 626ac24dd35SFelix Fietkau struct mt76_phy phy; /* must be first */ 627ac24dd35SFelix Fietkau 628bfc394ddSFelix Fietkau struct mt76_phy *phy2; 629bfc394ddSFelix Fietkau 63017f1de56SFelix Fietkau struct ieee80211_hw *hw; 63117f1de56SFelix Fietkau 63217f1de56SFelix Fietkau spinlock_t lock; 63317f1de56SFelix Fietkau spinlock_t cc_lock; 634108a4861SStanislaw Gruszka 6355ce09c1aSFelix Fietkau u32 cur_cc_bss_rx; 6365ce09c1aSFelix Fietkau 6375ce09c1aSFelix Fietkau struct mt76_rx_status rx_ampdu_status; 6385ce09c1aSFelix Fietkau u32 rx_ampdu_len; 6395ce09c1aSFelix Fietkau u32 rx_ampdu_ref; 6405ce09c1aSFelix Fietkau 641108a4861SStanislaw Gruszka struct mutex mutex; 642108a4861SStanislaw Gruszka 64317f1de56SFelix Fietkau const struct mt76_bus_ops *bus; 64417f1de56SFelix Fietkau const struct mt76_driver_ops *drv; 645db0f04f3SLorenzo Bianconi const struct mt76_mcu_ops *mcu_ops; 64617f1de56SFelix Fietkau struct device *dev; 64717f1de56SFelix Fietkau 64809872957SLorenzo Bianconi struct mt76_mcu mcu; 64909872957SLorenzo Bianconi 65017f1de56SFelix Fietkau struct net_device napi_dev; 651aa40528aSFelix Fietkau struct net_device tx_napi_dev; 652c3d7c82aSFelix Fietkau spinlock_t rx_lock; 65317f1de56SFelix Fietkau struct napi_struct napi[__MT_RXQ_MAX]; 65417f1de56SFelix Fietkau struct sk_buff_head rx_skb[__MT_RXQ_MAX]; 65517f1de56SFelix Fietkau 65617f1de56SFelix Fietkau struct list_head txwi_cache; 657b1cb42adSLorenzo Bianconi struct mt76_queue *q_mcu[__MT_MCUQ_MAX]; 65817f1de56SFelix Fietkau struct mt76_queue q_rx[__MT_RXQ_MAX]; 65917f1de56SFelix Fietkau const struct mt76_queue_ops *queue_ops; 660c1e0d2beSLorenzo Bianconi int tx_dma_idx[4]; 66117f1de56SFelix Fietkau 662781eef5bSFelix Fietkau struct mt76_worker tx_worker; 6638402650aSLorenzo Bianconi struct napi_struct tx_napi; 664a33b8ab8SFelix Fietkau 665b17aff33SLorenzo Bianconi spinlock_t token_lock; 666b17aff33SLorenzo Bianconi struct idr token; 667b17aff33SLorenzo Bianconi int token_count; 668b17aff33SLorenzo Bianconi 66926e40d4cSFelix Fietkau wait_queue_head_t tx_wait; 67088046b2cSFelix Fietkau struct sk_buff_head status_list; 67126e40d4cSFelix Fietkau 6725e616ad2SFelix Fietkau u32 wcid_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; 6735e616ad2SFelix Fietkau u32 wcid_phy_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; 67436404c06SStanislaw Gruszka 6752ab33b8dSFelix Fietkau u32 vif_mask; 6762ab33b8dSFelix Fietkau 67736404c06SStanislaw Gruszka struct mt76_wcid global_wcid; 67836404c06SStanislaw Gruszka struct mt76_wcid __rcu *wcid[MT76_N_WCIDS]; 67936404c06SStanislaw Gruszka 68017f1de56SFelix Fietkau u32 rev; 68117f1de56SFelix Fietkau 682d7b47bbdSLorenzo Bianconi u32 aggr_stats[32]; 683d7b47bbdSLorenzo Bianconi 684dc6057f4SLorenzo Bianconi struct tasklet_struct pre_tbtt_tasklet; 6853041c445SLorenzo Bianconi int beacon_int; 686c8a04d98SLorenzo Bianconi u8 beacon_mask; 6873041c445SLorenzo Bianconi 68817f1de56SFelix Fietkau struct debugfs_blob_wrapper eeprom; 68917f1de56SFelix Fietkau struct debugfs_blob_wrapper otp; 69017f1de56SFelix Fietkau 691b6862effSLorenzo Bianconi struct mt76_rate_power rate_power; 692b6862effSLorenzo Bianconi 6935b257371SLorenzo Bianconi char alpha2[3]; 694d8b8890dSLorenzo Bianconi enum nl80211_dfs_regions region; 695d8b8890dSLorenzo Bianconi 69617f1de56SFelix Fietkau u32 debugfs_reg; 69717f1de56SFelix Fietkau 69817f1de56SFelix Fietkau struct led_classdev led_cdev; 69917f1de56SFelix Fietkau char led_name[32]; 70017f1de56SFelix Fietkau bool led_al; 70117f1de56SFelix Fietkau u8 led_pin; 702b40b15e1SLorenzo Bianconi 703e7173858SFelix Fietkau u8 csa_complete; 704e7173858SFelix Fietkau 705108a4861SStanislaw Gruszka u32 rxfilter; 706108a4861SStanislaw Gruszka 707f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 708f0efa862SFelix Fietkau const struct mt76_testmode_ops *test_ops; 709e7a6a044SShayne Chen struct { 710e7a6a044SShayne Chen const char *name; 711e7a6a044SShayne Chen u32 offset; 712e7a6a044SShayne Chen } test_mtd; 713f0efa862SFelix Fietkau #endif 714a86f1d01SLorenzo Bianconi struct workqueue_struct *wq; 715a86f1d01SLorenzo Bianconi 716f7bbb80fSLorenzo Bianconi union { 717f7bbb80fSLorenzo Bianconi struct mt76_mmio mmio; 718b40b15e1SLorenzo Bianconi struct mt76_usb usb; 719d39b52e3SSean Wang struct mt76_sdio sdio; 72017f1de56SFelix Fietkau }; 721f7bbb80fSLorenzo Bianconi }; 72217f1de56SFelix Fietkau 72322b980baSFelix Fietkau struct mt76_power_limits { 72422b980baSFelix Fietkau s8 cck[4]; 72522b980baSFelix Fietkau s8 ofdm[8]; 72622b980baSFelix Fietkau s8 mcs[4][10]; 727a9627d99SShayne Chen s8 ru[7][12]; 72822b980baSFelix Fietkau }; 72922b980baSFelix Fietkau 73017f1de56SFelix Fietkau enum mt76_phy_type { 73117f1de56SFelix Fietkau MT_PHY_TYPE_CCK, 73217f1de56SFelix Fietkau MT_PHY_TYPE_OFDM, 73317f1de56SFelix Fietkau MT_PHY_TYPE_HT, 73417f1de56SFelix Fietkau MT_PHY_TYPE_HT_GF, 73517f1de56SFelix Fietkau MT_PHY_TYPE_VHT, 736d3377b78SRyder Lee MT_PHY_TYPE_HE_SU = 8, 737d3377b78SRyder Lee MT_PHY_TYPE_HE_EXT_SU, 738d3377b78SRyder Lee MT_PHY_TYPE_HE_TB, 739d3377b78SRyder Lee MT_PHY_TYPE_HE_MU, 74017f1de56SFelix Fietkau }; 74117f1de56SFelix Fietkau 74254b8fdebSLorenzo Bianconi #define CCK_RATE(_idx, _rate) { \ 74354b8fdebSLorenzo Bianconi .bitrate = _rate, \ 74454b8fdebSLorenzo Bianconi .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ 74554b8fdebSLorenzo Bianconi .hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \ 74654b8fdebSLorenzo Bianconi .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + _idx), \ 74754b8fdebSLorenzo Bianconi } 74854b8fdebSLorenzo Bianconi 74954b8fdebSLorenzo Bianconi #define OFDM_RATE(_idx, _rate) { \ 75054b8fdebSLorenzo Bianconi .bitrate = _rate, \ 75154b8fdebSLorenzo Bianconi .hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 75254b8fdebSLorenzo Bianconi .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 75354b8fdebSLorenzo Bianconi } 75454b8fdebSLorenzo Bianconi 75554b8fdebSLorenzo Bianconi extern struct ieee80211_rate mt76_rates[12]; 75654b8fdebSLorenzo Bianconi 757d4131273SStanislaw Gruszka #define __mt76_rr(dev, ...) (dev)->bus->rr((dev), __VA_ARGS__) 758d4131273SStanislaw Gruszka #define __mt76_wr(dev, ...) (dev)->bus->wr((dev), __VA_ARGS__) 759d4131273SStanislaw Gruszka #define __mt76_rmw(dev, ...) (dev)->bus->rmw((dev), __VA_ARGS__) 76035e4ebeaSLorenzo Bianconi #define __mt76_wr_copy(dev, ...) (dev)->bus->write_copy((dev), __VA_ARGS__) 76135e4ebeaSLorenzo Bianconi #define __mt76_rr_copy(dev, ...) (dev)->bus->read_copy((dev), __VA_ARGS__) 762d4131273SStanislaw Gruszka 76322c575c4SStanislaw Gruszka #define __mt76_set(dev, offset, val) __mt76_rmw(dev, offset, 0, val) 76422c575c4SStanislaw Gruszka #define __mt76_clear(dev, offset, val) __mt76_rmw(dev, offset, val, 0) 76522c575c4SStanislaw Gruszka 76617f1de56SFelix Fietkau #define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__) 76717f1de56SFelix Fietkau #define mt76_wr(dev, ...) (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__) 76817f1de56SFelix Fietkau #define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__) 76935e4ebeaSLorenzo Bianconi #define mt76_wr_copy(dev, ...) (dev)->mt76.bus->write_copy(&((dev)->mt76), __VA_ARGS__) 77035e4ebeaSLorenzo Bianconi #define mt76_rr_copy(dev, ...) (dev)->mt76.bus->read_copy(&((dev)->mt76), __VA_ARGS__) 7716da5a291SStanislaw Gruszka #define mt76_wr_rp(dev, ...) (dev)->mt76.bus->wr_rp(&((dev)->mt76), __VA_ARGS__) 7726da5a291SStanislaw Gruszka #define mt76_rd_rp(dev, ...) (dev)->mt76.bus->rd_rp(&((dev)->mt76), __VA_ARGS__) 77317f1de56SFelix Fietkau 774f4d45fe2SLorenzo Bianconi 775e2c2fd0fSLorenzo Bianconi #define mt76_mcu_restart(dev, ...) (dev)->mt76.mcu_ops->mcu_restart(&((dev)->mt76)) 776e2c2fd0fSLorenzo Bianconi #define __mt76_mcu_restart(dev, ...) (dev)->mcu_ops->mcu_restart((dev)) 777db0f04f3SLorenzo Bianconi 77817f1de56SFelix Fietkau #define mt76_set(dev, offset, val) mt76_rmw(dev, offset, 0, val) 77917f1de56SFelix Fietkau #define mt76_clear(dev, offset, val) mt76_rmw(dev, offset, val, 0) 78017f1de56SFelix Fietkau 78117f1de56SFelix Fietkau #define mt76_get_field(_dev, _reg, _field) \ 78217f1de56SFelix Fietkau FIELD_GET(_field, mt76_rr(dev, _reg)) 78317f1de56SFelix Fietkau 78417f1de56SFelix Fietkau #define mt76_rmw_field(_dev, _reg, _field, _val) \ 78517f1de56SFelix Fietkau mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) 78617f1de56SFelix Fietkau 78746436b5eSStanislaw Gruszka #define __mt76_rmw_field(_dev, _reg, _field, _val) \ 78846436b5eSStanislaw Gruszka __mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) 78946436b5eSStanislaw Gruszka 790ac24dd35SFelix Fietkau #define mt76_hw(dev) (dev)->mphy.hw 79117f1de56SFelix Fietkau 792426e8e41SFelix Fietkau static inline struct ieee80211_hw * 79349e649c3SRyder Lee mt76_wcid_hw(struct mt76_dev *dev, u16 wcid) 794426e8e41SFelix Fietkau { 795426e8e41SFelix Fietkau if (wcid <= MT76_N_WCIDS && 796426e8e41SFelix Fietkau mt76_wcid_mask_test(dev->wcid_phy_mask, wcid)) 797426e8e41SFelix Fietkau return dev->phy2->hw; 798426e8e41SFelix Fietkau 799426e8e41SFelix Fietkau return dev->phy.hw; 800426e8e41SFelix Fietkau } 801426e8e41SFelix Fietkau 80217f1de56SFelix Fietkau bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, 80317f1de56SFelix Fietkau int timeout); 80417f1de56SFelix Fietkau 80517f1de56SFelix Fietkau #define mt76_poll(dev, ...) __mt76_poll(&((dev)->mt76), __VA_ARGS__) 80617f1de56SFelix Fietkau 80717f1de56SFelix Fietkau bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, 80817f1de56SFelix Fietkau int timeout); 80917f1de56SFelix Fietkau 81017f1de56SFelix Fietkau #define mt76_poll_msec(dev, ...) __mt76_poll_msec(&((dev)->mt76), __VA_ARGS__) 81117f1de56SFelix Fietkau 81217f1de56SFelix Fietkau void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs); 813f37f0550SLorenzo Bianconi void mt76_pci_disable_aspm(struct pci_dev *pdev); 81417f1de56SFelix Fietkau 81517f1de56SFelix Fietkau static inline u16 mt76_chip(struct mt76_dev *dev) 81617f1de56SFelix Fietkau { 81717f1de56SFelix Fietkau return dev->rev >> 16; 81817f1de56SFelix Fietkau } 81917f1de56SFelix Fietkau 82017f1de56SFelix Fietkau static inline u16 mt76_rev(struct mt76_dev *dev) 82117f1de56SFelix Fietkau { 82217f1de56SFelix Fietkau return dev->rev & 0xffff; 82317f1de56SFelix Fietkau } 82417f1de56SFelix Fietkau 82517f1de56SFelix Fietkau #define mt76xx_chip(dev) mt76_chip(&((dev)->mt76)) 82617f1de56SFelix Fietkau #define mt76xx_rev(dev) mt76_rev(&((dev)->mt76)) 82717f1de56SFelix Fietkau 828cb8ed33dSLorenzo Bianconi #define mt76_init_queues(dev, ...) (dev)->mt76.queue_ops->init(&((dev)->mt76), __VA_ARGS__) 829a23fde09SLorenzo Bianconi #define mt76_queue_alloc(dev, ...) (dev)->mt76.queue_ops->alloc(&((dev)->mt76), __VA_ARGS__) 8305ed31128SLorenzo Bianconi #define mt76_tx_queue_skb_raw(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb_raw(&((dev)->mt76), __VA_ARGS__) 831eb9ca7ecSLorenzo Bianconi #define mt76_tx_queue_skb(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb(&((dev)->mt76), __VA_ARGS__) 83217f1de56SFelix Fietkau #define mt76_queue_rx_reset(dev, ...) (dev)->mt76.queue_ops->rx_reset(&((dev)->mt76), __VA_ARGS__) 83317f1de56SFelix Fietkau #define mt76_queue_tx_cleanup(dev, ...) (dev)->mt76.queue_ops->tx_cleanup(&((dev)->mt76), __VA_ARGS__) 834c001df97SLorenzo Bianconi #define mt76_queue_rx_cleanup(dev, ...) (dev)->mt76.queue_ops->rx_cleanup(&((dev)->mt76), __VA_ARGS__) 83517f1de56SFelix Fietkau #define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__) 8363990465dSLorenzo Bianconi #define mt76_queue_reset(dev, ...) (dev)->mt76.queue_ops->reset_q(&((dev)->mt76), __VA_ARGS__) 83717f1de56SFelix Fietkau 838f473b42aSFelix Fietkau #define mt76_for_each_q_rx(dev, i) \ 839f473b42aSFelix Fietkau for (i = 0; i < ARRAY_SIZE((dev)->q_rx) && \ 840f473b42aSFelix Fietkau (dev)->q_rx[i].ndesc; i++) 841f473b42aSFelix Fietkau 842c0f7b25aSLorenzo Bianconi struct mt76_dev *mt76_alloc_device(struct device *pdev, unsigned int size, 843c0f7b25aSLorenzo Bianconi const struct ieee80211_ops *ops, 844c0f7b25aSLorenzo Bianconi const struct mt76_driver_ops *drv_ops); 84517f1de56SFelix Fietkau int mt76_register_device(struct mt76_dev *dev, bool vht, 84617f1de56SFelix Fietkau struct ieee80211_rate *rates, int n_rates); 84717f1de56SFelix Fietkau void mt76_unregister_device(struct mt76_dev *dev); 848def34a2fSLorenzo Bianconi void mt76_free_device(struct mt76_dev *dev); 849c89d3625SFelix Fietkau void mt76_unregister_phy(struct mt76_phy *phy); 850c89d3625SFelix Fietkau 851c89d3625SFelix Fietkau struct mt76_phy *mt76_alloc_phy(struct mt76_dev *dev, unsigned int size, 852c89d3625SFelix Fietkau const struct ieee80211_ops *ops); 853db78a791SLorenzo Bianconi int mt76_register_phy(struct mt76_phy *phy, bool vht, 854db78a791SLorenzo Bianconi struct ieee80211_rate *rates, int n_rates); 85517f1de56SFelix Fietkau 85617f1de56SFelix Fietkau struct dentry *mt76_register_debugfs(struct mt76_dev *dev); 8570b82a8e8SLorenzo Bianconi int mt76_queues_read(struct seq_file *s, void *data); 8588f410a8bSLorenzo Bianconi void mt76_seq_puts_array(struct seq_file *file, const char *str, 8598f410a8bSLorenzo Bianconi s8 *val, int len); 86017f1de56SFelix Fietkau 86117f1de56SFelix Fietkau int mt76_eeprom_init(struct mt76_dev *dev, int len); 86298df2baeSLorenzo Bianconi void mt76_eeprom_override(struct mt76_phy *phy); 863495184acSRyder Lee int mt76_get_of_eeprom(struct mt76_dev *dev, void *data, int offset, int len); 86417f1de56SFelix Fietkau 865b1cb42adSLorenzo Bianconi struct mt76_queue * 866b1cb42adSLorenzo Bianconi mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc, 867b1cb42adSLorenzo Bianconi int ring_base); 868b1cb42adSLorenzo Bianconi static inline int mt76_init_tx_queue(struct mt76_phy *phy, int qid, int idx, 869b1cb42adSLorenzo Bianconi int n_desc, int ring_base) 870b1cb42adSLorenzo Bianconi { 871b1cb42adSLorenzo Bianconi struct mt76_queue *q; 872b1cb42adSLorenzo Bianconi 873b1cb42adSLorenzo Bianconi q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base); 874b1cb42adSLorenzo Bianconi if (IS_ERR(q)) 875b1cb42adSLorenzo Bianconi return PTR_ERR(q); 876b1cb42adSLorenzo Bianconi 877b1cb42adSLorenzo Bianconi q->qid = qid; 87891990519SLorenzo Bianconi phy->q_tx[qid] = q; 879b1cb42adSLorenzo Bianconi 880b1cb42adSLorenzo Bianconi return 0; 881b1cb42adSLorenzo Bianconi } 882b1cb42adSLorenzo Bianconi 883b1cb42adSLorenzo Bianconi static inline int mt76_init_mcu_queue(struct mt76_dev *dev, int qid, int idx, 884b1cb42adSLorenzo Bianconi int n_desc, int ring_base) 885b1cb42adSLorenzo Bianconi { 886b1cb42adSLorenzo Bianconi struct mt76_queue *q; 887b1cb42adSLorenzo Bianconi 888b1cb42adSLorenzo Bianconi q = mt76_init_queue(dev, qid, idx, n_desc, ring_base); 889b1cb42adSLorenzo Bianconi if (IS_ERR(q)) 890b1cb42adSLorenzo Bianconi return PTR_ERR(q); 891b1cb42adSLorenzo Bianconi 892e637763bSLorenzo Bianconi q->qid = __MT_TXQ_MAX + qid; 893b1cb42adSLorenzo Bianconi dev->q_mcu[qid] = q; 894b1cb42adSLorenzo Bianconi 895b1cb42adSLorenzo Bianconi return 0; 896b1cb42adSLorenzo Bianconi } 897b671da33SLorenzo Bianconi 898011849e0SFelix Fietkau static inline struct mt76_phy * 899011849e0SFelix Fietkau mt76_dev_phy(struct mt76_dev *dev, bool phy_ext) 900011849e0SFelix Fietkau { 901011849e0SFelix Fietkau if (phy_ext && dev->phy2) 902011849e0SFelix Fietkau return dev->phy2; 903011849e0SFelix Fietkau return &dev->phy; 904011849e0SFelix Fietkau } 905011849e0SFelix Fietkau 906bfc394ddSFelix Fietkau static inline struct ieee80211_hw * 907bfc394ddSFelix Fietkau mt76_phy_hw(struct mt76_dev *dev, bool phy_ext) 908bfc394ddSFelix Fietkau { 909011849e0SFelix Fietkau return mt76_dev_phy(dev, phy_ext)->hw; 910bfc394ddSFelix Fietkau } 911bfc394ddSFelix Fietkau 912f3950a41SLorenzo Bianconi static inline u8 * 913f3950a41SLorenzo Bianconi mt76_get_txwi_ptr(struct mt76_dev *dev, struct mt76_txwi_cache *t) 914f3950a41SLorenzo Bianconi { 915f3950a41SLorenzo Bianconi return (u8 *)t - dev->drv->txwi_size; 916f3950a41SLorenzo Bianconi } 917f3950a41SLorenzo Bianconi 918ee8aa945SLorenzo Bianconi /* increment with wrap-around */ 919ee8aa945SLorenzo Bianconi static inline int mt76_incr(int val, int size) 920ee8aa945SLorenzo Bianconi { 921ee8aa945SLorenzo Bianconi return (val + 1) & (size - 1); 922ee8aa945SLorenzo Bianconi } 923ee8aa945SLorenzo Bianconi 924ee8aa945SLorenzo Bianconi /* decrement with wrap-around */ 925ee8aa945SLorenzo Bianconi static inline int mt76_decr(int val, int size) 926ee8aa945SLorenzo Bianconi { 927ee8aa945SLorenzo Bianconi return (val - 1) & (size - 1); 928ee8aa945SLorenzo Bianconi } 929ee8aa945SLorenzo Bianconi 9301d0496c6SStanislaw Gruszka u8 mt76_ac_to_hwq(u8 ac); 931b40b15e1SLorenzo Bianconi 93217f1de56SFelix Fietkau static inline struct ieee80211_txq * 93317f1de56SFelix Fietkau mtxq_to_txq(struct mt76_txq *mtxq) 93417f1de56SFelix Fietkau { 93517f1de56SFelix Fietkau void *ptr = mtxq; 93617f1de56SFelix Fietkau 93717f1de56SFelix Fietkau return container_of(ptr, struct ieee80211_txq, drv_priv); 93817f1de56SFelix Fietkau } 93917f1de56SFelix Fietkau 9409c68a57bSFelix Fietkau static inline struct ieee80211_sta * 9419c68a57bSFelix Fietkau wcid_to_sta(struct mt76_wcid *wcid) 9429c68a57bSFelix Fietkau { 9439c68a57bSFelix Fietkau void *ptr = wcid; 9449c68a57bSFelix Fietkau 9459c68a57bSFelix Fietkau if (!wcid || !wcid->sta) 9469c68a57bSFelix Fietkau return NULL; 9479c68a57bSFelix Fietkau 9489c68a57bSFelix Fietkau return container_of(ptr, struct ieee80211_sta, drv_priv); 9499c68a57bSFelix Fietkau } 9509c68a57bSFelix Fietkau 95188046b2cSFelix Fietkau static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb) 95288046b2cSFelix Fietkau { 95388046b2cSFelix Fietkau BUILD_BUG_ON(sizeof(struct mt76_tx_cb) > 95488046b2cSFelix Fietkau sizeof(IEEE80211_SKB_CB(skb)->status.status_driver_data)); 95588046b2cSFelix Fietkau return ((void *)IEEE80211_SKB_CB(skb)->status.status_driver_data); 95688046b2cSFelix Fietkau } 95788046b2cSFelix Fietkau 95877ae1d5eSRyder Lee static inline void *mt76_skb_get_hdr(struct sk_buff *skb) 95977ae1d5eSRyder Lee { 96077ae1d5eSRyder Lee struct mt76_rx_status mstat; 96177ae1d5eSRyder Lee u8 *data = skb->data; 96277ae1d5eSRyder Lee 96377ae1d5eSRyder Lee /* Alignment concerns */ 96477ae1d5eSRyder Lee BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he) % 4); 96577ae1d5eSRyder Lee BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he_mu) % 4); 96677ae1d5eSRyder Lee 96777ae1d5eSRyder Lee mstat = *((struct mt76_rx_status *)skb->cb); 96877ae1d5eSRyder Lee 96977ae1d5eSRyder Lee if (mstat.flag & RX_FLAG_RADIOTAP_HE) 97077ae1d5eSRyder Lee data += sizeof(struct ieee80211_radiotap_he); 97177ae1d5eSRyder Lee if (mstat.flag & RX_FLAG_RADIOTAP_HE_MU) 97277ae1d5eSRyder Lee data += sizeof(struct ieee80211_radiotap_he_mu); 97377ae1d5eSRyder Lee 97477ae1d5eSRyder Lee return data; 97577ae1d5eSRyder Lee } 97677ae1d5eSRyder Lee 9773bb45b5fSLorenzo Bianconi static inline void mt76_insert_hdr_pad(struct sk_buff *skb) 9783bb45b5fSLorenzo Bianconi { 9793bb45b5fSLorenzo Bianconi int len = ieee80211_get_hdrlen_from_skb(skb); 9803bb45b5fSLorenzo Bianconi 9813bb45b5fSLorenzo Bianconi if (len % 4 == 0) 9823bb45b5fSLorenzo Bianconi return; 9833bb45b5fSLorenzo Bianconi 9843bb45b5fSLorenzo Bianconi skb_push(skb, 2); 9853bb45b5fSLorenzo Bianconi memmove(skb->data, skb->data + 2, len); 9863bb45b5fSLorenzo Bianconi 9873bb45b5fSLorenzo Bianconi skb->data[len] = 0; 9883bb45b5fSLorenzo Bianconi skb->data[len + 1] = 0; 9893bb45b5fSLorenzo Bianconi } 9903bb45b5fSLorenzo Bianconi 9918548c6ebSFelix Fietkau static inline bool mt76_is_skb_pktid(u8 pktid) 9928548c6ebSFelix Fietkau { 9938548c6ebSFelix Fietkau if (pktid & MT_PACKET_ID_HAS_RATE) 9948548c6ebSFelix Fietkau return false; 9958548c6ebSFelix Fietkau 9968548c6ebSFelix Fietkau return pktid >= MT_PACKET_ID_FIRST; 9978548c6ebSFelix Fietkau } 9988548c6ebSFelix Fietkau 99907cda406SFelix Fietkau static inline u8 mt76_tx_power_nss_delta(u8 nss) 100007cda406SFelix Fietkau { 100107cda406SFelix Fietkau static const u8 nss_delta[4] = { 0, 6, 9, 12 }; 100207cda406SFelix Fietkau 100307cda406SFelix Fietkau return nss_delta[nss - 1]; 100407cda406SFelix Fietkau } 100507cda406SFelix Fietkau 1006c918c74dSShayne Chen static inline bool mt76_testmode_enabled(struct mt76_phy *phy) 1007f0efa862SFelix Fietkau { 1008f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 1009c918c74dSShayne Chen return phy->test.state != MT76_TM_STATE_OFF; 1010c918c74dSShayne Chen #else 1011c918c74dSShayne Chen return false; 1012c918c74dSShayne Chen #endif 1013c918c74dSShayne Chen } 1014c918c74dSShayne Chen 1015c918c74dSShayne Chen static inline bool mt76_is_testmode_skb(struct mt76_dev *dev, 1016c918c74dSShayne Chen struct sk_buff *skb, 1017c918c74dSShayne Chen struct ieee80211_hw **hw) 1018c918c74dSShayne Chen { 1019c918c74dSShayne Chen #ifdef CONFIG_NL80211_TESTMODE 1020c918c74dSShayne Chen if (skb == dev->phy.test.tx_skb) 1021c918c74dSShayne Chen *hw = dev->phy.hw; 1022c918c74dSShayne Chen else if (dev->phy2 && skb == dev->phy2->test.tx_skb) 1023c918c74dSShayne Chen *hw = dev->phy2->hw; 1024c918c74dSShayne Chen else 1025c918c74dSShayne Chen return false; 1026c918c74dSShayne Chen return true; 1027f0efa862SFelix Fietkau #else 1028f0efa862SFelix Fietkau return false; 1029f0efa862SFelix Fietkau #endif 1030f0efa862SFelix Fietkau } 1031f0efa862SFelix Fietkau 103217f1de56SFelix Fietkau void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb); 10339fba6d07SFelix Fietkau void mt76_tx(struct mt76_phy *dev, struct ieee80211_sta *sta, 103417f1de56SFelix Fietkau struct mt76_wcid *wcid, struct sk_buff *skb); 103517f1de56SFelix Fietkau void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq); 103691990519SLorenzo Bianconi void mt76_stop_tx_queues(struct mt76_phy *phy, struct ieee80211_sta *sta, 103717f1de56SFelix Fietkau bool send_bar); 1038c50d105aSFelix Fietkau void mt76_tx_check_agg_ssn(struct ieee80211_sta *sta, struct sk_buff *skb); 10399fba6d07SFelix Fietkau void mt76_txq_schedule(struct mt76_phy *phy, enum mt76_txq_id qid); 10409fba6d07SFelix Fietkau void mt76_txq_schedule_all(struct mt76_phy *phy); 1041335e97acSLorenzo Bianconi void mt76_tx_worker_run(struct mt76_dev *dev); 1042781eef5bSFelix Fietkau void mt76_tx_worker(struct mt76_worker *w); 104317f1de56SFelix Fietkau void mt76_release_buffered_frames(struct ieee80211_hw *hw, 104417f1de56SFelix Fietkau struct ieee80211_sta *sta, 104517f1de56SFelix Fietkau u16 tids, int nframes, 104617f1de56SFelix Fietkau enum ieee80211_frame_release_type reason, 104717f1de56SFelix Fietkau bool more_data); 10485a95ca41SFelix Fietkau bool mt76_has_tx_pending(struct mt76_phy *phy); 104996747a51SFelix Fietkau void mt76_set_channel(struct mt76_phy *phy); 10505ce09c1aSFelix Fietkau void mt76_update_survey(struct mt76_dev *dev); 105104414240SLorenzo Bianconi void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time); 105217f1de56SFelix Fietkau int mt76_get_survey(struct ieee80211_hw *hw, int idx, 105317f1de56SFelix Fietkau struct survey_info *survey); 1054bb3e3fecSRyder Lee void mt76_set_stream_caps(struct mt76_phy *phy, bool vht); 105517f1de56SFelix Fietkau 1056aee5b8cfSFelix Fietkau int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid, 10577c4f744dSRyder Lee u16 ssn, u16 size); 1058aee5b8cfSFelix Fietkau void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid); 1059aee5b8cfSFelix Fietkau 106030ce7f44SFelix Fietkau void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, 106130ce7f44SFelix Fietkau struct ieee80211_key_conf *key); 106279d1c94cSFelix Fietkau 106379d1c94cSFelix Fietkau void mt76_tx_status_lock(struct mt76_dev *dev, struct sk_buff_head *list) 106479d1c94cSFelix Fietkau __acquires(&dev->status_list.lock); 106579d1c94cSFelix Fietkau void mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list) 106679d1c94cSFelix Fietkau __releases(&dev->status_list.lock); 106779d1c94cSFelix Fietkau 106888046b2cSFelix Fietkau int mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, 106988046b2cSFelix Fietkau struct sk_buff *skb); 107088046b2cSFelix Fietkau struct sk_buff *mt76_tx_status_skb_get(struct mt76_dev *dev, 107179d1c94cSFelix Fietkau struct mt76_wcid *wcid, int pktid, 107279d1c94cSFelix Fietkau struct sk_buff_head *list); 107379d1c94cSFelix Fietkau void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb, 107479d1c94cSFelix Fietkau struct sk_buff_head *list); 10750fe88644SFelix Fietkau void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb, 10760fe88644SFelix Fietkau struct list_head *free_list); 10770fe88644SFelix Fietkau static inline void 10780fe88644SFelix Fietkau mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb) 10790fe88644SFelix Fietkau { 10800fe88644SFelix Fietkau __mt76_tx_complete_skb(dev, wcid, skb, NULL); 10810fe88644SFelix Fietkau } 10820fe88644SFelix Fietkau 108379d1c94cSFelix Fietkau void mt76_tx_status_check(struct mt76_dev *dev, struct mt76_wcid *wcid, 108479d1c94cSFelix Fietkau bool flush); 1085e28487eaSFelix Fietkau int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1086e28487eaSFelix Fietkau struct ieee80211_sta *sta, 1087e28487eaSFelix Fietkau enum ieee80211_sta_state old_state, 1088e28487eaSFelix Fietkau enum ieee80211_sta_state new_state); 108913f61dfcSLorenzo Bianconi void __mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif, 109013f61dfcSLorenzo Bianconi struct ieee80211_sta *sta); 109143ba1922SFelix Fietkau void mt76_sta_pre_rcu_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 109243ba1922SFelix Fietkau struct ieee80211_sta *sta); 109330ce7f44SFelix Fietkau 10948af63fedSFelix Fietkau int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy); 1095ef13edc0SFelix Fietkau 10969313faacSFelix Fietkau int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 10979313faacSFelix Fietkau int *dbm); 10989313faacSFelix Fietkau 1099e7173858SFelix Fietkau void mt76_csa_check(struct mt76_dev *dev); 1100e7173858SFelix Fietkau void mt76_csa_finish(struct mt76_dev *dev); 1101e7173858SFelix Fietkau 1102e49c76d4SLorenzo Bianconi int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 110387d53103SStanislaw Gruszka int mt76_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set); 1104eadfd98fSLorenzo Bianconi void mt76_insert_ccmp_hdr(struct sk_buff *skb, u8 key_id); 1105d2679d65SLorenzo Bianconi int mt76_get_rate(struct mt76_dev *dev, 1106d2679d65SLorenzo Bianconi struct ieee80211_supported_band *sband, 1107d2679d65SLorenzo Bianconi int idx, bool cck); 11088b8ab5c2SLorenzo Bianconi void mt76_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 11098b8ab5c2SLorenzo Bianconi const u8 *mac); 11108b8ab5c2SLorenzo Bianconi void mt76_sw_scan_complete(struct ieee80211_hw *hw, 11118b8ab5c2SLorenzo Bianconi struct ieee80211_vif *vif); 1112f0efa862SFelix Fietkau int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1113f0efa862SFelix Fietkau void *data, int len); 1114f0efa862SFelix Fietkau int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, 1115f0efa862SFelix Fietkau struct netlink_callback *cb, void *data, int len); 1116c918c74dSShayne Chen int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state); 11172601dda8SShayne Chen int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len); 1118f0efa862SFelix Fietkau 1119c918c74dSShayne Chen static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable) 1120f0efa862SFelix Fietkau { 1121f0efa862SFelix Fietkau #ifdef CONFIG_NL80211_TESTMODE 1122f0efa862SFelix Fietkau enum mt76_testmode_state state = MT76_TM_STATE_IDLE; 1123f0efa862SFelix Fietkau 1124c918c74dSShayne Chen if (disable || phy->test.state == MT76_TM_STATE_OFF) 1125f0efa862SFelix Fietkau state = MT76_TM_STATE_OFF; 1126f0efa862SFelix Fietkau 1127c918c74dSShayne Chen mt76_testmode_set_state(phy, state); 1128f0efa862SFelix Fietkau #endif 1129f0efa862SFelix Fietkau } 1130f0efa862SFelix Fietkau 113187d53103SStanislaw Gruszka 113217f1de56SFelix Fietkau /* internal */ 1133e394b575SFelix Fietkau static inline struct ieee80211_hw * 1134e394b575SFelix Fietkau mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb) 1135e394b575SFelix Fietkau { 1136e394b575SFelix Fietkau struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1137e394b575SFelix Fietkau struct ieee80211_hw *hw = dev->phy.hw; 1138e394b575SFelix Fietkau 1139e394b575SFelix Fietkau if ((info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY) && dev->phy2) 1140e394b575SFelix Fietkau hw = dev->phy2->hw; 1141e394b575SFelix Fietkau 1142e394b575SFelix Fietkau info->hw_queue &= ~MT_TX_HW_QUEUE_EXT_PHY; 1143e394b575SFelix Fietkau 1144e394b575SFelix Fietkau return hw; 1145e394b575SFelix Fietkau } 1146e394b575SFelix Fietkau 114717f1de56SFelix Fietkau void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); 11489d9d738bSFelix Fietkau void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, 114981e850efSLorenzo Bianconi struct napi_struct *napi); 115081e850efSLorenzo Bianconi void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q, 115181e850efSLorenzo Bianconi struct napi_struct *napi); 1152aee5b8cfSFelix Fietkau void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames); 1153c918c74dSShayne Chen void mt76_testmode_tx_pending(struct mt76_phy *phy); 1154fe5b5ab5SFelix Fietkau void mt76_queue_tx_complete(struct mt76_dev *dev, struct mt76_queue *q, 1155fe5b5ab5SFelix Fietkau struct mt76_queue_entry *e); 115617f1de56SFelix Fietkau 1157b40b15e1SLorenzo Bianconi /* usb */ 1158b40b15e1SLorenzo Bianconi static inline bool mt76u_urb_error(struct urb *urb) 1159b40b15e1SLorenzo Bianconi { 1160b40b15e1SLorenzo Bianconi return urb->status && 1161b40b15e1SLorenzo Bianconi urb->status != -ECONNRESET && 1162b40b15e1SLorenzo Bianconi urb->status != -ESHUTDOWN && 1163b40b15e1SLorenzo Bianconi urb->status != -ENOENT; 1164b40b15e1SLorenzo Bianconi } 1165b40b15e1SLorenzo Bianconi 1166b40b15e1SLorenzo Bianconi /* Map hardware queues to usb endpoints */ 1167b40b15e1SLorenzo Bianconi static inline u8 q2ep(u8 qid) 1168b40b15e1SLorenzo Bianconi { 1169b40b15e1SLorenzo Bianconi /* TODO: take management packets to queue 5 */ 1170b40b15e1SLorenzo Bianconi return qid + 1; 1171b40b15e1SLorenzo Bianconi } 1172b40b15e1SLorenzo Bianconi 11735de4db8fSStanislaw Gruszka static inline int 1174b63aa031SStanislaw Gruszka mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len, 11753bcd979cSLorenzo Bianconi int timeout, int ep) 11765de4db8fSStanislaw Gruszka { 117780df01f4SLorenzo Bianconi struct usb_interface *uintf = to_usb_interface(dev->dev); 117880df01f4SLorenzo Bianconi struct usb_device *udev = interface_to_usbdev(uintf); 11795de4db8fSStanislaw Gruszka struct mt76_usb *usb = &dev->usb; 11805de4db8fSStanislaw Gruszka unsigned int pipe; 11815de4db8fSStanislaw Gruszka 1182b63aa031SStanislaw Gruszka if (actual_len) 11833bcd979cSLorenzo Bianconi pipe = usb_rcvbulkpipe(udev, usb->in_ep[ep]); 1184b63aa031SStanislaw Gruszka else 11853bcd979cSLorenzo Bianconi pipe = usb_sndbulkpipe(udev, usb->out_ep[ep]); 1186b63aa031SStanislaw Gruszka 1187b63aa031SStanislaw Gruszka return usb_bulk_msg(udev, pipe, data, len, actual_len, timeout); 11885de4db8fSStanislaw Gruszka } 11895de4db8fSStanislaw Gruszka 1190e98e6df6SLorenzo Bianconi int mt76_skb_adjust_pad(struct sk_buff *skb, int pad); 1191b40b15e1SLorenzo Bianconi int mt76u_vendor_request(struct mt76_dev *dev, u8 req, 1192b40b15e1SLorenzo Bianconi u8 req_type, u16 val, u16 offset, 1193b40b15e1SLorenzo Bianconi void *buf, size_t len); 1194b40b15e1SLorenzo Bianconi void mt76u_single_wr(struct mt76_dev *dev, const u8 req, 1195b40b15e1SLorenzo Bianconi const u16 offset, const u32 val); 11961e816c65SLorenzo Bianconi int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf, 11971e816c65SLorenzo Bianconi bool ext); 119894e1cfa8SLorenzo Bianconi int mt76u_alloc_mcu_queue(struct mt76_dev *dev); 1199b40b15e1SLorenzo Bianconi int mt76u_alloc_queues(struct mt76_dev *dev); 120039d501d9SStanislaw Gruszka void mt76u_stop_tx(struct mt76_dev *dev); 120139d501d9SStanislaw Gruszka void mt76u_stop_rx(struct mt76_dev *dev); 120239d501d9SStanislaw Gruszka int mt76u_resume_rx(struct mt76_dev *dev); 1203b40b15e1SLorenzo Bianconi void mt76u_queues_deinit(struct mt76_dev *dev); 1204b40b15e1SLorenzo Bianconi 1205d39b52e3SSean Wang int mt76s_init(struct mt76_dev *dev, struct sdio_func *func, 1206d39b52e3SSean Wang const struct mt76_bus_ops *bus_ops); 1207d39b52e3SSean Wang int mt76s_alloc_queues(struct mt76_dev *dev); 1208d39b52e3SSean Wang void mt76s_deinit(struct mt76_dev *dev); 1209d39b52e3SSean Wang 12109df0fab9SLorenzo Bianconi struct sk_buff * 1211bb31a80eSLorenzo Bianconi mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, 1212bb31a80eSLorenzo Bianconi int data_len); 1213c07a49d4SLorenzo Bianconi void mt76_mcu_rx_event(struct mt76_dev *dev, struct sk_buff *skb); 1214680abb25SLorenzo Bianconi struct sk_buff *mt76_mcu_get_response(struct mt76_dev *dev, 1215680abb25SLorenzo Bianconi unsigned long expires); 1216ae5ad627SFelix Fietkau int mt76_mcu_send_and_get_msg(struct mt76_dev *dev, int cmd, const void *data, 1217ae5ad627SFelix Fietkau int len, bool wait_resp, struct sk_buff **ret); 1218ae5ad627SFelix Fietkau int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, 1219ae5ad627SFelix Fietkau int cmd, bool wait_resp, struct sk_buff **ret); 12203cb43b66SLorenzo Bianconi int mt76_mcu_send_firmware(struct mt76_dev *dev, int cmd, const void *data, 12213cb43b66SLorenzo Bianconi int len); 1222ae5ad627SFelix Fietkau static inline int 1223ae5ad627SFelix Fietkau mt76_mcu_send_msg(struct mt76_dev *dev, int cmd, const void *data, int len, 1224ae5ad627SFelix Fietkau bool wait_resp) 1225ae5ad627SFelix Fietkau { 1226ae5ad627SFelix Fietkau return mt76_mcu_send_and_get_msg(dev, cmd, data, len, wait_resp, NULL); 1227ae5ad627SFelix Fietkau } 1228ae5ad627SFelix Fietkau 1229ae5ad627SFelix Fietkau static inline int 1230ae5ad627SFelix Fietkau mt76_mcu_skb_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, 1231ae5ad627SFelix Fietkau bool wait_resp) 1232ae5ad627SFelix Fietkau { 1233ae5ad627SFelix Fietkau return mt76_mcu_skb_send_and_get_msg(dev, skb, cmd, wait_resp, NULL); 1234ae5ad627SFelix Fietkau } 12359df0fab9SLorenzo Bianconi 12369220f695SLorenzo Bianconi void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set); 12379220f695SLorenzo Bianconi 123822b980baSFelix Fietkau s8 mt76_get_rate_power_limits(struct mt76_phy *phy, 123922b980baSFelix Fietkau struct ieee80211_channel *chan, 124022b980baSFelix Fietkau struct mt76_power_limits *dest, 124122b980baSFelix Fietkau s8 target_power); 124222b980baSFelix Fietkau 1243d089692bSLorenzo Bianconi struct mt76_txwi_cache * 1244d089692bSLorenzo Bianconi mt76_token_release(struct mt76_dev *dev, int token, bool *wake); 1245d089692bSLorenzo Bianconi int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi); 1246d089692bSLorenzo Bianconi void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked); 1247d089692bSLorenzo Bianconi 1248d089692bSLorenzo Bianconi static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked) 1249d089692bSLorenzo Bianconi { 1250d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1251d089692bSLorenzo Bianconi __mt76_set_tx_blocked(dev, blocked); 1252d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1253d089692bSLorenzo Bianconi } 1254d089692bSLorenzo Bianconi 1255d089692bSLorenzo Bianconi static inline int 1256d089692bSLorenzo Bianconi mt76_token_get(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi) 1257d089692bSLorenzo Bianconi { 1258d089692bSLorenzo Bianconi int token; 1259d089692bSLorenzo Bianconi 1260d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1261d089692bSLorenzo Bianconi token = idr_alloc(&dev->token, *ptxwi, 0, dev->drv->token_size, 1262d089692bSLorenzo Bianconi GFP_ATOMIC); 1263d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1264d089692bSLorenzo Bianconi 1265d089692bSLorenzo Bianconi return token; 1266d089692bSLorenzo Bianconi } 1267d089692bSLorenzo Bianconi 1268d089692bSLorenzo Bianconi static inline struct mt76_txwi_cache * 1269d089692bSLorenzo Bianconi mt76_token_put(struct mt76_dev *dev, int token) 1270d089692bSLorenzo Bianconi { 1271d089692bSLorenzo Bianconi struct mt76_txwi_cache *txwi; 1272d089692bSLorenzo Bianconi 1273d089692bSLorenzo Bianconi spin_lock_bh(&dev->token_lock); 1274d089692bSLorenzo Bianconi txwi = idr_remove(&dev->token, token); 1275d089692bSLorenzo Bianconi spin_unlock_bh(&dev->token_lock); 1276d089692bSLorenzo Bianconi 1277d089692bSLorenzo Bianconi return txwi; 1278d089692bSLorenzo Bianconi } 127990052b84SLorenzo Bianconi 128090052b84SLorenzo Bianconi static inline int 128190052b84SLorenzo Bianconi mt76_get_next_pkt_id(struct mt76_wcid *wcid) 128290052b84SLorenzo Bianconi { 128390052b84SLorenzo Bianconi wcid->packet_id = (wcid->packet_id + 1) & MT_PACKET_ID_MASK; 128490052b84SLorenzo Bianconi if (wcid->packet_id == MT_PACKET_ID_NO_ACK || 128590052b84SLorenzo Bianconi wcid->packet_id == MT_PACKET_ID_NO_SKB) 128690052b84SLorenzo Bianconi wcid->packet_id = MT_PACKET_ID_FIRST; 128790052b84SLorenzo Bianconi 128890052b84SLorenzo Bianconi return wcid->packet_id; 128990052b84SLorenzo Bianconi } 129017f1de56SFelix Fietkau #endif 1291