Merge tag lsk-v3.10-15.03-android
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723bu / hal / hal_com.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 _HAL_COM_C_
21
22 #include <drv_types.h>
23 #include "hal_com_h2c.h"
24
25 #include "hal_data.h"
26
27 //#define CONFIG_GTK_OL_DBG
28
29 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
30 char    file_path[PATH_LENGTH_MAX];
31 #endif
32
33 u8 rtw_hal_data_init(_adapter *padapter)
34 {
35         if(is_primary_adapter(padapter))
36         {
37                 padapter->hal_data_sz = sizeof(HAL_DATA_TYPE);
38                 padapter->HalData = rtw_zvmalloc(padapter->hal_data_sz);
39                 if(padapter->HalData == NULL){
40                         DBG_8192C("cant not alloc memory for HAL DATA \n");
41                         return _FAIL;
42                 }
43         }
44         return _SUCCESS;
45 }
46
47 void rtw_hal_data_deinit(_adapter *padapter)
48 {       
49         if(is_primary_adapter(padapter))
50         {
51                 if (padapter->HalData) 
52                 {
53                         #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
54                         phy_free_filebuf(padapter);                             
55                         #endif
56                         rtw_vmfree(padapter->HalData, padapter->hal_data_sz);
57                         padapter->HalData = NULL;
58                         padapter->hal_data_sz = 0;
59                 }       
60         }
61 }
62
63 void dump_chip_info(HAL_VERSION ChipVersion)
64 {
65         int cnt = 0;
66         u8 buf[128];
67         
68         if(IS_81XXC(ChipVersion)){
69                 cnt += sprintf((buf+cnt), "Chip Version Info: %s_", IS_92C_SERIAL(ChipVersion)?"CHIP_8192C":"CHIP_8188C");
70         }
71         else if(IS_92D(ChipVersion)){
72                 cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8192D_");
73         }
74         else if(IS_8723_SERIES(ChipVersion)){
75                 cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8723A_");
76         }
77         else if(IS_8188E(ChipVersion)){
78                 cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8188E_");
79         }
80         else if(IS_8812_SERIES(ChipVersion)){
81                 cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8812_");
82         }
83     else if(IS_8192E(ChipVersion)){
84                 cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8192E_");
85         }
86         else if(IS_8821_SERIES(ChipVersion)){
87                 cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8821_");
88         }
89         else if(IS_8723B_SERIES(ChipVersion)){
90                 cnt += sprintf((buf+cnt), "Chip Version Info: CHIP_8723B_");
91         }
92
93         cnt += sprintf((buf+cnt), "%s_", IS_NORMAL_CHIP(ChipVersion)?"Normal_Chip":"Test_Chip");
94         if(IS_CHIP_VENDOR_TSMC(ChipVersion))
95                 cnt += sprintf((buf+cnt), "%s_","TSMC");
96         else if(IS_CHIP_VENDOR_UMC(ChipVersion))        
97                 cnt += sprintf((buf+cnt), "%s_","UMC");
98         else if(IS_CHIP_VENDOR_SMIC(ChipVersion))
99                 cnt += sprintf((buf+cnt), "%s_","SMIC");                
100         
101         if(IS_A_CUT(ChipVersion)) cnt += sprintf((buf+cnt), "A_CUT_");
102         else if(IS_B_CUT(ChipVersion)) cnt += sprintf((buf+cnt), "B_CUT_");
103         else if(IS_C_CUT(ChipVersion)) cnt += sprintf((buf+cnt), "C_CUT_");
104         else if(IS_D_CUT(ChipVersion)) cnt += sprintf((buf+cnt), "D_CUT_");
105         else if(IS_E_CUT(ChipVersion)) cnt += sprintf((buf+cnt), "E_CUT_");
106         else if(IS_I_CUT(ChipVersion)) cnt += sprintf((buf+cnt), "I_CUT_");
107         else if(IS_J_CUT(ChipVersion)) cnt += sprintf((buf+cnt), "J_CUT_");
108         else if(IS_K_CUT(ChipVersion)) cnt += sprintf((buf+cnt), "K_CUT_");
109         else cnt += sprintf((buf+cnt), "UNKNOWN_CUT(%d)_", ChipVersion.CUTVersion);
110
111         if(IS_1T1R(ChipVersion)) cnt += sprintf((buf+cnt), "1T1R_");
112         else if(IS_1T2R(ChipVersion)) cnt += sprintf((buf+cnt), "1T2R_");
113         else if(IS_2T2R(ChipVersion)) cnt += sprintf((buf+cnt), "2T2R_");
114         else cnt += sprintf((buf+cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
115
116         cnt += sprintf((buf+cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
117
118         DBG_871X("%s", buf);
119 }
120
121
122 #define EEPROM_CHANNEL_PLAN_BY_HW_MASK  0x80
123
124 /*
125  * Description:
126  *      Use hardware(efuse), driver parameter(registry) and default channel plan
127  *      to decide which one should be used.
128  *
129  * Parameters:
130  *      padapter                        pointer of adapter
131  *      hw_channel_plan         channel plan from HW (efuse/eeprom)
132  *                                              BIT[7] software configure mode; 0:Enable, 1:disable
133  *                                              BIT[6:0] Channel Plan
134  *      sw_channel_plan         channel plan from SW (registry/module param)
135  *      def_channel_plan        channel plan used when HW/SW both invalid
136  *      AutoLoadFail            efuse autoload fail or not
137  *
138  * Return:
139  *      Final channel plan decision
140  *
141  */
142 u8
143 hal_com_config_channel_plan(
144         IN      PADAPTER        padapter,
145         IN      u8                      hw_channel_plan,
146         IN      u8                      sw_channel_plan,
147         IN      u8                      def_channel_plan,
148         IN      BOOLEAN         AutoLoadFail
149         )
150 {
151         PHAL_DATA_TYPE  pHalData;
152         u8 hwConfig;
153         u8 chnlPlan;
154
155
156         pHalData = GET_HAL_DATA(padapter);
157         pHalData->bDisableSWChannelPlan = _FALSE;
158         chnlPlan = def_channel_plan;
159
160         if (0xFF == hw_channel_plan)
161                 AutoLoadFail = _TRUE;
162
163         if (_FALSE == AutoLoadFail)
164         {
165                 u8 hw_chnlPlan;
166
167                 hw_chnlPlan = hw_channel_plan & (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
168                 if (rtw_is_channel_plan_valid(hw_chnlPlan))
169                 {
170 #ifndef CONFIG_SW_CHANNEL_PLAN
171                         if (hw_channel_plan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
172                                 pHalData->bDisableSWChannelPlan = _TRUE;
173 #endif // !CONFIG_SW_CHANNEL_PLAN
174
175                         chnlPlan = hw_chnlPlan;
176                 }
177         }
178
179         if ((_FALSE == pHalData->bDisableSWChannelPlan)
180                 && rtw_is_channel_plan_valid(sw_channel_plan))
181         {
182                 chnlPlan = sw_channel_plan;
183         }
184
185         return chnlPlan;
186 }
187
188 BOOLEAN
189 HAL_IsLegalChannel(
190         IN      PADAPTER        Adapter,
191         IN      u32                     Channel
192         )
193 {
194         BOOLEAN bLegalChannel = _TRUE;
195
196         if (Channel > 14) {
197                 if(IsSupported5G(Adapter->registrypriv.wireless_mode) == _FALSE) {
198                         bLegalChannel = _FALSE;
199                         DBG_871X("Channel > 14 but wireless_mode do not support 5G\n");
200                 }
201         } else if ((Channel <= 14) && (Channel >=1)){
202                 if(IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
203                         bLegalChannel = _FALSE;
204                         DBG_871X("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
205                 }
206         } else {
207                 bLegalChannel = _FALSE;
208                 DBG_871X("Channel is Invalid !!!\n");
209         }
210
211         return bLegalChannel;
212 }       
213
214 u8      MRateToHwRate(u8 rate)
215 {
216         u8      ret = DESC_RATE1M;
217                 
218         switch(rate)
219         {
220                 case MGN_1M:                ret = DESC_RATE1M;  break;
221                 case MGN_2M:                ret = DESC_RATE2M;  break;
222                 case MGN_5_5M:              ret = DESC_RATE5_5M;        break;
223                 case MGN_11M:               ret = DESC_RATE11M; break;
224                 case MGN_6M:                ret = DESC_RATE6M;  break;
225                 case MGN_9M:                ret = DESC_RATE9M;  break;
226                 case MGN_12M:               ret = DESC_RATE12M; break;
227                 case MGN_18M:               ret = DESC_RATE18M; break;
228                 case MGN_24M:               ret = DESC_RATE24M; break;
229                 case MGN_36M:               ret = DESC_RATE36M; break;
230                 case MGN_48M:               ret = DESC_RATE48M; break;
231                 case MGN_54M:               ret = DESC_RATE54M; break;
232
233                 case MGN_MCS0:              ret = DESC_RATEMCS0;        break;
234                 case MGN_MCS1:              ret = DESC_RATEMCS1;        break;
235                 case MGN_MCS2:              ret = DESC_RATEMCS2;        break;
236                 case MGN_MCS3:              ret = DESC_RATEMCS3;        break;
237                 case MGN_MCS4:              ret = DESC_RATEMCS4;        break;
238                 case MGN_MCS5:              ret = DESC_RATEMCS5;        break;
239                 case MGN_MCS6:              ret = DESC_RATEMCS6;        break;
240                 case MGN_MCS7:              ret = DESC_RATEMCS7;        break;
241                 case MGN_MCS8:              ret = DESC_RATEMCS8;        break;
242                 case MGN_MCS9:              ret = DESC_RATEMCS9;        break;
243                 case MGN_MCS10:         ret = DESC_RATEMCS10;   break;
244                 case MGN_MCS11:         ret = DESC_RATEMCS11;   break;
245                 case MGN_MCS12:         ret = DESC_RATEMCS12;   break;
246                 case MGN_MCS13:         ret = DESC_RATEMCS13;   break;
247                 case MGN_MCS14:         ret = DESC_RATEMCS14;   break;
248                 case MGN_MCS15:         ret = DESC_RATEMCS15;   break;
249                 case MGN_MCS16:             ret = DESC_RATEMCS16;       break;
250                 case MGN_MCS17:             ret = DESC_RATEMCS17;       break;
251                 case MGN_MCS18:             ret = DESC_RATEMCS18;       break;
252                 case MGN_MCS19:             ret = DESC_RATEMCS19;       break;
253                 case MGN_MCS20:         ret = DESC_RATEMCS20;   break;
254                 case MGN_MCS21:         ret = DESC_RATEMCS21;   break;
255                 case MGN_MCS22:         ret = DESC_RATEMCS22;   break;
256                 case MGN_MCS23:         ret = DESC_RATEMCS23;   break;
257                 case MGN_MCS24:         ret = DESC_RATEMCS24;   break;
258                 case MGN_MCS25:         ret = DESC_RATEMCS25;   break;
259                 case MGN_MCS26:             ret = DESC_RATEMCS26;       break;
260                 case MGN_MCS27:             ret = DESC_RATEMCS27;       break;
261                 case MGN_MCS28:             ret = DESC_RATEMCS28;       break;
262                 case MGN_MCS29:             ret = DESC_RATEMCS29;       break;
263                 case MGN_MCS30:         ret = DESC_RATEMCS30;   break;
264                 case MGN_MCS31:         ret = DESC_RATEMCS31;   break;
265
266                 case MGN_VHT1SS_MCS0:   ret = DESC_RATEVHTSS1MCS0;      break;
267                 case MGN_VHT1SS_MCS1:   ret = DESC_RATEVHTSS1MCS1;      break;
268                 case MGN_VHT1SS_MCS2:   ret = DESC_RATEVHTSS1MCS2;      break;
269                 case MGN_VHT1SS_MCS3:   ret = DESC_RATEVHTSS1MCS3;      break;
270                 case MGN_VHT1SS_MCS4:   ret = DESC_RATEVHTSS1MCS4;      break;
271                 case MGN_VHT1SS_MCS5:   ret = DESC_RATEVHTSS1MCS5;      break;
272                 case MGN_VHT1SS_MCS6:   ret = DESC_RATEVHTSS1MCS6;      break;
273                 case MGN_VHT1SS_MCS7:   ret = DESC_RATEVHTSS1MCS7;      break;
274                 case MGN_VHT1SS_MCS8:   ret = DESC_RATEVHTSS1MCS8;      break;
275                 case MGN_VHT1SS_MCS9:   ret = DESC_RATEVHTSS1MCS9;      break;  
276                 case MGN_VHT2SS_MCS0:   ret = DESC_RATEVHTSS2MCS0;      break;
277                 case MGN_VHT2SS_MCS1:   ret = DESC_RATEVHTSS2MCS1;      break;
278                 case MGN_VHT2SS_MCS2:   ret = DESC_RATEVHTSS2MCS2;      break;
279                 case MGN_VHT2SS_MCS3:   ret = DESC_RATEVHTSS2MCS3;      break;
280                 case MGN_VHT2SS_MCS4:   ret = DESC_RATEVHTSS2MCS4;      break;
281                 case MGN_VHT2SS_MCS5:   ret = DESC_RATEVHTSS2MCS5;      break;
282                 case MGN_VHT2SS_MCS6:   ret = DESC_RATEVHTSS2MCS6;      break;
283                 case MGN_VHT2SS_MCS7:   ret = DESC_RATEVHTSS2MCS7;      break;
284                 case MGN_VHT2SS_MCS8:   ret = DESC_RATEVHTSS2MCS8;      break;
285                 case MGN_VHT2SS_MCS9:   ret = DESC_RATEVHTSS2MCS9;      break;  
286                 case MGN_VHT3SS_MCS0:   ret = DESC_RATEVHTSS3MCS0;      break;
287                 case MGN_VHT3SS_MCS1:   ret = DESC_RATEVHTSS3MCS1;      break;
288                 case MGN_VHT3SS_MCS2:   ret = DESC_RATEVHTSS3MCS2;      break;
289                 case MGN_VHT3SS_MCS3:   ret = DESC_RATEVHTSS3MCS3;      break;
290                 case MGN_VHT3SS_MCS4:   ret = DESC_RATEVHTSS3MCS4;      break;
291                 case MGN_VHT3SS_MCS5:   ret = DESC_RATEVHTSS3MCS5;      break;
292                 case MGN_VHT3SS_MCS6:   ret = DESC_RATEVHTSS3MCS6;      break;
293                 case MGN_VHT3SS_MCS7:   ret = DESC_RATEVHTSS3MCS7;      break;
294                 case MGN_VHT3SS_MCS8:   ret = DESC_RATEVHTSS3MCS8;      break;
295                 case MGN_VHT3SS_MCS9:   ret = DESC_RATEVHTSS3MCS9;      break;
296                 case MGN_VHT4SS_MCS0:   ret = DESC_RATEVHTSS4MCS0;      break;
297                 case MGN_VHT4SS_MCS1:   ret = DESC_RATEVHTSS4MCS1;      break;
298                 case MGN_VHT4SS_MCS2:   ret = DESC_RATEVHTSS4MCS2;      break;
299                 case MGN_VHT4SS_MCS3:   ret = DESC_RATEVHTSS4MCS3;      break;
300                 case MGN_VHT4SS_MCS4:   ret = DESC_RATEVHTSS4MCS4;      break;
301                 case MGN_VHT4SS_MCS5:   ret = DESC_RATEVHTSS4MCS5;      break;
302                 case MGN_VHT4SS_MCS6:   ret = DESC_RATEVHTSS4MCS6;      break;
303                 case MGN_VHT4SS_MCS7:   ret = DESC_RATEVHTSS4MCS7;      break;
304                 case MGN_VHT4SS_MCS8:   ret = DESC_RATEVHTSS4MCS8;      break;
305                 case MGN_VHT4SS_MCS9:   ret = DESC_RATEVHTSS4MCS9;      break;
306                 default:                break;
307         }
308
309         return ret;
310 }
311
312 u8      HwRateToMRate(u8 rate)
313 {
314         u8      ret_rate = MGN_1M;
315
316         switch(rate)
317         {
318         
319                 case DESC_RATE1M:                   ret_rate = MGN_1M;          break;
320                 case DESC_RATE2M:                   ret_rate = MGN_2M;          break;
321                 case DESC_RATE5_5M:             ret_rate = MGN_5_5M;    break;
322                 case DESC_RATE11M:                  ret_rate = MGN_11M;         break;
323                 case DESC_RATE6M:                   ret_rate = MGN_6M;          break;
324                 case DESC_RATE9M:                   ret_rate = MGN_9M;          break;
325                 case DESC_RATE12M:                  ret_rate = MGN_12M;         break;
326                 case DESC_RATE18M:                  ret_rate = MGN_18M;         break;
327                 case DESC_RATE24M:                  ret_rate = MGN_24M;         break;
328                 case DESC_RATE36M:                  ret_rate = MGN_36M;         break;
329                 case DESC_RATE48M:                  ret_rate = MGN_48M;         break;
330                 case DESC_RATE54M:                  ret_rate = MGN_54M;         break;                  
331                 case DESC_RATEMCS0:             ret_rate = MGN_MCS0;    break;
332                 case DESC_RATEMCS1:             ret_rate = MGN_MCS1;    break;
333                 case DESC_RATEMCS2:             ret_rate = MGN_MCS2;    break;
334                 case DESC_RATEMCS3:             ret_rate = MGN_MCS3;    break;
335                 case DESC_RATEMCS4:             ret_rate = MGN_MCS4;    break;
336                 case DESC_RATEMCS5:             ret_rate = MGN_MCS5;    break;
337                 case DESC_RATEMCS6:             ret_rate = MGN_MCS6;    break;
338                 case DESC_RATEMCS7:             ret_rate = MGN_MCS7;    break;
339                 case DESC_RATEMCS8:             ret_rate = MGN_MCS8;    break;
340                 case DESC_RATEMCS9:             ret_rate = MGN_MCS9;    break;
341                 case DESC_RATEMCS10:        ret_rate = MGN_MCS10;       break;
342                 case DESC_RATEMCS11:        ret_rate = MGN_MCS11;       break;
343                 case DESC_RATEMCS12:        ret_rate = MGN_MCS12;       break;
344                 case DESC_RATEMCS13:        ret_rate = MGN_MCS13;       break;
345                 case DESC_RATEMCS14:        ret_rate = MGN_MCS14;       break;
346                 case DESC_RATEMCS15:        ret_rate = MGN_MCS15;       break;
347                 case DESC_RATEMCS16:        ret_rate = MGN_MCS16;       break;
348                 case DESC_RATEMCS17:        ret_rate = MGN_MCS17;       break;
349                 case DESC_RATEMCS18:        ret_rate = MGN_MCS18;       break;
350                 case DESC_RATEMCS19:        ret_rate = MGN_MCS19;       break;
351                 case DESC_RATEMCS20:        ret_rate = MGN_MCS20;       break;
352                 case DESC_RATEMCS21:        ret_rate = MGN_MCS21;       break;
353                 case DESC_RATEMCS22:        ret_rate = MGN_MCS22;       break;
354                 case DESC_RATEMCS23:        ret_rate = MGN_MCS23;       break;
355                 case DESC_RATEMCS24:        ret_rate = MGN_MCS24;       break;
356                 case DESC_RATEMCS25:        ret_rate = MGN_MCS25;       break;
357                 case DESC_RATEMCS26:        ret_rate = MGN_MCS26;       break;
358                 case DESC_RATEMCS27:        ret_rate = MGN_MCS27;       break;
359                 case DESC_RATEMCS28:        ret_rate = MGN_MCS28;       break;
360                 case DESC_RATEMCS29:        ret_rate = MGN_MCS29;       break;
361                 case DESC_RATEMCS30:        ret_rate = MGN_MCS30;       break;
362                 case DESC_RATEMCS31:        ret_rate = MGN_MCS31;       break;
363                 case DESC_RATEVHTSS1MCS0:       ret_rate = MGN_VHT1SS_MCS0;             break;
364                 case DESC_RATEVHTSS1MCS1:       ret_rate = MGN_VHT1SS_MCS1;             break;
365                 case DESC_RATEVHTSS1MCS2:       ret_rate = MGN_VHT1SS_MCS2;             break;
366                 case DESC_RATEVHTSS1MCS3:       ret_rate = MGN_VHT1SS_MCS3;             break;
367                 case DESC_RATEVHTSS1MCS4:       ret_rate = MGN_VHT1SS_MCS4;             break;
368                 case DESC_RATEVHTSS1MCS5:       ret_rate = MGN_VHT1SS_MCS5;             break;
369                 case DESC_RATEVHTSS1MCS6:       ret_rate = MGN_VHT1SS_MCS6;             break;
370                 case DESC_RATEVHTSS1MCS7:       ret_rate = MGN_VHT1SS_MCS7;             break;
371                 case DESC_RATEVHTSS1MCS8:       ret_rate = MGN_VHT1SS_MCS8;             break;
372                 case DESC_RATEVHTSS1MCS9:       ret_rate = MGN_VHT1SS_MCS9;             break;
373                 case DESC_RATEVHTSS2MCS0:       ret_rate = MGN_VHT2SS_MCS0;             break;
374                 case DESC_RATEVHTSS2MCS1:       ret_rate = MGN_VHT2SS_MCS1;             break;
375                 case DESC_RATEVHTSS2MCS2:       ret_rate = MGN_VHT2SS_MCS2;             break;
376                 case DESC_RATEVHTSS2MCS3:       ret_rate = MGN_VHT2SS_MCS3;             break;
377                 case DESC_RATEVHTSS2MCS4:       ret_rate = MGN_VHT2SS_MCS4;             break;
378                 case DESC_RATEVHTSS2MCS5:       ret_rate = MGN_VHT2SS_MCS5;             break;
379                 case DESC_RATEVHTSS2MCS6:       ret_rate = MGN_VHT2SS_MCS6;             break;
380                 case DESC_RATEVHTSS2MCS7:       ret_rate = MGN_VHT2SS_MCS7;             break;
381                 case DESC_RATEVHTSS2MCS8:       ret_rate = MGN_VHT2SS_MCS8;             break;
382                 case DESC_RATEVHTSS2MCS9:       ret_rate = MGN_VHT2SS_MCS9;             break;                          
383                 case DESC_RATEVHTSS3MCS0:       ret_rate = MGN_VHT3SS_MCS0;             break;
384                 case DESC_RATEVHTSS3MCS1:       ret_rate = MGN_VHT3SS_MCS1;             break;
385                 case DESC_RATEVHTSS3MCS2:       ret_rate = MGN_VHT3SS_MCS2;             break;
386                 case DESC_RATEVHTSS3MCS3:       ret_rate = MGN_VHT3SS_MCS3;             break;
387                 case DESC_RATEVHTSS3MCS4:       ret_rate = MGN_VHT3SS_MCS4;             break;
388                 case DESC_RATEVHTSS3MCS5:       ret_rate = MGN_VHT3SS_MCS5;             break;
389                 case DESC_RATEVHTSS3MCS6:       ret_rate = MGN_VHT3SS_MCS6;             break;
390                 case DESC_RATEVHTSS3MCS7:       ret_rate = MGN_VHT3SS_MCS7;             break;
391                 case DESC_RATEVHTSS3MCS8:       ret_rate = MGN_VHT3SS_MCS8;             break;
392                 case DESC_RATEVHTSS3MCS9:       ret_rate = MGN_VHT3SS_MCS9;             break;                          
393                 case DESC_RATEVHTSS4MCS0:       ret_rate = MGN_VHT4SS_MCS0;             break;
394                 case DESC_RATEVHTSS4MCS1:       ret_rate = MGN_VHT4SS_MCS1;             break;
395                 case DESC_RATEVHTSS4MCS2:       ret_rate = MGN_VHT4SS_MCS2;             break;
396                 case DESC_RATEVHTSS4MCS3:       ret_rate = MGN_VHT4SS_MCS3;             break;
397                 case DESC_RATEVHTSS4MCS4:       ret_rate = MGN_VHT4SS_MCS4;             break;
398                 case DESC_RATEVHTSS4MCS5:       ret_rate = MGN_VHT4SS_MCS5;             break;
399                 case DESC_RATEVHTSS4MCS6:       ret_rate = MGN_VHT4SS_MCS6;             break;
400                 case DESC_RATEVHTSS4MCS7:       ret_rate = MGN_VHT4SS_MCS7;             break;
401                 case DESC_RATEVHTSS4MCS8:       ret_rate = MGN_VHT4SS_MCS8;             break;
402                 case DESC_RATEVHTSS4MCS9:       ret_rate = MGN_VHT4SS_MCS9;             break;                          
403                 
404                 default:                                                        
405                         DBG_871X("HwRateToMRate(): Non supported Rate [%x]!!!\n",rate );
406                         break;
407         }
408
409         return ret_rate;
410 }
411
412 void    HalSetBrateCfg(
413         IN PADAPTER             Adapter,
414         IN u8                   *mBratesOS,
415         OUT u16                 *pBrateCfg)
416 {
417         u8      i, is_brate, brate;
418
419         for(i=0;i<NDIS_802_11_LENGTH_RATES_EX;i++)
420         {
421                 is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
422                 brate = mBratesOS[i] & 0x7f;
423                 
424                 if( is_brate )
425                 {               
426                         switch(brate)
427                         {
428                                 case IEEE80211_CCK_RATE_1MB:    *pBrateCfg |= RATE_1M;  break;
429                                 case IEEE80211_CCK_RATE_2MB:    *pBrateCfg |= RATE_2M;  break;
430                                 case IEEE80211_CCK_RATE_5MB:    *pBrateCfg |= RATE_5_5M;break;
431                                 case IEEE80211_CCK_RATE_11MB:   *pBrateCfg |= RATE_11M; break;
432                                 case IEEE80211_OFDM_RATE_6MB:   *pBrateCfg |= RATE_6M;  break;
433                                 case IEEE80211_OFDM_RATE_9MB:   *pBrateCfg |= RATE_9M;  break;
434                                 case IEEE80211_OFDM_RATE_12MB:  *pBrateCfg |= RATE_12M; break;
435                                 case IEEE80211_OFDM_RATE_18MB:  *pBrateCfg |= RATE_18M; break;
436                                 case IEEE80211_OFDM_RATE_24MB:  *pBrateCfg |= RATE_24M; break;
437                                 case IEEE80211_OFDM_RATE_36MB:  *pBrateCfg |= RATE_36M; break;
438                                 case IEEE80211_OFDM_RATE_48MB:  *pBrateCfg |= RATE_48M; break;
439                                 case IEEE80211_OFDM_RATE_54MB:  *pBrateCfg |= RATE_54M; break;
440                         }
441                 }
442         }
443 }
444
445 static VOID
446 _OneOutPipeMapping(
447         IN      PADAPTER        pAdapter
448         )
449 {
450         struct dvobj_priv       *pdvobjpriv = adapter_to_dvobj(pAdapter);
451
452         pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO
453         pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];//VI
454         pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];//BE
455         pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];//BK
456         
457         pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN
458         pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT
459         pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH
460         pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD
461 }
462
463 static VOID
464 _TwoOutPipeMapping(
465         IN      PADAPTER        pAdapter,
466         IN      BOOLEAN         bWIFICfg
467         )
468 {
469         struct dvobj_priv       *pdvobjpriv = adapter_to_dvobj(pAdapter);
470
471         if(bWIFICfg){ //WMM
472                 
473                 //      BK,     BE,     VI,     VO,     BCN,    CMD,MGT,HIGH,HCCA 
474                 //{  0,         1,      0,      1,      0,      0,      0,      0,              0       };
475                 //0:ep_0 num, 1:ep_1 num 
476                 
477                 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];//VO
478                 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];//VI
479                 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];//BE
480                 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];//BK
481                 
482                 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN
483                 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT
484                 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH
485                 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD
486                 
487         }
488         else{//typical setting
489
490                 
491                 //BK,   BE,     VI,     VO,     BCN,    CMD,MGT,HIGH,HCCA 
492                 //{  1,         1,      0,      0,      0,      0,      0,      0,              0       };                      
493                 //0:ep_0 num, 1:ep_1 num
494                 
495                 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO
496                 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];//VI
497                 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];//BE
498                 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];//BK
499                 
500                 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN
501                 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT
502                 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH
503                 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD    
504                 
505         }
506         
507 }
508
509 static VOID _ThreeOutPipeMapping(
510         IN      PADAPTER        pAdapter,
511         IN      BOOLEAN         bWIFICfg
512         )
513 {
514         struct dvobj_priv       *pdvobjpriv = adapter_to_dvobj(pAdapter);
515
516         if(bWIFICfg){//for WMM
517                 
518                 //      BK,     BE,     VI,     VO,     BCN,    CMD,MGT,HIGH,HCCA 
519                 //{  1,         2,      1,      0,      0,      0,      0,      0,              0       };
520                 //0:H, 1:N, 2:L 
521                 
522                 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO
523                 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];//VI
524                 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];//BE
525                 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];//BK
526                 
527                 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN
528                 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT
529                 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH
530                 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD
531                 
532         }
533         else{//typical setting
534
535                 
536                 //      BK,     BE,     VI,     VO,     BCN,    CMD,MGT,HIGH,HCCA 
537                 //{  2,         2,      1,      0,      0,      0,      0,      0,              0       };                      
538                 //0:H, 1:N, 2:L 
539                 
540                 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO
541                 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];//VI
542                 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];//BE
543                 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];//BK
544                 
545                 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN
546                 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT
547                 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];//HIGH
548                 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD    
549         }
550
551 }
552 static VOID _FourOutPipeMapping(
553         IN      PADAPTER        pAdapter,
554         IN      BOOLEAN         bWIFICfg
555         )
556 {
557         struct dvobj_priv       *pdvobjpriv = adapter_to_dvobj(pAdapter);
558
559         if(bWIFICfg){//for WMM
560                 
561                 //      BK,     BE,     VI,     VO,     BCN,    CMD,MGT,HIGH,HCCA 
562                 //{  1,         2,      1,      0,      0,      0,      0,      0,              0       };
563                 //0:H, 1:N, 2:L ,3:E
564                 
565                 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO
566                 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];//VI
567                 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];//BE
568                 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];//BK
569                 
570                 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN
571                 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT
572                 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];//HIGH
573                 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD
574                 
575         }
576         else{//typical setting
577
578                 
579                 //      BK,     BE,     VI,     VO,     BCN,    CMD,MGT,HIGH,HCCA 
580                 //{  2,         2,      1,      0,      0,      0,      0,      0,              0       };                      
581                 //0:H, 1:N, 2:L 
582                 
583                 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];//VO
584                 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];//VI
585                 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];//BE
586                 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];//BK
587                 
588                 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];//BCN
589                 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];//MGT
590                 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];//HIGH
591                 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];//TXCMD    
592         }
593
594 }
595 BOOLEAN
596 Hal_MappingOutPipe(
597         IN      PADAPTER        pAdapter,
598         IN      u8              NumOutPipe
599         )
600 {
601         struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
602
603         BOOLEAN  bWIFICfg = (pregistrypriv->wifi_spec) ?_TRUE:_FALSE;
604         
605         BOOLEAN result = _TRUE;
606
607         switch(NumOutPipe)
608         {
609                 case 2:
610                         _TwoOutPipeMapping(pAdapter, bWIFICfg);
611                         break;
612                 case 3:
613                 case 4:
614                         _ThreeOutPipeMapping(pAdapter, bWIFICfg);
615                         break;                  
616                 case 1:
617                         _OneOutPipeMapping(pAdapter);
618                         break;
619                 default:
620                         result = _FALSE;
621                         break;
622         }
623
624         return result;
625         
626 }
627
628 void hal_init_macaddr(_adapter *adapter)
629 {
630         rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, adapter->eeprompriv.mac_addr);
631 #ifdef  CONFIG_CONCURRENT_MODE
632         if (adapter->pbuddy_adapter)
633                 rtw_hal_set_hwreg(adapter->pbuddy_adapter, HW_VAR_MAC_ADDR, adapter->pbuddy_adapter->eeprompriv.mac_addr);
634 #endif
635 }
636
637 void rtw_init_hal_com_default_value(PADAPTER Adapter)
638 {
639         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(Adapter);
640
641         pHalData->AntDetection = 1;
642 }
643
644 /* 
645 * C2H event format:
646 * Field  TRIGGER                CONTENT    CMD_SEQ      CMD_LEN          CMD_ID
647 * BITS   [127:120]      [119:16]      [15:8]              [7:4]            [3:0]
648 */
649
650 void c2h_evt_clear(_adapter *adapter)
651 {
652         rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
653 }
654
655 s32 c2h_evt_read(_adapter *adapter, u8 *buf)
656 {
657         s32 ret = _FAIL;
658         struct c2h_evt_hdr *c2h_evt;
659         int i;
660         u8 trigger;
661
662         if (buf == NULL)
663                 goto exit;
664
665 #if defined(CONFIG_RTL8192C) || defined(CONFIG_RTL8192D) || defined(CONFIG_RTL8723A) || defined (CONFIG_RTL8188E)
666
667         trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
668
669         if (trigger == C2H_EVT_HOST_CLOSE) {
670                 goto exit; /* Not ready */
671         } else if (trigger != C2H_EVT_FW_CLOSE) {
672                 goto clear_evt; /* Not a valid value */
673         }
674
675         c2h_evt = (struct c2h_evt_hdr *)buf;
676
677         _rtw_memset(c2h_evt, 0, 16);
678
679         *buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
680         *(buf+1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);       
681
682         RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): ",
683                 &c2h_evt , sizeof(c2h_evt));
684
685         if (0) {
686                 DBG_871X("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n", __func__
687                         , c2h_evt->id, c2h_evt->plen, c2h_evt->seq, trigger);
688         }
689
690         /* Read the content */
691         for (i = 0; i < c2h_evt->plen; i++)
692                 c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + sizeof(*c2h_evt) + i);
693
694         RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): Command Content:\n",
695                 c2h_evt->payload, c2h_evt->plen);
696
697         ret = _SUCCESS;
698
699 clear_evt:
700         /* 
701         * Clear event to notify FW we have read the command.
702         * If this field isn't clear, the FW won't update the next command message.
703         */
704         c2h_evt_clear(adapter);
705 #endif
706 exit:
707         return ret;
708 }
709
710 /* 
711 * C2H event format:
712 * Field    TRIGGER    CMD_LEN    CONTENT    CMD_SEQ    CMD_ID
713 * BITS    [127:120]   [119:112]    [111:16]          [15:8]         [7:0]
714 */
715 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
716 {
717         s32 ret = _FAIL;
718         struct c2h_evt_hdr_88xx *c2h_evt;
719         int i;
720         u8 trigger;
721
722         if (buf == NULL)
723                 goto exit;
724
725 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8723B)
726
727         trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
728
729         if (trigger == C2H_EVT_HOST_CLOSE) {
730                 goto exit; /* Not ready */
731         } else if (trigger != C2H_EVT_FW_CLOSE) {
732                 goto clear_evt; /* Not a valid value */
733         }
734
735         c2h_evt = (struct c2h_evt_hdr_88xx *)buf;
736
737         _rtw_memset(c2h_evt, 0, 16);
738
739         c2h_evt->id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
740         c2h_evt->seq = rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX);
741         c2h_evt->plen = rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX);
742
743         RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): ",
744                 &c2h_evt , sizeof(c2h_evt));
745
746         if (0) {
747                 DBG_871X("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n", __func__
748                         , c2h_evt->id, c2h_evt->plen, c2h_evt->seq, trigger);
749         }
750
751         /* Read the content */
752         for (i = 0; i < c2h_evt->plen; i++)
753                 c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
754
755         RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): Command Content:\n",
756                 c2h_evt->payload, c2h_evt->plen);
757
758         ret = _SUCCESS;
759
760 clear_evt:
761         /* 
762         * Clear event to notify FW we have read the command.
763         * If this field isn't clear, the FW won't update the next command message.
764         */
765         c2h_evt_clear(adapter);
766 #endif
767 exit:
768         return ret;
769 }
770
771
772 u8  rtw_hal_networktype_to_raid(_adapter *adapter, struct sta_info *psta)
773 {
774         if(IS_NEW_GENERATION_IC(adapter)){
775                 return networktype_to_raid_ex(adapter,psta);
776         }
777         else{
778                 return networktype_to_raid(adapter,psta);
779         }
780
781 }
782 u8 rtw_get_mgntframe_raid(_adapter *adapter,unsigned char network_type)
783 {       
784
785         u8 raid;
786         if(IS_NEW_GENERATION_IC(adapter)){
787                 
788                 raid = (network_type & WIRELESS_11B)    ?RATEID_IDX_B
789                                                                                         :RATEID_IDX_G;          
790         }
791         else{
792                 raid = (network_type & WIRELESS_11B)    ?RATR_INX_WIRELESS_B
793                                                                                         :RATR_INX_WIRELESS_G;           
794         }       
795         return raid;
796 }
797
798 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
799 {
800         u8      i, rf_type, limit;
801         u32     tx_ra_bitmap;
802
803         if(psta == NULL)
804         {
805                 return;
806         }
807
808         tx_ra_bitmap = 0;
809
810         //b/g mode ra_bitmap  
811         for (i=0; i<sizeof(psta->bssrateset); i++)
812         {
813                 if (psta->bssrateset[i])
814                         tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
815         }
816
817 #ifdef CONFIG_80211N_HT
818 #ifdef CONFIG_80211AC_VHT
819         //AC mode ra_bitmap
820         if(psta->vhtpriv.vht_option) 
821         {
822                 tx_ra_bitmap |= (rtw_vht_rate_to_bitmap(psta->vhtpriv.vht_mcs_map) << 12);
823         }
824         else
825 #endif //CONFIG_80211AC_VHT
826         {
827                 //n mode ra_bitmap
828                 if(psta->htpriv.ht_option) 
829                 {
830                         rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
831                         if(rf_type == RF_2T2R)
832                                 limit=16;// 2R
833                         else
834                                 limit=8;//  1R
835
836                         for (i=0; i<limit; i++) {
837                                 if (psta->htpriv.ht_cap.supp_mcs_set[i/8] & BIT(i%8))
838                                         tx_ra_bitmap |= BIT(i+12);
839                         }
840                 }
841         }
842 #endif //CONFIG_80211N_HT
843
844         psta->ra_mask = tx_ra_bitmap;
845         psta->init_rate = get_highest_rate_idx(tx_ra_bitmap)&0x3f;
846 }
847
848 void hw_var_port_switch(_adapter *adapter)
849 {
850 #ifdef CONFIG_CONCURRENT_MODE
851 #ifdef CONFIG_RUNTIME_PORT_SWITCH
852 /*
853 0x102: MSR
854 0x550: REG_BCN_CTRL
855 0x551: REG_BCN_CTRL_1
856 0x55A: REG_ATIMWND
857 0x560: REG_TSFTR
858 0x568: REG_TSFTR1
859 0x570: REG_ATIMWND_1
860 0x610: REG_MACID
861 0x618: REG_BSSID
862 0x700: REG_MACID1
863 0x708: REG_BSSID1
864 */
865
866         int i;
867         u8 msr;
868         u8 bcn_ctrl;
869         u8 bcn_ctrl_1;
870         u8 atimwnd[2];
871         u8 atimwnd_1[2];
872         u8 tsftr[8];
873         u8 tsftr_1[8];
874         u8 macid[6];
875         u8 bssid[6];
876         u8 macid_1[6];
877         u8 bssid_1[6];
878
879         u8 iface_type;
880
881         msr = rtw_read8(adapter, MSR);
882         bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
883         bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
884
885         for (i=0; i<2; i++)
886                 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND+i);
887         for (i=0; i<2; i++)
888                 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1+i);
889
890         for (i=0; i<8; i++)
891                 tsftr[i] = rtw_read8(adapter, REG_TSFTR+i);
892         for (i=0; i<8; i++)
893                 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1+i);
894
895         for (i=0; i<6; i++)
896                 macid[i] = rtw_read8(adapter, REG_MACID+i);
897
898         for (i=0; i<6; i++)
899                 bssid[i] = rtw_read8(adapter, REG_BSSID+i);
900
901         for (i=0; i<6; i++)
902                 macid_1[i] = rtw_read8(adapter, REG_MACID1+i);
903
904         for (i=0; i<6; i++)
905                 bssid_1[i] = rtw_read8(adapter, REG_BSSID1+i);
906
907 #ifdef DBG_RUNTIME_PORT_SWITCH
908         DBG_871X(FUNC_ADPT_FMT" before switch\n"
909                 "msr:0x%02x\n"
910                 "bcn_ctrl:0x%02x\n"
911                 "bcn_ctrl_1:0x%02x\n"
912                 "atimwnd:0x%04x\n"
913                 "atimwnd_1:0x%04x\n"
914                 "tsftr:%llu\n"
915                 "tsftr1:%llu\n"
916                 "macid:"MAC_FMT"\n"
917                 "bssid:"MAC_FMT"\n"
918                 "macid_1:"MAC_FMT"\n"
919                 "bssid_1:"MAC_FMT"\n"
920                 , FUNC_ADPT_ARG(adapter)
921                 , msr
922                 , bcn_ctrl
923                 , bcn_ctrl_1
924                 , *((u16*)atimwnd)
925                 , *((u16*)atimwnd_1)
926                 , *((u64*)tsftr)
927                 , *((u64*)tsftr_1)
928                 , MAC_ARG(macid)
929                 , MAC_ARG(bssid)
930                 , MAC_ARG(macid_1)
931                 , MAC_ARG(bssid_1)
932         );
933 #endif /* DBG_RUNTIME_PORT_SWITCH */
934
935         /* disable bcn function, disable update TSF  */
936         rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
937         rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
938
939         /* switch msr */
940         msr = (msr&0xf0) |((msr&0x03) << 2) | ((msr&0x0c) >> 2);
941         rtw_write8(adapter, MSR, msr);
942
943         /* write port0 */
944         rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
945         for (i=0; i<2; i++)
946                 rtw_write8(adapter, REG_ATIMWND+i, atimwnd_1[i]);
947         for (i=0; i<8; i++)
948                 rtw_write8(adapter, REG_TSFTR+i, tsftr_1[i]);
949         for (i=0; i<6; i++)
950                 rtw_write8(adapter, REG_MACID+i, macid_1[i]);
951         for (i=0; i<6; i++)
952                 rtw_write8(adapter, REG_BSSID+i, bssid_1[i]);
953
954         /* write port1 */
955         rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
956         for (i=0; i<2; i++)
957                 rtw_write8(adapter, REG_ATIMWND_1+1, atimwnd[i]);
958         for (i=0; i<8; i++)
959                 rtw_write8(adapter, REG_TSFTR1+i, tsftr[i]);
960         for (i=0; i<6; i++)
961                 rtw_write8(adapter, REG_MACID1+i, macid[i]);
962         for (i=0; i<6; i++)
963                 rtw_write8(adapter, REG_BSSID1+i, bssid[i]);
964
965         /* write bcn ctl */
966 #ifdef CONFIG_BT_COEXIST
967 #if defined(CONFIG_RTL8723A) || defined(CONFIG_RTL8723B)
968         // always enable port0 beacon function for PSTDMA
969         bcn_ctrl_1 |= EN_BCN_FUNCTION;
970         // always disable port1 beacon function for PSTDMA
971         bcn_ctrl &= ~EN_BCN_FUNCTION;
972 #endif
973 #endif
974         rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
975         rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
976
977         if (adapter->iface_type == IFACE_PORT0) {
978                 adapter->iface_type = IFACE_PORT1;
979                 adapter->pbuddy_adapter->iface_type = IFACE_PORT0;
980                 DBG_871X_LEVEL(_drv_always_, "port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
981                         ADPT_ARG(adapter->pbuddy_adapter), ADPT_ARG(adapter));
982         } else {
983                 adapter->iface_type = IFACE_PORT0;
984                 adapter->pbuddy_adapter->iface_type = IFACE_PORT1;
985                 DBG_871X_LEVEL(_drv_always_, "port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
986                         ADPT_ARG(adapter), ADPT_ARG(adapter->pbuddy_adapter));
987         }
988
989 #ifdef DBG_RUNTIME_PORT_SWITCH
990         msr = rtw_read8(adapter, MSR);
991         bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
992         bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
993
994         for (i=0; i<2; i++)
995                 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND+i);
996         for (i=0; i<2; i++)
997                 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1+i);
998
999         for (i=0; i<8; i++)
1000                 tsftr[i] = rtw_read8(adapter, REG_TSFTR+i);
1001         for (i=0; i<8; i++)
1002                 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1+i);
1003
1004         for (i=0; i<6; i++)
1005                 macid[i] = rtw_read8(adapter, REG_MACID+i);
1006
1007         for (i=0; i<6; i++)
1008                 bssid[i] = rtw_read8(adapter, REG_BSSID+i);
1009
1010         for (i=0; i<6; i++)
1011                 macid_1[i] = rtw_read8(adapter, REG_MACID1+i);
1012
1013         for (i=0; i<6; i++)
1014                 bssid_1[i] = rtw_read8(adapter, REG_BSSID1+i);
1015
1016         DBG_871X(FUNC_ADPT_FMT" after switch\n"
1017                 "msr:0x%02x\n"
1018                 "bcn_ctrl:0x%02x\n"
1019                 "bcn_ctrl_1:0x%02x\n"
1020                 "atimwnd:%u\n"
1021                 "atimwnd_1:%u\n"
1022                 "tsftr:%llu\n"
1023                 "tsftr1:%llu\n"
1024                 "macid:"MAC_FMT"\n"
1025                 "bssid:"MAC_FMT"\n"
1026                 "macid_1:"MAC_FMT"\n"
1027                 "bssid_1:"MAC_FMT"\n"
1028                 , FUNC_ADPT_ARG(adapter)
1029                 , msr
1030                 , bcn_ctrl
1031                 , bcn_ctrl_1
1032                 , *((u16*)atimwnd)
1033                 , *((u16*)atimwnd_1)
1034                 , *((u64*)tsftr)
1035                 , *((u64*)tsftr_1)
1036                 , MAC_ARG(macid)
1037                 , MAC_ARG(bssid)
1038                 , MAC_ARG(macid_1)
1039                 , MAC_ARG(bssid_1)
1040         );
1041 #endif /* DBG_RUNTIME_PORT_SWITCH */
1042
1043 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
1044 #endif /* CONFIG_CONCURRENT_MODE */
1045 }
1046
1047 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
1048 {
1049         struct  hal_ops *pHalFunc = &padapter->HalFunc;
1050         u8      u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN]={0};
1051         u8      ret = 0;
1052
1053         DBG_871X("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
1054                 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
1055                 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
1056                 rsvdpageloc->LocBTQosNull);
1057
1058         SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
1059         SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
1060         SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
1061         SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
1062         SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
1063
1064         if (pHalFunc->fill_h2c_cmd != NULL) {
1065                 ret = pHalFunc->fill_h2c_cmd(padapter,
1066                                 H2C_RSVD_PAGE,
1067                                 H2C_RSVDPAGE_LOC_LEN,
1068                                 u1H2CRsvdPageParm);
1069         } else {
1070                 DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
1071                 ret = _FAIL;
1072         }
1073 }
1074
1075 #ifdef CONFIG_GPIO_WAKEUP
1076 static void rtw_hal_set_output_gpio(_adapter* padapter, u8 index, u8 outputval)
1077 {
1078         u8 val8;
1079
1080
1081         if ( index <= 7 ) {
1082                 /* config GPIO mode */
1083                 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
1084                                 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index) );
1085
1086                 /* config GPIO Sel */
1087                 /* 0: input */
1088                 /* 1: output */
1089                 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
1090                                 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
1091
1092                 /* set output value */
1093                 if ( outputval ) {
1094                         rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
1095                                         rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
1096                 } else {
1097                         rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
1098                                         rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
1099                 }
1100         } else if (index <= 15) {
1101                 /* 88C Series: */
1102                 /* index: 11~8 transform to 3~0 */
1103                 /* 8723 Series: */
1104                 /* index: 12~8 transform to 4~0 */
1105 #ifdef CONFIG_RTL8723B
1106                 if ((index == 13) || (index == 14)) {
1107                         // Set BIT_GPIO13_14_WL_CTRL_EN to 0
1108                         val8 = rtw_read8(padapter, 0x4e);
1109                         if (val8 & BIT(6)) {
1110                                 val8 &= ~BIT(6);
1111                                 rtw_write8(padapter, 0x4e, val8);
1112                                 DBG_871X("%s: set GPIO%d to WL control, 0x4E=0x%02X\n",
1113                                         __FUNCTION__, index, rtw_read8(padapter, 0x4e));
1114                         }
1115                 }
1116 #endif // CONFIG_RTL8723B
1117
1118                 index -= 8;
1119
1120                 /* config GPIO mode */
1121                 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
1122                                 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index) );
1123
1124                 /* config GPIO Sel */
1125                 /* 0: input */
1126                 /* 1: output */
1127                 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
1128                                 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
1129
1130                 /* set output value */
1131                 if ( outputval ) {
1132                         rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
1133                                         rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
1134                 } else {
1135                         rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
1136                                         rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
1137                 }
1138         } else {
1139                 DBG_871X("%s: invalid GPIO%d=%d\n", __FUNCTION__, index, outputval);
1140         }
1141 }
1142
1143 /*
1144  * Set GPIO high/low under init and
1145  * fw will trigger Low/High Pulse when need to wake up host
1146  */
1147 void rtw_clear_hostwakeupgpio(PADAPTER padapter)
1148 {
1149         u8 high = 0;
1150
1151
1152 #ifdef CONFIG_GPIO_WAKEUP_LOW_ACTIVE
1153         high = 1;
1154 #endif // CONFIG_GPIO_WAKEUP_LOW_ACTIVE
1155         DBG_871X("%s: Set GPIO%d to %s for wake\n",
1156                 __FUNCTION__, WAKEUP_GPIO_IDX, high?"high":"low");
1157         rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, high);
1158 }
1159 #endif
1160
1161 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
1162 {
1163         struct  hal_ops *pHalFunc = &padapter->HalFunc;
1164         struct  pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1165         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
1166         u8      res = 0, count = 0, ret = 0;
1167 #ifdef CONFIG_WOWLAN    
1168         u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN]={0};
1169
1170         DBG_871X("AOACRsvdPageLoc: RWC=%d ArpRsp=%d NbrAdv=%d GtkRsp=%d GtkInfo=%d ProbeReq=%d NetworkList=%d\n",
1171                         rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp,
1172                         rsvdpageloc->LocNbrAdv, rsvdpageloc->LocGTKRsp,
1173                         rsvdpageloc->LocGTKInfo, rsvdpageloc->LocProbeReq,
1174                         rsvdpageloc->LocNetList);
1175
1176         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1177                 SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
1178                 SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
1179                 //SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm, rsvdpageloc->LocNbrAdv);
1180                 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
1181                 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
1182 #ifdef CONFIG_GTK_OL
1183                 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
1184 #endif // CONFIG_GTK_OL
1185                 if (pHalFunc->fill_h2c_cmd != NULL) {
1186                         ret = pHalFunc->fill_h2c_cmd(padapter,
1187                                         H2C_AOAC_RSVD_PAGE,
1188                                         H2C_AOAC_RSVDPAGE_LOC_LEN,
1189                                         u1H2CAoacRsvdPageParm);
1190                 } else {
1191                         DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
1192                         ret = _FAIL;
1193                 }
1194         }
1195 #ifdef CONFIG_PNO_SUPPORT
1196         else
1197         {
1198
1199                 if(!pwrpriv->pno_in_resume) {
1200                         DBG_871X("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
1201                         _rtw_memset(&u1H2CAoacRsvdPageParm, 0,
1202                                         sizeof(u1H2CAoacRsvdPageParm));
1203                         SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
1204                                         rsvdpageloc->LocPNOInfo);
1205                         if (pHalFunc->fill_h2c_cmd != NULL) {
1206                                 ret = pHalFunc->fill_h2c_cmd(padapter,
1207                                                 H2C_AOAC_RSVDPAGE3,
1208                                                 H2C_AOAC_RSVDPAGE_LOC_LEN,
1209                                                 u1H2CAoacRsvdPageParm);
1210                         } else {
1211                                 DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
1212                                 ret = _FAIL;
1213                         }
1214                 }
1215         }
1216 #endif //CONFIG_PNO_SUPPORT
1217 #endif // CONFIG_WOWLAN
1218 }
1219
1220 #ifdef CONFIG_WOWLAN
1221 // rtw_hal_check_wow_ctrl
1222 // chk_type: _TRUE means to check enable, if 0x690 & bit1, WOW enable successful
1223 //           _FALSE means to check disable, if 0x690 & bit1, WOW disable fail
1224 static u8 rtw_hal_check_wow_ctrl(_adapter* adapter, u8 chk_type)
1225 {
1226         u8 mstatus = 0;
1227         u8 trycnt = 25;
1228         u8 res = _FALSE;
1229
1230         mstatus = rtw_read8(adapter, REG_WOW_CTRL);
1231         DBG_871X_LEVEL(_drv_info_, "%s mstatus:0x%02x\n", __func__, mstatus);
1232
1233         if (chk_type) {
1234                 while(!(mstatus&BIT1) && trycnt>1) {
1235                         mstatus = rtw_read8(adapter, REG_WOW_CTRL);
1236                         DBG_871X_LEVEL(_drv_always_,
1237                                         "Loop index: %d :0x%02x\n",
1238                                         trycnt, mstatus);
1239                         trycnt --;
1240                         rtw_msleep_os(2);
1241                 }
1242                 if (mstatus & BIT1)
1243                         res = _TRUE;
1244                 else
1245                         res = _FALSE;
1246         } else {
1247                 while (mstatus&BIT1 && trycnt>1) {
1248                         mstatus = rtw_read8(adapter, REG_WOW_CTRL);
1249                         DBG_871X_LEVEL(_drv_always_,
1250                                         "Loop index: %d :0x%02x\n",
1251                                         trycnt, mstatus);
1252                         trycnt --;
1253                         rtw_msleep_os(2);
1254                 }
1255
1256                 if (mstatus & BIT1)
1257                         res = _FALSE;
1258                 else
1259                         res = _TRUE;
1260         }
1261         DBG_871X_LEVEL(_drv_always_, "%s check_type: %d res: %d trycnt: %d\n",
1262                         __func__, chk_type, res, (25 - trycnt));
1263         return res;
1264 }
1265
1266 #ifdef CONFIG_PNO_SUPPORT
1267 static u8 rtw_hal_check_pno_enabled(_adapter* adapter)
1268 {
1269         struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
1270         u8 res = 0, count = 0;
1271         u8 ret = _FALSE;
1272         if (ppwrpriv->wowlan_pno_enable && ppwrpriv->pno_in_resume == _FALSE) {
1273                 res = rtw_read8(adapter, REG_PNO_STATUS);
1274                 while(!(res&BIT(7)) && count < 25) {
1275                         DBG_871X("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
1276                                         count, res);
1277                         res = rtw_read8(adapter, REG_PNO_STATUS);
1278                         count++;
1279                         rtw_msleep_os(2);
1280                 }
1281                 if (res & BIT(7))
1282                         ret = _TRUE;
1283                 else
1284                         ret = _FALSE;
1285                 DBG_871X("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
1286         }
1287         return ret;
1288 }
1289 #endif
1290
1291 static void rtw_hal_force_enable_rxdma(_adapter* adapter)
1292 {
1293         DBG_871X("%s: Set 0x690=0x00\n", __func__);
1294         rtw_write8(adapter, REG_WOW_CTRL,
1295                         (rtw_read8(adapter, REG_WOW_CTRL)&0xf0));
1296         DBG_871X_LEVEL(_drv_always_, "%s: Release RXDMA\n", __func__);
1297         rtw_write32(adapter, REG_RXPKT_NUM,
1298                         (rtw_read32(adapter,REG_RXPKT_NUM)&(~RW_RELEASE_EN)));
1299 }
1300
1301 static void rtw_hal_disable_tx_report(_adapter* adapter)
1302 {
1303         rtw_write8(adapter, REG_TX_RPT_CTRL,
1304                         ((rtw_read8(adapter, REG_TX_RPT_CTRL)&~BIT(1)))&~BIT(5));
1305         DBG_871X("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
1306 }
1307
1308 static void rtw_hal_enable_tx_report(_adapter* adapter)
1309 {
1310         rtw_write8(adapter, REG_TX_RPT_CTRL,
1311                         ((rtw_read8(adapter, REG_TX_RPT_CTRL)|BIT(1)))|BIT(5));
1312         DBG_871X("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
1313 }
1314
1315 void rtw_hal_fill_fake_txdesc(_adapter* padapter, u8* pDesc, u32 BufferLen,
1316                 u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame)
1317 {
1318
1319         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1320         struct hal_ops *pHalFunc = &padapter->HalFunc;
1321         struct tx_desc *ptxdesc;
1322
1323         // Clear all status
1324         _rtw_memset(pDesc, 0, TXDESC_SIZE);
1325
1326         if (TXDESC_SIZE == 32) {
1327                 ptxdesc = (struct tx_desc*)pDesc;
1328                 //offset 0
1329                 //own, bFirstSeg, bLastSeg;
1330                 ptxdesc->txdw0 |=
1331                         cpu_to_le32( BIT(31) | BIT(27)| BIT(26));
1332
1333                 //32 bytes for TX Desc
1334                 ptxdesc->txdw0 |=
1335                         cpu_to_le32(((TXDESC_SIZE + 0) << 16)&0x00ff0000);
1336
1337                 // Buffer size + command header
1338                 ptxdesc->txdw0 |=
1339                         cpu_to_le32(BufferLen&0x0000ffff);
1340
1341                 //offset 4
1342                 // Fixed queue of Mgnt queue
1343                 ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT<< 8)&0x00001f00);
1344
1345                 //Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw.
1346                 if (IsPsPoll) {
1347                         ptxdesc->txdw1 |= cpu_to_le32(BIT(20));
1348                 } else {
1349                         // Hw set sequence number
1350                         ptxdesc->txdw4 |= cpu_to_le32(BIT(7));
1351                         //set bit3 to 1. Suugested by TimChen. 2009.12.29.
1352                         ptxdesc->txdw3 |= cpu_to_le32((8 <<28));
1353                 }
1354
1355                 if (_TRUE == IsBTQosNull) {
1356                         ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); // BT NULL
1357                 }
1358
1359                 //offset 16
1360                 //driver uses rate
1361                 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));
1362
1363         } else if (TXDESC_SIZE == 40) {
1364                 SET_TX_DESC_FIRST_SEG(pDesc, 1); //bFirstSeg;
1365                 SET_TX_DESC_LAST_SEG(pDesc, 1); //bLastSeg;
1366
1367                 SET_TX_DESC_OFFSET(pDesc, TXDESC_SIZE);
1368
1369                 SET_TX_DESC_PKT_SIZE(pDesc, BufferLen); // Buffer size + command header
1370
1371                 if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {
1372                         SET_TX_DESC_RATE_ID(pDesc, RATR_INX_WIRELESS_B);
1373                 } else {
1374                         SET_TX_DESC_RATE_ID(pDesc, RATR_INX_WIRELESS_G);
1375                 }
1376
1377                 SET_TX_DESC_QUEUE_SEL(pDesc, QSLT_MGNT); // Fixed queue of Mgnt queue
1378
1379                 // Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw.
1380                 if (_TRUE == IsPsPoll) {
1381                         SET_TX_DESC_NAV_USE_HDR(pDesc, 1);
1382                 } else {
1383                         SET_TX_DESC_HWSEQ_EN(pDesc, 1); // Hw set sequence number
1384                         SET_TX_DESC_HWSEQ_SEL(pDesc, 0);
1385                 }
1386
1387                 if (_TRUE ==IsBTQosNull) {
1388                         SET_TX_DESC_BT_INT(pDesc, 1);
1389                 }
1390
1391                 SET_TX_DESC_USE_RATE(pDesc, 1); // use data rate which is set by Sw
1392                 SET_TX_DESC_OWN((pu1Byte)pDesc, 1);
1393
1394                 SET_TX_DESC_TX_RATE(pDesc, MRateToHwRate(pmlmeext->tx_rate));
1395
1396         }
1397
1398         //
1399         // Encrypt the data frame if under security mode excepct null data.
1400         // Suggested by CCW.
1401         //
1402         if (_TRUE ==bDataFrame)
1403         {
1404                 u32 EncAlg;
1405
1406                 EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm;
1407                 switch (EncAlg)
1408                 {
1409                         case _NO_PRIVACY_:
1410                                 SET_TX_DESC_SEC_TYPE(pDesc, 0x0);
1411                                 break;
1412                         case _WEP40_:
1413                         case _WEP104_:
1414                         case _TKIP_:
1415                                 SET_TX_DESC_SEC_TYPE(pDesc, 0x1);
1416                                 break;
1417                         case _SMS4_:
1418                                 SET_TX_DESC_SEC_TYPE(pDesc, 0x2);
1419                                 break;
1420                         case _AES_:
1421                                 SET_TX_DESC_SEC_TYPE(pDesc, 0x3);
1422                                 break;
1423                         default:
1424                                 SET_TX_DESC_SEC_TYPE(pDesc, 0x0);
1425                                 break;
1426                 }
1427         }
1428
1429 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
1430         // USB interface drop packet if the checksum of descriptor isn't correct.
1431         // Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.).
1432         if(pHalFunc->hal_cal_txdesc_chksum != NULL)
1433 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8723A) ||defined(CONFIG_RTL8723B)
1434                 pHalFunc->hal_cal_txdesc_chksum((struct tx_desc*)pDesc);
1435 #else
1436                 pHalFunc->hal_cal_txdesc_chksum(pDesc);
1437 #endif //CONFIG_RTL8188E || CONFIG_RTL8723B
1438 #endif
1439 }
1440
1441 static void rtw_hal_backup_rate(_adapter* adapter)
1442 {
1443         DBG_871X("%s\n", __func__);
1444         //backup data rate to register 0x8b for wowlan FW
1445         rtw_write8(adapter, 0x8d, 1);
1446         rtw_write8(adapter, 0x8c, 0);
1447         rtw_write8(adapter, 0x8f, 0x40);
1448         rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
1449 }
1450
1451 static u8 rtw_hal_pause_rx_dma(_adapter* adapter)
1452 {
1453         u8 ret = 0;
1454         u8 trycnt = 100;
1455         u16 len = 0;
1456         u32 tmp = 0;
1457         int res = 0;
1458         //RX DMA stop
1459         DBG_871X_LEVEL(_drv_always_, "Pause DMA\n");
1460         rtw_write32(adapter, REG_RXPKT_NUM,
1461                         (rtw_read32(adapter,REG_RXPKT_NUM)|RW_RELEASE_EN));
1462         do{
1463                 if((rtw_read32(adapter, REG_RXPKT_NUM)&RXDMA_IDLE)) {
1464                         DBG_871X_LEVEL(_drv_always_, "RX_DMA_IDLE is true\n");
1465                         ret = _SUCCESS;
1466                         break;
1467                 }
1468 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
1469                 else {
1470                         // If RX_DMA is not idle, receive one pkt from DMA
1471                         res = sdio_local_read(adapter,
1472                                         SDIO_REG_RX0_REQ_LEN, 4, (u8*)&tmp);
1473                         len = le16_to_cpu(tmp);
1474                         DBG_871X_LEVEL(_drv_always_, "RX len:%d\n", len);
1475
1476                         if (len > 0)
1477                                 res = RecvOnePkt(adapter, len);
1478                         else
1479                                 DBG_871X_LEVEL(_drv_always_, "read length fail %d\n", len);
1480
1481                         DBG_871X_LEVEL(_drv_always_, "RecvOnePkt Result: %d\n", res);
1482                 }
1483 #endif //CONFIG_SDIO_HCI || CONFIG_GSPI_HCI
1484         }while(trycnt--);
1485
1486         if(trycnt ==0) {
1487                 DBG_871X_LEVEL(_drv_always_, "Stop RX DMA failed...... \n");
1488                 ret = _FAIL;
1489         }
1490
1491         return ret;
1492 }
1493
1494 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
1495 static u8 rtw_hal_enable_cpwm2(_adapter* adapter)
1496 {
1497         u8 ret = 0;
1498         int res = 0;
1499         u32 tmp = 0;
1500
1501         DBG_871X_LEVEL(_drv_always_, "%s\n", __func__);
1502
1503         res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8*)&tmp);
1504         if (!res)
1505                 DBG_871X_LEVEL(_drv_info_, "read SDIO_REG_HIMR: 0x%08x\n", tmp);
1506         else
1507                 DBG_871X_LEVEL(_drv_info_, "sdio_local_read fail\n");
1508
1509         tmp = SDIO_HIMR_CPWM2_MSK;
1510
1511         res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8*)&tmp);
1512
1513         if (!res){
1514                 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8*)&tmp);
1515                 DBG_871X_LEVEL(_drv_info_, "read again SDIO_REG_HIMR: 0x%08x\n", tmp);
1516                 ret = _SUCCESS;
1517         }else {
1518                 DBG_871X_LEVEL(_drv_info_, "sdio_local_write fail\n");
1519                 ret = _FAIL;
1520         }
1521
1522         return ret;
1523 }
1524 #endif //CONFIG_SDIO_HCI, CONFIG_GSPI_HCI
1525
1526 #ifdef CONFIG_GTK_OL
1527 static void rtw_hal_fw_sync_cam_id(_adapter* adapter)
1528 {
1529         struct security_priv *psecuritypriv = &adapter->securitypriv;
1530         u8 null_addr[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
1531         int cam_id;
1532         u32 algorithm = 0;
1533         u16 ctrl = 0;
1534         u8 *addr;
1535         u8 index = 0;
1536         u8 get_key[16];
1537
1538         addr = get_bssid(&adapter->mlmepriv);
1539
1540         if (addr == NULL) {
1541                 DBG_871X("%s: get bssid MAC addr fail!!\n", __func__);
1542                 return;
1543         }
1544
1545         do{
1546                 cam_id = rtw_camid_search(adapter, addr, index);
1547                 if (cam_id == -1) {
1548                         DBG_871X("%s: cam_id: %d, key_id:%d\n",
1549                                         __func__, cam_id, index);
1550                 } else if (rtw_camid_is_gk(adapter, cam_id) != _TRUE) {
1551                         DBG_871X("%s: cam_id: %d key_id(%d) is not GK\n",
1552                                         __func__, cam_id, index);
1553                 } else {
1554                         read_cam(adapter ,cam_id, get_key);
1555                         algorithm = psecuritypriv->dot11PrivacyAlgrthm;
1556                         ctrl = BIT(15) | BIT6 |(algorithm << 2) | index;
1557                         write_cam(adapter, index, ctrl, addr, get_key);
1558                         ctrl = 0;
1559                         write_cam(adapter, cam_id, ctrl, null_addr, get_key);
1560                 }
1561                 index++;
1562         }while(cam_id != -1);
1563
1564         rtw_write8(adapter, REG_SECCFG, 0xcc);
1565 }
1566
1567 static void rtw_hal_update_gtk_offload_info(_adapter* adapter)
1568 {
1569         struct security_priv *psecuritypriv = &adapter->securitypriv;
1570         int cam_id;
1571         u8 *addr;
1572         u8 null_addr[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
1573         u8 gtk_keyindex=0;
1574         u8 get_key[16];
1575         u8 null_key[16];
1576         u8 index = 0;
1577         u16 ctrl = 0;
1578         u32 algorithm = 0;
1579
1580         addr = get_bssid(&adapter->mlmepriv);
1581
1582         if (addr == NULL) {
1583                 DBG_871X("%s: get bssid MAC addr fail!!\n", __func__);
1584                 return;
1585         }
1586
1587         _rtw_memset(null_key, 0, sizeof(null_key));
1588
1589         algorithm = psecuritypriv->dot11PrivacyAlgrthm;
1590
1591         if(psecuritypriv->binstallKCK_KEK == _TRUE) {
1592                 //read gtk key index
1593                 gtk_keyindex = rtw_read8(adapter, 0x48c);
1594
1595                 do{
1596                         cam_id = rtw_camid_search(adapter, addr, index);
1597                         if (cam_id == -1) {
1598                                 DBG_871X("%s: cam_id: %d, key_id:%d\n",
1599                                                 __func__, cam_id, index);
1600                         } else if (read_phy_cam_is_gtk(adapter, cam_id) ==
1601                                         _FALSE){
1602                                 DBG_871X("%s: cam_id: %d, key_id:%d is not GK\n",
1603                                                 __func__, cam_id, index);
1604                         } else if (cam_id >= 4) {
1605                                 DBG_871X("%s: cam_id(%d) is not in default key\n",
1606                                                 __func__, cam_id);
1607                         } else {
1608                                 read_cam(adapter ,cam_id, get_key);
1609                                 algorithm = psecuritypriv->dot11PrivacyAlgrthm;
1610                                 ctrl = BIT(15) | BIT6 |(algorithm << 2) | index;
1611                                 write_cam(adapter, cam_id+4, ctrl,
1612                                                 addr, get_key);
1613                                 ctrl = 0;
1614                                 write_cam(adapter, cam_id, ctrl,
1615                                                 null_addr, get_key);
1616                         }
1617
1618                         if (gtk_keyindex < 4 &&(index == gtk_keyindex)) {
1619                                 psecuritypriv->dot118021XGrpKeyid = gtk_keyindex;
1620                                 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey,
1621                                                 get_key, 16);
1622
1623                                 DBG_871X_LEVEL(_drv_always_, "GTK (%d) = 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
1624                                                 gtk_keyindex,
1625                                 psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[0], 
1626                                 psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[1],
1627                                 psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[2],
1628                                 psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[3]);
1629                         }
1630                         index++;
1631                 }while(index < 4);
1632
1633                 rtw_write8(adapter, REG_SECCFG, 0x0c);
1634 #ifdef CONFIG_GTK_OL_DBG
1635                 //if (gtk_keyindex != 5)
1636                 dump_cam_table(adapter);
1637 #endif
1638         }
1639 }
1640 #endif
1641
1642 static void rtw_hal_update_tx_iv(_adapter* adapter)
1643 {
1644         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
1645         u64 iv_low = 0, iv_high = 0;
1646
1647         // 3.1 read fw iv
1648         iv_low = rtw_read32(adapter, REG_TXPKTBUF_IV_LOW);
1649         //only low two bytes is PN, check AES_IV macro for detail
1650         iv_low &= 0xffff;
1651         iv_high = rtw_read32(adapter, REG_TXPKTBUF_IV_HIGH);
1652         //get the real packet number
1653         pwrctl->wowlan_fw_iv = iv_high << 16 | iv_low;
1654         DBG_871X_LEVEL(_drv_always_,
1655                         "fw_iv: 0x%016llx\n", pwrctl->wowlan_fw_iv);
1656         //Update TX iv data.
1657         rtw_set_sec_pn(adapter);
1658 }
1659
1660 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
1661 {
1662         struct hal_ops *pHalFunc = &adapter->HalFunc;
1663
1664         u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN]={0};
1665         u8 adopt = 1, check_period = 5;
1666         u8 ret = _FAIL;
1667
1668         DBG_871X("%s(): enable = %d\n", __func__, enable);
1669         SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
1670         SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
1671         SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
1672         SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
1673
1674         if (pHalFunc->fill_h2c_cmd != NULL) {
1675                 ret = pHalFunc->fill_h2c_cmd(adapter,
1676                                 H2C_KEEP_ALIVE,
1677                                 H2C_KEEP_ALIVE_CTRL_LEN,
1678                                 u1H2CKeepAliveParm);
1679         } else {
1680                 DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
1681                 ret = _FAIL;
1682         }
1683
1684         return ret;
1685 }
1686
1687 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
1688 {
1689         struct hal_ops *pHalFunc = &adapter->HalFunc;
1690         u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN]={0};
1691         u8 adopt = 1, check_period = 10, trypkt_num = 0;
1692         u8 ret = _FAIL;
1693
1694         DBG_871X("%s(): enable = %d\n", __func__, enable);
1695         SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
1696         SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
1697         SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
1698         SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
1699
1700         if (pHalFunc->fill_h2c_cmd != NULL) {
1701                 ret = pHalFunc->fill_h2c_cmd(adapter,
1702                                 H2C_DISCON_DECISION,
1703                                 H2C_DISCON_DECISION_LEN,
1704                                 u1H2CDisconDecisionParm);
1705         } else {
1706                 DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
1707                 ret = _FAIL;
1708         }
1709
1710         return ret;
1711 }
1712
1713 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
1714 {
1715         struct hal_ops *pHalFunc = &adapter->HalFunc;
1716         u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN]={0};
1717         u8 ret = _FAIL;
1718
1719         DBG_871X("%s(): bFuncEn=%d\n", __func__, enable);
1720
1721         SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
1722
1723         if (pHalFunc->fill_h2c_cmd != NULL) {
1724                 ret = pHalFunc->fill_h2c_cmd(adapter,
1725                                 H2C_AP_OFFLOAD,
1726                                 H2C_AP_OFFLOAD_LEN,
1727                                 u1H2CAPOffloadCtrlParm);
1728         } else {
1729                 DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
1730                 ret = _FAIL;
1731         }
1732         return ret;
1733 }
1734
1735 static u8 rtw_hal_set_ap_rsvdpage_loc_cmd(_adapter *adapter,
1736                 PRSVDPAGE_LOC rsvdpageloc)
1737 {
1738         struct hal_ops *pHalFunc = &adapter->HalFunc;
1739         u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN]={0};
1740         u8 ret = _FAIL, header = 0;
1741
1742         if (pHalFunc->fill_h2c_cmd == NULL) {
1743                 DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
1744                 return ret;
1745         }
1746
1747         header = rtw_read8(adapter, REG_BCNQ_BDNY);
1748
1749         DBG_871X("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
1750                         rsvdpageloc->LocApOffloadBCN,
1751                         rsvdpageloc->LocProbeRsp,
1752                         header);
1753
1754         SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
1755                         rsvdpageloc->LocApOffloadBCN + header);
1756
1757         ret = pHalFunc->fill_h2c_cmd(adapter, H2C_BCN_RSVDPAGE,
1758                                 H2C_BCN_RSVDPAGE_LEN, rsvdparm);
1759
1760         if (ret == _FAIL)
1761                 DBG_871X("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
1762
1763         _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
1764
1765         SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
1766                         rsvdpageloc->LocProbeRsp + header);
1767
1768         ret = pHalFunc->fill_h2c_cmd(adapter, H2C_PROBERSP_RSVDPAGE,
1769                                 H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
1770
1771         if (ret == _FAIL)
1772                 DBG_871X("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
1773
1774         return ret;
1775 }
1776
1777 u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
1778 {
1779         struct security_priv *psecpriv = &adapter->securitypriv;
1780         struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
1781         struct hal_ops *pHalFunc = &adapter->HalFunc;
1782
1783         u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN]={0};
1784         u8 discont_wake = 1, gpionum = 0, gpio_dur = 0;
1785         u8 hw_unicast = 0, gpio_pulse_cnt = 0;
1786         u8 sdio_wakeup_enable = 1;
1787         u8 gpio_high_active = 0; //0: low active, 1: high active
1788         u8 magic_pkt = 0;
1789         u8 ret = _FAIL;
1790
1791 #ifdef CONFIG_GPIO_WAKEUP
1792         gpionum = WAKEUP_GPIO_IDX;
1793         sdio_wakeup_enable = 0;
1794         gpio_dur = 32; // 32*32us = 1024us
1795 #ifdef CONFIG_GPIO_WAKEUP_LOW_ACTIVE
1796         gpio_high_active = 0;
1797 #else // !CONFIG_GPIO_WAKEUP_LOW_ACTIVE
1798         gpio_high_active = 1;
1799 #endif // !CONFIG_GPIO_WAKEUP_LOW_ACTIVE
1800 #endif //CONFIG_GPIO_WAKEUP
1801
1802         if (!ppwrpriv->wowlan_pno_enable)
1803                 magic_pkt = enable;
1804
1805         if (psecpriv->dot11PrivacyAlgrthm == _WEP40_ || psecpriv->dot11PrivacyAlgrthm == _WEP104_)
1806                 hw_unicast = 1;
1807         else if (IS_HARDWARE_TYPE_8192E(adapter))
1808                 hw_unicast = 1;
1809         else
1810                 hw_unicast = 0;
1811
1812         DBG_871X("%s: enable=%d GPIO=%d\n", __FUNCTION__, enable, gpionum);
1813
1814         SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
1815         SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, 0);
1816         SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
1817         SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
1818         SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
1819         SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
1820 #ifndef CONFIG_GTK_OL
1821         SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
1822 #endif
1823         SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
1824         SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
1825         SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
1826         SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur); // (real)unit: 32us
1827         SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, 1);
1828 #ifdef CONFIG_PLATFORM_ARM_RK3188
1829         SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, 4);
1830 #else
1831         SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
1832 #endif
1833
1834         if (pHalFunc->fill_h2c_cmd != NULL) {
1835                 ret = pHalFunc->fill_h2c_cmd(adapter,
1836                                 H2C_WOWLAN,
1837                                 H2C_WOWLAN_LEN,
1838                                 u1H2CWoWlanCtrlParm);
1839         } else {
1840                 DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
1841                 ret = _FAIL;
1842         }
1843         return ret;
1844 }
1845
1846 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
1847 {
1848         struct hal_ops *pHalFunc = &adapter->HalFunc;
1849         struct security_priv* psecuritypriv=&(adapter->securitypriv);
1850         struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
1851         u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN]={0};
1852         u8 ret = _FAIL, count = 0;
1853
1854         DBG_871X("%s(): enable=%d\n", __func__, enable);
1855
1856         if (!ppwrpriv->wowlan_pno_enable) {
1857                 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
1858                                 u1H2CRemoteWakeCtrlParm, enable);
1859                 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
1860                                 u1H2CRemoteWakeCtrlParm, 1);
1861 #ifdef CONFIG_GTK_OL
1862                 if (psecuritypriv->binstallKCK_KEK == _TRUE &&
1863                                 psecuritypriv->dot11PrivacyAlgrthm == _AES_) {
1864                         SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
1865                                         u1H2CRemoteWakeCtrlParm, 1);
1866                 } else {
1867                         DBG_871X("no kck or security is not AES\n");
1868                         SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
1869                                         u1H2CRemoteWakeCtrlParm, 0);
1870                 }
1871 #endif //CONFIG_GTK_OL
1872
1873                 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
1874                                 u1H2CRemoteWakeCtrlParm, 1);
1875                 if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
1876                         (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
1877                         SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
1878                                         u1H2CRemoteWakeCtrlParm, 0);
1879                 } else {
1880                         SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
1881                                         u1H2CRemoteWakeCtrlParm, 1);
1882                 }
1883         }
1884 #ifdef CONFIG_PNO_SUPPORT
1885         else {
1886                 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
1887                                 u1H2CRemoteWakeCtrlParm, enable);
1888                 SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
1889                                 u1H2CRemoteWakeCtrlParm, enable);
1890         }
1891 #endif
1892
1893 #ifdef CONFIG_P2P_WOWLAN
1894         if (_TRUE == ppwrpriv->wowlan_p2p_mode)
1895         {
1896                 DBG_871X("P2P OFFLOAD ENABLE\n");
1897                 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm,1);
1898         }
1899         else
1900         {
1901                 DBG_871X("P2P OFFLOAD DISABLE\n");
1902                 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm,0);
1903         }
1904 #endif //CONFIG_P2P_WOWLAN
1905
1906
1907         if (pHalFunc->fill_h2c_cmd != NULL) {
1908                 ret = pHalFunc->fill_h2c_cmd(adapter,
1909                                 H2C_REMOTE_WAKE_CTRL,
1910                                 H2C_REMOTE_WAKE_CTRL_LEN,
1911                                 u1H2CRemoteWakeCtrlParm);
1912         } else {
1913                 DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
1914                 ret = _FAIL;
1915         }
1916         return ret;
1917 }
1918
1919 static u8 rtw_hal_set_global_info_cmd(_adapter* adapter, u8 group_alg, u8 pairwise_alg)
1920 {
1921         struct hal_ops *pHalFunc = &adapter->HalFunc;
1922         u8 ret = _FAIL;
1923         u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN]={0};
1924
1925         DBG_871X("%s(): group_alg=%d pairwise_alg=%d\n",
1926                         __func__, group_alg, pairwise_alg);
1927         SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
1928                         pairwise_alg);
1929         SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
1930                         group_alg);
1931
1932         if (pHalFunc->fill_h2c_cmd != NULL) {
1933                 ret = pHalFunc->fill_h2c_cmd(adapter,
1934                                 H2C_AOAC_GLOBAL_INFO,
1935                                 H2C_AOAC_GLOBAL_INFO_LEN,
1936                                 u1H2CAOACGlobalInfoParm);
1937         } else {
1938                 DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
1939                 ret = _FAIL;
1940         }
1941
1942         return ret;
1943 }
1944
1945 #ifdef CONFIG_PNO_SUPPORT
1946 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter* adapter,
1947                 PRSVDPAGE_LOC rsvdpageloc, u8 enable)
1948 {
1949         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
1950         struct hal_ops *pHalFunc = &adapter->HalFunc;
1951
1952         u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN]={0};
1953         u8 res = 0, count = 0, ret = _FAIL;
1954
1955         DBG_871X("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
1956                 __func__, rsvdpageloc->LocProbePacket,
1957                 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
1958
1959         SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
1960         SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
1961                         rsvdpageloc->LocScanInfo);
1962         SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
1963                         rsvdpageloc->LocProbePacket);
1964         SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
1965                         rsvdpageloc->LocSSIDInfo);
1966
1967         if (pHalFunc->fill_h2c_cmd != NULL) {
1968                 ret = pHalFunc->fill_h2c_cmd(adapter,
1969                                 H2C_D0_SCAN_OFFLOAD_INFO,
1970                                 H2C_SCAN_OFFLOAD_CTRL_LEN,
1971                                 u1H2CScanOffloadInfoParm);
1972         } else {
1973                 DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
1974                 ret = _FAIL;
1975         }
1976         return ret;
1977 }
1978 #endif //CONFIG_PNO_SUPPORT
1979
1980 void rtw_hal_set_fw_wow_related_cmd(_adapter* padapter, u8 enable)
1981 {
1982         struct security_priv *psecpriv = &padapter->securitypriv;
1983         struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
1984         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
1985         struct sta_info *psta = NULL;
1986         u16 media_status_rpt;
1987         u8      pkt_type = 0;
1988         u8 ret = _SUCCESS;
1989
1990         DBG_871X_LEVEL(_drv_always_, "+%s()+: enable=%d\n", __func__, enable);
1991 _func_enter_;
1992
1993         rtw_hal_set_wowlan_ctrl_cmd(padapter, enable);
1994
1995         if (enable) {
1996                 rtw_hal_set_global_info_cmd(padapter,
1997                                 psecpriv->dot118021XGrpPrivacy,
1998                                 psecpriv->dot11PrivacyAlgrthm);
1999
2000                 if (!(ppwrpriv->wowlan_pno_enable)) {
2001                         rtw_hal_set_disconnect_decision_cmd(padapter, enable);
2002 #ifdef CONFIG_ARP_KEEP_ALIVE
2003                         if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
2004                                 (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
2005                                 pkt_type = 0;
2006                         else
2007                                 pkt_type = 1;
2008 #else
2009                         pkt_type = 0;
2010 #endif //CONFIG_ARP_KEEP_ALIVE
2011                         rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
2012                 }
2013                 rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
2014 #ifdef CONFIG_PNO_SUPPORT
2015                 rtw_hal_check_pno_enabled(padapter);
2016 #endif //CONFIG_PNO_SUPPORT
2017         } else {
2018 #if 0
2019                 {
2020                         u32 PageSize = 0;
2021                         rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
2022                         dump_TX_FIFO(padapter, 4, PageSize);
2023                 }
2024 #endif
2025
2026                 rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
2027                 rtw_hal_set_wowlan_ctrl_cmd(padapter, enable);
2028         }
2029 _func_exit_;
2030         DBG_871X_LEVEL(_drv_always_, "-%s()-\n", __func__);
2031 }
2032 #endif //CONFIG_WOWLAN
2033
2034 #ifdef CONFIG_P2P_WOWLAN
2035 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
2036 {
2037         u8 *ssid_ie;
2038         sint ssid_len_ori;
2039         int len_diff = 0;
2040         
2041         ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
2042
2043         //DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori);
2044         
2045         if(ssid_ie && ssid_len_ori>0)
2046         {
2047                 switch(hidden_ssid_mode)
2048                 {
2049                         case 1:
2050                         {
2051                                 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
2052                                 u32 remain_len = 0;
2053                                 
2054                                 remain_len = ies_len -(next_ie-ies);
2055                                 
2056                                 ssid_ie[1] = 0;                         
2057                                 _rtw_memcpy(ssid_ie+2, next_ie, remain_len);
2058                                 len_diff -= ssid_len_ori;
2059                                 
2060                                 break;
2061                         }               
2062                         case 2:
2063                                 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
2064                                 break;
2065                         default:
2066                                 break;
2067                 }
2068         }
2069
2070         return len_diff;
2071 }
2072
2073 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
2074 {
2075         //struct xmit_frame     *pmgntframe;
2076         //struct pkt_attrib     *pattrib;
2077         //unsigned char *pframe;
2078         struct rtw_ieee80211_hdr *pwlanhdr;
2079         unsigned short *fctrl;
2080         unsigned int    rate_len;
2081         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
2082         u32     pktlen;
2083 //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
2084 //      _irqL irqL;
2085 //      struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2086 //#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
2087         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2088         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
2089         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2090         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
2091         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2092 #ifdef CONFIG_P2P
2093         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
2094 #endif //CONFIG_P2P
2095
2096         //for debug
2097         u8 *dbgbuf = pframe;
2098         u8 dbgbufLen = 0, index = 0;
2099
2100         DBG_871X("%s\n", __FUNCTION__);
2101 //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
2102 //      _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
2103 //#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
2104                 
2105         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;  
2106         
2107         
2108         fctrl = &(pwlanhdr->frame_ctl);
2109         *(fctrl) = 0;
2110         
2111         _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
2112         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2113         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
2114
2115         SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
2116         //pmlmeext->mgnt_seq++;
2117         SetFrameSubType(pframe, WIFI_BEACON);
2118         
2119         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);       
2120         pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
2121         
2122         if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
2123         {
2124                 //DBG_871X("ie len=%d\n", cur_network->IELength);
2125 #ifdef CONFIG_P2P
2126                 // for P2P : Primary Device Type & Device Name
2127                 u32 wpsielen=0, insert_len=0;
2128                 u8 *wpsie=NULL;         
2129                 wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
2130                 
2131                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0)
2132                 {
2133                         uint wps_offset, remainder_ielen;
2134                         u8 *premainder_ie, *pframe_wscie;
2135         
2136                         wps_offset = (uint)(wpsie - cur_network->IEs);
2137
2138                         premainder_ie = wpsie + wpsielen;
2139
2140                         remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
2141
2142 #ifdef CONFIG_IOCTL_CFG80211
2143                         if(pwdinfo->driver_interface == DRIVER_CFG80211 )
2144                         {
2145                                 if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
2146                                 {
2147                                         _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
2148                                         pframe += wps_offset;
2149                                         pktlen += wps_offset;
2150
2151                                         _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
2152                                         pframe += pmlmepriv->wps_beacon_ie_len;
2153                                         pktlen += pmlmepriv->wps_beacon_ie_len;
2154
2155                                         //copy remainder_ie to pframe
2156                                         _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
2157                                         pframe += remainder_ielen;              
2158                                         pktlen += remainder_ielen;
2159                                 }
2160                                 else
2161                                 {
2162                                         _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
2163                                         pframe += cur_network->IELength;
2164                                         pktlen += cur_network->IELength;
2165                                 }
2166                         }
2167                         else
2168 #endif //CONFIG_IOCTL_CFG80211
2169                         {
2170                                 pframe_wscie = pframe + wps_offset;
2171                                 _rtw_memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);                     
2172                                 pframe += (wps_offset + wpsielen);              
2173                                 pktlen += (wps_offset + wpsielen);
2174
2175                                 //now pframe is end of wsc ie, insert Primary Device Type & Device Name
2176                                 //      Primary Device Type
2177                                 //      Type:
2178                                 *(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
2179                                 insert_len += 2;
2180                                 
2181                                 //      Length:
2182                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 );
2183                                 insert_len += 2;
2184                                 
2185                                 //      Value:
2186                                 //      Category ID
2187                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
2188                                 insert_len += 2;
2189
2190                                 //      OUI
2191                                 *(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI );
2192                                 insert_len += 4;
2193
2194                                 //      Sub Category ID
2195                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
2196                                 insert_len += 2;
2197
2198
2199                                 //      Device Name
2200                                 //      Type:
2201                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
2202                                 insert_len += 2;
2203
2204                                 //      Length:
2205                                 *(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len );
2206                                 insert_len += 2;
2207
2208                                 //      Value:
2209                                 _rtw_memcpy( pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len );
2210                                 insert_len += pwdinfo->device_name_len;
2211
2212
2213                                 //update wsc ie length
2214                                 *(pframe_wscie+1) = (wpsielen -2) + insert_len;
2215
2216                                 //pframe move to end
2217                                 pframe+=insert_len;
2218                                 pktlen += insert_len;
2219
2220                                 //copy remainder_ie to pframe
2221                                 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
2222                                 pframe += remainder_ielen;              
2223                                 pktlen += remainder_ielen;
2224                         }
2225                 }
2226                 else
2227 #endif //CONFIG_P2P
2228                 {
2229                         int len_diff;
2230                         _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
2231                         len_diff = update_hidden_ssid(
2232                                 pframe+_BEACON_IE_OFFSET_
2233                                 , cur_network->IELength-_BEACON_IE_OFFSET_
2234                                 , pmlmeinfo->hidden_ssid_mode
2235                         );
2236                         pframe += (cur_network->IELength+len_diff);
2237                         pktlen += (cur_network->IELength+len_diff);
2238                 }
2239 #if 0
2240                 {
2241                         u8 *wps_ie;
2242                         uint wps_ielen;
2243                         u8 sr = 0;
2244                         wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
2245                                 pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
2246                         if (wps_ie && wps_ielen>0) {
2247                                 rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
2248                         }
2249                         if (sr != 0)
2250                                 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
2251                         else
2252                                 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
2253                 }
2254 #endif 
2255 #ifdef CONFIG_P2P
2256                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2257                 {
2258                         u32 len;
2259 #ifdef CONFIG_IOCTL_CFG80211
2260                         if(pwdinfo->driver_interface == DRIVER_CFG80211 )
2261                         {
2262                                 len = pmlmepriv->p2p_beacon_ie_len;
2263                                 if(pmlmepriv->p2p_beacon_ie && len>0)                           
2264                                         _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
2265                         }
2266                         else
2267 #endif //CONFIG_IOCTL_CFG80211
2268                         {
2269                                 len = build_beacon_p2p_ie(pwdinfo, pframe);
2270                         }
2271
2272                         pframe += len;
2273                         pktlen += len;
2274 #ifdef CONFIG_WFD
2275 #ifdef CONFIG_IOCTL_CFG80211
2276                         if(_TRUE == pwdinfo->wfd_info->wfd_enable)
2277 #endif //CONFIG_IOCTL_CFG80211
2278                         {
2279                         len = build_beacon_wfd_ie( pwdinfo, pframe );
2280                         }
2281 #ifdef CONFIG_IOCTL_CFG80211
2282                         else
2283                         {       
2284                                 len = 0;
2285                                 if(pmlmepriv->wfd_beacon_ie && pmlmepriv->wfd_beacon_ie_len>0)
2286                                 {
2287                                         len = pmlmepriv->wfd_beacon_ie_len;
2288                                         _rtw_memcpy(pframe, pmlmepriv->wfd_beacon_ie, len);     
2289                                 }
2290                         }               
2291 #endif //CONFIG_IOCTL_CFG80211
2292                         pframe += len;
2293                         pktlen += len;
2294 #endif //CONFIG_WFD
2295                 }
2296 #endif //CONFIG_P2P
2297
2298                 goto _issue_bcn;
2299
2300         }
2301
2302         //below for ad-hoc mode
2303
2304         //timestamp will be inserted by hardware
2305         pframe += 8;
2306         pktlen += 8;
2307
2308         // beacon interval: 2 bytes
2309
2310         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); 
2311
2312         pframe += 2;
2313         pktlen += 2;
2314
2315         // capability info: 2 bytes
2316
2317         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
2318
2319         pframe += 2;
2320         pktlen += 2;
2321
2322         // SSID
2323         pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
2324
2325         // supported rates...
2326         rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
2327         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pktlen);
2328
2329         // DS parameter set
2330         pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
2331
2332         //if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
2333         {
2334                 u8 erpinfo=0;
2335                 u32 ATIMWindow;
2336                 // IBSS Parameter Set...
2337                 //ATIMWindow = cur->Configuration.ATIMWindow;
2338                 ATIMWindow = 0;
2339                 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
2340
2341                 //ERP IE
2342                 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
2343         }       
2344
2345
2346         // EXTERNDED SUPPORTED RATE
2347         if (rate_len > 8)
2348         {
2349                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
2350         }
2351
2352
2353         //todo:HT for adhoc
2354
2355 _issue_bcn:
2356
2357 //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
2358 //      pmlmepriv->update_bcn = _FALSE;
2359 //      
2360 //      _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);  
2361 //#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
2362
2363         *pLength = pktlen;
2364 #if 0
2365         // printf dbg msg
2366         dbgbufLen = pktlen;
2367         DBG_871X("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
2368
2369         for(index=0;index<dbgbufLen;index++)
2370                 printk("%x ",*(dbgbuf+index));
2371
2372         printk("\n");
2373         DBG_871X("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
2374         
2375 #endif
2376 }
2377
2378 static int get_reg_classes_full_count(struct p2p_channels channel_list) {
2379         int cnt = 0;
2380         int i;
2381
2382         for (i = 0; i < channel_list.reg_classes; i++) {
2383                 cnt += channel_list.reg_class[i].channels;
2384         }
2385
2386         return cnt;
2387 }
2388
2389 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
2390 {
2391         //struct xmit_frame                     *pmgntframe;
2392         //struct pkt_attrib                     *pattrib;
2393         //unsigned char                                 *pframe;
2394         struct rtw_ieee80211_hdr        *pwlanhdr;
2395         unsigned short                          *fctrl; 
2396         unsigned char                                   *mac;
2397         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
2398         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
2399         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2400         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2401         //WLAN_BSSID_EX                 *cur_network = &(pmlmeinfo->network);
2402         u16                                     beacon_interval = 100;
2403         u16                                     capInfo = 0;
2404         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
2405         u8                                      wpsie[255] = { 0x00 };
2406         u32                                     wpsielen = 0, p2pielen = 0;
2407         u32                                     pktlen;
2408 #ifdef CONFIG_WFD
2409         u32                                     wfdielen = 0;
2410 #endif //CONFIG_WFD
2411 #ifdef CONFIG_INTEL_WIDI
2412         u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
2413 #endif //CONFIG_INTEL_WIDI
2414
2415         //for debug
2416         u8 *dbgbuf = pframe;
2417         u8 dbgbufLen = 0, index = 0;
2418
2419         DBG_871X("%s\n", __FUNCTION__);
2420         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;  
2421         
2422         mac = myid(&(padapter->eeprompriv));
2423         
2424         fctrl = &(pwlanhdr->frame_ctl);
2425         *(fctrl) = 0;
2426
2427         //DA filled by FW
2428         _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
2429         _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
2430         
2431         //      Use the device address for BSSID field. 
2432         _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
2433
2434         SetSeqNum(pwlanhdr, 0);
2435         SetFrameSubType(fctrl, WIFI_PROBERSP);
2436
2437         pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
2438         pframe += pktlen;
2439
2440
2441         //timestamp will be inserted by hardware
2442         pframe += 8;
2443         pktlen += 8;
2444
2445         // beacon interval: 2 bytes
2446         _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2); 
2447         pframe += 2;
2448         pktlen += 2;
2449
2450         //      capability info: 2 bytes
2451         //      ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec)
2452         capInfo |= cap_ShortPremble;
2453         capInfo |= cap_ShortSlot;
2454         
2455         _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
2456         pframe += 2;
2457         pktlen += 2;
2458
2459
2460         // SSID
2461         pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
2462
2463         // supported rates...
2464         //      Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 )
2465         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
2466
2467         // DS parameter set
2468         pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
2469
2470 #ifdef CONFIG_IOCTL_CFG80211
2471         if(pwdinfo->driver_interface == DRIVER_CFG80211 )
2472         {
2473                 if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
2474                 {
2475                         //WPS IE
2476                         _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
2477                         pktlen += pmlmepriv->wps_probe_resp_ie_len;
2478                         pframe += pmlmepriv->wps_probe_resp_ie_len;
2479
2480                         //P2P IE
2481                         _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
2482                         pktlen += pmlmepriv->p2p_probe_resp_ie_len;
2483                         pframe += pmlmepriv->p2p_probe_resp_ie_len;
2484                 }
2485         }
2486         else
2487 #endif //CONFIG_IOCTL_CFG80211          
2488         {
2489
2490                 //      Todo: WPS IE
2491                 //      Noted by Albert 20100907
2492                 //      According to the WPS specification, all the WPS attribute is presented by Big Endian.
2493
2494                 wpsielen = 0;
2495                 //      WPS OUI
2496                 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
2497                 wpsielen += 4;
2498
2499                 //      WPS version
2500                 //      Type:
2501                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
2502                 wpsielen += 2;
2503
2504                 //      Length:
2505                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
2506                 wpsielen += 2;
2507
2508                 //      Value:
2509                 wpsie[wpsielen++] = WPS_VERSION_1;      //      Version 1.0
2510
2511 #ifdef CONFIG_INTEL_WIDI
2512                 //      Commented by Kurt
2513                 //      Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext.
2514                 if(  _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE 
2515                         || pmlmepriv->num_p2p_sdt != 0 )
2516                 {
2517                         //Sec dev type
2518                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
2519                         wpsielen += 2;
2520
2521                         //      Length:
2522                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
2523                         wpsielen += 2;
2524
2525                         //      Value:
2526                         //      Category ID
2527                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS );
2528                         wpsielen += 2;
2529
2530                         //      OUI
2531                         *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI );
2532                         wpsielen += 4;
2533
2534                         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
2535                         wpsielen += 2;
2536
2537                         if(  _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE )
2538                         {
2539                                 //      Vendor Extension
2540                                 _rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
2541                                 wpsielen += L2SDTA_SERVICE_VE_LEN;
2542                         }
2543                 }
2544 #endif //CONFIG_INTEL_WIDI
2545
2546                 //      WiFi Simple Config State
2547                 //      Type:
2548                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE );
2549                 wpsielen += 2;
2550
2551                 //      Length:
2552                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
2553                 wpsielen += 2;
2554
2555                 //      Value:
2556                 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;   //      Not Configured.
2557
2558                 //      Response Type
2559                 //      Type:
2560                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE );
2561                 wpsielen += 2;
2562
2563                 //      Length:
2564                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
2565                 wpsielen += 2;
2566
2567                 //      Value:
2568                 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
2569
2570                 //      UUID-E
2571                 //      Type:
2572                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
2573                 wpsielen += 2;
2574
2575                 //      Length:
2576                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
2577                 wpsielen += 2;
2578
2579                 //      Value:
2580                 if (pwdinfo->external_uuid == 0) {
2581                         _rtw_memset( wpsie + wpsielen, 0x0, 16 );
2582                         _rtw_memcpy( wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
2583                 } else {
2584                         _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
2585                 }
2586                 wpsielen += 0x10;
2587
2588                 //      Manufacturer
2589                 //      Type:
2590                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER );
2591                 wpsielen += 2;
2592
2593                 //      Length:
2594                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 );
2595                 wpsielen += 2;
2596
2597                 //      Value:
2598                 _rtw_memcpy( wpsie + wpsielen, "Realtek", 7 );
2599                 wpsielen += 7;
2600
2601                 //      Model Name
2602                 //      Type:
2603                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME );
2604                 wpsielen += 2;
2605
2606                 //      Length:
2607                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 );
2608                 wpsielen += 2;  
2609
2610                 //      Value:
2611                 _rtw_memcpy( wpsie + wpsielen, "8192CU", 6 );
2612                 wpsielen += 6;
2613
2614                 //      Model Number
2615                 //      Type:
2616                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER );
2617                 wpsielen += 2;
2618
2619                 //      Length:
2620                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
2621                 wpsielen += 2;
2622
2623                 //      Value:
2624                 wpsie[ wpsielen++ ] = 0x31;             //      character 1
2625
2626                 //      Serial Number
2627                 //      Type:
2628                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER );
2629                 wpsielen += 2;
2630
2631                 //      Length:
2632                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN );
2633                 wpsielen += 2;
2634
2635                 //      Value:
2636                 _rtw_memcpy( wpsie + wpsielen, "123456" , ETH_ALEN );
2637                 wpsielen += ETH_ALEN;
2638
2639                 //      Primary Device Type
2640                 //      Type:
2641                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
2642                 wpsielen += 2;
2643
2644                 //      Length:
2645                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
2646                 wpsielen += 2;
2647
2648                 //      Value:
2649                 //      Category ID
2650                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
2651                 wpsielen += 2;
2652
2653                 //      OUI
2654                 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
2655                 wpsielen += 4;
2656
2657                 //      Sub Category ID
2658                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
2659                 wpsielen += 2;
2660
2661                 //      Device Name
2662                 //      Type:
2663                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
2664                 wpsielen += 2;
2665
2666                 //      Length:
2667                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
2668                 wpsielen += 2;
2669
2670                 //      Value:
2671                 _rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
2672                 wpsielen += pwdinfo->device_name_len;
2673
2674                 //      Config Method
2675                 //      Type:
2676                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
2677                 wpsielen += 2;
2678
2679                 //      Length:
2680                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
2681                 wpsielen += 2;
2682
2683                 //      Value:
2684                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
2685                 wpsielen += 2;
2686                 
2687
2688                 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen );
2689                 
2690
2691                 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
2692                 pframe += p2pielen;
2693                 pktlen += p2pielen;
2694         }
2695
2696 #ifdef CONFIG_WFD
2697 #ifdef CONFIG_IOCTL_CFG80211
2698         if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
2699 #endif //CONFIG_IOCTL_CFG80211
2700         {
2701                 wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
2702                 pframe += wfdielen;
2703                 pktlen += wfdielen;
2704         }
2705 #ifdef CONFIG_IOCTL_CFG80211
2706         else if (pmlmepriv->wfd_probe_resp_ie != NULL && pmlmepriv->wfd_probe_resp_ie_len>0)
2707         {
2708                 //WFD IE
2709                 _rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, pmlmepriv->wfd_probe_resp_ie_len);
2710                 pktlen += pmlmepriv->wfd_probe_resp_ie_len;
2711                 pframe += pmlmepriv->wfd_probe_resp_ie_len;             
2712         }
2713 #endif //CONFIG_IOCTL_CFG80211
2714 #endif //CONFIG_WFD     
2715
2716         *pLength = pktlen;
2717
2718 #if 0
2719         // printf dbg msg
2720         dbgbufLen = pktlen;
2721         DBG_871X("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
2722
2723         for(index=0;index<dbgbufLen;index++)
2724                 printk("%x ",*(dbgbuf+index));
2725
2726         printk("\n");
2727         DBG_871X("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
2728 #endif
2729 }
2730 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
2731 {
2732         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
2733         u8                      action = P2P_PUB_ACTION_ACTION;
2734         u32                     p2poui = cpu_to_be32(P2POUI);
2735         u8                      oui_subtype = P2P_GO_NEGO_RESP;
2736         u8                      wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
2737         u8                      p2pielen = 0, i;
2738         uint                    wpsielen = 0;
2739         u16                     wps_devicepassword_id = 0x0000;
2740         uint                    wps_devicepassword_id_len = 0;
2741         u8                      channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
2742         u16                     len_channellist_attr = 0;
2743         u32                     pktlen;
2744         u8                      dialogToken = 0;
2745         
2746         //struct xmit_frame                     *pmgntframe;
2747         //struct pkt_attrib                     *pattrib;
2748         //unsigned char                                 *pframe;
2749         struct rtw_ieee80211_hdr        *pwlanhdr;
2750         unsigned short                          *fctrl;
2751         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
2752         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
2753         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2754         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo);
2755         //WLAN_BSSID_EX                 *cur_network = &(pmlmeinfo->network);
2756
2757 #ifdef CONFIG_WFD
2758         u32                                     wfdielen = 0;
2759 #endif //CONFIG_WFD
2760
2761         //for debug
2762         u8 *dbgbuf = pframe;
2763         u8 dbgbufLen = 0, index = 0;
2764
2765         DBG_871X( "%s\n", __FUNCTION__);
2766         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
2767
2768         fctrl = &(pwlanhdr->frame_ctl);
2769         *(fctrl) = 0;
2770
2771         //RA, filled by FW
2772         _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
2773         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2774         _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
2775
2776         SetSeqNum(pwlanhdr, 0);
2777         SetFrameSubType(pframe, WIFI_ACTION);
2778
2779         pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
2780         pframe += pktlen;
2781
2782         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
2783         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
2784         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
2785         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));        
2786         
2787         //dialog token, filled by FW
2788         pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
2789
2790         _rtw_memset( wpsie, 0x00, 255 );
2791         wpsielen = 0;
2792
2793         //      WPS Section
2794         wpsielen = 0;
2795         //      WPS OUI
2796         *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
2797         wpsielen += 4;
2798
2799         //      WPS version
2800         //      Type:
2801         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
2802         wpsielen += 2;
2803
2804         //      Length:
2805         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
2806         wpsielen += 2;
2807
2808         //      Value:
2809         wpsie[wpsielen++] = WPS_VERSION_1;      //      Version 1.0
2810
2811         //      Device Password ID
2812         //      Type:
2813         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
2814         wpsielen += 2;
2815
2816         //      Length:
2817         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
2818         wpsielen += 2;
2819
2820         //      Value:
2821         if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
2822         {
2823                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
2824         }
2825         else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
2826         {
2827                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
2828         }
2829         else
2830         {
2831                 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
2832         }
2833         wpsielen += 2;
2834
2835         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen );
2836
2837
2838         //      P2P IE Section.
2839
2840         //      P2P OUI
2841         p2pielen = 0;
2842         p2pie[ p2pielen++ ] = 0x50;
2843         p2pie[ p2pielen++ ] = 0x6F;
2844         p2pie[ p2pielen++ ] = 0x9A;
2845         p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
2846
2847         //      Commented by Albert 20100908
2848         //      According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes
2849         //      1. Status
2850         //      2. P2P Capability
2851         //      3. Group Owner Intent
2852         //      4. Configuration Timeout
2853         //      5. Operating Channel
2854         //      6. Intended P2P Interface Address
2855         //      7. Channel List
2856         //      8. Device Info
2857         //      9. Group ID     ( Only GO )
2858
2859
2860         //      ToDo:
2861
2862         //      P2P Status
2863         //      Type:
2864         p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
2865
2866         //      Length:
2867         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
2868         p2pielen += 2;
2869
2870         //      Value, filled by FW
2871         p2pie[ p2pielen++ ] = 1;
2872         
2873         //      P2P Capability
2874         //      Type:
2875         p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
2876
2877         //      Length:
2878         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
2879         p2pielen += 2;
2880
2881         //      Value:
2882         //      Device Capability Bitmap, 1 byte
2883
2884         if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
2885         {
2886                 //      Commented by Albert 2011/03/08
2887                 //      According to the P2P specification
2888                 //      if the sending device will be client, the P2P Capability should be reserved of group negotation response frame
2889                 p2pie[ p2pielen++ ] = 0;
2890         }
2891         else
2892         {
2893                 //      Be group owner or meet the error case
2894                 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
2895         }
2896         
2897         //      Group Capability Bitmap, 1 byte
2898         if ( pwdinfo->persistent_supported )
2899         {
2900                 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
2901         }
2902         else
2903         {
2904                 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
2905         }
2906
2907         //      Group Owner Intent
2908         //      Type:
2909         p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
2910
2911         //      Length:
2912         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
2913         p2pielen += 2;
2914
2915         //      Value:
2916         if ( pwdinfo->peer_intent & 0x01 )
2917         {
2918                 //      Peer's tie breaker bit is 1, our tie breaker bit should be 0
2919                 p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 );
2920         }
2921         else
2922         {
2923                 //      Peer's tie breaker bit is 0, our tie breaker bit should be 1
2924                 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
2925         }
2926
2927
2928         //      Configuration Timeout
2929         //      Type:
2930         p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
2931
2932         //      Length:
2933         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
2934         p2pielen += 2;
2935
2936         //      Value:
2937         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P GO
2938         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P Client
2939
2940         //      Operating Channel
2941         //      Type:
2942         p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
2943
2944         //      Length:
2945         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
2946         p2pielen += 2;
2947
2948         //      Value:
2949         //      Country String
2950         p2pie[ p2pielen++ ] = 'X';
2951         p2pie[ p2pielen++ ] = 'X';
2952         
2953         //      The third byte should be set to 0x04.
2954         //      Described in the "Operating Channel Attribute" section.
2955         p2pie[ p2pielen++ ] = 0x04;
2956
2957         //      Operating Class
2958         if ( pwdinfo->operating_channel <= 14 )
2959         {
2960                 //      Operating Class
2961                 p2pie[ p2pielen++ ] = 0x51;
2962         }
2963         else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
2964         {
2965                 //      Operating Class
2966                 p2pie[ p2pielen++ ] = 0x73;
2967         }
2968         else
2969         {
2970                 //      Operating Class
2971                 p2pie[ p2pielen++ ] = 0x7c;
2972         }
2973         
2974         //      Channel Number
2975         p2pie[ p2pielen++ ] = pwdinfo->operating_channel;       //      operating channel number
2976
2977         //      Intended P2P Interface Address  
2978         //      Type:
2979         p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
2980
2981         //      Length:
2982         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
2983         p2pielen += 2;
2984
2985         //      Value:
2986         _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
2987         p2pielen += ETH_ALEN;
2988
2989         //      Channel List
2990         //      Type:
2991         p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
2992
2993         // Country String(3)
2994         // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
2995         // + number of channels in all classes
2996         len_channellist_attr = 3
2997            + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
2998            + get_reg_classes_full_count(pmlmeext->channel_list);
2999
3000 #ifdef CONFIG_CONCURRENT_MODE
3001         if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3002         {
3003                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
3004         }
3005         else
3006         {
3007                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3008         }
3009 #else
3010
3011         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3012
3013  #endif
3014         p2pielen += 2;
3015
3016         //      Value:
3017         //      Country String
3018         p2pie[ p2pielen++ ] = 'X';
3019         p2pie[ p2pielen++ ] = 'X';
3020         
3021         //      The third byte should be set to 0x04.
3022         //      Described in the "Operating Channel Attribute" section.
3023         p2pie[ p2pielen++ ] = 0x04;
3024
3025         //      Channel Entry List
3026
3027 #ifdef CONFIG_CONCURRENT_MODE
3028         if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3029         {
3030                 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;    
3031                 struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3032
3033                 //      Operating Class
3034                 if ( pbuddy_mlmeext->cur_channel > 14 )
3035                 {
3036                         if ( pbuddy_mlmeext->cur_channel >= 149 )
3037                         {
3038                                 p2pie[ p2pielen++ ] = 0x7c;
3039                         }
3040                         else
3041                         {
3042                                 p2pie[ p2pielen++ ] = 0x73;
3043                         }
3044                 }
3045                 else
3046                 {
3047                         p2pie[ p2pielen++ ] = 0x51;
3048                 }
3049
3050                 //      Number of Channels
3051                 //      Just support 1 channel and this channel is AP's channel
3052                 p2pie[ p2pielen++ ] = 1;
3053
3054                 //      Channel List
3055                 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
3056         }
3057         else
3058         {
3059                 int i, j;
3060                 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3061                         //      Operating Class
3062                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3063
3064                         //      Number of Channels
3065                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3066
3067                         //      Channel List
3068                         for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3069                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3070                         }
3071                 }
3072         }
3073 #else // CONFIG_CONCURRENT_MODE
3074         {
3075                 int i, j;
3076                 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3077                         //      Operating Class
3078                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3079
3080                         //      Number of Channels
3081                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3082
3083                         //      Channel List
3084                         for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3085                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3086                         }
3087                 }
3088         }
3089 #endif // CONFIG_CONCURRENT_MODE
3090
3091         
3092         //      Device Info
3093         //      Type:
3094         p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
3095
3096         //      Length:
3097         //      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) 
3098         //      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
3099         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
3100         p2pielen += 2;
3101
3102         //      Value:
3103         //      P2P Device Address
3104         _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
3105         p2pielen += ETH_ALEN;
3106
3107         //      Config Method
3108         //      This field should be big endian. Noted by P2P specification.
3109
3110         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
3111
3112         p2pielen += 2;
3113
3114         //      Primary Device Type
3115         //      Category ID
3116         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
3117         p2pielen += 2;
3118
3119         //      OUI
3120         *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
3121         p2pielen += 4;
3122
3123         //      Sub Category ID
3124         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
3125         p2pielen += 2;
3126
3127         //      Number of Secondary Device Types
3128         p2pie[ p2pielen++ ] = 0x00;     //      No Secondary Device Type List
3129
3130         //      Device Name
3131         //      Type:
3132         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
3133         p2pielen += 2;
3134
3135         //      Length:
3136         *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
3137         p2pielen += 2;
3138
3139         //      Value:
3140         _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
3141         p2pielen += pwdinfo->device_name_len;   
3142         
3143         if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
3144         {
3145                 //      Group ID Attribute
3146                 //      Type:
3147                 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
3148
3149                 //      Length:
3150                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
3151                 p2pielen += 2;
3152
3153                 //      Value:
3154                 //      p2P Device Address
3155                 _rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
3156                 p2pielen += ETH_ALEN;
3157
3158                 //      SSID
3159                 _rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
3160                 p2pielen += pwdinfo->nego_ssidlen;
3161                 
3162         }
3163         
3164         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen ); 
3165         
3166 #ifdef CONFIG_WFD
3167         wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
3168         pframe += wfdielen;
3169         pktlen += wfdielen;
3170 #endif //CONFIG_WFD
3171         
3172         *pLength = pktlen;
3173 #if 0
3174         // printf dbg msg
3175         dbgbufLen = pktlen;
3176         DBG_871X("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
3177
3178         for(index=0;index<dbgbufLen;index++)
3179                 printk("%x ",*(dbgbuf+index));
3180         
3181         printk("\n");
3182         DBG_871X("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
3183 #endif
3184 }
3185
3186 static void rtw_hal_construct_P2PInviteRsp(_adapter * padapter, u8 * pframe, u32 * pLength)
3187 {
3188         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3189         u8                      action = P2P_PUB_ACTION_ACTION;
3190         u32                     p2poui = cpu_to_be32(P2POUI);
3191         u8                      oui_subtype = P2P_INVIT_RESP;
3192         u8                      p2pie[ 255 ] = { 0x00 };
3193         u8                      p2pielen = 0, i;
3194         u8                      channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
3195         u16                     len_channellist_attr = 0;
3196         u32                     pktlen;
3197         u8                      dialogToken = 0;
3198 #ifdef CONFIG_CONCURRENT_MODE
3199         _adapter                                *pbuddy_adapter = padapter->pbuddy_adapter;
3200         struct wifidirect_info  *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
3201         struct mlme_priv                *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
3202         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3203 #endif  
3204 #ifdef CONFIG_WFD
3205         u32                                     wfdielen = 0;
3206 #endif //CONFIG_WFD
3207         
3208         //struct xmit_frame                     *pmgntframe;
3209         //struct pkt_attrib                     *pattrib;
3210         //unsigned char                                 *pframe;
3211         struct rtw_ieee80211_hdr        *pwlanhdr;
3212         unsigned short                          *fctrl;
3213         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
3214         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
3215         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3216         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo);
3217
3218         //for debug
3219         u8 *dbgbuf = pframe;
3220         u8 dbgbufLen = 0, index = 0;
3221
3222
3223         DBG_871X( "%s\n", __FUNCTION__);
3224         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3225
3226         fctrl = &(pwlanhdr->frame_ctl);
3227         *(fctrl) = 0;
3228
3229         //RA fill by FW
3230         _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
3231         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3232
3233         //BSSID fill by FW
3234         _rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
3235
3236         SetSeqNum(pwlanhdr, 0);
3237         SetFrameSubType(pframe, WIFI_ACTION);
3238
3239         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3240         pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3241
3242         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
3243         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
3244         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
3245         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));        
3246
3247         //dialog token, filled by FW
3248         pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
3249
3250         //      P2P IE Section.
3251
3252         //      P2P OUI
3253         p2pielen = 0;
3254         p2pie[ p2pielen++ ] = 0x50;
3255         p2pie[ p2pielen++ ] = 0x6F;
3256         p2pie[ p2pielen++ ] = 0x9A;
3257         p2pie[ p2pielen++ ] = 0x09;     //      WFA P2P v1.0
3258
3259         //      Commented by Albert 20101005
3260         //      According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes
3261         //      1. Status
3262         //      2. Configuration Timeout
3263         //      3. Operating Channel    ( Only GO )
3264         //      4. P2P Group BSSID      ( Only GO )
3265         //      5. Channel List
3266
3267         //      P2P Status
3268         //      Type:
3269         p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
3270
3271         //      Length:
3272         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3273         p2pielen += 2;
3274
3275         //      Value: filled by FW, defult value is FAIL INFO UNAVAILABLE
3276         p2pie[ p2pielen++ ] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
3277         
3278         //      Configuration Timeout
3279         //      Type:
3280         p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
3281
3282         //      Length:
3283         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3284         p2pielen += 2;
3285
3286         //      Value:
3287         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P GO
3288         p2pie[ p2pielen++ ] = 200;      //      2 seconds needed to be the P2P Client
3289
3290         // due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed
3291 #if 0 
3292         if( status_code == P2P_STATUS_SUCCESS )
3293         {
3294                 if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) )
3295                 {
3296                         //      The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO
3297                         //      In this case, the P2P Invitation response frame should carry the two more P2P attributes.
3298                         //      First one is operating channel attribute.
3299                         //      Second one is P2P Group BSSID attribute.
3300
3301                         //      Operating Channel
3302                         //      Type:
3303                         p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
3304
3305                         //      Length:
3306                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3307                         p2pielen += 2;
3308
3309                         //      Value:
3310                         //      Country String
3311                         p2pie[ p2pielen++ ] = 'X';
3312                         p2pie[ p2pielen++ ] = 'X';
3313                 
3314                         //      The third byte should be set to 0x04.
3315                         //      Described in the "Operating Channel Attribute" section.
3316                         p2pie[ p2pielen++ ] = 0x04;
3317
3318                         //      Operating Class
3319                         p2pie[ p2pielen++ ] = 0x51;     //      Copy from SD7
3320                 
3321                         //      Channel Number
3322                         p2pie[ p2pielen++ ] = pwdinfo->operating_channel;       //      operating channel number
3323                         
3324
3325                         //      P2P Group BSSID
3326                         //      Type:
3327                         p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
3328
3329                         //      Length:
3330                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
3331                         p2pielen += 2;
3332
3333                         //      Value:
3334                         //      P2P Device Address for GO
3335                         _rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
3336                         p2pielen += ETH_ALEN;
3337
3338                 }
3339
3340                 //      Channel List
3341                 //      Type:
3342                 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
3343
3344                 //      Length:
3345                 // Country String(3)
3346                 // + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
3347                 // + number of channels in all classes
3348                 len_channellist_attr = 3
3349                         + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
3350                         + get_reg_classes_full_count(pmlmeext->channel_list);
3351
3352 #ifdef CONFIG_CONCURRENT_MODE
3353                 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3354                 {
3355                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
3356                 }
3357                 else
3358                 {
3359                         *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3360                 }
3361 #else
3362
3363                 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3364
3365 #endif
3366                 p2pielen += 2;
3367
3368                 //      Value:
3369                 //      Country String
3370                 p2pie[ p2pielen++ ] = 'X';
3371                 p2pie[ p2pielen++ ] = 'X';
3372
3373                 //      The third byte should be set to 0x04.
3374                 //      Described in the "Operating Channel Attribute" section.
3375                 p2pie[ p2pielen++ ] = 0x04;
3376
3377                 //      Channel Entry List
3378 #ifdef CONFIG_CONCURRENT_MODE
3379                 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3380                 {
3381                         _adapter *pbuddy_adapter = padapter->pbuddy_adapter;    
3382                         struct mlme_ext_priv    *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3383
3384                         //      Operating Class
3385                         if ( pbuddy_mlmeext->cur_channel > 14 )
3386                         {
3387                                 if ( pbuddy_mlmeext->cur_channel >= 149 )
3388                                 {
3389                                         p2pie[ p2pielen++ ] = 0x7c;
3390                                 }
3391                                 else
3392                                 {
3393                                         p2pie[ p2pielen++ ] = 0x73;
3394                                 }
3395                         }
3396                         else
3397                         {
3398                                 p2pie[ p2pielen++ ] = 0x51;
3399                         }
3400
3401                         //      Number of Channels
3402                         //      Just support 1 channel and this channel is AP's channel
3403                         p2pie[ p2pielen++ ] = 1;
3404
3405                         //      Channel List
3406                         p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
3407                 }
3408                 else
3409                 {
3410                         int i, j;
3411                         for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3412                                 //      Operating Class
3413                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3414
3415                                 //      Number of Channels
3416                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3417
3418                                 //      Channel List
3419                                 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3420                                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3421                                 }
3422                         }
3423                 }
3424 #else // CONFIG_CONCURRENT_MODE
3425                 {
3426                         int i, j;
3427                         for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3428                                 //      Operating Class
3429                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3430
3431                                 //      Number of Channels
3432                                 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3433
3434                                 //      Channel List
3435                                 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3436                                         p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3437                                 }
3438                         }
3439                 }
3440 #endif // CONFIG_CONCURRENT_MODE
3441         }
3442 #endif
3443
3444         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen ); 
3445         
3446 #ifdef CONFIG_WFD
3447         wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
3448         pframe += wfdielen;
3449         pktlen += wfdielen;
3450 #endif //CONFIG_WFD
3451
3452         *pLength = pktlen;
3453
3454 #if 0
3455         // printf dbg msg
3456         dbgbufLen = pktlen;
3457         DBG_871X("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
3458
3459         for(index=0;index<dbgbufLen;index++)
3460                 printk("%x ",*(dbgbuf+index));
3461         
3462         printk("\n");
3463         DBG_871X("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
3464 #endif
3465 }
3466
3467
3468 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter, u8 * pframe, u32 * pLength)
3469 {
3470         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3471         u8                      action = P2P_PUB_ACTION_ACTION;
3472         u8                      dialogToken = 0;        
3473         u32                     p2poui = cpu_to_be32(P2POUI);
3474         u8                      oui_subtype = P2P_PROVISION_DISC_RESP;
3475         u8                      wpsie[ 100 ] = { 0x00 };
3476         u8                      wpsielen = 0;
3477         u32                     pktlen;
3478 #ifdef CONFIG_WFD
3479         u32                                     wfdielen = 0;
3480 #endif //CONFIG_WFD             
3481         
3482         //struct xmit_frame                     *pmgntframe;
3483         //struct pkt_attrib                     *pattrib;
3484         //unsigned char                                 *pframe;
3485         struct rtw_ieee80211_hdr        *pwlanhdr;
3486         unsigned short                          *fctrl;
3487         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
3488         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
3489         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3490         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo);
3491
3492         //for debug
3493         u8 *dbgbuf = pframe;
3494         u8 dbgbufLen = 0, index = 0;
3495
3496         DBG_871X( "%s\n", __FUNCTION__);
3497
3498         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3499
3500         fctrl = &(pwlanhdr->frame_ctl);
3501         *(fctrl) = 0;
3502
3503         //RA filled by FW
3504         _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
3505         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3506         _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
3507
3508         SetSeqNum(pwlanhdr,0);
3509         SetFrameSubType(pframe, WIFI_ACTION);
3510
3511         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3512         pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3513
3514         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
3515         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
3516         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
3517         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));        
3518         //dialog token, filled by FW
3519         pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));                
3520
3521         wpsielen = 0;
3522         //      WPS OUI
3523         //*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
3524         RTW_PUT_BE32(wpsie, WPSOUI);
3525         wpsielen += 4;
3526
3527 #if 0
3528         //      WPS version
3529         //      Type:
3530         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
3531         wpsielen += 2;
3532
3533         //      Length:
3534         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
3535         wpsielen += 2;
3536
3537         //      Value:
3538         wpsie[wpsielen++] = WPS_VERSION_1;      //      Version 1.0
3539 #endif
3540
3541         //      Config Method
3542         //      Type:
3543         //*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
3544         RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
3545         wpsielen += 2;
3546
3547         //      Length:
3548         //*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
3549         RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
3550         wpsielen += 2;
3551
3552         //      Value: filled by FW, default value is PBC
3553         //*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method );
3554         RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
3555         wpsielen += 2;
3556
3557         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen ); 
3558
3559 #ifdef CONFIG_WFD
3560         wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
3561         pframe += wfdielen;
3562         pktlen += wfdielen;
3563 #endif //CONFIG_WFD
3564
3565         *pLength = pktlen;
3566
3567         // printf dbg msg
3568 #if 0
3569         dbgbufLen = pktlen;
3570         DBG_871X("======> DBG MSG FOR CONSTRAUCT  ProvisionDis Rsp\n");
3571
3572         for(index=0;index<dbgbufLen;index++)
3573                 printk("%x ",*(dbgbuf+index));
3574
3575         printk("\n");
3576         DBG_871X("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
3577 #endif
3578 }
3579
3580 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter* adapter, PRSVDPAGE_LOC rsvdpageloc)
3581 {
3582         u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN]={0};
3583         struct hal_ops *pHalFunc = &adapter->HalFunc;
3584         u8 ret = _FAIL;
3585
3586         DBG_871X("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",  
3587                 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
3588                 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
3589                 rsvdpageloc->LocPDRsp);
3590
3591         SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
3592         SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
3593         SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
3594         SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
3595         SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
3596         
3597         //FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm);
3598         if (pHalFunc->fill_h2c_cmd != NULL) {
3599                 ret = pHalFunc->fill_h2c_cmd(adapter,
3600                                 H2C_P2P_OFFLOAD_RSVD_PAGE,
3601                                 H2C_P2PRSVDPAGE_LOC_LEN,
3602                                 u1H2CP2PRsvdPageParm);
3603         } else {
3604                 DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
3605                 ret = _FAIL;
3606         }
3607
3608         return ret;
3609 }
3610
3611 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter* adapter)
3612 {
3613
3614         u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
3615         struct wifidirect_info  *pwdinfo = &(adapter->wdinfo);
3616         struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
3617         struct hal_ops *pHalFunc = &adapter->HalFunc;
3618         u8 ret = _FAIL;
3619
3620         _rtw_memset(p2p_wowlan_offload,0 ,sizeof(struct P2P_WoWlan_Offload_t)); 
3621         DBG_871X("%s\n",__func__);      
3622         switch(pwdinfo->role)
3623         {
3624                 case P2P_ROLE_DEVICE:
3625                         DBG_871X("P2P_ROLE_DEVICE\n");
3626                         p2p_wowlan_offload->role = 0;
3627                         break;
3628                 case P2P_ROLE_CLIENT:
3629                         DBG_871X("P2P_ROLE_CLIENT\n");
3630                         p2p_wowlan_offload->role = 1;
3631                         break;
3632                 case P2P_ROLE_GO:
3633                         DBG_871X("P2P_ROLE_GO\n");
3634                         p2p_wowlan_offload->role = 2;
3635                         break;
3636                 default: 
3637                         DBG_871X("P2P_ROLE_DISABLE\n");
3638                         break;
3639                 }
3640         p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm>>8;
3641         p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
3642         offload_cmd = (u8*)p2p_wowlan_offload;
3643         DBG_871X("p2p_wowlan_offload: %x:%x:%x\n",offload_cmd[0],offload_cmd[1],offload_cmd[2]);        
3644
3645         if (pHalFunc->fill_h2c_cmd != NULL) {
3646                 ret = pHalFunc->fill_h2c_cmd(adapter,
3647                                 H2C_P2P_OFFLOAD,
3648                                 H2C_P2P_OFFLOAD_LEN,
3649                                 offload_cmd);
3650         } else {
3651                 DBG_871X("%s: Please hook fill_h2c_cmd first!\n", __func__);
3652                 ret = _FAIL;
3653         }
3654
3655         return ret;
3656
3657         //FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload);
3658 }
3659 #endif //CONFIG_P2P_WOWLAN
3660
3661 static void rtw_hal_construct_beacon(_adapter *padapter,
3662                 u8 *pframe, u32 *pLength)
3663 {
3664         struct rtw_ieee80211_hdr        *pwlanhdr;
3665         u16                                     *fctrl;
3666         u32                                     rate_len, pktlen;
3667         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
3668         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3669         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
3670         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3671
3672
3673         //DBG_871X("%s\n", __FUNCTION__);
3674
3675         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3676
3677         fctrl = &(pwlanhdr->frame_ctl);
3678         *(fctrl) = 0;
3679
3680         _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
3681         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3682         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
3683
3684         SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
3685         //pmlmeext->mgnt_seq++;
3686         SetFrameSubType(pframe, WIFI_BEACON);
3687
3688         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3689         pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
3690
3691         //timestamp will be inserted by hardware
3692         pframe += 8;
3693         pktlen += 8;
3694
3695         // beacon interval: 2 bytes
3696         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
3697
3698         pframe += 2;
3699         pktlen += 2;
3700
3701         // capability info: 2 bytes
3702         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
3703
3704         pframe += 2;
3705         pktlen += 2;
3706
3707         if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3708         {
3709                 //DBG_871X("ie len=%d\n", cur_network->IELength);
3710                 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
3711                 _rtw_memcpy(pframe, cur_network->IEs+sizeof(NDIS_802_11_FIXED_IEs), pktlen);
3712
3713                 goto _ConstructBeacon;
3714         }
3715
3716         //below for ad-hoc mode
3717
3718         // SSID
3719         pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
3720
3721         // supported rates...
3722         rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
3723         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pktlen);
3724
3725         // DS parameter set
3726         pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
3727
3728         if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
3729         {
3730                 u32 ATIMWindow;
3731                 // IBSS Parameter Set...
3732                 //ATIMWindow = cur->Configuration.ATIMWindow;
3733                 ATIMWindow = 0;
3734                 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
3735         }
3736
3737
3738         //todo: ERP IE
3739
3740
3741         // EXTERNDED SUPPORTED RATE
3742         if (rate_len > 8)
3743         {
3744                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
3745         }
3746
3747
3748         //todo:HT for adhoc
3749
3750 _ConstructBeacon:
3751
3752         if ((pktlen + TXDESC_SIZE) > 512)
3753         {
3754                 DBG_871X("beacon frame too large\n");
3755                 return;
3756         }
3757
3758         *pLength = pktlen;
3759
3760         //DBG_871X("%s bcn_sz=%d\n", __FUNCTION__, pktlen);
3761
3762 }
3763
3764 static void rtw_hal_construct_PSPoll(_adapter *padapter,
3765                 u8 *pframe, u32 *pLength)
3766 {
3767         struct rtw_ieee80211_hdr        *pwlanhdr;
3768         u16                                     *fctrl;
3769         u32                                     pktlen;
3770         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
3771         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3772
3773         //DBG_871X("%s\n", __FUNCTION__);
3774
3775         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3776
3777         // Frame control.
3778         fctrl = &(pwlanhdr->frame_ctl);
3779         *(fctrl) = 0;
3780         SetPwrMgt(fctrl);
3781         SetFrameSubType(pframe, WIFI_PSPOLL);
3782
3783         // AID.
3784         SetDuration(pframe, (pmlmeinfo->aid | 0xc000));
3785
3786         // BSSID.
3787         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3788
3789         // TA.
3790         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3791
3792         *pLength = 16;
3793 }
3794
3795 static void rtw_hal_construct_NullFunctionData(
3796         PADAPTER padapter,
3797         u8              *pframe,
3798         u32             *pLength,
3799         u8              *StaAddr,
3800         u8              bQoS,
3801         u8              AC,
3802         u8              bEosp,
3803         u8              bForcePowerSave)
3804 {
3805         struct rtw_ieee80211_hdr        *pwlanhdr;
3806         u16                                             *fctrl;
3807         u32                                             pktlen;
3808         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
3809         struct wlan_network             *cur_network = &pmlmepriv->cur_network;
3810         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
3811         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3812
3813
3814         //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
3815
3816         pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
3817
3818         fctrl = &pwlanhdr->frame_ctl;
3819         *(fctrl) = 0;
3820         if (bForcePowerSave)
3821         {
3822                 SetPwrMgt(fctrl);
3823         }
3824
3825         switch(cur_network->network.InfrastructureMode)
3826         {
3827                 case Ndis802_11Infrastructure:
3828                         SetToDs(fctrl);
3829                         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3830                         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3831                         _rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
3832                         break;
3833                 case Ndis802_11APMode:
3834                         SetFrDs(fctrl);
3835                         _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
3836                         _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3837                         _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
3838                         break;
3839                 case Ndis802_11IBSS:
3840                 default:
3841                         _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
3842                         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3843                         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3844                         break;
3845         }
3846
3847         SetSeqNum(pwlanhdr, 0);
3848
3849         if (bQoS == _TRUE) {
3850                 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
3851
3852                 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
3853
3854                 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos*)pframe;
3855                 SetPriority(&pwlanqoshdr->qc, AC);
3856                 SetEOSP(&pwlanqoshdr->qc, bEosp);
3857
3858                 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
3859         } else {
3860                 SetFrameSubType(pframe, WIFI_DATA_NULL);
3861
3862                 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3863         }
3864
3865         *pLength = pktlen;
3866 }
3867
3868 #ifdef CONFIG_WOWLAN    
3869 //
3870 // Description:
3871 //      Construct the ARP response packet to support ARP offload.
3872 //
3873 static void rtw_hal_construct_ARPRsp(
3874         PADAPTER padapter,
3875         u8                      *pframe,
3876         u32                     *pLength,
3877         u8                      *pIPAddress
3878         )
3879 {
3880         struct rtw_ieee80211_hdr        *pwlanhdr;
3881         u16     *fctrl;
3882         u32     pktlen;
3883         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
3884         struct wlan_network     *cur_network = &pmlmepriv->cur_network;
3885         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
3886         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3887         struct security_priv    *psecuritypriv = &padapter->securitypriv;
3888         static u8       ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
3889         u8      *pARPRspPkt = pframe;
3890         //for TKIP Cal MIC
3891         u8      *payload = pframe;
3892         u8      EncryptionHeadOverhead = 0;
3893         //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
3894
3895         pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
3896
3897         fctrl = &pwlanhdr->frame_ctl;
3898         *(fctrl) = 0;
3899
3900         //-------------------------------------------------------------------------
3901         // MAC Header.
3902         //-------------------------------------------------------------------------
3903         SetFrameType(fctrl, WIFI_DATA);
3904         //SetFrameSubType(fctrl, 0);
3905         SetToDs(fctrl);
3906         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3907         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3908         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3909
3910         SetSeqNum(pwlanhdr, 0);
3911         SetDuration(pwlanhdr, 0);
3912         //SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0);
3913         //SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data);
3914         //SET_80211_HDR_TO_DS(pARPRspPkt, 1);
3915         //SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid);
3916         //SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress);
3917         //SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid);
3918
3919         //SET_80211_HDR_DURATION(pARPRspPkt, 0);
3920         //SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0);
3921 #ifdef CONFIG_WAPI_SUPPORT
3922         *pLength = sMacHdrLng;
3923 #else
3924         *pLength = 24;
3925 #endif
3926         switch (psecuritypriv->dot11PrivacyAlgrthm) {
3927                 case _WEP40_:
3928                 case _WEP104_:
3929                         EncryptionHeadOverhead = 4;
3930                         break;
3931                 case _TKIP_:
3932                         EncryptionHeadOverhead = 8;
3933                         break;
3934                 case _AES_:
3935                         EncryptionHeadOverhead = 8;
3936                         break;
3937 #ifdef CONFIG_WAPI_SUPPORT
3938                 case _SMS4_:
3939                         EncryptionHeadOverhead = 18;
3940                         break;
3941 #endif
3942                 default:
3943                         EncryptionHeadOverhead = 0;
3944         }
3945
3946         if(EncryptionHeadOverhead > 0) {
3947                 _rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead);
3948                 *pLength += EncryptionHeadOverhead;
3949                 //SET_80211_HDR_WEP(pARPRspPkt, 1);  //Suggested by CCW.
3950                 SetPrivacy(fctrl);
3951         }
3952
3953         //-------------------------------------------------------------------------
3954         // Frame Body.
3955         //-------------------------------------------------------------------------
3956         pARPRspPkt =  (u8*)(pframe+ *pLength);
3957         payload = pARPRspPkt; //Get Payload pointer
3958         // LLC header
3959         _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
3960         *pLength += 8;
3961
3962         // ARP element
3963         pARPRspPkt += 8;
3964         SET_ARP_PKT_HW(pARPRspPkt, 0x0100);
3965         SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008);       // IP protocol
3966         SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6);
3967         SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4);
3968         SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200);      // ARP response
3969         SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, myid(&(padapter->eeprompriv)));
3970         SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
3971 #ifdef CONFIG_ARP_KEEP_ALIVE
3972         if (rtw_gw_addr_query(padapter)==0) {
3973                 SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
3974                 SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
3975         }
3976         else
3977 #endif
3978         {
3979                 SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt,
3980                                 get_my_bssid(&(pmlmeinfo->network)));
3981                 SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt,
3982                                 pIPAddress);
3983                 DBG_871X("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
3984                                 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
3985                 DBG_871X("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
3986                                 IP_ARG(pIPAddress));
3987         }
3988
3989         *pLength += 28;
3990
3991         if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
3992                 u8      mic[8];
3993                 struct mic_data micdata;
3994                 struct sta_info *psta = NULL;
3995                 u8      priority[4]={0x0,0x0,0x0,0x0};
3996                 u8      null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
3997
3998                 DBG_871X("%s(): Add MIC\n",__FUNCTION__);
3999
4000                 psta = rtw_get_stainfo(&padapter->stapriv,
4001                                 get_my_bssid(&(pmlmeinfo->network)));
4002                 if (psta != NULL) {
4003                         if(_rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
4004                                                 null_key, 16)==_TRUE) {
4005                                 DBG_871X("%s(): STA dot11tkiptxmickey==0\n",
4006                                                 __func__);
4007                         }
4008                         //start to calculate the mic code
4009                         rtw_secmicsetkey(&micdata,
4010                                         &psta->dot11tkiptxmickey.skey[0]);
4011                 }
4012
4013                 rtw_secmicappend(&micdata, pwlanhdr->addr3, 6);  //DA
4014
4015                 rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); //SA
4016
4017                 priority[0]=0;
4018
4019                 rtw_secmicappend(&micdata, &priority[0], 4);
4020
4021                 rtw_secmicappend(&micdata, payload, 36); //payload length = 8 + 28
4022
4023                 rtw_secgetmic(&micdata,&(mic[0]));
4024
4025                 pARPRspPkt += 28;
4026                 _rtw_memcpy(pARPRspPkt, &(mic[0]),8);
4027
4028                 *pLength += 8;
4029         }
4030 }
4031
4032 #ifdef CONFIG_PNO_SUPPORT
4033 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
4034                 u32 *pLength, pno_ssid_t *ssid)
4035 {
4036         struct rtw_ieee80211_hdr        *pwlanhdr;
4037         u16                             *fctrl;
4038         u32                             pktlen;
4039         unsigned char                   *mac;
4040         unsigned char                   bssrate[NumRates];
4041         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);
4042         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4043         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
4044         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4045         int     bssrate_len = 0;
4046         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4047
4048         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4049         mac = myid(&(padapter->eeprompriv));
4050
4051         fctrl = &(pwlanhdr->frame_ctl);
4052         *(fctrl) = 0;
4053
4054         _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
4055         _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
4056
4057         _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
4058
4059         SetSeqNum(pwlanhdr, 0);
4060         SetFrameSubType(pframe, WIFI_PROBEREQ);
4061
4062         pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4063         pframe += pktlen;
4064
4065         if (ssid == NULL) {
4066                 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
4067         } else {
4068                 //DBG_871X("%s len:%d\n", ssid->SSID, ssid->SSID_len);
4069                 pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
4070         }
4071
4072         get_rate_set(padapter, bssrate, &bssrate_len);
4073
4074         if (bssrate_len > 8)
4075         {
4076                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
4077                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
4078         }
4079         else
4080         {
4081                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
4082         }
4083
4084         *pLength = pktlen;
4085 }
4086
4087 static void rtw_hal_construct_PNO_info(_adapter *padapter,
4088                 u8 *pframe, u32*pLength)
4089 {
4090         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4091
4092         u8      *pPnoInfoPkt = pframe;
4093         pPnoInfoPkt =  (u8*)(pframe+ *pLength);
4094         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
4095
4096         *pLength+=1;
4097         pPnoInfoPkt += 1;
4098         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
4099
4100         *pLength+=3;
4101         pPnoInfoPkt += 3;
4102         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
4103
4104         *pLength+=4;
4105         pPnoInfoPkt += 4;
4106         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
4107
4108         *pLength+=4;
4109         pPnoInfoPkt += 4;
4110         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
4111
4112         *pLength+=4;
4113         pPnoInfoPkt += 4;
4114         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length,
4115                         MAX_PNO_LIST_COUNT);
4116
4117         *pLength+=MAX_PNO_LIST_COUNT;
4118         pPnoInfoPkt += MAX_PNO_LIST_COUNT;
4119         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info,
4120                         MAX_PNO_LIST_COUNT);
4121
4122         *pLength+=MAX_PNO_LIST_COUNT;
4123         pPnoInfoPkt += MAX_PNO_LIST_COUNT;
4124         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info,
4125                         MAX_PNO_LIST_COUNT);
4126
4127         *pLength+=MAX_PNO_LIST_COUNT;
4128         pPnoInfoPkt += MAX_PNO_LIST_COUNT;
4129         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req,
4130                         MAX_HIDDEN_AP);
4131
4132         *pLength+=MAX_HIDDEN_AP;
4133         pPnoInfoPkt += MAX_HIDDEN_AP;
4134 }
4135
4136 static void rtw_hal_construct_ssid_list(_adapter *padapter,
4137         u8 *pframe, u32 *pLength)
4138 {
4139         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4140         u8 *pSSIDListPkt = pframe;
4141         int i;
4142
4143         pSSIDListPkt =  (u8*)(pframe+ *pLength);
4144
4145         for(i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
4146                 _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
4147                         pwrctl->pnlo_info->ssid_length[i]);
4148
4149                 *pLength += WLAN_SSID_MAXLEN;
4150                 pSSIDListPkt += WLAN_SSID_MAXLEN;
4151         }
4152 }
4153
4154 static void rtw_hal_construct_scan_info(_adapter *padapter,
4155         u8 *pframe, u32 *pLength)
4156 {
4157         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4158         u8 *pScanInfoPkt = pframe;
4159         int i;
4160
4161         pScanInfoPkt =  (u8*)(pframe+ *pLength);
4162
4163         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
4164
4165         *pLength+=1;
4166         pScanInfoPkt += 1;
4167         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
4168
4169
4170         *pLength+=1;
4171         pScanInfoPkt += 1;
4172         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
4173
4174
4175         *pLength+=1;
4176         pScanInfoPkt += 1;
4177         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
4178
4179         *pLength+=1;
4180         pScanInfoPkt += 1;
4181         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
4182
4183         *pLength+=1;
4184         pScanInfoPkt += 1;
4185         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
4186
4187         *pLength+=1;
4188         pScanInfoPkt += 1;
4189         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
4190
4191         *pLength+=1;
4192         pScanInfoPkt += 1;
4193         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
4194
4195         *pLength+=1;
4196         pScanInfoPkt += 1;
4197         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
4198
4199         *pLength+=8;
4200         pScanInfoPkt += 8;
4201
4202         for(i = 0 ; i < MAX_SCAN_LIST_COUNT ; i ++) {
4203                 _rtw_memcpy(pScanInfoPkt,
4204                         &pwrctl->pscan_info->ssid_channel_info[i], 4);
4205                 *pLength+=4;
4206                 pScanInfoPkt += 4;
4207         }
4208 }
4209 #endif //CONFIG_PNO_SUPPORT
4210
4211 #ifdef CONFIG_GTK_OL
4212 static void rtw_hal_construct_GTKRsp(
4213         PADAPTER        padapter,
4214         u8              *pframe,
4215         u32             *pLength
4216         )
4217 {
4218         struct rtw_ieee80211_hdr        *pwlanhdr;
4219         u16     *fctrl;
4220         u32     pktlen;
4221         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
4222         struct wlan_network     *cur_network = &pmlmepriv->cur_network;
4223         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
4224         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4225         struct security_priv    *psecuritypriv = &padapter->securitypriv;
4226         static u8       LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
4227         static u8       GTKbody_a[11] ={0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
4228         u8      *pGTKRspPkt = pframe;
4229         u8      EncryptionHeadOverhead = 0;
4230         //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
4231
4232         pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
4233
4234         fctrl = &pwlanhdr->frame_ctl;
4235         *(fctrl) = 0;
4236
4237         //-------------------------------------------------------------------------
4238         // MAC Header.
4239         //-------------------------------------------------------------------------
4240         SetFrameType(fctrl, WIFI_DATA);
4241         //SetFrameSubType(fctrl, 0);
4242         SetToDs(fctrl);
4243
4244         _rtw_memcpy(pwlanhdr->addr1,
4245                         get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
4246
4247         _rtw_memcpy(pwlanhdr->addr2,
4248                         myid(&(padapter->eeprompriv)), ETH_ALEN);
4249
4250         _rtw_memcpy(pwlanhdr->addr3,
4251                         get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
4252
4253         SetSeqNum(pwlanhdr, 0);
4254         SetDuration(pwlanhdr, 0);
4255
4256 #ifdef CONFIG_WAPI_SUPPORT
4257         *pLength = sMacHdrLng;
4258 #else
4259         *pLength = 24;
4260 #endif //CONFIG_WAPI_SUPPORT
4261
4262         //-------------------------------------------------------------------------
4263         // Security Header: leave space for it if necessary.
4264         //-------------------------------------------------------------------------
4265         switch (psecuritypriv->dot11PrivacyAlgrthm) {
4266                 case _WEP40_:
4267                 case _WEP104_:
4268                         EncryptionHeadOverhead = 4;
4269                         break;
4270                 case _TKIP_:
4271                         EncryptionHeadOverhead = 8;
4272                         break;
4273                 case _AES_:
4274                         EncryptionHeadOverhead = 8;
4275                         break;
4276 #ifdef CONFIG_WAPI_SUPPORT
4277                 case _SMS4_:
4278                         EncryptionHeadOverhead = 18;
4279                         break;
4280 #endif //CONFIG_WAPI_SUPPORT
4281                 default:
4282                         EncryptionHeadOverhead = 0;
4283         }
4284
4285         if (EncryptionHeadOverhead > 0) {
4286                 _rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead);
4287                 *pLength += EncryptionHeadOverhead;
4288                 //SET_80211_HDR_WEP(pGTKRspPkt, 1);  //Suggested by CCW.
4289                 //GTK's privacy bit is done by FW
4290                 //SetPrivacy(fctrl);
4291         }
4292         //-------------------------------------------------------------------------
4293         // Frame Body.
4294         //-------------------------------------------------------------------------
4295         pGTKRspPkt =  (u8*)(pframe+ *pLength);
4296         // LLC header
4297         _rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
4298         *pLength += 8;
4299
4300         // GTK element
4301         pGTKRspPkt += 8;
4302
4303         //GTK frame body after LLC, part 1
4304         _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
4305         *pLength += 11;
4306         pGTKRspPkt += 11;
4307         //GTK frame body after LLC, part 2
4308         _rtw_memset(&(pframe[*pLength]), 0, 88);
4309         *pLength += 88;
4310         pGTKRspPkt += 88;
4311
4312 }
4313 #endif //CONFIG_GTK_OL
4314
4315
4316 //
4317 // Description: Fill the reserved packets that FW will use to RSVD page.
4318 //                      Now we just send 4 types packet to rsvd page.
4319 //                      (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
4320 // Input:
4321 // finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
4322 //                  so we need to set the packet length to total lengh.
4323 //            TRUE: At the second time, we should send the first packet (default:beacon)
4324 //                  to Hw again and set the lengh in descriptor to the real beacon lengh.
4325 // 2009.10.15 by tynli.
4326 //
4327 //Page Size = 128: 8188e, 8723a/b, 8192c/d,  
4328 //Page Size = 256: 8192e, 8821a
4329 //Page Size = 512: 8812a
4330 void rtw_hal_set_fw_rsvd_page(_adapter* adapter, bool finished)
4331 {
4332         PHAL_DATA_TYPE pHalData;
4333         struct xmit_frame       *pcmdframe;
4334         struct pkt_attrib       *pattrib;
4335         struct xmit_priv        *pxmitpriv;
4336         struct mlme_ext_priv    *pmlmeext;
4337         struct mlme_ext_info    *pmlmeinfo;
4338         struct pwrctrl_priv *pwrctl;
4339         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4340         struct hal_ops *pHalFunc = &adapter->HalFunc;
4341         u32     BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
4342         u32     NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
4343         u32     ProbeReqLength = 0, NullFunctionDataLength = 0;
4344         u8      TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
4345         u8      TotalPageNum=0, CurtPktPageNum=0, RsvdPageNum=0;
4346         u8      *ReservedPagePacket;
4347         u16     BufIndex = 0;
4348         u32     TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
4349         RSVDPAGE_LOC    RsvdPageLoc;
4350 #ifdef CONFIG_WOWLAN    
4351         u32     ARPLegnth = 0, GTKLegnth = 0, PNOLength = 0, ScanInfoLength = 0;
4352         u32     SSIDLegnth = 0;
4353         struct security_priv *psecuritypriv = &adapter->securitypriv; //added by xx
4354         u8 currentip[4];
4355         u8 cur_dot11txpn[8];
4356 #ifdef CONFIG_GTK_OL
4357         struct sta_priv *pstapriv = &adapter->stapriv;
4358         struct sta_info * psta;
4359         u8 kek[RTW_KEK_LEN];
4360         u8 kck[RTW_KCK_LEN];
4361 #endif //CONFIG_GTK_OL
4362 #ifdef  CONFIG_PNO_SUPPORT 
4363         int index;
4364         u8 ssid_num;
4365 #endif //CONFIG_PNO_SUPPORT
4366 #endif
4367 #ifdef DBG_CONFIG_ERROR_DETECT
4368         struct sreset_priv *psrtpriv;
4369 #endif // DBG_CONFIG_ERROR_DETECT
4370
4371 #ifdef CONFIG_P2P_WOWLAN
4372         u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0, P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
4373 #endif
4374
4375         pHalData = GET_HAL_DATA(adapter);
4376 #ifdef DBG_CONFIG_ERROR_DETECT
4377         psrtpriv = &pHalData->srestpriv;
4378 #endif
4379         pxmitpriv = &adapter->xmitpriv;
4380         pmlmeext = &adapter->mlmeextpriv;
4381         pmlmeinfo = &pmlmeext->mlmext_info;
4382         pwrctl = adapter_to_pwrctl(adapter);
4383
4384         rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
4385         DBG_871X("%s PAGE_SIZE: %d\n", __func__, PageSize);
4386         if (pHalFunc->hal_get_tx_buff_rsvd_page_num != NULL) {
4387                 RsvdPageNum =
4388                         pHalFunc->hal_get_tx_buff_rsvd_page_num(adapter, _TRUE);
4389                 DBG_871X("%s RsvdPageNUm: %d\n", __func__, RsvdPageNum);
4390         } else {
4391                 DBG_871X("[Error]: %s, missing tx_buff_rsvd_page_num func!!\n",
4392                                 __func__);
4393         }
4394
4395         MaxRsvdPageBufSize = RsvdPageNum*PageSize;
4396
4397         pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
4398         if (pcmdframe == NULL) {
4399                 DBG_871X("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
4400                 return;
4401         }
4402
4403         ReservedPagePacket = pcmdframe->buf_addr;
4404         _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
4405
4406         //beacon * 2 pages
4407         BufIndex = TxDescOffset;
4408         rtw_hal_construct_beacon(adapter,
4409                         &ReservedPagePacket[BufIndex], &BeaconLength);
4410
4411         // When we count the first page size, we need to reserve description size for the RSVD
4412         // packet, it will be filled in front of the packet in TXPKTBUF.
4413         CurtPktPageNum = (u8)PageNum_128(TxDescLen + BeaconLength);
4414         //If we don't add 1 more page, the WOWLAN function has a problem. Baron thinks it's a bug of firmware
4415         if (CurtPktPageNum == 1)
4416                 CurtPktPageNum += 1;
4417
4418         TotalPageNum += CurtPktPageNum;
4419
4420         BufIndex += (CurtPktPageNum*PageSize);
4421
4422         //ps-poll * 1 page
4423         RsvdPageLoc.LocPsPoll = TotalPageNum;
4424         DBG_871X("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
4425         rtw_hal_construct_PSPoll(adapter,
4426                         &ReservedPagePacket[BufIndex], &PSPollLength);
4427         rtw_hal_fill_fake_txdesc(adapter,
4428                         &ReservedPagePacket[BufIndex-TxDescLen],
4429                         PSPollLength, _TRUE, _FALSE, _FALSE);
4430
4431         CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
4432
4433         TotalPageNum += CurtPktPageNum;
4434
4435         BufIndex += (CurtPktPageNum*PageSize);
4436
4437 #ifdef CONFIG_BT_COEXIST
4438         //BT Qos null data * 1 page
4439         RsvdPageLoc.LocBTQosNull = TotalPageNum;
4440         DBG_871X("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
4441         rtw_hal_construct_NullFunctionData(
4442                         adapter,
4443                         &ReservedPagePacket[BufIndex],
4444                         &BTQosNullLength,
4445                         get_my_bssid(&pmlmeinfo->network),
4446                         _TRUE, 0, 0, _FALSE);
4447         rtw_hal_fill_fake_txdesc(adapter,
4448                         &ReservedPagePacket[BufIndex-TxDescLen],
4449                         BTQosNullLength, _FALSE, _TRUE, _FALSE);
4450
4451         CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength, PageSize);
4452
4453         TotalPageNum += CurtPktPageNum;
4454
4455         BufIndex += (CurtPktPageNum*PageSize);
4456 #endif //CONFIG_BT_COEXIT
4457
4458         //null data * 1 page
4459         RsvdPageLoc.LocNullData = TotalPageNum;
4460         DBG_871X("LocNullData: %d\n", RsvdPageLoc.LocNullData);
4461         rtw_hal_construct_NullFunctionData(
4462                         adapter,
4463                         &ReservedPagePacket[BufIndex],
4464                         &NullDataLength,
4465                         get_my_bssid(&pmlmeinfo->network),
4466                         _FALSE, 0, 0, _FALSE);
4467         rtw_hal_fill_fake_txdesc(adapter,
4468                         &ReservedPagePacket[BufIndex-TxDescLen],
4469                         NullDataLength, _FALSE, _FALSE, _FALSE);
4470
4471         CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
4472
4473         TotalPageNum += CurtPktPageNum;
4474
4475         BufIndex += (CurtPktPageNum*PageSize);
4476
4477         //Qos null data * 1 page
4478         RsvdPageLoc.LocQosNull = TotalPageNum;
4479         DBG_871X("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
4480         rtw_hal_construct_NullFunctionData(
4481                         adapter,
4482                         &ReservedPagePacket[BufIndex],
4483                         &QosNullLength,
4484                         get_my_bssid(&pmlmeinfo->network),
4485                         _TRUE, 0, 0, _FALSE);
4486         rtw_hal_fill_fake_txdesc(adapter,
4487                         &ReservedPagePacket[BufIndex-TxDescLen],
4488                         QosNullLength, _FALSE, _FALSE, _FALSE);
4489
4490         CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength, PageSize);
4491
4492         TotalPageNum += CurtPktPageNum;
4493
4494         BufIndex += (CurtPktPageNum*PageSize);
4495
4496 #ifdef CONFIG_WOWLAN
4497         if (pwrctl->wowlan_mode == _TRUE &&
4498                         check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
4499                 //ARP RSP * 1 page
4500                 rtw_get_current_ip_address(adapter, currentip);
4501
4502                 RsvdPageLoc.LocArpRsp= TotalPageNum;
4503
4504                 rtw_hal_construct_ARPRsp(
4505                                 adapter,
4506                                 &ReservedPagePacket[BufIndex],
4507                                 &ARPLegnth,
4508                                 currentip);
4509
4510                 rtw_hal_fill_fake_txdesc(adapter,
4511                                 &ReservedPagePacket[BufIndex-TxDescLen],
4512                                 ARPLegnth, _FALSE, _FALSE, _TRUE);
4513
4514                 CurtPktPageNum = (u8)PageNum(TxDescLen + ARPLegnth, PageSize);
4515
4516                 TotalPageNum += CurtPktPageNum;
4517
4518                 BufIndex += (CurtPktPageNum*PageSize);
4519
4520                 //3 SEC IV * 1 page
4521                 rtw_get_sec_iv(adapter, cur_dot11txpn,
4522                                 get_my_bssid(&pmlmeinfo->network));
4523
4524                 RsvdPageLoc.LocRemoteCtrlInfo = TotalPageNum;
4525
4526                 _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen,
4527                                 cur_dot11txpn, _AES_IV_LEN_);
4528
4529                 CurtPktPageNum = (u8)PageNum(_AES_IV_LEN_, PageSize);
4530
4531                 TotalPageNum += CurtPktPageNum;
4532 #ifdef CONFIG_GTK_OL
4533                 BufIndex += (CurtPktPageNum*PageSize);
4534
4535                 //if the ap staion info. exists, get the kek, kck from staion info.
4536                 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
4537                 if (psta == NULL) {
4538                         _rtw_memset(kek, 0, RTW_KEK_LEN);
4539                         _rtw_memset(kck, 0, RTW_KCK_LEN);
4540                         DBG_8192C("%s, KEK, KCK download rsvd page all zero \n",
4541                                         __func__);
4542                 } else {
4543                         _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
4544                         _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
4545                 }
4546
4547                 //3 KEK, KCK
4548                 RsvdPageLoc.LocGTKInfo = TotalPageNum;
4549                 _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen,
4550                                 kck, RTW_KCK_LEN);
4551                 _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen+RTW_KCK_LEN,
4552                                 kek, RTW_KEK_LEN);
4553 #if 0
4554                 {
4555                         int i;
4556                         printk("\ntoFW KCK: ");
4557                         for(i=0;i<16; i++)
4558                                 printk(" %02x ", kck[i]);
4559                         printk("\ntoFW KEK: ");
4560                         for(i=0;i<16; i++)
4561                                 printk(" %02x ", kek[i]);
4562                         printk("\n");
4563                 }
4564 #endif
4565
4566                 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n", 
4567                 //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen],
4568                 //      (TxDescLen + RTW_KCK_LEN + RTW_KEK_LEN));
4569
4570                 CurtPktPageNum = (u8)PageNum(TxDescLen + RTW_KCK_LEN + RTW_KEK_LEN, PageSize);
4571
4572                 TotalPageNum += CurtPktPageNum;
4573
4574                 BufIndex += (CurtPktPageNum*PageSize);
4575
4576                 //3 GTK Response
4577                 RsvdPageLoc.LocGTKRsp= TotalPageNum;
4578                 rtw_hal_construct_GTKRsp(
4579                                 adapter,
4580                                 &ReservedPagePacket[BufIndex],
4581                                 &GTKLegnth);
4582
4583                 rtw_hal_fill_fake_txdesc(adapter,
4584                                 &ReservedPagePacket[BufIndex-TxDescLen],
4585                                 GTKLegnth, _FALSE, _FALSE, _TRUE);
4586 #if 0
4587                 {
4588                         int gj;
4589                         printk("123GTK pkt=> \n");
4590                         for(gj=0; gj < GTKLegnth+TxDescLen; gj++) {
4591                                 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]);
4592                                 if ((gj + 1)%16==0)
4593                                         printk("\n");
4594                         }
4595                         printk(" <=end\n");
4596                 }
4597 #endif
4598
4599                 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n", 
4600                 //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen],
4601                 //      (TxDescLen + GTKLegnth));
4602
4603                 CurtPktPageNum = (u8)PageNum(TxDescLen + GTKLegnth, PageSize);
4604
4605                 TotalPageNum += CurtPktPageNum;
4606
4607                 BufIndex += (CurtPktPageNum*PageSize);
4608
4609                 //below page is empty for GTK extension memory
4610                 //3(11) GTK EXT MEM
4611                 RsvdPageLoc.LocGTKEXTMEM= TotalPageNum;
4612
4613                 CurtPktPageNum = 2;
4614
4615                 TotalPageNum += CurtPktPageNum;
4616                 //extension memory for FW
4617                 TotalPacketLen = BufIndex-TxDescLen + (PageSize*CurtPktPageNum);
4618 #else //CONFIG_GTK_OL
4619                 TotalPacketLen = BufIndex + _AES_IV_LEN_;
4620 #endif //CONFIG_GTK_OL
4621         } else if (pwrctl->wowlan_pno_enable == _TRUE) {
4622 #ifdef CONFIG_PNO_SUPPORT
4623                 if (pwrctl->pno_in_resume == _FALSE &&
4624                                 pwrctl->pno_inited == _TRUE) {
4625
4626                         //Broadcast Probe Request
4627                         RsvdPageLoc.LocProbePacket = TotalPageNum;
4628
4629                         DBG_871X("loc_probe_req: %d\n",
4630                                         RsvdPageLoc.LocProbePacket);
4631
4632                         rtw_hal_construct_ProbeReq(
4633                                 adapter,
4634                                 &ReservedPagePacket[BufIndex],
4635                                 &ProbeReqLength,
4636                                 NULL);
4637
4638                         rtw_hal_fill_fake_txdesc(adapter,
4639                                 &ReservedPagePacket[BufIndex-TxDescLen],
4640                                 ProbeReqLength, _FALSE, _FALSE, _FALSE);
4641
4642 #ifdef CONFIG_PNO_SET_DEBUG
4643                         {
4644                                 int gj;
4645                                 printk("probe req pkt=> \n");
4646                                 for(gj=0; gj < ProbeReqLength + TxDescLen; gj++) {
4647                                         printk(" %02x ",ReservedPagePacket[BufIndex- TxDescLen + gj]);
4648                                         if ((gj + 1)%8==0)
4649                                                 printk("\n");
4650                                 }
4651                                 printk(" <=end\n");
4652                         }
4653 #endif
4654                         CurtPktPageNum =
4655                                 (u8)PageNum(TxDescLen + ProbeReqLength, PageSize);
4656
4657                         TotalPageNum += CurtPktPageNum;
4658
4659                         BufIndex += (CurtPktPageNum*PageSize);
4660
4661                         //Hidden SSID Probe Request
4662                         ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
4663
4664                         for (index = 0 ; index < ssid_num ; index++) {
4665                                 pwrctl->pnlo_info->loc_probe_req[index] =
4666                                         TotalPageNum;
4667
4668                                 rtw_hal_construct_ProbeReq(
4669                                         adapter,
4670                                         &ReservedPagePacket[BufIndex],
4671                                         &ProbeReqLength,
4672                                         &pwrctl->pno_ssid_list->node[index]);
4673
4674                                 rtw_hal_fill_fake_txdesc(adapter,
4675                                         &ReservedPagePacket[BufIndex-TxDescLen],
4676                                         ProbeReqLength, _FALSE, _FALSE, _FALSE);
4677
4678 #ifdef CONFIG_PNO_SET_DEBUG
4679                                 {
4680                                         int gj;
4681                                         printk("probe req pkt=> \n");
4682                                         for(gj=0; gj < ProbeReqLength + TxDescLen; gj++) {
4683                                                 printk(" %02x ", ReservedPagePacket[BufIndex- TxDescLen + gj]);
4684                                                 if ((gj + 1)%8==0)
4685                                                         printk("\n");
4686                                         }
4687                                         printk(" <=end\n");
4688                                 }
4689 #endif
4690                                 CurtPktPageNum =
4691                                         (u8)PageNum(TxDescLen + ProbeReqLength, PageSize);
4692
4693                                 TotalPageNum += CurtPktPageNum;
4694
4695                                 BufIndex += (CurtPktPageNum*PageSize);
4696                         }
4697
4698                         //PNO INFO Page
4699                         RsvdPageLoc.LocPNOInfo = TotalPageNum;
4700                         rtw_hal_construct_PNO_info(adapter,
4701                                         &ReservedPagePacket[BufIndex -TxDescLen],
4702                                         &PNOLength);
4703 #ifdef CONFIG_PNO_SET_DEBUG
4704         {
4705                         int gj;
4706                         printk("PNO pkt=> \n");
4707                         for(gj=0; gj < PNOLength; gj++) {
4708                                 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen +gj]);
4709                                 if ((gj + 1)%8==0)
4710                                         printk("\n");
4711                         }
4712                         printk(" <=end\n");
4713         }
4714 #endif
4715
4716                         CurtPktPageNum = (u8)PageNum_128(PNOLength);
4717                         TotalPageNum += CurtPktPageNum;
4718                         BufIndex += (CurtPktPageNum*PageSize);
4719
4720                         //SSID List Page
4721                         RsvdPageLoc.LocSSIDInfo = TotalPageNum;
4722                         rtw_hal_construct_ssid_list(adapter,
4723                                         &ReservedPagePacket[BufIndex-TxDescLen],
4724                                         &SSIDLegnth);
4725 #ifdef CONFIG_PNO_SET_DEBUG
4726         {
4727                         int gj;
4728                         printk("SSID list pkt=> \n");
4729                         for(gj=0; gj < SSIDLegnth; gj++) {
4730                                 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]);
4731                                 if ((gj + 1)%8==0)
4732                                         printk("\n");
4733                         }
4734                         printk(" <=end\n");
4735         }
4736 #endif
4737                         CurtPktPageNum = (u8)PageNum_128(SSIDLegnth);
4738                         TotalPageNum += CurtPktPageNum;
4739                         BufIndex += (CurtPktPageNum*PageSize);
4740
4741                         //Scan Info Page
4742                         RsvdPageLoc.LocScanInfo = TotalPageNum;
4743                         rtw_hal_construct_scan_info(adapter,
4744                                         &ReservedPagePacket[BufIndex-TxDescLen],
4745                                         &ScanInfoLength);
4746 #ifdef CONFIG_PNO_SET_DEBUG
4747         {
4748                         int gj;
4749                         printk("Scan info pkt=> \n");
4750                         for(gj=0; gj < ScanInfoLength; gj++) {
4751                                 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]);
4752                                 if ((gj + 1)%8==0)
4753                                         printk("\n");
4754                         }
4755                         printk(" <=end\n");
4756         }
4757 #endif
4758                         CurtPktPageNum = (u8)PageNum(ScanInfoLength, PageSize);
4759                         TotalPageNum += CurtPktPageNum;
4760                         BufIndex += (CurtPktPageNum*PageSize);
4761                         TotalPacketLen = BufIndex + ScanInfoLength;
4762                 } else {
4763                         TotalPacketLen = BufIndex + QosNullLength;
4764                 }
4765 #endif //CONFIG_PNO_SUPPORT
4766         } else {
4767                 TotalPacketLen = BufIndex + QosNullLength;
4768         }
4769 #else //CONFIG_WOWLAN
4770         TotalPacketLen = BufIndex + QosNullLength;
4771 #endif //CONFIG_WOWLAN
4772
4773 #ifdef CONFIG_P2P_WOWLAN
4774         if(_TRUE == pwrctl->wowlan_p2p_mode)
4775         {
4776
4777                 // P2P Beacon
4778                 RsvdPageLoc.LocP2PBeacon= TotalPageNum;
4779                 rtw_hal_construct_P2PBeacon(
4780                         adapter,
4781                         &ReservedPagePacket[BufIndex],
4782                         &P2PBCNLength);
4783                 rtw_hal_fill_fake_txdesc(adapter, 
4784                         &ReservedPagePacket[BufIndex-TxDescLen], 
4785                         P2PBCNLength, _FALSE, _FALSE, _FALSE);
4786
4787                 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", 
4788                 //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (P2PBCNLength+TxDescLen));
4789
4790                 CurtPktPageNum = (u8)PageNum(TxDescLen + P2PBCNLength, PageSize);
4791
4792                 TotalPageNum += CurtPktPageNum;
4793
4794                 BufIndex += (CurtPktPageNum*PageSize);
4795
4796                 // P2P Probe rsp
4797                 RsvdPageLoc.LocP2PProbeRsp = TotalPageNum;
4798                 rtw_hal_construct_P2PProbeRsp(
4799                         adapter,
4800                         &ReservedPagePacket[BufIndex],
4801                         &P2PProbeRspLength);
4802                 rtw_hal_fill_fake_txdesc(adapter, 
4803                         &ReservedPagePacket[BufIndex-TxDescLen], 
4804                         P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
4805
4806                 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", 
4807                 //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (P2PProbeRspLength+TxDescLen));
4808
4809                 CurtPktPageNum = (u8)PageNum(TxDescLen + P2PProbeRspLength, PageSize);
4810
4811                 TotalPageNum += CurtPktPageNum;
4812
4813                 BufIndex += (CurtPktPageNum*PageSize);
4814
4815                 //P2P nego rsp
4816                 RsvdPageLoc.LocNegoRsp = TotalPageNum;
4817                 rtw_hal_construct_P2PNegoRsp(
4818                         adapter,
4819                         &ReservedPagePacket[BufIndex],
4820                         &P2PNegoRspLength);
4821                 rtw_hal_fill_fake_txdesc(adapter, 
4822                         &ReservedPagePacket[BufIndex-TxDescLen], 
4823                         P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
4824
4825                 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", 
4826                 //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (NegoRspLength+TxDescLen));
4827
4828                 CurtPktPageNum = (u8)PageNum(TxDescLen + P2PNegoRspLength, PageSize);
4829
4830                 TotalPageNum += CurtPktPageNum;
4831
4832                 BufIndex += (CurtPktPageNum*PageSize);
4833                 
4834                 //P2P invite rsp
4835                 RsvdPageLoc.LocInviteRsp = TotalPageNum;
4836                 rtw_hal_construct_P2PInviteRsp(
4837                         adapter,
4838                         &ReservedPagePacket[BufIndex],
4839                         &P2PInviteRspLength);
4840                 rtw_hal_fill_fake_txdesc(adapter, 
4841                         &ReservedPagePacket[BufIndex-TxDescLen], 
4842                         P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
4843
4844                 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", 
4845                 //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (InviteRspLength+TxDescLen));
4846
4847                 CurtPktPageNum = (u8)PageNum(TxDescLen + P2PInviteRspLength, PageSize);
4848
4849                 TotalPageNum += CurtPktPageNum;
4850
4851                 BufIndex += (CurtPktPageNum*PageSize);
4852         
4853                 //P2P provision discovery rsp
4854                 RsvdPageLoc.LocPDRsp = TotalPageNum;
4855                 rtw_hal_construct_P2PProvisionDisRsp(
4856                         adapter,
4857                         &ReservedPagePacket[BufIndex],
4858                         &P2PPDRspLength);
4859                 rtw_hal_fill_fake_txdesc(adapter, 
4860                         &ReservedPagePacket[BufIndex-TxDescLen], 
4861                         P2PPDRspLength, _FALSE, _FALSE, _FALSE);
4862
4863                 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", 
4864                 //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (PDRspLength+TxDescLen));
4865
4866                 CurtPktPageNum = (u8)PageNum(TxDescLen + P2PPDRspLength, PageSize);
4867
4868                 TotalPageNum += CurtPktPageNum;
4869
4870                 BufIndex += (CurtPktPageNum*PageSize);
4871
4872                 TotalPacketLen = BufIndex + P2PPDRspLength;
4873         }
4874 #endif //CONFIG_P2P_WOWLAN
4875
4876         if(TotalPacketLen > MaxRsvdPageBufSize) {
4877                 DBG_871X("%s(ERROR): rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
4878                                 __FUNCTION__, TotalPacketLen,MaxRsvdPageBufSize);
4879                 goto error;
4880         } else {
4881                 // update attribute
4882                 pattrib = &pcmdframe->attrib;
4883                 update_mgntframe_attrib(adapter, pattrib);
4884                 pattrib->qsel = 0x10;
4885                 pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
4886 #ifdef CONFIG_PCI_HCI
4887                 dump_mgntframe(adapter, pcmdframe);
4888 #else
4889                 dump_mgntframe_and_wait(adapter, pcmdframe, 100);
4890 #endif
4891         }
4892
4893         DBG_871X("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
4894                         __func__,TotalPacketLen,TotalPageNum);
4895
4896         if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
4897                 rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
4898                 if (pwrctl->wowlan_mode == _TRUE)
4899                         rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
4900         } else if (pwrctl->wowlan_pno_enable) {
4901 #ifdef CONFIG_PNO_SUPPORT
4902                 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
4903                 if(pwrctl->pno_in_resume)
4904                         rtw_hal_set_scan_offload_info_cmd(adapter,
4905                                         &RsvdPageLoc, 0);
4906                 else
4907                         rtw_hal_set_scan_offload_info_cmd(adapter,
4908                                         &RsvdPageLoc, 1);
4909 #endif //CONFIG_PNO_SUPPORT
4910         }
4911 #ifdef CONFIG_P2P_WOWLAN
4912         if(_TRUE == pwrctl->wowlan_p2p_mode)
4913                 rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
4914         
4915 #endif //CONFIG_P2P_WOWLAN
4916         return;
4917 error:
4918         rtw_free_xmitframe(pxmitpriv, pcmdframe);
4919 }
4920
4921 static void rtw_hal_download_rsvd_page(_adapter* adapter, u8 mstatus)
4922 {
4923         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(adapter);
4924         struct mlme_ext_priv    *pmlmeext = &(adapter->mlmeextpriv);
4925         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4926         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
4927         BOOLEAN         bcn_valid = _FALSE;
4928         u8      DLBcnCount=0;
4929         u32 poll = 0;
4930         u8 val8;
4931
4932 _func_enter_;
4933
4934         DBG_8192C("+" FUNC_ADPT_FMT ": iface_type=%d mstatus(%x)\n",
4935                 FUNC_ADPT_ARG(adapter), get_iface_type(adapter), mstatus);
4936
4937         if(mstatus == RT_MEDIA_CONNECT) {
4938                 BOOLEAN bRecover = _FALSE;
4939                 u8 v8;
4940
4941                 // We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C.
4942                 // Suggested by filen. Added by tynli.
4943                 rtw_write16(adapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid));
4944
4945                 // set REG_CR bit 8
4946                 v8 = rtw_read8(adapter, REG_CR+1);
4947                 v8 |= BIT(0); // ENSWBCN
4948                 rtw_write8(adapter,  REG_CR+1, v8);
4949
4950                 // Disable Hw protection for a time which revserd for Hw sending beacon.
4951                 // Fix download reserved page packet fail that access collision with the protection time.
4952                 // 2010.05.11. Added by tynli.
4953                 val8 = rtw_read8(adapter, REG_BCN_CTRL);
4954                 val8 &= ~EN_BCN_FUNCTION;
4955                 val8 |= DIS_TSF_UDT;
4956                 rtw_write8(adapter, REG_BCN_CTRL, val8);
4957
4958                 // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.
4959                 if (pHalData->RegFwHwTxQCtrl & BIT(6))
4960                         bRecover = _TRUE;
4961
4962                 // To tell Hw the packet is not a real beacon frame.
4963                 rtw_write8(adapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl & ~BIT(6));
4964                 pHalData->RegFwHwTxQCtrl &= ~BIT(6);
4965
4966                 // Clear beacon valid check bit.
4967                 rtw_hal_set_hwreg(adapter, HW_VAR_BCN_VALID, NULL);
4968                 rtw_hal_set_hwreg(adapter, HW_VAR_DL_BCN_SEL, NULL);
4969
4970                 DLBcnCount = 0;
4971                 poll = 0;
4972                 do {
4973                         // download rsvd page.
4974                         rtw_hal_set_fw_rsvd_page(adapter, 0);
4975
4976                         DLBcnCount++;
4977                         do {
4978                                 rtw_yield_os();
4979                                 //rtw_mdelay_os(10);
4980                                 // check rsvd page download OK.
4981                                 rtw_hal_get_hwreg(adapter, HW_VAR_BCN_VALID, (u8*)(&bcn_valid));
4982                                 poll++;
4983                         } while(!bcn_valid && (poll%10)!=0 && !adapter->bSurpriseRemoved && !adapter->bDriverStopped);
4984                 }while(!bcn_valid && DLBcnCount<=100 && !adapter->bSurpriseRemoved && !adapter->bDriverStopped);
4985
4986                 if(adapter->bSurpriseRemoved || adapter->bDriverStopped) {
4987                         DBG_871X(ADPT_FMT": 0 bSurpriseRemoved:%d, bDriverStopped:%d\n",
4988                                 ADPT_ARG(adapter) ,adapter->bSurpriseRemoved,
4989                                 adapter->bDriverStopped);
4990                 } else if(!bcn_valid) {
4991                         DBG_871X(ADPT_FMT": 1 DL RSVD page failed! DLBcnCount:%u, poll:%u\n",
4992                                 ADPT_ARG(adapter) ,DLBcnCount, poll);
4993                 } else {
4994                         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4995                         pwrctl->fw_psmode_iface_id = adapter->iface_id;
4996                         DBG_871X(ADPT_FMT": 1 DL RSVD page success! DLBcnCount:%u, poll:%u\n",
4997                                 ADPT_ARG(adapter), DLBcnCount, poll);
4998                 }
4999
5000                 // 2010.05.11. Added by tynli.
5001                 val8 = rtw_read8(adapter, REG_BCN_CTRL);
5002                 val8 |= EN_BCN_FUNCTION;
5003                 val8 &= ~DIS_TSF_UDT;
5004                 rtw_write8(adapter, REG_BCN_CTRL, val8);
5005
5006                 // To make sure that if there exists an adapter which would like to send beacon.
5007                 // If exists, the origianl value of 0x422[6] will be 1, we should check this to
5008                 // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause
5009                 // the beacon cannot be sent by HW.
5010                 // 2010.06.23. Added by tynli.
5011                 if(bRecover) {
5012                         rtw_write8(adapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl | BIT(6));
5013                         pHalData->RegFwHwTxQCtrl |= BIT(6);
5014                 }
5015
5016                 // Clear CR[8] or beacon packet will not be send to TxBuf anymore.
5017                 v8 = rtw_read8(adapter, REG_CR+1);
5018                 v8 &= ~BIT(0); // ~ENSWBCN
5019                 rtw_write8(adapter, REG_CR+1, v8);
5020         }
5021
5022 _func_exit_;
5023 }
5024 #endif //CONFIG_WOWLAN
5025
5026 void SetHwReg(_adapter *adapter, u8 variable, u8 *val)
5027 {
5028         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
5029         DM_ODM_T *odm = &(hal_data->odmpriv);
5030
5031 _func_enter_;
5032
5033         switch (variable) {
5034                 case HW_VAR_INITIAL_GAIN:
5035                         {                               
5036                                 u32 rx_gain = ((u32 *)(val))[0];
5037                 
5038                                 if(rx_gain == 0xff){//restore rx gain                                   
5039                                         //ODM_Write_DIG(podmpriv,pDigTable->BackupIGValue);
5040                                         odm_PauseDIG(odm, ODM_RESUME_DIG,rx_gain);
5041                                 }
5042                                 else{
5043                                         //pDigTable->BackupIGValue = pDigTable->CurIGValue;
5044                                         //ODM_Write_DIG(podmpriv,rx_gain);
5045                                         odm_PauseDIG(odm, ODM_PAUSE_DIG,rx_gain);
5046                                 }
5047                         }
5048                         break;          
5049                 case HW_VAR_PORT_SWITCH:
5050                         hw_var_port_switch(adapter);
5051                         break;
5052                 case HW_VAR_INIT_RTS_RATE:
5053                 {
5054                         u16 brate_cfg = *((u16*)val);
5055                         u8 rate_index = 0;
5056                         HAL_VERSION *hal_ver = &hal_data->VersionID;
5057
5058                         if (IS_81XXC(*hal_ver) ||IS_92D(*hal_ver) || IS_8723_SERIES(*hal_ver) || IS_8188E(*hal_ver)) {
5059
5060                                 while (brate_cfg > 0x1) {
5061                                         brate_cfg = (brate_cfg >> 1);
5062                                         rate_index++;
5063                                 }
5064                                 rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
5065                         } else {
5066                                 rtw_warn_on(1);
5067                         }
5068                 }
5069                         break;
5070                 case HW_VAR_SEC_CFG:
5071                 {
5072                         #if defined(CONFIG_CONCURRENT_MODE) && !defined(DYNAMIC_CAMID_ALLOC)
5073                         // enable tx enc and rx dec engine, and no key search for MC/BC
5074                         rtw_write8(adapter, REG_SECCFG, SCR_NoSKMC|SCR_RxDecEnable|SCR_TxEncEnable);
5075                         #elif defined(DYNAMIC_CAMID_ALLOC)
5076                         u16 reg_scr;
5077
5078                         reg_scr = rtw_read16(adapter, REG_SECCFG);
5079                         rtw_write16(adapter, REG_SECCFG, reg_scr|SCR_CHK_KEYID|SCR_RxDecEnable|SCR_TxEncEnable);
5080                         #else
5081                         rtw_write8(adapter, REG_SECCFG, *((u8*)val));
5082                         #endif
5083                 }
5084                         break;
5085                 case HW_VAR_SEC_DK_CFG:
5086                 {
5087                         struct security_priv *sec = &adapter->securitypriv;
5088                         u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
5089
5090                         if (val) /* Enable default key related setting */
5091                         {
5092                                 reg_scr |= SCR_TXBCUSEDK;
5093                                 if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
5094                                         reg_scr |= (SCR_RxUseDK|SCR_TxUseDK);
5095                         }
5096                         else /* Disable default key related setting */
5097                         {
5098                                 reg_scr &= ~(SCR_RXBCUSEDK|SCR_TXBCUSEDK|SCR_RxUseDK|SCR_TxUseDK);
5099                         }
5100
5101                         rtw_write8(adapter, REG_SECCFG, reg_scr);
5102                 }
5103                         break;
5104                 case HW_VAR_DM_FLAG:
5105                         odm->SupportAbility = *((u32*)val);
5106                         break;
5107                 case HW_VAR_DM_FUNC_OP:
5108                         if (*((u8*)val) == _TRUE) {
5109                                 /* save dm flag */
5110                                 odm->BK_SupportAbility = odm->SupportAbility;                           
5111                         } else {
5112                                 /* restore dm flag */
5113                                 odm->SupportAbility = odm->BK_SupportAbility;
5114                         }
5115                         break;
5116                 case HW_VAR_DM_FUNC_SET:
5117                         if(*((u32*)val) == DYNAMIC_ALL_FUNC_ENABLE){
5118                                 struct dm_priv  *dm = &hal_data->dmpriv;
5119                                 dm->DMFlag = dm->InitDMFlag;
5120                                 odm->SupportAbility = dm->InitODMFlag;
5121                         } else {
5122                                 odm->SupportAbility |= *((u32 *)val);
5123                         }
5124                         break;
5125                 case HW_VAR_DM_FUNC_CLR:
5126                         /*
5127                         * input is already a mask to clear function
5128                         * don't invert it again! George,Lucas@20130513
5129                         */
5130                         odm->SupportAbility &= *((u32 *)val);
5131                         break;
5132                 case HW_VAR_ASIX_IOT:
5133                         // enable  ASIX IOT function
5134                         if (*((u8*)val) == _TRUE) {
5135                                 // 0xa2e[0]=0 (disable rake receiver)
5136                                 rtw_write8(adapter, rCCK0_FalseAlarmReport+2, 
5137                                                 rtw_read8(adapter, rCCK0_FalseAlarmReport+2) & ~(BIT0));
5138                                 //  0xa1c=0xa0 (reset channel estimation if signal quality is bad)
5139                                 rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
5140                         } else {
5141                         // restore reg:0xa2e,   reg:0xa1c
5142                                 rtw_write8(adapter, rCCK0_FalseAlarmReport+2, 
5143                                                 rtw_read8(adapter, rCCK0_FalseAlarmReport+2)|(BIT0));
5144                                 rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
5145                         }
5146                         break;
5147 #ifdef CONFIG_WOWLAN
5148         case HW_VAR_WOWLAN:
5149         {
5150                 struct wowlan_ioctl_param *poidparam;
5151                 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5152                 struct security_priv *psecuritypriv = &adapter->securitypriv;
5153                 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5154                 struct hal_ops *pHalFunc = &adapter->HalFunc;
5155                 struct sta_info *psta = NULL;
5156                 int res;
5157                 u16 media_status_rpt;
5158                 u8 val8;
5159
5160                 poidparam = (struct wowlan_ioctl_param *)val;
5161                 switch (poidparam->subcode) {
5162                         case WOWLAN_ENABLE:
5163                                 DBG_871X_LEVEL(_drv_always_, "WOWLAN_ENABLE\n");
5164
5165 #ifdef CONFIG_GTK_OL
5166                                 if (psecuritypriv->dot11PrivacyAlgrthm == _AES_)
5167                                         rtw_hal_fw_sync_cam_id(adapter);
5168 #endif
5169                                 if (IS_HARDWARE_TYPE_8723B(adapter))
5170                                         rtw_hal_backup_rate(adapter);
5171
5172                                 if (pHalFunc->hal_set_wowlan_fw != NULL)
5173                                         pHalFunc->hal_set_wowlan_fw(adapter, _TRUE);
5174                                 else
5175                                         DBG_871X("hal_set_wowlan_fw is null\n");
5176
5177                                 rtw_hal_download_rsvd_page(adapter, RT_MEDIA_CONNECT);
5178
5179                                 if (!pwrctl->wowlan_pno_enable) {
5180                                         psta = rtw_get_stainfo(&adapter->stapriv,
5181                                                         get_bssid(pmlmepriv));
5182                                         media_status_rpt =
5183                                                 (u16)((psta->mac_id<<8)|RT_MEDIA_CONNECT);
5184                                         if (psta != NULL) {
5185                                                 rtw_hal_set_hwreg(adapter,
5186                                                                 HW_VAR_H2C_MEDIA_STATUS_RPT,
5187                                                                 (u8 *)&media_status_rpt);
5188                                         }
5189                                 }
5190
5191                                 rtw_msleep_os(2);
5192
5193                                 if (IS_HARDWARE_TYPE_8188E(adapter))
5194                                         rtw_hal_disable_tx_report(adapter);
5195
5196                                 //RX DMA stop
5197                                 res = rtw_hal_pause_rx_dma(adapter);
5198                                 if (res == _FAIL)
5199                                         DBG_871X_LEVEL(_drv_always_, "[WARNING] pause RX DMA fail\n");
5200
5201 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5202                                 //Enable CPWM2 only.
5203                                 res = rtw_hal_enable_cpwm2(adapter);
5204                                 if (res == _FAIL)
5205                                         DBG_871X_LEVEL(_drv_always_, "[WARNING] enable cpwm2 fail\n");
5206 #endif
5207
5208                                 //Set WOWLAN H2C command.
5209                                 DBG_871X_LEVEL(_drv_always_, "Set WOWLan cmd\n");
5210                                 rtw_hal_set_fw_wow_related_cmd(adapter, 1);
5211
5212                                 res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
5213                                 if (res == _FALSE)
5214                                         DBG_871X("[Error]%s: set wowlan CMD fail!!\n", __func__);
5215
5216                                 pwrctl->wowlan_wake_reason =
5217                                         rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5218
5219                                 DBG_871X_LEVEL(_drv_always_,
5220                                                 "wowlan_wake_reason: 0x%02x\n",
5221                                                 pwrctl->wowlan_wake_reason);
5222 #ifdef CONFIG_GTK_OL_DBG
5223                                 dump_cam_table(adapter);
5224 #endif
5225 #ifdef CONFIG_USB_HCI
5226                                 if (adapter->intf_stop)
5227                                         adapter->intf_stop(adapter);
5228
5229                                 /* Invoid SE0 reset signal during suspending*/
5230                                 rtw_write8(adapter, REG_RSV_CTRL, 0x20);
5231                                 rtw_write8(adapter, REG_RSV_CTRL, 0x60);
5232 #endif //CONFIG_USB_HCI
5233                                 break;
5234                         case WOWLAN_DISABLE:
5235                                 DBG_871X_LEVEL(_drv_always_, "WOWLAN_DISABLE\n");
5236
5237                                 if (!pwrctl->wowlan_pno_enable) {
5238                                         psta = rtw_get_stainfo(&adapter->stapriv,
5239                                                                 get_bssid(pmlmepriv));
5240
5241                                         if (psta != NULL) {
5242                                                 media_status_rpt =
5243                                                         (u16)((psta->mac_id<<8)|RT_MEDIA_DISCONNECT);
5244                                                 rtw_hal_set_hwreg(adapter,
5245                                                                 HW_VAR_H2C_MEDIA_STATUS_RPT,
5246                                                                 (u8 *)&media_status_rpt);
5247                                         } else {
5248                                                 DBG_871X("%s: psta is null\n", __func__);
5249                                         }
5250                                 }
5251
5252                                 if (0) {
5253                                         DBG_871X("0x630:0x%02x\n",
5254                                                         rtw_read8(adapter, 0x630));
5255                                         DBG_871X("0x631:0x%02x\n",
5256                                                         rtw_read8(adapter, 0x631));
5257                                 }
5258
5259                                 pwrctl->wowlan_wake_reason = rtw_read8(adapter,
5260                                                 REG_WOWLAN_WAKE_REASON);
5261
5262                                 DBG_871X_LEVEL(_drv_always_, "wakeup_reason: 0x%02x\n",
5263                                                 pwrctl->wowlan_wake_reason);
5264
5265                                 rtw_hal_set_fw_wow_related_cmd(adapter, 0);
5266
5267                                 res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
5268                                 if (res == _FALSE) {
5269                                         DBG_871X("[Error]%s: disable WOW cmd fail\n!!", __func__);
5270                                         rtw_hal_force_enable_rxdma(adapter);
5271                                 }
5272
5273                                 if (IS_HARDWARE_TYPE_8188E(adapter))
5274                                         rtw_hal_enable_tx_report(adapter);
5275
5276                                 rtw_hal_update_tx_iv(adapter);
5277
5278 #ifdef CONFIG_GTK_OL
5279                                 if (psecuritypriv->dot11PrivacyAlgrthm == _AES_)
5280                                         rtw_hal_update_gtk_offload_info(adapter);
5281 #endif //CONFIG_GTK_OL
5282
5283                                 if (pHalFunc->hal_set_wowlan_fw != NULL)
5284                                         pHalFunc->hal_set_wowlan_fw(adapter, _FALSE);
5285                                 else
5286                                         DBG_871X("hal_set_wowlan_fw is null\n");
5287 #ifdef CONFIG_GPIO_WAKEUP
5288                                 rtw_clear_hostwakeupgpio(adapter);
5289 #endif
5290                                 if((pwrctl->wowlan_wake_reason != FWDecisionDisconnect) &&
5291                                         (pwrctl->wowlan_wake_reason != Rx_Pairwisekey) &&
5292                                         (pwrctl->wowlan_wake_reason != Rx_DisAssoc) &&
5293                                         (pwrctl->wowlan_wake_reason != Rx_DeAuth)) {
5294
5295                                         rtw_hal_download_rsvd_page(adapter, RT_MEDIA_CONNECT);
5296                                         if (psta != NULL) {
5297                                                 media_status_rpt =
5298                                                         (u16)((psta->mac_id<<8)|RT_MEDIA_CONNECT);
5299                                                 rtw_hal_set_hwreg(adapter,
5300                                                                 HW_VAR_H2C_MEDIA_STATUS_RPT,
5301                                                                 (u8 *)&media_status_rpt);
5302                                         }
5303                                 }
5304                                 break;
5305                         default:
5306                                 break;
5307                         }
5308                 }
5309                 break;
5310 #endif //CONFIG_WOWLAN
5311                 default:
5312                         if (0)
5313                         DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" variable(%d) not defined!\n",
5314                                 FUNC_ADPT_ARG(adapter), variable);
5315                         break;
5316         }
5317
5318 _func_exit_;
5319 }
5320
5321 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
5322 {
5323         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
5324         DM_ODM_T *odm = &(hal_data->odmpriv);
5325
5326 _func_enter_;
5327
5328         switch (variable) {
5329         case HW_VAR_BASIC_RATE:
5330                 *((u16*)val) = hal_data->BasicRateSet;
5331                 break;
5332         case HW_VAR_DM_FLAG:
5333                 *((u32*)val) = odm->SupportAbility;
5334                 break;
5335         case HW_VAR_RF_TYPE:
5336                 *((u8*)val) = hal_data->rf_type;
5337                 break;
5338         default:
5339                 if (0)
5340                 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" variable(%d) not defined!\n",
5341                         FUNC_ADPT_ARG(adapter), variable);
5342                 break;
5343         }
5344
5345 _func_exit_;
5346 }
5347
5348
5349
5350
5351 u8
5352 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
5353 {       
5354         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
5355         DM_ODM_T *odm = &(hal_data->odmpriv);
5356         u8 bResult = _SUCCESS;
5357
5358         switch(variable) {
5359         case HW_DEF_FA_CNT_DUMP:                
5360                 //ODM_COMP_COMMON
5361                 if(*((u8*)value))
5362                         odm->DebugComponents |= (ODM_COMP_DIG |ODM_COMP_FA_CNT);
5363                 else
5364                         odm->DebugComponents &= ~(ODM_COMP_DIG |ODM_COMP_FA_CNT);               
5365                 break;
5366         case HAL_DEF_DBG_RX_INFO_DUMP:
5367                 {
5368                         PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure( odm , PHYDM_FALSEALMCNT);
5369                         pDIG_T  pDM_DigTable = &odm->DM_DigTable;
5370
5371                         DBG_871X("============ Rx Info dump ===================\n");
5372                         DBG_871X("bLinked = %d, RSSI_Min = %d(%%), CurrentIGI = 0x%x \n",
5373                                 odm->bLinked, odm->RSSI_Min, pDM_DigTable->CurIGValue);
5374                         DBG_871X("Cnt_Cck_fail = %d, Cnt_Ofdm_fail = %d, Total False Alarm = %d\n",     
5375                                 FalseAlmCnt->Cnt_Cck_fail, FalseAlmCnt->Cnt_Ofdm_fail, FalseAlmCnt->Cnt_all);
5376
5377                         if(odm->bLinked){
5378                                 DBG_871X("RxRate = %s, RSSI_A = %d(%%), RSSI_B = %d(%%)\n", 
5379                                         HDATA_RATE(odm->RxRate), odm->RSSI_A, odm->RSSI_B);     
5380
5381                                 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
5382                                 rtw_dump_raw_rssi_info(adapter);
5383                                 #endif
5384                         }
5385                 }               
5386                 break;          
5387         case HW_DEF_ODM_DBG_FLAG:
5388                 ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_COMP, *((u8Byte*)value));
5389                 break;
5390         case HW_DEF_ODM_DBG_LEVEL:
5391                 ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_LEVEL, *((u4Byte*)value));
5392                 break;
5393         case HAL_DEF_DBG_DM_FUNC:
5394         {
5395                 u8 dm_func = *((u8*)value);
5396                 struct dm_priv *dm = &hal_data->dmpriv;
5397
5398                 if(dm_func == 0){ //disable all dynamic func
5399                         pDIG_T  pDM_DigTable = &odm->DM_DigTable;
5400                         odm->SupportAbility = DYNAMIC_FUNC_DISABLE;
5401                         pDM_DigTable->bStopDIG = _TRUE;
5402                         DBG_8192C("==> Disable all dynamic function...\n");
5403                 }
5404                 else if(dm_func == 1){//disable DIG
5405                         pDIG_T  pDM_DigTable = &odm->DM_DigTable;
5406                         odm->SupportAbility  &= (~DYNAMIC_BB_DIG);
5407                         pDM_DigTable->bStopDIG = _TRUE;         
5408                         DBG_8192C("==> Disable DIG...\n");
5409                 }
5410                 else if(dm_func == 2){//disable High power
5411                         odm->SupportAbility  &= (~DYNAMIC_BB_DYNAMIC_TXPWR);
5412                 }
5413                 else if(dm_func == 3){//disable tx power tracking
5414                         odm->SupportAbility  &= (~DYNAMIC_RF_CALIBRATION);
5415                         DBG_8192C("==> Disable tx power tracking...\n");
5416                 }
5417                 else if(dm_func == 4){//disable BT coexistence
5418                         dm->DMFlag &= (~DYNAMIC_FUNC_BT);
5419                 }
5420                 else if(dm_func == 5){//disable antenna diversity
5421                         odm->SupportAbility  &= (~DYNAMIC_BB_ANT_DIV);
5422                 }
5423                 else if(dm_func == 6){//turn on all dynamic func
5424                         if(!(odm->SupportAbility  & DYNAMIC_BB_DIG)) {
5425                                 DIG_T   *pDigTable = &odm->DM_DigTable;
5426                                 pDigTable->CurIGValue= rtw_read8(adapter, 0xc50);
5427                                 pDigTable->bStopDIG = _FALSE;
5428                         }
5429                         dm->DMFlag |= DYNAMIC_FUNC_BT;
5430                         odm->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
5431
5432                         DBG_8192C("==> Turn on all dynamic function...\n");
5433                 }
5434         }
5435                 break;
5436         case HAL_DEF_DBG_DUMP_RXPKT:
5437                 hal_data->bDumpRxPkt = *((u8*)value);
5438                 break;
5439         case HAL_DEF_DBG_DUMP_TXPKT:
5440                 hal_data->bDumpTxPkt = *((u8*)value);
5441                 break;
5442         case HAL_DEF_ANT_DETECT:
5443                 hal_data->AntDetection = *((u8 *)value);
5444                 break;
5445         case HAL_DEF_DBG_DIS_PWT:
5446                 hal_data->bDisableTXPowerTraining = *((u8*)value);
5447                 break;  
5448         default:
5449                 DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
5450                 bResult = _FAIL;
5451                 break;
5452         }
5453
5454         return bResult;
5455 }
5456
5457 u8
5458 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
5459 {
5460         HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
5461         DM_ODM_T *odm = &(hal_data->odmpriv);
5462         u8 bResult = _SUCCESS;
5463
5464         switch(variable) {
5465                 case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB:
5466                         {
5467                                 struct mlme_priv *pmlmepriv;
5468                                 struct sta_priv *pstapriv;
5469                                 struct sta_info *psta;
5470
5471                                 pmlmepriv = &adapter->mlmepriv;
5472                                 pstapriv = &adapter->stapriv;
5473                                 psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
5474                                 if (psta)
5475                                 {
5476                                         *((int*)value) = psta->rssi_stat.UndecoratedSmoothedPWDB;     
5477                                 }
5478                         }
5479                         break;
5480                 case HW_DEF_ODM_DBG_FLAG:
5481                         *((u8Byte*)value) = odm->DebugComponents;
5482                         break;
5483                 case HW_DEF_ODM_DBG_LEVEL:
5484                         *((u4Byte*)value) = odm->DebugLevel;
5485                         break;
5486                 case HAL_DEF_DBG_DM_FUNC:
5487                         *(( u32*)value) =hal_data->odmpriv.SupportAbility;
5488                         break;
5489                 case HAL_DEF_DBG_DUMP_RXPKT:
5490                         *((u8*)value) = hal_data->bDumpRxPkt;
5491                         break;
5492                 case HAL_DEF_DBG_DUMP_TXPKT:
5493                         *((u8*)value) = hal_data->bDumpTxPkt;
5494                         break;
5495                 case HAL_DEF_ANT_DETECT:
5496                         *((u8 *)value) = hal_data->AntDetection;
5497                         break;
5498                 case HAL_DEF_MACID_SLEEP:
5499                         *(u8*)value = _FALSE;
5500                         break;
5501                 case HAL_DEF_TX_PAGE_SIZE:
5502                         *(( u32*)value) = PAGE_SIZE_128;
5503                         break;
5504                 case HAL_DEF_DBG_DIS_PWT:
5505                         *(u8*)value = hal_data->bDisableTXPowerTraining;
5506                         break;
5507                 default:
5508                         DBG_871X_LEVEL(_drv_always_, "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
5509                         bResult = _FAIL;
5510                         break;
5511         }
5512
5513         return bResult;
5514 }
5515
5516 void GetHalODMVar(      
5517         PADAPTER                                Adapter,
5518         HAL_ODM_VARIABLE                eVariable,
5519         PVOID                                   pValue1,
5520         PVOID                                   pValue2)
5521 {
5522         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
5523         PDM_ODM_T podmpriv = &pHalData->odmpriv;
5524         switch(eVariable){
5525 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
5526                 case HAL_ODM_NOISE_MONITOR:
5527                         {
5528                                 u8 chan = *(u8*)pValue1;
5529                                 *(s16 *)pValue2 = pHalData->noise[chan];
5530                                 #ifdef DBG_NOISE_MONITOR
5531                                 DBG_8192C("### Noise monitor chan(%d)-noise:%d (dBm) ###\n",
5532                                         chan,pHalData->noise[chan]);
5533                                 #endif                  
5534                                                 
5535                         }
5536                         break;
5537 #endif//#ifdef CONFIG_BACKGROUND_NOISE_MONITOR
5538                 default:
5539                         break;
5540         }
5541 }
5542
5543 void SetHalODMVar(
5544         PADAPTER                                Adapter,
5545         HAL_ODM_VARIABLE                eVariable,
5546         PVOID                                   pValue1,
5547         BOOLEAN                                 bSet)
5548 {
5549         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
5550         PDM_ODM_T podmpriv = &pHalData->odmpriv;
5551         //_irqL irqL;
5552         switch(eVariable){
5553                 case HAL_ODM_STA_INFO:
5554                         {       
5555                                 struct sta_info *psta = (struct sta_info *)pValue1;                             
5556                                 if(bSet){
5557                                         DBG_8192C("### Set STA_(%d) info ###\n",psta->mac_id);
5558                                         ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS,psta->mac_id,psta);
5559                                 }
5560                                 else{
5561                                         DBG_8192C("### Clean STA_(%d) info ###\n",psta->mac_id);
5562                                         //_enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL);
5563                                         ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS,psta->mac_id,NULL);
5564                                         
5565                                         //_exit_critical_bh(&pHalData->odm_stainfo_lock, &irqL);
5566                                     }
5567                         }
5568                         break;
5569                 case HAL_ODM_P2P_STATE:         
5570                                 ODM_CmnInfoUpdate(podmpriv,ODM_CMNINFO_WIFI_DIRECT,bSet);
5571                         break;
5572                 case HAL_ODM_WIFI_DISPLAY_STATE:
5573                                 ODM_CmnInfoUpdate(podmpriv,ODM_CMNINFO_WIFI_DISPLAY,bSet);
5574                         break;
5575                 case HAL_ODM_REGULATION:
5576                                 ODM_CmnInfoInit(podmpriv, ODM_CMNINFO_DOMAIN_CODE_2G, pHalData->Regulation2_4G);
5577                                 ODM_CmnInfoInit(podmpriv, ODM_CMNINFO_DOMAIN_CODE_5G, pHalData->Regulation5G);
5578                         break;
5579                 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)              
5580                 case HAL_ODM_NOISE_MONITOR:
5581                         {
5582                                 struct noise_info *pinfo = (struct noise_info *)pValue1;
5583
5584                                 #ifdef DBG_NOISE_MONITOR
5585                                 DBG_8192C("### Noise monitor chan(%d)-bPauseDIG:%d,IGIValue:0x%02x,max_time:%d (ms) ###\n",
5586                                         pinfo->chan,pinfo->bPauseDIG,pinfo->IGIValue,pinfo->max_time);
5587                                 #endif
5588                                 
5589                                 pHalData->noise[pinfo->chan] = ODM_InbandNoise_Monitor(podmpriv,pinfo->bPauseDIG,pinfo->IGIValue,pinfo->max_time);                              
5590                                 DBG_871X("chan_%d, noise = %d (dBm)\n",pinfo->chan,pHalData->noise[pinfo->chan]);
5591                                 #ifdef DBG_NOISE_MONITOR
5592                                 DBG_871X("noise_a = %d, noise_b = %d  noise_all:%d \n", 
5593                                         podmpriv->noise_level.noise[ODM_RF_PATH_A], 
5594                                         podmpriv->noise_level.noise[ODM_RF_PATH_B],
5595                                         podmpriv->noise_level.noise_all);                                               
5596                                 #endif
5597                         }
5598                         break;
5599                 #endif//#ifdef CONFIG_BACKGROUND_NOISE_MONITOR
5600
5601                 default:
5602                         break;
5603         }
5604 }       
5605
5606
5607 BOOLEAN 
5608 eqNByte(
5609         u8*     str1,
5610         u8*     str2,
5611         u32     num
5612         )
5613 {
5614         if(num==0)
5615                 return _FALSE;
5616         while(num>0)
5617         {
5618                 num--;
5619                 if(str1[num]!=str2[num])
5620                         return _FALSE;
5621         }
5622         return _TRUE;
5623 }
5624
5625 //
5626 //      Description:
5627 //              Return TRUE if chTmp is represent for hex digit and 
5628 //              FALSE otherwise.
5629 //
5630 //
5631 BOOLEAN
5632 IsHexDigit(
5633         IN              char            chTmp
5634 )
5635 {
5636         if( (chTmp >= '0' && chTmp <= '9') ||  
5637                 (chTmp >= 'a' && chTmp <= 'f') ||
5638                 (chTmp >= 'A' && chTmp <= 'F') )
5639         {
5640                 return _TRUE;
5641         }
5642         else
5643         {
5644                 return _FALSE;
5645         }
5646 }
5647
5648
5649 //
5650 //      Description:
5651 //              Translate a character to hex digit.
5652 //
5653 u32
5654 MapCharToHexDigit(
5655         IN              char            chTmp
5656 )
5657 {
5658         if(chTmp >= '0' && chTmp <= '9')
5659                 return (chTmp - '0');
5660         else if(chTmp >= 'a' && chTmp <= 'f')
5661                 return (10 + (chTmp - 'a'));
5662         else if(chTmp >= 'A' && chTmp <= 'F') 
5663                 return (10 + (chTmp - 'A'));
5664         else
5665                 return 0;       
5666 }
5667
5668
5669
5670 //
5671 //      Description:
5672 //              Parse hex number from the string pucStr.
5673 //
5674 BOOLEAN 
5675 GetHexValueFromString(
5676         IN              char*                   szStr,
5677         IN OUT  u32*                    pu4bVal,
5678         IN OUT  u32*                    pu4bMove
5679 )
5680 {
5681         char*           szScan = szStr;
5682
5683         // Check input parameter.
5684         if(szStr == NULL || pu4bVal == NULL || pu4bMove == NULL)
5685         {
5686                 DBG_871X("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
5687                 return _FALSE;
5688         }
5689
5690         // Initialize output.
5691         *pu4bMove = 0;
5692         *pu4bVal = 0;
5693
5694         // Skip leading space.
5695         while(  *szScan != '\0' && 
5696                         (*szScan == ' ' || *szScan == '\t') )
5697         {
5698                 szScan++;
5699                 (*pu4bMove)++;
5700         }
5701
5702         // Skip leading '0x' or '0X'.
5703         if(*szScan == '0' && (*(szScan+1) == 'x' || *(szScan+1) == 'X'))
5704         {
5705                 szScan += 2;
5706                 (*pu4bMove) += 2;
5707         }       
5708
5709         // Check if szScan is now pointer to a character for hex digit, 
5710         // if not, it means this is not a valid hex number.
5711         if(!IsHexDigit(*szScan))
5712         {
5713                 return _FALSE;
5714         }
5715
5716         // Parse each digit.
5717         do
5718         {
5719                 (*pu4bVal) <<= 4;
5720                 *pu4bVal += MapCharToHexDigit(*szScan);
5721
5722                 szScan++;
5723                 (*pu4bMove)++;
5724         } while(IsHexDigit(*szScan));
5725
5726         return _TRUE;
5727 }
5728
5729 BOOLEAN 
5730 GetFractionValueFromString(
5731         IN              char*                   szStr,
5732         IN OUT  u8*                             pInteger,
5733         IN OUT  u8*                             pFraction,
5734         IN OUT  u32*                    pu4bMove
5735 )
5736 {
5737         char    *szScan = szStr;
5738
5739         // Initialize output.
5740         *pu4bMove = 0;
5741         *pInteger = 0;
5742         *pFraction = 0;
5743
5744         // Skip leading space.
5745         while ( *szScan != '\0' &&      (*szScan == ' ' || *szScan == '\t') ) {
5746                 ++szScan;
5747                 ++(*pu4bMove);
5748         }
5749
5750         // Parse each digit.
5751         do {
5752                 (*pInteger) *= 10;
5753                 *pInteger += ( *szScan - '0' );
5754
5755                 ++szScan;
5756                 ++(*pu4bMove);
5757
5758                 if ( *szScan == '.' ) 
5759                 {
5760                         ++szScan;
5761                         ++(*pu4bMove);
5762                         
5763                         if ( *szScan < '0' || *szScan > '9' )
5764                                 return _FALSE;
5765                         else {
5766                                 *pFraction = *szScan - '0';
5767                                 ++szScan;
5768                                 ++(*pu4bMove);
5769                                 return _TRUE;
5770                         }
5771                 }
5772         } while(*szScan >= '0' && *szScan <= '9');
5773
5774         return _TRUE;
5775 }
5776
5777 //
5778 //      Description:
5779 //              Return TRUE if szStr is comment out with leading "//".
5780 //
5781 BOOLEAN
5782 IsCommentString(
5783         IN              char                    *szStr
5784 )
5785 {
5786         if(*szStr == '/' && *(szStr+1) == '/')
5787         {
5788                 return _TRUE;
5789         }
5790         else
5791         {
5792                 return _FALSE;
5793         }
5794 }
5795
5796 BOOLEAN
5797 GetU1ByteIntegerFromStringInDecimal(
5798         IN              char*   Str,
5799         IN OUT  u8*             pInt
5800         )
5801 {
5802         u16 i = 0;
5803         *pInt = 0;
5804
5805         while ( Str[i] != '\0' )
5806         {
5807                 if ( Str[i] >= '0' && Str[i] <= '9' )
5808                 {
5809                         *pInt *= 10;
5810                         *pInt += ( Str[i] - '0' );
5811                 }
5812                 else
5813                 {
5814                         return _FALSE;
5815                 }
5816                 ++i;
5817         }
5818
5819         return _TRUE;
5820 }
5821
5822 // <20121004, Kordan> For example, 
5823 // ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
5824 // If RightQualifier does not exist, it will hang on in the while loop
5825 BOOLEAN 
5826 ParseQualifiedString(
5827     IN          char*   In, 
5828     IN OUT      u32*    Start, 
5829     OUT         char*   Out, 
5830     IN          char            LeftQualifier, 
5831     IN          char            RightQualifier
5832     )
5833 {
5834         u32     i = 0, j = 0;
5835         char    c = In[(*Start)++];
5836
5837         if (c != LeftQualifier)
5838                 return _FALSE;
5839
5840         i = (*Start);
5841         while ((c = In[(*Start)++]) != RightQualifier) 
5842                 ; // find ']'
5843         j = (*Start) - 2;
5844         strncpy((char *)Out, (const char*)(In+i), j-i+1);
5845
5846         return _TRUE;
5847 }
5848
5849 BOOLEAN
5850 isAllSpaceOrTab(
5851         u8*     data,
5852         u8      size
5853         )
5854 {
5855         u8      cnt = 0, NumOfSpaceAndTab = 0;
5856
5857         while( size > cnt )
5858         {
5859                 if ( data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0' )
5860                         ++NumOfSpaceAndTab;
5861
5862                 ++cnt;
5863         }
5864
5865         return size == NumOfSpaceAndTab;
5866 }
5867
5868
5869 void rtw_hal_check_rxfifo_full(_adapter *adapter)
5870 {
5871         struct dvobj_priv *psdpriv = adapter->dvobj;
5872         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
5873         HAL_DATA_TYPE           *pHalData = GET_HAL_DATA(adapter);
5874         int save_cnt=_FALSE;
5875         
5876         //switch counter to RX fifo
5877         if(IS_81XXC(pHalData->VersionID) || IS_92D(pHalData->VersionID) 
5878                 || IS_8188E(pHalData->VersionID) || IS_8723_SERIES(pHalData->VersionID)
5879                 || IS_8812_SERIES(pHalData->VersionID) || IS_8821_SERIES(pHalData->VersionID)
5880                 || IS_8723B_SERIES(pHalData->VersionID) || IS_8192E(pHalData->VersionID))
5881         {
5882                 rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xa0);
5883                 save_cnt = _TRUE;
5884         }
5885         else 
5886         {
5887                 //todo: other chips 
5888         }
5889         
5890                 
5891         if(save_cnt)
5892         {
5893                 //rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xa0);
5894                 pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
5895                 pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
5896                 pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow-pdbgpriv->dbg_rx_fifo_last_overflow;
5897         }
5898 }
5899
5900 void linked_info_dump(_adapter *padapter,u8 benable)
5901 {                       
5902         struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
5903
5904         if(padapter->bLinkInfoDump == benable)
5905                 return;
5906         
5907         DBG_871X("%s %s \n",__FUNCTION__,(benable)?"enable":"disable");
5908                                                                                 
5909         if(benable){
5910                 #ifdef CONFIG_LPS
5911                 pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;//keep org value
5912                 rtw_pm_set_lps(padapter,PS_MODE_ACTIVE);
5913                 #endif  
5914                                                                 
5915                 #ifdef CONFIG_IPS       
5916                 pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;//keep org value
5917                 rtw_pm_set_ips(padapter,IPS_NONE);
5918                 #endif  
5919         }
5920         else{
5921                 #ifdef CONFIG_IPS               
5922                 rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
5923                 #endif // CONFIG_IPS
5924
5925                 #ifdef CONFIG_LPS       
5926                 rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt );
5927                 #endif // CONFIG_LPS
5928         }
5929         padapter->bLinkInfoDump = benable ;     
5930 }
5931
5932 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
5933 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
5934 {
5935         u8 isCCKrate,rf_path;
5936         PHAL_DATA_TYPE  pHalData =  GET_HAL_DATA(padapter);
5937         struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
5938         
5939         DBG_871X_SEL_NL(sel,"RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", 
5940                         HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
5941         isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M)?TRUE :FALSE;
5942
5943         if(isCCKrate)
5944                 psample_pkt_rssi->mimo_singal_strength[0] = psample_pkt_rssi->pwdball;
5945                 
5946         for(rf_path = 0;rf_path<pHalData->NumTotalRFPath;rf_path++)
5947         {
5948                 DBG_871X_SEL_NL(sel,"RF_PATH_%d=>singal_strength:%d(%%),singal_quality:%d(%%)\n" 
5949                         ,rf_path,psample_pkt_rssi->mimo_singal_strength[rf_path],psample_pkt_rssi->mimo_singal_quality[rf_path]);
5950                 
5951                 if(!isCCKrate){
5952                         DBG_871X_SEL_NL(sel,"\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
5953                         psample_pkt_rssi->ofdm_pwr[rf_path],psample_pkt_rssi->ofdm_snr[rf_path]);
5954                 }
5955         }       
5956 }
5957
5958 void rtw_dump_raw_rssi_info(_adapter *padapter)
5959 {
5960         u8 isCCKrate,rf_path;
5961         PHAL_DATA_TYPE  pHalData =  GET_HAL_DATA(padapter);
5962         struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
5963         DBG_871X("============ RAW Rx Info dump ===================\n");
5964         DBG_871X("RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", 
5965                         HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all); 
5966
5967         isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M)?TRUE :FALSE;
5968
5969         if(isCCKrate)
5970                 psample_pkt_rssi->mimo_singal_strength[0] = psample_pkt_rssi->pwdball;
5971                 
5972         for(rf_path = 0;rf_path<pHalData->NumTotalRFPath;rf_path++)
5973         {
5974                 DBG_871X("RF_PATH_%d=>singal_strength:%d(%%),singal_quality:%d(%%)" 
5975                         ,rf_path,psample_pkt_rssi->mimo_singal_strength[rf_path],psample_pkt_rssi->mimo_singal_quality[rf_path]);
5976                 
5977                 if(!isCCKrate){
5978                         printk(",rx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
5979                         psample_pkt_rssi->ofdm_pwr[rf_path],psample_pkt_rssi->ofdm_snr[rf_path]);
5980                 }else{
5981                         printk("\n");   
5982                 }
5983         }       
5984 }
5985
5986 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)  
5987 {
5988         u8 isCCKrate,rf_path;
5989         PHAL_DATA_TYPE  pHalData =  GET_HAL_DATA(padapter);
5990         struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
5991
5992         PODM_PHY_INFO_T pPhyInfo  = (PODM_PHY_INFO_T)(&pattrib->phy_info);
5993         struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
5994         
5995         psample_pkt_rssi->data_rate = pattrib->data_rate;
5996         isCCKrate = (pattrib->data_rate <= DESC_RATE11M)?TRUE :FALSE;
5997         
5998         psample_pkt_rssi->pwdball = pPhyInfo->RxPWDBAll;
5999         psample_pkt_rssi->pwr_all = pPhyInfo->RecvSignalPower;
6000
6001         for(rf_path = 0;rf_path<pHalData->NumTotalRFPath;rf_path++)
6002         {               
6003                 psample_pkt_rssi->mimo_singal_strength[rf_path] = pPhyInfo->RxMIMOSignalStrength[rf_path];
6004                 psample_pkt_rssi->mimo_singal_quality[rf_path] = pPhyInfo->RxMIMOSignalQuality[rf_path];
6005                 if(!isCCKrate){
6006                         psample_pkt_rssi->ofdm_pwr[rf_path] = pPhyInfo->RxPwr[rf_path];
6007                         psample_pkt_rssi->ofdm_snr[rf_path] = pPhyInfo->RxSNR[rf_path];         
6008                 }
6009         }
6010 }
6011 #endif
6012
6013 #ifdef CONFIG_EFUSE_CONFIG_FILE
6014 int check_phy_efuse_tx_power_info_valid(PADAPTER padapter) {
6015         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
6016         u8* pContent = pEEPROM->efuse_eeprom_data;
6017         int index = 0;
6018         u16 tx_index_offset = 0x0000;
6019
6020         switch(padapter->chip_type) {
6021                 case RTL8723B:
6022                         tx_index_offset = EEPROM_TX_PWR_INX_8723B;
6023                 break;
6024                 case RTL8188E:
6025                         tx_index_offset = EEPROM_TX_PWR_INX_88E;
6026                 break;
6027                 case RTL8192E:
6028                         tx_index_offset = EEPROM_TX_PWR_INX_8192E;
6029                 break;
6030                 default:
6031                         tx_index_offset = 0x0010;
6032                 break;
6033         }
6034         for (index = 0 ; index < 12 ; index++) {
6035                 if (pContent[tx_index_offset + index] == 0xFF) {
6036                         return _FALSE;
6037                 } else {
6038                         DBG_871X("0x%02x ,", pContent[EEPROM_TX_PWR_INX_88E+index]);
6039                 }
6040         }
6041         DBG_871X("\n");
6042         return _TRUE;
6043 }
6044
6045 int check_phy_efuse_macaddr_info_valid(PADAPTER padapter) {
6046
6047         u8 val = 0;
6048         u16 addr_offset = 0x0000;
6049
6050         switch(padapter->chip_type) {
6051                 case RTL8723B:
6052                         if (padapter->interface_type == RTW_USB) {
6053                                 addr_offset = EEPROM_MAC_ADDR_8723BU;
6054                                 DBG_871X("%s: interface is USB\n", __func__);
6055                         } else if (padapter->interface_type == RTW_SDIO) {
6056                                 addr_offset = EEPROM_MAC_ADDR_8723BS;
6057                                 DBG_871X("%s: interface is SDIO\n", __func__);
6058                         } else if (padapter->interface_type == RTW_PCIE) {
6059                                 addr_offset = EEPROM_MAC_ADDR_8723BE;
6060                                 DBG_871X("%s: interface is PCIE\n", __func__);
6061                         } else if (padapter->interface_type == RTW_GSPI) {
6062                                 //addr_offset = EEPROM_MAC_ADDR_8723BS;
6063                                 DBG_871X("%s: interface is GSPI\n", __func__);
6064                         }
6065                 break;
6066                 case RTL8188E:
6067                         if (padapter->interface_type == RTW_USB) {
6068                                 addr_offset = EEPROM_MAC_ADDR_88EU;
6069                                 DBG_871X("%s: interface is USB\n", __func__);
6070                         } else if (padapter->interface_type == RTW_SDIO) {
6071                                 addr_offset = EEPROM_MAC_ADDR_88ES;
6072                                 DBG_871X("%s: interface is SDIO\n", __func__);
6073                         } else if (padapter->interface_type == RTW_PCIE) {
6074                                 addr_offset = EEPROM_MAC_ADDR_88EE;
6075                                 DBG_871X("%s: interface is PCIE\n", __func__);
6076                         } else if (padapter->interface_type == RTW_GSPI) {
6077                                 //addr_offset = EEPROM_MAC_ADDR_8723BS;
6078                                 DBG_871X("%s: interface is GSPI\n", __func__);
6079                         }
6080                 break;
6081         }
6082
6083         if (addr_offset == 0x0000) {
6084                 DBG_871X("phy efuse MAC addr offset is 0!!\n");
6085                 return _FALSE;
6086         } else {
6087                 rtw_efuse_map_read(padapter, addr_offset, 1, &val);
6088         }
6089
6090         if (val == 0xFF) {
6091                 return _FALSE;
6092         } else {
6093                 DBG_871X("phy efuse with valid MAC addr\n");
6094                 return _TRUE;
6095         }
6096 }
6097
6098 u32 Hal_readPGDataFromConfigFile(
6099         PADAPTER        padapter,
6100         struct file *fp)
6101 {
6102         u32 i;
6103         mm_segment_t fs;
6104         u8 temp[3];
6105         loff_t pos = 0;
6106         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
6107         u8      *PROMContent = pEEPROM->efuse_eeprom_data;
6108
6109         temp[2] = 0; // add end of string '\0'
6110
6111         fs = get_fs();
6112         set_fs(KERNEL_DS);
6113
6114         for (i = 0 ; i < HWSET_MAX_SIZE ; i++) {
6115                 vfs_read(fp, temp, 2, &pos);
6116                 PROMContent[i] = simple_strtoul(temp, NULL, 16);
6117                 if ((i % EFUSE_FILE_COLUMN_NUM) == (EFUSE_FILE_COLUMN_NUM - 1)) {
6118                         //Filter the lates space char.
6119                         vfs_read(fp, temp, 1, &pos);
6120                         if (strchr(temp, ' ') == NULL) {
6121                                 pos--;
6122                                 vfs_read(fp, temp, 2, &pos);
6123                         }
6124                 } else {
6125                         pos += 1; // Filter the space character
6126                 }
6127         }
6128
6129         set_fs(fs);
6130         pEEPROM->bloadfile_fail_flag = _FALSE;
6131
6132 #ifdef CONFIG_DEBUG
6133         DBG_871X("Efuse configure file:\n");
6134         for (i=0; i<HWSET_MAX_SIZE; i++)
6135         {
6136                 if (i % 16 == 0)
6137                         printk("\n");
6138
6139                 printk("%02X ", PROMContent[i]);
6140         }
6141         printk("\n");
6142 #endif
6143
6144         return _SUCCESS;
6145 }
6146
6147 void Hal_ReadMACAddrFromFile(
6148         PADAPTER                padapter,
6149         struct file *fp)
6150 {
6151         u32 i;
6152         mm_segment_t fs;
6153         u8 source_addr[18];
6154         loff_t pos = 0;
6155         u32     curtime = rtw_get_current_time();
6156         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
6157         u8 *head, *end;
6158
6159         _rtw_memset(source_addr, 0, 18);
6160         _rtw_memset(pEEPROM->mac_addr, 0, ETH_ALEN);
6161
6162         fs = get_fs();
6163         set_fs(KERNEL_DS);
6164
6165         DBG_871X("wifi mac address:\n");
6166         vfs_read(fp, source_addr, 18, &pos);
6167         source_addr[17] = ':';
6168
6169         head = end = source_addr;
6170         for (i=0; i<ETH_ALEN; i++) {
6171                 while (end && (*end != ':') )
6172                         end++;
6173
6174                 if (end && (*end == ':') )
6175                         *end = '\0';
6176
6177                 pEEPROM->mac_addr[i] = simple_strtoul(head, NULL, 16 );
6178
6179                 if (end) {
6180                         end++;
6181                         head = end;
6182                 }
6183         }
6184
6185         set_fs(fs);
6186         pEEPROM->bloadmac_fail_flag = _FALSE;
6187
6188         if (rtw_check_invalid_mac_address(pEEPROM->mac_addr) == _TRUE) {
6189 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
6190                 get_random_bytes(pEEPROM->mac_addr, ETH_ALEN);
6191                 pEEPROM->mac_addr[0] = 0x00;
6192                 pEEPROM->mac_addr[1] = 0xe0;
6193                 pEEPROM->mac_addr[2] = 0x4c;
6194 #else
6195                 pEEPROM->mac_addr[0] = 0x00;
6196                 pEEPROM->mac_addr[1] = 0xe0;
6197                 pEEPROM->mac_addr[2] = 0x4c;
6198                 pEEPROM->mac_addr[3] = (u8)(curtime & 0xff) ;
6199                 pEEPROM->mac_addr[4] = (u8)((curtime>>8) & 0xff) ;
6200                 pEEPROM->mac_addr[5] = (u8)((curtime>>16) & 0xff) ;
6201 #endif
6202                 DBG_871X("MAC Address from wifimac error is invalid, assign random MAC !!!\n");
6203         }
6204
6205         DBG_871X("%s: Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
6206                         __func__, pEEPROM->mac_addr[0], pEEPROM->mac_addr[1],
6207                         pEEPROM->mac_addr[2], pEEPROM->mac_addr[3],
6208                         pEEPROM->mac_addr[4], pEEPROM->mac_addr[5]);
6209 }
6210
6211 void Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8* mac_addr) {
6212         int i = 0;
6213         u16 addr_offset = 0x0000;
6214
6215         switch(padapter->chip_type) {
6216                 case RTL8723B:
6217                         if (padapter->interface_type == RTW_USB) {
6218                                 addr_offset = EEPROM_MAC_ADDR_8723BU;
6219                                 DBG_871X("%s: interface is USB\n", __func__);
6220                         } else if (padapter->interface_type == RTW_SDIO) {
6221                                 addr_offset = EEPROM_MAC_ADDR_8723BS;
6222                                 DBG_871X("%s: interface is SDIO\n", __func__);
6223                         } else if (padapter->interface_type == RTW_PCIE) {
6224                                 addr_offset = EEPROM_MAC_ADDR_8723BE;
6225                                 DBG_871X("%s: interface is PCIE\n", __func__);
6226                         } else if (padapter->interface_type == RTW_GSPI){
6227                                 //addr_offset = EEPROM_MAC_ADDR_8723BS;
6228                                 DBG_871X("%s: interface is GSPI\n", __func__);
6229                         }
6230                 break;
6231                 case RTL8188E:
6232                         if (padapter->interface_type == RTW_USB) {
6233                                 addr_offset = EEPROM_MAC_ADDR_88EU;
6234                                 DBG_871X("%s: interface is USB\n", __func__);
6235                         } else if (padapter->interface_type == RTW_SDIO) {
6236                                 addr_offset = EEPROM_MAC_ADDR_88ES;
6237                                 DBG_871X("%s: interface is SDIO\n", __func__);
6238                         } else if (padapter->interface_type == RTW_PCIE) {
6239                                 addr_offset = EEPROM_MAC_ADDR_88EE;
6240                                 DBG_871X("%s: interface is PCIE\n", __func__);
6241                         } else if (padapter->interface_type == RTW_GSPI){
6242                                 //addr_offset = EEPROM_MAC_ADDR_8723BS;
6243                                 DBG_871X("%s: interface is GSPI\n", __func__);
6244                         }
6245                 break;
6246         }
6247
6248         rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
6249
6250         if (rtw_check_invalid_mac_address(mac_addr) == _TRUE) {
6251 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
6252                 get_random_bytes(mac_addr, ETH_ALEN);
6253                 mac_addr[0] = 0x00;
6254                 mac_addr[1] = 0xe0;
6255                 mac_addr[2] = 0x4c;
6256 #else
6257                 mac_addr[0] = 0x00;
6258                 mac_addr[1] = 0xe0;
6259                 mac_addr[2] = 0x4c;
6260                 mac_addr[3] = (u8)(curtime & 0xff) ;
6261                 mac_addr[4] = (u8)((curtime>>8) & 0xff) ;
6262                 mac_addr[5] = (u8)((curtime>>16) & 0xff) ;
6263 #endif
6264                 DBG_871X("MAC Address from phy efuse error, assign random MAC !!!\n");
6265         }
6266
6267         DBG_871X("%s: Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
6268                         __func__, mac_addr[0], mac_addr[1], mac_addr[2],
6269                         mac_addr[3], mac_addr[4], mac_addr[5]);
6270 }
6271 #endif //CONFIG_EFUSE_CONFIG_FILE
6272
6273 #ifdef CONFIG_RF_GAIN_OFFSET
6274 u32 Array_kfreemap[] = { 
6275 0x08,0xe,
6276 0x06,0xc,
6277 0x04,0xa,
6278 0x02,0x8,
6279 0x00,0x6,
6280 0x03,0x4,
6281 0x05,0x2,
6282 0x07,0x0,
6283 0x09,0x0,
6284 0x0c,0x0,
6285 };
6286
6287 void rtw_bb_rf_gain_offset(_adapter *padapter)
6288 {
6289         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
6290         u8              value = padapter->eeprompriv.EEPROMRFGainOffset;
6291         u8              tmp = 0x3e;
6292         u32     res,i=0;
6293         u4Byte     ArrayLen    = sizeof(Array_kfreemap)/sizeof(u32);
6294         pu4Byte    Array           = Array_kfreemap;
6295         u4Byte v1=0,v2=0,GainValue,target=0; 
6296         //DBG_871X("+%s value: 0x%02x+\n", __func__, value);
6297 #if defined(CONFIG_RTL8723A)
6298         if (value & BIT0) {
6299                 DBG_871X("Offset RF Gain.\n");
6300                 DBG_871X("Offset RF Gain.  padapter->eeprompriv.EEPROMRFGainVal=0x%x\n",padapter->eeprompriv.EEPROMRFGainVal);
6301                 if(padapter->eeprompriv.EEPROMRFGainVal != 0xff){
6302                         res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0xd, 0xffffffff);
6303                         DBG_871X("Offset RF Gain. reg 0xd=0x%x\n",res);
6304                         res &= 0xfff87fff;
6305
6306                         res |= (padapter->eeprompriv.EEPROMRFGainVal & 0x0f)<< 15;
6307                         DBG_871X("Offset RF Gain.        reg 0xd=0x%x\n",res);
6308
6309                         rtw_hal_write_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET_CCK, RF_GAIN_OFFSET_MASK, res);
6310
6311                         res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0xe, 0xffffffff);
6312                         DBG_871X("Offset RF Gain. reg 0xe=0x%x\n",res);
6313                         res &= 0xfffffff0;
6314
6315                         res |= (padapter->eeprompriv.EEPROMRFGainVal & 0x0f);
6316                         DBG_871X("Offset RF Gain.        reg 0xe=0x%x\n",res);
6317
6318                         rtw_hal_write_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET_OFDM, RF_GAIN_OFFSET_MASK, res);
6319                 }
6320                 else
6321                 {
6322                         DBG_871X("Offset RF Gain.  padapter->eeprompriv.EEPROMRFGainVal=0x%x    != 0xff, didn't run Kfree\n",padapter->eeprompriv.EEPROMRFGainVal);
6323                 }
6324         } else {
6325                 DBG_871X("Using the default RF gain.\n");
6326         }
6327 #elif defined(CONFIG_RTL8723B)
6328         if (value & BIT4) {
6329                 DBG_871X("Offset RF Gain.\n");
6330                 DBG_871X("Offset RF Gain.  padapter->eeprompriv.EEPROMRFGainVal=0x%x\n",padapter->eeprompriv.EEPROMRFGainVal);
6331                 
6332                 if(padapter->eeprompriv.EEPROMRFGainVal != 0xff){
6333
6334                         if(pHalData->ant_path == ODM_RF_PATH_A) {
6335                                 GainValue=(padapter->eeprompriv.EEPROMRFGainVal & 0x0f);
6336                                 
6337                         } else {
6338                                 GainValue=(padapter->eeprompriv.EEPROMRFGainVal & 0xf0)>>4;
6339                         }
6340                         DBG_871X("Ant PATH_%d GainValue Offset = 0x%x\n",(pHalData->ant_path == ODM_RF_PATH_A) ? (ODM_RF_PATH_A) : (ODM_RF_PATH_B),GainValue);
6341                         
6342                         for (i = 0; i < ArrayLen; i += 2 )
6343                         {
6344                                 //DBG_871X("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x \n",i,Array[i],Array[i]+1);
6345                                 v1 = Array[i];
6346                                 v2 = Array[i+1];
6347                                  if ( v1 == GainValue ) {
6348                                                 DBG_871X("Offset RF Gain. got v1 =0x%x ,v2 =0x%x \n",v1,v2);
6349                                                 target=v2;
6350                                                 break;
6351                                  }
6352                         }        
6353                         DBG_871X("padapter->eeprompriv.EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n",padapter->eeprompriv.EEPROMRFGainVal,target);
6354
6355                         res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
6356                         DBG_871X("Offset RF Gain. before reg 0x7f=0x%08x\n",res);
6357                         PHY_SetRFReg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18|BIT17|BIT16|BIT15, target);
6358                         res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
6359
6360                         DBG_871X("Offset RF Gain. After reg 0x7f=0x%08x\n",res);
6361                         
6362                 }else {
6363
6364                         DBG_871X("Offset RF Gain.  padapter->eeprompriv.EEPROMRFGainVal=0x%x    != 0xff, didn't run Kfree\n",padapter->eeprompriv.EEPROMRFGainVal);
6365                 }
6366         } else {
6367                 DBG_871X("Using the default RF gain.\n");
6368         }
6369
6370 #elif defined(CONFIG_RTL8188E)
6371         if (value & BIT4) {
6372                 DBG_871X("8188ES Offset RF Gain.\n");
6373                 DBG_871X("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
6374                                 padapter->eeprompriv.EEPROMRFGainVal);
6375
6376                 if (padapter->eeprompriv.EEPROMRFGainVal != 0xff) {
6377                         res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
6378                                         REG_RF_BB_GAIN_OFFSET, 0xffffffff);
6379
6380                         DBG_871X("Offset RF Gain. reg 0x55=0x%x\n",res);
6381                         res &= 0xfff87fff;
6382
6383                         res |= (padapter->eeprompriv.EEPROMRFGainVal & 0x0f) << 15;
6384                         DBG_871X("Offset RF Gain. res=0x%x\n",res);
6385
6386                         rtw_hal_write_rfreg(padapter, RF_PATH_A,
6387                                         REG_RF_BB_GAIN_OFFSET,
6388                                         RF_GAIN_OFFSET_MASK, res);
6389                 } else {
6390                         DBG_871X("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
6391                                         padapter->eeprompriv.EEPROMRFGainVal);
6392                 }
6393         } else {
6394                 DBG_871X("Using the default RF gain.\n");
6395         }
6396 #else
6397         if (!(value & 0x01)) {
6398                 //DBG_871X("Offset RF Gain.\n");
6399                 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, 0xffffffff);
6400                 value &= tmp;
6401                 res = value << 14;
6402                 rtw_hal_write_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, RF_GAIN_OFFSET_MASK, res);
6403         } else {
6404                 DBG_871X("Using the default RF gain.\n");
6405         }
6406 #endif
6407         
6408 }
6409 #endif //CONFIG_RF_GAIN_OFFSET
6410
6411 //To avoid RX affect TX throughput
6412 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
6413 {
6414         struct dvobj_priv       *pdvobjpriv = adapter_to_dvobj(padapter);
6415         struct mlme_priv                *pmlmepriv = &(padapter->mlmepriv);
6416         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
6417 #ifdef CONFIG_USB_RX_AGGREGATION        
6418         if(IS_HARDWARE_TYPE_8821U(padapter) )//|| IS_HARDWARE_TYPE_8192EU(padapter))
6419         {
6420                 //This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB
6421                 if((pHalData->UsbRxAggMode == USB_RX_AGG_USB) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
6422                 {
6423                         if(pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
6424                                 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,0x1003);
6425                         else
6426                                 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,0x2005); //dmc agg th 20K
6427                         
6428                         //DBG_871X("TX_TP=%u, RX_TP=%u \n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp);
6429                 }
6430         }
6431 #endif
6432 }
6433
6434 //bus-agg check for SoftAP mode
6435 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter,u8 pre_qsel,u8 next_qsel)
6436 {
6437         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6438         u8 chk_rst = _SUCCESS;
6439         
6440         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
6441                 return chk_rst;
6442
6443         //if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) 
6444         //      return chk_rst;
6445         
6446         if(     ((pre_qsel == QSLT_HIGH)||((next_qsel== QSLT_HIGH))) 
6447                         && (pre_qsel != next_qsel )){
6448                         //DBG_871X("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n",
6449                         //      pre_qsel,next_qsel);
6450                         chk_rst = _FAIL;
6451                 }
6452         return chk_rst;
6453 }
6454
6455 /*
6456  * Description:
6457  * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
6458  * contant.
6459  *
6460  * Input:
6461  * adapter: adapter pointer.
6462  * page_num: The max. page number that user want to dump. 
6463  * page_size: page size of each page. eg. 128 bytes, 256 bytes.
6464  */
6465 void dump_TX_FIFO(_adapter* padapter, u8 page_num, u16 page_size){
6466
6467         int i;
6468         u8 val = 0;
6469         u8 base = 0;
6470         u32 addr = 0;
6471         u32 count = (page_size / 8);
6472
6473         if (page_num <= 0) {
6474                 DBG_871X("!!%s: incorrect input page_num paramter!\n", __func__);
6475                 return;
6476         }
6477
6478         if (page_size < 128 || page_size > 256) {
6479                 DBG_871X("!!%s: incorrect input page_size paramter!\n", __func__);
6480                 return;
6481         }
6482
6483         DBG_871X("+%s+\n", __func__);
6484         val = rtw_read8(padapter, 0x106);
6485         rtw_write8(padapter, 0x106, 0x69);
6486         DBG_871X("0x106: 0x%02x\n", val);
6487         base = rtw_read8(padapter, 0x209);
6488         DBG_871X("0x209: 0x%02x\n", base);
6489
6490         addr = ((base) * page_size)/8;
6491         for (i = 0 ; i < page_num * count ; i+=2) {
6492                 rtw_write32(padapter, 0x140, addr + i);
6493                 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
6494                 rtw_write32(padapter, 0x140, addr + i + 1);
6495                 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
6496         }
6497 }
6498
6499 #ifdef CONFIG_GPIO_API
6500 u8 rtw_hal_get_gpio(_adapter* adapter, u8 gpio_num)
6501 {
6502         u8 value;
6503         u8 direction;   
6504         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6505
6506         rtw_ps_deny(adapter, PS_DENY_IOCTL);
6507
6508         DBG_871X("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
6509         LeaveAllPowerSaveModeDirect(adapter);
6510
6511         /* Read GPIO Direction */
6512         direction = (rtw_read8(adapter,REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
6513
6514         /* According the direction to read register value */
6515         if( direction )
6516                 value =  (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 1)& BIT(gpio_num)) >> gpio_num;
6517         else
6518                 value =  (rtw_read8(adapter, REG_GPIO_PIN_CTRL)& BIT(gpio_num)) >> gpio_num;
6519
6520         rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
6521         DBG_871X("%s direction=%d value=%d\n",__FUNCTION__,direction,value);
6522
6523         return value;
6524 }
6525
6526 int  rtw_hal_set_gpio_output_value(_adapter* adapter, u8 gpio_num, BOOLEAN isHigh)
6527 {
6528         u8 direction = 0;
6529         u8 res = -1;
6530         if (IS_HARDWARE_TYPE_8188E(adapter)){
6531                 /* Check GPIO is 4~7 */
6532                 if( gpio_num > 7 || gpio_num < 4)
6533                 {
6534                         DBG_871X("%s The gpio number does not included 4~7.\n",__FUNCTION__);
6535                         return -1;
6536                 }
6537         }       
6538         
6539         rtw_ps_deny(adapter, PS_DENY_IOCTL);
6540
6541         LeaveAllPowerSaveModeDirect(adapter);
6542
6543         /* Read GPIO direction */
6544         direction = (rtw_read8(adapter,REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
6545
6546         /* If GPIO is output direction, setting value. */
6547         if( direction )
6548         {
6549                 if(isHigh)
6550                         rtw_write8(adapter, REG_GPIO_PIN_CTRL + 1, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 1) | BIT(gpio_num));
6551                 else
6552                         rtw_write8(adapter, REG_GPIO_PIN_CTRL + 1, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(gpio_num));
6553
6554                 DBG_871X("%s Set gpio %x[%d]=%d\n",__FUNCTION__,REG_GPIO_PIN_CTRL+1,gpio_num,isHigh );
6555                 res = 0;
6556         }
6557         else
6558         {
6559                 DBG_871X("%s The gpio is input,not be set!\n",__FUNCTION__);
6560                 res = -1;
6561         }
6562
6563         rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
6564         return res;
6565 }
6566
6567 int rtw_hal_config_gpio(_adapter* adapter, u8 gpio_num, BOOLEAN isOutput)
6568 {
6569         if (IS_HARDWARE_TYPE_8188E(adapter)){
6570                 if( gpio_num > 7 || gpio_num < 4)
6571                 {
6572                         DBG_871X("%s The gpio number does not included 4~7.\n",__FUNCTION__);
6573                         return -1;
6574                 }
6575         }       
6576
6577         DBG_871X("%s gpio_num =%d direction=%d\n",__FUNCTION__,gpio_num,isOutput);
6578
6579         rtw_ps_deny(adapter, PS_DENY_IOCTL);
6580
6581         LeaveAllPowerSaveModeDirect(adapter);
6582
6583         if( isOutput )
6584         {
6585                 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 2, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) | BIT(gpio_num));
6586         }
6587         else
6588         {
6589                 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 2, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(gpio_num));
6590         }
6591
6592         rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
6593
6594         return 0;
6595 }
6596
6597 #endif