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