1 | /* SPDX-License-Identifier: ISC */ |
2 | /* |
3 | * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> |
4 | * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl> |
5 | */ |
6 | |
7 | #ifndef __MT76x02_H |
8 | #define __MT76x02_H |
9 | |
10 | #include <linux/kfifo.h> |
11 | |
12 | #include "mt76.h" |
13 | #include "mt76x02_regs.h" |
14 | #include "mt76x02_mac.h" |
15 | #include "mt76x02_dfs.h" |
16 | #include "mt76x02_dma.h" |
17 | |
18 | #define MT76x02_TX_RING_SIZE 512 |
19 | #define MT76x02_PSD_RING_SIZE 128 |
20 | #define MT76x02_N_WCIDS 128 |
21 | #define MT_CALIBRATE_INTERVAL HZ |
22 | #define MT_MAC_WORK_INTERVAL (HZ / 10) |
23 | |
24 | #define MT_WATCHDOG_TIME (HZ / 10) |
25 | #define MT_TX_HANG_TH 10 |
26 | |
27 | #define MT_MAX_CHAINS 2 |
28 | struct mt76x02_rx_freq_cal { |
29 | s8 high_gain[MT_MAX_CHAINS]; |
30 | s8 [MT_MAX_CHAINS]; |
31 | s8 lna_gain; |
32 | u32 mcu_gain; |
33 | s16 temp_offset; |
34 | u8 freq_offset; |
35 | }; |
36 | |
37 | struct mt76x02_calibration { |
38 | struct mt76x02_rx_freq_cal rx; |
39 | |
40 | u8 agc_gain_init[MT_MAX_CHAINS]; |
41 | u8 agc_gain_cur[MT_MAX_CHAINS]; |
42 | |
43 | u16 false_cca; |
44 | s8 ; |
45 | s8 agc_gain_adjust; |
46 | s8 agc_lowest_gain; |
47 | s8 low_gain; |
48 | |
49 | s8 temp_vco; |
50 | s8 temp; |
51 | |
52 | bool init_cal_done; |
53 | bool tssi_cal_done; |
54 | bool tssi_comp_pending; |
55 | bool dpd_cal_done; |
56 | bool channel_cal_done; |
57 | bool gain_init_done; |
58 | |
59 | int tssi_target; |
60 | s8 tssi_dc; |
61 | }; |
62 | |
63 | struct mt76x02_beacon_ops { |
64 | unsigned int nslots; |
65 | unsigned int slot_size; |
66 | void (*pre_tbtt_enable)(struct mt76x02_dev *dev, bool en); |
67 | void (*beacon_enable)(struct mt76x02_dev *dev, bool en); |
68 | }; |
69 | |
70 | #define mt76x02_beacon_enable(dev, enable) \ |
71 | (dev)->beacon_ops->beacon_enable(dev, enable) |
72 | #define mt76x02_pre_tbtt_enable(dev, enable) \ |
73 | (dev)->beacon_ops->pre_tbtt_enable(dev, enable) |
74 | |
75 | struct mt76x02_rate_power { |
76 | union { |
77 | struct { |
78 | s8 cck[4]; |
79 | s8 ofdm[8]; |
80 | s8 ht[16]; |
81 | s8 vht[2]; |
82 | }; |
83 | s8 all[30]; |
84 | }; |
85 | }; |
86 | |
87 | struct mt76x02_dev { |
88 | union { /* must be first */ |
89 | struct mt76_dev mt76; |
90 | struct mt76_phy mphy; |
91 | }; |
92 | |
93 | struct mac_address macaddr_list[8]; |
94 | |
95 | struct mutex phy_mutex; |
96 | |
97 | u8 txdone_seq; |
98 | DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status); |
99 | spinlock_t txstatus_fifo_lock; |
100 | u32 tx_airtime; |
101 | u32 ampdu_ref; |
102 | |
103 | struct sk_buff *rx_head; |
104 | |
105 | struct delayed_work cal_work; |
106 | struct delayed_work wdt_work; |
107 | |
108 | struct hrtimer pre_tbtt_timer; |
109 | struct work_struct pre_tbtt_work; |
110 | |
111 | const struct mt76x02_beacon_ops *beacon_ops; |
112 | |
113 | u8 beacon_data_count; |
114 | |
115 | u8 tbtt_count; |
116 | |
117 | u32 tx_hang_reset; |
118 | u8 tx_hang_check[4]; |
119 | u8 beacon_hang_check; |
120 | u8 mcu_timeout; |
121 | |
122 | struct mt76x02_rate_power rate_power; |
123 | |
124 | struct mt76x02_calibration cal; |
125 | |
126 | int txpower_conf; |
127 | s8 target_power; |
128 | s8 target_power_delta[2]; |
129 | bool enable_tpc; |
130 | |
131 | bool no_2ghz; |
132 | |
133 | s16 coverage_class; |
134 | u8 slottime; |
135 | |
136 | struct mt76x02_dfs_pattern_detector dfs_pd; |
137 | |
138 | /* edcca monitor */ |
139 | unsigned long ed_trigger_timeout; |
140 | bool ed_tx_blocked; |
141 | bool ed_monitor; |
142 | u8 ed_monitor_enabled; |
143 | u8 ed_monitor_learning; |
144 | u8 ed_trigger; |
145 | u8 ed_silent; |
146 | ktime_t ed_time; |
147 | }; |
148 | |
149 | extern struct ieee80211_rate mt76x02_rates[12]; |
150 | |
151 | int mt76x02_init_device(struct mt76x02_dev *dev); |
152 | void mt76x02_configure_filter(struct ieee80211_hw *hw, |
153 | unsigned int changed_flags, |
154 | unsigned int *total_flags, u64 multicast); |
155 | int mt76x02_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
156 | struct ieee80211_sta *sta); |
157 | void mt76x02_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
158 | struct ieee80211_sta *sta); |
159 | |
160 | void mt76x02_config_mac_addr_list(struct mt76x02_dev *dev); |
161 | |
162 | int mt76x02_add_interface(struct ieee80211_hw *hw, |
163 | struct ieee80211_vif *vif); |
164 | void mt76x02_remove_interface(struct ieee80211_hw *hw, |
165 | struct ieee80211_vif *vif); |
166 | |
167 | int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
168 | struct ieee80211_ampdu_params *params); |
169 | int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
170 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
171 | struct ieee80211_key_conf *key); |
172 | int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
173 | unsigned int link_id, u16 queue, |
174 | const struct ieee80211_tx_queue_params *params); |
175 | void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, |
176 | struct ieee80211_vif *vif, |
177 | struct ieee80211_sta *sta); |
178 | s8 mt76x02_tx_get_max_txpwr_adj(struct mt76x02_dev *dev, |
179 | const struct ieee80211_tx_rate *rate); |
180 | s8 mt76x02_tx_get_txpwr_adj(struct mt76x02_dev *dev, s8 txpwr, |
181 | s8 max_txpwr_adj); |
182 | void mt76x02_wdt_work(struct work_struct *work); |
183 | void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev *dev, s8 txpwr); |
184 | void mt76x02_set_tx_ackto(struct mt76x02_dev *dev); |
185 | void mt76x02_set_coverage_class(struct ieee80211_hw *hw, |
186 | s16 coverage_class); |
187 | int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, u32 val); |
188 | void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len); |
189 | bool mt76x02_tx_status_data(struct mt76_dev *mdev, u8 *update); |
190 | void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, |
191 | struct sk_buff *skb, u32 *info); |
192 | void mt76x02_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q); |
193 | irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance); |
194 | void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, |
195 | struct sk_buff *skb); |
196 | int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi, |
197 | enum mt76_txq_id qid, struct mt76_wcid *wcid, |
198 | struct ieee80211_sta *sta, |
199 | struct mt76_tx_info *tx_info); |
200 | void mt76x02_sw_scan_complete(struct ieee80211_hw *hw, |
201 | struct ieee80211_vif *vif); |
202 | void mt76x02_sta_ps(struct mt76_dev *dev, struct ieee80211_sta *sta, bool ps); |
203 | void mt76x02_bss_info_changed(struct ieee80211_hw *hw, |
204 | struct ieee80211_vif *vif, |
205 | struct ieee80211_bss_conf *info, u64 changed); |
206 | void mt76x02_reconfig_complete(struct ieee80211_hw *hw, |
207 | enum ieee80211_reconfig_type reconfig_type); |
208 | |
209 | struct beacon_bc_data { |
210 | struct mt76x02_dev *dev; |
211 | struct sk_buff_head q; |
212 | struct sk_buff *tail[8]; |
213 | }; |
214 | |
215 | void mt76x02_init_beacon_config(struct mt76x02_dev *dev); |
216 | void mt76x02e_init_beacon_config(struct mt76x02_dev *dev); |
217 | void mt76x02_resync_beacon_timer(struct mt76x02_dev *dev); |
218 | void mt76x02_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif); |
219 | void mt76x02_enqueue_buffered_bc(struct mt76x02_dev *dev, |
220 | struct beacon_bc_data *data, |
221 | int max_nframes); |
222 | |
223 | void mt76x02_mac_start(struct mt76x02_dev *dev); |
224 | |
225 | void mt76x02_init_debugfs(struct mt76x02_dev *dev); |
226 | |
227 | static inline bool is_mt76x0(struct mt76x02_dev *dev) |
228 | { |
229 | return mt76_chip(dev: &dev->mt76) == 0x7610 || |
230 | mt76_chip(dev: &dev->mt76) == 0x7630 || |
231 | mt76_chip(dev: &dev->mt76) == 0x7650; |
232 | } |
233 | |
234 | static inline bool is_mt76x2(struct mt76x02_dev *dev) |
235 | { |
236 | return mt76_chip(dev: &dev->mt76) == 0x7612 || |
237 | mt76_chip(dev: &dev->mt76) == 0x7632 || |
238 | mt76_chip(dev: &dev->mt76) == 0x7662 || |
239 | mt76_chip(dev: &dev->mt76) == 0x7602; |
240 | } |
241 | |
242 | static inline void mt76x02_irq_enable(struct mt76x02_dev *dev, u32 mask) |
243 | { |
244 | mt76_set_irq_mask(dev: &dev->mt76, MT_INT_MASK_CSR, clear: 0, set: mask); |
245 | } |
246 | |
247 | static inline void mt76x02_irq_disable(struct mt76x02_dev *dev, u32 mask) |
248 | { |
249 | mt76_set_irq_mask(dev: &dev->mt76, MT_INT_MASK_CSR, clear: mask, set: 0); |
250 | } |
251 | |
252 | static inline bool |
253 | mt76x02_wait_for_txrx_idle(struct mt76_dev *dev) |
254 | { |
255 | return __mt76_poll_msec(dev, MT_MAC_STATUS, |
256 | MT_MAC_STATUS_TX | MT_MAC_STATUS_RX, |
257 | 0, 100); |
258 | } |
259 | |
260 | static inline struct mt76x02_sta * |
261 | mt76x02_rx_get_sta(struct mt76_dev *dev, u8 idx) |
262 | { |
263 | struct mt76_wcid *wcid; |
264 | |
265 | if (idx >= MT76x02_N_WCIDS) |
266 | return NULL; |
267 | |
268 | wcid = rcu_dereference(dev->wcid[idx]); |
269 | if (!wcid) |
270 | return NULL; |
271 | |
272 | return container_of(wcid, struct mt76x02_sta, wcid); |
273 | } |
274 | |
275 | static inline struct mt76_wcid * |
276 | mt76x02_rx_get_sta_wcid(struct mt76x02_sta *sta, bool unicast) |
277 | { |
278 | if (!sta) |
279 | return NULL; |
280 | |
281 | if (unicast) |
282 | return &sta->wcid; |
283 | else |
284 | return &sta->vif->group_wcid; |
285 | } |
286 | |
287 | #endif /* __MT76x02_H */ |
288 | |