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