]>
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. | |
fee05843 LB |
150 | * @vendor_req_mutex: protects @vend_buf, ensures atomicity of read/write |
151 | * accesses | |
c869f77d JK |
152 | * @reg_atomic_mutex: ensures atomicity of indirect register accesses |
153 | * (accesses to RF and BBP). | |
154 | * @hw_atomic_mutex: ensures exclusive access to HW during critical | |
155 | * operations (power management, channel switch). | |
156 | */ | |
157 | struct mt7601u_dev { | |
158 | struct ieee80211_hw *hw; | |
159 | struct device *dev; | |
160 | ||
161 | unsigned long state; | |
162 | ||
163 | struct mutex mutex; | |
164 | ||
165 | unsigned long wcid_mask[N_WCIDS / BITS_PER_LONG]; | |
166 | ||
167 | struct cfg80211_chan_def chandef; | |
168 | struct ieee80211_supported_band *sband_2g; | |
169 | ||
170 | struct mt7601u_mcu mcu; | |
171 | ||
172 | struct delayed_work cal_work; | |
173 | struct delayed_work mac_work; | |
174 | ||
175 | struct workqueue_struct *stat_wq; | |
176 | struct delayed_work stat_work; | |
177 | ||
178 | struct mt76_wcid *mon_wcid; | |
179 | struct mt76_wcid __rcu *wcid[N_WCIDS]; | |
180 | ||
181 | spinlock_t lock; | |
78623bfb | 182 | spinlock_t mac_lock; |
c869f77d JK |
183 | |
184 | const u16 *beacon_offsets; | |
185 | ||
186 | u8 macaddr[ETH_ALEN]; | |
187 | struct mt7601u_eeprom_params *ee; | |
188 | ||
189 | struct mutex vendor_req_mutex; | |
bed429e1 JK |
190 | void *vend_buf; |
191 | ||
c869f77d JK |
192 | struct mutex reg_atomic_mutex; |
193 | struct mutex hw_atomic_mutex; | |
194 | ||
195 | u32 rxfilter; | |
196 | u32 debugfs_reg; | |
197 | ||
198 | u8 out_eps[8]; | |
199 | u8 in_eps[8]; | |
200 | u16 out_max_packet; | |
201 | u16 in_max_packet; | |
202 | ||
203 | /* TX */ | |
204 | spinlock_t tx_lock; | |
4513493d | 205 | struct tasklet_struct tx_tasklet; |
c869f77d | 206 | struct mt7601u_tx_queue *tx_q; |
4513493d | 207 | struct sk_buff_head tx_skb_done; |
c869f77d JK |
208 | |
209 | atomic_t avg_ampdu_len; | |
210 | ||
211 | /* RX */ | |
212 | spinlock_t rx_lock; | |
213 | struct tasklet_struct rx_tasklet; | |
214 | struct mt7601u_rx_queue rx_q; | |
215 | ||
216 | /* Connection monitoring things */ | |
217 | spinlock_t con_mon_lock; | |
218 | u8 ap_bssid[ETH_ALEN]; | |
219 | ||
220 | s8 bcn_freq_off; | |
221 | u8 bcn_phy_mode; | |
222 | ||
223 | int avg_rssi; /* starts at 0 and converges */ | |
224 | ||
225 | u8 agc_save; | |
226 | ||
227 | struct mt7601u_freq_cal freq_cal; | |
228 | ||
229 | bool tssi_read_trig; | |
230 | ||
231 | s8 tssi_init; | |
232 | s8 tssi_init_hvga; | |
233 | s16 tssi_init_hvga_offset_db; | |
234 | ||
235 | int prev_pwr_diff; | |
236 | ||
237 | enum mt_temp_mode temp_mode; | |
238 | int curr_temp; | |
239 | int dpd_temp; | |
240 | s8 raw_temp; | |
241 | bool pll_lock_protect; | |
242 | ||
243 | u8 bw; | |
244 | bool chan_ext_below; | |
245 | ||
246 | /* PA mode */ | |
247 | u32 rf_pa_mode[2]; | |
248 | ||
249 | struct mac_stats stats; | |
250 | }; | |
251 | ||
252 | struct mt7601u_tssi_params { | |
253 | char tssi0; | |
254 | int trgt_power; | |
255 | }; | |
256 | ||
257 | struct mt76_wcid { | |
258 | u8 idx; | |
259 | u8 hw_key_idx; | |
260 | ||
261 | u16 tx_rate; | |
262 | bool tx_rate_set; | |
263 | u8 tx_rate_nss; | |
264 | }; | |
265 | ||
266 | struct mt76_vif { | |
267 | u8 idx; | |
268 | ||
269 | struct mt76_wcid group_wcid; | |
270 | }; | |
271 | ||
272 | struct mt76_sta { | |
273 | struct mt76_wcid wcid; | |
274 | u16 agg_ssn[IEEE80211_NUM_TIDS]; | |
275 | }; | |
276 | ||
277 | struct mt76_reg_pair { | |
278 | u32 reg; | |
279 | u32 value; | |
280 | }; | |
281 | ||
282 | struct mt7601u_rxwi; | |
283 | ||
284 | extern const struct ieee80211_ops mt7601u_ops; | |
285 | ||
286 | void mt7601u_init_debugfs(struct mt7601u_dev *dev); | |
287 | ||
288 | u32 mt7601u_rr(struct mt7601u_dev *dev, u32 offset); | |
289 | void mt7601u_wr(struct mt7601u_dev *dev, u32 offset, u32 val); | |
290 | u32 mt7601u_rmw(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val); | |
291 | u32 mt7601u_rmc(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val); | |
292 | void mt7601u_wr_copy(struct mt7601u_dev *dev, u32 offset, | |
293 | const void *data, int len); | |
294 | ||
295 | int mt7601u_wait_asic_ready(struct mt7601u_dev *dev); | |
296 | bool mt76_poll(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val, | |
297 | int timeout); | |
298 | bool mt76_poll_msec(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val, | |
299 | int timeout); | |
300 | ||
301 | /* Compatibility with mt76 */ | |
302 | #define mt76_rmw_field(_dev, _reg, _field, _val) \ | |
d43af505 | 303 | mt76_rmw(_dev, _reg, _field, FIELD_PREP(_field, _val)) |
c869f77d JK |
304 | |
305 | static inline u32 mt76_rr(struct mt7601u_dev *dev, u32 offset) | |
306 | { | |
307 | return mt7601u_rr(dev, offset); | |
308 | } | |
309 | ||
310 | static inline void mt76_wr(struct mt7601u_dev *dev, u32 offset, u32 val) | |
311 | { | |
312 | return mt7601u_wr(dev, offset, val); | |
313 | } | |
314 | ||
315 | static inline u32 | |
316 | mt76_rmw(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val) | |
317 | { | |
318 | return mt7601u_rmw(dev, offset, mask, val); | |
319 | } | |
320 | ||
321 | static inline u32 mt76_set(struct mt7601u_dev *dev, u32 offset, u32 val) | |
322 | { | |
323 | return mt76_rmw(dev, offset, 0, val); | |
324 | } | |
325 | ||
326 | static inline u32 mt76_clear(struct mt7601u_dev *dev, u32 offset, u32 val) | |
327 | { | |
328 | return mt76_rmw(dev, offset, val, 0); | |
329 | } | |
330 | ||
331 | int mt7601u_write_reg_pairs(struct mt7601u_dev *dev, u32 base, | |
332 | const struct mt76_reg_pair *data, int len); | |
333 | int mt7601u_burst_write_regs(struct mt7601u_dev *dev, u32 offset, | |
334 | const u32 *data, int n); | |
335 | void mt7601u_addr_wr(struct mt7601u_dev *dev, const u32 offset, const u8 *addr); | |
336 | ||
337 | /* Init */ | |
338 | struct mt7601u_dev *mt7601u_alloc_device(struct device *dev); | |
339 | int mt7601u_init_hardware(struct mt7601u_dev *dev); | |
340 | int mt7601u_register_device(struct mt7601u_dev *dev); | |
341 | void mt7601u_cleanup(struct mt7601u_dev *dev); | |
342 | ||
343 | int mt7601u_mac_start(struct mt7601u_dev *dev); | |
344 | void mt7601u_mac_stop(struct mt7601u_dev *dev); | |
345 | ||
346 | /* PHY */ | |
347 | int mt7601u_phy_init(struct mt7601u_dev *dev); | |
348 | int mt7601u_wait_bbp_ready(struct mt7601u_dev *dev); | |
349 | void mt7601u_set_rx_path(struct mt7601u_dev *dev, u8 path); | |
350 | void mt7601u_set_tx_dac(struct mt7601u_dev *dev, u8 path); | |
351 | int mt7601u_bbp_set_bw(struct mt7601u_dev *dev, int bw); | |
352 | void mt7601u_agc_save(struct mt7601u_dev *dev); | |
353 | void mt7601u_agc_restore(struct mt7601u_dev *dev); | |
354 | int mt7601u_phy_set_channel(struct mt7601u_dev *dev, | |
355 | struct cfg80211_chan_def *chandef); | |
356 | void mt7601u_phy_recalibrate_after_assoc(struct mt7601u_dev *dev); | |
357 | int mt7601u_phy_get_rssi(struct mt7601u_dev *dev, | |
358 | struct mt7601u_rxwi *rxwi, u16 rate); | |
359 | void mt7601u_phy_con_cal_onoff(struct mt7601u_dev *dev, | |
360 | struct ieee80211_bss_conf *info); | |
361 | ||
362 | /* MAC */ | |
363 | void mt7601u_mac_work(struct work_struct *work); | |
364 | void mt7601u_mac_set_protection(struct mt7601u_dev *dev, bool legacy_prot, | |
365 | int ht_mode); | |
366 | void mt7601u_mac_set_short_preamble(struct mt7601u_dev *dev, bool short_preamb); | |
367 | void mt7601u_mac_config_tsf(struct mt7601u_dev *dev, bool enable, int interval); | |
368 | void | |
369 | mt7601u_mac_wcid_setup(struct mt7601u_dev *dev, u8 idx, u8 vif_idx, u8 *mac); | |
370 | void mt7601u_mac_set_ampdu_factor(struct mt7601u_dev *dev); | |
371 | ||
372 | /* TX */ | |
373 | void mt7601u_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, | |
374 | struct sk_buff *skb); | |
375 | int mt7601u_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |
376 | u16 queue, const struct ieee80211_tx_queue_params *params); | |
377 | void mt7601u_tx_status(struct mt7601u_dev *dev, struct sk_buff *skb); | |
378 | void mt7601u_tx_stat(struct work_struct *work); | |
379 | ||
380 | /* util */ | |
381 | void mt76_remove_hdr_pad(struct sk_buff *skb); | |
382 | int mt76_insert_hdr_pad(struct sk_buff *skb); | |
383 | ||
384 | u32 mt7601u_bbp_set_ctrlch(struct mt7601u_dev *dev, bool below); | |
385 | ||
386 | static inline u32 mt7601u_mac_set_ctrlch(struct mt7601u_dev *dev, bool below) | |
387 | { | |
388 | return mt7601u_rmc(dev, MT_TX_BAND_CFG, 1, below); | |
389 | } | |
390 | ||
391 | int mt7601u_dma_init(struct mt7601u_dev *dev); | |
392 | void mt7601u_dma_cleanup(struct mt7601u_dev *dev); | |
393 | ||
394 | int mt7601u_dma_enqueue_tx(struct mt7601u_dev *dev, struct sk_buff *skb, | |
395 | struct mt76_wcid *wcid, int hw_q); | |
396 | ||
397 | #endif |