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