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