Commit | Line | Data |
---|---|---|
0e3d6777 | 1 | /* SPDX-License-Identifier: ISC */ |
108a4861 SG |
2 | /* |
3 | * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> | |
4 | * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl> | |
108a4861 SG |
5 | */ |
6 | ||
31217429 LB |
7 | #ifndef __MT76x02_H |
8 | #define __MT76x02_H | |
108a4861 | 9 | |
e40803f2 LB |
10 | #include <linux/kfifo.h> |
11 | ||
7a07adcd LB |
12 | #include "mt76.h" |
13 | #include "mt76x02_regs.h" | |
56e8d4dd | 14 | #include "mt76x02_mac.h" |
e40803f2 | 15 | #include "mt76x02_dfs.h" |
7a07adcd | 16 | #include "mt76x02_dma.h" |
e40803f2 | 17 | |
7dd73588 | 18 | #define MT_CALIBRATE_INTERVAL HZ |
2e405024 | 19 | #define MT_MAC_WORK_INTERVAL (HZ / 10) |
b2d871c0 | 20 | |
c1e0d2be LB |
21 | #define MT_WATCHDOG_TIME (HZ / 10) |
22 | #define MT_TX_HANG_TH 10 | |
23 | ||
e40803f2 LB |
24 | #define MT_MAX_CHAINS 2 |
25 | struct mt76x02_rx_freq_cal { | |
26 | s8 high_gain[MT_MAX_CHAINS]; | |
27 | s8 rssi_offset[MT_MAX_CHAINS]; | |
28 | s8 lna_gain; | |
29 | u32 mcu_gain; | |
b2d871c0 LB |
30 | s16 temp_offset; |
31 | u8 freq_offset; | |
e40803f2 LB |
32 | }; |
33 | ||
34 | struct mt76x02_calibration { | |
35 | struct mt76x02_rx_freq_cal rx; | |
36 | ||
37 | u8 agc_gain_init[MT_MAX_CHAINS]; | |
38 | u8 agc_gain_cur[MT_MAX_CHAINS]; | |
39 | ||
40 | u16 false_cca; | |
41 | s8 avg_rssi_all; | |
42 | s8 agc_gain_adjust; | |
a0ac8061 | 43 | s8 agc_lowest_gain; |
e40803f2 LB |
44 | s8 low_gain; |
45 | ||
66a34c66 LB |
46 | s8 temp_vco; |
47 | s8 temp; | |
e40803f2 LB |
48 | |
49 | bool init_cal_done; | |
50 | bool tssi_cal_done; | |
51 | bool tssi_comp_pending; | |
52 | bool dpd_cal_done; | |
53 | bool channel_cal_done; | |
f1b8ee35 | 54 | bool gain_init_done; |
3548a9dd LB |
55 | |
56 | int tssi_target; | |
57 | s8 tssi_dc; | |
e40803f2 LB |
58 | }; |
59 | ||
c004b881 | 60 | struct mt76x02_beacon_ops { |
f2276c29 SG |
61 | unsigned int nslots; |
62 | unsigned int slot_size; | |
ff97c52a RL |
63 | void (*pre_tbtt_enable)(struct mt76x02_dev *dev, bool en); |
64 | void (*beacon_enable)(struct mt76x02_dev *dev, bool en); | |
c004b881 SG |
65 | }; |
66 | ||
e40803f2 LB |
67 | struct mt76x02_dev { |
68 | struct mt76_dev mt76; /* must be first */ | |
69 | ||
70 | struct mac_address macaddr_list[8]; | |
71 | ||
b2d871c0 | 72 | struct mutex phy_mutex; |
e40803f2 | 73 | |
06662264 SG |
74 | u16 vif_mask; |
75 | ||
e40803f2 LB |
76 | u8 txdone_seq; |
77 | DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status); | |
6fe53337 | 78 | spinlock_t txstatus_fifo_lock; |
e40803f2 LB |
79 | |
80 | struct sk_buff *rx_head; | |
81 | ||
e40803f2 | 82 | struct delayed_work cal_work; |
c1e0d2be | 83 | struct delayed_work wdt_work; |
e40803f2 | 84 | |
5a3f1cc2 SG |
85 | struct hrtimer pre_tbtt_timer; |
86 | struct work_struct pre_tbtt_work; | |
87 | ||
c004b881 SG |
88 | const struct mt76x02_beacon_ops *beacon_ops; |
89 | ||
e40803f2 LB |
90 | u32 aggr_stats[32]; |
91 | ||
92 | struct sk_buff *beacons[8]; | |
e40803f2 LB |
93 | u8 beacon_data_mask; |
94 | ||
95 | u8 tbtt_count; | |
e40803f2 | 96 | |
c1e0d2be LB |
97 | u32 tx_hang_reset; |
98 | u8 tx_hang_check; | |
72e5d479 | 99 | u8 mcu_timeout; |
c1e0d2be | 100 | |
e40803f2 LB |
101 | struct mt76x02_calibration cal; |
102 | ||
103 | s8 target_power; | |
104 | s8 target_power_delta[2]; | |
105 | bool enable_tpc; | |
106 | ||
b2d871c0 LB |
107 | bool no_2ghz; |
108 | ||
e40803f2 LB |
109 | u8 coverage_class; |
110 | u8 slottime; | |
111 | ||
112 | struct mt76x02_dfs_pattern_detector dfs_pd; | |
f82ce8d9 LB |
113 | |
114 | /* edcca monitor */ | |
a0ac8061 | 115 | unsigned long ed_trigger_timeout; |
f82ce8d9 LB |
116 | bool ed_tx_blocked; |
117 | bool ed_monitor; | |
643749d4 | 118 | u8 ed_monitor_enabled; |
a0ac8061 | 119 | u8 ed_monitor_learning; |
f82ce8d9 LB |
120 | u8 ed_trigger; |
121 | u8 ed_silent; | |
ccdaf7b4 | 122 | ktime_t ed_time; |
e40803f2 | 123 | }; |
56e8d4dd | 124 | |
58b5eb8c LB |
125 | extern struct ieee80211_rate mt76x02_rates[12]; |
126 | ||
5cbace02 | 127 | void mt76x02_init_device(struct mt76x02_dev *dev); |
108a4861 | 128 | void mt76x02_configure_filter(struct ieee80211_hw *hw, |
ff97c52a RL |
129 | unsigned int changed_flags, |
130 | unsigned int *total_flags, u64 multicast); | |
e28487ea FF |
131 | int mt76x02_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
132 | struct ieee80211_sta *sta); | |
133 | void mt76x02_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, | |
134 | struct ieee80211_sta *sta); | |
cab12953 | 135 | |
269906ac | 136 | void mt76x02_config_mac_addr_list(struct mt76x02_dev *dev); |
f9a043c5 | 137 | |
212926eb | 138 | int mt76x02_add_interface(struct ieee80211_hw *hw, |
ff97c52a | 139 | struct ieee80211_vif *vif); |
0cd47bae | 140 | void mt76x02_remove_interface(struct ieee80211_hw *hw, |
ff97c52a | 141 | struct ieee80211_vif *vif); |
22c575c4 SG |
142 | |
143 | int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |
ff97c52a | 144 | struct ieee80211_ampdu_params *params); |
60c26859 | 145 | int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
ff97c52a RL |
146 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
147 | struct ieee80211_key_conf *key); | |
10337263 | 148 | int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
ff97c52a | 149 | u16 queue, const struct ieee80211_tx_queue_params *params); |
5327b5ea | 150 | void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, |
ff97c52a RL |
151 | struct ieee80211_vif *vif, |
152 | struct ieee80211_sta *sta); | |
91be8e8a | 153 | s8 mt76x02_tx_get_max_txpwr_adj(struct mt76x02_dev *dev, |
d697b00b | 154 | const struct ieee80211_tx_rate *rate); |
91be8e8a LB |
155 | s8 mt76x02_tx_get_txpwr_adj(struct mt76x02_dev *dev, s8 txpwr, |
156 | s8 max_txpwr_adj); | |
c1e0d2be | 157 | void mt76x02_wdt_work(struct work_struct *work); |
1ea0a1b1 | 158 | void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev *dev, s8 txpwr); |
36704051 LB |
159 | void mt76x02_set_tx_ackto(struct mt76x02_dev *dev); |
160 | void mt76x02_set_coverage_class(struct ieee80211_hw *hw, | |
161 | s16 coverage_class); | |
317ed42b | 162 | int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, u32 val); |
0e59cba8 | 163 | void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len); |
8d66af49 | 164 | bool mt76x02_tx_status_data(struct mt76_dev *mdev, u8 *update); |
9ba1e0e6 LB |
165 | void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, |
166 | struct sk_buff *skb); | |
9b43960b LB |
167 | void mt76x02_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q); |
168 | irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance); | |
2f0308d0 LB |
169 | void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, |
170 | struct sk_buff *skb); | |
5ec57485 | 171 | int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi, |
cfaae9e6 LB |
172 | enum mt76_txq_id qid, struct mt76_wcid *wcid, |
173 | struct ieee80211_sta *sta, | |
b5903c47 | 174 | struct mt76_tx_info *tx_info); |
c2756a1c LB |
175 | void mt76x02_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
176 | const u8 *mac); | |
177 | void mt76x02_sw_scan_complete(struct ieee80211_hw *hw, | |
178 | struct ieee80211_vif *vif); | |
f7c8a0f2 | 179 | void mt76x02_sta_ps(struct mt76_dev *dev, struct ieee80211_sta *sta, bool ps); |
cc726268 LB |
180 | void mt76x02_bss_info_changed(struct ieee80211_hw *hw, |
181 | struct ieee80211_vif *vif, | |
182 | struct ieee80211_bss_conf *info, u32 changed); | |
957068c2 | 183 | |
31cdd442 SG |
184 | struct beacon_bc_data { |
185 | struct mt76x02_dev *dev; | |
186 | struct sk_buff_head q; | |
187 | struct sk_buff *tail[8]; | |
188 | }; | |
ff97c52a | 189 | |
fc245983 | 190 | void mt76x02_init_beacon_config(struct mt76x02_dev *dev); |
8d71aef9 | 191 | void mt76x02e_init_beacon_config(struct mt76x02_dev *dev); |
31cdd442 SG |
192 | void mt76x02_resync_beacon_timer(struct mt76x02_dev *dev); |
193 | void mt76x02_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif); | |
194 | void mt76x02_enqueue_buffered_bc(struct mt76x02_dev *dev, | |
195 | struct beacon_bc_data *data, | |
196 | int max_nframes); | |
197 | ||
a23fde09 | 198 | void mt76x02_mac_start(struct mt76x02_dev *dev); |
957068c2 | 199 | |
76055413 LB |
200 | void mt76x02_init_debugfs(struct mt76x02_dev *dev); |
201 | ||
40b94161 SG |
202 | static inline bool is_mt76x0(struct mt76x02_dev *dev) |
203 | { | |
204 | return mt76_chip(&dev->mt76) == 0x7610 || | |
205 | mt76_chip(&dev->mt76) == 0x7630 || | |
206 | mt76_chip(&dev->mt76) == 0x7650; | |
207 | } | |
208 | ||
320c85e6 LB |
209 | static inline bool is_mt76x2(struct mt76x02_dev *dev) |
210 | { | |
211 | return mt76_chip(&dev->mt76) == 0x7612 || | |
212 | mt76_chip(&dev->mt76) == 0x7662 || | |
213 | mt76_chip(&dev->mt76) == 0x7602; | |
214 | } | |
215 | ||
a23fde09 | 216 | static inline void mt76x02_irq_enable(struct mt76x02_dev *dev, u32 mask) |
957068c2 | 217 | { |
9220f695 | 218 | mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, 0, mask); |
957068c2 LB |
219 | } |
220 | ||
a23fde09 | 221 | static inline void mt76x02_irq_disable(struct mt76x02_dev *dev, u32 mask) |
957068c2 | 222 | { |
9220f695 | 223 | mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0); |
957068c2 LB |
224 | } |
225 | ||
71322416 LB |
226 | static inline bool |
227 | mt76x02_wait_for_txrx_idle(struct mt76_dev *dev) | |
228 | { | |
229 | return __mt76_poll_msec(dev, MT_MAC_STATUS, | |
230 | MT_MAC_STATUS_TX | MT_MAC_STATUS_RX, | |
231 | 0, 100); | |
232 | } | |
233 | ||
56e8d4dd LB |
234 | static inline struct mt76x02_sta * |
235 | mt76x02_rx_get_sta(struct mt76_dev *dev, u8 idx) | |
236 | { | |
237 | struct mt76_wcid *wcid; | |
238 | ||
239 | if (idx >= ARRAY_SIZE(dev->wcid)) | |
240 | return NULL; | |
241 | ||
242 | wcid = rcu_dereference(dev->wcid[idx]); | |
243 | if (!wcid) | |
244 | return NULL; | |
245 | ||
246 | return container_of(wcid, struct mt76x02_sta, wcid); | |
247 | } | |
248 | ||
249 | static inline struct mt76_wcid * | |
250 | mt76x02_rx_get_sta_wcid(struct mt76x02_sta *sta, bool unicast) | |
251 | { | |
252 | if (!sta) | |
253 | return NULL; | |
254 | ||
255 | if (unicast) | |
256 | return &sta->wcid; | |
257 | else | |
258 | return &sta->vif->group_wcid; | |
259 | } | |
260 | ||
31217429 | 261 | #endif /* __MT76x02_H */ |