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