linux/drivers/net/wireless/rtlwifi/rtl8192se/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 "fw.h"
  37#include "trx.h"
  38#include "led.h"
  39
  40static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb,  u8 skb_queue)
  41{
  42        __le16 fc = rtl_get_fc(skb);
  43
  44        if (unlikely(ieee80211_is_beacon(fc)))
  45                return QSLT_BEACON;
  46        if (ieee80211_is_mgmt(fc))
  47                return QSLT_MGNT;
  48        if (ieee80211_is_nullfunc(fc))
  49                return QSLT_HIGH;
  50
  51        return skb->priority;
  52}
  53
  54static u8 _rtl92s_query_rxpwrpercentage(char antpower)
  55{
  56        if ((antpower <= -100) || (antpower >= 20))
  57                return 0;
  58        else if (antpower >= 0)
  59                return 100;
  60        else
  61                return 100 + antpower;
  62}
  63
  64static u8 _rtl92s_evm_db_to_percentage(char value)
  65{
  66        char ret_val;
  67        ret_val = value;
  68
  69        if (ret_val >= 0)
  70                ret_val = 0;
  71
  72        if (ret_val <= -33)
  73                ret_val = -33;
  74
  75        ret_val = 0 - ret_val;
  76        ret_val *= 3;
  77
  78        if (ret_val == 99)
  79                ret_val = 100;
  80
  81        return ret_val;
  82}
  83
  84static long _rtl92se_translate_todbm(struct ieee80211_hw *hw,
  85                                     u8 signal_strength_index)
  86{
  87        long signal_power;
  88
  89        signal_power = (long)((signal_strength_index + 1) >> 1);
  90        signal_power -= 95;
  91        return signal_power;
  92}
  93
  94static long _rtl92se_signal_scale_mapping(struct ieee80211_hw *hw,
  95                long currsig)
  96{
  97        long retsig = 0;
  98
  99        /* Step 1. Scale mapping. */
 100        if (currsig > 47)
 101                retsig = 100;
 102        else if (currsig > 14 && currsig <= 47)
 103                retsig = 100 - ((47 - currsig) * 3) / 2;
 104        else if (currsig > 2 && currsig <= 14)
 105                retsig = 48 - ((14 - currsig) * 15) / 7;
 106        else if (currsig >= 0)
 107                retsig = currsig * 9 + 1;
 108
 109        return retsig;
 110}
 111
 112
 113static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
 114                                       struct rtl_stats *pstats, u8 *pdesc,
 115                                       struct rx_fwinfo *p_drvinfo,
 116                                       bool packet_match_bssid,
 117                                       bool packet_toself,
 118                                       bool packet_beacon)
 119{
 120        struct rtl_priv *rtlpriv = rtl_priv(hw);
 121        struct phy_sts_cck_8192s_t *cck_buf;
 122        s8 rx_pwr_all = 0, rx_pwr[4];
 123        u8 rf_rx_num = 0, evm, pwdb_all;
 124        u8 i, max_spatial_stream;
 125        u32 rssi, total_rssi = 0;
 126        bool in_powersavemode = false;
 127        bool is_cck = pstats->is_cck;
 128
 129        pstats->packet_matchbssid = packet_match_bssid;
 130        pstats->packet_toself = packet_toself;
 131        pstats->packet_beacon = packet_beacon;
 132        pstats->rx_mimo_sig_qual[0] = -1;
 133        pstats->rx_mimo_sig_qual[1] = -1;
 134
 135        if (is_cck) {
 136                u8 report, cck_highpwr;
 137                cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
 138
 139                if (!in_powersavemode)
 140                        cck_highpwr = (u8) rtl_get_bbreg(hw,
 141                                                RFPGA0_XA_HSSIPARAMETER2,
 142                                                0x200);
 143                else
 144                        cck_highpwr = false;
 145
 146                if (!cck_highpwr) {
 147                        u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 148                        report = cck_buf->cck_agc_rpt & 0xc0;
 149                        report = report >> 6;
 150                        switch (report) {
 151                        case 0x3:
 152                                rx_pwr_all = -40 - (cck_agc_rpt & 0x3e);
 153                                break;
 154                        case 0x2:
 155                                rx_pwr_all = -20 - (cck_agc_rpt & 0x3e);
 156                                break;
 157                        case 0x1:
 158                                rx_pwr_all = -2 - (cck_agc_rpt & 0x3e);
 159                                break;
 160                        case 0x0:
 161                                rx_pwr_all = 14 - (cck_agc_rpt & 0x3e);
 162                                break;
 163                        }
 164                } else {
 165                        u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 166                        report = p_drvinfo->cfosho[0] & 0x60;
 167                        report = report >> 5;
 168                        switch (report) {
 169                        case 0x3:
 170                                rx_pwr_all = -40 - ((cck_agc_rpt & 0x1f) << 1);
 171                                break;
 172                        case 0x2:
 173                                rx_pwr_all = -20 - ((cck_agc_rpt & 0x1f) << 1);
 174                                break;
 175                        case 0x1:
 176                                rx_pwr_all = -2 - ((cck_agc_rpt & 0x1f) << 1);
 177                                break;
 178                        case 0x0:
 179                                rx_pwr_all = 14 - ((cck_agc_rpt & 0x1f) << 1);
 180                                break;
 181                        }
 182                }
 183
 184                pwdb_all = _rtl92s_query_rxpwrpercentage(rx_pwr_all);
 185
 186                /* CCK gain is smaller than OFDM/MCS gain,  */
 187                /* so we add gain diff by experiences, the val is 6 */
 188                pwdb_all += 6;
 189                if (pwdb_all > 100)
 190                        pwdb_all = 100;
 191                /* modify the offset to make the same gain index with OFDM. */
 192                if (pwdb_all > 34 && pwdb_all <= 42)
 193                        pwdb_all -= 2;
 194                else if (pwdb_all > 26 && pwdb_all <= 34)
 195                        pwdb_all -= 6;
 196                else if (pwdb_all > 14 && pwdb_all <= 26)
 197                        pwdb_all -= 8;
 198                else if (pwdb_all > 4 && pwdb_all <= 14)
 199                        pwdb_all -= 4;
 200
 201                pstats->rx_pwdb_all = pwdb_all;
 202                pstats->recvsignalpower = rx_pwr_all;
 203
 204                if (packet_match_bssid) {
 205                        u8 sq;
 206                        if (pstats->rx_pwdb_all > 40) {
 207                                sq = 100;
 208                        } else {
 209                                sq = cck_buf->sq_rpt;
 210                                if (sq > 64)
 211                                        sq = 0;
 212                                else if (sq < 20)
 213                                        sq = 100;
 214                                else
 215                                        sq = ((64 - sq) * 100) / 44;
 216                        }
 217
 218                        pstats->signalquality = sq;
 219                        pstats->rx_mimo_sig_qual[0] = sq;
 220                        pstats->rx_mimo_sig_qual[1] = -1;
 221                }
 222        } else {
 223                rtlpriv->dm.rfpath_rxenable[0] =
 224                    rtlpriv->dm.rfpath_rxenable[1] = true;
 225                for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
 226                        if (rtlpriv->dm.rfpath_rxenable[i])
 227                                rf_rx_num++;
 228
 229                        rx_pwr[i] = ((p_drvinfo->gain_trsw[i] &
 230                                    0x3f) * 2) - 110;
 231                        rssi = _rtl92s_query_rxpwrpercentage(rx_pwr[i]);
 232                        total_rssi += rssi;
 233                        rtlpriv->stats.rx_snr_db[i] =
 234                                         (long)(p_drvinfo->rxsnr[i] / 2);
 235
 236                        if (packet_match_bssid)
 237                                pstats->rx_mimo_signalstrength[i] = (u8) rssi;
 238                }
 239
 240                rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
 241                pwdb_all = _rtl92s_query_rxpwrpercentage(rx_pwr_all);
 242                pstats->rx_pwdb_all = pwdb_all;
 243                pstats->rxpower = rx_pwr_all;
 244                pstats->recvsignalpower = rx_pwr_all;
 245
 246                if (pstats->is_ht && pstats->rate >= DESC92_RATEMCS8 &&
 247                    pstats->rate <= DESC92_RATEMCS15)
 248                        max_spatial_stream = 2;
 249                else
 250                        max_spatial_stream = 1;
 251
 252                for (i = 0; i < max_spatial_stream; i++) {
 253                        evm = _rtl92s_evm_db_to_percentage(p_drvinfo->rxevm[i]);
 254
 255                        if (packet_match_bssid) {
 256                                if (i == 0)
 257                                        pstats->signalquality = (u8)(evm &
 258                                                                 0xff);
 259                                pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff);
 260                        }
 261                }
 262        }
 263
 264        if (is_cck)
 265                pstats->signalstrength = (u8)(_rtl92se_signal_scale_mapping(hw,
 266                                         pwdb_all));
 267        else if (rf_rx_num != 0)
 268                pstats->signalstrength = (u8) (_rtl92se_signal_scale_mapping(hw,
 269                                total_rssi /= rf_rx_num));
 270}
 271
 272static void _rtl92se_process_ui_rssi(struct ieee80211_hw *hw,
 273                                     struct rtl_stats *pstats)
 274{
 275        struct rtl_priv *rtlpriv = rtl_priv(hw);
 276        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 277        u8 rfpath;
 278        u32 last_rssi, tmpval;
 279
 280        if (pstats->packet_toself || pstats->packet_beacon) {
 281                rtlpriv->stats.rssi_calculate_cnt++;
 282
 283                if (rtlpriv->stats.ui_rssi.total_num++ >=
 284                    PHY_RSSI_SLID_WIN_MAX) {
 285                        rtlpriv->stats.ui_rssi.total_num =
 286                                         PHY_RSSI_SLID_WIN_MAX;
 287                        last_rssi = rtlpriv->stats.ui_rssi.elements[
 288                                rtlpriv->stats.ui_rssi.index];
 289                        rtlpriv->stats.ui_rssi.total_val -= last_rssi;
 290                }
 291
 292                rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
 293                rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++]
 294                         = pstats->signalstrength;
 295
 296                if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
 297                        rtlpriv->stats.ui_rssi.index = 0;
 298
 299                tmpval = rtlpriv->stats.ui_rssi.total_val /
 300                        rtlpriv->stats.ui_rssi.total_num;
 301                rtlpriv->stats.signal_strength = _rtl92se_translate_todbm(hw,
 302                                                                (u8) tmpval);
 303                pstats->rssi = rtlpriv->stats.signal_strength;
 304        }
 305
 306        if (!pstats->is_cck && pstats->packet_toself) {
 307                for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
 308                     rfpath++) {
 309                        if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
 310                                rtlpriv->stats.rx_rssi_percentage[rfpath] =
 311                                    pstats->rx_mimo_signalstrength[rfpath];
 312
 313                        }
 314
 315                        if (pstats->rx_mimo_signalstrength[rfpath] >
 316                            rtlpriv->stats.rx_rssi_percentage[rfpath]) {
 317                                rtlpriv->stats.rx_rssi_percentage[rfpath] =
 318                                    ((rtlpriv->stats.rx_rssi_percentage[rfpath]
 319                                    * (RX_SMOOTH_FACTOR - 1)) +
 320                                    (pstats->rx_mimo_signalstrength[rfpath])) /
 321                                    (RX_SMOOTH_FACTOR);
 322
 323                                rtlpriv->stats.rx_rssi_percentage[rfpath] =
 324                                    rtlpriv->stats.rx_rssi_percentage[rfpath]
 325                                    + 1;
 326                        } else {
 327                                rtlpriv->stats.rx_rssi_percentage[rfpath] =
 328                                    ((rtlpriv->stats.rx_rssi_percentage[rfpath]
 329                                    * (RX_SMOOTH_FACTOR - 1)) +
 330                                    (pstats->rx_mimo_signalstrength[rfpath])) /
 331                                    (RX_SMOOTH_FACTOR);
 332                        }
 333
 334                }
 335        }
 336}
 337
 338static void _rtl92se_update_rxsignalstatistics(struct ieee80211_hw *hw,
 339                                               struct rtl_stats *pstats)
 340{
 341        struct rtl_priv *rtlpriv = rtl_priv(hw);
 342        int weighting = 0;
 343
 344        if (rtlpriv->stats.recv_signal_power == 0)
 345                rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
 346
 347        if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
 348                weighting = 5;
 349        else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
 350                weighting = (-5);
 351
 352        rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * 5
 353                                           + pstats->recvsignalpower +
 354                                           weighting) / 6;
 355}
 356
 357static void _rtl92se_process_pwdb(struct ieee80211_hw *hw,
 358                                  struct rtl_stats *pstats)
 359{
 360        struct rtl_priv *rtlpriv = rtl_priv(hw);
 361        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 362        long undec_sm_pwdb = 0;
 363
 364        if (mac->opmode == NL80211_IFTYPE_ADHOC) {
 365                return;
 366        } else {
 367                undec_sm_pwdb =
 368                    rtlpriv->dm.undec_sm_pwdb;
 369        }
 370
 371        if (pstats->packet_toself || pstats->packet_beacon) {
 372                if (undec_sm_pwdb < 0)
 373                        undec_sm_pwdb = pstats->rx_pwdb_all;
 374
 375                if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) {
 376                        undec_sm_pwdb =
 377                            (((undec_sm_pwdb) *
 378                            (RX_SMOOTH_FACTOR - 1)) +
 379                            (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
 380
 381                        undec_sm_pwdb = undec_sm_pwdb + 1;
 382                } else {
 383                        undec_sm_pwdb = (((undec_sm_pwdb) *
 384                              (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) /
 385                              (RX_SMOOTH_FACTOR);
 386                }
 387
 388                rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb;
 389                _rtl92se_update_rxsignalstatistics(hw, pstats);
 390        }
 391}
 392
 393static void rtl_92s_process_streams(struct ieee80211_hw *hw,
 394                                    struct rtl_stats *pstats)
 395{
 396        struct rtl_priv *rtlpriv = rtl_priv(hw);
 397        u32 stream;
 398
 399        for (stream = 0; stream < 2; stream++) {
 400                if (pstats->rx_mimo_sig_qual[stream] != -1) {
 401                        if (rtlpriv->stats.rx_evm_percentage[stream] == 0) {
 402                                rtlpriv->stats.rx_evm_percentage[stream] =
 403                                    pstats->rx_mimo_sig_qual[stream];
 404                        }
 405
 406                        rtlpriv->stats.rx_evm_percentage[stream] =
 407                            ((rtlpriv->stats.rx_evm_percentage[stream] *
 408                                        (RX_SMOOTH_FACTOR - 1)) +
 409                             (pstats->rx_mimo_sig_qual[stream] *
 410                                        1)) / (RX_SMOOTH_FACTOR);
 411                }
 412        }
 413}
 414
 415static void _rtl92se_process_ui_link_quality(struct ieee80211_hw *hw,
 416                                             struct rtl_stats *pstats)
 417{
 418        struct rtl_priv *rtlpriv = rtl_priv(hw);
 419        u32 last_evm = 0, tmpval;
 420
 421        if (pstats->signalquality != 0) {
 422                if (pstats->packet_toself || pstats->packet_beacon) {
 423
 424                        if (rtlpriv->stats.ui_link_quality.total_num++ >=
 425                            PHY_LINKQUALITY_SLID_WIN_MAX) {
 426                                rtlpriv->stats.ui_link_quality.total_num =
 427                                    PHY_LINKQUALITY_SLID_WIN_MAX;
 428                                last_evm =
 429                                    rtlpriv->stats.ui_link_quality.elements[
 430                                    rtlpriv->stats.ui_link_quality.index];
 431                                rtlpriv->stats.ui_link_quality.total_val -=
 432                                    last_evm;
 433                        }
 434
 435                        rtlpriv->stats.ui_link_quality.total_val +=
 436                            pstats->signalquality;
 437                        rtlpriv->stats.ui_link_quality.elements[
 438                                rtlpriv->stats.ui_link_quality.index++] =
 439                            pstats->signalquality;
 440
 441                        if (rtlpriv->stats.ui_link_quality.index >=
 442                            PHY_LINKQUALITY_SLID_WIN_MAX)
 443                                rtlpriv->stats.ui_link_quality.index = 0;
 444
 445                        tmpval = rtlpriv->stats.ui_link_quality.total_val /
 446                            rtlpriv->stats.ui_link_quality.total_num;
 447                        rtlpriv->stats.signal_quality = tmpval;
 448
 449                        rtlpriv->stats.last_sigstrength_inpercent = tmpval;
 450
 451                        rtl_92s_process_streams(hw, pstats);
 452
 453                }
 454        }
 455}
 456
 457static void _rtl92se_process_phyinfo(struct ieee80211_hw *hw,
 458                                     u8 *buffer,
 459                                     struct rtl_stats *pcurrent_stats)
 460{
 461
 462        if (!pcurrent_stats->packet_matchbssid &&
 463            !pcurrent_stats->packet_beacon)
 464                return;
 465
 466        _rtl92se_process_ui_rssi(hw, pcurrent_stats);
 467        _rtl92se_process_pwdb(hw, pcurrent_stats);
 468        _rtl92se_process_ui_link_quality(hw, pcurrent_stats);
 469}
 470
 471static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw,
 472                struct sk_buff *skb, struct rtl_stats *pstats,
 473                u8 *pdesc, struct rx_fwinfo *p_drvinfo)
 474{
 475        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 476        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 477
 478        struct ieee80211_hdr *hdr;
 479        u8 *tmp_buf;
 480        u8 *praddr;
 481        __le16 fc;
 482        u16 type, cfc;
 483        bool packet_matchbssid, packet_toself, packet_beacon = false;
 484
 485        tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
 486
 487        hdr = (struct ieee80211_hdr *)tmp_buf;
 488        fc = hdr->frame_control;
 489        cfc = le16_to_cpu(fc);
 490        type = WLAN_FC_GET_TYPE(fc);
 491        praddr = hdr->addr1;
 492
 493        packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
 494             ether_addr_equal(mac->bssid,
 495                              (cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
 496                              (cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
 497                              hdr->addr3) &&
 498             (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
 499
 500        packet_toself = packet_matchbssid &&
 501            ether_addr_equal(praddr, rtlefuse->dev_addr);
 502
 503        if (ieee80211_is_beacon(fc))
 504                packet_beacon = true;
 505
 506        _rtl92se_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
 507                        packet_matchbssid, packet_toself, packet_beacon);
 508        _rtl92se_process_phyinfo(hw, tmp_buf, pstats);
 509}
 510
 511bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
 512                           struct ieee80211_rx_status *rx_status, u8 *pdesc,
 513                           struct sk_buff *skb)
 514{
 515        struct rx_fwinfo *p_drvinfo;
 516        u32 phystatus = (u32)GET_RX_STATUS_DESC_PHY_STATUS(pdesc);
 517        struct ieee80211_hdr *hdr;
 518        bool first_ampdu = false;
 519
 520        stats->length = (u16)GET_RX_STATUS_DESC_PKT_LEN(pdesc);
 521        stats->rx_drvinfo_size = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE(pdesc) * 8;
 522        stats->rx_bufshift = (u8)(GET_RX_STATUS_DESC_SHIFT(pdesc) & 0x03);
 523        stats->icv = (u16)GET_RX_STATUS_DESC_ICV(pdesc);
 524        stats->crc = (u16)GET_RX_STATUS_DESC_CRC32(pdesc);
 525        stats->hwerror = (u16)(stats->crc | stats->icv);
 526        stats->decrypted = !GET_RX_STATUS_DESC_SWDEC(pdesc);
 527
 528        stats->rate = (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc);
 529        stats->shortpreamble = (u16)GET_RX_STATUS_DESC_SPLCP(pdesc);
 530        stats->isampdu = (bool)(GET_RX_STATUS_DESC_PAGGR(pdesc) == 1);
 531        stats->isfirst_ampdu = (bool) ((GET_RX_STATUS_DESC_PAGGR(pdesc) == 1)
 532                               && (GET_RX_STATUS_DESC_FAGGR(pdesc) == 1));
 533        stats->timestamp_low = GET_RX_STATUS_DESC_TSFL(pdesc);
 534        stats->rx_is40Mhzpacket = (bool)GET_RX_STATUS_DESC_BW(pdesc);
 535        stats->is_ht = (bool)GET_RX_STATUS_DESC_RX_HT(pdesc);
 536        stats->is_cck = SE_RX_HAL_IS_CCK_RATE(pdesc);
 537
 538        if (stats->hwerror)
 539                return false;
 540
 541        rx_status->freq = hw->conf.channel->center_freq;
 542        rx_status->band = hw->conf.channel->band;
 543
 544        hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size
 545              + stats->rx_bufshift);
 546
 547        if (stats->crc)
 548                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
 549
 550        if (stats->rx_is40Mhzpacket)
 551                rx_status->flag |= RX_FLAG_40MHZ;
 552
 553        if (stats->is_ht)
 554                rx_status->flag |= RX_FLAG_HT;
 555
 556        rx_status->flag |= RX_FLAG_MACTIME_START;
 557
 558        /* hw will set stats->decrypted true, if it finds the
 559         * frame is open data frame or mgmt frame,
 560         * hw will not decrypt robust managment frame
 561         * for IEEE80211w but still set stats->decrypted
 562         * true, so here we should set it back to undecrypted
 563         * for IEEE80211w frame, and mac80211 sw will help
 564         * to decrypt it */
 565        if (stats->decrypted) {
 566                if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
 567                        (ieee80211_has_protected(hdr->frame_control)))
 568                        rx_status->flag &= ~RX_FLAG_DECRYPTED;
 569                else
 570                        rx_status->flag |= RX_FLAG_DECRYPTED;
 571        }
 572
 573        rx_status->rate_idx = rtlwifi_rate_mapping(hw,
 574                              stats->is_ht, stats->rate, first_ampdu);
 575
 576        rx_status->mactime = stats->timestamp_low;
 577        if (phystatus) {
 578                p_drvinfo = (struct rx_fwinfo *)(skb->data +
 579                                                 stats->rx_bufshift);
 580                _rtl92se_translate_rx_signal_stuff(hw, skb, stats, pdesc,
 581                                                   p_drvinfo);
 582        }
 583
 584        /*rx_status->qual = stats->signal; */
 585        rx_status->signal = stats->rssi + 10;
 586        /*rx_status->noise = -stats->noise; */
 587
 588        return true;
 589}
 590
 591void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
 592                struct ieee80211_hdr *hdr, u8 *pdesc_tx,
 593                struct ieee80211_tx_info *info,
 594                struct ieee80211_sta *sta,
 595                struct sk_buff *skb,
 596                u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
 597{
 598        struct rtl_priv *rtlpriv = rtl_priv(hw);
 599        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 600        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 601        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 602        u8 *pdesc = pdesc_tx;
 603        u16 seq_number;
 604        __le16 fc = hdr->frame_control;
 605        u8 reserved_macid = 0;
 606        u8 fw_qsel = _rtl92se_map_hwqueue_to_fwqueue(skb, hw_queue);
 607        bool firstseg = (!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)));
 608        bool lastseg = (!(hdr->frame_control &
 609                        cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)));
 610        dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
 611                    PCI_DMA_TODEVICE);
 612        u8 bw_40 = 0;
 613
 614        if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
 615                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 616                         "DMA mapping error");
 617                return;
 618        }
 619        if (mac->opmode == NL80211_IFTYPE_STATION) {
 620                bw_40 = mac->bw_40;
 621        } else if (mac->opmode == NL80211_IFTYPE_AP ||
 622                mac->opmode == NL80211_IFTYPE_ADHOC) {
 623                if (sta)
 624                        bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
 625        }
 626
 627        seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
 628
 629        rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
 630
 631        CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE_RTL8192S);
 632
 633        if (firstseg) {
 634                if (rtlpriv->dm.useramask) {
 635                        /* set txdesc macId */
 636                        if (ptcb_desc->mac_id < 32) {
 637                                SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
 638                                reserved_macid |= ptcb_desc->mac_id;
 639                        }
 640                }
 641                SET_TX_DESC_RSVD_MACID(pdesc, reserved_macid);
 642
 643                SET_TX_DESC_TXHT(pdesc, ((ptcb_desc->hw_rate >=
 644                                 DESC92_RATEMCS0) ? 1 : 0));
 645
 646                if (rtlhal->version == VERSION_8192S_ACUT) {
 647                        if (ptcb_desc->hw_rate == DESC92_RATE1M ||
 648                                ptcb_desc->hw_rate  == DESC92_RATE2M ||
 649                                ptcb_desc->hw_rate == DESC92_RATE5_5M ||
 650                                ptcb_desc->hw_rate == DESC92_RATE11M) {
 651                                ptcb_desc->hw_rate = DESC92_RATE12M;
 652                        }
 653                }
 654
 655                SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
 656
 657                if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
 658                        SET_TX_DESC_TX_SHORT(pdesc, 0);
 659
 660                /* Aggregation related */
 661                if (info->flags & IEEE80211_TX_CTL_AMPDU)
 662                        SET_TX_DESC_AGG_ENABLE(pdesc, 1);
 663
 664                /* For AMPDU, we must insert SSN into TX_DESC */
 665                SET_TX_DESC_SEQ(pdesc, seq_number);
 666
 667                /* Protection mode related */
 668                /* For 92S, if RTS/CTS are set, HW will execute RTS. */
 669                /* We choose only one protection mode to execute */
 670                SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
 671                                !ptcb_desc->cts_enable) ? 1 : 0));
 672                SET_TX_DESC_CTS_ENABLE(pdesc, ((ptcb_desc->cts_enable) ?
 673                                       1 : 0));
 674                SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
 675
 676                SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
 677                SET_TX_DESC_RTS_BANDWIDTH(pdesc, 0);
 678                SET_TX_DESC_RTS_SUB_CARRIER(pdesc, ptcb_desc->rts_sc);
 679                SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
 680                       DESC92_RATE54M) ?
 681                       (ptcb_desc->rts_use_shortpreamble ? 1 : 0)
 682                       : (ptcb_desc->rts_use_shortgi ? 1 : 0)));
 683
 684
 685                /* Set Bandwidth and sub-channel settings. */
 686                if (bw_40) {
 687                        if (ptcb_desc->packet_bw) {
 688                                SET_TX_DESC_TX_BANDWIDTH(pdesc, 1);
 689                                /* use duplicated mode */
 690                                SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
 691                        } else {
 692                                SET_TX_DESC_TX_BANDWIDTH(pdesc, 0);
 693                                SET_TX_DESC_TX_SUB_CARRIER(pdesc,
 694                                                   mac->cur_40_prime_sc);
 695                        }
 696                } else {
 697                        SET_TX_DESC_TX_BANDWIDTH(pdesc, 0);
 698                        SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
 699                }
 700
 701                /* 3 Fill necessary field in First Descriptor */
 702                /*DWORD 0*/
 703                SET_TX_DESC_LINIP(pdesc, 0);
 704                SET_TX_DESC_OFFSET(pdesc, 32);
 705                SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
 706
 707                /*DWORD 1*/
 708                SET_TX_DESC_RA_BRSR_ID(pdesc, ptcb_desc->ratr_index);
 709
 710                /* Fill security related */
 711                if (info->control.hw_key) {
 712                        struct ieee80211_key_conf *keyconf;
 713
 714                        keyconf = info->control.hw_key;
 715                        switch (keyconf->cipher) {
 716                        case WLAN_CIPHER_SUITE_WEP40:
 717                        case WLAN_CIPHER_SUITE_WEP104:
 718                                SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
 719                                break;
 720                        case WLAN_CIPHER_SUITE_TKIP:
 721                                SET_TX_DESC_SEC_TYPE(pdesc, 0x2);
 722                                break;
 723                        case WLAN_CIPHER_SUITE_CCMP:
 724                                SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
 725                                break;
 726                        default:
 727                                SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
 728                                break;
 729
 730                        }
 731                }
 732
 733                /* Set Packet ID */
 734                SET_TX_DESC_PACKET_ID(pdesc, 0);
 735
 736                /* We will assign magement queue to BK. */
 737                SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
 738
 739                /* Alwasy enable all rate fallback range */
 740                SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
 741
 742                /* Fix: I don't kown why hw use 6.5M to tx when set it */
 743                SET_TX_DESC_USER_RATE(pdesc,
 744                                      ptcb_desc->use_driver_rate ? 1 : 0);
 745
 746                /* Set NON_QOS bit. */
 747                if (!ieee80211_is_data_qos(fc))
 748                        SET_TX_DESC_NON_QOS(pdesc, 1);
 749
 750        }
 751
 752        /* Fill fields that are required to be initialized
 753         * in all of the descriptors */
 754        /*DWORD 0 */
 755        SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
 756        SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
 757
 758        /* DWORD 7 */
 759        SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
 760
 761        /* DOWRD 8 */
 762        SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 763
 764        RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
 765}
 766
 767void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
 768        bool firstseg, bool lastseg, struct sk_buff *skb)
 769{
 770        struct rtl_priv *rtlpriv = rtl_priv(hw);
 771        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 772        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 773        struct rtl_tcb_desc *tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
 774
 775        dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
 776                        PCI_DMA_TODEVICE);
 777
 778        if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
 779                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 780                         "DMA mapping error");
 781                return;
 782        }
 783        /* Clear all status     */
 784        CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_CMDDESC_SIZE_RTL8192S);
 785
 786        /* This bit indicate this packet is used for FW download. */
 787        if (tcb_desc->cmd_or_init == DESC_PACKET_TYPE_INIT) {
 788                /* For firmware downlaod we only need to set LINIP */
 789                SET_TX_DESC_LINIP(pdesc, tcb_desc->last_inipkt);
 790
 791                /* 92SE must set as 1 for firmware download HW DMA error */
 792                SET_TX_DESC_FIRST_SEG(pdesc, 1);
 793                SET_TX_DESC_LAST_SEG(pdesc, 1);
 794
 795                /* 92SE need not to set TX packet size when firmware download */
 796                SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
 797                SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
 798                SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 799
 800                wmb();
 801                SET_TX_DESC_OWN(pdesc, 1);
 802        } else { /* H2C Command Desc format (Host TXCMD) */
 803                /* 92SE must set as 1 for firmware download HW DMA error */
 804                SET_TX_DESC_FIRST_SEG(pdesc, 1);
 805                SET_TX_DESC_LAST_SEG(pdesc, 1);
 806
 807                SET_TX_DESC_OFFSET(pdesc, 0x20);
 808
 809                /* Buffer size + command header */
 810                SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
 811                /* Fixed queue of H2C command */
 812                SET_TX_DESC_QUEUE_SEL(pdesc, 0x13);
 813
 814                SET_BITS_TO_LE_4BYTE(skb->data, 24, 7, rtlhal->h2c_txcmd_seq);
 815
 816                SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
 817                SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 818
 819                wmb();
 820                SET_TX_DESC_OWN(pdesc, 1);
 821
 822        }
 823}
 824
 825void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
 826{
 827        if (istx) {
 828                switch (desc_name) {
 829                case HW_DESC_OWN:
 830                        wmb();
 831                        SET_TX_DESC_OWN(pdesc, 1);
 832                        break;
 833                case HW_DESC_TX_NEXTDESC_ADDR:
 834                        SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
 835                        break;
 836                default:
 837                        RT_ASSERT(false, "ERR txdesc :%d not process\n",
 838                                  desc_name);
 839                        break;
 840                }
 841        } else {
 842                switch (desc_name) {
 843                case HW_DESC_RXOWN:
 844                        wmb();
 845                        SET_RX_STATUS_DESC_OWN(pdesc, 1);
 846                        break;
 847                case HW_DESC_RXBUFF_ADDR:
 848                        SET_RX_STATUS__DESC_BUFF_ADDR(pdesc, *(u32 *) val);
 849                        break;
 850                case HW_DESC_RXPKT_LEN:
 851                        SET_RX_STATUS_DESC_PKT_LEN(pdesc, *(u32 *) val);
 852                        break;
 853                case HW_DESC_RXERO:
 854                        SET_RX_STATUS_DESC_EOR(pdesc, 1);
 855                        break;
 856                default:
 857                        RT_ASSERT(false, "ERR rxdesc :%d not process\n",
 858                                  desc_name);
 859                        break;
 860                }
 861        }
 862}
 863
 864u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name)
 865{
 866        u32 ret = 0;
 867
 868        if (istx) {
 869                switch (desc_name) {
 870                case HW_DESC_OWN:
 871                        ret = GET_TX_DESC_OWN(desc);
 872                        break;
 873                case HW_DESC_TXBUFF_ADDR:
 874                        ret = GET_TX_DESC_TX_BUFFER_ADDRESS(desc);
 875                        break;
 876                default:
 877                        RT_ASSERT(false, "ERR txdesc :%d not process\n",
 878                                  desc_name);
 879                        break;
 880                }
 881        } else {
 882                switch (desc_name) {
 883                case HW_DESC_OWN:
 884                        ret = GET_RX_STATUS_DESC_OWN(desc);
 885                        break;
 886                case HW_DESC_RXPKT_LEN:
 887                        ret = GET_RX_STATUS_DESC_PKT_LEN(desc);
 888                        break;
 889                default:
 890                        RT_ASSERT(false, "ERR rxdesc :%d not process\n",
 891                                  desc_name);
 892                        break;
 893                }
 894        }
 895        return ret;
 896}
 897
 898void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
 899{
 900        struct rtl_priv *rtlpriv = rtl_priv(hw);
 901        rtl_write_word(rtlpriv, TP_POLL, BIT(0) << (hw_queue));
 902}
 903