• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2019 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 _RTW_MLME_EXT_C_
16 
17 #include <drv_types.h>
18 #include <hal_data.h>
19 
20 struct mlme_handler mlme_sta_tbl[] = {
21 	{WIFI_ASSOCREQ,		"OnAssocReq",	&OnAssocReq},
22 	{WIFI_ASSOCRSP,		"OnAssocRsp",	&OnAssocRsp},
23 	{WIFI_REASSOCREQ,	"OnReAssocReq",	&OnAssocReq},
24 	{WIFI_REASSOCRSP,	"OnReAssocRsp",	&OnAssocRsp},
25 	{WIFI_PROBEREQ,		"OnProbeReq",	&OnProbeReq},
26 	{WIFI_PROBERSP,		"OnProbeRsp",		&OnProbeRsp},
27 
28 	/*----------------------------------------------------------
29 					below 2 are reserved
30 	-----------------------------------------------------------*/
31 	{0,					"DoReserved",		&DoReserved},
32 	{0,					"DoReserved",		&DoReserved},
33 	{WIFI_BEACON,		"OnBeacon",		&OnBeacon},
34 	{WIFI_ATIM,			"OnATIM",		&OnAtim},
35 	{WIFI_DISASSOC,		"OnDisassoc",		&OnDisassoc},
36 	{WIFI_AUTH,			"OnAuth",		&OnAuthClient},
37 	{WIFI_DEAUTH,		"OnDeAuth",		&OnDeAuth},
38 	{WIFI_ACTION,		"OnAction",		&OnAction},
39 	{WIFI_ACTION_NOACK, "OnActionNoAck",	&OnAction},
40 };
41 
42 #ifdef _CONFIG_NATIVEAP_MLME_
43 struct mlme_handler mlme_ap_tbl[] = {
44 	{WIFI_ASSOCREQ,		"OnAssocReq",	&OnAssocReq},
45 	{WIFI_ASSOCRSP,		"OnAssocRsp",	&OnAssocRsp},
46 	{WIFI_REASSOCREQ,	"OnReAssocReq",	&OnAssocReq},
47 	{WIFI_REASSOCRSP,	"OnReAssocRsp",	&OnAssocRsp},
48 	{WIFI_PROBEREQ,		"OnProbeReq",	&OnProbeReq},
49 	{WIFI_PROBERSP,		"OnProbeRsp",		&OnProbeRsp},
50 
51 	/*----------------------------------------------------------
52 					below 2 are reserved
53 	-----------------------------------------------------------*/
54 	{0,					"DoReserved",		&DoReserved},
55 	{0,					"DoReserved",		&DoReserved},
56 	{WIFI_BEACON,		"OnBeacon",		&OnBeacon},
57 	{WIFI_ATIM,			"OnATIM",		&OnAtim},
58 	{WIFI_DISASSOC,		"OnDisassoc",		&OnDisassoc},
59 	{WIFI_AUTH,			"OnAuth",		&OnAuth},
60 	{WIFI_DEAUTH,		"OnDeAuth",		&OnDeAuth},
61 	{WIFI_ACTION,		"OnAction",		&OnAction},
62 	{WIFI_ACTION_NOACK, "OnActionNoAck",	&OnAction},
63 };
64 #endif
65 
66 struct action_handler OnAction_tbl[] = {
67 	{RTW_WLAN_CATEGORY_SPECTRUM_MGMT,	 "ACTION_SPECTRUM_MGMT", on_action_spct},
68 	{RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos},
69 	{RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls},
70 	{RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
71 	{RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
72 	{RTW_WLAN_CATEGORY_RADIO_MEAS, "ACTION_RADIO_MEAS", &on_action_rm},
73 	{RTW_WLAN_CATEGORY_FT, "ACTION_FT",	&OnAction_ft},
74 	{RTW_WLAN_CATEGORY_HT,	"ACTION_HT",	&OnAction_ht},
75 #ifdef CONFIG_IEEE80211W
76 	{RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query},
77 #else
78 	{RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved},
79 #endif /* CONFIG_IEEE80211W */
80 #ifdef CONFIG_RTW_WNM
81 	{RTW_WLAN_CATEGORY_WNM, "ACTION_WNM", &on_action_wnm},
82 #endif
83 	{RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved},
84 #ifdef CONFIG_RTW_MESH
85 	{RTW_WLAN_CATEGORY_MESH, "ACTION_MESH", &on_action_mesh},
86 	{RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &on_action_self_protected},
87 #endif
88 	{RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
89 	{RTW_WLAN_CATEGORY_VHT, "ACTION_VHT", &OnAction_vht},
90 	{RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},
91 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
92 	{RTW_WLAN_CATEGORY_TBTX, "ACTION_TBTX_TOKEN", &OnAction_tbtx_token}
93 #endif
94 };
95 
96 
97 u8	null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
98 
99 /**************************************************
100 OUI definitions for the vendor specific IE
101 ***************************************************/
102 unsigned char	RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
103 unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
104 unsigned char	WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
105 unsigned char	P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09};
106 unsigned char	WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A};
107 unsigned char	DPP_OUI[] = {0x50, 0x6F, 0x9A, 0x1A};
108 unsigned char	MULTI_AP_OUI[] = {0x50, 0x6F, 0x9A, 0x1B};
109 
110 unsigned char	WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
111 unsigned char	WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
112 
113 unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
114 unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
115 
116 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
117 unsigned char REALTEK_TBTX_IE[] = {0x00, 0xe0, 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00};
118 #endif
119 extern unsigned char REALTEK_96B_IE[];
120 
init_channel_list(_adapter * padapter,RT_CHANNEL_INFO * channel_set,struct p2p_channels * channel_list)121 static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set
122 	, struct p2p_channels *channel_list)
123 {
124 	struct registry_priv *regsty = adapter_to_regsty(padapter);
125 
126 	struct p2p_oper_class_map op_class[] = {
127 		{ IEEE80211G,  81,   1,  13,  1, BW20 },
128 		{ IEEE80211G,  82,  14,  14,  1, BW20 },
129 #if 0 /* Do not enable HT40 on 2 GHz */
130 		{ IEEE80211G,  83,   1,   9,  1, BW40PLUS },
131 		{ IEEE80211G,  84,   5,  13,  1, BW40MINUS },
132 #endif
133 		{ IEEE80211A, 115,  36,  48,  4, BW20 },
134 		{ IEEE80211A, 116,  36,  44,  8, BW40PLUS },
135 		{ IEEE80211A, 117,  40,  48,  8, BW40MINUS },
136 		{ IEEE80211A, 124, 149, 161,  4, BW20 },
137 		{ IEEE80211A, 125, 149, 169,  4, BW20 },
138 		{ IEEE80211A, 126, 149, 157,  8, BW40PLUS },
139 		{ IEEE80211A, 127, 153, 161,  8, BW40MINUS },
140 		{ -1, 0, 0, 0, 0, BW20 }
141 	};
142 
143 	int cla, op;
144 
145 	cla = 0;
146 
147 	for (op = 0; op_class[op].op_class; op++) {
148 		u8 ch;
149 		struct p2p_oper_class_map *o = &op_class[op];
150 		struct p2p_reg_class *reg = NULL;
151 
152 		for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
153 			if (rtw_chset_search_ch(channel_set, ch) == -1)
154 				continue;
155 #if defined(CONFIG_80211N_HT) || defined(CONFIG_80211AC_VHT)
156 			if ((padapter->registrypriv.ht_enable == 0) && (o->inc == 8))
157 				continue;
158 
159 			if ((REGSTY_IS_BW_5G_SUPPORT(regsty, CHANNEL_WIDTH_40)) &&
160 			    ((o->bw == BW40MINUS) || (o->bw == BW40PLUS)))
161 				continue;
162 #endif
163 			if (reg == NULL) {
164 				reg = &channel_list->reg_class[cla];
165 				cla++;
166 				reg->reg_class = o->op_class;
167 				reg->channels = 0;
168 			}
169 			reg->channel[reg->channels] = ch;
170 			reg->channels++;
171 		}
172 	}
173 	channel_list->reg_classes = cla;
174 
175 }
176 
177 #if CONFIG_TXPWR_LIMIT
rtw_txpwr_init_regd_default(struct rf_ctl_t * rfctl)178 static void rtw_txpwr_init_regd_default(struct rf_ctl_t *rfctl)
179 {
180 	bool country_txpwr_lmt_override = 0;
181 	u8 txpwr_lmt[BAND_MAX];
182 	const char *name[BAND_MAX];
183 	u8 unknown_bmp = 0; /* unknown bitmap */
184 	char buf[TXPWR_NAMES_STR_LEN];
185 	u8 band;
186 	bool altenate_applied = 0;
187 
188 	for (band = 0; band < BAND_MAX; band++) {
189 		txpwr_lmt[band] = TXPWR_LMT_NONE;
190 		name[band] = NULL;
191 		unknown_bmp |= BIT(band);
192 	}
193 
194 	if (rfctl->txpwr_lmt_override != TXPWR_LMT_DEF) {
195 		country_txpwr_lmt_override = 1;
196 		for (band = 0; band < BAND_MAX; band++)
197 			txpwr_lmt[band] = rfctl->txpwr_lmt_override;
198 	} else {
199 		txpwr_lmt[BAND_ON_2_4G] = rtw_regd_to_txpwr_lmt(rtw_chplan_get_default_regd_2g(rfctl->ChannelPlan));
200 		#if CONFIG_IEEE80211_BAND_5GHZ
201 		txpwr_lmt[BAND_ON_5G] = rtw_regd_to_txpwr_lmt(rtw_chplan_get_default_regd_5g(rfctl->ChannelPlan));
202 		#endif
203 		#if CONFIG_IEEE80211_BAND_6GHZ
204 		txpwr_lmt[BAND_ON_6G] = rtw_regd_to_txpwr_lmt(rtw_chplan_get_default_regd_6g(rfctl->chplan_6g));
205 		#endif
206 	}
207 
208 	for (band = 0; band < BAND_MAX; band++) {
209 		name[band] = txpwr_lmt_str(txpwr_lmt[band]);
210 		if (txpwr_lmt[band] == TXPWR_LMT_NONE || txpwr_lmt[band] == TXPWR_LMT_WW || txpwr_lmt[band] == TXPWR_LMT_NUM
211 			|| _rtw_txpwr_lmt_get_by_name(rfctl, name[band]))
212 			unknown_bmp &= ~BIT(band);
213 	}
214 
215 	if (country_txpwr_lmt_override) {
216 		RTW_PRINT("default mapping country:%c%c to txpwr_lmt:%s\n"
217 			, rfctl->alpha2[0], rfctl->alpha2[1]
218 			, rtw_get_txpwr_lmt_names_str(buf, name, unknown_bmp)
219 		);
220 	} else {
221 		RTW_PRINT("default mapping domain to txpwr_lmt:%s\n"
222 			, rtw_get_txpwr_lmt_names_str(buf, name, unknown_bmp));
223 	}
224 	if (unknown_bmp == 0)
225 		goto exit;
226 
227 	for (band = 0; band < BAND_MAX; band++) {
228 		if (!(unknown_bmp & BIT(band)))
229 			continue;
230 		if (TXPWR_LMT_ALTERNATE_DEFINED(txpwr_lmt[band])) {
231 			/*
232 			* To support older chips without new predefined txpwr_lmt:
233 			* - use txpwr_lmt_alternate() to get alternate if the selection is  not found
234 			*/
235 			altenate_applied = 1;
236 			txpwr_lmt[band] = txpwr_lmt_alternate(txpwr_lmt[band]);
237 			name[band] = txpwr_lmt_str(txpwr_lmt[band]);
238 			if (_rtw_txpwr_lmt_get_by_name(rfctl, name[band]))
239 				unknown_bmp &= ~BIT(band);
240 		}
241 	}
242 	if (altenate_applied) {
243 		RTW_PRINT("alternate applied txpwr_lmt:%s\n"
244 			, rtw_get_txpwr_lmt_names_str(buf, name, unknown_bmp));
245 		if (unknown_bmp == 0)
246 			goto exit;
247 	}
248 
249 	for (band = 0; band < BAND_MAX; band++) {
250 		if (!(unknown_bmp & BIT(band)))
251 			continue;
252 		txpwr_lmt[band] = TXPWR_LMT_WW;
253 		name[band] = txpwr_lmt_str(txpwr_lmt[band]);
254 		unknown_bmp &= ~BIT(band);
255 	}
256 	RTW_PRINT("world wide applied txpwr_lmt:%s\n"
257 		, rtw_get_txpwr_lmt_names_str(buf, name, unknown_bmp));
258 
259 exit:
260 	for (band = 0; band < BAND_MAX; band++)
261 		rfctl->txpwr_lmt_name[band] = name[band];
262 }
263 
rtw_txpwr_init_regd(struct rf_ctl_t * rfctl)264 void rtw_txpwr_init_regd(struct rf_ctl_t *rfctl)
265 {
266 	const char *name = NULL;
267 	u8 band;
268 	struct regd_exc_ent *exc;
269 	struct txpwr_lmt_ent *ent;
270 	_irqL irqL;
271 
272 	_enter_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL);
273 
274 	for (band = 0; band < BAND_MAX; band++)
275 		rfctl->txpwr_lmt_name[band] = NULL;
276 
277 	if (rfctl->txpwr_lmt_num == 0) {
278 		RTW_PRINT("there is no any txpwr_regd\n");
279 		goto release_lock;
280 	}
281 
282 	/* search from exception mapping */
283 	exc = _rtw_regd_exc_search(rfctl, rfctl->alpha2, rfctl->ChannelPlan);
284 	if (exc) {
285 		u8 has_country = (exc->country[0] == '\0' && exc->country[1] == '\0') ? 0 : 1;
286 
287 		if (strcmp(exc->lmt_name, txpwr_lmt_str(TXPWR_LMT_NONE)) == 0)
288 			name = txpwr_lmt_str(TXPWR_LMT_NONE);
289 		else if (strcmp(exc->lmt_name, txpwr_lmt_str(TXPWR_LMT_WW)) == 0)
290 			name = txpwr_lmt_str(TXPWR_LMT_WW);
291 		else {
292 			ent = _rtw_txpwr_lmt_get_by_name(rfctl, exc->lmt_name);
293 			if (ent)
294 				name = ent->name;
295 		}
296 
297 		RTW_PRINT("exception mapping country:%c%c domain:0x%02x to%s txpwr_lmt:%s\n"
298 			, has_country ? exc->country[0] : '-'
299 			, has_country ? exc->country[1] : '-'
300 			, exc->domain
301 			, name ? "" : " unknown"
302 			, exc->lmt_name
303 		);
304 		if (name) {
305 			for (band = 0; band < BAND_MAX; band++)
306 				rfctl->txpwr_lmt_name[band] = name;
307 			goto release_lock;
308 		}
309 	}
310 
311 #ifdef CONFIG_REGD_SRC_FROM_OS
312 	if (rfctl->regd_src == REGD_SRC_OS) {
313 		if (RFCTL_REG_WORLDWIDE(rfctl))
314 			name = txpwr_lmt_str(TXPWR_LMT_WW);
315 		else {
316 			char alpha2[3] = {
317 				rfctl->alpha2[0], rfctl->alpha2[1], 0};
318 
319 			ent = _rtw_txpwr_lmt_get_by_name(rfctl, alpha2);
320 			if (ent)
321 				name = ent->name;
322 		}
323 
324 		if (name) {
325 			for (band = 0; band < BAND_MAX; band++)
326 				rfctl->txpwr_lmt_name[band] = name;
327 			RTW_PRINT("mapping country:%c%c to txpwr_lmt:%s\n"
328 				, rfctl->alpha2[0]
329 				, rfctl->alpha2[1]
330 				, name
331 			);
332 			goto release_lock;
333 		}
334 
335 		if (rfctl->ChannelPlan == RTW_CHPLAN_UNSPECIFIED) {
336 			name = txpwr_lmt_str(TXPWR_LMT_WW);
337 			for (band = 0; band < BAND_MAX; band++)
338 				rfctl->txpwr_lmt_name[band] = name;
339 			RTW_PRINT("mapping unsupported country:%c%c to txpwr_lmt:%s\n"
340 				, rfctl->alpha2[0]
341 				, rfctl->alpha2[1]
342 				, name
343 			);
344 			goto release_lock;
345 		}
346 	}
347 #endif
348 
349 	/* follow default channel plan mapping */
350 	rtw_txpwr_init_regd_default(rfctl);
351 
352 release_lock:
353 	_exit_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL);
354 }
355 
rtw_rfctl_is_current_txpwr_lmt(struct rf_ctl_t * rfctl,const char * name)356 bool rtw_rfctl_is_current_txpwr_lmt(struct rf_ctl_t *rfctl, const char *name)
357 {
358 	int band;
359 
360 	for (band = 0; band < BAND_MAX; band++)
361 		if (rfctl->txpwr_lmt_name[band] && strcmp(name, rfctl->txpwr_lmt_name[band]) == 0)
362 			return 1;
363 
364 	return 0;
365 }
366 #endif /* CONFIG_TXPWR_LIMIT */
367 
rtw_rfctl_init(_adapter * adapter)368 int rtw_rfctl_init(_adapter *adapter)
369 {
370 	struct registry_priv *regsty = adapter_to_regsty(adapter);
371 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
372 	int ret;
373 
374 	_rtw_mutex_init(&rfctl->offch_mutex);
375 
376 	rfctl->user_ChannelPlan = RTW_CHPLAN_UNSPECIFIED;
377 #if CONFIG_IEEE80211_BAND_6GHZ
378 	rfctl->user_chplan_6g = RTW_CHPLAN_6G_UNSPECIFIED;
379 #endif
380 
381 #ifdef CONFIG_80211D
382 	rfctl->country_ie_slave_en_role = regsty->country_ie_slave_en_role;
383 	rfctl->country_ie_slave_en_ifbmp = regsty->country_ie_slave_en_ifbmp;
384 	rfctl->effected_cisr_id = CONFIG_IFACE_NUMBER;
385 #endif
386 
387 #if CONFIG_TXPWR_LIMIT
388 	_rtw_mutex_init(&rfctl->txpwr_lmt_mutex);
389 	_rtw_init_listhead(&rfctl->reg_exc_list);
390 	_rtw_init_listhead(&rfctl->txpwr_lmt_list);
391 #endif
392 
393 	rfctl->ch_sel_within_same_band = 1;
394 
395 #ifdef CONFIG_DFS_MASTER
396 	rfctl->dfs_region_domain = regsty->dfs_region_domain;
397 	rfctl->cac_start_time = rfctl->cac_end_time = RTW_CAC_STOPPED;
398 	rtw_init_timer(&(rfctl->radar_detect_timer), adapter, rtw_dfs_rd_timer_hdl, rfctl);
399 #endif
400 #if CONFIG_DFS_SLAVE_WITH_RADAR_DETECT
401 	rfctl->dfs_slave_with_rd = 1;
402 #endif
403 
404 	if (regsty->antenna_gain != UNSPECIFIED_MBM)
405 		rfctl->antenna_gain = regsty->antenna_gain;
406 
407 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
408 	rfctl->ap_csa_cnt_input = DEFAULT_CSA_CNT;
409 #endif
410 
411 	ret = op_class_pref_init(adapter);
412 	if (ret != _SUCCESS)
413 		op_class_pref_deinit(adapter);
414 
415 	return ret;
416 }
417 
rtw_rfctl_deinit(_adapter * adapter)418 void rtw_rfctl_deinit(_adapter *adapter)
419 {
420 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
421 
422 	_rtw_mutex_free(&rfctl->offch_mutex);
423 
424 #if CONFIG_TXPWR_LIMIT
425 	rtw_regd_exc_list_free(rfctl);
426 	rtw_txpwr_lmt_list_free(rfctl);
427 	_rtw_mutex_free(&rfctl->txpwr_lmt_mutex);
428 #endif
429 
430 	op_class_pref_deinit(adapter);
431 }
432 
433 /*
434  * Description:
435  *	Use hardware(efuse), driver parameter(registry) and default channel plan
436  *	to decide which one should be used.
437  *
438  * Parameters:
439  *	rfctl				pointer of rfctl
440  *	hw_alpha2		country code from HW (efuse/eeprom/mapfile)
441  *	hw_chplan		domain code from HW (efuse/eeprom/mapfile)
442  *	hw_chplan_6g	6g domain code from HW (efuse/eeprom/mapfile)
443  *	hw_force_chplan	if forcing HW channel plan setting (efuse/eeprom/mapfile)
444  *					will modified tif HW channel plan setting is invlid, will
445  */
rtw_rfctl_decide_init_chplan(struct rf_ctl_t * rfctl,const char * hw_alpha2,u8 hw_chplan,u8 hw_chplan_6g,u8 hw_force_chplan)446 void rtw_rfctl_decide_init_chplan(struct rf_ctl_t *rfctl,
447 	const char *hw_alpha2, u8 hw_chplan, u8 hw_chplan_6g, u8 hw_force_chplan)
448 {
449 	struct registry_priv *regsty;
450 	char *sw_alpha2;
451 	const struct country_chplan *country_ent = NULL;
452 	struct country_chplan ent;
453 	int chplan = -1;
454 	int chplan_6g = -1;
455 
456 	u8 sw_chplan;
457 	u8 def_chplan = RTW_CHPLAN_WORLDWIDE; /* worldwide,  used when HW, SW both invalid */
458 #if CONFIG_IEEE80211_BAND_6GHZ
459 	u8 sw_chplan_6g;
460 	u8 def_chplan_6g = RTW_CHPLAN_6G_WORLDWIDE; /* worldwide,  used when HW, SW both invalid */
461 #endif
462 
463 	if (hw_alpha2) {
464 		if (rtw_get_chplan_from_country(hw_alpha2, &ent)) {
465 			/* get chplan from hw country code, by pass hw chplan setting */
466 			country_ent = &ent;
467 			chplan = ent.chplan;
468 			#if CONFIG_IEEE80211_BAND_6GHZ
469 			chplan_6g = ent.chplan_6g;
470 			#endif
471 			goto chk_sw_config;
472 		} else
473 			RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
474 	}
475 
476 	if (rtw_is_channel_plan_valid(hw_chplan))
477 		chplan = hw_chplan;
478 	else if (hw_force_chplan == _TRUE) {
479 		RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
480 		/* hw infomaton invalid, refer to sw information */
481 		hw_force_chplan = _FALSE;
482 	}
483 
484 #if CONFIG_IEEE80211_BAND_6GHZ
485 	if (rtw_is_channel_plan_6g_valid(hw_chplan_6g))
486 		chplan_6g = hw_chplan_6g;
487 	else if (hw_force_chplan == _TRUE) {
488 		RTW_PRINT("%s unsupported hw_chplan_6g:0x%02X\n", __func__, hw_chplan_6g);
489 		/* hw infomaton invalid, refer to sw information */
490 		hw_force_chplan = _FALSE;
491 	}
492 #endif
493 
494 chk_sw_config:
495 	if (hw_force_chplan == _TRUE)
496 		goto done;
497 
498 	regsty = dvobj_to_regsty(rfctl_to_dvobj(rfctl));
499 	sw_alpha2 = regsty->alpha2;
500 	sw_chplan = regsty->channel_plan;
501 	#if CONFIG_IEEE80211_BAND_6GHZ
502 	sw_chplan_6g = regsty->channel_plan_6g;
503 	#endif
504 
505 	if (sw_alpha2 && !IS_ALPHA2_UNSPEC(sw_alpha2)) {
506 		if (IS_ALPHA2_WORLDWIDE(sw_alpha2)
507 			|| rtw_get_chplan_from_country(sw_alpha2, &ent)
508 		) {
509 			/* get chplan from sw country code, by pass sw chplan setting */
510 			if (IS_ALPHA2_WORLDWIDE(sw_alpha2))
511 				rtw_get_chplan_worldwide(&ent);
512 			country_ent = &ent;
513 			chplan = ent.chplan;
514 			#if CONFIG_IEEE80211_BAND_6GHZ
515 			chplan_6g = ent.chplan_6g;
516 			#endif
517 			goto done;
518 		} else
519 			RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
520 	}
521 
522 	if (rtw_is_channel_plan_valid(sw_chplan)) {
523 		/* cancel hw_alpha2 because chplan is specified by sw_chplan */
524 		country_ent = NULL;
525 		chplan = sw_chplan;
526 	} else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)
527 		RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
528 
529 #if CONFIG_IEEE80211_BAND_6GHZ
530 	if (rtw_is_channel_plan_6g_valid(sw_chplan_6g)) {
531 		/* cancel hw_alpha2 because chplan_6g is specified by sw_chplan_6g */
532 		country_ent = NULL;
533 		chplan_6g = sw_chplan_6g;
534 	} else if (sw_chplan_6g != RTW_CHPLAN_6G_UNSPECIFIED)
535 		RTW_PRINT("%s unsupported sw_chplan_6g:0x%02X\n", __func__, sw_chplan_6g);
536 #endif
537 
538 done:
539 	if (chplan == -1) {
540 		RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
541 		chplan = def_chplan;
542 	} else
543 		RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
544 
545 #if CONFIG_IEEE80211_BAND_6GHZ
546 	if (chplan_6g == -1) {
547 		RTW_PRINT("%s use def_chplan_6g:0x%02X\n", __func__, def_chplan_6g);
548 		chplan_6g = def_chplan_6g;
549 	} else
550 		RTW_PRINT("%s chplan_6g:0x%02X\n", __func__, chplan_6g);
551 #endif
552 
553 	if (!country_ent) {
554 		if (rtw_chplan_ids_is_world_wide(chplan, chplan_6g))
555 			rtw_get_chplan_worldwide(&ent);
556 		else {
557 			SET_UNSPEC_ALPHA2(ent.alpha2);
558 			ent.edcca_mode_2g_override = RTW_EDCCA_DEF;
559 			#if CONFIG_IEEE80211_BAND_5GHZ
560 			ent.edcca_mode_5g_override = RTW_EDCCA_DEF;
561 			#endif
562 			#if CONFIG_IEEE80211_BAND_6GHZ
563 			ent.edcca_mode_6g_override = RTW_EDCCA_DEF;
564 			#endif
565 			ent.txpwr_lmt_override = TXPWR_LMT_DEF;
566 			#if defined(CONFIG_80211AX_HE) || defined(CONFIG_80211AC_VHT)
567 			ent.proto_en = CHPLAN_PROTO_EN_ALL;
568 			#endif
569 		}
570 	} else {
571 		RTW_PRINT("%s country code:\"%c%c\"\n", __func__
572 			, country_ent->alpha2[0], country_ent->alpha2[1]);
573 	}
574 
575 	rfctl->disable_sw_chplan = hw_force_chplan;
576 
577 	rfctl->regd_inr = RTW_REGD_SET_BY_INIT;
578 	rfctl->init_alpha2[0] = rfctl->alpha2[0] = ent.alpha2[0];
579 	rfctl->init_alpha2[1] = rfctl->alpha2[1] = ent.alpha2[1];
580 	rfctl->init_ChannelPlan = rfctl->ChannelPlan = chplan;
581 #if CONFIG_IEEE80211_BAND_6GHZ
582 	rfctl->init_chplan_6g = rfctl->chplan_6g = chplan_6g;
583 #endif
584 	rfctl->edcca_mode_2g_override = ent.edcca_mode_2g_override;
585 #if CONFIG_IEEE80211_BAND_5GHZ
586 	rfctl->edcca_mode_5g_override = ent.edcca_mode_5g_override;
587 #endif
588 #if CONFIG_IEEE80211_BAND_6GHZ
589 	rfctl->edcca_mode_6g_override = ent.edcca_mode_6g_override;
590 #endif
591 #if CONFIG_TXPWR_LIMIT
592 	rfctl->txpwr_lmt_override = ent.txpwr_lmt_override;
593 #endif
594 #if defined(CONFIG_80211AX_HE) || defined(CONFIG_80211AC_VHT)
595 	rfctl->proto_en = ent.proto_en;
596 #endif
597 }
598 
rtw_rfctl_chplan_init(_adapter * adapter)599 void rtw_rfctl_chplan_init(_adapter *adapter)
600 {
601 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
602 
603 	init_channel_set(adapter);
604 	op_class_pref_apply_regulatory(adapter, REG_CHANGE);
605 	init_channel_list(adapter, rfctl->channel_set, &rfctl->channel_list);
606 }
607 
rtw_rfctl_is_disable_sw_channel_plan(struct dvobj_priv * dvobj)608 bool rtw_rfctl_is_disable_sw_channel_plan(struct dvobj_priv *dvobj)
609 {
610 	return dvobj_to_rfctl(dvobj)->disable_sw_chplan;
611 }
612 
rtw_rfctl_update_op_mode(struct rf_ctl_t * rfctl,u8 ifbmp_mod,u8 if_op)613 void rtw_rfctl_update_op_mode(struct rf_ctl_t *rfctl, u8 ifbmp_mod, u8 if_op)
614 {
615 	struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
616 	_adapter *iface;
617 	struct mlme_ext_priv *mlmeext;
618 	u8 op_class = 0;
619 	u8 op_ch = 0;
620 	s16 op_txpwr_max;
621 	u8 if_op_class[CONFIG_IFACE_NUMBER] = {0};
622 	u8 if_op_ch[CONFIG_IFACE_NUMBER] = {0};
623 	u8 ch, bw, offset;
624 	u8 u_ch = 0, u_bw, u_offset;
625 	bool notify = 0;
626 	int i;
627 
628 	for (i = 0; i < dvobj->iface_nums; i++) {
629 		iface = dvobj->padapters[i];
630 		if (!iface)
631 			continue;
632 		mlmeext = &iface->mlmeextpriv;
633 
634 		if (ifbmp_mod & BIT(i)) {
635 			if (!if_op)
636 				continue;
637 		} else if (!MLME_IS_ASOC(iface) || MLME_IS_OPCH_SW(iface))
638 			continue;
639 
640 		ch = mlmeext->cur_channel;
641 		bw = mlmeext->cur_bwmode;
642 		offset = mlmeext->cur_ch_offset;
643 		if_op_class[i] = rtw_get_op_class_by_chbw(ch, bw, offset);
644 		if_op_ch[i] = if_op_class[i] ? ch : 0;
645 
646 		if (!u_ch) {
647 			u_ch = ch;
648 			u_bw = bw;
649 			u_offset = offset;
650 		} else {
651 			rtw_warn_on(!rtw_is_chbw_grouped(u_ch, u_bw, u_offset, ch, bw, offset));
652 			rtw_sync_chbw(&ch, &bw, &offset, &u_ch, &u_bw, &u_offset);
653 		}
654 	}
655 
656 	op_class = rtw_get_op_class_by_chbw(u_ch, u_bw, u_offset);
657 	op_ch = op_class ? u_ch : 0;
658 	op_txpwr_max = rtw_rfctl_get_oper_txpwr_max_mbm(rfctl, u_ch, u_bw, u_offset, ifbmp_mod, if_op, 1);
659 
660 	if (op_class != rfctl->op_class
661 		|| op_ch != rfctl->op_ch
662 		|| op_txpwr_max != rfctl->op_txpwr_max
663 		|| _rtw_memcmp(if_op_class, rfctl->if_op_class, sizeof(u8) * CONFIG_IFACE_NUMBER) == _FALSE
664 		|| _rtw_memcmp(if_op_ch, rfctl->if_op_ch, sizeof(u8) * CONFIG_IFACE_NUMBER) == _FALSE)
665 		notify = 1;
666 
667 	rfctl->op_class = op_class;
668 	rfctl->op_ch = op_ch;
669 	rfctl->op_txpwr_max = op_txpwr_max;
670 	_rtw_memcpy(rfctl->if_op_class, if_op_class, sizeof(u8) * CONFIG_IFACE_NUMBER);
671 	_rtw_memcpy(rfctl->if_op_ch, if_op_ch, sizeof(u8) * CONFIG_IFACE_NUMBER);
672 
673 	if (0)
674 		RTW_INFO("radio: %u,%u,%u %d notify:%d\n", u_ch, u_bw, u_offset, op_txpwr_max, notify);
675 	for (i = 0; i < dvobj->iface_nums; i++) {
676 		iface = dvobj->padapters[i];
677 		if (!iface)
678 			continue;
679 		mlmeext = &iface->mlmeextpriv;
680 
681 		if (ifbmp_mod & BIT(i)) {
682 			if (!if_op)
683 				continue;
684 		} else if (!MLME_IS_ASOC(iface))
685 			continue;
686 		if (0)
687 			RTW_INFO(ADPT_FMT": %u,%u,%u\n", ADPT_ARG(iface)
688 				, mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
689 	}
690 
691 	if (notify)
692 		rtw_nlrtw_radio_opmode_notify(rfctl);
693 
694 #ifdef CONFIG_PLATFORM_CMAP_INTFS
695 	for (i = 0; i < dvobj->iface_nums; i++) {
696 		iface = dvobj->padapters[i];
697 		if (!iface)
698 			continue;
699 		cmap_intfs_nl_bss_status_event(iface, 0);
700 	}
701 #endif
702 }
703 
704 /* domain status specific beacon hint rules */
705 #ifndef RTW_CHPLAN_BEACON_HINT_SPECIFIC_COUNTRY
706 #define RTW_CHPLAN_BEACON_HINT_SPECIFIC_COUNTRY 0
707 #endif
708 
rtw_rfctl_reg_allow_beacon_hint(struct rf_ctl_t * rfctl)709 bool rtw_rfctl_reg_allow_beacon_hint(struct rf_ctl_t *rfctl)
710 {
711 	return RTW_CHPLAN_BEACON_HINT_SPECIFIC_COUNTRY || RFCTL_REG_WORLDWIDE(rfctl) || RFCTL_REG_ALPHA2_UNSPEC(rfctl);
712 }
713 
rtw_rfctl_get_dfs_domain(struct rf_ctl_t * rfctl)714 inline u8 rtw_rfctl_get_dfs_domain(struct rf_ctl_t *rfctl)
715 {
716 #ifdef CONFIG_DFS_MASTER
717 	return rfctl->dfs_region_domain;
718 #else
719 	return RTW_DFS_REGD_NONE;
720 #endif
721 }
722 
rtw_rfctl_dfs_domain_unknown(struct rf_ctl_t * rfctl)723 inline u8 rtw_rfctl_dfs_domain_unknown(struct rf_ctl_t *rfctl)
724 {
725 #ifdef CONFIG_DFS_MASTER
726 	return rtw_rfctl_get_dfs_domain(rfctl) == RTW_DFS_REGD_NONE;
727 #else
728 	return 1;
729 #endif
730 }
731 
732 #ifdef CONFIG_DFS_MASTER
733 /*
734 * called in rtw_dfs_rd_enable()
735 * assume the request channel coverage is DFS range
736 * base on the current status and the request channel coverage to check if need to reset complete CAC time
737 */
rtw_is_cac_reset_needed(struct rf_ctl_t * rfctl,u8 ch,u8 bw,u8 offset)738 bool rtw_is_cac_reset_needed(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
739 {
740 	bool needed = _FALSE;
741 	u32 cur_hi, cur_lo, hi, lo;
742 
743 	if (rfctl->radar_detected == 1) {
744 		needed = _TRUE;
745 		goto exit;
746 	}
747 
748 	if (rfctl->radar_detect_ch == 0) {
749 		needed = _TRUE;
750 		goto exit;
751 	}
752 
753 	if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
754 		RTW_ERR("request detection range ch:%u, bw:%u, offset:%u\n", ch, bw, offset);
755 		rtw_warn_on(1);
756 	}
757 
758 	if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset, &cur_hi, &cur_lo) == _FALSE) {
759 		RTW_ERR("cur detection range ch:%u, bw:%u, offset:%u\n", rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset);
760 		rtw_warn_on(1);
761 	}
762 
763 	if (hi <= lo || cur_hi <= cur_lo) {
764 		RTW_ERR("hi:%u, lo:%u, cur_hi:%u, cur_lo:%u\n", hi, lo, cur_hi, cur_lo);
765 		rtw_warn_on(1);
766 	}
767 
768 	if (rtw_is_range_a_in_b(hi, lo, cur_hi, cur_lo)) {
769 		/* request is in current detect range */
770 		goto exit;
771 	}
772 
773 	/* check if request channel coverage has new range and the new range is in DFS range */
774 	if (!rtw_is_range_overlap(hi, lo, cur_hi, cur_lo)) {
775 		/* request has no overlap with current */
776 		needed = _TRUE;
777 	} else if (rtw_is_range_a_in_b(cur_hi, cur_lo, hi, lo)) {
778 		/* request is supper set of current */
779 		if ((hi != cur_hi && rtw_chset_is_dfs_range(rfctl->channel_set, hi, cur_hi))
780 			|| (lo != cur_lo && rtw_chset_is_dfs_range(rfctl->channel_set, cur_lo, lo)))
781 			needed = _TRUE;
782 	} else {
783 		/* request is not supper set of current, but has overlap */
784 		if ((lo < cur_lo && rtw_chset_is_dfs_range(rfctl->channel_set, cur_lo, lo))
785 			|| (hi > cur_hi && rtw_chset_is_dfs_range(rfctl->channel_set, hi, cur_hi)))
786 			needed = _TRUE;
787 	}
788 
789 exit:
790 	return needed;
791 }
792 
_rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t * rfctl,u8 ch,u8 bw,u8 offset)793 bool _rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
794 {
795 	bool ret = _FALSE;
796 	u32 hi = 0, lo = 0;
797 	u32 r_hi = 0, r_lo = 0;
798 	int i;
799 
800 	if (rfctl->radar_detect_by_others)
801 		goto exit;
802 
803 	if (rfctl->radar_detect_ch == 0)
804 		goto exit;
805 
806 	if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
807 		rtw_warn_on(1);
808 		goto exit;
809 	}
810 
811 	if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch
812 			, rfctl->radar_detect_bw, rfctl->radar_detect_offset
813 			, &r_hi, &r_lo) == _FALSE) {
814 		rtw_warn_on(1);
815 		goto exit;
816 	}
817 
818 	if (rtw_is_range_overlap(hi, lo, r_hi, r_lo))
819 		ret = _TRUE;
820 
821 exit:
822 	return ret;
823 }
824 
rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t * rfctl)825 bool rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl)
826 {
827 	return _rtw_rfctl_overlap_radar_detect_ch(rfctl
828 				, rfctl_to_dvobj(rfctl)->oper_channel
829 				, rfctl_to_dvobj(rfctl)->oper_bwmode
830 				, rfctl_to_dvobj(rfctl)->oper_ch_offset);
831 }
832 
rtw_rfctl_is_tx_blocked_by_ch_waiting(struct rf_ctl_t * rfctl)833 bool rtw_rfctl_is_tx_blocked_by_ch_waiting(struct rf_ctl_t *rfctl)
834 {
835 	return rtw_rfctl_overlap_radar_detect_ch(rfctl) && IS_CH_WAITING(rfctl);
836 }
837 
rtw_chset_is_chbw_non_ocp(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset)838 bool rtw_chset_is_chbw_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
839 {
840 	bool ret = _FALSE;
841 	u32 hi = 0, lo = 0;
842 	int i;
843 
844 	if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
845 		goto exit;
846 
847 	for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
848 		if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
849 			rtw_warn_on(1);
850 			continue;
851 		}
852 
853 		if (!CH_IS_NON_OCP(&ch_set[i]))
854 			continue;
855 
856 		if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
857 			&& rtw_ch2freq(ch_set[i].ChannelNum) <= hi
858 		) {
859 			ret = _TRUE;
860 			break;
861 		}
862 	}
863 
864 exit:
865 	return ret;
866 }
867 
rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO * ch_set,u8 ch)868 bool rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch)
869 {
870 	return rtw_chset_is_chbw_non_ocp(ch_set, ch, CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
871 }
872 
rtw_chset_get_ch_non_ocp_ms(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset)873 u32 rtw_chset_get_ch_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
874 {
875 	int ms = 0;
876 	systime current_time;
877 	u32 hi = 0, lo = 0;
878 	int i;
879 
880 	if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
881 		goto exit;
882 
883 	current_time = rtw_get_current_time();
884 
885 	for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
886 		if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
887 			rtw_warn_on(1);
888 			continue;
889 		}
890 
891 		if (!CH_IS_NON_OCP(&ch_set[i]))
892 			continue;
893 
894 		if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
895 			&& rtw_ch2freq(ch_set[i].ChannelNum) <= hi
896 		) {
897 			if (rtw_systime_to_ms(ch_set[i].non_ocp_end_time - current_time) > ms)
898 				ms = rtw_systime_to_ms(ch_set[i].non_ocp_end_time - current_time);
899 		}
900 	}
901 
902 exit:
903 	return ms;
904 }
905 
906 /**
907  * rtw_chset_update_non_ocp - update non_ocp_end_time according to the given @ch, @bw, @offset into @ch_set
908  * @ch_set: the given channel set
909  * @ch: channel number on which radar is detected
910  * @bw: bandwidth on which radar is detected
911  * @offset: bandwidth offset on which radar is detected
912  * @ms: ms to add from now to update non_ocp_end_time, ms < 0 means use NON_OCP_TIME_MS
913  */
_rtw_chset_update_non_ocp(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset,int ms)914 static bool _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
915 {
916 	u32 hi = 0, lo = 0;
917 	int i;
918 	bool updated = 0;
919 
920 	if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
921 		goto exit;
922 
923 	for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
924 		if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
925 			rtw_warn_on(1);
926 			continue;
927 		}
928 
929 		if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
930 			&& rtw_ch2freq(ch_set[i].ChannelNum) <= hi
931 		) {
932 			if (ms >= 0)
933 				ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(ms);
934 			else
935 				ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(NON_OCP_TIME_MS);
936 			ch_set[i].flags |= RTW_CHF_NON_OCP;
937 			updated = 1;
938 		}
939 	}
940 
941 exit:
942 	return updated;
943 }
944 
rtw_chset_update_non_ocp(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset)945 inline bool rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
946 {
947 	return _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, -1);
948 }
949 
rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset,int ms)950 inline bool rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
951 {
952 	return _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, ms);
953 }
954 
rtw_chset_chk_non_ocp_finish_for_chbw(struct rf_ctl_t * rfctl,u8 ch,u8 bw,u8 offset)955 static bool rtw_chset_chk_non_ocp_finish_for_chbw(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
956 {
957 	RT_CHANNEL_INFO *ch_set = rfctl->channel_set;
958 	u8 cch;
959 	u8 *op_chs;
960 	u8 op_ch_num;
961 	int i;
962 	int ch_idx;
963 	bool ret = 0;
964 
965 	cch = rtw_get_center_ch(ch, bw, offset);
966 
967 	if (!rtw_get_op_chs_by_cch_bw(cch, bw, &op_chs, &op_ch_num))
968 		goto exit;
969 
970 	for (i = 0; i < op_ch_num; i++) {
971 		if (0)
972 			RTW_INFO("%u,%u,%u - cch:%u, bw:%u, op_ch:%u\n", ch, bw, offset, cch, bw, *(op_chs + i));
973 		ch_idx = rtw_chset_search_ch(ch_set, *(op_chs + i));
974 		if (ch_idx == -1)
975 			break;
976 		if (!(ch_set[ch_idx].flags & RTW_CHF_NON_OCP) || CH_IS_NON_OCP(&ch_set[ch_idx]))
977 			break;
978 	}
979 
980 	if (op_ch_num != 0 && i == op_ch_num) {
981 		ret = 1;
982 		/* clear RTTW_CHF_NON_OCP flag */
983 		for (i = 0; i < op_ch_num; i++) {
984 			ch_idx = rtw_chset_search_ch(ch_set, *(op_chs + i));
985 			ch_set[ch_idx].flags &= ~RTW_CHF_NON_OCP;
986 		}
987 		rtw_nlrtw_nop_finish_event(dvobj_get_primary_adapter(rfctl_to_dvobj(rfctl)), cch, bw);
988 	}
989 
990 exit:
991 	return ret;
992 }
993 
994 /* called by watchdog to clear RTW_CHF_NON_OCP and generate NON_OCP finish event */
rtw_chset_chk_non_ocp_finish(struct rf_ctl_t * rfctl)995 void rtw_chset_chk_non_ocp_finish(struct rf_ctl_t *rfctl)
996 {
997 	u8 ch, bw, offset;
998 	int i;
999 
1000 	bw = CHANNEL_WIDTH_160;
1001 	while (1) {
1002 		for (i = 0; i < rfctl->max_chan_nums; i++) {
1003 			ch = rfctl->channel_set[i].ChannelNum;
1004 			if (!(rfctl->channel_set[i].flags & RTW_CHF_NON_OCP))
1005 				continue;
1006 			if (!rtw_get_offset_by_chbw(ch, bw, &offset))
1007 				continue;
1008 
1009 			rtw_chset_chk_non_ocp_finish_for_chbw(rfctl, ch, bw, offset);
1010 		}
1011 		if (bw-- == CHANNEL_WIDTH_20)
1012 			break;
1013 	}
1014 }
1015 
rtw_get_ch_waiting_ms(struct rf_ctl_t * rfctl,u8 ch,u8 bw,u8 offset,u32 * r_non_ocp_ms,u32 * r_cac_ms)1016 u32 rtw_get_ch_waiting_ms(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, u32 *r_non_ocp_ms, u32 *r_cac_ms)
1017 {
1018 	struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
1019 	u32 non_ocp_ms;
1020 	u32 cac_ms;
1021 	u8 in_rd_range = 0; /* if in current radar detection range*/
1022 
1023 	if (rtw_chset_is_chbw_non_ocp(rfctl->channel_set, ch, bw, offset))
1024 		non_ocp_ms = rtw_chset_get_ch_non_ocp_ms(rfctl->channel_set, ch, bw, offset);
1025 	else
1026 		non_ocp_ms = 0;
1027 
1028 	if (rfctl->radar_detect_enabled) {
1029 		u32 cur_hi, cur_lo, hi, lo;
1030 
1031 		if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
1032 			RTW_ERR("input range ch:%u, bw:%u, offset:%u\n", ch, bw, offset);
1033 			rtw_warn_on(1);
1034 		}
1035 
1036 		if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset, &cur_hi, &cur_lo) == _FALSE) {
1037 			RTW_ERR("cur detection range ch:%u, bw:%u, offset:%u\n", rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset);
1038 			rtw_warn_on(1);
1039 		}
1040 
1041 		if (rtw_is_range_a_in_b(hi, lo, cur_hi, cur_lo))
1042 			in_rd_range = 1;
1043 	}
1044 
1045 	if (!rtw_chset_is_dfs_chbw(rfctl->channel_set, ch, bw, offset))
1046 		cac_ms = 0;
1047 	else if (in_rd_range && !non_ocp_ms) {
1048 		if (IS_CH_WAITING(rfctl))
1049 			cac_ms = rtw_systime_to_ms(rfctl->cac_end_time - rtw_get_current_time());
1050 		else
1051 			cac_ms = 0;
1052 	} else if (rtw_is_long_cac_ch(ch, bw, offset, rtw_rfctl_get_dfs_domain(rfctl)))
1053 		cac_ms = CAC_TIME_CE_MS;
1054 	else
1055 		cac_ms = CAC_TIME_MS;
1056 
1057 	if (r_non_ocp_ms)
1058 		*r_non_ocp_ms = non_ocp_ms;
1059 	if (r_cac_ms)
1060 		*r_cac_ms = cac_ms;
1061 
1062 	return non_ocp_ms + cac_ms;
1063 }
1064 
rtw_reset_cac(struct rf_ctl_t * rfctl,u8 ch,u8 bw,u8 offset)1065 void rtw_reset_cac(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
1066 {
1067 	u32 non_ocp_ms;
1068 	u32 cac_ms;
1069 
1070 	rtw_get_ch_waiting_ms(rfctl
1071 		, ch
1072 		, bw
1073 		, offset
1074 		, &non_ocp_ms
1075 		, &cac_ms
1076 	);
1077 
1078 	rfctl->cac_start_time = rtw_get_current_time() + rtw_ms_to_systime(non_ocp_ms);
1079 	rfctl->cac_end_time = rfctl->cac_start_time + rtw_ms_to_systime(cac_ms);
1080 
1081 	/* skip special value */
1082 	if (rfctl->cac_start_time == RTW_CAC_STOPPED) {
1083 		rfctl->cac_start_time++;
1084 		rfctl->cac_end_time++;
1085 	}
1086 	if (rfctl->cac_end_time == RTW_CAC_STOPPED)
1087 		rfctl->cac_end_time++;
1088 }
1089 
rtw_force_stop_cac(struct rf_ctl_t * rfctl,u32 timeout_ms)1090 u32 rtw_force_stop_cac(struct rf_ctl_t *rfctl, u32 timeout_ms)
1091 {
1092 	struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
1093 	systime start;
1094 	u32 pass_ms;
1095 
1096 	start = rtw_get_current_time();
1097 
1098 	rfctl->cac_force_stop = 1;
1099 
1100 	while (rtw_get_passing_time_ms(start) <= timeout_ms
1101 		&& IS_UNDER_CAC(rfctl)
1102 	) {
1103 		if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
1104 			break;
1105 		rtw_msleep_os(20);
1106 	}
1107 
1108 	if (IS_UNDER_CAC(rfctl)) {
1109 		if (!dev_is_surprise_removed(dvobj) && !dev_is_drv_stopped(dvobj))
1110 			RTW_INFO("%s waiting for cac stop timeout!\n", __func__);
1111 	}
1112 
1113 	rfctl->cac_force_stop = 0;
1114 
1115 	pass_ms = rtw_get_passing_time_ms(start);
1116 
1117 	return pass_ms;
1118 }
1119 #endif /* CONFIG_DFS_MASTER */
1120 
1121 /* choose channel with shortest waiting (non ocp + cac) time */
rtw_choose_shortest_waiting_ch(struct rf_ctl_t * rfctl,u8 sel_ch,u8 max_bw,u8 * dec_ch,u8 * dec_bw,u8 * dec_offset,u8 e_flags,u8 d_flags,u8 cur_ch,bool by_int_info,u8 mesh_only)1122 bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw
1123 	, u8 *dec_ch, u8 *dec_bw, u8 *dec_offset
1124 	, u8 e_flags, u8 d_flags, u8 cur_ch, bool by_int_info, u8 mesh_only)
1125 {
1126 #ifndef DBG_CHOOSE_SHORTEST_WAITING_CH
1127 #define DBG_CHOOSE_SHORTEST_WAITING_CH 0
1128 #endif
1129 	struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
1130 #ifdef CONFIG_RTW_ACS
1131 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(dvobj_get_primary_adapter(dvobj));
1132 #endif
1133 	struct registry_priv *regsty = dvobj_to_regsty(dvobj);
1134 	u8 ch, bw, offset;
1135 	u8 ch_c = 0, bw_c = 0, offset_c = 0;
1136 	int i;
1137 	u32 min_waiting_ms = 0;
1138 	u16 int_factor_c = 0;
1139 
1140 	if (!dec_ch || !dec_bw || !dec_offset) {
1141 		rtw_warn_on(1);
1142 		return _FALSE;
1143 	}
1144 
1145 	RTW_INFO("%s: sel_ch:%u max_bw:%u e_flags:0x%02x d_flags:0x%02x cur_ch:%u within_sb:%d%s%s\n"
1146 		, __func__, sel_ch, max_bw, e_flags, d_flags, cur_ch, rfctl->ch_sel_within_same_band
1147 		, by_int_info ? " int" : "", mesh_only ? " mesh_only" : "");
1148 
1149 	/* full search and narrow bw judegement first to avoid potetial judegement timing issue */
1150 	for (bw = CHANNEL_WIDTH_20; bw <= max_bw; bw++) {
1151 		if (!hal_is_bw_support(dvobj_get_primary_adapter(dvobj), bw))
1152 			continue;
1153 
1154 		for (i = 0; i < rfctl->max_chan_nums; i++) {
1155 			u32 non_ocp_ms = 0;
1156 			u32 cac_ms = 0;
1157 			u32 waiting_ms = 0;
1158 			u16 int_factor = 0;
1159 			bool dfs_ch;
1160 			bool non_ocp;
1161 			bool long_cac;
1162 
1163 			ch = rfctl->channel_set[i].ChannelNum;
1164 			if (sel_ch) {
1165 				if (ch != sel_ch)
1166 					continue;
1167 			} else if (rfctl->ch_sel_within_same_band && !rtw_is_same_band(cur_ch, ch))
1168 				continue;
1169 
1170 			if (ch > 14) {
1171 				if (bw > REGSTY_BW_5G(regsty))
1172 					continue;
1173 			} else {
1174 				if (bw > REGSTY_BW_2G(regsty))
1175 					continue;
1176 			}
1177 
1178 			if (mesh_only && ch >= 5 && ch <= 9 && bw > CHANNEL_WIDTH_20)
1179 				continue;
1180 
1181 			if (!rtw_get_offset_by_chbw(ch, bw, &offset))
1182 				continue;
1183 
1184 			if (!rtw_chset_is_chbw_valid(rfctl->channel_set, ch, bw, offset, 0, 0))
1185 				continue;
1186 
1187 			if ((e_flags & RTW_CHF_DFS) || (d_flags & RTW_CHF_DFS)) {
1188 				dfs_ch = rtw_chset_is_dfs_chbw(rfctl->channel_set, ch, bw, offset);
1189 				if (((e_flags & RTW_CHF_DFS) && !dfs_ch)
1190 					|| ((d_flags & RTW_CHF_DFS) && dfs_ch))
1191 					continue;
1192 			}
1193 
1194 			if ((e_flags & RTW_CHF_LONG_CAC) || (d_flags & RTW_CHF_LONG_CAC)) {
1195 				long_cac = rtw_is_long_cac_ch(ch, bw, offset, rtw_rfctl_get_dfs_domain(rfctl));
1196 				if (((e_flags & RTW_CHF_LONG_CAC) && !long_cac)
1197 					|| ((d_flags & RTW_CHF_LONG_CAC) && long_cac))
1198 					continue;
1199 			}
1200 
1201 			if ((e_flags & RTW_CHF_NON_OCP) || (d_flags & RTW_CHF_NON_OCP)) {
1202 				non_ocp = rtw_chset_is_chbw_non_ocp(rfctl->channel_set, ch, bw, offset);
1203 				if (((e_flags & RTW_CHF_NON_OCP) && !non_ocp)
1204 					|| ((d_flags & RTW_CHF_NON_OCP) && non_ocp))
1205 					continue;
1206 			}
1207 
1208 			#ifdef CONFIG_DFS_MASTER
1209 			waiting_ms = rtw_get_ch_waiting_ms(rfctl, ch, bw, offset, &non_ocp_ms, &cac_ms);
1210 			#endif
1211 
1212 			#ifdef CONFIG_RTW_ACS
1213 			if (by_int_info) {
1214 				/* for now, consider only primary channel */
1215 				int_factor = hal_data->acs.interference_time[i];
1216 			}
1217 			#endif
1218 
1219 			if (DBG_CHOOSE_SHORTEST_WAITING_CH)
1220 				RTW_INFO("%s:%u,%u,%u %u(non_ocp:%u, cac:%u), int:%u\n"
1221 					, __func__, ch, bw, offset, waiting_ms, non_ocp_ms, cac_ms, int_factor);
1222 
1223 			if (ch_c == 0
1224 				/* first: smaller wating time */
1225 				|| min_waiting_ms > waiting_ms
1226 				/* then: less interference */
1227 				|| (min_waiting_ms == waiting_ms && int_factor_c > int_factor)
1228 				/* then: wider bw */
1229 				|| (min_waiting_ms == waiting_ms && int_factor_c == int_factor && bw > bw_c)
1230 				/* if all condition equal, same channel -> same band prefer */
1231 				|| (min_waiting_ms == waiting_ms && int_factor_c == int_factor && bw == bw_c
1232 					&& ((cur_ch != ch_c && cur_ch == ch)
1233 						|| (!rtw_is_same_band(cur_ch, ch_c) && rtw_is_same_band(cur_ch, ch)))
1234 					)
1235 			) {
1236 				ch_c = ch;
1237 				bw_c = bw;
1238 				offset_c = offset;
1239 				min_waiting_ms = waiting_ms;
1240 				int_factor_c = int_factor;
1241 			}
1242 		}
1243 	}
1244 
1245 	if (ch_c != 0) {
1246 		RTW_INFO("%s: select %u,%u,%u waiting_ms:%u\n"
1247 			, __func__, ch_c, bw_c, offset_c, min_waiting_ms);
1248 		*dec_ch = ch_c;
1249 		*dec_bw = bw_c;
1250 		*dec_offset = offset_c;
1251 		return _TRUE;
1252 	} else {
1253 		RTW_INFO("%s: not found\n", __func__);
1254 		if (d_flags == 0)
1255 			rtw_warn_on(1);
1256 	}
1257 
1258 	return _FALSE;
1259 }
1260 
1261 #ifdef CONFIG_PROC_DEBUG
1262 #define RTW_CHF_FMT "%s%s%s%s%s%s"
1263 
1264 #define RTW_CHF_ARG_NO_IR(flags)		(flags & RTW_CHF_NO_IR) ? " NO_IR" : ""
1265 #define RTW_CHF_ARG_DFS(flags)			, (flags & RTW_CHF_DFS) ? " DFS" : ""
1266 #define RTW_CHF_ARG_NO_HT40U(flags)		, (flags & RTW_CHF_NO_HT40U) ? " NO_40M+" : ""
1267 #define RTW_CHF_ARG_NO_HT40L(flags)		, (flags & RTW_CHF_NO_HT40L) ? " NO_40M-" : ""
1268 #define RTW_CHF_ARG_NO_80MHZ(flags)		, (flags & RTW_CHF_NO_80MHZ) ? " NO_80M" : ""
1269 #define RTW_CHF_ARG_NO_160MHZ(flags)	, (flags & RTW_CHF_NO_160MHZ) ? " NO_160M" : ""
1270 
1271 #define RTW_CHF_ARG(flags) \
1272 	RTW_CHF_ARG_NO_IR(flags) \
1273 	RTW_CHF_ARG_DFS(flags) \
1274 	RTW_CHF_ARG_NO_HT40U(flags) \
1275 	RTW_CHF_ARG_NO_HT40L(flags) \
1276 	RTW_CHF_ARG_NO_80MHZ(flags) \
1277 	RTW_CHF_ARG_NO_160MHZ(flags)
1278 
dump_chset(void * sel,RT_CHANNEL_INFO * ch_set,u8 chset_num)1279 static void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set, u8 chset_num)
1280 {
1281 	char buf[8];
1282 	u8 i;
1283 
1284 	RTW_PRINT_SEL(sel, "%-3s %-4s %-4s flags\n", "ch", "freq", "nocp");
1285 
1286 	for (i = 0; i < MAX_CHANNEL_NUM && i < chset_num && ch_set[i].ChannelNum != 0; i++) {
1287 		#ifdef CONFIG_DFS_MASTER
1288 		if ((ch_set[i].flags & RTW_CHF_DFS) && CH_IS_NON_OCP(&ch_set[i]))
1289 			snprintf(buf, 8, "%d", rtw_systime_to_ms(ch_set[i].non_ocp_end_time - rtw_get_current_time()) / 1000);
1290 		else
1291 		#endif
1292 			snprintf(buf, 8, "0");
1293 
1294 		RTW_PRINT_SEL(sel, "%3u %4u %4s"RTW_CHF_FMT"\n"
1295 			, ch_set[i].ChannelNum, rtw_ch2freq_by_band(ch_set[i].band, ch_set[i].ChannelNum), buf
1296 			, RTW_CHF_ARG(ch_set[i].flags)
1297 		);
1298 	}
1299 
1300 	RTW_PRINT_SEL(sel, "total ch number:%d\n", i);
1301 }
1302 
dump_chplan_txpwr_lmts(void * sel,struct get_chplan_resp * chplan)1303 static void dump_chplan_txpwr_lmts(void *sel, struct get_chplan_resp *chplan)
1304 {
1305 	char buf[TXPWR_NAMES_STR_LEN];
1306 
1307 	RTW_PRINT_SEL(sel, "txpwr_lmt:%s\n", rtw_get_txpwr_lmt_names_str(buf, chplan->txpwr_lmt_name, 0));
1308 }
1309 
dump_chplan_edcca_modes(void * sel,struct get_chplan_resp * chplan)1310 static void dump_chplan_edcca_modes(void *sel, struct get_chplan_resp *chplan)
1311 {
1312 	u8 modes[BAND_MAX];
1313 	char buf[EDCCA_MODES_STR_LEN];
1314 
1315 	modes[BAND_ON_2_4G] = chplan->edcca_mode_2g;
1316 #if CONFIG_IEEE80211_BAND_5GHZ
1317 	modes[BAND_ON_5G] = chplan->edcca_mode_5g;
1318 #endif
1319 #if CONFIG_IEEE80211_BAND_6GHZ
1320 	modes[BAND_ON_6G] = chplan->edcca_mode_6g;
1321 #endif
1322 
1323 	RTW_PRINT_SEL(sel, "edcca_mode:%s\n", rtw_get_edcca_modes_str(buf, modes));
1324 }
1325 
dump_cur_country(void * sel,struct rf_ctl_t * rfctl)1326 void dump_cur_country(void *sel, struct rf_ctl_t *rfctl)
1327 {
1328 	struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
1329 	struct get_chplan_resp *chplan;
1330 	int i;
1331 
1332 	if (rtw_get_chplan_cmd(dvobj_get_primary_adapter(dvobj), RTW_CMDF_WAIT_ACK, &chplan) == _FAIL)
1333 		return;
1334 
1335 	RTW_PRINT_SEL(sel, "%c%c\n", chplan->alpha2[0], chplan->alpha2[1]);
1336 
1337 	rtw_vmfree(chplan, sizeof(struct get_chplan_resp) + sizeof(RT_CHANNEL_INFO) * chplan->chset_num);
1338 }
1339 
dump_cur_chset(void * sel,struct rf_ctl_t * rfctl)1340 void dump_cur_chset(void *sel, struct rf_ctl_t *rfctl)
1341 {
1342 	struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
1343 	struct registry_priv *regsty = dvobj_to_regsty(dvobj);
1344 	struct get_chplan_resp *chplan;
1345 	int i;
1346 
1347 	if (rtw_get_chplan_cmd(dvobj_get_primary_adapter(dvobj), RTW_CMDF_WAIT_ACK, &chplan) == _FAIL)
1348 		return;
1349 
1350 	RTW_PRINT_SEL(sel, "regd_src:%s(%d)\n", regd_src_str(chplan->regd_src), chplan->regd_src);
1351 	RTW_PRINT_SEL(sel, "regd_inr:%s\n", regd_inr_str(chplan->regd_inr));
1352 
1353 	RTW_PRINT_SEL(sel, "alpha2:%c%c\n", chplan->alpha2[0], chplan->alpha2[1]);
1354 
1355 #ifdef CONFIG_80211AX_HE
1356 	RTW_PRINT_SEL(sel, "ax:%d\n", (chplan->proto_en & CHPLAN_PROTO_EN_AX) ? 1 : 0);
1357 #endif
1358 #ifdef CONFIG_80211AC_VHT
1359 	RTW_PRINT_SEL(sel, "ac:%d\n", (chplan->proto_en & CHPLAN_PROTO_EN_AC) ? 1 : 0);
1360 #endif
1361 
1362 	if (chplan->channel_plan == RTW_CHPLAN_UNSPECIFIED)
1363 		RTW_PRINT_SEL(sel, "chplan:NA\n");
1364 	else
1365 		RTW_PRINT_SEL(sel, "chplan:0x%02X\n", chplan->channel_plan);
1366 
1367 #if CONFIG_IEEE80211_BAND_6GHZ
1368 	if (chplan->chplan_6g == RTW_CHPLAN_6G_UNSPECIFIED)
1369 		RTW_PRINT_SEL(sel, "chplan_6g:NA\n");
1370 	else
1371 		RTW_PRINT_SEL(sel, "chplan_6g:0x%02X\n", chplan->chplan_6g);
1372 #endif
1373 
1374 #if CONFIG_TXPWR_LIMIT
1375 	dump_chplan_txpwr_lmts(sel, chplan);
1376 #endif
1377 
1378 	dump_chplan_edcca_modes(sel, chplan);
1379 
1380 #ifdef CONFIG_DFS_MASTER
1381 	RTW_PRINT_SEL(sel, "dfs_domain:%s(%u)\n", rtw_dfs_regd_str(chplan->dfs_domain), chplan->dfs_domain);
1382 #endif
1383 
1384 	for (i = 0; i < MAX_CHANNEL_NUM_2G_5G; i++)
1385 		if (regsty->excl_chs[i] != 0)
1386 			break;
1387 
1388 	if (i < MAX_CHANNEL_NUM_2G_5G) {
1389 		RTW_PRINT_SEL(sel, "excl_chs:");
1390 		for (i = 0; i < MAX_CHANNEL_NUM_2G_5G; i++) {
1391 			if (regsty->excl_chs[i] == 0)
1392 				break;
1393 			_RTW_PRINT_SEL(sel, "%u ", regsty->excl_chs[i]);
1394 		}
1395 		_RTW_PRINT_SEL(sel, "\n");
1396 	}
1397 
1398 #if CONFIG_IEEE80211_BAND_6GHZ
1399 	for (i = 0; i < MAX_CHANNEL_NUM_6G; i++)
1400 		if (regsty->excl_chs_6g[i] != 0)
1401 			break;
1402 
1403 	if (i < MAX_CHANNEL_NUM_6G) {
1404 		RTW_PRINT_SEL(sel, "excl_chs_6g:");
1405 		for (i = 0; i < MAX_CHANNEL_NUM_6G; i++) {
1406 			if (regsty->excl_chs_6g[i] == 0)
1407 				break;
1408 			_RTW_PRINT_SEL(sel, "%u ", regsty->excl_chs_6g[i]);
1409 		}
1410 		_RTW_PRINT_SEL(sel, "\n");
1411 	}
1412 #endif
1413 
1414 	dump_chset(sel, chplan->chset, chplan->chset_num);
1415 
1416 	rtw_vmfree(chplan, sizeof(struct get_chplan_resp) + sizeof(RT_CHANNEL_INFO) * chplan->chset_num);
1417 }
1418 #endif /* CONFIG_PROC_DEBUG */
1419 
1420 /*
1421  * Search the @param ch in given @param ch_set
1422  * @ch_set: the given channel set
1423  * @ch: the given channel number
1424  *
1425  * return the index of channel_num in channel_set, -1 if not found
1426  */
rtw_chset_search_ch(RT_CHANNEL_INFO * ch_set,const u32 ch)1427 int rtw_chset_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
1428 {
1429 	int i;
1430 
1431 	if (ch == 0)
1432 		return -1;
1433 
1434 	for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
1435 		if (ch == ch_set[i].ChannelNum)
1436 			return i;
1437 	}
1438 
1439 	return -1;
1440 }
1441 
1442 /*
1443  * Search the @param ch of @param band in given @param ch_set
1444  * @ch_set: the given channel set
1445  * @band: the given band
1446  * @ch: the given channel number
1447  *
1448  * return the index of channel_num in channel_set, -1 if not found
1449  */
rtw_chset_search_ch_by_band(RT_CHANNEL_INFO * ch_set,BAND_TYPE band,const u32 ch)1450 int rtw_chset_search_ch_by_band(RT_CHANNEL_INFO *ch_set, BAND_TYPE band, const u32 ch)
1451 {
1452 	int i;
1453 
1454 	if (ch == 0)
1455 		return -1;
1456 
1457 	for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
1458 		if (band == ch_set[i].band && ch == ch_set[i].ChannelNum)
1459 			return i;
1460 	}
1461 
1462 	return -1;
1463 }
1464 
1465 /*
1466  * Check if the @param ch, bw, offset is valid for the given @param ch_set
1467  * @ch_set: the given channel set
1468  * @ch: the given channel number
1469  * @bw: the given bandwidth
1470  * @offset: the given channel offset
1471  *
1472  * return valid (1) or not (0)
1473  */
rtw_chset_is_chbw_valid(RT_CHANNEL_INFO * ch_set,u8 ch,u8 bw,u8 offset,bool allow_primary_passive,bool allow_passive)1474 u8 rtw_chset_is_chbw_valid(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset
1475 	, bool allow_primary_passive, bool allow_passive)
1476 {
1477 	u8 cch;
1478 	u8 *op_chs;
1479 	u8 op_ch_num;
1480 	u8 valid = 0;
1481 	int i;
1482 	int ch_idx;
1483 
1484 	cch = rtw_get_center_ch(ch, bw, offset);
1485 
1486 	if (!rtw_get_op_chs_by_cch_bw(cch, bw, &op_chs, &op_ch_num))
1487 		goto exit;
1488 
1489 	for (i = 0; i < op_ch_num; i++) {
1490 		if (0)
1491 			RTW_INFO("%u,%u,%u - cch:%u, bw:%u, op_ch:%u\n", ch, bw, offset, cch, bw, *(op_chs + i));
1492 		ch_idx = rtw_chset_search_ch(ch_set, *(op_chs + i));
1493 		if (ch_idx == -1)
1494 			break;
1495 		if (ch_set[ch_idx].flags & RTW_CHF_NO_IR) {
1496 			if (!allow_passive
1497 				|| (!allow_primary_passive && ch_set[ch_idx].ChannelNum == ch))
1498 			break;
1499 		}
1500 		if (bw >= CHANNEL_WIDTH_40) {
1501 			if ((ch_set[ch_idx].flags & RTW_CHF_NO_HT40U) && i % 2 == 0)
1502 				break;
1503 			if ((ch_set[ch_idx].flags & RTW_CHF_NO_HT40L) && i % 2 == 1)
1504 				break;
1505 		}
1506 		if (bw >= CHANNEL_WIDTH_80 && (ch_set[ch_idx].flags & RTW_CHF_NO_80MHZ))
1507 			break;
1508 		if (bw >= CHANNEL_WIDTH_160 && (ch_set[ch_idx].flags & RTW_CHF_NO_160MHZ))
1509 			break;
1510 	}
1511 
1512 	if (op_ch_num != 0 && i == op_ch_num)
1513 		valid = 1;
1514 
1515 exit:
1516 	return valid;
1517 }
1518 
1519 /**
1520  * rtw_chset_sync_chbw - obey g_ch, adjust g_bw, g_offset, bw, offset to fit in channel plan
1521  * @ch_set: channel plan to check
1522  * @req_ch: pointer of the request ch, may be modified further
1523  * @req_bw: pointer of the request bw, may be modified further
1524  * @req_offset: pointer of the request offset, may be modified further
1525  * @g_ch: pointer of the ongoing group ch
1526  * @g_bw: pointer of the ongoing group bw, may be modified further
1527  * @g_offset: pointer of the ongoing group offset, may be modified further
1528  * @allow_primary_passive: if allow passive primary ch when deciding chbw
1529  * @allow_passive: if allow passive ch (not primary) when deciding chbw
1530  */
rtw_chset_sync_chbw(RT_CHANNEL_INFO * ch_set,u8 * req_ch,u8 * req_bw,u8 * req_offset,u8 * g_ch,u8 * g_bw,u8 * g_offset,bool allow_primary_passive,bool allow_passive)1531 void rtw_chset_sync_chbw(RT_CHANNEL_INFO *ch_set, u8 *req_ch, u8 *req_bw, u8 *req_offset
1532 	, u8 *g_ch, u8 *g_bw, u8 *g_offset, bool allow_primary_passive, bool allow_passive)
1533 {
1534 	u8 r_ch, r_bw, r_offset;
1535 	u8 u_ch, u_bw, u_offset;
1536 	u8 cur_bw = *req_bw;
1537 
1538 	while (1) {
1539 		r_ch = *req_ch;
1540 		r_bw = cur_bw;
1541 		r_offset = *req_offset;
1542 		u_ch = *g_ch;
1543 		u_bw = *g_bw;
1544 		u_offset = *g_offset;
1545 
1546 		rtw_sync_chbw(&r_ch, &r_bw, &r_offset, &u_ch, &u_bw, &u_offset);
1547 
1548 		if (rtw_chset_is_chbw_valid(ch_set, r_ch, r_bw, r_offset, allow_primary_passive, allow_passive))
1549 			break;
1550 		if (cur_bw == CHANNEL_WIDTH_20) {
1551 			rtw_warn_on(1);
1552 			break;
1553 		}
1554 		cur_bw--;
1555 	};
1556 
1557 	*req_ch = r_ch;
1558 	*req_bw = r_bw;
1559 	*req_offset = r_offset;
1560 	*g_ch = u_ch;
1561 	*g_bw = u_bw;
1562 	*g_offset = u_offset;
1563 }
1564 
1565 /*
1566  * Check the @param ch is fit with setband setting of @param adapter
1567  * @adapter: the given adapter
1568  * @ch: the given channel number
1569  *
1570  * return _TRUE when check valid, _FALSE not valid
1571  */
rtw_mlme_band_check(_adapter * adapter,const u32 ch)1572 bool rtw_mlme_band_check(_adapter *adapter, const u32 ch)
1573 {
1574 	if (adapter->setband == WIFI_FREQUENCY_BAND_AUTO /* 2.4G and 5G */
1575 		|| (adapter->setband == WIFI_FREQUENCY_BAND_2GHZ && ch < 35) /* 2.4G only */
1576 		|| (adapter->setband == WIFI_FREQUENCY_BAND_5GHZ && ch > 35) /* 5G only */
1577 	)
1578 		return _TRUE;
1579 	return _FALSE;
1580 }
RTW_SET_SCAN_BAND_SKIP(_adapter * padapter,int skip_band)1581 inline void RTW_SET_SCAN_BAND_SKIP(_adapter *padapter, int skip_band)
1582 {
1583 	int bs = ATOMIC_READ(&padapter->bandskip);
1584 
1585 	bs |= skip_band;
1586 	ATOMIC_SET(&padapter->bandskip, bs);
1587 }
1588 
RTW_CLR_SCAN_BAND_SKIP(_adapter * padapter,int skip_band)1589 inline void RTW_CLR_SCAN_BAND_SKIP(_adapter *padapter, int skip_band)
1590 {
1591 	int bs = ATOMIC_READ(&padapter->bandskip);
1592 
1593 	bs &= ~(skip_band);
1594 	ATOMIC_SET(&padapter->bandskip, bs);
1595 }
RTW_GET_SCAN_BAND_SKIP(_adapter * padapter)1596 inline int RTW_GET_SCAN_BAND_SKIP(_adapter *padapter)
1597 {
1598 	return ATOMIC_READ(&padapter->bandskip);
1599 }
1600 
1601 #define RTW_IS_SCAN_BAND_SKIP(padapter, skip_band) (ATOMIC_READ(&padapter->bandskip) & (skip_band))
1602 
rtw_mlme_ignore_chan(_adapter * adapter,const u32 ch)1603 bool rtw_mlme_ignore_chan(_adapter *adapter, const u32 ch)
1604 {
1605 	if (RTW_IS_SCAN_BAND_SKIP(adapter, BAND_24G) && ch < 35) /* SKIP 2.4G Band channel */
1606 		return _TRUE;
1607 	if (RTW_IS_SCAN_BAND_SKIP(adapter, BAND_5G)  && ch > 35) /* SKIP 5G Band channel */
1608 		return _TRUE;
1609 
1610 	return _FALSE;
1611 }
1612 
1613 
1614 /****************************************************************************
1615 
1616 Following are the initialization functions for WiFi MLME
1617 
1618 *****************************************************************************/
1619 
init_hw_mlme_ext(_adapter * padapter)1620 int init_hw_mlme_ext(_adapter *padapter)
1621 {
1622 	struct	mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1623 	HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1624 	u8 rx_bar_enble = _TRUE;
1625 
1626 	/*
1627 	 * Sync driver status and hardware setting
1628 	 */
1629 
1630 	/* Modify to make sure first time change channel(band) would be done properly */
1631 	pHalData->current_channel = 0;
1632 	pHalData->current_channel_bw = CHANNEL_WIDTH_MAX;
1633 	#if CONFIG_IEEE80211_BAND_5GHZ
1634 	pHalData->current_band_type = BAND_MAX;
1635 	#else
1636 	pHalData->current_band_type = BAND_ON_2_4G;
1637 	#endif
1638 
1639 	/* set_opmode_cmd(padapter, infra_client_with_mlme); */ /* removed */
1640 	rtw_hal_set_hwreg(padapter, HW_VAR_ENABLE_RX_BAR, &rx_bar_enble);
1641 	set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
1642 
1643 	return _SUCCESS;
1644 }
1645 
init_mlme_default_rate_set(_adapter * padapter)1646 void init_mlme_default_rate_set(_adapter *padapter)
1647 {
1648 	struct	mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
1649 	unsigned	char end_set[1] = {0xff};
1650 	u8	offset_datarate = 0;
1651 	u8	offset_basicrate = 0;
1652 #ifdef CONFIG_80211N_HT
1653 	unsigned char	supported_mcs_set[16] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
1654 #endif
1655 
1656 	if (IsSupportedTxCCK(padapter->registrypriv.wireless_mode)) {
1657 
1658 		unsigned char	datarate_b[B_MODE_RATE_NUM] ={_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_};
1659 		_rtw_memcpy(pmlmeext->datarate, datarate_b, B_MODE_RATE_NUM);
1660 		_rtw_memcpy(pmlmeext->basicrate, datarate_b, B_MODE_RATE_NUM);
1661 		offset_datarate += B_MODE_RATE_NUM;
1662 		offset_basicrate += B_MODE_RATE_NUM;
1663 		RTW_INFO("%s: support CCK\n", __func__);
1664 	}
1665 	if(IsSupportedTxOFDM(padapter->registrypriv.wireless_mode)) {
1666 		unsigned char	datarate_g[G_MODE_RATE_NUM] ={_6M_RATE_, _9M_RATE_, _12M_RATE_, _18M_RATE_,_24M_RATE_, _36M_RATE_, _48M_RATE_, _54M_RATE_};
1667 		unsigned char	basicrate_g[G_MODE_BASIC_RATE_NUM] = {_6M_RATE_, _12M_RATE_, _24M_RATE_};
1668 		_rtw_memcpy(pmlmeext->datarate + offset_datarate, datarate_g, G_MODE_RATE_NUM);
1669 		_rtw_memcpy(pmlmeext->basicrate + offset_basicrate,basicrate_g, G_MODE_BASIC_RATE_NUM);
1670 		offset_datarate += G_MODE_RATE_NUM;
1671 		offset_basicrate += G_MODE_BASIC_RATE_NUM;
1672 		RTW_INFO("%s: support OFDM\n", __func__);
1673 
1674 	}
1675 	_rtw_memcpy(pmlmeext->datarate + offset_datarate, end_set, 1);
1676 	_rtw_memcpy(pmlmeext->basicrate + offset_basicrate, end_set, 1);
1677 
1678 #ifdef CONFIG_80211N_HT
1679 	if( padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode))
1680 		_rtw_memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set));
1681 #endif
1682 }
1683 
init_mlme_ext_priv_value(_adapter * padapter)1684 static void init_mlme_ext_priv_value(_adapter *padapter)
1685 {
1686 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
1687 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
1688 
1689 	ATOMIC_SET(&pmlmeext->event_seq, 0);
1690 	pmlmeext->mgnt_seq = 0;/* reset to zero when disconnect at client mode */
1691 #ifdef CONFIG_IEEE80211W
1692 	pmlmeext->sa_query_seq = 0;
1693 #endif
1694 	pmlmeext->cur_channel = padapter->registrypriv.channel;
1695 	pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
1696 	pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1697 
1698 	pmlmeext->retry = 0;
1699 
1700 	pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
1701 	init_mlme_default_rate_set(padapter);
1702 
1703 	if ((pmlmeext->cur_channel > 14) || ((padapter->registrypriv.wireless_mode & WIRELESS_11B) == 0)) {
1704 		pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
1705 		pmlmeext->tx_rate_section = OFDM;
1706 	} else {
1707 		pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
1708 		pmlmeext->tx_rate_section = CCK;
1709 	}
1710 
1711 	mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
1712 	pmlmeext->sitesurvey_res.channel_idx = 0;
1713 	pmlmeext->sitesurvey_res.bss_cnt = 0;
1714 	pmlmeext->sitesurvey_res.scan_ch_ms = SURVEY_TO;
1715 	pmlmeext->sitesurvey_res.rx_ampdu_accept = RX_AMPDU_ACCEPT_INVALID;
1716 	pmlmeext->sitesurvey_res.rx_ampdu_size = RX_AMPDU_SIZE_INVALID;
1717 #ifdef CONFIG_SCAN_BACKOP
1718 #ifdef CONFIG_LAYER2_ROAMING
1719 	if (padapter->mlmepriv.roam_flags & BIT2)
1720 		mlmeext_assign_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME);
1721 	else
1722 #endif
1723 		mlmeext_assign_scan_backop_flags_sta(pmlmeext, /*SS_BACKOP_EN |*/ SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME);
1724 	#ifdef CONFIG_AP_MODE
1725 		#ifdef CONFIG_CUSTOMER_EZVIZ_CHIME2
1726 			mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME | SS_BACKOP_EN_NL);
1727 		#else
1728 			mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME);
1729 		#endif
1730 	#endif
1731 	#ifdef CONFIG_RTW_MESH
1732 	mlmeext_assign_scan_backop_flags_mesh(pmlmeext, /*SS_BACKOP_EN | */SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME);
1733 	#endif
1734 	pmlmeext->sitesurvey_res.scan_cnt = 0;
1735 	pmlmeext->sitesurvey_res.scan_cnt_max = RTW_SCAN_NUM_OF_CH;
1736 	pmlmeext->sitesurvey_res.backop_ms = RTW_BACK_OP_CH_MS;
1737 #endif
1738 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
1739 	pmlmeext->sitesurvey_res.is_sw_antdiv_bl_scan = 0;
1740 #endif
1741 	pmlmeext->scan_abort = _FALSE;
1742 
1743 	pmlmeinfo->state = WIFI_FW_NULL_STATE;
1744 	pmlmeinfo->reauth_count = 0;
1745 	pmlmeinfo->reassoc_count = 0;
1746 	pmlmeinfo->link_count = 0;
1747 	pmlmeinfo->auth_seq = 0;
1748 	pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1749 	pmlmeinfo->key_index = 0;
1750 	pmlmeinfo->iv = 0;
1751 
1752 	pmlmeinfo->enc_algo = _NO_PRIVACY_;
1753 	pmlmeinfo->authModeToggle = 0;
1754 
1755 	_rtw_memset(pmlmeinfo->chg_txt, 0, 128);
1756 
1757 	pmlmeinfo->slotTime = SHORT_SLOT_TIME;
1758 	pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
1759 
1760 	pmlmeinfo->dialogToken = 0;
1761 
1762 	pmlmeext->action_public_rxseq = 0xffff;
1763 	pmlmeext->action_public_dialog_token = 0xff;
1764 #ifdef ROKU_PRIVATE
1765 /*infra mode, used to store AP's info*/
1766 	_rtw_memset(pmlmeinfo->SupportedRates_infra_ap, 0, NDIS_802_11_LENGTH_RATES_EX);
1767 	pmlmeinfo->ht_vht_received = 0;
1768 #endif /* ROKU_PRIVATE */
1769 #ifdef CONFIG_WRITE_BCN_LEN_TO_FW
1770 	pmlmeinfo->last_bcn_len = 0;
1771 #endif
1772 }
1773 
init_mlme_ext_timer(_adapter * padapter)1774 void init_mlme_ext_timer(_adapter *padapter)
1775 {
1776 	struct	mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1777 
1778 	rtw_init_timer(&pmlmeext->survey_timer, padapter, survey_timer_hdl, padapter);
1779 	rtw_init_timer(&pmlmeext->link_timer, padapter, link_timer_hdl, padapter);
1780 #ifdef CONFIG_RTW_80211R
1781 	rtw_init_timer(&pmlmeext->ft_link_timer, padapter, rtw_ft_link_timer_hdl, padapter);
1782 	rtw_init_timer(&pmlmeext->ft_roam_timer, padapter, rtw_ft_roam_timer_hdl, padapter);
1783 #endif
1784 
1785 #ifdef CONFIG_RTW_REPEATER_SON
1786 	rtw_init_timer(&pmlmeext->rson_scan_timer, padapter, rson_timer_hdl, padapter);
1787 #endif
1788 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
1789 	rtw_init_timer(&pmlmeext->tbtx_xmit_timer, padapter, rtw_tbtx_xmit_timer_hdl, padapter);
1790 	rtw_init_timer(&pmlmeext->tbtx_token_dispatch_timer, padapter, rtw_tbtx_token_dispatch_timer_hdl, padapter);
1791 #endif
1792 #ifdef CONFIG_DFS
1793 	rtw_init_timer(&pmlmeext->csa_timer, padapter->pnetdev, csa_timer_hdl, padapter);
1794 #endif
1795 }
1796 
init_mlme_ext_priv(_adapter * padapter)1797 int	init_mlme_ext_priv(_adapter *padapter)
1798 {
1799 	int	res = _SUCCESS;
1800 	struct registry_priv *pregistrypriv = &padapter->registrypriv;
1801 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1802 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
1803 
1804 	/* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
1805 	/* _rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv)); */
1806 
1807 	pmlmeext->padapter = padapter;
1808 
1809 	/* fill_fwpriv(padapter, &(pmlmeext->fwpriv)); */
1810 
1811 	init_mlme_ext_priv_value(padapter);
1812 	pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
1813 
1814 	init_mlme_ext_timer(padapter);
1815 
1816 #ifdef CONFIG_AP_MODE
1817 	init_mlme_ap_info(padapter);
1818 #endif
1819 
1820 	pmlmeext->last_scan_time = 0;
1821 	pmlmeext->mlmeext_init = _TRUE;
1822 
1823 
1824 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
1825 	pmlmeext->active_keep_alive_check = _TRUE;
1826 #else
1827 	pmlmeext->active_keep_alive_check = _FALSE;
1828 #endif
1829 
1830 #ifdef DBG_FIXED_CHAN
1831 	pmlmeext->fixed_chan = 0xFF;
1832 #endif
1833 
1834 	pmlmeext->tsf_update_pause_factor = pregistrypriv->tsf_update_pause_factor;
1835 	pmlmeext->tsf_update_restore_factor = pregistrypriv->tsf_update_restore_factor;
1836 
1837 #ifdef CONFIG_SUPPORT_STATIC_SMPS
1838 	pmlmeext->ssmps_en = _FALSE;
1839 	pmlmeext->ssmps_tx_tp_th = SSMPS_TX_TP_TH;/*Mbps*/
1840 	pmlmeext->ssmps_rx_tp_th = SSMPS_RX_TP_TH;/*Mbps*/
1841 	#ifdef DBG_STATIC_SMPS
1842 	pmlmeext->ssmps_test = _FALSE;
1843 	#endif
1844 #endif
1845 
1846 #ifdef CONFIG_CTRL_TXSS_BY_TP
1847 	pmlmeext->txss_ctrl_en = _TRUE;
1848 	pmlmeext->txss_tp_th = TXSS_TP_TH;
1849 	pmlmeext->txss_tp_chk_cnt = TXSS_TP_CHK_CNT;
1850 #endif
1851 
1852 	return res;
1853 
1854 }
1855 
free_mlme_ext_priv(struct mlme_ext_priv * pmlmeext)1856 void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext)
1857 {
1858 	_adapter *padapter = pmlmeext->padapter;
1859 
1860 	if (!padapter)
1861 		return;
1862 
1863 	if (rtw_is_drv_stopped(padapter)) {
1864 		_cancel_timer_ex(&pmlmeext->survey_timer);
1865 		_cancel_timer_ex(&pmlmeext->link_timer);
1866 #ifdef CONFIG_DFS
1867 		_cancel_timer_ex(&pmlmeext->csa_timer);
1868 #endif /* CONFIG_DFS */
1869 	}
1870 }
1871 
1872 #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
cmp_pkt_chnl_diff(_adapter * padapter,u8 * pframe,uint packet_len)1873 static u8 cmp_pkt_chnl_diff(_adapter *padapter, u8 *pframe, uint packet_len)
1874 {
1875 	/* if the channel is same, return 0. else return channel differential	 */
1876 	uint len;
1877 	u8 channel;
1878 	u8 *p;
1879 
1880 	p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);
1881 	if (p) {
1882 		channel = *(p + 2);
1883 		if (padapter->mlmeextpriv.cur_channel >= channel)
1884 			return padapter->mlmeextpriv.cur_channel - channel;
1885 		else
1886 			return channel - padapter->mlmeextpriv.cur_channel;
1887 	} else
1888 		return 0;
1889 }
1890 #endif /* CONFIG_PATCH_JOIN_WRONG_CHANNEL */
1891 
_mgt_dispatcher(_adapter * padapter,struct mlme_handler * ptable,union recv_frame * precv_frame)1892 static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
1893 {
1894 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1895 	u8 *pframe = precv_frame->u.hdr.rx_data;
1896 
1897 	if (ptable->func) {
1898 		/* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
1899 		if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1900 		    !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1901 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
1902 		{
1903 			struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
1904 
1905 			if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) != _TRUE)
1906 				return;
1907 
1908 		    if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE)
1909 				return;
1910 
1911 		    if ( pwdev_priv->pno_mac_addr[0] == 0xFF)
1912 				return;
1913 
1914 		    if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_pno_mac_addr(padapter), ETH_ALEN))
1915 				return;
1916 		}
1917 #else
1918 			return;
1919 #endif
1920 
1921 		ptable->func(padapter, precv_frame);
1922 	}
1923 
1924 }
1925 
mgt_dispatcher(_adapter * padapter,union recv_frame * precv_frame)1926 void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
1927 {
1928 	int index;
1929 	struct mlme_handler *ptable;
1930 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1931 	u8 *pframe = precv_frame->u.hdr.rx_data;
1932 	struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, get_addr2_ptr(pframe));
1933 	struct recv_priv  *precvpriv = &padapter->recvpriv;
1934 
1935 
1936 #if 0
1937 	{
1938 		u8 *pbuf;
1939 		pbuf = GetAddr1Ptr(pframe);
1940 		RTW_INFO("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf + 1), *(pbuf + 2), *(pbuf + 3), *(pbuf + 4), *(pbuf + 5));
1941 		pbuf = get_addr2_ptr(pframe);
1942 		RTW_INFO("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf + 1), *(pbuf + 2), *(pbuf + 3), *(pbuf + 4), *(pbuf + 5));
1943 		pbuf = GetAddr3Ptr(pframe);
1944 		RTW_INFO("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf + 1), *(pbuf + 2), *(pbuf + 3), *(pbuf + 4), *(pbuf + 5));
1945 	}
1946 #endif
1947 
1948 	if (GetFrameType(pframe) != WIFI_MGT_TYPE) {
1949 		return;
1950 	}
1951 
1952 	/* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
1953 	if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1954 	    !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1955 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
1956 		{
1957 			struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
1958 
1959 			if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) != _TRUE)
1960 				return;
1961 
1962 			if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE)
1963 				return;
1964 
1965 			if ( pwdev_priv->pno_mac_addr[0] == 0xFF)
1966 				return;
1967 
1968 			if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_pno_mac_addr(padapter), ETH_ALEN))
1969 				return;
1970 		}
1971 #else
1972 		return;
1973 #endif
1974 
1975 	ptable = mlme_sta_tbl;
1976 
1977 	index = get_frame_sub_type(pframe) >> 4;
1978 
1979 #ifdef CONFIG_TDLS
1980 	if ((index << 4) == WIFI_ACTION) {
1981 		/* category==public (4), action==TDLS_DISCOVERY_RESPONSE */
1982 		if (*(pframe + 24) == RTW_WLAN_CATEGORY_PUBLIC && *(pframe + 25) == TDLS_DISCOVERY_RESPONSE) {
1983 			RTW_INFO("[TDLS] Recv %s from "MAC_FMT"\n", rtw_tdls_action_txt(TDLS_DISCOVERY_RESPONSE), MAC_ARG(get_addr2_ptr(pframe)));
1984 			On_TDLS_Dis_Rsp(padapter, precv_frame);
1985 		}
1986 	}
1987 #endif /* CONFIG_TDLS */
1988 
1989 	if (index >= (sizeof(mlme_sta_tbl) / sizeof(struct mlme_handler))) {
1990 		return;
1991 	}
1992 	ptable += index;
1993 
1994 #if 1
1995 	if (psta != NULL) {
1996 		if (GetRetry(pframe)) {
1997 			if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum) {
1998 				/* drop the duplicate management frame */
1999 				precvpriv->dbg_rx_dup_mgt_frame_drop_count++;
2000 				RTW_INFO("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
2001 				return;
2002 			}
2003 		}
2004 		psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
2005 	}
2006 #else
2007 
2008 	if (GetRetry(pframe)) {
2009 		/* return; */
2010 	}
2011 #endif
2012 
2013 #ifdef CONFIG_AP_MODE
2014 	switch (get_frame_sub_type(pframe)) {
2015 	case WIFI_AUTH:
2016 		if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter))
2017 			ptable->func = &OnAuth;
2018 		else
2019 			ptable->func = &OnAuthClient;
2020 		fallthrough;
2021 		/* fall through */
2022 	case WIFI_ASSOCREQ:
2023 	case WIFI_REASSOCREQ:
2024 		_mgt_dispatcher(padapter, ptable, precv_frame);
2025 		#ifdef CONFIG_HOSTAPD_MLME
2026 		if (MLME_IS_AP(padapter))
2027 			rtw_hostapd_mlme_rx(padapter, precv_frame);
2028 		#endif
2029 		break;
2030 	case WIFI_PROBEREQ:
2031 		_mgt_dispatcher(padapter, ptable, precv_frame);
2032 		#ifdef CONFIG_HOSTAPD_MLME
2033 		if (MLME_IS_AP(padapter))
2034 			rtw_hostapd_mlme_rx(padapter, precv_frame);
2035 		#endif
2036 		break;
2037 	case WIFI_BEACON:
2038 		_mgt_dispatcher(padapter, ptable, precv_frame);
2039 		break;
2040 	case WIFI_ACTION:
2041 		_mgt_dispatcher(padapter, ptable, precv_frame);
2042 		break;
2043 	default:
2044 		_mgt_dispatcher(padapter, ptable, precv_frame);
2045 		#ifdef CONFIG_HOSTAPD_MLME
2046 		if (MLME_IS_AP(padapter))
2047 			rtw_hostapd_mlme_rx(padapter, precv_frame);
2048 		#endif
2049 		break;
2050 	}
2051 #else
2052 
2053 	_mgt_dispatcher(padapter, ptable, precv_frame);
2054 
2055 #endif
2056 
2057 }
2058 
2059 #ifdef CONFIG_P2P
p2p_listen_state_process(_adapter * padapter,unsigned char * da)2060 u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
2061 {
2062 	bool response = _TRUE;
2063 
2064 #ifdef CONFIG_IOCTL_CFG80211
2065 	if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {
2066 		if (rtw_cfg80211_get_is_roch(padapter) == _FALSE
2067 			|| rtw_get_oper_ch(padapter) != padapter->wdinfo.listen_channel
2068 			|| adapter_wdev_data(padapter)->p2p_enabled == _FALSE
2069 			|| padapter->mlmepriv.wps_probe_resp_ie == NULL
2070 			|| padapter->mlmepriv.p2p_probe_resp_ie == NULL
2071 		) {
2072 #ifdef CONFIG_DEBUG_CFG80211
2073 			RTW_INFO(ADPT_FMT" DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p\n"
2074 				, ADPT_ARG(padapter)
2075 				, adapter_wdev_data(padapter)->p2p_enabled
2076 				, padapter->mlmepriv.wps_probe_resp_ie
2077 				, padapter->mlmepriv.p2p_probe_resp_ie);
2078 			RTW_INFO(ADPT_FMT" DON'T issue_probersp_p2p: is_ro_ch:%d, op_ch:%d, p2p_listen_channel:%d\n"
2079 				, ADPT_ARG(padapter)
2080 				, rtw_cfg80211_get_is_roch(padapter)
2081 				, rtw_get_oper_ch(padapter)
2082 				, padapter->wdinfo.listen_channel);
2083 #endif
2084 			response = _FALSE;
2085 		}
2086 	} else
2087 #endif /* CONFIG_IOCTL_CFG80211 */
2088 		if (padapter->wdinfo.driver_interface == DRIVER_WEXT) {
2089 			/*	do nothing if the device name is empty */
2090 			if (!padapter->wdinfo.device_name_len)
2091 				response	= _FALSE;
2092 		}
2093 
2094 	if (response == _TRUE)
2095 		issue_probersp_p2p(padapter, da);
2096 
2097 	return _SUCCESS;
2098 }
2099 #endif /* CONFIG_P2P */
2100 
2101 
2102 /****************************************************************************
2103 
2104 Following are the callback functions for each subtype of the management frames
2105 
2106 *****************************************************************************/
2107 
OnProbeReq(_adapter * padapter,union recv_frame * precv_frame)2108 unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
2109 {
2110 	unsigned int	ielen;
2111 	unsigned char	*p;
2112 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2113 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2114 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
2115 	WLAN_BSSID_EX	*cur = &(pmlmeinfo->network);
2116 	u8 *pframe = precv_frame->u.hdr.rx_data;
2117 	uint len = precv_frame->u.hdr.len;
2118 	u8 is_valid_p2p_probereq = _FALSE;
2119 
2120 #ifdef CONFIG_ATMEL_RC_PATCH
2121 	u8 *target_ie = NULL, *wps_ie = NULL;
2122 	u8 *start;
2123 	uint search_len = 0, wps_ielen = 0, target_ielen = 0;
2124 	struct sta_info	*psta;
2125 	struct sta_priv *pstapriv = &padapter->stapriv;
2126 #endif
2127 
2128 #ifdef CONFIG_P2P
2129 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
2130 	struct rx_pkt_attrib	*pattrib = &precv_frame->u.hdr.attrib;
2131 	u8 wifi_test_chk_rate = 1;
2132 
2133 #ifdef CONFIG_IOCTL_CFG80211
2134 #ifdef CONFIG_P2P
2135 	if ((adapter_to_dvobj(padapter)->wpas_type == RTW_WPAS_W1FI) &&
2136 		!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
2137 		(GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter),
2138 				IEEE80211_STYPE_PROBE_REQ) == _TRUE)) {
2139 		rtw_cfg80211_rx_probe_request(padapter, precv_frame);
2140 		return _SUCCESS;
2141 	}
2142 #endif
2143 #endif /* CONFIG_IOCTL_CFG80211 */
2144 
2145 	if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
2146 	    !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
2147 	    !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
2148 	    !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
2149 	    !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
2150 	   ) {
2151 		/*	Commented by Albert 2011/03/17 */
2152 		/*	mcs_rate = 0->CCK 1M rate */
2153 		/*	mcs_rate = 1->CCK 2M rate */
2154 		/*	mcs_rate = 2->CCK 5.5M rate */
2155 		/*	mcs_rate = 3->CCK 11M rate */
2156 		/*	In the P2P mode, the driver should not support the CCK rate */
2157 
2158 		/*	Commented by Kurt 2012/10/16 */
2159 		/*	IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client */
2160 		if (padapter->registrypriv.wifi_spec == 1) {
2161 			if (pattrib->data_rate <= DESC_RATE11M)
2162 				wifi_test_chk_rate = 0;
2163 		}
2164 
2165 		if (wifi_test_chk_rate == 1) {
2166 			is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len);
2167 			if (is_valid_p2p_probereq == _TRUE) {
2168 				if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) {
2169 					/* FIXME */
2170 					if (padapter->wdinfo.driver_interface == DRIVER_WEXT)
2171 						report_survey_event(padapter, precv_frame);
2172 
2173 					p2p_listen_state_process(padapter,  get_sa(pframe));
2174 
2175 					return _SUCCESS;
2176 				}
2177 
2178 				if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2179 					goto _continue;
2180 			}
2181 		}
2182 	}
2183 
2184 _continue:
2185 #endif /* CONFIG_P2P */
2186 
2187 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
2188 		return _SUCCESS;
2189 
2190 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE &&
2191 	    check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE | WIFI_MESH_STATE) == _FALSE)
2192 		return _SUCCESS;
2193 
2194 
2195 	/* RTW_INFO("+OnProbeReq\n"); */
2196 
2197 
2198 #ifdef CONFIG_ATMEL_RC_PATCH
2199 	wps_ie = rtw_get_wps_ie(
2200 			      pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_,
2201 			      len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_,
2202 			      NULL, &wps_ielen);
2203 	if (wps_ie)
2204 		target_ie = rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_MANUFACTURER, NULL, &target_ielen);
2205 	if ((target_ie && (target_ielen == 4)) && (_TRUE == _rtw_memcmp((void *)target_ie, "Ozmo", 4))) {
2206 		/* psta->flag_atmel_rc = 1; */
2207 		unsigned char *sa_addr = get_sa(pframe);
2208 		printk("%s: Find Ozmo RC -- %02x:%02x:%02x:%02x:%02x:%02x  \n\n",
2209 		       __func__, *sa_addr, *(sa_addr + 1), *(sa_addr + 2), *(sa_addr + 3), *(sa_addr + 4), *(sa_addr + 5));
2210 		_rtw_memcpy(pstapriv->atmel_rc_pattern, get_sa(pframe), ETH_ALEN);
2211 	}
2212 #endif
2213 
2214 
2215 #ifdef CONFIG_AUTO_AP_MODE
2216 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE &&
2217 	    pmlmepriv->cur_network.join_res == _TRUE) {
2218 		_irqL	irqL;
2219 		struct sta_info	*psta;
2220 		u8 *mac_addr, *peer_addr;
2221 		struct sta_priv *pstapriv = &padapter->stapriv;
2222 		u8 RC_OUI[4] = {0x00, 0xE0, 0x4C, 0x0A};
2223 		/* EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] */
2224 
2225 		p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
2226 			       len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
2227 
2228 		if (!p || ielen != 14)
2229 			goto _non_rc_device;
2230 
2231 		if (!_rtw_memcmp(p + 2, RC_OUI, sizeof(RC_OUI)))
2232 			goto _non_rc_device;
2233 
2234 		if (!_rtw_memcmp(p + 6, get_sa(pframe), ETH_ALEN)) {
2235 			RTW_INFO("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__,
2236 				 MAC_ARG(get_sa(pframe)), MAC_ARG(p + 6));
2237 
2238 			goto _non_rc_device;
2239 		}
2240 
2241 		RTW_INFO("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__,  MAC_ARG(get_sa(pframe)));
2242 
2243 		/* new a station */
2244 		psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
2245 		if (psta == NULL) {
2246 			/* allocate a new one */
2247 			RTW_INFO("going to alloc stainfo for rc="MAC_FMT"\n",  MAC_ARG(get_sa(pframe)));
2248 			psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
2249 			if (psta == NULL) {
2250 				/* TODO: */
2251 				RTW_INFO(" Exceed the upper limit of supported clients...\n");
2252 				return _SUCCESS;
2253 			}
2254 
2255 			_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2256 			if (rtw_is_list_empty(&psta->asoc_list)) {
2257 				psta->expire_to = pstapriv->expire_to;
2258 				rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list);
2259 				pstapriv->asoc_list_cnt++;
2260 				#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
2261 				if (psta->tbtx_enable)
2262 					pstapriv->tbtx_asoc_list_cnt++;
2263 				#endif
2264 			}
2265 			_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2266 
2267 			/* generate pairing ID */
2268 			mac_addr = adapter_mac_addr(padapter);
2269 			peer_addr = psta->cmn.mac_addr;
2270 			psta->pid = (u16)(((mac_addr[4] << 8) + mac_addr[5]) + ((peer_addr[4] << 8) + peer_addr[5]));
2271 
2272 			/* update peer stainfo */
2273 			psta->isrc = _TRUE;
2274 
2275 			/* AID assignment */
2276 			if (psta->cmn.aid > 0)
2277 				RTW_INFO(FUNC_ADPT_FMT" old AID=%d\n", FUNC_ADPT_ARG(padapter), psta->cmn.aid);
2278 			else {
2279 				if (!rtw_aid_alloc(padapter, psta)) {
2280 					RTW_INFO(FUNC_ADPT_FMT" no room for more AIDs\n", FUNC_ADPT_ARG(padapter));
2281 					return _SUCCESS;
2282 				}
2283 				RTW_INFO(FUNC_ADPT_FMT" allocate new AID=%d\n", FUNC_ADPT_ARG(padapter), psta->cmn.aid);
2284 			}
2285 
2286 			psta->qos_option = 1;
2287 			psta->cmn.bw_mode = CHANNEL_WIDTH_20;
2288 			psta->ieee8021x_blocked = _FALSE;
2289 #ifdef CONFIG_80211N_HT
2290 			if(padapter->registrypriv.ht_enable &&
2291 				is_supported_ht(padapter->registrypriv.wireless_mode)) {
2292 				psta->htpriv.ht_option = _TRUE;
2293 				psta->htpriv.ampdu_enable = _FALSE;
2294 				psta->htpriv.sgi_20m = _FALSE;
2295 				psta->htpriv.sgi_40m = _FALSE;
2296 				psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2297 				psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
2298 				psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
2299 			}
2300 #endif
2301 
2302 			rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
2303 
2304 			_rtw_memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
2305 
2306 			_enter_critical_bh(&psta->lock, &irqL);
2307 			psta->state |= WIFI_ASOC_STATE;
2308 			_exit_critical_bh(&psta->lock, &irqL);
2309 
2310 			report_add_sta_event(padapter, psta->cmn.mac_addr);
2311 
2312 		}
2313 
2314 		issue_probersp(padapter, get_sa(pframe), _FALSE);
2315 
2316 		return _SUCCESS;
2317 
2318 	}
2319 
2320 _non_rc_device:
2321 
2322 	return _SUCCESS;
2323 
2324 #endif /* CONFIG_AUTO_AP_MODE */
2325 
2326 
2327 #ifdef CONFIG_CONCURRENT_MODE
2328 	if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) &&
2329 	    rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING | WIFI_UNDER_SURVEY)) {
2330 		/* don't process probe req */
2331 		return _SUCCESS;
2332 	}
2333 #endif
2334 
2335 	p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
2336 		       len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
2337 
2338 
2339 	/* check (wildcard) SSID */
2340 	if (p != NULL) {
2341 		if (is_valid_p2p_probereq == _TRUE)
2342 			goto _issue_probersp;
2343 
2344 		if ((ielen != 0 && _FALSE == _rtw_memcmp((void *)(p + 2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
2345 			|| (ielen == 0 && pmlmeinfo->hidden_ssid_mode))
2346 			goto exit;
2347 
2348 		#ifdef CONFIG_RTW_MESH
2349 		if (MLME_IS_MESH(padapter)) {
2350 			p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, WLAN_EID_MESH_ID, (int *)&ielen,
2351 					len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
2352 
2353 			if (!p)
2354 				goto exit;
2355 			if (ielen != 0 && _rtw_memcmp((void *)(p + 2), (void *)cur->mesh_id.Ssid, cur->mesh_id.SsidLength) == _FALSE)
2356 				goto exit;
2357 		}
2358 		#endif
2359 
2360 _issue_probersp:
2361 		if (((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE &&
2362 		      pmlmepriv->cur_network.join_res == _TRUE)) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
2363 			/* RTW_INFO("+issue_probersp during ap mode\n"); */
2364 			issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
2365 		}
2366 
2367 	}
2368 
2369 exit:
2370 	return _SUCCESS;
2371 
2372 }
2373 
OnProbeRsp(_adapter * padapter,union recv_frame * precv_frame)2374 unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
2375 {
2376 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
2377 	u8	*pframe = precv_frame->u.hdr.rx_data;
2378 #ifdef CONFIG_P2P
2379 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
2380 #endif
2381 
2382 
2383 #ifdef CONFIG_P2P
2384 	if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) {
2385 		if (_TRUE == pwdinfo->tx_prov_disc_info.benable) {
2386 			if (_rtw_memcmp(pwdinfo->tx_prov_disc_info.peerIFAddr, get_addr2_ptr(pframe), ETH_ALEN)) {
2387 				if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
2388 					pwdinfo->tx_prov_disc_info.benable = _FALSE;
2389 					issue_p2p_provision_request(padapter,
2390 						pwdinfo->tx_prov_disc_info.ssid.Ssid,
2391 						pwdinfo->tx_prov_disc_info.ssid.SsidLength,
2392 						pwdinfo->tx_prov_disc_info.peerDevAddr);
2393 				} else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
2394 					pwdinfo->tx_prov_disc_info.benable = _FALSE;
2395 					issue_p2p_provision_request(padapter,
2396 								    NULL,
2397 								    0,
2398 						pwdinfo->tx_prov_disc_info.peerDevAddr);
2399 				}
2400 			}
2401 		}
2402 		return _SUCCESS;
2403 	} else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
2404 		if (_TRUE == pwdinfo->nego_req_info.benable) {
2405 			RTW_INFO("[%s] P2P State is GONEGO ING!\n", __FUNCTION__);
2406 			if (_rtw_memcmp(pwdinfo->nego_req_info.peerDevAddr, get_addr2_ptr(pframe), ETH_ALEN)) {
2407 				pwdinfo->nego_req_info.benable = _FALSE;
2408 				issue_p2p_GO_request(padapter, pwdinfo->nego_req_info.peerDevAddr);
2409 			}
2410 		}
2411 	} else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) {
2412 		if (_TRUE == pwdinfo->invitereq_info.benable) {
2413 			RTW_INFO("[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__);
2414 			if (_rtw_memcmp(pwdinfo->invitereq_info.peer_macaddr, get_addr2_ptr(pframe), ETH_ALEN)) {
2415 				pwdinfo->invitereq_info.benable = _FALSE;
2416 				issue_p2p_invitation_request(padapter, pwdinfo->invitereq_info.peer_macaddr);
2417 			}
2418 		}
2419 	}
2420 #endif
2421 
2422 
2423 	if ((mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS))
2424 		|| (MLME_IS_MESH(padapter) && check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE))
2425 		#ifdef CONFIG_RTW_REPEATER_SON
2426 		|| (padapter->rtw_rson_scanstage == RSON_SCAN_PROCESS)
2427 		#endif
2428 	) {
2429 		struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2430 
2431 		if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)
2432 			&& (pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
2433 		) {
2434 			if (!rtw_check_bcn_info(padapter, pframe, precv_frame->u.hdr.len)) {
2435 				RTW_PRINT(FUNC_ADPT_FMT" ap has changed, disconnect now\n", FUNC_ADPT_ARG(padapter));
2436 				receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0, _FALSE);
2437 			}
2438 		}
2439 
2440 		rtw_mi_report_survey_event(padapter, precv_frame);
2441 		return _SUCCESS;
2442 	}
2443 
2444 #if 0 /* move to validate_recv_mgnt_frame */
2445 	if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) {
2446 		if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
2447 			psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
2448 			if (psta != NULL)
2449 				psta->sta_stats.rx_mgnt_pkts++;
2450 		}
2451 	}
2452 #endif
2453 
2454 	return _SUCCESS;
2455 
2456 }
2457 
2458 /* for 11n Logo 4.2.31/4.2.32 */
2459 #ifdef CONFIG_AP_MODE
rtw_check_legacy_ap(_adapter * padapter,u8 * pframe,u32 len)2460 static void rtw_check_legacy_ap(_adapter *padapter, u8 *pframe, u32 len)
2461 {
2462 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2463 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2464 
2465 	if (!padapter->registrypriv.wifi_spec)
2466 		return;
2467 
2468 	if(!MLME_IS_AP(padapter))
2469 		return;
2470 
2471 	if (pmlmeext->bstart_bss == _TRUE) {
2472 		int left;
2473 		unsigned char *pos;
2474 		struct rtw_ieee802_11_elems elems;
2475 #ifdef CONFIG_80211N_HT
2476 		u16 cur_op_mode;
2477 #endif
2478 		/* checking IEs */
2479 		left = len - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_;
2480 		pos = pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_;
2481 		if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed) {
2482 			RTW_INFO("%s: parse fail for "MAC_FMT"\n", __func__, MAC_ARG(GetAddr3Ptr(pframe)));
2483 			return;
2484 		}
2485 #ifdef CONFIG_80211N_HT
2486 		cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
2487 #endif
2488 		/* for legacy ap */
2489 		if (elems.ht_capabilities == NULL && elems.ht_capabilities_len == 0) {
2490 
2491 			if (0)
2492 				RTW_INFO("%s: "MAC_FMT" is legacy ap\n", __func__, MAC_ARG(GetAddr3Ptr(pframe)));
2493 
2494 			ATOMIC_SET(&pmlmepriv->olbc, _TRUE);
2495 			ATOMIC_SET(&pmlmepriv->olbc_ht, _TRUE);
2496 		}
2497 	}
2498 }
2499 #endif /* CONFIG_AP_MODE */
2500 
OnBeacon(_adapter * padapter,union recv_frame * precv_frame)2501 unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
2502 {
2503 	struct sta_info	*psta;
2504 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
2505 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
2506 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2507 	struct sta_priv	*pstapriv = &padapter->stapriv;
2508 	u8 *pframe = precv_frame->u.hdr.rx_data;
2509 	uint len = precv_frame->u.hdr.len;
2510 	WLAN_BSSID_EX *pbss;
2511 	int ret = _SUCCESS;
2512 #ifdef CONFIG_TDLS
2513 	struct sta_info *ptdls_sta;
2514 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
2515 #ifdef CONFIG_TDLS_CH_SW
2516 	struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
2517 #endif
2518 #endif /* CONFIG_TDLS */
2519 #ifdef	CONFIG_LAYER2_ROAMING
2520 	_irqL irqL;
2521 #endif
2522 
2523 	if (validate_beacon_len(pframe, len) == _FALSE)
2524 		return _SUCCESS;
2525 
2526 	if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)
2527 		|| (MLME_IS_MESH(padapter) && check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
2528 	) {
2529 		if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)
2530 			&& (pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
2531 		) {
2532 			if (!rtw_check_bcn_info(padapter, pframe, len)) {
2533 				RTW_PRINT(FUNC_ADPT_FMT" ap has changed, disconnect now\n", FUNC_ADPT_ARG(padapter));
2534 				receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0, _FALSE);
2535 			}
2536 		}
2537 
2538 		rtw_mi_report_survey_event(padapter, precv_frame);
2539 		return _SUCCESS;
2540 	}
2541 
2542 #ifdef CONFIG_WRITE_BCN_LEN_TO_FW
2543 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
2544 		&& (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) {
2545 		struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
2546 
2547 		if (pmlmeinfo->last_bcn_len != pattrib->pkt_len) {
2548 			pmlmeinfo->last_bcn_len = pattrib->pkt_len;
2549 			rtw_write_bcnlen_to_fw_cmd(padapter, pattrib->pkt_len);
2550 		}
2551 	}
2552 #endif
2553 
2554 #ifdef CONFIG_RTW_REPEATER_SON
2555 	if (padapter->rtw_rson_scanstage == RSON_SCAN_PROCESS)
2556 		rtw_mi_report_survey_event(padapter, precv_frame);
2557 #endif
2558 
2559 #ifdef CONFIG_AP_MODE
2560 	rtw_check_legacy_ap(padapter, pframe, len);
2561 #endif
2562 
2563 	if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) {
2564 		if ((pmlmeinfo->state & WIFI_FW_AUTH_NULL)
2565 			&& (rtw_sta_linking_test_wait_done() || pmlmeext->join_abort)
2566 		) {
2567 			if (rtw_sta_linking_test_force_fail() || pmlmeext->join_abort) {
2568 				set_link_timer(pmlmeext, 1);
2569 				return _SUCCESS;
2570 			}
2571 #ifdef	CONFIG_LAYER2_ROAMING
2572 			_enter_critical_bh(&pmlmepriv->clnt_auth_lock, &irqL);
2573 #endif
2574 			/* we should update current network before auth, or some IE is wrong */
2575 			pbss = (WLAN_BSSID_EX *)rtw_malloc(sizeof(WLAN_BSSID_EX));
2576 			if (pbss) {
2577 				if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
2578 					struct beacon_keys recv_beacon;
2579 
2580 					update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
2581 
2582 					/* update bcn keys */
2583 					if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) {
2584 						RTW_INFO("%s: beacon keys ready\n", __func__);
2585 						_rtw_memcpy(&pmlmepriv->cur_beacon_keys,
2586 							&recv_beacon, sizeof(recv_beacon));
2587 						if (is_hidden_ssid(recv_beacon.ssid, recv_beacon.ssid_len)) {
2588 							_rtw_memcpy(pmlmepriv->cur_beacon_keys.ssid, pmlmeinfo->network.Ssid.Ssid, IW_ESSID_MAX_SIZE);
2589 							pmlmepriv->cur_beacon_keys.ssid_len = pmlmeinfo->network.Ssid.SsidLength;
2590 						}
2591 					} else {
2592 						RTW_ERR("%s: get beacon keys failed\n", __func__);
2593 						_rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon));
2594 					}
2595 					#ifdef CONFIG_BCN_CNT_CONFIRM_HDL
2596 					pmlmepriv->new_beacon_cnts = 0;
2597 					#endif
2598 				}
2599 				rtw_mfree((u8 *)pbss, sizeof(WLAN_BSSID_EX));
2600 			}
2601 
2602 			/* check the vendor of the assoc AP */
2603 			pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe + sizeof(struct rtw_ieee80211_hdr_3addr), len - sizeof(struct rtw_ieee80211_hdr_3addr));
2604 
2605 			rtw_phydm_update_ap_vendor_ie(padapter);
2606 
2607 			/* update TSF Value */
2608 			update_TSF(pmlmeext, pframe, len);
2609 			pmlmeext->bcn_cnt = 0;
2610 			pmlmeext->last_bcn_cnt = 0;
2611 
2612 #ifdef CONFIG_P2P_PS
2613 			/* Comment by YiWei , in wifi p2p spec the "3.3 P2P Power Management" , "These mechanisms are available in a P2P Group in which only P2P Devices are associated." */
2614 			/* process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)); */
2615 #endif /* CONFIG_P2P_PS */
2616 
2617 #if defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)
2618 			if (padapter->registrypriv.wifi_spec) {
2619 				if (process_p2p_cross_connect_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)) == _FALSE) {
2620 					if (rtw_mi_buddy_check_mlmeinfo_state(padapter, WIFI_FW_AP_STATE)) {
2621 						RTW_PRINT("no issue auth, P2P cross-connect does not permit\n ");
2622 						return _SUCCESS;
2623 					}
2624 				}
2625 			}
2626 #endif /* CONFIG_P2P CONFIG_P2P and CONFIG_CONCURRENT_MODE */
2627 
2628 			/* start auth */
2629 			start_clnt_auth(padapter);
2630 #ifdef	CONFIG_LAYER2_ROAMING
2631 			_exit_critical_bh(&pmlmepriv->clnt_auth_lock, &irqL);
2632 #endif
2633 			return _SUCCESS;
2634 		}
2635 
2636 		if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
2637 			psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
2638 			if (psta != NULL) {
2639 #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
2640 				/* Merge from 8712 FW code */
2641 				if (cmp_pkt_chnl_diff(padapter, pframe, len) != 0) {
2642 					/* join wrong channel, deauth and reconnect           */
2643 					issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
2644 
2645 					report_del_sta_event(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL, _TRUE, _FALSE);
2646 					pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);
2647 					return _SUCCESS;
2648 				}
2649 #endif /* CONFIG_PATCH_JOIN_WRONG_CHANNEL */
2650 #ifdef CONFIG_RTW_80211R
2651 				rtw_ft_update_bcn(padapter, precv_frame);
2652 #endif
2653 				ret = rtw_check_bcn_info(padapter, pframe, len);
2654 				if (!ret) {
2655 					RTW_PRINT(FUNC_ADPT_FMT" ap has changed, disconnect now\n", FUNC_ADPT_ARG(padapter));
2656 					receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0, _FALSE);
2657 					return _SUCCESS;
2658 				}
2659 				/* update WMM, ERP in the beacon */
2660 				/* todo: the timer is used instead of the number of the beacon received */
2661 				if ((sta_rx_pkts(psta) & 0xf) == 0) {
2662 					/* RTW_INFO("update_bcn_info\n"); */
2663 					update_beacon_info(padapter, pframe, len, psta);
2664 				}
2665 
2666 				pmlmepriv->cur_network_scanned->network.Rssi = precv_frame->u.hdr.attrib.phy_info.recv_signal_power;
2667 				pmlmeext->bcn_cnt++;
2668 #ifdef CONFIG_BCN_RECV_TIME
2669 				rtw_rx_bcn_time_update(padapter, len, precv_frame->u.hdr.attrib.data_rate);
2670 #endif
2671 #ifdef CONFIG_TDLS
2672 #ifdef CONFIG_TDLS_CH_SW
2673 				if (rtw_tdls_is_chsw_allowed(padapter) == _TRUE) {
2674 					/* Send TDLS Channel Switch Request when receiving Beacon */
2675 					if ((padapter->tdlsinfo.chsw_info.ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) && (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE)
2676 					    && (pmlmeext->cur_channel == rtw_get_oper_ch(padapter))) {
2677 						ptdls_sta = rtw_get_stainfo(&padapter->stapriv, padapter->tdlsinfo.chsw_info.addr);
2678 						if (ptdls_sta != NULL) {
2679 							if (ptdls_sta->tdls_sta_state | TDLS_LINKED_STATE)
2680 								_set_timer(&ptdls_sta->stay_on_base_chnl_timer, TDLS_CH_SW_STAY_ON_BASE_CHNL_TIMEOUT);
2681 						}
2682 					}
2683 				}
2684 #endif
2685 #endif /* CONFIG_TDLS */
2686 
2687 				#if CONFIG_DFS
2688 				process_csa_ie(padapter
2689 					, pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_
2690 					, len - (WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_));
2691 				#endif
2692 
2693 				#ifdef CONFIG_80211D
2694 				process_country_ie(padapter
2695 					, pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_
2696 					, len - (WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_));
2697 				#endif
2698 
2699 #ifdef CONFIG_P2P_PS
2700 				process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
2701 #endif /* CONFIG_P2P_PS */
2702 
2703 				if (pmlmeext->tsf_update_required && pmlmeext->en_hw_update_tsf)
2704 					rtw_enable_hw_update_tsf_cmd(padapter);
2705 
2706 #if 0 /* move to validate_recv_mgnt_frame */
2707 				psta->sta_stats.rx_mgnt_pkts++;
2708 #endif
2709 			}
2710 
2711 		} else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
2712 			u8 rate_set[16];
2713 			u8 rate_num = 0;
2714 
2715 			psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
2716 			if (psta != NULL) {
2717 				/*
2718 				* update WMM, ERP in the beacon
2719 				* todo: the timer is used instead of the number of the beacon received
2720 				*/
2721 				if ((sta_rx_pkts(psta) & 0xf) == 0)
2722 					update_beacon_info(padapter, pframe, len, psta);
2723 
2724 				if (pmlmeext->tsf_update_required && pmlmeext->en_hw_update_tsf)
2725 					rtw_enable_hw_update_tsf_cmd(padapter);
2726 			} else {
2727 				rtw_ies_get_supported_rate(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_, rate_set, &rate_num);
2728 				if (rate_num == 0) {
2729 					RTW_INFO(FUNC_ADPT_FMT" RX beacon with no supported rate\n", FUNC_ADPT_ARG(padapter));
2730 					goto _END_ONBEACON_;
2731 				}
2732 
2733 				psta = rtw_alloc_stainfo(pstapriv, get_addr2_ptr(pframe));
2734 				if (psta == NULL) {
2735 					RTW_INFO(FUNC_ADPT_FMT" Exceed the upper limit of supported clients\n", FUNC_ADPT_ARG(padapter));
2736 					goto _END_ONBEACON_;
2737 				}
2738 
2739 				psta->expire_to = pstapriv->adhoc_expire_to;
2740 
2741 				_rtw_memcpy(psta->bssrateset, rate_set, rate_num);
2742 				psta->bssratelen = rate_num;
2743 
2744 				/* update TSF Value */
2745 				update_TSF(pmlmeext, pframe, len);
2746 
2747 				/* report sta add event */
2748 				report_add_sta_event(padapter, get_addr2_ptr(pframe));
2749 			}
2750 		}
2751 	}
2752 
2753 _END_ONBEACON_:
2754 
2755 	return _SUCCESS;
2756 
2757 }
2758 
2759 #ifdef CONFIG_AP_MODE
rtw_get_sta_num_by_state(_adapter * padapter,u32 state)2760 static u32 rtw_get_sta_num_by_state(_adapter *padapter, u32 state)
2761 {
2762 	_irqL irqL;
2763 	_list	*plist, *phead;
2764 	u32	index, sta_num = 0;
2765 	struct sta_info *psta = NULL;
2766 	struct sta_priv *pstapriv = &(padapter->stapriv);
2767 
2768 	_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
2769 	for (index = 0; index < NUM_STA; index++) {
2770 		phead = &(pstapriv->sta_hash[index]);
2771 		plist = get_next(phead);
2772 		while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
2773 			psta = LIST_CONTAINOR(plist, struct sta_info , hash_list);
2774 			if ((psta->state & (state)))
2775 				sta_num++;
2776 			plist = get_next(plist);
2777 		}
2778 	}
2779 	_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
2780 
2781 	/* RTW_INFO("%s : waiting for %u sta under linking \n", __func__, sta_num); */
2782 	return sta_num;
2783 }
2784 
rtw_defs_attack_chk(_adapter * padapter)2785 static u8  rtw_defs_attack_chk(_adapter *padapter)
2786 {
2787 	struct mlme_priv *mlme = &(padapter->mlmepriv);
2788 	u8 is_reject = _FALSE;
2789 	u32 sta_limit = 0;
2790 	u32 stime = rtw_systime_to_ms(rtw_get_current_time());
2791 	static u32 ptime = 0;
2792 
2793 	/* RTW_INFO("%s : ptime=%u, stime=%u, diff=%u\n", __func__, ptime, stime, (stime - ptime)); */
2794 	if ((ptime > 0) && ((stime - ptime) < mlme->defs_lmt_time)) {
2795 		sta_limit = rtw_get_sta_num_by_state(padapter, WIFI_FW_LINKING_STATE);
2796 		if (sta_limit >= mlme->defs_lmt_sta)
2797 			is_reject = _TRUE;
2798 	}
2799 
2800 	ptime = stime;
2801 	/* RTW_INFO("%s : current linking num=%u\n", __func__, sta_limit); */
2802 	return is_reject;
2803 }
2804 #endif
2805 
OnAuth(_adapter * padapter,union recv_frame * precv_frame)2806 unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
2807 {
2808 #ifdef CONFIG_AP_MODE
2809 	_irqL irqL;
2810 	unsigned int	auth_mode, seq, ie_len;
2811 	unsigned char	*sa, *p;
2812 	u16	algorithm;
2813 	int	status;
2814 	static struct sta_info stat;
2815 	struct	sta_info	*pstat = NULL;
2816 	struct	sta_priv *pstapriv = &padapter->stapriv;
2817 	struct security_priv *psecuritypriv = &padapter->securitypriv;
2818 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
2819 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
2820 	u8 *pframe = precv_frame->u.hdr.rx_data;
2821 	uint len = precv_frame->u.hdr.len;
2822 	u8	offset = 0;
2823 
2824 
2825 #ifdef CONFIG_CONCURRENT_MODE
2826 	if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) &&
2827 	    rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING | WIFI_UNDER_SURVEY)) {
2828 		/* don't process auth request; */
2829 		return _SUCCESS;
2830 	}
2831 #endif /* CONFIG_CONCURRENT_MODE */
2832 
2833 	if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
2834 		return _FAIL;
2835 
2836 	if (!MLME_IS_ASOC(padapter))
2837 		return _SUCCESS;
2838 
2839 #if defined(CONFIG_IOCTL_CFG80211) && defined(CONFIG_RTW_MESH)
2840 	if (MLME_IS_MESH(padapter))
2841 		return rtw_mesh_on_auth(padapter, precv_frame);
2842 #endif
2843 
2844 	RTW_INFO("+OnAuth from "MAC_FMT"\n", MAC_ARG(get_addr2_ptr(pframe)));
2845 
2846 	sa = get_addr2_ptr(pframe);
2847 
2848 	auth_mode = psecuritypriv->dot11AuthAlgrthm;
2849 
2850 	if (GetPrivacy(pframe)) {
2851 		u8	*iv;
2852 		struct rx_pkt_attrib	*prxattrib = &(precv_frame->u.hdr.attrib);
2853 
2854 		prxattrib->hdrlen = WLAN_HDR_A3_LEN;
2855 		prxattrib->encrypt = _WEP40_;
2856 
2857 		iv = pframe + prxattrib->hdrlen;
2858 		prxattrib->key_index = ((iv[3] >> 6) & 0x3);
2859 
2860 		prxattrib->iv_len = 4;
2861 		prxattrib->icv_len = 4;
2862 
2863 		rtw_wep_decrypt(padapter, (u8 *)precv_frame);
2864 
2865 		offset = 4;
2866 	}
2867 
2868 	algorithm = le16_to_cpu(*(u16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
2869 	seq	= le16_to_cpu(*(u16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
2870 
2871 	RTW_INFO("auth alg=%x, seq=%X\n", algorithm, seq);
2872 
2873 	if (rtw_check_invalid_mac_address(sa, _FALSE)){
2874 		RTW_INFO("%s : reject invalid AUTH-req "MAC_FMT"\n",
2875 			__func__, MAC_ARG(get_addr2_ptr(pframe)));
2876 		return _FAIL;
2877 	}
2878 
2879 	if(rtw_defs_attack_chk(padapter))  {
2880 		struct sta_info *_psta;
2881 		_psta = rtw_get_stainfo(pstapriv, sa);
2882 		if ((_psta == NULL) || !(_psta->state & WIFI_FW_ASSOC_SUCCESS)) {
2883 			status = _STATS_REFUSED_TEMPORARILY_;
2884 			RTW_ERR("%s : refused temporarily for sa "MAC_FMT" !\n", __func__, MAC_ARG(sa));
2885 			goto auth_fail;
2886 		}
2887 	}
2888 
2889 	if (rtw_ap_linking_test_force_auth_fail()) {
2890 		status = rtw_ap_linking_test_force_auth_fail();
2891 		RTW_INFO(FUNC_ADPT_FMT" force auth fail with status:%u\n"
2892 			, FUNC_ADPT_ARG(padapter), status);
2893 		goto auth_fail;
2894 	}
2895 
2896 	if ((auth_mode == 2) && (algorithm != WLAN_AUTH_SAE) &&
2897 	    (psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) &&
2898 	    (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_))
2899 		auth_mode = 0;
2900 
2901 	if ((algorithm > 0 && auth_mode == 0) ||	/* rx a shared-key auth but shared not enabled */
2902 	    (algorithm == 0 && auth_mode == 1)) {	/* rx a open-system auth but shared-key is enabled */
2903 		RTW_INFO("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
2904 			algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
2905 
2906 		status = _STATS_NO_SUPP_ALG_;
2907 
2908 		goto auth_fail;
2909 	}
2910 
2911 #if CONFIG_RTW_MACADDR_ACL
2912 	if (rtw_access_ctrl(padapter, sa) == _FALSE) {
2913 		status = _STATS_UNABLE_HANDLE_STA_;
2914 		goto auth_fail;
2915 	}
2916 #endif
2917 
2918 	pstat = rtw_get_stainfo(pstapriv, sa);
2919 	if (pstat == NULL) {
2920 
2921 		/* allocate a new one */
2922 		RTW_INFO("going to alloc stainfo for sa="MAC_FMT"\n",  MAC_ARG(sa));
2923 		pstat = rtw_alloc_stainfo(pstapriv, sa);
2924 		if (pstat == NULL) {
2925 			RTW_INFO(" Exceed the upper limit of supported clients...\n");
2926 			status = _STATS_UNABLE_HANDLE_STA_;
2927 			goto auth_fail;
2928 		}
2929 
2930 		pstat->state = WIFI_FW_AUTH_NULL;
2931 		pstat->auth_seq = 0;
2932 
2933 		/* pstat->flags = 0; */
2934 		/* pstat->capability = 0; */
2935 	} else {
2936 #ifdef CONFIG_IEEE80211W
2937 		if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
2938 			|| !(pstat->flags & WLAN_STA_MFP))
2939 #endif /* CONFIG_IEEE80211W */
2940 		{
2941 
2942 			_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2943 			if (rtw_is_list_empty(&pstat->asoc_list) == _FALSE) {
2944 				rtw_list_delete(&pstat->asoc_list);
2945 				pstapriv->asoc_list_cnt--;
2946 				#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
2947 				if (pstat->tbtx_enable)
2948 					pstapriv->tbtx_asoc_list_cnt--;
2949 				#endif
2950 				if (pstat->expire_to > 0)
2951 					;/* TODO: STA re_auth within expire_to */
2952 			}
2953 			_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2954 
2955 			if (seq == 1)
2956 				; /* TODO: STA re_auth and auth timeout */
2957 
2958 		}
2959 	}
2960 
2961 #ifdef CONFIG_IEEE80211W
2962 	if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
2963 		|| !(pstat->flags & WLAN_STA_MFP))
2964 #endif /* CONFIG_IEEE80211W */
2965 	{
2966 		_enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2967 		if (rtw_is_list_empty(&pstat->auth_list)) {
2968 
2969 			rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
2970 			pstapriv->auth_list_cnt++;
2971 		}
2972 		_exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2973 	}
2974 
2975 	if (pstat->auth_seq == 0)
2976 		pstat->expire_to = pstapriv->auth_to;
2977 
2978 #ifdef CONFIG_IOCTL_CFG80211
2979 	if (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_AUTH) == _TRUE) {
2980 		if ((algorithm == WLAN_AUTH_SAE) &&
2981 			(auth_mode == dot11AuthAlgrthm_8021X)) {
2982 			pstat->authalg = algorithm;
2983 
2984 			rtw_cfg80211_rx_mframe(padapter, precv_frame, NULL);
2985 			return _SUCCESS;
2986 		}
2987 	}
2988 #endif /* CONFIG_IOCTL_CFG80211 */
2989 
2990 	if ((pstat->auth_seq + 1) != seq) {
2991 		RTW_INFO("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2992 			 seq, pstat->auth_seq + 1);
2993 		status = _STATS_OUT_OF_AUTH_SEQ_;
2994 		goto auth_fail;
2995 	}
2996 
2997 	if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3)) {
2998 		if (seq == 1) {
2999 #ifdef CONFIG_IEEE80211W
3000 			if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
3001 				|| !(pstat->flags & WLAN_STA_MFP))
3002 #endif /* CONFIG_IEEE80211W */
3003 			{
3004 				pstat->state &= ~WIFI_FW_AUTH_NULL;
3005 				pstat->state |= WIFI_FW_AUTH_SUCCESS;
3006 				pstat->expire_to = pstapriv->assoc_to;
3007 			}
3008 			pstat->authalg = algorithm;
3009 		} else {
3010 			RTW_INFO("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
3011 				 seq, pstat->auth_seq + 1);
3012 			status = _STATS_OUT_OF_AUTH_SEQ_;
3013 			goto auth_fail;
3014 		}
3015 	} else { /* shared system or auto authentication */
3016 		if (seq == 1) {
3017 			/* prepare for the challenging txt... */
3018 
3019 			/* get_random_bytes((void *)pstat->chg_txt, 128); */ /* TODO: */
3020 			_rtw_memset((void *)pstat->chg_txt, 78, 128);
3021 #ifdef CONFIG_IEEE80211W
3022 			if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
3023 				|| !(pstat->flags & WLAN_STA_MFP))
3024 #endif /* CONFIG_IEEE80211W */
3025 			{
3026 				pstat->state &= ~WIFI_FW_AUTH_NULL;
3027 				pstat->state |= WIFI_FW_AUTH_STATE;
3028 			}
3029 			pstat->authalg = algorithm;
3030 			pstat->auth_seq = 2;
3031 		} else if (seq == 3) {
3032 			/* checking for challenging txt... */
3033 			RTW_INFO("checking for challenging txt...\n");
3034 
3035 			p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
3036 				len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
3037 
3038 			if ((p == NULL) || (ie_len <= 0)) {
3039 				RTW_INFO("auth rejected because challenge failure!(1)\n");
3040 				status = _STATS_CHALLENGE_FAIL_;
3041 				goto auth_fail;
3042 			}
3043 
3044 			if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128)) {
3045 #ifdef CONFIG_IEEE80211W
3046 				if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
3047 					|| !(pstat->flags & WLAN_STA_MFP))
3048 #endif /* CONFIG_IEEE80211W */
3049 				{
3050 					pstat->state &= (~WIFI_FW_AUTH_STATE);
3051 					pstat->state |= WIFI_FW_AUTH_SUCCESS;
3052 					/* challenging txt is correct... */
3053 					pstat->expire_to =  pstapriv->assoc_to;
3054 				}
3055 			} else {
3056 				RTW_INFO("auth rejected because challenge failure!\n");
3057 				status = _STATS_CHALLENGE_FAIL_;
3058 				goto auth_fail;
3059 			}
3060 		} else {
3061 			RTW_INFO("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
3062 				 seq, pstat->auth_seq + 1);
3063 			status = _STATS_OUT_OF_AUTH_SEQ_;
3064 			goto auth_fail;
3065 		}
3066 	}
3067 
3068 
3069 	/* Now, we are going to issue_auth... */
3070 	pstat->auth_seq = seq + 1;
3071 
3072 #ifdef CONFIG_NATIVEAP_MLME
3073 	issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
3074 #endif
3075 
3076 	if ((pstat->state & WIFI_FW_AUTH_SUCCESS) || (pstat->state & WIFI_FW_ASSOC_SUCCESS))
3077 		pstat->auth_seq = 0;
3078 
3079 
3080 	return _SUCCESS;
3081 
3082 auth_fail:
3083 
3084 	if (pstat)
3085 		rtw_free_stainfo(padapter , pstat);
3086 
3087 	pstat = &stat;
3088 	_rtw_memset((char *)pstat, '\0', sizeof(stat));
3089 	pstat->auth_seq = 2;
3090 	_rtw_memcpy(pstat->cmn.mac_addr, sa, ETH_ALEN);
3091 
3092 #ifdef CONFIG_NATIVEAP_MLME
3093 	issue_auth(padapter, pstat, (unsigned short)status);
3094 #endif
3095 
3096 #endif /* CONFIG_AP_MODE */
3097 	return _FAIL;
3098 
3099 }
3100 
OnAuthClient(_adapter * padapter,union recv_frame * precv_frame)3101 unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
3102 {
3103 	unsigned int	seq, len, status, algthm, offset;
3104 	unsigned char	*p;
3105 	unsigned int	go2asoc = 0;
3106 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
3107 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3108 	u8 *pframe = precv_frame->u.hdr.rx_data;
3109 	uint pkt_len = precv_frame->u.hdr.len;
3110 
3111 	RTW_INFO("%s\n", __FUNCTION__);
3112 
3113 #ifdef CONFIG_IOCTL_CFG80211
3114 	if (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_AUTH) == _TRUE) {
3115 		if (rtw_sec_chk_auth_type(padapter, MLME_AUTHTYPE_SAE)) {
3116 			if (rtw_cached_pmkid(padapter, get_my_bssid(&pmlmeinfo->network)) != -1) {
3117 				RTW_INFO("SAE: PMKSA cache entry found\n");
3118 				goto normal;
3119 			}
3120 			rtw_cfg80211_rx_mframe(padapter, precv_frame, NULL);
3121 			return _SUCCESS;
3122 		}
3123 	}
3124 
3125 normal:
3126 #endif /* CONFIG_IOCTL_CFG80211 */
3127 
3128 	/* check A1 matches or not */
3129 	if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
3130 		return _SUCCESS;
3131 
3132 	if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE) || pmlmeext->join_abort)
3133 		return _SUCCESS;
3134 
3135 	offset = (GetPrivacy(pframe)) ? 4 : 0;
3136 
3137 	algthm	= le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
3138 	seq	= le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
3139 	status	= le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
3140 
3141 	if (status != 0) {
3142 		RTW_INFO("clnt auth fail, status: %d\n", status);
3143 		if (status == 13) { /* && pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
3144 			if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
3145 				pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
3146 			else
3147 				pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
3148 			/* pmlmeinfo->reauth_count = 0; */
3149 		}
3150 
3151 		pmlmeinfo->auth_status = status;
3152 		set_link_timer(pmlmeext, 1);
3153 		goto authclnt_fail;
3154 	}
3155 
3156 	if (seq == 2) {
3157 		if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
3158 			/* legendary shared system */
3159 			p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
3160 				pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
3161 
3162 			if (p == NULL) {
3163 				/* RTW_INFO("marc: no challenge text?\n"); */
3164 				goto authclnt_fail;
3165 			}
3166 
3167 			if (len > sizeof(pmlmeinfo->chg_txt)) {
3168 				goto authclnt_fail;
3169 			}
3170 
3171 			_rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
3172 			pmlmeinfo->auth_seq = 3;
3173 			issue_auth(padapter, NULL, 0);
3174 			set_link_timer(pmlmeext, REAUTH_TO);
3175 
3176 			return _SUCCESS;
3177 		} else {
3178 			/* open, or 802.11r FTAA system */
3179 			go2asoc = 1;
3180 		}
3181 	} else if (seq == 4) {
3182 		if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
3183 			go2asoc = 1;
3184 		else
3185 			goto authclnt_fail;
3186 	} else {
3187 		/* this is also illegal */
3188 		/* RTW_INFO("marc: clnt auth failed due to illegal seq=%x\n", seq); */
3189 		goto authclnt_fail;
3190 	}
3191 
3192 	if (go2asoc) {
3193 #ifdef CONFIG_RTW_80211R
3194 		if (rtw_ft_update_auth_rsp_ies(padapter, pframe, pkt_len))
3195 			return _SUCCESS;
3196 #endif
3197 		RTW_PRINT("auth success, start assoc\n");
3198 		start_clnt_assoc(padapter);
3199 		return _SUCCESS;
3200 	}
3201 
3202 authclnt_fail:
3203 
3204 	/* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
3205 
3206 	return _FAIL;
3207 
3208 }
3209 
OnAssocReq(_adapter * padapter,union recv_frame * precv_frame)3210 unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
3211 {
3212 #ifdef CONFIG_AP_MODE
3213 	_irqL irqL;
3214 	u16 listen_interval;
3215 	struct rtw_ieee802_11_elems elems;
3216 	struct sta_info	*pstat;
3217 	unsigned char		reassoc, *pos;
3218 	int		left;
3219 	unsigned short		status = _STATS_SUCCESSFUL_;
3220 	unsigned short		frame_type, ie_offset = 0;
3221 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3222 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3223 	WLAN_BSSID_EX	*cur = &(pmlmeinfo->network);
3224 	struct sta_priv *pstapriv = &padapter->stapriv;
3225 	u8 *pframe = precv_frame->u.hdr.rx_data;
3226 	uint pkt_len = precv_frame->u.hdr.len;
3227 #ifdef CONFIG_P2P
3228 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
3229 	u8 p2p_status_code = P2P_STATUS_SUCCESS;
3230 	u8 *p2pie;
3231 	u32 p2pielen = 0;
3232 #endif /* CONFIG_P2P */
3233 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
3234 	u8 sta_tbtx_enable = _FALSE;
3235 #endif
3236 
3237 #ifdef CONFIG_CONCURRENT_MODE
3238 	if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) &&
3239 	    rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING | WIFI_UNDER_SURVEY)) {
3240 		/* don't process assoc request; */
3241 		return _SUCCESS;
3242 	}
3243 #endif /* CONFIG_CONCURRENT_MODE */
3244 
3245 	if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
3246 		return _FAIL;
3247 
3248 	if (rtw_check_invalid_mac_address(get_addr2_ptr(pframe), _FALSE)) {
3249 		RTW_INFO("%s : reject invalid ASSOC-req "MAC_FMT"\n",
3250 			__func__, MAC_ARG(get_addr2_ptr(pframe)));
3251 		return _FAIL;
3252 	}
3253 
3254 	frame_type = get_frame_sub_type(pframe);
3255 	if (frame_type == WIFI_ASSOCREQ) {
3256 		reassoc = 0;
3257 		ie_offset = _ASOCREQ_IE_OFFSET_;
3258 	} else { /* WIFI_REASSOCREQ */
3259 		reassoc = 1;
3260 		ie_offset = _REASOCREQ_IE_OFFSET_;
3261 	}
3262 
3263 
3264 	if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
3265 		RTW_INFO("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
3266 			 "\n", reassoc, (unsigned long)pkt_len);
3267 		return _FAIL;
3268 	}
3269 
3270 	pstat = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3271 	if (pstat == (struct sta_info *)NULL) {
3272 		status = _RSON_CLS2_;
3273 		goto asoc_class2_error;
3274 	}
3275 
3276 	RTW_INFO("%s from "MAC_FMT"\n", __FUNCTION__, MAC_ARG(get_addr2_ptr(pframe)));
3277 
3278 	if (pstat->authalg == WLAN_AUTH_SAE) {
3279 		/* WPA3-SAE */
3280 		if (((pstat->state) & WIFI_FW_AUTH_NULL)) {
3281 			/* TODO:
3282 			   Queue AssocReq and Proccess
3283 			   by external auth trigger. */
3284 			RTW_INFO("%s: wait external auth trigger\n", __func__);
3285 			return _SUCCESS;
3286 		}
3287 	}
3288 
3289 	/* check if this stat has been successfully authenticated/assocated */
3290 	if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) {
3291 		if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) {
3292 			status = _RSON_CLS2_;
3293 			goto asoc_class2_error;
3294 		} else {
3295 			pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
3296 			pstat->state |= WIFI_FW_ASSOC_STATE;
3297 		}
3298 	} else {
3299 		pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
3300 		pstat->state |= WIFI_FW_ASSOC_STATE;
3301 	}
3302 
3303 #if 0/* todo:tkip_countermeasures */
3304 	if (hapd->tkip_countermeasures) {
3305 		resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
3306 		goto fail;
3307 	}
3308 #endif
3309 
3310 	if (rtw_ap_linking_test_force_asoc_fail()) {
3311 		status = rtw_ap_linking_test_force_asoc_fail();
3312 		RTW_INFO(FUNC_ADPT_FMT" force asoc fail with status:%u\n"
3313 			, FUNC_ADPT_ARG(padapter), status);
3314 		goto OnAssocReqFail;
3315 	}
3316 
3317 	/* now parse all ieee802_11 ie to point to elems */
3318 	left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
3319 	pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
3320 	if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed) {
3321 		RTW_INFO("STA " MAC_FMT " sent invalid association request\n",
3322 			 MAC_ARG(pstat->cmn.mac_addr));
3323 		status = _STATS_FAILURE_;
3324 		goto OnAssocReqFail;
3325 	}
3326 
3327 	rtw_ap_parse_sta_capability(padapter, pstat, pframe + WLAN_HDR_A3_LEN);
3328 
3329 	listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN + 2);
3330 #if 0/* todo: */
3331 	/* check listen_interval */
3332 	if (listen_interval > hapd->conf->max_listen_interval) {
3333 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
3334 			       HOSTAPD_LEVEL_DEBUG,
3335 			       "Too large Listen Interval (%d)",
3336 			       listen_interval);
3337 		resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
3338 		goto fail;
3339 	}
3340 
3341 	pstat->listen_interval = listen_interval;
3342 #endif
3343 
3344 	/* now we should check all the fields... */
3345 	/* checking SSID */
3346 	if (elems.ssid == NULL
3347 		|| elems.ssid_len == 0
3348 		|| elems.ssid_len != cur->Ssid.SsidLength
3349 		|| _rtw_memcmp(elems.ssid, cur->Ssid.Ssid, cur->Ssid.SsidLength) == _FALSE
3350 	) {
3351 		status = _STATS_FAILURE_;
3352 		goto OnAssocReqFail;
3353 	}
3354 
3355 	/* (Extended) Supported rates */
3356 	status = rtw_ap_parse_sta_supported_rates(padapter, pstat
3357 		, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
3358 	if (status != _STATS_SUCCESSFUL_)
3359 		goto OnAssocReqFail;
3360 
3361 	/* check RSN/WPA/WPS */
3362 	status = rtw_ap_parse_sta_security_ie(padapter, pstat, &elems);
3363 	if (status != _STATS_SUCCESSFUL_)
3364 		goto OnAssocReqFail;
3365 
3366 	/* check if there is WMM IE & support WWM-PS */
3367 	rtw_ap_parse_sta_wmm_ie(padapter, pstat
3368 		, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
3369 
3370 #ifdef CONFIG_RTS_FULL_BW
3371 	/*check vendor IE*/
3372 	rtw_parse_sta_vendor_ie_8812(padapter, pstat
3373 		, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
3374 #endif/*CONFIG_RTS_FULL_BW*/
3375 
3376 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
3377 	if (elems.tbtx_cap && elems.tbtx_cap_len != 0) {
3378 		if(rtw_is_tbtx_capabilty(elems.tbtx_cap, elems.tbtx_cap_len)) {
3379 			sta_tbtx_enable = _TRUE;
3380 		}
3381 	}
3382 
3383 #endif
3384 
3385 	rtw_ap_parse_sta_ht_ie(padapter, pstat, &elems);
3386 	rtw_ap_parse_sta_vht_ie(padapter, pstat, &elems);
3387 
3388 	if (((pstat->flags & WLAN_STA_HT) || (pstat->flags & WLAN_STA_VHT)) &&
3389 	    ((pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) ||
3390 	     (pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP))) {
3391 
3392 		RTW_INFO("(V)HT: " MAC_FMT " tried to use TKIP with (V)HT association\n", MAC_ARG(pstat->cmn.mac_addr));
3393 
3394 		pstat->flags &= ~WLAN_STA_HT;
3395 		pstat->flags &= ~WLAN_STA_VHT;
3396 		/*status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
3397 		  * goto OnAssocReqFail;
3398 		*/
3399 	}
3400 
3401 #ifdef CONFIG_P2P
3402 	pstat->is_p2p_device = _FALSE;
3403 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
3404 		p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen);
3405 		if (p2pie) {
3406 			pstat->is_p2p_device = _TRUE;
3407 			p2p_status_code = (u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat);
3408 			if (p2p_status_code > 0) {
3409 				pstat->p2p_status_code = p2p_status_code;
3410 				status = _STATS_CAP_FAIL_;
3411 				goto OnAssocReqFail;
3412 			}
3413 		}
3414 #ifdef CONFIG_WFD
3415 		rtw_process_wfd_ies(padapter, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, __func__);
3416 #endif
3417 	}
3418 	pstat->p2p_status_code = p2p_status_code;
3419 #endif /* CONFIG_P2P */
3420 
3421 	rtw_ap_parse_sta_multi_ap_ie(padapter, pstat, pos, left);
3422 
3423 #ifdef CONFIG_RTW_REPEATER_SON
3424 	if (rtw_rson_ap_check_sta(padapter, pframe, pkt_len, ie_offset))
3425 		goto OnAssocReqFail;
3426 #endif
3427 
3428 	/* TODO: identify_proprietary_vendor_ie(); */
3429 	/* Realtek proprietary IE */
3430 	/* identify if this is Broadcom sta */
3431 	/* identify if this is ralink sta */
3432 	/* Customer proprietary IE */
3433 
3434 #ifdef CONFIG_RTW_80211K
3435 	rtw_ap_parse_sta_rm_en_cap(padapter, pstat, &elems);
3436 #endif
3437 
3438 	/* AID assignment */
3439 	if (pstat->cmn.aid > 0)
3440 		RTW_INFO(FUNC_ADPT_FMT" use old AID=%d for "MAC_FMT"\n",
3441 			FUNC_ADPT_ARG(padapter), pstat->cmn.aid, MAC_ARG(pstat->cmn.mac_addr));
3442 	else {
3443 		if (!rtw_aid_alloc(padapter, pstat)) {
3444 			RTW_INFO(FUNC_ADPT_FMT" no room for more AIDs for "MAC_FMT"\n",
3445 				FUNC_ADPT_ARG(padapter), MAC_ARG(pstat->cmn.mac_addr));
3446 			status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
3447 			goto OnAssocReqFail;
3448 		}
3449 		RTW_INFO(FUNC_ADPT_FMT" allocate new AID=%d for "MAC_FMT"\n",
3450 			FUNC_ADPT_ARG(padapter), pstat->cmn.aid, MAC_ARG(pstat->cmn.mac_addr));
3451 	}
3452 
3453 	pstat->state &= (~WIFI_FW_ASSOC_STATE);
3454 	pstat->state |= WIFI_FW_ASSOC_SUCCESS;
3455 	/* RTW_INFO("==================%s, %d,  (%x), bpairwise_key_installed=%d, MAC:"MAC_FMT"\n"
3456 	, __func__, __LINE__, pstat->state, pstat->bpairwise_key_installed, MAC_ARG(pstat->cmn.mac_addr)); */
3457 #ifdef CONFIG_IEEE80211W
3458 	if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
3459 		|| !(pstat->flags & WLAN_STA_MFP))
3460 #endif /* CONFIG_IEEE80211W */
3461 	{
3462 		_enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
3463 		if (!rtw_is_list_empty(&pstat->auth_list)) {
3464 			rtw_list_delete(&pstat->auth_list);
3465 			pstapriv->auth_list_cnt--;
3466 		}
3467 		_exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
3468 
3469 		_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3470 		if (rtw_is_list_empty(&pstat->asoc_list)) {
3471 			pstat->expire_to = pstapriv->expire_to;
3472 			rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
3473 			pstapriv->asoc_list_cnt++;
3474 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
3475 			if (sta_tbtx_enable) {
3476 				pstat->tbtx_enable = _TRUE;
3477 				pstapriv->tbtx_asoc_list_cnt++;
3478 			}
3479 #endif
3480 		}
3481 		_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3482 	}
3483 
3484 	/* now the station is qualified to join our BSS...	 */
3485 	if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_ == status)) {
3486 #ifdef CONFIG_NATIVEAP_MLME
3487 #ifdef CONFIG_IEEE80211W
3488 		if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
3489 			|| !(pstat->flags & WLAN_STA_MFP))
3490 #endif /* CONFIG_IEEE80211W */
3491 		{
3492 			/* .1 bss_cap_update & sta_info_update */
3493 			bss_cap_update_on_sta_join(padapter, pstat);
3494 			sta_info_update(padapter, pstat);
3495 		}
3496 #ifdef CONFIG_IEEE80211W
3497 		if (pstat->bpairwise_key_installed == _TRUE && (pstat->flags & WLAN_STA_MFP))
3498 			status = _STATS_REFUSED_TEMPORARILY_;
3499 #endif /* CONFIG_IEEE80211W */
3500 		/* .2 issue assoc rsp before notify station join event. */
3501 		if (frame_type == WIFI_ASSOCREQ)
3502 			issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
3503 		else
3504 			issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
3505 
3506 #ifdef CONFIG_IOCTL_CFG80211
3507 		_enter_critical_bh(&pstat->lock, &irqL);
3508 		if (pstat->passoc_req) {
3509 			rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
3510 			pstat->passoc_req = NULL;
3511 			pstat->assoc_req_len = 0;
3512 		}
3513 
3514 		pstat->passoc_req =  rtw_zmalloc(pkt_len);
3515 		if (pstat->passoc_req) {
3516 			_rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
3517 			pstat->assoc_req_len = pkt_len;
3518 		}
3519 		_exit_critical_bh(&pstat->lock, &irqL);
3520 #endif /* CONFIG_IOCTL_CFG80211 */
3521 #ifdef CONFIG_IEEE80211W
3522 		if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
3523 			|| !(pstat->flags & WLAN_STA_MFP))
3524 #endif /* CONFIG_IEEE80211W */
3525 		{
3526 			/* .3-(1) report sta add event */
3527 			report_add_sta_event(padapter, pstat->cmn.mac_addr);
3528 		}
3529 #ifdef CONFIG_IEEE80211W
3530 		if (pstat->bpairwise_key_installed == _TRUE && (pstat->flags & WLAN_STA_MFP)) {
3531 			RTW_INFO(MAC_FMT"\n", MAC_ARG(pstat->cmn.mac_addr));
3532 			issue_action_SA_Query(padapter, pstat->cmn.mac_addr, 0, 0, IEEE80211W_RIGHT_KEY);
3533 		}
3534 #endif /* CONFIG_IEEE80211W */
3535 #endif /* CONFIG_NATIVEAP_MLME */
3536 	}
3537 
3538 	return _SUCCESS;
3539 
3540 asoc_class2_error:
3541 
3542 #ifdef CONFIG_NATIVEAP_MLME
3543 	issue_deauth(padapter, (void *)get_addr2_ptr(pframe), status);
3544 #endif
3545 
3546 	return _FAIL;
3547 
3548 OnAssocReqFail:
3549 
3550 
3551 #ifdef CONFIG_NATIVEAP_MLME
3552 	/* pstat->cmn.aid = 0; */
3553 	if (frame_type == WIFI_ASSOCREQ)
3554 		issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
3555 	else
3556 		issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
3557 #endif
3558 
3559 
3560 #endif /* CONFIG_AP_MODE */
3561 
3562 	return _FAIL;
3563 
3564 }
3565 
3566 #if defined(CONFIG_LAYER2_ROAMING) && defined(CONFIG_RTW_80211K)
rtw_roam_nb_discover(_adapter * padapter,u8 bfroce)3567 void rtw_roam_nb_discover(_adapter *padapter, u8 bfroce)
3568 {
3569 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3570 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3571 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3572 	struct sta_priv *pstapriv = &padapter->stapriv;
3573 	struct sta_info *psta;
3574 	u8 nb_req_issue = _FALSE;
3575 
3576 	if (!check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
3577 		return;
3578 
3579 	if (!rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE))
3580 		return;
3581 
3582 	psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
3583 	if (!psta)
3584 		return;
3585 
3586 	if (bfroce || (!pmlmepriv->nb_info.nb_rpt_is_same))
3587 		nb_req_issue = _TRUE;
3588 
3589 	if (nb_req_issue && (psta->rm_en_cap[0] & RTW_RRM_NB_RPT_EN))
3590 		rm_add_nb_req(padapter, psta);
3591 }
3592 #endif
3593 
OnAssocRsp(_adapter * padapter,union recv_frame * precv_frame)3594 unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
3595 {
3596 	uint i;
3597 	int res;
3598 	unsigned short	status;
3599 	PNDIS_802_11_VARIABLE_IEs	pIE;
3600 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3601 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
3602 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3603 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
3604 	u8 *pframe = precv_frame->u.hdr.rx_data;
3605 	uint pkt_len = precv_frame->u.hdr.len;
3606 #ifdef CONFIG_WAPI_SUPPORT
3607 	PNDIS_802_11_VARIABLE_IEs	pWapiIE = NULL;
3608 #endif
3609 
3610 	RTW_INFO("%s\n", __FUNCTION__);
3611 
3612 	/* check A1 matches or not */
3613 	if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
3614 		return _SUCCESS;
3615 
3616 	if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)) || pmlmeext->join_abort)
3617 		return _SUCCESS;
3618 
3619 	if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
3620 		return _SUCCESS;
3621 
3622 	_cancel_timer_ex(&pmlmeext->link_timer);
3623 
3624 	/* status */
3625 	status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2));
3626 	if (status > 0) {
3627 		RTW_INFO("assoc reject, status code: %d\n", status);
3628 		pmlmeinfo->state = WIFI_FW_NULL_STATE;
3629 		res = -4;
3630 		goto report_assoc_result;
3631 	}
3632 
3633 	/* get capabilities */
3634 	pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3635 
3636 	/* set slot time */
3637 	pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20;
3638 
3639 	/* AID */
3640 	res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4)) & 0x3fff);
3641 
3642 	/* check aid value */
3643 	if (res < 1 || res > 2007) {
3644 		RTW_INFO("assoc reject, aid: %d\n", res);
3645 		pmlmeinfo->state = WIFI_FW_NULL_STATE;
3646 		res = -4;
3647 		goto report_assoc_result;
3648 	}
3649 
3650 	/* following are moved to join event callback function */
3651 	/* to handle HT, WMM, rate adaptive, update MAC reg */
3652 	/* for not to handle the synchronous IO in the tasklet */
3653 	for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) {
3654 		pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
3655 
3656 		switch (pIE->ElementID) {
3657 		case _VENDOR_SPECIFIC_IE_:
3658 			if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6))	/* WMM */
3659 				WMM_param_handler(padapter, pIE);
3660 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
3661 			else if (_rtw_memcmp(pIE->data, WFD_OUI, 4))		/* WFD */
3662 				rtw_process_wfd_ie(padapter, (u8 *)pIE, pIE->Length, __func__);
3663 #endif
3664 			break;
3665 
3666 #ifdef CONFIG_WAPI_SUPPORT
3667 		case _WAPI_IE_:
3668 			pWapiIE = pIE;
3669 			break;
3670 #endif
3671 
3672 		case _HT_CAPABILITY_IE_:	/* HT caps */
3673 			HT_caps_handler(padapter, pIE);
3674 #ifdef ROKU_PRIVATE
3675 			HT_caps_handler_infra_ap(padapter, pIE);
3676 #endif /* ROKU_PRIVATE */
3677 			break;
3678 
3679 		case _HT_EXTRA_INFO_IE_:	/* HT info */
3680 			HT_info_handler(padapter, pIE);
3681 			break;
3682 
3683 #ifdef CONFIG_80211AC_VHT
3684 		case EID_VHTCapability:
3685 			VHT_caps_handler(padapter, pIE);
3686 #ifdef ROKU_PRIVATE
3687 			VHT_caps_handler_infra_ap(padapter, pIE);
3688 #endif /* ROKU_PRIVATE */
3689 			break;
3690 
3691 		case EID_VHTOperation:
3692 			VHT_operation_handler(padapter, pIE);
3693 			break;
3694 #endif
3695 
3696 		case _ERPINFO_IE_:
3697 			ERP_IE_handler(padapter, pIE);
3698 			break;
3699 #ifdef CONFIG_TDLS
3700 		case WLAN_EID_EXT_CAP:
3701 			if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE)
3702 				padapter->tdlsinfo.ap_prohibited = _TRUE;
3703 			if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE)
3704 				padapter->tdlsinfo.ch_switch_prohibited = _TRUE;
3705 			break;
3706 #endif /* CONFIG_TDLS */
3707 
3708 #ifdef CONFIG_RTW_80211K
3709 		case _EID_RRM_EN_CAP_IE_:
3710 			RM_IE_handler(padapter, pIE);
3711 			break;
3712 #endif
3713 
3714 #ifdef ROKU_PRIVATE
3715 		/* Infra mode, used to store AP's info , Parse the supported rates from AssocRsp */
3716 		case _SUPPORTEDRATES_IE_:
3717 			Supported_rate_infra_ap(padapter, pIE);
3718 			break;
3719 
3720 		case _EXT_SUPPORTEDRATES_IE_:
3721 			Extended_Supported_rate_infra_ap(padapter, pIE);
3722 			break;
3723 #endif /* ROKU_PRIVATE */
3724 		default:
3725 			break;
3726 		}
3727 
3728 		i += (pIE->Length + 2);
3729 	}
3730 
3731 #ifdef CONFIG_WAPI_SUPPORT
3732 	rtw_wapi_on_assoc_ok(padapter, pWapiIE);
3733 #endif
3734 
3735 	pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
3736 	pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
3737 
3738 	/* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
3739 	UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
3740 
3741 report_assoc_result:
3742 	if (res > 0)
3743 		rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
3744 	else
3745 		rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
3746 
3747 	report_join_res(padapter, res, status);
3748 
3749 #if defined(CONFIG_LAYER2_ROAMING) && defined(CONFIG_RTW_80211K)
3750 	rtw_roam_nb_discover(padapter, _TRUE);
3751 #endif
3752 	return _SUCCESS;
3753 }
3754 
OnDeAuth(_adapter * padapter,union recv_frame * precv_frame)3755 unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
3756 {
3757 	unsigned short	reason;
3758 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3759 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
3760 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3761 	u8 *pframe = precv_frame->u.hdr.rx_data;
3762 #ifdef CONFIG_P2P
3763 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3764 #endif /* CONFIG_P2P */
3765 
3766 	/* check A3 */
3767 	if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3768 		return _SUCCESS;
3769 
3770 	RTW_INFO(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3771 
3772 #ifdef CONFIG_P2P
3773 	if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
3774 		_cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
3775 		_set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
3776 	}
3777 #endif /* CONFIG_P2P */
3778 
3779 	reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3780 
3781 #ifdef CONFIG_AP_MODE
3782 	if (MLME_IS_AP(padapter)) {
3783 		_irqL irqL;
3784 		struct sta_info *psta;
3785 		struct sta_priv *pstapriv = &padapter->stapriv;
3786 
3787 		/* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);		 */
3788 		/* rtw_free_stainfo(padapter, psta); */
3789 		/* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);		 */
3790 
3791 		RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3792 			, FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe));
3793 
3794 		psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3795 		if (psta) {
3796 			u8 updated = _FALSE;
3797 
3798 			_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3799 			if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
3800 				rtw_list_delete(&psta->asoc_list);
3801 				pstapriv->asoc_list_cnt--;
3802 				#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
3803 				if (psta->tbtx_enable)
3804 					pstapriv->tbtx_asoc_list_cnt--;
3805 				#endif
3806 				updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3807 
3808 			}
3809 			_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3810 
3811 			associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3812 		}
3813 
3814 
3815 		return _SUCCESS;
3816 	} else
3817 #endif
3818 	if (!MLME_IS_MESH(padapter)) {
3819 		int	ignore_received_deauth = 0;
3820 
3821 		/*	Commented by Albert 20130604 */
3822 		/*	Before sending the auth frame to start the STA/GC mode connection with AP/GO,  */
3823 		/*	we will send the deauth first. */
3824 		/*	However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth. */
3825 		/*	Added the following code to avoid this case. */
3826 		if ((pmlmeinfo->state & WIFI_FW_AUTH_STATE) ||
3827 		    (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)) {
3828 			if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA)
3829 				ignore_received_deauth = 1;
3830 			else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
3831 				/* TODO: 802.11r */
3832 				ignore_received_deauth = 1;
3833 			}
3834 		}
3835 
3836 		RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM, ignore=%d\n"
3837 			, FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe), ignore_received_deauth);
3838 
3839 		if (0 == ignore_received_deauth)
3840 			receive_disconnect(padapter, get_addr2_ptr(pframe), reason, _FALSE);
3841 	}
3842 	pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3843 	return _SUCCESS;
3844 
3845 }
3846 
OnDisassoc(_adapter * padapter,union recv_frame * precv_frame)3847 unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
3848 {
3849 	unsigned short	reason;
3850 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3851 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
3852 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3853 	u8 *pframe = precv_frame->u.hdr.rx_data;
3854 #ifdef CONFIG_P2P
3855 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3856 #endif /* CONFIG_P2P */
3857 
3858 	/* check A3 */
3859 	if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3860 		return _SUCCESS;
3861 
3862 	RTW_INFO(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3863 
3864 #ifdef CONFIG_P2P
3865 	if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
3866 		_cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
3867 		_set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
3868 	}
3869 #endif /* CONFIG_P2P */
3870 
3871 	reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3872 
3873 #ifdef CONFIG_AP_MODE
3874 	if (MLME_IS_AP(padapter)) {
3875 		_irqL irqL;
3876 		struct sta_info *psta;
3877 		struct sta_priv *pstapriv = &padapter->stapriv;
3878 
3879 		/* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);	 */
3880 		/* rtw_free_stainfo(padapter, psta); */
3881 		/* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);		 */
3882 
3883 		RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3884 			, FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe));
3885 
3886 		psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3887 		if (psta) {
3888 			u8 updated = _FALSE;
3889 
3890 			_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3891 			if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
3892 				rtw_list_delete(&psta->asoc_list);
3893 				pstapriv->asoc_list_cnt--;
3894 				#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
3895 				if (psta->tbtx_enable)
3896 					pstapriv->tbtx_asoc_list_cnt--;
3897 				#endif
3898 				updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3899 
3900 			}
3901 			_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3902 
3903 			associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3904 		}
3905 
3906 		return _SUCCESS;
3907 	} else
3908 #endif
3909 	if (!MLME_IS_MESH(padapter)) {
3910 		RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3911 			, FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe));
3912 
3913 	#ifdef CONFIG_RTW_WNM
3914 		if (rtw_wnm_try_btm_roam_imnt(padapter) > 0)
3915 	#endif
3916 		receive_disconnect(padapter, get_addr2_ptr(pframe), reason, _FALSE);
3917 	}
3918 	pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3919 	return _SUCCESS;
3920 
3921 }
3922 
OnAtim(_adapter * padapter,union recv_frame * precv_frame)3923 unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
3924 {
3925 	RTW_INFO("%s\n", __FUNCTION__);
3926 	return _SUCCESS;
3927 }
3928 
on_action_spct_ch_switch(_adapter * padapter,struct sta_info * psta,u8 * ies,uint ies_len)3929 unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
3930 {
3931 	unsigned int ret = _FAIL;
3932 	struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
3933 	struct mlme_ext_info	*pmlmeinfo = &(mlmeext->mlmext_info);
3934 
3935 	if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
3936 		ret = _SUCCESS;
3937 		goto exit;
3938 	}
3939 
3940 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
3941 
3942 		int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
3943 		int ch_offset = -1;
3944 		u8 bwmode;
3945 		struct ieee80211_info_element *ie;
3946 
3947 		RTW_INFO(FUNC_NDEV_FMT" from "MAC_FMT"\n",
3948 			FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->cmn.mac_addr));
3949 
3950 		for_each_ie(ie, ies, ies_len) {
3951 			if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
3952 				ch_switch_mode = ie->data[0];
3953 				ch = ie->data[1];
3954 				ch_switch_cnt = ie->data[2];
3955 				RTW_INFO("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
3956 					 ch_switch_mode, ch, ch_switch_cnt);
3957 			} else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
3958 				ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
3959 				RTW_INFO("ch_offset:%d\n", ch_offset);
3960 			}
3961 		}
3962 
3963 		if (ch == -1)
3964 			return _SUCCESS;
3965 
3966 		if (ch_offset == -1)
3967 			bwmode = mlmeext->cur_bwmode;
3968 		else
3969 			bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
3970 				 CHANNEL_WIDTH_20 : CHANNEL_WIDTH_40;
3971 
3972 		ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
3973 
3974 		/* todo:
3975 		 * 1. the decision of channel switching
3976 		 * 2. things after channel switching
3977 		 */
3978 
3979 		ret = rtw_set_chbw_cmd(padapter, ch, bwmode, ch_offset, 0);
3980 	}
3981 
3982 exit:
3983 	return ret;
3984 }
3985 
on_action_spct(_adapter * padapter,union recv_frame * precv_frame)3986 unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
3987 {
3988 	unsigned int ret = _FAIL;
3989 	struct sta_info *psta = NULL;
3990 	struct sta_priv *pstapriv = &padapter->stapriv;
3991 	u8 *pframe = precv_frame->u.hdr.rx_data;
3992 	uint frame_len = precv_frame->u.hdr.len;
3993 	u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3994 	u8 category;
3995 	u8 action;
3996 
3997 	psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3998 
3999 	if (!psta)
4000 		goto exit;
4001 
4002 	category = frame_body[0];
4003 	if (category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
4004 		goto exit;
4005 
4006 	action = frame_body[1];
4007 
4008 	RTW_INFO(FUNC_ADPT_FMT" action:%u\n", FUNC_ADPT_ARG(padapter), action);
4009 
4010 	switch (action) {
4011 	case RTW_WLAN_ACTION_SPCT_MSR_REQ:
4012 	case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
4013 	case RTW_WLAN_ACTION_SPCT_TPC_REQ:
4014 	case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
4015 		break;
4016 	case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
4017 #ifdef CONFIG_SPCT_CH_SWITCH
4018 		ret = on_action_spct_ch_switch(padapter, psta
4019 				, frame_body + 2, frame_len - (frame_body - pframe) - 2);
4020 #elif CONFIG_DFS
4021 		if (MLME_IS_STA(padapter) && MLME_IS_ASOC(padapter)) {
4022 			process_csa_ie(padapter
4023 				, frame_body + 2, frame_len - (frame_body - pframe) - 2);
4024 		}
4025 #endif
4026 		break;
4027 	default:
4028 		break;
4029 	}
4030 
4031 exit:
4032 	return ret;
4033 }
4034 
OnAction_qos(_adapter * padapter,union recv_frame * precv_frame)4035 unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
4036 {
4037 	return _SUCCESS;
4038 }
4039 
OnAction_dls(_adapter * padapter,union recv_frame * precv_frame)4040 unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
4041 {
4042 	return _SUCCESS;
4043 }
4044 
4045 #ifdef CONFIG_RTW_WNM
on_action_wnm(_adapter * adapter,union recv_frame * rframe)4046 unsigned int on_action_wnm(_adapter *adapter, union recv_frame *rframe)
4047 {
4048 	unsigned int ret = _FAIL;
4049 	struct sta_info *sta = NULL;
4050 	struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
4051 	struct sta_priv *stapriv = &(adapter->stapriv);
4052 	u8 *frame = rframe->u.hdr.rx_data;
4053 	u32 frame_len = rframe->u.hdr.len;
4054 	u8 *frame_body = (u8 *)(frame + sizeof(struct rtw_ieee80211_hdr_3addr));
4055 	u32 frame_body_len = frame_len - sizeof(struct rtw_ieee80211_hdr_3addr);
4056 	u8 category, action;
4057 	int cnt = 0;
4058 	char msg[16];
4059 
4060 	sta = rtw_get_stainfo(stapriv, get_addr2_ptr(frame));
4061 	if (!sta)
4062 		goto exit;
4063 
4064 	category = frame_body[0];
4065 	if (category != RTW_WLAN_CATEGORY_WNM)
4066 		goto exit;
4067 
4068 	action = frame_body[1];
4069 
4070 	switch (action) {
4071 #ifdef CONFIG_RTW_80211R
4072 	case RTW_WLAN_ACTION_WNM_BTM_REQ:
4073 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
4074 			RTW_INFO("WNM: BSS Transition Management Request recv.\n");
4075 			rtw_wnm_process_btm_req(adapter, frame_body, frame_body_len);
4076 		}
4077 		ret = _SUCCESS;
4078 		break;
4079 #endif
4080 	case RTW_WLAN_ACTION_WNM_BTM_RSP:
4081 		if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) &&
4082 			(pmlmepriv->nb_info.features & RTW_WNM_FEATURE_BTM_REQ_EN)) {
4083 			struct btm_rsp_hdr rsp;
4084 			u32 sz;
4085 
4086 			RTW_INFO("WNM: BSS Transition Management Response recv.\n");
4087 			sz = rtw_wnm_btm_rsp_candidates_sz_get(adapter,
4088 					frame_body, frame_body_len);
4089 			_rtw_memset(&rsp, 0, sizeof(rsp));
4090 
4091 			if (sz > 0)
4092 				rsp.pcandidates = rtw_zmalloc(sz);
4093 
4094 			rtw_wnm_process_btm_rsp(adapter, frame_body, frame_body_len, &rsp);
4095 			/* TODO : handle candidates info in rsp.pcandidates for upper-layer services */
4096 			#ifdef CONFIG_PLATFORM_CMAP_INTFS
4097 			cmap_intfs_nl_btm_resp_event(adapter, sta->cmn.mac_addr,
4098 						     adapter_mac_addr(adapter),
4099 						     rsp.status, rsp.bssid,
4100 						     rsp.pcandidates,
4101 						     rsp.candidates_num);
4102 			#endif
4103 			if (0 && rsp.pcandidates && (rsp.candidates_num > 0))
4104 				RTW_INFO_DUMP("pcandidates : ", rsp.pcandidates, sz);
4105 
4106 			if ((sz > 0) && (rsp.pcandidates != NULL))
4107 				rtw_mfree(rsp.pcandidates, sz);
4108 		}
4109 		fallthrough;
4110 		 /* fall through */
4111 	default:
4112 		#ifdef CONFIG_IOCTL_CFG80211
4113 		cnt += sprintf((msg + cnt), "ACT_WNM %u", action);
4114 		rtw_cfg80211_rx_action(adapter, rframe, msg);
4115 		#endif
4116 		ret = _SUCCESS;
4117 		break;
4118 	}
4119 
4120 exit:
4121 	return ret;
4122 }
4123 #endif /* CONFIG_RTW_WNM */
4124 
4125 /**
4126  * rtw_rx_ampdu_size - Get the target RX AMPDU buffer size for the specific @adapter
4127  * @adapter: the adapter to get target RX AMPDU buffer size
4128  *
4129  * Returns: the target RX AMPDU buffer size
4130  */
rtw_rx_ampdu_size(_adapter * adapter)4131 u8 rtw_rx_ampdu_size(_adapter *adapter)
4132 {
4133 	u8 size;
4134 	HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
4135 
4136 #ifdef CONFIG_BT_COEXIST
4137 	if (rtw_btcoex_IsBTCoexCtrlAMPDUSize(adapter) == _TRUE) {
4138 		size = rtw_btcoex_GetAMPDUSize(adapter);
4139 		goto exit;
4140 	}
4141 #endif
4142 
4143 	/* for scan */
4144 	if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
4145 	    && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
4146 	    && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size != RX_AMPDU_SIZE_INVALID
4147 	   ) {
4148 		size = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size;
4149 		goto exit;
4150 	}
4151 
4152 	/* default value based on max_rx_ampdu_factor */
4153 	if (adapter->driver_rx_ampdu_factor != 0xFF)
4154 		max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)adapter->driver_rx_ampdu_factor;
4155 	else
4156 		rtw_hal_get_def_var(adapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
4157 
4158 	/* In Maximum A-MPDU Length Exponent subfield of A-MPDU Parameters field of HT Capabilities element,
4159 		the unit of max_rx_ampdu_factor are octets. 8K, 16K, 32K, 64K is right.
4160 		But the buffer size subfield of Block Ack Parameter Set field in ADDBA action frame indicates
4161 		the number of buffers available for this particular TID. Each buffer is equal to max. size of
4162 		MSDU or AMSDU.
4163 		The size variable means how many MSDUs or AMSDUs, it's not Kbytes.
4164 	*/
4165 	if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
4166 		size = 64;
4167 	else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
4168 		size = 32;
4169 	else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
4170 		size = 16;
4171 	else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
4172 		size = 8;
4173 	else
4174 		size = 64;
4175 
4176 exit:
4177 
4178 	if (size > 127)
4179 		size = 127;
4180 
4181 	return size;
4182 }
4183 
4184 /**
4185  * rtw_rx_ampdu_is_accept - Get the permission if RX AMPDU should be set up for the specific @adapter
4186  * @adapter: the adapter to get the permission if RX AMPDU should be set up
4187  *
4188  * Returns: accept or not
4189  */
rtw_rx_ampdu_is_accept(_adapter * adapter)4190 bool rtw_rx_ampdu_is_accept(_adapter *adapter)
4191 {
4192 	bool accept;
4193 
4194 	if (adapter->fix_rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID) {
4195 		accept = adapter->fix_rx_ampdu_accept;
4196 		goto exit;
4197 	}
4198 
4199 #ifdef CONFIG_BT_COEXIST
4200 	if (rtw_btcoex_IsBTCoexRejectAMPDU(adapter) == _TRUE) {
4201 		accept = _FALSE;
4202 		goto exit;
4203 	}
4204 #endif
4205 
4206 	/* for scan */
4207 	if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
4208 	    && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
4209 	    && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
4210 	   ) {
4211 		accept = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept;
4212 		goto exit;
4213 	}
4214 
4215 	/* default value for other cases */
4216 	accept = adapter->mlmeextpriv.mlmext_info.bAcceptAddbaReq;
4217 
4218 exit:
4219 	return accept;
4220 }
4221 
4222 /**
4223  * rtw_rx_ampdu_set_size - Set the target RX AMPDU buffer size for the specific @adapter and specific @reason
4224  * @adapter: the adapter to set target RX AMPDU buffer size
4225  * @size: the target RX AMPDU buffer size to set
4226  * @reason: reason for the target RX AMPDU buffer size setting
4227  *
4228  * Returns: whether the target RX AMPDU buffer size is changed
4229  */
rtw_rx_ampdu_set_size(_adapter * adapter,u8 size,u8 reason)4230 bool rtw_rx_ampdu_set_size(_adapter *adapter, u8 size, u8 reason)
4231 {
4232 	bool is_adj = _FALSE;
4233 	struct mlme_ext_priv *mlmeext;
4234 	struct mlme_ext_info *mlmeinfo;
4235 
4236 	mlmeext = &adapter->mlmeextpriv;
4237 	mlmeinfo = &mlmeext->mlmext_info;
4238 
4239 	if (reason == RX_AMPDU_DRV_FIXED) {
4240 		if (adapter->fix_rx_ampdu_size != size) {
4241 			adapter->fix_rx_ampdu_size = size;
4242 			is_adj = _TRUE;
4243 			RTW_INFO(FUNC_ADPT_FMT" fix_rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
4244 		}
4245 	} else if (reason == RX_AMPDU_DRV_SCAN) {
4246 		struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
4247 
4248 		if (ss->rx_ampdu_size != size) {
4249 			ss->rx_ampdu_size = size;
4250 			is_adj = _TRUE;
4251 			RTW_INFO(FUNC_ADPT_FMT" ss.rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
4252 		}
4253 	}
4254 
4255 	return is_adj;
4256 }
4257 
4258 /**
4259  * rtw_rx_ampdu_set_accept - Set the permission if RX AMPDU should be set up for the specific @adapter and specific @reason
4260  * @adapter: the adapter to set if RX AMPDU should be set up
4261  * @accept: if RX AMPDU should be set up
4262  * @reason: reason for the permission if RX AMPDU should be set up
4263  *
4264  * Returns: whether the permission if RX AMPDU should be set up is changed
4265  */
rtw_rx_ampdu_set_accept(_adapter * adapter,u8 accept,u8 reason)4266 bool rtw_rx_ampdu_set_accept(_adapter *adapter, u8 accept, u8 reason)
4267 {
4268 	bool is_adj = _FALSE;
4269 	struct mlme_ext_priv *mlmeext;
4270 	struct mlme_ext_info *mlmeinfo;
4271 
4272 	mlmeext = &adapter->mlmeextpriv;
4273 	mlmeinfo = &mlmeext->mlmext_info;
4274 
4275 	if (reason == RX_AMPDU_DRV_FIXED) {
4276 		if (adapter->fix_rx_ampdu_accept != accept) {
4277 			adapter->fix_rx_ampdu_accept = accept;
4278 			is_adj = _TRUE;
4279 			RTW_INFO(FUNC_ADPT_FMT" fix_rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
4280 		}
4281 	} else if (reason == RX_AMPDU_DRV_SCAN) {
4282 		if (adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != accept) {
4283 			adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept = accept;
4284 			is_adj = _TRUE;
4285 			RTW_INFO(FUNC_ADPT_FMT" ss.rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
4286 		}
4287 	}
4288 
4289 	return is_adj;
4290 }
4291 
4292 /**
4293  * rx_ampdu_apply_sta_tid - Apply RX AMPDU setting to the specific @sta and @tid
4294  * @adapter: the adapter to which @sta belongs
4295  * @sta: the sta to be checked
4296  * @tid: the tid to be checked
4297  * @accept: the target permission if RX AMPDU should be set up
4298  * @size: the target RX AMPDU buffer size
4299  *
4300  * Returns:
4301  * 0: no canceled
4302  * 1: canceled by no permission
4303  * 2: canceled by different buffer size
4304  * 3: canceled by potential mismatched status
4305  *
4306  * Blocking function, may sleep
4307  */
rx_ampdu_apply_sta_tid(_adapter * adapter,struct sta_info * sta,u8 tid,u8 accept,u8 size)4308 u8 rx_ampdu_apply_sta_tid(_adapter *adapter, struct sta_info *sta, u8 tid, u8 accept, u8 size)
4309 {
4310 	u8 ret = 0;
4311 	struct recv_reorder_ctrl *reorder_ctl = &sta->recvreorder_ctrl[tid];
4312 
4313 	if (reorder_ctl->enable == _FALSE) {
4314 		if (reorder_ctl->ampdu_size != RX_AMPDU_SIZE_INVALID) {
4315 			send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 1);
4316 			ret = 3;
4317 		}
4318 		goto exit;
4319 	}
4320 
4321 	if (accept == _FALSE) {
4322 		send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
4323 		ret = 1;
4324 	} else if (reorder_ctl->ampdu_size != size) {
4325 		send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
4326 		ret = 2;
4327 	}
4328 
4329 exit:
4330 	return ret;
4331 }
4332 
rx_ampdu_size_sta_limit(_adapter * adapter,struct sta_info * sta)4333 u8 rx_ampdu_size_sta_limit(_adapter *adapter, struct sta_info *sta)
4334 {
4335 	u8 sz_limit = 0xFF;
4336 
4337 #ifdef CONFIG_80211N_HT
4338 	struct registry_priv *regsty = adapter_to_regsty(adapter);
4339 	struct mlme_priv *mlme = &adapter->mlmepriv;
4340 	struct mlme_ext_info *mlmeinfo = &adapter->mlmeextpriv.mlmext_info;
4341 	s8 nss = -1;
4342 	u8 bw = rtw_min(sta->cmn.bw_mode, adapter->mlmeextpriv.cur_bwmode);
4343 
4344 	#ifdef CONFIG_80211AC_VHT
4345 	if (is_supported_vht(sta->wireless_mode)) {
4346 		nss = rtw_min(rtw_vht_mcsmap_to_nss(mlme->vhtpriv.vht_mcs_map)
4347 				, rtw_vht_mcsmap_to_nss(sta->vhtpriv.vht_mcs_map));
4348 	} else
4349 	#endif
4350 	if (is_supported_ht(sta->wireless_mode)) {
4351 		nss = rtw_min(rtw_ht_mcsset_to_nss(mlmeinfo->HT_caps.u.HT_cap_element.MCS_rate)
4352 				, rtw_ht_mcsset_to_nss(sta->htpriv.ht_cap.supp_mcs_set));
4353 	}
4354 
4355 	if (nss >= 1)
4356 		sz_limit = regsty->rx_ampdu_sz_limit_by_nss_bw[nss - 1][bw];
4357 #endif /* CONFIG_80211N_HT */
4358 
4359 	return sz_limit;
4360 }
4361 
4362 /**
4363  * rx_ampdu_apply_sta - Apply RX AMPDU setting to the specific @sta
4364  * @adapter: the adapter to which @sta belongs
4365  * @sta: the sta to be checked
4366  * @accept: the target permission if RX AMPDU should be set up
4367  * @size: the target RX AMPDU buffer size
4368  *
4369  * Returns: number of the RX AMPDU assciation canceled for applying current target setting
4370  *
4371  * Blocking function, may sleep
4372  */
rx_ampdu_apply_sta(_adapter * adapter,struct sta_info * sta,u8 accept,u8 size)4373 u8 rx_ampdu_apply_sta(_adapter *adapter, struct sta_info *sta, u8 accept, u8 size)
4374 {
4375 	u8 change_cnt = 0;
4376 	int i;
4377 
4378 	for (i = 0; i < TID_NUM; i++) {
4379 		if (rx_ampdu_apply_sta_tid(adapter, sta, i, accept, size) != 0)
4380 			change_cnt++;
4381 	}
4382 
4383 	return change_cnt;
4384 }
4385 
4386 /**
4387  * rtw_rx_ampdu_apply - Apply the current target RX AMPDU setting for the specific @adapter
4388  * @adapter: the adapter to be applied
4389  *
4390  * Returns: number of the RX AMPDU assciation canceled for applying current target setting
4391  */
rtw_rx_ampdu_apply(_adapter * adapter)4392 u16 rtw_rx_ampdu_apply(_adapter *adapter)
4393 {
4394 	u16 adj_cnt = 0;
4395 	struct sta_info *sta;
4396 	u8 accept = rtw_rx_ampdu_is_accept(adapter);
4397 	u8 size;
4398 
4399 	if (adapter->fix_rx_ampdu_size != RX_AMPDU_SIZE_INVALID)
4400 		size = adapter->fix_rx_ampdu_size;
4401 	else
4402 		size = rtw_rx_ampdu_size(adapter);
4403 
4404 	if (MLME_IS_STA(adapter)) {
4405 		sta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
4406 		if (sta) {
4407 			u8 sta_size = size;
4408 
4409 			if (adapter->fix_rx_ampdu_size == RX_AMPDU_SIZE_INVALID)
4410 				sta_size = rtw_min(size, rx_ampdu_size_sta_limit(adapter, sta));
4411 			adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, sta_size);
4412 		}
4413 		/* TODO: TDLS peer */
4414 #ifdef CONFIG_AP_MODE
4415 	} else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
4416 		_irqL irqL;
4417 		_list *phead, *plist;
4418 		u8 peer_num = 0;
4419 		char peers[NUM_STA];
4420 		struct sta_priv *pstapriv = &adapter->stapriv;
4421 		int i;
4422 
4423 		_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
4424 
4425 		phead = &pstapriv->asoc_list;
4426 		plist = get_next(phead);
4427 
4428 		while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
4429 			int stainfo_offset;
4430 
4431 			sta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
4432 			plist = get_next(plist);
4433 
4434 			stainfo_offset = rtw_stainfo_offset(pstapriv, sta);
4435 			if (stainfo_offset_valid(stainfo_offset))
4436 				peers[peer_num++] = stainfo_offset;
4437 		}
4438 
4439 		_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
4440 
4441 		for (i = 0; i < peer_num; i++) {
4442 			sta = rtw_get_stainfo_by_offset(pstapriv, peers[i]);
4443 			if (sta) {
4444 				u8 sta_size = size;
4445 
4446 				if (adapter->fix_rx_ampdu_size == RX_AMPDU_SIZE_INVALID)
4447 					sta_size = rtw_min(size, rx_ampdu_size_sta_limit(adapter, sta));
4448 				adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, sta_size);
4449 			}
4450 		}
4451 #endif /* CONFIG_AP_MODE */
4452 	}
4453 
4454 	/* TODO: ADHOC */
4455 
4456 	return adj_cnt;
4457 }
4458 
OnAction_back(_adapter * padapter,union recv_frame * precv_frame)4459 unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
4460 {
4461 	u8 *addr;
4462 	struct sta_info *psta = NULL;
4463 	struct recv_reorder_ctrl *preorder_ctrl;
4464 	unsigned char		*frame_body;
4465 	unsigned char		category, action;
4466 	unsigned short	tid, status, reason_code = 0;
4467 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
4468 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
4469 	u8 *pframe = precv_frame->u.hdr.rx_data;
4470 	struct sta_priv *pstapriv = &padapter->stapriv;
4471 	struct registry_priv *pregpriv = &padapter->registrypriv;
4472 
4473 #ifdef CONFIG_80211N_HT
4474 
4475 	RTW_INFO("%s\n", __FUNCTION__);
4476 
4477 	/* check RA matches or not	 */
4478 	if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
4479 		return _SUCCESS;
4480 
4481 #if 0
4482 	/* check A1 matches or not */
4483 	if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
4484 		return _SUCCESS;
4485 #endif
4486 
4487 	if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
4488 		if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
4489 			return _SUCCESS;
4490 
4491 	addr = get_addr2_ptr(pframe);
4492 	psta = rtw_get_stainfo(pstapriv, addr);
4493 
4494 	if (psta == NULL)
4495 		return _SUCCESS;
4496 
4497 	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
4498 
4499 	category = frame_body[0];
4500 	if (category == RTW_WLAN_CATEGORY_BACK) { /* representing Block Ack */
4501 #ifdef CONFIG_TDLS
4502 		if ((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
4503 		    (psta->htpriv.ht_option == _TRUE) &&
4504 		    (psta->htpriv.ampdu_enable == _TRUE))
4505 			RTW_INFO("Recv [%s] from direc link\n", __FUNCTION__);
4506 		else
4507 #endif /* CONFIG_TDLS */
4508 			if (!pmlmeinfo->HT_enable)
4509 				return _SUCCESS;
4510 
4511 		action = frame_body[1];
4512 		RTW_INFO("%s, action=%d\n", __FUNCTION__, action);
4513 		switch (action) {
4514 		case RTW_WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
4515 
4516 			_rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
4517 			/* process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe)); */
4518 			process_addba_req(padapter, (u8 *)&(pmlmeinfo->ADDBA_req), addr);
4519 
4520 			break;
4521 
4522 		case RTW_WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
4523 
4524 			/* status = frame_body[3] | (frame_body[4] << 8); */ /* endian issue */
4525 			status = RTW_GET_LE16(&frame_body[3]);
4526 			tid = ((frame_body[5] >> 2) & 0x7);
4527 			if (status == 0) {
4528 				/* successful */
4529 				RTW_INFO("agg_enable for TID=%d\n", tid);
4530 				psta->htpriv.agg_enable_bitmap |= 1 << tid;
4531 				psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
4532 				/* amsdu in ampdu */
4533 				if (pregpriv->tx_ampdu_amsdu == 0)
4534 					psta->htpriv.tx_amsdu_enable = _FALSE;
4535 				else if (pregpriv->tx_ampdu_amsdu == 1)
4536 					psta->htpriv.tx_amsdu_enable = _TRUE;
4537 				else {
4538 					if (frame_body[5] & 1)
4539 						psta->htpriv.tx_amsdu_enable = _TRUE;
4540 				}
4541 			} else
4542 				psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
4543 
4544 			#ifdef CONFIG_AP_MODE
4545 			if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
4546 				RTW_INFO("%s alive check - rx ADDBA response\n", __func__);
4547 				psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
4548 				psta->expire_to = pstapriv->expire_to;
4549 				psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
4550 			}
4551 			#endif
4552 
4553 			/* RTW_INFO("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap); */
4554 			break;
4555 
4556 		case RTW_WLAN_ACTION_DELBA: /* DELBA */
4557 			if ((frame_body[3] & BIT(3)) == 0) {
4558 				psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
4559 				psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
4560 
4561 				/* reason_code = frame_body[4] | (frame_body[5] << 8); */
4562 				reason_code = RTW_GET_LE16(&frame_body[4]);
4563 			} else if ((frame_body[3] & BIT(3)) == BIT(3)) {
4564 				tid = (frame_body[3] >> 4) & 0x0F;
4565 
4566 				preorder_ctrl = &psta->recvreorder_ctrl[tid];
4567 				preorder_ctrl->enable = _FALSE;
4568 				preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
4569 			}
4570 
4571 			RTW_INFO("%s(): DELBA: %x(%x)\n", __FUNCTION__, pmlmeinfo->agg_enable_bitmap, reason_code);
4572 			/* todo: how to notify the host while receiving DELETE BA */
4573 			break;
4574 
4575 		default:
4576 			break;
4577 		}
4578 	}
4579 #endif /* CONFIG_80211N_HT */
4580 	return _SUCCESS;
4581 }
4582 
4583 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
rtw_build_vendor_ie(_adapter * padapter,unsigned char ** pframe,u8 mgmt_frame_tyte)4584 u32 rtw_build_vendor_ie(_adapter *padapter , unsigned char **pframe , u8 mgmt_frame_tyte)
4585 {
4586 	int vendor_ie_num = 0;
4587 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4588 	u32 len = 0;
4589 
4590 	for (vendor_ie_num = 0 ; vendor_ie_num < WLAN_MAX_VENDOR_IE_NUM ; vendor_ie_num++) {
4591 		if (pmlmepriv->vendor_ielen[vendor_ie_num] > 0 && pmlmepriv->vendor_ie_mask[vendor_ie_num] & mgmt_frame_tyte) {
4592 			_rtw_memcpy(*pframe , pmlmepriv->vendor_ie[vendor_ie_num] , pmlmepriv->vendor_ielen[vendor_ie_num]);
4593 			*pframe +=  pmlmepriv->vendor_ielen[vendor_ie_num];
4594 			len += pmlmepriv->vendor_ielen[vendor_ie_num];
4595 		}
4596 	}
4597 
4598 	return len;
4599 }
4600 #endif
4601 
4602 #ifdef CONFIG_P2P
get_reg_classes_full_count(struct p2p_channels * channel_list)4603 int get_reg_classes_full_count(struct p2p_channels *channel_list)
4604 {
4605 	int cnt = 0;
4606 	int i;
4607 
4608 	for (i = 0; i < channel_list->reg_classes; i++)
4609 		cnt += channel_list->reg_class[i].channels;
4610 
4611 	return cnt;
4612 }
4613 
issue_p2p_GO_request(_adapter * padapter,u8 * raddr)4614 void issue_p2p_GO_request(_adapter *padapter, u8 *raddr)
4615 {
4616 	struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
4617 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4618 	u8			action = P2P_PUB_ACTION_ACTION;
4619 	u32			p2poui = cpu_to_be32(P2POUI);
4620 	u8			oui_subtype = P2P_GO_NEGO_REQ;
4621 	u8			wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
4622 	u8			wpsielen = 0, p2pielen = 0;
4623 	u16			len_channellist_attr = 0;
4624 #ifdef CONFIG_WFD
4625 	u32					wfdielen = 0;
4626 #endif
4627 
4628 	struct xmit_frame			*pmgntframe;
4629 	struct pkt_attrib			*pattrib;
4630 	unsigned char					*pframe;
4631 	struct rtw_ieee80211_hdr	*pwlanhdr;
4632 	unsigned short				*fctrl;
4633 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
4634 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
4635 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4636 
4637 
4638 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4639 	if (pmgntframe == NULL)
4640 		return;
4641 
4642 	RTW_INFO("[%s] In\n", __FUNCTION__);
4643 	/* update attribute */
4644 	pattrib = &pmgntframe->attrib;
4645 	update_mgntframe_attrib(padapter, pattrib);
4646 
4647 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4648 
4649 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4650 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4651 
4652 	fctrl = &(pwlanhdr->frame_ctl);
4653 	*(fctrl) = 0;
4654 
4655 	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4656 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4657 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4658 
4659 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4660 	pmlmeext->mgnt_seq++;
4661 	set_frame_sub_type(pframe, WIFI_ACTION);
4662 
4663 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4664 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4665 
4666 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4667 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4668 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4669 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4670 	pwdinfo->negotiation_dialog_token = 1;	/*	Initialize the dialog value */
4671 	pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
4672 
4673 
4674 
4675 	/*	WPS Section */
4676 	wpsielen = 0;
4677 	/*	WPS OUI */
4678 	*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
4679 	wpsielen += 4;
4680 
4681 	/*	WPS version */
4682 	/*	Type: */
4683 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
4684 	wpsielen += 2;
4685 
4686 	/*	Length: */
4687 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4688 	wpsielen += 2;
4689 
4690 	/*	Value: */
4691 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
4692 
4693 	/*	Device Password ID */
4694 	/*	Type: */
4695 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
4696 	wpsielen += 2;
4697 
4698 	/*	Length: */
4699 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
4700 	wpsielen += 2;
4701 
4702 	/*	Value: */
4703 
4704 	if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN)
4705 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
4706 	else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN)
4707 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
4708 	else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC)
4709 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
4710 
4711 	wpsielen += 2;
4712 
4713 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
4714 
4715 
4716 	/*	P2P IE Section. */
4717 
4718 	/*	P2P OUI */
4719 	p2pielen = 0;
4720 	p2pie[p2pielen++] = 0x50;
4721 	p2pie[p2pielen++] = 0x6F;
4722 	p2pie[p2pielen++] = 0x9A;
4723 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
4724 
4725 	/*	Commented by Albert 20110306 */
4726 	/*	According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes */
4727 	/*	1. P2P Capability */
4728 	/*	2. Group Owner Intent */
4729 	/*	3. Configuration Timeout */
4730 	/*	4. Listen Channel */
4731 	/*	5. Extended Listen Timing */
4732 	/*	6. Intended P2P Interface Address */
4733 	/*	7. Channel List */
4734 	/*	8. P2P Device Info */
4735 	/*	9. Operating Channel */
4736 
4737 
4738 	/*	P2P Capability */
4739 	/*	Type: */
4740 	p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
4741 
4742 	/*	Length: */
4743 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4744 	p2pielen += 2;
4745 
4746 	/*	Value: */
4747 	/*	Device Capability Bitmap, 1 byte */
4748 	p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
4749 
4750 	/*	Group Capability Bitmap, 1 byte */
4751 	if (pwdinfo->persistent_supported)
4752 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4753 	else
4754 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
4755 
4756 
4757 	/*	Group Owner Intent */
4758 	/*	Type: */
4759 	p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
4760 
4761 	/*	Length: */
4762 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
4763 	p2pielen += 2;
4764 
4765 	/*	Value: */
4766 	/*	Todo the tie breaker bit. */
4767 	p2pie[p2pielen++] = ((pwdinfo->intent << 1) &  0xFE);
4768 
4769 	/*	Configuration Timeout */
4770 	/*	Type: */
4771 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
4772 
4773 	/*	Length: */
4774 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4775 	p2pielen += 2;
4776 
4777 	/*	Value: */
4778 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
4779 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
4780 
4781 
4782 	/*	Listen Channel */
4783 	/*	Type: */
4784 	p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
4785 
4786 	/*	Length: */
4787 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
4788 	p2pielen += 2;
4789 
4790 	/*	Value: */
4791 	/*	Country String */
4792 	p2pie[p2pielen++] = 'X';
4793 	p2pie[p2pielen++] = 'X';
4794 
4795 	/*	The third byte should be set to 0x04. */
4796 	/*	Described in the "Operating Channel Attribute" section. */
4797 	p2pie[p2pielen++] = 0x04;
4798 
4799 	/*	Operating Class */
4800 	p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
4801 
4802 	/*	Channel Number */
4803 	p2pie[p2pielen++] = pwdinfo->listen_channel;	/*	listening channel number */
4804 
4805 
4806 	/*	Extended Listen Timing ATTR */
4807 	/*	Type: */
4808 	p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
4809 
4810 	/*	Length: */
4811 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
4812 	p2pielen += 2;
4813 
4814 	/*	Value: */
4815 	/*	Availability Period */
4816 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
4817 	p2pielen += 2;
4818 
4819 	/*	Availability Interval */
4820 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
4821 	p2pielen += 2;
4822 
4823 
4824 	/*	Intended P2P Interface Address */
4825 	/*	Type: */
4826 	p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
4827 
4828 	/*	Length: */
4829 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
4830 	p2pielen += 2;
4831 
4832 	/*	Value: */
4833 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4834 	p2pielen += ETH_ALEN;
4835 
4836 
4837 	/*	Channel List */
4838 	/*	Type: */
4839 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
4840 
4841 	/* Length: */
4842 	/* Country String(3) */
4843 	/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
4844 	/* + number of channels in all classes */
4845 	len_channellist_attr = 3
4846 		       + (1 + 1) * (u16)(ch_list->reg_classes)
4847 		       + get_reg_classes_full_count(ch_list);
4848 
4849 #ifdef CONFIG_CONCURRENT_MODE
4850 	if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4851 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
4852 	else
4853 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4854 #else
4855 
4856 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4857 
4858 #endif
4859 	p2pielen += 2;
4860 
4861 	/*	Value: */
4862 	/*	Country String */
4863 	p2pie[p2pielen++] = 'X';
4864 	p2pie[p2pielen++] = 'X';
4865 
4866 	/*	The third byte should be set to 0x04. */
4867 	/*	Described in the "Operating Channel Attribute" section. */
4868 	p2pie[p2pielen++] = 0x04;
4869 
4870 	/*	Channel Entry List */
4871 
4872 #ifdef CONFIG_CONCURRENT_MODE
4873 	if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
4874 		u8 union_ch = rtw_mi_get_union_chan(padapter);
4875 
4876 		/*	Operating Class */
4877 		if (union_ch > 14) {
4878 			if (union_ch >= 149)
4879 				p2pie[p2pielen++] = 0x7c;
4880 			else
4881 				p2pie[p2pielen++] = 0x73;
4882 		} else
4883 			p2pie[p2pielen++] = 0x51;
4884 
4885 
4886 		/*	Number of Channels */
4887 		/*	Just support 1 channel and this channel is AP's channel */
4888 		p2pie[p2pielen++] = 1;
4889 
4890 		/*	Channel List */
4891 		p2pie[p2pielen++] = union_ch;
4892 	} else
4893 #endif /* CONFIG_CONCURRENT_MODE */
4894 	{
4895 		int i, j;
4896 		for (j = 0; j < ch_list->reg_classes; j++) {
4897 			/*	Operating Class */
4898 			p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
4899 
4900 			/*	Number of Channels */
4901 			p2pie[p2pielen++] = ch_list->reg_class[j].channels;
4902 
4903 			/*	Channel List */
4904 			for (i = 0; i < ch_list->reg_class[j].channels; i++)
4905 				p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
4906 		}
4907 	}
4908 
4909 	/*	Device Info */
4910 	/*	Type: */
4911 	p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
4912 
4913 	/*	Length: */
4914 	/*	21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)  */
4915 	/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
4916 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
4917 	p2pielen += 2;
4918 
4919 	/*	Value: */
4920 	/*	P2P Device Address */
4921 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4922 	p2pielen += ETH_ALEN;
4923 
4924 	/*	Config Method */
4925 	/*	This field should be big endian. Noted by P2P specification. */
4926 
4927 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
4928 
4929 	p2pielen += 2;
4930 
4931 	/*	Primary Device Type */
4932 	/*	Category ID */
4933 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4934 	p2pielen += 2;
4935 
4936 	/*	OUI */
4937 	*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
4938 	p2pielen += 4;
4939 
4940 	/*	Sub Category ID */
4941 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4942 	p2pielen += 2;
4943 
4944 	/*	Number of Secondary Device Types */
4945 	p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
4946 
4947 	/*	Device Name */
4948 	/*	Type: */
4949 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4950 	p2pielen += 2;
4951 
4952 	/*	Length: */
4953 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
4954 	p2pielen += 2;
4955 
4956 	/*	Value: */
4957 	_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
4958 	p2pielen += pwdinfo->device_name_len;
4959 
4960 
4961 	/*	Operating Channel */
4962 	/*	Type: */
4963 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
4964 
4965 	/*	Length: */
4966 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
4967 	p2pielen += 2;
4968 
4969 	/*	Value: */
4970 	/*	Country String */
4971 	p2pie[p2pielen++] = 'X';
4972 	p2pie[p2pielen++] = 'X';
4973 
4974 	/*	The third byte should be set to 0x04. */
4975 	/*	Described in the "Operating Channel Attribute" section. */
4976 	p2pie[p2pielen++] = 0x04;
4977 
4978 	/*	Operating Class */
4979 	if (pwdinfo->operating_channel <= 14) {
4980 		/*	Operating Class */
4981 		p2pie[p2pielen++] = 0x51;
4982 	} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
4983 		/*	Operating Class */
4984 		p2pie[p2pielen++] = 0x73;
4985 	} else {
4986 		/*	Operating Class */
4987 		p2pie[p2pielen++] = 0x7c;
4988 	}
4989 
4990 	/*	Channel Number */
4991 	p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
4992 
4993 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
4994 
4995 #ifdef CONFIG_WFD
4996 	wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
4997 	pframe += wfdielen;
4998 	pattrib->pktlen += wfdielen;
4999 #endif
5000 
5001 	pattrib->last_txcmdsz = pattrib->pktlen;
5002 
5003 	dump_mgntframe(padapter, pmgntframe);
5004 
5005 	return;
5006 
5007 }
5008 
5009 
issue_p2p_GO_response(_adapter * padapter,u8 * raddr,u8 * frame_body,uint len,u8 result)5010 void issue_p2p_GO_response(_adapter *padapter, u8 *raddr, u8 *frame_body, uint len, u8 result)
5011 {
5012 	struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
5013 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5014 	u8			action = P2P_PUB_ACTION_ACTION;
5015 	u32			p2poui = cpu_to_be32(P2POUI);
5016 	u8			oui_subtype = P2P_GO_NEGO_RESP;
5017 	u8			wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
5018 	u8			p2pielen = 0;
5019 	uint			wpsielen = 0;
5020 	u16			wps_devicepassword_id = 0x0000;
5021 	uint			wps_devicepassword_id_len = 0;
5022 	u16			len_channellist_attr = 0;
5023 
5024 	struct xmit_frame			*pmgntframe;
5025 	struct pkt_attrib			*pattrib;
5026 	unsigned char					*pframe;
5027 	struct rtw_ieee80211_hdr	*pwlanhdr;
5028 	unsigned short				*fctrl;
5029 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
5030 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5031 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
5032 
5033 #ifdef CONFIG_WFD
5034 	u32					wfdielen = 0;
5035 #endif
5036 
5037 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5038 	if (pmgntframe == NULL)
5039 		return;
5040 
5041 	RTW_INFO("[%s] In, result = %d\n", __FUNCTION__,  result);
5042 	/* update attribute */
5043 	pattrib = &pmgntframe->attrib;
5044 	update_mgntframe_attrib(padapter, pattrib);
5045 
5046 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5047 
5048 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5049 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5050 
5051 	fctrl = &(pwlanhdr->frame_ctl);
5052 	*(fctrl) = 0;
5053 
5054 	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5055 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5056 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
5057 
5058 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5059 	pmlmeext->mgnt_seq++;
5060 	set_frame_sub_type(pframe, WIFI_ACTION);
5061 
5062 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5063 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5064 
5065 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5066 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5067 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5068 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5069 	pwdinfo->negotiation_dialog_token = frame_body[7];	/*	The Dialog Token of provisioning discovery request frame. */
5070 	pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
5071 
5072 	/*	Commented by Albert 20110328 */
5073 	/*	Try to get the device password ID from the WPS IE of group negotiation request frame */
5074 	/*	WiFi Direct test plan 5.1.15 */
5075 	rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
5076 	wps_devicepassword_id_len = sizeof(wps_devicepassword_id);
5077 	rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8 *) &wps_devicepassword_id, &wps_devicepassword_id_len);
5078 	wps_devicepassword_id = be16_to_cpu(wps_devicepassword_id);
5079 
5080 	_rtw_memset(wpsie, 0x00, 255);
5081 	wpsielen = 0;
5082 
5083 	/*	WPS Section */
5084 	wpsielen = 0;
5085 	/*	WPS OUI */
5086 	*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
5087 	wpsielen += 4;
5088 
5089 	/*	WPS version */
5090 	/*	Type: */
5091 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5092 	wpsielen += 2;
5093 
5094 	/*	Length: */
5095 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5096 	wpsielen += 2;
5097 
5098 	/*	Value: */
5099 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
5100 
5101 	/*	Device Password ID */
5102 	/*	Type: */
5103 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
5104 	wpsielen += 2;
5105 
5106 	/*	Length: */
5107 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
5108 	wpsielen += 2;
5109 
5110 	/*	Value: */
5111 	if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
5112 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
5113 	else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
5114 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
5115 	else
5116 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
5117 	wpsielen += 2;
5118 
5119 	/*	Commented by Kurt 20120113 */
5120 	/*	If some device wants to do p2p handshake without sending prov_disc_req */
5121 	/*	We have to get peer_req_cm from here. */
5122 	if (_rtw_memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) {
5123 		if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
5124 			_rtw_memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
5125 		else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
5126 			_rtw_memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
5127 		else
5128 			_rtw_memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
5129 	}
5130 
5131 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
5132 
5133 
5134 	/*	P2P IE Section. */
5135 
5136 	/*	P2P OUI */
5137 	p2pielen = 0;
5138 	p2pie[p2pielen++] = 0x50;
5139 	p2pie[p2pielen++] = 0x6F;
5140 	p2pie[p2pielen++] = 0x9A;
5141 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
5142 
5143 	/*	Commented by Albert 20100908 */
5144 	/*	According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
5145 	/*	1. Status */
5146 	/*	2. P2P Capability */
5147 	/*	3. Group Owner Intent */
5148 	/*	4. Configuration Timeout */
5149 	/*	5. Operating Channel */
5150 	/*	6. Intended P2P Interface Address */
5151 	/*	7. Channel List */
5152 	/*	8. Device Info */
5153 	/*	9. Group ID	( Only GO ) */
5154 
5155 
5156 	/*	ToDo: */
5157 
5158 	/*	P2P Status */
5159 	/*	Type: */
5160 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
5161 
5162 	/*	Length: */
5163 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5164 	p2pielen += 2;
5165 
5166 	/*	Value: */
5167 	p2pie[p2pielen++] = result;
5168 
5169 	/*	P2P Capability */
5170 	/*	Type: */
5171 	p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
5172 
5173 	/*	Length: */
5174 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5175 	p2pielen += 2;
5176 
5177 	/*	Value: */
5178 	/*	Device Capability Bitmap, 1 byte */
5179 
5180 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
5181 		/*	Commented by Albert 2011/03/08 */
5182 		/*	According to the P2P specification */
5183 		/*	if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
5184 		p2pie[p2pielen++] = 0;
5185 	} else {
5186 		/*	Be group owner or meet the error case */
5187 		p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
5188 	}
5189 
5190 	/*	Group Capability Bitmap, 1 byte */
5191 	if (pwdinfo->persistent_supported)
5192 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
5193 	else
5194 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
5195 
5196 	/*	Group Owner Intent */
5197 	/*	Type: */
5198 	p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
5199 
5200 	/*	Length: */
5201 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5202 	p2pielen += 2;
5203 
5204 	/*	Value: */
5205 	if (pwdinfo->peer_intent & 0x01) {
5206 		/*	Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
5207 		p2pie[p2pielen++] = (pwdinfo->intent << 1);
5208 	} else {
5209 		/*	Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
5210 		p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
5211 	}
5212 
5213 
5214 	/*	Configuration Timeout */
5215 	/*	Type: */
5216 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
5217 
5218 	/*	Length: */
5219 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5220 	p2pielen += 2;
5221 
5222 	/*	Value: */
5223 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
5224 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
5225 
5226 	/*	Operating Channel */
5227 	/*	Type: */
5228 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5229 
5230 	/*	Length: */
5231 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5232 	p2pielen += 2;
5233 
5234 	/*	Value: */
5235 	/*	Country String */
5236 	p2pie[p2pielen++] = 'X';
5237 	p2pie[p2pielen++] = 'X';
5238 
5239 	/*	The third byte should be set to 0x04. */
5240 	/*	Described in the "Operating Channel Attribute" section. */
5241 	p2pie[p2pielen++] = 0x04;
5242 
5243 	/*	Operating Class */
5244 	if (pwdinfo->operating_channel <= 14) {
5245 		/*	Operating Class */
5246 		p2pie[p2pielen++] = 0x51;
5247 	} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
5248 		/*	Operating Class */
5249 		p2pie[p2pielen++] = 0x73;
5250 	} else {
5251 		/*	Operating Class */
5252 		p2pie[p2pielen++] = 0x7c;
5253 	}
5254 
5255 	/*	Channel Number */
5256 	p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
5257 
5258 	/*	Intended P2P Interface Address	 */
5259 	/*	Type: */
5260 	p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
5261 
5262 	/*	Length: */
5263 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
5264 	p2pielen += 2;
5265 
5266 	/*	Value: */
5267 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5268 	p2pielen += ETH_ALEN;
5269 
5270 	/*	Channel List */
5271 	/*	Type: */
5272 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5273 
5274 	/* Country String(3) */
5275 	/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
5276 	/* + number of channels in all classes */
5277 	len_channellist_attr = 3
5278 		       + (1 + 1) * (u16)ch_list->reg_classes
5279 		       + get_reg_classes_full_count(ch_list);
5280 
5281 #ifdef CONFIG_CONCURRENT_MODE
5282 	if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5283 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
5284 	else
5285 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5286 #else
5287 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5288 
5289 #endif
5290 	p2pielen += 2;
5291 
5292 	/*	Value: */
5293 	/*	Country String */
5294 	p2pie[p2pielen++] = 'X';
5295 	p2pie[p2pielen++] = 'X';
5296 
5297 	/*	The third byte should be set to 0x04. */
5298 	/*	Described in the "Operating Channel Attribute" section. */
5299 	p2pie[p2pielen++] = 0x04;
5300 
5301 	/*	Channel Entry List */
5302 
5303 #ifdef CONFIG_CONCURRENT_MODE
5304 	if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
5305 
5306 		u8 union_chan = rtw_mi_get_union_chan(padapter);
5307 
5308 		/*Operating Class*/
5309 		if (union_chan > 14) {
5310 			if (union_chan >= 149)
5311 				p2pie[p2pielen++] = 0x7c;
5312 			else
5313 				p2pie[p2pielen++] = 0x73;
5314 
5315 		} else
5316 			p2pie[p2pielen++] = 0x51;
5317 
5318 		/*	Number of Channels
5319 			Just support 1 channel and this channel is AP's channel*/
5320 		p2pie[p2pielen++] = 1;
5321 
5322 		/*Channel List*/
5323 		p2pie[p2pielen++] = union_chan;
5324 	} else
5325 #endif /* CONFIG_CONCURRENT_MODE */
5326 	{
5327 		int i, j;
5328 		for (j = 0; j < ch_list->reg_classes; j++) {
5329 			/*	Operating Class */
5330 			p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
5331 
5332 			/*	Number of Channels */
5333 			p2pie[p2pielen++] = ch_list->reg_class[j].channels;
5334 
5335 			/*	Channel List */
5336 			for (i = 0; i < ch_list->reg_class[j].channels; i++)
5337 				p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
5338 		}
5339 	}
5340 
5341 	/*	Device Info */
5342 	/*	Type: */
5343 	p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
5344 
5345 	/*	Length: */
5346 	/*	21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)  */
5347 	/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
5348 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
5349 	p2pielen += 2;
5350 
5351 	/*	Value: */
5352 	/*	P2P Device Address */
5353 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5354 	p2pielen += ETH_ALEN;
5355 
5356 	/*	Config Method */
5357 	/*	This field should be big endian. Noted by P2P specification. */
5358 
5359 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
5360 
5361 	p2pielen += 2;
5362 
5363 	/*	Primary Device Type */
5364 	/*	Category ID */
5365 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5366 	p2pielen += 2;
5367 
5368 	/*	OUI */
5369 	*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
5370 	p2pielen += 4;
5371 
5372 	/*	Sub Category ID */
5373 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5374 	p2pielen += 2;
5375 
5376 	/*	Number of Secondary Device Types */
5377 	p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
5378 
5379 	/*	Device Name */
5380 	/*	Type: */
5381 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5382 	p2pielen += 2;
5383 
5384 	/*	Length: */
5385 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
5386 	p2pielen += 2;
5387 
5388 	/*	Value: */
5389 	_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
5390 	p2pielen += pwdinfo->device_name_len;
5391 
5392 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5393 		/*	Group ID Attribute */
5394 		/*	Type: */
5395 		p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
5396 
5397 		/*	Length: */
5398 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
5399 		p2pielen += 2;
5400 
5401 		/*	Value: */
5402 		/*	p2P Device Address */
5403 		_rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
5404 		p2pielen += ETH_ALEN;
5405 
5406 		/*	SSID */
5407 		_rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
5408 		p2pielen += pwdinfo->nego_ssidlen;
5409 
5410 	}
5411 
5412 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
5413 
5414 #ifdef CONFIG_WFD
5415 	wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
5416 	pframe += wfdielen;
5417 	pattrib->pktlen += wfdielen;
5418 #endif
5419 
5420 	pattrib->last_txcmdsz = pattrib->pktlen;
5421 
5422 	dump_mgntframe(padapter, pmgntframe);
5423 
5424 	return;
5425 
5426 }
5427 
issue_p2p_GO_confirm(_adapter * padapter,u8 * raddr,u8 result)5428 void issue_p2p_GO_confirm(_adapter *padapter, u8 *raddr, u8 result)
5429 {
5430 
5431 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5432 	u8			action = P2P_PUB_ACTION_ACTION;
5433 	u32			p2poui = cpu_to_be32(P2POUI);
5434 	u8			oui_subtype = P2P_GO_NEGO_CONF;
5435 	u8			p2pie[255] = { 0x00 };
5436 	u8			p2pielen = 0;
5437 
5438 	struct xmit_frame			*pmgntframe;
5439 	struct pkt_attrib			*pattrib;
5440 	unsigned char					*pframe;
5441 	struct rtw_ieee80211_hdr	*pwlanhdr;
5442 	unsigned short				*fctrl;
5443 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
5444 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5445 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
5446 #ifdef CONFIG_WFD
5447 	u32					wfdielen = 0;
5448 #endif
5449 
5450 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5451 	if (pmgntframe == NULL)
5452 		return;
5453 
5454 	RTW_INFO("[%s] In\n", __FUNCTION__);
5455 	/* update attribute */
5456 	pattrib = &pmgntframe->attrib;
5457 	update_mgntframe_attrib(padapter, pattrib);
5458 
5459 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5460 
5461 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5462 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5463 
5464 	fctrl = &(pwlanhdr->frame_ctl);
5465 	*(fctrl) = 0;
5466 
5467 	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5468 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5469 	_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
5470 
5471 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5472 	pmlmeext->mgnt_seq++;
5473 	set_frame_sub_type(pframe, WIFI_ACTION);
5474 
5475 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5476 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5477 
5478 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5479 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5480 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5481 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5482 	pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
5483 
5484 
5485 
5486 	/*	P2P IE Section. */
5487 
5488 	/*	P2P OUI */
5489 	p2pielen = 0;
5490 	p2pie[p2pielen++] = 0x50;
5491 	p2pie[p2pielen++] = 0x6F;
5492 	p2pie[p2pielen++] = 0x9A;
5493 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
5494 
5495 	/*	Commented by Albert 20110306 */
5496 	/*	According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes */
5497 	/*	1. Status */
5498 	/*	2. P2P Capability */
5499 	/*	3. Operating Channel */
5500 	/*	4. Channel List */
5501 	/*	5. Group ID	( if this WiFi is GO ) */
5502 
5503 	/*	P2P Status */
5504 	/*	Type: */
5505 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
5506 
5507 	/*	Length: */
5508 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5509 	p2pielen += 2;
5510 
5511 	/*	Value: */
5512 	p2pie[p2pielen++] = result;
5513 
5514 	/*	P2P Capability */
5515 	/*	Type: */
5516 	p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
5517 
5518 	/*	Length: */
5519 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5520 	p2pielen += 2;
5521 
5522 	/*	Value: */
5523 	/*	Device Capability Bitmap, 1 byte */
5524 	p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
5525 
5526 	/*	Group Capability Bitmap, 1 byte */
5527 	if (pwdinfo->persistent_supported)
5528 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
5529 	else
5530 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
5531 
5532 
5533 	/*	Operating Channel */
5534 	/*	Type: */
5535 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5536 
5537 	/*	Length: */
5538 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5539 	p2pielen += 2;
5540 
5541 	/*	Value: */
5542 	/*	Country String */
5543 	p2pie[p2pielen++] = 'X';
5544 	p2pie[p2pielen++] = 'X';
5545 
5546 	/*	The third byte should be set to 0x04. */
5547 	/*	Described in the "Operating Channel Attribute" section. */
5548 	p2pie[p2pielen++] = 0x04;
5549 
5550 
5551 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
5552 		if (pwdinfo->peer_operating_ch <= 14) {
5553 			/*	Operating Class */
5554 			p2pie[p2pielen++] = 0x51;
5555 		} else if ((pwdinfo->peer_operating_ch >= 36) && (pwdinfo->peer_operating_ch <= 48)) {
5556 			/*	Operating Class */
5557 			p2pie[p2pielen++] = 0x73;
5558 		} else {
5559 			/*	Operating Class */
5560 			p2pie[p2pielen++] = 0x7c;
5561 		}
5562 
5563 		p2pie[p2pielen++] = pwdinfo->peer_operating_ch;
5564 	} else {
5565 		if (pwdinfo->operating_channel <= 14) {
5566 			/*	Operating Class */
5567 			p2pie[p2pielen++] = 0x51;
5568 		} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
5569 			/*	Operating Class */
5570 			p2pie[p2pielen++] = 0x73;
5571 		} else {
5572 			/*	Operating Class */
5573 			p2pie[p2pielen++] = 0x7c;
5574 		}
5575 
5576 		/*	Channel Number */
5577 		p2pie[p2pielen++] = pwdinfo->operating_channel;		/*	Use the listen channel as the operating channel */
5578 	}
5579 
5580 
5581 	/*	Channel List */
5582 	/*	Type: */
5583 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5584 
5585 	*(u16 *)(p2pie + p2pielen) = 6;
5586 	p2pielen += 2;
5587 
5588 	/*	Country String */
5589 	p2pie[p2pielen++] = 'X';
5590 	p2pie[p2pielen++] = 'X';
5591 
5592 	/*	The third byte should be set to 0x04. */
5593 	/*	Described in the "Operating Channel Attribute" section. */
5594 	p2pie[p2pielen++] = 0x04;
5595 
5596 	/*	Value: */
5597 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
5598 		if (pwdinfo->peer_operating_ch <= 14) {
5599 			/*	Operating Class */
5600 			p2pie[p2pielen++] = 0x51;
5601 		} else if ((pwdinfo->peer_operating_ch >= 36) && (pwdinfo->peer_operating_ch <= 48)) {
5602 			/*	Operating Class */
5603 			p2pie[p2pielen++] = 0x73;
5604 		} else {
5605 			/*	Operating Class */
5606 			p2pie[p2pielen++] = 0x7c;
5607 		}
5608 		p2pie[p2pielen++] = 1;
5609 		p2pie[p2pielen++] = pwdinfo->peer_operating_ch;
5610 	} else {
5611 		if (pwdinfo->operating_channel <= 14) {
5612 			/*	Operating Class */
5613 			p2pie[p2pielen++] = 0x51;
5614 		} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
5615 			/*	Operating Class */
5616 			p2pie[p2pielen++] = 0x73;
5617 		} else {
5618 			/*	Operating Class */
5619 			p2pie[p2pielen++] = 0x7c;
5620 		}
5621 
5622 		/*	Channel Number */
5623 		p2pie[p2pielen++] = 1;
5624 		p2pie[p2pielen++] = pwdinfo->operating_channel;		/*	Use the listen channel as the operating channel */
5625 	}
5626 
5627 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5628 		/*	Group ID Attribute */
5629 		/*	Type: */
5630 		p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
5631 
5632 		/*	Length: */
5633 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
5634 		p2pielen += 2;
5635 
5636 		/*	Value: */
5637 		/*	p2P Device Address */
5638 		_rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
5639 		p2pielen += ETH_ALEN;
5640 
5641 		/*	SSID */
5642 		_rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
5643 		p2pielen += pwdinfo->nego_ssidlen;
5644 	}
5645 
5646 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
5647 
5648 #ifdef CONFIG_WFD
5649 	wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
5650 	pframe += wfdielen;
5651 	pattrib->pktlen += wfdielen;
5652 #endif
5653 
5654 	pattrib->last_txcmdsz = pattrib->pktlen;
5655 
5656 	dump_mgntframe(padapter, pmgntframe);
5657 
5658 	return;
5659 
5660 }
5661 
issue_p2p_invitation_request(_adapter * padapter,u8 * raddr)5662 void issue_p2p_invitation_request(_adapter *padapter, u8 *raddr)
5663 {
5664 	struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
5665 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5666 	u8			action = P2P_PUB_ACTION_ACTION;
5667 	u32			p2poui = cpu_to_be32(P2POUI);
5668 	u8			oui_subtype = P2P_INVIT_REQ;
5669 	u8			p2pie[255] = { 0x00 };
5670 	u8			p2pielen = 0;
5671 	u8			dialogToken = 3;
5672 	u16			len_channellist_attr = 0;
5673 #ifdef CONFIG_WFD
5674 	u32					wfdielen = 0;
5675 #endif
5676 
5677 	struct xmit_frame			*pmgntframe;
5678 	struct pkt_attrib			*pattrib;
5679 	unsigned char					*pframe;
5680 	struct rtw_ieee80211_hdr	*pwlanhdr;
5681 	unsigned short				*fctrl;
5682 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
5683 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5684 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
5685 
5686 
5687 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5688 	if (pmgntframe == NULL)
5689 		return;
5690 
5691 	/* update attribute */
5692 	pattrib = &pmgntframe->attrib;
5693 	update_mgntframe_attrib(padapter, pattrib);
5694 
5695 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5696 
5697 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5698 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5699 
5700 	fctrl = &(pwlanhdr->frame_ctl);
5701 	*(fctrl) = 0;
5702 
5703 	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5704 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5705 	_rtw_memcpy(pwlanhdr->addr3, raddr,  ETH_ALEN);
5706 
5707 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5708 	pmlmeext->mgnt_seq++;
5709 	set_frame_sub_type(pframe, WIFI_ACTION);
5710 
5711 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5712 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5713 
5714 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5715 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5716 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5717 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5718 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5719 
5720 	/*	P2P IE Section. */
5721 
5722 	/*	P2P OUI */
5723 	p2pielen = 0;
5724 	p2pie[p2pielen++] = 0x50;
5725 	p2pie[p2pielen++] = 0x6F;
5726 	p2pie[p2pielen++] = 0x9A;
5727 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
5728 
5729 	/*	Commented by Albert 20101011 */
5730 	/*	According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes */
5731 	/*	1. Configuration Timeout */
5732 	/*	2. Invitation Flags */
5733 	/*	3. Operating Channel	( Only GO ) */
5734 	/*	4. P2P Group BSSID	( Should be included if I am the GO ) */
5735 	/*	5. Channel List */
5736 	/*	6. P2P Group ID */
5737 	/*	7. P2P Device Info */
5738 
5739 	/*	Configuration Timeout */
5740 	/*	Type: */
5741 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
5742 
5743 	/*	Length: */
5744 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5745 	p2pielen += 2;
5746 
5747 	/*	Value: */
5748 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
5749 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
5750 
5751 	/*	Invitation Flags */
5752 	/*	Type: */
5753 	p2pie[p2pielen++] = P2P_ATTR_INVITATION_FLAGS;
5754 
5755 	/*	Length: */
5756 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5757 	p2pielen += 2;
5758 
5759 	/*	Value: */
5760 	p2pie[p2pielen++] = P2P_INVITATION_FLAGS_PERSISTENT;
5761 
5762 
5763 	/*	Operating Channel */
5764 	/*	Type: */
5765 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5766 
5767 	/*	Length: */
5768 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5769 	p2pielen += 2;
5770 
5771 	/*	Value: */
5772 	/*	Country String */
5773 	p2pie[p2pielen++] = 'X';
5774 	p2pie[p2pielen++] = 'X';
5775 
5776 	/*	The third byte should be set to 0x04. */
5777 	/*	Described in the "Operating Channel Attribute" section. */
5778 	p2pie[p2pielen++] = 0x04;
5779 
5780 	/*	Operating Class */
5781 	if (pwdinfo->invitereq_info.operating_ch <= 14)
5782 		p2pie[p2pielen++] = 0x51;
5783 	else if ((pwdinfo->invitereq_info.operating_ch >= 36) && (pwdinfo->invitereq_info.operating_ch <= 48))
5784 		p2pie[p2pielen++] = 0x73;
5785 	else
5786 		p2pie[p2pielen++] = 0x7c;
5787 
5788 	/*	Channel Number */
5789 	p2pie[p2pielen++] = pwdinfo->invitereq_info.operating_ch;	/*	operating channel number */
5790 
5791 	if (_rtw_memcmp(adapter_mac_addr(padapter), pwdinfo->invitereq_info.go_bssid, ETH_ALEN)) {
5792 		/*	P2P Group BSSID */
5793 		/*	Type: */
5794 		p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
5795 
5796 		/*	Length: */
5797 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
5798 		p2pielen += 2;
5799 
5800 		/*	Value: */
5801 		/*	P2P Device Address for GO */
5802 		_rtw_memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
5803 		p2pielen += ETH_ALEN;
5804 	}
5805 
5806 	/*	Channel List */
5807 	/*	Type: */
5808 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5809 
5810 
5811 	/*	Length: */
5812 	/* Country String(3) */
5813 	/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
5814 	/* + number of channels in all classes */
5815 	len_channellist_attr = 3
5816 		       + (1 + 1) * (u16)ch_list->reg_classes
5817 		       + get_reg_classes_full_count(ch_list);
5818 
5819 #ifdef CONFIG_CONCURRENT_MODE
5820 	if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5821 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
5822 	else
5823 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5824 #else
5825 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5826 #endif
5827 	p2pielen += 2;
5828 
5829 	/*	Value: */
5830 	/*	Country String */
5831 	p2pie[p2pielen++] = 'X';
5832 	p2pie[p2pielen++] = 'X';
5833 
5834 	/*	The third byte should be set to 0x04. */
5835 	/*	Described in the "Operating Channel Attribute" section. */
5836 	p2pie[p2pielen++] = 0x04;
5837 
5838 	/*	Channel Entry List */
5839 #ifdef CONFIG_CONCURRENT_MODE
5840 	if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
5841 		u8 union_ch =  rtw_mi_get_union_chan(padapter);
5842 
5843 		/*	Operating Class */
5844 		if (union_ch > 14) {
5845 			if (union_ch >= 149)
5846 				p2pie[p2pielen++] = 0x7c;
5847 			else
5848 				p2pie[p2pielen++] = 0x73;
5849 		} else
5850 			p2pie[p2pielen++] = 0x51;
5851 
5852 
5853 		/*	Number of Channels */
5854 		/*	Just support 1 channel and this channel is AP's channel */
5855 		p2pie[p2pielen++] = 1;
5856 
5857 		/*	Channel List */
5858 		p2pie[p2pielen++] = union_ch;
5859 	} else
5860 #endif /* CONFIG_CONCURRENT_MODE */
5861 	{
5862 		int i, j;
5863 		for (j = 0; j < ch_list->reg_classes; j++) {
5864 			/*	Operating Class */
5865 			p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
5866 
5867 			/*	Number of Channels */
5868 			p2pie[p2pielen++] = ch_list->reg_class[j].channels;
5869 
5870 			/*	Channel List */
5871 			for (i = 0; i < ch_list->reg_class[j].channels; i++)
5872 				p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
5873 		}
5874 	}
5875 
5876 
5877 	/*	P2P Group ID */
5878 	/*	Type: */
5879 	p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
5880 
5881 	/*	Length: */
5882 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(6 + pwdinfo->invitereq_info.ssidlen);
5883 	p2pielen += 2;
5884 
5885 	/*	Value: */
5886 	/*	P2P Device Address for GO */
5887 	_rtw_memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
5888 	p2pielen += ETH_ALEN;
5889 
5890 	/*	SSID */
5891 	_rtw_memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen);
5892 	p2pielen += pwdinfo->invitereq_info.ssidlen;
5893 
5894 
5895 	/*	Device Info */
5896 	/*	Type: */
5897 	p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
5898 
5899 	/*	Length: */
5900 	/*	21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)  */
5901 	/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
5902 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
5903 	p2pielen += 2;
5904 
5905 	/*	Value: */
5906 	/*	P2P Device Address */
5907 	_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5908 	p2pielen += ETH_ALEN;
5909 
5910 	/*	Config Method */
5911 	/*	This field should be big endian. Noted by P2P specification. */
5912 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
5913 	p2pielen += 2;
5914 
5915 	/*	Primary Device Type */
5916 	/*	Category ID */
5917 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5918 	p2pielen += 2;
5919 
5920 	/*	OUI */
5921 	*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
5922 	p2pielen += 4;
5923 
5924 	/*	Sub Category ID */
5925 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5926 	p2pielen += 2;
5927 
5928 	/*	Number of Secondary Device Types */
5929 	p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
5930 
5931 	/*	Device Name */
5932 	/*	Type: */
5933 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5934 	p2pielen += 2;
5935 
5936 	/*	Length: */
5937 	*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
5938 	p2pielen += 2;
5939 
5940 	/*	Value: */
5941 	_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
5942 	p2pielen += pwdinfo->device_name_len;
5943 
5944 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
5945 
5946 #ifdef CONFIG_WFD
5947 	wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
5948 	pframe += wfdielen;
5949 	pattrib->pktlen += wfdielen;
5950 #endif
5951 
5952 	pattrib->last_txcmdsz = pattrib->pktlen;
5953 
5954 	dump_mgntframe(padapter, pmgntframe);
5955 
5956 	return;
5957 
5958 }
5959 
issue_p2p_invitation_response(_adapter * padapter,u8 * raddr,u8 dialogToken,u8 status_code)5960 void issue_p2p_invitation_response(_adapter *padapter, u8 *raddr, u8 dialogToken, u8 status_code)
5961 {
5962 	struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
5963 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5964 	u8			action = P2P_PUB_ACTION_ACTION;
5965 	u32			p2poui = cpu_to_be32(P2POUI);
5966 	u8			oui_subtype = P2P_INVIT_RESP;
5967 	u8			p2pie[255] = { 0x00 };
5968 	u8			p2pielen = 0;
5969 	u16			len_channellist_attr = 0;
5970 #ifdef CONFIG_WFD
5971 	u32					wfdielen = 0;
5972 #endif
5973 
5974 	struct xmit_frame			*pmgntframe;
5975 	struct pkt_attrib			*pattrib;
5976 	unsigned char					*pframe;
5977 	struct rtw_ieee80211_hdr	*pwlanhdr;
5978 	unsigned short				*fctrl;
5979 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
5980 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
5981 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
5982 
5983 
5984 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5985 	if (pmgntframe == NULL)
5986 		return;
5987 
5988 	/* update attribute */
5989 	pattrib = &pmgntframe->attrib;
5990 	update_mgntframe_attrib(padapter, pattrib);
5991 
5992 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5993 
5994 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5995 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5996 
5997 	fctrl = &(pwlanhdr->frame_ctl);
5998 	*(fctrl) = 0;
5999 
6000 	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
6001 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6002 	_rtw_memcpy(pwlanhdr->addr3, raddr,  ETH_ALEN);
6003 
6004 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6005 	pmlmeext->mgnt_seq++;
6006 	set_frame_sub_type(pframe, WIFI_ACTION);
6007 
6008 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6009 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6010 
6011 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
6012 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
6013 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
6014 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
6015 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
6016 
6017 	/*	P2P IE Section. */
6018 
6019 	/*	P2P OUI */
6020 	p2pielen = 0;
6021 	p2pie[p2pielen++] = 0x50;
6022 	p2pie[p2pielen++] = 0x6F;
6023 	p2pie[p2pielen++] = 0x9A;
6024 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
6025 
6026 	/*	Commented by Albert 20101005 */
6027 	/*	According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
6028 	/*	1. Status */
6029 	/*	2. Configuration Timeout */
6030 	/*	3. Operating Channel	( Only GO ) */
6031 	/*	4. P2P Group BSSID	( Only GO ) */
6032 	/*	5. Channel List */
6033 
6034 	/*	P2P Status */
6035 	/*	Type: */
6036 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
6037 
6038 	/*	Length: */
6039 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
6040 	p2pielen += 2;
6041 
6042 	/*	Value: */
6043 	/*	When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. */
6044 	/*	Sent the event receiving the P2P Invitation Req frame to DMP UI. */
6045 	/*	DMP had to compare the MAC address to find out the profile. */
6046 	/*	So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. */
6047 	/*	If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req */
6048 	/*	to NB to rebuild the persistent group. */
6049 	p2pie[p2pielen++] = status_code;
6050 
6051 	/*	Configuration Timeout */
6052 	/*	Type: */
6053 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
6054 
6055 	/*	Length: */
6056 	*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
6057 	p2pielen += 2;
6058 
6059 	/*	Value: */
6060 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
6061 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
6062 
6063 	if (status_code == P2P_STATUS_SUCCESS) {
6064 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6065 			/*	The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
6066 			/*	In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
6067 			/*	First one is operating channel attribute. */
6068 			/*	Second one is P2P Group BSSID attribute. */
6069 
6070 			/*	Operating Channel */
6071 			/*	Type: */
6072 			p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
6073 
6074 			/*	Length: */
6075 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
6076 			p2pielen += 2;
6077 
6078 			/*	Value: */
6079 			/*	Country String */
6080 			p2pie[p2pielen++] = 'X';
6081 			p2pie[p2pielen++] = 'X';
6082 
6083 			/*	The third byte should be set to 0x04. */
6084 			/*	Described in the "Operating Channel Attribute" section. */
6085 			p2pie[p2pielen++] = 0x04;
6086 
6087 			/*	Operating Class */
6088 			p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
6089 
6090 			/*	Channel Number */
6091 			p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
6092 
6093 
6094 			/*	P2P Group BSSID */
6095 			/*	Type: */
6096 			p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
6097 
6098 			/*	Length: */
6099 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
6100 			p2pielen += 2;
6101 
6102 			/*	Value: */
6103 			/*	P2P Device Address for GO */
6104 			_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
6105 			p2pielen += ETH_ALEN;
6106 
6107 		}
6108 
6109 		/*	Channel List */
6110 		/*	Type: */
6111 		p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
6112 
6113 		/*	Length: */
6114 		/* Country String(3) */
6115 		/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
6116 		/* + number of channels in all classes */
6117 		len_channellist_attr = 3
6118 			+ (1 + 1) * (u16)ch_list->reg_classes
6119 			+ get_reg_classes_full_count(ch_list);
6120 
6121 #ifdef CONFIG_CONCURRENT_MODE
6122 		if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
6123 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
6124 		else
6125 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
6126 #else
6127 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
6128 #endif
6129 		p2pielen += 2;
6130 
6131 		/*	Value: */
6132 		/*	Country String */
6133 		p2pie[p2pielen++] = 'X';
6134 		p2pie[p2pielen++] = 'X';
6135 
6136 		/*	The third byte should be set to 0x04. */
6137 		/*	Described in the "Operating Channel Attribute" section. */
6138 		p2pie[p2pielen++] = 0x04;
6139 
6140 		/*	Channel Entry List */
6141 #ifdef CONFIG_CONCURRENT_MODE
6142 		if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
6143 			u8 union_ch = rtw_mi_get_union_chan(padapter);
6144 
6145 			/*	Operating Class */
6146 			if (union_ch > 14) {
6147 				if (union_ch >= 149)
6148 					p2pie[p2pielen++]  = 0x7c;
6149 				else
6150 					p2pie[p2pielen++] = 0x73;
6151 			} else
6152 				p2pie[p2pielen++] = 0x51;
6153 
6154 
6155 			/*	Number of Channels */
6156 			/*	Just support 1 channel and this channel is AP's channel */
6157 			p2pie[p2pielen++] = 1;
6158 
6159 			/*	Channel List */
6160 			p2pie[p2pielen++] = union_ch;
6161 		} else
6162 #endif /* CONFIG_CONCURRENT_MODE */
6163 		{
6164 			int i, j;
6165 			for (j = 0; j < ch_list->reg_classes; j++) {
6166 				/*	Operating Class */
6167 				p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
6168 
6169 				/*	Number of Channels */
6170 				p2pie[p2pielen++] = ch_list->reg_class[j].channels;
6171 
6172 				/*	Channel List */
6173 				for (i = 0; i < ch_list->reg_class[j].channels; i++)
6174 					p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
6175 			}
6176 		}
6177 	}
6178 
6179 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
6180 
6181 #ifdef CONFIG_WFD
6182 	wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
6183 	pframe += wfdielen;
6184 	pattrib->pktlen += wfdielen;
6185 #endif
6186 
6187 	pattrib->last_txcmdsz = pattrib->pktlen;
6188 
6189 	dump_mgntframe(padapter, pmgntframe);
6190 
6191 	return;
6192 
6193 }
6194 
issue_p2p_provision_request(_adapter * padapter,u8 * pssid,u8 ussidlen,u8 * pdev_raddr)6195 void issue_p2p_provision_request(_adapter *padapter, u8 *pssid, u8 ussidlen, u8 *pdev_raddr)
6196 {
6197 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
6198 	u8			action = P2P_PUB_ACTION_ACTION;
6199 	u8			dialogToken = 1;
6200 	u32			p2poui = cpu_to_be32(P2POUI);
6201 	u8			oui_subtype = P2P_PROVISION_DISC_REQ;
6202 	u8			wpsie[100] = { 0x00 };
6203 	u8			wpsielen = 0;
6204 	u32			p2pielen = 0;
6205 #ifdef CONFIG_WFD
6206 	u32					wfdielen = 0;
6207 #endif
6208 
6209 	struct xmit_frame			*pmgntframe;
6210 	struct pkt_attrib			*pattrib;
6211 	unsigned char					*pframe;
6212 	struct rtw_ieee80211_hdr	*pwlanhdr;
6213 	unsigned short				*fctrl;
6214 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
6215 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6216 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6217 
6218 
6219 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
6220 	if (pmgntframe == NULL)
6221 		return;
6222 
6223 	RTW_INFO("[%s] In\n", __FUNCTION__);
6224 	/* update attribute */
6225 	pattrib = &pmgntframe->attrib;
6226 	update_mgntframe_attrib(padapter, pattrib);
6227 
6228 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6229 
6230 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6231 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6232 
6233 	fctrl = &(pwlanhdr->frame_ctl);
6234 	*(fctrl) = 0;
6235 
6236 	_rtw_memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
6237 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6238 	_rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
6239 
6240 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6241 	pmlmeext->mgnt_seq++;
6242 	set_frame_sub_type(pframe, WIFI_ACTION);
6243 
6244 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6245 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6246 
6247 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
6248 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
6249 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
6250 	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
6251 	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
6252 
6253 	p2pielen = build_prov_disc_request_p2p_ie(pwdinfo, pframe, pssid, ussidlen, pdev_raddr);
6254 
6255 	pframe += p2pielen;
6256 	pattrib->pktlen += p2pielen;
6257 
6258 	wpsielen = 0;
6259 	/*	WPS OUI */
6260 	*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6261 	wpsielen += 4;
6262 
6263 	/*	WPS version */
6264 	/*	Type: */
6265 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6266 	wpsielen += 2;
6267 
6268 	/*	Length: */
6269 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6270 	wpsielen += 2;
6271 
6272 	/*	Value: */
6273 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
6274 
6275 	/*	Config Method */
6276 	/*	Type: */
6277 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
6278 	wpsielen += 2;
6279 
6280 	/*	Length: */
6281 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
6282 	wpsielen += 2;
6283 
6284 	/*	Value: */
6285 	*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
6286 	wpsielen += 2;
6287 
6288 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
6289 
6290 
6291 #ifdef CONFIG_WFD
6292 	wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
6293 	pframe += wfdielen;
6294 	pattrib->pktlen += wfdielen;
6295 #endif
6296 
6297 	pattrib->last_txcmdsz = pattrib->pktlen;
6298 
6299 	dump_mgntframe(padapter, pmgntframe);
6300 
6301 	return;
6302 
6303 }
6304 
6305 
is_matched_in_profilelist(u8 * peermacaddr,struct profile_info * profileinfo)6306 u8 is_matched_in_profilelist(u8 *peermacaddr, struct profile_info *profileinfo)
6307 {
6308 	u8 i, match_result = 0;
6309 
6310 	RTW_INFO("[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
6311 		peermacaddr[0], peermacaddr[1], peermacaddr[2], peermacaddr[3], peermacaddr[4], peermacaddr[5]);
6312 
6313 	for (i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++) {
6314 		RTW_INFO("[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
6315 			profileinfo->peermac[0], profileinfo->peermac[1], profileinfo->peermac[2], profileinfo->peermac[3], profileinfo->peermac[4], profileinfo->peermac[5]);
6316 		if (_rtw_memcmp(peermacaddr, profileinfo->peermac, ETH_ALEN)) {
6317 			match_result = 1;
6318 			RTW_INFO("[%s] Match!\n", __FUNCTION__);
6319 			break;
6320 		}
6321 	}
6322 
6323 	return match_result ;
6324 }
6325 
issue_probersp_p2p(_adapter * padapter,unsigned char * da)6326 void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
6327 {
6328 	struct xmit_frame			*pmgntframe;
6329 	struct pkt_attrib			*pattrib;
6330 	unsigned char					*pframe;
6331 	struct rtw_ieee80211_hdr	*pwlanhdr;
6332 	unsigned short				*fctrl;
6333 	unsigned char					*mac;
6334 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
6335 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6336 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6337 	/* WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network); */
6338 	u16					beacon_interval = 100;
6339 	u16					capInfo = 0;
6340 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6341 	u8					wpsie[255] = { 0x00 };
6342 	u32					wpsielen = 0, p2pielen = 0;
6343 #ifdef CONFIG_WFD
6344 	u32					wfdielen = 0;
6345 #endif
6346 
6347 	/* RTW_INFO("%s\n", __FUNCTION__); */
6348 
6349 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
6350 	if (pmgntframe == NULL)
6351 		return;
6352 
6353 	/* update attribute */
6354 	pattrib = &pmgntframe->attrib;
6355 	update_mgntframe_attrib(padapter, pattrib);
6356 
6357 	if (IS_CCK_RATE(pattrib->rate)) {
6358 		/* force OFDM 6M rate */
6359 		pattrib->rate = MGN_6M;
6360 		pattrib->raid = rtw_get_mgntframe_raid(padapter, WIRELESS_11G);
6361 	}
6362 
6363 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6364 
6365 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6366 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6367 
6368 	mac = adapter_mac_addr(padapter);
6369 
6370 	fctrl = &(pwlanhdr->frame_ctl);
6371 	*(fctrl) = 0;
6372 	_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6373 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6374 
6375 	/*	Use the device address for BSSID field.	 */
6376 	_rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
6377 
6378 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6379 	pmlmeext->mgnt_seq++;
6380 	set_frame_sub_type(fctrl, WIFI_PROBERSP);
6381 
6382 	pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6383 	pattrib->pktlen = pattrib->hdrlen;
6384 	pframe += pattrib->hdrlen;
6385 
6386 	/* timestamp will be inserted by hardware */
6387 	pframe += 8;
6388 	pattrib->pktlen += 8;
6389 
6390 	/* beacon interval: 2 bytes */
6391 	_rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
6392 	pframe += 2;
6393 	pattrib->pktlen += 2;
6394 
6395 	/*	capability info: 2 bytes */
6396 	/*	ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
6397 	capInfo |= cap_ShortPremble;
6398 	capInfo |= cap_ShortSlot;
6399 
6400 	_rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
6401 	pframe += 2;
6402 	pattrib->pktlen += 2;
6403 
6404 
6405 	/* SSID */
6406 	pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
6407 
6408 	/* supported rates... */
6409 	/*	Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
6410 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
6411 
6412 	/* DS parameter set */
6413 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
6414 
6415 #ifdef CONFIG_IOCTL_CFG80211
6416 	if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
6417 		if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
6418 			/* WPS IE */
6419 			_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
6420 			pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
6421 			pframe += pmlmepriv->wps_probe_resp_ie_len;
6422 
6423 			/* P2P IE */
6424 			_rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
6425 			pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
6426 			pframe += pmlmepriv->p2p_probe_resp_ie_len;
6427 		}
6428 	} else
6429 #endif /* CONFIG_IOCTL_CFG80211		 */
6430 	{
6431 
6432 		/*	Todo: WPS IE */
6433 		/*	Noted by Albert 20100907 */
6434 		/*	According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6435 
6436 		wpsielen = 0;
6437 		/*	WPS OUI */
6438 		*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6439 		wpsielen += 4;
6440 
6441 		/*	WPS version */
6442 		/*	Type: */
6443 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6444 		wpsielen += 2;
6445 
6446 		/*	Length: */
6447 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6448 		wpsielen += 2;
6449 
6450 		/*	Value: */
6451 		wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
6452 
6453 		/*	WiFi Simple Config State */
6454 		/*	Type: */
6455 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
6456 		wpsielen += 2;
6457 
6458 		/*	Length: */
6459 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6460 		wpsielen += 2;
6461 
6462 		/*	Value: */
6463 		wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;	/*	Not Configured. */
6464 
6465 		/*	Response Type */
6466 		/*	Type: */
6467 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
6468 		wpsielen += 2;
6469 
6470 		/*	Length: */
6471 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6472 		wpsielen += 2;
6473 
6474 		/*	Value: */
6475 		wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
6476 
6477 		/*	UUID-E */
6478 		/*	Type: */
6479 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6480 		wpsielen += 2;
6481 
6482 		/*	Length: */
6483 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6484 		wpsielen += 2;
6485 
6486 		/*	Value: */
6487 		if (pwdinfo->external_uuid == 0) {
6488 			_rtw_memset(wpsie + wpsielen, 0x0, 16);
6489 			_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6490 		} else
6491 			_rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6492 		wpsielen += 0x10;
6493 
6494 		/*	Manufacturer */
6495 		/*	Type: */
6496 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
6497 		wpsielen += 2;
6498 
6499 		/*	Length: */
6500 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
6501 		wpsielen += 2;
6502 
6503 		/*	Value: */
6504 		_rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
6505 		wpsielen += 7;
6506 
6507 		/*	Model Name */
6508 		/*	Type: */
6509 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
6510 		wpsielen += 2;
6511 
6512 		/*	Length: */
6513 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
6514 		wpsielen += 2;
6515 
6516 		/*	Value: */
6517 		_rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
6518 		wpsielen += 6;
6519 
6520 		/*	Model Number */
6521 		/*	Type: */
6522 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
6523 		wpsielen += 2;
6524 
6525 		/*	Length: */
6526 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6527 		wpsielen += 2;
6528 
6529 		/*	Value: */
6530 		wpsie[wpsielen++] = 0x31;		/*	character 1 */
6531 
6532 		/*	Serial Number */
6533 		/*	Type: */
6534 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
6535 		wpsielen += 2;
6536 
6537 		/*	Length: */
6538 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
6539 		wpsielen += 2;
6540 
6541 		/*	Value: */
6542 		_rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
6543 		wpsielen += ETH_ALEN;
6544 
6545 		/*	Primary Device Type */
6546 		/*	Type: */
6547 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6548 		wpsielen += 2;
6549 
6550 		/*	Length: */
6551 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6552 		wpsielen += 2;
6553 
6554 		/*	Value: */
6555 		/*	Category ID */
6556 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6557 		wpsielen += 2;
6558 
6559 		/*	OUI */
6560 		*(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6561 		wpsielen += 4;
6562 
6563 		/*	Sub Category ID */
6564 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6565 		wpsielen += 2;
6566 
6567 		/*	Device Name */
6568 		/*	Type: */
6569 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6570 		wpsielen += 2;
6571 
6572 		/*	Length: */
6573 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
6574 		wpsielen += 2;
6575 
6576 		/*	Value: */
6577 		_rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
6578 		wpsielen += pwdinfo->device_name_len;
6579 
6580 		/*	Config Method */
6581 		/*	Type: */
6582 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
6583 		wpsielen += 2;
6584 
6585 		/*	Length: */
6586 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
6587 		wpsielen += 2;
6588 
6589 		/*	Value: */
6590 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
6591 		wpsielen += 2;
6592 
6593 
6594 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
6595 
6596 
6597 		p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
6598 		pframe += p2pielen;
6599 		pattrib->pktlen += p2pielen;
6600 	}
6601 
6602 #ifdef CONFIG_WFD
6603 	wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
6604 	pframe += wfdielen;
6605 	pattrib->pktlen += wfdielen;
6606 #endif
6607 
6608 /* Vendor Specific IE */
6609 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
6610 	pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_P2P_PROBERESP_VENDOR_IE_BIT);
6611 #endif
6612 
6613 	pattrib->last_txcmdsz = pattrib->pktlen;
6614 
6615 
6616 	dump_mgntframe(padapter, pmgntframe);
6617 
6618 	return;
6619 
6620 }
6621 
_issue_probereq_p2p(_adapter * padapter,u8 * da,int wait_ack)6622 int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
6623 {
6624 	int ret = _FAIL;
6625 	struct xmit_frame		*pmgntframe;
6626 	struct pkt_attrib		*pattrib;
6627 	unsigned char			*pframe;
6628 	struct rtw_ieee80211_hdr	*pwlanhdr;
6629 	unsigned short		*fctrl;
6630 	unsigned char			*mac;
6631 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
6632 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6633 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6634 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
6635 	u8					wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
6636 	u16					wpsielen = 0, p2pielen = 0;
6637 #ifdef CONFIG_WFD
6638 	u32					wfdielen = 0;
6639 #endif
6640 
6641 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6642 
6643 
6644 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
6645 	if (pmgntframe == NULL)
6646 		goto exit;
6647 
6648 	/* update attribute */
6649 	pattrib = &pmgntframe->attrib;
6650 	update_mgntframe_attrib(padapter, pattrib);
6651 
6652 	if (IS_CCK_RATE(pattrib->rate)) {
6653 		/* force OFDM 6M rate */
6654 		pattrib->rate = MGN_6M;
6655 		pattrib->raid = rtw_get_mgntframe_raid(padapter, WIRELESS_11G);
6656 	}
6657 
6658 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6659 
6660 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6661 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6662 
6663 	mac = adapter_mac_addr(padapter);
6664 
6665 	fctrl = &(pwlanhdr->frame_ctl);
6666 	*(fctrl) = 0;
6667 
6668 	if (da) {
6669 		_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6670 		_rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
6671 	} else {
6672 		if ((pwdinfo->p2p_info.scan_op_ch_only) || (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
6673 			/*	This two flags will be set when this is only the P2P client mode. */
6674 			_rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6675 			_rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6676 		} else {
6677 			/*	broadcast probe request frame */
6678 			_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6679 			_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
6680 		}
6681 	}
6682 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6683 
6684 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6685 	pmlmeext->mgnt_seq++;
6686 	set_frame_sub_type(pframe, WIFI_PROBEREQ);
6687 
6688 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6689 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6690 
6691 	if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
6692 		pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
6693 	else
6694 		pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
6695 	/*	Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 ) */
6696 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
6697 
6698 #ifdef CONFIG_IOCTL_CFG80211
6699 	if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
6700 		if (pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL) {
6701 			/* WPS IE */
6702 			_rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
6703 			pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
6704 			pframe += pmlmepriv->wps_probe_req_ie_len;
6705 
6706 			/* P2P IE */
6707 			_rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
6708 			pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
6709 			pframe += pmlmepriv->p2p_probe_req_ie_len;
6710 		}
6711 	} else
6712 #endif /* CONFIG_IOCTL_CFG80211 */
6713 	{
6714 
6715 		/*	WPS IE */
6716 		/*	Noted by Albert 20110221 */
6717 		/*	According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6718 
6719 		wpsielen = 0;
6720 		/*	WPS OUI */
6721 		*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6722 		wpsielen += 4;
6723 
6724 		/*	WPS version */
6725 		/*	Type: */
6726 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6727 		wpsielen += 2;
6728 
6729 		/*	Length: */
6730 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6731 		wpsielen += 2;
6732 
6733 		/*	Value: */
6734 		wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
6735 
6736 		if (pmlmepriv->wps_probe_req_ie == NULL) {
6737 			/*	UUID-E */
6738 			/*	Type: */
6739 			*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6740 			wpsielen += 2;
6741 
6742 			/*	Length: */
6743 			*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6744 			wpsielen += 2;
6745 
6746 			/*	Value: */
6747 			if (pwdinfo->external_uuid == 0) {
6748 				_rtw_memset(wpsie + wpsielen, 0x0, 16);
6749 				_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6750 			} else
6751 				_rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6752 			wpsielen += 0x10;
6753 
6754 			/*	Config Method */
6755 			/*	Type: */
6756 			*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
6757 			wpsielen += 2;
6758 
6759 			/*	Length: */
6760 			*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
6761 			wpsielen += 2;
6762 
6763 			/*	Value: */
6764 			*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
6765 			wpsielen += 2;
6766 		}
6767 
6768 		/*	Device Name */
6769 		/*	Type: */
6770 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6771 		wpsielen += 2;
6772 
6773 		/*	Length: */
6774 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
6775 		wpsielen += 2;
6776 
6777 		/*	Value: */
6778 		_rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
6779 		wpsielen += pwdinfo->device_name_len;
6780 
6781 		/*	Primary Device Type */
6782 		/*	Type: */
6783 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6784 		wpsielen += 2;
6785 
6786 		/*	Length: */
6787 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6788 		wpsielen += 2;
6789 
6790 		/*	Value: */
6791 		/*	Category ID */
6792 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_RTK_WIDI);
6793 		wpsielen += 2;
6794 
6795 		/*	OUI */
6796 		*(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6797 		wpsielen += 4;
6798 
6799 		/*	Sub Category ID */
6800 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_RTK_DMP);
6801 		wpsielen += 2;
6802 
6803 		/*	Device Password ID */
6804 		/*	Type: */
6805 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
6806 		wpsielen += 2;
6807 
6808 		/*	Length: */
6809 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
6810 		wpsielen += 2;
6811 
6812 		/*	Value: */
6813 		*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);	/*	Registrar-specified */
6814 		wpsielen += 2;
6815 
6816 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
6817 
6818 		/*	P2P OUI */
6819 		p2pielen = 0;
6820 		p2pie[p2pielen++] = 0x50;
6821 		p2pie[p2pielen++] = 0x6F;
6822 		p2pie[p2pielen++] = 0x9A;
6823 		p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
6824 
6825 		/*	Commented by Albert 20110221 */
6826 		/*	According to the P2P Specification, the probe request frame should contain 5 P2P attributes */
6827 		/*	1. P2P Capability */
6828 		/*	2. P2P Device ID if this probe request wants to find the specific P2P device */
6829 		/*	3. Listen Channel */
6830 		/*	4. Extended Listen Timing */
6831 		/*	5. Operating Channel if this WiFi is working as the group owner now */
6832 
6833 		/*	P2P Capability */
6834 		/*	Type: */
6835 		p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
6836 
6837 		/*	Length: */
6838 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
6839 		p2pielen += 2;
6840 
6841 		/*	Value: */
6842 		/*	Device Capability Bitmap, 1 byte */
6843 		p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
6844 
6845 		/*	Group Capability Bitmap, 1 byte */
6846 		if (pwdinfo->persistent_supported)
6847 			p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
6848 		else
6849 			p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
6850 
6851 		/*	Listen Channel */
6852 		/*	Type: */
6853 		p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
6854 
6855 		/*	Length: */
6856 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
6857 		p2pielen += 2;
6858 
6859 		/*	Value: */
6860 		/*	Country String */
6861 		p2pie[p2pielen++] = 'X';
6862 		p2pie[p2pielen++] = 'X';
6863 
6864 		/*	The third byte should be set to 0x04. */
6865 		/*	Described in the "Operating Channel Attribute" section. */
6866 		p2pie[p2pielen++] = 0x04;
6867 
6868 		/*	Operating Class */
6869 		p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
6870 
6871 		/*	Channel Number */
6872 		p2pie[p2pielen++] = pwdinfo->listen_channel;	/*	listen channel */
6873 
6874 
6875 		/*	Extended Listen Timing */
6876 		/*	Type: */
6877 		p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
6878 
6879 		/*	Length: */
6880 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
6881 		p2pielen += 2;
6882 
6883 		/*	Value: */
6884 		/*	Availability Period */
6885 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
6886 		p2pielen += 2;
6887 
6888 		/*	Availability Interval */
6889 		*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
6890 		p2pielen += 2;
6891 
6892 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6893 			/*	Operating Channel (if this WiFi is working as the group owner now) */
6894 			/*	Type: */
6895 			p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
6896 
6897 			/*	Length: */
6898 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
6899 			p2pielen += 2;
6900 
6901 			/*	Value: */
6902 			/*	Country String */
6903 			p2pie[p2pielen++] = 'X';
6904 			p2pie[p2pielen++] = 'X';
6905 
6906 			/*	The third byte should be set to 0x04. */
6907 			/*	Described in the "Operating Channel Attribute" section. */
6908 			p2pie[p2pielen++] = 0x04;
6909 
6910 			/*	Operating Class */
6911 			p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
6912 
6913 			/*	Channel Number */
6914 			p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
6915 
6916 		}
6917 
6918 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
6919 
6920 	}
6921 
6922 #ifdef CONFIG_WFD
6923 	wfdielen = rtw_append_probe_req_wfd_ie(padapter, pframe);
6924 	pframe += wfdielen;
6925 	pattrib->pktlen += wfdielen;
6926 #endif
6927 
6928 /* Vendor Specific IE */
6929 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
6930 	pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_P2P_PROBEREQ_VENDOR_IE_BIT);
6931 #endif
6932 
6933 	pattrib->last_txcmdsz = pattrib->pktlen;
6934 
6935 
6936 	if (wait_ack)
6937 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
6938 	else {
6939 		dump_mgntframe(padapter, pmgntframe);
6940 		ret = _SUCCESS;
6941 	}
6942 
6943 exit:
6944 	return ret;
6945 }
6946 
issue_probereq_p2p(_adapter * adapter,u8 * da)6947 inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
6948 {
6949 	_issue_probereq_p2p(adapter, da, _FALSE);
6950 }
6951 
6952 /*
6953  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
6954  * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
6955  * try_cnt means the maximal TX count to try
6956  */
issue_probereq_p2p_ex(_adapter * adapter,u8 * da,int try_cnt,int wait_ms)6957 int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
6958 {
6959 	int ret;
6960 	int i = 0;
6961 	systime start = rtw_get_current_time();
6962 
6963 	do {
6964 		ret = _issue_probereq_p2p(adapter, da, wait_ms > 0 ? _TRUE : _FALSE);
6965 
6966 		i++;
6967 
6968 		if (RTW_CANNOT_RUN(adapter))
6969 			break;
6970 
6971 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
6972 			rtw_msleep_os(wait_ms);
6973 
6974 	} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
6975 
6976 	if (ret != _FAIL) {
6977 		ret = _SUCCESS;
6978 #ifndef DBG_XMIT_ACK
6979 		goto exit;
6980 #endif
6981 	}
6982 
6983 	if (try_cnt && wait_ms) {
6984 		if (da)
6985 			RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
6986 				FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
6987 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
6988 		else
6989 			RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
6990 				FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
6991 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
6992 	}
6993 exit:
6994 	return ret;
6995 }
6996 
6997 #endif /* CONFIG_P2P */
6998 
rtw_action_public_decache(union recv_frame * rframe,u8 token_offset)6999 s32 rtw_action_public_decache(union recv_frame *rframe, u8 token_offset)
7000 {
7001 	_adapter *adapter = rframe->u.hdr.adapter;
7002 	struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
7003 	u8 *frame = rframe->u.hdr.rx_data;
7004 	u16 seq_ctrl = ((rframe->u.hdr.attrib.seq_num & 0xffff) << 4) | (rframe->u.hdr.attrib.frag_num & 0xf);
7005 	u8 token = *(rframe->u.hdr.rx_data + sizeof(struct rtw_ieee80211_hdr_3addr) + token_offset);
7006 
7007 	if (GetRetry(frame)) {
7008 		if ((seq_ctrl == mlmeext->action_public_rxseq)
7009 		    && (token == mlmeext->action_public_dialog_token)
7010 		   ) {
7011 			RTW_INFO(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
7012 				FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
7013 			return _FAIL;
7014 		}
7015 	}
7016 
7017 	/* TODO: per sta seq & token */
7018 	mlmeext->action_public_rxseq = seq_ctrl;
7019 	mlmeext->action_public_dialog_token = token;
7020 
7021 	return _SUCCESS;
7022 }
7023 
on_action_public_p2p(union recv_frame * precv_frame)7024 unsigned int on_action_public_p2p(union recv_frame *precv_frame)
7025 {
7026 	_adapter *padapter = precv_frame->u.hdr.adapter;
7027 	u8 *pframe = precv_frame->u.hdr.rx_data;
7028 	uint len = precv_frame->u.hdr.len;
7029 	u8 *frame_body;
7030 #ifdef CONFIG_P2P
7031 	u8 *p2p_ie;
7032 	u32	p2p_ielen;
7033 	struct	wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7034 	u8	result = P2P_STATUS_SUCCESS;
7035 	u8	empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
7036 	u8 *merged_p2pie = NULL;
7037 	u32 merged_p2p_ielen = 0;
7038 #ifdef CONFIG_CONCURRENT_MODE
7039 	struct roch_info *prochinfo = &padapter->rochinfo;
7040 #endif
7041 #endif /* CONFIG_P2P */
7042 
7043 	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7044 
7045 #ifdef CONFIG_P2P
7046 	_cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
7047 #ifdef CONFIG_IOCTL_CFG80211
7048 	if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
7049 		rtw_cfg80211_rx_p2p_action_public(padapter, precv_frame);
7050 	else
7051 #endif /* CONFIG_IOCTL_CFG80211 */
7052 	{
7053 		/*	Do nothing if the driver doesn't enable the P2P function. */
7054 		if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
7055 			return _SUCCESS;
7056 
7057 		len -= sizeof(struct rtw_ieee80211_hdr_3addr);
7058 
7059 		switch (frame_body[6]) { /* OUI Subtype */
7060 		case P2P_GO_NEGO_REQ: {
7061 			RTW_INFO("[%s] Got GO Nego Req Frame\n", __FUNCTION__);
7062 			_rtw_memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
7063 
7064 			if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
7065 				rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
7066 
7067 			if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) {
7068 				/*	Commented by Albert 20110526 */
7069 				/*	In this case, this means the previous nego fail doesn't be reset yet. */
7070 				_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
7071 				/*	Restore the previous p2p state */
7072 				rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
7073 				RTW_INFO("[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo));
7074 			}
7075 #ifdef CONFIG_CONCURRENT_MODE
7076 			if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
7077 				_cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer);
7078 #endif /* CONFIG_CONCURRENT_MODE */
7079 
7080 			/*	Commented by Kurt 20110902 */
7081 			/* Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
7082 			if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
7083 				rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
7084 
7085 			/*	Commented by Kurt 20120113 */
7086 			/*	Get peer_dev_addr here if peer doesn't issue prov_disc frame. */
7087 			if (_rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN))
7088 				_rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, get_addr2_ptr(pframe), ETH_ALEN);
7089 
7090 			result = process_p2p_group_negotation_req(pwdinfo, frame_body, len);
7091 			issue_p2p_GO_response(padapter, get_addr2_ptr(pframe), frame_body, len, result);
7092 
7093 			/*	Commented by Albert 20110718 */
7094 			/*	No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. */
7095 #ifdef CONFIG_CONCURRENT_MODE
7096 			/*	Commented by Albert 20120107 */
7097 			_set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
7098 #else /* CONFIG_CONCURRENT_MODE */
7099 			_set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
7100 #endif /* CONFIG_CONCURRENT_MODE */
7101 			break;
7102 		}
7103 		case P2P_GO_NEGO_RESP: {
7104 			RTW_INFO("[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
7105 
7106 			if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
7107 				/*	Commented by Albert 20110425 */
7108 				/*	The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. */
7109 				_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
7110 				pwdinfo->nego_req_info.benable = _FALSE;
7111 				result = process_p2p_group_negotation_resp(pwdinfo, frame_body, len);
7112 				issue_p2p_GO_confirm(pwdinfo->padapter, get_addr2_ptr(pframe), result);
7113 				if (P2P_STATUS_SUCCESS == result) {
7114 					if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) {
7115 						pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch;
7116 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
7117 						pwdinfo->p2p_info.operation_ch[1] = 1;	/* Check whether GO is operating in channel 1; */
7118 						pwdinfo->p2p_info.operation_ch[2] = 6;	/* Check whether GO is operating in channel 6; */
7119 						pwdinfo->p2p_info.operation_ch[3] = 11;	/* Check whether GO is operating in channel 11; */
7120 #endif /* CONFIG_P2P_OP_CHK_SOCIAL_CH */
7121 						pwdinfo->p2p_info.scan_op_ch_only = 1;
7122 						_set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH);
7123 					}
7124 				}
7125 
7126 				/*	Reset the dialog token for group negotiation frames. */
7127 				pwdinfo->negotiation_dialog_token = 1;
7128 
7129 				if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
7130 					_set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
7131 			} else
7132 				RTW_INFO("[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
7133 
7134 			break;
7135 		}
7136 		case P2P_GO_NEGO_CONF: {
7137 			RTW_INFO("[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
7138 			result = process_p2p_group_negotation_confirm(pwdinfo, frame_body, len);
7139 			if (P2P_STATUS_SUCCESS == result) {
7140 				if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) {
7141 					pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch;
7142 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
7143 					pwdinfo->p2p_info.operation_ch[1] = 1;	/* Check whether GO is operating in channel 1; */
7144 					pwdinfo->p2p_info.operation_ch[2] = 6;	/* Check whether GO is operating in channel 6; */
7145 					pwdinfo->p2p_info.operation_ch[3] = 11;	/* Check whether GO is operating in channel 11; */
7146 #endif /* CONFIG_P2P_OP_CHK_SOCIAL_CH */
7147 					pwdinfo->p2p_info.scan_op_ch_only = 1;
7148 					_set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH);
7149 				}
7150 			}
7151 			break;
7152 		}
7153 		case P2P_INVIT_REQ: {
7154 			/*	Added by Albert 2010/10/05 */
7155 			/*	Received the P2P Invite Request frame. */
7156 
7157 			RTW_INFO("[%s] Got invite request frame!\n", __FUNCTION__);
7158 			p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
7159 			if (p2p_ie) {
7160 				/*	Parse the necessary information from the P2P Invitation Request frame. */
7161 				/*	For example: The MAC address of sending this P2P Invitation Request frame. */
7162 				u32	attr_contentlen = 0;
7163 				u8	status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7164 				struct group_id_info group_id;
7165 				u8	invitation_flag = 0;
7166 
7167 				merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_);
7168 
7169 				merged_p2pie = rtw_zmalloc(merged_p2p_ielen + 2);	/* 2 is for EID and Length */
7170 				if (merged_p2pie == NULL) {
7171 					RTW_INFO("[%s] Malloc p2p ie fail\n", __FUNCTION__);
7172 					goto exit;
7173 				}
7174 				_rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen);
7175 
7176 				merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie);
7177 
7178 				attr_contentlen = sizeof(invitation_flag);
7179 				rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
7180 				if (attr_contentlen) {
7181 
7182 					attr_contentlen = sizeof(pwdinfo->p2p_peer_interface_addr);
7183 					rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
7184 					/*	Commented by Albert 20120510 */
7185 					/*	Copy to the pwdinfo->p2p_peer_interface_addr. */
7186 					/*	So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command. */
7187 					/*	#> iwpriv wlan0 p2p_get peer_ifa */
7188 					/*	After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. */
7189 
7190 					if (attr_contentlen) {
7191 						RTW_INFO("[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
7192 							pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
7193 							pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
7194 							pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
7195 					}
7196 
7197 					if (invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT) {
7198 						/*	Re-invoke the persistent group. */
7199 
7200 						_rtw_memset(&group_id, 0x00, sizeof(struct group_id_info));
7201 						attr_contentlen = sizeof(struct group_id_info);
7202 						rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *) &group_id, &attr_contentlen);
7203 						if (attr_contentlen) {
7204 							if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN)) {
7205 								/*	The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. */
7206 								rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO);
7207 								rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
7208 								status_code = P2P_STATUS_SUCCESS;
7209 							} else {
7210 								/*	The p2p device sending this p2p invitation request wants to be the persistent GO. */
7211 								if (is_matched_in_profilelist(pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[0])) {
7212 									u8 operatingch_info[5] = { 0x00 };
7213 									attr_contentlen = sizeof(operatingch_info);
7214 									if (rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info,
7215 										&attr_contentlen)) {
7216 										if (rtw_chset_search_ch(adapter_to_chset(padapter), (u32)operatingch_info[4]) >= 0) {
7217 											/*	The operating channel is acceptable for this device. */
7218 											pwdinfo->rx_invitereq_info.operation_ch[0] = operatingch_info[4];
7219 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
7220 											pwdinfo->rx_invitereq_info.operation_ch[1] = 1;		/* Check whether GO is operating in channel 1; */
7221 											pwdinfo->rx_invitereq_info.operation_ch[2] = 6;		/* Check whether GO is operating in channel 6; */
7222 											pwdinfo->rx_invitereq_info.operation_ch[3] = 11;		/* Check whether GO is operating in channel 11; */
7223 #endif /* CONFIG_P2P_OP_CHK_SOCIAL_CH */
7224 											pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
7225 											_set_timer(&pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH);
7226 											rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
7227 											rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
7228 											status_code = P2P_STATUS_SUCCESS;
7229 										} else {
7230 											/*	The operating channel isn't supported by this device. */
7231 											rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
7232 											rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
7233 											status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
7234 											_set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
7235 										}
7236 									} else {
7237 										/*	Commented by Albert 20121130 */
7238 										/*	Intel will use the different P2P IE to store the operating channel information */
7239 										/*	Workaround for Intel WiDi 3.5 */
7240 										rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
7241 										rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
7242 										status_code = P2P_STATUS_SUCCESS;
7243 									}
7244 								} else {
7245 									rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
7246 									status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
7247 								}
7248 							}
7249 						} else {
7250 							RTW_INFO("[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__);
7251 							status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7252 						}
7253 					} else {
7254 						/*	Received the invitation to join a P2P group. */
7255 
7256 						_rtw_memset(&group_id, 0x00, sizeof(struct group_id_info));
7257 						attr_contentlen = sizeof(struct group_id_info);
7258 						rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *) &group_id, &attr_contentlen);
7259 						if (attr_contentlen) {
7260 							if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN)) {
7261 								/*	In this case, the GO can't be myself. */
7262 								rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
7263 								status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7264 							} else {
7265 								/*	The p2p device sending this p2p invitation request wants to join an existing P2P group */
7266 								/*	Commented by Albert 2012/06/28 */
7267 								/*	In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. */
7268 								/*	The peer device address should be the destination address for the provisioning discovery request. */
7269 								/*	Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. */
7270 								/*	The peer interface address should be the address for WPS mac address */
7271 								_rtw_memcpy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN);
7272 								rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
7273 								rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN);
7274 								status_code = P2P_STATUS_SUCCESS;
7275 							}
7276 						} else {
7277 							RTW_INFO("[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__);
7278 							status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7279 						}
7280 					}
7281 				} else {
7282 					RTW_INFO("[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__);
7283 					status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7284 				}
7285 
7286 				RTW_INFO("[%s] status_code = %d\n", __FUNCTION__, status_code);
7287 
7288 				pwdinfo->inviteresp_info.token = frame_body[7];
7289 				issue_p2p_invitation_response(padapter, get_addr2_ptr(pframe), pwdinfo->inviteresp_info.token, status_code);
7290 				_set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
7291 			}
7292 			break;
7293 		}
7294 		case P2P_INVIT_RESP: {
7295 			u8	attr_content = 0x00;
7296 			u32	attr_contentlen = 0;
7297 
7298 			RTW_INFO("[%s] Got invite response frame!\n", __FUNCTION__);
7299 			_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
7300 			p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
7301 			if (p2p_ie) {
7302 				attr_contentlen = sizeof(attr_content);
7303 				rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
7304 
7305 				if (attr_contentlen == 1) {
7306 					RTW_INFO("[%s] Status = %d\n", __FUNCTION__, attr_content);
7307 					pwdinfo->invitereq_info.benable = _FALSE;
7308 
7309 					if (attr_content == P2P_STATUS_SUCCESS) {
7310 						if (_rtw_memcmp(pwdinfo->invitereq_info.go_bssid, adapter_mac_addr(padapter), ETH_ALEN))
7311 							rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
7312 						else
7313 							rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
7314 
7315 						rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_OK);
7316 					} else {
7317 						rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
7318 						rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
7319 					}
7320 				} else {
7321 					rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
7322 					rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
7323 				}
7324 			} else {
7325 				rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
7326 				rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
7327 			}
7328 
7329 			if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL))
7330 				_set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
7331 			break;
7332 		}
7333 		case P2P_DEVDISC_REQ:
7334 
7335 			process_p2p_devdisc_req(pwdinfo, pframe, len);
7336 
7337 			break;
7338 
7339 		case P2P_DEVDISC_RESP:
7340 
7341 			process_p2p_devdisc_resp(pwdinfo, pframe, len);
7342 
7343 			break;
7344 
7345 		case P2P_PROVISION_DISC_REQ:
7346 			RTW_INFO("[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__);
7347 			process_p2p_provdisc_req(pwdinfo, pframe, len);
7348 			_rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, get_addr2_ptr(pframe), ETH_ALEN);
7349 
7350 			/* 20110902 Kurt */
7351 			/* Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
7352 			if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
7353 				rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
7354 
7355 			rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
7356 			_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
7357 			break;
7358 
7359 		case P2P_PROVISION_DISC_RESP:
7360 			/*	Commented by Albert 20110707 */
7361 			/*	Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? */
7362 			RTW_INFO("[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__);
7363 			/*	Commented by Albert 20110426 */
7364 			/*	The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. */
7365 			_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
7366 			rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
7367 			process_p2p_provdisc_resp(pwdinfo, pframe);
7368 			_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
7369 			break;
7370 
7371 		}
7372 	}
7373 
7374 
7375 exit:
7376 
7377 	if (merged_p2pie)
7378 		rtw_mfree(merged_p2pie, merged_p2p_ielen + 2);
7379 #endif /* CONFIG_P2P */
7380 	return _SUCCESS;
7381 }
7382 
on_action_public_vendor(union recv_frame * precv_frame)7383 unsigned int on_action_public_vendor(union recv_frame *precv_frame)
7384 {
7385 	unsigned int ret = _FAIL;
7386 	u8 *pframe = precv_frame->u.hdr.rx_data;
7387 	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7388 	_adapter *adapter = precv_frame->u.hdr.adapter;
7389 	int cnt = 0;
7390 	char msg[64];
7391 
7392 	if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) {
7393 		if (rtw_action_public_decache(precv_frame, 7) == _FAIL)
7394 			goto exit;
7395 
7396 		if (!hal_chk_wl_func(precv_frame->u.hdr.adapter, WL_FUNC_MIRACAST))
7397 			rtw_rframe_del_wfd_ie(precv_frame, 8);
7398 
7399 		ret = on_action_public_p2p(precv_frame);
7400 	} else if (_rtw_memcmp(frame_body + 2, DPP_OUI, 4) == _TRUE) {
7401 		u8 dpp_type = frame_body[7];
7402 
7403 #ifdef CONFIG_IOCTL_CFG80211
7404 		cnt += sprintf((msg + cnt), "DPP(type:%u)", dpp_type);
7405 		rtw_cfg80211_rx_action(adapter, precv_frame, msg);
7406 #endif
7407 	}
7408 
7409 exit:
7410 	return ret;
7411 }
7412 
on_action_public_default(union recv_frame * precv_frame,u8 action)7413 unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
7414 {
7415 	unsigned int ret = _FAIL;
7416 	u8 *pframe = precv_frame->u.hdr.rx_data;
7417 	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7418 	u8 token;
7419 	_adapter *adapter = precv_frame->u.hdr.adapter;
7420 	int cnt = 0;
7421 	char msg[64];
7422 
7423 	token = frame_body[2];
7424 
7425 	if (rtw_action_public_decache(precv_frame, 2) == _FAIL)
7426 		goto exit;
7427 
7428 #ifdef CONFIG_IOCTL_CFG80211
7429 	cnt += sprintf((msg + cnt), "%s(token:%u)", action_public_str(action), token);
7430 	rtw_cfg80211_rx_action(adapter, precv_frame, msg);
7431 #endif
7432 
7433 	ret = _SUCCESS;
7434 
7435 exit:
7436 	return ret;
7437 }
7438 
on_action_public(_adapter * padapter,union recv_frame * precv_frame)7439 unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
7440 {
7441 	unsigned int ret = _FAIL;
7442 	u8 *pframe = precv_frame->u.hdr.rx_data;
7443 	uint frame_len = precv_frame->u.hdr.len;
7444 	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7445 	u8 category, action;
7446 
7447 	/* check RA matches or broadcast */
7448 	if (!(_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN) ||
7449 		is_broadcast_mac_addr(GetAddr1Ptr(pframe))))
7450 		goto exit;
7451 
7452 	category = frame_body[0];
7453 	if (category != RTW_WLAN_CATEGORY_PUBLIC)
7454 		goto exit;
7455 
7456 	action = frame_body[1];
7457 	switch (action) {
7458 	case ACT_PUBLIC_BSSCOEXIST:
7459 #ifdef CONFIG_80211N_HT
7460 #ifdef CONFIG_AP_MODE
7461 		/*20/40 BSS Coexistence Management frame is a Public Action frame*/
7462 		if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
7463 			rtw_process_public_act_bsscoex(padapter, pframe, frame_len);
7464 #endif /*CONFIG_AP_MODE*/
7465 #endif /*CONFIG_80211N_HT*/
7466 		break;
7467 	case ACT_PUBLIC_VENDOR:
7468 		ret = on_action_public_vendor(precv_frame);
7469 		break;
7470 	default:
7471 		ret = on_action_public_default(precv_frame, action);
7472 		break;
7473 	}
7474 
7475 exit:
7476 	return ret;
7477 }
7478 
OnAction_ft(_adapter * padapter,union recv_frame * precv_frame)7479 unsigned int OnAction_ft(_adapter *padapter, union recv_frame *precv_frame)
7480 {
7481 #ifdef CONFIG_RTW_80211R
7482 	u32	ret = _FAIL;
7483 	u32	frame_len = 0;
7484 	u8	action_code = 0;
7485 	u8	category = 0;
7486 	u8	*pframe = NULL;
7487 	u8	*pframe_body = NULL;
7488 	u8 	tgt_addr[ETH_ALEN];
7489 	u8	*pie = NULL;
7490 	u32	ft_ie_len = 0;
7491 	u32 status_code = 0;
7492 	struct mlme_ext_priv *pmlmeext = NULL;
7493 	struct mlme_ext_info *pmlmeinfo = NULL;
7494 	struct mlme_priv *pmlmepriv = NULL;
7495 	struct wlan_network *proam_target = NULL;
7496 	struct ft_roam_info *pft_roam = NULL;
7497 	_irqL  irqL;
7498 
7499 	pmlmeext = &(padapter->mlmeextpriv);
7500 	pmlmeinfo = &(pmlmeext->mlmext_info);
7501 	pmlmepriv = &(padapter->mlmepriv);
7502 	pft_roam = &(pmlmepriv->ft_roam);
7503 	pframe = precv_frame->u.hdr.rx_data;
7504 	frame_len = precv_frame->u.hdr.len;
7505 	pframe_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7506 	category = pframe_body[0];
7507 
7508 	if (category != RTW_WLAN_CATEGORY_FT)
7509 		goto exit;
7510 
7511 	action_code = pframe_body[1];
7512 	switch (action_code) {
7513 	case RTW_WLAN_ACTION_FT_RSP:
7514 		RTW_INFO("FT: RTW_WLAN_ACTION_FT_RSP recv.\n");
7515 		if (!_rtw_memcmp(adapter_mac_addr(padapter), &pframe_body[2], ETH_ALEN)) {
7516 			RTW_ERR("FT: Unmatched STA MAC Address "MAC_FMT"\n", MAC_ARG(&pframe_body[2]));
7517 			goto exit;
7518 		}
7519 
7520 		status_code = le16_to_cpu(*(u16 *)((SIZE_PTR)pframe +  sizeof(struct rtw_ieee80211_hdr_3addr) + 14));
7521 		if (status_code != 0) {
7522 			RTW_ERR("FT: WLAN ACTION FT RESPONSE fail, status: %d\n", status_code);
7523 			goto exit;
7524 		}
7525 
7526 		_rtw_memcpy(tgt_addr, &pframe_body[8], ETH_ALEN);
7527 		if (is_zero_mac_addr(tgt_addr) || is_broadcast_mac_addr(tgt_addr)) {
7528 			RTW_ERR("FT: Invalid Target MAC Address "MAC_FMT"\n", MAC_ARG(tgt_addr));
7529 			goto exit;
7530 		}
7531 
7532 		pie = rtw_get_ie(pframe_body, _MDIE_, &ft_ie_len, frame_len);
7533 		if (pie) {
7534 			if (!_rtw_memcmp(&pft_roam->mdid, pie+2, 2)) {
7535 				RTW_ERR("FT: Invalid MDID\n");
7536 				goto exit;
7537 			}
7538 		}
7539 
7540 		rtw_ft_set_status(padapter, RTW_FT_REQUESTED_STA);
7541 		_cancel_timer_ex(&pmlmeext->ft_link_timer);
7542 
7543 		/*Disconnect current AP*/
7544 		receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress, WLAN_REASON_ACTIVE_ROAM, _FALSE);
7545 
7546 		pft_roam->ft_action_len = frame_len;
7547 		_rtw_memcpy(pft_roam->ft_action, pframe, rtw_min(frame_len, RTW_FT_MAX_IE_SZ));
7548 		ret = _SUCCESS;
7549 		break;
7550 	case RTW_WLAN_ACTION_FT_REQ:
7551 	case RTW_WLAN_ACTION_FT_CONF:
7552 	case RTW_WLAN_ACTION_FT_ACK:
7553 	default:
7554 		RTW_ERR("FT: Unsupported FT Action!\n");
7555 		break;
7556 	}
7557 
7558 exit:
7559 	return ret;
7560 #else
7561 	return _SUCCESS;
7562 #endif
7563 }
7564 
OnAction_ht(_adapter * padapter,union recv_frame * precv_frame)7565 unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
7566 {
7567 	u8 *pframe = precv_frame->u.hdr.rx_data;
7568 	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7569 	u8 category, action;
7570 
7571 	/* check RA matches or not */
7572 	if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7573 		goto exit;
7574 
7575 	category = frame_body[0];
7576 	if (category != RTW_WLAN_CATEGORY_HT)
7577 		goto exit;
7578 
7579 	action = frame_body[1];
7580 	switch (action) {
7581 	case RTW_WLAN_ACTION_HT_SM_PS:
7582 #ifdef CONFIG_80211N_HT
7583 #ifdef CONFIG_AP_MODE
7584 		if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
7585 			rtw_process_ht_action_smps(padapter, get_addr2_ptr(pframe), frame_body[2]);
7586 #endif /*CONFIG_AP_MODE*/
7587 #endif /*CONFIG_80211N_HT*/
7588 		break;
7589 	case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING:
7590 #ifdef CONFIG_BEAMFORMING
7591 		/*RTW_INFO("RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING\n");*/
7592 		rtw_beamforming_get_report_frame(padapter, precv_frame);
7593 #endif /*CONFIG_BEAMFORMING*/
7594 		break;
7595 	default:
7596 		break;
7597 	}
7598 
7599 exit:
7600 
7601 	return _SUCCESS;
7602 }
7603 
7604 #ifdef CONFIG_IEEE80211W
OnAction_sa_query(_adapter * padapter,union recv_frame * precv_frame)7605 unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame)
7606 {
7607 	u8 *pframe = precv_frame->u.hdr.rx_data;
7608 	struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
7609 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7610 	struct sta_info		*psta;
7611 	struct sta_priv		*pstapriv = &padapter->stapriv;
7612 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7613 	u16 tid;
7614 	/* Baron */
7615 
7616 	RTW_INFO("OnAction_sa_query\n");
7617 
7618 	switch (pframe[WLAN_HDR_A3_LEN + 1]) {
7619 	case 0: /* SA Query req */
7620 		_rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN + 2], sizeof(u16));
7621 		RTW_INFO("OnAction_sa_query request,action=%d, tid=%04x, pframe=%02x-%02x\n"
7622 			, pframe[WLAN_HDR_A3_LEN + 1], tid, pframe[WLAN_HDR_A3_LEN + 2], pframe[WLAN_HDR_A3_LEN + 3]);
7623 		issue_action_SA_Query(padapter, get_addr2_ptr(pframe), 1, tid, IEEE80211W_RIGHT_KEY);
7624 		break;
7625 
7626 	case 1: /* SA Query rsp */
7627 		psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
7628 		if (psta != NULL)
7629 			_cancel_timer_ex(&psta->dot11w_expire_timer);
7630 
7631 		_rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN + 2], sizeof(u16));
7632 		RTW_INFO("OnAction_sa_query response,action=%d, tid=%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN + 1], tid);
7633 		break;
7634 	default:
7635 		break;
7636 	}
7637 	if (0) {
7638 		int pp;
7639 		printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
7640 		for (pp = 0; pp < pattrib->pkt_len; pp++)
7641 			printk(" %02x ", pframe[pp]);
7642 		printk("\n");
7643 	}
7644 
7645 	return _SUCCESS;
7646 }
7647 #endif /* CONFIG_IEEE80211W */
7648 
on_action_rm(_adapter * padapter,union recv_frame * precv_frame)7649 unsigned int on_action_rm(_adapter *padapter, union recv_frame *precv_frame)
7650 {
7651 #ifdef CONFIG_RTW_80211K
7652 	return rm_on_action(padapter, precv_frame);
7653 #else
7654 	return _SUCCESS;
7655 #endif  /* CONFIG_RTW_80211K */
7656 }
7657 
OnAction_wmm(_adapter * padapter,union recv_frame * precv_frame)7658 unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
7659 {
7660 	return _SUCCESS;
7661 }
7662 
OnAction_vht(_adapter * padapter,union recv_frame * precv_frame)7663 unsigned int OnAction_vht(_adapter *padapter, union recv_frame *precv_frame)
7664 {
7665 #ifdef CONFIG_80211AC_VHT
7666 	u8 *pframe = precv_frame->u.hdr.rx_data;
7667 	struct rtw_ieee80211_hdr_3addr *whdr = (struct rtw_ieee80211_hdr_3addr *)pframe;
7668 	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7669 	u8 category, action;
7670 	struct sta_info *psta = NULL;
7671 
7672 	/* check RA matches or not */
7673 	if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7674 		goto exit;
7675 
7676 	category = frame_body[0];
7677 	if (category != RTW_WLAN_CATEGORY_VHT)
7678 		goto exit;
7679 
7680 	action = frame_body[1];
7681 	switch (action) {
7682 	case RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING:
7683 #ifdef CONFIG_BEAMFORMING
7684 		/*RTW_INFO("RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING\n");*/
7685 		rtw_beamforming_get_report_frame(padapter, precv_frame);
7686 #endif /*CONFIG_BEAMFORMING*/
7687 		break;
7688 	case RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION:
7689 		/* CategoryCode(1) + ActionCode(1) + OpModeNotification(1) */
7690 		/* RTW_INFO("RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION\n"); */
7691 		psta = rtw_get_stainfo(&padapter->stapriv, whdr->addr2);
7692 		if (psta)
7693 			rtw_process_vht_op_mode_notify(padapter, &frame_body[2], psta);
7694 		break;
7695 	case RTW_WLAN_ACTION_VHT_GROUPID_MANAGEMENT:
7696 #ifdef CONFIG_BEAMFORMING
7697 #ifdef RTW_BEAMFORMING_VERSION_2
7698 		rtw_beamforming_get_vht_gid_mgnt_frame(padapter, precv_frame);
7699 #endif /* RTW_BEAMFORMING_VERSION_2 */
7700 #endif /* CONFIG_BEAMFORMING */
7701 		break;
7702 	default:
7703 		break;
7704 	}
7705 
7706 exit:
7707 #endif /* CONFIG_80211AC_VHT */
7708 
7709 	return _SUCCESS;
7710 }
7711 
OnAction_p2p(_adapter * padapter,union recv_frame * precv_frame)7712 unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
7713 {
7714 #ifdef CONFIG_P2P
7715 	u8 *frame_body;
7716 	u8 category, OUI_Subtype, dialogToken = 0;
7717 	u8 *pframe = precv_frame->u.hdr.rx_data;
7718 	uint len = precv_frame->u.hdr.len;
7719 	struct	wifidirect_info	*pwdinfo = &(padapter->wdinfo);
7720 
7721 	/* check RA matches or not */
7722 	if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7723 		return _SUCCESS;
7724 
7725 	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7726 
7727 	category = frame_body[0];
7728 	if (category != RTW_WLAN_CATEGORY_P2P)
7729 		return _SUCCESS;
7730 
7731 	if (cpu_to_be32(*((u32 *)(frame_body + 1))) != P2POUI)
7732 		return _SUCCESS;
7733 
7734 #ifdef CONFIG_IOCTL_CFG80211
7735 	if (adapter_wdev_data(padapter)->p2p_enabled
7736 		&& pwdinfo->driver_interface == DRIVER_CFG80211
7737 	) {
7738 		rtw_cfg80211_rx_action_p2p(padapter, precv_frame);
7739 		return _SUCCESS;
7740 	} else
7741 #endif /* CONFIG_IOCTL_CFG80211 */
7742 	{
7743 		len -= sizeof(struct rtw_ieee80211_hdr_3addr);
7744 		OUI_Subtype = frame_body[5];
7745 		dialogToken = frame_body[6];
7746 
7747 		switch (OUI_Subtype) {
7748 		case P2P_NOTICE_OF_ABSENCE:
7749 
7750 			break;
7751 
7752 		case P2P_PRESENCE_REQUEST:
7753 
7754 			process_p2p_presence_req(pwdinfo, pframe, len);
7755 
7756 			break;
7757 
7758 		case P2P_PRESENCE_RESPONSE:
7759 
7760 			break;
7761 
7762 		case P2P_GO_DISC_REQUEST:
7763 
7764 			break;
7765 
7766 		default:
7767 			break;
7768 
7769 		}
7770 	}
7771 #endif /* CONFIG_P2P */
7772 
7773 	return _SUCCESS;
7774 
7775 }
7776 
7777 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
OnAction_tbtx_token(_adapter * padapter,union recv_frame * precv_frame)7778 unsigned int OnAction_tbtx_token(_adapter *padapter, union recv_frame *precv_frame)
7779 {
7780 #define TOKEN_REQ 0x00
7781 #define TOKEN_REL 0x01
7782 
7783 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
7784 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7785 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
7786 	struct sta_priv *pstapriv = &padapter->stapriv;
7787 	struct sta_info *psta;
7788 	u32 xmit_time;
7789 	u8 *src=NULL, *pframe = precv_frame->u.hdr.rx_data;
7790 	u8 tbtx_action_code;
7791 	u8 i, nr_send;
7792 	uint tx_duration = 0;
7793 
7794 	if (padapter->tbtx_capability == _FALSE)
7795 		goto exit;
7796 
7797 	tbtx_action_code = *(pframe + WLAN_HDR_A3_LEN + 1);
7798 
7799 
7800 	switch (tbtx_action_code)
7801 	{
7802 		case TOKEN_REQ:
7803 			// parse duration
7804 			tx_duration = le32_to_cpu(*(uint *)(pframe + WLAN_HDR_A3_LEN + 2));
7805 			padapter->tbtx_duration = tx_duration/1000; // Mirocsecond to Millisecond
7806 			ATOMIC_SET(&padapter->tbtx_tx_pause, _FALSE);
7807 			rtw_tx_control_cmd(padapter);
7808 			_set_timer(&pmlmeext->tbtx_xmit_timer, padapter->tbtx_duration);
7809 			ATOMIC_SET(&padapter->tbtx_remove_tx_pause, _FALSE);
7810 #if defined(CONFIG_SDIO_HCI) && !defined(CONFIG_SDIO_TX_TASKLET)
7811 			_rtw_up_sema(&pxmitpriv->SdioXmitSema);
7812 #else
7813 			tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
7814 #endif
7815 			break;
7816 #ifdef CONFIG_AP_MODE
7817 		case TOKEN_REL:
7818 			src = get_addr2_ptr(pframe);
7819 			if (!src)
7820 				goto exit;
7821 			psta = rtw_get_stainfo(&padapter->stapriv, src);
7822 			if (!psta)
7823 				goto exit;
7824 
7825 			if (ATOMIC_READ(&pstapriv->nr_token_keeper) < 1)
7826 				goto exit;
7827 
7828 			for (i=0; i< NR_MAXSTA_INSLOT; i++) {
7829 				if (pstapriv->token_holder[i] == psta) {
7830 					pstapriv->token_holder[i] = NULL;
7831 					//RTW_INFO("macaddr1:" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
7832 					ATOMIC_DEC(&pstapriv->nr_token_keeper);
7833 					break;
7834 				}
7835 			}
7836 
7837 			if (ATOMIC_READ(&pstapriv->nr_token_keeper) == 0)
7838 				_set_timer(&pmlmeext->tbtx_token_dispatch_timer, 1);
7839 
7840 			break;
7841 #endif
7842 		default:
7843 			RTW_INFO("Undefined Action Code\n");
7844 			goto exit;
7845 			break;
7846 	}
7847 
7848 exit:
7849 	return _SUCCESS;
7850 }
7851 
rtw_issue_action_token_rel(_adapter * padapter)7852 void rtw_issue_action_token_rel(_adapter *padapter)
7853 {
7854 
7855 	// Todo:
7856 	// gen token
7857 	/* Token Release Format
7858 		Category code : 	1 Byte
7859 		Action code : 		1 Byte */
7860 	int ret = _FAIL;
7861 	//u16	*fctrl;
7862 	u8	val = 0x01;
7863 	u8	category = RTW_WLAN_CATEGORY_TBTX;
7864 	u8	*pframe;
7865 	struct xmit_frame		*pmgntframe;
7866 	struct pkt_attrib		*pattrib;
7867 	struct rtw_ieee80211_hdr	*pwlanhdr;
7868 	struct	mlme_priv		*pmlmepriv = &padapter->mlmepriv;
7869 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
7870 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7871 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
7872 	//struct sta_info			*psta;
7873 	//struct sta_priv			*pstapriv = &padapter->stapriv;
7874 	//struct registry_priv		*pregpriv = &padapter->registrypriv;
7875 
7876 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
7877 		return;
7878 
7879 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
7880 	if (pmgntframe == NULL)
7881 		return;
7882 
7883 	/*update attribute */
7884 	pattrib = &pmgntframe->attrib;
7885 	update_mgntframe_attrib(padapter, pattrib);
7886 	pattrib->rate = MGN_24M; /* issue action release using OFDM rate? 20190716 Bruce add */
7887 
7888 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7889 
7890 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7891 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7892 
7893 	//fctrl = &(pwlanhdr->frame_ctl);
7894 	//*(fctrl) = 0;
7895 
7896 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7897 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7898 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7899 
7900 	// SetSeqNum??
7901 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7902 	pmlmeext->mgnt_seq++;
7903 	set_frame_sub_type(pframe, WIFI_ACTION);
7904 
7905 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7906 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7907 
7908 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
7909 	pframe = rtw_set_fixed_ie(pframe, 1, &(val), &(pattrib->pktlen));
7910 
7911 	pattrib->last_txcmdsz = pattrib->pktlen;
7912 
7913 	dump_mgntframe(padapter, pmgntframe);
7914 
7915 	//RTW_INFO("%s\n", __func__);
7916 
7917 }
7918 #endif
7919 
OnAction(_adapter * padapter,union recv_frame * precv_frame)7920 unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
7921 {
7922 	int i;
7923 	unsigned char	category;
7924 	struct action_handler *ptable;
7925 	unsigned char	*frame_body;
7926 	u8 *pframe = precv_frame->u.hdr.rx_data;
7927 
7928 	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7929 
7930 	category = frame_body[0];
7931 
7932 	for (i = 0; i < sizeof(OnAction_tbl) / sizeof(struct action_handler); i++) {
7933 		ptable = &OnAction_tbl[i];
7934 
7935 		if (category == ptable->num)
7936 			ptable->func(padapter, precv_frame);
7937 
7938 	}
7939 
7940 	return _SUCCESS;
7941 
7942 }
7943 
DoReserved(_adapter * padapter,union recv_frame * precv_frame)7944 unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
7945 {
7946 
7947 	/* RTW_INFO("rcvd mgt frame(%x, %x)\n", (get_frame_sub_type(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe)); */
7948 	return _SUCCESS;
7949 }
7950 
_alloc_mgtxmitframe(struct xmit_priv * pxmitpriv,bool once)7951 struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
7952 {
7953 	struct xmit_frame *pmgntframe;
7954 	struct xmit_buf *pxmitbuf;
7955 
7956 	if (once)
7957 		pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
7958 	else
7959 		pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
7960 
7961 	if (pmgntframe == NULL) {
7962 		RTW_INFO(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
7963 		goto exit;
7964 	}
7965 
7966 	pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv);
7967 	if (pxmitbuf == NULL) {
7968 		RTW_INFO(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
7969 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
7970 		pmgntframe = NULL;
7971 		goto exit;
7972 	}
7973 
7974 	pmgntframe->frame_tag = MGNT_FRAMETAG;
7975 	pmgntframe->pxmitbuf = pxmitbuf;
7976 	pmgntframe->buf_addr = pxmitbuf->pbuf;
7977 	pxmitbuf->priv_data = pmgntframe;
7978 
7979 exit:
7980 	return pmgntframe;
7981 
7982 }
7983 
alloc_mgtxmitframe(struct xmit_priv * pxmitpriv)7984 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
7985 {
7986 	return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
7987 }
7988 
alloc_mgtxmitframe_once(struct xmit_priv * pxmitpriv)7989 inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
7990 {
7991 	return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
7992 }
7993 
7994 
7995 /****************************************************************************
7996 
7997 Following are some TX fuctions for WiFi MLME
7998 
7999 *****************************************************************************/
8000 
update_mgnt_tx_rate(_adapter * padapter,u8 rate)8001 void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
8002 {
8003 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8004 
8005 	pmlmeext->tx_rate = rate;
8006 	pmlmeext->tx_rate_section = mgn_rate_to_rs(rate);
8007 	/* RTW_INFO("%s(): rate = %x\n",__FUNCTION__, rate); */
8008 }
8009 
8010 
update_monitor_frame_attrib(_adapter * padapter,struct pkt_attrib * pattrib)8011 void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
8012 {
8013 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
8014 	u8	wireless_mode;
8015 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8016 	struct xmit_priv		*pxmitpriv = &padapter->xmitpriv;
8017 	struct sta_info		*psta = NULL;
8018 	struct sta_priv		*pstapriv = &padapter->stapriv;
8019 
8020 	psta = rtw_get_stainfo(pstapriv, pattrib->ra);
8021 
8022 	pattrib->hdrlen = 24;
8023 	pattrib->nr_frags = 1;
8024 	pattrib->priority = 7;
8025 	pattrib->mac_id = RTW_DEFAULT_MGMT_MACID;
8026 	pattrib->qsel = QSLT_MGNT;
8027 
8028 	pattrib->pktlen = 0;
8029 
8030 	if (IS_CCK_RATE(pmlmeext->tx_rate))
8031 		wireless_mode = WIRELESS_11B;
8032 	else
8033 		wireless_mode = WIRELESS_11G;
8034 
8035 	pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
8036 #ifdef CONFIG_80211AC_VHT
8037 	if (pHalData->rf_type == RF_1T1R)
8038 		pattrib->raid = RATEID_IDX_VHT_1SS;
8039 	else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R)
8040 		pattrib->raid = RATEID_IDX_VHT_2SS;
8041 	else if (pHalData->rf_type == RF_3T3R)
8042 		pattrib->raid = RATEID_IDX_VHT_3SS;
8043 	else
8044 		pattrib->raid = RATEID_IDX_BGN_40M_1SS;
8045 #endif
8046 
8047 #ifdef CONFIG_80211AC_VHT
8048 	pattrib->rate = MGN_VHT1SS_MCS9;
8049 #else
8050 	pattrib->rate = MGN_MCS7;
8051 #endif
8052 
8053 	pattrib->encrypt = _NO_PRIVACY_;
8054 	pattrib->bswenc = _FALSE;
8055 
8056 	pattrib->qos_en = _FALSE;
8057 	pattrib->ht_en = 1;
8058 	pattrib->bwmode = CHANNEL_WIDTH_20;
8059 	pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
8060 	pattrib->sgi = _FALSE;
8061 
8062 	pattrib->seqnum = pmlmeext->mgnt_seq;
8063 
8064 	pattrib->retry_ctrl = _TRUE;
8065 
8066 	pattrib->mbssid = 0;
8067 	pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
8068 
8069 }
8070 
8071 #ifdef CONFIG_RTW_MGMT_QUEUE
update_mgntframe_subtype(_adapter * padapter,struct xmit_frame * pmgntframe)8072 void update_mgntframe_subtype(_adapter *padapter, struct xmit_frame *pmgntframe)
8073 {
8074 	struct pkt_attrib *pattrib = &pmgntframe->attrib;
8075 	u8 *pframe;
8076 	u8 subtype, category ,action;
8077 
8078 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8079 	subtype = get_frame_sub_type(pframe); /* bit(7)~bit(2) */
8080 	pattrib->subtype = subtype;
8081 
8082 	rtw_action_frame_parse(pframe, pattrib->pktlen, &category, &action);
8083 
8084 	if ((subtype == WIFI_ACTION && !(action == ACT_PUBLIC_FTM_REQ || action == ACT_PUBLIC_FTM)) ||
8085 		subtype == WIFI_DISASSOC || subtype == WIFI_DEAUTH ||
8086 		(subtype == WIFI_PROBERSP && MLME_IS_ADHOC(padapter)))
8087 		pattrib->ps_dontq = 0;
8088 	else
8089 		pattrib->ps_dontq = 1;
8090 }
8091 #endif
8092 
update_mgntframe_attrib(_adapter * padapter,struct pkt_attrib * pattrib)8093 void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
8094 {
8095 	u8	wireless_mode;
8096 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8097 	struct xmit_priv		*pxmitpriv = &padapter->xmitpriv;
8098 	struct sta_priv *pstapriv = &padapter->stapriv;
8099 	struct sta_info *psta;
8100 
8101 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
8102 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8103 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
8104 
8105 	/* _rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib)); */
8106 
8107 	pattrib->hdrlen = 24;
8108 	pattrib->nr_frags = 1;
8109 	pattrib->priority = 7;
8110 	pattrib->mac_id = RTW_DEFAULT_MGMT_MACID;
8111 	pattrib->qsel = QSLT_MGNT;
8112 
8113 #ifdef CONFIG_MCC_MODE
8114 	update_mcc_mgntframe_attrib(padapter, pattrib);
8115 #endif
8116 
8117 
8118 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
8119 #ifdef CONFIG_CONCURRENT_MODE
8120 	if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
8121 #endif /* CONFIG_CONCURRENT_MODE */
8122 		if (MLME_IS_GC(padapter)) {
8123 			if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
8124 				struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8125 				struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8126 				WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
8127 
8128 				psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
8129 				if (psta) {
8130 					/* use macid sleep during NoA, mgmt frame use ac queue & ap macid */
8131 					pattrib->mac_id = psta->cmn.mac_id;
8132 					pattrib->qsel = QSLT_VO;
8133 				} else {
8134 					if (pwdinfo->p2p_ps_state != P2P_PS_DISABLE)
8135 						RTW_ERR("%s , psta was NULL\n", __func__);
8136 				}
8137 			}
8138 		}
8139 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
8140 
8141 	pattrib->pktlen = 0;
8142 
8143 	if (IS_CCK_RATE(pmlmeext->tx_rate))
8144 		wireless_mode = WIRELESS_11B;
8145 	else
8146 		wireless_mode = WIRELESS_11G;
8147 	pattrib->raid =  rtw_get_mgntframe_raid(padapter, wireless_mode);
8148 	pattrib->rate = pmlmeext->tx_rate;
8149 
8150 	pattrib->encrypt = _NO_PRIVACY_;
8151 	pattrib->bswenc = _FALSE;
8152 
8153 	pattrib->qos_en = _FALSE;
8154 	pattrib->ht_en = _FALSE;
8155 	pattrib->bwmode = CHANNEL_WIDTH_20;
8156 	pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
8157 	pattrib->sgi = _FALSE;
8158 
8159 	pattrib->seqnum = pmlmeext->mgnt_seq;
8160 
8161 	pattrib->retry_ctrl = _TRUE;
8162 
8163 	pattrib->mbssid = 0;
8164 	pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
8165 #ifdef CONFIG_RTW_MGMT_QUEUE
8166 	pattrib->ps_dontq = 1;
8167 #endif
8168 }
8169 
update_mgntframe_attrib_addr(_adapter * padapter,struct xmit_frame * pmgntframe)8170 void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe)
8171 {
8172 	u8 *pframe;
8173 	struct pkt_attrib *pattrib = &pmgntframe->attrib;
8174 #if defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) || defined(CONFIG_RTW_MGMT_QUEUE)
8175 	struct sta_info *sta = NULL;
8176 #endif
8177 
8178 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8179 
8180 	_rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
8181 	_rtw_memcpy(pattrib->ta, get_addr2_ptr(pframe), ETH_ALEN);
8182 
8183 #if defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) || defined(CONFIG_RTW_MGMT_QUEUE)
8184 	sta = pattrib->psta;
8185 	if (!sta) {
8186 		sta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
8187 		pattrib->psta = sta;
8188 	}
8189 
8190 	#ifdef CONFIG_BEAMFORMING
8191 	if (sta)
8192 		update_attrib_txbf_info(padapter, pattrib, sta);
8193 	#endif
8194 #endif /* defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) || defined(CONFIG_RTW_MGMT_QUEUE) */
8195 }
8196 
dump_mgntframe(_adapter * padapter,struct xmit_frame * pmgntframe)8197 void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
8198 {
8199 	if (RTW_CANNOT_RUN(padapter)) {
8200 		rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
8201 		rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
8202 		return;
8203 	}
8204 
8205 	rtw_hal_mgnt_xmit(padapter, pmgntframe);
8206 }
8207 
dump_mgntframe_and_wait(_adapter * padapter,struct xmit_frame * pmgntframe,int timeout_ms)8208 s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
8209 {
8210 	s32 ret = _FAIL;
8211 	_irqL irqL;
8212 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
8213 	struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
8214 	struct submit_ctx sctx;
8215 
8216 	if (RTW_CANNOT_RUN(padapter)) {
8217 		rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
8218 		rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
8219 		return ret;
8220 	}
8221 
8222 	rtw_sctx_init(&sctx, timeout_ms);
8223 	pxmitbuf->sctx = &sctx;
8224 
8225 	ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
8226 
8227 	if (ret == _SUCCESS
8228 #ifdef CONFIG_RTW_MGMT_QUEUE
8229 	|| ret == RTW_QUEUE_MGMT
8230 #endif
8231 	)
8232 		ret = rtw_sctx_wait(&sctx, __func__);
8233 
8234 	_enter_critical(&pxmitpriv->lock_sctx, &irqL);
8235 	pxmitbuf->sctx = NULL;
8236 	_exit_critical(&pxmitpriv->lock_sctx, &irqL);
8237 
8238 	return ret;
8239 }
8240 
dump_mgntframe_and_wait_ack_timeout(_adapter * padapter,struct xmit_frame * pmgntframe,int timeout_ms)8241 s32 dump_mgntframe_and_wait_ack_timeout(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
8242 {
8243 #ifdef CONFIG_XMIT_ACK
8244 	static u8 seq_no = 0;
8245 	s32 ret = _FAIL;
8246 	struct xmit_priv	*pxmitpriv = &(GET_PRIMARY_ADAPTER(padapter))->xmitpriv;
8247 
8248 	if (RTW_CANNOT_RUN(padapter)) {
8249 		rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
8250 		rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
8251 		return -1;
8252 	}
8253 
8254 	_enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
8255 	pxmitpriv->ack_tx = _TRUE;
8256 	pxmitpriv->seq_no = seq_no++;
8257 	pmgntframe->ack_report = 1;
8258 	rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms);
8259 
8260 	ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
8261 
8262 	if (ret == _SUCCESS
8263 #ifdef CONFIG_RTW_MGMT_QUEUE
8264 	|| ret == RTW_QUEUE_MGMT
8265 #endif
8266 	)
8267 		ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__);
8268 
8269 	pxmitpriv->ack_tx = _FALSE;
8270 	_exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
8271 
8272 	return ret;
8273 #else /* !CONFIG_XMIT_ACK */
8274 	dump_mgntframe(padapter, pmgntframe);
8275 	rtw_msleep_os(50);
8276 	return _SUCCESS;
8277 #endif /* !CONFIG_XMIT_ACK */
8278 }
8279 
dump_mgntframe_and_wait_ack(_adapter * padapter,struct xmit_frame * pmgntframe)8280 s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
8281 {
8282 	/* In this case, use 500 ms as the default wait_ack timeout */
8283 	return dump_mgntframe_and_wait_ack_timeout(padapter, pmgntframe, 500);
8284 }
8285 
8286 
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)8287 int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
8288 {
8289 	u8 *ssid_ie;
8290 	sint ssid_len_ori;
8291 	int len_diff = 0;
8292 
8293 	ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
8294 
8295 	/* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
8296 
8297 	if (ssid_ie && ssid_len_ori > 0) {
8298 		switch (hidden_ssid_mode) {
8299 		case 1: {
8300 			u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
8301 			u32 remain_len = 0;
8302 
8303 			remain_len = ies_len - (next_ie - ies);
8304 
8305 			ssid_ie[1] = 0;
8306 			_rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
8307 			len_diff -= ssid_len_ori;
8308 
8309 			break;
8310 		}
8311 		case 2:
8312 			_rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
8313 			break;
8314 		default:
8315 			break;
8316 		}
8317 	}
8318 
8319 	return len_diff;
8320 }
8321 
8322 #ifdef CONFIG_AP_MODE
issue_beacon(_adapter * padapter,int timeout_ms)8323 void issue_beacon(_adapter *padapter, int timeout_ms)
8324 {
8325 	struct xmit_frame	*pmgntframe;
8326 	struct pkt_attrib	*pattrib;
8327 	unsigned char	*pframe;
8328 	struct rtw_ieee80211_hdr *pwlanhdr;
8329 	unsigned short *fctrl;
8330 	unsigned int	rate_len;
8331 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
8332 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
8333 	_irqL irqL;
8334 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8335 #endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
8336 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8337 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8338 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
8339 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8340 #ifdef CONFIG_P2P
8341 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
8342 #endif /* CONFIG_P2P */
8343 
8344 
8345 	/* RTW_INFO("%s\n", __FUNCTION__); */
8346 
8347 #ifdef CONFIG_BCN_ICF
8348 	pmgntframe = rtw_alloc_bcnxmitframe(pxmitpriv);
8349 	if (pmgntframe == NULL)
8350 #else
8351 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8352 	if (pmgntframe == NULL)
8353 #endif
8354 	{
8355 		RTW_INFO("%s, alloc mgnt frame fail\n", __FUNCTION__);
8356 		return;
8357 	}
8358 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
8359 	_enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
8360 #endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
8361 
8362 	/* update attribute */
8363 	pattrib = &pmgntframe->attrib;
8364 	update_mgntframe_attrib(padapter, pattrib);
8365 	pattrib->qsel = QSLT_BEACON;
8366 
8367 #if defined(CONFIG_CONCURRENT_MODE) && (!defined(CONFIG_SWTIMER_BASED_TXBCN))
8368 	if (padapter->hw_port == HW_PORT1)
8369 		pattrib->mbssid = 1;
8370 #endif
8371 #ifdef CONFIG_FW_HANDLE_TXBCN
8372 	if (padapter->vap_id != CONFIG_LIMITED_AP_NUM)
8373 		pattrib->mbssid = padapter->vap_id;
8374 #endif
8375 
8376 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8377 
8378 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8379 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8380 
8381 
8382 	fctrl = &(pwlanhdr->frame_ctl);
8383 	*(fctrl) = 0;
8384 
8385 	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8386 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8387 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
8388 
8389 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
8390 	/* pmlmeext->mgnt_seq++; */
8391 	set_frame_sub_type(pframe, WIFI_BEACON);
8392 
8393 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8394 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8395 
8396 	if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) {
8397 		/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
8398 #ifdef CONFIG_P2P
8399 		/* for P2P : Primary Device Type & Device Name */
8400 		u32 wpsielen = 0, insert_len = 0;
8401 		u8 *wpsie = NULL;
8402 		wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
8403 
8404 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
8405 			uint wps_offset, remainder_ielen;
8406 			u8 *premainder_ie, *pframe_wscie;
8407 
8408 			wps_offset = (uint)(wpsie - cur_network->IEs);
8409 
8410 			premainder_ie = wpsie + wpsielen;
8411 
8412 			remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
8413 
8414 #ifdef CONFIG_IOCTL_CFG80211
8415 			if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
8416 				if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
8417 					_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
8418 					pframe += wps_offset;
8419 					pattrib->pktlen += wps_offset;
8420 
8421 					_rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
8422 					pframe += pmlmepriv->wps_beacon_ie_len;
8423 					pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
8424 
8425 					/* copy remainder_ie to pframe */
8426 					_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
8427 					pframe += remainder_ielen;
8428 					pattrib->pktlen += remainder_ielen;
8429 				} else {
8430 					_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8431 					pframe += cur_network->IELength;
8432 					pattrib->pktlen += cur_network->IELength;
8433 				}
8434 			} else
8435 #endif /* CONFIG_IOCTL_CFG80211 */
8436 			{
8437 				pframe_wscie = pframe + wps_offset;
8438 				_rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
8439 				pframe += (wps_offset + wpsielen);
8440 				pattrib->pktlen += (wps_offset + wpsielen);
8441 
8442 				/* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
8443 				/*	Primary Device Type */
8444 				/*	Type: */
8445 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
8446 				insert_len += 2;
8447 
8448 				/*	Length: */
8449 				*(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
8450 				insert_len += 2;
8451 
8452 				/*	Value: */
8453 				/*	Category ID */
8454 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
8455 				insert_len += 2;
8456 
8457 				/*	OUI */
8458 				*(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
8459 				insert_len += 4;
8460 
8461 				/*	Sub Category ID */
8462 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
8463 				insert_len += 2;
8464 
8465 
8466 				/*	Device Name */
8467 				/*	Type: */
8468 				*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
8469 				insert_len += 2;
8470 
8471 				/*	Length: */
8472 				*(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
8473 				insert_len += 2;
8474 
8475 				/*	Value: */
8476 				_rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
8477 				insert_len += pwdinfo->device_name_len;
8478 
8479 
8480 				/* update wsc ie length */
8481 				*(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
8482 
8483 				/* pframe move to end */
8484 				pframe += insert_len;
8485 				pattrib->pktlen += insert_len;
8486 
8487 				/* copy remainder_ie to pframe */
8488 				_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
8489 				pframe += remainder_ielen;
8490 				pattrib->pktlen += remainder_ielen;
8491 			}
8492 		} else
8493 #endif /* CONFIG_P2P */
8494 		{
8495 			int len_diff;
8496 			_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8497 			len_diff = update_hidden_ssid(
8498 					   pframe + _BEACON_IE_OFFSET_
8499 				   , cur_network->IELength - _BEACON_IE_OFFSET_
8500 					   , pmlmeinfo->hidden_ssid_mode
8501 				   );
8502 			pframe += (cur_network->IELength + len_diff);
8503 			pattrib->pktlen += (cur_network->IELength + len_diff);
8504 		}
8505 
8506 		{
8507 			u8 *wps_ie;
8508 			uint wps_ielen;
8509 			u8 sr = 0;
8510 			wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
8511 				pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
8512 			if (wps_ie && wps_ielen > 0)
8513 				rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
8514 			if (sr != 0)
8515 				set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
8516 			else
8517 				_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
8518 		}
8519 
8520 #ifdef CONFIG_P2P
8521 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
8522 			u32 len;
8523 #ifdef CONFIG_IOCTL_CFG80211
8524 			if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
8525 				len = pmlmepriv->p2p_beacon_ie_len;
8526 				if (pmlmepriv->p2p_beacon_ie && len > 0)
8527 					_rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
8528 			} else
8529 #endif /* CONFIG_IOCTL_CFG80211 */
8530 			{
8531 				len = build_beacon_p2p_ie(pwdinfo, pframe);
8532 			}
8533 
8534 			pframe += len;
8535 			pattrib->pktlen += len;
8536 
8537 #ifdef CONFIG_MCC_MODE
8538 			pframe = rtw_hal_mcc_append_go_p2p_ie(padapter, pframe, &pattrib->pktlen);
8539 #endif /* CONFIG_MCC_MODE*/
8540 
8541 #ifdef CONFIG_WFD
8542 			len = rtw_append_beacon_wfd_ie(padapter, pframe);
8543 			pframe += len;
8544 			pattrib->pktlen += len;
8545 #endif
8546 		}
8547 #endif /* CONFIG_P2P */
8548 #ifdef CONFIG_RTW_REPEATER_SON
8549 		rtw_rson_append_ie(padapter, pframe, &pattrib->pktlen);
8550 #endif
8551 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
8552 		pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_BEACON_VENDOR_IE_BIT);
8553 #endif
8554 
8555 #ifdef CONFIG_RTL8812A
8556 		pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen );
8557 #endif/*CONFIG_RTL8812A*/
8558 
8559 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
8560 		if (padapter->tbtx_capability == _TRUE)
8561 			pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 8, REALTEK_TBTX_IE, &pattrib->pktlen);
8562 #endif
8563 
8564 		goto _issue_bcn;
8565 
8566 	}
8567 
8568 	/* below for ad-hoc mode */
8569 
8570 	/* timestamp will be inserted by hardware */
8571 	pframe += 8;
8572 	pattrib->pktlen += 8;
8573 
8574 	/* beacon interval: 2 bytes */
8575 
8576 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
8577 
8578 	pframe += 2;
8579 	pattrib->pktlen += 2;
8580 
8581 	/* capability info: 2 bytes */
8582 
8583 	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
8584 
8585 	pframe += 2;
8586 	pattrib->pktlen += 2;
8587 
8588 	/* SSID */
8589 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
8590 
8591 	/* supported rates... */
8592 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
8593 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
8594 
8595 	/* DS parameter set */
8596 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
8597 
8598 	/* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
8599 	{
8600 		u8 erpinfo = 0;
8601 		u32 ATIMWindow;
8602 		/* IBSS Parameter Set... */
8603 		/* ATIMWindow = cur->Configuration.ATIMWindow; */
8604 		ATIMWindow = 0;
8605 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
8606 
8607 		/* ERP IE */
8608 		pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
8609 	}
8610 
8611 
8612 	/* EXTERNDED SUPPORTED RATE */
8613 	if (rate_len > 8)
8614 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
8615 
8616 
8617 	/* todo:HT for adhoc */
8618 
8619 _issue_bcn:
8620 
8621 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
8622 	pmlmepriv->update_bcn = _FALSE;
8623 
8624 	_exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
8625 #endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
8626 
8627 	if ((pattrib->pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
8628 		RTW_ERR("beacon frame too large ,len(%d,%d)\n",
8629 			(pattrib->pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
8630 		rtw_warn_on(1);
8631 		return;
8632 	}
8633 
8634 	pattrib->last_txcmdsz = pattrib->pktlen;
8635 
8636 	/* RTW_INFO("issue bcn_sz=%d\n", pattrib->last_txcmdsz); */
8637 	if (timeout_ms > 0)
8638 		dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
8639 	else
8640 		dump_mgntframe(padapter, pmgntframe);
8641 
8642 }
8643 #endif /* CONFIG_AP_MODE */
8644 
issue_probersp(_adapter * padapter,unsigned char * da,u8 is_valid_p2p_probereq)8645 void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
8646 {
8647 	struct xmit_frame			*pmgntframe;
8648 	struct pkt_attrib			*pattrib;
8649 	unsigned char					*pframe;
8650 	struct rtw_ieee80211_hdr	*pwlanhdr;
8651 	unsigned short				*fctrl;
8652 	unsigned char					*mac, *bssid;
8653 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
8654 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
8655 	u8 *pwps_ie;
8656 	uint wps_ielen;
8657 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8658 #endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
8659 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8660 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
8661 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
8662 	unsigned int	rate_len;
8663 #ifdef CONFIG_P2P
8664 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
8665 #endif /* CONFIG_P2P */
8666 
8667 	/* RTW_INFO("%s\n", __FUNCTION__); */
8668 
8669 	if (da == NULL)
8670 		return;
8671 
8672 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8673 		return;
8674 
8675 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8676 	if (pmgntframe == NULL) {
8677 		RTW_INFO("%s, alloc mgnt frame fail\n", __FUNCTION__);
8678 		return;
8679 	}
8680 
8681 
8682 	/* update attribute */
8683 	pattrib = &pmgntframe->attrib;
8684 	update_mgntframe_attrib(padapter, pattrib);
8685 
8686 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8687 
8688 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8689 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8690 
8691 	mac = adapter_mac_addr(padapter);
8692 	bssid = cur_network->MacAddress;
8693 
8694 	fctrl = &(pwlanhdr->frame_ctl);
8695 	*(fctrl) = 0;
8696 	_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8697 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8698 	_rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8699 
8700 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8701 	pmlmeext->mgnt_seq++;
8702 	set_frame_sub_type(fctrl, WIFI_PROBERSP);
8703 
8704 	pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8705 	pattrib->pktlen = pattrib->hdrlen;
8706 	pframe += pattrib->hdrlen;
8707 
8708 
8709 	if (cur_network->IELength > MAX_IE_SZ)
8710 		return;
8711 
8712 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
8713 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
8714 		pwps_ie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wps_ielen);
8715 
8716 		/* inerset & update wps_probe_resp_ie */
8717 		if ((pmlmepriv->wps_probe_resp_ie != NULL) && pwps_ie && (wps_ielen > 0)) {
8718 			uint wps_offset, remainder_ielen;
8719 			u8 *premainder_ie;
8720 
8721 			wps_offset = (uint)(pwps_ie - cur_network->IEs);
8722 
8723 			premainder_ie = pwps_ie + wps_ielen;
8724 
8725 			remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
8726 
8727 			_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
8728 			pframe += wps_offset;
8729 			pattrib->pktlen += wps_offset;
8730 
8731 			wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];/* to get ie data len */
8732 			if ((wps_offset + wps_ielen + 2) <= MAX_IE_SZ) {
8733 				_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen + 2);
8734 				pframe += wps_ielen + 2;
8735 				pattrib->pktlen += wps_ielen + 2;
8736 			}
8737 
8738 			if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) {
8739 				_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
8740 				pframe += remainder_ielen;
8741 				pattrib->pktlen += remainder_ielen;
8742 			}
8743 		} else {
8744 			_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8745 			pframe += cur_network->IELength;
8746 			pattrib->pktlen += cur_network->IELength;
8747 		}
8748 
8749 		/* retrieve SSID IE from cur_network->Ssid */
8750 		{
8751 			u8 *ssid_ie;
8752 			sint ssid_ielen;
8753 			sint ssid_ielen_diff;
8754 			u8 buf[MAX_IE_SZ];
8755 			u8 *ies = pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr);
8756 
8757 			ssid_ie = rtw_get_ie(ies + _FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
8758 				     (pframe - ies) - _FIXED_IE_LENGTH_);
8759 
8760 			ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
8761 
8762 			if (ssid_ie &&  cur_network->Ssid.SsidLength) {
8763 				uint remainder_ielen;
8764 				u8 *remainder_ie;
8765 				remainder_ie = ssid_ie + 2;
8766 				remainder_ielen = (pframe - remainder_ie);
8767 
8768 				if (remainder_ielen > MAX_IE_SZ) {
8769 					RTW_WARN(FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
8770 					remainder_ielen = MAX_IE_SZ;
8771 				}
8772 
8773 				_rtw_memcpy(buf, remainder_ie, remainder_ielen);
8774 				_rtw_memcpy(remainder_ie + ssid_ielen_diff, buf, remainder_ielen);
8775 				*(ssid_ie + 1) = cur_network->Ssid.SsidLength;
8776 				_rtw_memcpy(ssid_ie + 2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
8777 
8778 				pframe += ssid_ielen_diff;
8779 				pattrib->pktlen += ssid_ielen_diff;
8780 			}
8781 		}
8782 #ifdef CONFIG_RTW_REPEATER_SON
8783 		rtw_rson_append_ie(padapter, pframe, &pattrib->pktlen);
8784 #endif
8785 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
8786 		pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_PROBERESP_VENDOR_IE_BIT);
8787 #endif
8788 	} else
8789 #endif
8790 	{
8791 
8792 		/* timestamp will be inserted by hardware */
8793 		pframe += 8;
8794 		pattrib->pktlen += 8;
8795 
8796 		/* beacon interval: 2 bytes */
8797 
8798 		_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
8799 
8800 		pframe += 2;
8801 		pattrib->pktlen += 2;
8802 
8803 		/* capability info: 2 bytes */
8804 
8805 		_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
8806 
8807 		pframe += 2;
8808 		pattrib->pktlen += 2;
8809 
8810 		/* below for ad-hoc mode */
8811 
8812 		/* SSID */
8813 		pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
8814 
8815 		/* supported rates... */
8816 		rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
8817 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
8818 
8819 		/* DS parameter set */
8820 		pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
8821 
8822 		if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
8823 			u8 erpinfo = 0;
8824 			u32 ATIMWindow;
8825 			/* IBSS Parameter Set... */
8826 			/* ATIMWindow = cur->Configuration.ATIMWindow; */
8827 			ATIMWindow = 0;
8828 			pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
8829 
8830 			/* ERP IE */
8831 			pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
8832 		}
8833 
8834 
8835 		/* EXTERNDED SUPPORTED RATE */
8836 		if (rate_len > 8)
8837 			pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
8838 
8839 
8840 		/* todo:HT for adhoc */
8841 
8842 	}
8843 
8844 #ifdef CONFIG_P2P
8845 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
8846 	    /* IOT issue, When wifi_spec is not set, send probe_resp with P2P IE even if probe_req has no P2P IE */
8847 	    && (is_valid_p2p_probereq || !padapter->registrypriv.wifi_spec)) {
8848 		u32 len;
8849 #ifdef CONFIG_IOCTL_CFG80211
8850 		if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
8851 			/* if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p() */
8852 			len = pmlmepriv->p2p_go_probe_resp_ie_len;
8853 			if (pmlmepriv->p2p_go_probe_resp_ie && len > 0)
8854 				_rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
8855 		} else
8856 #endif /* CONFIG_IOCTL_CFG80211 */
8857 		{
8858 			len = build_probe_resp_p2p_ie(pwdinfo, pframe);
8859 		}
8860 
8861 		pframe += len;
8862 		pattrib->pktlen += len;
8863 
8864 #ifdef CONFIG_MCC_MODE
8865 		pframe = rtw_hal_mcc_append_go_p2p_ie(padapter, pframe, &pattrib->pktlen);
8866 #endif /* CONFIG_MCC_MODE*/
8867 
8868 #ifdef CONFIG_WFD
8869 		len = rtw_append_probe_resp_wfd_ie(padapter, pframe);
8870 		pframe += len;
8871 		pattrib->pktlen += len;
8872 #endif
8873 	}
8874 #endif /* CONFIG_P2P */
8875 
8876 
8877 #ifdef CONFIG_AUTO_AP_MODE
8878 	{
8879 		struct sta_info	*psta;
8880 		struct sta_priv *pstapriv = &padapter->stapriv;
8881 
8882 		RTW_INFO("(%s)\n", __FUNCTION__);
8883 
8884 		/* check rc station */
8885 		psta = rtw_get_stainfo(pstapriv, da);
8886 		if (psta && psta->isrc && psta->pid > 0) {
8887 			u8 RC_OUI[4] = {0x00, 0xE0, 0x4C, 0x0A};
8888 			u8 RC_INFO[14] = {0};
8889 			/* EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] */
8890 			u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
8891 
8892 			RTW_INFO("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__,
8893 				 psta->pid, MAC_ARG(psta->cmn.mac_addr), cu_ch);
8894 
8895 			/* append vendor specific ie */
8896 			_rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
8897 			_rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN);
8898 			_rtw_memcpy(&RC_INFO[10], (u8 *)&psta->pid, 2);
8899 			_rtw_memcpy(&RC_INFO[12], (u8 *)&cu_ch, 2);
8900 
8901 			pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
8902 		}
8903 	}
8904 #endif /* CONFIG_AUTO_AP_MODE */
8905 
8906 #ifdef CONFIG_RTL8812A
8907 	pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen);
8908 #endif/*CONFIG_RTL8812A*/
8909 
8910 	pattrib->last_txcmdsz = pattrib->pktlen;
8911 
8912 
8913 	dump_mgntframe(padapter, pmgntframe);
8914 
8915 	return;
8916 
8917 }
8918 
_issue_probereq(_adapter * padapter,const NDIS_802_11_SSID * pssid,const u8 * da,u8 ch,bool append_wps,int wait_ack)8919 int _issue_probereq(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 *da, u8 ch, bool append_wps, int wait_ack)
8920 {
8921 	int ret = _FAIL;
8922 	struct xmit_frame		*pmgntframe;
8923 	struct pkt_attrib		*pattrib;
8924 	unsigned char			*pframe;
8925 	struct rtw_ieee80211_hdr	*pwlanhdr;
8926 	unsigned short		*fctrl;
8927 	unsigned char			*mac;
8928 	unsigned char			bssrate[NumRates];
8929 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
8930 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8931 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
8932 	int	bssrate_len = 0;
8933 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8934 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
8935 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
8936 #endif
8937 
8938 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8939 		goto exit;
8940 
8941 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8942 	if (pmgntframe == NULL)
8943 		goto exit;
8944 
8945 	/* update attribute */
8946 	pattrib = &pmgntframe->attrib;
8947 	update_mgntframe_attrib(padapter, pattrib);
8948 
8949 
8950 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8951 
8952 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8953 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8954 
8955 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
8956 	if ((pwdev_priv->pno_mac_addr[0] != 0xFF)
8957 	    && (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE)
8958 	    && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _FALSE))
8959 		mac = pwdev_priv->pno_mac_addr;
8960 	else
8961 #endif
8962 	mac = adapter_mac_addr(padapter);
8963 
8964 	fctrl = &(pwlanhdr->frame_ctl);
8965 	*(fctrl) = 0;
8966 
8967 	if (da) {
8968 		/*	unicast probe request frame */
8969 		_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8970 		_rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
8971 	} else {
8972 		/*	broadcast probe request frame */
8973 		_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8974 		_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8975 	}
8976 
8977 	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8978 
8979 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
8980 	if ((pwdev_priv->pno_mac_addr[0] != 0xFF)
8981 	    && (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE)
8982 	    && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _FALSE)) {
8983 #ifdef CONFIG_RTW_DEBUG
8984 		RTW_DBG("%s pno_scan_seq_num: %d\n", __func__,
8985 			 pwdev_priv->pno_scan_seq_num);
8986 #endif
8987 		SetSeqNum(pwlanhdr, pwdev_priv->pno_scan_seq_num);
8988 		pattrib->seqnum = pwdev_priv->pno_scan_seq_num;
8989 		pattrib->qos_en = 1;
8990 		pwdev_priv->pno_scan_seq_num++;
8991 	} else
8992 #endif
8993 	{
8994 		SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8995 		pmlmeext->mgnt_seq++;
8996 	}
8997 	set_frame_sub_type(pframe, WIFI_PROBEREQ);
8998 
8999 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9000 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9001 
9002 	if (pssid && !MLME_IS_MESH(padapter))
9003 		pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
9004 	else
9005 		pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
9006 
9007 	get_rate_set(padapter, bssrate, &bssrate_len);
9008 
9009 	if (bssrate_len > 8) {
9010 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
9011 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
9012 	} else
9013 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
9014 
9015 	if (ch)
9016 		pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen);
9017 
9018 #ifdef CONFIG_RTW_MESH
9019 	if (MLME_IS_MESH(padapter)) {
9020 		if (pssid)
9021 			pframe = rtw_set_ie_mesh_id(pframe, &pattrib->pktlen, pssid->Ssid, pssid->SsidLength);
9022 		else
9023 			pframe = rtw_set_ie_mesh_id(pframe, &pattrib->pktlen, NULL, 0);
9024 	}
9025 #endif
9026 
9027 	if (append_wps) {
9028 		/* add wps_ie for wps2.0 */
9029 		if (pmlmepriv->wps_probe_req_ie_len > 0 && pmlmepriv->wps_probe_req_ie) {
9030 			_rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
9031 			pframe += pmlmepriv->wps_probe_req_ie_len;
9032 			pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
9033 			/* pmlmepriv->wps_probe_req_ie_len = 0 ; */ /* reset to zero */
9034 		}
9035 	}
9036 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
9037 	pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_PROBEREQ_VENDOR_IE_BIT);
9038 #endif
9039 
9040 #ifdef CONFIG_RTL8812A
9041 	pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen );
9042 #endif/*CONFIG_RTL8812A*/
9043 
9044 
9045 #ifdef CONFIG_RTW_MBO
9046 	rtw_mbo_build_probe_req_ies(	padapter, &pframe, pattrib);
9047 #endif
9048 
9049 	pattrib->last_txcmdsz = pattrib->pktlen;
9050 
9051 
9052 	if (wait_ack)
9053 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9054 	else {
9055 		dump_mgntframe(padapter, pmgntframe);
9056 		ret = _SUCCESS;
9057 	}
9058 
9059 exit:
9060 	return ret;
9061 }
9062 
issue_probereq(_adapter * padapter,const NDIS_802_11_SSID * pssid,const u8 * da)9063 inline void issue_probereq(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 *da)
9064 {
9065 	_issue_probereq(padapter, pssid, da, 0, 1, _FALSE);
9066 }
9067 
9068 /*
9069  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9070  * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9071  * try_cnt means the maximal TX count to try
9072  */
issue_probereq_ex(_adapter * padapter,const NDIS_802_11_SSID * pssid,const u8 * da,u8 ch,bool append_wps,int try_cnt,int wait_ms)9073 int issue_probereq_ex(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 *da, u8 ch, bool append_wps,
9074 		      int try_cnt, int wait_ms)
9075 {
9076 	int ret = _FAIL;
9077 	int i = 0;
9078 	systime start = rtw_get_current_time();
9079 
9080 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9081 		goto exit;
9082 
9083 	do {
9084 		ret = _issue_probereq(padapter, pssid, da, ch, append_wps, wait_ms > 0 ? _TRUE : _FALSE);
9085 
9086 		i++;
9087 
9088 		if (RTW_CANNOT_RUN(padapter))
9089 			break;
9090 
9091 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
9092 			rtw_msleep_os(wait_ms);
9093 
9094 	} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
9095 
9096 	if (ret != _FAIL) {
9097 		ret = _SUCCESS;
9098 #ifndef DBG_XMIT_ACK
9099 		goto exit;
9100 #endif
9101 	}
9102 
9103 	if (try_cnt && wait_ms) {
9104 		if (da)
9105 			RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9106 				FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9107 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9108 		else
9109 			RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9110 				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9111 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9112 	}
9113 exit:
9114 	return ret;
9115 }
9116 
9117 /* if psta == NULL, indiate we are station(client) now... */
issue_auth(_adapter * padapter,struct sta_info * psta,unsigned short status)9118 void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
9119 {
9120 	struct xmit_frame			*pmgntframe;
9121 	struct pkt_attrib			*pattrib;
9122 	unsigned char					*pframe;
9123 	struct rtw_ieee80211_hdr	*pwlanhdr;
9124 	unsigned short				*fctrl;
9125 	unsigned int					val32;
9126 	unsigned short				val16;
9127 	int use_shared_key = 0;
9128 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
9129 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
9130 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9131 
9132 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9133 		return;
9134 
9135 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9136 	if (pmgntframe == NULL)
9137 		return;
9138 
9139 	/* update attribute */
9140 	pattrib = &pmgntframe->attrib;
9141 	update_mgntframe_attrib(padapter, pattrib);
9142 
9143 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9144 
9145 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9146 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9147 
9148 	fctrl = &(pwlanhdr->frame_ctl);
9149 	*(fctrl) = 0;
9150 
9151 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9152 	pmlmeext->mgnt_seq++;
9153 	set_frame_sub_type(pframe, WIFI_AUTH);
9154 
9155 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9156 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9157 
9158 
9159 	if (psta) { /* for AP mode */
9160 #ifdef CONFIG_NATIVEAP_MLME
9161 
9162 		_rtw_memcpy(pwlanhdr->addr1, psta->cmn.mac_addr, ETH_ALEN);
9163 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9164 		_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
9165 
9166 
9167 		/* setting auth algo number */
9168 		val16 = (u16)psta->authalg;
9169 
9170 		if (status != _STATS_SUCCESSFUL_)
9171 			val16 = 0;
9172 
9173 		if (val16)	{
9174 			val16 = cpu_to_le16(val16);
9175 			use_shared_key = 1;
9176 		}
9177 
9178 		pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
9179 
9180 		/* setting auth seq number */
9181 		val16 = (u16)psta->auth_seq;
9182 		val16 = cpu_to_le16(val16);
9183 		pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
9184 
9185 		/* setting status code... */
9186 		val16 = status;
9187 		val16 = cpu_to_le16(val16);
9188 		pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
9189 
9190 		/* added challenging text... */
9191 		if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
9192 			pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
9193 #endif
9194 	} else {
9195 		_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
9196 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9197 		_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
9198 
9199 #ifdef CONFIG_RTW_80211R
9200 		if (rtw_ft_roam(padapter)) {
9201 			/* 2: 802.11R FTAA */
9202 			val16 = cpu_to_le16(2);
9203 		} else
9204 #endif
9205 		{
9206 			/* setting auth algo number */
9207 			val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;	/* 0:OPEN System, 1:Shared key */
9208 			if (val16) {
9209 				val16 = cpu_to_le16(val16);
9210 				use_shared_key = 1;
9211 			}
9212 		}
9213 
9214 		/* RTW_INFO("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq); */
9215 
9216 		/* setting IV for auth seq #3 */
9217 		if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
9218 			/* RTW_INFO("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index); */
9219 			val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
9220 			val32 = cpu_to_le32(val32);
9221 			pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
9222 
9223 			pattrib->iv_len = 4;
9224 		}
9225 
9226 		pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
9227 
9228 		/* setting auth seq number */
9229 		val16 = pmlmeinfo->auth_seq;
9230 		val16 = cpu_to_le16(val16);
9231 		pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
9232 
9233 
9234 		/* setting status code... */
9235 		val16 = status;
9236 		val16 = cpu_to_le16(val16);
9237 		pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
9238 
9239 #ifdef CONFIG_RTW_80211R
9240 		rtw_ft_build_auth_req_ies(padapter, pattrib, &pframe);
9241 #endif
9242 
9243 		/* then checking to see if sending challenging text... */
9244 		if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
9245 			pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
9246 
9247 			SetPrivacy(fctrl);
9248 
9249 			pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9250 
9251 			pattrib->encrypt = _WEP40_;
9252 
9253 			pattrib->icv_len = 4;
9254 
9255 			pattrib->pktlen += pattrib->icv_len;
9256 
9257 		}
9258 
9259 	}
9260 
9261 	pattrib->last_txcmdsz = pattrib->pktlen;
9262 
9263 	rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
9264 	RTW_INFO("%s to "MAC_FMT" status:%u\n", __FUNCTION__, MAC_ARG(pwlanhdr->addr1), status);
9265 	dump_mgntframe(padapter, pmgntframe);
9266 
9267 	return;
9268 }
9269 
9270 
issue_asocrsp(_adapter * padapter,unsigned short status,struct sta_info * pstat,int pkt_type)9271 void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
9272 {
9273 #ifdef CONFIG_AP_MODE
9274 	struct xmit_frame	*pmgntframe;
9275 	struct rtw_ieee80211_hdr	*pwlanhdr;
9276 	struct pkt_attrib *pattrib;
9277 	unsigned char	*pbuf, *pframe;
9278 	unsigned short val, ie_status;
9279 	unsigned short *fctrl;
9280 	struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9281 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
9282 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9283 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9284 	WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
9285 	u8 *ie = pnetwork->IEs, cap[5], i;
9286 	struct security_priv *psecuritypriv = &(padapter->securitypriv);
9287 #ifdef CONFIG_P2P
9288 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
9289 #ifdef CONFIG_WFD
9290 	u32					wfdielen = 0;
9291 #endif
9292 
9293 #endif /* CONFIG_P2P */
9294 
9295 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9296 		return;
9297 
9298 	RTW_INFO("%s to "MAC_FMT" status:%u\n", __FUNCTION__, MAC_ARG(pstat->cmn.mac_addr), status);
9299 
9300 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9301 	if (pmgntframe == NULL)
9302 		return;
9303 
9304 	/* update attribute */
9305 	pattrib = &pmgntframe->attrib;
9306 	update_mgntframe_attrib(padapter, pattrib);
9307 
9308 
9309 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9310 
9311 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9312 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9313 
9314 	fctrl = &(pwlanhdr->frame_ctl);
9315 	*(fctrl) = 0;
9316 
9317 	_rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->cmn.mac_addr, ETH_ALEN);
9318 	_rtw_memcpy((void *)get_addr2_ptr(pwlanhdr), adapter_mac_addr(padapter), ETH_ALEN);
9319 	_rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9320 
9321 
9322 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9323 	pmlmeext->mgnt_seq++;
9324 	if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
9325 		set_frame_sub_type(pwlanhdr, pkt_type);
9326 	else
9327 		return;
9328 
9329 	pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9330 	pattrib->pktlen += pattrib->hdrlen;
9331 	pframe += pattrib->hdrlen;
9332 
9333 	/* capability */
9334 	val = *(unsigned short *)rtw_get_capability_from_ie(ie);
9335 #ifdef CONFIG_RTW_80211K
9336 	val |= cap_RM;
9337 #endif
9338 	pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
9339 
9340 	ie_status = cpu_to_le16(status);
9341 	pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&ie_status, &(pattrib->pktlen));
9342 
9343 	val = cpu_to_le16(pstat->cmn.aid | BIT(14) | BIT(15));
9344 	pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
9345 
9346 	if (pstat->bssratelen <= 8)
9347 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
9348 	else {
9349 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
9350 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen - 8), pstat->bssrateset + 8, &(pattrib->pktlen));
9351 	}
9352 
9353 #ifdef CONFIG_IEEE80211W
9354 	if (status == _STATS_REFUSED_TEMPORARILY_) {
9355 		u8 timeout_itvl[5];
9356 		u32 timeout_interval = 3000;
9357 		/* Association Comeback time */
9358 		timeout_itvl[0] = 0x03;
9359 		timeout_interval = cpu_to_le32(timeout_interval);
9360 		_rtw_memcpy(timeout_itvl + 1, &timeout_interval, 4);
9361 		pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
9362 	}
9363 #endif /* CONFIG_IEEE80211W */
9364 
9365 #ifdef CONFIG_80211N_HT
9366 	if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) {
9367 		uint ie_len = 0;
9368 
9369 		/* FILL HT CAP INFO IE */
9370 		/* p = hostapd_eid_ht_capabilities_info(hapd, p); */
9371 		pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
9372 		if (pbuf && ie_len > 0) {
9373 			_rtw_memcpy(pframe, pbuf, ie_len + 2);
9374 			pframe += (ie_len + 2);
9375 			pattrib->pktlen += (ie_len + 2);
9376 		}
9377 
9378 		/* FILL HT ADD INFO IE */
9379 		/* p = hostapd_eid_ht_operation(hapd, p); */
9380 		pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
9381 		if (pbuf && ie_len > 0) {
9382 			_rtw_memcpy(pframe, pbuf, ie_len + 2);
9383 			pframe += (ie_len + 2);
9384 			pattrib->pktlen += (ie_len + 2);
9385 		}
9386 
9387 	}
9388 #endif
9389 
9390 	/*adding EXT_CAPAB_IE */
9391 	if (pmlmepriv->ext_capab_ie_len > 0) {
9392 		uint ie_len = 0;
9393 
9394 		pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_EXT_CAP, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
9395 		if (pbuf && ie_len > 0) {
9396 			_rtw_memcpy(pframe, pbuf, ie_len + 2);
9397 			pframe += (ie_len + 2);
9398 			pattrib->pktlen += (ie_len + 2);
9399 		}
9400 	}
9401 
9402 #ifdef CONFIG_80211AC_VHT
9403 	if ((pstat->flags & WLAN_STA_VHT) && (pmlmepriv->vhtpriv.vht_option)
9404 	    && (pstat->wpa_pairwise_cipher != WPA_CIPHER_TKIP)
9405 	    && (pstat->wpa2_pairwise_cipher != WPA_CIPHER_TKIP)) {
9406 		u32 ie_len = 0;
9407 
9408 		/* FILL VHT CAP IE */
9409 		pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
9410 		if (pbuf && ie_len > 0) {
9411 			_rtw_memcpy(pframe, pbuf, ie_len + 2);
9412 			pframe += (ie_len + 2);
9413 			pattrib->pktlen += (ie_len + 2);
9414 		}
9415 
9416 		/* FILL VHT OPERATION IE */
9417 		pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTOperation, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
9418 		if (pbuf && ie_len > 0) {
9419 			_rtw_memcpy(pframe, pbuf, ie_len + 2);
9420 			pframe += (ie_len + 2);
9421 			pattrib->pktlen += (ie_len + 2);
9422 		}
9423 	}
9424 #endif /* CONFIG_80211AC_VHT */
9425 
9426 #ifdef CONFIG_RTW_80211K
9427 	/* FILL RM Enabled Capabilities with joint capabilities */
9428 	for (i = 0; i < 5; i++) {
9429 		cap[i] = padapter->rmpriv.rm_en_cap_def[i]
9430 			 & pstat->rm_en_cap[i];
9431 	}
9432 	if (pstat->capability & cap_RM)
9433 		pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, 5,
9434 				    (u8 *)cap, &(pattrib->pktlen));
9435 #endif /* CONFIG_RTW_80211K */
9436 
9437 	/* FILL WMM IE */
9438 	if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) {
9439 		uint ie_len = 0;
9440 		unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
9441 
9442 		for (pbuf = ie + _BEACON_IE_OFFSET_; ; pbuf += (ie_len + 2)) {
9443 			pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
9444 			if (pbuf && _rtw_memcmp(pbuf + 2, WMM_PARA_IE, 6)) {
9445 				_rtw_memcpy(pframe, pbuf, ie_len + 2);
9446 				pframe += (ie_len + 2);
9447 				pattrib->pktlen += (ie_len + 2);
9448 
9449 				break;
9450 			}
9451 
9452 			if ((pbuf == NULL) || (ie_len == 0))
9453 				break;
9454 		}
9455 
9456 	}
9457 
9458 
9459 	if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
9460 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
9461 
9462 	/* add WPS IE ie for wps 2.0 */
9463 	if (pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len > 0) {
9464 		_rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
9465 
9466 		pframe += pmlmepriv->wps_assoc_resp_ie_len;
9467 		pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
9468 	}
9469 
9470 
9471 	if ((psecuritypriv->auth_type == MLME_AUTHTYPE_SAE) &&
9472 		pmlmepriv->assoc_rsp && pmlmepriv->assoc_rsp_len > 0) {
9473 		_rtw_memcpy(pframe, pmlmepriv->assoc_rsp, pmlmepriv->assoc_rsp_len);
9474 		pframe += pmlmepriv->assoc_rsp_len;
9475 		pattrib->pktlen += pmlmepriv->assoc_rsp_len;
9476 	}
9477 
9478 #ifdef CONFIG_P2P
9479 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE)) {
9480 		u32 len;
9481 
9482 		if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {
9483 			len = 0;
9484 			if (pmlmepriv->p2p_assoc_resp_ie && pmlmepriv->p2p_assoc_resp_ie_len > 0) {
9485 				len = pmlmepriv->p2p_assoc_resp_ie_len;
9486 				_rtw_memcpy(pframe, pmlmepriv->p2p_assoc_resp_ie, len);
9487 			} else if (pmlmepriv->assoc_rsp && pmlmepriv->assoc_rsp_len > 0) {
9488 				len = pmlmepriv->assoc_rsp_len;
9489 				_rtw_memcpy(pframe, pmlmepriv->assoc_rsp, len);
9490 			}
9491 		} else
9492 			len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
9493 		pframe += len;
9494 		pattrib->pktlen += len;
9495 	}
9496 
9497 #ifdef CONFIG_WFD
9498 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
9499 		wfdielen = rtw_append_assoc_resp_wfd_ie(padapter, pframe);
9500 		pframe += wfdielen;
9501 		pattrib->pktlen += wfdielen;
9502 	}
9503 #endif
9504 
9505 #endif /* CONFIG_P2P */
9506 
9507 #ifdef CONFIG_RTW_MULTI_AP
9508 	if (padapter->multi_ap && (pstat->flags & WLAN_STA_MULTI_AP))
9509 		pframe = rtw_set_multi_ap_ie_ext(pframe, &pattrib->pktlen, padapter->multi_ap);
9510 #endif
9511 
9512 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
9513 	pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_ASSOCRESP_VENDOR_IE_BIT);
9514 #endif
9515 
9516 #ifdef CONFIG_RTL8812A
9517 	pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen );
9518 #endif/*CONFIG_RTL8812A*/
9519 
9520 
9521 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
9522 	if (padapter->tbtx_capability == _TRUE)
9523 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 8, REALTEK_TBTX_IE, &pattrib->pktlen);
9524 #endif
9525 
9526 	pattrib->last_txcmdsz = pattrib->pktlen;
9527 
9528 	dump_mgntframe(padapter, pmgntframe);
9529 
9530 #endif
9531 }
9532 
rtw_append_assoc_req_owe_ie(_adapter * adapter,u8 * pbuf)9533 static u32 rtw_append_assoc_req_owe_ie(_adapter *adapter, u8 *pbuf)
9534 {
9535 	struct security_priv *sec = &adapter->securitypriv;
9536 	u32 len = 0;
9537 
9538 	if (sec == NULL)
9539 		goto exit;
9540 
9541 	if (sec->owe_ie_len > 0) {
9542 		len = sec->owe_ie_len;
9543 		_rtw_memcpy(pbuf, sec->owe_ie, len);
9544 	}
9545 
9546 exit:
9547 	return len;
9548 }
9549 
9550 #ifdef CONFIG_ECSA
build_supported_op_class_ie(_adapter * padapter,u8 * pbuf,int * pktlen)9551 u8 *build_supported_op_class_ie(_adapter *padapter, u8 *pbuf, int *pktlen)
9552 {
9553 	u8 buf[32];
9554 	int ie_len = 0;
9555 
9556 	ie_len = get_supported_op_class(padapter, buf, sizeof(buf));
9557 	pbuf = rtw_set_ie(pbuf, EID_SupRegulatory , ie_len,
9558 			    (unsigned char *)buf, pktlen);
9559 	return pbuf;
9560 }
9561 #endif /* CONFIG_ECSA */
9562 
_issue_assocreq(_adapter * padapter,u8 is_reassoc)9563 void _issue_assocreq(_adapter *padapter, u8 is_reassoc)
9564 {
9565 	int ret = _FAIL;
9566 	struct xmit_frame				*pmgntframe;
9567 	struct pkt_attrib				*pattrib;
9568 	unsigned char					*pframe;
9569 	struct rtw_ieee80211_hdr			*pwlanhdr;
9570 	unsigned short				*fctrl;
9571 	unsigned short				val16;
9572 	unsigned int					i, j, index = 0;
9573 	unsigned char					bssrate[NumRates], sta_bssrate[NumRates];
9574 	PNDIS_802_11_VARIABLE_IEs	pIE;
9575 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
9576 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
9577 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
9578 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
9579 	int	bssrate_len = 0, sta_bssrate_len = 0;
9580 	u8	vs_ie_length = 0;
9581 #ifdef CONFIG_P2P
9582 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
9583 	u8					p2pie[255] = { 0x00 };
9584 	u16					p2pielen = 0;
9585 #ifdef CONFIG_WFD
9586 	u32					wfdielen = 0;
9587 #endif
9588 #endif /* CONFIG_P2P */
9589 
9590 #if CONFIG_DFS
9591 	u16	cap;
9592 #endif
9593 
9594 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9595 		goto exit;
9596 
9597 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9598 	if (pmgntframe == NULL)
9599 		goto exit;
9600 
9601 	/* update attribute */
9602 	pattrib = &pmgntframe->attrib;
9603 	update_mgntframe_attrib(padapter, pattrib);
9604 
9605 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9606 
9607 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9608 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9609 
9610 	fctrl = &(pwlanhdr->frame_ctl);
9611 	*(fctrl) = 0;
9612 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9613 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9614 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9615 
9616 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9617 	pmlmeext->mgnt_seq++;
9618 	if (is_reassoc == _TRUE)
9619 		set_frame_sub_type(pframe, WIFI_REASSOCREQ);
9620 	else
9621 		set_frame_sub_type(pframe, WIFI_ASSOCREQ);
9622 
9623 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9624 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9625 
9626 	/* caps */
9627 
9628 #if CONFIG_DFS
9629 	_rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
9630 	cap |= cap_SpecMgmt;
9631 #ifdef CONFIG_RTW_80211K
9632 	cap |= cap_RM;
9633 #endif
9634 	_rtw_memcpy(pframe, &cap, 2);
9635 #else
9636 	_rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
9637 #endif
9638 
9639 	pframe += 2;
9640 	pattrib->pktlen += 2;
9641 
9642 	/* listen interval */
9643 	/* todo: listen interval for power saving */
9644 	val16 = cpu_to_le16(3);
9645 	_rtw_memcpy(pframe , (unsigned char *)&val16, 2);
9646 	pframe += 2;
9647 	pattrib->pktlen += 2;
9648 
9649 	/*Construct Current AP Field for Reassoc-Req only*/
9650 	if (is_reassoc == _TRUE) {
9651 		_rtw_memcpy(pframe, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9652 		pframe += ETH_ALEN;
9653 		pattrib->pktlen += ETH_ALEN;
9654 	}
9655 
9656 	/* SSID */
9657 	pframe = rtw_set_ie(pframe, _SSID_IE_,  pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
9658 
9659 #if CONFIG_IEEE80211_BAND_5GHZ && CONFIG_DFS
9660 	/* Dot H */
9661 	if (pmlmeext->cur_channel > 14) {
9662 		struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
9663 		u8 pow_cap_ele[2] = { 0x00 };
9664 		u8 sup_ch[30 * 2] = {0x00 }, sup_ch_idx = 0, idx_5g = 2;	/* For supported channel */
9665 
9666 		pow_cap_ele[0] = 13;	/* Minimum transmit power capability */
9667 		pow_cap_ele[1] = 21;	/* Maximum transmit power capability */
9668 		pframe = rtw_set_ie(pframe, EID_PowerCap, 2, pow_cap_ele, &(pattrib->pktlen));
9669 
9670 		/* supported channels */
9671 		while (sup_ch_idx < rfctl->max_chan_nums && rfctl->channel_set[sup_ch_idx].ChannelNum != 0) {
9672 			if (rfctl->channel_set[sup_ch_idx].ChannelNum <= 14) {
9673 				/* TODO: fix 2.4G supported channel when channel doesn't start from 1 and continuous */
9674 				sup_ch[0] = 1;	/* First channel number */
9675 				sup_ch[1] = rfctl->channel_set[sup_ch_idx].ChannelNum;	/* Number of channel */
9676 			} else {
9677 				sup_ch[idx_5g++] = rfctl->channel_set[sup_ch_idx].ChannelNum;
9678 				sup_ch[idx_5g++] = 1;
9679 			}
9680 			sup_ch_idx++;
9681 		}
9682 		pframe = rtw_set_ie(pframe, EID_SupportedChannels, idx_5g, sup_ch, &(pattrib->pktlen));
9683 	}
9684 #endif /* CONFIG_IEEE80211_BAND_5GHZ && CONFIG_DFS */
9685 
9686 	/* supported rate & extended supported rate */
9687 
9688 #if 1	/* Check if the AP's supported rates are also supported by STA. */
9689 	get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
9690 	/* RTW_INFO("sta_bssrate_len=%d\n", sta_bssrate_len); */
9691 
9692 	if (pmlmeext->cur_channel == 14) /* for JAPAN, channel 14 can only uses B Mode(CCK) */
9693 		sta_bssrate_len = 4;
9694 
9695 
9696 	/* for (i = 0; i < sta_bssrate_len; i++) { */
9697 	/*	RTW_INFO("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
9698 	/* } */
9699 
9700 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
9701 		if (pmlmeinfo->network.SupportedRates[i] == 0)
9702 			break;
9703 		RTW_INFO("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
9704 	}
9705 
9706 
9707 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
9708 		if (pmlmeinfo->network.SupportedRates[i] == 0)
9709 			break;
9710 
9711 
9712 		/* Check if the AP's supported rates are also supported by STA. */
9713 		for (j = 0; j < sta_bssrate_len; j++) {
9714 			/* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
9715 			if ((pmlmeinfo->network.SupportedRates[i] | IEEE80211_BASIC_RATE_MASK)
9716 			    == (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
9717 				/* RTW_INFO("match i = %d, j=%d\n", i, j); */
9718 				break;
9719 			} else {
9720 				/* RTW_INFO("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)); */
9721 			}
9722 		}
9723 
9724 		if (j == sta_bssrate_len) {
9725 			/* the rate is not supported by STA */
9726 			RTW_INFO("%s(): the rate[%d]=%02X is not supported by STA!\n", __FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
9727 		} else {
9728 			/* the rate is supported by STA */
9729 			bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
9730 		}
9731 	}
9732 
9733 	bssrate_len = index;
9734 	RTW_INFO("bssrate_len = %d\n", bssrate_len);
9735 
9736 #else	/* Check if the AP's supported rates are also supported by STA. */
9737 #if 0
9738 	get_rate_set(padapter, bssrate, &bssrate_len);
9739 #else
9740 	for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
9741 		if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0)
9742 			break;
9743 
9744 		if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
9745 			break;
9746 
9747 		bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
9748 	}
9749 #endif
9750 #endif /* Check if the AP's supported rates are also supported by STA. */
9751 
9752 	if ((bssrate_len == 0) && (pmlmeinfo->network.SupportedRates[0] != 0)) {
9753 		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
9754 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
9755 		goto exit; /* don't connect to AP if no joint supported rate */
9756 	}
9757 
9758 
9759 	if (bssrate_len > 8) {
9760 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
9761 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
9762 	} else if (bssrate_len > 0)
9763 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
9764 	else
9765 		RTW_INFO("%s: Connect to AP without 11b and 11g data rate!\n", __FUNCTION__);
9766 
9767 #ifdef CONFIG_ECSA
9768 	pframe = build_supported_op_class_ie(padapter, pframe, &pattrib->pktlen);
9769 #endif /* CONFIG_ECSA */
9770 
9771 #ifdef CONFIG_RTW_MBO
9772 	rtw_mbo_build_assoc_req_ies(padapter, &pframe, pattrib);
9773 #endif
9774 #ifdef CONFIG_RTW_80211R
9775 	rtw_ft_build_assoc_req_ies(padapter, is_reassoc, pattrib, &pframe);
9776 #endif
9777 #ifdef CONFIG_RTW_80211K
9778 	pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, 5,
9779 			(u8 *)padapter->rmpriv.rm_en_cap_def,
9780 			&(pattrib->pktlen));
9781 #endif /* CONFIG_RTW_80211K */
9782 
9783 	/* vendor specific IE, such as WPA, WMM, WPS */
9784 	for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) {
9785 		pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
9786 
9787 		switch (pIE->ElementID) {
9788 		case _VENDOR_SPECIFIC_IE_:
9789 			if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
9790 			    (_rtw_memcmp(pIE->data, WMM_OUI, 4)) ||
9791 			    (_rtw_memcmp(pIE->data, WPS_OUI, 4))) {
9792 				vs_ie_length = pIE->Length;
9793 				if ((!padapter->registrypriv.wifi_spec) && (_rtw_memcmp(pIE->data, WPS_OUI, 4))) {
9794 					/* Commented by Kurt 20110629 */
9795 					/* In some older APs, WPS handshake */
9796 					/* would be fail if we append vender extensions informations to AP */
9797 
9798 					vs_ie_length = 14;
9799 				}
9800 
9801 				pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen));
9802 			}
9803 			break;
9804 
9805 		case EID_WPA2:
9806 #ifdef CONFIG_RTW_80211R
9807 			if ((is_reassoc) && (rtw_ft_roam(padapter))) {
9808 				rtw_ft_update_rsnie(padapter, _TRUE, pattrib, &pframe);
9809 			} else
9810 #endif
9811 			{
9812 #ifdef CONFIG_IOCTL_CFG80211
9813 				if (rtw_sec_chk_auth_alg(padapter, WLAN_AUTH_OPEN) &&
9814 					rtw_sec_chk_auth_type(padapter, MLME_AUTHTYPE_SAE)) {
9815 					s32 entry = rtw_cached_pmkid(padapter, pmlmepriv->assoc_bssid);
9816 
9817 					rtw_rsn_sync_pmkid(padapter, (u8 *)pIE, (pIE->Length + 2), entry);
9818 				}
9819 #endif /* CONFIG_IOCTL_CFG80211 */
9820 
9821 				pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen));
9822 				/* tmp: update rsn's spp related opt. */
9823 				/*rtw_set_spp_amsdu_mode(padapter->registrypriv.amsdu_mode, pframe - (pIE->Length + 2), pIE->Length +2);*/
9824 			}
9825 			break;
9826 			case WLAN_EID_RSNX:
9827 				pframe = rtw_set_ie(pframe, WLAN_EID_RSNX, pIE->Length,
9828 					pIE->data, &(pattrib->pktlen));
9829 			break;
9830 #ifdef CONFIG_80211N_HT
9831 		case EID_HTCapability:
9832 			if (padapter->mlmepriv.htpriv.ht_option == _TRUE) {
9833 				if (!(is_ap_in_tkip(padapter))) {
9834 					_rtw_memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
9835 
9836 					pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
9837 
9838 					pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
9839 				}
9840 			}
9841 			break;
9842 #endif /* CONFIG_80211N_HT */
9843 
9844 		case WLAN_EID_EXT_CAP:
9845 			pframe = rtw_set_ie(pframe, WLAN_EID_EXT_CAP, pIE->Length, pIE->data, &(pattrib->pktlen));
9846 			break;
9847 
9848 #ifdef CONFIG_80211AC_VHT
9849 		case EID_VHTCapability:
9850 			if (padapter->mlmepriv.vhtpriv.vht_option == _TRUE)
9851 				pframe = rtw_set_ie(pframe, EID_VHTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
9852 			break;
9853 
9854 		case EID_OpModeNotification:
9855 			if (padapter->mlmepriv.vhtpriv.vht_option == _TRUE)
9856 				pframe = rtw_set_ie(pframe, EID_OpModeNotification, pIE->Length, pIE->data, &(pattrib->pktlen));
9857 			break;
9858 #endif /* CONFIG_80211AC_VHT */
9859 		default:
9860 			break;
9861 		}
9862 
9863 		i += (pIE->Length + 2);
9864 	}
9865 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
9866 	if (padapter->tbtx_capability == _TRUE)
9867 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 8 , REALTEK_TBTX_IE, &(pattrib->pktlen));
9868 #endif
9869 
9870 	if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
9871 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
9872 
9873 
9874 #ifdef CONFIG_WAPI_SUPPORT
9875 	rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
9876 #endif
9877 
9878 
9879 #ifdef CONFIG_P2P
9880 
9881 #ifdef CONFIG_IOCTL_CFG80211
9882 	if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
9883 		if (pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len > 0) {
9884 			_rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
9885 			pframe += pmlmepriv->p2p_assoc_req_ie_len;
9886 			pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
9887 		}
9888 	} else
9889 #endif /* CONFIG_IOCTL_CFG80211 */
9890 	{
9891 		if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
9892 			/*	Should add the P2P IE in the association request frame.	 */
9893 			/*	P2P OUI */
9894 
9895 			p2pielen = 0;
9896 			p2pie[p2pielen++] = 0x50;
9897 			p2pie[p2pielen++] = 0x6F;
9898 			p2pie[p2pielen++] = 0x9A;
9899 			p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
9900 
9901 			/*	Commented by Albert 20101109 */
9902 			/*	According to the P2P Specification, the association request frame should contain 3 P2P attributes */
9903 			/*	1. P2P Capability */
9904 			/*	2. Extended Listen Timing */
9905 			/*	3. Device Info */
9906 			/*	Commented by Albert 20110516 */
9907 			/*	4. P2P Interface */
9908 
9909 			/*	P2P Capability */
9910 			/*	Type: */
9911 			p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
9912 
9913 			/*	Length: */
9914 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
9915 			p2pielen += 2;
9916 
9917 			/*	Value: */
9918 			/*	Device Capability Bitmap, 1 byte */
9919 			p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
9920 
9921 			/*	Group Capability Bitmap, 1 byte */
9922 			if (pwdinfo->persistent_supported)
9923 				p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
9924 			else
9925 				p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
9926 
9927 			/*	Extended Listen Timing */
9928 			/*	Type: */
9929 			p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
9930 
9931 			/*	Length: */
9932 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
9933 			p2pielen += 2;
9934 
9935 			/*	Value: */
9936 			/*	Availability Period */
9937 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
9938 			p2pielen += 2;
9939 
9940 			/*	Availability Interval */
9941 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
9942 			p2pielen += 2;
9943 
9944 			/*	Device Info */
9945 			/*	Type: */
9946 			p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
9947 
9948 			/*	Length: */
9949 			/*	21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)  */
9950 			/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
9951 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
9952 			p2pielen += 2;
9953 
9954 			/*	Value: */
9955 			/*	P2P Device Address */
9956 			_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
9957 			p2pielen += ETH_ALEN;
9958 
9959 			/*	Config Method */
9960 			/*	This field should be big endian. Noted by P2P specification. */
9961 			if ((pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN) ||
9962 			    (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN))
9963 				*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
9964 			else
9965 				*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC);
9966 
9967 			p2pielen += 2;
9968 
9969 			/*	Primary Device Type */
9970 			/*	Category ID */
9971 			*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
9972 			p2pielen += 2;
9973 
9974 			/*	OUI */
9975 			*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
9976 			p2pielen += 4;
9977 
9978 			/*	Sub Category ID */
9979 			*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
9980 			p2pielen += 2;
9981 
9982 			/*	Number of Secondary Device Types */
9983 			p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
9984 
9985 			/*	Device Name */
9986 			/*	Type: */
9987 			*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
9988 			p2pielen += 2;
9989 
9990 			/*	Length: */
9991 			*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
9992 			p2pielen += 2;
9993 
9994 			/*	Value: */
9995 			_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
9996 			p2pielen += pwdinfo->device_name_len;
9997 
9998 			/*	P2P Interface */
9999 			/*	Type: */
10000 			p2pie[p2pielen++] = P2P_ATTR_INTERFACE;
10001 
10002 			/*	Length: */
10003 			*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x000D);
10004 			p2pielen += 2;
10005 
10006 			/*	Value: */
10007 			_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);	/*	P2P Device Address */
10008 			p2pielen += ETH_ALEN;
10009 
10010 			p2pie[p2pielen++] = 1;	/*	P2P Interface Address Count */
10011 
10012 			_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);	/*	P2P Interface Address List */
10013 			p2pielen += ETH_ALEN;
10014 
10015 			pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
10016 		}
10017 	}
10018 
10019 #ifdef CONFIG_WFD
10020 	wfdielen = rtw_append_assoc_req_wfd_ie(padapter, pframe);
10021 	pframe += wfdielen;
10022 	pattrib->pktlen += wfdielen;
10023 #endif
10024 #endif /* CONFIG_P2P */
10025 
10026 #ifdef CONFIG_RTW_MULTI_AP
10027 	if (padapter->multi_ap)
10028 		pframe = rtw_set_multi_ap_ie_ext(pframe, &pattrib->pktlen, padapter->multi_ap);
10029 #endif
10030 
10031 	/* OWE */
10032 	{
10033 	u32 owe_ie_len;
10034 
10035 	owe_ie_len = rtw_append_assoc_req_owe_ie(padapter, pframe);
10036 	pframe += owe_ie_len;
10037 	pattrib->pktlen += owe_ie_len;
10038 	}
10039 
10040 #ifdef CONFIG_RTW_REPEATER_SON
10041 	rtw_rson_append_ie(padapter, pframe, &pattrib->pktlen);
10042 #endif
10043 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
10044 	pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_ASSOCREQ_VENDOR_IE_BIT);
10045 #endif
10046 
10047 #ifdef CONFIG_RTL8812A
10048 	pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen );
10049 #endif/*CONFIG_RTL8812A*/
10050 
10051 	pattrib->last_txcmdsz = pattrib->pktlen;
10052 	dump_mgntframe(padapter, pmgntframe);
10053 
10054 	ret = _SUCCESS;
10055 
10056 exit:
10057 	if (ret == _SUCCESS) {
10058 		rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
10059 	#ifdef CONFIG_RTW_WNM
10060 		if (is_reassoc == _TRUE)
10061 			rtw_wnm_update_reassoc_req_ie(padapter);
10062 	#endif
10063 	} else
10064 		rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
10065 
10066 	return;
10067 }
10068 
issue_assocreq(_adapter * padapter)10069 void issue_assocreq(_adapter *padapter)
10070 {
10071 	_issue_assocreq(padapter, _FALSE);
10072 }
10073 
issue_reassocreq(_adapter * padapter)10074 void issue_reassocreq(_adapter *padapter)
10075 {
10076 	_issue_assocreq(padapter, _TRUE);
10077 }
10078 
10079 /* when wait_ack is ture, this function shoule be called at process context */
_issue_nulldata(_adapter * padapter,unsigned char * da,unsigned int power_mode,int wait_ack)10080 static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
10081 {
10082 	int ret = _FAIL;
10083 	struct xmit_frame			*pmgntframe;
10084 	struct pkt_attrib			*pattrib;
10085 	unsigned char					*pframe;
10086 	struct rtw_ieee80211_hdr	*pwlanhdr;
10087 	unsigned short				*fctrl;
10088 	struct xmit_priv	*pxmitpriv;
10089 	struct mlme_ext_priv	*pmlmeext;
10090 	struct mlme_ext_info	*pmlmeinfo;
10091 	u8 a4_shift;
10092 
10093 	/* RTW_INFO("%s:%d\n", __FUNCTION__, power_mode); */
10094 
10095 	if (!padapter)
10096 		goto exit;
10097 
10098 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10099 		goto exit;
10100 
10101 	pxmitpriv = &(padapter->xmitpriv);
10102 	pmlmeext = &(padapter->mlmeextpriv);
10103 	pmlmeinfo = &(pmlmeext->mlmext_info);
10104 
10105 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10106 	if (pmgntframe == NULL)
10107 		goto exit;
10108 
10109 	/* update attribute */
10110 	pattrib = &pmgntframe->attrib;
10111 	update_mgntframe_attrib(padapter, pattrib);
10112 	pattrib->retry_ctrl = _FALSE;
10113 
10114 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10115 
10116 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10117 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10118 
10119 	fctrl = &(pwlanhdr->frame_ctl);
10120 	*(fctrl) = 0;
10121 
10122 	if (MLME_IS_AP(padapter))
10123 		SetFrDs(fctrl);
10124 	else if (MLME_IS_STA(padapter))
10125 		SetToDs(fctrl);
10126 	else if (MLME_IS_MESH(padapter)) {
10127 		SetToDs(fctrl);
10128 		SetFrDs(fctrl);
10129 	}
10130 
10131 	if (power_mode)
10132 		SetPwrMgt(fctrl);
10133 
10134 	if (get_tofr_ds(fctrl) == 3) {
10135 		_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
10136 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10137 		_rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
10138 		_rtw_memcpy(pwlanhdr->addr4, adapter_mac_addr(padapter), ETH_ALEN);
10139 		a4_shift = ETH_ALEN;
10140 		pattrib->hdrlen += ETH_ALEN;
10141 	} else {
10142 		_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
10143 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10144 		_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10145 		a4_shift = 0;
10146 	}
10147 
10148 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10149 	pmlmeext->mgnt_seq++;
10150 	set_frame_sub_type(pframe, WIFI_DATA_NULL);
10151 
10152 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr) + a4_shift;
10153 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr) + a4_shift;
10154 
10155 	pattrib->last_txcmdsz = pattrib->pktlen;
10156 
10157 	if (wait_ack)
10158 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10159 	else {
10160 		dump_mgntframe(padapter, pmgntframe);
10161 		ret = _SUCCESS;
10162 	}
10163 
10164 exit:
10165 	return ret;
10166 }
10167 
10168 /*
10169  * When wait_ms > 0, this function should be called at process context
10170  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10171  * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10172  * try_cnt means the maximal TX count to try
10173  * da == NULL for station mode
10174  */
issue_nulldata(_adapter * padapter,unsigned char * da,unsigned int power_mode,int try_cnt,int wait_ms)10175 int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
10176 {
10177 	int ret = _FAIL;
10178 	int i = 0;
10179 	systime start = rtw_get_current_time();
10180 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
10181 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10182 
10183 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10184 		goto exit;
10185 
10186 	/* da == NULL, assum it's null data for sta to ap */
10187 	if (da == NULL)
10188 		da = get_my_bssid(&(pmlmeinfo->network));
10189 
10190 	do {
10191 		ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0 ? _TRUE : _FALSE);
10192 
10193 		i++;
10194 
10195 		if (RTW_CANNOT_RUN(padapter))
10196 			break;
10197 
10198 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10199 			rtw_msleep_os(wait_ms);
10200 
10201 	} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10202 
10203 	if (ret != _FAIL) {
10204 		ret = _SUCCESS;
10205 #ifndef DBG_XMIT_ACK
10206 		goto exit;
10207 #endif
10208 	}
10209 
10210 	if (try_cnt && wait_ms) {
10211 		if (da)
10212 			RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
10213 				FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
10214 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10215 		else
10216 			RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
10217 				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
10218 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10219 	}
10220 exit:
10221 	return ret;
10222 }
10223 
10224 /* when wait_ack is ture, this function shoule be called at process context */
_issue_qos_nulldata(_adapter * padapter,unsigned char * da,u16 tid,u8 ps,int wait_ack)10225 static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, u8 ps, int wait_ack)
10226 {
10227 	int ret = _FAIL;
10228 	struct xmit_frame			*pmgntframe;
10229 	struct pkt_attrib			*pattrib;
10230 	unsigned char					*pframe;
10231 	struct rtw_ieee80211_hdr	*pwlanhdr;
10232 	unsigned short				*fctrl, *qc;
10233 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
10234 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
10235 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10236 	u8 a4_shift;
10237 
10238 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10239 		goto exit;
10240 
10241 	/* RTW_INFO("%s\n", __FUNCTION__); */
10242 
10243 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10244 	if (pmgntframe == NULL)
10245 		goto exit;
10246 
10247 	/* update attribute */
10248 	pattrib = &pmgntframe->attrib;
10249 	update_mgntframe_attrib(padapter, pattrib);
10250 
10251 	pattrib->hdrlen += 2;
10252 	pattrib->qos_en = _TRUE;
10253 	pattrib->eosp = 1;
10254 	pattrib->ack_policy = 0;
10255 	pattrib->mdata = 0;
10256 
10257 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10258 
10259 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10260 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10261 
10262 	fctrl = &(pwlanhdr->frame_ctl);
10263 	*(fctrl) = 0;
10264 
10265 	if (MLME_IS_AP(padapter))
10266 		SetFrDs(fctrl);
10267 	else if (MLME_IS_STA(padapter))
10268 		SetToDs(fctrl);
10269 	else if (MLME_IS_MESH(padapter)) {
10270 		SetToDs(fctrl);
10271 		SetFrDs(fctrl);
10272 	}
10273 
10274 	if (ps)
10275 		SetPwrMgt(fctrl);
10276 
10277 	if (pattrib->mdata)
10278 		SetMData(fctrl);
10279 
10280 	if (get_tofr_ds(fctrl) == 3) {
10281 		_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
10282 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10283 		_rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
10284 		_rtw_memcpy(pwlanhdr->addr4, adapter_mac_addr(padapter), ETH_ALEN);
10285 		a4_shift = ETH_ALEN;
10286 		pattrib->hdrlen += ETH_ALEN;
10287 	} else {
10288 		_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
10289 		_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10290 		_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10291 		a4_shift = 0;
10292 	}
10293 
10294 	qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
10295 
10296 	SetPriority(qc, tid);
10297 
10298 	SetEOSP(qc, pattrib->eosp);
10299 
10300 	SetAckpolicy(qc, pattrib->ack_policy);
10301 
10302 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10303 	pmlmeext->mgnt_seq++;
10304 	set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
10305 
10306 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos) + a4_shift;
10307 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos) + a4_shift;
10308 
10309 	pattrib->last_txcmdsz = pattrib->pktlen;
10310 
10311 	if (wait_ack)
10312 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10313 	else {
10314 		dump_mgntframe(padapter, pmgntframe);
10315 		ret = _SUCCESS;
10316 	}
10317 
10318 exit:
10319 	return ret;
10320 }
10321 
10322 /*
10323  * when wait_ms >0 , this function should be called at process context
10324  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10325  * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10326  * try_cnt means the maximal TX count to try
10327  * da == NULL for station mode
10328  */
issue_qos_nulldata(_adapter * padapter,unsigned char * da,u16 tid,u8 ps,int try_cnt,int wait_ms)10329 int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, u8 ps, int try_cnt, int wait_ms)
10330 {
10331 	int ret = _FAIL;
10332 	int i = 0;
10333 	systime start = rtw_get_current_time();
10334 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
10335 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10336 
10337 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10338 		goto exit;
10339 
10340 	/* da == NULL, assum it's null data for sta to ap*/
10341 	if (da == NULL)
10342 		da = get_my_bssid(&(pmlmeinfo->network));
10343 
10344 	do {
10345 		ret = _issue_qos_nulldata(padapter, da, tid, ps, wait_ms > 0 ? _TRUE : _FALSE);
10346 
10347 		i++;
10348 
10349 		if (RTW_CANNOT_RUN(padapter))
10350 			break;
10351 
10352 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10353 			rtw_msleep_os(wait_ms);
10354 
10355 	} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10356 
10357 	if (ret != _FAIL) {
10358 		ret = _SUCCESS;
10359 #ifndef DBG_XMIT_ACK
10360 		goto exit;
10361 #endif
10362 	}
10363 
10364 	if (try_cnt && wait_ms) {
10365 		if (da)
10366 			RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
10367 				FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
10368 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10369 		else
10370 			RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
10371 				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
10372 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10373 	}
10374 exit:
10375 	return ret;
10376 }
10377 
_issue_deauth(_adapter * padapter,unsigned char * da,unsigned short reason,u8 wait_ack,u8 key_type)10378 static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack, u8 key_type)
10379 {
10380 	struct xmit_frame			*pmgntframe;
10381 	struct pkt_attrib			*pattrib;
10382 	unsigned char					*pframe;
10383 	struct rtw_ieee80211_hdr	*pwlanhdr;
10384 	unsigned short				*fctrl;
10385 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
10386 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
10387 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10388 	int ret = _FAIL;
10389 #ifdef CONFIG_P2P
10390 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
10391 #endif /* CONFIG_P2P	 */
10392 
10393 	/* RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
10394 
10395 #ifdef CONFIG_P2P
10396 	if (!(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) && (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
10397 		_cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
10398 		_set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
10399 	}
10400 #endif /* CONFIG_P2P */
10401 
10402 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10403 		goto exit;
10404 
10405 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10406 	if (pmgntframe == NULL)
10407 		goto exit;
10408 
10409 	/* update attribute */
10410 	pattrib = &pmgntframe->attrib;
10411 	update_mgntframe_attrib(padapter, pattrib);
10412 	pattrib->retry_ctrl = _FALSE;
10413 	pattrib->key_type = key_type;
10414 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10415 
10416 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10417 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10418 
10419 	fctrl = &(pwlanhdr->frame_ctl);
10420 	*(fctrl) = 0;
10421 
10422 	_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
10423 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10424 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10425 
10426 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10427 	pmlmeext->mgnt_seq++;
10428 	set_frame_sub_type(pframe, WIFI_DEAUTH);
10429 
10430 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10431 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10432 
10433 	reason = cpu_to_le16(reason);
10434 	pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
10435 
10436 	pattrib->last_txcmdsz = pattrib->pktlen;
10437 
10438 
10439 	if (wait_ack)
10440 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10441 	else {
10442 		dump_mgntframe(padapter, pmgntframe);
10443 		ret = _SUCCESS;
10444 	}
10445 
10446 exit:
10447 	return ret;
10448 }
10449 
issue_deauth(_adapter * padapter,unsigned char * da,unsigned short reason)10450 int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
10451 {
10452 	RTW_INFO("%s reason(%u) to "MAC_FMT"\n", __func__, reason, MAC_ARG(da));
10453 	return _issue_deauth(padapter, da, reason, _FALSE, IEEE80211W_RIGHT_KEY);
10454 }
10455 
10456 #ifdef CONFIG_IEEE80211W
issue_deauth_11w(_adapter * padapter,unsigned char * da,unsigned short reason,u8 key_type)10457 int issue_deauth_11w(_adapter *padapter, unsigned char *da, unsigned short reason, u8 key_type)
10458 {
10459 	RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
10460 	return _issue_deauth(padapter, da, reason, _FALSE, key_type);
10461 }
10462 #endif /* CONFIG_IEEE80211W */
10463 
10464 /*
10465  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10466  * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10467  * try_cnt means the maximal TX count to try
10468  */
issue_deauth_ex(_adapter * padapter,u8 * da,unsigned short reason,int try_cnt,int wait_ms)10469 int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
10470 		    int wait_ms)
10471 {
10472 	int ret = _FAIL;
10473 	int i = 0;
10474 	systime start = rtw_get_current_time();
10475 
10476 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10477 		goto exit;
10478 
10479 	do {
10480 		ret = _issue_deauth(padapter, da, reason, wait_ms > 0 ? _TRUE : _FALSE, IEEE80211W_RIGHT_KEY);
10481 
10482 		i++;
10483 
10484 		if (RTW_CANNOT_RUN(padapter))
10485 			break;
10486 
10487 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10488 			rtw_msleep_os(wait_ms);
10489 
10490 	} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10491 
10492 	if (ret != _FAIL) {
10493 		ret = _SUCCESS;
10494 #ifndef DBG_XMIT_ACK
10495 		goto exit;
10496 #endif
10497 	}
10498 
10499 	if (try_cnt && wait_ms) {
10500 		if (da)
10501 			RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
10502 				FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
10503 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10504 		else
10505 			RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
10506 				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
10507 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10508 	}
10509 exit:
10510 	return ret;
10511 }
10512 
issue_action_spct_ch_switch(_adapter * padapter,u8 * ra,u8 new_ch,u8 ch_offset)10513 void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
10514 {
10515 	struct xmit_frame *pmgntframe;
10516 	struct pkt_attrib *pattrib;
10517 	unsigned char				*pframe;
10518 	struct rtw_ieee80211_hdr	*pwlanhdr;
10519 	unsigned short			*fctrl;
10520 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
10521 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
10522 
10523 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10524 		return;
10525 
10526 	RTW_INFO(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
10527 		FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
10528 
10529 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10530 	if (pmgntframe == NULL)
10531 		return;
10532 
10533 	/* update attribute */
10534 	pattrib = &pmgntframe->attrib;
10535 	update_mgntframe_attrib(padapter, pattrib);
10536 
10537 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10538 
10539 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10540 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10541 
10542 	fctrl = &(pwlanhdr->frame_ctl);
10543 	*(fctrl) = 0;
10544 
10545 	_rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
10546 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
10547 	_rtw_memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
10548 
10549 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10550 	pmlmeext->mgnt_seq++;
10551 	set_frame_sub_type(pframe, WIFI_ACTION);
10552 
10553 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10554 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10555 
10556 	/* category, action */
10557 	{
10558 		u8 category, action;
10559 		category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
10560 		action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
10561 
10562 		pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10563 		pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10564 	}
10565 
10566 	pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
10567 	pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
10568 			hal_ch_offset_to_secondary_ch_offset(ch_offset));
10569 
10570 	pattrib->last_txcmdsz = pattrib->pktlen;
10571 
10572 	dump_mgntframe(padapter, pmgntframe);
10573 
10574 }
10575 
10576 #ifdef CONFIG_IEEE80211W
issue_action_SA_Query(_adapter * padapter,unsigned char * raddr,unsigned char action,unsigned short tid,u8 key_type)10577 void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid, u8 key_type)
10578 {
10579 	u8	category = RTW_WLAN_CATEGORY_SA_QUERY;
10580 	u16	reason_code;
10581 	struct xmit_frame		*pmgntframe;
10582 	struct pkt_attrib		*pattrib;
10583 	u8					*pframe;
10584 	struct rtw_ieee80211_hdr	*pwlanhdr;
10585 	u16					*fctrl;
10586 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
10587 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
10588 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10589 	struct sta_info		*psta;
10590 	struct sta_priv		*pstapriv = &padapter->stapriv;
10591 	struct registry_priv		*pregpriv = &padapter->registrypriv;
10592 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10593 
10594 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10595 		return;
10596 
10597 	RTW_INFO("%s, %04x\n", __FUNCTION__, tid);
10598 
10599 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10600 	if (pmgntframe == NULL) {
10601 		RTW_INFO("%s: alloc_mgtxmitframe fail\n", __FUNCTION__);
10602 		return;
10603 	}
10604 
10605 	/* update attribute */
10606 	pattrib = &pmgntframe->attrib;
10607 	update_mgntframe_attrib(padapter, pattrib);
10608 	pattrib->key_type = key_type;
10609 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10610 
10611 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10612 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10613 
10614 	fctrl = &(pwlanhdr->frame_ctl);
10615 	*(fctrl) = 0;
10616 
10617 	if (raddr)
10618 		_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
10619 	else
10620 		_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10621 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10622 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10623 
10624 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10625 	pmlmeext->mgnt_seq++;
10626 	set_frame_sub_type(pframe, WIFI_ACTION);
10627 
10628 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10629 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10630 
10631 	pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
10632 	pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
10633 
10634 	switch (action) {
10635 	case 0: /* SA Query req */
10636 		pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
10637 		pmlmeext->sa_query_seq++;
10638 		/* send sa query request to AP, AP should reply sa query response in 1 second */
10639 		if (pattrib->key_type == IEEE80211W_RIGHT_KEY) {
10640 			psta = rtw_get_stainfo(pstapriv, pwlanhdr->addr1);
10641 			if (psta != NULL) {
10642 				/* RTW_INFO("%s, %d, set dot11w_expire_timer\n", __func__, __LINE__); */
10643 				_set_timer(&psta->dot11w_expire_timer, 1000);
10644 			}
10645 		}
10646 		break;
10647 
10648 	case 1: /* SA Query rsp */
10649 		tid = cpu_to_le16(tid);
10650 		/* RTW_INFO("rtw_set_fixed_ie, %04x\n", tid); */
10651 		pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen);
10652 		break;
10653 	default:
10654 		break;
10655 	}
10656 
10657 	pattrib->last_txcmdsz = pattrib->pktlen;
10658 
10659 	dump_mgntframe(padapter, pmgntframe);
10660 }
10661 #endif /* CONFIG_IEEE80211W */
10662 
10663 /**
10664  * issue_action_ba - internal function to TX Block Ack action frame
10665  * @padapter: the adapter to TX
10666  * @raddr: receiver address
10667  * @action: Block Ack Action
10668  * @tid: tid
10669  * @size: the announced AMPDU buffer size. used by ADDBA_RESP
10670  * @status: status/reason code. used by ADDBA_RESP, DELBA
10671  * @initiator: if we are the initiator of AMPDU association. used by DELBA
10672  * @wait_ack: used xmit ack
10673  *
10674  * Returns:
10675  * _SUCCESS: No xmit ack is used or acked
10676  * _FAIL: not acked when using xmit ack
10677  */
issue_action_ba(_adapter * padapter,unsigned char * raddr,unsigned char action,u8 tid,u8 size,u16 status,u8 initiator,int wait_ack)10678 static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned char action
10679 		   , u8 tid, u8 size, u16 status, u8 initiator, int wait_ack)
10680 {
10681 	int ret = _FAIL;
10682 	u8	category = RTW_WLAN_CATEGORY_BACK;
10683 	u16	start_seq;
10684 	u16	BA_para_set;
10685 	u16	BA_timeout_value;
10686 	u16	BA_starting_seqctrl = 0;
10687 	struct xmit_frame		*pmgntframe;
10688 	struct pkt_attrib		*pattrib;
10689 	u8					*pframe;
10690 	struct rtw_ieee80211_hdr	*pwlanhdr;
10691 	u16					*fctrl;
10692 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
10693 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
10694 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
10695 	struct sta_info		*psta;
10696 	struct sta_priv		*pstapriv = &padapter->stapriv;
10697 	struct registry_priv		*pregpriv = &padapter->registrypriv;
10698 
10699 #ifdef CONFIG_80211N_HT
10700 
10701 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10702 		goto exit;
10703 
10704 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10705 	if (pmgntframe == NULL)
10706 		goto exit;
10707 
10708 	/* update attribute */
10709 	pattrib = &pmgntframe->attrib;
10710 	update_mgntframe_attrib(padapter, pattrib);
10711 
10712 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10713 
10714 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10715 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10716 
10717 	fctrl = &(pwlanhdr->frame_ctl);
10718 	*(fctrl) = 0;
10719 
10720 	/* _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */
10721 	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
10722 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10723 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10724 
10725 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10726 	pmlmeext->mgnt_seq++;
10727 	set_frame_sub_type(pframe, WIFI_ACTION);
10728 
10729 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10730 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10731 
10732 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10733 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10734 
10735 	if (category == 3) {
10736 		switch (action) {
10737 		case RTW_WLAN_ACTION_ADDBA_REQ:
10738 			do {
10739 				pmlmeinfo->dialogToken++;
10740 			} while (pmlmeinfo->dialogToken == 0);
10741 			pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
10742 
10743 #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
10744 			BA_para_set = (0x0802 | ((tid & 0xf) << 2)); /* immediate ack & 16 buffer size */
10745 #else
10746 			BA_para_set = (0x1002 | ((tid & 0xf) << 2)); /* immediate ack & 64 buffer size */
10747 #endif
10748 
10749 #ifdef CONFIG_TX_AMSDU
10750 			if (padapter->tx_amsdu >= 1) /* TX AMSDU  enabled */
10751 				BA_para_set |= BIT(0);
10752 			else /* TX AMSDU disabled */
10753 				BA_para_set &= ~BIT(0);
10754 #endif
10755 			psta = rtw_get_stainfo(pstapriv, raddr);
10756 			if (psta != NULL) {
10757 				if (psta->flags & WLAN_STA_AMSDU_DISABLE)
10758 					BA_para_set &= ~BIT(0);
10759 			}
10760 
10761 			BA_para_set = cpu_to_le16(BA_para_set);
10762 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
10763 
10764 			/* BA_timeout_value = 0xffff; */ /* max: 65535 TUs(~ 65 ms) */
10765 			BA_timeout_value = 5000;/* ~ 5ms */
10766 			BA_timeout_value = cpu_to_le16(BA_timeout_value);
10767 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
10768 
10769 			/* if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) */
10770 			psta = rtw_get_stainfo(pstapriv, raddr);
10771 			if (psta != NULL) {
10772 				start_seq = (psta->sta_xmitpriv.txseq_tid[tid & 0x07] & 0xfff) + 1;
10773 
10774 				RTW_INFO("BA_starting_seqctrl = %d for TID=%d\n", start_seq, tid & 0x07);
10775 
10776 				psta->BA_starting_seqctrl[tid & 0x07] = start_seq;
10777 
10778 				BA_starting_seqctrl = start_seq << 4;
10779 			}
10780 
10781 			BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
10782 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
10783 			break;
10784 
10785 		case RTW_WLAN_ACTION_ADDBA_RESP:
10786 			pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
10787 			status = cpu_to_le16(status);
10788 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
10789 
10790 			BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set);
10791 
10792 			BA_para_set &= ~IEEE80211_ADDBA_PARAM_TID_MASK;
10793 			BA_para_set |= (tid << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
10794 
10795 			BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
10796 			BA_para_set |= (size << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
10797 
10798 			if (!padapter->registrypriv.wifi_spec) {
10799 				if (pregpriv->rx_ampdu_amsdu == 0) /* disabled */
10800 					BA_para_set &= ~BIT(0);
10801 				else if (pregpriv->rx_ampdu_amsdu == 1) /* enabled */
10802 					BA_para_set |= BIT(0);
10803 			}
10804 
10805 			psta = rtw_get_stainfo(pstapriv, raddr);
10806 			if (psta != NULL) {
10807 				if (psta->flags & WLAN_STA_AMSDU_DISABLE)
10808 					BA_para_set &= ~BIT(0);
10809 			}
10810 
10811 			BA_para_set = cpu_to_le16(BA_para_set);
10812 
10813 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
10814 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
10815 			break;
10816 
10817 		case RTW_WLAN_ACTION_DELBA:
10818 			BA_para_set = 0;
10819 			BA_para_set |= (tid << 12) & IEEE80211_DELBA_PARAM_TID_MASK;
10820 			BA_para_set |= (initiator << 11) & IEEE80211_DELBA_PARAM_INITIATOR_MASK;
10821 
10822 			BA_para_set = cpu_to_le16(BA_para_set);
10823 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
10824 			status = cpu_to_le16(status);
10825 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(status)), &(pattrib->pktlen));
10826 			break;
10827 		default:
10828 			break;
10829 		}
10830 	}
10831 
10832 	pattrib->last_txcmdsz = pattrib->pktlen;
10833 
10834 	if (wait_ack)
10835 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10836 	else {
10837 		dump_mgntframe(padapter, pmgntframe);
10838 		ret = _SUCCESS;
10839 	}
10840 
10841 exit:
10842 #endif /* CONFIG_80211N_HT */
10843 	return ret;
10844 }
10845 
10846 /**
10847  * issue_addba_req - TX ADDBA_REQ
10848  * @adapter: the adapter to TX
10849  * @ra: receiver address
10850  * @tid: tid
10851  */
issue_addba_req(_adapter * adapter,unsigned char * ra,u8 tid)10852 inline void issue_addba_req(_adapter *adapter, unsigned char *ra, u8 tid)
10853 {
10854 	issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_REQ
10855 			, tid
10856 			, 0 /* unused */
10857 			, 0 /* unused */
10858 			, 0 /* unused */
10859 			, _FALSE
10860 		       );
10861 	RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u\n"
10862 		 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid);
10863 
10864 }
10865 
10866 /**
10867  * issue_addba_rsp - TX ADDBA_RESP
10868  * @adapter: the adapter to TX
10869  * @ra: receiver address
10870  * @tid: tid
10871  * @status: status code
10872  * @size: the announced AMPDU buffer size
10873  */
issue_addba_rsp(_adapter * adapter,unsigned char * ra,u8 tid,u16 status,u8 size)10874 inline void issue_addba_rsp(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size)
10875 {
10876 	issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
10877 			, tid
10878 			, size
10879 			, status
10880 			, 0 /* unused */
10881 			, _FALSE
10882 		       );
10883 	RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" status=%u, tid=%u, size=%u\n"
10884 		 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size);
10885 }
10886 
10887 /**
10888  * issue_addba_rsp_wait_ack - TX ADDBA_RESP and wait ack
10889  * @adapter: the adapter to TX
10890  * @ra: receiver address
10891  * @tid: tid
10892  * @status: status code
10893  * @size: the announced AMPDU buffer size
10894  * @try_cnt: the maximal TX count to try
10895  * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10896  *           > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10897  */
issue_addba_rsp_wait_ack(_adapter * adapter,unsigned char * ra,u8 tid,u16 status,u8 size,int try_cnt,int wait_ms)10898 inline u8 issue_addba_rsp_wait_ack(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size, int try_cnt, int wait_ms)
10899 {
10900 	int ret = _FAIL;
10901 	int i = 0;
10902 	systime start = rtw_get_current_time();
10903 
10904 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(adapter)))
10905 		goto exit;
10906 
10907 	do {
10908 		ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
10909 				      , tid
10910 				      , size
10911 				      , status
10912 				      , 0 /* unused */
10913 				      , _TRUE
10914 				     );
10915 
10916 		i++;
10917 
10918 		if (RTW_CANNOT_RUN(adapter))
10919 			break;
10920 
10921 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10922 			rtw_msleep_os(wait_ms);
10923 
10924 	} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10925 
10926 	if (ret != _FAIL) {
10927 		ret = _SUCCESS;
10928 #ifndef DBG_XMIT_ACK
10929 		/* goto exit; */
10930 #endif
10931 	}
10932 
10933 	if (try_cnt && wait_ms) {
10934 		RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" status:=%u tid=%u size:%u%s, %d/%d in %u ms\n"
10935 			, FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size
10936 			, ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10937 	}
10938 
10939 exit:
10940 	return ret;
10941 }
10942 
10943 /**
10944  * issue_del_ba - TX DELBA
10945  * @adapter: the adapter to TX
10946  * @ra: receiver address
10947  * @tid: tid
10948  * @reason: reason code
10949  * @initiator: if we are the initiator of AMPDU association. used by DELBA
10950  */
issue_del_ba(_adapter * adapter,unsigned char * ra,u8 tid,u16 reason,u8 initiator)10951 inline void issue_del_ba(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator)
10952 {
10953 	issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10954 			, tid
10955 			, 0 /* unused */
10956 			, reason
10957 			, initiator
10958 			, _FALSE
10959 		       );
10960 	RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u\n"
10961 		 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator);
10962 }
10963 
10964 /**
10965  * issue_del_ba_ex - TX DELBA with xmit ack options
10966  * @adapter: the adapter to TX
10967  * @ra: receiver address
10968  * @tid: tid
10969  * @reason: reason code
10970  * @initiator: if we are the initiator of AMPDU association. used by DELBA
10971  * @try_cnt: the maximal TX count to try
10972  * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10973  *           > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10974  */
issue_del_ba_ex(_adapter * adapter,unsigned char * ra,u8 tid,u16 reason,u8 initiator,int try_cnt,int wait_ms)10975 int issue_del_ba_ex(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator
10976 		    , int try_cnt, int wait_ms)
10977 {
10978 	int ret = _FAIL;
10979 	int i = 0;
10980 	systime start = rtw_get_current_time();
10981 
10982 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(adapter)))
10983 		goto exit;
10984 
10985 	do {
10986 		ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10987 				      , tid
10988 				      , 0 /* unused */
10989 				      , reason
10990 				      , initiator
10991 				      , wait_ms > 0 ? _TRUE : _FALSE
10992 				     );
10993 
10994 		i++;
10995 
10996 		if (RTW_CANNOT_RUN(adapter))
10997 			break;
10998 
10999 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
11000 			rtw_msleep_os(wait_ms);
11001 
11002 	} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
11003 
11004 	if (ret != _FAIL) {
11005 		ret = _SUCCESS;
11006 #ifndef DBG_XMIT_ACK
11007 		/* goto exit; */
11008 #endif
11009 	}
11010 
11011 	if (try_cnt && wait_ms) {
11012 		RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u%s, %d/%d in %u ms\n"
11013 			, FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator
11014 			, ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
11015 	}
11016 exit:
11017 	return ret;
11018 }
11019 
issue_action_BSSCoexistPacket(_adapter * padapter)11020 void issue_action_BSSCoexistPacket(_adapter *padapter)
11021 {
11022 	_irqL	irqL;
11023 	_list		*plist, *phead;
11024 	unsigned char category, action;
11025 	struct xmit_frame			*pmgntframe;
11026 	struct pkt_attrib			*pattrib;
11027 	unsigned char				*pframe;
11028 	struct rtw_ieee80211_hdr	*pwlanhdr;
11029 	unsigned short			*fctrl;
11030 	struct	wlan_network	*pnetwork = NULL;
11031 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
11032 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
11033 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
11034 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
11035 	_queue		*queue	= &(pmlmepriv->scanned_queue);
11036 	u8 InfoContent[16] = {0};
11037 	u8 ICS[8][15];
11038 #ifdef CONFIG_80211N_HT
11039 	if ((pmlmepriv->num_FortyMHzIntolerant == 0) && (pmlmepriv->num_sta_no_ht == 0))
11040 		return;
11041 
11042 	if (_TRUE == pmlmeinfo->bwmode_updated)
11043 		return;
11044 
11045 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
11046 		return;
11047 
11048 	RTW_INFO("%s\n", __FUNCTION__);
11049 
11050 
11051 	category = RTW_WLAN_CATEGORY_PUBLIC;
11052 	action = ACT_PUBLIC_BSSCOEXIST;
11053 
11054 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
11055 	if (pmgntframe == NULL)
11056 		return;
11057 
11058 	/* update attribute */
11059 	pattrib = &pmgntframe->attrib;
11060 	update_mgntframe_attrib(padapter, pattrib);
11061 
11062 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
11063 
11064 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
11065 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
11066 
11067 	fctrl = &(pwlanhdr->frame_ctl);
11068 	*(fctrl) = 0;
11069 
11070 	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
11071 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
11072 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
11073 
11074 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
11075 	pmlmeext->mgnt_seq++;
11076 	set_frame_sub_type(pframe, WIFI_ACTION);
11077 
11078 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
11079 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
11080 
11081 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
11082 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
11083 
11084 	/* TODO calculate 40Mhz intolerant via ch and ch offset */
11085 	/* if (pmlmepriv->num_FortyMHzIntolerant > 0) */
11086 	{
11087 		u8 iedata = 0;
11088 
11089 		iedata |= BIT(2);/* 20 MHz BSS Width Request */
11090 		pframe = rtw_set_ie(pframe, EID_BSSCoexistence,  1, &iedata, &(pattrib->pktlen));
11091 	}
11092 
11093 	/*  */
11094 	_rtw_memset(ICS, 0, sizeof(ICS));
11095 	if (pmlmepriv->num_sta_no_ht > 0) {
11096 		int i;
11097 
11098 		_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
11099 
11100 		phead = get_list_head(queue);
11101 		plist = get_next(phead);
11102 
11103 		while (1) {
11104 			int len;
11105 			u8 *p;
11106 			WLAN_BSSID_EX *pbss_network;
11107 
11108 			if (rtw_end_of_queue_search(phead, plist) == _TRUE)
11109 				break;
11110 
11111 			pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
11112 
11113 			plist = get_next(plist);
11114 
11115 			pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
11116 
11117 			p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
11118 			if ((p == NULL) || (len == 0)) { /* non-HT */
11119 				if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14))
11120 					continue;
11121 
11122 				ICS[0][pbss_network->Configuration.DSConfig] = 1;
11123 
11124 				if (ICS[0][0] == 0)
11125 					ICS[0][0] = 1;
11126 			}
11127 
11128 		}
11129 
11130 		_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
11131 
11132 
11133 		for (i = 0; i < 8; i++) {
11134 			if (ICS[i][0] == 1) {
11135 				int j, k = 0;
11136 
11137 				InfoContent[k] = i;
11138 				/* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i); */
11139 				k++;
11140 
11141 				for (j = 1; j <= 14; j++) {
11142 					if (ICS[i][j] == 1) {
11143 						if (k < 16) {
11144 							InfoContent[k] = j; /* channel number */
11145 							/* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */
11146 							k++;
11147 						}
11148 					}
11149 				}
11150 
11151 				pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
11152 
11153 			}
11154 
11155 		}
11156 
11157 
11158 	}
11159 
11160 
11161 	pattrib->last_txcmdsz = pattrib->pktlen;
11162 
11163 	dump_mgntframe(padapter, pmgntframe);
11164 #endif /* CONFIG_80211N_HT */
11165 }
11166 
11167 /* Spatial Multiplexing Powersave (SMPS) action frame */
_issue_action_SM_PS(_adapter * padapter,unsigned char * raddr,u8 NewMimoPsMode,u8 wait_ack)11168 int _issue_action_SM_PS(_adapter *padapter ,  unsigned char *raddr , u8 NewMimoPsMode ,  u8 wait_ack)
11169 {
11170 
11171 	int ret = _FAIL;
11172 	unsigned char category = RTW_WLAN_CATEGORY_HT;
11173 	u8 action = RTW_WLAN_ACTION_HT_SM_PS;
11174 	u8 sm_power_control = 0;
11175 	struct xmit_frame			*pmgntframe;
11176 	struct pkt_attrib			*pattrib;
11177 	unsigned char					*pframe;
11178 	struct rtw_ieee80211_hdr	*pwlanhdr;
11179 	unsigned short				*fctrl;
11180 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
11181 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
11182 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
11183 
11184 
11185 	if (NewMimoPsMode == WLAN_HT_CAP_SM_PS_DISABLED) {
11186 		sm_power_control = sm_power_control  & ~(BIT(0)); /* SM Power Save Enable = 0 SM Power Save Disable */
11187 	} else if (NewMimoPsMode == WLAN_HT_CAP_SM_PS_STATIC) {
11188 		sm_power_control = sm_power_control | BIT(0);    /* SM Power Save Enable = 1 SM Power Save Enable  */
11189 		sm_power_control = sm_power_control & ~(BIT(1)); /* SM Mode = 0 Static Mode */
11190 	} else if (NewMimoPsMode == WLAN_HT_CAP_SM_PS_DYNAMIC) {
11191 		sm_power_control = sm_power_control | BIT(0); /* SM Power Save Enable = 1 SM Power Save Enable  */
11192 		sm_power_control = sm_power_control | BIT(1); /* SM Mode = 1 Dynamic Mode */
11193 	} else
11194 		return ret;
11195 
11196 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
11197 		return ret;
11198 
11199 	RTW_INFO("%s, sm_power_control=%u, NewMimoPsMode=%u\n", __FUNCTION__ , sm_power_control , NewMimoPsMode);
11200 
11201 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
11202 	if (pmgntframe == NULL)
11203 		return ret;
11204 
11205 	/* update attribute */
11206 	pattrib = &pmgntframe->attrib;
11207 	update_mgntframe_attrib(padapter, pattrib);
11208 
11209 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
11210 
11211 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
11212 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
11213 
11214 	fctrl = &(pwlanhdr->frame_ctl);
11215 	*(fctrl) = 0;
11216 
11217 	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); /* RA */
11218 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
11219 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); /* DA = RA */
11220 
11221 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
11222 	pmlmeext->mgnt_seq++;
11223 	set_frame_sub_type(pframe, WIFI_ACTION);
11224 
11225 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
11226 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
11227 
11228 	/* category, action */
11229 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
11230 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
11231 
11232 	pframe = rtw_set_fixed_ie(pframe, 1, &(sm_power_control), &(pattrib->pktlen));
11233 
11234 	pattrib->last_txcmdsz = pattrib->pktlen;
11235 
11236 	if (wait_ack)
11237 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
11238 	else {
11239 		dump_mgntframe(padapter, pmgntframe);
11240 		ret = _SUCCESS;
11241 	}
11242 
11243 	if (ret != _SUCCESS)
11244 		RTW_INFO("%s, ack to\n", __func__);
11245 
11246 	return ret;
11247 }
11248 
11249 /*
11250  * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
11251  * wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
11252  * try_cnt means the maximal TX count to try
11253  */
issue_action_SM_PS_wait_ack(_adapter * padapter,unsigned char * raddr,u8 NewMimoPsMode,int try_cnt,int wait_ms)11254 int issue_action_SM_PS_wait_ack(_adapter *padapter, unsigned char *raddr, u8 NewMimoPsMode, int try_cnt, int wait_ms)
11255 {
11256 	int ret = _FAIL;
11257 	int i = 0;
11258 	systime start = rtw_get_current_time();
11259 
11260 	if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
11261 		goto exit;
11262 
11263 	do {
11264 		ret = _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , wait_ms > 0 ? _TRUE : _FALSE);
11265 
11266 		i++;
11267 
11268 		if (RTW_CANNOT_RUN(padapter))
11269 			break;
11270 
11271 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
11272 			rtw_msleep_os(wait_ms);
11273 
11274 	} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
11275 
11276 	if (ret != _FAIL) {
11277 		ret = _SUCCESS;
11278 #ifndef DBG_XMIT_ACK
11279 		goto exit;
11280 #endif
11281 	}
11282 
11283 	if (try_cnt && wait_ms) {
11284 		if (raddr)
11285 			RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", %s , %d/%d in %u ms\n",
11286 				 FUNC_ADPT_ARG(padapter), MAC_ARG(raddr),
11287 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
11288 		else
11289 			RTW_INFO(FUNC_ADPT_FMT", %s , %d/%d in %u ms\n",
11290 				 FUNC_ADPT_ARG(padapter),
11291 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
11292 	}
11293 exit:
11294 
11295 	return ret;
11296 }
11297 
issue_action_SM_PS(_adapter * padapter,unsigned char * raddr,u8 NewMimoPsMode)11298 int issue_action_SM_PS(_adapter *padapter ,  unsigned char *raddr , u8 NewMimoPsMode)
11299 {
11300 	RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(raddr));
11301 	return _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , _FALSE);
11302 }
11303 
11304 /**
11305  * _send_delba_sta_tid - Cancel the AMPDU association for the specific @sta, @tid
11306  * @adapter: the adapter to which @sta belongs
11307  * @initiator: if we are the initiator of AMPDU association
11308  * @sta: the sta to be checked
11309  * @tid: the tid to be checked
11310  * @force: cancel and send DELBA even when no AMPDU association is setup
11311  * @wait_ack: send delba with xmit ack (valid when initiator == 0)
11312  *
11313  * Returns:
11314  * _FAIL if sta is NULL
11315  * when initiator is 1, always _SUCCESS
11316  * when initiator is 0, _SUCCESS if DELBA is acked
11317  */
_send_delba_sta_tid(_adapter * adapter,u8 initiator,struct sta_info * sta,u8 tid,u8 force,int wait_ack)11318 static unsigned int _send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
11319 					, u8 force, int wait_ack)
11320 {
11321 	int ret = _SUCCESS;
11322 
11323 	if (sta == NULL) {
11324 		ret = _FAIL;
11325 		goto exit;
11326 	}
11327 
11328 	if (initiator == 0) {
11329 		/* recipient */
11330 		if (force || sta->recvreorder_ctrl[tid].enable == _TRUE) {
11331 			u8 ampdu_size_bak = sta->recvreorder_ctrl[tid].ampdu_size;
11332 
11333 			sta->recvreorder_ctrl[tid].enable = _FALSE;
11334 			sta->recvreorder_ctrl[tid].ampdu_size = RX_AMPDU_SIZE_INVALID;
11335 
11336 			if (rtw_del_rx_ampdu_test_trigger_no_tx_fail())
11337 				ret = _FAIL;
11338 			else if (wait_ack)
11339 				ret = issue_del_ba_ex(adapter, sta->cmn.mac_addr, tid, 37, initiator, 3, 1);
11340 			else
11341 				issue_del_ba(adapter, sta->cmn.mac_addr, tid, 37, initiator);
11342 
11343 			if (ret == _FAIL && sta->recvreorder_ctrl[tid].enable == _FALSE)
11344 				sta->recvreorder_ctrl[tid].ampdu_size = ampdu_size_bak;
11345 		}
11346 	} else if (initiator == 1) {
11347 		/* originator */
11348 #ifdef CONFIG_80211N_HT
11349 		if (force || sta->htpriv.agg_enable_bitmap & BIT(tid)) {
11350 			sta->htpriv.agg_enable_bitmap &= ~BIT(tid);
11351 			sta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
11352 			issue_del_ba(adapter, sta->cmn.mac_addr, tid, 37, initiator);
11353 		}
11354 #endif
11355 	}
11356 
11357 exit:
11358 	return ret;
11359 }
11360 
send_delba_sta_tid(_adapter * adapter,u8 initiator,struct sta_info * sta,u8 tid,u8 force)11361 inline unsigned int send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
11362 				       , u8 force)
11363 {
11364 	return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 0);
11365 }
11366 
send_delba_sta_tid_wait_ack(_adapter * adapter,u8 initiator,struct sta_info * sta,u8 tid,u8 force)11367 inline unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
11368 		, u8 force)
11369 {
11370 	return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 1);
11371 }
11372 
send_delba(_adapter * padapter,u8 initiator,u8 * addr)11373 unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
11374 {
11375 	struct sta_priv *pstapriv = &padapter->stapriv;
11376 	struct sta_info *psta = NULL;
11377 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
11378 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
11379 	u16 tid;
11380 
11381 	if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
11382 		if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
11383 			return _SUCCESS;
11384 
11385 	psta = rtw_get_stainfo(pstapriv, addr);
11386 	if (psta == NULL)
11387 		return _SUCCESS;
11388 
11389 #if 0
11390 	RTW_INFO("%s:%s\n", __func__, (initiator == 0) ? "RX_DIR" : "TX_DIR");
11391 	if (initiator == 1) /* originator */
11392 		RTW_INFO("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
11393 #endif
11394 
11395 	for (tid = 0; tid < TID_NUM; tid++)
11396 		send_delba_sta_tid(padapter, initiator, psta, tid, 0);
11397 
11398 	return _SUCCESS;
11399 }
11400 
11401 #ifdef CONFIG_AP_MODE
send_beacon(_adapter * padapter)11402 unsigned int send_beacon(_adapter *padapter)
11403 {
11404 #if defined(CONFIG_PCI_HCI) && !defined(CONFIG_PCI_BCN_POLLING)
11405 	#ifdef CONFIG_FW_HANDLE_TXBCN
11406 	u8 vap_id = padapter->vap_id;
11407 
11408 	/* bypass TX BCN because vap_id is invalid*/
11409 	if (vap_id == CONFIG_LIMITED_AP_NUM)
11410 		return _SUCCESS;
11411 	#endif
11412 
11413 	/* bypass TX BCN queue because op ch is switching/waiting */
11414 	if (check_fwstate(&padapter->mlmepriv, WIFI_OP_CH_SWITCHING)
11415 		|| IS_CH_WAITING(adapter_to_rfctl(padapter))
11416 	)
11417 		return _SUCCESS;
11418 
11419 	/* RTW_INFO("%s\n", __FUNCTION__); */
11420 
11421 	rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
11422 
11423 	/* 8192EE Port select for Beacon DL */
11424 	rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
11425 	#ifdef CONFIG_FW_HANDLE_TXBCN
11426 	rtw_hal_set_hwreg(padapter, HW_VAR_BCN_HEAD_SEL, &vap_id);
11427 	#endif
11428 
11429 	issue_beacon(padapter, 0);
11430 
11431 	#ifdef CONFIG_FW_HANDLE_TXBCN
11432 	vap_id = 0xFF;
11433 	rtw_hal_set_hwreg(padapter, HW_VAR_BCN_HEAD_SEL, &vap_id);
11434 	#endif
11435 
11436 	#ifdef RTL8814AE_SW_BCN
11437 	if (GET_HAL_DATA(padapter)->bCorrectBCN != 0)
11438 		RTW_INFO("%s, line%d, Warnning, pHalData->bCorrectBCN != 0\n", __func__, __LINE__);
11439 	GET_HAL_DATA(padapter)->bCorrectBCN = 1;
11440 	#endif
11441 
11442 	return _SUCCESS;
11443 #endif
11444 
11445 /* CONFIG_PCI_BCN_POLLING is for pci interface beacon polling mode */
11446 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)|| defined(CONFIG_PCI_BCN_POLLING)
11447 	u8 bxmitok = _FALSE;
11448 	int issue = 0;
11449 	int poll = 0;
11450 	systime start = rtw_get_current_time();
11451 	#ifdef CONFIG_FW_HANDLE_TXBCN
11452 	u8 vap_id = padapter->vap_id;
11453 
11454 	/* bypass TX BCN because vap_id is invalid*/
11455 	if (vap_id == CONFIG_LIMITED_AP_NUM)
11456 		return _SUCCESS;
11457 	#endif
11458 
11459 	/* bypass TX BCN queue because op ch is switching/waiting */
11460 	if (check_fwstate(&padapter->mlmepriv, WIFI_OP_CH_SWITCHING)
11461 		|| IS_CH_WAITING(adapter_to_rfctl(padapter))
11462 	)
11463 		return _SUCCESS;
11464 
11465 	#if defined(CONFIG_USB_HCI)
11466 	#if defined(CONFIG_RTL8812A)
11467 	if (IS_FULL_SPEED_USB(padapter)) {
11468 		issue_beacon(padapter, 300);
11469 		bxmitok = _TRUE;
11470 	} else
11471 	#endif
11472 	#endif
11473 	{
11474 		rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
11475 		rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
11476 		#ifdef CONFIG_FW_HANDLE_TXBCN
11477 		rtw_hal_set_hwreg(padapter, HW_VAR_BCN_HEAD_SEL, &vap_id);
11478 		#endif
11479 		do {
11480 			#if defined(CONFIG_PCI_BCN_POLLING)
11481 			issue_beacon(padapter, 0);
11482 			#else
11483 			issue_beacon(padapter, 100);
11484 			#endif
11485 			issue++;
11486 			do {
11487 				#if defined(CONFIG_PCI_BCN_POLLING)
11488 				rtw_msleep_os(1);
11489 				#else
11490 				rtw_yield_os();
11491 				#endif
11492 				rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
11493 				poll++;
11494 			} while ((poll % 10) != 0 && _FALSE == bxmitok && !RTW_CANNOT_RUN(padapter));
11495 			#if defined(CONFIG_PCI_BCN_POLLING)
11496 			rtw_hal_unmap_beacon_icf(padapter);
11497 			#endif
11498 		} while (bxmitok == _FALSE && (issue < 100) && !RTW_CANNOT_RUN(padapter));
11499 		#ifdef CONFIG_FW_HANDLE_TXBCN
11500 		vap_id = 0xFF;
11501 		rtw_hal_set_hwreg(padapter, HW_VAR_BCN_HEAD_SEL, &vap_id);
11502 		#endif
11503 	}
11504 	if (RTW_CANNOT_RUN(padapter))
11505 		return _FAIL;
11506 
11507 
11508 	if (_FALSE == bxmitok) {
11509 		RTW_INFO("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
11510 		#ifdef CONFIG_BCN_RECOVERY
11511 		GET_HAL_DATA(padapter)->issue_bcn_fail++;
11512 		#endif  /*CONFIG_BCN_RECOVERY*/
11513 		return _FAIL;
11514 	} else {
11515 		u32 passing_time = rtw_get_passing_time_ms(start);
11516 
11517 		if (passing_time > 100 || issue > 3)
11518 			RTW_INFO("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
11519 		else if (0)
11520 			RTW_INFO("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
11521 
11522 		#ifdef CONFIG_FW_CORRECT_BCN
11523 		rtw_hal_fw_correct_bcn(padapter);
11524 		#endif
11525 		return _SUCCESS;
11526 	}
11527 
11528 #endif /*defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)*/
11529 
11530 }
11531 #endif /* CONFIG_AP_MODE */
11532 
11533 /****************************************************************************
11534 
11535 Following are some utitity fuctions for WiFi MLME
11536 
11537 *****************************************************************************/
11538 
IsLegal5GChannel(PADAPTER Adapter,u8 channel)11539 BOOLEAN IsLegal5GChannel(
11540 	PADAPTER			Adapter,
11541 	u8			channel)
11542 {
11543 
11544 	int i = 0;
11545 	u8 Channel_5G[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
11546 		60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
11547 		124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
11548 			     161, 163, 165
11549 			    };
11550 	for (i = 0; i < sizeof(Channel_5G); i++)
11551 		if (channel == Channel_5G[i])
11552 			return _TRUE;
11553 	return _FALSE;
11554 }
11555 
11556 /* collect bss info from Beacon and Probe request/response frames. */
collect_bss_info(_adapter * padapter,union recv_frame * precv_frame,WLAN_BSSID_EX * bssid)11557 u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
11558 {
11559 	int	i;
11560 	sint len;
11561 	u8	*p;
11562 	u8	rf_path;
11563 	u16	val16, subtype;
11564 	u8	*pframe = precv_frame->u.hdr.rx_data;
11565 	u32	packet_len = precv_frame->u.hdr.len;
11566 	u8 ie_offset;
11567 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
11568 	struct registry_priv	*pregistrypriv = &padapter->registrypriv;
11569 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
11570 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
11571 #ifdef	CONFIG_LAYER2_ROAMING
11572 	u32 *pbuf;
11573 #endif
11574 
11575 	len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
11576 
11577 	if (len > MAX_IE_SZ) {
11578 		/* RTW_INFO("IE too long for survey event\n"); */
11579 		return _FAIL;
11580 	}
11581 
11582 	_rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX));
11583 
11584 	subtype = get_frame_sub_type(pframe);
11585 
11586 	if (subtype == WIFI_BEACON) {
11587 		bssid->Reserved[0] = BSS_TYPE_BCN;
11588 		ie_offset = _BEACON_IE_OFFSET_;
11589 	} else {
11590 		/* FIXME : more type */
11591 		if (subtype == WIFI_PROBERSP) {
11592 			ie_offset = _PROBERSP_IE_OFFSET_;
11593 			bssid->Reserved[0] = BSS_TYPE_PROB_RSP;
11594 		} else if (subtype == WIFI_PROBEREQ) {
11595 			ie_offset = _PROBEREQ_IE_OFFSET_;
11596 			bssid->Reserved[0] = BSS_TYPE_PROB_REQ;
11597 		} else {
11598 			bssid->Reserved[0] = BSS_TYPE_UNDEF;
11599 			ie_offset = _FIXED_IE_LENGTH_;
11600 		}
11601 	}
11602 
11603 	bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
11604 
11605 	/* below is to copy the information element */
11606 	bssid->IELength = len;
11607 	_rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
11608 
11609 	/* get the signal strength */
11610 	/* bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; */ /* 0-100 index. */
11611 	bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.recv_signal_power; /* in dBM.raw data */
11612 	bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.signal_quality;/* in percentage */
11613 	bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.signal_strength;/* in percentage */
11614 
11615 	/* get rx_snr */
11616 	if (precv_frame->u.hdr.attrib.data_rate >= DESC_RATE11M) {
11617 		bssid->PhyInfo.is_cck_rate = 0;
11618 		for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++)
11619 			bssid->PhyInfo.rx_snr[rf_path] =
11620 				precv_frame->u.hdr.attrib.phy_info.rx_snr[rf_path];
11621 	} else
11622 		bssid->PhyInfo.is_cck_rate = 1;
11623 
11624 #ifdef CONFIG_ANTENNA_DIVERSITY
11625 	rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &(bssid->PhyInfo.Optimum_antenna), NULL);
11626 #endif
11627 
11628 	/* checking SSID */
11629 	p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset);
11630 	if (p == NULL) {
11631 		RTW_INFO("marc: cannot find SSID for survey event\n");
11632 		return _FAIL;
11633 	}
11634 
11635 	if (*(p + 1)) {
11636 		if (len > NDIS_802_11_LENGTH_SSID) {
11637 			RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
11638 			return _FAIL;
11639 		}
11640 		_rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
11641 		bssid->Ssid.SsidLength = *(p + 1);
11642 	} else
11643 		bssid->Ssid.SsidLength = 0;
11644 
11645 	_rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
11646 
11647 	/* checking rate info... */
11648 	i = 0;
11649 	p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
11650 	if (p != NULL) {
11651 		if (len > NDIS_802_11_LENGTH_RATES_EX) {
11652 			RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
11653 			return _FAIL;
11654 		}
11655 #ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT
11656 		if (rtw_validate_value(_SUPPORTEDRATES_IE_, p+2, len) == _FALSE) {
11657 			rtw_absorb_ssid_ifneed(padapter, bssid, pframe);
11658 			RTW_DBG_DUMP("Invalidated Support Rate IE --", p, len+2);
11659 			return _FAIL;
11660 		}
11661 #endif /* #ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT */
11662 		_rtw_memcpy(bssid->SupportedRates, (p + 2), len);
11663 		i = len;
11664 	}
11665 
11666 	p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
11667 	if (p != NULL) {
11668 		if (len > (NDIS_802_11_LENGTH_RATES_EX - i)) {
11669 			RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
11670 			return _FAIL;
11671 		}
11672 #ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT
11673 		if (rtw_validate_value(_EXT_SUPPORTEDRATES_IE_, p+2, len) == _FALSE) {
11674 			rtw_absorb_ssid_ifneed(padapter, bssid, pframe);
11675 			RTW_DBG_DUMP("Invalidated EXT Support Rate IE --", p, len+2);
11676 			return _FAIL;
11677 		}
11678 #endif /* #ifdef CONFIG_CHECK_SPECIFIC_IE_CONTENT */
11679 		_rtw_memcpy(bssid->SupportedRates + i, (p + 2), len);
11680 	}
11681 
11682 #ifdef CONFIG_P2P
11683 	if (subtype == WIFI_PROBEREQ) {
11684 		u8 *p2p_ie;
11685 		u32	p2p_ielen;
11686 		/* Set Listion Channel */
11687 		p2p_ie = rtw_get_p2p_ie(bssid->IEs, bssid->IELength, NULL, &p2p_ielen);
11688 		if (p2p_ie) {
11689 			u32	attr_contentlen = 0;
11690 			u8 listen_ch[5] = { 0x00 };
11691 
11692 			attr_contentlen = sizeof(listen_ch);
11693 			rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, listen_ch, &attr_contentlen);
11694 			bssid->Configuration.DSConfig = listen_ch[4];
11695 		} else {
11696 			/* use current channel */
11697 			bssid->Configuration.DSConfig = padapter->mlmeextpriv.cur_channel;
11698 			RTW_INFO("%s()-%d: Cannot get p2p_ie. set DSconfig to op_ch(%d)\n", __FUNCTION__, __LINE__, bssid->Configuration.DSConfig);
11699 		}
11700 
11701 		/* FIXME */
11702 		bssid->InfrastructureMode = Ndis802_11Infrastructure;
11703 		_rtw_memcpy(bssid->MacAddress, get_addr2_ptr(pframe), ETH_ALEN);
11704 		bssid->Privacy = 1;
11705 		return _SUCCESS;
11706 	}
11707 #endif /* CONFIG_P2P */
11708 
11709 	if (bssid->IELength < 12)
11710 		return _FAIL;
11711 
11712 	/* Checking for DSConfig */
11713 	p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
11714 
11715 	bssid->Configuration.DSConfig = 0;
11716 	bssid->Configuration.Length = 0;
11717 
11718 	if (p)
11719 		bssid->Configuration.DSConfig = *(p + 2);
11720 	else {
11721 		/* In 5G, some ap do not have DSSET IE */
11722 		/* checking HT info for channel */
11723 		p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
11724 		if (p) {
11725 			struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
11726 			bssid->Configuration.DSConfig = HT_info->primary_channel;
11727 		} else {
11728 			/* use current channel */
11729 			bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
11730 		}
11731 	}
11732 
11733 	_rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
11734 	bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
11735 
11736 	val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
11737 
11738 	if ((val16 & 0x03) == cap_ESS) {
11739 		bssid->InfrastructureMode = Ndis802_11Infrastructure;
11740 		_rtw_memcpy(bssid->MacAddress, get_addr2_ptr(pframe), ETH_ALEN);
11741 	} else if ((val16 & 0x03) == cap_IBSS){
11742 		bssid->InfrastructureMode = Ndis802_11IBSS;
11743 		_rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
11744 	} else if ((val16 & 0x03) == 0x00){
11745 		u8 *mesh_id_ie, *mesh_conf_ie;
11746 		sint mesh_id_ie_len, mesh_conf_ie_len;
11747 
11748 		mesh_id_ie = rtw_get_ie(bssid->IEs + ie_offset, WLAN_EID_MESH_ID, &mesh_id_ie_len, bssid->IELength - ie_offset);
11749 		mesh_conf_ie = rtw_get_ie(bssid->IEs + ie_offset, WLAN_EID_MESH_CONFIG, &mesh_conf_ie_len, bssid->IELength - ie_offset);
11750 		if (mesh_id_ie || mesh_conf_ie) {
11751 			if (!mesh_id_ie) {
11752 				RTW_INFO("cannot find Mesh ID for survey event\n");
11753 				return _FAIL;
11754 			}
11755 			if (mesh_id_ie_len) {
11756 				if (mesh_id_ie_len > NDIS_802_11_LENGTH_SSID) {
11757 					RTW_INFO("Mesh ID too long (%d) for survey event\n", mesh_id_ie_len);
11758 					return _FAIL;
11759 				}
11760 				_rtw_memcpy(bssid->mesh_id.Ssid, (mesh_id_ie + 2), mesh_id_ie_len);
11761 				bssid->mesh_id.SsidLength = mesh_id_ie_len;
11762 			} else
11763 				bssid->mesh_id.SsidLength = 0;
11764 
11765 			if (!mesh_conf_ie) {
11766 				RTW_INFO("cannot find Mesh config for survey event\n");
11767 				return _FAIL;
11768 			}
11769 			if (mesh_conf_ie_len != 7) {
11770 				RTW_INFO("invalid Mesh conf IE len (%d) for survey event\n", mesh_conf_ie_len);
11771 				return _FAIL;
11772 			}
11773 
11774 			bssid->InfrastructureMode = Ndis802_11_mesh;
11775 			_rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
11776 		} else {
11777 			/* default cases */
11778 			bssid->InfrastructureMode = Ndis802_11IBSS;
11779 			_rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
11780 		}
11781 	}
11782 
11783 	if (val16 & BIT(4))
11784 		bssid->Privacy = 1;
11785 	else
11786 		bssid->Privacy = 0;
11787 
11788 	bssid->Configuration.ATIMWindow = 0;
11789 
11790 	/* 20/40 BSS Coexistence check */
11791 	if ((pregistrypriv->wifi_spec == 1) && (_FALSE == pmlmeinfo->bwmode_updated)) {
11792 		struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
11793 #ifdef CONFIG_80211N_HT
11794 		p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
11795 		if (p && len > 0) {
11796 			struct HT_caps_element	*pHT_caps;
11797 			pHT_caps = (struct HT_caps_element *)(p + 2);
11798 
11799 			if (pHT_caps->u.HT_cap_element.HT_caps_info & BIT(14))
11800 				pmlmepriv->num_FortyMHzIntolerant++;
11801 		} else
11802 			pmlmepriv->num_sta_no_ht++;
11803 #endif /* CONFIG_80211N_HT */
11804 
11805 	}
11806 
11807 #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
11808 	if (strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
11809 		RTW_INFO("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
11810 			, bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
11811 			 , rtw_get_oper_ch(padapter)
11812 			, bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
11813 			);
11814 	}
11815 #endif
11816 
11817 	/* mark bss info receving from nearby channel as SignalQuality 101 */
11818 	if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
11819 		bssid->PhyInfo.SignalQuality = 101;
11820 
11821 #ifdef CONFIG_RTW_80211K
11822 	p = rtw_get_ie(bssid->IEs + ie_offset, _EID_RRM_EN_CAP_IE_, &len, bssid->IELength - ie_offset);
11823 	if (p)
11824 		_rtw_memcpy(bssid->PhyInfo.rm_en_cap, (p + 2), MIN(*(p + 1),
11825 			    sizeof(bssid->PhyInfo.rm_en_cap)));
11826 
11827 	/* save freerun counter */
11828 	bssid->PhyInfo.free_cnt = precv_frame->u.hdr.attrib.free_cnt;
11829 #endif
11830 #ifdef	CONFIG_LAYER2_ROAMING
11831 	pbuf = (u32 *)((u8 *)pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
11832 	bssid->tsf = le32_to_cpu(*(pbuf + 1));
11833 	bssid->tsf = bssid->tsf << 32;
11834 	bssid->tsf |= le32_to_cpu(*pbuf);
11835 #endif
11836 	return _SUCCESS;
11837 }
11838 
11839 #ifdef CONFIG_AP_MODE
start_create_ibss(_adapter * padapter)11840 void start_create_ibss(_adapter *padapter)
11841 {
11842 	unsigned short	caps;
11843 	u8	val8;
11844 	u8	join_type;
11845 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
11846 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
11847 	WLAN_BSSID_EX		*pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
11848 	u8 doiqk = _FALSE;
11849 	pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
11850 	pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
11851 
11852 	/* update wireless mode */
11853 	update_wireless_mode(padapter);
11854 
11855 	/* udpate capability */
11856 	caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
11857 	update_capinfo(padapter, caps);
11858 	if (caps & cap_IBSS) { /* adhoc master */
11859 		/* set_opmode_cmd(padapter, adhoc); */ /* removed */
11860 
11861 		val8 = 0xcf;
11862 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
11863 
11864 		doiqk = _TRUE;
11865 		rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
11866 
11867 		/* switch channel */
11868 		set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
11869 
11870 		doiqk = _FALSE;
11871 		rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
11872 
11873 		beacon_timing_control(padapter);
11874 
11875 		/* set msr to WIFI_FW_ADHOC_STATE */
11876 		pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
11877 		Set_MSR(padapter, (pmlmeinfo->state & 0x3));
11878 
11879 		/* issue beacon */
11880 		if (send_beacon(padapter) == _FAIL) {
11881 
11882 			report_join_res(padapter, -1, WLAN_STATUS_UNSPECIFIED_FAILURE);
11883 			pmlmeinfo->state = WIFI_FW_NULL_STATE;
11884 		} else {
11885 			rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
11886 			rtw_hal_rcr_set_chk_bssid(padapter, MLME_ADHOC_STARTED);
11887 			join_type = 0;
11888 			rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
11889 
11890 			rtw_btcoex_connect_notify(padapter, join_type);
11891 
11892 			report_join_res(padapter, 1, WLAN_STATUS_SUCCESS);
11893 			pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
11894 			rtw_indicate_connect(padapter);
11895 		}
11896 	} else {
11897 		RTW_INFO("start_create_ibss, invalid cap:%x\n", caps);
11898 		return;
11899 	}
11900 	/* update bc/mc sta_info */
11901 	update_bmc_sta(padapter);
11902 
11903 }
11904 #endif /* CONFIG_AP_MODE */
11905 
start_clnt_join(_adapter * padapter)11906 void start_clnt_join(_adapter *padapter)
11907 {
11908 	unsigned short	caps;
11909 	u8	val8;
11910 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
11911 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
11912 	WLAN_BSSID_EX		*pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
11913 	int beacon_timeout;
11914 	u8 ASIX_ID[] = {0x00, 0x0E, 0xC6};
11915 
11916 	/* update wireless mode */
11917 	update_wireless_mode(padapter);
11918 
11919 	/* udpate capability */
11920 	caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
11921 	update_capinfo(padapter, caps);
11922 
11923 	/* check if sta is ASIX peer and fix IOT issue if it is. */
11924 	if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) , ASIX_ID , 3)) {
11925 		u8 iot_flag = _TRUE;
11926 		rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
11927 	}
11928 
11929 	if (caps & cap_ESS) {
11930 		Set_MSR(padapter, WIFI_FW_STATION_STATE);
11931 
11932 		val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf;
11933 
11934 #ifdef CONFIG_WAPI_SUPPORT
11935 		if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI) {
11936 			/* Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey. */
11937 			val8 = 0x4c;
11938 		}
11939 #endif
11940 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
11941 
11942 #ifdef CONFIG_DEAUTH_BEFORE_CONNECT
11943 		/* Because of AP's not receiving deauth before */
11944 		/* AP may: 1)not response auth or 2)deauth us after link is complete */
11945 		/* issue deauth before issuing auth to deal with the situation */
11946 
11947 		/*	Commented by Albert 2012/07/21 */
11948 		/*	For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
11949 		{
11950 #ifdef CONFIG_P2P
11951 			_queue *queue = &(padapter->mlmepriv.scanned_queue);
11952 			_list	*head = get_list_head(queue);
11953 			_list *pos = get_next(head);
11954 			struct wlan_network *scanned = NULL;
11955 			u8 ie_offset = 0;
11956 			_irqL irqL;
11957 			bool has_p2p_ie = _FALSE;
11958 
11959 			_enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
11960 
11961 			for (pos = get_next(head); !rtw_end_of_queue_search(head, pos); pos = get_next(pos)) {
11962 
11963 				scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
11964 
11965 				if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
11966 				    && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
11967 				   ) {
11968 					ie_offset = (scanned->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12);
11969 					if (rtw_get_p2p_ie(scanned->network.IEs + ie_offset, scanned->network.IELength - ie_offset, NULL, NULL))
11970 						has_p2p_ie = _TRUE;
11971 					break;
11972 				}
11973 			}
11974 
11975 			_exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
11976 
11977 			if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE)
11978 #endif /* CONFIG_P2P */
11979 				/* To avoid connecting to AP fail during resume process, change retry count from 5 to 1 */
11980 				issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
11981 		}
11982 #endif /* CONFIG_DEAUTH_BEFORE_CONNECT */
11983 
11984 		/* here wait for receiving the beacon to start auth */
11985 		/* and enable a timer */
11986 		beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
11987 		set_link_timer(pmlmeext, beacon_timeout);
11988 		_set_timer(&padapter->mlmepriv.assoc_timer,
11989 			(REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO * REASSOC_LIMIT) + beacon_timeout);
11990 
11991 #ifdef CONFIG_RTW_80211R
11992 		if (rtw_ft_roam(padapter)) {
11993 			rtw_ft_start_clnt_join(padapter);
11994 		} else
11995 #endif
11996 		{
11997 			rtw_sta_linking_test_set_start();
11998 			pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
11999 		}
12000 	} else if (caps & cap_IBSS) { /* adhoc client */
12001 		Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
12002 
12003 		val8 = 0xcf;
12004 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
12005 
12006 		beacon_timing_control(padapter);
12007 
12008 		pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
12009 
12010 		report_join_res(padapter, 1, WLAN_STATUS_SUCCESS);
12011 	} else {
12012 		/* RTW_INFO("marc: invalid cap:%x\n", caps); */
12013 		return;
12014 	}
12015 
12016 }
12017 
start_clnt_auth(_adapter * padapter)12018 void start_clnt_auth(_adapter *padapter)
12019 {
12020 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
12021 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12022 
12023 	_cancel_timer_ex(&pmlmeext->link_timer);
12024 
12025 	pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
12026 	pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
12027 
12028 	pmlmeinfo->auth_seq = 1;
12029 	pmlmeinfo->reauth_count = 0;
12030 	pmlmeinfo->reassoc_count = 0;
12031 	pmlmeinfo->link_count = 0;
12032 	pmlmeext->retry = 0;
12033 
12034 #ifdef CONFIG_RTW_80211R
12035 	if (rtw_ft_roam(padapter)) {
12036 		rtw_ft_set_status(padapter, RTW_FT_AUTHENTICATING_STA);
12037 		RTW_PRINT("start ft auth\n");
12038 	} else
12039 #endif
12040 		RTW_PRINT("start auth\n");
12041 
12042 #ifdef CONFIG_IOCTL_CFG80211
12043 	if (rtw_sec_chk_auth_type(padapter, MLME_AUTHTYPE_SAE)) {
12044 		if (rtw_cached_pmkid(padapter, get_my_bssid(&pmlmeinfo->network)) != -1) {
12045 			RTW_INFO("SAE: PMKSA cache entry found\n");
12046 			padapter->securitypriv.auth_alg = WLAN_AUTH_OPEN;
12047 			goto no_external_auth;
12048 		}
12049 
12050 		RTW_PRINT("SAE: start external auth\n");
12051 		rtw_cfg80211_external_auth_request(padapter, NULL);
12052 		return;
12053 	}
12054 no_external_auth:
12055 #endif /* CONFIG_IOCTL_CFG80211 */
12056 
12057 	issue_auth(padapter, NULL, 0);
12058 
12059 	set_link_timer(pmlmeext, REAUTH_TO);
12060 
12061 }
12062 
12063 
start_clnt_assoc(_adapter * padapter)12064 void start_clnt_assoc(_adapter *padapter)
12065 {
12066 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
12067 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12068 
12069 	_cancel_timer_ex(&pmlmeext->link_timer);
12070 
12071 	pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
12072 	pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
12073 
12074 #ifdef CONFIG_RTW_80211R
12075 	if (rtw_ft_roam(padapter)
12076 	#ifdef CONFIG_RTW_WNM
12077 		|| rtw_wnm_btm_reassoc_req(padapter)
12078 	#endif
12079 	)
12080 		issue_reassocreq(padapter);
12081 	else
12082 #endif
12083 		issue_assocreq(padapter);
12084 
12085 	set_link_timer(pmlmeext, REASSOC_TO);
12086 }
12087 
receive_disconnect(_adapter * padapter,unsigned char * MacAddr,unsigned short reason,u8 locally_generated)12088 unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, u8 locally_generated)
12089 {
12090 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
12091 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12092 
12093 	if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
12094 		return _SUCCESS;
12095 
12096 	RTW_INFO("%s\n", __FUNCTION__);
12097 
12098 #ifdef CONFIG_RTW_REPEATER_SON
12099 	rtw_rson_do_disconnect(padapter);
12100 #endif
12101 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
12102 		if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
12103 			if (report_del_sta_event(padapter, MacAddr, reason, _TRUE, locally_generated) != _FAIL)
12104 				pmlmeinfo->state = WIFI_FW_NULL_STATE;
12105 		} else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) {
12106 			if (report_join_res(padapter, -2, reason) != _FAIL)
12107 				pmlmeinfo->state = WIFI_FW_NULL_STATE;
12108 		} else
12109 			RTW_INFO(FUNC_ADPT_FMT" - End to Disconnect\n", FUNC_ADPT_ARG(padapter));
12110 #ifdef CONFIG_RTW_80211R
12111 		rtw_ft_roam_status_reset(padapter);
12112 #endif
12113 #ifdef CONFIG_RTW_WNM
12114 		rtw_wnm_reset_btm_state(padapter);
12115 #endif
12116 	}
12117 
12118 	return _SUCCESS;
12119 }
12120 
rtw_hidden_ssid_bss_count(_adapter * adapter,WLAN_BSSID_EX * bss)12121 static void rtw_hidden_ssid_bss_count(_adapter *adapter, WLAN_BSSID_EX *bss)
12122 {
12123 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
12124 	RT_CHANNEL_INFO *chset = rfctl->channel_set;
12125 	int chset_idx;
12126 
12127 	if (bss->InfrastructureMode != Ndis802_11Infrastructure)
12128 		return;
12129 
12130 	if (!hidden_ssid_ap(bss))
12131 		return;
12132 
12133 	chset_idx = rtw_chset_search_ch(chset, bss->Configuration.DSConfig);
12134 	if (chset_idx < 0)
12135 		return;
12136 
12137 	chset[chset_idx].hidden_bss_cnt++;
12138 }
12139 
12140 /****************************************************************************
12141 
12142 Following are the functions to report events
12143 
12144 *****************************************************************************/
12145 
report_survey_event(_adapter * padapter,union recv_frame * precv_frame)12146 void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
12147 {
12148 	struct cmd_obj *pcmd_obj;
12149 	u8 *pevtcmd;
12150 	u32 cmdsz;
12151 	struct survey_event *psurvey_evt;
12152 	struct rtw_evt_header *evt_hdr;
12153 	struct mlme_ext_priv *pmlmeext;
12154 	struct cmd_priv *pcmdpriv;
12155 	/* u8 *pframe = precv_frame->u.hdr.rx_data; */
12156 	/* uint len = precv_frame->u.hdr.len; */
12157 
12158 	if (!padapter)
12159 		return;
12160 
12161 	pmlmeext = &padapter->mlmeextpriv;
12162 	pcmdpriv = &padapter->cmdpriv;
12163 
12164 	pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12165 	if (pcmd_obj == NULL)
12166 		return;
12167 
12168 	cmdsz = (sizeof(struct survey_event) + sizeof(struct rtw_evt_header));
12169 	pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12170 	if (pevtcmd == NULL) {
12171 		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12172 		return;
12173 	}
12174 
12175 	_rtw_init_listhead(&pcmd_obj->list);
12176 
12177 	pcmd_obj->cmdcode = CMD_SET_MLME_EVT;
12178 	pcmd_obj->cmdsz = cmdsz;
12179 	pcmd_obj->parmbuf = pevtcmd;
12180 
12181 	pcmd_obj->rsp = NULL;
12182 	pcmd_obj->rspsz  = 0;
12183 
12184 	evt_hdr = (struct rtw_evt_header *)(pevtcmd);
12185 	evt_hdr->len = sizeof(struct survey_event);
12186 	evt_hdr->id = EVT_SURVEY;
12187 	evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12188 
12189 	psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct rtw_evt_header));
12190 
12191 	if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL) {
12192 		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12193 		rtw_mfree((u8 *)pevtcmd, cmdsz);
12194 		return;
12195 	}
12196 
12197 	rtw_hidden_ssid_bss_count(padapter, &psurvey_evt->bss);
12198 
12199 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12200 
12201 	pmlmeext->sitesurvey_res.bss_cnt++;
12202 
12203 	return;
12204 
12205 }
12206 
12207 /*
12208 * @acs: aim to trigger channel selection
12209 */
report_surveydone_event(_adapter * padapter,bool acs)12210 void report_surveydone_event(_adapter *padapter, bool acs)
12211 {
12212 	struct cmd_obj *pcmd_obj;
12213 	u8	*pevtcmd;
12214 	u32 cmdsz;
12215 	struct surveydone_event *psurveydone_evt;
12216 	struct rtw_evt_header *evt_hdr;
12217 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12218 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12219 
12220 	pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12221 	if (pcmd_obj == NULL)
12222 		return;
12223 
12224 	cmdsz = (sizeof(struct surveydone_event) + sizeof(struct rtw_evt_header));
12225 	pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12226 	if (pevtcmd == NULL) {
12227 		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12228 		return;
12229 	}
12230 
12231 	_rtw_init_listhead(&pcmd_obj->list);
12232 
12233 	pcmd_obj->cmdcode = CMD_SET_MLME_EVT;
12234 	pcmd_obj->cmdsz = cmdsz;
12235 	pcmd_obj->parmbuf = pevtcmd;
12236 
12237 	pcmd_obj->rsp = NULL;
12238 	pcmd_obj->rspsz  = 0;
12239 
12240 	evt_hdr = (struct rtw_evt_header *)(pevtcmd);
12241 	evt_hdr->len = sizeof(struct surveydone_event);
12242 	evt_hdr->id = EVT_SURVEY_DONE;
12243 	evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12244 
12245 	psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct rtw_evt_header));
12246 	psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
12247 	psurveydone_evt->activate_ch_cnt = pmlmeext->sitesurvey_res.activate_ch_cnt;
12248 	psurveydone_evt->acs = acs;
12249 
12250 	RTW_INFO("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter));
12251 
12252 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12253 
12254 	return;
12255 
12256 }
12257 
report_join_res(_adapter * padapter,int aid_res,u16 status)12258 u32 report_join_res(_adapter *padapter, int aid_res, u16 status)
12259 {
12260 	struct cmd_obj *pcmd_obj;
12261 	u8	*pevtcmd;
12262 	u32 cmdsz;
12263 	struct joinbss_event *pjoinbss_evt;
12264 	struct rtw_evt_header *evt_hdr;
12265 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12266 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12267 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12268 	u32 ret = _FAIL;
12269 
12270 	pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12271 	if (pcmd_obj == NULL)
12272 		goto exit;
12273 
12274 	cmdsz = (sizeof(struct joinbss_event) + sizeof(struct rtw_evt_header));
12275 	pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12276 	if (pevtcmd == NULL) {
12277 		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12278 		goto exit;
12279 	}
12280 
12281 	_rtw_init_listhead(&pcmd_obj->list);
12282 
12283 	pcmd_obj->cmdcode = CMD_SET_MLME_EVT;
12284 	pcmd_obj->cmdsz = cmdsz;
12285 	pcmd_obj->parmbuf = pevtcmd;
12286 
12287 	pcmd_obj->rsp = NULL;
12288 	pcmd_obj->rspsz  = 0;
12289 
12290 	evt_hdr = (struct rtw_evt_header *)(pevtcmd);
12291 	evt_hdr->len = sizeof(struct joinbss_event);
12292 	evt_hdr->id = EVT_JOINBSS;
12293 	evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12294 
12295 	pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct rtw_evt_header));
12296 	_rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
12297 	pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = aid_res;
12298 
12299 	RTW_INFO("report_join_res(%d, %u)\n", aid_res, status);
12300 
12301 
12302 	rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network, status);
12303 
12304 
12305 	ret = rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12306 
12307 exit:
12308 	return ret;
12309 }
12310 
report_wmm_edca_update(_adapter * padapter)12311 void report_wmm_edca_update(_adapter *padapter)
12312 {
12313 	struct cmd_obj *pcmd_obj;
12314 	u8 *pevtcmd;
12315 	u32 cmdsz;
12316 	struct wmm_event *pwmm_event;
12317 	struct rtw_evt_header *evt_hdr;
12318 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12319 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12320 
12321 	pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12322 	if (pcmd_obj == NULL)
12323 		return;
12324 
12325 	cmdsz = (sizeof(struct wmm_event) + sizeof(struct rtw_evt_header));
12326 	pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12327 	if (pevtcmd == NULL) {
12328 		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12329 		return;
12330 	}
12331 
12332 	_rtw_init_listhead(&pcmd_obj->list);
12333 
12334 	pcmd_obj->cmdcode = CMD_SET_MLME_EVT;
12335 	pcmd_obj->cmdsz = cmdsz;
12336 	pcmd_obj->parmbuf = pevtcmd;
12337 
12338 	pcmd_obj->rsp = NULL;
12339 	pcmd_obj->rspsz  = 0;
12340 
12341 	evt_hdr = (struct rtw_evt_header *)(pevtcmd);
12342 	evt_hdr->len = sizeof(struct wmm_event);
12343 	evt_hdr->id = EVT_WMM_UPDATE;
12344 	evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12345 
12346 	pwmm_event = (struct wmm_event *)(pevtcmd + sizeof(struct rtw_evt_header));
12347 	pwmm_event->wmm = 0;
12348 
12349 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12350 
12351 	return;
12352 
12353 }
12354 
report_del_sta_event(_adapter * padapter,unsigned char * MacAddr,unsigned short reason,bool enqueue,u8 locally_generated)12355 u32 report_del_sta_event(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, bool enqueue, u8 locally_generated)
12356 {
12357 	struct cmd_obj *pcmd_obj;
12358 	u8 *pevtcmd;
12359 	u32 cmdsz;
12360 	struct sta_info *psta;
12361 	int mac_id = -1;
12362 	struct stadel_event *pdel_sta_evt;
12363 	struct rtw_evt_header *evt_hdr;
12364 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12365 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12366 	u8 res = _SUCCESS;
12367 
12368 	/* prepare cmd parameter */
12369 	cmdsz = (sizeof(struct stadel_event) + sizeof(struct rtw_evt_header));
12370 	pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12371 	if (pevtcmd == NULL) {
12372 		res = _FAIL;
12373 		goto exit;
12374 	}
12375 
12376 	evt_hdr = (struct rtw_evt_header *)(pevtcmd);
12377 	evt_hdr->len = sizeof(struct stadel_event);
12378 	evt_hdr->id = EVT_DEL_STA;
12379 	evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12380 
12381 	pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct rtw_evt_header));
12382 	_rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
12383 	_rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
12384 	psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
12385 	if (psta)
12386 		mac_id = (int)psta->cmn.mac_id;
12387 	else
12388 		mac_id = (-1);
12389 	pdel_sta_evt->mac_id = mac_id;
12390 	pdel_sta_evt->locally_generated = locally_generated;
12391 
12392 	if (!enqueue) {
12393 		/* do directly */
12394 		rtw_stadel_event_callback(padapter, (u8 *)pdel_sta_evt);
12395 		rtw_mfree(pevtcmd, cmdsz);
12396 	} else {
12397 		pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12398 		if (pcmd_obj == NULL) {
12399 			rtw_mfree(pevtcmd, cmdsz);
12400 			res = _FAIL;
12401 			goto exit;
12402 		}
12403 
12404 		_rtw_init_listhead(&pcmd_obj->list);
12405 		pcmd_obj->cmdcode = CMD_SET_MLME_EVT;
12406 		pcmd_obj->cmdsz = cmdsz;
12407 		pcmd_obj->parmbuf = pevtcmd;
12408 
12409 		pcmd_obj->rsp = NULL;
12410 		pcmd_obj->rspsz  = 0;
12411 
12412 		res = rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12413 	}
12414 
12415 exit:
12416 
12417 	RTW_INFO(FUNC_ADPT_FMT" "MAC_FMT" mac_id=%d, enqueue:%d, res:%u\n"
12418 		, FUNC_ADPT_ARG(padapter), MAC_ARG(MacAddr), mac_id, enqueue, res);
12419 
12420 	return res;
12421 }
12422 
report_add_sta_event(_adapter * padapter,unsigned char * MacAddr)12423 void report_add_sta_event(_adapter *padapter, unsigned char *MacAddr)
12424 {
12425 	struct cmd_obj *pcmd_obj;
12426 	u8 *pevtcmd;
12427 	u32 cmdsz;
12428 	struct stassoc_event *padd_sta_evt;
12429 	struct rtw_evt_header *evt_hdr;
12430 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12431 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12432 
12433 	pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12434 	if (pcmd_obj == NULL)
12435 		return;
12436 
12437 	cmdsz = (sizeof(struct stassoc_event) + sizeof(struct rtw_evt_header));
12438 	pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12439 	if (pevtcmd == NULL) {
12440 		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12441 		return;
12442 	}
12443 
12444 	_rtw_init_listhead(&pcmd_obj->list);
12445 
12446 	pcmd_obj->cmdcode = CMD_SET_MLME_EVT;
12447 	pcmd_obj->cmdsz = cmdsz;
12448 	pcmd_obj->parmbuf = pevtcmd;
12449 
12450 	pcmd_obj->rsp = NULL;
12451 	pcmd_obj->rspsz  = 0;
12452 
12453 	evt_hdr = (struct rtw_evt_header *)(pevtcmd);
12454 	evt_hdr->len = sizeof(struct stassoc_event);
12455 	evt_hdr->id = EVT_ADD_STA;
12456 	evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12457 
12458 	padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct rtw_evt_header));
12459 	_rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
12460 
12461 	RTW_INFO("report_add_sta_event: add STA\n");
12462 
12463 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12464 
12465 	return;
12466 }
12467 
12468 
rtw_port_switch_chk(_adapter * adapter)12469 bool rtw_port_switch_chk(_adapter *adapter)
12470 {
12471 	bool switch_needed = _FALSE;
12472 #ifdef CONFIG_CONCURRENT_MODE
12473 #ifdef CONFIG_RUNTIME_PORT_SWITCH
12474 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12475 	struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj);
12476 	_adapter *if_port0 = NULL;
12477 	_adapter *if_port1 = NULL;
12478 	struct mlme_ext_info *if_port0_mlmeinfo = NULL;
12479 	struct mlme_ext_info *if_port1_mlmeinfo = NULL;
12480 	int i;
12481 
12482 	for (i = 0; i < dvobj->iface_nums; i++) {
12483 		if (get_hw_port(dvobj->padapters[i]) == HW_PORT0) {
12484 			if_port0 = dvobj->padapters[i];
12485 			if_port0_mlmeinfo = &(if_port0->mlmeextpriv.mlmext_info);
12486 		} else if (get_hw_port(dvobj->padapters[i]) == HW_PORT1) {
12487 			if_port1 = dvobj->padapters[i];
12488 			if_port1_mlmeinfo = &(if_port1->mlmeextpriv.mlmext_info);
12489 		}
12490 	}
12491 
12492 	if (if_port0 == NULL) {
12493 		rtw_warn_on(1);
12494 		goto exit;
12495 	}
12496 
12497 	if (if_port1 == NULL) {
12498 		rtw_warn_on(1);
12499 		goto exit;
12500 	}
12501 
12502 #ifdef DBG_RUNTIME_PORT_SWITCH
12503 	RTW_INFO(FUNC_ADPT_FMT" wowlan_mode:%u\n"
12504 		 ADPT_FMT", port0, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n"
12505 		 ADPT_FMT", port1, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n",
12506 		 FUNC_ADPT_ARG(adapter), pwrctl->wowlan_mode,
12507 		ADPT_ARG(if_port0), if_port0_mlmeinfo->state, rtw_p2p_state(&if_port0->wdinfo), rtw_p2p_chk_state(&if_port0->wdinfo, P2P_STATE_NONE),
12508 		ADPT_ARG(if_port1), if_port1_mlmeinfo->state, rtw_p2p_state(&if_port1->wdinfo), rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE));
12509 #endif /* DBG_RUNTIME_PORT_SWITCH */
12510 
12511 #ifdef CONFIG_WOWLAN
12512 	/* WOWLAN interface(primary, for now) should be port0 */
12513 	if (pwrctl->wowlan_mode == _TRUE) {
12514 		if (!is_primary_adapter(if_port0)) {
12515 			RTW_INFO("%s "ADPT_FMT" enable WOWLAN\n", __func__, ADPT_ARG(if_port1));
12516 			switch_needed = _TRUE;
12517 		}
12518 		goto exit;
12519 	}
12520 #endif /* CONFIG_WOWLAN */
12521 
12522 	/* AP/Mesh should use port0 for ctl frame's ack */
12523 	if ((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
12524 		RTW_INFO("%s "ADPT_FMT" is AP/GO/Mesh\n", __func__, ADPT_ARG(if_port1));
12525 		switch_needed = _TRUE;
12526 		goto exit;
12527 	}
12528 
12529 	/* GC should use port0 for p2p ps */
12530 	if (((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
12531 	    && (if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
12532 #ifdef CONFIG_P2P
12533 	    && !rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE)
12534 #endif
12535 	    && !check_fwstate(&if_port1->mlmepriv, WIFI_UNDER_WPS)
12536 	   ) {
12537 		RTW_INFO("%s "ADPT_FMT" is GC\n", __func__, ADPT_ARG(if_port1));
12538 		switch_needed = _TRUE;
12539 		goto exit;
12540 	}
12541 
12542 	/* port1 linked, but port0 not linked */
12543 	if ((if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
12544 	    && !(if_port0_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
12545 	    && ((if_port0_mlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
12546 	   ) {
12547 		RTW_INFO("%s "ADPT_FMT" is SINGLE_LINK\n", __func__, ADPT_ARG(if_port1));
12548 		switch_needed = _TRUE;
12549 		goto exit;
12550 	}
12551 
12552 exit:
12553 #ifdef DBG_RUNTIME_PORT_SWITCH
12554 	RTW_INFO(FUNC_ADPT_FMT" ret:%d\n", FUNC_ADPT_ARG(adapter), switch_needed);
12555 #endif /* DBG_RUNTIME_PORT_SWITCH */
12556 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
12557 #endif /* CONFIG_CONCURRENT_MODE */
12558 	return switch_needed;
12559 }
12560 
12561 /****************************************************************************
12562 
12563 Following are the event callback functions
12564 
12565 *****************************************************************************/
12566 
12567 /* for sta/adhoc mode */
update_sta_info(_adapter * padapter,struct sta_info * psta)12568 void update_sta_info(_adapter *padapter, struct sta_info *psta)
12569 {
12570 	_irqL	irqL;
12571 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
12572 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
12573 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12574 
12575 	/* ERP */
12576 	VCS_update(padapter, psta);
12577 
12578 #ifdef CONFIG_80211N_HT
12579 	/* HT */
12580 	if (pmlmepriv->htpriv.ht_option) {
12581 		psta->htpriv.ht_option = _TRUE;
12582 
12583 		psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
12584 
12585 		psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
12586 
12587 		if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20))
12588 			psta->htpriv.sgi_20m = _TRUE;
12589 
12590 		if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40))
12591 			psta->htpriv.sgi_40m = _TRUE;
12592 
12593 		psta->qos_option = _TRUE;
12594 
12595 		psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap;
12596 		psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap;
12597 		psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
12598 
12599 		_rtw_memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap));
12600 		#ifdef CONFIG_BEAMFORMING
12601 		psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
12602 		psta->cmn.bf_info.ht_beamform_cap = pmlmepriv->htpriv.beamform_cap;
12603 		#endif
12604 	} else
12605 #endif /* CONFIG_80211N_HT */
12606 	{
12607 #ifdef CONFIG_80211N_HT
12608 		psta->htpriv.ht_option = _FALSE;
12609 		psta->htpriv.ampdu_enable = _FALSE;
12610 		psta->htpriv.tx_amsdu_enable = _FALSE;
12611 		psta->htpriv.sgi_20m = _FALSE;
12612 		psta->htpriv.sgi_40m = _FALSE;
12613 #endif /* CONFIG_80211N_HT */
12614 		psta->qos_option = _FALSE;
12615 
12616 	}
12617 
12618 #ifdef CONFIG_80211N_HT
12619 	psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
12620 
12621 	psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
12622 	psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
12623 #endif /* CONFIG_80211N_HT */
12624 
12625 	psta->cmn.bw_mode = pmlmeext->cur_bwmode;
12626 
12627 	/* QoS */
12628 	if (pmlmepriv->qospriv.qos_option)
12629 		psta->qos_option = _TRUE;
12630 
12631 #ifdef CONFIG_80211AC_VHT
12632 	_rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));
12633 	if (psta->vhtpriv.vht_option) {
12634 		psta->cmn.ra_info.is_vht_enable = _TRUE;
12635 		#ifdef CONFIG_BEAMFORMING
12636 		psta->vhtpriv.beamform_cap = pmlmepriv->vhtpriv.beamform_cap;
12637 		psta->cmn.bf_info.vht_beamform_cap = pmlmepriv->vhtpriv.beamform_cap;
12638 		#endif /*CONFIG_BEAMFORMING*/
12639 	}
12640 #endif /* CONFIG_80211AC_VHT */
12641 	psta->cmn.ra_info.is_support_sgi = query_ra_short_GI(psta, rtw_get_tx_bw_mode(padapter, psta));
12642 	update_ldpc_stbc_cap(psta);
12643 
12644 	_enter_critical_bh(&psta->lock, &irqL);
12645 	psta->state = WIFI_ASOC_STATE;
12646 	_exit_critical_bh(&psta->lock, &irqL);
12647 
12648 }
12649 
12650 #ifdef CONFIG_80211D
rtw_joinbss_update_regulatory(_adapter * adapter,const WLAN_BSSID_EX * network)12651 static void rtw_joinbss_update_regulatory(_adapter *adapter, const WLAN_BSSID_EX *network)
12652 {
12653 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
12654 
12655 	if (rfctl->regd_src == REGD_SRC_RTK_PRIV
12656 		&& !rtw_rfctl_is_disable_sw_channel_plan(rfctl_to_dvobj(rfctl))
12657 	) {
12658 		struct mlme_priv *mlme = &adapter->mlmepriv;
12659 		const u8 *country_ie = NULL;
12660 		sint country_ie_len = 0;
12661 
12662 		if (network) {
12663 			if (rtw_iface_accept_country_ie(adapter)) {
12664 				country_ie = rtw_get_ie(BSS_EX_TLV_IES(network)
12665 					, WLAN_EID_COUNTRY, &country_ie_len, BSS_EX_TLV_IES_LEN(network));
12666 				if (country_ie) {
12667 					if (country_ie_len < 6) {
12668 						country_ie = NULL;
12669 						country_ie_len = 0;
12670 					} else
12671 						country_ie_len += 2;
12672 				}
12673 			}
12674 		}
12675 
12676 		if (country_ie) {
12677 			rtw_buf_update(&mlme->recv_country_ie, &mlme->recv_country_ie_len, country_ie, country_ie_len);
12678 			if (rtw_apply_recv_country_ie_cmd(adapter, RTW_CMDF_DIRECTLY
12679 				, network->Configuration.DSConfig > 14 ? BAND_ON_5G : BAND_ON_2_4G
12680 				, network->Configuration.DSConfig, country_ie) != _SUCCESS
12681 			)
12682 				RTW_WARN(FUNC_ADPT_FMT" rtw_apply_recv_country_ie_cmd() fail\n", FUNC_ADPT_ARG(adapter));
12683 		} else
12684 			rtw_buf_free(&mlme->recv_country_ie, &mlme->recv_country_ie_len);
12685 	}
12686 }
12687 
rtw_leavebss_update_regulatory(_adapter * adapter)12688 static void rtw_leavebss_update_regulatory(_adapter *adapter)
12689 {
12690 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12691 	struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj);
12692 
12693 	if (rfctl->regd_src == REGD_SRC_RTK_PRIV
12694 		&& !rtw_rfctl_is_disable_sw_channel_plan(dvobj)
12695 	) {
12696 		if (rtw_apply_recv_country_ie_cmd(adapter, RTW_CMDF_DIRECTLY, 0, 0, NULL) != _SUCCESS)
12697 			RTW_WARN(FUNC_ADPT_FMT" rtw_apply_recv_country_ie_cmd() fail\n", FUNC_ADPT_ARG(adapter));
12698 	}
12699 }
12700 #endif /* CONFIG_80211D */
12701 
rtw_mlmeext_disconnect(_adapter * padapter)12702 static void rtw_mlmeext_disconnect(_adapter *padapter)
12703 {
12704 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
12705 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
12706 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12707 	u8 self_action = MLME_ACTION_UNKNOWN;
12708 	u8 state_backup = (pmlmeinfo->state & 0x03);
12709 	u8 ASIX_ID[] = {0x00, 0x0E, 0xC6};
12710 
12711 	if (MLME_IS_AP(padapter))
12712 		self_action = MLME_AP_STOPPED;
12713 	else if (MLME_IS_MESH(padapter))
12714 		self_action = MLME_MESH_STOPPED;
12715 	else if (MLME_IS_STA(padapter))
12716 		self_action = MLME_STA_DISCONNECTED;
12717 	else if (MLME_IS_ADHOC(padapter) || MLME_IS_ADHOC_MASTER(padapter))
12718 		self_action = MLME_ADHOC_STOPPED;
12719 	else {
12720 		RTW_INFO("state:0x%x\n", MLME_STATE(padapter));
12721 		rtw_warn_on(1);
12722 	}
12723 
12724 	/* set_opmode_cmd(padapter, infra_client_with_mlme); */
12725 #ifdef CONFIG_HW_P0_TSF_SYNC
12726 	if (self_action == MLME_STA_DISCONNECTED)
12727 		correct_TSF(padapter, self_action);
12728 #endif
12729 	rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
12730 	rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
12731 	if (self_action == MLME_STA_DISCONNECTED)
12732 		rtw_hal_rcr_set_chk_bssid(padapter, self_action);
12733 
12734 	/* set MSR to no link state->infra. mode */
12735 	Set_MSR(padapter, _HW_STATE_STATION_);
12736 
12737 	/* check if sta is ASIX peer and fix IOT issue if it is. */
12738 	if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) , ASIX_ID , 3)) {
12739 		u8 iot_flag = _FALSE;
12740 		rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
12741 	}
12742 	pmlmeinfo->state = WIFI_FW_NULL_STATE;
12743 
12744 #ifdef CONFIG_MCC_MODE
12745 	/* mcc disconnect setting before download LPS rsvd page */
12746 	rtw_hal_set_mcc_setting_disconnect(padapter);
12747 #endif /* CONFIG_MCC_MODE */
12748 
12749 	if (state_backup == WIFI_FW_STATION_STATE) {
12750 		if (rtw_port_switch_chk(padapter) == _TRUE) {
12751 			rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12752 #ifdef CONFIG_LPS
12753 			{
12754 				_adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
12755 				if (port0_iface)
12756 					rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, RTW_CMDF_DIRECTLY);
12757 			}
12758 #endif
12759 		}
12760 	}
12761 
12762 	/* switch to the 20M Hz mode after disconnect */
12763 	pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
12764 	pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
12765 #ifdef CONFIG_CTRL_TXSS_BY_TP
12766 	pmlmeext->txss_1ss = _FALSE;
12767 #endif
12768 
12769 #ifdef CONFIG_FCS_MODE
12770 	if (EN_FCS(padapter))
12771 		rtw_hal_set_hwreg(padapter, HW_VAR_STOP_FCS_MODE, NULL);
12772 #endif
12773 
12774 #ifdef CONFIG_80211D
12775 	if (self_action == MLME_STA_DISCONNECTED)
12776 		rtw_leavebss_update_regulatory(padapter);
12777 #endif
12778 
12779 	#ifdef CONFIG_DFS_MASTER
12780 	if (!CHK_MLME_STATE(padapter, WIFI_AP_STATE | WIFI_MESH_STATE | WIFI_OP_CH_SWITCHING)) {
12781 		/* radar detect status no need to check here for AP/MESH or iface under OPCH_SW */
12782 		rtw_dfs_rd_en_decision(padapter, self_action, 0);
12783 	}
12784 	#endif
12785 
12786 	if (!MLME_IS_OPCH_SW(padapter)) {
12787 		/* channel status no need to check here for iface under OPCH_SW */
12788 		u8 ch, bw, offset;
12789 
12790 		if (rtw_mi_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0)
12791 			set_channel_bwmode(padapter, ch, offset, bw);
12792 		rtw_mi_update_union_chan_inf(padapter, ch, offset, bw);
12793 		rtw_rfctl_update_op_mode(adapter_to_rfctl(padapter), BIT(padapter->iface_id), 0);
12794 	}
12795 
12796 	flush_all_cam_entry(padapter);
12797 
12798 	_cancel_timer_ex(&pmlmeext->link_timer);
12799 
12800 	/* pmlmepriv->LinkDetectInfo.TrafficBusyState = _FALSE; */
12801 	pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
12802 	pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
12803 
12804 #ifdef CONFIG_TDLS
12805 	padapter->tdlsinfo.ap_prohibited = _FALSE;
12806 
12807 	/* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */
12808 	if (padapter->registrypriv.wifi_spec == 1)
12809 		padapter->tdlsinfo.ch_switch_prohibited = _FALSE;
12810 #endif /* CONFIG_TDLS */
12811 
12812 #ifdef CONFIG_WMMPS_STA
12813 	 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
12814 		/* reset currently related uapsd setting when the connection has broken */
12815 		pmlmepriv->qospriv.uapsd_max_sp_len = 0;
12816 		pmlmepriv->qospriv.uapsd_tid = 0;
12817 		pmlmepriv->qospriv.uapsd_tid_delivery_enabled = 0;
12818 		pmlmepriv->qospriv.uapsd_tid_trigger_enabled = 0;
12819 		pmlmepriv->qospriv.uapsd_ap_supported = 0;
12820 	}
12821 #endif /* CONFIG_WMMPS_STA */
12822 #ifdef CONFIG_RTS_FULL_BW
12823 	rtw_set_rts_bw(padapter);
12824 #endif/*CONFIG_RTS_FULL_BW*/
12825 
12826 	pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_UNKNOWN;
12827 	rtw_phydm_update_ap_vendor_ie(padapter);
12828 }
12829 
mlmeext_joinbss_event_callback(_adapter * padapter,int join_res)12830 void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
12831 {
12832 	struct sta_info		*psta;
12833 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
12834 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12835 	WLAN_BSSID_EX		*cur_network = &(pmlmeinfo->network);
12836 	struct sta_priv		*pstapriv = &padapter->stapriv;
12837 	u8	join_type;
12838 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
12839 
12840 #if (!defined(CONFIG_IOCTL_CFG80211)) || defined(CONFIG_LAYER2_ROAMING)
12841 	struct security_priv *psecuritypriv = &padapter->securitypriv;
12842 #endif
12843 
12844 	if (pmlmepriv->wpa_phase == _TRUE)
12845 		pmlmepriv->wpa_phase = _FALSE;
12846 
12847 	if (join_res < 0) {
12848 		join_type = 1;
12849 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12850 		rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
12851 		if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
12852 			rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_DISCONNECTED);
12853 
12854 		rtw_btcoex_connect_notify(padapter, join_type);
12855 		pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_UNKNOWN;
12856 		goto exit_mlmeext_joinbss_event_callback;
12857 	}
12858 
12859 #ifdef CONFIG_ARP_KEEP_ALIVE
12860 	pmlmepriv->bGetGateway = 1;
12861 	pmlmepriv->GetGatewayTryCnt = 0;
12862 #endif
12863 
12864 #ifdef CONFIG_AP_MODE
12865 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
12866 		/* update bc/mc sta_info */
12867 		update_bmc_sta(padapter);
12868 	}
12869 #endif
12870 
12871 	/* turn on dynamic functions */
12872 	/* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */
12873 
12874 	/* update IOT-releated issue */
12875 	update_IOT_info(padapter);
12876 
12877 	#ifdef CONFIG_RTS_FULL_BW
12878 	rtw_set_rts_bw(padapter);
12879 	#endif/*CONFIG_RTS_FULL_BW*/
12880 
12881 	rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
12882 
12883 	/* BCN interval */
12884 	rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
12885 
12886 	/* udpate capability */
12887 	update_capinfo(padapter, pmlmeinfo->capability);
12888 
12889 	/* WMM, Update EDCA param */
12890 	WMMOnAssocRsp(padapter);
12891 #ifdef CONFIG_80211N_HT
12892 	/* HT */
12893 	HTOnAssocRsp(padapter);
12894 #endif /* CONFIG_80211N_HT */
12895 #ifdef CONFIG_80211AC_VHT
12896 	/* VHT */
12897 	VHTOnAssocRsp(padapter);
12898 #endif
12899 
12900 	psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
12901 	if (psta) { /* only for infra. mode */
12902 		psta->wireless_mode = pmlmeext->cur_wireless_mode;
12903 
12904 		/* set per sta rate after updating HT cap. */
12905 		set_sta_rate(padapter, psta);
12906 
12907 		rtw_sta_media_status_rpt(padapter, psta, 1);
12908 
12909 		/* wakeup macid after join bss successfully to ensure
12910 			the subsequent data frames can be sent out normally */
12911 		rtw_hal_macid_wakeup(padapter, psta->cmn.mac_id);
12912 
12913 		rtw_xmit_queue_clear(psta);
12914 	}
12915 
12916 #ifndef CONFIG_IOCTL_CFG80211
12917 	if (is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm))
12918 		rtw_sec_restore_wep_key(padapter);
12919 #endif /* CONFIG_IOCTL_CFG80211 */
12920 
12921 	if (rtw_port_switch_chk(padapter) == _TRUE)
12922 		rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12923 
12924 	join_type = 2;
12925 	rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12926 
12927 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
12928 		rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_CONNECTED);
12929 
12930 		/* correcting TSF */
12931 		correct_TSF(padapter, MLME_STA_CONNECTED);
12932 
12933 		/* set_link_timer(pmlmeext, DISCONNECT_TO); */
12934 	}
12935 
12936 #ifdef CONFIG_LPS
12937 	#ifndef CONFIG_FW_MULTI_PORT_SUPPORT
12938 	if (get_hw_port(padapter) == HW_PORT0)
12939 	#endif
12940 		rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, RTW_CMDF_DIRECTLY);
12941 #endif
12942 
12943 	rtw_btcoex_connect_notify(padapter, join_type);
12944 
12945 #ifdef CONFIG_BEAMFORMING
12946 	if (psta)
12947 		beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
12948 #endif/*CONFIG_BEAMFORMING*/
12949 
12950 exit_mlmeext_joinbss_event_callback:
12951 
12952 	rtw_phydm_update_ap_vendor_ie(padapter);
12953 
12954 	rtw_join_done_chk_ch(padapter, join_res);
12955 #ifdef CONFIG_RTW_REPEATER_SON
12956 	rtw_rson_join_done(padapter);
12957 #endif
12958 
12959 #ifdef CONFIG_LAYER2_ROAMING
12960 	if ((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_) &&
12961 		(pmlmepriv->roam_network)) {
12962 		struct xmit_frame *rframe;
12963 		struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
12964 		_list *plist, *phead;
12965 		_irqL irqL;
12966 		_pkt *pkt;
12967 
12968 		padapter->mlmepriv.roam_network = NULL;
12969 		_enter_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL);
12970 		phead = get_list_head(&pxmitpriv->rpkt_queue);
12971 		plist = get_next(phead);
12972 		while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
12973 			rframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
12974 			plist = get_next(plist);
12975 			rtw_list_delete(&rframe->list);
12976 			pkt = rframe->pkt;
12977 			rtw_xmit_posthandle(padapter, rframe, pkt);
12978 		}
12979 		_exit_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL);
12980 	}
12981 #endif
12982 	RTW_INFO("=>%s - End to Connection without 4-way\n", __FUNCTION__);
12983 }
12984 
12985 /* currently only adhoc mode will go here */
mlmeext_sta_add_event_callback(_adapter * padapter,struct sta_info * psta)12986 void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
12987 {
12988 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
12989 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
12990 	u8	join_type;
12991 
12992 	RTW_INFO("%s\n", __FUNCTION__);
12993 
12994 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
12995 		if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { /* adhoc master or sta_count>1 */
12996 			/* nothing to do */
12997 		} else { /* adhoc client */
12998 			#ifdef CONFIG_AP_MODE
12999 			/* update TSF Value */
13000 			/* update_TSF(pmlmeext, pframe, len);			 */
13001 
13002 			/* correcting TSF */
13003 			correct_TSF(padapter, MLME_ADHOC_STARTED);
13004 
13005 			/* start beacon */
13006 			if (send_beacon(padapter) == _FAIL)
13007 				rtw_warn_on(1);
13008 
13009 			pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
13010 			#endif
13011 		}
13012 
13013 		join_type = 2;
13014 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
13015 
13016 		rtw_btcoex_connect_notify(padapter, join_type);
13017 	}
13018 
13019 	/* update adhoc sta_info */
13020 	update_sta_info(padapter, psta);
13021 
13022 	rtw_hal_update_sta_ra_info(padapter, psta);
13023 
13024 	/* ToDo: HT for Ad-hoc */
13025 	psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel);
13026 	rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
13027 
13028 	/* rate radaptive */
13029 	Update_RA_Entry(padapter, psta);
13030 }
13031 
mlmeext_sta_del_event_callback(_adapter * padapter)13032 void mlmeext_sta_del_event_callback(_adapter *padapter)
13033 {
13034 	if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
13035 		rtw_mlmeext_disconnect(padapter);
13036 }
13037 
13038 /****************************************************************************
13039 
13040 Following are the functions for the timer handlers
13041 
13042 *****************************************************************************/
_linked_info_dump(_adapter * padapter)13043 void _linked_info_dump(_adapter *padapter)
13044 {
13045 	if (padapter->bLinkInfoDump) {
13046 		rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, RTW_DBGDUMP);
13047 		rtw_hal_set_odm_var(padapter, HAL_ODM_RX_INFO_DUMP, RTW_DBGDUMP, _FALSE);
13048 	}
13049 }
13050 /********************************************************************
13051 
13052 When station does not receive any packet in MAX_CONTINUAL_NORXPACKET_COUNT*2 seconds,
13053 recipient station will teardown the block ack by issuing DELBA frame.
13054 
13055 *********************************************************************/
rtw_delba_check(_adapter * padapter,struct sta_info * psta,u8 from_timer)13056 void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer)
13057 {
13058 	int	i = 0;
13059 	int ret = _SUCCESS;
13060 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
13061 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
13062 
13063 	/*
13064 		IOT issue,occur Broadcom ap(Buffalo WZR-D1800H,Netgear R6300).
13065 		AP is originator.AP does not transmit unicast packets when STA response its BAR.
13066 		This case probably occur ap issue BAR after AP builds BA.
13067 
13068 		Follow 802.11 spec, STA shall maintain an inactivity timer for every negotiated Block Ack setup.
13069 		The inactivity timer is not reset when MPDUs corresponding to other TIDs are received.
13070 	*/
13071 	if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM) {
13072 		for (i = 0; i < TID_NUM ; i++) {
13073 			if ((psta->recvreorder_ctrl[i].enable) &&
13074                         (sta_rx_data_qos_pkts(psta, i) == sta_last_rx_data_qos_pkts(psta, i)) ) {
13075 					if (_TRUE == rtw_inc_and_chk_continual_no_rx_packet(psta, i)) {
13076 						/* send a DELBA frame to the peer STA with the Reason Code field set to TIMEOUT */
13077 						if (!from_timer)
13078 							ret = issue_del_ba_ex(padapter, psta->cmn.mac_addr, i, 39, 0, 3, 1);
13079 						else
13080 							issue_del_ba(padapter,  psta->cmn.mac_addr, i, 39, 0);
13081 						psta->recvreorder_ctrl[i].enable = _FALSE;
13082 						if (ret != _FAIL)
13083 							psta->recvreorder_ctrl[i].ampdu_size = RX_AMPDU_SIZE_INVALID;
13084 						rtw_reset_continual_no_rx_packet(psta, i);
13085 					}
13086 			} else {
13087 				/* The inactivity timer is reset when MPDUs to the TID is received. */
13088 				rtw_reset_continual_no_rx_packet(psta, i);
13089 			}
13090 		}
13091 	}
13092 }
13093 
13094 
chk_ap_is_alive(_adapter * padapter,struct sta_info * psta)13095 u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
13096 {
13097 	u8 ret = _FALSE;
13098 #ifdef DBG_EXPIRATION_CHK
13099 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
13100 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
13101 
13102 	RTW_INFO(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
13103 		/*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
13104 		 ", retry:%u\n"
13105 		 , FUNC_ADPT_ARG(padapter)
13106 		 , STA_RX_PKTS_DIFF_ARG(psta)
13107 		, psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
13108 		, psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
13109 		/*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
13110 		, psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
13111 		, psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
13112 		 , pmlmeinfo->bcn_interval*/
13113 		 , pmlmeext->retry
13114 		);
13115 
13116 	RTW_INFO(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
13117 		 , sta_tx_pkts(psta)
13118 		 , pmlmeinfo->link_count
13119 		);
13120 #endif
13121 
13122 	if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
13123 	    && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
13124 	    && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
13125 	   )
13126 		ret = _FALSE;
13127 	else
13128 		ret = _TRUE;
13129 
13130 	sta_update_last_rx_pkts(psta);
13131 
13132 	return ret;
13133 }
13134 
chk_adhoc_peer_is_alive(struct sta_info * psta)13135 u8 chk_adhoc_peer_is_alive(struct sta_info *psta)
13136 {
13137 	u8 ret = _TRUE;
13138 
13139 #ifdef DBG_EXPIRATION_CHK
13140 	RTW_INFO("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
13141 		/*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
13142 		 ", expire_to:%u\n"
13143 		 , MAC_ARG(psta->cmn.mac_addr)
13144 		 , psta->cmn.rssi_stat.rssi
13145 		 , STA_RX_PKTS_DIFF_ARG(psta)
13146 		, psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
13147 		, psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
13148 		/*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
13149 		, psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
13150 		, psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
13151 		 , pmlmeinfo->bcn_interval*/
13152 		 , psta->expire_to
13153 		);
13154 #endif
13155 
13156 	if (sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)
13157 	    && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
13158 	    && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
13159 		ret = _FALSE;
13160 
13161 	sta_update_last_rx_pkts(psta);
13162 
13163 	return ret;
13164 }
13165 
13166 #ifdef CONFIG_TDLS
chk_tdls_peer_sta_is_alive(_adapter * padapter,struct sta_info * psta)13167 u8 chk_tdls_peer_sta_is_alive(_adapter *padapter, struct sta_info *psta)
13168 {
13169 	if ((psta->sta_stats.rx_data_pkts == psta->sta_stats.last_rx_data_pkts)
13170 	    && (psta->sta_stats.rx_tdls_disc_rsp_pkts == psta->sta_stats.last_rx_tdls_disc_rsp_pkts))
13171 		return _FALSE;
13172 
13173 	return _TRUE;
13174 }
13175 
linked_status_chk_tdls(_adapter * padapter)13176 void linked_status_chk_tdls(_adapter *padapter)
13177 {
13178 	struct candidate_pool {
13179 		struct sta_info *psta;
13180 		u8 addr[ETH_ALEN];
13181 	};
13182 	struct sta_priv *pstapriv = &padapter->stapriv;
13183 	_irqL irqL;
13184 	u8 ack_chk;
13185 	struct sta_info *psta;
13186 	int i, num_teardown = 0, num_checkalive = 0;
13187 	_list	*plist, *phead;
13188 	struct tdls_txmgmt txmgmt;
13189 	struct candidate_pool checkalive[MAX_ALLOWED_TDLS_STA_NUM];
13190 	struct candidate_pool teardown[MAX_ALLOWED_TDLS_STA_NUM];
13191 	u8 tdls_sta_max = _FALSE;
13192 
13193 #define ALIVE_MIN 2
13194 #define ALIVE_MAX 5
13195 
13196 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
13197 	_rtw_memset(checkalive, 0x00, sizeof(checkalive));
13198 	_rtw_memset(teardown, 0x00, sizeof(teardown));
13199 
13200 	if ((padapter->tdlsinfo.link_established == _TRUE)) {
13201 		_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13202 		for (i = 0; i < NUM_STA; i++) {
13203 			phead = &(pstapriv->sta_hash[i]);
13204 			plist = get_next(phead);
13205 
13206 			while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
13207 				psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
13208 				plist = get_next(plist);
13209 
13210 				if (psta->tdls_sta_state & TDLS_LINKED_STATE) {
13211 					psta->alive_count++;
13212 					if (psta->alive_count >= ALIVE_MIN) {
13213 						if (chk_tdls_peer_sta_is_alive(padapter, psta) == _FALSE) {
13214 							if (psta->alive_count < ALIVE_MAX) {
13215 								_rtw_memcpy(checkalive[num_checkalive].addr, psta->cmn.mac_addr, ETH_ALEN);
13216 								checkalive[num_checkalive].psta = psta;
13217 								num_checkalive++;
13218 							} else {
13219 								_rtw_memcpy(teardown[num_teardown].addr, psta->cmn.mac_addr, ETH_ALEN);
13220 								teardown[num_teardown].psta = psta;
13221 								num_teardown++;
13222 							}
13223 						} else
13224 							psta->alive_count = 0;
13225 					}
13226 					psta->sta_stats.last_rx_data_pkts = psta->sta_stats.rx_data_pkts;
13227 					psta->sta_stats.last_rx_tdls_disc_rsp_pkts = psta->sta_stats.rx_tdls_disc_rsp_pkts;
13228 
13229 					if ((num_checkalive >= MAX_ALLOWED_TDLS_STA_NUM) || (num_teardown >= MAX_ALLOWED_TDLS_STA_NUM)) {
13230 						tdls_sta_max = _TRUE;
13231 						break;
13232 					}
13233 				}
13234 			}
13235 
13236 			if (tdls_sta_max == _TRUE)
13237 				break;
13238 		}
13239 		_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13240 
13241 		if (num_checkalive > 0) {
13242 			for (i = 0; i < num_checkalive; i++) {
13243 				_rtw_memcpy(txmgmt.peer, checkalive[i].addr, ETH_ALEN);
13244 				issue_tdls_dis_req(padapter, &txmgmt);
13245 				issue_tdls_dis_req(padapter, &txmgmt);
13246 				issue_tdls_dis_req(padapter, &txmgmt);
13247 			}
13248 		}
13249 
13250 		if (num_teardown > 0) {
13251 			for (i = 0; i < num_teardown; i++) {
13252 				RTW_INFO("[%s %d] Send teardown to "MAC_FMT"\n", __FUNCTION__, __LINE__, MAC_ARG(teardown[i].addr));
13253 				txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
13254 				_rtw_memcpy(txmgmt.peer, teardown[i].addr, ETH_ALEN);
13255 				issue_tdls_teardown(padapter, &txmgmt, _FALSE);
13256 			}
13257 		}
13258 	}
13259 
13260 }
13261 #endif /* CONFIG_TDLS */
13262 
rtw_get_rx_chk_limit(_adapter * adapter)13263 inline int rtw_get_rx_chk_limit(_adapter *adapter)
13264 {
13265 	return adapter->stapriv.rx_chk_limit;
13266 }
13267 
rtw_set_rx_chk_limit(_adapter * adapter,int limit)13268 inline void rtw_set_rx_chk_limit(_adapter *adapter, int limit)
13269 {
13270 	adapter->stapriv.rx_chk_limit = limit;
13271 }
13272 
13273 /* from_timer == 1 means driver is in LPS */
linked_status_chk(_adapter * padapter,u8 from_timer)13274 void linked_status_chk(_adapter *padapter, u8 from_timer)
13275 {
13276 	u32	i;
13277 	struct sta_info		*psta;
13278 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
13279 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
13280 	struct sta_priv		*pstapriv = &padapter->stapriv;
13281 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
13282 #ifdef CONFIG_LAYER2_ROAMING
13283 	struct recv_priv	*precvpriv = &padapter->recvpriv;
13284 #endif
13285 
13286 #ifdef CONFIG_RTW_WDS
13287 	rtw_wds_gptr_expire(padapter);
13288 #endif
13289 
13290 	if (padapter->registrypriv.mp_mode == _TRUE)
13291 		return;
13292 
13293 	if (check_fwstate(pmlmepriv, WIFI_CSA_UPDATE_BEACON))
13294 		return;
13295 
13296 	if (is_client_associated_to_ap(padapter)) {
13297 		/* linked infrastructure client mode */
13298 
13299 		int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
13300 		int rx_chk_limit;
13301 		int link_count_limit;
13302 
13303 #if defined(CONFIG_RTW_REPEATER_SON)
13304 	rtw_rson_scan_wk_cmd(padapter, RSON_SCAN_PROCESS);
13305 #elif defined(CONFIG_LAYER2_ROAMING)
13306 		if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE)) {
13307 			RTW_INFO("signal_strength_data.avg_val = %d\n", precvpriv->signal_strength_data.avg_val);
13308 			if ((precvpriv->signal_strength_data.avg_val < pmlmepriv->roam_rssi_threshold)
13309 				&& (rtw_get_passing_time_ms(pmlmepriv->last_roaming) >= pmlmepriv->roam_scan_int*2000)) {
13310 #ifdef CONFIG_RTW_80211K
13311 				rtw_roam_nb_discover(padapter, _FALSE);
13312 #endif
13313 				pmlmepriv->need_to_roam = _TRUE;
13314 				rtw_drv_scan_by_self(padapter, RTW_AUTO_SCAN_REASON_ROAM);
13315 				pmlmepriv->last_roaming = rtw_get_current_time();
13316 			} else
13317 				pmlmepriv->need_to_roam = _FALSE;
13318 		}
13319 #endif
13320 #ifdef CONFIG_MCC_MODE
13321 		/*
13322 		 * due to tx ps null date to ao, so ap doest not tx pkt to driver
13323 		 * we may check chk_ap_is_alive fail, and may issue_probereq to wrong channel under sitesurvey
13324 		 * don't keep alive check under MCC
13325 		 */
13326 		if (rtw_hal_mcc_link_status_chk(padapter, __func__) == _FALSE)
13327 			return;
13328 #endif
13329 
13330 		rx_chk_limit = rtw_get_rx_chk_limit(padapter);
13331 
13332 #ifdef CONFIG_ARP_KEEP_ALIVE
13333 		if (!from_timer && pmlmepriv->bGetGateway == 1 && pmlmepriv->GetGatewayTryCnt < 3) {
13334 			RTW_INFO("do rtw_gw_addr_query() : %d\n", pmlmepriv->GetGatewayTryCnt);
13335 			pmlmepriv->GetGatewayTryCnt++;
13336 			if (rtw_gw_addr_query(padapter) == 0)
13337 				pmlmepriv->bGetGateway = 0;
13338 			else {
13339 				_rtw_memset(pmlmepriv->gw_ip, 0, 4);
13340 				_rtw_memset(pmlmepriv->gw_mac_addr, 0, ETH_ALEN);
13341 			}
13342 		}
13343 #endif
13344 #ifdef CONFIG_P2P
13345 		if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) {
13346 			if (!from_timer)
13347 				link_count_limit = 3; /* 8 sec */
13348 			else
13349 				link_count_limit = 15; /* 32 sec */
13350 		} else
13351 #endif /* CONFIG_P2P */
13352 		{
13353 			if (!from_timer)
13354 				link_count_limit = 7; /* 16 sec */
13355 			else
13356 				link_count_limit = 29; /* 60 sec */
13357 		}
13358 
13359 #ifdef CONFIG_TDLS
13360 #ifdef CONFIG_TDLS_CH_SW
13361 		if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
13362 			return;
13363 #endif /* CONFIG_TDLS_CH_SW */
13364 
13365 #ifdef CONFIG_TDLS_AUTOCHECKALIVE
13366 		linked_status_chk_tdls(padapter);
13367 #endif /* CONFIG_TDLS_AUTOCHECKALIVE */
13368 #endif /* CONFIG_TDLS */
13369 
13370 		psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
13371 		if (psta != NULL) {
13372 			bool is_p2p_enable = _FALSE;
13373 #ifdef CONFIG_P2P
13374 			is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
13375 #endif
13376 
13377 #ifdef CONFIG_ISSUE_DELBA_WHEN_NO_TRAFFIC
13378 			/*issue delba when ap does not tx data packet that is Broadcom ap */
13379 			rtw_delba_check(padapter, psta, from_timer);
13380 #endif
13381 			if (chk_ap_is_alive(padapter, psta) == _FALSE)
13382 				rx_chk = _FAIL;
13383 
13384 			if (sta_last_tx_pkts(psta) == sta_tx_pkts(psta))
13385 				tx_chk = _FAIL;
13386 
13387 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
13388 			if (!from_timer && pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)
13389 			) {
13390 				u8 backup_ch = 0, backup_bw = 0, backup_offset = 0;
13391 				u8 union_ch = 0, union_bw = 0, union_offset = 0;
13392 				u8 switch_channel_by_drv = _TRUE;
13393 
13394 
13395 #ifdef CONFIG_MCC_MODE
13396 				if (MCC_EN(padapter)) {
13397 					/* driver doesn't switch channel under MCC */
13398 					if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC))
13399 						switch_channel_by_drv = _FALSE;
13400 				}
13401 #endif
13402 				if (switch_channel_by_drv) {
13403 					if (!rtw_mi_get_ch_setting_union(padapter, &union_ch, &union_bw, &union_offset)
13404 						|| pmlmeext->cur_channel != union_ch)
13405 							goto bypass_active_keep_alive;
13406 
13407 					/* switch to correct channel of current network  before issue keep-alive frames */
13408 					if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
13409 						backup_ch = rtw_get_oper_ch(padapter);
13410 						backup_bw = rtw_get_oper_bw(padapter);
13411 						backup_offset = rtw_get_oper_choffset(padapter);
13412 						set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
13413 					}
13414 				}
13415 
13416 				if (rx_chk != _SUCCESS)
13417 					issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->cmn.mac_addr, 0, 0, 3, 1);
13418 
13419 				if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) || rx_chk != _SUCCESS) {
13420 					if (rtw_mi_check_fwstate(padapter, WIFI_UNDER_SURVEY))
13421 						tx_chk = issue_nulldata(padapter, psta->cmn.mac_addr, 1, 3, 1);
13422 					else
13423 						tx_chk = issue_nulldata(padapter, psta->cmn.mac_addr, 0, 3, 1);
13424 					/* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
13425 					if (tx_chk == _SUCCESS && !is_p2p_enable)
13426 						rx_chk = _SUCCESS;
13427 				}
13428 
13429 				/* back to the original operation channel */
13430 				if (backup_ch > 0 && switch_channel_by_drv)
13431 					set_channel_bwmode(padapter, backup_ch, backup_offset, backup_bw);
13432 
13433 bypass_active_keep_alive:
13434 				;
13435 			} else
13436 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
13437 			{
13438 				if (rx_chk != _SUCCESS) {
13439 					if (pmlmeext->retry == 0) {
13440 #ifdef DBG_EXPIRATION_CHK
13441 						RTW_INFO("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
13442 #endif
13443 						issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, (from_timer ? 0 : 1));
13444 						issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, (from_timer ? 0 : 1));
13445 						issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, (from_timer ? 0 : 1));
13446 					}
13447 				}
13448 
13449 				if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit
13450 #ifdef CONFIG_MCC_MODE
13451 				    /* FW tx nulldata under MCC mode, we just check  ap is alive */
13452 				    && (!rtw_hal_check_mcc_status(padapter, MCC_STATUS_NEED_MCC))
13453 #endif /* CONFIG_MCC_MODE */
13454 				) {
13455 					#ifdef DBG_EXPIRATION_CHK
13456 					RTW_INFO("%s issue_nulldata(%d)\n", __FUNCTION__, from_timer ? 1 : 0);
13457 					#endif
13458 					if (from_timer || rtw_mi_check_fwstate(padapter, WIFI_UNDER_SURVEY))
13459 						tx_chk = issue_nulldata(padapter, NULL, 1, 0, 0);
13460 					else
13461 						tx_chk = issue_nulldata(padapter, NULL, 0, 1, 1);
13462 				}
13463 			}
13464 
13465 			if (rx_chk == _FAIL) {
13466 				pmlmeext->retry++;
13467 				if (pmlmeext->retry > rx_chk_limit) {
13468 					RTW_PRINT(FUNC_ADPT_FMT" disconnect or roaming\n",
13469 						  FUNC_ADPT_ARG(padapter));
13470 					receive_disconnect(padapter, pmlmeinfo->network.MacAddress
13471 						, WLAN_REASON_EXPIRATION_CHK, _FALSE);
13472 					return;
13473 				}
13474 			} else
13475 				pmlmeext->retry = 0;
13476 
13477 			if (tx_chk == _FAIL)
13478 				pmlmeinfo->link_count %= (link_count_limit + 1);
13479 			else {
13480 				psta->sta_stats.last_tx_pkts = psta->sta_stats.tx_pkts;
13481 				pmlmeinfo->link_count = 0;
13482 			}
13483 
13484 		} /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */
13485 
13486 	} else if (is_client_associated_to_ibss(padapter)) {
13487 		_irqL irqL;
13488 		_list *phead, *plist, dlist;
13489 
13490 		_rtw_init_listhead(&dlist);
13491 
13492 		_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13493 
13494 		for (i = 0; i < NUM_STA; i++) {
13495 
13496 			phead = &(pstapriv->sta_hash[i]);
13497 			plist = get_next(phead);
13498 			while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
13499 				psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
13500 				plist = get_next(plist);
13501 
13502 				if (is_broadcast_mac_addr(psta->cmn.mac_addr))
13503 					continue;
13504 
13505 				if (chk_adhoc_peer_is_alive(psta) || !psta->expire_to)
13506 					psta->expire_to = pstapriv->adhoc_expire_to;
13507 				else
13508 					psta->expire_to--;
13509 
13510 				if (psta->expire_to <= 0) {
13511 					rtw_list_delete(&psta->list);
13512 					rtw_list_insert_tail(&psta->list, &dlist);
13513 				}
13514 			}
13515 		}
13516 
13517 		_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13518 
13519 		plist = get_next(&dlist);
13520 		while (rtw_end_of_queue_search(&dlist, plist) == _FALSE) {
13521 			psta = LIST_CONTAINOR(plist, struct sta_info, list);
13522 			plist = get_next(plist);
13523 			rtw_list_delete(&psta->list);
13524 			RTW_INFO(FUNC_ADPT_FMT" ibss expire "MAC_FMT"\n"
13525 				, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
13526 			report_del_sta_event(padapter, psta->cmn.mac_addr, WLAN_REASON_EXPIRATION_CHK, from_timer ? _TRUE : _FALSE, _FALSE);
13527 		}
13528 	}
13529 
13530 }
13531 
survey_timer_hdl(void * ctx)13532 void survey_timer_hdl(void *ctx)
13533 {
13534 	_adapter *padapter = (_adapter *)ctx;
13535 	struct cmd_obj *cmd;
13536 	struct sitesurvey_parm *psurveyPara;
13537 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
13538 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13539 
13540 	if (mlmeext_scan_state(pmlmeext) > SCAN_DISABLE) {
13541 		cmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
13542 		if (cmd == NULL) {
13543 			rtw_warn_on(1);
13544 			goto exit;
13545 		}
13546 
13547 		psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm));
13548 		if (psurveyPara == NULL) {
13549 			rtw_warn_on(1);
13550 			rtw_mfree((unsigned char *)cmd, sizeof(struct cmd_obj));
13551 			goto exit;
13552 		}
13553 
13554 		init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, CMD_SITE_SURVEY);
13555 		rtw_enqueue_cmd(pcmdpriv, cmd);
13556 	}
13557 
13558 exit:
13559 	return;
13560 }
13561 
13562 #ifdef CONFIG_RTW_REPEATER_SON
13563 /*	 100ms pass, stop rson_scan	*/
rson_timer_hdl(void * ctx)13564 void rson_timer_hdl(void *ctx)
13565 {
13566 	_adapter *padapter = (_adapter *)ctx;
13567 
13568 	rtw_rson_scan_wk_cmd(padapter, RSON_SCAN_DISABLE);
13569 }
13570 
13571 #endif
13572 
13573 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
rtw_tbtx_xmit_timer_hdl(void * ctx)13574 void rtw_tbtx_xmit_timer_hdl(void *ctx)
13575 {
13576 	_adapter *padapter = (_adapter *)ctx;
13577 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
13578 
13579 	if (ATOMIC_READ(&padapter->tbtx_remove_tx_pause) == _TRUE){
13580 		ATOMIC_SET(&padapter->tbtx_tx_pause, _FALSE);
13581 		rtw_tx_control_cmd(padapter);
13582 	}else {
13583 		rtw_issue_action_token_rel(padapter);
13584 		ATOMIC_SET(&padapter->tbtx_tx_pause, _TRUE);
13585 		rtw_tx_control_cmd(padapter);
13586 		_set_timer(&pmlmeext->tbtx_xmit_timer, MAX_TXPAUSE_DURATION);
13587 		ATOMIC_SET(&padapter->tbtx_remove_tx_pause, _TRUE);
13588 	}
13589 }
13590 
13591 #ifdef CONFIG_AP_MODE
rtw_tbtx_token_dispatch_timer_hdl(void * ctx)13592 void rtw_tbtx_token_dispatch_timer_hdl(void *ctx)
13593 {
13594 	_adapter *padapter = (_adapter *)ctx;
13595 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
13596 	_irqL irqL;
13597 	struct sta_info *psta = NULL;
13598 	struct sta_priv *pstapriv = &padapter->stapriv;
13599 	_list *phead, *plist;
13600 	int i, found = _FALSE;
13601 	u8 nr_send, th_idx = 0;
13602 
13603 	_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
13604 	RTW_DBG("%s:asoc_cnt: %d\n",__func__, pstapriv->tbtx_asoc_list_cnt);
13605 
13606 	// check number of TBTX sta
13607 	if (padapter->stapriv.tbtx_asoc_list_cnt < 2)
13608 		goto exit;
13609 
13610 	// dispatch token
13611 
13612 	nr_send = RTW_DIV_ROUND_UP(pstapriv->tbtx_asoc_list_cnt, NR_TBTX_SLOT);
13613 
13614 	phead = &pstapriv->asoc_list;
13615 	plist = get_next(phead);
13616 	while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
13617 		psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
13618 		/* psta is supporting TBTX */
13619 		if ((!psta) || (!psta->tbtx_enable))
13620 			RTW_DBG("sta tbtx_enable is false\n");
13621 		else {
13622 			for (i = 0; i < nr_send; i++) {
13623 				if (pstapriv->last_token_holder == psta) {
13624 					found = _TRUE;
13625 					goto outof_loop;
13626 				}
13627 			}
13628 		}
13629 		plist = get_next(plist);
13630 	}
13631 outof_loop:
13632 
13633 	RTW_DBG("rtw_tbtx_token_dispatch_timer_hdl()   th_idx=%d,  nr_send=%d, phead=%p, plist=%p, found=%d\n ", th_idx ,  nr_send, phead, plist, found);
13634 	if (!found) {
13635 		plist = get_next(phead);
13636 		while(rtw_end_of_queue_search(phead, plist) == _FALSE) {
13637 			psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
13638 			if ((!psta) || (!psta->tbtx_enable))
13639 				RTW_DBG("sta tbtx_enable is false\n");
13640 			else {
13641 					pstapriv->token_holder[th_idx] = psta;
13642 					rtw_issue_action_token_req(padapter, pstapriv->token_holder[th_idx++]);
13643 					break;
13644 			}
13645 			plist = get_next(plist);
13646 		}
13647 	}
13648 
13649 	for (i=th_idx; i<nr_send;) {
13650 		plist = get_next(plist);
13651 		if (plist == phead)
13652 			plist = get_next(plist);
13653 		psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
13654 		if ((!psta) || (!psta->tbtx_enable))
13655 			RTW_DBG("sta tbtx_enable is false\n");
13656 		else {
13657 			pstapriv->token_holder[th_idx] = psta;
13658 			rtw_issue_action_token_req(padapter, pstapriv->token_holder[th_idx++]);
13659 			i++;
13660 		}
13661 	}
13662 	ATOMIC_SET(&pstapriv->nr_token_keeper, nr_send);
13663 
13664 
13665 exit:
13666 	// set_timer
13667 	_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
13668 	_set_timer(&pmlmeext->tbtx_token_dispatch_timer, TBTX_TX_DURATION);
13669 }
13670 #endif /* CONFIG_AP_MODE */
13671 #endif /* CONFIG_RTW_TOKEN_BASED_XMIT */
13672 
link_timer_hdl(void * ctx)13673 void link_timer_hdl(void *ctx)
13674 {
13675 	_adapter *padapter = (_adapter *)ctx;
13676 	/* static unsigned int		rx_pkt = 0; */
13677 	/* static u64				tx_cnt = 0; */
13678 	/* struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv); */
13679 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
13680 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
13681 	/* struct sta_priv		*pstapriv = &padapter->stapriv; */
13682 #ifdef CONFIG_RTW_80211R
13683 	struct	sta_priv		*pstapriv = &padapter->stapriv;
13684 	struct	sta_info		*psta = NULL;
13685 	WLAN_BSSID_EX		*pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
13686 #endif
13687 
13688 	if (rtw_sta_linking_test_force_fail())
13689 		RTW_INFO("rtw_sta_linking_test_force_fail\n");
13690 
13691 	if (pmlmeext->join_abort && pmlmeinfo->state != WIFI_FW_NULL_STATE) {
13692 		RTW_INFO(FUNC_ADPT_FMT" join abort\n", FUNC_ADPT_ARG(padapter));
13693 		pmlmeinfo->state = WIFI_FW_NULL_STATE;
13694 		report_join_res(padapter, -4, WLAN_STATUS_UNSPECIFIED_FAILURE);
13695 		goto exit;
13696 	}
13697 
13698 	if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
13699 		RTW_INFO("link_timer_hdl:no beacon while connecting\n");
13700 		pmlmeinfo->state = WIFI_FW_NULL_STATE;
13701 		report_join_res(padapter, -3, WLAN_STATUS_UNSPECIFIED_FAILURE);
13702 	} else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
13703 
13704 #ifdef CONFIG_IOCTL_CFG80211
13705 		if (rtw_sec_chk_auth_type(padapter, MLME_AUTHTYPE_SAE))
13706 			return;
13707 #endif /* CONFIG_IOCTL_CFG80211 */
13708 
13709 		/* re-auth timer */
13710 		if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
13711 			/* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
13712 			/* { */
13713 			pmlmeinfo->state = 0;
13714 			if (pmlmeinfo->auth_status) {
13715 				report_join_res(padapter, -1, pmlmeinfo->auth_status);
13716 				pmlmeinfo->auth_status = 0; /* reset */
13717 			} else
13718 				report_join_res(padapter, -1, WLAN_STATUS_UNSPECIFIED_FAILURE);
13719 			return;
13720 			/* } */
13721 			/* else */
13722 			/* { */
13723 			/*	pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
13724 			/*	pmlmeinfo->reauth_count = 0; */
13725 			/* } */
13726 		}
13727 
13728 		RTW_INFO("link_timer_hdl: auth timeout and try again\n");
13729 		pmlmeinfo->auth_seq = 1;
13730 		issue_auth(padapter, NULL, 0);
13731 		set_link_timer(pmlmeext, REAUTH_TO);
13732 	} else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
13733 		/* re-assoc timer */
13734 		if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
13735 			pmlmeinfo->state = WIFI_FW_NULL_STATE;
13736 #ifdef CONFIG_RTW_80211R
13737 			if (rtw_ft_roam(padapter)) {
13738 				psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
13739 				if (psta)
13740 					rtw_free_stainfo(padapter,  psta);
13741 			}
13742 #endif
13743 			report_join_res(padapter, -2, WLAN_STATUS_UNSPECIFIED_FAILURE);
13744 			return;
13745 		}
13746 
13747 #ifdef CONFIG_RTW_80211R
13748 		if (rtw_ft_roam(padapter)) {
13749 			RTW_INFO("link_timer_hdl: reassoc timeout and try again\n");
13750 			issue_reassocreq(padapter);
13751 		} else
13752 #endif
13753 		{
13754 			RTW_INFO("link_timer_hdl: assoc timeout and try again\n");
13755 			issue_assocreq(padapter);
13756 		}
13757 
13758 		set_link_timer(pmlmeext, REASSOC_TO);
13759 	}
13760 
13761 exit:
13762 	return;
13763 }
13764 
addba_timer_hdl(void * ctx)13765 void addba_timer_hdl(void *ctx)
13766 {
13767 	struct sta_info *psta = (struct sta_info *)ctx;
13768 
13769 #ifdef CONFIG_80211N_HT
13770 	struct ht_priv	*phtpriv;
13771 
13772 	if (!psta)
13773 		return;
13774 
13775 	phtpriv = &psta->htpriv;
13776 
13777 	if ((phtpriv->ht_option == _TRUE) && (phtpriv->ampdu_enable == _TRUE)) {
13778 		if (phtpriv->candidate_tid_bitmap)
13779 			phtpriv->candidate_tid_bitmap = 0x0;
13780 
13781 	}
13782 #endif /* CONFIG_80211N_HT */
13783 }
13784 
13785 #ifdef CONFIG_IEEE80211W
report_sta_timeout_event(_adapter * padapter,u8 * MacAddr,unsigned short reason)13786 void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short reason)
13787 {
13788 	struct cmd_obj *pcmd_obj;
13789 	u8 *pevtcmd;
13790 	u32 cmdsz;
13791 	struct sta_info *psta;
13792 	int	mac_id;
13793 	struct stadel_event *pdel_sta_evt;
13794 	struct rtw_evt_header *evt_hdr;
13795 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13796 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
13797 
13798 	pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
13799 	if (pcmd_obj == NULL)
13800 		return;
13801 
13802 	cmdsz = (sizeof(struct stadel_event) + sizeof(struct rtw_evt_header));
13803 	pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
13804 	if (pevtcmd == NULL) {
13805 		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
13806 		return;
13807 	}
13808 
13809 	_rtw_init_listhead(&pcmd_obj->list);
13810 
13811 	pcmd_obj->cmdcode = CMD_SET_MLME_EVT;
13812 	pcmd_obj->cmdsz = cmdsz;
13813 	pcmd_obj->parmbuf = pevtcmd;
13814 
13815 	pcmd_obj->rsp = NULL;
13816 	pcmd_obj->rspsz  = 0;
13817 
13818 	evt_hdr = (struct rtw_evt_header *)(pevtcmd);
13819 	evt_hdr->len = sizeof(struct stadel_event);
13820 	evt_hdr->id = EVT_TIMEOUT_STA;
13821 	evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
13822 
13823 	pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct rtw_evt_header));
13824 	_rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
13825 	_rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
13826 
13827 
13828 	psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
13829 	if (psta)
13830 		mac_id = (int)psta->cmn.mac_id;
13831 	else
13832 		mac_id = (-1);
13833 
13834 	pdel_sta_evt->mac_id = mac_id;
13835 
13836 	RTW_INFO("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
13837 
13838 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
13839 
13840 	return;
13841 }
13842 
clnt_sa_query_timeout(_adapter * padapter)13843 void clnt_sa_query_timeout(_adapter *padapter)
13844 {
13845 	struct mlme_ext_priv *mlmeext = &(padapter->mlmeextpriv);
13846 	struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
13847 
13848 	RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
13849 	receive_disconnect(padapter, get_my_bssid(&(mlmeinfo->network)), WLAN_REASON_SA_QUERY_TIMEOUT, _FALSE);
13850 }
13851 
sa_query_timer_hdl(void * ctx)13852 void sa_query_timer_hdl(void *ctx)
13853 {
13854 	struct sta_info *psta = (struct sta_info *)ctx;
13855 	_adapter *padapter = psta->padapter;
13856 	_irqL irqL;
13857 	struct sta_priv *pstapriv = &padapter->stapriv;
13858 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
13859 
13860 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE &&
13861 	    check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
13862 		clnt_sa_query_timeout(padapter);
13863 	else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
13864 		report_sta_timeout_event(padapter, psta->cmn.mac_addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
13865 }
13866 
13867 #endif /* CONFIG_IEEE80211W */
13868 
13869 #ifdef CONFIG_AUTO_AP_MODE
rtw_auto_ap_rx_msg_dump(_adapter * padapter,union recv_frame * precv_frame,u8 * ehdr_pos)13870 void rtw_auto_ap_rx_msg_dump(_adapter *padapter, union recv_frame *precv_frame, u8 *ehdr_pos)
13871 {
13872 	struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
13873 	struct sta_info *psta = precv_frame->u.hdr.psta;
13874 	struct ethhdr *ehdr = (struct ethhdr *)ehdr_pos;
13875 
13876 	RTW_INFO("eth rx: got eth_type=0x%x\n", ntohs(ehdr->h_proto));
13877 
13878 	if (psta && psta->isrc && psta->pid > 0) {
13879 		u16 rx_pid;
13880 
13881 		rx_pid = *(u16 *)(ehdr_pos + ETH_HLEN);
13882 
13883 		RTW_INFO("eth rx(pid=0x%x): sta("MAC_FMT") pid=0x%x\n",
13884 			 rx_pid, MAC_ARG(psta->cmn.mac_addr), psta->pid);
13885 
13886 		if (rx_pid == psta->pid) {
13887 			int i;
13888 			u16 len = *(u16 *)(ehdr_pos + ETH_HLEN + 2);
13889 			/* u16 ctrl_type = *(u16 *)(ehdr_pos + ETH_HLEN + 4); */
13890 
13891 			/* RTW_INFO("eth, RC: len=0x%x, ctrl_type=0x%x\n", len, ctrl_type);  */
13892 			RTW_INFO("eth, RC: len=0x%x\n", len);
13893 
13894 			for (i = 0; i < len; i++)
13895 				RTW_INFO("0x%x\n", *(ehdr_pos + ETH_HLEN + 4 + i));
13896 			/* RTW_INFO("0x%x\n", *(ehdr_pos + ETH_HLEN + 6 + i)); */
13897 
13898 			RTW_INFO("eth, RC-end\n");
13899 		}
13900 	}
13901 
13902 }
13903 
rtw_start_auto_ap(_adapter * adapter)13904 void rtw_start_auto_ap(_adapter *adapter)
13905 {
13906 	RTW_INFO("%s\n", __FUNCTION__);
13907 
13908 	rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode, 0);
13909 
13910 	rtw_setopmode_cmd(adapter, Ndis802_11APMode, RTW_CMDF_WAIT_ACK);
13911 }
13912 
rtw_auto_ap_start_beacon(_adapter * adapter)13913 static int rtw_auto_ap_start_beacon(_adapter *adapter)
13914 {
13915 	int ret = 0;
13916 	u8 *pbuf = NULL;
13917 	uint len;
13918 	u8	supportRate[16];
13919 	int	sz = 0, rateLen;
13920 	u8	*ie;
13921 	u8	wireless_mode, oper_channel;
13922 	u8 ssid[3] = {0}; /* hidden ssid */
13923 	u32 ssid_len = sizeof(ssid);
13924 	struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
13925 
13926 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
13927 		return -EINVAL;
13928 
13929 
13930 	len = 128;
13931 	pbuf = rtw_zmalloc(len);
13932 	if (!pbuf)
13933 		return -ENOMEM;
13934 
13935 
13936 	/* generate beacon */
13937 	ie = pbuf;
13938 
13939 	/* timestamp will be inserted by hardware */
13940 	sz += 8;
13941 	ie += sz;
13942 
13943 	/* beacon interval : 2bytes */
13944 	*(u16 *)ie = cpu_to_le16((u16)100); /* BCN_INTERVAL=100; */
13945 	sz += 2;
13946 	ie += 2;
13947 
13948 	/* capability info */
13949 	*(u16 *)ie = 0;
13950 	*(u16 *)ie |= cpu_to_le16(cap_ESS);
13951 	*(u16 *)ie |= cpu_to_le16(cap_ShortPremble);
13952 	/* *(u16*)ie |= cpu_to_le16(cap_Privacy); */
13953 	sz += 2;
13954 	ie += 2;
13955 
13956 	/* SSID */
13957 	ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
13958 
13959 	/* supported rates */
13960 	wireless_mode = (WIRELESS_11BG_24N & padapter->registrypriv.wireless_mode);
13961 	rtw_set_supported_rate(supportRate, wireless_mode);
13962 	rateLen = rtw_get_rateset_len(supportRate);
13963 	if (rateLen > 8)
13964 		ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
13965 	else
13966 		ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
13967 
13968 
13969 	/* DS parameter set */
13970 	if (rtw_mi_check_status(adapter, MI_LINKED))
13971 		oper_channel = rtw_mi_get_union_chan(adapter);
13972 	else
13973 		oper_channel = adapter_to_dvobj(adapter)->oper_channel;
13974 
13975 	ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
13976 
13977 	/* ext supported rates */
13978 	if (rateLen > 8)
13979 		ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
13980 
13981 	RTW_INFO("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz);
13982 
13983 	/* lunch ap mode & start to issue beacon */
13984 	if (rtw_check_beacon_data(adapter, pbuf,  sz) == _SUCCESS) {
13985 
13986 	} else
13987 		ret = -EINVAL;
13988 
13989 
13990 	rtw_mfree(pbuf, len);
13991 
13992 	return ret;
13993 
13994 }
13995 #endif/* CONFIG_AUTO_AP_MODE */
13996 
13997 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
tx_control_hdl(_adapter * adapter)13998 u8 tx_control_hdl(_adapter *adapter)
13999 {
14000 	u8 val;
14001 
14002 	if(ATOMIC_READ(&adapter->tbtx_tx_pause))
14003 		val = 0xff;
14004 	else
14005 		val = 0x00;
14006 
14007 	rtw_hal_set_hwreg(adapter, HW_VAR_TXPAUSE, &val);
14008 
14009 	return H2C_SUCCESS;
14010 }
14011 #endif
14012 
14013 #ifdef CONFIG_AP_MODE
stop_ap_hdl(_adapter * adapter)14014 u8 stop_ap_hdl(_adapter *adapter)
14015 {
14016 	u8 self_action = MLME_ACTION_UNKNOWN;
14017 
14018 	RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
14019 
14020 	if (MLME_IS_AP(adapter))
14021 		self_action = MLME_AP_STOPPED;
14022 	else if (MLME_IS_MESH(adapter))
14023 		self_action = MLME_MESH_STOPPED;
14024 	else
14025 		rtw_warn_on(1);
14026 
14027 	rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11Infrastructure, RTW_CMDF_DIRECTLY);
14028 	rtw_setopmode_cmd(adapter, Ndis802_11Infrastructure, RTW_CMDF_DIRECTLY);
14029 
14030 #ifdef CONFIG_DFS_MASTER
14031 	rtw_dfs_rd_en_decision(adapter, self_action, 0);
14032 #endif
14033 
14034 	return H2C_SUCCESS;
14035 }
14036 #endif
14037 
setopmode_hdl(_adapter * padapter,u8 * pbuf)14038 u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
14039 {
14040 	u8	type;
14041 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
14042 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14043 	struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
14044 
14045 	if (psetop->mode == Ndis802_11APMode
14046 		|| psetop->mode == Ndis802_11_mesh
14047 	) {
14048 		pmlmeinfo->state = WIFI_FW_AP_STATE;
14049 		type = _HW_STATE_AP_;
14050 	} else if (psetop->mode == Ndis802_11Infrastructure) {
14051 		pmlmeinfo->state &= ~(BIT(0) | BIT(1)); /* clear state */
14052 		pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to 	STATION_STATE */
14053 		type = _HW_STATE_STATION_;
14054 	} else if (psetop->mode == Ndis802_11IBSS)
14055 		type = _HW_STATE_ADHOC_;
14056 	else if (psetop->mode == Ndis802_11Monitor)
14057 		type = _HW_STATE_MONITOR_;
14058 	else
14059 		type = _HW_STATE_NOLINK_;
14060 
14061 #ifdef CONFIG_AP_PORT_SWAP
14062 	rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, (u8 *)(&type));
14063 #endif
14064 
14065 	rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
14066 
14067 #ifdef CONFIG_AUTO_AP_MODE
14068 	if (psetop->mode == Ndis802_11APMode)
14069 		rtw_auto_ap_start_beacon(padapter);
14070 #endif
14071 
14072 	if (rtw_port_switch_chk(padapter) == _TRUE) {
14073 		rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
14074 
14075 		if (psetop->mode == Ndis802_11APMode)
14076 			adapter_to_pwrctl(padapter)->fw_psmode_iface_id = 0xff; /* ap mode won't dowload rsvd pages */
14077 		else if (psetop->mode == Ndis802_11Infrastructure) {
14078 #ifdef CONFIG_LPS
14079 			_adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
14080 			if (port0_iface)
14081 				rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, RTW_CMDF_DIRECTLY);
14082 #endif
14083 		}
14084 	}
14085 
14086 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
14087 	/* Enable beacon early interrupt IMR of AP mode after port switch done */
14088 	if (MLME_IS_AP(padapter))
14089 		rtw_hal_set_ap_bcn_imr_cmd(padapter, 1);
14090 #endif
14091 
14092 #ifdef CONFIG_BT_COEXIST
14093 	if (psetop->mode == Ndis802_11APMode
14094 		|| psetop->mode == Ndis802_11_mesh
14095 		|| psetop->mode == Ndis802_11Monitor
14096 	) {
14097 		/* Do this after port switch to */
14098 		/* prevent from downloading rsvd page to wrong port */
14099 		rtw_btcoex_MediaStatusNotify(padapter, 1); /* connect */
14100 	}
14101 #endif /* CONFIG_BT_COEXIST */
14102 
14103 	return H2C_SUCCESS;
14104 
14105 }
14106 
createbss_hdl(_adapter * padapter,u8 * pbuf)14107 u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
14108 {
14109 #ifdef CONFIG_AP_MODE
14110 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
14111 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14112 	WLAN_BSSID_EX	*pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
14113 	WLAN_BSSID_EX	*pdev_network = &padapter->registrypriv.dev_network;
14114 	struct createbss_parm *parm = (struct createbss_parm *)pbuf;
14115 	u8 ret = H2C_SUCCESS;
14116 	/* u8	initialgain; */
14117 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14118 	struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj);
14119 
14120 	if ((parm->req_ch == 0 && pmlmeinfo->state == WIFI_FW_AP_STATE)
14121 		|| parm->req_ch != 0
14122 	) {
14123 		start_bss_network(padapter, parm);
14124 		if (rfctl->ap_csa_en) {
14125 			u8 enable = 0;
14126 			rfctl->ap_csa_en = AP_CSA_DISABLE;
14127 			rtw_hal_set_hwreg(padapter, HW_VAR_BCN_EARLY_C2H_RPT, &enable);
14128 		}
14129 		goto exit;
14130 	}
14131 
14132 	/* below is for ad-hoc master */
14133 	if (parm->adhoc) {
14134 		rtw_warn_on(pdev_network->InfrastructureMode != Ndis802_11IBSS);
14135 		rtw_joinbss_reset(padapter);
14136 
14137 		pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
14138 		pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
14139 		pmlmeinfo->ERP_enable = 0;
14140 		pmlmeinfo->WMM_enable = 0;
14141 		pmlmeinfo->HT_enable = 0;
14142 		pmlmeinfo->HT_caps_enable = 0;
14143 		pmlmeinfo->HT_info_enable = 0;
14144 		pmlmeinfo->agg_enable_bitmap = 0;
14145 		pmlmeinfo->candidate_tid_bitmap = 0;
14146 
14147 		/* cancel link timer */
14148 		_cancel_timer_ex(&pmlmeext->link_timer);
14149 
14150 		/* clear CAM */
14151 		flush_all_cam_entry(padapter);
14152 
14153 		pdev_network->Length = get_WLAN_BSSID_EX_sz(pdev_network);
14154 		_rtw_memcpy(pnetwork, pdev_network, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
14155 		pnetwork->IELength = pdev_network->IELength;
14156 
14157 		if (pnetwork->IELength > MAX_IE_SZ) {
14158 			ret = H2C_PARAMETERS_ERROR;
14159 			goto ibss_post_hdl;
14160 		}
14161 
14162 		_rtw_memcpy(pnetwork->IEs, pdev_network->IEs, pnetwork->IELength);
14163 		start_create_ibss(padapter);
14164 	} else {
14165 		rtw_warn_on(1);
14166 		ret = H2C_PARAMETERS_ERROR;
14167 	}
14168 
14169 ibss_post_hdl:
14170 	rtw_create_ibss_post_hdl(padapter, ret);
14171 
14172 exit:
14173 	return ret;
14174 #else
14175 	return H2C_SUCCESS;
14176 #endif /* CONFIG_AP_MODE */
14177 }
14178 
join_cmd_hdl(_adapter * padapter,u8 * pbuf)14179 u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
14180 {
14181 	u8	join_type;
14182 	PNDIS_802_11_VARIABLE_IEs	pIE;
14183 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
14184 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14185 	WLAN_BSSID_EX		*pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
14186 #ifdef CONFIG_ANTENNA_DIVERSITY
14187 	struct joinbss_parm	*pparm = (struct joinbss_parm *)pbuf;
14188 #endif /* CONFIG_ANTENNA_DIVERSITY */
14189 #ifdef  CONFIG_LAYER2_ROAMING
14190 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
14191 	struct wlan_network     *rnetwork = pmlmepriv->roam_network;
14192 	struct beacon_keys bcn_keys;
14193 	u32 roam_ielen;
14194 	_irqL irqL;
14195 #endif
14196 	u32 i;
14197 	/* u8	initialgain; */
14198 	/* u32	acparm; */
14199 	u8 u_ch, u_bw, u_offset;
14200 	u8 doiqk = _FALSE;
14201 
14202 	/* check already connecting to AP or not */
14203 	if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
14204 		if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
14205 			issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
14206 		pmlmeinfo->state = WIFI_FW_NULL_STATE;
14207 
14208 		/* clear CAM */
14209 		flush_all_cam_entry(padapter);
14210 
14211 		_cancel_timer_ex(&pmlmeext->link_timer);
14212 
14213 		/* set MSR to nolink->infra. mode		 */
14214 		/* Set_MSR(padapter, _HW_STATE_NOLINK_); */
14215 		Set_MSR(padapter, _HW_STATE_STATION_);
14216 
14217 
14218 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
14219 		if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
14220 			rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_DISCONNECTED);
14221 	}
14222 
14223 #ifdef CONFIG_ANTENNA_DIVERSITY
14224 	rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
14225 #endif
14226 
14227 #ifdef CONFIG_WAPI_SUPPORT
14228 	rtw_wapi_clear_all_cam_entry(padapter);
14229 #endif
14230 
14231 	rtw_joinbss_reset(padapter);
14232 
14233 	pmlmeinfo->ERP_enable = 0;
14234 	pmlmeinfo->WMM_enable = 0;
14235 	pmlmeinfo->HT_enable = 0;
14236 	pmlmeinfo->HT_caps_enable = 0;
14237 	pmlmeinfo->HT_info_enable = 0;
14238 	pmlmeinfo->agg_enable_bitmap = 0;
14239 	pmlmeinfo->candidate_tid_bitmap = 0;
14240 	pmlmeinfo->bwmode_updated = _FALSE;
14241 	/* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
14242 	pmlmeinfo->VHT_enable = 0;
14243 #ifdef ROKU_PRIVATE
14244 	pmlmeinfo->ht_vht_received = 0;
14245 	_rtw_memset(pmlmeinfo->SupportedRates_infra_ap, 0, NDIS_802_11_LENGTH_RATES_EX);
14246 #endif /* ROKU_PRIVATE */
14247 	_rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
14248 	pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
14249 
14250 	if (pnetwork->IELength > MAX_IE_SZ) /* Check pbuf->IELength */
14251 		return H2C_PARAMETERS_ERROR;
14252 
14253 	if (pnetwork->IELength < 2) {
14254 		report_join_res(padapter, (-4), WLAN_STATUS_UNSPECIFIED_FAILURE);
14255 		return H2C_SUCCESS;
14256 	}
14257 	_rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
14258 
14259 	pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
14260 
14261 	/* Check AP vendor to move rtw_joinbss_cmd() */
14262 	/* pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength); */
14263 
14264 	/* sizeof(NDIS_802_11_FIXED_IEs)	 */
14265 	for (i = _FIXED_IE_LENGTH_ ; i < pnetwork->IELength - 2 ;) {
14266 		pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
14267 
14268 		switch (pIE->ElementID) {
14269 		case _VENDOR_SPECIFIC_IE_: /* Get WMM IE. */
14270 			if (_rtw_memcmp(pIE->data, WMM_OUI, 4))
14271 				WMM_param_handler(padapter, pIE);
14272 			break;
14273 
14274 #ifdef CONFIG_80211N_HT
14275 		case _HT_CAPABILITY_IE_:	/* Get HT Cap IE. */
14276 			pmlmeinfo->HT_caps_enable = 1;
14277 			break;
14278 
14279 		case _HT_EXTRA_INFO_IE_:	/* Get HT Info IE. */
14280 			pmlmeinfo->HT_info_enable = 1;
14281 			break;
14282 #endif /* CONFIG_80211N_HT */
14283 
14284 #ifdef CONFIG_80211AC_VHT
14285 		case EID_VHTCapability: /* Get VHT Cap IE. */
14286 			pmlmeinfo->VHT_enable = 1;
14287 			break;
14288 
14289 		case EID_VHTOperation: /* Get VHT Operation IE. */
14290 			break;
14291 #endif /* CONFIG_80211AC_VHT */
14292 		default:
14293 			break;
14294 		}
14295 
14296 		i += (pIE->Length + 2);
14297 	}
14298 
14299 	rtw_bss_get_chbw(pnetwork
14300 		, &pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset, 1, 1);
14301 
14302 	rtw_adjust_chbw(padapter, pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
14303 
14304 #if 0
14305 	if (padapter->registrypriv.wifi_spec) {
14306 		/* for WiFi test, follow WMM test plan spec */
14307 		acparm = 0x002F431C; /* VO */
14308 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
14309 		acparm = 0x005E541C; /* VI */
14310 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
14311 		acparm = 0x0000A525; /* BE */
14312 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
14313 		acparm = 0x0000A549; /* BK */
14314 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
14315 
14316 		/* for WiFi test, mixed mode with intel STA under bg mode throughput issue */
14317 		if (padapter->mlmepriv.htpriv.ht_option == _FALSE) {
14318 			acparm = 0x00004320;
14319 			rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
14320 		}
14321 	} else {
14322 		acparm = 0x002F3217; /* VO */
14323 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
14324 		acparm = 0x005E4317; /* VI */
14325 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
14326 		acparm = 0x00105320; /* BE */
14327 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
14328 		acparm = 0x0000A444; /* BK */
14329 		rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
14330 	}
14331 #endif
14332 
14333 	/* check channel, bandwidth, offset and switch */
14334 	if (rtw_chk_start_clnt_join(padapter, &u_ch, &u_bw, &u_offset) == _FAIL) {
14335 		report_join_res(padapter, (-4), WLAN_STATUS_UNSPECIFIED_FAILURE);
14336 		return H2C_SUCCESS;
14337 	}
14338 
14339 	/* disable dynamic functions, such as high power, DIG */
14340 	/*rtw_phydm_func_disable_all(padapter);*/
14341 
14342 	/* config the initial gain under linking, need to write the BB registers */
14343 	/* initialgain = 0x1E; */
14344 	/*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
14345 
14346 	rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
14347 	if (MLME_IS_STA(padapter))
14348 		rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_CONNECTING);
14349 	else
14350 		rtw_hal_rcr_set_chk_bssid(padapter, MLME_ADHOC_STARTED);
14351 
14352 	join_type = 0;
14353 	rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
14354 
14355 	rtw_btcoex_connect_notify(padapter, join_type);
14356 
14357 	doiqk = _TRUE;
14358 	rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
14359 
14360 	set_channel_bwmode(padapter, u_ch, u_offset, u_bw);
14361 
14362 	doiqk = _FALSE;
14363 	rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
14364 
14365 	/* cancel link timer */
14366 	_cancel_timer_ex(&pmlmeext->link_timer);
14367 
14368 	start_clnt_join(padapter);
14369 
14370 #ifdef	CONFIG_LAYER2_ROAMING
14371 	_enter_critical_bh(&pmlmepriv->clnt_auth_lock, &irqL);
14372 	if (rnetwork && (pmlmeinfo->state & (WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE))
14373 	#ifdef CONFIG_RTW_80211R
14374 		&& (!rtw_ft_roam(padapter))
14375 	#endif
14376 	) {
14377 		struct beacon_keys bcn_keys;
14378 		u32 roam_ielen;
14379 
14380 		roam_ielen = rnetwork->network.IELength;
14381 		update_network(&(pmlmepriv->cur_network.network), &(rnetwork->network), padapter, _TRUE);
14382 
14383 		/* update bcn keys */
14384 		if (rtw_get_bcn_keys_from_bss(&rnetwork->network, &bcn_keys) == _TRUE) {
14385 			_rtw_memcpy(&pmlmepriv->cur_beacon_keys, &bcn_keys, sizeof(bcn_keys));
14386 			if (is_hidden_ssid(bcn_keys.ssid, bcn_keys.ssid_len)) {
14387 				_rtw_memcpy(pmlmepriv->cur_beacon_keys.ssid, pmlmeinfo->network.Ssid.Ssid, IW_ESSID_MAX_SIZE);
14388 				pmlmepriv->cur_beacon_keys.ssid_len = pmlmeinfo->network.Ssid.SsidLength;
14389 			}
14390 		} else {
14391 			RTW_ERR("%s: get beacon keys failed\n", __func__);
14392 			_rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(bcn_keys));
14393 		}
14394 		#ifdef CONFIG_BCN_CNT_CONFIRM_HDL
14395 		pmlmepriv->new_beacon_cnts = 0;
14396 		#endif
14397 
14398 		/* check the vendor of the assoc AP */
14399 		pmlmeinfo->assoc_AP_vendor = check_assoc_AP(rnetwork->network.IEs, rnetwork->network.IELength);
14400 		rtw_phydm_update_ap_vendor_ie(padapter);
14401 
14402 		/* update TSF Value */
14403 		pmlmeext->TSFValue = rnetwork->network.tsf + rtw_get_passing_time_ms(rnetwork->last_scanned)*1000;
14404 		pmlmeext->bcn_cnt = 0;
14405 		pmlmeext->last_bcn_cnt = 0;
14406 		/* start auth */
14407 		start_clnt_auth(padapter);
14408 	}
14409 	_exit_critical_bh(&pmlmepriv->clnt_auth_lock, &irqL);
14410 #endif
14411 	return H2C_SUCCESS;
14412 
14413 }
14414 
disconnect_hdl(_adapter * padapter,unsigned char * pbuf)14415 u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
14416 {
14417 #if CONFIG_DFS
14418 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
14419 #endif
14420 	struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
14421 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
14422 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
14423 	WLAN_BSSID_EX		*pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
14424 	u8 val8;
14425 
14426 	if (is_client_associated_to_ap(padapter)
14427 		#if CONFIG_DFS
14428 		&& !IS_RADAR_DETECTED(rfctl) && !rfctl->csa_ch
14429 		#endif
14430 	) {
14431 		#ifdef CONFIG_PLATFORM_ROCKCHIPS
14432 		/* To avoid connecting to AP fail during resume process, change retry count from 5 to 1 */
14433 		issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
14434 		#else
14435 		issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms / 100, 100);
14436 		#endif /* CONFIG_PLATFORM_ROCKCHIPS */
14437 	}
14438 
14439 #ifndef CONFIG_SUPPORT_MULTI_BCN
14440 	if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
14441 		/* Stop BCN */
14442 		val8 = 0;
14443 		rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
14444 	}
14445 #endif
14446 
14447 	rtw_sta_mstatus_report(padapter);
14448 
14449 	rtw_mlmeext_disconnect(padapter);
14450 
14451 	rtw_free_uc_swdec_pending_queue(padapter);
14452 
14453 	return	H2C_SUCCESS;
14454 }
14455 
14456 static const char *const _scan_state_str[] = {
14457 	"SCAN_DISABLE",
14458 	"SCAN_START",
14459 	"SCAN_PS_ANNC_WAIT",
14460 	"SCAN_ENTER",
14461 	"SCAN_PROCESS",
14462 	"SCAN_BACKING_OP",
14463 	"SCAN_BACK_OP",
14464 	"SCAN_LEAVING_OP",
14465 	"SCAN_LEAVE_OP",
14466 	"SCAN_SW_ANTDIV_BL",
14467 	"SCAN_TO_P2P_LISTEN",
14468 	"SCAN_P2P_LISTEN",
14469 	"SCAN_COMPLETE",
14470 	"SCAN_STATE_MAX",
14471 };
14472 
scan_state_str(u8 state)14473 const char *scan_state_str(u8 state)
14474 {
14475 	state = (state >= SCAN_STATE_MAX) ? SCAN_STATE_MAX : state;
14476 	return _scan_state_str[state];
14477 }
14478 
scan_abort_hdl(_adapter * adapter)14479 static bool scan_abort_hdl(_adapter *adapter)
14480 {
14481 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
14482 	struct ss_res *ss = &pmlmeext->sitesurvey_res;
14483 #ifdef CONFIG_P2P
14484 	struct wifidirect_info *pwdinfo = &adapter->wdinfo;
14485 #endif
14486 	bool ret = _FALSE;
14487 
14488 	if (pmlmeext->scan_abort == _TRUE) {
14489 #ifdef CONFIG_P2P
14490 		if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) {
14491 			rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
14492 			ss->channel_idx = 3;
14493 			RTW_INFO("%s idx:%d, cnt:%u\n", __FUNCTION__
14494 				 , ss->channel_idx
14495 				 , pwdinfo->find_phase_state_exchange_cnt
14496 				);
14497 		} else
14498 #endif
14499 		{
14500 			ss->channel_idx = ss->ch_num;
14501 			RTW_INFO("%s idx:%d\n", __FUNCTION__
14502 				 , ss->channel_idx
14503 				);
14504 		}
14505 		ret = _TRUE;
14506 	}
14507 
14508 	return ret;
14509 }
14510 
rtw_scan_sparse(_adapter * adapter,struct rtw_ieee80211_channel * ch,u8 ch_num)14511 u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num)
14512 {
14513 	/* interval larger than this is treated as backgroud scan */
14514 #ifndef RTW_SCAN_SPARSE_BG_INTERVAL_MS
14515 #define RTW_SCAN_SPARSE_BG_INTERVAL_MS 12000
14516 #endif
14517 
14518 #ifndef RTW_SCAN_SPARSE_CH_NUM_MIRACAST
14519 #define RTW_SCAN_SPARSE_CH_NUM_MIRACAST 1
14520 #endif
14521 #ifndef RTW_SCAN_SPARSE_CH_NUM_BG
14522 #define RTW_SCAN_SPARSE_CH_NUM_BG 4
14523 #endif
14524 
14525 #define SCAN_SPARSE_CH_NUM_INVALID 255
14526 
14527 	static u8 token = 255;
14528 	u32 interval;
14529 	bool busy_traffic = _FALSE;
14530 	bool miracast_enabled = _FALSE;
14531 	bool bg_scan = _FALSE;
14532 	u8 max_allow_ch = SCAN_SPARSE_CH_NUM_INVALID;
14533 	u8 scan_division_num;
14534 	u8 ret_num = ch_num;
14535 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
14536 
14537 	if (mlmeext->last_scan_time == 0)
14538 		mlmeext->last_scan_time = rtw_get_current_time();
14539 
14540 	interval = rtw_get_passing_time_ms(mlmeext->last_scan_time);
14541 
14542 
14543 	if (rtw_mi_busy_traffic_check(adapter))
14544 		busy_traffic = _TRUE;
14545 
14546 	if (rtw_mi_check_miracast_enabled(adapter))
14547 		miracast_enabled = _TRUE;
14548 
14549 	if (interval > RTW_SCAN_SPARSE_BG_INTERVAL_MS)
14550 		bg_scan = _TRUE;
14551 
14552 	/* max_allow_ch by conditions*/
14553 
14554 #if RTW_SCAN_SPARSE_MIRACAST
14555 	if (miracast_enabled == _TRUE && busy_traffic == _TRUE)
14556 		max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_MIRACAST);
14557 #endif
14558 
14559 #if RTW_SCAN_SPARSE_BG
14560 	if (bg_scan == _TRUE)
14561 		max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_BG);
14562 #endif
14563 
14564 	if (max_allow_ch != SCAN_SPARSE_CH_NUM_INVALID) {
14565 		int i;
14566 		int k = 0;
14567 
14568 		scan_division_num = (ch_num / max_allow_ch) + ((ch_num % max_allow_ch) ? 1 : 0);
14569 		token = (token + 1) % scan_division_num;
14570 
14571 		if (0)
14572 			RTW_INFO("scan_division_num:%u, token:%u\n", scan_division_num, token);
14573 
14574 		for (i = 0; i < ch_num; i++) {
14575 			if (ch[i].hw_value && (i % scan_division_num) == token
14576 			   ) {
14577 				if (i != k)
14578 					_rtw_memcpy(&ch[k], &ch[i], sizeof(struct rtw_ieee80211_channel));
14579 				k++;
14580 			}
14581 		}
14582 
14583 		_rtw_memset(&ch[k], 0, sizeof(struct rtw_ieee80211_channel));
14584 
14585 		ret_num = k;
14586 		mlmeext->last_scan_time = rtw_get_current_time();
14587 	}
14588 
14589 	return ret_num;
14590 }
14591 
14592 #ifdef CONFIG_SCAN_BACKOP
rtw_scan_backop_decision(_adapter * adapter)14593 u8 rtw_scan_backop_decision(_adapter *adapter)
14594 {
14595 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
14596 	struct mi_state mstate;
14597 	u8 backop_flags = 0;
14598 
14599 	rtw_mi_status(adapter, &mstate);
14600 
14601 	if ((MSTATE_STA_LD_NUM(&mstate) && mlmeext_chk_scan_backop_flags_sta(mlmeext, SS_BACKOP_EN))
14602 		|| (MSTATE_STA_NUM(&mstate) && mlmeext_chk_scan_backop_flags_sta(mlmeext, SS_BACKOP_EN_NL)))
14603 		backop_flags |= mlmeext_scan_backop_flags_sta(mlmeext);
14604 
14605 #ifdef CONFIG_AP_MODE
14606 	if ((MSTATE_AP_LD_NUM(&mstate) && mlmeext_chk_scan_backop_flags_ap(mlmeext, SS_BACKOP_EN))
14607 		|| (MSTATE_AP_NUM(&mstate) && mlmeext_chk_scan_backop_flags_ap(mlmeext, SS_BACKOP_EN_NL)))
14608 		backop_flags |= mlmeext_scan_backop_flags_ap(mlmeext);
14609 #endif
14610 
14611 #ifdef CONFIG_RTW_MESH
14612 	if ((MSTATE_MESH_LD_NUM(&mstate) && mlmeext_chk_scan_backop_flags_mesh(mlmeext, SS_BACKOP_EN))
14613 		|| (MSTATE_MESH_NUM(&mstate) && mlmeext_chk_scan_backop_flags_mesh(mlmeext, SS_BACKOP_EN_NL)))
14614 		backop_flags |= mlmeext_scan_backop_flags_mesh(mlmeext);
14615 #endif
14616 
14617 	return backop_flags;
14618 }
14619 #endif
14620 
14621 #define SCANNING_TIMEOUT_EX	2000
rtw_scan_timeout_decision(_adapter * padapter)14622 u32 rtw_scan_timeout_decision(_adapter *padapter)
14623 {
14624 	u32 back_op_times= 0;
14625 	u8 max_chan_num;
14626 	u16 scan_ms;
14627 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14628 	struct ss_res *ss = &pmlmeext->sitesurvey_res;
14629 
14630 	if (is_supported_5g(padapter->registrypriv.wireless_mode)
14631 		&& IsSupported24G(padapter->registrypriv.wireless_mode))
14632 		max_chan_num = MAX_CHANNEL_NUM_2G_5G;/* dual band */
14633 	else
14634 		max_chan_num = MAX_CHANNEL_NUM_2G;/*single band*/
14635 
14636 	#ifdef CONFIG_SCAN_BACKOP
14637 	if (rtw_scan_backop_decision(padapter))
14638 		back_op_times = (max_chan_num / ss->scan_cnt_max) * ss->backop_ms;
14639 	#endif
14640 
14641 	if (ss->duration)
14642 		scan_ms = ss->duration;
14643 	else
14644 	#if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
14645 	if (IS_ACS_ENABLE(padapter) && rtw_is_acs_st_valid(padapter))
14646 		scan_ms = rtw_acs_get_adv_st(padapter);
14647 	else
14648 	#endif /*CONFIG_RTW_ACS*/
14649 		scan_ms = ss->scan_ch_ms;
14650 
14651 	ss->scan_timeout_ms = (scan_ms * max_chan_num) + back_op_times + SCANNING_TIMEOUT_EX;
14652 	#ifdef DBG_SITESURVEY
14653 	RTW_INFO("%s , scan_timeout_ms = %d (ms)\n", __func__, ss->scan_timeout_ms);
14654 	#endif /*DBG_SITESURVEY*/
14655 	return ss->scan_timeout_ms;
14656 }
14657 
rtw_scan_ch_decision(_adapter * padapter,struct rtw_ieee80211_channel * out,u32 out_num,struct rtw_ieee80211_channel * in,u32 in_num,bool no_sparse,int reason)14658 static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
14659 		u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num, bool no_sparse, int reason)
14660 {
14661 	int i, j;
14662 	int set_idx;
14663 	u8 chan;
14664 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
14665 	struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(padapter));
14666 #ifdef CONFIG_RTW_ROAM_QUICKSCAN
14667 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14668 #endif
14669 
14670 	/* clear first */
14671 	_rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel) * out_num);
14672 
14673 #ifdef CONFIG_RTW_ROAM_QUICKSCAN
14674 	if ((reason == RTW_AUTO_SCAN_REASON_ROAM) && (pmlmeext->quickscan_next)) {
14675 		pmlmeext->quickscan_next = _FALSE;
14676 		_rtw_memcpy(out, pmlmeext->roam_ch, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
14677 		return pmlmeext->roam_ch_num;
14678 	}
14679 #endif
14680 
14681 	/* acquire channels from in */
14682 	j = 0;
14683 	for (i = 0; i < in_num; i++) {
14684 
14685 		if (0)
14686 			RTW_INFO(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
14687 
14688 		if (!in[i].hw_value || (in[i].flags & RTW_IEEE80211_CHAN_DISABLED))
14689 			continue;
14690 		if (rtw_mlme_band_check(padapter, in[i].hw_value) == _FALSE)
14691 			continue;
14692 
14693 		set_idx = rtw_chset_search_ch(rfctl->channel_set, in[i].hw_value);
14694 		if (set_idx >= 0) {
14695 			if (j >= out_num) {
14696 				RTW_PRINT(FUNC_ADPT_FMT" out_num:%u not enough\n",
14697 					  FUNC_ADPT_ARG(padapter), out_num);
14698 				break;
14699 			}
14700 
14701 			_rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
14702 
14703 			if (rfctl->channel_set[set_idx].flags & (RTW_CHF_NO_IR | RTW_CHF_DFS))
14704 				out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
14705 
14706 			j++;
14707 		}
14708 		if (j >= out_num)
14709 			break;
14710 	}
14711 
14712 	/* if out is empty, use channel_set as default */
14713 	if (j == 0) {
14714 		for (i = 0; i < rfctl->max_chan_nums; i++) {
14715 			chan = rfctl->channel_set[i].ChannelNum;
14716 			if (rtw_mlme_band_check(padapter, chan) == _TRUE) {
14717 				if (rtw_mlme_ignore_chan(padapter, chan) == _TRUE)
14718 					continue;
14719 
14720 				if (0)
14721 					RTW_INFO(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), chan);
14722 
14723 				if (j >= out_num) {
14724 					RTW_PRINT(FUNC_ADPT_FMT" out_num:%u not enough\n",
14725 						FUNC_ADPT_ARG(padapter), out_num);
14726 					break;
14727 				}
14728 
14729 				out[j].hw_value = chan;
14730 
14731 				if (rfctl->channel_set[i].flags & (RTW_CHF_NO_IR | RTW_CHF_DFS))
14732 					out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
14733 
14734 				j++;
14735 			}
14736 		}
14737 	}
14738 
14739 	if (!no_sparse
14740 		&& !regsty->wifi_spec
14741 		&& j > 6 /* assume ch_num > 6 is normal scan */
14742 	) {
14743 		/* scan_sparse */
14744 		j = rtw_scan_sparse(padapter, out, j);
14745 	}
14746 
14747 	return j;
14748 }
14749 
sitesurvey_res_reset(_adapter * adapter,struct sitesurvey_parm * parm)14750 static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm)
14751 {
14752 	struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
14753 	RT_CHANNEL_INFO *chset = adapter_to_chset(adapter);
14754 	int i, reason = 0;
14755 
14756 	ss->bss_cnt = 0;
14757 	ss->activate_ch_cnt = 0;
14758 	ss->channel_idx = 0;
14759 	ss->force_ssid_scan = 0;
14760 	ss->igi_scan = 0;
14761 	ss->igi_before_scan = 0;
14762 #ifdef CONFIG_SCAN_BACKOP
14763 	ss->scan_cnt = 0;
14764 #endif
14765 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14766 	ss->is_sw_antdiv_bl_scan = 0;
14767 #endif
14768 	ss->ssid_num = 0;
14769 	for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
14770 		if (parm->ssid[i].SsidLength) {
14771 			_rtw_memcpy(ss->ssid[i].Ssid, parm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
14772 			ss->ssid[i].SsidLength = parm->ssid[i].SsidLength;
14773 			ss->ssid_num++;
14774 		} else
14775 			ss->ssid[i].SsidLength = 0;
14776 	}
14777 	reason = parm->reason;
14778 	ss->ch_num = rtw_scan_ch_decision(adapter
14779 					, ss->ch, RTW_CHANNEL_SCAN_AMOUNT
14780 					, parm->ch, parm->ch_num
14781 					, parm->acs
14782 					, reason
14783 				);
14784 
14785 	for (i = 0; i < MAX_CHANNEL_NUM; i++)
14786 		chset[i].hidden_bss_cnt = 0;
14787 
14788 	ss->bw = parm->bw;
14789 	ss->igi = parm->igi;
14790 	ss->token = parm->token;
14791 	ss->duration = parm->duration;
14792 	ss->scan_mode = parm->scan_mode;
14793 	ss->token = parm->token;
14794 	ss->acs = parm->acs;
14795 }
14796 
sitesurvey_pick_ch_behavior(_adapter * padapter,u8 * ch,RT_SCAN_TYPE * type)14797 static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch, RT_SCAN_TYPE *type)
14798 {
14799 	u8 next_state;
14800 	u8 scan_ch = 0;
14801 	RT_SCAN_TYPE scan_type = SCAN_PASSIVE;
14802 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14803 	struct ss_res *ss = &pmlmeext->sitesurvey_res;
14804 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
14805 	int ch_set_idx;
14806 #ifdef CONFIG_P2P
14807 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
14808 #endif
14809 #ifdef CONFIG_SCAN_BACKOP
14810 	u8 backop_flags = 0;
14811 #endif
14812 
14813 	/* handle scan abort request */
14814 	scan_abort_hdl(padapter);
14815 
14816 #ifdef CONFIG_P2P
14817 	if (pwdinfo->rx_invitereq_info.scan_op_ch_only || pwdinfo->p2p_info.scan_op_ch_only) {
14818 		if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
14819 			scan_ch = pwdinfo->rx_invitereq_info.operation_ch[ss->channel_idx];
14820 		else
14821 			scan_ch = pwdinfo->p2p_info.operation_ch[ss->channel_idx];
14822 		scan_type = SCAN_ACTIVE;
14823 	} else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
14824 		/*
14825 		* Commented by Albert 2011/06/03
14826 		* The driver is in the find phase, it should go through the social channel.
14827 		*/
14828 		scan_ch = pwdinfo->social_chan[ss->channel_idx];
14829 		ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, scan_ch);
14830 		if (ch_set_idx >= 0)
14831 			scan_type = rfctl->channel_set[ch_set_idx].flags & RTW_CHF_NO_IR ? SCAN_PASSIVE : SCAN_ACTIVE;
14832 		else
14833 			scan_type = SCAN_ACTIVE;
14834 	} else
14835 #endif /* CONFIG_P2P */
14836 	{
14837 		struct rtw_ieee80211_channel *ch;
14838 
14839 		#ifdef CONFIG_SCAN_BACKOP
14840 		backop_flags = rtw_scan_backop_decision(padapter);
14841 		#endif
14842 
14843 		#ifdef CONFIG_SCAN_BACKOP
14844 		if (!(backop_flags && ss->scan_cnt >= ss->scan_cnt_max))
14845 		#endif
14846 		{
14847 			#ifdef CONFIG_RTW_WIFI_HAL
14848 			if (adapter_to_dvobj(padapter)->nodfs) {
14849 				while (ss->channel_idx < ss->ch_num && rtw_chset_is_dfs_ch(rfctl->channel_set, ss->ch[ss->channel_idx].hw_value))
14850 					ss->channel_idx++;
14851 			} else
14852 			#endif
14853 			if (ss->channel_idx != 0 && ss->force_ssid_scan == 0
14854 				&& pmlmeext->sitesurvey_res.ssid_num
14855 				&& (ss->ch[ss->channel_idx - 1].flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN)
14856 			) {
14857 				ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, ss->ch[ss->channel_idx - 1].hw_value);
14858 				if (ch_set_idx != -1 && rfctl->channel_set[ch_set_idx].hidden_bss_cnt
14859 					&& (!IS_DFS_SLAVE_WITH_RD(rfctl)
14860 						|| rtw_rfctl_dfs_domain_unknown(rfctl)
14861 						|| !CH_IS_NON_OCP(&rfctl->channel_set[ch_set_idx]))
14862 				) {
14863 					ss->channel_idx--;
14864 					ss->force_ssid_scan = 1;
14865 				}
14866 			} else
14867 				ss->force_ssid_scan = 0;
14868 		}
14869 
14870 		if (ss->channel_idx < ss->ch_num) {
14871 			ch = &ss->ch[ss->channel_idx];
14872 			scan_ch = ch->hw_value;
14873 
14874 			#if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
14875 			if (IS_ACS_ENABLE(padapter) && rtw_is_acs_passiv_scan(padapter))
14876 				scan_type = SCAN_PASSIVE;
14877 			else
14878 			#endif /*CONFIG_RTW_ACS*/
14879 				scan_type = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
14880 		}
14881 	}
14882 
14883 	if (scan_ch != 0) {
14884 		next_state = SCAN_PROCESS;
14885 
14886 		#ifdef CONFIG_SCAN_BACKOP
14887 		if (backop_flags) {
14888 			if (ss->scan_cnt < ss->scan_cnt_max)
14889 				ss->scan_cnt++;
14890 			else {
14891 				mlmeext_assign_scan_backop_flags(pmlmeext, backop_flags);
14892 				next_state = SCAN_BACKING_OP;
14893 			}
14894 		}
14895 		#endif
14896 
14897 	} else if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) {
14898 		/* go p2p listen */
14899 		next_state = SCAN_TO_P2P_LISTEN;
14900 
14901 #ifdef CONFIG_ANTENNA_DIVERSITY
14902 	} else if (rtw_hal_antdiv_before_linked(padapter)) {
14903 		/* go sw antdiv before link */
14904 		next_state = SCAN_SW_ANTDIV_BL;
14905 #endif
14906 	} else {
14907 		next_state = SCAN_COMPLETE;
14908 
14909 #if defined(DBG_SCAN_SW_ANTDIV_BL)
14910 		{
14911 			/* for SCAN_SW_ANTDIV_BL state testing */
14912 			struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14913 			int i;
14914 			bool is_linked = _FALSE;
14915 
14916 			for (i = 0; i < dvobj->iface_nums; i++) {
14917 				if (rtw_linked_check(dvobj->padapters[i]))
14918 					is_linked = _TRUE;
14919 			}
14920 
14921 			if (!is_linked) {
14922 				static bool fake_sw_antdiv_bl_state = 0;
14923 
14924 				if (fake_sw_antdiv_bl_state == 0) {
14925 					next_state = SCAN_SW_ANTDIV_BL;
14926 					fake_sw_antdiv_bl_state = 1;
14927 				} else
14928 					fake_sw_antdiv_bl_state = 0;
14929 			}
14930 		}
14931 #endif /* defined(DBG_SCAN_SW_ANTDIV_BL) */
14932 	}
14933 
14934 #ifdef CONFIG_SCAN_BACKOP
14935 	if (next_state != SCAN_PROCESS)
14936 		ss->scan_cnt = 0;
14937 #endif
14938 
14939 
14940 #ifdef DBG_FIXED_CHAN
14941 	if (pmlmeext->fixed_chan != 0xff && next_state == SCAN_PROCESS)
14942 		scan_ch = pmlmeext->fixed_chan;
14943 #endif
14944 
14945 	if (ch)
14946 		*ch = scan_ch;
14947 	if (type)
14948 		*type = scan_type;
14949 
14950 	return next_state;
14951 }
14952 
site_survey(_adapter * padapter,u8 survey_channel,RT_SCAN_TYPE ScanType)14953 void site_survey(_adapter *padapter, u8 survey_channel, RT_SCAN_TYPE ScanType)
14954 {
14955 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14956 	struct ss_res *ss = &pmlmeext->sitesurvey_res;
14957 	u8 ssid_scan = 0;
14958 
14959 #ifdef CONFIG_P2P
14960 #ifndef CONFIG_IOCTL_CFG80211
14961 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
14962 #endif
14963 #endif
14964 
14965 	if (survey_channel != 0) {
14966 		set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
14967 
14968 		if (ScanType == SCAN_PASSIVE && ss->force_ssid_scan)
14969 			ssid_scan = 1;
14970 		else if (ScanType == SCAN_ACTIVE) {
14971 #ifdef CONFIG_P2P
14972 			#ifdef CONFIG_IOCTL_CFG80211
14973 			if (rtw_cfg80211_is_p2p_scan(padapter))
14974 			#else
14975 			if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
14976 				|| rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
14977 			#endif
14978 			{
14979 				issue_probereq_p2p(padapter, NULL);
14980 				issue_probereq_p2p(padapter, NULL);
14981 				issue_probereq_p2p(padapter, NULL);
14982 			} else
14983 #endif /* CONFIG_P2P */
14984 			{
14985 				if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
14986 					/* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
14987 					if (padapter->registrypriv.wifi_spec)
14988 						issue_probereq(padapter, NULL, NULL);
14989 					else
14990 						issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
14991 					issue_probereq(padapter, NULL, NULL);
14992 				}
14993 
14994 				ssid_scan = 1;
14995 			}
14996 		}
14997 
14998 		if (ssid_scan) {
14999 			int i;
15000 
15001 			for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
15002 				if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
15003 					/* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
15004 					if (padapter->registrypriv.wifi_spec)
15005 						issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
15006 					else
15007 						issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
15008 					issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
15009 				}
15010 			}
15011 		}
15012 	} else {
15013 		/* channel number is 0 or this channel is not valid. */
15014 		rtw_warn_on(1);
15015 	}
15016 
15017 	return;
15018 }
15019 
survey_done_set_ch_bw(_adapter * padapter)15020 void survey_done_set_ch_bw(_adapter *padapter)
15021 {
15022 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15023 	u8 cur_channel = 0;
15024 	u8 cur_bwmode;
15025 	u8 cur_ch_offset;
15026 
15027 #ifdef CONFIG_MCC_MODE
15028 	if (!rtw_hal_mcc_change_scan_flag(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset)) {
15029 		if (0)
15030 			RTW_INFO(FUNC_ADPT_FMT" back to AP channel - ch:%u, bw:%u, offset:%u\n",
15031 				FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
15032 		goto exit;
15033 	}
15034 #endif
15035 
15036 	if (rtw_mi_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0) {
15037 		if (0)
15038 			RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n",
15039 				FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
15040 	} else {
15041 #ifdef CONFIG_P2P
15042 		struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
15043 		_adapter *iface;
15044 		int i;
15045 
15046 		for (i = 0; i < dvobj->iface_nums; i++) {
15047 			iface = dvobj->padapters[i];
15048 			if (!iface)
15049 				continue;
15050 
15051 #ifdef CONFIG_IOCTL_CFG80211
15052 			if (iface->wdinfo.driver_interface == DRIVER_CFG80211 && !adapter_wdev_data(iface)->p2p_enabled)
15053 				continue;
15054 #endif
15055 
15056 			if (rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_LISTEN)) {
15057 				cur_channel = iface->wdinfo.listen_channel;
15058 				cur_bwmode = CHANNEL_WIDTH_20;
15059 				cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
15060 				if (0)
15061 					RTW_INFO(FUNC_ADPT_FMT" back to "ADPT_FMT"'s listen ch - ch:%u, bw:%u, offset:%u\n",
15062 						FUNC_ADPT_ARG(padapter), ADPT_ARG(iface), cur_channel, cur_bwmode, cur_ch_offset);
15063 				break;
15064 			}
15065 		}
15066 #endif /* CONFIG_P2P */
15067 
15068 		if (cur_channel == 0) {
15069 			cur_channel = pmlmeext->cur_channel;
15070 			cur_bwmode = pmlmeext->cur_bwmode;
15071 			cur_ch_offset = pmlmeext->cur_ch_offset;
15072 			if (0)
15073 				RTW_INFO(FUNC_ADPT_FMT" back to ch:%u, bw:%u, offset:%u\n",
15074 					FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
15075 		}
15076 	}
15077 #ifdef CONFIG_MCC_MODE
15078 exit:
15079 #endif
15080 	set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
15081 }
15082 
15083 /**
15084  * rtw_ps_annc - check and doing ps announcement for all the adapters
15085  * @adapter: the requesting adapter
15086  * @ps: power saving or not
15087  *
15088  * Returns: 0: no ps announcement is doing. 1: ps announcement is doing
15089  */
rtw_ps_annc(_adapter * adapter,bool ps)15090 u8 rtw_ps_annc(_adapter *adapter, bool ps)
15091 {
15092 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15093 	_adapter *iface;
15094 	int i;
15095 	u8 ps_anc = 0;
15096 
15097 	for (i = 0; i < dvobj->iface_nums; i++) {
15098 		iface = dvobj->padapters[i];
15099 		if (!iface)
15100 			continue;
15101 
15102 		if (MLME_IS_STA(iface)) {
15103 			if (is_client_associated_to_ap(iface) == _TRUE) {
15104 				/* TODO: TDLS peers */
15105 				#ifdef CONFIG_MCC_MODE
15106 				/* for two station case */
15107 				if (MCC_EN(adapter) && rtw_hal_check_mcc_status(adapter, MCC_STATUS_NEED_MCC)) {
15108 					u8 ch = iface->mlmeextpriv.cur_channel;
15109 					u8 offset = iface->mlmeextpriv.cur_ch_offset;
15110 					u8 bw = iface->mlmeextpriv.cur_bwmode;
15111 
15112 					set_channel_bwmode(iface, ch, offset, bw);
15113 				}
15114 				#endif /* CONFIG_MCC_MODE */
15115 				issue_nulldata(iface, NULL, ps, 3, 500);
15116 				ps_anc = 1;
15117 			}
15118 		#ifdef CONFIG_RTW_MESH
15119 		} else if (MLME_IS_MESH(iface)) {
15120 			if (rtw_mesh_ps_annc(iface, ps))
15121 				ps_anc = 1;
15122 		#endif
15123 		}
15124 	}
15125 	return ps_anc;
15126 }
15127 
rtw_leave_opch(_adapter * adapter)15128 void rtw_leave_opch(_adapter *adapter)
15129 {
15130 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
15131 
15132 #ifdef CONFIG_MCC_MODE
15133 	if (MCC_EN(adapter) && rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))
15134 		return;
15135 #endif
15136 
15137 	_enter_critical_mutex(&rfctl->offch_mutex, NULL);
15138 
15139 	if (rfctl->offch_state == OFFCHS_NONE) {
15140 		/* prepare to leave operating channel */
15141 		rfctl->offch_state = OFFCHS_LEAVING_OP;
15142 
15143 		/* clear HW TX queue */
15144 		rtw_hal_set_hwreg(adapter, HW_VAR_CHECK_TXBUF, 0);
15145 
15146 		rtw_hal_macid_sleep_all_used(adapter);
15147 
15148 		rtw_ps_annc(adapter, 1);
15149 
15150 		rfctl->offch_state = OFFCHS_LEAVE_OP;
15151 	}
15152 
15153 	_exit_critical_mutex(&rfctl->offch_mutex, NULL);
15154 }
15155 
rtw_back_opch(_adapter * adapter)15156 void rtw_back_opch(_adapter *adapter)
15157 {
15158 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
15159 
15160 #ifdef CONFIG_MCC_MODE
15161 	if (MCC_EN(adapter) && rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))
15162 		return;
15163 #endif
15164 
15165 	_enter_critical_mutex(&rfctl->offch_mutex, NULL);
15166 
15167 	if (rfctl->offch_state != OFFCHS_NONE) {
15168 		rfctl->offch_state = OFFCHS_BACKING_OP;
15169 		rtw_hal_macid_wakeup_all_used(adapter);
15170 		rtw_ps_annc(adapter, 0);
15171 
15172 		rfctl->offch_state = OFFCHS_NONE;
15173 		rtw_mi_os_xmit_schedule(adapter);
15174 	}
15175 
15176 	_exit_critical_mutex(&rfctl->offch_mutex, NULL);
15177 }
15178 
sitesurvey_set_igi(_adapter * adapter)15179 void sitesurvey_set_igi(_adapter *adapter)
15180 {
15181 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
15182 	struct ss_res *ss = &mlmeext->sitesurvey_res;
15183 	u8 igi;
15184 #ifdef CONFIG_P2P
15185 	struct wifidirect_info *pwdinfo = &adapter->wdinfo;
15186 #endif
15187 
15188 	switch (mlmeext_scan_state(mlmeext)) {
15189 	case SCAN_ENTER:
15190 		#ifdef CONFIG_P2P
15191 		#ifdef CONFIG_IOCTL_CFG80211
15192 		if (pwdinfo->driver_interface == DRIVER_CFG80211 && rtw_cfg80211_is_p2p_scan(adapter))
15193 			igi = 0x30;
15194 		else
15195 		#endif /* CONFIG_IOCTL_CFG80211 */
15196 		if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
15197 			igi = 0x28;
15198 		else
15199 		#endif /* CONFIG_P2P */
15200 
15201 		if (ss->igi)
15202 			igi = ss->igi;
15203 		else
15204 		#if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
15205 		if (IS_ACS_ENABLE(adapter) && rtw_is_acs_igi_valid(adapter))
15206 			igi = rtw_acs_get_adv_igi(adapter);
15207 		else
15208 		#endif /*CONFIG_RTW_ACS*/
15209 			igi = 0x1e;
15210 
15211 		/* record IGI status */
15212 		ss->igi_scan = igi;
15213 		rtw_hal_get_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &ss->igi_before_scan, NULL);
15214 
15215 		/* disable DIG and set IGI for scan */
15216 		rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE);
15217 		break;
15218 	case SCAN_COMPLETE:
15219 	case SCAN_TO_P2P_LISTEN:
15220 		/* enable DIG and restore IGI */
15221 		igi = 0xff;
15222 		rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE);
15223 		break;
15224 #ifdef CONFIG_SCAN_BACKOP
15225 	case SCAN_BACKING_OP:
15226 		/* write IGI for op channel when DIG is not enabled */
15227 		odm_write_dig(adapter_to_phydm(adapter), ss->igi_before_scan);
15228 		break;
15229 	case SCAN_LEAVE_OP:
15230 		/* write IGI for scan when DIG is not enabled */
15231 		odm_write_dig(adapter_to_phydm(adapter), ss->igi_scan);
15232 		break;
15233 #endif /* CONFIG_SCAN_BACKOP */
15234 	default:
15235 		rtw_warn_on(1);
15236 		break;
15237 	}
15238 }
sitesurvey_set_msr(_adapter * adapter,bool enter)15239 void sitesurvey_set_msr(_adapter *adapter, bool enter)
15240 {
15241 	u8 network_type;
15242 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
15243 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15244 
15245 	if (enter) {
15246 #ifdef CONFIG_MI_WITH_MBSSID_CAM
15247 		rtw_hal_get_hwreg(adapter, HW_VAR_MEDIA_STATUS, (u8 *)(&pmlmeinfo->hw_media_state));
15248 #endif
15249 		/* set MSR to no link state */
15250 		network_type = _HW_STATE_NOLINK_;
15251 	} else {
15252 #ifdef CONFIG_MI_WITH_MBSSID_CAM
15253 		network_type = pmlmeinfo->hw_media_state;
15254 #else
15255 		network_type = pmlmeinfo->state & 0x3;
15256 #endif
15257 	}
15258 	Set_MSR(adapter, network_type);
15259 }
15260 
sitesurvey_set_offch_state(_adapter * adapter,u8 scan_state)15261 void sitesurvey_set_offch_state(_adapter *adapter, u8 scan_state)
15262 {
15263 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
15264 
15265 	_enter_critical_mutex(&rfctl->offch_mutex, NULL);
15266 
15267 	switch (scan_state) {
15268 	case SCAN_DISABLE:
15269 	case SCAN_BACK_OP:
15270 		rfctl->offch_state = OFFCHS_NONE;
15271 		break;
15272 	case SCAN_START:
15273 	case SCAN_LEAVING_OP:
15274 		rfctl->offch_state = OFFCHS_LEAVING_OP;
15275 		break;
15276 	case SCAN_ENTER:
15277 	case SCAN_LEAVE_OP:
15278 		rfctl->offch_state = OFFCHS_LEAVE_OP;
15279 		break;
15280 	case SCAN_COMPLETE:
15281 	case SCAN_BACKING_OP:
15282 		rfctl->offch_state = OFFCHS_BACKING_OP;
15283 		break;
15284 	default:
15285 		break;
15286 	}
15287 
15288 	_exit_critical_mutex(&rfctl->offch_mutex, NULL);
15289 }
15290 
15291 #ifdef CONFIG_RTW_ROAM_QUICKSCAN
15292 extern inline int is_same_ess(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b);
15293 extern int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork);
generate_quickss(_adapter * padapter)15294 void generate_quickss(_adapter *padapter)
15295 {
15296 	struct mlme_priv        *pmlmepriv = &(padapter->mlmepriv);
15297 	struct wlan_network     *pnetwork = NULL;
15298 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15299 	struct rtw_ieee80211_channel *roam_ch = pmlmeext->roam_ch;
15300 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
15301 	int chan;
15302 	_irqL irqL;
15303 	_list *plist, *phead;
15304 	u8 *target_ssid=NULL, *ssid=NULL, ds_cfg, j, ch_num;
15305 	u32  target_ssid_len=0, ssid_len=0;
15306 	u8 mark[166];
15307 
15308 	target_ssid = pmlmepriv->cur_network.network.Ssid.Ssid;
15309 	target_ssid_len = pmlmepriv->cur_network.network.Ssid.SsidLength;
15310 	_rtw_memset(mark, 0, sizeof(u8)*166);
15311 
15312 	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
15313 	phead = get_list_head(&(pmlmepriv->scanned_queue));
15314 	if (!phead) {
15315 		_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
15316 		return;
15317 	}
15318 	plist = get_next(phead);
15319 	if (!plist) {
15320 		_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
15321 		return;
15322 	}
15323 	while (1) {
15324 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
15325 			break;
15326 
15327 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
15328 		if (!pnetwork)
15329 			break;
15330 
15331 		ds_cfg = pnetwork->network.Configuration.DSConfig;
15332 		if (is_same_ess(&pnetwork->network, &pmlmepriv->cur_network.network) &&
15333 				rtw_is_desired_network(padapter, pnetwork))
15334 			mark[ds_cfg] = 1;
15335 
15336 		plist = get_next(plist);
15337 	}
15338        /* ex: assume roaming channel=1/6/40/165, then mark[1]/[6]/[40]/[165] are 1.  */
15339 	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
15340 
15341 	ch_num = 0;
15342 	for (j = 0; j < rfctl->max_chan_nums; j++) {
15343 		chan = rfctl->channel_set[j].ChannelNum;
15344 		if (mark[chan]) {
15345 			roam_ch[ch_num].hw_value = chan;
15346 			roam_ch[ch_num++].flags = rfctl->channel_set[j].flags;
15347 		}
15348 	}
15349 	pmlmeext->roam_ch_num = ch_num;
15350 }
15351 #endif
15352 
sitesurvey_cmd_hdl(_adapter * padapter,u8 * pbuf)15353 u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
15354 {
15355 	struct sitesurvey_parm	*pparm = (struct sitesurvey_parm *)pbuf;
15356 #ifdef DBG_CHECK_FW_PS_STATE
15357 	struct dvobj_priv *dvobj = padapter->dvobj;
15358 	struct debug_priv *pdbgpriv = &dvobj->drv_dbg;
15359 #endif
15360 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15361 	struct ss_res *ss = &pmlmeext->sitesurvey_res;
15362 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
15363 	struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
15364 #endif
15365 	u8 val8;
15366 
15367 #ifdef CONFIG_P2P
15368 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
15369 #ifdef CONFIG_CONCURRENT_MODE
15370 	struct roch_info *prochinfo = &padapter->rochinfo;
15371 #endif
15372 #endif
15373 
15374 #ifdef DBG_CHECK_FW_PS_STATE
15375 	if (rtw_fw_ps_state(padapter) == _FAIL) {
15376 		RTW_INFO("scan without leave 32k\n");
15377 		pdbgpriv->dbg_scan_pwr_state_cnt++;
15378 	}
15379 #endif /* DBG_CHECK_FW_PS_STATE */
15380 
15381 	/* increase channel idx */
15382 	if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS))
15383 		ss->channel_idx++;
15384 
15385 	/* update scan state to next state (assigned by previous cmd hdl) */
15386 	if (mlmeext_scan_state(pmlmeext) != mlmeext_scan_next_state(pmlmeext))
15387 		mlmeext_set_scan_state(pmlmeext, mlmeext_scan_next_state(pmlmeext));
15388 
15389 operation_by_state:
15390 	switch (mlmeext_scan_state(pmlmeext)) {
15391 
15392 	case SCAN_DISABLE:
15393 		/*
15394 		* SW parameter initialization
15395 		*/
15396 
15397 		sitesurvey_res_reset(padapter, pparm);
15398 		mlmeext_set_scan_state(pmlmeext, SCAN_START);
15399 		goto operation_by_state;
15400 
15401 	case SCAN_START:
15402 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
15403 		if ((pwdev_priv->pno_mac_addr[0] != 0xFF)
15404 			    && (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE)
15405 	    	    && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _FALSE)) {
15406 			u16 seq_num;
15407 
15408 #ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
15409 			rtw_hal_pno_random_gen_mac_addr(padapter);
15410 #endif
15411 			rtw_hal_set_hw_macaddr(padapter, pwdev_priv->pno_mac_addr);
15412 			get_random_bytes(&seq_num, 2);
15413 			pwdev_priv->pno_scan_seq_num = seq_num & 0xFFF;
15414 			RTW_INFO("%s pno_scan_seq_num %d\n", __func__,
15415 				 pwdev_priv->pno_scan_seq_num);
15416 		}
15417 #endif
15418 
15419 		/*
15420 		* prepare to leave operating channel
15421 		*/
15422 
15423 #ifdef CONFIG_MCC_MODE
15424 		rtw_hal_set_mcc_setting_scan_start(padapter);
15425 #endif /* CONFIG_MCC_MODE */
15426 
15427 		/* apply rx ampdu setting */
15428 		if (ss->rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
15429 			|| ss->rx_ampdu_size != RX_AMPDU_SIZE_INVALID)
15430 			rtw_rx_ampdu_apply(padapter);
15431 
15432 		/* clear HW TX queue before scan */
15433 		rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
15434 
15435 		rtw_hal_macid_sleep_all_used(padapter);
15436 
15437 		/* power save state announcement */
15438 		if (rtw_ps_annc(padapter, 1)) {
15439 			mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
15440 			mlmeext_set_scan_next_state(pmlmeext, SCAN_ENTER);
15441 			set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
15442 		} else {
15443 			mlmeext_set_scan_state(pmlmeext, SCAN_ENTER);
15444 			goto operation_by_state;
15445 		}
15446 
15447 		break;
15448 
15449 	case SCAN_ENTER:
15450 		/*
15451 		* HW register and DM setting for enter scan
15452 		*/
15453 
15454 		rtw_phydm_ability_backup(padapter);
15455 
15456 		sitesurvey_set_igi(padapter);
15457 
15458 		/* config dynamic functions for off channel */
15459 		rtw_phydm_func_for_offchannel(padapter);
15460 		/* set MSR to no link state */
15461 		sitesurvey_set_msr(padapter, _TRUE);
15462 
15463 		val8 = 1; /* under site survey */
15464 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
15465 
15466 		mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
15467 		goto operation_by_state;
15468 
15469 	case SCAN_PROCESS: {
15470 		u8 scan_ch;
15471 		RT_SCAN_TYPE scan_type;
15472 		u8 next_state;
15473 		u32 scan_ms;
15474 
15475 #ifdef CONFIG_RTW_ACS
15476 		if (IS_ACS_ENABLE(padapter))
15477 			rtw_acs_get_rst(padapter);
15478 #endif
15479 
15480 		next_state = sitesurvey_pick_ch_behavior(padapter, &scan_ch, &scan_type);
15481 
15482 		if (next_state != SCAN_PROCESS) {
15483 			mlmeext_set_scan_state(pmlmeext, next_state);
15484 			goto operation_by_state;
15485 		}
15486 
15487 		/* still SCAN_PROCESS state */
15488 		#ifdef DBG_SITESURVEY
15489 			#ifdef CONFIG_P2P
15490 			RTW_INFO(FUNC_ADPT_FMT" %s ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c%c\n"
15491 				, FUNC_ADPT_ARG(padapter)
15492 				, mlmeext_scan_state_str(pmlmeext)
15493 				, scan_ch
15494 				, pwdinfo->find_phase_state_exchange_cnt, ss->channel_idx
15495 				, rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
15496 				, scan_type ? 'A' : 'P', ss->scan_mode ? 'A' : 'P'
15497 				, ss->ssid[0].SsidLength ? 'S' : ' '
15498 				, ss->force_ssid_scan ? 'F' : ' '
15499 			);
15500 			#else
15501 			RTW_INFO(FUNC_ADPT_FMT" %s ch:%u (idx:%d) at %dms, %c%c%c%c\n"
15502 				, FUNC_ADPT_ARG(padapter)
15503 				, mlmeext_scan_state_str(pmlmeext)
15504 				, scan_ch
15505 				, ss->channel_idx
15506 				, rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
15507 				, scan_type ? 'A' : 'P', ss->scan_mode ? 'A' : 'P'
15508 				, ss->ssid[0].SsidLength ? 'S' : ' '
15509 				, ss->force_ssid_scan ? 'F' : ' '
15510 			);
15511 			#endif /* CONFIG_P2P */
15512 		#endif /*DBG_SITESURVEY*/
15513 #ifdef DBG_FIXED_CHAN
15514 		if (pmlmeext->fixed_chan != 0xff)
15515 			RTW_INFO(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
15516 #endif
15517 
15518 		site_survey(padapter, scan_ch, scan_type);
15519 
15520 #if defined(CONFIG_ATMEL_RC_PATCH)
15521 		if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
15522 			scan_ms = 20;
15523 		else
15524 			scan_ms = 40;
15525 #else
15526 		#if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
15527 		if (IS_ACS_ENABLE(padapter) && rtw_is_acs_st_valid(padapter))
15528 			scan_ms = rtw_acs_get_adv_st(padapter);
15529 		else
15530 		#endif /*CONFIG_RTW_ACS*/
15531 			scan_ms = ss->scan_ch_ms;
15532 #endif
15533 
15534 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
15535 		if (ss->is_sw_antdiv_bl_scan)
15536 			scan_ms = scan_ms / 2;
15537 #endif
15538 
15539 #ifdef CONFIG_RTW_ACS
15540 		if (IS_ACS_ENABLE(padapter)) {
15541 			if (pparm->token)
15542 				rtw_acs_trigger(padapter, scan_ms, scan_ch, NHM_PID_IEEE_11K_HIGH);
15543 			else
15544 				rtw_acs_trigger(padapter, scan_ms, scan_ch, NHM_PID_ACS);
15545 		}
15546 #endif
15547 
15548 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
15549 		if (IS_NM_ENABLE(padapter))
15550 			rtw_noise_measure(padapter, scan_ch, _FALSE, 0, scan_ms / 2);
15551 #endif
15552 		set_survey_timer(pmlmeext, scan_ms);
15553 		break;
15554 	}
15555 
15556 #ifdef CONFIG_SCAN_BACKOP
15557 	case SCAN_BACKING_OP: {
15558 		u8 back_ch = 0, back_bw = 0, back_ch_offset = 0;
15559 		u8 need_ch_setting_union = _TRUE;
15560 
15561 #ifdef CONFIG_MCC_MODE
15562 		need_ch_setting_union = rtw_hal_mcc_change_scan_flag(padapter,
15563 				&back_ch, &back_bw, &back_ch_offset);
15564 #endif /* CONFIG_MCC_MODE */
15565 
15566 		if (need_ch_setting_union) {
15567 			if (rtw_mi_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0) {
15568 				rtw_warn_on(1);
15569 				back_ch = pmlmeext->cur_channel;
15570 				back_bw = pmlmeext->cur_bwmode;
15571 				back_ch_offset = pmlmeext->cur_ch_offset;
15572 			}
15573 		}
15574 
15575 		#ifdef DBG_SITESURVEY
15576 			RTW_INFO(FUNC_ADPT_FMT" %s ch:%u, bw:%u, offset:%u at %dms\n"
15577 				 , FUNC_ADPT_ARG(padapter)
15578 				 , mlmeext_scan_state_str(pmlmeext)
15579 				 , back_ch, back_bw, back_ch_offset
15580 				, rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
15581 				);
15582 		#endif /*DBG_SITESURVEY*/
15583 		set_channel_bwmode(padapter, back_ch, back_ch_offset, back_bw);
15584 
15585 		sitesurvey_set_msr(padapter, _FALSE);
15586 
15587 		val8 = 0; /* survey done */
15588 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
15589 
15590 		if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
15591 			sitesurvey_set_igi(padapter);
15592 			rtw_hal_macid_wakeup_all_used(padapter);
15593 			rtw_ps_annc(padapter, 0);
15594 		}
15595 
15596 		mlmeext_set_scan_state(pmlmeext, SCAN_BACK_OP);
15597 		ss->backop_time = rtw_get_current_time();
15598 
15599 		if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_TX_RESUME))
15600 			rtw_mi_os_xmit_schedule(padapter);
15601 
15602 
15603 		goto operation_by_state;
15604 	}
15605 
15606 	case SCAN_BACK_OP:
15607 		if (rtw_get_passing_time_ms(ss->backop_time) >= ss->backop_ms
15608 		    || pmlmeext->scan_abort
15609 		   ) {
15610 			mlmeext_set_scan_state(pmlmeext, SCAN_LEAVING_OP);
15611 			goto operation_by_state;
15612 		}
15613 		set_survey_timer(pmlmeext, 50);
15614 		break;
15615 
15616 	case SCAN_LEAVING_OP:
15617 		/*
15618 		 * prepare to leave operating channel
15619 		 */
15620 
15621 		/* clear HW TX queue before scan */
15622 		rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
15623 
15624 		rtw_hal_macid_sleep_all_used(padapter);
15625 		if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)
15626 			&& rtw_ps_annc(padapter, 1)
15627 		) {
15628 			mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
15629 			mlmeext_set_scan_next_state(pmlmeext, SCAN_LEAVE_OP);
15630 			set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
15631 		} else {
15632 			mlmeext_set_scan_state(pmlmeext, SCAN_LEAVE_OP);
15633 			goto operation_by_state;
15634 		}
15635 
15636 		break;
15637 
15638 	case SCAN_LEAVE_OP:
15639 		/*
15640 		* HW register and DM setting for enter scan
15641 		*/
15642 
15643 		if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC))
15644 			sitesurvey_set_igi(padapter);
15645 
15646 		sitesurvey_set_msr(padapter, _TRUE);
15647 
15648 		val8 = 1; /* under site survey */
15649 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
15650 
15651 		mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
15652 		goto operation_by_state;
15653 
15654 #endif /* CONFIG_SCAN_BACKOP */
15655 
15656 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
15657 	case SCAN_SW_ANTDIV_BL:
15658 		/*
15659 		* 20100721
15660 		* For SW antenna diversity before link, it needs to switch to another antenna and scan again.
15661 		* It compares the scan result and select better one to do connection.
15662 		*/
15663 		ss->bss_cnt = 0;
15664 		ss->channel_idx = 0;
15665 		ss->is_sw_antdiv_bl_scan = 1;
15666 
15667 		mlmeext_set_scan_next_state(pmlmeext, SCAN_PROCESS);
15668 		set_survey_timer(pmlmeext, ss->scan_ch_ms);
15669 		break;
15670 #endif
15671 
15672 #ifdef CONFIG_P2P
15673 	case SCAN_TO_P2P_LISTEN:
15674 		/*
15675 		* Set the P2P State to the listen state of find phase
15676 		* and set the current channel to the listen channel
15677 		*/
15678 		set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
15679 		rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
15680 
15681 		/* turn on phy-dynamic functions */
15682 		rtw_phydm_ability_restore(padapter);
15683 
15684 		sitesurvey_set_igi(padapter);
15685 
15686 		mlmeext_set_scan_state(pmlmeext, SCAN_P2P_LISTEN);
15687 		_set_timer(&pwdinfo->find_phase_timer, (u32)((u32)pwdinfo->listen_dwell * 100));
15688 		break;
15689 
15690 	case SCAN_P2P_LISTEN:
15691 		mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
15692 		ss->channel_idx = 0;
15693 		goto operation_by_state;
15694 #endif /* CONFIG_P2P */
15695 
15696 	case SCAN_COMPLETE:
15697 #if defined(CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI) || defined(CONFIG_RTW_SCAN_RAND)
15698 		rtw_hal_set_hw_macaddr(padapter, adapter_mac_addr(padapter));
15699 #endif
15700 #ifdef CONFIG_P2P
15701 		if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
15702 		    || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
15703 		   ) {
15704 #ifdef CONFIG_CONCURRENT_MODE
15705 			if (pwdinfo->driver_interface == DRIVER_WEXT) {
15706 				if (rtw_mi_check_status(padapter, MI_LINKED))
15707 					_set_timer(&prochinfo->ap_roch_ch_switch_timer, 500);
15708 			}
15709 #endif
15710 
15711 			rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
15712 		}
15713 		rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
15714 #endif /* CONFIG_P2P */
15715 
15716 		/* switch channel */
15717 		survey_done_set_ch_bw(padapter);
15718 
15719 		sitesurvey_set_msr(padapter, _FALSE);
15720 
15721 		val8 = 0; /* survey done */
15722 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
15723 
15724 		/* turn on phy-dynamic functions */
15725 		rtw_phydm_ability_restore(padapter);
15726 
15727 		sitesurvey_set_igi(padapter);
15728 
15729 #ifdef CONFIG_MCC_MODE
15730 		/* start MCC fail, then tx null data */
15731 		if (!rtw_hal_set_mcc_setting_scan_complete(padapter))
15732 #endif
15733 		{
15734 			rtw_hal_macid_wakeup_all_used(padapter);
15735 			rtw_ps_annc(padapter, 0);
15736 		}
15737 
15738 		/* apply rx ampdu setting */
15739 		rtw_rx_ampdu_apply(padapter);
15740 
15741 		mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
15742 
15743 		report_surveydone_event(padapter, ss->acs);
15744 #ifdef CONFIG_RTW_ACS
15745 		if (IS_ACS_ENABLE(padapter))
15746 			rtw_acs_select_best_chan(padapter);
15747 #endif
15748 
15749 #if defined(CONFIG_BACKGROUND_NOISE_MONITOR) && defined(DBG_NOISE_MONITOR)
15750 		if (IS_NM_ENABLE(padapter))
15751 			rtw_noise_info_dump(RTW_DBGDUMP, padapter);
15752 #endif
15753 		issue_action_BSSCoexistPacket(padapter);
15754 		issue_action_BSSCoexistPacket(padapter);
15755 		issue_action_BSSCoexistPacket(padapter);
15756 
15757 #ifdef CONFIG_RTW_80211K
15758 		if (ss->token)
15759 			rm_post_event(padapter, ss->token, RM_EV_survey_done);
15760 #endif /* CONFIG_RTW_80211K */
15761 #ifdef CONFIG_RTW_ROAM_QUICKSCAN
15762 		if (padapter->mlmepriv.need_to_roam == _TRUE)
15763 			generate_quickss(padapter);
15764 #endif
15765 		break;
15766 	}
15767 
15768 	return H2C_SUCCESS;
15769 }
15770 
setauth_hdl(_adapter * padapter,unsigned char * pbuf)15771 u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
15772 {
15773 	struct setauth_parm		*pparm = (struct setauth_parm *)pbuf;
15774 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
15775 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
15776 
15777 	if (pparm->mode < 4)
15778 		pmlmeinfo->auth_algo = pparm->mode;
15779 
15780 	return	H2C_SUCCESS;
15781 }
15782 
amsdu_spp_enable(_adapter * pdapter,enum security_type type)15783 static u8 amsdu_spp_enable(_adapter *pdapter, enum security_type type)
15784 {
15785 	u8 ret = _FALSE;
15786 
15787 	if (pdapter->registrypriv.amsdu_mode == RTW_AMSDU_MODE_SPP) {
15788 		if ( type == _AES_ || type == _CCMP_256_
15789 			|| type == _GCMP_ || type == _GCMP_256_ )
15790 			ret = _SUCCESS;
15791 	}
15792 
15793 	return ret;
15794 }
15795 
15796 /*
15797 SEC CAM Entry format (32 bytes)
15798 DW0 - MAC_ADDR[15:0] | Valid[15] | MFB[14:8] | RSVD[7]  | GK[6] | MIC_KEY[5] | SEC_TYPE[4:2] | KID[1:0]
15799 DW0 - MAC_ADDR[15:0] | Valid[15] |RSVD[14:9] | RPT_MODE[8] | SPP_MODE[7]  | GK[6] | MIC_KEY[5] | SEC_TYPE[4:2] | KID[1:0] (92E/8812A/8814A)
15800 DW1 - MAC_ADDR[47:16]
15801 DW2 - KEY[31:0]
15802 DW3 - KEY[63:32]
15803 DW4 - KEY[95:64]
15804 DW5 - KEY[127:96]
15805 DW6 - RSVD
15806 DW7 - RSVD
15807 */
15808 
15809 /*Set WEP key or Group Key*/
setkey_hdl(_adapter * padapter,u8 * pbuf)15810 u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
15811 {
15812 	u16	ctrl = 0;
15813 	s16 cam_id = 0;
15814 	struct setkey_parm		*pparm = (struct setkey_parm *)pbuf;
15815 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
15816 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
15817 	unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
15818 	u8 *addr;
15819 	bool used = _FALSE;
15820 
15821 	/* main tx key for wep. */
15822 	if (pparm->set_tx)
15823 		pmlmeinfo->key_index = pparm->keyid;
15824 
15825 #ifndef SEC_DEFAULT_KEY_SEARCH
15826 	if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE))
15827 		cam_id = rtw_iface_bcmc_id_get(padapter);
15828 	else
15829 #endif
15830 		cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid, 1,
15831 			!!(pparm->algorithm & _SEC_TYPE_256_), &used);
15832 
15833 	if (cam_id < 0)
15834 		goto enable_mc;
15835 
15836 #ifdef SEC_DEFAULT_KEY_SEARCH
15837 	if (cam_id >= 0 && cam_id <= 3) {
15838 		/* default key camid */
15839 		addr = null_addr;
15840 	} else
15841 #endif
15842 	{
15843 		/* not default key camid */
15844 		if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
15845 			/* group TX, force sec cam entry_id */
15846 			addr = adapter_mac_addr(padapter);
15847 		} else {
15848 			/* group RX, searched by A2 (TA) */
15849 			addr = get_bssid(&padapter->mlmepriv);
15850 		}
15851 	}
15852 
15853 #ifdef CONFIG_LPS_PG
15854 	if (adapter_to_pwrctl(padapter)->lps_level == LPS_PG)
15855 		LPS_Leave(padapter, "SET_KEY");
15856 #endif
15857 
15858 	/* cam entry searched is pairwise key */
15859 	if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _FALSE) {
15860 		s16 camid_clr;
15861 
15862 		RTW_PRINT(FUNC_ADPT_FMT" group key with "MAC_FMT" id:%u the same key id as pairwise key\n"
15863 			, FUNC_ADPT_ARG(padapter), MAC_ARG(addr), pparm->keyid);
15864 
15865 		/* HW has problem to distinguish this group key with existing pairwise key, stop HW enc and dec for BMC */
15866 		rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
15867 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
15868 
15869 		/* clear group key */
15870 		while ((camid_clr = rtw_camid_search(padapter, addr, -1, 1)) >= 0) {
15871 			RTW_PRINT("clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), camid_clr);
15872 			clear_cam_entry(padapter, camid_clr);
15873 			rtw_camid_free(padapter, camid_clr);
15874 		}
15875 
15876 		goto enable_mc;
15877 	}
15878 
15879 	ctrl = BIT(15) | BIT(6) | ((pparm->algorithm & 0x07) << 2) | pparm->keyid;
15880 
15881 	RTW_PRINT("set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
15882 		, cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm));
15883 
15884 	if (pparm->algorithm & _SEC_TYPE_256_)  {
15885 		RTW_INFO_DUMP("GTK : ", pparm->key, sizeof(pparm->key));
15886 		ctrl |= BIT(9);
15887 	}
15888 	if (amsdu_spp_enable(padapter, pparm->algorithm) == _SUCCESS)
15889 		ctrl |= BIT(7);
15890 	write_cam(padapter, cam_id, ctrl, addr, pparm->key);
15891 
15892 	/* if ((cam_id > 3) && (((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)))*/
15893 #ifndef SEC_DEFAULT_KEY_SEARCH
15894 	if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
15895 		if (is_wep_enc(pparm->algorithm)) {
15896 			padapter->securitypriv.dot11Def_camid[pparm->keyid] = cam_id;
15897 			padapter->securitypriv.dot118021x_bmc_cam_id =
15898 				padapter->securitypriv.dot11Def_camid[padapter->securitypriv.dot11PrivacyKeyIndex];
15899 			RTW_PRINT("wep group key - force camid:%d\n", padapter->securitypriv.dot118021x_bmc_cam_id);
15900 		} else {
15901 			/*u8 org_cam_id = padapter->securitypriv.dot118021x_bmc_cam_id;*/
15902 
15903 			/*force GK's cam id*/
15904 			padapter->securitypriv.dot118021x_bmc_cam_id = cam_id;
15905 
15906 			/* for GTK rekey
15907 			if ((org_cam_id != INVALID_SEC_MAC_CAM_ID) &&
15908 				(org_cam_id != cam_id)) {
15909 				RTW_PRINT("clear group key for addr:"MAC_FMT", org_camid:%d new_camid:%d\n", MAC_ARG(addr), org_cam_id, cam_id);
15910 				clear_cam_entry(padapter, org_cam_id);
15911 				rtw_camid_free(padapter, org_cam_id);
15912 			}*/
15913 		}
15914 	}
15915 #else
15916 	if (cam_id >= 0 && cam_id <= 3)
15917 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_TRUE);
15918 #endif
15919 
15920 	/* 8814au should set both broadcast and unicast CAM entry for WEP key in STA mode */
15921 	if (is_wep_enc(pparm->algorithm) && check_mlmeinfo_state(pmlmeext, WIFI_FW_STATION_STATE) &&
15922 	    _rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_BMC)) {
15923 		struct set_stakey_parm	sta_pparm;
15924 
15925 		_rtw_memset(&sta_pparm, 0, sizeof(struct set_stakey_parm));
15926 		sta_pparm.algorithm = pparm->algorithm;
15927 		sta_pparm.keyid = pparm->keyid;
15928 		_rtw_memcpy(sta_pparm.key, pparm->key, 16);
15929 		_rtw_memcpy(sta_pparm.addr, get_bssid(&padapter->mlmepriv), ETH_ALEN);
15930 		set_stakey_hdl(padapter, (u8 *)&sta_pparm);
15931 	}
15932 
15933 enable_mc:
15934 	/* allow multicast packets to driver */
15935 	rtw_hal_set_hwreg(padapter, HW_VAR_ON_RCR_AM, null_addr);
15936 #ifdef CONFIG_LAYER2_ROAMING
15937 	if (padapter->mlmepriv.roam_network) {
15938 		struct xmit_frame *rframe;
15939 		struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
15940 		_list *plist, *phead;
15941 		_irqL irqL;
15942 		_pkt *pkt;
15943 
15944 		padapter->mlmepriv.roam_network = NULL;
15945 		_enter_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL);
15946 		phead = get_list_head(&pxmitpriv->rpkt_queue);
15947 		plist = get_next(phead);
15948 		while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
15949 			rframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
15950 			plist = get_next(plist);
15951 			rtw_list_delete(&rframe->list);
15952 			pkt = rframe->pkt;
15953 			rtw_xmit_posthandle(padapter, rframe, pkt);
15954 		}
15955 		_exit_critical_bh(&pxmitpriv->rpkt_queue.lock, &irqL);
15956 	}
15957 #endif
15958 	return H2C_SUCCESS;
15959 }
15960 
rtw_ap_wep_pk_setting(_adapter * adapter,struct sta_info * psta)15961 void rtw_ap_wep_pk_setting(_adapter *adapter, struct sta_info *psta)
15962 {
15963 	struct security_priv *psecuritypriv = &(adapter->securitypriv);
15964 	struct set_stakey_parm	sta_pparm;
15965 	sint keyid;
15966 
15967 	if (!is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm))
15968 		return;
15969 
15970 	for (keyid = 0; keyid < 4; keyid++) {
15971 		if ((psecuritypriv->key_mask & BIT(keyid)) && (keyid == psecuritypriv->dot11PrivacyKeyIndex)) {
15972 			sta_pparm.algorithm = psecuritypriv->dot11PrivacyAlgrthm;
15973 			sta_pparm.keyid = keyid;
15974 			sta_pparm.gk = 0;
15975 			_rtw_memcpy(sta_pparm.key, &(psecuritypriv->dot11DefKey[keyid].skey[0]), 16);
15976 			_rtw_memcpy(sta_pparm.addr, psta->cmn.mac_addr, ETH_ALEN);
15977 
15978 			RTW_PRINT(FUNC_ADPT_FMT"set WEP - PK with "MAC_FMT" keyid:%u\n"
15979 				, FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr), keyid);
15980 
15981 			set_stakey_hdl(adapter, (u8 *)&sta_pparm);
15982 		}
15983 	}
15984 }
15985 
set_stakey_hdl(_adapter * padapter,u8 * pbuf)15986 u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
15987 {
15988 	u16 ctrl = 0;
15989 	s16 cam_id = 0;
15990 	bool used;
15991 	u8 ret = H2C_SUCCESS;
15992 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
15993 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
15994 	struct set_stakey_parm	*pparm = (struct set_stakey_parm *)pbuf;
15995 	struct sta_priv *pstapriv = &padapter->stapriv;
15996 	struct sta_info *psta;
15997 
15998 	if (pparm->algorithm == _NO_PRIVACY_)
15999 		goto write_to_cam;
16000 
16001 	psta = rtw_get_stainfo(pstapriv, pparm->addr);
16002 	if (!psta) {
16003 		RTW_PRINT("%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr));
16004 		ret = H2C_REJECTED;
16005 		goto exit;
16006 	}
16007 
16008 	pmlmeinfo->enc_algo = pparm->algorithm;
16009 
16010 	cam_id = rtw_camid_alloc(padapter, psta, pparm->keyid, pparm->gk,
16011 		!!(pparm->algorithm & _SEC_TYPE_256_), &used);
16012 	if (cam_id < 0)
16013 		goto exit;
16014 
16015 #ifdef CONFIG_LPS_PG
16016 	if (adapter_to_pwrctl(padapter)->lps_level == LPS_PG)
16017 		LPS_Leave(padapter, "SET_KEY");
16018 #endif
16019 
16020 	/* cam entry searched is group key when setting pariwise key */
16021 	if (!pparm->gk && used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _TRUE) {
16022 		s16 camid_clr;
16023 
16024 		RTW_PRINT(FUNC_ADPT_FMT" pairwise key with "MAC_FMT" id:%u the same key id as group key\n"
16025 			, FUNC_ADPT_ARG(padapter), MAC_ARG(pparm->addr), pparm->keyid);
16026 
16027 		/* HW has problem to distinguish this pairwise key with existing group key, stop HW enc and dec for BMC */
16028 		rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
16029 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
16030 
16031 		/* clear group key */
16032 		while ((camid_clr = rtw_camid_search(padapter, pparm->addr, -1, 1)) >= 0) {
16033 			RTW_PRINT("clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), camid_clr);
16034 			clear_cam_entry(padapter, camid_clr);
16035 			rtw_camid_free(padapter, camid_clr);
16036 		}
16037 	}
16038 
16039 write_to_cam:
16040 	if (pparm->algorithm == _NO_PRIVACY_) {
16041 		while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1, -1)) >= 0) {
16042 			RTW_PRINT("clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id);
16043 			clear_cam_entry(padapter, cam_id);
16044 			rtw_camid_free(padapter, cam_id);
16045 		}
16046 	} else {
16047 		RTW_PRINT("set %s key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
16048 			, pparm->gk ? "group" : "pairwise"
16049 			, cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm));
16050 		ctrl = BIT(15) | ((pparm->algorithm & 0x07) << 2) | pparm->keyid;
16051 		if (pparm->gk)
16052 			ctrl |= BIT(6);
16053 		if (pparm->algorithm & _SEC_TYPE_256_) {
16054 			RTW_INFO_DUMP("PTK : ", pparm->key, sizeof(pparm->key));
16055 			ctrl |= BIT(9);
16056 		}
16057 
16058 		if (amsdu_spp_enable(padapter, pparm->algorithm) == _SUCCESS)
16059 			ctrl |= BIT(7);
16060 
16061 		write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
16062 		if (!(pparm->gk))
16063 			ATOMIC_INC(&psta->keytrack);	/*CVE-2020-24587*/
16064 	}
16065 	ret = H2C_SUCCESS_RSP;
16066 
16067 exit:
16068 	return ret;
16069 }
16070 
add_ba_hdl(_adapter * padapter,unsigned char * pbuf)16071 u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
16072 {
16073 	struct addBaReq_parm	*pparm = (struct addBaReq_parm *)pbuf;
16074 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
16075 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
16076 
16077 	struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
16078 
16079 	if (!psta)
16080 		return	H2C_SUCCESS;
16081 
16082 #ifdef CONFIG_80211N_HT
16083 	if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
16084 	    ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
16085 		/* pmlmeinfo->ADDBA_retry_count = 0; */
16086 		/* pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid);		 */
16087 		/* psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid); */
16088 		issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
16089 		_set_timer(&psta->addba_retry_timer, ADDBA_TO);
16090 	}
16091 #ifdef CONFIG_TDLS
16092 	else if ((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
16093 		 (psta->htpriv.ht_option == _TRUE) &&
16094 		 (psta->htpriv.ampdu_enable == _TRUE)) {
16095 		issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
16096 		_set_timer(&psta->addba_retry_timer, ADDBA_TO);
16097 	}
16098 #endif /* CONFIG */
16099 	else
16100 		psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
16101 #endif /* CONFIG_80211N_HT */
16102 	return	H2C_SUCCESS;
16103 }
16104 
16105 
add_ba_rsp_hdl(_adapter * padapter,unsigned char * pbuf)16106 u8 add_ba_rsp_hdl(_adapter *padapter, unsigned char *pbuf)
16107 {
16108 	struct addBaRsp_parm *pparm = (struct addBaRsp_parm *)pbuf;
16109 	struct recv_reorder_ctrl *preorder_ctrl;
16110 	struct sta_priv *pstapriv = &padapter->stapriv;
16111 	struct sta_info *psta;
16112 	u8 ret = _TRUE;
16113 
16114 	psta = rtw_get_stainfo(pstapriv, pparm->addr);
16115 	if (!psta)
16116 		goto exit;
16117 
16118 	preorder_ctrl = &psta->recvreorder_ctrl[pparm->tid];
16119 	ret = issue_addba_rsp_wait_ack(padapter, pparm->addr, pparm->tid, pparm->status, pparm->size, 3, 50);
16120 
16121 #ifdef CONFIG_UPDATE_INDICATE_SEQ_WHILE_PROCESS_ADDBA_REQ
16122 	/* status = 0 means accept this addba req, so update indicate seq = start_seq under this compile flag */
16123 	if (pparm->status == 0) {
16124 		preorder_ctrl->indicate_seq = pparm->start_seq;
16125 		#ifdef DBG_RX_SEQ
16126 		RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_UPDATE indicate_seq:%d, start_seq:%d\n"
16127 			, FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, pparm->start_seq);
16128 		#endif
16129 	}
16130 #else
16131 	rtw_set_bit(RTW_RECV_ACK_OR_TIMEOUT, &preorder_ctrl->rec_abba_rsp_ack);
16132 	#ifdef DBG_RX_SEQ
16133 	RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_CLEAR indicate_seq:%d, start_seq:%d preorder_ctrl->rec_abba_rsp_ack =%lu \n"
16134 		, FUNC_ADPT_ARG(padapter)
16135 		, preorder_ctrl->tid
16136 		, preorder_ctrl->indicate_seq
16137 		, pparm->start_seq
16138 		,preorder_ctrl->rec_abba_rsp_ack
16139 		);
16140 	#endif
16141 #endif
16142 
16143 	/*
16144 	  * status = 0 means accept this addba req
16145 	  * status = 37 means reject this addba req
16146 	  */
16147 	if (pparm->status == 0) {
16148 		preorder_ctrl->enable = _TRUE;
16149 		preorder_ctrl->ampdu_size = pparm->size;
16150 	} else if (pparm->status == 37)
16151 		preorder_ctrl->enable = _FALSE;
16152 
16153 exit:
16154 	return H2C_SUCCESS;
16155 }
16156 
chk_bmc_sleepq_cmd(_adapter * padapter)16157 u8 chk_bmc_sleepq_cmd(_adapter *padapter)
16158 {
16159 	struct cmd_obj *ph2c;
16160 	struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
16161 	u8 res = _SUCCESS;
16162 
16163 
16164 	ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
16165 	if (ph2c == NULL) {
16166 		res = _FAIL;
16167 		goto exit;
16168 	}
16169 
16170 	init_h2fwcmd_w_parm_no_parm_rsp(ph2c, CMD_CHK_BMCSLEEPQ);
16171 
16172 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
16173 
16174 exit:
16175 
16176 
16177 	return res;
16178 }
16179 
set_tx_beacon_cmd(_adapter * padapter,u8 flags)16180 u8 set_tx_beacon_cmd(_adapter *padapter, u8 flags)
16181 {
16182 	struct cmd_obj	*ph2c;
16183 	struct Tx_Beacon_param	*ptxBeacon_parm;
16184 	struct cmd_priv	*pcmdpriv = &(padapter->cmdpriv);
16185 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
16186 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
16187 	struct submit_ctx sctx;
16188 	u8	res = _SUCCESS;
16189 	int len_diff = 0;
16190 
16191 	/*prepare cmd parameter*/
16192 	ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param));
16193 	if (ptxBeacon_parm == NULL) {
16194 		res = _FAIL;
16195 		goto exit;
16196 	}
16197 
16198 	_rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
16199 
16200 	len_diff = update_hidden_ssid(
16201 			   ptxBeacon_parm->network.IEs + _BEACON_IE_OFFSET_
16202 		   , ptxBeacon_parm->network.IELength - _BEACON_IE_OFFSET_
16203 			   , pmlmeinfo->hidden_ssid_mode
16204 		   );
16205 	ptxBeacon_parm->network.IELength += len_diff;
16206 
16207 
16208 	/* need enqueue, prepare cmd_obj and enqueue */
16209 	ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
16210 	if (ph2c == NULL) {
16211 		res = _FAIL;
16212 		rtw_mfree((u8 *)ptxBeacon_parm, sizeof(*ptxBeacon_parm));
16213 		goto exit;
16214 	}
16215 
16216 	init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, CMD_TX_BEACON);
16217 
16218 	if (flags & RTW_CMDF_WAIT_ACK) {
16219 		ph2c->sctx = &sctx;
16220 		rtw_sctx_init(&sctx, 10 * 1000);
16221 	}
16222 
16223 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
16224 
16225 	if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) {
16226 		rtw_sctx_wait(&sctx, __func__);
16227 		_enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL);
16228 		if (sctx.status == RTW_SCTX_SUBMITTED)
16229 			ph2c->sctx = NULL;
16230 		_exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL);
16231 	}
16232 
16233 
16234 exit:
16235 
16236 
16237 	return res;
16238 }
16239 
16240 
mlme_evt_hdl(_adapter * padapter,unsigned char * pbuf)16241 u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
16242 {
16243 	struct rtw_evt_header *evt_hdr;
16244 	u8 *peventbuf;
16245 	void (*event_callback)(_adapter *dev, u8 *pbuf);
16246 	struct evt_priv *pevt_priv = &(padapter->evtpriv);
16247 
16248 	if (pbuf == NULL)
16249 		goto _abort_event_;
16250 
16251 	evt_hdr = (struct rtw_evt_header *)pbuf;
16252 	peventbuf = pbuf + sizeof(struct rtw_evt_header);
16253 
16254 #ifdef CHECK_EVENT_SEQ
16255 	/* checking event sequence...		 */
16256 	if (evt_hdr->seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f)) {
16257 		pevt_priv->event_seq = (evt_hdr->seq + 1) & 0x7f;
16258 		goto _abort_event_;
16259 	}
16260 #endif
16261 
16262 	/* checking if event code is valid */
16263 	if (evt_hdr->id >= EVT_ID_MAX) {
16264 		goto _abort_event_;
16265 	}
16266 
16267 	/* checking if event size match the event parm size	 */
16268 	if ((wlanevents[evt_hdr->id].parmsize != 0) &&
16269 	    (wlanevents[evt_hdr->id].parmsize != evt_hdr->len)) {
16270 
16271 		goto _abort_event_;
16272 
16273 	}
16274 
16275 	ATOMIC_INC(&pevt_priv->event_seq);
16276 
16277 	if (peventbuf) {
16278 		event_callback = wlanevents[evt_hdr->id].event_callback;
16279 		event_callback(padapter, (u8 *)peventbuf);
16280 		pevt_priv->evt_done_cnt++;
16281 	}
16282 
16283 _abort_event_:
16284 	return H2C_SUCCESS;
16285 
16286 }
16287 
chk_bmc_sleepq_hdl(_adapter * padapter,unsigned char * pbuf)16288 u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf)
16289 {
16290 #ifdef CONFIG_AP_MODE
16291 	_irqL irqL;
16292 	struct sta_info *psta_bmc;
16293 	_list	*xmitframe_plist, *xmitframe_phead;
16294 	struct xmit_frame *pxmitframe = NULL;
16295 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
16296 	struct sta_priv  *pstapriv = &padapter->stapriv;
16297 
16298 	/* for BC/MC Frames */
16299 	psta_bmc = rtw_get_bcmc_stainfo(padapter);
16300 	if (!psta_bmc)
16301 		return H2C_SUCCESS;
16302 
16303 	if ((rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, 0)) && (psta_bmc->sleepq_len > 0)) {
16304 #ifndef CONFIG_PCI_HCI
16305 		rtw_msleep_os(10);/* 10ms, ATIM(HIQ) Windows */
16306 #endif
16307 		/* _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL); */
16308 		_enter_critical_bh(&pxmitpriv->lock, &irqL);
16309 
16310 		xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
16311 		xmitframe_plist = get_next(xmitframe_phead);
16312 
16313 		while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
16314 			pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
16315 
16316 			xmitframe_plist = get_next(xmitframe_plist);
16317 
16318 			rtw_list_delete(&pxmitframe->list);
16319 
16320 			psta_bmc->sleepq_len--;
16321 			if (psta_bmc->sleepq_len > 0)
16322 				pxmitframe->attrib.mdata = 1;
16323 			else
16324 				pxmitframe->attrib.mdata = 0;
16325 
16326 			pxmitframe->attrib.triggered = 1;
16327 
16328 			if (xmitframe_hiq_filter(pxmitframe) == _TRUE)
16329 				pxmitframe->attrib.qsel = QSLT_HIGH;/* HIQ */
16330 
16331 #if 0
16332 			_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
16333 			if (rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
16334 				rtw_os_xmit_complete(padapter, pxmitframe);
16335 			_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
16336 #endif
16337 			rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
16338 		}
16339 
16340 		/* _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); */
16341 		_exit_critical_bh(&pxmitpriv->lock, &irqL);
16342 
16343 		if (rtw_get_intf_type(padapter) != RTW_PCIE) {
16344 			/* check hi queue and bmc_sleepq */
16345 			rtw_chk_hi_queue_cmd(padapter);
16346 		}
16347 	}
16348 #endif
16349 
16350 	return H2C_SUCCESS;
16351 }
16352 
tx_beacon_hdl(_adapter * padapter,unsigned char * pbuf)16353 u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
16354 {
16355 #ifdef CONFIG_AP_MODE
16356 	/*RTW_INFO(FUNC_ADPT_FMT, FUNC_ADPT_ARG(padapter));*/
16357 #ifdef CONFIG_SWTIMER_BASED_TXBCN
16358 
16359 	tx_beacon_handlder(padapter->dvobj);
16360 
16361 #else
16362 
16363 	if (send_beacon(padapter) == _FAIL) {
16364 		RTW_INFO("issue_beacon, fail!\n");
16365 		return H2C_PARAMETERS_ERROR;
16366 	}
16367 
16368 	/* tx bc/mc frames after update TIM */
16369 	chk_bmc_sleepq_hdl(padapter, NULL);
16370 #endif
16371 #endif /* CONFIG_AP_MODE */
16372 	return H2C_SUCCESS;
16373 }
16374 
16375 /*
16376 * according to channel
16377 * add/remove WLAN_BSSID_EX.IEs's ERP ie
16378 * set WLAN_BSSID_EX.SupportedRates
16379 * update WLAN_BSSID_EX.IEs's Supported Rate and Extended Supported Rate ie
16380 */
16381 #ifdef CONFIG_AP_MODE
change_band_update_ie(_adapter * padapter,WLAN_BSSID_EX * pnetwork,u8 ch)16382 void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch)
16383 {
16384 	u8	network_type, rate_len, total_rate_len, remainder_rate_len;
16385 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
16386 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
16387 	u8	erpinfo = 0x4;
16388 
16389 	if (ch >= 36) {
16390 		network_type = WIRELESS_11A;
16391 		total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
16392 		rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
16393 		#ifdef CONFIG_80211AC_VHT
16394 		/* if channel in 5G band, then add vht ie . */
16395 		if ((pmlmepriv->htpriv.ht_option == _TRUE)
16396 			&& REGSTY_IS_11AC_ENABLE(&padapter->registrypriv)
16397 			&& is_supported_vht(padapter->registrypriv.wireless_mode)
16398 			&& RFCTL_REG_EN_11AC(rfctl)
16399 		) {
16400 			if (pmlmepriv->vhtpriv.upper_layer_setting)
16401 				rtw_reattach_vht_ies(padapter, pnetwork);
16402 			else if (REGSTY_IS_11AC_AUTO(&padapter->registrypriv))
16403 				rtw_vht_ies_attach(padapter, pnetwork);
16404 		}
16405 		#endif
16406 	} else {
16407 		network_type = 0;
16408 		total_rate_len = 0;
16409 		if (padapter->registrypriv.wireless_mode & WIRELESS_11B) {
16410 			network_type |= WIRELESS_11B;
16411 			total_rate_len += IEEE80211_CCK_RATE_LEN;
16412 		}
16413 		if (padapter->registrypriv.wireless_mode & WIRELESS_11G) {
16414 			network_type |= WIRELESS_11G;
16415 			total_rate_len += IEEE80211_NUM_OFDM_RATESLEN;
16416 		}
16417 		rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
16418 		#ifdef CONFIG_80211AC_VHT
16419 		rtw_vht_ies_detach(padapter, pnetwork);
16420 		#endif
16421 	}
16422 
16423 	rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
16424 
16425 	UpdateBrateTbl(padapter, pnetwork->SupportedRates);
16426 
16427 	if (total_rate_len > 8) {
16428 		rate_len = 8;
16429 		remainder_rate_len = total_rate_len - 8;
16430 	} else {
16431 		rate_len = total_rate_len;
16432 		remainder_rate_len = 0;
16433 	}
16434 
16435 	rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
16436 
16437 	if (remainder_rate_len)
16438 		rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates + 8), remainder_rate_len);
16439 	else
16440 		rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
16441 
16442 	pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork);
16443 }
16444 #endif /* CONFIG_AP_MODE */
16445 
rtw_join_done_chk_ch(_adapter * adapter,int join_res)16446 void rtw_join_done_chk_ch(_adapter *adapter, int join_res)
16447 {
16448 #define DUMP_ADAPTERS_STATUS 0
16449 
16450 	struct dvobj_priv *dvobj;
16451 	_adapter *iface;
16452 	struct mlme_priv *mlme;
16453 	struct mlme_ext_priv *mlmeext;
16454 	u8 u_ch, u_offset, u_bw;
16455 	int i, ret;
16456 
16457 	dvobj = adapter_to_dvobj(adapter);
16458 
16459 	if (DUMP_ADAPTERS_STATUS) {
16460 		RTW_INFO(FUNC_ADPT_FMT" enter\n", FUNC_ADPT_ARG(adapter));
16461 		dump_adapters_status(RTW_DBGDUMP , dvobj);
16462 	}
16463 
16464 	ret = rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset);
16465 	if (join_res >= 0 && ret <= 0) {
16466 		join_res = -1;
16467 		dump_adapters_status(RTW_DBGDUMP , dvobj);
16468 		rtw_warn_on(1);
16469 	}
16470 
16471 	if (join_res >= 0) {
16472 #ifdef CONFIG_MCC_MODE
16473 		/* MCC setting success, don't go to ch union process */
16474 		if (rtw_hal_set_mcc_setting_join_done_chk_ch(adapter))
16475 			return;
16476 #endif /* CONFIG_MCC_MODE */
16477 
16478 		for (i = 0; i < dvobj->iface_nums; i++) {
16479 			iface = dvobj->padapters[i];
16480 			mlme = &iface->mlmepriv;
16481 			mlmeext = &iface->mlmeextpriv;
16482 
16483 			if (!iface || iface == adapter)
16484 				continue;
16485 
16486 #ifdef CONFIG_AP_MODE
16487 			if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
16488 				&& check_fwstate(mlme, WIFI_ASOC_STATE)
16489 			) {
16490 				u8 ori_ch, ori_bw, ori_offset;
16491 				bool is_grouped = rtw_is_chbw_grouped(u_ch, u_bw, u_offset
16492 					, mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
16493 
16494 				if (is_grouped == _FALSE) {
16495 					/* handle AP which need to switch ch setting */
16496 
16497 					ori_ch = mlmeext->cur_channel;
16498 					ori_bw = mlmeext->cur_bwmode;
16499 					ori_offset = mlmeext->cur_ch_offset;
16500 
16501 					/* restore original bw, adjust bw by registry setting on target ch */
16502 					mlmeext->cur_bwmode = mlme->ori_bw;
16503 					mlmeext->cur_channel = u_ch;
16504 					rtw_adjust_chbw(iface, mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset);
16505 					#ifdef CONFIG_RTW_MESH
16506 					if (MLME_IS_MESH(iface))
16507 						rtw_mesh_adjust_chbw(mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset);
16508 					#endif
16509 
16510 					rtw_chset_sync_chbw(adapter_to_chset(adapter)
16511 						, &mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset
16512 						, &u_ch, &u_bw, &u_offset, 1, 0);
16513 
16514 					RTW_INFO(FUNC_ADPT_FMT" %u,%u,%u => %u,%u,%u\n", FUNC_ADPT_ARG(iface)
16515 						, ori_ch, ori_bw, ori_offset
16516 						, mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
16517 
16518 					rtw_ap_update_bss_chbw(iface, &(mlmeext->mlmext_info.network)
16519 						, mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
16520 
16521 					_rtw_memcpy(&(mlme->cur_network.network), &(mlmeext->mlmext_info.network), sizeof(WLAN_BSSID_EX));
16522 
16523 					rtw_start_bss_hdl_after_chbw_decided(iface);
16524 
16525 					{
16526 						#if defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
16527 						u8 ht_option = 0;
16528 
16529 						#ifdef CONFIG_80211N_HT
16530 						ht_option = mlme->htpriv.ht_option;
16531 						#endif
16532 
16533 						rtw_cfg80211_ch_switch_notify(iface
16534 							, mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset
16535 							, ht_option, 0);
16536 						#endif
16537 					}
16538 				}
16539 
16540 				clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
16541 				#ifdef CONFIG_ACTIVE_TPC_REPORT
16542 				if (MLME_ACTIVE_TPC_REPORT(mlme))
16543 					update_beacon(iface, WLAN_EID_TPC_REPORT, NULL, _FALSE, 0);
16544 				#endif
16545 				update_beacon(iface, 0xFF, NULL, _TRUE, 0);
16546 			}
16547 #endif /* CONFIG_AP_MODE */
16548 		}
16549 
16550 #ifdef CONFIG_DFS_MASTER
16551 		rtw_dfs_rd_en_decision(adapter, MLME_STA_CONNECTED, 0);
16552 #endif
16553 	} else {
16554 		for (i = 0; i < dvobj->iface_nums; i++) {
16555 			iface = dvobj->padapters[i];
16556 			mlme = &iface->mlmepriv;
16557 			mlmeext = &iface->mlmeextpriv;
16558 
16559 			if (!iface || iface == adapter)
16560 				continue;
16561 #ifdef CONFIG_AP_MODE
16562 			if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
16563 				&& check_fwstate(mlme, WIFI_ASOC_STATE)
16564 			) {
16565 				clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
16566 				update_beacon(iface, 0xFF, NULL, _TRUE, 0);
16567 			}
16568 #endif
16569 		}
16570 
16571 		#ifdef CONFIG_80211D
16572 		rtw_leavebss_update_regulatory(adapter);
16573 		#endif
16574 
16575 #ifdef CONFIG_DFS_MASTER
16576 		rtw_dfs_rd_en_decision(adapter, MLME_STA_DISCONNECTED, 0);
16577 #endif
16578 	}
16579 
16580 	if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset)) {
16581 		RTW_INFO(FUNC_ADPT_FMT" union:%u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
16582 		set_channel_bwmode(adapter, u_ch, u_offset, u_bw);
16583 	}
16584 
16585 	rtw_mi_update_union_chan_inf(adapter, u_ch, u_offset, u_bw);
16586 
16587 	if (join_res >= 0)
16588 		rtw_rfctl_update_op_mode(adapter_to_rfctl(adapter), BIT(adapter->iface_id), 1);
16589 
16590 	if (DUMP_ADAPTERS_STATUS) {
16591 		RTW_INFO(FUNC_ADPT_FMT" exit\n", FUNC_ADPT_ARG(adapter));
16592 		dump_adapters_status(RTW_DBGDUMP , dvobj);
16593 	}
16594 }
16595 
rtw_chk_start_clnt_join(_adapter * adapter,u8 * ch,u8 * bw,u8 * offset)16596 int rtw_chk_start_clnt_join(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
16597 {
16598 #ifdef CONFIG_CONCURRENT_MODE
16599 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
16600 	bool chbw_allow = _TRUE;
16601 #endif
16602 	bool connect_allow = _TRUE;
16603 	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
16604 	u8 cur_ch, cur_bw, cur_ch_offset;
16605 	u8 u_ch, u_offset, u_bw;
16606 
16607 	u_ch = cur_ch = pmlmeext->cur_channel;
16608 	u_bw = cur_bw = pmlmeext->cur_bwmode;
16609 	u_offset = cur_ch_offset = pmlmeext->cur_ch_offset;
16610 
16611 	if (!ch || !bw || !offset) {
16612 		connect_allow = _FALSE;
16613 		rtw_warn_on(1);
16614 		goto exit;
16615 	}
16616 
16617 	if (cur_ch == 0) {
16618 		connect_allow = _FALSE;
16619 		RTW_ERR(FUNC_ADPT_FMT" cur_ch:%u\n"
16620 			, FUNC_ADPT_ARG(adapter), cur_ch);
16621 		rtw_warn_on(1);
16622 		goto exit;
16623 	}
16624 	RTW_INFO(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
16625 
16626 #ifdef CONFIG_CONCURRENT_MODE
16627 	{
16628 		struct dvobj_priv *dvobj;
16629 		_adapter *iface;
16630 		struct mlme_priv *mlme;
16631 		struct mlme_ext_priv *mlmeext;
16632 		struct mi_state mstate;
16633 		int i;
16634 
16635 		dvobj = adapter_to_dvobj(adapter);
16636 
16637 		rtw_mi_status_no_self(adapter, &mstate);
16638 		RTW_INFO(FUNC_ADPT_FMT" others ld_sta_num:%u, ap_num:%u, mesh_num:%u\n"
16639 			, FUNC_ADPT_ARG(adapter), MSTATE_STA_LD_NUM(&mstate)
16640 			, MSTATE_AP_NUM(&mstate), MSTATE_MESH_NUM(&mstate));
16641 
16642 		if (!MSTATE_STA_LD_NUM(&mstate) && !MSTATE_AP_NUM(&mstate) && !MSTATE_MESH_NUM(&mstate)) {
16643 			/* consider linking STA? */
16644 			goto connect_allow_hdl;
16645 		}
16646 
16647 		if (rtw_mi_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
16648 			dump_adapters_status(RTW_DBGDUMP , dvobj);
16649 			rtw_warn_on(1);
16650 		}
16651 		RTW_INFO(FUNC_ADPT_FMT" others union:%u,%u,%u\n"
16652 			 , FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
16653 
16654 		/* chbw_allow? */
16655 		chbw_allow = rtw_is_chbw_grouped(pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset
16656 						 , u_ch, u_bw, u_offset);
16657 
16658 		RTW_INFO(FUNC_ADPT_FMT" chbw_allow:%d\n"
16659 			 , FUNC_ADPT_ARG(adapter), chbw_allow);
16660 
16661 #ifdef CONFIG_MCC_MODE
16662 		/* check setting success, don't go to ch union process */
16663 		if (rtw_hal_set_mcc_setting_chk_start_clnt_join(adapter, &u_ch, &u_bw, &u_offset, chbw_allow))
16664 			goto exit;
16665 #endif
16666 
16667 		if (chbw_allow == _TRUE) {
16668 			rtw_sync_chbw(&cur_ch, &cur_bw, &cur_ch_offset, &u_ch, &u_bw, &u_offset);
16669 			rtw_warn_on(cur_ch != pmlmeext->cur_channel);
16670 			rtw_warn_on(cur_bw != pmlmeext->cur_bwmode);
16671 			rtw_warn_on(cur_ch_offset != pmlmeext->cur_ch_offset);
16672 			goto connect_allow_hdl;
16673 		}
16674 
16675 #ifdef CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT
16676 		/* chbw_allow is _FALSE, connect allow? */
16677 		for (i = 0; i < dvobj->iface_nums; i++) {
16678 			iface = dvobj->padapters[i];
16679 			mlme = &iface->mlmepriv;
16680 			mlmeext = &iface->mlmeextpriv;
16681 
16682 			if (check_fwstate(mlme, WIFI_STATION_STATE)
16683 			    && check_fwstate(mlme, WIFI_ASOC_STATE)
16684 #if defined(CONFIG_P2P)
16685 			    && rtw_p2p_chk_state(&(iface->wdinfo), P2P_STATE_NONE)
16686 #endif
16687 			   ) {
16688 				connect_allow = _FALSE;
16689 				break;
16690 			}
16691 		}
16692 #endif /* CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT */
16693 
16694 		if (MSTATE_STA_LD_NUM(&mstate) + MSTATE_AP_LD_NUM(&mstate) + MSTATE_MESH_LD_NUM(&mstate) >= 4)
16695 			connect_allow = _FALSE;
16696 
16697 		RTW_INFO(FUNC_ADPT_FMT" connect_allow:%d\n"
16698 			 , FUNC_ADPT_ARG(adapter), connect_allow);
16699 
16700 		if (connect_allow == _FALSE)
16701 			goto exit;
16702 
16703 connect_allow_hdl:
16704 		/* connect_allow == _TRUE */
16705 
16706 		if (chbw_allow == _FALSE) {
16707 			u_ch = cur_ch;
16708 			u_bw = cur_bw;
16709 			u_offset = cur_ch_offset;
16710 
16711 			for (i = 0; i < dvobj->iface_nums; i++) {
16712 				iface = dvobj->padapters[i];
16713 				mlme = &iface->mlmepriv;
16714 				mlmeext = &iface->mlmeextpriv;
16715 
16716 				if (!iface || iface == adapter)
16717 					continue;
16718 
16719 				#ifdef CONFIG_AP_MODE
16720 				if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
16721 					&& check_fwstate(mlme, WIFI_ASOC_STATE)
16722 				) {
16723 					#ifdef CONFIG_SPCT_CH_SWITCH
16724 					if (1)
16725 						rtw_ap_inform_ch_switch(iface, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
16726 					else
16727 					#endif
16728 					if (rfctl->ap_csa_en == AP_CSA_DISABLE)
16729 						rtw_sta_flush(iface, _FALSE);
16730 
16731 					rtw_hal_set_hwreg(iface, HW_VAR_CHECK_TXBUF, 0);
16732 					set_fwstate(mlme, WIFI_OP_CH_SWITCHING);
16733 				} else
16734 				#endif /* CONFIG_AP_MODE */
16735 				if (check_fwstate(mlme, WIFI_STATION_STATE)
16736 					&& check_fwstate(mlme, WIFI_ASOC_STATE)
16737 				) {
16738 					rtw_disassoc_cmd(iface, 500, RTW_CMDF_DIRECTLY);
16739 					rtw_indicate_disconnect(iface, 0, _FALSE);
16740 					rtw_free_assoc_resources(iface, _TRUE);
16741 				}
16742 			}
16743 		}
16744 	}
16745 #endif /* CONFIG_CONCURRENT_MODE */
16746 
16747 	#ifdef CONFIG_80211D
16748 	rtw_joinbss_update_regulatory(adapter, &adapter->mlmeextpriv.mlmext_info.network);
16749 	#endif
16750 
16751 	#ifdef CONFIG_DFS_MASTER
16752 	rtw_dfs_rd_en_decision(adapter, MLME_STA_CONNECTING, 0);
16753 	#endif
16754 
16755 exit:
16756 
16757 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
16758 	if (rfctl->ap_csa_en != AP_CSA_DISABLE) {
16759 		u8 enable = 0;
16760 		rfctl->ap_csa_en = AP_CSA_DISABLE;
16761 		rtw_hal_set_hwreg(adapter, HW_VAR_BCN_EARLY_C2H_RPT, &enable);
16762 	}
16763 #endif
16764 
16765 	if (connect_allow == _TRUE) {
16766 		RTW_INFO(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
16767 		rtw_mi_update_union_chan_inf(adapter, u_ch, u_offset, u_bw);
16768 		*ch = u_ch;
16769 		*bw = u_bw;
16770 		*offset = u_offset;
16771 
16772 #if defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
16773 		{
16774 			u8 ht_option = 0;
16775 
16776 #ifdef CONFIG_80211N_HT
16777 			ht_option = adapter->mlmepriv.htpriv.ht_option;
16778 #endif /* CONFIG_80211N_HT */
16779 
16780 			/*
16781 				when supplicant send the mlme frame,
16782 				the bss freq is updated by channel switch event.
16783 			*/
16784 			rtw_cfg80211_ch_switch_notify(adapter,
16785 				cur_ch, cur_bw, cur_ch_offset, ht_option, 1);
16786 		}
16787 #endif
16788 	}
16789 
16790 	return connect_allow == _TRUE ? _SUCCESS : _FAIL;
16791 }
16792 
rtw_set_external_auth_status(_adapter * padapter,const void * data,int len)16793 void rtw_set_external_auth_status(_adapter *padapter,
16794 	const void *data, int len)
16795 {
16796 #ifdef CONFIG_IOCTL_CFG80211
16797 	struct net_device *dev = padapter->pnetdev;
16798 	struct wiphy *wiphy = adapter_to_wiphy(padapter);
16799 	struct rtw_external_auth_params params;
16800 
16801 	/* convert data to external_auth_params */
16802 	params.action = RTW_GET_BE32((u8 *)data);
16803 	_rtw_memcpy(&params.bssid, (u8 *)data + 4, ETH_ALEN);
16804 	_rtw_memcpy(&params.ssid.ssid, (u8 *)data + 10, WLAN_SSID_MAXLEN);
16805 	params.ssid.ssid_len = RTW_GET_BE64((u8 *)data + 42);
16806 	params.key_mgmt_suite = RTW_GET_BE32((u8 *)data + 58);
16807 	params.status = RTW_GET_BE16((u8 *)data + 62);
16808 	_rtw_memcpy(&params.pmkid, (u8 *)data + 64, PMKID_LEN);
16809 
16810 	rtw_cfg80211_external_auth_status(wiphy, dev, &params);
16811 #endif /* CONFIG_IOCTL_CFG80211 */
16812 }
16813 
rtw_iqk_hdl(_adapter * padapter,unsigned char * pbuf)16814 u8 rtw_iqk_hdl(_adapter *padapter, unsigned char *pbuf)
16815 {
16816 	rtw_hal_phydm_cal_trigger(padapter);
16817 	return	H2C_SUCCESS;
16818 }
16819 
rtw_set_chbw_hdl(_adapter * padapter,u8 * pbuf)16820 u8 rtw_set_chbw_hdl(_adapter *padapter, u8 *pbuf)
16821 {
16822 	struct set_ch_parm *set_ch_parm;
16823 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
16824 	u8 ifbmp_s = rtw_mi_get_ld_sta_ifbmp(padapter);
16825 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
16826 	u8 u_ch, u_bw, u_offset;
16827 
16828 	if (!pbuf)
16829 		return H2C_PARAMETERS_ERROR;
16830 
16831 	set_ch_parm = (struct set_ch_parm *)pbuf;
16832 
16833 	RTW_INFO(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
16834 		 FUNC_NDEV_ARG(padapter->pnetdev),
16835 		 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
16836 
16837 	/*  update ch, bw, offset for all asoc STA ifaces */
16838 	if (ifbmp_s) {
16839 		_adapter *iface;
16840 		int i;
16841 
16842 		for (i = 0; i < dvobj->iface_nums; i++) {
16843 			iface = dvobj->padapters[i];
16844 			if (!iface || !(ifbmp_s & BIT(iface->iface_id)))
16845 				continue;
16846 
16847 			/* update STA mode ch/bw/offset */
16848 			iface->mlmeextpriv.cur_channel = set_ch_parm->ch;
16849 			iface->mlmeextpriv.cur_bwmode = set_ch_parm->bw;
16850 			iface->mlmeextpriv.cur_ch_offset = set_ch_parm->ch_offset;
16851 			/* updaet STA mode DSConfig , ap mode will update in rtw_change_bss_chbw_cmd */
16852 			iface->mlmepriv.cur_network.network.Configuration.DSConfig = set_ch_parm->ch;
16853 		}
16854 	}
16855 
16856 	LeaveAllPowerSaveModeDirect(padapter);
16857 
16858 	set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
16859 
16860 	rtw_mi_get_ch_setting_union(padapter, &u_ch, &u_bw, &u_offset);
16861 	rtw_mi_update_union_chan_inf(padapter, u_ch, u_offset, u_bw);
16862 	rtw_rfctl_update_op_mode(dvobj_to_rfctl(dvobj), 0, 0);
16863 
16864 	return	H2C_SUCCESS;
16865 }
16866 
get_str_of_set_chplan_keys(char * buf,u8 buf_len,struct SetChannelPlan_param * param)16867 static void get_str_of_set_chplan_keys(char *buf, u8 buf_len, struct SetChannelPlan_param *param)
16868 {
16869 	char *pos = buf;
16870 
16871 #ifdef CONFIG_80211D
16872 	if (param->has_cisr) {
16873 		pos += snprintf(pos, buf_len - (pos - buf), "alpha2:"ALPHA2_FMT" %s"
16874 			, ALPHA2_ARG(param->cisr.alpha2), cis_status_str(param->cisr.status));
16875 	} else
16876 #endif
16877 	if (param->has_country)
16878 		pos += snprintf(pos, buf_len - (pos - buf), "alpha2:"ALPHA2_FMT, ALPHA2_ARG(param->country_ent.alpha2));
16879 	else {
16880 		if (param->channel_plan == RTW_CHPLAN_UNSPECIFIED)
16881 			pos += snprintf(pos, buf_len - (pos - buf), "chplan:NA");
16882 		else
16883 			pos += snprintf(pos, buf_len - (pos - buf), "chplan:0x%02X", param->channel_plan);
16884 
16885 		#if CONFIG_IEEE80211_BAND_6GHZ
16886 		if (param->channel_plan_6g == RTW_CHPLAN_6G_UNSPECIFIED)
16887 			pos += snprintf(pos, buf_len - (pos - buf), " chplan_6g:NA");
16888 		else
16889 			pos += snprintf(pos, buf_len - (pos - buf), " chplan_6g:0x%02X", param->channel_plan_6g);
16890 		#endif
16891 	}
16892 }
16893 
16894 #ifdef CONFIG_80211D
rtw_chplan_rtk_priv_req_prehdl_country_ie(_adapter * adapter,struct SetChannelPlan_param * param,const char * caller)16895 static bool rtw_chplan_rtk_priv_req_prehdl_country_ie(_adapter *adapter, struct SetChannelPlan_param *param, const char *caller)
16896 {
16897 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
16898 	int i;
16899 	bool effected = 1;
16900 
16901 #ifdef CONFIG_RTW_DEBUG
16902 	if (rtw_drv_log_level >= _DRV_DEBUG_) {
16903 		RTW_PRINT("%s cisr before\n", caller);
16904 		dump_country_ie_slave_records(RTW_DBGDUMP, rfctl, 0);
16905 	}
16906 #endif
16907 
16908 	if (param->inr == RTW_REGD_SET_BY_USER
16909 		&& rfctl->effected_cisr_id != CONFIG_IFACE_NUMBER
16910 	) {
16911 		/* country IE setting is applied, user setting is only recorded but not applied */
16912 		effected = 0;
16913 		goto exit;
16914 	}
16915 
16916 	if (param->inr == RTW_REGD_SET_BY_COUNTRY_IE) {
16917 		struct country_ie_slave_record ori_cisr = rfctl->cisr[adapter->iface_id];
16918 		struct country_ie_slave_record ori_ecisr;
16919 		u8 ori_ecisr_id = rfctl->effected_cisr_id;
16920 		u8 new_ecisr_id = CONFIG_IFACE_NUMBER;
16921 		u8 status_score[] = { /* conservative policy */
16922 			[COUNTRY_IE_SLAVE_UNKNOWN] = 3,
16923 			[COUNTRY_IE_SLAVE_OPCH_NOEXIST] = 2,
16924 			[COUNTRY_IE_SLAVE_APPLICABLE] = 1,
16925 		};
16926 		char buf[32];
16927 
16928 		if (_rtw_memcmp(&rfctl->cisr[adapter->iface_id], &param->cisr, sizeof(param->cisr)) == _TRUE) {
16929 			/* record no change  */
16930 			effected = 0;
16931 			goto exit;
16932 		}
16933 
16934 		if (ori_ecisr_id != CONFIG_IFACE_NUMBER)
16935 			_rtw_memcpy(&ori_ecisr, &rfctl->cisr[ori_ecisr_id], sizeof(ori_ecisr));
16936 
16937 		_rtw_memcpy(&rfctl->cisr[adapter->iface_id], &param->cisr, sizeof(param->cisr));
16938 		if ((ori_cisr.status == COUNTRY_IE_SLAVE_NOCOUNTRY
16939 				&& rfctl->cisr[adapter->iface_id].status == COUNTRY_IE_SLAVE_NOCOUNTRY)
16940 			|| (ori_cisr.status == COUNTRY_IE_SLAVE_UNKNOWN
16941 				&& rfctl->cisr[adapter->iface_id].status == COUNTRY_IE_SLAVE_UNKNOWN)
16942 		) {
16943 			/* will take no effect  */
16944 			effected = 0;
16945 			goto exit;
16946 		}
16947 
16948 		for (i = 0; i < CONFIG_IFACE_NUMBER; i++) {
16949 			if (rfctl->cisr[i].status == COUNTRY_IE_SLAVE_NOCOUNTRY)
16950 				continue;
16951 			if (new_ecisr_id == CONFIG_IFACE_NUMBER
16952 				/* high score */
16953 				|| status_score[rfctl->cisr[i].status] > status_score[rfctl->cisr[new_ecisr_id].status]
16954 				/* same score, prefer the same alpha2 as current effected(same score) one */
16955 				|| (status_score[rfctl->cisr[i].status] == status_score[rfctl->cisr[new_ecisr_id].status]
16956 					&& ori_ecisr_id != CONFIG_IFACE_NUMBER
16957 					&& rfctl->cisr[ori_ecisr_id].status == rfctl->cisr[new_ecisr_id].status
16958 					&& _rtw_memcmp(rfctl->cisr[ori_ecisr_id].alpha2, rfctl->cisr[new_ecisr_id].alpha2, 2) == _FALSE
16959 					&& _rtw_memcmp(rfctl->cisr[ori_ecisr_id].alpha2, rfctl->cisr[i].alpha2, 2) == _TRUE)
16960 			)
16961 				new_ecisr_id = i;
16962 		}
16963 
16964 		rfctl->effected_cisr_id = new_ecisr_id;
16965 
16966 		if (rfctl->effected_cisr_id == CONFIG_IFACE_NUMBER) {
16967 			/* no country IE setting */
16968 			const char *alpha2;
16969 
16970 			if (strncmp(rfctl->user_alpha2, "\x00\x00", 2) != 0) {
16971 				/* restore to user setting */
16972 				param->inr = RTW_REGD_SET_BY_USER;
16973 				alpha2 = rfctl->user_alpha2;
16974 				param->channel_plan = rfctl->user_ChannelPlan;
16975 				#if CONFIG_IEEE80211_BAND_6GHZ
16976 				param->channel_plan_6g = rfctl->user_chplan_6g;
16977 				#endif
16978 			} else {
16979 				/* restore to init setting */
16980 				param->inr = RTW_REGD_SET_BY_INIT;
16981 				alpha2 = rfctl->init_alpha2;
16982 				param->channel_plan = rfctl->init_ChannelPlan;
16983 				#if CONFIG_IEEE80211_BAND_6GHZ
16984 				param->channel_plan_6g = rfctl->init_chplan_6g;
16985 				#endif
16986 			}
16987 
16988 			if (IS_ALPHA2_UNSPEC(alpha2) || IS_ALPHA2_WORLDWIDE(alpha2))
16989 				param->has_country = 0;
16990 			else if (rtw_get_chplan_from_country(alpha2, &param->country_ent)) {
16991 				param->channel_plan = param->country_ent.chplan;
16992 				#if CONFIG_IEEE80211_BAND_6GHZ
16993 				param->channel_plan_6g = param->country_ent.chplan_6g;
16994 				#endif
16995 				param->has_country = 1;
16996 			} else {
16997 				RTW_WARN("%s unexpected country_code:\"%c%c\", set to \"00\"\n", caller, alpha2[0], alpha2[1]);
16998 				rtw_warn_on(1);
16999 				rtw_get_chplan_worldwide(&param->country_ent);
17000 				param->channel_plan = param->country_ent.chplan;
17001 				#if CONFIG_IEEE80211_BAND_6GHZ
17002 				param->channel_plan_6g = param->country_ent.chplan_6g;
17003 				#endif
17004 				param->has_country = 1;
17005 			}
17006 			param->has_cisr = 0;
17007 
17008 			get_str_of_set_chplan_keys(buf, 32, param);
17009 			RTW_INFO("%s restore inr:%s %s\n", caller, regd_inr_str(param->inr), buf);
17010 		}
17011 		else {
17012 			/* has country IE setting */
17013 			if (ori_ecisr_id != CONFIG_IFACE_NUMBER) {
17014 				/* has country IE setting originally  */
17015 				if (_rtw_memcmp(&ori_ecisr, &rfctl->cisr[new_ecisr_id], sizeof(ori_ecisr)) == _TRUE) {
17016 					/* same record content, no effect */
17017 					effected = 0;
17018 					goto exit;
17019 				}
17020 			}
17021 			rtw_get_chplan_from_cisrs(rfctl, &param->country_ent, caller);
17022 			param->channel_plan = param->country_ent.chplan;
17023 			#if CONFIG_IEEE80211_BAND_6GHZ
17024 			param->channel_plan_6g = param->country_ent.chplan_6g;
17025 			#endif
17026 			param->has_country = 1;
17027 			param->has_cisr = 0;
17028 
17029 			get_str_of_set_chplan_keys(buf, 32, param);
17030 			RTW_INFO("%s trigger inr:%s %s\n", caller, regd_inr_str(param->inr), buf);
17031 		}
17032 	}
17033 
17034 exit:
17035 #ifdef CONFIG_RTW_DEBUG
17036 	if (rtw_drv_log_level >= _DRV_DEBUG_) {
17037 		RTW_PRINT("%s cisr after\n", caller);
17038 		dump_country_ie_slave_records(RTW_DBGDUMP, rfctl, 0);
17039 	}
17040 #endif
17041 
17042 	return effected;
17043 }
17044 #endif /* CONFIG_80211D */
17045 
rtw_chplan_rtk_priv_req_prehdl_domain_code(_adapter * adapter,struct SetChannelPlan_param * param,const char * caller)17046 static bool rtw_chplan_rtk_priv_req_prehdl_domain_code(_adapter *adapter, struct SetChannelPlan_param *param, const char *caller)
17047 {
17048 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
17049 
17050 	/* disallow invalid input */
17051 	if ((param->channel_plan != RTW_CHPLAN_UNSPECIFIED
17052 		&& !rtw_is_channel_plan_valid(param->channel_plan))
17053 	) {
17054 		RTW_WARN("%s invalid chplan:0x%02X\n", caller, param->channel_plan);
17055 		return _FAIL;
17056 	}
17057 
17058 	#if CONFIG_IEEE80211_BAND_6GHZ
17059 	if (param->channel_plan_6g != RTW_CHPLAN_6G_UNSPECIFIED
17060 		&& !rtw_is_channel_plan_6g_valid(param->channel_plan_6g)
17061 	) {
17062 		RTW_WARN("%s invalid chplan_6g:0x%02X\n", caller, param->channel_plan_6g);
17063 		return _FAIL;
17064 	}
17065 	#endif
17066 
17067 	/* use original value when unspecified */
17068 	if (param->channel_plan == RTW_CHPLAN_UNSPECIFIED)
17069 		param->channel_plan = rfctl->ChannelPlan;
17070 	#if CONFIG_IEEE80211_BAND_6GHZ
17071 	if (param->channel_plan_6g == RTW_CHPLAN_6G_UNSPECIFIED)
17072 		param->channel_plan_6g = rfctl->chplan_6g;
17073 	#endif
17074 
17075 	return _SUCCESS;
17076 }
17077 
rtw_chplan_rtk_priv_req_prehdl_country_ent(struct SetChannelPlan_param * param)17078 static void rtw_chplan_rtk_priv_req_prehdl_country_ent(struct SetChannelPlan_param *param)
17079 {
17080 	if (!param->has_country) {
17081 		u8 chplan_6g = RTW_CHPLAN_6G_NULL;
17082 
17083 		#if CONFIG_IEEE80211_BAND_6GHZ
17084 		chplan_6g = param->channel_plan_6g;
17085 		#endif
17086 
17087 		if (rtw_chplan_ids_is_world_wide(param->channel_plan, chplan_6g))
17088 			rtw_get_chplan_worldwide(&param->country_ent);
17089 		else {
17090 			SET_UNSPEC_ALPHA2(param->country_ent.alpha2);
17091 			param->country_ent.edcca_mode_2g_override = RTW_EDCCA_DEF;
17092 			#if CONFIG_IEEE80211_BAND_5GHZ
17093 			param->country_ent.edcca_mode_5g_override = RTW_EDCCA_DEF;
17094 			#endif
17095 			#if CONFIG_IEEE80211_BAND_6GHZ
17096 			param->country_ent.edcca_mode_6g_override = RTW_EDCCA_DEF;
17097 			#endif
17098 			param->country_ent.txpwr_lmt_override = TXPWR_LMT_DEF;
17099 			#if defined(CONFIG_80211AX_HE) || defined(CONFIG_80211AC_VHT)
17100 			param->country_ent.proto_en = CHPLAN_PROTO_EN_ALL;
17101 			#endif
17102 		}
17103 		param->has_country = 1;
17104 	}
17105 }
17106 
rtw_set_chplan_hdl(_adapter * padapter,unsigned char * pbuf)17107 u8 rtw_set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
17108 {
17109 	struct SetChannelPlan_param *param;
17110 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
17111 	bool effected = 1;
17112 	char buf[32];
17113 	enum rtw_regd_inr ori_inr;
17114 #ifdef CONFIG_IOCTL_CFG80211
17115 	struct get_chplan_resp *chplan;
17116 #endif
17117 
17118 	if (!pbuf)
17119 		return H2C_PARAMETERS_ERROR;
17120 
17121 	param = (struct SetChannelPlan_param *)pbuf;
17122 	ori_inr = param->inr;
17123 
17124 	get_str_of_set_chplan_keys(buf, 32, param);
17125 	RTW_INFO("%s iface_id:%u src:%s inr:%s %s\n", __func__, padapter->iface_id
17126 		, regd_src_str(param->regd_src), regd_inr_str(param->inr), buf);
17127 
17128 	/* check input parameter */
17129 	if (param->regd_src == REGD_SRC_RTK_PRIV) {
17130 		#ifdef CONFIG_80211D
17131 		effected = rtw_chplan_rtk_priv_req_prehdl_country_ie(padapter, param, __func__);
17132 		#endif
17133 
17134 		if (rtw_chplan_rtk_priv_req_prehdl_domain_code(padapter, param, __func__) != _SUCCESS)
17135 			return H2C_PARAMETERS_ERROR;
17136 
17137 		rtw_chplan_rtk_priv_req_prehdl_country_ent(param);
17138 	}
17139 
17140 	rtw_warn_on(!param->has_country);
17141 
17142 	if (param->inr == RTW_REGD_SET_BY_USER) {
17143 		rfctl->user_alpha2[0] = param->country_ent.alpha2[0];
17144 		rfctl->user_alpha2[1] = param->country_ent.alpha2[1];
17145 		rfctl->user_ChannelPlan = param->channel_plan;
17146 		#if CONFIG_IEEE80211_BAND_6GHZ
17147 		rfctl->user_chplan_6g = param->channel_plan_6g;
17148 		#endif
17149 	}
17150 
17151 	if (!effected)
17152 		goto exit;
17153 
17154 	rfctl->regd_src = param->regd_src;
17155 	rfctl->regd_inr = param->inr;
17156 	rfctl->alpha2[0] = param->country_ent.alpha2[0];
17157 	rfctl->alpha2[1] = param->country_ent.alpha2[1];
17158 	rfctl->edcca_mode_2g_override = param->country_ent.edcca_mode_2g_override;
17159 #if CONFIG_IEEE80211_BAND_5GHZ
17160 	rfctl->edcca_mode_5g_override = param->country_ent.edcca_mode_5g_override;
17161 #endif
17162 #if CONFIG_IEEE80211_BAND_6GHZ
17163 	rfctl->edcca_mode_6g_override = param->country_ent.edcca_mode_6g_override;
17164 #endif
17165 #if CONFIG_TXPWR_LIMIT
17166 	rfctl->txpwr_lmt_override = param->country_ent.txpwr_lmt_override;
17167 #endif
17168 #if defined(CONFIG_80211AX_HE) || defined(CONFIG_80211AC_VHT)
17169 	rfctl->proto_en = param->country_ent.proto_en;
17170 #endif
17171 
17172 	rfctl->ChannelPlan = param->channel_plan;
17173 #if CONFIG_IEEE80211_BAND_6GHZ
17174 	rfctl->chplan_6g = param->channel_plan_6g;
17175 #endif
17176 
17177 #if CONFIG_TXPWR_LIMIT
17178 	rtw_txpwr_init_regd(rfctl);
17179 #endif
17180 
17181 	rtw_edcca_mode_update(rfctl_to_dvobj(rfctl));
17182 	rtw_odm_adaptivity_update(rfctl_to_dvobj(rfctl));
17183 
17184 	rtw_rfctl_chplan_init(padapter);
17185 
17186 #ifdef CONFIG_IOCTL_CFG80211
17187 	if (rfctl->regd_src != REGD_SRC_OS)
17188 		rtw_chset_hook_os_channels(rfctl);
17189 
17190 	if (rtw_get_chplan_cmd(padapter, RTW_CMDF_DIRECTLY, &chplan) == _SUCCESS) {
17191 		if (!param->rtnl_lock_needed)
17192 			rtw_regd_change_complete_sync(adapter_to_wiphy(padapter), chplan, 0);
17193 		else
17194 			rtw_warn_on(rtw_regd_change_complete_async(adapter_to_wiphy(padapter), chplan) != _SUCCESS);
17195 	} else
17196 		rtw_warn_on(1);
17197 #endif
17198 
17199 	rtw_nlrtw_reg_change_event(padapter);
17200 
17201 	#ifdef CONFIG_LPS
17202 	LPS_Leave(padapter, "SET_CHPLAN");
17203 	#endif
17204 
17205 	if (GET_HAL_DATA(padapter)->txpwr_limit_loaded
17206 		&& rtw_get_hw_init_completed(padapter))
17207 		rtw_hal_update_txpwr_level(padapter);
17208 
17209 exit:
17210 	return	H2C_SUCCESS;
17211 }
17212 
rtw_get_chplan_hdl(_adapter * padapter,unsigned char * pbuf)17213 u8 rtw_get_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
17214 {
17215 	struct get_channel_plan_param *param;
17216 	struct get_chplan_resp *chplan;
17217 	struct rf_ctl_t *rfctl;
17218 	int i;
17219 
17220 	if (!pbuf)
17221 		return H2C_PARAMETERS_ERROR;
17222 
17223 	rfctl = adapter_to_rfctl(padapter);
17224 	param = (struct get_channel_plan_param *)pbuf;
17225 
17226 	chplan = rtw_vmalloc(sizeof(struct get_chplan_resp) + sizeof(RT_CHANNEL_INFO) * rfctl->max_chan_nums);
17227 	if (!chplan)
17228 		return H2C_CMD_FAIL;
17229 
17230 	chplan->regd_src = rfctl->regd_src;
17231 	chplan->regd_inr = rfctl->regd_inr;
17232 
17233 	chplan->alpha2[0] = rfctl->alpha2[0];
17234 	chplan->alpha2[1] = rfctl->alpha2[1];
17235 
17236 	chplan->channel_plan = rfctl->ChannelPlan;
17237 #if CONFIG_IEEE80211_BAND_6GHZ
17238 	chplan->chplan_6g = rfctl->chplan_6g;
17239 #endif
17240 #if CONFIG_TXPWR_LIMIT
17241 	for (i = 0; i < BAND_MAX; i++)
17242 		chplan->txpwr_lmt_name[i] = rfctl->txpwr_lmt_name[i];
17243 #endif
17244 	chplan->edcca_mode_2g = rfctl->edcca_mode_2g;
17245 #if CONFIG_IEEE80211_BAND_5GHZ
17246 	chplan->edcca_mode_5g = rfctl->edcca_mode_5g;
17247 #endif
17248 #if CONFIG_IEEE80211_BAND_6GHZ
17249 	chplan->edcca_mode_6g = rfctl->edcca_mode_6g;
17250 #endif
17251 #ifdef CONFIG_DFS_MASTER
17252 	chplan->dfs_domain = rtw_rfctl_get_dfs_domain(rfctl);
17253 #endif
17254 
17255 	chplan->proto_en = 0
17256 		#if defined(CONFIG_80211AX_HE) || defined(CONFIG_80211AC_VHT)
17257 		| rfctl->proto_en
17258 		#endif
17259 		;
17260 
17261 	chplan->chset_num = rfctl->max_chan_nums;
17262 	_rtw_memcpy(chplan->chset, rfctl->channel_set, sizeof(RT_CHANNEL_INFO) * rfctl->max_chan_nums);
17263 	*param->chplan = chplan;
17264 
17265 	return	H2C_SUCCESS;
17266 }
17267 
led_blink_hdl(_adapter * padapter,unsigned char * pbuf)17268 u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
17269 {
17270 	struct LedBlink_param *ledBlink_param;
17271 
17272 	if (!pbuf)
17273 		return H2C_PARAMETERS_ERROR;
17274 
17275 	ledBlink_param = (struct LedBlink_param *)pbuf;
17276 
17277 #ifdef CONFIG_RTW_LED_HANDLED_BY_CMD_THREAD
17278 	BlinkHandler((PLED_DATA)ledBlink_param->pLed);
17279 #endif
17280 
17281 	return	H2C_SUCCESS;
17282 }
17283 
csa_timer_hdl(void * FunctionContext)17284 void csa_timer_hdl(void *FunctionContext)
17285 {
17286 	_adapter *padapter = (_adapter *)FunctionContext;
17287 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
17288 	struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj);
17289 	u8 i;
17290 
17291 	for (i = 0; i < dvobj->iface_nums; i++) {
17292 		_adapter *iface;
17293 		iface = dvobj->padapters[i];
17294 		if (!iface)
17295 			continue;
17296 		if (check_fwstate(&(iface->mlmepriv), WIFI_CSA_UPDATE_BEACON)) {
17297 			clr_fwstate(&(iface->mlmepriv), WIFI_CSA_UPDATE_BEACON);
17298 			RTW_INFO(FUNC_ADPT_FMT" wait beacons more than 70 seconds\n", FUNC_ADPT_ARG(iface));
17299 			return;
17300 		}
17301 	}
17302 
17303 	if (rfctl->csa_ch == 0) {
17304 		RTW_INFO("channel switch done\n");
17305 		return ;
17306 	}
17307 
17308 	/* channel switch */
17309 	if (rtw_set_csa_cmd(padapter) != _SUCCESS) {
17310 		rfctl->csa_ch = 0;
17311 		rfctl->csa_switch_cnt = 0;
17312 		rfctl->csa_ch_offset = 0;
17313 		rfctl->csa_ch_width = 0;
17314 		rfctl->csa_ch_freq_seg0 = 0;
17315 		rfctl->csa_ch_freq_seg1 = 0;
17316 	}
17317 }
17318 
set_csa_hdl(_adapter * adapter,unsigned char * pbuf)17319 u8 set_csa_hdl(_adapter *adapter, unsigned char *pbuf)
17320 {
17321 #if CONFIG_DFS
17322 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
17323 
17324 	if (rfctl->csa_ch)
17325 		rtw_dfs_ch_switch_hdl(adapter_to_dvobj(adapter));
17326 #endif
17327 	return	H2C_SUCCESS;
17328 }
17329 
set_ap_csa_hdl(_adapter * adapter,unsigned char * pbuf)17330 u8 set_ap_csa_hdl(_adapter *adapter, unsigned char *pbuf)
17331 {
17332 #ifdef CONFIG_AP_MODE
17333 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
17334 	u8 ifbmp_m = rtw_mi_get_ap_mesh_ifbmp(adapter);
17335 	u8 enable = 1;
17336 	int i;
17337 	_adapter *iface;
17338 
17339 	for (i = 0; i < dvobj->iface_nums; i++) {
17340 		iface = dvobj->padapters[i];
17341 		if (!iface || !(ifbmp_m & BIT(iface->iface_id)))
17342 			continue;
17343 		RTW_INFO("%s, HW_VAR_BCN_EARLY_C2H_RPT enable=%d\n", __FUNCTION__, enable);
17344 		rtw_hal_set_hwreg(iface, HW_VAR_BCN_EARLY_C2H_RPT, &enable);
17345 	}
17346 #endif
17347 	return H2C_SUCCESS;
17348 }
17349 
tdls_hdl(_adapter * padapter,unsigned char * pbuf)17350 u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
17351 {
17352 #ifdef CONFIG_TDLS
17353 	_irqL irqL;
17354 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
17355 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
17356 #ifdef CONFIG_TDLS_CH_SW
17357 	struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info;
17358 #endif
17359 	struct TDLSoption_param *TDLSoption;
17360 	struct sta_info *ptdls_sta = NULL;
17361 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
17362 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
17363 	struct sta_info *ap_sta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(&(pmlmeinfo->network)));
17364 	u8 survey_channel, i, min, option;
17365 	struct tdls_txmgmt txmgmt;
17366 	u32 setchtime, resp_sleep = 0, wait_time;
17367 	u8 zaddr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
17368 	u8 ret;
17369 	u8 doiqk;
17370 	u64 tx_ra_bitmap = 0;
17371 
17372 	if (!pbuf)
17373 		return H2C_PARAMETERS_ERROR;
17374 
17375 	TDLSoption = (struct TDLSoption_param *)pbuf;
17376 	option = TDLSoption->option;
17377 
17378 	if (!_rtw_memcmp(TDLSoption->addr, zaddr, ETH_ALEN)) {
17379 		ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), TDLSoption->addr);
17380 		if (ptdls_sta == NULL)
17381 			return H2C_REJECTED;
17382 	} else {
17383 		if (!(option == TDLS_RS_RCR))
17384 			return H2C_REJECTED;
17385 	}
17386 
17387 	/* _enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); */
17388 	/* RTW_INFO("[%s] option:%d\n", __FUNCTION__, option); */
17389 
17390 	switch (option) {
17391 	case TDLS_ESTABLISHED: {
17392 		/* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */
17393 		/* So we can receive all kinds of data frames. */
17394 		u8 sta_band = 0;
17395 
17396 		/* leave ALL PS when TDLS is established */
17397 		rtw_pwr_wakeup(padapter);
17398 
17399 		rtw_hal_rcr_set_chk_bssid(padapter, MLME_TDLS_LINKED);
17400 		RTW_INFO("Created Direct Link with "MAC_FMT"\n", MAC_ARG(ptdls_sta->cmn.mac_addr));
17401 
17402 		/* Set TDLS sta rate. */
17403 		/* Update station supportRate */
17404 		rtw_hal_update_sta_ra_info(padapter, ptdls_sta);
17405 		tx_ra_bitmap = ptdls_sta->cmn.ra_info.ramask;
17406 
17407 		if (pmlmeext->cur_channel > 14) {
17408 			if (tx_ra_bitmap & 0xffff000)
17409 				sta_band |= WIRELESS_11_5N ;
17410 
17411 			if (tx_ra_bitmap & 0xff0)
17412 				sta_band |= WIRELESS_11A;
17413 
17414 			/* 5G band */
17415 #ifdef CONFIG_80211AC_VHT
17416 			if (ptdls_sta->vhtpriv.vht_option)
17417 				sta_band = WIRELESS_11_5AC;
17418 #endif
17419 
17420 		} else {
17421 			if (tx_ra_bitmap & 0xffff000)
17422 				sta_band |= WIRELESS_11_24N;
17423 
17424 			if (tx_ra_bitmap & 0xff0)
17425 				sta_band |= WIRELESS_11G;
17426 
17427 			if (tx_ra_bitmap & 0x0f)
17428 				sta_band |= WIRELESS_11B;
17429 		}
17430 		ptdls_sta->wireless_mode = sta_band;
17431 		rtw_hal_update_sta_wset(padapter, ptdls_sta);
17432 		/* Sta mode */
17433 		rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, ptdls_sta, _TRUE);
17434 
17435 		set_sta_rate(padapter, ptdls_sta);
17436 		rtw_sta_media_status_rpt(padapter, ptdls_sta, 1);
17437 		break;
17438 	}
17439 	case TDLS_ISSUE_PTI:
17440 		ptdls_sta->tdls_sta_state |= TDLS_WAIT_PTR_STATE;
17441 		issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
17442 		_set_timer(&ptdls_sta->pti_timer, TDLS_PTI_TIME);
17443 		break;
17444 #ifdef CONFIG_TDLS_CH_SW
17445 	case TDLS_CH_SW_RESP:
17446 		_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
17447 		txmgmt.status_code = 0;
17448 		_rtw_memcpy(txmgmt.peer, ptdls_sta->cmn.mac_addr, ETH_ALEN);
17449 
17450 		if (ap_sta)
17451 			rtw_hal_macid_sleep(padapter, ap_sta->cmn.mac_id);
17452 		issue_nulldata(padapter, NULL, 1, 3, 3);
17453 
17454 		RTW_INFO("[TDLS ] issue tdls channel switch response\n");
17455 		ret = issue_tdls_ch_switch_rsp(padapter, &txmgmt, _TRUE);
17456 
17457 		/* If we receive TDLS_CH_SW_REQ at off channel which it's target is AP's channel */
17458 		/* then we just switch to AP's channel*/
17459 		if (padapter->mlmeextpriv.cur_channel == pchsw_info->off_ch_num) {
17460 			rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_END_TO_BASE_CHNL);
17461 			break;
17462 		}
17463 
17464 		if (ret == _SUCCESS)
17465 			rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_TO_OFF_CHNL);
17466 		else
17467 			RTW_INFO("[TDLS] issue_tdls_ch_switch_rsp wait ack fail !!!!!!!!!!\n");
17468 
17469 		break;
17470 	case TDLS_CH_SW_PREPARE:
17471 		pchsw_info->ch_sw_state |= TDLS_CH_SWITCH_PREPARE_STATE;
17472 
17473 		/* to collect IQK info of off-chnl */
17474 		doiqk = _TRUE;
17475 		rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
17476 		set_channel_bwmode(padapter, pchsw_info->off_ch_num, pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20);
17477 		doiqk = _FALSE;
17478 		rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
17479 
17480 		/* switch back to base-chnl */
17481 		doiqk = _TRUE;
17482 		rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
17483 		set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
17484 		doiqk = _FALSE;
17485 		rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
17486 
17487 		rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START);
17488 
17489 		pchsw_info->ch_sw_state &= ~(TDLS_CH_SWITCH_PREPARE_STATE);
17490 
17491 		break;
17492 	case TDLS_CH_SW_START:
17493 		rtw_tdls_set_ch_sw_oper_control(padapter, _TRUE);
17494 		break;
17495 	case TDLS_CH_SW_TO_OFF_CHNL:
17496 		if (ap_sta)
17497 			rtw_hal_macid_sleep(padapter, ap_sta->cmn.mac_id);
17498 		issue_nulldata(padapter, NULL, 1, 3, 3);
17499 
17500 		if (padapter->registrypriv.wifi_spec == 0) {
17501 		if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
17502 			_set_timer(&ptdls_sta->ch_sw_timer, (u32)(ptdls_sta->ch_switch_timeout) / 1000);
17503 		}
17504 
17505 		if (rtw_tdls_do_ch_sw(padapter, ptdls_sta, TDLS_CH_SW_OFF_CHNL, pchsw_info->off_ch_num,
17506 			pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20, ptdls_sta->ch_switch_time) == _SUCCESS) {
17507 			pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE);
17508 			if (pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) {
17509 				if (issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->cmn.mac_addr, 0, 1,
17510 					(padapter->registrypriv.wifi_spec == 0) ? 3 : 0) == _FAIL)
17511 					rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_TO_BASE_CHNL);
17512 			}
17513 		} else {
17514 			if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
17515 				_cancel_timer_ex(&ptdls_sta->ch_sw_timer);
17516 		}
17517 
17518 
17519 		break;
17520 	case TDLS_CH_SW_END:
17521 	case TDLS_CH_SW_END_TO_BASE_CHNL:
17522 		rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
17523 		_cancel_timer_ex(&ptdls_sta->ch_sw_timer);
17524 		_cancel_timer_ex(&ptdls_sta->stay_on_base_chnl_timer);
17525 		_cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
17526 #if 0
17527 		_rtw_memset(pHalData->tdls_ch_sw_iqk_info_base_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_base_chnl));
17528 		_rtw_memset(pHalData->tdls_ch_sw_iqk_info_off_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_off_chnl));
17529 #endif
17530 
17531 		if (option == TDLS_CH_SW_END_TO_BASE_CHNL)
17532 			rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_TO_BASE_CHNL);
17533 
17534 		break;
17535 	case TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED:
17536 	case TDLS_CH_SW_TO_BASE_CHNL:
17537 		pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE | TDLS_WAIT_CH_RSP_STATE);
17538 
17539 		if (option == TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED) {
17540 			if (ptdls_sta != NULL) {
17541 				/* Send unsolicited channel switch rsp. to peer */
17542 				_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
17543 				txmgmt.status_code = 0;
17544 				_rtw_memcpy(txmgmt.peer, ptdls_sta->cmn.mac_addr, ETH_ALEN);
17545 				issue_tdls_ch_switch_rsp(padapter, &txmgmt, _FALSE);
17546 			}
17547 		}
17548 
17549 		if (rtw_tdls_do_ch_sw(padapter, ptdls_sta, TDLS_CH_SW_BASE_CHNL, pmlmeext->cur_channel,
17550 			pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode, ptdls_sta->ch_switch_time) == _SUCCESS) {
17551 			if (ap_sta)
17552 				rtw_hal_macid_wakeup(padapter, ap_sta->cmn.mac_id);
17553 			issue_nulldata(padapter, NULL, 0, 3, 3);
17554 			/* set ch sw monitor timer for responder */
17555 			if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
17556 				_set_timer(&ptdls_sta->ch_sw_monitor_timer, TDLS_CH_SW_MONITOR_TIMEOUT);
17557 		}
17558 
17559 		break;
17560 #endif
17561 	case TDLS_RS_RCR:
17562 		rtw_hal_rcr_set_chk_bssid(padapter, MLME_TDLS_NOLINK);
17563 		break;
17564 	case TDLS_TEARDOWN_STA:
17565 	case TDLS_TEARDOWN_STA_NO_WAIT:
17566 		_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
17567 		txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
17568 		_rtw_memcpy(txmgmt.peer, ptdls_sta->cmn.mac_addr, ETH_ALEN);
17569 
17570 		issue_tdls_teardown(padapter, &txmgmt, (option == TDLS_TEARDOWN_STA) ? _TRUE : _FALSE);
17571 
17572 		break;
17573 	case TDLS_TEARDOWN_STA_LOCALLY:
17574 	case TDLS_TEARDOWN_STA_LOCALLY_POST:
17575 #ifdef CONFIG_TDLS_CH_SW
17576 		if (_rtw_memcmp(TDLSoption->addr, pchsw_info->addr, ETH_ALEN) == _TRUE) {
17577 			pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
17578 						     TDLS_CH_SWITCH_ON_STATE |
17579 						     TDLS_PEER_AT_OFF_STATE);
17580 			rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
17581 			_rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
17582 		}
17583 #endif
17584 
17585 		if (option == TDLS_TEARDOWN_STA_LOCALLY)
17586 			rtw_tdls_teardown_pre_hdl(padapter, ptdls_sta);
17587 
17588 		rtw_tdls_teardown_post_hdl(padapter, ptdls_sta, _FALSE);
17589 
17590 		if (ptdlsinfo->tdls_sctx != NULL)
17591 			rtw_sctx_done(&(ptdlsinfo->tdls_sctx));
17592 
17593 		break;
17594 	}
17595 
17596 	/* _exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); */
17597 
17598 	return H2C_SUCCESS;
17599 #else
17600 	return H2C_REJECTED;
17601 #endif /* CONFIG_TDLS */
17602 
17603 }
17604 
run_in_thread_hdl(_adapter * padapter,u8 * pbuf)17605 u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf)
17606 {
17607 	struct RunInThread_param *p;
17608 
17609 
17610 	if (NULL == pbuf)
17611 		return H2C_PARAMETERS_ERROR;
17612 	p = (struct RunInThread_param *)pbuf;
17613 
17614 	if (p->func)
17615 		p->func(p->context);
17616 
17617 	return H2C_SUCCESS;
17618 }
17619 
rtw_sae_preprocess(_adapter * adapter,const u8 * buf,u32 len,u8 tx)17620 int rtw_sae_preprocess(_adapter *adapter, const u8 *buf, u32 len, u8 tx)
17621 {
17622 #ifdef CONFIG_IOCTL_CFG80211
17623 	const u8 *frame_body = buf + sizeof(struct rtw_ieee80211_hdr_3addr);
17624 	u16 alg;
17625 	u16 seq;
17626 	u16 status;
17627 	int ret = _FAIL;
17628 
17629 	alg = RTW_GET_LE16(frame_body);
17630 	if (alg != WLAN_AUTH_SAE)
17631 		goto exit;
17632 
17633 	seq = RTW_GET_LE16(frame_body + 2);
17634 	status = RTW_GET_LE16(frame_body + 4);
17635 
17636 	RTW_INFO("RTW_%s:AUTH alg:0x%04x, seq:0x%04x, status:0x%04x, mesg:%s\n",
17637 		(tx == _TRUE) ? "Tx" : "Rx", alg, seq, status,
17638 		(seq == 1) ? "Commit" : "Confirm");
17639 
17640 	ret = _SUCCESS;
17641 
17642 #ifdef CONFIG_RTW_MESH
17643 	if (MLME_IS_MESH(adapter)) {
17644 		rtw_mesh_sae_check_frames(adapter, buf, len, tx, alg, seq, status);
17645 		goto exit;
17646 	}
17647 #endif
17648 
17649 	if (tx && (seq == 2) && (status == 0)) {
17650 		/* quere commit frame until external auth statue update */
17651 		struct sta_priv *pstapriv = &adapter->stapriv;
17652 		struct sta_info	*psta = NULL;
17653 		_irqL irqL;
17654 
17655 		psta = rtw_get_stainfo(pstapriv, GetAddr1Ptr(buf));
17656 		if (psta) {
17657 			_enter_critical_bh(&psta->lock, &irqL);
17658 			if (psta->pauth_frame) {
17659 				rtw_mfree(psta->pauth_frame, psta->auth_len);
17660 				psta->pauth_frame = NULL;
17661 				psta->auth_len = 0;
17662 			}
17663 
17664 			psta->pauth_frame =  rtw_zmalloc(len);
17665 			if (psta->pauth_frame) {
17666 				_rtw_memcpy(psta->pauth_frame, buf, len);
17667 				psta->auth_len = len;
17668 			}
17669 			_exit_critical_bh(&psta->lock, &irqL);
17670 
17671 			ret = 2;
17672 		}
17673 	}
17674 exit:
17675 	return ret;
17676 #else
17677 	return _SUCCESS;
17678 #endif /* CONFIG_IOCTL_CFG80211 */
17679 }
17680 
17681 /* Needs to confirm with FW the value of REG_RX_BEACON_LENGTH */
rtw_write_bcnlen_hdl(_adapter * padapter,u8 * pbuf)17682 u8 rtw_write_bcnlen_hdl(_adapter *padapter, u8 *pbuf)
17683 {
17684 #ifdef CONFIG_WRITE_BCN_LEN_TO_FW
17685 	struct write_bcnlen_param *parm = (struct write_bcnlen_param *)pbuf;
17686 	u16 bcn_len = parm->bcn_len;
17687 
17688 	rtw_write16(padapter, REG_RX_BEACON_LENGTH + 2, bcn_len);
17689 #endif
17690 	return H2C_SUCCESS;
17691 }
17692 
rtw_reqtxrpt_cmd_hdl(_adapter * adapter,u8 * pbuf)17693 u8 rtw_reqtxrpt_cmd_hdl(_adapter *adapter, u8 *pbuf)
17694 {
17695 	struct reqtxrpt_param *parm = (struct reqtxrpt_param *)pbuf;
17696 
17697 	rtw_hal_reqtxrpt(adapter, parm->macid);
17698 
17699 	return H2C_SUCCESS;
17700 }
17701 
17702