rtl8192ce: drop 'rtl8192c-' prefix from files
[linux-2.6-block.git] / drivers / net / wireless / rtlwifi / rtl8192ce / trx.c
CommitLineData
0c817338
LF
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"
5c405b5c
JL
33#include "reg.h"
34#include "def.h"
35#include "phy.h"
36#include "trx.h"
37#include "led.h"
0c817338
LF
38
39static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(u16 fc,
40 unsigned int
41 skb_queue)
42{
43 enum rtl_desc_qsel qsel;
44
45 if (unlikely(ieee80211_is_beacon(fc))) {
46 qsel = QSLT_BEACON;
47 return qsel;
48 }
49
50 if (ieee80211_is_mgmt(fc)) {
51 qsel = QSLT_MGNT;
52 return qsel;
53 }
54
55 switch (skb_queue) {
56 case VO_QUEUE:
57 qsel = QSLT_VO;
58 break;
59 case VI_QUEUE:
60 qsel = QSLT_VI;
61 break;
62 case BE_QUEUE:
63 qsel = QSLT_BE;
64 break;
65 case BK_QUEUE:
66 qsel = QSLT_BK;
67 break;
68 default:
69 qsel = QSLT_BE;
70 RT_ASSERT(false, ("BE queue, skb_queue:%d,"
71 " set qsel = 0x%X\n", skb_queue, QSLT_BE));
72 break;
73 }
74 return qsel;
75}
76
77static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu)
78{
79 int rate_idx;
80
81 if (first_ampdu) {
82 if (false == isht) {
83 switch (desc_rate) {
84 case DESC92C_RATE1M:
85 rate_idx = 0;
86 break;
87 case DESC92C_RATE2M:
88 rate_idx = 1;
89 break;
90 case DESC92C_RATE5_5M:
91 rate_idx = 2;
92 break;
93 case DESC92C_RATE11M:
94 rate_idx = 3;
95 break;
96 case DESC92C_RATE6M:
97 rate_idx = 4;
98 break;
99 case DESC92C_RATE9M:
100 rate_idx = 5;
101 break;
102 case DESC92C_RATE12M:
103 rate_idx = 6;
104 break;
105 case DESC92C_RATE18M:
106 rate_idx = 7;
107 break;
108 case DESC92C_RATE24M:
109 rate_idx = 8;
110 break;
111 case DESC92C_RATE36M:
112 rate_idx = 9;
113 break;
114 case DESC92C_RATE48M:
115 rate_idx = 10;
116 break;
117 case DESC92C_RATE54M:
118 rate_idx = 11;
119 break;
120 default:
121 rate_idx = 0;
122 break;
123 }
124 } else {
125 rate_idx = 11;
126 }
127
128 return rate_idx;
129 }
130
131 switch (desc_rate) {
132 case DESC92C_RATE1M:
133 rate_idx = 0;
134 break;
135 case DESC92C_RATE2M:
136 rate_idx = 1;
137 break;
138 case DESC92C_RATE5_5M:
139 rate_idx = 2;
140 break;
141 case DESC92C_RATE11M:
142 rate_idx = 3;
143 break;
144 case DESC92C_RATE6M:
145 rate_idx = 4;
146 break;
147 case DESC92C_RATE9M:
148 rate_idx = 5;
149 break;
150 case DESC92C_RATE12M:
151 rate_idx = 6;
152 break;
153 case DESC92C_RATE18M:
154 rate_idx = 7;
155 break;
156 case DESC92C_RATE24M:
157 rate_idx = 8;
158 break;
159 case DESC92C_RATE36M:
160 rate_idx = 9;
161 break;
162 case DESC92C_RATE48M:
163 rate_idx = 10;
164 break;
165 case DESC92C_RATE54M:
166 rate_idx = 11;
167 break;
168 default:
169 rate_idx = 11;
170 break;
171 }
172 return rate_idx;
173}
174
175static u8 _rtl92c_query_rxpwrpercentage(char antpower)
176{
177 if ((antpower <= -100) || (antpower >= 20))
178 return 0;
179 else if (antpower >= 0)
180 return 100;
181 else
182 return 100 + antpower;
183}
184
185static u8 _rtl92c_evm_db_to_percentage(char value)
186{
187 char ret_val;
188 ret_val = value;
189
190 if (ret_val >= 0)
191 ret_val = 0;
192
193 if (ret_val <= -33)
194 ret_val = -33;
195
196 ret_val = 0 - ret_val;
197 ret_val *= 3;
198
199 if (ret_val == 99)
200 ret_val = 100;
201
202 return ret_val;
203}
204
205static long _rtl92ce_translate_todbm(struct ieee80211_hw *hw,
206 u8 signal_strength_index)
207{
208 long signal_power;
209
210 signal_power = (long)((signal_strength_index + 1) >> 1);
211 signal_power -= 95;
212 return signal_power;
213}
214
215static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw,
216 long currsig)
217{
218 long retsig;
219
220 if (currsig >= 61 && currsig <= 100)
221 retsig = 90 + ((currsig - 60) / 4);
222 else if (currsig >= 41 && currsig <= 60)
223 retsig = 78 + ((currsig - 40) / 2);
224 else if (currsig >= 31 && currsig <= 40)
225 retsig = 66 + (currsig - 30);
226 else if (currsig >= 21 && currsig <= 30)
227 retsig = 54 + (currsig - 20);
228 else if (currsig >= 5 && currsig <= 20)
229 retsig = 42 + (((currsig - 5) * 2) / 3);
230 else if (currsig == 4)
231 retsig = 36;
232 else if (currsig == 3)
233 retsig = 27;
234 else if (currsig == 2)
235 retsig = 18;
236 else if (currsig == 1)
237 retsig = 9;
238 else
239 retsig = currsig;
240
241 return retsig;
242}
243
244static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
245 struct rtl_stats *pstats,
246 struct rx_desc_92c *pdesc,
247 struct rx_fwinfo_92c *p_drvinfo,
248 bool bpacket_match_bssid,
249 bool bpacket_toself,
250 bool b_packet_beacon)
251{
252 struct rtl_priv *rtlpriv = rtl_priv(hw);
253 struct phy_sts_cck_8192s_t *cck_buf;
254 s8 rx_pwr_all, rx_pwr[4];
255 u8 rf_rx_num, evm, pwdb_all;
256 u8 i, max_spatial_stream;
257 u32 rssi, total_rssi;
258 bool is_cck_rate;
259
260 is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
261 pstats->b_packet_matchbssid = bpacket_match_bssid;
262 pstats->b_packet_toself = bpacket_toself;
263 pstats->b_is_cck = is_cck_rate;
264 pstats->b_packet_beacon = b_packet_beacon;
265 pstats->b_is_cck = is_cck_rate;
266 pstats->rx_mimo_signalquality[0] = -1;
267 pstats->rx_mimo_signalquality[1] = -1;
268
269 if (is_cck_rate) {
270 u8 report, cck_highpwr;
271 cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
272
273 cck_highpwr = (u8) rtl_get_bbreg(hw,
274 RFPGA0_XA_HSSIPARAMETER2,
275 BIT(9));
276 if (!cck_highpwr) {
277 u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
278 report = cck_buf->cck_agc_rpt & 0xc0;
279 report = report >> 6;
280 switch (report) {
281 case 0x3:
282 rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
283 break;
284 case 0x2:
285 rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
286 break;
287 case 0x1:
288 rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
289 break;
290 case 0x0:
291 rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
292 break;
293 }
294 } else {
295 u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
296 report = p_drvinfo->cfosho[0] & 0x60;
297 report = report >> 5;
298 switch (report) {
299 case 0x3:
300 rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
301 break;
302 case 0x2:
303 rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
304 break;
305 case 0x1:
306 rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
307 break;
308 case 0x0:
309 rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
310 break;
311 }
312 }
313
314 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
315 pstats->rx_pwdb_all = pwdb_all;
316 pstats->recvsignalpower = rx_pwr_all;
317
318 if (bpacket_match_bssid) {
319 u8 sq;
320 if (pstats->rx_pwdb_all > 40)
321 sq = 100;
322 else {
323 sq = cck_buf->sq_rpt;
324 if (sq > 64)
325 sq = 0;
326 else if (sq < 20)
327 sq = 100;
328 else
329 sq = ((64 - sq) * 100) / 44;
330 }
331
332 pstats->signalquality = sq;
333 pstats->rx_mimo_signalquality[0] = sq;
334 pstats->rx_mimo_signalquality[1] = -1;
335 }
336 } else {
337 rtlpriv->dm.brfpath_rxenable[0] =
338 rtlpriv->dm.brfpath_rxenable[1] = true;
339 for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
340 if (rtlpriv->dm.brfpath_rxenable[i])
341 rf_rx_num++;
342
343 rx_pwr[i] =
344 ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
345 rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
346 total_rssi += rssi;
347 rtlpriv->stats.rx_snr_db[i] =
348 (long)(p_drvinfo->rxsnr[i] / 2);
349
350 if (bpacket_match_bssid)
351 pstats->rx_mimo_signalstrength[i] = (u8) rssi;
352 }
353
354 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
355 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
356 pstats->rx_pwdb_all = pwdb_all;
357 pstats->rxpower = rx_pwr_all;
358 pstats->recvsignalpower = rx_pwr_all;
359
360 if (pdesc->rxht && pdesc->rxmcs >= DESC92C_RATEMCS8 &&
361 pdesc->rxmcs <= DESC92C_RATEMCS15)
362 max_spatial_stream = 2;
363 else
364 max_spatial_stream = 1;
365
366 for (i = 0; i < max_spatial_stream; i++) {
367 evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
368
369 if (bpacket_match_bssid) {
370 if (i == 0)
371 pstats->signalquality =
372 (u8) (evm & 0xff);
373 pstats->rx_mimo_signalquality[i] =
374 (u8) (evm & 0xff);
375 }
376 }
377 }
378
379 if (is_cck_rate)
380 pstats->signalstrength =
381 (u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all));
382 else if (rf_rx_num != 0)
383 pstats->signalstrength =
384 (u8) (_rtl92ce_signal_scale_mapping
385 (hw, total_rssi /= rf_rx_num));
386}
387
388static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw,
389 struct rtl_stats *pstats)
390{
391 struct rtl_priv *rtlpriv = rtl_priv(hw);
392 struct rtl_phy *rtlphy = &(rtlpriv->phy);
393 u8 rfpath;
394 u32 last_rssi, tmpval;
395
396 if (pstats->b_packet_toself || pstats->b_packet_beacon) {
397 rtlpriv->stats.rssi_calculate_cnt++;
398
399 if (rtlpriv->stats.ui_rssi.total_num++ >=
400 PHY_RSSI_SLID_WIN_MAX) {
401 rtlpriv->stats.ui_rssi.total_num =
402 PHY_RSSI_SLID_WIN_MAX;
403 last_rssi =
404 rtlpriv->stats.ui_rssi.elements[rtlpriv->
405 stats.ui_rssi.index];
406 rtlpriv->stats.ui_rssi.total_val -= last_rssi;
407 }
408
409 rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
410 rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.
411 index++] =
412 pstats->signalstrength;
413
414 if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
415 rtlpriv->stats.ui_rssi.index = 0;
416
417 tmpval = rtlpriv->stats.ui_rssi.total_val /
418 rtlpriv->stats.ui_rssi.total_num;
419 rtlpriv->stats.signal_strength =
420 _rtl92ce_translate_todbm(hw, (u8) tmpval);
421 pstats->rssi = rtlpriv->stats.signal_strength;
422 }
423
424 if (!pstats->b_is_cck && pstats->b_packet_toself) {
425 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
426 rfpath++) {
427
428 if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath))
429 continue;
430
431 if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
432 rtlpriv->stats.rx_rssi_percentage[rfpath] =
433 pstats->rx_mimo_signalstrength[rfpath];
434
435 }
436
437 if (pstats->rx_mimo_signalstrength[rfpath] >
438 rtlpriv->stats.rx_rssi_percentage[rfpath]) {
439 rtlpriv->stats.rx_rssi_percentage[rfpath] =
440 ((rtlpriv->stats.
441 rx_rssi_percentage[rfpath] *
442 (RX_SMOOTH_FACTOR - 1)) +
443 (pstats->rx_mimo_signalstrength[rfpath])) /
444 (RX_SMOOTH_FACTOR);
445
446 rtlpriv->stats.rx_rssi_percentage[rfpath] =
447 rtlpriv->stats.rx_rssi_percentage[rfpath] +
448 1;
449 } else {
450 rtlpriv->stats.rx_rssi_percentage[rfpath] =
451 ((rtlpriv->stats.
452 rx_rssi_percentage[rfpath] *
453 (RX_SMOOTH_FACTOR - 1)) +
454 (pstats->rx_mimo_signalstrength[rfpath])) /
455 (RX_SMOOTH_FACTOR);
456 }
457
458 }
459 }
460}
461
462static void _rtl92ce_update_rxsignalstatistics(struct ieee80211_hw *hw,
463 struct rtl_stats *pstats)
464{
465 struct rtl_priv *rtlpriv = rtl_priv(hw);
466 int weighting;
467
468 if (rtlpriv->stats.recv_signal_power == 0)
469 rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
470
471 if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
472 weighting = 5;
473
474 else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
475 weighting = (-5);
476
477 rtlpriv->stats.recv_signal_power =
478 (rtlpriv->stats.recv_signal_power * 5 +
479 pstats->recvsignalpower + weighting) / 6;
480}
481
482static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw,
483 struct rtl_stats *pstats)
484{
485 struct rtl_priv *rtlpriv = rtl_priv(hw);
486 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
487 long undecorated_smoothed_pwdb;
488
489 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
490 return;
491 } else {
492 undecorated_smoothed_pwdb =
493 rtlpriv->dm.undecorated_smoothed_pwdb;
494 }
495
496 if (pstats->b_packet_toself || pstats->b_packet_beacon) {
497 if (undecorated_smoothed_pwdb < 0)
498 undecorated_smoothed_pwdb = pstats->rx_pwdb_all;
499
500 if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) {
501 undecorated_smoothed_pwdb =
502 (((undecorated_smoothed_pwdb) *
503 (RX_SMOOTH_FACTOR - 1)) +
504 (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
505
506 undecorated_smoothed_pwdb = undecorated_smoothed_pwdb
507 + 1;
508 } else {
509 undecorated_smoothed_pwdb =
510 (((undecorated_smoothed_pwdb) *
511 (RX_SMOOTH_FACTOR - 1)) +
512 (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
513 }
514
515 rtlpriv->dm.undecorated_smoothed_pwdb =
516 undecorated_smoothed_pwdb;
517 _rtl92ce_update_rxsignalstatistics(hw, pstats);
518 }
519}
520
521static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw,
522 struct rtl_stats *pstats)
523{
524 struct rtl_priv *rtlpriv = rtl_priv(hw);
525 u32 last_evm, n_spatialstream, tmpval;
526
527 if (pstats->signalquality != 0) {
528 if (pstats->b_packet_toself || pstats->b_packet_beacon) {
529
530 if (rtlpriv->stats.ui_link_quality.total_num++ >=
531 PHY_LINKQUALITY_SLID_WIN_MAX) {
532 rtlpriv->stats.ui_link_quality.total_num =
533 PHY_LINKQUALITY_SLID_WIN_MAX;
534 last_evm =
535 rtlpriv->stats.
536 ui_link_quality.elements[rtlpriv->
537 stats.ui_link_quality.
538 index];
539 rtlpriv->stats.ui_link_quality.total_val -=
540 last_evm;
541 }
542
543 rtlpriv->stats.ui_link_quality.total_val +=
544 pstats->signalquality;
545 rtlpriv->stats.ui_link_quality.elements[rtlpriv->stats.
546 ui_link_quality.
547 index++] =
548 pstats->signalquality;
549
550 if (rtlpriv->stats.ui_link_quality.index >=
551 PHY_LINKQUALITY_SLID_WIN_MAX)
552 rtlpriv->stats.ui_link_quality.index = 0;
553
554 tmpval = rtlpriv->stats.ui_link_quality.total_val /
555 rtlpriv->stats.ui_link_quality.total_num;
556 rtlpriv->stats.signal_quality = tmpval;
557
558 rtlpriv->stats.last_sigstrength_inpercent = tmpval;
559
560 for (n_spatialstream = 0; n_spatialstream < 2;
561 n_spatialstream++) {
562 if (pstats->
563 rx_mimo_signalquality[n_spatialstream] !=
564 -1) {
565 if (rtlpriv->stats.
566 rx_evm_percentage[n_spatialstream]
567 == 0) {
568 rtlpriv->stats.
569 rx_evm_percentage
570 [n_spatialstream] =
571 pstats->rx_mimo_signalquality
572 [n_spatialstream];
573 }
574
575 rtlpriv->stats.
576 rx_evm_percentage[n_spatialstream] =
577 ((rtlpriv->
578 stats.rx_evm_percentage
579 [n_spatialstream] *
580 (RX_SMOOTH_FACTOR - 1)) +
581 (pstats->
582 rx_mimo_signalquality
583 [n_spatialstream] * 1)) /
584 (RX_SMOOTH_FACTOR);
585 }
586 }
587 }
588 } else {
589 ;
590 }
591}
592
593static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw,
594 u8 *buffer,
595 struct rtl_stats *pcurrent_stats)
596{
597
598 if (!pcurrent_stats->b_packet_matchbssid &&
599 !pcurrent_stats->b_packet_beacon)
600 return;
601
602 _rtl92ce_process_ui_rssi(hw, pcurrent_stats);
603 _rtl92ce_process_pwdb(hw, pcurrent_stats);
604 _rtl92ce_process_ui_link_quality(hw, pcurrent_stats);
605}
606
607static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
608 struct sk_buff *skb,
609 struct rtl_stats *pstats,
610 struct rx_desc_92c *pdesc,
611 struct rx_fwinfo_92c *p_drvinfo)
612{
613 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
614 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
615
616 struct ieee80211_hdr *hdr;
617 u8 *tmp_buf;
618 u8 *praddr;
619 u8 *psaddr;
620 u16 fc, type;
621 bool b_packet_matchbssid, b_packet_toself, b_packet_beacon;
622
623 tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
624
625 hdr = (struct ieee80211_hdr *)tmp_buf;
626 fc = le16_to_cpu(hdr->frame_control);
627 type = WLAN_FC_GET_TYPE(fc);
628 praddr = hdr->addr1;
629 psaddr = hdr->addr2;
630
631 b_packet_matchbssid =
632 ((IEEE80211_FTYPE_CTL != type) &&
633 (!compare_ether_addr(mac->bssid,
634 (fc & IEEE80211_FCTL_TODS) ?
635 hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ?
636 hdr->addr2 : hdr->addr3)) &&
637 (!pstats->b_hwerror) && (!pstats->b_crc) && (!pstats->b_icv));
638
639 b_packet_toself = b_packet_matchbssid &&
640 (!compare_ether_addr(praddr, rtlefuse->dev_addr));
641
642 if (ieee80211_is_beacon(fc))
643 b_packet_beacon = true;
644
645 _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
646 b_packet_matchbssid, b_packet_toself,
647 b_packet_beacon);
648
649 _rtl92ce_process_phyinfo(hw, tmp_buf, pstats);
650}
651
652bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
653 struct rtl_stats *stats,
654 struct ieee80211_rx_status *rx_status,
655 u8 *p_desc, struct sk_buff *skb)
656{
657 struct rx_fwinfo_92c *p_drvinfo;
658 struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
659
660 u32 phystatus = GET_RX_DESC_PHYST(pdesc);
661 stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
662 stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
663 RX_DRV_INFO_SIZE_UNIT;
664 stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
665 stats->b_icv = (u16) GET_RX_DESC_ICV(pdesc);
666 stats->b_crc = (u16) GET_RX_DESC_CRC32(pdesc);
667 stats->b_hwerror = (stats->b_crc | stats->b_icv);
668 stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
669 stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
670 stats->b_shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
671 stats->b_isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
672 stats->b_isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
673 && (GET_RX_DESC_FAGGR(pdesc) == 1));
674 stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
675 stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
676
677 rx_status->freq = hw->conf.channel->center_freq;
678 rx_status->band = hw->conf.channel->band;
679
680 if (GET_RX_DESC_CRC32(pdesc))
681 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
682
683 if (!GET_RX_DESC_SWDEC(pdesc))
684 rx_status->flag |= RX_FLAG_DECRYPTED;
685
686 if (GET_RX_DESC_BW(pdesc))
687 rx_status->flag |= RX_FLAG_40MHZ;
688
689 if (GET_RX_DESC_RXHT(pdesc))
690 rx_status->flag |= RX_FLAG_HT;
691
692 rx_status->flag |= RX_FLAG_TSFT;
693
694 if (stats->decrypted)
695 rx_status->flag |= RX_FLAG_DECRYPTED;
696
697 rx_status->rate_idx = _rtl92ce_rate_mapping((bool)
698 GET_RX_DESC_RXHT(pdesc),
699 (u8)
700 GET_RX_DESC_RXMCS(pdesc),
701 (bool)
702 GET_RX_DESC_PAGGR(pdesc));
703
704 rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
705 if (phystatus == true) {
706 p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
707 stats->rx_bufshift);
708
709 _rtl92ce_translate_rx_signal_stuff(hw,
710 skb, stats, pdesc,
711 p_drvinfo);
712 }
713
714 /*rx_status->qual = stats->signal; */
715 rx_status->signal = stats->rssi + 10;
716 /*rx_status->noise = -stats->noise; */
717
718 return true;
719}
720
721void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
722 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
723 struct ieee80211_tx_info *info, struct sk_buff *skb,
724 unsigned int queue_index)
725{
726 struct rtl_priv *rtlpriv = rtl_priv(hw);
727 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
728 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
729 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
730 bool b_defaultadapter = true;
731
732 struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid);
733
734 u8 *pdesc = (u8 *) pdesc_tx;
735 struct rtl_tcb_desc tcb_desc;
736 u8 *qc = ieee80211_get_qos_ctl(hdr);
737 u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
738 u16 seq_number;
739 u16 fc = le16_to_cpu(hdr->frame_control);
740 u8 rate_flag = info->control.rates[0].flags;
741
742 enum rtl_desc_qsel fw_qsel =
743 _rtl92ce_map_hwqueue_to_fwqueue(le16_to_cpu(hdr->frame_control),
744 queue_index);
745
746 bool b_firstseg = ((hdr->seq_ctrl &
747 cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
748
749 bool b_lastseg = ((hdr->frame_control &
750 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
751
752 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
753 skb->data, skb->len,
754 PCI_DMA_TODEVICE);
755
756 seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
757
758 rtl_get_tcb_desc(hw, info, skb, &tcb_desc);
759
760 CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
761
762 if (b_firstseg) {
763 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
764
765 SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate);
766
767 if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble)
768 SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
769
770 if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
771 info->flags & IEEE80211_TX_CTL_AMPDU) {
772 SET_TX_DESC_AGG_BREAK(pdesc, 1);
773 SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
774 }
775 SET_TX_DESC_SEQ(pdesc, seq_number);
776
777 SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.b_rts_enable &&
778 !tcb_desc.
779 b_cts_enable) ? 1 : 0));
780 SET_TX_DESC_HW_RTS_ENABLE(pdesc,
781 ((tcb_desc.b_rts_enable
782 || tcb_desc.b_cts_enable) ? 1 : 0));
783 SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.b_cts_enable) ? 1 : 0));
784 SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.b_rts_stbc) ? 1 : 0));
785
786 SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate);
787 SET_TX_DESC_RTS_BW(pdesc, 0);
788 SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc);
789 SET_TX_DESC_RTS_SHORT(pdesc,
790 ((tcb_desc.rts_rate <= DESC92C_RATE54M) ?
791 (tcb_desc.b_rts_use_shortpreamble ? 1 : 0)
792 : (tcb_desc.b_rts_use_shortgi ? 1 : 0)));
793
794 if (mac->bw_40) {
795 if (tcb_desc.b_packet_bw) {
796 SET_TX_DESC_DATA_BW(pdesc, 1);
797 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
798 } else {
799 SET_TX_DESC_DATA_BW(pdesc, 0);
800
801 if (rate_flag & IEEE80211_TX_RC_DUP_DATA) {
802 SET_TX_DESC_TX_SUB_CARRIER(pdesc,
803 mac->cur_40_prime_sc);
804 }
805 }
806 } else {
807 SET_TX_DESC_DATA_BW(pdesc, 0);
808 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
809 }
810
811 SET_TX_DESC_LINIP(pdesc, 0);
812 SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
813
814 if (sta) {
815 u8 ampdu_density = sta->ht_cap.ampdu_density;
816 SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
817 }
818
819 if (info->control.hw_key) {
820 struct ieee80211_key_conf *keyconf =
821 info->control.hw_key;
822
823 switch (keyconf->cipher) {
824 case WLAN_CIPHER_SUITE_WEP40:
825 case WLAN_CIPHER_SUITE_WEP104:
826 case WLAN_CIPHER_SUITE_TKIP:
827 SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
828 break;
829 case WLAN_CIPHER_SUITE_CCMP:
830 SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
831 break;
832 default:
833 SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
834 break;
835
836 }
837 }
838
839 SET_TX_DESC_PKT_ID(pdesc, 0);
840 SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
841
842 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
843 SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
844 SET_TX_DESC_DISABLE_FB(pdesc, 0);
845 SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0);
846
847 if (ieee80211_is_data_qos(fc)) {
848 if (mac->rdg_en) {
849 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
850 ("Enable RDG function.\n"));
851 SET_TX_DESC_RDG_ENABLE(pdesc, 1);
852 SET_TX_DESC_HTC(pdesc, 1);
853 }
854 }
855 }
856
857 SET_TX_DESC_FIRST_SEG(pdesc, (b_firstseg ? 1 : 0));
858 SET_TX_DESC_LAST_SEG(pdesc, (b_lastseg ? 1 : 0));
859
860 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
861
862 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
863
864 if (rtlpriv->dm.b_useramask) {
865 SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index);
866 SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id);
867 } else {
868 SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index);
869 SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index);
870 }
871
872 if ((!ieee80211_is_data_qos(fc)) && ppsc->b_leisure_ps &&
873 ppsc->b_fwctrl_lps) {
874 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
875 SET_TX_DESC_PKT_ID(pdesc, 8);
876
877 if (!b_defaultadapter)
878 SET_TX_DESC_QOS(pdesc, 1);
879 }
880
881 SET_TX_DESC_MORE_FRAG(pdesc, (b_lastseg ? 0 : 1));
882
883 if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
884 is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
885 SET_TX_DESC_BMC(pdesc, 1);
886 }
887
888 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
889}
890
891void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
892 u8 *pdesc, bool b_firstseg,
893 bool b_lastseg, struct sk_buff *skb)
894{
895 struct rtl_priv *rtlpriv = rtl_priv(hw);
896 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
897 u8 fw_queue = QSLT_BEACON;
898
899 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
900 skb->data, skb->len,
901 PCI_DMA_TODEVICE);
902
903 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
904 u16 fc = le16_to_cpu(hdr->frame_control);
905
906 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
907
908 if (b_firstseg)
909 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
910
911 SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
912
913 SET_TX_DESC_SEQ(pdesc, 0);
914
915 SET_TX_DESC_LINIP(pdesc, 0);
916
917 SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
918
919 SET_TX_DESC_FIRST_SEG(pdesc, 1);
920 SET_TX_DESC_LAST_SEG(pdesc, 1);
921
922 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
923
924 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
925
926 SET_TX_DESC_RATE_ID(pdesc, 7);
927 SET_TX_DESC_MACID(pdesc, 0);
928
929 SET_TX_DESC_OWN(pdesc, 1);
930
931 SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
932
933 SET_TX_DESC_FIRST_SEG(pdesc, 1);
934 SET_TX_DESC_LAST_SEG(pdesc, 1);
935
936 SET_TX_DESC_OFFSET(pdesc, 0x20);
937
938 SET_TX_DESC_USE_RATE(pdesc, 1);
939
940 if (!ieee80211_is_data_qos(fc)) {
941 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
942 SET_TX_DESC_PKT_ID(pdesc, 8);
943 }
944
945 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
946 "H2C Tx Cmd Content\n",
947 pdesc, TX_DESC_SIZE);
948}
949
950void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
951{
952 if (istx == true) {
953 switch (desc_name) {
954 case HW_DESC_OWN:
955 SET_TX_DESC_OWN(pdesc, 1);
956 break;
957 case HW_DESC_TX_NEXTDESC_ADDR:
958 SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
959 break;
960 default:
961 RT_ASSERT(false, ("ERR txdesc :%d"
962 " not process\n", desc_name));
963 break;
964 }
965 } else {
966 switch (desc_name) {
967 case HW_DESC_RXOWN:
968 SET_RX_DESC_OWN(pdesc, 1);
969 break;
970 case HW_DESC_RXBUFF_ADDR:
971 SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
972 break;
973 case HW_DESC_RXPKT_LEN:
974 SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
975 break;
976 case HW_DESC_RXERO:
977 SET_RX_DESC_EOR(pdesc, 1);
978 break;
979 default:
980 RT_ASSERT(false, ("ERR rxdesc :%d "
981 "not process\n", desc_name));
982 break;
983 }
984 }
985}
986
987u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
988{
989 u32 ret = 0;
990
991 if (istx == true) {
992 switch (desc_name) {
993 case HW_DESC_OWN:
994 ret = GET_TX_DESC_OWN(p_desc);
995 break;
996 case HW_DESC_TXBUFF_ADDR:
997 ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
998 break;
999 default:
1000 RT_ASSERT(false, ("ERR txdesc :%d "
1001 "not process\n", desc_name));
1002 break;
1003 }
1004 } else {
1005 struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
1006 switch (desc_name) {
1007 case HW_DESC_OWN:
1008 ret = GET_RX_DESC_OWN(pdesc);
1009 break;
1010 case HW_DESC_RXPKT_LEN:
1011 ret = GET_RX_DESC_PKT_LEN(pdesc);
1012 break;
1013 default:
1014 RT_ASSERT(false, ("ERR rxdesc :%d "
1015 "not process\n", desc_name));
1016 break;
1017 }
1018 }
1019 return ret;
1020}
1021
1022void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue)
1023{
1024 struct rtl_priv *rtlpriv = rtl_priv(hw);
1025 if (hw_queue == BEACON_QUEUE) {
1026 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
1027 } else {
1028 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
1029 BIT(0) << (hw_queue));
1030 }
1031}