xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8189fs/hal/hal_com.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2017 Realtek Corporation.
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  *****************************************************************************/
15 #define _HAL_COM_C_
16 
17 #include <drv_types.h>
18 #include "hal_com_h2c.h"
19 
20 #include "hal_data.h"
21 
22 #ifdef RTW_HALMAC
23 #include "../../hal/hal_halmac.h"
24 #endif
25 
rtw_dump_fw_info(void * sel,_adapter * adapter)26 void rtw_dump_fw_info(void *sel, _adapter *adapter)
27 {
28 	HAL_DATA_TYPE	*hal_data = NULL;
29 
30 	if (!adapter)
31 		return;
32 
33 	hal_data = GET_HAL_DATA(adapter);
34 	if (hal_data->bFWReady)
35 		RTW_PRINT_SEL(sel, "FW VER -%d.%d\n", hal_data->firmware_version, hal_data->firmware_sub_version);
36 	else
37 		RTW_PRINT_SEL(sel, "FW not ready\n");
38 }
39 
rsvd_page_cache_update_all(struct rsvd_page_cache_t * cache,u8 loc,u8 txdesc_len,u32 page_size,u8 * info,u32 info_len)40 bool rsvd_page_cache_update_all(struct rsvd_page_cache_t *cache, u8 loc
41 	, u8 txdesc_len, u32 page_size, u8 *info, u32 info_len)
42 {
43 	u8 page_num;
44 	bool modified = 0;
45 	bool loc_mod = 0, size_mod = 0, page_num_mod = 0;
46 
47 	page_num = info_len ? (u8)PageNum(txdesc_len + info_len, page_size) : 0;
48 	if (!info_len)
49 		loc = 0;
50 
51 	if (cache->loc != loc) {
52 		RTW_INFO("%s %s loc change (%u -> %u)\n"
53 			, __func__, cache->name, cache->loc, loc);
54 		loc_mod = 1;
55 	}
56 	if (cache->size != info_len) {
57 		RTW_INFO("%s %s size change (%u -> %u)\n"
58 			, __func__, cache->name, cache->size, info_len);
59 		size_mod = 1;
60 	}
61 	if (cache->page_num != page_num) {
62 		RTW_INFO("%s %s page_num change (%u -> %u)\n"
63 			, __func__, cache->name, cache->page_num, page_num);
64 		page_num_mod = 1;
65 	}
66 
67 	if (info && info_len) {
68 		if (cache->data) {
69 			if (cache->size == info_len) {
70 				if (_rtw_memcmp(cache->data, info, info_len) != _TRUE) {
71 					RTW_INFO("%s %s data change\n", __func__, cache->name);
72 					modified = 1;
73 				}
74 			} else
75 				rsvd_page_cache_free_data(cache);
76 		}
77 
78 		if (!cache->data) {
79 			cache->data = rtw_malloc(info_len);
80 			if (!cache->data) {
81 				RTW_ERR("%s %s alloc data with size(%u) fail\n"
82 					, __func__, cache->name, info_len);
83 				rtw_warn_on(1);
84 			} else {
85 				RTW_INFO("%s %s alloc data with size(%u)\n"
86 					, __func__, cache->name, info_len);
87 			}
88 			modified = 1;
89 		}
90 
91 		if (cache->data && modified)
92 			_rtw_memcpy(cache->data, info, info_len);
93 	} else {
94 		if (cache->data && size_mod)
95 			rsvd_page_cache_free_data(cache);
96 	}
97 
98 	cache->loc = loc;
99 	cache->page_num = page_num;
100 	cache->size = info_len;
101 
102 	return modified | loc_mod | size_mod | page_num_mod;
103 }
104 
rsvd_page_cache_update_data(struct rsvd_page_cache_t * cache,u8 * info,u32 info_len)105 bool rsvd_page_cache_update_data(struct rsvd_page_cache_t *cache, u8 *info, u32 info_len)
106 {
107 	bool modified = 0;
108 
109 	if (!info || !info_len) {
110 		RTW_WARN("%s %s invalid input(info:%p, info_len:%u)\n"
111 			, __func__, cache->name, info, info_len);
112 		goto exit;
113 	}
114 
115 	if (!cache->loc || !cache->page_num || !cache->size) {
116 		RTW_ERR("%s %s layout not ready(loc:%u, page_num:%u, size:%u)\n"
117 			, __func__, cache->name, cache->loc, cache->page_num, cache->size);
118 		rtw_warn_on(1);
119 		goto exit;
120 	}
121 
122 	if (cache->size != info_len) {
123 		RTW_ERR("%s %s size(%u) differ with info_len(%u)\n"
124 			, __func__, cache->name, cache->size, info_len);
125 		rtw_warn_on(1);
126 		goto exit;
127 	}
128 
129 	if (!cache->data) {
130 		cache->data = rtw_zmalloc(cache->size);
131 		if (!cache->data) {
132 			RTW_ERR("%s %s alloc data with size(%u) fail\n"
133 				, __func__, cache->name, cache->size);
134 			rtw_warn_on(1);
135 			goto exit;
136 		} else {
137 			RTW_INFO("%s %s alloc data with size(%u)\n"
138 				, __func__, cache->name, info_len);
139 		}
140 		modified = 1;
141 	}
142 
143 	if (_rtw_memcmp(cache->data, info, cache->size) == _FALSE) {
144 		RTW_INFO("%s %s data change\n", __func__, cache->name);
145 		_rtw_memcpy(cache->data, info, cache->size);
146 		modified = 1;
147 	}
148 
149 exit:
150 	return modified;
151 }
152 
rsvd_page_cache_free_data(struct rsvd_page_cache_t * cache)153 void rsvd_page_cache_free_data(struct rsvd_page_cache_t *cache)
154 {
155 	if (cache->data) {
156 		rtw_mfree(cache->data, cache->size);
157 		cache->data = NULL;
158 	}
159 }
160 
rsvd_page_cache_free(struct rsvd_page_cache_t * cache)161 void rsvd_page_cache_free(struct rsvd_page_cache_t *cache)
162 {
163 	cache->loc = 0;
164 	cache->page_num = 0;
165 	rsvd_page_cache_free_data(cache);
166 	cache->size = 0;
167 }
168 
169 /* #define CONFIG_GTK_OL_DBG */
170 
171 /*#define DBG_SEC_CAM_MOVE*/
172 #ifdef DBG_SEC_CAM_MOVE
rtw_hal_move_sta_gk_to_dk(_adapter * adapter)173 void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
174 {
175 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
176 	int cam_id, index = 0;
177 	u8 *addr = NULL;
178 
179 	if (!MLME_IS_STA(adapter))
180 		return;
181 
182 	addr = get_bssid(pmlmepriv);
183 
184 	if (addr == NULL) {
185 		RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
186 		return;
187 	}
188 
189 	rtw_clean_dk_section(adapter);
190 
191 	do {
192 		cam_id = rtw_camid_search(adapter, addr, index, 1);
193 
194 		if (cam_id == -1)
195 			RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
196 		else
197 			rtw_sec_cam_swap(adapter, cam_id, index);
198 
199 		index++;
200 	} while (index < 4);
201 
202 }
203 
rtw_hal_read_sta_dk_key(_adapter * adapter,u8 key_id)204 void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
205 {
206 	struct security_priv *psecuritypriv = &adapter->securitypriv;
207 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
208 	struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
209 	_irqL irqL;
210 	u8 get_key[16];
211 
212 	_rtw_memset(get_key, 0, sizeof(get_key));
213 
214 	if (key_id > 4) {
215 		RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
216 		rtw_warn_on(1);
217 		return;
218 	}
219 	rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
220 
221 	/*update key into related sw variable*/
222 	_enter_critical_bh(&cam_ctl->lock, &irqL);
223 	if (_rtw_camid_is_gk(adapter, key_id)) {
224 		RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
225 		RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
226 	}
227 	_exit_critical_bh(&cam_ctl->lock, &irqL);
228 
229 }
230 #endif
231 
232 
233 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
234 	char	rtw_phy_para_file_path[PATH_LENGTH_MAX];
235 #endif
236 
dump_chip_info(HAL_VERSION ChipVersion)237 void dump_chip_info(HAL_VERSION	ChipVersion)
238 {
239 	int cnt = 0;
240 	u8 buf[128] = {0};
241 
242 	if (IS_8188E(ChipVersion))
243 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
244 	else if (IS_8188F(ChipVersion))
245 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
246 	else if (IS_8188GTV(ChipVersion))
247 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188GTV_");
248 	else if (IS_8812_SERIES(ChipVersion))
249 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
250 	else if (IS_8192E(ChipVersion))
251 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
252 	else if (IS_8821_SERIES(ChipVersion))
253 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
254 	else if (IS_8723B_SERIES(ChipVersion))
255 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
256 	else if (IS_8703B_SERIES(ChipVersion))
257 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
258 	else if (IS_8723D_SERIES(ChipVersion))
259 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
260 	else if (IS_8814A_SERIES(ChipVersion))
261 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
262 	else if (IS_8822B_SERIES(ChipVersion))
263 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
264 	else if (IS_8821C_SERIES(ChipVersion))
265 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
266 	else if (IS_8710B_SERIES(ChipVersion))
267 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8710B_");
268 	else if (IS_8192F_SERIES(ChipVersion))
269 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192F_");
270 	else if (IS_8822C_SERIES(ChipVersion))
271 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822C_");
272 	else
273 		cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
274 
275 	cnt += sprintf((buf + cnt), "%s", IS_NORMAL_CHIP(ChipVersion) ? "" : "T_");
276 
277 	if (IS_CHIP_VENDOR_TSMC(ChipVersion))
278 		cnt += sprintf((buf + cnt), "%s", "T");
279 	else if (IS_CHIP_VENDOR_UMC(ChipVersion))
280 		cnt += sprintf((buf + cnt), "%s", "U");
281 	else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
282 		cnt += sprintf((buf + cnt), "%s", "S");
283 
284 	if (IS_A_CUT(ChipVersion))
285 		cnt += sprintf((buf + cnt), "1_");
286 	else if (IS_B_CUT(ChipVersion))
287 		cnt += sprintf((buf + cnt), "2_");
288 	else if (IS_C_CUT(ChipVersion))
289 		cnt += sprintf((buf + cnt), "3_");
290 	else if (IS_D_CUT(ChipVersion))
291 		cnt += sprintf((buf + cnt), "4_");
292 	else if (IS_E_CUT(ChipVersion))
293 		cnt += sprintf((buf + cnt), "5_");
294 	else if (IS_F_CUT(ChipVersion))
295 		cnt += sprintf((buf + cnt), "6_");
296 	else if (IS_I_CUT(ChipVersion))
297 		cnt += sprintf((buf + cnt), "9_");
298 	else if (IS_J_CUT(ChipVersion))
299 		cnt += sprintf((buf + cnt), "10_");
300 	else if (IS_K_CUT(ChipVersion))
301 		cnt += sprintf((buf + cnt), "11_");
302 	else
303 		cnt += sprintf((buf + cnt), "UNKNOWN_Cv(%d)_", ChipVersion.CUTVersion);
304 
305 	if (IS_1T1R(ChipVersion))
306 		cnt += sprintf((buf + cnt), "1T1R_");
307 	else if (IS_1T2R(ChipVersion))
308 		cnt += sprintf((buf + cnt), "1T2R_");
309 	else if (IS_2T2R(ChipVersion))
310 		cnt += sprintf((buf + cnt), "2T2R_");
311 	else if (IS_3T3R(ChipVersion))
312 		cnt += sprintf((buf + cnt), "3T3R_");
313 	else if (IS_3T4R(ChipVersion))
314 		cnt += sprintf((buf + cnt), "3T4R_");
315 	else if (IS_4T4R(ChipVersion))
316 		cnt += sprintf((buf + cnt), "4T4R_");
317 	else
318 		cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
319 
320 	cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
321 
322 	RTW_INFO("%s", buf);
323 }
324 
rtw_hal_get_port(_adapter * adapter)325 u8 rtw_hal_get_port(_adapter *adapter)
326 {
327 	u8 hw_port = get_hw_port(adapter);
328 #ifdef CONFIG_CLIENT_PORT_CFG
329 	u8 clt_port = get_clt_port(adapter);
330 
331 	if (clt_port)
332 		hw_port = clt_port;
333 
334 #ifdef DBG_HW_PORT
335 	if (MLME_IS_STA(adapter) && (adapter->client_id != MAX_CLIENT_PORT_NUM)) {
336 		if(hw_port == CLT_PORT_INVALID) {
337 			RTW_ERR(ADPT_FMT" @@@@@ Client port == 0 @@@@@\n", ADPT_ARG(adapter));
338 			rtw_warn_on(1);
339 		}
340 	}
341 	#ifdef CONFIG_AP_MODE
342 	else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
343 		if (hw_port != HW_PORT0) {
344 			RTW_ERR(ADPT_FMT" @@@@@ AP / MESH port != 0 @@@@@\n", ADPT_ARG(adapter));
345 			rtw_warn_on(1);
346 		}
347 	}
348 	#endif
349 	if (0)
350 		RTW_INFO(ADPT_FMT" - HP:%d,CP:%d\n", ADPT_ARG(adapter), get_hw_port(adapter), get_clt_port(adapter));
351 #endif /*DBG_HW_PORT*/
352 
353 #endif/*CONFIG_CLIENT_PORT_CFG*/
354 
355 	return hw_port;
356 }
357 
358 #define	EEPROM_CHANNEL_PLAN_BY_HW_MASK	0x80
359 
360 /*
361  * Description:
362  *	Use hardware(efuse), driver parameter(registry) and default channel plan
363  *	to decide which one should be used.
364  *
365  * Parameters:
366  *	padapter			pointer of adapter
367  *	hw_alpha2		country code from HW (efuse/eeprom/mapfile)
368  *	hw_chplan		channel plan from HW (efuse/eeprom/mapfile)
369  *						BIT[7] software configure mode; 0:Enable, 1:disable
370  *						BIT[6:0] Channel Plan
371  *	sw_alpha2		country code from HW (registry/module param)
372  *	sw_chplan		channel plan from SW (registry/module param)
373  *	AutoLoadFail		efuse autoload fail or not
374  *
375  */
hal_com_config_channel_plan(PADAPTER padapter,char * hw_alpha2,u8 hw_chplan,char * sw_alpha2,u8 sw_chplan,BOOLEAN AutoLoadFail)376 void hal_com_config_channel_plan(
377 		PADAPTER padapter,
378 		char *hw_alpha2,
379 		u8 hw_chplan,
380 		char *sw_alpha2,
381 		u8 sw_chplan,
382 		BOOLEAN AutoLoadFail
383 )
384 {
385 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
386 	PHAL_DATA_TYPE	pHalData;
387 	u8 force_hw_chplan = _FALSE;
388 	int chplan = -1;
389 	const struct country_chplan *country_ent = NULL, *ent;
390 	u8 def_chplan = 0x7F; /* Realtek define,  used when HW, SW both invalid */
391 
392 	pHalData = GET_HAL_DATA(padapter);
393 
394 	/* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
395 	if (hw_chplan == 0xFF)
396 		goto chk_hw_country_code;
397 
398 	if (AutoLoadFail == _TRUE)
399 		goto chk_sw_config;
400 
401 #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
402 	if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
403 		force_hw_chplan = _TRUE;
404 #endif
405 
406 	hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
407 
408 chk_hw_country_code:
409 	if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
410 		ent = rtw_get_chplan_from_country(hw_alpha2);
411 		if (ent) {
412 			/* get chplan from hw country code, by pass hw chplan setting */
413 			country_ent = ent;
414 			chplan = ent->chplan;
415 			goto chk_sw_config;
416 		} else
417 			RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
418 	}
419 
420 	if (rtw_is_channel_plan_valid(hw_chplan))
421 		chplan = hw_chplan;
422 	else if (force_hw_chplan == _TRUE) {
423 		RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
424 		/* hw infomaton invalid, refer to sw information */
425 		force_hw_chplan = _FALSE;
426 	}
427 
428 chk_sw_config:
429 	if (force_hw_chplan == _TRUE)
430 		goto done;
431 
432 	if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
433 		ent = rtw_get_chplan_from_country(sw_alpha2);
434 		if (ent) {
435 			/* get chplan from sw country code, by pass sw chplan setting */
436 			country_ent = ent;
437 			chplan = ent->chplan;
438 			goto done;
439 		} else
440 			RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
441 	}
442 
443 	if (rtw_is_channel_plan_valid(sw_chplan)) {
444 		/* cancel hw_alpha2 because chplan is specified by sw_chplan*/
445 		country_ent = NULL;
446 		chplan = sw_chplan;
447 	} else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)
448 		RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
449 
450 done:
451 	if (chplan == -1) {
452 		RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
453 		chplan = def_chplan;
454 	} else if (country_ent) {
455 		RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
456 			, country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
457 	} else
458 		RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
459 
460 	rfctl->country_ent = country_ent;
461 	rfctl->ChannelPlan = chplan;
462 	pHalData->bDisableSWChannelPlan = force_hw_chplan;
463 }
464 
465 BOOLEAN
HAL_IsLegalChannel(PADAPTER Adapter,u32 Channel)466 HAL_IsLegalChannel(
467 		PADAPTER	Adapter,
468 		u32			Channel
469 )
470 {
471 	BOOLEAN bLegalChannel = _TRUE;
472 
473 	if (Channel > 14) {
474 		if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
475 			bLegalChannel = _FALSE;
476 			RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
477 		}
478 	} else if ((Channel <= 14) && (Channel >= 1)) {
479 		if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
480 			bLegalChannel = _FALSE;
481 			RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
482 		}
483 	} else {
484 		bLegalChannel = _FALSE;
485 		RTW_INFO("Channel is Invalid !!!\n");
486 	}
487 
488 	return bLegalChannel;
489 }
490 
MRateToHwRate(u8 rate)491 u8	MRateToHwRate(u8 rate)
492 {
493 	u8	ret = DESC_RATE1M;
494 
495 	switch (rate) {
496 	case MGN_1M:
497 		ret = DESC_RATE1M;
498 		break;
499 	case MGN_2M:
500 		ret = DESC_RATE2M;
501 		break;
502 	case MGN_5_5M:
503 		ret = DESC_RATE5_5M;
504 		break;
505 	case MGN_11M:
506 		ret = DESC_RATE11M;
507 		break;
508 	case MGN_6M:
509 		ret = DESC_RATE6M;
510 		break;
511 	case MGN_9M:
512 		ret = DESC_RATE9M;
513 		break;
514 	case MGN_12M:
515 		ret = DESC_RATE12M;
516 		break;
517 	case MGN_18M:
518 		ret = DESC_RATE18M;
519 		break;
520 	case MGN_24M:
521 		ret = DESC_RATE24M;
522 		break;
523 	case MGN_36M:
524 		ret = DESC_RATE36M;
525 		break;
526 	case MGN_48M:
527 		ret = DESC_RATE48M;
528 		break;
529 	case MGN_54M:
530 		ret = DESC_RATE54M;
531 		break;
532 
533 	case MGN_MCS0:
534 		ret = DESC_RATEMCS0;
535 		break;
536 	case MGN_MCS1:
537 		ret = DESC_RATEMCS1;
538 		break;
539 	case MGN_MCS2:
540 		ret = DESC_RATEMCS2;
541 		break;
542 	case MGN_MCS3:
543 		ret = DESC_RATEMCS3;
544 		break;
545 	case MGN_MCS4:
546 		ret = DESC_RATEMCS4;
547 		break;
548 	case MGN_MCS5:
549 		ret = DESC_RATEMCS5;
550 		break;
551 	case MGN_MCS6:
552 		ret = DESC_RATEMCS6;
553 		break;
554 	case MGN_MCS7:
555 		ret = DESC_RATEMCS7;
556 		break;
557 	case MGN_MCS8:
558 		ret = DESC_RATEMCS8;
559 		break;
560 	case MGN_MCS9:
561 		ret = DESC_RATEMCS9;
562 		break;
563 	case MGN_MCS10:
564 		ret = DESC_RATEMCS10;
565 		break;
566 	case MGN_MCS11:
567 		ret = DESC_RATEMCS11;
568 		break;
569 	case MGN_MCS12:
570 		ret = DESC_RATEMCS12;
571 		break;
572 	case MGN_MCS13:
573 		ret = DESC_RATEMCS13;
574 		break;
575 	case MGN_MCS14:
576 		ret = DESC_RATEMCS14;
577 		break;
578 	case MGN_MCS15:
579 		ret = DESC_RATEMCS15;
580 		break;
581 	case MGN_MCS16:
582 		ret = DESC_RATEMCS16;
583 		break;
584 	case MGN_MCS17:
585 		ret = DESC_RATEMCS17;
586 		break;
587 	case MGN_MCS18:
588 		ret = DESC_RATEMCS18;
589 		break;
590 	case MGN_MCS19:
591 		ret = DESC_RATEMCS19;
592 		break;
593 	case MGN_MCS20:
594 		ret = DESC_RATEMCS20;
595 		break;
596 	case MGN_MCS21:
597 		ret = DESC_RATEMCS21;
598 		break;
599 	case MGN_MCS22:
600 		ret = DESC_RATEMCS22;
601 		break;
602 	case MGN_MCS23:
603 		ret = DESC_RATEMCS23;
604 		break;
605 	case MGN_MCS24:
606 		ret = DESC_RATEMCS24;
607 		break;
608 	case MGN_MCS25:
609 		ret = DESC_RATEMCS25;
610 		break;
611 	case MGN_MCS26:
612 		ret = DESC_RATEMCS26;
613 		break;
614 	case MGN_MCS27:
615 		ret = DESC_RATEMCS27;
616 		break;
617 	case MGN_MCS28:
618 		ret = DESC_RATEMCS28;
619 		break;
620 	case MGN_MCS29:
621 		ret = DESC_RATEMCS29;
622 		break;
623 	case MGN_MCS30:
624 		ret = DESC_RATEMCS30;
625 		break;
626 	case MGN_MCS31:
627 		ret = DESC_RATEMCS31;
628 		break;
629 
630 	case MGN_VHT1SS_MCS0:
631 		ret = DESC_RATEVHTSS1MCS0;
632 		break;
633 	case MGN_VHT1SS_MCS1:
634 		ret = DESC_RATEVHTSS1MCS1;
635 		break;
636 	case MGN_VHT1SS_MCS2:
637 		ret = DESC_RATEVHTSS1MCS2;
638 		break;
639 	case MGN_VHT1SS_MCS3:
640 		ret = DESC_RATEVHTSS1MCS3;
641 		break;
642 	case MGN_VHT1SS_MCS4:
643 		ret = DESC_RATEVHTSS1MCS4;
644 		break;
645 	case MGN_VHT1SS_MCS5:
646 		ret = DESC_RATEVHTSS1MCS5;
647 		break;
648 	case MGN_VHT1SS_MCS6:
649 		ret = DESC_RATEVHTSS1MCS6;
650 		break;
651 	case MGN_VHT1SS_MCS7:
652 		ret = DESC_RATEVHTSS1MCS7;
653 		break;
654 	case MGN_VHT1SS_MCS8:
655 		ret = DESC_RATEVHTSS1MCS8;
656 		break;
657 	case MGN_VHT1SS_MCS9:
658 		ret = DESC_RATEVHTSS1MCS9;
659 		break;
660 	case MGN_VHT2SS_MCS0:
661 		ret = DESC_RATEVHTSS2MCS0;
662 		break;
663 	case MGN_VHT2SS_MCS1:
664 		ret = DESC_RATEVHTSS2MCS1;
665 		break;
666 	case MGN_VHT2SS_MCS2:
667 		ret = DESC_RATEVHTSS2MCS2;
668 		break;
669 	case MGN_VHT2SS_MCS3:
670 		ret = DESC_RATEVHTSS2MCS3;
671 		break;
672 	case MGN_VHT2SS_MCS4:
673 		ret = DESC_RATEVHTSS2MCS4;
674 		break;
675 	case MGN_VHT2SS_MCS5:
676 		ret = DESC_RATEVHTSS2MCS5;
677 		break;
678 	case MGN_VHT2SS_MCS6:
679 		ret = DESC_RATEVHTSS2MCS6;
680 		break;
681 	case MGN_VHT2SS_MCS7:
682 		ret = DESC_RATEVHTSS2MCS7;
683 		break;
684 	case MGN_VHT2SS_MCS8:
685 		ret = DESC_RATEVHTSS2MCS8;
686 		break;
687 	case MGN_VHT2SS_MCS9:
688 		ret = DESC_RATEVHTSS2MCS9;
689 		break;
690 	case MGN_VHT3SS_MCS0:
691 		ret = DESC_RATEVHTSS3MCS0;
692 		break;
693 	case MGN_VHT3SS_MCS1:
694 		ret = DESC_RATEVHTSS3MCS1;
695 		break;
696 	case MGN_VHT3SS_MCS2:
697 		ret = DESC_RATEVHTSS3MCS2;
698 		break;
699 	case MGN_VHT3SS_MCS3:
700 		ret = DESC_RATEVHTSS3MCS3;
701 		break;
702 	case MGN_VHT3SS_MCS4:
703 		ret = DESC_RATEVHTSS3MCS4;
704 		break;
705 	case MGN_VHT3SS_MCS5:
706 		ret = DESC_RATEVHTSS3MCS5;
707 		break;
708 	case MGN_VHT3SS_MCS6:
709 		ret = DESC_RATEVHTSS3MCS6;
710 		break;
711 	case MGN_VHT3SS_MCS7:
712 		ret = DESC_RATEVHTSS3MCS7;
713 		break;
714 	case MGN_VHT3SS_MCS8:
715 		ret = DESC_RATEVHTSS3MCS8;
716 		break;
717 	case MGN_VHT3SS_MCS9:
718 		ret = DESC_RATEVHTSS3MCS9;
719 		break;
720 	case MGN_VHT4SS_MCS0:
721 		ret = DESC_RATEVHTSS4MCS0;
722 		break;
723 	case MGN_VHT4SS_MCS1:
724 		ret = DESC_RATEVHTSS4MCS1;
725 		break;
726 	case MGN_VHT4SS_MCS2:
727 		ret = DESC_RATEVHTSS4MCS2;
728 		break;
729 	case MGN_VHT4SS_MCS3:
730 		ret = DESC_RATEVHTSS4MCS3;
731 		break;
732 	case MGN_VHT4SS_MCS4:
733 		ret = DESC_RATEVHTSS4MCS4;
734 		break;
735 	case MGN_VHT4SS_MCS5:
736 		ret = DESC_RATEVHTSS4MCS5;
737 		break;
738 	case MGN_VHT4SS_MCS6:
739 		ret = DESC_RATEVHTSS4MCS6;
740 		break;
741 	case MGN_VHT4SS_MCS7:
742 		ret = DESC_RATEVHTSS4MCS7;
743 		break;
744 	case MGN_VHT4SS_MCS8:
745 		ret = DESC_RATEVHTSS4MCS8;
746 		break;
747 	case MGN_VHT4SS_MCS9:
748 		ret = DESC_RATEVHTSS4MCS9;
749 		break;
750 	default:
751 		break;
752 	}
753 
754 	return ret;
755 }
756 
hw_rate_to_m_rate(u8 rate)757 u8	hw_rate_to_m_rate(u8 rate)
758 {
759 	u8	ret_rate = MGN_1M;
760 
761 	switch (rate) {
762 
763 	case DESC_RATE1M:
764 		ret_rate = MGN_1M;
765 		break;
766 	case DESC_RATE2M:
767 		ret_rate = MGN_2M;
768 		break;
769 	case DESC_RATE5_5M:
770 		ret_rate = MGN_5_5M;
771 		break;
772 	case DESC_RATE11M:
773 		ret_rate = MGN_11M;
774 		break;
775 	case DESC_RATE6M:
776 		ret_rate = MGN_6M;
777 		break;
778 	case DESC_RATE9M:
779 		ret_rate = MGN_9M;
780 		break;
781 	case DESC_RATE12M:
782 		ret_rate = MGN_12M;
783 		break;
784 	case DESC_RATE18M:
785 		ret_rate = MGN_18M;
786 		break;
787 	case DESC_RATE24M:
788 		ret_rate = MGN_24M;
789 		break;
790 	case DESC_RATE36M:
791 		ret_rate = MGN_36M;
792 		break;
793 	case DESC_RATE48M:
794 		ret_rate = MGN_48M;
795 		break;
796 	case DESC_RATE54M:
797 		ret_rate = MGN_54M;
798 		break;
799 	case DESC_RATEMCS0:
800 		ret_rate = MGN_MCS0;
801 		break;
802 	case DESC_RATEMCS1:
803 		ret_rate = MGN_MCS1;
804 		break;
805 	case DESC_RATEMCS2:
806 		ret_rate = MGN_MCS2;
807 		break;
808 	case DESC_RATEMCS3:
809 		ret_rate = MGN_MCS3;
810 		break;
811 	case DESC_RATEMCS4:
812 		ret_rate = MGN_MCS4;
813 		break;
814 	case DESC_RATEMCS5:
815 		ret_rate = MGN_MCS5;
816 		break;
817 	case DESC_RATEMCS6:
818 		ret_rate = MGN_MCS6;
819 		break;
820 	case DESC_RATEMCS7:
821 		ret_rate = MGN_MCS7;
822 		break;
823 	case DESC_RATEMCS8:
824 		ret_rate = MGN_MCS8;
825 		break;
826 	case DESC_RATEMCS9:
827 		ret_rate = MGN_MCS9;
828 		break;
829 	case DESC_RATEMCS10:
830 		ret_rate = MGN_MCS10;
831 		break;
832 	case DESC_RATEMCS11:
833 		ret_rate = MGN_MCS11;
834 		break;
835 	case DESC_RATEMCS12:
836 		ret_rate = MGN_MCS12;
837 		break;
838 	case DESC_RATEMCS13:
839 		ret_rate = MGN_MCS13;
840 		break;
841 	case DESC_RATEMCS14:
842 		ret_rate = MGN_MCS14;
843 		break;
844 	case DESC_RATEMCS15:
845 		ret_rate = MGN_MCS15;
846 		break;
847 	case DESC_RATEMCS16:
848 		ret_rate = MGN_MCS16;
849 		break;
850 	case DESC_RATEMCS17:
851 		ret_rate = MGN_MCS17;
852 		break;
853 	case DESC_RATEMCS18:
854 		ret_rate = MGN_MCS18;
855 		break;
856 	case DESC_RATEMCS19:
857 		ret_rate = MGN_MCS19;
858 		break;
859 	case DESC_RATEMCS20:
860 		ret_rate = MGN_MCS20;
861 		break;
862 	case DESC_RATEMCS21:
863 		ret_rate = MGN_MCS21;
864 		break;
865 	case DESC_RATEMCS22:
866 		ret_rate = MGN_MCS22;
867 		break;
868 	case DESC_RATEMCS23:
869 		ret_rate = MGN_MCS23;
870 		break;
871 	case DESC_RATEMCS24:
872 		ret_rate = MGN_MCS24;
873 		break;
874 	case DESC_RATEMCS25:
875 		ret_rate = MGN_MCS25;
876 		break;
877 	case DESC_RATEMCS26:
878 		ret_rate = MGN_MCS26;
879 		break;
880 	case DESC_RATEMCS27:
881 		ret_rate = MGN_MCS27;
882 		break;
883 	case DESC_RATEMCS28:
884 		ret_rate = MGN_MCS28;
885 		break;
886 	case DESC_RATEMCS29:
887 		ret_rate = MGN_MCS29;
888 		break;
889 	case DESC_RATEMCS30:
890 		ret_rate = MGN_MCS30;
891 		break;
892 	case DESC_RATEMCS31:
893 		ret_rate = MGN_MCS31;
894 		break;
895 	case DESC_RATEVHTSS1MCS0:
896 		ret_rate = MGN_VHT1SS_MCS0;
897 		break;
898 	case DESC_RATEVHTSS1MCS1:
899 		ret_rate = MGN_VHT1SS_MCS1;
900 		break;
901 	case DESC_RATEVHTSS1MCS2:
902 		ret_rate = MGN_VHT1SS_MCS2;
903 		break;
904 	case DESC_RATEVHTSS1MCS3:
905 		ret_rate = MGN_VHT1SS_MCS3;
906 		break;
907 	case DESC_RATEVHTSS1MCS4:
908 		ret_rate = MGN_VHT1SS_MCS4;
909 		break;
910 	case DESC_RATEVHTSS1MCS5:
911 		ret_rate = MGN_VHT1SS_MCS5;
912 		break;
913 	case DESC_RATEVHTSS1MCS6:
914 		ret_rate = MGN_VHT1SS_MCS6;
915 		break;
916 	case DESC_RATEVHTSS1MCS7:
917 		ret_rate = MGN_VHT1SS_MCS7;
918 		break;
919 	case DESC_RATEVHTSS1MCS8:
920 		ret_rate = MGN_VHT1SS_MCS8;
921 		break;
922 	case DESC_RATEVHTSS1MCS9:
923 		ret_rate = MGN_VHT1SS_MCS9;
924 		break;
925 	case DESC_RATEVHTSS2MCS0:
926 		ret_rate = MGN_VHT2SS_MCS0;
927 		break;
928 	case DESC_RATEVHTSS2MCS1:
929 		ret_rate = MGN_VHT2SS_MCS1;
930 		break;
931 	case DESC_RATEVHTSS2MCS2:
932 		ret_rate = MGN_VHT2SS_MCS2;
933 		break;
934 	case DESC_RATEVHTSS2MCS3:
935 		ret_rate = MGN_VHT2SS_MCS3;
936 		break;
937 	case DESC_RATEVHTSS2MCS4:
938 		ret_rate = MGN_VHT2SS_MCS4;
939 		break;
940 	case DESC_RATEVHTSS2MCS5:
941 		ret_rate = MGN_VHT2SS_MCS5;
942 		break;
943 	case DESC_RATEVHTSS2MCS6:
944 		ret_rate = MGN_VHT2SS_MCS6;
945 		break;
946 	case DESC_RATEVHTSS2MCS7:
947 		ret_rate = MGN_VHT2SS_MCS7;
948 		break;
949 	case DESC_RATEVHTSS2MCS8:
950 		ret_rate = MGN_VHT2SS_MCS8;
951 		break;
952 	case DESC_RATEVHTSS2MCS9:
953 		ret_rate = MGN_VHT2SS_MCS9;
954 		break;
955 	case DESC_RATEVHTSS3MCS0:
956 		ret_rate = MGN_VHT3SS_MCS0;
957 		break;
958 	case DESC_RATEVHTSS3MCS1:
959 		ret_rate = MGN_VHT3SS_MCS1;
960 		break;
961 	case DESC_RATEVHTSS3MCS2:
962 		ret_rate = MGN_VHT3SS_MCS2;
963 		break;
964 	case DESC_RATEVHTSS3MCS3:
965 		ret_rate = MGN_VHT3SS_MCS3;
966 		break;
967 	case DESC_RATEVHTSS3MCS4:
968 		ret_rate = MGN_VHT3SS_MCS4;
969 		break;
970 	case DESC_RATEVHTSS3MCS5:
971 		ret_rate = MGN_VHT3SS_MCS5;
972 		break;
973 	case DESC_RATEVHTSS3MCS6:
974 		ret_rate = MGN_VHT3SS_MCS6;
975 		break;
976 	case DESC_RATEVHTSS3MCS7:
977 		ret_rate = MGN_VHT3SS_MCS7;
978 		break;
979 	case DESC_RATEVHTSS3MCS8:
980 		ret_rate = MGN_VHT3SS_MCS8;
981 		break;
982 	case DESC_RATEVHTSS3MCS9:
983 		ret_rate = MGN_VHT3SS_MCS9;
984 		break;
985 	case DESC_RATEVHTSS4MCS0:
986 		ret_rate = MGN_VHT4SS_MCS0;
987 		break;
988 	case DESC_RATEVHTSS4MCS1:
989 		ret_rate = MGN_VHT4SS_MCS1;
990 		break;
991 	case DESC_RATEVHTSS4MCS2:
992 		ret_rate = MGN_VHT4SS_MCS2;
993 		break;
994 	case DESC_RATEVHTSS4MCS3:
995 		ret_rate = MGN_VHT4SS_MCS3;
996 		break;
997 	case DESC_RATEVHTSS4MCS4:
998 		ret_rate = MGN_VHT4SS_MCS4;
999 		break;
1000 	case DESC_RATEVHTSS4MCS5:
1001 		ret_rate = MGN_VHT4SS_MCS5;
1002 		break;
1003 	case DESC_RATEVHTSS4MCS6:
1004 		ret_rate = MGN_VHT4SS_MCS6;
1005 		break;
1006 	case DESC_RATEVHTSS4MCS7:
1007 		ret_rate = MGN_VHT4SS_MCS7;
1008 		break;
1009 	case DESC_RATEVHTSS4MCS8:
1010 		ret_rate = MGN_VHT4SS_MCS8;
1011 		break;
1012 	case DESC_RATEVHTSS4MCS9:
1013 		ret_rate = MGN_VHT4SS_MCS9;
1014 		break;
1015 
1016 	default:
1017 		RTW_INFO("hw_rate_to_m_rate(): Non supported Rate [%x]!!!\n", rate);
1018 		break;
1019 	}
1020 
1021 	return ret_rate;
1022 }
1023 
HalSetBrateCfg(PADAPTER Adapter,u8 * mBratesOS,u16 * pBrateCfg)1024 void	HalSetBrateCfg(
1025 	PADAPTER		Adapter,
1026 	u8			*mBratesOS,
1027 	u16			*pBrateCfg)
1028 {
1029 	u8	i, is_brate, brate;
1030 
1031 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
1032 		is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
1033 		brate = mBratesOS[i] & 0x7f;
1034 
1035 		if (is_brate) {
1036 			switch (brate) {
1037 			case IEEE80211_CCK_RATE_1MB:
1038 				*pBrateCfg |= RATE_1M;
1039 				break;
1040 			case IEEE80211_CCK_RATE_2MB:
1041 				*pBrateCfg |= RATE_2M;
1042 				break;
1043 			case IEEE80211_CCK_RATE_5MB:
1044 				*pBrateCfg |= RATE_5_5M;
1045 				break;
1046 			case IEEE80211_CCK_RATE_11MB:
1047 				*pBrateCfg |= RATE_11M;
1048 				break;
1049 			case IEEE80211_OFDM_RATE_6MB:
1050 				*pBrateCfg |= RATE_6M;
1051 				break;
1052 			case IEEE80211_OFDM_RATE_9MB:
1053 				*pBrateCfg |= RATE_9M;
1054 				break;
1055 			case IEEE80211_OFDM_RATE_12MB:
1056 				*pBrateCfg |= RATE_12M;
1057 				break;
1058 			case IEEE80211_OFDM_RATE_18MB:
1059 				*pBrateCfg |= RATE_18M;
1060 				break;
1061 			case IEEE80211_OFDM_RATE_24MB:
1062 				*pBrateCfg |= RATE_24M;
1063 				break;
1064 			case IEEE80211_OFDM_RATE_36MB:
1065 				*pBrateCfg |= RATE_36M;
1066 				break;
1067 			case IEEE80211_OFDM_RATE_48MB:
1068 				*pBrateCfg |= RATE_48M;
1069 				break;
1070 			case IEEE80211_OFDM_RATE_54MB:
1071 				*pBrateCfg |= RATE_54M;
1072 				break;
1073 			}
1074 		}
1075 	}
1076 }
1077 
1078 static void
_OneOutPipeMapping(PADAPTER pAdapter)1079 _OneOutPipeMapping(
1080 		PADAPTER	pAdapter
1081 )
1082 {
1083 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
1084 
1085 	pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1086 	pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1087 	pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
1088 	pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
1089 
1090 	pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1091 	pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1092 	pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1093 	pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1094 }
1095 
1096 static void
_TwoOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)1097 _TwoOutPipeMapping(
1098 		PADAPTER	pAdapter,
1099 		BOOLEAN		bWIFICfg
1100 )
1101 {
1102 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
1103 
1104 	if (bWIFICfg) { /* WMM */
1105 
1106 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1107 		/* {  0, 	1, 	0, 	1, 	0, 	0, 	0, 	0, 		0	}; */
1108 		/* 0:ep_0 num, 1:ep_1 num */
1109 
1110 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
1111 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1112 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
1113 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
1114 
1115 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1116 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1117 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1118 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1119 
1120 	} else { /* typical setting */
1121 
1122 
1123 		/* BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA */
1124 		/* {  1, 	1, 	0, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
1125 		/* 0:ep_0 num, 1:ep_1 num */
1126 
1127 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1128 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1129 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
1130 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1131 
1132 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1133 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1134 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1135 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
1136 
1137 	}
1138 
1139 }
1140 
_ThreeOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)1141 static void _ThreeOutPipeMapping(
1142 		PADAPTER	pAdapter,
1143 		BOOLEAN		bWIFICfg
1144 )
1145 {
1146 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
1147 
1148 	if (bWIFICfg) { /* for WMM */
1149 
1150 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1151 		/* {  1, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	}; */
1152 		/* 0:H, 1:N, 2:L */
1153 
1154 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1155 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1156 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1157 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1158 
1159 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1160 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1161 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1162 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1163 
1164 	} else { /* typical setting */
1165 
1166 
1167 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1168 		/* {  2, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
1169 		/* 0:H, 1:N, 2:L */
1170 
1171 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1172 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1173 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1174 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1175 
1176 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1177 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1178 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1179 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
1180 	}
1181 
1182 }
1183 #if 0
1184 static void _FourOutPipeMapping(
1185 		PADAPTER	pAdapter,
1186 		BOOLEAN		bWIFICfg
1187 )
1188 {
1189 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(pAdapter);
1190 
1191 	if (bWIFICfg) { /* for WMM */
1192 
1193 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1194 		/* {  1, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	}; */
1195 		/* 0:H, 1:N, 2:L ,3:E */
1196 
1197 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1198 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1199 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1200 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1201 
1202 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1203 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1204 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1205 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1206 
1207 	} else { /* typical setting */
1208 
1209 
1210 		/*	BK, 	BE, 	VI, 	VO, 	BCN,	CMD,MGT,HIGH,HCCA  */
1211 		/* {  2, 	2, 	1, 	0, 	0, 	0, 	0, 	0, 		0	};			 */
1212 		/* 0:H, 1:N, 2:L */
1213 
1214 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1215 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1216 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1217 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1218 
1219 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1220 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1221 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1222 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD	 */
1223 	}
1224 
1225 }
1226 #endif
1227 BOOLEAN
Hal_MappingOutPipe(PADAPTER pAdapter,u8 NumOutPipe)1228 Hal_MappingOutPipe(
1229 		PADAPTER	pAdapter,
1230 		u8		NumOutPipe
1231 )
1232 {
1233 	struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
1234 
1235 	BOOLEAN	 bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
1236 
1237 	BOOLEAN result = _TRUE;
1238 
1239 	switch (NumOutPipe) {
1240 	case 2:
1241 		_TwoOutPipeMapping(pAdapter, bWIFICfg);
1242 		break;
1243 	case 3:
1244 	case 4:
1245 	case 5:
1246 	case 6:
1247 		_ThreeOutPipeMapping(pAdapter, bWIFICfg);
1248 		break;
1249 	case 1:
1250 		_OneOutPipeMapping(pAdapter);
1251 		break;
1252 	default:
1253 		result = _FALSE;
1254 		break;
1255 	}
1256 
1257 	return result;
1258 
1259 }
1260 
rtw_hal_reqtxrpt(_adapter * padapter,u8 macid)1261 void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1262 {
1263 	if (padapter->hal_func.reqtxrpt)
1264 		padapter->hal_func.reqtxrpt(padapter, macid);
1265 }
1266 
rtw_hal_dump_macaddr(void * sel,_adapter * adapter)1267 void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1268 {
1269 	int i;
1270 	_adapter *iface;
1271 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1272 	u8 mac_addr[ETH_ALEN];
1273 
1274 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1275 	rtw_mbid_cam_dump(sel, __func__, adapter);
1276 #else
1277 	rtw_mi_hal_dump_macaddr(sel, adapter);
1278 #endif
1279 }
1280 
1281 #ifdef RTW_HALMAC
rtw_hal_hw_port_enable(_adapter * adapter)1282 void rtw_hal_hw_port_enable(_adapter *adapter)
1283 {
1284 #if 1
1285 	u8 port_enable = _TRUE;
1286 
1287 	rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1288 #else
1289 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1290 	struct rtw_halmac_bcn_ctrl bcn_ctrl;
1291 
1292 	_rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));
1293 	bcn_ctrl.enable_bcn = 1;
1294 	bcn_ctrl.rx_bssid_fit = 1;
1295 	bcn_ctrl.rxbcn_rpt = 1;
1296 
1297 	/*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
1298 				struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/
1299 	if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {
1300 		RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));
1301 		rtw_warn_on(1);
1302 	}
1303 #endif
1304 }
rtw_hal_hw_port_disable(_adapter * adapter)1305 void rtw_hal_hw_port_disable(_adapter *adapter)
1306 {
1307 	u8 port_enable = _FALSE;
1308 
1309 	rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1310 }
1311 
rtw_restore_hw_port_cfg(_adapter * adapter)1312 void rtw_restore_hw_port_cfg(_adapter *adapter)
1313 {
1314 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1315 
1316 #else
1317 	int i;
1318 	_adapter *iface;
1319 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1320 
1321 	for (i = 0; i < dvobj->iface_nums; i++) {
1322 		iface = dvobj->padapters[i];
1323 		if (iface)
1324 			rtw_hal_hw_port_enable(iface);
1325 	}
1326 #endif
1327 }
1328 #endif
1329 
rtw_mi_set_mac_addr(_adapter * adapter)1330 void rtw_mi_set_mac_addr(_adapter *adapter)
1331 {
1332 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1333 	rtw_mi_set_mbid_cam(adapter);
1334 #else
1335 	int i;
1336 	_adapter *iface;
1337 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1338 
1339 	for (i = 0; i < dvobj->iface_nums; i++) {
1340 		iface = dvobj->padapters[i];
1341 		if (iface)
1342 			rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));
1343 	}
1344 #endif
1345 	if (0)
1346 		rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1347 }
1348 
rtw_init_hal_com_default_value(PADAPTER Adapter)1349 void rtw_init_hal_com_default_value(PADAPTER Adapter)
1350 {
1351 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(Adapter);
1352 	struct registry_priv *regsty = adapter_to_regsty(Adapter);
1353 
1354 	pHalData->AntDetection = 1;
1355 	pHalData->antenna_test = _FALSE;
1356 	pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;
1357 	pHalData->ch_switch_offload = regsty->ch_switch_offload;
1358 	pHalData->multi_ch_switch_mode = 0;
1359 #ifdef RTW_REDUCE_SCAN_SWITCH_CH_TIME
1360 	if (pHalData->ch_switch_offload == 0)
1361 		pHalData->ch_switch_offload = 1;
1362 #endif
1363 }
1364 
1365 #ifdef CONFIG_FW_C2H_REG
c2h_evt_clear(_adapter * adapter)1366 void c2h_evt_clear(_adapter *adapter)
1367 {
1368 	rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1369 }
1370 
c2h_evt_read_88xx(_adapter * adapter,u8 * buf)1371 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1372 {
1373 	s32 ret = _FAIL;
1374 	int i;
1375 	u8 trigger;
1376 
1377 	if (buf == NULL)
1378 		goto exit;
1379 
1380 	trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1381 
1382 	if (trigger == C2H_EVT_HOST_CLOSE) {
1383 		goto exit; /* Not ready */
1384 	} else if (trigger != C2H_EVT_FW_CLOSE) {
1385 		goto clear_evt; /* Not a valid value */
1386 	}
1387 
1388 	_rtw_memset(buf, 0, C2H_REG_LEN);
1389 
1390 	/* Read ID, LEN, SEQ */
1391 	SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
1392 	SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
1393 	SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
1394 
1395 	if (0) {
1396 		RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
1397 			, C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
1398 	}
1399 
1400 	/* Read the content */
1401 	for (i = 0; i < C2H_PLEN_88XX(buf); i++)
1402 		*(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1403 
1404 	RTW_DBG_DUMP("payload: ", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
1405 
1406 	ret = _SUCCESS;
1407 
1408 clear_evt:
1409 	/*
1410 	* Clear event to notify FW we have read the command.
1411 	* If this field isn't clear, the FW won't update the next command message.
1412 	*/
1413 	c2h_evt_clear(adapter);
1414 
1415 exit:
1416 	return ret;
1417 }
1418 #endif /* CONFIG_FW_C2H_REG */
1419 
1420 #ifdef CONFIG_FW_C2H_PKT
1421 #ifndef DBG_C2H_PKT_PRE_HDL
1422 #define DBG_C2H_PKT_PRE_HDL 0
1423 #endif
1424 #ifndef DBG_C2H_PKT_HDL
1425 #define DBG_C2H_PKT_HDL 0
1426 #endif
rtw_hal_c2h_pkt_pre_hdl(_adapter * adapter,u8 * buf,u16 len)1427 void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
1428 {
1429 #ifdef RTW_HALMAC
1430 	/* TODO: extract hal_mac IC's code here*/
1431 #else
1432 	u8 parse_fail = 0;
1433 	u8 hdl_here = 0;
1434 	s32 ret = _FAIL;
1435 	u8 id, seq, plen;
1436 	u8 *payload;
1437 
1438 	if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1439 		parse_fail = 1;
1440 		goto exit;
1441 	}
1442 
1443 	hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
1444 	if (hdl_here)
1445 		ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1446 	else
1447 		ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
1448 
1449 exit:
1450 	if (parse_fail)
1451 		RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1452 	else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
1453 		RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1454 			, hdl_here ? "handle" : "enqueue"
1455 			, ret == _SUCCESS ? "ok" : "fail"
1456 		);
1457 		if (DBG_C2H_PKT_PRE_HDL >= 2)
1458 			RTW_PRINT_DUMP("dump: ", buf, len);
1459 	}
1460 #endif
1461 }
1462 
rtw_hal_c2h_pkt_hdl(_adapter * adapter,u8 * buf,u16 len)1463 void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
1464 {
1465 #ifdef RTW_HALMAC
1466 	adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
1467 #else
1468 	u8 parse_fail = 0;
1469 	u8 bypass = 0;
1470 	s32 ret = _FAIL;
1471 	u8 id, seq, plen;
1472 	u8 *payload;
1473 
1474 	if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1475 		parse_fail = 1;
1476 		goto exit;
1477 	}
1478 
1479 #ifdef CONFIG_WOWLAN
1480 	if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
1481 		bypass = 1;
1482 		ret = _SUCCESS;
1483 		goto exit;
1484 	}
1485 #endif
1486 
1487 	ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1488 
1489 exit:
1490 	if (parse_fail)
1491 		RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1492 	else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
1493 		RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1494 			, !bypass ? "handle" : "bypass"
1495 			, ret == _SUCCESS ? "ok" : "fail"
1496 		);
1497 		if (DBG_C2H_PKT_HDL >= 2)
1498 			RTW_PRINT_DUMP("dump: ", buf, len);
1499 	}
1500 #endif
1501 }
1502 #endif /* CONFIG_FW_C2H_PKT */
1503 
c2h_iqk_offload(_adapter * adapter,u8 * data,u8 len)1504 void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
1505 {
1506 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1507 	struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1508 
1509 	RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
1510 	if (0)
1511 		RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
1512 
1513 	rtw_sctx_done(&iqk_sctx);
1514 }
1515 
c2h_iqk_offload_wait(_adapter * adapter,u32 timeout_ms)1516 int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
1517 {
1518 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1519 	struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1520 
1521 	iqk_sctx->submit_time = rtw_get_current_time();
1522 	iqk_sctx->timeout_ms = timeout_ms;
1523 	iqk_sctx->status = RTW_SCTX_SUBMITTED;
1524 
1525 	return rtw_sctx_wait(iqk_sctx, __func__);
1526 }
1527 
1528 #ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX
c2h_txpwr_idx_offload_done(_adapter * adapter,u8 * data,u8 len)1529 void c2h_txpwr_idx_offload_done(_adapter *adapter, u8 *data, u8 len)
1530 {
1531 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1532 	struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1533 
1534 	if (0)
1535 		RTW_INFO("txpwr_idx offload finish in %dms\n", rtw_get_passing_time_ms(sctx->submit_time));
1536 	rtw_sctx_done(&sctx);
1537 }
1538 
c2h_txpwr_idx_offload_wait(_adapter * adapter)1539 int c2h_txpwr_idx_offload_wait(_adapter *adapter)
1540 {
1541 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1542 	struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1543 
1544 	return rtw_sctx_wait(sctx, __func__);
1545 }
1546 #endif
1547 
1548 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1549 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1550 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1551 #define	GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data)			LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1552 #define	GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1553 #define	GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
1554 #define	GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
1555 #define	GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1556 #define	GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1557 #define	GET_C2H_MAC_HIDDEN_RPT_BW(_data)				LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1558 #define	GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data)			LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1559 #define	GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1560 #define	GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1561 
1562 #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1563 #define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1564 #endif
1565 
1566 #ifdef CONFIG_RTW_MAC_HIDDEN_RPT
c2h_mac_hidden_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1567 int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1568 {
1569 	HAL_DATA_TYPE	*hal_data = GET_HAL_DATA(adapter);
1570 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1571 	enum rf_type rf_type;
1572 	u8 tx_path_num, rx_path_num;
1573 	int ret = _FAIL;
1574 
1575 	u8 uuid_x;
1576 	u8 uuid_y;
1577 	u8 uuid_z;
1578 	u16 uuid_crc;
1579 
1580 	u8 hci_type;
1581 	u8 package_type;
1582 	u8 tr_switch;
1583 	u8 wl_func;
1584 	u8 hw_stype;
1585 	u8 bw;
1586 	u8 ss_num = 4;
1587 	u8 ant_num;
1588 	u8 protocol;
1589 	u8 nic;
1590 
1591 	int i;
1592 
1593 	if (len < MAC_HIDDEN_RPT_LEN) {
1594 		RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1595 		goto exit;
1596 	}
1597 
1598 	uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1599 	uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1600 	uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1601 	uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1602 
1603 	hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1604 	package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1605 
1606 	tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
1607 
1608 	wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1609 	hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1610 
1611 	bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1612 	ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1613 
1614 	protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1615 	nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1616 
1617 	if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1618 		for (i = 0; i < len; i++)
1619 			RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1620 
1621 		RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1622 		RTW_PRINT("hci_type:0x%x\n", hci_type);
1623 		RTW_PRINT("package_type:0x%x\n", package_type);
1624 		RTW_PRINT("tr_switch:0x%x\n", tr_switch);
1625 		RTW_PRINT("wl_func:0x%x\n", wl_func);
1626 		RTW_PRINT("hw_stype:0x%x\n", hw_stype);
1627 		RTW_PRINT("bw:0x%x\n", bw);
1628 		RTW_PRINT("ant_num:0x%x\n", ant_num);
1629 		RTW_PRINT("protocol:0x%x\n", protocol);
1630 		RTW_PRINT("nic:0x%x\n", nic);
1631 	}
1632 
1633 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
1634 	if (IS_8822C_SERIES(hal_data->version_id) || IS_8814B_SERIES(hal_data->version_id)) {
1635 		#define GET_C2H_MAC_HIDDEN_RPT_SS_NUM(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 3, 2)
1636 		ss_num = GET_C2H_MAC_HIDDEN_RPT_SS_NUM(data);
1637 
1638 		if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1639 			RTW_PRINT("ss_num:0x%x\n", ss_num);
1640 
1641 		if (ss_num == 0x03)
1642 			ss_num = 4;
1643 	}
1644 #endif
1645 
1646 #if defined(CONFIG_RTL8822C)
1647 	if (IS_8822C_SERIES(hal_data->version_id)) {
1648 		if (ant_num == 1)
1649 			hal_spec->rf_reg_trx_path_bmp = 0x22; /* 1T1R pathB */
1650 		if (hw_stype == 0xE)
1651 			hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, 1); /* limit 1TX only */
1652 	}
1653 #endif
1654 	hal_data->PackageType = package_type;
1655 	hal_spec->hci_type = hci_type;
1656 	hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1657 	hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1658 	hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1659 
1660 	rf_type = rtw_chip_rftype_to_hal_rftype(adapter, 0);
1661 	if (!RF_TYPE_VALID(rf_type)) {
1662 		RTW_ERR("%s rtw_chip_rftype_to_hal_rftype failed\n", __func__);
1663 		goto exit;
1664 	}
1665 	hal_spec->rf_reg_path_avail_num = rtw_min(hal_spec->rf_reg_path_num, ant_num);
1666 	tx_path_num = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1667 	rx_path_num = rtw_min(rf_type_to_rf_rx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1668 	hal_spec->rf_reg_trx_path_bmp = rtw_restrict_trx_path_bmp_by_trx_num_lmt(
1669 		hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num, &tx_path_num, &rx_path_num);
1670 	if (!hal_spec->rf_reg_trx_path_bmp) {
1671 		RTW_ERR("%s rtw_restrict_trx_path_bmp_by_trx_num_lmt(0x%x, %u, %u) failed\n"
1672 			, __func__, hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num);
1673 		goto exit;
1674 	}
1675 	hal_spec->rf_reg_path_avail_num = rtw_max(tx_path_num, rx_path_num);
1676 
1677 	/*
1678 	* RF TX path num >= max_tx_cnt >= tx_nss_num
1679 	* ex: RF TX path num(4) >= max_tx_cnt(2) >= tx_nss_num(1)
1680 	* Select at most 2 out of 4 TX RF path to do 1SS 2TX
1681 	*/
1682 	hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, tx_path_num);
1683 	hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, hal_spec->max_tx_cnt);
1684 	hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ss_num);
1685 
1686 	hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, rx_path_num);
1687 	hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ss_num);
1688 
1689 	ret = _SUCCESS;
1690 
1691 exit:
1692 	return ret;
1693 }
1694 
c2h_mac_hidden_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1695 int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1696 {
1697 	HAL_DATA_TYPE	*hal_data = GET_HAL_DATA(adapter);
1698 	int ret = _FAIL;
1699 
1700 	int i;
1701 
1702 	if (len < MAC_HIDDEN_RPT_2_LEN) {
1703 		RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
1704 		goto exit;
1705 	}
1706 
1707 	if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1708 		for (i = 0; i < len; i++)
1709 			RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1710 	}
1711 
1712 	#if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV)
1713 	if (IS_8188F(hal_data->version_id) || IS_8188GTV(hal_data->version_id)) {
1714 		#define GET_C2H_MAC_HIDDEN_RPT_IRV(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)
1715 		u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);
1716 
1717 		if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1718 			RTW_PRINT("irv:0x%x\n", irv);
1719 
1720 		if(irv != 0xf)
1721 			hal_data->version_id.CUTVersion = irv;
1722 	}
1723 	#endif
1724 
1725 	ret = _SUCCESS;
1726 
1727 exit:
1728 	return ret;
1729 }
1730 
hal_read_mac_hidden_rpt(_adapter * adapter)1731 int hal_read_mac_hidden_rpt(_adapter *adapter)
1732 {
1733 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(adapter);
1734 	int ret = _FAIL;
1735 	int ret_fwdl;
1736 	u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
1737 	systime start = rtw_get_current_time();
1738 	u32 cnt = 0;
1739 	u32 timeout_ms = 800;
1740 	u32 min_cnt = 10;
1741 	u8 id = C2H_DEFEATURE_RSVD;
1742 	int i;
1743 
1744 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1745 	u8 hci_type = rtw_get_intf_type(adapter);
1746 
1747 	if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1748 		&& !rtw_is_hw_init_completed(adapter))
1749 		rtw_hal_power_on(adapter);
1750 #endif
1751 
1752 	/* inform FW mac hidden rpt from reg is needed */
1753 	rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
1754 
1755 	/* download FW */
1756 	pHalData->not_xmitframe_fw_dl = 1;
1757 	ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1758 	pHalData->not_xmitframe_fw_dl = 0;
1759 	if (ret_fwdl != _SUCCESS)
1760 		goto mac_hidden_rpt_hdl;
1761 
1762 	/* polling for data ready */
1763 	start = rtw_get_current_time();
1764 	do {
1765 		cnt++;
1766 		id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1767 		if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1768 			break;
1769 		rtw_msleep_os(10);
1770 	} while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1771 
1772 	if (id == C2H_MAC_HIDDEN_RPT) {
1773 		/* read data */
1774 		for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
1775 			mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1776 	}
1777 
1778 	/* inform FW mac hidden rpt has read */
1779 	rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
1780 
1781 mac_hidden_rpt_hdl:
1782 	c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1783 	c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
1784 
1785 	if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1786 		ret = _SUCCESS;
1787 
1788 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1789 	if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1790 		&& !rtw_is_hw_init_completed(adapter))
1791 		rtw_hal_power_off(adapter);
1792 #endif
1793 
1794 	RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1795 		, (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1796 
1797 	return ret;
1798 }
1799 #endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
1800 
c2h_defeature_dbg_hdl(_adapter * adapter,u8 * data,u8 len)1801 int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
1802 {
1803 	int ret = _FAIL;
1804 
1805 	int i;
1806 
1807 	if (len < DEFEATURE_DBG_LEN) {
1808 		RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
1809 		goto exit;
1810 	}
1811 
1812 	for (i = 0; i < len; i++)
1813 		RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1814 
1815 	ret = _SUCCESS;
1816 
1817 exit:
1818 	return ret;
1819 }
1820 
1821 #ifndef DBG_CUSTOMER_STR_RPT_HANDLE
1822 #define DBG_CUSTOMER_STR_RPT_HANDLE 0
1823 #endif
1824 
1825 #ifdef CONFIG_RTW_CUSTOMER_STR
rtw_hal_h2c_customer_str_req(_adapter * adapter)1826 s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
1827 {
1828 	u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
1829 
1830 	SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
1831 	return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
1832 }
1833 
1834 #define	C2H_CUSTOMER_STR_RPT_BYTE0(_data)		((u8 *)(_data))
1835 #define	C2H_CUSTOMER_STR_RPT_2_BYTE8(_data)		((u8 *)(_data))
1836 
c2h_customer_str_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1837 int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1838 {
1839 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1840 	int ret = _FAIL;
1841 	int i;
1842 
1843 	if (len < CUSTOMER_STR_RPT_LEN) {
1844 		RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
1845 		goto exit;
1846 	}
1847 
1848 	if (DBG_CUSTOMER_STR_RPT_HANDLE)
1849 		RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
1850 
1851 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1852 
1853 	if (dvobj->customer_str_sctx != NULL) {
1854 		if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
1855 			RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
1856 		_rtw_memcpy(dvobj->customer_str,  C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
1857 		dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
1858 	} else
1859 		RTW_WARN("%s sctx not set\n", __func__);
1860 
1861 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1862 
1863 	ret = _SUCCESS;
1864 
1865 exit:
1866 	return ret;
1867 }
1868 
c2h_customer_str_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1869 int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1870 {
1871 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1872 	int ret = _FAIL;
1873 	int i;
1874 
1875 	if (len < CUSTOMER_STR_RPT_2_LEN) {
1876 		RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
1877 		goto exit;
1878 	}
1879 
1880 	if (DBG_CUSTOMER_STR_RPT_HANDLE)
1881 		RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
1882 
1883 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1884 
1885 	if (dvobj->customer_str_sctx != NULL) {
1886 		if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
1887 			RTW_WARN("%s rpt not ready\n", __func__);
1888 		_rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN,  C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
1889 		rtw_sctx_done(&dvobj->customer_str_sctx);
1890 	} else
1891 		RTW_WARN("%s sctx not set\n", __func__);
1892 
1893 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1894 
1895 	ret = _SUCCESS;
1896 
1897 exit:
1898 	return ret;
1899 }
1900 
1901 /* read customer str */
rtw_hal_customer_str_read(_adapter * adapter,u8 * cs)1902 s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
1903 {
1904 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1905 	struct submit_ctx sctx;
1906 	s32 ret = _SUCCESS;
1907 
1908 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1909 	if (dvobj->customer_str_sctx != NULL)
1910 		ret = _FAIL;
1911 	else {
1912 		rtw_sctx_init(&sctx, 2 * 1000);
1913 		dvobj->customer_str_sctx = &sctx;
1914 	}
1915 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1916 
1917 	if (ret == _FAIL) {
1918 		RTW_WARN("%s another handle ongoing\n", __func__);
1919 		goto exit;
1920 	}
1921 
1922 	ret = rtw_customer_str_req_cmd(adapter);
1923 	if (ret != _SUCCESS) {
1924 		RTW_WARN("%s read cmd fail\n", __func__);
1925 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1926 		dvobj->customer_str_sctx = NULL;
1927 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1928 		goto exit;
1929 	}
1930 
1931 	/* wait till rpt done or timeout */
1932 	rtw_sctx_wait(&sctx, __func__);
1933 
1934 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1935 	dvobj->customer_str_sctx = NULL;
1936 	if (sctx.status == RTW_SCTX_DONE_SUCCESS)
1937 		_rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1938 	else
1939 		ret = _FAIL;
1940 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1941 
1942 exit:
1943 	return ret;
1944 }
1945 
rtw_hal_h2c_customer_str_write(_adapter * adapter,const u8 * cs)1946 s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
1947 {
1948 	u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
1949 	u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
1950 	u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
1951 	s32 ret;
1952 
1953 	SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
1954 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
1955 
1956 	SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
1957 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
1958 
1959 	SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
1960 	_rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
1961 
1962 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
1963 	if (ret != _SUCCESS) {
1964 		RTW_WARN("%s w1 fail\n", __func__);
1965 		goto exit;
1966 	}
1967 
1968 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
1969 	if (ret != _SUCCESS) {
1970 		RTW_WARN("%s w2 fail\n", __func__);
1971 		goto exit;
1972 	}
1973 
1974 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
1975 	if (ret != _SUCCESS) {
1976 		RTW_WARN("%s w3 fail\n", __func__);
1977 		goto exit;
1978 	}
1979 
1980 exit:
1981 	return ret;
1982 }
1983 
1984 /* write customer str and check if value reported is the same as requested */
rtw_hal_customer_str_write(_adapter * adapter,const u8 * cs)1985 s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
1986 {
1987 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1988 	struct submit_ctx sctx;
1989 	s32 ret = _SUCCESS;
1990 
1991 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1992 	if (dvobj->customer_str_sctx != NULL)
1993 		ret = _FAIL;
1994 	else {
1995 		rtw_sctx_init(&sctx, 2 * 1000);
1996 		dvobj->customer_str_sctx = &sctx;
1997 	}
1998 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1999 
2000 	if (ret == _FAIL) {
2001 		RTW_WARN("%s another handle ongoing\n", __func__);
2002 		goto exit;
2003 	}
2004 
2005 	ret = rtw_customer_str_write_cmd(adapter, cs);
2006 	if (ret != _SUCCESS) {
2007 		RTW_WARN("%s write cmd fail\n", __func__);
2008 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2009 		dvobj->customer_str_sctx = NULL;
2010 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2011 		goto exit;
2012 	}
2013 
2014 	ret = rtw_customer_str_req_cmd(adapter);
2015 	if (ret != _SUCCESS) {
2016 		RTW_WARN("%s read cmd fail\n", __func__);
2017 		_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2018 		dvobj->customer_str_sctx = NULL;
2019 		_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2020 		goto exit;
2021 	}
2022 
2023 	/* wait till rpt done or timeout */
2024 	rtw_sctx_wait(&sctx, __func__);
2025 
2026 	_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2027 	dvobj->customer_str_sctx = NULL;
2028 	if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
2029 		if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
2030 			RTW_WARN("%s read back check fail\n", __func__);
2031 			RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
2032 			RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
2033 			ret = _FAIL;
2034 		}
2035 	} else
2036 		ret = _FAIL;
2037 	_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2038 
2039 exit:
2040 	return ret;
2041 }
2042 #endif /* CONFIG_RTW_CUSTOMER_STR */
2043 
2044 #ifdef RTW_PER_CMD_SUPPORT_FW
2045 #define H2C_REQ_PER_RPT_LEN 5
2046 #define SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value)
2047 #define SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value)
2048 #define SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(__pH2CCmd, __Value)	SET_BITS_TO_LE_4BYTE(__pH2CCmd + 1, 0, 32, __Value)
2049 
rtw_hal_set_req_per_rpt_cmd(_adapter * adapter,u8 group_macid,u8 rpt_type,u32 macid_bitmap)2050 u8 rtw_hal_set_req_per_rpt_cmd(_adapter *adapter, u8 group_macid,
2051 				      u8 rpt_type, u32 macid_bitmap)
2052 {
2053 	u8 ret = _FAIL;
2054 	u8 cmd_buf[H2C_REQ_PER_RPT_LEN] = {0};
2055 
2056 	SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(cmd_buf, group_macid);
2057 	SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(cmd_buf, rpt_type);
2058 	SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(cmd_buf, macid_bitmap);
2059 
2060 	ret = rtw_hal_fill_h2c_cmd(adapter,
2061 				   H2C_REQ_PER_RPT,
2062 				   H2C_REQ_PER_RPT_LEN,
2063 				   cmd_buf);
2064 	return ret;
2065 }
2066 
2067 #define	GET_C2H_PER_RATE_RPT_TYPE0_MACID0(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2068 #define	GET_C2H_PER_RATE_RPT_TYPE0_PER0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2069 #define	GET_C2H_PER_RATE_RPT_TYPE0_RATE0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
2070 #define	GET_C2H_PER_RATE_RPT_TYPE0_BW0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
2071 #define	GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(_data)	LE_BITS_TO_2BYTE(((u8 *)(_data)) + 4, 0, 16)
2072 #define	GET_C2H_PER_RATE_RPT_TYPE0_MACID1(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
2073 #define	GET_C2H_PER_RATE_RPT_TYPE0_PER1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 8)
2074 #define	GET_C2H_PER_RATE_RPT_TYPE0_RATE1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
2075 #define	GET_C2H_PER_RATE_RPT_TYPE0_BW1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 2)
2076 #define	GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(_data)	LE_BITS_TO_2BYTE(((u8 *)(_data)) + 10, 0, 16)
2077 
2078 #define	GET_C2H_PER_RATE_RPT_TYPE1_MACID0(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2079 #define	GET_C2H_PER_RATE_RPT_TYPE1_PER0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2080 #define	GET_C2H_PER_RATE_RPT_TYPE1_RATE0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
2081 #define	GET_C2H_PER_RATE_RPT_TYPE1_BW0(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
2082 #define	GET_C2H_PER_RATE_RPT_TYPE1_MACID1(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 8)
2083 #define	GET_C2H_PER_RATE_RPT_TYPE1_PER1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 8)
2084 #define	GET_C2H_PER_RATE_RPT_TYPE1_RATE1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
2085 #define	GET_C2H_PER_RATE_RPT_TYPE1_BW1(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 2)
2086 #define	GET_C2H_PER_RATE_RPT_TYPE1_MACID2(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
2087 #define	GET_C2H_PER_RATE_RPT_TYPE1_PER2(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 8)
2088 #define	GET_C2H_PER_RATE_RPT_TYPE1_RATE2(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 10, 0, 8)
2089 #define	GET_C2H_PER_RATE_RPT_TYPE1_BW2(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 11, 0, 2)
2090 
per_rate_rpt_update(_adapter * adapter,u8 mac_id,u8 per,u8 rate,u8 bw,u8 total_pkt)2091 static void per_rate_rpt_update(_adapter *adapter, u8 mac_id,
2092 				u8 per, u8 rate,
2093 				u8 bw, u8 total_pkt)
2094 {
2095 #ifdef CONFIG_RTW_MESH
2096 	rtw_ieee80211s_update_metric(adapter, mac_id,
2097 				     per, rate,
2098 				     bw, total_pkt);
2099 #endif
2100 }
2101 
c2h_per_rate_rpt_hdl(_adapter * adapter,u8 * data,u8 len)2102 int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
2103 {
2104 	/* Now only consider type0, since it covers all params in type1
2105 	 * type0: mac_id, per, rate, bw, total_pkt
2106 	 * type1: mac_id, per, rate, bw
2107 	 */
2108 	u8 mac_id[2] = {0}, per[2] = {0}, rate[2] = {0}, bw[2] = {0};
2109 	u16 total_pkt[2] = {0};
2110 	int ret = _FAIL, i, macid_cnt = 0;
2111 
2112 	/* type0:
2113 	 * 1 macid includes   6 bytes info + 1 byte 0xff
2114 	 * 2 macid includes 2*6 bytes info
2115 	 */
2116 	if (!(len == 7 || len == 12)) {
2117 		RTW_WARN("%s len(%u) != 7 or 12\n", __FUNCTION__, len);
2118 		goto exit;
2119 	}
2120 
2121 	macid_cnt++;
2122 	mac_id[0] = GET_C2H_PER_RATE_RPT_TYPE0_MACID0(data);
2123 	per[0] = GET_C2H_PER_RATE_RPT_TYPE0_PER0(data);
2124 	rate[0] = GET_C2H_PER_RATE_RPT_TYPE0_RATE0(data);
2125 	bw[0] = GET_C2H_PER_RATE_RPT_TYPE0_BW0(data);
2126 	total_pkt[0] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(data);
2127 
2128 	mac_id[1] = GET_C2H_PER_RATE_RPT_TYPE0_MACID1(data);
2129 	/* 0xff means no report anymore */
2130 	if (mac_id[1] == 0xff)
2131 		goto update_per;
2132 	if (len != 12) {
2133 		RTW_WARN("%s incorrect format\n", __FUNCTION__);
2134 		goto exit;
2135 	}
2136 	macid_cnt++;
2137 	per[1] = GET_C2H_PER_RATE_RPT_TYPE0_PER1(data);
2138 	rate[1] = GET_C2H_PER_RATE_RPT_TYPE0_RATE1(data);
2139 	bw[1] = GET_C2H_PER_RATE_RPT_TYPE0_BW1(data);
2140 	total_pkt[1] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(data);
2141 
2142 update_per:
2143 	for (i = 0; i < macid_cnt; i++) {
2144 		RTW_DBG("[%s] type0 rpt[%d]: macid = %u, per = %u, "
2145 			"rate = %u, bw = %u, total_pkt = %u\n",
2146 			__FUNCTION__, i, mac_id[i], per[i],
2147 			rate[i], bw[i], total_pkt[i]);
2148 		per_rate_rpt_update(adapter, mac_id[i],
2149 				    per[i], rate[i],
2150 				    bw[i], total_pkt[i]);
2151 	}
2152 	ret = _SUCCESS;
2153 exit:
2154 	return ret;
2155 }
2156 #endif /* RTW_PER_CMD_SUPPORT_FW */
2157 
2158 #ifdef CONFIG_LPS_ACK
2159 #define	GET_C2H_LPS_STATUS_RPT_GET_ACTION(_data)	LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2160 #define	GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(_data)		LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2161 #define DBG_LPS_STATUS_RPT 0
2162 
c2h_lps_status_rpt(PADAPTER adapter,u8 * data,u8 len)2163 int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len)
2164 {
2165 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
2166 	struct submit_ctx *lps_sctx = &pwrpriv->lps_ack_sctx;
2167 	u8 action = 0;
2168 	s8 status_code = 0;
2169 	int ret = _FAIL;
2170 
2171 	if (len < LPS_STATUS_RPT_LEN) {
2172 		RTW_WARN("%s len(%u) < %d\n", __func__, len, LPS_STATUS_RPT_LEN);
2173 		goto exit;
2174 	}
2175 
2176 	action = GET_C2H_LPS_STATUS_RPT_GET_ACTION(data);
2177 	status_code = GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(data);
2178 
2179 	/* action=0: report force leave null data status */
2180 	/* action=1: report Rf on status when receiving a SetPwrMode H2C with PwrState = RFON */
2181 	switch (action) {
2182 		case 0:
2183 			/* status code 0: success, 1: no ack, 2: timeout, 3: cancel */
2184 		case 1:
2185 			/* status code 0: FW has already turn to RFON */
2186 			pwrpriv->lps_ack_status = status_code;
2187 
2188 			if (DBG_LPS_STATUS_RPT)
2189 				RTW_INFO("=== [C2H LPS Action(%d)] LPS Status Code:%d ===\n", action, status_code);
2190 
2191 			break;
2192 		default:
2193 			RTW_INFO("UnKnown Action(%d) for C2H LPS RPT\n", action);
2194 			break;
2195 	}
2196 
2197 	rtw_sctx_done(&lps_sctx);
2198 	ret = _SUCCESS;
2199 
2200 exit:
2201 	return ret;
2202 }
2203 #endif /* CONFIG_LPS_ACK */
2204 
rtw_hal_update_sta_wset(_adapter * adapter,struct sta_info * psta)2205 void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)
2206 {
2207 	u8 w_set = 0;
2208 
2209 	if (psta->wireless_mode & WIRELESS_11B)
2210 		w_set |= WIRELESS_CCK;
2211 
2212 	if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))
2213 		w_set |= WIRELESS_OFDM;
2214 
2215 	if (psta->wireless_mode & WIRELESS_11_24N)
2216 		w_set |= WIRELESS_HT;
2217 
2218 	if ((psta->wireless_mode & WIRELESS_11AC) || (psta->wireless_mode & WIRELESS_11_5N))
2219 		w_set |= WIRELESS_VHT;
2220 
2221 	psta->cmn.support_wireless_set = w_set;
2222 }
2223 
rtw_hal_update_sta_mimo_type(_adapter * adapter,struct sta_info * psta)2224 void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)
2225 {
2226 	s8 tx_nss, rx_nss;
2227 
2228 	tx_nss = rtw_get_sta_tx_nss(adapter, psta);
2229 	rx_nss =  rtw_get_sta_rx_nss(adapter, psta);
2230 	if ((tx_nss == 1) && (rx_nss == 1))
2231 		psta->cmn.mimo_type = RF_1T1R;
2232 	else if ((tx_nss == 1) && (rx_nss == 2))
2233 		psta->cmn.mimo_type = RF_1T2R;
2234 	else if ((tx_nss == 2) && (rx_nss == 2))
2235 		psta->cmn.mimo_type = RF_2T2R;
2236 	else if ((tx_nss == 2) && (rx_nss == 3))
2237 		psta->cmn.mimo_type = RF_2T3R;
2238 	else if ((tx_nss == 2) && (rx_nss == 4))
2239 		psta->cmn.mimo_type = RF_2T4R;
2240 	else if ((tx_nss == 3) && (rx_nss == 3))
2241 		psta->cmn.mimo_type = RF_3T3R;
2242 	else if ((tx_nss == 3) && (rx_nss == 4))
2243 		psta->cmn.mimo_type = RF_3T4R;
2244 	else if ((tx_nss == 4) && (rx_nss == 4))
2245 		psta->cmn.mimo_type = RF_4T4R;
2246 	else
2247 		rtw_warn_on(1);
2248 
2249 #ifdef CONFIG_CTRL_TXSS_BY_TP
2250 	rtw_ctrl_txss_update_mimo_type(adapter, psta);
2251 #endif
2252 
2253 	RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",
2254 			psta->cmn.mac_id, tx_nss, rx_nss);
2255 }
2256 
rtw_hal_update_sta_smps_cap(_adapter * adapter,struct sta_info * psta)2257 void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)
2258 {
2259 	/*Spatial Multiplexing Power Save*/
2260 #if 0
2261 	if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2262 		#ifdef CONFIG_80211N_HT
2263 		if (psta->htpriv.ht_option) {
2264 			if (psta->htpriv.smps_cap == 0)
2265 				psta->cmn.sm_ps = SM_PS_STATIC;
2266 			else if (psta->htpriv.smps_cap == 1)
2267 				psta->cmn.sm_ps = SM_PS_DYNAMIC;
2268 			else
2269 				psta->cmn.sm_ps = SM_PS_DISABLE;
2270 		}
2271 		#endif /* CONFIG_80211N_HT */
2272 	} else
2273 #endif
2274 		psta->cmn.sm_ps = SM_PS_DISABLE;
2275 
2276 	RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",
2277 			psta->cmn.mac_id, psta->cmn.sm_ps);
2278 }
2279 
rtw_get_mgntframe_raid(_adapter * adapter,unsigned char network_type)2280 u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
2281 {
2282 
2283 	u8 raid;
2284 	if (IS_NEW_GENERATION_IC(adapter)) {
2285 
2286 		raid = (network_type & WIRELESS_11B)	? RATEID_IDX_B
2287 		       : RATEID_IDX_G;
2288 	} else {
2289 		raid = (network_type & WIRELESS_11B)	? RATR_INX_WIRELESS_B
2290 		       : RATR_INX_WIRELESS_G;
2291 	}
2292 	return raid;
2293 }
2294 
rtw_hal_update_sta_rate_mask(PADAPTER padapter,struct sta_info * psta)2295 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
2296 {
2297 	u8 i, tx_nss;
2298 	u64 tx_ra_bitmap = 0, tmp64=0;
2299 
2300 	if (psta == NULL)
2301 		return;
2302 
2303 	/* b/g mode ra_bitmap  */
2304 	for (i = 0; i < sizeof(psta->bssrateset); i++) {
2305 		if (psta->bssrateset[i])
2306 			tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
2307 	}
2308 
2309 #ifdef CONFIG_80211N_HT
2310 if (padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
2311 	tx_nss = GET_HAL_TX_NSS(padapter);
2312 #ifdef CONFIG_80211AC_VHT
2313 	if (psta->vhtpriv.vht_option) {
2314 		/* AC mode ra_bitmap */
2315 		tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
2316 	} else
2317 #endif /* CONFIG_80211AC_VHT */
2318 	if (psta->htpriv.ht_option) {
2319 		/* n mode ra_bitmap */
2320 
2321 		/* Handling SMPS mode for AP MODE only*/
2322 		if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2323 			/*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
2324 			if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
2325 				/*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
2326 				tx_nss = rtw_min(tx_nss, 1);
2327 			}
2328 		}
2329 
2330 		tmp64 = rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss);
2331 		tx_ra_bitmap |= (tmp64 << 12);
2332 	}
2333 }
2334 #endif /* CONFIG_80211N_HT */
2335 	psta->cmn.ra_info.ramask = tx_ra_bitmap;
2336 	psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
2337 }
2338 
rtw_hal_update_sta_ra_info(PADAPTER padapter,struct sta_info * psta)2339 void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)
2340 {
2341 	rtw_hal_update_sta_mimo_type(padapter, psta);
2342 	rtw_hal_update_sta_smps_cap(padapter, psta);
2343 	rtw_hal_update_sta_rate_mask(padapter, psta);
2344 }
2345 
2346 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
hw_bcn_ctrl_addr(_adapter * adapter,u8 hw_port)2347 static u32 hw_bcn_ctrl_addr(_adapter *adapter, u8 hw_port)
2348 {
2349 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2350 
2351 	if (hw_port >= hal_spec->port_num) {
2352 		RTW_ERR(FUNC_ADPT_FMT" HW Port(%d) invalid\n", FUNC_ADPT_ARG(adapter), hw_port);
2353 		rtw_warn_on(1);
2354 		return 0;
2355 	}
2356 
2357 	switch (hw_port) {
2358 	case HW_PORT0:
2359 		return REG_BCN_CTRL;
2360 	case HW_PORT1:
2361 		return REG_BCN_CTRL_1;
2362 	}
2363 
2364 	return 0;
2365 }
2366 #endif
2367 
rtw_hal_get_msr(_adapter * adapter,u8 * net_type)2368 static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2369 {
2370 #ifdef RTW_HALMAC
2371 	rtw_halmac_get_network_type(adapter_to_dvobj(adapter),
2372 				adapter->hw_port, net_type);
2373 #else /* !RTW_HALMAC */
2374 	switch (adapter->hw_port) {
2375 	case HW_PORT0:
2376 		/*REG_CR - BIT[17:16]-Network Type for port 1*/
2377 		*net_type = rtw_read8(adapter, MSR) & 0x03;
2378 		break;
2379 	case HW_PORT1:
2380 		/*REG_CR - BIT[19:18]-Network Type for port 1*/
2381 		*net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2382 		break;
2383 #if defined(CONFIG_RTL8814A)
2384 	case HW_PORT2:
2385 		/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2386 		*net_type = rtw_read8(adapter, MSR1) & 0x03;
2387 		break;
2388 	case HW_PORT3:
2389 		/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2390 		*net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2391 		break;
2392 	case HW_PORT4:
2393 		/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2394 		*net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2395 		break;
2396 #endif /*#if defined(CONFIG_RTL8814A)*/
2397 	default:
2398 		RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2399 			 ADPT_ARG(adapter), adapter->hw_port);
2400 		rtw_warn_on(1);
2401 		break;
2402 	}
2403 #endif /* !RTW_HALMAC */
2404 }
2405 
2406 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM) /*For 2 hw ports - 88E/92E/8812/8821/8723B*/
rtw_hal_net_type_decision(_adapter * adapter,u8 net_type)2407 static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)
2408 {
2409 	if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {
2410 		if (net_type != _HW_STATE_NOLINK_)
2411 			return _HW_STATE_AP_;
2412 	}
2413 	return net_type;
2414 }
2415 #endif
rtw_hal_set_msr(_adapter * adapter,u8 net_type)2416 static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2417 {
2418 #ifdef RTW_HALMAC
2419 	#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2420 	net_type = rtw_hal_net_type_decision(adapter, net_type);
2421 	#endif
2422 	rtw_halmac_set_network_type(adapter_to_dvobj(adapter),
2423 				adapter->hw_port, net_type);
2424 #else /* !RTW_HALMAC */
2425 	u8 val8 = 0;
2426 
2427 	switch (adapter->hw_port) {
2428 	case HW_PORT0:
2429 		#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2430 		net_type = rtw_hal_net_type_decision(adapter, net_type);
2431 		#endif
2432 		/*REG_CR - BIT[17:16]-Network Type for port 0*/
2433 		val8 = rtw_read8(adapter, MSR) & 0x0C;
2434 		val8 |= net_type;
2435 		rtw_write8(adapter, MSR, val8);
2436 		break;
2437 	case HW_PORT1:
2438 		/*REG_CR - BIT[19:18]-Network Type for port 1*/
2439 		val8 = rtw_read8(adapter, MSR) & 0x03;
2440 		val8 |= net_type << 2;
2441 		rtw_write8(adapter, MSR, val8);
2442 		break;
2443 #if defined(CONFIG_RTL8814A)
2444 	case HW_PORT2:
2445 		/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2446 		val8 = rtw_read8(adapter, MSR1) & 0xFC;
2447 		val8 |= net_type;
2448 		rtw_write8(adapter, MSR1, val8);
2449 		break;
2450 	case HW_PORT3:
2451 		/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2452 		val8 = rtw_read8(adapter, MSR1) & 0xF3;
2453 		val8 |= net_type << 2;
2454 		rtw_write8(adapter, MSR1, val8);
2455 		break;
2456 	case HW_PORT4:
2457 		/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2458 		val8 = rtw_read8(adapter, MSR1) & 0xCF;
2459 		val8 |= net_type << 4;
2460 		rtw_write8(adapter, MSR1, val8);
2461 		break;
2462 #endif /* CONFIG_RTL8814A */
2463 	default:
2464 		RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2465 			 ADPT_ARG(adapter), adapter->hw_port);
2466 		rtw_warn_on(1);
2467 		break;
2468 	}
2469 #endif /* !RTW_HALMAC */
2470 }
2471 
2472 #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
2473 	#define SEC_CAM_ACCESS_TIMEOUT_MS 200
2474 #endif
2475 
2476 #ifndef DBG_SEC_CAM_ACCESS
2477 	#define DBG_SEC_CAM_ACCESS 0
2478 #endif
2479 
rtw_sec_read_cam(_adapter * adapter,u8 addr)2480 u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
2481 {
2482 	_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2483 	u32 rdata;
2484 	u32 cnt = 0;
2485 	systime start = 0, end = 0;
2486 	u8 timeout = 0;
2487 	u8 sr = 0;
2488 
2489 	_enter_critical_mutex(mutex, NULL);
2490 
2491 	rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
2492 
2493 	start = rtw_get_current_time();
2494 	while (1) {
2495 		if (rtw_is_surprise_removed(adapter)) {
2496 			sr = 1;
2497 			break;
2498 		}
2499 
2500 		cnt++;
2501 		if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2502 			break;
2503 
2504 		if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2505 			timeout = 1;
2506 			break;
2507 		}
2508 	}
2509 	end = rtw_get_current_time();
2510 
2511 	rdata = rtw_read32(adapter, REG_CAMREAD);
2512 
2513 	_exit_critical_mutex(mutex, NULL);
2514 
2515 	if (DBG_SEC_CAM_ACCESS || timeout) {
2516 		RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
2517 			, FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2518 	}
2519 
2520 	return rdata;
2521 }
2522 
rtw_sec_write_cam(_adapter * adapter,u8 addr,u32 wdata)2523 void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
2524 {
2525 	_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2526 	u32 cnt = 0;
2527 	systime start = 0, end = 0;
2528 	u8 timeout = 0;
2529 	u8 sr = 0;
2530 
2531 	_enter_critical_mutex(mutex, NULL);
2532 
2533 	rtw_write32(adapter, REG_CAMWRITE, wdata);
2534 	rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
2535 
2536 	start = rtw_get_current_time();
2537 	while (1) {
2538 		if (rtw_is_surprise_removed(adapter)) {
2539 			sr = 1;
2540 			break;
2541 		}
2542 
2543 		cnt++;
2544 		if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2545 			break;
2546 
2547 		if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2548 			timeout = 1;
2549 			break;
2550 		}
2551 	}
2552 	end = rtw_get_current_time();
2553 
2554 	_exit_critical_mutex(mutex, NULL);
2555 
2556 	if (DBG_SEC_CAM_ACCESS || timeout) {
2557 		RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
2558 			, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2559 	}
2560 }
2561 
rtw_sec_read_cam_ent(_adapter * adapter,u8 id,u8 * ctrl,u8 * mac,u8 * key)2562 void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
2563 {
2564 	u8 i;
2565 	u32 rdata;
2566 	u8 begin = 0;
2567 	u8 end = 5; /* TODO: consider other key length accordingly */
2568 
2569 	if (!ctrl && !mac && !key) {
2570 		rtw_warn_on(1);
2571 		goto exit;
2572 	}
2573 
2574 	/* TODO: check id range */
2575 
2576 	if (!ctrl && !mac)
2577 		begin = 2; /* read from key */
2578 
2579 	if (!key && !mac)
2580 		end = 0; /* read to ctrl */
2581 	else if (!key)
2582 		end = 2; /* read to mac */
2583 
2584 	for (i = begin; i <= end; i++) {
2585 		rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
2586 
2587 		switch (i) {
2588 		case 0:
2589 			if (ctrl)
2590 				_rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
2591 			if (mac)
2592 				_rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
2593 			break;
2594 		case 1:
2595 			if (mac)
2596 				_rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
2597 			break;
2598 		default:
2599 			if (key)
2600 				_rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
2601 			break;
2602 		}
2603 	}
2604 
2605 exit:
2606 	return;
2607 }
2608 
2609 
rtw_sec_write_cam_ent(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)2610 void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
2611 {
2612 	unsigned int i;
2613 	int j;
2614 	u8 addr, addr1 = 0;
2615 	u32 wdata, wdata1 = 0;
2616 
2617 	/* TODO: consider other key length accordingly */
2618 #if 0
2619 	switch ((ctrl & 0x1c) >> 2) {
2620 	case _WEP40_:
2621 	case _TKIP_:
2622 	case _AES_:
2623 	case _WEP104_:
2624 
2625 	}
2626 #else
2627 	j = 7;
2628 #endif
2629 
2630 	for (; j >= 0; j--) {
2631 		switch (j) {
2632 		case 0:
2633 			wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
2634 			break;
2635 		case 1:
2636 			wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
2637 			break;
2638 		case 6:
2639 		case 7:
2640 			wdata = 0;
2641 			break;
2642 		default:
2643 			i = (j - 2) << 2;
2644 			wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
2645 			break;
2646 		}
2647 
2648 		addr = (id << 3) + j;
2649 
2650 #if defined(CONFIG_RTL8192F)
2651 		if(j == 1) {
2652 			wdata1 = wdata;
2653 			addr1 = addr;
2654 			continue;
2655 		}
2656 #endif
2657 
2658 		rtw_sec_write_cam(adapter, addr, wdata);
2659 	}
2660 
2661 #if defined(CONFIG_RTL8192F)
2662 	rtw_sec_write_cam(adapter, addr1, wdata1);
2663 #endif
2664 }
2665 
rtw_sec_clr_cam_ent(_adapter * adapter,u8 id)2666 void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
2667 {
2668 	u8 addr;
2669 
2670 	addr = (id << 3);
2671 	rtw_sec_write_cam(adapter, addr, 0);
2672 }
2673 
rtw_sec_read_cam_is_gk(_adapter * adapter,u8 id)2674 bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
2675 {
2676 	bool res;
2677 	u16 ctrl;
2678 
2679 	rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
2680 
2681 	res = (ctrl & BIT6) ? _TRUE : _FALSE;
2682 	return res;
2683 }
2684 #ifdef CONFIG_MBSSID_CAM
rtw_mbid_cam_init(struct dvobj_priv * dvobj)2685 void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
2686 {
2687 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2688 
2689 	_rtw_spinlock_init(&mbid_cam_ctl->lock);
2690 	mbid_cam_ctl->bitmap = 0;
2691 	ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2692 	_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2693 }
2694 
rtw_mbid_cam_deinit(struct dvobj_priv * dvobj)2695 void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
2696 {
2697 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2698 
2699 	_rtw_spinlock_free(&mbid_cam_ctl->lock);
2700 }
2701 
rtw_mbid_cam_reset(_adapter * adapter)2702 void rtw_mbid_cam_reset(_adapter *adapter)
2703 {
2704 	_irqL irqL;
2705 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2706 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2707 
2708 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2709 	mbid_cam_ctl->bitmap = 0;
2710 	_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2711 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2712 
2713 	ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2714 }
_rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2715 static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2716 {
2717 	u8 i;
2718 	u8 cam_id = INVALID_CAM_ID;
2719 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2720 
2721 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2722 		if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
2723 			cam_id = i;
2724 			break;
2725 		}
2726 	}
2727 
2728 	RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2729 	return cam_id;
2730 }
2731 
rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2732 u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2733 {
2734 	_irqL irqL;
2735 
2736 	u8 cam_id = INVALID_CAM_ID;
2737 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2738 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2739 
2740 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2741 	cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
2742 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2743 
2744 	return cam_id;
2745 }
_rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2746 static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2747 {
2748 	u8 i;
2749 	u8 cam_id = INVALID_CAM_ID;
2750 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2751 
2752 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2753 		if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
2754 			cam_id = i;
2755 			break;
2756 		}
2757 	}
2758 	if (cam_id != INVALID_CAM_ID)
2759 		RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
2760 			__func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
2761 
2762 	return cam_id;
2763 }
2764 
rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2765 u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2766 {
2767 	_irqL irqL;
2768 	u8 cam_id = INVALID_CAM_ID;
2769 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2770 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2771 
2772 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2773 	cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
2774 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2775 
2776 	return cam_id;
2777 }
rtw_get_max_mbid_cam_id(_adapter * adapter)2778 u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
2779 {
2780 	_irqL irqL;
2781 	s8 i;
2782 	u8 cam_id = INVALID_CAM_ID;
2783 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2784 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2785 
2786 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2787 	for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
2788 		if (mbid_cam_ctl->bitmap & BIT(i)) {
2789 			cam_id = i;
2790 			break;
2791 		}
2792 	}
2793 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2794 	/*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
2795 	return cam_id;
2796 }
2797 
rtw_get_mbid_cam_entry_num(_adapter * adapter)2798 inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
2799 {
2800 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2801 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2802 
2803 	return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2804 }
2805 
mbid_cam_cache_init(_adapter * adapter,struct mbid_cam_cache * pmbid_cam,u8 * mac_addr)2806 static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
2807 {
2808 	if (adapter && pmbid_cam && mac_addr) {
2809 		_rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
2810 		pmbid_cam->iface_id = adapter->iface_id;
2811 	}
2812 }
mbid_cam_cache_clr(struct mbid_cam_cache * pmbid_cam)2813 static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
2814 {
2815 	if (pmbid_cam) {
2816 		_rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
2817 		pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
2818 	}
2819 }
2820 
rtw_mbid_camid_alloc(_adapter * adapter,u8 * mac_addr)2821 u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
2822 {
2823 	_irqL irqL;
2824 	u8 cam_id = INVALID_CAM_ID, i;
2825 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2826 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2827 	u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2828 
2829 	if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2830 		goto exit;
2831 
2832 	if (entry_num >= TOTAL_MBID_CAM_NUM) {
2833 		RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
2834 		rtw_warn_on(1);
2835 	}
2836 
2837 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2838 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2839 		if (!(mbid_cam_ctl->bitmap & BIT(i))) {
2840 			mbid_cam_ctl->bitmap |= BIT(i);
2841 			cam_id = i;
2842 			break;
2843 		}
2844 	}
2845 	if ((cam_id != INVALID_CAM_ID) && (mac_addr))
2846 		mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
2847 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2848 
2849 	if (cam_id != INVALID_CAM_ID) {
2850 		ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2851 		RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2852 #ifdef DBG_MBID_CAM_DUMP
2853 		rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2854 #endif
2855 	} else
2856 		RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2857 exit:
2858 	return cam_id;
2859 }
2860 
rtw_mbid_cam_info_change(_adapter * adapter,u8 * mac_addr)2861 u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
2862 {
2863 	_irqL irqL;
2864 	u8 entry_id = INVALID_CAM_ID;
2865 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2866 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2867 
2868 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2869 	entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
2870 	if (entry_id != INVALID_CAM_ID)
2871 		mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
2872 
2873 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2874 
2875 	return entry_id;
2876 }
2877 
rtw_mbid_cam_assign(_adapter * adapter,u8 * mac_addr,u8 camid)2878 u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
2879 {
2880 	_irqL irqL;
2881 	u8 ret = _FALSE;
2882 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2883 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2884 
2885 	if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
2886 		RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
2887 		rtw_warn_on(1);
2888 	}
2889 	if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2890 		goto exit;
2891 
2892 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2893 	if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
2894 		if (mac_addr) {
2895 			mbid_cam_ctl->bitmap |= BIT(camid);
2896 			mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
2897 			ret = _TRUE;
2898 		}
2899 	}
2900 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2901 
2902 	if (ret == _TRUE) {
2903 		ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2904 		RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
2905 #ifdef DBG_MBID_CAM_DUMP
2906 		rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2907 #endif
2908 	} else
2909 		RTW_INFO("%s  [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
2910 
2911 exit:
2912 	return ret;
2913 }
2914 
rtw_mbid_camid_clean(_adapter * adapter,u8 mbss_canid)2915 void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
2916 {
2917 	_irqL irqL;
2918 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2919 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2920 
2921 	if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
2922 		RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
2923 		rtw_warn_on(1);
2924 	}
2925 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2926 	mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
2927 	mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
2928 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2929 	ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
2930 	RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
2931 }
rtw_mbid_cam_cache_dump(void * sel,const char * fun_name,_adapter * adapter)2932 int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
2933 {
2934 	_irqL irqL;
2935 	u8 i;
2936 	_adapter *iface;
2937 	u8 iface_id;
2938 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2939 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2940 	u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2941 	u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2942 
2943 	RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
2944 
2945 	_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2946 	RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
2947 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2948 		RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2949 
2950 		if (mbid_cam_ctl->bitmap & BIT(i)) {
2951 			iface_id = dvobj->mbid_cam_cache[i].iface_id;
2952 			_RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
2953 			_RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2954 
2955 			iface = dvobj->padapters[iface_id];
2956 			if (iface) {
2957 				if (MLME_IS_STA(iface))
2958 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
2959 				else if (MLME_IS_AP(iface))
2960 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
2961 				else if (MLME_IS_MESH(iface))
2962 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "MESH");
2963 				else
2964 					_RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2965 			}
2966 
2967 		} else
2968 			_RTW_PRINT_SEL(sel, "N/A\n");
2969 	}
2970 	_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2971 	return 0;
2972 }
2973 
read_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2974 static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2975 {
2976 	u8 poll = 1;
2977 	u8 cam_ready = _FALSE;
2978 	u32 cam_data1 = 0;
2979 	u16 cam_data2 = 0;
2980 
2981 	if (RTW_CANNOT_RUN(padapter))
2982 		return;
2983 
2984 	rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2985 
2986 	do {
2987 		if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2988 			cam_ready = _TRUE;
2989 			break;
2990 		}
2991 		poll++;
2992 	} while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2993 
2994 	if (cam_ready) {
2995 		cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2996 		mac[0] = cam_data1 & 0xFF;
2997 		mac[1] = (cam_data1 >> 8) & 0xFF;
2998 		mac[2] = (cam_data1 >> 16) & 0xFF;
2999 		mac[3] = (cam_data1 >> 24) & 0xFF;
3000 
3001 		cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
3002 		mac[4] = cam_data2 & 0xFF;
3003 		mac[5] = (cam_data2 >> 8) & 0xFF;
3004 	}
3005 
3006 }
rtw_mbid_cam_dump(void * sel,const char * fun_name,_adapter * adapter)3007 int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
3008 {
3009 	/*_irqL irqL;*/
3010 	u8 i;
3011 	u8 mac_addr[ETH_ALEN];
3012 
3013 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3014 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
3015 
3016 	RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
3017 
3018 	/*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
3019 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
3020 		RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
3021 		_rtw_memset(mac_addr, 0, ETH_ALEN);
3022 		read_mbssid_cam(adapter, i, mac_addr);
3023 		_RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
3024 	}
3025 	/*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
3026 	return 0;
3027 }
3028 
write_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)3029 static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
3030 {
3031 	u32	cam_val[2] = {0};
3032 
3033 	cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
3034 	cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT)  | (mac[5] << 8) | mac[4];
3035 
3036 	rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
3037 }
3038 
3039 /*
3040 static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
3041 {
3042 	rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
3043 }
3044 */
3045 
rtw_ap_set_mbid_num(_adapter * adapter,u8 ap_num)3046 void rtw_ap_set_mbid_num(_adapter *adapter, u8 ap_num)
3047 {
3048 	rtw_write8(adapter, REG_MBID_NUM,
3049 		((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | ((ap_num -1) & 0x07)));
3050 
3051 }
rtw_mbid_cam_enable(_adapter * adapter)3052 void rtw_mbid_cam_enable(_adapter *adapter)
3053 {
3054 	/*enable MBSSID*/
3055 	rtw_hal_rcr_add(adapter, RCR_ENMBID);
3056 }
rtw_mi_set_mbid_cam(_adapter * adapter)3057 void rtw_mi_set_mbid_cam(_adapter *adapter)
3058 {
3059 	u8 i;
3060 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3061 	struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
3062 
3063 #ifdef DBG_MBID_CAM_DUMP
3064 	rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
3065 #endif
3066 
3067 	for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
3068 		if (mbid_cam_ctl->bitmap & BIT(i)) {
3069 			write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
3070 			RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
3071 		}
3072 	}
3073 	rtw_mbid_cam_enable(adapter);
3074 }
3075 #endif /*CONFIG_MBSSID_CAM*/
3076 
3077 #ifdef CONFIG_FW_HANDLE_TXBCN
3078 #define H2C_BCN_OFFLOAD_LEN	1
3079 
3080 #define SET_H2CCMD_BCN_OFFLOAD_EN(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)
3081 #define SET_H2CCMD_BCN_ROOT_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)
3082 #define SET_H2CCMD_BCN_VAP1_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value)
3083 #define SET_H2CCMD_BCN_VAP2_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value)
3084 #define SET_H2CCMD_BCN_VAP3_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value)
3085 #define SET_H2CCMD_BCN_VAP4_TBTT_RPT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value)
3086 
rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter * adapter,bool fw_bcn_en,u8 tbtt_rpt_map)3087 void rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter *adapter, bool fw_bcn_en, u8 tbtt_rpt_map)
3088 {
3089 	u8 fw_bcn_offload[1] = {0};
3090 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3091 
3092 	if (fw_bcn_en)
3093 		SET_H2CCMD_BCN_OFFLOAD_EN(fw_bcn_offload, 1);
3094 
3095 	if (tbtt_rpt_map & BIT(0))
3096 		SET_H2CCMD_BCN_ROOT_TBTT_RPT(fw_bcn_offload, 1);
3097 	if (tbtt_rpt_map & BIT(1))
3098 		SET_H2CCMD_BCN_VAP1_TBTT_RPT(fw_bcn_offload, 1);
3099 	if (tbtt_rpt_map & BIT(2))
3100 		SET_H2CCMD_BCN_VAP2_TBTT_RPT(fw_bcn_offload, 1);
3101 	if (tbtt_rpt_map & BIT(3))
3102 			SET_H2CCMD_BCN_VAP3_TBTT_RPT(fw_bcn_offload, 1);
3103 
3104 	dvobj->vap_tbtt_rpt_map = tbtt_rpt_map;
3105 	dvobj->fw_bcn_offload = fw_bcn_en;
3106 	RTW_INFO("[FW BCN] Offload : %s\n", (dvobj->fw_bcn_offload) ? "EN" : "DIS");
3107 	RTW_INFO("[FW BCN] TBTT RPT map : 0x%02x\n", dvobj->vap_tbtt_rpt_map);
3108 
3109 	rtw_hal_fill_h2c_cmd(adapter, H2C_FW_BCN_OFFLOAD,
3110 					H2C_BCN_OFFLOAD_LEN, fw_bcn_offload);
3111 }
3112 
rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter * adapter)3113 void rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter *adapter)
3114 {
3115 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3116 	u8 ret, vap_id;
3117 	u32 page_size = 0;
3118 	u8 bcn_rsvdpage[H2C_BCN_RSVDPAGE_LEN] = {0};
3119 
3120 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
3121 	#if 1
3122 	for (vap_id = 0; vap_id < CONFIG_LIMITED_AP_NUM; vap_id++) {
3123 		if (dvobj->vap_map & BIT(vap_id))
3124 			bcn_rsvdpage[vap_id] = vap_id * (MAX_BEACON_LEN / page_size);
3125 	}
3126 	#else
3127 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value)
3128 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 8, __Value)
3129 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 8, __Value)
3130 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 8, __Value)
3131 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(__pH2CCmd, __Value)	SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 8, __Value)
3132 
3133 	if (dvobj->vap_map & BIT(0))
3134  		SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(bcn_rsvdpage, 0);
3135 	if (dvobj->vap_map & BIT(1))
3136 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(bcn_rsvdpage,
3137 					1 * (MAX_BEACON_LEN / page_size));
3138 	if (dvobj->vap_map & BIT(2))
3139 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(bcn_rsvdpage,
3140 					2 * (MAX_BEACON_LEN / page_size));
3141 	if (dvobj->vap_map & BIT(3))
3142 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(bcn_rsvdpage,
3143 					3 * (MAX_BEACON_LEN / page_size));
3144 	if (dvobj->vap_map & BIT(4))
3145 		SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(bcn_rsvdpage,
3146 					4 * (MAX_BEACON_LEN / page_size));
3147 	#endif
3148 	if (1) {
3149 		RTW_INFO("[BCN_LOC] vap_map : 0x%02x\n", dvobj->vap_map);
3150 		RTW_INFO("[BCN_LOC] page_size :%d, @bcn_page_num :%d\n"
3151 			, page_size, (MAX_BEACON_LEN / page_size));
3152 		RTW_INFO("[BCN_LOC] root ap : 0x%02x\n", *bcn_rsvdpage);
3153 		RTW_INFO("[BCN_LOC] vap_1 : 0x%02x\n", *(bcn_rsvdpage + 1));
3154 		RTW_INFO("[BCN_LOC] vap_2 : 0x%02x\n", *(bcn_rsvdpage + 2));
3155 		RTW_INFO("[BCN_LOC] vap_3 : 0x%02x\n", *(bcn_rsvdpage + 3));
3156 		RTW_INFO("[BCN_LOC] vap_4 : 0x%02x\n", *(bcn_rsvdpage + 4));
3157 	}
3158 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_BCN_RSVDPAGE,
3159 					H2C_BCN_RSVDPAGE_LEN, bcn_rsvdpage);
3160 }
3161 
rtw_ap_multi_bcn_cfg(_adapter * adapter)3162 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3163 {
3164 	u8 dft_bcn_space = DEFAULT_BCN_INTERVAL;
3165 	u8 sub_bcn_space = (DEFAULT_BCN_INTERVAL / CONFIG_LIMITED_AP_NUM);
3166 
3167 	/*enable to rx data frame*/
3168 	rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3169 
3170 	/*Disable Port0's beacon function*/
3171 	rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
3172 	/*Reset Port0's TSF*/
3173 	rtw_write8(adapter, REG_DUAL_TSF_RST, BIT_TSFTR_RST);
3174 
3175 	rtw_ap_set_mbid_num(adapter, CONFIG_LIMITED_AP_NUM);
3176 
3177 	/*BCN space & BCN sub-space 0x554[15:0] = 0x64,0x5BC[23:16] = 0x21*/
3178 	rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), HW_PORT0, dft_bcn_space);
3179 	rtw_write8(adapter, REG_MBSSID_BCN_SPACE3 + 2, sub_bcn_space);
3180 
3181 	#if 0 /*setting in hw_var_set_opmode_mbid - ResumeTxBeacon*/
3182 	/*BCN hold time  0x540[19:8] = 0x80*/
3183 	rtw_write8(adapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
3184 	rtw_write8(adapter, REG_TBTT_PROHIBIT + 2,
3185 		(rtw_read8(adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
3186 	#endif
3187 
3188 	/*ATIM window -0x55A = 0x32, reg 0x570 = 0x32, reg 0x5A0 = 0x32 */
3189 	rtw_write8(adapter, REG_ATIMWND, 0x32);
3190 	rtw_write8(adapter, REG_ATIMWND1_V1, 0x32);
3191 	rtw_write8(adapter, REG_ATIMWND2, 0x32);
3192 	rtw_write8(adapter, REG_ATIMWND3, 0x32);
3193 	/*
3194 	rtw_write8(adapter, REG_ATIMWND4, 0x32);
3195 	rtw_write8(adapter, REG_ATIMWND5, 0x32);
3196 	rtw_write8(adapter, REG_ATIMWND6, 0x32);
3197 	rtw_write8(adapter, REG_ATIMWND7, 0x32);*/
3198 
3199 	/*no limit setting - 0x5A7 = 0xFF - Packet in Hi Queue Tx immediately*/
3200 	rtw_write8(adapter, REG_HIQ_NO_LMT_EN, 0xFF);
3201 
3202 	/*Mask all beacon*/
3203 	rtw_write8(adapter, REG_MBSSID_CTRL, 0);
3204 
3205 	/*BCN invalid bit setting 0x454[6] = 1*/
3206 	/*rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);*/
3207 
3208 	/*Enable Port0's beacon function*/
3209 	rtw_write8(adapter, REG_BCN_CTRL,
3210 	rtw_read8(adapter, REG_BCN_CTRL) | BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT  | BIT_EN_BCN_FUNCTION);
3211 
3212 	/* Enable HW seq for BCN
3213 	* 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT  */
3214 	 #ifdef CONFIG_RTL8822B
3215 	if (IS_HARDWARE_TYPE_8822B(adapter))
3216 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3217 	#endif
3218 
3219 	 #ifdef CONFIG_RTL8822C
3220 	if (IS_HARDWARE_TYPE_8822C(adapter))
3221 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3222 	#endif
3223 }
_rtw_mbid_bcn_cfg(_adapter * adapter,bool mbcnq_en,u8 mbcnq_id)3224 static void _rtw_mbid_bcn_cfg(_adapter *adapter, bool mbcnq_en, u8 mbcnq_id)
3225 {
3226 	if (mbcnq_id >= CONFIG_LIMITED_AP_NUM) {
3227 		RTW_ERR(FUNC_ADPT_FMT"- mbid bcnq_id(%d) invalid\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3228 		rtw_warn_on(1);
3229 	}
3230 
3231 	if (mbcnq_en) {
3232 		rtw_write8(adapter, REG_MBSSID_CTRL,
3233 			rtw_read8(adapter, REG_MBSSID_CTRL) | BIT(mbcnq_id));
3234 		RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) enabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3235 	} else {
3236 		rtw_write8(adapter, REG_MBSSID_CTRL,
3237 			rtw_read8(adapter, REG_MBSSID_CTRL) & (~BIT(mbcnq_id)));
3238 		RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) disabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3239 	}
3240 }
3241 /*#define CONFIG_FW_TBTT_RPT*/
rtw_ap_mbid_bcn_en(_adapter * adapter,u8 ap_id)3242 void rtw_ap_mbid_bcn_en(_adapter *adapter, u8 ap_id)
3243 {
3244 	RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3245 
3246 	#ifdef CONFIG_FW_TBTT_RPT
3247 	if (rtw_ap_get_nums(adapter) >= 1) {
3248 		u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3249 
3250 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3251 			tbtt_rpt_map | BIT(ap_id));/*H2C-0xBA*/
3252 	}
3253 	#else
3254 	if (rtw_ap_get_nums(adapter) == 1)
3255 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE, 0);/*H2C-0xBA*/
3256 	#endif
3257 
3258 	rtw_hal_set_bcn_rsvdpage_loc_cmd(adapter);/*H2C-0x09*/
3259 
3260 	_rtw_mbid_bcn_cfg(adapter, _TRUE, ap_id);
3261 }
rtw_ap_mbid_bcn_dis(_adapter * adapter,u8 ap_id)3262 void rtw_ap_mbid_bcn_dis(_adapter *adapter, u8 ap_id)
3263 {
3264 	RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3265 	_rtw_mbid_bcn_cfg(adapter, _FALSE, ap_id);
3266 
3267 	if (rtw_ap_get_nums(adapter) == 0)
3268 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _FALSE, 0);
3269 	#ifdef CONFIG_FW_TBTT_RPT
3270 	else if (rtw_ap_get_nums(adapter) >= 1) {
3271 		u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3272 
3273 		rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3274 			tbtt_rpt_map & ~BIT(ap_id));/*H2C-0xBA*/
3275 	}
3276 	#endif
3277 }
3278 #endif
3279 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_ap_multi_bcn_cfg(_adapter * adapter)3280 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3281 {
3282 	#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3283 	rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT);
3284 	#else
3285 	rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
3286 	#endif
3287 	/*enable to rx data frame*/
3288 	rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3289 
3290 	/*Beacon Control related register for first time*/
3291 	rtw_write8(adapter, REG_BCNDMATIM, 0x02); /* 2ms */
3292 
3293 	/*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
3294 	rtw_write8(adapter, REG_ATIMWND, 0x0c); /* 12ms */
3295 
3296 	#ifndef CONFIG_HW_P0_TSF_SYNC
3297 	rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
3298 	#endif
3299 
3300 	/*reset TSF*/
3301 	rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
3302 
3303 	/*enable BCN0 Function for if1*/
3304 	/*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
3305 	#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3306 	rtw_write8(adapter, REG_BCN_CTRL, BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT |BIT_EN_BCN_FUNCTION);
3307 	#else
3308 	rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
3309 	#endif
3310 	#ifdef CONFIG_BCN_XMIT_PROTECT
3311 	rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
3312 	#endif
3313 
3314 	if (IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8192E(adapter))/* select BCN on port 0 for DualBeacon*/
3315 		rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
3316 
3317 	/* Enable HW seq for BCN
3318 	 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT  */
3319 	#ifdef CONFIG_RTL8822B
3320 	if (IS_HARDWARE_TYPE_8822B(adapter))
3321 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3322 	#endif
3323 
3324 	#ifdef CONFIG_RTL8822C
3325 	if (IS_HARDWARE_TYPE_8822C(adapter))
3326 		rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3327 	#endif
3328 }
3329 #endif
3330 
3331 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3332 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3333 {
3334 
3335 #if 0 /*TODO - modify for more flexible*/
3336 	u8 idx = 0;
3337 
3338 	if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
3339 	    (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
3340 		for (idx = 0; idx < 6; idx++)
3341 			rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
3342 	}  else {
3343 		/*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
3344 		u8 entry_id;
3345 
3346 		if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
3347 		    (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
3348 			entry_id = 0;
3349 			if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
3350 				RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
3351 				write_mbssid_cam(adapter, entry_id, val);
3352 			}
3353 		} else {
3354 			entry_id = rtw_mbid_camid_alloc(adapter, val);
3355 			if (entry_id != INVALID_CAM_ID)
3356 				write_mbssid_cam(adapter, entry_id, val);
3357 		}
3358 	}
3359 #else
3360 	{
3361 		/*
3362 			MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
3363 		*/
3364 		u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
3365 
3366 
3367 		if (entry_id != INVALID_CAM_ID) {
3368 			write_mbssid_cam(adapter, entry_id, mac_addr);
3369 			RTW_INFO("%s "ADPT_FMT"- mbid(%d) mac_addr ="MAC_FMT"\n", __func__,
3370 				ADPT_ARG(adapter), entry_id, MAC_ARG(mac_addr));
3371 		}
3372 	}
3373 #endif
3374 }
3375 
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3376 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3377 {
3378 	u8 idx = 0;
3379 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3380 	u8 entry_id;
3381 
3382 	if (!mac_addr) {
3383 		rtw_warn_on(1);
3384 		return;
3385 	}
3386 
3387 
3388 	entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
3389 
3390 	if (entry_id != INVALID_CAM_ID)
3391 		write_mbssid_cam(adapter, entry_id, mac_addr);
3392 }
3393 
3394 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_hal_bcn_interval_adjust(_adapter * adapter,u16 bcn_interval)3395 u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
3396 {
3397 	if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
3398 		return adapter_to_dvobj(adapter)->inter_bcn_space;
3399 	else
3400 		return bcn_interval;
3401 }
3402 #endif/*CONFIG_SWTIMER_BASED_TXBCN*/
3403 
3404 #else
3405 
3406 #ifndef RTW_HALMAC
_get_macaddr_reg(enum _hw_port hwport)3407 static u32 _get_macaddr_reg(enum _hw_port hwport)
3408 {
3409 	u32 reg_macaddr = REG_MACID;
3410 
3411 	#ifdef CONFIG_CONCURRENT_MODE
3412 	if (hwport == HW_PORT1)
3413 		reg_macaddr = REG_MACID1;
3414 	#if defined(CONFIG_RTL8814A)
3415 	else if (hwport == HW_PORT2)
3416 		reg_macaddr = REG_MACID2;
3417 	else if (hwport == HW_PORT3)
3418 		reg_macaddr = REG_MACID3;
3419 	else if (hwport == HW_PORT4)
3420 		reg_macaddr = REG_MACID4;
3421 	#endif /*CONFIG_RTL8814A*/
3422 	#endif /*CONFIG_CONCURRENT_MODE*/
3423 
3424 	return reg_macaddr;
3425 }
3426 #endif /*!RTW_HALMAC*/
3427 
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * mac_addr)3428 static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *mac_addr)
3429 {
3430 	enum _hw_port hwport;
3431 
3432 	if (mac_addr == NULL)
3433 		return;
3434 	hwport = get_hw_port(adapter);
3435 
3436 	RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",  __func__,
3437 		 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3438 
3439 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3440 	rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3441 #else /* !RTW_HALMAC */
3442 	{
3443 		u8 idx = 0;
3444 		u32 reg_macaddr = _get_macaddr_reg(hwport);
3445 
3446 		for (idx = 0; idx < ETH_ALEN; idx++)
3447 			rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx), mac_addr[idx]);
3448 	}
3449 #endif /* !RTW_HALMAC */
3450 }
3451 
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)3452 static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
3453 {
3454 	enum _hw_port hwport;
3455 
3456 	if (mac_addr == NULL)
3457 		return;
3458 	hwport = get_hw_port(adapter);
3459 
3460 	_rtw_memset(mac_addr, 0, ETH_ALEN);
3461 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3462 	rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3463 #else /* !RTW_HALMAC */
3464 	{
3465 		u8 idx = 0;
3466 		u32 reg_macaddr = _get_macaddr_reg(hwport);
3467 
3468 		for (idx = 0; idx < ETH_ALEN; idx++)
3469 			mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx));
3470 	}
3471 #endif /* !RTW_HALMAC */
3472 
3473 	RTW_DBG("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",  __func__,
3474 		 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3475 }
3476 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
3477 
3478 #ifndef RTW_HALMAC
_get_bssid_reg(enum _hw_port hw_port)3479 static u32 _get_bssid_reg(enum _hw_port hw_port)
3480 {
3481 	u32 reg_bssid = REG_BSSID;
3482 
3483 	#ifdef CONFIG_CONCURRENT_MODE
3484 	if (hw_port == HW_PORT1)
3485 		reg_bssid = REG_BSSID1;
3486 	#if defined(CONFIG_RTL8814A)
3487 	else if (hw_port == HW_PORT2)
3488 		reg_bssid = REG_BSSID2;
3489 	else if (hw_port == HW_PORT3)
3490 		reg_bssid = REG_BSSID3;
3491 	else if (hw_port == HW_PORT4)
3492 		reg_bssid = REG_BSSID4;
3493 	#endif /*CONFIG_RTL8814A*/
3494 	#endif /*CONFIG_CONCURRENT_MODE*/
3495 
3496 	return reg_bssid;
3497 }
3498 #endif /*!RTW_HALMAC*/
rtw_hal_set_bssid(_adapter * adapter,u8 * val)3499 static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
3500 {
3501 	enum _hw_port hw_port = rtw_hal_get_port(adapter);
3502 #ifdef RTW_HALMAC
3503 
3504 	rtw_halmac_set_bssid(adapter_to_dvobj(adapter), hw_port, val);
3505 #else /* !RTW_HALMAC */
3506 	u8 idx = 0;
3507 	u32 reg_bssid = _get_bssid_reg(hw_port);
3508 
3509 	for (idx = 0 ; idx < ETH_ALEN; idx++)
3510 		rtw_write8(adapter, (reg_bssid + idx), val[idx]);
3511 #endif /* !RTW_HALMAC */
3512 
3513 	RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n",
3514 		__func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val));
3515 }
3516 
3517 #ifndef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_tsf_update(_adapter * adapter,u8 en)3518 static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en)
3519 {
3520 	u32 addr = 0;
3521 	u8 val8;
3522 
3523 	rtw_hal_get_hwreg(adapter, HW_VAR_BCN_CTRL_ADDR, (u8 *)&addr);
3524 	if (addr) {
3525 		rtw_enter_protsel_port(adapter, get_hw_port(adapter));
3526 		val8 = rtw_read8(adapter, addr);
3527 		if (en && (val8 & DIS_TSF_UDT)) {
3528 			rtw_write8(adapter, addr, val8 & ~DIS_TSF_UDT);
3529 			#ifdef DBG_TSF_UPDATE
3530 			RTW_INFO("port%u("ADPT_FMT") enable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3531 			#endif
3532 		}
3533 		if (!en && !(val8 & DIS_TSF_UDT)) {
3534 			rtw_write8(adapter, addr, val8 | DIS_TSF_UDT);
3535 			#ifdef DBG_TSF_UPDATE
3536 			RTW_INFO("port%u("ADPT_FMT") disable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3537 			#endif
3538 		}
3539 		rtw_leave_protsel_port(adapter);
3540 	} else {
3541 		RTW_WARN("unknown port%d("ADPT_FMT") %s TSF update\n"
3542 			, adapter->hw_port, ADPT_ARG(adapter), en ? "enable" : "disable");
3543 		rtw_warn_on(1);
3544 	}
3545 }
3546 #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_set_hw_update_tsf(PADAPTER padapter)3547 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
3548 {
3549 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3550 
3551 #else
3552 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3553 
3554 	if (!pmlmeext->en_hw_update_tsf)
3555 		return;
3556 
3557 	/* check RCR */
3558 	if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
3559 		return;
3560 
3561 	if (pmlmeext->tsf_update_required) {
3562 		pmlmeext->tsf_update_pause_stime = 0;
3563 		rtw_hal_set_tsf_update(padapter, 1);
3564 	}
3565 
3566 	pmlmeext->en_hw_update_tsf = 0;
3567 #endif
3568 }
3569 
rtw_iface_enable_tsf_update(_adapter * adapter)3570 void rtw_iface_enable_tsf_update(_adapter *adapter)
3571 {
3572 	adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3573 	adapter->mlmeextpriv.tsf_update_required = 1;
3574 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3575 
3576 #else
3577 	rtw_hal_set_tsf_update(adapter, 1);
3578 #endif
3579 }
3580 
rtw_iface_disable_tsf_update(_adapter * adapter)3581 void rtw_iface_disable_tsf_update(_adapter *adapter)
3582 {
3583 	adapter->mlmeextpriv.tsf_update_required = 0;
3584 	adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3585 	adapter->mlmeextpriv.en_hw_update_tsf = 0;
3586 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3587 
3588 #else
3589 	rtw_hal_set_tsf_update(adapter, 0);
3590 #endif
3591 }
3592 
rtw_hal_tsf_update_pause(_adapter * adapter)3593 static void rtw_hal_tsf_update_pause(_adapter *adapter)
3594 {
3595 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3596 
3597 #else
3598 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3599 	_adapter *iface;
3600 	int i;
3601 
3602 	for (i = 0; i < dvobj->iface_nums; i++) {
3603 		iface = dvobj->padapters[i];
3604 		if (!iface)
3605 			continue;
3606 
3607 		rtw_hal_set_tsf_update(iface, 0);
3608 		if (iface->mlmeextpriv.tsf_update_required) {
3609 			iface->mlmeextpriv.tsf_update_pause_stime = rtw_get_current_time();
3610 			if (!iface->mlmeextpriv.tsf_update_pause_stime)
3611 				iface->mlmeextpriv.tsf_update_pause_stime++;
3612 		}
3613 		iface->mlmeextpriv.en_hw_update_tsf = 0;
3614 	}
3615 #endif
3616 }
3617 
rtw_hal_tsf_update_restore(_adapter * adapter)3618 static void rtw_hal_tsf_update_restore(_adapter *adapter)
3619 {
3620 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3621 
3622 #else
3623 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3624 	_adapter *iface;
3625 	int i;
3626 
3627 	for (i = 0; i < dvobj->iface_nums; i++) {
3628 		iface = dvobj->padapters[i];
3629 		if (!iface)
3630 			continue;
3631 
3632 		if (iface->mlmeextpriv.tsf_update_required) {
3633 			/* enable HW TSF update when recive beacon*/
3634 			iface->mlmeextpriv.en_hw_update_tsf = 1;
3635 			#ifdef DBG_TSF_UPDATE
3636 			RTW_INFO("port%d("ADPT_FMT") enabling TSF update...\n"
3637 				, iface->hw_port, ADPT_ARG(iface));
3638 			#endif
3639 		}
3640 	}
3641 #endif
3642 }
3643 
rtw_hal_periodic_tsf_update_chk(_adapter * adapter)3644 void rtw_hal_periodic_tsf_update_chk(_adapter *adapter)
3645 {
3646 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3647 
3648 #else
3649 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3650 	_adapter *iface;
3651 	struct mlme_ext_priv *mlmeext;
3652 	int i;
3653 	u32 restore_ms = 0;
3654 
3655 	if (dvobj->periodic_tsf_update_etime) {
3656 		if (rtw_time_after(rtw_get_current_time(), dvobj->periodic_tsf_update_etime)) {
3657 			/* end for restore status */
3658 			dvobj->periodic_tsf_update_etime = 0;
3659 			rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3660 		}
3661 		return;
3662 	}
3663 
3664 	if (dvobj->rf_ctl.offch_state != OFFCHS_NONE)
3665 		return;
3666 
3667 	/*
3668 	* all required ifaces can switch to restore status together
3669 	* loop all pause iface to get largest restore time required
3670 	*/
3671 	for (i = 0; i < dvobj->iface_nums; i++) {
3672 		iface = dvobj->padapters[i];
3673 		if (!iface)
3674 			continue;
3675 
3676 		mlmeext = &iface->mlmeextpriv;
3677 
3678 		if (mlmeext->tsf_update_required
3679 			&& mlmeext->tsf_update_pause_stime
3680 			&& rtw_get_passing_time_ms(mlmeext->tsf_update_pause_stime)
3681 				> mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_pause_factor
3682 		) {
3683 			if (restore_ms < mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor)
3684 				restore_ms = mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor;
3685 		}
3686 	}
3687 
3688 	if (!restore_ms)
3689 		return;
3690 
3691 	dvobj->periodic_tsf_update_etime = rtw_get_current_time() + rtw_ms_to_systime(restore_ms);
3692 	if (!dvobj->periodic_tsf_update_etime)
3693 		dvobj->periodic_tsf_update_etime++;
3694 
3695 	rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3696 
3697 	/* set timer to end restore status */
3698 	_set_timer(&dvobj->periodic_tsf_update_end_timer, restore_ms);
3699 #endif
3700 }
3701 
rtw_hal_periodic_tsf_update_end_timer_hdl(void * ctx)3702 void rtw_hal_periodic_tsf_update_end_timer_hdl(void *ctx)
3703 {
3704 	struct dvobj_priv *dvobj = (struct dvobj_priv *)ctx;
3705 
3706 	if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
3707 		return;
3708 
3709 	rtw_periodic_tsf_update_end_cmd(dvobj_get_primary_adapter(dvobj));
3710 }
3711 
hw_var_rcr_config(_adapter * adapter,u32 rcr)3712 static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
3713 {
3714 	int err;
3715 
3716 #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
3717 	rcr = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_AMF | RCR_APP_PHYST_RXFF | RCR_APP_MIC | RCR_APP_ICV;
3718 #endif
3719 	err = rtw_write32(adapter, REG_RCR, rcr);
3720 	if (err == _SUCCESS)
3721 		GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
3722 	return err;
3723 }
3724 
hw_var_rcr_get(_adapter * adapter,u32 * rcr)3725 static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
3726 {
3727 	u32 v32;
3728 
3729 	v32 = rtw_read32(adapter, REG_RCR);
3730 	if (rcr)
3731 		*rcr = v32;
3732 	GET_HAL_DATA(adapter)->ReceiveConfig = v32;
3733 	return _SUCCESS;
3734 }
3735 
3736 /* only check SW RCR variable */
rtw_hal_rcr_check(_adapter * adapter,u32 check_bit)3737 inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
3738 {
3739 	PHAL_DATA_TYPE hal;
3740 	u32 rcr;
3741 
3742 	hal = GET_HAL_DATA(adapter);
3743 
3744 	rcr = hal->ReceiveConfig;
3745 	if ((rcr & check_bit) == check_bit)
3746 		return 1;
3747 
3748 	return 0;
3749 }
3750 
rtw_hal_rcr_add(_adapter * adapter,u32 add)3751 inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
3752 {
3753 	PHAL_DATA_TYPE hal;
3754 	u32 rcr;
3755 	u8 ret = _SUCCESS;
3756 
3757 	hal = GET_HAL_DATA(adapter);
3758 
3759 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3760 	rcr |= add;
3761 	if (rcr != hal->ReceiveConfig)
3762 		ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3763 
3764 	return ret;
3765 }
3766 
rtw_hal_rcr_clear(_adapter * adapter,u32 clear)3767 inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
3768 {
3769 	PHAL_DATA_TYPE hal;
3770 	u32 rcr;
3771 	u8 ret = _SUCCESS;
3772 
3773 	hal = GET_HAL_DATA(adapter);
3774 
3775 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3776 	rcr &= ~clear;
3777 	if (rcr != hal->ReceiveConfig)
3778 		ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3779 
3780 	return ret;
3781 }
3782 
rtw_hal_rcr_set_chk_bssid(_adapter * adapter,u8 self_action)3783 void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
3784 {
3785 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3786 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3787 	u32 rcr, rcr_new;
3788 	struct mi_state mstate, mstate_s;
3789 
3790 	rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3791 	rcr_new = rcr;
3792 
3793 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && !defined(CONFIG_CLIENT_PORT_CFG)
3794 	rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
3795 #else
3796 	rtw_mi_status_no_self(adapter, &mstate);
3797 	rtw_mi_status_no_others(adapter, &mstate_s);
3798 
3799 	/* only adjust parameters interested */
3800 	switch (self_action) {
3801 	case MLME_SCAN_ENTER:
3802 		mstate_s.scan_num = 1;
3803 		mstate_s.scan_enter_num = 1;
3804 		break;
3805 	case MLME_SCAN_DONE:
3806 		mstate_s.scan_enter_num = 0;
3807 		break;
3808 	case MLME_STA_CONNECTING:
3809 		mstate_s.lg_sta_num = 1;
3810 		mstate_s.ld_sta_num = 0;
3811 		break;
3812 	case MLME_STA_CONNECTED:
3813 		mstate_s.lg_sta_num = 0;
3814 		mstate_s.ld_sta_num = 1;
3815 		break;
3816 	case MLME_STA_DISCONNECTED:
3817 		mstate_s.lg_sta_num = 0;
3818 		mstate_s.ld_sta_num = 0;
3819 		break;
3820 #ifdef CONFIG_TDLS
3821 	case MLME_TDLS_LINKED:
3822 		mstate_s.ld_tdls_num = 1;
3823 		break;
3824 	case MLME_TDLS_NOLINK:
3825 		mstate_s.ld_tdls_num = 0;
3826 		break;
3827 #endif
3828 #ifdef CONFIG_AP_MODE
3829 	case MLME_AP_STARTED:
3830 		mstate_s.ap_num = 1;
3831 		break;
3832 	case MLME_AP_STOPPED:
3833 		mstate_s.ap_num = 0;
3834 		mstate_s.ld_ap_num = 0;
3835 		break;
3836 #endif
3837 #ifdef CONFIG_RTW_MESH
3838 	case MLME_MESH_STARTED:
3839 		mstate_s.mesh_num = 1;
3840 		break;
3841 	case MLME_MESH_STOPPED:
3842 		mstate_s.mesh_num = 0;
3843 		mstate_s.ld_mesh_num = 0;
3844 		break;
3845 #endif
3846 	case MLME_ACTION_NONE:
3847 	case MLME_ADHOC_STARTED:
3848 		/* caller without effect of decision */
3849 		break;
3850 	default:
3851 		rtw_warn_on(1);
3852 	};
3853 
3854 	rtw_mi_status_merge(&mstate, &mstate_s);
3855 
3856 	if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
3857 		#ifdef CONFIG_FIND_BEST_CHANNEL
3858 		|| MSTATE_SCAN_ENTER_NUM(&mstate)
3859 		#endif
3860 		|| hal_data->in_cta_test
3861 	)
3862 		rcr_new &= ~RCR_CBSSID_DATA;
3863 	else
3864 		rcr_new |= RCR_CBSSID_DATA;
3865 
3866 	if (MSTATE_SCAN_ENTER_NUM(&mstate) || hal_data->in_cta_test)
3867 		rcr_new &= ~RCR_CBSSID_BCN;
3868 	else if (MSTATE_STA_LG_NUM(&mstate)
3869 		|| adapter_to_dvobj(adapter)->periodic_tsf_update_etime
3870 	)
3871 		rcr_new |= RCR_CBSSID_BCN;
3872 	else if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
3873 		|| MSTATE_MESH_NUM(&mstate)
3874 	)
3875 		rcr_new &= ~RCR_CBSSID_BCN;
3876 	else
3877 		rcr_new |= RCR_CBSSID_BCN;
3878 
3879 	#ifdef CONFIG_CLIENT_PORT_CFG
3880 	if (get_clt_num(adapter) > MAX_CLIENT_PORT_NUM)
3881 		rcr_new &= ~RCR_CBSSID_BCN;
3882 	#endif
3883 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
3884 
3885 #ifdef CONFIG_RTW_MULTI_AP
3886 	if (MSTATE_AP_NUM(&mstate)
3887 		&& rtw_unassoc_sta_src_chk(adapter, UNASOC_STA_SRC_RX_NMY_UC)
3888 	) {
3889 		rcr_new |= RCR_AAP;
3890 	} else
3891 		rcr_new &= ~RCR_AAP;
3892 #endif
3893 
3894 	if (rcr == rcr_new)
3895 		return;
3896 
3897 	if (!hal_spec->rx_tsf_filter
3898 		&& (rcr & RCR_CBSSID_BCN) && !(rcr_new & RCR_CBSSID_BCN))
3899 		rtw_hal_tsf_update_pause(adapter);
3900 
3901 	rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
3902 
3903 	if (!hal_spec->rx_tsf_filter
3904 		&& !(rcr & RCR_CBSSID_BCN) && (rcr_new & RCR_CBSSID_BCN)
3905 		&& self_action != MLME_STA_CONNECTING)
3906 		rtw_hal_tsf_update_restore(adapter);
3907 }
3908 
rtw_hal_rcr_set_chk_bssid_act_non(_adapter * adapter)3909 void rtw_hal_rcr_set_chk_bssid_act_non(_adapter *adapter)
3910 {
3911 	rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3912 }
3913 
hw_var_set_rcr_am(_adapter * adapter,u8 enable)3914 static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
3915 {
3916 	u32 rcr = RCR_AM;
3917 
3918 	if (enable)
3919 		rtw_hal_rcr_add(adapter, rcr);
3920 	else
3921 		rtw_hal_rcr_clear(adapter, rcr);
3922 }
3923 
hw_var_set_bcn_interval(_adapter * adapter,u16 interval)3924 static void hw_var_set_bcn_interval(_adapter *adapter, u16 interval)
3925 {
3926 #ifdef CONFIG_SWTIMER_BASED_TXBCN
3927 	interval = rtw_hal_bcn_interval_adjust(adapter, interval);
3928 #endif
3929 
3930 #ifdef RTW_HALMAC
3931 	rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), adapter->hw_port, interval);
3932 #else
3933 	rtw_write16(adapter, REG_MBSSID_BCN_SPACE, interval);
3934 #endif
3935 
3936 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3937 	{
3938 		struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
3939 		struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3940 
3941 		if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3942 			RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, interval, interval >> 1);
3943 			rtw_write8(adapter, REG_DRVERLYINT, interval >> 1);
3944 		}
3945 	}
3946 #endif
3947 }
3948 
3949 #if CONFIG_TX_AC_LIFETIME
3950 const char *const _tx_aclt_conf_str[] = {
3951 	"DEFAULT",
3952 	"AP_M2U",
3953 	"MESH",
3954 	"INVALID",
3955 };
3956 
dump_tx_aclt_force_val(void * sel,struct dvobj_priv * dvobj)3957 void dump_tx_aclt_force_val(void *sel, struct dvobj_priv *dvobj)
3958 {
3959 #define TX_ACLT_FORCE_MSG_LEN 64
3960 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3961 	struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3962 	char buf[TX_ACLT_FORCE_MSG_LEN];
3963 	int cnt = 0;
3964 
3965 	RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3966 		, hal_spec->tx_aclt_unit_factor * 32
3967 		, 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3968 
3969 	RTW_PRINT_SEL(sel, "%-5s %-12s %-12s\n", "en", "vo_vi(us)", "be_bk(us)");
3970 	RTW_PRINT_SEL(sel, " 0x%02x %12u %12u\n"
3971 		, conf->en
3972 		, conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3973 		, conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3974 	);
3975 
3976 	cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "%5s", conf->en == 0xFF ? "AUTO" : "FORCE");
3977 	if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3978 		goto exit;
3979 
3980 	if (conf->vo_vi)
3981 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->vo_vi);
3982 	else
3983 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "         AUTO");
3984 	if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3985 		goto exit;
3986 
3987 
3988 	if (conf->be_bk)
3989 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->be_bk);
3990 	else
3991 		cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "         AUTO");
3992 	if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3993 		goto exit;
3994 
3995 	RTW_PRINT_SEL(sel, "%s\n", buf);
3996 
3997 exit:
3998 	return;
3999 }
4000 
rtw_hal_set_tx_aclt_force_val(_adapter * adapter,struct tx_aclt_conf_t * input,u8 arg_num)4001 void rtw_hal_set_tx_aclt_force_val(_adapter *adapter, struct tx_aclt_conf_t *input, u8 arg_num)
4002 {
4003 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4004 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4005 	struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
4006 
4007 	if (arg_num >= 1) {
4008 		if (input->en == 0xFF)
4009 			conf->en = input->en;
4010 		else
4011 			conf->en = input->en & 0xF;
4012 	}
4013 	if (arg_num >= 2) {
4014 		conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
4015 		if (conf->vo_vi > 0xFFFF)
4016 			conf->vo_vi = 0xFFFF;
4017 	}
4018 	if (arg_num >= 3) {
4019 		conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
4020 		if (conf->be_bk > 0xFFFF)
4021 			conf->be_bk = 0xFFFF;
4022 	}
4023 }
4024 
dump_tx_aclt_confs(void * sel,struct dvobj_priv * dvobj)4025 void dump_tx_aclt_confs(void *sel, struct dvobj_priv *dvobj)
4026 {
4027 #define TX_ACLT_CONF_MSG_LEN 32
4028 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
4029 	struct tx_aclt_conf_t *conf;
4030 	char buf[TX_ACLT_CONF_MSG_LEN];
4031 	int cnt;
4032 	int i;
4033 
4034 	RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
4035 		, hal_spec->tx_aclt_unit_factor * 32
4036 		, 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
4037 
4038 	RTW_PRINT_SEL(sel, "%-7s %-1s %-3s %-9s %-9s %-10s %-10s\n"
4039 		, "name", "#", "en", "vo_vi(us)", "be_bk(us)", "vo_vi(reg)", "be_bk(reg)");
4040 
4041 	for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
4042 		conf = &dvobj->tx_aclt_confs[i];
4043 		cnt = 0;
4044 
4045 		if (conf->vo_vi)
4046 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "     0x%04x", conf->vo_vi);
4047 		else
4048 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "        N/A");
4049 		if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
4050 			continue;
4051 
4052 		if (conf->be_bk)
4053 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "     0x%04x", conf->be_bk);
4054 		else
4055 			cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, "        N/A");
4056 		if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
4057 			continue;
4058 
4059 		RTW_PRINT_SEL(sel, "%7s %1u 0x%x %9u %9u%s\n"
4060 			, tx_aclt_conf_str(i), i
4061 			, conf->en
4062 			, conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
4063 			, conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
4064 			, buf
4065 		);
4066 	}
4067 }
4068 
rtw_hal_set_tx_aclt_conf(_adapter * adapter,u8 conf_idx,struct tx_aclt_conf_t * input,u8 arg_num)4069 void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_conf_t *input, u8 arg_num)
4070 {
4071 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4072 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4073 	struct tx_aclt_conf_t *conf;
4074 
4075 	if (conf_idx >= TX_ACLT_CONF_NUM)
4076 		return;
4077 
4078 	conf = &dvobj->tx_aclt_confs[conf_idx];
4079 
4080 	if (arg_num >= 1) {
4081 		if (input->en != 0xFF)
4082 			conf->en = input->en & 0xF;
4083 	}
4084 	if (arg_num >= 2) {
4085 		conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
4086 		if (conf->vo_vi > 0xFFFF)
4087 			conf->vo_vi = 0xFFFF;
4088 	}
4089 	if (arg_num >= 3) {
4090 		conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
4091 		if (conf->be_bk > 0xFFFF)
4092 			conf->be_bk = 0xFFFF;
4093 	}
4094 }
4095 
rtw_hal_update_tx_aclt(_adapter * adapter)4096 void rtw_hal_update_tx_aclt(_adapter *adapter)
4097 {
4098 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4099 	struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter);
4100 	u8 lt_en = 0, lt_en_ori;
4101 	u16 lt_vo_vi = 0xFFFF, lt_be_bk = 0xFFFF;
4102 	u32 lt, lt_ori;
4103 	struct tx_aclt_conf_t *conf;
4104 	int i;
4105 #ifdef CONFIG_AP_MODE
4106 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
4107 	_adapter *iface;
4108 	u8 ap_m2u_num = 0;
4109 
4110 	for (i = 0; i < dvobj->iface_nums; i++) {
4111 		iface = dvobj->padapters[i];
4112 		if (!iface)
4113 			continue;
4114 
4115 		if (MLME_IS_AP(iface)
4116 			&& ((iface->b2u_flags_ap_src & RTW_AP_B2U_IP_MCAST)
4117 				|| (iface->b2u_flags_ap_fwd & RTW_AP_B2U_IP_MCAST))
4118 		)
4119 			ap_m2u_num++;
4120 	}
4121 #endif
4122 #endif /* CONFIG_AP_MODE */
4123 
4124 	lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN);
4125 	lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME);
4126 
4127 	for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
4128 		if (!(dvobj->tx_aclt_flags & BIT(i)))
4129 			continue;
4130 
4131 		conf = &dvobj->tx_aclt_confs[i];
4132 
4133 		if (i == TX_ACLT_CONF_DEFAULT) {
4134 			/* first and default status, assign directly */
4135 			lt_en = conf->en;
4136 			if (conf->vo_vi)
4137 				lt_vo_vi = conf->vo_vi;
4138 			if (conf->be_bk)
4139 				lt_be_bk = conf->be_bk;
4140 		}
4141 		#ifdef CONFIG_AP_MODE
4142 		#if CONFIG_RTW_AP_DATA_BMC_TO_UC || defined(CONFIG_RTW_MESH)
4143 		else if (0
4144 			#if CONFIG_RTW_AP_DATA_BMC_TO_UC
4145 			|| (i == TX_ACLT_CONF_AP_M2U
4146 				&& ap_m2u_num
4147 				&& macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */)
4148 			#endif
4149 			#ifdef CONFIG_RTW_MESH
4150 			|| (i == TX_ACLT_CONF_MESH
4151 				&& macid_ctl->op_num[H2C_MSR_ROLE_MESH] > 1 /* implies only 1 MESH mode supported */)
4152 			#endif
4153 		) {
4154 			/* long term status, OR en and MIN lifetime */
4155 			lt_en |= conf->en;
4156 			if (conf->vo_vi && lt_vo_vi > conf->vo_vi)
4157 				lt_vo_vi = conf->vo_vi;
4158 			if (conf->be_bk && lt_be_bk > conf->be_bk)
4159 				lt_be_bk = conf->be_bk;
4160 		}
4161 		#endif
4162 		#endif /* CONFIG_AP_MODE */
4163 	}
4164 
4165 	if (dvobj->tx_aclt_force_val.en != 0xFF)
4166 		lt_en = dvobj->tx_aclt_force_val.en;
4167 	if (dvobj->tx_aclt_force_val.vo_vi)
4168 		lt_vo_vi = dvobj->tx_aclt_force_val.vo_vi;
4169 	if (dvobj->tx_aclt_force_val.be_bk)
4170 		lt_be_bk = dvobj->tx_aclt_force_val.be_bk;
4171 
4172 	lt_en = (lt_en_ori & 0xF0) | (lt_en & 0x0F);
4173 	lt = (lt_be_bk << 16) | lt_vo_vi;
4174 
4175 	if (0)
4176 		RTW_INFO("lt_en:0x%x(0x%x), lt:0x%08x(0x%08x)\n", lt_en, lt_en_ori, lt, lt_ori);
4177 
4178 	if (lt_en != lt_en_ori)
4179 		rtw_write8(adapter, REG_LIFETIME_EN, lt_en);
4180 	if (lt != lt_ori)
4181 		rtw_write32(adapter, REG_PKT_LIFE_TIME, lt);
4182 }
4183 #endif /* CONFIG_TX_AC_LIFETIME */
4184 
hw_var_port_switch(_adapter * adapter)4185 void hw_var_port_switch(_adapter *adapter)
4186 {
4187 #ifdef CONFIG_CONCURRENT_MODE
4188 #ifdef CONFIG_RUNTIME_PORT_SWITCH
4189 	/*
4190 	0x102: MSR
4191 	0x550: REG_BCN_CTRL
4192 	0x551: REG_BCN_CTRL_1
4193 	0x55A: REG_ATIMWND
4194 	0x560: REG_TSFTR
4195 	0x568: REG_TSFTR1
4196 	0x570: REG_ATIMWND_1
4197 	0x610: REG_MACID
4198 	0x618: REG_BSSID
4199 	0x700: REG_MACID1
4200 	0x708: REG_BSSID1
4201 	*/
4202 
4203 	int i;
4204 	u8 msr;
4205 	u8 bcn_ctrl;
4206 	u8 bcn_ctrl_1;
4207 	u8 atimwnd[2];
4208 	u8 atimwnd_1[2];
4209 	u8 tsftr[8];
4210 	u8 tsftr_1[8];
4211 	u8 macid[6];
4212 	u8 bssid[6];
4213 	u8 macid_1[6];
4214 	u8 bssid_1[6];
4215 #if defined(CONFIG_RTL8192F)
4216 	u16 wlan_act_mask_ctrl = 0;
4217 	u16 en_port_mask = EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION;
4218 #endif
4219 
4220 	u8 hw_port;
4221 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4222 	_adapter *iface = NULL;
4223 
4224 	msr = rtw_read8(adapter, MSR);
4225 	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4226 	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4227 #if defined(CONFIG_RTL8192F)
4228 	wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4229 #endif
4230 
4231 	for (i = 0; i < 2; i++)
4232 		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4233 	for (i = 0; i < 2; i++)
4234 		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4235 
4236 	for (i = 0; i < 8; i++)
4237 		tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4238 	for (i = 0; i < 8; i++)
4239 		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4240 
4241 	for (i = 0; i < 6; i++)
4242 		macid[i] = rtw_read8(adapter, REG_MACID + i);
4243 
4244 	for (i = 0; i < 6; i++)
4245 		bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4246 
4247 	for (i = 0; i < 6; i++)
4248 		macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4249 
4250 	for (i = 0; i < 6; i++)
4251 		bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4252 
4253 #ifdef DBG_RUNTIME_PORT_SWITCH
4254 	RTW_INFO(FUNC_ADPT_FMT" before switch\n"
4255 		 "msr:0x%02x\n"
4256 		 "bcn_ctrl:0x%02x\n"
4257 		 "bcn_ctrl_1:0x%02x\n"
4258 #if defined(CONFIG_RTL8192F)
4259 		 "wlan_act_mask_ctrl:0x%02x\n"
4260 #endif
4261 		 "atimwnd:0x%04x\n"
4262 		 "atimwnd_1:0x%04x\n"
4263 		 "tsftr:%llu\n"
4264 		 "tsftr1:%llu\n"
4265 		 "macid:"MAC_FMT"\n"
4266 		 "bssid:"MAC_FMT"\n"
4267 		 "macid_1:"MAC_FMT"\n"
4268 		 "bssid_1:"MAC_FMT"\n"
4269 		 , FUNC_ADPT_ARG(adapter)
4270 		 , msr
4271 		 , bcn_ctrl
4272 		 , bcn_ctrl_1
4273 #if defined(CONFIG_RTL8192F)
4274 		 , wlan_act_mask_ctrl
4275 #endif
4276 		 , *((u16 *)atimwnd)
4277 		 , *((u16 *)atimwnd_1)
4278 		 , *((u64 *)tsftr)
4279 		 , *((u64 *)tsftr_1)
4280 		 , MAC_ARG(macid)
4281 		 , MAC_ARG(bssid)
4282 		 , MAC_ARG(macid_1)
4283 		 , MAC_ARG(bssid_1)
4284 		);
4285 #endif /* DBG_RUNTIME_PORT_SWITCH */
4286 
4287 	/* disable bcn function, disable update TSF */
4288 	rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4289 	rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4290 
4291 #if defined(CONFIG_RTL8192F)
4292 	rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl & ~en_port_mask);
4293 #endif
4294 
4295 	/* switch msr */
4296 	msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
4297 	rtw_write8(adapter, MSR, msr);
4298 
4299 	/* write port0 */
4300 	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
4301 	for (i = 0; i < 2; i++)
4302 		rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
4303 	for (i = 0; i < 8; i++)
4304 		rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
4305 	for (i = 0; i < 6; i++)
4306 		rtw_write8(adapter, REG_MACID + i, macid_1[i]);
4307 	for (i = 0; i < 6; i++)
4308 		rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
4309 
4310 	/* write port1 */
4311 	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
4312 	for (i = 0; i < 2; i++)
4313 		rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
4314 	for (i = 0; i < 8; i++)
4315 		rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
4316 	for (i = 0; i < 6; i++)
4317 		rtw_write8(adapter, REG_MACID1 + i, macid[i]);
4318 	for (i = 0; i < 6; i++)
4319 		rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
4320 
4321 	/* write bcn ctl */
4322 #ifdef CONFIG_BT_COEXIST
4323 	/* always enable port0 beacon function for PSTDMA */
4324 	if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
4325 	    || IS_HARDWARE_TYPE_8723D(adapter))
4326 		bcn_ctrl_1 |= EN_BCN_FUNCTION;
4327 	/* always disable port1 beacon function for PSTDMA */
4328 	if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
4329 		bcn_ctrl &= ~EN_BCN_FUNCTION;
4330 #endif
4331 	rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
4332 	rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
4333 
4334 #if defined(CONFIG_RTL8192F)
4335 	/* if the setting of port0 and port1 are the same, it does not need to switch port setting*/
4336 	if(((wlan_act_mask_ctrl & en_port_mask) != 0) && ((wlan_act_mask_ctrl & en_port_mask)
4337 		!= (EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION)))
4338 		wlan_act_mask_ctrl ^= en_port_mask;
4339 	rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl);
4340 #endif
4341 
4342 	if (adapter->iface_id == IFACE_ID0)
4343 		iface = dvobj->padapters[IFACE_ID1];
4344 	else if (adapter->iface_id == IFACE_ID1)
4345 		iface = dvobj->padapters[IFACE_ID0];
4346 
4347 
4348 	if (adapter->hw_port == HW_PORT0) {
4349 		adapter->hw_port = HW_PORT1;
4350 		iface->hw_port = HW_PORT0;
4351 		RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4352 			  ADPT_ARG(iface), ADPT_ARG(adapter));
4353 	} else {
4354 		adapter->hw_port = HW_PORT0;
4355 		iface->hw_port = HW_PORT1;
4356 		RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4357 			  ADPT_ARG(adapter), ADPT_ARG(iface));
4358 	}
4359 
4360 #ifdef DBG_RUNTIME_PORT_SWITCH
4361 	msr = rtw_read8(adapter, MSR);
4362 	bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4363 	bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4364 #if defined(CONFIG_RTL8192F)
4365 	wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4366 #endif
4367 
4368 	for (i = 0; i < 2; i++)
4369 		atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4370 	for (i = 0; i < 2; i++)
4371 		atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4372 
4373 	for (i = 0; i < 8; i++)
4374 		tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4375 	for (i = 0; i < 8; i++)
4376 		tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4377 
4378 	for (i = 0; i < 6; i++)
4379 		macid[i] = rtw_read8(adapter, REG_MACID + i);
4380 
4381 	for (i = 0; i < 6; i++)
4382 		bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4383 
4384 	for (i = 0; i < 6; i++)
4385 		macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4386 
4387 	for (i = 0; i < 6; i++)
4388 		bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4389 
4390 	RTW_INFO(FUNC_ADPT_FMT" after switch\n"
4391 		 "msr:0x%02x\n"
4392 		 "bcn_ctrl:0x%02x\n"
4393 		 "bcn_ctrl_1:0x%02x\n"
4394 #if defined(CONFIG_RTL8192F)
4395 		 "wlan_act_mask_ctrl:0x%02x\n"
4396 #endif
4397 		 "atimwnd:%u\n"
4398 		 "atimwnd_1:%u\n"
4399 		 "tsftr:%llu\n"
4400 		 "tsftr1:%llu\n"
4401 		 "macid:"MAC_FMT"\n"
4402 		 "bssid:"MAC_FMT"\n"
4403 		 "macid_1:"MAC_FMT"\n"
4404 		 "bssid_1:"MAC_FMT"\n"
4405 		 , FUNC_ADPT_ARG(adapter)
4406 		 , msr
4407 		 , bcn_ctrl
4408 		 , bcn_ctrl_1
4409 #if defined(CONFIG_RTL8192F)
4410 		 , wlan_act_mask_ctrl
4411 #endif
4412 		 , *((u16 *)atimwnd)
4413 		 , *((u16 *)atimwnd_1)
4414 		 , *((u64 *)tsftr)
4415 		 , *((u64 *)tsftr_1)
4416 		 , MAC_ARG(macid)
4417 		 , MAC_ARG(bssid)
4418 		 , MAC_ARG(macid_1)
4419 		 , MAC_ARG(bssid_1)
4420 		);
4421 #endif /* DBG_RUNTIME_PORT_SWITCH */
4422 
4423 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
4424 #endif /* CONFIG_CONCURRENT_MODE */
4425 }
4426 
4427 const char *const _h2c_msr_role_str[] = {
4428 	"RSVD",
4429 	"STA",
4430 	"AP",
4431 	"GC",
4432 	"GO",
4433 	"TDLS",
4434 	"ADHOC",
4435 	"MESH",
4436 	"INVALID",
4437 };
4438 
4439 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_default_port_id_cmd(_adapter * adapter,u8 mac_id)4440 s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
4441 {
4442 	s32 ret = _SUCCESS;
4443 	u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
4444 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4445 	u8 port_id = rtw_hal_get_port(adapter);
4446 
4447 	if ((dvobj->dft.port_id == port_id) && (dvobj->dft.mac_id == mac_id))
4448 		return ret;
4449 
4450 	SET_H2CCMD_DFTPID_PORT_ID(parm, port_id);
4451 	SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
4452 
4453 	RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
4454 	RTW_INFO("%s ("ADPT_FMT") port_id :%d, mad_id:%d\n",
4455 		__func__, ADPT_ARG(adapter), port_id, mac_id);
4456 
4457 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
4458 	dvobj->dft.port_id = port_id;
4459 	dvobj->dft.mac_id = mac_id;
4460 
4461 	return ret;
4462 }
rtw_set_default_port_id(_adapter * adapter)4463 s32 rtw_set_default_port_id(_adapter *adapter)
4464 {
4465 	s32 ret = _SUCCESS;
4466 	struct sta_info		*psta;
4467 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4468 
4469 	if (is_client_associated_to_ap(adapter)) {
4470 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
4471 		if (psta)
4472 			ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
4473 	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
4474 
4475 	} else {
4476 	}
4477 
4478 	return ret;
4479 }
rtw_set_ps_rsvd_page(_adapter * adapter)4480 s32 rtw_set_ps_rsvd_page(_adapter *adapter)
4481 {
4482 	s32 ret = _SUCCESS;
4483 	u16 media_status_rpt = RT_MEDIA_CONNECT;
4484 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4485 
4486 	if (adapter->iface_id == pwrctl->fw_psmode_iface_id)
4487 		return ret;
4488 
4489 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
4490 			  (u8 *)&media_status_rpt);
4491 
4492 	return ret;
4493 }
4494 
4495 #if 0
4496 _adapter * _rtw_search_dp_iface(_adapter *adapter)
4497 {
4498 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4499 	_adapter *iface;
4500 	_adapter *target_iface = NULL;
4501 	int i;
4502 	u8 sta_num = 0, tdls_num = 0, ap_num = 0, mesh_num = 0, adhoc_num = 0;
4503 	u8 p2p_go_num = 0, p2p_gc_num = 0;
4504 	_adapter *sta_ifs[8];
4505 	_adapter *ap_ifs[8];
4506 	_adapter *mesh_ifs[8];
4507 	_adapter *gc_ifs[8];
4508 	_adapter *go_ifs[8];
4509 
4510 	for (i = 0; i < dvobj->iface_nums; i++) {
4511 		iface = dvobj->padapters[i];
4512 
4513 		if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
4514 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4515 				sta_ifs[sta_num++] = iface;
4516 
4517 				#ifdef CONFIG_TDLS
4518 				if (iface->tdlsinfo.link_established == _TRUE)
4519 					tdls_num++;
4520 				#endif
4521 				#ifdef CONFIG_P2P
4522 				if (MLME_IS_GC(iface))
4523 					gc_ifs[p2p_gc_num++] = iface;
4524 				#endif
4525 			}
4526 #ifdef CONFIG_AP_MODE
4527 		} else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
4528 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4529 				ap_ifs[ap_num++] = iface;
4530 				#ifdef CONFIG_P2P
4531 				if (MLME_IS_GO(iface))
4532 					go_ifs[p2p_go_num++] = iface;
4533 				#endif
4534 			}
4535 #endif
4536 		} else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
4537 			&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4538 		) {
4539 			adhoc_num++;
4540 
4541 #ifdef CONFIG_RTW_MESH
4542 		} else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
4543 			&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4544 		) {
4545 			mesh_ifs[mesh_num++] = iface;
4546 #endif
4547 		}
4548 	}
4549 
4550 	if (p2p_gc_num) {
4551 		target_iface = gc_ifs[0];
4552 	}
4553 	else if (sta_num) {
4554 		if(sta_num == 1) {
4555 			target_iface = sta_ifs[0];
4556 		} else if (sta_num >= 2) {
4557 			/*TODO get target_iface by timestamp*/
4558 			target_iface = sta_ifs[0];
4559 		}
4560 	} else if (ap_num) {
4561 		target_iface = ap_ifs[0];
4562 	}
4563 
4564 	RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", sta_num);
4565 	RTW_INFO("[IFS_ASSOC_STATUS] - TDLS :%d", tdls_num);
4566 	RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", ap_num);
4567 	RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", mesh_num);
4568 	RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", adhoc_num);
4569 	RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", p2p_gc_num);
4570 	RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", p2p_go_num);
4571 
4572 	if (target_iface)
4573 		RTW_INFO("%s => target_iface ("ADPT_FMT")\n",
4574 			__func__, ADPT_ARG(target_iface));
4575 	else
4576 		RTW_INFO("%s => target_iface NULL\n", __func__);
4577 
4578 	return target_iface;
4579 }
4580 
4581 void rtw_search_default_port(_adapter *adapter)
4582 {
4583 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4584 	_adapter *adp_iface = NULL;
4585 #ifdef CONFIG_WOWLAN
4586 	struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
4587 
4588 	if (pwrpriv->wowlan_mode == _TRUE) {
4589 		adp_iface = adapter;
4590 		goto exit;
4591 	}
4592 #endif
4593 	adp_iface = _rtw_search_dp_iface(adapter);
4594 
4595 exit :
4596 	if ((adp_iface != NULL) && (MLME_IS_STA(adp_iface)))
4597 		rtw_set_default_port_id(adp_iface);
4598 	else
4599 		rtw_hal_set_default_port_id_cmd(adapter, 0);
4600 
4601 	if (1) {
4602 		_adapter *tmp_adp;
4603 
4604 		tmp_adp = (adp_iface) ? adp_iface : adapter;
4605 
4606 		RTW_INFO("%s ("ADPT_FMT")=> hw_port :%d, default_port(%d)\n",
4607 			__func__, ADPT_ARG(adapter), get_hw_port(tmp_adp), get_dft_portid(tmp_adp));
4608 	}
4609 }
4610 #endif
4611 #endif /*CONFIG_FW_MULTI_PORT_SUPPORT*/
4612 
4613 #ifdef CONFIG_P2P_PS
4614 #ifdef RTW_HALMAC
rtw_set_p2p_ps_offload_cmd(_adapter * adapter,u8 p2p_ps_state)4615 void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
4616 {
4617 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4618 	struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4619 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
4620 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
4621 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
4622 	struct sta_priv		*pstapriv = &adapter->stapriv;
4623 	struct sta_info		*psta;
4624 	HAL_P2P_PS_PARA p2p_ps_para;
4625 	int status = -1;
4626 	u8 i;
4627 	u8 hw_port = rtw_hal_get_port(adapter);
4628 
4629 	_rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
4630 	_rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
4631 
4632 	(&p2p_ps_para)->p2p_port_id = hw_port;
4633 	(&p2p_ps_para)->p2p_group = 0;
4634 	psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
4635 	if (psta) {
4636 		(&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
4637 	} else {
4638 		if (p2p_ps_state != P2P_PS_DISABLE) {
4639 			RTW_ERR("%s , psta was NULL\n", __func__);
4640 			return;
4641 		}
4642 	}
4643 
4644 
4645 	switch (p2p_ps_state) {
4646 	case P2P_PS_DISABLE:
4647 		RTW_INFO("P2P_PS_DISABLE\n");
4648 		_rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
4649 		break;
4650 
4651 	case P2P_PS_ENABLE:
4652 		RTW_INFO("P2P_PS_ENABLE\n");
4653 		/* update CTWindow value. */
4654 		if (pwdinfo->ctwindow > 0) {
4655 			(&p2p_ps_para)->ctwindow_en = 1;
4656 			(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4657 			/*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
4658 		}
4659 
4660 
4661 		if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
4662 			(&p2p_ps_para)->offload_en = 1;
4663 			if (pwdinfo->role == P2P_ROLE_GO) {
4664 				(&p2p_ps_para)->role = 1;
4665 				(&p2p_ps_para)->all_sta_sleep = 0;
4666 			} else
4667 				(&p2p_ps_para)->role = 0;
4668 
4669 			(&p2p_ps_para)->discovery = 0;
4670 		}
4671 		/* hw only support 2 set of NoA */
4672 		for (i = 0; i < pwdinfo->noa_num; i++) {
4673 			/* To control the register setting for which NOA */
4674 			(&p2p_ps_para)->noa_sel = i;
4675 			(&p2p_ps_para)->noa_en = 1;
4676 			(&p2p_ps_para)->disable_close_rf = 0;
4677 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
4678 #ifdef CONFIG_CONCURRENT_MODE
4679 			if (rtw_mi_buddy_check_fwstate(adapter, WIFI_ASOC_STATE))
4680 #endif /* CONFIG_CONCURRENT_MODE */
4681 				(&p2p_ps_para)->disable_close_rf = 1;
4682 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
4683 			/* config P2P NoA Descriptor Register */
4684 			/* config NOA duration */
4685 			(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
4686 			/* config NOA interval */
4687 			(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
4688 			/* config NOA start time */
4689 			(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
4690 			/* config NOA count */
4691 			(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
4692 			/*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
4693 				(&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
4694 				(&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
4695 			status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4696 			if (status == -1)
4697 				RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4698 		}
4699 
4700 		break;
4701 
4702 	case P2P_PS_SCAN:
4703 		/*This feature FW not ready 20161116 YiWei*/
4704 		return;
4705 		/*
4706 		RTW_INFO("P2P_PS_SCAN\n");
4707 		(&p2p_ps_para)->discovery = 1;
4708 		(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4709 		(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4710 		(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4711 		(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4712 		(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4713 		*/
4714 		break;
4715 
4716 	case P2P_PS_SCAN_DONE:
4717 		/*This feature FW not ready 20161116 YiWei*/
4718 		return;
4719 		/*
4720 		RTW_INFO("P2P_PS_SCAN_DONE\n");
4721 		(&p2p_ps_para)->discovery = 0;
4722 		pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
4723 		(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4724 		(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4725 		(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4726 		(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4727 		(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4728 		*/
4729 		break;
4730 
4731 	default:
4732 		break;
4733 	}
4734 
4735 	if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
4736 		status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4737 		if (status == -1)
4738 			RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4739 	}
4740 	_rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
4741 
4742 }
4743 #endif /* RTW_HALMAC */
4744 #endif /* CONFIG_P2P */
4745 
4746 /*
4747 * rtw_hal_set_FwMediaStatusRpt_cmd -
4748 *
4749 * @adapter:
4750 * @opmode:  0:disconnect, 1:connect
4751 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
4752 * @miracast_sink: 0:source. 1:sink
4753 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
4754 * @macid:
4755 * @macid_ind:  0:update Media Status to macid.  1:update Media Status from macid to macid_end
4756 * @macid_end:
4757 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)4758 s32 rtw_hal_set_FwMediaStatusRpt_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, bool macid_ind, u8 macid_end)
4759 {
4760 	struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
4761 	u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
4762 	int i;
4763 	s32 ret;
4764 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4765 	u8 hw_port = rtw_hal_get_port(adapter);
4766 #endif
4767 	u8 op_num_change_bmp = 0;
4768 
4769 	SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
4770 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
4771 	SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
4772 	SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
4773 	SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
4774 	SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
4775 	SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
4776 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4777 	SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, hw_port);
4778 #endif
4779 	RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
4780 
4781 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
4782 	if (ret != _SUCCESS)
4783 		goto exit;
4784 
4785 #if defined(CONFIG_RTL8188E)
4786 	if (rtw_get_chip_type(adapter) == RTL8188E) {
4787 		HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4788 
4789 		/* 8188E FW doesn't set macid no link, driver does it by self */
4790 		if (opmode)
4791 			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
4792 		else
4793 			rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
4794 
4795 		/* for 8188E RA */
4796 #if (RATE_ADAPTIVE_SUPPORT == 1)
4797 		if (hal_data->fw_ractrl == _FALSE) {
4798 			u8 max_macid;
4799 
4800 			max_macid = rtw_search_max_mac_id(adapter);
4801 			rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
4802 		}
4803 #endif
4804 	}
4805 #endif
4806 
4807 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
4808 	/* TODO: this should move to IOT issue area */
4809 	if (rtw_get_chip_type(adapter) == RTL8812
4810 		|| rtw_get_chip_type(adapter) == RTL8821
4811 	) {
4812 		if (MLME_IS_STA(adapter))
4813 			Hal_PatchwithJaguar_8812(adapter, opmode);
4814 	}
4815 #endif
4816 
4817 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
4818 	if (macid_ind == 0)
4819 		macid_end = macid;
4820 
4821 	for (i = macid; macid <= macid_end; macid++) {
4822 		op_num_change_bmp |= rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
4823 		if (!opmode) {
4824 			rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
4825 			rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
4826 			rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
4827 			rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
4828 		}
4829 	}
4830 
4831 #if CONFIG_TX_AC_LIFETIME
4832 	if (op_num_change_bmp)
4833 		rtw_hal_update_tx_aclt(adapter);
4834 #endif
4835 
4836 	if (!opmode)
4837 		rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
4838 
4839 exit:
4840 	return ret;
4841 }
4842 
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)4843 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
4844 {
4845 	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
4846 }
4847 
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)4848 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
4849 {
4850 	return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
4851 }
4852 
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4853 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4854 {
4855 	u8	u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
4856 	u8	ret = 0;
4857 
4858 	RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
4859 		 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
4860 		 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
4861 		 rsvdpageloc->LocBTQosNull);
4862 
4863 	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
4864 	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
4865 	SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
4866 	SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
4867 	SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
4868 
4869 	ret = rtw_hal_fill_h2c_cmd(padapter,
4870 				   H2C_RSVD_PAGE,
4871 				   H2C_RSVDPAGE_LOC_LEN,
4872 				   u1H2CRsvdPageParm);
4873 
4874 }
4875 
4876 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)4877 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
4878 {
4879 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4880 
4881 	if (IS_8723D_SERIES(pHalData->version_id) || IS_8192F_SERIES(pHalData->version_id)
4882 		|| IS_8822B_SERIES(pHalData->version_id) || IS_8821C_SERIES(pHalData->version_id)
4883 		|| IS_8822C_SERIES(pHalData->version_id))
4884 		rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4885 	/*
4886 	* Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
4887 	* It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
4888 	* and implement HAL function.
4889 	* TODO: GPIO_8 multi function?
4890 	*/
4891 
4892 	if ((index == 13 || index == 14)
4893 		#if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
4894 		/* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
4895 		&& (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
4896 		#endif
4897 	)
4898 		rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4899 }
4900 
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)4901 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
4902 {
4903 #if defined(CONFIG_RTL8192F)
4904 	rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&outputval));
4905 #else
4906 	if (index <= 7) {
4907 		/* config GPIO mode */
4908 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4909 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4910 
4911 		/* config GPIO Sel */
4912 		/* 0: input */
4913 		/* 1: output */
4914 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4915 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
4916 
4917 		/* set output value */
4918 		if (outputval) {
4919 			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4920 				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
4921 		} else {
4922 			rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4923 				rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
4924 		}
4925 	} else if (index <= 15) {
4926 		/* 88C Series: */
4927 		/* index: 11~8 transform to 3~0 */
4928 		/* 8723 Series: */
4929 		/* index: 12~8 transform to 4~0 */
4930 
4931 		index -= 8;
4932 
4933 		/* config GPIO mode */
4934 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4935 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4936 
4937 		/* config GPIO Sel */
4938 		/* 0: input */
4939 		/* 1: output */
4940 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4941 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
4942 
4943 		/* set output value */
4944 		if (outputval) {
4945 			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4946 				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
4947 		} else {
4948 			rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4949 				rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
4950 		}
4951 	} else {
4952 		RTW_INFO("%s: invalid GPIO%d=%d\n",
4953 			 __FUNCTION__, index, outputval);
4954 	}
4955 #endif
4956 }
rtw_hal_set_input_gpio(_adapter * padapter,u8 index)4957 void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
4958 {
4959 #if defined(CONFIG_RTL8192F)
4960 	rtw_hal_set_hwreg(padapter, HW_VAR_WOW_INPUT_GPIO, (u8 *)(&index));
4961 #else
4962 	if (index <= 7) {
4963 		/* config GPIO mode */
4964 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4965 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4966 
4967 		/* config GPIO Sel */
4968 		/* 0: input */
4969 		/* 1: output */
4970 		rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4971 			rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
4972 
4973 	} else if (index <= 15) {
4974 		/* 88C Series: */
4975 		/* index: 11~8 transform to 3~0 */
4976 		/* 8723 Series: */
4977 		/* index: 12~8 transform to 4~0 */
4978 
4979 		index -= 8;
4980 
4981 		/* config GPIO mode */
4982 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4983 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4984 
4985 		/* config GPIO Sel */
4986 		/* 0: input */
4987 		/* 1: output */
4988 		rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4989 			rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
4990 	} else
4991 		RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
4992 #endif
4993 }
4994 
4995 #endif
4996 
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4997 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4998 {
4999 	struct	pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
5000 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
5001 	u8 ret = 0;
5002 #ifdef CONFIG_WOWLAN
5003 	u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
5004 
5005 	RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
5006 		 __func__, rsvdpageloc->LocRemoteCtrlInfo,
5007 		 rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
5008 		 rsvdpageloc->LocNDPInfo);
5009 	RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
5010 		 __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
5011 		 rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
5012 
5013 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
5014 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
5015 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
5016 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
5017 							rsvdpageloc->LocNbrAdv);
5018 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
5019 						      rsvdpageloc->LocNDPInfo);
5020 #ifdef CONFIG_GTK_OL
5021 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
5022 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
5023 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
5024 #endif /* CONFIG_GTK_OL */
5025 		ret = rtw_hal_fill_h2c_cmd(padapter,
5026 					   H2C_AOAC_RSVD_PAGE,
5027 					   H2C_AOAC_RSVDPAGE_LOC_LEN,
5028 					   u1H2CAoacRsvdPageParm);
5029 
5030 		RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
5031 		_rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
5032 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
5033 					 rsvdpageloc->LocAOACReport);
5034 		ret = rtw_hal_fill_h2c_cmd(padapter,
5035 				   H2C_AOAC_RSVDPAGE3,
5036 				   H2C_AOAC_RSVDPAGE_LOC_LEN,
5037 				   u1H2CAoacRsvdPageParm);
5038 		pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
5039 	}
5040 #ifdef CONFIG_PNO_SUPPORT
5041 	else {
5042 
5043 		if (!pwrpriv->wowlan_in_resume) {
5044 			RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
5045 			_rtw_memset(&u1H2CAoacRsvdPageParm, 0,
5046 				    sizeof(u1H2CAoacRsvdPageParm));
5047 			SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
5048 						      rsvdpageloc->LocPNOInfo);
5049 			ret = rtw_hal_fill_h2c_cmd(padapter,
5050 						   H2C_AOAC_RSVDPAGE3,
5051 						   H2C_AOAC_RSVDPAGE_LOC_LEN,
5052 						   u1H2CAoacRsvdPageParm);
5053 		}
5054 	}
5055 #endif /* CONFIG_PNO_SUPPORT */
5056 #endif /* CONFIG_WOWLAN */
5057 }
5058 
5059 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)5060 void rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
5061 {
5062 	struct	hal_ops *pHalFunc = &padapter->hal_func;
5063 	u8	u1H2C_fw_dbg_msg_pkt_parm[H2C_FW_DBG_MSG_PKT_LEN] = {0};
5064 	u8	ret = 0;
5065 
5066 
5067 	RTW_INFO("RsvdPageLoc: loc_fw_dbg_msg_pkt =%d\n", rsvdpageloc->loc_fw_dbg_msg_pkt);
5068 
5069 	SET_H2CCMD_FW_DBG_MSG_PKT_EN(u1H2C_fw_dbg_msg_pkt_parm, 1);
5070 	SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(u1H2C_fw_dbg_msg_pkt_parm, rsvdpageloc->loc_fw_dbg_msg_pkt);
5071 	ret = rtw_hal_fill_h2c_cmd(padapter,
5072 				   H2C_FW_DBG_MSG_PKT,
5073 				   H2C_FW_DBG_MSG_PKT_LEN,
5074 				   u1H2C_fw_dbg_msg_pkt_parm);
5075 
5076 }
5077 #endif /*DBG_FW_DEBUG_MSG_PKT*/
5078 
5079 /*#define DBG_GET_RSVD_PAGE*/
rtw_hal_get_rsvd_page(_adapter * adapter,u32 page_offset,u32 page_num,u8 * buffer,u32 buffer_size)5080 int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
5081 	u32 page_num, u8 *buffer, u32 buffer_size)
5082 {
5083 	u32 addr = 0, size = 0, count = 0;
5084 	u32 page_size = 0, data_low = 0, data_high = 0;
5085 	u16 txbndy = 0, offset = 0;
5086 	u8 i = 0;
5087 	bool rst = _FALSE;
5088 
5089 #ifdef DBG_LA_MODE
5090 	struct registry_priv *registry_par = &adapter->registrypriv;
5091 
5092 	if(registry_par->la_mode_en == 1) {
5093 		RTW_INFO("%s LA debug mode can't dump rsvd pg \n", __func__);
5094 		return rst;
5095 	}
5096 #endif
5097 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5098 
5099 	addr = page_offset * page_size;
5100 	size = page_num * page_size;
5101 
5102 	if (buffer_size < size) {
5103 		RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
5104 			__func__, buffer_size, size);
5105 		return rst;
5106 	}
5107 #ifdef RTW_HALMAC
5108 	if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
5109 		rst = _FALSE;
5110 	else
5111 		rst = _TRUE;
5112 #else
5113 	txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
5114 
5115 	offset = (txbndy + page_offset) * page_size / 8;
5116 	count = (buffer_size / 8) + 1;
5117 
5118 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
5119 
5120 	for (i = 0 ; i < count ; i++) {
5121 		rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
5122 		data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
5123 		data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
5124 		_rtw_memcpy(buffer + (i * 8),
5125 			&data_low, sizeof(data_low));
5126 		_rtw_memcpy(buffer + ((i * 8) + 4),
5127 			&data_high, sizeof(data_high));
5128 	}
5129 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
5130 	rst = _TRUE;
5131 #endif /*RTW_HALMAC*/
5132 
5133 #ifdef DBG_GET_RSVD_PAGE
5134 	RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
5135 		 __func__, page_offset, page_num, addr, size);
5136 	RTW_INFO_DUMP("\n", buffer, size);
5137 	RTW_INFO(" ==================================================\n");
5138 #endif
5139 	return rst;
5140 }
5141 
rtw_dump_rsvd_page(void * sel,_adapter * adapter,u8 page_offset,u8 page_num)5142 void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
5143 {
5144 #if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG)
5145 	u32 page_size = 0;
5146 	u8 *buffer = NULL;
5147 	u32 buf_size = 0;
5148 
5149 	if (page_num == 0)
5150 		return;
5151 
5152 	RTW_PRINT_SEL(sel, "======= RSVD PAGE DUMP =======\n");
5153 	RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
5154 
5155 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5156 	if (page_size) {
5157 		buf_size = page_size * page_num;
5158 		buffer = rtw_zvmalloc(buf_size);
5159 
5160 		if (buffer) {
5161 			rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
5162 			RTW_DUMP_SEL(sel, buffer, buf_size);
5163 			rtw_vmfree(buffer, buf_size);
5164 		} else
5165 			RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
5166 	} else
5167 			RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
5168 
5169 	RTW_PRINT_SEL(sel, "==========================\n");
5170 #endif
5171 }
5172 
5173 #ifdef CONFIG_SUPPORT_FIFO_DUMP
rtw_dump_fifo(void * sel,_adapter * adapter,u8 fifo_sel,u32 fifo_addr,u32 fifo_size)5174 void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
5175 {
5176 	u8 *buffer = NULL;
5177 	u32 buff_size = 0;
5178 	static const char * const fifo_sel_str[] = {
5179 		"TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
5180 	};
5181 
5182 	if (fifo_sel > 5) {
5183 		RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
5184 		return;
5185 	}
5186 
5187 	RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
5188 	RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
5189 
5190 	if (fifo_size) {
5191 		buff_size = RND4(fifo_size);
5192 		buffer = rtw_zvmalloc(buff_size);
5193 		if (buffer == NULL)
5194 			buff_size = 0;
5195 	}
5196 
5197 	rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
5198 
5199 	if (buffer) {
5200 		RTW_DUMP_SEL(sel, buffer, fifo_size);
5201 		rtw_vmfree(buffer, buff_size);
5202 	}
5203 
5204 	RTW_PRINT_SEL(sel, "==========================\n");
5205 }
5206 #endif
5207 
5208 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)5209 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
5210 {
5211 	RTW_INFO("%s: Set 0x690=0x00\n", __func__);
5212 	rtw_write8(adapter, REG_WOW_CTRL,
5213 		   (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
5214 	RTW_PRINT("%s: Release RXDMA\n", __func__);
5215 	rtw_write32(adapter, REG_RXPKT_NUM,
5216 		    (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
5217 }
5218 #if defined(CONFIG_RTL8188E)
rtw_hal_disable_tx_report(_adapter * adapter)5219 static void rtw_hal_disable_tx_report(_adapter *adapter)
5220 {
5221 	rtw_write8(adapter, REG_TX_RPT_CTRL,
5222 		   ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
5223 	RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5224 }
5225 
rtw_hal_enable_tx_report(_adapter * adapter)5226 static void rtw_hal_enable_tx_report(_adapter *adapter)
5227 {
5228 	rtw_write8(adapter, REG_TX_RPT_CTRL,
5229 		   ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
5230 	RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5231 }
5232 #endif
rtw_hal_release_rx_dma(_adapter * adapter)5233 static void rtw_hal_release_rx_dma(_adapter *adapter)
5234 {
5235 	u32 val32 = 0;
5236 
5237 	val32 = rtw_read32(adapter, REG_RXPKT_NUM);
5238 
5239 	rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
5240 
5241 	RTW_INFO("%s, [0x%04x]: 0x%08x\n",
5242 		 __func__, REG_RXPKT_NUM, (u32)(val32 & (~RW_RELEASE_EN)));
5243 }
5244 
rtw_hal_pause_rx_dma(_adapter * adapter)5245 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
5246 {
5247 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
5248 	u8 ret = 0;
5249 	s8 trycnt = 100;
5250 	u32 tmp = 0;
5251 	int res = 0;
5252 	/* RX DMA stop */
5253 	RTW_PRINT("Pause DMA\n");
5254 	rtw_write32(adapter, REG_RXPKT_NUM,
5255 		    (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
5256 	do {
5257 		if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
5258 #ifdef CONFIG_USB_HCI
5259 			/* stop interface before leave */
5260 			if (_TRUE == hal->usb_intf_start) {
5261 				rtw_intf_stop(adapter);
5262 				RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
5263 				RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
5264 			}
5265 #endif /* CONFIG_USB_HCI */
5266 
5267 			RTW_PRINT("RX_DMA_IDLE is true\n");
5268 			ret = _SUCCESS;
5269 			break;
5270 		}
5271 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5272 		else {
5273 			res = RecvOnePkt(adapter);
5274 			RTW_PRINT("RecvOnePkt Result: %d\n", res);
5275 		}
5276 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
5277 
5278 #ifdef CONFIG_USB_HCI
5279 		else {
5280 			/* to avoid interface start repeatedly  */
5281 			if (_FALSE == hal->usb_intf_start)
5282 				rtw_intf_start(adapter);
5283 		}
5284 #endif /* CONFIG_USB_HCI */
5285 	} while (trycnt--);
5286 
5287 	if (trycnt < 0) {
5288 		tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
5289 
5290 		RTW_PRINT("Stop RX DMA failed......\n");
5291 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
5292 		RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
5293 			  __func__, rtw_read16(adapter, REG_RXPKTNUM));
5294 #else
5295 		RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
5296 			  __func__, ((tmp & 0xFF00) >> 8));
5297 #endif
5298 		if (tmp & BIT(3))
5299 			RTW_PRINT("%s, RX DMA has req\n",
5300 				  __func__);
5301 		else
5302 			RTW_PRINT("%s, RX DMA no req\n",
5303 				  __func__);
5304 		ret = _FAIL;
5305 	}
5306 
5307 	return ret;
5308 }
5309 
5310 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5311 #ifndef RTW_HALMAC
rtw_hal_enable_cpwm2(_adapter * adapter)5312 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
5313 {
5314 	u8 ret = 0;
5315 	int res = 0;
5316 	u32 tmp = 0;
5317 #ifdef CONFIG_GPIO_WAKEUP
5318 	return _SUCCESS;
5319 #else
5320 	RTW_PRINT("%s\n", __func__);
5321 
5322 	res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5323 	if (!res)
5324 		RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
5325 	else
5326 		RTW_INFO("sdio_local_read fail\n");
5327 
5328 	tmp = SDIO_HIMR_CPWM2_MSK;
5329 
5330 	res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5331 
5332 	if (!res) {
5333 		res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5334 		RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
5335 		ret = _SUCCESS;
5336 	} else {
5337 		RTW_INFO("sdio_local_write fail\n");
5338 		ret = _FAIL;
5339 	}
5340 	return ret;
5341 #endif /* CONFIG_CPIO_WAKEUP */
5342 }
5343 #endif
5344 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
5345 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
5346 
5347 #ifdef CONFIG_WOWLAN
5348 /*
5349  * rtw_hal_check_wow_ctrl
5350  * chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
5351  *									If 0x1C7 == 0 (for 3081), WOW enable successful.
5352  *		     _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
5353  *									If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
5354  */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)5355 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
5356 {
5357 	u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
5358 	u8 mstatus = 0;
5359 	u8 reason = 0xFF;
5360 	u8 trycnt = 25;
5361 	u8 res = _FALSE;
5362 
5363 	if (IS_HARDWARE_TYPE_JAGUAR2(adapter) || IS_HARDWARE_TYPE_JAGUAR3(adapter)) {
5364 		if (chk_type) {
5365 			reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5366 			RTW_INFO("%s reason:0x%02x\n", __func__, reason);
5367 
5368 			while (reason && trycnt > 1) {
5369 				reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5370 				RTW_PRINT("Loop index: %d :0x%02x\n",
5371 					  trycnt, reason);
5372 				trycnt--;
5373 				rtw_msleep_os(20);
5374 			}
5375 			if (!reason)
5376 				res = _TRUE;
5377 			else
5378 				res = _FALSE;
5379 		} else {
5380 			/* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
5381 			fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
5382 			rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
5383 			RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
5384 
5385 			while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
5386 				rtw_msleep_os(20);
5387 				fe1_imr = rtw_read32(adapter, REG_FE1IMR);
5388 				rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
5389 				RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
5390 					  trycnt, fe1_imr, rxpkt_num);
5391 				trycnt--;
5392 			}
5393 
5394 			if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
5395 				res = _FALSE;
5396 			else
5397 				res = _TRUE;
5398 		}
5399 	} else {
5400 		mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5401 		RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
5402 
5403 
5404 		if (chk_type) {
5405 			while (!(mstatus & BIT1) && trycnt > 1) {
5406 				mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5407 				RTW_PRINT("Loop index: %d :0x%02x\n",
5408 					  trycnt, mstatus);
5409 				trycnt--;
5410 				rtw_msleep_os(20);
5411 			}
5412 			if (mstatus & BIT1)
5413 				res = _TRUE;
5414 			else
5415 				res = _FALSE;
5416 		} else {
5417 			while (mstatus & BIT1 && trycnt > 1) {
5418 				mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5419 				RTW_PRINT("Loop index: %d :0x%02x\n",
5420 					  trycnt, mstatus);
5421 				trycnt--;
5422 				rtw_msleep_os(20);
5423 			}
5424 
5425 			if (mstatus & BIT1)
5426 				res = _FALSE;
5427 			else
5428 				res = _TRUE;
5429 		}
5430 	}
5431 
5432 	RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
5433 		  __func__, chk_type, res, (25 - trycnt));
5434 	return res;
5435 }
5436 
5437 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_check_pno_enabled(_adapter * adapter)5438 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
5439 {
5440 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5441 	u8 res = 0, count = 0;
5442 	u8 ret = _FALSE;
5443 
5444 	if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
5445 		res = rtw_read8(adapter, REG_PNO_STATUS);
5446 		while (!(res & BIT(7)) && count < 25) {
5447 			RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
5448 				 count, res);
5449 			res = rtw_read8(adapter, REG_PNO_STATUS);
5450 			count++;
5451 			rtw_msleep_os(2);
5452 		}
5453 		if (res & BIT(7))
5454 			ret = _TRUE;
5455 		else
5456 			ret = _FALSE;
5457 		RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
5458 	}
5459 	return ret;
5460 }
5461 #endif
5462 
rtw_hal_backup_rate(_adapter * adapter)5463 static void rtw_hal_backup_rate(_adapter *adapter)
5464 {
5465 	RTW_INFO("%s\n", __func__);
5466 	/* backup data rate to register 0x8b for wowlan FW */
5467 	rtw_write8(adapter, 0x8d, 1);
5468 	rtw_write8(adapter, 0x8c, 0);
5469 	rtw_write8(adapter, 0x8f, 0x40);
5470 	rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
5471 }
5472 
5473 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)5474 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
5475 {
5476 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5477 	int cam_id, index = 0;
5478 	u8 *addr = NULL;
5479 
5480 	if (!MLME_IS_STA(adapter))
5481 		return;
5482 
5483 	addr = get_bssid(pmlmepriv);
5484 
5485 	if (addr == NULL) {
5486 		RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
5487 		return;
5488 	}
5489 
5490 	rtw_clean_dk_section(adapter);
5491 
5492 	do {
5493 		cam_id = rtw_camid_search(adapter, addr, index, 1);
5494 
5495 		if (cam_id == -1)
5496 			RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
5497 		else
5498 			rtw_sec_cam_swap(adapter, cam_id, index);
5499 
5500 		index++;
5501 	} while (index < 4);
5502 
5503 	rtw_write8(adapter, REG_SECCFG, 0xcc);
5504 }
5505 
rtw_hal_update_gtk_offload_info(_adapter * adapter)5506 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
5507 {
5508 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5509 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5510 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5511 	struct security_priv *psecuritypriv = &adapter->securitypriv;
5512 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5513 	struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
5514 	_irqL irqL;
5515 	u8 get_key[16];
5516 	u8 gtk_id = 0, offset = 0, i = 0, sz = 0, aoac_rpt_ver = 0, has_rekey = _FALSE;
5517 	u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
5518 
5519 	if (!MLME_IS_STA(adapter))
5520 		return;
5521 
5522 	_rtw_memset(get_key, 0, sizeof(get_key));
5523 	_rtw_memcpy(&replay_count,
5524 		paoac_rpt->replay_counter_eapol_key, 8);
5525 
5526 	/*read gtk key index*/
5527 	gtk_id = paoac_rpt->key_index;
5528 	aoac_rpt_ver = paoac_rpt->version_info;
5529 
5530 	if (aoac_rpt_ver == 0) {
5531 		/* initial verison */
5532 		if (gtk_id == 5)
5533 			has_rekey = _FALSE;
5534 		else
5535 			has_rekey = _TRUE;
5536 	} else if (aoac_rpt_ver >= 1) {
5537 		/* Add krack patch */
5538 		if (gtk_id == 5)
5539 			RTW_WARN("%s FW check iv fail\n", __func__);
5540 
5541 		if (aoac_rpt_ver == 1)
5542 			RTW_WARN("%s aoac report version should be update to v2\n", __func__);
5543 
5544 		/* Fix key id mismatch */
5545 		if (aoac_rpt_ver == 2)
5546 			has_rekey = paoac_rpt->rekey_ok == 1 ? _TRUE : _FALSE;
5547 	}
5548 
5549 	if (has_rekey == _FALSE) {
5550 		RTW_INFO("%s no rekey event happened.\n", __func__);
5551 	} else if (has_rekey == _TRUE) {
5552 		RTW_INFO("%s update security key.\n", __func__);
5553 		/*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
5554 		rtw_sec_read_cam_ent(adapter, gtk_id,
5555 				     NULL, NULL, get_key);
5556 		rtw_clean_hw_dk_cam(adapter);
5557 
5558 		if (_rtw_camid_is_gk(adapter, gtk_id)) {
5559 			_enter_critical_bh(&cam_ctl->lock, &irqL);
5560 			_rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
5561 				    get_key, 16);
5562 			_exit_critical_bh(&cam_ctl->lock, &irqL);
5563 		} else {
5564 			struct setkey_parm parm_gtk;
5565 
5566 			parm_gtk.algorithm = paoac_rpt->security_type;
5567 			parm_gtk.keyid = gtk_id;
5568 			_rtw_memcpy(parm_gtk.key, get_key, 16);
5569 			setkey_hdl(adapter, (u8 *)&parm_gtk);
5570 		}
5571 
5572 		/*update key into related sw variable and sec-cam cache*/
5573 		psecuritypriv->dot118021XGrpKeyid = gtk_id;
5574 		_rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
5575 				get_key, 16);
5576 		/* update SW TKIP TX/RX MIC value */
5577 		if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
5578 			offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
5579 			_rtw_memcpy(
5580 				&psecuritypriv->dot118021XGrptxmickey[gtk_id],
5581 				&(paoac_rpt->group_key[offset]),
5582 				RTW_TKIP_MIC_LEN);
5583 
5584 			offset = RTW_KEK_LEN;
5585 			_rtw_memcpy(
5586 				&psecuritypriv->dot118021XGrprxmickey[gtk_id],
5587 				&(paoac_rpt->group_key[offset]),
5588 				RTW_TKIP_MIC_LEN);
5589 		}
5590 		RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
5591 			KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
5592 	}
5593 
5594 	/* Update broadcast RX IV */
5595 	if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
5596 		sz = sizeof(psecuritypriv->iv_seq[0]);
5597 		for (i = 0 ; i < 4 ; i++) {
5598 			_rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
5599 			tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
5600 			pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
5601 			_rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
5602 		}
5603 	}
5604 
5605 	rtw_clean_dk_section(adapter);
5606 
5607 	rtw_write8(adapter, REG_SECCFG, 0x0c);
5608 
5609 	#ifdef CONFIG_GTK_OL_DBG
5610 	/* if (gtk_keyindex != 5) */
5611 	dump_sec_cam(RTW_DBGDUMP, adapter);
5612 	dump_sec_cam_cache(RTW_DBGDUMP, adapter);
5613 	#endif
5614 }
5615 #endif /*CONFIG_GTK_OL*/
5616 
rtw_dump_aoac_rpt(_adapter * adapter)5617 static void rtw_dump_aoac_rpt(_adapter *adapter)
5618 {
5619 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5620 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5621 	int i = 0;
5622 
5623 	RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
5624 	RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
5625 		paoac_rpt->replay_counter_eapol_key, 8);
5626 	RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
5627 	RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
5628 	RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
5629 	RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
5630 		 paoac_rpt->wow_pattern_idx);
5631 	RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
5632 	RTW_INFO("[AOAC-RPT] rekey_ok - %d\n", paoac_rpt->rekey_ok);
5633 	RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
5634 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
5635 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
5636 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
5637 	RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
5638 }
5639 
rtw_hal_get_aoac_rpt(_adapter * adapter)5640 static void rtw_hal_get_aoac_rpt(_adapter *adapter)
5641 {
5642 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5643 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5644 	u32 page_offset = 0, page_number = 0;
5645 	u32 page_size = 0, buf_size = 0;
5646 	u8 *buffer = NULL;
5647 	u8 i = 0, tmp = 0;
5648 	int ret = -1;
5649 
5650 	/* read aoac report from rsvd page */
5651 	page_offset = pwrctl->wowlan_aoac_rpt_loc;
5652 	page_number = 1;
5653 
5654 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5655 	buf_size = page_size * page_number;
5656 
5657 	buffer = rtw_zvmalloc(buf_size);
5658 
5659 	if (buffer == NULL) {
5660 		RTW_ERR("%s buffer allocate failed size(%d)\n",
5661 			__func__, buf_size);
5662 		return;
5663 	}
5664 
5665 	RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
5666 
5667 	ret = rtw_hal_get_rsvd_page(adapter, page_offset,
5668 		page_number, buffer, buf_size);
5669 
5670 	if (ret == _FALSE) {
5671 		RTW_ERR("%s get aoac report failed\n", __func__);
5672 		rtw_warn_on(1);
5673 		goto _exit;
5674 	}
5675 
5676 	_rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
5677 	_rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
5678 
5679 	for (i = 0 ; i < 4 ; i++) {
5680 		tmp = paoac_rpt->replay_counter_eapol_key[i];
5681 		paoac_rpt->replay_counter_eapol_key[i] =
5682 			paoac_rpt->replay_counter_eapol_key[7 - i];
5683 		paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
5684 	}
5685 
5686 	rtw_dump_aoac_rpt(adapter);
5687 
5688 _exit:
5689 	if (buffer)
5690 		rtw_vmfree(buffer, buf_size);
5691 }
5692 
rtw_hal_update_tx_iv(_adapter * adapter)5693 static void rtw_hal_update_tx_iv(_adapter *adapter)
5694 {
5695 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5696 	struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5697 	struct sta_info	*psta;
5698 	struct mlme_ext_priv	*pmlmeext = &(adapter->mlmeextpriv);
5699 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5700 	struct security_priv	*psecpriv = &adapter->securitypriv;
5701 
5702 	u16 val16 = 0;
5703 	u32 val32 = 0;
5704 	u64 txiv = 0;
5705 	u8 *pval = NULL;
5706 
5707 	psta = rtw_get_stainfo(&adapter->stapriv,
5708 			       get_my_bssid(&pmlmeinfo->network));
5709 
5710 	/* Update TX iv data. */
5711 	pval = (u8 *)&paoac_rpt->iv;
5712 
5713 	if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
5714 		val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
5715 			((u16)(paoac_rpt->iv[0]) << 8);
5716 		val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5717 			((u32)(paoac_rpt->iv[5]) << 8) +
5718 			((u32)(paoac_rpt->iv[6]) << 16) +
5719 			((u32)(paoac_rpt->iv[7]) << 24);
5720 	} else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
5721 		val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
5722 			((u16)(paoac_rpt->iv[1]) << 8);
5723 		val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5724 			((u32)(paoac_rpt->iv[5]) << 8) +
5725 			((u32)(paoac_rpt->iv[6]) << 16) +
5726 			((u32)(paoac_rpt->iv[7]) << 24);
5727 	}
5728 
5729 	if (psta) {
5730 		txiv = val16 + ((u64)val32 << 16);
5731 		if (txiv != 0)
5732 			psta->dot11txpn.val = txiv;
5733 	}
5734 }
5735 
rtw_hal_update_sw_security_info(_adapter * adapter)5736 static void rtw_hal_update_sw_security_info(_adapter *adapter)
5737 {
5738 	struct security_priv *psecpriv = &adapter->securitypriv;
5739 	u8 sz = sizeof (psecpriv->iv_seq);
5740 
5741 	rtw_hal_update_tx_iv(adapter);
5742 #ifdef CONFIG_GTK_OL
5743 	if (psecpriv->binstallKCK_KEK == _TRUE &&
5744 		(psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5745 		rtw_hal_update_gtk_offload_info(adapter);
5746 #else
5747 	_rtw_memset(psecpriv->iv_seq, 0, sz);
5748 #endif
5749 }
5750 #ifdef CONFIG_CUSTOM_PULSE
rtw_hal_set_gpio_custom_cmd(_adapter * adapter,u8 enable)5751 static u8 rtw_hal_set_gpio_custom_cmd(_adapter *adapter, u8 enable)
5752 {
5753 	u8 H2CGpioCustomParm[H2C_GPIO_CUSTOM_LEN] = {0};
5754 	u8 customid = 0x2, special_wakeup_reason = RX_MAGIC_PKT, custom_for_wakeup_reason=0x1;
5755 	u8 ret = _FAIL;
5756 
5757 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5758 
5759 	if(enable) {
5760 		SET_H2CCMD_CUSTOMERID(H2CGpioCustomParm, customid);
5761 		SET_H2CCMD_SPECIAL_WAKE_REASON(H2CGpioCustomParm, special_wakeup_reason);
5762 		SET_H2CCMD_CUSTOM_WAKE_REASON(H2CGpioCustomParm, custom_for_wakeup_reason);
5763 
5764 		ret = rtw_hal_fill_h2c_cmd(adapter,
5765 						H2C_GPIO_CUSTOM,
5766 						H2C_GPIO_CUSTOM_LEN,
5767 						H2CGpioCustomParm);
5768 		RTW_DBG("%s(): H2C_cmd=%x, cmd=%02x, %02x, %02x\n", __func__, H2C_GPIO_CUSTOM,
5769 		H2CGpioCustomParm[0], H2CGpioCustomParm[1], H2CGpioCustomParm[2]);
5770 	}
5771 
5772 	return ret;
5773 }
5774 #endif /* CONFIG_CUSTOM_PULSE */
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)5775 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
5776 {
5777 	u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
5778 	u8 adopt = 1, check_period = 5;
5779 	u8 ret = _FAIL;
5780 	u8 hw_port = rtw_hal_get_port(adapter);
5781 
5782 	SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
5783 	SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
5784 	SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
5785 	SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
5786 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5787 	SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, hw_port);
5788 	RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5789 #else
5790 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5791 #endif
5792 	ret = rtw_hal_fill_h2c_cmd(adapter,
5793 				   H2C_KEEP_ALIVE,
5794 				   H2C_KEEP_ALIVE_CTRL_LEN,
5795 				   u1H2CKeepAliveParm);
5796 
5797 	return ret;
5798 }
5799 
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)5800 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
5801 {
5802 	u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
5803 	u8 adopt = 1, check_period = 100, trypkt_num = 5;
5804 	u8 ret = _FAIL;
5805 	struct registry_priv *pregistry = &adapter->registrypriv;
5806 	u8 hw_port = rtw_hal_get_port(adapter);
5807 
5808 	SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
5809 	SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
5810 	if (!(pregistry->wakeup_event & BIT(2)))
5811 		SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt);
5812 	SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
5813 	SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
5814 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5815 	SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, hw_port);
5816 	RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5817 #else
5818 	RTW_INFO("%s(): enable = %d\n", __func__, enable);
5819 #endif
5820 
5821 	ret = rtw_hal_fill_h2c_cmd(adapter,
5822 				   H2C_DISCON_DECISION,
5823 				   H2C_DISCON_DECISION_LEN,
5824 				   u1H2CDisconDecisionParm);
5825 	return ret;
5826 }
5827 
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)5828 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
5829 {
5830 	struct registry_priv  *registry_par = &adapter->registrypriv;
5831 	struct security_priv *psecpriv = &adapter->securitypriv;
5832 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5833 	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
5834 
5835 	u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
5836 	u8 discont_wake = 0, gpionum = 0, gpio_dur = 0, no_wake = 0;
5837 	u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
5838 	u8 sdio_wakeup_enable = 1;
5839 	u8 gpio_high_active = 0;
5840 	u8 magic_pkt = 0;
5841 	u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
5842 	u8 ret = _FAIL;
5843 #ifdef CONFIG_DIS_UPHY
5844 	u8 dis_uphy = 0, dis_uphy_unit = 0, dis_uphy_time = 0;
5845 #endif /* CONFIG_DIS_UPHY */
5846 
5847 #ifdef CONFIG_GPIO_WAKEUP
5848 	gpio_high_active = ppwrpriv->is_high_active;
5849 	gpionum = ppwrpriv->wowlan_gpio_index;
5850 	sdio_wakeup_enable = 0;
5851 #endif /* CONFIG_GPIO_WAKEUP */
5852 
5853 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
5854 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5855 		no_wake = 1;
5856 
5857 	if (!ppwrpriv->wowlan_pno_enable &&
5858 		registry_par->wakeup_event & BIT(0) && !no_wake)
5859 		magic_pkt = enable;
5860 
5861 	if (registry_par->wakeup_event & BIT(2) && !no_wake)
5862 		discont_wake = enable;
5863 
5864 	RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
5865 		 enable, change_unit);
5866 
5867 	/* time = (gpio_dur/2) * gpio_unit, default:256 ms */
5868 	if (enable && change_unit) {
5869 		gpio_dur = 0x40;
5870 		gpio_unit = 1;
5871 		gpio_pulse_en = 1;
5872 	}
5873 
5874 #ifdef CONFIG_PLATFORM_ARM_RK3188
5875 	if (enable) {
5876 		gpio_pulse_en = 1;
5877 		gpio_pulse_cnt = 0x04;
5878 	}
5879 #endif
5880 
5881 	SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
5882 	if(!no_wake)
5883 		SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
5884 	SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
5885 	SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
5886 	SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
5887 	SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
5888 
5889 #ifdef CONFIG_GTK_OL
5890 	if (psecpriv->binstallKCK_KEK == _TRUE &&
5891 		(psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5892 		SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
5893 	else
5894 		SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
5895 #else
5896 	SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
5897 #endif
5898 	SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
5899 	SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
5900 	SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
5901 
5902 	SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
5903 	SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
5904 
5905 	SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
5906 	SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
5907 
5908 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
5909 	if (enable)
5910 		SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5911 #endif
5912 
5913 #ifdef CONFIG_DIS_UPHY
5914 	if (enable) {
5915 		dis_uphy = 1;
5916 		/* time unit: 0 -> ms, 1 -> 256 ms*/
5917 		dis_uphy_unit = 1;
5918 		dis_uphy_time = 0x4;
5919 	}
5920 
5921 	SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);
5922 	SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);
5923 	SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);
5924 	if (ppwrpriv->hst2dev_high_active == 1)
5925 		SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);
5926 #ifdef CONFIG_RTW_ONE_PIN_GPIO
5927 	SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5928 	SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);
5929 	SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);
5930 #else
5931 	SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);
5932 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
5933 #endif /* CONFIG_DIS_UPHY */
5934 
5935 
5936 	ret = rtw_hal_fill_h2c_cmd(adapter,
5937 				   H2C_WOWLAN,
5938 				   H2C_WOWLAN_LEN,
5939 				   u1H2CWoWlanCtrlParm);
5940 	return ret;
5941 }
5942 
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)5943 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
5944 {
5945 	struct security_priv *psecuritypriv = &(adapter->securitypriv);
5946 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5947 	struct registry_priv *pregistrypriv = &adapter->registrypriv;
5948 	u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
5949 	u8 ret = _FAIL, count = 0, no_wake = 0;
5950 	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
5951 
5952 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
5953 
5954 	if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF &&
5955 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5956 		no_wake = 1;
5957 	if(no_wake) {
5958 		SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5959 			u1H2CRemoteWakeCtrlParm, enable);
5960 	} else {
5961 		if (!ppwrpriv->wowlan_pno_enable) {
5962 			SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5963 				u1H2CRemoteWakeCtrlParm, enable);
5964 			SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5965 				u1H2CRemoteWakeCtrlParm, 1);
5966 	#ifdef CONFIG_GTK_OL
5967 			if (psecuritypriv->binstallKCK_KEK == _TRUE &&
5968 				(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) {
5969 				SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5970 					u1H2CRemoteWakeCtrlParm, 1);
5971 			} else {
5972 				RTW_INFO("no kck kek\n");
5973 				SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5974 					u1H2CRemoteWakeCtrlParm, 0);
5975 			}
5976 	#endif /* CONFIG_GTK_OL */
5977 
5978 	#ifdef CONFIG_IPV6
5979 			if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
5980 				RTW_INFO("enable NS offload\n");
5981 				SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
5982 					u1H2CRemoteWakeCtrlParm, enable);
5983 			}
5984 
5985 			/*
5986 			 * filter NetBios name service pkt to avoid being waked-up
5987 			 * by this kind of unicast pkt this exceptional modification
5988 			 * is used for match competitor's behavior
5989 			 */
5990 
5991 			SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
5992 				u1H2CRemoteWakeCtrlParm, enable);
5993 	#endif /*CONFIG_IPV6*/
5994 #if 0 /* replaced by WOWLAN pattern match */
5995 	#ifdef CONFIG_RTL8192F
5996 			if (IS_HARDWARE_TYPE_8192F(adapter)){
5997 				SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
5998 					u1H2CRemoteWakeCtrlParm, enable);
5999 			}
6000 	#endif /* CONFIG_RTL8192F */
6001 #endif
6002 			if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
6003 				(psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
6004 				(psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
6005 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
6006 					u1H2CRemoteWakeCtrlParm, 0);
6007 			} else {
6008 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
6009 					u1H2CRemoteWakeCtrlParm, 1);
6010 			}
6011 
6012 			if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
6013 #ifdef CONFIG_GTK_OL
6014 				if(_rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))
6015 					SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
6016 						u1H2CRemoteWakeCtrlParm, enable);
6017 #endif /* CONFIG_GTK_OL */
6018 				if (IS_HARDWARE_TYPE_8188E(adapter) ||
6019 				    IS_HARDWARE_TYPE_8812(adapter)) {
6020 					SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
6021 						u1H2CRemoteWakeCtrlParm, 0);
6022 					SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
6023 						u1H2CRemoteWakeCtrlParm, 1);
6024 				}
6025 			}
6026 
6027 			SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
6028 				u1H2CRemoteWakeCtrlParm, 1);
6029 		}
6030 	#ifdef CONFIG_PNO_SUPPORT
6031 		else {
6032 			SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
6033 				u1H2CRemoteWakeCtrlParm, enable);
6034 			SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
6035 				u1H2CRemoteWakeCtrlParm, enable);
6036 		}
6037 	#endif
6038 
6039 	#ifdef CONFIG_P2P_WOWLAN
6040 		if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
6041 			RTW_INFO("P2P OFFLOAD ENABLE\n");
6042 			SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
6043 		} else {
6044 			RTW_INFO("P2P OFFLOAD DISABLE\n");
6045 			SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
6046 		}
6047 	#endif /* CONFIG_P2P_WOWLAN */
6048 	}
6049 
6050 
6051 	ret = rtw_hal_fill_h2c_cmd(adapter,
6052 				   H2C_REMOTE_WAKE_CTRL,
6053 				   H2C_REMOTE_WAKE_CTRL_LEN,
6054 				   u1H2CRemoteWakeCtrlParm);
6055 	return ret;
6056 }
6057 
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)6058 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
6059 {
6060 	u8 ret = _FAIL;
6061 	u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
6062 
6063 	RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
6064 		 __func__, group_alg, pairwise_alg);
6065 	SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
6066 			pairwise_alg);
6067 	SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
6068 			group_alg);
6069 
6070 	ret = rtw_hal_fill_h2c_cmd(adapter,
6071 				   H2C_AOAC_GLOBAL_INFO,
6072 				   H2C_AOAC_GLOBAL_INFO_LEN,
6073 				   u1H2CAOACGlobalInfoParm);
6074 
6075 	return ret;
6076 }
6077 
6078 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)6079 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
6080 		PRSVDPAGE_LOC rsvdpageloc, u8 enable)
6081 {
6082 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6083 	u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
6084 	u8 res = 0, count = 0, ret = _FAIL;
6085 
6086 	RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
6087 		 __func__, rsvdpageloc->LocProbePacket,
6088 		 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
6089 
6090 	SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
6091 	SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
6092 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
6093 					       rsvdpageloc->LocScanInfo);
6094 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
6095 			rsvdpageloc->LocProbePacket);
6096 	/*
6097 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
6098 				rsvdpageloc->LocSSIDInfo);
6099 	*/
6100 	ret = rtw_hal_fill_h2c_cmd(adapter,
6101 				   H2C_D0_SCAN_OFFLOAD_INFO,
6102 				   H2C_SCAN_OFFLOAD_CTRL_LEN,
6103 				   u1H2CScanOffloadInfoParm);
6104 	return ret;
6105 }
6106 #endif /* CONFIG_PNO_SUPPORT */
6107 
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)6108 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
6109 {
6110 	struct security_priv *psecpriv = &padapter->securitypriv;
6111 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
6112 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
6113 	struct registry_priv *pregistry = &padapter->registrypriv;
6114 	u8	pkt_type = 0, no_wake = 0;
6115 
6116 	if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF &&
6117 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
6118 		no_wake = 1;
6119 
6120 	RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
6121 
6122 	rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
6123 
6124 	if (enable) {
6125 		if(!no_wake)
6126 			rtw_hal_set_global_info_cmd(padapter,
6127 					    psecpriv->dot118021XGrpPrivacy,
6128 					    psecpriv->dot11PrivacyAlgrthm);
6129 
6130 		if (!(ppwrpriv->wowlan_pno_enable)) {
6131 			if (!no_wake)
6132 				rtw_hal_set_disconnect_decision_cmd(padapter,
6133 								    enable);
6134 #ifdef CONFIG_ARP_KEEP_ALIVE
6135 			if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
6136 			    (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
6137 				pkt_type = 0;
6138 			else
6139 				pkt_type = 1;
6140 #else
6141 			pkt_type = 0;
6142 #endif /* CONFIG_ARP_KEEP_ALIVE */
6143 			if(!no_wake)
6144 				rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
6145 		}
6146 #ifdef CONFIG_PNO_SUPPORT
6147 		rtw_hal_check_pno_enabled(padapter);
6148 #endif /* CONFIG_PNO_SUPPORT */
6149 	} else {
6150 #if 0
6151 		{
6152 			u32 PageSize = 0;
6153 			rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
6154 			dump_TX_FIFO(padapter, 4, PageSize);
6155 		}
6156 #endif
6157 	}
6158 #ifdef CONFIG_CUSTOM_PULSE
6159 	rtw_hal_set_gpio_custom_cmd(padapter, enable);
6160 #endif /* CONFIG_CUSTOM_PULSE */
6161 	rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
6162 	RTW_PRINT("-%s()-\n", __func__);
6163 }
6164 #endif /* CONFIG_WOWLAN */
6165 
6166 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)6167 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
6168 {
6169 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6170 
6171 	u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
6172 	u8 gpionum = 0, gpio_dur = 0;
6173 	u8 gpio_pulse = enable;
6174 	u8 sdio_wakeup_enable = 1;
6175 	u8 gpio_high_active = 0;
6176 	u8 ret = _FAIL;
6177 
6178 #ifdef CONFIG_GPIO_WAKEUP
6179 	gpio_high_active = ppwrpriv->is_high_active;
6180 	gpionum = ppwrpriv->wowlan_gpio_index;
6181 	sdio_wakeup_enable = 0;
6182 #endif /*CONFIG_GPIO_WAKEUP*/
6183 
6184 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
6185 
6186 	SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
6187 					  gpionum);
6188 	SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
6189 					 gpio_pulse);
6190 	SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
6191 						gpio_high_active);
6192 	SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
6193 				       enable);
6194 	SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
6195 					     gpio_dur);
6196 
6197 	ret = rtw_hal_fill_h2c_cmd(adapter,
6198 				   H2C_AP_WOW_GPIO_CTRL,
6199 				   H2C_AP_WOW_GPIO_CTRL_LEN,
6200 				   u1H2CAPWoWlanCtrlParm);
6201 
6202 	return ret;
6203 }
6204 
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)6205 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
6206 {
6207 	u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
6208 	u8 ret = _FAIL;
6209 
6210 	RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
6211 
6212 	SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
6213 
6214 	ret = rtw_hal_fill_h2c_cmd(adapter,
6215 				   H2C_AP_OFFLOAD,
6216 				   H2C_AP_OFFLOAD_LEN,
6217 				   u1H2CAPOffloadCtrlParm);
6218 
6219 	return ret;
6220 }
6221 
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)6222 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
6223 {
6224 	u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
6225 	u8 ret = _FAIL;
6226 
6227 	RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
6228 
6229 	SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
6230 #ifndef CONFIG_USB_HCI
6231 	SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
6232 #endif /*CONFIG_USB_HCI*/
6233 	SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
6234 
6235 	if (enable)
6236 		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
6237 	else
6238 		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
6239 
6240 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
6241 				   H2C_AP_PS_LEN, ap_ps_parm);
6242 
6243 	return ret;
6244 }
6245 
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)6246 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
6247 		PRSVDPAGE_LOC rsvdpageloc)
6248 {
6249 	struct hal_ops *pHalFunc = &padapter->hal_func;
6250 	u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
6251 	u8 ret = _FAIL, header = 0;
6252 
6253 	if (pHalFunc->fill_h2c_cmd == NULL) {
6254 		RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
6255 		return;
6256 	}
6257 
6258 	header = rtw_read8(padapter, REG_BCNQ_BDNY);
6259 
6260 	RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
6261 		 rsvdpageloc->LocApOffloadBCN,
6262 		 rsvdpageloc->LocProbeRsp,
6263 		 header);
6264 
6265 	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
6266 				      rsvdpageloc->LocApOffloadBCN + header);
6267 
6268 	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
6269 				   H2C_BCN_RSVDPAGE_LEN, rsvdparm);
6270 
6271 	if (ret == _FAIL)
6272 		RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
6273 
6274 	rtw_msleep_os(10);
6275 
6276 	_rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
6277 
6278 	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
6279 			rsvdpageloc->LocProbeRsp + header);
6280 
6281 	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
6282 				   H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
6283 
6284 	if (ret == _FAIL)
6285 		RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
6286 
6287 	rtw_msleep_os(10);
6288 }
6289 
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)6290 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
6291 {
6292 	rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
6293 	rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
6294 	rtw_hal_set_ap_ps_cmd(padapter, enable);
6295 }
6296 
rtw_hal_ap_wow_enable(_adapter * padapter)6297 static void rtw_hal_ap_wow_enable(_adapter *padapter)
6298 {
6299 	struct security_priv *psecuritypriv = &padapter->securitypriv;
6300 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6301 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6302 	struct sta_info *psta = NULL;
6303 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
6304 #ifdef DBG_CHECK_FW_PS_STATE
6305 	struct dvobj_priv *psdpriv = padapter->dvobj;
6306 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6307 #endif /*DBG_CHECK_FW_PS_STATE*/
6308 	int res;
6309 	u16 media_status_rpt;
6310 #ifdef CONFIG_GPIO_WAKEUP
6311 	u8 val8 = 0;
6312 #endif
6313 
6314 	RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
6315 #ifdef DBG_CHECK_FW_PS_STATE
6316 	if (rtw_fw_ps_state(padapter) == _FAIL) {
6317 		pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
6318 		RTW_PRINT("wowlan enable no leave 32k\n");
6319 	}
6320 #endif /*DBG_CHECK_FW_PS_STATE*/
6321 
6322 	/* 1. Download WOWLAN FW*/
6323 	rtw_hal_fw_dl(padapter, _TRUE);
6324 
6325 	media_status_rpt = RT_MEDIA_CONNECT;
6326 	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6327 			  (u8 *)&media_status_rpt);
6328 
6329 	issue_beacon(padapter, 0);
6330 
6331 	rtw_msleep_os(2);
6332 	#if defined(CONFIG_RTL8188E)
6333 	if (IS_HARDWARE_TYPE_8188E(padapter))
6334 		rtw_hal_disable_tx_report(padapter);
6335 	#endif
6336 	/* RX DMA stop */
6337 	res = rtw_hal_pause_rx_dma(padapter);
6338 	if (res == _FAIL)
6339 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
6340 
6341 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6342 	/* Enable CPWM2 only. */
6343 	res = rtw_hal_enable_cpwm2(padapter);
6344 	if (res == _FAIL)
6345 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
6346 #endif
6347 
6348 #ifdef CONFIG_GPIO_WAKEUP
6349 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6350 	rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6351 	rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6352 #else
6353 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6354 	if (pwrctrlpriv->is_high_active == 0)
6355 		rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6356 	else
6357 		rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index,
6358 			GPIO_OUTPUT_LOW);
6359 #else
6360 	val8 = (pwrpriv->is_high_active == 0) ? 1 : 0;
6361 	rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8);
6362 	rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6363 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow suspend and %s_ACTIVE.\n",
6364 		 __func__, pwrpriv->wowlan_gpio_index,
6365 		 pwrpriv->wowlan_gpio_output_state ? "HIGH" : "LOW",
6366 		 pwrpriv->is_high_active ? "HIGI" : "LOW");
6367 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
6368 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6369 #endif /* CONFIG_GPIO_WAKEUP */
6370 
6371 	/* 5. Set Enable WOWLAN H2C command. */
6372 	RTW_PRINT("Set Enable AP WOWLan cmd\n");
6373 	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
6374 
6375 	rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
6376 #ifdef CONFIG_USB_HCI
6377 	rtw_mi_intf_stop(padapter);
6378 #endif
6379 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
6380 	/* Invoid SE0 reset signal during suspending*/
6381 	rtw_write8(padapter, REG_RSV_CTRL, 0x20);
6382 	if (IS_8188F(pHalData->version_id) == FALSE
6383 		&& IS_8188GTV(pHalData->version_id) == FALSE)
6384 		rtw_write8(padapter, REG_RSV_CTRL, 0x60);
6385 #endif
6386 }
6387 
rtw_hal_ap_wow_disable(_adapter * padapter)6388 static void rtw_hal_ap_wow_disable(_adapter *padapter)
6389 {
6390 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6391 #ifdef DBG_CHECK_FW_PS_STATE
6392 	struct dvobj_priv *psdpriv = padapter->dvobj;
6393 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6394 #endif /*DBG_CHECK_FW_PS_STATE*/
6395 	u16 media_status_rpt;
6396 
6397 	RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
6398 	/* 1. Read wakeup reason*/
6399 	pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
6400 
6401 	RTW_PRINT("wakeup_reason: 0x%02x\n",
6402 		  pwrctl->wowlan_wake_reason);
6403 
6404 	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
6405 
6406 	rtw_msleep_os(2);
6407 #ifdef DBG_CHECK_FW_PS_STATE
6408 	if (rtw_fw_ps_state(padapter) == _FAIL) {
6409 		pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
6410 		RTW_PRINT("wowlan enable no leave 32k\n");
6411 	}
6412 #endif /*DBG_CHECK_FW_PS_STATE*/
6413 
6414 	#if defined(CONFIG_RTL8188E)
6415 	if (IS_HARDWARE_TYPE_8188E(padapter))
6416 		rtw_hal_enable_tx_report(padapter);
6417 	#endif
6418 
6419 	rtw_hal_force_enable_rxdma(padapter);
6420 
6421 	rtw_hal_fw_dl(padapter, _FALSE);
6422 
6423 #ifdef CONFIG_GPIO_WAKEUP
6424 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6425 	rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6426 #else
6427 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6428 	if (pwrctl->is_high_active == 0)
6429 		rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6430 	else
6431 		rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index
6432 			, GPIO_OUTPUT_LOW);
6433 #else
6434 	rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index,
6435 		pwrctl->wowlan_gpio_output_state);
6436 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow resume and %s_ACTIVE.\n",
6437 		 __func__, pwrctl->wowlan_gpio_index,
6438 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
6439 		 pwrctl->is_high_active ? "HIGI" : "LOW");
6440 #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
6441 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6442 #endif /* CONFIG_GPIO_WAKEUP */
6443 	media_status_rpt = RT_MEDIA_CONNECT;
6444 
6445 	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6446 			  (u8 *)&media_status_rpt);
6447 
6448 	issue_beacon(padapter, 0);
6449 }
6450 #endif /*CONFIG_AP_WOWLAN*/
6451 
6452 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)6453 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
6454 {
6455 	u8 *ssid_ie;
6456 	sint ssid_len_ori;
6457 	int len_diff = 0;
6458 
6459 	ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
6460 
6461 	/* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
6462 
6463 	if (ssid_ie && ssid_len_ori > 0) {
6464 		switch (hidden_ssid_mode) {
6465 		case 1: {
6466 			u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
6467 			u32 remain_len = 0;
6468 
6469 			remain_len = ies_len - (next_ie - ies);
6470 
6471 			ssid_ie[1] = 0;
6472 			_rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
6473 			len_diff -= ssid_len_ori;
6474 
6475 			break;
6476 		}
6477 		case 2:
6478 			_rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
6479 			break;
6480 		default:
6481 			break;
6482 		}
6483 	}
6484 
6485 	return len_diff;
6486 }
6487 
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)6488 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
6489 {
6490 	/* struct xmit_frame	*pmgntframe; */
6491 	/* struct pkt_attrib	*pattrib; */
6492 	/* unsigned char	*pframe; */
6493 	struct rtw_ieee80211_hdr *pwlanhdr;
6494 	unsigned short *fctrl;
6495 	unsigned int	rate_len;
6496 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
6497 	u32	pktlen;
6498 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6499 	/*	_irqL irqL;
6500 	 *	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6501 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6502 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6503 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6504 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6505 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
6506 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6507 #ifdef CONFIG_P2P
6508 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6509 #endif /* CONFIG_P2P */
6510 
6511 	/* for debug */
6512 	u8 *dbgbuf = pframe;
6513 	u8 dbgbufLen = 0, index = 0;
6514 
6515 	RTW_INFO("%s\n", __FUNCTION__);
6516 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6517 	/*	_enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6518 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6519 
6520 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6521 
6522 
6523 	fctrl = &(pwlanhdr->frame_ctl);
6524 	*(fctrl) = 0;
6525 
6526 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6527 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6528 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
6529 
6530 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
6531 	/* pmlmeext->mgnt_seq++; */
6532 	set_frame_sub_type(pframe, WIFI_BEACON);
6533 
6534 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6535 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6536 
6537 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6538 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
6539 #ifdef CONFIG_P2P
6540 		/* for P2P : Primary Device Type & Device Name */
6541 		u32 wpsielen = 0, insert_len = 0;
6542 		u8 *wpsie = NULL;
6543 		wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
6544 
6545 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
6546 			uint wps_offset, remainder_ielen;
6547 			u8 *premainder_ie, *pframe_wscie;
6548 
6549 			wps_offset = (uint)(wpsie - cur_network->IEs);
6550 
6551 			premainder_ie = wpsie + wpsielen;
6552 
6553 			remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
6554 
6555 #ifdef CONFIG_IOCTL_CFG80211
6556 			if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6557 				if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
6558 					_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
6559 					pframe += wps_offset;
6560 					pktlen += wps_offset;
6561 
6562 					_rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
6563 					pframe += pmlmepriv->wps_beacon_ie_len;
6564 					pktlen += pmlmepriv->wps_beacon_ie_len;
6565 
6566 					/* copy remainder_ie to pframe */
6567 					_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6568 					pframe += remainder_ielen;
6569 					pktlen += remainder_ielen;
6570 				} else {
6571 					_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6572 					pframe += cur_network->IELength;
6573 					pktlen += cur_network->IELength;
6574 				}
6575 			} else
6576 #endif /* CONFIG_IOCTL_CFG80211 */
6577 			{
6578 				pframe_wscie = pframe + wps_offset;
6579 				_rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
6580 				pframe += (wps_offset + wpsielen);
6581 				pktlen += (wps_offset + wpsielen);
6582 
6583 				/* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
6584 				/*	Primary Device Type */
6585 				/*	Type: */
6586 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6587 				insert_len += 2;
6588 
6589 				/*	Length: */
6590 				*(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
6591 				insert_len += 2;
6592 
6593 				/*	Value: */
6594 				/*	Category ID */
6595 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6596 				insert_len += 2;
6597 
6598 				/*	OUI */
6599 				*(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
6600 				insert_len += 4;
6601 
6602 				/*	Sub Category ID */
6603 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6604 				insert_len += 2;
6605 
6606 
6607 				/*	Device Name */
6608 				/*	Type: */
6609 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6610 				insert_len += 2;
6611 
6612 				/*	Length: */
6613 				*(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
6614 				insert_len += 2;
6615 
6616 				/*	Value: */
6617 				_rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
6618 				insert_len += pwdinfo->device_name_len;
6619 
6620 
6621 				/* update wsc ie length */
6622 				*(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
6623 
6624 				/* pframe move to end */
6625 				pframe += insert_len;
6626 				pktlen += insert_len;
6627 
6628 				/* copy remainder_ie to pframe */
6629 				_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6630 				pframe += remainder_ielen;
6631 				pktlen += remainder_ielen;
6632 			}
6633 		} else
6634 #endif /* CONFIG_P2P */
6635 		{
6636 			int len_diff;
6637 			_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6638 			len_diff = update_hidden_ssid(
6639 					   pframe + _BEACON_IE_OFFSET_
6640 				   , cur_network->IELength - _BEACON_IE_OFFSET_
6641 					   , pmlmeinfo->hidden_ssid_mode
6642 				   );
6643 			pframe += (cur_network->IELength + len_diff);
6644 			pktlen += (cur_network->IELength + len_diff);
6645 		}
6646 #if 0
6647 		{
6648 			u8 *wps_ie;
6649 			uint wps_ielen;
6650 			u8 sr = 0;
6651 			wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
6652 				pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
6653 			if (wps_ie && wps_ielen > 0)
6654 				rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
6655 			if (sr != 0)
6656 				set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
6657 			else
6658 				_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
6659 		}
6660 #endif
6661 #ifdef CONFIG_P2P
6662 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6663 			u32 len;
6664 #ifdef CONFIG_IOCTL_CFG80211
6665 			if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6666 				len = pmlmepriv->p2p_beacon_ie_len;
6667 				if (pmlmepriv->p2p_beacon_ie && len > 0)
6668 					_rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
6669 			} else
6670 #endif /* CONFIG_IOCTL_CFG80211 */
6671 			{
6672 				len = build_beacon_p2p_ie(pwdinfo, pframe);
6673 			}
6674 
6675 			pframe += len;
6676 			pktlen += len;
6677 
6678 			#ifdef CONFIG_WFD
6679 			len = rtw_append_beacon_wfd_ie(padapter, pframe);
6680 			pframe += len;
6681 			pktlen += len;
6682 			#endif
6683 
6684 		}
6685 #endif /* CONFIG_P2P */
6686 
6687 		goto _issue_bcn;
6688 
6689 	}
6690 
6691 	/* below for ad-hoc mode */
6692 
6693 	/* timestamp will be inserted by hardware */
6694 	pframe += 8;
6695 	pktlen += 8;
6696 
6697 	/* beacon interval: 2 bytes */
6698 
6699 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6700 
6701 	pframe += 2;
6702 	pktlen += 2;
6703 
6704 	/* capability info: 2 bytes */
6705 
6706 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6707 
6708 	pframe += 2;
6709 	pktlen += 2;
6710 
6711 	/* SSID */
6712 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
6713 
6714 	/* supported rates... */
6715 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6716 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
6717 
6718 	/* DS parameter set */
6719 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
6720 
6721 	/* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
6722 	{
6723 		u8 erpinfo = 0;
6724 		u32 ATIMWindow;
6725 		/* IBSS Parameter Set... */
6726 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
6727 		ATIMWindow = 0;
6728 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
6729 
6730 		/* ERP IE */
6731 		pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
6732 	}
6733 
6734 
6735 	/* EXTERNDED SUPPORTED RATE */
6736 	if (rate_len > 8)
6737 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
6738 
6739 
6740 	/* todo:HT for adhoc */
6741 
6742 _issue_bcn:
6743 
6744 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6745 	/*	pmlmepriv->update_bcn = _FALSE;
6746 	 *
6747 	 *	_exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6748 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6749 
6750 	*pLength = pktlen;
6751 #if 0
6752 	/* printf dbg msg */
6753 	dbgbufLen = pktlen;
6754 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6755 
6756 	for (index = 0; index < dbgbufLen; index++)
6757 		printk("%x ", *(dbgbuf + index));
6758 
6759 	printk("\n");
6760 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6761 
6762 #endif
6763 }
6764 
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6765 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6766 {
6767 	/* struct xmit_frame			*pmgntframe; */
6768 	/* struct pkt_attrib			*pattrib; */
6769 	/* unsigned char					*pframe; */
6770 	struct rtw_ieee80211_hdr	*pwlanhdr;
6771 	unsigned short				*fctrl;
6772 	unsigned char					*mac;
6773 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
6774 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6775 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6776 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6777 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
6778 	u16					beacon_interval = 100;
6779 	u16					capInfo = 0;
6780 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6781 	u8					wpsie[255] = { 0x00 };
6782 	u32					wpsielen = 0, p2pielen = 0;
6783 	u32					pktlen;
6784 #ifdef CONFIG_WFD
6785 	u32					wfdielen = 0;
6786 #endif
6787 
6788 	/* for debug */
6789 	u8 *dbgbuf = pframe;
6790 	u8 dbgbufLen = 0, index = 0;
6791 
6792 	RTW_INFO("%s\n", __FUNCTION__);
6793 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6794 
6795 	mac = adapter_mac_addr(padapter);
6796 
6797 	fctrl = &(pwlanhdr->frame_ctl);
6798 	*(fctrl) = 0;
6799 
6800 	/* DA filled by FW */
6801 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6802 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6803 
6804 	/*	Use the device address for BSSID field.	 */
6805 	_rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
6806 
6807 	SetSeqNum(pwlanhdr, 0);
6808 	set_frame_sub_type(fctrl, WIFI_PROBERSP);
6809 
6810 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6811 	pframe += pktlen;
6812 
6813 
6814 	/* timestamp will be inserted by hardware */
6815 	pframe += 8;
6816 	pktlen += 8;
6817 
6818 	/* beacon interval: 2 bytes */
6819 	_rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
6820 	pframe += 2;
6821 	pktlen += 2;
6822 
6823 	/*	capability info: 2 bytes */
6824 	/*	ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
6825 	capInfo |= cap_ShortPremble;
6826 	capInfo |= cap_ShortSlot;
6827 
6828 	_rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
6829 	pframe += 2;
6830 	pktlen += 2;
6831 
6832 
6833 	/* SSID */
6834 	pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
6835 
6836 	/* supported rates... */
6837 	/*	Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
6838 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
6839 
6840 	/* DS parameter set */
6841 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
6842 
6843 #ifdef CONFIG_IOCTL_CFG80211
6844 	if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6845 		if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
6846 			/* WPS IE */
6847 			_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
6848 			pktlen += pmlmepriv->wps_probe_resp_ie_len;
6849 			pframe += pmlmepriv->wps_probe_resp_ie_len;
6850 
6851 			/* P2P IE */
6852 			_rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
6853 			pktlen += pmlmepriv->p2p_probe_resp_ie_len;
6854 			pframe += pmlmepriv->p2p_probe_resp_ie_len;
6855 		}
6856 	} else
6857 #endif /* CONFIG_IOCTL_CFG80211		 */
6858 	{
6859 
6860 		/*	Todo: WPS IE */
6861 		/*	Noted by Albert 20100907 */
6862 		/*	According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6863 
6864 		wpsielen = 0;
6865 		/*	WPS OUI */
6866 		*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6867 		wpsielen += 4;
6868 
6869 		/*	WPS version */
6870 		/*	Type: */
6871 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6872 		wpsielen += 2;
6873 
6874 		/*	Length: */
6875 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6876 		wpsielen += 2;
6877 
6878 		/*	Value: */
6879 		wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
6880 
6881 		/*	WiFi Simple Config State */
6882 		/*	Type: */
6883 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
6884 		wpsielen += 2;
6885 
6886 		/*	Length: */
6887 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6888 		wpsielen += 2;
6889 
6890 		/*	Value: */
6891 		wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;	/*	Not Configured. */
6892 
6893 		/*	Response Type */
6894 		/*	Type: */
6895 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
6896 		wpsielen += 2;
6897 
6898 		/*	Length: */
6899 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6900 		wpsielen += 2;
6901 
6902 		/*	Value: */
6903 		wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
6904 
6905 		/*	UUID-E */
6906 		/*	Type: */
6907 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6908 		wpsielen += 2;
6909 
6910 		/*	Length: */
6911 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6912 		wpsielen += 2;
6913 
6914 		/*	Value: */
6915 		if (pwdinfo->external_uuid == 0) {
6916 			_rtw_memset(wpsie + wpsielen, 0x0, 16);
6917 			_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6918 		} else
6919 			_rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6920 		wpsielen += 0x10;
6921 
6922 		/*	Manufacturer */
6923 		/*	Type: */
6924 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
6925 		wpsielen += 2;
6926 
6927 		/*	Length: */
6928 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
6929 		wpsielen += 2;
6930 
6931 		/*	Value: */
6932 		_rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
6933 		wpsielen += 7;
6934 
6935 		/*	Model Name */
6936 		/*	Type: */
6937 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
6938 		wpsielen += 2;
6939 
6940 		/*	Length: */
6941 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
6942 		wpsielen += 2;
6943 
6944 		/*	Value: */
6945 		_rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
6946 		wpsielen += 6;
6947 
6948 		/*	Model Number */
6949 		/*	Type: */
6950 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
6951 		wpsielen += 2;
6952 
6953 		/*	Length: */
6954 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6955 		wpsielen += 2;
6956 
6957 		/*	Value: */
6958 		wpsie[wpsielen++] = 0x31;		/*	character 1 */
6959 
6960 		/*	Serial Number */
6961 		/*	Type: */
6962 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
6963 		wpsielen += 2;
6964 
6965 		/*	Length: */
6966 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
6967 		wpsielen += 2;
6968 
6969 		/*	Value: */
6970 		_rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
6971 		wpsielen += ETH_ALEN;
6972 
6973 		/*	Primary Device Type */
6974 		/*	Type: */
6975 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6976 		wpsielen += 2;
6977 
6978 		/*	Length: */
6979 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6980 		wpsielen += 2;
6981 
6982 		/*	Value: */
6983 		/*	Category ID */
6984 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6985 		wpsielen += 2;
6986 
6987 		/*	OUI */
6988 		*(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6989 		wpsielen += 4;
6990 
6991 		/*	Sub Category ID */
6992 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6993 		wpsielen += 2;
6994 
6995 		/*	Device Name */
6996 		/*	Type: */
6997 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6998 		wpsielen += 2;
6999 
7000 		/*	Length: */
7001 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
7002 		wpsielen += 2;
7003 
7004 		/*	Value: */
7005 		_rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
7006 		wpsielen += pwdinfo->device_name_len;
7007 
7008 		/*	Config Method */
7009 		/*	Type: */
7010 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
7011 		wpsielen += 2;
7012 
7013 		/*	Length: */
7014 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7015 		wpsielen += 2;
7016 
7017 		/*	Value: */
7018 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7019 		wpsielen += 2;
7020 
7021 
7022 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7023 
7024 
7025 		p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
7026 		pframe += p2pielen;
7027 		pktlen += p2pielen;
7028 	}
7029 
7030 #ifdef CONFIG_WFD
7031 	wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
7032 	pframe += wfdielen;
7033 	pktlen += wfdielen;
7034 #endif
7035 
7036 	*pLength = pktlen;
7037 
7038 #if 0
7039 	/* printf dbg msg */
7040 	dbgbufLen = pktlen;
7041 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7042 
7043 	for (index = 0; index < dbgbufLen; index++)
7044 		printk("%x ", *(dbgbuf + index));
7045 
7046 	printk("\n");
7047 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7048 #endif
7049 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7050 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7051 {
7052 	struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7053 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7054 	u8			action = P2P_PUB_ACTION_ACTION;
7055 	u32			p2poui = cpu_to_be32(P2POUI);
7056 	u8			oui_subtype = P2P_GO_NEGO_RESP;
7057 	u8			wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
7058 	u8			p2pielen = 0, i;
7059 	uint			wpsielen = 0;
7060 	u16			wps_devicepassword_id = 0x0000;
7061 	uint			wps_devicepassword_id_len = 0;
7062 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
7063 	u16			len_channellist_attr = 0;
7064 	u32			pktlen;
7065 	u8			dialogToken = 0;
7066 
7067 	/* struct xmit_frame			*pmgntframe; */
7068 	/* struct pkt_attrib			*pattrib; */
7069 	/* unsigned char					*pframe; */
7070 	struct rtw_ieee80211_hdr	*pwlanhdr;
7071 	unsigned short				*fctrl;
7072 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7073 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7074 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7075 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7076 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
7077 
7078 #ifdef CONFIG_WFD
7079 	u32					wfdielen = 0;
7080 #endif
7081 
7082 	/* for debug */
7083 	u8 *dbgbuf = pframe;
7084 	u8 dbgbufLen = 0, index = 0;
7085 
7086 	RTW_INFO("%s\n", __FUNCTION__);
7087 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7088 
7089 	fctrl = &(pwlanhdr->frame_ctl);
7090 	*(fctrl) = 0;
7091 
7092 	/* RA, filled by FW */
7093 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7094 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7095 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7096 
7097 	SetSeqNum(pwlanhdr, 0);
7098 	set_frame_sub_type(pframe, WIFI_ACTION);
7099 
7100 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7101 	pframe += pktlen;
7102 
7103 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7104 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7105 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7106 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7107 
7108 	/* dialog token, filled by FW */
7109 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7110 
7111 	_rtw_memset(wpsie, 0x00, 255);
7112 	wpsielen = 0;
7113 
7114 	/*	WPS Section */
7115 	wpsielen = 0;
7116 	/*	WPS OUI */
7117 	*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
7118 	wpsielen += 4;
7119 
7120 	/*	WPS version */
7121 	/*	Type: */
7122 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7123 	wpsielen += 2;
7124 
7125 	/*	Length: */
7126 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7127 	wpsielen += 2;
7128 
7129 	/*	Value: */
7130 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
7131 
7132 	/*	Device Password ID */
7133 	/*	Type: */
7134 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
7135 	wpsielen += 2;
7136 
7137 	/*	Length: */
7138 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7139 	wpsielen += 2;
7140 
7141 	/*	Value: */
7142 	if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
7143 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
7144 	else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
7145 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
7146 	else
7147 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
7148 	wpsielen += 2;
7149 
7150 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7151 
7152 
7153 	/*	P2P IE Section. */
7154 
7155 	/*	P2P OUI */
7156 	p2pielen = 0;
7157 	p2pie[p2pielen++] = 0x50;
7158 	p2pie[p2pielen++] = 0x6F;
7159 	p2pie[p2pielen++] = 0x9A;
7160 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
7161 
7162 	/*	Commented by Albert 20100908 */
7163 	/*	According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
7164 	/*	1. Status */
7165 	/*	2. P2P Capability */
7166 	/*	3. Group Owner Intent */
7167 	/*	4. Configuration Timeout */
7168 	/*	5. Operating Channel */
7169 	/*	6. Intended P2P Interface Address */
7170 	/*	7. Channel List */
7171 	/*	8. Device Info */
7172 	/*	9. Group ID	( Only GO ) */
7173 
7174 
7175 	/*	ToDo: */
7176 
7177 	/*	P2P Status */
7178 	/*	Type: */
7179 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
7180 
7181 	/*	Length: */
7182 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7183 	p2pielen += 2;
7184 
7185 	/*	Value, filled by FW */
7186 	p2pie[p2pielen++] = 1;
7187 
7188 	/*	P2P Capability */
7189 	/*	Type: */
7190 	p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
7191 
7192 	/*	Length: */
7193 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7194 	p2pielen += 2;
7195 
7196 	/*	Value: */
7197 	/*	Device Capability Bitmap, 1 byte */
7198 
7199 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
7200 		/*	Commented by Albert 2011/03/08 */
7201 		/*	According to the P2P specification */
7202 		/*	if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
7203 		p2pie[p2pielen++] = 0;
7204 	} else {
7205 		/*	Be group owner or meet the error case */
7206 		p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
7207 	}
7208 
7209 	/*	Group Capability Bitmap, 1 byte */
7210 	if (pwdinfo->persistent_supported)
7211 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
7212 	else
7213 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
7214 
7215 	/*	Group Owner Intent */
7216 	/*	Type: */
7217 	p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
7218 
7219 	/*	Length: */
7220 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7221 	p2pielen += 2;
7222 
7223 	/*	Value: */
7224 	if (pwdinfo->peer_intent & 0x01) {
7225 		/*	Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
7226 		p2pie[p2pielen++] = (pwdinfo->intent << 1);
7227 	} else {
7228 		/*	Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
7229 		p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
7230 	}
7231 
7232 
7233 	/*	Configuration Timeout */
7234 	/*	Type: */
7235 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7236 
7237 	/*	Length: */
7238 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7239 	p2pielen += 2;
7240 
7241 	/*	Value: */
7242 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
7243 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
7244 
7245 	/*	Operating Channel */
7246 	/*	Type: */
7247 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7248 
7249 	/*	Length: */
7250 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7251 	p2pielen += 2;
7252 
7253 	/*	Value: */
7254 	/*	Country String */
7255 	p2pie[p2pielen++] = 'X';
7256 	p2pie[p2pielen++] = 'X';
7257 
7258 	/*	The third byte should be set to 0x04. */
7259 	/*	Described in the "Operating Channel Attribute" section. */
7260 	p2pie[p2pielen++] = 0x04;
7261 
7262 	/*	Operating Class */
7263 	if (pwdinfo->operating_channel <= 14) {
7264 		/*	Operating Class */
7265 		p2pie[p2pielen++] = 0x51;
7266 	} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
7267 		/*	Operating Class */
7268 		p2pie[p2pielen++] = 0x73;
7269 	} else {
7270 		/*	Operating Class */
7271 		p2pie[p2pielen++] = 0x7c;
7272 	}
7273 
7274 	/*	Channel Number */
7275 	p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
7276 
7277 	/*	Intended P2P Interface Address	 */
7278 	/*	Type: */
7279 	p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
7280 
7281 	/*	Length: */
7282 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7283 	p2pielen += 2;
7284 
7285 	/*	Value: */
7286 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7287 	p2pielen += ETH_ALEN;
7288 
7289 	/*	Channel List */
7290 	/*	Type: */
7291 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7292 
7293 	/* Country String(3) */
7294 	/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7295 	/* + number of channels in all classes */
7296 	len_channellist_attr = 3
7297 		       + (1 + 1) * (u16)ch_list->reg_classes
7298 		       + get_reg_classes_full_count(ch_list);
7299 
7300 #ifdef CONFIG_CONCURRENT_MODE
7301 	if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
7302 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7303 	else
7304 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7305 
7306 #else
7307 
7308 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7309 
7310 #endif
7311 	p2pielen += 2;
7312 
7313 	/*	Value: */
7314 	/*	Country String */
7315 	p2pie[p2pielen++] = 'X';
7316 	p2pie[p2pielen++] = 'X';
7317 
7318 	/*	The third byte should be set to 0x04. */
7319 	/*	Described in the "Operating Channel Attribute" section. */
7320 	p2pie[p2pielen++] = 0x04;
7321 
7322 	/*	Channel Entry List */
7323 
7324 #ifdef CONFIG_CONCURRENT_MODE
7325 	if (rtw_mi_check_status(padapter, MI_LINKED)) {
7326 		u8 union_ch = rtw_mi_get_union_chan(padapter);
7327 
7328 		/*	Operating Class */
7329 		if (union_ch > 14) {
7330 			if (union_ch >= 149)
7331 				p2pie[p2pielen++] = 0x7c;
7332 			else
7333 				p2pie[p2pielen++] = 0x73;
7334 		} else
7335 			p2pie[p2pielen++] = 0x51;
7336 
7337 
7338 		/*	Number of Channels */
7339 		/*	Just support 1 channel and this channel is AP's channel */
7340 		p2pie[p2pielen++] = 1;
7341 
7342 		/*	Channel List */
7343 		p2pie[p2pielen++] = union_ch;
7344 	} else
7345 #endif /* CONFIG_CONCURRENT_MODE */
7346 	{
7347 		int i, j;
7348 		for (j = 0; j < ch_list->reg_classes; j++) {
7349 			/*	Operating Class */
7350 			p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7351 
7352 			/*	Number of Channels */
7353 			p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7354 
7355 			/*	Channel List */
7356 			for (i = 0; i < ch_list->reg_class[j].channels; i++)
7357 				p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7358 		}
7359 	}
7360 
7361 	/*	Device Info */
7362 	/*	Type: */
7363 	p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
7364 
7365 	/*	Length: */
7366 	/*	21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)  */
7367 	/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7368 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
7369 	p2pielen += 2;
7370 
7371 	/*	Value: */
7372 	/*	P2P Device Address */
7373 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7374 	p2pielen += ETH_ALEN;
7375 
7376 	/*	Config Method */
7377 	/*	This field should be big endian. Noted by P2P specification. */
7378 
7379 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7380 
7381 	p2pielen += 2;
7382 
7383 	/*	Primary Device Type */
7384 	/*	Category ID */
7385 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7386 	p2pielen += 2;
7387 
7388 	/*	OUI */
7389 	*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
7390 	p2pielen += 4;
7391 
7392 	/*	Sub Category ID */
7393 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7394 	p2pielen += 2;
7395 
7396 	/*	Number of Secondary Device Types */
7397 	p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
7398 
7399 	/*	Device Name */
7400 	/*	Type: */
7401 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7402 	p2pielen += 2;
7403 
7404 	/*	Length: */
7405 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
7406 	p2pielen += 2;
7407 
7408 	/*	Value: */
7409 	_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
7410 	p2pielen += pwdinfo->device_name_len;
7411 
7412 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7413 		/*	Group ID Attribute */
7414 		/*	Type: */
7415 		p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
7416 
7417 		/*	Length: */
7418 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
7419 		p2pielen += 2;
7420 
7421 		/*	Value: */
7422 		/*	p2P Device Address */
7423 		_rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
7424 		p2pielen += ETH_ALEN;
7425 
7426 		/*	SSID */
7427 		_rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
7428 		p2pielen += pwdinfo->nego_ssidlen;
7429 
7430 	}
7431 
7432 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7433 
7434 #ifdef CONFIG_WFD
7435 	wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
7436 	pframe += wfdielen;
7437 	pktlen += wfdielen;
7438 #endif
7439 
7440 	*pLength = pktlen;
7441 #if 0
7442 	/* printf dbg msg */
7443 	dbgbufLen = pktlen;
7444 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7445 
7446 	for (index = 0; index < dbgbufLen; index++)
7447 		printk("%x ", *(dbgbuf + index));
7448 
7449 	printk("\n");
7450 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7451 #endif
7452 }
7453 
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7454 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7455 {
7456 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7457 	u8			action = P2P_PUB_ACTION_ACTION;
7458 	u32			p2poui = cpu_to_be32(P2POUI);
7459 	u8			oui_subtype = P2P_INVIT_RESP;
7460 	u8			p2pie[255] = { 0x00 };
7461 	u8			p2pielen = 0, i;
7462 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
7463 	u16			len_channellist_attr = 0;
7464 	u32			pktlen;
7465 	u8			dialogToken = 0;
7466 #ifdef CONFIG_WFD
7467 	u32					wfdielen = 0;
7468 #endif
7469 
7470 	/* struct xmit_frame			*pmgntframe; */
7471 	/* struct pkt_attrib			*pattrib; */
7472 	/* unsigned char					*pframe; */
7473 	struct rtw_ieee80211_hdr	*pwlanhdr;
7474 	unsigned short				*fctrl;
7475 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7476 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7477 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7478 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7479 
7480 	/* for debug */
7481 	u8 *dbgbuf = pframe;
7482 	u8 dbgbufLen = 0, index = 0;
7483 
7484 
7485 	RTW_INFO("%s\n", __FUNCTION__);
7486 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7487 
7488 	fctrl = &(pwlanhdr->frame_ctl);
7489 	*(fctrl) = 0;
7490 
7491 	/* RA fill by FW */
7492 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7493 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7494 
7495 	/* BSSID fill by FW */
7496 	_rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
7497 
7498 	SetSeqNum(pwlanhdr, 0);
7499 	set_frame_sub_type(pframe, WIFI_ACTION);
7500 
7501 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7502 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7503 
7504 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7505 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7506 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7507 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7508 
7509 	/* dialog token, filled by FW */
7510 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7511 
7512 	/*	P2P IE Section. */
7513 
7514 	/*	P2P OUI */
7515 	p2pielen = 0;
7516 	p2pie[p2pielen++] = 0x50;
7517 	p2pie[p2pielen++] = 0x6F;
7518 	p2pie[p2pielen++] = 0x9A;
7519 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
7520 
7521 	/*	Commented by Albert 20101005 */
7522 	/*	According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
7523 	/*	1. Status */
7524 	/*	2. Configuration Timeout */
7525 	/*	3. Operating Channel	( Only GO ) */
7526 	/*	4. P2P Group BSSID	( Only GO ) */
7527 	/*	5. Channel List */
7528 
7529 	/*	P2P Status */
7530 	/*	Type: */
7531 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
7532 
7533 	/*	Length: */
7534 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7535 	p2pielen += 2;
7536 
7537 	/*	Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
7538 	p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7539 
7540 	/*	Configuration Timeout */
7541 	/*	Type: */
7542 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7543 
7544 	/*	Length: */
7545 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7546 	p2pielen += 2;
7547 
7548 	/*	Value: */
7549 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
7550 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
7551 
7552 	/* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
7553 #if 0
7554 	if (status_code == P2P_STATUS_SUCCESS) {
7555 		struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7556 
7557 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7558 			/*	The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
7559 			/*	In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
7560 			/*	First one is operating channel attribute. */
7561 			/*	Second one is P2P Group BSSID attribute. */
7562 
7563 			/*	Operating Channel */
7564 			/*	Type: */
7565 			p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7566 
7567 			/*	Length: */
7568 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7569 			p2pielen += 2;
7570 
7571 			/*	Value: */
7572 			/*	Country String */
7573 			p2pie[p2pielen++] = 'X';
7574 			p2pie[p2pielen++] = 'X';
7575 
7576 			/*	The third byte should be set to 0x04. */
7577 			/*	Described in the "Operating Channel Attribute" section. */
7578 			p2pie[p2pielen++] = 0x04;
7579 
7580 			/*	Operating Class */
7581 			p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
7582 
7583 			/*	Channel Number */
7584 			p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
7585 
7586 
7587 			/*	P2P Group BSSID */
7588 			/*	Type: */
7589 			p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
7590 
7591 			/*	Length: */
7592 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7593 			p2pielen += 2;
7594 
7595 			/*	Value: */
7596 			/*	P2P Device Address for GO */
7597 			_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7598 			p2pielen += ETH_ALEN;
7599 
7600 		}
7601 
7602 		/*	Channel List */
7603 		/*	Type: */
7604 		p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7605 
7606 		/*	Length: */
7607 		/* Country String(3) */
7608 		/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7609 		/* + number of channels in all classes */
7610 		len_channellist_attr = 3
7611 			+ (1 + 1) * (u16)ch_list->reg_classes
7612 			+ get_reg_classes_full_count(ch_list);
7613 
7614 #ifdef CONFIG_CONCURRENT_MODE
7615 		if (rtw_mi_check_status(padapter, MI_LINKED))
7616 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7617 		else
7618 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7619 
7620 #else
7621 
7622 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7623 
7624 #endif
7625 		p2pielen += 2;
7626 
7627 		/*	Value: */
7628 		/*	Country String */
7629 		p2pie[p2pielen++] = 'X';
7630 		p2pie[p2pielen++] = 'X';
7631 
7632 		/*	The third byte should be set to 0x04. */
7633 		/*	Described in the "Operating Channel Attribute" section. */
7634 		p2pie[p2pielen++] = 0x04;
7635 
7636 		/*	Channel Entry List */
7637 #ifdef CONFIG_CONCURRENT_MODE
7638 		if (rtw_mi_check_status(padapter, MI_LINKED)) {
7639 			u8 union_ch = rtw_mi_get_union_chan(padapter);
7640 
7641 			/*	Operating Class */
7642 			if (union_ch > 14) {
7643 				if (union_ch >= 149)
7644 					p2pie[p2pielen++] = 0x7c;
7645 				else
7646 					p2pie[p2pielen++] = 0x73;
7647 
7648 			} else
7649 				p2pie[p2pielen++] = 0x51;
7650 
7651 
7652 			/*	Number of Channels */
7653 			/*	Just support 1 channel and this channel is AP's channel */
7654 			p2pie[p2pielen++] = 1;
7655 
7656 			/*	Channel List */
7657 			p2pie[p2pielen++] = union_ch;
7658 		} else
7659 #endif /* CONFIG_CONCURRENT_MODE */
7660 		{
7661 			int i, j;
7662 			for (j = 0; j < ch_list->reg_classes; j++) {
7663 				/*	Operating Class */
7664 				p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7665 
7666 				/*	Number of Channels */
7667 				p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7668 
7669 				/*	Channel List */
7670 				for (i = 0; i < ch_list->reg_class[j].channels; i++)
7671 					p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7672 			}
7673 		}
7674 	}
7675 #endif
7676 
7677 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7678 
7679 #ifdef CONFIG_WFD
7680 	wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
7681 	pframe += wfdielen;
7682 	pktlen += wfdielen;
7683 #endif
7684 
7685 	*pLength = pktlen;
7686 
7687 #if 0
7688 	/* printf dbg msg */
7689 	dbgbufLen = pktlen;
7690 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7691 
7692 	for (index = 0; index < dbgbufLen; index++)
7693 		printk("%x ", *(dbgbuf + index));
7694 
7695 	printk("\n");
7696 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7697 #endif
7698 }
7699 
7700 
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7701 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7702 {
7703 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7704 	u8			action = P2P_PUB_ACTION_ACTION;
7705 	u8			dialogToken = 0;
7706 	u32			p2poui = cpu_to_be32(P2POUI);
7707 	u8			oui_subtype = P2P_PROVISION_DISC_RESP;
7708 	u8			wpsie[100] = { 0x00 };
7709 	u8			wpsielen = 0;
7710 	u32			pktlen;
7711 #ifdef CONFIG_WFD
7712 	u32					wfdielen = 0;
7713 #endif
7714 
7715 	/* struct xmit_frame			*pmgntframe; */
7716 	/* struct pkt_attrib			*pattrib; */
7717 	/* unsigned char					*pframe; */
7718 	struct rtw_ieee80211_hdr	*pwlanhdr;
7719 	unsigned short				*fctrl;
7720 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7721 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7722 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7723 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7724 
7725 	/* for debug */
7726 	u8 *dbgbuf = pframe;
7727 	u8 dbgbufLen = 0, index = 0;
7728 
7729 	RTW_INFO("%s\n", __FUNCTION__);
7730 
7731 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7732 
7733 	fctrl = &(pwlanhdr->frame_ctl);
7734 	*(fctrl) = 0;
7735 
7736 	/* RA filled by FW */
7737 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7738 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7739 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7740 
7741 	SetSeqNum(pwlanhdr, 0);
7742 	set_frame_sub_type(pframe, WIFI_ACTION);
7743 
7744 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7745 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7746 
7747 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7748 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7749 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7750 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7751 	/* dialog token, filled by FW */
7752 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7753 
7754 	wpsielen = 0;
7755 	/*	WPS OUI */
7756 	/* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
7757 	RTW_PUT_BE32(wpsie, WPSOUI);
7758 	wpsielen += 4;
7759 
7760 #if 0
7761 	/*	WPS version */
7762 	/*	Type: */
7763 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7764 	wpsielen += 2;
7765 
7766 	/*	Length: */
7767 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7768 	wpsielen += 2;
7769 
7770 	/*	Value: */
7771 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
7772 #endif
7773 
7774 	/*	Config Method */
7775 	/*	Type: */
7776 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
7777 	RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
7778 	wpsielen += 2;
7779 
7780 	/*	Length: */
7781 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
7782 	RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
7783 	wpsielen += 2;
7784 
7785 	/*	Value: filled by FW, default value is PBC */
7786 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
7787 	RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
7788 	wpsielen += 2;
7789 
7790 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7791 
7792 #ifdef CONFIG_WFD
7793 	wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
7794 	pframe += wfdielen;
7795 	pktlen += wfdielen;
7796 #endif
7797 
7798 	*pLength = pktlen;
7799 
7800 	/* printf dbg msg */
7801 #if 0
7802 	dbgbufLen = pktlen;
7803 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT  ProvisionDis Rsp\n");
7804 
7805 	for (index = 0; index < dbgbufLen; index++)
7806 		printk("%x ", *(dbgbuf + index));
7807 
7808 	printk("\n");
7809 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7810 #endif
7811 }
7812 
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)7813 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
7814 {
7815 	u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
7816 	struct hal_ops *pHalFunc = &adapter->hal_func;
7817 	u8 ret = _FAIL;
7818 
7819 	RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
7820 		 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
7821 		 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
7822 		 rsvdpageloc->LocPDRsp);
7823 
7824 	SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
7825 	SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
7826 	SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
7827 	SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
7828 	SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
7829 
7830 	/* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
7831 	ret = rtw_hal_fill_h2c_cmd(adapter,
7832 				   H2C_P2P_OFFLOAD_RSVD_PAGE,
7833 				   H2C_P2PRSVDPAGE_LOC_LEN,
7834 				   u1H2CP2PRsvdPageParm);
7835 
7836 	return ret;
7837 }
7838 
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)7839 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
7840 {
7841 
7842 	u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
7843 	struct wifidirect_info	*pwdinfo = &(adapter->wdinfo);
7844 	struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
7845 	struct hal_ops *pHalFunc = &adapter->hal_func;
7846 	u8 ret = _FAIL;
7847 
7848 	_rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
7849 	RTW_INFO("%s\n", __func__);
7850 	switch (pwdinfo->role) {
7851 	case P2P_ROLE_DEVICE:
7852 		RTW_INFO("P2P_ROLE_DEVICE\n");
7853 		p2p_wowlan_offload->role = 0;
7854 		break;
7855 	case P2P_ROLE_CLIENT:
7856 		RTW_INFO("P2P_ROLE_CLIENT\n");
7857 		p2p_wowlan_offload->role = 1;
7858 		break;
7859 	case P2P_ROLE_GO:
7860 		RTW_INFO("P2P_ROLE_GO\n");
7861 		p2p_wowlan_offload->role = 2;
7862 		break;
7863 	default:
7864 		RTW_INFO("P2P_ROLE_DISABLE\n");
7865 		break;
7866 	}
7867 	p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
7868 	p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
7869 	offload_cmd = (u8 *)p2p_wowlan_offload;
7870 	RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
7871 
7872 	ret = rtw_hal_fill_h2c_cmd(adapter,
7873 				   H2C_P2P_OFFLOAD,
7874 				   H2C_P2P_OFFLOAD_LEN,
7875 				   offload_cmd);
7876 	return ret;
7877 
7878 	/* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
7879 }
7880 #endif /* CONFIG_P2P_WOWLAN */
7881 
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)7882 void rtw_hal_construct_beacon(_adapter *padapter,
7883 				     u8 *pframe, u32 *pLength)
7884 {
7885 	struct rtw_ieee80211_hdr	*pwlanhdr;
7886 	u16					*fctrl;
7887 	u32					pktlen;
7888 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7889 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7890 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
7891 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7892 
7893 
7894 	/* RTW_INFO("%s\n", __FUNCTION__); */
7895 
7896 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7897 
7898 	fctrl = &(pwlanhdr->frame_ctl);
7899 	*(fctrl) = 0;
7900 
7901 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7902 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7903 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7904 
7905 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7906 	/* pmlmeext->mgnt_seq++; */
7907 	set_frame_sub_type(pframe, WIFI_BEACON);
7908 
7909 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7910 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7911 
7912 	/* timestamp will be inserted by hardware */
7913 	pframe += 8;
7914 	pktlen += 8;
7915 
7916 	/* beacon interval: 2 bytes */
7917 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7918 
7919 	pframe += 2;
7920 	pktlen += 2;
7921 
7922 #if 0
7923 	/* capability info: 2 bytes */
7924 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7925 
7926 	pframe += 2;
7927 	pktlen += 2;
7928 
7929 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
7930 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
7931 		pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
7932 		_rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
7933 
7934 		goto _ConstructBeacon;
7935 	}
7936 
7937 	/* below for ad-hoc mode */
7938 
7939 	/* SSID */
7940 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
7941 
7942 	/* supported rates... */
7943 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7944 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
7945 
7946 	/* DS parameter set */
7947 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
7948 
7949 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
7950 		u32 ATIMWindow;
7951 		/* IBSS Parameter Set... */
7952 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
7953 		ATIMWindow = 0;
7954 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
7955 	}
7956 
7957 
7958 	/* todo: ERP IE */
7959 
7960 
7961 	/* EXTERNDED SUPPORTED RATE */
7962 	if (rate_len > 8)
7963 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
7964 
7965 	/* todo:HT for adhoc */
7966 
7967 _ConstructBeacon:
7968 #endif
7969 
7970 	if ((pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
7971 		RTW_ERR("beacon frame too large ,len(%d,%d)\n",
7972 			(pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
7973 		rtw_warn_on(1);
7974 		return;
7975 	}
7976 
7977 	*pLength = pktlen;
7978 
7979 	/* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
7980 
7981 }
7982 
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)7983 static void rtw_hal_construct_PSPoll(_adapter *padapter,
7984 				     u8 *pframe, u32 *pLength)
7985 {
7986 	struct rtw_ieee80211_hdr	*pwlanhdr;
7987 	u16					*fctrl;
7988 	u32					pktlen;
7989 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7990 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7991 
7992 	/* RTW_INFO("%s\n", __FUNCTION__); */
7993 
7994 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7995 
7996 	/* Frame control. */
7997 	fctrl = &(pwlanhdr->frame_ctl);
7998 	*(fctrl) = 0;
7999 	SetPwrMgt(fctrl);
8000 	set_frame_sub_type(pframe, WIFI_PSPOLL);
8001 
8002 	/* AID. */
8003 	set_duration(pframe, (pmlmeinfo->aid | 0xc000));
8004 
8005 	/* BSSID. */
8006 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8007 
8008 	/* TA. */
8009 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8010 
8011 	*pLength = 16;
8012 }
8013 
8014 
8015 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_construct_fw_dbg_msg_pkt(PADAPTER padapter,u8 * pframe,u32 * plength)8016 void rtw_hal_construct_fw_dbg_msg_pkt(
8017 	PADAPTER padapter,
8018 	u8		*pframe,
8019 	u32		*plength)
8020 {
8021 	struct rtw_ieee80211_hdr	*pwlanhdr;
8022 	u16						*fctrl;
8023 	u32						pktlen;
8024 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
8025 	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
8026 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8027 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8028 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8029 
8030 
8031 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8032 
8033 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8034 
8035 	fctrl = &pwlanhdr->frame_ctl;
8036 	*(fctrl) = 0;
8037 
8038 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8039 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8040 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8041 
8042 	SetSeqNum(pwlanhdr, 0);
8043 
8044 	set_frame_sub_type(pframe, WIFI_DATA);
8045 
8046 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8047 
8048 	*plength = pktlen;
8049 }
8050 #endif /*DBG_FW_DEBUG_MSG_PKT*/
8051 
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)8052 void rtw_hal_construct_NullFunctionData(
8053 	PADAPTER padapter,
8054 	u8		*pframe,
8055 	u32		*pLength,
8056 	u8		bQoS,
8057 	u8		AC,
8058 	u8		bEosp,
8059 	u8		bForcePowerSave)
8060 {
8061 	struct rtw_ieee80211_hdr	*pwlanhdr;
8062 	u16						*fctrl;
8063 	u32						pktlen;
8064 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
8065 	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
8066 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8067 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8068 	u8 *sta_addr = NULL;
8069 	u8 bssid[ETH_ALEN] = {0};
8070 
8071 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8072 
8073 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8074 
8075 	fctrl = &pwlanhdr->frame_ctl;
8076 	*(fctrl) = 0;
8077 	if (bForcePowerSave)
8078 		SetPwrMgt(fctrl);
8079 
8080 	sta_addr = get_my_bssid(&pmlmeinfo->network);
8081 	if (NULL == sta_addr) {
8082 		_rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);
8083 		sta_addr = bssid;
8084 	}
8085 
8086 	switch (cur_network->network.InfrastructureMode) {
8087 	case Ndis802_11Infrastructure:
8088 		SetToDs(fctrl);
8089 		_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8090 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8091 		_rtw_memcpy(pwlanhdr->addr3, sta_addr, ETH_ALEN);
8092 		break;
8093 	case Ndis802_11APMode:
8094 		SetFrDs(fctrl);
8095 		_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8096 		_rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8097 		_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8098 		break;
8099 	case Ndis802_11IBSS:
8100 	default:
8101 		_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8102 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8103 		_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8104 		break;
8105 	}
8106 
8107 	SetSeqNum(pwlanhdr, 0);
8108 	set_duration(pwlanhdr, 0);
8109 
8110 	if (bQoS == _TRUE) {
8111 		struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
8112 
8113 		set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
8114 
8115 		pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
8116 		SetPriority(&pwlanqoshdr->qc, AC);
8117 		SetEOSP(&pwlanqoshdr->qc, bEosp);
8118 
8119 		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
8120 	} else {
8121 		set_frame_sub_type(pframe, WIFI_DATA_NULL);
8122 
8123 		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8124 	}
8125 
8126 	*pLength = pktlen;
8127 }
8128 
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,BOOLEAN bHideSSID)8129 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
8130 				BOOLEAN bHideSSID)
8131 {
8132 	struct rtw_ieee80211_hdr	*pwlanhdr;
8133 	u16					*fctrl;
8134 	u8					*mac, *bssid, *sta_addr;
8135 	u32					pktlen;
8136 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8137 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8138 	WLAN_BSSID_EX  *cur_network = &(pmlmeinfo->network);
8139 
8140 	/*RTW_INFO("%s\n", __FUNCTION__);*/
8141 
8142 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8143 
8144 	mac = adapter_mac_addr(padapter);
8145 	bssid = cur_network->MacAddress;
8146 	sta_addr = get_my_bssid(&pmlmeinfo->network);
8147 
8148 	fctrl = &(pwlanhdr->frame_ctl);
8149 	*(fctrl) = 0;
8150 	_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8151 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8152 	_rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8153 
8154 	SetSeqNum(pwlanhdr, 0);
8155 	set_frame_sub_type(fctrl, WIFI_PROBERSP);
8156 
8157 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8158 	pframe += pktlen;
8159 
8160 	if (cur_network->IELength > MAX_IE_SZ)
8161 		return;
8162 
8163 	_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8164 	pframe += cur_network->IELength;
8165 	pktlen += cur_network->IELength;
8166 
8167 	*pLength = pktlen;
8168 }
8169 
8170 #ifdef CONFIG_WOWLAN
rtw_hal_append_tkip_mic(PADAPTER padapter,u8 * pframe,u32 offset)8171 static void rtw_hal_append_tkip_mic(PADAPTER padapter,
8172 				    u8 *pframe, u32 offset)
8173 {
8174 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8175 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8176 	struct rtw_ieee80211_hdr	*pwlanhdr;
8177 	struct mic_data	micdata;
8178 	struct sta_info	*psta = NULL;
8179 	int res = 0;
8180 
8181 	u8	*payload = (u8 *)(pframe + offset);
8182 
8183 	u8	mic[8];
8184 	u8	priority[4] = {0x0};
8185 	u8	null_key[16] = {0x0};
8186 
8187 	RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
8188 
8189 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8190 
8191 	psta = rtw_get_stainfo(&padapter->stapriv,
8192 			get_my_bssid(&(pmlmeinfo->network)));
8193 	if (psta != NULL) {
8194 		res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
8195 				  null_key, 16);
8196 		if (res == _TRUE)
8197 			RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
8198 		rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
8199 	}
8200 
8201 	rtw_secmicappend(&micdata, pwlanhdr->addr3, 6);  /* DA */
8202 
8203 	rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
8204 
8205 	priority[0] = 0;
8206 
8207 	rtw_secmicappend(&micdata, &priority[0], 4);
8208 
8209 	rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
8210 
8211 	rtw_secgetmic(&micdata, &(mic[0]));
8212 
8213 	payload += 36;
8214 
8215 	_rtw_memcpy(payload, &(mic[0]), 8);
8216 }
8217 /*
8218  * Description:
8219  *	Construct the ARP response packet to support ARP offload.
8220  *   */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8221 static void rtw_hal_construct_ARPRsp(
8222 	PADAPTER padapter,
8223 	u8			*pframe,
8224 	u32			*pLength,
8225 	u8			*pIPAddress
8226 )
8227 {
8228 	struct rtw_ieee80211_hdr	*pwlanhdr;
8229 	u16	*fctrl;
8230 	u32	pktlen;
8231 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8232 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8233 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8234 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8235 	static u8	ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
8236 	u8	*pARPRspPkt = pframe;
8237 	/* for TKIP Cal MIC */
8238 	u8	*payload = pframe;
8239 	u8	EncryptionHeadOverhead = 0, arp_offset = 0;
8240 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8241 
8242 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8243 
8244 	fctrl = &pwlanhdr->frame_ctl;
8245 	*(fctrl) = 0;
8246 
8247 	/* ------------------------------------------------------------------------- */
8248 	/* MAC Header. */
8249 	/* ------------------------------------------------------------------------- */
8250 	SetFrameType(fctrl, WIFI_DATA);
8251 	/* set_frame_sub_type(fctrl, 0); */
8252 	SetToDs(fctrl);
8253 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8254 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8255 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8256 
8257 	SetSeqNum(pwlanhdr, 0);
8258 	set_duration(pwlanhdr, 0);
8259 	/* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
8260 	/* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
8261 	/* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
8262 	/* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
8263 	/* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
8264 	/* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
8265 
8266 	/* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
8267 	/* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
8268 #ifdef CONFIG_WAPI_SUPPORT
8269 	*pLength = sMacHdrLng;
8270 #else
8271 	*pLength = 24;
8272 #endif
8273 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8274 	case _WEP40_:
8275 	case _WEP104_:
8276 		EncryptionHeadOverhead = 4;
8277 		break;
8278 	case _TKIP_:
8279 		EncryptionHeadOverhead = 8;
8280 		break;
8281 	case _AES_:
8282 		EncryptionHeadOverhead = 8;
8283 		break;
8284 #ifdef CONFIG_WAPI_SUPPORT
8285 	case _SMS4_:
8286 		EncryptionHeadOverhead = 18;
8287 		break;
8288 #endif
8289 	default:
8290 		EncryptionHeadOverhead = 0;
8291 	}
8292 
8293 	if (EncryptionHeadOverhead > 0) {
8294 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8295 		*pLength += EncryptionHeadOverhead;
8296 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8297 		SetPrivacy(fctrl);
8298 	}
8299 
8300 	/* ------------------------------------------------------------------------- */
8301 	/* Frame Body. */
8302 	/* ------------------------------------------------------------------------- */
8303 	arp_offset = *pLength;
8304 	pARPRspPkt = (u8 *)(pframe + arp_offset);
8305 	payload = pARPRspPkt; /* Get Payload pointer */
8306 	/* LLC header */
8307 	_rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
8308 	*pLength += 8;
8309 
8310 	/* ARP element */
8311 	pARPRspPkt += 8;
8312 	SET_ARP_HTYPE(pARPRspPkt, 1);
8313 	SET_ARP_PTYPE(pARPRspPkt, ETH_P_IP);	/* IP protocol */
8314 	SET_ARP_HLEN(pARPRspPkt, ETH_ALEN);
8315 	SET_ARP_PLEN(pARPRspPkt, RTW_IP_ADDR_LEN);
8316 	SET_ARP_OPER(pARPRspPkt, 2);	/* ARP response */
8317 	SET_ARP_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
8318 	SET_ARP_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
8319 #ifdef CONFIG_ARP_KEEP_ALIVE
8320 	if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
8321 		SET_ARP_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
8322 		SET_ARP_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
8323 	} else
8324 #endif
8325 	{
8326 		SET_ARP_TARGET_MAC_ADDR(pARPRspPkt,
8327 				    get_my_bssid(&(pmlmeinfo->network)));
8328 		SET_ARP_TARGET_IP_ADDR(pARPRspPkt,
8329 					   pIPAddress);
8330 		RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
8331 			 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
8332 		RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
8333 			 IP_ARG(pIPAddress));
8334 	}
8335 
8336 	*pLength += 28;
8337 
8338 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8339 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
8340 		    IS_HARDWARE_TYPE_8812(padapter)) {
8341 			rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
8342 		}
8343 		*pLength += 8;
8344 	}
8345 }
8346 
8347 #ifdef CONFIG_IPV6
8348 /*
8349  * Description: Neighbor Discovery Offload.
8350  */
rtw_hal_construct_na_message(_adapter * padapter,u8 * pframe,u32 * pLength)8351 static void rtw_hal_construct_na_message(_adapter *padapter,
8352 				     u8 *pframe, u32 *pLength)
8353 {
8354 	struct rtw_ieee80211_hdr *pwlanhdr = NULL;
8355 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8356 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
8357 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
8358 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8359 
8360 	u32 pktlen = 0;
8361 	u16 *fctrl = NULL;
8362 
8363 	u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8364 	u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
8365 	u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
8366 	u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
8367 	u8 val8 = 0;
8368 
8369 	u8 *p_na_msg = pframe;
8370 	/* for TKIP Cal MIC */
8371 	u8 *payload = pframe;
8372 	u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
8373 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8374 
8375 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8376 
8377 	fctrl = &pwlanhdr->frame_ctl;
8378 	*(fctrl) = 0;
8379 
8380 	/* ------------------------------------------------------------------------- */
8381 	/* MAC Header. */
8382 	/* ------------------------------------------------------------------------- */
8383 	SetFrameType(fctrl, WIFI_DATA);
8384 	SetToDs(fctrl);
8385 	_rtw_memcpy(pwlanhdr->addr1,
8386 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8387 	_rtw_memcpy(pwlanhdr->addr2,
8388 		    adapter_mac_addr(padapter), ETH_ALEN);
8389 	_rtw_memcpy(pwlanhdr->addr3,
8390 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8391 
8392 	SetSeqNum(pwlanhdr, 0);
8393 	set_duration(pwlanhdr, 0);
8394 
8395 #ifdef CONFIG_WAPI_SUPPORT
8396 	*pLength = sMacHdrLng;
8397 #else
8398 	*pLength = 24;
8399 #endif
8400 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8401 	case _WEP40_:
8402 	case _WEP104_:
8403 		EncryptionHeadOverhead = 4;
8404 		break;
8405 	case _TKIP_:
8406 		EncryptionHeadOverhead = 8;
8407 		break;
8408 	case _AES_:
8409 		EncryptionHeadOverhead = 8;
8410 		break;
8411 #ifdef CONFIG_WAPI_SUPPORT
8412 	case _SMS4_:
8413 		EncryptionHeadOverhead = 18;
8414 		break;
8415 #endif
8416 	default:
8417 		EncryptionHeadOverhead = 0;
8418 	}
8419 
8420 	if (EncryptionHeadOverhead > 0) {
8421 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8422 		*pLength += EncryptionHeadOverhead;
8423 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8424 		SetPrivacy(fctrl);
8425 	}
8426 
8427 	/* ------------------------------------------------------------------------- */
8428 	/* Frame Body. */
8429 	/* ------------------------------------------------------------------------- */
8430 	na_msg_offset = *pLength;
8431 	p_na_msg = (u8 *)(pframe + na_msg_offset);
8432 	payload = p_na_msg; /* Get Payload pointer */
8433 
8434 	/* LLC header */
8435 	val8 = sizeof(ns_hdr);
8436 	_rtw_memcpy(p_na_msg, ns_hdr, val8);
8437 	*pLength += val8;
8438 	p_na_msg += val8;
8439 
8440 	/* IPv6 Header */
8441 	/* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
8442 	val8 = sizeof(ipv6_info);
8443 	_rtw_memcpy(p_na_msg, ipv6_info, val8);
8444 	*pLength += val8;
8445 	p_na_msg += val8;
8446 
8447 	/* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
8448 	val8 = sizeof(ipv6_contx);
8449 	_rtw_memcpy(p_na_msg, ipv6_contx, val8);
8450 	*pLength += val8;
8451 	p_na_msg += val8;
8452 
8453 	/* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
8454 	_rtw_memset(&(p_na_msg[*pLength]), 0, 32);
8455 	*pLength += 32;
8456 	p_na_msg += 32;
8457 
8458 	/* ICMPv6 */
8459 	/* 1. Type : 0x88 (NA)
8460 	 * 2. Code : 0x00
8461 	 * 3. ChechSum : 0x00 0x00 (RSvd)
8462 	 * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
8463 	 */
8464 	val8 = sizeof(icmpv6_hdr);
8465 	_rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
8466 	*pLength += val8;
8467 	p_na_msg += val8;
8468 
8469 	/* TA: 16 bytes*/
8470 	_rtw_memset(&(p_na_msg[*pLength]), 0, 16);
8471 	*pLength += 16;
8472 	p_na_msg += 16;
8473 
8474 	/* ICMPv6 Target Link Layer Address */
8475 	p_na_msg[0] = 0x02; /* type */
8476 	p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
8477 	*pLength += 2;
8478 	p_na_msg += 2;
8479 
8480 	_rtw_memset(&(p_na_msg[*pLength]), 0, 6);
8481 	*pLength += 6;
8482 	p_na_msg += 6;
8483 
8484 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8485 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
8486 		    IS_HARDWARE_TYPE_8812(padapter)) {
8487 			rtw_hal_append_tkip_mic(padapter, pframe,
8488 						na_msg_offset);
8489 		}
8490 		*pLength += 8;
8491 	}
8492 }
8493 /*
8494  * Description: Neighbor Discovery Protocol Information.
8495  */
rtw_hal_construct_ndp_info(_adapter * padapter,u8 * pframe,u32 * pLength)8496 static void rtw_hal_construct_ndp_info(_adapter *padapter,
8497 				     u8 *pframe, u32 *pLength)
8498 {
8499 	struct mlme_ext_priv *pmlmeext = NULL;
8500 	struct mlme_ext_info *pmlmeinfo = NULL;
8501 	struct rtw_ndp_info ndp_info;
8502 	u8	*pndp_info = pframe;
8503 	u8	len = sizeof(struct rtw_ndp_info);
8504 
8505 	RTW_INFO("%s: len: %d\n", __func__, len);
8506 
8507 	pmlmeext =  &padapter->mlmeextpriv;
8508 	pmlmeinfo = &pmlmeext->mlmext_info;
8509 
8510 	_rtw_memset(pframe, 0, len);
8511 	_rtw_memset(&ndp_info, 0, len);
8512 
8513 	ndp_info.enable = 1;
8514 	ndp_info.check_remote_ip = 0;
8515 	ndp_info.num_of_target_ip = 1;
8516 
8517 	_rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
8518 		    ETH_ALEN);
8519 	_rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
8520 		    RTW_IPv6_ADDR_LEN);
8521 
8522 	_rtw_memcpy(pndp_info, &ndp_info, len);
8523 }
8524 #endif /* CONFIG_IPV6 */
8525 
8526 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)8527 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
8528 				       u32 *pLength, pno_ssid_t *ssid)
8529 {
8530 	struct rtw_ieee80211_hdr	*pwlanhdr;
8531 	u16				*fctrl;
8532 	u32				pktlen;
8533 	unsigned char			*mac;
8534 	unsigned char			bssrate[NumRates];
8535 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
8536 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8537 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8538 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8539 	int	bssrate_len = 0;
8540 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8541 
8542 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8543 	mac = adapter_mac_addr(padapter);
8544 
8545 	fctrl = &(pwlanhdr->frame_ctl);
8546 	*(fctrl) = 0;
8547 
8548 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8549 	_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8550 
8551 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8552 
8553 	SetSeqNum(pwlanhdr, 0);
8554 	set_frame_sub_type(pframe, WIFI_PROBEREQ);
8555 
8556 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8557 	pframe += pktlen;
8558 
8559 	if (ssid == NULL)
8560 		pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
8561 	else {
8562 		/* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
8563 		pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
8564 	}
8565 
8566 	get_rate_set(padapter, bssrate, &bssrate_len);
8567 
8568 	if (bssrate_len > 8) {
8569 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
8570 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
8571 	} else
8572 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
8573 
8574 	*pLength = pktlen;
8575 }
8576 
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)8577 static void rtw_hal_construct_PNO_info(_adapter *padapter,
8578 				       u8 *pframe, u32 *pLength)
8579 {
8580 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8581 	int i;
8582 
8583 	u8	*pPnoInfoPkt = pframe;
8584 	pPnoInfoPkt = (u8 *)(pframe + *pLength);
8585 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
8586 
8587 	pPnoInfoPkt += 1;
8588 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
8589 
8590 	pPnoInfoPkt += 3;
8591 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
8592 
8593 	pPnoInfoPkt += 4;
8594 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
8595 
8596 	pPnoInfoPkt += 4;
8597 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
8598 
8599 	pPnoInfoPkt += 4;
8600 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
8601 
8602 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8603 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
8604 
8605 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8606 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
8607 
8608 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8609 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
8610 
8611 	pPnoInfoPkt += MAX_HIDDEN_AP;
8612 
8613 	/*
8614 	SSID is located at 128th Byte in NLO info Page
8615 	*/
8616 
8617 	*pLength += 128;
8618 	pPnoInfoPkt = pframe + 128;
8619 
8620 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8621 		_rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8622 			    pwrctl->pnlo_info->ssid_length[i]);
8623 		*pLength += WLAN_SSID_MAXLEN;
8624 		pPnoInfoPkt += WLAN_SSID_MAXLEN;
8625 	}
8626 }
8627 
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)8628 static void rtw_hal_construct_ssid_list(_adapter *padapter,
8629 					u8 *pframe, u32 *pLength)
8630 {
8631 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8632 	u8 *pSSIDListPkt = pframe;
8633 	int i;
8634 
8635 	pSSIDListPkt = (u8 *)(pframe + *pLength);
8636 
8637 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8638 		_rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8639 			    pwrctl->pnlo_info->ssid_length[i]);
8640 
8641 		*pLength += WLAN_SSID_MAXLEN;
8642 		pSSIDListPkt += WLAN_SSID_MAXLEN;
8643 	}
8644 }
8645 
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)8646 static void rtw_hal_construct_scan_info(_adapter *padapter,
8647 					u8 *pframe, u32 *pLength)
8648 {
8649 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8650 	u8 *pScanInfoPkt = pframe;
8651 	int i;
8652 
8653 	pScanInfoPkt = (u8 *)(pframe + *pLength);
8654 
8655 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
8656 
8657 	*pLength += 1;
8658 	pScanInfoPkt += 1;
8659 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
8660 
8661 
8662 	*pLength += 1;
8663 	pScanInfoPkt += 1;
8664 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
8665 
8666 
8667 	*pLength += 1;
8668 	pScanInfoPkt += 1;
8669 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
8670 
8671 	*pLength += 1;
8672 	pScanInfoPkt += 1;
8673 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
8674 
8675 	*pLength += 1;
8676 	pScanInfoPkt += 1;
8677 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
8678 
8679 	*pLength += 1;
8680 	pScanInfoPkt += 1;
8681 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
8682 
8683 	*pLength += 1;
8684 	pScanInfoPkt += 1;
8685 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
8686 
8687 	*pLength += 1;
8688 	pScanInfoPkt += 1;
8689 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
8690 
8691 	*pLength += 8;
8692 	pScanInfoPkt += 8;
8693 
8694 	for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
8695 		_rtw_memcpy(pScanInfoPkt,
8696 			    &pwrctl->pscan_info->ssid_channel_info[i], 4);
8697 		*pLength += 4;
8698 		pScanInfoPkt += 4;
8699 	}
8700 }
8701 #endif /* CONFIG_PNO_SUPPORT */
8702 
8703 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)8704 static void rtw_hal_construct_GTKRsp(
8705 	PADAPTER	padapter,
8706 	u8		*pframe,
8707 	u32		*pLength
8708 )
8709 {
8710 	struct rtw_ieee80211_hdr	*pwlanhdr;
8711 	u16	*fctrl;
8712 	u32	pktlen;
8713 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8714 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
8715 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8716 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8717 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8718 	static u8	LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
8719 	static u8	GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
8720 	u8	*pGTKRspPkt = pframe;
8721 	u8	EncryptionHeadOverhead = 0;
8722 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8723 
8724 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8725 
8726 	fctrl = &pwlanhdr->frame_ctl;
8727 	*(fctrl) = 0;
8728 
8729 	/* ------------------------------------------------------------------------- */
8730 	/* MAC Header. */
8731 	/* ------------------------------------------------------------------------- */
8732 	SetFrameType(fctrl, WIFI_DATA);
8733 	/* set_frame_sub_type(fctrl, 0); */
8734 	SetToDs(fctrl);
8735 
8736 	_rtw_memcpy(pwlanhdr->addr1,
8737 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8738 
8739 	_rtw_memcpy(pwlanhdr->addr2,
8740 		    adapter_mac_addr(padapter), ETH_ALEN);
8741 
8742 	_rtw_memcpy(pwlanhdr->addr3,
8743 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8744 
8745 	SetSeqNum(pwlanhdr, 0);
8746 	set_duration(pwlanhdr, 0);
8747 
8748 #ifdef CONFIG_WAPI_SUPPORT
8749 	*pLength = sMacHdrLng;
8750 #else
8751 	*pLength = 24;
8752 #endif /* CONFIG_WAPI_SUPPORT */
8753 
8754 	/* ------------------------------------------------------------------------- */
8755 	/* Security Header: leave space for it if necessary. */
8756 	/* ------------------------------------------------------------------------- */
8757 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8758 	case _WEP40_:
8759 	case _WEP104_:
8760 		EncryptionHeadOverhead = 4;
8761 		break;
8762 	case _TKIP_:
8763 		EncryptionHeadOverhead = 8;
8764 		break;
8765 	case _AES_:
8766 		EncryptionHeadOverhead = 8;
8767 		break;
8768 #ifdef CONFIG_WAPI_SUPPORT
8769 	case _SMS4_:
8770 		EncryptionHeadOverhead = 18;
8771 		break;
8772 #endif /* CONFIG_WAPI_SUPPORT */
8773 	default:
8774 		EncryptionHeadOverhead = 0;
8775 	}
8776 
8777 	if (EncryptionHeadOverhead > 0) {
8778 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8779 		*pLength += EncryptionHeadOverhead;
8780 		/* SET_80211_HDR_WEP(pGTKRspPkt, 1);  */ /* Suggested by CCW. */
8781 		/* GTK's privacy bit is done by FW */
8782 		/* SetPrivacy(fctrl); */
8783 	}
8784 	/* ------------------------------------------------------------------------- */
8785 	/* Frame Body. */
8786 	/* ------------------------------------------------------------------------- */
8787 	pGTKRspPkt = (u8 *)(pframe + *pLength);
8788 	/* LLC header */
8789 	_rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
8790 	*pLength += 8;
8791 
8792 	/* GTK element */
8793 	pGTKRspPkt += 8;
8794 
8795 	/* GTK frame body after LLC, part 1 */
8796 	/* TKIP key_length = 32, AES key_length = 16 */
8797 	if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
8798 		GTKbody_a[8] = 0x20;
8799 
8800 	/* GTK frame body after LLC, part 1 */
8801 	_rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
8802 	*pLength += 11;
8803 	pGTKRspPkt += 11;
8804 	/* GTK frame body after LLC, part 2 */
8805 	_rtw_memset(&(pframe[*pLength]), 0, 88);
8806 	*pLength += 88;
8807 	pGTKRspPkt += 88;
8808 
8809 	if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
8810 		*pLength += 8;
8811 }
8812 #endif /* CONFIG_GTK_OL */
8813 
8814 #define PN_2_CCMPH(ch,key_id)	((ch) & 0x000000000000ffff) \
8815 				| (((ch) & 0x0000ffffffff0000) << 16) \
8816 				| (((key_id) << 30)) \
8817 				| BIT(29)
rtw_hal_construct_remote_control_info(_adapter * adapter,u8 * pframe,u32 * pLength)8818 static void rtw_hal_construct_remote_control_info(_adapter *adapter,
8819 						  u8 *pframe, u32 *pLength)
8820 {
8821 	struct mlme_priv   *pmlmepriv = &adapter->mlmepriv;
8822 	struct sta_priv *pstapriv = &adapter->stapriv;
8823 	struct security_priv *psecuritypriv = &adapter->securitypriv;
8824 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
8825 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8826 	struct sta_info *psta;
8827 	struct stainfo_rxcache *prxcache;
8828 	u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
8829 	size_t sz = 0, total = 0;
8830 	u64 ccmp_hdr = 0, tmp_key = 0;
8831 
8832 	psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
8833 
8834 	if (psta == NULL) {
8835 		rtw_warn_on(1);
8836 		return;
8837 	}
8838 
8839 	prxcache = &psta->sta_recvpriv.rxcache;
8840 	sz = sizeof(cur_dot11rxiv);
8841 
8842 	/* 3 SEC IV * 1 page */
8843 	rtw_get_sec_iv(adapter, cur_dot11rxiv,
8844 		       get_my_bssid(&pmlmeinfo->network));
8845 
8846 	_rtw_memcpy(pframe, cur_dot11rxiv, sz);
8847 	*pLength += sz;
8848 	pframe += sz;
8849 
8850 	_rtw_memset(&cur_dot11rxiv, 0, sz);
8851 
8852 	if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
8853 		id = psecuritypriv->dot118021XGrpKeyid;
8854 		tid_id = prxcache->last_tid;
8855 		REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
8856 		REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
8857 		REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
8858 		REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
8859 		_rtw_memcpy(pframe, cur_dot11rxiv, sz);
8860 		*pLength += sz;
8861 		pframe += sz;
8862 
8863 		_rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
8864 		*pLength += sz;
8865 		pframe += sz;
8866 
8867 		total = sizeof(psecuritypriv->iv_seq);
8868 		total /= sizeof(psecuritypriv->iv_seq[0]);
8869 
8870 		for (i = 0 ; i < total ; i ++) {
8871 			ccmp_hdr =
8872 				le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
8873 			_rtw_memset(&cur_dot11rxiv, 0, sz);
8874 			if (ccmp_hdr != 0) {
8875 				tmp_key = i;
8876 				ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
8877 				*(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
8878 				_rtw_memcpy(pframe, cur_dot11rxiv, sz);
8879 			}
8880 			*pLength += sz;
8881 			pframe += sz;
8882 		}
8883 	}
8884 }
8885 
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)8886 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
8887 		  u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
8888 				  RSVDPAGE_LOC *rsvd_page_loc)
8889 {
8890 	struct security_priv *psecuritypriv = &adapter->securitypriv;
8891 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8892 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8893 	struct mlme_ext_priv	*pmlmeext;
8894 	struct mlme_ext_info	*pmlmeinfo;
8895 	u32	ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
8896 	u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0;
8897 	u8 CurtPktPageNum = 0;
8898 
8899 #ifdef CONFIG_GTK_OL
8900 	struct sta_priv *pstapriv = &adapter->stapriv;
8901 	struct sta_info *psta;
8902 	struct security_priv *psecpriv = &adapter->securitypriv;
8903 	u8 kek[RTW_KEK_LEN];
8904 	u8 kck[RTW_KCK_LEN];
8905 #endif /* CONFIG_GTK_OL */
8906 #ifdef CONFIG_PNO_SUPPORT
8907 	int pno_index;
8908 	u8 ssid_num;
8909 #endif /* CONFIG_PNO_SUPPORT */
8910 
8911 	pmlmeext = &adapter->mlmeextpriv;
8912 	pmlmeinfo = &pmlmeext->mlmext_info;
8913 
8914 	if (pwrctl->wowlan_pno_enable == _FALSE) {
8915 		/* ARP RSP * 1 page */
8916 
8917 		rsvd_page_loc->LocArpRsp = *page_num;
8918 
8919 		RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
8920 
8921 		rtw_hal_construct_ARPRsp(adapter, &pframe[index],
8922 					 &ARPLength, pmlmeinfo->ip_addr);
8923 
8924 		rtw_hal_fill_fake_txdesc(adapter,
8925 					 &pframe[index - tx_desc],
8926 					 ARPLength, _FALSE, _FALSE, _TRUE);
8927 
8928 		CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
8929 
8930 		*page_num += CurtPktPageNum;
8931 
8932 		index += (CurtPktPageNum * page_size);
8933 		RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);
8934 
8935 #ifdef CONFIG_IPV6
8936 		/* 2 NS offload and NDP Info*/
8937 		if (pwrctl->wowlan_ns_offload_en == _TRUE) {
8938 			rsvd_page_loc->LocNbrAdv = *page_num;
8939 			RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
8940 			rtw_hal_construct_na_message(adapter,
8941 						     &pframe[index], &ns_len);
8942 			rtw_hal_fill_fake_txdesc(adapter,
8943 						 &pframe[index - tx_desc],
8944 						 ns_len, _FALSE,
8945 						 _FALSE, _TRUE);
8946 			CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
8947 						      page_size);
8948 			*page_num += CurtPktPageNum;
8949 			index += (CurtPktPageNum * page_size);
8950 			RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);
8951 
8952 			rsvd_page_loc->LocNDPInfo = *page_num;
8953 			RTW_INFO("LocNDPInfo: %d\n",
8954 				 rsvd_page_loc->LocNDPInfo);
8955 
8956 			rtw_hal_construct_ndp_info(adapter,
8957 						   &pframe[index - tx_desc],
8958 						   &ns_len);
8959 			CurtPktPageNum =
8960 				(u8)PageNum(tx_desc + ns_len, page_size);
8961 			*page_num += CurtPktPageNum;
8962 			index += (CurtPktPageNum * page_size);
8963 			RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);
8964 
8965 		}
8966 #endif /*CONFIG_IPV6*/
8967 		/* 3 Remote Control Info. * 1 page */
8968 		rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
8969 		RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
8970 		rtw_hal_construct_remote_control_info(adapter,
8971 						      &pframe[index - tx_desc],
8972 						      &rc_len);
8973 		CurtPktPageNum = (u8)PageNum(rc_len, page_size);
8974 		*page_num += CurtPktPageNum;
8975 		*total_pkt_len = index + rc_len;
8976 		RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
8977 #ifdef CONFIG_GTK_OL
8978 		index += (CurtPktPageNum * page_size);
8979 
8980 		/* if the ap staion info. exists, get the kek, kck from staion info. */
8981 		psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
8982 		if (psta == NULL) {
8983 			_rtw_memset(kek, 0, RTW_KEK_LEN);
8984 			_rtw_memset(kck, 0, RTW_KCK_LEN);
8985 			RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
8986 				 __func__);
8987 		} else {
8988 			_rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
8989 			_rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
8990 		}
8991 
8992 		/* 3 KEK, KCK */
8993 		rsvd_page_loc->LocGTKInfo = *page_num;
8994 		RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
8995 
8996 		if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
8997 			struct security_priv *psecpriv = NULL;
8998 
8999 			psecpriv = &adapter->securitypriv;
9000 			_rtw_memcpy(pframe + index - tx_desc,
9001 				    &psecpriv->dot11PrivacyAlgrthm, 1);
9002 			_rtw_memcpy(pframe + index - tx_desc + 1,
9003 				    &psecpriv->dot118021XGrpPrivacy, 1);
9004 			_rtw_memcpy(pframe + index - tx_desc + 2,
9005 				    kck, RTW_KCK_LEN);
9006 			_rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
9007 				    kek, RTW_KEK_LEN);
9008 			CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
9009 		} else {
9010 
9011 			_rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
9012 			_rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
9013 				    kek, RTW_KEK_LEN);
9014 			GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
9015 
9016 			if (psta != NULL &&
9017 				psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
9018 				_rtw_memcpy(pframe + index - tx_desc + 56,
9019 					&psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
9020 				GTKLength += RTW_TKIP_MIC_LEN;
9021 			}
9022 			CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
9023 		}
9024 #if 0
9025 		{
9026 			int i;
9027 			printk("\ntoFW KCK: ");
9028 			for (i = 0; i < 16; i++)
9029 				printk(" %02x ", kck[i]);
9030 			printk("\ntoFW KEK: ");
9031 			for (i = 0; i < 16; i++)
9032 				printk(" %02x ", kek[i]);
9033 			printk("\n");
9034 		}
9035 
9036 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
9037 			 __FUNCTION__, &pframe[index - tx_desc],
9038 			 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
9039 #endif
9040 
9041 		*page_num += CurtPktPageNum;
9042 
9043 		index += (CurtPktPageNum * page_size);
9044 		RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);
9045 
9046 		/* 3 GTK Response */
9047 		rsvd_page_loc->LocGTKRsp = *page_num;
9048 		RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
9049 		rtw_hal_construct_GTKRsp(adapter, &pframe[index], &GTKLength);
9050 
9051 		rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
9052 					 GTKLength, _FALSE, _FALSE, _TRUE);
9053 #if 0
9054 		{
9055 			int gj;
9056 			printk("123GTK pkt=>\n");
9057 			for (gj = 0; gj < GTKLength + tx_desc; gj++) {
9058 				printk(" %02x ", pframe[index - tx_desc + gj]);
9059 				if ((gj + 1) % 16 == 0)
9060 					printk("\n");
9061 			}
9062 			printk(" <=end\n");
9063 		}
9064 
9065 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
9066 			 __FUNCTION__, &pframe[index - tx_desc],
9067 			 (tx_desc + GTKLength));
9068 #endif
9069 
9070 		CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
9071 
9072 		*page_num += CurtPktPageNum;
9073 
9074 		index += (CurtPktPageNum * page_size);
9075 		RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);
9076 
9077 		/* below page is empty for GTK extension memory */
9078 		/* 3(11) GTK EXT MEM */
9079 		rsvd_page_loc->LocGTKEXTMEM = *page_num;
9080 		RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
9081 		CurtPktPageNum = 2;
9082 
9083 		if (page_size >= 256)
9084 			CurtPktPageNum = 1;
9085 
9086 		*page_num += CurtPktPageNum;
9087 		/* extension memory for FW */
9088 		*total_pkt_len = index + (page_size * CurtPktPageNum);
9089 		RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);
9090 #endif /* CONFIG_GTK_OL */
9091 
9092 		index += (CurtPktPageNum * page_size);
9093 
9094 		/*Reserve 1 page for AOAC report*/
9095 		rsvd_page_loc->LocAOACReport = *page_num;
9096 		RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
9097 		*page_num += 1;
9098 		*total_pkt_len = index + (page_size * 1);
9099 		RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);
9100 	} else {
9101 #ifdef CONFIG_PNO_SUPPORT
9102 		if (pwrctl->wowlan_in_resume == _FALSE &&
9103 		    pwrctl->pno_inited == _TRUE) {
9104 
9105 			/* Broadcast Probe Request */
9106 			rsvd_page_loc->LocProbePacket = *page_num;
9107 
9108 			RTW_INFO("loc_probe_req: %d\n",
9109 				 rsvd_page_loc->LocProbePacket);
9110 
9111 			rtw_hal_construct_ProbeReq(
9112 				adapter,
9113 				&pframe[index],
9114 				&ProbeReqLength,
9115 				NULL);
9116 
9117 			rtw_hal_fill_fake_txdesc(adapter,
9118 						 &pframe[index - tx_desc],
9119 				 ProbeReqLength, _FALSE, _FALSE, _FALSE);
9120 
9121 			CurtPktPageNum =
9122 				(u8)PageNum(tx_desc + ProbeReqLength, page_size);
9123 
9124 			*page_num += CurtPktPageNum;
9125 
9126 			index += (CurtPktPageNum * page_size);
9127 			RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9128 
9129 			/* Hidden SSID Probe Request */
9130 			ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
9131 
9132 			for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
9133 				pwrctl->pnlo_info->loc_probe_req[pno_index] =
9134 					*page_num;
9135 
9136 				rtw_hal_construct_ProbeReq(
9137 					adapter,
9138 					&pframe[index],
9139 					&ProbeReqLength,
9140 					&pwrctl->pno_ssid_list->node[pno_index]);
9141 
9142 				rtw_hal_fill_fake_txdesc(adapter,
9143 						 &pframe[index - tx_desc],
9144 					ProbeReqLength, _FALSE, _FALSE, _FALSE);
9145 
9146 				CurtPktPageNum =
9147 					(u8)PageNum(tx_desc + ProbeReqLength, page_size);
9148 
9149 				*page_num += CurtPktPageNum;
9150 
9151 				index += (CurtPktPageNum * page_size);
9152 				RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9153 			}
9154 
9155 			/* PNO INFO Page */
9156 			rsvd_page_loc->LocPNOInfo = *page_num;
9157 			RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
9158 			rtw_hal_construct_PNO_info(adapter,
9159 						   &pframe[index - tx_desc],
9160 						   &PNOLength);
9161 
9162 			CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
9163 			*page_num += CurtPktPageNum;
9164 			index += (CurtPktPageNum * page_size);
9165 			RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);
9166 
9167 			/* Scan Info Page */
9168 			rsvd_page_loc->LocScanInfo = *page_num;
9169 			RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
9170 			rtw_hal_construct_scan_info(adapter,
9171 						    &pframe[index - tx_desc],
9172 						    &ScanInfoLength);
9173 
9174 			CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
9175 			*page_num += CurtPktPageNum;
9176 			*total_pkt_len = index + ScanInfoLength;
9177 			index += (CurtPktPageNum * page_size);
9178 			RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);
9179 		}
9180 #endif /* CONFIG_PNO_SUPPORT */
9181 	}
9182 }
9183 
rtw_hal_gate_bb(_adapter * adapter,bool stop)9184 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
9185 {
9186 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9187 	u8 i = 0, val8 = 0, empty = _FAIL;
9188 
9189 	if (stop) {
9190 		/* checking TX queue status */
9191 		for (i = 0 ; i < 5 ; i++) {
9192 			rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
9193 			if (empty) {
9194 				break;
9195 			} else {
9196 				RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
9197 					 __func__, i);
9198 				rtw_mdelay_os(10);
9199 			}
9200 		}
9201 
9202 		if (val8 == 5)
9203 			RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
9204 
9205 		/* Pause TX*/
9206 		pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
9207 		rtw_write8(adapter, REG_TXPAUSE, 0xff);
9208 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9209 		val8 &= ~BIT(0);
9210 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9211 		RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
9212 			 __func__,
9213 			 rtw_read8(adapter, REG_SYS_FUNC_EN),
9214 			 pwrpriv->wowlan_txpause_status);
9215 	} else {
9216 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9217 		val8 |= BIT(0);
9218 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9219 		RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
9220 			 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
9221 			 pwrpriv->wowlan_txpause_status);
9222 		/* release TX*/
9223 		rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
9224 	}
9225 }
9226 
rtw_hal_wow_pattern_generate(_adapter * adapter,u8 idx,struct rtl_wow_pattern * pwow_pattern)9227 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
9228 {
9229 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9230 	 u8 *pattern;
9231 	 u8 len = 0;
9232 	 u8 *mask;
9233 
9234 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
9235 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9236 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9237 	u8 multicast_addr1[2] = {0x33, 0x33};
9238 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9239 	u8 mask_len = 0;
9240 	u8 mac_addr[ETH_ALEN] = {0};
9241 	u16 count = 0;
9242 	int i;
9243 
9244 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9245 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9246 			 __func__, MAX_WKFM_CAM_NUM);
9247 		return _FAIL;
9248 	}
9249 
9250 	pattern = pwrctl->patterns[idx].content;
9251 	len = pwrctl->patterns[idx].len;
9252 	mask = pwrctl->patterns[idx].mask;
9253 
9254 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9255 	_rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
9256 
9257 	mask_len = DIV_ROUND_UP(len, 8);
9258 
9259 	/* 1. setup A1 table */
9260 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9261 		pwow_pattern->type = PATTERN_BROADCAST;
9262 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
9263 		pwow_pattern->type = PATTERN_MULTICAST;
9264 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
9265 		pwow_pattern->type = PATTERN_MULTICAST;
9266 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9267 		pwow_pattern->type = PATTERN_UNICAST;
9268 	else
9269 		pwow_pattern->type = PATTERN_INVALID;
9270 
9271 	/* translate mask from os to mask for hw */
9272 
9273 	/******************************************************************************
9274 	 * pattern from OS uses 'ethenet frame', like this:
9275 
9276 		|    6   |    6   |   2  |     20    |  Variable  |  4  |
9277 		|--------+--------+------+-----------+------------+-----|
9278 		|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
9279 		|   DA   |   SA   | Type |
9280 
9281 	 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9282 
9283 		|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
9284 		|-------------------+--------+------+-----------+------------+-----|
9285 		| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
9286 				    | Others | Tpye |
9287 
9288 	 * Therefore, we need translate mask_from_OS to mask_to_hw.
9289 	 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9290 	 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9291 	 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9292 	 ******************************************************************************/
9293 	/* Shift 6 bits */
9294 	for (i = 0; i < mask_len - 1; i++) {
9295 		mask_hw[i] = mask[i] >> 6;
9296 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9297 	}
9298 
9299 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
9300 	/* Set bit 0-5 to zero */
9301 	mask_hw[0] &= 0xC0;
9302 
9303 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9304 		pwow_pattern->mask[i] = mask_hw[i * 4];
9305 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
9306 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
9307 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
9308 	}
9309 
9310 	/* To get the wake up pattern from the mask.
9311 	 * We do not count first 12 bits which means
9312 	 * DA[6] and SA[6] in the pattern to match HW design. */
9313 	count = 0;
9314 	for (i = 12; i < len; i++) {
9315 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
9316 			content[count] = pattern[i];
9317 			count++;
9318 		}
9319 	}
9320 
9321 	pwow_pattern->crc = rtw_calc_crc(content, count);
9322 
9323 	if (pwow_pattern->crc != 0) {
9324 		if (pwow_pattern->type == PATTERN_INVALID)
9325 			pwow_pattern->type = PATTERN_VALID;
9326 	}
9327 
9328 	return _SUCCESS;
9329 }
9330 
rtw_dump_wow_pattern(void * sel,struct rtl_wow_pattern * pwow_pattern,u8 idx)9331 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
9332 {
9333 	int j;
9334 
9335 	RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
9336 	RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
9337 	RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
9338 	for (j = 0; j < 4; j++)
9339 		RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
9340 }
9341 /*bit definition of pattern match format*/
9342 #define WOW_VALID_BIT	BIT31
9343 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
9344 #define WOW_BC_BIT		BIT26
9345 #define WOW_MC_BIT		BIT25
9346 #define WOW_UC_BIT		BIT24
9347 #else
9348 #define WOW_BC_BIT		BIT18
9349 #define WOW_UC_BIT		BIT17
9350 #define WOW_MC_BIT		BIT16
9351 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
9352 
9353 #ifndef CONFIG_WOW_PATTERN_HW_CAM
9354 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_hal_reset_mac_rx(_adapter * adapter)9355 static void rtw_hal_reset_mac_rx(_adapter *adapter)
9356 {
9357 	u8 val8 = 0;
9358 	/* Set REG_CR bit1, bit3, bit7 to 0*/
9359 	val8 = rtw_read8(adapter, REG_CR);
9360 	val8 &= 0x75;
9361 	rtw_write8(adapter, REG_CR, val8);
9362 	val8 = rtw_read8(adapter, REG_CR);
9363 	/* Set REG_CR bit1, bit3, bit7 to 1*/
9364 	val8 |= 0x8a;
9365 	rtw_write8(adapter, REG_CR, val8);
9366 	RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
9367 }
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)9368 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
9369 {
9370 	u8 val8 = 0;
9371 	u16 rxff_bndy = 0;
9372 	u32 rx_dma_buff_sz = 0;
9373 
9374 	val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
9375 	if (val8 != 0)
9376 		RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
9377 			 __func__, (REG_FIFOPAGE + 3));
9378 
9379 	rtw_hal_reset_mac_rx(adapter);
9380 
9381 	if (wow_mode) {
9382 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9383 				    (u8 *)&rx_dma_buff_sz);
9384 		rxff_bndy = rx_dma_buff_sz - 1;
9385 
9386 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9387 		RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
9388 			 REG_TRXFF_BNDY + 2,
9389 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9390 	} else {
9391 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
9392 				    (u8 *)&rx_dma_buff_sz);
9393 		rxff_bndy = rx_dma_buff_sz - 1;
9394 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9395 		RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
9396 			 REG_TRXFF_BNDY + 2,
9397 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9398 	}
9399 }
9400 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO*/
9401 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9402 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9403 {
9404 	u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9405 	u16 offset, rx_buf_ptr = 0;
9406 	u16 cam_start_offset = 0;
9407 	u16 ctrl_l = 0, ctrl_h = 0;
9408 	u8 count = 0, tmp = 0;
9409 	int i = 0;
9410 	bool res = _TRUE;
9411 
9412 	if (idx > MAX_WKFM_CAM_NUM) {
9413 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9414 			 __func__);
9415 		return _FALSE;
9416 	}
9417 
9418 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9419 			    (u8 *)&rx_dma_buff_sz);
9420 
9421 	if (rx_dma_buff_sz == 0) {
9422 		RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9423 		return _FALSE;
9424 	}
9425 
9426 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9427 
9428 	if (page_sz == 0) {
9429 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9430 		return _FALSE;
9431 	}
9432 
9433 	offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9434 	cam_start_offset = offset * page_sz;
9435 
9436 	ctrl_l = 0x0;
9437 	ctrl_h = 0x0;
9438 
9439 	/* Enable RX packet buffer access */
9440 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9441 
9442 	/* Read the WKFM CAM */
9443 	for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9444 		/*
9445 		 * Set Rx packet buffer offset.
9446 		 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9447 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9448 		 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9449 		 * * Index: The index of the wake up frame mask
9450 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9451 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9452 		 */
9453 		rx_buf_ptr =
9454 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9455 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9456 
9457 		rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9458 		data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9459 		data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9460 
9461 		RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9462 
9463 		count = 0;
9464 
9465 		do {
9466 			tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9467 			rtw_udelay_os(2);
9468 			count++;
9469 		} while (!tmp && count < 100);
9470 
9471 		if (count >= 100) {
9472 			RTW_INFO("%s count:%d\n", __func__, count);
9473 			res = _FALSE;
9474 		}
9475 	}
9476 
9477 	/* Disable RX packet buffer access */
9478 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9479 		   DISABLE_TRXPKT_BUF_ACCESS);
9480 	return res;
9481 }
9482 
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9483 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9484 			     struct  rtl_wow_pattern *context)
9485 {
9486 	u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
9487 	u16 offset, rx_buf_ptr = 0;
9488 	u16 cam_start_offset = 0;
9489 	u16 ctrl_l = 0, ctrl_h = 0;
9490 	u8 count = 0, tmp = 0;
9491 	int res = 0, i = 0;
9492 
9493 	if (idx > MAX_WKFM_CAM_NUM) {
9494 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9495 			 __func__);
9496 		return _FALSE;
9497 	}
9498 
9499 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9500 			    (u8 *)&rx_dma_buff_sz);
9501 
9502 	if (rx_dma_buff_sz == 0) {
9503 		RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9504 		return _FALSE;
9505 	}
9506 
9507 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9508 
9509 	if (page_sz == 0) {
9510 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9511 		return _FALSE;
9512 	}
9513 
9514 	offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9515 
9516 	cam_start_offset = offset * page_sz;
9517 
9518 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
9519 		ctrl_l = 0x0001;
9520 		ctrl_h = 0x0001;
9521 	} else {
9522 		ctrl_l = 0x0f01;
9523 		ctrl_h = 0xf001;
9524 	}
9525 
9526 	/* Enable RX packet buffer access */
9527 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9528 
9529 	/* Write the WKFM CAM */
9530 	for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
9531 		/*
9532 		 * Set Rx packet buffer offset.
9533 		 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9534 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9535 		 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9536 		 * * Index: The index of the wake up frame mask
9537 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9538 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9539 		 */
9540 		rx_buf_ptr =
9541 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
9542 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9543 
9544 		if (i == 0) {
9545 			if (context->type == PATTERN_VALID)
9546 				data = WOW_VALID_BIT;
9547 			else if (context->type == PATTERN_BROADCAST)
9548 				data = WOW_VALID_BIT | WOW_BC_BIT;
9549 			else if (context->type == PATTERN_MULTICAST)
9550 				data = WOW_VALID_BIT | WOW_MC_BIT;
9551 			else if (context->type == PATTERN_UNICAST)
9552 				data = WOW_VALID_BIT | WOW_UC_BIT;
9553 
9554 			if (context->crc != 0)
9555 				data |= context->crc;
9556 
9557 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9558 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9559 		} else if (i == 1) {
9560 			data = 0;
9561 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9562 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9563 		} else if (i == 2 || i == 4) {
9564 			data = context->mask[i - 2];
9565 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9566 			/* write to RX packet buffer*/
9567 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9568 		} else if (i == 3 || i == 5) {
9569 			data = context->mask[i - 2];
9570 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9571 			/* write to RX packet buffer*/
9572 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9573 		}
9574 
9575 		count = 0;
9576 		do {
9577 			tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9578 			rtw_udelay_os(2);
9579 			count++;
9580 		} while (tmp && count < 100);
9581 
9582 		if (count >= 100)
9583 			res = _FALSE;
9584 		else
9585 			res = _TRUE;
9586 	}
9587 
9588 	/* Disable RX packet buffer access */
9589 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9590 		   DISABLE_TRXPKT_BUF_ACCESS);
9591 
9592 	return res;
9593 }
9594 #else /* CONFIG_WOW_PATTERN_IN_TXFIFO */
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9595 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9596 {
9597 	u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9598 	u16 tx_page_start, tx_buf_ptr = 0;
9599 	u16 cam_start_offset = 0;
9600 	u16 ctrl_l = 0, ctrl_h = 0;
9601 	u8 count = 0, tmp = 0, last_entry = 0;
9602 	int i = 0;
9603 	bool res = _TRUE;
9604 
9605 	if (idx > MAX_WKFM_CAM_NUM) {
9606 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9607 			 __func__);
9608 		return _FALSE;
9609 	}
9610 
9611 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9612 	if (page_sz == 0) {
9613 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9614 		return _FALSE;
9615 	}
9616 
9617 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9618 	if (last_entry == 0) {
9619 		RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9620 		return _FALSE;
9621 	}
9622 
9623 	/* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9624 	tx_page_start = last_entry - 1;
9625 	cam_start_offset = tx_page_start * page_sz / 8;
9626 	ctrl_l = 0x0;
9627 	ctrl_h = 0x0;
9628 
9629 	/* Enable TX packet buffer access */
9630 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9631 
9632 	/* Read the WKFM CAM */
9633 	for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9634 		/*
9635 		 * Set Tx packet buffer offset.
9636 		 * TxBufer pointer increases 1, we can access 8 bytes in Tx packet buffer.
9637 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9638 		 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9639 		 * * Index: The index of the wake up frame mask
9640 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9641 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9642 		 */
9643 		tx_buf_ptr =
9644 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9645 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, tx_buf_ptr);
9646 		rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9647 		data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9648 		data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9649 
9650 		RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9651 
9652 		count = 0;
9653 
9654 		do {
9655 			tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9656 			rtw_udelay_os(2);
9657 			count++;
9658 		} while (!tmp && count < 100);
9659 
9660 		if (count >= 100) {
9661 			RTW_INFO("%s count:%d\n", __func__, count);
9662 			res = _FALSE;
9663 		}
9664 	}
9665 
9666 	/* Disable RX packet buffer access */
9667 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9668 		   DISABLE_TRXPKT_BUF_ACCESS);
9669 	return res;
9670 }
9671 
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9672 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9673 			     struct  rtl_wow_pattern *context)
9674 {
9675 	u32 tx_page_start = 0, page_sz = 0;
9676 	u16 tx_buf_ptr = 0;
9677 	u16 cam_start_offset = 0;
9678 	u32 data_l = 0, data_h = 0;
9679 	u8 count = 0, tmp = 0, last_entry = 0;
9680 	int res = 0, i = 0;
9681 
9682 	if (idx > MAX_WKFM_CAM_NUM) {
9683 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9684 			 __func__);
9685 		return _FALSE;
9686 	}
9687 
9688 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9689 	if (page_sz == 0) {
9690 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9691 		return _FALSE;
9692 	}
9693 
9694 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9695 	if (last_entry == 0) {
9696 		RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9697 		return _FALSE;
9698 	}
9699 
9700 	/* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9701 	tx_page_start = last_entry - 1;
9702 	cam_start_offset = tx_page_start * page_sz / 8;
9703 
9704 	/* Write the PATTERN location to BIT_TXBUF_WKCAM_OFFSET */
9705 	rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET, cam_start_offset & 0xFF);
9706 	rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET + 1, (cam_start_offset >> 8) & 0xFF);
9707 	/* Enable TX packet buffer access */
9708 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9709 
9710 	/* Write the WKFM CAM */
9711 	for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
9712 		/*
9713 		 * Set Tx packet buffer offset.
9714 		 * TxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9715 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9716 		 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9717 		 * * Index: The index of the wake up frame mask
9718 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9719 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9720 		 */
9721 		tx_buf_ptr = cam_start_offset + ((idx * WKFMCAM_SIZE + i * 8) >> 3);
9722 
9723 		if (i == 0) {
9724 			if (context->type == PATTERN_VALID)
9725 				data_l = WOW_VALID_BIT;
9726 			else if (context->type == PATTERN_BROADCAST)
9727 				data_l = WOW_VALID_BIT | WOW_BC_BIT;
9728 			else if (context->type == PATTERN_MULTICAST)
9729 				data_l = WOW_VALID_BIT | WOW_MC_BIT;
9730 			else if (context->type == PATTERN_UNICAST)
9731 				data_l = WOW_VALID_BIT | WOW_UC_BIT;
9732 
9733 			if (context->crc != 0)
9734 				data_l |= context->crc;
9735 
9736 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9737 		} else {
9738 			data_l = context->mask[i * 2 - 2];
9739 			data_h = context->mask[i * 2 - 1];
9740 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9741 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data_h);
9742 		}
9743 
9744 		rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0x1FFF) | BIT23 | (0xff <<24));
9745 		count = 0;
9746 		do {
9747 			tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9748 			rtw_udelay_os(2);
9749 			count++;
9750 		} while (tmp && count < 100);
9751 
9752 		if (count >= 100) {
9753 			res = _FALSE;
9754 			RTW_INFO("%s write failed\n", __func__);
9755 		} else {
9756 			res = _TRUE;
9757 			RTW_INFO("%s write OK\n", __func__);
9758 		}
9759 	}
9760 
9761 	/* Disable TX packet buffer access */
9762 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
9763 	return res;
9764 }
9765 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
9766 
rtw_clean_pattern(_adapter * adapter)9767 void rtw_clean_pattern(_adapter *adapter)
9768 {
9769 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9770 	struct rtl_wow_pattern zero_pattern;
9771 	int i = 0;
9772 
9773 	_rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
9774 
9775 	zero_pattern.type = PATTERN_INVALID;
9776 
9777 	for (i = 0; i < MAX_WKFM_CAM_NUM; i++)
9778 		rtw_write_to_frame_mask(adapter, i, &zero_pattern);
9779 
9780 	rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
9781 }
9782 #if 0
9783 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
9784 			       u8 len, u8 *mask, u8 idx)
9785 {
9786 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9787 	struct mlme_ext_priv *pmlmeext = NULL;
9788 	struct mlme_ext_info *pmlmeinfo = NULL;
9789 	struct rtl_wow_pattern wow_pattern;
9790 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
9791 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9792 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9793 	u8 multicast_addr1[2] = {0x33, 0x33};
9794 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9795 	u8 res = _FALSE, index = 0, mask_len = 0;
9796 	u8 mac_addr[ETH_ALEN] = {0};
9797 	u16 count = 0;
9798 	int i, j;
9799 
9800 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9801 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9802 			 __func__, MAX_WKFM_CAM_NUM);
9803 		return _FALSE;
9804 	}
9805 
9806 	pmlmeext = &adapter->mlmeextpriv;
9807 	pmlmeinfo = &pmlmeext->mlmext_info;
9808 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9809 	_rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
9810 
9811 	mask_len = DIV_ROUND_UP(len, 8);
9812 
9813 	/* 1. setup A1 table */
9814 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9815 		wow_pattern.type = PATTERN_BROADCAST;
9816 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
9817 		wow_pattern.type = PATTERN_MULTICAST;
9818 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
9819 		wow_pattern.type = PATTERN_MULTICAST;
9820 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9821 		wow_pattern.type = PATTERN_UNICAST;
9822 	else
9823 		wow_pattern.type = PATTERN_INVALID;
9824 
9825 	/* translate mask from os to mask for hw */
9826 
9827 /******************************************************************************
9828  * pattern from OS uses 'ethenet frame', like this:
9829 
9830 	|    6   |    6   |   2  |     20    |  Variable  |  4  |
9831 	|--------+--------+------+-----------+------------+-----|
9832 	|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
9833 	|   DA   |   SA   | Type |
9834 
9835  * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9836 
9837 	|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
9838 	|-------------------+--------+------+-----------+------------+-----|
9839 	| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
9840 			    | Others | Tpye |
9841 
9842  * Therefore, we need translate mask_from_OS to mask_to_hw.
9843  * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9844  * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9845  * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9846  ******************************************************************************/
9847 	/* Shift 6 bits */
9848 	for (i = 0; i < mask_len - 1; i++) {
9849 		mask_hw[i] = mask[i] >> 6;
9850 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9851 	}
9852 
9853 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
9854 	/* Set bit 0-5 to zero */
9855 	mask_hw[0] &= 0xC0;
9856 
9857 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9858 		wow_pattern.mask[i] = mask_hw[i * 4];
9859 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
9860 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
9861 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
9862 	}
9863 
9864 	/* To get the wake up pattern from the mask.
9865 	 * We do not count first 12 bits which means
9866 	 * DA[6] and SA[6] in the pattern to match HW design. */
9867 	count = 0;
9868 	for (i = 12; i < len; i++) {
9869 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
9870 			content[count] = pattern[i];
9871 			count++;
9872 		}
9873 	}
9874 
9875 	wow_pattern.crc = rtw_calc_crc(content, count);
9876 
9877 	if (wow_pattern.crc != 0) {
9878 		if (wow_pattern.type == PATTERN_INVALID)
9879 			wow_pattern.type = PATTERN_VALID;
9880 	}
9881 
9882 	index = idx;
9883 
9884 	if (!pwrctl->bInSuspend)
9885 		index += 2;
9886 
9887 	/* write pattern */
9888 	res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
9889 
9890 	if (res == _FALSE)
9891 		RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
9892 			 __func__, idx);
9893 
9894 	return res;
9895 }
9896 #endif
9897 
rtw_fill_pattern(_adapter * adapter)9898 void rtw_fill_pattern(_adapter *adapter)
9899 {
9900 	int i = 0, total = 0, index;
9901 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9902 	struct rtl_wow_pattern wow_pattern;
9903 
9904 	total = pwrpriv->wowlan_pattern_idx;
9905 
9906 	if (total > MAX_WKFM_CAM_NUM)
9907 		total = MAX_WKFM_CAM_NUM;
9908 
9909 	for (i = 0 ; i < total ; i++) {
9910 		if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
9911 
9912 			index = i;
9913 			if (!pwrpriv->bInSuspend)
9914 				index += 2;
9915 			rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
9916 			if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
9917 				RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
9918 		}
9919 
9920 	}
9921 	rtw_write8(adapter, REG_WKFMCAM_NUM, total);
9922 
9923 }
9924 
9925 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
9926 
9927 #define WOW_CAM_ACCESS_TIMEOUT_MS	200
_rtw_wow_pattern_read_cam(_adapter * adapter,u8 addr)9928 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
9929 {
9930 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9931 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
9932 
9933 	u32 rdata = 0;
9934 	u32 cnt = 0;
9935 	systime start = 0;
9936 	u8 timeout = 0;
9937 	u8 rst = _FALSE;
9938 
9939 	_enter_critical_mutex(mutex, NULL);
9940 
9941 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
9942 
9943 	start = rtw_get_current_time();
9944 	while (1) {
9945 		if (rtw_is_surprise_removed(adapter))
9946 			break;
9947 
9948 		cnt++;
9949 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
9950 			rst = _SUCCESS;
9951 			break;
9952 		}
9953 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
9954 			timeout = 1;
9955 			break;
9956 		}
9957 	}
9958 
9959 	rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
9960 
9961 	_exit_critical_mutex(mutex, NULL);
9962 
9963 	/*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
9964 
9965 	if (timeout)
9966 		RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
9967 
9968 	return rdata;
9969 }
rtw_wow_pattern_read_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)9970 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct  rtl_wow_pattern *context)
9971 {
9972 	int i;
9973 	u32 rdata;
9974 
9975 	_rtw_memset(context, 0, sizeof(struct  rtl_wow_pattern));
9976 
9977 	for (i = 4; i >= 0; i--) {
9978 		rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
9979 
9980 		switch (i) {
9981 		case 4:
9982 			if (rdata & WOW_BC_BIT)
9983 				context->type = PATTERN_BROADCAST;
9984 			else if (rdata & WOW_MC_BIT)
9985 				context->type = PATTERN_MULTICAST;
9986 			else if (rdata & WOW_UC_BIT)
9987 				context->type = PATTERN_UNICAST;
9988 			else
9989 				context->type = PATTERN_INVALID;
9990 
9991 			context->crc = rdata & 0xFFFF;
9992 			break;
9993 		default:
9994 			_rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
9995 			break;
9996 		}
9997 	}
9998 }
9999 
_rtw_wow_pattern_write_cam(_adapter * adapter,u8 addr,u32 wdata)10000 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
10001 {
10002 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10003 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10004 	u32 cnt = 0;
10005 	systime start = 0, end = 0;
10006 	u8 timeout = 0;
10007 
10008 	/*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
10009 	_enter_critical_mutex(mutex, NULL);
10010 
10011 	rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
10012 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
10013 
10014 	start = rtw_get_current_time();
10015 	while (1) {
10016 		if (rtw_is_surprise_removed(adapter))
10017 			break;
10018 
10019 		cnt++;
10020 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
10021 			break;
10022 
10023 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10024 			timeout = 1;
10025 			break;
10026 		}
10027 	}
10028 	end = rtw_get_current_time();
10029 
10030 	_exit_critical_mutex(mutex, NULL);
10031 
10032 	if (timeout) {
10033 		RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
10034 			, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
10035 	}
10036 }
10037 
rtw_wow_pattern_write_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10038 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct  rtl_wow_pattern *context)
10039 {
10040 	int j;
10041 	u8 addr;
10042 	u32 wdata = 0;
10043 
10044 	for (j = 4; j >= 0; j--) {
10045 		switch (j) {
10046 		case 4:
10047 			wdata = context->crc;
10048 
10049 			if (PATTERN_BROADCAST == context->type)
10050 				wdata |= WOW_BC_BIT;
10051 			if (PATTERN_MULTICAST == context->type)
10052 				wdata |= WOW_MC_BIT;
10053 			if (PATTERN_UNICAST == context->type)
10054 				wdata |= WOW_UC_BIT;
10055 			if (PATTERN_INVALID != context->type)
10056 				wdata |= WOW_VALID_BIT;
10057 			break;
10058 		default:
10059 			wdata = context->mask[j];
10060 			break;
10061 		}
10062 
10063 		addr = (id << 3) + j;
10064 
10065 		_rtw_wow_pattern_write_cam(adapter, addr, wdata);
10066 	}
10067 }
10068 
_rtw_wow_pattern_clean_cam(_adapter * adapter)10069 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
10070 {
10071 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10072 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10073 	u32 cnt = 0;
10074 	systime start = 0;
10075 	u8 timeout = 0;
10076 	u8 rst = _FAIL;
10077 
10078 	_enter_critical_mutex(mutex, NULL);
10079 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
10080 
10081 	start = rtw_get_current_time();
10082 	while (1) {
10083 		if (rtw_is_surprise_removed(adapter))
10084 			break;
10085 
10086 		cnt++;
10087 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10088 			rst = _SUCCESS;
10089 			break;
10090 		}
10091 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10092 			timeout = 1;
10093 			break;
10094 		}
10095 	}
10096 	_exit_critical_mutex(mutex, NULL);
10097 
10098 	if (timeout)
10099 		RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
10100 
10101 	return rst;
10102 }
10103 
rtw_clean_pattern(_adapter * adapter)10104 void rtw_clean_pattern(_adapter *adapter)
10105 {
10106 	if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
10107 		RTW_ERR("rtw_clean_pattern failed\n");
10108 }
rtw_fill_pattern(_adapter * adapter)10109 void rtw_fill_pattern(_adapter *adapter)
10110 {
10111 	int i = 0, total = 0;
10112 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10113 	struct rtl_wow_pattern wow_pattern;
10114 
10115 	total = pwrpriv->wowlan_pattern_idx;
10116 
10117 	if (total > MAX_WKFM_CAM_NUM)
10118 		total = MAX_WKFM_CAM_NUM;
10119 
10120 	for (i = 0 ; i < total ; i++) {
10121 		if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
10122 			rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10123 			rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
10124 		}
10125 	}
10126 }
10127 
10128 #endif
rtw_wow_pattern_cam_dump(_adapter * adapter)10129 void rtw_wow_pattern_cam_dump(_adapter *adapter)
10130 {
10131 
10132 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10133 	int i;
10134 
10135 	for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10136 		RTW_INFO("=======[%d]=======\n", i);
10137 		rtw_read_from_frame_mask(adapter, i);
10138 	}
10139 #else
10140 	struct  rtl_wow_pattern context;
10141 	int i;
10142 
10143 	for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10144 		rtw_wow_pattern_read_cam_ent(adapter, i, &context);
10145 		rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
10146 	}
10147 
10148 #endif
10149 }
10150 
10151 
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)10152 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
10153 {
10154 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10155 
10156 	switch (mode) {
10157 	case 0:
10158 		rtw_clean_pattern(adapter);
10159 		RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
10160 		break;
10161 	case 1:
10162 		rtw_set_default_pattern(adapter);
10163 		rtw_fill_pattern(adapter);
10164 		RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
10165 		break;
10166 	case 2:
10167 		rtw_clean_pattern(adapter);
10168 		rtw_wow_pattern_sw_reset(adapter);
10169 		RTW_INFO("%s: clean patterns\n", __func__);
10170 		break;
10171 	default:
10172 		RTW_INFO("%s: unknown mode\n", __func__);
10173 		break;
10174 	}
10175 }
10176 
rtw_hal_wow_enable(_adapter * adapter)10177 static void rtw_hal_wow_enable(_adapter *adapter)
10178 {
10179 	struct registry_priv  *registry_par = &adapter->registrypriv;
10180 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10181 	struct security_priv *psecuritypriv = &adapter->securitypriv;
10182 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10183 	struct sta_info *psta = NULL;
10184 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
10185 	int res;
10186 	u16 media_status_rpt;
10187 	u8 no_wake = 0, i;
10188 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10189 	_adapter *iface;
10190 #ifdef CONFIG_GPIO_WAKEUP
10191 	u8 val8 = 0;
10192 #endif
10193 
10194 #ifdef CONFIG_LPS_PG
10195 	u8 lps_pg_hdl_id = 0;
10196 #endif
10197 
10198 
10199 
10200 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
10201 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
10202 		no_wake = 1;
10203 
10204 	RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));
10205 	rtw_hal_gate_bb(adapter, _TRUE);
10206 
10207 	for (i = 0; i < dvobj->iface_nums; i++) {
10208 		iface = dvobj->padapters[i];
10209 		/* Start Usb TxDMA */
10210 		if(iface) {
10211 			RTW_INFO(ADPT_FMT "enable TX\n", ADPT_ARG(iface));
10212 			RTW_ENABLE_FUNC(iface, DF_TX_BIT);
10213 		}
10214 	}
10215 
10216 #ifdef CONFIG_GTK_OL
10217 	if (psecuritypriv->binstallKCK_KEK == _TRUE)
10218 		rtw_hal_fw_sync_cam_id(adapter);
10219 #endif
10220 	if (IS_HARDWARE_TYPE_8723B(adapter))
10221 		rtw_hal_backup_rate(adapter);
10222 
10223 	rtw_hal_fw_dl(adapter, _TRUE);
10224 	if(no_wake)
10225 		media_status_rpt = RT_MEDIA_DISCONNECT;
10226 	else
10227 		media_status_rpt = RT_MEDIA_CONNECT;
10228 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10229 			  (u8 *)&media_status_rpt);
10230 
10231 	/* RX DMA stop */
10232 	#if defined(CONFIG_RTL8188E)
10233 	if (IS_HARDWARE_TYPE_8188E(adapter))
10234 		rtw_hal_disable_tx_report(adapter);
10235 	#endif
10236 
10237 	res = rtw_hal_pause_rx_dma(adapter);
10238 	if (res == _FAIL)
10239 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
10240 
10241 	#ifndef CONFIG_WOW_PATTERN_HW_CAM
10242 	/* Reconfig RX_FF Boundary */
10243 	#ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10244 	rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
10245 	#endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10246 	#endif
10247 
10248 	/* redownload wow pattern */
10249 	if(!no_wake)
10250 		rtw_hal_dl_pattern(adapter, 1);
10251 
10252 	if (!pwrctl->wowlan_pno_enable) {
10253 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10254 
10255 		if (psta != NULL) {
10256 			#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10257 			adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10258 			adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10259 			rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10260 			#endif
10261 			if(!no_wake)
10262 				rtw_sta_media_status_rpt(adapter, psta, 1);
10263 		}
10264 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10265 		else {
10266 			if(registry_par->suspend_type == FW_IPS_WRC) {
10267 				adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10268 				adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10269 				rtw_hal_set_default_port_id_cmd(adapter, 0);
10270 			}
10271 		}
10272 #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */
10273 	}
10274 
10275 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10276 	/* Enable CPWM2 only. */
10277 	res = rtw_hal_enable_cpwm2(adapter);
10278 	if (res == _FAIL)
10279 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
10280 #endif
10281 #ifdef CONFIG_GPIO_WAKEUP
10282 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10283 	rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10284 	rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10285 #else
10286 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10287 	if (pwrctl->is_high_active == 0)
10288 		rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10289 	else
10290 		rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10291 			GPIO_OUTPUT_LOW);
10292 #else
10293 	val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
10294 	rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, val8);
10295 	rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10296 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow suspend and %s_ACTIVE.\n",
10297 		 __func__, pwrctl->wowlan_gpio_index,
10298 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10299 		 pwrctl->is_high_active ? "HIGI" : "LOW");
10300 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10301 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10302 #endif /* CONFIG_GPIO_WAKEUP */
10303 	/* Set WOWLAN H2C command. */
10304 	RTW_PRINT("Set WOWLan cmd\n");
10305 	rtw_hal_set_fw_wow_related_cmd(adapter, 1);
10306 
10307 	res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
10308 
10309 	if (res == _FALSE)
10310 		RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
10311 
10312 	pwrctl->wowlan_wake_reason =
10313 		rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10314 
10315 	RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
10316 		  pwrctl->wowlan_wake_reason);
10317 #ifdef CONFIG_GTK_OL_DBG
10318 	dump_sec_cam(RTW_DBGDUMP, adapter);
10319 	dump_sec_cam_cache(RTW_DBGDUMP, adapter);
10320 #endif
10321 
10322 #ifdef CONFIG_LPS_PG
10323 	if (pwrctl->lps_level == LPS_PG) {
10324 		lps_pg_hdl_id = LPS_PG_INFO_CFG;
10325 		rtw_hal_set_hwreg(adapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
10326 	}
10327 #endif
10328 
10329 #ifdef CONFIG_USB_HCI
10330 	/* free adapter's resource */
10331 	rtw_mi_intf_stop(adapter);
10332 
10333 #endif
10334 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
10335 	/* Invoid SE0 reset signal during suspending*/
10336 	rtw_write8(adapter, REG_RSV_CTRL, 0x20);
10337 	if (IS_8188F(pHalData->version_id) == FALSE
10338 		&& IS_8188GTV(pHalData->version_id) == FALSE)
10339 		rtw_write8(adapter, REG_RSV_CTRL, 0x60);
10340 #endif
10341 
10342 	rtw_hal_gate_bb(adapter, _FALSE);
10343 }
10344 
10345 #define DBG_WAKEUP_REASON
10346 #ifdef DBG_WAKEUP_REASON
_dbg_wake_up_reason_string(_adapter * adapter,const char * srt_res)10347 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
10348 {
10349 	RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
10350 }
_dbg_rtw_wake_up_reason(_adapter * adapter,u8 reason)10351 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
10352 {
10353 	if (RX_PAIRWISEKEY == reason)
10354 		_dbg_wake_up_reason_string(adapter, "Rx pairwise key");
10355 	else if (RX_GTK == reason)
10356 		_dbg_wake_up_reason_string(adapter, "Rx GTK");
10357 	else if (RX_FOURWAY_HANDSHAKE == reason)
10358 		_dbg_wake_up_reason_string(adapter, "Rx four way handshake");
10359 	else if (RX_DISASSOC == reason)
10360 		_dbg_wake_up_reason_string(adapter, "Rx disassoc");
10361 	else if (RX_DEAUTH == reason)
10362 		_dbg_wake_up_reason_string(adapter, "Rx deauth");
10363 	else if (RX_ARP_REQUEST == reason)
10364 		_dbg_wake_up_reason_string(adapter, "Rx ARP request");
10365 	else if (FW_DECISION_DISCONNECT == reason)
10366 		_dbg_wake_up_reason_string(adapter, "FW detect disconnect");
10367 	else if (RX_MAGIC_PKT == reason)
10368 		_dbg_wake_up_reason_string(adapter, "Rx magic packet");
10369 	else if (RX_UNICAST_PKT == reason)
10370 		_dbg_wake_up_reason_string(adapter, "Rx unicast packet");
10371 	else if (RX_PATTERN_PKT == reason)
10372 		_dbg_wake_up_reason_string(adapter, "Rx pattern packet");
10373 	else if (RTD3_SSID_MATCH == reason)
10374 		_dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
10375 	else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
10376 		_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
10377 	else if (RX_REALWOW_V2_ACK_LOST == reason)
10378 		_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
10379 	else if (ENABLE_FAIL_DMA_IDLE == reason)
10380 		_dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
10381 	else if (ENABLE_FAIL_DMA_PAUSE == reason)
10382 		_dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
10383 	else if (AP_OFFLOAD_WAKEUP == reason)
10384 		_dbg_wake_up_reason_string(adapter, "AP offload wakeup");
10385 	else if (CLK_32K_UNLOCK == reason)
10386 		_dbg_wake_up_reason_string(adapter, "clk 32k unlock");
10387 	else if (RTIME_FAIL_DMA_IDLE == reason)
10388 		_dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
10389 	else if (CLK_32K_LOCK == reason)
10390 		_dbg_wake_up_reason_string(adapter, "clk 32k lock");
10391 	else
10392 		_dbg_wake_up_reason_string(adapter, "unknown reasoen");
10393 }
10394 #endif
10395 
rtw_hal_wow_disable(_adapter * adapter)10396 static void rtw_hal_wow_disable(_adapter *adapter)
10397 {
10398 	int i;
10399 	struct recv_reorder_ctrl *preorder_ctrl;
10400 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10401 	struct security_priv *psecuritypriv = &adapter->securitypriv;
10402 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10403 	struct sta_info *psta = NULL;
10404 	struct registry_priv  *registry_par = &adapter->registrypriv;
10405 	int res;
10406 	u16 media_status_rpt;
10407 
10408 	RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
10409 
10410 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
10411 		RTW_INFO("FW_IPS_DISABLE_BBRF resume\n");
10412 		return;
10413 	}
10414 
10415 	if (!pwrctl->wowlan_pno_enable) {
10416 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10417 		if (psta != NULL)
10418 			rtw_sta_media_status_rpt(adapter, psta, 0);
10419 		else
10420 			RTW_INFO("%s: psta is null\n", __func__);
10421 	}
10422 
10423 	if (0) {
10424 		RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
10425 		RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
10426 		RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
10427 		RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
10428 	}
10429 
10430 	pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10431 
10432 	RTW_PRINT("wakeup_reason: 0x%02x\n",
10433 		  pwrctl->wowlan_wake_reason);
10434 	#ifdef DBG_WAKEUP_REASON
10435 	_dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
10436 	#endif
10437 
10438 	rtw_hal_set_fw_wow_related_cmd(adapter, 0);
10439 
10440 	res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
10441 
10442 	#if defined(CONFIG_RTL8188E)
10443 	if (IS_HARDWARE_TYPE_8188E(adapter))
10444 		rtw_hal_enable_tx_report(adapter);
10445 	#endif
10446 
10447 	if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10448 		(pwrctl->wowlan_wake_reason != RX_DEAUTH) &&
10449 		(pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {
10450 		rtw_hal_get_aoac_rpt(adapter);
10451 		rtw_hal_update_sw_security_info(adapter);
10452 	}
10453 
10454 	if (res == _FALSE) {
10455 		RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
10456 		rtw_hal_force_enable_rxdma(adapter);
10457 	}
10458 
10459 	rtw_hal_gate_bb(adapter, _TRUE);
10460 
10461 	res = rtw_hal_pause_rx_dma(adapter);
10462 	if (res == _FAIL)
10463 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
10464 
10465 	/* clean HW pattern match */
10466 	rtw_hal_dl_pattern(adapter, 0);
10467 
10468 	#ifndef CONFIG_WOW_PATTERN_HW_CAM
10469 	/* config RXFF boundary to original */
10470 	#ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10471 	rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
10472 	#endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10473 	#endif
10474 	rtw_hal_release_rx_dma(adapter);
10475 
10476 	rtw_hal_fw_dl(adapter, _FALSE);
10477 
10478 #ifdef CONFIG_GPIO_WAKEUP
10479 
10480 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10481 	rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10482 #else
10483 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10484 	if (pwrctl->is_high_active == 0)
10485 		rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10486 	else
10487 		rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10488 			GPIO_OUTPUT_LOW);
10489 #else
10490 	rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index
10491 		, pwrctl->wowlan_gpio_output_state);
10492 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow resume and %s_ACTIVE.\n",
10493 		 __func__, pwrctl->wowlan_gpio_index,
10494 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10495 		 pwrctl->is_high_active ? "HIGI" : "LOW");
10496 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10497 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10498 #endif /* CONFIG_GPIO_WAKEUP */
10499 	if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
10500 	    (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
10501 	    (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10502 	    (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
10503 
10504 		media_status_rpt = RT_MEDIA_CONNECT;
10505 		rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10506 				  (u8 *)&media_status_rpt);
10507 
10508 		if (psta != NULL) {
10509 			#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10510 			adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10511 			adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10512 			rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10513 			#endif
10514 			rtw_sta_media_status_rpt(adapter, psta, 1);
10515 		}
10516 	}
10517 
10518 	if (psta != NULL) {
10519 		RTW_PRINT("rtw_set_bit RTW_RECV_REORDER_WOW\n");
10520 		for (i = 0; i < TID_NUM; i++) {
10521 			preorder_ctrl = &psta->recvreorder_ctrl[i];
10522 			rtw_set_bit(RTW_RECV_REORDER_WOW,
10523 				    &preorder_ctrl->rec_abba_rsp_ack);
10524 		}
10525 	}
10526 
10527 	rtw_hal_gate_bb(adapter, _FALSE);
10528 }
10529 #endif /*CONFIG_WOWLAN*/
10530 
10531 #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)10532 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
10533 	      u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
10534 				      RSVDPAGE_LOC *rsvd_page_loc)
10535 {
10536 	u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
10537 	u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
10538 	u8 CurtPktPageNum = 0;
10539 
10540 	/* P2P Beacon */
10541 	rsvd_page_loc->LocP2PBeacon = *page_num;
10542 	rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
10543 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10544 				 P2PBCNLength, _FALSE, _FALSE, _FALSE);
10545 
10546 #if 0
10547 	RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
10548 		__FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
10549 #endif
10550 
10551 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
10552 
10553 	*page_num += CurtPktPageNum;
10554 
10555 	index += (CurtPktPageNum * page_size);
10556 	RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);
10557 
10558 	/* P2P Probe rsp */
10559 	rsvd_page_loc->LocP2PProbeRsp = *page_num;
10560 	rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
10561 				      &P2PProbeRspLength);
10562 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10563 				 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
10564 
10565 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",  */
10566 	/*	__FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
10567 
10568 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
10569 
10570 	*page_num += CurtPktPageNum;
10571 
10572 	index += (CurtPktPageNum * page_size);
10573 	RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);
10574 
10575 	/* P2P nego rsp */
10576 	rsvd_page_loc->LocNegoRsp = *page_num;
10577 	rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
10578 				     &P2PNegoRspLength);
10579 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10580 				 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
10581 
10582 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
10583 	/*	__FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
10584 
10585 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
10586 
10587 	*page_num += CurtPktPageNum;
10588 
10589 	index += (CurtPktPageNum * page_size);
10590 	RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);
10591 
10592 	/* P2P invite rsp */
10593 	rsvd_page_loc->LocInviteRsp = *page_num;
10594 	rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
10595 				       &P2PInviteRspLength);
10596 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10597 				 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
10598 
10599 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
10600 	/* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
10601 
10602 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
10603 
10604 	*page_num += CurtPktPageNum;
10605 
10606 	index += (CurtPktPageNum * page_size);
10607 	RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);
10608 
10609 	/* P2P provision discovery rsp */
10610 	rsvd_page_loc->LocPDRsp = *page_num;
10611 	rtw_hal_construct_P2PProvisionDisRsp(adapter,
10612 					     &pframe[index], &P2PPDRspLength);
10613 
10614 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10615 				 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
10616 
10617 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
10618 	/*	__FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
10619 
10620 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
10621 
10622 	*page_num += CurtPktPageNum;
10623 
10624 	*total_pkt_len = index + P2PPDRspLength;
10625 	RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);
10626 
10627 	index += (CurtPktPageNum * page_size);
10628 
10629 
10630 }
10631 #endif /* CONFIG_P2P_WOWLAN */
10632 
10633 #ifdef CONFIG_LPS_PG
10634 #ifndef DBG_LPSPG_INFO_DUMP
10635 #define DBG_LPSPG_INFO_DUMP 1
10636 #endif
10637 
10638 #include "hal_halmac.h"
10639 
10640 #ifdef CONFIG_RTL8822C
rtw_lps_pg_set_dpk_info_rsvd_page(_adapter * adapter)10641 static int rtw_lps_pg_set_dpk_info_rsvd_page(_adapter *adapter)
10642 {
10643 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10644 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10645 	struct dm_struct *dm = adapter_to_phydm(adapter);
10646 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_dpk_info;
10647 	u8 *info = NULL;
10648 	u32 info_len;
10649 	int ret = _FAIL;
10650 
10651 	/* get length */
10652 	halrf_dpk_info_rsvd_page(dm, NULL, &info_len);
10653 	if (!info_len) {
10654 		RTW_ERR("get %s length fail\n", cache->name);
10655 		goto exit;
10656 	}
10657 
10658 	/* allocate buf */
10659 	info = rtw_zmalloc(info_len);
10660 	if (!info) {
10661 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10662 		goto exit;
10663 	}
10664 
10665 	/* get content */
10666 	halrf_dpk_info_rsvd_page(dm, info, NULL);
10667 
10668 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
10669 
10670 		#if (DBG_LPSPG_INFO_DUMP >= 1)
10671 		RTW_INFO_DUMP(cache->name, info, info_len);
10672 		#endif
10673 
10674 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10675 		ret = !ret ? _SUCCESS : _FAIL;
10676 		if (ret != _SUCCESS) {
10677 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10678 			goto free_mem;
10679 		}
10680 
10681 		#if (DBG_LPSPG_INFO_DUMP >= 2)
10682 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10683 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10684 		#endif
10685 	}
10686 
10687 free_mem:
10688 	rtw_mfree(info, info_len);
10689 
10690 exit:
10691 	return ret;
10692 }
10693 
rtw_lps_pg_set_iqk_info_rsvd_page(_adapter * adapter)10694 static int rtw_lps_pg_set_iqk_info_rsvd_page(_adapter *adapter)
10695 {
10696 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10697 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10698 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10699 	struct dm_struct *dm = adapter_to_phydm(adapter);
10700 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_iqk_info;
10701 	u8 *info = NULL;
10702 	u32 info_len = 0;
10703 	int ret = _FAIL;
10704 
10705 	if (hal_data->RegIQKFWOffload) {
10706 		rsvd_page_cache_free_data(cache);
10707 		ret = _SUCCESS;
10708 		goto exit;
10709 	}
10710 
10711 	/* get length */
10712 	halrf_iqk_info_rsvd_page(dm, NULL, &info_len);
10713 	if (!info_len) {
10714 		RTW_ERR("get %s length fail\n", cache->name);
10715 		goto exit;
10716 	}
10717 
10718 	/* allocate buf */
10719 	info = rtw_zmalloc(info_len);
10720 	if (!info) {
10721 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10722 		goto exit;
10723 	}
10724 
10725 	/* get content */
10726 	halrf_iqk_info_rsvd_page(dm, info, NULL);
10727 
10728 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
10729 
10730 		#if (DBG_LPSPG_INFO_DUMP >= 1)
10731 		RTW_INFO_DUMP(cache->name, info, info_len);
10732 		#endif
10733 
10734 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10735 		ret = !ret ? _SUCCESS : _FAIL;
10736 		if (ret != _SUCCESS) {
10737 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10738 			goto free_mem;
10739 		}
10740 
10741 		#if (DBG_LPSPG_INFO_DUMP >= 2)
10742 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10743 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10744 		#endif
10745 	}
10746 
10747 free_mem:
10748 	rtw_mfree(info, info_len);
10749 
10750 exit:
10751 	return ret;
10752 }
10753 #endif /* CONFIG_RTL8822C */
10754 
rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv * dvobj,_adapter * ld_sta_iface,u8 * buf,u32 * buf_size)10755 static void rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv *dvobj, _adapter *ld_sta_iface, u8 *buf, u32 *buf_size)
10756 {
10757 #define LPS_PG_INFO_RSVD_LEN	16
10758 
10759 	if (buf) {
10760 		_adapter *adapter = dvobj_get_primary_adapter(dvobj);
10761 		struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10762 		struct sta_info *psta;
10763 #ifdef CONFIG_MBSSID_CAM
10764 		u8 cam_id = INVALID_CAM_ID;
10765 #endif
10766 		u8 *psec_cam_id = buf + 8;
10767 		u8 sec_cam_num = 0;
10768 		u8 drv_rsvdpage_num = 0;
10769 
10770 		if (ld_sta_iface) {
10771 			psta = rtw_get_stainfo(&ld_sta_iface->stapriv, get_bssid(&ld_sta_iface->mlmepriv));
10772 			if (!psta) {
10773 				RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
10774 				rtw_warn_on(1);
10775 				goto size_chk;
10776 			}
10777 			/*Byte 0 - used macid*/
10778 			LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id);
10779 			RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
10780 		}
10781 
10782 #ifdef CONFIG_MBSSID_CAM
10783 		/*Byte 1 - used BSSID CAM entry*/
10784 		cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
10785 		if (cam_id != INVALID_CAM_ID)
10786 			LPSPG_RSVD_PAGE_SET_MBSSCAMID(buf, cam_id);
10787 		RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
10788 #endif
10789 
10790 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
10791 		/*Btye 2 - Max used Pattern Match CAM entry*/
10792 		if (pwrpriv->wowlan_mode == _TRUE
10793 			&& ld_sta_iface && check_fwstate(&ld_sta_iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
10794 			LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx);
10795 			RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
10796 		}
10797 #endif
10798 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
10799 		/*Btye 3 - Max MU rate table Group ID*/
10800 		LPSPG_RSVD_PAGE_SET_MU_RAID_GID(buf, 0);
10801 		RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);
10802 #endif
10803 
10804 		/*Btye 8 ~15 - used Security CAM entry */
10805 		sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
10806 
10807 		/*Btye 4 - used Security CAM entry number*/
10808 		if (sec_cam_num < 8)
10809 			LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(buf, sec_cam_num);
10810 		RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
10811 
10812 		/*Btye 5 - Txbuf used page number for fw offload*/
10813 		if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
10814 			drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
10815 		else
10816 			drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
10817 		LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(buf, drv_rsvdpage_num);
10818 		RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
10819 	}
10820 
10821 size_chk:
10822 	if (buf_size)
10823 		*buf_size = LPS_PG_INFO_RSVD_LEN;
10824 }
10825 
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)10826 static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
10827 {
10828 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10829 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10830 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_info;
10831 	u8 *info = NULL;
10832 	u32 info_len = 0;
10833 	int ret = _FAIL;
10834 
10835 	/* get length */
10836 	rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, NULL, &info_len);
10837 	if (!info_len) {
10838 		RTW_ERR("get %s length fail\n", cache->name);
10839 		goto exit;
10840 	}
10841 
10842 	/* allocate buf */
10843 	info = rtw_zmalloc(info_len);
10844 	if (!info) {
10845 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10846 		goto exit;
10847 	}
10848 
10849 	/* get content */
10850 	rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, info, NULL);
10851 
10852 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
10853 
10854 		#if (DBG_LPSPG_INFO_DUMP >= 1)
10855 		RTW_INFO_DUMP(cache->name, info, info_len);
10856 		#endif
10857 
10858 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10859 		ret = !ret ? _SUCCESS : _FAIL;
10860 		if (ret != _SUCCESS) {
10861 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10862 			goto free_mem;
10863 		}
10864 
10865 		#if (DBG_LPSPG_INFO_DUMP >= 2)
10866 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10867 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10868 		#endif
10869 	}
10870 
10871 free_mem:
10872 	rtw_mfree(info, info_len);
10873 
10874 exit:
10875 	return ret;
10876 }
10877 
rtw_lps_pg_set_rsvd_page(_adapter * adapter,u8 * frame,u16 * index,u8 txdesc_size,u32 page_size,u8 * total_page_num,bool is_wow_mode,_adapter * ld_sta_iface,bool only_get_page_num)10878 static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index
10879 	, u8 txdesc_size, u32 page_size, u8 *total_page_num
10880 	, bool is_wow_mode, _adapter *ld_sta_iface, bool only_get_page_num)
10881 {
10882 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10883 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10884 	struct rsvd_page_cache_t *cache;
10885 	bool rsvd = 1;
10886 	u8 *pos;
10887 	u32 len;
10888 
10889 	if (is_wow_mode) {
10890 		/* lps_level will not change when enter wow_mode */
10891 		if (pwrctl->lps_level != LPS_PG)
10892 			rsvd = 0;
10893 	} else {
10894 		if (!only_get_page_num && !ld_sta_iface)
10895 			rsvd = 0;
10896 	}
10897 
10898 	pos = only_get_page_num ? NULL : frame + *index;
10899 
10900 #ifdef CONFIG_RTL8822C
10901 	if (IS_8822C_SERIES(hal_data->version_id)) {
10902 		/* LPSPG_DPK_INFO */
10903 		cache = &pwrctl->lpspg_dpk_info;
10904 		if (rsvd) {
10905 			if (pwrctl->lps_level != LPS_PG)
10906 				pos = NULL;
10907 			len = 0;
10908 			halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
10909 			#if (DBG_LPSPG_INFO_DUMP >= 1)
10910 			if (pos)
10911 				RTW_INFO_DUMP(cache->name, pos, len);
10912 			#endif
10913 			rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10914 			*total_page_num += cache->page_num;
10915 			*index += page_size * cache->page_num;
10916 			pos = only_get_page_num ? NULL : frame + *index;
10917 			RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10918 		} else
10919 			rsvd_page_cache_free(cache);
10920 
10921 		/* LPSPG_IQK_INFO */
10922 		cache = &pwrctl->lpspg_iqk_info;
10923 		if (rsvd
10924 			/* RegIQKFWOffload will not change when enter wow_mode */
10925 			&& !(is_wow_mode && hal_data->RegIQKFWOffload)
10926 		) {
10927 			if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload)
10928 				pos = NULL;
10929 			len = 0;
10930 			halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
10931 			#if (DBG_LPSPG_INFO_DUMP >= 1)
10932 			if (pos)
10933 				RTW_INFO_DUMP(cache->name, pos, len);
10934 			#endif
10935 			rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10936 			*total_page_num += cache->page_num;
10937 			*index += page_size * cache->page_num;
10938 			pos = only_get_page_num ? NULL : frame + *index;
10939 			RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10940 		} else
10941 			rsvd_page_cache_free(cache);
10942 	}
10943 #endif
10944 
10945 	/* LPSPG_INFO */
10946 	cache = &pwrctl->lpspg_info;
10947 	if (rsvd) {
10948 		if (pwrctl->lps_level != LPS_PG)
10949 			pos = NULL;
10950 		rtw_hal_build_lps_pg_info_rsvd_page(adapter_to_dvobj(adapter), ld_sta_iface, pos, &len);
10951 		#if (DBG_LPSPG_INFO_DUMP >= 1)
10952 		if (pos)
10953 			RTW_INFO_DUMP(cache->name, pos, len);
10954 		#endif
10955 		rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10956 		*total_page_num += cache->page_num;
10957 		*index += page_size * cache->page_num;
10958 		pos = only_get_page_num ? NULL : frame + *index;
10959 		RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10960 	} else
10961 		rsvd_page_cache_free(cache);
10962 }
10963 
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)10964 u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
10965 {
10966 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10967 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10968 
10969 	u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
10970 	u8 ret = _FAIL;
10971 
10972 	if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
10973 		SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1);	/*SecurityCAM_En*/
10974 
10975 #ifdef CONFIG_MBSSID_CAM
10976 	SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1);		/*BSSIDCAM_En*/
10977 #endif
10978 
10979 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
10980 	if (pwrpriv->wowlan_mode == _TRUE &&
10981 	    check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
10982 
10983 		SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1);	/*PatternMatchCAM_En*/
10984 	}
10985 #endif
10986 
10987 #ifdef CONFIG_MACID_SEARCH
10988 	SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1);	/*MACIDSearch_En*/
10989 #endif
10990 
10991 #ifdef CONFIG_TX_SC
10992 	SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1);	/*TXSC_En*/
10993 #endif
10994 
10995 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
10996 	SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1);	/*MURateTable_En*/
10997 #endif
10998 
10999 	SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc);
11000 
11001 #ifdef CONFIG_RTL8822C
11002 	if (pwrpriv->bFwCurrentInPSMode == _FALSE) {
11003 		SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc);
11004 		if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11005 			SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc);
11006 	} else {
11007 		SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, 0);
11008 		if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11009 			SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, 0);
11010 	}
11011 #endif
11012 
11013 #if (DBG_LPSPG_INFO_DUMP >= 1)
11014 	RTW_INFO_DUMP("H2C_LPS_PG_INFO: ", lpspg_info, H2C_LPS_PG_INFO_LEN);
11015 #endif
11016 
11017 	ret = rtw_hal_fill_h2c_cmd(adapter,
11018 				   H2C_LPS_PG_INFO,
11019 				   H2C_LPS_PG_INFO_LEN,
11020 				   lpspg_info);
11021 	return ret;
11022 }
rtw_hal_set_lps_pg_info(_adapter * adapter)11023 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
11024 {
11025 	u8 ret = _FAIL;
11026 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11027 
11028 	if (pwrpriv->lpspg_info.loc == 0) {
11029 		RTW_ERR("%s lpspg_info.loc = 0\n", __func__);
11030 		rtw_warn_on(1);
11031 		return ret;
11032 	}
11033 	#ifdef CONFIG_RTL8822C
11034 	rtw_lps_pg_set_dpk_info_rsvd_page(adapter);
11035 	rtw_lps_pg_set_iqk_info_rsvd_page(adapter);
11036 	#endif
11037 	rtw_hal_set_lps_pg_info_rsvd_page(adapter);
11038 
11039 	ret = rtw_hal_set_lps_pg_info_cmd(adapter);
11040 
11041 	return ret;
11042 }
11043 
rtw_hal_lps_pg_rssi_lv_decide(_adapter * adapter,struct sta_info * sta)11044 void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
11045 {
11046 #if 0
11047 	if (sta->cmn.ra_info.rssi_level >= 4)
11048 		sta->lps_pg_rssi_lv = 3;	/*RSSI High - 1SS_VHT_MCS7*/
11049 	else if (sta->cmn.ra_info.rssi_level >=  2)
11050 		sta->lps_pg_rssi_lv = 2;	/*RSSI Middle - 1SS_VHT_MCS3*/
11051 	else
11052 		sta->lps_pg_rssi_lv = 1;	/*RSSI Lower - Lowest_rate*/
11053 #else
11054 	sta->lps_pg_rssi_lv = 0;
11055 #endif
11056 	RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
11057 		__func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
11058 }
11059 
rtw_hal_lps_pg_handler(_adapter * adapter,enum lps_pg_hdl_id hdl_id)11060 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
11061 {
11062 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
11063 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11064 	struct sta_priv *pstapriv = &adapter->stapriv;
11065 	struct sta_info *sta;
11066 
11067 	sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
11068 
11069 	switch (hdl_id) {
11070 	case LPS_PG_INFO_CFG:
11071 		rtw_hal_set_lps_pg_info(adapter);
11072 		break;
11073 	case LPS_PG_REDLEMEM:
11074 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11075 			break;
11076 
11077 		/*set xmit_block*/
11078 		rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11079 		if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
11080 			rtw_warn_on(1);
11081 		/*clearn xmit_block*/
11082 		rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11083 		break;
11084 	case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/
11085 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11086 			break;
11087 
11088 		if (sta)
11089 			rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);
11090 		break;
11091 	case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/
11092 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11093 			break;
11094 
11095 		if (sta) {
11096 			rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
11097 			rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);
11098 			sta->lps_pg_rssi_lv = 0;
11099 		}
11100 		break;
11101 
11102 	default:
11103 		break;
11104 	}
11105 }
11106 
11107 #endif /*CONFIG_LPS_PG*/
11108 
_rtw_mi_assoc_if_num(_adapter * adapter)11109 static u8 _rtw_mi_assoc_if_num(_adapter *adapter)
11110 {
11111 	u8 mi_iface_num = 0;
11112 
11113 	if (0) {
11114 		RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));
11115 		RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));
11116 		RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11117 		RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));
11118 		RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));
11119 		/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/
11120 		/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/
11121 	}
11122 
11123 	mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +
11124 		DEV_AP_NUM(adapter_to_dvobj(adapter)) +
11125 		DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11126 	return mi_iface_num;
11127 }
11128 #ifdef CONFIG_CONCURRENT_MODE
_rtw_search_sta_iface(_adapter * adapter)11129 static _adapter *_rtw_search_sta_iface(_adapter *adapter)
11130 {
11131 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11132 	_adapter *iface = NULL;
11133 	_adapter *sta_iface = NULL;
11134 	int i;
11135 
11136 	for (i = 0; i < dvobj->iface_nums; i++) {
11137 		iface = dvobj->padapters[i];
11138 		if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
11139 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11140 				sta_iface = iface;
11141 				break;
11142 			}
11143 		}
11144 	}
11145 	return sta_iface;
11146 }
11147 #if defined(CONFIG_AP_MODE) && defined(CONFIG_BT_COEXIST)
_rtw_search_ap_iface(_adapter * adapter)11148 static _adapter *_rtw_search_ap_iface(_adapter *adapter)
11149 {
11150 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11151 	_adapter *iface = NULL;
11152 	_adapter *ap_iface = NULL;
11153 	int i;
11154 
11155 	for (i = 0; i < dvobj->iface_nums; i++) {
11156 		iface = dvobj->padapters[i];
11157 		if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
11158 			ap_iface = iface;
11159 			break;
11160 		}
11161 	}
11162 	return ap_iface;
11163 }
11164 #endif/*CONFIG_AP_MODE*/
11165 #endif/*CONFIG_CONCURRENT_MODE*/
11166 
11167 #ifdef CONFIG_CUSTOMER01_SMART_ANTENNA
rtw_hal_set_pathb_phase(_adapter * adapter,u8 phase_idx)11168 void rtw_hal_set_pathb_phase(_adapter *adapter, u8 phase_idx)
11169 {
11170 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(adapter);
11171 	struct PHY_DM_STRUCT		*pDM_Odm = &pHalData->odmpriv;
11172 
11173 	return phydm_pathb_q_matrix_rotate(pDM_Odm, phase_idx);
11174 }
11175 #endif
11176 
11177 /*
11178  * Description: Fill the reserved packets that FW will use to RSVD page.
11179  *			Now we just send 4 types packet to rsvd page.
11180  *			(1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
11181  * Input:
11182  * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
11183  *		    so we need to set the packet length to total lengh.
11184  *	      TRUE: At the second time, we should send the first packet (default:beacon)
11185  *		    to Hw again and set the lengh in descriptor to the real beacon lengh.
11186  * page_num - The amount of reserved page which driver need.
11187  *	      If this is not NULL, this function doesn't real download reserved
11188  *	      page, but just count the number of reserved page.
11189  *
11190  * 2009.10.15 by tynli.
11191  * 2017.06.20 modified by Lucas.
11192  *
11193  * Page Size = 128: 8188e, 8723a/b, 8192c/d,
11194  * Page Size = 256: 8192e, 8821a
11195  * Page Size = 512: 8812a
11196  */
11197 
11198 /*#define DBG_DUMP_SET_RSVD_PAGE*/
_rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished,u8 * page_num)11199 static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
11200 {
11201 	PHAL_DATA_TYPE pHalData;
11202 	struct xmit_frame	*pcmdframe = NULL;
11203 	struct pkt_attrib	*pattrib;
11204 	struct xmit_priv	*pxmitpriv;
11205 	struct pwrctrl_priv *pwrctl;
11206 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11207 	u32	BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
11208 	u32	NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
11209 	u32	ProbeReqLength = 0, NullFunctionDataLength = 0;
11210 	u8	TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
11211 	u8	TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
11212 	u8	*ReservedPagePacket;
11213 	u16	BufIndex = 0;
11214 	u32	TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
11215 	RSVDPAGE_LOC	RsvdPageLoc;
11216 	struct registry_priv  *registry_par = &adapter->registrypriv;
11217 
11218 #ifdef DBG_FW_DEBUG_MSG_PKT
11219 	u32	fw_dbg_msg_pkt_len = 0;
11220 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11221 
11222 #ifdef DBG_CONFIG_ERROR_DETECT
11223 	struct sreset_priv *psrtpriv;
11224 #endif /* DBG_CONFIG_ERROR_DETECT */
11225 
11226 #ifdef CONFIG_MCC_MODE
11227 	u8 dl_mcc_page = _FAIL;
11228 #endif /* CONFIG_MCC_MODE */
11229 	u8 nr_assoc_if;
11230 
11231 	_adapter *sta_iface = NULL;
11232 	_adapter *ap_iface = NULL;
11233 
11234 	bool is_wow_mode = _FALSE;
11235 
11236 	pHalData = GET_HAL_DATA(adapter);
11237 #ifdef DBG_CONFIG_ERROR_DETECT
11238 	psrtpriv = &pHalData->srestpriv;
11239 #endif
11240 	pxmitpriv = &adapter->xmitpriv;
11241 	pwrctl = adapter_to_pwrctl(adapter);
11242 
11243 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
11244 
11245 	if (PageSize == 0) {
11246 		RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);
11247 		return;
11248 	}
11249 	nr_assoc_if = _rtw_mi_assoc_if_num(adapter);
11250 
11251 	if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||
11252 		pwrctl->wowlan_ap_mode == _TRUE ||
11253 		pwrctl->wowlan_p2p_mode == _TRUE)
11254 		is_wow_mode = _TRUE;
11255 
11256 	/*page_num for init time to get rsvd page number*/
11257 	/* Prepare ReservedPagePacket */
11258 	if (page_num) {
11259 		ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
11260 		if (!ReservedPagePacket) {
11261 			RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11262 			*page_num = 0xFF;
11263 			return;
11264 		}
11265 		RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm  ==>\n",
11266 			FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11267 
11268 	} else {
11269 		if (is_wow_mode)
11270 			RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
11271 		else
11272 			RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
11273 
11274 		RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",
11275 			FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);
11276 
11277 		MaxRsvdPageBufSize = RsvdPageNum * PageSize;
11278 		if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
11279 			RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
11280 				 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
11281 			rtw_warn_on(1);
11282 			return;
11283 		}
11284 
11285 		pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
11286 		if (pcmdframe == NULL) {
11287 			RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11288 			return;
11289 		}
11290 
11291 		ReservedPagePacket = pcmdframe->buf_addr;
11292 	}
11293 
11294 	_rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
11295 
11296 	BufIndex = TxDescOffset;
11297 
11298 	/*======== beacon content =======*/
11299 	rtw_hal_construct_beacon(adapter,
11300 				 &ReservedPagePacket[BufIndex], &BeaconLength);
11301 
11302 	/*
11303 	* When we count the first page size, we need to reserve description size for the RSVD
11304 	* packet, it will be filled in front of the packet in TXPKTBUF.
11305 	*/
11306 	BeaconLength = MAX_BEACON_LEN - TxDescLen;
11307 	CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
11308 
11309 #if defined(CONFIG_FW_HANDLE_TXBCN) || defined(CONFIG_PORT_BASED_TXBCN)
11310 	CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;
11311 #endif
11312 	TotalPageNum += CurtPktPageNum;
11313 
11314 	BufIndex += (CurtPktPageNum * PageSize);
11315 
11316 	RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11317 
11318 	/*======== probe response content ========*/
11319 	if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/
11320 		#ifdef CONFIG_CONCURRENT_MODE
11321 		if (nr_assoc_if >= 2)
11322 			RTW_ERR("Not support > 2 net-interface in WOW\n");
11323 		#endif
11324 		/* (4) probe response*/
11325 		RsvdPageLoc.LocProbeRsp = TotalPageNum;
11326 		rtw_hal_construct_ProbeRsp(
11327 			adapter, &ReservedPagePacket[BufIndex],
11328 			&ProbeRspLength,
11329 			_FALSE);
11330 		rtw_hal_fill_fake_txdesc(adapter,
11331 				 &ReservedPagePacket[BufIndex - TxDescLen],
11332 				 ProbeRspLength, _FALSE, _FALSE, _FALSE);
11333 
11334 		CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
11335 		TotalPageNum += CurtPktPageNum;
11336 		TotalPacketLen = BufIndex + ProbeRspLength;
11337 		BufIndex += (CurtPktPageNum * PageSize);
11338 		RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11339 		goto download_page;
11340 	}
11341 
11342 	/*======== ps-poll content * 1 page ========*/
11343 	sta_iface = adapter;
11344 	#ifdef CONFIG_CONCURRENT_MODE
11345 	if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {
11346 		sta_iface = _rtw_search_sta_iface(adapter);
11347 		RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));
11348 	}
11349 	#endif
11350 
11351 	if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11352 		RsvdPageLoc.LocPsPoll = TotalPageNum;
11353 		RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
11354 		rtw_hal_construct_PSPoll(sta_iface,
11355 					 &ReservedPagePacket[BufIndex], &PSPollLength);
11356 		rtw_hal_fill_fake_txdesc(sta_iface,
11357 					 &ReservedPagePacket[BufIndex - TxDescLen],
11358 					 PSPollLength, _TRUE, _FALSE, _FALSE);
11359 
11360 		CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
11361 
11362 		TotalPageNum += CurtPktPageNum;
11363 
11364 		BufIndex += (CurtPktPageNum * PageSize);
11365 		RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11366 	}
11367 
11368 #ifdef CONFIG_MCC_MODE
11369 	/*======== MCC * n page ======== */
11370 	if (MCC_EN(adapter)) {/*Normal mode*/
11371 		dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
11372 				&BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);
11373 	} else {
11374 		dl_mcc_page = _FAIL;
11375 	}
11376 
11377 	if (dl_mcc_page == _FAIL)
11378 #endif /* CONFIG_MCC_MODE */
11379 	{	/*======== null data * 1 page ======== */
11380 		if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11381 			RsvdPageLoc.LocNullData = TotalPageNum;
11382 			RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
11383 			rtw_hal_construct_NullFunctionData(
11384 				sta_iface,
11385 				&ReservedPagePacket[BufIndex],
11386 				&NullDataLength,
11387 				_FALSE, 0, 0, _FALSE);
11388 			rtw_hal_fill_fake_txdesc(sta_iface,
11389 				 &ReservedPagePacket[BufIndex - TxDescLen],
11390 				 NullDataLength, _FALSE, _FALSE, _FALSE);
11391 
11392 			CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
11393 
11394 			TotalPageNum += CurtPktPageNum;
11395 
11396 			BufIndex += (CurtPktPageNum * PageSize);
11397 			RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11398 		}
11399 	}
11400 
11401 	/*======== Qos null data * 1 page ======== */
11402 	if (pwrctl->wowlan_mode == _FALSE ||
11403 		pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
11404 		if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11405 			RsvdPageLoc.LocQosNull = TotalPageNum;
11406 			RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
11407 			rtw_hal_construct_NullFunctionData(sta_iface,
11408 						&ReservedPagePacket[BufIndex],
11409 						&QosNullLength,
11410 						_TRUE, 0, 0, _FALSE);
11411 			rtw_hal_fill_fake_txdesc(sta_iface,
11412 					 &ReservedPagePacket[BufIndex - TxDescLen],
11413 					 QosNullLength, _FALSE, _FALSE, _FALSE);
11414 
11415 			CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
11416 						     PageSize);
11417 
11418 			TotalPageNum += CurtPktPageNum;
11419 
11420 			BufIndex += (CurtPktPageNum * PageSize);
11421 			RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11422 		}
11423 	}
11424 
11425 #ifdef CONFIG_BT_COEXIST
11426 	/*======== BT Qos null data * 1 page ======== */
11427 	if (pwrctl->wowlan_mode == _FALSE ||
11428 		pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
11429 
11430 		ap_iface = adapter;
11431 		#if defined (CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
11432 		if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) {	/*DEV_AP_STARTING_NUM*/
11433 			ap_iface = _rtw_search_ap_iface(adapter);
11434 			RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));
11435 		}
11436 		#endif
11437 
11438 		if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {
11439 			RsvdPageLoc.LocBTQosNull = TotalPageNum;
11440 
11441 			RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
11442 
11443 			rtw_hal_construct_NullFunctionData(ap_iface,
11444 						&ReservedPagePacket[BufIndex],
11445 						&BTQosNullLength,
11446 						_TRUE, 0, 0, _FALSE);
11447 
11448 			rtw_hal_fill_fake_txdesc(ap_iface,
11449 					&ReservedPagePacket[BufIndex - TxDescLen],
11450 					BTQosNullLength, _FALSE, _TRUE, _FALSE);
11451 
11452 			CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
11453 							 PageSize);
11454 
11455 			TotalPageNum += CurtPktPageNum;
11456 			BufIndex += (CurtPktPageNum * PageSize);
11457 
11458 			RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11459 		}
11460 	}
11461 #endif /* CONFIG_BT_COEXIT */
11462 
11463 	TotalPacketLen = BufIndex;
11464 
11465 #ifdef DBG_FW_DEBUG_MSG_PKT
11466 		/*======== FW DEBUG MSG * n page ======== */
11467 		RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;
11468 		RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);
11469 		rtw_hal_construct_fw_dbg_msg_pkt(
11470 			adapter,
11471 			&ReservedPagePacket[BufIndex],
11472 			&fw_dbg_msg_pkt_len);
11473 
11474 		rtw_hal_fill_fake_txdesc(adapter,
11475 				 &ReservedPagePacket[BufIndex - TxDescLen],
11476 				 fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);
11477 
11478 		CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);
11479 
11480 		if (CurtPktPageNum < 2)
11481 			CurtPktPageNum = 2; /*Need at least 2 rsvd page*/
11482 		TotalPageNum += CurtPktPageNum;
11483 
11484 		TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;
11485 		BufIndex += (CurtPktPageNum * PageSize);
11486 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11487 
11488 #ifdef CONFIG_LPS_PG
11489 	rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex
11490 		, TxDescLen, PageSize, &TotalPageNum, is_wow_mode
11491 		, (sta_iface && MLME_IS_STA(sta_iface) && MLME_IS_ASOC(sta_iface)) ? sta_iface : NULL
11492 		, page_num ? 1 : 0
11493 	);
11494 	TotalPacketLen = BufIndex;
11495 #endif
11496 
11497 #ifdef CONFIG_WOWLAN
11498 	/*======== WOW * n page ======== */
11499 	if (pwrctl->wowlan_mode == _TRUE &&
11500 		pwrctl->wowlan_in_resume == _FALSE &&
11501 		check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {/*WOW mode*/
11502 		rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
11503 					     BufIndex, TxDescLen, PageSize,
11504 			     &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
11505 	}
11506 #endif /* CONFIG_WOWLAN */
11507 
11508 #ifdef CONFIG_P2P_WOWLAN
11509 	/*======== P2P WOW * n page ======== */
11510 	if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/
11511 		rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
11512 						 BufIndex, TxDescLen, PageSize,
11513 				 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
11514 	}
11515 #endif /* CONFIG_P2P_WOWLAN */
11516 
11517 	/*Note:  BufIndex already add a TxDescOffset offset in first Beacon page
11518 	* The "TotalPacketLen" is calculate by BufIndex.
11519 	* We need to decrease TxDescOffset before doing length check. by yiwei
11520 	*/
11521 	TotalPacketLen = TotalPacketLen - TxDescOffset;
11522 
11523 download_page:
11524 	if (page_num) {
11525 		*page_num = TotalPageNum;
11526 		rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
11527 		ReservedPagePacket = NULL;
11528 		RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",
11529 			FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11530 		return;
11531 	}
11532 
11533 	/* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
11534 	RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
11535 		 __func__, TotalPageNum, TotalPacketLen);
11536 
11537 	if (TotalPacketLen > MaxRsvdPageBufSize) {
11538 		RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
11539 			 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
11540 		rtw_warn_on(1);
11541 		goto error;
11542 	} else {
11543 		/* update attribute */
11544 		pattrib = &pcmdframe->attrib;
11545 		update_mgntframe_attrib(adapter, pattrib);
11546 		pattrib->qsel = QSLT_BEACON;
11547 		pattrib->pktlen = TotalPacketLen;
11548 		pattrib->last_txcmdsz = TotalPacketLen;
11549 #ifdef CONFIG_PCI_HCI
11550 		dump_mgntframe(adapter, pcmdframe);
11551 #else
11552 		dump_mgntframe_and_wait(adapter, pcmdframe, 100);
11553 #endif
11554 	}
11555 
11556 	RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
11557 		 __func__, TotalPacketLen, TotalPageNum);
11558 #ifdef DBG_DUMP_SET_RSVD_PAGE
11559 	RTW_INFO(" ==================================================\n");
11560 	RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
11561 	RTW_INFO(" ==================================================\n");
11562 #endif
11563 
11564 
11565 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
11566 		|| MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){
11567 		rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
11568 #ifdef DBG_FW_DEBUG_MSG_PKT
11569 		rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);
11570 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11571 #ifdef CONFIG_WOWLAN
11572 		if (pwrctl->wowlan_mode == _TRUE &&
11573 			pwrctl->wowlan_in_resume == _FALSE)
11574 			rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
11575 #endif /* CONFIG_WOWLAN */
11576 #ifdef CONFIG_AP_WOWLAN
11577 		if (pwrctl->wowlan_ap_mode == _TRUE)
11578 			rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
11579 #endif /* CONFIG_AP_WOWLAN */
11580 	} else if (pwrctl->wowlan_pno_enable) {
11581 #ifdef CONFIG_PNO_SUPPORT
11582 		rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
11583 		if (pwrctl->wowlan_in_resume)
11584 			rtw_hal_set_scan_offload_info_cmd(adapter,
11585 							  &RsvdPageLoc, 0);
11586 		else
11587 			rtw_hal_set_scan_offload_info_cmd(adapter,
11588 							  &RsvdPageLoc, 1);
11589 #endif /* CONFIG_PNO_SUPPORT */
11590 	}
11591 
11592 #ifdef CONFIG_P2P_WOWLAN
11593 	if (_TRUE == pwrctl->wowlan_p2p_mode)
11594 		rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
11595 #endif /* CONFIG_P2P_WOWLAN */
11596 
11597 	return;
11598 error:
11599 	rtw_free_xmitframe(pxmitpriv, pcmdframe);
11600 }
11601 
rtw_hal_set_fw_rsvd_page(struct _ADAPTER * adapter,bool finished)11602 void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
11603 {
11604 #ifdef CONFIG_AP_MODE
11605 	if (finished)
11606 		rtw_mi_tx_beacon_hdl(adapter);
11607 	else
11608 #endif
11609 		_rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
11610 }
11611 
11612 /**
11613  * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
11614  * @adapter:	struct _ADAPTER*
11615  *
11616  * Caculate needed reserved page number.
11617  * In different state would get different number, for example normal mode and
11618  * WOW mode would need different reserved page size.
11619  *
11620  * Return the number of reserved page which driver need.
11621  */
rtw_hal_get_rsvd_page_num(struct _ADAPTER * adapter)11622 u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
11623 {
11624 	u8 num = 0;
11625 
11626 
11627 	_rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
11628 
11629 	return num;
11630 }
11631 
11632 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
hw_var_set_bcn_func(_adapter * adapter,u8 enable)11633 static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)
11634 {
11635 	u32 bcn_ctrl_reg;
11636 
11637 #ifdef CONFIG_CONCURRENT_MODE
11638 	if (adapter->hw_port == HW_PORT1)
11639 		bcn_ctrl_reg = REG_BCN_CTRL_1;
11640 	else
11641 #endif
11642 		bcn_ctrl_reg = REG_BCN_CTRL;
11643 
11644 	if (enable)
11645 		rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
11646 	else {
11647 		u8 val8;
11648 
11649 		val8 = rtw_read8(adapter, bcn_ctrl_reg);
11650 		val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
11651 
11652 #ifdef CONFIG_BT_COEXIST
11653 		if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {
11654 			/* Always enable port0 beacon function for PSTDMA */
11655 			if (REG_BCN_CTRL == bcn_ctrl_reg)
11656 				val8 |= EN_BCN_FUNCTION;
11657 		}
11658 #endif
11659 
11660 		rtw_write8(adapter, bcn_ctrl_reg, val8);
11661 	}
11662 
11663 #ifdef CONFIG_RTL8192F
11664 	if (IS_HARDWARE_TYPE_8192F(adapter)) {
11665 		u16 val16, val16_ori;
11666 
11667 		val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
11668 
11669 		#ifdef CONFIG_CONCURRENT_MODE
11670 		if (adapter->hw_port == HW_PORT1) {
11671 			if (enable)
11672 				val16 |= EN_PORT_1_FUNCTION;
11673 			else
11674 				val16 &= ~EN_PORT_1_FUNCTION;
11675 		} else
11676 		#endif
11677 		{
11678 			if (enable)
11679 				val16 |= EN_PORT_0_FUNCTION;
11680 			else
11681 				val16 &= ~EN_PORT_0_FUNCTION;
11682 
11683 			#ifdef CONFIG_BT_COEXIST
11684 			if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
11685 				val16 |= EN_PORT_0_FUNCTION;
11686 			#endif
11687 		}
11688 
11689 		if (val16 != val16_ori)
11690 			rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1,  val16);
11691 	}
11692 #endif
11693 }
11694 #endif
11695 
11696 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
hw_var_set_mlme_disconnect(_adapter * adapter)11697 static void hw_var_set_mlme_disconnect(_adapter *adapter)
11698 {
11699 	u8 val8;
11700 
11701 	/* reject all data frames */
11702 #ifdef CONFIG_CONCURRENT_MODE
11703 	if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
11704 #endif
11705 		rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);
11706 
11707 #ifdef CONFIG_CONCURRENT_MODE
11708 	if (adapter->hw_port == HW_PORT1) {
11709 		/* reset TSF1 */
11710 		rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));
11711 
11712 		/* disable update TSF1 */
11713 		rtw_iface_disable_tsf_update(adapter);
11714 
11715 		if (!IS_HARDWARE_TYPE_8723D(adapter)
11716 			&& !IS_HARDWARE_TYPE_8192F(adapter)
11717 			&& !IS_HARDWARE_TYPE_8710B(adapter)
11718 		) {
11719 			/* disable Port1's beacon function */
11720 			val8 = rtw_read8(adapter, REG_BCN_CTRL_1);
11721 			val8 &= ~EN_BCN_FUNCTION;
11722 			rtw_write8(adapter, REG_BCN_CTRL_1, val8);
11723 		}
11724 	} else
11725 #endif
11726 	{
11727 		/* reset TSF */
11728 		rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
11729 
11730 		/* disable update TSF */
11731 		rtw_iface_disable_tsf_update(adapter);
11732 	}
11733 }
11734 #endif
11735 
hw_var_set_mlme_sitesurvey(_adapter * adapter,u8 enable)11736 static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)
11737 {
11738 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11739 	u16 value_rxfltmap2;
11740 
11741 #ifdef DBG_IFACE_STATUS
11742 	DBG_IFACE_STATUS_DUMP(adapter);
11743 #endif
11744 
11745 #ifdef CONFIG_FIND_BEST_CHANNEL
11746 	/* Receive all data frames */
11747 	value_rxfltmap2 = 0xFFFF;
11748 #else
11749 	/* not to receive data frame */
11750 	value_rxfltmap2 = 0;
11751 #endif
11752 
11753 	if (enable) { /* under sitesurvey */
11754 		/*
11755 		* 1. configure REG_RXFLTMAP2
11756 		* 2. disable TSF update &  buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
11757 		* 3. config RCR to receive different BSSID BCN or probe rsp
11758 		*/
11759 		rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
11760 
11761 		rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
11762 
11763 		/* Save orignal RRSR setting, only 8812 set RRSR after set ch/bw/band */
11764 		#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11765 		hal_data->RegRRSR = rtw_read32(adapter, REG_RRSR);
11766 		hal_data->RegRRSR &= 0x000FFFFF;
11767 		#endif
11768 
11769 		#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
11770 		if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
11771 			/* set 718[1:0]=2'b00 to avoid BF scan hang */
11772 			hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
11773 			rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
11774 		}
11775 		#endif
11776 
11777 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11778 			StopTxBeacon(adapter);
11779 	} else { /* sitesurvey done */
11780 		/*
11781 		* 1. enable rx data frame
11782 		* 2. config RCR not to receive different BSSID BCN or probe rsp
11783 		* 3. doesn't enable TSF update &  buddy TSF right now to avoid HW conflict
11784 		*	 so, we enable TSF update when rx first BCN after sitesurvey done
11785 		*/
11786 		if (rtw_mi_check_fwstate(adapter, WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) {
11787 			/* enable to rx data frame */
11788 			rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11789 		}
11790 
11791 		rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
11792 
11793 		/* Restore orignal RRSR setting,only 8812 set RRSR after set ch/bw/band */
11794 		#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11795 			rtw_phydm_set_rrsr(adapter, hal_data->RegRRSR, TRUE);
11796 		#endif
11797 
11798 		#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
11799 		if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
11800 			/* Restore orignal 0x718 setting*/
11801 			rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
11802 		}
11803 		#endif
11804 
11805 		#ifdef CONFIG_AP_MODE
11806 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11807 			ResumeTxBeacon(adapter);
11808 			rtw_mi_tx_beacon_hdl(adapter);
11809 		}
11810 		#endif
11811 	}
11812 }
11813 
11814 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
hw_var_set_mlme_join(_adapter * adapter,u8 type)11815 static void hw_var_set_mlme_join(_adapter *adapter, u8 type)
11816 {
11817 	u8 val8;
11818 	u16 val16;
11819 	u32 val32;
11820 	u8 RetryLimit = RL_VAL_STA;
11821 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11822 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11823 
11824 #ifdef CONFIG_CONCURRENT_MODE
11825 	if (type == 0) {
11826 		/* prepare to join */
11827 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11828 			StopTxBeacon(adapter);
11829 
11830 		/* enable to rx data frame.Accept all data frame */
11831 		rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11832 
11833 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
11834 			RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
11835 		else /* Ad-hoc Mode */
11836 			RetryLimit = RL_VAL_AP;
11837 
11838 		rtw_iface_enable_tsf_update(adapter);
11839 
11840 	} else if (type == 1) {
11841 		/* joinbss_event call back when join res < 0 */
11842 		if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
11843 			rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
11844 
11845 		rtw_iface_disable_tsf_update(adapter);
11846 
11847 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11848 			ResumeTxBeacon(adapter);
11849 
11850 			/* reset TSF 1/2 after ResumeTxBeacon */
11851 			rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
11852 		}
11853 
11854 	} else if (type == 2) {
11855 		/* sta add event call back */
11856 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
11857 			/* fixed beacon issue for 8191su........... */
11858 			rtw_write8(adapter, 0x542 , 0x02);
11859 			RetryLimit = RL_VAL_AP;
11860 		}
11861 
11862 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11863 			ResumeTxBeacon(adapter);
11864 
11865 			/* reset TSF 1/2 after ResumeTxBeacon */
11866 			rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
11867 		}
11868 	}
11869 
11870 	val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
11871 	rtw_write16(adapter, REG_RETRY_LIMIT, val16);
11872 #else /* !CONFIG_CONCURRENT_MODE */
11873 	if (type == 0) { /* prepare to join */
11874 		/* enable to rx data frame.Accept all data frame */
11875 		rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11876 
11877 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
11878 			RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
11879 		else /* Ad-hoc Mode */
11880 			RetryLimit = RL_VAL_AP;
11881 
11882 		rtw_iface_enable_tsf_update(adapter);
11883 
11884 	} else if (type == 1) { /* joinbss_event call back when join res < 0 */
11885 		rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
11886 
11887 		rtw_iface_disable_tsf_update(adapter);
11888 
11889 	} else if (type == 2) { /* sta add event call back */
11890 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
11891 			RetryLimit = RL_VAL_AP;
11892 	}
11893 
11894 	val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
11895 	rtw_write16(adapter, REG_RETRY_LIMIT, val16);
11896 #endif /* !CONFIG_CONCURRENT_MODE */
11897 }
11898 #endif
11899 
11900 #ifdef CONFIG_TSF_RESET_OFFLOAD
rtw_hal_h2c_reset_tsf(_adapter * adapter,u8 reset_port)11901 static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
11902 {
11903 	u8 buf[2];
11904 	int ret;
11905 
11906 	if (reset_port == HW_PORT0) {
11907 		buf[0] = 0x1;
11908 		buf[1] = 0;
11909 	} else {
11910 		buf[0] = 0x0;
11911 		buf[1] = 0x1;
11912 	}
11913 
11914 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
11915 
11916 	return ret;
11917 }
11918 
rtw_hal_reset_tsf(_adapter * adapter,u8 reset_port)11919 int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
11920 {
11921 	u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
11922 	u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
11923 				REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
11924 	int ret;
11925 
11926 	/* site survey will cause reset tsf fail */
11927 	rtw_mi_buddy_scan_abort(adapter, _FALSE);
11928 	reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
11929 	ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
11930 	if (ret != _SUCCESS)
11931 		return ret;
11932 
11933 	while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
11934 		rtw_msleep_os(100);
11935 		loop_cnt++;
11936 		reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
11937 	}
11938 
11939 	return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
11940 }
11941 #endif /* CONFIG_TSF_RESET_OFFLOAD */
11942 
11943 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
11944 #ifdef CONFIG_HW_P0_TSF_SYNC
11945 #ifdef CONFIG_CONCURRENT_MODE
hw_port0_tsf_sync_sel(_adapter * adapter,u8 benable,u8 hw_port,u16 tr_offset)11946 static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)
11947 {
11948 	u8 val8;
11949 	u8 client_id = 0;
11950 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11951 
11952 #ifdef CONFIG_MCC_MODE
11953 	if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {
11954 		RTW_INFO("[MCC] do not set HW TSF sync\n");
11955 		return;
11956 	}
11957 #endif
11958 	/* check if port0 is already synced */
11959 	if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {
11960 		RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",
11961 			FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);
11962 		return;
11963 	}
11964 
11965 	/* check if port0 already disable sync */
11966 	if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {
11967 		RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));
11968 		return;
11969 	}
11970 
11971 	/* check if port0 sync to port0 */
11972 	if (benable && hw_port == HW_PORT0) {
11973 		RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));
11974 		rtw_warn_on(1);
11975 		return;
11976 	}
11977 
11978 	/*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/
11979 	/*	Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.
11980 		Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/
11981 
11982 	val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);
11983 
11984 	if (benable) {
11985 		/*Disable Port0's beacon function*/
11986 		rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
11987 
11988 		/*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/
11989 		if (tr_offset)
11990 			rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);
11991 
11992 		/*reg 0x577[6]=1*/	/*auto sync by tbtt*/
11993 		rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);
11994 
11995 		if (HW_PORT1 == hw_port)
11996 			client_id = 0;
11997 		else if (HW_PORT2 == hw_port)
11998 			client_id = 1;
11999 		else if (HW_PORT3 == hw_port)
12000 			client_id = 2;
12001 		else if (HW_PORT4 == hw_port)
12002 			client_id = 3;
12003 
12004 		val8 &= 0x8F;
12005 		val8 |= (BIT(6) | (client_id << 4));
12006 
12007 		dvobj->p0_tsf.sync_port = hw_port;
12008 		dvobj->p0_tsf.offset = tr_offset;
12009 		rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12010 
12011 		/*Enable Port0's beacon function*/
12012 		rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL)  | BIT_EN_BCN_FUNCTION);
12013 		RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);
12014 	} else {
12015 		val8 &= ~BIT(6);
12016 
12017 		dvobj->p0_tsf.sync_port = MAX_HW_PORT;
12018 		dvobj->p0_tsf.offset = 0;
12019 		rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12020 		RTW_INFO("%s P0 TSF sync disable\n", __func__);
12021 	}
12022 }
_search_ld_sta(_adapter * adapter,u8 include_self)12023 static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)
12024 {
12025 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12026 	u8 i;
12027 	_adapter *iface = NULL;
12028 
12029 	if (rtw_mi_get_assoced_sta_num(adapter) == 0) {
12030 		RTW_ERR("STA_LD_NUM == 0\n");
12031 		rtw_warn_on(1);
12032 	}
12033 
12034 	for (i = 0; i < dvobj->iface_nums; i++) {
12035 		iface = dvobj->padapters[i];
12036 		if (!iface)
12037 			continue;
12038 		if (include_self == _FALSE && adapter == iface)
12039 			continue;
12040 		if (is_client_associated_to_ap(iface))
12041 			break;
12042 	}
12043 	if (iface)
12044 		RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));
12045 	return iface;
12046 }
12047 #endif /*CONFIG_CONCURRENT_MODE*/
12048 /*Correct port0's TSF*/
12049 /*#define DBG_P0_TSF_SYNC*/
hw_var_set_correct_tsf(PADAPTER adapter,u8 mlme_state)12050 void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)
12051 {
12052 #ifdef CONFIG_CONCURRENT_MODE
12053 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12054 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12055 	_adapter *sta_if = NULL;
12056 	u8 hw_port;
12057 
12058 	RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));
12059 	#ifdef DBG_P0_TSF_SYNC
12060 	RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));
12061 	RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));
12062 	RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));
12063 	if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12064 		RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");
12065 	else
12066 		RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12067 	RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12068 	#endif
12069 	switch (mlme_state) {
12070 		case MLME_STA_CONNECTED :
12071 			{
12072 				hw_port = rtw_hal_get_port(adapter);
12073 
12074 				if (!MLME_IS_STA(adapter)) {
12075 					RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12076 					rtw_warn_on(1);
12077 				}
12078 
12079 				if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {
12080 					RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));
12081 					rtw_warn_on(1);
12082 					hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12083 				}
12084 
12085 				if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12086 					(rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {
12087 					hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12088 					#ifdef DBG_P0_TSF_SYNC
12089 					RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");
12090 					#endif
12091 				}
12092 			}
12093 			break;
12094 		case MLME_STA_DISCONNECTED :
12095 			{
12096 				hw_port = rtw_hal_get_port(adapter);
12097 
12098 				if (!MLME_IS_STA(adapter)) {
12099 					RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12100 					rtw_warn_on(1);
12101 				}
12102 
12103 				if (dvobj->p0_tsf.sync_port == hw_port) {
12104 					if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {
12105 						/* search next appropriate sta*/
12106 						sta_if = _search_ld_sta(adapter, _FALSE);
12107 						if (sta_if) {
12108 							hw_port = rtw_hal_get_port(sta_if);
12109 							hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12110 							#ifdef DBG_P0_TSF_SYNC
12111 							RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");
12112 							#endif
12113 						}
12114 					} else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {
12115 						hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12116 						#ifdef DBG_P0_TSF_SYNC
12117 						RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");
12118 						#endif
12119 					}
12120 				}
12121 			}
12122 			break;
12123 #ifdef CONFIG_AP_MODE
12124 		case MLME_AP_STARTED :
12125 		case MLME_MESH_STARTED :
12126 			{
12127 				if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12128 					RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12129 					rtw_warn_on(1);
12130 				}
12131 
12132 				if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12133 					rtw_mi_get_assoced_sta_num(adapter)) {
12134 					/* get port of sta */
12135 					sta_if = _search_ld_sta(adapter, _FALSE);
12136 					if (sta_if) {
12137 						hw_port = rtw_hal_get_port(sta_if);
12138 						hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12139 						#ifdef DBG_P0_TSF_SYNC
12140 						RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");
12141 						#endif
12142 					}
12143 				}
12144 			}
12145 			break;
12146 		case MLME_AP_STOPPED :
12147 		case MLME_MESH_STOPPED :
12148 			{
12149 				if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12150 					RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12151 					rtw_warn_on(1);
12152 				}
12153 				/*stop ap mode*/
12154 				if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&
12155 					(dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {
12156 					hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12157 					#ifdef DBG_P0_TSF_SYNC
12158 					RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");
12159 					#endif
12160 				}
12161 			}
12162 			break;
12163 #endif /* CONFIG_AP_MODE */
12164 		default :
12165 			RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);
12166 			break;
12167 	}
12168 
12169 	/*#ifdef DBG_P0_TSF_SYNC*/
12170 	#if 1
12171 	if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12172 		RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");
12173 	else
12174 		RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12175 	RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12176 	#endif
12177 #endif /*CONFIG_CONCURRENT_MODE*/
12178 }
12179 
12180 #else /*! CONFIG_HW_P0_TSF_SYNC*/
12181 
12182 #ifdef CONFIG_MI_WITH_MBSSID_CAM
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12183 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12184 {
12185 	/*do nothing*/
12186 }
12187 #else /* !CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)12188 static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
12189 {
12190 	if (hw_port == HW_PORT0) {
12191 		/*disable related TSF function*/
12192 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
12193 #if defined(CONFIG_RTL8192F)
12194 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12195 					REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);
12196 #endif
12197 
12198 		rtw_write32(padapter, REG_TSFTR, tsf);
12199 		rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
12200 
12201 		/*enable related TSF function*/
12202 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
12203 #if defined(CONFIG_RTL8192F)
12204 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12205 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
12206 #endif
12207 	} else if (hw_port == HW_PORT1) {
12208 		/*disable related TSF function*/
12209 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
12210 #if defined(CONFIG_RTL8192F)
12211 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12212 					REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_1_FUNCTION);
12213 #endif
12214 
12215 		rtw_write32(padapter, REG_TSFTR1, tsf);
12216 		rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
12217 
12218 		/*enable related TSF function*/
12219 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
12220 #if defined(CONFIG_RTL8192F)
12221 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12222 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);
12223 #endif
12224 	} else
12225 		RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
12226 }
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12227 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12228 {
12229 	u64 tsf;
12230 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
12231 	struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
12232 
12233 	tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
12234 
12235 	if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12236 		|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12237 		StopTxBeacon(adapter);
12238 
12239 	rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
12240 
12241 #ifdef CONFIG_CONCURRENT_MODE
12242 	/* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
12243 	if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
12244 		&& (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12245 	) {
12246 		struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12247 		int i;
12248 		_adapter *iface;
12249 
12250 		for (i = 0; i < dvobj->iface_nums; i++) {
12251 			iface = dvobj->padapters[i];
12252 			if (!iface)
12253 				continue;
12254 			if (iface == adapter)
12255 				continue;
12256 
12257 			#ifdef CONFIG_AP_MODE
12258 			if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
12259 				&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
12260 			) {
12261 				rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
12262 				#ifdef CONFIG_TSF_RESET_OFFLOAD
12263 				if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
12264 					RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
12265 						, __func__, ADPT_ARG(iface), iface->hw_port);
12266 				#endif	/* CONFIG_TSF_RESET_OFFLOAD*/
12267 			}
12268 			#endif /* CONFIG_AP_MODE */
12269 		}
12270 	}
12271 #endif /* CONFIG_CONCURRENT_MODE */
12272 	if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12273 		|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12274 		ResumeTxBeacon(adapter);
12275 }
12276 #endif /*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
12277 #endif /*#ifdef CONFIG_HW_P0_TSF_SYNC*/
12278 #endif /*#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF*/
12279 
rtw_hal_get_tsftr_by_port(_adapter * adapter,u8 port)12280 u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)
12281 {
12282 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
12283 	u64 tsftr = 0;
12284 
12285 	if (port >= hal_spec->port_num) {
12286 		RTW_ERR("%s invalid port(%d) \n", __func__, port);
12287 		goto exit;
12288 	}
12289 
12290 	switch (rtw_get_chip_type(adapter)) {
12291 #if defined(CONFIG_RTL8814B)
12292 	case RTL8814B:
12293 	{
12294 		u8 val8;
12295 
12296 		/* 0x1500[6:4] - BIT_BCN_TIMER_SEL_FWRD_V1 */
12297 		val8 = rtw_read8(adapter, REG_PORT_CTRL_SEL);
12298 		val8 &= ~0x70;
12299 		val8 |= port << 4;
12300 		rtw_write8(adapter, REG_PORT_CTRL_SEL, val8);
12301 
12302 		tsftr = rtw_read32(adapter, REG_TSFTR_HIGH);
12303 		tsftr = tsftr << 32;
12304 		tsftr |= rtw_read32(adapter, REG_TSFTR_LOW);
12305 
12306 		break;
12307 	}
12308 #endif
12309 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
12310 	case RTL8814A:
12311 	case RTL8822B:
12312 	case RTL8821C:
12313 	case RTL8822C:
12314 	{
12315 		u8 val8;
12316 
12317 		/* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */
12318 		val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);
12319 		val8 &= 0x8F;
12320 		val8 |= port << 4;
12321 		rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);
12322 
12323 		tsftr = rtw_read32(adapter, REG_TSFTR + 4);
12324 		tsftr = tsftr << 32;
12325 		tsftr |= rtw_read32(adapter, REG_TSFTR);
12326 
12327 		break;
12328 	}
12329 #endif
12330 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \
12331 		|| defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \
12332 		|| defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \
12333 		|| defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
12334 		|| defined(CONFIG_RTL8710B)
12335 	case RTL8188E:
12336 	case RTL8188F:
12337 	case RTL8188GTV:
12338 	case RTL8192E:
12339 	case RTL8192F:
12340 	case RTL8723B:
12341 	case RTL8703B:
12342 	case RTL8723D:
12343 	case RTL8812:
12344 	case RTL8821:
12345 	case RTL8710B:
12346 	{
12347 		u32 addr;
12348 
12349 		if (port == HW_PORT0)
12350 			addr = REG_TSFTR;
12351 		else if (port == HW_PORT1)
12352 			addr = REG_TSFTR1;
12353 		else {
12354 			RTW_ERR("%s unknown port(%d) \n", __func__, port);
12355 			goto exit;
12356 		}
12357 
12358 		tsftr = rtw_read32(adapter, addr + 4);
12359 		tsftr = tsftr << 32;
12360 		tsftr |= rtw_read32(adapter, addr);
12361 
12362 		break;
12363 	}
12364 #endif
12365 	default:
12366 		RTW_ERR("%s unknow chip type\n", __func__);
12367 	}
12368 
12369 exit:
12370 	return tsftr;
12371 }
12372 
12373 #ifdef CONFIG_TDLS
12374 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)12375 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
12376 {
12377 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
12378 	u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
12379 
12380 
12381 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
12382 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
12383 	switch (bwmode) {
12384 	case CHANNEL_WIDTH_40:
12385 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
12386 		break;
12387 	case CHANNEL_WIDTH_80:
12388 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
12389 		break;
12390 	case CHANNEL_WIDTH_20:
12391 	default:
12392 		break;
12393 	}
12394 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
12395 
12396 	return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
12397 }
12398 #endif
12399 #endif
12400 
12401 #ifdef CONFIG_WMMPS_STA
rtw_hal_update_uapsd_tid(_adapter * adapter)12402 void rtw_hal_update_uapsd_tid(_adapter *adapter)
12403 {
12404 	struct mlme_priv		*pmlmepriv = &adapter->mlmepriv;
12405 	struct qos_priv		*pqospriv = &pmlmepriv->qospriv;
12406 
12407 	/* write complement of pqospriv->uapsd_tid to mac register 0x693 because
12408 	    it's designed  for "0" represents "enable" and "1" represents "disable" */
12409 	rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
12410 }
12411 #endif /* CONFIG_WMMPS_STA */
12412 
12413 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
12414 /* For multi-port support, driver needs to inform the port ID to FW for btc operations */
rtw_hal_set_wifi_btc_port_id_cmd(_adapter * adapter)12415 s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)
12416 {
12417 	u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
12418 	u8 hw_port = rtw_hal_get_port(adapter);
12419 
12420 	SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);
12421 	RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);
12422 	return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
12423 }
12424 #endif
12425 
12426 #define LPS_ACTIVE_TIMEOUT	50 /*number of times*/
rtw_lps_state_chk(_adapter * adapter,u8 ps_mode)12427 void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)
12428 {
12429 	struct pwrctrl_priv 		*pwrpriv = adapter_to_pwrctl(adapter);
12430 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
12431 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12432 	struct sta_priv		*pstapriv = &adapter->stapriv;
12433 	struct sta_info		*psta = NULL;
12434 	u8 ps_ready = _FALSE;
12435 	s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;
12436 
12437 	if (ps_mode == PS_MODE_ACTIVE) {
12438 #ifdef CONFIG_LPS_ACK
12439 		if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) {
12440 			if (pwrpriv->lps_ack_status > 0) {
12441 				psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
12442 				if (psta != NULL) {
12443 					if(issue_nulldata(adapter, psta->cmn.mac_addr, PS_MODE_ACTIVE, 3, 1) == _FAIL)
12444 						RTW_INFO(FUNC_ADPT_FMT" LPS state sync not yet finished.\n", FUNC_ADPT_ARG(adapter));
12445 				}
12446 			}
12447 		} else {
12448 			RTW_WARN("LPS sctx query timeout, operation abort!!\n");
12449 			return;
12450 		}
12451 		pwrpriv->lps_ack_status = -1;
12452 #else
12453 		do {
12454 			if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {
12455 				ps_ready = _TRUE;
12456 				break;
12457 			}
12458 			rtw_msleep_os(1);
12459 		} while (leave_wait_count--);
12460 
12461 		if (ps_ready == _FALSE) {
12462 			RTW_WARN(FUNC_ADPT_FMT" Power Bit Control is still in HW!\n", FUNC_ADPT_ARG(adapter));
12463 			return;
12464 		}
12465 #endif /* CONFIG_LPS_ACK */
12466 		}
12467 	}
12468 
rtw_var_set_basic_rate(PADAPTER padapter,u8 * val)12469 void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) {
12470 
12471 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
12472 	struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
12473 	u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
12474 	u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
12475 	u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
12476 	#if CONFIG_IEEE80211_BAND_5GHZ
12477 	u16 rrsr_5g_force_mask = (RRSR_6M);
12478 	u16 rrsr_5g_allow_mask = (RRSR_OFDM_RATES);
12479 	#endif
12480 	u32 temp_RRSR;
12481 
12482 	HalSetBrateCfg(padapter, val, &BrateCfg);
12483 	input_b = BrateCfg;
12484 
12485 	/* apply force and allow mask */
12486 	#if CONFIG_IEEE80211_BAND_5GHZ
12487 	if (pHalData->current_band_type != BAND_ON_2_4G) {
12488 		BrateCfg |= rrsr_5g_force_mask;
12489 		BrateCfg &= rrsr_5g_allow_mask;
12490 	} else
12491 	#endif
12492 	{ /* 2.4G */
12493 		BrateCfg |= rrsr_2g_force_mask;
12494 		BrateCfg &= rrsr_2g_allow_mask;
12495 	}
12496 	masked = BrateCfg;
12497 
12498 #ifdef CONFIG_CMCC_TEST
12499 	BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */
12500 	BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */
12501 #endif
12502 
12503 	/* IOT consideration */
12504 	if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
12505 		/* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
12506 		if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
12507 			BrateCfg |= RRSR_6M;
12508 	}
12509 		ioted = BrateCfg;
12510 
12511 #ifdef CONFIG_NARROWBAND_SUPPORTING
12512 	if ((padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
12513 		|| (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_5)) {
12514 		BrateCfg &= ~RRSR_CCK_RATES;
12515 		BrateCfg |= RRSR_6M;
12516 	}
12517 #endif
12518 	pHalData->BasicRateSet = BrateCfg;
12519 
12520 	RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
12521 
12522 	/* Set RRSR rate table. */
12523 		temp_RRSR = rtw_read32(padapter, REG_RRSR);
12524 		temp_RRSR &=0xFFFF0000;
12525 		temp_RRSR |=BrateCfg;
12526 		rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE);
12527 
12528 	rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);
12529 
12530 	#if defined(CONFIG_RTL8188E)
12531 	rtw_hal_set_hwreg(padapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);
12532 	#endif
12533 }
12534 
SetHwReg(_adapter * adapter,u8 variable,u8 * val)12535 u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
12536 {
12537 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12538 	u8 ret = _SUCCESS;
12539 
12540 	switch (variable) {
12541 	case HW_VAR_MEDIA_STATUS: {
12542 		u8 net_type = *((u8 *)val);
12543 
12544 		rtw_hal_set_msr(adapter, net_type);
12545 	}
12546 	break;
12547 	case HW_VAR_DO_IQK:
12548 		if (*val)
12549 			hal_data->bNeedIQK = _TRUE;
12550 		else
12551 			hal_data->bNeedIQK = _FALSE;
12552 		break;
12553 	case HW_VAR_MAC_ADDR:
12554 #ifdef CONFIG_MI_WITH_MBSSID_CAM
12555 		rtw_hal_set_macaddr_mbid(adapter, val);
12556 #else
12557 		rtw_hal_set_macaddr_port(adapter, val);
12558 #endif
12559 		break;
12560 	case HW_VAR_BSSID:
12561 		rtw_hal_set_bssid(adapter, val);
12562 		break;
12563 	case HW_VAR_RCR:
12564 		ret = hw_var_rcr_config(adapter, *((u32 *)val));
12565 		break;
12566 	case HW_VAR_ON_RCR_AM:
12567 		hw_var_set_rcr_am(adapter, 1);
12568 		break;
12569 	case HW_VAR_OFF_RCR_AM:
12570 		hw_var_set_rcr_am(adapter, 0);
12571 		break;
12572 	case HW_VAR_BEACON_INTERVAL:
12573 		hw_var_set_bcn_interval(adapter, *(u16 *)val);
12574 		break;
12575 #ifdef CONFIG_MBSSID_CAM
12576 	case HW_VAR_MBSSID_CAM_WRITE: {
12577 		u32	cmd = 0;
12578 		u32	*cam_val = (u32 *)val;
12579 
12580 		rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
12581 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
12582 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
12583 	}
12584 		break;
12585 	case HW_VAR_MBSSID_CAM_CLEAR: {
12586 		u32 cmd;
12587 		u8 entry_id = *(u8 *)val;
12588 
12589 		rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
12590 
12591 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
12592 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
12593 	}
12594 		break;
12595 	case HW_VAR_RCR_MBSSID_EN:
12596 		if (*((u8 *)val))
12597 			rtw_hal_rcr_add(adapter, RCR_ENMBID);
12598 		else
12599 			rtw_hal_rcr_clear(adapter, RCR_ENMBID);
12600 		break;
12601 #endif
12602 	case HW_VAR_PORT_SWITCH:
12603 		hw_var_port_switch(adapter);
12604 		break;
12605 	case HW_VAR_INIT_RTS_RATE: {
12606 		u16 brate_cfg = *((u16 *)val);
12607 		u8 rate_index = 0;
12608 		HAL_VERSION *hal_ver = &hal_data->version_id;
12609 
12610 		if (IS_8188E(*hal_ver)) {
12611 
12612 			while (brate_cfg > 0x1) {
12613 				brate_cfg = (brate_cfg >> 1);
12614 				rate_index++;
12615 			}
12616 			rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
12617 		} else
12618 			rtw_warn_on(1);
12619 	}
12620 		break;
12621 	case HW_VAR_SEC_CFG: {
12622 		u16 reg_scr_ori;
12623 		u16 reg_scr;
12624 
12625 		reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
12626 		reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
12627 
12628 		if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
12629 			reg_scr |= SCR_CHK_BMC;
12630 
12631 		if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
12632 			reg_scr |= SCR_NoSKMC;
12633 
12634 		if (reg_scr != reg_scr_ori)
12635 			rtw_write16(adapter, REG_SECCFG, reg_scr);
12636 	}
12637 		break;
12638 	case HW_VAR_SEC_DK_CFG: {
12639 		struct security_priv *sec = &adapter->securitypriv;
12640 		u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
12641 
12642 		if (val) { /* Enable default key related setting */
12643 			reg_scr |= SCR_TXBCUSEDK;
12644 			if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
12645 				reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
12646 		} else /* Disable default key related setting */
12647 			reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
12648 
12649 		rtw_write8(adapter, REG_SECCFG, reg_scr);
12650 	}
12651 		break;
12652 
12653 	case HW_VAR_ASIX_IOT:
12654 		/* enable  ASIX IOT function */
12655 		if (*((u8 *)val) == _TRUE) {
12656 			/* 0xa2e[0]=0 (disable rake receiver) */
12657 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
12658 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
12659 			/* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
12660 			rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
12661 		} else {
12662 			/* restore reg:0xa2e,   reg:0xa1c */
12663 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
12664 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
12665 			rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
12666 		}
12667 		break;
12668 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
12669 	case HW_VAR_WOWLAN: {
12670 		struct wowlan_ioctl_param *poidparam;
12671 
12672 		poidparam = (struct wowlan_ioctl_param *)val;
12673 		switch (poidparam->subcode) {
12674 #ifdef CONFIG_WOWLAN
12675 		case WOWLAN_PATTERN_CLEAN:
12676 			rtw_hal_dl_pattern(adapter, 2);
12677 			break;
12678 		case WOWLAN_ENABLE:
12679 			rtw_hal_wow_enable(adapter);
12680 			break;
12681 		case WOWLAN_DISABLE:
12682 			rtw_hal_wow_disable(adapter);
12683 			break;
12684 #endif /*CONFIG_WOWLAN*/
12685 #ifdef CONFIG_AP_WOWLAN
12686 		case WOWLAN_AP_ENABLE:
12687 			rtw_hal_ap_wow_enable(adapter);
12688 			break;
12689 		case WOWLAN_AP_DISABLE:
12690 			rtw_hal_ap_wow_disable(adapter);
12691 			break;
12692 #endif /*CONFIG_AP_WOWLAN*/
12693 		default:
12694 			break;
12695 		}
12696 	}
12697 		break;
12698 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
12699 
12700 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
12701 	case HW_VAR_BCN_FUNC:
12702 		hw_var_set_bcn_func(adapter, *val);
12703 		break;
12704 #endif
12705 
12706 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
12707 	case HW_VAR_MLME_DISCONNECT:
12708 		hw_var_set_mlme_disconnect(adapter);
12709 		break;
12710 #endif
12711 
12712 	case HW_VAR_MLME_SITESURVEY:
12713 		hw_var_set_mlme_sitesurvey(adapter, *val);
12714 		#ifdef CONFIG_BT_COEXIST
12715 		if (hal_data->EEPROMBluetoothCoexist == 1)
12716 			rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
12717 		#endif
12718 		break;
12719 
12720 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
12721 	case HW_VAR_MLME_JOIN:
12722 		hw_var_set_mlme_join(adapter, *val);
12723 		break;
12724 #endif
12725 
12726 	case HW_VAR_EN_HW_UPDATE_TSF:
12727 		rtw_hal_set_hw_update_tsf(adapter);
12728 		break;
12729 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
12730 	case HW_VAR_CORRECT_TSF:
12731 		hw_var_set_correct_tsf(adapter, *val);
12732 		break;
12733 #endif
12734 
12735 #if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_MCC_MODE)
12736 	case HW_VAR_TSF_AUTO_SYNC:
12737 		if (*val == _TRUE)
12738 			hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);
12739 		else
12740 			hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);
12741 		break;
12742 #endif
12743 	case HW_VAR_APFM_ON_MAC:
12744 		hal_data->bMacPwrCtrlOn = *val;
12745 		RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
12746 		break;
12747 #ifdef CONFIG_WMMPS_STA
12748 	case  HW_VAR_UAPSD_TID:
12749 		rtw_hal_update_uapsd_tid(adapter);
12750 		break;
12751 #endif /* CONFIG_WMMPS_STA */
12752 #ifdef CONFIG_LPS_PG
12753 	case HW_VAR_LPS_PG_HANDLE:
12754 		rtw_hal_lps_pg_handler(adapter, *val);
12755 		break;
12756 #endif
12757 #ifdef CONFIG_LPS_LCLK_WD_TIMER
12758 	case HW_VAR_DM_IN_LPS_LCLK:
12759 		rtw_phydm_wd_lps_lclk_hdl(adapter);
12760 		break;
12761 #endif
12762 	case HW_VAR_ENABLE_RX_BAR:
12763 		if (*val == _TRUE) {
12764 			/* enable RX BAR */
12765 			u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
12766 
12767 			val16 |= BIT(8);
12768 			rtw_write16(adapter, REG_RXFLTMAP1, val16);
12769 		} else {
12770 			/* disable RX BAR */
12771 			u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
12772 
12773 			val16 &= (~BIT(8));
12774 			rtw_write16(adapter, REG_RXFLTMAP1, val16);
12775 		}
12776 		RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",
12777 			REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));
12778 		break;
12779 	case HW_VAR_HCI_SUS_STATE:
12780 		hal_data->hci_sus_state = *(u8 *)val;
12781 		RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);
12782 		break;
12783 #if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)
12784 		case HW_VAR_BCN_HEAD_SEL:
12785 		{
12786 			u8 vap_id = *(u8 *)val;
12787 
12788 			if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {
12789 				RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);
12790 				rtw_warn_on(1);
12791 			}
12792 			if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
12793 				u16 drv_pg_bndy = 0, bcn_addr = 0;
12794 				u32 page_size = 0;
12795 
12796 				/*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/
12797 				rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);
12798 				rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
12799 
12800 				if (vap_id != 0xFF)
12801 					bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));
12802 				else
12803 					bcn_addr = drv_pg_bndy;
12804 				RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",
12805 					ADPT_ARG(adapter), vap_id, bcn_addr);
12806 				rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,
12807 					(bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);
12808 			}
12809 		}
12810 		break;
12811 #endif
12812 	case HW_VAR_LPS_STATE_CHK :
12813 		rtw_lps_state_chk(adapter, *(u8 *)val);
12814 		break;
12815 
12816 #ifdef CONFIG_RTS_FULL_BW
12817 	case HW_VAR_SET_RTS_BW:
12818 	{
12819 		#ifdef RTW_HALMAC
12820 			rtw_halmac_set_rts_full_bw(adapter_to_dvobj(adapter), (*val));
12821 		#else
12822 			u8 temp;
12823 			if(*val)
12824 				temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) | BIT5 );
12825 			else
12826 				temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) & (~BIT5));
12827 			rtw_write8(adapter, REG_INIRTS_RATE_SEL, temp);
12828 			/*RTW_INFO("HW_VAR_SET_RTS_BW	val=%u REG480=0x%x\n", *val, rtw_read8(adapter, REG_INIRTS_RATE_SEL));*/
12829 		#endif
12830 	}
12831 	break;
12832 #endif/*CONFIG_RTS_FULL_BW*/
12833 #if defined(CONFIG_PCI_HCI)
12834 	case HW_VAR_ENSWBCN:
12835 	if (*val == _TRUE) {
12836 		rtw_write8(adapter, REG_CR + 1,
12837 			   rtw_read8(adapter, REG_CR + 1) | BIT(0));
12838 	} else
12839 		rtw_write8(adapter, REG_CR + 1,
12840 			   rtw_read8(adapter, REG_CR + 1) & ~BIT(0));
12841 	break;
12842 #endif
12843 	default:
12844 		if (0)
12845 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
12846 				  FUNC_ADPT_ARG(adapter), variable);
12847 		ret = _FAIL;
12848 		break;
12849 	}
12850 
12851 	return ret;
12852 }
12853 
GetHwReg(_adapter * adapter,u8 variable,u8 * val)12854 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
12855 {
12856 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12857 	u64 val64;
12858 
12859 
12860 	switch (variable) {
12861 	case HW_VAR_MAC_ADDR:
12862 		#ifndef CONFIG_MI_WITH_MBSSID_CAM
12863 		rtw_hal_get_macaddr_port(adapter, val);
12864 		#endif
12865 		break;
12866 	case HW_VAR_BASIC_RATE:
12867 		*((u16 *)val) = hal_data->BasicRateSet;
12868 		break;
12869 	case HW_VAR_MEDIA_STATUS:
12870 		rtw_hal_get_msr(adapter, val);
12871 		break;
12872 	case HW_VAR_DO_IQK:
12873 		*val = hal_data->bNeedIQK;
12874 		break;
12875 	case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
12876 		if (hal_is_band_support(adapter, BAND_ON_5G))
12877 			*val = _TRUE;
12878 		else
12879 			*val = _FALSE;
12880 		break;
12881 	case HW_VAR_APFM_ON_MAC:
12882 		*val = hal_data->bMacPwrCtrlOn;
12883 		break;
12884 	case HW_VAR_RCR:
12885 		hw_var_rcr_get(adapter, (u32 *)val);
12886 		break;
12887 	case HW_VAR_FWLPS_RF_ON:
12888 		/* When we halt NIC, we should check if FW LPS is leave. */
12889 		if (rtw_is_surprise_removed(adapter)
12890 			|| (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
12891 		) {
12892 			/*
12893 			 * If it is in HW/SW Radio OFF or IPS state,
12894 			 * we do not check Fw LPS Leave,
12895 			 * because Fw is unload.
12896 			 */
12897 			*val = _TRUE;
12898 		} else {
12899 			u32 rcr = 0;
12900 
12901 			rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
12902 			if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
12903 				*val = _FALSE;
12904 			else
12905 				*val = _TRUE;
12906 		}
12907 		break;
12908 
12909 	case HW_VAR_HCI_SUS_STATE:
12910 		*((u8 *)val) = hal_data->hci_sus_state;
12911 		break;
12912 
12913 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
12914 	case HW_VAR_BCN_CTRL_ADDR:
12915 		*((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);
12916 		break;
12917 #endif
12918 
12919 #ifdef CONFIG_WAPI_SUPPORT
12920 	case HW_VAR_CAM_EMPTY_ENTRY: {
12921 		u8	ucIndex = *((u8 *)val);
12922 		u8	i;
12923 		u32	ulCommand = 0;
12924 		u32	ulContent = 0;
12925 		u32	ulEncAlgo = CAM_AES;
12926 
12927 		for (i = 0; i < CAM_CONTENT_COUNT; i++) {
12928 			/* filled id in CAM config 2 byte */
12929 			if (i == 0)
12930 				ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
12931 			else
12932 				ulContent = 0;
12933 			/* polling bit, and No Write enable, and address */
12934 			ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
12935 			ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
12936 			/* write content 0 is equall to mark invalid */
12937 			rtw_write32(adapter, REG_CAMWRITE, ulContent);  /* delay_ms(40); */
12938 			rtw_write32(adapter, REG_CAMCMD, ulCommand);  /* delay_ms(40); */
12939 		}
12940 	}
12941 #endif
12942 
12943 	default:
12944 		if (0)
12945 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
12946 				  FUNC_ADPT_ARG(adapter), variable);
12947 		break;
12948 	}
12949 
12950 }
12951 
_get_page_size(struct _ADAPTER * a)12952 static u32 _get_page_size(struct _ADAPTER *a)
12953 {
12954 #ifdef RTW_HALMAC
12955 	struct dvobj_priv *d;
12956 	u32 size = 0;
12957 	int err = 0;
12958 
12959 
12960 	d = adapter_to_dvobj(a);
12961 
12962 	err = rtw_halmac_get_page_size(d, &size);
12963 	if (!err)
12964 		return size;
12965 
12966 	RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
12967 		 FUNC_ADPT_ARG(a), err);
12968 #endif /* RTW_HALMAC */
12969 
12970 	return PAGE_SIZE_128;
12971 }
12972 
12973 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)12974 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
12975 {
12976 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12977 	u8 bResult = _SUCCESS;
12978 
12979 	switch (variable) {
12980 
12981 	case HAL_DEF_DBG_DUMP_RXPKT:
12982 		hal_data->bDumpRxPkt = *((u8 *)value);
12983 		break;
12984 	case HAL_DEF_DBG_DUMP_TXPKT:
12985 		hal_data->bDumpTxPkt = *((u8 *)value);
12986 		break;
12987 	case HAL_DEF_ANT_DETECT:
12988 		hal_data->AntDetection = *((u8 *)value);
12989 		break;
12990 	default:
12991 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
12992 		bResult = _FAIL;
12993 		break;
12994 	}
12995 
12996 	return bResult;
12997 }
12998 
12999 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)13000 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
13001 {
13002 	struct registry_priv	*pregistrypriv = &adapter->registrypriv;
13003 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13004 
13005 	if ((pregistrypriv->beamformer_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter) || IS_HARDWARE_TYPE_8821C(adapter)))
13006 		return pregistrypriv->beamformer_rf_num;
13007 	else if (IS_HARDWARE_TYPE_8814AE(adapter)
13008 #if 0
13009 #if defined(CONFIG_USB_HCI)
13010 		|| (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2))  /* for USB3.0 */
13011 #endif
13012 #endif
13013 		) {
13014 		/*BF cap provided by Yu Chen, Sean, 2015, 01 */
13015 		if (hal_data->rf_type == RF_3T3R)
13016 			return 2;
13017 		else if (hal_data->rf_type == RF_4T4R)
13018 			return 3;
13019 		else
13020 			return 1;
13021 	} else
13022 		return 1;
13023 
13024 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)13025 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
13026 {
13027 	struct registry_priv		*pregistrypriv = &adapter->registrypriv;
13028 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
13029 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
13030 
13031 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13032 
13033 	if ((pregistrypriv->beamformee_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter) || IS_HARDWARE_TYPE_8821C(adapter)))
13034 		return pregistrypriv->beamformee_rf_num;
13035 	else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
13036 		if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
13037 			return 2;
13038 		else
13039 			return 2;/*TODO: May be 3 in the future, by ChenYu. */
13040 	} else
13041 		return 1;
13042 
13043 }
13044 #ifdef RTW_BEAMFORMING_VERSION_2
rtw_hal_beamforming_config_csirate(PADAPTER adapter)13045 void rtw_hal_beamforming_config_csirate(PADAPTER adapter)
13046 {
13047 	struct dm_struct *p_dm_odm;
13048 	struct beamforming_info *bf_info;
13049 	u8 fix_rate_enable = 0;
13050 	u8 new_csi_rate_idx;
13051 	u8 rrsr_54_en;
13052 	u32 temp_rrsr;
13053 
13054 	/* Acting as BFee */
13055 	if (IS_BEAMFORMEE(adapter)) {
13056 	#if 0
13057 		/* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */
13058 		if (IS_HARDWARE_TYPE_8821C(Adapter))
13059 			FixRateEnable = 1;	/* Support after 8821C */
13060 	#endif
13061 
13062 		p_dm_odm = adapter_to_phydm(adapter);
13063 		bf_info = GET_BEAMFORM_INFO(adapter);
13064 
13065 		rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),
13066 				p_dm_odm->rssi_min,
13067 				bf_info->cur_csi_rpt_rate,
13068 				fix_rate_enable, &new_csi_rate_idx, &rrsr_54_en);
13069 
13070 		temp_rrsr = rtw_read32(adapter, REG_RRSR);
13071 		if (rrsr_54_en == 1)
13072 			temp_rrsr |= RRSR_54M;
13073 		else if (rrsr_54_en == 0)
13074 			temp_rrsr &= ~RRSR_54M;
13075 		rtw_phydm_set_rrsr(adapter, temp_rrsr, FALSE);
13076 
13077 		if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)
13078 			bf_info->cur_csi_rpt_rate = new_csi_rate_idx;
13079 	}
13080 }
13081 #endif
13082 #endif
13083 
13084 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13085 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13086 {
13087 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13088 	u8 bResult = _SUCCESS;
13089 
13090 	switch (variable) {
13091 	case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
13092 		struct mlme_priv *pmlmepriv;
13093 		struct sta_priv *pstapriv;
13094 		struct sta_info *psta;
13095 
13096 		pmlmepriv = &adapter->mlmepriv;
13097 		pstapriv = &adapter->stapriv;
13098 		psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
13099 		if (psta)
13100 			*((int *)value) = psta->cmn.rssi_stat.rssi;
13101 	}
13102 	break;
13103 	case HAL_DEF_DBG_DUMP_RXPKT:
13104 		*((u8 *)value) = hal_data->bDumpRxPkt;
13105 		break;
13106 	case HAL_DEF_DBG_DUMP_TXPKT:
13107 		*((u8 *)value) = hal_data->bDumpTxPkt;
13108 		break;
13109 	case HAL_DEF_ANT_DETECT:
13110 		*((u8 *)value) = hal_data->AntDetection;
13111 		break;
13112 	case HAL_DEF_TX_PAGE_SIZE:
13113 		*((u32 *)value) = _get_page_size(adapter);
13114 		break;
13115 	case HAL_DEF_TX_STBC:
13116 		#ifdef CONFIG_ALPHA_SMART_ANTENNA
13117 		*(u8 *)value = 0;
13118 		#else
13119 		*(u8 *)value = hal_data->max_tx_cnt > 1 ? 1 : 0;
13120 		#endif
13121 		break;
13122 	case HAL_DEF_EXPLICIT_BEAMFORMER:
13123 	case HAL_DEF_EXPLICIT_BEAMFORMEE:
13124 	case HAL_DEF_VHT_MU_BEAMFORMER:
13125 	case HAL_DEF_VHT_MU_BEAMFORMEE:
13126 		*(u8 *)value = _FALSE;
13127 		break;
13128 #ifdef CONFIG_BEAMFORMING
13129 	case HAL_DEF_BEAMFORMER_CAP:
13130 		*(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
13131 		break;
13132 	case HAL_DEF_BEAMFORMEE_CAP:
13133 		*(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
13134 		break;
13135 #endif
13136 	default:
13137 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
13138 		bResult = _FAIL;
13139 		break;
13140 	}
13141 
13142 	return bResult;
13143 }
13144 
13145 /*
13146  *	Description:
13147  *		Translate a character to hex digit.
13148  *   */
13149 u32
MapCharToHexDigit(char chTmp)13150 MapCharToHexDigit(
13151 			char		chTmp
13152 )
13153 {
13154 	if (chTmp >= '0' && chTmp <= '9')
13155 		return chTmp - '0';
13156 	else if (chTmp >= 'a' && chTmp <= 'f')
13157 		return 10 + (chTmp - 'a');
13158 	else if (chTmp >= 'A' && chTmp <= 'F')
13159 		return 10 + (chTmp - 'A');
13160 	else
13161 		return 0;
13162 }
13163 
13164 
13165 
13166 /*
13167  *	Description:
13168  *		Parse hex number from the string pucStr.
13169  *   */
13170 BOOLEAN
GetHexValueFromString(char * szStr,u32 * pu4bVal,u32 * pu4bMove)13171 GetHexValueFromString(
13172 		char			*szStr,
13173 		u32			*pu4bVal,
13174 		u32			*pu4bMove
13175 )
13176 {
13177 	char		*szScan = szStr;
13178 
13179 	/* Check input parameter. */
13180 	if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
13181 		RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
13182 		return _FALSE;
13183 	}
13184 
13185 	/* Initialize output. */
13186 	*pu4bMove = 0;
13187 	*pu4bVal = 0;
13188 
13189 	/* Skip leading space. */
13190 	while (*szScan != '\0' &&
13191 	       (*szScan == ' ' || *szScan == '\t')) {
13192 		szScan++;
13193 		(*pu4bMove)++;
13194 	}
13195 
13196 	/* Skip leading '0x' or '0X'. */
13197 	if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
13198 		szScan += 2;
13199 		(*pu4bMove) += 2;
13200 	}
13201 
13202 	/* Check if szScan is now pointer to a character for hex digit, */
13203 	/* if not, it means this is not a valid hex number. */
13204 	if (!IsHexDigit(*szScan))
13205 		return _FALSE;
13206 
13207 	/* Parse each digit. */
13208 	do {
13209 		(*pu4bVal) <<= 4;
13210 		*pu4bVal += MapCharToHexDigit(*szScan);
13211 
13212 		szScan++;
13213 		(*pu4bMove)++;
13214 	} while (IsHexDigit(*szScan));
13215 
13216 	return _TRUE;
13217 }
13218 
13219 BOOLEAN
GetFractionValueFromString(char * szStr,u8 * pInteger,u8 * pFraction,u32 * pu4bMove)13220 GetFractionValueFromString(
13221 		char			*szStr,
13222 		u8				*pInteger,
13223 		u8				*pFraction,
13224 		u32			*pu4bMove
13225 )
13226 {
13227 	char	*szScan = szStr;
13228 
13229 	/* Initialize output. */
13230 	*pu4bMove = 0;
13231 	*pInteger = 0;
13232 	*pFraction = 0;
13233 
13234 	/* Skip leading space. */
13235 	while (*szScan != '\0' &&	(*szScan == ' ' || *szScan == '\t')) {
13236 		++szScan;
13237 		++(*pu4bMove);
13238 	}
13239 
13240 	if (*szScan < '0' || *szScan > '9')
13241 		return _FALSE;
13242 
13243 	/* Parse each digit. */
13244 	do {
13245 		(*pInteger) *= 10;
13246 		*pInteger += (*szScan - '0');
13247 
13248 		++szScan;
13249 		++(*pu4bMove);
13250 
13251 		if (*szScan == '.') {
13252 			++szScan;
13253 			++(*pu4bMove);
13254 
13255 			if (*szScan < '0' || *szScan > '9')
13256 				return _FALSE;
13257 
13258 			*pFraction += (*szScan - '0') * 10;
13259 			++szScan;
13260 			++(*pu4bMove);
13261 
13262 			if (*szScan >= '0' && *szScan <= '9') {
13263 				*pFraction += *szScan - '0';
13264 				++szScan;
13265 				++(*pu4bMove);
13266 			}
13267 			return _TRUE;
13268 		}
13269 	} while (*szScan >= '0' && *szScan <= '9');
13270 
13271 	return _TRUE;
13272 }
13273 
13274 /*
13275  *	Description:
13276  * Return TRUE if szStr is comment out with leading " */ /* ".
13277  *   */
13278 BOOLEAN
IsCommentString(char * szStr)13279 IsCommentString(
13280 		char			*szStr
13281 )
13282 {
13283 	if (*szStr == '/' && *(szStr + 1) == '/')
13284 		return _TRUE;
13285 	else
13286 		return _FALSE;
13287 }
13288 
13289 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(char * Str,u8 * pInt)13290 GetU1ByteIntegerFromStringInDecimal(
13291 		char	*Str,
13292 		u8		*pInt
13293 )
13294 {
13295 	u16 i = 0;
13296 	*pInt = 0;
13297 
13298 	while (Str[i] != '\0') {
13299 		if (Str[i] >= '0' && Str[i] <= '9') {
13300 			*pInt *= 10;
13301 			*pInt += (Str[i] - '0');
13302 		} else
13303 			return _FALSE;
13304 		++i;
13305 	}
13306 
13307 	return _TRUE;
13308 }
13309 
13310 /* <20121004, Kordan> For example,
13311  * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
13312  * If RightQualifier does not exist, it will hang on in the while loop */
13313 BOOLEAN
ParseQualifiedString(char * In,u32 * Start,char * Out,char LeftQualifier,char RightQualifier)13314 ParseQualifiedString(
13315 			char	*In,
13316 			u32	*Start,
13317 			char	*Out,
13318 			char		LeftQualifier,
13319 			char		RightQualifier
13320 )
13321 {
13322 	u32	i = 0, j = 0;
13323 	char	c = In[(*Start)++];
13324 
13325 	if (c != LeftQualifier)
13326 		return _FALSE;
13327 
13328 	i = (*Start);
13329 	c = In[(*Start)++];
13330 	while (c != RightQualifier && c != '\0')
13331 		c = In[(*Start)++];
13332 
13333 	if (c == '\0')
13334 		return _FALSE;
13335 
13336 	j = (*Start) - 2;
13337 	strncpy((char *)Out, (const char *)(In + i), j - i + 1);
13338 
13339 	return _TRUE;
13340 }
13341 
13342 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)13343 isAllSpaceOrTab(
13344 	u8	*data,
13345 	u8	size
13346 )
13347 {
13348 	u8	cnt = 0, NumOfSpaceAndTab = 0;
13349 
13350 	while (size > cnt) {
13351 		if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
13352 			++NumOfSpaceAndTab;
13353 
13354 		++cnt;
13355 	}
13356 
13357 	return size == NumOfSpaceAndTab;
13358 }
13359 
13360 
rtw_hal_check_rxfifo_full(_adapter * adapter)13361 void rtw_hal_check_rxfifo_full(_adapter *adapter)
13362 {
13363 	struct dvobj_priv *psdpriv = adapter->dvobj;
13364 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
13365 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
13366 	struct registry_priv *regsty = &adapter->registrypriv;
13367 	int save_cnt = _FALSE;
13368 
13369 	if (regsty->check_hw_status == 1) {
13370 		/* switch counter to RX fifo */
13371 		if (IS_8188E(pHalData->version_id) ||
13372 		    IS_8188F(pHalData->version_id) ||
13373 		    IS_8188GTV(pHalData->version_id) ||
13374 		    IS_8812_SERIES(pHalData->version_id) ||
13375 		    IS_8821_SERIES(pHalData->version_id) ||
13376 		    IS_8723B_SERIES(pHalData->version_id) ||
13377 		    IS_8192E(pHalData->version_id) ||
13378 		    IS_8703B_SERIES(pHalData->version_id) ||
13379 		    IS_8723D_SERIES(pHalData->version_id) ||
13380 		    IS_8192F_SERIES(pHalData->version_id)) {
13381 			rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
13382 			save_cnt = _TRUE;
13383 		} else {
13384 			/* todo: other chips */
13385 		}
13386 
13387 
13388 		if (save_cnt) {
13389 			pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
13390 			pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
13391 			pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
13392 		} else {
13393 			/* special value to indicate no implementation */
13394 			pdbgpriv->dbg_rx_fifo_last_overflow = 1;
13395 			pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
13396 			pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
13397 		}
13398 	}
13399 }
13400 
linked_info_dump(_adapter * padapter,u8 benable)13401 void linked_info_dump(_adapter *padapter, u8 benable)
13402 {
13403 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
13404 
13405 	if (padapter->bLinkInfoDump == benable)
13406 		return;
13407 
13408 	RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
13409 
13410 	if (benable) {
13411 #ifdef CONFIG_LPS
13412 		pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
13413 		rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
13414 #endif
13415 
13416 #ifdef CONFIG_IPS
13417 		pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
13418 		rtw_pm_set_ips(padapter, IPS_NONE);
13419 #endif
13420 	} else {
13421 #ifdef CONFIG_IPS
13422 		rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
13423 #endif /* CONFIG_IPS */
13424 
13425 #ifdef CONFIG_LPS
13426 		rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
13427 #endif /* CONFIG_LPS */
13428 	}
13429 	padapter->bLinkInfoDump = benable ;
13430 }
13431 
13432 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)13433 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
13434 {
13435 	u8 isCCKrate, rf_path;
13436 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13437 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13438 	RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
13439 		HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
13440 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13441 
13442 	if (isCCKrate)
13443 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
13444 
13445 	for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13446 		if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13447 			continue;
13448 		RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
13449 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
13450 
13451 		if (!isCCKrate) {
13452 			RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
13453 				psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
13454 		}
13455 	}
13456 }
13457 
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)13458 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
13459 {
13460 	u8 isCCKrate, rf_path;
13461 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13462 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13463 	_RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
13464 	_RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
13465 
13466 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13467 
13468 	if (isCCKrate)
13469 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
13470 
13471 	for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13472 		if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13473 			continue;
13474 		_RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
13475 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
13476 
13477 		if (!isCCKrate)
13478 			_RTW_PRINT_SEL(sel , ",rx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n", psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
13479 		else
13480 			_RTW_PRINT_SEL(sel , "\n");
13481 
13482 	}
13483 }
13484 #endif
13485 
13486 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)13487 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
13488 {
13489 #define DBG_RX_DFRAME_RAW_DATA_UC		0
13490 #define DBG_RX_DFRAME_RAW_DATA_BMC		1
13491 #define DBG_RX_DFRAME_RAW_DATA_TYPES	2
13492 
13493 	_irqL irqL;
13494 	u8 isCCKrate, rf_path;
13495 	struct recv_priv *precvpriv = &(padapter->recvpriv);
13496 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13497 	struct sta_priv *pstapriv = &padapter->stapriv;
13498 	struct sta_info *psta;
13499 	struct sta_recv_dframe_info *psta_dframe_info;
13500 	int i, j;
13501 	_list	*plist, *phead;
13502 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13503 	u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
13504 
13505 	if (precvpriv->store_law_data_flag) {
13506 
13507 		_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13508 
13509 		for (i = 0; i < NUM_STA; i++) {
13510 			phead = &(pstapriv->sta_hash[i]);
13511 			plist = get_next(phead);
13512 
13513 			while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
13514 
13515 				psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
13516 				plist = get_next(plist);
13517 
13518 				if (psta) {
13519 					if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN)  !=   _TRUE)
13520 					    && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN)  !=  _TRUE)
13521 					    && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN)  !=  _TRUE)) {
13522 
13523 						RTW_PRINT_SEL(sel, "==============================\n");
13524 						RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
13525 
13526 						for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {
13527 							if (j == DBG_RX_DFRAME_RAW_DATA_UC) {
13528 								psta_dframe_info = &psta->sta_dframe_info;
13529 								RTW_PRINT_SEL(sel, "\n");
13530 								RTW_PRINT_SEL(sel, "Unicast:\n");
13531 							} else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {
13532 								psta_dframe_info = &psta->sta_dframe_info_bmc;
13533 								RTW_PRINT_SEL(sel, "\n");
13534 								RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");
13535 							}
13536 
13537 							isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13538 
13539 							RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);
13540 							RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
13541 
13542 							for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13543 								if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13544 									continue;
13545 								if (!isCCKrate) {
13546 									RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
13547 									_RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
13548 								} else
13549 									RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
13550 							}
13551 						}
13552 
13553 					}
13554 				}
13555 			}
13556 		}
13557 		_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13558 	}
13559 }
13560 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)13561 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
13562 {
13563 	u8 isCCKrate, rf_path , dframe_type;
13564 	u8 *ptr;
13565 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13566 #ifdef DBG_RX_DFRAME_RAW_DATA
13567 	struct sta_recv_dframe_info *psta_dframe_info;
13568 #endif
13569 	struct recv_priv *precvpriv = &(padapter->recvpriv);
13570 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13571 	struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
13572 	struct sta_info *psta = prframe->u.hdr.psta;
13573 	struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
13574 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13575 	psample_pkt_rssi->data_rate = pattrib->data_rate;
13576 	ptr = prframe->u.hdr.rx_data;
13577 	dframe_type = GetFrameType(ptr);
13578 	/*RTW_INFO("=>%s\n", __FUNCTION__);*/
13579 
13580 
13581 	if (precvpriv->store_law_data_flag) {
13582 		isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13583 
13584 		psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
13585 		psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
13586 
13587 		for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13588 			psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
13589 			psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
13590 			if (!isCCKrate) {
13591 				psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
13592 				psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
13593 			}
13594 		}
13595 #ifdef DBG_RX_DFRAME_RAW_DATA
13596 		if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
13597 
13598 			/*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
13599 			if (psta) {
13600 				if (IS_MCAST(get_ra(get_recvframe_data(prframe))))
13601 					psta_dframe_info = &psta->sta_dframe_info_bmc;
13602 				else
13603 					psta_dframe_info = &psta->sta_dframe_info;
13604 				/*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
13605 					__FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
13606 				if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
13607 					psta_dframe_info->sta_data_rate = pattrib->data_rate;
13608 					psta_dframe_info->sta_sgi = pattrib->sgi;
13609 					psta_dframe_info->sta_bw_mode = pattrib->bw;
13610 					for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13611 
13612 						psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
13613 
13614 						if (!isCCKrate) {
13615 							psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
13616 							psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
13617 						}
13618 					}
13619 				}
13620 			}
13621 		}
13622 #endif
13623 	}
13624 
13625 }
13626 
hal_efuse_macaddr_offset(_adapter * adapter)13627 int hal_efuse_macaddr_offset(_adapter *adapter)
13628 {
13629 	u8 interface_type = 0;
13630 	int addr_offset = -1;
13631 
13632 	interface_type = rtw_get_intf_type(adapter);
13633 
13634 	switch (rtw_get_chip_type(adapter)) {
13635 #ifdef CONFIG_RTL8723B
13636 	case RTL8723B:
13637 		if (interface_type == RTW_USB)
13638 			addr_offset = EEPROM_MAC_ADDR_8723BU;
13639 		else if (interface_type == RTW_SDIO)
13640 			addr_offset = EEPROM_MAC_ADDR_8723BS;
13641 		else if (interface_type == RTW_PCIE)
13642 			addr_offset = EEPROM_MAC_ADDR_8723BE;
13643 		break;
13644 #endif
13645 #ifdef CONFIG_RTL8703B
13646 	case RTL8703B:
13647 		if (interface_type == RTW_USB)
13648 			addr_offset = EEPROM_MAC_ADDR_8703BU;
13649 		else if (interface_type == RTW_SDIO)
13650 			addr_offset = EEPROM_MAC_ADDR_8703BS;
13651 		break;
13652 #endif
13653 #ifdef CONFIG_RTL8723D
13654 	case RTL8723D:
13655 		if (interface_type == RTW_USB)
13656 			addr_offset = EEPROM_MAC_ADDR_8723DU;
13657 		else if (interface_type == RTW_SDIO)
13658 			addr_offset = EEPROM_MAC_ADDR_8723DS;
13659 		else if (interface_type == RTW_PCIE)
13660 			addr_offset = EEPROM_MAC_ADDR_8723DE;
13661 		break;
13662 #endif
13663 
13664 #ifdef CONFIG_RTL8188E
13665 	case RTL8188E:
13666 		if (interface_type == RTW_USB)
13667 			addr_offset = EEPROM_MAC_ADDR_88EU;
13668 		else if (interface_type == RTW_SDIO)
13669 			addr_offset = EEPROM_MAC_ADDR_88ES;
13670 		else if (interface_type == RTW_PCIE)
13671 			addr_offset = EEPROM_MAC_ADDR_88EE;
13672 		break;
13673 #endif
13674 #ifdef CONFIG_RTL8188F
13675 	case RTL8188F:
13676 		if (interface_type == RTW_USB)
13677 			addr_offset = EEPROM_MAC_ADDR_8188FU;
13678 		else if (interface_type == RTW_SDIO)
13679 			addr_offset = EEPROM_MAC_ADDR_8188FS;
13680 		break;
13681 #endif
13682 #ifdef CONFIG_RTL8188GTV
13683 	case RTL8188GTV:
13684 		if (interface_type == RTW_USB)
13685 			addr_offset = EEPROM_MAC_ADDR_8188GTVU;
13686 		else if (interface_type == RTW_SDIO)
13687 			addr_offset = EEPROM_MAC_ADDR_8188GTVS;
13688 		break;
13689 #endif
13690 #ifdef CONFIG_RTL8812A
13691 	case RTL8812:
13692 		if (interface_type == RTW_USB)
13693 			addr_offset = EEPROM_MAC_ADDR_8812AU;
13694 		else if (interface_type == RTW_PCIE)
13695 			addr_offset = EEPROM_MAC_ADDR_8812AE;
13696 		break;
13697 #endif
13698 #ifdef CONFIG_RTL8821A
13699 	case RTL8821:
13700 		if (interface_type == RTW_USB)
13701 			addr_offset = EEPROM_MAC_ADDR_8821AU;
13702 		else if (interface_type == RTW_SDIO)
13703 			addr_offset = EEPROM_MAC_ADDR_8821AS;
13704 		else if (interface_type == RTW_PCIE)
13705 			addr_offset = EEPROM_MAC_ADDR_8821AE;
13706 		break;
13707 #endif
13708 #ifdef CONFIG_RTL8192E
13709 	case RTL8192E:
13710 		if (interface_type == RTW_USB)
13711 			addr_offset = EEPROM_MAC_ADDR_8192EU;
13712 		else if (interface_type == RTW_SDIO)
13713 			addr_offset = EEPROM_MAC_ADDR_8192ES;
13714 		else if (interface_type == RTW_PCIE)
13715 			addr_offset = EEPROM_MAC_ADDR_8192EE;
13716 		break;
13717 #endif
13718 #ifdef CONFIG_RTL8814A
13719 	case RTL8814A:
13720 		if (interface_type == RTW_USB)
13721 			addr_offset = EEPROM_MAC_ADDR_8814AU;
13722 		else if (interface_type == RTW_PCIE)
13723 			addr_offset = EEPROM_MAC_ADDR_8814AE;
13724 		break;
13725 #endif
13726 
13727 #ifdef CONFIG_RTL8822B
13728 	case RTL8822B:
13729 		if (interface_type == RTW_USB)
13730 			addr_offset = EEPROM_MAC_ADDR_8822BU;
13731 		else if (interface_type == RTW_SDIO)
13732 			addr_offset = EEPROM_MAC_ADDR_8822BS;
13733 		else if (interface_type == RTW_PCIE)
13734 			addr_offset = EEPROM_MAC_ADDR_8822BE;
13735 		break;
13736 #endif /* CONFIG_RTL8822B */
13737 
13738 #ifdef CONFIG_RTL8821C
13739 	case RTL8821C:
13740 		if (interface_type == RTW_USB)
13741 			addr_offset = EEPROM_MAC_ADDR_8821CU;
13742 		else if (interface_type == RTW_SDIO)
13743 			addr_offset = EEPROM_MAC_ADDR_8821CS;
13744 		else if (interface_type == RTW_PCIE)
13745 			addr_offset = EEPROM_MAC_ADDR_8821CE;
13746 		break;
13747 #endif /* CONFIG_RTL8821C */
13748 
13749 #ifdef CONFIG_RTL8710B
13750 	case RTL8710B:
13751 		if (interface_type == RTW_USB)
13752 			addr_offset = EEPROM_MAC_ADDR_8710B;
13753 		break;
13754 #endif
13755 
13756 #ifdef CONFIG_RTL8192F
13757 	case RTL8192F:
13758 		if (interface_type == RTW_USB)
13759 			addr_offset = EEPROM_MAC_ADDR_8192FU;
13760 		else if (interface_type == RTW_SDIO)
13761 			addr_offset = EEPROM_MAC_ADDR_8192FS;
13762 		else if (interface_type == RTW_PCIE)
13763 			addr_offset = EEPROM_MAC_ADDR_8192FE;
13764 		break;
13765 #endif /* CONFIG_RTL8192F */
13766 
13767 #ifdef CONFIG_RTL8822C
13768 	case RTL8822C:
13769 		if (interface_type == RTW_USB)
13770 			addr_offset = EEPROM_MAC_ADDR_8822CU;
13771 		else if (interface_type == RTW_SDIO)
13772 			addr_offset = EEPROM_MAC_ADDR_8822CS;
13773 		else if (interface_type == RTW_PCIE)
13774 			addr_offset = EEPROM_MAC_ADDR_8822CE;
13775 		break;
13776 #endif /* CONFIG_RTL8822C */
13777 
13778 #ifdef CONFIG_RTL8814B
13779 	case RTL8814B:
13780 		if (interface_type == RTW_USB)
13781 			addr_offset = EEPROM_MAC_ADDR_8814BU;
13782 		else if (interface_type == RTW_PCIE)
13783 			addr_offset = EEPROM_MAC_ADDR_8814BE;
13784 		break;
13785 #endif /* CONFIG_RTL8814B */
13786 	}
13787 
13788 	if (addr_offset == -1) {
13789 		RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
13790 			, __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
13791 	}
13792 
13793 	return addr_offset;
13794 }
13795 
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)13796 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
13797 {
13798 	int ret = _FAIL;
13799 	int addr_offset;
13800 
13801 	addr_offset = hal_efuse_macaddr_offset(padapter);
13802 	if (addr_offset == -1)
13803 		goto exit;
13804 
13805 	ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
13806 
13807 exit:
13808 	return ret;
13809 }
13810 
rtw_dump_cur_efuse(PADAPTER padapter)13811 void rtw_dump_cur_efuse(PADAPTER padapter)
13812 {
13813 	int mapsize =0;
13814 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13815 
13816 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
13817 
13818 	if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
13819 		RTW_ERR("wrong map size %d\n", mapsize);
13820 		return;
13821 	}
13822 
13823 #ifdef CONFIG_RTW_DEBUG
13824 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13825 		RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);
13826 	else
13827 		RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);
13828 #endif
13829 }
13830 
13831 
13832 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)13833 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
13834 {
13835 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13836 	u32 ret = _FALSE;
13837 	u32 maplen = 0;
13838 
13839 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
13840 
13841 	if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
13842 		RTW_ERR("eFuse length error :%d\n", maplen);
13843 		return _FALSE;
13844 	}
13845 
13846 	ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
13847 
13848 	hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
13849 
13850 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13851 		rtw_dump_cur_efuse(padapter);
13852 
13853 	return ret;
13854 }
13855 
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)13856 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
13857 {
13858 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13859 	u32 ret = _FAIL;
13860 
13861 	if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
13862 		&& rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
13863 	) {
13864 		hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
13865 		ret = _SUCCESS;
13866 	} else
13867 		hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
13868 
13869 	return ret;
13870 }
13871 #endif /* CONFIG_EFUSE_CONFIG_FILE */
13872 
hal_config_macaddr(_adapter * adapter,bool autoload_fail)13873 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
13874 {
13875 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13876 	u8 addr[ETH_ALEN];
13877 	int addr_offset = hal_efuse_macaddr_offset(adapter);
13878 	u8 *hw_addr = NULL;
13879 	int ret = _SUCCESS;
13880 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
13881 	u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */
13882 #endif
13883 
13884 	if (autoload_fail)
13885 		goto bypass_hw_pg;
13886 
13887 	if (addr_offset != -1)
13888 		hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
13889 
13890 #ifdef CONFIG_EFUSE_CONFIG_FILE
13891 	/* if the hw_addr is written by efuse file, set to NULL */
13892 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13893 		hw_addr = NULL;
13894 #endif
13895 
13896 	if (!hw_addr) {
13897 		/* try getting hw pg data */
13898 		if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
13899 			hw_addr = addr;
13900 	}
13901 
13902 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
13903 	if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))
13904 		hw_addr[0] = 0xff;
13905 #endif
13906 
13907 	/* check hw pg data */
13908 	if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
13909 		_rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
13910 		goto exit;
13911 	}
13912 
13913 bypass_hw_pg:
13914 
13915 #ifdef CONFIG_EFUSE_CONFIG_FILE
13916 	/* check wifi mac file */
13917 	if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
13918 		_rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
13919 		goto exit;
13920 	}
13921 #endif
13922 
13923 	_rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
13924 	ret = _FAIL;
13925 
13926 exit:
13927 	return ret;
13928 }
13929 
13930 #ifdef CONFIG_RF_POWER_TRIM
13931 u32 Array_kfreemap[] = {
13932 	0x08, 0xe,
13933 	0x06, 0xc,
13934 	0x04, 0xa,
13935 	0x02, 0x8,
13936 	0x00, 0x6,
13937 	0x03, 0x4,
13938 	0x05, 0x2,
13939 	0x07, 0x0,
13940 	0x09, 0x0,
13941 	0x0c, 0x0,
13942 };
13943 
rtw_bb_rf_gain_offset(_adapter * padapter)13944 void rtw_bb_rf_gain_offset(_adapter *padapter)
13945 {
13946 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
13947 	struct registry_priv  *registry_par = &padapter->registrypriv;
13948 	struct kfree_data_t *kfree_data = &pHalData->kfree_data;
13949 	u8		value = pHalData->EEPROMRFGainOffset;
13950 	u8		tmp = 0x3e;
13951 	u32		res, i = 0;
13952 	u32		ArrayLen	= sizeof(Array_kfreemap) / sizeof(u32);
13953 	u32		*Array = Array_kfreemap;
13954 	u32		v1 = 0, v2 = 0, GainValue = 0, target = 0;
13955 
13956 	if (registry_par->RegPwrTrimEnable == 2) {
13957 		RTW_INFO("Registry kfree default force disable.\n");
13958 		return;
13959 	}
13960 
13961 #if defined(CONFIG_RTL8723B)
13962 	if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
13963 		RTW_INFO("Offset RF Gain.\n");
13964 		RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
13965 
13966 		if (pHalData->EEPROMRFGainVal != 0xff) {
13967 
13968 			if (pHalData->ant_path == RF_PATH_A)
13969 				GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
13970 
13971 			else
13972 				GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
13973 			RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
13974 
13975 			for (i = 0; i < ArrayLen; i += 2) {
13976 				/* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
13977 				v1 = Array[i];
13978 				v2 = Array[i + 1];
13979 				if (v1 == GainValue) {
13980 					RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
13981 					target = v2;
13982 					break;
13983 				}
13984 			}
13985 			RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
13986 
13987 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
13988 			RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
13989 			phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
13990 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
13991 
13992 			RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
13993 
13994 		} else
13995 
13996 			RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x	!= 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
13997 	} else
13998 		RTW_INFO("Using the default RF gain.\n");
13999 
14000 #elif defined(CONFIG_RTL8188E)
14001 	if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
14002 		RTW_INFO("8188ES Offset RF Gain.\n");
14003 		RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
14004 			 pHalData->EEPROMRFGainVal);
14005 
14006 		if (pHalData->EEPROMRFGainVal != 0xff) {
14007 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
14008 					 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
14009 
14010 			RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
14011 			res &= 0xfff87fff;
14012 
14013 			res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
14014 			RTW_INFO("Offset RF Gain. res=0x%x\n", res);
14015 
14016 			rtw_hal_write_rfreg(padapter, RF_PATH_A,
14017 					    REG_RF_BB_GAIN_OFFSET,
14018 					    RF_GAIN_OFFSET_MASK, res);
14019 		} else {
14020 			RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
14021 				 pHalData->EEPROMRFGainVal);
14022 		}
14023 	} else
14024 		RTW_INFO("Using the default RF gain.\n");
14025 #else
14026 	/* TODO: call this when channel switch */
14027 	if (kfree_data->flag & KFREE_FLAG_ON)
14028 		rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
14029 #endif
14030 
14031 }
14032 #endif /*CONFIG_RF_POWER_TRIM */
14033 
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)14034 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
14035 {
14036 #ifdef CONFIG_RF_POWER_TRIM
14037 	int i, j;
14038 
14039 	for (i = 0; i < BB_GAIN_NUM; i++)
14040 		for (j = 0; j < RF_PATH_MAX; j++)
14041 			if (data->bb_gain[i][j] != 0)
14042 				return 0;
14043 #endif
14044 	return 1;
14045 }
14046 
14047 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)14048 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
14049 {
14050 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14051 	if (cur_wireless_mode < WIRELESS_11_24N
14052 	    && cur_wireless_mode > 0) { /* ABG mode */
14053 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14054 		u32 remainder = 0;
14055 		u8 quotient = 0;
14056 
14057 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
14058 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14059 
14060 		if (quotient > 5) {
14061 			pHalData->rxagg_usb_size = 0x6;
14062 			pHalData->rxagg_usb_timeout = 0x10;
14063 		} else {
14064 			if (remainder >= 2048) {
14065 				pHalData->rxagg_usb_size = quotient;
14066 				pHalData->rxagg_usb_timeout = 0x10;
14067 			} else {
14068 				pHalData->rxagg_usb_size = (quotient - 1);
14069 				pHalData->rxagg_usb_timeout = 0x10;
14070 			}
14071 		}
14072 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14073 		if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
14074 			pHalData->rxagg_usb_size = 0x6;
14075 			pHalData->rxagg_usb_timeout = 0x10;
14076 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14077 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14078 		}
14079 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14080 
14081 	} else if (cur_wireless_mode >= WIRELESS_11_24N
14082 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14083 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14084 		u32 remainder = 0;
14085 		u8 quotient = 0;
14086 
14087 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
14088 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14089 
14090 		if (quotient > 5) {
14091 			pHalData->rxagg_usb_size = 0x5;
14092 			pHalData->rxagg_usb_timeout = 0x20;
14093 		} else {
14094 			if (remainder >= 2048) {
14095 				pHalData->rxagg_usb_size = quotient;
14096 				pHalData->rxagg_usb_timeout = 0x10;
14097 			} else {
14098 				pHalData->rxagg_usb_size = (quotient - 1);
14099 				pHalData->rxagg_usb_timeout = 0x10;
14100 			}
14101 		}
14102 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14103 		if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
14104 			pHalData->rxagg_usb_size = 0x5;
14105 			pHalData->rxagg_usb_timeout = 0x20;
14106 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14107 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14108 		}
14109 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14110 
14111 	} else {
14112 		/* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14113 	}
14114 }
14115 
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)14116 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
14117 {
14118 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14119 
14120 	if (cur_wireless_mode < WIRELESS_11_24N
14121 	    && cur_wireless_mode > 0) { /* ABG mode */
14122 		if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
14123 		    || 0x10 != pHalData->rxagg_usb_timeout) {
14124 			pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
14125 			pHalData->rxagg_usb_timeout = 0x10;
14126 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14127 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14128 		}
14129 	} else if (cur_wireless_mode >= WIRELESS_11_24N
14130 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14131 		if (UsbDmaSize != pHalData->rxagg_usb_size
14132 		    || 0x20 != pHalData->rxagg_usb_timeout) {
14133 			pHalData->rxagg_usb_size = UsbDmaSize;
14134 			pHalData->rxagg_usb_timeout = 0x20;
14135 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14136 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14137 		}
14138 	} else {
14139 		/* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14140 	}
14141 }
14142 
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)14143 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
14144 {
14145 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14146 	rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
14147 	return;
14148 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14149 
14150 	rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
14151 }
14152 #endif /* CONFIG_USB_RX_AGGREGATION */
14153 
14154 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)14155 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
14156 {
14157 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
14158 	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
14159 	struct registry_priv *registry_par = &padapter->registrypriv;
14160 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14161 	u8 cur_wireless_mode = WIRELESS_INVALID;
14162 
14163 #ifdef CONFIG_USB_RX_AGGREGATION
14164 	if (!registry_par->dynamic_agg_enable)
14165 		return;
14166 
14167 #ifdef RTW_HALMAC
14168 	if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter)
14169 		|| IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter))
14170 		rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
14171 #else /* !RTW_HALMAC */
14172 	if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
14173 		/* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
14174 		if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) {
14175 			if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14176 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
14177 			else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14178 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
14179 			else
14180 				rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
14181 
14182 			/* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
14183 		}
14184 	} else if (IS_HARDWARE_TYPE_8812(padapter)) {
14185 #ifdef CONFIG_CONCURRENT_MODE
14186 		u8 i;
14187 		_adapter *iface;
14188 		u8 bassocaed = _FALSE;
14189 		struct mlme_ext_priv *mlmeext;
14190 
14191 		for (i = 0; i < pdvobjpriv->iface_nums; i++) {
14192 			iface = pdvobjpriv->padapters[i];
14193 			mlmeext = &iface->mlmeextpriv;
14194 			if (rtw_linked_check(iface) == _TRUE) {
14195 				if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
14196 					cur_wireless_mode = mlmeext->cur_wireless_mode;
14197 				bassocaed = _TRUE;
14198 			}
14199 		}
14200 		if (bassocaed)
14201 #endif
14202 			rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14203 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14204 	} else {
14205 		rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14206 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14207 	}
14208 #endif /* RTW_HALMAC */
14209 #endif /* CONFIG_USB_RX_AGGREGATION */
14210 
14211 }
14212 
14213 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)14214 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
14215 {
14216 #ifdef CONFIG_AP_MODE
14217 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
14218 	u8 chk_rst = _SUCCESS;
14219 
14220 	if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
14221 		return chk_rst;
14222 
14223 	/* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
14224 	/*	return chk_rst; */
14225 
14226 	if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
14227 	    && (pre_qsel != next_qsel)) {
14228 		/* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
14229 		/*	pre_qsel,next_qsel); */
14230 		chk_rst = _FAIL;
14231 	}
14232 	return chk_rst;
14233 #else
14234 	return _SUCCESS;
14235 #endif /* CONFIG_AP_MODE */
14236 }
14237 
14238 #ifdef CONFIG_WOWLAN
14239 /*
14240  * Description:
14241  * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
14242  * contant.
14243  *
14244  * Input:
14245  * adapter: adapter pointer.
14246  * page_num: The max. page number that user want to dump.
14247  * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
14248  */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)14249 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
14250 {
14251 
14252 	int i;
14253 	u8 val = 0;
14254 	u8 base = 0;
14255 	u32 addr = 0;
14256 	u32 count = (page_size / 8);
14257 
14258 	if (page_num <= 0) {
14259 		RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
14260 		return;
14261 	}
14262 
14263 	if (page_size < 128 || page_size > 512) {
14264 		RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
14265 		return;
14266 	}
14267 
14268 	RTW_INFO("+%s+\n", __func__);
14269 	val = rtw_read8(padapter, 0x106);
14270 	rtw_write8(padapter, 0x106, 0x69);
14271 	RTW_INFO("0x106: 0x%02x\n", val);
14272 	base = rtw_read8(padapter, 0x209);
14273 	RTW_INFO("0x209: 0x%02x\n", base);
14274 
14275 	addr = ((base)*page_size) / 8;
14276 	for (i = 0 ; i < page_num * count ; i += 2) {
14277 		rtw_write32(padapter, 0x140, addr + i);
14278 		printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14279 		rtw_write32(padapter, 0x140, addr + i + 1);
14280 		printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14281 	}
14282 }
14283 #endif
14284 
14285 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)14286 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
14287 {
14288 	u8 value = 0;
14289 	u8 direction = 0;
14290 	u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
14291 	u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
14292 	u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
14293 	u8 gpio_num_to_set = gpio_num;
14294 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
14295 
14296 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14297 		return value;
14298 
14299 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14300 
14301 	RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
14302 	LeaveAllPowerSaveModeDirect(adapter);
14303 
14304 	if (gpio_num > 7) {
14305 		gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
14306 		gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
14307 		gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
14308 		gpio_num_to_set = gpio_num - 8;
14309 	}
14310 
14311 	/* Read GPIO Direction */
14312 	direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14313 
14314 	/* According the direction to read register value */
14315 	if (direction)
14316 		value =  (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14317 	else
14318 		value =  (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14319 
14320 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14321 	RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
14322 
14323 	return value;
14324 }
14325 
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)14326 int  rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
14327 {
14328 	u8 direction = 0;
14329 	u8 res = -1;
14330 	u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
14331 	u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
14332 	u8 gpio_num_to_set = gpio_num;
14333 
14334 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14335 		return -1;
14336 
14337 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14338 
14339 	LeaveAllPowerSaveModeDirect(adapter);
14340 
14341 	if (gpio_num > 7) {
14342 		gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
14343 		gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
14344 		gpio_num_to_set = gpio_num - 8;
14345 	}
14346 
14347 	/* Read GPIO direction */
14348 	direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14349 
14350 	/* If GPIO is output direction, setting value. */
14351 	if (direction) {
14352 		if (isHigh)
14353 			rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
14354 		else
14355 			rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
14356 
14357 		RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
14358 		res = 0;
14359 	} else {
14360 		RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
14361 		res = -1;
14362 	}
14363 
14364 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14365 	return res;
14366 }
14367 
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)14368 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
14369 {
14370 	u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
14371 	u8 gpio_num_to_set = gpio_num;
14372 
14373 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14374 		return -1;
14375 
14376 	RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
14377 
14378 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14379 
14380 	LeaveAllPowerSaveModeDirect(adapter);
14381 
14382 	rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
14383 
14384 	if (gpio_num > 7) {
14385 		gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
14386 		gpio_num_to_set = gpio_num - 8;
14387 	}
14388 
14389 	if (isOutput)
14390 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
14391 	else
14392 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
14393 
14394 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14395 
14396 	return 0;
14397 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))14398 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
14399 {
14400 	u8 value;
14401 	u8 direction;
14402 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
14403 
14404 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
14405 		if (gpio_num > 7 || gpio_num < 4) {
14406 			RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
14407 			return -1;
14408 		}
14409 	}
14410 
14411 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14412 
14413 	LeaveAllPowerSaveModeDirect(adapter);
14414 
14415 	/* Read GPIO direction */
14416 	direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
14417 	if (direction) {
14418 		RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
14419 		return -1;
14420 	}
14421 
14422 	/* Config GPIO Mode */
14423 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
14424 
14425 	/* Register GPIO interrupt handler*/
14426 	adapter->gpiointpriv.callback[gpio_num] = callback;
14427 
14428 	/* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
14429 	value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
14430 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
14431 	rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
14432 
14433 	/* Enable GPIO interrupt */
14434 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
14435 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
14436 
14437 	rtw_hal_update_hisr_hsisr_ind(adapter, 1);
14438 
14439 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14440 
14441 	return 0;
14442 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)14443 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
14444 {
14445 	u8 value;
14446 	u8 direction;
14447 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
14448 
14449 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
14450 		if (gpio_num > 7 || gpio_num < 4) {
14451 			RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
14452 			return -1;
14453 		}
14454 	}
14455 
14456 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14457 
14458 	LeaveAllPowerSaveModeDirect(adapter);
14459 
14460 	/* Config GPIO Mode */
14461 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
14462 
14463 	/* Unregister GPIO interrupt handler*/
14464 	adapter->gpiointpriv.callback[gpio_num] = NULL;
14465 
14466 	/* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
14467 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
14468 	rtw_write8(adapter, REG_GPIO_INTM, 0x00);
14469 
14470 	/* Disable GPIO interrupt */
14471 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
14472 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
14473 
14474 	if (!adapter->gpiointpriv.interrupt_enable_mask)
14475 		rtw_hal_update_hisr_hsisr_ind(adapter, 0);
14476 
14477 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14478 
14479 	return 0;
14480 }
14481 #endif
14482 
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)14483 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
14484 {
14485 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14486 	u8 i;
14487 
14488 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
14489 		if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
14490 			if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
14491 			    && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
14492 				return i;
14493 		}
14494 	}
14495 
14496 	return -1;
14497 }
14498 
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)14499 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
14500 {
14501 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14502 	s8 res;
14503 	u8 i;
14504 
14505 	/* If it's an existed record, overwrite it */
14506 	res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
14507 	if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
14508 		rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
14509 		return;
14510 	}
14511 
14512 	/* Search for the empty record to use */
14513 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
14514 		if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
14515 			rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
14516 			return;
14517 		}
14518 	}
14519 
14520 	/* Else, overwrite the oldest record */
14521 	for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
14522 		_rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
14523 
14524 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
14525 }
14526 
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)14527 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
14528 {
14529 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
14530 }
14531 
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14532 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14533 {
14534 	u32	mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
14535 	u32	mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
14536 	u32	mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
14537 	u32	DropPacket = 0;
14538 
14539 	if (!rx_counter) {
14540 		rtw_warn_on(1);
14541 		return;
14542 	}
14543 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
14544 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14545 
14546 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
14547 	mac_cck_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	  */
14548 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
14549 	mac_ofdm_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14550 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
14551 	mac_ht_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14552 	mac_vht_ok	= 0;
14553 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14554 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
14555 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
14556 		mac_vht_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
14557 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14558 	}
14559 
14560 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
14561 	mac_cck_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14562 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
14563 	mac_ofdm_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14564 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
14565 	mac_ht_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
14566 	mac_vht_err	= 0;
14567 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14568 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
14569 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
14570 		mac_vht_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
14571 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14572 	}
14573 
14574 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
14575 	mac_cck_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14576 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
14577 	mac_ofdm_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14578 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
14579 	mac_ht_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
14580 
14581 	/* Mac_DropPacket */
14582 	rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
14583 	DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
14584 
14585 	rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
14586 	rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
14587 	rx_counter->rx_cck_fa = mac_cck_fa;
14588 	rx_counter->rx_ofdm_fa = mac_ofdm_fa;
14589 	rx_counter->rx_ht_fa = mac_ht_fa;
14590 	rx_counter->rx_pkt_drop = DropPacket;
14591 }
rtw_reset_mac_rx_counters(_adapter * padapter)14592 void rtw_reset_mac_rx_counters(_adapter *padapter)
14593 {
14594 
14595 	/* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
14596 	if (IS_HARDWARE_TYPE_8703B(padapter) ||
14597 		IS_HARDWARE_TYPE_8723D(padapter) ||
14598 		IS_HARDWARE_TYPE_8188F(padapter) ||
14599 		IS_HARDWARE_TYPE_8188GTV(padapter) ||
14600 		IS_HARDWARE_TYPE_8192F(padapter) ||
14601 		IS_HARDWARE_TYPE_8822C(padapter))
14602 		phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
14603 
14604 	/* reset mac counter */
14605 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
14606 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
14607 }
14608 
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14609 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14610 {
14611 	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;
14612 	if (!rx_counter) {
14613 		rtw_warn_on(1);
14614 		return;
14615 	}
14616 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14617 		cckok	= phy_query_bb_reg(padapter, 0xF04, 0x3FFF);	     /* [13:0] */
14618 		ofdmok	= phy_query_bb_reg(padapter, 0xF14, 0x3FFF);	     /* [13:0] */
14619 		htok		= phy_query_bb_reg(padapter, 0xF10, 0x3FFF);     /* [13:0] */
14620 		vht_ok	= phy_query_bb_reg(padapter, 0xF0C, 0x3FFF);     /* [13:0] */
14621 		cckcrc	= phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16]	 */
14622 		ofdmcrc	= phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
14623 		htcrc	= phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
14624 		vht_err	= phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
14625 		CCK_FA	= phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
14626 		OFDM_FA	= phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
14627 	} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)){
14628 		cckok = phy_query_bb_reg(padapter, 0x2c04, 0xffff);
14629 		ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
14630 		htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
14631 		vht_ok = phy_query_bb_reg(padapter, 0x2c0c, 0xffff);
14632 		cckcrc = phy_query_bb_reg(padapter, 0x2c04, 0xffff0000);
14633 		ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
14634 		htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
14635 		vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000);
14636 		CCK_FA	= phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord);
14637 		OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
14638 
14639 	} else {
14640 		cckok	= phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
14641 		ofdmok	= phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
14642 		htok		= phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
14643 		vht_ok	= 0;
14644 		cckcrc	= phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
14645 		ofdmcrc	= phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
14646 		htcrc	= phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
14647 		vht_err	= 0;
14648 		OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +
14649 			phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
14650 			phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
14651 
14652 		CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
14653 	}
14654 
14655 	rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
14656 	rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
14657 	rx_counter->rx_ofdm_fa = OFDM_FA;
14658 	rx_counter->rx_cck_fa = CCK_FA;
14659 
14660 }
14661 
rtw_reset_phy_trx_ok_counters(_adapter * padapter)14662 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
14663 {
14664 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14665 		phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
14666 		phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
14667 	} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
14668 		phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1);
14669 		phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0);
14670 	} else {
14671 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
14672 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
14673 	}
14674 }
14675 
rtw_reset_phy_rx_counters(_adapter * padapter)14676 void rtw_reset_phy_rx_counters(_adapter *padapter)
14677 {
14678 	/* reset phy counter */
14679 	if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
14680 		/* reset CCK FA counter */
14681 		phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 0);
14682 		phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 2);
14683 
14684 		/* reset CCK CCA counter */
14685 		phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0);
14686 		phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2);
14687 		rtw_reset_phy_trx_ok_counters(padapter);
14688 
14689 	} else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14690 		rtw_reset_phy_trx_ok_counters(padapter);
14691 
14692 		phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset  OFDA FA counter */
14693 		phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
14694 
14695 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
14696 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
14697 	} else {
14698 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
14699 		rtw_msleep_os(10);
14700 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
14701 
14702 		phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset  OFDA FA counter */
14703 		phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset  OFDA FA counter */
14704 		phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
14705 		phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
14706 
14707 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
14708 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
14709 	}
14710 }
14711 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14712 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14713 {
14714 	struct recv_priv *precvpriv = &padapter->recvpriv;
14715 	if (!rx_counter) {
14716 		rtw_warn_on(1);
14717 		return;
14718 	}
14719 	rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
14720 	rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
14721 	rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
14722 }
rtw_reset_drv_rx_counters(_adapter * padapter)14723 void rtw_reset_drv_rx_counters(_adapter *padapter)
14724 {
14725 	struct recv_priv *precvpriv = &padapter->recvpriv;
14726 	padapter->drv_rx_cnt_ok = 0;
14727 	padapter->drv_rx_cnt_crcerror = 0;
14728 	padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
14729 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)14730 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
14731 {
14732 	u8 initialgain;
14733 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14734 
14735 	if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
14736 		rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
14737 		RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
14738 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
14739 		/*disable dynamic functions, such as high power, DIG*/
14740 		rtw_phydm_ability_backup(padapter);
14741 		rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
14742 	} else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
14743 		/* turn on phy-dynamic functions */
14744 		rtw_phydm_ability_restore(padapter);
14745 		initialgain = 0xff; /* restore RX GAIN */
14746 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
14747 
14748 	}
14749 }
14750 
rtw_dump_rx_counters(_adapter * padapter)14751 void rtw_dump_rx_counters(_adapter *padapter)
14752 {
14753 	struct dbg_rx_counter rx_counter;
14754 
14755 	if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
14756 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14757 		rtw_dump_drv_rx_counters(padapter, &rx_counter);
14758 		RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
14759 			rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
14760 		rtw_reset_drv_rx_counters(padapter);
14761 	}
14762 
14763 	if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
14764 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14765 		rtw_dump_mac_rx_counters(padapter, &rx_counter);
14766 		RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
14767 			 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
14768 			rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
14769 			 rx_counter.rx_pkt_drop);
14770 		rtw_reset_mac_rx_counters(padapter);
14771 	}
14772 
14773 	if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
14774 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14775 		rtw_dump_phy_rx_counters(padapter, &rx_counter);
14776 		/* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
14777 		/* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
14778 		RTW_INFO("Phy Received packet OK:%d CRC error:%d FA Counter: %d\n", rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
14779 			 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
14780 		rtw_reset_phy_rx_counters(padapter);
14781 	}
14782 }
14783 #endif
rtw_get_current_tx_sgi(_adapter * padapter,struct sta_info * psta)14784 u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
14785 {
14786 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14787 	u8 curr_tx_sgi = 0;
14788 	struct ra_sta_info *ra_info;
14789 
14790 	if (!psta)
14791 		return curr_tx_sgi;
14792 
14793 	if (padapter->fix_rate == 0xff) {
14794 #if defined(CONFIG_RTL8188E)
14795 #if (RATE_ADAPTIVE_SUPPORT == 1)
14796 		curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;
14797 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
14798 #else
14799 		ra_info = &psta->cmn.ra_info;
14800 		curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
14801 #endif
14802 	} else {
14803 		curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;
14804 	}
14805 
14806 	return curr_tx_sgi;
14807 }
14808 
rtw_get_current_tx_rate(_adapter * padapter,struct sta_info * psta)14809 u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
14810 {
14811 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14812 	u8 rate_id = 0;
14813 	struct ra_sta_info *ra_info;
14814 
14815 	if (!psta)
14816 		return rate_id;
14817 
14818 	if (padapter->fix_rate == 0xff) {
14819 #if defined(CONFIG_RTL8188E)
14820 #if (RATE_ADAPTIVE_SUPPORT == 1)
14821 		rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;
14822 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
14823 #else
14824 		ra_info = &psta->cmn.ra_info;
14825 		rate_id = ra_info->curr_tx_rate & 0x7f;
14826 #endif
14827 	} else {
14828 		rate_id = padapter->fix_rate & 0x7f;
14829 	}
14830 
14831 	return rate_id;
14832 }
14833 
update_IOT_info(_adapter * padapter)14834 void update_IOT_info(_adapter *padapter)
14835 {
14836 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
14837 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14838 
14839 	switch (pmlmeinfo->assoc_AP_vendor) {
14840 	case HT_IOT_PEER_MARVELL:
14841 		pmlmeinfo->turboMode_cts2self = 1;
14842 		pmlmeinfo->turboMode_rtsen = 0;
14843 		break;
14844 
14845 	case HT_IOT_PEER_RALINK:
14846 		pmlmeinfo->turboMode_cts2self = 0;
14847 		pmlmeinfo->turboMode_rtsen = 1;
14848 		break;
14849 	case HT_IOT_PEER_REALTEK:
14850 		/* rtw_write16(padapter, 0x4cc, 0xffff); */
14851 		/* rtw_write16(padapter, 0x546, 0x01c0); */
14852 		break;
14853 	default:
14854 		pmlmeinfo->turboMode_cts2self = 0;
14855 		pmlmeinfo->turboMode_rtsen = 1;
14856 		break;
14857 	}
14858 
14859 }
14860 #ifdef CONFIG_RTS_FULL_BW
14861 /*
14862 8188E: not support full RTS BW feature(mac REG no define 480[5])
14863 */
rtw_set_rts_bw(_adapter * padapter)14864 void rtw_set_rts_bw(_adapter *padapter) {
14865 	int i;
14866 	u8 enable = 1;
14867 	bool connect_to_8812 = _FALSE;
14868 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14869 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14870 	struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
14871 	struct sta_info *station = NULL;
14872 
14873 	for (i = 0; i < macid_ctl->num; i++) {
14874 		if (rtw_macid_is_used(macid_ctl, i)) {
14875 
14876 			station = NULL;
14877 			station = macid_ctl->sta[i];
14878 			if(station) {
14879 
14880 				 _adapter *sta_adapter =station->padapter;
14881 				struct mlme_ext_priv	*pmlmeext = &(sta_adapter->mlmeextpriv);
14882 				struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14883 
14884 				if ( pmlmeinfo->state != WIFI_FW_NULL_STATE) {
14885 					if(_rtw_memcmp(macid_ctl->sta[i]->cmn.mac_addr, bc_addr, ETH_ALEN) !=  _TRUE) {
14886 						if (  macid_ctl->sta[i]->vendor_8812) {
14887 							connect_to_8812 = _TRUE;
14888 							enable = 0;
14889 						}
14890 					}
14891 				}
14892 			}
14893 		}
14894 
14895 		if(connect_to_8812)
14896 			break;
14897 	}
14898 
14899 		RTW_INFO("%s connect_to_8812=%d,enable=%u\n", __FUNCTION__,connect_to_8812,enable);
14900 		rtw_hal_set_hwreg(padapter, HW_VAR_SET_RTS_BW, &enable);
14901 }
14902 #endif/*CONFIG_RTS_FULL_BW*/
14903 
hal_spec_init(_adapter * adapter)14904 int hal_spec_init(_adapter *adapter)
14905 {
14906 	u8 interface_type = 0;
14907 	int ret = _SUCCESS;
14908 
14909 	interface_type = rtw_get_intf_type(adapter);
14910 
14911 	switch (rtw_get_chip_type(adapter)) {
14912 #ifdef CONFIG_RTL8723B
14913 	case RTL8723B:
14914 		init_hal_spec_8723b(adapter);
14915 		break;
14916 #endif
14917 #ifdef CONFIG_RTL8703B
14918 	case RTL8703B:
14919 		init_hal_spec_8703b(adapter);
14920 		break;
14921 #endif
14922 #ifdef CONFIG_RTL8723D
14923 	case RTL8723D:
14924 		init_hal_spec_8723d(adapter);
14925 		break;
14926 #endif
14927 #ifdef CONFIG_RTL8188E
14928 	case RTL8188E:
14929 		init_hal_spec_8188e(adapter);
14930 		break;
14931 #endif
14932 #ifdef CONFIG_RTL8188F
14933 	case RTL8188F:
14934 		init_hal_spec_8188f(adapter);
14935 		break;
14936 #endif
14937 #ifdef CONFIG_RTL8188GTV
14938 	case RTL8188GTV:
14939 		init_hal_spec_8188gtv(adapter);
14940 		break;
14941 #endif
14942 #ifdef CONFIG_RTL8812A
14943 	case RTL8812:
14944 		init_hal_spec_8812a(adapter);
14945 		break;
14946 #endif
14947 #ifdef CONFIG_RTL8821A
14948 	case RTL8821:
14949 		init_hal_spec_8821a(adapter);
14950 		break;
14951 #endif
14952 #ifdef CONFIG_RTL8192E
14953 	case RTL8192E:
14954 		init_hal_spec_8192e(adapter);
14955 		break;
14956 #endif
14957 #ifdef CONFIG_RTL8814A
14958 	case RTL8814A:
14959 		init_hal_spec_8814a(adapter);
14960 		break;
14961 #endif
14962 #ifdef CONFIG_RTL8822B
14963 	case RTL8822B:
14964 		rtl8822b_init_hal_spec(adapter);
14965 		break;
14966 #endif
14967 #ifdef CONFIG_RTL8821C
14968 	case RTL8821C:
14969 		init_hal_spec_rtl8821c(adapter);
14970 		break;
14971 #endif
14972 #ifdef CONFIG_RTL8710B
14973 	case RTL8710B:
14974 		init_hal_spec_8710b(adapter);
14975 		break;
14976 #endif
14977 #ifdef CONFIG_RTL8192F
14978 	case RTL8192F:
14979 		init_hal_spec_8192f(adapter);
14980 		break;
14981 #endif
14982 #ifdef CONFIG_RTL8822C
14983 	case RTL8822C:
14984 		rtl8822c_init_hal_spec(adapter);
14985 		break;
14986 #endif
14987 #ifdef CONFIG_RTL8814B
14988 	case RTL8814B:
14989 		rtl8814b_init_hal_spec(adapter);
14990 		break;
14991 #endif
14992 	default:
14993 		RTW_ERR("%s: unknown chip_type:%u\n"
14994 			, __func__, rtw_get_chip_type(adapter));
14995 		ret = _FAIL;
14996 		break;
14997 	}
14998 
14999 	return ret;
15000 }
15001 
15002 static const char *const _band_cap_str[] = {
15003 	/* BIT0 */"2G",
15004 	/* BIT1 */"5G",
15005 };
15006 
15007 static const char *const _bw_cap_str[] = {
15008 	/* BIT0 */"5M",
15009 	/* BIT1 */"10M",
15010 	/* BIT2 */"20M",
15011 	/* BIT3 */"40M",
15012 	/* BIT4 */"80M",
15013 	/* BIT5 */"160M",
15014 	/* BIT6 */"80_80M",
15015 };
15016 
15017 static const char *const _proto_cap_str[] = {
15018 	/* BIT0 */"b",
15019 	/* BIT1 */"g",
15020 	/* BIT2 */"n",
15021 	/* BIT3 */"ac",
15022 };
15023 
15024 static const char *const _wl_func_str[] = {
15025 	/* BIT0 */"P2P",
15026 	/* BIT1 */"MIRACAST",
15027 	/* BIT2 */"TDLS",
15028 	/* BIT3 */"FTM",
15029 };
15030 
dump_hal_spec(void * sel,_adapter * adapter)15031 void dump_hal_spec(void *sel, _adapter *adapter)
15032 {
15033 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15034 	int i;
15035 
15036 	RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
15037 	RTW_PRINT_SEL(sel, "macid_cap:%u\n", hal_spec->macid_cap);
15038 	RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
15039 	RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
15040 
15041 	RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
15042 	RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
15043 	RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num);
15044 	RTW_PRINT_SEL(sel, "rf_reg_path_avail_num:%u\n", hal_spec->rf_reg_path_avail_num);
15045 	RTW_PRINT_SEL(sel, "rf_reg_trx_path_bmp:0x%02x\n", hal_spec->rf_reg_trx_path_bmp);
15046 	RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
15047 
15048 	RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
15049 	RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
15050 
15051 	RTW_PRINT_SEL(sel, "band_cap:");
15052 	for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
15053 		if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
15054 			_RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
15055 	}
15056 	_RTW_PRINT_SEL(sel, "\n");
15057 
15058 	RTW_PRINT_SEL(sel, "bw_cap:");
15059 	for (i = 0; i < BW_CAP_BIT_NUM; i++) {
15060 		if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
15061 			_RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
15062 	}
15063 	_RTW_PRINT_SEL(sel, "\n");
15064 
15065 	RTW_PRINT_SEL(sel, "proto_cap:");
15066 	for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
15067 		if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
15068 			_RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
15069 	}
15070 	_RTW_PRINT_SEL(sel, "\n");
15071 
15072 	RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);
15073 	RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);
15074 
15075 	RTW_PRINT_SEL(sel, "wl_func:");
15076 	for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
15077 		if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
15078 			_RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
15079 	}
15080 	_RTW_PRINT_SEL(sel, "\n");
15081 
15082 #if CONFIG_TX_AC_LIFETIME
15083 	RTW_PRINT_SEL(sel, "tx_aclt_unit_factor:%u (unit:%uus)\n"
15084 		, hal_spec->tx_aclt_unit_factor, hal_spec->tx_aclt_unit_factor * 32);
15085 #endif
15086 
15087 	RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);
15088 
15089 	RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);
15090 	RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);
15091 }
15092 
hal_chk_band_cap(_adapter * adapter,u8 cap)15093 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
15094 {
15095 	return GET_HAL_SPEC(adapter)->band_cap & cap;
15096 }
15097 
hal_chk_bw_cap(_adapter * adapter,u8 cap)15098 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
15099 {
15100 	return GET_HAL_SPEC(adapter)->bw_cap & cap;
15101 }
15102 
hal_chk_proto_cap(_adapter * adapter,u8 cap)15103 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
15104 {
15105 	return GET_HAL_SPEC(adapter)->proto_cap & cap;
15106 }
15107 
hal_chk_wl_func(_adapter * adapter,u8 func)15108 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
15109 {
15110 	return GET_HAL_SPEC(adapter)->wl_func & func;
15111 }
15112 
hal_is_band_support(_adapter * adapter,u8 band)15113 inline bool hal_is_band_support(_adapter *adapter, u8 band)
15114 {
15115 	return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
15116 }
15117 
hal_is_bw_support(_adapter * adapter,u8 bw)15118 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
15119 {
15120 	return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
15121 }
15122 
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)15123 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
15124 {
15125 	u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
15126 
15127 	if (mode == WIRELESS_11B)
15128 		if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15129 			return 1;
15130 
15131 	if (mode == WIRELESS_11G)
15132 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15133 			return 1;
15134 
15135 	if (mode == WIRELESS_11A)
15136 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15137 			return 1;
15138 
15139 	if (mode == WIRELESS_11_24N)
15140 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15141 			return 1;
15142 
15143 	if (mode == WIRELESS_11_5N)
15144 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15145 			return 1;
15146 
15147 	if (mode == WIRELESS_11AC)
15148 		if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15149 			return 1;
15150 
15151 	return 0;
15152 }
hal_is_mimo_support(_adapter * adapter)15153 inline bool hal_is_mimo_support(_adapter *adapter)
15154 {
15155 	if ((GET_HAL_TX_NSS(adapter) == 1) &&
15156 		(GET_HAL_RX_NSS(adapter) == 1))
15157 		return 0;
15158 	return 1;
15159 }
15160 
15161 /*
15162 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
15163 * @adapter:
15164 * @in_bw: starting bw, value of enum channel_width
15165 *
15166 * Returns: value of enum channel_width
15167 */
hal_largest_bw(_adapter * adapter,u8 in_bw)15168 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
15169 {
15170 	for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
15171 		if (hal_is_bw_support(adapter, in_bw))
15172 			break;
15173 	}
15174 
15175 	if (!hal_is_bw_support(adapter, in_bw))
15176 		rtw_warn_on(1);
15177 
15178 	return in_bw;
15179 }
15180 
15181 #ifndef CONFIG_HAS_TX_BEACON_PAUSE
ResumeTxBeacon(_adapter * padapter)15182 void ResumeTxBeacon(_adapter *padapter)
15183 {
15184 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15185 		rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
15186 
15187 #ifdef RTW_HALMAC
15188 	/* Add this for driver using HALMAC because driver doesn't have setup time init by self */
15189 	/* TBTT setup time */
15190 	rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
15191 #endif
15192 
15193 	/* TBTT hold time: 0x540[19:8] */
15194 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
15195 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15196 		(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
15197 }
15198 
StopTxBeacon(_adapter * padapter)15199 void StopTxBeacon(_adapter *padapter)
15200 {
15201 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15202 		rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
15203 
15204 	/* TBTT hold time: 0x540[19:8] */
15205 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
15206 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15207 		(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
15208 }
15209 #endif /* CONFIG_HAS_TX_BEACON_PAUSE */
15210 
15211 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
15212 
15213 #ifdef CONFIG_CLIENT_PORT_CFG
15214 const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {
15215 	CLT_PORT0,
15216 	CLT_PORT1,
15217 	CLT_PORT2,
15218 	CLT_PORT3
15219 };
15220 
rtw_clt_port_init(struct clt_port_t * cltp)15221 void rtw_clt_port_init(struct clt_port_t  *cltp)
15222 {
15223 	cltp->bmp = 0;
15224 	cltp->num = 0;
15225 	_rtw_spinlock_init(&cltp->lock);
15226 }
rtw_clt_port_deinit(struct clt_port_t * cltp)15227 void rtw_clt_port_deinit(struct clt_port_t *cltp)
15228 {
15229 	_rtw_spinlock_free(&cltp->lock);
15230 }
_hw_client_port_alloc(_adapter * adapter)15231 static void _hw_client_port_alloc(_adapter *adapter)
15232 {
15233 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15234 	struct clt_port_t  *cltp = &dvobj->clt_port;
15235 	_irqL irql;
15236 	int i;
15237 
15238 	#if 0
15239 	if (cltp->num > MAX_CLIENT_PORT_NUM) {
15240 		RTW_ERR(ADPT_FMT" cann't  alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);
15241 		rtw_warn_on(1);
15242 		return;
15243 	}
15244 	#endif
15245 
15246 	if (adapter->client_id !=  MAX_CLIENT_PORT_NUM) {
15247 		RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",
15248 			ADPT_ARG(adapter), adapter->client_id, adapter->client_port);
15249 		return;
15250 	}
15251 	_enter_critical_bh(&cltp->lock, &irql);
15252 	for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {
15253 		if (!(cltp->bmp & BIT(i)))
15254 			break;
15255 	}
15256 
15257 	if (i < MAX_CLIENT_PORT_NUM) {
15258 		adapter->client_id = i;
15259 		cltp->bmp |= BIT(i);
15260 		adapter->client_port = _clt_port_id[i];
15261 	}
15262 	cltp->num++;
15263 	_exit_critical_bh(&cltp->lock, &irql);
15264 	RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",
15265 		__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
15266 }
_hw_client_port_free(_adapter * adapter)15267 static void _hw_client_port_free(_adapter *adapter)
15268 {
15269 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15270 	struct clt_port_t  *cltp = &dvobj->clt_port;
15271 	_irqL irql;
15272 
15273 	#if 0
15274 	if (adapter->client_id >=  MAX_CLIENT_PORT_NUM) {
15275 		RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);
15276 		/*rtw_warn_on(1);*/
15277 	}
15278 	#endif
15279 
15280 	RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",
15281 		__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
15282 
15283 	_enter_critical_bh(&cltp->lock, &irql);
15284 	if (adapter->client_id !=  MAX_CLIENT_PORT_NUM) {
15285 		cltp->bmp &= ~ BIT(adapter->client_id);
15286 		adapter->client_id = MAX_CLIENT_PORT_NUM;
15287 		adapter->client_port = CLT_PORT_INVALID;
15288 	}
15289 	cltp->num--;
15290 	if (cltp->num < 0)
15291 		cltp->num = 0;
15292 	_exit_critical_bh(&cltp->lock, &irql);
15293 }
rtw_hw_client_port_allocate(_adapter * adapter)15294 void rtw_hw_client_port_allocate(_adapter *adapter)
15295 {
15296 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15297 
15298 	if (hal_spec->port_num != 5)
15299 		return;
15300 
15301 	_hw_client_port_alloc(adapter);
15302 }
rtw_hw_client_port_release(_adapter * adapter)15303 void rtw_hw_client_port_release(_adapter *adapter)
15304 {
15305 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15306 
15307 	if (hal_spec->port_num != 5)
15308 		return;
15309 
15310 	_hw_client_port_free(adapter);
15311 }
15312 #endif /*CONFIG_CLIENT_PORT_CFG*/
15313 
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)15314 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
15315 {
15316 	RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
15317 
15318 	rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
15319 
15320 	/* set net_type */
15321 	Set_MSR(Adapter, mode);
15322 
15323 	if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
15324 		if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
15325 			StopTxBeacon(Adapter);
15326 	} else if (mode == _HW_STATE_ADHOC_)
15327 		ResumeTxBeacon(Adapter);
15328 	else if (mode == _HW_STATE_AP_)
15329 		/* enable rx ps-poll */
15330 		rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);
15331 
15332 	/* enable rx data frame */
15333 	rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
15334 
15335 #ifdef CONFIG_CLIENT_PORT_CFG
15336 	if (mode == _HW_STATE_STATION_)
15337 		rtw_hw_client_port_allocate(Adapter);
15338 	else
15339 		rtw_hw_client_port_release(Adapter);
15340 #endif
15341 #if defined(CONFIG_RTL8192F)
15342 		rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,
15343 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
15344 #endif
15345 }
15346 #endif
15347 
15348 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)15349 u8	rtw_hal_antdiv_before_linked(_adapter *padapter)
15350 {
15351 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15352 	u8 cur_ant, change_ant;
15353 
15354 	if (!pHalData->AntDivCfg)
15355 		return _FALSE;
15356 
15357 	if (pHalData->sw_antdiv_bl_state == 0) {
15358 		pHalData->sw_antdiv_bl_state = 1;
15359 
15360 		rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
15361 		change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
15362 
15363 		return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
15364 	}
15365 
15366 	pHalData->sw_antdiv_bl_state = 0;
15367 	return _FALSE;
15368 }
15369 
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)15370 void	rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
15371 {
15372 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15373 
15374 	if (pHalData->AntDivCfg) {
15375 		/*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
15376 		/*select optimum_antenna for before linked =>For antenna diversity*/
15377 		if (dst->Rssi >=  src->Rssi) {/*keep org parameter*/
15378 			src->Rssi = dst->Rssi;
15379 			src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
15380 		}
15381 	}
15382 }
15383 #endif
15384 
15385 #ifdef CONFIG_PROC_DEBUG
15386 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap_by_phydmapi(void * sel,_adapter * adapter)15387 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
15388 {
15389 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
15390 	struct phy_spec_t *phy_spec = &pHalData->phy_spec;
15391 
15392 	RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
15393 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
15394 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
15395 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index	[15:8]*/
15396 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index	[7:0]*/
15397 
15398 	RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
15399 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Tx : %s\n", ((phy_spec->stbc_cap >> 24) & 0xFF) ? "Supported" : "N/A"); /*VHT STBC Tx [31:24]*/
15400 	/*VHT STBC Rx [23:16]
15401 	0 = not support
15402 	1 = support for 1 spatial stream
15403 	2 = support for 1 or 2 spatial streams
15404 	3 = support for 1 or 2 or 3 spatial streams
15405 	4 = support for 1 or 2 or 3 or 4 spatial streams*/
15406 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
15407 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Tx : %s\n", ((phy_spec->stbc_cap >> 8) & 0xFF) ? "Supported" : "N/A"); /*HT STBC Tx [15:8]*/
15408 	/*HT STBC Rx [7:0]
15409 	0 = not support
15410 	1 = support for 1 spatial stream
15411 	2 = support for 1 or 2 spatial streams
15412 	3 = support for 1 or 2 or 3 spatial streams*/
15413 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
15414 
15415 	RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
15416 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT LDPC Tx : %s\n", ((phy_spec->ldpc_cap >> 24) & 0xFF) ? "Supported" : "N/A"); /*VHT LDPC Tx [31:24]*/
15417 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT LDPC Rx : %s\n", ((phy_spec->ldpc_cap >> 16) & 0xFF) ? "Supported" : "N/A"); /*VHT LDPC Rx [23:16]*/
15418 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Tx : %s\n", ((phy_spec->ldpc_cap >> 8) & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Tx [15:8]*/
15419 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Rx : %s\n\n", (phy_spec->ldpc_cap & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Rx [7:0]*/
15420 	#ifdef CONFIG_BEAMFORMING
15421 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
15422 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT MU Bfer : %s\n", ((phy_spec->txbf_cap >> 28) & 0xF) ? "Supported" : "N/A"); /*VHT MU Bfer [31:28]*/
15423 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT MU Bfee : %s\n", ((phy_spec->txbf_cap >> 24) & 0xF) ? "Supported" : "N/A"); /*VHT MU Bfee [27:24]*/
15424 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT SU Bfer : %s\n", ((phy_spec->txbf_cap >> 20) & 0xF) ? "Supported" : "N/A"); /*VHT SU Bfer [23:20]*/
15425 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT SU Bfee : %s\n", ((phy_spec->txbf_cap >> 16) & 0xF) ? "Supported" : "N/A"); /*VHT SU Bfee [19:16]*/
15426 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF)  ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
15427 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
15428 
15429 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
15430 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
15431 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
15432 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
15433 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
15434 	#endif
15435 }
15436 #else
rtw_dump_phy_cap_by_hal(void * sel,_adapter * adapter)15437 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
15438 {
15439 	u8 phy_cap = _FALSE;
15440 
15441 	/* STBC */
15442 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
15443 	RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15444 
15445 	phy_cap = _FALSE;
15446 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
15447 	RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15448 
15449 	/* LDPC support */
15450 	phy_cap = _FALSE;
15451 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
15452 	RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15453 
15454 	phy_cap = _FALSE;
15455 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
15456 	RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15457 
15458 	#ifdef CONFIG_BEAMFORMING
15459 	phy_cap = _FALSE;
15460 	rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
15461 	RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15462 
15463 	phy_cap = _FALSE;
15464 	rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
15465 	RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15466 
15467 	phy_cap = _FALSE;
15468 	rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
15469 	RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15470 
15471 	phy_cap = _FALSE;
15472 	rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
15473 	RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15474 	#endif
15475 }
15476 #endif
rtw_dump_phy_cap(void * sel,_adapter * adapter)15477 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
15478 {
15479 	RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
15480 #ifdef CONFIG_PHY_CAPABILITY_QUERY
15481 	rtw_dump_phy_cap_by_phydmapi(sel, adapter);
15482 #else
15483 	rtw_dump_phy_cap_by_hal(sel, adapter);
15484 #endif
15485 }
15486 #endif
15487 
translate_dbm_to_percentage(s16 signal)15488 inline s16 translate_dbm_to_percentage(s16 signal)
15489 {
15490 	if ((signal <= -100) || (signal >= 20))
15491 		return	0;
15492 	else if (signal >= 0)
15493 		return	100;
15494 	else
15495 		return 100 + signal;
15496 }
15497 
15498 #ifdef CONFIG_SWTIMER_BASED_TXBCN
15499 #ifdef CONFIG_BCN_RECOVERY
15500 #define REG_CPU_MGQ_INFO	0x041C
15501 #define BIT_BCN_POLL			BIT(28)
rtw_ap_bcn_recovery(_adapter * padapter)15502 u8 rtw_ap_bcn_recovery(_adapter *padapter)
15503 {
15504 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15505 
15506 	if (hal_data->issue_bcn_fail >= 2) {
15507 		RTW_ERR("%s ISSUE BCN Fail\n", __func__);
15508 		rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
15509 		hal_data->issue_bcn_fail = 0;
15510 	}
15511 	return _SUCCESS;
15512 }
15513 #endif /*CONFIG_BCN_RECOVERY*/
15514 
15515 #ifdef CONFIG_BCN_XMIT_PROTECT
rtw_ap_bcn_queue_empty_check(_adapter * padapter,u32 txbcn_timer_ms)15516 u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
15517 {
15518 	u32 start_time = rtw_get_current_time();
15519 	u8 bcn_queue_empty = _FALSE;
15520 
15521 	do {
15522 		if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
15523 			bcn_queue_empty = _TRUE;
15524 			break;
15525 		}
15526 	} while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
15527 
15528 	if (bcn_queue_empty == _FALSE)
15529 		RTW_ERR("%s BCN queue not empty\n", __func__);
15530 
15531 	return bcn_queue_empty;
15532 }
15533 #endif /*CONFIG_BCN_XMIT_PROTECT*/
15534 #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
15535 
15536 /**
15537  * rtw_hal_get_trx_path() - Get RF path related information
15538  * @d:		struct dvobj_priv*
15539  * @type:	RF type, nTnR
15540  * @tx:		Tx path
15541  * @rx:		Rx path
15542  *
15543  * Get RF type, TX path and RX path information.
15544  */
rtw_hal_get_trx_path(struct dvobj_priv * d,enum rf_type * type,enum bb_path * tx,enum bb_path * rx)15545 void rtw_hal_get_trx_path(struct dvobj_priv *d, enum rf_type *type,
15546 			 enum bb_path *tx, enum bb_path *rx)
15547 {
15548 	struct _ADAPTER *a = dvobj_get_primary_adapter(d);
15549 	enum rf_type t = GET_HAL_RFPATH(a);
15550 
15551 	if (type)
15552 		*type = t;
15553 
15554 	if (tx || rx) {
15555 		u8 tx_bmp = GET_HAL_TX_PATH_BMP(a);
15556 		u8 rx_bmp = GET_HAL_RX_PATH_BMP(a);
15557 
15558 		if (!tx_bmp && !rx_bmp)
15559 			rf_type_to_default_trx_bmp(t, tx, rx);
15560 		else {
15561 			if (tx)
15562 				*tx = GET_HAL_TX_PATH_BMP(a);
15563 			if (rx)
15564 				*rx = GET_HAL_RX_PATH_BMP(a);
15565 		}
15566 	}
15567 }
15568 
15569 #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
rtw_hal_switch_chnl_and_set_bw_offload(_adapter * adapter,u8 central_ch,u8 pri_ch_idx,u8 bw)15570 void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)
15571 {
15572 	u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};
15573 	PHAL_DATA_TYPE hal;
15574 	struct submit_ctx *chsw_sctx;
15575 
15576 	hal = GET_HAL_DATA(adapter);
15577 	chsw_sctx = &hal->chsw_sctx;
15578 
15579 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);
15580 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);
15581 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);
15582 
15583 	rtw_sctx_init(chsw_sctx, 10);
15584 	rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);
15585 	rtw_sctx_wait(chsw_sctx, __func__);
15586 }
15587 #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */
15588 
phy_get_current_tx_num(PADAPTER pAdapter,u8 Rate)15589 u8 phy_get_current_tx_num(
15590 		PADAPTER		pAdapter,
15591 		u8				Rate
15592 )
15593 {
15594 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(pAdapter);
15595 	u8	tx_num = 0;
15596 
15597 	if (IS_1T_RATE(Rate))
15598 		tx_num = hal_data->txpath_num_nss[0];
15599 	else if (IS_2T_RATE(Rate))
15600 		tx_num = hal_data->txpath_num_nss[1];
15601 	else if (IS_3T_RATE(Rate))
15602 		tx_num = hal_data->txpath_num_nss[2];
15603 	else if (IS_4T_RATE(Rate))
15604 		tx_num = hal_data->txpath_num_nss[3];
15605 	else
15606 		rtw_warn_on(1);
15607 
15608 	return tx_num == 0 ? RF_1TX : tx_num - 1;
15609 }
15610 
15611 #ifdef CONFIG_RTL8812A
rtw_hal_set_8812a_vendor_ie(_adapter * padapter,u8 * pframe,uint * frlen)15612 u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ) {
15613 	int vender_len = 7;
15614 	unsigned char	vendor_info[vender_len];
15615 	unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
15616 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
15617 
15618 	if( !IS_HARDWARE_TYPE_8812(padapter) )
15619 		return pframe;
15620 
15621 	_rtw_memset(vendor_info,0,vender_len);
15622 	_rtw_memcpy(vendor_info, REALTEK_OUI, 3);
15623 	vendor_info[4] =2;
15624 	if(pHalData->version_id.CUTVersion > B_CUT_VERSION )
15625 		vendor_info[6] = RT_HT_CAP_USE_JAGUAR_CCUT;
15626 	else
15627 		vendor_info[6] = RT_HT_CAP_USE_JAGUAR_BCUT;
15628 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,vender_len,vendor_info , frlen);
15629 
15630 	return pframe;
15631 }
15632 #endif /*CONFIG_RTL8812A*/
15633 
rtw_enter_protsel(struct protsel * protsel,u32 sel)15634 static inline void rtw_enter_protsel(struct protsel *protsel, u32 sel)
15635 {
15636 	int refcnt;
15637 
15638 	_enter_critical_mutex(&protsel->mutex, NULL);
15639 
15640 	refcnt = ATOMIC_INC_RETURN(&protsel->refcnt);
15641 
15642 	WARN_ON(refcnt > 1 && protsel->sel != sel);
15643 
15644 	protsel->sel = sel;
15645 
15646 	_exit_critical_mutex(&protsel->mutex, NULL);
15647 }
15648 
rtw_leave_protsel(struct protsel * protsel)15649 static inline void rtw_leave_protsel(struct protsel *protsel)
15650 {
15651 	int refcnt;
15652 
15653 	_enter_critical_mutex(&protsel->mutex, NULL);
15654 
15655 	refcnt = ATOMIC_DEC_RETURN(&protsel->refcnt);
15656 
15657 	_exit_critical_mutex(&protsel->mutex, NULL);
15658 
15659 	WARN_ON(refcnt < 0);
15660 }
15661 
rtw_assert_protsel(struct protsel * protsel)15662 static inline bool rtw_assert_protsel(struct protsel *protsel)
15663 {
15664 	int refcnt = ATOMIC_READ(&protsel->refcnt);
15665 
15666 	if (refcnt > 0)
15667 		return true;
15668 
15669 	return false;
15670 }
15671 
15672 #ifdef CONFIG_PROTSEL_PORT
rtw_enter_protsel_port(_adapter * padapter,u8 port_sel)15673 void rtw_enter_protsel_port(_adapter *padapter, u8 port_sel)
15674 {
15675 	u8 val8;
15676 
15677 	rtw_enter_protsel(&padapter->dvobj->protsel_port, port_sel);
15678 
15679 	val8 = rtw_read8(padapter, REG_PORT_CTRL_SEL);
15680 	val8 &= ~BIT_MASK_PORT_CTRL_SEL;
15681 	val8 |= BIT_PORT_CTRL_SEL(port_sel);
15682 	rtw_write8(padapter, REG_PORT_CTRL_SEL, val8);
15683 }
15684 
rtw_assert_protsel_port(_adapter * padapter,u32 addr,u8 len)15685 bool rtw_assert_protsel_port(_adapter *padapter, u32 addr, u8 len)
15686 {
15687 	if (!padapter->bup)	/* don't assert before IF up */
15688 		return true;
15689 
15690 	return rtw_assert_protsel(&padapter->dvobj->protsel_port);
15691 }
15692 
rtw_leave_protsel_port(_adapter * padapter)15693 void rtw_leave_protsel_port(_adapter *padapter)
15694 {
15695 	rtw_leave_protsel(&padapter->dvobj->protsel_port);
15696 }
15697 #endif
15698 
15699 #ifdef CONFIG_PROTSEL_ATIMDTIM
rtw_enter_protsel_atimdtim(_adapter * padapter,u8 port_sel)15700 void rtw_enter_protsel_atimdtim(_adapter *padapter, u8 port_sel)
15701 {
15702 	/* 0~15 is for port 0 MBSSID setting
15703 	 * 16 is for port 1 setting
15704 	 * 17 is for port 2 setting
15705 	 * 18 is for port 3 setting
15706 	 * 19 is for port 4 setting
15707 	 */
15708 	u8 val8;
15709 
15710 	if (port_sel >= 1 && port_sel <= 4)
15711 		port_sel += 15;
15712 
15713 	rtw_enter_protsel(&padapter->dvobj->protsel_atimdtim, port_sel);
15714 
15715 	val8 = rtw_read8(padapter, REG_ATIM_DTIM_CTRL_SEL);
15716 	val8 &= ~BIT_MASK_ATIM_DTIM_SEL;
15717 	val8 |= BIT_ATIM_DTIM_SEL(port_sel);
15718 	rtw_write8(padapter, REG_ATIM_DTIM_CTRL_SEL, val8);
15719 }
15720 
rtw_assert_protsel_atimdtim(_adapter * padapter,u32 addr,u8 len)15721 bool rtw_assert_protsel_atimdtim(_adapter *padapter, u32 addr, u8 len)
15722 {
15723 	return rtw_assert_protsel(&padapter->dvobj->protsel_atimdtim);
15724 }
15725 
rtw_leave_protsel_atimdtim(_adapter * padapter)15726 void rtw_leave_protsel_atimdtim(_adapter *padapter)
15727 {
15728 	rtw_leave_protsel(&padapter->dvobj->protsel_atimdtim);
15729 }
15730 #endif
15731 
15732 #ifdef CONFIG_PROTSEL_MACSLEEP
rtw_enter_protsel_macsleep(_adapter * padapter,u8 sel)15733 void rtw_enter_protsel_macsleep(_adapter *padapter, u8 sel)
15734 {
15735 	u32 val32;
15736 
15737 	rtw_enter_protsel(&padapter->dvobj->protsel_macsleep, sel);
15738 
15739 	val32 = rtw_read32(padapter, REG_MACID_SLEEP_CTRL);
15740 	val32 &= ~BIT_MASK_MACID_SLEEP_SEL;
15741 	val32 |= BIT_MACID_SLEEP_SEL(sel);
15742 	rtw_write32(padapter, REG_MACID_SLEEP_CTRL, val32);
15743 }
15744 
rtw_assert_protsel_macsleep(_adapter * padapter,u32 addr,u8 len)15745 bool rtw_assert_protsel_macsleep(_adapter *padapter, u32 addr, u8 len)
15746 {
15747 	return rtw_assert_protsel(&padapter->dvobj->protsel_macsleep);
15748 }
15749 
rtw_leave_protsel_macsleep(_adapter * padapter)15750 void rtw_leave_protsel_macsleep(_adapter *padapter)
15751 {
15752 	rtw_leave_protsel(&padapter->dvobj->protsel_macsleep);
15753 }
15754 #endif
15755 
15756 #ifndef RTW_HALMAC
rtw_hal_init_sifs_backup(_adapter * adapter)15757 void rtw_hal_init_sifs_backup(_adapter *adapter)
15758 {
15759 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
15760 
15761 	hal_data->init_reg_0x428 = rtw_read16(adapter, 0x428);
15762 	hal_data->init_reg_0x514 = rtw_read32(adapter, 0x514);
15763 	hal_data->init_reg_0x63a = rtw_read16(adapter, 0x63a);
15764 	hal_data->init_reg_0x63c = rtw_read32(adapter, 0x63c);
15765 
15766 #ifndef RTW_SIFS_INIT_CHK
15767 #define RTW_SIFS_INIT_CHK 1
15768 #endif
15769 
15770 #if RTW_SIFS_INIT_CHK
15771 /*
15772 the expected initial values:
15773 0x428[15:0]=0x100A
15774 0x514[31:0]=0x0E0A0E0A
15775 0x63A[15:0]=0x100A
15776 0x63C[31:0]=0x0E0E0A0A
15777 */
15778 #define INIT_REG_0x428 0x100A
15779 #define INIT_REG_0x514 0x0E0A0E0A
15780 #define INIT_REG_0x63A 0x100A
15781 #define INIT_REG_0x63C 0x0E0E0A0A
15782 
15783 	if (hal_data->init_reg_0x428 != INIT_REG_0x428) {
15784 		RTW_WARN("init_reg_0x428:0x%04x != 0x%04x\n", hal_data->init_reg_0x428, INIT_REG_0x428);
15785 		#if RTW_SIFS_INIT_CHK > 1
15786 		hal_data->init_reg_0x428 = INIT_REG_0x428;
15787 		rtw_write16(adapter, 0x428, hal_data->init_reg_0x428);
15788 		#endif
15789 	}
15790 	if (hal_data->init_reg_0x514 != INIT_REG_0x514) {
15791 		RTW_WARN("init_reg_0x514:0x%08x != 0x%08x\n", hal_data->init_reg_0x514, INIT_REG_0x514);
15792 		#if RTW_SIFS_INIT_CHK > 1
15793 		hal_data->init_reg_0x514 = INIT_REG_0x514;
15794 		rtw_write32(adapter, 0x514, hal_data->init_reg_0x514);
15795 		#endif
15796 	}
15797 	if (hal_data->init_reg_0x63a != INIT_REG_0x63A) {
15798 		RTW_WARN("init_reg_0x63a:0x%04x != 0x%04x\n", hal_data->init_reg_0x63a, INIT_REG_0x63A);
15799 		#if RTW_SIFS_INIT_CHK > 1
15800 		hal_data->init_reg_0x63a = INIT_REG_0x63A;
15801 		rtw_write16(adapter, 0x63a, hal_data->init_reg_0x63a);
15802 		#endif
15803 	}
15804 	if (hal_data->init_reg_0x63c != INIT_REG_0x63C) {
15805 		RTW_WARN("init_reg_0x63c:0x%08x != 0x%08x\n", hal_data->init_reg_0x63c, INIT_REG_0x63C);
15806 		#if RTW_SIFS_INIT_CHK > 1
15807 		hal_data->init_reg_0x63c = INIT_REG_0x63C;
15808 		rtw_write32(adapter, 0x63c, hal_data->init_reg_0x63c);
15809 		#endif
15810 	}
15811 #endif
15812 }
15813 #endif
15814