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 (is_supported_24g(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.ssid_length))
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.mac_address, 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.ssid_length))
1026 status = WLAN_STATUS_CHALLENGE_FAIL;
1027
1028 if (ie_len != cur->ssid.ssid_length)
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->element_id) {
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.supported_rates);
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->ie_length);
2185 len_diff = update_hidden_ssid(pframe+_BEACON_IE_OFFSET_,
2186 cur_network->ie_length-_BEACON_IE_OFFSET_,
2187 pmlmeinfo->hidden_ssid_mode);
2188 pframe += (cur_network->ie_length+len_diff);
2189 pattrib->pktlen += (cur_network->ie_length+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.ssid_length, cur_network->ssid.ssid, &pattrib->pktlen);
2234
2235
2236 rate_len = rtw_get_rateset_len(cur_network->supported_rates);
2237 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, ((rate_len > 8) ? 8 : rate_len), cur_network->supported_rates, &pattrib->pktlen);
2238
2239
2240 pframe = rtw_set_ie(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)&(cur_network->configuration.ds_config), &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->supported_rates + 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->mac_address;
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->ie_length > 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->ie_length-_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->ie_length - 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->ie_length);
2369 pframe += cur_network->ie_length;
2370 pattrib->pktlen += cur_network->ie_length;
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.ssid_length - ssid_ielen;
2389
2390 if (ssid_ie && cur_network->ssid.ssid_length) {
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.ssid_length;
2407 memcpy(ssid_ie+2, cur_network->ssid.ssid, cur_network->ssid.ssid_length);
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.ssid_length, cur_network->ssid.ssid, &pattrib->pktlen);
2437
2438
2439 rate_len = rtw_get_rateset_len(cur_network->supported_rates);
2440 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, ((rate_len > 8) ? 8 : rate_len), cur_network->supported_rates, &pattrib->pktlen);
2441
2442
2443 pframe = rtw_set_ie(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)&(cur_network->configuration.ds_config), &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->supported_rates + 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->ssid_length, 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->ie_length - _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->ie_length - _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->ie_length - _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.ssid_length, 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.supported_rates[i] == 0)
2942 break;
2943 }
2944
2945
2946 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
2947 if (pmlmeinfo->network.supported_rates[i] == 0)
2948 break;
2949
2950
2951
2952 for (j = 0; j < sta_bssrate_len; j++) {
2953
2954 if ((pmlmeinfo->network.supported_rates[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.supported_rates[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.ie_length;) {
2981 pIE = (struct ndis_80211_var_ie *)(pmlmeinfo->network.ies + i);
2982
2983 switch (pIE->element_id) {
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->ie_length - _FIXED_IE_LENGTH_);
3709 if ((p == NULL) || (len == 0)) {
3710
3711 if (pbss_network->configuration.ds_config <= 0)
3712 continue;
3713
3714 ICS[0][pbss_network->configuration.ds_config] = 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->htpriv.agg_enable_bitmap & BIT(tid)) {
3786 issue_action_BA(padapter, addr, WLAN_ACTION_DELBA, (((tid << 1) | initiator)&0x1F));
3787 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3788 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
3789
3790 }
3791 }
3792 }
3793
3794 return _SUCCESS;
3795
3796}
3797
3798unsigned int send_beacon(struct adapter *padapter)
3799{
3800 u8 bxmitok = false;
3801 int issue = 0;
3802 int poll = 0;
3803
3804 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
3805 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
3806 do {
3807 issue_beacon(padapter, 100);
3808 issue++;
3809 do {
3810 cond_resched();
3811 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
3812 poll++;
3813 } while ((poll%10) != 0 && false == bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
3814
3815 } while (false == bxmitok && issue < 100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
3816
3817 if (padapter->bSurpriseRemoved || padapter->bDriverStopped) {
3818 return _FAIL;
3819 }
3820
3821
3822 if (!bxmitok)
3823 return _FAIL;
3824 else
3825 return _SUCCESS;
3826}
3827
3828
3829
3830
3831
3832
3833
3834void site_survey(struct adapter *padapter)
3835{
3836 unsigned char survey_channel = 0, val8;
3837 enum rt_scan_type ScanType = SCAN_PASSIVE;
3838 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3839 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3840 u32 initialgain = 0;
3841 u32 channel_scan_time_ms = 0;
3842
3843 {
3844 struct rtw_ieee80211_channel *ch;
3845
3846 if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
3847 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
3848 survey_channel = ch->hw_value;
3849 ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
3850 }
3851 }
3852
3853 if (survey_channel != 0) {
3854
3855
3856
3857
3858 if (pmlmeext->sitesurvey_res.channel_idx == 0) {
3859#ifdef DBG_FIXED_CHAN
3860 if (pmlmeext->fixed_chan != 0xff)
3861 set_channel_bwmode(padapter, pmlmeext->fixed_chan, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
3862 else
3863#endif
3864 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
3865 } else {
3866#ifdef DBG_FIXED_CHAN
3867 if (pmlmeext->fixed_chan != 0xff)
3868 SelectChannel(padapter, pmlmeext->fixed_chan);
3869 else
3870#endif
3871 SelectChannel(padapter, survey_channel);
3872 }
3873
3874 if (ScanType == SCAN_ACTIVE) {
3875 {
3876 int i;
3877
3878 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
3879 if (pmlmeext->sitesurvey_res.ssid[i].ssid_length) {
3880
3881 if (padapter->registrypriv.wifi_spec)
3882 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
3883 else
3884 issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
3885 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
3886 }
3887 }
3888
3889 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
3890
3891 if (padapter->registrypriv.wifi_spec)
3892 issue_probereq(padapter, NULL, NULL);
3893 else
3894 issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
3895 issue_probereq(padapter, NULL, NULL);
3896 }
3897 }
3898 }
3899
3900 channel_scan_time_ms = pmlmeext->chan_scan_time;
3901
3902 set_survey_timer(pmlmeext, channel_scan_time_ms);
3903 } else {
3904
3905
3906
3907 {
3908 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
3909
3910
3911
3912
3913 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
3914
3915
3916
3917
3918
3919
3920 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
3921
3922 initialgain = 0xff;
3923 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
3924
3925 Restore_DM_Func_Flag(padapter);
3926
3927
3928 if (is_client_associated_to_ap(padapter))
3929 issue_nulldata(padapter, NULL, 0, 3, 500);
3930
3931 val8 = 0;
3932 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
3933
3934 report_surveydone_event(padapter);
3935
3936 pmlmeext->chan_scan_time = SURVEY_TO;
3937 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
3938
3939 issue_action_BSSCoexistPacket(padapter);
3940 issue_action_BSSCoexistPacket(padapter);
3941 issue_action_BSSCoexistPacket(padapter);
3942 }
3943 }
3944
3945 return;
3946
3947}
3948
3949
3950u8 collect_bss_info(struct adapter *padapter, union recv_frame *precv_frame, struct wlan_bssid_ex *bssid)
3951{
3952 int i;
3953 u32 len;
3954 u8 *p;
3955 u16 val16, subtype;
3956 u8 *pframe = precv_frame->u.hdr.rx_data;
3957 u32 packet_len = precv_frame->u.hdr.len;
3958 u8 ie_offset;
3959 struct registry_priv *pregistrypriv = &padapter->registrypriv;
3960 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3961 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3962 __le32 le32_tmp;
3963
3964 len = packet_len - sizeof(struct ieee80211_hdr_3addr);
3965
3966 if (len > MAX_IE_SZ)
3967 return _FAIL;
3968
3969 memset(bssid, 0, sizeof(struct wlan_bssid_ex));
3970
3971 subtype = GetFrameSubType(pframe);
3972
3973 if (subtype == WIFI_BEACON) {
3974 bssid->reserved[0] = 1;
3975 ie_offset = _BEACON_IE_OFFSET_;
3976 } else {
3977
3978 if (subtype == WIFI_PROBERSP) {
3979 ie_offset = _PROBERSP_IE_OFFSET_;
3980 bssid->reserved[0] = 3;
3981 } else if (subtype == WIFI_PROBEREQ) {
3982 ie_offset = _PROBEREQ_IE_OFFSET_;
3983 bssid->reserved[0] = 2;
3984 } else {
3985 bssid->reserved[0] = 0;
3986 ie_offset = _FIXED_IE_LENGTH_;
3987 }
3988 }
3989
3990 bssid->length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len;
3991
3992
3993 bssid->ie_length = len;
3994 memcpy(bssid->ies, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->ie_length);
3995
3996
3997 bssid->rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower;
3998 bssid->phy_info.signal_quality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;
3999 bssid->phy_info.signal_strength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;
4000
4001
4002 p = rtw_get_ie(bssid->ies + ie_offset, WLAN_EID_SSID, &len, bssid->ie_length - ie_offset);
4003 if (!p)
4004 return _FAIL;
4005
4006 if (*(p + 1)) {
4007 if (len > NDIS_802_11_LENGTH_SSID)
4008 return _FAIL;
4009
4010 memcpy(bssid->ssid.ssid, (p + 2), *(p + 1));
4011 bssid->ssid.ssid_length = *(p + 1);
4012 } else
4013 bssid->ssid.ssid_length = 0;
4014
4015 memset(bssid->supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
4016
4017
4018 i = 0;
4019 p = rtw_get_ie(bssid->ies + ie_offset, WLAN_EID_SUPP_RATES, &len, bssid->ie_length - ie_offset);
4020 if (p) {
4021 if (len > NDIS_802_11_LENGTH_RATES_EX)
4022 return _FAIL;
4023
4024 memcpy(bssid->supported_rates, (p + 2), len);
4025 i = len;
4026 }
4027
4028 p = rtw_get_ie(bssid->ies + ie_offset, WLAN_EID_EXT_SUPP_RATES, &len, bssid->ie_length - ie_offset);
4029 if (p) {
4030 if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
4031 return _FAIL;
4032
4033 memcpy(bssid->supported_rates + i, (p + 2), len);
4034 }
4035
4036 bssid->network_type_in_use = Ndis802_11OFDM24;
4037
4038 if (bssid->ie_length < 12)
4039 return _FAIL;
4040
4041
4042 p = rtw_get_ie(bssid->ies + ie_offset, WLAN_EID_DS_PARAMS, &len, bssid->ie_length - ie_offset);
4043
4044 bssid->configuration.ds_config = 0;
4045 bssid->configuration.length = 0;
4046
4047 if (p) {
4048 bssid->configuration.ds_config = *(p + 2);
4049 } else {
4050
4051
4052 p = rtw_get_ie(bssid->ies + ie_offset, WLAN_EID_HT_OPERATION, &len, bssid->ie_length - ie_offset);
4053 if (p) {
4054 struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
4055
4056 bssid->configuration.ds_config = HT_info->primary_channel;
4057 } else {
4058 bssid->configuration.ds_config = rtw_get_oper_ch(padapter);
4059 }
4060 }
4061
4062 memcpy(&le32_tmp, rtw_get_beacon_interval_from_ie(bssid->ies), 2);
4063 bssid->configuration.beacon_period = le32_to_cpu(le32_tmp);
4064
4065 val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid);
4066
4067 if (val16 & BIT(0)) {
4068 bssid->infrastructure_mode = Ndis802_11Infrastructure;
4069 memcpy(bssid->mac_address, GetAddr2Ptr(pframe), ETH_ALEN);
4070 } else {
4071 bssid->infrastructure_mode = Ndis802_11IBSS;
4072 memcpy(bssid->mac_address, GetAddr3Ptr(pframe), ETH_ALEN);
4073 }
4074
4075 if (val16 & BIT(4))
4076 bssid->privacy = 1;
4077 else
4078 bssid->privacy = 0;
4079
4080 bssid->configuration.atim_window = 0;
4081
4082
4083 if ((pregistrypriv->wifi_spec == 1) && (false == pmlmeinfo->bwmode_updated)) {
4084 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4085
4086 p = rtw_get_ie(bssid->ies + ie_offset, WLAN_EID_HT_CAPABILITY, &len, bssid->ie_length - ie_offset);
4087 if (p && len > 0) {
4088 struct HT_caps_element *pHT_caps;
4089
4090 pHT_caps = (struct HT_caps_element *)(p + 2);
4091
4092 if (le16_to_cpu(pHT_caps->u.HT_cap_element.HT_caps_info) & BIT(14))
4093 pmlmepriv->num_FortyMHzIntolerant++;
4094 } else
4095 pmlmepriv->num_sta_no_ht++;
4096 }
4097
4098
4099 if (bssid->configuration.ds_config != rtw_get_oper_ch(padapter))
4100 bssid->phy_info.signal_quality = 101;
4101
4102 return _SUCCESS;
4103}
4104
4105void start_create_ibss(struct adapter *padapter)
4106{
4107 unsigned short caps;
4108 u8 val8;
4109 u8 join_type;
4110 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4111 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4112 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
4113
4114 pmlmeext->cur_channel = (u8)pnetwork->configuration.ds_config;
4115 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
4116
4117
4118 update_wireless_mode(padapter);
4119
4120
4121 caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork);
4122 update_capinfo(padapter, caps);
4123 if (caps&WLAN_CAPABILITY_IBSS) {
4124 val8 = 0xcf;
4125 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
4126
4127 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
4128
4129
4130
4131 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
4132
4133 beacon_timing_control(padapter);
4134
4135
4136 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4137 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
4138
4139
4140 if (send_beacon(padapter) == _FAIL) {
4141 report_join_res(padapter, -1);
4142 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4143 } else {
4144 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.mac_address);
4145 join_type = 0;
4146 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
4147
4148 report_join_res(padapter, 1);
4149 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
4150 rtw_indicate_connect(padapter);
4151 }
4152 } else {
4153 return;
4154 }
4155
4156 update_bmc_sta(padapter);
4157
4158}
4159
4160void start_clnt_join(struct adapter *padapter)
4161{
4162 unsigned short caps;
4163 u8 val8;
4164 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4165 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4166 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
4167 int beacon_timeout;
4168
4169
4170 update_wireless_mode(padapter);
4171
4172
4173 caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork);
4174 update_capinfo(padapter, caps);
4175 if (caps&WLAN_CAPABILITY_ESS) {
4176 Set_MSR(padapter, WIFI_FW_STATION_STATE);
4177
4178 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf;
4179
4180 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
4181
4182
4183
4184
4185
4186
4187
4188 {
4189
4190 issue_deauth_ex(padapter, pnetwork->mac_address, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
4191 }
4192
4193
4194
4195 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
4196 set_link_timer(pmlmeext, beacon_timeout);
4197 _set_timer(&padapter->mlmepriv.assoc_timer,
4198 (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout);
4199
4200 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
4201 } else if (caps&WLAN_CAPABILITY_IBSS) {
4202 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
4203
4204 val8 = 0xcf;
4205 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
4206
4207 beacon_timing_control(padapter);
4208
4209 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4210
4211 report_join_res(padapter, 1);
4212 } else {
4213 return;
4214 }
4215
4216}
4217
4218void start_clnt_auth(struct adapter *padapter)
4219{
4220 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4221 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4222
4223 del_timer_sync(&pmlmeext->link_timer);
4224
4225 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
4226 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
4227
4228 pmlmeinfo->auth_seq = 1;
4229 pmlmeinfo->reauth_count = 0;
4230 pmlmeinfo->reassoc_count = 0;
4231 pmlmeinfo->link_count = 0;
4232 pmlmeext->retry = 0;
4233
4234
4235 netdev_dbg(padapter->pnetdev, "start auth\n");
4236 issue_auth(padapter, NULL, 0);
4237
4238 set_link_timer(pmlmeext, REAUTH_TO);
4239
4240}
4241
4242
4243void start_clnt_assoc(struct adapter *padapter)
4244{
4245 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4246 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4247
4248 del_timer_sync(&pmlmeext->link_timer);
4249
4250 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
4251 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
4252
4253 issue_assocreq(padapter);
4254
4255 set_link_timer(pmlmeext, REASSOC_TO);
4256}
4257
4258unsigned int receive_disconnect(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason)
4259{
4260 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4261 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4262
4263
4264 if (!(!memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
4265 return _SUCCESS;
4266
4267 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
4268 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
4269 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4270 report_del_sta_event(padapter, MacAddr, reason);
4271
4272 } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) {
4273 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4274 report_join_res(padapter, -2);
4275 }
4276 }
4277
4278 return _SUCCESS;
4279}
4280
4281static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid)
4282{
4283 struct registry_priv *pregistrypriv;
4284 struct mlme_ext_priv *pmlmeext;
4285 struct rt_channel_info *chplan_new;
4286 u8 channel;
4287 u8 i;
4288
4289
4290 pregistrypriv = &padapter->registrypriv;
4291 pmlmeext = &padapter->mlmeextpriv;
4292
4293
4294 if (pregistrypriv->enable80211d &&
4295 (!pmlmeext->update_channel_plan_by_ap_done)) {
4296 u8 *ie, *p;
4297 u32 len;
4298 struct rt_channel_plan chplan_ap;
4299 struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM];
4300 u8 country[4];
4301 u8 fcn;
4302 u8 noc;
4303 u8 j, k;
4304
4305 ie = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, WLAN_EID_COUNTRY, &len, bssid->ie_length - _FIXED_IE_LENGTH_);
4306 if (!ie)
4307 return;
4308 if (len < 6)
4309 return;
4310
4311 ie += 2;
4312 p = ie;
4313 ie += len;
4314
4315 memset(country, 0, 4);
4316 memcpy(country, p, 3);
4317 p += 3;
4318
4319 i = 0;
4320 while ((ie - p) >= 3) {
4321 fcn = *(p++);
4322 noc = *(p++);
4323 p++;
4324
4325 for (j = 0; j < noc; j++) {
4326 if (fcn <= 14)
4327 channel = fcn + j;
4328 else
4329 channel = fcn + j*4;
4330
4331 chplan_ap.Channel[i++] = channel;
4332 }
4333 }
4334 chplan_ap.Len = i;
4335
4336 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
4337
4338 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
4339 chplan_new = pmlmeext->channel_set;
4340
4341 i = j = k = 0;
4342 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
4343 do {
4344 if ((i == MAX_CHANNEL_NUM) ||
4345 (chplan_sta[i].ChannelNum == 0) ||
4346 (chplan_sta[i].ChannelNum > 14))
4347 break;
4348
4349 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
4350 break;
4351
4352 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
4353 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4354 chplan_new[k].ScanType = SCAN_ACTIVE;
4355 i++;
4356 j++;
4357 k++;
4358 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
4359 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4360
4361 chplan_new[k].ScanType = SCAN_PASSIVE;
4362 i++;
4363 k++;
4364 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
4365 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4366 chplan_new[k].ScanType = SCAN_ACTIVE;
4367 j++;
4368 k++;
4369 }
4370 } while (1);
4371
4372
4373 while ((i < MAX_CHANNEL_NUM) &&
4374 (chplan_sta[i].ChannelNum != 0) &&
4375 (chplan_sta[i].ChannelNum <= 14)) {
4376
4377 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4378
4379 chplan_new[k].ScanType = SCAN_PASSIVE;
4380 i++;
4381 k++;
4382 }
4383
4384
4385 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
4386 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4387 chplan_new[k].ScanType = SCAN_ACTIVE;
4388 j++;
4389 k++;
4390 }
4391 } else {
4392
4393 while ((i < MAX_CHANNEL_NUM) &&
4394 (chplan_sta[i].ChannelNum != 0) &&
4395 (chplan_sta[i].ChannelNum <= 14)) {
4396 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
4397 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4398 i++;
4399 k++;
4400 }
4401
4402
4403 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
4404 j++;
4405 }
4406 }
4407
4408 pmlmeext->update_channel_plan_by_ap_done = 1;
4409 }
4410
4411
4412 channel = bssid->configuration.ds_config;
4413 chplan_new = pmlmeext->channel_set;
4414 i = 0;
4415 while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) {
4416 if (chplan_new[i].ChannelNum == channel) {
4417 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
4418 chplan_new[i].ScanType = SCAN_ACTIVE;
4419 }
4420 break;
4421 }
4422 i++;
4423 }
4424}
4425
4426
4427
4428
4429
4430
4431
4432void report_survey_event(struct adapter *padapter, union recv_frame *precv_frame)
4433{
4434 struct cmd_obj *pcmd_obj;
4435 u8 *pevtcmd;
4436 u32 cmdsz;
4437 struct survey_event *psurvey_evt;
4438 struct C2HEvent_Header *pc2h_evt_hdr;
4439 struct mlme_ext_priv *pmlmeext;
4440 struct cmd_priv *pcmdpriv;
4441
4442
4443
4444 if (!padapter)
4445 return;
4446
4447 pmlmeext = &padapter->mlmeextpriv;
4448 pcmdpriv = &padapter->cmdpriv;
4449
4450 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
4451 if (!pcmd_obj)
4452 return;
4453
4454 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
4455 pevtcmd = rtw_zmalloc(cmdsz);
4456 if (!pevtcmd) {
4457 kfree(pcmd_obj);
4458 return;
4459 }
4460
4461 INIT_LIST_HEAD(&pcmd_obj->list);
4462
4463 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4464 pcmd_obj->cmdsz = cmdsz;
4465 pcmd_obj->parmbuf = pevtcmd;
4466
4467 pcmd_obj->rsp = NULL;
4468 pcmd_obj->rspsz = 0;
4469
4470 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4471 pc2h_evt_hdr->len = sizeof(struct survey_event);
4472 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
4473 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4474
4475 psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
4476
4477 if (collect_bss_info(padapter, precv_frame, (struct wlan_bssid_ex *)&psurvey_evt->bss) == _FAIL) {
4478 kfree(pcmd_obj);
4479 kfree(pevtcmd);
4480 return;
4481 }
4482
4483 process_80211d(padapter, &psurvey_evt->bss);
4484
4485 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
4486
4487 pmlmeext->sitesurvey_res.bss_cnt++;
4488
4489 return;
4490
4491}
4492
4493void report_surveydone_event(struct adapter *padapter)
4494{
4495 struct cmd_obj *pcmd_obj;
4496 u8 *pevtcmd;
4497 u32 cmdsz;
4498 struct surveydone_event *psurveydone_evt;
4499 struct C2HEvent_Header *pc2h_evt_hdr;
4500 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4501 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4502
4503 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
4504 if (!pcmd_obj)
4505 return;
4506
4507 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
4508 pevtcmd = rtw_zmalloc(cmdsz);
4509 if (!pevtcmd) {
4510 kfree(pcmd_obj);
4511 return;
4512 }
4513
4514 INIT_LIST_HEAD(&pcmd_obj->list);
4515
4516 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4517 pcmd_obj->cmdsz = cmdsz;
4518 pcmd_obj->parmbuf = pevtcmd;
4519
4520 pcmd_obj->rsp = NULL;
4521 pcmd_obj->rspsz = 0;
4522
4523 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4524 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
4525 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
4526 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4527
4528 psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
4529 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
4530
4531 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
4532
4533 return;
4534
4535}
4536
4537void report_join_res(struct adapter *padapter, int res)
4538{
4539 struct cmd_obj *pcmd_obj;
4540 u8 *pevtcmd;
4541 u32 cmdsz;
4542 struct joinbss_event *pjoinbss_evt;
4543 struct C2HEvent_Header *pc2h_evt_hdr;
4544 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4545 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4546 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4547
4548 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
4549 if (!pcmd_obj)
4550 return;
4551
4552 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
4553 pevtcmd = rtw_zmalloc(cmdsz);
4554 if (!pevtcmd) {
4555 kfree(pcmd_obj);
4556 return;
4557 }
4558
4559 INIT_LIST_HEAD(&pcmd_obj->list);
4560
4561 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4562 pcmd_obj->cmdsz = cmdsz;
4563 pcmd_obj->parmbuf = pevtcmd;
4564
4565 pcmd_obj->rsp = NULL;
4566 pcmd_obj->rspsz = 0;
4567
4568 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4569 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
4570 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
4571 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4572
4573 pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
4574 memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(struct wlan_bssid_ex));
4575 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
4576
4577
4578 rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
4579
4580
4581 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
4582
4583 return;
4584
4585}
4586
4587void report_wmm_edca_update(struct adapter *padapter)
4588{
4589 struct cmd_obj *pcmd_obj;
4590 u8 *pevtcmd;
4591 u32 cmdsz;
4592 struct wmm_event *pwmm_event;
4593 struct C2HEvent_Header *pc2h_evt_hdr;
4594 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4595 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4596
4597 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
4598 if (!pcmd_obj)
4599 return;
4600
4601 cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header));
4602 pevtcmd = rtw_zmalloc(cmdsz);
4603 if (!pevtcmd) {
4604 kfree(pcmd_obj);
4605 return;
4606 }
4607
4608 INIT_LIST_HEAD(&pcmd_obj->list);
4609
4610 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4611 pcmd_obj->cmdsz = cmdsz;
4612 pcmd_obj->parmbuf = pevtcmd;
4613
4614 pcmd_obj->rsp = NULL;
4615 pcmd_obj->rspsz = 0;
4616
4617 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4618 pc2h_evt_hdr->len = sizeof(struct wmm_event);
4619 pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM);
4620 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4621
4622 pwmm_event = (struct wmm_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
4623 pwmm_event->wmm = 0;
4624
4625 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
4626
4627 return;
4628
4629}
4630
4631void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason)
4632{
4633 struct cmd_obj *pcmd_obj;
4634 u8 *pevtcmd;
4635 u32 cmdsz;
4636 struct sta_info *psta;
4637 int mac_id;
4638 struct stadel_event *pdel_sta_evt;
4639 struct C2HEvent_Header *pc2h_evt_hdr;
4640 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4641 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4642
4643 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
4644 if (pcmd_obj == NULL) {
4645 return;
4646 }
4647
4648 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
4649 pevtcmd = rtw_zmalloc(cmdsz);
4650 if (pevtcmd == NULL) {
4651 kfree(pcmd_obj);
4652 return;
4653 }
4654
4655 INIT_LIST_HEAD(&pcmd_obj->list);
4656
4657 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4658 pcmd_obj->cmdsz = cmdsz;
4659 pcmd_obj->parmbuf = pevtcmd;
4660
4661 pcmd_obj->rsp = NULL;
4662 pcmd_obj->rspsz = 0;
4663
4664 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4665 pc2h_evt_hdr->len = sizeof(struct stadel_event);
4666 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
4667 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4668
4669 pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
4670 memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
4671 memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
4672
4673
4674 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
4675 if (psta)
4676 mac_id = (int)psta->mac_id;
4677 else
4678 mac_id = (-1);
4679
4680 pdel_sta_evt->mac_id = mac_id;
4681
4682 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
4683}
4684
4685void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int cam_idx)
4686{
4687 struct cmd_obj *pcmd_obj;
4688 u8 *pevtcmd;
4689 u32 cmdsz;
4690 struct stassoc_event *padd_sta_evt;
4691 struct C2HEvent_Header *pc2h_evt_hdr;
4692 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4693 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4694
4695 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
4696 if (pcmd_obj == NULL)
4697 return;
4698
4699 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
4700 pevtcmd = rtw_zmalloc(cmdsz);
4701 if (pevtcmd == NULL) {
4702 kfree(pcmd_obj);
4703 return;
4704 }
4705
4706 INIT_LIST_HEAD(&pcmd_obj->list);
4707
4708 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
4709 pcmd_obj->cmdsz = cmdsz;
4710 pcmd_obj->parmbuf = pevtcmd;
4711
4712 pcmd_obj->rsp = NULL;
4713 pcmd_obj->rspsz = 0;
4714
4715 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4716 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
4717 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
4718 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4719
4720 padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
4721 memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
4722 padd_sta_evt->cam_id = cam_idx;
4723
4724 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
4725}
4726
4727
4728
4729
4730
4731
4732
4733
4734void update_sta_info(struct adapter *padapter, struct sta_info *psta)
4735{
4736 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4737 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4738 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4739
4740
4741 VCS_update(padapter, psta);
4742
4743
4744 if (pmlmepriv->htpriv.ht_option) {
4745 psta->htpriv.ht_option = true;
4746
4747 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
4748
4749 psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para&IEEE80211_HT_CAP_AMPDU_DENSITY)>>2;
4750
4751 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20))
4752 psta->htpriv.sgi_20m = true;
4753
4754 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40))
4755 psta->htpriv.sgi_40m = true;
4756
4757 psta->qos_option = true;
4758
4759 psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap;
4760 psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap;
4761 psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
4762
4763 memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct ieee80211_ht_cap));
4764 } else {
4765 psta->htpriv.ht_option = false;
4766
4767 psta->htpriv.ampdu_enable = false;
4768
4769 psta->htpriv.sgi_20m = false;
4770 psta->htpriv.sgi_40m = false;
4771 psta->qos_option = false;
4772
4773 }
4774
4775 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
4776
4777 psta->htpriv.agg_enable_bitmap = 0x0;
4778 psta->htpriv.candidate_tid_bitmap = 0x0;
4779
4780 psta->bw_mode = pmlmeext->cur_bwmode;
4781
4782
4783 if (pmlmepriv->qospriv.qos_option)
4784 psta->qos_option = true;
4785
4786 update_ldpc_stbc_cap(psta);
4787
4788 spin_lock_bh(&psta->lock);
4789 psta->state = _FW_LINKED;
4790 spin_unlock_bh(&psta->lock);
4791
4792}
4793
4794static void rtw_mlmeext_disconnect(struct adapter *padapter)
4795{
4796 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4797 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4798 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4799 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809 {
4810 struct sta_info *psta;
4811
4812 psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(pnetwork));
4813 if (psta)
4814 rtw_hal_macid_wakeup(padapter, psta->mac_id);
4815 }
4816
4817 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL);
4818 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
4819
4820
4821 Set_MSR(padapter, _HW_STATE_STATION_);
4822
4823 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4824
4825
4826 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
4827 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4828
4829 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4830
4831 flush_all_cam_entry(padapter);
4832
4833 del_timer_sync(&pmlmeext->link_timer);
4834
4835
4836 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
4837 pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
4838
4839}
4840
4841void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res)
4842{
4843 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4844 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4845 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
4846 struct sta_priv *pstapriv = &padapter->stapriv;
4847 u8 join_type;
4848 struct sta_info *psta;
4849
4850 if (join_res < 0) {
4851 join_type = 1;
4852 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
4853 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
4854
4855 return;
4856 }
4857
4858 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
4859
4860 update_bmc_sta(padapter);
4861
4862
4863
4864 Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true);
4865
4866
4867 update_IOT_info(padapter);
4868
4869 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->supported_rates);
4870
4871
4872 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
4873
4874
4875 update_capinfo(padapter, pmlmeinfo->capability);
4876
4877
4878 WMMOnAssocRsp(padapter);
4879
4880
4881 HTOnAssocRsp(padapter);
4882
4883
4884 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4885
4886 psta = rtw_get_stainfo(pstapriv, cur_network->mac_address);
4887 if (psta) {
4888
4889 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
4890
4891 psta->wireless_mode = pmlmeext->cur_wireless_mode;
4892
4893
4894 set_sta_rate(padapter, psta);
4895
4896 rtw_sta_media_status_rpt(padapter, psta, 1);
4897
4898
4899
4900 rtw_hal_macid_wakeup(padapter, psta->mac_id);
4901 }
4902
4903 join_type = 2;
4904 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
4905
4906 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
4907
4908 correct_TSF(padapter, pmlmeext);
4909
4910
4911 }
4912
4913 if (get_iface_type(padapter) == IFACE_PORT0)
4914 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
4915}
4916
4917
4918void mlmeext_sta_add_event_callback(struct adapter *padapter, struct sta_info *psta)
4919{
4920 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4921 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4922 u8 join_type;
4923
4924 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
4925 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
4926
4927
4928 } else {
4929
4930
4931
4932
4933 correct_TSF(padapter, pmlmeext);
4934
4935
4936 if (send_beacon(padapter) == _FAIL) {
4937 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
4938
4939 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
4940
4941 return;
4942 }
4943
4944 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
4945
4946 }
4947
4948 join_type = 2;
4949 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
4950 }
4951
4952 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
4953
4954 psta->bssratelen = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates);
4955 memcpy(psta->bssrateset, pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates, psta->bssratelen);
4956
4957
4958 update_sta_info(padapter, psta);
4959
4960 rtw_hal_update_sta_rate_mask(padapter, psta);
4961
4962
4963 psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel);
4964 psta->raid = networktype_to_raid_ex(padapter, psta);
4965
4966
4967 Update_RA_Entry(padapter, psta);
4968}
4969
4970void mlmeext_sta_del_event_callback(struct adapter *padapter)
4971{
4972 if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
4973 rtw_mlmeext_disconnect(padapter);
4974}
4975
4976
4977
4978
4979
4980
4981void _linked_info_dump(struct adapter *padapter)
4982{
4983 int i;
4984 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4985 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4986 int UndecoratedSmoothedPWDB;
4987 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
4988
4989 if (padapter->bLinkInfoDump) {
4990
4991 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
4992 rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
4993
4994 for (i = 0; i < NUM_STA; i++) {
4995 if (pdvobj->macid[i]) {
4996 if (i != 1)
4997
4998 rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &i);
4999 }
5000 }
5001 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_RX_INFO_DUMP, NULL);
5002 }
5003}
5004
5005static u8 chk_ap_is_alive(struct adapter *padapter, struct sta_info *psta)
5006{
5007 u8 ret = false;
5008
5009 if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
5010 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
5011 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
5012 ) {
5013 ret = false;
5014 } else {
5015 ret = true;
5016 }
5017
5018 sta_update_last_rx_pkts(psta);
5019
5020 return ret;
5021}
5022
5023void linked_status_chk(struct adapter *padapter)
5024{
5025 u32 i;
5026 struct sta_info *psta;
5027 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5028 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5029 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5030 struct sta_priv *pstapriv = &padapter->stapriv;
5031
5032
5033 if (is_client_associated_to_ap(padapter)) {
5034
5035
5036 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
5037 int rx_chk_limit;
5038 int link_count_limit;
5039
5040 #if defined(DBG_ROAMING_TEST)
5041 rx_chk_limit = 1;
5042 #else
5043 rx_chk_limit = 8;
5044 #endif
5045 link_count_limit = 7;
5046
5047
5048
5049
5050 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.mac_address);
5051 if (psta) {
5052 if (chk_ap_is_alive(padapter, psta) == false)
5053 rx_chk = _FAIL;
5054
5055 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
5056 tx_chk = _FAIL;
5057
5058 {
5059 if (rx_chk != _SUCCESS) {
5060 if (pmlmeext->retry == 0) {
5061 issue_probereq_ex(padapter, &pmlmeinfo->network.ssid, pmlmeinfo->network.mac_address, 0, 0, 0, 0);
5062 issue_probereq_ex(padapter, &pmlmeinfo->network.ssid, pmlmeinfo->network.mac_address, 0, 0, 0, 0);
5063 issue_probereq_ex(padapter, &pmlmeinfo->network.ssid, pmlmeinfo->network.mac_address, 0, 0, 0, 0);
5064 }
5065 }
5066
5067 if (tx_chk != _SUCCESS &&
5068 pmlmeinfo->link_count++ == link_count_limit)
5069 tx_chk = issue_nulldata_in_interrupt(padapter, NULL);
5070 }
5071
5072 if (rx_chk == _FAIL) {
5073 pmlmeext->retry++;
5074 if (pmlmeext->retry > rx_chk_limit) {
5075 netdev_dbg(padapter->pnetdev,
5076 FUNC_ADPT_FMT " disconnect or roaming\n",
5077 FUNC_ADPT_ARG(padapter));
5078 receive_disconnect(padapter, pmlmeinfo->network.mac_address
5079 , WLAN_REASON_EXPIRATION_CHK);
5080 return;
5081 }
5082 } else {
5083 pmlmeext->retry = 0;
5084 }
5085
5086 if (tx_chk == _FAIL) {
5087 pmlmeinfo->link_count %= (link_count_limit+1);
5088 } else {
5089 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
5090 pmlmeinfo->link_count = 0;
5091 }
5092
5093 }
5094 } else if (is_client_associated_to_ibss(padapter)) {
5095
5096
5097 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
5098 if (pmlmeinfo->FW_sta_info[i].status == 1) {
5099 psta = pmlmeinfo->FW_sta_info[i].psta;
5100
5101 if (NULL == psta)
5102 continue;
5103
5104 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta)) {
5105
5106 if (pmlmeinfo->FW_sta_info[i].retry < 3) {
5107 pmlmeinfo->FW_sta_info[i].retry++;
5108 } else {
5109 pmlmeinfo->FW_sta_info[i].retry = 0;
5110 pmlmeinfo->FW_sta_info[i].status = 0;
5111 report_del_sta_event(padapter, psta->hwaddr
5112 , 65535
5113 );
5114 }
5115 } else {
5116 pmlmeinfo->FW_sta_info[i].retry = 0;
5117 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
5118 }
5119 }
5120 }
5121
5122
5123
5124 }
5125
5126}
5127
5128void survey_timer_hdl(struct timer_list *t)
5129{
5130 struct adapter *padapter =
5131 from_timer(padapter, t, mlmeextpriv.survey_timer);
5132 struct cmd_obj *ph2c;
5133 struct sitesurvey_parm *psurveyPara;
5134 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5135 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5136
5137
5138 if (pmlmeext->sitesurvey_res.state > SCAN_START) {
5139 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
5140 pmlmeext->sitesurvey_res.channel_idx++;
5141 }
5142
5143 if (pmlmeext->scan_abort) {
5144 pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
5145
5146 pmlmeext->scan_abort = false;
5147 }
5148
5149 ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
5150 if (ph2c == NULL) {
5151 goto exit_survey_timer_hdl;
5152 }
5153
5154 psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm));
5155 if (psurveyPara == NULL) {
5156 kfree(ph2c);
5157 goto exit_survey_timer_hdl;
5158 }
5159
5160 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
5161 rtw_enqueue_cmd(pcmdpriv, ph2c);
5162 }
5163
5164
5165exit_survey_timer_hdl:
5166
5167 return;
5168}
5169
5170void link_timer_hdl(struct timer_list *t)
5171{
5172 struct adapter *padapter =
5173 from_timer(padapter, t, mlmeextpriv.link_timer);
5174
5175
5176
5177 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5178 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5179
5180
5181
5182 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
5183 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5184 report_join_res(padapter, -3);
5185 } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
5186
5187 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
5188
5189
5190 pmlmeinfo->state = 0;
5191 report_join_res(padapter, -1);
5192 return;
5193
5194
5195
5196
5197
5198
5199 }
5200
5201 pmlmeinfo->auth_seq = 1;
5202 issue_auth(padapter, NULL, 0);
5203 set_link_timer(pmlmeext, REAUTH_TO);
5204 } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
5205
5206 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
5207 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5208 report_join_res(padapter, -2);
5209 return;
5210 }
5211
5212 issue_assocreq(padapter);
5213 set_link_timer(pmlmeext, REASSOC_TO);
5214 }
5215}
5216
5217void addba_timer_hdl(struct timer_list *t)
5218{
5219 struct sta_info *psta = from_timer(psta, t, addba_retry_timer);
5220 struct ht_priv *phtpriv;
5221
5222 if (!psta)
5223 return;
5224
5225 phtpriv = &psta->htpriv;
5226
5227 if (phtpriv->ht_option && phtpriv->ampdu_enable) {
5228 if (phtpriv->candidate_tid_bitmap)
5229 phtpriv->candidate_tid_bitmap = 0x0;
5230
5231 }
5232}
5233
5234void sa_query_timer_hdl(struct timer_list *t)
5235{
5236 struct adapter *padapter =
5237 from_timer(padapter, t, mlmeextpriv.sa_query_timer);
5238 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5239
5240 spin_lock_bh(&pmlmepriv->lock);
5241
5242 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
5243 rtw_disassoc_cmd(padapter, 0, true);
5244 rtw_indicate_disconnect(padapter);
5245 rtw_free_assoc_resources(padapter, 1);
5246 }
5247
5248 spin_unlock_bh(&pmlmepriv->lock);
5249}
5250
5251u8 NULL_hdl(struct adapter *padapter, u8 *pbuf)
5252{
5253 return H2C_SUCCESS;
5254}
5255
5256u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf)
5257{
5258 u8 type;
5259 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5260 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5261 struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
5262
5263 if (psetop->mode == Ndis802_11APMode) {
5264 pmlmeinfo->state = WIFI_FW_AP_STATE;
5265 type = _HW_STATE_AP_;
5266
5267 } else if (psetop->mode == Ndis802_11Infrastructure) {
5268 pmlmeinfo->state &= ~(BIT(0)|BIT(1));
5269 pmlmeinfo->state |= WIFI_FW_STATION_STATE;
5270 type = _HW_STATE_STATION_;
5271 } else if (psetop->mode == Ndis802_11IBSS) {
5272 type = _HW_STATE_ADHOC_;
5273 } else {
5274 type = _HW_STATE_NOLINK_;
5275 }
5276
5277 rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
5278
5279
5280 if (psetop->mode == Ndis802_11APMode) {
5281
5282
5283 rtw_btcoex_MediaStatusNotify(padapter, 1);
5284 }
5285
5286 return H2C_SUCCESS;
5287
5288}
5289
5290u8 createbss_hdl(struct adapter *padapter, u8 *pbuf)
5291{
5292 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5293 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5294 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
5295 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
5296
5297
5298 if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
5299 start_bss_network(padapter);
5300 return H2C_SUCCESS;
5301 }
5302
5303
5304 if (pparm->network.infrastructure_mode == Ndis802_11IBSS) {
5305 rtw_joinbss_reset(padapter);
5306
5307 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
5308 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5309 pmlmeinfo->ERP_enable = 0;
5310 pmlmeinfo->WMM_enable = 0;
5311 pmlmeinfo->HT_enable = 0;
5312 pmlmeinfo->HT_caps_enable = 0;
5313 pmlmeinfo->HT_info_enable = 0;
5314 pmlmeinfo->agg_enable_bitmap = 0;
5315 pmlmeinfo->candidate_tid_bitmap = 0;
5316
5317
5318 Save_DM_Func_Flag(padapter);
5319 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
5320
5321
5322
5323
5324
5325
5326 del_timer_sync(&pmlmeext->link_timer);
5327
5328
5329 flush_all_cam_entry(padapter);
5330
5331 memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, ie_length));
5332 pnetwork->ie_length = ((struct wlan_bssid_ex *)pbuf)->ie_length;
5333
5334 if (pnetwork->ie_length > MAX_IE_SZ)
5335 return H2C_PARAMETERS_ERROR;
5336
5337 memcpy(pnetwork->ies, ((struct wlan_bssid_ex *)pbuf)->ies, pnetwork->ie_length);
5338
5339 start_create_ibss(padapter);
5340
5341 }
5342
5343 return H2C_SUCCESS;
5344
5345}
5346
5347u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
5348{
5349 u8 join_type;
5350 struct ndis_80211_var_ie *pIE;
5351 struct registry_priv *pregpriv = &padapter->registrypriv;
5352 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5353 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5354 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
5355 u32 i;
5356 u8 cbw40_enable = 0;
5357
5358
5359 u8 ch, bw, offset;
5360
5361
5362 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
5363 if (pmlmeinfo->state & WIFI_FW_STATION_STATE) {
5364 issue_deauth_ex(padapter, pnetwork->mac_address, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
5365 }
5366 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5367
5368
5369 flush_all_cam_entry(padapter);
5370
5371 del_timer_sync(&pmlmeext->link_timer);
5372
5373
5374
5375 Set_MSR(padapter, _HW_STATE_STATION_);
5376
5377
5378 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL);
5379 }
5380
5381 rtw_joinbss_reset(padapter);
5382
5383 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
5384 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5385 pmlmeinfo->ERP_enable = 0;
5386 pmlmeinfo->WMM_enable = 0;
5387 pmlmeinfo->HT_enable = 0;
5388 pmlmeinfo->HT_caps_enable = 0;
5389 pmlmeinfo->HT_info_enable = 0;
5390 pmlmeinfo->agg_enable_bitmap = 0;
5391 pmlmeinfo->candidate_tid_bitmap = 0;
5392 pmlmeinfo->bwmode_updated = false;
5393
5394 pmlmeinfo->VHT_enable = 0;
5395
5396 memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, ie_length));
5397 pnetwork->ie_length = ((struct wlan_bssid_ex *)pbuf)->ie_length;
5398
5399 if (pnetwork->ie_length > MAX_IE_SZ)
5400 return H2C_PARAMETERS_ERROR;
5401
5402 memcpy(pnetwork->ies, ((struct wlan_bssid_ex *)pbuf)->ies, pnetwork->ie_length);
5403
5404 pmlmeext->cur_channel = (u8)pnetwork->configuration.ds_config;
5405 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
5406
5407
5408
5409
5410
5411 for (i = _FIXED_IE_LENGTH_; i < pnetwork->ie_length;) {
5412 pIE = (struct ndis_80211_var_ie *)(pnetwork->ies + i);
5413
5414 switch (pIE->element_id) {
5415 case WLAN_EID_VENDOR_SPECIFIC:
5416 if (!memcmp(pIE->data, WMM_OUI, 4))
5417 WMM_param_handler(padapter, pIE);
5418 break;
5419
5420 case WLAN_EID_HT_CAPABILITY:
5421 pmlmeinfo->HT_caps_enable = 1;
5422 break;
5423
5424 case WLAN_EID_HT_OPERATION:
5425 pmlmeinfo->HT_info_enable = 1;
5426
5427
5428 {
5429 struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data);
5430
5431 if (pnetwork->configuration.ds_config <= 14) {
5432 if ((pregpriv->bw_mode & 0x0f) > CHANNEL_WIDTH_20)
5433 cbw40_enable = 1;
5434 }
5435
5436 if ((cbw40_enable) && (pht_info->infos[0] & BIT(2))) {
5437
5438 pmlmeext->cur_bwmode = CHANNEL_WIDTH_40;
5439 switch (pht_info->infos[0] & 0x3) {
5440 case 1:
5441 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
5442 break;
5443
5444 case 3:
5445 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
5446 break;
5447
5448 default:
5449 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5450 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
5451 break;
5452 }
5453 }
5454 }
5455 break;
5456 default:
5457 break;
5458 }
5459
5460 i += (pIE->length + 2);
5461 }
5462
5463
5464 if (rtw_chk_start_clnt_join(padapter, &ch, &bw, &offset) == _FAIL) {
5465 report_join_res(padapter, (-4));
5466 return H2C_SUCCESS;
5467 }
5468
5469
5470
5471
5472
5473
5474
5475
5476 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.mac_address);
5477 join_type = 0;
5478 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
5479 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
5480
5481 set_channel_bwmode(padapter, ch, offset, bw);
5482
5483
5484 del_timer_sync(&pmlmeext->link_timer);
5485
5486 start_clnt_join(padapter);
5487
5488 return H2C_SUCCESS;
5489
5490}
5491
5492u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf)
5493{
5494 struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
5495 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5496 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5497 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
5498 u8 val8;
5499
5500 if (is_client_associated_to_ap(padapter)) {
5501 issue_deauth_ex(padapter, pnetwork->mac_address, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
5502 }
5503
5504 if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) {
5505
5506 val8 = 0;
5507 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
5508 }
5509
5510 rtw_mlmeext_disconnect(padapter);
5511
5512 rtw_free_uc_swdec_pending_queue(padapter);
5513
5514 return H2C_SUCCESS;
5515}
5516
5517static int rtw_scan_ch_decision(struct adapter *padapter, struct rtw_ieee80211_channel *out,
5518 u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
5519{
5520 int i, j;
5521 int set_idx;
5522 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5523
5524
5525 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
5526
5527
5528 j = 0;
5529 for (i = 0; i < in_num; i++) {
5530
5531 set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value);
5532 if (in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
5533 && set_idx >= 0
5534 ) {
5535 if (j >= out_num) {
5536 netdev_dbg(padapter->pnetdev,
5537 FUNC_ADPT_FMT " out_num:%u not enough\n",
5538 FUNC_ADPT_ARG(padapter), out_num);
5539 break;
5540 }
5541
5542 memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
5543
5544 if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
5545 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
5546
5547 j++;
5548 }
5549 if (j >= out_num)
5550 break;
5551 }
5552
5553
5554 if (j == 0) {
5555 for (i = 0; i < pmlmeext->max_chan_nums; i++) {
5556
5557 if (j >= out_num) {
5558 netdev_dbg(padapter->pnetdev,
5559 FUNC_ADPT_FMT " out_num:%u not enough\n",
5560 FUNC_ADPT_ARG(padapter),
5561 out_num);
5562 break;
5563 }
5564
5565 out[j].hw_value = pmlmeext->channel_set[i].ChannelNum;
5566
5567 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
5568 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
5569
5570 j++;
5571 }
5572 }
5573
5574 return j;
5575}
5576
5577u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf)
5578{
5579 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5580 struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
5581 u8 bdelayscan = false;
5582 u8 val8;
5583 u32 initialgain;
5584 u32 i;
5585
5586 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
5587 pmlmeext->sitesurvey_res.state = SCAN_START;
5588 pmlmeext->sitesurvey_res.bss_cnt = 0;
5589 pmlmeext->sitesurvey_res.channel_idx = 0;
5590
5591 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
5592 if (pparm->ssid[i].ssid_length) {
5593 memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid, pparm->ssid[i].ssid, IW_ESSID_MAX_SIZE);
5594 pmlmeext->sitesurvey_res.ssid[i].ssid_length = pparm->ssid[i].ssid_length;
5595 } else {
5596 pmlmeext->sitesurvey_res.ssid[i].ssid_length = 0;
5597 }
5598 }
5599
5600 pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter
5601 , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT
5602 , pparm->ch, pparm->ch_num
5603 );
5604
5605 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
5606
5607
5608 if (is_client_associated_to_ap(padapter)) {
5609 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
5610
5611 issue_nulldata(padapter, NULL, 1, 3, 500);
5612
5613 bdelayscan = true;
5614 }
5615 if (bdelayscan) {
5616
5617 set_survey_timer(pmlmeext, 50);
5618 return H2C_SUCCESS;
5619 }
5620 }
5621
5622 if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) {
5623
5624 Save_DM_Func_Flag(padapter);
5625 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
5626
5627
5628
5629
5630 initialgain = 0x1e;
5631
5632 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
5633
5634
5635 Set_MSR(padapter, _HW_STATE_NOLINK_);
5636
5637 val8 = 1;
5638 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
5639
5640 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
5641 }
5642
5643 site_survey(padapter);
5644
5645 return H2C_SUCCESS;
5646
5647}
5648
5649u8 setauth_hdl(struct adapter *padapter, unsigned char *pbuf)
5650{
5651 struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
5652 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5653 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5654
5655 if (pparm->mode < 4)
5656 pmlmeinfo->auth_algo = pparm->mode;
5657
5658 return H2C_SUCCESS;
5659}
5660
5661u8 setkey_hdl(struct adapter *padapter, u8 *pbuf)
5662{
5663 u16 ctrl = 0;
5664 s16 cam_id = 0;
5665 struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
5666 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5667 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5668 unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
5669 u8 *addr;
5670
5671
5672 if (pparm->set_tx)
5673 pmlmeinfo->key_index = pparm->keyid;
5674
5675 cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid);
5676
5677 if (cam_id < 0) {
5678 } else {
5679 if (cam_id > 3)
5680 addr = get_bssid(&padapter->mlmepriv);
5681 else
5682 addr = null_addr;
5683
5684 ctrl = BIT(15) | BIT6 | ((pparm->algorithm) << 2) | pparm->keyid;
5685 write_cam(padapter, cam_id, ctrl, addr, pparm->key);
5686 netdev_dbg(padapter->pnetdev,
5687 "set group key camid:%d, addr:%pM, kid:%d, type:%s\n",
5688 cam_id, MAC_ARG(addr), pparm->keyid,
5689 security_type_str(pparm->algorithm));
5690 }
5691
5692 if (cam_id >= 0 && cam_id <= 3)
5693 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)true);
5694
5695
5696 padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_ON_RCR_AM, null_addr);
5697
5698 return H2C_SUCCESS;
5699}
5700
5701u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf)
5702{
5703 u16 ctrl = 0;
5704 s16 cam_id = 0;
5705 u8 ret = H2C_SUCCESS;
5706 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5707 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5708 struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
5709 struct sta_priv *pstapriv = &padapter->stapriv;
5710 struct sta_info *psta;
5711
5712 if (pparm->algorithm == _NO_PRIVACY_)
5713 goto write_to_cam;
5714
5715 psta = rtw_get_stainfo(pstapriv, pparm->addr);
5716 if (!psta) {
5717 netdev_dbg(padapter->pnetdev, "%s sta:%pM not found\n",
5718 __func__, MAC_ARG(pparm->addr));
5719 ret = H2C_REJECTED;
5720 goto exit;
5721 }
5722
5723 pmlmeinfo->enc_algo = pparm->algorithm;
5724 cam_id = rtw_camid_alloc(padapter, psta, 0);
5725 if (cam_id < 0)
5726 goto exit;
5727
5728write_to_cam:
5729 if (pparm->algorithm == _NO_PRIVACY_) {
5730 while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1)) >= 0) {
5731 netdev_dbg(padapter->pnetdev,
5732 "clear key for addr:%pM, camid:%d\n",
5733 MAC_ARG(pparm->addr), cam_id);
5734 clear_cam_entry(padapter, cam_id);
5735 rtw_camid_free(padapter, cam_id);
5736 }
5737 } else {
5738 netdev_dbg(padapter->pnetdev,
5739 "set pairwise key camid:%d, addr:%pM, kid:%d, type:%s\n",
5740 cam_id, MAC_ARG(pparm->addr), pparm->keyid,
5741 security_type_str(pparm->algorithm));
5742 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
5743 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
5744 }
5745 ret = H2C_SUCCESS_RSP;
5746
5747exit:
5748 return ret;
5749}
5750
5751u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf)
5752{
5753 struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
5754 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5755 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5756
5757 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
5758
5759 if (!psta)
5760 return H2C_SUCCESS;
5761
5762 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
5763 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) {
5764
5765
5766
5767 issue_action_BA(padapter, pparm->addr, WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
5768
5769 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
5770 } else {
5771 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
5772 }
5773 return H2C_SUCCESS;
5774}
5775
5776
5777u8 chk_bmc_sleepq_cmd(struct adapter *padapter)
5778{
5779 struct cmd_obj *ph2c;
5780 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
5781 u8 res = _SUCCESS;
5782
5783 ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
5784 if (ph2c == NULL) {
5785 res = _FAIL;
5786 goto exit;
5787 }
5788
5789 init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq));
5790
5791 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
5792
5793exit:
5794 return res;
5795}
5796
5797u8 set_tx_beacon_cmd(struct adapter *padapter)
5798{
5799 struct cmd_obj *ph2c;
5800 struct Tx_Beacon_param *ptxBeacon_parm;
5801 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
5802 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5803 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5804 u8 res = _SUCCESS;
5805 int len_diff = 0;
5806
5807 ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
5808 if (ph2c == NULL) {
5809 res = _FAIL;
5810 goto exit;
5811 }
5812
5813 ptxBeacon_parm = rtw_zmalloc(sizeof(struct Tx_Beacon_param));
5814 if (ptxBeacon_parm == NULL) {
5815 kfree(ph2c);
5816 res = _FAIL;
5817 goto exit;
5818 }
5819
5820 memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(struct wlan_bssid_ex));
5821
5822 len_diff = update_hidden_ssid(ptxBeacon_parm->network.ies+_BEACON_IE_OFFSET_,
5823 ptxBeacon_parm->network.ie_length-_BEACON_IE_OFFSET_,
5824 pmlmeinfo->hidden_ssid_mode);
5825 ptxBeacon_parm->network.ie_length += len_diff;
5826
5827 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
5828
5829 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
5830
5831exit:
5832 return res;
5833}
5834
5835static struct fwevent wlanevents[] = {
5836 {0, rtw_dummy_event_callback},
5837 {0, NULL},
5838 {0, NULL},
5839 {0, NULL},
5840 {0, NULL},
5841 {0, NULL},
5842 {0, NULL},
5843 {0, NULL},
5844 {0, &rtw_survey_event_callback},
5845 {sizeof(struct surveydone_event), &rtw_surveydone_event_callback},
5846
5847 {0, &rtw_joinbss_event_callback},
5848 {sizeof(struct stassoc_event), &rtw_stassoc_event_callback},
5849 {sizeof(struct stadel_event), &rtw_stadel_event_callback},
5850 {0, &rtw_atimdone_event_callback},
5851 {0, rtw_dummy_event_callback},
5852 {0, NULL},
5853 {0, NULL},
5854 {0, NULL},
5855 {0, NULL},
5856 {0, rtw_fwdbg_event_callback},
5857 {0, NULL},
5858 {0, NULL},
5859 {0, NULL},
5860 {0, &rtw_cpwm_event_callback},
5861 {0, NULL},
5862 {0, &rtw_wmm_event_callback},
5863
5864};
5865
5866u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf)
5867{
5868 u8 evt_code;
5869 u16 evt_sz;
5870 uint *peventbuf;
5871 void (*event_callback)(struct adapter *dev, u8 *pbuf);
5872 struct evt_priv *pevt_priv = &(padapter->evtpriv);
5873
5874 if (pbuf == NULL)
5875 goto _abort_event_;
5876
5877 peventbuf = (uint *)pbuf;
5878 evt_sz = (u16)(*peventbuf&0xffff);
5879 evt_code = (u8)((*peventbuf>>16)&0xff);
5880
5881
5882 if (evt_code >= MAX_C2HEVT)
5883 goto _abort_event_;
5884
5885
5886 if ((wlanevents[evt_code].parmsize != 0) &&
5887 (wlanevents[evt_code].parmsize != evt_sz))
5888 goto _abort_event_;
5889
5890 atomic_inc(&pevt_priv->event_seq);
5891
5892 peventbuf += 2;
5893
5894 if (peventbuf) {
5895 event_callback = wlanevents[evt_code].event_callback;
5896 event_callback(padapter, (u8 *)peventbuf);
5897
5898 pevt_priv->evt_done_cnt++;
5899 }
5900
5901
5902_abort_event_:
5903
5904
5905 return H2C_SUCCESS;
5906
5907}
5908
5909u8 h2c_msg_hdl(struct adapter *padapter, unsigned char *pbuf)
5910{
5911 if (!pbuf)
5912 return H2C_PARAMETERS_ERROR;
5913
5914 return H2C_SUCCESS;
5915}
5916
5917u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf)
5918{
5919 struct sta_info *psta_bmc;
5920 struct list_head *xmitframe_plist, *xmitframe_phead, *tmp;
5921 struct xmit_frame *pxmitframe = NULL;
5922 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5923 struct sta_priv *pstapriv = &padapter->stapriv;
5924
5925
5926 psta_bmc = rtw_get_bcmc_stainfo(padapter);
5927 if (!psta_bmc)
5928 return H2C_SUCCESS;
5929
5930 if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len > 0)) {
5931 msleep(10);
5932
5933
5934 spin_lock_bh(&pxmitpriv->lock);
5935
5936 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
5937 list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) {
5938 pxmitframe = list_entry(xmitframe_plist,
5939 struct xmit_frame, list);
5940
5941 list_del_init(&pxmitframe->list);
5942
5943 psta_bmc->sleepq_len--;
5944 if (psta_bmc->sleepq_len > 0)
5945 pxmitframe->attrib.mdata = 1;
5946 else
5947 pxmitframe->attrib.mdata = 0;
5948
5949 pxmitframe->attrib.triggered = 1;
5950
5951 if (xmitframe_hiq_filter(pxmitframe))
5952 pxmitframe->attrib.qsel = 0x11;
5953
5954 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
5955 }
5956
5957
5958 spin_unlock_bh(&pxmitpriv->lock);
5959
5960
5961 rtw_chk_hi_queue_cmd(padapter);
5962 }
5963
5964 return H2C_SUCCESS;
5965}
5966
5967u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf)
5968{
5969 if (send_beacon(padapter) == _FAIL)
5970 return H2C_PARAMETERS_ERROR;
5971
5972
5973 chk_bmc_sleepq_hdl(padapter, NULL);
5974
5975 return H2C_SUCCESS;
5976}
5977
5978int rtw_chk_start_clnt_join(struct adapter *padapter, u8 *ch, u8 *bw, u8 *offset)
5979{
5980 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5981 unsigned char cur_ch = pmlmeext->cur_channel;
5982 unsigned char cur_bw = pmlmeext->cur_bwmode;
5983 unsigned char cur_ch_offset = pmlmeext->cur_ch_offset;
5984 bool connect_allow = true;
5985
5986 if (!ch || !bw || !offset) {
5987 rtw_warn_on(1);
5988 connect_allow = false;
5989 }
5990
5991 if (connect_allow) {
5992 *ch = cur_ch;
5993 *bw = cur_bw;
5994 *offset = cur_ch_offset;
5995 }
5996
5997 return connect_allow ? _SUCCESS : _FAIL;
5998}
5999
6000
6001int rtw_get_ch_setting_union(struct adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
6002{
6003 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
6004 struct adapter *iface;
6005
6006 if (ch)
6007 *ch = 0;
6008 if (bw)
6009 *bw = CHANNEL_WIDTH_20;
6010 if (offset)
6011 *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6012
6013 iface = dvobj->padapters;
6014
6015 if (!check_fwstate(&iface->mlmepriv, _FW_LINKED|_FW_UNDER_LINKING))
6016 return 0;
6017
6018 return 1;
6019}
6020
6021u8 set_ch_hdl(struct adapter *padapter, u8 *pbuf)
6022{
6023 struct set_ch_parm *set_ch_parm;
6024 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6025
6026 if (!pbuf)
6027 return H2C_PARAMETERS_ERROR;
6028
6029 set_ch_parm = (struct set_ch_parm *)pbuf;
6030
6031 pmlmeext->cur_channel = set_ch_parm->ch;
6032 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
6033 pmlmeext->cur_bwmode = set_ch_parm->bw;
6034
6035 set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
6036
6037 return H2C_SUCCESS;
6038}
6039
6040u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf)
6041{
6042 struct SetChannelPlan_param *setChannelPlan_param;
6043 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6044
6045 if (!pbuf)
6046 return H2C_PARAMETERS_ERROR;
6047
6048 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
6049
6050 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
6051 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
6052
6053 if (padapter->rtw_wdev && padapter->rtw_wdev->wiphy) {
6054 struct regulatory_request request;
6055
6056 request.initiator = NL80211_REGDOM_SET_BY_DRIVER;
6057 rtw_reg_notifier(padapter->rtw_wdev->wiphy, &request);
6058 }
6059
6060 return H2C_SUCCESS;
6061}
6062
6063u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf)
6064{
6065 return H2C_REJECTED;
6066}
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf)
6079{
6080 return H2C_REJECTED;
6081}
6082
6083u8 run_in_thread_hdl(struct adapter *padapter, u8 *pbuf)
6084{
6085 struct RunInThread_param *p;
6086
6087
6088 if (NULL == pbuf)
6089 return H2C_PARAMETERS_ERROR;
6090 p = (struct RunInThread_param *)pbuf;
6091
6092 if (p->func)
6093 p->func(p->context);
6094
6095 return H2C_SUCCESS;
6096}
6097