GNU Linux-libre 4.14.290-gnu1
[releases.git] / drivers / net / wireless / realtek / 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  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  *****************************************************************************/
25
26 #include "../wifi.h"
27 #include "../pci.h"
28 #include "../base.h"
29 #include "../stats.h"
30 #include "reg.h"
31 #include "def.h"
32 #include "phy.h"
33 #include "trx.h"
34 #include "led.h"
35
36 static u8 _rtl92ce_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
37 {
38         __le16 fc = rtl_get_fc(skb);
39
40         if (unlikely(ieee80211_is_beacon(fc)))
41                 return QSLT_BEACON;
42         if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
43                 return QSLT_MGNT;
44
45         return skb->priority;
46 }
47
48 static u8 _rtl92c_query_rxpwrpercentage(s8 antpower)
49 {
50         if ((antpower <= -100) || (antpower >= 20))
51                 return 0;
52         else if (antpower >= 0)
53                 return 100;
54         else
55                 return 100 + antpower;
56 }
57
58 static u8 _rtl92c_evm_db_to_percentage(s8 value)
59 {
60         s8 ret_val;
61         ret_val = value;
62
63         if (ret_val >= 0)
64                 ret_val = 0;
65
66         if (ret_val <= -33)
67                 ret_val = -33;
68
69         ret_val = 0 - ret_val;
70         ret_val *= 3;
71
72         if (ret_val == 99)
73                 ret_val = 100;
74
75         return ret_val;
76 }
77
78 static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw,
79                 long currsig)
80 {
81         long retsig;
82
83         if (currsig >= 61 && currsig <= 100)
84                 retsig = 90 + ((currsig - 60) / 4);
85         else if (currsig >= 41 && currsig <= 60)
86                 retsig = 78 + ((currsig - 40) / 2);
87         else if (currsig >= 31 && currsig <= 40)
88                 retsig = 66 + (currsig - 30);
89         else if (currsig >= 21 && currsig <= 30)
90                 retsig = 54 + (currsig - 20);
91         else if (currsig >= 5 && currsig <= 20)
92                 retsig = 42 + (((currsig - 5) * 2) / 3);
93         else if (currsig == 4)
94                 retsig = 36;
95         else if (currsig == 3)
96                 retsig = 27;
97         else if (currsig == 2)
98                 retsig = 18;
99         else if (currsig == 1)
100                 retsig = 9;
101         else
102                 retsig = currsig;
103
104         return retsig;
105 }
106
107 static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
108                                        struct rtl_stats *pstats,
109                                        struct rx_desc_92c *pdesc,
110                                        struct rx_fwinfo_92c *p_drvinfo,
111                                        bool packet_match_bssid,
112                                        bool packet_toself,
113                                        bool packet_beacon)
114 {
115         struct rtl_priv *rtlpriv = rtl_priv(hw);
116         struct phy_sts_cck_8192s_t *cck_buf;
117         struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
118         s8 rx_pwr_all = 0, rx_pwr[4];
119         u8 evm, pwdb_all, rf_rx_num = 0;
120         u8 i, max_spatial_stream;
121         u32 rssi, total_rssi = 0;
122         bool is_cck_rate;
123
124         is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc->rxmcs);
125         pstats->packet_matchbssid = packet_match_bssid;
126         pstats->packet_toself = packet_toself;
127         pstats->is_cck = is_cck_rate;
128         pstats->packet_beacon = packet_beacon;
129         pstats->rx_mimo_sig_qual[0] = -1;
130         pstats->rx_mimo_sig_qual[1] = -1;
131
132         if (is_cck_rate) {
133                 u8 report, cck_highpwr;
134                 cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
135
136                 if (ppsc->rfpwr_state == ERFON)
137                         cck_highpwr = (u8) rtl_get_bbreg(hw,
138                                                  RFPGA0_XA_HSSIPARAMETER2,
139                                                  BIT(9));
140                 else
141                         cck_highpwr = false;
142
143                 if (!cck_highpwr) {
144                         u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
145                         report = cck_buf->cck_agc_rpt & 0xc0;
146                         report = report >> 6;
147                         switch (report) {
148                         case 0x3:
149                                 rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
150                                 break;
151                         case 0x2:
152                                 rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
153                                 break;
154                         case 0x1:
155                                 rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
156                                 break;
157                         case 0x0:
158                                 rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
159                                 break;
160                         }
161                 } else {
162                         u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
163                         report = p_drvinfo->cfosho[0] & 0x60;
164                         report = report >> 5;
165                         switch (report) {
166                         case 0x3:
167                                 rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
168                                 break;
169                         case 0x2:
170                                 rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
171                                 break;
172                         case 0x1:
173                                 rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
174                                 break;
175                         case 0x0:
176                                 rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
177                                 break;
178                         }
179                 }
180
181                 pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
182                 /* CCK gain is smaller than OFDM/MCS gain,
183                  * so we add gain diff by experiences,
184                  * the val is 6
185                  */
186                 pwdb_all += 6;
187                 if (pwdb_all > 100)
188                         pwdb_all = 100;
189                 /* modify the offset to make the same
190                  * gain index with OFDM.
191                  */
192                 if (pwdb_all > 34 && pwdb_all <= 42)
193                         pwdb_all -= 2;
194                 else if (pwdb_all > 26 && pwdb_all <= 34)
195                         pwdb_all -= 6;
196                 else if (pwdb_all > 14 && pwdb_all <= 26)
197                         pwdb_all -= 8;
198                 else if (pwdb_all > 4 && pwdb_all <= 14)
199                         pwdb_all -= 4;
200
201                 pstats->rx_pwdb_all = pwdb_all;
202                 pstats->recvsignalpower = rx_pwr_all;
203
204                 /* (3) Get Signal Quality (EVM) */
205                 if (packet_match_bssid) {
206                         u8 sq;
207                         if (pstats->rx_pwdb_all > 40)
208                                 sq = 100;
209                         else {
210                                 sq = cck_buf->sq_rpt;
211                                 if (sq > 64)
212                                         sq = 0;
213                                 else if (sq < 20)
214                                         sq = 100;
215                                 else
216                                         sq = ((64 - sq) * 100) / 44;
217                         }
218
219                         pstats->signalquality = sq;
220                         pstats->rx_mimo_sig_qual[0] = sq;
221                         pstats->rx_mimo_sig_qual[1] = -1;
222                 }
223         } else {
224                 rtlpriv->dm.rfpath_rxenable[0] =
225                     rtlpriv->dm.rfpath_rxenable[1] = true;
226                 /* (1)Get RSSI for HT rate */
227                 for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
228                         /* we will judge RF RX path now. */
229                         if (rtlpriv->dm.rfpath_rxenable[i])
230                                 rf_rx_num++;
231
232                         rx_pwr[i] =
233                             ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
234                         /* Translate DBM to percentage. */
235                         rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
236                         total_rssi += rssi;
237                         /* Get Rx snr value in DB */
238                         rtlpriv->stats.rx_snr_db[i] =
239                             (long)(p_drvinfo->rxsnr[i] / 2);
240
241                         /* Record Signal Strength for next packet */
242                         if (packet_match_bssid)
243                                 pstats->rx_mimo_signalstrength[i] = (u8) rssi;
244                 }
245
246                 /* (2)PWDB, Average PWDB cacluated by
247                  * hardware (for rate adaptive)
248                  */
249                 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
250                 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
251                 pstats->rx_pwdb_all = pwdb_all;
252                 pstats->rxpower = rx_pwr_all;
253                 pstats->recvsignalpower = rx_pwr_all;
254
255                 /* (3)EVM of HT rate */
256                 if (pstats->is_ht && pstats->rate >= DESC_RATEMCS8 &&
257                     pstats->rate <= DESC_RATEMCS15)
258                         max_spatial_stream = 2;
259                 else
260                         max_spatial_stream = 1;
261
262                 for (i = 0; i < max_spatial_stream; i++) {
263                         evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
264
265                         if (packet_match_bssid) {
266                                 /* Fill value in RFD, Get the first
267                                  * spatial stream only
268                                  */
269                                 if (i == 0)
270                                         pstats->signalquality =
271                                             (u8) (evm & 0xff);
272                                 pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff);
273                         }
274                 }
275         }
276
277         /* UI BSS List signal strength(in percentage),
278          * make it good looking, from 0~100.
279          */
280         if (is_cck_rate)
281                 pstats->signalstrength =
282                     (u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all));
283         else if (rf_rx_num != 0)
284                 pstats->signalstrength =
285                     (u8) (_rtl92ce_signal_scale_mapping
286                           (hw, total_rssi /= rf_rx_num));
287 }
288
289 static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
290                                                struct sk_buff *skb,
291                                                struct rtl_stats *pstats,
292                                                struct rx_desc_92c *pdesc,
293                                                struct rx_fwinfo_92c *p_drvinfo)
294 {
295         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
296         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
297
298         struct ieee80211_hdr *hdr;
299         u8 *tmp_buf;
300         u8 *praddr;
301         __le16 fc;
302         u16 type, c_fc;
303         bool packet_matchbssid, packet_toself, packet_beacon = false;
304
305         tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
306
307         hdr = (struct ieee80211_hdr *)tmp_buf;
308         fc = hdr->frame_control;
309         c_fc = le16_to_cpu(fc);
310         type = WLAN_FC_GET_TYPE(fc);
311         praddr = hdr->addr1;
312
313         packet_matchbssid =
314             ((IEEE80211_FTYPE_CTL != type) &&
315              ether_addr_equal(mac->bssid,
316                               (c_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
317                               (c_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
318                               hdr->addr3) &&
319              (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
320
321         packet_toself = packet_matchbssid &&
322              ether_addr_equal(praddr, rtlefuse->dev_addr);
323
324         if (ieee80211_is_beacon(fc))
325                 packet_beacon = true;
326
327         _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
328                                    packet_matchbssid, packet_toself,
329                                    packet_beacon);
330
331         rtl_process_phyinfo(hw, tmp_buf, pstats);
332 }
333
334 bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
335                            struct rtl_stats *stats,
336                            struct ieee80211_rx_status *rx_status,
337                            u8 *p_desc, struct sk_buff *skb)
338 {
339         struct rx_fwinfo_92c *p_drvinfo;
340         struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
341         struct ieee80211_hdr *hdr;
342         u32 phystatus = GET_RX_DESC_PHYST(pdesc);
343         stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
344         stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
345             RX_DRV_INFO_SIZE_UNIT;
346         stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
347         stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
348         stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
349         stats->hwerror = (stats->crc | stats->icv);
350         stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
351         stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
352         stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
353         stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
354         stats->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
355                                    && (GET_RX_DESC_FAGGR(pdesc) == 1));
356         stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
357         stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
358         stats->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
359
360         stats->is_cck = RX_HAL_IS_CCK_RATE(pdesc->rxmcs);
361
362         rx_status->freq = hw->conf.chandef.chan->center_freq;
363         rx_status->band = hw->conf.chandef.chan->band;
364
365         hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size
366                         + stats->rx_bufshift);
367
368         if (stats->crc)
369                 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
370
371         if (stats->rx_is40Mhzpacket)
372                 rx_status->bw = RATE_INFO_BW_40;
373
374         if (stats->is_ht)
375                 rx_status->encoding = RX_ENC_HT;
376
377         rx_status->flag |= RX_FLAG_MACTIME_START;
378
379         /* hw will set stats->decrypted true, if it finds the
380          * frame is open data frame or mgmt frame.
381          * So hw will not decryption robust managment frame
382          * for IEEE80211w but still set status->decrypted
383          * true, so here we should set it back to undecrypted
384          * for IEEE80211w frame, and mac80211 sw will help
385          * to decrypt it
386          */
387         if (stats->decrypted) {
388                 if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
389                     (ieee80211_has_protected(hdr->frame_control)))
390                         rx_status->flag &= ~RX_FLAG_DECRYPTED;
391                 else
392                         rx_status->flag |= RX_FLAG_DECRYPTED;
393         }
394         /* rate_idx: index of data rate into band's
395          * supported rates or MCS index if HT rates
396          * are use (RX_FLAG_HT)
397          * Notice: this is diff with windows define
398          */
399         rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht,
400                                                    false, stats->rate);
401
402         rx_status->mactime = stats->timestamp_low;
403         if (phystatus) {
404                 p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
405                                                      stats->rx_bufshift);
406
407                 _rtl92ce_translate_rx_signal_stuff(hw,
408                                                    skb, stats, pdesc,
409                                                    p_drvinfo);
410         }
411
412         /*rx_status->qual = stats->signal; */
413         rx_status->signal = stats->recvsignalpower + 10;
414
415         return true;
416 }
417
418 void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
419                           struct ieee80211_hdr *hdr, u8 *pdesc_tx,
420                           u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
421                           struct ieee80211_sta *sta,
422                           struct sk_buff *skb,
423                           u8 hw_queue, struct rtl_tcb_desc *tcb_desc)
424 {
425         struct rtl_priv *rtlpriv = rtl_priv(hw);
426         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
427         struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
428         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
429         bool defaultadapter = true;
430         u8 *pdesc = pdesc_tx;
431         u16 seq_number;
432         __le16 fc = hdr->frame_control;
433         u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue);
434         bool firstseg = ((hdr->seq_ctrl &
435                           cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
436
437         bool lastseg = ((hdr->frame_control &
438                          cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
439
440         dma_addr_t mapping = pci_map_single(rtlpci->pdev,
441                                             skb->data, skb->len,
442                                             PCI_DMA_TODEVICE);
443
444         u8 bw_40 = 0;
445
446         if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
447                 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
448                          "DMA mapping error\n");
449                 return;
450         }
451         rcu_read_lock();
452         sta = get_sta(hw, mac->vif, mac->bssid);
453         if (mac->opmode == NL80211_IFTYPE_STATION) {
454                 bw_40 = mac->bw_40;
455         } else if (mac->opmode == NL80211_IFTYPE_AP ||
456                    mac->opmode == NL80211_IFTYPE_ADHOC ||
457                    mac->opmode == NL80211_IFTYPE_MESH_POINT) {
458                 if (sta)
459                         bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
460         }
461
462         seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
463
464         rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
465
466         CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
467
468         if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
469                 firstseg = true;
470                 lastseg = true;
471         }
472         if (firstseg) {
473                 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
474
475                 SET_TX_DESC_TX_RATE(pdesc, tcb_desc->hw_rate);
476
477                 if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
478                         SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
479
480                 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
481                         SET_TX_DESC_AGG_BREAK(pdesc, 1);
482                         SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
483                 }
484                 SET_TX_DESC_SEQ(pdesc, seq_number);
485
486                 SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc->rts_enable &&
487                                                 !tcb_desc->
488                                                 cts_enable) ? 1 : 0));
489                 SET_TX_DESC_HW_RTS_ENABLE(pdesc,
490                                           ((tcb_desc->rts_enable
491                                             || tcb_desc->cts_enable) ? 1 : 0));
492                 SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc->cts_enable) ? 1 : 0));
493                 SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
494
495                 SET_TX_DESC_RTS_RATE(pdesc, tcb_desc->rts_rate);
496                 SET_TX_DESC_RTS_BW(pdesc, 0);
497                 SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc);
498                 SET_TX_DESC_RTS_SHORT(pdesc,
499                                       ((tcb_desc->rts_rate <= DESC_RATE54M) ?
500                                        (tcb_desc->rts_use_shortpreamble ? 1 : 0)
501                                        : (tcb_desc->rts_use_shortgi ? 1 : 0)));
502
503                 if (bw_40) {
504                         if (tcb_desc->packet_bw) {
505                                 SET_TX_DESC_DATA_BW(pdesc, 1);
506                                 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
507                         } else {
508                                 SET_TX_DESC_DATA_BW(pdesc, 0);
509                                 SET_TX_DESC_TX_SUB_CARRIER(pdesc,
510                                                  mac->cur_40_prime_sc);
511                         }
512                 } else {
513                         SET_TX_DESC_DATA_BW(pdesc, 0);
514                         SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
515                 }
516
517                 SET_TX_DESC_LINIP(pdesc, 0);
518                 SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
519
520                 if (sta) {
521                         u8 ampdu_density = sta->ht_cap.ampdu_density;
522                         SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
523                 }
524
525                 if (info->control.hw_key) {
526                         struct ieee80211_key_conf *keyconf =
527                             info->control.hw_key;
528
529                         switch (keyconf->cipher) {
530                         case WLAN_CIPHER_SUITE_WEP40:
531                         case WLAN_CIPHER_SUITE_WEP104:
532                         case WLAN_CIPHER_SUITE_TKIP:
533                                 SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
534                                 break;
535                         case WLAN_CIPHER_SUITE_CCMP:
536                                 SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
537                                 break;
538                         default:
539                                 SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
540                                 break;
541
542                         }
543                 }
544
545                 SET_TX_DESC_PKT_ID(pdesc, 0);
546                 SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
547
548                 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
549                 SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
550                 SET_TX_DESC_DISABLE_FB(pdesc, 0);
551                 SET_TX_DESC_USE_RATE(pdesc, tcb_desc->use_driver_rate ? 1 : 0);
552
553                 if (ieee80211_is_data_qos(fc)) {
554                         if (mac->rdg_en) {
555                                 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
556                                          "Enable RDG function\n");
557                                 SET_TX_DESC_RDG_ENABLE(pdesc, 1);
558                                 SET_TX_DESC_HTC(pdesc, 1);
559                         }
560                 }
561         }
562         rcu_read_unlock();
563
564         SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
565         SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
566
567         SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
568
569         SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
570
571         if (rtlpriv->dm.useramask) {
572                 SET_TX_DESC_RATE_ID(pdesc, tcb_desc->ratr_index);
573                 SET_TX_DESC_MACID(pdesc, tcb_desc->mac_id);
574         } else {
575                 SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc->ratr_index);
576                 SET_TX_DESC_MACID(pdesc, tcb_desc->ratr_index);
577         }
578
579         if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
580                 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
581                 SET_TX_DESC_PKT_ID(pdesc, 8);
582
583                 if (!defaultadapter)
584                         SET_TX_DESC_QOS(pdesc, 1);
585         }
586
587         SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
588
589         if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
590             is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
591                 SET_TX_DESC_BMC(pdesc, 1);
592         }
593
594         RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
595 }
596
597 void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
598                              u8 *pdesc, bool firstseg,
599                              bool lastseg, struct sk_buff *skb)
600 {
601         struct rtl_priv *rtlpriv = rtl_priv(hw);
602         struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
603         u8 fw_queue = QSLT_BEACON;
604
605         dma_addr_t mapping = pci_map_single(rtlpci->pdev,
606                                             skb->data, skb->len,
607                                             PCI_DMA_TODEVICE);
608
609         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
610         __le16 fc = hdr->frame_control;
611
612         if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
613                 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
614                          "DMA mapping error\n");
615                 return;
616         }
617         CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
618
619         if (firstseg)
620                 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
621
622         SET_TX_DESC_TX_RATE(pdesc, DESC_RATE1M);
623
624         SET_TX_DESC_SEQ(pdesc, 0);
625
626         SET_TX_DESC_LINIP(pdesc, 0);
627
628         SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
629
630         SET_TX_DESC_FIRST_SEG(pdesc, 1);
631         SET_TX_DESC_LAST_SEG(pdesc, 1);
632
633         SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
634
635         SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
636
637         SET_TX_DESC_RATE_ID(pdesc, 7);
638         SET_TX_DESC_MACID(pdesc, 0);
639
640         SET_TX_DESC_OWN(pdesc, 1);
641
642         SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len));
643
644         SET_TX_DESC_FIRST_SEG(pdesc, 1);
645         SET_TX_DESC_LAST_SEG(pdesc, 1);
646
647         SET_TX_DESC_OFFSET(pdesc, 0x20);
648
649         SET_TX_DESC_USE_RATE(pdesc, 1);
650
651         if (!ieee80211_is_data_qos(fc)) {
652                 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
653                 SET_TX_DESC_PKT_ID(pdesc, 8);
654         }
655
656         RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
657                       "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
658 }
659
660 void rtl92ce_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
661                       u8 desc_name, u8 *val)
662 {
663         if (istx) {
664                 switch (desc_name) {
665                 case HW_DESC_OWN:
666                         wmb();
667                         SET_TX_DESC_OWN(pdesc, 1);
668                         break;
669                 case HW_DESC_TX_NEXTDESC_ADDR:
670                         SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
671                         break;
672                 default:
673                         WARN_ONCE(true, "rtl8192ce: ERR txdesc :%d not processed\n",
674                                   desc_name);
675                         break;
676                 }
677         } else {
678                 switch (desc_name) {
679                 case HW_DESC_RXOWN:
680                         wmb();
681                         SET_RX_DESC_OWN(pdesc, 1);
682                         break;
683                 case HW_DESC_RXBUFF_ADDR:
684                         SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
685                         break;
686                 case HW_DESC_RXPKT_LEN:
687                         SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
688                         break;
689                 case HW_DESC_RXERO:
690                         SET_RX_DESC_EOR(pdesc, 1);
691                         break;
692                 default:
693                         WARN_ONCE(true, "rtl8192ce: ERR rxdesc :%d not processed\n",
694                                   desc_name);
695                         break;
696                 }
697         }
698 }
699
700 u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
701 {
702         u32 ret = 0;
703
704         if (istx) {
705                 switch (desc_name) {
706                 case HW_DESC_OWN:
707                         ret = GET_TX_DESC_OWN(p_desc);
708                         break;
709                 case HW_DESC_TXBUFF_ADDR:
710                         ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
711                         break;
712                 default:
713                         WARN_ONCE(true, "rtl8192ce: ERR txdesc :%d not processed\n",
714                                   desc_name);
715                         break;
716                 }
717         } else {
718                 switch (desc_name) {
719                 case HW_DESC_OWN:
720                         ret = GET_RX_DESC_OWN(p_desc);
721                         break;
722                 case HW_DESC_RXPKT_LEN:
723                         ret = GET_RX_DESC_PKT_LEN(p_desc);
724                         break;
725                 case HW_DESC_RXBUFF_ADDR:
726                         ret = GET_RX_DESC_BUFF_ADDR(p_desc);
727                         break;
728                 default:
729                         WARN_ONCE(true, "rtl8192ce: ERR rxdesc :%d not processed\n",
730                                   desc_name);
731                         break;
732                 }
733         }
734         return ret;
735 }
736
737 bool rtl92ce_is_tx_desc_closed(struct ieee80211_hw *hw,
738                                u8 hw_queue, u16 index)
739 {
740         struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
741         struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
742         u8 *entry = (u8 *)(&ring->desc[ring->idx]);
743         u8 own = (u8)rtl92ce_get_desc(entry, true, HW_DESC_OWN);
744
745         /*beacon packet will only use the first
746          *descriptor defautly,and the own may not
747          *be cleared by the hardware
748          */
749         if (own)
750                 return false;
751         return true;
752 }
753
754 void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
755 {
756         struct rtl_priv *rtlpriv = rtl_priv(hw);
757         if (hw_queue == BEACON_QUEUE) {
758                 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
759         } else {
760                 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
761                                BIT(0) << (hw_queue));
762         }
763 }
764