wifi: renew patch drivers/net/wireless
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rtl8192du / hal / rtl8192d / rtl8192d_cmd.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 _RTL8192D_CMD_C_
21
22 #include <drv_conf.h>
23 #include <osdep_service.h>
24 #include <drv_types.h>
25 #include <recv_osdep.h>
26 #include <cmd_osdep.h>
27 #include <mlme_osdep.h>
28 #include <rtw_byteorder.h>
29 #include <circ_buf.h>
30 #include <rtw_ioctl_set.h>
31
32 #include <rtl8192d_hal.h>
33
34 #ifndef PLATFORM_FREEBSD
35 static BOOLEAN
36 CheckWriteH2C(
37         IN      PADAPTER                Adapter,
38         IN      u8              BoxNum
39 )
40 {
41         u8      valHMETFR;
42         BOOLEAN Result = _FALSE;
43         
44         valHMETFR = rtw_read8(Adapter, REG_HMETFR);
45
46         //DbgPrint("CheckWriteH2C(): Reg[0x%2x] = %x\n",REG_HMETFR, valHMETFR);
47
48         if(((valHMETFR>>BoxNum)&BIT0) == 1)
49                 Result = _TRUE;
50         
51         return Result;
52
53 }
54 #endif //PLATFORM_FREEBSD
55
56 static BOOLEAN
57 CheckFwReadLastH2C(
58         IN      PADAPTER                Adapter,
59         IN      u8              BoxNum
60 )
61 {
62         u8      valHMETFR;
63         BOOLEAN  Result = _FALSE;
64         
65         valHMETFR = rtw_read8(Adapter, REG_HMETFR);
66         //RT_TRACE(COMP_INIT,DBG_LOUD,("REG[%x] = %x\n",        REG_HMETFR, valHMETFR));
67
68         // Do not seperate to 91C and 88C, we use the same setting. Suggested by SD4 Filen. 2009.12.03.
69         if(((valHMETFR>>BoxNum)&BIT0) == 0)
70                 Result = _TRUE;
71
72         return Result;
73 }
74
75
76 //
77 // Description: 
78 //      Fill H2C command
79 //      BOX_0-4 Format: 
80 //      bit [31-8]      |     7         |  [6-0]
81 //           RSVD       |  CMD_EXT      |  CMD_ID
82 //
83 //      BOX Extension 0-4 format:
84 //      bit 15-0: RSVD  
85 //
86
87 /*****************************************
88 * H2C Msg format :
89 *| 31 - 8               |7              | 6 - 0 |       
90 *| h2c_msg      |Ext_bit        |CMD_ID |
91 *
92 ******************************************/
93 static void _FillH2CCmd92D(_adapter* padapter, u8 ElementID, u32 CmdLen, u8* pCmdBuffer)
94 {
95         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
96         u8      BoxNum;
97         u16     BOXReg=0, BOXExtReg=0;
98         u8      BoxContent[4], BoxExtContent[2];
99         u8      BufIndex=0;
100         u8      U1btmp; //Read 0x1bf
101         u8      bWriteSucess = _FALSE;
102         u8      IsFwRead = _FALSE;
103         u8      WaitH2cLimmit = 100;
104         u8      WaitWriteH2cLimmit = 100;
105         u8      idx=0;
106
107 _func_enter_;   
108
109         padapter = GET_PRIMARY_ADAPTER(padapter);               
110         pHalData = GET_HAL_DATA(padapter);
111
112         _enter_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);
113
114         //DBG_8192C("FillH2CCmd : ElementID=%d \n",ElementID);
115
116         while(!bWriteSucess)
117         {
118                 WaitWriteH2cLimmit--;
119                 if(WaitWriteH2cLimmit == 0)
120                 {       
121                         DBG_8192C("FillH2CCmd92C():Write H2C fail because no trigger for FW INT!!!!!!!!\n");
122                         break;
123                 }
124         
125                 // 2. Find the last BOX number which has been writen.
126                 BoxNum = pHalData->LastHMEBoxNum;
127                 switch(BoxNum)
128                 {
129                         case 0:
130                                 BOXReg = REG_HMEBOX_0;
131                                 BOXExtReg = REG_HMEBOX_EXT_0;
132                                 break;
133                         case 1:
134                                 BOXReg = REG_HMEBOX_1;
135                                 BOXExtReg = REG_HMEBOX_EXT_1;
136                                 break;
137                         case 2:
138                                 BOXReg = REG_HMEBOX_2;
139                                 BOXExtReg = REG_HMEBOX_EXT_2;
140                                 break;
141                         case 3:
142                                 BOXReg = REG_HMEBOX_3;
143                                 BOXExtReg = REG_HMEBOX_EXT_3;
144                                 break;
145                         default:
146                                 break;
147                 }
148
149                 // 3. Check if the box content is empty.
150                 IsFwRead = CheckFwReadLastH2C(padapter, BoxNum);
151                 while(!IsFwRead)
152                 {
153                         //wait until Fw read
154                         WaitH2cLimmit--;
155                         if(WaitH2cLimmit == 0)
156                         {
157                                 DBG_8192C("FillH2CCmd92C(): Wating too long for FW read clear HMEBox(%d)!!!\n", BoxNum);
158                                 break;
159                         }
160                         rtw_udelay_os(10); //us
161                         IsFwRead = CheckFwReadLastH2C(padapter, BoxNum);
162                         U1btmp = rtw_read8(padapter, 0x1BF);
163                         //DBG_8192C("FillH2CCmd92C(): Wating for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n", BoxNum, U1btmp);
164                 }
165
166                 // If Fw has not read the last H2C cmd, break and give up this H2C.
167                 if(!IsFwRead)
168                 {
169                         DBG_8192C("FillH2CCmd92C():  Write H2C register BOX[%d] fail!!!!! Fw do not read. \n", BoxNum);
170                         break;
171                 }
172
173                 // 4. Fill the H2C cmd into box         
174                 _rtw_memset(BoxContent, 0, sizeof(BoxContent));
175                 _rtw_memset(BoxExtContent, 0, sizeof(BoxExtContent));
176                 
177                 BoxContent[0] = ElementID; // Fill element ID
178
179                 //DBG_8192C("FillH2CCmd92C():Write ElementID BOXReg(%4x) = %2x \n", BOXReg, ElementID);
180
181                 switch(CmdLen)
182                 {
183                         case 1:
184                         {
185                                 BoxContent[0] &= ~(BIT7);
186                                 _rtw_memcpy((u8 *)(BoxContent)+1, pCmdBuffer+BufIndex, 1);
187                                 //PlatformEFIOWrite4Byte(Adapter, BOXReg, *((pu4Byte)BoxContent));
188                                 //For Endian Free.
189                                 for(idx= 0; idx < 4; idx++)
190                                 {
191                                         rtw_write8(padapter, BOXReg+idx, BoxContent[idx]);
192                                 }
193                                 break;
194                         }
195                         case 2:
196                         {       
197                                 BoxContent[0] &= ~(BIT7);
198                                 _rtw_memcpy((u8 *)(BoxContent)+1, pCmdBuffer+BufIndex, 2);
199                                 //PlatformEFIOWrite4Byte(Adapter, BOXReg, *((pu4Byte)BoxContent));
200                                 for(idx=0; idx < 4; idx++)
201                                 {
202                                         rtw_write8(padapter, BOXReg+idx, BoxContent[idx]);
203                                 }
204                                 break;
205                         }
206                         case 3:
207                         {
208                                 BoxContent[0] &= ~(BIT7);
209                                 _rtw_memcpy((u8 *)(BoxContent)+1, pCmdBuffer+BufIndex, 3);
210                                 //PlatformEFIOWrite4Byte(Adapter, BOXReg, *((pu4Byte)BoxContent));
211                                 for(idx = 0; idx < 4 ; idx++)
212                                 {
213                                         rtw_write8(padapter, BOXReg+idx, BoxContent[idx]);
214                                 }
215                                 break;
216                         }
217                         case 4:
218                         {
219                                 BoxContent[0] |= (BIT7);
220                                 _rtw_memcpy((u8 *)(BoxExtContent), pCmdBuffer+BufIndex, 2);
221                                 _rtw_memcpy((u8 *)(BoxContent)+1, pCmdBuffer+BufIndex+2, 2);
222                                 //PlatformEFIOWrite2Byte(Adapter, BOXExtReg, *((pu2Byte)BoxExtContent));
223                                 //PlatformEFIOWrite4Byte(Adapter, BOXReg, *((pu4Byte)BoxContent));
224                                 for(idx = 0 ; idx < 2 ; idx ++)
225                                 {
226                                         rtw_write8(padapter, BOXExtReg+idx, BoxExtContent[idx]);
227                                 }               
228                                 for(idx = 0 ; idx < 4 ; idx ++)
229                                 {
230                                         rtw_write8(padapter, BOXReg+idx, BoxContent[idx]);
231                                 }
232                                 break;
233                         }
234                         case 5:
235                         {
236                                 BoxContent[0] |= (BIT7);
237                                 _rtw_memcpy((u8 *)(BoxExtContent), pCmdBuffer+BufIndex, 2);
238                                 _rtw_memcpy((u8 *)(BoxContent)+1, pCmdBuffer+BufIndex+2, 3);
239                                 //PlatformEFIOWrite2Byte(Adapter, BOXExtReg, *((pu2Byte)BoxExtContent));
240                                 //PlatformEFIOWrite4Byte(Adapter, BOXReg, *((pu4Byte)BoxContent));
241                                 for(idx = 0 ; idx < 2 ; idx ++)
242                                 {
243                                         rtw_write8(padapter, BOXExtReg+idx, BoxExtContent[idx]);
244                                 }
245                                 for(idx = 0 ; idx < 4 ; idx ++)
246                                 {
247                                         rtw_write8(padapter, BOXReg+idx, BoxContent[idx]);
248                                 }
249                                 break;
250                         }
251                         default:
252                                 break;
253                 }
254
255                 //DBG_8192C("FillH2CCmd(): BoxExtContent=0x%04x\n", *(u16*)BoxExtContent);              
256                 //DBG_8192C("FillH2CCmd(): BoxContent=0x%08x\n", *(u32*)BoxContent);
257
258                 // 5. Normal chip does not need to check if the H2C cmd has be written successfully.
259                 // 92D test chip does not need to check,
260                 bWriteSucess = _TRUE;
261
262                 // Record the next BoxNum
263                 pHalData->LastHMEBoxNum = BoxNum+1;
264                 if(pHalData->LastHMEBoxNum == 4) // loop to 0
265                         pHalData->LastHMEBoxNum = 0;
266                 
267                 //DBG_8192C("FillH2CCmd92C():pHalData->LastHMEBoxNum  = %d\n", pHalData->LastHMEBoxNum);
268                 
269         }
270
271         _exit_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);
272
273 _func_exit_;
274 }
275
276 VOID
277 FillH2CCmd92D(  
278         IN      PADAPTER        Adapter,
279         IN      u8      ElementID,
280         IN      u32     CmdLen,
281         IN      u8*     pCmdBuffer
282 )
283 {
284         u32     tmpCmdBuf[2];   
285
286         //Adapter = ADJUST_TO_ADAPTIVE_ADAPTER(Adapter, TRUE);
287
288         if(Adapter->bFWReady == _FALSE)
289         {
290                 DBG_8192C("FillH2CCmd92D(): return H2C cmd because of Fw download fail!!!\n");
291                 return;
292         }
293
294         _rtw_memset(tmpCmdBuf, 0, 8);
295         _rtw_memcpy(tmpCmdBuf, pCmdBuffer, CmdLen);
296
297         _FillH2CCmd92D(Adapter, ElementID, CmdLen, (u8 *)&tmpCmdBuf);
298
299         return;
300 }
301
302 u8 rtl8192d_h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf);
303 u8 rtl8192d_h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
304 {       
305         u8 ElementID, CmdLen;
306         u8 *pCmdBuffer;
307         struct cmd_msg_parm  *pcmdmsg;
308         
309         if(!pbuf)
310                 return H2C_PARAMETERS_ERROR;
311
312         pcmdmsg = (struct cmd_msg_parm*)pbuf;
313         ElementID = pcmdmsg->eid;
314         CmdLen = pcmdmsg->sz;
315         pCmdBuffer = pcmdmsg->buf;
316
317         FillH2CCmd92D(padapter, ElementID, CmdLen, pCmdBuffer);
318
319         return H2C_SUCCESS;
320 }
321
322
323 u8 rtl8192d_set_raid_cmd(_adapter*padapter, u32 mask, u8 arg)
324 {       
325         u8      buf[5];
326         u8      res=_SUCCESS;
327         
328 _func_enter_;   
329         
330         _rtw_memset(buf, 0, 5);
331         mask = cpu_to_le32( mask );
332         _rtw_memcpy(buf, &mask, 4);
333         buf[4]  = arg;
334
335         FillH2CCmd92D(padapter, H2C_RA_MASK, 5, buf);
336         
337 _func_exit_;
338
339         return res;
340
341 }
342
343 //bitmap[0:27] = tx_rate_bitmap
344 //bitmap[28:31]= Rate Adaptive id
345 //arg[0:4] = macid
346 //arg[5] = Short GI
347 void rtl8192d_Add_RateATid(PADAPTER pAdapter, u32 bitmap, u8 arg)
348 {       
349         
350         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
351                 
352         if(pHalData->fw_ractrl == _TRUE)
353         {
354                 rtl8192d_set_raid_cmd(pAdapter, bitmap, arg);
355         }
356         else
357         {
358                 u8 macid, init_rate, shortGIrate=_FALSE;
359
360                 init_rate = get_highest_rate_idx(bitmap&0x0fffffff)&0x3f;
361                 
362                 macid = arg&0x1f;
363                 
364                 shortGIrate = (arg&BIT(5)) ? _TRUE:_FALSE;
365                 
366                 if (shortGIrate==_TRUE)
367                         init_rate |= BIT(6);
368
369                 rtw_write8(pAdapter, (REG_INIDATA_RATE_SEL+macid), (u8)init_rate);              
370         }
371
372 }
373
374
375 void rtl8192d_set_FwPwrMode_cmd(_adapter*padapter, u8 Mode)
376 {
377         struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
378         u8      u1H2CSetPwrMode[3]={0};
379         u8      beacon_interval = 1;
380         
381 _func_enter_;
382
383         DBG_871X("%s(): Mode = %d, SmartPS = %d\n", __FUNCTION__,Mode,pwrpriv->smart_ps);
384
385         SET_H2CCMD_PWRMODE_PARM_MODE(u1H2CSetPwrMode, Mode);
386         SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CSetPwrMode, pwrpriv->smart_ps);
387         SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1H2CSetPwrMode, beacon_interval);
388
389         FillH2CCmd92D(padapter, H2C_SETPWRMODE, 3, u1H2CSetPwrMode);
390
391 _func_exit_;
392 }
393
394 void ConstructBeacon(_adapter *padapter, u8 *pframe, u32 *pLength);
395 void ConstructBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
396 {
397         struct rtw_ieee80211_hdr        *pwlanhdr;
398         u16                                     *fctrl;
399         u32                                     rate_len, pktlen;
400         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
401         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
402         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
403         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
404
405
406         //DBG_871X("%s\n", __FUNCTION__);
407
408         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;  
409
410         fctrl = &(pwlanhdr->frame_ctl);
411         *(fctrl) = 0;
412         
413         _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
414         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
415         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
416
417         SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
418
419         SetFrameSubType(pframe, WIFI_BEACON);
420         
421         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);       
422         pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
423         
424         //timestamp will be inserted by hardware
425         pframe += 8;
426         pktlen += 8;
427
428         // beacon interval: 2 bytes
429         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); 
430
431         pframe += 2;
432         pktlen += 2;
433
434         // capability info: 2 bytes
435         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
436
437         pframe += 2;
438         pktlen += 2;
439
440
441         if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
442         {
443                 DBG_871X("ie len=%u\n", cur_network->IELength);
444                 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
445                 _rtw_memcpy(pframe, cur_network->IEs+sizeof(NDIS_802_11_FIXED_IEs), pktlen);
446                 
447                 goto _ConstructBeacon;
448         }
449
450         //below for ad-hoc mode
451
452         // SSID
453         pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
454
455         // supported rates...
456         rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
457         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pktlen);
458
459         // DS parameter set
460         pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
461
462         if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
463         {
464                 u32 ATIMWindow;
465                 // IBSS Parameter Set...
466                 //ATIMWindow = cur->Configuration.ATIMWindow;
467                 ATIMWindow = 0;
468                 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
469         }       
470
471
472         //todo: ERP IE
473         
474         
475         // EXTERNDED SUPPORTED RATE
476         if (rate_len > 8)
477         {
478                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
479         }
480
481
482         //todo:HT for adhoc
483
484 _ConstructBeacon:
485
486         if ((pktlen + TXDESC_SIZE) > 512)
487         {
488                 DBG_871X("beacon frame too large\n");
489                 return;
490         }
491
492         *pLength = pktlen;
493
494         //DBG_871X("%s bcn_sz=%u\n", __FUNCTION__, pktlen);
495
496 }
497
498 void ConstructPSPoll(_adapter *padapter, u8 *pframe, u32 *pLength);
499 void ConstructPSPoll(_adapter *padapter, u8 *pframe, u32 *pLength)
500 {
501         struct rtw_ieee80211_hdr        *pwlanhdr;
502         u16                                     *fctrl;
503         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
504         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
505
506         //DBG_871X("%s\n", __FUNCTION__);
507
508         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
509
510         // Frame control.
511         fctrl = &(pwlanhdr->frame_ctl);
512         *(fctrl) = 0;
513         SetPwrMgt(fctrl);
514         SetFrameSubType(pframe, WIFI_PSPOLL);
515
516         // AID.
517         SetDuration(pframe, (pmlmeinfo->aid| 0xc000));
518
519         // BSSID.
520         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
521
522         // TA.
523         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
524
525         *pLength = 16;
526 }
527
528 void ConstructNullFunctionData(_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, BOOLEAN bForcePowerSave);
529 void ConstructNullFunctionData(_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, BOOLEAN bForcePowerSave)
530 {
531         struct rtw_ieee80211_hdr        *pwlanhdr;
532         u16                                     *fctrl;
533         u32                                     pktlen;
534         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
535         struct wlan_network     *cur_network = &pmlmepriv->cur_network;
536         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
537         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
538
539         //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
540
541         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
542
543         fctrl = &(pwlanhdr->frame_ctl);
544         *(fctrl) = 0;
545         if (bForcePowerSave)
546         {
547                 SetPwrMgt(fctrl);
548         }
549
550         switch(cur_network->network.InfrastructureMode)
551         {                       
552                 case Ndis802_11Infrastructure:
553                         SetToDs(fctrl);
554                         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
555                         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
556                         _rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
557                         break;
558                 case Ndis802_11APMode:
559                         SetFrDs(fctrl);
560                         _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
561                         _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
562                         _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
563                         break;
564                 case Ndis802_11IBSS:
565                 default:
566                         _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
567                         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
568                         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
569                         break;
570         }
571
572         SetSeqNum(pwlanhdr, 0);
573
574         SetFrameSubType(pframe, WIFI_DATA_NULL);
575
576         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
577         pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
578
579         *pLength = pktlen;
580 }
581
582 void ConstructProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, BOOLEAN bHideSSID);
583 void ConstructProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, BOOLEAN bHideSSID)
584 {
585         struct rtw_ieee80211_hdr        *pwlanhdr;
586         u16                                     *fctrl; 
587         u8                                      *mac, *bssid;
588         u32                                     pktlen;
589         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
590         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
591         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
592         
593         
594         //DBG_871X("%s\n", __FUNCTION__);
595         
596         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;  
597         
598         mac = myid(&(padapter->eeprompriv));
599         bssid = cur_network->MacAddress;
600         
601         fctrl = &(pwlanhdr->frame_ctl);
602         *(fctrl) = 0;
603         _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
604         _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
605         _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
606
607         SetSeqNum(pwlanhdr, 0);
608         SetFrameSubType(fctrl, WIFI_PROBERSP);
609         
610         pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
611         pframe += pktlen;
612
613         if(cur_network->IELength>MAX_IE_SZ)
614                 return;
615
616         _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
617         pframe += cur_network->IELength;
618         pktlen += cur_network->IELength;
619         
620         *pLength = pktlen;
621 }
622
623 //
624 // Description: In normal chip, we should send some packet to Hw which will be used by Fw
625 //                      in FW LPS mode. The function is to fill the Tx descriptor of this packets, then 
626 //                      Fw can tell Hw to send these packet derectly.
627 // Added by tynli. 2009.10.15.
628 //
629 static VOID
630 FillFakeTxDescriptor92D(
631         IN PADAPTER             Adapter,
632         IN u8*                  pDesc,
633         IN u32                  BufferLen,
634         IN BOOLEAN              IsPsPoll
635 )
636 {
637         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
638         struct tx_desc  *ptxdesc = (struct tx_desc *)pDesc;
639
640         // Clear all status
641         _rtw_memset(pDesc, 0, 32);
642
643         //offset 0
644         ptxdesc->txdw0 |= cpu_to_le32( OWN | FSG | LSG); //own, bFirstSeg, bLastSeg;
645
646         ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000); //32 bytes for TX Desc
647
648         ptxdesc->txdw0 |= cpu_to_le32(BufferLen&0x0000ffff); // Buffer size + command header
649
650         //offset 4
651         ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT<<QSEL_SHT)&0x00001f00); // Fixed queue of Mgnt queue
652
653         //Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw.
654         if(IsPsPoll)
655         {
656                 ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR);
657         }
658         else
659         {
660                 ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
661                 ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
662         }
663
664         //offset 16
665         ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
666
667         if(pHalData->CurrentBandType92D == BAND_ON_5G)
668                 ptxdesc->txdw5 |= cpu_to_le32(BIT(2));// use OFDM 6Mbps
669
670 #ifdef CONFIG_USB_HCI
671         // USB interface drop packet if the checksum of descriptor isn't correct.
672         // Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.).
673         rtl8192du_cal_txdesc_chksum(ptxdesc);
674 #endif
675
676         RT_PRINT_DATA(_module_rtl8712_cmd_c_, _drv_info_, "FillFakeTxDescriptor92D(): H2C Tx Desc Content ----->\n", pDesc, TXDESC_SIZE);
677 }
678
679
680 //
681 // Description: Fill the reserved packets that FW will use to RSVD page. 
682 //                      Now we just send 4 types packet to rsvd page.
683 //                      (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
684 //      Input: 
685 //          bDLFinished - FALSE: At the first time we will send all the packets as a large packet to Hw,
686 //                                              so we need to set the packet length to total lengh.
687 //                            TRUE: At the second time, we should send the first packet (default:beacon)
688 //                                              to Hw again and set the lengh in descriptor to the real beacon lengh.
689 // 2009.10.15 by tynli.
690 void SetFwRsvdPagePkt(PADAPTER Adapter, BOOLEAN bDLFinished);
691 void SetFwRsvdPagePkt(PADAPTER Adapter, BOOLEAN bDLFinished)
692 {
693         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
694         struct xmit_frame       *pmgntframe;
695         struct pkt_attrib       *pattrib;
696         struct xmit_priv        *pxmitpriv = &(Adapter->xmitpriv);
697         struct mlme_ext_priv    *pmlmeext = &(Adapter->mlmeextpriv);
698         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
699         u32     BeaconLength, ProbeRspLength, PSPollLength, NullFunctionDataLength;
700         u8      *ReservedPagePacket;
701         u8      PageNum=0, U1bTmp, TxDescLen=0, TxDescOffset=0;
702         u16     BufIndex=0;
703         u32     TotalPacketLen;
704         u8      u1RsvdPageLoc[3]={0};
705         BOOLEAN bDLOK = _FALSE;
706
707         DBG_871X("%s\n", __FUNCTION__);
708
709         ReservedPagePacket = (u8*)rtw_malloc(1000);
710         if(ReservedPagePacket == NULL){
711                 DBG_871X("%s(): alloc ReservedPagePacket fail !!!\n", __FUNCTION__);
712                 return;
713         }
714         
715         _rtw_memset(ReservedPagePacket, 0, 1000);
716
717         TxDescLen = 32;//TX_DESC_SIZE;
718
719 #ifdef CONFIG_USB_HCI
720         BufIndex = TXDESC_OFFSET;
721         TxDescOffset = TxDescLen+8; //Shift index for 8 bytes because the dummy bytes in the first descipstor.
722 #else
723         BufIndex = 0;
724         TxDescOffset = 0;
725 #endif
726
727         //(1) beacon
728         ConstructBeacon(Adapter,&ReservedPagePacket[BufIndex],&BeaconLength);
729
730         RT_PRINT_DATA(_module_rtl8712_cmd_c_, _drv_info_, 
731                 "SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: BCN\n", 
732                 &ReservedPagePacket[BufIndex], (BeaconLength+BufIndex));
733
734 //--------------------------------------------------------------------
735
736         // When we count the first page size, we need to reserve description size for the RSVD 
737         // packet, it will be filled in front of the packet in TXPKTBUF.
738         U1bTmp = (u8)PageNum_128(BeaconLength+TxDescLen);
739         PageNum += U1bTmp;
740         // To reserved 2 pages for beacon buffer. 2010.06.24.
741         if(PageNum == 1)
742                 PageNum+=1;
743         pHalData->FwRsvdPageStartOffset = PageNum;
744
745         BufIndex = (PageNum*128) + TxDescOffset;
746                 
747         //(2) ps-poll
748         ConstructPSPoll(Adapter, &ReservedPagePacket[BufIndex],&PSPollLength);
749         
750         FillFakeTxDescriptor92D(Adapter, &ReservedPagePacket[BufIndex-TxDescLen], PSPollLength, _TRUE);
751
752         RT_PRINT_DATA(_module_rtl8712_cmd_c_, _drv_info_, 
753                 "SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: PS-POLL\n", 
754                 &ReservedPagePacket[BufIndex-TxDescLen], (PSPollLength+TxDescLen));
755
756         SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PageNum );
757
758 //------------------------------------------------------------------
759                         
760         U1bTmp = (u8)PageNum_128(PSPollLength+TxDescLen);
761         PageNum += U1bTmp;
762
763         BufIndex = (PageNum*128) + TxDescOffset;
764
765         //(3) null data
766         ConstructNullFunctionData(
767                 Adapter, 
768                 &ReservedPagePacket[BufIndex],
769                 &NullFunctionDataLength,
770                 get_my_bssid(&(pmlmeinfo->network)),
771                 _FALSE);
772         
773         FillFakeTxDescriptor92D(Adapter, &ReservedPagePacket[BufIndex-TxDescLen], NullFunctionDataLength, _FALSE);
774
775         SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, PageNum);
776
777         RT_PRINT_DATA(_module_rtl8712_cmd_c_, _drv_info_, 
778                 "SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: NULL DATA \n", 
779                 &ReservedPagePacket[BufIndex-TxDescLen], (NullFunctionDataLength+TxDescLen));
780 //------------------------------------------------------------------
781
782         U1bTmp = (u8)PageNum_128(NullFunctionDataLength+TxDescLen);
783         PageNum += U1bTmp;
784         
785         BufIndex = (PageNum*128) + TxDescOffset;
786         
787         //(4) probe response
788         ConstructProbeRsp(
789                 Adapter, 
790                 &ReservedPagePacket[BufIndex],
791                 &ProbeRspLength,
792                 get_my_bssid(&(pmlmeinfo->network)),
793                 _FALSE);
794         
795         FillFakeTxDescriptor92D(Adapter, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, _FALSE);
796
797         SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PageNum);
798
799         RT_PRINT_DATA(_module_rtl8712_cmd_c_, _drv_info_, 
800                 "SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: PROBE RSP \n", 
801                 &ReservedPagePacket[BufIndex-TxDescLen], (ProbeRspLength-TxDescLen));
802
803 //------------------------------------------------------------------
804
805         U1bTmp = (u8)PageNum_128(ProbeRspLength+TxDescLen);
806
807         PageNum += U1bTmp;
808
809         TotalPacketLen = (PageNum*128);
810
811         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
812         {
813                 return;
814         }
815
816         //update attribute
817         pattrib = &pmgntframe->attrib;
818         update_mgntframe_attrib(Adapter, pattrib);
819         pattrib->qsel = 0x10;
820         pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescLen;
821         _rtw_memcpy(pmgntframe->buf_addr, ReservedPagePacket, TotalPacketLen);
822
823         rtw_hal_mgnt_xmit(Adapter, pmgntframe);
824
825         bDLOK = _TRUE;
826
827         if(bDLOK)
828         {
829                 DBG_871X("Set RSVD page location to Fw.\n");
830                 FillH2CCmd92D(Adapter, H2C_RSVDPAGE, sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
831                 //FillH2CCmd92D(Adapter, H2C_RSVDPAGE, sizeof(RsvdPageLoc), (u8 *)&RsvdPageLoc);
832         }
833
834         rtw_mfree(ReservedPagePacket,1000);
835 }
836
837 void rtl8192d_set_FwJoinBssReport_cmd(_adapter* padapter, u8 mstatus)
838 {
839         u8      u1JoinBssRptParm[1]={0};
840         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
841         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
842         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
843         BOOLEAN bRecover = _FALSE;
844         
845 _func_enter_;
846
847         DBG_871X("%s\n", __FUNCTION__);
848
849         if(mstatus == 1)
850         {
851                 // We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C.
852                 // Suggested by filen. Added by tynli.
853                 rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid));
854                 // Do not set TSF again here or vWiFi beacon DMA INT will not work.
855                 //rtw_hal_set_hwreg(Adapter, HW_VAR_CORRECT_TSF, (pu1Byte)(&bTypeIbss));
856                 // Hw sequende enable by dedault. 2010.06.23. by tynli.
857
858                 //set REG_CR bit 8
859                 pHalData->RegCR_1 |= BIT0;
860                 rtw_write8(padapter,  REG_CR+1, pHalData->RegCR_1);
861
862                 // Disable Hw protection for a time which revserd for Hw sending beacon.
863                 // Fix download reserved page packet fail that access collision with the protection time.
864                 // 2010.05.11. Added by tynli.
865                 //SetBcnCtrlReg(Adapter, 0, BIT3);
866                 //SetBcnCtrlReg(Adapter, BIT4, 0);
867                 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)&(~BIT(3)));
868                 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|BIT(4));
869
870                 // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.
871                 if(pHalData->RegFwHwTxQCtrl&BIT6)
872                         bRecover = _TRUE;
873                 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl&(~BIT6)));
874                 pHalData->RegFwHwTxQCtrl &= (~BIT6);
875                 SetFwRsvdPagePkt(padapter, 0);
876                                 
877                 // 2010.05.11. Added by tynli.
878                 //SetBcnCtrlReg(Adapter, BIT3, 0);
879                 //SetBcnCtrlReg(Adapter, 0, BIT4);
880                 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|BIT(3));
881                 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)&(~BIT(4)));
882
883                 // To make sure that if there exists an adapter which would like to send beacon.
884                 // If exists, the origianl value of 0x422[6] will be 1, we should check this to
885                 // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause 
886                 // the beacon cannot be sent by HW.
887                 // 2010.06.23. Added by tynli.
888                 if(bRecover)
889                 {
890                         rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl|BIT6));
891                         pHalData->RegFwHwTxQCtrl |= BIT6;
892                 }
893
894                 // Clear CR[8] or beacon packet will not be send to TxBuf anymore.
895                 pHalData->RegCR_1 &= (~BIT0);
896                 rtw_write8(padapter,  REG_CR+1, pHalData->RegCR_1);
897         }
898
899         SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1JoinBssRptParm, mstatus);
900         
901         FillH2CCmd92D(padapter, H2C_JOINBSSRPT, 1, u1JoinBssRptParm);
902
903 _func_exit_;
904 }
905
906 #ifdef CONFIG_P2P_PS
907 void rtl8192d_set_p2p_ctw_period_cmd(_adapter* padapter, u8 ctwindow)
908 {
909         u8      CTWPeriod = ctwindow;
910
911         FillH2CCmd92D(padapter, H2C_P2P_PS_CTW_CMD, 1, (u8 *)(&CTWPeriod));
912         
913 }
914
915 void rtl8192d_set_p2p_ps_offload_cmd(_adapter* padapter, u8 p2p_ps_state)
916 {
917         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);     
918         struct pwrctrl_priv             *pwrpriv = &padapter->pwrctrlpriv;
919         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );
920         struct P2P_PS_Offload_t *p2p_ps_offload = &pHalData->p2p_ps_offload;
921         u8      i;
922         u16     ctwindow;
923         u32     start_time, tsf_low;
924
925 _func_enter_;
926
927         switch(p2p_ps_state)
928         {
929                 case P2P_PS_DISABLE:
930                         DBG_8192C("P2P_PS_DISABLE \n");
931                         _rtw_memset(p2p_ps_offload, 0 ,1);
932                         break;
933                 case P2P_PS_ENABLE:
934                         DBG_8192C("P2P_PS_ENABLE \n");
935                         // update CTWindow value.
936                         if( pwdinfo->ctwindow > 0 )
937                         {
938                                 p2p_ps_offload->CTWindow_En = 1;
939                                 ctwindow = pwdinfo->ctwindow;
940                                 rtl8192d_set_p2p_ctw_period_cmd(padapter, ctwindow);
941                                 //rtw_write16(padapter, REG_ATIMWND, ctwindow);
942                         }
943
944                         // hw only support 2 set of NoA
945                         for( i=0 ; i<pwdinfo->noa_num ; i++)
946                         {
947                                 // To control the register setting for which NOA
948                                 rtw_write8(padapter, 0x5CF, (i << 4));
949                                 if(i == 0)
950                                         p2p_ps_offload->NoA0_En = 1;
951                                 else
952                                         p2p_ps_offload->NoA1_En = 1;
953
954                                 // config P2P NoA Descriptor Register
955                                 rtw_write32(padapter, 0x5E0, pwdinfo->noa_duration[i]);
956
957                                 rtw_write32(padapter, 0x5E4, pwdinfo->noa_interval[i]);
958
959                                 //Get Current \14TSF value
960                                 tsf_low = rtw_read32(padapter, REG_TSFTR);
961
962                                 start_time = pwdinfo->noa_start_time[i];
963                                 if(pwdinfo->noa_count[i] != 1)
964                                 {
965                                         while( start_time <= (tsf_low+(50*1024) ) )
966                                         {
967                                                 start_time += pwdinfo->noa_interval[i];
968                                                 if(pwdinfo->noa_count[i] != 255)
969                                                         pwdinfo->noa_count[i]--;
970                                         }
971                                 }
972                                 //DBG_8192C("%s(): start_time = %x\n",__FUNCTION__,start_time);
973                                 rtw_write32(padapter, 0x5E8, start_time);
974
975                                 rtw_write8(padapter, 0x5EC, pwdinfo->noa_count[i]);
976                         }
977
978                         if( (pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0) )
979                         {
980                                 // rst p2p circuit
981                                 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(4));
982
983                                 p2p_ps_offload->Offload_En = 1;
984
985                                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
986                                 {
987                                         p2p_ps_offload->role= 1;
988                                         p2p_ps_offload->AllStaSleep = 0;
989                                 }
990                                 else
991                                 {
992                                         p2p_ps_offload->role= 0;
993                                 }
994
995                                 p2p_ps_offload->discovery = 0;
996                         }
997                         break;
998                 case P2P_PS_SCAN:
999                         DBG_8192C("P2P_PS_SCAN \n");
1000                         p2p_ps_offload->discovery = 1;
1001                         break;
1002                 case P2P_PS_SCAN_DONE:
1003                         DBG_8192C("P2P_PS_SCAN_DONE \n");
1004                         p2p_ps_offload->discovery = 0;
1005                         pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
1006                         break;
1007                 default:
1008                         break;
1009         }
1010
1011         FillH2CCmd92D(padapter, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);
1012
1013 _func_exit_;
1014
1015 }
1016 #endif // CONFIG_P2P_PS
1017
1018
1019
1020 #ifdef CONFIG_TSF_RESET_OFFLOAD
1021 /*
1022         ask FW to Reset sync register at Beacon early interrupt
1023 */
1024 u8 rtl8192d_reset_tsf(_adapter *padapter, u8 reset_port )
1025 {       
1026         u8      buf[2];
1027         u8      res=_SUCCESS;
1028         
1029 _func_enter_;
1030         if (IFACE_PORT0==reset_port) {
1031                 buf[0] = 0x1; buf[1] = 0;
1032         
1033         } else{
1034                 buf[0] = 0x0; buf[1] = 0x1;
1035         }
1036         FillH2CCmd92D(padapter, H2C_92D_RESET_TSF, 2, buf);
1037 _func_exit_;
1038
1039         return res;
1040 }
1041
1042 int reset_tsf(PADAPTER Adapter, u8 reset_port )
1043 {
1044         u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
1045         u32 reg_reset_tsf_cnt = (IFACE_PORT0==reset_port) ?
1046                                 REG_FW_RESET_TSF_CNT_0:REG_FW_RESET_TSF_CNT_1;
1047
1048         rtw_scan_abort(Adapter->pbuddy_adapter);        /*      site survey will cause reset_tsf fail   */
1049         reset_cnt_after = reset_cnt_before = rtw_read8(Adapter,reg_reset_tsf_cnt);
1050         rtl8192d_reset_tsf(Adapter, reset_port);
1051
1052         while ((reset_cnt_after == reset_cnt_before ) && (loop_cnt < 10)) {
1053                 rtw_msleep_os(100);
1054                 loop_cnt++;
1055                 reset_cnt_after = rtw_read8(Adapter, reg_reset_tsf_cnt);
1056         }
1057
1058         return(loop_cnt >= 10) ? _FAIL : _TRUE;
1059 }
1060
1061
1062 #endif  // CONFIG_TSF_RESET_OFFLOAD
1063
1064 #ifdef CONFIG_WOWLAN
1065
1066 void rtl8192d_set_wowlan_cmd(_adapter* padapter)
1067 {
1068         u8      res=_SUCCESS;
1069         u32 test=0;
1070         struct recv_priv        *precvpriv = &padapter->recvpriv;
1071
1072         SETWOWLAN_PARM pwowlan_parm;
1073         struct pwrctrl_priv *pwrpriv=&padapter->pwrctrlpriv;
1074         
1075 _func_enter_;
1076
1077         pwowlan_parm.mode =0;
1078         pwowlan_parm.gpio_index=0;
1079         pwowlan_parm.gpio_duration=0;
1080         pwowlan_parm.second_mode =0;
1081         pwowlan_parm.reserve=0;
1082
1083
1084         
1085         if(pwrpriv->wowlan_mode ==_TRUE){
1086                 //pause RX DMA
1087                 test = rtw_read8(padapter, REG_RXPKT_NUM+2);
1088                 test |= BIT(2);
1089                 rtw_write8(padapter, REG_RXPKT_NUM+2, test);
1090                 //286 BIT(1) , not 1(means idle) do rx urb
1091                 test = rtw_read8(padapter, REG_RXPKT_NUM+2) & BIT(1);
1092                 //printk("line(%d) 0x286=%d\n", __LINE__, rtw_read8(padapter, REG_RXPKT_NUM+2));
1093                 //check DMA idle?
1094                 while(test != BIT(1))
1095                 {
1096                         tasklet_schedule(&precvpriv->recv_tasklet);
1097                         test = rtw_read8(padapter, REG_RXPKT_NUM+2) & BIT(1);
1098                         rtw_msleep_os(10);
1099                         //printk("line(%d) 0x286=%d\n", __LINE__, test);
1100                 }
1101                 //mask usb se0 reset by Alex and DD
1102                 test = rtw_read8(padapter, 0xf8);
1103                 test &= ~(BIT(3)|BIT(4));
1104                 rtw_write8(padapter, 0xf8, test);
1105
1106                 pwowlan_parm.mode |=FW_WOWLAN_FUN_EN;
1107                 //printk("\n %s 1.pwowlan_parm.mode=0x%x \n",__FUNCTION__,pwowlan_parm.mode );
1108                 if(pwrpriv->wowlan_pattern ==_TRUE){
1109                         pwowlan_parm.mode |= FW_WOWLAN_PATTERN_MATCH;
1110                 //printk("\n %s 2.pwowlan_parm.mode=0x%x \n",__FUNCTION__,pwowlan_parm.mode );
1111                 }
1112                 if(pwrpriv->wowlan_magic ==_TRUE){
1113                         //pwowlan_parm.mode |=FW_WOWLAN_MAGIC_PKT;
1114                 //printk("\n %s 3.pwowlan_parm.mode=0x%x \n",__FUNCTION__,pwowlan_parm.mode );
1115                 }
1116                 if(pwrpriv->wowlan_unicast ==_TRUE){
1117                         pwowlan_parm.mode |=FW_WOWLAN_UNICAST;
1118                 //printk("\n %s 4.pwowlan_parm.mode=0x%x \n",__FUNCTION__,pwowlan_parm.mode );
1119                 }
1120                 
1121                 rtl8192d_set_FwJoinBssReport_cmd(padapter, 1);
1122                 
1123                 //WOWLAN_GPIO_ACTIVE means GPIO high active
1124                 //pwowlan_parm.mode |=FW_WOWLAN_GPIO_ACTIVE;
1125                 pwowlan_parm.mode |=FW_WOWLAN_REKEY_WAKEUP;
1126                 pwowlan_parm.mode |=FW_WOWLAN_DEAUTH_WAKEUP;
1127                 
1128                 //GPIO 0
1129                 pwowlan_parm.gpio_index=0;
1130                 
1131                 //duration unit is 64us
1132                 pwowlan_parm.gpio_duration=0xff;
1133                 
1134                 pwowlan_parm.second_mode|=FW_WOWLAN_GPIO_WAKEUP_EN;
1135                 pwowlan_parm.second_mode|=FW_FW_PARSE_MAGIC_PKT;
1136                 //printk("\n %s 5.pwowlan_parm.mode=0x%x \n",__FUNCTION__,pwowlan_parm.mode );
1137                 {       u8 *ptr=(u8 *)&pwowlan_parm;
1138                         printk("\n %s H2C_WO_WLAN=%x %02x:%02x:%02x:%02x:%02x \n",__FUNCTION__,H2C_WO_WLAN_CMD,ptr[0],ptr[1],ptr[2],ptr[3],ptr[4] );
1139                 }
1140                 FillH2CCmd92D(padapter, H2C_WO_WLAN_CMD, 4, (u8 *)&pwowlan_parm);
1141                         
1142                 
1143                 //keep alive period = 3 * 10 BCN interval
1144                 pwowlan_parm.mode =3;
1145                 pwowlan_parm.gpio_index=3;
1146                 FillH2CCmd92D(padapter, KEEP_ALIVE_CONTROL_CMD, 2, (u8 *)&pwowlan_parm);
1147                 printk("%s after KEEP_ALIVE_CONTROL_CMD register 0x81=%x \n",__FUNCTION__,rtw_read8(padapter, 0x85));
1148
1149                 pwowlan_parm.mode =1;
1150                 pwowlan_parm.gpio_index=0;
1151                 pwowlan_parm.gpio_duration=0;
1152                 FillH2CCmd92D(padapter, DISCONNECT_DECISION_CTRL_CMD, 3, (u8 *)&pwowlan_parm);
1153                 printk("%s after DISCONNECT_DECISION_CTRL_CMD register 0x81=%x \n",__FUNCTION__,rtw_read8(padapter, 0x85));
1154                 
1155                 //enable GPIO wakeup
1156                 pwowlan_parm.mode =1;
1157                 pwowlan_parm.gpio_index=0;
1158                 pwowlan_parm.gpio_duration=0;
1159                 FillH2CCmd92D(padapter, REMOTE_WAKE_CTRL_CMD, 1, (u8 *)&pwowlan_parm);
1160                 printk("%s after DISCONNECT_DECISION_CTRL_CMD register \n",__FUNCTION__);
1161
1162         }
1163         else
1164                 FillH2CCmd92D(padapter, H2C_WO_WLAN_CMD, 4, (u8 *)&pwowlan_parm);
1165
1166         
1167 _func_exit_;
1168
1169         return ;
1170
1171 }
1172
1173 #endif  //CONFIG_WOWLAN
1174