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