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, ®);
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, ®);
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, ®32);
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, ®);
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, ®);
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, ®);
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