Commit | Line | Data |
---|---|---|
c869f77d JK |
1 | /* |
2 | * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org> | |
3 | * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl> | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License version 2 | |
7 | * as published by the Free Software Foundation | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | */ | |
14 | ||
15 | #ifndef MT7601U_H | |
16 | #define MT7601U_H | |
17 | ||
d43af505 | 18 | #include <linux/bitfield.h> |
c869f77d JK |
19 | #include <linux/kernel.h> |
20 | #include <linux/device.h> | |
21 | #include <linux/mutex.h> | |
22 | #include <linux/usb.h> | |
23 | #include <linux/completion.h> | |
24 | #include <net/mac80211.h> | |
25 | #include <linux/debugfs.h> | |
26 | ||
27 | #include "regs.h" | |
c869f77d JK |
28 | |
29 | #define MT_CALIBRATE_INTERVAL (4 * HZ) | |
30 | ||
31 | #define MT_FREQ_CAL_INIT_DELAY (30 * HZ) | |
32 | #define MT_FREQ_CAL_CHECK_INTERVAL (10 * HZ) | |
33 | #define MT_FREQ_CAL_ADJ_INTERVAL (HZ / 2) | |
34 | ||
35 | #define MT_BBP_REG_VERSION 0x00 | |
36 | ||
37 | #define MT_USB_AGGR_SIZE_LIMIT 28 /* * 1024B */ | |
38 | #define MT_USB_AGGR_TIMEOUT 0x80 /* * 33ns */ | |
39 | #define MT_RX_ORDER 3 | |
40 | #define MT_RX_URB_SIZE (PAGE_SIZE << MT_RX_ORDER) | |
41 | ||
42 | struct mt7601u_dma_buf { | |
43 | struct urb *urb; | |
44 | void *buf; | |
45 | dma_addr_t dma; | |
46 | size_t len; | |
47 | }; | |
48 | ||
49 | struct mt7601u_mcu { | |
50 | struct mutex mutex; | |
51 | ||
52 | u8 msg_seq; | |
53 | ||
54 | struct mt7601u_dma_buf resp; | |
55 | struct completion resp_cmpl; | |
56 | }; | |
57 | ||
58 | struct mt7601u_freq_cal { | |
59 | struct delayed_work work; | |
60 | u8 freq; | |
61 | bool enabled; | |
62 | bool adjusting; | |
63 | }; | |
64 | ||
65 | struct mac_stats { | |
66 | u64 rx_stat[6]; | |
67 | u64 tx_stat[6]; | |
68 | u64 aggr_stat[2]; | |
69 | u64 aggr_n[32]; | |
70 | u64 zero_len_del[2]; | |
71 | }; | |
72 | ||
73 | #define N_RX_ENTRIES 16 | |
74 | struct mt7601u_rx_queue { | |
75 | struct mt7601u_dev *dev; | |
76 | ||
77 | struct mt7601u_dma_buf_rx { | |
78 | struct urb *urb; | |
79 | struct page *p; | |
80 | } e[N_RX_ENTRIES]; | |
81 | ||
82 | unsigned int start; | |
83 | unsigned int end; | |
84 | unsigned int entries; | |
85 | unsigned int pending; | |
86 | }; | |
87 | ||
88 | #define N_TX_ENTRIES 64 | |
89 | ||
90 | struct mt7601u_tx_queue { | |
91 | struct mt7601u_dev *dev; | |
92 | ||
93 | struct mt7601u_dma_buf_tx { | |
94 | struct urb *urb; | |
95 | struct sk_buff *skb; | |
96 | } e[N_TX_ENTRIES]; | |
97 | ||
98 | unsigned int start; | |
99 | unsigned int end; | |
100 | unsigned int entries; | |
101 | unsigned int used; | |
102 | unsigned int fifo_seq; | |
103 | }; | |
104 | ||
105 | /* WCID allocation: | |
106 | * 0: mcast wcid | |
107 | * 1: bssid wcid | |
108 | * 1...: STAs | |
109 | * ...7e: group wcids | |
110 | * 7f: reserved | |
111 | */ | |
112 | #define N_WCIDS 128 | |
113 | #define GROUP_WCID(idx) (N_WCIDS - 2 - idx) | |
114 | ||
115 | struct mt7601u_eeprom_params; | |
116 | ||
117 | #define MT_EE_TEMPERATURE_SLOPE 39 | |
118 | #define MT_FREQ_OFFSET_INVALID -128 | |
119 | ||
120 | enum mt_temp_mode { | |
121 | MT_TEMP_MODE_NORMAL, | |
122 | MT_TEMP_MODE_HIGH, | |
123 | MT_TEMP_MODE_LOW, | |
124 | }; | |
125 | ||
126 | enum mt_bw { | |
127 | MT_BW_20, | |
128 | MT_BW_40, | |
129 | }; | |
130 | ||
131 | enum { | |
132 | MT7601U_STATE_INITIALIZED, | |
133 | MT7601U_STATE_REMOVED, | |
134 | MT7601U_STATE_WLAN_RUNNING, | |
135 | MT7601U_STATE_MCU_RUNNING, | |
136 | MT7601U_STATE_SCANNING, | |
137 | MT7601U_STATE_READING_STATS, | |
138 | MT7601U_STATE_MORE_STATS, | |
139 | }; | |
140 | ||
141 | /** | |
142 | * struct mt7601u_dev - adapter structure | |
143 | * @lock: protects @wcid->tx_rate. | |
78623bfb | 144 | * @mac_lock: locks out mac80211's tx status and rx paths. |
c869f77d | 145 | * @tx_lock: protects @tx_q and changes of MT7601U_STATE_*_STATS |
78623bfb | 146 | * flags in @state. |
c869f77d JK |
147 | * @rx_lock: protects @rx_q. |
148 | * @con_mon_lock: protects @ap_bssid, @bcn_*, @avg_rssi. | |
149 | * @mutex: ensures exclusive access from mac80211 callbacks. | |
bed429e1 | 150 | * @vendor_req_mutex: protects @vend_buf, ensures atomicity of split writes. |
c869f77d JK |
151 | * @reg_atomic_mutex: ensures atomicity of indirect register accesses |
152 | * (accesses to RF and BBP). | |
153 | * @hw_atomic_mutex: ensures exclusive access to HW during critical | |
154 | * operations (power management, channel switch). | |
155 | */ | |
156 | struct mt7601u_dev { | |
157 | struct ieee80211_hw *hw; | |
158 | struct device *dev; | |
159 | ||
160 | unsigned long state; | |
161 | ||
162 | struct mutex mutex; | |
163 | ||
164 | unsigned long wcid_mask[N_WCIDS / BITS_PER_LONG]; | |
165 | ||
166 | struct cfg80211_chan_def chandef; | |
167 | struct ieee80211_supported_band *sband_2g; | |
168 | ||
169 | struct mt7601u_mcu mcu; | |
170 | ||
171 | struct delayed_work cal_work; | |
172 | struct delayed_work mac_work; | |
173 | ||
174 | struct workqueue_struct *stat_wq; | |
175 | struct delayed_work stat_work; | |
176 | ||
177 | struct mt76_wcid *mon_wcid; | |
178 | struct mt76_wcid __rcu *wcid[N_WCIDS]; | |
179 | ||
180 | spinlock_t lock; | |
78623bfb | 181 | spinlock_t mac_lock; |
c869f77d JK |
182 | |
183 | const u16 *beacon_offsets; | |
184 | ||
185 | u8 macaddr[ETH_ALEN]; | |
186 | struct mt7601u_eeprom_params *ee; | |
187 | ||
188 | struct mutex vendor_req_mutex; | |
bed429e1 JK |
189 | void *vend_buf; |
190 | ||
c869f77d JK |
191 | struct mutex reg_atomic_mutex; |
192 | struct mutex hw_atomic_mutex; | |
193 | ||
194 | u32 rxfilter; | |
195 | u32 debugfs_reg; | |
196 | ||
197 | u8 out_eps[8]; | |
198 | u8 in_eps[8]; | |
199 | u16 out_max_packet; | |
200 | u16 in_max_packet; | |
201 | ||
202 | /* TX */ | |
203 | spinlock_t tx_lock; | |
4513493d | 204 | struct tasklet_struct tx_tasklet; |
c869f77d | 205 | struct mt7601u_tx_queue *tx_q; |
4513493d | 206 | struct sk_buff_head tx_skb_done; |
c869f77d JK |
207 | |
208 | atomic_t avg_ampdu_len; | |
209 | ||
210 | /* RX */ | |
211 | spinlock_t rx_lock; | |
212 | struct tasklet_struct rx_tasklet; | |
213 | struct mt7601u_rx_queue rx_q; | |
214 | ||
215 | /* Connection monitoring things */ | |
216 | spinlock_t con_mon_lock; | |
217 | u8 ap_bssid[ETH_ALEN]; | |
218 | ||
219 | s8 bcn_freq_off; | |
220 | u8 bcn_phy_mode; | |
221 | ||
222 | int avg_rssi; /* starts at 0 and converges */ | |
223 | ||
224 | u8 agc_save; | |
225 | ||
226 | struct mt7601u_freq_cal freq_cal; | |
227 | ||
228 | bool tssi_read_trig; | |
229 | ||
230 | s8 tssi_init; | |
231 | s8 tssi_init_hvga; | |
232 | s16 tssi_init_hvga_offset_db; | |
233 | ||
234 | int prev_pwr_diff; | |
235 | ||
236 | enum mt_temp_mode temp_mode; | |
237 | int curr_temp; | |
238 | int dpd_temp; | |
239 | s8 raw_temp; | |
240 | bool pll_lock_protect; | |
241 | ||
242 | u8 bw; | |
243 | bool chan_ext_below; | |
244 | ||
245 | /* PA mode */ | |
246 | u32 rf_pa_mode[2]; | |
247 | ||
248 | struct mac_stats stats; | |
249 | }; | |
250 | ||
251 | struct mt7601u_tssi_params { | |
252 | char tssi0; | |
253 | int trgt_power; | |
254 | }; | |
255 | ||
256 | struct mt76_wcid { | |
257 | u8 idx; | |
258 | u8 hw_key_idx; | |
259 | ||
260 | u16 tx_rate; | |
261 | bool tx_rate_set; | |
262 | u8 tx_rate_nss; | |
263 | }; | |
264 | ||
265 | struct mt76_vif { | |
266 | u8 idx; | |
267 | ||
268 | struct mt76_wcid group_wcid; | |
269 | }; | |
270 | ||
271 | struct mt76_sta { | |
272 | struct mt76_wcid wcid; | |
273 | u16 agg_ssn[IEEE80211_NUM_TIDS]; | |
274 | }; | |
275 | ||
276 | struct mt76_reg_pair { | |
277 | u32 reg; | |
278 | u32 value; | |
279 | }; | |
280 | ||
281 | struct mt7601u_rxwi; | |
282 | ||
283 | extern const struct ieee80211_ops mt7601u_ops; | |
284 | ||
285 | void mt7601u_init_debugfs(struct mt7601u_dev *dev); | |
286 | ||
287 | u32 mt7601u_rr(struct mt7601u_dev *dev, u32 offset); | |
288 | void mt7601u_wr(struct mt7601u_dev *dev, u32 offset, u32 val); | |
289 | u32 mt7601u_rmw(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val); | |
290 | u32 mt7601u_rmc(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val); | |
291 | void mt7601u_wr_copy(struct mt7601u_dev *dev, u32 offset, | |
292 | const void *data, int len); | |
293 | ||
294 | int mt7601u_wait_asic_ready(struct mt7601u_dev *dev); | |
295 | bool mt76_poll(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val, | |
296 | int timeout); | |
297 | bool mt76_poll_msec(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val, | |
298 | int timeout); | |
299 | ||
300 | /* Compatibility with mt76 */ | |
301 | #define mt76_rmw_field(_dev, _reg, _field, _val) \ | |
d43af505 | 302 | mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) |
c869f77d JK |
303 | |
304 | static inline u32 mt76_rr(struct mt7601u_dev *dev, u32 offset) | |
305 | { | |
306 | return mt7601u_rr(dev, offset); | |
307 | } | |
308 | ||
309 | static inline void mt76_wr(struct mt7601u_dev *dev, u32 offset, u32 val) | |
310 | { | |
311 | return mt7601u_wr(dev, offset, val); | |
312 | } | |
313 | ||
314 | static inline u32 | |
315 | mt76_rmw(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val) | |
316 | { | |
317 | return mt7601u_rmw(dev, offset, mask, val); | |
318 | } | |
319 | ||
320 | static inline u32 mt76_set(struct mt7601u_dev *dev, u32 offset, u32 val) | |
321 | { | |
322 | return mt76_rmw(dev, offset, 0, val); | |
323 | } | |
324 | ||
325 | static inline u32 mt76_clear(struct mt7601u_dev *dev, u32 offset, u32 val) | |
326 | { | |
327 | return mt76_rmw(dev, offset, val, 0); | |
328 | } | |
329 | ||
330 | int mt7601u_write_reg_pairs(struct mt7601u_dev *dev, u32 base, | |
331 | const struct mt76_reg_pair *data, int len); | |
332 | int mt7601u_burst_write_regs(struct mt7601u_dev *dev, u32 offset, | |
333 | const u32 *data, int n); | |
334 | void mt7601u_addr_wr(struct mt7601u_dev *dev, const u32 offset, const u8 *addr); | |
335 | ||
336 | /* Init */ | |
337 | struct mt7601u_dev *mt7601u_alloc_device(struct device *dev); | |
338 | int mt7601u_init_hardware(struct mt7601u_dev *dev); | |
339 | int mt7601u_register_device(struct mt7601u_dev *dev); | |
340 | void mt7601u_cleanup(struct mt7601u_dev *dev); | |
341 | ||
342 | int mt7601u_mac_start(struct mt7601u_dev *dev); | |
343 | void mt7601u_mac_stop(struct mt7601u_dev *dev); | |
344 | ||
345 | /* PHY */ | |
346 | int mt7601u_phy_init(struct mt7601u_dev *dev); | |
347 | int mt7601u_wait_bbp_ready(struct mt7601u_dev *dev); | |
348 | void mt7601u_set_rx_path(struct mt7601u_dev *dev, u8 path); | |
349 | void mt7601u_set_tx_dac(struct mt7601u_dev *dev, u8 path); | |
350 | int mt7601u_bbp_set_bw(struct mt7601u_dev *dev, int bw); | |
351 | void mt7601u_agc_save(struct mt7601u_dev *dev); | |
352 | void mt7601u_agc_restore(struct mt7601u_dev *dev); | |
353 | int mt7601u_phy_set_channel(struct mt7601u_dev *dev, | |
354 | struct cfg80211_chan_def *chandef); | |
355 | void mt7601u_phy_recalibrate_after_assoc(struct mt7601u_dev *dev); | |
356 | int mt7601u_phy_get_rssi(struct mt7601u_dev *dev, | |
357 | struct mt7601u_rxwi *rxwi, u16 rate); | |
358 | void mt7601u_phy_con_cal_onoff(struct mt7601u_dev *dev, | |
359 | struct ieee80211_bss_conf *info); | |
360 | ||
361 | /* MAC */ | |
362 | void mt7601u_mac_work(struct work_struct *work); | |
363 | void mt7601u_mac_set_protection(struct mt7601u_dev *dev, bool legacy_prot, | |
364 | int ht_mode); | |
365 | void mt7601u_mac_set_short_preamble(struct mt7601u_dev *dev, bool short_preamb); | |
366 | void mt7601u_mac_config_tsf(struct mt7601u_dev *dev, bool enable, int interval); | |
367 | void | |
368 | mt7601u_mac_wcid_setup(struct mt7601u_dev *dev, u8 idx, u8 vif_idx, u8 *mac); | |
369 | void mt7601u_mac_set_ampdu_factor(struct mt7601u_dev *dev); | |
370 | ||
371 | /* TX */ | |
372 | void mt7601u_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, | |
373 | struct sk_buff *skb); | |
374 | int mt7601u_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |
375 | u16 queue, const struct ieee80211_tx_queue_params *params); | |
376 | void mt7601u_tx_status(struct mt7601u_dev *dev, struct sk_buff *skb); | |
377 | void mt7601u_tx_stat(struct work_struct *work); | |
378 | ||
379 | /* util */ | |
380 | void mt76_remove_hdr_pad(struct sk_buff *skb); | |
381 | int mt76_insert_hdr_pad(struct sk_buff *skb); | |
382 | ||
383 | u32 mt7601u_bbp_set_ctrlch(struct mt7601u_dev *dev, bool below); | |
384 | ||
385 | static inline u32 mt7601u_mac_set_ctrlch(struct mt7601u_dev *dev, bool below) | |
386 | { | |
387 | return mt7601u_rmc(dev, MT_TX_BAND_CFG, 1, below); | |
388 | } | |
389 | ||
390 | int mt7601u_dma_init(struct mt7601u_dev *dev); | |
391 | void mt7601u_dma_cleanup(struct mt7601u_dev *dev); | |
392 | ||
393 | int mt7601u_dma_enqueue_tx(struct mt7601u_dev *dev, struct sk_buff *skb, | |
394 | struct mt76_wcid *wcid, int hw_q); | |
395 | ||
396 | #endif |