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