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