1 /******************************************************************************
3 * Copyright(c) 2009-2010 Realtek Corporation.
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.
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
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
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
26 * Larry Finger <Larry.Finger@lwfinger.net>
28 *****************************************************************************/
39 static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(u16 fc,
43 enum rtl_desc_qsel qsel;
45 if (unlikely(ieee80211_is_beacon(fc))) {
50 if (ieee80211_is_mgmt(fc)) {
70 RT_ASSERT(false, ("BE queue, skb_queue:%d,"
71 " set qsel = 0x%X\n", skb_queue, QSLT_BE));
77 static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu)
90 case DESC92C_RATE5_5M:
102 case DESC92C_RATE12M:
105 case DESC92C_RATE18M:
108 case DESC92C_RATE24M:
111 case DESC92C_RATE36M:
114 case DESC92C_RATE48M:
117 case DESC92C_RATE54M:
138 case DESC92C_RATE5_5M:
141 case DESC92C_RATE11M:
150 case DESC92C_RATE12M:
153 case DESC92C_RATE18M:
156 case DESC92C_RATE24M:
159 case DESC92C_RATE36M:
162 case DESC92C_RATE48M:
165 case DESC92C_RATE54M:
175 static u8 _rtl92c_query_rxpwrpercentage(char antpower)
177 if ((antpower <= -100) || (antpower >= 20))
179 else if (antpower >= 0)
182 return 100 + antpower;
185 static u8 _rtl92c_evm_db_to_percentage(char value)
196 ret_val = 0 - ret_val;
205 static long _rtl92ce_translate_todbm(struct ieee80211_hw *hw,
206 u8 signal_strength_index)
210 signal_power = (long)((signal_strength_index + 1) >> 1);
215 static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw,
220 if (currsig >= 61 && currsig <= 100)
221 retsig = 90 + ((currsig - 60) / 4);
222 else if (currsig >= 41 && currsig <= 60)
223 retsig = 78 + ((currsig - 40) / 2);
224 else if (currsig >= 31 && currsig <= 40)
225 retsig = 66 + (currsig - 30);
226 else if (currsig >= 21 && currsig <= 30)
227 retsig = 54 + (currsig - 20);
228 else if (currsig >= 5 && currsig <= 20)
229 retsig = 42 + (((currsig - 5) * 2) / 3);
230 else if (currsig == 4)
232 else if (currsig == 3)
234 else if (currsig == 2)
236 else if (currsig == 1)
244 static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
245 struct rtl_stats *pstats,
246 struct rx_desc_92c *pdesc,
247 struct rx_fwinfo_92c *p_drvinfo,
248 bool bpacket_match_bssid,
250 bool b_packet_beacon)
252 struct rtl_priv *rtlpriv = rtl_priv(hw);
253 struct phy_sts_cck_8192s_t *cck_buf;
254 s8 rx_pwr_all, rx_pwr[4];
255 u8 rf_rx_num, evm, pwdb_all;
256 u8 i, max_spatial_stream;
257 u32 rssi, total_rssi;
260 is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
261 pstats->b_packet_matchbssid = bpacket_match_bssid;
262 pstats->b_packet_toself = bpacket_toself;
263 pstats->b_is_cck = is_cck_rate;
264 pstats->b_packet_beacon = b_packet_beacon;
265 pstats->b_is_cck = is_cck_rate;
266 pstats->rx_mimo_signalquality[0] = -1;
267 pstats->rx_mimo_signalquality[1] = -1;
270 u8 report, cck_highpwr;
271 cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
273 cck_highpwr = (u8) rtl_get_bbreg(hw,
274 RFPGA0_XA_HSSIPARAMETER2,
277 u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
278 report = cck_buf->cck_agc_rpt & 0xc0;
279 report = report >> 6;
282 rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
285 rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
288 rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
291 rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
295 u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
296 report = p_drvinfo->cfosho[0] & 0x60;
297 report = report >> 5;
300 rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
303 rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
306 rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
309 rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
314 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
315 pstats->rx_pwdb_all = pwdb_all;
316 pstats->recvsignalpower = rx_pwr_all;
318 if (bpacket_match_bssid) {
320 if (pstats->rx_pwdb_all > 40)
323 sq = cck_buf->sq_rpt;
329 sq = ((64 - sq) * 100) / 44;
332 pstats->signalquality = sq;
333 pstats->rx_mimo_signalquality[0] = sq;
334 pstats->rx_mimo_signalquality[1] = -1;
337 rtlpriv->dm.brfpath_rxenable[0] =
338 rtlpriv->dm.brfpath_rxenable[1] = true;
339 for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
340 if (rtlpriv->dm.brfpath_rxenable[i])
344 ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
345 rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
347 rtlpriv->stats.rx_snr_db[i] =
348 (long)(p_drvinfo->rxsnr[i] / 2);
350 if (bpacket_match_bssid)
351 pstats->rx_mimo_signalstrength[i] = (u8) rssi;
354 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
355 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
356 pstats->rx_pwdb_all = pwdb_all;
357 pstats->rxpower = rx_pwr_all;
358 pstats->recvsignalpower = rx_pwr_all;
360 if (pdesc->rxht && pdesc->rxmcs >= DESC92C_RATEMCS8 &&
361 pdesc->rxmcs <= DESC92C_RATEMCS15)
362 max_spatial_stream = 2;
364 max_spatial_stream = 1;
366 for (i = 0; i < max_spatial_stream; i++) {
367 evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
369 if (bpacket_match_bssid) {
371 pstats->signalquality =
373 pstats->rx_mimo_signalquality[i] =
380 pstats->signalstrength =
381 (u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all));
382 else if (rf_rx_num != 0)
383 pstats->signalstrength =
384 (u8) (_rtl92ce_signal_scale_mapping
385 (hw, total_rssi /= rf_rx_num));
388 static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw,
389 struct rtl_stats *pstats)
391 struct rtl_priv *rtlpriv = rtl_priv(hw);
392 struct rtl_phy *rtlphy = &(rtlpriv->phy);
394 u32 last_rssi, tmpval;
396 if (pstats->b_packet_toself || pstats->b_packet_beacon) {
397 rtlpriv->stats.rssi_calculate_cnt++;
399 if (rtlpriv->stats.ui_rssi.total_num++ >=
400 PHY_RSSI_SLID_WIN_MAX) {
401 rtlpriv->stats.ui_rssi.total_num =
402 PHY_RSSI_SLID_WIN_MAX;
404 rtlpriv->stats.ui_rssi.elements[rtlpriv->
405 stats.ui_rssi.index];
406 rtlpriv->stats.ui_rssi.total_val -= last_rssi;
409 rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
410 rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.
412 pstats->signalstrength;
414 if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
415 rtlpriv->stats.ui_rssi.index = 0;
417 tmpval = rtlpriv->stats.ui_rssi.total_val /
418 rtlpriv->stats.ui_rssi.total_num;
419 rtlpriv->stats.signal_strength =
420 _rtl92ce_translate_todbm(hw, (u8) tmpval);
421 pstats->rssi = rtlpriv->stats.signal_strength;
424 if (!pstats->b_is_cck && pstats->b_packet_toself) {
425 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
428 if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath))
431 if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
432 rtlpriv->stats.rx_rssi_percentage[rfpath] =
433 pstats->rx_mimo_signalstrength[rfpath];
437 if (pstats->rx_mimo_signalstrength[rfpath] >
438 rtlpriv->stats.rx_rssi_percentage[rfpath]) {
439 rtlpriv->stats.rx_rssi_percentage[rfpath] =
441 rx_rssi_percentage[rfpath] *
442 (RX_SMOOTH_FACTOR - 1)) +
443 (pstats->rx_mimo_signalstrength[rfpath])) /
446 rtlpriv->stats.rx_rssi_percentage[rfpath] =
447 rtlpriv->stats.rx_rssi_percentage[rfpath] +
450 rtlpriv->stats.rx_rssi_percentage[rfpath] =
452 rx_rssi_percentage[rfpath] *
453 (RX_SMOOTH_FACTOR - 1)) +
454 (pstats->rx_mimo_signalstrength[rfpath])) /
462 static void _rtl92ce_update_rxsignalstatistics(struct ieee80211_hw *hw,
463 struct rtl_stats *pstats)
465 struct rtl_priv *rtlpriv = rtl_priv(hw);
468 if (rtlpriv->stats.recv_signal_power == 0)
469 rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
471 if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
474 else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
477 rtlpriv->stats.recv_signal_power =
478 (rtlpriv->stats.recv_signal_power * 5 +
479 pstats->recvsignalpower + weighting) / 6;
482 static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw,
483 struct rtl_stats *pstats)
485 struct rtl_priv *rtlpriv = rtl_priv(hw);
486 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
487 long undecorated_smoothed_pwdb;
489 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
492 undecorated_smoothed_pwdb =
493 rtlpriv->dm.undecorated_smoothed_pwdb;
496 if (pstats->b_packet_toself || pstats->b_packet_beacon) {
497 if (undecorated_smoothed_pwdb < 0)
498 undecorated_smoothed_pwdb = pstats->rx_pwdb_all;
500 if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) {
501 undecorated_smoothed_pwdb =
502 (((undecorated_smoothed_pwdb) *
503 (RX_SMOOTH_FACTOR - 1)) +
504 (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
506 undecorated_smoothed_pwdb = undecorated_smoothed_pwdb
509 undecorated_smoothed_pwdb =
510 (((undecorated_smoothed_pwdb) *
511 (RX_SMOOTH_FACTOR - 1)) +
512 (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
515 rtlpriv->dm.undecorated_smoothed_pwdb =
516 undecorated_smoothed_pwdb;
517 _rtl92ce_update_rxsignalstatistics(hw, pstats);
521 static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw,
522 struct rtl_stats *pstats)
524 struct rtl_priv *rtlpriv = rtl_priv(hw);
525 u32 last_evm, n_spatialstream, tmpval;
527 if (pstats->signalquality != 0) {
528 if (pstats->b_packet_toself || pstats->b_packet_beacon) {
530 if (rtlpriv->stats.ui_link_quality.total_num++ >=
531 PHY_LINKQUALITY_SLID_WIN_MAX) {
532 rtlpriv->stats.ui_link_quality.total_num =
533 PHY_LINKQUALITY_SLID_WIN_MAX;
536 ui_link_quality.elements[rtlpriv->
537 stats.ui_link_quality.
539 rtlpriv->stats.ui_link_quality.total_val -=
543 rtlpriv->stats.ui_link_quality.total_val +=
544 pstats->signalquality;
545 rtlpriv->stats.ui_link_quality.elements[rtlpriv->stats.
548 pstats->signalquality;
550 if (rtlpriv->stats.ui_link_quality.index >=
551 PHY_LINKQUALITY_SLID_WIN_MAX)
552 rtlpriv->stats.ui_link_quality.index = 0;
554 tmpval = rtlpriv->stats.ui_link_quality.total_val /
555 rtlpriv->stats.ui_link_quality.total_num;
556 rtlpriv->stats.signal_quality = tmpval;
558 rtlpriv->stats.last_sigstrength_inpercent = tmpval;
560 for (n_spatialstream = 0; n_spatialstream < 2;
563 rx_mimo_signalquality[n_spatialstream] !=
566 rx_evm_percentage[n_spatialstream]
571 pstats->rx_mimo_signalquality
576 rx_evm_percentage[n_spatialstream] =
578 stats.rx_evm_percentage
580 (RX_SMOOTH_FACTOR - 1)) +
582 rx_mimo_signalquality
583 [n_spatialstream] * 1)) /
593 static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw,
595 struct rtl_stats *pcurrent_stats)
598 if (!pcurrent_stats->b_packet_matchbssid &&
599 !pcurrent_stats->b_packet_beacon)
602 _rtl92ce_process_ui_rssi(hw, pcurrent_stats);
603 _rtl92ce_process_pwdb(hw, pcurrent_stats);
604 _rtl92ce_process_ui_link_quality(hw, pcurrent_stats);
607 static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
609 struct rtl_stats *pstats,
610 struct rx_desc_92c *pdesc,
611 struct rx_fwinfo_92c *p_drvinfo)
613 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
614 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
616 struct ieee80211_hdr *hdr;
621 bool b_packet_matchbssid, b_packet_toself, b_packet_beacon;
623 tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
625 hdr = (struct ieee80211_hdr *)tmp_buf;
626 fc = le16_to_cpu(hdr->frame_control);
627 type = WLAN_FC_GET_TYPE(fc);
631 b_packet_matchbssid =
632 ((IEEE80211_FTYPE_CTL != type) &&
633 (!compare_ether_addr(mac->bssid,
634 (fc & IEEE80211_FCTL_TODS) ?
635 hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ?
636 hdr->addr2 : hdr->addr3)) &&
637 (!pstats->b_hwerror) && (!pstats->b_crc) && (!pstats->b_icv));
639 b_packet_toself = b_packet_matchbssid &&
640 (!compare_ether_addr(praddr, rtlefuse->dev_addr));
642 if (ieee80211_is_beacon(fc))
643 b_packet_beacon = true;
645 _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
646 b_packet_matchbssid, b_packet_toself,
649 _rtl92ce_process_phyinfo(hw, tmp_buf, pstats);
652 bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
653 struct rtl_stats *stats,
654 struct ieee80211_rx_status *rx_status,
655 u8 *p_desc, struct sk_buff *skb)
657 struct rx_fwinfo_92c *p_drvinfo;
658 struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
660 u32 phystatus = GET_RX_DESC_PHYST(pdesc);
661 stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
662 stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
663 RX_DRV_INFO_SIZE_UNIT;
664 stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
665 stats->b_icv = (u16) GET_RX_DESC_ICV(pdesc);
666 stats->b_crc = (u16) GET_RX_DESC_CRC32(pdesc);
667 stats->b_hwerror = (stats->b_crc | stats->b_icv);
668 stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
669 stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
670 stats->b_shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
671 stats->b_isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
672 stats->b_isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
673 && (GET_RX_DESC_FAGGR(pdesc) == 1));
674 stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
675 stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
677 rx_status->freq = hw->conf.channel->center_freq;
678 rx_status->band = hw->conf.channel->band;
680 if (GET_RX_DESC_CRC32(pdesc))
681 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
683 if (!GET_RX_DESC_SWDEC(pdesc))
684 rx_status->flag |= RX_FLAG_DECRYPTED;
686 if (GET_RX_DESC_BW(pdesc))
687 rx_status->flag |= RX_FLAG_40MHZ;
689 if (GET_RX_DESC_RXHT(pdesc))
690 rx_status->flag |= RX_FLAG_HT;
692 rx_status->flag |= RX_FLAG_TSFT;
694 if (stats->decrypted)
695 rx_status->flag |= RX_FLAG_DECRYPTED;
697 rx_status->rate_idx = _rtl92ce_rate_mapping((bool)
698 GET_RX_DESC_RXHT(pdesc),
700 GET_RX_DESC_RXMCS(pdesc),
702 GET_RX_DESC_PAGGR(pdesc));
704 rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
705 if (phystatus == true) {
706 p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
709 _rtl92ce_translate_rx_signal_stuff(hw,
714 /*rx_status->qual = stats->signal; */
715 rx_status->signal = stats->rssi + 10;
716 /*rx_status->noise = -stats->noise; */
721 void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
722 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
723 struct ieee80211_tx_info *info, struct sk_buff *skb,
724 unsigned int queue_index)
726 struct rtl_priv *rtlpriv = rtl_priv(hw);
727 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
728 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
729 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
730 bool b_defaultadapter = true;
732 struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid);
734 u8 *pdesc = (u8 *) pdesc_tx;
735 struct rtl_tcb_desc tcb_desc;
736 u8 *qc = ieee80211_get_qos_ctl(hdr);
737 u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
739 u16 fc = le16_to_cpu(hdr->frame_control);
740 u8 rate_flag = info->control.rates[0].flags;
742 enum rtl_desc_qsel fw_qsel =
743 _rtl92ce_map_hwqueue_to_fwqueue(le16_to_cpu(hdr->frame_control),
746 bool b_firstseg = ((hdr->seq_ctrl &
747 cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
749 bool b_lastseg = ((hdr->frame_control &
750 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
752 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
756 seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
758 rtl_get_tcb_desc(hw, info, skb, &tcb_desc);
760 CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
763 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
765 SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate);
767 if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble)
768 SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
770 if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
771 info->flags & IEEE80211_TX_CTL_AMPDU) {
772 SET_TX_DESC_AGG_BREAK(pdesc, 1);
773 SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
775 SET_TX_DESC_SEQ(pdesc, seq_number);
777 SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.b_rts_enable &&
779 b_cts_enable) ? 1 : 0));
780 SET_TX_DESC_HW_RTS_ENABLE(pdesc,
781 ((tcb_desc.b_rts_enable
782 || tcb_desc.b_cts_enable) ? 1 : 0));
783 SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.b_cts_enable) ? 1 : 0));
784 SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.b_rts_stbc) ? 1 : 0));
786 SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate);
787 SET_TX_DESC_RTS_BW(pdesc, 0);
788 SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc);
789 SET_TX_DESC_RTS_SHORT(pdesc,
790 ((tcb_desc.rts_rate <= DESC92C_RATE54M) ?
791 (tcb_desc.b_rts_use_shortpreamble ? 1 : 0)
792 : (tcb_desc.b_rts_use_shortgi ? 1 : 0)));
795 if (tcb_desc.b_packet_bw) {
796 SET_TX_DESC_DATA_BW(pdesc, 1);
797 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
799 SET_TX_DESC_DATA_BW(pdesc, 0);
801 if (rate_flag & IEEE80211_TX_RC_DUP_DATA) {
802 SET_TX_DESC_TX_SUB_CARRIER(pdesc,
803 mac->cur_40_prime_sc);
807 SET_TX_DESC_DATA_BW(pdesc, 0);
808 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
811 SET_TX_DESC_LINIP(pdesc, 0);
812 SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
815 u8 ampdu_density = sta->ht_cap.ampdu_density;
816 SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
819 if (info->control.hw_key) {
820 struct ieee80211_key_conf *keyconf =
821 info->control.hw_key;
823 switch (keyconf->cipher) {
824 case WLAN_CIPHER_SUITE_WEP40:
825 case WLAN_CIPHER_SUITE_WEP104:
826 case WLAN_CIPHER_SUITE_TKIP:
827 SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
829 case WLAN_CIPHER_SUITE_CCMP:
830 SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
833 SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
839 SET_TX_DESC_PKT_ID(pdesc, 0);
840 SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
842 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
843 SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
844 SET_TX_DESC_DISABLE_FB(pdesc, 0);
845 SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0);
847 if (ieee80211_is_data_qos(fc)) {
849 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
850 ("Enable RDG function.\n"));
851 SET_TX_DESC_RDG_ENABLE(pdesc, 1);
852 SET_TX_DESC_HTC(pdesc, 1);
857 SET_TX_DESC_FIRST_SEG(pdesc, (b_firstseg ? 1 : 0));
858 SET_TX_DESC_LAST_SEG(pdesc, (b_lastseg ? 1 : 0));
860 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
862 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
864 if (rtlpriv->dm.b_useramask) {
865 SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index);
866 SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id);
868 SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index);
869 SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index);
872 if ((!ieee80211_is_data_qos(fc)) && ppsc->b_leisure_ps &&
873 ppsc->b_fwctrl_lps) {
874 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
875 SET_TX_DESC_PKT_ID(pdesc, 8);
877 if (!b_defaultadapter)
878 SET_TX_DESC_QOS(pdesc, 1);
881 SET_TX_DESC_MORE_FRAG(pdesc, (b_lastseg ? 0 : 1));
883 if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
884 is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
885 SET_TX_DESC_BMC(pdesc, 1);
888 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
891 void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
892 u8 *pdesc, bool b_firstseg,
893 bool b_lastseg, struct sk_buff *skb)
895 struct rtl_priv *rtlpriv = rtl_priv(hw);
896 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
897 u8 fw_queue = QSLT_BEACON;
899 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
903 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
904 u16 fc = le16_to_cpu(hdr->frame_control);
906 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
909 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
911 SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
913 SET_TX_DESC_SEQ(pdesc, 0);
915 SET_TX_DESC_LINIP(pdesc, 0);
917 SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
919 SET_TX_DESC_FIRST_SEG(pdesc, 1);
920 SET_TX_DESC_LAST_SEG(pdesc, 1);
922 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
924 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
926 SET_TX_DESC_RATE_ID(pdesc, 7);
927 SET_TX_DESC_MACID(pdesc, 0);
929 SET_TX_DESC_OWN(pdesc, 1);
931 SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
933 SET_TX_DESC_FIRST_SEG(pdesc, 1);
934 SET_TX_DESC_LAST_SEG(pdesc, 1);
936 SET_TX_DESC_OFFSET(pdesc, 0x20);
938 SET_TX_DESC_USE_RATE(pdesc, 1);
940 if (!ieee80211_is_data_qos(fc)) {
941 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
942 SET_TX_DESC_PKT_ID(pdesc, 8);
945 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
946 "H2C Tx Cmd Content\n",
947 pdesc, TX_DESC_SIZE);
950 void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
955 SET_TX_DESC_OWN(pdesc, 1);
957 case HW_DESC_TX_NEXTDESC_ADDR:
958 SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
961 RT_ASSERT(false, ("ERR txdesc :%d"
962 " not process\n", desc_name));
968 SET_RX_DESC_OWN(pdesc, 1);
970 case HW_DESC_RXBUFF_ADDR:
971 SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
973 case HW_DESC_RXPKT_LEN:
974 SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
977 SET_RX_DESC_EOR(pdesc, 1);
980 RT_ASSERT(false, ("ERR rxdesc :%d "
981 "not process\n", desc_name));
987 u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
994 ret = GET_TX_DESC_OWN(p_desc);
996 case HW_DESC_TXBUFF_ADDR:
997 ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
1000 RT_ASSERT(false, ("ERR txdesc :%d "
1001 "not process\n", desc_name));
1005 struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
1006 switch (desc_name) {
1008 ret = GET_RX_DESC_OWN(pdesc);
1010 case HW_DESC_RXPKT_LEN:
1011 ret = GET_RX_DESC_PKT_LEN(pdesc);
1014 RT_ASSERT(false, ("ERR rxdesc :%d "
1015 "not process\n", desc_name));
1022 void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue)
1024 struct rtl_priv *rtlpriv = rtl_priv(hw);
1025 if (hw_queue == BEACON_QUEUE) {
1026 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
1028 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
1029 BIT(0) << (hw_queue));