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->bw = RATE_INFO_BW_40; 321 322 if (status->is_ht) 323 rx_status->encoding = RX_ENC_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\n"); 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\n"); 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 WARN_ONCE(true, "rtl8723ae: ERR txdesc :%d not processed\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 WARN_ONCE(true, "rtl8723ae: ERR rxdesc :%d not processed\n", 640 desc_name); 641 break; 642 } 643 } 644 } 645 646 u64 rtl8723e_get_desc(struct ieee80211_hw *hw, 647 u8 *pdesc, bool istx, u8 desc_name) 648 { 649 u32 ret = 0; 650 651 if (istx == true) { 652 switch (desc_name) { 653 case HW_DESC_OWN: 654 ret = GET_TX_DESC_OWN(pdesc); 655 break; 656 case HW_DESC_TXBUFF_ADDR: 657 ret = GET_TX_DESC_TX_BUFFER_ADDRESS(pdesc); 658 break; 659 default: 660 WARN_ONCE(true, "rtl8723ae: ERR txdesc :%d not processed\n", 661 desc_name); 662 break; 663 } 664 } else { 665 switch (desc_name) { 666 case HW_DESC_OWN: 667 ret = GET_RX_DESC_OWN(pdesc); 668 break; 669 case HW_DESC_RXPKT_LEN: 670 ret = GET_RX_DESC_PKT_LEN(pdesc); 671 break; 672 case HW_DESC_RXBUFF_ADDR: 673 ret = GET_RX_DESC_BUFF_ADDR(pdesc); 674 break; 675 default: 676 WARN_ONCE(true, "rtl8723ae: ERR rxdesc :%d not processed\n", 677 desc_name); 678 break; 679 } 680 } 681 return ret; 682 } 683 684 bool rtl8723e_is_tx_desc_closed(struct ieee80211_hw *hw, 685 u8 hw_queue, u16 index) 686 { 687 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 688 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; 689 u8 *entry = (u8 *)(&ring->desc[ring->idx]); 690 u8 own = (u8)rtl8723e_get_desc(hw, entry, true, HW_DESC_OWN); 691 692 /** 693 *beacon packet will only use the first 694 *descriptor defautly,and the own may not 695 *be cleared by the hardware 696 */ 697 if (own) 698 return false; 699 return true; 700 } 701 702 void rtl8723e_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) 703 { 704 struct rtl_priv *rtlpriv = rtl_priv(hw); 705 if (hw_queue == BEACON_QUEUE) { 706 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); 707 } else { 708 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, 709 BIT(0) << (hw_queue)); 710 } 711 } 712