linux/drivers/net/wireless/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 >= DESC92_RATEMCS8 &&
 239                    pdesc->rxmcs <= DESC92_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        rx_status->freq = hw->conf.chandef.chan->center_freq;
 503        rx_status->band = hw->conf.chandef.chan->band;
 504        if (GET_RX_DESC_CRC32(pdesc))
 505                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
 506        if (!GET_RX_DESC_SWDEC(pdesc))
 507                rx_status->flag |= RX_FLAG_DECRYPTED;
 508        if (GET_RX_DESC_BW(pdesc))
 509                rx_status->flag |= RX_FLAG_40MHZ;
 510        if (GET_RX_DESC_RXHT(pdesc))
 511                rx_status->flag |= RX_FLAG_HT;
 512        rx_status->flag |= RX_FLAG_MACTIME_START;
 513        if (stats->decrypted)
 514                rx_status->flag |= RX_FLAG_DECRYPTED;
 515        rx_status->rate_idx = rtlwifi_rate_mapping(hw,
 516                                        (bool)GET_RX_DESC_RXHT(pdesc),
 517                                        (u8)GET_RX_DESC_RXMCS(pdesc),
 518                                        (bool)GET_RX_DESC_PAGGR(pdesc));
 519        rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
 520        if (phystatus) {
 521                p_drvinfo = (struct rx_fwinfo_92d *)(skb->data +
 522                                                     stats->rx_bufshift);
 523                _rtl92de_translate_rx_signal_stuff(hw,
 524                                                   skb, stats, pdesc,
 525                                                   p_drvinfo);
 526        }
 527        /*rx_status->qual = stats->signal; */
 528        rx_status->signal = stats->recvsignalpower + 10;
 529        return true;
 530}
 531
 532static void _rtl92de_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
 533                                      u8 *virtualaddress)
 534{
 535        memset(virtualaddress, 0, 8);
 536
 537        SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num);
 538        SET_EARLYMODE_LEN0(virtualaddress, ptcb_desc->empkt_len[0]);
 539        SET_EARLYMODE_LEN1(virtualaddress, ptcb_desc->empkt_len[1]);
 540        SET_EARLYMODE_LEN2_1(virtualaddress, ptcb_desc->empkt_len[2] & 0xF);
 541        SET_EARLYMODE_LEN2_2(virtualaddress, ptcb_desc->empkt_len[2] >> 4);
 542        SET_EARLYMODE_LEN3(virtualaddress, ptcb_desc->empkt_len[3]);
 543        SET_EARLYMODE_LEN4(virtualaddress, ptcb_desc->empkt_len[4]);
 544}
 545
 546void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
 547                          struct ieee80211_hdr *hdr, u8 *pdesc_tx,
 548                          u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
 549                          struct ieee80211_sta *sta,
 550                          struct sk_buff *skb,
 551                          u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
 552{
 553        struct rtl_priv *rtlpriv = rtl_priv(hw);
 554        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 555        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 556        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 557        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 558        u8 *pdesc = pdesc_tx;
 559        u16 seq_number;
 560        __le16 fc = hdr->frame_control;
 561        unsigned int buf_len = 0;
 562        unsigned int skb_len = skb->len;
 563        u8 fw_qsel = _rtl92de_map_hwqueue_to_fwqueue(skb, hw_queue);
 564        bool firstseg = ((hdr->seq_ctrl &
 565                        cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
 566        bool lastseg = ((hdr->frame_control &
 567                        cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
 568        dma_addr_t mapping;
 569        u8 bw_40 = 0;
 570
 571        if (mac->opmode == NL80211_IFTYPE_STATION) {
 572                bw_40 = mac->bw_40;
 573        } else if (mac->opmode == NL80211_IFTYPE_AP ||
 574                mac->opmode == NL80211_IFTYPE_ADHOC) {
 575                if (sta)
 576                        bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
 577        }
 578        seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
 579        rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
 580        /* reserve 8 byte for AMPDU early mode */
 581        if (rtlhal->earlymode_enable) {
 582                skb_push(skb, EM_HDR_LEN);
 583                memset(skb->data, 0, EM_HDR_LEN);
 584        }
 585        buf_len = skb->len;
 586        mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
 587                                 PCI_DMA_TODEVICE);
 588        if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
 589                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 590                         "DMA mapping error");
 591                return;
 592        }
 593        CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92d));
 594        if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
 595                firstseg = true;
 596                lastseg = true;
 597        }
 598        if (firstseg) {
 599                if (rtlhal->earlymode_enable) {
 600                        SET_TX_DESC_PKT_OFFSET(pdesc, 1);
 601                        SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN +
 602                                           EM_HDR_LEN);
 603                        if (ptcb_desc->empkt_num) {
 604                                RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD,
 605                                         "Insert 8 byte.pTcb->EMPktNum:%d\n",
 606                                         ptcb_desc->empkt_num);
 607                                _rtl92de_insert_emcontent(ptcb_desc,
 608                                                          (u8 *)(skb->data));
 609                        }
 610                } else {
 611                        SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
 612                }
 613                /* 5G have no CCK rate */
 614                if (rtlhal->current_bandtype == BAND_ON_5G)
 615                        if (ptcb_desc->hw_rate < DESC92_RATE6M)
 616                                ptcb_desc->hw_rate = DESC92_RATE6M;
 617                SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
 618                if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
 619                        SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
 620
 621                if (rtlhal->macphymode == DUALMAC_DUALPHY &&
 622                        ptcb_desc->hw_rate == DESC92_RATEMCS7)
 623                        SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
 624
 625                if (info->flags & IEEE80211_TX_CTL_AMPDU) {
 626                        SET_TX_DESC_AGG_ENABLE(pdesc, 1);
 627                        SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
 628                }
 629                SET_TX_DESC_SEQ(pdesc, seq_number);
 630                SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
 631                                       !ptcb_desc->cts_enable) ? 1 : 0));
 632                SET_TX_DESC_HW_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable
 633                                          || ptcb_desc->cts_enable) ? 1 : 0));
 634                SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0));
 635                SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
 636                /* 5G have no CCK rate */
 637                if (rtlhal->current_bandtype == BAND_ON_5G)
 638                        if (ptcb_desc->rts_rate < DESC92_RATE6M)
 639                                ptcb_desc->rts_rate = DESC92_RATE6M;
 640                SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
 641                SET_TX_DESC_RTS_BW(pdesc, 0);
 642                SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
 643                SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
 644                        DESC92_RATE54M) ?
 645                        (ptcb_desc->rts_use_shortpreamble ? 1 : 0) :
 646                        (ptcb_desc->rts_use_shortgi ? 1 : 0)));
 647                if (bw_40) {
 648                        if (ptcb_desc->packet_bw) {
 649                                SET_TX_DESC_DATA_BW(pdesc, 1);
 650                                SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
 651                        } else {
 652                                SET_TX_DESC_DATA_BW(pdesc, 0);
 653                                SET_TX_DESC_TX_SUB_CARRIER(pdesc,
 654                                                        mac->cur_40_prime_sc);
 655                        }
 656                } else {
 657                        SET_TX_DESC_DATA_BW(pdesc, 0);
 658                        SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
 659                }
 660                SET_TX_DESC_LINIP(pdesc, 0);
 661                SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb_len);
 662                if (sta) {
 663                        u8 ampdu_density = sta->ht_cap.ampdu_density;
 664                        SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
 665                }
 666                if (info->control.hw_key) {
 667                        struct ieee80211_key_conf *keyconf;
 668
 669                        keyconf = info->control.hw_key;
 670                        switch (keyconf->cipher) {
 671                        case WLAN_CIPHER_SUITE_WEP40:
 672                        case WLAN_CIPHER_SUITE_WEP104:
 673                        case WLAN_CIPHER_SUITE_TKIP:
 674                                SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
 675                                break;
 676                        case WLAN_CIPHER_SUITE_CCMP:
 677                                SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
 678                                break;
 679                        default:
 680                                SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
 681                                break;
 682
 683                        }
 684                }
 685                SET_TX_DESC_PKT_ID(pdesc, 0);
 686                SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
 687                SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
 688                SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
 689                SET_TX_DESC_DISABLE_FB(pdesc, ptcb_desc->disable_ratefallback ?
 690                                       1 : 0);
 691                SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
 692
 693                /* Set TxRate and RTSRate in TxDesc  */
 694                /* This prevent Tx initial rate of new-coming packets */
 695                /* from being overwritten by retried  packet rate.*/
 696                if (!ptcb_desc->use_driver_rate) {
 697                        SET_TX_DESC_RTS_RATE(pdesc, 0x08);
 698                        /* SET_TX_DESC_TX_RATE(pdesc, 0x0b); */
 699                }
 700                if (ieee80211_is_data_qos(fc)) {
 701                        if (mac->rdg_en) {
 702                                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 703                                         "Enable RDG function\n");
 704                                SET_TX_DESC_RDG_ENABLE(pdesc, 1);
 705                                SET_TX_DESC_HTC(pdesc, 1);
 706                        }
 707                }
 708        }
 709
 710        SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
 711        SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
 712        SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) buf_len);
 713        SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 714        if (rtlpriv->dm.useramask) {
 715                SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index);
 716                SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
 717        } else {
 718                SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index);
 719                SET_TX_DESC_MACID(pdesc, ptcb_desc->ratr_index);
 720        }
 721        if (ieee80211_is_data_qos(fc))
 722                SET_TX_DESC_QOS(pdesc, 1);
 723
 724        if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
 725                SET_TX_DESC_HWSEQ_EN(pdesc, 1);
 726                SET_TX_DESC_PKT_ID(pdesc, 8);
 727        }
 728        SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
 729        RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
 730}
 731
 732void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
 733                             u8 *pdesc, bool firstseg,
 734                             bool lastseg, struct sk_buff *skb)
 735{
 736        struct rtl_priv *rtlpriv = rtl_priv(hw);
 737        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 738        struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
 739        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 740        u8 fw_queue = QSLT_BEACON;
 741        dma_addr_t mapping = pci_map_single(rtlpci->pdev,
 742                    skb->data, skb->len, PCI_DMA_TODEVICE);
 743        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
 744        __le16 fc = hdr->frame_control;
 745
 746        if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
 747                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 748                         "DMA mapping error");
 749                return;
 750        }
 751        CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
 752        if (firstseg)
 753                SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
 754        /* 5G have no CCK rate
 755         * Caution: The macros below are multi-line expansions.
 756         * The braces are needed no matter what checkpatch says
 757         */
 758        if (rtlhal->current_bandtype == BAND_ON_5G) {
 759                SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE6M);
 760        } else {
 761                SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M);
 762        }
 763        SET_TX_DESC_SEQ(pdesc, 0);
 764        SET_TX_DESC_LINIP(pdesc, 0);
 765        SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
 766        SET_TX_DESC_FIRST_SEG(pdesc, 1);
 767        SET_TX_DESC_LAST_SEG(pdesc, 1);
 768        SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)skb->len);
 769        SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 770        SET_TX_DESC_RATE_ID(pdesc, 7);
 771        SET_TX_DESC_MACID(pdesc, 0);
 772        SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len));
 773        SET_TX_DESC_FIRST_SEG(pdesc, 1);
 774        SET_TX_DESC_LAST_SEG(pdesc, 1);
 775        SET_TX_DESC_OFFSET(pdesc, 0x20);
 776        SET_TX_DESC_USE_RATE(pdesc, 1);
 777
 778        if (!ieee80211_is_data_qos(fc) && ppsc->fwctrl_lps) {
 779                SET_TX_DESC_HWSEQ_EN(pdesc, 1);
 780                SET_TX_DESC_PKT_ID(pdesc, 8);
 781        }
 782
 783        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
 784                      "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
 785        wmb();
 786        SET_TX_DESC_OWN(pdesc, 1);
 787}
 788
 789void rtl92de_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
 790                      u8 desc_name, u8 *val)
 791{
 792        if (istx) {
 793                switch (desc_name) {
 794                case HW_DESC_OWN:
 795                        wmb();
 796                        SET_TX_DESC_OWN(pdesc, 1);
 797                        break;
 798                case HW_DESC_TX_NEXTDESC_ADDR:
 799                        SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
 800                        break;
 801                default:
 802                        RT_ASSERT(false, "ERR txdesc :%d not process\n",
 803                                  desc_name);
 804                        break;
 805                }
 806        } else {
 807                switch (desc_name) {
 808                case HW_DESC_RXOWN:
 809                        wmb();
 810                        SET_RX_DESC_OWN(pdesc, 1);
 811                        break;
 812                case HW_DESC_RXBUFF_ADDR:
 813                        SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
 814                        break;
 815                case HW_DESC_RXPKT_LEN:
 816                        SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
 817                        break;
 818                case HW_DESC_RXERO:
 819                        SET_RX_DESC_EOR(pdesc, 1);
 820                        break;
 821                default:
 822                        RT_ASSERT(false, "ERR rxdesc :%d not process\n",
 823                                  desc_name);
 824                        break;
 825                }
 826        }
 827}
 828
 829u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name)
 830{
 831        u32 ret = 0;
 832
 833        if (istx) {
 834                switch (desc_name) {
 835                case HW_DESC_OWN:
 836                        ret = GET_TX_DESC_OWN(p_desc);
 837                        break;
 838                case HW_DESC_TXBUFF_ADDR:
 839                        ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
 840                        break;
 841                default:
 842                        RT_ASSERT(false, "ERR txdesc :%d not process\n",
 843                                  desc_name);
 844                        break;
 845                }
 846        } else {
 847                struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
 848                switch (desc_name) {
 849                case HW_DESC_OWN:
 850                        ret = GET_RX_DESC_OWN(pdesc);
 851                        break;
 852                case HW_DESC_RXPKT_LEN:
 853                        ret = GET_RX_DESC_PKT_LEN(pdesc);
 854                        break;
 855                default:
 856                        RT_ASSERT(false, "ERR rxdesc :%d not process\n",
 857                                  desc_name);
 858                        break;
 859                }
 860        }
 861        return ret;
 862}
 863
 864void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
 865{
 866        struct rtl_priv *rtlpriv = rtl_priv(hw);
 867        if (hw_queue == BEACON_QUEUE)
 868                rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
 869        else
 870                rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
 871                               BIT(0) << (hw_queue));
 872}
 873