Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / drivers / net / wireless / rtlwifi / rtl8192ce / trx.c
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 enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(__le16 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
77 static 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
175 static 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
185 static 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
205 static 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
215 static 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
244 static 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 packet_match_bssid,
249                                        bool packet_toself,
250                                        bool 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 evm, pwdb_all, rf_rx_num = 0;
256         u8 i, max_spatial_stream;
257         u32 rssi, total_rssi = 0;
258         bool is_cck_rate;
259
260         is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
261         pstats->packet_matchbssid = packet_match_bssid;
262         pstats->packet_toself = packet_toself;
263         pstats->is_cck = is_cck_rate;
264         pstats->packet_beacon = packet_beacon;
265         pstats->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 (packet_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.rfpath_rxenable[0] =
338                     rtlpriv->dm.rfpath_rxenable[1] = true;
339                 for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
340                         if (rtlpriv->dm.rfpath_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 (packet_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 (packet_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
388 static 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->packet_toself || pstats->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->is_cck && pstats->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
462 static 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 = 0;
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
482 static 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->packet_toself || pstats->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
521 static 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->packet_toself || pstats->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
593 static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw,
594                                      u8 *buffer,
595                                      struct rtl_stats *pcurrent_stats)
596 {
597
598         if (!pcurrent_stats->packet_matchbssid &&
599             !pcurrent_stats->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
607 static 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         __le16 fc;
621         u16 type, c_fc;
622         bool packet_matchbssid, packet_toself, packet_beacon;
623
624         tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
625
626         hdr = (struct ieee80211_hdr *)tmp_buf;
627         fc = hdr->frame_control;
628         c_fc = le16_to_cpu(fc);
629         type = WLAN_FC_GET_TYPE(fc);
630         praddr = hdr->addr1;
631         psaddr = hdr->addr2;
632
633         packet_matchbssid =
634             ((IEEE80211_FTYPE_CTL != type) &&
635              (!compare_ether_addr(mac->bssid,
636                                   (c_fc & IEEE80211_FCTL_TODS) ?
637                                   hdr->addr1 : (c_fc & IEEE80211_FCTL_FROMDS) ?
638                                   hdr->addr2 : hdr->addr3)) &&
639              (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
640
641         packet_toself = packet_matchbssid &&
642             (!compare_ether_addr(praddr, rtlefuse->dev_addr));
643
644         if (ieee80211_is_beacon(fc))
645                 packet_beacon = true;
646
647         _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
648                                    packet_matchbssid, packet_toself,
649                                    packet_beacon);
650
651         _rtl92ce_process_phyinfo(hw, tmp_buf, pstats);
652 }
653
654 bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
655                            struct rtl_stats *stats,
656                            struct ieee80211_rx_status *rx_status,
657                            u8 *p_desc, struct sk_buff *skb)
658 {
659         struct rx_fwinfo_92c *p_drvinfo;
660         struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
661
662         u32 phystatus = GET_RX_DESC_PHYST(pdesc);
663         stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
664         stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
665             RX_DRV_INFO_SIZE_UNIT;
666         stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
667         stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
668         stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
669         stats->hwerror = (stats->crc | stats->icv);
670         stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
671         stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
672         stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
673         stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
674         stats->isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
675                                    && (GET_RX_DESC_FAGGR(pdesc) == 1));
676         stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
677         stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
678
679         rx_status->freq = hw->conf.channel->center_freq;
680         rx_status->band = hw->conf.channel->band;
681
682         if (GET_RX_DESC_CRC32(pdesc))
683                 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
684
685         if (!GET_RX_DESC_SWDEC(pdesc))
686                 rx_status->flag |= RX_FLAG_DECRYPTED;
687
688         if (GET_RX_DESC_BW(pdesc))
689                 rx_status->flag |= RX_FLAG_40MHZ;
690
691         if (GET_RX_DESC_RXHT(pdesc))
692                 rx_status->flag |= RX_FLAG_HT;
693
694         rx_status->flag |= RX_FLAG_MACTIME_MPDU;
695
696         if (stats->decrypted)
697                 rx_status->flag |= RX_FLAG_DECRYPTED;
698
699         rx_status->rate_idx = _rtl92ce_rate_mapping((bool)
700                                                     GET_RX_DESC_RXHT(pdesc),
701                                                     (u8)
702                                                     GET_RX_DESC_RXMCS(pdesc),
703                                                     (bool)
704                                                     GET_RX_DESC_PAGGR(pdesc));
705
706         rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
707         if (phystatus == true) {
708                 p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
709                                                      stats->rx_bufshift);
710
711                 _rtl92ce_translate_rx_signal_stuff(hw,
712                                                    skb, stats, pdesc,
713                                                    p_drvinfo);
714         }
715
716         /*rx_status->qual = stats->signal; */
717         rx_status->signal = stats->rssi + 10;
718         /*rx_status->noise = -stats->noise; */
719
720         return true;
721 }
722
723 void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
724                           struct ieee80211_hdr *hdr, u8 *pdesc_tx,
725                           struct ieee80211_tx_info *info, struct sk_buff *skb,
726                           unsigned int queue_index)
727 {
728         struct rtl_priv *rtlpriv = rtl_priv(hw);
729         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
730         struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
731         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
732         bool defaultadapter = true;
733         struct ieee80211_sta *sta;
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         __le16 fc = 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(fc, queue_index);
744
745         bool firstseg = ((hdr->seq_ctrl &
746                           cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
747
748         bool lastseg = ((hdr->frame_control &
749                          cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
750
751         dma_addr_t mapping = pci_map_single(rtlpci->pdev,
752                                             skb->data, skb->len,
753                                             PCI_DMA_TODEVICE);
754
755         seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
756
757         rtl_get_tcb_desc(hw, info, skb, &tcb_desc);
758
759         CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
760
761         if (firstseg) {
762                 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
763
764                 SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate);
765
766                 if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble)
767                         SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
768
769                 if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
770                     info->flags & IEEE80211_TX_CTL_AMPDU) {
771                         SET_TX_DESC_AGG_BREAK(pdesc, 1);
772                         SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
773                 }
774                 SET_TX_DESC_SEQ(pdesc, seq_number);
775
776                 SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.rts_enable &&
777                                                 !tcb_desc.
778                                                 cts_enable) ? 1 : 0));
779                 SET_TX_DESC_HW_RTS_ENABLE(pdesc,
780                                           ((tcb_desc.rts_enable
781                                             || tcb_desc.cts_enable) ? 1 : 0));
782                 SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.cts_enable) ? 1 : 0));
783                 SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.rts_stbc) ? 1 : 0));
784
785                 SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate);
786                 SET_TX_DESC_RTS_BW(pdesc, 0);
787                 SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc);
788                 SET_TX_DESC_RTS_SHORT(pdesc,
789                                       ((tcb_desc.rts_rate <= DESC92C_RATE54M) ?
790                                       (tcb_desc.rts_use_shortpreamble ? 1 : 0)
791                                       : (tcb_desc.rts_use_shortgi ? 1 : 0)));
792
793                 if (mac->bw_40) {
794                         if (tcb_desc.packet_bw) {
795                                 SET_TX_DESC_DATA_BW(pdesc, 1);
796                                 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
797                         } else {
798                                 SET_TX_DESC_DATA_BW(pdesc, 0);
799
800                                 if (rate_flag & IEEE80211_TX_RC_DUP_DATA) {
801                                         SET_TX_DESC_TX_SUB_CARRIER(pdesc,
802                                                         mac->cur_40_prime_sc);
803                                 }
804                         }
805                 } else {
806                         SET_TX_DESC_DATA_BW(pdesc, 0);
807                         SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
808                 }
809
810                 SET_TX_DESC_LINIP(pdesc, 0);
811                 SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
812
813                 rcu_read_lock();
814                 sta = ieee80211_find_sta(mac->vif, mac->bssid);
815                 if (sta) {
816                         u8 ampdu_density = sta->ht_cap.ampdu_density;
817                         SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
818                 }
819                 rcu_read_unlock();
820
821                 if (info->control.hw_key) {
822                         struct ieee80211_key_conf *keyconf =
823                             info->control.hw_key;
824
825                         switch (keyconf->cipher) {
826                         case WLAN_CIPHER_SUITE_WEP40:
827                         case WLAN_CIPHER_SUITE_WEP104:
828                         case WLAN_CIPHER_SUITE_TKIP:
829                                 SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
830                                 break;
831                         case WLAN_CIPHER_SUITE_CCMP:
832                                 SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
833                                 break;
834                         default:
835                                 SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
836                                 break;
837
838                         }
839                 }
840
841                 SET_TX_DESC_PKT_ID(pdesc, 0);
842                 SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
843
844                 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
845                 SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
846                 SET_TX_DESC_DISABLE_FB(pdesc, 0);
847                 SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0);
848
849                 if (ieee80211_is_data_qos(fc)) {
850                         if (mac->rdg_en) {
851                                 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
852                                          ("Enable RDG function.\n"));
853                                 SET_TX_DESC_RDG_ENABLE(pdesc, 1);
854                                 SET_TX_DESC_HTC(pdesc, 1);
855                         }
856                 }
857         }
858
859         SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
860         SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
861
862         SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
863
864         SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
865
866         if (rtlpriv->dm.useramask) {
867                 SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index);
868                 SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id);
869         } else {
870                 SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index);
871                 SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index);
872         }
873
874         if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps &&
875             ppsc->fwctrl_lps) {
876                 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
877                 SET_TX_DESC_PKT_ID(pdesc, 8);
878
879                 if (!defaultadapter)
880                         SET_TX_DESC_QOS(pdesc, 1);
881         }
882
883         SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
884
885         if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
886             is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
887                 SET_TX_DESC_BMC(pdesc, 1);
888         }
889
890         RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
891 }
892
893 void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
894                              u8 *pdesc, bool firstseg,
895                              bool lastseg, struct sk_buff *skb)
896 {
897         struct rtl_priv *rtlpriv = rtl_priv(hw);
898         struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
899         u8 fw_queue = QSLT_BEACON;
900
901         dma_addr_t mapping = pci_map_single(rtlpci->pdev,
902                                             skb->data, skb->len,
903                                             PCI_DMA_TODEVICE);
904
905         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
906         __le16 fc = hdr->frame_control;
907
908         CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
909
910         if (firstseg)
911                 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
912
913         SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
914
915         SET_TX_DESC_SEQ(pdesc, 0);
916
917         SET_TX_DESC_LINIP(pdesc, 0);
918
919         SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
920
921         SET_TX_DESC_FIRST_SEG(pdesc, 1);
922         SET_TX_DESC_LAST_SEG(pdesc, 1);
923
924         SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
925
926         SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
927
928         SET_TX_DESC_RATE_ID(pdesc, 7);
929         SET_TX_DESC_MACID(pdesc, 0);
930
931         SET_TX_DESC_OWN(pdesc, 1);
932
933         SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
934
935         SET_TX_DESC_FIRST_SEG(pdesc, 1);
936         SET_TX_DESC_LAST_SEG(pdesc, 1);
937
938         SET_TX_DESC_OFFSET(pdesc, 0x20);
939
940         SET_TX_DESC_USE_RATE(pdesc, 1);
941
942         if (!ieee80211_is_data_qos(fc)) {
943                 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
944                 SET_TX_DESC_PKT_ID(pdesc, 8);
945         }
946
947         RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
948                       "H2C Tx Cmd Content\n",
949                       pdesc, TX_DESC_SIZE);
950 }
951
952 void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
953 {
954         if (istx == true) {
955                 switch (desc_name) {
956                 case HW_DESC_OWN:
957                         SET_TX_DESC_OWN(pdesc, 1);
958                         break;
959                 case HW_DESC_TX_NEXTDESC_ADDR:
960                         SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
961                         break;
962                 default:
963                         RT_ASSERT(false, ("ERR txdesc :%d"
964                                           " not process\n", desc_name));
965                         break;
966                 }
967         } else {
968                 switch (desc_name) {
969                 case HW_DESC_RXOWN:
970                         SET_RX_DESC_OWN(pdesc, 1);
971                         break;
972                 case HW_DESC_RXBUFF_ADDR:
973                         SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
974                         break;
975                 case HW_DESC_RXPKT_LEN:
976                         SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
977                         break;
978                 case HW_DESC_RXERO:
979                         SET_RX_DESC_EOR(pdesc, 1);
980                         break;
981                 default:
982                         RT_ASSERT(false, ("ERR rxdesc :%d "
983                                           "not process\n", desc_name));
984                         break;
985                 }
986         }
987 }
988
989 u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
990 {
991         u32 ret = 0;
992
993         if (istx == true) {
994                 switch (desc_name) {
995                 case HW_DESC_OWN:
996                         ret = GET_TX_DESC_OWN(p_desc);
997                         break;
998                 case HW_DESC_TXBUFF_ADDR:
999                         ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
1000                         break;
1001                 default:
1002                         RT_ASSERT(false, ("ERR txdesc :%d "
1003                                           "not process\n", desc_name));
1004                         break;
1005                 }
1006         } else {
1007                 struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
1008                 switch (desc_name) {
1009                 case HW_DESC_OWN:
1010                         ret = GET_RX_DESC_OWN(pdesc);
1011                         break;
1012                 case HW_DESC_RXPKT_LEN:
1013                         ret = GET_RX_DESC_PKT_LEN(pdesc);
1014                         break;
1015                 default:
1016                         RT_ASSERT(false, ("ERR rxdesc :%d "
1017                                           "not process\n", desc_name));
1018                         break;
1019                 }
1020         }
1021         return ret;
1022 }
1023
1024 void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue)
1025 {
1026         struct rtl_priv *rtlpriv = rtl_priv(hw);
1027         if (hw_queue == BEACON_QUEUE) {
1028                 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
1029         } else {
1030                 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
1031                                BIT(0) << (hw_queue));
1032         }
1033 }
1034
1035 bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
1036                              struct sk_buff *skb)
1037 {
1038         struct rtl_priv *rtlpriv = rtl_priv(hw);
1039         struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1040         struct rtl8192_tx_ring *ring;
1041         struct rtl_tx_desc *pdesc;
1042         u8 own;
1043         unsigned long flags;
1044         struct sk_buff *pskb = NULL;
1045
1046         ring = &rtlpci->tx_ring[BEACON_QUEUE];
1047
1048         spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
1049
1050         pskb = __skb_dequeue(&ring->queue);
1051         if (pskb)
1052                 kfree_skb(pskb);
1053
1054         pdesc = &ring->desc[0];
1055         own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
1056
1057         rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
1058
1059         __skb_queue_tail(&ring->queue, skb);
1060
1061         spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
1062
1063         rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
1064
1065         return true;
1066 }