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(__le16 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 packet_match_bssid,
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 evm, pwdb_all, rf_rx_num = 0;
256 u8 i, max_spatial_stream;
257 u32 rssi, total_rssi = 0;
260 is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
261 pstats->packet_matchbssid = packet_match_bssid;
262 pstats->packet_toself = packet_toself;
263 pstats->is_cck = is_cck_rate;
264 pstats->packet_beacon = packet_beacon;
265 pstats->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 (packet_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.rfpath_rxenable[0] =
338 rtlpriv->dm.rfpath_rxenable[1] = true;
339 for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
340 if (rtlpriv->dm.rfpath_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 (packet_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 (packet_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->packet_toself || pstats->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->is_cck && pstats->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->packet_toself || pstats->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->packet_toself || pstats->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->packet_matchbssid &&
599 !pcurrent_stats->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;
622 bool packet_matchbssid, packet_toself, packet_beacon;
624 tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
626 hdr = (struct ieee80211_hdr *)tmp_buf;
627 fc = hdr->frame_control;
628 c_fc = le16_to_cpu(fc);
629 type = WLAN_FC_GET_TYPE(fc);
634 ((IEEE80211_FTYPE_CTL != type) &&
635 (!compare_ether_addr(mac->bssid,
636 (c_fc & IEEE80211_FCTL_TODS) ?
637 hdr->addr1 : (c_fc & IEEE80211_FCTL_FROMDS) ?
638 hdr->addr2 : hdr->addr3)) &&
639 (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
641 packet_toself = packet_matchbssid &&
642 (!compare_ether_addr(praddr, rtlefuse->dev_addr));
644 if (ieee80211_is_beacon(fc))
645 packet_beacon = true;
647 _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
648 packet_matchbssid, packet_toself,
651 _rtl92ce_process_phyinfo(hw, tmp_buf, pstats);
654 bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
655 struct rtl_stats *stats,
656 struct ieee80211_rx_status *rx_status,
657 u8 *p_desc, struct sk_buff *skb)
659 struct rx_fwinfo_92c *p_drvinfo;
660 struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
662 u32 phystatus = GET_RX_DESC_PHYST(pdesc);
663 stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
664 stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
665 RX_DRV_INFO_SIZE_UNIT;
666 stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
667 stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
668 stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
669 stats->hwerror = (stats->crc | stats->icv);
670 stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
671 stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
672 stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
673 stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
674 stats->isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
675 && (GET_RX_DESC_FAGGR(pdesc) == 1));
676 stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
677 stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
679 rx_status->freq = hw->conf.channel->center_freq;
680 rx_status->band = hw->conf.channel->band;
682 if (GET_RX_DESC_CRC32(pdesc))
683 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
685 if (!GET_RX_DESC_SWDEC(pdesc))
686 rx_status->flag |= RX_FLAG_DECRYPTED;
688 if (GET_RX_DESC_BW(pdesc))
689 rx_status->flag |= RX_FLAG_40MHZ;
691 if (GET_RX_DESC_RXHT(pdesc))
692 rx_status->flag |= RX_FLAG_HT;
694 rx_status->flag |= RX_FLAG_MACTIME_MPDU;
696 if (stats->decrypted)
697 rx_status->flag |= RX_FLAG_DECRYPTED;
699 rx_status->rate_idx = _rtl92ce_rate_mapping((bool)
700 GET_RX_DESC_RXHT(pdesc),
702 GET_RX_DESC_RXMCS(pdesc),
704 GET_RX_DESC_PAGGR(pdesc));
706 rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
707 if (phystatus == true) {
708 p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
711 _rtl92ce_translate_rx_signal_stuff(hw,
716 /*rx_status->qual = stats->signal; */
717 rx_status->signal = stats->rssi + 10;
718 /*rx_status->noise = -stats->noise; */
723 void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
724 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
725 struct ieee80211_tx_info *info, struct sk_buff *skb,
726 unsigned int queue_index)
728 struct rtl_priv *rtlpriv = rtl_priv(hw);
729 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
730 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
731 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
732 bool defaultadapter = true;
733 struct ieee80211_sta *sta;
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 __le16 fc = 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(fc, queue_index);
745 bool firstseg = ((hdr->seq_ctrl &
746 cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
748 bool lastseg = ((hdr->frame_control &
749 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
751 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
755 seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
757 rtl_get_tcb_desc(hw, info, skb, &tcb_desc);
759 CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
762 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
764 SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate);
766 if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble)
767 SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
769 if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
770 info->flags & IEEE80211_TX_CTL_AMPDU) {
771 SET_TX_DESC_AGG_BREAK(pdesc, 1);
772 SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
774 SET_TX_DESC_SEQ(pdesc, seq_number);
776 SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.rts_enable &&
778 cts_enable) ? 1 : 0));
779 SET_TX_DESC_HW_RTS_ENABLE(pdesc,
780 ((tcb_desc.rts_enable
781 || tcb_desc.cts_enable) ? 1 : 0));
782 SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.cts_enable) ? 1 : 0));
783 SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.rts_stbc) ? 1 : 0));
785 SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate);
786 SET_TX_DESC_RTS_BW(pdesc, 0);
787 SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc);
788 SET_TX_DESC_RTS_SHORT(pdesc,
789 ((tcb_desc.rts_rate <= DESC92C_RATE54M) ?
790 (tcb_desc.rts_use_shortpreamble ? 1 : 0)
791 : (tcb_desc.rts_use_shortgi ? 1 : 0)));
794 if (tcb_desc.packet_bw) {
795 SET_TX_DESC_DATA_BW(pdesc, 1);
796 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
798 SET_TX_DESC_DATA_BW(pdesc, 0);
800 if (rate_flag & IEEE80211_TX_RC_DUP_DATA) {
801 SET_TX_DESC_TX_SUB_CARRIER(pdesc,
802 mac->cur_40_prime_sc);
806 SET_TX_DESC_DATA_BW(pdesc, 0);
807 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
810 SET_TX_DESC_LINIP(pdesc, 0);
811 SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
814 sta = ieee80211_find_sta(mac->vif, mac->bssid);
816 u8 ampdu_density = sta->ht_cap.ampdu_density;
817 SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
821 if (info->control.hw_key) {
822 struct ieee80211_key_conf *keyconf =
823 info->control.hw_key;
825 switch (keyconf->cipher) {
826 case WLAN_CIPHER_SUITE_WEP40:
827 case WLAN_CIPHER_SUITE_WEP104:
828 case WLAN_CIPHER_SUITE_TKIP:
829 SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
831 case WLAN_CIPHER_SUITE_CCMP:
832 SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
835 SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
841 SET_TX_DESC_PKT_ID(pdesc, 0);
842 SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
844 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
845 SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
846 SET_TX_DESC_DISABLE_FB(pdesc, 0);
847 SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0);
849 if (ieee80211_is_data_qos(fc)) {
851 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
852 ("Enable RDG function.\n"));
853 SET_TX_DESC_RDG_ENABLE(pdesc, 1);
854 SET_TX_DESC_HTC(pdesc, 1);
859 SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
860 SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
862 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
864 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
866 if (rtlpriv->dm.useramask) {
867 SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index);
868 SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id);
870 SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index);
871 SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index);
874 if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps &&
876 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
877 SET_TX_DESC_PKT_ID(pdesc, 8);
880 SET_TX_DESC_QOS(pdesc, 1);
883 SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
885 if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
886 is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
887 SET_TX_DESC_BMC(pdesc, 1);
890 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
893 void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
894 u8 *pdesc, bool firstseg,
895 bool lastseg, struct sk_buff *skb)
897 struct rtl_priv *rtlpriv = rtl_priv(hw);
898 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
899 u8 fw_queue = QSLT_BEACON;
901 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
905 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
906 __le16 fc = hdr->frame_control;
908 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
911 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
913 SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
915 SET_TX_DESC_SEQ(pdesc, 0);
917 SET_TX_DESC_LINIP(pdesc, 0);
919 SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
921 SET_TX_DESC_FIRST_SEG(pdesc, 1);
922 SET_TX_DESC_LAST_SEG(pdesc, 1);
924 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
926 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
928 SET_TX_DESC_RATE_ID(pdesc, 7);
929 SET_TX_DESC_MACID(pdesc, 0);
931 SET_TX_DESC_OWN(pdesc, 1);
933 SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
935 SET_TX_DESC_FIRST_SEG(pdesc, 1);
936 SET_TX_DESC_LAST_SEG(pdesc, 1);
938 SET_TX_DESC_OFFSET(pdesc, 0x20);
940 SET_TX_DESC_USE_RATE(pdesc, 1);
942 if (!ieee80211_is_data_qos(fc)) {
943 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
944 SET_TX_DESC_PKT_ID(pdesc, 8);
947 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
948 "H2C Tx Cmd Content\n",
949 pdesc, TX_DESC_SIZE);
952 void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
957 SET_TX_DESC_OWN(pdesc, 1);
959 case HW_DESC_TX_NEXTDESC_ADDR:
960 SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
963 RT_ASSERT(false, ("ERR txdesc :%d"
964 " not process\n", desc_name));
970 SET_RX_DESC_OWN(pdesc, 1);
972 case HW_DESC_RXBUFF_ADDR:
973 SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
975 case HW_DESC_RXPKT_LEN:
976 SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
979 SET_RX_DESC_EOR(pdesc, 1);
982 RT_ASSERT(false, ("ERR rxdesc :%d "
983 "not process\n", desc_name));
989 u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
996 ret = GET_TX_DESC_OWN(p_desc);
998 case HW_DESC_TXBUFF_ADDR:
999 ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
1002 RT_ASSERT(false, ("ERR txdesc :%d "
1003 "not process\n", desc_name));
1007 struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
1008 switch (desc_name) {
1010 ret = GET_RX_DESC_OWN(pdesc);
1012 case HW_DESC_RXPKT_LEN:
1013 ret = GET_RX_DESC_PKT_LEN(pdesc);
1016 RT_ASSERT(false, ("ERR rxdesc :%d "
1017 "not process\n", desc_name));
1024 void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue)
1026 struct rtl_priv *rtlpriv = rtl_priv(hw);
1027 if (hw_queue == BEACON_QUEUE) {
1028 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
1030 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
1031 BIT(0) << (hw_queue));
1035 bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
1036 struct sk_buff *skb)
1038 struct rtl_priv *rtlpriv = rtl_priv(hw);
1039 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1040 struct rtl8192_tx_ring *ring;
1041 struct rtl_tx_desc *pdesc;
1043 unsigned long flags;
1044 struct sk_buff *pskb = NULL;
1046 ring = &rtlpci->tx_ring[BEACON_QUEUE];
1048 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
1050 pskb = __skb_dequeue(&ring->queue);
1054 pdesc = &ring->desc[0];
1055 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
1057 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
1059 __skb_queue_tail(&ring->queue, skb);
1061 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
1063 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);