trx.c revision 6ebacbb79d2d05978ba50a24d8cbe2a76ff2014c
1/****************************************************************************** 2 * 3 * Copyright(c) 2009-2010 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 * 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 17 * 18 * The full GNU General Public License is included in this distribution in the 19 * file called LICENSE. 20 * 21 * Contact Information: 22 * wlanfae <wlanfae@realtek.com> 23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, 24 * Hsinchu 300, Taiwan. 25 * 26 * Larry Finger <Larry.Finger@lwfinger.net> 27 * 28 *****************************************************************************/ 29 30#include "../wifi.h" 31#include "../pci.h" 32#include "../base.h" 33#include "reg.h" 34#include "def.h" 35#include "phy.h" 36#include "trx.h" 37#include "led.h" 38 39static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(__le16 fc, 40 unsigned int 41 skb_queue) 42{ 43 enum rtl_desc_qsel qsel; 44 45 if (unlikely(ieee80211_is_beacon(fc))) { 46 qsel = QSLT_BEACON; 47 return qsel; 48 } 49 50 if (ieee80211_is_mgmt(fc)) { 51 qsel = QSLT_MGNT; 52 return qsel; 53 } 54 55 switch (skb_queue) { 56 case VO_QUEUE: 57 qsel = QSLT_VO; 58 break; 59 case VI_QUEUE: 60 qsel = QSLT_VI; 61 break; 62 case BE_QUEUE: 63 qsel = QSLT_BE; 64 break; 65 case BK_QUEUE: 66 qsel = QSLT_BK; 67 break; 68 default: 69 qsel = QSLT_BE; 70 RT_ASSERT(false, ("BE queue, skb_queue:%d," 71 " set qsel = 0x%X\n", skb_queue, QSLT_BE)); 72 break; 73 } 74 return qsel; 75} 76 77static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu) 78{ 79 int rate_idx; 80 81 if (first_ampdu) { 82 if (false == isht) { 83 switch (desc_rate) { 84 case DESC92C_RATE1M: 85 rate_idx = 0; 86 break; 87 case DESC92C_RATE2M: 88 rate_idx = 1; 89 break; 90 case DESC92C_RATE5_5M: 91 rate_idx = 2; 92 break; 93 case DESC92C_RATE11M: 94 rate_idx = 3; 95 break; 96 case DESC92C_RATE6M: 97 rate_idx = 4; 98 break; 99 case DESC92C_RATE9M: 100 rate_idx = 5; 101 break; 102 case DESC92C_RATE12M: 103 rate_idx = 6; 104 break; 105 case DESC92C_RATE18M: 106 rate_idx = 7; 107 break; 108 case DESC92C_RATE24M: 109 rate_idx = 8; 110 break; 111 case DESC92C_RATE36M: 112 rate_idx = 9; 113 break; 114 case DESC92C_RATE48M: 115 rate_idx = 10; 116 break; 117 case DESC92C_RATE54M: 118 rate_idx = 11; 119 break; 120 default: 121 rate_idx = 0; 122 break; 123 } 124 } else { 125 rate_idx = 11; 126 } 127 128 return rate_idx; 129 } 130 131 switch (desc_rate) { 132 case DESC92C_RATE1M: 133 rate_idx = 0; 134 break; 135 case DESC92C_RATE2M: 136 rate_idx = 1; 137 break; 138 case DESC92C_RATE5_5M: 139 rate_idx = 2; 140 break; 141 case DESC92C_RATE11M: 142 rate_idx = 3; 143 break; 144 case DESC92C_RATE6M: 145 rate_idx = 4; 146 break; 147 case DESC92C_RATE9M: 148 rate_idx = 5; 149 break; 150 case DESC92C_RATE12M: 151 rate_idx = 6; 152 break; 153 case DESC92C_RATE18M: 154 rate_idx = 7; 155 break; 156 case DESC92C_RATE24M: 157 rate_idx = 8; 158 break; 159 case DESC92C_RATE36M: 160 rate_idx = 9; 161 break; 162 case DESC92C_RATE48M: 163 rate_idx = 10; 164 break; 165 case DESC92C_RATE54M: 166 rate_idx = 11; 167 break; 168 default: 169 rate_idx = 11; 170 break; 171 } 172 return rate_idx; 173} 174 175static u8 _rtl92c_query_rxpwrpercentage(char antpower) 176{ 177 if ((antpower <= -100) || (antpower >= 20)) 178 return 0; 179 else if (antpower >= 0) 180 return 100; 181 else 182 return 100 + antpower; 183} 184 185static u8 _rtl92c_evm_db_to_percentage(char value) 186{ 187 char ret_val; 188 ret_val = value; 189 190 if (ret_val >= 0) 191 ret_val = 0; 192 193 if (ret_val <= -33) 194 ret_val = -33; 195 196 ret_val = 0 - ret_val; 197 ret_val *= 3; 198 199 if (ret_val == 99) 200 ret_val = 100; 201 202 return ret_val; 203} 204 205static long _rtl92ce_translate_todbm(struct ieee80211_hw *hw, 206 u8 signal_strength_index) 207{ 208 long signal_power; 209 210 signal_power = (long)((signal_strength_index + 1) >> 1); 211 signal_power -= 95; 212 return signal_power; 213} 214 215static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw, 216 long currsig) 217{ 218 long retsig; 219 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) 231 retsig = 36; 232 else if (currsig == 3) 233 retsig = 27; 234 else if (currsig == 2) 235 retsig = 18; 236 else if (currsig == 1) 237 retsig = 9; 238 else 239 retsig = currsig; 240 241 return retsig; 242} 243 244static 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, 249 bool packet_toself, 250 bool packet_beacon) 251{ 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; 258 bool is_cck_rate; 259 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; 268 269 if (is_cck_rate) { 270 u8 report, cck_highpwr; 271 cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; 272 273 cck_highpwr = (u8) rtl_get_bbreg(hw, 274 RFPGA0_XA_HSSIPARAMETER2, 275 BIT(9)); 276 if (!cck_highpwr) { 277 u8 cck_agc_rpt = cck_buf->cck_agc_rpt; 278 report = cck_buf->cck_agc_rpt & 0xc0; 279 report = report >> 6; 280 switch (report) { 281 case 0x3: 282 rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); 283 break; 284 case 0x2: 285 rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); 286 break; 287 case 0x1: 288 rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); 289 break; 290 case 0x0: 291 rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); 292 break; 293 } 294 } else { 295 u8 cck_agc_rpt = cck_buf->cck_agc_rpt; 296 report = p_drvinfo->cfosho[0] & 0x60; 297 report = report >> 5; 298 switch (report) { 299 case 0x3: 300 rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); 301 break; 302 case 0x2: 303 rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); 304 break; 305 case 0x1: 306 rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); 307 break; 308 case 0x0: 309 rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); 310 break; 311 } 312 } 313 314 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all); 315 pstats->rx_pwdb_all = pwdb_all; 316 pstats->recvsignalpower = rx_pwr_all; 317 318 if (packet_match_bssid) { 319 u8 sq; 320 if (pstats->rx_pwdb_all > 40) 321 sq = 100; 322 else { 323 sq = cck_buf->sq_rpt; 324 if (sq > 64) 325 sq = 0; 326 else if (sq < 20) 327 sq = 100; 328 else 329 sq = ((64 - sq) * 100) / 44; 330 } 331 332 pstats->signalquality = sq; 333 pstats->rx_mimo_signalquality[0] = sq; 334 pstats->rx_mimo_signalquality[1] = -1; 335 } 336 } else { 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]) 341 rf_rx_num++; 342 343 rx_pwr[i] = 344 ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110; 345 rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]); 346 total_rssi += rssi; 347 rtlpriv->stats.rx_snr_db[i] = 348 (long)(p_drvinfo->rxsnr[i] / 2); 349 350 if (packet_match_bssid) 351 pstats->rx_mimo_signalstrength[i] = (u8) rssi; 352 } 353 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; 359 360 if (pdesc->rxht && pdesc->rxmcs >= DESC92C_RATEMCS8 && 361 pdesc->rxmcs <= DESC92C_RATEMCS15) 362 max_spatial_stream = 2; 363 else 364 max_spatial_stream = 1; 365 366 for (i = 0; i < max_spatial_stream; i++) { 367 evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]); 368 369 if (packet_match_bssid) { 370 if (i == 0) 371 pstats->signalquality = 372 (u8) (evm & 0xff); 373 pstats->rx_mimo_signalquality[i] = 374 (u8) (evm & 0xff); 375 } 376 } 377 } 378 379 if (is_cck_rate) 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)); 386} 387 388static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw, 389 struct rtl_stats *pstats) 390{ 391 struct rtl_priv *rtlpriv = rtl_priv(hw); 392 struct rtl_phy *rtlphy = &(rtlpriv->phy); 393 u8 rfpath; 394 u32 last_rssi, tmpval; 395 396 if (pstats->packet_toself || pstats->packet_beacon) { 397 rtlpriv->stats.rssi_calculate_cnt++; 398 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; 403 last_rssi = 404 rtlpriv->stats.ui_rssi.elements[rtlpriv-> 405 stats.ui_rssi.index]; 406 rtlpriv->stats.ui_rssi.total_val -= last_rssi; 407 } 408 409 rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength; 410 rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi. 411 index++] = 412 pstats->signalstrength; 413 414 if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) 415 rtlpriv->stats.ui_rssi.index = 0; 416 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; 422 } 423 424 if (!pstats->is_cck && pstats->packet_toself) { 425 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; 426 rfpath++) { 427 428 if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath)) 429 continue; 430 431 if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { 432 rtlpriv->stats.rx_rssi_percentage[rfpath] = 433 pstats->rx_mimo_signalstrength[rfpath]; 434 435 } 436 437 if (pstats->rx_mimo_signalstrength[rfpath] > 438 rtlpriv->stats.rx_rssi_percentage[rfpath]) { 439 rtlpriv->stats.rx_rssi_percentage[rfpath] = 440 ((rtlpriv->stats. 441 rx_rssi_percentage[rfpath] * 442 (RX_SMOOTH_FACTOR - 1)) + 443 (pstats->rx_mimo_signalstrength[rfpath])) / 444 (RX_SMOOTH_FACTOR); 445 446 rtlpriv->stats.rx_rssi_percentage[rfpath] = 447 rtlpriv->stats.rx_rssi_percentage[rfpath] + 448 1; 449 } else { 450 rtlpriv->stats.rx_rssi_percentage[rfpath] = 451 ((rtlpriv->stats. 452 rx_rssi_percentage[rfpath] * 453 (RX_SMOOTH_FACTOR - 1)) + 454 (pstats->rx_mimo_signalstrength[rfpath])) / 455 (RX_SMOOTH_FACTOR); 456 } 457 458 } 459 } 460} 461 462static void _rtl92ce_update_rxsignalstatistics(struct ieee80211_hw *hw, 463 struct rtl_stats *pstats) 464{ 465 struct rtl_priv *rtlpriv = rtl_priv(hw); 466 int weighting; 467 468 if (rtlpriv->stats.recv_signal_power == 0) 469 rtlpriv->stats.recv_signal_power = pstats->recvsignalpower; 470 471 if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power) 472 weighting = 5; 473 474 else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power) 475 weighting = (-5); 476 477 rtlpriv->stats.recv_signal_power = 478 (rtlpriv->stats.recv_signal_power * 5 + 479 pstats->recvsignalpower + weighting) / 6; 480} 481 482static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw, 483 struct rtl_stats *pstats) 484{ 485 struct rtl_priv *rtlpriv = rtl_priv(hw); 486 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 487 long undecorated_smoothed_pwdb; 488 489 if (mac->opmode == NL80211_IFTYPE_ADHOC) { 490 return; 491 } else { 492 undecorated_smoothed_pwdb = 493 rtlpriv->dm.undecorated_smoothed_pwdb; 494 } 495 496 if (pstats->packet_toself || pstats->packet_beacon) { 497 if (undecorated_smoothed_pwdb < 0) 498 undecorated_smoothed_pwdb = pstats->rx_pwdb_all; 499 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); 505 506 undecorated_smoothed_pwdb = undecorated_smoothed_pwdb 507 + 1; 508 } else { 509 undecorated_smoothed_pwdb = 510 (((undecorated_smoothed_pwdb) * 511 (RX_SMOOTH_FACTOR - 1)) + 512 (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); 513 } 514 515 rtlpriv->dm.undecorated_smoothed_pwdb = 516 undecorated_smoothed_pwdb; 517 _rtl92ce_update_rxsignalstatistics(hw, pstats); 518 } 519} 520 521static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw, 522 struct rtl_stats *pstats) 523{ 524 struct rtl_priv *rtlpriv = rtl_priv(hw); 525 u32 last_evm, n_spatialstream, tmpval; 526 527 if (pstats->signalquality != 0) { 528 if (pstats->packet_toself || pstats->packet_beacon) { 529 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; 534 last_evm = 535 rtlpriv->stats. 536 ui_link_quality.elements[rtlpriv-> 537 stats.ui_link_quality. 538 index]; 539 rtlpriv->stats.ui_link_quality.total_val -= 540 last_evm; 541 } 542 543 rtlpriv->stats.ui_link_quality.total_val += 544 pstats->signalquality; 545 rtlpriv->stats.ui_link_quality.elements[rtlpriv->stats. 546 ui_link_quality. 547 index++] = 548 pstats->signalquality; 549 550 if (rtlpriv->stats.ui_link_quality.index >= 551 PHY_LINKQUALITY_SLID_WIN_MAX) 552 rtlpriv->stats.ui_link_quality.index = 0; 553 554 tmpval = rtlpriv->stats.ui_link_quality.total_val / 555 rtlpriv->stats.ui_link_quality.total_num; 556 rtlpriv->stats.signal_quality = tmpval; 557 558 rtlpriv->stats.last_sigstrength_inpercent = tmpval; 559 560 for (n_spatialstream = 0; n_spatialstream < 2; 561 n_spatialstream++) { 562 if (pstats-> 563 rx_mimo_signalquality[n_spatialstream] != 564 -1) { 565 if (rtlpriv->stats. 566 rx_evm_percentage[n_spatialstream] 567 == 0) { 568 rtlpriv->stats. 569 rx_evm_percentage 570 [n_spatialstream] = 571 pstats->rx_mimo_signalquality 572 [n_spatialstream]; 573 } 574 575 rtlpriv->stats. 576 rx_evm_percentage[n_spatialstream] = 577 ((rtlpriv-> 578 stats.rx_evm_percentage 579 [n_spatialstream] * 580 (RX_SMOOTH_FACTOR - 1)) + 581 (pstats-> 582 rx_mimo_signalquality 583 [n_spatialstream] * 1)) / 584 (RX_SMOOTH_FACTOR); 585 } 586 } 587 } 588 } else { 589 ; 590 } 591} 592 593static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw, 594 u8 *buffer, 595 struct rtl_stats *pcurrent_stats) 596{ 597 598 if (!pcurrent_stats->packet_matchbssid && 599 !pcurrent_stats->packet_beacon) 600 return; 601 602 _rtl92ce_process_ui_rssi(hw, pcurrent_stats); 603 _rtl92ce_process_pwdb(hw, pcurrent_stats); 604 _rtl92ce_process_ui_link_quality(hw, pcurrent_stats); 605} 606 607static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, 608 struct sk_buff *skb, 609 struct rtl_stats *pstats, 610 struct rx_desc_92c *pdesc, 611 struct rx_fwinfo_92c *p_drvinfo) 612{ 613 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 614 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 615 616 struct ieee80211_hdr *hdr; 617 u8 *tmp_buf; 618 u8 *praddr; 619 u8 *psaddr; 620 __le16 fc; 621 u16 type, c_fc; 622 bool packet_matchbssid, packet_toself, packet_beacon; 623 624 tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; 625 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); 630 praddr = hdr->addr1; 631 psaddr = hdr->addr2; 632 633 packet_matchbssid = 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)); 640 641 packet_toself = packet_matchbssid && 642 (!compare_ether_addr(praddr, rtlefuse->dev_addr)); 643 644 if (ieee80211_is_beacon(fc)) 645 packet_beacon = true; 646 647 _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, 648 packet_matchbssid, packet_toself, 649 packet_beacon); 650 651 _rtl92ce_process_phyinfo(hw, tmp_buf, pstats); 652} 653 654bool 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) 658{ 659 struct rx_fwinfo_92c *p_drvinfo; 660 struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; 661 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); 678 679 rx_status->freq = hw->conf.channel->center_freq; 680 rx_status->band = hw->conf.channel->band; 681 682 if (GET_RX_DESC_CRC32(pdesc)) 683 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; 684 685 if (!GET_RX_DESC_SWDEC(pdesc)) 686 rx_status->flag |= RX_FLAG_DECRYPTED; 687 688 if (GET_RX_DESC_BW(pdesc)) 689 rx_status->flag |= RX_FLAG_40MHZ; 690 691 if (GET_RX_DESC_RXHT(pdesc)) 692 rx_status->flag |= RX_FLAG_HT; 693 694 rx_status->flag |= RX_FLAG_MACTIME_MPDU; 695 696 if (stats->decrypted) 697 rx_status->flag |= RX_FLAG_DECRYPTED; 698 699 rx_status->rate_idx = _rtl92ce_rate_mapping((bool) 700 GET_RX_DESC_RXHT(pdesc), 701 (u8) 702 GET_RX_DESC_RXMCS(pdesc), 703 (bool) 704 GET_RX_DESC_PAGGR(pdesc)); 705 706 rx_status->mactime = GET_RX_DESC_TSFL(pdesc); 707 if (phystatus == true) { 708 p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + 709 stats->rx_bufshift); 710 711 _rtl92ce_translate_rx_signal_stuff(hw, 712 skb, stats, pdesc, 713 p_drvinfo); 714 } 715 716 /*rx_status->qual = stats->signal; */ 717 rx_status->signal = stats->rssi + 10; 718 /*rx_status->noise = -stats->noise; */ 719 720 return true; 721} 722 723void 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) 727{ 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 = 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; 738 u16 seq_number; 739 __le16 fc = hdr->frame_control; 740 u8 rate_flag = info->control.rates[0].flags; 741 742 enum rtl_desc_qsel fw_qsel = 743 _rtl92ce_map_hwqueue_to_fwqueue(fc, queue_index); 744 745 bool firstseg = ((hdr->seq_ctrl & 746 cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); 747 748 bool lastseg = ((hdr->frame_control & 749 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); 750 751 dma_addr_t mapping = pci_map_single(rtlpci->pdev, 752 skb->data, skb->len, 753 PCI_DMA_TODEVICE); 754 755 seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; 756 757 rtl_get_tcb_desc(hw, info, skb, &tcb_desc); 758 759 CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c)); 760 761 if (firstseg) { 762 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); 763 764 SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate); 765 766 if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble) 767 SET_TX_DESC_DATA_SHORTGI(pdesc, 1); 768 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); 773 } 774 SET_TX_DESC_SEQ(pdesc, seq_number); 775 776 SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.rts_enable && 777 !tcb_desc. 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)); 784 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))); 792 793 if (mac->bw_40) { 794 if (tcb_desc.packet_bw) { 795 SET_TX_DESC_DATA_BW(pdesc, 1); 796 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); 797 } else { 798 SET_TX_DESC_DATA_BW(pdesc, 0); 799 800 if (rate_flag & IEEE80211_TX_RC_DUP_DATA) { 801 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 802 mac->cur_40_prime_sc); 803 } 804 } 805 } else { 806 SET_TX_DESC_DATA_BW(pdesc, 0); 807 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0); 808 } 809 810 SET_TX_DESC_LINIP(pdesc, 0); 811 SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len); 812 813 if (sta) { 814 u8 ampdu_density = sta->ht_cap.ampdu_density; 815 SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); 816 } 817 818 if (info->control.hw_key) { 819 struct ieee80211_key_conf *keyconf = 820 info->control.hw_key; 821 822 switch (keyconf->cipher) { 823 case WLAN_CIPHER_SUITE_WEP40: 824 case WLAN_CIPHER_SUITE_WEP104: 825 case WLAN_CIPHER_SUITE_TKIP: 826 SET_TX_DESC_SEC_TYPE(pdesc, 0x1); 827 break; 828 case WLAN_CIPHER_SUITE_CCMP: 829 SET_TX_DESC_SEC_TYPE(pdesc, 0x3); 830 break; 831 default: 832 SET_TX_DESC_SEC_TYPE(pdesc, 0x0); 833 break; 834 835 } 836 } 837 838 SET_TX_DESC_PKT_ID(pdesc, 0); 839 SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel); 840 841 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F); 842 SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF); 843 SET_TX_DESC_DISABLE_FB(pdesc, 0); 844 SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0); 845 846 if (ieee80211_is_data_qos(fc)) { 847 if (mac->rdg_en) { 848 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, 849 ("Enable RDG function.\n")); 850 SET_TX_DESC_RDG_ENABLE(pdesc, 1); 851 SET_TX_DESC_HTC(pdesc, 1); 852 } 853 } 854 } 855 856 SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0)); 857 SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0)); 858 859 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); 860 861 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); 862 863 if (rtlpriv->dm.useramask) { 864 SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index); 865 SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id); 866 } else { 867 SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index); 868 SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index); 869 } 870 871 if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps && 872 ppsc->fwctrl_lps) { 873 SET_TX_DESC_HWSEQ_EN(pdesc, 1); 874 SET_TX_DESC_PKT_ID(pdesc, 8); 875 876 if (!defaultadapter) 877 SET_TX_DESC_QOS(pdesc, 1); 878 } 879 880 SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1)); 881 882 if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || 883 is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { 884 SET_TX_DESC_BMC(pdesc, 1); 885 } 886 887 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); 888} 889 890void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, 891 u8 *pdesc, bool firstseg, 892 bool lastseg, struct sk_buff *skb) 893{ 894 struct rtl_priv *rtlpriv = rtl_priv(hw); 895 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 896 u8 fw_queue = QSLT_BEACON; 897 898 dma_addr_t mapping = pci_map_single(rtlpci->pdev, 899 skb->data, skb->len, 900 PCI_DMA_TODEVICE); 901 902 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); 903 __le16 fc = hdr->frame_control; 904 905 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE); 906 907 if (firstseg) 908 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); 909 910 SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); 911 912 SET_TX_DESC_SEQ(pdesc, 0); 913 914 SET_TX_DESC_LINIP(pdesc, 0); 915 916 SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); 917 918 SET_TX_DESC_FIRST_SEG(pdesc, 1); 919 SET_TX_DESC_LAST_SEG(pdesc, 1); 920 921 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len)); 922 923 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); 924 925 SET_TX_DESC_RATE_ID(pdesc, 7); 926 SET_TX_DESC_MACID(pdesc, 0); 927 928 SET_TX_DESC_OWN(pdesc, 1); 929 930 SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); 931 932 SET_TX_DESC_FIRST_SEG(pdesc, 1); 933 SET_TX_DESC_LAST_SEG(pdesc, 1); 934 935 SET_TX_DESC_OFFSET(pdesc, 0x20); 936 937 SET_TX_DESC_USE_RATE(pdesc, 1); 938 939 if (!ieee80211_is_data_qos(fc)) { 940 SET_TX_DESC_HWSEQ_EN(pdesc, 1); 941 SET_TX_DESC_PKT_ID(pdesc, 8); 942 } 943 944 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, 945 "H2C Tx Cmd Content\n", 946 pdesc, TX_DESC_SIZE); 947} 948 949void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) 950{ 951 if (istx == true) { 952 switch (desc_name) { 953 case HW_DESC_OWN: 954 SET_TX_DESC_OWN(pdesc, 1); 955 break; 956 case HW_DESC_TX_NEXTDESC_ADDR: 957 SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); 958 break; 959 default: 960 RT_ASSERT(false, ("ERR txdesc :%d" 961 " not process\n", desc_name)); 962 break; 963 } 964 } else { 965 switch (desc_name) { 966 case HW_DESC_RXOWN: 967 SET_RX_DESC_OWN(pdesc, 1); 968 break; 969 case HW_DESC_RXBUFF_ADDR: 970 SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val); 971 break; 972 case HW_DESC_RXPKT_LEN: 973 SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val); 974 break; 975 case HW_DESC_RXERO: 976 SET_RX_DESC_EOR(pdesc, 1); 977 break; 978 default: 979 RT_ASSERT(false, ("ERR rxdesc :%d " 980 "not process\n", desc_name)); 981 break; 982 } 983 } 984} 985 986u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) 987{ 988 u32 ret = 0; 989 990 if (istx == true) { 991 switch (desc_name) { 992 case HW_DESC_OWN: 993 ret = GET_TX_DESC_OWN(p_desc); 994 break; 995 case HW_DESC_TXBUFF_ADDR: 996 ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc); 997 break; 998 default: 999 RT_ASSERT(false, ("ERR txdesc :%d " 1000 "not process\n", desc_name)); 1001 break; 1002 } 1003 } else { 1004 struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; 1005 switch (desc_name) { 1006 case HW_DESC_OWN: 1007 ret = GET_RX_DESC_OWN(pdesc); 1008 break; 1009 case HW_DESC_RXPKT_LEN: 1010 ret = GET_RX_DESC_PKT_LEN(pdesc); 1011 break; 1012 default: 1013 RT_ASSERT(false, ("ERR rxdesc :%d " 1014 "not process\n", desc_name)); 1015 break; 1016 } 1017 } 1018 return ret; 1019} 1020 1021void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue) 1022{ 1023 struct rtl_priv *rtlpriv = rtl_priv(hw); 1024 if (hw_queue == BEACON_QUEUE) { 1025 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); 1026 } else { 1027 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, 1028 BIT(0) << (hw_queue)); 1029 } 1030} 1031 1032bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, 1033 struct sk_buff *skb) 1034{ 1035 struct rtl_priv *rtlpriv = rtl_priv(hw); 1036 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 1037 struct rtl8192_tx_ring *ring; 1038 struct rtl_tx_desc *pdesc; 1039 u8 own; 1040 unsigned long flags; 1041 struct sk_buff *pskb = NULL; 1042 1043 ring = &rtlpci->tx_ring[BEACON_QUEUE]; 1044 1045 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); 1046 1047 pskb = __skb_dequeue(&ring->queue); 1048 if (pskb) 1049 kfree_skb(pskb); 1050 1051 pdesc = &ring->desc[0]; 1052 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); 1053 1054 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); 1055 1056 __skb_queue_tail(&ring->queue, skb); 1057 1058 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); 1059 1060 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); 1061 1062 return true; 1063} 1064