cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

trx.c (18534B)


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