diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8192de/trx.c')
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192de/trx.c | 959 |
1 files changed, 959 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c new file mode 100644 index 000000000000..bf1462f69b52 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c | |||
@@ -0,0 +1,959 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../wifi.h" | ||
31 | #include "../pci.h" | ||
32 | #include "../base.h" | ||
33 | #include "reg.h" | ||
34 | #include "def.h" | ||
35 | #include "phy.h" | ||
36 | #include "trx.h" | ||
37 | #include "led.h" | ||
38 | |||
39 | static u8 _rtl92de_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) | ||
40 | { | ||
41 | __le16 fc = rtl_get_fc(skb); | ||
42 | |||
43 | if (unlikely(ieee80211_is_beacon(fc))) | ||
44 | return QSLT_BEACON; | ||
45 | if (ieee80211_is_mgmt(fc)) | ||
46 | return QSLT_MGNT; | ||
47 | |||
48 | return skb->priority; | ||
49 | } | ||
50 | |||
51 | static int _rtl92de_rate_mapping(bool isht, u8 desc_rate) | ||
52 | { | ||
53 | int rate_idx; | ||
54 | |||
55 | if (false == isht) { | ||
56 | switch (desc_rate) { | ||
57 | case DESC92D_RATE1M: | ||
58 | rate_idx = 0; | ||
59 | break; | ||
60 | case DESC92D_RATE2M: | ||
61 | rate_idx = 1; | ||
62 | break; | ||
63 | case DESC92D_RATE5_5M: | ||
64 | rate_idx = 2; | ||
65 | break; | ||
66 | case DESC92D_RATE11M: | ||
67 | rate_idx = 3; | ||
68 | break; | ||
69 | case DESC92D_RATE6M: | ||
70 | rate_idx = 4; | ||
71 | break; | ||
72 | case DESC92D_RATE9M: | ||
73 | rate_idx = 5; | ||
74 | break; | ||
75 | case DESC92D_RATE12M: | ||
76 | rate_idx = 6; | ||
77 | break; | ||
78 | case DESC92D_RATE18M: | ||
79 | rate_idx = 7; | ||
80 | break; | ||
81 | case DESC92D_RATE24M: | ||
82 | rate_idx = 8; | ||
83 | break; | ||
84 | case DESC92D_RATE36M: | ||
85 | rate_idx = 9; | ||
86 | break; | ||
87 | case DESC92D_RATE48M: | ||
88 | rate_idx = 10; | ||
89 | break; | ||
90 | case DESC92D_RATE54M: | ||
91 | rate_idx = 11; | ||
92 | break; | ||
93 | default: | ||
94 | rate_idx = 0; | ||
95 | break; | ||
96 | } | ||
97 | return rate_idx; | ||
98 | } else { | ||
99 | switch (desc_rate) { | ||
100 | case DESC92D_RATE1M: | ||
101 | rate_idx = 0; | ||
102 | break; | ||
103 | case DESC92D_RATE2M: | ||
104 | rate_idx = 1; | ||
105 | break; | ||
106 | case DESC92D_RATE5_5M: | ||
107 | rate_idx = 2; | ||
108 | break; | ||
109 | case DESC92D_RATE11M: | ||
110 | rate_idx = 3; | ||
111 | break; | ||
112 | case DESC92D_RATE6M: | ||
113 | rate_idx = 4; | ||
114 | break; | ||
115 | case DESC92D_RATE9M: | ||
116 | rate_idx = 5; | ||
117 | break; | ||
118 | case DESC92D_RATE12M: | ||
119 | rate_idx = 6; | ||
120 | break; | ||
121 | case DESC92D_RATE18M: | ||
122 | rate_idx = 7; | ||
123 | break; | ||
124 | case DESC92D_RATE24M: | ||
125 | rate_idx = 8; | ||
126 | break; | ||
127 | case DESC92D_RATE36M: | ||
128 | rate_idx = 9; | ||
129 | break; | ||
130 | case DESC92D_RATE48M: | ||
131 | rate_idx = 10; | ||
132 | break; | ||
133 | case DESC92D_RATE54M: | ||
134 | rate_idx = 11; | ||
135 | break; | ||
136 | default: | ||
137 | rate_idx = 11; | ||
138 | break; | ||
139 | } | ||
140 | return rate_idx; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | static u8 _rtl92d_query_rxpwrpercentage(char antpower) | ||
145 | { | ||
146 | if ((antpower <= -100) || (antpower >= 20)) | ||
147 | return 0; | ||
148 | else if (antpower >= 0) | ||
149 | return 100; | ||
150 | else | ||
151 | return 100 + antpower; | ||
152 | } | ||
153 | |||
154 | static u8 _rtl92d_evm_db_to_percentage(char value) | ||
155 | { | ||
156 | char ret_val = value; | ||
157 | |||
158 | if (ret_val >= 0) | ||
159 | ret_val = 0; | ||
160 | if (ret_val <= -33) | ||
161 | ret_val = -33; | ||
162 | ret_val = 0 - ret_val; | ||
163 | ret_val *= 3; | ||
164 | if (ret_val == 99) | ||
165 | ret_val = 100; | ||
166 | return ret_val; | ||
167 | } | ||
168 | |||
169 | static long _rtl92de_translate_todbm(struct ieee80211_hw *hw, | ||
170 | u8 signal_strength_index) | ||
171 | { | ||
172 | long signal_power; | ||
173 | |||
174 | signal_power = (long)((signal_strength_index + 1) >> 1); | ||
175 | signal_power -= 95; | ||
176 | return signal_power; | ||
177 | } | ||
178 | |||
179 | static long _rtl92de_signal_scale_mapping(struct ieee80211_hw *hw, long currsig) | ||
180 | { | ||
181 | long retsig; | ||
182 | |||
183 | if (currsig >= 61 && currsig <= 100) | ||
184 | retsig = 90 + ((currsig - 60) / 4); | ||
185 | else if (currsig >= 41 && currsig <= 60) | ||
186 | retsig = 78 + ((currsig - 40) / 2); | ||
187 | else if (currsig >= 31 && currsig <= 40) | ||
188 | retsig = 66 + (currsig - 30); | ||
189 | else if (currsig >= 21 && currsig <= 30) | ||
190 | retsig = 54 + (currsig - 20); | ||
191 | else if (currsig >= 5 && currsig <= 20) | ||
192 | retsig = 42 + (((currsig - 5) * 2) / 3); | ||
193 | else if (currsig == 4) | ||
194 | retsig = 36; | ||
195 | else if (currsig == 3) | ||
196 | retsig = 27; | ||
197 | else if (currsig == 2) | ||
198 | retsig = 18; | ||
199 | else if (currsig == 1) | ||
200 | retsig = 9; | ||
201 | else | ||
202 | retsig = currsig; | ||
203 | return retsig; | ||
204 | } | ||
205 | |||
206 | static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw, | ||
207 | struct rtl_stats *pstats, | ||
208 | struct rx_desc_92d *pdesc, | ||
209 | struct rx_fwinfo_92d *p_drvinfo, | ||
210 | bool packet_match_bssid, | ||
211 | bool packet_toself, | ||
212 | bool packet_beacon) | ||
213 | { | ||
214 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
215 | struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); | ||
216 | struct phy_sts_cck_8192d *cck_buf; | ||
217 | s8 rx_pwr_all, rx_pwr[4]; | ||
218 | u8 rf_rx_num = 0, evm, pwdb_all; | ||
219 | u8 i, max_spatial_stream; | ||
220 | u32 rssi, total_rssi = 0; | ||
221 | bool is_cck_rate; | ||
222 | |||
223 | is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); | ||
224 | pstats->packet_matchbssid = packet_match_bssid; | ||
225 | pstats->packet_toself = packet_toself; | ||
226 | pstats->packet_beacon = packet_beacon; | ||
227 | pstats->is_cck = is_cck_rate; | ||
228 | pstats->rx_mimo_signalquality[0] = -1; | ||
229 | pstats->rx_mimo_signalquality[1] = -1; | ||
230 | |||
231 | if (is_cck_rate) { | ||
232 | u8 report, cck_highpwr; | ||
233 | cck_buf = (struct phy_sts_cck_8192d *)p_drvinfo; | ||
234 | if (ppsc->rfpwr_state == ERFON) | ||
235 | cck_highpwr = (u8) rtl_get_bbreg(hw, | ||
236 | RFPGA0_XA_HSSIPARAMETER2, | ||
237 | BIT(9)); | ||
238 | else | ||
239 | cck_highpwr = false; | ||
240 | if (!cck_highpwr) { | ||
241 | u8 cck_agc_rpt = cck_buf->cck_agc_rpt; | ||
242 | report = cck_buf->cck_agc_rpt & 0xc0; | ||
243 | report = report >> 6; | ||
244 | switch (report) { | ||
245 | case 0x3: | ||
246 | rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); | ||
247 | break; | ||
248 | case 0x2: | ||
249 | rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); | ||
250 | break; | ||
251 | case 0x1: | ||
252 | rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); | ||
253 | break; | ||
254 | case 0x0: | ||
255 | rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); | ||
256 | break; | ||
257 | } | ||
258 | } else { | ||
259 | u8 cck_agc_rpt = cck_buf->cck_agc_rpt; | ||
260 | report = p_drvinfo->cfosho[0] & 0x60; | ||
261 | report = report >> 5; | ||
262 | switch (report) { | ||
263 | case 0x3: | ||
264 | rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); | ||
265 | break; | ||
266 | case 0x2: | ||
267 | rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); | ||
268 | break; | ||
269 | case 0x1: | ||
270 | rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); | ||
271 | break; | ||
272 | case 0x0: | ||
273 | rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); | ||
274 | break; | ||
275 | } | ||
276 | } | ||
277 | pwdb_all = _rtl92d_query_rxpwrpercentage(rx_pwr_all); | ||
278 | /* CCK gain is smaller than OFDM/MCS gain, */ | ||
279 | /* so we add gain diff by experiences, the val is 6 */ | ||
280 | pwdb_all += 6; | ||
281 | if (pwdb_all > 100) | ||
282 | pwdb_all = 100; | ||
283 | /* modify the offset to make the same gain index with OFDM. */ | ||
284 | if (pwdb_all > 34 && pwdb_all <= 42) | ||
285 | pwdb_all -= 2; | ||
286 | else if (pwdb_all > 26 && pwdb_all <= 34) | ||
287 | pwdb_all -= 6; | ||
288 | else if (pwdb_all > 14 && pwdb_all <= 26) | ||
289 | pwdb_all -= 8; | ||
290 | else if (pwdb_all > 4 && pwdb_all <= 14) | ||
291 | pwdb_all -= 4; | ||
292 | pstats->rx_pwdb_all = pwdb_all; | ||
293 | pstats->recvsignalpower = rx_pwr_all; | ||
294 | if (packet_match_bssid) { | ||
295 | u8 sq; | ||
296 | if (pstats->rx_pwdb_all > 40) { | ||
297 | sq = 100; | ||
298 | } else { | ||
299 | sq = cck_buf->sq_rpt; | ||
300 | if (sq > 64) | ||
301 | sq = 0; | ||
302 | else if (sq < 20) | ||
303 | sq = 100; | ||
304 | else | ||
305 | sq = ((64 - sq) * 100) / 44; | ||
306 | } | ||
307 | pstats->signalquality = sq; | ||
308 | pstats->rx_mimo_signalquality[0] = sq; | ||
309 | pstats->rx_mimo_signalquality[1] = -1; | ||
310 | } | ||
311 | } else { | ||
312 | rtlpriv->dm.rfpath_rxenable[0] = true; | ||
313 | rtlpriv->dm.rfpath_rxenable[1] = true; | ||
314 | for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) { | ||
315 | if (rtlpriv->dm.rfpath_rxenable[i]) | ||
316 | rf_rx_num++; | ||
317 | rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) | ||
318 | - 110; | ||
319 | rssi = _rtl92d_query_rxpwrpercentage(rx_pwr[i]); | ||
320 | total_rssi += rssi; | ||
321 | rtlpriv->stats.rx_snr_db[i] = | ||
322 | (long)(p_drvinfo->rxsnr[i] / 2); | ||
323 | if (packet_match_bssid) | ||
324 | pstats->rx_mimo_signalstrength[i] = (u8) rssi; | ||
325 | } | ||
326 | rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 106; | ||
327 | pwdb_all = _rtl92d_query_rxpwrpercentage(rx_pwr_all); | ||
328 | pstats->rx_pwdb_all = pwdb_all; | ||
329 | pstats->rxpower = rx_pwr_all; | ||
330 | pstats->recvsignalpower = rx_pwr_all; | ||
331 | if (pdesc->rxht && pdesc->rxmcs >= DESC92D_RATEMCS8 && | ||
332 | pdesc->rxmcs <= DESC92D_RATEMCS15) | ||
333 | max_spatial_stream = 2; | ||
334 | else | ||
335 | max_spatial_stream = 1; | ||
336 | for (i = 0; i < max_spatial_stream; i++) { | ||
337 | evm = _rtl92d_evm_db_to_percentage(p_drvinfo->rxevm[i]); | ||
338 | if (packet_match_bssid) { | ||
339 | if (i == 0) | ||
340 | pstats->signalquality = | ||
341 | (u8)(evm & 0xff); | ||
342 | pstats->rx_mimo_signalquality[i] = | ||
343 | (u8)(evm & 0xff); | ||
344 | } | ||
345 | } | ||
346 | } | ||
347 | if (is_cck_rate) | ||
348 | pstats->signalstrength = (u8)(_rtl92de_signal_scale_mapping(hw, | ||
349 | pwdb_all)); | ||
350 | else if (rf_rx_num != 0) | ||
351 | pstats->signalstrength = (u8)(_rtl92de_signal_scale_mapping(hw, | ||
352 | total_rssi /= rf_rx_num)); | ||
353 | } | ||
354 | |||
355 | static void rtl92d_loop_over_paths(struct ieee80211_hw *hw, | ||
356 | struct rtl_stats *pstats) | ||
357 | { | ||
358 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
359 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
360 | u8 rfpath; | ||
361 | |||
362 | for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; | ||
363 | rfpath++) { | ||
364 | if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { | ||
365 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
366 | pstats->rx_mimo_signalstrength[rfpath]; | ||
367 | |||
368 | } | ||
369 | if (pstats->rx_mimo_signalstrength[rfpath] > | ||
370 | rtlpriv->stats.rx_rssi_percentage[rfpath]) { | ||
371 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
372 | ((rtlpriv->stats.rx_rssi_percentage[rfpath] * | ||
373 | (RX_SMOOTH_FACTOR - 1)) + | ||
374 | (pstats->rx_mimo_signalstrength[rfpath])) / | ||
375 | (RX_SMOOTH_FACTOR); | ||
376 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
377 | rtlpriv->stats.rx_rssi_percentage[rfpath] + 1; | ||
378 | } else { | ||
379 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
380 | ((rtlpriv->stats.rx_rssi_percentage[rfpath] * | ||
381 | (RX_SMOOTH_FACTOR - 1)) + | ||
382 | (pstats->rx_mimo_signalstrength[rfpath])) / | ||
383 | (RX_SMOOTH_FACTOR); | ||
384 | } | ||
385 | } | ||
386 | } | ||
387 | |||
388 | static void _rtl92de_process_ui_rssi(struct ieee80211_hw *hw, | ||
389 | struct rtl_stats *pstats) | ||
390 | { | ||
391 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
392 | u32 last_rssi, tmpval; | ||
393 | |||
394 | if (pstats->packet_toself || pstats->packet_beacon) { | ||
395 | rtlpriv->stats.rssi_calculate_cnt++; | ||
396 | if (rtlpriv->stats.ui_rssi.total_num++ >= | ||
397 | PHY_RSSI_SLID_WIN_MAX) { | ||
398 | rtlpriv->stats.ui_rssi.total_num = | ||
399 | PHY_RSSI_SLID_WIN_MAX; | ||
400 | last_rssi = rtlpriv->stats.ui_rssi.elements[ | ||
401 | rtlpriv->stats.ui_rssi.index]; | ||
402 | rtlpriv->stats.ui_rssi.total_val -= last_rssi; | ||
403 | } | ||
404 | rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength; | ||
405 | rtlpriv->stats.ui_rssi.elements | ||
406 | [rtlpriv->stats.ui_rssi.index++] = | ||
407 | pstats->signalstrength; | ||
408 | if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) | ||
409 | rtlpriv->stats.ui_rssi.index = 0; | ||
410 | tmpval = rtlpriv->stats.ui_rssi.total_val / | ||
411 | rtlpriv->stats.ui_rssi.total_num; | ||
412 | rtlpriv->stats.signal_strength = _rtl92de_translate_todbm(hw, | ||
413 | (u8) tmpval); | ||
414 | pstats->rssi = rtlpriv->stats.signal_strength; | ||
415 | } | ||
416 | if (!pstats->is_cck && pstats->packet_toself) | ||
417 | rtl92d_loop_over_paths(hw, pstats); | ||
418 | } | ||
419 | |||
420 | static void _rtl92de_update_rxsignalstatistics(struct ieee80211_hw *hw, | ||
421 | struct rtl_stats *pstats) | ||
422 | { | ||
423 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
424 | int weighting = 0; | ||
425 | |||
426 | if (rtlpriv->stats.recv_signal_power == 0) | ||
427 | rtlpriv->stats.recv_signal_power = pstats->recvsignalpower; | ||
428 | if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power) | ||
429 | weighting = 5; | ||
430 | else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power) | ||
431 | weighting = (-5); | ||
432 | rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * | ||
433 | 5 + pstats->recvsignalpower + weighting) / 6; | ||
434 | } | ||
435 | |||
436 | static void _rtl92de_process_pwdb(struct ieee80211_hw *hw, | ||
437 | struct rtl_stats *pstats) | ||
438 | { | ||
439 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
440 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
441 | long undecorated_smoothed_pwdb; | ||
442 | |||
443 | if (mac->opmode == NL80211_IFTYPE_ADHOC || | ||
444 | mac->opmode == NL80211_IFTYPE_AP) | ||
445 | return; | ||
446 | else | ||
447 | undecorated_smoothed_pwdb = | ||
448 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
449 | |||
450 | if (pstats->packet_toself || pstats->packet_beacon) { | ||
451 | if (undecorated_smoothed_pwdb < 0) | ||
452 | undecorated_smoothed_pwdb = pstats->rx_pwdb_all; | ||
453 | if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { | ||
454 | undecorated_smoothed_pwdb = | ||
455 | (((undecorated_smoothed_pwdb) * | ||
456 | (RX_SMOOTH_FACTOR - 1)) + | ||
457 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); | ||
458 | undecorated_smoothed_pwdb = | ||
459 | undecorated_smoothed_pwdb + 1; | ||
460 | } else { | ||
461 | undecorated_smoothed_pwdb = | ||
462 | (((undecorated_smoothed_pwdb) * | ||
463 | (RX_SMOOTH_FACTOR - 1)) + | ||
464 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); | ||
465 | } | ||
466 | rtlpriv->dm.undecorated_smoothed_pwdb = | ||
467 | undecorated_smoothed_pwdb; | ||
468 | _rtl92de_update_rxsignalstatistics(hw, pstats); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | static void rtl92d_loop_over_streams(struct ieee80211_hw *hw, | ||
473 | struct rtl_stats *pstats) | ||
474 | { | ||
475 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
476 | int stream; | ||
477 | |||
478 | for (stream = 0; stream < 2; stream++) { | ||
479 | if (pstats->rx_mimo_signalquality[stream] != -1) { | ||
480 | if (rtlpriv->stats.rx_evm_percentage[stream] == 0) { | ||
481 | rtlpriv->stats.rx_evm_percentage[stream] = | ||
482 | pstats->rx_mimo_signalquality[stream]; | ||
483 | } | ||
484 | rtlpriv->stats.rx_evm_percentage[stream] = | ||
485 | ((rtlpriv->stats.rx_evm_percentage[stream] | ||
486 | * (RX_SMOOTH_FACTOR - 1)) + | ||
487 | (pstats->rx_mimo_signalquality[stream] * 1)) / | ||
488 | (RX_SMOOTH_FACTOR); | ||
489 | } | ||
490 | } | ||
491 | } | ||
492 | |||
493 | static void _rtl92de_process_ui_link_quality(struct ieee80211_hw *hw, | ||
494 | struct rtl_stats *pstats) | ||
495 | { | ||
496 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
497 | u32 last_evm, tmpval; | ||
498 | |||
499 | if (pstats->signalquality == 0) | ||
500 | return; | ||
501 | if (pstats->packet_toself || pstats->packet_beacon) { | ||
502 | if (rtlpriv->stats.ui_link_quality.total_num++ >= | ||
503 | PHY_LINKQUALITY_SLID_WIN_MAX) { | ||
504 | rtlpriv->stats.ui_link_quality.total_num = | ||
505 | PHY_LINKQUALITY_SLID_WIN_MAX; | ||
506 | last_evm = rtlpriv->stats.ui_link_quality.elements[ | ||
507 | rtlpriv->stats.ui_link_quality.index]; | ||
508 | rtlpriv->stats.ui_link_quality.total_val -= last_evm; | ||
509 | } | ||
510 | rtlpriv->stats.ui_link_quality.total_val += | ||
511 | pstats->signalquality; | ||
512 | rtlpriv->stats.ui_link_quality.elements[ | ||
513 | rtlpriv->stats.ui_link_quality.index++] = | ||
514 | pstats->signalquality; | ||
515 | if (rtlpriv->stats.ui_link_quality.index >= | ||
516 | PHY_LINKQUALITY_SLID_WIN_MAX) | ||
517 | rtlpriv->stats.ui_link_quality.index = 0; | ||
518 | tmpval = rtlpriv->stats.ui_link_quality.total_val / | ||
519 | rtlpriv->stats.ui_link_quality.total_num; | ||
520 | rtlpriv->stats.signal_quality = tmpval; | ||
521 | rtlpriv->stats.last_sigstrength_inpercent = tmpval; | ||
522 | rtl92d_loop_over_streams(hw, pstats); | ||
523 | } | ||
524 | } | ||
525 | |||
526 | static void _rtl92de_process_phyinfo(struct ieee80211_hw *hw, | ||
527 | u8 *buffer, | ||
528 | struct rtl_stats *pcurrent_stats) | ||
529 | { | ||
530 | |||
531 | if (!pcurrent_stats->packet_matchbssid && | ||
532 | !pcurrent_stats->packet_beacon) | ||
533 | return; | ||
534 | |||
535 | _rtl92de_process_ui_rssi(hw, pcurrent_stats); | ||
536 | _rtl92de_process_pwdb(hw, pcurrent_stats); | ||
537 | _rtl92de_process_ui_link_quality(hw, pcurrent_stats); | ||
538 | } | ||
539 | |||
540 | static void _rtl92de_translate_rx_signal_stuff(struct ieee80211_hw *hw, | ||
541 | struct sk_buff *skb, | ||
542 | struct rtl_stats *pstats, | ||
543 | struct rx_desc_92d *pdesc, | ||
544 | struct rx_fwinfo_92d *p_drvinfo) | ||
545 | { | ||
546 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
547 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
548 | struct ieee80211_hdr *hdr; | ||
549 | u8 *tmp_buf; | ||
550 | u8 *praddr; | ||
551 | u16 type, cfc; | ||
552 | __le16 fc; | ||
553 | bool packet_matchbssid, packet_toself, packet_beacon; | ||
554 | |||
555 | tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; | ||
556 | hdr = (struct ieee80211_hdr *)tmp_buf; | ||
557 | fc = hdr->frame_control; | ||
558 | cfc = le16_to_cpu(fc); | ||
559 | type = WLAN_FC_GET_TYPE(fc); | ||
560 | praddr = hdr->addr1; | ||
561 | packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && | ||
562 | (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ? | ||
563 | hdr->addr1 : (cfc & IEEE80211_FCTL_FROMDS) ? | ||
564 | hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) && | ||
565 | (!pstats->crc) && (!pstats->icv)); | ||
566 | packet_toself = packet_matchbssid && | ||
567 | (!compare_ether_addr(praddr, rtlefuse->dev_addr)); | ||
568 | if (ieee80211_is_beacon(fc)) | ||
569 | packet_beacon = true; | ||
570 | _rtl92de_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, | ||
571 | packet_matchbssid, packet_toself, | ||
572 | packet_beacon); | ||
573 | _rtl92de_process_phyinfo(hw, tmp_buf, pstats); | ||
574 | } | ||
575 | |||
576 | bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, | ||
577 | struct ieee80211_rx_status *rx_status, | ||
578 | u8 *p_desc, struct sk_buff *skb) | ||
579 | { | ||
580 | struct rx_fwinfo_92d *p_drvinfo; | ||
581 | struct rx_desc_92d *pdesc = (struct rx_desc_92d *)p_desc; | ||
582 | u32 phystatus = GET_RX_DESC_PHYST(pdesc); | ||
583 | |||
584 | stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); | ||
585 | stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) * | ||
586 | RX_DRV_INFO_SIZE_UNIT; | ||
587 | stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03); | ||
588 | stats->icv = (u16) GET_RX_DESC_ICV(pdesc); | ||
589 | stats->crc = (u16) GET_RX_DESC_CRC32(pdesc); | ||
590 | stats->hwerror = (stats->crc | stats->icv); | ||
591 | stats->decrypted = !GET_RX_DESC_SWDEC(pdesc); | ||
592 | stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc); | ||
593 | stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); | ||
594 | stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); | ||
595 | stats->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) | ||
596 | && (GET_RX_DESC_FAGGR(pdesc) == 1)); | ||
597 | stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); | ||
598 | stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); | ||
599 | rx_status->freq = hw->conf.channel->center_freq; | ||
600 | rx_status->band = hw->conf.channel->band; | ||
601 | if (GET_RX_DESC_CRC32(pdesc)) | ||
602 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | ||
603 | if (!GET_RX_DESC_SWDEC(pdesc)) | ||
604 | rx_status->flag |= RX_FLAG_DECRYPTED; | ||
605 | if (GET_RX_DESC_BW(pdesc)) | ||
606 | rx_status->flag |= RX_FLAG_40MHZ; | ||
607 | if (GET_RX_DESC_RXHT(pdesc)) | ||
608 | rx_status->flag |= RX_FLAG_HT; | ||
609 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; | ||
610 | if (stats->decrypted) | ||
611 | rx_status->flag |= RX_FLAG_DECRYPTED; | ||
612 | rx_status->rate_idx = _rtl92de_rate_mapping((bool) | ||
613 | GET_RX_DESC_RXHT(pdesc), | ||
614 | (u8) | ||
615 | GET_RX_DESC_RXMCS(pdesc)); | ||
616 | rx_status->mactime = GET_RX_DESC_TSFL(pdesc); | ||
617 | if (phystatus == true) { | ||
618 | p_drvinfo = (struct rx_fwinfo_92d *)(skb->data + | ||
619 | stats->rx_bufshift); | ||
620 | _rtl92de_translate_rx_signal_stuff(hw, | ||
621 | skb, stats, pdesc, | ||
622 | p_drvinfo); | ||
623 | } | ||
624 | /*rx_status->qual = stats->signal; */ | ||
625 | rx_status->signal = stats->rssi + 10; | ||
626 | /*rx_status->noise = -stats->noise; */ | ||
627 | return true; | ||
628 | } | ||
629 | |||
630 | static void _rtl92de_insert_emcontent(struct rtl_tcb_desc *ptcb_desc, | ||
631 | u8 *virtualaddress) | ||
632 | { | ||
633 | memset(virtualaddress, 0, 8); | ||
634 | |||
635 | SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num); | ||
636 | SET_EARLYMODE_LEN0(virtualaddress, ptcb_desc->empkt_len[0]); | ||
637 | SET_EARLYMODE_LEN1(virtualaddress, ptcb_desc->empkt_len[1]); | ||
638 | SET_EARLYMODE_LEN2_1(virtualaddress, ptcb_desc->empkt_len[2] & 0xF); | ||
639 | SET_EARLYMODE_LEN2_2(virtualaddress, ptcb_desc->empkt_len[2] >> 4); | ||
640 | SET_EARLYMODE_LEN3(virtualaddress, ptcb_desc->empkt_len[3]); | ||
641 | SET_EARLYMODE_LEN4(virtualaddress, ptcb_desc->empkt_len[4]); | ||
642 | } | ||
643 | |||
644 | void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, | ||
645 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, | ||
646 | struct ieee80211_tx_info *info, struct sk_buff *skb, | ||
647 | u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) | ||
648 | { | ||
649 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
650 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
651 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
652 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
653 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
654 | struct ieee80211_sta *sta = info->control.sta; | ||
655 | u8 *pdesc = (u8 *) pdesc_tx; | ||
656 | u16 seq_number; | ||
657 | __le16 fc = hdr->frame_control; | ||
658 | unsigned int buf_len = 0; | ||
659 | unsigned int skb_len = skb->len; | ||
660 | u8 fw_qsel = _rtl92de_map_hwqueue_to_fwqueue(skb, hw_queue); | ||
661 | bool firstseg = ((hdr->seq_ctrl & | ||
662 | cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); | ||
663 | bool lastseg = ((hdr->frame_control & | ||
664 | cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); | ||
665 | dma_addr_t mapping; | ||
666 | u8 bw_40 = 0; | ||
667 | |||
668 | if (mac->opmode == NL80211_IFTYPE_STATION) { | ||
669 | bw_40 = mac->bw_40; | ||
670 | } else if (mac->opmode == NL80211_IFTYPE_AP || | ||
671 | mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
672 | if (sta) | ||
673 | bw_40 = sta->ht_cap.cap & | ||
674 | IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
675 | } | ||
676 | seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; | ||
677 | rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); | ||
678 | /* reserve 8 byte for AMPDU early mode */ | ||
679 | if (rtlhal->earlymode_enable) { | ||
680 | skb_push(skb, EM_HDR_LEN); | ||
681 | memset(skb->data, 0, EM_HDR_LEN); | ||
682 | } | ||
683 | buf_len = skb->len; | ||
684 | mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, | ||
685 | PCI_DMA_TODEVICE); | ||
686 | CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92d)); | ||
687 | if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { | ||
688 | firstseg = true; | ||
689 | lastseg = true; | ||
690 | } | ||
691 | if (firstseg) { | ||
692 | if (rtlhal->earlymode_enable) { | ||
693 | SET_TX_DESC_PKT_OFFSET(pdesc, 1); | ||
694 | SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN + | ||
695 | EM_HDR_LEN); | ||
696 | if (ptcb_desc->empkt_num) { | ||
697 | RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD, | ||
698 | ("Insert 8 byte.pTcb->EMPktNum:%d\n", | ||
699 | ptcb_desc->empkt_num)); | ||
700 | _rtl92de_insert_emcontent(ptcb_desc, | ||
701 | (u8 *)(skb->data)); | ||
702 | } | ||
703 | } else { | ||
704 | SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); | ||
705 | } | ||
706 | /* 5G have no CCK rate */ | ||
707 | if (rtlhal->current_bandtype == BAND_ON_5G) | ||
708 | if (ptcb_desc->hw_rate < DESC92D_RATE6M) | ||
709 | ptcb_desc->hw_rate = DESC92D_RATE6M; | ||
710 | SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate); | ||
711 | if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble) | ||
712 | SET_TX_DESC_DATA_SHORTGI(pdesc, 1); | ||
713 | |||
714 | if (rtlhal->macphymode == DUALMAC_DUALPHY && | ||
715 | ptcb_desc->hw_rate == DESC92D_RATEMCS7) | ||
716 | SET_TX_DESC_DATA_SHORTGI(pdesc, 1); | ||
717 | |||
718 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
719 | SET_TX_DESC_AGG_ENABLE(pdesc, 1); | ||
720 | SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14); | ||
721 | } | ||
722 | SET_TX_DESC_SEQ(pdesc, seq_number); | ||
723 | SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable && | ||
724 | !ptcb_desc->cts_enable) ? 1 : 0)); | ||
725 | SET_TX_DESC_HW_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable | ||
726 | || ptcb_desc->cts_enable) ? 1 : 0)); | ||
727 | SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0)); | ||
728 | SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0)); | ||
729 | /* 5G have no CCK rate */ | ||
730 | if (rtlhal->current_bandtype == BAND_ON_5G) | ||
731 | if (ptcb_desc->rts_rate < DESC92D_RATE6M) | ||
732 | ptcb_desc->rts_rate = DESC92D_RATE6M; | ||
733 | SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate); | ||
734 | SET_TX_DESC_RTS_BW(pdesc, 0); | ||
735 | SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc); | ||
736 | SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <= | ||
737 | DESC92D_RATE54M) ? | ||
738 | (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : | ||
739 | (ptcb_desc->rts_use_shortgi ? 1 : 0))); | ||
740 | if (bw_40) { | ||
741 | if (ptcb_desc->packet_bw) { | ||
742 | SET_TX_DESC_DATA_BW(pdesc, 1); | ||
743 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); | ||
744 | } else { | ||
745 | SET_TX_DESC_DATA_BW(pdesc, 0); | ||
746 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, | ||
747 | mac->cur_40_prime_sc); | ||
748 | } | ||
749 | } else { | ||
750 | SET_TX_DESC_DATA_BW(pdesc, 0); | ||
751 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0); | ||
752 | } | ||
753 | SET_TX_DESC_LINIP(pdesc, 0); | ||
754 | SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb_len); | ||
755 | if (sta) { | ||
756 | u8 ampdu_density = sta->ht_cap.ampdu_density; | ||
757 | SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); | ||
758 | } | ||
759 | if (info->control.hw_key) { | ||
760 | struct ieee80211_key_conf *keyconf; | ||
761 | |||
762 | keyconf = info->control.hw_key; | ||
763 | switch (keyconf->cipher) { | ||
764 | case WLAN_CIPHER_SUITE_WEP40: | ||
765 | case WLAN_CIPHER_SUITE_WEP104: | ||
766 | case WLAN_CIPHER_SUITE_TKIP: | ||
767 | SET_TX_DESC_SEC_TYPE(pdesc, 0x1); | ||
768 | break; | ||
769 | case WLAN_CIPHER_SUITE_CCMP: | ||
770 | SET_TX_DESC_SEC_TYPE(pdesc, 0x3); | ||
771 | break; | ||
772 | default: | ||
773 | SET_TX_DESC_SEC_TYPE(pdesc, 0x0); | ||
774 | break; | ||
775 | |||
776 | } | ||
777 | } | ||
778 | SET_TX_DESC_PKT_ID(pdesc, 0); | ||
779 | SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel); | ||
780 | SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F); | ||
781 | SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF); | ||
782 | SET_TX_DESC_DISABLE_FB(pdesc, ptcb_desc->disable_ratefallback ? | ||
783 | 1 : 0); | ||
784 | SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0); | ||
785 | |||
786 | /* Set TxRate and RTSRate in TxDesc */ | ||
787 | /* This prevent Tx initial rate of new-coming packets */ | ||
788 | /* from being overwritten by retried packet rate.*/ | ||
789 | if (!ptcb_desc->use_driver_rate) { | ||
790 | SET_TX_DESC_RTS_RATE(pdesc, 0x08); | ||
791 | /* SET_TX_DESC_TX_RATE(pdesc, 0x0b); */ | ||
792 | } | ||
793 | if (ieee80211_is_data_qos(fc)) { | ||
794 | if (mac->rdg_en) { | ||
795 | RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, | ||
796 | ("Enable RDG function.\n")); | ||
797 | SET_TX_DESC_RDG_ENABLE(pdesc, 1); | ||
798 | SET_TX_DESC_HTC(pdesc, 1); | ||
799 | } | ||
800 | } | ||
801 | } | ||
802 | |||
803 | SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0)); | ||
804 | SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0)); | ||
805 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) buf_len); | ||
806 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); | ||
807 | if (rtlpriv->dm.useramask) { | ||
808 | SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index); | ||
809 | SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id); | ||
810 | } else { | ||
811 | SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index); | ||
812 | SET_TX_DESC_MACID(pdesc, ptcb_desc->ratr_index); | ||
813 | } | ||
814 | if (ieee80211_is_data_qos(fc)) | ||
815 | SET_TX_DESC_QOS(pdesc, 1); | ||
816 | |||
817 | if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) { | ||
818 | SET_TX_DESC_HWSEQ_EN(pdesc, 1); | ||
819 | SET_TX_DESC_PKT_ID(pdesc, 8); | ||
820 | } | ||
821 | SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1)); | ||
822 | RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); | ||
823 | } | ||
824 | |||
825 | void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, | ||
826 | u8 *pdesc, bool firstseg, | ||
827 | bool lastseg, struct sk_buff *skb) | ||
828 | { | ||
829 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
830 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
831 | struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); | ||
832 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
833 | u8 fw_queue = QSLT_BEACON; | ||
834 | dma_addr_t mapping = pci_map_single(rtlpci->pdev, | ||
835 | skb->data, skb->len, PCI_DMA_TODEVICE); | ||
836 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | ||
837 | __le16 fc = hdr->frame_control; | ||
838 | |||
839 | CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE); | ||
840 | if (firstseg) | ||
841 | SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); | ||
842 | /* 5G have no CCK rate | ||
843 | * Caution: The macros below are multi-line expansions. | ||
844 | * The braces are needed no matter what checkpatch says | ||
845 | */ | ||
846 | if (rtlhal->current_bandtype == BAND_ON_5G) { | ||
847 | SET_TX_DESC_TX_RATE(pdesc, DESC92D_RATE6M); | ||
848 | } else { | ||
849 | SET_TX_DESC_TX_RATE(pdesc, DESC92D_RATE1M); | ||
850 | } | ||
851 | SET_TX_DESC_SEQ(pdesc, 0); | ||
852 | SET_TX_DESC_LINIP(pdesc, 0); | ||
853 | SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); | ||
854 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | ||
855 | SET_TX_DESC_LAST_SEG(pdesc, 1); | ||
856 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len)); | ||
857 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); | ||
858 | SET_TX_DESC_RATE_ID(pdesc, 7); | ||
859 | SET_TX_DESC_MACID(pdesc, 0); | ||
860 | SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); | ||
861 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | ||
862 | SET_TX_DESC_LAST_SEG(pdesc, 1); | ||
863 | SET_TX_DESC_OFFSET(pdesc, 0x20); | ||
864 | SET_TX_DESC_USE_RATE(pdesc, 1); | ||
865 | |||
866 | if (!ieee80211_is_data_qos(fc) && ppsc->fwctrl_lps) { | ||
867 | SET_TX_DESC_HWSEQ_EN(pdesc, 1); | ||
868 | SET_TX_DESC_PKT_ID(pdesc, 8); | ||
869 | } | ||
870 | |||
871 | RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, | ||
872 | "H2C Tx Cmd Content\n", pdesc, TX_DESC_SIZE); | ||
873 | wmb(); | ||
874 | SET_TX_DESC_OWN(pdesc, 1); | ||
875 | } | ||
876 | |||
877 | void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) | ||
878 | { | ||
879 | if (istx == true) { | ||
880 | switch (desc_name) { | ||
881 | case HW_DESC_OWN: | ||
882 | wmb(); | ||
883 | SET_TX_DESC_OWN(pdesc, 1); | ||
884 | break; | ||
885 | case HW_DESC_TX_NEXTDESC_ADDR: | ||
886 | SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); | ||
887 | break; | ||
888 | default: | ||
889 | RT_ASSERT(false, ("ERR txdesc :%d" | ||
890 | " not process\n", desc_name)); | ||
891 | break; | ||
892 | } | ||
893 | } else { | ||
894 | switch (desc_name) { | ||
895 | case HW_DESC_RXOWN: | ||
896 | wmb(); | ||
897 | SET_RX_DESC_OWN(pdesc, 1); | ||
898 | break; | ||
899 | case HW_DESC_RXBUFF_ADDR: | ||
900 | SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val); | ||
901 | break; | ||
902 | case HW_DESC_RXPKT_LEN: | ||
903 | SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val); | ||
904 | break; | ||
905 | case HW_DESC_RXERO: | ||
906 | SET_RX_DESC_EOR(pdesc, 1); | ||
907 | break; | ||
908 | default: | ||
909 | RT_ASSERT(false, ("ERR rxdesc :%d " | ||
910 | "not process\n", desc_name)); | ||
911 | break; | ||
912 | } | ||
913 | } | ||
914 | } | ||
915 | |||
916 | u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name) | ||
917 | { | ||
918 | u32 ret = 0; | ||
919 | |||
920 | if (istx == true) { | ||
921 | switch (desc_name) { | ||
922 | case HW_DESC_OWN: | ||
923 | ret = GET_TX_DESC_OWN(p_desc); | ||
924 | break; | ||
925 | case HW_DESC_TXBUFF_ADDR: | ||
926 | ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc); | ||
927 | break; | ||
928 | default: | ||
929 | RT_ASSERT(false, ("ERR txdesc :%d " | ||
930 | "not process\n", desc_name)); | ||
931 | break; | ||
932 | } | ||
933 | } else { | ||
934 | struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; | ||
935 | switch (desc_name) { | ||
936 | case HW_DESC_OWN: | ||
937 | ret = GET_RX_DESC_OWN(pdesc); | ||
938 | break; | ||
939 | case HW_DESC_RXPKT_LEN: | ||
940 | ret = GET_RX_DESC_PKT_LEN(pdesc); | ||
941 | break; | ||
942 | default: | ||
943 | RT_ASSERT(false, ("ERR rxdesc :%d " | ||
944 | "not process\n", desc_name)); | ||
945 | break; | ||
946 | } | ||
947 | } | ||
948 | return ret; | ||
949 | } | ||
950 | |||
951 | void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) | ||
952 | { | ||
953 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
954 | if (hw_queue == BEACON_QUEUE) | ||
955 | rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); | ||
956 | else | ||
957 | rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, | ||
958 | BIT(0) << (hw_queue)); | ||
959 | } | ||