Promote the capacity of WiFi connect AP.(V3.20)
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rtl8192c / core / rtw_mp.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _RTW_MP_C_
21
22 #include <drv_types.h>
23
24 #ifdef CONFIG_RTL8712
25 #include <rtw_mp_phy_regdef.h>
26 #endif
27 #ifdef CONFIG_RTL8192C
28 #include <rtl8192c_hal.h>
29 #endif
30 #ifdef CONFIG_RTL8192D
31 #include <rtl8192d_hal.h>
32 #endif
33
34 #ifdef CONFIG_MP_INCLUDED
35
36 u32 read_macreg(_adapter *padapter, u32 addr, u32 sz)
37 {
38         u32 val = 0;
39
40         switch(sz)
41         {
42                 case 1:
43                         val = rtw_read8(padapter, addr);
44                         break;
45                 case 2:
46                         val = rtw_read16(padapter, addr);
47                         break;
48                 case 4:
49                         val = rtw_read32(padapter, addr);
50                         break;
51                 default:
52                         val = 0xffffffff;
53                         break;
54         }
55
56         return val;
57         
58 }
59
60 void write_macreg(_adapter *padapter, u32 addr, u32 val, u32 sz)
61 {
62         switch(sz)
63         {
64                 case 1:
65                         rtw_write8(padapter, addr, (u8)val);
66                         break;
67                 case 2:
68                         rtw_write16(padapter, addr, (u16)val);
69                         break;
70                 case 4:
71                         rtw_write32(padapter, addr, val);
72                         break;
73                 default:
74                         break;
75         }
76
77 }
78
79 u32 read_bbreg(_adapter *padapter, u32 addr, u32 bitmask)
80 {
81         return padapter->HalFunc.read_bbreg(padapter, addr, bitmask);
82 }
83
84 void write_bbreg(_adapter *padapter, u32 addr, u32 bitmask, u32 val)
85 {
86         padapter->HalFunc.write_bbreg(padapter, addr, bitmask, val);
87 }
88
89 u32 _read_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 bitmask)
90 {
91         return padapter->HalFunc.read_rfreg(padapter, (RF90_RADIO_PATH_E)rfpath, addr, bitmask);
92 }
93
94 void _write_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val)
95 {
96         padapter->HalFunc.write_rfreg(padapter, (RF90_RADIO_PATH_E)rfpath, addr, bitmask, val);
97 }
98
99 u32 read_rfreg(PADAPTER padapter, u8 rfpath, u32 addr)
100 {
101         return _read_rfreg(padapter, (RF90_RADIO_PATH_E)rfpath, addr, bRFRegOffsetMask);
102 }
103
104 void write_rfreg(PADAPTER padapter, u8 rfpath, u32 addr, u32 val)
105 {
106         _write_rfreg(padapter, (RF90_RADIO_PATH_E)rfpath, addr, bRFRegOffsetMask, val);
107 }
108
109
110 static void _init_mp_priv_(struct mp_priv *pmp_priv)
111 {
112         WLAN_BSSID_EX *pnetwork;
113
114         _rtw_memset(pmp_priv, 0, sizeof(struct mp_priv));
115
116         pmp_priv->mode = MP_OFF;
117
118         pmp_priv->channel = 1;
119         pmp_priv->bandwidth = HT_CHANNEL_WIDTH_20;
120         pmp_priv->prime_channel_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
121         pmp_priv->rateidx = MPT_RATE_1M;
122         pmp_priv->txpoweridx = 0x2A;
123
124         pmp_priv->antenna_tx = ANTENNA_A;
125         pmp_priv->antenna_rx = ANTENNA_AB;
126
127         pmp_priv->check_mp_pkt = 0;
128
129         pmp_priv->tx_pktcount = 0;
130
131         pmp_priv->rx_pktcount = 0;
132         pmp_priv->rx_crcerrpktcount = 0;
133
134         pmp_priv->network_macaddr[0] = 0x00;
135         pmp_priv->network_macaddr[1] = 0xE0;
136         pmp_priv->network_macaddr[2] = 0x4C;
137         pmp_priv->network_macaddr[3] = 0x87;
138         pmp_priv->network_macaddr[4] = 0x66;
139         pmp_priv->network_macaddr[5] = 0x55;
140
141         pnetwork = &pmp_priv->mp_network.network;
142         _rtw_memcpy(pnetwork->MacAddress, pmp_priv->network_macaddr, ETH_ALEN);
143
144         pnetwork->Ssid.SsidLength = 8;
145         _rtw_memcpy(pnetwork->Ssid.Ssid, "mp_871x", pnetwork->Ssid.SsidLength);
146 }
147
148 #ifdef PLATFORM_WINDOWS
149 /*
150 void mp_wi_callback(
151         IN NDIS_WORK_ITEM*      pwk_item,
152         IN PVOID                        cntx
153         )
154 {
155         _adapter* padapter =(_adapter *)cntx;
156         struct mp_priv *pmppriv=&padapter->mppriv;
157         struct mp_wi_cntx       *pmp_wi_cntx=&pmppriv->wi_cntx;
158
159         // Execute specified action.
160         if(pmp_wi_cntx->curractfunc != NULL)
161         {
162                 LARGE_INTEGER   cur_time;
163                 ULONGLONG start_time, end_time;
164                 NdisGetCurrentSystemTime(&cur_time);    // driver version
165                 start_time = cur_time.QuadPart/10; // The return value is in microsecond
166
167                 pmp_wi_cntx->curractfunc(padapter);
168
169                 NdisGetCurrentSystemTime(&cur_time);    // driver version
170                 end_time = cur_time.QuadPart/10; // The return value is in microsecond
171
172                 RT_TRACE(_module_mp_, _drv_info_,
173                          ("WorkItemActType: %d, time spent: %I64d us\n",
174                           pmp_wi_cntx->param.act_type, (end_time-start_time)));
175         }
176
177         NdisAcquireSpinLock(&(pmp_wi_cntx->mp_wi_lock));
178         pmp_wi_cntx->bmp_wi_progress= _FALSE;
179         NdisReleaseSpinLock(&(pmp_wi_cntx->mp_wi_lock));
180
181         if (pmp_wi_cntx->bmpdrv_unload)
182         {
183                 NdisSetEvent(&(pmp_wi_cntx->mp_wi_evt));
184         }
185
186 }
187 */
188
189 static int init_mp_priv_by_os(struct mp_priv *pmp_priv)
190 {
191         struct mp_wi_cntx *pmp_wi_cntx;
192
193         if (pmp_priv == NULL) return _FAIL;
194
195         pmp_priv->rx_testcnt = 0;
196         pmp_priv->rx_testcnt1 = 0;
197         pmp_priv->rx_testcnt2 = 0;
198
199         pmp_priv->tx_testcnt = 0;
200         pmp_priv->tx_testcnt1 = 0;
201
202         pmp_wi_cntx = &pmp_priv->wi_cntx
203         pmp_wi_cntx->bmpdrv_unload = _FALSE;
204         pmp_wi_cntx->bmp_wi_progress = _FALSE;
205         pmp_wi_cntx->curractfunc = NULL;
206
207         return _SUCCESS;
208 }
209 #endif
210
211 #ifdef PLATFORM_LINUX
212 static int init_mp_priv_by_os(struct mp_priv *pmp_priv)
213 {
214         int i, res;
215         struct mp_xmit_frame *pmp_xmitframe;
216
217         if (pmp_priv == NULL) return _FAIL;
218
219         _rtw_init_queue(&pmp_priv->free_mp_xmitqueue);
220
221         pmp_priv->pallocated_mp_xmitframe_buf = NULL;
222         pmp_priv->pallocated_mp_xmitframe_buf = rtw_zmalloc(NR_MP_XMITFRAME * sizeof(struct mp_xmit_frame) + 4);
223         if (pmp_priv->pallocated_mp_xmitframe_buf == NULL) {
224                 res = _FAIL;
225                 goto _exit_init_mp_priv;
226         }
227
228         pmp_priv->pmp_xmtframe_buf = pmp_priv->pallocated_mp_xmitframe_buf + 4 - ((uint) (pmp_priv->pallocated_mp_xmitframe_buf) & 3);
229
230         pmp_xmitframe = (struct mp_xmit_frame*)pmp_priv->pmp_xmtframe_buf;
231
232         for (i = 0; i < NR_MP_XMITFRAME; i++)
233         {
234                 _rtw_init_listhead(&pmp_xmitframe->list);
235                 rtw_list_insert_tail(&pmp_xmitframe->list, &pmp_priv->free_mp_xmitqueue.queue);
236
237                 pmp_xmitframe->pkt = NULL;
238                 pmp_xmitframe->frame_tag = MP_FRAMETAG;
239                 pmp_xmitframe->padapter = pmp_priv->papdater;
240
241                 pmp_xmitframe++;
242         }
243
244         pmp_priv->free_mp_xmitframe_cnt = NR_MP_XMITFRAME;
245
246         res = _SUCCESS;
247
248 _exit_init_mp_priv:
249
250         return res;
251 }
252 #endif
253
254 static void mp_init_xmit_attrib(struct mp_tx *pmptx, PADAPTER padapter)
255 {
256         struct pkt_attrib *pattrib;
257         struct tx_desc *desc;
258
259         // init xmitframe attribute
260         pattrib = &pmptx->attrib;
261         _rtw_memset(pattrib, 0, sizeof(struct pkt_attrib));
262         desc = &pmptx->desc;
263         _rtw_memset(desc, 0, TXDESC_SIZE);
264
265         pattrib->ether_type = 0x8712;
266         //_rtw_memcpy(pattrib->src, padapter->eeprompriv.mac_addr, ETH_ALEN);
267 //      _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
268         _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);
269 //      pattrib->pctrl = 0;
270 //      pattrib->dhcp_pkt = 0;
271 //      pattrib->pktlen = 0;
272         pattrib->ack_policy = 0;
273 //      pattrib->pkt_hdrlen = ETH_HLEN;
274         pattrib->hdrlen = WLAN_HDR_A3_LEN;
275         pattrib->subtype = WIFI_DATA;
276         pattrib->priority = 0;
277         pattrib->qsel = pattrib->priority;
278 //      do_queue_select(padapter, pattrib);
279         pattrib->nr_frags = 1;
280         pattrib->encrypt = 0;
281         pattrib->bswenc = _FALSE;
282         pattrib->qos_en = _FALSE;
283 }
284
285 s32 init_mp_priv(PADAPTER padapter)
286 {
287         struct mp_priv *pmppriv = &padapter->mppriv;
288
289         _init_mp_priv_(pmppriv);
290         pmppriv->papdater = padapter;
291
292         pmppriv->tx.stop = 1;
293         mp_init_xmit_attrib(&pmppriv->tx, padapter);
294
295         switch (padapter->registrypriv.rf_config) {
296                 case RF_1T1R:
297                         pmppriv->antenna_tx = ANTENNA_A;
298                         pmppriv->antenna_rx = ANTENNA_A;
299                         break;
300                 case RF_1T2R:
301                 default:
302                         pmppriv->antenna_tx = ANTENNA_A;
303                         pmppriv->antenna_rx = ANTENNA_AB;
304                         break;
305                 case RF_2T2R:
306                 case RF_2T2R_GREEN:
307                         pmppriv->antenna_tx = ANTENNA_AB;
308                         pmppriv->antenna_rx = ANTENNA_AB;
309                         break;
310                 case RF_2T4R:
311                         pmppriv->antenna_tx = ANTENNA_AB;
312                         pmppriv->antenna_rx = ANTENNA_ABCD;
313                         break;
314         }
315
316         return _SUCCESS;
317 }
318
319 void free_mp_priv(struct mp_priv *pmp_priv)
320 {
321         if (pmp_priv->pallocated_mp_xmitframe_buf) {
322                 rtw_mfree(pmp_priv->pallocated_mp_xmitframe_buf, 0);
323                 pmp_priv->pallocated_mp_xmitframe_buf = NULL;
324         }
325         pmp_priv->pmp_xmtframe_buf = NULL;
326 }
327
328 #ifdef CONFIG_RTL8192C
329 #define PHY_IQCalibrate(a,b)    rtl8192c_PHY_IQCalibrate(a,b)
330 #define PHY_LCCalibrate(a)      rtl8192c_PHY_LCCalibrate(a)
331 #define dm_CheckTXPowerTracking(a)      rtl8192c_dm_CheckTXPowerTracking(a)
332 #define PHY_SetRFPathSwitch(a,b)        rtl8192c_PHY_SetRFPathSwitch(a,b)
333 #endif
334
335 #ifdef CONFIG_RTL8192D
336 #define PHY_IQCalibrate(a)      rtl8192d_PHY_IQCalibrate(a)
337 #define PHY_LCCalibrate(a)      rtl8192d_PHY_LCCalibrate(a)
338 #define dm_CheckTXPowerTracking(a)      rtl8192d_dm_CheckTXPowerTracking(a)
339 #define PHY_SetRFPathSwitch(a,b)        rtl8192d_PHY_SetRFPathSwitch(a,b)
340 #endif
341
342 s32
343 MPT_InitializeAdapter(
344         IN      PADAPTER                        pAdapter,
345         IN      u8                              Channel
346         )
347 {
348         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
349         s32             rtStatus = _SUCCESS;
350         PMPT_CONTEXT    pMptCtx = &pAdapter->mppriv.MptCtx;
351         u32             tmpRegA, tmpRegC, TempCCk,ledsetting;
352
353         //-------------------------------------------------------------------------
354         // HW Initialization for 8190 MPT.
355         //-------------------------------------------------------------------------
356         //-------------------------------------------------------------------------
357         // SW Initialization for 8190 MP.
358         //-------------------------------------------------------------------------
359         pMptCtx->bMptDrvUnload = _FALSE;
360         pMptCtx->bMassProdTest = _FALSE;
361         pMptCtx->bMptIndexEven = _TRUE; //default gain index is -6.0db
362
363         /* Init mpt event. */
364 #if 0 // for Windows
365         NdisInitializeEvent( &(pMptCtx->MptWorkItemEvent) );
366         NdisAllocateSpinLock( &(pMptCtx->MptWorkItemSpinLock) );
367
368         PlatformInitializeWorkItem(
369                 Adapter,
370                 &(pMptCtx->MptWorkItem),
371                 (RT_WORKITEM_CALL_BACK)MPT_WorkItemCallback,
372                 (PVOID)Adapter,
373                 "MptWorkItem");
374 #endif
375         pMptCtx->bMptWorkItemInProgress = _FALSE;
376         pMptCtx->CurrMptAct = NULL;
377         //-------------------------------------------------------------------------
378
379 #if 1
380         // Don't accept any packets
381         rtw_write32(pAdapter, REG_RCR, 0);
382 #else
383         // Accept CRC error and destination address
384         pHalData->ReceiveConfig |= (RCR_ACRC32|RCR_AAP);
385         rtw_write32(pAdapter, REG_RCR, pHalData->ReceiveConfig);
386 #endif
387
388 #if 0
389         // If EEPROM or EFUSE is empty,we assign as RF 2T2R for MP.
390         if (pHalData->AutoloadFailFlag == TRUE)
391         {
392                 pHalData->RF_Type = RF_2T2R;
393         }
394 #endif
395         ledsetting = rtw_read32(pAdapter, REG_LEDCFG0);
396         rtw_write32(pAdapter, REG_LEDCFG0, ledsetting & ~LED0DIS);
397
398 #ifdef CONFIG_RTL8192C
399         PHY_IQCalibrate(pAdapter, _FALSE);
400         dm_CheckTXPowerTracking(pAdapter);      //trigger thermal meter
401         PHY_LCCalibrate(pAdapter);
402 #endif
403
404 #ifdef CONFIG_RTL8192D
405         PHY_IQCalibrate(pAdapter);
406         dm_CheckTXPowerTracking(pAdapter);      //trigger thermal meter
407         PHY_LCCalibrate(pAdapter);
408 #endif
409
410 #ifdef CONFIG_PCI_HCI
411         PHY_SetRFPathSwitch(pAdapter, 1/*pHalData->bDefaultAntenna*/);  //Wifi default use Main
412 #else
413
414 #ifdef CONFIG_RTL8192C
415 #if 1
416         if (pHalData->BoardType == BOARD_MINICARD)
417                 PHY_SetRFPathSwitch(pAdapter, 1/*pHalData->bDefaultAntenna*/); //default use Main
418 #else
419         if(pAdapter->HalFunc.GetInterfaceSelectionHandler(pAdapter) == INTF_SEL2_MINICARD )
420                 PHY_SetRFPathSwitch(Adapter, pAdapter->MgntInfo.bDefaultAntenna); //default use Main
421 #endif
422
423 #endif
424
425 #endif
426
427         pMptCtx->backup0xc50 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0);
428         pMptCtx->backup0xc58 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0);
429         pMptCtx->backup0xc30 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_RxDetector1, bMaskByte0);
430
431         return  rtStatus;
432 }
433
434 /*-----------------------------------------------------------------------------
435  * Function:    MPT_DeInitAdapter()
436  *
437  * Overview:    Extra DeInitialization for Mass Production Test.
438  *
439  * Input:               PADAPTER        pAdapter
440  *
441  * Output:              NONE
442  *
443  * Return:              NONE
444  *
445  * Revised History:
446  *      When            Who             Remark
447  *      05/08/2007      MHC             Create Version 0.
448  *      05/18/2007      MHC             Add normal driver MPHalt code.
449  *
450  *---------------------------------------------------------------------------*/
451 VOID
452 MPT_DeInitAdapter(
453         IN      PADAPTER        pAdapter
454         )
455 {
456         PMPT_CONTEXT            pMptCtx = &pAdapter->mppriv.MptCtx;
457
458         pMptCtx->bMptDrvUnload = _TRUE;
459 #if 0 // for Windows
460         PlatformFreeWorkItem( &(pMptCtx->MptWorkItem) );
461
462         while(pMptCtx->bMptWorkItemInProgress)
463         {
464                 if(NdisWaitEvent(&(pMptCtx->MptWorkItemEvent), 50))
465                 {
466                         break;
467                 }
468         }
469         NdisFreeSpinLock( &(pMptCtx->MptWorkItemSpinLock) );
470 #endif
471 }
472
473 static u8 mpt_ProStartTest(PADAPTER padapter)
474 {
475         PMPT_CONTEXT pMptCtx = &padapter->mppriv.MptCtx;
476
477         pMptCtx->bMassProdTest = _TRUE;
478         pMptCtx->bStartContTx = _FALSE;
479         pMptCtx->bCckContTx = _FALSE;
480         pMptCtx->bOfdmContTx = _FALSE;
481         pMptCtx->bSingleCarrier = _FALSE;
482         pMptCtx->bCarrierSuppression = _FALSE;
483         pMptCtx->bSingleTone = _FALSE;
484
485         return _SUCCESS;
486 }
487
488 /*
489  * General use
490  */
491 s32 SetPowerTracking(PADAPTER padapter, u8 enable)
492 {
493
494         Hal_SetPowerTracking( padapter, enable );
495         return 0;
496 }
497
498 void GetPowerTracking(PADAPTER padapter, u8 *enable)
499 {
500         Hal_GetPowerTracking( padapter, enable );
501 }
502
503 static void disable_dm(PADAPTER padapter)
504 {
505         u8 v8;
506         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
507         struct dm_priv  *pdmpriv = &pHalData->dmpriv;
508
509
510         //3 1. disable firmware dynamic mechanism
511         // disable Power Training, Rate Adaptive
512         v8 = rtw_read8(padapter, REG_BCN_CTRL);
513         v8 &= ~EN_BCN_FUNCTION;
514         rtw_write8(padapter, REG_BCN_CTRL, v8);
515
516         //3 2. disable driver dynamic mechanism
517         // disable Dynamic Initial Gain
518         // disable High Power
519         // disable Power Tracking
520         Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
521
522         // enable APK, LCK and IQK but disable power tracking
523         pdmpriv->TxPowerTrackControl = _FALSE;
524         Switch_DM_Func(padapter, DYNAMIC_FUNC_SS, _TRUE);
525 }
526
527 //This function initializes the DUT to the MP test mode
528 s32 mp_start_test(PADAPTER padapter)
529 {
530         WLAN_BSSID_EX bssid;
531         struct sta_info *psta;
532         u32 length;
533         u8 val8;
534
535         _irqL irqL;
536         s32 res = _SUCCESS;
537
538         struct mp_priv *pmppriv = &padapter->mppriv;
539         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
540         struct wlan_network *tgt_network = &pmlmepriv->cur_network;
541
542
543         //3 disable dynamic mechanism
544         disable_dm(padapter);
545
546         //3 0. update mp_priv
547 #if  defined (CONFIG_RTL8192C)  ||  defined (CONFIG_RTL8192D)
548         if (padapter->registrypriv.rf_config == RF_819X_MAX_TYPE) {
549 //              HAL_DATA_TYPE *phal = GET_HAL_DATA(padapter);
550 //              switch (phal->rf_type) {
551                 switch (GET_RF_TYPE(padapter)) {
552                         case RF_1T1R:
553                                 pmppriv->antenna_tx = ANTENNA_A;
554                                 pmppriv->antenna_rx = ANTENNA_A;
555                                 break;
556                         case RF_1T2R:
557                         default:
558                                 pmppriv->antenna_tx = ANTENNA_A;
559                                 pmppriv->antenna_rx = ANTENNA_AB;
560                                 break;
561                         case RF_2T2R:
562                         case RF_2T2R_GREEN:
563                                 pmppriv->antenna_tx = ANTENNA_AB;
564                                 pmppriv->antenna_rx = ANTENNA_AB;
565                                 break;
566                         case RF_2T4R:
567                                 pmppriv->antenna_tx = ANTENNA_AB;
568                                 pmppriv->antenna_rx = ANTENNA_ABCD;
569                                 break;
570                 }
571         }
572 #endif
573         mpt_ProStartTest(padapter);
574
575         //3 1. initialize a new WLAN_BSSID_EX
576 //      _rtw_memset(&bssid, 0, sizeof(WLAN_BSSID_EX));
577         _rtw_memcpy(bssid.MacAddress, pmppriv->network_macaddr, ETH_ALEN);
578         bssid.Ssid.SsidLength = strlen("mp_pseudo_adhoc");
579         _rtw_memcpy(bssid.Ssid.Ssid, (u8*)"mp_pseudo_adhoc", bssid.Ssid.SsidLength);
580         bssid.InfrastructureMode = Ndis802_11IBSS;
581         bssid.NetworkTypeInUse = Ndis802_11DS;
582         bssid.IELength = 0;
583
584         length = get_WLAN_BSSID_EX_sz(&bssid);
585         if (length % 4)
586                 bssid.Length = ((length >> 2) + 1) << 2; //round up to multiple of 4 bytes.
587         else
588                 bssid.Length = length;
589
590         _enter_critical_bh(&pmlmepriv->lock, &irqL);
591
592         if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
593                 goto end_of_mp_start_test;
594
595         //init mp_start_test status
596         if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
597                 rtw_disassoc_cmd(padapter);
598                 rtw_indicate_disconnect(padapter);
599                 rtw_free_assoc_resources(padapter);
600         }
601         pmppriv->prev_fw_state = get_fwstate(pmlmepriv);
602         pmlmepriv->fw_state = WIFI_MP_STATE;
603 #if 0
604         if (pmppriv->mode == _LOOPBOOK_MODE_) {
605                 set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); //append txdesc
606                 RT_TRACE(_module_mp_, _drv_notice_, ("+start mp in Lookback mode\n"));
607         } else {
608                 RT_TRACE(_module_mp_, _drv_notice_, ("+start mp in normal mode\n"));
609         }
610 #endif
611         set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
612
613         //3 2. create a new psta for mp driver
614         //clear psta in the cur_network, if any
615         psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress);
616         if (psta) rtw_free_stainfo(padapter, psta);
617
618         psta = rtw_alloc_stainfo(&padapter->stapriv, bssid.MacAddress);
619         if (psta == NULL) {
620                 RT_TRACE(_module_mp_, _drv_err_, ("mp_start_test: Can't alloc sta_info!\n"));
621                 pmlmepriv->fw_state = pmppriv->prev_fw_state;
622                 res = _FAIL;
623                 goto end_of_mp_start_test;
624         }
625
626         //3 3. join psudo AdHoc
627         tgt_network->join_res = 1;
628         tgt_network->aid = psta->aid = 1;
629         _rtw_memcpy(&tgt_network->network, &bssid, length);
630
631         rtw_indicate_connect(padapter);
632         _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
633
634 end_of_mp_start_test:
635
636         _exit_critical_bh(&pmlmepriv->lock, &irqL);
637
638         if (res == _SUCCESS)
639         {
640                 // set MSR to WIFI_FW_ADHOC_STATE
641 #if  defined (CONFIG_RTL8192C)  ||  defined (CONFIG_RTL8192D)
642                 val8 = rtw_read8(padapter, MSR) & 0xFC; // 0x0102
643                 val8 |= WIFI_FW_ADHOC_STATE;
644                 rtw_write8(padapter, MSR, val8); // Link in ad hoc network
645 #endif
646
647 #if  !defined (CONFIG_RTL8192C)  &&  !defined (CONFIG_RTL8192D)
648                 rtw_write8(padapter, MSR, 1); // Link in ad hoc network
649                 rtw_write8(padapter, RCR, 0); // RCR : disable all pkt, 0x10250048
650                 rtw_write8(padapter, RCR+2, 0x57); // RCR disable Check BSSID, 0x1025004a
651
652                 // disable RX filter map , mgt frames will put in RX FIFO 0
653                 rtw_write16(padapter, RXFLTMAP0, 0x0); // 0x10250116
654
655                 val8 = rtw_read8(padapter, EE_9346CR); // 0x1025000A
656                 if (!(val8 & _9356SEL))//boot from EFUSE
657                         efuse_change_max_size(padapter);
658 #endif
659         }
660
661         return res;
662 }
663 //------------------------------------------------------------------------------
664 //This function change the DUT from the MP test mode into normal mode
665 void mp_stop_test(PADAPTER padapter)
666 {
667         struct mp_priv *pmppriv = &padapter->mppriv;
668         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
669         struct wlan_network *tgt_network = &pmlmepriv->cur_network;
670         struct sta_info *psta;
671
672         _irqL irqL;
673
674
675         _enter_critical_bh(&pmlmepriv->lock, &irqL);
676
677         if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _FALSE)
678                 goto end_of_mp_stop_test;
679
680         //3 1. disconnect psudo AdHoc
681         rtw_indicate_disconnect(padapter);
682
683         //3 2. clear psta used in mp test mode.
684 //      rtw_free_assoc_resources(padapter);
685         psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress);
686         if (psta) rtw_free_stainfo(padapter, psta);
687
688         //3 3. return to normal state (default:station mode)
689         pmlmepriv->fw_state = pmppriv->prev_fw_state; // WIFI_STATION_STATE;
690
691         //flush the cur_network
692         _rtw_memset(tgt_network, 0, sizeof(struct wlan_network));
693
694         _clr_fwstate_(pmlmepriv, WIFI_MP_STATE);
695
696 end_of_mp_stop_test:
697
698         _exit_critical_bh(&pmlmepriv->lock, &irqL);
699 }
700 /*---------------------------hal\rtl8192c\MPT_Phy.c---------------------------*/
701 #if 0
702 //#ifdef CONFIG_USB_HCI
703 static VOID mpt_AdjustRFRegByRateByChan92CU(PADAPTER pAdapter, u8 RateIdx, u8 Channel, u8 BandWidthID)
704 {
705         u8              eRFPath;
706         u32             rfReg0x26;
707         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
708
709
710         if (RateIdx < MPT_RATE_6M) {    // CCK rate,for 88cu
711                 rfReg0x26 = 0xf400;
712         }
713         else if ((RateIdx >= MPT_RATE_6M) && (RateIdx <= MPT_RATE_54M)) {// OFDM rate,for 88cu
714                 if ((4 == Channel) || (8 == Channel) || (12 == Channel))
715                         rfReg0x26 = 0xf000;
716                 else if ((5 == Channel) || (7 == Channel) || (13 == Channel) || (14 == Channel))
717                         rfReg0x26 = 0xf400;
718                 else
719                         rfReg0x26 = 0x4f200;
720         }
721         else if ((RateIdx >= MPT_RATE_MCS0) && (RateIdx <= MPT_RATE_MCS15)) {// MCS 20M ,for 88cu // MCS40M rate,for 88cu
722
723                 if (HT_CHANNEL_WIDTH_20 == BandWidthID) {
724                         if ((4 == Channel) || (8 == Channel))
725                                 rfReg0x26 = 0xf000;
726                         else if ((5 == Channel) || (7 == Channel) || (13 == Channel) || (14 == Channel))
727                                 rfReg0x26 = 0xf400;
728                         else
729                                 rfReg0x26 = 0x4f200;
730                 }
731                 else{
732                         if ((4 == Channel) || (8 == Channel))
733                                 rfReg0x26 = 0xf000;
734                         else if ((5 == Channel) || (7 == Channel))
735                                 rfReg0x26 = 0xf400;
736                         else
737                                 rfReg0x26 = 0x4f200;
738                 }
739         }
740
741 //      RT_TRACE(COMP_CMD, DBG_LOUD, ("\n mpt_AdjustRFRegByRateByChan92CU():Chan:%d Rate=%d rfReg0x26:0x%08x\n",Channel, RateIdx,rfReg0x26));
742         for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) {
743                 write_rfreg(pAdapter, eRFPath, RF_SYN_G2, rfReg0x26);
744         }
745 }
746 #endif
747 /*-----------------------------------------------------------------------------
748  * Function:    mpt_SwitchRfSetting
749  *
750  * Overview:    Change RF Setting when we siwthc channel/rate/BW for MP.
751  *
752  * Input:       IN      PADAPTER                                pAdapter
753  *
754  * Output:      NONE
755  *
756  * Return:      NONE
757  *
758  * Revised History:
759  * When                 Who             Remark
760  * 01/08/2009   MHC             Suggestion from SD3 Willis for 92S series.
761  * 01/09/2009   MHC             Add CCK modification for 40MHZ. Suggestion from SD3.
762  *
763  *---------------------------------------------------------------------------*/
764 static void mpt_SwitchRfSetting(PADAPTER pAdapter)
765 {
766         Hal_mpt_SwitchRfSetting(pAdapter);
767          }
768
769 /*---------------------------hal\rtl8192c\MPT_Phy.c---------------------------*/
770 /*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/
771 static void MPT_CCKTxPowerAdjust(PADAPTER Adapter, BOOLEAN bInCH14)
772 {
773         Hal_MPT_CCKTxPowerAdjust(Adapter,bInCH14);
774 }
775
776 static void MPT_CCKTxPowerAdjustbyIndex(PADAPTER pAdapter, BOOLEAN beven)
777 {
778         Hal_MPT_CCKTxPowerAdjustbyIndex(pAdapter,beven);
779         }
780
781 /*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/
782
783 /*
784  * SetChannel
785  * Description
786  *      Use H2C command to change channel,
787  *      not only modify rf register, but also other setting need to be done.
788  */
789 void SetChannel(PADAPTER pAdapter)
790 {
791         Hal_SetChannel(pAdapter);
792
793 }
794
795 /*
796  * Notice
797  *      Switch bandwitdth may change center frequency(channel)
798  */
799 void SetBandwidth(PADAPTER pAdapter)
800 {
801         Hal_SetBandwidth(pAdapter);
802
803 }
804
805 static void SetCCKTxPower(PADAPTER pAdapter, u8 *TxPower)
806 {
807         Hal_SetCCKTxPower(pAdapter,TxPower);
808 }
809
810 static void SetOFDMTxPower(PADAPTER pAdapter, u8 *TxPower)
811 {
812         Hal_SetOFDMTxPower(pAdapter,TxPower);
813         }
814
815
816 void SetAntenna(PADAPTER pAdapter)
817         {
818         Hal_SetAntenna(pAdapter);
819 }
820
821 void    SetAntennaPathPower(PADAPTER pAdapter)
822 {
823         Hal_SetAntennaPathPower(pAdapter);
824 }
825         
826 void SetTxPower(PADAPTER pAdapter)
827 {
828         Hal_SetTxPower(pAdapter);
829 }
830
831 void SetTxAGCOffset(PADAPTER pAdapter, u32 ulTxAGCOffset)
832 {
833         u32 TxAGCOffset_B, TxAGCOffset_C, TxAGCOffset_D,tmpAGC;
834
835         TxAGCOffset_B = (ulTxAGCOffset&0x000000ff);
836         TxAGCOffset_C = ((ulTxAGCOffset&0x0000ff00)>>8);
837         TxAGCOffset_D = ((ulTxAGCOffset&0x00ff0000)>>16);
838
839         tmpAGC = (TxAGCOffset_D<<8 | TxAGCOffset_C<<4 | TxAGCOffset_B);
840         write_bbreg(pAdapter, rFPGA0_TxGainStage,
841                         (bXBTxAGC|bXCTxAGC|bXDTxAGC), tmpAGC);
842 }
843
844 void SetDataRate(PADAPTER pAdapter)
845 {
846         Hal_SetDataRate(pAdapter);
847 }
848
849 #if  !defined (CONFIG_RTL8192C)  &&  !defined (CONFIG_RTL8192D)
850 /*------------------------------Define structure----------------------------*/
851 typedef struct _R_ANTENNA_SELECT_OFDM {
852         u32     r_tx_antenna:4;
853         u32     r_ant_l:4;
854         u32     r_ant_non_ht:4;
855         u32     r_ant_ht1:4;
856         u32     r_ant_ht2:4;
857         u32     r_ant_ht_s1:4;
858         u32     r_ant_non_ht_s1:4;
859         u32     OFDM_TXSC:2;
860         u32     Reserved:2;
861 }R_ANTENNA_SELECT_OFDM;
862
863 typedef struct _R_ANTENNA_SELECT_CCK {
864         u8      r_cckrx_enable_2:2;
865         u8      r_cckrx_enable:2;
866         u8      r_ccktx_enable:4;
867 }R_ANTENNA_SELECT_CCK;
868 #endif
869
870 s32 SetThermalMeter(PADAPTER pAdapter, u8 target_ther)
871 {
872         return Hal_SetThermalMeter( pAdapter, target_ther);
873 }
874
875 static void TriggerRFThermalMeter(PADAPTER pAdapter)
876 {
877         Hal_TriggerRFThermalMeter(pAdapter);
878 }
879
880 static u8 ReadRFThermalMeter(PADAPTER pAdapter)
881 {
882         return Hal_ReadRFThermalMeter(pAdapter);
883 }
884
885 void GetThermalMeter(PADAPTER pAdapter, u8 *value)
886 {
887         Hal_GetThermalMeter(pAdapter,value);
888 }
889
890 void SetSingleCarrierTx(PADAPTER pAdapter, u8 bStart)
891 {
892         Hal_SetSingleCarrierTx(pAdapter,bStart);
893 }
894
895 void SetSingleToneTx(PADAPTER pAdapter, u8 bStart)
896 {
897         Hal_SetSingleToneTx(pAdapter,bStart);
898 }
899
900 void SetCarrierSuppressionTx(PADAPTER pAdapter, u8 bStart)
901 {
902         Hal_SetCarrierSuppressionTx(pAdapter, bStart);
903 }
904
905 void SetCCKContinuousTx(PADAPTER pAdapter, u8 bStart)
906 {
907         Hal_SetCCKContinuousTx(pAdapter,bStart);
908                 }
909
910 void SetOFDMContinuousTx(PADAPTER pAdapter, u8 bStart)
911 {
912    Hal_SetOFDMContinuousTx( pAdapter, bStart);
913 }/* mpt_StartOfdmContTx */
914
915 void SetContinuousTx(PADAPTER pAdapter, u8 bStart)
916 {
917         Hal_SetContinuousTx(pAdapter,bStart);
918 }
919
920 //------------------------------------------------------------------------------
921 void dump_mpframe(_adapter *padapter, struct xmit_frame *pmpframe)
922 {
923         padapter->HalFunc.mgnt_xmit(padapter, pmpframe);
924 }
925
926 struct xmit_frame *alloc_mp_xmitframe(struct xmit_priv *pxmitpriv)
927 {
928         struct xmit_frame       *pmpframe;
929         struct xmit_buf *pxmitbuf;
930
931         if ((pmpframe = rtw_alloc_xmitframe(pxmitpriv)) == NULL)
932         {
933                 return NULL;
934         }
935
936         if ((pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv)) == NULL)
937         {
938                 rtw_free_xmitframe_ex(pxmitpriv, pmpframe);
939                 return NULL;
940         }
941
942         pmpframe->frame_tag = MP_FRAMETAG;
943
944         pmpframe->pxmitbuf = pxmitbuf;
945
946         pmpframe->buf_addr = pxmitbuf->pbuf;
947
948         pxmitbuf->priv_data = pmpframe;
949
950         return pmpframe;
951
952 }
953
954 thread_return mp_xmit_packet_thread(thread_context context)
955 {
956         struct xmit_frame       *pxmitframe;
957         struct mp_tx            *pmptx;
958         struct mp_priv  *pmp_priv;
959         struct xmit_priv        *pxmitpriv;
960         PADAPTER padapter;
961
962         pmp_priv = (struct mp_priv *)context;
963         pmptx = &pmp_priv->tx;
964         padapter = pmp_priv->papdater;
965         pxmitpriv = &(padapter->xmitpriv);
966
967         thread_enter(padapter);
968
969         //DBG_8192C("%s:pkTx Start\n", __func__);
970         while (1) {
971                 pxmitframe = alloc_mp_xmitframe(pxmitpriv);
972                 if (pxmitframe == NULL) {
973                         if (pmptx->stop ||
974                             padapter->bSurpriseRemoved ||
975                             padapter->bDriverStopped) {
976                                 goto exit;
977                         }
978                         else {
979                                 rtw_msleep_os(1);
980                                 continue;
981                         }
982                 }
983
984                 _rtw_memcpy((u8 *)(pxmitframe->buf_addr+TXDESC_OFFSET), pmptx->buf, pmptx->write_size);
985                 _rtw_memcpy(&(pxmitframe->attrib), &(pmptx->attrib), sizeof(struct pkt_attrib));
986
987                 dump_mpframe(padapter, pxmitframe);
988
989                 pmptx->sended++;
990                 pmp_priv->tx_pktcount++;
991
992                 if (pmptx->stop ||
993                     padapter->bSurpriseRemoved ||
994                     padapter->bDriverStopped)
995                         goto exit;
996                 if ((pmptx->count != 0) &&
997                     (pmptx->count == pmptx->sended))
998                         goto exit;
999
1000                 flush_signals_thread();
1001         }
1002
1003 exit:
1004         //DBG_8192C("%s:pkTx Exit\n", __func__);
1005         rtw_mfree(pmptx->pallocated_buf, pmptx->buf_size);
1006         pmptx->pallocated_buf = NULL;
1007         pmptx->stop = 1;
1008
1009         thread_exit();
1010 }
1011
1012 void fill_txdesc_for_mp(PADAPTER padapter, struct tx_desc *ptxdesc)
1013 {               
1014         struct mp_priv *pmp_priv = &padapter->mppriv;
1015         _rtw_memcpy(ptxdesc, &(pmp_priv->tx.desc), TXDESC_SIZE);
1016 }
1017
1018 void SetPacketTx(PADAPTER padapter)
1019 {
1020         u8 *ptr, *pkt_start, *pkt_end;
1021         u32 pkt_size;
1022         struct tx_desc *desc;
1023         struct ieee80211_hdr *hdr;
1024         u8 macid, payload;
1025         s32 bmcast;
1026         struct pkt_attrib *pattrib;
1027         struct mp_priv *pmp_priv;
1028
1029
1030         pmp_priv = &padapter->mppriv;
1031         if (pmp_priv->tx.stop) return;
1032         pmp_priv->tx.sended = 0;
1033         pmp_priv->tx.stop = 0;
1034         pmp_priv->tx_pktcount = 0;
1035
1036         //3 1. update_attrib()
1037         pattrib = &pmp_priv->tx.attrib;
1038         _rtw_memcpy(pattrib->src, padapter->eeprompriv.mac_addr, ETH_ALEN);
1039         _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1040         _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1041         bmcast = IS_MCAST(pattrib->ra);
1042         if (bmcast) {
1043                 pattrib->mac_id = 1;
1044                 pattrib->psta = rtw_get_bcmc_stainfo(padapter);
1045         } else {
1046                 pattrib->mac_id = 0;
1047                 pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
1048         }
1049
1050         pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen;
1051
1052         //3 2. allocate xmit buffer
1053         pkt_size = pattrib->last_txcmdsz;
1054
1055         if (pmp_priv->tx.pallocated_buf)
1056                 rtw_mfree(pmp_priv->tx.pallocated_buf, pmp_priv->tx.buf_size);
1057         pmp_priv->tx.write_size = pkt_size;
1058         pmp_priv->tx.buf_size = pkt_size + XMITBUF_ALIGN_SZ;
1059         pmp_priv->tx.pallocated_buf = rtw_zmalloc(pmp_priv->tx.buf_size);
1060         if (pmp_priv->tx.pallocated_buf == NULL) {
1061                 DBG_8192C("%s: malloc(%d) fail!!\n", __func__, pmp_priv->tx.buf_size);
1062                 return;
1063         }
1064         pmp_priv->tx.buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pmp_priv->tx.pallocated_buf), XMITBUF_ALIGN_SZ);
1065         ptr = pmp_priv->tx.buf;
1066
1067         desc = &(pmp_priv->tx.desc);
1068         _rtw_memset(desc, 0, TXDESC_SIZE);
1069         pkt_start = ptr;
1070         pkt_end = pkt_start + pkt_size;
1071
1072         //3 3. init TX descriptor
1073         // offset 0
1074         //desc->txdw0 |= cpu_to_le32(pkt_size & 0x0000FFFF); // packet size
1075         //desc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
1076         //desc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00FF0000); //32 bytes for TX Desc
1077         //if (bmcast) desc->txdw0 |= cpu_to_le32(BMC); // broadcast packet
1078
1079         // offset 4
1080         desc->txdw1 |= cpu_to_le32(BK); // don't aggregate(AMPDU)
1081         desc->txdw1 |= cpu_to_le32((pattrib->mac_id) & 0x1F); //CAM_ID(MAC_ID)
1082         desc->txdw1 |= cpu_to_le32((pattrib->qsel << QSEL_SHT) & 0x00001F00); // Queue Select, TID
1083         desc->txdw1 |= cpu_to_le32((pattrib->raid << Rate_ID_SHT) & 0x000F0000); // Rate Adaptive ID
1084
1085         // offset 8
1086         // offset 12
1087         //desc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0xffff0000);
1088
1089         // offset 16
1090         //desc->txdw4 |= cpu_to_le32(QoS);
1091         desc->txdw4 |= cpu_to_le32(HW_SEQ_EN);
1092         desc->txdw4 |= cpu_to_le32(USERATE);
1093         desc->txdw4 |= cpu_to_le32(DISDATAFB);
1094
1095         if( pmp_priv->preamble ){
1096                 if (pmp_priv->rateidx <=  MPT_RATE_54M)
1097                         desc->txdw4 |= cpu_to_le32(DATA_SHORT); // CCK Short Preamble
1098         }
1099         if (pmp_priv->bandwidth == HT_CHANNEL_WIDTH_40)
1100                 desc->txdw4 |= cpu_to_le32(DATA_BW);
1101
1102         // offset 20
1103         desc->txdw5 |= cpu_to_le32(pmp_priv->rateidx & 0x0000001F);
1104
1105         if( pmp_priv->preamble ){
1106                 if (pmp_priv->rateidx > MPT_RATE_54M)
1107                         desc->txdw5 |= cpu_to_le32(SGI); // MCS Short Guard Interval
1108         }
1109         desc->txdw5 |= cpu_to_le32(0x0001FF00); // DATA/RTS Rate Fallback Limit
1110
1111         //3 4. make wlan header, make_wlanhdr()
1112         hdr = (struct ieee80211_hdr *)pkt_start;
1113         SetFrameSubType(&hdr->frame_ctl, pattrib->subtype);
1114         _rtw_memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); // DA
1115         _rtw_memcpy(hdr->addr2, pattrib->src, ETH_ALEN); // SA
1116         _rtw_memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); // RA, BSSID
1117
1118         //3 5. make payload
1119         ptr = pkt_start + pattrib->hdrlen;
1120
1121         switch (pmp_priv->tx.payload) {
1122                 case 0:
1123                         payload = 0x00;
1124                         break;
1125                 case 1:
1126                         payload = 0x5a;
1127                         break;
1128                 case 2:
1129                         payload = 0xa5;
1130                         break;
1131                 case 3:
1132                         payload = 0xff;
1133                         break;
1134                 default:
1135                         payload = 0x00;
1136                         break;
1137         }
1138
1139         _rtw_memset(ptr, payload, pkt_end - ptr);
1140
1141         //3 6. start thread
1142         pmp_priv->tx.PktTxThread = kernel_thread(mp_xmit_packet_thread, pmp_priv, CLONE_FS|CLONE_FILES);
1143         if(pmp_priv->tx.PktTxThread < 0)
1144                 DBG_871X("Create PktTx Thread Fail !!!!!\n");
1145
1146 }
1147
1148 void SetPacketRx(PADAPTER pAdapter, u8 bStartRx)
1149 {
1150         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
1151
1152         if(bStartRx)
1153         {
1154                 // Accept CRC error and destination address
1155                 pHalData->ReceiveConfig |= (RCR_ACRC32|RCR_AAP);
1156                 rtw_write32(pAdapter, REG_RCR, pHalData->ReceiveConfig);
1157         }
1158         else
1159         {
1160                 rtw_write32(pAdapter, REG_RCR, 0);
1161         }
1162 }
1163
1164 void ResetPhyRxPktCount(PADAPTER pAdapter)
1165 {
1166         u32 i, phyrx_set = 0;
1167
1168         for (i = 0; i <= 0xF; i++) {
1169                 phyrx_set = 0;
1170                 phyrx_set |= _RXERR_RPT_SEL(i); //select
1171                 phyrx_set |= RXERR_RPT_RST;     // set counter to zero
1172                 rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set);
1173         }
1174 }
1175
1176 static u32 GetPhyRxPktCounts(PADAPTER pAdapter, u32 selbit)
1177 {
1178         //selection
1179         u32 phyrx_set = 0, count = 0;
1180
1181         phyrx_set = _RXERR_RPT_SEL(selbit & 0xF);
1182         rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set);
1183
1184         //Read packet count
1185         count = rtw_read32(pAdapter, REG_RXERR_RPT) & RXERR_COUNTER_MASK;
1186
1187         return count;
1188 }
1189
1190 u32 GetPhyRxPktReceived(PADAPTER pAdapter)
1191 {
1192         u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0;
1193
1194         OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_OK);
1195         CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_OK);
1196         HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_OK);
1197
1198         return OFDM_cnt + CCK_cnt + HT_cnt;
1199 }
1200
1201 u32 GetPhyRxPktCRC32Error(PADAPTER pAdapter)
1202 {
1203         u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0;
1204
1205         OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_FAIL);
1206         CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_FAIL);
1207         HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_FAIL);
1208
1209         return OFDM_cnt + CCK_cnt + HT_cnt;
1210 }
1211
1212 //reg 0x808[9:0]: FFT data x
1213 //reg 0x808[22]:  0  -->  1  to get 1 FFT data y
1214 //reg 0x8B4[15:0]: FFT data y report
1215 static u32 GetPSDData(PADAPTER pAdapter, u32 point)
1216 {
1217         int psd_val;
1218
1219
1220         psd_val = rtw_read32(pAdapter, 0x808);
1221         psd_val &= 0xFFBFFC00;
1222         psd_val |= point;
1223
1224         rtw_write32(pAdapter, 0x808, psd_val);
1225         rtw_mdelay_os(1);
1226         psd_val |= 0x00400000;
1227
1228         rtw_write32(pAdapter, 0x808, psd_val);
1229         rtw_mdelay_os(1);
1230         psd_val = rtw_read32(pAdapter, 0x8B4);
1231
1232         psd_val &= 0x0000FFFF;
1233
1234         return psd_val;
1235 }
1236
1237 /*
1238  * pts  start_point_min         stop_point_max
1239  * 128  64                      64 + 128 = 192
1240  * 256  128                     128 + 256 = 384
1241  * 512  256                     256 + 512 = 768
1242  * 1024 512                     512 + 1024 = 1536
1243  *
1244  */
1245 u32 mp_query_psd(PADAPTER pAdapter, u8 *data)
1246 {
1247         u8 *val;
1248         u32 i, psd_pts=0, psd_start=0, psd_stop=0;
1249         u32 psd_data=0;
1250
1251
1252         if (!netif_running(pAdapter->pnetdev)) {
1253                 RT_TRACE(_module_mp_, _drv_warning_, ("mp_query_psd: Fail! interface not opened!\n"));
1254                 return 0;
1255         }
1256
1257         if (check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE) == _FALSE) {
1258                 RT_TRACE(_module_mp_, _drv_warning_, ("mp_query_psd: Fail! not in MP mode!\n"));
1259                 return 0;
1260         }
1261
1262         if (strlen(data) == 0) { //default value
1263                 psd_pts = 128;
1264                 psd_start = 64;
1265                 psd_stop = 128;   
1266         } else {
1267                 sscanf(data, "pts=%d,start=%d,stop=%d", &psd_pts, &psd_start, &psd_stop);
1268         }
1269
1270         _rtw_memset(data, '\0', sizeof(data));
1271
1272         i = psd_start;
1273         while (i < psd_stop)
1274         {
1275                 if (i >= psd_pts) {
1276                         psd_data = GetPSDData(pAdapter, i-psd_pts);
1277                 } else {
1278                         psd_data = GetPSDData(pAdapter, i);
1279                 }
1280                 sprintf(data, "%s%x ", data, psd_data);
1281                 i++;
1282         }
1283
1284         #ifdef CONFIG_LONG_DELAY_ISSUE
1285         rtw_msleep_os(100);
1286         #else
1287         rtw_mdelay_os(100);
1288         #endif
1289
1290         return strlen(data)+1;
1291 }
1292
1293 #endif
1294