xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8189es/hal/hal_com.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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], &GTKLegnth);
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