linux/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2009-2010  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#include "dm.h"
  36#include "phy.h"
  37#include "fw.h"
  38
  39static u8 _rtl8821ae_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
  40{
  41        __le16 fc = rtl_get_fc(skb);
  42
  43        if (unlikely(ieee80211_is_beacon(fc)))
  44                return QSLT_BEACON;
  45        if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
  46                return QSLT_MGNT;
  47
  48        return skb->priority;
  49}
  50
  51static u16 odm_cfo(s8 value)
  52{
  53        int ret_val;
  54
  55        if (value < 0) {
  56                ret_val = 0 - value;
  57                ret_val = (ret_val << 1) + (ret_val >> 1);
  58                /* set bit12 as 1 for negative cfo */
  59                ret_val = ret_val | BIT(12);
  60        } else {
  61                ret_val = value;
  62                ret_val = (ret_val << 1) + (ret_val >> 1);
  63        }
  64        return ret_val;
  65}
  66
  67static u8 _rtl8821ae_evm_dbm_jaguar(s8 value)
  68{
  69        s8 ret_val = value;
  70
  71        /* -33dB~0dB to 33dB ~ 0dB*/
  72        if (ret_val == -128)
  73                ret_val = 127;
  74        else if (ret_val < 0)
  75                ret_val = 0 - ret_val;
  76
  77        ret_val  = ret_val >> 1;
  78        return ret_val;
  79}
  80
  81static void query_rxphystatus(struct ieee80211_hw *hw,
  82                              struct rtl_stats *pstatus, u8 *pdesc,
  83                              struct rx_fwinfo_8821ae *p_drvinfo,
  84                              bool bpacket_match_bssid,
  85                              bool bpacket_toself, bool packet_beacon)
  86{
  87        struct rtl_priv *rtlpriv = rtl_priv(hw);
  88        struct phy_status_rpt *p_phystrpt = (struct phy_status_rpt *)p_drvinfo;
  89        struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
  90        struct rtl_phy *rtlphy = &rtlpriv->phy;
  91        s8 rx_pwr_all = 0, rx_pwr[4];
  92        u8 rf_rx_num = 0, evm, evmdbm, pwdb_all;
  93        u8 i, max_spatial_stream;
  94        u32 rssi, total_rssi = 0;
  95        bool is_cck = pstatus->is_cck;
  96        u8 lan_idx, vga_idx;
  97
  98        /* Record it for next packet processing */
  99        pstatus->packet_matchbssid = bpacket_match_bssid;
 100        pstatus->packet_toself = bpacket_toself;
 101        pstatus->packet_beacon = packet_beacon;
 102        pstatus->rx_mimo_signalquality[0] = -1;
 103        pstatus->rx_mimo_signalquality[1] = -1;
 104
 105        if (is_cck) {
 106                u8 cck_highpwr;
 107                u8 cck_agc_rpt;
 108
 109                cck_agc_rpt = p_phystrpt->cfosho[0];
 110
 111                /* (1)Hardware does not provide RSSI for CCK
 112                 * (2)PWDB, Average PWDB cacluated by
 113                 * hardware (for rate adaptive)
 114                 */
 115                cck_highpwr = (u8)rtlphy->cck_high_power;
 116
 117                lan_idx = ((cck_agc_rpt & 0xE0) >> 5);
 118                vga_idx = (cck_agc_rpt & 0x1f);
 119                if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) {
 120                        switch (lan_idx) {
 121                        case 7:
 122                                if (vga_idx <= 27)
 123                                        /*VGA_idx = 27~2*/
 124                                        rx_pwr_all = -100 + 2*(27-vga_idx);
 125                                else
 126                                        rx_pwr_all = -100;
 127                                break;
 128                        case 6:
 129                                /*VGA_idx = 2~0*/
 130                                rx_pwr_all = -48 + 2*(2-vga_idx);
 131                                break;
 132                        case 5:
 133                                /*VGA_idx = 7~5*/
 134                                rx_pwr_all = -42 + 2*(7-vga_idx);
 135                                break;
 136                        case 4:
 137                                /*VGA_idx = 7~4*/
 138                                rx_pwr_all = -36 + 2*(7-vga_idx);
 139                                break;
 140                        case 3:
 141                                /*VGA_idx = 7~0*/
 142                                rx_pwr_all = -24 + 2*(7-vga_idx);
 143                                break;
 144                        case 2:
 145                                if (cck_highpwr)
 146                                        /*VGA_idx = 5~0*/
 147                                        rx_pwr_all = -12 + 2*(5-vga_idx);
 148                                else
 149                                        rx_pwr_all = -6 + 2*(5-vga_idx);
 150                                break;
 151                        case 1:
 152                                rx_pwr_all = 8-2*vga_idx;
 153                                break;
 154                        case 0:
 155                                rx_pwr_all = 14-2*vga_idx;
 156                                break;
 157                        default:
 158                                break;
 159                        }
 160                        rx_pwr_all += 6;
 161                        pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
 162                        if (!cck_highpwr) {
 163                                if (pwdb_all >= 80)
 164                                        pwdb_all =
 165                                          ((pwdb_all - 80)<<1) +
 166                                         ((pwdb_all - 80)>>1) + 80;
 167                                else if ((pwdb_all <= 78) && (pwdb_all >= 20))
 168                                        pwdb_all += 3;
 169                                if (pwdb_all > 100)
 170                                        pwdb_all = 100;
 171                        }
 172                } else { /* 8821 */
 173                        s8 pout = -6;
 174
 175                        switch (lan_idx) {
 176                        case 5:
 177                                rx_pwr_all = pout - 32 - (2*vga_idx);
 178                                        break;
 179                        case 4:
 180                                rx_pwr_all = pout - 24 - (2*vga_idx);
 181                                        break;
 182                        case 2:
 183                                rx_pwr_all = pout - 11 - (2*vga_idx);
 184                                        break;
 185                        case 1:
 186                                rx_pwr_all = pout + 5 - (2*vga_idx);
 187                                        break;
 188                        case 0:
 189                                rx_pwr_all = pout + 21 - (2*vga_idx);
 190                                        break;
 191                        }
 192                        pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
 193                }
 194
 195                pstatus->rx_pwdb_all = pwdb_all;
 196                pstatus->recvsignalpower = rx_pwr_all;
 197
 198                /* (3) Get Signal Quality (EVM) */
 199                if (bpacket_match_bssid) {
 200                        u8 sq;
 201
 202                        if (pstatus->rx_pwdb_all > 40) {
 203                                sq = 100;
 204                        } else {
 205                                sq = p_phystrpt->pwdb_all;
 206                                if (sq > 64)
 207                                        sq = 0;
 208                                else if (sq < 20)
 209                                        sq = 100;
 210                                else
 211                                        sq = ((64 - sq) * 100) / 44;
 212                        }
 213
 214                        pstatus->signalquality = sq;
 215                        pstatus->rx_mimo_signalquality[0] = sq;
 216                        pstatus->rx_mimo_signalquality[1] = -1;
 217                }
 218        } else {
 219                /* (1)Get RSSI for HT rate */
 220                for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
 221                        /* we will judge RF RX path now. */
 222                        if (rtlpriv->dm.rfpath_rxenable[i])
 223                                rf_rx_num++;
 224
 225                        rx_pwr[i] = (p_phystrpt->gain_trsw[i] & 0x7f) - 110;
 226
 227                        /* Translate DBM to percentage. */
 228                        rssi = rtl_query_rxpwrpercentage(rx_pwr[i]);
 229                        total_rssi += rssi;
 230
 231                        /* Get Rx snr value in DB */
 232                        pstatus->rx_snr[i] = p_phystrpt->rxsnr[i] / 2;
 233                        rtlpriv->stats.rx_snr_db[i] = p_phystrpt->rxsnr[i] / 2;
 234
 235                        pstatus->cfo_short[i] = odm_cfo(p_phystrpt->cfosho[i]);
 236                        pstatus->cfo_tail[i] = odm_cfo(p_phystrpt->cfotail[i]);
 237                        /* Record Signal Strength for next packet */
 238                        pstatus->rx_mimo_signalstrength[i] = (u8)rssi;
 239                }
 240
 241                /* (2)PWDB, Average PWDB cacluated by
 242                 * hardware (for rate adaptive)
 243                 */
 244                rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
 245
 246                pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
 247                pstatus->rx_pwdb_all = pwdb_all;
 248                pstatus->rxpower = rx_pwr_all;
 249                pstatus->recvsignalpower = rx_pwr_all;
 250
 251                /* (3)EVM of HT rate */
 252                if ((pstatus->is_ht && pstatus->rate >= DESC_RATEMCS8 &&
 253                     pstatus->rate <= DESC_RATEMCS15) ||
 254                    (pstatus->is_vht &&
 255                     pstatus->rate >= DESC_RATEVHT2SS_MCS0 &&
 256                     pstatus->rate <= DESC_RATEVHT2SS_MCS9))
 257                        max_spatial_stream = 2;
 258                else
 259                        max_spatial_stream = 1;
 260
 261                for (i = 0; i < max_spatial_stream; i++) {
 262                        evm = rtl_evm_db_to_percentage(p_phystrpt->rxevm[i]);
 263                        evmdbm = _rtl8821ae_evm_dbm_jaguar(p_phystrpt->rxevm[i]);
 264
 265                        if (bpacket_match_bssid) {
 266                                /* Fill value in RFD, Get the first
 267                                 * spatial stream only
 268                                 */
 269                                if (i == 0)
 270                                        pstatus->signalquality = evm;
 271                                pstatus->rx_mimo_signalquality[i] = evm;
 272                                pstatus->rx_mimo_evm_dbm[i] = evmdbm;
 273                        }
 274                }
 275                if (bpacket_match_bssid) {
 276                        for (i = RF90_PATH_A; i <= RF90_PATH_B; i++)
 277                                rtl_priv(hw)->dm.cfo_tail[i] =
 278                                        (s8)p_phystrpt->cfotail[i];
 279
 280                        rtl_priv(hw)->dm.packet_count++;
 281                }
 282        }
 283
 284        /* UI BSS List signal strength(in percentage),
 285         * make it good looking, from 0~100.
 286         */
 287        if (is_cck)
 288                pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
 289                        pwdb_all));
 290        else if (rf_rx_num != 0)
 291                pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
 292                        total_rssi /= rf_rx_num));
 293        /*HW antenna diversity*/
 294        rtldm->fat_table.antsel_rx_keep_0 = p_phystrpt->antidx_anta;
 295        rtldm->fat_table.antsel_rx_keep_1 = p_phystrpt->antidx_antb;
 296}
 297
 298static void translate_rx_signal_stuff(struct ieee80211_hw *hw,
 299                                      struct sk_buff *skb,
 300                                      struct rtl_stats *pstatus, u8 *pdesc,
 301                                      struct rx_fwinfo_8821ae *p_drvinfo)
 302{
 303        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 304        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 305        struct ieee80211_hdr *hdr;
 306        u8 *tmp_buf;
 307        u8 *praddr;
 308        u8 *psaddr;
 309        __le16 fc;
 310        u16 type;
 311        bool packet_matchbssid, packet_toself, packet_beacon;
 312
 313        tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift;
 314
 315        hdr = (struct ieee80211_hdr *)tmp_buf;
 316        fc = hdr->frame_control;
 317        type = WLAN_FC_GET_TYPE(hdr->frame_control);
 318        praddr = hdr->addr1;
 319        psaddr = ieee80211_get_SA(hdr);
 320        ether_addr_copy(pstatus->psaddr, psaddr);
 321
 322        packet_matchbssid = (!ieee80211_is_ctl(fc) &&
 323                             (ether_addr_equal(mac->bssid,
 324                                               ieee80211_has_tods(fc) ?
 325                                               hdr->addr1 :
 326                                               ieee80211_has_fromds(fc) ?
 327                                               hdr->addr2 : hdr->addr3)) &&
 328                              (!pstatus->hwerror) &&
 329                              (!pstatus->crc) && (!pstatus->icv));
 330
 331        packet_toself = packet_matchbssid &&
 332            (ether_addr_equal(praddr, rtlefuse->dev_addr));
 333
 334        if (ieee80211_is_beacon(hdr->frame_control))
 335                packet_beacon = true;
 336        else
 337                packet_beacon = false;
 338
 339        if (packet_beacon && packet_matchbssid)
 340                rtl_priv(hw)->dm.dbginfo.num_qry_beacon_pkt++;
 341
 342        if (packet_matchbssid &&
 343            ieee80211_is_data_qos(hdr->frame_control) &&
 344            !is_multicast_ether_addr(ieee80211_get_DA(hdr))) {
 345                struct ieee80211_qos_hdr *hdr_qos =
 346                        (struct ieee80211_qos_hdr *)tmp_buf;
 347                u16 tid = le16_to_cpu(hdr_qos->qos_ctrl) & 0xf;
 348
 349                if (tid != 0 && tid != 3)
 350                        rtl_priv(hw)->dm.dbginfo.num_non_be_pkt++;
 351        }
 352
 353        query_rxphystatus(hw, pstatus, pdesc, p_drvinfo,
 354                          packet_matchbssid, packet_toself,
 355                          packet_beacon);
 356        /*_rtl8821ae_smart_antenna(hw, pstatus); */
 357        rtl_process_phyinfo(hw, tmp_buf, pstatus);
 358}
 359
 360static void _rtl8821ae_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
 361                                        u8 *virtualaddress)
 362{
 363        u32 dwtmp = 0;
 364
 365        memset(virtualaddress, 0, 8);
 366
 367        SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num);
 368        if (ptcb_desc->empkt_num == 1) {
 369                dwtmp = ptcb_desc->empkt_len[0];
 370        } else {
 371                dwtmp = ptcb_desc->empkt_len[0];
 372                dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0)+4;
 373                dwtmp += ptcb_desc->empkt_len[1];
 374        }
 375        SET_EARLYMODE_LEN0(virtualaddress, dwtmp);
 376
 377        if (ptcb_desc->empkt_num <= 3) {
 378                dwtmp = ptcb_desc->empkt_len[2];
 379        } else {
 380                dwtmp = ptcb_desc->empkt_len[2];
 381                dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0)+4;
 382                dwtmp += ptcb_desc->empkt_len[3];
 383        }
 384        SET_EARLYMODE_LEN1(virtualaddress, dwtmp);
 385        if (ptcb_desc->empkt_num <= 5) {
 386                dwtmp = ptcb_desc->empkt_len[4];
 387        } else {
 388                dwtmp = ptcb_desc->empkt_len[4];
 389                dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0)+4;
 390                dwtmp += ptcb_desc->empkt_len[5];
 391        }
 392        SET_EARLYMODE_LEN2_1(virtualaddress, dwtmp & 0xF);
 393        SET_EARLYMODE_LEN2_2(virtualaddress, dwtmp >> 4);
 394        if (ptcb_desc->empkt_num <= 7) {
 395                dwtmp = ptcb_desc->empkt_len[6];
 396        } else {
 397                dwtmp = ptcb_desc->empkt_len[6];
 398                dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0)+4;
 399                dwtmp += ptcb_desc->empkt_len[7];
 400        }
 401        SET_EARLYMODE_LEN3(virtualaddress, dwtmp);
 402        if (ptcb_desc->empkt_num <= 9) {
 403                dwtmp = ptcb_desc->empkt_len[8];
 404        } else {
 405                dwtmp = ptcb_desc->empkt_len[8];
 406                dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0)+4;
 407                dwtmp += ptcb_desc->empkt_len[9];
 408        }
 409        SET_EARLYMODE_LEN4(virtualaddress, dwtmp);
 410}
 411
 412static bool rtl8821ae_get_rxdesc_is_ht(struct ieee80211_hw *hw, u8 *pdesc)
 413{
 414        struct rtl_priv *rtlpriv = rtl_priv(hw);
 415        u8 rx_rate = 0;
 416
 417        rx_rate = GET_RX_DESC_RXMCS(pdesc);
 418
 419        RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD, "rx_rate=0x%02x.\n", rx_rate);
 420
 421        if ((rx_rate >= DESC_RATEMCS0) && (rx_rate <= DESC_RATEMCS15))
 422                return true;
 423        return false;
 424}
 425
 426static bool rtl8821ae_get_rxdesc_is_vht(struct ieee80211_hw *hw, u8 *pdesc)
 427{
 428        struct rtl_priv *rtlpriv = rtl_priv(hw);
 429        u8 rx_rate = 0;
 430
 431        rx_rate = GET_RX_DESC_RXMCS(pdesc);
 432
 433        RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD, "rx_rate=0x%02x.\n", rx_rate);
 434
 435        if (rx_rate >= DESC_RATEVHT1SS_MCS0)
 436                return true;
 437        return false;
 438}
 439
 440static u8 rtl8821ae_get_rx_vht_nss(struct ieee80211_hw *hw, u8 *pdesc)
 441{
 442        u8 rx_rate = 0;
 443        u8 vht_nss = 0;
 444
 445        rx_rate = GET_RX_DESC_RXMCS(pdesc);
 446        if ((rx_rate >= DESC_RATEVHT1SS_MCS0) &&
 447            (rx_rate <= DESC_RATEVHT1SS_MCS9))
 448                vht_nss = 1;
 449        else if ((rx_rate >= DESC_RATEVHT2SS_MCS0) &&
 450                 (rx_rate <= DESC_RATEVHT2SS_MCS9))
 451                vht_nss = 2;
 452
 453        return vht_nss;
 454}
 455
 456bool rtl8821ae_rx_query_desc(struct ieee80211_hw *hw,
 457                             struct rtl_stats *status,
 458                             struct ieee80211_rx_status *rx_status,
 459                             u8 *pdesc, struct sk_buff *skb)
 460{
 461        struct rtl_priv *rtlpriv = rtl_priv(hw);
 462        struct rx_fwinfo_8821ae *p_drvinfo;
 463        struct ieee80211_hdr *hdr;
 464
 465        u32 phystatus = GET_RX_DESC_PHYST(pdesc);
 466
 467        status->length = (u16)GET_RX_DESC_PKT_LEN(pdesc);
 468        status->rx_drvinfo_size = (u8)GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
 469            RX_DRV_INFO_SIZE_UNIT;
 470        status->rx_bufshift = (u8)(GET_RX_DESC_SHIFT(pdesc) & 0x03);
 471        status->icv = (u16)GET_RX_DESC_ICV(pdesc);
 472        status->crc = (u16)GET_RX_DESC_CRC32(pdesc);
 473        status->hwerror = (status->crc | status->icv);
 474        status->decrypted = !GET_RX_DESC_SWDEC(pdesc);
 475        status->rate = (u8)GET_RX_DESC_RXMCS(pdesc);
 476        status->shortpreamble = (u16)GET_RX_DESC_SPLCP(pdesc);
 477        status->isampdu = (bool)(GET_RX_DESC_PAGGR(pdesc) == 1);
 478        status->isfirst_ampdu = (bool)(GET_RX_DESC_PAGGR(pdesc) == 1);
 479        status->timestamp_low = GET_RX_DESC_TSFL(pdesc);
 480        status->rx_packet_bw = GET_RX_DESC_BW(pdesc);
 481        status->macid = GET_RX_DESC_MACID(pdesc);
 482        status->is_short_gi = !(bool)GET_RX_DESC_SPLCP(pdesc);
 483        status->is_ht = rtl8821ae_get_rxdesc_is_ht(hw, pdesc);
 484        status->is_vht = rtl8821ae_get_rxdesc_is_vht(hw, pdesc);
 485        status->vht_nss = rtl8821ae_get_rx_vht_nss(hw, pdesc);
 486        status->is_cck = RTL8821AE_RX_HAL_IS_CCK_RATE(status->rate);
 487
 488        RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD,
 489                 "rx_packet_bw=%s,is_ht %d, is_vht %d, vht_nss=%d,is_short_gi %d.\n",
 490                 (status->rx_packet_bw == 2) ? "80M" :
 491                 (status->rx_packet_bw == 1) ? "40M" : "20M",
 492                 status->is_ht, status->is_vht, status->vht_nss,
 493                 status->is_short_gi);
 494
 495        if (GET_RX_STATUS_DESC_RPT_SEL(pdesc))
 496                status->packet_report_type = C2H_PACKET;
 497        else
 498                status->packet_report_type = NORMAL_RX;
 499
 500        if (GET_RX_STATUS_DESC_PATTERN_MATCH(pdesc))
 501                status->wake_match = BIT(2);
 502        else if (GET_RX_STATUS_DESC_MAGIC_MATCH(pdesc))
 503                status->wake_match = BIT(1);
 504        else if (GET_RX_STATUS_DESC_UNICAST_MATCH(pdesc))
 505                status->wake_match = BIT(0);
 506        else
 507                status->wake_match = 0;
 508
 509        if (status->wake_match)
 510                RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD,
 511                         "GGGGGGGGGGGGGet Wakeup Packet!! WakeMatch=%d\n",
 512                         status->wake_match);
 513        rx_status->freq = hw->conf.chandef.chan->center_freq;
 514        rx_status->band = hw->conf.chandef.chan->band;
 515
 516        hdr = (struct ieee80211_hdr *)(skb->data +
 517              status->rx_drvinfo_size + status->rx_bufshift);
 518
 519        if (status->crc)
 520                rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
 521
 522        if (status->rx_packet_bw == HT_CHANNEL_WIDTH_20_40)
 523                rx_status->bw = RATE_INFO_BW_40;
 524        else if (status->rx_packet_bw == HT_CHANNEL_WIDTH_80)
 525                rx_status->bw = RATE_INFO_BW_80;
 526        if (status->is_ht)
 527                rx_status->encoding = RX_ENC_HT;
 528        if (status->is_vht)
 529                rx_status->encoding = RX_ENC_VHT;
 530
 531        if (status->is_short_gi)
 532                rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
 533
 534        rx_status->nss = status->vht_nss;
 535        rx_status->flag |= RX_FLAG_MACTIME_START;
 536
 537        /* hw will set status->decrypted true, if it finds the
 538         * frame is open data frame or mgmt frame.
 539         * So hw will not decryption robust managment frame
 540         * for IEEE80211w but still set status->decrypted
 541         * true, so here we should set it back to undecrypted
 542         * for IEEE80211w frame, and mac80211 sw will help
 543         * to decrypt it
 544         */
 545        if (status->decrypted) {
 546                if ((!_ieee80211_is_robust_mgmt_frame(hdr)) &&
 547                    (ieee80211_has_protected(hdr->frame_control)))
 548                        rx_status->flag |= RX_FLAG_DECRYPTED;
 549                else
 550                        rx_status->flag &= ~RX_FLAG_DECRYPTED;
 551        }
 552
 553        /* rate_idx: index of data rate into band's
 554         * supported rates or MCS index if HT rates
 555         * are use (RX_FLAG_HT)
 556         */
 557        rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht,
 558                                                   status->is_vht,
 559                                                   status->rate);
 560
 561        rx_status->mactime = status->timestamp_low;
 562        if (phystatus) {
 563                p_drvinfo = (struct rx_fwinfo_8821ae *)(skb->data +
 564                            status->rx_bufshift);
 565
 566                translate_rx_signal_stuff(hw, skb, status, pdesc, p_drvinfo);
 567        }
 568        rx_status->signal = status->recvsignalpower + 10;
 569        if (status->packet_report_type == TX_REPORT2) {
 570                status->macid_valid_entry[0] =
 571                  GET_RX_RPT2_DESC_MACID_VALID_1(pdesc);
 572                status->macid_valid_entry[1] =
 573                  GET_RX_RPT2_DESC_MACID_VALID_2(pdesc);
 574        }
 575        return true;
 576}
 577
 578static u8 rtl8821ae_bw_mapping(struct ieee80211_hw *hw,
 579                               struct rtl_tcb_desc *ptcb_desc)
 580{
 581        struct rtl_priv *rtlpriv = rtl_priv(hw);
 582        struct rtl_phy *rtlphy = &rtlpriv->phy;
 583        u8 bw_setting_of_desc = 0;
 584
 585        RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 586                 "rtl8821ae_bw_mapping, current_chan_bw %d, packet_bw %d\n",
 587                 rtlphy->current_chan_bw, ptcb_desc->packet_bw);
 588
 589        if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
 590                if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80)
 591                        bw_setting_of_desc = 2;
 592                else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40)
 593                        bw_setting_of_desc = 1;
 594                else
 595                        bw_setting_of_desc = 0;
 596        } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
 597                if ((ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) ||
 598                    (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80))
 599                        bw_setting_of_desc = 1;
 600                else
 601                        bw_setting_of_desc = 0;
 602        } else {
 603                bw_setting_of_desc = 0;
 604        }
 605        return bw_setting_of_desc;
 606}
 607
 608static u8 rtl8821ae_sc_mapping(struct ieee80211_hw *hw,
 609                               struct rtl_tcb_desc *ptcb_desc)
 610{
 611        struct rtl_priv *rtlpriv = rtl_priv(hw);
 612        struct rtl_phy *rtlphy = &rtlpriv->phy;
 613        struct rtl_mac *mac = rtl_mac(rtlpriv);
 614        u8 sc_setting_of_desc = 0;
 615
 616        if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
 617                if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80) {
 618                        sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE;
 619                } else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) {
 620                        if (mac->cur_80_prime_sc ==
 621                            HAL_PRIME_CHNL_OFFSET_LOWER)
 622                                sc_setting_of_desc =
 623                                        VHT_DATA_SC_40_LOWER_OF_80MHZ;
 624                        else if (mac->cur_80_prime_sc ==
 625                                 HAL_PRIME_CHNL_OFFSET_UPPER)
 626                                sc_setting_of_desc =
 627                                        VHT_DATA_SC_40_UPPER_OF_80MHZ;
 628                        else
 629                                RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD,
 630                                         "rtl8821ae_sc_mapping: Not Correct Primary40MHz Setting\n");
 631                } else {
 632                        if ((mac->cur_40_prime_sc ==
 633                             HAL_PRIME_CHNL_OFFSET_LOWER) &&
 634                            (mac->cur_80_prime_sc  ==
 635                             HAL_PRIME_CHNL_OFFSET_LOWER))
 636                                sc_setting_of_desc =
 637                                        VHT_DATA_SC_20_LOWEST_OF_80MHZ;
 638                        else if ((mac->cur_40_prime_sc ==
 639                                  HAL_PRIME_CHNL_OFFSET_UPPER) &&
 640                                 (mac->cur_80_prime_sc ==
 641                                  HAL_PRIME_CHNL_OFFSET_LOWER))
 642                                sc_setting_of_desc =
 643                                        VHT_DATA_SC_20_LOWER_OF_80MHZ;
 644                        else if ((mac->cur_40_prime_sc ==
 645                                  HAL_PRIME_CHNL_OFFSET_LOWER) &&
 646                                 (mac->cur_80_prime_sc ==
 647                                  HAL_PRIME_CHNL_OFFSET_UPPER))
 648                                sc_setting_of_desc =
 649                                        VHT_DATA_SC_20_UPPER_OF_80MHZ;
 650                        else if ((mac->cur_40_prime_sc ==
 651                                  HAL_PRIME_CHNL_OFFSET_UPPER) &&
 652                                 (mac->cur_80_prime_sc ==
 653                                  HAL_PRIME_CHNL_OFFSET_UPPER))
 654                                sc_setting_of_desc =
 655                                        VHT_DATA_SC_20_UPPERST_OF_80MHZ;
 656                        else
 657                                RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD,
 658                                         "rtl8821ae_sc_mapping: Not Correct Primary40MHz Setting\n");
 659                }
 660        } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
 661                if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) {
 662                        sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE;
 663                } else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20) {
 664                        if (mac->cur_40_prime_sc ==
 665                                HAL_PRIME_CHNL_OFFSET_UPPER) {
 666                                sc_setting_of_desc =
 667                                        VHT_DATA_SC_20_UPPER_OF_80MHZ;
 668                        } else if (mac->cur_40_prime_sc ==
 669                                HAL_PRIME_CHNL_OFFSET_LOWER){
 670                                sc_setting_of_desc =
 671                                        VHT_DATA_SC_20_LOWER_OF_80MHZ;
 672                        } else {
 673                                sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE;
 674                        }
 675                }
 676        } else {
 677                sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE;
 678        }
 679
 680        return sc_setting_of_desc;
 681}
 682
 683void rtl8821ae_tx_fill_desc(struct ieee80211_hw *hw,
 684                            struct ieee80211_hdr *hdr, u8 *pdesc_tx, u8 *txbd,
 685                            struct ieee80211_tx_info *info,
 686                            struct ieee80211_sta *sta,
 687                            struct sk_buff *skb,
 688                            u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
 689{
 690        struct rtl_priv *rtlpriv = rtl_priv(hw);
 691        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 692        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 693        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 694        struct rtlwifi_tx_info *tx_info = rtl_tx_skb_cb_info(skb);
 695        u8 *pdesc = (u8 *)pdesc_tx;
 696        u16 seq_number;
 697        __le16 fc = hdr->frame_control;
 698        unsigned int buf_len = 0;
 699        unsigned int skb_len = skb->len;
 700        u8 fw_qsel = _rtl8821ae_map_hwqueue_to_fwqueue(skb, hw_queue);
 701        bool firstseg = ((hdr->seq_ctrl &
 702                          cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
 703        bool lastseg = ((hdr->frame_control &
 704                         cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
 705        dma_addr_t mapping;
 706        u8 short_gi = 0;
 707
 708        seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
 709        rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
 710        /* reserve 8 byte for AMPDU early mode */
 711        if (rtlhal->earlymode_enable) {
 712                skb_push(skb, EM_HDR_LEN);
 713                memset(skb->data, 0, EM_HDR_LEN);
 714        }
 715        buf_len = skb->len;
 716        mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
 717                                 PCI_DMA_TODEVICE);
 718        if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
 719                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 720                         "DMA mapping error\n");
 721                return;
 722        }
 723        CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_8821ae));
 724        if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
 725                firstseg = true;
 726                lastseg = true;
 727        }
 728        if (firstseg) {
 729                if (rtlhal->earlymode_enable) {
 730                        SET_TX_DESC_PKT_OFFSET(pdesc, 1);
 731                        SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN +
 732                                           EM_HDR_LEN);
 733                        if (ptcb_desc->empkt_num) {
 734                                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 735                                         "Insert 8 byte.pTcb->EMPktNum:%d\n",
 736                                          ptcb_desc->empkt_num);
 737                                _rtl8821ae_insert_emcontent(ptcb_desc,
 738                                         (u8 *)(skb->data));
 739                        }
 740                } else {
 741                        SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
 742                }
 743
 744
 745                /* ptcb_desc->use_driver_rate = true; */
 746                SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
 747                if (ptcb_desc->hw_rate > DESC_RATEMCS0)
 748                        short_gi = (ptcb_desc->use_shortgi) ? 1 : 0;
 749                else
 750                        short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0;
 751
 752                SET_TX_DESC_DATA_SHORTGI(pdesc, short_gi);
 753
 754                if (info->flags & IEEE80211_TX_CTL_AMPDU) {
 755                        SET_TX_DESC_AGG_ENABLE(pdesc, 1);
 756                        SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x1f);
 757                }
 758                SET_TX_DESC_SEQ(pdesc, seq_number);
 759                SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
 760                                        !ptcb_desc->cts_enable) ? 1 : 0));
 761                SET_TX_DESC_HW_RTS_ENABLE(pdesc, 0);
 762                SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0));
 763
 764                SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
 765                SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
 766                SET_TX_DESC_RTS_SHORT(pdesc,
 767                        ((ptcb_desc->rts_rate <= DESC_RATE54M) ?
 768                        (ptcb_desc->rts_use_shortpreamble ? 1 : 0) :
 769                        (ptcb_desc->rts_use_shortgi ? 1 : 0)));
 770
 771                if (ptcb_desc->tx_enable_sw_calc_duration)
 772                        SET_TX_DESC_NAV_USE_HDR(pdesc, 1);
 773
 774                SET_TX_DESC_DATA_BW(pdesc,
 775                        rtl8821ae_bw_mapping(hw, ptcb_desc));
 776
 777                SET_TX_DESC_TX_SUB_CARRIER(pdesc,
 778                        rtl8821ae_sc_mapping(hw, ptcb_desc));
 779
 780                SET_TX_DESC_LINIP(pdesc, 0);
 781                SET_TX_DESC_PKT_SIZE(pdesc, (u16)skb_len);
 782                if (sta) {
 783                        u8 ampdu_density = sta->ht_cap.ampdu_density;
 784
 785                        SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
 786                }
 787                if (info->control.hw_key) {
 788                        struct ieee80211_key_conf *keyconf =
 789                                info->control.hw_key;
 790                        switch (keyconf->cipher) {
 791                        case WLAN_CIPHER_SUITE_WEP40:
 792                        case WLAN_CIPHER_SUITE_WEP104:
 793                        case WLAN_CIPHER_SUITE_TKIP:
 794                                SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
 795                                break;
 796                        case WLAN_CIPHER_SUITE_CCMP:
 797                                SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
 798                                break;
 799                        default:
 800                                SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
 801                                break;
 802                        }
 803                }
 804
 805                SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
 806                SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
 807                SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
 808                SET_TX_DESC_DISABLE_FB(pdesc, ptcb_desc->disable_ratefallback ?
 809                                       1 : 0);
 810                SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
 811
 812                if (ieee80211_is_data_qos(fc)) {
 813                        if (mac->rdg_en) {
 814                                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 815                                         "Enable RDG function.\n");
 816                                SET_TX_DESC_RDG_ENABLE(pdesc, 1);
 817                                SET_TX_DESC_HTC(pdesc, 1);
 818                        }
 819                }
 820                /* tx report */
 821                rtl_set_tx_report(ptcb_desc, pdesc, hw, tx_info);
 822        }
 823
 824        SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
 825        SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
 826        SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)buf_len);
 827        SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 828        /* if (rtlpriv->dm.useramask) { */
 829        if (1) {
 830                SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index);
 831                SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
 832        } else {
 833                SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index);
 834                SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
 835        }
 836        if (!ieee80211_is_data_qos(fc))  {
 837                SET_TX_DESC_HWSEQ_EN(pdesc, 1);
 838                SET_TX_DESC_HWSEQ_SEL(pdesc, 0);
 839        }
 840        SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
 841        if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
 842            is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
 843                SET_TX_DESC_BMC(pdesc, 1);
 844        }
 845
 846        rtl8821ae_dm_set_tx_ant_by_tx_info(hw, pdesc, ptcb_desc->mac_id);
 847        RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
 848}
 849
 850void rtl8821ae_tx_fill_cmddesc(struct ieee80211_hw *hw,
 851                               u8 *pdesc, bool firstseg,
 852                               bool lastseg, struct sk_buff *skb)
 853{
 854        struct rtl_priv *rtlpriv = rtl_priv(hw);
 855        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 856        u8 fw_queue = QSLT_BEACON;
 857
 858        dma_addr_t mapping = pci_map_single(rtlpci->pdev,
 859                                            skb->data, skb->len,
 860                                            PCI_DMA_TODEVICE);
 861
 862        if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
 863                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 864                         "DMA mapping error\n");
 865                return;
 866        }
 867        CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
 868
 869        SET_TX_DESC_FIRST_SEG(pdesc, 1);
 870        SET_TX_DESC_LAST_SEG(pdesc, 1);
 871
 872        SET_TX_DESC_PKT_SIZE((u8 *)pdesc, (u16)(skb->len));
 873
 874        SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
 875
 876        SET_TX_DESC_USE_RATE(pdesc, 1);
 877        SET_TX_DESC_TX_RATE(pdesc, DESC_RATE1M);
 878        SET_TX_DESC_DISABLE_FB(pdesc, 1);
 879
 880        SET_TX_DESC_DATA_BW(pdesc, 0);
 881
 882        SET_TX_DESC_HWSEQ_EN(pdesc, 1);
 883
 884        SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
 885
 886        SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
 887
 888        SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 889
 890        SET_TX_DESC_MACID(pdesc, 0);
 891
 892        SET_TX_DESC_OWN(pdesc, 1);
 893
 894        RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
 895                      "H2C Tx Cmd Content\n",
 896                      pdesc, TX_DESC_SIZE);
 897}
 898
 899void rtl8821ae_set_desc(struct ieee80211_hw *hw, u8 *pdesc,
 900                        bool istx, u8 desc_name, u8 *val)
 901{
 902        if (istx) {
 903                switch (desc_name) {
 904                case HW_DESC_OWN:
 905                        SET_TX_DESC_OWN(pdesc, 1);
 906                        break;
 907                case HW_DESC_TX_NEXTDESC_ADDR:
 908                        SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *)val);
 909                        break;
 910                default:
 911                        WARN_ONCE(true,
 912                                  "rtl8821ae: ERR txdesc :%d not processed\n",
 913                                  desc_name);
 914                        break;
 915                }
 916        } else {
 917                switch (desc_name) {
 918                case HW_DESC_RXOWN:
 919                        SET_RX_DESC_OWN(pdesc, 1);
 920                        break;
 921                case HW_DESC_RXBUFF_ADDR:
 922                        SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *)val);
 923                        break;
 924                case HW_DESC_RXPKT_LEN:
 925                        SET_RX_DESC_PKT_LEN(pdesc, *(u32 *)val);
 926                        break;
 927                case HW_DESC_RXERO:
 928                        SET_RX_DESC_EOR(pdesc, 1);
 929                        break;
 930                default:
 931                        WARN_ONCE(true,
 932                                  "rtl8821ae: ERR rxdesc :%d not processed\n",
 933                                  desc_name);
 934                        break;
 935                }
 936        }
 937}
 938
 939u64 rtl8821ae_get_desc(struct ieee80211_hw *hw,
 940                       u8 *pdesc, bool istx, u8 desc_name)
 941{
 942        u32 ret = 0;
 943
 944        if (istx) {
 945                switch (desc_name) {
 946                case HW_DESC_OWN:
 947                        ret = GET_TX_DESC_OWN(pdesc);
 948                        break;
 949                case HW_DESC_TXBUFF_ADDR:
 950                        ret = GET_TX_DESC_TX_BUFFER_ADDRESS(pdesc);
 951                        break;
 952                default:
 953                        WARN_ONCE(true,
 954                                  "rtl8821ae: ERR txdesc :%d not processed\n",
 955                                  desc_name);
 956                        break;
 957                }
 958        } else {
 959                switch (desc_name) {
 960                case HW_DESC_OWN:
 961                        ret = GET_RX_DESC_OWN(pdesc);
 962                        break;
 963                case HW_DESC_RXPKT_LEN:
 964                        ret = GET_RX_DESC_PKT_LEN(pdesc);
 965                        break;
 966                case HW_DESC_RXBUFF_ADDR:
 967                        ret = GET_RX_DESC_BUFF_ADDR(pdesc);
 968                        break;
 969                default:
 970                        WARN_ONCE(true,
 971                                  "rtl8821ae: ERR rxdesc :%d not processed\n",
 972                                  desc_name);
 973                        break;
 974                }
 975        }
 976        return ret;
 977}
 978
 979bool rtl8821ae_is_tx_desc_closed(struct ieee80211_hw *hw,
 980                                 u8 hw_queue, u16 index)
 981{
 982        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 983        struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
 984        u8 *entry = (u8 *)(&ring->desc[ring->idx]);
 985        u8 own = (u8)rtl8821ae_get_desc(hw, entry, true, HW_DESC_OWN);
 986
 987        /**
 988         *beacon packet will only use the first
 989         *descriptor defautly,and the own may not
 990         *be cleared by the hardware
 991         */
 992        if (own)
 993                return false;
 994        return true;
 995}
 996
 997void rtl8821ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
 998{
 999        struct rtl_priv *rtlpriv = rtl_priv(hw);
1000
1001        if (hw_queue == BEACON_QUEUE) {
1002                rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
1003        } else {
1004                rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
1005                               BIT(0) << (hw_queue));
1006        }
1007}
1008