linux/drivers/net/wireless/realtek/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->rxmcs);
 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 >= DESC_RATEMCS8 &&
 261                    pstats->rate <= DESC_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->rxmcs);
 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 ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
 393                    (ieee80211_has_protected(hdr->frame_control)))
 394                        rx_status->flag &= ~RX_FLAG_DECRYPTED;
 395                else
 396                        rx_status->flag |= RX_FLAG_DECRYPTED;
 397        }
 398        /* rate_idx: index of data rate into band's
 399         * supported rates or MCS index if HT rates
 400         * are use (RX_FLAG_HT)
 401         * Notice: this is diff with windows define
 402         */
 403        rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht,
 404                                                   false, stats->rate);
 405
 406        rx_status->mactime = stats->timestamp_low;
 407        if (phystatus) {
 408                p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
 409                                                     stats->rx_bufshift);
 410
 411                _rtl92ce_translate_rx_signal_stuff(hw,
 412                                                   skb, stats, pdesc,
 413                                                   p_drvinfo);
 414        }
 415
 416        /*rx_status->qual = stats->signal; */
 417        rx_status->signal = stats->recvsignalpower + 10;
 418
 419        return true;
 420}
 421
 422void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
 423                          struct ieee80211_hdr *hdr, u8 *pdesc_tx,
 424                          u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
 425                          struct ieee80211_sta *sta,
 426                          struct sk_buff *skb,
 427                          u8 hw_queue, struct rtl_tcb_desc *tcb_desc)
 428{
 429        struct rtl_priv *rtlpriv = rtl_priv(hw);
 430        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 431        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 432        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 433        bool defaultadapter = true;
 434        u8 *pdesc = pdesc_tx;
 435        u16 seq_number;
 436        __le16 fc = hdr->frame_control;
 437        u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue);
 438        bool firstseg = ((hdr->seq_ctrl &
 439                          cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
 440
 441        bool lastseg = ((hdr->frame_control &
 442                         cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
 443
 444        dma_addr_t mapping = pci_map_single(rtlpci->pdev,
 445                                            skb->data, skb->len,
 446                                            PCI_DMA_TODEVICE);
 447
 448        u8 bw_40 = 0;
 449
 450        if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
 451                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 452                         "DMA mapping error");
 453                return;
 454        }
 455        rcu_read_lock();
 456        sta = get_sta(hw, mac->vif, mac->bssid);
 457        if (mac->opmode == NL80211_IFTYPE_STATION) {
 458                bw_40 = mac->bw_40;
 459        } else if (mac->opmode == NL80211_IFTYPE_AP ||
 460                   mac->opmode == NL80211_IFTYPE_ADHOC ||
 461                   mac->opmode == NL80211_IFTYPE_MESH_POINT) {
 462                if (sta)
 463                        bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
 464        }
 465
 466        seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
 467
 468        rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
 469
 470        CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
 471
 472        if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
 473                firstseg = true;
 474                lastseg = true;
 475        }
 476        if (firstseg) {
 477                SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
 478
 479                SET_TX_DESC_TX_RATE(pdesc, tcb_desc->hw_rate);
 480
 481                if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
 482                        SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
 483
 484                if (info->flags & IEEE80211_TX_CTL_AMPDU) {
 485                        SET_TX_DESC_AGG_BREAK(pdesc, 1);
 486                        SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
 487                }
 488                SET_TX_DESC_SEQ(pdesc, seq_number);
 489
 490                SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc->rts_enable &&
 491                                                !tcb_desc->
 492                                                cts_enable) ? 1 : 0));
 493                SET_TX_DESC_HW_RTS_ENABLE(pdesc,
 494                                          ((tcb_desc->rts_enable
 495                                            || tcb_desc->cts_enable) ? 1 : 0));
 496                SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc->cts_enable) ? 1 : 0));
 497                SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
 498
 499                SET_TX_DESC_RTS_RATE(pdesc, tcb_desc->rts_rate);
 500                SET_TX_DESC_RTS_BW(pdesc, 0);
 501                SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc);
 502                SET_TX_DESC_RTS_SHORT(pdesc,
 503                                      ((tcb_desc->rts_rate <= DESC_RATE54M) ?
 504                                       (tcb_desc->rts_use_shortpreamble ? 1 : 0)
 505                                       : (tcb_desc->rts_use_shortgi ? 1 : 0)));
 506
 507                if (bw_40) {
 508                        if (tcb_desc->packet_bw) {
 509                                SET_TX_DESC_DATA_BW(pdesc, 1);
 510                                SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
 511                        } else {
 512                                SET_TX_DESC_DATA_BW(pdesc, 0);
 513                                SET_TX_DESC_TX_SUB_CARRIER(pdesc,
 514                                                 mac->cur_40_prime_sc);
 515                        }
 516                } else {
 517                        SET_TX_DESC_DATA_BW(pdesc, 0);
 518                        SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
 519                }
 520
 521                SET_TX_DESC_LINIP(pdesc, 0);
 522                SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
 523
 524                if (sta) {
 525                        u8 ampdu_density = sta->ht_cap.ampdu_density;
 526                        SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
 527                }
 528
 529                if (info->control.hw_key) {
 530                        struct ieee80211_key_conf *keyconf =
 531                            info->control.hw_key;
 532
 533                        switch (keyconf->cipher) {
 534                        case WLAN_CIPHER_SUITE_WEP40:
 535                        case WLAN_CIPHER_SUITE_WEP104:
 536                        case WLAN_CIPHER_SUITE_TKIP:
 537                                SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
 538                                break;
 539                        case WLAN_CIPHER_SUITE_CCMP:
 540                                SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
 541                                break;
 542                        default:
 543                                SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
 544                                break;
 545
 546                        }
 547                }
 548
 549                SET_TX_DESC_PKT_ID(pdesc, 0);
 550                SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
 551
 552                SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
 553                SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
 554                SET_TX_DESC_DISABLE_FB(pdesc, 0);
 555                SET_TX_DESC_USE_RATE(pdesc, tcb_desc->use_driver_rate ? 1 : 0);
 556
 557                if (ieee80211_is_data_qos(fc)) {
 558                        if (mac->rdg_en) {
 559                                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 560                                         "Enable RDG function\n");
 561                                SET_TX_DESC_RDG_ENABLE(pdesc, 1);
 562                                SET_TX_DESC_HTC(pdesc, 1);
 563                        }
 564                }
 565        }
 566        rcu_read_unlock();
 567
 568        SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
 569        SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
 570
 571        SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
 572
 573        SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 574
 575        if (rtlpriv->dm.useramask) {
 576                SET_TX_DESC_RATE_ID(pdesc, tcb_desc->ratr_index);
 577                SET_TX_DESC_MACID(pdesc, tcb_desc->mac_id);
 578        } else {
 579                SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc->ratr_index);
 580                SET_TX_DESC_MACID(pdesc, tcb_desc->ratr_index);
 581        }
 582
 583        if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
 584                SET_TX_DESC_HWSEQ_EN(pdesc, 1);
 585                SET_TX_DESC_PKT_ID(pdesc, 8);
 586
 587                if (!defaultadapter)
 588                        SET_TX_DESC_QOS(pdesc, 1);
 589        }
 590
 591        SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
 592
 593        if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
 594            is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
 595                SET_TX_DESC_BMC(pdesc, 1);
 596        }
 597
 598        RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
 599}
 600
 601void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
 602                             u8 *pdesc, bool firstseg,
 603                             bool lastseg, struct sk_buff *skb)
 604{
 605        struct rtl_priv *rtlpriv = rtl_priv(hw);
 606        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 607        u8 fw_queue = QSLT_BEACON;
 608
 609        dma_addr_t mapping = pci_map_single(rtlpci->pdev,
 610                                            skb->data, skb->len,
 611                                            PCI_DMA_TODEVICE);
 612
 613        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
 614        __le16 fc = hdr->frame_control;
 615
 616        if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
 617                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 618                         "DMA mapping error");
 619                return;
 620        }
 621        CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
 622
 623        if (firstseg)
 624                SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
 625
 626        SET_TX_DESC_TX_RATE(pdesc, DESC_RATE1M);
 627
 628        SET_TX_DESC_SEQ(pdesc, 0);
 629
 630        SET_TX_DESC_LINIP(pdesc, 0);
 631
 632        SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
 633
 634        SET_TX_DESC_FIRST_SEG(pdesc, 1);
 635        SET_TX_DESC_LAST_SEG(pdesc, 1);
 636
 637        SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
 638
 639        SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 640
 641        SET_TX_DESC_RATE_ID(pdesc, 7);
 642        SET_TX_DESC_MACID(pdesc, 0);
 643
 644        SET_TX_DESC_OWN(pdesc, 1);
 645
 646        SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len));
 647
 648        SET_TX_DESC_FIRST_SEG(pdesc, 1);
 649        SET_TX_DESC_LAST_SEG(pdesc, 1);
 650
 651        SET_TX_DESC_OFFSET(pdesc, 0x20);
 652
 653        SET_TX_DESC_USE_RATE(pdesc, 1);
 654
 655        if (!ieee80211_is_data_qos(fc)) {
 656                SET_TX_DESC_HWSEQ_EN(pdesc, 1);
 657                SET_TX_DESC_PKT_ID(pdesc, 8);
 658        }
 659
 660        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
 661                      "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
 662}
 663
 664void rtl92ce_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
 665                      u8 desc_name, u8 *val)
 666{
 667        if (istx) {
 668                switch (desc_name) {
 669                case HW_DESC_OWN:
 670                        wmb();
 671                        SET_TX_DESC_OWN(pdesc, 1);
 672                        break;
 673                case HW_DESC_TX_NEXTDESC_ADDR:
 674                        SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
 675                        break;
 676                default:
 677                        RT_ASSERT(false, "ERR txdesc :%d not process\n",
 678                                  desc_name);
 679                        break;
 680                }
 681        } else {
 682                switch (desc_name) {
 683                case HW_DESC_RXOWN:
 684                        wmb();
 685                        SET_RX_DESC_OWN(pdesc, 1);
 686                        break;
 687                case HW_DESC_RXBUFF_ADDR:
 688                        SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
 689                        break;
 690                case HW_DESC_RXPKT_LEN:
 691                        SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
 692                        break;
 693                case HW_DESC_RXERO:
 694                        SET_RX_DESC_EOR(pdesc, 1);
 695                        break;
 696                default:
 697                        RT_ASSERT(false, "ERR rxdesc :%d not process\n",
 698                                  desc_name);
 699                        break;
 700                }
 701        }
 702}
 703
 704u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
 705{
 706        u32 ret = 0;
 707
 708        if (istx) {
 709                switch (desc_name) {
 710                case HW_DESC_OWN:
 711                        ret = GET_TX_DESC_OWN(p_desc);
 712                        break;
 713                case HW_DESC_TXBUFF_ADDR:
 714                        ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
 715                        break;
 716                default:
 717                        RT_ASSERT(false, "ERR txdesc :%d not process\n",
 718                                  desc_name);
 719                        break;
 720                }
 721        } else {
 722                switch (desc_name) {
 723                case HW_DESC_OWN:
 724                        ret = GET_RX_DESC_OWN(p_desc);
 725                        break;
 726                case HW_DESC_RXPKT_LEN:
 727                        ret = GET_RX_DESC_PKT_LEN(p_desc);
 728                        break;
 729                case HW_DESC_RXBUFF_ADDR:
 730                        ret = GET_RX_DESC_BUFF_ADDR(p_desc);
 731                        break;
 732                default:
 733                        RT_ASSERT(false, "ERR rxdesc :%d not process\n",
 734                                  desc_name);
 735                        break;
 736                }
 737        }
 738        return ret;
 739}
 740
 741bool rtl92ce_is_tx_desc_closed(struct ieee80211_hw *hw,
 742                               u8 hw_queue, u16 index)
 743{
 744        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 745        struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
 746        u8 *entry = (u8 *)(&ring->desc[ring->idx]);
 747        u8 own = (u8)rtl92ce_get_desc(entry, true, HW_DESC_OWN);
 748
 749        /*beacon packet will only use the first
 750         *descriptor defautly,and the own may not
 751         *be cleared by the hardware
 752         */
 753        if (own)
 754                return false;
 755        return true;
 756}
 757
 758void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
 759{
 760        struct rtl_priv *rtlpriv = rtl_priv(hw);
 761        if (hw_queue == BEACON_QUEUE) {
 762                rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
 763        } else {
 764                rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
 765                               BIT(0) << (hw_queue));
 766        }
 767}
 768
 769