linux/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c
<<
>>
Prefs
   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 * 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 u8 _rtl92de_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
  40{
  41        __le16 fc = rtl_get_fc(skb);
  42
  43        if (unlikely(ieee80211_is_beacon(fc)))
  44                return QSLT_BEACON;
  45        if (ieee80211_is_mgmt(fc))
  46                return QSLT_MGNT;
  47
  48        return skb->priority;
  49}
  50
  51static u8 _rtl92d_query_rxpwrpercentage(char antpower)
  52{
  53        if ((antpower <= -100) || (antpower >= 20))
  54                return 0;
  55        else if (antpower >= 0)
  56                return 100;
  57        else
  58                return 100 + antpower;
  59}
  60
  61static u8 _rtl92d_evm_db_to_percentage(char value)
  62{
  63        char ret_val = value;
  64
  65        if (ret_val >= 0)
  66                ret_val = 0;
  67        if (ret_val <= -33)
  68                ret_val = -33;
  69        ret_val = 0 - ret_val;
  70        ret_val *= 3;
  71        if (ret_val == 99)
  72                ret_val = 100;
  73        return ret_val;
  74}
  75
  76static long _rtl92de_translate_todbm(struct ieee80211_hw *hw,
  77                                     u8 signal_strength_index)
  78{
  79        long signal_power;
  80
  81        signal_power = (long)((signal_strength_index + 1) >> 1);
  82        signal_power -= 95;
  83        return signal_power;
  84}
  85
  86static long _rtl92de_signal_scale_mapping(struct ieee80211_hw *hw, long currsig)
  87{
  88        long retsig;
  89
  90        if (currsig >= 61 && currsig <= 100)
  91                retsig = 90 + ((currsig - 60) / 4);
  92        else if (currsig >= 41 && currsig <= 60)
  93                retsig = 78 + ((currsig - 40) / 2);
  94        else if (currsig >= 31 && currsig <= 40)
  95                retsig = 66 + (currsig - 30);
  96        else if (currsig >= 21 && currsig <= 30)
  97                retsig = 54 + (currsig - 20);
  98        else if (currsig >= 5 && currsig <= 20)
  99                retsig = 42 + (((currsig - 5) * 2) / 3);
 100        else if (currsig == 4)
 101                retsig = 36;
 102        else if (currsig == 3)
 103                retsig = 27;
 104        else if (currsig == 2)
 105                retsig = 18;
 106        else if (currsig == 1)
 107                retsig = 9;
 108        else
 109                retsig = currsig;
 110        return retsig;
 111}
 112
 113static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw,
 114                                       struct rtl_stats *pstats,
 115                                       struct rx_desc_92d *pdesc,
 116                                       struct rx_fwinfo_92d *p_drvinfo,
 117                                       bool packet_match_bssid,
 118                                       bool packet_toself,
 119                                       bool packet_beacon)
 120{
 121        struct rtl_priv *rtlpriv = rtl_priv(hw);
 122        struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
 123        struct phy_sts_cck_8192d *cck_buf;
 124        s8 rx_pwr_all, rx_pwr[4];
 125        u8 rf_rx_num = 0, evm, pwdb_all;
 126        u8 i, max_spatial_stream;
 127        u32 rssi, total_rssi = 0;
 128        bool is_cck_rate;
 129
 130        is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc->rxmcs);
 131        pstats->packet_matchbssid = packet_match_bssid;
 132        pstats->packet_toself = packet_toself;
 133        pstats->packet_beacon = packet_beacon;
 134        pstats->is_cck = is_cck_rate;
 135        pstats->rx_mimo_sig_qual[0] = -1;
 136        pstats->rx_mimo_sig_qual[1] = -1;
 137
 138        if (is_cck_rate) {
 139                u8 report, cck_highpwr;
 140                cck_buf = (struct phy_sts_cck_8192d *)p_drvinfo;
 141                if (ppsc->rfpwr_state == ERFON)
 142                        cck_highpwr = (u8) rtl_get_bbreg(hw,
 143                                                 RFPGA0_XA_HSSIPARAMETER2,
 144                                                 BIT(9));
 145                else
 146                        cck_highpwr = false;
 147                if (!cck_highpwr) {
 148                        u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 149                        report = cck_buf->cck_agc_rpt & 0xc0;
 150                        report = report >> 6;
 151                        switch (report) {
 152                        case 0x3:
 153                                rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
 154                                break;
 155                        case 0x2:
 156                                rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
 157                                break;
 158                        case 0x1:
 159                                rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
 160                                break;
 161                        case 0x0:
 162                                rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
 163                                break;
 164                        }
 165                } else {
 166                        u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 167                        report = p_drvinfo->cfosho[0] & 0x60;
 168                        report = report >> 5;
 169                        switch (report) {
 170                        case 0x3:
 171                                rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
 172                                break;
 173                        case 0x2:
 174                                rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
 175                                break;
 176                        case 0x1:
 177                                rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
 178                                break;
 179                        case 0x0:
 180                                rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
 181                                break;
 182                        }
 183                }
 184                pwdb_all = _rtl92d_query_rxpwrpercentage(rx_pwr_all);
 185                /* CCK gain is smaller than OFDM/MCS gain,  */
 186                /* so we add gain diff by experiences, the val is 6 */
 187                pwdb_all += 6;
 188                if (pwdb_all > 100)
 189                        pwdb_all = 100;
 190                /* modify the offset to make the same gain index with OFDM. */
 191                if (pwdb_all > 34 && pwdb_all <= 42)
 192                        pwdb_all -= 2;
 193                else if (pwdb_all > 26 && pwdb_all <= 34)
 194                        pwdb_all -= 6;
 195                else if (pwdb_all > 14 && pwdb_all <= 26)
 196                        pwdb_all -= 8;
 197                else if (pwdb_all > 4 && pwdb_all <= 14)
 198                        pwdb_all -= 4;
 199                pstats->rx_pwdb_all = pwdb_all;
 200                pstats->recvsignalpower = rx_pwr_all;
 201                if (packet_match_bssid) {
 202                        u8 sq;
 203                        if (pstats->rx_pwdb_all > 40) {
 204                                sq = 100;
 205                        } else {
 206                                sq = cck_buf->sq_rpt;
 207                                if (sq > 64)
 208                                        sq = 0;
 209                                else if (sq < 20)
 210                                        sq = 100;
 211                                else
 212                                        sq = ((64 - sq) * 100) / 44;
 213                        }
 214                        pstats->signalquality = sq;
 215                        pstats->rx_mimo_sig_qual[0] = sq;
 216                        pstats->rx_mimo_sig_qual[1] = -1;
 217                }
 218        } else {
 219                rtlpriv->dm.rfpath_rxenable[0] = true;
 220                rtlpriv->dm.rfpath_rxenable[1] = true;
 221                for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
 222                        if (rtlpriv->dm.rfpath_rxenable[i])
 223                                rf_rx_num++;
 224                        rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f) * 2)
 225                                    - 110;
 226                        rssi = _rtl92d_query_rxpwrpercentage(rx_pwr[i]);
 227                        total_rssi += rssi;
 228                        rtlpriv->stats.rx_snr_db[i] =
 229                                         (long)(p_drvinfo->rxsnr[i] / 2);
 230                        if (packet_match_bssid)
 231                                pstats->rx_mimo_signalstrength[i] = (u8) rssi;
 232                }
 233                rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 106;
 234                pwdb_all = _rtl92d_query_rxpwrpercentage(rx_pwr_all);
 235                pstats->rx_pwdb_all = pwdb_all;
 236                pstats->rxpower = rx_pwr_all;
 237                pstats->recvsignalpower = rx_pwr_all;
 238                if (pdesc->rxht && pdesc->rxmcs >= DESC_RATEMCS8 &&
 239                    pdesc->rxmcs <= DESC_RATEMCS15)
 240                        max_spatial_stream = 2;
 241                else
 242                        max_spatial_stream = 1;
 243                for (i = 0; i < max_spatial_stream; i++) {
 244                        evm = _rtl92d_evm_db_to_percentage(p_drvinfo->rxevm[i]);
 245                        if (packet_match_bssid) {
 246                                if (i == 0)
 247                                        pstats->signalquality =
 248                                                 (u8)(evm & 0xff);
 249                                pstats->rx_mimo_sig_qual[i] =
 250                                                 (u8)(evm & 0xff);
 251                        }
 252                }
 253        }
 254        if (is_cck_rate)
 255                pstats->signalstrength = (u8)(_rtl92de_signal_scale_mapping(hw,
 256                                pwdb_all));
 257        else if (rf_rx_num != 0)
 258                pstats->signalstrength = (u8)(_rtl92de_signal_scale_mapping(hw,
 259                                total_rssi /= rf_rx_num));
 260}
 261
 262static void rtl92d_loop_over_paths(struct ieee80211_hw *hw,
 263                                   struct rtl_stats *pstats)
 264{
 265        struct rtl_priv *rtlpriv = rtl_priv(hw);
 266        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 267        u8 rfpath;
 268
 269        for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
 270             rfpath++) {
 271                if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
 272                        rtlpriv->stats.rx_rssi_percentage[rfpath] =
 273                            pstats->rx_mimo_signalstrength[rfpath];
 274
 275                }
 276                if (pstats->rx_mimo_signalstrength[rfpath] >
 277                    rtlpriv->stats.rx_rssi_percentage[rfpath]) {
 278                        rtlpriv->stats.rx_rssi_percentage[rfpath] =
 279                            ((rtlpriv->stats.rx_rssi_percentage[rfpath] *
 280                              (RX_SMOOTH_FACTOR - 1)) +
 281                             (pstats->rx_mimo_signalstrength[rfpath])) /
 282                            (RX_SMOOTH_FACTOR);
 283                        rtlpriv->stats.rx_rssi_percentage[rfpath] =
 284                            rtlpriv->stats.rx_rssi_percentage[rfpath] + 1;
 285                } else {
 286                        rtlpriv->stats.rx_rssi_percentage[rfpath] =
 287                            ((rtlpriv->stats.rx_rssi_percentage[rfpath] *
 288                              (RX_SMOOTH_FACTOR - 1)) +
 289                             (pstats->rx_mimo_signalstrength[rfpath])) /
 290                            (RX_SMOOTH_FACTOR);
 291                }
 292        }
 293}
 294
 295static void _rtl92de_process_ui_rssi(struct ieee80211_hw *hw,
 296                                     struct rtl_stats *pstats)
 297{
 298        struct rtl_priv *rtlpriv = rtl_priv(hw);
 299        u32 last_rssi, tmpval;
 300
 301        if (pstats->packet_toself || pstats->packet_beacon) {
 302                rtlpriv->stats.rssi_calculate_cnt++;
 303                if (rtlpriv->stats.ui_rssi.total_num++ >=
 304                    PHY_RSSI_SLID_WIN_MAX) {
 305                        rtlpriv->stats.ui_rssi.total_num =
 306                                                 PHY_RSSI_SLID_WIN_MAX;
 307                        last_rssi = rtlpriv->stats.ui_rssi.elements[
 308                                rtlpriv->stats.ui_rssi.index];
 309                        rtlpriv->stats.ui_rssi.total_val -= last_rssi;
 310                }
 311                rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
 312                rtlpriv->stats.ui_rssi.elements
 313                        [rtlpriv->stats.ui_rssi.index++] =
 314                        pstats->signalstrength;
 315                if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
 316                        rtlpriv->stats.ui_rssi.index = 0;
 317                tmpval = rtlpriv->stats.ui_rssi.total_val /
 318                        rtlpriv->stats.ui_rssi.total_num;
 319                rtlpriv->stats.signal_strength = _rtl92de_translate_todbm(hw,
 320                        (u8) tmpval);
 321                pstats->rssi = rtlpriv->stats.signal_strength;
 322        }
 323        if (!pstats->is_cck && pstats->packet_toself)
 324                rtl92d_loop_over_paths(hw, pstats);
 325}
 326
 327static void _rtl92de_update_rxsignalstatistics(struct ieee80211_hw *hw,
 328                                               struct rtl_stats *pstats)
 329{
 330        struct rtl_priv *rtlpriv = rtl_priv(hw);
 331        int weighting = 0;
 332
 333        if (rtlpriv->stats.recv_signal_power == 0)
 334                rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
 335        if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
 336                weighting = 5;
 337        else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
 338                weighting = (-5);
 339        rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power *
 340                5 + pstats->recvsignalpower + weighting) / 6;
 341}
 342
 343static void _rtl92de_process_pwdb(struct ieee80211_hw *hw,
 344                                  struct rtl_stats *pstats)
 345{
 346        struct rtl_priv *rtlpriv = rtl_priv(hw);
 347        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 348        long undec_sm_pwdb;
 349
 350        if (mac->opmode == NL80211_IFTYPE_ADHOC ||
 351                mac->opmode == NL80211_IFTYPE_AP)
 352                return;
 353        else
 354                undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
 355
 356        if (pstats->packet_toself || pstats->packet_beacon) {
 357                if (undec_sm_pwdb < 0)
 358                        undec_sm_pwdb = pstats->rx_pwdb_all;
 359                if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) {
 360                        undec_sm_pwdb = (((undec_sm_pwdb) *
 361                              (RX_SMOOTH_FACTOR - 1)) +
 362                              (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
 363                        undec_sm_pwdb = undec_sm_pwdb + 1;
 364                } else {
 365                        undec_sm_pwdb = (((undec_sm_pwdb) *
 366                              (RX_SMOOTH_FACTOR - 1)) +
 367                              (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
 368                }
 369                rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb;
 370                _rtl92de_update_rxsignalstatistics(hw, pstats);
 371        }
 372}
 373
 374static void rtl92d_loop_over_streams(struct ieee80211_hw *hw,
 375                                     struct rtl_stats *pstats)
 376{
 377        struct rtl_priv *rtlpriv = rtl_priv(hw);
 378        int stream;
 379
 380        for (stream = 0; stream < 2; stream++) {
 381                if (pstats->rx_mimo_sig_qual[stream] != -1) {
 382                        if (rtlpriv->stats.rx_evm_percentage[stream] == 0) {
 383                                rtlpriv->stats.rx_evm_percentage[stream] =
 384                                    pstats->rx_mimo_sig_qual[stream];
 385                        }
 386                        rtlpriv->stats.rx_evm_percentage[stream] =
 387                            ((rtlpriv->stats.rx_evm_percentage[stream]
 388                              * (RX_SMOOTH_FACTOR - 1)) +
 389                             (pstats->rx_mimo_sig_qual[stream] * 1)) /
 390                            (RX_SMOOTH_FACTOR);
 391                }
 392        }
 393}
 394
 395static void _rtl92de_process_ui_link_quality(struct ieee80211_hw *hw,
 396                                             struct rtl_stats *pstats)
 397{
 398        struct rtl_priv *rtlpriv = rtl_priv(hw);
 399        u32 last_evm, tmpval;
 400
 401        if (pstats->signalquality == 0)
 402                return;
 403        if (pstats->packet_toself || pstats->packet_beacon) {
 404                if (rtlpriv->stats.ui_link_quality.total_num++ >=
 405                    PHY_LINKQUALITY_SLID_WIN_MAX) {
 406                        rtlpriv->stats.ui_link_quality.total_num =
 407                            PHY_LINKQUALITY_SLID_WIN_MAX;
 408                        last_evm = rtlpriv->stats.ui_link_quality.elements[
 409                                rtlpriv->stats.ui_link_quality.index];
 410                        rtlpriv->stats.ui_link_quality.total_val -= last_evm;
 411                }
 412                rtlpriv->stats.ui_link_quality.total_val +=
 413                                                 pstats->signalquality;
 414                rtlpriv->stats.ui_link_quality.elements[
 415                        rtlpriv->stats.ui_link_quality.index++] =
 416                                                 pstats->signalquality;
 417                if (rtlpriv->stats.ui_link_quality.index >=
 418                    PHY_LINKQUALITY_SLID_WIN_MAX)
 419                        rtlpriv->stats.ui_link_quality.index = 0;
 420                tmpval = rtlpriv->stats.ui_link_quality.total_val /
 421                    rtlpriv->stats.ui_link_quality.total_num;
 422                rtlpriv->stats.signal_quality = tmpval;
 423                rtlpriv->stats.last_sigstrength_inpercent = tmpval;
 424                rtl92d_loop_over_streams(hw, pstats);
 425        }
 426}
 427
 428static void _rtl92de_process_phyinfo(struct ieee80211_hw *hw,
 429                                     u8 *buffer,
 430                                     struct rtl_stats *pcurrent_stats)
 431{
 432
 433        if (!pcurrent_stats->packet_matchbssid &&
 434            !pcurrent_stats->packet_beacon)
 435                return;
 436
 437        _rtl92de_process_ui_rssi(hw, pcurrent_stats);
 438        _rtl92de_process_pwdb(hw, pcurrent_stats);
 439        _rtl92de_process_ui_link_quality(hw, pcurrent_stats);
 440}
 441
 442static void _rtl92de_translate_rx_signal_stuff(struct ieee80211_hw *hw,
 443                                               struct sk_buff *skb,
 444                                               struct rtl_stats *pstats,
 445                                               struct rx_desc_92d *pdesc,
 446                                               struct rx_fwinfo_92d *p_drvinfo)
 447{
 448        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 449        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 450        struct ieee80211_hdr *hdr;
 451        u8 *tmp_buf;
 452        u8 *praddr;
 453        u16 type, cfc;
 454        __le16 fc;
 455        bool packet_matchbssid, packet_toself, packet_beacon = false;
 456
 457        tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
 458        hdr = (struct ieee80211_hdr *)tmp_buf;
 459        fc = hdr->frame_control;
 460        cfc = le16_to_cpu(fc);
 461        type = WLAN_FC_GET_TYPE(fc);
 462        praddr = hdr->addr1;
 463        packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
 464             ether_addr_equal(mac->bssid,
 465                              (cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
 466                              (cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
 467                              hdr->addr3) &&
 468             (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
 469        packet_toself = packet_matchbssid &&
 470                        ether_addr_equal(praddr, rtlefuse->dev_addr);
 471        if (ieee80211_is_beacon(fc))
 472                packet_beacon = true;
 473        _rtl92de_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
 474                                   packet_matchbssid, packet_toself,
 475                                   packet_beacon);
 476        _rtl92de_process_phyinfo(hw, tmp_buf, pstats);
 477}
 478
 479bool rtl92de_rx_query_desc(struct ieee80211_hw *hw,     struct rtl_stats *stats,
 480                struct ieee80211_rx_status *rx_status,
 481                u8 *p_desc, struct sk_buff *skb)
 482{
 483        struct rx_fwinfo_92d *p_drvinfo;
 484        struct rx_desc_92d *pdesc = (struct rx_desc_92d *)p_desc;
 485        u32 phystatus = GET_RX_DESC_PHYST(pdesc);
 486
 487        stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
 488        stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
 489                                 RX_DRV_INFO_SIZE_UNIT;
 490        stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
 491        stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
 492        stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
 493        stats->hwerror = (stats->crc | stats->icv);
 494        stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
 495        stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
 496        stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
 497        stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
 498        stats->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
 499                                         && (GET_RX_DESC_FAGGR(pdesc) == 1));
 500        stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
 501        stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
 502        stats->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
 503        rx_status->freq = hw->conf.chandef.chan->center_freq;
 504        rx_status->band = hw->conf.chandef.chan->band;
 505        if (GET_RX_DESC_CRC32(pdesc))
 506                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
 507        if (!GET_RX_DESC_SWDEC(pdesc))
 508                rx_status->flag |= RX_FLAG_DECRYPTED;
 509        if (GET_RX_DESC_BW(pdesc))
 510                rx_status->flag |= RX_FLAG_40MHZ;
 511        if (GET_RX_DESC_RXHT(pdesc))
 512                rx_status->flag |= RX_FLAG_HT;
 513        rx_status->flag |= RX_FLAG_MACTIME_START;
 514        if (stats->decrypted)
 515                rx_status->flag |= RX_FLAG_DECRYPTED;
 516        rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht,
 517                                                   false, stats->rate);
 518        rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
 519        if (phystatus) {
 520                p_drvinfo = (struct rx_fwinfo_92d *)(skb->data +
 521                                                     stats->rx_bufshift);
 522                _rtl92de_translate_rx_signal_stuff(hw,
 523                                                   skb, stats, pdesc,
 524                                                   p_drvinfo);
 525        }
 526        /*rx_status->qual = stats->signal; */
 527        rx_status->signal = stats->recvsignalpower + 10;
 528        return true;
 529}
 530
 531static void _rtl92de_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
 532                                      u8 *virtualaddress)
 533{
 534        memset(virtualaddress, 0, 8);
 535
 536        SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num);
 537        SET_EARLYMODE_LEN0(virtualaddress, ptcb_desc->empkt_len[0]);
 538        SET_EARLYMODE_LEN1(virtualaddress, ptcb_desc->empkt_len[1]);
 539        SET_EARLYMODE_LEN2_1(virtualaddress, ptcb_desc->empkt_len[2] & 0xF);
 540        SET_EARLYMODE_LEN2_2(virtualaddress, ptcb_desc->empkt_len[2] >> 4);
 541        SET_EARLYMODE_LEN3(virtualaddress, ptcb_desc->empkt_len[3]);
 542        SET_EARLYMODE_LEN4(virtualaddress, ptcb_desc->empkt_len[4]);
 543}
 544
 545void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
 546                          struct ieee80211_hdr *hdr, u8 *pdesc_tx,
 547                          u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
 548                          struct ieee80211_sta *sta,
 549                          struct sk_buff *skb,
 550                          u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
 551{
 552        struct rtl_priv *rtlpriv = rtl_priv(hw);
 553        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 554        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 555        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 556        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 557        u8 *pdesc = pdesc_tx;
 558        u16 seq_number;
 559        __le16 fc = hdr->frame_control;
 560        unsigned int buf_len = 0;
 561        unsigned int skb_len = skb->len;
 562        u8 fw_qsel = _rtl92de_map_hwqueue_to_fwqueue(skb, hw_queue);
 563        bool firstseg = ((hdr->seq_ctrl &
 564                        cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
 565        bool lastseg = ((hdr->frame_control &
 566                        cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
 567        dma_addr_t mapping;
 568        u8 bw_40 = 0;
 569
 570        if (mac->opmode == NL80211_IFTYPE_STATION) {
 571                bw_40 = mac->bw_40;
 572        } else if (mac->opmode == NL80211_IFTYPE_AP ||
 573                mac->opmode == NL80211_IFTYPE_ADHOC) {
 574                if (sta)
 575                        bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
 576        }
 577        seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
 578        rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
 579        /* reserve 8 byte for AMPDU early mode */
 580        if (rtlhal->earlymode_enable) {
 581                skb_push(skb, EM_HDR_LEN);
 582                memset(skb->data, 0, EM_HDR_LEN);
 583        }
 584        buf_len = skb->len;
 585        mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
 586                                 PCI_DMA_TODEVICE);
 587        if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
 588                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 589                         "DMA mapping error");
 590                return;
 591        }
 592        CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92d));
 593        if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
 594                firstseg = true;
 595                lastseg = true;
 596        }
 597        if (firstseg) {
 598                if (rtlhal->earlymode_enable) {
 599                        SET_TX_DESC_PKT_OFFSET(pdesc, 1);
 600                        SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN +
 601                                           EM_HDR_LEN);
 602                        if (ptcb_desc->empkt_num) {
 603                                RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD,
 604                                         "Insert 8 byte.pTcb->EMPktNum:%d\n",
 605                                         ptcb_desc->empkt_num);
 606                                _rtl92de_insert_emcontent(ptcb_desc,
 607                                                          (u8 *)(skb->data));
 608                        }
 609                } else {
 610                        SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
 611                }
 612                /* 5G have no CCK rate */
 613                if (rtlhal->current_bandtype == BAND_ON_5G)
 614                        if (ptcb_desc->hw_rate < DESC_RATE6M)
 615                                ptcb_desc->hw_rate = DESC_RATE6M;
 616                SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
 617                if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
 618                        SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
 619
 620                if (rtlhal->macphymode == DUALMAC_DUALPHY &&
 621                        ptcb_desc->hw_rate == DESC_RATEMCS7)
 622                        SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
 623
 624                if (info->flags & IEEE80211_TX_CTL_AMPDU) {
 625                        SET_TX_DESC_AGG_ENABLE(pdesc, 1);
 626                        SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
 627                }
 628                SET_TX_DESC_SEQ(pdesc, seq_number);
 629                SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
 630                                       !ptcb_desc->cts_enable) ? 1 : 0));
 631                SET_TX_DESC_HW_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable
 632                                          || ptcb_desc->cts_enable) ? 1 : 0));
 633                SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0));
 634                SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
 635                /* 5G have no CCK rate */
 636                if (rtlhal->current_bandtype == BAND_ON_5G)
 637                        if (ptcb_desc->rts_rate < DESC_RATE6M)
 638                                ptcb_desc->rts_rate = DESC_RATE6M;
 639                SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
 640                SET_TX_DESC_RTS_BW(pdesc, 0);
 641                SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
 642                SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
 643                        DESC_RATE54M) ?
 644                        (ptcb_desc->rts_use_shortpreamble ? 1 : 0) :
 645                        (ptcb_desc->rts_use_shortgi ? 1 : 0)));
 646                if (bw_40) {
 647                        if (ptcb_desc->packet_bw) {
 648                                SET_TX_DESC_DATA_BW(pdesc, 1);
 649                                SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
 650                        } else {
 651                                SET_TX_DESC_DATA_BW(pdesc, 0);
 652                                SET_TX_DESC_TX_SUB_CARRIER(pdesc,
 653                                                        mac->cur_40_prime_sc);
 654                        }
 655                } else {
 656                        SET_TX_DESC_DATA_BW(pdesc, 0);
 657                        SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
 658                }
 659                SET_TX_DESC_LINIP(pdesc, 0);
 660                SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb_len);
 661                if (sta) {
 662                        u8 ampdu_density = sta->ht_cap.ampdu_density;
 663                        SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
 664                }
 665                if (info->control.hw_key) {
 666                        struct ieee80211_key_conf *keyconf;
 667
 668                        keyconf = info->control.hw_key;
 669                        switch (keyconf->cipher) {
 670                        case WLAN_CIPHER_SUITE_WEP40:
 671                        case WLAN_CIPHER_SUITE_WEP104:
 672                        case WLAN_CIPHER_SUITE_TKIP:
 673                                SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
 674                                break;
 675                        case WLAN_CIPHER_SUITE_CCMP:
 676                                SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
 677                                break;
 678                        default:
 679                                SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
 680                                break;
 681
 682                        }
 683                }
 684                SET_TX_DESC_PKT_ID(pdesc, 0);
 685                SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
 686                SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
 687                SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
 688                SET_TX_DESC_DISABLE_FB(pdesc, ptcb_desc->disable_ratefallback ?
 689                                       1 : 0);
 690                SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
 691
 692                /* Set TxRate and RTSRate in TxDesc  */
 693                /* This prevent Tx initial rate of new-coming packets */
 694                /* from being overwritten by retried  packet rate.*/
 695                if (!ptcb_desc->use_driver_rate) {
 696                        SET_TX_DESC_RTS_RATE(pdesc, 0x08);
 697                        /* SET_TX_DESC_TX_RATE(pdesc, 0x0b); */
 698                }
 699                if (ieee80211_is_data_qos(fc)) {
 700                        if (mac->rdg_en) {
 701                                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 702                                         "Enable RDG function\n");
 703                                SET_TX_DESC_RDG_ENABLE(pdesc, 1);
 704                                SET_TX_DESC_HTC(pdesc, 1);
 705                        }
 706                }
 707        }
 708
 709        SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
 710        SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
 711        SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) buf_len);
 712        SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 713        if (rtlpriv->dm.useramask) {
 714                SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index);
 715                SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
 716        } else {
 717                SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index);
 718                SET_TX_DESC_MACID(pdesc, ptcb_desc->ratr_index);
 719        }
 720        if (ieee80211_is_data_qos(fc))
 721                SET_TX_DESC_QOS(pdesc, 1);
 722
 723        if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
 724                SET_TX_DESC_HWSEQ_EN(pdesc, 1);
 725                SET_TX_DESC_PKT_ID(pdesc, 8);
 726        }
 727        SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
 728        RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
 729}
 730
 731void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
 732                             u8 *pdesc, bool firstseg,
 733                             bool lastseg, struct sk_buff *skb)
 734{
 735        struct rtl_priv *rtlpriv = rtl_priv(hw);
 736        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 737        struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
 738        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 739        u8 fw_queue = QSLT_BEACON;
 740        dma_addr_t mapping = pci_map_single(rtlpci->pdev,
 741                    skb->data, skb->len, PCI_DMA_TODEVICE);
 742        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
 743        __le16 fc = hdr->frame_control;
 744
 745        if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
 746                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 747                         "DMA mapping error");
 748                return;
 749        }
 750        CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
 751        if (firstseg)
 752                SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
 753        /* 5G have no CCK rate
 754         * Caution: The macros below are multi-line expansions.
 755         * The braces are needed no matter what checkpatch says
 756         */
 757        if (rtlhal->current_bandtype == BAND_ON_5G) {
 758                SET_TX_DESC_TX_RATE(pdesc, DESC_RATE6M);
 759        } else {
 760                SET_TX_DESC_TX_RATE(pdesc, DESC_RATE1M);
 761        }
 762        SET_TX_DESC_SEQ(pdesc, 0);
 763        SET_TX_DESC_LINIP(pdesc, 0);
 764        SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
 765        SET_TX_DESC_FIRST_SEG(pdesc, 1);
 766        SET_TX_DESC_LAST_SEG(pdesc, 1);
 767        SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)skb->len);
 768        SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 769        SET_TX_DESC_RATE_ID(pdesc, 7);
 770        SET_TX_DESC_MACID(pdesc, 0);
 771        SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len));
 772        SET_TX_DESC_FIRST_SEG(pdesc, 1);
 773        SET_TX_DESC_LAST_SEG(pdesc, 1);
 774        SET_TX_DESC_OFFSET(pdesc, 0x20);
 775        SET_TX_DESC_USE_RATE(pdesc, 1);
 776
 777        if (!ieee80211_is_data_qos(fc) && ppsc->fwctrl_lps) {
 778                SET_TX_DESC_HWSEQ_EN(pdesc, 1);
 779                SET_TX_DESC_PKT_ID(pdesc, 8);
 780        }
 781
 782        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
 783                      "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
 784        wmb();
 785        SET_TX_DESC_OWN(pdesc, 1);
 786}
 787
 788void rtl92de_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
 789                      u8 desc_name, u8 *val)
 790{
 791        if (istx) {
 792                switch (desc_name) {
 793                case HW_DESC_OWN:
 794                        wmb();
 795                        SET_TX_DESC_OWN(pdesc, 1);
 796                        break;
 797                case HW_DESC_TX_NEXTDESC_ADDR:
 798                        SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
 799                        break;
 800                default:
 801                        RT_ASSERT(false, "ERR txdesc :%d not process\n",
 802                                  desc_name);
 803                        break;
 804                }
 805        } else {
 806                switch (desc_name) {
 807                case HW_DESC_RXOWN:
 808                        wmb();
 809                        SET_RX_DESC_OWN(pdesc, 1);
 810                        break;
 811                case HW_DESC_RXBUFF_ADDR:
 812                        SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
 813                        break;
 814                case HW_DESC_RXPKT_LEN:
 815                        SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
 816                        break;
 817                case HW_DESC_RXERO:
 818                        SET_RX_DESC_EOR(pdesc, 1);
 819                        break;
 820                default:
 821                        RT_ASSERT(false, "ERR rxdesc :%d not process\n",
 822                                  desc_name);
 823                        break;
 824                }
 825        }
 826}
 827
 828u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name)
 829{
 830        u32 ret = 0;
 831
 832        if (istx) {
 833                switch (desc_name) {
 834                case HW_DESC_OWN:
 835                        ret = GET_TX_DESC_OWN(p_desc);
 836                        break;
 837                case HW_DESC_TXBUFF_ADDR:
 838                        ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
 839                        break;
 840                default:
 841                        RT_ASSERT(false, "ERR txdesc :%d not process\n",
 842                                  desc_name);
 843                        break;
 844                }
 845        } else {
 846                struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
 847                switch (desc_name) {
 848                case HW_DESC_OWN:
 849                        ret = GET_RX_DESC_OWN(pdesc);
 850                        break;
 851                case HW_DESC_RXPKT_LEN:
 852                        ret = GET_RX_DESC_PKT_LEN(pdesc);
 853                        break;
 854                default:
 855                        RT_ASSERT(false, "ERR rxdesc :%d not process\n",
 856                                  desc_name);
 857                        break;
 858                }
 859        }
 860        return ret;
 861}
 862
 863void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
 864{
 865        struct rtl_priv *rtlpriv = rtl_priv(hw);
 866        if (hw_queue == BEACON_QUEUE)
 867                rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
 868        else
 869                rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
 870                               BIT(0) << (hw_queue));
 871}
 872