linux/drivers/net/wireless/rtlwifi/rtl8192ce/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 "../stats.h"
  34#include "reg.h"
  35#include "def.h"
  36#include "phy.h"
  37#include "trx.h"
  38#include "led.h"
  39
  40static u8 _rtl92ce_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_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) || ieee80211_is_ctl(fc))
  47                return QSLT_MGNT;
  48
  49        return skb->priority;
  50}
  51
  52static u8 _rtl92c_query_rxpwrpercentage(char antpower)
  53{
  54        if ((antpower <= -100) || (antpower >= 20))
  55                return 0;
  56        else if (antpower >= 0)
  57                return 100;
  58        else
  59                return 100 + antpower;
  60}
  61
  62static u8 _rtl92c_evm_db_to_percentage(char value)
  63{
  64        char ret_val;
  65        ret_val = value;
  66
  67        if (ret_val >= 0)
  68                ret_val = 0;
  69
  70        if (ret_val <= -33)
  71                ret_val = -33;
  72
  73        ret_val = 0 - ret_val;
  74        ret_val *= 3;
  75
  76        if (ret_val == 99)
  77                ret_val = 100;
  78
  79        return ret_val;
  80}
  81
  82static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw,
  83                long currsig)
  84{
  85        long retsig;
  86
  87        if (currsig >= 61 && currsig <= 100)
  88                retsig = 90 + ((currsig - 60) / 4);
  89        else if (currsig >= 41 && currsig <= 60)
  90                retsig = 78 + ((currsig - 40) / 2);
  91        else if (currsig >= 31 && currsig <= 40)
  92                retsig = 66 + (currsig - 30);
  93        else if (currsig >= 21 && currsig <= 30)
  94                retsig = 54 + (currsig - 20);
  95        else if (currsig >= 5 && currsig <= 20)
  96                retsig = 42 + (((currsig - 5) * 2) / 3);
  97        else if (currsig == 4)
  98                retsig = 36;
  99        else if (currsig == 3)
 100                retsig = 27;
 101        else if (currsig == 2)
 102                retsig = 18;
 103        else if (currsig == 1)
 104                retsig = 9;
 105        else
 106                retsig = currsig;
 107
 108        return retsig;
 109}
 110
 111static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
 112                                       struct rtl_stats *pstats,
 113                                       struct rx_desc_92c *pdesc,
 114                                       struct rx_fwinfo_92c *p_drvinfo,
 115                                       bool packet_match_bssid,
 116                                       bool packet_toself,
 117                                       bool packet_beacon)
 118{
 119        struct rtl_priv *rtlpriv = rtl_priv(hw);
 120        struct phy_sts_cck_8192s_t *cck_buf;
 121        struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
 122        s8 rx_pwr_all = 0, rx_pwr[4];
 123        u8 evm, pwdb_all, rf_rx_num = 0;
 124        u8 i, max_spatial_stream;
 125        u32 rssi, total_rssi = 0;
 126        bool is_cck_rate;
 127
 128        is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
 129        pstats->packet_matchbssid = packet_match_bssid;
 130        pstats->packet_toself = packet_toself;
 131        pstats->is_cck = is_cck_rate;
 132        pstats->packet_beacon = packet_beacon;
 133        pstats->rx_mimo_sig_qual[0] = -1;
 134        pstats->rx_mimo_sig_qual[1] = -1;
 135
 136        if (is_cck_rate) {
 137                u8 report, cck_highpwr;
 138                cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
 139
 140                if (ppsc->rfpwr_state == ERFON)
 141                        cck_highpwr = (u8) rtl_get_bbreg(hw,
 142                                                 RFPGA0_XA_HSSIPARAMETER2,
 143                                                 BIT(9));
 144                else
 145                        cck_highpwr = false;
 146
 147                if (!cck_highpwr) {
 148                        u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 149                        report = cck_buf->cck_agc_rpt & 0xc0;
 150                        report = report >> 6;
 151                        switch (report) {
 152                        case 0x3:
 153                                rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
 154                                break;
 155                        case 0x2:
 156                                rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
 157                                break;
 158                        case 0x1:
 159                                rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
 160                                break;
 161                        case 0x0:
 162                                rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
 163                                break;
 164                        }
 165                } else {
 166                        u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 167                        report = p_drvinfo->cfosho[0] & 0x60;
 168                        report = report >> 5;
 169                        switch (report) {
 170                        case 0x3:
 171                                rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
 172                                break;
 173                        case 0x2:
 174                                rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
 175                                break;
 176                        case 0x1:
 177                                rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
 178                                break;
 179                        case 0x0:
 180                                rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
 181                                break;
 182                        }
 183                }
 184
 185                pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
 186                /* CCK gain is smaller than OFDM/MCS gain,
 187                 * so we add gain diff by experiences,
 188                 * the val is 6
 189                 */
 190                pwdb_all += 6;
 191                if (pwdb_all > 100)
 192                        pwdb_all = 100;
 193                /* modify the offset to make the same
 194                 * gain index with OFDM.
 195                 */
 196                if (pwdb_all > 34 && pwdb_all <= 42)
 197                        pwdb_all -= 2;
 198                else if (pwdb_all > 26 && pwdb_all <= 34)
 199                        pwdb_all -= 6;
 200                else if (pwdb_all > 14 && pwdb_all <= 26)
 201                        pwdb_all -= 8;
 202                else if (pwdb_all > 4 && pwdb_all <= 14)
 203                        pwdb_all -= 4;
 204
 205                pstats->rx_pwdb_all = pwdb_all;
 206                pstats->recvsignalpower = rx_pwr_all;
 207
 208                /* (3) Get Signal Quality (EVM) */
 209                if (packet_match_bssid) {
 210                        u8 sq;
 211                        if (pstats->rx_pwdb_all > 40)
 212                                sq = 100;
 213                        else {
 214                                sq = cck_buf->sq_rpt;
 215                                if (sq > 64)
 216                                        sq = 0;
 217                                else if (sq < 20)
 218                                        sq = 100;
 219                                else
 220                                        sq = ((64 - sq) * 100) / 44;
 221                        }
 222
 223                        pstats->signalquality = sq;
 224                        pstats->rx_mimo_sig_qual[0] = sq;
 225                        pstats->rx_mimo_sig_qual[1] = -1;
 226                }
 227        } else {
 228                rtlpriv->dm.rfpath_rxenable[0] =
 229                    rtlpriv->dm.rfpath_rxenable[1] = true;
 230                /* (1)Get RSSI for HT rate */
 231                for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
 232                        /* we will judge RF RX path now. */
 233                        if (rtlpriv->dm.rfpath_rxenable[i])
 234                                rf_rx_num++;
 235
 236                        rx_pwr[i] =
 237                            ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
 238                        /* Translate DBM to percentage. */
 239                        rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
 240                        total_rssi += rssi;
 241                        /* Get Rx snr value in DB */
 242                        rtlpriv->stats.rx_snr_db[i] =
 243                            (long)(p_drvinfo->rxsnr[i] / 2);
 244
 245                        /* Record Signal Strength for next packet */
 246                        if (packet_match_bssid)
 247                                pstats->rx_mimo_signalstrength[i] = (u8) rssi;
 248                }
 249
 250                /* (2)PWDB, Average PWDB cacluated by
 251                 * hardware (for rate adaptive)
 252                 */
 253                rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
 254                pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
 255                pstats->rx_pwdb_all = pwdb_all;
 256                pstats->rxpower = rx_pwr_all;
 257                pstats->recvsignalpower = rx_pwr_all;
 258
 259                /* (3)EVM of HT rate */
 260                if (pstats->is_ht && pstats->rate >= DESC92_RATEMCS8 &&
 261                    pstats->rate <= DESC92_RATEMCS15)
 262                        max_spatial_stream = 2;
 263                else
 264                        max_spatial_stream = 1;
 265
 266                for (i = 0; i < max_spatial_stream; i++) {
 267                        evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
 268
 269                        if (packet_match_bssid) {
 270                                /* Fill value in RFD, Get the first
 271                                 * spatial stream only
 272                                 */
 273                                if (i == 0)
 274                                        pstats->signalquality =
 275                                            (u8) (evm & 0xff);
 276                                pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff);
 277                        }
 278                }
 279        }
 280
 281        /* UI BSS List signal strength(in percentage),
 282         * make it good looking, from 0~100.
 283         */
 284        if (is_cck_rate)
 285                pstats->signalstrength =
 286                    (u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all));
 287        else if (rf_rx_num != 0)
 288                pstats->signalstrength =
 289                    (u8) (_rtl92ce_signal_scale_mapping
 290                          (hw, total_rssi /= rf_rx_num));
 291}
 292
 293static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
 294                                               struct sk_buff *skb,
 295                                               struct rtl_stats *pstats,
 296                                               struct rx_desc_92c *pdesc,
 297                                               struct rx_fwinfo_92c *p_drvinfo)
 298{
 299        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 300        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 301
 302        struct ieee80211_hdr *hdr;
 303        u8 *tmp_buf;
 304        u8 *praddr;
 305        __le16 fc;
 306        u16 type, c_fc;
 307        bool packet_matchbssid, packet_toself, packet_beacon = false;
 308
 309        tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
 310
 311        hdr = (struct ieee80211_hdr *)tmp_buf;
 312        fc = hdr->frame_control;
 313        c_fc = le16_to_cpu(fc);
 314        type = WLAN_FC_GET_TYPE(fc);
 315        praddr = hdr->addr1;
 316
 317        packet_matchbssid =
 318            ((IEEE80211_FTYPE_CTL != type) &&
 319             ether_addr_equal(mac->bssid,
 320                              (c_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
 321                              (c_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
 322                              hdr->addr3) &&
 323             (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
 324
 325        packet_toself = packet_matchbssid &&
 326             ether_addr_equal(praddr, rtlefuse->dev_addr);
 327
 328        if (ieee80211_is_beacon(fc))
 329                packet_beacon = true;
 330
 331        _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
 332                                   packet_matchbssid, packet_toself,
 333                                   packet_beacon);
 334
 335        rtl_process_phyinfo(hw, tmp_buf, pstats);
 336}
 337
 338bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
 339                           struct rtl_stats *stats,
 340                           struct ieee80211_rx_status *rx_status,
 341                           u8 *p_desc, struct sk_buff *skb)
 342{
 343        struct rx_fwinfo_92c *p_drvinfo;
 344        struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
 345        struct ieee80211_hdr *hdr;
 346        u32 phystatus = GET_RX_DESC_PHYST(pdesc);
 347        stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
 348        stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
 349            RX_DRV_INFO_SIZE_UNIT;
 350        stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
 351        stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
 352        stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
 353        stats->hwerror = (stats->crc | stats->icv);
 354        stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
 355        stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
 356        stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
 357        stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
 358        stats->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
 359                                   && (GET_RX_DESC_FAGGR(pdesc) == 1));
 360        stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
 361        stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
 362        stats->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
 363
 364        stats->is_cck = RX_HAL_IS_CCK_RATE(pdesc);
 365
 366        rx_status->freq = hw->conf.chandef.chan->center_freq;
 367        rx_status->band = hw->conf.chandef.chan->band;
 368
 369        hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size
 370                        + stats->rx_bufshift);
 371
 372        if (stats->crc)
 373                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
 374
 375        if (stats->rx_is40Mhzpacket)
 376                rx_status->flag |= RX_FLAG_40MHZ;
 377
 378        if (stats->is_ht)
 379                rx_status->flag |= RX_FLAG_HT;
 380
 381        rx_status->flag |= RX_FLAG_MACTIME_START;
 382
 383        /* hw will set stats->decrypted true, if it finds the
 384         * frame is open data frame or mgmt frame.
 385         * So hw will not decryption robust managment frame
 386         * for IEEE80211w but still set status->decrypted
 387         * true, so here we should set it back to undecrypted
 388         * for IEEE80211w frame, and mac80211 sw will help
 389         * to decrypt it
 390         */
 391        if (stats->decrypted) {
 392                if (!hdr) {
 393                        /* In testing, hdr was NULL here */
 394                        return false;
 395                }
 396                if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
 397                    (ieee80211_has_protected(hdr->frame_control)))
 398                        rx_status->flag &= ~RX_FLAG_DECRYPTED;
 399                else
 400                        rx_status->flag |= RX_FLAG_DECRYPTED;
 401        }
 402        /* rate_idx: index of data rate into band's
 403         * supported rates or MCS index if HT rates
 404         * are use (RX_FLAG_HT)
 405         * Notice: this is diff with windows define
 406         */
 407        rx_status->rate_idx = rtlwifi_rate_mapping(hw,
 408                                stats->is_ht, stats->rate,
 409                                stats->isfirst_ampdu);
 410
 411        rx_status->mactime = stats->timestamp_low;
 412        if (phystatus) {
 413                p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
 414                                                     stats->rx_bufshift);
 415
 416                _rtl92ce_translate_rx_signal_stuff(hw,
 417                                                   skb, stats, pdesc,
 418                                                   p_drvinfo);
 419        }
 420
 421        /*rx_status->qual = stats->signal; */
 422        rx_status->signal = stats->recvsignalpower + 10;
 423
 424        return true;
 425}
 426
 427void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
 428                          struct ieee80211_hdr *hdr, u8 *pdesc_tx,
 429                          struct ieee80211_tx_info *info,
 430                          struct ieee80211_sta *sta,
 431                          struct sk_buff *skb,
 432                          u8 hw_queue, struct rtl_tcb_desc *tcb_desc)
 433{
 434        struct rtl_priv *rtlpriv = rtl_priv(hw);
 435        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 436        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 437        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 438        bool defaultadapter = true;
 439        u8 *pdesc = pdesc_tx;
 440        u16 seq_number;
 441        __le16 fc = hdr->frame_control;
 442        u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue);
 443        bool firstseg = ((hdr->seq_ctrl &
 444                          cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
 445
 446        bool lastseg = ((hdr->frame_control &
 447                         cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
 448
 449        dma_addr_t mapping = pci_map_single(rtlpci->pdev,
 450                                            skb->data, skb->len,
 451                                            PCI_DMA_TODEVICE);
 452
 453        u8 bw_40 = 0;
 454
 455        if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
 456                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 457                         "DMA mapping error");
 458                return;
 459        }
 460        rcu_read_lock();
 461        sta = get_sta(hw, mac->vif, mac->bssid);
 462        if (mac->opmode == NL80211_IFTYPE_STATION) {
 463                bw_40 = mac->bw_40;
 464        } else if (mac->opmode == NL80211_IFTYPE_AP ||
 465                   mac->opmode == NL80211_IFTYPE_ADHOC ||
 466                   mac->opmode == NL80211_IFTYPE_MESH_POINT) {
 467                if (sta)
 468                        bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
 469        }
 470
 471        seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
 472
 473        rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
 474
 475        CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
 476
 477        if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
 478                firstseg = true;
 479                lastseg = true;
 480        }
 481        if (firstseg) {
 482                SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
 483
 484                SET_TX_DESC_TX_RATE(pdesc, tcb_desc->hw_rate);
 485
 486                if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
 487                        SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
 488
 489                if (info->flags & IEEE80211_TX_CTL_AMPDU) {
 490                        SET_TX_DESC_AGG_BREAK(pdesc, 1);
 491                        SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
 492                }
 493                SET_TX_DESC_SEQ(pdesc, seq_number);
 494
 495                SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc->rts_enable &&
 496                                                !tcb_desc->
 497                                                cts_enable) ? 1 : 0));
 498                SET_TX_DESC_HW_RTS_ENABLE(pdesc,
 499                                          ((tcb_desc->rts_enable
 500                                            || tcb_desc->cts_enable) ? 1 : 0));
 501                SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc->cts_enable) ? 1 : 0));
 502                SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
 503
 504                SET_TX_DESC_RTS_RATE(pdesc, tcb_desc->rts_rate);
 505                SET_TX_DESC_RTS_BW(pdesc, 0);
 506                SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc);
 507                SET_TX_DESC_RTS_SHORT(pdesc,
 508                                      ((tcb_desc->rts_rate <= DESC92_RATE54M) ?
 509                                       (tcb_desc->rts_use_shortpreamble ? 1 : 0)
 510                                       : (tcb_desc->rts_use_shortgi ? 1 : 0)));
 511
 512                if (bw_40) {
 513                        if (tcb_desc->packet_bw) {
 514                                SET_TX_DESC_DATA_BW(pdesc, 1);
 515                                SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
 516                        } else {
 517                                SET_TX_DESC_DATA_BW(pdesc, 0);
 518                                SET_TX_DESC_TX_SUB_CARRIER(pdesc,
 519                                                 mac->cur_40_prime_sc);
 520                        }
 521                } else {
 522                        SET_TX_DESC_DATA_BW(pdesc, 0);
 523                        SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
 524                }
 525
 526                SET_TX_DESC_LINIP(pdesc, 0);
 527                SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
 528
 529                if (sta) {
 530                        u8 ampdu_density = sta->ht_cap.ampdu_density;
 531                        SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
 532                }
 533
 534                if (info->control.hw_key) {
 535                        struct ieee80211_key_conf *keyconf =
 536                            info->control.hw_key;
 537
 538                        switch (keyconf->cipher) {
 539                        case WLAN_CIPHER_SUITE_WEP40:
 540                        case WLAN_CIPHER_SUITE_WEP104:
 541                        case WLAN_CIPHER_SUITE_TKIP:
 542                                SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
 543                                break;
 544                        case WLAN_CIPHER_SUITE_CCMP:
 545                                SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
 546                                break;
 547                        default:
 548                                SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
 549                                break;
 550
 551                        }
 552                }
 553
 554                SET_TX_DESC_PKT_ID(pdesc, 0);
 555                SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
 556
 557                SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
 558                SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
 559                SET_TX_DESC_DISABLE_FB(pdesc, 0);
 560                SET_TX_DESC_USE_RATE(pdesc, tcb_desc->use_driver_rate ? 1 : 0);
 561
 562                if (ieee80211_is_data_qos(fc)) {
 563                        if (mac->rdg_en) {
 564                                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 565                                         "Enable RDG function\n");
 566                                SET_TX_DESC_RDG_ENABLE(pdesc, 1);
 567                                SET_TX_DESC_HTC(pdesc, 1);
 568                        }
 569                }
 570        }
 571        rcu_read_unlock();
 572
 573        SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
 574        SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
 575
 576        SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
 577
 578        SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 579
 580        if (rtlpriv->dm.useramask) {
 581                SET_TX_DESC_RATE_ID(pdesc, tcb_desc->ratr_index);
 582                SET_TX_DESC_MACID(pdesc, tcb_desc->mac_id);
 583        } else {
 584                SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc->ratr_index);
 585                SET_TX_DESC_MACID(pdesc, tcb_desc->ratr_index);
 586        }
 587
 588        if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
 589                SET_TX_DESC_HWSEQ_EN(pdesc, 1);
 590                SET_TX_DESC_PKT_ID(pdesc, 8);
 591
 592                if (!defaultadapter)
 593                        SET_TX_DESC_QOS(pdesc, 1);
 594        }
 595
 596        SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
 597
 598        if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
 599            is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
 600                SET_TX_DESC_BMC(pdesc, 1);
 601        }
 602
 603        RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
 604}
 605
 606void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
 607                             u8 *pdesc, bool firstseg,
 608                             bool lastseg, struct sk_buff *skb)
 609{
 610        struct rtl_priv *rtlpriv = rtl_priv(hw);
 611        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 612        u8 fw_queue = QSLT_BEACON;
 613
 614        dma_addr_t mapping = pci_map_single(rtlpci->pdev,
 615                                            skb->data, skb->len,
 616                                            PCI_DMA_TODEVICE);
 617
 618        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
 619        __le16 fc = hdr->frame_control;
 620
 621        if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
 622                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 623                         "DMA mapping error");
 624                return;
 625        }
 626        CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
 627
 628        if (firstseg)
 629                SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
 630
 631        SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M);
 632
 633        SET_TX_DESC_SEQ(pdesc, 0);
 634
 635        SET_TX_DESC_LINIP(pdesc, 0);
 636
 637        SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
 638
 639        SET_TX_DESC_FIRST_SEG(pdesc, 1);
 640        SET_TX_DESC_LAST_SEG(pdesc, 1);
 641
 642        SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
 643
 644        SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 645
 646        SET_TX_DESC_RATE_ID(pdesc, 7);
 647        SET_TX_DESC_MACID(pdesc, 0);
 648
 649        SET_TX_DESC_OWN(pdesc, 1);
 650
 651        SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len));
 652
 653        SET_TX_DESC_FIRST_SEG(pdesc, 1);
 654        SET_TX_DESC_LAST_SEG(pdesc, 1);
 655
 656        SET_TX_DESC_OFFSET(pdesc, 0x20);
 657
 658        SET_TX_DESC_USE_RATE(pdesc, 1);
 659
 660        if (!ieee80211_is_data_qos(fc)) {
 661                SET_TX_DESC_HWSEQ_EN(pdesc, 1);
 662                SET_TX_DESC_PKT_ID(pdesc, 8);
 663        }
 664
 665        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
 666                      "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
 667}
 668
 669void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
 670{
 671        if (istx) {
 672                switch (desc_name) {
 673                case HW_DESC_OWN:
 674                        wmb();
 675                        SET_TX_DESC_OWN(pdesc, 1);
 676                        break;
 677                case HW_DESC_TX_NEXTDESC_ADDR:
 678                        SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
 679                        break;
 680                default:
 681                        RT_ASSERT(false, "ERR txdesc :%d not process\n",
 682                                  desc_name);
 683                        break;
 684                }
 685        } else {
 686                switch (desc_name) {
 687                case HW_DESC_RXOWN:
 688                        wmb();
 689                        SET_RX_DESC_OWN(pdesc, 1);
 690                        break;
 691                case HW_DESC_RXBUFF_ADDR:
 692                        SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
 693                        break;
 694                case HW_DESC_RXPKT_LEN:
 695                        SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
 696                        break;
 697                case HW_DESC_RXERO:
 698                        SET_RX_DESC_EOR(pdesc, 1);
 699                        break;
 700                default:
 701                        RT_ASSERT(false, "ERR rxdesc :%d not process\n",
 702                                  desc_name);
 703                        break;
 704                }
 705        }
 706}
 707
 708u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
 709{
 710        u32 ret = 0;
 711
 712        if (istx) {
 713                switch (desc_name) {
 714                case HW_DESC_OWN:
 715                        ret = GET_TX_DESC_OWN(p_desc);
 716                        break;
 717                case HW_DESC_TXBUFF_ADDR:
 718                        ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
 719                        break;
 720                default:
 721                        RT_ASSERT(false, "ERR txdesc :%d not process\n",
 722                                  desc_name);
 723                        break;
 724                }
 725        } else {
 726                struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
 727                switch (desc_name) {
 728                case HW_DESC_OWN:
 729                        ret = GET_RX_DESC_OWN(pdesc);
 730                        break;
 731                case HW_DESC_RXPKT_LEN:
 732                        ret = GET_RX_DESC_PKT_LEN(pdesc);
 733                        break;
 734                default:
 735                        RT_ASSERT(false, "ERR rxdesc :%d not process\n",
 736                                  desc_name);
 737                        break;
 738                }
 739        }
 740        return ret;
 741}
 742
 743void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
 744{
 745        struct rtl_priv *rtlpriv = rtl_priv(hw);
 746        if (hw_queue == BEACON_QUEUE) {
 747                rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
 748        } else {
 749                rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
 750                               BIT(0) << (hw_queue));
 751        }
 752}
 753
 754