linux/drivers/staging/r8188eu/core/rtw_mp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2007 - 2011 Realtek Corporation. */
   3
   4#define _RTW_MP_C_
   5
   6#include "../include/drv_types.h"
   7#include "../include/odm_precomp.h"
   8#include "../include/rtl8188e_hal.h"
   9
  10u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask)
  11{
  12        return rtw_hal_read_bbreg(padapter, addr, bitmask);
  13}
  14
  15void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val)
  16{
  17        rtw_hal_write_bbreg(padapter, addr, bitmask, val);
  18}
  19
  20u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask)
  21{
  22        return rtw_hal_read_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bitmask);
  23}
  24
  25void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val)
  26{
  27        rtw_hal_write_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bitmask, val);
  28}
  29
  30u32 read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr)
  31{
  32        return _read_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bRFRegOffsetMask);
  33}
  34
  35void write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 val)
  36{
  37        _write_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bRFRegOffsetMask, val);
  38}
  39
  40static void _init_mp_priv_(struct mp_priv *pmp_priv)
  41{
  42        struct wlan_bssid_ex *pnetwork;
  43
  44        memset(pmp_priv, 0, sizeof(struct mp_priv));
  45
  46        pmp_priv->mode = MP_OFF;
  47
  48        pmp_priv->channel = 1;
  49        pmp_priv->bandwidth = HT_CHANNEL_WIDTH_20;
  50        pmp_priv->prime_channel_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  51        pmp_priv->rateidx = MPT_RATE_1M;
  52        pmp_priv->txpoweridx = 0x2A;
  53
  54        pmp_priv->antenna_tx = ANTENNA_A;
  55        pmp_priv->antenna_rx = ANTENNA_AB;
  56
  57        pmp_priv->check_mp_pkt = 0;
  58
  59        pmp_priv->tx_pktcount = 0;
  60
  61        pmp_priv->rx_pktcount = 0;
  62        pmp_priv->rx_crcerrpktcount = 0;
  63
  64        pmp_priv->network_macaddr[0] = 0x00;
  65        pmp_priv->network_macaddr[1] = 0xE0;
  66        pmp_priv->network_macaddr[2] = 0x4C;
  67        pmp_priv->network_macaddr[3] = 0x87;
  68        pmp_priv->network_macaddr[4] = 0x66;
  69        pmp_priv->network_macaddr[5] = 0x55;
  70
  71        pnetwork = &pmp_priv->mp_network.network;
  72        memcpy(pnetwork->MacAddress, pmp_priv->network_macaddr, ETH_ALEN);
  73
  74        pnetwork->Ssid.SsidLength = 8;
  75        memcpy(pnetwork->Ssid.Ssid, "mp_871x", pnetwork->Ssid.SsidLength);
  76}
  77
  78static void mp_init_xmit_attrib(struct mp_tx *pmptx, struct adapter *padapter)
  79{
  80        struct pkt_attrib *pattrib;
  81        struct tx_desc *desc;
  82
  83        /*  init xmitframe attribute */
  84        pattrib = &pmptx->attrib;
  85        memset(pattrib, 0, sizeof(struct pkt_attrib));
  86        desc = &pmptx->desc;
  87        memset(desc, 0, TXDESC_SIZE);
  88
  89        pattrib->ether_type = 0x8712;
  90        memset(pattrib->dst, 0xFF, ETH_ALEN);
  91        pattrib->ack_policy = 0;
  92        pattrib->hdrlen = WLAN_HDR_A3_LEN;
  93        pattrib->subtype = WIFI_DATA;
  94        pattrib->priority = 0;
  95        pattrib->qsel = pattrib->priority;
  96        pattrib->nr_frags = 1;
  97        pattrib->encrypt = 0;
  98        pattrib->bswenc = false;
  99        pattrib->qos_en = false;
 100}
 101
 102s32 init_mp_priv(struct adapter *padapter)
 103{
 104        struct mp_priv *pmppriv = &padapter->mppriv;
 105
 106        _init_mp_priv_(pmppriv);
 107        pmppriv->papdater = padapter;
 108
 109        pmppriv->tx.stop = 1;
 110        mp_init_xmit_attrib(&pmppriv->tx, padapter);
 111
 112        switch (padapter->registrypriv.rf_config) {
 113        case RF_1T1R:
 114                pmppriv->antenna_tx = ANTENNA_A;
 115                pmppriv->antenna_rx = ANTENNA_A;
 116                break;
 117        case RF_1T2R:
 118        default:
 119                pmppriv->antenna_tx = ANTENNA_A;
 120                pmppriv->antenna_rx = ANTENNA_AB;
 121                break;
 122        case RF_2T2R:
 123        case RF_2T2R_GREEN:
 124                pmppriv->antenna_tx = ANTENNA_AB;
 125                pmppriv->antenna_rx = ANTENNA_AB;
 126                break;
 127        case RF_2T4R:
 128                pmppriv->antenna_tx = ANTENNA_AB;
 129                pmppriv->antenna_rx = ANTENNA_ABCD;
 130                break;
 131        }
 132
 133        return _SUCCESS;
 134}
 135
 136void free_mp_priv(struct mp_priv *pmp_priv)
 137{
 138        kfree(pmp_priv->pallocated_mp_xmitframe_buf);
 139        pmp_priv->pallocated_mp_xmitframe_buf = NULL;
 140        pmp_priv->pmp_xmtframe_buf = NULL;
 141}
 142
 143#define PHY_IQCalibrate(a, b)   PHY_IQCalibrate_8188E(a, b)
 144#define PHY_LCCalibrate(a)      PHY_LCCalibrate_8188E(a)
 145#define PHY_SetRFPathSwitch(a, b) PHY_SetRFPathSwitch_8188E(a, b)
 146
 147s32 MPT_InitializeAdapter(struct adapter *pAdapter, u8 Channel)
 148{
 149        struct hal_data_8188e   *pHalData = GET_HAL_DATA(pAdapter);
 150        s32             rtStatus = _SUCCESS;
 151        struct mpt_context *pMptCtx = &pAdapter->mppriv.MptCtx;
 152        struct mlme_priv *pmlmepriv = &pAdapter->mlmepriv;
 153
 154        /*  HW Initialization for 8190 MPT. */
 155        /*  SW Initialization for 8190 MP. */
 156        pMptCtx->bMptDrvUnload = false;
 157        pMptCtx->bMassProdTest = false;
 158        pMptCtx->bMptIndexEven = true;  /* default gain index is -6.0db */
 159        pMptCtx->h2cReqNum = 0x0;
 160        /* Init mpt event. */
 161        /* init for BT MP */
 162
 163        pMptCtx->bMptWorkItemInProgress = false;
 164        pMptCtx->CurrMptAct = NULL;
 165        /*  */
 166
 167        /*  Don't accept any packets */
 168        rtw_write32(pAdapter, REG_RCR, 0);
 169
 170        PHY_IQCalibrate(pAdapter, false);
 171        dm_CheckTXPowerTracking(&pHalData->odmpriv);    /* trigger thermal meter */
 172        PHY_LCCalibrate(pAdapter);
 173
 174        pMptCtx->backup0xc50 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0);
 175        pMptCtx->backup0xc58 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0);
 176        pMptCtx->backup0xc30 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_RxDetector1, bMaskByte0);
 177        pMptCtx->backup0x52_RF_A = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0);
 178        pMptCtx->backup0x52_RF_B = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0);
 179
 180        /* set ant to wifi side in mp mode */
 181        rtw_write16(pAdapter, 0x870, 0x300);
 182        rtw_write16(pAdapter, 0x860, 0x110);
 183
 184        if (pAdapter->registrypriv.mp_mode == 1)
 185                pmlmepriv->fw_state = WIFI_MP_STATE;
 186
 187        return  rtStatus;
 188}
 189
 190/*-----------------------------------------------------------------------------
 191 * Function:    MPT_DeInitAdapter()
 192 *
 193 * Overview:    Extra DeInitialization for Mass Production Test.
 194 *
 195 * Input:               struct adapter *        pAdapter
 196 *
 197 * Output:              NONE
 198 *
 199 * Return:              NONE
 200 *
 201 * Revised History:
 202 *      When            Who             Remark
 203 *      05/08/2007      MHC             Create Version 0.
 204 *      05/18/2007      MHC             Add normal driver MPHalt code.
 205 *
 206 *---------------------------------------------------------------------------*/
 207void MPT_DeInitAdapter(struct adapter *pAdapter)
 208{
 209        struct mpt_context *pMptCtx = &pAdapter->mppriv.MptCtx;
 210
 211        pMptCtx->bMptDrvUnload = true;
 212}
 213
 214static u8 mpt_ProStartTest(struct adapter *padapter)
 215{
 216        struct mpt_context *pMptCtx = &padapter->mppriv.MptCtx;
 217
 218        pMptCtx->bMassProdTest = true;
 219        pMptCtx->bStartContTx = false;
 220        pMptCtx->bCckContTx = false;
 221        pMptCtx->bOfdmContTx = false;
 222        pMptCtx->bSingleCarrier = false;
 223        pMptCtx->bCarrierSuppression = false;
 224        pMptCtx->bSingleTone = false;
 225
 226        return _SUCCESS;
 227}
 228
 229/*
 230 * General use
 231 */
 232s32 SetPowerTracking(struct adapter *padapter, u8 enable)
 233{
 234        Hal_SetPowerTracking(padapter, enable);
 235        return 0;
 236}
 237
 238void GetPowerTracking(struct adapter *padapter, u8 *enable)
 239{
 240        Hal_GetPowerTracking(padapter, enable);
 241}
 242
 243static void disable_dm(struct adapter *padapter)
 244{
 245        u8 v8;
 246
 247        /* 3 1. disable firmware dynamic mechanism */
 248        /*  disable Power Training, Rate Adaptive */
 249        v8 = rtw_read8(padapter, REG_BCN_CTRL);
 250        v8 &= ~EN_BCN_FUNCTION;
 251        rtw_write8(padapter, REG_BCN_CTRL, v8);
 252
 253        /* 3 2. disable driver dynamic mechanism */
 254        /*  disable Dynamic Initial Gain */
 255        /*  disable High Power */
 256        /*  disable Power Tracking */
 257        Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
 258
 259        /*  enable APK, LCK and IQK but disable power tracking */
 260        Switch_DM_Func(padapter, DYNAMIC_RF_CALIBRATION, true);
 261}
 262
 263/* This function initializes the DUT to the MP test mode */
 264s32 mp_start_test(struct adapter *padapter)
 265{
 266        struct wlan_bssid_ex bssid;
 267        struct sta_info *psta;
 268        u32 length;
 269        u8 val8;
 270        s32 res = _SUCCESS;
 271        struct mp_priv *pmppriv = &padapter->mppriv;
 272        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 273        struct wlan_network *tgt_network = &pmlmepriv->cur_network;
 274
 275        padapter->registrypriv.mp_mode = 1;
 276        pmppriv->bSetTxPower = 0;               /* for  manually set tx power */
 277
 278        /* 3 disable dynamic mechanism */
 279        disable_dm(padapter);
 280
 281        /* 3 0. update mp_priv */
 282
 283        if (padapter->registrypriv.rf_config == RF_819X_MAX_TYPE) {
 284                switch (GET_RF_TYPE(padapter)) {
 285                case RF_1T1R:
 286                        pmppriv->antenna_tx = ANTENNA_A;
 287                        pmppriv->antenna_rx = ANTENNA_A;
 288                        break;
 289                case RF_1T2R:
 290                default:
 291                        pmppriv->antenna_tx = ANTENNA_A;
 292                        pmppriv->antenna_rx = ANTENNA_AB;
 293                        break;
 294                case RF_2T2R:
 295                case RF_2T2R_GREEN:
 296                        pmppriv->antenna_tx = ANTENNA_AB;
 297                        pmppriv->antenna_rx = ANTENNA_AB;
 298                        break;
 299                case RF_2T4R:
 300                        pmppriv->antenna_tx = ANTENNA_AB;
 301                        pmppriv->antenna_rx = ANTENNA_ABCD;
 302                        break;
 303                }
 304        }
 305
 306        mpt_ProStartTest(padapter);
 307
 308        /* 3 1. initialize a new struct wlan_bssid_ex */
 309/*      memset(&bssid, 0, sizeof(struct wlan_bssid_ex)); */
 310        memcpy(bssid.MacAddress, pmppriv->network_macaddr, ETH_ALEN);
 311        bssid.Ssid.SsidLength = strlen("mp_pseudo_adhoc");
 312        memcpy(bssid.Ssid.Ssid, (u8 *)"mp_pseudo_adhoc", bssid.Ssid.SsidLength);
 313        bssid.InfrastructureMode = Ndis802_11IBSS;
 314        bssid.NetworkTypeInUse = Ndis802_11DS;
 315        bssid.IELength = 0;
 316
 317        length = get_wlan_bssid_ex_sz(&bssid);
 318        if (length % 4)
 319                bssid.Length = ((length >> 2) + 1) << 2; /* round up to multiple of 4 bytes. */
 320        else
 321                bssid.Length = length;
 322
 323        spin_lock_bh(&pmlmepriv->lock);
 324
 325        if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
 326                goto end_of_mp_start_test;
 327
 328        /* init mp_start_test status */
 329        if (check_fwstate(pmlmepriv, _FW_LINKED)) {
 330                rtw_disassoc_cmd(padapter, 500, true);
 331                rtw_indicate_disconnect(padapter);
 332                rtw_free_assoc_resources(padapter, 1);
 333        }
 334        pmppriv->prev_fw_state = get_fwstate(pmlmepriv);
 335        if (padapter->registrypriv.mp_mode == 1)
 336                pmlmepriv->fw_state = WIFI_MP_STATE;
 337        set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
 338
 339        /* 3 2. create a new psta for mp driver */
 340        /* clear psta in the cur_network, if any */
 341        psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress);
 342        if (psta)
 343                rtw_free_stainfo(padapter, psta);
 344
 345        psta = rtw_alloc_stainfo(&padapter->stapriv, bssid.MacAddress);
 346        if (!psta) {
 347                pmlmepriv->fw_state = pmppriv->prev_fw_state;
 348                res = _FAIL;
 349                goto end_of_mp_start_test;
 350        }
 351
 352        /* 3 3. join psudo AdHoc */
 353        tgt_network->join_res = 1;
 354        tgt_network->aid = 1;
 355        psta->aid = 1;
 356        memcpy(&tgt_network->network, &bssid, length);
 357
 358        rtw_indicate_connect(padapter);
 359        _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
 360
 361end_of_mp_start_test:
 362
 363        spin_unlock_bh(&pmlmepriv->lock);
 364
 365        if (res == _SUCCESS) {
 366                /*  set MSR to WIFI_FW_ADHOC_STATE */
 367                val8 = rtw_read8(padapter, MSR) & 0xFC; /*  0x0102 */
 368                val8 |= WIFI_FW_ADHOC_STATE;
 369                rtw_write8(padapter, MSR, val8); /*  Link in ad hoc network */
 370        }
 371        return res;
 372}
 373/*  */
 374/* This function change the DUT from the MP test mode into normal mode */
 375void mp_stop_test(struct adapter *padapter)
 376{
 377        struct mp_priv *pmppriv = &padapter->mppriv;
 378        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 379        struct wlan_network *tgt_network = &pmlmepriv->cur_network;
 380        struct sta_info *psta;
 381
 382        if (pmppriv->mode == MP_ON) {
 383                pmppriv->bSetTxPower = 0;
 384                spin_lock_bh(&pmlmepriv->lock);
 385                if (!check_fwstate(pmlmepriv, WIFI_MP_STATE))
 386                        goto end_of_mp_stop_test;
 387
 388                /* 3 1. disconnect psudo AdHoc */
 389                rtw_indicate_disconnect(padapter);
 390
 391                /* 3 2. clear psta used in mp test mode. */
 392                psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress);
 393                if (psta)
 394                        rtw_free_stainfo(padapter, psta);
 395
 396                /* 3 3. return to normal state (default:station mode) */
 397                pmlmepriv->fw_state = pmppriv->prev_fw_state; /*  WIFI_STATION_STATE; */
 398
 399                /* flush the cur_network */
 400                memset(tgt_network, 0, sizeof(struct wlan_network));
 401
 402                _clr_fwstate_(pmlmepriv, WIFI_MP_STATE);
 403
 404end_of_mp_stop_test:
 405
 406                spin_unlock_bh(&pmlmepriv->lock);
 407        }
 408}
 409
 410/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/
 411/*
 412 * SetChannel
 413 * Description
 414 *      Use H2C command to change channel,
 415 *      not only modify rf register, but also other setting need to be done.
 416 */
 417void SetChannel(struct adapter *pAdapter)
 418{
 419        Hal_SetChannel(pAdapter);
 420}
 421
 422/*
 423 * Notice
 424 *      Switch bandwitdth may change center frequency(channel)
 425 */
 426void SetBandwidth(struct adapter *pAdapter)
 427{
 428        Hal_SetBandwidth(pAdapter);
 429}
 430
 431void SetAntenna(struct adapter *pAdapter)
 432{
 433        Hal_SetAntenna(pAdapter);
 434}
 435
 436void    SetAntennaPathPower(struct adapter *pAdapter)
 437{
 438        Hal_SetAntennaPathPower(pAdapter);
 439}
 440
 441void SetTxPower(struct adapter *pAdapter)
 442{
 443        Hal_SetTxPower(pAdapter);
 444        }
 445
 446void SetDataRate(struct adapter *pAdapter)
 447{
 448        Hal_SetDataRate(pAdapter);
 449}
 450
 451void MP_PHY_SetRFPathSwitch(struct adapter *pAdapter, bool bMain)
 452{
 453        PHY_SetRFPathSwitch(pAdapter, bMain);
 454}
 455
 456s32 SetThermalMeter(struct adapter *pAdapter, u8 target_ther)
 457{
 458        return Hal_SetThermalMeter(pAdapter, target_ther);
 459}
 460
 461void GetThermalMeter(struct adapter *pAdapter, u8 *value)
 462{
 463        Hal_GetThermalMeter(pAdapter, value);
 464}
 465
 466void SetSingleCarrierTx(struct adapter *pAdapter, u8 bStart)
 467{
 468        PhySetTxPowerLevel(pAdapter);
 469        Hal_SetSingleCarrierTx(pAdapter, bStart);
 470}
 471
 472void SetSingleToneTx(struct adapter *pAdapter, u8 bStart)
 473{
 474        PhySetTxPowerLevel(pAdapter);
 475        Hal_SetSingleToneTx(pAdapter, bStart);
 476}
 477
 478void SetCarrierSuppressionTx(struct adapter *pAdapter, u8 bStart)
 479{
 480        PhySetTxPowerLevel(pAdapter);
 481        Hal_SetCarrierSuppressionTx(pAdapter, bStart);
 482}
 483
 484void SetContinuousTx(struct adapter *pAdapter, u8 bStart)
 485{
 486        PhySetTxPowerLevel(pAdapter);
 487        Hal_SetContinuousTx(pAdapter, bStart);
 488}
 489
 490void PhySetTxPowerLevel(struct adapter *pAdapter)
 491{
 492        struct mp_priv *pmp_priv = &pAdapter->mppriv;
 493
 494        if (pmp_priv->bSetTxPower == 0) /*  for NO manually set power index */
 495                PHY_SetTxPowerLevel8188E(pAdapter, pmp_priv->channel);
 496}
 497
 498/*  */
 499static void dump_mpframe(struct adapter *padapter, struct xmit_frame *pmpframe)
 500{
 501        rtw_hal_mgnt_xmit(padapter, pmpframe);
 502}
 503
 504static struct xmit_frame *alloc_mp_xmitframe(struct xmit_priv *pxmitpriv)
 505{
 506        struct xmit_frame       *pmpframe;
 507        struct xmit_buf *pxmitbuf;
 508
 509        pmpframe = rtw_alloc_xmitframe(pxmitpriv);
 510        if (!pmpframe)
 511                return NULL;
 512
 513        pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
 514        if (!pxmitbuf) {
 515                rtw_free_xmitframe(pxmitpriv, pmpframe);
 516                return NULL;
 517        }
 518
 519        pmpframe->frame_tag = MP_FRAMETAG;
 520
 521        pmpframe->pxmitbuf = pxmitbuf;
 522
 523        pmpframe->buf_addr = pxmitbuf->pbuf;
 524
 525        pxmitbuf->priv_data = pmpframe;
 526
 527        return pmpframe;
 528}
 529
 530static int mp_xmit_packet_thread(void *context)
 531{
 532        struct xmit_frame       *pxmitframe;
 533        struct mp_tx            *pmptx;
 534        struct mp_priv  *pmp_priv;
 535        struct xmit_priv        *pxmitpriv;
 536        struct adapter *padapter;
 537
 538        pmp_priv = (struct mp_priv *)context;
 539        pmptx = &pmp_priv->tx;
 540        padapter = pmp_priv->papdater;
 541        pxmitpriv = &padapter->xmitpriv;
 542
 543        thread_enter("RTW_MP_THREAD");
 544
 545        /* DBG_88E("%s:pkTx Start\n", __func__); */
 546        while (1) {
 547                pxmitframe = alloc_mp_xmitframe(pxmitpriv);
 548                if (!pxmitframe) {
 549                        if (pmptx->stop ||
 550                            padapter->bSurpriseRemoved ||
 551                            padapter->bDriverStopped) {
 552                                goto exit;
 553                        } else {
 554                                msleep(1);
 555                                continue;
 556                        }
 557                }
 558
 559                memcpy((u8 *)(pxmitframe->buf_addr + TXDESC_OFFSET), pmptx->buf, pmptx->write_size);
 560                memcpy(&pxmitframe->attrib, &pmptx->attrib, sizeof(struct pkt_attrib));
 561
 562                dump_mpframe(padapter, pxmitframe);
 563
 564                pmptx->sended++;
 565                pmp_priv->tx_pktcount++;
 566
 567                if (pmptx->stop ||
 568                    padapter->bSurpriseRemoved ||
 569                    padapter->bDriverStopped)
 570                        goto exit;
 571                if ((pmptx->count != 0) &&
 572                    (pmptx->count == pmptx->sended))
 573                        goto exit;
 574
 575                flush_signals_thread();
 576        }
 577
 578exit:
 579        kfree(pmptx->pallocated_buf);
 580        pmptx->pallocated_buf = NULL;
 581        pmptx->stop = 1;
 582
 583        thread_exit();
 584}
 585
 586void fill_txdesc_for_mp(struct adapter *padapter, struct tx_desc *ptxdesc)
 587{
 588        struct mp_priv *pmp_priv = &padapter->mppriv;
 589        memcpy(ptxdesc, &pmp_priv->tx.desc, TXDESC_SIZE);
 590}
 591
 592void SetPacketTx(struct adapter *padapter)
 593{
 594        u8 *ptr, *pkt_start, *pkt_end;
 595        u32 pkt_size;
 596        struct tx_desc *desc;
 597        struct rtw_ieee80211_hdr *hdr;
 598        u8 payload;
 599        bool bmcast;
 600        struct pkt_attrib *pattrib;
 601        struct mp_priv *pmp_priv;
 602
 603        pmp_priv = &padapter->mppriv;
 604        if (pmp_priv->tx.stop)
 605                return;
 606        pmp_priv->tx.sended = 0;
 607        pmp_priv->tx.stop = 0;
 608        pmp_priv->tx_pktcount = 0;
 609
 610        /* 3 1. update_attrib() */
 611        pattrib = &pmp_priv->tx.attrib;
 612        memcpy(pattrib->src, padapter->eeprompriv.mac_addr, ETH_ALEN);
 613        memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
 614        memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
 615        bmcast = is_multicast_ether_addr(pattrib->ra);
 616        if (bmcast) {
 617                pattrib->mac_id = 1;
 618                pattrib->psta = rtw_get_bcmc_stainfo(padapter);
 619        } else {
 620                pattrib->mac_id = 0;
 621                pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
 622        }
 623
 624        pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen;
 625
 626        /* 3 2. allocate xmit buffer */
 627        pkt_size = pattrib->last_txcmdsz;
 628
 629        kfree(pmp_priv->tx.pallocated_buf);
 630        pmp_priv->tx.write_size = pkt_size;
 631        pmp_priv->tx.buf_size = pkt_size + XMITBUF_ALIGN_SZ;
 632        pmp_priv->tx.pallocated_buf = kzalloc(pmp_priv->tx.buf_size, GFP_KERNEL);
 633        if (!pmp_priv->tx.pallocated_buf) {
 634                DBG_88E("%s: malloc(%d) fail!!\n", __func__, pmp_priv->tx.buf_size);
 635                return;
 636        }
 637        pmp_priv->tx.buf = (u8 *)N_BYTE_ALIGMENT((size_t)(pmp_priv->tx.pallocated_buf), XMITBUF_ALIGN_SZ);
 638        ptr = pmp_priv->tx.buf;
 639
 640        desc = &pmp_priv->tx.desc;
 641        memset(desc, 0, TXDESC_SIZE);
 642        pkt_start = ptr;
 643        pkt_end = pkt_start + pkt_size;
 644
 645        /* 3 3. init TX descriptor */
 646        /*  offset 0 */
 647        desc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
 648        desc->txdw0 |= cpu_to_le32(pkt_size & 0x0000FFFF); /*  packet size */
 649        desc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00FF0000); /* 32 bytes for TX Desc */
 650        if (bmcast)
 651                desc->txdw0 |= cpu_to_le32(BMC); /*  broadcast packet */
 652
 653        desc->txdw1 |= cpu_to_le32((0x01 << 26) & 0xff000000);
 654        /*  offset 4 */
 655        desc->txdw1 |= cpu_to_le32((pattrib->mac_id) & 0x3F); /* CAM_ID(MAC_ID) */
 656        desc->txdw1 |= cpu_to_le32((pattrib->qsel << QSEL_SHT) & 0x00001F00); /*  Queue Select, TID */
 657
 658        desc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000F0000); /*  Rate Adaptive ID */
 659        /*  offset 8 */
 660        /*  offset 12 */
 661
 662        desc->txdw3 |= cpu_to_le32((pattrib->seqnum << 16) & 0x0fff0000);
 663
 664        /*  offset 16 */
 665        desc->txdw4 |= cpu_to_le32(HW_SSN);
 666        desc->txdw4 |= cpu_to_le32(USERATE);
 667        desc->txdw4 |= cpu_to_le32(DISDATAFB);
 668
 669        if (pmp_priv->preamble) {
 670                if (pmp_priv->rateidx <=  MPT_RATE_54M)
 671                        desc->txdw4 |= cpu_to_le32(DATA_SHORT); /*  CCK Short Preamble */
 672        }
 673        if (pmp_priv->bandwidth == HT_CHANNEL_WIDTH_40)
 674                desc->txdw4 |= cpu_to_le32(DATA_BW);
 675
 676        /*  offset 20 */
 677        desc->txdw5 |= cpu_to_le32(pmp_priv->rateidx & 0x0000001F);
 678
 679        if (pmp_priv->preamble) {
 680                if (pmp_priv->rateidx > MPT_RATE_54M)
 681                        desc->txdw5 |= cpu_to_le32(SGI); /*  MCS Short Guard Interval */
 682        }
 683        desc->txdw5 |= cpu_to_le32(RTY_LMT_EN); /*  retry limit enable */
 684        desc->txdw5 |= cpu_to_le32(0x00180000); /*  DATA/RTS Rate Fallback Limit */
 685
 686        /* 3 4. make wlan header, make_wlanhdr() */
 687        hdr = (struct rtw_ieee80211_hdr *)pkt_start;
 688        SetFrameSubType(&hdr->frame_ctl, pattrib->subtype);
 689        memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); /*  DA */
 690        memcpy(hdr->addr2, pattrib->src, ETH_ALEN); /*  SA */
 691        memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); /*  RA, BSSID */
 692
 693        /* 3 5. make payload */
 694        ptr = pkt_start + pattrib->hdrlen;
 695
 696        switch (pmp_priv->tx.payload) {
 697        case 0:
 698                payload = 0x00;
 699                break;
 700        case 1:
 701                payload = 0x5a;
 702                break;
 703        case 2:
 704                payload = 0xa5;
 705                break;
 706        case 3:
 707                payload = 0xff;
 708                break;
 709        default:
 710                payload = 0x00;
 711                break;
 712        }
 713
 714        memset(ptr, payload, pkt_end - ptr);
 715
 716        /* 3 6. start thread */
 717        pmp_priv->tx.PktTxThread = kthread_run(mp_xmit_packet_thread, pmp_priv, "RTW_MP_THREAD");
 718        if (IS_ERR(pmp_priv->tx.PktTxThread))
 719                DBG_88E("Create PktTx Thread Fail !!!!!\n");
 720}
 721
 722void SetPacketRx(struct adapter *pAdapter, u8 bStartRx)
 723{
 724        struct hal_data_8188e   *pHalData = GET_HAL_DATA(pAdapter);
 725
 726        if (bStartRx) {
 727                /*  Accept CRC error and destination address */
 728                pHalData->ReceiveConfig = AAP | APM | AM | AB | APP_ICV |
 729                                          AMF | ADF | APP_FCS | HTC_LOC_CTRL |
 730                                          APP_MIC | APP_PHYSTS;
 731
 732                pHalData->ReceiveConfig |= (RCR_ACRC32 | RCR_AAP);
 733
 734                rtw_write32(pAdapter, REG_RCR, pHalData->ReceiveConfig);
 735
 736                /*  Accept all data frames */
 737                rtw_write16(pAdapter, REG_RXFLTMAP2, 0xFFFF);
 738        } else {
 739                rtw_write32(pAdapter, REG_RCR, 0);
 740        }
 741}
 742
 743void ResetPhyRxPktCount(struct adapter *pAdapter)
 744{
 745        u32 i, phyrx_set = 0;
 746
 747        for (i = 0; i <= 0xF; i++) {
 748                phyrx_set = 0;
 749                phyrx_set |= _RXERR_RPT_SEL(i); /* select */
 750                phyrx_set |= RXERR_RPT_RST;     /*  set counter to zero */
 751                rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set);
 752        }
 753}
 754
 755static u32 GetPhyRxPktCounts(struct adapter *pAdapter, u32 selbit)
 756{
 757        /* selection */
 758        u32 phyrx_set = 0, count = 0;
 759
 760        phyrx_set = _RXERR_RPT_SEL(selbit & 0xF);
 761        rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set);
 762
 763        /* Read packet count */
 764        count = rtw_read32(pAdapter, REG_RXERR_RPT) & RXERR_COUNTER_MASK;
 765
 766        return count;
 767}
 768
 769u32 GetPhyRxPktReceived(struct adapter *pAdapter)
 770{
 771        u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0;
 772
 773        OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_OK);
 774        CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_OK);
 775        HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_OK);
 776
 777        return OFDM_cnt + CCK_cnt + HT_cnt;
 778}
 779
 780u32 GetPhyRxPktCRC32Error(struct adapter *pAdapter)
 781{
 782        u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0;
 783
 784        OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_FAIL);
 785        CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_FAIL);
 786        HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_FAIL);
 787
 788        return OFDM_cnt + CCK_cnt + HT_cnt;
 789}
 790
 791/* reg 0x808[9:0]: FFT data x */
 792/* reg 0x808[22]:  0  -->  1  to get 1 FFT data y */
 793/* reg 0x8B4[15:0]: FFT data y report */
 794static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
 795{
 796        int psd_val;
 797
 798        psd_val = rtw_read32(pAdapter, 0x808);
 799        psd_val &= 0xFFBFFC00;
 800        psd_val |= point;
 801
 802        rtw_write32(pAdapter, 0x808, psd_val);
 803        mdelay(1);
 804        psd_val |= 0x00400000;
 805
 806        rtw_write32(pAdapter, 0x808, psd_val);
 807        mdelay(1);
 808        psd_val = rtw_read32(pAdapter, 0x8B4);
 809
 810        psd_val &= 0x0000FFFF;
 811
 812        return psd_val;
 813}
 814
 815/*
 816 *pts   start_point_min         stop_point_max
 817 * 128  64                      64 + 128 = 192
 818 * 256  128                     128 + 256 = 384
 819 * 512  256                     256 + 512 = 768
 820 * 1024 512                     512 + 1024 = 1536
 821 */
 822u32 mp_query_psd(struct adapter *pAdapter, u8 *data)
 823{
 824        u32 i, psd_pts = 0, psd_start = 0, psd_stop = 0;
 825        u32 psd_data = 0;
 826
 827        if (!netif_running(pAdapter->pnetdev))
 828                return 0;
 829
 830        if (!check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE))
 831                return 0;
 832
 833        if (strlen(data) == 0) { /* default value */
 834                psd_pts = 128;
 835                psd_start = 64;
 836                psd_stop = 128;
 837        } else {
 838                sscanf(data, "pts =%d, start =%d, stop =%d", &psd_pts, &psd_start, &psd_stop);
 839        }
 840
 841        memset(data, '\0', sizeof(*data));
 842
 843        i = psd_start;
 844        while (i < psd_stop) {
 845                if (i >= psd_pts) {
 846                        psd_data = rtw_GetPSDData(pAdapter, i - psd_pts);
 847                } else {
 848                        psd_data = rtw_GetPSDData(pAdapter, i);
 849                }
 850                sprintf(data + strlen(data), "%x ", psd_data);
 851                i++;
 852        }
 853
 854        msleep(100);
 855        return strlen(data) + 1;
 856}
 857
 858void _rtw_mp_xmit_priv(struct xmit_priv *pxmitpriv)
 859{
 860        int i, res;
 861        struct adapter *padapter = pxmitpriv->adapter;
 862        struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
 863        u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
 864        u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
 865
 866        if (padapter->registrypriv.mp_mode == 0) {
 867                max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
 868                num_xmit_extbuf = NR_XMIT_EXTBUFF;
 869        } else {
 870                max_xmit_extbuf_size = 6000;
 871                num_xmit_extbuf = 8;
 872        }
 873
 874        pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
 875        for (i = 0; i < num_xmit_extbuf; i++) {
 876                rtw_os_xmit_resource_free(padapter, pxmitbuf, (max_xmit_extbuf_size + XMITBUF_ALIGN_SZ));
 877
 878                pxmitbuf++;
 879        }
 880
 881        vfree(pxmitpriv->pallocated_xmit_extbuf);
 882
 883        if (padapter->registrypriv.mp_mode == 0) {
 884                max_xmit_extbuf_size = 6000;
 885                num_xmit_extbuf = 8;
 886        } else {
 887                max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
 888                num_xmit_extbuf = NR_XMIT_EXTBUFF;
 889        }
 890
 891        /*  Init xmit extension buff */
 892        _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue);
 893
 894        pxmitpriv->pallocated_xmit_extbuf = vzalloc(num_xmit_extbuf * sizeof(struct xmit_buf) + 4);
 895
 896        if (!pxmitpriv->pallocated_xmit_extbuf) {
 897                res = _FAIL;
 898                goto exit;
 899        }
 900
 901        pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmit_extbuf), 4);
 902
 903        pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
 904
 905        for (i = 0; i < num_xmit_extbuf; i++) {
 906                INIT_LIST_HEAD(&pxmitbuf->list);
 907
 908                pxmitbuf->priv_data = NULL;
 909                pxmitbuf->padapter = padapter;
 910                pxmitbuf->ext_tag = true;
 911
 912                res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ);
 913                if (res == _FAIL) {
 914                        res = _FAIL;
 915                        goto exit;
 916                }
 917
 918                list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmit_extbuf_queue.queue);
 919                pxmitbuf++;
 920        }
 921
 922        pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf;
 923
 924exit:
 925        ;
 926}
 927
 928void Hal_ProSetCrystalCap(struct adapter *pAdapter, u32 CrystalCapVal)
 929{
 930        CrystalCapVal = CrystalCapVal & 0x3F;
 931
 932        // write 0x24[16:11] = 0x24[22:17] = CrystalCap
 933        PHY_SetBBReg(pAdapter, REG_AFE_XTAL_CTRL, 0x7FF800,
 934                     (CrystalCapVal | (CrystalCapVal << 6)));
 935}
 936