]> rtime.felk.cvut.cz Git - linux-imx.git/blob - drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
net: wireless/rtlwifi: fix uninitialized variable issue
[linux-imx.git] / drivers / net / wireless / rtlwifi / rtl8192ce / trx.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2012  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         struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
131         s8 rx_pwr_all = 0, rx_pwr[4];
132         u8 evm, pwdb_all, rf_rx_num = 0;
133         u8 i, max_spatial_stream;
134         u32 rssi, total_rssi = 0;
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_sig_qual[0] = -1;
144         pstats->rx_mimo_sig_qual[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 (ppsc->rfpwr_state == ERFON)
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_sig_qual[0] = sq;
215                         pstats->rx_mimo_sig_qual[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_sig_qual[i] = (u8) (evm & 0xff);
255                         }
256                 }
257         }
258
259         if (is_cck_rate)
260                 pstats->signalstrength =
261                     (u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all));
262         else if (rf_rx_num != 0)
263                 pstats->signalstrength =
264                     (u8) (_rtl92ce_signal_scale_mapping
265                           (hw, total_rssi /= rf_rx_num));
266 }
267
268 static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw,
269                 struct rtl_stats *pstats)
270 {
271         struct rtl_priv *rtlpriv = rtl_priv(hw);
272         struct rtl_phy *rtlphy = &(rtlpriv->phy);
273         u8 rfpath;
274         u32 last_rssi, tmpval;
275
276         if (pstats->packet_toself || pstats->packet_beacon) {
277                 rtlpriv->stats.rssi_calculate_cnt++;
278
279                 if (rtlpriv->stats.ui_rssi.total_num++ >=
280                     PHY_RSSI_SLID_WIN_MAX) {
281
282                         rtlpriv->stats.ui_rssi.total_num =
283                             PHY_RSSI_SLID_WIN_MAX;
284                         last_rssi =
285                             rtlpriv->stats.ui_rssi.elements[rtlpriv->
286                                                     stats.ui_rssi.index];
287                         rtlpriv->stats.ui_rssi.total_val -= last_rssi;
288                 }
289
290                 rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
291                 rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.
292                                                 index++] =
293                     pstats->signalstrength;
294
295                 if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
296                         rtlpriv->stats.ui_rssi.index = 0;
297
298                 tmpval = rtlpriv->stats.ui_rssi.total_val /
299                     rtlpriv->stats.ui_rssi.total_num;
300                 rtlpriv->stats.signal_strength =
301                     _rtl92ce_translate_todbm(hw, (u8) tmpval);
302                 pstats->rssi = rtlpriv->stats.signal_strength;
303         }
304
305         if (!pstats->is_cck && pstats->packet_toself) {
306                 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
307                      rfpath++) {
308                         if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
309                                 rtlpriv->stats.rx_rssi_percentage[rfpath] =
310                                     pstats->rx_mimo_signalstrength[rfpath];
311
312                         }
313
314                         if (pstats->rx_mimo_signalstrength[rfpath] >
315                             rtlpriv->stats.rx_rssi_percentage[rfpath]) {
316                                 rtlpriv->stats.rx_rssi_percentage[rfpath] =
317                                     ((rtlpriv->stats.
318                                       rx_rssi_percentage[rfpath] *
319                                       (RX_SMOOTH_FACTOR - 1)) +
320                                      (pstats->rx_mimo_signalstrength[rfpath])) /
321                                     (RX_SMOOTH_FACTOR);
322
323                                 rtlpriv->stats.rx_rssi_percentage[rfpath] =
324                                     rtlpriv->stats.rx_rssi_percentage[rfpath] +
325                                     1;
326                         } else {
327                                 rtlpriv->stats.rx_rssi_percentage[rfpath] =
328                                     ((rtlpriv->stats.
329                                       rx_rssi_percentage[rfpath] *
330                                       (RX_SMOOTH_FACTOR - 1)) +
331                                      (pstats->rx_mimo_signalstrength[rfpath])) /
332                                     (RX_SMOOTH_FACTOR);
333                         }
334
335                 }
336         }
337 }
338
339 static void _rtl92ce_update_rxsignalstatistics(struct ieee80211_hw *hw,
340                                                struct rtl_stats *pstats)
341 {
342         struct rtl_priv *rtlpriv = rtl_priv(hw);
343         int weighting = 0;
344
345         if (rtlpriv->stats.recv_signal_power == 0)
346                 rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
347
348         if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
349                 weighting = 5;
350
351         else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
352                 weighting = (-5);
353
354         rtlpriv->stats.recv_signal_power =
355             (rtlpriv->stats.recv_signal_power * 5 +
356              pstats->recvsignalpower + weighting) / 6;
357 }
358
359 static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw,
360                 struct rtl_stats *pstats)
361 {
362         struct rtl_priv *rtlpriv = rtl_priv(hw);
363         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
364         long undec_sm_pwdb;
365
366         if (mac->opmode == NL80211_IFTYPE_ADHOC) {
367                 return;
368         } else {
369                 undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
370         }
371
372         if (pstats->packet_toself || pstats->packet_beacon) {
373                 if (undec_sm_pwdb < 0)
374                         undec_sm_pwdb = pstats->rx_pwdb_all;
375
376                 if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) {
377                         undec_sm_pwdb = (((undec_sm_pwdb) *
378                               (RX_SMOOTH_FACTOR - 1)) +
379                              (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
380
381                         undec_sm_pwdb += 1;
382                 } else {
383                         undec_sm_pwdb = (((undec_sm_pwdb) *
384                               (RX_SMOOTH_FACTOR - 1)) +
385                              (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
386                 }
387
388                 rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb;
389                 _rtl92ce_update_rxsignalstatistics(hw, pstats);
390         }
391 }
392
393 static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw,
394                                              struct rtl_stats *pstats)
395 {
396         struct rtl_priv *rtlpriv = rtl_priv(hw);
397         u32 last_evm, n_spatialstream, tmpval;
398
399         if (pstats->signalquality != 0) {
400                 if (pstats->packet_toself || pstats->packet_beacon) {
401
402                         if (rtlpriv->stats.ui_link_quality.total_num++ >=
403                             PHY_LINKQUALITY_SLID_WIN_MAX) {
404                                 rtlpriv->stats.ui_link_quality.total_num =
405                                     PHY_LINKQUALITY_SLID_WIN_MAX;
406                                 last_evm =
407                                     rtlpriv->stats.
408                                     ui_link_quality.elements[rtlpriv->
409                                                           stats.ui_link_quality.
410                                                           index];
411                                 rtlpriv->stats.ui_link_quality.total_val -=
412                                     last_evm;
413                         }
414
415                         rtlpriv->stats.ui_link_quality.total_val +=
416                             pstats->signalquality;
417                         rtlpriv->stats.ui_link_quality.elements[rtlpriv->stats.
418                                                                 ui_link_quality.
419                                                                 index++] =
420                             pstats->signalquality;
421
422                         if (rtlpriv->stats.ui_link_quality.index >=
423                             PHY_LINKQUALITY_SLID_WIN_MAX)
424                                 rtlpriv->stats.ui_link_quality.index = 0;
425
426                         tmpval = rtlpriv->stats.ui_link_quality.total_val /
427                             rtlpriv->stats.ui_link_quality.total_num;
428                         rtlpriv->stats.signal_quality = tmpval;
429
430                         rtlpriv->stats.last_sigstrength_inpercent = tmpval;
431
432                         for (n_spatialstream = 0; n_spatialstream < 2;
433                              n_spatialstream++) {
434                                 if (pstats->
435                                     rx_mimo_sig_qual[n_spatialstream] != -1) {
436                                         if (rtlpriv->stats.
437                                             rx_evm_percentage[n_spatialstream]
438                                             == 0) {
439                                                 rtlpriv->stats.
440                                                    rx_evm_percentage
441                                                    [n_spatialstream] =
442                                                    pstats->rx_mimo_sig_qual
443                                                    [n_spatialstream];
444                                         }
445
446                                         rtlpriv->stats.
447                                             rx_evm_percentage[n_spatialstream] =
448                                             ((rtlpriv->
449                                               stats.rx_evm_percentage
450                                               [n_spatialstream] *
451                                               (RX_SMOOTH_FACTOR - 1)) +
452                                              (pstats->rx_mimo_sig_qual
453                                               [n_spatialstream] * 1)) /
454                                             (RX_SMOOTH_FACTOR);
455                                 }
456                         }
457                 }
458         } else {
459                 ;
460         }
461 }
462
463 static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw,
464                                      u8 *buffer,
465                                      struct rtl_stats *pcurrent_stats)
466 {
467
468         if (!pcurrent_stats->packet_matchbssid &&
469             !pcurrent_stats->packet_beacon)
470                 return;
471
472         _rtl92ce_process_ui_rssi(hw, pcurrent_stats);
473         _rtl92ce_process_pwdb(hw, pcurrent_stats);
474         _rtl92ce_process_ui_link_quality(hw, pcurrent_stats);
475 }
476
477 static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
478                                                struct sk_buff *skb,
479                                                struct rtl_stats *pstats,
480                                                struct rx_desc_92c *pdesc,
481                                                struct rx_fwinfo_92c *p_drvinfo)
482 {
483         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
484         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
485
486         struct ieee80211_hdr *hdr;
487         u8 *tmp_buf;
488         u8 *praddr;
489         __le16 fc;
490         u16 type, c_fc;
491         bool packet_matchbssid, packet_toself, packet_beacon = false;
492
493         tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
494
495         hdr = (struct ieee80211_hdr *)tmp_buf;
496         fc = hdr->frame_control;
497         c_fc = le16_to_cpu(fc);
498         type = WLAN_FC_GET_TYPE(fc);
499         praddr = hdr->addr1;
500
501         packet_matchbssid =
502             ((IEEE80211_FTYPE_CTL != type) &&
503              ether_addr_equal(mac->bssid,
504                               (c_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
505                               (c_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
506                               hdr->addr3) &&
507              (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
508
509         packet_toself = packet_matchbssid &&
510              ether_addr_equal(praddr, rtlefuse->dev_addr);
511
512         if (ieee80211_is_beacon(fc))
513                 packet_beacon = true;
514
515         _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
516                                    packet_matchbssid, packet_toself,
517                                    packet_beacon);
518
519         _rtl92ce_process_phyinfo(hw, tmp_buf, pstats);
520 }
521
522 bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
523                            struct rtl_stats *stats,
524                            struct ieee80211_rx_status *rx_status,
525                            u8 *p_desc, struct sk_buff *skb)
526 {
527         struct rx_fwinfo_92c *p_drvinfo;
528         struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
529
530         u32 phystatus = GET_RX_DESC_PHYST(pdesc);
531         stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
532         stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
533             RX_DRV_INFO_SIZE_UNIT;
534         stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
535         stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
536         stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
537         stats->hwerror = (stats->crc | stats->icv);
538         stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
539         stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
540         stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
541         stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
542         stats->isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
543                                    && (GET_RX_DESC_FAGGR(pdesc) == 1));
544         stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
545         stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
546
547         rx_status->freq = hw->conf.channel->center_freq;
548         rx_status->band = hw->conf.channel->band;
549
550         if (GET_RX_DESC_CRC32(pdesc))
551                 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
552
553         if (!GET_RX_DESC_SWDEC(pdesc))
554                 rx_status->flag |= RX_FLAG_DECRYPTED;
555
556         if (GET_RX_DESC_BW(pdesc))
557                 rx_status->flag |= RX_FLAG_40MHZ;
558
559         if (GET_RX_DESC_RXHT(pdesc))
560                 rx_status->flag |= RX_FLAG_HT;
561
562         rx_status->flag |= RX_FLAG_MACTIME_START;
563
564         if (stats->decrypted)
565                 rx_status->flag |= RX_FLAG_DECRYPTED;
566
567         rx_status->rate_idx = rtlwifi_rate_mapping(hw,
568                                 (bool)GET_RX_DESC_RXHT(pdesc),
569                                 (u8)GET_RX_DESC_RXMCS(pdesc),
570                                 (bool)GET_RX_DESC_PAGGR(pdesc));
571
572         rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
573         if (phystatus) {
574                 p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
575                                                      stats->rx_bufshift);
576
577                 _rtl92ce_translate_rx_signal_stuff(hw,
578                                                    skb, stats, pdesc,
579                                                    p_drvinfo);
580         }
581
582         /*rx_status->qual = stats->signal; */
583         rx_status->signal = stats->rssi + 10;
584         /*rx_status->noise = -stats->noise; */
585
586         return true;
587 }
588
589 void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
590                           struct ieee80211_hdr *hdr, u8 *pdesc_tx,
591                           struct ieee80211_tx_info *info,
592                           struct ieee80211_sta *sta,
593                           struct sk_buff *skb,
594                           u8 hw_queue, struct rtl_tcb_desc *tcb_desc)
595 {
596         struct rtl_priv *rtlpriv = rtl_priv(hw);
597         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
598         struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
599         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
600         bool defaultadapter = true;
601         u8 *pdesc = pdesc_tx;
602         u16 seq_number;
603         __le16 fc = hdr->frame_control;
604         u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue);
605         bool firstseg = ((hdr->seq_ctrl &
606                           cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
607
608         bool lastseg = ((hdr->frame_control &
609                          cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
610
611         dma_addr_t mapping = pci_map_single(rtlpci->pdev,
612                                             skb->data, skb->len,
613                                             PCI_DMA_TODEVICE);
614
615         u8 bw_40 = 0;
616
617         if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
618                 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
619                          "DMA mapping error");
620                 return;
621         }
622         rcu_read_lock();
623         sta = get_sta(hw, mac->vif, mac->bssid);
624         if (mac->opmode == NL80211_IFTYPE_STATION) {
625                 bw_40 = mac->bw_40;
626         } else if (mac->opmode == NL80211_IFTYPE_AP ||
627                 mac->opmode == NL80211_IFTYPE_ADHOC) {
628                 if (sta)
629                         bw_40 = sta->ht_cap.cap &
630                                 IEEE80211_HT_CAP_SUP_WIDTH_20_40;
631         }
632
633         seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
634
635         rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
636
637         CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
638
639         if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
640                 firstseg = true;
641                 lastseg = true;
642         }
643         if (firstseg) {
644                 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
645
646                 SET_TX_DESC_TX_RATE(pdesc, tcb_desc->hw_rate);
647
648                 if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
649                         SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
650
651                 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
652                         SET_TX_DESC_AGG_BREAK(pdesc, 1);
653                         SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
654                 }
655                 SET_TX_DESC_SEQ(pdesc, seq_number);
656
657                 SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc->rts_enable &&
658                                                 !tcb_desc->
659                                                 cts_enable) ? 1 : 0));
660                 SET_TX_DESC_HW_RTS_ENABLE(pdesc,
661                                           ((tcb_desc->rts_enable
662                                             || tcb_desc->cts_enable) ? 1 : 0));
663                 SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc->cts_enable) ? 1 : 0));
664                 SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
665
666                 SET_TX_DESC_RTS_RATE(pdesc, tcb_desc->rts_rate);
667                 SET_TX_DESC_RTS_BW(pdesc, 0);
668                 SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc);
669                 SET_TX_DESC_RTS_SHORT(pdesc,
670                                       ((tcb_desc->rts_rate <= DESC92_RATE54M) ?
671                                        (tcb_desc->rts_use_shortpreamble ? 1 : 0)
672                                        : (tcb_desc->rts_use_shortgi ? 1 : 0)));
673
674                 if (bw_40) {
675                         if (tcb_desc->packet_bw) {
676                                 SET_TX_DESC_DATA_BW(pdesc, 1);
677                                 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
678                         } else {
679                                 SET_TX_DESC_DATA_BW(pdesc, 0);
680                                 SET_TX_DESC_TX_SUB_CARRIER(pdesc,
681                                                  mac->cur_40_prime_sc);
682                         }
683                 } else {
684                         SET_TX_DESC_DATA_BW(pdesc, 0);
685                         SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
686                 }
687
688                 SET_TX_DESC_LINIP(pdesc, 0);
689                 SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
690
691                 if (sta) {
692                         u8 ampdu_density = sta->ht_cap.ampdu_density;
693                         SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
694                 }
695
696                 if (info->control.hw_key) {
697                         struct ieee80211_key_conf *keyconf =
698                             info->control.hw_key;
699
700                         switch (keyconf->cipher) {
701                         case WLAN_CIPHER_SUITE_WEP40:
702                         case WLAN_CIPHER_SUITE_WEP104:
703                         case WLAN_CIPHER_SUITE_TKIP:
704                                 SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
705                                 break;
706                         case WLAN_CIPHER_SUITE_CCMP:
707                                 SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
708                                 break;
709                         default:
710                                 SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
711                                 break;
712
713                         }
714                 }
715
716                 SET_TX_DESC_PKT_ID(pdesc, 0);
717                 SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
718
719                 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
720                 SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
721                 SET_TX_DESC_DISABLE_FB(pdesc, 0);
722                 SET_TX_DESC_USE_RATE(pdesc, tcb_desc->use_driver_rate ? 1 : 0);
723
724                 if (ieee80211_is_data_qos(fc)) {
725                         if (mac->rdg_en) {
726                                 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
727                                          "Enable RDG function\n");
728                                 SET_TX_DESC_RDG_ENABLE(pdesc, 1);
729                                 SET_TX_DESC_HTC(pdesc, 1);
730                         }
731                 }
732         }
733         rcu_read_unlock();
734
735         SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
736         SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
737
738         SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
739
740         SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
741
742         if (rtlpriv->dm.useramask) {
743                 SET_TX_DESC_RATE_ID(pdesc, tcb_desc->ratr_index);
744                 SET_TX_DESC_MACID(pdesc, tcb_desc->mac_id);
745         } else {
746                 SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc->ratr_index);
747                 SET_TX_DESC_MACID(pdesc, tcb_desc->ratr_index);
748         }
749
750         if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
751                 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
752                 SET_TX_DESC_PKT_ID(pdesc, 8);
753
754                 if (!defaultadapter)
755                         SET_TX_DESC_QOS(pdesc, 1);
756         }
757
758         SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
759
760         if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
761             is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
762                 SET_TX_DESC_BMC(pdesc, 1);
763         }
764
765         RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
766 }
767
768 void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
769                              u8 *pdesc, bool firstseg,
770                              bool lastseg, struct sk_buff *skb)
771 {
772         struct rtl_priv *rtlpriv = rtl_priv(hw);
773         struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
774         u8 fw_queue = QSLT_BEACON;
775
776         dma_addr_t mapping = pci_map_single(rtlpci->pdev,
777                                             skb->data, skb->len,
778                                             PCI_DMA_TODEVICE);
779
780         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
781         __le16 fc = hdr->frame_control;
782
783         if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
784                 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
785                          "DMA mapping error");
786                 return;
787         }
788         CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
789
790         if (firstseg)
791                 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
792
793         SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M);
794
795         SET_TX_DESC_SEQ(pdesc, 0);
796
797         SET_TX_DESC_LINIP(pdesc, 0);
798
799         SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
800
801         SET_TX_DESC_FIRST_SEG(pdesc, 1);
802         SET_TX_DESC_LAST_SEG(pdesc, 1);
803
804         SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
805
806         SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
807
808         SET_TX_DESC_RATE_ID(pdesc, 7);
809         SET_TX_DESC_MACID(pdesc, 0);
810
811         SET_TX_DESC_OWN(pdesc, 1);
812
813         SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len));
814
815         SET_TX_DESC_FIRST_SEG(pdesc, 1);
816         SET_TX_DESC_LAST_SEG(pdesc, 1);
817
818         SET_TX_DESC_OFFSET(pdesc, 0x20);
819
820         SET_TX_DESC_USE_RATE(pdesc, 1);
821
822         if (!ieee80211_is_data_qos(fc)) {
823                 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
824                 SET_TX_DESC_PKT_ID(pdesc, 8);
825         }
826
827         RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
828                       "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
829 }
830
831 void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
832 {
833         if (istx) {
834                 switch (desc_name) {
835                 case HW_DESC_OWN:
836                         wmb();
837                         SET_TX_DESC_OWN(pdesc, 1);
838                         break;
839                 case HW_DESC_TX_NEXTDESC_ADDR:
840                         SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
841                         break;
842                 default:
843                         RT_ASSERT(false, "ERR txdesc :%d not process\n",
844                                   desc_name);
845                         break;
846                 }
847         } else {
848                 switch (desc_name) {
849                 case HW_DESC_RXOWN:
850                         wmb();
851                         SET_RX_DESC_OWN(pdesc, 1);
852                         break;
853                 case HW_DESC_RXBUFF_ADDR:
854                         SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
855                         break;
856                 case HW_DESC_RXPKT_LEN:
857                         SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
858                         break;
859                 case HW_DESC_RXERO:
860                         SET_RX_DESC_EOR(pdesc, 1);
861                         break;
862                 default:
863                         RT_ASSERT(false, "ERR rxdesc :%d not process\n",
864                                   desc_name);
865                         break;
866                 }
867         }
868 }
869
870 u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
871 {
872         u32 ret = 0;
873
874         if (istx) {
875                 switch (desc_name) {
876                 case HW_DESC_OWN:
877                         ret = GET_TX_DESC_OWN(p_desc);
878                         break;
879                 case HW_DESC_TXBUFF_ADDR:
880                         ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
881                         break;
882                 default:
883                         RT_ASSERT(false, "ERR txdesc :%d not process\n",
884                                   desc_name);
885                         break;
886                 }
887         } else {
888                 struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
889                 switch (desc_name) {
890                 case HW_DESC_OWN:
891                         ret = GET_RX_DESC_OWN(pdesc);
892                         break;
893                 case HW_DESC_RXPKT_LEN:
894                         ret = GET_RX_DESC_PKT_LEN(pdesc);
895                         break;
896                 default:
897                         RT_ASSERT(false, "ERR rxdesc :%d not process\n",
898                                   desc_name);
899                         break;
900                 }
901         }
902         return ret;
903 }
904
905 void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
906 {
907         struct rtl_priv *rtlpriv = rtl_priv(hw);
908         if (hw_queue == BEACON_QUEUE) {
909                 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
910         } else {
911                 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
912                                BIT(0) << (hw_queue));
913         }
914 }
915