linux/drivers/net/wireless/realtek/rtlwifi/rtl8192se/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 "fw.h"
  34#include "trx.h"
  35#include "led.h"
  36
  37static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb,  u8 skb_queue)
  38{
  39        __le16 fc = rtl_get_fc(skb);
  40
  41        if (unlikely(ieee80211_is_beacon(fc)))
  42                return QSLT_BEACON;
  43        if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
  44                return QSLT_MGNT;
  45        if (ieee80211_is_nullfunc(fc))
  46                return QSLT_HIGH;
  47
  48        /* Kernel commit 1bf4bbb4024dcdab changed EAPOL packets to use
  49         * queue V0 at priority 7; however, the RTL8192SE appears to have
  50         * that queue at priority 6
  51         */
  52        if (skb->priority == 7)
  53                return QSLT_VO;
  54        return skb->priority;
  55}
  56
  57static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
  58                                       struct rtl_stats *pstats, u8 *pdesc,
  59                                       struct rx_fwinfo *p_drvinfo,
  60                                       bool packet_match_bssid,
  61                                       bool packet_toself,
  62                                       bool packet_beacon)
  63{
  64        struct rtl_priv *rtlpriv = rtl_priv(hw);
  65        struct phy_sts_cck_8192s_t *cck_buf;
  66        struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
  67        s8 rx_pwr_all = 0, rx_pwr[4];
  68        u8 rf_rx_num = 0, evm, pwdb_all;
  69        u8 i, max_spatial_stream;
  70        u32 rssi, total_rssi = 0;
  71        bool is_cck = pstats->is_cck;
  72
  73        pstats->packet_matchbssid = packet_match_bssid;
  74        pstats->packet_toself = packet_toself;
  75        pstats->packet_beacon = packet_beacon;
  76        pstats->rx_mimo_sig_qual[0] = -1;
  77        pstats->rx_mimo_sig_qual[1] = -1;
  78
  79        if (is_cck) {
  80                u8 report, cck_highpwr;
  81                cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
  82
  83                if (ppsc->rfpwr_state == ERFON)
  84                        cck_highpwr = (u8) rtl_get_bbreg(hw,
  85                                                RFPGA0_XA_HSSIPARAMETER2,
  86                                                0x200);
  87                else
  88                        cck_highpwr = false;
  89
  90                if (!cck_highpwr) {
  91                        u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
  92                        report = cck_buf->cck_agc_rpt & 0xc0;
  93                        report = report >> 6;
  94                        switch (report) {
  95                        case 0x3:
  96                                rx_pwr_all = -40 - (cck_agc_rpt & 0x3e);
  97                                break;
  98                        case 0x2:
  99                                rx_pwr_all = -20 - (cck_agc_rpt & 0x3e);
 100                                break;
 101                        case 0x1:
 102                                rx_pwr_all = -2 - (cck_agc_rpt & 0x3e);
 103                                break;
 104                        case 0x0:
 105                                rx_pwr_all = 14 - (cck_agc_rpt & 0x3e);
 106                                break;
 107                        }
 108                } else {
 109                        u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 110                        report = p_drvinfo->cfosho[0] & 0x60;
 111                        report = report >> 5;
 112                        switch (report) {
 113                        case 0x3:
 114                                rx_pwr_all = -40 - ((cck_agc_rpt & 0x1f) << 1);
 115                                break;
 116                        case 0x2:
 117                                rx_pwr_all = -20 - ((cck_agc_rpt & 0x1f) << 1);
 118                                break;
 119                        case 0x1:
 120                                rx_pwr_all = -2 - ((cck_agc_rpt & 0x1f) << 1);
 121                                break;
 122                        case 0x0:
 123                                rx_pwr_all = 14 - ((cck_agc_rpt & 0x1f) << 1);
 124                                break;
 125                        }
 126                }
 127
 128                pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
 129
 130                /* CCK gain is smaller than OFDM/MCS gain,  */
 131                /* so we add gain diff by experiences, the val is 6 */
 132                pwdb_all += 6;
 133                if (pwdb_all > 100)
 134                        pwdb_all = 100;
 135                /* modify the offset to make the same gain index with OFDM. */
 136                if (pwdb_all > 34 && pwdb_all <= 42)
 137                        pwdb_all -= 2;
 138                else if (pwdb_all > 26 && pwdb_all <= 34)
 139                        pwdb_all -= 6;
 140                else if (pwdb_all > 14 && pwdb_all <= 26)
 141                        pwdb_all -= 8;
 142                else if (pwdb_all > 4 && pwdb_all <= 14)
 143                        pwdb_all -= 4;
 144
 145                pstats->rx_pwdb_all = pwdb_all;
 146                pstats->recvsignalpower = rx_pwr_all;
 147
 148                if (packet_match_bssid) {
 149                        u8 sq;
 150                        if (pstats->rx_pwdb_all > 40) {
 151                                sq = 100;
 152                        } else {
 153                                sq = cck_buf->sq_rpt;
 154                                if (sq > 64)
 155                                        sq = 0;
 156                                else if (sq < 20)
 157                                        sq = 100;
 158                                else
 159                                        sq = ((64 - sq) * 100) / 44;
 160                        }
 161
 162                        pstats->signalquality = sq;
 163                        pstats->rx_mimo_sig_qual[0] = sq;
 164                        pstats->rx_mimo_sig_qual[1] = -1;
 165                }
 166        } else {
 167                rtlpriv->dm.rfpath_rxenable[0] =
 168                    rtlpriv->dm.rfpath_rxenable[1] = true;
 169                for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
 170                        if (rtlpriv->dm.rfpath_rxenable[i])
 171                                rf_rx_num++;
 172
 173                        rx_pwr[i] = ((p_drvinfo->gain_trsw[i] &
 174                                    0x3f) * 2) - 110;
 175                        rssi = rtl_query_rxpwrpercentage(rx_pwr[i]);
 176                        total_rssi += rssi;
 177                        rtlpriv->stats.rx_snr_db[i] =
 178                                         (long)(p_drvinfo->rxsnr[i] / 2);
 179
 180                        if (packet_match_bssid)
 181                                pstats->rx_mimo_signalstrength[i] = (u8) rssi;
 182                }
 183
 184                rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
 185                pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
 186                pstats->rx_pwdb_all = pwdb_all;
 187                pstats->rxpower = rx_pwr_all;
 188                pstats->recvsignalpower = rx_pwr_all;
 189
 190                if (pstats->is_ht && pstats->rate >= DESC_RATEMCS8 &&
 191                    pstats->rate <= DESC_RATEMCS15)
 192                        max_spatial_stream = 2;
 193                else
 194                        max_spatial_stream = 1;
 195
 196                for (i = 0; i < max_spatial_stream; i++) {
 197                        evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
 198
 199                        if (packet_match_bssid) {
 200                                if (i == 0)
 201                                        pstats->signalquality = (u8)(evm &
 202                                                                 0xff);
 203                                pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff);
 204                        }
 205                }
 206        }
 207
 208        if (is_cck)
 209                pstats->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
 210                                         pwdb_all));
 211        else if (rf_rx_num != 0)
 212                pstats->signalstrength = (u8) (rtl_signal_scale_mapping(hw,
 213                                total_rssi /= rf_rx_num));
 214}
 215
 216static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw,
 217                struct sk_buff *skb, struct rtl_stats *pstats,
 218                u8 *pdesc, struct rx_fwinfo *p_drvinfo)
 219{
 220        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 221        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 222
 223        struct ieee80211_hdr *hdr;
 224        u8 *tmp_buf;
 225        u8 *praddr;
 226        __le16 fc;
 227        u16 type, cfc;
 228        bool packet_matchbssid, packet_toself, packet_beacon = false;
 229
 230        tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
 231
 232        hdr = (struct ieee80211_hdr *)tmp_buf;
 233        fc = hdr->frame_control;
 234        cfc = le16_to_cpu(fc);
 235        type = WLAN_FC_GET_TYPE(fc);
 236        praddr = hdr->addr1;
 237
 238        packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
 239             ether_addr_equal(mac->bssid,
 240                              (cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
 241                              (cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
 242                              hdr->addr3) &&
 243             (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
 244
 245        packet_toself = packet_matchbssid &&
 246            ether_addr_equal(praddr, rtlefuse->dev_addr);
 247
 248        if (ieee80211_is_beacon(fc))
 249                packet_beacon = true;
 250
 251        _rtl92se_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
 252                        packet_matchbssid, packet_toself, packet_beacon);
 253        rtl_process_phyinfo(hw, tmp_buf, pstats);
 254}
 255
 256bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
 257                           struct ieee80211_rx_status *rx_status, u8 *pdesc,
 258                           struct sk_buff *skb)
 259{
 260        struct rx_fwinfo *p_drvinfo;
 261        u32 phystatus = (u32)GET_RX_STATUS_DESC_PHY_STATUS(pdesc);
 262        struct ieee80211_hdr *hdr;
 263
 264        stats->length = (u16)GET_RX_STATUS_DESC_PKT_LEN(pdesc);
 265        stats->rx_drvinfo_size = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE(pdesc) * 8;
 266        stats->rx_bufshift = (u8)(GET_RX_STATUS_DESC_SHIFT(pdesc) & 0x03);
 267        stats->icv = (u16)GET_RX_STATUS_DESC_ICV(pdesc);
 268        stats->crc = (u16)GET_RX_STATUS_DESC_CRC32(pdesc);
 269        stats->hwerror = (u16)(stats->crc | stats->icv);
 270        stats->decrypted = !GET_RX_STATUS_DESC_SWDEC(pdesc);
 271
 272        stats->rate = (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc);
 273        stats->shortpreamble = (u16)GET_RX_STATUS_DESC_SPLCP(pdesc);
 274        stats->isampdu = (bool)(GET_RX_STATUS_DESC_PAGGR(pdesc) == 1);
 275        stats->isfirst_ampdu = (bool) ((GET_RX_STATUS_DESC_PAGGR(pdesc) == 1)
 276                               && (GET_RX_STATUS_DESC_FAGGR(pdesc) == 1));
 277        stats->timestamp_low = GET_RX_STATUS_DESC_TSFL(pdesc);
 278        stats->rx_is40Mhzpacket = (bool)GET_RX_STATUS_DESC_BW(pdesc);
 279        stats->is_ht = (bool)GET_RX_STATUS_DESC_RX_HT(pdesc);
 280        stats->is_cck = SE_RX_HAL_IS_CCK_RATE(pdesc);
 281
 282        if (stats->hwerror)
 283                return false;
 284
 285        rx_status->freq = hw->conf.chandef.chan->center_freq;
 286        rx_status->band = hw->conf.chandef.chan->band;
 287
 288        if (stats->crc)
 289                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
 290
 291        if (stats->rx_is40Mhzpacket)
 292                rx_status->bw = RATE_INFO_BW_40;
 293
 294        if (stats->is_ht)
 295                rx_status->encoding = RX_ENC_HT;
 296
 297        rx_status->flag |= RX_FLAG_MACTIME_START;
 298
 299        /* hw will set stats->decrypted true, if it finds the
 300         * frame is open data frame or mgmt frame,
 301         * hw will not decrypt robust managment frame
 302         * for IEEE80211w but still set stats->decrypted
 303         * true, so here we should set it back to undecrypted
 304         * for IEEE80211w frame, and mac80211 sw will help
 305         * to decrypt it */
 306        if (stats->decrypted) {
 307                hdr = (struct ieee80211_hdr *)(skb->data +
 308                       stats->rx_drvinfo_size + stats->rx_bufshift);
 309
 310                if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
 311                        (ieee80211_has_protected(hdr->frame_control)))
 312                        rx_status->flag &= ~RX_FLAG_DECRYPTED;
 313                else
 314                        rx_status->flag |= RX_FLAG_DECRYPTED;
 315        }
 316
 317        rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht,
 318                                                   false, stats->rate);
 319
 320        rx_status->mactime = stats->timestamp_low;
 321        if (phystatus) {
 322                p_drvinfo = (struct rx_fwinfo *)(skb->data +
 323                                                 stats->rx_bufshift);
 324                _rtl92se_translate_rx_signal_stuff(hw, skb, stats, pdesc,
 325                                                   p_drvinfo);
 326        }
 327
 328        /*rx_status->qual = stats->signal; */
 329        rx_status->signal = stats->recvsignalpower + 10;
 330
 331        return true;
 332}
 333
 334void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
 335                struct ieee80211_hdr *hdr, u8 *pdesc_tx,
 336                u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
 337                struct ieee80211_sta *sta,
 338                struct sk_buff *skb,
 339                u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
 340{
 341        struct rtl_priv *rtlpriv = rtl_priv(hw);
 342        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 343        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 344        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 345        u8 *pdesc = pdesc_tx;
 346        u16 seq_number;
 347        __le16 fc = hdr->frame_control;
 348        u8 reserved_macid = 0;
 349        u8 fw_qsel = _rtl92se_map_hwqueue_to_fwqueue(skb, hw_queue);
 350        bool firstseg = (!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)));
 351        bool lastseg = (!(hdr->frame_control &
 352                        cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)));
 353        dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
 354                    PCI_DMA_TODEVICE);
 355        u8 bw_40 = 0;
 356
 357        if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
 358                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 359                         "DMA mapping error\n");
 360                return;
 361        }
 362        if (mac->opmode == NL80211_IFTYPE_STATION) {
 363                bw_40 = mac->bw_40;
 364        } else if (mac->opmode == NL80211_IFTYPE_AP ||
 365                mac->opmode == NL80211_IFTYPE_ADHOC) {
 366                if (sta)
 367                        bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
 368        }
 369
 370        seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
 371
 372        rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
 373
 374        CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE_RTL8192S);
 375
 376        if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
 377                firstseg = true;
 378                lastseg = true;
 379        }
 380
 381        if (firstseg) {
 382                if (rtlpriv->dm.useramask) {
 383                        /* set txdesc macId */
 384                        if (ptcb_desc->mac_id < 32) {
 385                                SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
 386                                reserved_macid |= ptcb_desc->mac_id;
 387                        }
 388                }
 389                SET_TX_DESC_RSVD_MACID(pdesc, reserved_macid);
 390
 391                SET_TX_DESC_TXHT(pdesc, ((ptcb_desc->hw_rate >=
 392                                 DESC_RATEMCS0) ? 1 : 0));
 393
 394                if (rtlhal->version == VERSION_8192S_ACUT) {
 395                        if (ptcb_desc->hw_rate == DESC_RATE1M ||
 396                            ptcb_desc->hw_rate  == DESC_RATE2M ||
 397                            ptcb_desc->hw_rate == DESC_RATE5_5M ||
 398                            ptcb_desc->hw_rate == DESC_RATE11M) {
 399                                ptcb_desc->hw_rate = DESC_RATE12M;
 400                        }
 401                }
 402
 403                SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
 404
 405                if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
 406                        SET_TX_DESC_TX_SHORT(pdesc, 0);
 407
 408                /* Aggregation related */
 409                if (info->flags & IEEE80211_TX_CTL_AMPDU)
 410                        SET_TX_DESC_AGG_ENABLE(pdesc, 1);
 411
 412                /* For AMPDU, we must insert SSN into TX_DESC */
 413                SET_TX_DESC_SEQ(pdesc, seq_number);
 414
 415                /* Protection mode related */
 416                /* For 92S, if RTS/CTS are set, HW will execute RTS. */
 417                /* We choose only one protection mode to execute */
 418                SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
 419                                !ptcb_desc->cts_enable) ? 1 : 0));
 420                SET_TX_DESC_CTS_ENABLE(pdesc, ((ptcb_desc->cts_enable) ?
 421                                       1 : 0));
 422                SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
 423
 424                SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
 425                SET_TX_DESC_RTS_BANDWIDTH(pdesc, 0);
 426                SET_TX_DESC_RTS_SUB_CARRIER(pdesc, ptcb_desc->rts_sc);
 427                SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
 428                       DESC_RATE54M) ?
 429                       (ptcb_desc->rts_use_shortpreamble ? 1 : 0)
 430                       : (ptcb_desc->rts_use_shortgi ? 1 : 0)));
 431
 432
 433                /* Set Bandwidth and sub-channel settings. */
 434                if (bw_40) {
 435                        if (ptcb_desc->packet_bw) {
 436                                SET_TX_DESC_TX_BANDWIDTH(pdesc, 1);
 437                                /* use duplicated mode */
 438                                SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
 439                        } else {
 440                                SET_TX_DESC_TX_BANDWIDTH(pdesc, 0);
 441                                SET_TX_DESC_TX_SUB_CARRIER(pdesc,
 442                                                   mac->cur_40_prime_sc);
 443                        }
 444                } else {
 445                        SET_TX_DESC_TX_BANDWIDTH(pdesc, 0);
 446                        SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
 447                }
 448
 449                /* 3 Fill necessary field in First Descriptor */
 450                /*DWORD 0*/
 451                SET_TX_DESC_LINIP(pdesc, 0);
 452                SET_TX_DESC_OFFSET(pdesc, 32);
 453                SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
 454
 455                /*DWORD 1*/
 456                SET_TX_DESC_RA_BRSR_ID(pdesc, ptcb_desc->ratr_index);
 457
 458                /* Fill security related */
 459                if (info->control.hw_key) {
 460                        struct ieee80211_key_conf *keyconf;
 461
 462                        keyconf = info->control.hw_key;
 463                        switch (keyconf->cipher) {
 464                        case WLAN_CIPHER_SUITE_WEP40:
 465                        case WLAN_CIPHER_SUITE_WEP104:
 466                                SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
 467                                break;
 468                        case WLAN_CIPHER_SUITE_TKIP:
 469                                SET_TX_DESC_SEC_TYPE(pdesc, 0x2);
 470                                break;
 471                        case WLAN_CIPHER_SUITE_CCMP:
 472                                SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
 473                                break;
 474                        default:
 475                                SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
 476                                break;
 477
 478                        }
 479                }
 480
 481                /* Set Packet ID */
 482                SET_TX_DESC_PACKET_ID(pdesc, 0);
 483
 484                /* We will assign magement queue to BK. */
 485                SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
 486
 487                /* Alwasy enable all rate fallback range */
 488                SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
 489
 490                /* Fix: I don't kown why hw use 6.5M to tx when set it */
 491                SET_TX_DESC_USER_RATE(pdesc,
 492                                      ptcb_desc->use_driver_rate ? 1 : 0);
 493
 494                /* Set NON_QOS bit. */
 495                if (!ieee80211_is_data_qos(fc))
 496                        SET_TX_DESC_NON_QOS(pdesc, 1);
 497
 498        }
 499
 500        /* Fill fields that are required to be initialized
 501         * in all of the descriptors */
 502        /*DWORD 0 */
 503        SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
 504        SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
 505
 506        /* DWORD 7 */
 507        SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
 508
 509        /* DOWRD 8 */
 510        SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 511
 512        RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
 513}
 514
 515void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
 516        bool firstseg, bool lastseg, struct sk_buff *skb)
 517{
 518        struct rtl_priv *rtlpriv = rtl_priv(hw);
 519        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 520        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 521        struct rtl_tcb_desc *tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
 522
 523        dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
 524                        PCI_DMA_TODEVICE);
 525
 526        if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
 527                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 528                         "DMA mapping error\n");
 529                return;
 530        }
 531        /* Clear all status     */
 532        CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_CMDDESC_SIZE_RTL8192S);
 533
 534        /* This bit indicate this packet is used for FW download. */
 535        if (tcb_desc->cmd_or_init == DESC_PACKET_TYPE_INIT) {
 536                /* For firmware downlaod we only need to set LINIP */
 537                SET_TX_DESC_LINIP(pdesc, tcb_desc->last_inipkt);
 538
 539                /* 92SE must set as 1 for firmware download HW DMA error */
 540                SET_TX_DESC_FIRST_SEG(pdesc, 1);
 541                SET_TX_DESC_LAST_SEG(pdesc, 1);
 542
 543                /* 92SE need not to set TX packet size when firmware download */
 544                SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
 545                SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
 546                SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 547
 548                wmb();
 549                SET_TX_DESC_OWN(pdesc, 1);
 550        } else { /* H2C Command Desc format (Host TXCMD) */
 551                /* 92SE must set as 1 for firmware download HW DMA error */
 552                SET_TX_DESC_FIRST_SEG(pdesc, 1);
 553                SET_TX_DESC_LAST_SEG(pdesc, 1);
 554
 555                SET_TX_DESC_OFFSET(pdesc, 0x20);
 556
 557                /* Buffer size + command header */
 558                SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
 559                /* Fixed queue of H2C command */
 560                SET_TX_DESC_QUEUE_SEL(pdesc, 0x13);
 561
 562                SET_BITS_TO_LE_4BYTE(skb->data, 24, 7, rtlhal->h2c_txcmd_seq);
 563
 564                SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
 565                SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 566
 567                wmb();
 568                SET_TX_DESC_OWN(pdesc, 1);
 569
 570        }
 571}
 572
 573void rtl92se_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
 574                      u8 desc_name, u8 *val)
 575{
 576        if (istx) {
 577                switch (desc_name) {
 578                case HW_DESC_OWN:
 579                        wmb();
 580                        SET_TX_DESC_OWN(pdesc, 1);
 581                        break;
 582                case HW_DESC_TX_NEXTDESC_ADDR:
 583                        SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
 584                        break;
 585                default:
 586                        WARN_ONCE(true, "rtl8192se: ERR txdesc :%d not processed\n",
 587                                  desc_name);
 588                        break;
 589                }
 590        } else {
 591                switch (desc_name) {
 592                case HW_DESC_RXOWN:
 593                        wmb();
 594                        SET_RX_STATUS_DESC_OWN(pdesc, 1);
 595                        break;
 596                case HW_DESC_RXBUFF_ADDR:
 597                        SET_RX_STATUS__DESC_BUFF_ADDR(pdesc, *(u32 *) val);
 598                        break;
 599                case HW_DESC_RXPKT_LEN:
 600                        SET_RX_STATUS_DESC_PKT_LEN(pdesc, *(u32 *) val);
 601                        break;
 602                case HW_DESC_RXERO:
 603                        SET_RX_STATUS_DESC_EOR(pdesc, 1);
 604                        break;
 605                default:
 606                        WARN_ONCE(true, "rtl8192se: ERR rxdesc :%d not processed\n",
 607                                  desc_name);
 608                        break;
 609                }
 610        }
 611}
 612
 613u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name)
 614{
 615        u32 ret = 0;
 616
 617        if (istx) {
 618                switch (desc_name) {
 619                case HW_DESC_OWN:
 620                        ret = GET_TX_DESC_OWN(desc);
 621                        break;
 622                case HW_DESC_TXBUFF_ADDR:
 623                        ret = GET_TX_DESC_TX_BUFFER_ADDRESS(desc);
 624                        break;
 625                default:
 626                        WARN_ONCE(true, "rtl8192se: ERR txdesc :%d not processed\n",
 627                                  desc_name);
 628                        break;
 629                }
 630        } else {
 631                switch (desc_name) {
 632                case HW_DESC_OWN:
 633                        ret = GET_RX_STATUS_DESC_OWN(desc);
 634                        break;
 635                case HW_DESC_RXPKT_LEN:
 636                        ret = GET_RX_STATUS_DESC_PKT_LEN(desc);
 637                        break;
 638                case HW_DESC_RXBUFF_ADDR:
 639                        ret = GET_RX_STATUS_DESC_BUFF_ADDR(desc);
 640                        break;
 641                default:
 642                        WARN_ONCE(true, "rtl8192se: ERR rxdesc :%d not processed\n",
 643                                  desc_name);
 644                        break;
 645                }
 646        }
 647        return ret;
 648}
 649
 650void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
 651{
 652        struct rtl_priv *rtlpriv = rtl_priv(hw);
 653        rtl_write_word(rtlpriv, TP_POLL, BIT(0) << (hw_queue));
 654}
 655