1 | /* SPDX-License-Identifier: ISC */ |
2 | /* Copyright (C) 2020 MediaTek Inc. */ |
3 | |
4 | #ifndef __MT76_CONNAC_H |
5 | #define __MT76_CONNAC_H |
6 | |
7 | #include "mt76.h" |
8 | |
9 | enum rx_pkt_type { |
10 | PKT_TYPE_TXS, |
11 | PKT_TYPE_TXRXV, |
12 | PKT_TYPE_NORMAL, |
13 | PKT_TYPE_RX_DUP_RFB, |
14 | PKT_TYPE_RX_TMR, |
15 | PKT_TYPE_RETRIEVE, |
16 | PKT_TYPE_TXRX_NOTIFY, |
17 | PKT_TYPE_RX_EVENT, |
18 | PKT_TYPE_NORMAL_MCU, |
19 | PKT_TYPE_RX_FW_MONITOR = 0x0c, |
20 | PKT_TYPE_TXRX_NOTIFY_V0 = 0x18, |
21 | }; |
22 | |
23 | #define MT76_CONNAC_SCAN_IE_LEN 600 |
24 | #define MT76_CONNAC_MAX_NUM_SCHED_SCAN_INTERVAL 10 |
25 | #define MT76_CONNAC_MAX_TIME_SCHED_SCAN_INTERVAL U16_MAX |
26 | #define MT76_CONNAC_MAX_SCHED_SCAN_SSID 10 |
27 | #define MT76_CONNAC_MAX_SCAN_MATCH 16 |
28 | |
29 | #define MT76_CONNAC_MAX_WMM_SETS 4 |
30 | |
31 | #define MT76_CONNAC_COREDUMP_TIMEOUT (HZ / 20) |
32 | #define MT76_CONNAC_COREDUMP_SZ (1300 * 1024) |
33 | |
34 | #define MT_TXD_SIZE (8 * 4) |
35 | |
36 | #define MT_USB_TXD_SIZE (MT_TXD_SIZE + 8 * 4) |
37 | #define MT_USB_HDR_SIZE 4 |
38 | #define MT_USB_TAIL_SIZE 4 |
39 | |
40 | #define MT_SDIO_TXD_SIZE (MT_TXD_SIZE + 8 * 4) |
41 | #define MT_SDIO_TAIL_SIZE 8 |
42 | #define MT_SDIO_HDR_SIZE 4 |
43 | |
44 | #define MT_MSDU_ID_VALID BIT(15) |
45 | |
46 | #define MT_TXD_LEN_LAST BIT(15) |
47 | #define MT_TXD_LEN_MASK GENMASK(11, 0) |
48 | #define MT_TXD_LEN_MSDU_LAST BIT(14) |
49 | #define MT_TXD_LEN_AMSDU_LAST BIT(15) |
50 | |
51 | enum { |
52 | CMD_CBW_20MHZ = IEEE80211_STA_RX_BW_20, |
53 | CMD_CBW_40MHZ = IEEE80211_STA_RX_BW_40, |
54 | CMD_CBW_80MHZ = IEEE80211_STA_RX_BW_80, |
55 | CMD_CBW_160MHZ = IEEE80211_STA_RX_BW_160, |
56 | CMD_CBW_10MHZ, |
57 | CMD_CBW_5MHZ, |
58 | CMD_CBW_8080MHZ, |
59 | CMD_CBW_320MHZ, |
60 | |
61 | CMD_HE_MCS_BW80 = 0, |
62 | CMD_HE_MCS_BW160, |
63 | CMD_HE_MCS_BW8080, |
64 | CMD_HE_MCS_BW_NUM |
65 | }; |
66 | |
67 | enum { |
68 | HW_BSSID_0 = 0x0, |
69 | HW_BSSID_1, |
70 | HW_BSSID_2, |
71 | HW_BSSID_3, |
72 | HW_BSSID_MAX = HW_BSSID_3, |
73 | EXT_BSSID_START = 0x10, |
74 | EXT_BSSID_1, |
75 | EXT_BSSID_15 = 0x1f, |
76 | EXT_BSSID_MAX = EXT_BSSID_15, |
77 | REPEATER_BSSID_START = 0x20, |
78 | REPEATER_BSSID_MAX = 0x3f, |
79 | }; |
80 | |
81 | struct mt76_connac_reg_map { |
82 | u32 phys; |
83 | u32 maps; |
84 | u32 size; |
85 | }; |
86 | |
87 | struct mt76_connac_pm { |
88 | bool enable:1; |
89 | bool enable_user:1; |
90 | bool ds_enable:1; |
91 | bool ds_enable_user:1; |
92 | bool suspended:1; |
93 | |
94 | spinlock_t txq_lock; |
95 | struct { |
96 | struct mt76_wcid *wcid; |
97 | struct sk_buff *skb; |
98 | } tx_q[IEEE80211_NUM_ACS]; |
99 | |
100 | struct work_struct wake_work; |
101 | wait_queue_head_t wait; |
102 | |
103 | struct { |
104 | spinlock_t lock; |
105 | u32 count; |
106 | } wake; |
107 | struct mutex mutex; |
108 | |
109 | struct delayed_work ps_work; |
110 | unsigned long last_activity; |
111 | unsigned long idle_timeout; |
112 | |
113 | struct { |
114 | unsigned long last_wake_event; |
115 | unsigned long awake_time; |
116 | unsigned long last_doze_event; |
117 | unsigned long doze_time; |
118 | unsigned int lp_wake; |
119 | } stats; |
120 | }; |
121 | |
122 | struct mt76_connac_coredump { |
123 | struct sk_buff_head msg_list; |
124 | struct delayed_work work; |
125 | unsigned long last_activity; |
126 | }; |
127 | |
128 | struct mt76_connac_sta_key_conf { |
129 | s8 keyidx; |
130 | u8 key[16]; |
131 | }; |
132 | |
133 | #define MT_TXP_MAX_BUF_NUM 6 |
134 | |
135 | struct mt76_connac_fw_txp { |
136 | __le16 flags; |
137 | __le16 token; |
138 | u8 bss_idx; |
139 | __le16 rept_wds_wcid; |
140 | u8 nbuf; |
141 | __le32 buf[MT_TXP_MAX_BUF_NUM]; |
142 | __le16 len[MT_TXP_MAX_BUF_NUM]; |
143 | } __packed __aligned(4); |
144 | |
145 | #define MT_HW_TXP_MAX_MSDU_NUM 4 |
146 | #define MT_HW_TXP_MAX_BUF_NUM 4 |
147 | |
148 | struct mt76_connac_txp_ptr { |
149 | __le32 buf0; |
150 | __le16 len0; |
151 | __le16 len1; |
152 | __le32 buf1; |
153 | } __packed __aligned(4); |
154 | |
155 | struct mt76_connac_hw_txp { |
156 | __le16 msdu_id[MT_HW_TXP_MAX_MSDU_NUM]; |
157 | struct mt76_connac_txp_ptr ptr[MT_HW_TXP_MAX_BUF_NUM / 2]; |
158 | } __packed __aligned(4); |
159 | |
160 | struct mt76_connac_txp_common { |
161 | union { |
162 | struct mt76_connac_fw_txp fw; |
163 | struct mt76_connac_hw_txp hw; |
164 | }; |
165 | }; |
166 | |
167 | struct mt76_connac_tx_free { |
168 | __le16 rx_byte_cnt; |
169 | __le16 ctrl; |
170 | __le32 txd; |
171 | } __packed __aligned(4); |
172 | |
173 | extern const struct wiphy_wowlan_support mt76_connac_wowlan_support; |
174 | |
175 | static inline bool is_mt7925(struct mt76_dev *dev) |
176 | { |
177 | return mt76_chip(dev) == 0x7925; |
178 | } |
179 | |
180 | static inline bool is_mt7922(struct mt76_dev *dev) |
181 | { |
182 | return mt76_chip(dev) == 0x7922; |
183 | } |
184 | |
185 | static inline bool is_mt7921(struct mt76_dev *dev) |
186 | { |
187 | return mt76_chip(dev) == 0x7961 || is_mt7922(dev); |
188 | } |
189 | |
190 | static inline bool is_mt7663(struct mt76_dev *dev) |
191 | { |
192 | return mt76_chip(dev) == 0x7663; |
193 | } |
194 | |
195 | static inline bool is_mt7915(struct mt76_dev *dev) |
196 | { |
197 | return mt76_chip(dev) == 0x7915; |
198 | } |
199 | |
200 | static inline bool is_mt7916(struct mt76_dev *dev) |
201 | { |
202 | return mt76_chip(dev) == 0x7906; |
203 | } |
204 | |
205 | static inline bool is_mt7981(struct mt76_dev *dev) |
206 | { |
207 | return mt76_chip(dev) == 0x7981; |
208 | } |
209 | |
210 | static inline bool is_mt7986(struct mt76_dev *dev) |
211 | { |
212 | return mt76_chip(dev) == 0x7986; |
213 | } |
214 | |
215 | static inline bool is_mt798x(struct mt76_dev *dev) |
216 | { |
217 | return is_mt7981(dev) || is_mt7986(dev); |
218 | } |
219 | |
220 | static inline bool is_mt7996(struct mt76_dev *dev) |
221 | { |
222 | return mt76_chip(dev) == 0x7990; |
223 | } |
224 | |
225 | static inline bool is_mt7992(struct mt76_dev *dev) |
226 | { |
227 | return mt76_chip(dev) == 0x7992; |
228 | } |
229 | |
230 | static inline bool is_mt799x(struct mt76_dev *dev) |
231 | { |
232 | return is_mt7996(dev) || is_mt7992(dev); |
233 | } |
234 | |
235 | static inline bool is_mt7622(struct mt76_dev *dev) |
236 | { |
237 | if (!IS_ENABLED(CONFIG_MT7622_WMAC)) |
238 | return false; |
239 | |
240 | return mt76_chip(dev) == 0x7622; |
241 | } |
242 | |
243 | static inline bool is_mt7615(struct mt76_dev *dev) |
244 | { |
245 | return mt76_chip(dev) == 0x7615 || mt76_chip(dev) == 0x7611; |
246 | } |
247 | |
248 | static inline bool is_mt7611(struct mt76_dev *dev) |
249 | { |
250 | return mt76_chip(dev) == 0x7611; |
251 | } |
252 | |
253 | static inline bool is_connac_v1(struct mt76_dev *dev) |
254 | { |
255 | return is_mt7615(dev) || is_mt7663(dev) || is_mt7622(dev); |
256 | } |
257 | |
258 | static inline bool is_mt76_fw_txp(struct mt76_dev *dev) |
259 | { |
260 | switch (mt76_chip(dev)) { |
261 | case 0x7961: |
262 | case 0x7922: |
263 | case 0x7925: |
264 | case 0x7663: |
265 | case 0x7622: |
266 | return false; |
267 | default: |
268 | return true; |
269 | } |
270 | } |
271 | |
272 | static inline u8 mt76_connac_chan_bw(struct cfg80211_chan_def *chandef) |
273 | { |
274 | static const u8 width_to_bw[] = { |
275 | [NL80211_CHAN_WIDTH_40] = CMD_CBW_40MHZ, |
276 | [NL80211_CHAN_WIDTH_80] = CMD_CBW_80MHZ, |
277 | [NL80211_CHAN_WIDTH_80P80] = CMD_CBW_8080MHZ, |
278 | [NL80211_CHAN_WIDTH_160] = CMD_CBW_160MHZ, |
279 | [NL80211_CHAN_WIDTH_5] = CMD_CBW_5MHZ, |
280 | [NL80211_CHAN_WIDTH_10] = CMD_CBW_10MHZ, |
281 | [NL80211_CHAN_WIDTH_20] = CMD_CBW_20MHZ, |
282 | [NL80211_CHAN_WIDTH_20_NOHT] = CMD_CBW_20MHZ, |
283 | [NL80211_CHAN_WIDTH_320] = CMD_CBW_320MHZ, |
284 | }; |
285 | |
286 | if (chandef->width >= ARRAY_SIZE(width_to_bw)) |
287 | return 0; |
288 | |
289 | return width_to_bw[chandef->width]; |
290 | } |
291 | |
292 | static inline u8 mt76_connac_lmac_mapping(u8 ac) |
293 | { |
294 | /* LMAC uses the reverse order of mac80211 AC indexes */ |
295 | return 3 - ac; |
296 | } |
297 | |
298 | static inline void * |
299 | mt76_connac_txwi_to_txp(struct mt76_dev *dev, struct mt76_txwi_cache *t) |
300 | { |
301 | u8 *txwi; |
302 | |
303 | if (!t) |
304 | return NULL; |
305 | |
306 | txwi = mt76_get_txwi_ptr(dev, t); |
307 | |
308 | return (void *)(txwi + MT_TXD_SIZE); |
309 | } |
310 | |
311 | static inline u8 mt76_connac_spe_idx(u8 antenna_mask) |
312 | { |
313 | static const u8 ant_to_spe[] = {0, 0, 1, 0, 3, 2, 4, 0, |
314 | 9, 8, 6, 10, 16, 12, 18, 0}; |
315 | |
316 | if (antenna_mask >= sizeof(ant_to_spe)) |
317 | return 0; |
318 | |
319 | return ant_to_spe[antenna_mask]; |
320 | } |
321 | |
322 | static inline void mt76_connac_irq_enable(struct mt76_dev *dev, u32 mask) |
323 | { |
324 | mt76_set_irq_mask(dev, addr: 0, clear: 0, set: mask); |
325 | tasklet_schedule(t: &dev->irq_tasklet); |
326 | } |
327 | |
328 | int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm); |
329 | void mt76_connac_power_save_sched(struct mt76_phy *phy, |
330 | struct mt76_connac_pm *pm); |
331 | void mt76_connac_free_pending_tx_skbs(struct mt76_connac_pm *pm, |
332 | struct mt76_wcid *wcid); |
333 | |
334 | static inline void mt76_connac_tx_cleanup(struct mt76_dev *dev) |
335 | { |
336 | dev->queue_ops->tx_cleanup(dev, dev->q_mcu[MT_MCUQ_WM], false); |
337 | dev->queue_ops->tx_cleanup(dev, dev->q_mcu[MT_MCUQ_WA], false); |
338 | } |
339 | |
340 | static inline bool |
341 | mt76_connac_pm_ref(struct mt76_phy *phy, struct mt76_connac_pm *pm) |
342 | { |
343 | bool ret = false; |
344 | |
345 | spin_lock_bh(lock: &pm->wake.lock); |
346 | if (test_bit(MT76_STATE_PM, &phy->state)) |
347 | goto out; |
348 | |
349 | pm->wake.count++; |
350 | ret = true; |
351 | out: |
352 | spin_unlock_bh(lock: &pm->wake.lock); |
353 | |
354 | return ret; |
355 | } |
356 | |
357 | static inline void |
358 | mt76_connac_pm_unref(struct mt76_phy *phy, struct mt76_connac_pm *pm) |
359 | { |
360 | spin_lock_bh(lock: &pm->wake.lock); |
361 | |
362 | pm->last_activity = jiffies; |
363 | if (--pm->wake.count == 0 && |
364 | test_bit(MT76_STATE_MCU_RUNNING, &phy->state)) |
365 | mt76_connac_power_save_sched(phy, pm); |
366 | |
367 | spin_unlock_bh(lock: &pm->wake.lock); |
368 | } |
369 | |
370 | static inline bool |
371 | mt76_connac_skip_fw_pmctrl(struct mt76_phy *phy, struct mt76_connac_pm *pm) |
372 | { |
373 | struct mt76_dev *dev = phy->dev; |
374 | bool ret; |
375 | |
376 | if (dev->token_count) |
377 | return true; |
378 | |
379 | spin_lock_bh(lock: &pm->wake.lock); |
380 | ret = pm->wake.count || test_and_set_bit(nr: MT76_STATE_PM, addr: &phy->state); |
381 | spin_unlock_bh(lock: &pm->wake.lock); |
382 | |
383 | return ret; |
384 | } |
385 | |
386 | static inline void |
387 | mt76_connac_mutex_acquire(struct mt76_dev *dev, struct mt76_connac_pm *pm) |
388 | __acquires(&dev->mutex) |
389 | { |
390 | mutex_lock(&dev->mutex); |
391 | mt76_connac_pm_wake(phy: &dev->phy, pm); |
392 | } |
393 | |
394 | static inline void |
395 | mt76_connac_mutex_release(struct mt76_dev *dev, struct mt76_connac_pm *pm) |
396 | __releases(&dev->mutex) |
397 | { |
398 | mt76_connac_power_save_sched(phy: &dev->phy, pm); |
399 | mutex_unlock(lock: &dev->mutex); |
400 | } |
401 | |
402 | void mt76_connac_gen_ppe_thresh(u8 *he_ppet, int nss); |
403 | int mt76_connac_init_tx_queues(struct mt76_phy *phy, int idx, int n_desc, |
404 | int ring_base, void *wed, u32 flags); |
405 | |
406 | void mt76_connac_write_hw_txp(struct mt76_dev *dev, |
407 | struct mt76_tx_info *tx_info, |
408 | void *txp_ptr, u32 id); |
409 | void mt76_connac_txp_skb_unmap(struct mt76_dev *dev, |
410 | struct mt76_txwi_cache *txwi); |
411 | void mt76_connac_tx_complete_skb(struct mt76_dev *mdev, |
412 | struct mt76_queue_entry *e); |
413 | void mt76_connac_pm_queue_skb(struct ieee80211_hw *hw, |
414 | struct mt76_connac_pm *pm, |
415 | struct mt76_wcid *wcid, |
416 | struct sk_buff *skb); |
417 | void mt76_connac_pm_dequeue_skbs(struct mt76_phy *phy, |
418 | struct mt76_connac_pm *pm); |
419 | void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, |
420 | struct sk_buff *skb, struct mt76_wcid *wcid, |
421 | struct ieee80211_key_conf *key, int pid, |
422 | enum mt76_txq_id qid, u32 changed); |
423 | u16 mt76_connac2_mac_tx_rate_val(struct mt76_phy *mphy, |
424 | struct ieee80211_vif *vif, |
425 | bool beacon, bool mcast); |
426 | bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid, |
427 | __le32 *txs_data); |
428 | bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid, |
429 | int pid, __le32 *txs_data); |
430 | void mt76_connac2_mac_decode_he_radiotap(struct mt76_dev *dev, |
431 | struct sk_buff *skb, |
432 | __le32 *rxv, u32 mode); |
433 | int mt76_connac2_reverse_frag0_hdr_trans(struct ieee80211_vif *vif, |
434 | struct sk_buff *skb, u16 hdr_offset); |
435 | int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev, |
436 | struct mt76_rx_status *status, |
437 | struct ieee80211_supported_band *sband, |
438 | __le32 *rxv, u8 *mode); |
439 | void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi); |
440 | void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t, |
441 | struct ieee80211_sta *sta, |
442 | struct list_head *free_list); |
443 | void mt76_connac2_tx_token_put(struct mt76_dev *dev); |
444 | |
445 | /* connac3 */ |
446 | void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, |
447 | u8 mode); |
448 | #endif /* __MT76_CONNAC_H */ |
449 | |