xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8188fu/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(1)) &&
5862 		(psecpriv->dot11PrivacyAlgrthm == _WEP40_ ||
5863 		psecpriv->dot11PrivacyAlgrthm == _WEP104_) && !no_wake)
5864 			hw_unicast = 1;
5865 
5866 	if (registry_par->wakeup_event & BIT(2) && !no_wake)
5867 		discont_wake = enable;
5868 
5869 	RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
5870 		 enable, change_unit);
5871 
5872 	/* time = (gpio_dur/2) * gpio_unit, default:256 ms */
5873 	if (enable && change_unit) {
5874 		gpio_dur = 0x40;
5875 		gpio_unit = 1;
5876 		gpio_pulse_en = 1;
5877 	}
5878 
5879 #ifdef CONFIG_PLATFORM_ARM_RK3188
5880 	if (enable) {
5881 		gpio_pulse_en = 1;
5882 		gpio_pulse_cnt = 0x04;
5883 	}
5884 #endif
5885 
5886 	SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
5887 	if(!no_wake)
5888 		SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
5889 	SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
5890 	SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
5891 	SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
5892 	SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
5893 
5894 #ifdef CONFIG_GTK_OL
5895 	if (psecpriv->binstallKCK_KEK == _TRUE &&
5896 		(psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5897 		SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
5898 	else
5899 		SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
5900 #else
5901 	SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
5902 #endif
5903 	SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
5904 	SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
5905 	SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
5906 
5907 	SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
5908 	SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
5909 
5910 	SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
5911 	SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
5912 
5913 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
5914 	if (enable)
5915 		SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5916 #endif
5917 
5918 #ifdef CONFIG_DIS_UPHY
5919 	if (enable) {
5920 		dis_uphy = 1;
5921 		/* time unit: 0 -> ms, 1 -> 256 ms*/
5922 		dis_uphy_unit = 1;
5923 		dis_uphy_time = 0x4;
5924 	}
5925 
5926 	SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);
5927 	SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);
5928 	SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);
5929 	if (ppwrpriv->hst2dev_high_active == 1)
5930 		SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);
5931 #ifdef CONFIG_RTW_ONE_PIN_GPIO
5932 	SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5933 	SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);
5934 	SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);
5935 #else
5936 	SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);
5937 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
5938 #endif /* CONFIG_DIS_UPHY */
5939 
5940 
5941 	ret = rtw_hal_fill_h2c_cmd(adapter,
5942 				   H2C_WOWLAN,
5943 				   H2C_WOWLAN_LEN,
5944 				   u1H2CWoWlanCtrlParm);
5945 	return ret;
5946 }
5947 
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)5948 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
5949 {
5950 	struct security_priv *psecuritypriv = &(adapter->securitypriv);
5951 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5952 	struct registry_priv *pregistrypriv = &adapter->registrypriv;
5953 	u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
5954 	u8 ret = _FAIL, count = 0, no_wake = 0;
5955 	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
5956 
5957 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
5958 
5959 	if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF &&
5960 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5961 		no_wake = 1;
5962 	if(no_wake) {
5963 		SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5964 			u1H2CRemoteWakeCtrlParm, enable);
5965 	} else {
5966 		if (!ppwrpriv->wowlan_pno_enable) {
5967 			SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5968 				u1H2CRemoteWakeCtrlParm, enable);
5969 			SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5970 				u1H2CRemoteWakeCtrlParm, 1);
5971 	#ifdef CONFIG_GTK_OL
5972 			if (psecuritypriv->binstallKCK_KEK == _TRUE &&
5973 				(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) {
5974 				SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5975 					u1H2CRemoteWakeCtrlParm, 1);
5976 			} else {
5977 				RTW_INFO("no kck kek\n");
5978 				SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5979 					u1H2CRemoteWakeCtrlParm, 0);
5980 			}
5981 	#endif /* CONFIG_GTK_OL */
5982 
5983 	#ifdef CONFIG_IPV6
5984 			if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
5985 				RTW_INFO("enable NS offload\n");
5986 				SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
5987 					u1H2CRemoteWakeCtrlParm, enable);
5988 			}
5989 
5990 			/*
5991 			 * filter NetBios name service pkt to avoid being waked-up
5992 			 * by this kind of unicast pkt this exceptional modification
5993 			 * is used for match competitor's behavior
5994 			 */
5995 
5996 			SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
5997 				u1H2CRemoteWakeCtrlParm, enable);
5998 	#endif /*CONFIG_IPV6*/
5999 #if 0 /* replaced by WOWLAN pattern match */
6000 	#ifdef CONFIG_RTL8192F
6001 			if (IS_HARDWARE_TYPE_8192F(adapter)){
6002 				SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
6003 					u1H2CRemoteWakeCtrlParm, enable);
6004 			}
6005 	#endif /* CONFIG_RTL8192F */
6006 #endif
6007 			if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
6008 				(psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
6009 				(psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
6010 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
6011 					u1H2CRemoteWakeCtrlParm, 0);
6012 			} else {
6013 				SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
6014 					u1H2CRemoteWakeCtrlParm, 1);
6015 			}
6016 
6017 			if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
6018 #ifdef CONFIG_GTK_OL
6019 				if(_rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))
6020 					SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
6021 						u1H2CRemoteWakeCtrlParm, enable);
6022 #endif /* CONFIG_GTK_OL */
6023 				if (IS_HARDWARE_TYPE_8188E(adapter) ||
6024 				    IS_HARDWARE_TYPE_8812(adapter)) {
6025 					SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
6026 						u1H2CRemoteWakeCtrlParm, 0);
6027 					SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
6028 						u1H2CRemoteWakeCtrlParm, 1);
6029 				}
6030 			}
6031 
6032 			SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
6033 				u1H2CRemoteWakeCtrlParm, 1);
6034 		}
6035 	#ifdef CONFIG_PNO_SUPPORT
6036 		else {
6037 			SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
6038 				u1H2CRemoteWakeCtrlParm, enable);
6039 			SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
6040 				u1H2CRemoteWakeCtrlParm, enable);
6041 		}
6042 	#endif
6043 
6044 	#ifdef CONFIG_P2P_WOWLAN
6045 		if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
6046 			RTW_INFO("P2P OFFLOAD ENABLE\n");
6047 			SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
6048 		} else {
6049 			RTW_INFO("P2P OFFLOAD DISABLE\n");
6050 			SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
6051 		}
6052 	#endif /* CONFIG_P2P_WOWLAN */
6053 	}
6054 
6055 
6056 	ret = rtw_hal_fill_h2c_cmd(adapter,
6057 				   H2C_REMOTE_WAKE_CTRL,
6058 				   H2C_REMOTE_WAKE_CTRL_LEN,
6059 				   u1H2CRemoteWakeCtrlParm);
6060 	return ret;
6061 }
6062 
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)6063 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
6064 {
6065 	u8 ret = _FAIL;
6066 	u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
6067 
6068 	RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
6069 		 __func__, group_alg, pairwise_alg);
6070 	SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
6071 			pairwise_alg);
6072 	SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
6073 			group_alg);
6074 
6075 	ret = rtw_hal_fill_h2c_cmd(adapter,
6076 				   H2C_AOAC_GLOBAL_INFO,
6077 				   H2C_AOAC_GLOBAL_INFO_LEN,
6078 				   u1H2CAOACGlobalInfoParm);
6079 
6080 	return ret;
6081 }
6082 
6083 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)6084 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
6085 		PRSVDPAGE_LOC rsvdpageloc, u8 enable)
6086 {
6087 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6088 	u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
6089 	u8 res = 0, count = 0, ret = _FAIL;
6090 
6091 	RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
6092 		 __func__, rsvdpageloc->LocProbePacket,
6093 		 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
6094 
6095 	SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
6096 	SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
6097 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
6098 					       rsvdpageloc->LocScanInfo);
6099 	SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
6100 			rsvdpageloc->LocProbePacket);
6101 	/*
6102 		SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
6103 				rsvdpageloc->LocSSIDInfo);
6104 	*/
6105 	ret = rtw_hal_fill_h2c_cmd(adapter,
6106 				   H2C_D0_SCAN_OFFLOAD_INFO,
6107 				   H2C_SCAN_OFFLOAD_CTRL_LEN,
6108 				   u1H2CScanOffloadInfoParm);
6109 	return ret;
6110 }
6111 #endif /* CONFIG_PNO_SUPPORT */
6112 
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)6113 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
6114 {
6115 	struct security_priv *psecpriv = &padapter->securitypriv;
6116 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
6117 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
6118 	struct registry_priv *pregistry = &padapter->registrypriv;
6119 	u8	pkt_type = 0, no_wake = 0;
6120 
6121 	if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF &&
6122 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
6123 		no_wake = 1;
6124 
6125 	RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
6126 
6127 	rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
6128 
6129 	if (enable) {
6130 		if(!no_wake)
6131 			rtw_hal_set_global_info_cmd(padapter,
6132 					    psecpriv->dot118021XGrpPrivacy,
6133 					    psecpriv->dot11PrivacyAlgrthm);
6134 
6135 		if (!(ppwrpriv->wowlan_pno_enable)) {
6136 			if (!no_wake)
6137 				rtw_hal_set_disconnect_decision_cmd(padapter,
6138 								    enable);
6139 #ifdef CONFIG_ARP_KEEP_ALIVE
6140 			if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
6141 			    (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
6142 				pkt_type = 0;
6143 			else
6144 				pkt_type = 1;
6145 #else
6146 			pkt_type = 0;
6147 #endif /* CONFIG_ARP_KEEP_ALIVE */
6148 			if(!no_wake)
6149 				rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
6150 		}
6151 #ifdef CONFIG_PNO_SUPPORT
6152 		rtw_hal_check_pno_enabled(padapter);
6153 #endif /* CONFIG_PNO_SUPPORT */
6154 	} else {
6155 #if 0
6156 		{
6157 			u32 PageSize = 0;
6158 			rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
6159 			dump_TX_FIFO(padapter, 4, PageSize);
6160 		}
6161 #endif
6162 	}
6163 #ifdef CONFIG_CUSTOM_PULSE
6164 	rtw_hal_set_gpio_custom_cmd(padapter, enable);
6165 #endif /* CONFIG_CUSTOM_PULSE */
6166 	rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
6167 	RTW_PRINT("-%s()-\n", __func__);
6168 }
6169 #endif /* CONFIG_WOWLAN */
6170 
6171 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)6172 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
6173 {
6174 	struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6175 
6176 	u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
6177 	u8 gpionum = 0, gpio_dur = 0;
6178 	u8 gpio_pulse = enable;
6179 	u8 sdio_wakeup_enable = 1;
6180 	u8 gpio_high_active = 0;
6181 	u8 ret = _FAIL;
6182 
6183 #ifdef CONFIG_GPIO_WAKEUP
6184 	gpio_high_active = ppwrpriv->is_high_active;
6185 	gpionum = ppwrpriv->wowlan_gpio_index;
6186 	sdio_wakeup_enable = 0;
6187 #endif /*CONFIG_GPIO_WAKEUP*/
6188 
6189 	RTW_INFO("%s(): enable=%d\n", __func__, enable);
6190 
6191 	SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
6192 					  gpionum);
6193 	SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
6194 					 gpio_pulse);
6195 	SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
6196 						gpio_high_active);
6197 	SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
6198 				       enable);
6199 	SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
6200 					     gpio_dur);
6201 
6202 	ret = rtw_hal_fill_h2c_cmd(adapter,
6203 				   H2C_AP_WOW_GPIO_CTRL,
6204 				   H2C_AP_WOW_GPIO_CTRL_LEN,
6205 				   u1H2CAPWoWlanCtrlParm);
6206 
6207 	return ret;
6208 }
6209 
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)6210 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
6211 {
6212 	u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
6213 	u8 ret = _FAIL;
6214 
6215 	RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
6216 
6217 	SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
6218 
6219 	ret = rtw_hal_fill_h2c_cmd(adapter,
6220 				   H2C_AP_OFFLOAD,
6221 				   H2C_AP_OFFLOAD_LEN,
6222 				   u1H2CAPOffloadCtrlParm);
6223 
6224 	return ret;
6225 }
6226 
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)6227 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
6228 {
6229 	u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
6230 	u8 ret = _FAIL;
6231 
6232 	RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
6233 
6234 	SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
6235 #ifndef CONFIG_USB_HCI
6236 	SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
6237 #endif /*CONFIG_USB_HCI*/
6238 	SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
6239 
6240 	if (enable)
6241 		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
6242 	else
6243 		SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
6244 
6245 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
6246 				   H2C_AP_PS_LEN, ap_ps_parm);
6247 
6248 	return ret;
6249 }
6250 
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)6251 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
6252 		PRSVDPAGE_LOC rsvdpageloc)
6253 {
6254 	struct hal_ops *pHalFunc = &padapter->hal_func;
6255 	u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
6256 	u8 ret = _FAIL, header = 0;
6257 
6258 	if (pHalFunc->fill_h2c_cmd == NULL) {
6259 		RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
6260 		return;
6261 	}
6262 
6263 	header = rtw_read8(padapter, REG_BCNQ_BDNY);
6264 
6265 	RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
6266 		 rsvdpageloc->LocApOffloadBCN,
6267 		 rsvdpageloc->LocProbeRsp,
6268 		 header);
6269 
6270 	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
6271 				      rsvdpageloc->LocApOffloadBCN + header);
6272 
6273 	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
6274 				   H2C_BCN_RSVDPAGE_LEN, rsvdparm);
6275 
6276 	if (ret == _FAIL)
6277 		RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
6278 
6279 	rtw_msleep_os(10);
6280 
6281 	_rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
6282 
6283 	SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
6284 			rsvdpageloc->LocProbeRsp + header);
6285 
6286 	ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
6287 				   H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
6288 
6289 	if (ret == _FAIL)
6290 		RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
6291 
6292 	rtw_msleep_os(10);
6293 }
6294 
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)6295 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
6296 {
6297 	rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
6298 	rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
6299 	rtw_hal_set_ap_ps_cmd(padapter, enable);
6300 }
6301 
rtw_hal_ap_wow_enable(_adapter * padapter)6302 static void rtw_hal_ap_wow_enable(_adapter *padapter)
6303 {
6304 	struct security_priv *psecuritypriv = &padapter->securitypriv;
6305 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6306 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6307 	struct sta_info *psta = NULL;
6308 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
6309 #ifdef DBG_CHECK_FW_PS_STATE
6310 	struct dvobj_priv *psdpriv = padapter->dvobj;
6311 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6312 #endif /*DBG_CHECK_FW_PS_STATE*/
6313 	int res;
6314 	u16 media_status_rpt;
6315 #ifdef CONFIG_GPIO_WAKEUP
6316 	u8 val8 = 0;
6317 #endif
6318 
6319 	RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
6320 #ifdef DBG_CHECK_FW_PS_STATE
6321 	if (rtw_fw_ps_state(padapter) == _FAIL) {
6322 		pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
6323 		RTW_PRINT("wowlan enable no leave 32k\n");
6324 	}
6325 #endif /*DBG_CHECK_FW_PS_STATE*/
6326 
6327 	/* 1. Download WOWLAN FW*/
6328 	rtw_hal_fw_dl(padapter, _TRUE);
6329 
6330 	media_status_rpt = RT_MEDIA_CONNECT;
6331 	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6332 			  (u8 *)&media_status_rpt);
6333 
6334 	issue_beacon(padapter, 0);
6335 
6336 	rtw_msleep_os(2);
6337 	#if defined(CONFIG_RTL8188E)
6338 	if (IS_HARDWARE_TYPE_8188E(padapter))
6339 		rtw_hal_disable_tx_report(padapter);
6340 	#endif
6341 	/* RX DMA stop */
6342 	res = rtw_hal_pause_rx_dma(padapter);
6343 	if (res == _FAIL)
6344 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
6345 
6346 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6347 	/* Enable CPWM2 only. */
6348 	res = rtw_hal_enable_cpwm2(padapter);
6349 	if (res == _FAIL)
6350 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
6351 #endif
6352 
6353 #ifdef CONFIG_GPIO_WAKEUP
6354 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6355 	rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6356 	rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6357 #else
6358 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6359 	if (pwrctrlpriv->is_high_active == 0)
6360 		rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6361 	else
6362 		rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index,
6363 			GPIO_OUTPUT_LOW);
6364 #else
6365 	val8 = (pwrpriv->is_high_active == 0) ? 1 : 0;
6366 	rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8);
6367 	rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6368 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow suspend and %s_ACTIVE.\n",
6369 		 __func__, pwrpriv->wowlan_gpio_index,
6370 		 pwrpriv->wowlan_gpio_output_state ? "HIGH" : "LOW",
6371 		 pwrpriv->is_high_active ? "HIGI" : "LOW");
6372 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
6373 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6374 #endif /* CONFIG_GPIO_WAKEUP */
6375 
6376 	/* 5. Set Enable WOWLAN H2C command. */
6377 	RTW_PRINT("Set Enable AP WOWLan cmd\n");
6378 	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
6379 
6380 	rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
6381 #ifdef CONFIG_USB_HCI
6382 	rtw_mi_intf_stop(padapter);
6383 #endif
6384 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
6385 	/* Invoid SE0 reset signal during suspending*/
6386 	rtw_write8(padapter, REG_RSV_CTRL, 0x20);
6387 	if (IS_8188F(pHalData->version_id) == FALSE
6388 		&& IS_8188GTV(pHalData->version_id) == FALSE)
6389 		rtw_write8(padapter, REG_RSV_CTRL, 0x60);
6390 #endif
6391 }
6392 
rtw_hal_ap_wow_disable(_adapter * padapter)6393 static void rtw_hal_ap_wow_disable(_adapter *padapter)
6394 {
6395 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6396 #ifdef DBG_CHECK_FW_PS_STATE
6397 	struct dvobj_priv *psdpriv = padapter->dvobj;
6398 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6399 #endif /*DBG_CHECK_FW_PS_STATE*/
6400 	u16 media_status_rpt;
6401 
6402 	RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
6403 	/* 1. Read wakeup reason*/
6404 	pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
6405 
6406 	RTW_PRINT("wakeup_reason: 0x%02x\n",
6407 		  pwrctl->wowlan_wake_reason);
6408 
6409 	rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
6410 
6411 	rtw_msleep_os(2);
6412 #ifdef DBG_CHECK_FW_PS_STATE
6413 	if (rtw_fw_ps_state(padapter) == _FAIL) {
6414 		pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
6415 		RTW_PRINT("wowlan enable no leave 32k\n");
6416 	}
6417 #endif /*DBG_CHECK_FW_PS_STATE*/
6418 
6419 	#if defined(CONFIG_RTL8188E)
6420 	if (IS_HARDWARE_TYPE_8188E(padapter))
6421 		rtw_hal_enable_tx_report(padapter);
6422 	#endif
6423 
6424 	rtw_hal_force_enable_rxdma(padapter);
6425 
6426 	rtw_hal_fw_dl(padapter, _FALSE);
6427 
6428 #ifdef CONFIG_GPIO_WAKEUP
6429 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6430 	rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6431 #else
6432 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6433 	if (pwrctl->is_high_active == 0)
6434 		rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6435 	else
6436 		rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index
6437 			, GPIO_OUTPUT_LOW);
6438 #else
6439 	rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index,
6440 		pwrctl->wowlan_gpio_output_state);
6441 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow resume and %s_ACTIVE.\n",
6442 		 __func__, pwrctl->wowlan_gpio_index,
6443 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
6444 		 pwrctl->is_high_active ? "HIGI" : "LOW");
6445 #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
6446 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6447 #endif /* CONFIG_GPIO_WAKEUP */
6448 	media_status_rpt = RT_MEDIA_CONNECT;
6449 
6450 	rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6451 			  (u8 *)&media_status_rpt);
6452 
6453 	issue_beacon(padapter, 0);
6454 }
6455 #endif /*CONFIG_AP_WOWLAN*/
6456 
6457 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)6458 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
6459 {
6460 	u8 *ssid_ie;
6461 	sint ssid_len_ori;
6462 	int len_diff = 0;
6463 
6464 	ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
6465 
6466 	/* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
6467 
6468 	if (ssid_ie && ssid_len_ori > 0) {
6469 		switch (hidden_ssid_mode) {
6470 		case 1: {
6471 			u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
6472 			u32 remain_len = 0;
6473 
6474 			remain_len = ies_len - (next_ie - ies);
6475 
6476 			ssid_ie[1] = 0;
6477 			_rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
6478 			len_diff -= ssid_len_ori;
6479 
6480 			break;
6481 		}
6482 		case 2:
6483 			_rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
6484 			break;
6485 		default:
6486 			break;
6487 		}
6488 	}
6489 
6490 	return len_diff;
6491 }
6492 
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)6493 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
6494 {
6495 	/* struct xmit_frame	*pmgntframe; */
6496 	/* struct pkt_attrib	*pattrib; */
6497 	/* unsigned char	*pframe; */
6498 	struct rtw_ieee80211_hdr *pwlanhdr;
6499 	unsigned short *fctrl;
6500 	unsigned int	rate_len;
6501 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
6502 	u32	pktlen;
6503 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6504 	/*	_irqL irqL;
6505 	 *	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6506 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6507 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6508 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6509 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6510 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
6511 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6512 #ifdef CONFIG_P2P
6513 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6514 #endif /* CONFIG_P2P */
6515 
6516 	/* for debug */
6517 	u8 *dbgbuf = pframe;
6518 	u8 dbgbufLen = 0, index = 0;
6519 
6520 	RTW_INFO("%s\n", __FUNCTION__);
6521 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6522 	/*	_enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6523 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6524 
6525 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6526 
6527 
6528 	fctrl = &(pwlanhdr->frame_ctl);
6529 	*(fctrl) = 0;
6530 
6531 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6532 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6533 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
6534 
6535 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
6536 	/* pmlmeext->mgnt_seq++; */
6537 	set_frame_sub_type(pframe, WIFI_BEACON);
6538 
6539 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6540 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6541 
6542 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6543 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
6544 #ifdef CONFIG_P2P
6545 		/* for P2P : Primary Device Type & Device Name */
6546 		u32 wpsielen = 0, insert_len = 0;
6547 		u8 *wpsie = NULL;
6548 		wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
6549 
6550 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
6551 			uint wps_offset, remainder_ielen;
6552 			u8 *premainder_ie, *pframe_wscie;
6553 
6554 			wps_offset = (uint)(wpsie - cur_network->IEs);
6555 
6556 			premainder_ie = wpsie + wpsielen;
6557 
6558 			remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
6559 
6560 #ifdef CONFIG_IOCTL_CFG80211
6561 			if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6562 				if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
6563 					_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
6564 					pframe += wps_offset;
6565 					pktlen += wps_offset;
6566 
6567 					_rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
6568 					pframe += pmlmepriv->wps_beacon_ie_len;
6569 					pktlen += pmlmepriv->wps_beacon_ie_len;
6570 
6571 					/* copy remainder_ie to pframe */
6572 					_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6573 					pframe += remainder_ielen;
6574 					pktlen += remainder_ielen;
6575 				} else {
6576 					_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6577 					pframe += cur_network->IELength;
6578 					pktlen += cur_network->IELength;
6579 				}
6580 			} else
6581 #endif /* CONFIG_IOCTL_CFG80211 */
6582 			{
6583 				pframe_wscie = pframe + wps_offset;
6584 				_rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
6585 				pframe += (wps_offset + wpsielen);
6586 				pktlen += (wps_offset + wpsielen);
6587 
6588 				/* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
6589 				/*	Primary Device Type */
6590 				/*	Type: */
6591 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6592 				insert_len += 2;
6593 
6594 				/*	Length: */
6595 				*(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
6596 				insert_len += 2;
6597 
6598 				/*	Value: */
6599 				/*	Category ID */
6600 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6601 				insert_len += 2;
6602 
6603 				/*	OUI */
6604 				*(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
6605 				insert_len += 4;
6606 
6607 				/*	Sub Category ID */
6608 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6609 				insert_len += 2;
6610 
6611 
6612 				/*	Device Name */
6613 				/*	Type: */
6614 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6615 				insert_len += 2;
6616 
6617 				/*	Length: */
6618 				*(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
6619 				insert_len += 2;
6620 
6621 				/*	Value: */
6622 				_rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
6623 				insert_len += pwdinfo->device_name_len;
6624 
6625 
6626 				/* update wsc ie length */
6627 				*(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
6628 
6629 				/* pframe move to end */
6630 				pframe += insert_len;
6631 				pktlen += insert_len;
6632 
6633 				/* copy remainder_ie to pframe */
6634 				_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6635 				pframe += remainder_ielen;
6636 				pktlen += remainder_ielen;
6637 			}
6638 		} else
6639 #endif /* CONFIG_P2P */
6640 		{
6641 			int len_diff;
6642 			_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6643 			len_diff = update_hidden_ssid(
6644 					   pframe + _BEACON_IE_OFFSET_
6645 				   , cur_network->IELength - _BEACON_IE_OFFSET_
6646 					   , pmlmeinfo->hidden_ssid_mode
6647 				   );
6648 			pframe += (cur_network->IELength + len_diff);
6649 			pktlen += (cur_network->IELength + len_diff);
6650 		}
6651 #if 0
6652 		{
6653 			u8 *wps_ie;
6654 			uint wps_ielen;
6655 			u8 sr = 0;
6656 			wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
6657 				pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
6658 			if (wps_ie && wps_ielen > 0)
6659 				rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
6660 			if (sr != 0)
6661 				set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
6662 			else
6663 				_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
6664 		}
6665 #endif
6666 #ifdef CONFIG_P2P
6667 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6668 			u32 len;
6669 #ifdef CONFIG_IOCTL_CFG80211
6670 			if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6671 				len = pmlmepriv->p2p_beacon_ie_len;
6672 				if (pmlmepriv->p2p_beacon_ie && len > 0)
6673 					_rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
6674 			} else
6675 #endif /* CONFIG_IOCTL_CFG80211 */
6676 			{
6677 				len = build_beacon_p2p_ie(pwdinfo, pframe);
6678 			}
6679 
6680 			pframe += len;
6681 			pktlen += len;
6682 
6683 			#ifdef CONFIG_WFD
6684 			len = rtw_append_beacon_wfd_ie(padapter, pframe);
6685 			pframe += len;
6686 			pktlen += len;
6687 			#endif
6688 
6689 		}
6690 #endif /* CONFIG_P2P */
6691 
6692 		goto _issue_bcn;
6693 
6694 	}
6695 
6696 	/* below for ad-hoc mode */
6697 
6698 	/* timestamp will be inserted by hardware */
6699 	pframe += 8;
6700 	pktlen += 8;
6701 
6702 	/* beacon interval: 2 bytes */
6703 
6704 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6705 
6706 	pframe += 2;
6707 	pktlen += 2;
6708 
6709 	/* capability info: 2 bytes */
6710 
6711 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6712 
6713 	pframe += 2;
6714 	pktlen += 2;
6715 
6716 	/* SSID */
6717 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
6718 
6719 	/* supported rates... */
6720 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6721 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
6722 
6723 	/* DS parameter set */
6724 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
6725 
6726 	/* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
6727 	{
6728 		u8 erpinfo = 0;
6729 		u32 ATIMWindow;
6730 		/* IBSS Parameter Set... */
6731 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
6732 		ATIMWindow = 0;
6733 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
6734 
6735 		/* ERP IE */
6736 		pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
6737 	}
6738 
6739 
6740 	/* EXTERNDED SUPPORTED RATE */
6741 	if (rate_len > 8)
6742 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
6743 
6744 
6745 	/* todo:HT for adhoc */
6746 
6747 _issue_bcn:
6748 
6749 	/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6750 	/*	pmlmepriv->update_bcn = _FALSE;
6751 	 *
6752 	 *	_exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6753 	 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6754 
6755 	*pLength = pktlen;
6756 #if 0
6757 	/* printf dbg msg */
6758 	dbgbufLen = pktlen;
6759 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6760 
6761 	for (index = 0; index < dbgbufLen; index++)
6762 		printk("%x ", *(dbgbuf + index));
6763 
6764 	printk("\n");
6765 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6766 
6767 #endif
6768 }
6769 
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6770 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6771 {
6772 	/* struct xmit_frame			*pmgntframe; */
6773 	/* struct pkt_attrib			*pattrib; */
6774 	/* unsigned char					*pframe; */
6775 	struct rtw_ieee80211_hdr	*pwlanhdr;
6776 	unsigned short				*fctrl;
6777 	unsigned char					*mac;
6778 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
6779 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6780 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
6781 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6782 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
6783 	u16					beacon_interval = 100;
6784 	u16					capInfo = 0;
6785 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6786 	u8					wpsie[255] = { 0x00 };
6787 	u32					wpsielen = 0, p2pielen = 0;
6788 	u32					pktlen;
6789 #ifdef CONFIG_WFD
6790 	u32					wfdielen = 0;
6791 #endif
6792 
6793 	/* for debug */
6794 	u8 *dbgbuf = pframe;
6795 	u8 dbgbufLen = 0, index = 0;
6796 
6797 	RTW_INFO("%s\n", __FUNCTION__);
6798 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6799 
6800 	mac = adapter_mac_addr(padapter);
6801 
6802 	fctrl = &(pwlanhdr->frame_ctl);
6803 	*(fctrl) = 0;
6804 
6805 	/* DA filled by FW */
6806 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6807 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6808 
6809 	/*	Use the device address for BSSID field.	 */
6810 	_rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
6811 
6812 	SetSeqNum(pwlanhdr, 0);
6813 	set_frame_sub_type(fctrl, WIFI_PROBERSP);
6814 
6815 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6816 	pframe += pktlen;
6817 
6818 
6819 	/* timestamp will be inserted by hardware */
6820 	pframe += 8;
6821 	pktlen += 8;
6822 
6823 	/* beacon interval: 2 bytes */
6824 	_rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
6825 	pframe += 2;
6826 	pktlen += 2;
6827 
6828 	/*	capability info: 2 bytes */
6829 	/*	ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
6830 	capInfo |= cap_ShortPremble;
6831 	capInfo |= cap_ShortSlot;
6832 
6833 	_rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
6834 	pframe += 2;
6835 	pktlen += 2;
6836 
6837 
6838 	/* SSID */
6839 	pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
6840 
6841 	/* supported rates... */
6842 	/*	Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
6843 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
6844 
6845 	/* DS parameter set */
6846 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
6847 
6848 #ifdef CONFIG_IOCTL_CFG80211
6849 	if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6850 		if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
6851 			/* WPS IE */
6852 			_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
6853 			pktlen += pmlmepriv->wps_probe_resp_ie_len;
6854 			pframe += pmlmepriv->wps_probe_resp_ie_len;
6855 
6856 			/* P2P IE */
6857 			_rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
6858 			pktlen += pmlmepriv->p2p_probe_resp_ie_len;
6859 			pframe += pmlmepriv->p2p_probe_resp_ie_len;
6860 		}
6861 	} else
6862 #endif /* CONFIG_IOCTL_CFG80211		 */
6863 	{
6864 
6865 		/*	Todo: WPS IE */
6866 		/*	Noted by Albert 20100907 */
6867 		/*	According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6868 
6869 		wpsielen = 0;
6870 		/*	WPS OUI */
6871 		*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6872 		wpsielen += 4;
6873 
6874 		/*	WPS version */
6875 		/*	Type: */
6876 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6877 		wpsielen += 2;
6878 
6879 		/*	Length: */
6880 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6881 		wpsielen += 2;
6882 
6883 		/*	Value: */
6884 		wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
6885 
6886 		/*	WiFi Simple Config State */
6887 		/*	Type: */
6888 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
6889 		wpsielen += 2;
6890 
6891 		/*	Length: */
6892 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6893 		wpsielen += 2;
6894 
6895 		/*	Value: */
6896 		wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;	/*	Not Configured. */
6897 
6898 		/*	Response Type */
6899 		/*	Type: */
6900 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
6901 		wpsielen += 2;
6902 
6903 		/*	Length: */
6904 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6905 		wpsielen += 2;
6906 
6907 		/*	Value: */
6908 		wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
6909 
6910 		/*	UUID-E */
6911 		/*	Type: */
6912 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6913 		wpsielen += 2;
6914 
6915 		/*	Length: */
6916 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6917 		wpsielen += 2;
6918 
6919 		/*	Value: */
6920 		if (pwdinfo->external_uuid == 0) {
6921 			_rtw_memset(wpsie + wpsielen, 0x0, 16);
6922 			_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6923 		} else
6924 			_rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6925 		wpsielen += 0x10;
6926 
6927 		/*	Manufacturer */
6928 		/*	Type: */
6929 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
6930 		wpsielen += 2;
6931 
6932 		/*	Length: */
6933 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
6934 		wpsielen += 2;
6935 
6936 		/*	Value: */
6937 		_rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
6938 		wpsielen += 7;
6939 
6940 		/*	Model Name */
6941 		/*	Type: */
6942 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
6943 		wpsielen += 2;
6944 
6945 		/*	Length: */
6946 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
6947 		wpsielen += 2;
6948 
6949 		/*	Value: */
6950 		_rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
6951 		wpsielen += 6;
6952 
6953 		/*	Model Number */
6954 		/*	Type: */
6955 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
6956 		wpsielen += 2;
6957 
6958 		/*	Length: */
6959 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6960 		wpsielen += 2;
6961 
6962 		/*	Value: */
6963 		wpsie[wpsielen++] = 0x31;		/*	character 1 */
6964 
6965 		/*	Serial Number */
6966 		/*	Type: */
6967 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
6968 		wpsielen += 2;
6969 
6970 		/*	Length: */
6971 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
6972 		wpsielen += 2;
6973 
6974 		/*	Value: */
6975 		_rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
6976 		wpsielen += ETH_ALEN;
6977 
6978 		/*	Primary Device Type */
6979 		/*	Type: */
6980 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6981 		wpsielen += 2;
6982 
6983 		/*	Length: */
6984 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6985 		wpsielen += 2;
6986 
6987 		/*	Value: */
6988 		/*	Category ID */
6989 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6990 		wpsielen += 2;
6991 
6992 		/*	OUI */
6993 		*(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6994 		wpsielen += 4;
6995 
6996 		/*	Sub Category ID */
6997 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6998 		wpsielen += 2;
6999 
7000 		/*	Device Name */
7001 		/*	Type: */
7002 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7003 		wpsielen += 2;
7004 
7005 		/*	Length: */
7006 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
7007 		wpsielen += 2;
7008 
7009 		/*	Value: */
7010 		_rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
7011 		wpsielen += pwdinfo->device_name_len;
7012 
7013 		/*	Config Method */
7014 		/*	Type: */
7015 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
7016 		wpsielen += 2;
7017 
7018 		/*	Length: */
7019 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7020 		wpsielen += 2;
7021 
7022 		/*	Value: */
7023 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7024 		wpsielen += 2;
7025 
7026 
7027 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7028 
7029 
7030 		p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
7031 		pframe += p2pielen;
7032 		pktlen += p2pielen;
7033 	}
7034 
7035 #ifdef CONFIG_WFD
7036 	wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
7037 	pframe += wfdielen;
7038 	pktlen += wfdielen;
7039 #endif
7040 
7041 	*pLength = pktlen;
7042 
7043 #if 0
7044 	/* printf dbg msg */
7045 	dbgbufLen = pktlen;
7046 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7047 
7048 	for (index = 0; index < dbgbufLen; index++)
7049 		printk("%x ", *(dbgbuf + index));
7050 
7051 	printk("\n");
7052 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7053 #endif
7054 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7055 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7056 {
7057 	struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7058 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7059 	u8			action = P2P_PUB_ACTION_ACTION;
7060 	u32			p2poui = cpu_to_be32(P2POUI);
7061 	u8			oui_subtype = P2P_GO_NEGO_RESP;
7062 	u8			wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
7063 	u8			p2pielen = 0, i;
7064 	uint			wpsielen = 0;
7065 	u16			wps_devicepassword_id = 0x0000;
7066 	uint			wps_devicepassword_id_len = 0;
7067 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
7068 	u16			len_channellist_attr = 0;
7069 	u32			pktlen;
7070 	u8			dialogToken = 0;
7071 
7072 	/* struct xmit_frame			*pmgntframe; */
7073 	/* struct pkt_attrib			*pattrib; */
7074 	/* unsigned char					*pframe; */
7075 	struct rtw_ieee80211_hdr	*pwlanhdr;
7076 	unsigned short				*fctrl;
7077 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7078 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7079 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7080 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7081 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
7082 
7083 #ifdef CONFIG_WFD
7084 	u32					wfdielen = 0;
7085 #endif
7086 
7087 	/* for debug */
7088 	u8 *dbgbuf = pframe;
7089 	u8 dbgbufLen = 0, index = 0;
7090 
7091 	RTW_INFO("%s\n", __FUNCTION__);
7092 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7093 
7094 	fctrl = &(pwlanhdr->frame_ctl);
7095 	*(fctrl) = 0;
7096 
7097 	/* RA, filled by FW */
7098 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7099 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7100 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7101 
7102 	SetSeqNum(pwlanhdr, 0);
7103 	set_frame_sub_type(pframe, WIFI_ACTION);
7104 
7105 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7106 	pframe += pktlen;
7107 
7108 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7109 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7110 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7111 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7112 
7113 	/* dialog token, filled by FW */
7114 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7115 
7116 	_rtw_memset(wpsie, 0x00, 255);
7117 	wpsielen = 0;
7118 
7119 	/*	WPS Section */
7120 	wpsielen = 0;
7121 	/*	WPS OUI */
7122 	*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
7123 	wpsielen += 4;
7124 
7125 	/*	WPS version */
7126 	/*	Type: */
7127 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7128 	wpsielen += 2;
7129 
7130 	/*	Length: */
7131 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7132 	wpsielen += 2;
7133 
7134 	/*	Value: */
7135 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
7136 
7137 	/*	Device Password ID */
7138 	/*	Type: */
7139 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
7140 	wpsielen += 2;
7141 
7142 	/*	Length: */
7143 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7144 	wpsielen += 2;
7145 
7146 	/*	Value: */
7147 	if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
7148 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
7149 	else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
7150 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
7151 	else
7152 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
7153 	wpsielen += 2;
7154 
7155 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7156 
7157 
7158 	/*	P2P IE Section. */
7159 
7160 	/*	P2P OUI */
7161 	p2pielen = 0;
7162 	p2pie[p2pielen++] = 0x50;
7163 	p2pie[p2pielen++] = 0x6F;
7164 	p2pie[p2pielen++] = 0x9A;
7165 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
7166 
7167 	/*	Commented by Albert 20100908 */
7168 	/*	According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
7169 	/*	1. Status */
7170 	/*	2. P2P Capability */
7171 	/*	3. Group Owner Intent */
7172 	/*	4. Configuration Timeout */
7173 	/*	5. Operating Channel */
7174 	/*	6. Intended P2P Interface Address */
7175 	/*	7. Channel List */
7176 	/*	8. Device Info */
7177 	/*	9. Group ID	( Only GO ) */
7178 
7179 
7180 	/*	ToDo: */
7181 
7182 	/*	P2P Status */
7183 	/*	Type: */
7184 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
7185 
7186 	/*	Length: */
7187 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7188 	p2pielen += 2;
7189 
7190 	/*	Value, filled by FW */
7191 	p2pie[p2pielen++] = 1;
7192 
7193 	/*	P2P Capability */
7194 	/*	Type: */
7195 	p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
7196 
7197 	/*	Length: */
7198 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7199 	p2pielen += 2;
7200 
7201 	/*	Value: */
7202 	/*	Device Capability Bitmap, 1 byte */
7203 
7204 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
7205 		/*	Commented by Albert 2011/03/08 */
7206 		/*	According to the P2P specification */
7207 		/*	if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
7208 		p2pie[p2pielen++] = 0;
7209 	} else {
7210 		/*	Be group owner or meet the error case */
7211 		p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
7212 	}
7213 
7214 	/*	Group Capability Bitmap, 1 byte */
7215 	if (pwdinfo->persistent_supported)
7216 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
7217 	else
7218 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
7219 
7220 	/*	Group Owner Intent */
7221 	/*	Type: */
7222 	p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
7223 
7224 	/*	Length: */
7225 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7226 	p2pielen += 2;
7227 
7228 	/*	Value: */
7229 	if (pwdinfo->peer_intent & 0x01) {
7230 		/*	Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
7231 		p2pie[p2pielen++] = (pwdinfo->intent << 1);
7232 	} else {
7233 		/*	Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
7234 		p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
7235 	}
7236 
7237 
7238 	/*	Configuration Timeout */
7239 	/*	Type: */
7240 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7241 
7242 	/*	Length: */
7243 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7244 	p2pielen += 2;
7245 
7246 	/*	Value: */
7247 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
7248 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
7249 
7250 	/*	Operating Channel */
7251 	/*	Type: */
7252 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7253 
7254 	/*	Length: */
7255 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7256 	p2pielen += 2;
7257 
7258 	/*	Value: */
7259 	/*	Country String */
7260 	p2pie[p2pielen++] = 'X';
7261 	p2pie[p2pielen++] = 'X';
7262 
7263 	/*	The third byte should be set to 0x04. */
7264 	/*	Described in the "Operating Channel Attribute" section. */
7265 	p2pie[p2pielen++] = 0x04;
7266 
7267 	/*	Operating Class */
7268 	if (pwdinfo->operating_channel <= 14) {
7269 		/*	Operating Class */
7270 		p2pie[p2pielen++] = 0x51;
7271 	} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
7272 		/*	Operating Class */
7273 		p2pie[p2pielen++] = 0x73;
7274 	} else {
7275 		/*	Operating Class */
7276 		p2pie[p2pielen++] = 0x7c;
7277 	}
7278 
7279 	/*	Channel Number */
7280 	p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
7281 
7282 	/*	Intended P2P Interface Address	 */
7283 	/*	Type: */
7284 	p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
7285 
7286 	/*	Length: */
7287 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7288 	p2pielen += 2;
7289 
7290 	/*	Value: */
7291 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7292 	p2pielen += ETH_ALEN;
7293 
7294 	/*	Channel List */
7295 	/*	Type: */
7296 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7297 
7298 	/* Country String(3) */
7299 	/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7300 	/* + number of channels in all classes */
7301 	len_channellist_attr = 3
7302 		       + (1 + 1) * (u16)ch_list->reg_classes
7303 		       + get_reg_classes_full_count(ch_list);
7304 
7305 #ifdef CONFIG_CONCURRENT_MODE
7306 	if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
7307 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7308 	else
7309 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7310 
7311 #else
7312 
7313 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7314 
7315 #endif
7316 	p2pielen += 2;
7317 
7318 	/*	Value: */
7319 	/*	Country String */
7320 	p2pie[p2pielen++] = 'X';
7321 	p2pie[p2pielen++] = 'X';
7322 
7323 	/*	The third byte should be set to 0x04. */
7324 	/*	Described in the "Operating Channel Attribute" section. */
7325 	p2pie[p2pielen++] = 0x04;
7326 
7327 	/*	Channel Entry List */
7328 
7329 #ifdef CONFIG_CONCURRENT_MODE
7330 	if (rtw_mi_check_status(padapter, MI_LINKED)) {
7331 		u8 union_ch = rtw_mi_get_union_chan(padapter);
7332 
7333 		/*	Operating Class */
7334 		if (union_ch > 14) {
7335 			if (union_ch >= 149)
7336 				p2pie[p2pielen++] = 0x7c;
7337 			else
7338 				p2pie[p2pielen++] = 0x73;
7339 		} else
7340 			p2pie[p2pielen++] = 0x51;
7341 
7342 
7343 		/*	Number of Channels */
7344 		/*	Just support 1 channel and this channel is AP's channel */
7345 		p2pie[p2pielen++] = 1;
7346 
7347 		/*	Channel List */
7348 		p2pie[p2pielen++] = union_ch;
7349 	} else
7350 #endif /* CONFIG_CONCURRENT_MODE */
7351 	{
7352 		int i, j;
7353 		for (j = 0; j < ch_list->reg_classes; j++) {
7354 			/*	Operating Class */
7355 			p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7356 
7357 			/*	Number of Channels */
7358 			p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7359 
7360 			/*	Channel List */
7361 			for (i = 0; i < ch_list->reg_class[j].channels; i++)
7362 				p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7363 		}
7364 	}
7365 
7366 	/*	Device Info */
7367 	/*	Type: */
7368 	p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
7369 
7370 	/*	Length: */
7371 	/*	21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)  */
7372 	/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7373 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
7374 	p2pielen += 2;
7375 
7376 	/*	Value: */
7377 	/*	P2P Device Address */
7378 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7379 	p2pielen += ETH_ALEN;
7380 
7381 	/*	Config Method */
7382 	/*	This field should be big endian. Noted by P2P specification. */
7383 
7384 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7385 
7386 	p2pielen += 2;
7387 
7388 	/*	Primary Device Type */
7389 	/*	Category ID */
7390 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7391 	p2pielen += 2;
7392 
7393 	/*	OUI */
7394 	*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
7395 	p2pielen += 4;
7396 
7397 	/*	Sub Category ID */
7398 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7399 	p2pielen += 2;
7400 
7401 	/*	Number of Secondary Device Types */
7402 	p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
7403 
7404 	/*	Device Name */
7405 	/*	Type: */
7406 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7407 	p2pielen += 2;
7408 
7409 	/*	Length: */
7410 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
7411 	p2pielen += 2;
7412 
7413 	/*	Value: */
7414 	_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
7415 	p2pielen += pwdinfo->device_name_len;
7416 
7417 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7418 		/*	Group ID Attribute */
7419 		/*	Type: */
7420 		p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
7421 
7422 		/*	Length: */
7423 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
7424 		p2pielen += 2;
7425 
7426 		/*	Value: */
7427 		/*	p2P Device Address */
7428 		_rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
7429 		p2pielen += ETH_ALEN;
7430 
7431 		/*	SSID */
7432 		_rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
7433 		p2pielen += pwdinfo->nego_ssidlen;
7434 
7435 	}
7436 
7437 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7438 
7439 #ifdef CONFIG_WFD
7440 	wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
7441 	pframe += wfdielen;
7442 	pktlen += wfdielen;
7443 #endif
7444 
7445 	*pLength = pktlen;
7446 #if 0
7447 	/* printf dbg msg */
7448 	dbgbufLen = pktlen;
7449 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7450 
7451 	for (index = 0; index < dbgbufLen; index++)
7452 		printk("%x ", *(dbgbuf + index));
7453 
7454 	printk("\n");
7455 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7456 #endif
7457 }
7458 
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7459 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7460 {
7461 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7462 	u8			action = P2P_PUB_ACTION_ACTION;
7463 	u32			p2poui = cpu_to_be32(P2POUI);
7464 	u8			oui_subtype = P2P_INVIT_RESP;
7465 	u8			p2pie[255] = { 0x00 };
7466 	u8			p2pielen = 0, i;
7467 	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
7468 	u16			len_channellist_attr = 0;
7469 	u32			pktlen;
7470 	u8			dialogToken = 0;
7471 #ifdef CONFIG_WFD
7472 	u32					wfdielen = 0;
7473 #endif
7474 
7475 	/* struct xmit_frame			*pmgntframe; */
7476 	/* struct pkt_attrib			*pattrib; */
7477 	/* unsigned char					*pframe; */
7478 	struct rtw_ieee80211_hdr	*pwlanhdr;
7479 	unsigned short				*fctrl;
7480 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7481 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7482 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7483 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7484 
7485 	/* for debug */
7486 	u8 *dbgbuf = pframe;
7487 	u8 dbgbufLen = 0, index = 0;
7488 
7489 
7490 	RTW_INFO("%s\n", __FUNCTION__);
7491 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7492 
7493 	fctrl = &(pwlanhdr->frame_ctl);
7494 	*(fctrl) = 0;
7495 
7496 	/* RA fill by FW */
7497 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7498 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7499 
7500 	/* BSSID fill by FW */
7501 	_rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
7502 
7503 	SetSeqNum(pwlanhdr, 0);
7504 	set_frame_sub_type(pframe, WIFI_ACTION);
7505 
7506 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7507 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7508 
7509 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7510 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7511 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7512 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7513 
7514 	/* dialog token, filled by FW */
7515 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7516 
7517 	/*	P2P IE Section. */
7518 
7519 	/*	P2P OUI */
7520 	p2pielen = 0;
7521 	p2pie[p2pielen++] = 0x50;
7522 	p2pie[p2pielen++] = 0x6F;
7523 	p2pie[p2pielen++] = 0x9A;
7524 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
7525 
7526 	/*	Commented by Albert 20101005 */
7527 	/*	According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
7528 	/*	1. Status */
7529 	/*	2. Configuration Timeout */
7530 	/*	3. Operating Channel	( Only GO ) */
7531 	/*	4. P2P Group BSSID	( Only GO ) */
7532 	/*	5. Channel List */
7533 
7534 	/*	P2P Status */
7535 	/*	Type: */
7536 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
7537 
7538 	/*	Length: */
7539 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7540 	p2pielen += 2;
7541 
7542 	/*	Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
7543 	p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7544 
7545 	/*	Configuration Timeout */
7546 	/*	Type: */
7547 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7548 
7549 	/*	Length: */
7550 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7551 	p2pielen += 2;
7552 
7553 	/*	Value: */
7554 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
7555 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
7556 
7557 	/* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
7558 #if 0
7559 	if (status_code == P2P_STATUS_SUCCESS) {
7560 		struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7561 
7562 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7563 			/*	The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
7564 			/*	In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
7565 			/*	First one is operating channel attribute. */
7566 			/*	Second one is P2P Group BSSID attribute. */
7567 
7568 			/*	Operating Channel */
7569 			/*	Type: */
7570 			p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7571 
7572 			/*	Length: */
7573 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7574 			p2pielen += 2;
7575 
7576 			/*	Value: */
7577 			/*	Country String */
7578 			p2pie[p2pielen++] = 'X';
7579 			p2pie[p2pielen++] = 'X';
7580 
7581 			/*	The third byte should be set to 0x04. */
7582 			/*	Described in the "Operating Channel Attribute" section. */
7583 			p2pie[p2pielen++] = 0x04;
7584 
7585 			/*	Operating Class */
7586 			p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
7587 
7588 			/*	Channel Number */
7589 			p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
7590 
7591 
7592 			/*	P2P Group BSSID */
7593 			/*	Type: */
7594 			p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
7595 
7596 			/*	Length: */
7597 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7598 			p2pielen += 2;
7599 
7600 			/*	Value: */
7601 			/*	P2P Device Address for GO */
7602 			_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7603 			p2pielen += ETH_ALEN;
7604 
7605 		}
7606 
7607 		/*	Channel List */
7608 		/*	Type: */
7609 		p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7610 
7611 		/*	Length: */
7612 		/* Country String(3) */
7613 		/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7614 		/* + number of channels in all classes */
7615 		len_channellist_attr = 3
7616 			+ (1 + 1) * (u16)ch_list->reg_classes
7617 			+ get_reg_classes_full_count(ch_list);
7618 
7619 #ifdef CONFIG_CONCURRENT_MODE
7620 		if (rtw_mi_check_status(padapter, MI_LINKED))
7621 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7622 		else
7623 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7624 
7625 #else
7626 
7627 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7628 
7629 #endif
7630 		p2pielen += 2;
7631 
7632 		/*	Value: */
7633 		/*	Country String */
7634 		p2pie[p2pielen++] = 'X';
7635 		p2pie[p2pielen++] = 'X';
7636 
7637 		/*	The third byte should be set to 0x04. */
7638 		/*	Described in the "Operating Channel Attribute" section. */
7639 		p2pie[p2pielen++] = 0x04;
7640 
7641 		/*	Channel Entry List */
7642 #ifdef CONFIG_CONCURRENT_MODE
7643 		if (rtw_mi_check_status(padapter, MI_LINKED)) {
7644 			u8 union_ch = rtw_mi_get_union_chan(padapter);
7645 
7646 			/*	Operating Class */
7647 			if (union_ch > 14) {
7648 				if (union_ch >= 149)
7649 					p2pie[p2pielen++] = 0x7c;
7650 				else
7651 					p2pie[p2pielen++] = 0x73;
7652 
7653 			} else
7654 				p2pie[p2pielen++] = 0x51;
7655 
7656 
7657 			/*	Number of Channels */
7658 			/*	Just support 1 channel and this channel is AP's channel */
7659 			p2pie[p2pielen++] = 1;
7660 
7661 			/*	Channel List */
7662 			p2pie[p2pielen++] = union_ch;
7663 		} else
7664 #endif /* CONFIG_CONCURRENT_MODE */
7665 		{
7666 			int i, j;
7667 			for (j = 0; j < ch_list->reg_classes; j++) {
7668 				/*	Operating Class */
7669 				p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7670 
7671 				/*	Number of Channels */
7672 				p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7673 
7674 				/*	Channel List */
7675 				for (i = 0; i < ch_list->reg_class[j].channels; i++)
7676 					p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7677 			}
7678 		}
7679 	}
7680 #endif
7681 
7682 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7683 
7684 #ifdef CONFIG_WFD
7685 	wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
7686 	pframe += wfdielen;
7687 	pktlen += wfdielen;
7688 #endif
7689 
7690 	*pLength = pktlen;
7691 
7692 #if 0
7693 	/* printf dbg msg */
7694 	dbgbufLen = pktlen;
7695 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7696 
7697 	for (index = 0; index < dbgbufLen; index++)
7698 		printk("%x ", *(dbgbuf + index));
7699 
7700 	printk("\n");
7701 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7702 #endif
7703 }
7704 
7705 
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7706 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7707 {
7708 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7709 	u8			action = P2P_PUB_ACTION_ACTION;
7710 	u8			dialogToken = 0;
7711 	u32			p2poui = cpu_to_be32(P2POUI);
7712 	u8			oui_subtype = P2P_PROVISION_DISC_RESP;
7713 	u8			wpsie[100] = { 0x00 };
7714 	u8			wpsielen = 0;
7715 	u32			pktlen;
7716 #ifdef CONFIG_WFD
7717 	u32					wfdielen = 0;
7718 #endif
7719 
7720 	/* struct xmit_frame			*pmgntframe; */
7721 	/* struct pkt_attrib			*pattrib; */
7722 	/* unsigned char					*pframe; */
7723 	struct rtw_ieee80211_hdr	*pwlanhdr;
7724 	unsigned short				*fctrl;
7725 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
7726 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7727 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7728 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7729 
7730 	/* for debug */
7731 	u8 *dbgbuf = pframe;
7732 	u8 dbgbufLen = 0, index = 0;
7733 
7734 	RTW_INFO("%s\n", __FUNCTION__);
7735 
7736 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7737 
7738 	fctrl = &(pwlanhdr->frame_ctl);
7739 	*(fctrl) = 0;
7740 
7741 	/* RA filled by FW */
7742 	_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7743 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7744 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7745 
7746 	SetSeqNum(pwlanhdr, 0);
7747 	set_frame_sub_type(pframe, WIFI_ACTION);
7748 
7749 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7750 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7751 
7752 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7753 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7754 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7755 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7756 	/* dialog token, filled by FW */
7757 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7758 
7759 	wpsielen = 0;
7760 	/*	WPS OUI */
7761 	/* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
7762 	RTW_PUT_BE32(wpsie, WPSOUI);
7763 	wpsielen += 4;
7764 
7765 #if 0
7766 	/*	WPS version */
7767 	/*	Type: */
7768 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7769 	wpsielen += 2;
7770 
7771 	/*	Length: */
7772 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7773 	wpsielen += 2;
7774 
7775 	/*	Value: */
7776 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
7777 #endif
7778 
7779 	/*	Config Method */
7780 	/*	Type: */
7781 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
7782 	RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
7783 	wpsielen += 2;
7784 
7785 	/*	Length: */
7786 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
7787 	RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
7788 	wpsielen += 2;
7789 
7790 	/*	Value: filled by FW, default value is PBC */
7791 	/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
7792 	RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
7793 	wpsielen += 2;
7794 
7795 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7796 
7797 #ifdef CONFIG_WFD
7798 	wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
7799 	pframe += wfdielen;
7800 	pktlen += wfdielen;
7801 #endif
7802 
7803 	*pLength = pktlen;
7804 
7805 	/* printf dbg msg */
7806 #if 0
7807 	dbgbufLen = pktlen;
7808 	RTW_INFO("======> DBG MSG FOR CONSTRAUCT  ProvisionDis Rsp\n");
7809 
7810 	for (index = 0; index < dbgbufLen; index++)
7811 		printk("%x ", *(dbgbuf + index));
7812 
7813 	printk("\n");
7814 	RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7815 #endif
7816 }
7817 
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)7818 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
7819 {
7820 	u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
7821 	struct hal_ops *pHalFunc = &adapter->hal_func;
7822 	u8 ret = _FAIL;
7823 
7824 	RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
7825 		 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
7826 		 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
7827 		 rsvdpageloc->LocPDRsp);
7828 
7829 	SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
7830 	SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
7831 	SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
7832 	SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
7833 	SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
7834 
7835 	/* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
7836 	ret = rtw_hal_fill_h2c_cmd(adapter,
7837 				   H2C_P2P_OFFLOAD_RSVD_PAGE,
7838 				   H2C_P2PRSVDPAGE_LOC_LEN,
7839 				   u1H2CP2PRsvdPageParm);
7840 
7841 	return ret;
7842 }
7843 
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)7844 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
7845 {
7846 
7847 	u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
7848 	struct wifidirect_info	*pwdinfo = &(adapter->wdinfo);
7849 	struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
7850 	struct hal_ops *pHalFunc = &adapter->hal_func;
7851 	u8 ret = _FAIL;
7852 
7853 	_rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
7854 	RTW_INFO("%s\n", __func__);
7855 	switch (pwdinfo->role) {
7856 	case P2P_ROLE_DEVICE:
7857 		RTW_INFO("P2P_ROLE_DEVICE\n");
7858 		p2p_wowlan_offload->role = 0;
7859 		break;
7860 	case P2P_ROLE_CLIENT:
7861 		RTW_INFO("P2P_ROLE_CLIENT\n");
7862 		p2p_wowlan_offload->role = 1;
7863 		break;
7864 	case P2P_ROLE_GO:
7865 		RTW_INFO("P2P_ROLE_GO\n");
7866 		p2p_wowlan_offload->role = 2;
7867 		break;
7868 	default:
7869 		RTW_INFO("P2P_ROLE_DISABLE\n");
7870 		break;
7871 	}
7872 	p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
7873 	p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
7874 	offload_cmd = (u8 *)p2p_wowlan_offload;
7875 	RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
7876 
7877 	ret = rtw_hal_fill_h2c_cmd(adapter,
7878 				   H2C_P2P_OFFLOAD,
7879 				   H2C_P2P_OFFLOAD_LEN,
7880 				   offload_cmd);
7881 	return ret;
7882 
7883 	/* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
7884 }
7885 #endif /* CONFIG_P2P_WOWLAN */
7886 
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)7887 void rtw_hal_construct_beacon(_adapter *padapter,
7888 				     u8 *pframe, u32 *pLength)
7889 {
7890 	struct rtw_ieee80211_hdr	*pwlanhdr;
7891 	u16					*fctrl;
7892 	u32					pktlen;
7893 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7894 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7895 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
7896 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7897 
7898 
7899 	/* RTW_INFO("%s\n", __FUNCTION__); */
7900 
7901 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7902 
7903 	fctrl = &(pwlanhdr->frame_ctl);
7904 	*(fctrl) = 0;
7905 
7906 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7907 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7908 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7909 
7910 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7911 	/* pmlmeext->mgnt_seq++; */
7912 	set_frame_sub_type(pframe, WIFI_BEACON);
7913 
7914 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7915 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7916 
7917 	/* timestamp will be inserted by hardware */
7918 	pframe += 8;
7919 	pktlen += 8;
7920 
7921 	/* beacon interval: 2 bytes */
7922 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7923 
7924 	pframe += 2;
7925 	pktlen += 2;
7926 
7927 #if 0
7928 	/* capability info: 2 bytes */
7929 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7930 
7931 	pframe += 2;
7932 	pktlen += 2;
7933 
7934 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
7935 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
7936 		pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
7937 		_rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
7938 
7939 		goto _ConstructBeacon;
7940 	}
7941 
7942 	/* below for ad-hoc mode */
7943 
7944 	/* SSID */
7945 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
7946 
7947 	/* supported rates... */
7948 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7949 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
7950 
7951 	/* DS parameter set */
7952 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
7953 
7954 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
7955 		u32 ATIMWindow;
7956 		/* IBSS Parameter Set... */
7957 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
7958 		ATIMWindow = 0;
7959 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
7960 	}
7961 
7962 
7963 	/* todo: ERP IE */
7964 
7965 
7966 	/* EXTERNDED SUPPORTED RATE */
7967 	if (rate_len > 8)
7968 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
7969 
7970 	/* todo:HT for adhoc */
7971 
7972 _ConstructBeacon:
7973 #endif
7974 
7975 	if ((pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
7976 		RTW_ERR("beacon frame too large ,len(%d,%d)\n",
7977 			(pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
7978 		rtw_warn_on(1);
7979 		return;
7980 	}
7981 
7982 	*pLength = pktlen;
7983 
7984 	/* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
7985 
7986 }
7987 
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)7988 static void rtw_hal_construct_PSPoll(_adapter *padapter,
7989 				     u8 *pframe, u32 *pLength)
7990 {
7991 	struct rtw_ieee80211_hdr	*pwlanhdr;
7992 	u16					*fctrl;
7993 	u32					pktlen;
7994 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7995 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7996 
7997 	/* RTW_INFO("%s\n", __FUNCTION__); */
7998 
7999 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8000 
8001 	/* Frame control. */
8002 	fctrl = &(pwlanhdr->frame_ctl);
8003 	*(fctrl) = 0;
8004 	SetPwrMgt(fctrl);
8005 	set_frame_sub_type(pframe, WIFI_PSPOLL);
8006 
8007 	/* AID. */
8008 	set_duration(pframe, (pmlmeinfo->aid | 0xc000));
8009 
8010 	/* BSSID. */
8011 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8012 
8013 	/* TA. */
8014 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8015 
8016 	*pLength = 16;
8017 }
8018 
8019 
8020 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_construct_fw_dbg_msg_pkt(PADAPTER padapter,u8 * pframe,u32 * plength)8021 void rtw_hal_construct_fw_dbg_msg_pkt(
8022 	PADAPTER padapter,
8023 	u8		*pframe,
8024 	u32		*plength)
8025 {
8026 	struct rtw_ieee80211_hdr	*pwlanhdr;
8027 	u16						*fctrl;
8028 	u32						pktlen;
8029 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
8030 	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
8031 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8032 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8033 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8034 
8035 
8036 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8037 
8038 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8039 
8040 	fctrl = &pwlanhdr->frame_ctl;
8041 	*(fctrl) = 0;
8042 
8043 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8044 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8045 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8046 
8047 	SetSeqNum(pwlanhdr, 0);
8048 
8049 	set_frame_sub_type(pframe, WIFI_DATA);
8050 
8051 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8052 
8053 	*plength = pktlen;
8054 }
8055 #endif /*DBG_FW_DEBUG_MSG_PKT*/
8056 
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)8057 void rtw_hal_construct_NullFunctionData(
8058 	PADAPTER padapter,
8059 	u8		*pframe,
8060 	u32		*pLength,
8061 	u8		bQoS,
8062 	u8		AC,
8063 	u8		bEosp,
8064 	u8		bForcePowerSave)
8065 {
8066 	struct rtw_ieee80211_hdr	*pwlanhdr;
8067 	u16						*fctrl;
8068 	u32						pktlen;
8069 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
8070 	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
8071 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8072 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8073 	u8 *sta_addr = NULL;
8074 	u8 bssid[ETH_ALEN] = {0};
8075 
8076 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8077 
8078 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8079 
8080 	fctrl = &pwlanhdr->frame_ctl;
8081 	*(fctrl) = 0;
8082 	if (bForcePowerSave)
8083 		SetPwrMgt(fctrl);
8084 
8085 	sta_addr = get_my_bssid(&pmlmeinfo->network);
8086 	if (NULL == sta_addr) {
8087 		_rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);
8088 		sta_addr = bssid;
8089 	}
8090 
8091 	switch (cur_network->network.InfrastructureMode) {
8092 	case Ndis802_11Infrastructure:
8093 		SetToDs(fctrl);
8094 		_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8095 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8096 		_rtw_memcpy(pwlanhdr->addr3, sta_addr, ETH_ALEN);
8097 		break;
8098 	case Ndis802_11APMode:
8099 		SetFrDs(fctrl);
8100 		_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8101 		_rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8102 		_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8103 		break;
8104 	case Ndis802_11IBSS:
8105 	default:
8106 		_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8107 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8108 		_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8109 		break;
8110 	}
8111 
8112 	SetSeqNum(pwlanhdr, 0);
8113 	set_duration(pwlanhdr, 0);
8114 
8115 	if (bQoS == _TRUE) {
8116 		struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
8117 
8118 		set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
8119 
8120 		pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
8121 		SetPriority(&pwlanqoshdr->qc, AC);
8122 		SetEOSP(&pwlanqoshdr->qc, bEosp);
8123 
8124 		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
8125 	} else {
8126 		set_frame_sub_type(pframe, WIFI_DATA_NULL);
8127 
8128 		pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8129 	}
8130 
8131 	*pLength = pktlen;
8132 }
8133 
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,BOOLEAN bHideSSID)8134 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
8135 				BOOLEAN bHideSSID)
8136 {
8137 	struct rtw_ieee80211_hdr	*pwlanhdr;
8138 	u16					*fctrl;
8139 	u8					*mac, *bssid, *sta_addr;
8140 	u32					pktlen;
8141 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8142 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8143 	WLAN_BSSID_EX  *cur_network = &(pmlmeinfo->network);
8144 
8145 	/*RTW_INFO("%s\n", __FUNCTION__);*/
8146 
8147 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8148 
8149 	mac = adapter_mac_addr(padapter);
8150 	bssid = cur_network->MacAddress;
8151 	sta_addr = get_my_bssid(&pmlmeinfo->network);
8152 
8153 	fctrl = &(pwlanhdr->frame_ctl);
8154 	*(fctrl) = 0;
8155 	_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8156 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8157 	_rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8158 
8159 	SetSeqNum(pwlanhdr, 0);
8160 	set_frame_sub_type(fctrl, WIFI_PROBERSP);
8161 
8162 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8163 	pframe += pktlen;
8164 
8165 	if (cur_network->IELength > MAX_IE_SZ)
8166 		return;
8167 
8168 	_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8169 	pframe += cur_network->IELength;
8170 	pktlen += cur_network->IELength;
8171 
8172 	*pLength = pktlen;
8173 }
8174 
8175 #ifdef CONFIG_WOWLAN
rtw_hal_append_tkip_mic(PADAPTER padapter,u8 * pframe,u32 offset)8176 static void rtw_hal_append_tkip_mic(PADAPTER padapter,
8177 				    u8 *pframe, u32 offset)
8178 {
8179 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8180 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8181 	struct rtw_ieee80211_hdr	*pwlanhdr;
8182 	struct mic_data	micdata;
8183 	struct sta_info	*psta = NULL;
8184 	int res = 0;
8185 
8186 	u8	*payload = (u8 *)(pframe + offset);
8187 
8188 	u8	mic[8];
8189 	u8	priority[4] = {0x0};
8190 	u8	null_key[16] = {0x0};
8191 
8192 	RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
8193 
8194 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8195 
8196 	psta = rtw_get_stainfo(&padapter->stapriv,
8197 			get_my_bssid(&(pmlmeinfo->network)));
8198 	if (psta != NULL) {
8199 		res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
8200 				  null_key, 16);
8201 		if (res == _TRUE)
8202 			RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
8203 		rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
8204 	}
8205 
8206 	rtw_secmicappend(&micdata, pwlanhdr->addr3, 6);  /* DA */
8207 
8208 	rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
8209 
8210 	priority[0] = 0;
8211 
8212 	rtw_secmicappend(&micdata, &priority[0], 4);
8213 
8214 	rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
8215 
8216 	rtw_secgetmic(&micdata, &(mic[0]));
8217 
8218 	payload += 36;
8219 
8220 	_rtw_memcpy(payload, &(mic[0]), 8);
8221 }
8222 /*
8223  * Description:
8224  *	Construct the ARP response packet to support ARP offload.
8225  *   */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8226 static void rtw_hal_construct_ARPRsp(
8227 	PADAPTER padapter,
8228 	u8			*pframe,
8229 	u32			*pLength,
8230 	u8			*pIPAddress
8231 )
8232 {
8233 	struct rtw_ieee80211_hdr	*pwlanhdr;
8234 	u16	*fctrl;
8235 	u32	pktlen;
8236 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8237 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8238 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8239 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8240 	static u8	ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
8241 	u8	*pARPRspPkt = pframe;
8242 	/* for TKIP Cal MIC */
8243 	u8	*payload = pframe;
8244 	u8	EncryptionHeadOverhead = 0, arp_offset = 0;
8245 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8246 
8247 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8248 
8249 	fctrl = &pwlanhdr->frame_ctl;
8250 	*(fctrl) = 0;
8251 
8252 	/* ------------------------------------------------------------------------- */
8253 	/* MAC Header. */
8254 	/* ------------------------------------------------------------------------- */
8255 	SetFrameType(fctrl, WIFI_DATA);
8256 	/* set_frame_sub_type(fctrl, 0); */
8257 	SetToDs(fctrl);
8258 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8259 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8260 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8261 
8262 	SetSeqNum(pwlanhdr, 0);
8263 	set_duration(pwlanhdr, 0);
8264 	/* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
8265 	/* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
8266 	/* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
8267 	/* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
8268 	/* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
8269 	/* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
8270 
8271 	/* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
8272 	/* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
8273 #ifdef CONFIG_WAPI_SUPPORT
8274 	*pLength = sMacHdrLng;
8275 #else
8276 	*pLength = 24;
8277 #endif
8278 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8279 	case _WEP40_:
8280 	case _WEP104_:
8281 		EncryptionHeadOverhead = 4;
8282 		break;
8283 	case _TKIP_:
8284 		EncryptionHeadOverhead = 8;
8285 		break;
8286 	case _AES_:
8287 		EncryptionHeadOverhead = 8;
8288 		break;
8289 #ifdef CONFIG_WAPI_SUPPORT
8290 	case _SMS4_:
8291 		EncryptionHeadOverhead = 18;
8292 		break;
8293 #endif
8294 	default:
8295 		EncryptionHeadOverhead = 0;
8296 	}
8297 
8298 	if (EncryptionHeadOverhead > 0) {
8299 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8300 		*pLength += EncryptionHeadOverhead;
8301 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8302 		SetPrivacy(fctrl);
8303 	}
8304 
8305 	/* ------------------------------------------------------------------------- */
8306 	/* Frame Body. */
8307 	/* ------------------------------------------------------------------------- */
8308 	arp_offset = *pLength;
8309 	pARPRspPkt = (u8 *)(pframe + arp_offset);
8310 	payload = pARPRspPkt; /* Get Payload pointer */
8311 	/* LLC header */
8312 	_rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
8313 	*pLength += 8;
8314 
8315 	/* ARP element */
8316 	pARPRspPkt += 8;
8317 	SET_ARP_HTYPE(pARPRspPkt, 1);
8318 	SET_ARP_PTYPE(pARPRspPkt, ETH_P_IP);	/* IP protocol */
8319 	SET_ARP_HLEN(pARPRspPkt, ETH_ALEN);
8320 	SET_ARP_PLEN(pARPRspPkt, RTW_IP_ADDR_LEN);
8321 	SET_ARP_OPER(pARPRspPkt, 2);	/* ARP response */
8322 	SET_ARP_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
8323 	SET_ARP_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
8324 #ifdef CONFIG_ARP_KEEP_ALIVE
8325 	if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
8326 		SET_ARP_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
8327 		SET_ARP_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
8328 	} else
8329 #endif
8330 	{
8331 		SET_ARP_TARGET_MAC_ADDR(pARPRspPkt,
8332 				    get_my_bssid(&(pmlmeinfo->network)));
8333 		SET_ARP_TARGET_IP_ADDR(pARPRspPkt,
8334 					   pIPAddress);
8335 		RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
8336 			 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
8337 		RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
8338 			 IP_ARG(pIPAddress));
8339 	}
8340 
8341 	*pLength += 28;
8342 
8343 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8344 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
8345 		    IS_HARDWARE_TYPE_8812(padapter)) {
8346 			rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
8347 		}
8348 		*pLength += 8;
8349 	}
8350 }
8351 
8352 #ifdef CONFIG_IPV6
8353 /*
8354  * Description: Neighbor Discovery Offload.
8355  */
rtw_hal_construct_na_message(_adapter * padapter,u8 * pframe,u32 * pLength)8356 static void rtw_hal_construct_na_message(_adapter *padapter,
8357 				     u8 *pframe, u32 *pLength)
8358 {
8359 	struct rtw_ieee80211_hdr *pwlanhdr = NULL;
8360 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8361 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
8362 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
8363 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8364 
8365 	u32 pktlen = 0;
8366 	u16 *fctrl = NULL;
8367 
8368 	u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8369 	u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
8370 	u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
8371 	u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
8372 	u8 val8 = 0;
8373 
8374 	u8 *p_na_msg = pframe;
8375 	/* for TKIP Cal MIC */
8376 	u8 *payload = pframe;
8377 	u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
8378 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8379 
8380 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8381 
8382 	fctrl = &pwlanhdr->frame_ctl;
8383 	*(fctrl) = 0;
8384 
8385 	/* ------------------------------------------------------------------------- */
8386 	/* MAC Header. */
8387 	/* ------------------------------------------------------------------------- */
8388 	SetFrameType(fctrl, WIFI_DATA);
8389 	SetToDs(fctrl);
8390 	_rtw_memcpy(pwlanhdr->addr1,
8391 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8392 	_rtw_memcpy(pwlanhdr->addr2,
8393 		    adapter_mac_addr(padapter), ETH_ALEN);
8394 	_rtw_memcpy(pwlanhdr->addr3,
8395 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8396 
8397 	SetSeqNum(pwlanhdr, 0);
8398 	set_duration(pwlanhdr, 0);
8399 
8400 #ifdef CONFIG_WAPI_SUPPORT
8401 	*pLength = sMacHdrLng;
8402 #else
8403 	*pLength = 24;
8404 #endif
8405 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8406 	case _WEP40_:
8407 	case _WEP104_:
8408 		EncryptionHeadOverhead = 4;
8409 		break;
8410 	case _TKIP_:
8411 		EncryptionHeadOverhead = 8;
8412 		break;
8413 	case _AES_:
8414 		EncryptionHeadOverhead = 8;
8415 		break;
8416 #ifdef CONFIG_WAPI_SUPPORT
8417 	case _SMS4_:
8418 		EncryptionHeadOverhead = 18;
8419 		break;
8420 #endif
8421 	default:
8422 		EncryptionHeadOverhead = 0;
8423 	}
8424 
8425 	if (EncryptionHeadOverhead > 0) {
8426 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8427 		*pLength += EncryptionHeadOverhead;
8428 		/* SET_80211_HDR_WEP(pARPRspPkt, 1);  */ /* Suggested by CCW. */
8429 		SetPrivacy(fctrl);
8430 	}
8431 
8432 	/* ------------------------------------------------------------------------- */
8433 	/* Frame Body. */
8434 	/* ------------------------------------------------------------------------- */
8435 	na_msg_offset = *pLength;
8436 	p_na_msg = (u8 *)(pframe + na_msg_offset);
8437 	payload = p_na_msg; /* Get Payload pointer */
8438 
8439 	/* LLC header */
8440 	val8 = sizeof(ns_hdr);
8441 	_rtw_memcpy(p_na_msg, ns_hdr, val8);
8442 	*pLength += val8;
8443 	p_na_msg += val8;
8444 
8445 	/* IPv6 Header */
8446 	/* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
8447 	val8 = sizeof(ipv6_info);
8448 	_rtw_memcpy(p_na_msg, ipv6_info, val8);
8449 	*pLength += val8;
8450 	p_na_msg += val8;
8451 
8452 	/* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
8453 	val8 = sizeof(ipv6_contx);
8454 	_rtw_memcpy(p_na_msg, ipv6_contx, val8);
8455 	*pLength += val8;
8456 	p_na_msg += val8;
8457 
8458 	/* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
8459 	_rtw_memset(&(p_na_msg[*pLength]), 0, 32);
8460 	*pLength += 32;
8461 	p_na_msg += 32;
8462 
8463 	/* ICMPv6 */
8464 	/* 1. Type : 0x88 (NA)
8465 	 * 2. Code : 0x00
8466 	 * 3. ChechSum : 0x00 0x00 (RSvd)
8467 	 * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
8468 	 */
8469 	val8 = sizeof(icmpv6_hdr);
8470 	_rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
8471 	*pLength += val8;
8472 	p_na_msg += val8;
8473 
8474 	/* TA: 16 bytes*/
8475 	_rtw_memset(&(p_na_msg[*pLength]), 0, 16);
8476 	*pLength += 16;
8477 	p_na_msg += 16;
8478 
8479 	/* ICMPv6 Target Link Layer Address */
8480 	p_na_msg[0] = 0x02; /* type */
8481 	p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
8482 	*pLength += 2;
8483 	p_na_msg += 2;
8484 
8485 	_rtw_memset(&(p_na_msg[*pLength]), 0, 6);
8486 	*pLength += 6;
8487 	p_na_msg += 6;
8488 
8489 	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8490 		if (IS_HARDWARE_TYPE_8188E(padapter) ||
8491 		    IS_HARDWARE_TYPE_8812(padapter)) {
8492 			rtw_hal_append_tkip_mic(padapter, pframe,
8493 						na_msg_offset);
8494 		}
8495 		*pLength += 8;
8496 	}
8497 }
8498 /*
8499  * Description: Neighbor Discovery Protocol Information.
8500  */
rtw_hal_construct_ndp_info(_adapter * padapter,u8 * pframe,u32 * pLength)8501 static void rtw_hal_construct_ndp_info(_adapter *padapter,
8502 				     u8 *pframe, u32 *pLength)
8503 {
8504 	struct mlme_ext_priv *pmlmeext = NULL;
8505 	struct mlme_ext_info *pmlmeinfo = NULL;
8506 	struct rtw_ndp_info ndp_info;
8507 	u8	*pndp_info = pframe;
8508 	u8	len = sizeof(struct rtw_ndp_info);
8509 
8510 	RTW_INFO("%s: len: %d\n", __func__, len);
8511 
8512 	pmlmeext =  &padapter->mlmeextpriv;
8513 	pmlmeinfo = &pmlmeext->mlmext_info;
8514 
8515 	_rtw_memset(pframe, 0, len);
8516 	_rtw_memset(&ndp_info, 0, len);
8517 
8518 	ndp_info.enable = 1;
8519 	ndp_info.check_remote_ip = 0;
8520 	ndp_info.num_of_target_ip = 1;
8521 
8522 	_rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
8523 		    ETH_ALEN);
8524 	_rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
8525 		    RTW_IPv6_ADDR_LEN);
8526 
8527 	_rtw_memcpy(pndp_info, &ndp_info, len);
8528 }
8529 #endif /* CONFIG_IPV6 */
8530 
8531 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)8532 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
8533 				       u32 *pLength, pno_ssid_t *ssid)
8534 {
8535 	struct rtw_ieee80211_hdr	*pwlanhdr;
8536 	u16				*fctrl;
8537 	u32				pktlen;
8538 	unsigned char			*mac;
8539 	unsigned char			bssrate[NumRates];
8540 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
8541 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8542 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8543 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8544 	int	bssrate_len = 0;
8545 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8546 
8547 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8548 	mac = adapter_mac_addr(padapter);
8549 
8550 	fctrl = &(pwlanhdr->frame_ctl);
8551 	*(fctrl) = 0;
8552 
8553 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8554 	_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8555 
8556 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8557 
8558 	SetSeqNum(pwlanhdr, 0);
8559 	set_frame_sub_type(pframe, WIFI_PROBEREQ);
8560 
8561 	pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8562 	pframe += pktlen;
8563 
8564 	if (ssid == NULL)
8565 		pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
8566 	else {
8567 		/* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
8568 		pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
8569 	}
8570 
8571 	get_rate_set(padapter, bssrate, &bssrate_len);
8572 
8573 	if (bssrate_len > 8) {
8574 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
8575 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
8576 	} else
8577 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
8578 
8579 	*pLength = pktlen;
8580 }
8581 
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)8582 static void rtw_hal_construct_PNO_info(_adapter *padapter,
8583 				       u8 *pframe, u32 *pLength)
8584 {
8585 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8586 	int i;
8587 
8588 	u8	*pPnoInfoPkt = pframe;
8589 	pPnoInfoPkt = (u8 *)(pframe + *pLength);
8590 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
8591 
8592 	pPnoInfoPkt += 1;
8593 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
8594 
8595 	pPnoInfoPkt += 3;
8596 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
8597 
8598 	pPnoInfoPkt += 4;
8599 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
8600 
8601 	pPnoInfoPkt += 4;
8602 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
8603 
8604 	pPnoInfoPkt += 4;
8605 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
8606 
8607 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8608 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
8609 
8610 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8611 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
8612 
8613 	pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8614 	_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
8615 
8616 	pPnoInfoPkt += MAX_HIDDEN_AP;
8617 
8618 	/*
8619 	SSID is located at 128th Byte in NLO info Page
8620 	*/
8621 
8622 	*pLength += 128;
8623 	pPnoInfoPkt = pframe + 128;
8624 
8625 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8626 		_rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8627 			    pwrctl->pnlo_info->ssid_length[i]);
8628 		*pLength += WLAN_SSID_MAXLEN;
8629 		pPnoInfoPkt += WLAN_SSID_MAXLEN;
8630 	}
8631 }
8632 
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)8633 static void rtw_hal_construct_ssid_list(_adapter *padapter,
8634 					u8 *pframe, u32 *pLength)
8635 {
8636 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8637 	u8 *pSSIDListPkt = pframe;
8638 	int i;
8639 
8640 	pSSIDListPkt = (u8 *)(pframe + *pLength);
8641 
8642 	for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8643 		_rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8644 			    pwrctl->pnlo_info->ssid_length[i]);
8645 
8646 		*pLength += WLAN_SSID_MAXLEN;
8647 		pSSIDListPkt += WLAN_SSID_MAXLEN;
8648 	}
8649 }
8650 
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)8651 static void rtw_hal_construct_scan_info(_adapter *padapter,
8652 					u8 *pframe, u32 *pLength)
8653 {
8654 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8655 	u8 *pScanInfoPkt = pframe;
8656 	int i;
8657 
8658 	pScanInfoPkt = (u8 *)(pframe + *pLength);
8659 
8660 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
8661 
8662 	*pLength += 1;
8663 	pScanInfoPkt += 1;
8664 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
8665 
8666 
8667 	*pLength += 1;
8668 	pScanInfoPkt += 1;
8669 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
8670 
8671 
8672 	*pLength += 1;
8673 	pScanInfoPkt += 1;
8674 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
8675 
8676 	*pLength += 1;
8677 	pScanInfoPkt += 1;
8678 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
8679 
8680 	*pLength += 1;
8681 	pScanInfoPkt += 1;
8682 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
8683 
8684 	*pLength += 1;
8685 	pScanInfoPkt += 1;
8686 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
8687 
8688 	*pLength += 1;
8689 	pScanInfoPkt += 1;
8690 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
8691 
8692 	*pLength += 1;
8693 	pScanInfoPkt += 1;
8694 	_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
8695 
8696 	*pLength += 8;
8697 	pScanInfoPkt += 8;
8698 
8699 	for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
8700 		_rtw_memcpy(pScanInfoPkt,
8701 			    &pwrctl->pscan_info->ssid_channel_info[i], 4);
8702 		*pLength += 4;
8703 		pScanInfoPkt += 4;
8704 	}
8705 }
8706 #endif /* CONFIG_PNO_SUPPORT */
8707 
8708 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)8709 static void rtw_hal_construct_GTKRsp(
8710 	PADAPTER	padapter,
8711 	u8		*pframe,
8712 	u32		*pLength
8713 )
8714 {
8715 	struct rtw_ieee80211_hdr	*pwlanhdr;
8716 	u16	*fctrl;
8717 	u32	pktlen;
8718 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
8719 	struct wlan_network	*cur_network = &pmlmepriv->cur_network;
8720 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8721 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8722 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
8723 	static u8	LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
8724 	static u8	GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
8725 	u8	*pGTKRspPkt = pframe;
8726 	u8	EncryptionHeadOverhead = 0;
8727 	/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8728 
8729 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8730 
8731 	fctrl = &pwlanhdr->frame_ctl;
8732 	*(fctrl) = 0;
8733 
8734 	/* ------------------------------------------------------------------------- */
8735 	/* MAC Header. */
8736 	/* ------------------------------------------------------------------------- */
8737 	SetFrameType(fctrl, WIFI_DATA);
8738 	/* set_frame_sub_type(fctrl, 0); */
8739 	SetToDs(fctrl);
8740 
8741 	_rtw_memcpy(pwlanhdr->addr1,
8742 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8743 
8744 	_rtw_memcpy(pwlanhdr->addr2,
8745 		    adapter_mac_addr(padapter), ETH_ALEN);
8746 
8747 	_rtw_memcpy(pwlanhdr->addr3,
8748 		    get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8749 
8750 	SetSeqNum(pwlanhdr, 0);
8751 	set_duration(pwlanhdr, 0);
8752 
8753 #ifdef CONFIG_WAPI_SUPPORT
8754 	*pLength = sMacHdrLng;
8755 #else
8756 	*pLength = 24;
8757 #endif /* CONFIG_WAPI_SUPPORT */
8758 
8759 	/* ------------------------------------------------------------------------- */
8760 	/* Security Header: leave space for it if necessary. */
8761 	/* ------------------------------------------------------------------------- */
8762 	switch (psecuritypriv->dot11PrivacyAlgrthm) {
8763 	case _WEP40_:
8764 	case _WEP104_:
8765 		EncryptionHeadOverhead = 4;
8766 		break;
8767 	case _TKIP_:
8768 		EncryptionHeadOverhead = 8;
8769 		break;
8770 	case _AES_:
8771 		EncryptionHeadOverhead = 8;
8772 		break;
8773 #ifdef CONFIG_WAPI_SUPPORT
8774 	case _SMS4_:
8775 		EncryptionHeadOverhead = 18;
8776 		break;
8777 #endif /* CONFIG_WAPI_SUPPORT */
8778 	default:
8779 		EncryptionHeadOverhead = 0;
8780 	}
8781 
8782 	if (EncryptionHeadOverhead > 0) {
8783 		_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8784 		*pLength += EncryptionHeadOverhead;
8785 		/* SET_80211_HDR_WEP(pGTKRspPkt, 1);  */ /* Suggested by CCW. */
8786 		/* GTK's privacy bit is done by FW */
8787 		/* SetPrivacy(fctrl); */
8788 	}
8789 	/* ------------------------------------------------------------------------- */
8790 	/* Frame Body. */
8791 	/* ------------------------------------------------------------------------- */
8792 	pGTKRspPkt = (u8 *)(pframe + *pLength);
8793 	/* LLC header */
8794 	_rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
8795 	*pLength += 8;
8796 
8797 	/* GTK element */
8798 	pGTKRspPkt += 8;
8799 
8800 	/* GTK frame body after LLC, part 1 */
8801 	/* TKIP key_length = 32, AES key_length = 16 */
8802 	if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
8803 		GTKbody_a[8] = 0x20;
8804 
8805 	/* GTK frame body after LLC, part 1 */
8806 	_rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
8807 	*pLength += 11;
8808 	pGTKRspPkt += 11;
8809 	/* GTK frame body after LLC, part 2 */
8810 	_rtw_memset(&(pframe[*pLength]), 0, 88);
8811 	*pLength += 88;
8812 	pGTKRspPkt += 88;
8813 
8814 	if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
8815 		*pLength += 8;
8816 }
8817 #endif /* CONFIG_GTK_OL */
8818 
8819 #define PN_2_CCMPH(ch,key_id)	((ch) & 0x000000000000ffff) \
8820 				| (((ch) & 0x0000ffffffff0000) << 16) \
8821 				| (((key_id) << 30)) \
8822 				| BIT(29)
rtw_hal_construct_remote_control_info(_adapter * adapter,u8 * pframe,u32 * pLength)8823 static void rtw_hal_construct_remote_control_info(_adapter *adapter,
8824 						  u8 *pframe, u32 *pLength)
8825 {
8826 	struct mlme_priv   *pmlmepriv = &adapter->mlmepriv;
8827 	struct sta_priv *pstapriv = &adapter->stapriv;
8828 	struct security_priv *psecuritypriv = &adapter->securitypriv;
8829 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
8830 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8831 	struct sta_info *psta;
8832 	struct stainfo_rxcache *prxcache;
8833 	u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
8834 	size_t sz = 0, total = 0;
8835 	u64 ccmp_hdr = 0, tmp_key = 0;
8836 
8837 	psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
8838 
8839 	if (psta == NULL) {
8840 		rtw_warn_on(1);
8841 		return;
8842 	}
8843 
8844 	prxcache = &psta->sta_recvpriv.rxcache;
8845 	sz = sizeof(cur_dot11rxiv);
8846 
8847 	/* 3 SEC IV * 1 page */
8848 	rtw_get_sec_iv(adapter, cur_dot11rxiv,
8849 		       get_my_bssid(&pmlmeinfo->network));
8850 
8851 	_rtw_memcpy(pframe, cur_dot11rxiv, sz);
8852 	*pLength += sz;
8853 	pframe += sz;
8854 
8855 	_rtw_memset(&cur_dot11rxiv, 0, sz);
8856 
8857 	if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
8858 		id = psecuritypriv->dot118021XGrpKeyid;
8859 		tid_id = prxcache->last_tid;
8860 		REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
8861 		REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
8862 		REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
8863 		REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
8864 		_rtw_memcpy(pframe, cur_dot11rxiv, sz);
8865 		*pLength += sz;
8866 		pframe += sz;
8867 
8868 		_rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
8869 		*pLength += sz;
8870 		pframe += sz;
8871 
8872 		total = sizeof(psecuritypriv->iv_seq);
8873 		total /= sizeof(psecuritypriv->iv_seq[0]);
8874 
8875 		for (i = 0 ; i < total ; i ++) {
8876 			ccmp_hdr =
8877 				le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
8878 			_rtw_memset(&cur_dot11rxiv, 0, sz);
8879 			if (ccmp_hdr != 0) {
8880 				tmp_key = i;
8881 				ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
8882 				*(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
8883 				_rtw_memcpy(pframe, cur_dot11rxiv, sz);
8884 			}
8885 			*pLength += sz;
8886 			pframe += sz;
8887 		}
8888 	}
8889 }
8890 
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)8891 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
8892 		  u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
8893 				  RSVDPAGE_LOC *rsvd_page_loc)
8894 {
8895 	struct security_priv *psecuritypriv = &adapter->securitypriv;
8896 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8897 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8898 	struct mlme_ext_priv	*pmlmeext;
8899 	struct mlme_ext_info	*pmlmeinfo;
8900 	u32	ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
8901 	u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0;
8902 	u8 CurtPktPageNum = 0;
8903 
8904 #ifdef CONFIG_GTK_OL
8905 	struct sta_priv *pstapriv = &adapter->stapriv;
8906 	struct sta_info *psta;
8907 	struct security_priv *psecpriv = &adapter->securitypriv;
8908 	u8 kek[RTW_KEK_LEN];
8909 	u8 kck[RTW_KCK_LEN];
8910 #endif /* CONFIG_GTK_OL */
8911 #ifdef CONFIG_PNO_SUPPORT
8912 	int pno_index;
8913 	u8 ssid_num;
8914 #endif /* CONFIG_PNO_SUPPORT */
8915 
8916 	pmlmeext = &adapter->mlmeextpriv;
8917 	pmlmeinfo = &pmlmeext->mlmext_info;
8918 
8919 	if (pwrctl->wowlan_pno_enable == _FALSE) {
8920 		/* ARP RSP * 1 page */
8921 
8922 		rsvd_page_loc->LocArpRsp = *page_num;
8923 
8924 		RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
8925 
8926 		rtw_hal_construct_ARPRsp(adapter, &pframe[index],
8927 					 &ARPLength, pmlmeinfo->ip_addr);
8928 
8929 		rtw_hal_fill_fake_txdesc(adapter,
8930 					 &pframe[index - tx_desc],
8931 					 ARPLength, _FALSE, _FALSE, _TRUE);
8932 
8933 		CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
8934 
8935 		*page_num += CurtPktPageNum;
8936 
8937 		index += (CurtPktPageNum * page_size);
8938 		RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);
8939 
8940 #ifdef CONFIG_IPV6
8941 		/* 2 NS offload and NDP Info*/
8942 		if (pwrctl->wowlan_ns_offload_en == _TRUE) {
8943 			rsvd_page_loc->LocNbrAdv = *page_num;
8944 			RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
8945 			rtw_hal_construct_na_message(adapter,
8946 						     &pframe[index], &ns_len);
8947 			rtw_hal_fill_fake_txdesc(adapter,
8948 						 &pframe[index - tx_desc],
8949 						 ns_len, _FALSE,
8950 						 _FALSE, _TRUE);
8951 			CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
8952 						      page_size);
8953 			*page_num += CurtPktPageNum;
8954 			index += (CurtPktPageNum * page_size);
8955 			RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);
8956 
8957 			rsvd_page_loc->LocNDPInfo = *page_num;
8958 			RTW_INFO("LocNDPInfo: %d\n",
8959 				 rsvd_page_loc->LocNDPInfo);
8960 
8961 			rtw_hal_construct_ndp_info(adapter,
8962 						   &pframe[index - tx_desc],
8963 						   &ns_len);
8964 			CurtPktPageNum =
8965 				(u8)PageNum(tx_desc + ns_len, page_size);
8966 			*page_num += CurtPktPageNum;
8967 			index += (CurtPktPageNum * page_size);
8968 			RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);
8969 
8970 		}
8971 #endif /*CONFIG_IPV6*/
8972 		/* 3 Remote Control Info. * 1 page */
8973 		rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
8974 		RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
8975 		rtw_hal_construct_remote_control_info(adapter,
8976 						      &pframe[index - tx_desc],
8977 						      &rc_len);
8978 		CurtPktPageNum = (u8)PageNum(rc_len, page_size);
8979 		*page_num += CurtPktPageNum;
8980 		*total_pkt_len = index + rc_len;
8981 		RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
8982 #ifdef CONFIG_GTK_OL
8983 		index += (CurtPktPageNum * page_size);
8984 
8985 		/* if the ap staion info. exists, get the kek, kck from staion info. */
8986 		psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
8987 		if (psta == NULL) {
8988 			_rtw_memset(kek, 0, RTW_KEK_LEN);
8989 			_rtw_memset(kck, 0, RTW_KCK_LEN);
8990 			RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
8991 				 __func__);
8992 		} else {
8993 			_rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
8994 			_rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
8995 		}
8996 
8997 		/* 3 KEK, KCK */
8998 		rsvd_page_loc->LocGTKInfo = *page_num;
8999 		RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
9000 
9001 		if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
9002 			struct security_priv *psecpriv = NULL;
9003 
9004 			psecpriv = &adapter->securitypriv;
9005 			_rtw_memcpy(pframe + index - tx_desc,
9006 				    &psecpriv->dot11PrivacyAlgrthm, 1);
9007 			_rtw_memcpy(pframe + index - tx_desc + 1,
9008 				    &psecpriv->dot118021XGrpPrivacy, 1);
9009 			_rtw_memcpy(pframe + index - tx_desc + 2,
9010 				    kck, RTW_KCK_LEN);
9011 			_rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
9012 				    kek, RTW_KEK_LEN);
9013 			CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
9014 		} else {
9015 
9016 			_rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
9017 			_rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
9018 				    kek, RTW_KEK_LEN);
9019 			GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
9020 
9021 			if (psta != NULL &&
9022 				psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
9023 				_rtw_memcpy(pframe + index - tx_desc + 56,
9024 					&psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
9025 				GTKLength += RTW_TKIP_MIC_LEN;
9026 			}
9027 			CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
9028 		}
9029 #if 0
9030 		{
9031 			int i;
9032 			printk("\ntoFW KCK: ");
9033 			for (i = 0; i < 16; i++)
9034 				printk(" %02x ", kck[i]);
9035 			printk("\ntoFW KEK: ");
9036 			for (i = 0; i < 16; i++)
9037 				printk(" %02x ", kek[i]);
9038 			printk("\n");
9039 		}
9040 
9041 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
9042 			 __FUNCTION__, &pframe[index - tx_desc],
9043 			 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
9044 #endif
9045 
9046 		*page_num += CurtPktPageNum;
9047 
9048 		index += (CurtPktPageNum * page_size);
9049 		RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);
9050 
9051 		/* 3 GTK Response */
9052 		rsvd_page_loc->LocGTKRsp = *page_num;
9053 		RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
9054 		rtw_hal_construct_GTKRsp(adapter, &pframe[index], &GTKLength);
9055 
9056 		rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
9057 					 GTKLength, _FALSE, _FALSE, _TRUE);
9058 #if 0
9059 		{
9060 			int gj;
9061 			printk("123GTK pkt=>\n");
9062 			for (gj = 0; gj < GTKLength + tx_desc; gj++) {
9063 				printk(" %02x ", pframe[index - tx_desc + gj]);
9064 				if ((gj + 1) % 16 == 0)
9065 					printk("\n");
9066 			}
9067 			printk(" <=end\n");
9068 		}
9069 
9070 		RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
9071 			 __FUNCTION__, &pframe[index - tx_desc],
9072 			 (tx_desc + GTKLength));
9073 #endif
9074 
9075 		CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
9076 
9077 		*page_num += CurtPktPageNum;
9078 
9079 		index += (CurtPktPageNum * page_size);
9080 		RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);
9081 
9082 		/* below page is empty for GTK extension memory */
9083 		/* 3(11) GTK EXT MEM */
9084 		rsvd_page_loc->LocGTKEXTMEM = *page_num;
9085 		RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
9086 		CurtPktPageNum = 2;
9087 
9088 		if (page_size >= 256)
9089 			CurtPktPageNum = 1;
9090 
9091 		*page_num += CurtPktPageNum;
9092 		/* extension memory for FW */
9093 		*total_pkt_len = index + (page_size * CurtPktPageNum);
9094 		RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);
9095 #endif /* CONFIG_GTK_OL */
9096 
9097 		index += (CurtPktPageNum * page_size);
9098 
9099 		/*Reserve 1 page for AOAC report*/
9100 		rsvd_page_loc->LocAOACReport = *page_num;
9101 		RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
9102 		*page_num += 1;
9103 		*total_pkt_len = index + (page_size * 1);
9104 		RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);
9105 	} else {
9106 #ifdef CONFIG_PNO_SUPPORT
9107 		if (pwrctl->wowlan_in_resume == _FALSE &&
9108 		    pwrctl->pno_inited == _TRUE) {
9109 
9110 			/* Broadcast Probe Request */
9111 			rsvd_page_loc->LocProbePacket = *page_num;
9112 
9113 			RTW_INFO("loc_probe_req: %d\n",
9114 				 rsvd_page_loc->LocProbePacket);
9115 
9116 			rtw_hal_construct_ProbeReq(
9117 				adapter,
9118 				&pframe[index],
9119 				&ProbeReqLength,
9120 				NULL);
9121 
9122 			rtw_hal_fill_fake_txdesc(adapter,
9123 						 &pframe[index - tx_desc],
9124 				 ProbeReqLength, _FALSE, _FALSE, _FALSE);
9125 
9126 			CurtPktPageNum =
9127 				(u8)PageNum(tx_desc + ProbeReqLength, page_size);
9128 
9129 			*page_num += CurtPktPageNum;
9130 
9131 			index += (CurtPktPageNum * page_size);
9132 			RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9133 
9134 			/* Hidden SSID Probe Request */
9135 			ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
9136 
9137 			for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
9138 				pwrctl->pnlo_info->loc_probe_req[pno_index] =
9139 					*page_num;
9140 
9141 				rtw_hal_construct_ProbeReq(
9142 					adapter,
9143 					&pframe[index],
9144 					&ProbeReqLength,
9145 					&pwrctl->pno_ssid_list->node[pno_index]);
9146 
9147 				rtw_hal_fill_fake_txdesc(adapter,
9148 						 &pframe[index - tx_desc],
9149 					ProbeReqLength, _FALSE, _FALSE, _FALSE);
9150 
9151 				CurtPktPageNum =
9152 					(u8)PageNum(tx_desc + ProbeReqLength, page_size);
9153 
9154 				*page_num += CurtPktPageNum;
9155 
9156 				index += (CurtPktPageNum * page_size);
9157 				RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9158 			}
9159 
9160 			/* PNO INFO Page */
9161 			rsvd_page_loc->LocPNOInfo = *page_num;
9162 			RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
9163 			rtw_hal_construct_PNO_info(adapter,
9164 						   &pframe[index - tx_desc],
9165 						   &PNOLength);
9166 
9167 			CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
9168 			*page_num += CurtPktPageNum;
9169 			index += (CurtPktPageNum * page_size);
9170 			RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);
9171 
9172 			/* Scan Info Page */
9173 			rsvd_page_loc->LocScanInfo = *page_num;
9174 			RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
9175 			rtw_hal_construct_scan_info(adapter,
9176 						    &pframe[index - tx_desc],
9177 						    &ScanInfoLength);
9178 
9179 			CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
9180 			*page_num += CurtPktPageNum;
9181 			*total_pkt_len = index + ScanInfoLength;
9182 			index += (CurtPktPageNum * page_size);
9183 			RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);
9184 		}
9185 #endif /* CONFIG_PNO_SUPPORT */
9186 	}
9187 }
9188 
rtw_hal_gate_bb(_adapter * adapter,bool stop)9189 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
9190 {
9191 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9192 	u8 i = 0, val8 = 0, empty = _FAIL;
9193 
9194 	if (stop) {
9195 		/* checking TX queue status */
9196 		for (i = 0 ; i < 5 ; i++) {
9197 			rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
9198 			if (empty) {
9199 				break;
9200 			} else {
9201 				RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
9202 					 __func__, i);
9203 				rtw_mdelay_os(10);
9204 			}
9205 		}
9206 
9207 		if (val8 == 5)
9208 			RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
9209 
9210 		/* Pause TX*/
9211 		pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
9212 		rtw_write8(adapter, REG_TXPAUSE, 0xff);
9213 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9214 		val8 &= ~BIT(0);
9215 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9216 		RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
9217 			 __func__,
9218 			 rtw_read8(adapter, REG_SYS_FUNC_EN),
9219 			 pwrpriv->wowlan_txpause_status);
9220 	} else {
9221 		val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9222 		val8 |= BIT(0);
9223 		rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9224 		RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
9225 			 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
9226 			 pwrpriv->wowlan_txpause_status);
9227 		/* release TX*/
9228 		rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
9229 	}
9230 }
9231 
rtw_hal_wow_pattern_generate(_adapter * adapter,u8 idx,struct rtl_wow_pattern * pwow_pattern)9232 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
9233 {
9234 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9235 	 u8 *pattern;
9236 	 u8 len = 0;
9237 	 u8 *mask;
9238 
9239 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
9240 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9241 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9242 	u8 multicast_addr1[2] = {0x33, 0x33};
9243 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9244 	u8 mask_len = 0;
9245 	u8 mac_addr[ETH_ALEN] = {0};
9246 	u16 count = 0;
9247 	int i;
9248 
9249 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9250 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9251 			 __func__, MAX_WKFM_CAM_NUM);
9252 		return _FAIL;
9253 	}
9254 
9255 	pattern = pwrctl->patterns[idx].content;
9256 	len = pwrctl->patterns[idx].len;
9257 	mask = pwrctl->patterns[idx].mask;
9258 
9259 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9260 	_rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
9261 
9262 	mask_len = DIV_ROUND_UP(len, 8);
9263 
9264 	/* 1. setup A1 table */
9265 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9266 		pwow_pattern->type = PATTERN_BROADCAST;
9267 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
9268 		pwow_pattern->type = PATTERN_MULTICAST;
9269 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
9270 		pwow_pattern->type = PATTERN_MULTICAST;
9271 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9272 		pwow_pattern->type = PATTERN_UNICAST;
9273 	else
9274 		pwow_pattern->type = PATTERN_INVALID;
9275 
9276 	/* translate mask from os to mask for hw */
9277 
9278 	/******************************************************************************
9279 	 * pattern from OS uses 'ethenet frame', like this:
9280 
9281 		|    6   |    6   |   2  |     20    |  Variable  |  4  |
9282 		|--------+--------+------+-----------+------------+-----|
9283 		|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
9284 		|   DA   |   SA   | Type |
9285 
9286 	 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9287 
9288 		|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
9289 		|-------------------+--------+------+-----------+------------+-----|
9290 		| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
9291 				    | Others | Tpye |
9292 
9293 	 * Therefore, we need translate mask_from_OS to mask_to_hw.
9294 	 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9295 	 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9296 	 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9297 	 ******************************************************************************/
9298 	/* Shift 6 bits */
9299 	for (i = 0; i < mask_len - 1; i++) {
9300 		mask_hw[i] = mask[i] >> 6;
9301 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9302 	}
9303 
9304 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
9305 	/* Set bit 0-5 to zero */
9306 	mask_hw[0] &= 0xC0;
9307 
9308 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9309 		pwow_pattern->mask[i] = mask_hw[i * 4];
9310 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
9311 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
9312 		pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
9313 	}
9314 
9315 	/* To get the wake up pattern from the mask.
9316 	 * We do not count first 12 bits which means
9317 	 * DA[6] and SA[6] in the pattern to match HW design. */
9318 	count = 0;
9319 	for (i = 12; i < len; i++) {
9320 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
9321 			content[count] = pattern[i];
9322 			count++;
9323 		}
9324 	}
9325 
9326 	pwow_pattern->crc = rtw_calc_crc(content, count);
9327 
9328 	if (pwow_pattern->crc != 0) {
9329 		if (pwow_pattern->type == PATTERN_INVALID)
9330 			pwow_pattern->type = PATTERN_VALID;
9331 	}
9332 
9333 	return _SUCCESS;
9334 }
9335 
rtw_dump_wow_pattern(void * sel,struct rtl_wow_pattern * pwow_pattern,u8 idx)9336 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
9337 {
9338 	int j;
9339 
9340 	RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
9341 	RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
9342 	RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
9343 	for (j = 0; j < 4; j++)
9344 		RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
9345 }
9346 /*bit definition of pattern match format*/
9347 #define WOW_VALID_BIT	BIT31
9348 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
9349 #define WOW_BC_BIT		BIT26
9350 #define WOW_MC_BIT		BIT25
9351 #define WOW_UC_BIT		BIT24
9352 #else
9353 #define WOW_BC_BIT		BIT18
9354 #define WOW_UC_BIT		BIT17
9355 #define WOW_MC_BIT		BIT16
9356 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
9357 
9358 #ifndef CONFIG_WOW_PATTERN_HW_CAM
9359 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_hal_reset_mac_rx(_adapter * adapter)9360 static void rtw_hal_reset_mac_rx(_adapter *adapter)
9361 {
9362 	u8 val8 = 0;
9363 	/* Set REG_CR bit1, bit3, bit7 to 0*/
9364 	val8 = rtw_read8(adapter, REG_CR);
9365 	val8 &= 0x75;
9366 	rtw_write8(adapter, REG_CR, val8);
9367 	val8 = rtw_read8(adapter, REG_CR);
9368 	/* Set REG_CR bit1, bit3, bit7 to 1*/
9369 	val8 |= 0x8a;
9370 	rtw_write8(adapter, REG_CR, val8);
9371 	RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
9372 }
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)9373 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
9374 {
9375 	u8 val8 = 0;
9376 	u16 rxff_bndy = 0;
9377 	u32 rx_dma_buff_sz = 0;
9378 
9379 	val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
9380 	if (val8 != 0)
9381 		RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
9382 			 __func__, (REG_FIFOPAGE + 3));
9383 
9384 	rtw_hal_reset_mac_rx(adapter);
9385 
9386 	if (wow_mode) {
9387 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9388 				    (u8 *)&rx_dma_buff_sz);
9389 		rxff_bndy = rx_dma_buff_sz - 1;
9390 
9391 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9392 		RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
9393 			 REG_TRXFF_BNDY + 2,
9394 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9395 	} else {
9396 		rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
9397 				    (u8 *)&rx_dma_buff_sz);
9398 		rxff_bndy = rx_dma_buff_sz - 1;
9399 		rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9400 		RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
9401 			 REG_TRXFF_BNDY + 2,
9402 			 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9403 	}
9404 }
9405 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO*/
9406 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9407 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9408 {
9409 	u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9410 	u16 offset, rx_buf_ptr = 0;
9411 	u16 cam_start_offset = 0;
9412 	u16 ctrl_l = 0, ctrl_h = 0;
9413 	u8 count = 0, tmp = 0;
9414 	int i = 0;
9415 	bool res = _TRUE;
9416 
9417 	if (idx > MAX_WKFM_CAM_NUM) {
9418 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9419 			 __func__);
9420 		return _FALSE;
9421 	}
9422 
9423 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9424 			    (u8 *)&rx_dma_buff_sz);
9425 
9426 	if (rx_dma_buff_sz == 0) {
9427 		RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9428 		return _FALSE;
9429 	}
9430 
9431 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9432 
9433 	if (page_sz == 0) {
9434 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9435 		return _FALSE;
9436 	}
9437 
9438 	offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9439 	cam_start_offset = offset * page_sz;
9440 
9441 	ctrl_l = 0x0;
9442 	ctrl_h = 0x0;
9443 
9444 	/* Enable RX packet buffer access */
9445 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9446 
9447 	/* Read the WKFM CAM */
9448 	for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9449 		/*
9450 		 * Set Rx packet buffer offset.
9451 		 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9452 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9453 		 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9454 		 * * Index: The index of the wake up frame mask
9455 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9456 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9457 		 */
9458 		rx_buf_ptr =
9459 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9460 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9461 
9462 		rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9463 		data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9464 		data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9465 
9466 		RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9467 
9468 		count = 0;
9469 
9470 		do {
9471 			tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9472 			rtw_udelay_os(2);
9473 			count++;
9474 		} while (!tmp && count < 100);
9475 
9476 		if (count >= 100) {
9477 			RTW_INFO("%s count:%d\n", __func__, count);
9478 			res = _FALSE;
9479 		}
9480 	}
9481 
9482 	/* Disable RX packet buffer access */
9483 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9484 		   DISABLE_TRXPKT_BUF_ACCESS);
9485 	return res;
9486 }
9487 
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9488 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9489 			     struct  rtl_wow_pattern *context)
9490 {
9491 	u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
9492 	u16 offset, rx_buf_ptr = 0;
9493 	u16 cam_start_offset = 0;
9494 	u16 ctrl_l = 0, ctrl_h = 0;
9495 	u8 count = 0, tmp = 0;
9496 	int res = 0, i = 0;
9497 
9498 	if (idx > MAX_WKFM_CAM_NUM) {
9499 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9500 			 __func__);
9501 		return _FALSE;
9502 	}
9503 
9504 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9505 			    (u8 *)&rx_dma_buff_sz);
9506 
9507 	if (rx_dma_buff_sz == 0) {
9508 		RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9509 		return _FALSE;
9510 	}
9511 
9512 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9513 
9514 	if (page_sz == 0) {
9515 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9516 		return _FALSE;
9517 	}
9518 
9519 	offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9520 
9521 	cam_start_offset = offset * page_sz;
9522 
9523 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
9524 		ctrl_l = 0x0001;
9525 		ctrl_h = 0x0001;
9526 	} else {
9527 		ctrl_l = 0x0f01;
9528 		ctrl_h = 0xf001;
9529 	}
9530 
9531 	/* Enable RX packet buffer access */
9532 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9533 
9534 	/* Write the WKFM CAM */
9535 	for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
9536 		/*
9537 		 * Set Rx packet buffer offset.
9538 		 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9539 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9540 		 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9541 		 * * Index: The index of the wake up frame mask
9542 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9543 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9544 		 */
9545 		rx_buf_ptr =
9546 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
9547 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9548 
9549 		if (i == 0) {
9550 			if (context->type == PATTERN_VALID)
9551 				data = WOW_VALID_BIT;
9552 			else if (context->type == PATTERN_BROADCAST)
9553 				data = WOW_VALID_BIT | WOW_BC_BIT;
9554 			else if (context->type == PATTERN_MULTICAST)
9555 				data = WOW_VALID_BIT | WOW_MC_BIT;
9556 			else if (context->type == PATTERN_UNICAST)
9557 				data = WOW_VALID_BIT | WOW_UC_BIT;
9558 
9559 			if (context->crc != 0)
9560 				data |= context->crc;
9561 
9562 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9563 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9564 		} else if (i == 1) {
9565 			data = 0;
9566 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9567 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9568 		} else if (i == 2 || i == 4) {
9569 			data = context->mask[i - 2];
9570 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9571 			/* write to RX packet buffer*/
9572 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9573 		} else if (i == 3 || i == 5) {
9574 			data = context->mask[i - 2];
9575 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9576 			/* write to RX packet buffer*/
9577 			rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9578 		}
9579 
9580 		count = 0;
9581 		do {
9582 			tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9583 			rtw_udelay_os(2);
9584 			count++;
9585 		} while (tmp && count < 100);
9586 
9587 		if (count >= 100)
9588 			res = _FALSE;
9589 		else
9590 			res = _TRUE;
9591 	}
9592 
9593 	/* Disable RX packet buffer access */
9594 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9595 		   DISABLE_TRXPKT_BUF_ACCESS);
9596 
9597 	return res;
9598 }
9599 #else /* CONFIG_WOW_PATTERN_IN_TXFIFO */
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9600 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9601 {
9602 	u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9603 	u16 tx_page_start, tx_buf_ptr = 0;
9604 	u16 cam_start_offset = 0;
9605 	u16 ctrl_l = 0, ctrl_h = 0;
9606 	u8 count = 0, tmp = 0, last_entry = 0;
9607 	int i = 0;
9608 	bool res = _TRUE;
9609 
9610 	if (idx > MAX_WKFM_CAM_NUM) {
9611 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9612 			 __func__);
9613 		return _FALSE;
9614 	}
9615 
9616 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9617 	if (page_sz == 0) {
9618 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9619 		return _FALSE;
9620 	}
9621 
9622 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9623 	if (last_entry == 0) {
9624 		RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9625 		return _FALSE;
9626 	}
9627 
9628 	/* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9629 	tx_page_start = last_entry - 1;
9630 	cam_start_offset = tx_page_start * page_sz / 8;
9631 	ctrl_l = 0x0;
9632 	ctrl_h = 0x0;
9633 
9634 	/* Enable TX packet buffer access */
9635 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9636 
9637 	/* Read the WKFM CAM */
9638 	for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9639 		/*
9640 		 * Set Tx packet buffer offset.
9641 		 * TxBufer pointer increases 1, we can access 8 bytes in Tx packet buffer.
9642 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9643 		 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9644 		 * * Index: The index of the wake up frame mask
9645 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9646 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9647 		 */
9648 		tx_buf_ptr =
9649 			(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9650 		rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, tx_buf_ptr);
9651 		rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9652 		data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9653 		data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9654 
9655 		RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9656 
9657 		count = 0;
9658 
9659 		do {
9660 			tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9661 			rtw_udelay_os(2);
9662 			count++;
9663 		} while (!tmp && count < 100);
9664 
9665 		if (count >= 100) {
9666 			RTW_INFO("%s count:%d\n", __func__, count);
9667 			res = _FALSE;
9668 		}
9669 	}
9670 
9671 	/* Disable RX packet buffer access */
9672 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9673 		   DISABLE_TRXPKT_BUF_ACCESS);
9674 	return res;
9675 }
9676 
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9677 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9678 			     struct  rtl_wow_pattern *context)
9679 {
9680 	u32 tx_page_start = 0, page_sz = 0;
9681 	u16 tx_buf_ptr = 0;
9682 	u16 cam_start_offset = 0;
9683 	u32 data_l = 0, data_h = 0;
9684 	u8 count = 0, tmp = 0, last_entry = 0;
9685 	int res = 0, i = 0;
9686 
9687 	if (idx > MAX_WKFM_CAM_NUM) {
9688 		RTW_INFO("[Error]: %s, pattern index is out of range\n",
9689 			 __func__);
9690 		return _FALSE;
9691 	}
9692 
9693 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9694 	if (page_sz == 0) {
9695 		RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9696 		return _FALSE;
9697 	}
9698 
9699 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9700 	if (last_entry == 0) {
9701 		RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9702 		return _FALSE;
9703 	}
9704 
9705 	/* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9706 	tx_page_start = last_entry - 1;
9707 	cam_start_offset = tx_page_start * page_sz / 8;
9708 
9709 	/* Write the PATTERN location to BIT_TXBUF_WKCAM_OFFSET */
9710 	rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET, cam_start_offset & 0xFF);
9711 	rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET + 1, (cam_start_offset >> 8) & 0xFF);
9712 	/* Enable TX packet buffer access */
9713 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9714 
9715 	/* Write the WKFM CAM */
9716 	for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
9717 		/*
9718 		 * Set Tx packet buffer offset.
9719 		 * TxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9720 		 * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
9721 		 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9722 		 * * Index: The index of the wake up frame mask
9723 		 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9724 		 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9725 		 */
9726 		tx_buf_ptr = cam_start_offset + ((idx * WKFMCAM_SIZE + i * 8) >> 3);
9727 
9728 		if (i == 0) {
9729 			if (context->type == PATTERN_VALID)
9730 				data_l = WOW_VALID_BIT;
9731 			else if (context->type == PATTERN_BROADCAST)
9732 				data_l = WOW_VALID_BIT | WOW_BC_BIT;
9733 			else if (context->type == PATTERN_MULTICAST)
9734 				data_l = WOW_VALID_BIT | WOW_MC_BIT;
9735 			else if (context->type == PATTERN_UNICAST)
9736 				data_l = WOW_VALID_BIT | WOW_UC_BIT;
9737 
9738 			if (context->crc != 0)
9739 				data_l |= context->crc;
9740 
9741 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9742 		} else {
9743 			data_l = context->mask[i * 2 - 2];
9744 			data_h = context->mask[i * 2 - 1];
9745 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9746 			rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data_h);
9747 		}
9748 
9749 		rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0x1FFF) | BIT23 | (0xff <<24));
9750 		count = 0;
9751 		do {
9752 			tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9753 			rtw_udelay_os(2);
9754 			count++;
9755 		} while (tmp && count < 100);
9756 
9757 		if (count >= 100) {
9758 			res = _FALSE;
9759 			RTW_INFO("%s write failed\n", __func__);
9760 		} else {
9761 			res = _TRUE;
9762 			RTW_INFO("%s write OK\n", __func__);
9763 		}
9764 	}
9765 
9766 	/* Disable TX packet buffer access */
9767 	rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
9768 	return res;
9769 }
9770 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
9771 
rtw_clean_pattern(_adapter * adapter)9772 void rtw_clean_pattern(_adapter *adapter)
9773 {
9774 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9775 	struct rtl_wow_pattern zero_pattern;
9776 	int i = 0;
9777 
9778 	_rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
9779 
9780 	zero_pattern.type = PATTERN_INVALID;
9781 
9782 	for (i = 0; i < MAX_WKFM_CAM_NUM; i++)
9783 		rtw_write_to_frame_mask(adapter, i, &zero_pattern);
9784 
9785 	rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
9786 }
9787 #if 0
9788 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
9789 			       u8 len, u8 *mask, u8 idx)
9790 {
9791 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9792 	struct mlme_ext_priv *pmlmeext = NULL;
9793 	struct mlme_ext_info *pmlmeinfo = NULL;
9794 	struct rtl_wow_pattern wow_pattern;
9795 	u8 mask_hw[MAX_WKFM_SIZE] = {0};
9796 	u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9797 	u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9798 	u8 multicast_addr1[2] = {0x33, 0x33};
9799 	u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9800 	u8 res = _FALSE, index = 0, mask_len = 0;
9801 	u8 mac_addr[ETH_ALEN] = {0};
9802 	u16 count = 0;
9803 	int i, j;
9804 
9805 	if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9806 		RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9807 			 __func__, MAX_WKFM_CAM_NUM);
9808 		return _FALSE;
9809 	}
9810 
9811 	pmlmeext = &adapter->mlmeextpriv;
9812 	pmlmeinfo = &pmlmeext->mlmext_info;
9813 	_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9814 	_rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
9815 
9816 	mask_len = DIV_ROUND_UP(len, 8);
9817 
9818 	/* 1. setup A1 table */
9819 	if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9820 		wow_pattern.type = PATTERN_BROADCAST;
9821 	else if (memcmp(pattern, multicast_addr1, 2) == 0)
9822 		wow_pattern.type = PATTERN_MULTICAST;
9823 	else if (memcmp(pattern, multicast_addr2, 3) == 0)
9824 		wow_pattern.type = PATTERN_MULTICAST;
9825 	else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9826 		wow_pattern.type = PATTERN_UNICAST;
9827 	else
9828 		wow_pattern.type = PATTERN_INVALID;
9829 
9830 	/* translate mask from os to mask for hw */
9831 
9832 /******************************************************************************
9833  * pattern from OS uses 'ethenet frame', like this:
9834 
9835 	|    6   |    6   |   2  |     20    |  Variable  |  4  |
9836 	|--------+--------+------+-----------+------------+-----|
9837 	|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
9838 	|   DA   |   SA   | Type |
9839 
9840  * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9841 
9842 	|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
9843 	|-------------------+--------+------+-----------+------------+-----|
9844 	| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
9845 			    | Others | Tpye |
9846 
9847  * Therefore, we need translate mask_from_OS to mask_to_hw.
9848  * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9849  * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9850  * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9851  ******************************************************************************/
9852 	/* Shift 6 bits */
9853 	for (i = 0; i < mask_len - 1; i++) {
9854 		mask_hw[i] = mask[i] >> 6;
9855 		mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9856 	}
9857 
9858 	mask_hw[i] = (mask[i] >> 6) & 0x3F;
9859 	/* Set bit 0-5 to zero */
9860 	mask_hw[0] &= 0xC0;
9861 
9862 	for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9863 		wow_pattern.mask[i] = mask_hw[i * 4];
9864 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
9865 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
9866 		wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
9867 	}
9868 
9869 	/* To get the wake up pattern from the mask.
9870 	 * We do not count first 12 bits which means
9871 	 * DA[6] and SA[6] in the pattern to match HW design. */
9872 	count = 0;
9873 	for (i = 12; i < len; i++) {
9874 		if ((mask[i / 8] >> (i % 8)) & 0x01) {
9875 			content[count] = pattern[i];
9876 			count++;
9877 		}
9878 	}
9879 
9880 	wow_pattern.crc = rtw_calc_crc(content, count);
9881 
9882 	if (wow_pattern.crc != 0) {
9883 		if (wow_pattern.type == PATTERN_INVALID)
9884 			wow_pattern.type = PATTERN_VALID;
9885 	}
9886 
9887 	index = idx;
9888 
9889 	if (!pwrctl->bInSuspend)
9890 		index += 2;
9891 
9892 	/* write pattern */
9893 	res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
9894 
9895 	if (res == _FALSE)
9896 		RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
9897 			 __func__, idx);
9898 
9899 	return res;
9900 }
9901 #endif
9902 
rtw_fill_pattern(_adapter * adapter)9903 void rtw_fill_pattern(_adapter *adapter)
9904 {
9905 	int i = 0, total = 0, index;
9906 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9907 	struct rtl_wow_pattern wow_pattern;
9908 
9909 	total = pwrpriv->wowlan_pattern_idx;
9910 
9911 	if (total > MAX_WKFM_CAM_NUM)
9912 		total = MAX_WKFM_CAM_NUM;
9913 
9914 	for (i = 0 ; i < total ; i++) {
9915 		if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
9916 
9917 			index = i;
9918 			if (!pwrpriv->bInSuspend)
9919 				index += 2;
9920 			rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
9921 			if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
9922 				RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
9923 		}
9924 
9925 	}
9926 	rtw_write8(adapter, REG_WKFMCAM_NUM, total);
9927 
9928 }
9929 
9930 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
9931 
9932 #define WOW_CAM_ACCESS_TIMEOUT_MS	200
_rtw_wow_pattern_read_cam(_adapter * adapter,u8 addr)9933 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
9934 {
9935 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9936 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
9937 
9938 	u32 rdata = 0;
9939 	u32 cnt = 0;
9940 	systime start = 0;
9941 	u8 timeout = 0;
9942 	u8 rst = _FALSE;
9943 
9944 	_enter_critical_mutex(mutex, NULL);
9945 
9946 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
9947 
9948 	start = rtw_get_current_time();
9949 	while (1) {
9950 		if (rtw_is_surprise_removed(adapter))
9951 			break;
9952 
9953 		cnt++;
9954 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
9955 			rst = _SUCCESS;
9956 			break;
9957 		}
9958 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
9959 			timeout = 1;
9960 			break;
9961 		}
9962 	}
9963 
9964 	rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
9965 
9966 	_exit_critical_mutex(mutex, NULL);
9967 
9968 	/*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
9969 
9970 	if (timeout)
9971 		RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
9972 
9973 	return rdata;
9974 }
rtw_wow_pattern_read_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)9975 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct  rtl_wow_pattern *context)
9976 {
9977 	int i;
9978 	u32 rdata;
9979 
9980 	_rtw_memset(context, 0, sizeof(struct  rtl_wow_pattern));
9981 
9982 	for (i = 4; i >= 0; i--) {
9983 		rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
9984 
9985 		switch (i) {
9986 		case 4:
9987 			if (rdata & WOW_BC_BIT)
9988 				context->type = PATTERN_BROADCAST;
9989 			else if (rdata & WOW_MC_BIT)
9990 				context->type = PATTERN_MULTICAST;
9991 			else if (rdata & WOW_UC_BIT)
9992 				context->type = PATTERN_UNICAST;
9993 			else
9994 				context->type = PATTERN_INVALID;
9995 
9996 			context->crc = rdata & 0xFFFF;
9997 			break;
9998 		default:
9999 			_rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
10000 			break;
10001 		}
10002 	}
10003 }
10004 
_rtw_wow_pattern_write_cam(_adapter * adapter,u8 addr,u32 wdata)10005 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
10006 {
10007 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10008 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10009 	u32 cnt = 0;
10010 	systime start = 0, end = 0;
10011 	u8 timeout = 0;
10012 
10013 	/*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
10014 	_enter_critical_mutex(mutex, NULL);
10015 
10016 	rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
10017 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
10018 
10019 	start = rtw_get_current_time();
10020 	while (1) {
10021 		if (rtw_is_surprise_removed(adapter))
10022 			break;
10023 
10024 		cnt++;
10025 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
10026 			break;
10027 
10028 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10029 			timeout = 1;
10030 			break;
10031 		}
10032 	}
10033 	end = rtw_get_current_time();
10034 
10035 	_exit_critical_mutex(mutex, NULL);
10036 
10037 	if (timeout) {
10038 		RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
10039 			, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
10040 	}
10041 }
10042 
rtw_wow_pattern_write_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10043 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct  rtl_wow_pattern *context)
10044 {
10045 	int j;
10046 	u8 addr;
10047 	u32 wdata = 0;
10048 
10049 	for (j = 4; j >= 0; j--) {
10050 		switch (j) {
10051 		case 4:
10052 			wdata = context->crc;
10053 
10054 			if (PATTERN_BROADCAST == context->type)
10055 				wdata |= WOW_BC_BIT;
10056 			if (PATTERN_MULTICAST == context->type)
10057 				wdata |= WOW_MC_BIT;
10058 			if (PATTERN_UNICAST == context->type)
10059 				wdata |= WOW_UC_BIT;
10060 			if (PATTERN_INVALID != context->type)
10061 				wdata |= WOW_VALID_BIT;
10062 			break;
10063 		default:
10064 			wdata = context->mask[j];
10065 			break;
10066 		}
10067 
10068 		addr = (id << 3) + j;
10069 
10070 		_rtw_wow_pattern_write_cam(adapter, addr, wdata);
10071 	}
10072 }
10073 
_rtw_wow_pattern_clean_cam(_adapter * adapter)10074 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
10075 {
10076 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10077 	_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10078 	u32 cnt = 0;
10079 	systime start = 0;
10080 	u8 timeout = 0;
10081 	u8 rst = _FAIL;
10082 
10083 	_enter_critical_mutex(mutex, NULL);
10084 	rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
10085 
10086 	start = rtw_get_current_time();
10087 	while (1) {
10088 		if (rtw_is_surprise_removed(adapter))
10089 			break;
10090 
10091 		cnt++;
10092 		if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10093 			rst = _SUCCESS;
10094 			break;
10095 		}
10096 		if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10097 			timeout = 1;
10098 			break;
10099 		}
10100 	}
10101 	_exit_critical_mutex(mutex, NULL);
10102 
10103 	if (timeout)
10104 		RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
10105 
10106 	return rst;
10107 }
10108 
rtw_clean_pattern(_adapter * adapter)10109 void rtw_clean_pattern(_adapter *adapter)
10110 {
10111 	if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
10112 		RTW_ERR("rtw_clean_pattern failed\n");
10113 }
rtw_fill_pattern(_adapter * adapter)10114 void rtw_fill_pattern(_adapter *adapter)
10115 {
10116 	int i = 0, total = 0;
10117 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10118 	struct rtl_wow_pattern wow_pattern;
10119 
10120 	total = pwrpriv->wowlan_pattern_idx;
10121 
10122 	if (total > MAX_WKFM_CAM_NUM)
10123 		total = MAX_WKFM_CAM_NUM;
10124 
10125 	for (i = 0 ; i < total ; i++) {
10126 		if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
10127 			rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10128 			rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
10129 		}
10130 	}
10131 }
10132 
10133 #endif
rtw_wow_pattern_cam_dump(_adapter * adapter)10134 void rtw_wow_pattern_cam_dump(_adapter *adapter)
10135 {
10136 
10137 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10138 	int i;
10139 
10140 	for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10141 		RTW_INFO("=======[%d]=======\n", i);
10142 		rtw_read_from_frame_mask(adapter, i);
10143 	}
10144 #else
10145 	struct  rtl_wow_pattern context;
10146 	int i;
10147 
10148 	for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10149 		rtw_wow_pattern_read_cam_ent(adapter, i, &context);
10150 		rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
10151 	}
10152 
10153 #endif
10154 }
10155 
10156 
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)10157 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
10158 {
10159 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10160 
10161 	switch (mode) {
10162 	case 0:
10163 		rtw_clean_pattern(adapter);
10164 		RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
10165 		break;
10166 	case 1:
10167 		rtw_set_default_pattern(adapter);
10168 		rtw_fill_pattern(adapter);
10169 		RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
10170 		break;
10171 	case 2:
10172 		rtw_clean_pattern(adapter);
10173 		rtw_wow_pattern_sw_reset(adapter);
10174 		RTW_INFO("%s: clean patterns\n", __func__);
10175 		break;
10176 	default:
10177 		RTW_INFO("%s: unknown mode\n", __func__);
10178 		break;
10179 	}
10180 }
10181 
rtw_hal_wow_enable(_adapter * adapter)10182 static void rtw_hal_wow_enable(_adapter *adapter)
10183 {
10184 	struct registry_priv  *registry_par = &adapter->registrypriv;
10185 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10186 	struct security_priv *psecuritypriv = &adapter->securitypriv;
10187 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10188 	struct sta_info *psta = NULL;
10189 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
10190 	int res;
10191 	u16 media_status_rpt;
10192 	u8 no_wake = 0, i;
10193 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10194 	_adapter *iface;
10195 #ifdef CONFIG_GPIO_WAKEUP
10196 	u8 val8 = 0;
10197 #endif
10198 
10199 #ifdef CONFIG_LPS_PG
10200 	u8 lps_pg_hdl_id = 0;
10201 #endif
10202 
10203 
10204 
10205 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
10206 	!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
10207 		no_wake = 1;
10208 
10209 	RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));
10210 	rtw_hal_gate_bb(adapter, _TRUE);
10211 
10212 	for (i = 0; i < dvobj->iface_nums; i++) {
10213 		iface = dvobj->padapters[i];
10214 		/* Start Usb TxDMA */
10215 		if(iface) {
10216 			RTW_INFO(ADPT_FMT "enable TX\n", ADPT_ARG(iface));
10217 			RTW_ENABLE_FUNC(iface, DF_TX_BIT);
10218 		}
10219 	}
10220 
10221 #ifdef CONFIG_GTK_OL
10222 	if (psecuritypriv->binstallKCK_KEK == _TRUE)
10223 		rtw_hal_fw_sync_cam_id(adapter);
10224 #endif
10225 	if (IS_HARDWARE_TYPE_8723B(adapter))
10226 		rtw_hal_backup_rate(adapter);
10227 
10228 	rtw_hal_fw_dl(adapter, _TRUE);
10229 	if(no_wake)
10230 		media_status_rpt = RT_MEDIA_DISCONNECT;
10231 	else
10232 		media_status_rpt = RT_MEDIA_CONNECT;
10233 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10234 			  (u8 *)&media_status_rpt);
10235 
10236 	/* RX DMA stop */
10237 	#if defined(CONFIG_RTL8188E)
10238 	if (IS_HARDWARE_TYPE_8188E(adapter))
10239 		rtw_hal_disable_tx_report(adapter);
10240 	#endif
10241 
10242 	res = rtw_hal_pause_rx_dma(adapter);
10243 	if (res == _FAIL)
10244 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
10245 
10246 	#ifndef CONFIG_WOW_PATTERN_HW_CAM
10247 	/* Reconfig RX_FF Boundary */
10248 	#ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10249 	rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
10250 	#endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10251 	#endif
10252 
10253 	/* redownload wow pattern */
10254 	if(!no_wake)
10255 		rtw_hal_dl_pattern(adapter, 1);
10256 
10257 	if (!pwrctl->wowlan_pno_enable) {
10258 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10259 
10260 		if (psta != NULL) {
10261 			#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10262 			adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10263 			adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10264 			rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10265 			#endif
10266 			if(!no_wake)
10267 				rtw_sta_media_status_rpt(adapter, psta, 1);
10268 		}
10269 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10270 		else {
10271 			if(registry_par->suspend_type == FW_IPS_WRC) {
10272 				adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10273 				adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10274 				rtw_hal_set_default_port_id_cmd(adapter, 0);
10275 			}
10276 		}
10277 #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */
10278 	}
10279 
10280 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10281 	/* Enable CPWM2 only. */
10282 	res = rtw_hal_enable_cpwm2(adapter);
10283 	if (res == _FAIL)
10284 		RTW_PRINT("[WARNING] enable cpwm2 fail\n");
10285 #endif
10286 #ifdef CONFIG_GPIO_WAKEUP
10287 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10288 	rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10289 	rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10290 #else
10291 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10292 	if (pwrctl->is_high_active == 0)
10293 		rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10294 	else
10295 		rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10296 			GPIO_OUTPUT_LOW);
10297 #else
10298 	val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
10299 	rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, val8);
10300 	rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10301 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow suspend and %s_ACTIVE.\n",
10302 		 __func__, pwrctl->wowlan_gpio_index,
10303 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10304 		 pwrctl->is_high_active ? "HIGI" : "LOW");
10305 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10306 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10307 #endif /* CONFIG_GPIO_WAKEUP */
10308 	/* Set WOWLAN H2C command. */
10309 	RTW_PRINT("Set WOWLan cmd\n");
10310 	rtw_hal_set_fw_wow_related_cmd(adapter, 1);
10311 
10312 	res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
10313 
10314 	if (res == _FALSE)
10315 		RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
10316 
10317 	pwrctl->wowlan_wake_reason =
10318 		rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10319 
10320 	RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
10321 		  pwrctl->wowlan_wake_reason);
10322 #ifdef CONFIG_GTK_OL_DBG
10323 	dump_sec_cam(RTW_DBGDUMP, adapter);
10324 	dump_sec_cam_cache(RTW_DBGDUMP, adapter);
10325 #endif
10326 
10327 #ifdef CONFIG_LPS_PG
10328 	if (pwrctl->lps_level == LPS_PG) {
10329 		lps_pg_hdl_id = LPS_PG_INFO_CFG;
10330 		rtw_hal_set_hwreg(adapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
10331 	}
10332 #endif
10333 
10334 #ifdef CONFIG_USB_HCI
10335 	/* free adapter's resource */
10336 	rtw_mi_intf_stop(adapter);
10337 
10338 #endif
10339 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
10340 	/* Invoid SE0 reset signal during suspending*/
10341 	rtw_write8(adapter, REG_RSV_CTRL, 0x20);
10342 	if (IS_8188F(pHalData->version_id) == FALSE
10343 		&& IS_8188GTV(pHalData->version_id) == FALSE)
10344 		rtw_write8(adapter, REG_RSV_CTRL, 0x60);
10345 #endif
10346 
10347 	rtw_hal_gate_bb(adapter, _FALSE);
10348 }
10349 
10350 #define DBG_WAKEUP_REASON
10351 #ifdef DBG_WAKEUP_REASON
_dbg_wake_up_reason_string(_adapter * adapter,const char * srt_res)10352 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
10353 {
10354 	RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
10355 }
_dbg_rtw_wake_up_reason(_adapter * adapter,u8 reason)10356 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
10357 {
10358 	if (RX_PAIRWISEKEY == reason)
10359 		_dbg_wake_up_reason_string(adapter, "Rx pairwise key");
10360 	else if (RX_GTK == reason)
10361 		_dbg_wake_up_reason_string(adapter, "Rx GTK");
10362 	else if (RX_FOURWAY_HANDSHAKE == reason)
10363 		_dbg_wake_up_reason_string(adapter, "Rx four way handshake");
10364 	else if (RX_DISASSOC == reason)
10365 		_dbg_wake_up_reason_string(adapter, "Rx disassoc");
10366 	else if (RX_DEAUTH == reason)
10367 		_dbg_wake_up_reason_string(adapter, "Rx deauth");
10368 	else if (RX_ARP_REQUEST == reason)
10369 		_dbg_wake_up_reason_string(adapter, "Rx ARP request");
10370 	else if (FW_DECISION_DISCONNECT == reason)
10371 		_dbg_wake_up_reason_string(adapter, "FW detect disconnect");
10372 	else if (RX_MAGIC_PKT == reason)
10373 		_dbg_wake_up_reason_string(adapter, "Rx magic packet");
10374 	else if (RX_UNICAST_PKT == reason)
10375 		_dbg_wake_up_reason_string(adapter, "Rx unicast packet");
10376 	else if (RX_PATTERN_PKT == reason)
10377 		_dbg_wake_up_reason_string(adapter, "Rx pattern packet");
10378 	else if (RTD3_SSID_MATCH == reason)
10379 		_dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
10380 	else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
10381 		_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
10382 	else if (RX_REALWOW_V2_ACK_LOST == reason)
10383 		_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
10384 	else if (ENABLE_FAIL_DMA_IDLE == reason)
10385 		_dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
10386 	else if (ENABLE_FAIL_DMA_PAUSE == reason)
10387 		_dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
10388 	else if (AP_OFFLOAD_WAKEUP == reason)
10389 		_dbg_wake_up_reason_string(adapter, "AP offload wakeup");
10390 	else if (CLK_32K_UNLOCK == reason)
10391 		_dbg_wake_up_reason_string(adapter, "clk 32k unlock");
10392 	else if (RTIME_FAIL_DMA_IDLE == reason)
10393 		_dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
10394 	else if (CLK_32K_LOCK == reason)
10395 		_dbg_wake_up_reason_string(adapter, "clk 32k lock");
10396 	else
10397 		_dbg_wake_up_reason_string(adapter, "unknown reasoen");
10398 }
10399 #endif
10400 
rtw_hal_wow_disable(_adapter * adapter)10401 static void rtw_hal_wow_disable(_adapter *adapter)
10402 {
10403 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10404 	struct security_priv *psecuritypriv = &adapter->securitypriv;
10405 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10406 	struct sta_info *psta = NULL;
10407 	struct registry_priv  *registry_par = &adapter->registrypriv;
10408 	int res;
10409 	u16 media_status_rpt;
10410 
10411 	RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
10412 
10413 	if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
10414 		RTW_INFO("FW_IPS_DISABLE_BBRF resume\n");
10415 		return;
10416 	}
10417 
10418 	if (!pwrctl->wowlan_pno_enable) {
10419 		psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10420 		if (psta != NULL)
10421 			rtw_sta_media_status_rpt(adapter, psta, 0);
10422 		else
10423 			RTW_INFO("%s: psta is null\n", __func__);
10424 	}
10425 
10426 	if (0) {
10427 		RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
10428 		RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
10429 		RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
10430 		RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
10431 	}
10432 
10433 	pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10434 
10435 	RTW_PRINT("wakeup_reason: 0x%02x\n",
10436 		  pwrctl->wowlan_wake_reason);
10437 	#ifdef DBG_WAKEUP_REASON
10438 	_dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
10439 	#endif
10440 
10441 	rtw_hal_set_fw_wow_related_cmd(adapter, 0);
10442 
10443 	res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
10444 
10445 	#if defined(CONFIG_RTL8188E)
10446 	if (IS_HARDWARE_TYPE_8188E(adapter))
10447 		rtw_hal_enable_tx_report(adapter);
10448 	#endif
10449 
10450 	if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10451 		(pwrctl->wowlan_wake_reason != RX_DEAUTH) &&
10452 		(pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {
10453 		rtw_hal_get_aoac_rpt(adapter);
10454 		rtw_hal_update_sw_security_info(adapter);
10455 	}
10456 
10457 	if (res == _FALSE) {
10458 		RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
10459 		rtw_hal_force_enable_rxdma(adapter);
10460 	}
10461 
10462 	rtw_hal_gate_bb(adapter, _TRUE);
10463 
10464 	res = rtw_hal_pause_rx_dma(adapter);
10465 	if (res == _FAIL)
10466 		RTW_PRINT("[WARNING] pause RX DMA fail\n");
10467 
10468 	/* clean HW pattern match */
10469 	rtw_hal_dl_pattern(adapter, 0);
10470 
10471 	#ifndef CONFIG_WOW_PATTERN_HW_CAM
10472 	/* config RXFF boundary to original */
10473 	#ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10474 	rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
10475 	#endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10476 	#endif
10477 	rtw_hal_release_rx_dma(adapter);
10478 
10479 	rtw_hal_fw_dl(adapter, _FALSE);
10480 
10481 #ifdef CONFIG_GPIO_WAKEUP
10482 
10483 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10484 	rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10485 #else
10486 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10487 	if (pwrctl->is_high_active == 0)
10488 		rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10489 	else
10490 		rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10491 			GPIO_OUTPUT_LOW);
10492 #else
10493 	rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index
10494 		, pwrctl->wowlan_gpio_output_state);
10495 	RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow resume and %s_ACTIVE.\n",
10496 		 __func__, pwrctl->wowlan_gpio_index,
10497 		 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10498 		 pwrctl->is_high_active ? "HIGI" : "LOW");
10499 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10500 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10501 #endif /* CONFIG_GPIO_WAKEUP */
10502 	if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
10503 	    (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
10504 	    (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10505 	    (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
10506 
10507 		media_status_rpt = RT_MEDIA_CONNECT;
10508 		rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10509 				  (u8 *)&media_status_rpt);
10510 
10511 		if (psta != NULL) {
10512 			#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10513 			adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10514 			adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10515 			rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10516 			#endif
10517 			rtw_sta_media_status_rpt(adapter, psta, 1);
10518 		}
10519 	}
10520 	rtw_hal_gate_bb(adapter, _FALSE);
10521 }
10522 #endif /*CONFIG_WOWLAN*/
10523 
10524 #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)10525 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
10526 	      u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
10527 				      RSVDPAGE_LOC *rsvd_page_loc)
10528 {
10529 	u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
10530 	u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
10531 	u8 CurtPktPageNum = 0;
10532 
10533 	/* P2P Beacon */
10534 	rsvd_page_loc->LocP2PBeacon = *page_num;
10535 	rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
10536 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10537 				 P2PBCNLength, _FALSE, _FALSE, _FALSE);
10538 
10539 #if 0
10540 	RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
10541 		__FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
10542 #endif
10543 
10544 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
10545 
10546 	*page_num += CurtPktPageNum;
10547 
10548 	index += (CurtPktPageNum * page_size);
10549 	RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);
10550 
10551 	/* P2P Probe rsp */
10552 	rsvd_page_loc->LocP2PProbeRsp = *page_num;
10553 	rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
10554 				      &P2PProbeRspLength);
10555 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10556 				 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
10557 
10558 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",  */
10559 	/*	__FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
10560 
10561 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
10562 
10563 	*page_num += CurtPktPageNum;
10564 
10565 	index += (CurtPktPageNum * page_size);
10566 	RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);
10567 
10568 	/* P2P nego rsp */
10569 	rsvd_page_loc->LocNegoRsp = *page_num;
10570 	rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
10571 				     &P2PNegoRspLength);
10572 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10573 				 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
10574 
10575 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
10576 	/*	__FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
10577 
10578 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
10579 
10580 	*page_num += CurtPktPageNum;
10581 
10582 	index += (CurtPktPageNum * page_size);
10583 	RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);
10584 
10585 	/* P2P invite rsp */
10586 	rsvd_page_loc->LocInviteRsp = *page_num;
10587 	rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
10588 				       &P2PInviteRspLength);
10589 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10590 				 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
10591 
10592 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
10593 	/* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
10594 
10595 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
10596 
10597 	*page_num += CurtPktPageNum;
10598 
10599 	index += (CurtPktPageNum * page_size);
10600 	RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);
10601 
10602 	/* P2P provision discovery rsp */
10603 	rsvd_page_loc->LocPDRsp = *page_num;
10604 	rtw_hal_construct_P2PProvisionDisRsp(adapter,
10605 					     &pframe[index], &P2PPDRspLength);
10606 
10607 	rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10608 				 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
10609 
10610 	/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",  */
10611 	/*	__FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
10612 
10613 	CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
10614 
10615 	*page_num += CurtPktPageNum;
10616 
10617 	*total_pkt_len = index + P2PPDRspLength;
10618 	RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);
10619 
10620 	index += (CurtPktPageNum * page_size);
10621 
10622 
10623 }
10624 #endif /* CONFIG_P2P_WOWLAN */
10625 
10626 #ifdef CONFIG_LPS_PG
10627 #ifndef DBG_LPSPG_INFO_DUMP
10628 #define DBG_LPSPG_INFO_DUMP 1
10629 #endif
10630 
10631 #include "hal_halmac.h"
10632 
10633 #ifdef CONFIG_RTL8822C
rtw_lps_pg_set_dpk_info_rsvd_page(_adapter * adapter)10634 static int rtw_lps_pg_set_dpk_info_rsvd_page(_adapter *adapter)
10635 {
10636 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10637 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10638 	struct dm_struct *dm = adapter_to_phydm(adapter);
10639 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_dpk_info;
10640 	u8 *info = NULL;
10641 	u32 info_len;
10642 	int ret = _FAIL;
10643 
10644 	/* get length */
10645 	halrf_dpk_info_rsvd_page(dm, NULL, &info_len);
10646 	if (!info_len) {
10647 		RTW_ERR("get %s length fail\n", cache->name);
10648 		goto exit;
10649 	}
10650 
10651 	/* allocate buf */
10652 	info = rtw_zmalloc(info_len);
10653 	if (!info) {
10654 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10655 		goto exit;
10656 	}
10657 
10658 	/* get content */
10659 	halrf_dpk_info_rsvd_page(dm, info, NULL);
10660 
10661 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
10662 
10663 		#if (DBG_LPSPG_INFO_DUMP >= 1)
10664 		RTW_INFO_DUMP(cache->name, info, info_len);
10665 		#endif
10666 
10667 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10668 		ret = !ret ? _SUCCESS : _FAIL;
10669 		if (ret != _SUCCESS) {
10670 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10671 			goto free_mem;
10672 		}
10673 
10674 		#if (DBG_LPSPG_INFO_DUMP >= 2)
10675 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10676 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10677 		#endif
10678 	}
10679 
10680 free_mem:
10681 	rtw_mfree(info, info_len);
10682 
10683 exit:
10684 	return ret;
10685 }
10686 
rtw_lps_pg_set_iqk_info_rsvd_page(_adapter * adapter)10687 static int rtw_lps_pg_set_iqk_info_rsvd_page(_adapter *adapter)
10688 {
10689 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10690 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10691 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10692 	struct dm_struct *dm = adapter_to_phydm(adapter);
10693 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_iqk_info;
10694 	u8 *info = NULL;
10695 	u32 info_len = 0;
10696 	int ret = _FAIL;
10697 
10698 	if (hal_data->RegIQKFWOffload) {
10699 		rsvd_page_cache_free_data(cache);
10700 		ret = _SUCCESS;
10701 		goto exit;
10702 	}
10703 
10704 	/* get length */
10705 	halrf_iqk_info_rsvd_page(dm, NULL, &info_len);
10706 	if (!info_len) {
10707 		RTW_ERR("get %s length fail\n", cache->name);
10708 		goto exit;
10709 	}
10710 
10711 	/* allocate buf */
10712 	info = rtw_zmalloc(info_len);
10713 	if (!info) {
10714 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10715 		goto exit;
10716 	}
10717 
10718 	/* get content */
10719 	halrf_iqk_info_rsvd_page(dm, info, NULL);
10720 
10721 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
10722 
10723 		#if (DBG_LPSPG_INFO_DUMP >= 1)
10724 		RTW_INFO_DUMP(cache->name, info, info_len);
10725 		#endif
10726 
10727 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10728 		ret = !ret ? _SUCCESS : _FAIL;
10729 		if (ret != _SUCCESS) {
10730 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10731 			goto free_mem;
10732 		}
10733 
10734 		#if (DBG_LPSPG_INFO_DUMP >= 2)
10735 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10736 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10737 		#endif
10738 	}
10739 
10740 free_mem:
10741 	rtw_mfree(info, info_len);
10742 
10743 exit:
10744 	return ret;
10745 }
10746 #endif /* CONFIG_RTL8822C */
10747 
rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv * dvobj,_adapter * ld_sta_iface,u8 * buf,u32 * buf_size)10748 static void rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv *dvobj, _adapter *ld_sta_iface, u8 *buf, u32 *buf_size)
10749 {
10750 #define LPS_PG_INFO_RSVD_LEN	16
10751 
10752 	if (buf) {
10753 		_adapter *adapter = dvobj_get_primary_adapter(dvobj);
10754 		struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10755 		struct sta_info *psta;
10756 #ifdef CONFIG_MBSSID_CAM
10757 		u8 cam_id = INVALID_CAM_ID;
10758 #endif
10759 		u8 *psec_cam_id = buf + 8;
10760 		u8 sec_cam_num = 0;
10761 		u8 drv_rsvdpage_num = 0;
10762 
10763 		if (ld_sta_iface) {
10764 			psta = rtw_get_stainfo(&ld_sta_iface->stapriv, get_bssid(&ld_sta_iface->mlmepriv));
10765 			if (!psta) {
10766 				RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
10767 				rtw_warn_on(1);
10768 				goto size_chk;
10769 			}
10770 			/*Byte 0 - used macid*/
10771 			LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id);
10772 			RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
10773 		}
10774 
10775 #ifdef CONFIG_MBSSID_CAM
10776 		/*Byte 1 - used BSSID CAM entry*/
10777 		cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
10778 		if (cam_id != INVALID_CAM_ID)
10779 			LPSPG_RSVD_PAGE_SET_MBSSCAMID(buf, cam_id);
10780 		RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
10781 #endif
10782 
10783 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
10784 		/*Btye 2 - Max used Pattern Match CAM entry*/
10785 		if (pwrpriv->wowlan_mode == _TRUE
10786 			&& ld_sta_iface && check_fwstate(&ld_sta_iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
10787 			LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx);
10788 			RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
10789 		}
10790 #endif
10791 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
10792 		/*Btye 3 - Max MU rate table Group ID*/
10793 		LPSPG_RSVD_PAGE_SET_MU_RAID_GID(buf, 0);
10794 		RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);
10795 #endif
10796 
10797 		/*Btye 8 ~15 - used Security CAM entry */
10798 		sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
10799 
10800 		/*Btye 4 - used Security CAM entry number*/
10801 		if (sec_cam_num < 8)
10802 			LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(buf, sec_cam_num);
10803 		RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
10804 
10805 		/*Btye 5 - Txbuf used page number for fw offload*/
10806 		if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
10807 			drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
10808 		else
10809 			drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
10810 		LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(buf, drv_rsvdpage_num);
10811 		RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
10812 	}
10813 
10814 size_chk:
10815 	if (buf_size)
10816 		*buf_size = LPS_PG_INFO_RSVD_LEN;
10817 }
10818 
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)10819 static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
10820 {
10821 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10822 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10823 	struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_info;
10824 	u8 *info = NULL;
10825 	u32 info_len = 0;
10826 	int ret = _FAIL;
10827 
10828 	/* get length */
10829 	rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, NULL, &info_len);
10830 	if (!info_len) {
10831 		RTW_ERR("get %s length fail\n", cache->name);
10832 		goto exit;
10833 	}
10834 
10835 	/* allocate buf */
10836 	info = rtw_zmalloc(info_len);
10837 	if (!info) {
10838 		RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10839 		goto exit;
10840 	}
10841 
10842 	/* get content */
10843 	rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, info, NULL);
10844 
10845 	if (rsvd_page_cache_update_data(cache, info, info_len)) {
10846 
10847 		#if (DBG_LPSPG_INFO_DUMP >= 1)
10848 		RTW_INFO_DUMP(cache->name, info, info_len);
10849 		#endif
10850 
10851 		ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10852 		ret = !ret ? _SUCCESS : _FAIL;
10853 		if (ret != _SUCCESS) {
10854 			RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10855 			goto free_mem;
10856 		}
10857 
10858 		#if (DBG_LPSPG_INFO_DUMP >= 2)
10859 		RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10860 		rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10861 		#endif
10862 	}
10863 
10864 free_mem:
10865 	rtw_mfree(info, info_len);
10866 
10867 exit:
10868 	return ret;
10869 }
10870 
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)10871 static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index
10872 	, u8 txdesc_size, u32 page_size, u8 *total_page_num
10873 	, bool is_wow_mode, _adapter *ld_sta_iface, bool only_get_page_num)
10874 {
10875 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10876 	struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10877 	struct rsvd_page_cache_t *cache;
10878 	bool rsvd = 1;
10879 	u8 *pos;
10880 	u32 len;
10881 
10882 	if (is_wow_mode) {
10883 		/* lps_level will not change when enter wow_mode */
10884 		if (pwrctl->lps_level != LPS_PG)
10885 			rsvd = 0;
10886 	} else {
10887 		if (!only_get_page_num && !ld_sta_iface)
10888 			rsvd = 0;
10889 	}
10890 
10891 	pos = only_get_page_num ? NULL : frame + *index;
10892 
10893 #ifdef CONFIG_RTL8822C
10894 	if (IS_8822C_SERIES(hal_data->version_id)) {
10895 		/* LPSPG_DPK_INFO */
10896 		cache = &pwrctl->lpspg_dpk_info;
10897 		if (rsvd) {
10898 			if (pwrctl->lps_level != LPS_PG)
10899 				pos = NULL;
10900 			len = 0;
10901 			halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
10902 			#if (DBG_LPSPG_INFO_DUMP >= 1)
10903 			if (pos)
10904 				RTW_INFO_DUMP(cache->name, pos, len);
10905 			#endif
10906 			rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10907 			*total_page_num += cache->page_num;
10908 			*index += page_size * cache->page_num;
10909 			pos = only_get_page_num ? NULL : frame + *index;
10910 			RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10911 		} else
10912 			rsvd_page_cache_free(cache);
10913 
10914 		/* LPSPG_IQK_INFO */
10915 		cache = &pwrctl->lpspg_iqk_info;
10916 		if (rsvd
10917 			/* RegIQKFWOffload will not change when enter wow_mode */
10918 			&& !(is_wow_mode && hal_data->RegIQKFWOffload)
10919 		) {
10920 			if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload)
10921 				pos = NULL;
10922 			len = 0;
10923 			halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
10924 			#if (DBG_LPSPG_INFO_DUMP >= 1)
10925 			if (pos)
10926 				RTW_INFO_DUMP(cache->name, pos, len);
10927 			#endif
10928 			rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10929 			*total_page_num += cache->page_num;
10930 			*index += page_size * cache->page_num;
10931 			pos = only_get_page_num ? NULL : frame + *index;
10932 			RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10933 		} else
10934 			rsvd_page_cache_free(cache);
10935 	}
10936 #endif
10937 
10938 	/* LPSPG_INFO */
10939 	cache = &pwrctl->lpspg_info;
10940 	if (rsvd) {
10941 		if (pwrctl->lps_level != LPS_PG)
10942 			pos = NULL;
10943 		rtw_hal_build_lps_pg_info_rsvd_page(adapter_to_dvobj(adapter), ld_sta_iface, pos, &len);
10944 		#if (DBG_LPSPG_INFO_DUMP >= 1)
10945 		if (pos)
10946 			RTW_INFO_DUMP(cache->name, pos, len);
10947 		#endif
10948 		rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10949 		*total_page_num += cache->page_num;
10950 		*index += page_size * cache->page_num;
10951 		pos = only_get_page_num ? NULL : frame + *index;
10952 		RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10953 	} else
10954 		rsvd_page_cache_free(cache);
10955 }
10956 
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)10957 u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
10958 {
10959 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10960 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10961 
10962 	u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
10963 	u8 ret = _FAIL;
10964 
10965 	if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
10966 		SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1);	/*SecurityCAM_En*/
10967 
10968 #ifdef CONFIG_MBSSID_CAM
10969 	SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1);		/*BSSIDCAM_En*/
10970 #endif
10971 
10972 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
10973 	if (pwrpriv->wowlan_mode == _TRUE &&
10974 	    check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
10975 
10976 		SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1);	/*PatternMatchCAM_En*/
10977 	}
10978 #endif
10979 
10980 #ifdef CONFIG_MACID_SEARCH
10981 	SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1);	/*MACIDSearch_En*/
10982 #endif
10983 
10984 #ifdef CONFIG_TX_SC
10985 	SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1);	/*TXSC_En*/
10986 #endif
10987 
10988 #ifdef CONFIG_BEAMFORMING  /*&& MU BF*/
10989 	SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1);	/*MURateTable_En*/
10990 #endif
10991 
10992 	SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc);
10993 
10994 #ifdef CONFIG_RTL8822C
10995 	if (pwrpriv->bFwCurrentInPSMode == _FALSE) {
10996 		SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc);
10997 		if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
10998 			SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc);
10999 	} else {
11000 		SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, 0);
11001 		if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11002 			SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, 0);
11003 	}
11004 #endif
11005 
11006 #if (DBG_LPSPG_INFO_DUMP >= 1)
11007 	RTW_INFO_DUMP("H2C_LPS_PG_INFO: ", lpspg_info, H2C_LPS_PG_INFO_LEN);
11008 #endif
11009 
11010 	ret = rtw_hal_fill_h2c_cmd(adapter,
11011 				   H2C_LPS_PG_INFO,
11012 				   H2C_LPS_PG_INFO_LEN,
11013 				   lpspg_info);
11014 	return ret;
11015 }
rtw_hal_set_lps_pg_info(_adapter * adapter)11016 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
11017 {
11018 	u8 ret = _FAIL;
11019 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11020 
11021 	if (pwrpriv->lpspg_info.loc == 0) {
11022 		RTW_ERR("%s lpspg_info.loc = 0\n", __func__);
11023 		rtw_warn_on(1);
11024 		return ret;
11025 	}
11026 	#ifdef CONFIG_RTL8822C
11027 	rtw_lps_pg_set_dpk_info_rsvd_page(adapter);
11028 	rtw_lps_pg_set_iqk_info_rsvd_page(adapter);
11029 	#endif
11030 	rtw_hal_set_lps_pg_info_rsvd_page(adapter);
11031 
11032 	ret = rtw_hal_set_lps_pg_info_cmd(adapter);
11033 
11034 	return ret;
11035 }
11036 
rtw_hal_lps_pg_rssi_lv_decide(_adapter * adapter,struct sta_info * sta)11037 void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
11038 {
11039 #if 0
11040 	if (sta->cmn.ra_info.rssi_level >= 4)
11041 		sta->lps_pg_rssi_lv = 3;	/*RSSI High - 1SS_VHT_MCS7*/
11042 	else if (sta->cmn.ra_info.rssi_level >=  2)
11043 		sta->lps_pg_rssi_lv = 2;	/*RSSI Middle - 1SS_VHT_MCS3*/
11044 	else
11045 		sta->lps_pg_rssi_lv = 1;	/*RSSI Lower - Lowest_rate*/
11046 #else
11047 	sta->lps_pg_rssi_lv = 0;
11048 #endif
11049 	RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
11050 		__func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
11051 }
11052 
rtw_hal_lps_pg_handler(_adapter * adapter,enum lps_pg_hdl_id hdl_id)11053 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
11054 {
11055 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
11056 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11057 	struct sta_priv *pstapriv = &adapter->stapriv;
11058 	struct sta_info *sta;
11059 
11060 	sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
11061 
11062 	switch (hdl_id) {
11063 	case LPS_PG_INFO_CFG:
11064 		rtw_hal_set_lps_pg_info(adapter);
11065 		break;
11066 	case LPS_PG_REDLEMEM:
11067 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11068 			break;
11069 
11070 		/*set xmit_block*/
11071 		rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11072 		if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
11073 			rtw_warn_on(1);
11074 		/*clearn xmit_block*/
11075 		rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11076 		break;
11077 	case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/
11078 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11079 			break;
11080 
11081 		if (sta)
11082 			rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);
11083 		break;
11084 	case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/
11085 		if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11086 			break;
11087 
11088 		if (sta) {
11089 			rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
11090 			rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);
11091 			sta->lps_pg_rssi_lv = 0;
11092 		}
11093 		break;
11094 
11095 	default:
11096 		break;
11097 	}
11098 }
11099 
11100 #endif /*CONFIG_LPS_PG*/
11101 
_rtw_mi_assoc_if_num(_adapter * adapter)11102 static u8 _rtw_mi_assoc_if_num(_adapter *adapter)
11103 {
11104 	u8 mi_iface_num = 0;
11105 
11106 	if (0) {
11107 		RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));
11108 		RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));
11109 		RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11110 		RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));
11111 		RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));
11112 		/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/
11113 		/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/
11114 	}
11115 
11116 	mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +
11117 		DEV_AP_NUM(adapter_to_dvobj(adapter)) +
11118 		DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11119 	return mi_iface_num;
11120 }
11121 #ifdef CONFIG_CONCURRENT_MODE
_rtw_search_sta_iface(_adapter * adapter)11122 static _adapter *_rtw_search_sta_iface(_adapter *adapter)
11123 {
11124 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11125 	_adapter *iface = NULL;
11126 	_adapter *sta_iface = NULL;
11127 	int i;
11128 
11129 	for (i = 0; i < dvobj->iface_nums; i++) {
11130 		iface = dvobj->padapters[i];
11131 		if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
11132 			if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11133 				sta_iface = iface;
11134 				break;
11135 			}
11136 		}
11137 	}
11138 	return sta_iface;
11139 }
11140 #if defined(CONFIG_AP_MODE) && defined(CONFIG_BT_COEXIST)
_rtw_search_ap_iface(_adapter * adapter)11141 static _adapter *_rtw_search_ap_iface(_adapter *adapter)
11142 {
11143 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11144 	_adapter *iface = NULL;
11145 	_adapter *ap_iface = NULL;
11146 	int i;
11147 
11148 	for (i = 0; i < dvobj->iface_nums; i++) {
11149 		iface = dvobj->padapters[i];
11150 		if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
11151 			ap_iface = iface;
11152 			break;
11153 		}
11154 	}
11155 	return ap_iface;
11156 }
11157 #endif/*CONFIG_AP_MODE*/
11158 #endif/*CONFIG_CONCURRENT_MODE*/
11159 
11160 #ifdef CONFIG_CUSTOMER01_SMART_ANTENNA
rtw_hal_set_pathb_phase(_adapter * adapter,u8 phase_idx)11161 void rtw_hal_set_pathb_phase(_adapter *adapter, u8 phase_idx)
11162 {
11163 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(adapter);
11164 	struct PHY_DM_STRUCT		*pDM_Odm = &pHalData->odmpriv;
11165 
11166 	return phydm_pathb_q_matrix_rotate(pDM_Odm, phase_idx);
11167 }
11168 #endif
11169 
11170 /*
11171  * Description: Fill the reserved packets that FW will use to RSVD page.
11172  *			Now we just send 4 types packet to rsvd page.
11173  *			(1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
11174  * Input:
11175  * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
11176  *		    so we need to set the packet length to total lengh.
11177  *	      TRUE: At the second time, we should send the first packet (default:beacon)
11178  *		    to Hw again and set the lengh in descriptor to the real beacon lengh.
11179  * page_num - The amount of reserved page which driver need.
11180  *	      If this is not NULL, this function doesn't real download reserved
11181  *	      page, but just count the number of reserved page.
11182  *
11183  * 2009.10.15 by tynli.
11184  * 2017.06.20 modified by Lucas.
11185  *
11186  * Page Size = 128: 8188e, 8723a/b, 8192c/d,
11187  * Page Size = 256: 8192e, 8821a
11188  * Page Size = 512: 8812a
11189  */
11190 
11191 /*#define DBG_DUMP_SET_RSVD_PAGE*/
_rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished,u8 * page_num)11192 static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
11193 {
11194 	PHAL_DATA_TYPE pHalData;
11195 	struct xmit_frame	*pcmdframe = NULL;
11196 	struct pkt_attrib	*pattrib;
11197 	struct xmit_priv	*pxmitpriv;
11198 	struct pwrctrl_priv *pwrctl;
11199 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11200 	u32	BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
11201 	u32	NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
11202 	u32	ProbeReqLength = 0, NullFunctionDataLength = 0;
11203 	u8	TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
11204 	u8	TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
11205 	u8	*ReservedPagePacket;
11206 	u16	BufIndex = 0;
11207 	u32	TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
11208 	RSVDPAGE_LOC	RsvdPageLoc;
11209 	struct registry_priv  *registry_par = &adapter->registrypriv;
11210 
11211 #ifdef DBG_FW_DEBUG_MSG_PKT
11212 	u32	fw_dbg_msg_pkt_len = 0;
11213 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11214 
11215 #ifdef DBG_CONFIG_ERROR_DETECT
11216 	struct sreset_priv *psrtpriv;
11217 #endif /* DBG_CONFIG_ERROR_DETECT */
11218 
11219 #ifdef CONFIG_MCC_MODE
11220 	u8 dl_mcc_page = _FAIL;
11221 #endif /* CONFIG_MCC_MODE */
11222 	u8 nr_assoc_if;
11223 
11224 	_adapter *sta_iface = NULL;
11225 	_adapter *ap_iface = NULL;
11226 
11227 	bool is_wow_mode = _FALSE;
11228 
11229 	pHalData = GET_HAL_DATA(adapter);
11230 #ifdef DBG_CONFIG_ERROR_DETECT
11231 	psrtpriv = &pHalData->srestpriv;
11232 #endif
11233 	pxmitpriv = &adapter->xmitpriv;
11234 	pwrctl = adapter_to_pwrctl(adapter);
11235 
11236 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
11237 
11238 	if (PageSize == 0) {
11239 		RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);
11240 		return;
11241 	}
11242 	nr_assoc_if = _rtw_mi_assoc_if_num(adapter);
11243 
11244 	if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||
11245 		pwrctl->wowlan_ap_mode == _TRUE ||
11246 		pwrctl->wowlan_p2p_mode == _TRUE)
11247 		is_wow_mode = _TRUE;
11248 
11249 	/*page_num for init time to get rsvd page number*/
11250 	/* Prepare ReservedPagePacket */
11251 	if (page_num) {
11252 		ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
11253 		if (!ReservedPagePacket) {
11254 			RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11255 			*page_num = 0xFF;
11256 			return;
11257 		}
11258 		RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm  ==>\n",
11259 			FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11260 
11261 	} else {
11262 		if (is_wow_mode)
11263 			RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
11264 		else
11265 			RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
11266 
11267 		RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",
11268 			FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);
11269 
11270 		MaxRsvdPageBufSize = RsvdPageNum * PageSize;
11271 		if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
11272 			RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
11273 				 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
11274 			rtw_warn_on(1);
11275 			return;
11276 		}
11277 
11278 		pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
11279 		if (pcmdframe == NULL) {
11280 			RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11281 			return;
11282 		}
11283 
11284 		ReservedPagePacket = pcmdframe->buf_addr;
11285 	}
11286 
11287 	_rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
11288 
11289 	BufIndex = TxDescOffset;
11290 
11291 	/*======== beacon content =======*/
11292 	rtw_hal_construct_beacon(adapter,
11293 				 &ReservedPagePacket[BufIndex], &BeaconLength);
11294 
11295 	/*
11296 	* When we count the first page size, we need to reserve description size for the RSVD
11297 	* packet, it will be filled in front of the packet in TXPKTBUF.
11298 	*/
11299 	BeaconLength = MAX_BEACON_LEN - TxDescLen;
11300 	CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
11301 
11302 #if defined(CONFIG_FW_HANDLE_TXBCN) || defined(CONFIG_PORT_BASED_TXBCN)
11303 	CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;
11304 #endif
11305 	TotalPageNum += CurtPktPageNum;
11306 
11307 	BufIndex += (CurtPktPageNum * PageSize);
11308 
11309 	RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11310 
11311 	/*======== probe response content ========*/
11312 	if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/
11313 		#ifdef CONFIG_CONCURRENT_MODE
11314 		if (nr_assoc_if >= 2)
11315 			RTW_ERR("Not support > 2 net-interface in WOW\n");
11316 		#endif
11317 		/* (4) probe response*/
11318 		RsvdPageLoc.LocProbeRsp = TotalPageNum;
11319 		rtw_hal_construct_ProbeRsp(
11320 			adapter, &ReservedPagePacket[BufIndex],
11321 			&ProbeRspLength,
11322 			_FALSE);
11323 		rtw_hal_fill_fake_txdesc(adapter,
11324 				 &ReservedPagePacket[BufIndex - TxDescLen],
11325 				 ProbeRspLength, _FALSE, _FALSE, _FALSE);
11326 
11327 		CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
11328 		TotalPageNum += CurtPktPageNum;
11329 		TotalPacketLen = BufIndex + ProbeRspLength;
11330 		BufIndex += (CurtPktPageNum * PageSize);
11331 		RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11332 		goto download_page;
11333 	}
11334 
11335 	/*======== ps-poll content * 1 page ========*/
11336 	sta_iface = adapter;
11337 	#ifdef CONFIG_CONCURRENT_MODE
11338 	if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {
11339 		sta_iface = _rtw_search_sta_iface(adapter);
11340 		RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));
11341 	}
11342 	#endif
11343 
11344 	if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11345 		RsvdPageLoc.LocPsPoll = TotalPageNum;
11346 		RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
11347 		rtw_hal_construct_PSPoll(sta_iface,
11348 					 &ReservedPagePacket[BufIndex], &PSPollLength);
11349 		rtw_hal_fill_fake_txdesc(sta_iface,
11350 					 &ReservedPagePacket[BufIndex - TxDescLen],
11351 					 PSPollLength, _TRUE, _FALSE, _FALSE);
11352 
11353 		CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
11354 
11355 		TotalPageNum += CurtPktPageNum;
11356 
11357 		BufIndex += (CurtPktPageNum * PageSize);
11358 		RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11359 	}
11360 
11361 #ifdef CONFIG_MCC_MODE
11362 	/*======== MCC * n page ======== */
11363 	if (MCC_EN(adapter)) {/*Normal mode*/
11364 		dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
11365 				&BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);
11366 	} else {
11367 		dl_mcc_page = _FAIL;
11368 	}
11369 
11370 	if (dl_mcc_page == _FAIL)
11371 #endif /* CONFIG_MCC_MODE */
11372 	{	/*======== null data * 1 page ======== */
11373 		if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11374 			RsvdPageLoc.LocNullData = TotalPageNum;
11375 			RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
11376 			rtw_hal_construct_NullFunctionData(
11377 				sta_iface,
11378 				&ReservedPagePacket[BufIndex],
11379 				&NullDataLength,
11380 				_FALSE, 0, 0, _FALSE);
11381 			rtw_hal_fill_fake_txdesc(sta_iface,
11382 				 &ReservedPagePacket[BufIndex - TxDescLen],
11383 				 NullDataLength, _FALSE, _FALSE, _FALSE);
11384 
11385 			CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
11386 
11387 			TotalPageNum += CurtPktPageNum;
11388 
11389 			BufIndex += (CurtPktPageNum * PageSize);
11390 			RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11391 		}
11392 	}
11393 
11394 	/*======== Qos null data * 1 page ======== */
11395 	if (pwrctl->wowlan_mode == _FALSE ||
11396 		pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
11397 		if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11398 			RsvdPageLoc.LocQosNull = TotalPageNum;
11399 			RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
11400 			rtw_hal_construct_NullFunctionData(sta_iface,
11401 						&ReservedPagePacket[BufIndex],
11402 						&QosNullLength,
11403 						_TRUE, 0, 0, _FALSE);
11404 			rtw_hal_fill_fake_txdesc(sta_iface,
11405 					 &ReservedPagePacket[BufIndex - TxDescLen],
11406 					 QosNullLength, _FALSE, _FALSE, _FALSE);
11407 
11408 			CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
11409 						     PageSize);
11410 
11411 			TotalPageNum += CurtPktPageNum;
11412 
11413 			BufIndex += (CurtPktPageNum * PageSize);
11414 			RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11415 		}
11416 	}
11417 
11418 #ifdef CONFIG_BT_COEXIST
11419 	/*======== BT Qos null data * 1 page ======== */
11420 	if (pwrctl->wowlan_mode == _FALSE ||
11421 		pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
11422 
11423 		ap_iface = adapter;
11424 		#if defined (CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
11425 		if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) {	/*DEV_AP_STARTING_NUM*/
11426 			ap_iface = _rtw_search_ap_iface(adapter);
11427 			RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));
11428 		}
11429 		#endif
11430 
11431 		if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {
11432 			RsvdPageLoc.LocBTQosNull = TotalPageNum;
11433 
11434 			RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
11435 
11436 			rtw_hal_construct_NullFunctionData(ap_iface,
11437 						&ReservedPagePacket[BufIndex],
11438 						&BTQosNullLength,
11439 						_TRUE, 0, 0, _FALSE);
11440 
11441 			rtw_hal_fill_fake_txdesc(ap_iface,
11442 					&ReservedPagePacket[BufIndex - TxDescLen],
11443 					BTQosNullLength, _FALSE, _TRUE, _FALSE);
11444 
11445 			CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
11446 							 PageSize);
11447 
11448 			TotalPageNum += CurtPktPageNum;
11449 			BufIndex += (CurtPktPageNum * PageSize);
11450 
11451 			RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11452 		}
11453 	}
11454 #endif /* CONFIG_BT_COEXIT */
11455 
11456 	TotalPacketLen = BufIndex;
11457 
11458 #ifdef DBG_FW_DEBUG_MSG_PKT
11459 		/*======== FW DEBUG MSG * n page ======== */
11460 		RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;
11461 		RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);
11462 		rtw_hal_construct_fw_dbg_msg_pkt(
11463 			adapter,
11464 			&ReservedPagePacket[BufIndex],
11465 			&fw_dbg_msg_pkt_len);
11466 
11467 		rtw_hal_fill_fake_txdesc(adapter,
11468 				 &ReservedPagePacket[BufIndex - TxDescLen],
11469 				 fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);
11470 
11471 		CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);
11472 
11473 		if (CurtPktPageNum < 2)
11474 			CurtPktPageNum = 2; /*Need at least 2 rsvd page*/
11475 		TotalPageNum += CurtPktPageNum;
11476 
11477 		TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;
11478 		BufIndex += (CurtPktPageNum * PageSize);
11479 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11480 
11481 #ifdef CONFIG_LPS_PG
11482 	rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex
11483 		, TxDescLen, PageSize, &TotalPageNum, is_wow_mode
11484 		, (sta_iface && MLME_IS_STA(sta_iface) && MLME_IS_ASOC(sta_iface)) ? sta_iface : NULL
11485 		, page_num ? 1 : 0
11486 	);
11487 	TotalPacketLen = BufIndex;
11488 #endif
11489 
11490 #ifdef CONFIG_WOWLAN
11491 	/*======== WOW * n page ======== */
11492 	if (pwrctl->wowlan_mode == _TRUE &&
11493 		pwrctl->wowlan_in_resume == _FALSE &&
11494 		check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {/*WOW mode*/
11495 		rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
11496 					     BufIndex, TxDescLen, PageSize,
11497 			     &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
11498 	}
11499 #endif /* CONFIG_WOWLAN */
11500 
11501 #ifdef CONFIG_P2P_WOWLAN
11502 	/*======== P2P WOW * n page ======== */
11503 	if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/
11504 		rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
11505 						 BufIndex, TxDescLen, PageSize,
11506 				 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
11507 	}
11508 #endif /* CONFIG_P2P_WOWLAN */
11509 
11510 	/*Note:  BufIndex already add a TxDescOffset offset in first Beacon page
11511 	* The "TotalPacketLen" is calculate by BufIndex.
11512 	* We need to decrease TxDescOffset before doing length check. by yiwei
11513 	*/
11514 	TotalPacketLen = TotalPacketLen - TxDescOffset;
11515 
11516 download_page:
11517 	if (page_num) {
11518 		*page_num = TotalPageNum;
11519 		rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
11520 		ReservedPagePacket = NULL;
11521 		RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",
11522 			FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11523 		return;
11524 	}
11525 
11526 	/* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
11527 	RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
11528 		 __func__, TotalPageNum, TotalPacketLen);
11529 
11530 	if (TotalPacketLen > MaxRsvdPageBufSize) {
11531 		RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
11532 			 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
11533 		rtw_warn_on(1);
11534 		goto error;
11535 	} else {
11536 		/* update attribute */
11537 		pattrib = &pcmdframe->attrib;
11538 		update_mgntframe_attrib(adapter, pattrib);
11539 		pattrib->qsel = QSLT_BEACON;
11540 		pattrib->pktlen = TotalPacketLen;
11541 		pattrib->last_txcmdsz = TotalPacketLen;
11542 #ifdef CONFIG_PCI_HCI
11543 		dump_mgntframe(adapter, pcmdframe);
11544 #else
11545 		dump_mgntframe_and_wait(adapter, pcmdframe, 100);
11546 #endif
11547 	}
11548 
11549 	RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
11550 		 __func__, TotalPacketLen, TotalPageNum);
11551 #ifdef DBG_DUMP_SET_RSVD_PAGE
11552 	RTW_INFO(" ==================================================\n");
11553 	RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
11554 	RTW_INFO(" ==================================================\n");
11555 #endif
11556 
11557 
11558 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
11559 		|| MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){
11560 		rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
11561 #ifdef DBG_FW_DEBUG_MSG_PKT
11562 		rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);
11563 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11564 #ifdef CONFIG_WOWLAN
11565 		if (pwrctl->wowlan_mode == _TRUE &&
11566 			pwrctl->wowlan_in_resume == _FALSE)
11567 			rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
11568 #endif /* CONFIG_WOWLAN */
11569 #ifdef CONFIG_AP_WOWLAN
11570 		if (pwrctl->wowlan_ap_mode == _TRUE)
11571 			rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
11572 #endif /* CONFIG_AP_WOWLAN */
11573 	} else if (pwrctl->wowlan_pno_enable) {
11574 #ifdef CONFIG_PNO_SUPPORT
11575 		rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
11576 		if (pwrctl->wowlan_in_resume)
11577 			rtw_hal_set_scan_offload_info_cmd(adapter,
11578 							  &RsvdPageLoc, 0);
11579 		else
11580 			rtw_hal_set_scan_offload_info_cmd(adapter,
11581 							  &RsvdPageLoc, 1);
11582 #endif /* CONFIG_PNO_SUPPORT */
11583 	}
11584 
11585 #ifdef CONFIG_P2P_WOWLAN
11586 	if (_TRUE == pwrctl->wowlan_p2p_mode)
11587 		rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
11588 #endif /* CONFIG_P2P_WOWLAN */
11589 
11590 	return;
11591 error:
11592 	rtw_free_xmitframe(pxmitpriv, pcmdframe);
11593 }
11594 
rtw_hal_set_fw_rsvd_page(struct _ADAPTER * adapter,bool finished)11595 void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
11596 {
11597 #ifdef CONFIG_AP_MODE
11598 	if (finished)
11599 		rtw_mi_tx_beacon_hdl(adapter);
11600 	else
11601 #endif
11602 		_rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
11603 }
11604 
11605 /**
11606  * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
11607  * @adapter:	struct _ADAPTER*
11608  *
11609  * Caculate needed reserved page number.
11610  * In different state would get different number, for example normal mode and
11611  * WOW mode would need different reserved page size.
11612  *
11613  * Return the number of reserved page which driver need.
11614  */
rtw_hal_get_rsvd_page_num(struct _ADAPTER * adapter)11615 u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
11616 {
11617 	u8 num = 0;
11618 
11619 
11620 	_rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
11621 
11622 	return num;
11623 }
11624 
11625 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
hw_var_set_bcn_func(_adapter * adapter,u8 enable)11626 static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)
11627 {
11628 	u32 bcn_ctrl_reg;
11629 
11630 #ifdef CONFIG_CONCURRENT_MODE
11631 	if (adapter->hw_port == HW_PORT1)
11632 		bcn_ctrl_reg = REG_BCN_CTRL_1;
11633 	else
11634 #endif
11635 		bcn_ctrl_reg = REG_BCN_CTRL;
11636 
11637 	if (enable)
11638 		rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
11639 	else {
11640 		u8 val8;
11641 
11642 		val8 = rtw_read8(adapter, bcn_ctrl_reg);
11643 		val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
11644 
11645 #ifdef CONFIG_BT_COEXIST
11646 		if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {
11647 			/* Always enable port0 beacon function for PSTDMA */
11648 			if (REG_BCN_CTRL == bcn_ctrl_reg)
11649 				val8 |= EN_BCN_FUNCTION;
11650 		}
11651 #endif
11652 
11653 		rtw_write8(adapter, bcn_ctrl_reg, val8);
11654 	}
11655 
11656 #ifdef CONFIG_RTL8192F
11657 	if (IS_HARDWARE_TYPE_8192F(adapter)) {
11658 		u16 val16, val16_ori;
11659 
11660 		val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
11661 
11662 		#ifdef CONFIG_CONCURRENT_MODE
11663 		if (adapter->hw_port == HW_PORT1) {
11664 			if (enable)
11665 				val16 |= EN_PORT_1_FUNCTION;
11666 			else
11667 				val16 &= ~EN_PORT_1_FUNCTION;
11668 		} else
11669 		#endif
11670 		{
11671 			if (enable)
11672 				val16 |= EN_PORT_0_FUNCTION;
11673 			else
11674 				val16 &= ~EN_PORT_0_FUNCTION;
11675 
11676 			#ifdef CONFIG_BT_COEXIST
11677 			if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
11678 				val16 |= EN_PORT_0_FUNCTION;
11679 			#endif
11680 		}
11681 
11682 		if (val16 != val16_ori)
11683 			rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1,  val16);
11684 	}
11685 #endif
11686 }
11687 #endif
11688 
11689 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
hw_var_set_mlme_disconnect(_adapter * adapter)11690 static void hw_var_set_mlme_disconnect(_adapter *adapter)
11691 {
11692 	u8 val8;
11693 
11694 	/* reject all data frames */
11695 #ifdef CONFIG_CONCURRENT_MODE
11696 	if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
11697 #endif
11698 		rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);
11699 
11700 #ifdef CONFIG_CONCURRENT_MODE
11701 	if (adapter->hw_port == HW_PORT1) {
11702 		/* reset TSF1 */
11703 		rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));
11704 
11705 		/* disable update TSF1 */
11706 		rtw_iface_disable_tsf_update(adapter);
11707 
11708 		if (!IS_HARDWARE_TYPE_8723D(adapter)
11709 			&& !IS_HARDWARE_TYPE_8192F(adapter)
11710 			&& !IS_HARDWARE_TYPE_8710B(adapter)
11711 		) {
11712 			/* disable Port1's beacon function */
11713 			val8 = rtw_read8(adapter, REG_BCN_CTRL_1);
11714 			val8 &= ~EN_BCN_FUNCTION;
11715 			rtw_write8(adapter, REG_BCN_CTRL_1, val8);
11716 		}
11717 	} else
11718 #endif
11719 	{
11720 		/* reset TSF */
11721 		rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
11722 
11723 		/* disable update TSF */
11724 		rtw_iface_disable_tsf_update(adapter);
11725 	}
11726 }
11727 #endif
11728 
hw_var_set_mlme_sitesurvey(_adapter * adapter,u8 enable)11729 static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)
11730 {
11731 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11732 	u16 value_rxfltmap2;
11733 
11734 #ifdef DBG_IFACE_STATUS
11735 	DBG_IFACE_STATUS_DUMP(adapter);
11736 #endif
11737 
11738 #ifdef CONFIG_FIND_BEST_CHANNEL
11739 	/* Receive all data frames */
11740 	value_rxfltmap2 = 0xFFFF;
11741 #else
11742 	/* not to receive data frame */
11743 	value_rxfltmap2 = 0;
11744 #endif
11745 
11746 	if (enable) { /* under sitesurvey */
11747 		/*
11748 		* 1. configure REG_RXFLTMAP2
11749 		* 2. disable TSF update &  buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
11750 		* 3. config RCR to receive different BSSID BCN or probe rsp
11751 		*/
11752 		rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
11753 
11754 		rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
11755 
11756 		/* Save orignal RRSR setting, only 8812 set RRSR after set ch/bw/band */
11757 		#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11758 		hal_data->RegRRSR = rtw_read32(adapter, REG_RRSR);
11759 		hal_data->RegRRSR &= 0x000FFFFF;
11760 		#endif
11761 
11762 		#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
11763 		if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
11764 			/* set 718[1:0]=2'b00 to avoid BF scan hang */
11765 			hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
11766 			rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
11767 		}
11768 		#endif
11769 
11770 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11771 			StopTxBeacon(adapter);
11772 	} else { /* sitesurvey done */
11773 		/*
11774 		* 1. enable rx data frame
11775 		* 2. config RCR not to receive different BSSID BCN or probe rsp
11776 		* 3. doesn't enable TSF update &  buddy TSF right now to avoid HW conflict
11777 		*	 so, we enable TSF update when rx first BCN after sitesurvey done
11778 		*/
11779 		if (rtw_mi_check_fwstate(adapter, WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) {
11780 			/* enable to rx data frame */
11781 			rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11782 		}
11783 
11784 		rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
11785 
11786 		/* Restore orignal RRSR setting,only 8812 set RRSR after set ch/bw/band */
11787 		#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11788 			rtw_phydm_set_rrsr(adapter, hal_data->RegRRSR, TRUE);
11789 		#endif
11790 
11791 		#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
11792 		if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
11793 			/* Restore orignal 0x718 setting*/
11794 			rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
11795 		}
11796 		#endif
11797 
11798 		#ifdef CONFIG_AP_MODE
11799 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11800 			ResumeTxBeacon(adapter);
11801 			rtw_mi_tx_beacon_hdl(adapter);
11802 		}
11803 		#endif
11804 	}
11805 }
11806 
11807 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
hw_var_set_mlme_join(_adapter * adapter,u8 type)11808 static void hw_var_set_mlme_join(_adapter *adapter, u8 type)
11809 {
11810 	u8 val8;
11811 	u16 val16;
11812 	u32 val32;
11813 	u8 RetryLimit = RL_VAL_STA;
11814 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11815 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11816 
11817 #ifdef CONFIG_CONCURRENT_MODE
11818 	if (type == 0) {
11819 		/* prepare to join */
11820 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11821 			StopTxBeacon(adapter);
11822 
11823 		/* enable to rx data frame.Accept all data frame */
11824 		rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11825 
11826 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
11827 			RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
11828 		else /* Ad-hoc Mode */
11829 			RetryLimit = RL_VAL_AP;
11830 
11831 		rtw_iface_enable_tsf_update(adapter);
11832 
11833 	} else if (type == 1) {
11834 		/* joinbss_event call back when join res < 0 */
11835 		if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
11836 			rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
11837 
11838 		rtw_iface_disable_tsf_update(adapter);
11839 
11840 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11841 			ResumeTxBeacon(adapter);
11842 
11843 			/* reset TSF 1/2 after ResumeTxBeacon */
11844 			rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
11845 		}
11846 
11847 	} else if (type == 2) {
11848 		/* sta add event call back */
11849 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
11850 			/* fixed beacon issue for 8191su........... */
11851 			rtw_write8(adapter, 0x542 , 0x02);
11852 			RetryLimit = RL_VAL_AP;
11853 		}
11854 
11855 		if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11856 			ResumeTxBeacon(adapter);
11857 
11858 			/* reset TSF 1/2 after ResumeTxBeacon */
11859 			rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
11860 		}
11861 	}
11862 
11863 	val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
11864 	rtw_write16(adapter, REG_RETRY_LIMIT, val16);
11865 #else /* !CONFIG_CONCURRENT_MODE */
11866 	if (type == 0) { /* prepare to join */
11867 		/* enable to rx data frame.Accept all data frame */
11868 		rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11869 
11870 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
11871 			RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
11872 		else /* Ad-hoc Mode */
11873 			RetryLimit = RL_VAL_AP;
11874 
11875 		rtw_iface_enable_tsf_update(adapter);
11876 
11877 	} else if (type == 1) { /* joinbss_event call back when join res < 0 */
11878 		rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
11879 
11880 		rtw_iface_disable_tsf_update(adapter);
11881 
11882 	} else if (type == 2) { /* sta add event call back */
11883 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
11884 			RetryLimit = RL_VAL_AP;
11885 	}
11886 
11887 	val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
11888 	rtw_write16(adapter, REG_RETRY_LIMIT, val16);
11889 #endif /* !CONFIG_CONCURRENT_MODE */
11890 }
11891 #endif
11892 
11893 #ifdef CONFIG_TSF_RESET_OFFLOAD
rtw_hal_h2c_reset_tsf(_adapter * adapter,u8 reset_port)11894 static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
11895 {
11896 	u8 buf[2];
11897 	int ret;
11898 
11899 	if (reset_port == HW_PORT0) {
11900 		buf[0] = 0x1;
11901 		buf[1] = 0;
11902 	} else {
11903 		buf[0] = 0x0;
11904 		buf[1] = 0x1;
11905 	}
11906 
11907 	ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
11908 
11909 	return ret;
11910 }
11911 
rtw_hal_reset_tsf(_adapter * adapter,u8 reset_port)11912 int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
11913 {
11914 	u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
11915 	u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
11916 				REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
11917 	int ret;
11918 
11919 	/* site survey will cause reset tsf fail */
11920 	rtw_mi_buddy_scan_abort(adapter, _FALSE);
11921 	reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
11922 	ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
11923 	if (ret != _SUCCESS)
11924 		return ret;
11925 
11926 	while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
11927 		rtw_msleep_os(100);
11928 		loop_cnt++;
11929 		reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
11930 	}
11931 
11932 	return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
11933 }
11934 #endif /* CONFIG_TSF_RESET_OFFLOAD */
11935 
11936 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
11937 #ifdef CONFIG_HW_P0_TSF_SYNC
11938 #ifdef CONFIG_CONCURRENT_MODE
hw_port0_tsf_sync_sel(_adapter * adapter,u8 benable,u8 hw_port,u16 tr_offset)11939 static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)
11940 {
11941 	u8 val8;
11942 	u8 client_id = 0;
11943 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11944 
11945 #ifdef CONFIG_MCC_MODE
11946 	if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {
11947 		RTW_INFO("[MCC] do not set HW TSF sync\n");
11948 		return;
11949 	}
11950 #endif
11951 	/* check if port0 is already synced */
11952 	if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {
11953 		RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",
11954 			FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);
11955 		return;
11956 	}
11957 
11958 	/* check if port0 already disable sync */
11959 	if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {
11960 		RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));
11961 		return;
11962 	}
11963 
11964 	/* check if port0 sync to port0 */
11965 	if (benable && hw_port == HW_PORT0) {
11966 		RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));
11967 		rtw_warn_on(1);
11968 		return;
11969 	}
11970 
11971 	/*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/
11972 	/*	Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.
11973 		Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/
11974 
11975 	val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);
11976 
11977 	if (benable) {
11978 		/*Disable Port0's beacon function*/
11979 		rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
11980 
11981 		/*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/
11982 		if (tr_offset)
11983 			rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);
11984 
11985 		/*reg 0x577[6]=1*/	/*auto sync by tbtt*/
11986 		rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);
11987 
11988 		if (HW_PORT1 == hw_port)
11989 			client_id = 0;
11990 		else if (HW_PORT2 == hw_port)
11991 			client_id = 1;
11992 		else if (HW_PORT3 == hw_port)
11993 			client_id = 2;
11994 		else if (HW_PORT4 == hw_port)
11995 			client_id = 3;
11996 
11997 		val8 &= 0x8F;
11998 		val8 |= (BIT(6) | (client_id << 4));
11999 
12000 		dvobj->p0_tsf.sync_port = hw_port;
12001 		dvobj->p0_tsf.offset = tr_offset;
12002 		rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12003 
12004 		/*Enable Port0's beacon function*/
12005 		rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL)  | BIT_EN_BCN_FUNCTION);
12006 		RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);
12007 	} else {
12008 		val8 &= ~BIT(6);
12009 
12010 		dvobj->p0_tsf.sync_port = MAX_HW_PORT;
12011 		dvobj->p0_tsf.offset = 0;
12012 		rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12013 		RTW_INFO("%s P0 TSF sync disable\n", __func__);
12014 	}
12015 }
_search_ld_sta(_adapter * adapter,u8 include_self)12016 static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)
12017 {
12018 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12019 	u8 i;
12020 	_adapter *iface = NULL;
12021 
12022 	if (rtw_mi_get_assoced_sta_num(adapter) == 0) {
12023 		RTW_ERR("STA_LD_NUM == 0\n");
12024 		rtw_warn_on(1);
12025 	}
12026 
12027 	for (i = 0; i < dvobj->iface_nums; i++) {
12028 		iface = dvobj->padapters[i];
12029 		if (!iface)
12030 			continue;
12031 		if (include_self == _FALSE && adapter == iface)
12032 			continue;
12033 		if (is_client_associated_to_ap(iface))
12034 			break;
12035 	}
12036 	if (iface)
12037 		RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));
12038 	return iface;
12039 }
12040 #endif /*CONFIG_CONCURRENT_MODE*/
12041 /*Correct port0's TSF*/
12042 /*#define DBG_P0_TSF_SYNC*/
hw_var_set_correct_tsf(PADAPTER adapter,u8 mlme_state)12043 void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)
12044 {
12045 #ifdef CONFIG_CONCURRENT_MODE
12046 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12047 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12048 	_adapter *sta_if = NULL;
12049 	u8 hw_port;
12050 
12051 	RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));
12052 	#ifdef DBG_P0_TSF_SYNC
12053 	RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));
12054 	RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));
12055 	RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));
12056 	if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12057 		RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");
12058 	else
12059 		RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12060 	RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12061 	#endif
12062 	switch (mlme_state) {
12063 		case MLME_STA_CONNECTED :
12064 			{
12065 				hw_port = rtw_hal_get_port(adapter);
12066 
12067 				if (!MLME_IS_STA(adapter)) {
12068 					RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12069 					rtw_warn_on(1);
12070 				}
12071 
12072 				if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {
12073 					RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));
12074 					rtw_warn_on(1);
12075 					hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12076 				}
12077 
12078 				if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12079 					(rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {
12080 					hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12081 					#ifdef DBG_P0_TSF_SYNC
12082 					RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");
12083 					#endif
12084 				}
12085 			}
12086 			break;
12087 		case MLME_STA_DISCONNECTED :
12088 			{
12089 				hw_port = rtw_hal_get_port(adapter);
12090 
12091 				if (!MLME_IS_STA(adapter)) {
12092 					RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12093 					rtw_warn_on(1);
12094 				}
12095 
12096 				if (dvobj->p0_tsf.sync_port == hw_port) {
12097 					if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {
12098 						/* search next appropriate sta*/
12099 						sta_if = _search_ld_sta(adapter, _FALSE);
12100 						if (sta_if) {
12101 							hw_port = rtw_hal_get_port(sta_if);
12102 							hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12103 							#ifdef DBG_P0_TSF_SYNC
12104 							RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");
12105 							#endif
12106 						}
12107 					} else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {
12108 						hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12109 						#ifdef DBG_P0_TSF_SYNC
12110 						RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");
12111 						#endif
12112 					}
12113 				}
12114 			}
12115 			break;
12116 #ifdef CONFIG_AP_MODE
12117 		case MLME_AP_STARTED :
12118 		case MLME_MESH_STARTED :
12119 			{
12120 				if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12121 					RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12122 					rtw_warn_on(1);
12123 				}
12124 
12125 				if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12126 					rtw_mi_get_assoced_sta_num(adapter)) {
12127 					/* get port of sta */
12128 					sta_if = _search_ld_sta(adapter, _FALSE);
12129 					if (sta_if) {
12130 						hw_port = rtw_hal_get_port(sta_if);
12131 						hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12132 						#ifdef DBG_P0_TSF_SYNC
12133 						RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");
12134 						#endif
12135 					}
12136 				}
12137 			}
12138 			break;
12139 		case MLME_AP_STOPPED :
12140 		case MLME_MESH_STOPPED :
12141 			{
12142 				if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12143 					RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12144 					rtw_warn_on(1);
12145 				}
12146 				/*stop ap mode*/
12147 				if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&
12148 					(dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {
12149 					hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12150 					#ifdef DBG_P0_TSF_SYNC
12151 					RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");
12152 					#endif
12153 				}
12154 			}
12155 			break;
12156 #endif /* CONFIG_AP_MODE */
12157 		default :
12158 			RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);
12159 			break;
12160 	}
12161 
12162 	/*#ifdef DBG_P0_TSF_SYNC*/
12163 	#if 1
12164 	if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12165 		RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");
12166 	else
12167 		RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12168 	RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12169 	#endif
12170 #endif /*CONFIG_CONCURRENT_MODE*/
12171 }
12172 
12173 #else /*! CONFIG_HW_P0_TSF_SYNC*/
12174 
12175 #ifdef CONFIG_MI_WITH_MBSSID_CAM
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12176 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12177 {
12178 	/*do nothing*/
12179 }
12180 #else /* !CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)12181 static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
12182 {
12183 	if (hw_port == HW_PORT0) {
12184 		/*disable related TSF function*/
12185 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
12186 #if defined(CONFIG_RTL8192F)
12187 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12188 					REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);
12189 #endif
12190 
12191 		rtw_write32(padapter, REG_TSFTR, tsf);
12192 		rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
12193 
12194 		/*enable related TSF function*/
12195 		rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
12196 #if defined(CONFIG_RTL8192F)
12197 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12198 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
12199 #endif
12200 	} else if (hw_port == HW_PORT1) {
12201 		/*disable related TSF function*/
12202 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~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_1_FUNCTION);
12206 #endif
12207 
12208 		rtw_write32(padapter, REG_TSFTR1, tsf);
12209 		rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
12210 
12211 		/*enable related TSF function*/
12212 		rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
12213 #if defined(CONFIG_RTL8192F)
12214 		rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12215 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);
12216 #endif
12217 	} else
12218 		RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
12219 }
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12220 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12221 {
12222 	u64 tsf;
12223 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
12224 	struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
12225 
12226 	tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
12227 
12228 	if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12229 		|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12230 		StopTxBeacon(adapter);
12231 
12232 	rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
12233 
12234 #ifdef CONFIG_CONCURRENT_MODE
12235 	/* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
12236 	if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
12237 		&& (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12238 	) {
12239 		struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12240 		int i;
12241 		_adapter *iface;
12242 
12243 		for (i = 0; i < dvobj->iface_nums; i++) {
12244 			iface = dvobj->padapters[i];
12245 			if (!iface)
12246 				continue;
12247 			if (iface == adapter)
12248 				continue;
12249 
12250 			#ifdef CONFIG_AP_MODE
12251 			if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
12252 				&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
12253 			) {
12254 				rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
12255 				#ifdef CONFIG_TSF_RESET_OFFLOAD
12256 				if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
12257 					RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
12258 						, __func__, ADPT_ARG(iface), iface->hw_port);
12259 				#endif	/* CONFIG_TSF_RESET_OFFLOAD*/
12260 			}
12261 			#endif /* CONFIG_AP_MODE */
12262 		}
12263 	}
12264 #endif /* CONFIG_CONCURRENT_MODE */
12265 	if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12266 		|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12267 		ResumeTxBeacon(adapter);
12268 }
12269 #endif /*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
12270 #endif /*#ifdef CONFIG_HW_P0_TSF_SYNC*/
12271 #endif /*#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF*/
12272 
rtw_hal_get_tsftr_by_port(_adapter * adapter,u8 port)12273 u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)
12274 {
12275 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
12276 	u64 tsftr = 0;
12277 
12278 	if (port >= hal_spec->port_num) {
12279 		RTW_ERR("%s invalid port(%d) \n", __func__, port);
12280 		goto exit;
12281 	}
12282 
12283 	switch (rtw_get_chip_type(adapter)) {
12284 #if defined(CONFIG_RTL8814B)
12285 	case RTL8814B:
12286 	{
12287 		u8 val8;
12288 
12289 		/* 0x1500[6:4] - BIT_BCN_TIMER_SEL_FWRD_V1 */
12290 		val8 = rtw_read8(adapter, REG_PORT_CTRL_SEL);
12291 		val8 &= ~0x70;
12292 		val8 |= port << 4;
12293 		rtw_write8(adapter, REG_PORT_CTRL_SEL, val8);
12294 
12295 		tsftr = rtw_read32(adapter, REG_TSFTR_HIGH);
12296 		tsftr = tsftr << 32;
12297 		tsftr |= rtw_read32(adapter, REG_TSFTR_LOW);
12298 
12299 		break;
12300 	}
12301 #endif
12302 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
12303 	case RTL8814A:
12304 	case RTL8822B:
12305 	case RTL8821C:
12306 	case RTL8822C:
12307 	{
12308 		u8 val8;
12309 
12310 		/* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */
12311 		val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);
12312 		val8 &= 0x8F;
12313 		val8 |= port << 4;
12314 		rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);
12315 
12316 		tsftr = rtw_read32(adapter, REG_TSFTR + 4);
12317 		tsftr = tsftr << 32;
12318 		tsftr |= rtw_read32(adapter, REG_TSFTR);
12319 
12320 		break;
12321 	}
12322 #endif
12323 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \
12324 		|| defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \
12325 		|| defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \
12326 		|| defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
12327 		|| defined(CONFIG_RTL8710B)
12328 	case RTL8188E:
12329 	case RTL8188F:
12330 	case RTL8188GTV:
12331 	case RTL8192E:
12332 	case RTL8192F:
12333 	case RTL8723B:
12334 	case RTL8703B:
12335 	case RTL8723D:
12336 	case RTL8812:
12337 	case RTL8821:
12338 	case RTL8710B:
12339 	{
12340 		u32 addr;
12341 
12342 		if (port == HW_PORT0)
12343 			addr = REG_TSFTR;
12344 		else if (port == HW_PORT1)
12345 			addr = REG_TSFTR1;
12346 		else {
12347 			RTW_ERR("%s unknown port(%d) \n", __func__, port);
12348 			goto exit;
12349 		}
12350 
12351 		tsftr = rtw_read32(adapter, addr + 4);
12352 		tsftr = tsftr << 32;
12353 		tsftr |= rtw_read32(adapter, addr);
12354 
12355 		break;
12356 	}
12357 #endif
12358 	default:
12359 		RTW_ERR("%s unknow chip type\n", __func__);
12360 	}
12361 
12362 exit:
12363 	return tsftr;
12364 }
12365 
12366 #ifdef CONFIG_TDLS
12367 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)12368 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
12369 {
12370 	PHAL_DATA_TYPE	pHalData =  GET_HAL_DATA(padapter);
12371 	u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
12372 
12373 
12374 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
12375 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
12376 	switch (bwmode) {
12377 	case CHANNEL_WIDTH_40:
12378 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
12379 		break;
12380 	case CHANNEL_WIDTH_80:
12381 		SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
12382 		break;
12383 	case CHANNEL_WIDTH_20:
12384 	default:
12385 		break;
12386 	}
12387 	SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
12388 
12389 	return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
12390 }
12391 #endif
12392 #endif
12393 
12394 #ifdef CONFIG_WMMPS_STA
rtw_hal_update_uapsd_tid(_adapter * adapter)12395 void rtw_hal_update_uapsd_tid(_adapter *adapter)
12396 {
12397 	struct mlme_priv		*pmlmepriv = &adapter->mlmepriv;
12398 	struct qos_priv		*pqospriv = &pmlmepriv->qospriv;
12399 
12400 	/* write complement of pqospriv->uapsd_tid to mac register 0x693 because
12401 	    it's designed  for "0" represents "enable" and "1" represents "disable" */
12402 	rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
12403 }
12404 #endif /* CONFIG_WMMPS_STA */
12405 
12406 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
12407 /* 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)12408 s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)
12409 {
12410 	u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
12411 	u8 hw_port = rtw_hal_get_port(adapter);
12412 
12413 	SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);
12414 	RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);
12415 	return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
12416 }
12417 #endif
12418 
12419 #define LPS_ACTIVE_TIMEOUT	50 /*number of times*/
rtw_lps_state_chk(_adapter * adapter,u8 ps_mode)12420 void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)
12421 {
12422 	struct pwrctrl_priv 		*pwrpriv = adapter_to_pwrctl(adapter);
12423 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
12424 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12425 	struct sta_priv		*pstapriv = &adapter->stapriv;
12426 	struct sta_info		*psta = NULL;
12427 	u8 ps_ready = _FALSE;
12428 	s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;
12429 
12430 	if (ps_mode == PS_MODE_ACTIVE) {
12431 #ifdef CONFIG_LPS_ACK
12432 		if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) {
12433 			if (pwrpriv->lps_ack_status > 0) {
12434 				psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
12435 				if (psta != NULL) {
12436 					if(issue_nulldata(adapter, psta->cmn.mac_addr, PS_MODE_ACTIVE, 3, 1) == _FAIL)
12437 						RTW_INFO(FUNC_ADPT_FMT" LPS state sync not yet finished.\n", FUNC_ADPT_ARG(adapter));
12438 				}
12439 			}
12440 		} else {
12441 			RTW_WARN("LPS sctx query timeout, operation abort!!\n");
12442 			return;
12443 		}
12444 		pwrpriv->lps_ack_status = -1;
12445 #else
12446 		do {
12447 			if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {
12448 				ps_ready = _TRUE;
12449 				break;
12450 			}
12451 			rtw_msleep_os(1);
12452 		} while (leave_wait_count--);
12453 
12454 		if (ps_ready == _FALSE) {
12455 			RTW_WARN(FUNC_ADPT_FMT" Power Bit Control is still in HW!\n", FUNC_ADPT_ARG(adapter));
12456 			return;
12457 		}
12458 #endif /* CONFIG_LPS_ACK */
12459 		}
12460 	}
12461 
rtw_var_set_basic_rate(PADAPTER padapter,u8 * val)12462 void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) {
12463 
12464 	PHAL_DATA_TYPE	pHalData = GET_HAL_DATA(padapter);
12465 	struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
12466 	u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
12467 	u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
12468 	u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
12469 	#if CONFIG_IEEE80211_BAND_5GHZ
12470 	u16 rrsr_5g_force_mask = (RRSR_6M);
12471 	u16 rrsr_5g_allow_mask = (RRSR_OFDM_RATES);
12472 	#endif
12473 	u32 temp_RRSR;
12474 
12475 	HalSetBrateCfg(padapter, val, &BrateCfg);
12476 	input_b = BrateCfg;
12477 
12478 	/* apply force and allow mask */
12479 	#if CONFIG_IEEE80211_BAND_5GHZ
12480 	if (pHalData->current_band_type != BAND_ON_2_4G) {
12481 		BrateCfg |= rrsr_5g_force_mask;
12482 		BrateCfg &= rrsr_5g_allow_mask;
12483 	} else
12484 	#endif
12485 	{ /* 2.4G */
12486 		BrateCfg |= rrsr_2g_force_mask;
12487 		BrateCfg &= rrsr_2g_allow_mask;
12488 	}
12489 	masked = BrateCfg;
12490 
12491 #ifdef CONFIG_CMCC_TEST
12492 	BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */
12493 	BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */
12494 #endif
12495 
12496 	/* IOT consideration */
12497 	if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
12498 		/* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
12499 		if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
12500 			BrateCfg |= RRSR_6M;
12501 	}
12502 		ioted = BrateCfg;
12503 
12504 #ifdef CONFIG_NARROWBAND_SUPPORTING
12505 	if ((padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
12506 		|| (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_5)) {
12507 		BrateCfg &= ~RRSR_CCK_RATES;
12508 		BrateCfg |= RRSR_6M;
12509 	}
12510 #endif
12511 	pHalData->BasicRateSet = BrateCfg;
12512 
12513 	RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
12514 
12515 	/* Set RRSR rate table. */
12516 		temp_RRSR = rtw_read32(padapter, REG_RRSR);
12517 		temp_RRSR &=0xFFFF0000;
12518 		temp_RRSR |=BrateCfg;
12519 		rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE);
12520 
12521 	rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);
12522 
12523 	#if defined(CONFIG_RTL8188E)
12524 	rtw_hal_set_hwreg(padapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);
12525 	#endif
12526 }
12527 
SetHwReg(_adapter * adapter,u8 variable,u8 * val)12528 u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
12529 {
12530 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12531 	u8 ret = _SUCCESS;
12532 
12533 	switch (variable) {
12534 	case HW_VAR_MEDIA_STATUS: {
12535 		u8 net_type = *((u8 *)val);
12536 
12537 		rtw_hal_set_msr(adapter, net_type);
12538 	}
12539 	break;
12540 	case HW_VAR_DO_IQK:
12541 		if (*val)
12542 			hal_data->bNeedIQK = _TRUE;
12543 		else
12544 			hal_data->bNeedIQK = _FALSE;
12545 		break;
12546 	case HW_VAR_MAC_ADDR:
12547 #ifdef CONFIG_MI_WITH_MBSSID_CAM
12548 		rtw_hal_set_macaddr_mbid(adapter, val);
12549 #else
12550 		rtw_hal_set_macaddr_port(adapter, val);
12551 #endif
12552 		break;
12553 	case HW_VAR_BSSID:
12554 		rtw_hal_set_bssid(adapter, val);
12555 		break;
12556 	case HW_VAR_RCR:
12557 		ret = hw_var_rcr_config(adapter, *((u32 *)val));
12558 		break;
12559 	case HW_VAR_ON_RCR_AM:
12560 		hw_var_set_rcr_am(adapter, 1);
12561 		break;
12562 	case HW_VAR_OFF_RCR_AM:
12563 		hw_var_set_rcr_am(adapter, 0);
12564 		break;
12565 	case HW_VAR_BEACON_INTERVAL:
12566 		hw_var_set_bcn_interval(adapter, *(u16 *)val);
12567 		break;
12568 #ifdef CONFIG_MBSSID_CAM
12569 	case HW_VAR_MBSSID_CAM_WRITE: {
12570 		u32	cmd = 0;
12571 		u32	*cam_val = (u32 *)val;
12572 
12573 		rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
12574 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
12575 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
12576 	}
12577 		break;
12578 	case HW_VAR_MBSSID_CAM_CLEAR: {
12579 		u32 cmd;
12580 		u8 entry_id = *(u8 *)val;
12581 
12582 		rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
12583 
12584 		cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
12585 		rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
12586 	}
12587 		break;
12588 	case HW_VAR_RCR_MBSSID_EN:
12589 		if (*((u8 *)val))
12590 			rtw_hal_rcr_add(adapter, RCR_ENMBID);
12591 		else
12592 			rtw_hal_rcr_clear(adapter, RCR_ENMBID);
12593 		break;
12594 #endif
12595 	case HW_VAR_PORT_SWITCH:
12596 		hw_var_port_switch(adapter);
12597 		break;
12598 	case HW_VAR_INIT_RTS_RATE: {
12599 		u16 brate_cfg = *((u16 *)val);
12600 		u8 rate_index = 0;
12601 		HAL_VERSION *hal_ver = &hal_data->version_id;
12602 
12603 		if (IS_8188E(*hal_ver)) {
12604 
12605 			while (brate_cfg > 0x1) {
12606 				brate_cfg = (brate_cfg >> 1);
12607 				rate_index++;
12608 			}
12609 			rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
12610 		} else
12611 			rtw_warn_on(1);
12612 	}
12613 		break;
12614 	case HW_VAR_SEC_CFG: {
12615 		u16 reg_scr_ori;
12616 		u16 reg_scr;
12617 
12618 		reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
12619 		reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
12620 
12621 		if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
12622 			reg_scr |= SCR_CHK_BMC;
12623 
12624 		if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
12625 			reg_scr |= SCR_NoSKMC;
12626 
12627 		if (reg_scr != reg_scr_ori)
12628 			rtw_write16(adapter, REG_SECCFG, reg_scr);
12629 	}
12630 		break;
12631 	case HW_VAR_SEC_DK_CFG: {
12632 		struct security_priv *sec = &adapter->securitypriv;
12633 		u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
12634 
12635 		if (val) { /* Enable default key related setting */
12636 			reg_scr |= SCR_TXBCUSEDK;
12637 			if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
12638 				reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
12639 		} else /* Disable default key related setting */
12640 			reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
12641 
12642 		rtw_write8(adapter, REG_SECCFG, reg_scr);
12643 	}
12644 		break;
12645 
12646 	case HW_VAR_ASIX_IOT:
12647 		/* enable  ASIX IOT function */
12648 		if (*((u8 *)val) == _TRUE) {
12649 			/* 0xa2e[0]=0 (disable rake receiver) */
12650 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
12651 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
12652 			/* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
12653 			rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
12654 		} else {
12655 			/* restore reg:0xa2e,   reg:0xa1c */
12656 			rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
12657 				rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
12658 			rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
12659 		}
12660 		break;
12661 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
12662 	case HW_VAR_WOWLAN: {
12663 		struct wowlan_ioctl_param *poidparam;
12664 
12665 		poidparam = (struct wowlan_ioctl_param *)val;
12666 		switch (poidparam->subcode) {
12667 #ifdef CONFIG_WOWLAN
12668 		case WOWLAN_PATTERN_CLEAN:
12669 			rtw_hal_dl_pattern(adapter, 2);
12670 			break;
12671 		case WOWLAN_ENABLE:
12672 			rtw_hal_wow_enable(adapter);
12673 			break;
12674 		case WOWLAN_DISABLE:
12675 			rtw_hal_wow_disable(adapter);
12676 			break;
12677 #endif /*CONFIG_WOWLAN*/
12678 #ifdef CONFIG_AP_WOWLAN
12679 		case WOWLAN_AP_ENABLE:
12680 			rtw_hal_ap_wow_enable(adapter);
12681 			break;
12682 		case WOWLAN_AP_DISABLE:
12683 			rtw_hal_ap_wow_disable(adapter);
12684 			break;
12685 #endif /*CONFIG_AP_WOWLAN*/
12686 		default:
12687 			break;
12688 		}
12689 	}
12690 		break;
12691 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
12692 
12693 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
12694 	case HW_VAR_BCN_FUNC:
12695 		hw_var_set_bcn_func(adapter, *val);
12696 		break;
12697 #endif
12698 
12699 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
12700 	case HW_VAR_MLME_DISCONNECT:
12701 		hw_var_set_mlme_disconnect(adapter);
12702 		break;
12703 #endif
12704 
12705 	case HW_VAR_MLME_SITESURVEY:
12706 		hw_var_set_mlme_sitesurvey(adapter, *val);
12707 		#ifdef CONFIG_BT_COEXIST
12708 		if (hal_data->EEPROMBluetoothCoexist == 1)
12709 			rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
12710 		#endif
12711 		break;
12712 
12713 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
12714 	case HW_VAR_MLME_JOIN:
12715 		hw_var_set_mlme_join(adapter, *val);
12716 		break;
12717 #endif
12718 
12719 	case HW_VAR_EN_HW_UPDATE_TSF:
12720 		rtw_hal_set_hw_update_tsf(adapter);
12721 		break;
12722 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
12723 	case HW_VAR_CORRECT_TSF:
12724 		hw_var_set_correct_tsf(adapter, *val);
12725 		break;
12726 #endif
12727 
12728 #if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_MCC_MODE)
12729 	case HW_VAR_TSF_AUTO_SYNC:
12730 		if (*val == _TRUE)
12731 			hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);
12732 		else
12733 			hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);
12734 		break;
12735 #endif
12736 	case HW_VAR_APFM_ON_MAC:
12737 		hal_data->bMacPwrCtrlOn = *val;
12738 		RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
12739 		break;
12740 #ifdef CONFIG_WMMPS_STA
12741 	case  HW_VAR_UAPSD_TID:
12742 		rtw_hal_update_uapsd_tid(adapter);
12743 		break;
12744 #endif /* CONFIG_WMMPS_STA */
12745 #ifdef CONFIG_LPS_PG
12746 	case HW_VAR_LPS_PG_HANDLE:
12747 		rtw_hal_lps_pg_handler(adapter, *val);
12748 		break;
12749 #endif
12750 #ifdef CONFIG_LPS_LCLK_WD_TIMER
12751 	case HW_VAR_DM_IN_LPS_LCLK:
12752 		rtw_phydm_wd_lps_lclk_hdl(adapter);
12753 		break;
12754 #endif
12755 	case HW_VAR_ENABLE_RX_BAR:
12756 		if (*val == _TRUE) {
12757 			/* enable RX BAR */
12758 			u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
12759 
12760 			val16 |= BIT(8);
12761 			rtw_write16(adapter, REG_RXFLTMAP1, val16);
12762 		} else {
12763 			/* disable RX BAR */
12764 			u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
12765 
12766 			val16 &= (~BIT(8));
12767 			rtw_write16(adapter, REG_RXFLTMAP1, val16);
12768 		}
12769 		RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",
12770 			REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));
12771 		break;
12772 	case HW_VAR_HCI_SUS_STATE:
12773 		hal_data->hci_sus_state = *(u8 *)val;
12774 		RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);
12775 		break;
12776 #if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)
12777 		case HW_VAR_BCN_HEAD_SEL:
12778 		{
12779 			u8 vap_id = *(u8 *)val;
12780 
12781 			if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {
12782 				RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);
12783 				rtw_warn_on(1);
12784 			}
12785 			if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
12786 				u16 drv_pg_bndy = 0, bcn_addr = 0;
12787 				u32 page_size = 0;
12788 
12789 				/*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/
12790 				rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);
12791 				rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
12792 
12793 				if (vap_id != 0xFF)
12794 					bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));
12795 				else
12796 					bcn_addr = drv_pg_bndy;
12797 				RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",
12798 					ADPT_ARG(adapter), vap_id, bcn_addr);
12799 				rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,
12800 					(bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);
12801 			}
12802 		}
12803 		break;
12804 #endif
12805 	case HW_VAR_LPS_STATE_CHK :
12806 		rtw_lps_state_chk(adapter, *(u8 *)val);
12807 		break;
12808 
12809 #ifdef CONFIG_RTS_FULL_BW
12810 	case HW_VAR_SET_RTS_BW:
12811 	{
12812 		#ifdef RTW_HALMAC
12813 			rtw_halmac_set_rts_full_bw(adapter_to_dvobj(adapter), (*val));
12814 		#else
12815 			u8 temp;
12816 			if(*val)
12817 				temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) | BIT5 );
12818 			else
12819 				temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) & (~BIT5));
12820 			rtw_write8(adapter, REG_INIRTS_RATE_SEL, temp);
12821 			/*RTW_INFO("HW_VAR_SET_RTS_BW	val=%u REG480=0x%x\n", *val, rtw_read8(adapter, REG_INIRTS_RATE_SEL));*/
12822 		#endif
12823 	}
12824 	break;
12825 #endif/*CONFIG_RTS_FULL_BW*/
12826 #if defined(CONFIG_PCI_HCI)
12827 	case HW_VAR_ENSWBCN:
12828 	if (*val == _TRUE) {
12829 		rtw_write8(adapter, REG_CR + 1,
12830 			   rtw_read8(adapter, REG_CR + 1) | BIT(0));
12831 	} else
12832 		rtw_write8(adapter, REG_CR + 1,
12833 			   rtw_read8(adapter, REG_CR + 1) & ~BIT(0));
12834 	break;
12835 #endif
12836 	default:
12837 		if (0)
12838 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
12839 				  FUNC_ADPT_ARG(adapter), variable);
12840 		ret = _FAIL;
12841 		break;
12842 	}
12843 
12844 	return ret;
12845 }
12846 
GetHwReg(_adapter * adapter,u8 variable,u8 * val)12847 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
12848 {
12849 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12850 	u64 val64;
12851 
12852 
12853 	switch (variable) {
12854 	case HW_VAR_MAC_ADDR:
12855 		#ifndef CONFIG_MI_WITH_MBSSID_CAM
12856 		rtw_hal_get_macaddr_port(adapter, val);
12857 		#endif
12858 		break;
12859 	case HW_VAR_BASIC_RATE:
12860 		*((u16 *)val) = hal_data->BasicRateSet;
12861 		break;
12862 	case HW_VAR_MEDIA_STATUS:
12863 		rtw_hal_get_msr(adapter, val);
12864 		break;
12865 	case HW_VAR_DO_IQK:
12866 		*val = hal_data->bNeedIQK;
12867 		break;
12868 	case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
12869 		if (hal_is_band_support(adapter, BAND_ON_5G))
12870 			*val = _TRUE;
12871 		else
12872 			*val = _FALSE;
12873 		break;
12874 	case HW_VAR_APFM_ON_MAC:
12875 		*val = hal_data->bMacPwrCtrlOn;
12876 		break;
12877 	case HW_VAR_RCR:
12878 		hw_var_rcr_get(adapter, (u32 *)val);
12879 		break;
12880 	case HW_VAR_FWLPS_RF_ON:
12881 		/* When we halt NIC, we should check if FW LPS is leave. */
12882 		if (rtw_is_surprise_removed(adapter)
12883 			|| (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
12884 		) {
12885 			/*
12886 			 * If it is in HW/SW Radio OFF or IPS state,
12887 			 * we do not check Fw LPS Leave,
12888 			 * because Fw is unload.
12889 			 */
12890 			*val = _TRUE;
12891 		} else {
12892 			u32 rcr = 0;
12893 
12894 			rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
12895 			if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
12896 				*val = _FALSE;
12897 			else
12898 				*val = _TRUE;
12899 		}
12900 		break;
12901 
12902 	case HW_VAR_HCI_SUS_STATE:
12903 		*((u8 *)val) = hal_data->hci_sus_state;
12904 		break;
12905 
12906 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
12907 	case HW_VAR_BCN_CTRL_ADDR:
12908 		*((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);
12909 		break;
12910 #endif
12911 
12912 #ifdef CONFIG_WAPI_SUPPORT
12913 	case HW_VAR_CAM_EMPTY_ENTRY: {
12914 		u8	ucIndex = *((u8 *)val);
12915 		u8	i;
12916 		u32	ulCommand = 0;
12917 		u32	ulContent = 0;
12918 		u32	ulEncAlgo = CAM_AES;
12919 
12920 		for (i = 0; i < CAM_CONTENT_COUNT; i++) {
12921 			/* filled id in CAM config 2 byte */
12922 			if (i == 0)
12923 				ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
12924 			else
12925 				ulContent = 0;
12926 			/* polling bit, and No Write enable, and address */
12927 			ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
12928 			ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
12929 			/* write content 0 is equall to mark invalid */
12930 			rtw_write32(adapter, REG_CAMWRITE, ulContent);  /* delay_ms(40); */
12931 			rtw_write32(adapter, REG_CAMCMD, ulCommand);  /* delay_ms(40); */
12932 		}
12933 	}
12934 #endif
12935 
12936 	default:
12937 		if (0)
12938 			RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
12939 				  FUNC_ADPT_ARG(adapter), variable);
12940 		break;
12941 	}
12942 
12943 }
12944 
_get_page_size(struct _ADAPTER * a)12945 static u32 _get_page_size(struct _ADAPTER *a)
12946 {
12947 #ifdef RTW_HALMAC
12948 	struct dvobj_priv *d;
12949 	u32 size = 0;
12950 	int err = 0;
12951 
12952 
12953 	d = adapter_to_dvobj(a);
12954 
12955 	err = rtw_halmac_get_page_size(d, &size);
12956 	if (!err)
12957 		return size;
12958 
12959 	RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
12960 		 FUNC_ADPT_ARG(a), err);
12961 #endif /* RTW_HALMAC */
12962 
12963 	return PAGE_SIZE_128;
12964 }
12965 
12966 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)12967 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
12968 {
12969 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12970 	u8 bResult = _SUCCESS;
12971 
12972 	switch (variable) {
12973 
12974 	case HAL_DEF_DBG_DUMP_RXPKT:
12975 		hal_data->bDumpRxPkt = *((u8 *)value);
12976 		break;
12977 	case HAL_DEF_DBG_DUMP_TXPKT:
12978 		hal_data->bDumpTxPkt = *((u8 *)value);
12979 		break;
12980 	case HAL_DEF_ANT_DETECT:
12981 		hal_data->AntDetection = *((u8 *)value);
12982 		break;
12983 	default:
12984 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
12985 		bResult = _FAIL;
12986 		break;
12987 	}
12988 
12989 	return bResult;
12990 }
12991 
12992 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)12993 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
12994 {
12995 	struct registry_priv	*pregistrypriv = &adapter->registrypriv;
12996 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12997 
12998 	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)))
12999 		return pregistrypriv->beamformer_rf_num;
13000 	else if (IS_HARDWARE_TYPE_8814AE(adapter)
13001 #if 0
13002 #if defined(CONFIG_USB_HCI)
13003 		|| (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2))  /* for USB3.0 */
13004 #endif
13005 #endif
13006 		) {
13007 		/*BF cap provided by Yu Chen, Sean, 2015, 01 */
13008 		if (hal_data->rf_type == RF_3T3R)
13009 			return 2;
13010 		else if (hal_data->rf_type == RF_4T4R)
13011 			return 3;
13012 		else
13013 			return 1;
13014 	} else
13015 		return 1;
13016 
13017 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)13018 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
13019 {
13020 	struct registry_priv		*pregistrypriv = &adapter->registrypriv;
13021 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
13022 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
13023 
13024 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13025 
13026 	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)))
13027 		return pregistrypriv->beamformee_rf_num;
13028 	else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
13029 		if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
13030 			return 2;
13031 		else
13032 			return 2;/*TODO: May be 3 in the future, by ChenYu. */
13033 	} else
13034 		return 1;
13035 
13036 }
13037 #ifdef RTW_BEAMFORMING_VERSION_2
rtw_hal_beamforming_config_csirate(PADAPTER adapter)13038 void rtw_hal_beamforming_config_csirate(PADAPTER adapter)
13039 {
13040 	struct dm_struct *p_dm_odm;
13041 	struct beamforming_info *bf_info;
13042 	u8 fix_rate_enable = 0;
13043 	u8 new_csi_rate_idx;
13044 	u8 rrsr_54_en;
13045 	u32 temp_rrsr;
13046 
13047 	/* Acting as BFee */
13048 	if (IS_BEAMFORMEE(adapter)) {
13049 	#if 0
13050 		/* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */
13051 		if (IS_HARDWARE_TYPE_8821C(Adapter))
13052 			FixRateEnable = 1;	/* Support after 8821C */
13053 	#endif
13054 
13055 		p_dm_odm = adapter_to_phydm(adapter);
13056 		bf_info = GET_BEAMFORM_INFO(adapter);
13057 
13058 		rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),
13059 				p_dm_odm->rssi_min,
13060 				bf_info->cur_csi_rpt_rate,
13061 				fix_rate_enable, &new_csi_rate_idx, &rrsr_54_en);
13062 
13063 		temp_rrsr = rtw_read32(adapter, REG_RRSR);
13064 		if (rrsr_54_en == 1)
13065 			temp_rrsr |= RRSR_54M;
13066 		else if (rrsr_54_en == 0)
13067 			temp_rrsr &= ~RRSR_54M;
13068 		rtw_phydm_set_rrsr(adapter, temp_rrsr, FALSE);
13069 
13070 		if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)
13071 			bf_info->cur_csi_rpt_rate = new_csi_rate_idx;
13072 	}
13073 }
13074 #endif
13075 #endif
13076 
13077 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13078 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13079 {
13080 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13081 	u8 bResult = _SUCCESS;
13082 
13083 	switch (variable) {
13084 	case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
13085 		struct mlme_priv *pmlmepriv;
13086 		struct sta_priv *pstapriv;
13087 		struct sta_info *psta;
13088 
13089 		pmlmepriv = &adapter->mlmepriv;
13090 		pstapriv = &adapter->stapriv;
13091 		psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
13092 		if (psta)
13093 			*((int *)value) = psta->cmn.rssi_stat.rssi;
13094 	}
13095 	break;
13096 	case HAL_DEF_DBG_DUMP_RXPKT:
13097 		*((u8 *)value) = hal_data->bDumpRxPkt;
13098 		break;
13099 	case HAL_DEF_DBG_DUMP_TXPKT:
13100 		*((u8 *)value) = hal_data->bDumpTxPkt;
13101 		break;
13102 	case HAL_DEF_ANT_DETECT:
13103 		*((u8 *)value) = hal_data->AntDetection;
13104 		break;
13105 	case HAL_DEF_TX_PAGE_SIZE:
13106 		*((u32 *)value) = _get_page_size(adapter);
13107 		break;
13108 	case HAL_DEF_TX_STBC:
13109 		#ifdef CONFIG_ALPHA_SMART_ANTENNA
13110 		*(u8 *)value = 0;
13111 		#else
13112 		*(u8 *)value = hal_data->max_tx_cnt > 1 ? 1 : 0;
13113 		#endif
13114 		break;
13115 	case HAL_DEF_EXPLICIT_BEAMFORMER:
13116 	case HAL_DEF_EXPLICIT_BEAMFORMEE:
13117 	case HAL_DEF_VHT_MU_BEAMFORMER:
13118 	case HAL_DEF_VHT_MU_BEAMFORMEE:
13119 		*(u8 *)value = _FALSE;
13120 		break;
13121 #ifdef CONFIG_BEAMFORMING
13122 	case HAL_DEF_BEAMFORMER_CAP:
13123 		*(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
13124 		break;
13125 	case HAL_DEF_BEAMFORMEE_CAP:
13126 		*(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
13127 		break;
13128 #endif
13129 	default:
13130 		RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
13131 		bResult = _FAIL;
13132 		break;
13133 	}
13134 
13135 	return bResult;
13136 }
13137 
13138 /*
13139  *	Description:
13140  *		Translate a character to hex digit.
13141  *   */
13142 u32
MapCharToHexDigit(char chTmp)13143 MapCharToHexDigit(
13144 			char		chTmp
13145 )
13146 {
13147 	if (chTmp >= '0' && chTmp <= '9')
13148 		return chTmp - '0';
13149 	else if (chTmp >= 'a' && chTmp <= 'f')
13150 		return 10 + (chTmp - 'a');
13151 	else if (chTmp >= 'A' && chTmp <= 'F')
13152 		return 10 + (chTmp - 'A');
13153 	else
13154 		return 0;
13155 }
13156 
13157 
13158 
13159 /*
13160  *	Description:
13161  *		Parse hex number from the string pucStr.
13162  *   */
13163 BOOLEAN
GetHexValueFromString(char * szStr,u32 * pu4bVal,u32 * pu4bMove)13164 GetHexValueFromString(
13165 		char			*szStr,
13166 		u32			*pu4bVal,
13167 		u32			*pu4bMove
13168 )
13169 {
13170 	char		*szScan = szStr;
13171 
13172 	/* Check input parameter. */
13173 	if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
13174 		RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
13175 		return _FALSE;
13176 	}
13177 
13178 	/* Initialize output. */
13179 	*pu4bMove = 0;
13180 	*pu4bVal = 0;
13181 
13182 	/* Skip leading space. */
13183 	while (*szScan != '\0' &&
13184 	       (*szScan == ' ' || *szScan == '\t')) {
13185 		szScan++;
13186 		(*pu4bMove)++;
13187 	}
13188 
13189 	/* Skip leading '0x' or '0X'. */
13190 	if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
13191 		szScan += 2;
13192 		(*pu4bMove) += 2;
13193 	}
13194 
13195 	/* Check if szScan is now pointer to a character for hex digit, */
13196 	/* if not, it means this is not a valid hex number. */
13197 	if (!IsHexDigit(*szScan))
13198 		return _FALSE;
13199 
13200 	/* Parse each digit. */
13201 	do {
13202 		(*pu4bVal) <<= 4;
13203 		*pu4bVal += MapCharToHexDigit(*szScan);
13204 
13205 		szScan++;
13206 		(*pu4bMove)++;
13207 	} while (IsHexDigit(*szScan));
13208 
13209 	return _TRUE;
13210 }
13211 
13212 BOOLEAN
GetFractionValueFromString(char * szStr,u8 * pInteger,u8 * pFraction,u32 * pu4bMove)13213 GetFractionValueFromString(
13214 		char			*szStr,
13215 		u8				*pInteger,
13216 		u8				*pFraction,
13217 		u32			*pu4bMove
13218 )
13219 {
13220 	char	*szScan = szStr;
13221 
13222 	/* Initialize output. */
13223 	*pu4bMove = 0;
13224 	*pInteger = 0;
13225 	*pFraction = 0;
13226 
13227 	/* Skip leading space. */
13228 	while (*szScan != '\0' &&	(*szScan == ' ' || *szScan == '\t')) {
13229 		++szScan;
13230 		++(*pu4bMove);
13231 	}
13232 
13233 	if (*szScan < '0' || *szScan > '9')
13234 		return _FALSE;
13235 
13236 	/* Parse each digit. */
13237 	do {
13238 		(*pInteger) *= 10;
13239 		*pInteger += (*szScan - '0');
13240 
13241 		++szScan;
13242 		++(*pu4bMove);
13243 
13244 		if (*szScan == '.') {
13245 			++szScan;
13246 			++(*pu4bMove);
13247 
13248 			if (*szScan < '0' || *szScan > '9')
13249 				return _FALSE;
13250 
13251 			*pFraction += (*szScan - '0') * 10;
13252 			++szScan;
13253 			++(*pu4bMove);
13254 
13255 			if (*szScan >= '0' && *szScan <= '9') {
13256 				*pFraction += *szScan - '0';
13257 				++szScan;
13258 				++(*pu4bMove);
13259 			}
13260 			return _TRUE;
13261 		}
13262 	} while (*szScan >= '0' && *szScan <= '9');
13263 
13264 	return _TRUE;
13265 }
13266 
13267 /*
13268  *	Description:
13269  * Return TRUE if szStr is comment out with leading " */ /* ".
13270  *   */
13271 BOOLEAN
IsCommentString(char * szStr)13272 IsCommentString(
13273 		char			*szStr
13274 )
13275 {
13276 	if (*szStr == '/' && *(szStr + 1) == '/')
13277 		return _TRUE;
13278 	else
13279 		return _FALSE;
13280 }
13281 
13282 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(char * Str,u8 * pInt)13283 GetU1ByteIntegerFromStringInDecimal(
13284 		char	*Str,
13285 		u8		*pInt
13286 )
13287 {
13288 	u16 i = 0;
13289 	*pInt = 0;
13290 
13291 	while (Str[i] != '\0') {
13292 		if (Str[i] >= '0' && Str[i] <= '9') {
13293 			*pInt *= 10;
13294 			*pInt += (Str[i] - '0');
13295 		} else
13296 			return _FALSE;
13297 		++i;
13298 	}
13299 
13300 	return _TRUE;
13301 }
13302 
13303 /* <20121004, Kordan> For example,
13304  * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
13305  * If RightQualifier does not exist, it will hang on in the while loop */
13306 BOOLEAN
ParseQualifiedString(char * In,u32 * Start,char * Out,char LeftQualifier,char RightQualifier)13307 ParseQualifiedString(
13308 			char	*In,
13309 			u32	*Start,
13310 			char	*Out,
13311 			char		LeftQualifier,
13312 			char		RightQualifier
13313 )
13314 {
13315 	u32	i = 0, j = 0;
13316 	char	c = In[(*Start)++];
13317 
13318 	if (c != LeftQualifier)
13319 		return _FALSE;
13320 
13321 	i = (*Start);
13322 	c = In[(*Start)++];
13323 	while (c != RightQualifier && c != '\0')
13324 		c = In[(*Start)++];
13325 
13326 	if (c == '\0')
13327 		return _FALSE;
13328 
13329 	j = (*Start) - 2;
13330 	strncpy((char *)Out, (const char *)(In + i), j - i + 1);
13331 
13332 	return _TRUE;
13333 }
13334 
13335 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)13336 isAllSpaceOrTab(
13337 	u8	*data,
13338 	u8	size
13339 )
13340 {
13341 	u8	cnt = 0, NumOfSpaceAndTab = 0;
13342 
13343 	while (size > cnt) {
13344 		if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
13345 			++NumOfSpaceAndTab;
13346 
13347 		++cnt;
13348 	}
13349 
13350 	return size == NumOfSpaceAndTab;
13351 }
13352 
13353 
rtw_hal_check_rxfifo_full(_adapter * adapter)13354 void rtw_hal_check_rxfifo_full(_adapter *adapter)
13355 {
13356 	struct dvobj_priv *psdpriv = adapter->dvobj;
13357 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
13358 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
13359 	struct registry_priv *regsty = &adapter->registrypriv;
13360 	int save_cnt = _FALSE;
13361 
13362 	if (regsty->check_hw_status == 1) {
13363 		/* switch counter to RX fifo */
13364 		if (IS_8188E(pHalData->version_id) ||
13365 		    IS_8188F(pHalData->version_id) ||
13366 		    IS_8188GTV(pHalData->version_id) ||
13367 		    IS_8812_SERIES(pHalData->version_id) ||
13368 		    IS_8821_SERIES(pHalData->version_id) ||
13369 		    IS_8723B_SERIES(pHalData->version_id) ||
13370 		    IS_8192E(pHalData->version_id) ||
13371 		    IS_8703B_SERIES(pHalData->version_id) ||
13372 		    IS_8723D_SERIES(pHalData->version_id) ||
13373 		    IS_8192F_SERIES(pHalData->version_id)) {
13374 			rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
13375 			save_cnt = _TRUE;
13376 		} else {
13377 			/* todo: other chips */
13378 		}
13379 
13380 
13381 		if (save_cnt) {
13382 			pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
13383 			pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
13384 			pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
13385 		} else {
13386 			/* special value to indicate no implementation */
13387 			pdbgpriv->dbg_rx_fifo_last_overflow = 1;
13388 			pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
13389 			pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
13390 		}
13391 	}
13392 }
13393 
linked_info_dump(_adapter * padapter,u8 benable)13394 void linked_info_dump(_adapter *padapter, u8 benable)
13395 {
13396 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
13397 
13398 	if (padapter->bLinkInfoDump == benable)
13399 		return;
13400 
13401 	RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
13402 
13403 	if (benable) {
13404 #ifdef CONFIG_LPS
13405 		pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
13406 		rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
13407 #endif
13408 
13409 #ifdef CONFIG_IPS
13410 		pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
13411 		rtw_pm_set_ips(padapter, IPS_NONE);
13412 #endif
13413 	} else {
13414 #ifdef CONFIG_IPS
13415 		rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
13416 #endif /* CONFIG_IPS */
13417 
13418 #ifdef CONFIG_LPS
13419 		rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
13420 #endif /* CONFIG_LPS */
13421 	}
13422 	padapter->bLinkInfoDump = benable ;
13423 }
13424 
13425 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)13426 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
13427 {
13428 	u8 isCCKrate, rf_path;
13429 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13430 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13431 	RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
13432 		HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
13433 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13434 
13435 	if (isCCKrate)
13436 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
13437 
13438 	for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13439 		if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13440 			continue;
13441 		RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
13442 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
13443 
13444 		if (!isCCKrate) {
13445 			RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
13446 				psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
13447 		}
13448 	}
13449 }
13450 
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)13451 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
13452 {
13453 	u8 isCCKrate, rf_path;
13454 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13455 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13456 	_RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
13457 	_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);
13458 
13459 	isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13460 
13461 	if (isCCKrate)
13462 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
13463 
13464 	for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13465 		if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13466 			continue;
13467 		_RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
13468 			, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
13469 
13470 		if (!isCCKrate)
13471 			_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]);
13472 		else
13473 			_RTW_PRINT_SEL(sel , "\n");
13474 
13475 	}
13476 }
13477 #endif
13478 
13479 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)13480 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
13481 {
13482 #define DBG_RX_DFRAME_RAW_DATA_UC		0
13483 #define DBG_RX_DFRAME_RAW_DATA_BMC		1
13484 #define DBG_RX_DFRAME_RAW_DATA_TYPES	2
13485 
13486 	_irqL irqL;
13487 	u8 isCCKrate, rf_path;
13488 	struct recv_priv *precvpriv = &(padapter->recvpriv);
13489 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13490 	struct sta_priv *pstapriv = &padapter->stapriv;
13491 	struct sta_info *psta;
13492 	struct sta_recv_dframe_info *psta_dframe_info;
13493 	int i, j;
13494 	_list	*plist, *phead;
13495 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13496 	u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
13497 
13498 	if (precvpriv->store_law_data_flag) {
13499 
13500 		_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13501 
13502 		for (i = 0; i < NUM_STA; i++) {
13503 			phead = &(pstapriv->sta_hash[i]);
13504 			plist = get_next(phead);
13505 
13506 			while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
13507 
13508 				psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
13509 				plist = get_next(plist);
13510 
13511 				if (psta) {
13512 					if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN)  !=   _TRUE)
13513 					    && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN)  !=  _TRUE)
13514 					    && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN)  !=  _TRUE)) {
13515 
13516 						RTW_PRINT_SEL(sel, "==============================\n");
13517 						RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
13518 
13519 						for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {
13520 							if (j == DBG_RX_DFRAME_RAW_DATA_UC) {
13521 								psta_dframe_info = &psta->sta_dframe_info;
13522 								RTW_PRINT_SEL(sel, "\n");
13523 								RTW_PRINT_SEL(sel, "Unicast:\n");
13524 							} else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {
13525 								psta_dframe_info = &psta->sta_dframe_info_bmc;
13526 								RTW_PRINT_SEL(sel, "\n");
13527 								RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");
13528 							}
13529 
13530 							isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13531 
13532 							RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);
13533 							RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
13534 
13535 							for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13536 								if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13537 									continue;
13538 								if (!isCCKrate) {
13539 									RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
13540 									_RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
13541 								} else
13542 									RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
13543 							}
13544 						}
13545 
13546 					}
13547 				}
13548 			}
13549 		}
13550 		_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13551 	}
13552 }
13553 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)13554 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
13555 {
13556 	u8 isCCKrate, rf_path , dframe_type;
13557 	u8 *ptr;
13558 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13559 #ifdef DBG_RX_DFRAME_RAW_DATA
13560 	struct sta_recv_dframe_info *psta_dframe_info;
13561 #endif
13562 	struct recv_priv *precvpriv = &(padapter->recvpriv);
13563 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13564 	struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
13565 	struct sta_info *psta = prframe->u.hdr.psta;
13566 	struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
13567 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13568 	psample_pkt_rssi->data_rate = pattrib->data_rate;
13569 	ptr = prframe->u.hdr.rx_data;
13570 	dframe_type = GetFrameType(ptr);
13571 	/*RTW_INFO("=>%s\n", __FUNCTION__);*/
13572 
13573 
13574 	if (precvpriv->store_law_data_flag) {
13575 		isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13576 
13577 		psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
13578 		psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
13579 
13580 		for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13581 			psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
13582 			psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
13583 			if (!isCCKrate) {
13584 				psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
13585 				psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
13586 			}
13587 		}
13588 #ifdef DBG_RX_DFRAME_RAW_DATA
13589 		if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
13590 
13591 			/*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
13592 			if (psta) {
13593 				if (IS_MCAST(get_ra(get_recvframe_data(prframe))))
13594 					psta_dframe_info = &psta->sta_dframe_info_bmc;
13595 				else
13596 					psta_dframe_info = &psta->sta_dframe_info;
13597 				/*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
13598 					__FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
13599 				if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
13600 					psta_dframe_info->sta_data_rate = pattrib->data_rate;
13601 					psta_dframe_info->sta_sgi = pattrib->sgi;
13602 					psta_dframe_info->sta_bw_mode = pattrib->bw;
13603 					for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13604 
13605 						psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
13606 
13607 						if (!isCCKrate) {
13608 							psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
13609 							psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
13610 						}
13611 					}
13612 				}
13613 			}
13614 		}
13615 #endif
13616 	}
13617 
13618 }
13619 
hal_efuse_macaddr_offset(_adapter * adapter)13620 int hal_efuse_macaddr_offset(_adapter *adapter)
13621 {
13622 	u8 interface_type = 0;
13623 	int addr_offset = -1;
13624 
13625 	interface_type = rtw_get_intf_type(adapter);
13626 
13627 	switch (rtw_get_chip_type(adapter)) {
13628 #ifdef CONFIG_RTL8723B
13629 	case RTL8723B:
13630 		if (interface_type == RTW_USB)
13631 			addr_offset = EEPROM_MAC_ADDR_8723BU;
13632 		else if (interface_type == RTW_SDIO)
13633 			addr_offset = EEPROM_MAC_ADDR_8723BS;
13634 		else if (interface_type == RTW_PCIE)
13635 			addr_offset = EEPROM_MAC_ADDR_8723BE;
13636 		break;
13637 #endif
13638 #ifdef CONFIG_RTL8703B
13639 	case RTL8703B:
13640 		if (interface_type == RTW_USB)
13641 			addr_offset = EEPROM_MAC_ADDR_8703BU;
13642 		else if (interface_type == RTW_SDIO)
13643 			addr_offset = EEPROM_MAC_ADDR_8703BS;
13644 		break;
13645 #endif
13646 #ifdef CONFIG_RTL8723D
13647 	case RTL8723D:
13648 		if (interface_type == RTW_USB)
13649 			addr_offset = EEPROM_MAC_ADDR_8723DU;
13650 		else if (interface_type == RTW_SDIO)
13651 			addr_offset = EEPROM_MAC_ADDR_8723DS;
13652 		else if (interface_type == RTW_PCIE)
13653 			addr_offset = EEPROM_MAC_ADDR_8723DE;
13654 		break;
13655 #endif
13656 
13657 #ifdef CONFIG_RTL8188E
13658 	case RTL8188E:
13659 		if (interface_type == RTW_USB)
13660 			addr_offset = EEPROM_MAC_ADDR_88EU;
13661 		else if (interface_type == RTW_SDIO)
13662 			addr_offset = EEPROM_MAC_ADDR_88ES;
13663 		else if (interface_type == RTW_PCIE)
13664 			addr_offset = EEPROM_MAC_ADDR_88EE;
13665 		break;
13666 #endif
13667 #ifdef CONFIG_RTL8188F
13668 	case RTL8188F:
13669 		if (interface_type == RTW_USB)
13670 			addr_offset = EEPROM_MAC_ADDR_8188FU;
13671 		else if (interface_type == RTW_SDIO)
13672 			addr_offset = EEPROM_MAC_ADDR_8188FS;
13673 		break;
13674 #endif
13675 #ifdef CONFIG_RTL8188GTV
13676 	case RTL8188GTV:
13677 		if (interface_type == RTW_USB)
13678 			addr_offset = EEPROM_MAC_ADDR_8188GTVU;
13679 		else if (interface_type == RTW_SDIO)
13680 			addr_offset = EEPROM_MAC_ADDR_8188GTVS;
13681 		break;
13682 #endif
13683 #ifdef CONFIG_RTL8812A
13684 	case RTL8812:
13685 		if (interface_type == RTW_USB)
13686 			addr_offset = EEPROM_MAC_ADDR_8812AU;
13687 		else if (interface_type == RTW_PCIE)
13688 			addr_offset = EEPROM_MAC_ADDR_8812AE;
13689 		break;
13690 #endif
13691 #ifdef CONFIG_RTL8821A
13692 	case RTL8821:
13693 		if (interface_type == RTW_USB)
13694 			addr_offset = EEPROM_MAC_ADDR_8821AU;
13695 		else if (interface_type == RTW_SDIO)
13696 			addr_offset = EEPROM_MAC_ADDR_8821AS;
13697 		else if (interface_type == RTW_PCIE)
13698 			addr_offset = EEPROM_MAC_ADDR_8821AE;
13699 		break;
13700 #endif
13701 #ifdef CONFIG_RTL8192E
13702 	case RTL8192E:
13703 		if (interface_type == RTW_USB)
13704 			addr_offset = EEPROM_MAC_ADDR_8192EU;
13705 		else if (interface_type == RTW_SDIO)
13706 			addr_offset = EEPROM_MAC_ADDR_8192ES;
13707 		else if (interface_type == RTW_PCIE)
13708 			addr_offset = EEPROM_MAC_ADDR_8192EE;
13709 		break;
13710 #endif
13711 #ifdef CONFIG_RTL8814A
13712 	case RTL8814A:
13713 		if (interface_type == RTW_USB)
13714 			addr_offset = EEPROM_MAC_ADDR_8814AU;
13715 		else if (interface_type == RTW_PCIE)
13716 			addr_offset = EEPROM_MAC_ADDR_8814AE;
13717 		break;
13718 #endif
13719 
13720 #ifdef CONFIG_RTL8822B
13721 	case RTL8822B:
13722 		if (interface_type == RTW_USB)
13723 			addr_offset = EEPROM_MAC_ADDR_8822BU;
13724 		else if (interface_type == RTW_SDIO)
13725 			addr_offset = EEPROM_MAC_ADDR_8822BS;
13726 		else if (interface_type == RTW_PCIE)
13727 			addr_offset = EEPROM_MAC_ADDR_8822BE;
13728 		break;
13729 #endif /* CONFIG_RTL8822B */
13730 
13731 #ifdef CONFIG_RTL8821C
13732 	case RTL8821C:
13733 		if (interface_type == RTW_USB)
13734 			addr_offset = EEPROM_MAC_ADDR_8821CU;
13735 		else if (interface_type == RTW_SDIO)
13736 			addr_offset = EEPROM_MAC_ADDR_8821CS;
13737 		else if (interface_type == RTW_PCIE)
13738 			addr_offset = EEPROM_MAC_ADDR_8821CE;
13739 		break;
13740 #endif /* CONFIG_RTL8821C */
13741 
13742 #ifdef CONFIG_RTL8710B
13743 	case RTL8710B:
13744 		if (interface_type == RTW_USB)
13745 			addr_offset = EEPROM_MAC_ADDR_8710B;
13746 		break;
13747 #endif
13748 
13749 #ifdef CONFIG_RTL8192F
13750 	case RTL8192F:
13751 		if (interface_type == RTW_USB)
13752 			addr_offset = EEPROM_MAC_ADDR_8192FU;
13753 		else if (interface_type == RTW_SDIO)
13754 			addr_offset = EEPROM_MAC_ADDR_8192FS;
13755 		else if (interface_type == RTW_PCIE)
13756 			addr_offset = EEPROM_MAC_ADDR_8192FE;
13757 		break;
13758 #endif /* CONFIG_RTL8192F */
13759 
13760 #ifdef CONFIG_RTL8822C
13761 	case RTL8822C:
13762 		if (interface_type == RTW_USB)
13763 			addr_offset = EEPROM_MAC_ADDR_8822CU;
13764 		else if (interface_type == RTW_SDIO)
13765 			addr_offset = EEPROM_MAC_ADDR_8822CS;
13766 		else if (interface_type == RTW_PCIE)
13767 			addr_offset = EEPROM_MAC_ADDR_8822CE;
13768 		break;
13769 #endif /* CONFIG_RTL8822C */
13770 
13771 #ifdef CONFIG_RTL8814B
13772 	case RTL8814B:
13773 		if (interface_type == RTW_USB)
13774 			addr_offset = EEPROM_MAC_ADDR_8814BU;
13775 		else if (interface_type == RTW_PCIE)
13776 			addr_offset = EEPROM_MAC_ADDR_8814BE;
13777 		break;
13778 #endif /* CONFIG_RTL8814B */
13779 	}
13780 
13781 	if (addr_offset == -1) {
13782 		RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
13783 			, __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
13784 	}
13785 
13786 	return addr_offset;
13787 }
13788 
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)13789 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
13790 {
13791 	int ret = _FAIL;
13792 	int addr_offset;
13793 
13794 	addr_offset = hal_efuse_macaddr_offset(padapter);
13795 	if (addr_offset == -1)
13796 		goto exit;
13797 
13798 	ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
13799 
13800 exit:
13801 	return ret;
13802 }
13803 
rtw_dump_cur_efuse(PADAPTER padapter)13804 void rtw_dump_cur_efuse(PADAPTER padapter)
13805 {
13806 	int mapsize =0;
13807 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13808 
13809 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
13810 
13811 	if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
13812 		RTW_ERR("wrong map size %d\n", mapsize);
13813 		return;
13814 	}
13815 
13816 #ifdef CONFIG_RTW_DEBUG
13817 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13818 		RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);
13819 	else
13820 		RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);
13821 #endif
13822 }
13823 
13824 
13825 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)13826 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
13827 {
13828 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13829 	u32 ret = _FALSE;
13830 	u32 maplen = 0;
13831 
13832 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
13833 
13834 	if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
13835 		RTW_ERR("eFuse length error :%d\n", maplen);
13836 		return _FALSE;
13837 	}
13838 
13839 	ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
13840 
13841 	hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
13842 
13843 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13844 		rtw_dump_cur_efuse(padapter);
13845 
13846 	return ret;
13847 }
13848 
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)13849 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
13850 {
13851 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13852 	u32 ret = _FAIL;
13853 
13854 	if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
13855 		&& rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
13856 	) {
13857 		hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
13858 		ret = _SUCCESS;
13859 	} else
13860 		hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
13861 
13862 	return ret;
13863 }
13864 #endif /* CONFIG_EFUSE_CONFIG_FILE */
13865 
hal_config_macaddr(_adapter * adapter,bool autoload_fail)13866 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
13867 {
13868 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13869 	u8 addr[ETH_ALEN];
13870 	int addr_offset = hal_efuse_macaddr_offset(adapter);
13871 	u8 *hw_addr = NULL;
13872 	int ret = _SUCCESS;
13873 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
13874 	u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */
13875 #endif
13876 
13877 	if (autoload_fail)
13878 		goto bypass_hw_pg;
13879 
13880 	if (addr_offset != -1)
13881 		hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
13882 
13883 #ifdef CONFIG_EFUSE_CONFIG_FILE
13884 	/* if the hw_addr is written by efuse file, set to NULL */
13885 	if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13886 		hw_addr = NULL;
13887 #endif
13888 
13889 	if (!hw_addr) {
13890 		/* try getting hw pg data */
13891 		if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
13892 			hw_addr = addr;
13893 	}
13894 
13895 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
13896 	if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))
13897 		hw_addr[0] = 0xff;
13898 #endif
13899 
13900 	/* check hw pg data */
13901 	if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
13902 		_rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
13903 		goto exit;
13904 	}
13905 
13906 bypass_hw_pg:
13907 
13908 #ifdef CONFIG_EFUSE_CONFIG_FILE
13909 	/* check wifi mac file */
13910 	if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
13911 		_rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
13912 		goto exit;
13913 	}
13914 #endif
13915 
13916 	_rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
13917 	ret = _FAIL;
13918 
13919 exit:
13920 	return ret;
13921 }
13922 
13923 #ifdef CONFIG_RF_POWER_TRIM
13924 u32 Array_kfreemap[] = {
13925 	0x08, 0xe,
13926 	0x06, 0xc,
13927 	0x04, 0xa,
13928 	0x02, 0x8,
13929 	0x00, 0x6,
13930 	0x03, 0x4,
13931 	0x05, 0x2,
13932 	0x07, 0x0,
13933 	0x09, 0x0,
13934 	0x0c, 0x0,
13935 };
13936 
rtw_bb_rf_gain_offset(_adapter * padapter)13937 void rtw_bb_rf_gain_offset(_adapter *padapter)
13938 {
13939 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
13940 	struct registry_priv  *registry_par = &padapter->registrypriv;
13941 	struct kfree_data_t *kfree_data = &pHalData->kfree_data;
13942 	u8		value = pHalData->EEPROMRFGainOffset;
13943 	u8		tmp = 0x3e;
13944 	u32		res, i = 0;
13945 	u32		ArrayLen	= sizeof(Array_kfreemap) / sizeof(u32);
13946 	u32		*Array = Array_kfreemap;
13947 	u32		v1 = 0, v2 = 0, GainValue = 0, target = 0;
13948 
13949 	if (registry_par->RegPwrTrimEnable == 2) {
13950 		RTW_INFO("Registry kfree default force disable.\n");
13951 		return;
13952 	}
13953 
13954 #if defined(CONFIG_RTL8723B)
13955 	if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
13956 		RTW_INFO("Offset RF Gain.\n");
13957 		RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
13958 
13959 		if (pHalData->EEPROMRFGainVal != 0xff) {
13960 
13961 			if (pHalData->ant_path == RF_PATH_A)
13962 				GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
13963 
13964 			else
13965 				GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
13966 			RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
13967 
13968 			for (i = 0; i < ArrayLen; i += 2) {
13969 				/* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
13970 				v1 = Array[i];
13971 				v2 = Array[i + 1];
13972 				if (v1 == GainValue) {
13973 					RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
13974 					target = v2;
13975 					break;
13976 				}
13977 			}
13978 			RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
13979 
13980 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
13981 			RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
13982 			phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
13983 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
13984 
13985 			RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
13986 
13987 		} else
13988 
13989 			RTW_INFO("Offset RF Gain.  pHalData->EEPROMRFGainVal=0x%x	!= 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
13990 	} else
13991 		RTW_INFO("Using the default RF gain.\n");
13992 
13993 #elif defined(CONFIG_RTL8188E)
13994 	if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
13995 		RTW_INFO("8188ES Offset RF Gain.\n");
13996 		RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
13997 			 pHalData->EEPROMRFGainVal);
13998 
13999 		if (pHalData->EEPROMRFGainVal != 0xff) {
14000 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
14001 					 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
14002 
14003 			RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
14004 			res &= 0xfff87fff;
14005 
14006 			res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
14007 			RTW_INFO("Offset RF Gain. res=0x%x\n", res);
14008 
14009 			rtw_hal_write_rfreg(padapter, RF_PATH_A,
14010 					    REG_RF_BB_GAIN_OFFSET,
14011 					    RF_GAIN_OFFSET_MASK, res);
14012 		} else {
14013 			RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
14014 				 pHalData->EEPROMRFGainVal);
14015 		}
14016 	} else
14017 		RTW_INFO("Using the default RF gain.\n");
14018 #else
14019 	/* TODO: call this when channel switch */
14020 	if (kfree_data->flag & KFREE_FLAG_ON)
14021 		rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
14022 #endif
14023 
14024 }
14025 #endif /*CONFIG_RF_POWER_TRIM */
14026 
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)14027 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
14028 {
14029 #ifdef CONFIG_RF_POWER_TRIM
14030 	int i, j;
14031 
14032 	for (i = 0; i < BB_GAIN_NUM; i++)
14033 		for (j = 0; j < RF_PATH_MAX; j++)
14034 			if (data->bb_gain[i][j] != 0)
14035 				return 0;
14036 #endif
14037 	return 1;
14038 }
14039 
14040 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)14041 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
14042 {
14043 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14044 	if (cur_wireless_mode < WIRELESS_11_24N
14045 	    && cur_wireless_mode > 0) { /* ABG mode */
14046 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14047 		u32 remainder = 0;
14048 		u8 quotient = 0;
14049 
14050 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
14051 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14052 
14053 		if (quotient > 5) {
14054 			pHalData->rxagg_usb_size = 0x6;
14055 			pHalData->rxagg_usb_timeout = 0x10;
14056 		} else {
14057 			if (remainder >= 2048) {
14058 				pHalData->rxagg_usb_size = quotient;
14059 				pHalData->rxagg_usb_timeout = 0x10;
14060 			} else {
14061 				pHalData->rxagg_usb_size = (quotient - 1);
14062 				pHalData->rxagg_usb_timeout = 0x10;
14063 			}
14064 		}
14065 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14066 		if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
14067 			pHalData->rxagg_usb_size = 0x6;
14068 			pHalData->rxagg_usb_timeout = 0x10;
14069 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14070 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14071 		}
14072 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14073 
14074 	} else if (cur_wireless_mode >= WIRELESS_11_24N
14075 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14076 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14077 		u32 remainder = 0;
14078 		u8 quotient = 0;
14079 
14080 		remainder = MAX_RECVBUF_SZ % (4 * 1024);
14081 		quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14082 
14083 		if (quotient > 5) {
14084 			pHalData->rxagg_usb_size = 0x5;
14085 			pHalData->rxagg_usb_timeout = 0x20;
14086 		} else {
14087 			if (remainder >= 2048) {
14088 				pHalData->rxagg_usb_size = quotient;
14089 				pHalData->rxagg_usb_timeout = 0x10;
14090 			} else {
14091 				pHalData->rxagg_usb_size = (quotient - 1);
14092 				pHalData->rxagg_usb_timeout = 0x10;
14093 			}
14094 		}
14095 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14096 		if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
14097 			pHalData->rxagg_usb_size = 0x5;
14098 			pHalData->rxagg_usb_timeout = 0x20;
14099 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14100 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14101 		}
14102 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14103 
14104 	} else {
14105 		/* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14106 	}
14107 }
14108 
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)14109 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
14110 {
14111 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14112 
14113 	if (cur_wireless_mode < WIRELESS_11_24N
14114 	    && cur_wireless_mode > 0) { /* ABG mode */
14115 		if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
14116 		    || 0x10 != pHalData->rxagg_usb_timeout) {
14117 			pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
14118 			pHalData->rxagg_usb_timeout = 0x10;
14119 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14120 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14121 		}
14122 	} else if (cur_wireless_mode >= WIRELESS_11_24N
14123 		   && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14124 		if (UsbDmaSize != pHalData->rxagg_usb_size
14125 		    || 0x20 != pHalData->rxagg_usb_timeout) {
14126 			pHalData->rxagg_usb_size = UsbDmaSize;
14127 			pHalData->rxagg_usb_timeout = 0x20;
14128 			rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14129 				pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14130 		}
14131 	} else {
14132 		/* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14133 	}
14134 }
14135 
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)14136 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
14137 {
14138 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14139 	rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
14140 	return;
14141 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14142 
14143 	rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
14144 }
14145 #endif /* CONFIG_USB_RX_AGGREGATION */
14146 
14147 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)14148 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
14149 {
14150 	struct dvobj_priv	*pdvobjpriv = adapter_to_dvobj(padapter);
14151 	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
14152 	struct registry_priv *registry_par = &padapter->registrypriv;
14153 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
14154 	u8 cur_wireless_mode = WIRELESS_INVALID;
14155 
14156 #ifdef CONFIG_USB_RX_AGGREGATION
14157 	if (!registry_par->dynamic_agg_enable)
14158 		return;
14159 
14160 #ifdef RTW_HALMAC
14161 	if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter)
14162 		|| IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter))
14163 		rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
14164 #else /* !RTW_HALMAC */
14165 	if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
14166 		/* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
14167 		if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) {
14168 			if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14169 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
14170 			else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14171 				rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
14172 			else
14173 				rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
14174 
14175 			/* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
14176 		}
14177 	} else if (IS_HARDWARE_TYPE_8812(padapter)) {
14178 #ifdef CONFIG_CONCURRENT_MODE
14179 		u8 i;
14180 		_adapter *iface;
14181 		u8 bassocaed = _FALSE;
14182 		struct mlme_ext_priv *mlmeext;
14183 
14184 		for (i = 0; i < pdvobjpriv->iface_nums; i++) {
14185 			iface = pdvobjpriv->padapters[i];
14186 			mlmeext = &iface->mlmeextpriv;
14187 			if (rtw_linked_check(iface) == _TRUE) {
14188 				if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
14189 					cur_wireless_mode = mlmeext->cur_wireless_mode;
14190 				bassocaed = _TRUE;
14191 			}
14192 		}
14193 		if (bassocaed)
14194 #endif
14195 			rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14196 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14197 	} else {
14198 		rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14199 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14200 	}
14201 #endif /* RTW_HALMAC */
14202 #endif /* CONFIG_USB_RX_AGGREGATION */
14203 
14204 }
14205 
14206 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)14207 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
14208 {
14209 #ifdef CONFIG_AP_MODE
14210 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
14211 	u8 chk_rst = _SUCCESS;
14212 
14213 	if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
14214 		return chk_rst;
14215 
14216 	/* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
14217 	/*	return chk_rst; */
14218 
14219 	if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
14220 	    && (pre_qsel != next_qsel)) {
14221 		/* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
14222 		/*	pre_qsel,next_qsel); */
14223 		chk_rst = _FAIL;
14224 	}
14225 	return chk_rst;
14226 #else
14227 	return _SUCCESS;
14228 #endif /* CONFIG_AP_MODE */
14229 }
14230 
14231 #ifdef CONFIG_WOWLAN
14232 /*
14233  * Description:
14234  * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
14235  * contant.
14236  *
14237  * Input:
14238  * adapter: adapter pointer.
14239  * page_num: The max. page number that user want to dump.
14240  * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
14241  */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)14242 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
14243 {
14244 
14245 	int i;
14246 	u8 val = 0;
14247 	u8 base = 0;
14248 	u32 addr = 0;
14249 	u32 count = (page_size / 8);
14250 
14251 	if (page_num <= 0) {
14252 		RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
14253 		return;
14254 	}
14255 
14256 	if (page_size < 128 || page_size > 512) {
14257 		RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
14258 		return;
14259 	}
14260 
14261 	RTW_INFO("+%s+\n", __func__);
14262 	val = rtw_read8(padapter, 0x106);
14263 	rtw_write8(padapter, 0x106, 0x69);
14264 	RTW_INFO("0x106: 0x%02x\n", val);
14265 	base = rtw_read8(padapter, 0x209);
14266 	RTW_INFO("0x209: 0x%02x\n", base);
14267 
14268 	addr = ((base)*page_size) / 8;
14269 	for (i = 0 ; i < page_num * count ; i += 2) {
14270 		rtw_write32(padapter, 0x140, addr + i);
14271 		printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14272 		rtw_write32(padapter, 0x140, addr + i + 1);
14273 		printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14274 	}
14275 }
14276 #endif
14277 
14278 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)14279 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
14280 {
14281 	u8 value = 0;
14282 	u8 direction = 0;
14283 	u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
14284 	u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
14285 	u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
14286 	u8 gpio_num_to_set = gpio_num;
14287 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
14288 
14289 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14290 		return value;
14291 
14292 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14293 
14294 	RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
14295 	LeaveAllPowerSaveModeDirect(adapter);
14296 
14297 	if (gpio_num > 7) {
14298 		gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
14299 		gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
14300 		gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
14301 		gpio_num_to_set = gpio_num - 8;
14302 	}
14303 
14304 	/* Read GPIO Direction */
14305 	direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14306 
14307 	/* According the direction to read register value */
14308 	if (direction)
14309 		value =  (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14310 	else
14311 		value =  (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14312 
14313 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14314 	RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
14315 
14316 	return value;
14317 }
14318 
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)14319 int  rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
14320 {
14321 	u8 direction = 0;
14322 	u8 res = -1;
14323 	u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
14324 	u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
14325 	u8 gpio_num_to_set = gpio_num;
14326 
14327 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14328 		return -1;
14329 
14330 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14331 
14332 	LeaveAllPowerSaveModeDirect(adapter);
14333 
14334 	if (gpio_num > 7) {
14335 		gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
14336 		gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
14337 		gpio_num_to_set = gpio_num - 8;
14338 	}
14339 
14340 	/* Read GPIO direction */
14341 	direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14342 
14343 	/* If GPIO is output direction, setting value. */
14344 	if (direction) {
14345 		if (isHigh)
14346 			rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
14347 		else
14348 			rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
14349 
14350 		RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
14351 		res = 0;
14352 	} else {
14353 		RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
14354 		res = -1;
14355 	}
14356 
14357 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14358 	return res;
14359 }
14360 
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)14361 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
14362 {
14363 	u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
14364 	u8 gpio_num_to_set = gpio_num;
14365 
14366 	if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14367 		return -1;
14368 
14369 	RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
14370 
14371 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14372 
14373 	LeaveAllPowerSaveModeDirect(adapter);
14374 
14375 	rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
14376 
14377 	if (gpio_num > 7) {
14378 		gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
14379 		gpio_num_to_set = gpio_num - 8;
14380 	}
14381 
14382 	if (isOutput)
14383 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
14384 	else
14385 		rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
14386 
14387 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14388 
14389 	return 0;
14390 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))14391 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
14392 {
14393 	u8 value;
14394 	u8 direction;
14395 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
14396 
14397 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
14398 		if (gpio_num > 7 || gpio_num < 4) {
14399 			RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
14400 			return -1;
14401 		}
14402 	}
14403 
14404 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14405 
14406 	LeaveAllPowerSaveModeDirect(adapter);
14407 
14408 	/* Read GPIO direction */
14409 	direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
14410 	if (direction) {
14411 		RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
14412 		return -1;
14413 	}
14414 
14415 	/* Config GPIO Mode */
14416 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
14417 
14418 	/* Register GPIO interrupt handler*/
14419 	adapter->gpiointpriv.callback[gpio_num] = callback;
14420 
14421 	/* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
14422 	value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
14423 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
14424 	rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
14425 
14426 	/* Enable GPIO interrupt */
14427 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
14428 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
14429 
14430 	rtw_hal_update_hisr_hsisr_ind(adapter, 1);
14431 
14432 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14433 
14434 	return 0;
14435 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)14436 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
14437 {
14438 	u8 value;
14439 	u8 direction;
14440 	PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
14441 
14442 	if (IS_HARDWARE_TYPE_8188E(adapter)) {
14443 		if (gpio_num > 7 || gpio_num < 4) {
14444 			RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
14445 			return -1;
14446 		}
14447 	}
14448 
14449 	rtw_ps_deny(adapter, PS_DENY_IOCTL);
14450 
14451 	LeaveAllPowerSaveModeDirect(adapter);
14452 
14453 	/* Config GPIO Mode */
14454 	rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
14455 
14456 	/* Unregister GPIO interrupt handler*/
14457 	adapter->gpiointpriv.callback[gpio_num] = NULL;
14458 
14459 	/* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
14460 	adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
14461 	rtw_write8(adapter, REG_GPIO_INTM, 0x00);
14462 
14463 	/* Disable GPIO interrupt */
14464 	adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
14465 	rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
14466 
14467 	if (!adapter->gpiointpriv.interrupt_enable_mask)
14468 		rtw_hal_update_hisr_hsisr_ind(adapter, 0);
14469 
14470 	rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14471 
14472 	return 0;
14473 }
14474 #endif
14475 
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)14476 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
14477 {
14478 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14479 	u8 i;
14480 
14481 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
14482 		if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
14483 			if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
14484 			    && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
14485 				return i;
14486 		}
14487 	}
14488 
14489 	return -1;
14490 }
14491 
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)14492 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
14493 {
14494 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14495 	s8 res;
14496 	u8 i;
14497 
14498 	/* If it's an existed record, overwrite it */
14499 	res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
14500 	if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
14501 		rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
14502 		return;
14503 	}
14504 
14505 	/* Search for the empty record to use */
14506 	for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
14507 		if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
14508 			rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
14509 			return;
14510 		}
14511 	}
14512 
14513 	/* Else, overwrite the oldest record */
14514 	for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
14515 		_rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
14516 
14517 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
14518 }
14519 
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)14520 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
14521 {
14522 	rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
14523 }
14524 
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14525 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14526 {
14527 	u32	mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
14528 	u32	mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
14529 	u32	mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
14530 	u32	DropPacket = 0;
14531 
14532 	if (!rx_counter) {
14533 		rtw_warn_on(1);
14534 		return;
14535 	}
14536 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
14537 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14538 
14539 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
14540 	mac_cck_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	  */
14541 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
14542 	mac_ofdm_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14543 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
14544 	mac_ht_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14545 	mac_vht_ok	= 0;
14546 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14547 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
14548 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
14549 		mac_vht_ok	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
14550 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14551 	}
14552 
14553 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
14554 	mac_cck_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14555 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
14556 	mac_ofdm_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14557 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
14558 	mac_ht_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
14559 	mac_vht_err	= 0;
14560 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14561 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
14562 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
14563 		mac_vht_err	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
14564 		phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14565 	}
14566 
14567 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
14568 	mac_cck_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14569 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
14570 	mac_ofdm_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]	 */
14571 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
14572 	mac_ht_fa	= phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]		 */
14573 
14574 	/* Mac_DropPacket */
14575 	rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
14576 	DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
14577 
14578 	rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
14579 	rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
14580 	rx_counter->rx_cck_fa = mac_cck_fa;
14581 	rx_counter->rx_ofdm_fa = mac_ofdm_fa;
14582 	rx_counter->rx_ht_fa = mac_ht_fa;
14583 	rx_counter->rx_pkt_drop = DropPacket;
14584 }
rtw_reset_mac_rx_counters(_adapter * padapter)14585 void rtw_reset_mac_rx_counters(_adapter *padapter)
14586 {
14587 
14588 	/* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
14589 	if (IS_HARDWARE_TYPE_8703B(padapter) ||
14590 		IS_HARDWARE_TYPE_8723D(padapter) ||
14591 		IS_HARDWARE_TYPE_8188F(padapter) ||
14592 		IS_HARDWARE_TYPE_8188GTV(padapter) ||
14593 		IS_HARDWARE_TYPE_8192F(padapter) ||
14594 		IS_HARDWARE_TYPE_8822C(padapter))
14595 		phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
14596 
14597 	/* reset mac counter */
14598 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
14599 	phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
14600 }
14601 
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14602 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14603 {
14604 	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;
14605 	if (!rx_counter) {
14606 		rtw_warn_on(1);
14607 		return;
14608 	}
14609 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14610 		cckok	= phy_query_bb_reg(padapter, 0xF04, 0x3FFF);	     /* [13:0] */
14611 		ofdmok	= phy_query_bb_reg(padapter, 0xF14, 0x3FFF);	     /* [13:0] */
14612 		htok		= phy_query_bb_reg(padapter, 0xF10, 0x3FFF);     /* [13:0] */
14613 		vht_ok	= phy_query_bb_reg(padapter, 0xF0C, 0x3FFF);     /* [13:0] */
14614 		cckcrc	= phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16]	 */
14615 		ofdmcrc	= phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
14616 		htcrc	= phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
14617 		vht_err	= phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
14618 		CCK_FA	= phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
14619 		OFDM_FA	= phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
14620 	} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)){
14621 		cckok = phy_query_bb_reg(padapter, 0x2c04, 0xffff);
14622 		ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
14623 		htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
14624 		vht_ok = phy_query_bb_reg(padapter, 0x2c0c, 0xffff);
14625 		cckcrc = phy_query_bb_reg(padapter, 0x2c04, 0xffff0000);
14626 		ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
14627 		htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
14628 		vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000);
14629 		CCK_FA	= phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord);
14630 		OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
14631 
14632 	} else {
14633 		cckok	= phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
14634 		ofdmok	= phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
14635 		htok		= phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
14636 		vht_ok	= 0;
14637 		cckcrc	= phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
14638 		ofdmcrc	= phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
14639 		htcrc	= phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
14640 		vht_err	= 0;
14641 		OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +
14642 			phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
14643 			phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
14644 
14645 		CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
14646 	}
14647 
14648 	rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
14649 	rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
14650 	rx_counter->rx_ofdm_fa = OFDM_FA;
14651 	rx_counter->rx_cck_fa = CCK_FA;
14652 
14653 }
14654 
rtw_reset_phy_trx_ok_counters(_adapter * padapter)14655 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
14656 {
14657 	if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14658 		phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
14659 		phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
14660 	} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
14661 		phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1);
14662 		phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0);
14663 	} else {
14664 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
14665 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
14666 	}
14667 }
14668 
rtw_reset_phy_rx_counters(_adapter * padapter)14669 void rtw_reset_phy_rx_counters(_adapter *padapter)
14670 {
14671 	/* reset phy counter */
14672 	if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
14673 		/* reset CCK FA counter */
14674 		phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 0);
14675 		phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 2);
14676 
14677 		/* reset CCK CCA counter */
14678 		phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0);
14679 		phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2);
14680 		rtw_reset_phy_trx_ok_counters(padapter);
14681 
14682 	} else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14683 		rtw_reset_phy_trx_ok_counters(padapter);
14684 
14685 		phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset  OFDA FA counter */
14686 		phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
14687 
14688 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
14689 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
14690 	} else {
14691 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
14692 		rtw_msleep_os(10);
14693 		phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
14694 
14695 		phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset  OFDA FA counter */
14696 		phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset  OFDA FA counter */
14697 		phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
14698 		phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
14699 
14700 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset  CCK FA counter */
14701 		phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
14702 	}
14703 }
14704 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14705 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14706 {
14707 	struct recv_priv *precvpriv = &padapter->recvpriv;
14708 	if (!rx_counter) {
14709 		rtw_warn_on(1);
14710 		return;
14711 	}
14712 	rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
14713 	rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
14714 	rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
14715 }
rtw_reset_drv_rx_counters(_adapter * padapter)14716 void rtw_reset_drv_rx_counters(_adapter *padapter)
14717 {
14718 	struct recv_priv *precvpriv = &padapter->recvpriv;
14719 	padapter->drv_rx_cnt_ok = 0;
14720 	padapter->drv_rx_cnt_crcerror = 0;
14721 	padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
14722 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)14723 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
14724 {
14725 	u8 initialgain;
14726 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14727 
14728 	if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
14729 		rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
14730 		RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
14731 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
14732 		/*disable dynamic functions, such as high power, DIG*/
14733 		rtw_phydm_ability_backup(padapter);
14734 		rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
14735 	} else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
14736 		/* turn on phy-dynamic functions */
14737 		rtw_phydm_ability_restore(padapter);
14738 		initialgain = 0xff; /* restore RX GAIN */
14739 		rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
14740 
14741 	}
14742 }
14743 
rtw_dump_rx_counters(_adapter * padapter)14744 void rtw_dump_rx_counters(_adapter *padapter)
14745 {
14746 	struct dbg_rx_counter rx_counter;
14747 
14748 	if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
14749 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14750 		rtw_dump_drv_rx_counters(padapter, &rx_counter);
14751 		RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
14752 			rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
14753 		rtw_reset_drv_rx_counters(padapter);
14754 	}
14755 
14756 	if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
14757 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14758 		rtw_dump_mac_rx_counters(padapter, &rx_counter);
14759 		RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
14760 			 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
14761 			rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
14762 			 rx_counter.rx_pkt_drop);
14763 		rtw_reset_mac_rx_counters(padapter);
14764 	}
14765 
14766 	if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
14767 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14768 		rtw_dump_phy_rx_counters(padapter, &rx_counter);
14769 		/* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
14770 		/* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
14771 		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,
14772 			 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
14773 		rtw_reset_phy_rx_counters(padapter);
14774 	}
14775 }
14776 #endif
rtw_get_current_tx_sgi(_adapter * padapter,struct sta_info * psta)14777 u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
14778 {
14779 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14780 	u8 curr_tx_sgi = 0;
14781 	struct ra_sta_info *ra_info;
14782 
14783 	if (!psta)
14784 		return curr_tx_sgi;
14785 
14786 	if (padapter->fix_rate == 0xff) {
14787 #if defined(CONFIG_RTL8188E)
14788 #if (RATE_ADAPTIVE_SUPPORT == 1)
14789 		curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;
14790 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
14791 #else
14792 		ra_info = &psta->cmn.ra_info;
14793 		curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
14794 #endif
14795 	} else {
14796 		curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;
14797 	}
14798 
14799 	return curr_tx_sgi;
14800 }
14801 
rtw_get_current_tx_rate(_adapter * padapter,struct sta_info * psta)14802 u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
14803 {
14804 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14805 	u8 rate_id = 0;
14806 	struct ra_sta_info *ra_info;
14807 
14808 	if (!psta)
14809 		return rate_id;
14810 
14811 	if (padapter->fix_rate == 0xff) {
14812 #if defined(CONFIG_RTL8188E)
14813 #if (RATE_ADAPTIVE_SUPPORT == 1)
14814 		rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;
14815 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
14816 #else
14817 		ra_info = &psta->cmn.ra_info;
14818 		rate_id = ra_info->curr_tx_rate & 0x7f;
14819 #endif
14820 	} else {
14821 		rate_id = padapter->fix_rate & 0x7f;
14822 	}
14823 
14824 	return rate_id;
14825 }
14826 
update_IOT_info(_adapter * padapter)14827 void update_IOT_info(_adapter *padapter)
14828 {
14829 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
14830 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14831 
14832 	switch (pmlmeinfo->assoc_AP_vendor) {
14833 	case HT_IOT_PEER_MARVELL:
14834 		pmlmeinfo->turboMode_cts2self = 1;
14835 		pmlmeinfo->turboMode_rtsen = 0;
14836 		break;
14837 
14838 	case HT_IOT_PEER_RALINK:
14839 		pmlmeinfo->turboMode_cts2self = 0;
14840 		pmlmeinfo->turboMode_rtsen = 1;
14841 		break;
14842 	case HT_IOT_PEER_REALTEK:
14843 		/* rtw_write16(padapter, 0x4cc, 0xffff); */
14844 		/* rtw_write16(padapter, 0x546, 0x01c0); */
14845 		break;
14846 	default:
14847 		pmlmeinfo->turboMode_cts2self = 0;
14848 		pmlmeinfo->turboMode_rtsen = 1;
14849 		break;
14850 	}
14851 
14852 }
14853 #ifdef CONFIG_RTS_FULL_BW
14854 /*
14855 8188E: not support full RTS BW feature(mac REG no define 480[5])
14856 */
rtw_set_rts_bw(_adapter * padapter)14857 void rtw_set_rts_bw(_adapter *padapter) {
14858 	int i;
14859 	u8 enable = 1;
14860 	bool connect_to_8812 = _FALSE;
14861 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14862 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14863 	struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
14864 	struct sta_info *station = NULL;
14865 
14866 	for (i = 0; i < macid_ctl->num; i++) {
14867 		if (rtw_macid_is_used(macid_ctl, i)) {
14868 
14869 			station = NULL;
14870 			station = macid_ctl->sta[i];
14871 			if(station) {
14872 
14873 				 _adapter *sta_adapter =station->padapter;
14874 				struct mlme_ext_priv	*pmlmeext = &(sta_adapter->mlmeextpriv);
14875 				struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14876 
14877 				if ( pmlmeinfo->state != WIFI_FW_NULL_STATE) {
14878 					if(_rtw_memcmp(macid_ctl->sta[i]->cmn.mac_addr, bc_addr, ETH_ALEN) !=  _TRUE) {
14879 						if (  macid_ctl->sta[i]->vendor_8812) {
14880 							connect_to_8812 = _TRUE;
14881 							enable = 0;
14882 						}
14883 					}
14884 				}
14885 			}
14886 		}
14887 
14888 		if(connect_to_8812)
14889 			break;
14890 	}
14891 
14892 		RTW_INFO("%s connect_to_8812=%d,enable=%u\n", __FUNCTION__,connect_to_8812,enable);
14893 		rtw_hal_set_hwreg(padapter, HW_VAR_SET_RTS_BW, &enable);
14894 }
14895 #endif/*CONFIG_RTS_FULL_BW*/
14896 
hal_spec_init(_adapter * adapter)14897 int hal_spec_init(_adapter *adapter)
14898 {
14899 	u8 interface_type = 0;
14900 	int ret = _SUCCESS;
14901 
14902 	interface_type = rtw_get_intf_type(adapter);
14903 
14904 	switch (rtw_get_chip_type(adapter)) {
14905 #ifdef CONFIG_RTL8723B
14906 	case RTL8723B:
14907 		init_hal_spec_8723b(adapter);
14908 		break;
14909 #endif
14910 #ifdef CONFIG_RTL8703B
14911 	case RTL8703B:
14912 		init_hal_spec_8703b(adapter);
14913 		break;
14914 #endif
14915 #ifdef CONFIG_RTL8723D
14916 	case RTL8723D:
14917 		init_hal_spec_8723d(adapter);
14918 		break;
14919 #endif
14920 #ifdef CONFIG_RTL8188E
14921 	case RTL8188E:
14922 		init_hal_spec_8188e(adapter);
14923 		break;
14924 #endif
14925 #ifdef CONFIG_RTL8188F
14926 	case RTL8188F:
14927 		init_hal_spec_8188f(adapter);
14928 		break;
14929 #endif
14930 #ifdef CONFIG_RTL8188GTV
14931 	case RTL8188GTV:
14932 		init_hal_spec_8188gtv(adapter);
14933 		break;
14934 #endif
14935 #ifdef CONFIG_RTL8812A
14936 	case RTL8812:
14937 		init_hal_spec_8812a(adapter);
14938 		break;
14939 #endif
14940 #ifdef CONFIG_RTL8821A
14941 	case RTL8821:
14942 		init_hal_spec_8821a(adapter);
14943 		break;
14944 #endif
14945 #ifdef CONFIG_RTL8192E
14946 	case RTL8192E:
14947 		init_hal_spec_8192e(adapter);
14948 		break;
14949 #endif
14950 #ifdef CONFIG_RTL8814A
14951 	case RTL8814A:
14952 		init_hal_spec_8814a(adapter);
14953 		break;
14954 #endif
14955 #ifdef CONFIG_RTL8822B
14956 	case RTL8822B:
14957 		rtl8822b_init_hal_spec(adapter);
14958 		break;
14959 #endif
14960 #ifdef CONFIG_RTL8821C
14961 	case RTL8821C:
14962 		init_hal_spec_rtl8821c(adapter);
14963 		break;
14964 #endif
14965 #ifdef CONFIG_RTL8710B
14966 	case RTL8710B:
14967 		init_hal_spec_8710b(adapter);
14968 		break;
14969 #endif
14970 #ifdef CONFIG_RTL8192F
14971 	case RTL8192F:
14972 		init_hal_spec_8192f(adapter);
14973 		break;
14974 #endif
14975 #ifdef CONFIG_RTL8822C
14976 	case RTL8822C:
14977 		rtl8822c_init_hal_spec(adapter);
14978 		break;
14979 #endif
14980 #ifdef CONFIG_RTL8814B
14981 	case RTL8814B:
14982 		rtl8814b_init_hal_spec(adapter);
14983 		break;
14984 #endif
14985 	default:
14986 		RTW_ERR("%s: unknown chip_type:%u\n"
14987 			, __func__, rtw_get_chip_type(adapter));
14988 		ret = _FAIL;
14989 		break;
14990 	}
14991 
14992 	return ret;
14993 }
14994 
14995 static const char *const _band_cap_str[] = {
14996 	/* BIT0 */"2G",
14997 	/* BIT1 */"5G",
14998 };
14999 
15000 static const char *const _bw_cap_str[] = {
15001 	/* BIT0 */"5M",
15002 	/* BIT1 */"10M",
15003 	/* BIT2 */"20M",
15004 	/* BIT3 */"40M",
15005 	/* BIT4 */"80M",
15006 	/* BIT5 */"160M",
15007 	/* BIT6 */"80_80M",
15008 };
15009 
15010 static const char *const _proto_cap_str[] = {
15011 	/* BIT0 */"b",
15012 	/* BIT1 */"g",
15013 	/* BIT2 */"n",
15014 	/* BIT3 */"ac",
15015 };
15016 
15017 static const char *const _wl_func_str[] = {
15018 	/* BIT0 */"P2P",
15019 	/* BIT1 */"MIRACAST",
15020 	/* BIT2 */"TDLS",
15021 	/* BIT3 */"FTM",
15022 };
15023 
dump_hal_spec(void * sel,_adapter * adapter)15024 void dump_hal_spec(void *sel, _adapter *adapter)
15025 {
15026 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15027 	int i;
15028 
15029 	RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
15030 	RTW_PRINT_SEL(sel, "macid_cap:%u\n", hal_spec->macid_cap);
15031 	RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
15032 	RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
15033 
15034 	RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
15035 	RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
15036 	RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num);
15037 	RTW_PRINT_SEL(sel, "rf_reg_path_avail_num:%u\n", hal_spec->rf_reg_path_avail_num);
15038 	RTW_PRINT_SEL(sel, "rf_reg_trx_path_bmp:0x%02x\n", hal_spec->rf_reg_trx_path_bmp);
15039 	RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
15040 
15041 	RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
15042 	RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
15043 
15044 	RTW_PRINT_SEL(sel, "band_cap:");
15045 	for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
15046 		if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
15047 			_RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
15048 	}
15049 	_RTW_PRINT_SEL(sel, "\n");
15050 
15051 	RTW_PRINT_SEL(sel, "bw_cap:");
15052 	for (i = 0; i < BW_CAP_BIT_NUM; i++) {
15053 		if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
15054 			_RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
15055 	}
15056 	_RTW_PRINT_SEL(sel, "\n");
15057 
15058 	RTW_PRINT_SEL(sel, "proto_cap:");
15059 	for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
15060 		if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
15061 			_RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
15062 	}
15063 	_RTW_PRINT_SEL(sel, "\n");
15064 
15065 	RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);
15066 	RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);
15067 
15068 	RTW_PRINT_SEL(sel, "wl_func:");
15069 	for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
15070 		if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
15071 			_RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
15072 	}
15073 	_RTW_PRINT_SEL(sel, "\n");
15074 
15075 #if CONFIG_TX_AC_LIFETIME
15076 	RTW_PRINT_SEL(sel, "tx_aclt_unit_factor:%u (unit:%uus)\n"
15077 		, hal_spec->tx_aclt_unit_factor, hal_spec->tx_aclt_unit_factor * 32);
15078 #endif
15079 
15080 	RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);
15081 
15082 	RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);
15083 	RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);
15084 }
15085 
hal_chk_band_cap(_adapter * adapter,u8 cap)15086 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
15087 {
15088 	return GET_HAL_SPEC(adapter)->band_cap & cap;
15089 }
15090 
hal_chk_bw_cap(_adapter * adapter,u8 cap)15091 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
15092 {
15093 	return GET_HAL_SPEC(adapter)->bw_cap & cap;
15094 }
15095 
hal_chk_proto_cap(_adapter * adapter,u8 cap)15096 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
15097 {
15098 	return GET_HAL_SPEC(adapter)->proto_cap & cap;
15099 }
15100 
hal_chk_wl_func(_adapter * adapter,u8 func)15101 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
15102 {
15103 	return GET_HAL_SPEC(adapter)->wl_func & func;
15104 }
15105 
hal_is_band_support(_adapter * adapter,u8 band)15106 inline bool hal_is_band_support(_adapter *adapter, u8 band)
15107 {
15108 	return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
15109 }
15110 
hal_is_bw_support(_adapter * adapter,u8 bw)15111 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
15112 {
15113 	return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
15114 }
15115 
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)15116 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
15117 {
15118 	u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
15119 
15120 	if (mode == WIRELESS_11B)
15121 		if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15122 			return 1;
15123 
15124 	if (mode == WIRELESS_11G)
15125 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15126 			return 1;
15127 
15128 	if (mode == WIRELESS_11A)
15129 		if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15130 			return 1;
15131 
15132 	if (mode == WIRELESS_11_24N)
15133 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15134 			return 1;
15135 
15136 	if (mode == WIRELESS_11_5N)
15137 		if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15138 			return 1;
15139 
15140 	if (mode == WIRELESS_11AC)
15141 		if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15142 			return 1;
15143 
15144 	return 0;
15145 }
hal_is_mimo_support(_adapter * adapter)15146 inline bool hal_is_mimo_support(_adapter *adapter)
15147 {
15148 	if ((GET_HAL_TX_NSS(adapter) == 1) &&
15149 		(GET_HAL_RX_NSS(adapter) == 1))
15150 		return 0;
15151 	return 1;
15152 }
15153 
15154 /*
15155 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
15156 * @adapter:
15157 * @in_bw: starting bw, value of enum channel_width
15158 *
15159 * Returns: value of enum channel_width
15160 */
hal_largest_bw(_adapter * adapter,u8 in_bw)15161 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
15162 {
15163 	for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
15164 		if (hal_is_bw_support(adapter, in_bw))
15165 			break;
15166 	}
15167 
15168 	if (!hal_is_bw_support(adapter, in_bw))
15169 		rtw_warn_on(1);
15170 
15171 	return in_bw;
15172 }
15173 
15174 #ifndef CONFIG_HAS_TX_BEACON_PAUSE
ResumeTxBeacon(_adapter * padapter)15175 void ResumeTxBeacon(_adapter *padapter)
15176 {
15177 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15178 		rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
15179 
15180 #ifdef RTW_HALMAC
15181 	/* Add this for driver using HALMAC because driver doesn't have setup time init by self */
15182 	/* TBTT setup time */
15183 	rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
15184 #endif
15185 
15186 	/* TBTT hold time: 0x540[19:8] */
15187 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
15188 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15189 		(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
15190 }
15191 
StopTxBeacon(_adapter * padapter)15192 void StopTxBeacon(_adapter *padapter)
15193 {
15194 	rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15195 		rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
15196 
15197 	/* TBTT hold time: 0x540[19:8] */
15198 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
15199 	rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15200 		(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
15201 }
15202 #endif /* CONFIG_HAS_TX_BEACON_PAUSE */
15203 
15204 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
15205 
15206 #ifdef CONFIG_CLIENT_PORT_CFG
15207 const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {
15208 	CLT_PORT0,
15209 	CLT_PORT1,
15210 	CLT_PORT2,
15211 	CLT_PORT3
15212 };
15213 
rtw_clt_port_init(struct clt_port_t * cltp)15214 void rtw_clt_port_init(struct clt_port_t  *cltp)
15215 {
15216 	cltp->bmp = 0;
15217 	cltp->num = 0;
15218 	_rtw_spinlock_init(&cltp->lock);
15219 }
rtw_clt_port_deinit(struct clt_port_t * cltp)15220 void rtw_clt_port_deinit(struct clt_port_t *cltp)
15221 {
15222 	_rtw_spinlock_free(&cltp->lock);
15223 }
_hw_client_port_alloc(_adapter * adapter)15224 static void _hw_client_port_alloc(_adapter *adapter)
15225 {
15226 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15227 	struct clt_port_t  *cltp = &dvobj->clt_port;
15228 	_irqL irql;
15229 	int i;
15230 
15231 	#if 0
15232 	if (cltp->num > MAX_CLIENT_PORT_NUM) {
15233 		RTW_ERR(ADPT_FMT" cann't  alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);
15234 		rtw_warn_on(1);
15235 		return;
15236 	}
15237 	#endif
15238 
15239 	if (adapter->client_id !=  MAX_CLIENT_PORT_NUM) {
15240 		RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",
15241 			ADPT_ARG(adapter), adapter->client_id, adapter->client_port);
15242 		return;
15243 	}
15244 	_enter_critical_bh(&cltp->lock, &irql);
15245 	for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {
15246 		if (!(cltp->bmp & BIT(i)))
15247 			break;
15248 	}
15249 
15250 	if (i < MAX_CLIENT_PORT_NUM) {
15251 		adapter->client_id = i;
15252 		cltp->bmp |= BIT(i);
15253 		adapter->client_port = _clt_port_id[i];
15254 	}
15255 	cltp->num++;
15256 	_exit_critical_bh(&cltp->lock, &irql);
15257 	RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",
15258 		__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
15259 }
_hw_client_port_free(_adapter * adapter)15260 static void _hw_client_port_free(_adapter *adapter)
15261 {
15262 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15263 	struct clt_port_t  *cltp = &dvobj->clt_port;
15264 	_irqL irql;
15265 
15266 	#if 0
15267 	if (adapter->client_id >=  MAX_CLIENT_PORT_NUM) {
15268 		RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);
15269 		/*rtw_warn_on(1);*/
15270 	}
15271 	#endif
15272 
15273 	RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",
15274 		__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
15275 
15276 	_enter_critical_bh(&cltp->lock, &irql);
15277 	if (adapter->client_id !=  MAX_CLIENT_PORT_NUM) {
15278 		cltp->bmp &= ~ BIT(adapter->client_id);
15279 		adapter->client_id = MAX_CLIENT_PORT_NUM;
15280 		adapter->client_port = CLT_PORT_INVALID;
15281 	}
15282 	cltp->num--;
15283 	if (cltp->num < 0)
15284 		cltp->num = 0;
15285 	_exit_critical_bh(&cltp->lock, &irql);
15286 }
rtw_hw_client_port_allocate(_adapter * adapter)15287 void rtw_hw_client_port_allocate(_adapter *adapter)
15288 {
15289 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15290 
15291 	if (hal_spec->port_num != 5)
15292 		return;
15293 
15294 	_hw_client_port_alloc(adapter);
15295 }
rtw_hw_client_port_release(_adapter * adapter)15296 void rtw_hw_client_port_release(_adapter *adapter)
15297 {
15298 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15299 
15300 	if (hal_spec->port_num != 5)
15301 		return;
15302 
15303 	_hw_client_port_free(adapter);
15304 }
15305 #endif /*CONFIG_CLIENT_PORT_CFG*/
15306 
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)15307 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
15308 {
15309 	RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
15310 
15311 	rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
15312 
15313 	/* set net_type */
15314 	Set_MSR(Adapter, mode);
15315 
15316 	if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
15317 		if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
15318 			StopTxBeacon(Adapter);
15319 	} else if (mode == _HW_STATE_ADHOC_)
15320 		ResumeTxBeacon(Adapter);
15321 	else if (mode == _HW_STATE_AP_)
15322 		/* enable rx ps-poll */
15323 		rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);
15324 
15325 	/* enable rx data frame */
15326 	rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
15327 
15328 #ifdef CONFIG_CLIENT_PORT_CFG
15329 	if (mode == _HW_STATE_STATION_)
15330 		rtw_hw_client_port_allocate(Adapter);
15331 	else
15332 		rtw_hw_client_port_release(Adapter);
15333 #endif
15334 #if defined(CONFIG_RTL8192F)
15335 		rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,
15336 					REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
15337 #endif
15338 }
15339 #endif
15340 
15341 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)15342 u8	rtw_hal_antdiv_before_linked(_adapter *padapter)
15343 {
15344 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15345 	u8 cur_ant, change_ant;
15346 
15347 	if (!pHalData->AntDivCfg)
15348 		return _FALSE;
15349 
15350 	if (pHalData->sw_antdiv_bl_state == 0) {
15351 		pHalData->sw_antdiv_bl_state = 1;
15352 
15353 		rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
15354 		change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
15355 
15356 		return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
15357 	}
15358 
15359 	pHalData->sw_antdiv_bl_state = 0;
15360 	return _FALSE;
15361 }
15362 
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)15363 void	rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
15364 {
15365 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15366 
15367 	if (pHalData->AntDivCfg) {
15368 		/*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
15369 		/*select optimum_antenna for before linked =>For antenna diversity*/
15370 		if (dst->Rssi >=  src->Rssi) {/*keep org parameter*/
15371 			src->Rssi = dst->Rssi;
15372 			src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
15373 		}
15374 	}
15375 }
15376 #endif
15377 
15378 #ifdef CONFIG_PROC_DEBUG
15379 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap_by_phydmapi(void * sel,_adapter * adapter)15380 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
15381 {
15382 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
15383 	struct phy_spec_t *phy_spec = &pHalData->phy_spec;
15384 
15385 	RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
15386 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
15387 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
15388 	RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index	[15:8]*/
15389 	RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index	[7:0]*/
15390 
15391 	RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
15392 	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]*/
15393 	/*VHT STBC Rx [23:16]
15394 	0 = not support
15395 	1 = support for 1 spatial stream
15396 	2 = support for 1 or 2 spatial streams
15397 	3 = support for 1 or 2 or 3 spatial streams
15398 	4 = support for 1 or 2 or 3 or 4 spatial streams*/
15399 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
15400 	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]*/
15401 	/*HT STBC Rx [7:0]
15402 	0 = not support
15403 	1 = support for 1 spatial stream
15404 	2 = support for 1 or 2 spatial streams
15405 	3 = support for 1 or 2 or 3 spatial streams*/
15406 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
15407 
15408 	RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
15409 	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]*/
15410 	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]*/
15411 	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]*/
15412 	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]*/
15413 	#ifdef CONFIG_BEAMFORMING
15414 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
15415 	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]*/
15416 	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]*/
15417 	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]*/
15418 	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]*/
15419 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF)  ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
15420 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
15421 
15422 	RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
15423 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
15424 	RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
15425 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
15426 	RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
15427 	#endif
15428 }
15429 #else
rtw_dump_phy_cap_by_hal(void * sel,_adapter * adapter)15430 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
15431 {
15432 	u8 phy_cap = _FALSE;
15433 
15434 	/* STBC */
15435 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
15436 	RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15437 
15438 	phy_cap = _FALSE;
15439 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
15440 	RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15441 
15442 	/* LDPC support */
15443 	phy_cap = _FALSE;
15444 	rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
15445 	RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15446 
15447 	phy_cap = _FALSE;
15448 	rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
15449 	RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15450 
15451 	#ifdef CONFIG_BEAMFORMING
15452 	phy_cap = _FALSE;
15453 	rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
15454 	RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15455 
15456 	phy_cap = _FALSE;
15457 	rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
15458 	RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15459 
15460 	phy_cap = _FALSE;
15461 	rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
15462 	RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15463 
15464 	phy_cap = _FALSE;
15465 	rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
15466 	RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15467 	#endif
15468 }
15469 #endif
rtw_dump_phy_cap(void * sel,_adapter * adapter)15470 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
15471 {
15472 	RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
15473 #ifdef CONFIG_PHY_CAPABILITY_QUERY
15474 	rtw_dump_phy_cap_by_phydmapi(sel, adapter);
15475 #else
15476 	rtw_dump_phy_cap_by_hal(sel, adapter);
15477 #endif
15478 }
15479 #endif
15480 
translate_dbm_to_percentage(s16 signal)15481 inline s16 translate_dbm_to_percentage(s16 signal)
15482 {
15483 	if ((signal <= -100) || (signal >= 20))
15484 		return	0;
15485 	else if (signal >= 0)
15486 		return	100;
15487 	else
15488 		return 100 + signal;
15489 }
15490 
15491 #ifdef CONFIG_SWTIMER_BASED_TXBCN
15492 #ifdef CONFIG_BCN_RECOVERY
15493 #define REG_CPU_MGQ_INFO	0x041C
15494 #define BIT_BCN_POLL			BIT(28)
rtw_ap_bcn_recovery(_adapter * padapter)15495 u8 rtw_ap_bcn_recovery(_adapter *padapter)
15496 {
15497 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15498 
15499 	if (hal_data->issue_bcn_fail >= 2) {
15500 		RTW_ERR("%s ISSUE BCN Fail\n", __func__);
15501 		rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
15502 		hal_data->issue_bcn_fail = 0;
15503 	}
15504 	return _SUCCESS;
15505 }
15506 #endif /*CONFIG_BCN_RECOVERY*/
15507 
15508 #ifdef CONFIG_BCN_XMIT_PROTECT
rtw_ap_bcn_queue_empty_check(_adapter * padapter,u32 txbcn_timer_ms)15509 u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
15510 {
15511 	u32 start_time = rtw_get_current_time();
15512 	u8 bcn_queue_empty = _FALSE;
15513 
15514 	do {
15515 		if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
15516 			bcn_queue_empty = _TRUE;
15517 			break;
15518 		}
15519 	} while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
15520 
15521 	if (bcn_queue_empty == _FALSE)
15522 		RTW_ERR("%s BCN queue not empty\n", __func__);
15523 
15524 	return bcn_queue_empty;
15525 }
15526 #endif /*CONFIG_BCN_XMIT_PROTECT*/
15527 #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
15528 
15529 /**
15530  * rtw_hal_get_trx_path() - Get RF path related information
15531  * @d:		struct dvobj_priv*
15532  * @type:	RF type, nTnR
15533  * @tx:		Tx path
15534  * @rx:		Rx path
15535  *
15536  * Get RF type, TX path and RX path information.
15537  */
rtw_hal_get_trx_path(struct dvobj_priv * d,enum rf_type * type,enum bb_path * tx,enum bb_path * rx)15538 void rtw_hal_get_trx_path(struct dvobj_priv *d, enum rf_type *type,
15539 			 enum bb_path *tx, enum bb_path *rx)
15540 {
15541 	struct _ADAPTER *a = dvobj_get_primary_adapter(d);
15542 	enum rf_type t = GET_HAL_RFPATH(a);
15543 
15544 	if (type)
15545 		*type = t;
15546 
15547 	if (tx || rx) {
15548 		u8 tx_bmp = GET_HAL_TX_PATH_BMP(a);
15549 		u8 rx_bmp = GET_HAL_RX_PATH_BMP(a);
15550 
15551 		if (!tx_bmp && !rx_bmp)
15552 			rf_type_to_default_trx_bmp(t, tx, rx);
15553 		else {
15554 			if (tx)
15555 				*tx = GET_HAL_TX_PATH_BMP(a);
15556 			if (rx)
15557 				*rx = GET_HAL_RX_PATH_BMP(a);
15558 		}
15559 	}
15560 }
15561 
15562 #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
rtw_hal_switch_chnl_and_set_bw_offload(_adapter * adapter,u8 central_ch,u8 pri_ch_idx,u8 bw)15563 void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)
15564 {
15565 	u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};
15566 	PHAL_DATA_TYPE hal;
15567 	struct submit_ctx *chsw_sctx;
15568 
15569 	hal = GET_HAL_DATA(adapter);
15570 	chsw_sctx = &hal->chsw_sctx;
15571 
15572 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);
15573 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);
15574 	SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);
15575 
15576 	rtw_sctx_init(chsw_sctx, 10);
15577 	rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);
15578 	rtw_sctx_wait(chsw_sctx, __func__);
15579 }
15580 #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */
15581 
phy_get_current_tx_num(PADAPTER pAdapter,u8 Rate)15582 u8 phy_get_current_tx_num(
15583 		PADAPTER		pAdapter,
15584 		u8				Rate
15585 )
15586 {
15587 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(pAdapter);
15588 	u8	tx_num = 0;
15589 
15590 	if (IS_1T_RATE(Rate))
15591 		tx_num = hal_data->txpath_num_nss[0];
15592 	else if (IS_2T_RATE(Rate))
15593 		tx_num = hal_data->txpath_num_nss[1];
15594 	else if (IS_3T_RATE(Rate))
15595 		tx_num = hal_data->txpath_num_nss[2];
15596 	else if (IS_4T_RATE(Rate))
15597 		tx_num = hal_data->txpath_num_nss[3];
15598 	else
15599 		rtw_warn_on(1);
15600 
15601 	return tx_num == 0 ? RF_1TX : tx_num - 1;
15602 }
15603 
15604 #ifdef CONFIG_RTL8812A
rtw_hal_set_8812a_vendor_ie(_adapter * padapter,u8 * pframe,uint * frlen)15605 u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ) {
15606 	int vender_len = 7;
15607 	unsigned char	vendor_info[vender_len];
15608 	unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
15609 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
15610 
15611 	if( !IS_HARDWARE_TYPE_8812(padapter) )
15612 		return pframe;
15613 
15614 	_rtw_memset(vendor_info,0,vender_len);
15615 	_rtw_memcpy(vendor_info, REALTEK_OUI, 3);
15616 	vendor_info[4] =2;
15617 	if(pHalData->version_id.CUTVersion > B_CUT_VERSION )
15618 		vendor_info[6] = RT_HT_CAP_USE_JAGUAR_CCUT;
15619 	else
15620 		vendor_info[6] = RT_HT_CAP_USE_JAGUAR_BCUT;
15621 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,vender_len,vendor_info , frlen);
15622 
15623 	return pframe;
15624 }
15625 #endif /*CONFIG_RTL8812A*/
15626 
rtw_enter_protsel(struct protsel * protsel,u32 sel)15627 static inline void rtw_enter_protsel(struct protsel *protsel, u32 sel)
15628 {
15629 	int refcnt;
15630 
15631 	_enter_critical_mutex(&protsel->mutex, NULL);
15632 
15633 	refcnt = ATOMIC_INC_RETURN(&protsel->refcnt);
15634 
15635 	WARN_ON(refcnt > 1 && protsel->sel != sel);
15636 
15637 	protsel->sel = sel;
15638 
15639 	_exit_critical_mutex(&protsel->mutex, NULL);
15640 }
15641 
rtw_leave_protsel(struct protsel * protsel)15642 static inline void rtw_leave_protsel(struct protsel *protsel)
15643 {
15644 	int refcnt;
15645 
15646 	_enter_critical_mutex(&protsel->mutex, NULL);
15647 
15648 	refcnt = ATOMIC_DEC_RETURN(&protsel->refcnt);
15649 
15650 	_exit_critical_mutex(&protsel->mutex, NULL);
15651 
15652 	WARN_ON(refcnt < 0);
15653 }
15654 
rtw_assert_protsel(struct protsel * protsel)15655 static inline bool rtw_assert_protsel(struct protsel *protsel)
15656 {
15657 	int refcnt = ATOMIC_READ(&protsel->refcnt);
15658 
15659 	if (refcnt > 0)
15660 		return true;
15661 
15662 	return false;
15663 }
15664 
15665 #ifdef CONFIG_PROTSEL_PORT
rtw_enter_protsel_port(_adapter * padapter,u8 port_sel)15666 void rtw_enter_protsel_port(_adapter *padapter, u8 port_sel)
15667 {
15668 	u8 val8;
15669 
15670 	rtw_enter_protsel(&padapter->dvobj->protsel_port, port_sel);
15671 
15672 	val8 = rtw_read8(padapter, REG_PORT_CTRL_SEL);
15673 	val8 &= ~BIT_MASK_PORT_CTRL_SEL;
15674 	val8 |= BIT_PORT_CTRL_SEL(port_sel);
15675 	rtw_write8(padapter, REG_PORT_CTRL_SEL, val8);
15676 }
15677 
rtw_assert_protsel_port(_adapter * padapter,u32 addr,u8 len)15678 bool rtw_assert_protsel_port(_adapter *padapter, u32 addr, u8 len)
15679 {
15680 	if (!padapter->bup)	/* don't assert before IF up */
15681 		return true;
15682 
15683 	return rtw_assert_protsel(&padapter->dvobj->protsel_port);
15684 }
15685 
rtw_leave_protsel_port(_adapter * padapter)15686 void rtw_leave_protsel_port(_adapter *padapter)
15687 {
15688 	rtw_leave_protsel(&padapter->dvobj->protsel_port);
15689 }
15690 #endif
15691 
15692 #ifdef CONFIG_PROTSEL_ATIMDTIM
rtw_enter_protsel_atimdtim(_adapter * padapter,u8 port_sel)15693 void rtw_enter_protsel_atimdtim(_adapter *padapter, u8 port_sel)
15694 {
15695 	/* 0~15 is for port 0 MBSSID setting
15696 	 * 16 is for port 1 setting
15697 	 * 17 is for port 2 setting
15698 	 * 18 is for port 3 setting
15699 	 * 19 is for port 4 setting
15700 	 */
15701 	u8 val8;
15702 
15703 	if (port_sel >= 1 && port_sel <= 4)
15704 		port_sel += 15;
15705 
15706 	rtw_enter_protsel(&padapter->dvobj->protsel_atimdtim, port_sel);
15707 
15708 	val8 = rtw_read8(padapter, REG_ATIM_DTIM_CTRL_SEL);
15709 	val8 &= ~BIT_MASK_ATIM_DTIM_SEL;
15710 	val8 |= BIT_ATIM_DTIM_SEL(port_sel);
15711 	rtw_write8(padapter, REG_ATIM_DTIM_CTRL_SEL, val8);
15712 }
15713 
rtw_assert_protsel_atimdtim(_adapter * padapter,u32 addr,u8 len)15714 bool rtw_assert_protsel_atimdtim(_adapter *padapter, u32 addr, u8 len)
15715 {
15716 	return rtw_assert_protsel(&padapter->dvobj->protsel_atimdtim);
15717 }
15718 
rtw_leave_protsel_atimdtim(_adapter * padapter)15719 void rtw_leave_protsel_atimdtim(_adapter *padapter)
15720 {
15721 	rtw_leave_protsel(&padapter->dvobj->protsel_atimdtim);
15722 }
15723 #endif
15724 
15725 #ifdef CONFIG_PROTSEL_MACSLEEP
rtw_enter_protsel_macsleep(_adapter * padapter,u8 sel)15726 void rtw_enter_protsel_macsleep(_adapter *padapter, u8 sel)
15727 {
15728 	u32 val32;
15729 
15730 	rtw_enter_protsel(&padapter->dvobj->protsel_macsleep, sel);
15731 
15732 	val32 = rtw_read32(padapter, REG_MACID_SLEEP_CTRL);
15733 	val32 &= ~BIT_MASK_MACID_SLEEP_SEL;
15734 	val32 |= BIT_MACID_SLEEP_SEL(sel);
15735 	rtw_write32(padapter, REG_MACID_SLEEP_CTRL, val32);
15736 }
15737 
rtw_assert_protsel_macsleep(_adapter * padapter,u32 addr,u8 len)15738 bool rtw_assert_protsel_macsleep(_adapter *padapter, u32 addr, u8 len)
15739 {
15740 	return rtw_assert_protsel(&padapter->dvobj->protsel_macsleep);
15741 }
15742 
rtw_leave_protsel_macsleep(_adapter * padapter)15743 void rtw_leave_protsel_macsleep(_adapter *padapter)
15744 {
15745 	rtw_leave_protsel(&padapter->dvobj->protsel_macsleep);
15746 }
15747 #endif
15748