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