1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2012 Realtek Corporation. */
3 
4 #define _RTW_MLME_EXT_C_
5 
6 #include "../include/osdep_service.h"
7 #include "../include/drv_types.h"
8 #include "../include/wifi.h"
9 #include "../include/rtw_mlme_ext.h"
10 #include "../include/wlan_bssdef.h"
11 #include "../include/mlme_osdep.h"
12 #include "../include/recv_osdep.h"
13 
14 static struct mlme_handler mlme_sta_tbl[] = {
15 	{WIFI_ASSOCREQ,		"OnAssocReq",	&OnAssocReq},
16 	{WIFI_ASSOCRSP,		"OnAssocRsp",	&OnAssocRsp},
17 	{WIFI_REASSOCREQ,	"OnReAssocReq",	&OnAssocReq},
18 	{WIFI_REASSOCRSP,	"OnReAssocRsp",	&OnAssocRsp},
19 	{WIFI_PROBEREQ,		"OnProbeReq",	&OnProbeReq},
20 	{WIFI_PROBERSP,		"OnProbeRsp",		&OnProbeRsp},
21 
22 	/*----------------------------------------------------------
23 					below 2 are reserved
24 	-----------------------------------------------------------*/
25 	{0,					"DoReserved",		&DoReserved},
26 	{0,					"DoReserved",		&DoReserved},
27 	{WIFI_BEACON,		"OnBeacon",		&OnBeacon},
28 	{WIFI_ATIM,			"OnATIM",		&OnAtim},
29 	{WIFI_DISASSOC,		"OnDisassoc",		&OnDisassoc},
30 	{WIFI_AUTH,			"OnAuth",		&OnAuthClient},
31 	{WIFI_DEAUTH,		"OnDeAuth",		&OnDeAuth},
32 	{WIFI_ACTION,		"OnAction",		&OnAction},
33 };
34 
35 static struct action_handler OnAction_tbl[] = {
36 	{RTW_WLAN_CATEGORY_SPECTRUM_MGMT,	 "ACTION_SPECTRUM_MGMT", on_action_spct},
37 	{RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos},
38 	{RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls},
39 	{RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
40 	{RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
41 	{RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved},
42 	{RTW_WLAN_CATEGORY_FT, "ACTION_FT",	&DoReserved},
43 	{RTW_WLAN_CATEGORY_HT,	"ACTION_HT",	&OnAction_ht},
44 	{RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved},
45 	{RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
46 	{RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},
47 };
48 
49 static u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
50 
51 /**************************************************
52 OUI definitions for the vendor specific IE
53 ***************************************************/
54 unsigned char	RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
55 unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
56 unsigned char	WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
57 unsigned char	P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09};
58 unsigned char	WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A};
59 
60 unsigned char	WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
61 unsigned char	WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
62 
63 unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
64 unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
65 
66 extern unsigned char REALTEK_96B_IE[];
67 
68 /********************************************************
69 MCS rate definitions
70 *********************************************************/
71 unsigned char	MCS_rate_2R[16] = {0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
72 unsigned char	MCS_rate_1R[16] = {0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
73 
74 /********************************************************
75 ChannelPlan definitions
76 *********************************************************/
77 static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
78 	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},		/*  0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
79 	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},		/*  0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
80 	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},			/*  0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
81 	{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},	/*  0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
82 	{{10, 11, 12, 13}, 4},					/*  0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
83 	{{}, 0},									/*  0x05, RT_CHANNEL_DOMAIN_2G_NULL */
84 };
85 
86 static struct rt_channel_plan_map	RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
87 	/*  0x00 ~ 0x1F , Old Define ===== */
88 	{0x02},	/* 0x00, RT_CHANNEL_DOMAIN_FCC */
89 	{0x02},	/* 0x01, RT_CHANNEL_DOMAIN_IC */
90 	{0x01},	/* 0x02, RT_CHANNEL_DOMAIN_ETSI */
91 	{0x01},	/* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
92 	{0x01},	/* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
93 	{0x03},	/* 0x05, RT_CHANNEL_DOMAIN_MKK */
94 	{0x03},	/* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
95 	{0x01},	/* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
96 	{0x03},	/* 0x08, RT_CHANNEL_DOMAIN_TELEC */
97 	{0x03},	/* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
98 	{0x00},	/* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
99 	{0x02},	/* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
100 	{0x01},	/* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
101 	{0x02},	/* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
102 	{0x02},	/* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
103 	{0x02},	/* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
104 	{0x01},	/* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
105 	{0x02},	/* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
106 	{0x01},	/* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
107 	{0x02},	/* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
108 	{0x00},	/* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
109 	{0x00},	/* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
110 	{0x03},	/* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
111 	{0x05},	/* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
112 	{0x02},	/* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
113 	{0x00},	/* 0x1A, */
114 	{0x00},	/* 0x1B, */
115 	{0x00},	/* 0x1C, */
116 	{0x00},	/* 0x1D, */
117 	{0x00},	/* 0x1E, */
118 	/*  0x20 ~ 0x7F , New Define ===== */
119 	{0x00},	/* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
120 	{0x01},	/* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
121 	{0x02},	/* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
122 	{0x03},	/* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
123 	{0x04},	/* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
124 	{0x02},	/* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
125 	{0x00},	/* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
126 	{0x03},	/* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
127 	{0x00},	/* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
128 	{0x00},	/* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
129 	{0x00},	/* 0x2A, */
130 	{0x00},	/* 0x2B, */
131 	{0x00},	/* 0x2C, */
132 	{0x00},	/* 0x2D, */
133 	{0x00},	/* 0x2E, */
134 	{0x00},	/* 0x2F, */
135 	{0x00},	/* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
136 	{0x00},	/* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
137 	{0x00},	/* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
138 	{0x00},	/* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
139 	{0x02},	/* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
140 	{0x00},	/* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
141 	{0x00},	/* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
142 	{0x03},	/* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
143 	{0x03},	/* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
144 	{0x02},	/* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
145 	{0x00},	/* 0x3A, */
146 	{0x00},	/* 0x3B, */
147 	{0x00},	/* 0x3C, */
148 	{0x00},	/* 0x3D, */
149 	{0x00},	/* 0x3E, */
150 	{0x00},	/* 0x3F, */
151 	{0x02},	/* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
152 	{0x03},	/* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
153 };
154 
155 static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03}; /* use the conbination for max channel numbers */
156 
157 /*
158  * Search the @param channel_num in given @param channel_set
159  * @ch_set: the given channel set
160  * @ch: the given channel number
161  *
162  * return the index of channel_num in channel_set, -1 if not found
163  */
rtw_ch_set_search_ch(struct rt_channel_info * ch_set,const u32 ch)164 int rtw_ch_set_search_ch(struct rt_channel_info *ch_set, const u32 ch)
165 {
166 	int i;
167 	for (i = 0; ch_set[i].ChannelNum != 0; i++) {
168 		if (ch == ch_set[i].ChannelNum)
169 			break;
170 	}
171 
172 	if (i >= ch_set[i].ChannelNum)
173 		return -1;
174 	return i;
175 }
176 
177 /****************************************************************************
178 
179 Following are the initialization functions for WiFi MLME
180 
181 *****************************************************************************/
182 
init_hw_mlme_ext(struct adapter * padapter)183 int init_hw_mlme_ext(struct adapter *padapter)
184 {
185 	struct	mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
186 
187 	set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
188 	return _SUCCESS;
189 }
190 
init_mlme_ext_priv_value(struct adapter * padapter)191 static void init_mlme_ext_priv_value(struct adapter *padapter)
192 {
193 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
194 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
195 	unsigned char	mixed_datarate[NumRates] = {
196 		_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
197 		_9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_,
198 		 _48M_RATE_, _54M_RATE_, 0xff
199 	};
200 	unsigned char	mixed_basicrate[NumRates] = {
201 		_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
202 		_12M_RATE_, _24M_RATE_, 0xff,
203 	};
204 
205 	atomic_set(&pmlmeext->event_seq, 0);
206 	pmlmeext->mgnt_seq = 0;/* reset to zero when disconnect at client mode */
207 
208 	pmlmeext->cur_channel = padapter->registrypriv.channel;
209 	pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
210 	pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
211 	pmlmeext->retry = 0;
212 
213 	pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
214 
215 	memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
216 	memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
217 
218 	pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
219 
220 	pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
221 	pmlmeext->sitesurvey_res.channel_idx = 0;
222 	pmlmeext->sitesurvey_res.bss_cnt = 0;
223 	pmlmeext->scan_abort = false;
224 
225 	pmlmeinfo->state = WIFI_FW_NULL_STATE;
226 	pmlmeinfo->reauth_count = 0;
227 	pmlmeinfo->reassoc_count = 0;
228 	pmlmeinfo->link_count = 0;
229 	pmlmeinfo->auth_seq = 0;
230 	pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
231 	pmlmeinfo->key_index = 0;
232 	pmlmeinfo->iv = 0;
233 
234 	pmlmeinfo->enc_algo = _NO_PRIVACY_;
235 	pmlmeinfo->authModeToggle = 0;
236 
237 	memset(pmlmeinfo->chg_txt, 0, 128);
238 
239 	pmlmeinfo->slotTime = SHORT_SLOT_TIME;
240 	pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
241 
242 	pmlmeinfo->dialogToken = 0;
243 
244 	pmlmeext->action_public_rxseq = 0xffff;
245 	pmlmeext->action_public_dialog_token = 0xff;
246 }
247 
has_channel(struct rt_channel_info * channel_set,u8 chanset_size,u8 chan)248 static int has_channel(struct rt_channel_info *channel_set,
249 					   u8 chanset_size,
250 					   u8 chan) {
251 	int i;
252 
253 	for (i = 0; i < chanset_size; i++) {
254 		if (channel_set[i].ChannelNum == chan)
255 			return 1;
256 	}
257 	return 0;
258 }
259 
init_channel_list(struct adapter * padapter,struct rt_channel_info * channel_set,u8 chanset_size,struct p2p_channels * channel_list)260 static void init_channel_list(struct adapter *padapter, struct rt_channel_info *channel_set,
261 							  u8 chanset_size,
262 							  struct p2p_channels *channel_list) {
263 	struct p2p_oper_class_map op_class[] = {
264 		{ IEEE80211G,  81,   1,  13,  1, BW20 },
265 		{ IEEE80211G,  82,  14,  14,  1, BW20 },
266 		{ -1, 0, 0, 0, 0, BW20 }
267 	};
268 
269 	int cla, op;
270 
271 	cla = 0;
272 
273 	for (op = 0; op_class[op].op_class; op++) {
274 		u8 ch;
275 		struct p2p_oper_class_map *o = &op_class[op];
276 		struct p2p_reg_class *reg = NULL;
277 
278 		for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
279 			if (!has_channel(channel_set, chanset_size, ch)) {
280 				continue;
281 			}
282 
283 			if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
284 				continue;
285 
286 			if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) &&
287 			    ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
288 				continue;
289 
290 			if (!reg) {
291 				reg = &channel_list->reg_class[cla];
292 				cla++;
293 				reg->reg_class = o->op_class;
294 				reg->channels = 0;
295 			}
296 			reg->channel[reg->channels] = ch;
297 			reg->channels++;
298 		}
299 	}
300 	channel_list->reg_classes = cla;
301 }
302 
init_channel_set(struct adapter * padapter,u8 ChannelPlan,struct rt_channel_info * channel_set)303 static u8 init_channel_set(struct adapter *padapter, u8 ChannelPlan, struct rt_channel_info *channel_set)
304 {
305 	u8 index, chanset_size = 0;
306 	u8 b2_4GBand = false;
307 	u8 Index2G = 0;
308 
309 	memset(channel_set, 0, sizeof(struct rt_channel_info) * MAX_CHANNEL_NUM);
310 
311 	if (ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) {
312 		DBG_88E("ChannelPlan ID %x error !!!!!\n", ChannelPlan);
313 		return chanset_size;
314 	}
315 
316 	if (padapter->registrypriv.wireless_mode & WIRELESS_11G) {
317 		b2_4GBand = true;
318 		if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
319 			Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
320 		else
321 			Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
322 	}
323 
324 	if (b2_4GBand) {
325 		for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) {
326 			channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
327 
328 			if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||/* Channel 1~11 is active, and 12~14 is passive */
329 			    (RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G == ChannelPlan)) {
330 				if (channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
331 					channel_set[chanset_size].ScanType = SCAN_ACTIVE;
332 				else if ((channel_set[chanset_size].ChannelNum  >= 12 && channel_set[chanset_size].ChannelNum  <= 14))
333 					channel_set[chanset_size].ScanType  = SCAN_PASSIVE;
334 			} else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan ||
335 				   RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) {/*  channel 12~13, passive scan */
336 				if (channel_set[chanset_size].ChannelNum <= 11)
337 					channel_set[chanset_size].ScanType = SCAN_ACTIVE;
338 				else
339 					channel_set[chanset_size].ScanType = SCAN_PASSIVE;
340 			} else {
341 				channel_set[chanset_size].ScanType = SCAN_ACTIVE;
342 			}
343 
344 			chanset_size++;
345 		}
346 	}
347 	return chanset_size;
348 }
349 
init_mlme_ext_priv(struct adapter * padapter)350 int	init_mlme_ext_priv(struct adapter *padapter)
351 {
352 	int	res = _SUCCESS;
353 	struct registry_priv *pregistrypriv = &padapter->registrypriv;
354 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
355 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
356 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
357 
358 	pmlmeext->padapter = padapter;
359 
360 	init_mlme_ext_priv_value(padapter);
361 	pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
362 
363 	init_mlme_ext_timer(padapter);
364 
365 #ifdef CONFIG_88EU_AP_MODE
366 	init_mlme_ap_info(padapter);
367 #endif
368 
369 	pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan, pmlmeext->channel_set);
370 	init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
371 
372 	pmlmeext->chan_scan_time = SURVEY_TO;
373 	pmlmeext->mlmeext_init = true;
374 
375 	pmlmeext->active_keep_alive_check = true;
376 
377 	return res;
378 }
379 
free_mlme_ext_priv(struct mlme_ext_priv * pmlmeext)380 void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext)
381 {
382 	struct adapter *padapter = pmlmeext->padapter;
383 
384 	if (!padapter)
385 		return;
386 
387 	if (padapter->bDriverStopped) {
388 		_cancel_timer_ex(&pmlmeext->survey_timer);
389 		_cancel_timer_ex(&pmlmeext->link_timer);
390 		/* _cancel_timer_ex(&pmlmeext->ADDBA_timer); */
391 	}
392 }
393 
_mgt_dispatcher(struct adapter * padapter,struct mlme_handler * ptable,struct recv_frame * precv_frame)394 static void _mgt_dispatcher(struct adapter *padapter, struct mlme_handler *ptable, struct recv_frame *precv_frame)
395 {
396 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
397 	u8 *pframe = precv_frame->rx_data;
398 
399 	if (ptable->func) {
400 	/* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
401 		if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) &&
402 		    memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
403 			return;
404 		ptable->func(padapter, precv_frame);
405 	}
406 }
407 
mgt_dispatcher(struct adapter * padapter,struct recv_frame * precv_frame)408 void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame)
409 {
410 	int index;
411 	struct mlme_handler *ptable;
412 #ifdef CONFIG_88EU_AP_MODE
413 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
414 #endif /* CONFIG_88EU_AP_MODE */
415 	u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
416 	u8 *pframe = precv_frame->rx_data;
417 	struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
418 
419 	if (GetFrameType(pframe) != WIFI_MGT_TYPE)
420 		return;
421 
422 	/* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
423 	if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) &&
424 	    memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
425 		return;
426 
427 	ptable = mlme_sta_tbl;
428 
429 	index = GetFrameSubType(pframe) >> 4;
430 
431 	if (index > 13)
432 		return;
433 	ptable += index;
434 
435 	if (psta) {
436 		if (GetRetry(pframe)) {
437 			if (precv_frame->attrib.seq_num == psta->RxMgmtFrameSeqNum) {
438 				/* drop the duplicate management frame */
439 				DBG_88E("Drop duplicate management frame with seq_num=%d.\n", precv_frame->attrib.seq_num);
440 				return;
441 			}
442 		}
443 		psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num;
444 	}
445 
446 #ifdef CONFIG_88EU_AP_MODE
447 	switch (GetFrameSubType(pframe)) {
448 	case WIFI_AUTH:
449 		if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
450 			ptable->func = &OnAuth;
451 		else
452 			ptable->func = &OnAuthClient;
453 		fallthrough;
454 	case WIFI_ASSOCREQ:
455 	case WIFI_REASSOCREQ:
456 		_mgt_dispatcher(padapter, ptable, precv_frame);
457 		break;
458 	case WIFI_PROBEREQ:
459 		if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
460 			_mgt_dispatcher(padapter, ptable, precv_frame);
461 		else
462 			_mgt_dispatcher(padapter, ptable, precv_frame);
463 		break;
464 	case WIFI_BEACON:
465 		_mgt_dispatcher(padapter, ptable, precv_frame);
466 		break;
467 	case WIFI_ACTION:
468 		_mgt_dispatcher(padapter, ptable, precv_frame);
469 		break;
470 	default:
471 		_mgt_dispatcher(padapter, ptable, precv_frame);
472 		if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
473 			rtw_hostapd_mlme_rx(padapter, precv_frame);
474 		break;
475 	}
476 #else
477 	_mgt_dispatcher(padapter, ptable, precv_frame);
478 #endif
479 }
480 
481 #ifdef CONFIG_88EU_P2P
p2p_listen_state_process(struct adapter * padapter,unsigned char * da)482 static u32 p2p_listen_state_process(struct adapter *padapter, unsigned char *da)
483 {
484 	bool response = true;
485 
486 	/*	do nothing if the device name is empty */
487 	if (!padapter->wdinfo.device_name_len)
488 		response = false;
489 
490 	if (response)
491 		issue_probersp_p2p(padapter, da);
492 
493 	return _SUCCESS;
494 }
495 #endif /* CONFIG_88EU_P2P */
496 
497 /****************************************************************************
498 
499 Following are the callback functions for each subtype of the management frames
500 
501 *****************************************************************************/
502 
OnProbeReq(struct adapter * padapter,struct recv_frame * precv_frame)503 unsigned int OnProbeReq(struct adapter *padapter, struct recv_frame *precv_frame)
504 {
505 	unsigned int	ielen;
506 	unsigned char	*p;
507 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
508 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
509 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
510 	struct wlan_bssid_ex *cur = &pmlmeinfo->network;
511 	u8 *pframe = precv_frame->rx_data;
512 	uint len = precv_frame->len;
513 	u8 is_valid_p2p_probereq = false;
514 
515 #ifdef CONFIG_88EU_P2P
516 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
517 	u8 wifi_test_chk_rate = 1;
518 
519 	if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
520 	    !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
521 	    !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
522 	    !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
523 	    !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)) {
524 		/*	mcs_rate = 0 -> CCK 1M rate */
525 		/*	mcs_rate = 1 -> CCK 2M rate */
526 		/*	mcs_rate = 2 -> CCK 5.5M rate */
527 		/*	mcs_rate = 3 -> CCK 11M rate */
528 		/*	In the P2P mode, the driver should not support the CCK rate */
529 
530 		/*	Commented by Kurt 2012/10/16 */
531 		/*	IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client */
532 		if (wifi_test_chk_rate == 1) {
533 			is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len);
534 			if (is_valid_p2p_probereq) {
535 				if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) {
536 					/*  FIXME */
537 					report_survey_event(padapter, precv_frame);
538 					p2p_listen_state_process(padapter,  get_sa(pframe));
539 
540 					return _SUCCESS;
541 				}
542 
543 				if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
544 					goto _continue;
545 			}
546 		}
547 	}
548 
549 _continue:
550 #endif /* CONFIG_88EU_P2P */
551 
552 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
553 		return _SUCCESS;
554 
555 	if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
556 	    !check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
557 		return _SUCCESS;
558 
559 	p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
560 			len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
561 
562 	/* check (wildcard) SSID */
563 	if (p) {
564 		if (is_valid_p2p_probereq)
565 			goto _issue_probersp;
566 
567 		if ((ielen != 0 && memcmp((void *)(p + 2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength)) ||
568 		    (ielen == 0 && pmlmeinfo->hidden_ssid_mode))
569 			return _SUCCESS;
570 
571 _issue_probersp:
572 
573 		if (check_fwstate(pmlmepriv, _FW_LINKED) &&
574 		    (pmlmepriv->cur_network.join_res ||
575 		    check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
576 			issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
577 	}
578 	return _SUCCESS;
579 }
580 
OnProbeRsp(struct adapter * padapter,struct recv_frame * precv_frame)581 unsigned int OnProbeRsp(struct adapter *padapter, struct recv_frame *precv_frame)
582 {
583 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
584 #ifdef CONFIG_88EU_P2P
585 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
586 	u8 *pframe = precv_frame->rx_data;
587 #endif
588 
589 #ifdef CONFIG_88EU_P2P
590 	if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) {
591 		if (pwdinfo->tx_prov_disc_info.benable) {
592 			if (!memcmp(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN)) {
593 				if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
594 					pwdinfo->tx_prov_disc_info.benable = false;
595 					issue_p2p_provision_request(padapter,
596 								    pwdinfo->tx_prov_disc_info.ssid.Ssid,
597 								    pwdinfo->tx_prov_disc_info.ssid.SsidLength,
598 								    pwdinfo->tx_prov_disc_info.peerDevAddr);
599 				} else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
600 					pwdinfo->tx_prov_disc_info.benable = false;
601 					issue_p2p_provision_request(padapter, NULL, 0,
602 								    pwdinfo->tx_prov_disc_info.peerDevAddr);
603 				}
604 			}
605 		}
606 		return _SUCCESS;
607 	} else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
608 		if (pwdinfo->nego_req_info.benable) {
609 			DBG_88E("[%s] P2P State is GONEGO ING!\n", __func__);
610 			if (!memcmp(pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN)) {
611 				pwdinfo->nego_req_info.benable = false;
612 				issue_p2p_GO_request(padapter, pwdinfo->nego_req_info.peerDevAddr);
613 			}
614 		}
615 	} else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) {
616 		if (pwdinfo->invitereq_info.benable) {
617 			DBG_88E("[%s] P2P_STATE_TX_INVITE_REQ!\n", __func__);
618 			if (!memcmp(pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN)) {
619 				pwdinfo->invitereq_info.benable = false;
620 				issue_p2p_invitation_request(padapter, pwdinfo->invitereq_info.peer_macaddr);
621 			}
622 		}
623 	}
624 #endif
625 
626 	if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
627 		report_survey_event(padapter, precv_frame);
628 		return _SUCCESS;
629 	}
630 
631 	return _SUCCESS;
632 }
633 
OnBeacon(struct adapter * padapter,struct recv_frame * precv_frame)634 unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame)
635 {
636 	int cam_idx;
637 	struct sta_info	*psta;
638 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
639 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
640 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
641 	struct sta_priv	*pstapriv = &padapter->stapriv;
642 	u8 *pframe = precv_frame->rx_data;
643 	uint len = precv_frame->len;
644 	struct wlan_bssid_ex *pbss;
645 	int ret = _SUCCESS;
646 
647 	if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
648 		report_survey_event(padapter, precv_frame);
649 		return _SUCCESS;
650 	}
651 
652 	if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) {
653 		if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
654 			/* we should update current network before auth, or some IE is wrong */
655 			pbss = kmalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
656 			if (pbss) {
657 				if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
658 					update_network(&pmlmepriv->cur_network.network, pbss, padapter, true);
659 					rtw_get_bcn_info(&pmlmepriv->cur_network);
660 				}
661 				kfree(pbss);
662 			}
663 
664 			/* check the vendor of the assoc AP */
665 			pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe + sizeof(struct rtw_ieee80211_hdr_3addr), len - sizeof(struct rtw_ieee80211_hdr_3addr));
666 
667 			/* update TSF Value */
668 			update_TSF(pmlmeext, pframe, len);
669 
670 			/* start auth */
671 			start_clnt_auth(padapter);
672 
673 			return _SUCCESS;
674 		}
675 
676 		if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
677 			psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
678 			if (psta) {
679 				ret = rtw_check_bcn_info(padapter, pframe, len);
680 				if (!ret) {
681 						DBG_88E_LEVEL(_drv_info_, "ap has changed, disconnect now\n ");
682 						receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0);
683 						return _SUCCESS;
684 				}
685 				/* update WMM, ERP in the beacon */
686 				/* todo: the timer is used instead of the number of the beacon received */
687 				if ((sta_rx_pkts(psta) & 0xf) == 0)
688 					update_beacon_info(padapter, pframe, len, psta);
689 				process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
690 			}
691 		} else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
692 			psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
693 			if (psta) {
694 				/* update WMM, ERP in the beacon */
695 				/* todo: the timer is used instead of the number of the beacon received */
696 				if ((sta_rx_pkts(psta) & 0xf) == 0)
697 					update_beacon_info(padapter, pframe, len, psta);
698 			} else {
699 				/* allocate a new CAM entry for IBSS station */
700 				cam_idx = allocate_fw_sta_entry(padapter);
701 				if (cam_idx == NUM_STA)
702 					goto _END_ONBEACON_;
703 
704 				/* get supported rate */
705 				if (update_sta_support_rate(padapter, (pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_), (len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_), cam_idx) == _FAIL) {
706 					pmlmeinfo->FW_sta_info[cam_idx].status = 0;
707 					goto _END_ONBEACON_;
708 				}
709 
710 				/* update TSF Value */
711 				update_TSF(pmlmeext, pframe, len);
712 
713 				/* report sta add event */
714 				report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx);
715 			}
716 		}
717 	}
718 
719 _END_ONBEACON_:
720 
721 	return _SUCCESS;
722 }
723 
OnAuth(struct adapter * padapter,struct recv_frame * precv_frame)724 unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_frame)
725 {
726 #ifdef CONFIG_88EU_AP_MODE
727 	unsigned int	auth_mode, ie_len;
728 	u16 seq;
729 	unsigned char	*sa, *p;
730 	u16 algorithm;
731 	int	status;
732 	static struct sta_info stat;
733 	struct	sta_info	*pstat = NULL;
734 	struct	sta_priv *pstapriv = &padapter->stapriv;
735 	struct security_priv *psecuritypriv = &padapter->securitypriv;
736 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
737 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
738 	u8 *pframe = precv_frame->rx_data;
739 	uint len = precv_frame->len;
740 
741 	if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
742 		return _FAIL;
743 
744 	DBG_88E("+OnAuth\n");
745 
746 	sa = GetAddr2Ptr(pframe);
747 
748 	auth_mode = psecuritypriv->dot11AuthAlgrthm;
749 	seq = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + 2));
750 	algorithm = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN));
751 
752 	DBG_88E("auth alg=%x, seq=%X\n", algorithm, seq);
753 
754 	if (auth_mode == 2 && psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
755 	    psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
756 		auth_mode = 0;
757 
758 	if ((algorithm > 0 && auth_mode == 0) ||	/*  rx a shared-key auth but shared not enabled */
759 	    (algorithm == 0 && auth_mode == 1)) {	/*  rx a open-system auth but shared-key is enabled */
760 		DBG_88E("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
761 			algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
762 
763 		status = _STATS_NO_SUPP_ALG_;
764 
765 		goto auth_fail;
766 	}
767 
768 	if (!rtw_access_ctrl(padapter, sa)) {
769 		status = _STATS_UNABLE_HANDLE_STA_;
770 		goto auth_fail;
771 	}
772 
773 	pstat = rtw_get_stainfo(pstapriv, sa);
774 	if (!pstat) {
775 		/*  allocate a new one */
776 		DBG_88E("going to alloc stainfo for sa=%pM\n", sa);
777 		pstat = rtw_alloc_stainfo(pstapriv, sa);
778 		if (!pstat) {
779 			DBG_88E(" Exceed the upper limit of supported clients...\n");
780 			status = _STATS_UNABLE_HANDLE_STA_;
781 			goto auth_fail;
782 		}
783 
784 		pstat->state = WIFI_FW_AUTH_NULL;
785 		pstat->auth_seq = 0;
786 	} else {
787 		spin_lock_bh(&pstapriv->asoc_list_lock);
788 		if (!list_empty(&pstat->asoc_list)) {
789 			list_del_init(&pstat->asoc_list);
790 			pstapriv->asoc_list_cnt--;
791 		}
792 		spin_unlock_bh(&pstapriv->asoc_list_lock);
793 
794 		if (seq == 1) {
795 			/* TODO: STA re_auth and auth timeout */
796 		}
797 	}
798 
799 	spin_lock_bh(&pstapriv->auth_list_lock);
800 	if (list_empty(&pstat->auth_list)) {
801 		list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
802 		pstapriv->auth_list_cnt++;
803 	}
804 	spin_unlock_bh(&pstapriv->auth_list_lock);
805 
806 	if (pstat->auth_seq == 0)
807 		pstat->expire_to = pstapriv->auth_to;
808 
809 	if ((pstat->auth_seq + 1) != seq) {
810 		DBG_88E("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
811 			seq, pstat->auth_seq + 1);
812 		status = _STATS_OUT_OF_AUTH_SEQ_;
813 		goto auth_fail;
814 	}
815 
816 	if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2)) {
817 		if (seq == 1) {
818 			pstat->state &= ~WIFI_FW_AUTH_NULL;
819 			pstat->state |= WIFI_FW_AUTH_SUCCESS;
820 			pstat->expire_to = pstapriv->assoc_to;
821 			pstat->authalg = algorithm;
822 		} else {
823 			DBG_88E("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
824 				seq, pstat->auth_seq + 1);
825 			status = _STATS_OUT_OF_AUTH_SEQ_;
826 			goto auth_fail;
827 		}
828 	} else { /*  shared system or auto authentication */
829 		if (seq == 1) {
830 			/* prepare for the challenging txt... */
831 
832 			pstat->state &= ~WIFI_FW_AUTH_NULL;
833 			pstat->state |= WIFI_FW_AUTH_STATE;
834 			pstat->authalg = algorithm;
835 			pstat->auth_seq = 2;
836 		} else if (seq == 3) {
837 			/* checking for challenging txt... */
838 			DBG_88E("checking for challenging txt...\n");
839 
840 			p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&ie_len,
841 					len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
842 
843 			if (!p || ie_len <= 0) {
844 				DBG_88E("auth rejected because challenge failure!(1)\n");
845 				status = _STATS_CHALLENGE_FAIL_;
846 				goto auth_fail;
847 			}
848 
849 			if (!memcmp((void *)(p + 2), pstat->chg_txt, 128)) {
850 				pstat->state &= (~WIFI_FW_AUTH_STATE);
851 				pstat->state |= WIFI_FW_AUTH_SUCCESS;
852 				/*  challenging txt is correct... */
853 				pstat->expire_to =  pstapriv->assoc_to;
854 			} else {
855 				DBG_88E("auth rejected because challenge failure!\n");
856 				status = _STATS_CHALLENGE_FAIL_;
857 				goto auth_fail;
858 			}
859 		} else {
860 			DBG_88E("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
861 				seq, pstat->auth_seq + 1);
862 			status = _STATS_OUT_OF_AUTH_SEQ_;
863 			goto auth_fail;
864 		}
865 	}
866 
867 	/*  Now, we are going to issue_auth... */
868 	pstat->auth_seq = seq + 1;
869 
870 #ifdef CONFIG_88EU_AP_MODE
871 	issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
872 #endif
873 
874 	if (pstat->state & WIFI_FW_AUTH_SUCCESS)
875 		pstat->auth_seq = 0;
876 
877 	return _SUCCESS;
878 
879 auth_fail:
880 
881 	if (pstat)
882 		rtw_free_stainfo(padapter, pstat);
883 
884 	pstat = &stat;
885 	memset((char *)pstat, '\0', sizeof(stat));
886 	pstat->auth_seq = 2;
887 	memcpy(pstat->hwaddr, sa, 6);
888 
889 #ifdef CONFIG_88EU_AP_MODE
890 	issue_auth(padapter, pstat, (unsigned short)status);
891 #endif
892 
893 #endif
894 	return _FAIL;
895 }
896 
OnAuthClient(struct adapter * padapter,struct recv_frame * precv_frame)897 unsigned int OnAuthClient(struct adapter *padapter, struct recv_frame *precv_frame)
898 {
899 	unsigned int	seq, len, status, offset;
900 	unsigned char	*p;
901 	unsigned int	go2asoc = 0;
902 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
903 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
904 	u8 *pframe = precv_frame->rx_data;
905 	uint pkt_len = precv_frame->len;
906 
907 	DBG_88E("%s\n", __func__);
908 
909 	/* check A1 matches or not */
910 	if (memcmp(myid(&padapter->eeprompriv), get_da(pframe), ETH_ALEN))
911 		return _SUCCESS;
912 
913 	if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
914 		return _SUCCESS;
915 
916 	offset = (GetPrivacy(pframe)) ? 4 : 0;
917 
918 	seq	= le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + offset + 2));
919 	status	= le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + offset + 4));
920 
921 	if (status != 0) {
922 		DBG_88E("clnt auth fail, status: %d\n", status);
923 		if (status == 13) { /*  pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
924 			if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
925 				pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
926 			else
927 				pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
928 		}
929 
930 		set_link_timer(pmlmeext, 1);
931 		goto authclnt_fail;
932 	}
933 
934 	if (seq == 2) {
935 		if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
936 			 /*  legendary shared system */
937 			p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
938 				pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
939 
940 			if (!p)
941 				goto authclnt_fail;
942 
943 			memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
944 			pmlmeinfo->auth_seq = 3;
945 			issue_auth(padapter, NULL, 0);
946 			set_link_timer(pmlmeext, REAUTH_TO);
947 
948 			return _SUCCESS;
949 		} else {
950 			/*  open system */
951 			go2asoc = 1;
952 		}
953 	} else if (seq == 4) {
954 		if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
955 			go2asoc = 1;
956 		else
957 			goto authclnt_fail;
958 	} else {
959 		/*  this is also illegal */
960 		goto authclnt_fail;
961 	}
962 
963 	if (go2asoc) {
964 		DBG_88E_LEVEL(_drv_info_, "auth success, start assoc\n");
965 		start_clnt_assoc(padapter);
966 		return _SUCCESS;
967 	}
968 authclnt_fail:
969 	return _FAIL;
970 }
971 
OnAssocReq(struct adapter * padapter,struct recv_frame * precv_frame)972 unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame)
973 {
974 #ifdef CONFIG_88EU_AP_MODE
975 	u16 capab_info;
976 	struct rtw_ieee802_11_elems elems;
977 	struct sta_info	*pstat;
978 	unsigned char		reassoc, *p, *pos, *wpa_ie;
979 	unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
980 	int		i, ie_len, wpa_ie_len, left;
981 	unsigned char		supportRate[16];
982 	int					supportRateNum;
983 	unsigned short		status = _STATS_SUCCESSFUL_;
984 	unsigned short		frame_type, ie_offset = 0;
985 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
986 	struct security_priv *psecuritypriv = &padapter->securitypriv;
987 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
988 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
989 	struct wlan_bssid_ex *cur = &pmlmeinfo->network;
990 	struct sta_priv *pstapriv = &padapter->stapriv;
991 	u8 *pframe = precv_frame->rx_data;
992 	uint pkt_len = precv_frame->len;
993 #ifdef CONFIG_88EU_P2P
994 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
995 	u8 p2p_status_code = P2P_STATUS_SUCCESS;
996 	u8 *p2pie;
997 	u32 p2pielen = 0;
998 #endif /* CONFIG_88EU_P2P */
999 
1000 	if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
1001 		return _FAIL;
1002 
1003 	frame_type = GetFrameSubType(pframe);
1004 	if (frame_type == WIFI_ASSOCREQ) {
1005 		reassoc = 0;
1006 		ie_offset = _ASOCREQ_IE_OFFSET_;
1007 	} else { /*  WIFI_REASSOCREQ */
1008 		reassoc = 1;
1009 		ie_offset = _REASOCREQ_IE_OFFSET_;
1010 	}
1011 
1012 	if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
1013 		DBG_88E("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
1014 		       "\n", reassoc, (unsigned long)pkt_len);
1015 		return _FAIL;
1016 	}
1017 
1018 	pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1019 	if (pstat == (struct sta_info *)NULL) {
1020 		status = _RSON_CLS2_;
1021 		goto asoc_class2_error;
1022 	}
1023 
1024 	capab_info = get_unaligned_le16(pframe + WLAN_HDR_A3_LEN);
1025 
1026 	left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
1027 	pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
1028 
1029 	DBG_88E("%s\n", __func__);
1030 
1031 	/*  check if this stat has been successfully authenticated/assocated */
1032 	if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) {
1033 		if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) {
1034 			status = _RSON_CLS2_;
1035 			goto asoc_class2_error;
1036 		} else {
1037 			pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
1038 			pstat->state |= WIFI_FW_ASSOC_STATE;
1039 		}
1040 	} else {
1041 		pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
1042 		pstat->state |= WIFI_FW_ASSOC_STATE;
1043 	}
1044 	pstat->capability = capab_info;
1045 	/* now parse all ieee802_11 ie to point to elems */
1046 	if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
1047 	    !elems.ssid) {
1048 		DBG_88E("STA %pM sent invalid association request\n",
1049 			pstat->hwaddr);
1050 		status = _STATS_FAILURE_;
1051 		goto OnAssocReqFail;
1052 	}
1053 
1054 	/*  now we should check all the fields... */
1055 	/*  checking SSID */
1056 	p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
1057 		pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1058 	if (!p)
1059 		status = _STATS_FAILURE_;
1060 
1061 	if (ie_len == 0) { /*  broadcast ssid, however it is not allowed in assocreq */
1062 		status = _STATS_FAILURE_;
1063 	} else {
1064 		/*  check if ssid match */
1065 		if (memcmp((void *)(p + 2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
1066 			status = _STATS_FAILURE_;
1067 
1068 		if (ie_len != cur->Ssid.SsidLength)
1069 			status = _STATS_FAILURE_;
1070 	}
1071 
1072 	if (_STATS_SUCCESSFUL_ != status)
1073 		goto OnAssocReqFail;
1074 
1075 	/*  check if the supported rate is ok */
1076 	p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1077 	if (!p) {
1078 		DBG_88E("Rx a sta assoc-req which supported rate is empty!\n");
1079 		/*  use our own rate set as statoin used */
1080 		/* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
1081 		/* supportRateNum = AP_BSSRATE_LEN; */
1082 
1083 		status = _STATS_FAILURE_;
1084 		goto OnAssocReqFail;
1085 	} else {
1086 		memcpy(supportRate, p + 2, ie_len);
1087 		supportRateNum = ie_len;
1088 
1089 		p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_, &ie_len,
1090 				pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1091 		if (p) {
1092 			if (supportRateNum <= sizeof(supportRate)) {
1093 				memcpy(supportRate + supportRateNum, p + 2, ie_len);
1094 				supportRateNum += ie_len;
1095 			}
1096 		}
1097 	}
1098 
1099 	/* todo: mask supportRate between AP & STA -> move to update raid */
1100 	/* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
1101 
1102 	/* update station supportRate */
1103 	pstat->bssratelen = supportRateNum;
1104 	memcpy(pstat->bssrateset, supportRate, supportRateNum);
1105 	UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
1106 
1107 	/* check RSN/WPA/WPS */
1108 	pstat->dot8021xalg = 0;
1109 	pstat->wpa_psk = 0;
1110 	pstat->wpa_group_cipher = 0;
1111 	pstat->wpa2_group_cipher = 0;
1112 	pstat->wpa_pairwise_cipher = 0;
1113 	pstat->wpa2_pairwise_cipher = 0;
1114 	memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
1115 	if ((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
1116 		int group_cipher = 0, pairwise_cipher = 0;
1117 
1118 		wpa_ie = elems.rsn_ie;
1119 		wpa_ie_len = elems.rsn_ie_len;
1120 
1121 		if (rtw_parse_wpa2_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1122 			pstat->dot8021xalg = 1;/* psk,  todo:802.1x */
1123 			pstat->wpa_psk |= BIT(1);
1124 
1125 			pstat->wpa2_group_cipher = group_cipher & psecuritypriv->wpa2_group_cipher;
1126 			pstat->wpa2_pairwise_cipher = pairwise_cipher & psecuritypriv->wpa2_pairwise_cipher;
1127 
1128 			if (!pstat->wpa2_group_cipher)
1129 				status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
1130 
1131 			if (!pstat->wpa2_pairwise_cipher)
1132 				status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1133 		} else {
1134 			status = WLAN_STATUS_INVALID_IE;
1135 		}
1136 	} else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
1137 		int group_cipher = 0, pairwise_cipher = 0;
1138 
1139 		wpa_ie = elems.wpa_ie;
1140 		wpa_ie_len = elems.wpa_ie_len;
1141 
1142 		if (rtw_parse_wpa_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1143 			pstat->dot8021xalg = 1;/* psk,  todo:802.1x */
1144 			pstat->wpa_psk |= BIT(0);
1145 
1146 			pstat->wpa_group_cipher = group_cipher & psecuritypriv->wpa_group_cipher;
1147 			pstat->wpa_pairwise_cipher = pairwise_cipher & psecuritypriv->wpa_pairwise_cipher;
1148 
1149 			if (!pstat->wpa_group_cipher)
1150 				status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
1151 
1152 			if (!pstat->wpa_pairwise_cipher)
1153 				status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1154 		} else {
1155 			status = WLAN_STATUS_INVALID_IE;
1156 		}
1157 	} else {
1158 		wpa_ie = NULL;
1159 		wpa_ie_len = 0;
1160 	}
1161 
1162 	if (_STATS_SUCCESSFUL_ != status)
1163 		goto OnAssocReqFail;
1164 
1165 	pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
1166 	if (!wpa_ie) {
1167 		if (elems.wps_ie) {
1168 			DBG_88E("STA included WPS IE in "
1169 				   "(Re)Association Request - assume WPS is "
1170 				   "used\n");
1171 			pstat->flags |= WLAN_STA_WPS;
1172 			/* wpabuf_free(sta->wps_ie); */
1173 			/* sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, */
1174 			/*				elems.wps_ie_len - 4); */
1175 		} else {
1176 			DBG_88E("STA did not include WPA/RSN IE "
1177 				   "in (Re)Association Request - possible WPS "
1178 				   "use\n");
1179 			pstat->flags |= WLAN_STA_MAYBE_WPS;
1180 		}
1181 
1182 		/*  AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */
1183 		/*  that the selected registrar of AP is _FLASE */
1184 		if ((psecuritypriv->wpa_psk > 0) && (pstat->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) {
1185 			if (pmlmepriv->wps_beacon_ie) {
1186 				u8 selected_registrar = 0;
1187 
1188 				rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR, &selected_registrar, NULL);
1189 
1190 				if (!selected_registrar) {
1191 					DBG_88E("selected_registrar is false , or AP is not ready to do WPS\n");
1192 
1193 					status = _STATS_UNABLE_HANDLE_STA_;
1194 
1195 					goto OnAssocReqFail;
1196 				}
1197 			}
1198 		}
1199 	} else {
1200 		int copy_len;
1201 
1202 		if (psecuritypriv->wpa_psk == 0) {
1203 			DBG_88E("STA %pM: WPA/RSN IE in association "
1204 			"request, but AP don't support WPA/RSN\n", pstat->hwaddr);
1205 
1206 			status = WLAN_STATUS_INVALID_IE;
1207 
1208 			goto OnAssocReqFail;
1209 		}
1210 
1211 		if (elems.wps_ie) {
1212 			DBG_88E("STA included WPS IE in "
1213 				   "(Re)Association Request - WPS is "
1214 				   "used\n");
1215 			pstat->flags |= WLAN_STA_WPS;
1216 			copy_len = 0;
1217 		} else {
1218 			copy_len = ((wpa_ie_len + 2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)) : (wpa_ie_len + 2);
1219 		}
1220 		if (copy_len > 0)
1221 			memcpy(pstat->wpa_ie, wpa_ie - 2, copy_len);
1222 	}
1223 	/*  check if there is WMM IE & support WWM-PS */
1224 	pstat->flags &= ~WLAN_STA_WME;
1225 	pstat->qos_option = 0;
1226 	pstat->qos_info = 0;
1227 	pstat->has_legacy_ac = true;
1228 	pstat->uapsd_vo = 0;
1229 	pstat->uapsd_vi = 0;
1230 	pstat->uapsd_be = 0;
1231 	pstat->uapsd_bk = 0;
1232 	if (pmlmepriv->qospriv.qos_option) {
1233 		p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
1234 		for (;;) {
1235 			p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1236 			if (p) {
1237 				if (!memcmp(p + 2, WMM_IE, 6)) {
1238 					pstat->flags |= WLAN_STA_WME;
1239 
1240 					pstat->qos_option = 1;
1241 					pstat->qos_info = *(p + 8);
1242 
1243 					pstat->max_sp_len = (pstat->qos_info >> 5) & 0x3;
1244 
1245 					if ((pstat->qos_info & 0xf) != 0xf)
1246 						pstat->has_legacy_ac = true;
1247 					else
1248 						pstat->has_legacy_ac = false;
1249 
1250 					if (pstat->qos_info & 0xf) {
1251 						if (pstat->qos_info & BIT(0))
1252 							pstat->uapsd_vo = BIT(0) | BIT(1);
1253 						else
1254 							pstat->uapsd_vo = 0;
1255 
1256 						if (pstat->qos_info & BIT(1))
1257 							pstat->uapsd_vi = BIT(0) | BIT(1);
1258 						else
1259 							pstat->uapsd_vi = 0;
1260 
1261 						if (pstat->qos_info & BIT(2))
1262 							pstat->uapsd_bk = BIT(0) | BIT(1);
1263 						else
1264 							pstat->uapsd_bk = 0;
1265 
1266 						if (pstat->qos_info & BIT(3))
1267 							pstat->uapsd_be = BIT(0) | BIT(1);
1268 						else
1269 							pstat->uapsd_be = 0;
1270 					}
1271 					break;
1272 				}
1273 			} else {
1274 				break;
1275 			}
1276 			p = p + ie_len + 2;
1277 		}
1278 	}
1279 
1280 	/* save HT capabilities in the sta object */
1281 	memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
1282 	if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct ieee80211_ht_cap)) {
1283 		pstat->flags |= WLAN_STA_HT;
1284 
1285 		pstat->flags |= WLAN_STA_WME;
1286 
1287 		memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct ieee80211_ht_cap));
1288 	} else {
1289 		pstat->flags &= ~WLAN_STA_HT;
1290 	}
1291 	if ((!pmlmepriv->htpriv.ht_option) && (pstat->flags & WLAN_STA_HT)) {
1292 		status = _STATS_FAILURE_;
1293 		goto OnAssocReqFail;
1294 	}
1295 
1296 	if ((pstat->flags & WLAN_STA_HT) &&
1297 	    ((pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) ||
1298 	    (pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP))) {
1299 		DBG_88E("HT: %pM tried to "
1300 			"use TKIP with HT association\n", pstat->hwaddr);
1301 
1302 		/* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
1303 		/* goto OnAssocReqFail; */
1304 	}
1305 
1306 	pstat->flags |= WLAN_STA_NONERP;
1307 	for (i = 0; i < pstat->bssratelen; i++) {
1308 		if ((pstat->bssrateset[i] & 0x7f) > 22) {
1309 			pstat->flags &= ~WLAN_STA_NONERP;
1310 			break;
1311 		}
1312 	}
1313 
1314 	if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1315 		pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
1316 	else
1317 		pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1318 
1319 	if (status != _STATS_SUCCESSFUL_)
1320 		goto OnAssocReqFail;
1321 
1322 #ifdef CONFIG_88EU_P2P
1323 	pstat->is_p2p_device = false;
1324 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
1325 		p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, NULL, &p2pielen);
1326 		if (p2pie) {
1327 			pstat->is_p2p_device = true;
1328 			p2p_status_code = (u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat);
1329 			if (p2p_status_code > 0) {
1330 				pstat->p2p_status_code = p2p_status_code;
1331 				status = _STATS_CAP_FAIL_;
1332 				goto OnAssocReqFail;
1333 			}
1334 		}
1335 	}
1336 	pstat->p2p_status_code = p2p_status_code;
1337 #endif /* CONFIG_88EU_P2P */
1338 
1339 	/* TODO: identify_proprietary_vendor_ie(); */
1340 	/*  Realtek proprietary IE */
1341 	/*  identify if this is Broadcom sta */
1342 	/*  identify if this is ralink sta */
1343 	/*  Customer proprietary IE */
1344 
1345 	/* get a unique AID */
1346 	if (pstat->aid > 0) {
1347 		DBG_88E("  old AID %d\n", pstat->aid);
1348 	} else {
1349 		for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
1350 			if (!pstapriv->sta_aid[pstat->aid - 1])
1351 				break;
1352 
1353 		/* if (pstat->aid > NUM_STA) { */
1354 		if (pstat->aid > pstapriv->max_num_sta) {
1355 			pstat->aid = 0;
1356 
1357 			DBG_88E("  no room for more AIDs\n");
1358 
1359 			status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1360 
1361 			goto OnAssocReqFail;
1362 		} else {
1363 			pstapriv->sta_aid[pstat->aid - 1] = pstat;
1364 			DBG_88E("allocate new AID=(%d)\n", pstat->aid);
1365 		}
1366 	}
1367 
1368 	pstat->state &= (~WIFI_FW_ASSOC_STATE);
1369 	pstat->state |= WIFI_FW_ASSOC_SUCCESS;
1370 
1371 	spin_lock_bh(&pstapriv->auth_list_lock);
1372 	if (!list_empty(&pstat->auth_list)) {
1373 		list_del_init(&pstat->auth_list);
1374 		pstapriv->auth_list_cnt--;
1375 	}
1376 	spin_unlock_bh(&pstapriv->auth_list_lock);
1377 
1378 	spin_lock_bh(&pstapriv->asoc_list_lock);
1379 	if (list_empty(&pstat->asoc_list)) {
1380 		pstat->expire_to = pstapriv->expire_to;
1381 		list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
1382 		pstapriv->asoc_list_cnt++;
1383 	}
1384 	spin_unlock_bh(&pstapriv->asoc_list_lock);
1385 
1386 	/*  now the station is qualified to join our BSS... */
1387 	if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_ == status)) {
1388 #ifdef CONFIG_88EU_AP_MODE
1389 		/* 1 bss_cap_update & sta_info_update */
1390 		bss_cap_update_on_sta_join(padapter, pstat);
1391 		sta_info_update(padapter, pstat);
1392 
1393 		/* issue assoc rsp before notify station join event. */
1394 		if (frame_type == WIFI_ASSOCREQ)
1395 			issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
1396 		else
1397 			issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
1398 
1399 		/* 2 - report to upper layer */
1400 		DBG_88E("indicate_sta_join_event to upper layer - hostapd\n");
1401 		rtw_indicate_sta_assoc_event(padapter, pstat);
1402 
1403 		/* 3-(1) report sta add event */
1404 		report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
1405 #endif
1406 	}
1407 
1408 	return _SUCCESS;
1409 
1410 asoc_class2_error:
1411 
1412 #ifdef CONFIG_88EU_AP_MODE
1413 	issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
1414 #endif
1415 
1416 	return _FAIL;
1417 
1418 OnAssocReqFail:
1419 
1420 #ifdef CONFIG_88EU_AP_MODE
1421 	pstat->aid = 0;
1422 	if (frame_type == WIFI_ASSOCREQ)
1423 		issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
1424 	else
1425 		issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
1426 #endif
1427 
1428 #endif /* CONFIG_88EU_AP_MODE */
1429 
1430 	return _FAIL;
1431 }
1432 
OnAssocRsp(struct adapter * padapter,struct recv_frame * precv_frame)1433 unsigned int OnAssocRsp(struct adapter *padapter, struct recv_frame *precv_frame)
1434 {
1435 	uint i;
1436 	int res;
1437 	unsigned short	status;
1438 	struct ndis_802_11_var_ie *pIE;
1439 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1440 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
1441 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
1442 	/* struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); */
1443 	u8 *pframe = precv_frame->rx_data;
1444 	uint pkt_len = precv_frame->len;
1445 
1446 	DBG_88E("%s\n", __func__);
1447 
1448 	/* check A1 matches or not */
1449 	if (memcmp(myid(&padapter->eeprompriv), get_da(pframe), ETH_ALEN))
1450 		return _SUCCESS;
1451 
1452 	if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
1453 		return _SUCCESS;
1454 
1455 	if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1456 		return _SUCCESS;
1457 
1458 	_cancel_timer_ex(&pmlmeext->link_timer);
1459 
1460 	/* status */
1461 	status = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 2));
1462 	if (status > 0) {
1463 		DBG_88E("assoc reject, status code: %d\n", status);
1464 		pmlmeinfo->state = WIFI_FW_NULL_STATE;
1465 		res = -4;
1466 		goto report_assoc_result;
1467 	}
1468 
1469 	/* get capabilities */
1470 	pmlmeinfo->capability = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
1471 
1472 	/* set slot time */
1473 	pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20;
1474 
1475 	/* AID */
1476 	pmlmeinfo->aid = (int)(le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 4)) & 0x3fff);
1477 	res = pmlmeinfo->aid;
1478 
1479 	/* following are moved to join event callback function */
1480 	/* to handle HT, WMM, rate adaptive, update MAC reg */
1481 	/* for not to handle the synchronous IO in the tasklet */
1482 	for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) {
1483 		pIE = (struct ndis_802_11_var_ie *)(pframe + i);
1484 
1485 		switch (pIE->ElementID) {
1486 		case _VENDOR_SPECIFIC_IE_:
1487 			if (!memcmp(pIE->data, WMM_PARA_OUI, 6))	/* WMM */
1488 				WMM_param_handler(padapter, pIE);
1489 			break;
1490 		case _HT_CAPABILITY_IE_:	/* HT caps */
1491 			HT_caps_handler(padapter, pIE);
1492 			break;
1493 		case _HT_EXTRA_INFO_IE_:	/* HT info */
1494 			HT_info_handler(padapter, pIE);
1495 			break;
1496 		case _ERPINFO_IE_:
1497 			ERP_IE_handler(padapter, pIE);
1498 			break;
1499 		default:
1500 			break;
1501 		}
1502 
1503 		i += (pIE->Length + 2);
1504 	}
1505 
1506 	pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
1507 	pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
1508 
1509 	/* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
1510 	UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
1511 
1512 report_assoc_result:
1513 	if (res > 0)
1514 		rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
1515 	else
1516 		kfree(pmlmepriv->assoc_rsp);
1517 
1518 	report_join_res(padapter, res);
1519 
1520 	return _SUCCESS;
1521 }
1522 
OnDeAuth(struct adapter * padapter,struct recv_frame * precv_frame)1523 unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame)
1524 {
1525 	unsigned short	reason;
1526 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1527 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
1528 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
1529 	u8 *pframe = precv_frame->rx_data;
1530 #ifdef CONFIG_88EU_P2P
1531 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1532 #endif /* CONFIG_88EU_P2P */
1533 
1534 	/* check A3 */
1535 	if (!(!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
1536 		return _SUCCESS;
1537 
1538 #ifdef CONFIG_88EU_P2P
1539 	if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
1540 		_cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
1541 		_set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
1542 	}
1543 #endif /* CONFIG_88EU_P2P */
1544 
1545 	reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
1546 
1547 	DBG_88E("%s Reason code(%d)\n", __func__, reason);
1548 
1549 #ifdef CONFIG_88EU_AP_MODE
1550 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1551 		struct sta_info *psta;
1552 		struct sta_priv *pstapriv = &padapter->stapriv;
1553 
1554 		DBG_88E_LEVEL(_drv_always_, "ap recv deauth reason code(%d) sta:%pM\n",
1555 			      reason, GetAddr2Ptr(pframe));
1556 
1557 		psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1558 		if (psta) {
1559 			u8 updated = 0;
1560 
1561 			spin_lock_bh(&pstapriv->asoc_list_lock);
1562 			if (!list_empty(&psta->asoc_list)) {
1563 				list_del_init(&psta->asoc_list);
1564 				pstapriv->asoc_list_cnt--;
1565 				updated = ap_free_sta(padapter, psta, false, reason);
1566 			}
1567 			spin_unlock_bh(&pstapriv->asoc_list_lock);
1568 
1569 			associated_clients_update(padapter, updated);
1570 		}
1571 
1572 		return _SUCCESS;
1573 	} else
1574 #endif
1575 	{
1576 		int	ignore_received_deauth = 0;
1577 
1578 		/* Before sending the auth frame to start the STA/GC mode connection with AP/GO,
1579 		 *	we will send the deauth first.
1580 		 *	However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth.
1581 		 *	Added the following code to avoid this case.
1582 		 */
1583 		if ((pmlmeinfo->state & WIFI_FW_AUTH_STATE) ||
1584 		    (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)) {
1585 			if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA) {
1586 				ignore_received_deauth = 1;
1587 			} else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
1588 				// TODO: 802.11r
1589 				ignore_received_deauth = 1;
1590 			}
1591 		}
1592 
1593 		DBG_88E_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM, ignore = %d\n",
1594 			      reason, GetAddr3Ptr(pframe), ignore_received_deauth);
1595 
1596 		if (!ignore_received_deauth)
1597 			receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
1598 	}
1599 	pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1600 	return _SUCCESS;
1601 }
1602 
OnDisassoc(struct adapter * padapter,struct recv_frame * precv_frame)1603 unsigned int OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame)
1604 {
1605 	u16 reason;
1606 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1607 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
1608 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
1609 	u8 *pframe = precv_frame->rx_data;
1610 #ifdef CONFIG_88EU_P2P
1611 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1612 #endif /* CONFIG_88EU_P2P */
1613 
1614 	/* check A3 */
1615 	if (!(!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
1616 		return _SUCCESS;
1617 
1618 #ifdef CONFIG_88EU_P2P
1619 	if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
1620 		_cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
1621 		_set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
1622 	}
1623 #endif /* CONFIG_88EU_P2P */
1624 
1625 	reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
1626 
1627 	DBG_88E("%s Reason code(%d)\n", __func__, reason);
1628 
1629 #ifdef CONFIG_88EU_AP_MODE
1630 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1631 		struct sta_info *psta;
1632 		struct sta_priv *pstapriv = &padapter->stapriv;
1633 
1634 		DBG_88E_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
1635 			      reason, GetAddr2Ptr(pframe));
1636 
1637 		psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1638 		if (psta) {
1639 			u8 updated = 0;
1640 
1641 			spin_lock_bh(&pstapriv->asoc_list_lock);
1642 			if (!list_empty(&psta->asoc_list)) {
1643 				list_del_init(&psta->asoc_list);
1644 				pstapriv->asoc_list_cnt--;
1645 				updated = ap_free_sta(padapter, psta, false, reason);
1646 			}
1647 			spin_unlock_bh(&pstapriv->asoc_list_lock);
1648 
1649 			associated_clients_update(padapter, updated);
1650 		}
1651 
1652 		return _SUCCESS;
1653 	} else
1654 #endif
1655 	{
1656 		DBG_88E_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
1657 			      reason, GetAddr3Ptr(pframe));
1658 
1659 		receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
1660 	}
1661 	pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1662 	return _SUCCESS;
1663 }
1664 
OnAtim(struct adapter * padapter,struct recv_frame * precv_frame)1665 unsigned int OnAtim(struct adapter *padapter, struct recv_frame *precv_frame)
1666 {
1667 	DBG_88E("%s\n", __func__);
1668 	return _SUCCESS;
1669 }
1670 
on_action_spct(struct adapter * padapter,struct recv_frame * precv_frame)1671 unsigned int on_action_spct(struct adapter *padapter, struct recv_frame *precv_frame)
1672 {
1673 	unsigned int ret = _FAIL;
1674 	struct sta_info *psta = NULL;
1675 	struct sta_priv *pstapriv = &padapter->stapriv;
1676 	u8 *pframe = precv_frame->rx_data;
1677 	u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
1678 	u8 category;
1679 	u8 action;
1680 
1681 	DBG_88E(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
1682 
1683 	psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1684 
1685 	if (!psta)
1686 		goto exit;
1687 
1688 	category = frame_body[0];
1689 	if (category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
1690 		goto exit;
1691 
1692 	action = frame_body[1];
1693 	switch (action) {
1694 	case RTW_WLAN_ACTION_SPCT_MSR_REQ:
1695 	case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
1696 	case RTW_WLAN_ACTION_SPCT_TPC_REQ:
1697 	case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
1698 		break;
1699 	case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
1700 		break;
1701 	default:
1702 		break;
1703 	}
1704 
1705 exit:
1706 	return ret;
1707 }
1708 
OnAction_qos(struct adapter * padapter,struct recv_frame * precv_frame)1709 unsigned int OnAction_qos(struct adapter *padapter, struct recv_frame *precv_frame)
1710 {
1711 	return _SUCCESS;
1712 }
1713 
OnAction_dls(struct adapter * padapter,struct recv_frame * precv_frame)1714 unsigned int OnAction_dls(struct adapter *padapter, struct recv_frame *precv_frame)
1715 {
1716 	return _SUCCESS;
1717 }
1718 
OnAction_back(struct adapter * padapter,struct recv_frame * precv_frame)1719 unsigned int OnAction_back(struct adapter *padapter, struct recv_frame *precv_frame)
1720 {
1721 	u8 *addr;
1722 	struct sta_info *psta = NULL;
1723 	struct recv_reorder_ctrl *preorder_ctrl;
1724 	unsigned char		*frame_body;
1725 	unsigned char		category, action;
1726 	unsigned short	tid, status, reason_code = 0;
1727 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
1728 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
1729 	u8 *pframe = precv_frame->rx_data;
1730 	struct sta_priv *pstapriv = &padapter->stapriv;
1731 	/* check RA matches or not */
1732 	if (memcmp(myid(&padapter->eeprompriv), GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */
1733 		return _SUCCESS;
1734 
1735 	DBG_88E("%s\n", __func__);
1736 
1737 	if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
1738 		if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
1739 			return _SUCCESS;
1740 
1741 	addr = GetAddr2Ptr(pframe);
1742 	psta = rtw_get_stainfo(pstapriv, addr);
1743 
1744 	if (!psta)
1745 		return _SUCCESS;
1746 
1747 	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
1748 
1749 	category = frame_body[0];
1750 	if (category == RTW_WLAN_CATEGORY_BACK) { /*  representing Block Ack */
1751 		if (!pmlmeinfo->HT_enable)
1752 			return _SUCCESS;
1753 		action = frame_body[1];
1754 		DBG_88E("%s, action=%d\n", __func__, action);
1755 		switch (action) {
1756 		case RTW_WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
1757 			memcpy(&pmlmeinfo->ADDBA_req, &frame_body[2], sizeof(struct ADDBA_request));
1758 			process_addba_req(padapter, (u8 *)&pmlmeinfo->ADDBA_req, addr);
1759 
1760 			if (pmlmeinfo->bAcceptAddbaReq)
1761 				issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 0);
1762 			else
1763 				issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 37);/* reject ADDBA Req */
1764 			break;
1765 		case RTW_WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
1766 			status = get_unaligned_le16(&frame_body[3]);
1767 			tid = ((frame_body[5] >> 2) & 0x7);
1768 			if (status == 0) {	/* successful */
1769 				DBG_88E("agg_enable for TID=%d\n", tid);
1770 				psta->htpriv.agg_enable_bitmap |= 1 << tid;
1771 				psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
1772 			} else {
1773 				psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
1774 			}
1775 			break;
1776 		case RTW_WLAN_ACTION_DELBA: /* DELBA */
1777 			if ((frame_body[3] & BIT(3)) == 0) {
1778 				psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
1779 				psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
1780 				reason_code = get_unaligned_le16(&frame_body[4]);
1781 			} else if ((frame_body[3] & BIT(3)) == BIT(3)) {
1782 				tid = (frame_body[3] >> 4) & 0x0F;
1783 				preorder_ctrl =  &psta->recvreorder_ctrl[tid];
1784 				preorder_ctrl->enable = false;
1785 				preorder_ctrl->indicate_seq = 0xffff;
1786 			}
1787 			DBG_88E("%s(): DELBA: %x(%x)\n", __func__, pmlmeinfo->agg_enable_bitmap, reason_code);
1788 			/* todo: how to notify the host while receiving DELETE BA */
1789 			break;
1790 		default:
1791 			break;
1792 		}
1793 	}
1794 	return _SUCCESS;
1795 }
1796 
1797 #ifdef CONFIG_88EU_P2P
1798 
get_reg_classes_full_count(struct p2p_channels * channel_list)1799 static int get_reg_classes_full_count(struct p2p_channels *channel_list)
1800 {
1801 	int cnt = 0;
1802 	int i;
1803 
1804 	for (i = 0; i < channel_list->reg_classes; i++) {
1805 		cnt += channel_list->reg_class[i].channels;
1806 	}
1807 
1808 	return cnt;
1809 }
1810 
issue_p2p_GO_request(struct adapter * padapter,u8 * raddr)1811 void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr)
1812 {
1813 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
1814 	u8 action = P2P_PUB_ACTION_ACTION;
1815 	__be32 p2poui = cpu_to_be32(P2POUI);
1816 	u8 oui_subtype = P2P_GO_NEGO_REQ;
1817 	u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
1818 	u8 wpsielen = 0, p2pielen = 0;
1819 	u16 len_channellist_attr = 0;
1820 	struct xmit_frame *pmgntframe;
1821 	struct pkt_attrib *pattrib;
1822 	unsigned char *pframe;
1823 	struct rtw_ieee80211_hdr	*pwlanhdr;
1824 	__le16 *fctrl;
1825 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1826 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
1827 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
1828 
1829 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1830 	if (!pmgntframe)
1831 		return;
1832 
1833 	DBG_88E("[%s] In\n", __func__);
1834 	/* update attribute */
1835 	pattrib = &pmgntframe->attrib;
1836 	update_mgntframe_attrib(padapter, pattrib);
1837 
1838 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
1839 
1840 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
1841 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
1842 
1843 	fctrl = &pwlanhdr->frame_ctl;
1844 	*(fctrl) = 0;
1845 
1846 	memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
1847 	memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
1848 	memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
1849 
1850 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
1851 	pmlmeext->mgnt_seq++;
1852 	SetFrameSubType(pframe, WIFI_ACTION);
1853 
1854 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
1855 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
1856 
1857 	pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
1858 	pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
1859 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
1860 	pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
1861 	pwdinfo->negotiation_dialog_token = 1;	/*	Initialize the dialog value */
1862 	pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &pattrib->pktlen);
1863 
1864 	/*	WPS Section */
1865 	wpsielen = 0;
1866 	/*	WPS OUI */
1867 	*(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
1868 	wpsielen += 4;
1869 
1870 	/*	WPS version */
1871 	/*	Type: */
1872 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
1873 	wpsielen += 2;
1874 
1875 	/*	Length: */
1876 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
1877 	wpsielen += 2;
1878 
1879 	/*	Value: */
1880 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
1881 
1882 	/*	Device Password ID */
1883 	/*	Type: */
1884 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
1885 	wpsielen += 2;
1886 
1887 	/*	Length: */
1888 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
1889 	wpsielen += 2;
1890 
1891 	/*	Value: */
1892 
1893 	if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN)
1894 		*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
1895 	else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN)
1896 		*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
1897 	else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC)
1898 		*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
1899 
1900 	wpsielen += 2;
1901 
1902 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
1903 
1904 	/*	P2P IE Section. */
1905 
1906 	/*	P2P OUI */
1907 	p2pielen = 0;
1908 	p2pie[p2pielen++] = 0x50;
1909 	p2pie[p2pielen++] = 0x6F;
1910 	p2pie[p2pielen++] = 0x9A;
1911 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
1912 
1913 	/*	Commented by Albert 20110306 */
1914 	/*	According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes */
1915 	/*	1. P2P Capability */
1916 	/*	2. Group Owner Intent */
1917 	/*	3. Configuration Timeout */
1918 	/*	4. Listen Channel */
1919 	/*	5. Extended Listen Timing */
1920 	/*	6. Intended P2P Interface Address */
1921 	/*	7. Channel List */
1922 	/*	8. P2P Device Info */
1923 	/*	9. Operating Channel */
1924 
1925 	/*	P2P Capability */
1926 	/*	Type: */
1927 	p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
1928 
1929 	/*	Length: */
1930 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
1931 	p2pielen += 2;
1932 
1933 	/*	Value: */
1934 	/*	Device Capability Bitmap, 1 byte */
1935 	p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
1936 
1937 	/*	Group Capability Bitmap, 1 byte */
1938 	if (pwdinfo->persistent_supported)
1939 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
1940 	else
1941 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
1942 
1943 	/*	Group Owner Intent */
1944 	/*	Type: */
1945 	p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
1946 
1947 	/*	Length: */
1948 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
1949 	p2pielen += 2;
1950 
1951 	/*	Value: */
1952 	/*	Todo the tie breaker bit. */
1953 	p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
1954 
1955 	/*	Configuration Timeout */
1956 	/*	Type: */
1957 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
1958 
1959 	/*	Length: */
1960 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
1961 	p2pielen += 2;
1962 
1963 	/*	Value: */
1964 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
1965 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
1966 
1967 	/*	Listen Channel */
1968 	/*	Type: */
1969 	p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
1970 
1971 	/*	Length: */
1972 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
1973 	p2pielen += 2;
1974 
1975 	/*	Value: */
1976 	/*	Country String */
1977 	p2pie[p2pielen++] = 'X';
1978 	p2pie[p2pielen++] = 'X';
1979 
1980 	/*	The third byte should be set to 0x04. */
1981 	/*	Described in the "Operating Channel Attribute" section. */
1982 	p2pie[p2pielen++] = 0x04;
1983 
1984 	/*	Operating Class */
1985 	p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
1986 
1987 	/*	Channel Number */
1988 	p2pie[p2pielen++] = pwdinfo->listen_channel;	/*	listening channel number */
1989 
1990 	/*	Extended Listen Timing ATTR */
1991 	/*	Type: */
1992 	p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
1993 
1994 	/*	Length: */
1995 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
1996 	p2pielen += 2;
1997 
1998 	/*	Value: */
1999 	/*	Availability Period */
2000 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
2001 	p2pielen += 2;
2002 
2003 	/*	Availability Interval */
2004 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
2005 	p2pielen += 2;
2006 
2007 	/*	Intended P2P Interface Address */
2008 	/*	Type: */
2009 	p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR;
2010 
2011 	/*	Length: */
2012 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
2013 	p2pielen += 2;
2014 
2015 	/*	Value: */
2016 	memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
2017 	p2pielen += ETH_ALEN;
2018 
2019 	/*	Channel List */
2020 	/*	Type: */
2021 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
2022 
2023 	/*  Length: */
2024 	/*  Country String(3) */
2025 	/*  + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */
2026 	/*  + number of channels in all classes */
2027 	len_channellist_attr = 3
2028 	   + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
2029 	   + get_reg_classes_full_count(&pmlmeext->channel_list);
2030 
2031 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
2032 	p2pielen += 2;
2033 
2034 	/*	Value: */
2035 	/*	Country String */
2036 	p2pie[p2pielen++] = 'X';
2037 	p2pie[p2pielen++] = 'X';
2038 
2039 	/*	The third byte should be set to 0x04. */
2040 	/*	Described in the "Operating Channel Attribute" section. */
2041 	p2pie[p2pielen++] = 0x04;
2042 
2043 	/*	Channel Entry List */
2044 
2045 	{
2046 		int i, j;
2047 		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
2048 			/*	Operating Class */
2049 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
2050 
2051 			/*	Number of Channels */
2052 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
2053 
2054 			/*	Channel List */
2055 			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
2056 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
2057 			}
2058 		}
2059 	}
2060 
2061 	/*	Device Info */
2062 	/*	Type: */
2063 	p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
2064 
2065 	/*	Length: */
2066 	/*	21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
2067 	/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
2068 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
2069 	p2pielen += 2;
2070 
2071 	/*	Value: */
2072 	/*	P2P Device Address */
2073 	memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
2074 	p2pielen += ETH_ALEN;
2075 
2076 	/*	Config Method */
2077 	/*	This field should be big endian. Noted by P2P specification. */
2078 
2079 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
2080 
2081 	p2pielen += 2;
2082 
2083 	/*	Primary Device Type */
2084 	/*	Category ID */
2085 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
2086 	p2pielen += 2;
2087 
2088 	/*	OUI */
2089 	*(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
2090 	p2pielen += 4;
2091 
2092 	/*	Sub Category ID */
2093 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
2094 	p2pielen += 2;
2095 
2096 	/*	Number of Secondary Device Types */
2097 	p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
2098 
2099 	/*	Device Name */
2100 	/*	Type: */
2101 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
2102 	p2pielen += 2;
2103 
2104 	/*	Length: */
2105 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
2106 	p2pielen += 2;
2107 
2108 	/*	Value: */
2109 	memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
2110 	p2pielen += pwdinfo->device_name_len;
2111 
2112 	/*	Operating Channel */
2113 	/*	Type: */
2114 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
2115 
2116 	/*	Length: */
2117 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
2118 	p2pielen += 2;
2119 
2120 	/*	Value: */
2121 	/*	Country String */
2122 	p2pie[p2pielen++] = 'X';
2123 	p2pie[p2pielen++] = 'X';
2124 
2125 	/*	The third byte should be set to 0x04. */
2126 	/*	Described in the "Operating Channel Attribute" section. */
2127 	p2pie[p2pielen++] = 0x04;
2128 
2129 	/*	Operating Class */
2130 	p2pie[p2pielen++] = 0x51;
2131 
2132 	/*	Channel Number */
2133 	p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
2134 
2135 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
2136 
2137 	pattrib->last_txcmdsz = pattrib->pktlen;
2138 
2139 	dump_mgntframe(padapter, pmgntframe);
2140 }
2141 
issue_p2p_GO_response(struct adapter * padapter,u8 * raddr,u8 * frame_body,uint len,u8 result)2142 static void issue_p2p_GO_response(struct adapter *padapter, u8 *raddr, u8 *frame_body, uint len, u8 result)
2143 {
2144 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
2145 	u8 action = P2P_PUB_ACTION_ACTION;
2146 	__be32			p2poui = cpu_to_be32(P2POUI);
2147 	u8 oui_subtype = P2P_GO_NEGO_RESP;
2148 	u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
2149 	u8 p2pielen = 0;
2150 	uint			wpsielen = 0;
2151 	u16 wps_devicepassword_id = 0x0000;
2152 	__be16			be_tmp;
2153 	uint			wps_devicepassword_id_len = 0;
2154 	u16 len_channellist_attr = 0;
2155 
2156 	struct xmit_frame			*pmgntframe;
2157 	struct pkt_attrib			*pattrib;
2158 	unsigned char					*pframe;
2159 	struct rtw_ieee80211_hdr	*pwlanhdr;
2160 	__le16 *fctrl;
2161 	struct xmit_priv			*pxmitpriv = &padapter->xmitpriv;
2162 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
2163 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
2164 
2165 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2166 	if (!pmgntframe)
2167 		return;
2168 
2169 	DBG_88E("[%s] In, result=%d\n", __func__,  result);
2170 	/* update attribute */
2171 	pattrib = &pmgntframe->attrib;
2172 	update_mgntframe_attrib(padapter, pattrib);
2173 
2174 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2175 
2176 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2177 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
2178 
2179 	fctrl = &pwlanhdr->frame_ctl;
2180 	*(fctrl) = 0;
2181 
2182 	memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
2183 	memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
2184 	memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
2185 
2186 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2187 	pmlmeext->mgnt_seq++;
2188 	SetFrameSubType(pframe, WIFI_ACTION);
2189 
2190 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
2191 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
2192 
2193 	pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
2194 	pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
2195 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
2196 	pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
2197 	pwdinfo->negotiation_dialog_token = frame_body[7];	/*	The Dialog Token of provisioning discovery request frame. */
2198 	pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &pattrib->pktlen);
2199 
2200 	/*	Commented by Albert 20110328 */
2201 	/*	Try to get the device password ID from the WPS IE of group negotiation request frame */
2202 	/*	WiFi Direct test plan 5.1.15 */
2203 	rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
2204 	rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8 *)&be_tmp, &wps_devicepassword_id_len);
2205 	wps_devicepassword_id = be16_to_cpu(be_tmp);
2206 
2207 	memset(wpsie, 0x00, 255);
2208 	wpsielen = 0;
2209 
2210 	/*	WPS Section */
2211 	wpsielen = 0;
2212 	/*	WPS OUI */
2213 	*(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
2214 	wpsielen += 4;
2215 
2216 	/*	WPS version */
2217 	/*	Type: */
2218 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
2219 	wpsielen += 2;
2220 
2221 	/*	Length: */
2222 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
2223 	wpsielen += 2;
2224 
2225 	/*	Value: */
2226 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
2227 
2228 	/*	Device Password ID */
2229 	/*	Type: */
2230 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
2231 	wpsielen += 2;
2232 
2233 	/*	Length: */
2234 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
2235 	wpsielen += 2;
2236 
2237 	/*	Value: */
2238 	if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
2239 		*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
2240 	else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
2241 		*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
2242 	else
2243 		*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
2244 	wpsielen += 2;
2245 
2246 	/*	Commented by Kurt 20120113 */
2247 	/*	If some device wants to do p2p handshake without sending prov_disc_req */
2248 	/*	We have to get peer_req_cm from here. */
2249 	if (!memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) {
2250 		if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
2251 			memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
2252 		else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
2253 			memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
2254 		else
2255 			memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
2256 	}
2257 
2258 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
2259 
2260 	/*	P2P IE Section. */
2261 
2262 	/*	P2P OUI */
2263 	p2pielen = 0;
2264 	p2pie[p2pielen++] = 0x50;
2265 	p2pie[p2pielen++] = 0x6F;
2266 	p2pie[p2pielen++] = 0x9A;
2267 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
2268 
2269 	/*	Commented by Albert 20100908 */
2270 	/*	According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
2271 	/*	1. Status */
2272 	/*	2. P2P Capability */
2273 	/*	3. Group Owner Intent */
2274 	/*	4. Configuration Timeout */
2275 	/*	5. Operating Channel */
2276 	/*	6. Intended P2P Interface Address */
2277 	/*	7. Channel List */
2278 	/*	8. Device Info */
2279 	/*	9. Group ID	(Only GO) */
2280 
2281 	/*	ToDo: */
2282 
2283 	/*	P2P Status */
2284 	/*	Type: */
2285 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
2286 
2287 	/*	Length: */
2288 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
2289 	p2pielen += 2;
2290 
2291 	/*	Value: */
2292 	p2pie[p2pielen++] = result;
2293 
2294 	/*	P2P Capability */
2295 	/*	Type: */
2296 	p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
2297 
2298 	/*	Length: */
2299 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
2300 	p2pielen += 2;
2301 
2302 	/*	Value: */
2303 	/*	Device Capability Bitmap, 1 byte */
2304 
2305 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
2306 		/*	Commented by Albert 2011/03/08 */
2307 		/*	According to the P2P specification */
2308 		/*	if the sending device will be client, the P2P Capability should be reserved of group negotiation response frame */
2309 		p2pie[p2pielen++] = 0;
2310 	} else {
2311 		/*	Be group owner or meet the error case */
2312 		p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
2313 	}
2314 
2315 	/*	Group Capability Bitmap, 1 byte */
2316 	if (pwdinfo->persistent_supported) {
2317 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
2318 	} else {
2319 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
2320 	}
2321 
2322 	/*	Group Owner Intent */
2323 	/*	Type: */
2324 	p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
2325 
2326 	/*	Length: */
2327 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
2328 	p2pielen += 2;
2329 
2330 	/*	Value: */
2331 	if (pwdinfo->peer_intent & 0x01) {
2332 		/*	Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
2333 		p2pie[p2pielen++] = (pwdinfo->intent << 1);
2334 	} else {
2335 		/*	Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
2336 		p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
2337 	}
2338 
2339 	/*	Configuration Timeout */
2340 	/*	Type: */
2341 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
2342 
2343 	/*	Length: */
2344 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
2345 	p2pielen += 2;
2346 
2347 	/*	Value: */
2348 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
2349 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
2350 
2351 	/*	Operating Channel */
2352 	/*	Type: */
2353 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
2354 
2355 	/*	Length: */
2356 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
2357 	p2pielen += 2;
2358 
2359 	/*	Value: */
2360 	/*	Country String */
2361 	p2pie[p2pielen++] = 'X';
2362 	p2pie[p2pielen++] = 'X';
2363 
2364 	/*	The third byte should be set to 0x04. */
2365 	/*	Described in the "Operating Channel Attribute" section. */
2366 	p2pie[p2pielen++] = 0x04;
2367 
2368 	/*	Operating Class */
2369 	p2pie[p2pielen++] = 0x51;
2370 
2371 	/*	Channel Number */
2372 	p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
2373 
2374 	/*	Intended P2P Interface Address */
2375 	/*	Type: */
2376 	p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR;
2377 
2378 	/*	Length: */
2379 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
2380 	p2pielen += 2;
2381 
2382 	/*	Value: */
2383 	memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
2384 	p2pielen += ETH_ALEN;
2385 
2386 	/*	Channel List */
2387 	/*	Type: */
2388 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
2389 
2390 	/*  Country String(3) */
2391 	/*  + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */
2392 	/*  + number of channels in all classes */
2393 	len_channellist_attr = 3
2394 	   + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
2395 	   + get_reg_classes_full_count(&pmlmeext->channel_list);
2396 
2397 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
2398 
2399 	p2pielen += 2;
2400 
2401 	/*	Value: */
2402 	/*	Country String */
2403 	p2pie[p2pielen++] = 'X';
2404 	p2pie[p2pielen++] = 'X';
2405 
2406 	/*	The third byte should be set to 0x04. */
2407 	/*	Described in the "Operating Channel Attribute" section. */
2408 	p2pie[p2pielen++] = 0x04;
2409 
2410 	/*	Channel Entry List */
2411 
2412 	{
2413 		int i, j;
2414 		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
2415 			/*	Operating Class */
2416 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
2417 
2418 			/*	Number of Channels */
2419 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
2420 
2421 			/*	Channel List */
2422 			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
2423 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
2424 			}
2425 		}
2426 	}
2427 
2428 	/*	Device Info */
2429 	/*	Type: */
2430 	p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
2431 
2432 	/*	Length: */
2433 	/*	21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
2434 	/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
2435 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
2436 	p2pielen += 2;
2437 
2438 	/*	Value: */
2439 	/*	P2P Device Address */
2440 	memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
2441 	p2pielen += ETH_ALEN;
2442 
2443 	/*	Config Method */
2444 	/*	This field should be big endian. Noted by P2P specification. */
2445 
2446 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
2447 
2448 	p2pielen += 2;
2449 
2450 	/*	Primary Device Type */
2451 	/*	Category ID */
2452 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
2453 	p2pielen += 2;
2454 
2455 	/*	OUI */
2456 	*(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
2457 	p2pielen += 4;
2458 
2459 	/*	Sub Category ID */
2460 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
2461 	p2pielen += 2;
2462 
2463 	/*	Number of Secondary Device Types */
2464 	p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
2465 
2466 	/*	Device Name */
2467 	/*	Type: */
2468 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
2469 	p2pielen += 2;
2470 
2471 	/*	Length: */
2472 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
2473 	p2pielen += 2;
2474 
2475 	/*	Value: */
2476 	memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
2477 	p2pielen += pwdinfo->device_name_len;
2478 
2479 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
2480 		/*	Group ID Attribute */
2481 		/*	Type: */
2482 		p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
2483 
2484 		/*	Length: */
2485 		*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
2486 		p2pielen += 2;
2487 
2488 		/*	Value: */
2489 		/*	p2P Device Address */
2490 		memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
2491 		p2pielen += ETH_ALEN;
2492 
2493 		/*	SSID */
2494 		memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
2495 		p2pielen += pwdinfo->nego_ssidlen;
2496 	}
2497 
2498 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
2499 
2500 	pattrib->last_txcmdsz = pattrib->pktlen;
2501 
2502 	dump_mgntframe(padapter, pmgntframe);
2503 }
2504 
issue_p2p_GO_confirm(struct adapter * padapter,u8 * raddr,u8 result)2505 static void issue_p2p_GO_confirm(struct adapter *padapter, u8 *raddr, u8 result)
2506 {
2507 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
2508 	u8 action = P2P_PUB_ACTION_ACTION;
2509 	__be32			p2poui = cpu_to_be32(P2POUI);
2510 	u8 oui_subtype = P2P_GO_NEGO_CONF;
2511 	u8 p2pie[255] = { 0x00 };
2512 	u8 p2pielen = 0;
2513 
2514 	struct xmit_frame			*pmgntframe;
2515 	struct pkt_attrib			*pattrib;
2516 	unsigned char					*pframe;
2517 	struct rtw_ieee80211_hdr	*pwlanhdr;
2518 	__le16 *fctrl;
2519 	struct xmit_priv			*pxmitpriv = &padapter->xmitpriv;
2520 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
2521 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
2522 
2523 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2524 	if (!pmgntframe)
2525 		return;
2526 
2527 	DBG_88E("[%s] In\n", __func__);
2528 	/* update attribute */
2529 	pattrib = &pmgntframe->attrib;
2530 	update_mgntframe_attrib(padapter, pattrib);
2531 
2532 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2533 
2534 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2535 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
2536 
2537 	fctrl = &pwlanhdr->frame_ctl;
2538 	*(fctrl) = 0;
2539 
2540 	memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
2541 	memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
2542 	memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
2543 
2544 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2545 	pmlmeext->mgnt_seq++;
2546 	SetFrameSubType(pframe, WIFI_ACTION);
2547 
2548 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
2549 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
2550 
2551 	pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
2552 	pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
2553 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
2554 	pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
2555 	pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &pattrib->pktlen);
2556 
2557 	/*	P2P IE Section. */
2558 
2559 	/*	P2P OUI */
2560 	p2pielen = 0;
2561 	p2pie[p2pielen++] = 0x50;
2562 	p2pie[p2pielen++] = 0x6F;
2563 	p2pie[p2pielen++] = 0x9A;
2564 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
2565 
2566 	/*	Commented by Albert 20110306 */
2567 	/*	According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes */
2568 	/*	1. Status */
2569 	/*	2. P2P Capability */
2570 	/*	3. Operating Channel */
2571 	/*	4. Channel List */
2572 	/*	5. Group ID	(if this WiFi is GO) */
2573 
2574 	/*	P2P Status */
2575 	/*	Type: */
2576 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
2577 
2578 	/*	Length: */
2579 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
2580 	p2pielen += 2;
2581 
2582 	/*	Value: */
2583 	p2pie[p2pielen++] = result;
2584 
2585 	/*	P2P Capability */
2586 	/*	Type: */
2587 	p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
2588 
2589 	/*	Length: */
2590 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
2591 	p2pielen += 2;
2592 
2593 	/*	Value: */
2594 	/*	Device Capability Bitmap, 1 byte */
2595 	p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
2596 
2597 	/*	Group Capability Bitmap, 1 byte */
2598 	if (pwdinfo->persistent_supported)
2599 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
2600 	else
2601 		p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
2602 
2603 	/*	Operating Channel */
2604 	/*	Type: */
2605 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
2606 
2607 	/*	Length: */
2608 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
2609 	p2pielen += 2;
2610 
2611 	/*	Value: */
2612 	/*	Country String */
2613 	p2pie[p2pielen++] = 'X';
2614 	p2pie[p2pielen++] = 'X';
2615 
2616 	/*	The third byte should be set to 0x04. */
2617 	/*	Described in the "Operating Channel Attribute" section. */
2618 	p2pie[p2pielen++] = 0x04;
2619 
2620 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
2621 		/*	Operating Class */
2622 		p2pie[p2pielen++] = 0x51;
2623 		p2pie[p2pielen++] = pwdinfo->peer_operating_ch;
2624 	} else {
2625 		/*	Operating Class */
2626 		p2pie[p2pielen++] = 0x51;
2627 
2628 		/*	Channel Number */
2629 		p2pie[p2pielen++] = pwdinfo->operating_channel;		/*	Use the listen channel as the operating channel */
2630 	}
2631 
2632 	/*	Channel List */
2633 	/*	Type: */
2634 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
2635 
2636 	/*	Length: */
2637 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(pwdinfo->channel_list_attr_len);
2638 	p2pielen += 2;
2639 
2640 	/*	Value: */
2641 	memcpy(p2pie + p2pielen, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len);
2642 	p2pielen += pwdinfo->channel_list_attr_len;
2643 
2644 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
2645 		/*	Group ID Attribute */
2646 		/*	Type: */
2647 		p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
2648 
2649 		/*	Length: */
2650 		*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
2651 		p2pielen += 2;
2652 
2653 		/*	Value: */
2654 		/*	p2P Device Address */
2655 		memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
2656 		p2pielen += ETH_ALEN;
2657 
2658 		/*	SSID */
2659 		memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
2660 		p2pielen += pwdinfo->nego_ssidlen;
2661 	}
2662 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
2663 	pattrib->last_txcmdsz = pattrib->pktlen;
2664 	dump_mgntframe(padapter, pmgntframe);
2665 }
2666 
issue_p2p_invitation_request(struct adapter * padapter,u8 * raddr)2667 void issue_p2p_invitation_request(struct adapter *padapter, u8 *raddr)
2668 {
2669 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
2670 	u8 action = P2P_PUB_ACTION_ACTION;
2671 	__be32			p2poui = cpu_to_be32(P2POUI);
2672 	u8 oui_subtype = P2P_INVIT_REQ;
2673 	u8 p2pie[255] = { 0x00 };
2674 	u8 p2pielen = 0;
2675 	u8 dialogToken = 3;
2676 	u16 len_channellist_attr = 0;
2677 	struct xmit_frame			*pmgntframe;
2678 	struct pkt_attrib			*pattrib;
2679 	unsigned char					*pframe;
2680 	struct rtw_ieee80211_hdr	*pwlanhdr;
2681 	__le16 *fctrl;
2682 	struct xmit_priv			*pxmitpriv = &padapter->xmitpriv;
2683 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
2684 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
2685 
2686 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2687 	if (!pmgntframe)
2688 		return;
2689 
2690 	/* update attribute */
2691 	pattrib = &pmgntframe->attrib;
2692 	update_mgntframe_attrib(padapter, pattrib);
2693 
2694 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2695 
2696 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2697 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
2698 
2699 	fctrl = &pwlanhdr->frame_ctl;
2700 	*(fctrl) = 0;
2701 
2702 	memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
2703 	memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
2704 	memcpy(pwlanhdr->addr3, raddr,  ETH_ALEN);
2705 
2706 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2707 	pmlmeext->mgnt_seq++;
2708 	SetFrameSubType(pframe, WIFI_ACTION);
2709 
2710 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
2711 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
2712 
2713 	pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
2714 	pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
2715 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
2716 	pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
2717 	pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
2718 
2719 	/*	P2P IE Section. */
2720 
2721 	/*	P2P OUI */
2722 	p2pielen = 0;
2723 	p2pie[p2pielen++] = 0x50;
2724 	p2pie[p2pielen++] = 0x6F;
2725 	p2pie[p2pielen++] = 0x9A;
2726 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
2727 
2728 	/*	Commented by Albert 20101011 */
2729 	/*	According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes */
2730 	/*	1. Configuration Timeout */
2731 	/*	2. Invitation Flags */
2732 	/*	3. Operating Channel	(Only GO) */
2733 	/*	4. P2P Group BSSID	(Should be included if I am the GO) */
2734 	/*	5. Channel List */
2735 	/*	6. P2P Group ID */
2736 	/*	7. P2P Device Info */
2737 
2738 	/*	Configuration Timeout */
2739 	/*	Type: */
2740 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
2741 
2742 	/*	Length: */
2743 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
2744 	p2pielen += 2;
2745 
2746 	/*	Value: */
2747 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
2748 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
2749 
2750 	/*	Invitation Flags */
2751 	/*	Type: */
2752 	p2pie[p2pielen++] = P2P_ATTR_INVITATION_FLAGS;
2753 
2754 	/*	Length: */
2755 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
2756 	p2pielen += 2;
2757 
2758 	/*	Value: */
2759 	p2pie[p2pielen++] = P2P_INVITATION_FLAGS_PERSISTENT;
2760 
2761 	/*	Operating Channel */
2762 	/*	Type: */
2763 	p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
2764 
2765 	/*	Length: */
2766 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
2767 	p2pielen += 2;
2768 
2769 	/*	Value: */
2770 	/*	Country String */
2771 	p2pie[p2pielen++] = 'X';
2772 	p2pie[p2pielen++] = 'X';
2773 
2774 	/*	The third byte should be set to 0x04. */
2775 	/*	Described in the "Operating Channel Attribute" section. */
2776 	p2pie[p2pielen++] = 0x04;
2777 
2778 	/*	Operating Class */
2779 	p2pie[p2pielen++] = 0x51;
2780 
2781 	/*	Channel Number */
2782 	p2pie[p2pielen++] = pwdinfo->invitereq_info.operating_ch;	/*	operating channel number */
2783 
2784 	if (!memcmp(myid(&padapter->eeprompriv), pwdinfo->invitereq_info.go_bssid, ETH_ALEN)) {
2785 		/*	P2P Group BSSID */
2786 		/*	Type: */
2787 		p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
2788 
2789 		/*	Length: */
2790 		*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
2791 		p2pielen += 2;
2792 
2793 		/*	Value: */
2794 		/*	P2P Device Address for GO */
2795 		memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
2796 		p2pielen += ETH_ALEN;
2797 	}
2798 
2799 	/*	Channel List */
2800 	/*	Type: */
2801 	p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
2802 
2803 	/*	Length: */
2804 	/*  Country String(3) */
2805 	/*  + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */
2806 	/*  + number of channels in all classes */
2807 	len_channellist_attr = 3
2808 	   + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
2809 	   + get_reg_classes_full_count(&pmlmeext->channel_list);
2810 
2811 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
2812 
2813 	p2pielen += 2;
2814 
2815 	/*	Value: */
2816 	/*	Country String */
2817 	p2pie[p2pielen++] = 'X';
2818 	p2pie[p2pielen++] = 'X';
2819 
2820 	/*	The third byte should be set to 0x04. */
2821 	/*	Described in the "Operating Channel Attribute" section. */
2822 	p2pie[p2pielen++] = 0x04;
2823 
2824 	/*	Channel Entry List */
2825 	{
2826 		int i, j;
2827 		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
2828 			/*	Operating Class */
2829 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
2830 
2831 			/*	Number of Channels */
2832 			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
2833 
2834 			/*	Channel List */
2835 			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
2836 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
2837 			}
2838 		}
2839 	}
2840 
2841 	/*	P2P Group ID */
2842 	/*	Type: */
2843 	p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
2844 
2845 	/*	Length: */
2846 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(6 + pwdinfo->invitereq_info.ssidlen);
2847 	p2pielen += 2;
2848 
2849 	/*	Value: */
2850 	/*	P2P Device Address for GO */
2851 	memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
2852 	p2pielen += ETH_ALEN;
2853 
2854 	/*	SSID */
2855 	memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen);
2856 	p2pielen += pwdinfo->invitereq_info.ssidlen;
2857 
2858 	/*	Device Info */
2859 	/*	Type: */
2860 	p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
2861 
2862 	/*	Length: */
2863 	/*	21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
2864 	/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
2865 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
2866 	p2pielen += 2;
2867 
2868 	/*	Value: */
2869 	/*	P2P Device Address */
2870 	memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
2871 	p2pielen += ETH_ALEN;
2872 
2873 	/*	Config Method */
2874 	/*	This field should be big endian. Noted by P2P specification. */
2875 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
2876 	p2pielen += 2;
2877 
2878 	/*	Primary Device Type */
2879 	/*	Category ID */
2880 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
2881 	p2pielen += 2;
2882 
2883 	/*	OUI */
2884 	*(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
2885 	p2pielen  += 4;
2886 
2887 	/*	Sub Category ID */
2888 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
2889 	p2pielen += 2;
2890 
2891 	/*	Number of Secondary Device Types */
2892 	p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
2893 
2894 	/*	Device Name */
2895 	/*	Type: */
2896 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
2897 	p2pielen += 2;
2898 
2899 	/*	Length: */
2900 	*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
2901 	p2pielen += 2;
2902 
2903 	/*	Value: */
2904 	memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
2905 	p2pielen += pwdinfo->device_name_len;
2906 
2907 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
2908 
2909 	pattrib->last_txcmdsz = pattrib->pktlen;
2910 
2911 	dump_mgntframe(padapter, pmgntframe);
2912 }
2913 
issue_p2p_invitation_response(struct adapter * padapter,u8 * raddr,u8 dialogToken,u8 status_code)2914 void issue_p2p_invitation_response(struct adapter *padapter, u8 *raddr, u8 dialogToken, u8 status_code)
2915 {
2916 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
2917 	u8 action = P2P_PUB_ACTION_ACTION;
2918 	__be32			p2poui = cpu_to_be32(P2POUI);
2919 	u8 oui_subtype = P2P_INVIT_RESP;
2920 	u8 p2pie[255] = { 0x00 };
2921 	u8 p2pielen = 0;
2922 	u16 len_channellist_attr = 0;
2923 	struct xmit_frame			*pmgntframe;
2924 	struct pkt_attrib			*pattrib;
2925 	unsigned char					*pframe;
2926 	struct rtw_ieee80211_hdr	*pwlanhdr;
2927 	__le16 *fctrl;
2928 	struct xmit_priv			*pxmitpriv = &padapter->xmitpriv;
2929 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
2930 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
2931 
2932 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2933 	if (!pmgntframe)
2934 		return;
2935 
2936 	/* update attribute */
2937 	pattrib = &pmgntframe->attrib;
2938 	update_mgntframe_attrib(padapter, pattrib);
2939 
2940 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2941 
2942 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2943 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
2944 
2945 	fctrl = &pwlanhdr->frame_ctl;
2946 	*(fctrl) = 0;
2947 
2948 	memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
2949 	memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
2950 	memcpy(pwlanhdr->addr3, raddr,  ETH_ALEN);
2951 
2952 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2953 	pmlmeext->mgnt_seq++;
2954 	SetFrameSubType(pframe, WIFI_ACTION);
2955 
2956 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
2957 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
2958 
2959 	pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
2960 	pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
2961 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
2962 	pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
2963 	pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
2964 
2965 	/*	P2P IE Section. */
2966 
2967 	/*	P2P OUI */
2968 	p2pielen = 0;
2969 	p2pie[p2pielen++] = 0x50;
2970 	p2pie[p2pielen++] = 0x6F;
2971 	p2pie[p2pielen++] = 0x9A;
2972 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
2973 
2974 	/*	Commented by Albert 20101005 */
2975 	/*	According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
2976 	/*	1. Status */
2977 	/*	2. Configuration Timeout */
2978 	/*	3. Operating Channel	(Only GO) */
2979 	/*	4. P2P Group BSSID	(Only GO) */
2980 	/*	5. Channel List */
2981 
2982 	/*	P2P Status */
2983 	/*	Type: */
2984 	p2pie[p2pielen++] = P2P_ATTR_STATUS;
2985 
2986 	/*	Length: */
2987 	*(__le16  *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
2988 	p2pielen += 2;
2989 
2990 	/*	Value: */
2991 	/*	When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. */
2992 	/*	Sent the event receiving the P2P Invitation Req frame to DMP UI. */
2993 	/*	DMP had to compare the MAC address to find out the profile. */
2994 	/*	So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. */
2995 	/*	If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req */
2996 	/*	to NB to rebuild the persistent group. */
2997 	p2pie[p2pielen++] = status_code;
2998 
2999 	/*	Configuration Timeout */
3000 	/*	Type: */
3001 	p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
3002 
3003 	/*	Length: */
3004 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
3005 	p2pielen += 2;
3006 
3007 	/*	Value: */
3008 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P GO */
3009 	p2pie[p2pielen++] = 200;	/*	2 seconds needed to be the P2P Client */
3010 
3011 	if (status_code == P2P_STATUS_SUCCESS) {
3012 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
3013 			/*	The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
3014 			/*	In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
3015 			/*	First one is operating channel attribute. */
3016 			/*	Second one is P2P Group BSSID attribute. */
3017 
3018 			/*	Operating Channel */
3019 			/*	Type: */
3020 			p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
3021 
3022 			/*	Length: */
3023 			*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
3024 			p2pielen += 2;
3025 
3026 			/*	Value: */
3027 			/*	Country String */
3028 			p2pie[p2pielen++] = 'X';
3029 			p2pie[p2pielen++] = 'X';
3030 
3031 			/*	The third byte should be set to 0x04. */
3032 			/*	Described in the "Operating Channel Attribute" section. */
3033 			p2pie[p2pielen++] = 0x04;
3034 
3035 			/*	Operating Class */
3036 			p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
3037 
3038 			/*	Channel Number */
3039 			p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
3040 
3041 			/*	P2P Group BSSID */
3042 			/*	Type: */
3043 			p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
3044 
3045 			/*	Length: */
3046 			*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
3047 			p2pielen += 2;
3048 
3049 			/*	Value: */
3050 			/*	P2P Device Address for GO */
3051 			memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
3052 			p2pielen += ETH_ALEN;
3053 		}
3054 
3055 		/*	Channel List */
3056 		/*	Type: */
3057 		p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
3058 
3059 		/*	Length: */
3060 		/*  Country String(3) */
3061 		/*  + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */
3062 		/*  + number of channels in all classes */
3063 		len_channellist_attr = 3
3064 			+ (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
3065 			+ get_reg_classes_full_count(&pmlmeext->channel_list);
3066 
3067 		*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
3068 		p2pielen += 2;
3069 
3070 		/*	Value: */
3071 		/*	Country String */
3072 		p2pie[p2pielen++] = 'X';
3073 		p2pie[p2pielen++] = 'X';
3074 
3075 		/*	The third byte should be set to 0x04. */
3076 		/*	Described in the "Operating Channel Attribute" section. */
3077 		p2pie[p2pielen++] = 0x04;
3078 
3079 		/*	Channel Entry List */
3080 		{
3081 			int i, j;
3082 			for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3083 				/*	Operating Class */
3084 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3085 
3086 				/*	Number of Channels */
3087 				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3088 
3089 				/*	Channel List */
3090 				for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3091 					p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3092 				}
3093 			}
3094 		}
3095 	}
3096 
3097 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
3098 
3099 	pattrib->last_txcmdsz = pattrib->pktlen;
3100 
3101 	dump_mgntframe(padapter, pmgntframe);
3102 }
3103 
issue_p2p_provision_request(struct adapter * padapter,u8 * pssid,u8 ussidlen,u8 * pdev_raddr)3104 void issue_p2p_provision_request(struct adapter *padapter, u8 *pssid, u8 ussidlen, u8 *pdev_raddr)
3105 {
3106 	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3107 	u8 action = P2P_PUB_ACTION_ACTION;
3108 	u8 dialogToken = 1;
3109 	u8 oui_subtype = P2P_PROVISION_DISC_REQ;
3110 	u8 wpsie[100] = { 0x00 };
3111 	u8 wpsielen = 0;
3112 	__be32 p2poui = cpu_to_be32(P2POUI);
3113 	u32			p2pielen = 0;
3114 	struct xmit_frame			*pmgntframe;
3115 	struct pkt_attrib			*pattrib;
3116 	unsigned char					*pframe;
3117 	struct rtw_ieee80211_hdr	*pwlanhdr;
3118 	__le16 *fctrl;
3119 	struct xmit_priv			*pxmitpriv = &padapter->xmitpriv;
3120 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
3121 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
3122 
3123 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3124 	if (!pmgntframe)
3125 		return;
3126 
3127 	DBG_88E("[%s] In\n", __func__);
3128 	/* update attribute */
3129 	pattrib = &pmgntframe->attrib;
3130 	update_mgntframe_attrib(padapter, pattrib);
3131 
3132 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3133 
3134 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3135 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3136 
3137 	fctrl = &pwlanhdr->frame_ctl;
3138 	*(fctrl) = 0;
3139 
3140 	memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
3141 	memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
3142 	memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
3143 
3144 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3145 	pmlmeext->mgnt_seq++;
3146 	SetFrameSubType(pframe, WIFI_ACTION);
3147 
3148 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3149 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3150 
3151 	pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
3152 	pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
3153 	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
3154 	pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
3155 	pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
3156 
3157 	p2pielen = build_prov_disc_request_p2p_ie(pwdinfo, pframe, pssid, ussidlen, pdev_raddr);
3158 
3159 	pframe += p2pielen;
3160 	pattrib->pktlen += p2pielen;
3161 
3162 	wpsielen = 0;
3163 	/*	WPS OUI */
3164 	*(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
3165 	wpsielen += 4;
3166 
3167 	/*	WPS version */
3168 	/*	Type: */
3169 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
3170 	wpsielen += 2;
3171 
3172 	/*	Length: */
3173 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
3174 	wpsielen += 2;
3175 
3176 	/*	Value: */
3177 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
3178 
3179 	/*	Config Method */
3180 	/*	Type: */
3181 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
3182 	wpsielen += 2;
3183 
3184 	/*	Length: */
3185 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
3186 	wpsielen += 2;
3187 
3188 	/*	Value: */
3189 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
3190 	wpsielen += 2;
3191 
3192 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
3193 
3194 	pattrib->last_txcmdsz = pattrib->pktlen;
3195 
3196 	dump_mgntframe(padapter, pmgntframe);
3197 }
3198 
is_matched_in_profilelist(u8 * peermacaddr,struct profile_info * profileinfo)3199 static u8 is_matched_in_profilelist(u8 *peermacaddr, struct profile_info *profileinfo)
3200 {
3201 	u8 i, match_result = 0;
3202 
3203 	DBG_88E("[%s] peermac=%.2X %.2X %.2X %.2X %.2X %.2X\n", __func__,
3204 		peermacaddr[0], peermacaddr[1], peermacaddr[2], peermacaddr[3], peermacaddr[4], peermacaddr[5]);
3205 
3206 	for (i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++) {
3207 		DBG_88E("[%s] profileinfo_mac=%.2X %.2X %.2X %.2X %.2X %.2X\n", __func__,
3208 			profileinfo->peermac[0], profileinfo->peermac[1], profileinfo->peermac[2],
3209 			profileinfo->peermac[3], profileinfo->peermac[4], profileinfo->peermac[5]);
3210 		if (!memcmp(peermacaddr, profileinfo->peermac, ETH_ALEN)) {
3211 			match_result = 1;
3212 			DBG_88E("[%s] Match!\n", __func__);
3213 			break;
3214 		}
3215 	}
3216 	return match_result;
3217 }
3218 
issue_probersp_p2p(struct adapter * padapter,unsigned char * da)3219 void issue_probersp_p2p(struct adapter *padapter, unsigned char *da)
3220 {
3221 	struct xmit_frame			*pmgntframe;
3222 	struct pkt_attrib			*pattrib;
3223 	unsigned char					*pframe;
3224 	struct rtw_ieee80211_hdr	*pwlanhdr;
3225 	__le16 *fctrl;
3226 	unsigned char					*mac;
3227 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
3228 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
3229 	u16 beacon_interval = 100;
3230 	u16 capInfo = 0;
3231 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
3232 	u8 wpsie[255] = { 0x00 };
3233 	u32					wpsielen = 0, p2pielen = 0;
3234 
3235 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3236 	if (!pmgntframe)
3237 		return;
3238 
3239 	/* update attribute */
3240 	pattrib = &pmgntframe->attrib;
3241 	update_mgntframe_attrib(padapter, pattrib);
3242 
3243 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3244 
3245 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3246 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3247 
3248 	mac = myid(&padapter->eeprompriv);
3249 
3250 	fctrl = &pwlanhdr->frame_ctl;
3251 	*(fctrl) = 0;
3252 	memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3253 	memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
3254 
3255 	/*	Use the device address for BSSID field. */
3256 	memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
3257 
3258 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3259 	pmlmeext->mgnt_seq++;
3260 	SetFrameSubType(fctrl, WIFI_PROBERSP);
3261 
3262 	pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3263 	pattrib->pktlen = pattrib->hdrlen;
3264 	pframe += pattrib->hdrlen;
3265 
3266 	/* timestamp will be inserted by hardware */
3267 	pframe += 8;
3268 	pattrib->pktlen += 8;
3269 
3270 	/*  beacon interval: 2 bytes */
3271 	memcpy(pframe, (unsigned char *)&beacon_interval, 2);
3272 	pframe += 2;
3273 	pattrib->pktlen += 2;
3274 
3275 	/*	capability info: 2 bytes */
3276 	/*	ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
3277 	capInfo |= cap_ShortPremble;
3278 	capInfo |= cap_ShortSlot;
3279 
3280 	memcpy(pframe, (unsigned char *)&capInfo, 2);
3281 	pframe += 2;
3282 	pattrib->pktlen += 2;
3283 
3284 	/*  SSID */
3285 	pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
3286 
3287 	/*  supported rates... */
3288 	/*	Use the OFDM rate in the P2P probe response frame. (6(B), 9(B), 12, 18, 24, 36, 48, 54) */
3289 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
3290 
3291 	/*  DS parameter set */
3292 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
3293 
3294 	/*	Todo: WPS IE */
3295 	/*	Noted by Albert 20100907 */
3296 	/*	According to the WPS specification, all the WPS attribute is presented by Big Endian. */
3297 
3298 	wpsielen = 0;
3299 	/*	WPS OUI */
3300 	*(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
3301 	wpsielen += 4;
3302 
3303 	/*	WPS version */
3304 	/*	Type: */
3305 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
3306 	wpsielen += 2;
3307 
3308 	/*	Length: */
3309 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
3310 	wpsielen += 2;
3311 
3312 	/*	Value: */
3313 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
3314 
3315 	/*	WiFi Simple Config State */
3316 	/*	Type: */
3317 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
3318 	wpsielen += 2;
3319 
3320 	/*	Length: */
3321 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
3322 	wpsielen += 2;
3323 
3324 	/*	Value: */
3325 	wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;	/*	Not Configured. */
3326 
3327 	/*	Response Type */
3328 	/*	Type: */
3329 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
3330 	wpsielen += 2;
3331 
3332 	/*	Length: */
3333 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
3334 	wpsielen += 2;
3335 
3336 	/*	Value: */
3337 	wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
3338 
3339 	/*	UUID-E */
3340 	/*	Type: */
3341 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
3342 	wpsielen += 2;
3343 
3344 	/*	Length: */
3345 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
3346 	wpsielen += 2;
3347 
3348 	/*	Value: */
3349 	memcpy(wpsie + wpsielen, myid(&padapter->eeprompriv), ETH_ALEN);
3350 	wpsielen += 0x10;
3351 
3352 	/*	Manufacturer */
3353 	/*	Type: */
3354 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
3355 	wpsielen += 2;
3356 
3357 	/*	Length: */
3358 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
3359 	wpsielen += 2;
3360 
3361 	/*	Value: */
3362 	memcpy(wpsie + wpsielen, "Realtek", 7);
3363 	wpsielen += 7;
3364 
3365 	/*	Model Name */
3366 	/*	Type: */
3367 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
3368 	wpsielen += 2;
3369 
3370 	/*	Length: */
3371 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
3372 	wpsielen += 2;
3373 
3374 	/*	Value: */
3375 	memcpy(wpsie + wpsielen, "8188EU", 6);
3376 	wpsielen += 6;
3377 
3378 	/*	Model Number */
3379 	/*	Type: */
3380 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
3381 	wpsielen += 2;
3382 
3383 	/*	Length: */
3384 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
3385 	wpsielen += 2;
3386 
3387 	/*	Value: */
3388 	wpsie[wpsielen++] = 0x31;		/*	character 1 */
3389 
3390 	/*	Serial Number */
3391 	/*	Type: */
3392 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
3393 	wpsielen += 2;
3394 
3395 	/*	Length: */
3396 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
3397 	wpsielen += 2;
3398 
3399 	/*	Value: */
3400 	memcpy(wpsie + wpsielen, "123456", ETH_ALEN);
3401 	wpsielen += ETH_ALEN;
3402 
3403 	/*	Primary Device Type */
3404 	/*	Type: */
3405 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
3406 	wpsielen += 2;
3407 
3408 	/*	Length: */
3409 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
3410 	wpsielen += 2;
3411 
3412 	/*	Value: */
3413 	/*	Category ID */
3414 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
3415 	wpsielen += 2;
3416 
3417 	/*	OUI */
3418 	*(__be32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
3419 	wpsielen += 4;
3420 
3421 	/*	Sub Category ID */
3422 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
3423 	wpsielen += 2;
3424 
3425 	/*	Device Name */
3426 	/*	Type: */
3427 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
3428 	wpsielen += 2;
3429 
3430 	/*	Length: */
3431 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
3432 	wpsielen += 2;
3433 
3434 	/*	Value: */
3435 	if (pwdinfo->device_name_len) {
3436 		memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
3437 		wpsielen += pwdinfo->device_name_len;
3438 	}
3439 
3440 	/*	Config Method */
3441 	/*	Type: */
3442 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
3443 	wpsielen += 2;
3444 
3445 	/*	Length: */
3446 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
3447 	wpsielen += 2;
3448 
3449 	/*	Value: */
3450 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
3451 	wpsielen += 2;
3452 
3453 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
3454 
3455 	p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
3456 	pframe += p2pielen;
3457 	pattrib->pktlen += p2pielen;
3458 
3459 	pattrib->last_txcmdsz = pattrib->pktlen;
3460 
3461 	dump_mgntframe(padapter, pmgntframe);
3462 }
3463 
_issue_probereq_p2p(struct adapter * padapter,u8 * da,int wait_ack)3464 static int _issue_probereq_p2p(struct adapter *padapter, u8 *da, int wait_ack)
3465 {
3466 	int ret = _FAIL;
3467 	struct xmit_frame		*pmgntframe;
3468 	struct pkt_attrib		*pattrib;
3469 	unsigned char			*pframe;
3470 	struct rtw_ieee80211_hdr	*pwlanhdr;
3471 	__le16 *fctrl;
3472 	unsigned char			*mac;
3473 	struct xmit_priv		*pxmitpriv = &padapter->xmitpriv;
3474 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
3475 	u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3476 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
3477 	u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
3478 	u16 wpsielen = 0, p2pielen = 0;
3479 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3480 
3481 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3482 	if (!pmgntframe)
3483 		goto exit;
3484 
3485 	/* update attribute */
3486 	pattrib = &pmgntframe->attrib;
3487 	update_mgntframe_attrib(padapter, pattrib);
3488 
3489 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3490 
3491 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3492 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3493 
3494 	mac = myid(&padapter->eeprompriv);
3495 
3496 	fctrl = &pwlanhdr->frame_ctl;
3497 	*(fctrl) = 0;
3498 
3499 	if (da) {
3500 		memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3501 		memcpy(pwlanhdr->addr3, da, ETH_ALEN);
3502 	} else {
3503 		if ((pwdinfo->p2p_info.scan_op_ch_only) || (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
3504 			/*	This two flags will be set when this is only the P2P client mode. */
3505 			memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
3506 			memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
3507 		} else {
3508 			/*	broadcast probe request frame */
3509 			memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
3510 			memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
3511 		}
3512 	}
3513 	memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
3514 
3515 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3516 	pmlmeext->mgnt_seq++;
3517 	SetFrameSubType(pframe, WIFI_PROBEREQ);
3518 
3519 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3520 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3521 
3522 	if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
3523 		pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &pattrib->pktlen);
3524 	else
3525 		pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
3526 
3527 	/*	Use the OFDM rate in the P2P probe request frame. (6(B), 9(B), 12(B), 24(B), 36, 48, 54) */
3528 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
3529 
3530 	/*	WPS IE */
3531 	/*	Noted by Albert 20110221 */
3532 	/*	According to the WPS specification, all the WPS attribute is presented by Big Endian. */
3533 
3534 	wpsielen = 0;
3535 	/*	WPS OUI */
3536 	*(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
3537 	wpsielen += 4;
3538 
3539 	/*	WPS version */
3540 	/*	Type: */
3541 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
3542 	wpsielen += 2;
3543 
3544 	/*	Length: */
3545 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
3546 	wpsielen += 2;
3547 
3548 	/*	Value: */
3549 	wpsie[wpsielen++] = WPS_VERSION_1;	/*	Version 1.0 */
3550 
3551 	if (!pmlmepriv->wps_probe_req_ie) {
3552 		/*	UUID-E */
3553 		/*	Type: */
3554 		*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
3555 		wpsielen += 2;
3556 
3557 		/*	Length: */
3558 		*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
3559 		wpsielen += 2;
3560 
3561 		/*	Value: */
3562 		memcpy(wpsie + wpsielen, myid(&padapter->eeprompriv), ETH_ALEN);
3563 		wpsielen += 0x10;
3564 
3565 		/*	Config Method */
3566 		/*	Type: */
3567 		*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
3568 		wpsielen += 2;
3569 
3570 		/*	Length: */
3571 		*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
3572 		wpsielen += 2;
3573 
3574 		/*	Value: */
3575 		*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
3576 		wpsielen += 2;
3577 	}
3578 
3579 	/*	Device Name */
3580 	/*	Type: */
3581 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
3582 	wpsielen += 2;
3583 
3584 	/*	Length: */
3585 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
3586 	wpsielen += 2;
3587 
3588 	/*	Value: */
3589 	memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
3590 	wpsielen += pwdinfo->device_name_len;
3591 
3592 	/*	Primary Device Type */
3593 	/*	Type: */
3594 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
3595 	wpsielen += 2;
3596 
3597 	/*	Length: */
3598 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
3599 	wpsielen += 2;
3600 
3601 	/*	Value: */
3602 	/*	Category ID */
3603 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_RTK_WIDI);
3604 	wpsielen += 2;
3605 
3606 	/*	OUI */
3607 	*(__be32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
3608 	wpsielen += 4;
3609 
3610 	/*	Sub Category ID */
3611 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_RTK_DMP);
3612 	wpsielen += 2;
3613 
3614 	/*	Device Password ID */
3615 	/*	Type: */
3616 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
3617 	wpsielen += 2;
3618 
3619 	/*	Length: */
3620 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
3621 	wpsielen += 2;
3622 
3623 	/*	Value: */
3624 	*(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);	/*	Registrar-specified */
3625 	wpsielen += 2;
3626 
3627 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
3628 
3629 	/*	P2P OUI */
3630 	p2pielen = 0;
3631 	p2pie[p2pielen++] = 0x50;
3632 	p2pie[p2pielen++] = 0x6F;
3633 	p2pie[p2pielen++] = 0x9A;
3634 	p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
3635 
3636 	/*	Commented by Albert 20110221 */
3637 	/*	According to the P2P Specification, the probe request frame should contain 5 P2P attributes */
3638 	/*	1. P2P Capability */
3639 	/*	2. P2P Device ID if this probe request wants to find the specific P2P device */
3640 	/*	3. Listen Channel */
3641 	/*	4. Extended Listen Timing */
3642 	/*	5. Operating Channel if this WiFi is working as the group owner now */
3643 
3644 	/*	P2P Capability */
3645 	/*	Type: */
3646 	p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
3647 
3648 	/*	Length: */
3649 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
3650 	p2pielen += 2;
3651 
3652 	/*	Value: */
3653 	/*	Device Capability Bitmap, 1 byte */
3654 	p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
3655 
3656 	/*	Group Capability Bitmap, 1 byte */
3657 	if (pwdinfo->persistent_supported)
3658 		p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
3659 	else
3660 		p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
3661 
3662 	/*	Listen Channel */
3663 	/*	Type: */
3664 	p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
3665 
3666 	/*	Length: */
3667 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
3668 	p2pielen += 2;
3669 
3670 	/*	Value: */
3671 	/*	Country String */
3672 	p2pie[p2pielen++] = 'X';
3673 	p2pie[p2pielen++] = 'X';
3674 
3675 	/*	The third byte should be set to 0x04. */
3676 	/*	Described in the "Operating Channel Attribute" section. */
3677 	p2pie[p2pielen++] = 0x04;
3678 
3679 	/*	Operating Class */
3680 	p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
3681 
3682 	/*	Channel Number */
3683 	p2pie[p2pielen++] = pwdinfo->listen_channel;	/*	listen channel */
3684 
3685 	/*	Extended Listen Timing */
3686 	/*	Type: */
3687 	p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
3688 
3689 	/*	Length: */
3690 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
3691 	p2pielen += 2;
3692 
3693 	/*	Value: */
3694 	/*	Availability Period */
3695 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
3696 	p2pielen += 2;
3697 
3698 	/*	Availability Interval */
3699 	*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
3700 	p2pielen += 2;
3701 
3702 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
3703 		/*	Operating Channel (if this WiFi is working as the group owner now) */
3704 		/*	Type: */
3705 		p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
3706 
3707 		/*	Length: */
3708 		*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
3709 		p2pielen += 2;
3710 
3711 		/*	Value: */
3712 		/*	Country String */
3713 		p2pie[p2pielen++] = 'X';
3714 		p2pie[p2pielen++] = 'X';
3715 
3716 		/*	The third byte should be set to 0x04. */
3717 		/*	Described in the "Operating Channel Attribute" section. */
3718 		p2pie[p2pielen++] = 0x04;
3719 
3720 		/*	Operating Class */
3721 		p2pie[p2pielen++] = 0x51;	/*	Copy from SD7 */
3722 
3723 		/*	Channel Number */
3724 		p2pie[p2pielen++] = pwdinfo->operating_channel;	/*	operating channel number */
3725 	}
3726 
3727 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
3728 
3729 	if (pmlmepriv->wps_probe_req_ie) {
3730 		/* WPS IE */
3731 		memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
3732 		pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
3733 		pframe += pmlmepriv->wps_probe_req_ie_len;
3734 	}
3735 
3736 	pattrib->last_txcmdsz = pattrib->pktlen;
3737 
3738 	if (wait_ack) {
3739 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
3740 	} else {
3741 		dump_mgntframe(padapter, pmgntframe);
3742 		ret = _SUCCESS;
3743 	}
3744 
3745 exit:
3746 	return ret;
3747 }
3748 
issue_probereq_p2p(struct adapter * adapter,u8 * da)3749 inline void issue_probereq_p2p(struct adapter *adapter, u8 *da)
3750 {
3751 	_issue_probereq_p2p(adapter, da, false);
3752 }
3753 
issue_probereq_p2p_ex(struct adapter * adapter,u8 * da,int try_cnt,int wait_ms)3754 int issue_probereq_p2p_ex(struct adapter *adapter, u8 *da, int try_cnt, int wait_ms)
3755 {
3756 	int ret;
3757 	int i = 0;
3758 	u32 start = jiffies;
3759 
3760 	do {
3761 		ret = _issue_probereq_p2p(adapter, da, wait_ms > 0);
3762 
3763 		i++;
3764 
3765 		if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
3766 			break;
3767 
3768 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3769 			msleep(wait_ms);
3770 	} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3771 
3772 	if (ret != _FAIL) {
3773 		ret = _SUCCESS;
3774 		goto exit;
3775 	}
3776 
3777 	if (try_cnt && wait_ms) {
3778 		if (da)
3779 			DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n",
3780 				FUNC_ADPT_ARG(adapter), da, rtw_get_oper_ch(adapter),
3781 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
3782 		else
3783 			DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
3784 				FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
3785 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
3786 	}
3787 exit:
3788 	return ret;
3789 }
3790 
3791 #endif /* CONFIG_88EU_P2P */
3792 
rtw_action_public_decache(struct recv_frame * recv_frame,s32 token)3793 static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token)
3794 {
3795 	struct adapter *adapter = recv_frame->adapter;
3796 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
3797 	u8 *frame = recv_frame->rx_data;
3798 	u16 seq_ctrl = ((recv_frame->attrib.seq_num & 0xffff) << 4) |
3799 		(recv_frame->attrib.frag_num & 0xf);
3800 
3801 	if (GetRetry(frame)) {
3802 		if (token >= 0) {
3803 			if ((seq_ctrl == mlmeext->action_public_rxseq) && (token == mlmeext->action_public_dialog_token)) {
3804 				DBG_88E(FUNC_ADPT_FMT" seq_ctrl = 0x%x, rxseq = 0x%x, token:%d\n",
3805 					FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
3806 				return _FAIL;
3807 			}
3808 		} else {
3809 			if (seq_ctrl == mlmeext->action_public_rxseq) {
3810 				DBG_88E(FUNC_ADPT_FMT" seq_ctrl = 0x%x, rxseq = 0x%x\n",
3811 					FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq);
3812 				return _FAIL;
3813 			}
3814 		}
3815 	}
3816 
3817 	mlmeext->action_public_rxseq = seq_ctrl;
3818 
3819 	if (token >= 0)
3820 		mlmeext->action_public_dialog_token = token;
3821 
3822 	return _SUCCESS;
3823 }
3824 
on_action_public_p2p(struct recv_frame * precv_frame)3825 static unsigned int on_action_public_p2p(struct recv_frame *precv_frame)
3826 {
3827 	u8 *pframe = precv_frame->rx_data;
3828 	u8 *frame_body;
3829 	u8 dialogToken = 0;
3830 #ifdef CONFIG_88EU_P2P
3831 	struct adapter *padapter = precv_frame->adapter;
3832 	uint len = precv_frame->len;
3833 	u8 *p2p_ie;
3834 	u32	p2p_ielen;
3835 	struct	wifidirect_info	*pwdinfo = &padapter->wdinfo;
3836 	u8	result = P2P_STATUS_SUCCESS;
3837 	u8	empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3838 #endif /* CONFIG_88EU_P2P */
3839 
3840 	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3841 
3842 	dialogToken = frame_body[7];
3843 
3844 	if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
3845 		return _FAIL;
3846 
3847 #ifdef CONFIG_88EU_P2P
3848 	_cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
3849 	/*	Do nothing if the driver doesn't enable the P2P function. */
3850 	if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
3851 		return _SUCCESS;
3852 
3853 	len -= sizeof(struct rtw_ieee80211_hdr_3addr);
3854 
3855 	switch (frame_body[6]) { /* OUI Subtype */
3856 	case P2P_GO_NEGO_REQ:
3857 		DBG_88E("[%s] Got GO Nego Req Frame\n", __func__);
3858 		memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
3859 
3860 		if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
3861 			rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
3862 
3863 		if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) {
3864 			/*	Commented by Albert 20110526 */
3865 			/*	In this case, this means the previous nego fail doesn't be reset yet. */
3866 			_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
3867 			/*	Restore the previous p2p state */
3868 			rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
3869 			DBG_88E("[%s] Restore the previous p2p state to %d\n", __func__, rtw_p2p_state(pwdinfo));
3870 		}
3871 
3872 		/*	Commented by Kurt 20110902 */
3873 		/* Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
3874 		if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
3875 			rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
3876 
3877 		/*	Commented by Kurt 20120113 */
3878 		/*	Get peer_dev_addr here if peer doesn't issue prov_disc frame. */
3879 		if (!memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN))
3880 			memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
3881 
3882 		result = process_p2p_group_negotation_req(pwdinfo, frame_body, len);
3883 		issue_p2p_GO_response(padapter, GetAddr2Ptr(pframe), frame_body, len, result);
3884 
3885 		/*	Commented by Albert 20110718 */
3886 		/*	No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. */
3887 		_set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
3888 		break;
3889 	case P2P_GO_NEGO_RESP:
3890 		DBG_88E("[%s] Got GO Nego Resp Frame\n", __func__);
3891 
3892 		if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
3893 			/*	Commented by Albert 20110425 */
3894 			/*	The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. */
3895 			_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
3896 			pwdinfo->nego_req_info.benable = false;
3897 			result = process_p2p_group_negotation_resp(pwdinfo, frame_body, len);
3898 			issue_p2p_GO_confirm(pwdinfo->padapter, GetAddr2Ptr(pframe), result);
3899 			if (P2P_STATUS_SUCCESS == result) {
3900 				if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) {
3901 					pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch;
3902 					pwdinfo->p2p_info.scan_op_ch_only = 1;
3903 					_set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH);
3904 				}
3905 			}
3906 			/*	Reset the dialog token for group negotiation frames. */
3907 			pwdinfo->negotiation_dialog_token = 1;
3908 			if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
3909 				_set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
3910 		} else {
3911 			DBG_88E("[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __func__);
3912 		}
3913 		break;
3914 	case P2P_GO_NEGO_CONF:
3915 		DBG_88E("[%s] Got GO Nego Confirm Frame\n", __func__);
3916 		result = process_p2p_group_negotation_confirm(pwdinfo, frame_body, len);
3917 		if (P2P_STATUS_SUCCESS == result) {
3918 			if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) {
3919 				pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch;
3920 				pwdinfo->p2p_info.scan_op_ch_only = 1;
3921 				_set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH);
3922 			}
3923 		}
3924 		break;
3925 	case P2P_INVIT_REQ:
3926 		/*	Added by Albert 2010/10/05 */
3927 		/*	Received the P2P Invite Request frame. */
3928 
3929 		DBG_88E("[%s] Got invite request frame!\n", __func__);
3930 		p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
3931 		if (p2p_ie) {
3932 			/*	Parse the necessary information from the P2P Invitation Request frame. */
3933 			/*	For example: The MAC address of sending this P2P Invitation Request frame. */
3934 			u32	attr_contentlen = 0;
3935 			u8	status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
3936 			struct group_id_info group_id;
3937 			u8	invitation_flag = 0;
3938 
3939 			rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
3940 			if (attr_contentlen) {
3941 				rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
3942 				/*	Commented by Albert 20120510 */
3943 				/*	Copy to the pwdinfo->p2p_peer_interface_addr. */
3944 				/*	So that the WFD UI (or Sigma) can get the peer interface address by using the following command. */
3945 				/*	#> iwpriv wlan0 p2p_get peer_ifa */
3946 				/*	After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. */
3947 
3948 				if (attr_contentlen) {
3949 					DBG_88E("[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __func__,
3950 						pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
3951 						pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
3952 						pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
3953 				}
3954 
3955 				if (invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT) {
3956 					/*	Re-invoke the persistent group. */
3957 
3958 					memset(&group_id, 0x00, sizeof(struct group_id_info));
3959 					rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *)&group_id, &attr_contentlen);
3960 					if (attr_contentlen) {
3961 						if (!memcmp(group_id.go_device_addr, myid(&padapter->eeprompriv), ETH_ALEN)) {
3962 							/*	The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. */
3963 							rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO);
3964 							rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
3965 							status_code = P2P_STATUS_SUCCESS;
3966 						} else {
3967 							/*	The p2p device sending this p2p invitation request wants to be the persistent GO. */
3968 							if (is_matched_in_profilelist(pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[0])) {
3969 								u8 operatingch_info[5] = { 0x00 };
3970 								if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) {
3971 									if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4])) {
3972 										/*	The operating channel is acceptable for this device. */
3973 										pwdinfo->rx_invitereq_info.operation_ch[0] = operatingch_info[4];
3974 										pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
3975 										_set_timer(&pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH);
3976 										rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
3977 										rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
3978 										status_code = P2P_STATUS_SUCCESS;
3979 									} else {
3980 										/*	The operating channel isn't supported by this device. */
3981 										rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
3982 										rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
3983 										status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
3984 										_set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
3985 									}
3986 								} else {
3987 									/*	Commented by Albert 20121130 */
3988 									/*	Intel will use the different P2P IE to store the operating channel information */
3989 									/*	Workaround for Intel WiDi 3.5 */
3990 									rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
3991 									rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
3992 									status_code = P2P_STATUS_SUCCESS;
3993 								}
3994 							} else {
3995 								rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
3996 								status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
3997 							}
3998 						}
3999 					} else {
4000 						DBG_88E("[%s] P2P Group ID Attribute NOT FOUND!\n", __func__);
4001 						status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
4002 					}
4003 				} else {
4004 					/*	Received the invitation to join a P2P group. */
4005 
4006 					memset(&group_id, 0x00, sizeof(struct group_id_info));
4007 					rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *)&group_id, &attr_contentlen);
4008 					if (attr_contentlen) {
4009 						if (!memcmp(group_id.go_device_addr, myid(&padapter->eeprompriv), ETH_ALEN)) {
4010 							/*	In this case, the GO can't be myself. */
4011 							rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
4012 							status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
4013 						} else {
4014 							/*	The p2p device sending this p2p invitation request wants to join an existing P2P group */
4015 							/*	Commented by Albert 2012/06/28 */
4016 							/*	In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. */
4017 							/*	The peer device address should be the destination address for the provisioning discovery request. */
4018 							/*	Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. */
4019 							/*	The peer interface address should be the address for WPS mac address */
4020 							memcpy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr, ETH_ALEN);
4021 							rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
4022 							rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN);
4023 							status_code = P2P_STATUS_SUCCESS;
4024 						}
4025 					} else {
4026 						DBG_88E("[%s] P2P Group ID Attribute NOT FOUND!\n", __func__);
4027 						status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
4028 					}
4029 				}
4030 			} else {
4031 				DBG_88E("[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __func__);
4032 				status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
4033 			}
4034 
4035 			DBG_88E("[%s] status_code = %d\n", __func__, status_code);
4036 
4037 			pwdinfo->inviteresp_info.token = frame_body[7];
4038 			issue_p2p_invitation_response(padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code);
4039 		}
4040 		break;
4041 	case P2P_INVIT_RESP: {
4042 		u8	attr_content = 0x00;
4043 		u32	attr_contentlen = 0;
4044 
4045 		DBG_88E("[%s] Got invite response frame!\n", __func__);
4046 		_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
4047 		p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
4048 		if (p2p_ie) {
4049 			rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
4050 
4051 			if (attr_contentlen == 1) {
4052 				DBG_88E("[%s] Status = %d\n", __func__, attr_content);
4053 				pwdinfo->invitereq_info.benable = false;
4054 
4055 				if (attr_content == P2P_STATUS_SUCCESS) {
4056 					if (!memcmp(pwdinfo->invitereq_info.go_bssid, myid(&padapter->eeprompriv), ETH_ALEN)) {
4057 						rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
4058 					} else {
4059 						rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
4060 					}
4061 					rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_OK);
4062 				} else {
4063 					rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
4064 					rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
4065 				}
4066 			} else {
4067 				rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
4068 				rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
4069 			}
4070 		} else {
4071 			rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
4072 			rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
4073 		}
4074 
4075 		if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL))
4076 			_set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
4077 		break;
4078 	}
4079 	case P2P_DEVDISC_REQ:
4080 		process_p2p_devdisc_req(pwdinfo, pframe, len);
4081 		break;
4082 	case P2P_DEVDISC_RESP:
4083 		process_p2p_devdisc_resp(pwdinfo, pframe, len);
4084 		break;
4085 	case P2P_PROVISION_DISC_REQ:
4086 		DBG_88E("[%s] Got Provisioning Discovery Request Frame\n", __func__);
4087 		process_p2p_provdisc_req(pwdinfo, pframe, len);
4088 		memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
4089 
4090 		/* 20110902 Kurt */
4091 		/* Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
4092 		if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
4093 			rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4094 
4095 		rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
4096 		_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
4097 		break;
4098 	case P2P_PROVISION_DISC_RESP:
4099 		/*	Commented by Albert 20110707 */
4100 		/*	Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? */
4101 		DBG_88E("[%s] Got Provisioning Discovery Response Frame\n", __func__);
4102 		/*	Commented by Albert 20110426 */
4103 		/*	The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. */
4104 		_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
4105 		rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
4106 		process_p2p_provdisc_resp(pwdinfo, pframe);
4107 		_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
4108 		break;
4109 	}
4110 #endif /* CONFIG_88EU_P2P */
4111 
4112 	return _SUCCESS;
4113 }
4114 
on_action_public_vendor(struct recv_frame * precv_frame)4115 static unsigned int on_action_public_vendor(struct recv_frame *precv_frame)
4116 {
4117 	unsigned int ret = _FAIL;
4118 	u8 *pframe = precv_frame->rx_data;
4119 	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
4120 
4121 	if (!memcmp(frame_body + 2, P2P_OUI, 4)) {
4122 		ret = on_action_public_p2p(precv_frame);
4123 	}
4124 
4125 	return ret;
4126 }
4127 
on_action_public_default(struct recv_frame * precv_frame,u8 action)4128 static unsigned int on_action_public_default(struct recv_frame *precv_frame, u8 action)
4129 {
4130 	unsigned int ret = _FAIL;
4131 	u8 *pframe = precv_frame->rx_data;
4132 	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
4133 	u8 token;
4134 
4135 	token = frame_body[2];
4136 
4137 	if (rtw_action_public_decache(precv_frame, token) == _FAIL)
4138 		goto exit;
4139 
4140 	ret = _SUCCESS;
4141 
4142 exit:
4143 	return ret;
4144 }
4145 
on_action_public(struct adapter * padapter,struct recv_frame * precv_frame)4146 unsigned int on_action_public(struct adapter *padapter, struct recv_frame *precv_frame)
4147 {
4148 	unsigned int ret = _FAIL;
4149 	u8 *pframe = precv_frame->rx_data;
4150 	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
4151 	u8 category, action;
4152 
4153 	/* check RA matches or not */
4154 	if (memcmp(myid(&padapter->eeprompriv), GetAddr1Ptr(pframe), ETH_ALEN))
4155 		goto exit;
4156 
4157 	category = frame_body[0];
4158 	if (category != RTW_WLAN_CATEGORY_PUBLIC)
4159 		goto exit;
4160 
4161 	action = frame_body[1];
4162 	switch (action) {
4163 	case ACT_PUBLIC_VENDOR:
4164 		ret = on_action_public_vendor(precv_frame);
4165 		break;
4166 	default:
4167 		ret = on_action_public_default(precv_frame, action);
4168 		break;
4169 	}
4170 
4171 exit:
4172 	return ret;
4173 }
4174 
OnAction_ht(struct adapter * padapter,struct recv_frame * precv_frame)4175 unsigned int OnAction_ht(struct adapter *padapter, struct recv_frame *precv_frame)
4176 {
4177 	return _SUCCESS;
4178 }
4179 
OnAction_wmm(struct adapter * padapter,struct recv_frame * precv_frame)4180 unsigned int OnAction_wmm(struct adapter *padapter, struct recv_frame *precv_frame)
4181 {
4182 	return _SUCCESS;
4183 }
4184 
OnAction_p2p(struct adapter * padapter,struct recv_frame * precv_frame)4185 unsigned int OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame)
4186 {
4187 #ifdef CONFIG_88EU_P2P
4188 	u8 *frame_body;
4189 	u8 category, OUI_Subtype;
4190 	u8 *pframe = precv_frame->rx_data;
4191 	uint len = precv_frame->len;
4192 	struct	wifidirect_info	*pwdinfo = &padapter->wdinfo;
4193 
4194 	DBG_88E("%s\n", __func__);
4195 
4196 	/* check RA matches or not */
4197 	if (memcmp(myid(&padapter->eeprompriv), GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */
4198 		return _SUCCESS;
4199 
4200 	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
4201 
4202 	category = frame_body[0];
4203 	if (category != RTW_WLAN_CATEGORY_P2P)
4204 		return _SUCCESS;
4205 
4206 	if (be32_to_cpu(*((__be32 *)(frame_body + 1))) != P2POUI)
4207 		return _SUCCESS;
4208 
4209 	len -= sizeof(struct rtw_ieee80211_hdr_3addr);
4210 	OUI_Subtype = frame_body[5];
4211 
4212 	switch (OUI_Subtype) {
4213 	case P2P_NOTICE_OF_ABSENCE:
4214 		break;
4215 	case P2P_PRESENCE_REQUEST:
4216 		process_p2p_presence_req(pwdinfo, pframe, len);
4217 		break;
4218 	case P2P_PRESENCE_RESPONSE:
4219 		break;
4220 	case P2P_GO_DISC_REQUEST:
4221 		break;
4222 	default:
4223 		break;
4224 	}
4225 #endif /* CONFIG_88EU_P2P */
4226 	return _SUCCESS;
4227 }
4228 
OnAction(struct adapter * padapter,struct recv_frame * precv_frame)4229 unsigned int OnAction(struct adapter *padapter, struct recv_frame *precv_frame)
4230 {
4231 	int i;
4232 	unsigned char	category;
4233 	struct action_handler *ptable;
4234 	unsigned char	*frame_body;
4235 	u8 *pframe = precv_frame->rx_data;
4236 
4237 	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
4238 
4239 	category = frame_body[0];
4240 
4241 	for (i = 0; i < sizeof(OnAction_tbl) / sizeof(struct action_handler); i++) {
4242 		ptable = &OnAction_tbl[i];
4243 		if (category == ptable->num)
4244 			ptable->func(padapter, precv_frame);
4245 	}
4246 	return _SUCCESS;
4247 }
4248 
DoReserved(struct adapter * padapter,struct recv_frame * precv_frame)4249 unsigned int DoReserved(struct adapter *padapter, struct recv_frame *precv_frame)
4250 {
4251 	return _SUCCESS;
4252 }
4253 
alloc_mgtxmitframe(struct xmit_priv * pxmitpriv)4254 struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
4255 {
4256 	struct xmit_frame			*pmgntframe;
4257 	struct xmit_buf				*pxmitbuf;
4258 
4259 	pmgntframe = rtw_alloc_xmitframe(pxmitpriv);
4260 	if (!pmgntframe) {
4261 		DBG_88E("%s, alloc xmitframe fail\n", __func__);
4262 		return NULL;
4263 	}
4264 
4265 	pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv);
4266 	if (!pxmitbuf) {
4267 		DBG_88E("%s, alloc xmitbuf fail\n", __func__);
4268 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
4269 		return NULL;
4270 	}
4271 	pmgntframe->frame_tag = MGNT_FRAMETAG;
4272 	pmgntframe->pxmitbuf = pxmitbuf;
4273 	pmgntframe->buf_addr = pxmitbuf->pbuf;
4274 	pxmitbuf->priv_data = pmgntframe;
4275 	return pmgntframe;
4276 }
4277 
4278 /****************************************************************************
4279 
4280 Following are some TX fuctions for WiFi MLME
4281 
4282 *****************************************************************************/
4283 
update_mgnt_tx_rate(struct adapter * padapter,u8 rate)4284 void update_mgnt_tx_rate(struct adapter *padapter, u8 rate)
4285 {
4286 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
4287 
4288 	pmlmeext->tx_rate = rate;
4289 	DBG_88E("%s(): rate = %x\n", __func__, rate);
4290 }
4291 
update_mgntframe_attrib(struct adapter * padapter,struct pkt_attrib * pattrib)4292 void update_mgntframe_attrib(struct adapter *padapter, struct pkt_attrib *pattrib)
4293 {
4294 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
4295 
4296 	memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
4297 
4298 	pattrib->hdrlen = 24;
4299 	pattrib->nr_frags = 1;
4300 	pattrib->priority = 7;
4301 	pattrib->mac_id = 0;
4302 	pattrib->qsel = 0x12;
4303 
4304 	pattrib->pktlen = 0;
4305 
4306 	if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
4307 		pattrib->raid = 6;/* b mode */
4308 	else
4309 		pattrib->raid = 5;/* a/g mode */
4310 
4311 	pattrib->encrypt = _NO_PRIVACY_;
4312 	pattrib->bswenc = false;
4313 
4314 	pattrib->qos_en = false;
4315 	pattrib->ht_en = false;
4316 	pattrib->bwmode = HT_CHANNEL_WIDTH_20;
4317 	pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4318 	pattrib->sgi = false;
4319 
4320 	pattrib->seqnum = pmlmeext->mgnt_seq;
4321 
4322 	pattrib->retry_ctrl = true;
4323 }
4324 
dump_mgntframe(struct adapter * padapter,struct xmit_frame * pmgntframe)4325 void dump_mgntframe(struct adapter *padapter, struct xmit_frame *pmgntframe)
4326 {
4327 	if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
4328 		return;
4329 
4330 	rtw_hal_mgnt_xmit(padapter, pmgntframe);
4331 }
4332 
dump_mgntframe_and_wait(struct adapter * padapter,struct xmit_frame * pmgntframe,int timeout_ms)4333 s32 dump_mgntframe_and_wait(struct adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
4334 {
4335 	s32 ret = _FAIL;
4336 	struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
4337 	struct submit_ctx sctx;
4338 
4339 	if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
4340 		return ret;
4341 
4342 	rtw_sctx_init(&sctx, timeout_ms);
4343 	pxmitbuf->sctx = &sctx;
4344 
4345 	ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
4346 
4347 	if (ret == _SUCCESS)
4348 		ret = rtw_sctx_wait(&sctx);
4349 
4350 	return ret;
4351 }
4352 
dump_mgntframe_and_wait_ack(struct adapter * padapter,struct xmit_frame * pmgntframe)4353 s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmgntframe)
4354 {
4355 	s32 ret = _FAIL;
4356 	u32 timeout_ms = 500;/*   500ms */
4357 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
4358 
4359 	if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
4360 		return -1;
4361 
4362 	_enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
4363 	pxmitpriv->ack_tx = true;
4364 
4365 	pmgntframe->ack_report = 1;
4366 	if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
4367 		ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms);
4368 	}
4369 
4370 	pxmitpriv->ack_tx = false;
4371 	_exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
4372 
4373 	return ret;
4374 }
4375 
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)4376 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
4377 {
4378 	u8 *ssid_ie;
4379 	int ssid_len_ori;
4380 	int len_diff = 0;
4381 
4382 	ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
4383 
4384 	if (ssid_ie && ssid_len_ori > 0) {
4385 		switch (hidden_ssid_mode) {
4386 		case 1: {
4387 			u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
4388 			u32 remain_len = 0;
4389 
4390 			remain_len = ies_len - (next_ie - ies);
4391 
4392 			ssid_ie[1] = 0;
4393 			memcpy(ssid_ie + 2, next_ie, remain_len);
4394 			len_diff -= ssid_len_ori;
4395 
4396 			break;
4397 		}
4398 		case 2:
4399 			memset(&ssid_ie[2], 0, ssid_len_ori);
4400 			break;
4401 		default:
4402 			break;
4403 		}
4404 	}
4405 
4406 	return len_diff;
4407 }
4408 
issue_beacon(struct adapter * padapter,int timeout_ms)4409 void issue_beacon(struct adapter *padapter, int timeout_ms)
4410 {
4411 	struct xmit_frame	*pmgntframe;
4412 	struct pkt_attrib	*pattrib;
4413 	unsigned char	*pframe;
4414 	struct rtw_ieee80211_hdr *pwlanhdr;
4415 	__le16 *fctrl;
4416 	unsigned int	rate_len;
4417 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
4418 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4419 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
4420 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
4421 	struct wlan_bssid_ex		*cur_network = &pmlmeinfo->network;
4422 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4423 #ifdef CONFIG_88EU_P2P
4424 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
4425 #endif /* CONFIG_88EU_P2P */
4426 
4427 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4428 	if (!pmgntframe) {
4429 		DBG_88E("%s, alloc mgnt frame fail\n", __func__);
4430 		return;
4431 	}
4432 #if defined(CONFIG_88EU_AP_MODE)
4433 	spin_lock_bh(&pmlmepriv->bcn_update_lock);
4434 #endif /* if defined (CONFIG_88EU_AP_MODE) */
4435 
4436 	/* update attribute */
4437 	pattrib = &pmgntframe->attrib;
4438 	update_mgntframe_attrib(padapter, pattrib);
4439 	pattrib->qsel = 0x10;
4440 
4441 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4442 
4443 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4444 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4445 
4446 	fctrl = &pwlanhdr->frame_ctl;
4447 	*(fctrl) = 0;
4448 
4449 	memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
4450 	memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
4451 	memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
4452 
4453 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
4454 	/* pmlmeext->mgnt_seq++; */
4455 	SetFrameSubType(pframe, WIFI_BEACON);
4456 
4457 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4458 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4459 
4460 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
4461 #ifdef CONFIG_88EU_P2P
4462 		/*  for P2P : Primary Device Type & Device Name */
4463 		u32 wpsielen = 0, insert_len = 0;
4464 		u8 *wpsie = NULL;
4465 		wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
4466 
4467 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
4468 			uint wps_offset, remainder_ielen;
4469 			u8 *premainder_ie, *pframe_wscie;
4470 
4471 			wps_offset = (uint)(wpsie - cur_network->IEs);
4472 			premainder_ie = wpsie + wpsielen;
4473 			remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
4474 			pframe_wscie = pframe + wps_offset;
4475 			memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
4476 			pframe += (wps_offset + wpsielen);
4477 			pattrib->pktlen += (wps_offset + wpsielen);
4478 
4479 			/* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
4480 			/*	Primary Device Type */
4481 			/*	Type: */
4482 			*(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
4483 			insert_len += 2;
4484 
4485 			/*	Length: */
4486 			*(__be16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
4487 			insert_len += 2;
4488 
4489 			/*	Value: */
4490 			/*	Category ID */
4491 			*(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4492 			insert_len += 2;
4493 
4494 			/*	OUI */
4495 			*(__be32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
4496 			insert_len += 4;
4497 
4498 			/*	Sub Category ID */
4499 			*(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4500 			insert_len += 2;
4501 
4502 			/*	Device Name */
4503 			/*	Type: */
4504 			*(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4505 			insert_len += 2;
4506 
4507 			/*	Length: */
4508 			*(__be16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
4509 			insert_len += 2;
4510 
4511 			/*	Value: */
4512 			memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
4513 			insert_len += pwdinfo->device_name_len;
4514 
4515 			/* update wsc ie length */
4516 			*(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
4517 
4518 			/* pframe move to end */
4519 			pframe += insert_len;
4520 			pattrib->pktlen += insert_len;
4521 
4522 			/* copy remainder_ie to pframe */
4523 			memcpy(pframe, premainder_ie, remainder_ielen);
4524 			pframe += remainder_ielen;
4525 			pattrib->pktlen += remainder_ielen;
4526 		} else
4527 #endif /* CONFIG_88EU_P2P */
4528 		{
4529 			int len_diff;
4530 			memcpy(pframe, cur_network->IEs, cur_network->IELength);
4531 			len_diff = update_hidden_ssid(
4532 				pframe + _BEACON_IE_OFFSET_
4533 				, cur_network->IELength - _BEACON_IE_OFFSET_
4534 				, pmlmeinfo->hidden_ssid_mode
4535 			);
4536 			pframe += (cur_network->IELength + len_diff);
4537 			pattrib->pktlen += (cur_network->IELength + len_diff);
4538 		}
4539 
4540 		{
4541 			u8 *wps_ie;
4542 			uint wps_ielen;
4543 			u8 sr = 0;
4544 			wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
4545 				pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
4546 			if (wps_ie && wps_ielen > 0)
4547 				rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
4548 			if (sr != 0)
4549 				set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
4550 			else
4551 				_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
4552 		}
4553 
4554 #ifdef CONFIG_88EU_P2P
4555 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
4556 			u32 len;
4557 			len = build_beacon_p2p_ie(pwdinfo, pframe);
4558 
4559 			pframe += len;
4560 			pattrib->pktlen += len;
4561 		}
4562 #endif /* CONFIG_88EU_P2P */
4563 
4564 		goto _issue_bcn;
4565 	}
4566 
4567 	/* below for ad-hoc mode */
4568 
4569 	/* timestamp will be inserted by hardware */
4570 	pframe += 8;
4571 	pattrib->pktlen += 8;
4572 
4573 	/*  beacon interval: 2 bytes */
4574 
4575 	memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
4576 
4577 	pframe += 2;
4578 	pattrib->pktlen += 2;
4579 
4580 	/*  capability info: 2 bytes */
4581 
4582 	memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
4583 
4584 	pframe += 2;
4585 	pattrib->pktlen += 2;
4586 
4587 	/*  SSID */
4588 	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
4589 
4590 	/*  supported rates... */
4591 	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
4592 	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
4593 
4594 	/*  DS parameter set */
4595 	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&cur_network->Configuration.DSConfig, &pattrib->pktlen);
4596 
4597 	{
4598 		u8 erpinfo = 0;
4599 		u32 ATIMWindow;
4600 		/*  IBSS Parameter Set... */
4601 		ATIMWindow = 0;
4602 		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
4603 
4604 		/* ERP IE */
4605 		pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
4606 	}
4607 
4608 	/*  EXTERNDED SUPPORTED RATE */
4609 	if (rate_len > 8)
4610 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
4611 	/* todo:HT for adhoc */
4612 _issue_bcn:
4613 
4614 #if defined(CONFIG_88EU_AP_MODE)
4615 	pmlmepriv->update_bcn = false;
4616 
4617 	spin_unlock_bh(&pmlmepriv->bcn_update_lock);
4618 #endif /* if defined (CONFIG_88EU_AP_MODE) */
4619 
4620 	if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
4621 		DBG_88E("beacon frame too large\n");
4622 		return;
4623 	}
4624 
4625 	pattrib->last_txcmdsz = pattrib->pktlen;
4626 
4627 	/* DBG_88E("issue bcn_sz=%d\n", pattrib->last_txcmdsz); */
4628 	if (timeout_ms > 0)
4629 		dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
4630 	else
4631 		dump_mgntframe(padapter, pmgntframe);
4632 }
4633 
issue_probersp(struct adapter * padapter,unsigned char * da,u8 is_valid_p2p_probereq)4634 void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
4635 {
4636 	struct xmit_frame			*pmgntframe;
4637 	struct pkt_attrib			*pattrib;
4638 	unsigned char					*pframe;
4639 	struct rtw_ieee80211_hdr	*pwlanhdr;
4640 	__le16 *fctrl;
4641 	unsigned char					*mac, *bssid;
4642 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
4643 #if defined(CONFIG_88EU_AP_MODE)
4644 	u8 *pwps_ie;
4645 	uint wps_ielen;
4646 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4647 #endif /* if defined (CONFIG_88EU_AP_MODE) */
4648 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
4649 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
4650 	struct wlan_bssid_ex		*cur_network = &pmlmeinfo->network;
4651 	unsigned int	rate_len;
4652 #ifdef CONFIG_88EU_P2P
4653 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
4654 #endif /* CONFIG_88EU_P2P */
4655 
4656 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4657 	if (!pmgntframe) {
4658 		DBG_88E("%s, alloc mgnt frame fail\n", __func__);
4659 		return;
4660 	}
4661 
4662 	/* update attribute */
4663 	pattrib = &pmgntframe->attrib;
4664 	update_mgntframe_attrib(padapter, pattrib);
4665 
4666 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4667 
4668 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4669 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4670 
4671 	mac = myid(&padapter->eeprompriv);
4672 	bssid = cur_network->MacAddress;
4673 
4674 	fctrl = &pwlanhdr->frame_ctl;
4675 	*(fctrl) = 0;
4676 	memcpy(pwlanhdr->addr1, da, ETH_ALEN);
4677 	memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
4678 	memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
4679 
4680 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4681 	pmlmeext->mgnt_seq++;
4682 	SetFrameSubType(fctrl, WIFI_PROBERSP);
4683 
4684 	pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4685 	pattrib->pktlen = pattrib->hdrlen;
4686 	pframe += pattrib->hdrlen;
4687 
4688 	if (cur_network->IELength > MAX_IE_SZ)
4689 		return;
4690 
4691 #if defined(CONFIG_88EU_AP_MODE)
4692 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
4693 		pwps_ie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wps_ielen);
4694 
4695 		/* inerset & update wps_probe_resp_ie */
4696 		if (pmlmepriv->wps_probe_resp_ie && pwps_ie && wps_ielen > 0) {
4697 			uint wps_offset, remainder_ielen;
4698 			u8 *premainder_ie;
4699 
4700 			wps_offset = (uint)(pwps_ie - cur_network->IEs);
4701 
4702 			premainder_ie = pwps_ie + wps_ielen;
4703 
4704 			remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
4705 
4706 			memcpy(pframe, cur_network->IEs, wps_offset);
4707 			pframe += wps_offset;
4708 			pattrib->pktlen += wps_offset;
4709 
4710 			wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];/* to get ie data len */
4711 			if ((wps_offset + wps_ielen + 2) <= MAX_IE_SZ) {
4712 				memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen + 2);
4713 				pframe += wps_ielen + 2;
4714 				pattrib->pktlen += wps_ielen + 2;
4715 			}
4716 
4717 			if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) {
4718 				memcpy(pframe, premainder_ie, remainder_ielen);
4719 				pframe += remainder_ielen;
4720 				pattrib->pktlen += remainder_ielen;
4721 			}
4722 		} else {
4723 			memcpy(pframe, cur_network->IEs, cur_network->IELength);
4724 			pframe += cur_network->IELength;
4725 			pattrib->pktlen += cur_network->IELength;
4726 		}
4727 	} else
4728 #endif
4729 	{
4730 		/* timestamp will be inserted by hardware */
4731 		pframe += 8;
4732 		pattrib->pktlen += 8;
4733 
4734 		/*  beacon interval: 2 bytes */
4735 
4736 		memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
4737 
4738 		pframe += 2;
4739 		pattrib->pktlen += 2;
4740 
4741 		/*  capability info: 2 bytes */
4742 
4743 		memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
4744 
4745 		pframe += 2;
4746 		pattrib->pktlen += 2;
4747 
4748 		/* below for ad-hoc mode */
4749 
4750 		/*  SSID */
4751 		pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
4752 
4753 		/*  supported rates... */
4754 		rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
4755 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
4756 
4757 		/*  DS parameter set */
4758 		pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&cur_network->Configuration.DSConfig, &pattrib->pktlen);
4759 
4760 		if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
4761 			u8 erpinfo = 0;
4762 			u32 ATIMWindow;
4763 			/*  IBSS Parameter Set... */
4764 			/* ATIMWindow = cur->Configuration.ATIMWindow; */
4765 			ATIMWindow = 0;
4766 			pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
4767 
4768 			/* ERP IE */
4769 			pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
4770 		}
4771 
4772 		/*  EXTERNDED SUPPORTED RATE */
4773 		if (rate_len > 8)
4774 			pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
4775 		/* todo:HT for adhoc */
4776 	}
4777 
4778 #ifdef CONFIG_88EU_P2P
4779 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && is_valid_p2p_probereq) {
4780 		u32 len;
4781 		len = build_probe_resp_p2p_ie(pwdinfo, pframe);
4782 
4783 		pframe += len;
4784 		pattrib->pktlen += len;
4785 	}
4786 #endif /* CONFIG_88EU_P2P */
4787 
4788 	pattrib->last_txcmdsz = pattrib->pktlen;
4789 
4790 	dump_mgntframe(padapter, pmgntframe);
4791 }
4792 
_issue_probereq(struct adapter * padapter,struct ndis_802_11_ssid * pssid,u8 * da,int wait_ack)4793 static int _issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, int wait_ack)
4794 {
4795 	int ret = _FAIL;
4796 	struct xmit_frame		*pmgntframe;
4797 	struct pkt_attrib		*pattrib;
4798 	unsigned char			*pframe;
4799 	struct rtw_ieee80211_hdr	*pwlanhdr;
4800 	__le16 *fctrl;
4801 	unsigned char			*mac;
4802 	unsigned char			bssrate[NumRates];
4803 	struct xmit_priv		*pxmitpriv = &padapter->xmitpriv;
4804 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4805 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
4806 	int	bssrate_len = 0;
4807 	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4808 
4809 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4810 	if (!pmgntframe)
4811 		goto exit;
4812 
4813 	/* update attribute */
4814 	pattrib = &pmgntframe->attrib;
4815 	update_mgntframe_attrib(padapter, pattrib);
4816 
4817 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4818 
4819 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4820 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4821 
4822 	mac = myid(&padapter->eeprompriv);
4823 
4824 	fctrl = &pwlanhdr->frame_ctl;
4825 	*(fctrl) = 0;
4826 
4827 	if (da) {
4828 		/*	unicast probe request frame */
4829 		memcpy(pwlanhdr->addr1, da, ETH_ALEN);
4830 		memcpy(pwlanhdr->addr3, da, ETH_ALEN);
4831 	} else {
4832 		/*	broadcast probe request frame */
4833 		memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
4834 		memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
4835 	}
4836 
4837 	memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
4838 
4839 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4840 	pmlmeext->mgnt_seq++;
4841 	SetFrameSubType(pframe, WIFI_PROBEREQ);
4842 
4843 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4844 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4845 
4846 	if (pssid)
4847 		pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &pattrib->pktlen);
4848 	else
4849 		pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pattrib->pktlen);
4850 
4851 	get_rate_set(padapter, bssrate, &bssrate_len);
4852 
4853 	if (bssrate_len > 8) {
4854 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &pattrib->pktlen);
4855 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, bssrate_len - 8, bssrate + 8, &pattrib->pktlen);
4856 	} else {
4857 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &pattrib->pktlen);
4858 	}
4859 
4860 	/* add wps_ie for wps2.0 */
4861 	if (pmlmepriv->wps_probe_req_ie_len > 0 && pmlmepriv->wps_probe_req_ie) {
4862 		memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
4863 		pframe += pmlmepriv->wps_probe_req_ie_len;
4864 		pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
4865 	}
4866 
4867 	pattrib->last_txcmdsz = pattrib->pktlen;
4868 
4869 	if (wait_ack) {
4870 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
4871 	} else {
4872 		dump_mgntframe(padapter, pmgntframe);
4873 		ret = _SUCCESS;
4874 	}
4875 
4876 exit:
4877 	return ret;
4878 }
4879 
issue_probereq(struct adapter * padapter,struct ndis_802_11_ssid * pssid,u8 * da)4880 inline void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da)
4881 {
4882 	_issue_probereq(padapter, pssid, da, false);
4883 }
4884 
issue_probereq_ex(struct adapter * padapter,struct ndis_802_11_ssid * pssid,u8 * da,int try_cnt,int wait_ms)4885 int issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da,
4886 	int try_cnt, int wait_ms)
4887 {
4888 	int ret;
4889 	int i = 0;
4890 	u32 start = jiffies;
4891 
4892 	do {
4893 		ret = _issue_probereq(padapter, pssid, da, wait_ms > 0);
4894 
4895 		i++;
4896 
4897 		if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
4898 			break;
4899 
4900 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
4901 			msleep(wait_ms);
4902 
4903 	} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
4904 
4905 	if (ret != _FAIL) {
4906 		ret = _SUCCESS;
4907 		goto exit;
4908 	}
4909 
4910 	if (try_cnt && wait_ms) {
4911 		if (da)
4912 			DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n",
4913 				FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter),
4914 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
4915 		else
4916 			DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
4917 				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
4918 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
4919 	}
4920 exit:
4921 	return ret;
4922 }
4923 
4924 /*  if psta == NULL, indiate we are station(client) now... */
issue_auth(struct adapter * padapter,struct sta_info * psta,unsigned short status)4925 void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short status)
4926 {
4927 	struct xmit_frame *pmgntframe;
4928 	struct pkt_attrib *pattrib;
4929 	unsigned char *pframe;
4930 	struct rtw_ieee80211_hdr *pwlanhdr;
4931 	__le16 *fctrl;
4932 	unsigned int val32;
4933 	u16 val16;
4934 #ifdef CONFIG_88EU_AP_MODE
4935 	__le16 le_val16;
4936 #endif
4937 	int use_shared_key = 0;
4938 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4939 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
4940 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
4941 
4942 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4943 	if (!pmgntframe)
4944 		return;
4945 
4946 	/* update attribute */
4947 	pattrib = &pmgntframe->attrib;
4948 	update_mgntframe_attrib(padapter, pattrib);
4949 
4950 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4951 
4952 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4953 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4954 
4955 	fctrl = &pwlanhdr->frame_ctl;
4956 	*(fctrl) = 0;
4957 
4958 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4959 	pmlmeext->mgnt_seq++;
4960 	SetFrameSubType(pframe, WIFI_AUTH);
4961 
4962 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4963 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4964 
4965 	if (psta) {/*  for AP mode */
4966 #ifdef CONFIG_88EU_AP_MODE
4967 
4968 		memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
4969 		memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
4970 		memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
4971 
4972 		/*  setting auth algo number */
4973 		val16 = (u16)psta->authalg;
4974 
4975 		if (status != _STATS_SUCCESSFUL_)
4976 			val16 = 0;
4977 
4978 		if (val16) {
4979 			le_val16 = cpu_to_le16(val16);
4980 			use_shared_key = 1;
4981 		} else {
4982 			le_val16 = 0;
4983 		}
4984 
4985 		pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_val16, &pattrib->pktlen);
4986 
4987 		/*  setting auth seq number */
4988 		val16 = (u16)psta->auth_seq;
4989 		le_val16 = cpu_to_le16(val16);
4990 		pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_val16, &pattrib->pktlen);
4991 
4992 		/*  setting status code... */
4993 		val16 = status;
4994 		le_val16 = cpu_to_le16(val16);
4995 		pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_val16, &pattrib->pktlen);
4996 
4997 		/*  added challenging text... */
4998 		if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
4999 			pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &pattrib->pktlen);
5000 #endif
5001 	} else {
5002 		__le32 le_tmp32;
5003 		__le16 le_tmp16;
5004 		memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
5005 		memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
5006 		memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
5007 
5008 		/*  setting auth algo number */
5009 		val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;/*  0:OPEN System, 1:Shared key */
5010 		if (val16)
5011 			use_shared_key = 1;
5012 
5013 		/* setting IV for auth seq #3 */
5014 		if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
5015 			val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
5016 			le_tmp32 = cpu_to_le32(val32);
5017 			pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&le_tmp32, &pattrib->pktlen);
5018 
5019 			pattrib->iv_len = 4;
5020 		}
5021 
5022 		le_tmp16 = cpu_to_le16(val16);
5023 		pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_tmp16, &pattrib->pktlen);
5024 
5025 		/*  setting auth seq number */
5026 		val16 = pmlmeinfo->auth_seq;
5027 		le_tmp16 = cpu_to_le16(val16);
5028 		pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_tmp16, &pattrib->pktlen);
5029 
5030 		/*  setting status code... */
5031 		le_tmp16 = cpu_to_le16(status);
5032 		pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_tmp16, &pattrib->pktlen);
5033 
5034 		/*  then checking to see if sending challenging text... */
5035 		if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
5036 			pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &pattrib->pktlen);
5037 
5038 			SetPrivacy(fctrl);
5039 
5040 			pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5041 
5042 			pattrib->encrypt = _WEP40_;
5043 
5044 			pattrib->icv_len = 4;
5045 
5046 			pattrib->pktlen += pattrib->icv_len;
5047 		}
5048 	}
5049 
5050 	pattrib->last_txcmdsz = pattrib->pktlen;
5051 
5052 	rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
5053 	DBG_88E("%s\n", __func__);
5054 	dump_mgntframe(padapter, pmgntframe);
5055 }
5056 
issue_asocrsp(struct adapter * padapter,unsigned short status,struct sta_info * pstat,int pkt_type)5057 void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
5058 {
5059 #ifdef CONFIG_88EU_AP_MODE
5060 	struct xmit_frame	*pmgntframe;
5061 	struct rtw_ieee80211_hdr	*pwlanhdr;
5062 	struct pkt_attrib *pattrib;
5063 	unsigned char	*pbuf, *pframe;
5064 	unsigned short val;
5065 	__le16 *fctrl;
5066 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5067 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5068 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5069 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
5070 	struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5071 	u8 *ie = pnetwork->IEs;
5072 	__le16 lestatus, leval;
5073 #ifdef CONFIG_88EU_P2P
5074 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
5075 #endif /* CONFIG_88EU_P2P */
5076 
5077 	DBG_88E("%s\n", __func__);
5078 
5079 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5080 	if (!pmgntframe)
5081 		return;
5082 
5083 	/* update attribute */
5084 	pattrib = &pmgntframe->attrib;
5085 	update_mgntframe_attrib(padapter, pattrib);
5086 
5087 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5088 
5089 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5090 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5091 
5092 	fctrl = &pwlanhdr->frame_ctl;
5093 	*(fctrl) = 0;
5094 
5095 	memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
5096 	memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&padapter->eeprompriv), ETH_ALEN);
5097 	memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
5098 
5099 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5100 	pmlmeext->mgnt_seq++;
5101 	if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
5102 		SetFrameSubType(pwlanhdr, pkt_type);
5103 	else
5104 		return;
5105 
5106 	pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5107 	pattrib->pktlen += pattrib->hdrlen;
5108 	pframe += pattrib->hdrlen;
5109 
5110 	/* capability */
5111 	val = *(unsigned short *)rtw_get_capability_from_ie(ie);
5112 
5113 	pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_, (unsigned char *)&val, &pattrib->pktlen);
5114 
5115 	lestatus = cpu_to_le16(status);
5116 	pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&lestatus, &pattrib->pktlen);
5117 
5118 	leval = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
5119 	pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_, (unsigned char *)&leval, &pattrib->pktlen);
5120 
5121 	if (pstat->bssratelen <= 8) {
5122 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &pattrib->pktlen);
5123 	} else {
5124 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &pattrib->pktlen);
5125 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, pstat->bssratelen - 8, pstat->bssrateset + 8, &pattrib->pktlen);
5126 	}
5127 
5128 	if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) {
5129 		uint ie_len = 0;
5130 
5131 		/* FILL HT CAP INFO IE */
5132 		pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
5133 		if (pbuf && ie_len > 0) {
5134 			memcpy(pframe, pbuf, ie_len + 2);
5135 			pframe += (ie_len + 2);
5136 			pattrib->pktlen += (ie_len + 2);
5137 		}
5138 
5139 		/* FILL HT ADD INFO IE */
5140 		pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
5141 		if (pbuf && ie_len > 0) {
5142 			memcpy(pframe, pbuf, ie_len + 2);
5143 			pframe += (ie_len + 2);
5144 			pattrib->pktlen += (ie_len + 2);
5145 		}
5146 	}
5147 
5148 	/* FILL WMM IE */
5149 	if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) {
5150 		uint ie_len = 0;
5151 		unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
5152 
5153 		for (pbuf = ie + _BEACON_IE_OFFSET_;; pbuf += (ie_len + 2)) {
5154 			pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
5155 			if (pbuf && !memcmp(pbuf + 2, WMM_PARA_IE, 6)) {
5156 				memcpy(pframe, pbuf, ie_len + 2);
5157 				pframe += (ie_len + 2);
5158 				pattrib->pktlen += (ie_len + 2);
5159 				break;
5160 			}
5161 
5162 			if (!pbuf || ie_len == 0)
5163 				break;
5164 		}
5165 	}
5166 
5167 	if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
5168 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &pattrib->pktlen);
5169 
5170 	/* add WPS IE ie for wps 2.0 */
5171 	if (pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len > 0) {
5172 		memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
5173 
5174 		pframe += pmlmepriv->wps_assoc_resp_ie_len;
5175 		pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
5176 	}
5177 
5178 #ifdef CONFIG_88EU_P2P
5179 	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device)) {
5180 		u32 len;
5181 
5182 		len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
5183 
5184 		pframe += len;
5185 		pattrib->pktlen += len;
5186 	}
5187 #endif /* CONFIG_88EU_P2P */
5188 	pattrib->last_txcmdsz = pattrib->pktlen;
5189 	dump_mgntframe(padapter, pmgntframe);
5190 #endif
5191 }
5192 
issue_assocreq(struct adapter * padapter)5193 void issue_assocreq(struct adapter *padapter)
5194 {
5195 	int ret = _FAIL;
5196 	struct xmit_frame	*pmgntframe;
5197 	struct pkt_attrib	*pattrib;
5198 	unsigned char		*pframe, *p;
5199 	struct rtw_ieee80211_hdr	*pwlanhdr;
5200 	__le16 *fctrl;
5201 	__le16		le_tmp;
5202 	unsigned int	i, j, ie_len, index = 0;
5203 	unsigned char	rf_type, bssrate[NumRates], sta_bssrate[NumRates];
5204 	struct ndis_802_11_var_ie *pIE;
5205 	struct registry_priv	*pregpriv = &padapter->registrypriv;
5206 	struct xmit_priv		*pxmitpriv = &padapter->xmitpriv;
5207 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5208 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
5209 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
5210 	int	bssrate_len = 0, sta_bssrate_len = 0;
5211 #ifdef CONFIG_88EU_P2P
5212 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
5213 	u8 p2pie[255] = { 0x00 };
5214 	u16 p2pielen = 0;
5215 #endif /* CONFIG_88EU_P2P */
5216 
5217 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5218 	if (!pmgntframe)
5219 		goto exit;
5220 
5221 	/* update attribute */
5222 	pattrib = &pmgntframe->attrib;
5223 	update_mgntframe_attrib(padapter, pattrib);
5224 
5225 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5226 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5227 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5228 
5229 	fctrl = &pwlanhdr->frame_ctl;
5230 	*(fctrl) = 0;
5231 	memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
5232 	memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
5233 	memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
5234 
5235 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5236 	pmlmeext->mgnt_seq++;
5237 	SetFrameSubType(pframe, WIFI_ASSOCREQ);
5238 
5239 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5240 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5241 
5242 	/* caps */
5243 
5244 	memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
5245 
5246 	pframe += 2;
5247 	pattrib->pktlen += 2;
5248 
5249 	/* listen interval */
5250 	/* todo: listen interval for power saving */
5251 	le_tmp = cpu_to_le16(3);
5252 	memcpy(pframe, (unsigned char *)&le_tmp, 2);
5253 	pframe += 2;
5254 	pattrib->pktlen += 2;
5255 
5256 	/* SSID */
5257 	pframe = rtw_set_ie(pframe, _SSID_IE_,  pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &pattrib->pktlen);
5258 
5259 	/* supported rate & extended supported rate */
5260 
5261 	/*  Check if the AP's supported rates are also supported by STA. */
5262 	get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
5263 
5264 	if (pmlmeext->cur_channel == 14)/*  for JAPAN, channel 14 can only uses B Mode(CCK) */
5265 		sta_bssrate_len = 4;
5266 
5267 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
5268 		if (pmlmeinfo->network.SupportedRates[i] == 0)
5269 			break;
5270 		DBG_88E("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
5271 	}
5272 
5273 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
5274 		if (pmlmeinfo->network.SupportedRates[i] == 0)
5275 			break;
5276 
5277 		/*  Check if the AP's supported rates are also supported by STA. */
5278 		for (j = 0; j < sta_bssrate_len; j++) {
5279 			 /*  Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
5280 			if ((pmlmeinfo->network.SupportedRates[i] | IEEE80211_BASIC_RATE_MASK)
5281 					== (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK))
5282 				break;
5283 		}
5284 
5285 		if (j == sta_bssrate_len) {
5286 			/*  the rate is not supported by STA */
5287 			DBG_88E("%s(): the rate[%d]=%02X is not supported by STA!\n", __func__, i, pmlmeinfo->network.SupportedRates[i]);
5288 		} else {
5289 			/*  the rate is supported by STA */
5290 			bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
5291 		}
5292 	}
5293 
5294 	bssrate_len = index;
5295 	DBG_88E("bssrate_len=%d\n", bssrate_len);
5296 
5297 	if (bssrate_len == 0) {
5298 		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
5299 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
5300 		goto exit; /* don't connect to AP if no joint supported rate */
5301 	}
5302 
5303 	if (bssrate_len > 8) {
5304 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &pattrib->pktlen);
5305 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, bssrate_len - 8, bssrate + 8, &pattrib->pktlen);
5306 	} else {
5307 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &pattrib->pktlen);
5308 	}
5309 
5310 	/* RSN */
5311 	p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(struct ndis_802_11_fixed_ie)), _RSN_IE_2_, &ie_len, (pmlmeinfo->network.IELength - sizeof(struct ndis_802_11_fixed_ie)));
5312 	if (p)
5313 		pframe = rtw_set_ie(pframe, _RSN_IE_2_, ie_len, p + 2, &pattrib->pktlen);
5314 
5315 	/* HT caps */
5316 	if (padapter->mlmepriv.htpriv.ht_option) {
5317 		p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(struct ndis_802_11_fixed_ie)), _HT_CAPABILITY_IE_, &ie_len, (pmlmeinfo->network.IELength - sizeof(struct ndis_802_11_fixed_ie)));
5318 		if (p && !is_ap_in_tkip(padapter)) {
5319 			memcpy(&pmlmeinfo->HT_caps, p + 2, sizeof(struct HT_caps_element));
5320 
5321 			/* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
5322 			if (pregpriv->cbw40_enable == 0)
5323 				pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= cpu_to_le16(~(BIT(6) | BIT(1)));
5324 			else
5325 				pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(BIT(1));
5326 
5327 			/* todo: disable SM power save mode */
5328 			pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x000c);
5329 
5330 			rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
5331 			switch (rf_type) {
5332 			case RF_1T1R:
5333 				if (pregpriv->rx_stbc)
5334 					pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);/* RX STBC One spatial stream */
5335 				memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16);
5336 				break;
5337 			case RF_2T2R:
5338 			case RF_1T2R:
5339 			default:
5340 				if ((pregpriv->rx_stbc == 0x3) ||/* enable for 2.4/5 GHz */
5341 				    ((pmlmeext->cur_wireless_mode & WIRELESS_11_24N) && (pregpriv->rx_stbc == 0x1)) || /* enable for 2.4GHz */
5342 				    (pregpriv->wifi_spec == 1)) {
5343 					DBG_88E("declare supporting RX STBC\n");
5344 					pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);/* RX STBC two spatial stream */
5345 				}
5346 				memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16);
5347 				break;
5348 			}
5349 			pframe = rtw_set_ie(pframe, _HT_CAPABILITY_IE_, ie_len, (u8 *)(&pmlmeinfo->HT_caps), &pattrib->pktlen);
5350 		}
5351 	}
5352 
5353 	/* vendor specific IE, such as WPA, WMM, WPS */
5354 	for (i = sizeof(struct ndis_802_11_fixed_ie); i < pmlmeinfo->network.IELength;) {
5355 		pIE = (struct ndis_802_11_var_ie *)(pmlmeinfo->network.IEs + i);
5356 
5357 		switch (pIE->ElementID) {
5358 		case _VENDOR_SPECIFIC_IE_:
5359 			if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
5360 			    (!memcmp(pIE->data, WMM_OUI, 4)) ||
5361 			    (!memcmp(pIE->data, WPS_OUI, 4))) {
5362 				if (!padapter->registrypriv.wifi_spec) {
5363 					/* Commented by Kurt 20110629 */
5364 					/* In some older APs, WPS handshake */
5365 					/* would be fail if we append vender extensions informations to AP */
5366 					if (!memcmp(pIE->data, WPS_OUI, 4))
5367 						pIE->Length = 14;
5368 				}
5369 				pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, pIE->Length, pIE->data, &pattrib->pktlen);
5370 			}
5371 			break;
5372 		default:
5373 			break;
5374 		}
5375 		i += (pIE->Length + 2);
5376 	}
5377 
5378 	if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
5379 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &pattrib->pktlen);
5380 
5381 #ifdef CONFIG_88EU_P2P
5382 
5383 	if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
5384 		/*	Should add the P2P IE in the association request frame. */
5385 		/*	P2P OUI */
5386 
5387 		p2pielen = 0;
5388 		p2pie[p2pielen++] = 0x50;
5389 		p2pie[p2pielen++] = 0x6F;
5390 		p2pie[p2pielen++] = 0x9A;
5391 		p2pie[p2pielen++] = 0x09;	/*	WFA P2P v1.0 */
5392 
5393 		/*	Commented by Albert 20101109 */
5394 		/*	According to the P2P Specification, the association request frame should contain 3 P2P attributes */
5395 		/*	1. P2P Capability */
5396 		/*	2. Extended Listen Timing */
5397 		/*	3. Device Info */
5398 		/*	Commented by Albert 20110516 */
5399 		/*	4. P2P Interface */
5400 
5401 		/*	P2P Capability */
5402 		/*	Type: */
5403 		p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
5404 
5405 		/*	Length: */
5406 		*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5407 		p2pielen += 2;
5408 
5409 		/*	Value: */
5410 		/*	Device Capability Bitmap, 1 byte */
5411 		p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
5412 
5413 		/*	Group Capability Bitmap, 1 byte */
5414 		if (pwdinfo->persistent_supported)
5415 			p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
5416 		else
5417 			p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
5418 
5419 		/*	Extended Listen Timing */
5420 		/*	Type: */
5421 		p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
5422 
5423 		/*	Length: */
5424 		*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
5425 		p2pielen += 2;
5426 
5427 		/*	Value: */
5428 		/*	Availability Period */
5429 		*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
5430 		p2pielen += 2;
5431 
5432 		/*	Availability Interval */
5433 		*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
5434 		p2pielen += 2;
5435 
5436 		/*	Device Info */
5437 		/*	Type: */
5438 		p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
5439 
5440 		/*	Length: */
5441 		/*	21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
5442 		/*	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
5443 		*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
5444 		p2pielen += 2;
5445 
5446 		/*	Value: */
5447 		/*	P2P Device Address */
5448 		memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
5449 		p2pielen += ETH_ALEN;
5450 
5451 		/*	Config Method */
5452 		/*	This field should be big endian. Noted by P2P specification. */
5453 		if ((pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN) ||
5454 		    (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN))
5455 			*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
5456 		else
5457 			*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC);
5458 
5459 		p2pielen += 2;
5460 
5461 		/*	Primary Device Type */
5462 		/*	Category ID */
5463 		*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5464 		p2pielen += 2;
5465 
5466 		/*	OUI */
5467 		*(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
5468 		p2pielen += 4;
5469 
5470 		/*	Sub Category ID */
5471 		*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5472 		p2pielen += 2;
5473 
5474 		/*	Number of Secondary Device Types */
5475 		p2pie[p2pielen++] = 0x00;	/*	No Secondary Device Type List */
5476 
5477 		/*	Device Name */
5478 		/*	Type: */
5479 		*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5480 		p2pielen += 2;
5481 
5482 		/*	Length: */
5483 		*(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
5484 		p2pielen += 2;
5485 
5486 		/*	Value: */
5487 		memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
5488 		p2pielen += pwdinfo->device_name_len;
5489 
5490 		/*	P2P Interface */
5491 		/*	Type: */
5492 		p2pie[p2pielen++] = P2P_ATTR_INTERFACE;
5493 
5494 		/*	Length: */
5495 		*(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x000D);
5496 		p2pielen += 2;
5497 
5498 		/*	Value: */
5499 		memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);	/*	P2P Device Address */
5500 		p2pielen += ETH_ALEN;
5501 
5502 		p2pie[p2pielen++] = 1;	/*	P2P Interface Address Count */
5503 
5504 		memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);	/*	P2P Interface Address List */
5505 		p2pielen += ETH_ALEN;
5506 
5507 		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
5508 	}
5509 
5510 #endif /* CONFIG_88EU_P2P */
5511 
5512 	pattrib->last_txcmdsz = pattrib->pktlen;
5513 	dump_mgntframe(padapter, pmgntframe);
5514 
5515 	ret = _SUCCESS;
5516 
5517 exit:
5518 	if (ret == _SUCCESS)
5519 		rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
5520 	else
5521 		kfree(pmlmepriv->assoc_req);
5522 }
5523 
5524 /* when wait_ack is ture, this function shoule be called at process context */
_issue_nulldata(struct adapter * padapter,unsigned char * da,unsigned int power_mode,int wait_ack)5525 static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
5526 {
5527 	int ret = _FAIL;
5528 	struct xmit_frame			*pmgntframe;
5529 	struct pkt_attrib			*pattrib;
5530 	unsigned char					*pframe;
5531 	struct rtw_ieee80211_hdr	*pwlanhdr;
5532 	__le16 *fctrl;
5533 	struct xmit_priv	*pxmitpriv;
5534 	struct mlme_ext_priv	*pmlmeext;
5535 	struct mlme_ext_info	*pmlmeinfo;
5536 
5537 	if (!padapter)
5538 		goto exit;
5539 
5540 	pxmitpriv = &padapter->xmitpriv;
5541 	pmlmeext = &padapter->mlmeextpriv;
5542 	pmlmeinfo = &pmlmeext->mlmext_info;
5543 
5544 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5545 	if (!pmgntframe)
5546 		goto exit;
5547 
5548 	/* update attribute */
5549 	pattrib = &pmgntframe->attrib;
5550 	update_mgntframe_attrib(padapter, pattrib);
5551 	pattrib->retry_ctrl = false;
5552 
5553 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5554 
5555 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5556 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5557 
5558 	fctrl = &pwlanhdr->frame_ctl;
5559 	*(fctrl) = 0;
5560 
5561 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
5562 		SetFrDs(fctrl);
5563 	else if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
5564 		SetToDs(fctrl);
5565 
5566 	if (power_mode)
5567 		SetPwrMgt(fctrl);
5568 
5569 	memcpy(pwlanhdr->addr1, da, ETH_ALEN);
5570 	memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
5571 	memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
5572 
5573 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5574 	pmlmeext->mgnt_seq++;
5575 	SetFrameSubType(pframe, WIFI_DATA_NULL);
5576 
5577 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5578 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5579 
5580 	pattrib->last_txcmdsz = pattrib->pktlen;
5581 
5582 	if (wait_ack) {
5583 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
5584 	} else {
5585 		dump_mgntframe(padapter, pmgntframe);
5586 		ret = _SUCCESS;
5587 	}
5588 
5589 exit:
5590 	return ret;
5591 }
5592 
5593 /* when wait_ms > 0 , this function shoule be called at process context */
5594 /* da == NULL for station mode */
issue_nulldata(struct adapter * padapter,unsigned char * da,unsigned int power_mode,int try_cnt,int wait_ms)5595 int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
5596 {
5597 	int ret;
5598 	int i = 0;
5599 	u32 start = jiffies;
5600 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
5601 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
5602 
5603 	/* da == NULL, assum it's null data for sta to ap*/
5604 	if (!da)
5605 		da = get_my_bssid(&pmlmeinfo->network);
5606 
5607 	do {
5608 		ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0);
5609 
5610 		i++;
5611 
5612 		if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
5613 			break;
5614 
5615 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
5616 			msleep(wait_ms);
5617 	} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
5618 
5619 	if (ret != _FAIL) {
5620 		ret = _SUCCESS;
5621 		goto exit;
5622 	}
5623 
5624 	if (try_cnt && wait_ms) {
5625 		if (da)
5626 			DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n",
5627 				FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter),
5628 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
5629 		else
5630 			DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
5631 				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
5632 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
5633 	}
5634 exit:
5635 	return ret;
5636 }
5637 
5638 /* when wait_ack is ture, this function shoule be called at process context */
_issue_qos_nulldata(struct adapter * padapter,unsigned char * da,u16 tid,int wait_ack)5639 static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
5640 {
5641 	int ret = _FAIL;
5642 	struct xmit_frame			*pmgntframe;
5643 	struct pkt_attrib			*pattrib;
5644 	unsigned char					*pframe;
5645 	struct rtw_ieee80211_hdr	*pwlanhdr;
5646 	__le16 *fctrl;
5647 	unsigned short *qc;
5648 	struct xmit_priv			*pxmitpriv = &padapter->xmitpriv;
5649 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
5650 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
5651 
5652 	DBG_88E("%s\n", __func__);
5653 
5654 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5655 	if (!pmgntframe)
5656 		goto exit;
5657 
5658 	/* update attribute */
5659 	pattrib = &pmgntframe->attrib;
5660 	update_mgntframe_attrib(padapter, pattrib);
5661 
5662 	pattrib->hdrlen += 2;
5663 	pattrib->qos_en = true;
5664 	pattrib->eosp = 1;
5665 	pattrib->ack_policy = 0;
5666 	pattrib->mdata = 0;
5667 
5668 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5669 
5670 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5671 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5672 
5673 	fctrl = &pwlanhdr->frame_ctl;
5674 	*(fctrl) = 0;
5675 
5676 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
5677 		SetFrDs(fctrl);
5678 	else if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
5679 		SetToDs(fctrl);
5680 
5681 	if (pattrib->mdata)
5682 		SetMData(fctrl);
5683 
5684 	qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
5685 
5686 	SetPriority(qc, tid);
5687 
5688 	SetEOSP(qc, pattrib->eosp);
5689 
5690 	SetAckpolicy(qc, pattrib->ack_policy);
5691 
5692 	memcpy(pwlanhdr->addr1, da, ETH_ALEN);
5693 	memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
5694 	memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
5695 
5696 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5697 	pmlmeext->mgnt_seq++;
5698 	SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
5699 
5700 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
5701 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
5702 
5703 	pattrib->last_txcmdsz = pattrib->pktlen;
5704 
5705 	if (wait_ack) {
5706 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
5707 	} else {
5708 		dump_mgntframe(padapter, pmgntframe);
5709 		ret = _SUCCESS;
5710 	}
5711 
5712 exit:
5713 	return ret;
5714 }
5715 
5716 /* when wait_ms > 0 , this function shoule be called at process context */
5717 /* da == NULL for station mode */
issue_qos_nulldata(struct adapter * padapter,unsigned char * da,u16 tid,int try_cnt,int wait_ms)5718 int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
5719 {
5720 	int ret;
5721 	int i = 0;
5722 	u32 start = jiffies;
5723 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
5724 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
5725 
5726 	/* da == NULL, assum it's null data for sta to ap*/
5727 	if (!da)
5728 		da = get_my_bssid(&pmlmeinfo->network);
5729 
5730 	do {
5731 		ret = _issue_qos_nulldata(padapter, da, tid, wait_ms > 0);
5732 
5733 		i++;
5734 
5735 		if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
5736 			break;
5737 
5738 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
5739 			msleep(wait_ms);
5740 	} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
5741 
5742 	if (ret != _FAIL) {
5743 		ret = _SUCCESS;
5744 		goto exit;
5745 	}
5746 
5747 	if (try_cnt && wait_ms) {
5748 		if (da)
5749 			DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n",
5750 				FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter),
5751 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
5752 		else
5753 			DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
5754 				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
5755 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
5756 	}
5757 exit:
5758 	return ret;
5759 }
5760 
_issue_deauth(struct adapter * padapter,unsigned char * da,unsigned short reason,u8 wait_ack)5761 static int _issue_deauth(struct adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack)
5762 {
5763 	struct xmit_frame			*pmgntframe;
5764 	struct pkt_attrib			*pattrib;
5765 	unsigned char					*pframe;
5766 	struct rtw_ieee80211_hdr	*pwlanhdr;
5767 	__le16 *fctrl;
5768 	struct xmit_priv			*pxmitpriv = &padapter->xmitpriv;
5769 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
5770 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
5771 	int ret = _FAIL;
5772 	__le16 le_tmp;
5773 #ifdef CONFIG_88EU_P2P
5774 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
5775 #endif /* CONFIG_88EU_P2P */
5776 
5777 #ifdef CONFIG_88EU_P2P
5778 	if (!(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) && (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
5779 		_cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
5780 		_set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
5781 	}
5782 #endif /* CONFIG_88EU_P2P */
5783 
5784 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5785 	if (!pmgntframe)
5786 		goto exit;
5787 
5788 	/* update attribute */
5789 	pattrib = &pmgntframe->attrib;
5790 	update_mgntframe_attrib(padapter, pattrib);
5791 	pattrib->retry_ctrl = false;
5792 
5793 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5794 
5795 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5796 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5797 
5798 	fctrl = &pwlanhdr->frame_ctl;
5799 	*(fctrl) = 0;
5800 
5801 	memcpy(pwlanhdr->addr1, da, ETH_ALEN);
5802 	memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
5803 	memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
5804 
5805 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5806 	pmlmeext->mgnt_seq++;
5807 	SetFrameSubType(pframe, WIFI_DEAUTH);
5808 
5809 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5810 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5811 
5812 	le_tmp = cpu_to_le16(reason);
5813 	pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_, (unsigned char *)&le_tmp, &pattrib->pktlen);
5814 
5815 	pattrib->last_txcmdsz = pattrib->pktlen;
5816 
5817 	if (wait_ack) {
5818 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
5819 	} else {
5820 		dump_mgntframe(padapter, pmgntframe);
5821 		ret = _SUCCESS;
5822 	}
5823 
5824 exit:
5825 	return ret;
5826 }
5827 
issue_deauth(struct adapter * padapter,unsigned char * da,unsigned short reason)5828 int issue_deauth(struct adapter *padapter, unsigned char *da, unsigned short reason)
5829 {
5830 	DBG_88E("%s to %pM\n", __func__, da);
5831 	return _issue_deauth(padapter, da, reason, false);
5832 }
5833 
issue_deauth_ex(struct adapter * padapter,u8 * da,unsigned short reason,int try_cnt,int wait_ms)5834 int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
5835 	int wait_ms)
5836 {
5837 	int ret;
5838 	int i = 0;
5839 	u32 start = jiffies;
5840 
5841 	do {
5842 		ret = _issue_deauth(padapter, da, reason, wait_ms > 0);
5843 
5844 		i++;
5845 
5846 		if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
5847 			break;
5848 
5849 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
5850 			msleep(wait_ms);
5851 	} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
5852 
5853 	if (ret != _FAIL) {
5854 		ret = _SUCCESS;
5855 		goto exit;
5856 	}
5857 
5858 	if (try_cnt && wait_ms) {
5859 		if (da)
5860 			DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n",
5861 				FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter),
5862 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
5863 		else
5864 			DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
5865 				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
5866 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
5867 	}
5868 exit:
5869 	return ret;
5870 }
5871 
issue_action_spct_ch_switch(struct adapter * padapter,u8 * ra,u8 new_ch,u8 ch_offset)5872 void issue_action_spct_ch_switch(struct adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
5873 {
5874 	struct xmit_frame			*pmgntframe;
5875 	struct pkt_attrib			*pattrib;
5876 	unsigned char				*pframe;
5877 	struct rtw_ieee80211_hdr	*pwlanhdr;
5878 	__le16 *fctrl;
5879 	struct xmit_priv			*pxmitpriv = &padapter->xmitpriv;
5880 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
5881 
5882 	DBG_88E(FUNC_NDEV_FMT" ra =%pM, ch:%u, offset:%u\n",
5883 		FUNC_NDEV_ARG(padapter->pnetdev), ra, new_ch, ch_offset);
5884 
5885 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5886 	if (!pmgntframe)
5887 		return;
5888 
5889 	/* update attribute */
5890 	pattrib = &pmgntframe->attrib;
5891 	update_mgntframe_attrib(padapter, pattrib);
5892 
5893 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5894 
5895 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5896 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5897 
5898 	fctrl = &pwlanhdr->frame_ctl;
5899 	*(fctrl) = 0;
5900 
5901 	memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
5902 	memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); /* TA */
5903 	memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
5904 
5905 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5906 	pmlmeext->mgnt_seq++;
5907 	SetFrameSubType(pframe, WIFI_ACTION);
5908 
5909 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5910 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5911 
5912 	/* category, action */
5913 	{
5914 		u8 category, action;
5915 		category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
5916 		action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
5917 
5918 		pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
5919 		pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
5920 	}
5921 
5922 	pframe = rtw_set_ie_ch_switch(pframe, &pattrib->pktlen, 0, new_ch, 0);
5923 	pframe = rtw_set_ie_secondary_ch_offset(pframe, &pattrib->pktlen,
5924 		hal_ch_offset_to_secondary_ch_offset(ch_offset));
5925 
5926 	pattrib->last_txcmdsz = pattrib->pktlen;
5927 
5928 	dump_mgntframe(padapter, pmgntframe);
5929 }
5930 
issue_action_BA(struct adapter * padapter,unsigned char * raddr,unsigned char action,unsigned short status)5931 void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status)
5932 {
5933 	u8 category = RTW_WLAN_CATEGORY_BACK;
5934 	u16 start_seq;
5935 	u16 BA_para_set;
5936 	u16 reason_code;
5937 	u16 BA_timeout_value;
5938 	__le16	le_tmp;
5939 	u16 BA_starting_seqctrl = 0;
5940 	enum ht_cap_ampdu_factor max_rx_ampdu_factor;
5941 	struct xmit_frame *pmgntframe;
5942 	struct pkt_attrib *pattrib;
5943 	u8 *pframe;
5944 	struct rtw_ieee80211_hdr *pwlanhdr;
5945 	__le16 *fctrl;
5946 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5947 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5948 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5949 	struct sta_info *psta;
5950 	struct sta_priv *pstapriv = &padapter->stapriv;
5951 	struct registry_priv *pregpriv = &padapter->registrypriv;
5952 
5953 	DBG_88E("%s, category=%d, action=%d, status=%d\n", __func__, category, action, status);
5954 
5955 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5956 	if (!pmgntframe)
5957 		return;
5958 
5959 	/* update attribute */
5960 	pattrib = &pmgntframe->attrib;
5961 	update_mgntframe_attrib(padapter, pattrib);
5962 
5963 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5964 
5965 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5966 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5967 
5968 	fctrl = &pwlanhdr->frame_ctl;
5969 	*(fctrl) = 0;
5970 
5971 	/* memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */
5972 	memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5973 	memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
5974 	memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
5975 
5976 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5977 	pmlmeext->mgnt_seq++;
5978 	SetFrameSubType(pframe, WIFI_ACTION);
5979 
5980 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5981 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5982 
5983 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &pattrib->pktlen);
5984 	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &pattrib->pktlen);
5985 
5986 	if (category == 3) {
5987 		switch (action) {
5988 		case 0: /* ADDBA req */
5989 			do {
5990 				pmlmeinfo->dialogToken++;
5991 			} while (pmlmeinfo->dialogToken == 0);
5992 			pframe = rtw_set_fixed_ie(pframe, 1, &pmlmeinfo->dialogToken, &pattrib->pktlen);
5993 
5994 			BA_para_set = (0x1002 | ((status & 0xf) << 2)); /* immediate ack & 64 buffer size */
5995 			le_tmp = cpu_to_le16(BA_para_set);
5996 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
5997 
5998 			BA_timeout_value = 5000;/*  5ms */
5999 			le_tmp = cpu_to_le16(BA_timeout_value);
6000 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
6001 
6002 			psta = rtw_get_stainfo(pstapriv, raddr);
6003 			if (psta) {
6004 				start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07] & 0xfff) + 1;
6005 
6006 				DBG_88E("BA_starting_seqctrl=%d for TID=%d\n", start_seq, status & 0x07);
6007 
6008 				psta->BA_starting_seqctrl[status & 0x07] = start_seq;
6009 
6010 				BA_starting_seqctrl = start_seq << 4;
6011 			}
6012 			le_tmp = cpu_to_le16(BA_starting_seqctrl);
6013 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
6014 			break;
6015 		case 1: /* ADDBA rsp */
6016 			pframe = rtw_set_fixed_ie(pframe, 1, &pmlmeinfo->ADDBA_req.dialog_token, &pattrib->pktlen);
6017 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&status, &pattrib->pktlen);
6018 			BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f;
6019 			rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
6020 			switch (max_rx_ampdu_factor) {
6021 			case MAX_AMPDU_FACTOR_64K:
6022 				BA_para_set |= 0x1000; /* 64 buffer size */
6023 				break;
6024 			case MAX_AMPDU_FACTOR_32K:
6025 				BA_para_set |= 0x0800; /* 32 buffer size */
6026 				break;
6027 			case MAX_AMPDU_FACTOR_16K:
6028 				BA_para_set |= 0x0400; /* 16 buffer size */
6029 				break;
6030 			case MAX_AMPDU_FACTOR_8K:
6031 				BA_para_set |= 0x0200; /* 8 buffer size */
6032 				break;
6033 			default:
6034 				BA_para_set |= 0x1000; /* 64 buffer size */
6035 				break;
6036 			}
6037 
6038 			if (pregpriv->ampdu_amsdu == 0)/* disabled */
6039 				BA_para_set = BA_para_set & ~BIT(0);
6040 			else if (pregpriv->ampdu_amsdu == 1)/* enabled */
6041 				BA_para_set = BA_para_set | BIT(0);
6042 			le_tmp = cpu_to_le16(BA_para_set);
6043 
6044 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
6045 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeinfo->ADDBA_req.BA_timeout_value, &pattrib->pktlen);
6046 			break;
6047 		case 2:/* DELBA */
6048 			BA_para_set = (status & 0x1F) << 3;
6049 			le_tmp = cpu_to_le16(BA_para_set);
6050 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
6051 
6052 			reason_code = 37;/* Requested from peer STA as it does not want to use the mechanism */
6053 			le_tmp = cpu_to_le16(reason_code);
6054 			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
6055 			break;
6056 		default:
6057 			break;
6058 		}
6059 	}
6060 
6061 	pattrib->last_txcmdsz = pattrib->pktlen;
6062 
6063 	dump_mgntframe(padapter, pmgntframe);
6064 }
6065 
issue_action_BSSCoexistPacket(struct adapter * padapter)6066 static void issue_action_BSSCoexistPacket(struct adapter *padapter)
6067 {
6068 	struct list_head *plist, *phead;
6069 	unsigned char category, action;
6070 	struct xmit_frame			*pmgntframe;
6071 	struct pkt_attrib			*pattrib;
6072 	unsigned char				*pframe;
6073 	struct rtw_ieee80211_hdr	*pwlanhdr;
6074 	__le16 *fctrl;
6075 	struct	wlan_network	*pnetwork = NULL;
6076 	struct xmit_priv			*pxmitpriv = &padapter->xmitpriv;
6077 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6078 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
6079 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
6080 	struct __queue *queue	= &pmlmepriv->scanned_queue;
6081 	u8 InfoContent[16] = {0};
6082 	u8 ICS[8][15];
6083 	if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0))
6084 		return;
6085 
6086 	if (pmlmeinfo->bwmode_updated)
6087 		return;
6088 
6089 	DBG_88E("%s\n", __func__);
6090 
6091 	category = RTW_WLAN_CATEGORY_PUBLIC;
6092 	action = ACT_PUBLIC_BSSCOEXIST;
6093 
6094 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
6095 	if (!pmgntframe)
6096 		return;
6097 
6098 	/* update attribute */
6099 	pattrib = &pmgntframe->attrib;
6100 	update_mgntframe_attrib(padapter, pattrib);
6101 
6102 	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6103 
6104 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6105 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6106 
6107 	fctrl = &pwlanhdr->frame_ctl;
6108 	*(fctrl) = 0;
6109 
6110 	memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
6111 	memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
6112 	memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
6113 
6114 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6115 	pmlmeext->mgnt_seq++;
6116 	SetFrameSubType(pframe, WIFI_ACTION);
6117 
6118 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6119 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6120 
6121 	pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
6122 	pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
6123 
6124 	/*  */
6125 	if (pmlmepriv->num_FortyMHzIntolerant > 0) {
6126 		u8 iedata = 0;
6127 
6128 		iedata |= BIT(2);/* 20 MHz BSS Width Request */
6129 
6130 		pframe = rtw_set_ie(pframe, EID_BSSCoexistence,  1, &iedata, &pattrib->pktlen);
6131 	}
6132 
6133 	/*  */
6134 	memset(ICS, 0, sizeof(ICS));
6135 	if (pmlmepriv->num_sta_no_ht > 0) {
6136 		int i;
6137 
6138 		spin_lock_bh(&pmlmepriv->scanned_queue.lock);
6139 
6140 		phead = get_list_head(queue);
6141 		plist = phead->next;
6142 
6143 		while (phead != plist) {
6144 			int len;
6145 			u8 *p;
6146 			struct wlan_bssid_ex *pbss_network;
6147 
6148 			pnetwork = container_of(plist, struct wlan_network, list);
6149 
6150 			plist = plist->next;
6151 
6152 			pbss_network = (struct wlan_bssid_ex *)&pnetwork->network;
6153 
6154 			p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
6155 			if (!p || len == 0) { /* non-HT */
6156 				if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14))
6157 					continue;
6158 
6159 				ICS[0][pbss_network->Configuration.DSConfig] = 1;
6160 
6161 				if (ICS[0][0] == 0)
6162 					ICS[0][0] = 1;
6163 			}
6164 		}
6165 		spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
6166 
6167 		for (i = 0; i < 8; i++) {
6168 			if (ICS[i][0] == 1) {
6169 				int j, k = 0;
6170 
6171 				InfoContent[k] = i;
6172 				/* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */
6173 				k++;
6174 
6175 				for (j = 1; j <= 14; j++) {
6176 					if (ICS[i][j] == 1) {
6177 						if (k < 16) {
6178 							InfoContent[k] = j; /* channel number */
6179 							/* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */
6180 							k++;
6181 						}
6182 					}
6183 				}
6184 
6185 				pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &pattrib->pktlen);
6186 			}
6187 		}
6188 	}
6189 
6190 	pattrib->last_txcmdsz = pattrib->pktlen;
6191 
6192 	dump_mgntframe(padapter, pmgntframe);
6193 }
6194 
send_delba(struct adapter * padapter,u8 initiator,u8 * addr)6195 unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr)
6196 {
6197 	struct sta_priv *pstapriv = &padapter->stapriv;
6198 	struct sta_info *psta = NULL;
6199 	/* struct recv_reorder_ctrl *preorder_ctrl; */
6200 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
6201 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
6202 	u16 tid;
6203 
6204 	if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
6205 		if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
6206 			return _SUCCESS;
6207 
6208 	psta = rtw_get_stainfo(pstapriv, addr);
6209 	if (!psta)
6210 		return _SUCCESS;
6211 
6212 	if (initiator == 0) { /*  recipient */
6213 		for (tid = 0; tid < MAXTID; tid++) {
6214 			if (psta->recvreorder_ctrl[tid].enable) {
6215 				DBG_88E("rx agg disable tid(%d)\n", tid);
6216 				issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator) & 0x1F));
6217 				psta->recvreorder_ctrl[tid].enable = false;
6218 				psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
6219 			}
6220 		}
6221 	} else if (initiator == 1) { /*  originator */
6222 		for (tid = 0; tid < MAXTID; tid++) {
6223 			if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
6224 				DBG_88E("tx agg disable tid(%d)\n", tid);
6225 				issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator) & 0x1F));
6226 				psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
6227 				psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
6228 			}
6229 		}
6230 	}
6231 
6232 	return _SUCCESS;
6233 }
6234 
send_beacon(struct adapter * padapter)6235 unsigned int send_beacon(struct adapter *padapter)
6236 {
6237 	u8 bxmitok = false;
6238 	int	issue = 0;
6239 	int poll = 0;
6240 
6241 	u32 start = jiffies;
6242 
6243 	rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
6244 	do {
6245 		issue_beacon(padapter, 100);
6246 		issue++;
6247 		do {
6248 			yield();
6249 			rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
6250 			poll++;
6251 		} while ((poll % 10) != 0 && !bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
6252 	} while (!bxmitok && issue < 100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
6253 
6254 	if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
6255 		return _FAIL;
6256 	if (!bxmitok) {
6257 		DBG_88E("%s fail! %u ms\n", __func__, rtw_get_passing_time_ms(start));
6258 		return _FAIL;
6259 	} else {
6260 		u32 passing_time = rtw_get_passing_time_ms(start);
6261 
6262 		if (passing_time > 100 || issue > 3)
6263 			DBG_88E("%s success, issue:%d, poll:%d, %u ms\n", __func__, issue, poll, rtw_get_passing_time_ms(start));
6264 		return _SUCCESS;
6265 	}
6266 }
6267 
6268 /****************************************************************************
6269 
6270 Following are some utitity fuctions for WiFi MLME
6271 
6272 *****************************************************************************/
6273 
site_survey(struct adapter * padapter)6274 void site_survey(struct adapter *padapter)
6275 {
6276 	unsigned char		survey_channel = 0, val8;
6277 	enum rt_scan_type ScanType = SCAN_PASSIVE;
6278 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
6279 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
6280 	u32 initialgain = 0;
6281 
6282 #ifdef CONFIG_88EU_P2P
6283 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
6284 
6285 	if ((pwdinfo->rx_invitereq_info.scan_op_ch_only) || (pwdinfo->p2p_info.scan_op_ch_only)) {
6286 		if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
6287 			survey_channel = pwdinfo->rx_invitereq_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
6288 		} else {
6289 			survey_channel = pwdinfo->p2p_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
6290 		}
6291 		ScanType = SCAN_ACTIVE;
6292 	} else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
6293 		/*	Commented by Albert 2011/06/03 */
6294 		/*	The driver is in the find phase, it should go through the social channel. */
6295 		int ch_set_idx;
6296 		survey_channel = pwdinfo->social_chan[pmlmeext->sitesurvey_res.channel_idx];
6297 		ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, survey_channel);
6298 		if (ch_set_idx >= 0)
6299 			ScanType = pmlmeext->channel_set[ch_set_idx].ScanType;
6300 		else
6301 			ScanType = SCAN_ACTIVE;
6302 	} else
6303 #endif /* CONFIG_88EU_P2P */
6304 	{
6305 		struct rtw_ieee80211_channel *ch;
6306 		if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
6307 			ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
6308 			survey_channel = ch->hw_value;
6309 			ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
6310 		}
6311 	}
6312 
6313 	if (survey_channel != 0) {
6314 		/* PAUSE 4-AC Queue when site_survey */
6315 		/* rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
6316 		/* val8 |= 0x0f; */
6317 		/* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
6318 		if (pmlmeext->sitesurvey_res.channel_idx == 0)
6319 			set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
6320 		else
6321 			SelectChannel(padapter, survey_channel);
6322 
6323 		if (ScanType == SCAN_ACTIVE) { /* obey the channel plan setting... */
6324 			#ifdef CONFIG_88EU_P2P
6325 			if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
6326 			    rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) {
6327 				issue_probereq_p2p(padapter, NULL);
6328 				issue_probereq_p2p(padapter, NULL);
6329 				issue_probereq_p2p(padapter, NULL);
6330 			} else
6331 			#endif /* CONFIG_88EU_P2P */
6332 			{
6333 				int i;
6334 				for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
6335 					if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
6336 						/* todo: to issue two probe req??? */
6337 						issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
6338 						/* msleep(SURVEY_TO>>1); */
6339 						issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
6340 					}
6341 				}
6342 
6343 				if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
6344 					/* todo: to issue two probe req??? */
6345 					issue_probereq(padapter, NULL, NULL);
6346 					/* msleep(SURVEY_TO>>1); */
6347 					issue_probereq(padapter, NULL, NULL);
6348 				}
6349 			}
6350 		}
6351 
6352 		set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
6353 	} else {
6354 		/*	channel number is 0 or this channel is not valid. */
6355 
6356 #ifdef CONFIG_88EU_P2P
6357 		if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) {
6358 			if ((pwdinfo->rx_invitereq_info.scan_op_ch_only) || (pwdinfo->p2p_info.scan_op_ch_only)) {
6359 				/*	Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT. */
6360 				/*	This will let the following flow to run the scanning end. */
6361 				rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
6362 			}
6363 		}
6364 
6365 		if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) {
6366 			/*	Set the P2P State to the listen state of find phase and set the current channel to the listen channel */
6367 			set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
6368 			rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
6369 			pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
6370 
6371 			initialgain = 0xff; /* restore RX GAIN */
6372 			rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
6373 			/* turn on dynamic functions */
6374 			Restore_DM_Func_Flag(padapter);
6375 			/* Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, true); */
6376 
6377 			_set_timer(&pwdinfo->find_phase_timer, (u32)((u32)(pwdinfo->listen_dwell) * 100));
6378 		} else
6379 #endif /* CONFIG_88EU_P2P */
6380 		{
6381 			/*  20100721:Interrupt scan operation here. */
6382 			/*  For SW antenna diversity before link, it needs to switch to another antenna and scan again. */
6383 			/*  It compares the scan result and select beter one to do connection. */
6384 			if (rtw_hal_antdiv_before_linked(padapter)) {
6385 				pmlmeext->sitesurvey_res.bss_cnt = 0;
6386 				pmlmeext->sitesurvey_res.channel_idx = -1;
6387 				pmlmeext->chan_scan_time = SURVEY_TO / 2;
6388 				set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
6389 				return;
6390 			}
6391 #ifdef CONFIG_88EU_P2P
6392 			if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
6393 				rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6394 			rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
6395 #endif /* CONFIG_88EU_P2P */
6396 
6397 			pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
6398 
6399 			/* switch back to the original channel */
6400 
6401 #ifdef CONFIG_88EU_P2P
6402 			if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN))
6403 				set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
6404 			else
6405 				set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
6406 #endif /* CONFIG_88EU_P2P */
6407 
6408 			/* flush 4-AC Queue after site_survey */
6409 			/* val8 = 0; */
6410 			/* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
6411 
6412 			/* config MSR */
6413 			Set_MSR(padapter, (pmlmeinfo->state & 0x3));
6414 
6415 			initialgain = 0xff; /* restore RX GAIN */
6416 			rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
6417 			/* turn on dynamic functions */
6418 			Restore_DM_Func_Flag(padapter);
6419 			/* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */
6420 
6421 			if (is_client_associated_to_ap(padapter))
6422 				issue_nulldata(padapter, NULL, 0, 3, 500);
6423 
6424 			val8 = 0; /* survey done */
6425 			rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
6426 
6427 			report_surveydone_event(padapter);
6428 
6429 			pmlmeext->chan_scan_time = SURVEY_TO;
6430 			pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
6431 
6432 			issue_action_BSSCoexistPacket(padapter);
6433 			issue_action_BSSCoexistPacket(padapter);
6434 			issue_action_BSSCoexistPacket(padapter);
6435 		}
6436 	}
6437 }
6438 
6439 /* collect bss info from Beacon and Probe request/response frames. */
collect_bss_info(struct adapter * padapter,struct recv_frame * precv_frame,struct wlan_bssid_ex * bssid)6440 u8 collect_bss_info(struct adapter *padapter, struct recv_frame *precv_frame, struct wlan_bssid_ex *bssid)
6441 {
6442 	int	i;
6443 	u32	len;
6444 	u8 *p;
6445 	u16 val16, subtype;
6446 	u8 *pframe = precv_frame->rx_data;
6447 	u32	packet_len = precv_frame->len;
6448 	u8 ie_offset;
6449 	struct registry_priv	*pregistrypriv = &padapter->registrypriv;
6450 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
6451 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
6452 	__le32 le32_tmp;
6453 
6454 	len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
6455 
6456 	if (len > MAX_IE_SZ)
6457 		return _FAIL;
6458 
6459 	memset(bssid, 0, sizeof(struct wlan_bssid_ex));
6460 
6461 	subtype = GetFrameSubType(pframe);
6462 
6463 	if (subtype == WIFI_BEACON) {
6464 		bssid->Reserved[0] = 1;
6465 		ie_offset = _BEACON_IE_OFFSET_;
6466 	} else {
6467 		/*  FIXME : more type */
6468 		if (subtype == WIFI_PROBEREQ) {
6469 			ie_offset = _PROBEREQ_IE_OFFSET_;
6470 			bssid->Reserved[0] = 2;
6471 		} else if (subtype == WIFI_PROBERSP) {
6472 			ie_offset = _PROBERSP_IE_OFFSET_;
6473 			bssid->Reserved[0] = 3;
6474 		} else {
6475 			bssid->Reserved[0] = 0;
6476 			ie_offset = _FIXED_IE_LENGTH_;
6477 		}
6478 	}
6479 
6480 	bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len;
6481 
6482 	/* below is to copy the information element */
6483 	bssid->IELength = len;
6484 	memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
6485 
6486 	/* get the signal strength */
6487 	bssid->Rssi = precv_frame->attrib.phy_info.recvpower; /*  in dBM.raw data */
6488 	bssid->PhyInfo.SignalQuality = precv_frame->attrib.phy_info.SignalQuality;/* in percentage */
6489 	bssid->PhyInfo.SignalStrength = precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
6490 	rtw_hal_get_def_var(padapter, HAL_DEF_CURRENT_ANTENNA,  &bssid->PhyInfo.Optimum_antenna);
6491 
6492 	/*  checking SSID */
6493 	p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset);
6494 	if (!p) {
6495 		DBG_88E("marc: cannot find SSID for survey event\n");
6496 		return _FAIL;
6497 	}
6498 
6499 	if (*(p + 1)) {
6500 		if (len > NDIS_802_11_LENGTH_SSID) {
6501 			DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
6502 			return _FAIL;
6503 		}
6504 		memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
6505 		bssid->Ssid.SsidLength = *(p + 1);
6506 	} else {
6507 		bssid->Ssid.SsidLength = 0;
6508 	}
6509 
6510 	memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
6511 
6512 	/* checking rate info... */
6513 	i = 0;
6514 	p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
6515 	if (p) {
6516 		if (len > NDIS_802_11_LENGTH_RATES_EX) {
6517 			DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
6518 			return _FAIL;
6519 		}
6520 		memcpy(bssid->SupportedRates, (p + 2), len);
6521 		i = len;
6522 	}
6523 
6524 	p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
6525 	if (p) {
6526 		if (len > (NDIS_802_11_LENGTH_RATES_EX - i)) {
6527 			DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
6528 			return _FAIL;
6529 		}
6530 		memcpy(bssid->SupportedRates + i, (p + 2), len);
6531 	}
6532 
6533 	/* todo: */
6534 	bssid->NetworkTypeInUse = Ndis802_11OFDM24;
6535 
6536 	if (bssid->IELength < 12)
6537 		return _FAIL;
6538 
6539 	/*  Checking for DSConfig */
6540 	p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
6541 
6542 	bssid->Configuration.DSConfig = 0;
6543 	bssid->Configuration.Length = 0;
6544 
6545 	if (p) {
6546 		bssid->Configuration.DSConfig = *(p + 2);
6547 	} else {/*  In 5G, some ap do not have DSSET IE */
6548 		/*  checking HT info for channel */
6549 		p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
6550 		if (p) {
6551 			struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
6552 			bssid->Configuration.DSConfig = HT_info->primary_channel;
6553 		} else { /*  use current channel */
6554 			bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
6555 		}
6556 	}
6557 
6558 	memcpy(&le32_tmp, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
6559 	bssid->Configuration.BeaconPeriod = le32_to_cpu(le32_tmp);
6560 
6561 	val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid);
6562 
6563 	if (val16 & BIT(0)) {
6564 		bssid->InfrastructureMode = Ndis802_11Infrastructure;
6565 		memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
6566 	} else {
6567 		bssid->InfrastructureMode = Ndis802_11IBSS;
6568 		memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
6569 	}
6570 
6571 	if (val16 & BIT(4))
6572 		bssid->Privacy = 1;
6573 	else
6574 		bssid->Privacy = 0;
6575 
6576 	bssid->Configuration.ATIMWindow = 0;
6577 
6578 	/* 20/40 BSS Coexistence check */
6579 	if ((pregistrypriv->wifi_spec == 1) && (!pmlmeinfo->bwmode_updated)) {
6580 		struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6581 		p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
6582 		if (p && len > 0) {
6583 			struct HT_caps_element	*pHT_caps;
6584 			pHT_caps = (struct HT_caps_element *)(p + 2);
6585 
6586 			if (le16_to_cpu(pHT_caps->u.HT_cap_element.HT_caps_info) & BIT(14))
6587 				pmlmepriv->num_FortyMHzIntolerant++;
6588 		} else {
6589 			pmlmepriv->num_sta_no_ht++;
6590 		}
6591 	}
6592 
6593 	/*  mark bss info receiving from nearby channel as SignalQuality 101 */
6594 	if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
6595 		bssid->PhyInfo.SignalQuality = 101;
6596 	return _SUCCESS;
6597 }
6598 
start_create_ibss(struct adapter * padapter)6599 void start_create_ibss(struct adapter *padapter)
6600 {
6601 	unsigned short	caps;
6602 	u8 val8;
6603 	u8 join_type;
6604 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
6605 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
6606 	struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network);
6607 	pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
6608 	pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
6609 
6610 	/* update wireless mode */
6611 	update_wireless_mode(padapter);
6612 
6613 	/* udpate capability */
6614 	caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork);
6615 	update_capinfo(padapter, caps);
6616 	if (caps & cap_IBSS) {/* adhoc master */
6617 		val8 = 0xcf;
6618 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
6619 
6620 		/* switch channel */
6621 		/* SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
6622 		set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
6623 
6624 		beacon_timing_control(padapter);
6625 
6626 		/* set msr to WIFI_FW_ADHOC_STATE */
6627 		pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
6628 		Set_MSR(padapter, (pmlmeinfo->state & 0x3));
6629 
6630 		/* issue beacon */
6631 		if (send_beacon(padapter) == _FAIL) {
6632 			report_join_res(padapter, -1);
6633 			pmlmeinfo->state = WIFI_FW_NULL_STATE;
6634 		} else {
6635 			rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
6636 			join_type = 0;
6637 			rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
6638 
6639 			report_join_res(padapter, 1);
6640 			pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
6641 			rtw_indicate_connect(padapter);
6642 		}
6643 	} else {
6644 		DBG_88E("start_create_ibss, invalid cap:%x\n", caps);
6645 		return;
6646 	}
6647 	/* update bc/mc sta_info */
6648 	update_bmc_sta(padapter);
6649 }
6650 
start_clnt_join(struct adapter * padapter)6651 void start_clnt_join(struct adapter *padapter)
6652 {
6653 	unsigned short	caps;
6654 	u8 val8;
6655 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
6656 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
6657 	struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network);
6658 	int beacon_timeout;
6659 
6660 	pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
6661 	pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
6662 
6663 	/* update wireless mode */
6664 	update_wireless_mode(padapter);
6665 
6666 	/* udpate capability */
6667 	caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork);
6668 	update_capinfo(padapter, caps);
6669 	if (caps & cap_ESS) {
6670 		Set_MSR(padapter, WIFI_FW_STATION_STATE);
6671 
6672 		val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf;
6673 
6674 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
6675 
6676 		/* switch channel */
6677 		set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
6678 
6679 		/* here wait for receiving the beacon to start auth */
6680 		/* and enable a timer */
6681 		beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
6682 		set_link_timer(pmlmeext, beacon_timeout);
6683 		_set_timer(&padapter->mlmepriv.assoc_timer,
6684 			   (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO * REASSOC_LIMIT) + beacon_timeout);
6685 
6686 		pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
6687 	} else if (caps & cap_IBSS) { /* adhoc client */
6688 		Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
6689 
6690 		val8 = 0xcf;
6691 		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
6692 
6693 		/* switch channel */
6694 		set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
6695 
6696 		beacon_timing_control(padapter);
6697 
6698 		pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
6699 
6700 		report_join_res(padapter, 1);
6701 	} else {
6702 		return;
6703 	}
6704 }
6705 
start_clnt_auth(struct adapter * padapter)6706 void start_clnt_auth(struct adapter *padapter)
6707 {
6708 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
6709 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
6710 
6711 	_cancel_timer_ex(&pmlmeext->link_timer);
6712 
6713 	pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
6714 	pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
6715 
6716 	pmlmeinfo->auth_seq = 1;
6717 	pmlmeinfo->reauth_count = 0;
6718 	pmlmeinfo->reassoc_count = 0;
6719 	pmlmeinfo->link_count = 0;
6720 	pmlmeext->retry = 0;
6721 
6722 	/*  Because of AP's not receiving deauth before */
6723 	/*  AP may: 1)not response auth or 2)deauth us after link is complete */
6724 	/*  issue deauth before issuing auth to deal with the situation */
6725 	/*	Commented by Albert 2012/07/21 */
6726 	/*	For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
6727 	issue_deauth(padapter, (&pmlmeinfo->network)->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
6728 
6729 	DBG_88E_LEVEL(_drv_info_, "start auth\n");
6730 	issue_auth(padapter, NULL, 0);
6731 
6732 	set_link_timer(pmlmeext, REAUTH_TO);
6733 }
6734 
start_clnt_assoc(struct adapter * padapter)6735 void start_clnt_assoc(struct adapter *padapter)
6736 {
6737 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
6738 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
6739 
6740 	_cancel_timer_ex(&pmlmeext->link_timer);
6741 
6742 	pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
6743 	pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
6744 
6745 	issue_assocreq(padapter);
6746 
6747 	set_link_timer(pmlmeext, REASSOC_TO);
6748 }
6749 
receive_disconnect(struct adapter * padapter,unsigned char * MacAddr,unsigned short reason)6750 unsigned int receive_disconnect(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason)
6751 {
6752 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
6753 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
6754 
6755 	/* check A3 */
6756 	if (!(!memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
6757 		return _SUCCESS;
6758 
6759 	DBG_88E("%s\n", __func__);
6760 
6761 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
6762 		if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
6763 			pmlmeinfo->state = WIFI_FW_NULL_STATE;
6764 			report_del_sta_event(padapter, MacAddr, reason);
6765 		} else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) {
6766 			pmlmeinfo->state = WIFI_FW_NULL_STATE;
6767 			report_join_res(padapter, -2);
6768 		}
6769 	}
6770 	return _SUCCESS;
6771 }
6772 
process_80211d(struct adapter * padapter,struct wlan_bssid_ex * bssid)6773 static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid)
6774 {
6775 	struct registry_priv *pregistrypriv;
6776 	struct mlme_ext_priv *pmlmeext;
6777 	struct rt_channel_info *chplan_new;
6778 	u8 channel;
6779 	u8 i;
6780 
6781 	pregistrypriv = &padapter->registrypriv;
6782 	pmlmeext = &padapter->mlmeextpriv;
6783 
6784 	/*  Adjust channel plan by AP Country IE */
6785 	if (pregistrypriv->enable80211d &&
6786 	    (!pmlmeext->update_channel_plan_by_ap_done)) {
6787 		u8 *ie, *p;
6788 		u32 len;
6789 		struct rt_channel_plan chplan_ap;
6790 		struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM];
6791 		u8 country[4];
6792 		u8 fcn; /*  first channel number */
6793 		u8 noc; /*  number of channel */
6794 		u8 j, k;
6795 
6796 		ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
6797 		if (!ie)
6798 			return;
6799 		if (len < 6)
6800 			return;
6801 		ie += 2;
6802 		p = ie;
6803 		ie += len;
6804 
6805 		memset(country, 0, 4);
6806 		memcpy(country, p, 3);
6807 		p += 3;
6808 
6809 		i = 0;
6810 		while ((ie - p) >= 3) {
6811 			fcn = *(p++);
6812 			noc = *(p++);
6813 			p++;
6814 
6815 			for (j = 0; j < noc; j++) {
6816 				channel = fcn + j;
6817 				chplan_ap.Channel[i++] = channel;
6818 			}
6819 		}
6820 		chplan_ap.Len = i;
6821 
6822 		memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
6823 
6824 		memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
6825 		chplan_new = pmlmeext->channel_set;
6826 
6827 		i = 0;
6828 		j = 0;
6829 		k = 0;
6830 		if (pregistrypriv->wireless_mode & WIRELESS_11G) {
6831 			do {
6832 				if ((i == MAX_CHANNEL_NUM) ||
6833 				    (chplan_sta[i].ChannelNum == 0))
6834 					break;
6835 
6836 				if (j == chplan_ap.Len)
6837 					break;
6838 
6839 				if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
6840 					chplan_new[k].ChannelNum = chplan_ap.Channel[j];
6841 					chplan_new[k].ScanType = SCAN_ACTIVE;
6842 					i++;
6843 					j++;
6844 					k++;
6845 				} else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
6846 					chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
6847 					chplan_new[k].ScanType = SCAN_PASSIVE;
6848 					i++;
6849 					k++;
6850 				} else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
6851 					chplan_new[k].ChannelNum = chplan_ap.Channel[j];
6852 					chplan_new[k].ScanType = SCAN_ACTIVE;
6853 					j++;
6854 					k++;
6855 				}
6856 			} while (1);
6857 
6858 			/*  change AP not support channel to Passive scan */
6859 			while ((i < MAX_CHANNEL_NUM) &&
6860 			       (chplan_sta[i].ChannelNum != 0) &&
6861 			       (chplan_sta[i].ChannelNum <= 14)) {
6862 				chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
6863 				chplan_new[k].ScanType = SCAN_PASSIVE;
6864 				i++;
6865 				k++;
6866 			}
6867 
6868 			/*  add channel AP supported */
6869 			while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
6870 				chplan_new[k].ChannelNum = chplan_ap.Channel[j];
6871 				chplan_new[k].ScanType = SCAN_ACTIVE;
6872 				j++;
6873 				k++;
6874 			}
6875 		} else {
6876 			/*  keep original STA 2.4G channel plan */
6877 			while ((i < MAX_CHANNEL_NUM) &&
6878 			       (chplan_sta[i].ChannelNum != 0) &&
6879 			       (chplan_sta[i].ChannelNum <= 14)) {
6880 				chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
6881 				chplan_new[k].ScanType = chplan_sta[i].ScanType;
6882 				i++;
6883 				k++;
6884 			}
6885 
6886 			/*  skip AP 2.4G channel plan */
6887 			while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
6888 				j++;
6889 		}
6890 
6891 		/*  keep original STA 5G channel plan */
6892 		while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
6893 			chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
6894 			chplan_new[k].ScanType = chplan_sta[i].ScanType;
6895 			i++;
6896 			k++;
6897 		}
6898 
6899 		pmlmeext->update_channel_plan_by_ap_done = 1;
6900 	}
6901 
6902 	/*  If channel is used by AP, set channel scan type to active */
6903 	channel = bssid->Configuration.DSConfig;
6904 	chplan_new = pmlmeext->channel_set;
6905 	i = 0;
6906 	while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) {
6907 		if (chplan_new[i].ChannelNum == channel) {
6908 			if (chplan_new[i].ScanType == SCAN_PASSIVE)
6909 				chplan_new[i].ScanType = SCAN_ACTIVE;
6910 			break;
6911 		}
6912 		i++;
6913 	}
6914 }
6915 
6916 /****************************************************************************
6917 
6918 Following are the functions to report events
6919 
6920 *****************************************************************************/
6921 
report_survey_event(struct adapter * padapter,struct recv_frame * precv_frame)6922 void report_survey_event(struct adapter *padapter, struct recv_frame *precv_frame)
6923 {
6924 	struct cmd_obj *pcmd_obj;
6925 	u8 *pevtcmd;
6926 	u32 cmdsz;
6927 	struct survey_event	*psurvey_evt;
6928 	struct C2HEvent_Header *pc2h_evt_hdr;
6929 	struct mlme_ext_priv *pmlmeext;
6930 	struct cmd_priv *pcmdpriv;
6931 	/* u8 *pframe = precv_frame->rx_data; */
6932 	/* uint len = precv_frame->len; */
6933 
6934 	if (!padapter)
6935 		return;
6936 
6937 	pmlmeext = &padapter->mlmeextpriv;
6938 	pcmdpriv = &padapter->cmdpriv;
6939 
6940 	pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
6941 	if (!pcmd_obj)
6942 		return;
6943 
6944 	cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
6945 	pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
6946 	if (!pevtcmd) {
6947 		kfree(pcmd_obj);
6948 		return;
6949 	}
6950 
6951 	INIT_LIST_HEAD(&pcmd_obj->list);
6952 
6953 	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
6954 	pcmd_obj->cmdsz = cmdsz;
6955 	pcmd_obj->parmbuf = pevtcmd;
6956 
6957 	pcmd_obj->rsp = NULL;
6958 	pcmd_obj->rspsz  = 0;
6959 
6960 	pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
6961 	pc2h_evt_hdr->len = sizeof(struct survey_event);
6962 	pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
6963 	pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
6964 
6965 	psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
6966 
6967 	if (collect_bss_info(padapter, precv_frame, (struct wlan_bssid_ex *)&psurvey_evt->bss) == _FAIL) {
6968 		kfree(pcmd_obj);
6969 		kfree(pevtcmd);
6970 		return;
6971 	}
6972 
6973 	process_80211d(padapter, &psurvey_evt->bss);
6974 
6975 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
6976 
6977 	pmlmeext->sitesurvey_res.bss_cnt++;
6978 }
6979 
report_surveydone_event(struct adapter * padapter)6980 void report_surveydone_event(struct adapter *padapter)
6981 {
6982 	struct cmd_obj *pcmd_obj;
6983 	u8 *pevtcmd;
6984 	u32 cmdsz;
6985 	struct surveydone_event *psurveydone_evt;
6986 	struct C2HEvent_Header	*pc2h_evt_hdr;
6987 	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
6988 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
6989 
6990 	pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
6991 	if (!pcmd_obj)
6992 		return;
6993 
6994 	cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
6995 	pevtcmd = kzalloc(cmdsz, GFP_KERNEL);
6996 	if (!pevtcmd) {
6997 		kfree(pcmd_obj);
6998 		return;
6999 	}
7000 
7001 	INIT_LIST_HEAD(&pcmd_obj->list);
7002 
7003 	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
7004 	pcmd_obj->cmdsz = cmdsz;
7005 	pcmd_obj->parmbuf = pevtcmd;
7006 
7007 	pcmd_obj->rsp = NULL;
7008 	pcmd_obj->rspsz  = 0;
7009 
7010 	pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
7011 	pc2h_evt_hdr->len = sizeof(struct surveydone_event);
7012 	pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
7013 	pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
7014 
7015 	psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
7016 	psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
7017 
7018 	DBG_88E("survey done event(%x)\n", psurveydone_evt->bss_cnt);
7019 
7020 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
7021 }
7022 
report_join_res(struct adapter * padapter,int res)7023 void report_join_res(struct adapter *padapter, int res)
7024 {
7025 	struct cmd_obj *pcmd_obj;
7026 	u8 *pevtcmd;
7027 	u32 cmdsz;
7028 	struct joinbss_event		*pjoinbss_evt;
7029 	struct C2HEvent_Header	*pc2h_evt_hdr;
7030 	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
7031 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
7032 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
7033 
7034 	pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
7035 	if (!pcmd_obj)
7036 		return;
7037 
7038 	cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
7039 	pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
7040 	if (!pevtcmd) {
7041 		kfree(pcmd_obj);
7042 		return;
7043 	}
7044 
7045 	INIT_LIST_HEAD(&pcmd_obj->list);
7046 
7047 	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
7048 	pcmd_obj->cmdsz = cmdsz;
7049 	pcmd_obj->parmbuf = pevtcmd;
7050 
7051 	pcmd_obj->rsp = NULL;
7052 	pcmd_obj->rspsz  = 0;
7053 
7054 	pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
7055 	pc2h_evt_hdr->len = sizeof(struct joinbss_event);
7056 	pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
7057 	pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
7058 
7059 	pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
7060 	memcpy((unsigned char *)(&pjoinbss_evt->network.network), &pmlmeinfo->network, sizeof(struct wlan_bssid_ex));
7061 	pjoinbss_evt->network.join_res	= res;
7062 	pjoinbss_evt->network.aid = res;
7063 
7064 	DBG_88E("report_join_res(%d)\n", res);
7065 
7066 	rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
7067 
7068 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
7069 }
7070 
report_del_sta_event(struct adapter * padapter,unsigned char * MacAddr,unsigned short reason)7071 void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason)
7072 {
7073 	struct cmd_obj *pcmd_obj;
7074 	u8 *pevtcmd;
7075 	u32 cmdsz;
7076 	struct sta_info *psta;
7077 	int	mac_id;
7078 	struct stadel_event			*pdel_sta_evt;
7079 	struct C2HEvent_Header	*pc2h_evt_hdr;
7080 	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
7081 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
7082 
7083 	pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
7084 	if (!pcmd_obj)
7085 		return;
7086 
7087 	cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
7088 	pevtcmd = kzalloc(cmdsz, GFP_KERNEL);
7089 	if (!pevtcmd) {
7090 		kfree(pcmd_obj);
7091 		return;
7092 	}
7093 
7094 	INIT_LIST_HEAD(&pcmd_obj->list);
7095 
7096 	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
7097 	pcmd_obj->cmdsz = cmdsz;
7098 	pcmd_obj->parmbuf = pevtcmd;
7099 
7100 	pcmd_obj->rsp = NULL;
7101 	pcmd_obj->rspsz  = 0;
7102 
7103 	pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
7104 	pc2h_evt_hdr->len = sizeof(struct stadel_event);
7105 	pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
7106 	pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
7107 
7108 	pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
7109 	memcpy((unsigned char *)(&pdel_sta_evt->macaddr), MacAddr, ETH_ALEN);
7110 	memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
7111 
7112 	psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
7113 	if (psta)
7114 		mac_id = (int)psta->mac_id;
7115 	else
7116 		mac_id = (-1);
7117 
7118 	pdel_sta_evt->mac_id = mac_id;
7119 
7120 	DBG_88E("report_del_sta_event: delete STA, mac_id =%d\n", mac_id);
7121 
7122 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
7123 }
7124 
report_add_sta_event(struct adapter * padapter,unsigned char * MacAddr,int cam_idx)7125 void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int cam_idx)
7126 {
7127 	struct cmd_obj *pcmd_obj;
7128 	u8 *pevtcmd;
7129 	u32 cmdsz;
7130 	struct stassoc_event		*padd_sta_evt;
7131 	struct C2HEvent_Header	*pc2h_evt_hdr;
7132 	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
7133 	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
7134 
7135 	pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
7136 	if (!pcmd_obj)
7137 		return;
7138 
7139 	cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
7140 	pevtcmd = kzalloc(cmdsz, GFP_KERNEL);
7141 	if (!pevtcmd) {
7142 		kfree(pcmd_obj);
7143 		return;
7144 	}
7145 
7146 	INIT_LIST_HEAD(&pcmd_obj->list);
7147 
7148 	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
7149 	pcmd_obj->cmdsz = cmdsz;
7150 	pcmd_obj->parmbuf = pevtcmd;
7151 
7152 	pcmd_obj->rsp = NULL;
7153 	pcmd_obj->rspsz  = 0;
7154 
7155 	pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
7156 	pc2h_evt_hdr->len = sizeof(struct stassoc_event);
7157 	pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
7158 	pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
7159 
7160 	padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
7161 	memcpy((unsigned char *)(&padd_sta_evt->macaddr), MacAddr, ETH_ALEN);
7162 	padd_sta_evt->cam_id = cam_idx;
7163 
7164 	DBG_88E("report_add_sta_event: add STA\n");
7165 
7166 	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
7167 }
7168 
7169 /****************************************************************************
7170 
7171 Following are the event callback functions
7172 
7173 *****************************************************************************/
7174 
7175 /* for sta/adhoc mode */
update_sta_info(struct adapter * padapter,struct sta_info * psta)7176 void update_sta_info(struct adapter *padapter, struct sta_info *psta)
7177 {
7178 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7179 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
7180 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
7181 
7182 	/* ERP */
7183 	VCS_update(padapter, psta);
7184 
7185 	/* HT */
7186 	if (pmlmepriv->htpriv.ht_option) {
7187 		psta->htpriv.ht_option = true;
7188 
7189 		psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
7190 
7191 		if (support_short_GI(padapter, &pmlmeinfo->HT_caps))
7192 			psta->htpriv.sgi = true;
7193 
7194 		psta->qos_option = true;
7195 	} else {
7196 		psta->htpriv.ht_option = false;
7197 
7198 		psta->htpriv.ampdu_enable = false;
7199 
7200 		psta->htpriv.sgi = false;
7201 		psta->qos_option = false;
7202 	}
7203 	psta->htpriv.bwmode = pmlmeext->cur_bwmode;
7204 	psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
7205 
7206 	psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
7207 	psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
7208 
7209 	/* QoS */
7210 	if (pmlmepriv->qospriv.qos_option)
7211 		psta->qos_option = true;
7212 
7213 	psta->state = _FW_LINKED;
7214 }
7215 
mlmeext_joinbss_event_callback(struct adapter * padapter,int join_res)7216 void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res)
7217 {
7218 	struct sta_info		*psta, *psta_bmc;
7219 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
7220 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
7221 	struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
7222 	struct sta_priv		*pstapriv = &padapter->stapriv;
7223 	u8 join_type;
7224 	u16 media_status;
7225 
7226 	if (join_res < 0) {
7227 		join_type = 1;
7228 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
7229 		rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
7230 
7231 		/* restore to initial setting. */
7232 		update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
7233 
7234 		goto exit_mlmeext_joinbss_event_callback;
7235 	}
7236 
7237 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
7238 		/* for bc/mc */
7239 		psta_bmc = rtw_get_bcmc_stainfo(padapter);
7240 		if (psta_bmc) {
7241 			pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
7242 			update_bmc_sta_support_rate(padapter, psta_bmc->mac_id);
7243 			Update_RA_Entry(padapter, psta_bmc->mac_id);
7244 		}
7245 	}
7246 
7247 	/* turn on dynamic functions */
7248 	Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true);
7249 
7250 	/*  update IOT-releated issue */
7251 	update_IOT_info(padapter);
7252 
7253 	rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
7254 
7255 	/* BCN interval */
7256 	rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
7257 
7258 	/* udpate capability */
7259 	update_capinfo(padapter, pmlmeinfo->capability);
7260 
7261 	/* WMM, Update EDCA param */
7262 	WMMOnAssocRsp(padapter);
7263 
7264 	/* HT */
7265 	HTOnAssocRsp(padapter);
7266 
7267 	set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
7268 
7269 	psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
7270 	if (psta) { /* only for infra. mode */
7271 		pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
7272 
7273 		psta->wireless_mode = pmlmeext->cur_wireless_mode;
7274 
7275 		/* set per sta rate after updating HT cap. */
7276 		set_sta_rate(padapter, psta);
7277 		rtw_hal_set_hwreg(padapter, HW_VAR_TX_RPT_MAX_MACID, (u8 *)&psta->mac_id);
7278 		media_status = (psta->mac_id << 8) | 1; /*   MACID|OPMODE: 1 means connect */
7279 		rtw_hal_set_hwreg(padapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
7280 	}
7281 
7282 	join_type = 2;
7283 	rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
7284 
7285 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
7286 		/*  correcting TSF */
7287 		correct_TSF(padapter, pmlmeext);
7288 	}
7289 	rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
7290 
7291 exit_mlmeext_joinbss_event_callback:
7292 
7293 	DBG_88E("=>%s\n", __func__);
7294 }
7295 
mlmeext_sta_add_event_callback(struct adapter * padapter,struct sta_info * psta)7296 void mlmeext_sta_add_event_callback(struct adapter *padapter, struct sta_info *psta)
7297 {
7298 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
7299 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
7300 	u8 join_type;
7301 
7302 	DBG_88E("%s\n", __func__);
7303 
7304 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
7305 		if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {/* adhoc master or sta_count>1 */
7306 			/* nothing to do */
7307 		} else { /* adhoc client */
7308 			/*  correcting TSF */
7309 			correct_TSF(padapter, pmlmeext);
7310 
7311 			/* start beacon */
7312 			if (send_beacon(padapter) == _FAIL) {
7313 				pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
7314 				pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
7315 				return;
7316 			}
7317 			pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
7318 		}
7319 
7320 		join_type = 2;
7321 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
7322 	}
7323 
7324 	pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
7325 
7326 	/* rate radaptive */
7327 	Update_RA_Entry(padapter, psta->mac_id);
7328 
7329 	/* update adhoc sta_info */
7330 	update_sta_info(padapter, psta);
7331 }
7332 
mlmeext_sta_del_event_callback(struct adapter * padapter)7333 void mlmeext_sta_del_event_callback(struct adapter *padapter)
7334 {
7335 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
7336 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
7337 
7338 	if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter)) {
7339 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL);
7340 		rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
7341 
7342 		/* restore to initial setting. */
7343 		update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
7344 
7345 		/* switch to the 20M Hz mode after disconnect */
7346 		pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
7347 		pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7348 
7349 		/* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
7350 		set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
7351 
7352 		flush_all_cam_entry(padapter);
7353 
7354 		pmlmeinfo->state = WIFI_FW_NULL_STATE;
7355 
7356 		/* set MSR to no link state -> infra. mode */
7357 		Set_MSR(padapter, _HW_STATE_STATION_);
7358 
7359 		_cancel_timer_ex(&pmlmeext->link_timer);
7360 	}
7361 }
7362 
7363 /****************************************************************************
7364 
7365 Following are the functions for the timer handlers
7366 
7367 *****************************************************************************/
7368 void _linked_rx_signal_strehgth_display(struct adapter *padapter);
_linked_rx_signal_strehgth_display(struct adapter * padapter)7369 void _linked_rx_signal_strehgth_display(struct adapter *padapter)
7370 {
7371 	struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
7372 	struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
7373 	u8 mac_id;
7374 	int UndecoratedSmoothedPWDB;
7375 
7376 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
7377 		mac_id = 0;
7378 	else if ((pmlmeinfo->state & 0x03) == _HW_STATE_AP_)
7379 		mac_id = 2;
7380 
7381 	rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &mac_id);
7382 
7383 	rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
7384 	DBG_88E("UndecoratedSmoothedPWDB:%d\n", UndecoratedSmoothedPWDB);
7385 }
7386 
chk_ap_is_alive(struct adapter * padapter,struct sta_info * psta)7387 static u8 chk_ap_is_alive(struct adapter *padapter, struct sta_info *psta)
7388 {
7389 	u8 ret = false;
7390 
7391 	if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) &&
7392 	    sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) &&
7393 	    sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
7394 		ret = false;
7395 	else
7396 		ret = true;
7397 
7398 	sta_update_last_rx_pkts(psta);
7399 
7400 	return ret;
7401 }
7402 
linked_status_chk(struct adapter * padapter)7403 void linked_status_chk(struct adapter *padapter)
7404 {
7405 	u32	i;
7406 	struct sta_info		*psta;
7407 	struct xmit_priv		*pxmitpriv = &padapter->xmitpriv;
7408 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
7409 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
7410 	struct sta_priv		*pstapriv = &padapter->stapriv;
7411 
7412 	if (padapter->bRxRSSIDisplay)
7413 		_linked_rx_signal_strehgth_display(padapter);
7414 
7415 	rtw_hal_sreset_linked_status_check(padapter);
7416 
7417 	if (is_client_associated_to_ap(padapter)) {
7418 		/* linked infrastructure client mode */
7419 
7420 		int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
7421 		int rx_chk_limit;
7422 
7423 		rx_chk_limit = 4;
7424 		psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
7425 		if (psta) {
7426 			bool is_p2p_enable = false;
7427 			#ifdef CONFIG_88EU_P2P
7428 			is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
7429 			#endif
7430 
7431 			if (!chk_ap_is_alive(padapter, psta))
7432 				rx_chk = _FAIL;
7433 
7434 			if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
7435 				tx_chk = _FAIL;
7436 
7437 			if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
7438 				u8 backup_oper_channel = 0;
7439 
7440 				/* switch to correct channel of current network  before issue keep-alive frames */
7441 				if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
7442 					backup_oper_channel = rtw_get_oper_ch(padapter);
7443 					SelectChannel(padapter, pmlmeext->cur_channel);
7444 				}
7445 
7446 				if (rx_chk != _SUCCESS)
7447 					issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
7448 
7449 				if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) {
7450 					tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
7451 					/* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
7452 					if (tx_chk == _SUCCESS && !is_p2p_enable)
7453 						rx_chk = _SUCCESS;
7454 				}
7455 
7456 				/* back to the original operation channel */
7457 				if (backup_oper_channel > 0)
7458 					SelectChannel(padapter, backup_oper_channel);
7459 			} else {
7460 				if (rx_chk != _SUCCESS) {
7461 					if (pmlmeext->retry == 0) {
7462 						issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
7463 						issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
7464 						issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
7465 					}
7466 				}
7467 
7468 				if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) {
7469 					tx_chk = issue_nulldata(padapter, NULL, 0, 1, 0);
7470 				}
7471 			}
7472 
7473 			if (rx_chk == _FAIL) {
7474 				pmlmeext->retry++;
7475 				if (pmlmeext->retry > rx_chk_limit) {
7476 					DBG_88E_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
7477 						      FUNC_ADPT_ARG(padapter));
7478 					receive_disconnect(padapter, pmlmeinfo->network.MacAddress,
7479 							   WLAN_REASON_EXPIRATION_CHK);
7480 					return;
7481 				}
7482 			} else {
7483 				pmlmeext->retry = 0;
7484 			}
7485 
7486 			if (tx_chk == _FAIL) {
7487 				pmlmeinfo->link_count &= 0xf;
7488 			} else {
7489 				pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
7490 				pmlmeinfo->link_count = 0;
7491 			}
7492 		} /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */
7493 	} else if (is_client_associated_to_ibss(padapter)) {
7494 		/* linked IBSS mode */
7495 		/* for each assoc list entry to check the rx pkt counter */
7496 		for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
7497 			if (pmlmeinfo->FW_sta_info[i].status == 1) {
7498 				psta = pmlmeinfo->FW_sta_info[i].psta;
7499 
7500 				if (NULL == psta)
7501 					continue;
7502 				if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta)) {
7503 					if (pmlmeinfo->FW_sta_info[i].retry < 3) {
7504 						pmlmeinfo->FW_sta_info[i].retry++;
7505 					} else {
7506 						pmlmeinfo->FW_sta_info[i].retry = 0;
7507 						pmlmeinfo->FW_sta_info[i].status = 0;
7508 						report_del_sta_event(padapter, psta->hwaddr
7509 							, 65535/*  indicate disconnect caused by no rx */
7510 					);
7511 					}
7512 				} else {
7513 					pmlmeinfo->FW_sta_info[i].retry = 0;
7514 					pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
7515 				}
7516 			}
7517 		}
7518 	}
7519 }
7520 
survey_timer_hdl(struct adapter * padapter)7521 void survey_timer_hdl(struct adapter *padapter)
7522 {
7523 	struct cmd_obj	*ph2c;
7524 	struct sitesurvey_parm	*psurveyPara;
7525 	struct cmd_priv					*pcmdpriv = &padapter->cmdpriv;
7526 	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
7527 #ifdef CONFIG_88EU_P2P
7528 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
7529 #endif
7530 
7531 	/* issue rtw_sitesurvey_cmd */
7532 	if (pmlmeext->sitesurvey_res.state > SCAN_START) {
7533 		if (pmlmeext->sitesurvey_res.state ==  SCAN_PROCESS)
7534 			pmlmeext->sitesurvey_res.channel_idx++;
7535 
7536 		if (pmlmeext->scan_abort) {
7537 			#ifdef CONFIG_88EU_P2P
7538 			if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) {
7539 				rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
7540 				pmlmeext->sitesurvey_res.channel_idx = 3;
7541 				DBG_88E("%s idx:%d, cnt:%u\n", __func__
7542 					, pmlmeext->sitesurvey_res.channel_idx
7543 					, pwdinfo->find_phase_state_exchange_cnt
7544 			);
7545 			} else
7546 			#endif
7547 			{
7548 				pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
7549 				DBG_88E("%s idx:%d\n", __func__
7550 					, pmlmeext->sitesurvey_res.channel_idx
7551 			);
7552 			}
7553 
7554 			pmlmeext->scan_abort = false;/* reset */
7555 		}
7556 
7557 		ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
7558 		if (!ph2c)
7559 			goto exit_survey_timer_hdl;
7560 
7561 		psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
7562 		if (!psurveyPara) {
7563 			kfree(ph2c);
7564 			goto exit_survey_timer_hdl;
7565 		}
7566 
7567 		init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
7568 		rtw_enqueue_cmd(pcmdpriv, ph2c);
7569 	}
7570 
7571 exit_survey_timer_hdl:
7572 	return;
7573 }
7574 
link_timer_hdl(struct adapter * padapter)7575 void link_timer_hdl(struct adapter *padapter)
7576 {
7577 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
7578 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
7579 
7580 	if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
7581 		DBG_88E("link_timer_hdl:no beacon while connecting\n");
7582 		pmlmeinfo->state = WIFI_FW_NULL_STATE;
7583 		report_join_res(padapter, -3);
7584 	} else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
7585 		/* re-auth timer */
7586 		if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
7587 			pmlmeinfo->state = 0;
7588 			report_join_res(padapter, -1);
7589 			return;
7590 		}
7591 
7592 		DBG_88E("link_timer_hdl: auth timeout and try again\n");
7593 		pmlmeinfo->auth_seq = 1;
7594 		issue_auth(padapter, NULL, 0);
7595 		set_link_timer(pmlmeext, REAUTH_TO);
7596 	} else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
7597 		/* re-assoc timer */
7598 		if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
7599 			pmlmeinfo->state = WIFI_FW_NULL_STATE;
7600 			report_join_res(padapter, -2);
7601 			return;
7602 		}
7603 
7604 		DBG_88E("link_timer_hdl: assoc timeout and try again\n");
7605 		issue_assocreq(padapter);
7606 		set_link_timer(pmlmeext, REASSOC_TO);
7607 	}
7608 }
7609 
addba_timer_hdl(struct sta_info * psta)7610 void addba_timer_hdl(struct sta_info *psta)
7611 {
7612 	struct ht_priv	*phtpriv;
7613 
7614 	if (!psta)
7615 		return;
7616 
7617 	phtpriv = &psta->htpriv;
7618 
7619 	if ((phtpriv->ht_option) && (phtpriv->ampdu_enable)) {
7620 		if (phtpriv->candidate_tid_bitmap)
7621 			phtpriv->candidate_tid_bitmap = 0x0;
7622 	}
7623 }
7624 
NULL_hdl(struct adapter * padapter,u8 * pbuf)7625 u8 NULL_hdl(struct adapter *padapter, u8 *pbuf)
7626 {
7627 	return H2C_SUCCESS;
7628 }
7629 
setopmode_hdl(struct adapter * padapter,u8 * pbuf)7630 u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf)
7631 {
7632 	u8 type;
7633 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
7634 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
7635 	struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
7636 
7637 	if (psetop->mode == Ndis802_11APMode) {
7638 		pmlmeinfo->state = WIFI_FW_AP_STATE;
7639 		type = _HW_STATE_AP_;
7640 	} else if (psetop->mode == Ndis802_11Infrastructure) {
7641 		pmlmeinfo->state &= ~(BIT(0) | BIT(1));/*  clear state */
7642 		pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to	STATION_STATE */
7643 		type = _HW_STATE_STATION_;
7644 	} else if (psetop->mode == Ndis802_11IBSS) {
7645 		type = _HW_STATE_ADHOC_;
7646 	} else {
7647 		type = _HW_STATE_NOLINK_;
7648 	}
7649 
7650 	rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
7651 	/* Set_NETYPE0_MSR(padapter, type); */
7652 
7653 	return H2C_SUCCESS;
7654 }
7655 
createbss_hdl(struct adapter * padapter,u8 * pbuf)7656 u8 createbss_hdl(struct adapter *padapter, u8 *pbuf)
7657 {
7658 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
7659 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
7660 	struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network);
7661 	struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
7662 	/* u32	initialgain; */
7663 
7664 	if (pparm->network.InfrastructureMode == Ndis802_11APMode) {
7665 #ifdef CONFIG_88EU_AP_MODE
7666 
7667 		if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
7668 			/* todo: */
7669 			return H2C_SUCCESS;
7670 		}
7671 #endif
7672 	}
7673 
7674 	/* below is for ad-hoc master */
7675 	if (pparm->network.InfrastructureMode == Ndis802_11IBSS) {
7676 		rtw_joinbss_reset(padapter);
7677 
7678 		pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
7679 		pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7680 		pmlmeinfo->ERP_enable = 0;
7681 		pmlmeinfo->WMM_enable = 0;
7682 		pmlmeinfo->HT_enable = 0;
7683 		pmlmeinfo->HT_caps_enable = 0;
7684 		pmlmeinfo->HT_info_enable = 0;
7685 		pmlmeinfo->agg_enable_bitmap = 0;
7686 		pmlmeinfo->candidate_tid_bitmap = 0;
7687 
7688 		/* disable dynamic functions, such as high power, DIG */
7689 		Save_DM_Func_Flag(padapter);
7690 		Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
7691 
7692 		/* config the initial gain under linking, need to write the BB registers */
7693 		/* initialgain = 0x1E; */
7694 		/* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
7695 
7696 		/* cancel link timer */
7697 		_cancel_timer_ex(&pmlmeext->link_timer);
7698 
7699 		/* clear CAM */
7700 		flush_all_cam_entry(padapter);
7701 
7702 		memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength));
7703 		pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength;
7704 
7705 		if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
7706 			return H2C_PARAMETERS_ERROR;
7707 
7708 		memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength);
7709 
7710 		start_create_ibss(padapter);
7711 	}
7712 
7713 	return H2C_SUCCESS;
7714 }
7715 
join_cmd_hdl(struct adapter * padapter,u8 * pbuf)7716 u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
7717 {
7718 	u8 join_type;
7719 	struct ndis_802_11_var_ie *pIE;
7720 	struct registry_priv	*pregpriv = &padapter->registrypriv;
7721 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
7722 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
7723 	struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network);
7724 	struct joinbss_parm	*pparm = (struct joinbss_parm *)pbuf;
7725 	u32 i;
7726 
7727 	/* check already connecting to AP or not */
7728 	if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
7729 		if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
7730 			issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 5, 100);
7731 
7732 		pmlmeinfo->state = WIFI_FW_NULL_STATE;
7733 
7734 		/* clear CAM */
7735 		flush_all_cam_entry(padapter);
7736 
7737 		_cancel_timer_ex(&pmlmeext->link_timer);
7738 
7739 		/* set MSR to nolink -> infra. mode */
7740 		Set_MSR(padapter, _HW_STATE_STATION_);
7741 
7742 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL);
7743 	}
7744 
7745 	rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, false);
7746 
7747 	rtw_joinbss_reset(padapter);
7748 
7749 	pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
7750 	pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7751 	pmlmeinfo->ERP_enable = 0;
7752 	pmlmeinfo->WMM_enable = 0;
7753 	pmlmeinfo->HT_enable = 0;
7754 	pmlmeinfo->HT_caps_enable = 0;
7755 	pmlmeinfo->HT_info_enable = 0;
7756 	pmlmeinfo->agg_enable_bitmap = 0;
7757 	pmlmeinfo->candidate_tid_bitmap = 0;
7758 	pmlmeinfo->bwmode_updated = false;
7759 
7760 	memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength));
7761 	pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength;
7762 
7763 	if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
7764 		return H2C_PARAMETERS_ERROR;
7765 
7766 	memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength);
7767 
7768 	/* Check AP vendor to move rtw_joinbss_cmd() */
7769 
7770 	for (i = sizeof(struct ndis_802_11_fixed_ie); i < pnetwork->IELength;) {
7771 		pIE = (struct ndis_802_11_var_ie *)(pnetwork->IEs + i);
7772 
7773 		switch (pIE->ElementID) {
7774 		case _VENDOR_SPECIFIC_IE_:/* Get WMM IE. */
7775 			if (!memcmp(pIE->data, WMM_OUI, 4))
7776 				pmlmeinfo->WMM_enable = 1;
7777 			break;
7778 		case _HT_CAPABILITY_IE_:	/* Get HT Cap IE. */
7779 			pmlmeinfo->HT_caps_enable = 1;
7780 			break;
7781 		case _HT_EXTRA_INFO_IE_:	/* Get HT Info IE. */
7782 			pmlmeinfo->HT_info_enable = 1;
7783 
7784 			/* spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz */
7785 			{
7786 				struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data);
7787 
7788 				if ((pregpriv->cbw40_enable) &&	 (pht_info->infos[0] & BIT(2))) {
7789 					/* switch to the 40M Hz mode according to the AP */
7790 					pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
7791 					switch (pht_info->infos[0] & 0x3) {
7792 					case 1:
7793 						pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
7794 						break;
7795 					case 3:
7796 						pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
7797 						break;
7798 					default:
7799 						pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7800 						break;
7801 				}
7802 
7803 					DBG_88E("set ch/bw before connected\n");
7804 				}
7805 			}
7806 			break;
7807 		default:
7808 			break;
7809 		}
7810 
7811 		i += (pIE->Length + 2);
7812 	}
7813 	/* disable dynamic functions, such as high power, DIG */
7814 
7815 	/* config the initial gain under linking, need to write the BB registers */
7816 
7817 	rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
7818 	join_type = 0;
7819 	rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
7820 
7821 	/* cancel link timer */
7822 	_cancel_timer_ex(&pmlmeext->link_timer);
7823 
7824 	start_clnt_join(padapter);
7825 
7826 	return H2C_SUCCESS;
7827 }
7828 
disconnect_hdl(struct adapter * padapter,unsigned char * pbuf)7829 u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf)
7830 {
7831 	struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
7832 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
7833 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
7834 	struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network);
7835 	u8 val8;
7836 
7837 	if (is_client_associated_to_ap(padapter))
7838 		issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms / 100, 100);
7839 
7840 	rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL);
7841 	rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
7842 
7843 	/* restore to initial setting. */
7844 	update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
7845 
7846 	if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
7847 		/* Stop BCN */
7848 		val8 = 0;
7849 		rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
7850 	}
7851 
7852 	/* set MSR to no link state -> infra. mode */
7853 	Set_MSR(padapter, _HW_STATE_STATION_);
7854 
7855 	pmlmeinfo->state = WIFI_FW_NULL_STATE;
7856 
7857 	/* switch to the 20M Hz mode after disconnect */
7858 	pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
7859 	pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7860 
7861 	set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
7862 
7863 	flush_all_cam_entry(padapter);
7864 
7865 	_cancel_timer_ex(&pmlmeext->link_timer);
7866 
7867 	rtw_free_uc_swdec_pending_queue(padapter);
7868 
7869 	return	H2C_SUCCESS;
7870 }
7871 
rtw_scan_ch_decision(struct adapter * padapter,struct rtw_ieee80211_channel * out,u32 out_num,struct rtw_ieee80211_channel * in,u32 in_num)7872 static int rtw_scan_ch_decision(struct adapter *padapter, struct rtw_ieee80211_channel *out,
7873 	u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
7874 {
7875 	int i, j;
7876 	int set_idx;
7877 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
7878 
7879 	/* clear out first */
7880 	memset(out, 0, sizeof(struct rtw_ieee80211_channel) * out_num);
7881 
7882 	/* acquire channels from in */
7883 	j = 0;
7884 	for (i = 0; i < in_num; i++) {
7885 		set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value);
7886 		if (in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED) &&
7887 		    set_idx >= 0) {
7888 			memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
7889 
7890 			if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
7891 				out[j].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
7892 
7893 			j++;
7894 		}
7895 		if (j >= out_num)
7896 			break;
7897 	}
7898 
7899 	/* if out is empty, use channel_set as default */
7900 	if (j == 0) {
7901 		for (i = 0; i < pmlmeext->max_chan_nums; i++) {
7902 			out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
7903 
7904 			if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
7905 				out[i].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
7906 
7907 			j++;
7908 		}
7909 	}
7910 
7911 	return j;
7912 }
7913 
sitesurvey_cmd_hdl(struct adapter * padapter,u8 * pbuf)7914 u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf)
7915 {
7916 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
7917 	struct sitesurvey_parm	*pparm = (struct sitesurvey_parm *)pbuf;
7918 	u8 bdelayscan = false;
7919 	u8 val8;
7920 	u32	initialgain;
7921 	u32	i;
7922 
7923 #ifdef CONFIG_88EU_P2P
7924 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
7925 #endif
7926 
7927 	if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
7928 		/* for first time sitesurvey_cmd */
7929 		rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, NULL);
7930 
7931 		pmlmeext->sitesurvey_res.state = SCAN_START;
7932 		pmlmeext->sitesurvey_res.bss_cnt = 0;
7933 		pmlmeext->sitesurvey_res.channel_idx = 0;
7934 
7935 		for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
7936 			if (pparm->ssid[i].SsidLength) {
7937 				memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
7938 				pmlmeext->sitesurvey_res.ssid[i].SsidLength = pparm->ssid[i].SsidLength;
7939 			} else {
7940 				pmlmeext->sitesurvey_res.ssid[i].SsidLength = 0;
7941 			}
7942 		}
7943 
7944 		pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter
7945 			, pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT
7946 			, pparm->ch, pparm->ch_num
7947 	);
7948 
7949 		pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
7950 
7951 		/* issue null data if associating to the AP */
7952 		if (is_client_associated_to_ap(padapter)) {
7953 			pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
7954 
7955 			issue_nulldata(padapter, NULL, 1, 3, 500);
7956 
7957 			bdelayscan = true;
7958 		}
7959 		if (bdelayscan) {
7960 			/* delay 50ms to protect nulldata(1). */
7961 			set_survey_timer(pmlmeext, 50);
7962 			return H2C_SUCCESS;
7963 		}
7964 	}
7965 
7966 	if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) {
7967 		/* disable dynamic functions, such as high power, DIG */
7968 		Save_DM_Func_Flag(padapter);
7969 		Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
7970 
7971 		/* config the initial gain under scanning, need to write the BB registers */
7972 #ifdef CONFIG_88EU_P2P
7973 		if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
7974 			initialgain = 0x1E;
7975 		else
7976 			initialgain = 0x28;
7977 #else	/*  CONFIG_88EU_P2P */
7978 		initialgain = 0x1E;
7979 #endif /*  CONFIG_88EU_P2P */
7980 
7981 		rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
7982 
7983 		/* set MSR to no link state */
7984 		Set_MSR(padapter, _HW_STATE_NOLINK_);
7985 
7986 		val8 = 1; /* under site survey */
7987 		rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
7988 
7989 		pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
7990 	}
7991 
7992 	site_survey(padapter);
7993 
7994 	return H2C_SUCCESS;
7995 }
7996 
setauth_hdl(struct adapter * padapter,unsigned char * pbuf)7997 u8 setauth_hdl(struct adapter *padapter, unsigned char *pbuf)
7998 {
7999 	struct setauth_parm		*pparm = (struct setauth_parm *)pbuf;
8000 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
8001 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
8002 
8003 	if (pparm->mode < 4)
8004 		pmlmeinfo->auth_algo = pparm->mode;
8005 	return	H2C_SUCCESS;
8006 }
8007 
setkey_hdl(struct adapter * padapter,u8 * pbuf)8008 u8 setkey_hdl(struct adapter *padapter, u8 *pbuf)
8009 {
8010 	unsigned short				ctrl;
8011 	struct setkey_parm		*pparm = (struct setkey_parm *)pbuf;
8012 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
8013 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
8014 	unsigned char					null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
8015 
8016 	/* main tx key for wep. */
8017 	if (pparm->set_tx)
8018 		pmlmeinfo->key_index = pparm->keyid;
8019 
8020 	/* write cam */
8021 	ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
8022 
8023 	DBG_88E_LEVEL(_drv_info_, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
8024 			"keyid:%d\n", pparm->algorithm, pparm->keyid);
8025 	write_cam(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
8026 
8027 	return H2C_SUCCESS;
8028 }
8029 
set_stakey_hdl(struct adapter * padapter,u8 * pbuf)8030 u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf)
8031 {
8032 	u16 ctrl = 0;
8033 	u8 cam_id;/* cam_entry */
8034 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
8035 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
8036 	struct set_stakey_parm	*pparm = (struct set_stakey_parm *)pbuf;
8037 
8038 	/* cam_entry: */
8039 	/* 0~3 for default key */
8040 
8041 	/* for concurrent mode (ap+sta): */
8042 	/* default key is disable, using sw encrypt/decrypt */
8043 	/* cam_entry = 4 for sta mode (macid = 0) */
8044 	/* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
8045 
8046 	/* for concurrent mode (sta+sta): */
8047 	/* default key is disable, using sw encrypt/decrypt */
8048 	/* cam_entry = 4 mapping to macid = 0 */
8049 	/* cam_entry = 5 mapping to macid = 2 */
8050 
8051 	cam_id = 4;
8052 
8053 	DBG_88E_LEVEL(_drv_info_, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n",
8054 		      pparm->algorithm, cam_id);
8055 	if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
8056 		struct sta_info *psta;
8057 		struct sta_priv *pstapriv = &padapter->stapriv;
8058 
8059 		if (pparm->algorithm == _NO_PRIVACY_)	/*  clear cam entry */ {
8060 			clear_cam_entry(padapter, pparm->id);
8061 			return H2C_SUCCESS_RSP;
8062 		}
8063 
8064 		psta = rtw_get_stainfo(pstapriv, pparm->addr);
8065 		if (psta) {
8066 			ctrl = (BIT(15) | ((pparm->algorithm) << 2));
8067 
8068 			DBG_88E("r871x_set_stakey_hdl(): enc_algorithm=%d\n", pparm->algorithm);
8069 
8070 			if ((psta->mac_id < 1) || (psta->mac_id > (NUM_STA - 4))) {
8071 				DBG_88E("r871x_set_stakey_hdl():set_stakey failed, mac_id(aid)=%d\n", psta->mac_id);
8072 				return H2C_REJECTED;
8073 			}
8074 
8075 			cam_id = (psta->mac_id + 3);/* 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
8076 
8077 			DBG_88E("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, cam_entry=%d\n", pparm->addr[0],
8078 				pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4],
8079 				pparm->addr[5], cam_id);
8080 
8081 			write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
8082 
8083 			return H2C_SUCCESS_RSP;
8084 		} else {
8085 			DBG_88E("r871x_set_stakey_hdl(): sta has been free\n");
8086 			return H2C_REJECTED;
8087 		}
8088 	}
8089 
8090 	/* below for sta mode */
8091 
8092 	if (pparm->algorithm == _NO_PRIVACY_) {	/*  clear cam entry */
8093 		clear_cam_entry(padapter, pparm->id);
8094 		return H2C_SUCCESS;
8095 	}
8096 	ctrl = BIT(15) | ((pparm->algorithm) << 2);
8097 	write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
8098 	pmlmeinfo->enc_algo = pparm->algorithm;
8099 	return H2C_SUCCESS;
8100 }
8101 
add_ba_hdl(struct adapter * padapter,unsigned char * pbuf)8102 u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf)
8103 {
8104 	struct addBaReq_parm	*pparm = (struct addBaReq_parm *)pbuf;
8105 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
8106 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
8107 
8108 	struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
8109 
8110 	if (!psta)
8111 		return	H2C_SUCCESS;
8112 
8113 	if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
8114 	    ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
8115 		issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
8116 		_set_timer(&psta->addba_retry_timer, ADDBA_TO);
8117 	} else {
8118 		psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
8119 	}
8120 	return	H2C_SUCCESS;
8121 }
8122 
set_tx_beacon_cmd(struct adapter * padapter)8123 u8 set_tx_beacon_cmd(struct adapter *padapter)
8124 {
8125 	struct cmd_obj	*ph2c;
8126 	struct Tx_Beacon_param	*ptxBeacon_parm;
8127 	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
8128 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
8129 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
8130 	u8 res = _SUCCESS;
8131 	int len_diff = 0;
8132 
8133 	ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
8134 	if (!ph2c) {
8135 		res = _FAIL;
8136 		goto exit;
8137 	}
8138 
8139 	ptxBeacon_parm = kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC);
8140 	if (!ptxBeacon_parm) {
8141 		kfree(ph2c);
8142 		res = _FAIL;
8143 		goto exit;
8144 	}
8145 
8146 	memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network, sizeof(struct wlan_bssid_ex));
8147 
8148 	len_diff = update_hidden_ssid(ptxBeacon_parm->network.IEs + _BEACON_IE_OFFSET_,
8149 				      ptxBeacon_parm->network.IELength - _BEACON_IE_OFFSET_,
8150 				      pmlmeinfo->hidden_ssid_mode);
8151 	ptxBeacon_parm->network.IELength += len_diff;
8152 
8153 	init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
8154 
8155 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
8156 
8157 exit:
8158 
8159 	return res;
8160 }
8161 
mlme_evt_hdl(struct adapter * padapter,unsigned char * pbuf)8162 u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf)
8163 {
8164 	u8 evt_code;
8165 	u16 evt_sz;
8166 	uint	*peventbuf;
8167 	void (*event_callback)(struct adapter *dev, u8 *pbuf);
8168 	struct evt_priv *pevt_priv = &padapter->evtpriv;
8169 
8170 	peventbuf = (uint *)pbuf;
8171 	evt_sz = (u16)(*peventbuf & 0xffff);
8172 	evt_code = (u8)((*peventbuf >> 16) & 0xff);
8173 
8174 	/*  checking if event code is valid */
8175 	if (evt_code >= MAX_C2HEVT)
8176 		goto _abort_event_;
8177 
8178 	/*  checking if event size match the event parm size */
8179 	if ((wlanevents[evt_code].parmsize != 0) &&
8180 	    (wlanevents[evt_code].parmsize != evt_sz))
8181 		goto _abort_event_;
8182 
8183 	atomic_inc(&pevt_priv->event_seq);
8184 
8185 	peventbuf += 2;
8186 
8187 	if (peventbuf) {
8188 		event_callback = wlanevents[evt_code].event_callback;
8189 		event_callback(padapter, (u8 *)peventbuf);
8190 
8191 		pevt_priv->evt_done_cnt++;
8192 	}
8193 
8194 _abort_event_:
8195 	return H2C_SUCCESS;
8196 }
8197 
h2c_msg_hdl(struct adapter * padapter,unsigned char * pbuf)8198 u8 h2c_msg_hdl(struct adapter *padapter, unsigned char *pbuf)
8199 {
8200 	if (!pbuf)
8201 		return H2C_PARAMETERS_ERROR;
8202 
8203 	return H2C_SUCCESS;
8204 }
8205 
tx_beacon_hdl(struct adapter * padapter,unsigned char * pbuf)8206 u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf)
8207 {
8208 	if (send_beacon(padapter) == _FAIL) {
8209 		DBG_88E("issue_beacon, fail!\n");
8210 		return H2C_PARAMETERS_ERROR;
8211 	}
8212 #ifdef CONFIG_88EU_AP_MODE
8213 	else { /* tx bc/mc frames after update TIM */
8214 		struct sta_info *psta_bmc;
8215 		struct list_head *xmitframe_plist, *xmitframe_phead;
8216 		struct xmit_frame *pxmitframe = NULL;
8217 		struct sta_priv  *pstapriv = &padapter->stapriv;
8218 
8219 		/* for BC/MC Frames */
8220 		psta_bmc = rtw_get_bcmc_stainfo(padapter);
8221 		if (!psta_bmc)
8222 			return H2C_SUCCESS;
8223 
8224 		if ((pstapriv->tim_bitmap & BIT(0)) && (psta_bmc->sleepq_len > 0)) {
8225 			msleep(10);/*  10ms, ATIM(HIQ) Windows */
8226 			spin_lock_bh(&psta_bmc->sleep_q.lock);
8227 
8228 			xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
8229 			xmitframe_plist = xmitframe_phead->next;
8230 
8231 			while (xmitframe_phead != xmitframe_plist) {
8232 				pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
8233 
8234 				xmitframe_plist = xmitframe_plist->next;
8235 
8236 				list_del_init(&pxmitframe->list);
8237 
8238 				psta_bmc->sleepq_len--;
8239 				if (psta_bmc->sleepq_len > 0)
8240 					pxmitframe->attrib.mdata = 1;
8241 				else
8242 					pxmitframe->attrib.mdata = 0;
8243 
8244 				pxmitframe->attrib.triggered = 1;
8245 
8246 				pxmitframe->attrib.qsel = 0x11;/* HIQ */
8247 
8248 				spin_unlock_bh(&psta_bmc->sleep_q.lock);
8249 				if (rtw_hal_xmit(padapter, pxmitframe))
8250 					rtw_os_xmit_complete(padapter, pxmitframe);
8251 				spin_lock_bh(&psta_bmc->sleep_q.lock);
8252 			}
8253 			spin_unlock_bh(&psta_bmc->sleep_q.lock);
8254 		}
8255 	}
8256 #endif
8257 	return H2C_SUCCESS;
8258 }
8259 
set_ch_hdl(struct adapter * padapter,u8 * pbuf)8260 u8 set_ch_hdl(struct adapter *padapter, u8 *pbuf)
8261 {
8262 	struct set_ch_parm *set_ch_parm;
8263 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
8264 
8265 	if (!pbuf)
8266 		return H2C_PARAMETERS_ERROR;
8267 
8268 	set_ch_parm = (struct set_ch_parm *)pbuf;
8269 
8270 	DBG_88E(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
8271 		FUNC_NDEV_ARG(padapter->pnetdev),
8272 		set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
8273 
8274 	pmlmeext->cur_channel = set_ch_parm->ch;
8275 	pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
8276 	pmlmeext->cur_bwmode = set_ch_parm->bw;
8277 
8278 	set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
8279 
8280 	return	H2C_SUCCESS;
8281 }
8282 
set_chplan_hdl(struct adapter * padapter,unsigned char * pbuf)8283 u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf)
8284 {
8285 	struct SetChannelPlan_param *setChannelPlan_param;
8286 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
8287 
8288 	if (!pbuf)
8289 		return H2C_PARAMETERS_ERROR;
8290 
8291 	setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
8292 
8293 	pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
8294 	init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
8295 
8296 	return	H2C_SUCCESS;
8297 }
8298 
led_blink_hdl(struct adapter * padapter,unsigned char * pbuf)8299 u8 led_blink_hdl(struct adapter *padapter, unsigned char *pbuf)
8300 {
8301 	if (!pbuf)
8302 		return H2C_PARAMETERS_ERROR;
8303 	return	H2C_SUCCESS;
8304 }
8305 
set_csa_hdl(struct adapter * padapter,unsigned char * pbuf)8306 u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf)
8307 {
8308 	return	H2C_REJECTED;
8309 }
8310 
8311 /*  TDLS_WRCR		: write RCR DATA BIT */
8312 /*  TDLS_SD_PTI		: issue peer traffic indication */
8313 /*  TDLS_CS_OFF		: go back to the channel linked with AP, terminating channel switch procedure */
8314 /*  TDLS_INIT_CH_SEN	: init channel sensing, receive all data and mgnt frame */
8315 /*  TDLS_DONE_CH_SEN: channel sensing and report candidate channel */
8316 /*  TDLS_OFF_CH		: first time set channel to off channel */
8317 /*  TDLS_BASE_CH		: go back tp the channel linked with AP when set base channel as target channel */
8318 /*  TDLS_P_OFF_CH	: periodically go to off channel */
8319 /*  TDLS_P_BASE_CH	: periodically go back to base channel */
8320 /*  TDLS_RS_RCR		: restore RCR */
8321 /*  TDLS_CKALV_PH1	: check alive timer phase1 */
8322 /*  TDLS_CKALV_PH2	: check alive timer phase2 */
8323 /*  TDLS_FREE_STA	: free tdls sta */
tdls_hdl(struct adapter * padapter,unsigned char * pbuf)8324 u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf)
8325 {
8326 	return H2C_REJECTED;
8327 }
8328