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