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