1
2
3
4
5
6
7#include <drv_types.h>
8#include <rtw_debug.h>
9#include <rtw_wifi_regd.h>
10#include <hal_btcoex.h>
11#include <linux/kernel.h>
12#include <asm/unaligned.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 {WIFI_ACTION_NOACK, "OnActionNoAck", &OnAction},
34};
35
36static struct action_handler OnAction_tbl[] = {
37 {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct},
38 {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &DoReserved},
39 {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &DoReserved},
40 {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
41 {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
42 {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved},
43 {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved},
44 {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht},
45 {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query},
46 {RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved},
47 {RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &DoReserved},
48 {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &DoReserved},
49 {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &DoReserved},
50};
51
52static u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
53
54
55
56
57unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
58unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
59unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
60unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09};
61unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A};
62
63unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
64unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
65
66static unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
67
68
69
70
71static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
72 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
73 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
74 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
75 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
76 {{10, 11, 12, 13}, 4},
77 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
78 {{}, 0},
79};
80
81static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
82
83 {0x02},
84 {0x02},
85 {0x01},
86 {0x01},
87 {0x01},
88 {0x03},
89 {0x03},
90 {0x01},
91 {0x03},
92 {0x03},
93 {0x00},
94 {0x02},
95 {0x01},
96 {0x02},
97 {0x02},
98 {0x02},
99 {0x01},
100 {0x02},
101 {0x01},
102 {0x00},
103 {0x02},
104 {0x00},
105 {0x00},
106 {0x03},
107 {0x06},
108 {0x02},
109 {0x00},
110 {0x00},
111 {0x00},
112 {0x00},
113 {0x00},
114 {0x06},
115
116 {0x00},
117 {0x01},
118 {0x02},
119 {0x03},
120 {0x04},
121 {0x02},
122 {0x00},
123 {0x03},
124 {0x00},
125 {0x00},
126 {0x00},
127 {0x00},
128 {0x00},
129 {0x00},
130 {0x00},
131 {0x00},
132 {0x00},
133 {0x00},
134 {0x00},
135 {0x00},
136 {0x02},
137 {0x00},
138 {0x00},
139 {0x03},
140 {0x03},
141 {0x02},
142 {0x00},
143 {0x00},
144 {0x00},
145 {0x00},
146 {0x00},
147 {0x00},
148 {0x02},
149 {0x05},
150 {0x01},
151 {0x02},
152 {0x02},
153 {0x00},
154 {0x02},
155 {0x00},
156 {0x00},
157 {0x00},
158 {0x00},
159 {0x00},
160 {0x00},
161 {0x02},
162 {0x00},
163 {0x02},
164 {0x00},
165 {0x02},
166};
167
168
169static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03};
170
171
172
173
174
175
176
177int rtw_ch_set_search_ch(struct rt_channel_info *ch_set, const u32 ch)
178{
179 int i;
180
181 for (i = 0; ch_set[i].ChannelNum != 0; i++) {
182 if (ch == ch_set[i].ChannelNum)
183 break;
184 }
185
186 if (i >= ch_set[i].ChannelNum)
187 return -1;
188 return i;
189}
190
191
192
193
194
195
196
197int init_hw_mlme_ext(struct adapter *padapter)
198{
199 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
200
201 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
202 return _SUCCESS;
203}
204
205void init_mlme_default_rate_set(struct adapter *padapter)
206{
207 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
208
209 unsigned char mixed_datarate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_, _48M_RATE_, _54M_RATE_, 0xff};
210 unsigned char mixed_basicrate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,};
211 unsigned char supported_mcs_set[16] = {0xff, 0xff, 0x00, 0x00, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
212
213 memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
214 memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
215
216 memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set));
217}
218
219static void init_mlme_ext_priv_value(struct adapter *padapter)
220{
221 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
222 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
223
224 atomic_set(&pmlmeext->event_seq, 0);
225 pmlmeext->mgnt_seq = 0;
226 pmlmeext->sa_query_seq = 0;
227 pmlmeext->mgnt_80211w_IPN = 0;
228 pmlmeext->mgnt_80211w_IPN_rx = 0;
229 pmlmeext->cur_channel = padapter->registrypriv.channel;
230 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
231 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
232
233 pmlmeext->retry = 0;
234
235 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
236
237 init_mlme_default_rate_set(padapter);
238
239 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
240 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
241 pmlmeext->sitesurvey_res.channel_idx = 0;
242 pmlmeext->sitesurvey_res.bss_cnt = 0;
243 pmlmeext->scan_abort = false;
244
245 pmlmeinfo->state = WIFI_FW_NULL_STATE;
246 pmlmeinfo->reauth_count = 0;
247 pmlmeinfo->reassoc_count = 0;
248 pmlmeinfo->link_count = 0;
249 pmlmeinfo->auth_seq = 0;
250 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
251 pmlmeinfo->key_index = 0;
252 pmlmeinfo->iv = 0;
253
254 pmlmeinfo->enc_algo = _NO_PRIVACY_;
255 pmlmeinfo->authModeToggle = 0;
256
257 memset(pmlmeinfo->chg_txt, 0, 128);
258
259 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
260 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
261
262 pmlmeinfo->dialogToken = 0;
263
264 pmlmeext->action_public_rxseq = 0xffff;
265 pmlmeext->action_public_dialog_token = 0xff;
266}
267
268static int has_channel(struct rt_channel_info *channel_set,
269 u8 chanset_size,
270 u8 chan)
271{
272 int i;
273
274 for (i = 0; i < chanset_size; i++) {
275 if (channel_set[i].ChannelNum == chan) {
276 return 1;
277 }
278 }
279
280 return 0;
281}
282
283static void init_channel_list(struct adapter *padapter, struct rt_channel_info *channel_set,
284 u8 chanset_size,
285 struct p2p_channels *channel_list)
286{
287
288 static const struct p2p_oper_class_map op_class[] = {
289 { IEEE80211G, 81, 1, 13, 1, BW20 },
290 { IEEE80211G, 82, 14, 14, 1, BW20 },
291 { IEEE80211A, 115, 36, 48, 4, BW20 },
292 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
293 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
294 { IEEE80211A, 124, 149, 161, 4, BW20 },
295 { IEEE80211A, 125, 149, 169, 4, BW20 },
296 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
297 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
298 { -1, 0, 0, 0, 0, BW20 }
299 };
300
301 int cla, op;
302
303 cla = 0;
304
305 for (op = 0; op_class[op].op_class; op++) {
306 u8 ch;
307 const struct p2p_oper_class_map *o = &op_class[op];
308 struct p2p_reg_class *reg = NULL;
309
310 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
311 if (!has_channel(channel_set, chanset_size, ch))
312 continue;
313
314 if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
315 continue;
316
317 if ((0 < (padapter->registrypriv.bw_mode & 0xf0)) &&
318 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
319 continue;
320
321 if (!reg) {
322 reg = &channel_list->reg_class[cla];
323 cla++;
324 reg->reg_class = o->op_class;
325 reg->channels = 0;
326 }
327 reg->channel[reg->channels] = ch;
328 reg->channels++;
329 }
330 }
331 channel_list->reg_classes = cla;
332
333}
334
335static u8 init_channel_set(struct adapter *padapter, u8 ChannelPlan, struct rt_channel_info *channel_set)
336{
337 u8 index, chanset_size = 0;
338 u8 b2_4GBand = false;
339 u8 Index2G = 0;
340
341 memset(channel_set, 0, sizeof(struct rt_channel_info)*MAX_CHANNEL_NUM);
342
343 if (ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE)
344 return chanset_size;
345
346 if (IsSupported24G(padapter->registrypriv.wireless_mode)) {
347 b2_4GBand = true;
348 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
349 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
350 else
351 Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
352 }
353
354 if (b2_4GBand) {
355 for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) {
356 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
357
358 if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||
359 (RT_CHANNEL_DOMAIN_GLOBAL_NULL == ChannelPlan)) {
360 if (channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
361 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
362 else if ((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14))
363 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
364 } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan ||
365 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) {
366 if (channel_set[chanset_size].ChannelNum <= 11)
367 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
368 else
369 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
370 } else
371 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
372
373 chanset_size++;
374 }
375 }
376
377 return chanset_size;
378}
379
380void init_mlme_ext_priv(struct adapter *padapter)
381{
382 struct registry_priv *pregistrypriv = &padapter->registrypriv;
383 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
384 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
385 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
386
387 pmlmeext->padapter = padapter;
388
389
390
391 init_mlme_ext_priv_value(padapter);
392 pmlmeinfo->accept_addba_req = pregistrypriv->accept_addba_req;
393
394 init_mlme_ext_timer(padapter);
395
396 init_mlme_ap_info(padapter);
397
398 pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan, pmlmeext->channel_set);
399 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
400 pmlmeext->last_scan_time = 0;
401 pmlmeext->chan_scan_time = SURVEY_TO;
402 pmlmeext->mlmeext_init = true;
403 pmlmeext->active_keep_alive_check = true;
404
405#ifdef DBG_FIXED_CHAN
406 pmlmeext->fixed_chan = 0xFF;
407#endif
408}
409
410void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext)
411{
412 struct adapter *padapter = pmlmeext->padapter;
413
414 if (!padapter)
415 return;
416
417 if (padapter->bDriverStopped) {
418 del_timer_sync(&pmlmeext->survey_timer);
419 del_timer_sync(&pmlmeext->link_timer);
420
421 }
422}
423
424static void _mgt_dispatcher(struct adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
425{
426 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
427 u8 *pframe = precv_frame->u.hdr.rx_data;
428
429 if (ptable->func) {
430
431 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) &&
432 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
433 return;
434
435 ptable->func(padapter, precv_frame);
436 }
437}
438
439void mgt_dispatcher(struct adapter *padapter, union recv_frame *precv_frame)
440{
441 int index;
442 struct mlme_handler *ptable;
443 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
444 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
445 u8 *pframe = precv_frame->u.hdr.rx_data;
446 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
447 struct dvobj_priv *psdpriv = padapter->dvobj;
448 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
449
450 if (GetFrameType(pframe) != WIFI_MGT_TYPE)
451 return;
452
453
454 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) &&
455 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) {
456 return;
457 }
458
459 ptable = mlme_sta_tbl;
460
461 index = GetFrameSubType(pframe) >> 4;
462
463 if (index >= ARRAY_SIZE(mlme_sta_tbl))
464 return;
465
466 ptable += index;
467
468 if (psta) {
469 if (GetRetry(pframe)) {
470 if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum) {
471
472 pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++;
473 return;
474 }
475 }
476 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
477 }
478
479 switch (GetFrameSubType(pframe)) {
480 case WIFI_AUTH:
481 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
482 ptable->func = &OnAuth;
483 else
484 ptable->func = &OnAuthClient;
485 fallthrough;
486 case WIFI_ASSOCREQ:
487 case WIFI_REASSOCREQ:
488 _mgt_dispatcher(padapter, ptable, precv_frame);
489 break;
490 case WIFI_PROBEREQ:
491 _mgt_dispatcher(padapter, ptable, precv_frame);
492 break;
493 case WIFI_BEACON:
494 _mgt_dispatcher(padapter, ptable, precv_frame);
495 break;
496 case WIFI_ACTION:
497
498 _mgt_dispatcher(padapter, ptable, precv_frame);
499 break;
500 default:
501 _mgt_dispatcher(padapter, ptable, precv_frame);
502 break;
503 }
504}
505
506
507
508
509
510
511
512unsigned int OnProbeReq(struct adapter *padapter, union recv_frame *precv_frame)
513{
514 unsigned int ielen;
515 unsigned char *p;
516 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
517 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
518 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
519 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
520 u8 *pframe = precv_frame->u.hdr.rx_data;
521 uint len = precv_frame->u.hdr.len;
522 u8 is_valid_p2p_probereq = false;
523
524 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
525 return _SUCCESS;
526
527 if (check_fwstate(pmlmepriv, _FW_LINKED) == false &&
528 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == false) {
529 return _SUCCESS;
530 }
531
532 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, WLAN_EID_SSID, (int *)&ielen,
533 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
534
535
536
537 if (p) {
538 if (is_valid_p2p_probereq)
539 goto _issue_probersp;
540
541 if ((ielen != 0 && false == !memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
542 || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)
543 )
544 return _SUCCESS;
545
546_issue_probersp:
547 if ((check_fwstate(pmlmepriv, _FW_LINKED) &&
548 pmlmepriv->cur_network.join_res) ||
549 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
550 issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
551 }
552
553 return _SUCCESS;
554
555}
556
557unsigned int OnProbeRsp(struct adapter *padapter, union recv_frame *precv_frame)
558{
559 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
560
561 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
562 report_survey_event(padapter, precv_frame);
563 return _SUCCESS;
564 }
565
566 return _SUCCESS;
567
568}
569
570unsigned int OnBeacon(struct adapter *padapter, union recv_frame *precv_frame)
571{
572 int cam_idx;
573 struct sta_info *psta;
574 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
575 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
576 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
577 struct sta_priv *pstapriv = &padapter->stapriv;
578 u8 *pframe = precv_frame->u.hdr.rx_data;
579 uint len = precv_frame->u.hdr.len;
580 struct wlan_bssid_ex *pbss;
581 int ret = _SUCCESS;
582 u8 *p = NULL;
583 u32 ielen = 0;
584
585 p = rtw_get_ie(pframe + sizeof(struct ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, WLAN_EID_EXT_SUPP_RATES, &ielen, precv_frame->u.hdr.len - sizeof(struct ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_);
586 if (p && ielen > 0) {
587 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
588
589 *(p + 1) = ielen - 1;
590 }
591
592 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
593 report_survey_event(padapter, precv_frame);
594 return _SUCCESS;
595 }
596
597 if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) {
598 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
599
600 pbss = rtw_malloc(sizeof(struct wlan_bssid_ex));
601 if (pbss) {
602 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
603 update_network(&(pmlmepriv->cur_network.network), pbss, padapter, true);
604 rtw_get_bcn_info(&(pmlmepriv->cur_network));
605 }
606 kfree(pbss);
607 }
608
609
610 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct ieee80211_hdr_3addr), len-sizeof(struct ieee80211_hdr_3addr));
611
612
613 update_TSF(pmlmeext, pframe, len);
614
615
616 pmlmeext->adaptive_tsf_done = false;
617 pmlmeext->DrvBcnEarly = 0xff;
618 pmlmeext->DrvBcnTimeOut = 0xff;
619 pmlmeext->bcn_cnt = 0;
620 memset(pmlmeext->bcn_delay_cnt, 0, sizeof(pmlmeext->bcn_delay_cnt));
621 memset(pmlmeext->bcn_delay_ratio, 0, sizeof(pmlmeext->bcn_delay_ratio));
622
623
624 start_clnt_auth(padapter);
625
626 return _SUCCESS;
627 }
628
629 if (((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
630 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
631 if (psta) {
632 ret = rtw_check_bcn_info(padapter, pframe, len);
633 if (!ret) {
634 netdev_dbg(padapter->pnetdev,
635 "ap has changed, disconnect now\n ");
636 receive_disconnect(padapter,
637 pmlmeinfo->network.MacAddress, 0);
638 return _SUCCESS;
639 }
640
641
642 if ((sta_rx_pkts(psta) & 0xf) == 0)
643 update_beacon_info(padapter, pframe, len, psta);
644
645 adaptive_early_32k(pmlmeext, pframe, len);
646 }
647 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
648 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
649 if (psta) {
650
651
652 if ((sta_rx_pkts(psta) & 0xf) == 0) {
653 update_beacon_info(padapter, pframe, len, psta);
654 }
655 } else {
656
657 cam_idx = allocate_fw_sta_entry(padapter);
658 if (cam_idx == NUM_STA)
659 goto _END_ONBEACON_;
660
661
662 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) {
663 pmlmeinfo->FW_sta_info[cam_idx].status = 0;
664 goto _END_ONBEACON_;
665 }
666
667
668 update_TSF(pmlmeext, pframe, len);
669
670
671 report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx);
672 }
673 }
674 }
675
676_END_ONBEACON_:
677
678 return _SUCCESS;
679
680}
681
682unsigned int OnAuth(struct adapter *padapter, union recv_frame *precv_frame)
683{
684 unsigned int auth_mode, seq, ie_len;
685 unsigned char *sa, *p;
686 u16 algorithm;
687 int status;
688 static struct sta_info stat;
689 struct sta_info *pstat = NULL;
690 struct sta_priv *pstapriv = &padapter->stapriv;
691 struct security_priv *psecuritypriv = &padapter->securitypriv;
692 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
693 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
694 u8 *pframe = precv_frame->u.hdr.rx_data;
695 uint len = precv_frame->u.hdr.len;
696 u8 offset = 0;
697
698 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
699 return _FAIL;
700
701 sa = GetAddr2Ptr(pframe);
702
703 auth_mode = psecuritypriv->dot11AuthAlgrthm;
704
705 if (GetPrivacy(pframe)) {
706 u8 *iv;
707 struct rx_pkt_attrib *prxattrib = &(precv_frame->u.hdr.attrib);
708
709 prxattrib->hdrlen = WLAN_HDR_A3_LEN;
710 prxattrib->encrypt = _WEP40_;
711
712 iv = pframe+prxattrib->hdrlen;
713 prxattrib->key_index = ((iv[3]>>6)&0x3);
714
715 prxattrib->iv_len = 4;
716 prxattrib->icv_len = 4;
717
718 rtw_wep_decrypt(padapter, (u8 *)precv_frame);
719
720 offset = 4;
721 }
722
723 algorithm = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
724 seq = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
725
726 if (auth_mode == 2 &&
727 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
728 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
729 auth_mode = 0;
730
731 if ((algorithm > 0 && auth_mode == 0) ||
732 (algorithm == 0 && auth_mode == 1)) {
733
734 status = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
735
736 goto auth_fail;
737 }
738
739 if (rtw_access_ctrl(padapter, sa) == false) {
740 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
741 goto auth_fail;
742 }
743
744 pstat = rtw_get_stainfo(pstapriv, sa);
745 if (pstat == NULL) {
746
747
748 pstat = rtw_alloc_stainfo(pstapriv, sa);
749 if (pstat == NULL) {
750 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
751 goto auth_fail;
752 }
753
754 pstat->state = WIFI_FW_AUTH_NULL;
755 pstat->auth_seq = 0;
756
757
758
759 } else {
760
761 spin_lock_bh(&pstapriv->asoc_list_lock);
762 if (list_empty(&pstat->asoc_list) == false) {
763 list_del_init(&pstat->asoc_list);
764 pstapriv->asoc_list_cnt--;
765 if (pstat->expire_to > 0) {
766
767 }
768 }
769 spin_unlock_bh(&pstapriv->asoc_list_lock);
770
771 if (seq == 1) {
772
773 }
774 }
775
776 spin_lock_bh(&pstapriv->auth_list_lock);
777 if (list_empty(&pstat->auth_list)) {
778
779 list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
780 pstapriv->auth_list_cnt++;
781 }
782 spin_unlock_bh(&pstapriv->auth_list_lock);
783
784 if (pstat->auth_seq == 0)
785 pstat->expire_to = pstapriv->auth_to;
786
787
788 if ((pstat->auth_seq + 1) != seq) {
789 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
790 goto auth_fail;
791 }
792
793 if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3)) {
794 if (seq == 1) {
795 pstat->state &= ~WIFI_FW_AUTH_NULL;
796 pstat->state |= WIFI_FW_AUTH_SUCCESS;
797 pstat->expire_to = pstapriv->assoc_to;
798 pstat->authalg = algorithm;
799 } else {
800 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
801 goto auth_fail;
802 }
803 } else {
804 if (seq == 1) {
805
806 memset((void *)pstat->chg_txt, 78, 128);
807
808 pstat->state &= ~WIFI_FW_AUTH_NULL;
809 pstat->state |= WIFI_FW_AUTH_STATE;
810 pstat->authalg = algorithm;
811 pstat->auth_seq = 2;
812 } else if (seq == 3) {
813
814 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, WLAN_EID_CHALLENGE, (int *)&ie_len,
815 len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
816
817 if ((p == NULL) || (ie_len <= 0)) {
818 status = WLAN_STATUS_CHALLENGE_FAIL;
819 goto auth_fail;
820 }
821
822 if (!memcmp((void *)(p + 2), pstat->chg_txt, 128)) {
823 pstat->state &= (~WIFI_FW_AUTH_STATE);
824 pstat->state |= WIFI_FW_AUTH_SUCCESS;
825
826 pstat->expire_to = pstapriv->assoc_to;
827 } else {
828 status = WLAN_STATUS_CHALLENGE_FAIL;
829 goto auth_fail;
830 }
831 } else {
832 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
833 goto auth_fail;
834 }
835 }
836
837
838
839 pstat->auth_seq = seq + 1;
840
841 issue_auth(padapter, pstat, (unsigned short)(WLAN_STATUS_SUCCESS));
842
843 if (pstat->state & WIFI_FW_AUTH_SUCCESS)
844 pstat->auth_seq = 0;
845
846
847 return _SUCCESS;
848
849auth_fail:
850
851 if (pstat)
852 rtw_free_stainfo(padapter, pstat);
853
854 pstat = &stat;
855 memset((char *)pstat, '\0', sizeof(stat));
856 pstat->auth_seq = 2;
857 memcpy(pstat->hwaddr, sa, 6);
858
859 issue_auth(padapter, pstat, (unsigned short)status);
860
861 return _FAIL;
862
863}
864
865unsigned int OnAuthClient(struct adapter *padapter, union recv_frame *precv_frame)
866{
867 unsigned int seq, len, status, offset;
868 unsigned char *p;
869 unsigned int go2asoc = 0;
870 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
871 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
872 u8 *pframe = precv_frame->u.hdr.rx_data;
873 uint pkt_len = precv_frame->u.hdr.len;
874
875
876 if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
877 return _SUCCESS;
878
879 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
880 return _SUCCESS;
881
882 offset = (GetPrivacy(pframe)) ? 4 : 0;
883
884 seq = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
885 status = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
886
887 if (status != 0) {
888 if (status == 13) {
889 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
890 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
891 else
892 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
893
894 }
895
896 set_link_timer(pmlmeext, 1);
897 goto authclnt_fail;
898 }
899
900 if (seq == 2) {
901 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
902
903 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, WLAN_EID_CHALLENGE, (int *)&len,
904 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
905
906 if (!p)
907 goto authclnt_fail;
908
909 memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
910 pmlmeinfo->auth_seq = 3;
911 issue_auth(padapter, NULL, 0);
912 set_link_timer(pmlmeext, REAUTH_TO);
913
914 return _SUCCESS;
915 } else {
916
917 go2asoc = 1;
918 }
919 } else if (seq == 4) {
920 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
921 go2asoc = 1;
922 } else {
923 goto authclnt_fail;
924 }
925 } else {
926
927 goto authclnt_fail;
928 }
929
930 if (go2asoc) {
931 netdev_dbg(padapter->pnetdev, "auth success, start assoc\n");
932 start_clnt_assoc(padapter);
933 return _SUCCESS;
934 }
935
936authclnt_fail:
937
938
939
940 return _FAIL;
941
942}
943
944unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame)
945{
946 u16 capab_info;
947 struct rtw_ieee802_11_elems elems;
948 struct sta_info *pstat;
949 unsigned char *p, *pos, *wpa_ie;
950 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
951 int i, ie_len, wpa_ie_len, left;
952 unsigned char supportRate[16];
953 int supportRateNum;
954 unsigned short status = WLAN_STATUS_SUCCESS;
955 unsigned short frame_type, ie_offset = 0;
956 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
957 struct security_priv *psecuritypriv = &padapter->securitypriv;
958 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
959 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
960 struct wlan_bssid_ex *cur = &(pmlmeinfo->network);
961 struct sta_priv *pstapriv = &padapter->stapriv;
962 u8 *pframe = precv_frame->u.hdr.rx_data;
963 uint pkt_len = precv_frame->u.hdr.len;
964
965 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
966 return _FAIL;
967
968 frame_type = GetFrameSubType(pframe);
969 if (frame_type == WIFI_ASSOCREQ)
970 ie_offset = _ASOCREQ_IE_OFFSET_;
971 else
972 ie_offset = _REASOCREQ_IE_OFFSET_;
973
974
975 if (pkt_len < sizeof(struct ieee80211_hdr_3addr) + ie_offset)
976 return _FAIL;
977
978 pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
979 if (!pstat) {
980 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
981 goto asoc_class2_error;
982 }
983
984 capab_info = get_unaligned_le16(pframe + WLAN_HDR_A3_LEN);
985
986
987 left = pkt_len - (sizeof(struct ieee80211_hdr_3addr) + ie_offset);
988 pos = pframe + (sizeof(struct ieee80211_hdr_3addr) + ie_offset);
989
990
991 if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) {
992 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) {
993 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
994 goto asoc_class2_error;
995 } else {
996 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
997 pstat->state |= WIFI_FW_ASSOC_STATE;
998 }
999 } else {
1000 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
1001 pstat->state |= WIFI_FW_ASSOC_STATE;
1002 }
1003
1004
1005 pstat->capability = capab_info;
1006
1007
1008 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
1009 !elems.ssid) {
1010 status = WLAN_STATUS_CHALLENGE_FAIL;
1011 goto OnAssocReqFail;
1012 }
1013
1014
1015
1016 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, WLAN_EID_SSID, &ie_len,
1017 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1018
1019 if (!p || ie_len == 0) {
1020
1021 status = WLAN_STATUS_CHALLENGE_FAIL;
1022 goto OnAssocReqFail;
1023 } else {
1024
1025 if (memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
1026 status = WLAN_STATUS_CHALLENGE_FAIL;
1027
1028 if (ie_len != cur->Ssid.SsidLength)
1029 status = WLAN_STATUS_CHALLENGE_FAIL;
1030 }
1031
1032 if (status != WLAN_STATUS_SUCCESS)
1033 goto OnAssocReqFail;
1034
1035
1036 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, WLAN_EID_SUPP_RATES, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1037 if (p == NULL) {
1038
1039
1040
1041
1042 status = WLAN_STATUS_CHALLENGE_FAIL;
1043 goto OnAssocReqFail;
1044 } else {
1045 memcpy(supportRate, p+2, ie_len);
1046 supportRateNum = ie_len;
1047
1048 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, WLAN_EID_EXT_SUPP_RATES, &ie_len,
1049 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1050 if (p != NULL) {
1051
1052 if (supportRateNum <= sizeof(supportRate)) {
1053 memcpy(supportRate+supportRateNum, p+2, ie_len);
1054 supportRateNum += ie_len;
1055 }
1056 }
1057 }
1058
1059
1060
1061
1062
1063 pstat->bssratelen = supportRateNum;
1064 memcpy(pstat->bssrateset, supportRate, supportRateNum);
1065 UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
1066
1067
1068 pstat->dot8021xalg = 0;
1069 pstat->wpa_psk = 0;
1070 pstat->wpa_group_cipher = 0;
1071 pstat->wpa2_group_cipher = 0;
1072 pstat->wpa_pairwise_cipher = 0;
1073 pstat->wpa2_pairwise_cipher = 0;
1074 memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
1075 if ((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
1076
1077 int group_cipher = 0, pairwise_cipher = 0;
1078
1079 wpa_ie = elems.rsn_ie;
1080 wpa_ie_len = elems.rsn_ie_len;
1081
1082 if (rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1083 pstat->dot8021xalg = 1;
1084 pstat->wpa_psk |= BIT(1);
1085
1086 pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
1087 pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
1088
1089 if (!pstat->wpa2_group_cipher)
1090 status = WLAN_STATUS_INVALID_GROUP_CIPHER;
1091
1092 if (!pstat->wpa2_pairwise_cipher)
1093 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER;
1094 } else {
1095 status = WLAN_STATUS_INVALID_IE;
1096 }
1097
1098 } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
1099
1100 int group_cipher = 0, pairwise_cipher = 0;
1101
1102 wpa_ie = elems.wpa_ie;
1103 wpa_ie_len = elems.wpa_ie_len;
1104
1105 if (rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1106 pstat->dot8021xalg = 1;
1107 pstat->wpa_psk |= BIT(0);
1108
1109 pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
1110 pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
1111
1112 if (!pstat->wpa_group_cipher)
1113 status = WLAN_STATUS_INVALID_GROUP_CIPHER;
1114
1115 if (!pstat->wpa_pairwise_cipher)
1116 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER;
1117
1118 } else {
1119 status = WLAN_STATUS_INVALID_IE;
1120 }
1121
1122 } else {
1123 wpa_ie = NULL;
1124 wpa_ie_len = 0;
1125 }
1126
1127 if (status != WLAN_STATUS_SUCCESS)
1128 goto OnAssocReqFail;
1129
1130 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
1131 if (!wpa_ie) {
1132 if (elems.wps_ie) {
1133 pstat->flags |= WLAN_STA_WPS;
1134
1135
1136
1137 } else {
1138 pstat->flags |= WLAN_STA_MAYBE_WPS;
1139 }
1140
1141
1142
1143
1144 if ((psecuritypriv->wpa_psk > 0)
1145 && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS))) {
1146 if (pmlmepriv->wps_beacon_ie) {
1147 u8 selected_registrar = 0;
1148
1149 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR, &selected_registrar, NULL);
1150
1151 if (!selected_registrar) {
1152 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1153
1154 goto OnAssocReqFail;
1155 }
1156 }
1157 }
1158
1159 } else {
1160 int copy_len;
1161
1162 if (psecuritypriv->wpa_psk == 0) {
1163 status = WLAN_STATUS_INVALID_IE;
1164
1165 goto OnAssocReqFail;
1166
1167 }
1168
1169 if (elems.wps_ie) {
1170 pstat->flags |= WLAN_STA_WPS;
1171 copy_len = 0;
1172 } else {
1173 copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
1174 }
1175
1176
1177 if (copy_len > 0)
1178 memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
1179
1180 }
1181
1182
1183
1184 pstat->flags &= ~WLAN_STA_WME;
1185 pstat->qos_option = 0;
1186 pstat->qos_info = 0;
1187 pstat->has_legacy_ac = true;
1188 pstat->uapsd_vo = 0;
1189 pstat->uapsd_vi = 0;
1190 pstat->uapsd_be = 0;
1191 pstat->uapsd_bk = 0;
1192 if (pmlmepriv->qospriv.qos_option) {
1193 p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
1194 for (;;) {
1195 p = rtw_get_ie(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1196 if (p) {
1197 if (!memcmp(p+2, WMM_IE, 6)) {
1198
1199 pstat->flags |= WLAN_STA_WME;
1200
1201 pstat->qos_option = 1;
1202 pstat->qos_info = *(p+8);
1203
1204 pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
1205
1206 if ((pstat->qos_info&0xf) != 0xf)
1207 pstat->has_legacy_ac = true;
1208 else
1209 pstat->has_legacy_ac = false;
1210
1211 if (pstat->qos_info&0xf) {
1212 if (pstat->qos_info&BIT(0))
1213 pstat->uapsd_vo = BIT(0)|BIT(1);
1214 else
1215 pstat->uapsd_vo = 0;
1216
1217 if (pstat->qos_info&BIT(1))
1218 pstat->uapsd_vi = BIT(0)|BIT(1);
1219 else
1220 pstat->uapsd_vi = 0;
1221
1222 if (pstat->qos_info&BIT(2))
1223 pstat->uapsd_bk = BIT(0)|BIT(1);
1224 else
1225 pstat->uapsd_bk = 0;
1226
1227 if (pstat->qos_info&BIT(3))
1228 pstat->uapsd_be = BIT(0)|BIT(1);
1229 else
1230 pstat->uapsd_be = 0;
1231
1232 }
1233
1234 break;
1235 }
1236 } else {
1237 break;
1238 }
1239 p = p + ie_len + 2;
1240 }
1241 }
1242
1243
1244 memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
1245 if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct ieee80211_ht_cap)) {
1246 pstat->flags |= WLAN_STA_HT;
1247
1248 pstat->flags |= WLAN_STA_WME;
1249
1250 memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct ieee80211_ht_cap));
1251
1252 } else
1253 pstat->flags &= ~WLAN_STA_HT;
1254
1255
1256 if ((pmlmepriv->htpriv.ht_option == false) && (pstat->flags&WLAN_STA_HT)) {
1257 status = WLAN_STATUS_CHALLENGE_FAIL;
1258 goto OnAssocReqFail;
1259 }
1260
1261
1262 if ((pstat->flags & WLAN_STA_HT) &&
1263 ((pstat->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
1264 (pstat->wpa_pairwise_cipher&WPA_CIPHER_TKIP))) {
1265
1266
1267 }
1268 pstat->flags |= WLAN_STA_NONERP;
1269 for (i = 0; i < pstat->bssratelen; i++) {
1270 if ((pstat->bssrateset[i] & 0x7f) > 22) {
1271 pstat->flags &= ~WLAN_STA_NONERP;
1272 break;
1273 }
1274 }
1275
1276 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1277 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
1278 else
1279 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1280
1281
1282
1283 if (status != WLAN_STATUS_SUCCESS)
1284 goto OnAssocReqFail;
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295 if (pstat->aid == 0) {
1296 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
1297 if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
1298 break;
1299
1300
1301 if (pstat->aid > pstapriv->max_num_sta) {
1302
1303 pstat->aid = 0;
1304
1305 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1306
1307 goto OnAssocReqFail;
1308
1309
1310 } else {
1311 pstapriv->sta_aid[pstat->aid - 1] = pstat;
1312 }
1313 }
1314
1315
1316 pstat->state &= (~WIFI_FW_ASSOC_STATE);
1317 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
1318
1319 spin_lock_bh(&pstapriv->auth_list_lock);
1320 if (!list_empty(&pstat->auth_list)) {
1321 list_del_init(&pstat->auth_list);
1322 pstapriv->auth_list_cnt--;
1323 }
1324 spin_unlock_bh(&pstapriv->auth_list_lock);
1325
1326 spin_lock_bh(&pstapriv->asoc_list_lock);
1327 if (list_empty(&pstat->asoc_list)) {
1328 pstat->expire_to = pstapriv->expire_to;
1329 list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
1330 pstapriv->asoc_list_cnt++;
1331 }
1332 spin_unlock_bh(&pstapriv->asoc_list_lock);
1333
1334
1335 if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (WLAN_STATUS_SUCCESS == status)) {
1336
1337 bss_cap_update_on_sta_join(padapter, pstat);
1338 sta_info_update(padapter, pstat);
1339
1340
1341 if (frame_type == WIFI_ASSOCREQ)
1342 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
1343 else
1344 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
1345
1346 spin_lock_bh(&pstat->lock);
1347 if (pstat->passoc_req) {
1348 kfree(pstat->passoc_req);
1349 pstat->passoc_req = NULL;
1350 pstat->assoc_req_len = 0;
1351 }
1352
1353 pstat->passoc_req = rtw_zmalloc(pkt_len);
1354 if (pstat->passoc_req) {
1355 memcpy(pstat->passoc_req, pframe, pkt_len);
1356 pstat->assoc_req_len = pkt_len;
1357 }
1358 spin_unlock_bh(&pstat->lock);
1359
1360
1361 report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
1362 }
1363
1364 return _SUCCESS;
1365
1366asoc_class2_error:
1367
1368 issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
1369
1370 return _FAIL;
1371
1372OnAssocReqFail:
1373
1374 pstat->aid = 0;
1375 if (frame_type == WIFI_ASSOCREQ)
1376 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
1377 else
1378 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
1379
1380 return _FAIL;
1381}
1382
1383unsigned int OnAssocRsp(struct adapter *padapter, union recv_frame *precv_frame)
1384{
1385 uint i;
1386 int res;
1387 unsigned short status;
1388 struct ndis_80211_var_ie *pIE;
1389 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1390 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1391 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1392
1393 u8 *pframe = precv_frame->u.hdr.rx_data;
1394 uint pkt_len = precv_frame->u.hdr.len;
1395
1396
1397 if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
1398 return _SUCCESS;
1399
1400 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
1401 return _SUCCESS;
1402
1403 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1404 return _SUCCESS;
1405
1406 del_timer_sync(&pmlmeext->link_timer);
1407
1408
1409 status = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 2));
1410 if (status > 0) {
1411 pmlmeinfo->state = WIFI_FW_NULL_STATE;
1412 res = -4;
1413 goto report_assoc_result;
1414 }
1415
1416
1417 pmlmeinfo->capability = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
1418
1419
1420 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20;
1421
1422
1423 res = pmlmeinfo->aid = (int)(le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
1424
1425
1426
1427
1428 for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) {
1429 pIE = (struct ndis_80211_var_ie *)(pframe + i);
1430
1431 switch (pIE->ElementID) {
1432 case WLAN_EID_VENDOR_SPECIFIC:
1433 if (!memcmp(pIE->data, WMM_PARA_OUI, 6))
1434 WMM_param_handler(padapter, pIE);
1435 break;
1436
1437 case WLAN_EID_HT_CAPABILITY:
1438 HT_caps_handler(padapter, pIE);
1439 break;
1440
1441 case WLAN_EID_HT_OPERATION:
1442 HT_info_handler(padapter, pIE);
1443 break;
1444
1445 case WLAN_EID_ERP_INFO:
1446 ERP_IE_handler(padapter, pIE);
1447 break;
1448
1449 default:
1450 break;
1451 }
1452
1453 i += (pIE->Length + 2);
1454 }
1455
1456 pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
1457 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
1458
1459
1460 UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
1461
1462report_assoc_result:
1463 if (res > 0) {
1464 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
1465 } else {
1466 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
1467 }
1468
1469 report_join_res(padapter, res);
1470
1471 return _SUCCESS;
1472}
1473
1474unsigned int OnDeAuth(struct adapter *padapter, union recv_frame *precv_frame)
1475{
1476 unsigned short reason;
1477 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1478 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1479 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1480 u8 *pframe = precv_frame->u.hdr.rx_data;
1481
1482
1483 if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1484 return _SUCCESS;
1485
1486 reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
1487
1488 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1489 struct sta_info *psta;
1490 struct sta_priv *pstapriv = &padapter->stapriv;
1491
1492
1493
1494
1495
1496 netdev_dbg(padapter->pnetdev,
1497 "ap recv deauth reason code(%d) sta:%pM\n", reason,
1498 GetAddr2Ptr(pframe));
1499
1500 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1501 if (psta) {
1502 u8 updated = false;
1503
1504 spin_lock_bh(&pstapriv->asoc_list_lock);
1505 if (list_empty(&psta->asoc_list) == false) {
1506 list_del_init(&psta->asoc_list);
1507 pstapriv->asoc_list_cnt--;
1508 updated = ap_free_sta(padapter, psta, false, reason);
1509
1510 }
1511 spin_unlock_bh(&pstapriv->asoc_list_lock);
1512
1513 associated_clients_update(padapter, updated);
1514 }
1515
1516
1517 return _SUCCESS;
1518 } else {
1519 int ignore_received_deauth = 0;
1520
1521
1522
1523
1524
1525
1526 if ((pmlmeinfo->state & WIFI_FW_AUTH_STATE) ||
1527 (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)) {
1528 if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA) {
1529 ignore_received_deauth = 1;
1530 } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
1531
1532 ignore_received_deauth = 1;
1533 }
1534 }
1535
1536 netdev_dbg(padapter->pnetdev,
1537 "sta recv deauth reason code(%d) sta:%pM, ignore = %d\n",
1538 reason, GetAddr3Ptr(pframe),
1539 ignore_received_deauth);
1540
1541 if (0 == ignore_received_deauth) {
1542 receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
1543 }
1544 }
1545 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1546 return _SUCCESS;
1547
1548}
1549
1550unsigned int OnDisassoc(struct adapter *padapter, union recv_frame *precv_frame)
1551{
1552 unsigned short reason;
1553 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1554 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1555 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1556 u8 *pframe = precv_frame->u.hdr.rx_data;
1557
1558
1559 if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
1560 return _SUCCESS;
1561
1562 reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
1563
1564 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1565 struct sta_info *psta;
1566 struct sta_priv *pstapriv = &padapter->stapriv;
1567
1568
1569
1570
1571
1572 netdev_dbg(padapter->pnetdev,
1573 "ap recv disassoc reason code(%d) sta:%pM\n",
1574 reason, GetAddr2Ptr(pframe));
1575
1576 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1577 if (psta) {
1578 u8 updated = false;
1579
1580 spin_lock_bh(&pstapriv->asoc_list_lock);
1581 if (list_empty(&psta->asoc_list) == false) {
1582 list_del_init(&psta->asoc_list);
1583 pstapriv->asoc_list_cnt--;
1584 updated = ap_free_sta(padapter, psta, false, reason);
1585
1586 }
1587 spin_unlock_bh(&pstapriv->asoc_list_lock);
1588
1589 associated_clients_update(padapter, updated);
1590 }
1591
1592 return _SUCCESS;
1593 } else {
1594 netdev_dbg(padapter->pnetdev,
1595 "sta recv disassoc reason code(%d) sta:%pM\n",
1596 reason, GetAddr3Ptr(pframe));
1597
1598 receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
1599 }
1600 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1601 return _SUCCESS;
1602
1603}
1604
1605unsigned int OnAtim(struct adapter *padapter, union recv_frame *precv_frame)
1606{
1607 return _SUCCESS;
1608}
1609
1610unsigned int on_action_spct(struct adapter *padapter, union recv_frame *precv_frame)
1611{
1612 struct sta_info *psta = NULL;
1613 struct sta_priv *pstapriv = &padapter->stapriv;
1614 u8 *pframe = precv_frame->u.hdr.rx_data;
1615 u8 *frame_body = (u8 *)(pframe + sizeof(struct ieee80211_hdr_3addr));
1616 u8 category;
1617 u8 action;
1618
1619 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1620
1621 if (!psta)
1622 goto exit;
1623
1624 category = frame_body[0];
1625 if (category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
1626 goto exit;
1627
1628 action = frame_body[1];
1629 switch (action) {
1630 case WLAN_ACTION_SPCT_MSR_REQ:
1631 case WLAN_ACTION_SPCT_MSR_RPRT:
1632 case WLAN_ACTION_SPCT_TPC_REQ:
1633 case WLAN_ACTION_SPCT_TPC_RPRT:
1634 case WLAN_ACTION_SPCT_CHL_SWITCH:
1635 break;
1636 default:
1637 break;
1638 }
1639
1640exit:
1641 return _FAIL;
1642}
1643
1644unsigned int OnAction_back(struct adapter *padapter, union recv_frame *precv_frame)
1645{
1646 u8 *addr;
1647 struct sta_info *psta = NULL;
1648 struct recv_reorder_ctrl *preorder_ctrl;
1649 unsigned char *frame_body;
1650 unsigned char category, action;
1651 unsigned short tid, status;
1652 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1653 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1654 u8 *pframe = precv_frame->u.hdr.rx_data;
1655 struct sta_priv *pstapriv = &padapter->stapriv;
1656
1657
1658 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))
1659 return _SUCCESS;
1660
1661 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1662 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
1663 return _SUCCESS;
1664
1665 addr = GetAddr2Ptr(pframe);
1666 psta = rtw_get_stainfo(pstapriv, addr);
1667
1668 if (!psta)
1669 return _SUCCESS;
1670
1671 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
1672
1673 category = frame_body[0];
1674 if (category == RTW_WLAN_CATEGORY_BACK) {
1675 if (!pmlmeinfo->HT_enable)
1676 return _SUCCESS;
1677
1678 action = frame_body[1];
1679 switch (action) {
1680 case WLAN_ACTION_ADDBA_REQ:
1681
1682 memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
1683
1684 process_addba_req(padapter, (u8 *)&(pmlmeinfo->ADDBA_req), addr);
1685
1686 if (pmlmeinfo->accept_addba_req) {
1687 issue_action_BA(padapter, addr, WLAN_ACTION_ADDBA_RESP, 0);
1688 } else {
1689 issue_action_BA(padapter, addr, WLAN_ACTION_ADDBA_RESP, 37);
1690 }
1691
1692 break;
1693
1694 case WLAN_ACTION_ADDBA_RESP:
1695 status = get_unaligned_le16(&frame_body[3]);
1696 tid = ((frame_body[5] >> 2) & 0x7);
1697
1698 if (status == 0) {
1699
1700 psta->htpriv.agg_enable_bitmap |= BIT(tid);
1701 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
1702 } else {
1703 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
1704 }
1705
1706 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
1707 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
1708 psta->expire_to = pstapriv->expire_to;
1709 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
1710 }
1711
1712 break;
1713
1714 case WLAN_ACTION_DELBA:
1715 if ((frame_body[3] & BIT(3)) == 0) {
1716 psta->htpriv.agg_enable_bitmap &=
1717 ~BIT((frame_body[3] >> 4) & 0xf);
1718 psta->htpriv.candidate_tid_bitmap &=
1719 ~BIT((frame_body[3] >> 4) & 0xf);
1720 } else if ((frame_body[3] & BIT(3)) == BIT(3)) {
1721 tid = (frame_body[3] >> 4) & 0x0F;
1722
1723 preorder_ctrl = &psta->recvreorder_ctrl[tid];
1724 preorder_ctrl->enable = false;
1725 preorder_ctrl->indicate_seq = 0xffff;
1726 }
1727
1728 break;
1729
1730 default:
1731 break;
1732 }
1733 }
1734 return _SUCCESS;
1735}
1736
1737static s32 rtw_action_public_decache(union recv_frame *recv_frame, s32 token)
1738{
1739 struct adapter *adapter = recv_frame->u.hdr.adapter;
1740 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
1741 u8 *frame = recv_frame->u.hdr.rx_data;
1742 u16 seq_ctrl = ((recv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
1743 (recv_frame->u.hdr.attrib.frag_num & 0xf);
1744
1745 if (GetRetry(frame)) {
1746 if (token >= 0) {
1747 if ((seq_ctrl == mlmeext->action_public_rxseq)
1748 && (token == mlmeext->action_public_dialog_token))
1749 return _FAIL;
1750 } else {
1751 if (seq_ctrl == mlmeext->action_public_rxseq)
1752 return _FAIL;
1753 }
1754 }
1755
1756 mlmeext->action_public_rxseq = seq_ctrl;
1757
1758 if (token >= 0)
1759 mlmeext->action_public_dialog_token = token;
1760
1761 return _SUCCESS;
1762}
1763
1764static unsigned int on_action_public_p2p(union recv_frame *precv_frame)
1765{
1766 u8 *pframe = precv_frame->u.hdr.rx_data;
1767 u8 *frame_body;
1768 u8 dialogToken = 0;
1769
1770 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
1771
1772 dialogToken = frame_body[7];
1773
1774 if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
1775 return _FAIL;
1776
1777 return _SUCCESS;
1778}
1779
1780static unsigned int on_action_public_vendor(union recv_frame *precv_frame)
1781{
1782 unsigned int ret = _FAIL;
1783 u8 *pframe = precv_frame->u.hdr.rx_data;
1784 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
1785
1786 if (!memcmp(frame_body + 2, P2P_OUI, 4)) {
1787 ret = on_action_public_p2p(precv_frame);
1788 }
1789
1790 return ret;
1791}
1792
1793static unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
1794{
1795 unsigned int ret = _FAIL;
1796 u8 *pframe = precv_frame->u.hdr.rx_data;
1797 uint frame_len = precv_frame->u.hdr.len;
1798 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
1799 u8 token;
1800 struct adapter *adapter = precv_frame->u.hdr.adapter;
1801 char msg[64];
1802
1803 token = frame_body[2];
1804
1805 if (rtw_action_public_decache(precv_frame, token) == _FAIL)
1806 goto exit;
1807
1808 scnprintf(msg, sizeof(msg), "%s(token:%u)", action_public_str(action), token);
1809 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
1810
1811 ret = _SUCCESS;
1812
1813exit:
1814 return ret;
1815}
1816
1817unsigned int on_action_public(struct adapter *padapter, union recv_frame *precv_frame)
1818{
1819 unsigned int ret = _FAIL;
1820 u8 *pframe = precv_frame->u.hdr.rx_data;
1821 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
1822 u8 category, action;
1823
1824
1825 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))
1826 goto exit;
1827
1828 category = frame_body[0];
1829 if (category != RTW_WLAN_CATEGORY_PUBLIC)
1830 goto exit;
1831
1832 action = frame_body[1];
1833 switch (action) {
1834 case ACT_PUBLIC_VENDOR:
1835 ret = on_action_public_vendor(precv_frame);
1836 break;
1837 default:
1838 ret = on_action_public_default(precv_frame, action);
1839 break;
1840 }
1841
1842exit:
1843 return ret;
1844}
1845
1846unsigned int OnAction_ht(struct adapter *padapter, union recv_frame *precv_frame)
1847{
1848 u8 *pframe = precv_frame->u.hdr.rx_data;
1849 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
1850 u8 category, action;
1851
1852
1853 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))
1854 goto exit;
1855
1856 category = frame_body[0];
1857 if (category != RTW_WLAN_CATEGORY_HT)
1858 goto exit;
1859
1860 action = frame_body[1];
1861 switch (action) {
1862 case WLAN_HT_ACTION_COMPRESSED_BF:
1863 break;
1864 default:
1865 break;
1866 }
1867
1868exit:
1869
1870 return _SUCCESS;
1871}
1872
1873unsigned int OnAction_sa_query(struct adapter *padapter, union recv_frame *precv_frame)
1874{
1875 u8 *pframe = precv_frame->u.hdr.rx_data;
1876 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1877 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1878 unsigned short tid;
1879
1880 switch (pframe[WLAN_HDR_A3_LEN+1]) {
1881 case 0:
1882 memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(unsigned short));
1883 issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid);
1884 break;
1885
1886 case 1:
1887 del_timer_sync(&pmlmeext->sa_query_timer);
1888 break;
1889 default:
1890 break;
1891 }
1892 if (0) {
1893 int pp;
1894
1895 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
1896 for (pp = 0; pp < pattrib->pkt_len; pp++)
1897 printk(" %02x ", pframe[pp]);
1898 printk("\n");
1899 }
1900
1901 return _SUCCESS;
1902}
1903
1904unsigned int OnAction(struct adapter *padapter, union recv_frame *precv_frame)
1905{
1906 int i;
1907 unsigned char category;
1908 struct action_handler *ptable;
1909 unsigned char *frame_body;
1910 u8 *pframe = precv_frame->u.hdr.rx_data;
1911
1912 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
1913
1914 category = frame_body[0];
1915
1916 for (i = 0; i < ARRAY_SIZE(OnAction_tbl); i++) {
1917 ptable = &OnAction_tbl[i];
1918
1919 if (category == ptable->num)
1920 ptable->func(padapter, precv_frame);
1921
1922 }
1923
1924 return _SUCCESS;
1925
1926}
1927
1928unsigned int DoReserved(struct adapter *padapter, union recv_frame *precv_frame)
1929{
1930 return _SUCCESS;
1931}
1932
1933static struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
1934{
1935 struct xmit_frame *pmgntframe;
1936 struct xmit_buf *pxmitbuf;
1937
1938 if (once)
1939 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
1940 else
1941 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
1942
1943 if (!pmgntframe)
1944 goto exit;
1945
1946 pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv);
1947 if (pxmitbuf == NULL) {
1948 rtw_free_xmitframe(pxmitpriv, pmgntframe);
1949 pmgntframe = NULL;
1950 goto exit;
1951 }
1952
1953 pmgntframe->frame_tag = MGNT_FRAMETAG;
1954 pmgntframe->pxmitbuf = pxmitbuf;
1955 pmgntframe->buf_addr = pxmitbuf->pbuf;
1956 pxmitbuf->priv_data = pmgntframe;
1957
1958exit:
1959 return pmgntframe;
1960
1961}
1962
1963inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
1964{
1965 return _alloc_mgtxmitframe(pxmitpriv, false);
1966}
1967
1968
1969
1970
1971
1972
1973
1974void update_mgnt_tx_rate(struct adapter *padapter, u8 rate)
1975{
1976 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1977
1978 pmlmeext->tx_rate = rate;
1979}
1980
1981void update_mgntframe_attrib(struct adapter *padapter, struct pkt_attrib *pattrib)
1982{
1983 u8 wireless_mode;
1984 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1985
1986
1987
1988 pattrib->hdrlen = 24;
1989 pattrib->nr_frags = 1;
1990 pattrib->priority = 7;
1991 pattrib->mac_id = 0;
1992 pattrib->qsel = 0x12;
1993
1994 pattrib->pktlen = 0;
1995
1996 if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
1997 wireless_mode = WIRELESS_11B;
1998 else
1999 wireless_mode = WIRELESS_11G;
2000 pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
2001 pattrib->rate = pmlmeext->tx_rate;
2002
2003 pattrib->encrypt = _NO_PRIVACY_;
2004 pattrib->bswenc = false;
2005
2006 pattrib->qos_en = false;
2007 pattrib->ht_en = false;
2008 pattrib->bwmode = CHANNEL_WIDTH_20;
2009 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2010 pattrib->sgi = false;
2011
2012 pattrib->seqnum = pmlmeext->mgnt_seq;
2013
2014 pattrib->retry_ctrl = true;
2015
2016 pattrib->mbssid = 0;
2017
2018}
2019
2020void update_mgntframe_attrib_addr(struct adapter *padapter, struct xmit_frame *pmgntframe)
2021{
2022 u8 *pframe;
2023 struct pkt_attrib *pattrib = &pmgntframe->attrib;
2024
2025 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2026
2027 memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
2028 memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN);
2029}
2030
2031void dump_mgntframe(struct adapter *padapter, struct xmit_frame *pmgntframe)
2032{
2033 if (padapter->bSurpriseRemoved ||
2034 padapter->bDriverStopped) {
2035 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
2036 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
2037 return;
2038 }
2039
2040 rtw_hal_mgnt_xmit(padapter, pmgntframe);
2041}
2042
2043s32 dump_mgntframe_and_wait(struct adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
2044{
2045 s32 ret = _FAIL;
2046 unsigned long irqL;
2047 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2048 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
2049 struct submit_ctx sctx;
2050
2051 if (padapter->bSurpriseRemoved ||
2052 padapter->bDriverStopped) {
2053 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
2054 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
2055 return ret;
2056 }
2057
2058 rtw_sctx_init(&sctx, timeout_ms);
2059 pxmitbuf->sctx = &sctx;
2060
2061 ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
2062
2063 if (ret == _SUCCESS)
2064 ret = rtw_sctx_wait(&sctx);
2065
2066 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
2067 pxmitbuf->sctx = NULL;
2068 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
2069
2070 return ret;
2071}
2072
2073s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmgntframe)
2074{
2075 static u8 seq_no;
2076 s32 ret = _FAIL;
2077 u32 timeout_ms = 500;
2078 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2079
2080 if (padapter->bSurpriseRemoved ||
2081 padapter->bDriverStopped) {
2082 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
2083 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
2084 return -1;
2085 }
2086
2087 if (mutex_lock_interruptible(&pxmitpriv->ack_tx_mutex) == 0) {
2088 pxmitpriv->ack_tx = true;
2089 pxmitpriv->seq_no = seq_no++;
2090 pmgntframe->ack_report = 1;
2091 if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS)
2092 ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms);
2093
2094 pxmitpriv->ack_tx = false;
2095 mutex_unlock(&pxmitpriv->ack_tx_mutex);
2096 }
2097
2098 return ret;
2099}
2100
2101static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
2102{
2103 u8 *ssid_ie;
2104 signed int ssid_len_ori;
2105 int len_diff = 0;
2106
2107 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
2108
2109 if (ssid_ie && ssid_len_ori > 0) {
2110 switch (hidden_ssid_mode) {
2111 case 1:
2112 {
2113 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
2114 u32 remain_len = 0;
2115
2116 remain_len = ies_len - (next_ie-ies);
2117
2118 ssid_ie[1] = 0;
2119 memcpy(ssid_ie+2, next_ie, remain_len);
2120 len_diff -= ssid_len_ori;
2121
2122 break;
2123 }
2124 case 2:
2125 memset(&ssid_ie[2], 0, ssid_len_ori);
2126 break;
2127 default:
2128 break;
2129 }
2130 }
2131
2132 return len_diff;
2133}
2134
2135void issue_beacon(struct adapter *padapter, int timeout_ms)
2136{
2137 struct xmit_frame *pmgntframe;
2138 struct pkt_attrib *pattrib;
2139 unsigned char *pframe;
2140 struct ieee80211_hdr *pwlanhdr;
2141 __le16 *fctrl;
2142 unsigned int rate_len;
2143 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2144 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2145 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2146 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2147 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
2148
2149 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2150 if (!pmgntframe)
2151 return;
2152
2153 spin_lock_bh(&pmlmepriv->bcn_update_lock);
2154
2155
2156 pattrib = &pmgntframe->attrib;
2157 update_mgntframe_attrib(padapter, pattrib);
2158 pattrib->qsel = 0x10;
2159
2160 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2161
2162 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2163 pwlanhdr = (struct ieee80211_hdr *)pframe;
2164
2165
2166 fctrl = &(pwlanhdr->frame_control);
2167 *(fctrl) = 0;
2168
2169 eth_broadcast_addr(pwlanhdr->addr1);
2170 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2171 memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
2172
2173 SetSeqNum(pwlanhdr, 0);
2174
2175 SetFrameSubType(pframe, WIFI_BEACON);
2176
2177 pframe += sizeof(struct ieee80211_hdr_3addr);
2178 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2179
2180 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
2181 {
2182 int len_diff;
2183
2184 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2185 len_diff = update_hidden_ssid(pframe+_BEACON_IE_OFFSET_,
2186 cur_network->IELength-_BEACON_IE_OFFSET_,
2187 pmlmeinfo->hidden_ssid_mode);
2188 pframe += (cur_network->IELength+len_diff);
2189 pattrib->pktlen += (cur_network->IELength+len_diff);
2190 }
2191
2192 {
2193 u8 *wps_ie;
2194 uint wps_ielen;
2195 u8 sr = 0;
2196
2197 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
2198 pattrib->pktlen-sizeof(struct ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
2199 if (wps_ie && wps_ielen > 0) {
2200 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
2201 }
2202 if (sr != 0)
2203 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
2204 else
2205 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
2206 }
2207
2208 goto _issue_bcn;
2209
2210 }
2211
2212
2213
2214
2215 pframe += 8;
2216 pattrib->pktlen += 8;
2217
2218
2219
2220 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
2221
2222 pframe += 2;
2223 pattrib->pktlen += 2;
2224
2225
2226
2227 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
2228
2229 pframe += 2;
2230 pattrib->pktlen += 2;
2231
2232
2233 pframe = rtw_set_ie(pframe, WLAN_EID_SSID, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
2234
2235
2236 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
2237 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
2238
2239
2240 pframe = rtw_set_ie(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
2241
2242
2243 {
2244 u8 erpinfo = 0;
2245 u32 ATIMWindow;
2246
2247
2248 ATIMWindow = 0;
2249 pframe = rtw_set_ie(pframe, WLAN_EID_IBSS_PARAMS, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
2250
2251
2252 pframe = rtw_set_ie(pframe, WLAN_EID_ERP_INFO, 1, &erpinfo, &pattrib->pktlen);
2253 }
2254
2255
2256
2257 if (rate_len > 8) {
2258 pframe = rtw_set_ie(pframe, WLAN_EID_EXT_SUPP_RATES, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
2259 }
2260
2261
2262
2263
2264_issue_bcn:
2265
2266 pmlmepriv->update_bcn = false;
2267
2268 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
2269
2270 if ((pattrib->pktlen + TXDESC_SIZE) > 512)
2271 return;
2272
2273 pattrib->last_txcmdsz = pattrib->pktlen;
2274
2275 if (timeout_ms > 0)
2276 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
2277 else
2278 dump_mgntframe(padapter, pmgntframe);
2279
2280}
2281
2282void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
2283{
2284 struct xmit_frame *pmgntframe;
2285 struct pkt_attrib *pattrib;
2286 unsigned char *pframe;
2287 struct ieee80211_hdr *pwlanhdr;
2288 __le16 *fctrl;
2289 unsigned char *mac, *bssid;
2290 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2291
2292 u8 *pwps_ie;
2293 uint wps_ielen;
2294 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2295 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2296 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2297 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
2298 unsigned int rate_len;
2299
2300 if (da == NULL)
2301 return;
2302
2303 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2304 if (!pmgntframe)
2305 return;
2306
2307
2308 pattrib = &pmgntframe->attrib;
2309 update_mgntframe_attrib(padapter, pattrib);
2310
2311 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2312
2313 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2314 pwlanhdr = (struct ieee80211_hdr *)pframe;
2315
2316 mac = myid(&(padapter->eeprompriv));
2317 bssid = cur_network->MacAddress;
2318
2319 fctrl = &(pwlanhdr->frame_control);
2320 *(fctrl) = 0;
2321 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
2322 memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
2323 memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
2324
2325 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2326 pmlmeext->mgnt_seq++;
2327 SetFrameSubType(fctrl, WIFI_PROBERSP);
2328
2329 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2330 pattrib->pktlen = pattrib->hdrlen;
2331 pframe += pattrib->hdrlen;
2332
2333
2334 if (cur_network->IELength > MAX_IE_SZ)
2335 return;
2336
2337 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
2338 pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
2339
2340
2341 if (pmlmepriv->wps_probe_resp_ie && pwps_ie && wps_ielen > 0) {
2342 uint wps_offset, remainder_ielen;
2343 u8 *premainder_ie;
2344
2345 wps_offset = (uint)(pwps_ie - cur_network->IEs);
2346
2347 premainder_ie = pwps_ie + wps_ielen;
2348
2349 remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
2350
2351 memcpy(pframe, cur_network->IEs, wps_offset);
2352 pframe += wps_offset;
2353 pattrib->pktlen += wps_offset;
2354
2355 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];
2356 if ((wps_offset+wps_ielen+2) <= MAX_IE_SZ) {
2357 memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
2358 pframe += wps_ielen+2;
2359 pattrib->pktlen += wps_ielen+2;
2360 }
2361
2362 if ((wps_offset+wps_ielen+2+remainder_ielen) <= MAX_IE_SZ) {
2363 memcpy(pframe, premainder_ie, remainder_ielen);
2364 pframe += remainder_ielen;
2365 pattrib->pktlen += remainder_ielen;
2366 }
2367 } else {
2368 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2369 pframe += cur_network->IELength;
2370 pattrib->pktlen += cur_network->IELength;
2371 }
2372
2373
2374 {
2375 u8 *ssid_ie;
2376 signed int ssid_ielen;
2377 signed int ssid_ielen_diff;
2378 u8 *buf;
2379 u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr);
2380
2381 buf = rtw_zmalloc(MAX_IE_SZ);
2382 if (!buf)
2383 return;
2384
2385 ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, WLAN_EID_SSID, &ssid_ielen,
2386 (pframe-ies)-_FIXED_IE_LENGTH_);
2387
2388 ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
2389
2390 if (ssid_ie && cur_network->Ssid.SsidLength) {
2391 uint remainder_ielen;
2392 u8 *remainder_ie;
2393
2394 remainder_ie = ssid_ie+2;
2395 remainder_ielen = (pframe-remainder_ie);
2396
2397 if (remainder_ielen > MAX_IE_SZ) {
2398 netdev_warn(padapter->pnetdev,
2399 FUNC_ADPT_FMT " remainder_ielen > MAX_IE_SZ\n",
2400 FUNC_ADPT_ARG(padapter));
2401 remainder_ielen = MAX_IE_SZ;
2402 }
2403
2404 memcpy(buf, remainder_ie, remainder_ielen);
2405 memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
2406 *(ssid_ie+1) = cur_network->Ssid.SsidLength;
2407 memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
2408
2409 pframe += ssid_ielen_diff;
2410 pattrib->pktlen += ssid_ielen_diff;
2411 }
2412 kfree (buf);
2413 }
2414 } else {
2415
2416 pframe += 8;
2417 pattrib->pktlen += 8;
2418
2419
2420
2421 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
2422
2423 pframe += 2;
2424 pattrib->pktlen += 2;
2425
2426
2427
2428 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
2429
2430 pframe += 2;
2431 pattrib->pktlen += 2;
2432
2433
2434
2435
2436 pframe = rtw_set_ie(pframe, WLAN_EID_SSID, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
2437
2438
2439 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
2440 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
2441
2442
2443 pframe = rtw_set_ie(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
2444
2445 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
2446 u8 erpinfo = 0;
2447 u32 ATIMWindow;
2448
2449
2450 ATIMWindow = 0;
2451 pframe = rtw_set_ie(pframe, WLAN_EID_IBSS_PARAMS, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
2452
2453
2454 pframe = rtw_set_ie(pframe, WLAN_EID_ERP_INFO, 1, &erpinfo, &pattrib->pktlen);
2455 }
2456
2457
2458
2459 if (rate_len > 8) {
2460 pframe = rtw_set_ie(pframe, WLAN_EID_EXT_SUPP_RATES, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
2461 }
2462
2463
2464
2465
2466 }
2467
2468 pattrib->last_txcmdsz = pattrib->pktlen;
2469
2470
2471 dump_mgntframe(padapter, pmgntframe);
2472
2473 return;
2474
2475}
2476
2477static int _issue_probereq(struct adapter *padapter,
2478 struct ndis_802_11_ssid *pssid,
2479 u8 *da, u8 ch, bool append_wps, bool wait_ack)
2480{
2481 int ret = _FAIL;
2482 struct xmit_frame *pmgntframe;
2483 struct pkt_attrib *pattrib;
2484 unsigned char *pframe;
2485 struct ieee80211_hdr *pwlanhdr;
2486 __le16 *fctrl;
2487 unsigned char *mac;
2488 unsigned char bssrate[NumRates];
2489 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2490 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2491 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2492 int bssrate_len = 0;
2493
2494 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2495 if (!pmgntframe)
2496 goto exit;
2497
2498
2499 pattrib = &pmgntframe->attrib;
2500 update_mgntframe_attrib(padapter, pattrib);
2501
2502
2503 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2504
2505 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2506 pwlanhdr = (struct ieee80211_hdr *)pframe;
2507
2508 mac = myid(&(padapter->eeprompriv));
2509
2510 fctrl = &(pwlanhdr->frame_control);
2511 *(fctrl) = 0;
2512
2513 if (da) {
2514
2515 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
2516 memcpy(pwlanhdr->addr3, da, ETH_ALEN);
2517 } else {
2518
2519 eth_broadcast_addr(pwlanhdr->addr1);
2520 eth_broadcast_addr(pwlanhdr->addr3);
2521 }
2522
2523 memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
2524
2525 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2526 pmlmeext->mgnt_seq++;
2527 SetFrameSubType(pframe, WIFI_PROBEREQ);
2528
2529 pframe += sizeof(struct ieee80211_hdr_3addr);
2530 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2531
2532 if (pssid)
2533 pframe = rtw_set_ie(pframe, WLAN_EID_SSID, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
2534 else
2535 pframe = rtw_set_ie(pframe, WLAN_EID_SSID, 0, NULL, &(pattrib->pktlen));
2536
2537 get_rate_set(padapter, bssrate, &bssrate_len);
2538
2539 if (bssrate_len > 8) {
2540 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, 8, bssrate, &(pattrib->pktlen));
2541 pframe = rtw_set_ie(pframe, WLAN_EID_EXT_SUPP_RATES, (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
2542 } else {
2543 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, bssrate_len, bssrate, &(pattrib->pktlen));
2544 }
2545
2546 if (ch)
2547 pframe = rtw_set_ie(pframe, WLAN_EID_DS_PARAMS, 1, &ch, &pattrib->pktlen);
2548
2549 if (append_wps) {
2550
2551 if (pmlmepriv->wps_probe_req_ie_len > 0 && pmlmepriv->wps_probe_req_ie) {
2552 memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
2553 pframe += pmlmepriv->wps_probe_req_ie_len;
2554 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
2555 }
2556 }
2557
2558 pattrib->last_txcmdsz = pattrib->pktlen;
2559
2560 if (wait_ack) {
2561 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
2562 } else {
2563 dump_mgntframe(padapter, pmgntframe);
2564 ret = _SUCCESS;
2565 }
2566
2567exit:
2568 return ret;
2569}
2570
2571inline void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da)
2572{
2573 _issue_probereq(padapter, pssid, da, 0, 1, false);
2574}
2575
2576int issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, u8 ch, bool append_wps,
2577 int try_cnt, int wait_ms)
2578{
2579 int ret;
2580 int i = 0;
2581
2582 do {
2583 ret = _issue_probereq(padapter, pssid, da, ch, append_wps,
2584 wait_ms > 0);
2585
2586 i++;
2587
2588 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
2589 break;
2590
2591 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
2592 msleep(wait_ms);
2593
2594 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
2595
2596 if (ret != _FAIL) {
2597 ret = _SUCCESS;
2598 #ifndef DBG_XMIT_ACK
2599 goto exit;
2600 #endif
2601 }
2602
2603exit:
2604 return ret;
2605}
2606
2607
2608void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short status)
2609{
2610 struct xmit_frame *pmgntframe;
2611 struct pkt_attrib *pattrib;
2612 unsigned char *pframe;
2613 struct ieee80211_hdr *pwlanhdr;
2614 __le16 *fctrl;
2615 unsigned int val32;
2616 unsigned short val16;
2617 int use_shared_key = 0;
2618 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2619 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2620 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2621 __le16 le_tmp;
2622
2623 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2624 if (pmgntframe == NULL)
2625 return;
2626
2627
2628 pattrib = &pmgntframe->attrib;
2629 update_mgntframe_attrib(padapter, pattrib);
2630
2631 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2632
2633 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2634 pwlanhdr = (struct ieee80211_hdr *)pframe;
2635
2636 fctrl = &(pwlanhdr->frame_control);
2637 *(fctrl) = 0;
2638
2639 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2640 pmlmeext->mgnt_seq++;
2641 SetFrameSubType(pframe, WIFI_AUTH);
2642
2643 pframe += sizeof(struct ieee80211_hdr_3addr);
2644 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2645
2646
2647 if (psta) {
2648 memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
2649 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2650 memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
2651
2652
2653 val16 = (u16)psta->authalg;
2654
2655 if (status != WLAN_STATUS_SUCCESS)
2656 val16 = 0;
2657
2658 if (val16)
2659 use_shared_key = 1;
2660
2661 le_tmp = cpu_to_le16(val16);
2662
2663 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
2664
2665
2666 val16 = (u16)psta->auth_seq;
2667 le_tmp = cpu_to_le16(val16);
2668 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
2669
2670
2671 val16 = status;
2672 le_tmp = cpu_to_le16(val16);
2673 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
2674
2675
2676 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
2677 pframe = rtw_set_ie(pframe, WLAN_EID_CHALLENGE, 128, psta->chg_txt, &(pattrib->pktlen));
2678
2679 } else {
2680 memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
2681 memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
2682 memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
2683
2684
2685 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;
2686 if (val16) {
2687 use_shared_key = 1;
2688 }
2689 le_tmp = cpu_to_le16(val16);
2690
2691
2692 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
2693 __le32 le_tmp32;
2694
2695 val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
2696 le_tmp32 = cpu_to_le32(val32);
2697 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&le_tmp32, &(pattrib->pktlen));
2698
2699 pattrib->iv_len = 4;
2700 }
2701
2702 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
2703
2704
2705 le_tmp = cpu_to_le16(pmlmeinfo->auth_seq);
2706 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
2707
2708
2709
2710 le_tmp = cpu_to_le16(status);
2711 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
2712
2713
2714 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
2715 pframe = rtw_set_ie(pframe, WLAN_EID_CHALLENGE, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
2716
2717 SetPrivacy(fctrl);
2718
2719 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2720
2721 pattrib->encrypt = _WEP40_;
2722
2723 pattrib->icv_len = 4;
2724
2725 pattrib->pktlen += pattrib->icv_len;
2726
2727 }
2728
2729 }
2730
2731 pattrib->last_txcmdsz = pattrib->pktlen;
2732
2733 rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
2734 dump_mgntframe(padapter, pmgntframe);
2735}
2736
2737
2738void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
2739{
2740 struct xmit_frame *pmgntframe;
2741 struct ieee80211_hdr *pwlanhdr;
2742 struct pkt_attrib *pattrib;
2743 unsigned char *pbuf, *pframe;
2744 unsigned short val;
2745 __le16 *fctrl;
2746 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2747 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2748 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2749 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2750 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
2751 u8 *ie = pnetwork->IEs;
2752 __le16 lestatus, le_tmp;
2753
2754 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2755 if (pmgntframe == NULL)
2756 return;
2757
2758
2759 pattrib = &pmgntframe->attrib;
2760 update_mgntframe_attrib(padapter, pattrib);
2761
2762
2763 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2764
2765 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2766 pwlanhdr = (struct ieee80211_hdr *)pframe;
2767
2768 fctrl = &(pwlanhdr->frame_control);
2769 *(fctrl) = 0;
2770
2771 memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
2772 memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN);
2773 memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
2774
2775
2776 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2777 pmlmeext->mgnt_seq++;
2778 if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
2779 SetFrameSubType(pwlanhdr, pkt_type);
2780 else
2781 return;
2782
2783 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2784 pattrib->pktlen += pattrib->hdrlen;
2785 pframe += pattrib->hdrlen;
2786
2787
2788 val = *(unsigned short *)rtw_get_capability_from_ie(ie);
2789
2790 pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_, (unsigned char *)&val, &(pattrib->pktlen));
2791
2792 lestatus = cpu_to_le16(status);
2793 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&lestatus, &(pattrib->pktlen));
2794
2795 le_tmp = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
2796 pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
2797
2798 if (pstat->bssratelen <= 8) {
2799 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
2800 } else {
2801 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, 8, pstat->bssrateset, &(pattrib->pktlen));
2802 pframe = rtw_set_ie(pframe, WLAN_EID_EXT_SUPP_RATES, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
2803 }
2804
2805 if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) {
2806 uint ie_len = 0;
2807
2808
2809
2810 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_HT_CAPABILITY, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
2811 if (pbuf && ie_len > 0) {
2812 memcpy(pframe, pbuf, ie_len+2);
2813 pframe += (ie_len+2);
2814 pattrib->pktlen += (ie_len+2);
2815 }
2816
2817
2818
2819 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_HT_OPERATION, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
2820 if (pbuf && ie_len > 0) {
2821 memcpy(pframe, pbuf, ie_len+2);
2822 pframe += (ie_len+2);
2823 pattrib->pktlen += (ie_len+2);
2824 }
2825
2826 }
2827
2828
2829 if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) {
2830 uint ie_len = 0;
2831 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
2832
2833 for (pbuf = ie + _BEACON_IE_OFFSET_; ; pbuf += (ie_len + 2)) {
2834 pbuf = rtw_get_ie(pbuf, WLAN_EID_VENDOR_SPECIFIC, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
2835 if (pbuf && !memcmp(pbuf+2, WMM_PARA_IE, 6)) {
2836 memcpy(pframe, pbuf, ie_len+2);
2837 pframe += (ie_len+2);
2838 pattrib->pktlen += (ie_len+2);
2839
2840 break;
2841 }
2842
2843 if ((pbuf == NULL) || (ie_len == 0)) {
2844 break;
2845 }
2846 }
2847
2848 }
2849
2850 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) {
2851 pframe = rtw_set_ie(pframe, WLAN_EID_VENDOR_SPECIFIC, 6, REALTEK_96B_IE, &(pattrib->pktlen));
2852 }
2853
2854
2855 if (pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len > 0) {
2856 memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
2857
2858 pframe += pmlmepriv->wps_assoc_resp_ie_len;
2859 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
2860 }
2861
2862 pattrib->last_txcmdsz = pattrib->pktlen;
2863
2864 dump_mgntframe(padapter, pmgntframe);
2865}
2866
2867void issue_assocreq(struct adapter *padapter)
2868{
2869 int ret = _FAIL;
2870 struct xmit_frame *pmgntframe;
2871 struct pkt_attrib *pattrib;
2872 unsigned char *pframe;
2873 struct ieee80211_hdr *pwlanhdr;
2874 __le16 *fctrl;
2875 __le16 val16;
2876 unsigned int i, j, index = 0;
2877 unsigned char bssrate[NumRates], sta_bssrate[NumRates];
2878 struct ndis_80211_var_ie *pIE;
2879 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2880 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2881 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2882 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2883 int bssrate_len = 0, sta_bssrate_len = 0;
2884 u8 vs_ie_length = 0;
2885
2886 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
2887 if (pmgntframe == NULL)
2888 goto exit;
2889
2890
2891 pattrib = &pmgntframe->attrib;
2892 update_mgntframe_attrib(padapter, pattrib);
2893
2894 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2895
2896 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2897 pwlanhdr = (struct ieee80211_hdr *)pframe;
2898
2899 fctrl = &(pwlanhdr->frame_control);
2900 *(fctrl) = 0;
2901 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
2902 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2903 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
2904
2905 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2906 pmlmeext->mgnt_seq++;
2907 SetFrameSubType(pframe, WIFI_ASSOCREQ);
2908
2909 pframe += sizeof(struct ieee80211_hdr_3addr);
2910 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2911
2912
2913 memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
2914
2915 pframe += 2;
2916 pattrib->pktlen += 2;
2917
2918
2919
2920 val16 = cpu_to_le16(3);
2921 memcpy(pframe, (unsigned char *)&val16, 2);
2922 pframe += 2;
2923 pattrib->pktlen += 2;
2924
2925
2926 pframe = rtw_set_ie(pframe, WLAN_EID_SSID, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
2927
2928
2929
2930
2931 get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
2932
2933 if (pmlmeext->cur_channel == 14)
2934 sta_bssrate_len = 4;
2935
2936
2937
2938
2939
2940 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
2941 if (pmlmeinfo->network.SupportedRates[i] == 0)
2942 break;
2943 }
2944
2945
2946 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
2947 if (pmlmeinfo->network.SupportedRates[i] == 0)
2948 break;
2949
2950
2951
2952 for (j = 0; j < sta_bssrate_len; j++) {
2953
2954 if ((pmlmeinfo->network.SupportedRates[i] | IEEE80211_BASIC_RATE_MASK)
2955 == (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK))
2956 break;
2957 }
2958
2959 if (j != sta_bssrate_len)
2960
2961 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
2962 }
2963
2964 bssrate_len = index;
2965
2966 if (bssrate_len == 0) {
2967 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
2968 rtw_free_xmitframe(pxmitpriv, pmgntframe);
2969 goto exit;
2970 }
2971
2972
2973 if (bssrate_len > 8) {
2974 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, 8, bssrate, &(pattrib->pktlen));
2975 pframe = rtw_set_ie(pframe, WLAN_EID_EXT_SUPP_RATES, (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
2976 } else
2977 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, bssrate_len, bssrate, &(pattrib->pktlen));
2978
2979
2980 for (i = sizeof(struct ndis_802_11_fix_ie); i < pmlmeinfo->network.IELength;) {
2981 pIE = (struct ndis_80211_var_ie *)(pmlmeinfo->network.IEs + i);
2982
2983 switch (pIE->ElementID) {
2984 case WLAN_EID_VENDOR_SPECIFIC:
2985 if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
2986 (!memcmp(pIE->data, WMM_OUI, 4)) ||
2987 (!memcmp(pIE->data, WPS_OUI, 4))) {
2988 vs_ie_length = pIE->Length;
2989 if ((!padapter->registrypriv.wifi_spec) && (!memcmp(pIE->data, WPS_OUI, 4))) {
2990
2991
2992
2993
2994
2995
2996 vs_ie_length = 14;
2997 }
2998
2999 pframe = rtw_set_ie(pframe, WLAN_EID_VENDOR_SPECIFIC, vs_ie_length, pIE->data, &(pattrib->pktlen));
3000 }
3001 break;
3002
3003 case WLAN_EID_RSN:
3004 pframe = rtw_set_ie(pframe, WLAN_EID_RSN, pIE->Length, pIE->data, &(pattrib->pktlen));
3005 break;
3006 case WLAN_EID_HT_CAPABILITY:
3007 if (padapter->mlmepriv.htpriv.ht_option) {
3008 if (!(is_ap_in_tkip(padapter))) {
3009 memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
3010 pframe = rtw_set_ie(pframe, WLAN_EID_HT_CAPABILITY, pIE->Length, (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
3011 }
3012 }
3013 break;
3014
3015 case WLAN_EID_EXT_CAPABILITY:
3016 if (padapter->mlmepriv.htpriv.ht_option)
3017 pframe = rtw_set_ie(pframe, WLAN_EID_EXT_CAPABILITY, pIE->Length, pIE->data, &(pattrib->pktlen));
3018 break;
3019 default:
3020 break;
3021 }
3022
3023 i += (pIE->Length + 2);
3024 }
3025
3026 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
3027 pframe = rtw_set_ie(pframe, WLAN_EID_VENDOR_SPECIFIC, 6, REALTEK_96B_IE, &(pattrib->pktlen));
3028
3029
3030 pattrib->last_txcmdsz = pattrib->pktlen;
3031 dump_mgntframe(padapter, pmgntframe);
3032
3033 ret = _SUCCESS;
3034
3035exit:
3036 if (ret == _SUCCESS)
3037 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
3038 else
3039 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
3040}
3041
3042
3043static int _issue_nulldata(struct adapter *padapter, unsigned char *da,
3044 unsigned int power_mode, bool wait_ack)
3045{
3046 int ret = _FAIL;
3047 struct xmit_frame *pmgntframe;
3048 struct pkt_attrib *pattrib;
3049 unsigned char *pframe;
3050 struct ieee80211_hdr *pwlanhdr;
3051 __le16 *fctrl;
3052 struct xmit_priv *pxmitpriv;
3053 struct mlme_ext_priv *pmlmeext;
3054 struct mlme_ext_info *pmlmeinfo;
3055
3056 if (!padapter)
3057 goto exit;
3058
3059 pxmitpriv = &(padapter->xmitpriv);
3060 pmlmeext = &(padapter->mlmeextpriv);
3061 pmlmeinfo = &(pmlmeext->mlmext_info);
3062
3063 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3064 if (pmgntframe == NULL)
3065 goto exit;
3066
3067
3068 pattrib = &pmgntframe->attrib;
3069 update_mgntframe_attrib(padapter, pattrib);
3070 pattrib->retry_ctrl = false;
3071
3072 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3073
3074 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3075 pwlanhdr = (struct ieee80211_hdr *)pframe;
3076
3077 fctrl = &(pwlanhdr->frame_control);
3078 *(fctrl) = 0;
3079
3080 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3081 SetFrDs(fctrl);
3082 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3083 SetToDs(fctrl);
3084
3085 if (power_mode)
3086 SetPwrMgt(fctrl);
3087
3088 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3089 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3090 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3091
3092 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3093 pmlmeext->mgnt_seq++;
3094 SetFrameSubType(pframe, WIFI_DATA_NULL);
3095
3096 pframe += sizeof(struct ieee80211_hdr_3addr);
3097 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3098
3099 pattrib->last_txcmdsz = pattrib->pktlen;
3100
3101 if (wait_ack) {
3102 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
3103 } else {
3104 dump_mgntframe(padapter, pmgntframe);
3105 ret = _SUCCESS;
3106 }
3107
3108exit:
3109 return ret;
3110}
3111
3112
3113
3114
3115
3116
3117
3118int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
3119{
3120 int ret;
3121 int i = 0;
3122 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3123 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3124 struct sta_info *psta;
3125
3126
3127
3128 if (!da)
3129 da = get_my_bssid(&(pmlmeinfo->network));
3130
3131 psta = rtw_get_stainfo(&padapter->stapriv, da);
3132 if (psta) {
3133 if (power_mode)
3134 rtw_hal_macid_sleep(padapter, psta->mac_id);
3135 else
3136 rtw_hal_macid_wakeup(padapter, psta->mac_id);
3137 } else {
3138 rtw_warn_on(1);
3139 }
3140
3141 do {
3142 ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0);
3143
3144 i++;
3145
3146 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3147 break;
3148
3149 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3150 msleep(wait_ms);
3151
3152 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3153
3154 if (ret != _FAIL) {
3155 ret = _SUCCESS;
3156 #ifndef DBG_XMIT_ACK
3157 goto exit;
3158 #endif
3159 }
3160
3161exit:
3162 return ret;
3163}
3164
3165
3166
3167
3168
3169
3170
3171s32 issue_nulldata_in_interrupt(struct adapter *padapter, u8 *da)
3172{
3173 struct mlme_ext_priv *pmlmeext;
3174 struct mlme_ext_info *pmlmeinfo;
3175
3176
3177 pmlmeext = &padapter->mlmeextpriv;
3178 pmlmeinfo = &pmlmeext->mlmext_info;
3179
3180
3181 if (!da)
3182 da = get_my_bssid(&(pmlmeinfo->network));
3183
3184 return _issue_nulldata(padapter, da, 0, false);
3185}
3186
3187
3188static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da,
3189 u16 tid, bool wait_ack)
3190{
3191 int ret = _FAIL;
3192 struct xmit_frame *pmgntframe;
3193 struct pkt_attrib *pattrib;
3194 unsigned char *pframe;
3195 struct ieee80211_hdr *pwlanhdr;
3196 __le16 *fctrl;
3197 u16 *qc;
3198 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3199 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3200 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3201
3202 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3203 if (pmgntframe == NULL)
3204 goto exit;
3205
3206
3207 pattrib = &pmgntframe->attrib;
3208 update_mgntframe_attrib(padapter, pattrib);
3209
3210 pattrib->hdrlen += 2;
3211 pattrib->qos_en = true;
3212 pattrib->eosp = 1;
3213 pattrib->ack_policy = 0;
3214 pattrib->mdata = 0;
3215
3216 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3217
3218 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3219 pwlanhdr = (struct ieee80211_hdr *)pframe;
3220
3221 fctrl = &(pwlanhdr->frame_control);
3222 *(fctrl) = 0;
3223
3224 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3225 SetFrDs(fctrl);
3226 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3227 SetToDs(fctrl);
3228
3229 if (pattrib->mdata)
3230 SetMData(fctrl);
3231
3232 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
3233
3234 SetPriority(qc, tid);
3235
3236 SetEOSP(qc, pattrib->eosp);
3237
3238 SetAckpolicy(qc, pattrib->ack_policy);
3239
3240 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3241 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3242 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3243
3244 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3245 pmlmeext->mgnt_seq++;
3246 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
3247
3248 pframe += sizeof(struct ieee80211_qos_hdr);
3249 pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
3250
3251 pattrib->last_txcmdsz = pattrib->pktlen;
3252
3253 if (wait_ack) {
3254 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
3255 } else {
3256 dump_mgntframe(padapter, pmgntframe);
3257 ret = _SUCCESS;
3258 }
3259
3260exit:
3261 return ret;
3262}
3263
3264
3265
3266int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
3267{
3268 int ret;
3269 int i = 0;
3270 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3271 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3272
3273
3274 if (!da)
3275 da = get_my_bssid(&(pmlmeinfo->network));
3276
3277 do {
3278 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms > 0);
3279
3280 i++;
3281
3282 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3283 break;
3284
3285 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3286 msleep(wait_ms);
3287
3288 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3289
3290 if (ret != _FAIL) {
3291 ret = _SUCCESS;
3292 #ifndef DBG_XMIT_ACK
3293 goto exit;
3294 #endif
3295 }
3296
3297exit:
3298 return ret;
3299}
3300
3301static int _issue_deauth(struct adapter *padapter, unsigned char *da,
3302 unsigned short reason, bool wait_ack)
3303{
3304 struct xmit_frame *pmgntframe;
3305 struct pkt_attrib *pattrib;
3306 unsigned char *pframe;
3307 struct ieee80211_hdr *pwlanhdr;
3308 __le16 *fctrl;
3309 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3310 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3311 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3312 int ret = _FAIL;
3313 __le16 le_tmp;
3314
3315 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3316 if (pmgntframe == NULL) {
3317 goto exit;
3318 }
3319
3320
3321 pattrib = &pmgntframe->attrib;
3322 update_mgntframe_attrib(padapter, pattrib);
3323 pattrib->retry_ctrl = false;
3324
3325 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3326
3327 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3328 pwlanhdr = (struct ieee80211_hdr *)pframe;
3329
3330 fctrl = &(pwlanhdr->frame_control);
3331 *(fctrl) = 0;
3332
3333 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3334 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3335 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3336
3337 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3338 pmlmeext->mgnt_seq++;
3339 SetFrameSubType(pframe, WIFI_DEAUTH);
3340
3341 pframe += sizeof(struct ieee80211_hdr_3addr);
3342 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3343
3344 le_tmp = cpu_to_le16(reason);
3345 pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen));
3346
3347 pattrib->last_txcmdsz = pattrib->pktlen;
3348
3349
3350 if (wait_ack) {
3351 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
3352 } else {
3353 dump_mgntframe(padapter, pmgntframe);
3354 ret = _SUCCESS;
3355 }
3356
3357exit:
3358 return ret;
3359}
3360
3361int issue_deauth(struct adapter *padapter, unsigned char *da, unsigned short reason)
3362{
3363 return _issue_deauth(padapter, da, reason, false);
3364}
3365
3366int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
3367 int wait_ms)
3368{
3369 int ret;
3370 int i = 0;
3371
3372 do {
3373 ret = _issue_deauth(padapter, da, reason, wait_ms > 0);
3374
3375 i++;
3376
3377 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3378 break;
3379
3380 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3381 mdelay(wait_ms);
3382
3383 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3384
3385 if (ret != _FAIL) {
3386 ret = _SUCCESS;
3387 #ifndef DBG_XMIT_ACK
3388 goto exit;
3389 #endif
3390 }
3391
3392exit:
3393 return ret;
3394}
3395
3396void issue_action_SA_Query(struct adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid)
3397{
3398 u8 category = RTW_WLAN_CATEGORY_SA_QUERY;
3399 struct xmit_frame *pmgntframe;
3400 struct pkt_attrib *pattrib;
3401 u8 *pframe;
3402 struct ieee80211_hdr *pwlanhdr;
3403 __le16 *fctrl;
3404 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3405 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3406 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3407 __le16 le_tmp;
3408
3409 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3410 if (!pmgntframe)
3411 return;
3412
3413
3414 pattrib = &pmgntframe->attrib;
3415 update_mgntframe_attrib(padapter, pattrib);
3416
3417 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3418
3419 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3420 pwlanhdr = (struct ieee80211_hdr *)pframe;
3421
3422 fctrl = &(pwlanhdr->frame_control);
3423 *(fctrl) = 0;
3424
3425 if (raddr)
3426 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3427 else
3428 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3429 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3430 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3431
3432 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3433 pmlmeext->mgnt_seq++;
3434 SetFrameSubType(pframe, WIFI_ACTION);
3435
3436 pframe += sizeof(struct ieee80211_hdr_3addr);
3437 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3438
3439 pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
3440 pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
3441
3442 switch (action) {
3443 case 0:
3444 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
3445 pmlmeext->sa_query_seq++;
3446
3447 set_sa_query_timer(pmlmeext, 1000);
3448 break;
3449
3450 case 1:
3451 le_tmp = cpu_to_le16(tid);
3452 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
3453 break;
3454 default:
3455 break;
3456 }
3457
3458 pattrib->last_txcmdsz = pattrib->pktlen;
3459
3460 dump_mgntframe(padapter, pmgntframe);
3461}
3462
3463void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status)
3464{
3465 u8 category = RTW_WLAN_CATEGORY_BACK;
3466 u16 start_seq;
3467 u16 BA_para_set;
3468 u16 reason_code;
3469 u16 BA_timeout_value;
3470 u16 BA_starting_seqctrl = 0;
3471 enum ieee80211_max_ampdu_length_exp max_rx_ampdu_factor;
3472 struct xmit_frame *pmgntframe;
3473 struct pkt_attrib *pattrib;
3474 u8 *pframe;
3475 struct ieee80211_hdr *pwlanhdr;
3476 __le16 *fctrl;
3477 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3478 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3479 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3480 struct sta_info *psta;
3481 struct sta_priv *pstapriv = &padapter->stapriv;
3482 struct registry_priv *pregpriv = &padapter->registrypriv;
3483 __le16 le_tmp;
3484
3485 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3486 if (!pmgntframe)
3487 return;
3488
3489
3490 pattrib = &pmgntframe->attrib;
3491 update_mgntframe_attrib(padapter, pattrib);
3492
3493 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3494
3495 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3496 pwlanhdr = (struct ieee80211_hdr *)pframe;
3497
3498 fctrl = &(pwlanhdr->frame_control);
3499 *(fctrl) = 0;
3500
3501
3502 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3503 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3504 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3505
3506 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3507 pmlmeext->mgnt_seq++;
3508 SetFrameSubType(pframe, WIFI_ACTION);
3509
3510 pframe += sizeof(struct ieee80211_hdr_3addr);
3511 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3512
3513 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3514 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3515
3516 if (category == 3) {
3517 switch (action) {
3518 case 0:
3519 do {
3520 pmlmeinfo->dialogToken++;
3521 } while (pmlmeinfo->dialogToken == 0);
3522 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
3523
3524 if (hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter)) {
3525
3526 BA_para_set = 0;
3527
3528 BA_para_set |= BIT(1) & IEEE80211_ADDBA_PARAM_POLICY_MASK;
3529
3530 BA_para_set |= (status << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
3531
3532 BA_para_set |= (8 << 6) & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3533 } else {
3534 BA_para_set = (0x1002 | ((status & 0xf) << 2));
3535 }
3536 le_tmp = cpu_to_le16(BA_para_set);
3537 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
3538
3539 BA_timeout_value = 5000;
3540 le_tmp = cpu_to_le16(BA_timeout_value);
3541 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
3542
3543
3544 psta = rtw_get_stainfo(pstapriv, raddr);
3545 if (psta) {
3546 start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
3547
3548 psta->BA_starting_seqctrl[status & 0x07] = start_seq;
3549
3550 BA_starting_seqctrl = start_seq << 4;
3551 }
3552
3553 le_tmp = cpu_to_le16(BA_starting_seqctrl);
3554 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
3555 break;
3556
3557 case 1:
3558 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
3559 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
3560 if (padapter->driver_rx_ampdu_factor != 0xFF)
3561 max_rx_ampdu_factor =
3562 (enum ieee80211_max_ampdu_length_exp)padapter->driver_rx_ampdu_factor;
3563 else
3564 rtw_hal_get_def_var(padapter,
3565 HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
3566
3567 if (IEEE80211_HT_MAX_AMPDU_64K == max_rx_ampdu_factor)
3568 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000);
3569 else if (IEEE80211_HT_MAX_AMPDU_32K == max_rx_ampdu_factor)
3570 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800);
3571 else if (IEEE80211_HT_MAX_AMPDU_16K == max_rx_ampdu_factor)
3572 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400);
3573 else if (IEEE80211_HT_MAX_AMPDU_8K == max_rx_ampdu_factor)
3574 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200);
3575 else
3576 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000);
3577
3578 if (hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter) &&
3579 padapter->driver_rx_ampdu_factor == 0xFF) {
3580
3581 BA_para_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3582 BA_para_set |= (8 << 6) & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
3583 }
3584
3585 if (pregpriv->ampdu_amsdu == 0)
3586 le_tmp = cpu_to_le16(BA_para_set & ~BIT(0));
3587 else if (pregpriv->ampdu_amsdu == 1)
3588 le_tmp = cpu_to_le16(BA_para_set | BIT(0));
3589 else
3590 le_tmp = cpu_to_le16(BA_para_set);
3591
3592 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
3593 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
3594 break;
3595 case 2:
3596 BA_para_set = (status & 0x1F) << 3;
3597 le_tmp = cpu_to_le16(BA_para_set);
3598 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
3599
3600 reason_code = 37;
3601 le_tmp = cpu_to_le16(reason_code);
3602 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen));
3603 break;
3604 default:
3605 break;
3606 }
3607 }
3608
3609 pattrib->last_txcmdsz = pattrib->pktlen;
3610
3611 dump_mgntframe(padapter, pmgntframe);
3612}
3613
3614static void issue_action_BSSCoexistPacket(struct adapter *padapter)
3615{
3616 struct list_head *plist, *phead;
3617 unsigned char category, action;
3618 struct xmit_frame *pmgntframe;
3619 struct pkt_attrib *pattrib;
3620 unsigned char *pframe;
3621 struct ieee80211_hdr *pwlanhdr;
3622 __le16 *fctrl;
3623 struct wlan_network *pnetwork = NULL;
3624 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3625 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3626 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3627 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3628 struct __queue *queue = &(pmlmepriv->scanned_queue);
3629 u8 InfoContent[16] = {0};
3630 u8 ICS[8][15];
3631
3632 if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0))
3633 return;
3634
3635 if (true == pmlmeinfo->bwmode_updated)
3636 return;
3637
3638 category = RTW_WLAN_CATEGORY_PUBLIC;
3639 action = ACT_PUBLIC_BSSCOEXIST;
3640
3641 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3642 if (pmgntframe == NULL) {
3643 return;
3644 }
3645
3646
3647 pattrib = &pmgntframe->attrib;
3648 update_mgntframe_attrib(padapter, pattrib);
3649
3650 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3651
3652 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3653 pwlanhdr = (struct ieee80211_hdr *)pframe;
3654
3655 fctrl = &(pwlanhdr->frame_control);
3656 *(fctrl) = 0;
3657
3658 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3659 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3660 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3661
3662 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3663 pmlmeext->mgnt_seq++;
3664 SetFrameSubType(pframe, WIFI_ACTION);
3665
3666 pframe += sizeof(struct ieee80211_hdr_3addr);
3667 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3668
3669 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3670 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3671
3672
3673
3674 if (pmlmepriv->num_FortyMHzIntolerant > 0) {
3675 u8 iedata = 0;
3676
3677 iedata |= BIT(2);
3678
3679 pframe = rtw_set_ie(pframe, WLAN_EID_BSS_COEX_2040, 1, &iedata, &(pattrib->pktlen));
3680
3681 }
3682
3683
3684
3685 memset(ICS, 0, sizeof(ICS));
3686 if (pmlmepriv->num_sta_no_ht > 0) {
3687 int i;
3688
3689 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
3690
3691 phead = get_list_head(queue);
3692 plist = get_next(phead);
3693
3694 while (1) {
3695 int len;
3696 u8 *p;
3697 struct wlan_bssid_ex *pbss_network;
3698
3699 if (phead == plist)
3700 break;
3701
3702 pnetwork = container_of(plist, struct wlan_network, list);
3703
3704 plist = get_next(plist);
3705
3706 pbss_network = (struct wlan_bssid_ex *)&pnetwork->network;
3707
3708 p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, WLAN_EID_HT_CAPABILITY, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
3709 if ((p == NULL) || (len == 0)) {
3710
3711 if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14))
3712 continue;
3713
3714 ICS[0][pbss_network->Configuration.DSConfig] = 1;
3715
3716 if (ICS[0][0] == 0)
3717 ICS[0][0] = 1;
3718 }
3719
3720 }
3721
3722 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
3723
3724
3725 for (i = 0; i < 8; i++) {
3726 if (ICS[i][0] == 1) {
3727 int j, k = 0;
3728
3729 InfoContent[k] = i;
3730
3731 k++;
3732
3733 for (j = 1; j <= 14; j++) {
3734 if (ICS[i][j] == 1) {
3735 if (k < 16) {
3736 InfoContent[k] = j;
3737
3738 k++;
3739 }
3740 }
3741 }
3742
3743 pframe = rtw_set_ie(pframe, WLAN_EID_BSS_INTOLERANT_CHL_REPORT, k, InfoContent, &(pattrib->pktlen));
3744
3745 }
3746
3747 }
3748
3749
3750 }
3751
3752
3753 pattrib->last_txcmdsz = pattrib->pktlen;
3754
3755 dump_mgntframe(padapter, pmgntframe);
3756}
3757
3758unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr)
3759{
3760 struct sta_priv *pstapriv = &padapter->stapriv;
3761 struct sta_info *psta = NULL;
3762
3763 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3764 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3765 u16 tid;
3766
3767 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
3768 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
3769 return _SUCCESS;
3770
3771 psta = rtw_get_stainfo(pstapriv, addr);
3772 if (psta == NULL)
3773 return _SUCCESS;
3774
3775 if (initiator == 0) {
3776 for (tid = 0; tid < MAXTID; tid++) {
3777 if (psta->recvreorder_ctrl[tid].enable) {
3778 issue_action_BA(padapter, addr, WLAN_ACTION_DELBA, (((tid << 1) | initiator)&0x1F));
3779 psta->recvreorder_ctrl[tid].enable = false;
3780 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
3781 }
3782 }
3783 } else if (initiator == 1) {
3784 for (tid = 0; tid < MAXTID; tid++) {
3785 if (psta