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