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