1
2
3
4
5
6
7#define _RTW_MLME_EXT_C_
8
9#include <linux/ieee80211.h>
10#include <asm/unaligned.h>
11
12#include <osdep_service.h>
13#include <drv_types.h>
14#include <wifi.h>
15#include <rtw_mlme_ext.h>
16#include <wlan_bssdef.h>
17#include <mlme_osdep.h>
18#include <recv_osdep.h>
19
20static u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
21
22
23
24
25unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
26unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
27unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
28unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09};
29unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A};
30
31unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
32unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
33
34unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
35unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
36
37extern unsigned char REALTEK_96B_IE[];
38
39
40
41
42const u8 MCS_rate_1R[16] = {
43 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
45};
46
47
48
49
50static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
51 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
52 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
53 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
54 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
55 {{10, 11, 12, 13}, 4},
56 {{}, 0},
57};
58
59static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
60
61 {0x02},
62 {0x02},
63 {0x01},
64 {0x01},
65 {0x01},
66 {0x03},
67 {0x03},
68 {0x01},
69 {0x03},
70 {0x03},
71 {0x00},
72 {0x02},
73 {0x01},
74 {0x02},
75 {0x02},
76 {0x02},
77 {0x01},
78 {0x02},
79 {0x01},
80 {0x00},
81 {0x02},
82 {0x00},
83 {0x00},
84 {0x03},
85 {0x05},
86 {0x02},
87 {0x00},
88 {0x00},
89 {0x00},
90 {0x00},
91 {0x00},
92 {0x05},
93
94 {0x00},
95 {0x01},
96 {0x02},
97 {0x03},
98 {0x04},
99 {0x02},
100 {0x00},
101 {0x03},
102 {0x00},
103 {0x00},
104 {0x00},
105 {0x00},
106 {0x00},
107 {0x00},
108 {0x00},
109 {0x00},
110 {0x00},
111 {0x00},
112 {0x00},
113 {0x00},
114 {0x02},
115 {0x00},
116 {0x00},
117 {0x03},
118 {0x03},
119 {0x02},
120 {0x00},
121 {0x00},
122 {0x00},
123 {0x00},
124 {0x00},
125 {0x00},
126 {0x02},
127 {0x03},
128};
129
130static const struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {
131 0x03
132};
133
134
135
136
137
138
139
140
141int rtw_ch_set_search_ch(struct rt_channel_info *ch_set, const u32 ch)
142{
143 int i;
144
145 for (i = 0; ch_set[i].ChannelNum != 0; i++) {
146 if (ch == ch_set[i].ChannelNum)
147 break;
148 }
149
150 if (i >= ch_set[i].ChannelNum)
151 return -1;
152 return i;
153}
154
155struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
156{
157 struct xmit_frame *pmgntframe;
158 struct xmit_buf *pxmitbuf;
159
160 pmgntframe = rtw_alloc_xmitframe(pxmitpriv);
161 if (!pmgntframe) {
162 DBG_88E("%s, alloc xmitframe fail\n", __func__);
163 return NULL;
164 }
165
166 pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv);
167 if (!pxmitbuf) {
168 DBG_88E("%s, alloc xmitbuf fail\n", __func__);
169 rtw_free_xmitframe(pxmitpriv, pmgntframe);
170 return NULL;
171 }
172 pmgntframe->frame_tag = MGNT_FRAMETAG;
173 pmgntframe->pxmitbuf = pxmitbuf;
174 pmgntframe->buf_addr = pxmitbuf->pbuf;
175 pxmitbuf->priv_data = pmgntframe;
176 return pmgntframe;
177}
178
179
180
181
182
183
184
185void update_mgnt_tx_rate(struct adapter *padapter, u8 rate)
186{
187 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
188
189 pmlmeext->tx_rate = rate;
190 DBG_88E("%s(): rate = %x\n", __func__, rate);
191}
192
193void update_mgntframe_attrib(struct adapter *padapter, struct pkt_attrib *pattrib)
194{
195 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
196
197 memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
198
199 pattrib->hdrlen = 24;
200 pattrib->nr_frags = 1;
201 pattrib->priority = 7;
202 pattrib->mac_id = 0;
203 pattrib->qsel = 0x12;
204
205 pattrib->pktlen = 0;
206
207 if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
208 pattrib->raid = 6;
209 else
210 pattrib->raid = 5;
211
212 pattrib->encrypt = _NO_PRIVACY_;
213 pattrib->bswenc = false;
214
215 pattrib->qos_en = false;
216 pattrib->ht_en = false;
217 pattrib->bwmode = HT_CHANNEL_WIDTH_20;
218 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
219 pattrib->sgi = false;
220
221 pattrib->seqnum = pmlmeext->mgnt_seq;
222
223 pattrib->retry_ctrl = true;
224}
225
226static void dump_mgntframe(struct adapter *padapter,
227 struct xmit_frame *pmgntframe)
228{
229 if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
230 return;
231
232 rtw_hal_mgnt_xmit(padapter, pmgntframe);
233}
234
235static s32 dump_mgntframe_and_wait(struct adapter *padapter,
236 struct xmit_frame *pmgntframe,
237 int timeout_ms)
238{
239 s32 ret = _FAIL;
240 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
241 struct submit_ctx sctx;
242
243 if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
244 return ret;
245
246 rtw_sctx_init(&sctx, timeout_ms);
247 pxmitbuf->sctx = &sctx;
248
249 ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
250
251 if (ret == _SUCCESS)
252 ret = rtw_sctx_wait(&sctx);
253
254 return ret;
255}
256
257static s32 dump_mgntframe_and_wait_ack(struct adapter *padapter,
258 struct xmit_frame *pmgntframe)
259{
260 s32 ret = _FAIL;
261 u32 timeout_ms = 500;
262 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
263
264 if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
265 return -1;
266
267 if (mutex_lock_interruptible(&pxmitpriv->ack_tx_mutex))
268 return _FAIL;
269 pxmitpriv->ack_tx = true;
270
271 pmgntframe->ack_report = 1;
272 if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS)
273 ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms);
274
275 pxmitpriv->ack_tx = false;
276 mutex_unlock(&pxmitpriv->ack_tx_mutex);
277
278 return ret;
279}
280
281static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
282{
283 u8 *ssid_ie;
284 uint ssid_len_ori;
285 int len_diff = 0;
286
287 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
288
289 if (ssid_ie && ssid_len_ori > 0) {
290 switch (hidden_ssid_mode) {
291 case 1: {
292 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
293 u32 remain_len = 0;
294
295 remain_len = ies_len - (next_ie - ies);
296
297 ssid_ie[1] = 0;
298 memcpy(ssid_ie+2, next_ie, remain_len);
299 len_diff -= ssid_len_ori;
300
301 break;
302 }
303 case 2:
304 memset(&ssid_ie[2], 0, ssid_len_ori);
305 break;
306 default:
307 break;
308 }
309 }
310
311 return len_diff;
312}
313
314static void issue_beacon(struct adapter *padapter, int timeout_ms)
315{
316 struct xmit_frame *pmgntframe;
317 struct pkt_attrib *pattrib;
318 unsigned char *pframe;
319 struct ieee80211_hdr *pwlanhdr;
320 __le16 *fctrl;
321 unsigned int rate_len;
322 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
323 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
324 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
325 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
326 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
327 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
328
329 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
330 if (!pmgntframe) {
331 DBG_88E("%s, alloc mgnt frame fail\n", __func__);
332 return;
333 }
334#if defined(CONFIG_88EU_AP_MODE)
335 spin_lock_bh(&pmlmepriv->bcn_update_lock);
336#endif
337
338
339 pattrib = &pmgntframe->attrib;
340 update_mgntframe_attrib(padapter, pattrib);
341 pattrib->qsel = 0x10;
342
343 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
344
345 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
346 pwlanhdr = (struct ieee80211_hdr *)pframe;
347
348 fctrl = &pwlanhdr->frame_control;
349 *(fctrl) = 0;
350
351 ether_addr_copy(pwlanhdr->addr1, bc_addr);
352 ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
353 ether_addr_copy(pwlanhdr->addr3, cur_network->MacAddress);
354
355 SetSeqNum(pwlanhdr, 0);
356
357 SetFrameSubType(pframe, WIFI_BEACON);
358
359 pframe += sizeof(struct ieee80211_hdr_3addr);
360 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
361
362 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
363 int len_diff;
364 u8 *wps_ie;
365 uint wps_ielen;
366 u8 sr = 0;
367
368 memcpy(pframe, cur_network->ies, cur_network->ie_length);
369 len_diff = update_hidden_ssid(
370 pframe+_BEACON_IE_OFFSET_
371 , cur_network->ie_length-_BEACON_IE_OFFSET_
372 , pmlmeinfo->hidden_ssid_mode
373 );
374 pframe += (cur_network->ie_length+len_diff);
375 pattrib->pktlen += (cur_network->ie_length+len_diff);
376 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
377 pattrib->pktlen-sizeof(struct ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
378 if (wps_ie && wps_ielen > 0)
379 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
380 if (sr != 0)
381 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
382 else
383 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
384
385 goto _issue_bcn;
386 }
387
388
389
390
391 pframe += 8;
392 pattrib->pktlen += 8;
393
394
395
396 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->ies)), 2);
397
398 pframe += 2;
399 pattrib->pktlen += 2;
400
401
402
403 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->ies)), 2);
404
405 pframe += 2;
406 pattrib->pktlen += 2;
407
408
409 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
410
411
412 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
413 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, min_t(unsigned int, rate_len, 8), cur_network->SupportedRates, &pattrib->pktlen);
414
415
416 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
417
418 {
419 u8 erpinfo = 0;
420 u32 ATIMWindow;
421
422 ATIMWindow = 0;
423 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
424
425
426 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
427 }
428
429
430 if (rate_len > 8)
431 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
432
433_issue_bcn:
434
435#if defined(CONFIG_88EU_AP_MODE)
436 pmlmepriv->update_bcn = false;
437
438 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
439#endif
440
441 if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
442 DBG_88E("beacon frame too large\n");
443 return;
444 }
445
446 pattrib->last_txcmdsz = pattrib->pktlen;
447
448
449 if (timeout_ms > 0)
450 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
451 else
452 dump_mgntframe(padapter, pmgntframe);
453}
454
455static void issue_probersp(struct adapter *padapter, unsigned char *da)
456{
457 struct xmit_frame *pmgntframe;
458 struct pkt_attrib *pattrib;
459 unsigned char *pframe;
460 struct ieee80211_hdr *pwlanhdr;
461 __le16 *fctrl;
462 unsigned char *mac, *bssid;
463 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
464#if defined(CONFIG_88EU_AP_MODE)
465 u8 *pwps_ie;
466 uint wps_ielen;
467 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
468#endif
469 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
470 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
471 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
472 unsigned int rate_len;
473
474 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
475 if (!pmgntframe) {
476 DBG_88E("%s, alloc mgnt frame fail\n", __func__);
477 return;
478 }
479
480
481 pattrib = &pmgntframe->attrib;
482 update_mgntframe_attrib(padapter, pattrib);
483
484 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
485
486 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
487 pwlanhdr = (struct ieee80211_hdr *)pframe;
488
489 mac = myid(&(padapter->eeprompriv));
490 bssid = cur_network->MacAddress;
491
492 fctrl = &pwlanhdr->frame_control;
493 *(fctrl) = 0;
494 ether_addr_copy(pwlanhdr->addr1, da);
495 ether_addr_copy(pwlanhdr->addr2, mac);
496 ether_addr_copy(pwlanhdr->addr3, bssid);
497
498 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
499 pmlmeext->mgnt_seq++;
500 SetFrameSubType(fctrl, WIFI_PROBERSP);
501
502 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
503 pattrib->pktlen = pattrib->hdrlen;
504 pframe += pattrib->hdrlen;
505
506 if (cur_network->ie_length > MAX_IE_SZ)
507 return;
508
509#if defined(CONFIG_88EU_AP_MODE)
510 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
511 pwps_ie = rtw_get_wps_ie(cur_network->ies+_FIXED_IE_LENGTH_, cur_network->ie_length-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
512
513
514 if ((pmlmepriv->wps_probe_resp_ie != NULL) && pwps_ie && (wps_ielen > 0)) {
515 uint wps_offset, remainder_ielen;
516 u8 *premainder_ie;
517
518 wps_offset = (uint)(pwps_ie - cur_network->ies);
519
520 premainder_ie = pwps_ie + wps_ielen;
521
522 remainder_ielen = cur_network->ie_length - wps_offset - wps_ielen;
523
524 memcpy(pframe, cur_network->ies, wps_offset);
525 pframe += wps_offset;
526 pattrib->pktlen += wps_offset;
527
528 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];
529 if ((wps_offset+wps_ielen+2) <= MAX_IE_SZ) {
530 memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
531 pframe += wps_ielen+2;
532 pattrib->pktlen += wps_ielen+2;
533 }
534
535 if ((wps_offset+wps_ielen+2+remainder_ielen) <= MAX_IE_SZ) {
536 memcpy(pframe, premainder_ie, remainder_ielen);
537 pframe += remainder_ielen;
538 pattrib->pktlen += remainder_ielen;
539 }
540 } else {
541 memcpy(pframe, cur_network->ies, cur_network->ie_length);
542 pframe += cur_network->ie_length;
543 pattrib->pktlen += cur_network->ie_length;
544 }
545 } else
546#endif
547 {
548
549 pframe += 8;
550 pattrib->pktlen += 8;
551
552
553
554 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->ies)), 2);
555
556 pframe += 2;
557 pattrib->pktlen += 2;
558
559
560
561 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->ies)), 2);
562
563 pframe += 2;
564 pattrib->pktlen += 2;
565
566
567
568
569 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
570
571
572 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
573 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, min_t(unsigned int, rate_len, 8), cur_network->SupportedRates, &pattrib->pktlen);
574
575
576 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
577
578 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
579 u8 erpinfo = 0;
580 u32 ATIMWindow;
581
582
583 ATIMWindow = 0;
584 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
585
586
587 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
588 }
589
590
591 if (rate_len > 8)
592 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
593
594 }
595
596 pattrib->last_txcmdsz = pattrib->pktlen;
597
598 dump_mgntframe(padapter, pmgntframe);
599}
600
601static int issue_probereq(struct adapter *padapter,
602 struct ndis_802_11_ssid *pssid, u8 *da,
603 bool wait_ack)
604{
605 int ret = _FAIL;
606 struct xmit_frame *pmgntframe;
607 struct pkt_attrib *pattrib;
608 unsigned char *pframe;
609 struct ieee80211_hdr *pwlanhdr;
610 __le16 *fctrl;
611 unsigned char *mac;
612 unsigned char bssrate[NumRates];
613 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
614 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
615 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
616 int bssrate_len = 0;
617 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
618
619 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+%s\n", __func__));
620
621 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
622 if (!pmgntframe)
623 goto exit;
624
625
626 pattrib = &pmgntframe->attrib;
627 update_mgntframe_attrib(padapter, pattrib);
628
629 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
630
631 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
632 pwlanhdr = (struct ieee80211_hdr *)pframe;
633
634 mac = myid(&(padapter->eeprompriv));
635
636 fctrl = &pwlanhdr->frame_control;
637 *(fctrl) = 0;
638
639 if (da) {
640
641 ether_addr_copy(pwlanhdr->addr1, da);
642 ether_addr_copy(pwlanhdr->addr3, da);
643 } else {
644
645 ether_addr_copy(pwlanhdr->addr1, bc_addr);
646 ether_addr_copy(pwlanhdr->addr3, bc_addr);
647 }
648
649 ether_addr_copy(pwlanhdr->addr2, mac);
650
651 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
652 pmlmeext->mgnt_seq++;
653 SetFrameSubType(pframe, WIFI_PROBEREQ);
654
655 pframe += sizeof(struct ieee80211_hdr_3addr);
656 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
657
658 if (pssid)
659 pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
660 else
661 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
662
663 get_rate_set(padapter, bssrate, &bssrate_len);
664
665 if (bssrate_len > 8) {
666 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &(pattrib->pktlen));
667 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
668 } else {
669 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &(pattrib->pktlen));
670 }
671
672
673 if (pmlmepriv->wps_probe_req_ie_len > 0 && pmlmepriv->wps_probe_req_ie) {
674 memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
675 pframe += pmlmepriv->wps_probe_req_ie_len;
676 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
677 }
678
679 pattrib->last_txcmdsz = pattrib->pktlen;
680
681 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
682 ("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
683
684 if (wait_ack) {
685 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
686 } else {
687 dump_mgntframe(padapter, pmgntframe);
688 ret = _SUCCESS;
689 }
690
691exit:
692 return ret;
693}
694
695static int issue_probereq_ex(struct adapter *padapter,
696 struct ndis_802_11_ssid *pssid, u8 *da,
697 int try_cnt, int wait_ms)
698{
699 int ret;
700 int i = 0;
701 unsigned long start = jiffies;
702
703 do {
704 ret = issue_probereq(padapter, pssid, da, wait_ms > 0);
705
706 i++;
707
708 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
709 break;
710
711 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
712 msleep(wait_ms);
713
714 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
715
716 if (ret != _FAIL) {
717 ret = _SUCCESS;
718 goto exit;
719 }
720
721 if (try_cnt && wait_ms) {
722 if (da)
723 DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n",
724 FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter),
725 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
726 jiffies_to_msecs(jiffies - start));
727 else
728 DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
729 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
730 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
731 jiffies_to_msecs(jiffies - start));
732 }
733exit:
734 return ret;
735}
736
737
738static void issue_auth(struct adapter *padapter, struct sta_info *psta,
739 unsigned short status)
740{
741 struct xmit_frame *pmgntframe;
742 struct pkt_attrib *pattrib;
743 unsigned char *pframe;
744 struct ieee80211_hdr *pwlanhdr;
745 __le16 *fctrl;
746 unsigned int val32;
747 u16 val16;
748#ifdef CONFIG_88EU_AP_MODE
749 __le16 le_val16;
750#endif
751 int use_shared_key = 0;
752 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
753 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
754 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
755 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
756
757 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
758 if (pmgntframe == NULL)
759 return;
760
761
762 pattrib = &pmgntframe->attrib;
763 update_mgntframe_attrib(padapter, pattrib);
764
765 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
766
767 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
768 pwlanhdr = (struct ieee80211_hdr *)pframe;
769
770 fctrl = &pwlanhdr->frame_control;
771 *(fctrl) = 0;
772
773 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
774 pmlmeext->mgnt_seq++;
775 SetFrameSubType(pframe, WIFI_AUTH);
776
777 pframe += sizeof(struct ieee80211_hdr_3addr);
778 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
779
780 if (psta) {
781#ifdef CONFIG_88EU_AP_MODE
782
783 ether_addr_copy(pwlanhdr->addr1, psta->hwaddr);
784 ether_addr_copy(pwlanhdr->addr2,
785 myid(&(padapter->eeprompriv)));
786 ether_addr_copy(pwlanhdr->addr3,
787 myid(&(padapter->eeprompriv)));
788
789
790 val16 = (u16)psta->authalg;
791
792 if (status != _STATS_SUCCESSFUL_)
793 val16 = 0;
794
795 if (val16) {
796 le_val16 = cpu_to_le16(val16);
797 use_shared_key = 1;
798 } else {
799 le_val16 = 0;
800 }
801
802 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, &le_val16,
803 &pattrib->pktlen);
804
805
806 val16 = (u16)psta->auth_seq;
807 le_val16 = cpu_to_le16(val16);
808 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, &le_val16,
809 &pattrib->pktlen);
810
811
812 val16 = status;
813 le_val16 = cpu_to_le16(val16);
814 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_,
815 &le_val16, &pattrib->pktlen);
816
817
818 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
819 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
820#endif
821 } else {
822 __le32 le_tmp32;
823 __le16 le_tmp16;
824
825 ether_addr_copy(pwlanhdr->addr1, pnetwork->MacAddress);
826 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
827 ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress);
828
829
830 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;
831 if (val16)
832 use_shared_key = 1;
833
834
835 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
836 val32 = (pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30);
837 le_tmp32 = cpu_to_le32(val32);
838 pframe = rtw_set_fixed_ie(pframe, 4, &le_tmp32,
839 &pattrib->pktlen);
840
841 pattrib->iv_len = 4;
842 }
843
844 le_tmp16 = cpu_to_le16(val16);
845 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, &le_tmp16,
846 &pattrib->pktlen);
847
848
849 val16 = pmlmeinfo->auth_seq;
850 le_tmp16 = cpu_to_le16(val16);
851 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, &le_tmp16,
852 &pattrib->pktlen);
853
854
855 le_tmp16 = cpu_to_le16(status);
856 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, &le_tmp16,
857 &pattrib->pktlen);
858
859
860 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
861 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
862
863 SetPrivacy(fctrl);
864
865 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
866
867 pattrib->encrypt = _WEP40_;
868
869 pattrib->icv_len = 4;
870
871 pattrib->pktlen += pattrib->icv_len;
872 }
873 }
874
875 pattrib->last_txcmdsz = pattrib->pktlen;
876
877 rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
878 DBG_88E("%s\n", __func__);
879 dump_mgntframe(padapter, pmgntframe);
880}
881
882#ifdef CONFIG_88EU_AP_MODE
883static void issue_asocrsp(struct adapter *padapter, unsigned short status,
884 struct sta_info *pstat, int pkt_type)
885{
886 struct xmit_frame *pmgntframe;
887 struct ieee80211_hdr *pwlanhdr;
888 struct pkt_attrib *pattrib;
889 unsigned char *pbuf, *pframe;
890 unsigned short val;
891 __le16 *fctrl;
892 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
893 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
894 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
895 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
896 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
897 u8 *ie = pnetwork->ies;
898 __le16 lestatus, leval;
899
900 DBG_88E("%s\n", __func__);
901
902 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
903 if (!pmgntframe)
904 return;
905
906
907 pattrib = &pmgntframe->attrib;
908 update_mgntframe_attrib(padapter, pattrib);
909
910 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
911
912 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
913 pwlanhdr = (struct ieee80211_hdr *)pframe;
914
915 fctrl = &pwlanhdr->frame_control;
916 *(fctrl) = 0;
917
918 ether_addr_copy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr);
919 ether_addr_copy((void *)GetAddr2Ptr(pwlanhdr),
920 myid(&(padapter->eeprompriv)));
921 ether_addr_copy((void *)GetAddr3Ptr(pwlanhdr), pnetwork->MacAddress);
922
923 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
924 pmlmeext->mgnt_seq++;
925 if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
926 SetFrameSubType(pwlanhdr, pkt_type);
927 else
928 return;
929
930 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
931 pattrib->pktlen += pattrib->hdrlen;
932 pframe += pattrib->hdrlen;
933
934
935 val = *(unsigned short *)rtw_get_capability_from_ie(ie);
936
937 pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_, &val, &pattrib->pktlen);
938
939 lestatus = cpu_to_le16(status);
940 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, &lestatus,
941 &pattrib->pktlen);
942
943 leval = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
944 pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_, &leval, &pattrib->pktlen);
945
946 if (pstat->bssratelen <= 8) {
947 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
948 } else {
949 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
950 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
951 }
952
953 if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) {
954 uint ie_len = 0;
955
956
957 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->ie_length - _BEACON_IE_OFFSET_));
958 if (pbuf && ie_len > 0) {
959 memcpy(pframe, pbuf, ie_len+2);
960 pframe += (ie_len+2);
961 pattrib->pktlen += (ie_len+2);
962 }
963
964
965 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->ie_length - _BEACON_IE_OFFSET_));
966 if (pbuf && ie_len > 0) {
967 memcpy(pframe, pbuf, ie_len+2);
968 pframe += (ie_len+2);
969 pattrib->pktlen += (ie_len+2);
970 }
971 }
972
973
974 if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) {
975 uint ie_len = 0;
976 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
977
978 for (pbuf = ie + _BEACON_IE_OFFSET_;; pbuf += (ie_len + 2)) {
979 pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->ie_length - _BEACON_IE_OFFSET_ - (ie_len + 2)));
980 if (pbuf && !memcmp(pbuf+2, WMM_PARA_IE, 6)) {
981 memcpy(pframe, pbuf, ie_len+2);
982 pframe += (ie_len+2);
983 pattrib->pktlen += (ie_len+2);
984 break;
985 }
986
987 if ((pbuf == NULL) || (ie_len == 0))
988 break;
989 }
990 }
991
992 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
993 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &(pattrib->pktlen));
994
995
996 if (pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len > 0) {
997 memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
998
999 pframe += pmlmepriv->wps_assoc_resp_ie_len;
1000 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
1001 }
1002
1003 pattrib->last_txcmdsz = pattrib->pktlen;
1004 dump_mgntframe(padapter, pmgntframe);
1005}
1006#endif
1007
1008static void issue_assocreq(struct adapter *padapter)
1009{
1010 int ret = _FAIL;
1011 struct xmit_frame *pmgntframe;
1012 struct pkt_attrib *pattrib;
1013 unsigned char *pframe, *p;
1014 struct ieee80211_hdr *pwlanhdr;
1015 __le16 *fctrl;
1016 unsigned int i, j, ie_len, index = 0;
1017 unsigned char bssrate[NumRates], sta_bssrate[NumRates];
1018 struct ndis_802_11_var_ie *pIE;
1019 struct registry_priv *pregpriv = &padapter->registrypriv;
1020 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
1021 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1022 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1023 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1024 int bssrate_len = 0, sta_bssrate_len = 0;
1025 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1026
1027 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1028 if (!pmgntframe)
1029 goto exit;
1030
1031
1032 pattrib = &pmgntframe->attrib;
1033 update_mgntframe_attrib(padapter, pattrib);
1034
1035 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
1036 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
1037 pwlanhdr = (struct ieee80211_hdr *)pframe;
1038
1039 fctrl = &pwlanhdr->frame_control;
1040 *(fctrl) = 0;
1041 ether_addr_copy(pwlanhdr->addr1, pnetwork->MacAddress);
1042 ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
1043 ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress);
1044
1045 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
1046 pmlmeext->mgnt_seq++;
1047 SetFrameSubType(pframe, WIFI_ASSOCREQ);
1048
1049 pframe += sizeof(struct ieee80211_hdr_3addr);
1050 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
1051
1052
1053
1054 memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.ies), 2);
1055
1056 pframe += 2;
1057 pattrib->pktlen += 2;
1058
1059
1060
1061 put_unaligned_le16(3, pframe);
1062 pframe += 2;
1063 pattrib->pktlen += 2;
1064
1065
1066 pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
1067
1068
1069
1070
1071 get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
1072
1073 if (pmlmeext->cur_channel == 14)
1074 sta_bssrate_len = 4;
1075
1076 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
1077 if (pmlmeinfo->network.SupportedRates[i] == 0)
1078 break;
1079 DBG_88E("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
1080 }
1081
1082 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
1083 if (pmlmeinfo->network.SupportedRates[i] == 0)
1084 break;
1085
1086
1087 for (j = 0; j < sta_bssrate_len; j++) {
1088
1089 if ((pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
1090 == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK))
1091 break;
1092 }
1093
1094 if (j == sta_bssrate_len) {
1095
1096 DBG_88E("%s(): the rate[%d]=%02X is not supported by STA!\n", __func__, i, pmlmeinfo->network.SupportedRates[i]);
1097 } else {
1098
1099 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
1100 }
1101 }
1102
1103 bssrate_len = index;
1104 DBG_88E("bssrate_len=%d\n", bssrate_len);
1105
1106 if (bssrate_len == 0) {
1107 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1108 rtw_free_xmitframe(pxmitpriv, pmgntframe);
1109 goto exit;
1110 }
1111
1112 if (bssrate_len > 8) {
1113 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &(pattrib->pktlen));
1114 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
1115 } else {
1116 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &(pattrib->pktlen));
1117 }
1118
1119
1120 p = rtw_get_ie((pmlmeinfo->network.ies + sizeof(struct ndis_802_11_fixed_ie)), _RSN_IE_2_, &ie_len, (pmlmeinfo->network.ie_length - sizeof(struct ndis_802_11_fixed_ie)));
1121 if (p)
1122 pframe = rtw_set_ie(pframe, _RSN_IE_2_, ie_len, (p + 2), &(pattrib->pktlen));
1123
1124
1125 if (padapter->mlmepriv.htpriv.ht_option) {
1126 p = rtw_get_ie((pmlmeinfo->network.ies + sizeof(struct ndis_802_11_fixed_ie)), _HT_CAPABILITY_IE_, &ie_len, (pmlmeinfo->network.ie_length - sizeof(struct ndis_802_11_fixed_ie)));
1127 if ((p != NULL) && (!(is_ap_in_tkip(padapter)))) {
1128 memcpy(&pmlmeinfo->HT_caps, p + 2, sizeof(struct ieee80211_ht_cap));
1129
1130
1131 if (pregpriv->cbw40_enable == 0)
1132 pmlmeinfo->HT_caps.cap_info &= cpu_to_le16(~(BIT(6) | BIT(1)));
1133 else
1134 pmlmeinfo->HT_caps.cap_info |= cpu_to_le16(BIT(1));
1135
1136
1137 pmlmeinfo->HT_caps.cap_info |= cpu_to_le16(0x000c);
1138
1139 if (pregpriv->rx_stbc)
1140 pmlmeinfo->HT_caps.cap_info |= cpu_to_le16(0x0100);
1141 memcpy((u8 *)&pmlmeinfo->HT_caps.mcs, MCS_rate_1R, 16);
1142 pframe = rtw_set_ie(pframe, _HT_CAPABILITY_IE_, ie_len, (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
1143 }
1144 }
1145
1146
1147 for (i = sizeof(struct ndis_802_11_fixed_ie); i < pmlmeinfo->network.ie_length; i += (pIE->Length + 2)) {
1148 pIE = (struct ndis_802_11_var_ie *)(pmlmeinfo->network.ies + i);
1149
1150 switch (pIE->ElementID) {
1151 case _VENDOR_SPECIFIC_IE_:
1152 if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
1153 (!memcmp(pIE->data, WMM_OUI, 4)) ||
1154 (!memcmp(pIE->data, WPS_OUI, 4))) {
1155 if (!padapter->registrypriv.wifi_spec) {
1156
1157
1158
1159 if (!memcmp(pIE->data, WPS_OUI, 4))
1160 pIE->Length = 14;
1161 }
1162 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, pIE->Length, pIE->data, &(pattrib->pktlen));
1163 }
1164 break;
1165 default:
1166 break;
1167 }
1168 }
1169
1170 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
1171 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &(pattrib->pktlen));
1172
1173 pattrib->last_txcmdsz = pattrib->pktlen;
1174 dump_mgntframe(padapter, pmgntframe);
1175
1176 ret = _SUCCESS;
1177
1178exit:
1179 if (ret == _SUCCESS)
1180 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
1181 else
1182 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
1183}
1184
1185
1186static int _issue_nulldata(struct adapter *padapter, unsigned char *da,
1187 unsigned int power_mode, bool wait_ack)
1188{
1189 int ret = _FAIL;
1190 struct xmit_frame *pmgntframe;
1191 struct pkt_attrib *pattrib;
1192 unsigned char *pframe;
1193 struct ieee80211_hdr *pwlanhdr;
1194 __le16 *fctrl;
1195 struct xmit_priv *pxmitpriv;
1196 struct mlme_ext_priv *pmlmeext;
1197 struct mlme_ext_info *pmlmeinfo;
1198 struct wlan_bssid_ex *pnetwork;
1199
1200 if (!padapter)
1201 goto exit;
1202
1203 pxmitpriv = &(padapter->xmitpriv);
1204 pmlmeext = &(padapter->mlmeextpriv);
1205 pmlmeinfo = &(pmlmeext->mlmext_info);
1206 pnetwork = &(pmlmeinfo->network);
1207
1208 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1209 if (!pmgntframe)
1210 goto exit;
1211
1212
1213 pattrib = &pmgntframe->attrib;
1214 update_mgntframe_attrib(padapter, pattrib);
1215 pattrib->retry_ctrl = false;
1216
1217 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
1218
1219 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
1220 pwlanhdr = (struct ieee80211_hdr *)pframe;
1221
1222 fctrl = &pwlanhdr->frame_control;
1223 *(fctrl) = 0;
1224
1225 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
1226 SetFrDs(fctrl);
1227 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
1228 SetToDs(fctrl);
1229
1230 if (power_mode)
1231 SetPwrMgt(fctrl);
1232
1233 ether_addr_copy(pwlanhdr->addr1, da);
1234 ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
1235 ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress);
1236
1237 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
1238 pmlmeext->mgnt_seq++;
1239 SetFrameSubType(pframe, WIFI_DATA_NULL);
1240
1241 pframe += sizeof(struct ieee80211_hdr_3addr);
1242 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
1243
1244 pattrib->last_txcmdsz = pattrib->pktlen;
1245
1246 if (wait_ack) {
1247 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
1248 } else {
1249 dump_mgntframe(padapter, pmgntframe);
1250 ret = _SUCCESS;
1251 }
1252
1253exit:
1254 return ret;
1255}
1256
1257
1258
1259int issue_nulldata(struct adapter *padapter, unsigned char *da,
1260 unsigned int power_mode, int try_cnt, int wait_ms)
1261{
1262 int ret;
1263 int i = 0;
1264 unsigned long start = jiffies;
1265 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1266 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1267 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1268
1269
1270 if (da == NULL)
1271 da = pnetwork->MacAddress;
1272
1273 do {
1274 ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0);
1275
1276 i++;
1277
1278 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
1279 break;
1280
1281 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
1282 msleep(wait_ms);
1283 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
1284
1285 if (ret != _FAIL) {
1286 ret = _SUCCESS;
1287 goto exit;
1288 }
1289
1290 if (try_cnt && wait_ms) {
1291 if (da)
1292 DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n",
1293 FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter),
1294 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
1295 jiffies_to_msecs(jiffies - start));
1296 else
1297 DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
1298 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
1299 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
1300 jiffies_to_msecs(jiffies - start));
1301 }
1302exit:
1303 return ret;
1304}
1305
1306
1307static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da,
1308 u16 tid, bool wait_ack)
1309{
1310 int ret = _FAIL;
1311 struct xmit_frame *pmgntframe;
1312 struct pkt_attrib *pattrib;
1313 unsigned char *pframe;
1314 struct ieee80211_hdr *pwlanhdr;
1315 __le16 *fctrl;
1316 unsigned short *qc;
1317 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
1318 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1319 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1320 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1321
1322 DBG_88E("%s\n", __func__);
1323
1324 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1325 if (!pmgntframe)
1326 goto exit;
1327
1328
1329 pattrib = &pmgntframe->attrib;
1330 update_mgntframe_attrib(padapter, pattrib);
1331
1332 pattrib->hdrlen += 2;
1333 pattrib->qos_en = true;
1334 pattrib->eosp = 1;
1335 pattrib->ack_policy = 0;
1336 pattrib->mdata = 0;
1337
1338 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
1339
1340 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
1341 pwlanhdr = (struct ieee80211_hdr *)pframe;
1342
1343 fctrl = &pwlanhdr->frame_control;
1344 *(fctrl) = 0;
1345
1346 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
1347 SetFrDs(fctrl);
1348 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
1349 SetToDs(fctrl);
1350
1351 if (pattrib->mdata)
1352 SetMData(fctrl);
1353
1354 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
1355
1356 SetPriority(qc, tid);
1357
1358 SetEOSP(qc, pattrib->eosp);
1359
1360 SetAckpolicy(qc, pattrib->ack_policy);
1361
1362 ether_addr_copy(pwlanhdr->addr1, da);
1363 ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
1364 ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress);
1365
1366 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
1367 pmlmeext->mgnt_seq++;
1368 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
1369
1370 pframe += sizeof(struct ieee80211_qos_hdr);
1371 pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
1372
1373 pattrib->last_txcmdsz = pattrib->pktlen;
1374
1375 if (wait_ack) {
1376 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
1377 } else {
1378 dump_mgntframe(padapter, pmgntframe);
1379 ret = _SUCCESS;
1380 }
1381
1382exit:
1383 return ret;
1384}
1385
1386
1387
1388int issue_qos_nulldata(struct adapter *padapter, unsigned char *da,
1389 u16 tid, int try_cnt, int wait_ms)
1390{
1391 int ret;
1392 int i = 0;
1393 unsigned long start = jiffies;
1394 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1395 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1396 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1397
1398
1399 if (da == NULL)
1400 da = pnetwork->MacAddress;
1401
1402 do {
1403 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms > 0);
1404
1405 i++;
1406
1407 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
1408 break;
1409
1410 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
1411 msleep(wait_ms);
1412 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
1413
1414 if (ret != _FAIL) {
1415 ret = _SUCCESS;
1416 goto exit;
1417 }
1418
1419 if (try_cnt && wait_ms) {
1420 if (da)
1421 DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n",
1422 FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter),
1423 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
1424 jiffies_to_msecs(jiffies - start));
1425 else
1426 DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
1427 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
1428 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
1429 jiffies_to_msecs(jiffies - start));
1430 }
1431exit:
1432 return ret;
1433}
1434
1435static int _issue_deauth(struct adapter *padapter, unsigned char *da,
1436 unsigned short reason, bool wait_ack)
1437{
1438 struct xmit_frame *pmgntframe;
1439 struct pkt_attrib *pattrib;
1440 unsigned char *pframe;
1441 struct ieee80211_hdr *pwlanhdr;
1442 __le16 *fctrl;
1443 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
1444 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1445 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1446 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1447 int ret = _FAIL;
1448 __le16 le_tmp;
1449
1450 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1451 if (pmgntframe == NULL)
1452 goto exit;
1453
1454
1455 pattrib = &pmgntframe->attrib;
1456 update_mgntframe_attrib(padapter, pattrib);
1457 pattrib->retry_ctrl = false;
1458
1459 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
1460
1461 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
1462 pwlanhdr = (struct ieee80211_hdr *)pframe;
1463
1464 fctrl = &pwlanhdr->frame_control;
1465 *(fctrl) = 0;
1466
1467 ether_addr_copy(pwlanhdr->addr1, da);
1468 ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
1469 ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress);
1470
1471 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
1472 pmlmeext->mgnt_seq++;
1473 SetFrameSubType(pframe, WIFI_DEAUTH);
1474
1475 pframe += sizeof(struct ieee80211_hdr_3addr);
1476 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
1477
1478 le_tmp = cpu_to_le16(reason);
1479 pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_, &le_tmp,
1480 &pattrib->pktlen);
1481
1482 pattrib->last_txcmdsz = pattrib->pktlen;
1483
1484 if (wait_ack) {
1485 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
1486 } else {
1487 dump_mgntframe(padapter, pmgntframe);
1488 ret = _SUCCESS;
1489 }
1490
1491exit:
1492 return ret;
1493}
1494
1495int issue_deauth(struct adapter *padapter, unsigned char *da,
1496 unsigned short reason)
1497{
1498 DBG_88E("%s to %pM\n", __func__, da);
1499 return _issue_deauth(padapter, da, reason, false);
1500}
1501
1502static int issue_deauth_ex(struct adapter *padapter, u8 *da,
1503 unsigned short reason, int try_cnt,
1504 int wait_ms)
1505{
1506 int ret;
1507 int i = 0;
1508 unsigned long start = jiffies;
1509
1510 do {
1511 ret = _issue_deauth(padapter, da, reason, wait_ms > 0);
1512
1513 i++;
1514
1515 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
1516 break;
1517
1518 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
1519 mdelay(wait_ms);
1520 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
1521
1522 if (ret != _FAIL) {
1523 ret = _SUCCESS;
1524 goto exit;
1525 }
1526
1527 if (try_cnt && wait_ms) {
1528 if (da)
1529 DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n",
1530 FUNC_ADPT_ARG(padapter), da, rtw_get_oper_ch(padapter),
1531 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
1532 jiffies_to_msecs(jiffies - start));
1533 else
1534 DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
1535 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
1536 ret == _SUCCESS ? ", acked" : "", i, try_cnt,
1537 jiffies_to_msecs(jiffies - start));
1538 }
1539exit:
1540 return ret;
1541}
1542
1543static void issue_action_BA(struct adapter *padapter, unsigned char *raddr,
1544 unsigned char action, unsigned short status)
1545{
1546 u8 category = RTW_WLAN_CATEGORY_BACK;
1547 u16 start_seq;
1548 u16 BA_para_set;
1549 u16 reason_code;
1550 u16 BA_timeout_value;
1551 __le16 le_tmp;
1552 u16 BA_starting_seqctrl = 0;
1553 enum ht_cap_ampdu_factor max_rx_ampdu_factor;
1554 struct xmit_frame *pmgntframe;
1555 struct pkt_attrib *pattrib;
1556 u8 *pframe;
1557 struct ieee80211_hdr *pwlanhdr;
1558 __le16 *fctrl;
1559 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
1560 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1561 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1562 struct sta_info *psta;
1563 struct sta_priv *pstapriv = &padapter->stapriv;
1564 struct registry_priv *pregpriv = &padapter->registrypriv;
1565 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1566
1567 DBG_88E("%s, category=%d, action=%d, status=%d\n", __func__, category, action, status);
1568
1569 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1570 if (!pmgntframe)
1571 return;
1572
1573
1574 pattrib = &pmgntframe->attrib;
1575 update_mgntframe_attrib(padapter, pattrib);
1576
1577 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
1578
1579 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
1580 pwlanhdr = (struct ieee80211_hdr *)pframe;
1581
1582 fctrl = &pwlanhdr->frame_control;
1583 *(fctrl) = 0;
1584
1585 ether_addr_copy(pwlanhdr->addr1, raddr);
1586 ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
1587 ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress);
1588
1589 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
1590 pmlmeext->mgnt_seq++;
1591 SetFrameSubType(pframe, WIFI_ACTION);
1592
1593 pframe += sizeof(struct ieee80211_hdr_3addr);
1594 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
1595
1596 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
1597 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
1598
1599 if (category == 3) {
1600 switch (action) {
1601 case 0:
1602 do {
1603 pmlmeinfo->dialogToken++;
1604 } while (pmlmeinfo->dialogToken == 0);
1605 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
1606
1607 BA_para_set = 0x1002 | ((status & 0xf) << 2);
1608 le_tmp = cpu_to_le16(BA_para_set);
1609 pframe = rtw_set_fixed_ie(pframe, 2, &(le_tmp),
1610 &pattrib->pktlen);
1611
1612 BA_timeout_value = 5000;
1613 le_tmp = cpu_to_le16(BA_timeout_value);
1614 pframe = rtw_set_fixed_ie(pframe, 2, &(le_tmp),
1615 &pattrib->pktlen);
1616
1617 psta = rtw_get_stainfo(pstapriv, raddr);
1618 if (psta) {
1619 start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
1620
1621 DBG_88E("BA_starting_seqctrl=%d for TID=%d\n", start_seq, status & 0x07);
1622
1623 psta->BA_starting_seqctrl[status & 0x07] = start_seq;
1624
1625 BA_starting_seqctrl = start_seq << 4;
1626 }
1627 le_tmp = cpu_to_le16(BA_starting_seqctrl);
1628 pframe = rtw_set_fixed_ie(pframe, 2, &(le_tmp),
1629 &pattrib->pktlen);
1630 break;
1631 case 1:
1632 {
1633 struct ADDBA_request *ADDBA_req = &pmlmeinfo->ADDBA_req;
1634
1635 pframe = rtw_set_fixed_ie(pframe, 1,
1636 &ADDBA_req->dialog_token,
1637 &pattrib->pktlen);
1638 pframe = rtw_set_fixed_ie(pframe, 2, &status,
1639 &pattrib->pktlen);
1640
1641 BA_para_set = le16_to_cpu(ADDBA_req->BA_para_set) &
1642 0x3f;
1643 rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
1644 switch (max_rx_ampdu_factor) {
1645 case MAX_AMPDU_FACTOR_64K:
1646 BA_para_set |= 0x1000;
1647 break;
1648 case MAX_AMPDU_FACTOR_32K:
1649 BA_para_set |= 0x0800;
1650 break;
1651 case MAX_AMPDU_FACTOR_16K:
1652 BA_para_set |= 0x0400;
1653 break;
1654 case MAX_AMPDU_FACTOR_8K:
1655 BA_para_set |= 0x0200;
1656 break;
1657 default:
1658 BA_para_set |= 0x1000;
1659 break;
1660 }
1661
1662 if (pregpriv->ampdu_amsdu == 0)
1663 BA_para_set = BA_para_set & ~BIT(0);
1664 else if (pregpriv->ampdu_amsdu == 1)
1665 BA_para_set = BA_para_set | BIT(0);
1666 le_tmp = cpu_to_le16(BA_para_set);
1667
1668 pframe = rtw_set_fixed_ie(pframe, 2, &(le_tmp),
1669 &pattrib->pktlen);
1670 pframe = rtw_set_fixed_ie(pframe, 2,
1671 &ADDBA_req->BA_timeout_value,
1672 &pattrib->pktlen);
1673 break;
1674 }
1675 case 2:
1676 BA_para_set = (status & 0x1F) << 3;
1677 le_tmp = cpu_to_le16(BA_para_set);
1678 pframe = rtw_set_fixed_ie(pframe, 2, &(le_tmp),
1679 &pattrib->pktlen);
1680
1681 reason_code = 37;
1682 le_tmp = cpu_to_le16(reason_code);
1683 pframe = rtw_set_fixed_ie(pframe, 2, &(le_tmp),
1684 &pattrib->pktlen);
1685 break;
1686 default:
1687 break;
1688 }
1689 }
1690
1691 pattrib->last_txcmdsz = pattrib->pktlen;
1692
1693 dump_mgntframe(padapter, pmgntframe);
1694}
1695
1696static void issue_action_BSSCoexistPacket(struct adapter *padapter)
1697{
1698 struct list_head *plist, *phead;
1699 unsigned char category, action;
1700 struct xmit_frame *pmgntframe;
1701 struct pkt_attrib *pattrib;
1702 unsigned char *pframe;
1703 struct ieee80211_hdr *pwlanhdr;
1704 __le16 *fctrl;
1705 struct wlan_network *pnetwork = NULL;
1706 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
1707 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1708 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1709 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1710 struct __queue *queue = &(pmlmepriv->scanned_queue);
1711 u8 InfoContent[16] = {0};
1712 u8 ICS[8][15];
1713 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
1714
1715 if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0))
1716 return;
1717
1718 if (pmlmeinfo->bwmode_updated)
1719 return;
1720
1721 DBG_88E("%s\n", __func__);
1722
1723 category = RTW_WLAN_CATEGORY_PUBLIC;
1724 action = ACT_PUBLIC_BSSCOEXIST;
1725
1726 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1727 if (!pmgntframe)
1728 return;
1729
1730
1731 pattrib = &pmgntframe->attrib;
1732 update_mgntframe_attrib(padapter, pattrib);
1733
1734 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
1735
1736 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
1737 pwlanhdr = (struct ieee80211_hdr *)pframe;
1738
1739 fctrl = &pwlanhdr->frame_control;
1740 *(fctrl) = 0;
1741
1742 ether_addr_copy(pwlanhdr->addr1, cur_network->MacAddress);
1743 ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
1744 ether_addr_copy(pwlanhdr->addr3, cur_network->MacAddress);
1745
1746 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
1747 pmlmeext->mgnt_seq++;
1748 SetFrameSubType(pframe, WIFI_ACTION);
1749
1750 pframe += sizeof(struct ieee80211_hdr_3addr);
1751 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
1752
1753 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
1754 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
1755
1756
1757 if (pmlmepriv->num_FortyMHzIntolerant > 0) {
1758 u8 iedata = 0;
1759
1760 iedata |= BIT(2);
1761
1762 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
1763 }
1764
1765
1766 memset(ICS, 0, sizeof(ICS));
1767 if (pmlmepriv->num_sta_no_ht > 0) {
1768 int i;
1769
1770 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1771
1772 phead = get_list_head(queue);
1773 plist = phead->next;
1774
1775 while (phead != plist) {
1776 uint len;
1777 u8 *p;
1778 struct wlan_bssid_ex *pbss_network;
1779
1780 pnetwork = container_of(plist, struct wlan_network, list);
1781
1782 plist = plist->next;
1783
1784 pbss_network = (struct wlan_bssid_ex *)&pnetwork->network;
1785
1786 p = rtw_get_ie(pbss_network->ies + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->ie_length - _FIXED_IE_LENGTH_);
1787 if ((p == NULL) || (len == 0)) {
1788 if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14))
1789 continue;
1790
1791 ICS[0][pbss_network->Configuration.DSConfig] = 1;
1792
1793 if (ICS[0][0] == 0)
1794 ICS[0][0] = 1;
1795 }
1796 }
1797 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1798
1799 for (i = 0; i < 8; i++) {
1800 if (ICS[i][0] == 1) {
1801 int j, k = 0;
1802
1803 InfoContent[k] = i;
1804
1805 k++;
1806
1807 for (j = 1; j <= 14; j++) {
1808 if (ICS[i][j] == 1) {
1809 if (k < 16) {
1810 InfoContent[k] = j;
1811
1812 k++;
1813 }
1814 }
1815 }
1816
1817 pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
1818 }
1819 }
1820 }
1821
1822 pattrib->last_txcmdsz = pattrib->pktlen;
1823
1824 dump_mgntframe(padapter, pmgntframe);
1825}
1826
1827unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr)
1828{
1829 struct sta_priv *pstapriv = &padapter->stapriv;
1830 struct sta_info *psta = NULL;
1831
1832 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1833 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1834 u16 tid;
1835
1836 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1837 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
1838 return _SUCCESS;
1839
1840 psta = rtw_get_stainfo(pstapriv, addr);
1841 if (psta == NULL)
1842 return _SUCCESS;
1843
1844 if (initiator == 0) {
1845 for (tid = 0; tid < MAXTID; tid++) {
1846 if (psta->recvreorder_ctrl[tid].enable) {
1847 DBG_88E("rx agg disable tid(%d)\n", tid);
1848 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator)&0x1F));
1849 psta->recvreorder_ctrl[tid].enable = false;
1850 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
1851 }
1852 }
1853 } else if (initiator == 1) {
1854 for (tid = 0; tid < MAXTID; tid++) {
1855 if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
1856 DBG_88E("tx agg disable tid(%d)\n", tid);
1857 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator)&0x1F));
1858 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
1859 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
1860 }
1861 }
1862 }
1863
1864 return _SUCCESS;
1865}
1866
1867unsigned int send_beacon(struct adapter *padapter)
1868{
1869 u8 bxmitok = false;
1870 int issue = 0;
1871 int poll = 0;
1872
1873 unsigned long start = jiffies;
1874
1875 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
1876 do {
1877 issue_beacon(padapter, 100);
1878 issue++;
1879 do {
1880 yield();
1881 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
1882 poll++;
1883 } while ((poll%10) != 0 && !bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
1884 } while (!bxmitok && issue < 100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
1885
1886 if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
1887 return _FAIL;
1888 if (!bxmitok) {
1889 DBG_88E("%s fail! %u ms\n", __func__,
1890 jiffies_to_msecs(jiffies - start));
1891 return _FAIL;
1892 } else {
1893 u32 passing_time = jiffies_to_msecs(jiffies - start);
1894
1895 if (passing_time > 100 || issue > 3)
1896 DBG_88E("%s success, issue:%d, poll:%d, %u ms\n",
1897 __func__, issue, poll,
1898 jiffies_to_msecs(jiffies - start));
1899 return _SUCCESS;
1900 }
1901}
1902
1903
1904
1905
1906
1907
1908
1909static void site_survey(struct adapter *padapter)
1910{
1911 unsigned char survey_channel = 0, val8;
1912 enum rt_scan_type ScanType = SCAN_PASSIVE;
1913 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1914 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1915 u32 initialgain = 0;
1916 struct rtw_ieee80211_channel *ch;
1917
1918 if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
1919 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
1920 survey_channel = ch->hw_value;
1921 ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
1922 }
1923
1924 if (survey_channel != 0) {
1925
1926
1927
1928
1929 if (pmlmeext->sitesurvey_res.channel_idx == 0)
1930 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
1931 else
1932 SelectChannel(padapter, survey_channel);
1933
1934 if (ScanType == SCAN_ACTIVE) {
1935 int i;
1936
1937 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
1938 if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
1939
1940 issue_probereq(padapter,
1941 &(pmlmeext->sitesurvey_res.ssid[i]),
1942 NULL, false);
1943
1944 issue_probereq(padapter,
1945 &(pmlmeext->sitesurvey_res.ssid[i]),
1946 NULL, false);
1947 }
1948 }
1949
1950 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
1951
1952 issue_probereq(padapter, NULL, NULL, false);
1953
1954 issue_probereq(padapter, NULL, NULL, false);
1955 }
1956
1957 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
1958
1959 issue_probereq(padapter, NULL, NULL, false);
1960
1961 issue_probereq(padapter, NULL, NULL, false);
1962 }
1963 }
1964
1965 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
1966 } else {
1967
1968
1969
1970 if (rtw_hal_antdiv_before_linked(padapter)) {
1971 pmlmeext->sitesurvey_res.bss_cnt = 0;
1972 pmlmeext->sitesurvey_res.channel_idx = -1;
1973 pmlmeext->chan_scan_time = SURVEY_TO / 2;
1974 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
1975 return;
1976 }
1977
1978 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
1979
1980
1981
1982 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
1983
1984
1985
1986
1987
1988
1989 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
1990
1991 initialgain = 0xff;
1992 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
1993
1994 Restore_DM_Func_Flag(padapter);
1995
1996
1997 if (is_client_associated_to_ap(padapter))
1998 issue_nulldata(padapter, NULL, 0, 3, 500);
1999
2000 val8 = 0;
2001 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
2002
2003 report_surveydone_event(padapter);
2004
2005 pmlmeext->chan_scan_time = SURVEY_TO;
2006 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
2007
2008 issue_action_BSSCoexistPacket(padapter);
2009 issue_action_BSSCoexistPacket(padapter);
2010 issue_action_BSSCoexistPacket(padapter);
2011 }
2012}
2013
2014
2015static u8 collect_bss_info(struct adapter *padapter,
2016 struct recv_frame *precv_frame,
2017 struct wlan_bssid_ex *bssid)
2018{
2019 int i;
2020 u32 len;
2021 u8 *p;
2022 u16 val16, subtype;
2023 u8 *pframe = precv_frame->pkt->data;
2024 u32 packet_len = precv_frame->pkt->len;
2025 u8 ie_offset;
2026 struct registry_priv *pregistrypriv = &padapter->registrypriv;
2027 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2028 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2029
2030 len = packet_len - sizeof(struct ieee80211_hdr_3addr);
2031
2032 if (len > MAX_IE_SZ)
2033 return _FAIL;
2034
2035 memset(bssid, 0, sizeof(struct wlan_bssid_ex));
2036
2037 subtype = GetFrameSubType(pframe);
2038
2039 if (subtype == WIFI_BEACON) {
2040 bssid->Reserved[0] = 1;
2041 ie_offset = _BEACON_IE_OFFSET_;
2042 } else {
2043
2044 if (subtype == WIFI_PROBEREQ) {
2045 ie_offset = _PROBEREQ_IE_OFFSET_;
2046 bssid->Reserved[0] = 2;
2047 } else if (subtype == WIFI_PROBERSP) {
2048 ie_offset = _PROBERSP_IE_OFFSET_;
2049 bssid->Reserved[0] = 3;
2050 } else {
2051 bssid->Reserved[0] = 0;
2052 ie_offset = _FIXED_IE_LENGTH_;
2053 }
2054 }
2055
2056 bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len;
2057
2058
2059 bssid->ie_length = len;
2060 memcpy(bssid->ies, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->ie_length);
2061
2062
2063 bssid->Rssi = precv_frame->attrib.phy_info.recvpower;
2064 bssid->PhyInfo.SignalQuality = precv_frame->attrib.phy_info.SignalQuality;
2065 bssid->PhyInfo.SignalStrength = precv_frame->attrib.phy_info.SignalStrength;
2066 rtw_hal_get_def_var(padapter, HAL_DEF_CURRENT_ANTENNA, &bssid->PhyInfo.Optimum_antenna);
2067
2068
2069 p = rtw_get_ie(bssid->ies + ie_offset, _SSID_IE_, &len, bssid->ie_length - ie_offset);
2070 if (!p) {
2071 DBG_88E("marc: cannot find SSID for survey event\n");
2072 return _FAIL;
2073 }
2074
2075 if (len) {
2076 if (len > NDIS_802_11_LENGTH_SSID) {
2077 DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
2078 return _FAIL;
2079 }
2080 memcpy(bssid->Ssid.Ssid, (p + 2), len);
2081 bssid->Ssid.SsidLength = len;
2082 } else {
2083 bssid->Ssid.SsidLength = 0;
2084 }
2085
2086 memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
2087
2088
2089 i = 0;
2090 p = rtw_get_ie(bssid->ies + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->ie_length - ie_offset);
2091 if (p != NULL) {
2092 if (len > NDIS_802_11_LENGTH_RATES_EX) {
2093 DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
2094 return _FAIL;
2095 }
2096 memcpy(bssid->SupportedRates, (p + 2), len);
2097 i = len;
2098 }
2099
2100 p = rtw_get_ie(bssid->ies + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->ie_length - ie_offset);
2101 if (p) {
2102 if (len > (NDIS_802_11_LENGTH_RATES_EX-i)) {
2103 DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
2104 return _FAIL;
2105 }
2106 memcpy(bssid->SupportedRates + i, (p + 2), len);
2107 }
2108
2109
2110 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
2111
2112 if (bssid->ie_length < 12)
2113 return _FAIL;
2114
2115
2116 p = rtw_get_ie(bssid->ies + ie_offset, _DSSET_IE_, &len, bssid->ie_length - ie_offset);
2117
2118 bssid->Configuration.DSConfig = 0;
2119 bssid->Configuration.Length = 0;
2120
2121 if (p) {
2122 bssid->Configuration.DSConfig = *(p + 2);
2123 } else {
2124
2125 p = rtw_get_ie(bssid->ies + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->ie_length - ie_offset);
2126 if (p) {
2127 struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
2128
2129 bssid->Configuration.DSConfig = HT_info->primary_channel;
2130 } else {
2131 bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
2132 }
2133 }
2134
2135 if (subtype == WIFI_PROBEREQ) {
2136
2137 bssid->InfrastructureMode = Ndis802_11Infrastructure;
2138 ether_addr_copy(bssid->MacAddress, GetAddr2Ptr(pframe));
2139 bssid->Privacy = 1;
2140 return _SUCCESS;
2141 }
2142
2143 bssid->Configuration.BeaconPeriod =
2144 get_unaligned_le16(rtw_get_beacon_interval_from_ie(bssid->ies));
2145
2146 val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid);
2147
2148 if (val16 & BIT(0)) {
2149 bssid->InfrastructureMode = Ndis802_11Infrastructure;
2150 ether_addr_copy(bssid->MacAddress, GetAddr2Ptr(pframe));
2151 } else {
2152 bssid->InfrastructureMode = Ndis802_11IBSS;
2153 ether_addr_copy(bssid->MacAddress, GetAddr3Ptr(pframe));
2154 }
2155
2156 if (val16 & BIT(4))
2157 bssid->Privacy = 1;
2158 else
2159 bssid->Privacy = 0;
2160
2161 bssid->Configuration.ATIMWindow = 0;
2162
2163
2164 if ((pregistrypriv->wifi_spec == 1) && (!pmlmeinfo->bwmode_updated)) {
2165 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2166
2167 p = rtw_get_ie(bssid->ies + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->ie_length - ie_offset);
2168 if (p && len > 0) {
2169 struct ieee80211_ht_cap *pHT_caps =
2170 (struct ieee80211_ht_cap *)(p + 2);
2171
2172 if (le16_to_cpu(pHT_caps->cap_info) & BIT(14))
2173 pmlmepriv->num_FortyMHzIntolerant++;
2174 } else {
2175 pmlmepriv->num_sta_no_ht++;
2176 }
2177 }
2178
2179
2180 if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
2181 bssid->PhyInfo.SignalQuality = 101;
2182 return _SUCCESS;
2183}
2184
2185static void start_create_ibss(struct adapter *padapter)
2186{
2187 unsigned short caps;
2188 u8 val8;
2189 u8 join_type;
2190 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2191 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2192 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
2193
2194 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
2195 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
2196
2197
2198 update_wireless_mode(padapter);
2199
2200
2201 caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork);
2202 update_capinfo(padapter, caps);
2203 if (caps&cap_IBSS) {
2204 val8 = 0xcf;
2205 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
2206
2207
2208
2209 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
2210
2211 beacon_timing_control(padapter);
2212
2213
2214 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
2215 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
2216
2217
2218 if (send_beacon(padapter) == _FAIL) {
2219 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("issuing beacon frame fail....\n"));
2220
2221 report_join_res(padapter, -1);
2222 pmlmeinfo->state = WIFI_FW_NULL_STATE;
2223 } else {
2224 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
2225 join_type = 0;
2226 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
2227
2228 report_join_res(padapter, 1);
2229 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
2230 }
2231 } else {
2232 DBG_88E("%s, invalid cap:%x\n", __func__, caps);
2233 return;
2234 }
2235}
2236
2237static void start_clnt_join(struct adapter *padapter)
2238{
2239 unsigned short caps;
2240 u8 val8;
2241 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2242 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2243 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
2244 int beacon_timeout;
2245
2246 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
2247 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
2248
2249
2250 update_wireless_mode(padapter);
2251
2252
2253 caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork);
2254 update_capinfo(padapter, caps);
2255 if (caps&cap_ESS) {
2256 Set_MSR(padapter, WIFI_FW_STATION_STATE);
2257
2258 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf;
2259
2260 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
2261
2262
2263 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
2264
2265
2266
2267 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
2268 set_link_timer(pmlmeext, beacon_timeout);
2269 mod_timer(&padapter->mlmepriv.assoc_timer, jiffies +
2270 msecs_to_jiffies((REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO * REASSOC_LIMIT) + beacon_timeout));
2271
2272 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
2273 } else if (caps&cap_IBSS) {
2274 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
2275
2276 val8 = 0xcf;
2277 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
2278
2279
2280 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
2281
2282 beacon_timing_control(padapter);
2283
2284 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
2285
2286 report_join_res(padapter, 1);
2287 } else {
2288 return;
2289 }
2290}
2291
2292static void start_clnt_auth(struct adapter *padapter)
2293{
2294 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2295 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2296
2297 del_timer_sync(&pmlmeext->link_timer);
2298
2299 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
2300 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
2301
2302 pmlmeinfo->auth_seq = 1;
2303 pmlmeinfo->reauth_count = 0;
2304 pmlmeinfo->reassoc_count = 0;
2305 pmlmeinfo->link_count = 0;
2306 pmlmeext->retry = 0;
2307
2308
2309
2310
2311
2312
2313 issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
2314
2315 DBG_88E_LEVEL(_drv_info_, "start auth\n");
2316 issue_auth(padapter, NULL, 0);
2317
2318 set_link_timer(pmlmeext, REAUTH_TO);
2319}
2320
2321static void start_clnt_assoc(struct adapter *padapter)
2322{
2323 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2324 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2325
2326 del_timer_sync(&pmlmeext->link_timer);
2327
2328 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
2329 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
2330
2331 issue_assocreq(padapter);
2332
2333 set_link_timer(pmlmeext, REASSOC_TO);
2334}
2335
2336static unsigned int receive_disconnect(struct adapter *padapter,
2337 unsigned char *MacAddr,
2338 unsigned short reason)
2339{
2340 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2341 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2342 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
2343
2344
2345 if (memcmp(MacAddr, pnetwork->MacAddress, ETH_ALEN))
2346 return _SUCCESS;
2347
2348 DBG_88E("%s\n", __func__);
2349
2350 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
2351 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
2352 pmlmeinfo->state = WIFI_FW_NULL_STATE;
2353 report_del_sta_event(padapter, MacAddr, reason);
2354 } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) {
2355 pmlmeinfo->state = WIFI_FW_NULL_STATE;
2356 report_join_res(padapter, -2);
2357 }
2358 }
2359 return _SUCCESS;
2360}
2361
2362static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid)
2363{
2364 struct registry_priv *pregistrypriv;
2365 struct mlme_ext_priv *pmlmeext;
2366 struct rt_channel_info *chplan_new;
2367 u8 channel;
2368 u8 i;
2369
2370 pregistrypriv = &padapter->registrypriv;
2371 pmlmeext = &padapter->mlmeextpriv;
2372
2373
2374 if (pregistrypriv->enable80211d &&
2375 (!pmlmeext->update_channel_plan_by_ap_done)) {
2376 u8 *ie, *p;
2377 u32 len;
2378 struct rt_channel_plan chplan_ap;
2379 struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM];
2380 u8 country[4];
2381 u8 fcn;
2382 u8 noc;
2383 u8 j, k;
2384
2385 ie = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->ie_length - _FIXED_IE_LENGTH_);
2386 if (!ie)
2387 return;
2388 if (len < 6)
2389 return;
2390 ie += 2;
2391 p = ie;
2392 ie += len;
2393
2394 memset(country, 0, 4);
2395 memcpy(country, p, 3);
2396 p += 3;
2397 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2398 ("%s: 802.11d country =%s\n", __func__, country));
2399
2400 i = 0;
2401 while ((ie - p) >= 3) {
2402 fcn = *(p++);
2403 noc = *(p++);
2404 p++;
2405
2406 for (j = 0; j < noc; j++) {
2407 channel = fcn + j;
2408
2409 chplan_ap.Channel[i++] = channel;
2410 }
2411 }
2412 chplan_ap.Len = i;
2413
2414 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
2415
2416 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
2417 chplan_new = pmlmeext->channel_set;
2418
2419 i = 0;
2420 j = 0;
2421 k = 0;
2422 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
2423 do {
2424 if ((i == MAX_CHANNEL_NUM) ||
2425 (chplan_sta[i].ChannelNum == 0) ||
2426 (chplan_sta[i].ChannelNum > 14))
2427 break;
2428
2429 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
2430 break;
2431
2432 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
2433 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
2434 chplan_new[k].ScanType = SCAN_ACTIVE;
2435 i++;
2436 j++;
2437 k++;
2438 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
2439 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
2440 chplan_new[k].ScanType = SCAN_PASSIVE;
2441 i++;
2442 k++;
2443 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
2444 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
2445 chplan_new[k].ScanType = SCAN_ACTIVE;
2446 j++;
2447 k++;
2448 }
2449 } while (1);
2450
2451
2452 while ((i < MAX_CHANNEL_NUM) &&
2453 (chplan_sta[i].ChannelNum != 0) &&
2454 (chplan_sta[i].ChannelNum <= 14)) {
2455 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
2456 chplan_new[k].ScanType = SCAN_PASSIVE;
2457 i++;
2458 k++;
2459 }
2460
2461
2462 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
2463 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
2464 chplan_new[k].ScanType = SCAN_ACTIVE;
2465 j++;
2466 k++;
2467 }
2468 } else {
2469
2470 while ((i < MAX_CHANNEL_NUM) &&
2471 (chplan_sta[i].ChannelNum != 0) &&
2472 (chplan_sta[i].ChannelNum <= 14)) {
2473 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
2474 chplan_new[k].ScanType = chplan_sta[i].ScanType;
2475 i++;
2476 k++;
2477 }
2478
2479
2480 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
2481 j++;
2482 }
2483
2484 pmlmeext->update_channel_plan_by_ap_done = 1;
2485 }
2486
2487
2488 channel = bssid->Configuration.DSConfig;
2489 chplan_new = pmlmeext->channel_set;
2490 i = 0;
2491 while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) {
2492 if (chplan_new[i].ChannelNum == channel) {
2493 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
2494 chplan_new[i].ScanType = SCAN_ACTIVE;
2495 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2496 ("%s: change channel %d scan type from passive to active\n",
2497 __func__, channel));
2498 }
2499 break;
2500 }
2501 i++;
2502 }
2503}
2504
2505
2506
2507
2508
2509
2510
2511static unsigned int OnProbeReq(struct adapter *padapter,
2512 struct recv_frame *precv_frame)
2513{
2514 unsigned int ielen;
2515 unsigned char *p;
2516 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2517 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2518 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2519 struct wlan_bssid_ex *cur = &(pmlmeinfo->network);
2520 u8 *pframe = precv_frame->pkt->data;
2521 uint len = precv_frame->pkt->len;
2522
2523 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
2524 return _SUCCESS;
2525
2526 if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
2527 !check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE))
2528 return _SUCCESS;
2529
2530 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, &ielen,
2531 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
2532
2533
2534 if (p) {
2535 if ((ielen != 0 && memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength)) ||
2536 (ielen == 0 && pmlmeinfo->hidden_ssid_mode))
2537 return _SUCCESS;
2538
2539 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
2540 pmlmepriv->cur_network.join_res)
2541 issue_probersp(padapter, get_sa(pframe));
2542 }
2543 return _SUCCESS;
2544}
2545
2546static unsigned int OnProbeRsp(struct adapter *padapter,
2547 struct recv_frame *precv_frame)
2548{
2549 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2550
2551 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
2552 report_survey_event(padapter, precv_frame);
2553 return _SUCCESS;
2554 }
2555
2556 return _SUCCESS;
2557}
2558
2559static unsigned int OnBeacon(struct adapter *padapter,
2560 struct recv_frame *precv_frame)
2561{
2562 int cam_idx;
2563 struct sta_info *psta;
2564 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2565 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2566 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2567 struct sta_priv *pstapriv = &padapter->stapriv;
2568 u8 *pframe = precv_frame->pkt->data;
2569 uint len = precv_frame->pkt->len;
2570 struct wlan_bssid_ex *pbss;
2571 int ret = _SUCCESS;
2572 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
2573
2574 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
2575 report_survey_event(padapter, precv_frame);
2576 return _SUCCESS;
2577 }
2578
2579 if (!memcmp(GetAddr3Ptr(pframe), pnetwork->MacAddress, ETH_ALEN)) {
2580 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
2581
2582 pbss = (struct wlan_bssid_ex *)rtw_malloc(sizeof(struct wlan_bssid_ex));
2583 if (pbss) {
2584 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
2585 update_network(&(pmlmepriv->cur_network.network), pbss, padapter, true);
2586 rtw_get_bcn_info(&(pmlmepriv->cur_network));
2587 }
2588 kfree(pbss);
2589 }
2590
2591
2592 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct ieee80211_hdr_3addr), len-sizeof(struct ieee80211_hdr_3addr));
2593
2594
2595 update_TSF(pmlmeext, pframe, len);
2596
2597
2598 start_clnt_auth(padapter);
2599
2600 return _SUCCESS;
2601 }
2602
2603 if (((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
2604 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2605 if (psta != NULL) {
2606 ret = rtw_check_bcn_info(padapter, pframe, len);
2607 if (!ret) {
2608 DBG_88E_LEVEL(_drv_info_, "ap has changed, disconnect now\n ");
2609 receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 65535);
2610 return _SUCCESS;
2611 }
2612
2613
2614 if ((sta_rx_pkts(psta) & 0xf) == 0)
2615 update_beacon_info(padapter, pframe, len, psta);
2616 }
2617 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
2618 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2619 if (psta != NULL) {
2620
2621
2622 if ((sta_rx_pkts(psta) & 0xf) == 0)
2623 update_beacon_info(padapter, pframe, len, psta);
2624 } else {
2625
2626 cam_idx = allocate_fw_sta_entry(padapter);
2627 if (cam_idx == NUM_STA)
2628 goto _END_ONBEACON_;
2629
2630
2631 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) {
2632 pmlmeinfo->FW_sta_info[cam_idx].status = 0;
2633 goto _END_ONBEACON_;
2634 }
2635
2636
2637 update_TSF(pmlmeext, pframe, len);
2638
2639
2640 report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx);
2641 }
2642 }
2643 }
2644
2645_END_ONBEACON_:
2646
2647 return _SUCCESS;
2648}
2649
2650#ifdef CONFIG_88EU_AP_MODE
2651static unsigned int OnAuth(struct adapter *padapter,
2652 struct recv_frame *precv_frame)
2653{
2654 unsigned int auth_mode, ie_len;
2655 u16 seq;
2656 unsigned char *sa, *p;
2657 u16 algorithm;
2658 int status;
2659 static struct sta_info stat;
2660 struct sta_info *pstat = NULL;
2661 struct sta_priv *pstapriv = &padapter->stapriv;
2662 struct security_priv *psecuritypriv = &padapter->securitypriv;
2663 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2664 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2665 u8 *pframe = precv_frame->pkt->data;
2666 uint len = precv_frame->pkt->len;
2667
2668 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2669 return _FAIL;
2670
2671 DBG_88E("+%s\n", __func__);
2672
2673 sa = GetAddr2Ptr(pframe);
2674
2675 auth_mode = psecuritypriv->dot11AuthAlgrthm;
2676 seq = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + 2));
2677 algorithm = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN));
2678
2679 DBG_88E("auth alg=%x, seq=%X\n", algorithm, seq);
2680
2681 if (auth_mode == 2 && psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
2682 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
2683 auth_mode = 0;
2684
2685 if ((algorithm > 0 && auth_mode == 0) ||
2686 (algorithm == 0 && auth_mode == 1)) {
2687 DBG_88E("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
2688 algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
2689
2690 status = _STATS_NO_SUPP_ALG_;
2691
2692 goto auth_fail;
2693 }
2694
2695 if (!rtw_access_ctrl(padapter, sa)) {
2696 status = _STATS_UNABLE_HANDLE_STA_;
2697 goto auth_fail;
2698 }
2699
2700 pstat = rtw_get_stainfo(pstapriv, sa);
2701 if (!pstat) {
2702
2703 DBG_88E("going to alloc stainfo for sa=%pM\n", sa);
2704 pstat = rtw_alloc_stainfo(pstapriv, sa);
2705 if (!pstat) {
2706 DBG_88E(" Exceed the upper limit of supported clients...\n");
2707 status = _STATS_UNABLE_HANDLE_STA_;
2708 goto auth_fail;
2709 }
2710
2711 pstat->state = WIFI_FW_AUTH_NULL;
2712 pstat->auth_seq = 0;
2713 } else {
2714 spin_lock_bh(&pstapriv->asoc_list_lock);
2715 if (!list_empty(&pstat->asoc_list)) {
2716 list_del_init(&pstat->asoc_list);
2717 pstapriv->asoc_list_cnt--;
2718 }
2719 spin_unlock_bh(&pstapriv->asoc_list_lock);
2720
2721 if (seq == 1) {
2722
2723 }
2724 }
2725
2726 spin_lock_bh(&pstapriv->auth_list_lock);
2727 if (list_empty(&pstat->auth_list)) {
2728 list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
2729 pstapriv->auth_list_cnt++;
2730 }
2731 spin_unlock_bh(&pstapriv->auth_list_lock);
2732
2733 if (pstat->auth_seq == 0)
2734 pstat->expire_to = pstapriv->auth_to;
2735
2736 if ((pstat->auth_seq + 1) != seq) {
2737 DBG_88E("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2738 seq, pstat->auth_seq+1);
2739 status = _STATS_OUT_OF_AUTH_SEQ_;
2740 goto auth_fail;
2741 }
2742
2743 if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2)) {
2744 if (seq == 1) {
2745 pstat->state &= ~WIFI_FW_AUTH_NULL;
2746 pstat->state |= WIFI_FW_AUTH_SUCCESS;
2747 pstat->expire_to = pstapriv->assoc_to;
2748 pstat->authalg = algorithm;
2749 } else {
2750 DBG_88E("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2751 seq, pstat->auth_seq+1);
2752 status = _STATS_OUT_OF_AUTH_SEQ_;
2753 goto auth_fail;
2754 }
2755 } else {
2756 if (seq == 1) {
2757
2758
2759 pstat->state &= ~WIFI_FW_AUTH_NULL;
2760 pstat->state |= WIFI_FW_AUTH_STATE;
2761 pstat->authalg = algorithm;
2762 pstat->auth_seq = 2;
2763 } else if (seq == 3) {
2764
2765 DBG_88E("checking for challenging txt...\n");
2766
2767 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, &ie_len,
2768 len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
2769
2770 if ((p == NULL) || (ie_len <= 0)) {
2771 DBG_88E("auth rejected because challenge failure!(1)\n");
2772 status = _STATS_CHALLENGE_FAIL_;
2773 goto auth_fail;
2774 }
2775
2776 if (!memcmp((void *)(p + 2), pstat->chg_txt, 128)) {
2777 pstat->state &= (~WIFI_FW_AUTH_STATE);
2778 pstat->state |= WIFI_FW_AUTH_SUCCESS;
2779
2780 pstat->expire_to = pstapriv->assoc_to;
2781 } else {
2782 DBG_88E("auth rejected because challenge failure!\n");
2783 status = _STATS_CHALLENGE_FAIL_;
2784 goto auth_fail;
2785 }
2786 } else {
2787 DBG_88E("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2788 seq, pstat->auth_seq+1);
2789 status = _STATS_OUT_OF_AUTH_SEQ_;
2790 goto auth_fail;
2791 }
2792 }
2793
2794
2795 pstat->auth_seq = seq + 1;
2796
2797 issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
2798
2799 if (pstat->state & WIFI_FW_AUTH_SUCCESS)
2800 pstat->auth_seq = 0;
2801
2802 return _SUCCESS;
2803
2804auth_fail:
2805
2806 if (pstat)
2807 rtw_free_stainfo(padapter, pstat);
2808
2809 pstat = &stat;
2810 memset((char *)pstat, '\0', sizeof(stat));
2811 pstat->auth_seq = 2;
2812 memcpy(pstat->hwaddr, sa, 6);
2813
2814 issue_auth(padapter, pstat, (unsigned short)status);
2815
2816 return _FAIL;
2817}
2818#endif
2819
2820static unsigned int OnAuthClient(struct adapter *padapter,
2821 struct recv_frame *precv_frame)
2822{
2823 unsigned int seq, len, status, offset;
2824 unsigned char *p;
2825 unsigned int go2asoc = 0;
2826 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2827 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2828 u8 *pframe = precv_frame->pkt->data;
2829 uint pkt_len = precv_frame->pkt->len;
2830
2831 DBG_88E("%s\n", __func__);
2832
2833
2834 if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
2835 return _SUCCESS;
2836
2837 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
2838 return _SUCCESS;
2839
2840 offset = (GetPrivacy(pframe)) ? 4 : 0;
2841
2842 seq = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + offset + 2));
2843 status = le16_to_cpu(*(__le16 *)((size_t)pframe + WLAN_HDR_A3_LEN + offset + 4));
2844
2845 if (status != 0) {
2846 DBG_88E("clnt auth fail, status: %d\n", status);
2847 if (status == 13) {
2848 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2849 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
2850 else
2851 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
2852 }
2853
2854 set_link_timer(pmlmeext, 1);
2855 goto authclnt_fail;
2856 }
2857
2858 if (seq == 2) {
2859 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
2860
2861 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, &len,
2862 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
2863
2864 if (p == NULL)
2865 goto authclnt_fail;
2866
2867 memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
2868 pmlmeinfo->auth_seq = 3;
2869 issue_auth(padapter, NULL, 0);
2870 set_link_timer(pmlmeext, REAUTH_TO);
2871
2872 return _SUCCESS;
2873 } else {
2874
2875 go2asoc = 1;
2876 }
2877 } else if (seq == 4) {
2878 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2879 go2asoc = 1;
2880 else
2881 goto authclnt_fail;
2882 } else {
2883
2884 goto authclnt_fail;
2885 }
2886
2887 if (go2asoc) {
2888 DBG_88E_LEVEL(_drv_info_, "auth success, start assoc\n");
2889 start_clnt_assoc(padapter);
2890 return _SUCCESS;
2891 }
2892authclnt_fail:
2893 return _FAIL;
2894}
2895
2896static unsigned int OnAssocReq(struct adapter *padapter,
2897 struct recv_frame *precv_frame)
2898{
2899#ifdef CONFIG_88EU_AP_MODE
2900 u16 capab_info;
2901 struct rtw_ieee802_11_elems elems;
2902 struct sta_info *pstat;
2903 unsigned char reassoc, *p, *pos, *wpa_ie;
2904 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
2905 int i, wpa_ie_len, left;
2906 unsigned char supportRate[16];
2907 int supportRateNum;
2908 unsigned short status = _STATS_SUCCESSFUL_;
2909 unsigned short frame_type, ie_offset = 0;
2910 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2911 struct security_priv *psecuritypriv = &padapter->securitypriv;
2912 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2913 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2914 struct wlan_bssid_ex *cur = &(pmlmeinfo->network);
2915 struct sta_priv *pstapriv = &padapter->stapriv;
2916 u8 *pframe = precv_frame->pkt->data;
2917 uint ie_len, pkt_len = precv_frame->pkt->len;
2918
2919 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2920 return _FAIL;
2921
2922 frame_type = GetFrameSubType(pframe);
2923 if (frame_type == WIFI_ASSOCREQ) {
2924 reassoc = 0;
2925 ie_offset = _ASOCREQ_IE_OFFSET_;
2926 } else {
2927 reassoc = 1;
2928 ie_offset = _REASOCREQ_IE_OFFSET_;
2929 }
2930
2931 if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
2932 DBG_88E("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
2933 "\n", reassoc, (unsigned long)pkt_len);
2934 return _FAIL;
2935 }
2936
2937 pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2938 if (!pstat) {
2939 status = _RSON_CLS2_;
2940 goto asoc_class2_error;
2941 }
2942
2943 capab_info = get_unaligned_le16(pframe + WLAN_HDR_A3_LEN);
2944
2945 left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
2946 pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
2947
2948 DBG_88E("%s\n", __func__);
2949
2950
2951 if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) {
2952 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) {
2953 status = _RSON_CLS2_;
2954 goto asoc_class2_error;
2955 } else {
2956 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
2957 pstat->state |= WIFI_FW_ASSOC_STATE;
2958 }
2959 } else {
2960 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
2961 pstat->state |= WIFI_FW_ASSOC_STATE;
2962 }
2963 pstat->capability = capab_info;
2964
2965 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
2966 !elems.ssid) {
2967 DBG_88E("STA %pM sent invalid association request\n",
2968 pstat->hwaddr);
2969 status = _STATS_FAILURE_;
2970 goto OnAssocReqFail;
2971 }
2972
2973
2974
2975 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
2976 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2977
2978 if (!p || ie_len == 0) {
2979
2980 status = _STATS_FAILURE_;
2981 goto OnAssocReqFail;
2982 } else {
2983
2984 if (memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
2985 status = _STATS_FAILURE_;
2986
2987 if (ie_len != cur->Ssid.SsidLength)
2988 status = _STATS_FAILURE_;
2989 }
2990
2991 if (_STATS_SUCCESSFUL_ != status)
2992 goto OnAssocReqFail;
2993
2994
2995 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2996 if (p == NULL) {
2997 DBG_88E("Rx a sta assoc-req which supported rate is empty!\n");
2998
2999
3000
3001
3002 status = _STATS_FAILURE_;
3003 goto OnAssocReqFail;
3004 } else {
3005 memcpy(supportRate, p+2, ie_len);
3006 supportRateNum = ie_len;
3007
3008 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_, &ie_len,
3009 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
3010 if (p != NULL) {
3011 if (supportRateNum <= sizeof(supportRate)) {
3012 memcpy(supportRate+supportRateNum, p+2, ie_len);
3013 supportRateNum += ie_len;
3014 }
3015 }
3016 }
3017
3018
3019
3020
3021
3022 pstat->bssratelen = supportRateNum;
3023 memcpy(pstat->bssrateset, supportRate, supportRateNum);
3024 UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
3025
3026
3027 pstat->dot8021xalg = 0;
3028 pstat->wpa_psk = 0;
3029 pstat->wpa_group_cipher = 0;
3030 pstat->wpa2_group_cipher = 0;
3031 pstat->wpa_pairwise_cipher = 0;
3032 pstat->wpa2_pairwise_cipher = 0;
3033 memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
3034 if ((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
3035 int group_cipher = 0, pairwise_cipher = 0;
3036
3037 wpa_ie = elems.rsn_ie;
3038 wpa_ie_len = elems.rsn_ie_len;
3039
3040 if (rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
3041 pstat->dot8021xalg = 1;
3042 pstat->wpa_psk |= BIT(1);
3043
3044 pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
3045 pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
3046
3047 if (!pstat->wpa2_group_cipher)
3048 status = WLAN_STATUS_INVALID_GROUP_CIPHER;
3049
3050 if (!pstat->wpa2_pairwise_cipher)
3051 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER;
3052 } else {
3053 status = WLAN_STATUS_INVALID_IE;
3054 }
3055 } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
3056 int group_cipher = 0, pairwise_cipher = 0;
3057
3058 wpa_ie = elems.wpa_ie;
3059 wpa_ie_len = elems.wpa_ie_len;
3060
3061 if (rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
3062 pstat->dot8021xalg = 1;
3063 pstat->wpa_psk |= BIT(0);
3064
3065 pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
3066 pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
3067
3068 if (!pstat->wpa_group_cipher)
3069 status = WLAN_STATUS_INVALID_GROUP_CIPHER;
3070
3071 if (!pstat->wpa_pairwise_cipher)
3072 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER;
3073 } else {
3074 status = WLAN_STATUS_INVALID_IE;
3075 }
3076 } else {
3077 wpa_ie = NULL;
3078 wpa_ie_len = 0;
3079 }
3080
3081 if (_STATS_SUCCESSFUL_ != status)
3082 goto OnAssocReqFail;
3083
3084 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
3085 if (!wpa_ie) {
3086 if (elems.wps_ie) {
3087 DBG_88E("STA included WPS IE in "
3088 "(Re)Association Request - assume WPS is "
3089 "used\n");
3090 pstat->flags |= WLAN_STA_WPS;
3091
3092
3093
3094 } else {
3095 DBG_88E("STA did not include WPA/RSN IE "
3096 "in (Re)Association Request - possible WPS "
3097 "use\n");
3098 pstat->flags |= WLAN_STA_MAYBE_WPS;
3099 }
3100
3101
3102
3103 if ((psecuritypriv->wpa_psk > 0) && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS))) {
3104 if (pmlmepriv->wps_beacon_ie) {
3105 u8 selected_registrar = 0;
3106
3107 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR, &selected_registrar, NULL);
3108
3109 if (!selected_registrar) {
3110 DBG_88E("selected_registrar is false , or AP is not ready to do WPS\n");
3111
3112 status = _STATS_UNABLE_HANDLE_STA_;
3113
3114 goto OnAssocReqFail;
3115 }
3116 }
3117 }
3118 } else {
3119 int copy_len;
3120
3121 if (psecuritypriv->wpa_psk == 0) {
3122 DBG_88E("STA %pM: WPA/RSN IE in association "
3123 "request, but AP don't support WPA/RSN\n", pstat->hwaddr);
3124
3125 status = WLAN_STATUS_INVALID_IE;
3126
3127 goto OnAssocReqFail;
3128 }
3129
3130 if (elems.wps_ie) {
3131 DBG_88E("STA included WPS IE in "
3132 "(Re)Association Request - WPS is "
3133 "used\n");
3134 pstat->flags |= WLAN_STA_WPS;
3135 copy_len = 0;
3136 } else {
3137 copy_len = min_t(int, wpa_ie_len + 2, sizeof(pstat->wpa_ie));
3138 }
3139 if (copy_len > 0)
3140 memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
3141 }
3142
3143 pstat->flags &= ~WLAN_STA_WME;
3144 pstat->qos_option = 0;
3145 pstat->qos_info = 0;
3146 pstat->has_legacy_ac = true;
3147 pstat->uapsd_vo = 0;
3148 pstat->uapsd_vi = 0;
3149 pstat->uapsd_be = 0;
3150 pstat->uapsd_bk = 0;
3151 if (pmlmepriv->qospriv.qos_option) {
3152 p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
3153 for (;;) {
3154 p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
3155 if (p != NULL) {
3156 if (!memcmp(p+2, WMM_IE, 6)) {
3157 pstat->flags |= WLAN_STA_WME;
3158
3159 pstat->qos_option = 1;
3160 pstat->qos_info = *(p+8);
3161
3162 pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
3163
3164 if ((pstat->qos_info&0xf) != 0xf)
3165 pstat->has_legacy_ac = true;
3166 else
3167 pstat->has_legacy_ac = false;
3168
3169 if (pstat->qos_info&0xf) {
3170 if (pstat->qos_info&BIT(0))
3171 pstat->uapsd_vo = BIT(0)|BIT(1);
3172 else
3173 pstat->uapsd_vo = 0;
3174
3175 if (pstat->qos_info&BIT(1))
3176 pstat->uapsd_vi = BIT(0)|BIT(1);
3177 else
3178 pstat->uapsd_vi = 0;
3179
3180 if (pstat->qos_info&BIT(2))
3181 pstat->uapsd_bk = BIT(0)|BIT(1);
3182 else
3183 pstat->uapsd_bk = 0;
3184
3185 if (pstat->qos_info&BIT(3))
3186 pstat->uapsd_be = BIT(0)|BIT(1);
3187 else
3188 pstat->uapsd_be = 0;
3189 }
3190 break;
3191 }
3192 } else {
3193 break;
3194 }
3195 p = p + ie_len + 2;
3196 }
3197 }
3198
3199
3200 memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
3201 if (elems.ht_capabilities &&
3202 elems.ht_capabilities_len >= sizeof(struct ieee80211_ht_cap)) {
3203 pstat->flags |= WLAN_STA_HT;
3204
3205 pstat->flags |= WLAN_STA_WME;
3206
3207 memcpy(&pstat->htpriv.ht_cap,
3208 elems.ht_capabilities, sizeof(struct ieee80211_ht_cap));
3209 } else {
3210 pstat->flags &= ~WLAN_STA_HT;
3211 }
3212 if ((!pmlmepriv->htpriv.ht_option) && (pstat->flags&WLAN_STA_HT)) {
3213 status = _STATS_FAILURE_;
3214 goto OnAssocReqFail;
3215 }
3216
3217 if ((pstat->flags & WLAN_STA_HT) &&
3218 ((pstat->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
3219 (pstat->wpa_pairwise_cipher&WPA_CIPHER_TKIP))) {
3220 DBG_88E("HT: %pM tried to "
3221 "use TKIP with HT association\n", pstat->hwaddr);
3222
3223
3224
3225 }
3226
3227 pstat->flags |= WLAN_STA_NONERP;
3228 for (i = 0; i < pstat->bssratelen; i++) {
3229 if ((pstat->bssrateset[i] & 0x7f) > 22) {
3230 pstat->flags &= ~WLAN_STA_NONERP;
3231 break;
3232 }
3233 }
3234
3235 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
3236 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
3237 else
3238 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
3239
3240 if (status != _STATS_SUCCESSFUL_)
3241 goto OnAssocReqFail;
3242
3243
3244
3245
3246
3247
3248
3249
3250 if (pstat->aid > 0) {
3251 DBG_88E(" old AID %d\n", pstat->aid);
3252 } else {
3253 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
3254 if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
3255 break;
3256
3257
3258 if (pstat->aid > pstapriv->max_num_sta) {
3259 pstat->aid = 0;
3260
3261 DBG_88E(" no room for more AIDs\n");
3262
3263 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
3264
3265 goto OnAssocReqFail;
3266 } else {
3267 pstapriv->sta_aid[pstat->aid - 1] = pstat;
3268 DBG_88E("allocate new AID=(%d)\n", pstat->aid);
3269 }
3270 }
3271
3272 pstat->state &= (~WIFI_FW_ASSOC_STATE);
3273 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
3274
3275 spin_lock_bh(&pstapriv->auth_list_lock);
3276 if (!list_empty(&pstat->auth_list)) {
3277 list_del_init(&pstat->auth_list);
3278 pstapriv->auth_list_cnt--;
3279 }
3280 spin_unlock_bh(&pstapriv->auth_list_lock);
3281
3282 spin_lock_bh(&pstapriv->asoc_list_lock);
3283 if (list_empty(&pstat->asoc_list)) {
3284 pstat->expire_to = pstapriv->expire_to;
3285 list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
3286 pstapriv->asoc_list_cnt++;
3287 }
3288 spin_unlock_bh(&pstapriv->asoc_list_lock);
3289
3290
3291 if ((pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_ == status)) {
3292
3293 bss_cap_update_on_sta_join(padapter, pstat);
3294 sta_info_update(padapter, pstat);
3295
3296
3297 if (frame_type == WIFI_ASSOCREQ)
3298 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
3299 else
3300 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
3301
3302
3303 DBG_88E("indicate_sta_join_event to upper layer - hostapd\n");
3304 rtw_indicate_sta_assoc_event(padapter, pstat);
3305
3306
3307 report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
3308 }
3309
3310 return _SUCCESS;
3311
3312asoc_class2_error:
3313
3314 issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
3315
3316 return _FAIL;
3317
3318OnAssocReqFail:
3319
3320 pstat->aid = 0;
3321 if (frame_type == WIFI_ASSOCREQ)
3322 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
3323 else
3324 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
3325
3326#endif
3327
3328 return _FAIL;
3329}
3330
3331static unsigned int OnAssocRsp(struct adapter *padapter,
3332 struct recv_frame *precv_frame)
3333{
3334 uint i;
3335 int res;
3336 unsigned short status;
3337 struct ndis_802_11_var_ie *pIE;
3338 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3339 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3340 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3341
3342 u8 *pframe = precv_frame->pkt->data;
3343 uint pkt_len = precv_frame->pkt->len;
3344
3345 DBG_88E("%s\n", __func__);
3346
3347
3348 if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
3349 return _SUCCESS;
3350
3351 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
3352 return _SUCCESS;
3353
3354 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
3355 return _SUCCESS;
3356
3357 del_timer_sync(&pmlmeext->link_timer);
3358
3359
3360 status = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 2));
3361 if (status > 0) {
3362 DBG_88E("assoc reject, status code: %d\n", status);
3363 pmlmeinfo->state = WIFI_FW_NULL_STATE;
3364 res = -4;
3365 goto report_assoc_result;
3366 }
3367
3368
3369 pmlmeinfo->capability = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
3370
3371
3372 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20;
3373
3374
3375 pmlmeinfo->aid = (int)(le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
3376 res = pmlmeinfo->aid;
3377
3378
3379
3380
3381 for (i = 6 + WLAN_HDR_A3_LEN; i < pkt_len;) {
3382 pIE = (struct ndis_802_11_var_ie *)(pframe + i);
3383
3384 switch (pIE->ElementID) {
3385 case _VENDOR_SPECIFIC_IE_:
3386 if (!memcmp(pIE->data, WMM_PARA_OUI, 6))
3387 WMM_param_handler(padapter, pIE);
3388 break;
3389 case _HT_CAPABILITY_IE_:
3390 HT_caps_handler(padapter, pIE);
3391 break;
3392 case _HT_EXTRA_INFO_IE_:
3393 HT_info_handler(padapter, pIE);
3394 break;
3395 case _ERPINFO_IE_:
3396 ERP_IE_handler(padapter, pIE);
3397 default:
3398 break;
3399 }
3400
3401 i += (pIE->Length + 2);
3402 }
3403
3404 pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
3405 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
3406
3407 UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
3408
3409report_assoc_result:
3410 if (res > 0)
3411 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
3412 else
3413 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
3414
3415 report_join_res(padapter, res);
3416
3417 return _SUCCESS;
3418}
3419
3420static unsigned int OnDeAuth(struct adapter *padapter,
3421 struct recv_frame *precv_frame)
3422{
3423 unsigned short reason;
3424 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3425 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3426 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3427 u8 *pframe = precv_frame->pkt->data;
3428 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
3429
3430
3431 if (memcmp(GetAddr3Ptr(pframe), pnetwork->MacAddress, ETH_ALEN))
3432 return _SUCCESS;
3433
3434 reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
3435
3436 DBG_88E("%s Reason code(%d)\n", __func__, reason);
3437
3438#ifdef CONFIG_88EU_AP_MODE
3439 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
3440 struct sta_info *psta;
3441 struct sta_priv *pstapriv = &padapter->stapriv;
3442
3443 DBG_88E_LEVEL(_drv_always_, "ap recv deauth reason code(%d) sta:%pM\n",
3444 reason, GetAddr2Ptr(pframe));
3445
3446 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3447 if (psta) {
3448 u8 updated = 0;
3449
3450 spin_lock_bh(&pstapriv->asoc_list_lock);
3451 if (!list_empty(&psta->asoc_list)) {
3452 list_del_init(&psta->asoc_list);
3453 pstapriv->asoc_list_cnt--;
3454 updated = ap_free_sta(padapter, psta, false, reason);
3455 }
3456 spin_unlock_bh(&pstapriv->asoc_list_lock);
3457
3458 associated_clients_update(padapter, updated);
3459 }
3460
3461 return _SUCCESS;
3462 } else
3463#endif
3464 {
3465 DBG_88E_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM\n",
3466 reason, GetAddr3Ptr(pframe));
3467
3468 receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
3469 }
3470 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
3471 return _SUCCESS;
3472}
3473
3474static unsigned int OnDisassoc(struct adapter *padapter,
3475 struct recv_frame *precv_frame)
3476{
3477 u16 reason;
3478 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3479 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3480 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3481 u8 *pframe = precv_frame->pkt->data;
3482 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
3483
3484
3485 if (memcmp(GetAddr3Ptr(pframe), pnetwork->MacAddress, ETH_ALEN))
3486 return _SUCCESS;
3487
3488 reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
3489
3490 DBG_88E("%s Reason code(%d)\n", __func__, reason);
3491
3492#ifdef CONFIG_88EU_AP_MODE
3493 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
3494 struct sta_info *psta;
3495 struct sta_priv *pstapriv = &padapter->stapriv;
3496
3497 DBG_88E_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
3498 reason, GetAddr2Ptr(pframe));
3499
3500 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3501 if (psta) {
3502 u8 updated = 0;
3503
3504 spin_lock_bh(&pstapriv->asoc_list_lock);
3505 if (!list_empty(&psta->asoc_list)) {
3506 list_del_init(&psta->asoc_list);
3507 pstapriv->asoc_list_cnt--;
3508 updated = ap_free_sta(padapter, psta, false, reason);
3509 }
3510 spin_unlock_bh(&pstapriv->asoc_list_lock);
3511
3512 associated_clients_update(padapter, updated);
3513 }
3514
3515 return _SUCCESS;
3516 } else
3517#endif
3518 {
3519 DBG_88E_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
3520 reason, GetAddr3Ptr(pframe));
3521
3522 receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
3523 }
3524 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
3525 return _SUCCESS;
3526}
3527
3528static unsigned int OnAtim(struct adapter *padapter,
3529 struct recv_frame *precv_frame)
3530{
3531 DBG_88E("%s\n", __func__);
3532 return _SUCCESS;
3533}
3534
3535static unsigned int on_action_spct(struct adapter *padapter,
3536 struct recv_frame *precv_frame)
3537{
3538 struct sta_info *psta = NULL;
3539 struct sta_priv *pstapriv = &padapter->stapriv;
3540 u8 *pframe = precv_frame->pkt->data;
3541 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
3542 u8 category;
3543 u8 action;
3544
3545 DBG_88E(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
3546
3547 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
3548
3549 if (!psta)
3550 goto exit;
3551
3552 category = frame_body[0];
3553 if (category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
3554 goto exit;
3555
3556 action = frame_body[1];
3557 switch (action) {
3558 case RTW_WLAN_ACTION_SPCT_MSR_REQ:
3559 case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
3560 case RTW_WLAN_ACTION_SPCT_TPC_REQ:
3561 case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
3562 break;
3563 case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
3564 break;
3565 default:
3566 break;
3567 }
3568
3569exit:
3570 return _FAIL;
3571}
3572
3573static unsigned int OnAction_qos(struct adapter *padapter,
3574 struct recv_frame *precv_frame)
3575{
3576 return _SUCCESS;
3577}
3578
3579static unsigned int OnAction_dls(struct adapter *padapter,
3580 struct recv_frame *precv_frame)
3581{
3582 return _SUCCESS;
3583}
3584
3585static unsigned int OnAction_back(struct adapter *padapter,
3586 struct recv_frame *precv_frame)
3587{
3588 u8 *addr;
3589 struct sta_info *psta = NULL;
3590 struct recv_reorder_ctrl *preorder_ctrl;
3591 unsigned char *frame_body;
3592 unsigned char category, action;
3593 unsigned short tid, status, reason_code = 0;
3594 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3595 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3596 u8 *pframe = precv_frame->pkt->data;
3597 struct sta_priv *pstapriv = &padapter->stapriv;
3598
3599 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe),
3600 ETH_ALEN))
3601 return _SUCCESS;
3602
3603 DBG_88E("%s\n", __func__);
3604
3605 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
3606 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
3607 return _SUCCESS;
3608
3609 addr = GetAddr2Ptr(pframe);
3610 psta = rtw_get_stainfo(pstapriv, addr);
3611
3612 if (!psta)
3613 return _SUCCESS;
3614
3615 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
3616
3617 category = frame_body[0];
3618 if (category == RTW_WLAN_CATEGORY_BACK) {
3619 if (!pmlmeinfo->HT_enable)
3620 return _SUCCESS;
3621 action = frame_body[1];
3622 DBG_88E("%s, action=%d\n", __func__, action);
3623 switch (action) {
3624 case RTW_WLAN_ACTION_ADDBA_REQ:
3625 memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
3626 process_addba_req(padapter, (u8 *)&(pmlmeinfo->ADDBA_req), addr);
3627
3628
3629 issue_action_BA(padapter, addr,
3630 RTW_WLAN_ACTION_ADDBA_RESP,
3631 pmlmeinfo->accept_addba_req ? 0 : 37);
3632 break;
3633 case RTW_WLAN_ACTION_ADDBA_RESP:
3634 status = get_unaligned_le16(&frame_body[3]);
3635 tid = (frame_body[5] >> 2) & 0x7;
3636 if (status == 0) {
3637 DBG_88E("agg_enable for TID=%d\n", tid);
3638 psta->htpriv.agg_enable_bitmap |= 1 << tid;
3639 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
3640 } else {
3641 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3642 }
3643 break;
3644 case RTW_WLAN_ACTION_DELBA:
3645 if ((frame_body[3] & BIT(3)) == 0) {
3646 psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3647 psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3648 reason_code = get_unaligned_le16(&frame_body[4]);
3649 } else if ((frame_body[3] & BIT(3)) == BIT(3)) {
3650 tid = (frame_body[3] >> 4) & 0x0F;
3651 preorder_ctrl = &psta->recvreorder_ctrl[tid];
3652 preorder_ctrl->enable = false;
3653 preorder_ctrl->indicate_seq = 0xffff;
3654 }
3655 DBG_88E("%s(): DELBA: %x(%x)\n", __func__, pmlmeinfo->agg_enable_bitmap, reason_code);
3656
3657 break;
3658 default:
3659 break;
3660 }
3661 }
3662 return _SUCCESS;
3663}
3664
3665static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token)
3666{
3667 struct adapter *adapter = recv_frame->adapter;
3668 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
3669 u8 *frame = recv_frame->pkt->data;
3670 u16 seq_ctrl = ((recv_frame->attrib.seq_num&0xffff) << 4) |
3671 (recv_frame->attrib.frag_num & 0xf);
3672
3673 if (GetRetry(frame)) {
3674 if (token >= 0) {
3675 if ((seq_ctrl == mlmeext->action_public_rxseq) && (token == mlmeext->action_public_dialog_token)) {
3676 DBG_88E(FUNC_ADPT_FMT" seq_ctrl = 0x%x, rxseq = 0x%x, token:%d\n",
3677 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
3678 return _FAIL;
3679 }
3680 } else {
3681 if (seq_ctrl == mlmeext->action_public_rxseq) {
3682 DBG_88E(FUNC_ADPT_FMT" seq_ctrl = 0x%x, rxseq = 0x%x\n",
3683 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq);
3684 return _FAIL;
3685 }
3686 }
3687 }
3688
3689 mlmeext->action_public_rxseq = seq_ctrl;
3690
3691 if (token >= 0)
3692 mlmeext->action_public_dialog_token = token;
3693
3694 return _SUCCESS;
3695}
3696
3697static unsigned int on_action_public_p2p(struct recv_frame *precv_frame)
3698{
3699 u8 *pframe = precv_frame->pkt->data;
3700 u8 *frame_body;
3701 u8 dialogToken = 0;
3702
3703 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
3704 dialogToken = frame_body[7];
3705
3706 if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
3707 return _FAIL;
3708
3709 return _SUCCESS;
3710}
3711
3712static unsigned int on_action_public_vendor(struct recv_frame *precv_frame)
3713{
3714 unsigned int ret = _FAIL;
3715 u8 *pframe = precv_frame->pkt->data;
3716 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
3717
3718 if (!memcmp(frame_body + 2, P2P_OUI, 4))
3719 ret = on_action_public_p2p(precv_frame);
3720
3721 return ret;
3722}
3723
3724static unsigned int on_action_public_default(struct recv_frame *precv_frame,
3725 u8 action)
3726{
3727 unsigned int ret = _FAIL;
3728 u8 *pframe = precv_frame->pkt->data;
3729 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
3730 u8 token;
3731
3732 token = frame_body[2];
3733
3734 if (rtw_action_public_decache(precv_frame, token) == _FAIL)
3735 goto exit;
3736
3737 ret = _SUCCESS;
3738
3739exit:
3740 return ret;
3741}
3742
3743static unsigned int on_action_public(struct adapter *padapter,
3744 struct recv_frame *precv_frame)
3745{
3746 unsigned int ret = _FAIL;
3747 u8 *pframe = precv_frame->pkt->data;
3748 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
3749 u8 category, action;
3750
3751
3752 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))
3753 goto exit;
3754
3755 category = frame_body[0];
3756 if (category != RTW_WLAN_CATEGORY_PUBLIC)
3757 goto exit;
3758
3759 action = frame_body[1];
3760 switch (action) {
3761 case ACT_PUBLIC_VENDOR:
3762 ret = on_action_public_vendor(precv_frame);
3763 break;
3764 default:
3765 ret = on_action_public_default(precv_frame, action);
3766 break;
3767 }
3768
3769exit:
3770 return ret;
3771}
3772
3773static unsigned int OnAction_ht(struct adapter *padapter,
3774 struct recv_frame *precv_frame)
3775{
3776 return _SUCCESS;
3777}
3778
3779static unsigned int OnAction_wmm(struct adapter *padapter,
3780 struct recv_frame *precv_frame)
3781{
3782 return _SUCCESS;
3783}
3784
3785static unsigned int OnAction_p2p(struct adapter *padapter,
3786 struct recv_frame *precv_frame)
3787{
3788 return _SUCCESS;
3789}
3790
3791static unsigned int DoReserved(struct adapter *padapter,
3792 struct recv_frame *precv_frame)
3793{
3794 return _SUCCESS;
3795}
3796
3797static struct action_handler OnAction_tbl[] = {
3798 {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct},
3799 {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos},
3800 {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls},
3801 {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
3802 {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
3803 {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved},
3804 {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved},
3805 {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht},
3806 {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved},
3807 {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
3808 {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},
3809};
3810
3811static unsigned int OnAction(struct adapter *padapter,
3812 struct recv_frame *precv_frame)
3813{
3814 int i;
3815 unsigned char category;
3816 struct action_handler *ptable;
3817 unsigned char *frame_body;
3818 u8 *pframe = precv_frame->pkt->data;
3819
3820 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
3821
3822 category = frame_body[0];
3823
3824 for (i = 0; i < ARRAY_SIZE(OnAction_tbl); i++) {
3825 ptable = &OnAction_tbl[i];
3826 if (category == ptable->num)
3827 ptable->func(padapter, precv_frame);
3828 }
3829 return _SUCCESS;
3830}
3831
3832
3833
3834
3835
3836
3837
3838static struct mlme_handler mlme_sta_tbl[] = {
3839 {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
3840 {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
3841 {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
3842 {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
3843 {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
3844 {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
3845 {0, "DoReserved", &DoReserved},
3846 {0, "DoReserved", &DoReserved},
3847 {WIFI_BEACON, "OnBeacon", &OnBeacon},
3848 {WIFI_ATIM, "OnATIM", &OnAtim},
3849 {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
3850 {WIFI_AUTH, "OnAuth", &OnAuthClient},
3851 {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
3852 {WIFI_ACTION, "OnAction", &OnAction},
3853};
3854
3855int init_hw_mlme_ext(struct adapter *padapter)
3856{
3857 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3858
3859 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
3860 return _SUCCESS;
3861}
3862
3863static void init_mlme_ext_priv_value(struct adapter *padapter)
3864{
3865 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3866 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3867 unsigned char mixed_datarate[NumRates] = {
3868 _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
3869 _9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_,
3870 _48M_RATE_, _54M_RATE_, 0xff
3871 };
3872 unsigned char mixed_basicrate[NumRates] = {
3873 _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
3874 _12M_RATE_, _24M_RATE_, 0xff,
3875 };
3876
3877 atomic_set(&pmlmeext->event_seq, 0);
3878 pmlmeext->mgnt_seq = 0;
3879
3880 pmlmeext->cur_channel = padapter->registrypriv.channel;
3881 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
3882 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
3883 pmlmeext->oper_channel = pmlmeext->cur_channel;
3884 pmlmeext->oper_bwmode = pmlmeext->cur_bwmode;
3885 pmlmeext->oper_ch_offset = pmlmeext->cur_ch_offset;
3886 pmlmeext->retry = 0;
3887
3888 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
3889
3890 memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
3891 memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
3892
3893 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
3894
3895 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
3896 pmlmeext->sitesurvey_res.channel_idx = 0;
3897 pmlmeext->sitesurvey_res.bss_cnt = 0;
3898 pmlmeext->scan_abort = false;
3899
3900 pmlmeinfo->state = WIFI_FW_NULL_STATE;
3901 pmlmeinfo->reauth_count = 0;
3902 pmlmeinfo->reassoc_count = 0;
3903 pmlmeinfo->link_count = 0;
3904 pmlmeinfo->auth_seq = 0;
3905 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
3906 pmlmeinfo->key_index = 0;
3907 pmlmeinfo->iv = 0;
3908
3909 pmlmeinfo->enc_algo = _NO_PRIVACY_;
3910 pmlmeinfo->authModeToggle = 0;
3911
3912 memset(pmlmeinfo->chg_txt, 0, 128);
3913
3914 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
3915 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
3916
3917 pmlmeinfo->dialogToken = 0;
3918
3919 pmlmeext->action_public_rxseq = 0xffff;
3920 pmlmeext->action_public_dialog_token = 0xff;
3921}
3922
3923static int has_channel(struct rt_channel_info *channel_set,
3924 u8 chanset_size,
3925 u8 chan)
3926{
3927 int i;
3928
3929 for (i = 0; i < chanset_size; i++) {
3930 if (channel_set[i].ChannelNum == chan)
3931 return 1;
3932 }
3933 return 0;
3934}
3935
3936static void init_channel_list(struct adapter *padapter,
3937 struct rt_channel_info *channel_set,
3938 u8 chanset_size,
3939 struct p2p_channels *channel_list)
3940{
3941 struct p2p_oper_class_map op_class[] = {
3942 { IEEE80211G, 81, 1, 13, 1, BW20 },
3943 { IEEE80211G, 82, 14, 14, 1, BW20 },
3944 { -1, 0, 0, 0, 0, BW20 }
3945 };
3946
3947 int cla, op;
3948
3949 cla = 0;
3950
3951 for (op = 0; op_class[op].op_class; op++) {
3952 u8 ch;
3953 struct p2p_oper_class_map *o = &op_class[op];
3954 struct p2p_reg_class *reg = NULL;
3955
3956 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
3957 if (!has_channel(channel_set, chanset_size, ch))
3958 continue;
3959
3960 if (!padapter->registrypriv.ht_enable && o->inc == 8)
3961 continue;
3962
3963 if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) &&
3964 ((o->bw == BW40MINUS) || (o->bw == BW40PLUS)))
3965 continue;
3966
3967 if (reg == NULL) {
3968 reg = &channel_list->reg_class[cla];
3969 cla++;
3970 reg->reg_class = o->op_class;
3971 reg->channels = 0;
3972 }
3973 reg->channel[reg->channels] = ch;
3974 reg->channels++;
3975 }
3976 }
3977 channel_list->reg_classes = cla;
3978}
3979
3980static u8 init_channel_set(struct adapter *padapter, u8 ChannelPlan,
3981 struct rt_channel_info *channel_set)
3982{
3983 u8 index, chanset_size = 0;
3984 u8 b2_4GBand = false;
3985 u8 Index2G = 0;
3986
3987 memset(channel_set, 0, sizeof(struct rt_channel_info) * MAX_CHANNEL_NUM);
3988
3989 if (ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) {
3990 DBG_88E("ChannelPlan ID %x error !!!!!\n", ChannelPlan);
3991 return chanset_size;
3992 }
3993
3994 if (padapter->registrypriv.wireless_mode & WIRELESS_11G) {
3995 b2_4GBand = true;
3996 if (ChannelPlan == RT_CHANNEL_DOMAIN_REALTEK_DEFINE)
3997 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
3998 else
3999 Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
4000 }
4001
4002 if (b2_4GBand) {
4003 for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) {
4004 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
4005
4006 if ((ChannelPlan == RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN) ||
4007 (ChannelPlan == RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G)) {
4008 if (channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
4009 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
4010 else if ((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14))
4011 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
4012 } else if (ChannelPlan == RT_CHANNEL_DOMAIN_WORLD_WIDE_13 ||
4013 Index2G == RT_CHANNEL_DOMAIN_2G_WORLD) {
4014 if (channel_set[chanset_size].ChannelNum <= 11)
4015 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
4016 else
4017 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
4018 } else {
4019 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
4020 }
4021
4022 chanset_size++;
4023 }
4024 }
4025 return chanset_size;
4026}
4027
4028int init_mlme_ext_priv(struct adapter *padapter)
4029{
4030 struct registry_priv *pregistrypriv = &padapter->registrypriv;
4031 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4032 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4033 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4034
4035 pmlmeext->padapter = padapter;
4036
4037 init_mlme_ext_priv_value(padapter);
4038 pmlmeinfo->accept_addba_req = pregistrypriv->accept_addba_req;
4039
4040 init_mlme_ext_timer(padapter);
4041
4042#ifdef CONFIG_88EU_AP_MODE
4043 init_mlme_ap_info(padapter);
4044#endif
4045
4046 pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan, pmlmeext->channel_set);
4047 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
4048
4049 pmlmeext->chan_scan_time = SURVEY_TO;
4050 pmlmeext->mlmeext_init = true;
4051
4052 pmlmeext->active_keep_alive_check = true;
4053
4054 return _SUCCESS;
4055}
4056
4057void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext)
4058{
4059 struct adapter *padapter = pmlmeext->padapter;
4060
4061 if (!padapter)
4062 return;
4063
4064 if (padapter->bDriverStopped) {
4065 del_timer_sync(&pmlmeext->survey_timer);
4066 del_timer_sync(&pmlmeext->link_timer);
4067 }
4068}
4069
4070static void _mgt_dispatcher(struct adapter *padapter,
4071 struct mlme_handler *ptable,
4072 struct recv_frame *precv_frame)
4073{
4074 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4075 u8 *pframe = precv_frame->pkt->data;
4076
4077 if (ptable->func) {
4078
4079 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) &&
4080 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
4081 return;
4082 ptable->func(padapter, precv_frame);
4083 }
4084}
4085
4086void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame)
4087{
4088 int index;
4089 struct mlme_handler *ptable;
4090#ifdef CONFIG_88EU_AP_MODE
4091 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4092#endif
4093 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4094 u8 *pframe = precv_frame->pkt->data;
4095 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
4096
4097 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
4098 ("+%s: type(0x%x) subtype(0x%x)\n", __func__,
4099 (unsigned int)GetFrameType(pframe),
4100 (unsigned int)GetFrameSubType(pframe)));
4101
4102 if (GetFrameType(pframe) != WIFI_MGT_TYPE) {
4103 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
4104 ("%s: type(0x%x) error!\n", __func__,
4105 (unsigned int)GetFrameType(pframe)));
4106 return;
4107 }
4108
4109
4110 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) &&
4111 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
4112 return;
4113
4114 ptable = mlme_sta_tbl;
4115
4116 index = GetFrameSubType(pframe) >> 4;
4117
4118 if (index > 13) {
4119 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("Currently we do not support reserved sub-fr-type=%d\n", index));
4120 return;
4121 }
4122 ptable += index;
4123
4124 if (psta) {
4125 if (GetRetry(pframe)) {
4126 if (precv_frame->attrib.seq_num ==
4127 psta->RxMgmtFrameSeqNum) {
4128
4129 DBG_88E("Drop duplicate management frame with seq_num=%d.\n",
4130 precv_frame->attrib.seq_num);
4131 return;
4132 }
4133 }
4134 psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num;
4135 }
4136
4137#ifdef CONFIG_88EU_AP_MODE
4138 switch (GetFrameSubType(pframe)) {
4139 case WIFI_AUTH:
4140 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
4141 ptable->func = &OnAuth;
4142 else
4143 ptable->func = &OnAuthClient;
4144
4145 case WIFI_ASSOCREQ:
4146 case WIFI_REASSOCREQ:
4147 case WIFI_PROBEREQ:
4148 case WIFI_BEACON:
4149 case WIFI_ACTION:
4150 _mgt_dispatcher(padapter, ptable, precv_frame);
4151 break;
4152 default:
4153 _mgt_dispatcher(padapter, ptable, precv_frame);
4154 break;
4155 }
4156#else
4157 _mgt_dispatcher(padapter, ptable, precv_frame);
4158#endif
4159}
4160
4161
4162
4163
4164
4165
4166
4167void report_survey_event(struct adapter *padapter,
4168 struct recv_frame *precv_frame)
4169{
4170 struct cmd_obj *pcmd_obj;
4171 u8 *pevtcmd;
4172 u32 cmdsz;
4173 struct survey_event *psurvey_evt;
4174 struct C2HEvent_Header *pc2h_evt_hdr;
4175 struct mlme_ext_priv *pmlmeext;
4176 struct cmd_priv *pcmdpriv;
4177
4178 if (!padapter)
4179 return;
4180
4181 pmlmeext = &padapter->mlmeextpriv;
4182 pcmdpriv = &padapter->cmdpriv;
4183
4184 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4185 if (!pcmd_obj)
4186 return;
4187
4188 cmdsz = sizeof(struct survey_event) + sizeof(struct C2HEvent_Header);
4189 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4190 if (!pevtcmd) {
4191 kfree(pcmd_obj);
4192 return;
4193 }
4194
4195 INIT_LIST_HEAD(&pcmd_obj->list);
4196
4197 pcmd_obj->cmdcode = _Set_MLME_EVT_CMD_;
4198 pcmd_obj->cmdsz = cmdsz;
4199 pcmd_obj->parmbuf = pevtcmd;
4200
4201 pcmd_obj->rsp = NULL;
4202 pcmd_obj->rspsz = 0;
4203
4204 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4205 pc2h_evt_hdr->len = sizeof(struct survey_event);
4206 pc2h_evt_hdr->ID = _Survey_EVT_;
4207 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4208
4209 psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
4210
4211 if (collect_bss_info(padapter, precv_frame, (struct wlan_bssid_ex *)&psurvey_evt->bss) == _FAIL) {
4212 kfree(pcmd_obj);
4213 kfree(pevtcmd);
4214 return;
4215 }
4216
4217 process_80211d(padapter, &psurvey_evt->bss);
4218
4219 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
4220
4221 pmlmeext->sitesurvey_res.bss_cnt++;
4222}
4223
4224void report_surveydone_event(struct adapter *padapter)
4225{
4226 struct cmd_obj *pcmd_obj;
4227 u8 *pevtcmd;
4228 u32 cmdsz;
4229 struct surveydone_event *psurveydone_evt;
4230 struct C2HEvent_Header *pc2h_evt_hdr;
4231 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4232 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4233
4234 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
4235 if (!pcmd_obj)
4236 return;
4237
4238 cmdsz = sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header);
4239 pevtcmd = kzalloc(cmdsz, GFP_KERNEL);
4240 if (!pevtcmd) {
4241 kfree(pcmd_obj);
4242 return;
4243 }
4244
4245 INIT_LIST_HEAD(&pcmd_obj->list);
4246
4247 pcmd_obj->cmdcode = _Set_MLME_EVT_CMD_;
4248 pcmd_obj->cmdsz = cmdsz;
4249 pcmd_obj->parmbuf = pevtcmd;
4250
4251 pcmd_obj->rsp = NULL;
4252 pcmd_obj->rspsz = 0;
4253
4254 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4255 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
4256 pc2h_evt_hdr->ID = _SurveyDone_EVT_;
4257 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4258
4259 psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
4260 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
4261
4262 DBG_88E("survey done event(%x)\n", psurveydone_evt->bss_cnt);
4263
4264 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
4265}
4266
4267void report_join_res(struct adapter *padapter, int res)
4268{
4269 struct cmd_obj *pcmd_obj;
4270 u8 *pevtcmd;
4271 u32 cmdsz;
4272 struct joinbss_event *pjoinbss_evt;
4273 struct C2HEvent_Header *pc2h_evt_hdr;
4274 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4275 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4276 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4277
4278 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4279 if (!pcmd_obj)
4280 return;
4281
4282 cmdsz = sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header);
4283 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
4284 if (!pevtcmd) {
4285 kfree(pcmd_obj);
4286 return;
4287 }
4288
4289 INIT_LIST_HEAD(&pcmd_obj->list);
4290
4291 pcmd_obj->cmdcode = _Set_MLME_EVT_CMD_;
4292 pcmd_obj->cmdsz = cmdsz;
4293 pcmd_obj->parmbuf = pevtcmd;
4294
4295 pcmd_obj->rsp = NULL;
4296 pcmd_obj->rspsz = 0;
4297
4298 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4299 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
4300 pc2h_evt_hdr->ID = _JoinBss_EVT_;
4301 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4302
4303 pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
4304 memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(struct wlan_bssid_ex));
4305 pjoinbss_evt->network.join_res = res;
4306 pjoinbss_evt->network.aid = res;
4307
4308 DBG_88E("%s(%d)\n", __func__, res);
4309
4310 rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
4311
4312 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
4313}
4314
4315void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr,
4316 unsigned short reason)
4317{
4318 struct cmd_obj *pcmd_obj;
4319 u8 *pevtcmd;
4320 u32 cmdsz;
4321 struct sta_info *psta;
4322 int mac_id;
4323 struct stadel_event *pdel_sta_evt;
4324 struct C2HEvent_Header *pc2h_evt_hdr;
4325 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4326 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4327
4328 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
4329 if (!pcmd_obj)
4330 return;
4331
4332 cmdsz = sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header);
4333 pevtcmd = kzalloc(cmdsz, GFP_KERNEL);
4334 if (!pevtcmd) {
4335 kfree(pcmd_obj);
4336 return;
4337 }
4338
4339 INIT_LIST_HEAD(&pcmd_obj->list);
4340
4341 pcmd_obj->cmdcode = _Set_MLME_EVT_CMD_;
4342 pcmd_obj->cmdsz = cmdsz;
4343 pcmd_obj->parmbuf = pevtcmd;
4344
4345 pcmd_obj->rsp = NULL;
4346 pcmd_obj->rspsz = 0;
4347
4348 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4349 pc2h_evt_hdr->len = sizeof(struct stadel_event);
4350 pc2h_evt_hdr->ID = _DelSTA_EVT_;
4351 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4352
4353 pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
4354 ether_addr_copy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr);
4355 memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
4356
4357 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
4358 if (psta)
4359 mac_id = (int)psta->mac_id;
4360 else
4361 mac_id = -1;
4362
4363 pdel_sta_evt->mac_id = mac_id;
4364
4365 DBG_88E("%s: delete STA, mac_id =%d\n", __func__, mac_id);
4366
4367 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
4368}
4369
4370void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr,
4371 int cam_idx)
4372{
4373 struct cmd_obj *pcmd_obj;
4374 u8 *pevtcmd;
4375 u32 cmdsz;
4376 struct stassoc_event *padd_sta_evt;
4377 struct C2HEvent_Header *pc2h_evt_hdr;
4378 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4379 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4380
4381 pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
4382 if (!pcmd_obj)
4383 return;
4384
4385 cmdsz = sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header);
4386 pevtcmd = kzalloc(cmdsz, GFP_KERNEL);
4387 if (!pevtcmd) {
4388 kfree(pcmd_obj);
4389 return;
4390 }
4391
4392 INIT_LIST_HEAD(&pcmd_obj->list);
4393
4394 pcmd_obj->cmdcode = _Set_MLME_EVT_CMD_;
4395 pcmd_obj->cmdsz = cmdsz;
4396 pcmd_obj->parmbuf = pevtcmd;
4397
4398 pcmd_obj->rsp = NULL;
4399 pcmd_obj->rspsz = 0;
4400
4401 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
4402 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
4403 pc2h_evt_hdr->ID = _AddSTA_EVT_;
4404 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
4405
4406 padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
4407 ether_addr_copy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr);
4408 padd_sta_evt->cam_id = cam_idx;
4409
4410 DBG_88E("%s: add STA\n", __func__);
4411
4412 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
4413}
4414
4415
4416
4417
4418
4419
4420
4421
4422void update_sta_info(struct adapter *padapter, struct sta_info *psta)
4423{
4424 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4425 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4426 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4427
4428
4429 VCS_update(padapter, psta);
4430
4431
4432 if (pmlmepriv->htpriv.ht_option) {
4433 psta->htpriv.ht_option = true;
4434
4435 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
4436
4437 if (support_short_GI(padapter, &pmlmeinfo->HT_caps))
4438 psta->htpriv.sgi = true;
4439
4440 psta->qos_option = true;
4441 } else {
4442 psta->htpriv.ht_option = false;
4443
4444 psta->htpriv.ampdu_enable = false;
4445
4446 psta->htpriv.sgi = false;
4447 psta->qos_option = false;
4448 }
4449 psta->htpriv.bwmode = pmlmeext->cur_bwmode;
4450 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
4451
4452 psta->htpriv.agg_enable_bitmap = 0x0;
4453 psta->htpriv.candidate_tid_bitmap = 0x0;
4454
4455
4456 if (pmlmepriv->qospriv.qos_option)
4457 psta->qos_option = true;
4458
4459 psta->state = _FW_LINKED;
4460}
4461
4462void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res)
4463{
4464 struct sta_info *psta, *psta_bmc;
4465 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4466 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4467 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
4468 struct sta_priv *pstapriv = &padapter->stapriv;
4469 u8 join_type;
4470 u16 media_status;
4471
4472 if (join_res < 0) {
4473 join_type = 1;
4474 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
4475 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
4476
4477
4478 update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
4479
4480 goto exit_mlmeext_joinbss_event_callback;
4481 }
4482
4483 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
4484
4485 psta_bmc = rtw_get_bcmc_stainfo(padapter);
4486 if (psta_bmc) {
4487 pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
4488 update_bmc_sta_support_rate(padapter, psta_bmc->mac_id);
4489 Update_RA_Entry(padapter, psta_bmc->mac_id);
4490 }
4491 }
4492
4493
4494 Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true);
4495
4496
4497 update_IOT_info(padapter);
4498
4499 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
4500
4501
4502 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
4503
4504
4505 update_capinfo(padapter, pmlmeinfo->capability);
4506
4507
4508 WMMOnAssocRsp(padapter);
4509
4510
4511 HTOnAssocRsp(padapter);
4512
4513 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4514
4515 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
4516 if (psta) {
4517 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
4518
4519 psta->wireless_mode = pmlmeext->cur_wireless_mode;
4520
4521
4522 set_sta_rate(padapter, psta);
4523 rtw_hal_set_hwreg(padapter, HW_VAR_TX_RPT_MAX_MACID, (u8 *)&psta->mac_id);
4524 media_status = (psta->mac_id<<8)|1;
4525 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
4526 }
4527
4528 join_type = 2;
4529 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
4530
4531 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
4532
4533 correct_TSF(padapter, pmlmeext);
4534 }
4535 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
4536
4537exit_mlmeext_joinbss_event_callback:
4538
4539 DBG_88E("=>%s\n", __func__);
4540}
4541
4542void mlmeext_sta_add_event_callback(struct adapter *padapter, struct sta_info *psta)
4543{
4544 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4545 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4546 u8 join_type;
4547
4548 DBG_88E("%s\n", __func__);
4549
4550 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
4551 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
4552
4553 } else {
4554
4555 correct_TSF(padapter, pmlmeext);
4556
4557
4558 if (send_beacon(padapter) == _FAIL) {
4559 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
4560 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
4561 return;
4562 }
4563 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
4564 }
4565
4566 join_type = 2;
4567 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
4568 }
4569
4570 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
4571
4572
4573 Update_RA_Entry(padapter, psta->mac_id);
4574
4575
4576 update_sta_info(padapter, psta);
4577}
4578
4579void mlmeext_sta_del_event_callback(struct adapter *padapter)
4580{
4581 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4582 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4583
4584 if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter)) {
4585 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL);
4586 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
4587
4588
4589 update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
4590
4591
4592 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
4593 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4594
4595
4596 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4597
4598 flush_all_cam_entry(padapter);
4599
4600 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4601
4602
4603 Set_MSR(padapter, _HW_STATE_STATION_);
4604
4605 del_timer_sync(&pmlmeext->link_timer);
4606 }
4607}
4608
4609
4610
4611
4612
4613
4614
4615static u8 chk_ap_is_alive(struct adapter *padapter, struct sta_info *psta)
4616{
4617 u8 ret = false;
4618
4619 if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) &&
4620 sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) &&
4621 sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
4622 ret = false;
4623 else
4624 ret = true;
4625
4626 sta_update_last_rx_pkts(psta);
4627
4628 return ret;
4629}
4630
4631void linked_status_chk(struct adapter *padapter)
4632{
4633 u32 i;
4634 struct sta_info *psta;
4635 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4636 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4637 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4638 struct sta_priv *pstapriv = &padapter->stapriv;
4639
4640 if (is_client_associated_to_ap(padapter)) {
4641
4642
4643 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
4644 int rx_chk_limit;
4645
4646 rx_chk_limit = 4;
4647 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
4648 if (psta) {
4649 bool is_p2p_enable = false;
4650
4651 if (!chk_ap_is_alive(padapter, psta))
4652 rx_chk = _FAIL;
4653
4654 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
4655 tx_chk = _FAIL;
4656
4657 if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
4658 u8 backup_oper_channel = 0;
4659
4660
4661 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
4662 backup_oper_channel = rtw_get_oper_ch(padapter);
4663 SelectChannel(padapter, pmlmeext->cur_channel);
4664 }
4665
4666 if (rx_chk != _SUCCESS)
4667 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
4668
4669 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) {
4670 tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
4671
4672 if (tx_chk == _SUCCESS && !is_p2p_enable)
4673 rx_chk = _SUCCESS;
4674 }
4675
4676
4677 if (backup_oper_channel > 0)
4678 SelectChannel(padapter, backup_oper_channel);
4679 } else {
4680 if (rx_chk != _SUCCESS) {
4681 if (pmlmeext->retry == 0) {
4682 issue_probereq(padapter,
4683 &pmlmeinfo->network.Ssid,
4684 pmlmeinfo->network.MacAddress,
4685 false);
4686 issue_probereq(padapter,
4687 &pmlmeinfo->network.Ssid,
4688 pmlmeinfo->network.MacAddress,
4689 false);
4690 issue_probereq(padapter,
4691 &pmlmeinfo->network.Ssid,
4692 pmlmeinfo->network.MacAddress,
4693 false);
4694 }
4695 }
4696
4697 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf)
4698 tx_chk = issue_nulldata(padapter, NULL, 0, 1, 0);
4699 }
4700
4701 if (rx_chk == _FAIL) {
4702 pmlmeext->retry++;
4703 if (pmlmeext->retry > rx_chk_limit) {
4704 DBG_88E_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
4705 FUNC_ADPT_ARG(padapter));
4706 receive_disconnect(padapter, pmlmeinfo->network.MacAddress,
4707 WLAN_REASON_EXPIRATION_CHK);
4708 return;
4709 }
4710 } else {
4711 pmlmeext->retry = 0;
4712 }
4713
4714 if (tx_chk == _FAIL) {
4715 pmlmeinfo->link_count &= 0xf;
4716 } else {
4717 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
4718 pmlmeinfo->link_count = 0;
4719 }
4720 }
4721 } else if (is_client_associated_to_ibss(padapter)) {
4722
4723
4724 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
4725 if (pmlmeinfo->FW_sta_info[i].status == 1) {
4726 psta = pmlmeinfo->FW_sta_info[i].psta;
4727
4728 if (!psta)
4729 continue;
4730 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta)) {
4731 if (pmlmeinfo->FW_sta_info[i].retry < 3) {
4732 pmlmeinfo->FW_sta_info[i].retry++;
4733 } else {
4734 pmlmeinfo->FW_sta_info[i].retry = 0;
4735 pmlmeinfo->FW_sta_info[i].status = 0;
4736 report_del_sta_event(padapter, psta->hwaddr
4737 , 65535
4738 );
4739 }
4740 } else {
4741 pmlmeinfo->FW_sta_info[i].retry = 0;
4742 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
4743 }
4744 }
4745 }
4746 }
4747}
4748
4749void survey_timer_hdl(struct timer_list *t)
4750{
4751 struct adapter *padapter = from_timer(padapter, t,
4752 mlmeextpriv.survey_timer);
4753 struct cmd_obj *ph2c;
4754 struct sitesurvey_parm *psurveyPara;
4755 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4756 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4757
4758
4759 if (pmlmeext->sitesurvey_res.state > SCAN_START) {
4760 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
4761 pmlmeext->sitesurvey_res.channel_idx++;
4762
4763 if (pmlmeext->scan_abort) {
4764 pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
4765 DBG_88E("%s idx:%d\n", __func__
4766 , pmlmeext->sitesurvey_res.channel_idx);
4767
4768 pmlmeext->scan_abort = false;
4769 }
4770
4771 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
4772 if (!ph2c)
4773 goto exit_survey_timer_hdl;
4774
4775 psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
4776 if (!psurveyPara) {
4777 kfree(ph2c);
4778 goto exit_survey_timer_hdl;
4779 }
4780
4781 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, _SiteSurvey_CMD_);
4782 rtw_enqueue_cmd(pcmdpriv, ph2c);
4783 }
4784
4785exit_survey_timer_hdl:
4786 return;
4787}
4788
4789void link_timer_hdl(struct timer_list *t)
4790{
4791 struct adapter *padapter = from_timer(padapter, t,
4792 mlmeextpriv.link_timer);
4793 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4794 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4795
4796 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
4797 DBG_88E("%s:no beacon while connecting\n", __func__);
4798 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4799 report_join_res(padapter, -3);
4800 } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
4801
4802 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
4803 pmlmeinfo->state = 0;
4804 report_join_res(padapter, -1);
4805 return;
4806 }
4807
4808 DBG_88E("%s: auth timeout and try again\n", __func__);
4809 pmlmeinfo->auth_seq = 1;
4810 issue_auth(padapter, NULL, 0);
4811 set_link_timer(pmlmeext, REAUTH_TO);
4812 } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
4813
4814 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
4815 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4816 report_join_res(padapter, -2);
4817 return;
4818 }
4819
4820 DBG_88E("%s: assoc timeout and try again\n", __func__);
4821 issue_assocreq(padapter);
4822 set_link_timer(pmlmeext, REASSOC_TO);
4823 }
4824}
4825
4826void addba_timer_hdl(struct timer_list *t)
4827{
4828 struct sta_info *psta = from_timer(psta, t, addba_retry_timer);
4829 struct ht_priv *phtpriv;
4830
4831 if (!psta)
4832 return;
4833
4834 phtpriv = &psta->htpriv;
4835
4836 if ((phtpriv->ht_option) && (phtpriv->ampdu_enable)) {
4837 if (phtpriv->candidate_tid_bitmap)
4838 phtpriv->candidate_tid_bitmap = 0x0;
4839 }
4840}
4841
4842u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf)
4843{
4844 u8 type;
4845 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4846 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4847 struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
4848
4849 if (psetop->mode == Ndis802_11APMode) {
4850 pmlmeinfo->state = WIFI_FW_AP_STATE;
4851 type = _HW_STATE_AP_;
4852 } else if (psetop->mode == Ndis802_11Infrastructure) {
4853 pmlmeinfo->state &= ~(BIT(0)|BIT(1));
4854 pmlmeinfo->state |= WIFI_FW_STATION_STATE;
4855 type = _HW_STATE_STATION_;
4856 } else if (psetop->mode == Ndis802_11IBSS) {
4857 type = _HW_STATE_ADHOC_;
4858 } else {
4859 type = _HW_STATE_NOLINK_;
4860 }
4861
4862 rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
4863
4864
4865 return H2C_SUCCESS;
4866}
4867
4868u8 createbss_hdl(struct adapter *padapter, u8 *pbuf)
4869{
4870 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4871 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4872 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
4873 struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
4874
4875
4876 if (pparm->InfrastructureMode == Ndis802_11APMode) {
4877#ifdef CONFIG_88EU_AP_MODE
4878
4879 if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
4880
4881 return H2C_SUCCESS;
4882 }
4883#endif
4884 }
4885
4886
4887 if (pparm->InfrastructureMode == Ndis802_11IBSS) {
4888 rtw_joinbss_reset(padapter);
4889
4890 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
4891 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4892 pmlmeinfo->ERP_enable = 0;
4893 pmlmeinfo->WMM_enable = 0;
4894 pmlmeinfo->HT_enable = 0;
4895 pmlmeinfo->HT_caps_enable = 0;
4896 pmlmeinfo->HT_info_enable = 0;
4897 pmlmeinfo->agg_enable_bitmap = 0;
4898 pmlmeinfo->candidate_tid_bitmap = 0;
4899
4900
4901 Save_DM_Func_Flag(padapter);
4902 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
4903
4904
4905
4906
4907
4908
4909 del_timer_sync(&pmlmeext->link_timer);
4910
4911
4912 flush_all_cam_entry(padapter);
4913
4914 memcpy(pnetwork, pbuf, offsetof(struct wlan_bssid_ex, ie_length));
4915 pnetwork->ie_length = ((struct wlan_bssid_ex *)pbuf)->ie_length;
4916
4917 if (pnetwork->ie_length > MAX_IE_SZ)
4918 return H2C_PARAMETERS_ERROR;
4919
4920 memcpy(pnetwork->ies, ((struct wlan_bssid_ex *)pbuf)->ies, pnetwork->ie_length);
4921
4922 start_create_ibss(padapter);
4923 }
4924
4925 return H2C_SUCCESS;
4926}
4927
4928u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
4929{
4930 u8 join_type;
4931 struct ndis_802_11_var_ie *pIE;
4932 struct registry_priv *pregpriv = &padapter->registrypriv;
4933 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4934 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4935 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
4936 struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
4937 u32 i;
4938
4939
4940 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
4941 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
4942 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 5, 100);
4943
4944 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4945
4946
4947 flush_all_cam_entry(padapter);
4948
4949 del_timer_sync(&pmlmeext->link_timer);
4950
4951
4952 Set_MSR(padapter, _HW_STATE_STATION_);
4953
4954 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL);
4955 }
4956
4957 rtw_antenna_select_cmd(padapter, pparm->PhyInfo.Optimum_antenna, false);
4958
4959 rtw_joinbss_reset(padapter);
4960
4961 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
4962 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4963 pmlmeinfo->ERP_enable = 0;
4964 pmlmeinfo->WMM_enable = 0;
4965 pmlmeinfo->HT_enable = 0;
4966 pmlmeinfo->HT_caps_enable = 0;
4967 pmlmeinfo->HT_info_enable = 0;
4968 pmlmeinfo->agg_enable_bitmap = 0;
4969 pmlmeinfo->candidate_tid_bitmap = 0;
4970 pmlmeinfo->bwmode_updated = false;
4971
4972 memcpy(pnetwork, pbuf, offsetof(struct wlan_bssid_ex, ie_length));
4973 pnetwork->ie_length = ((struct wlan_bssid_ex *)pbuf)->ie_length;
4974
4975 if (pnetwork->ie_length > MAX_IE_SZ)
4976 return H2C_PARAMETERS_ERROR;
4977
4978 memcpy(pnetwork->ies, ((struct wlan_bssid_ex *)pbuf)->ies, pnetwork->ie_length);
4979
4980
4981
4982 for (i = sizeof(struct ndis_802_11_fixed_ie); i < pnetwork->ie_length;) {
4983 pIE = (struct ndis_802_11_var_ie *)(pnetwork->ies + i);
4984
4985 switch (pIE->ElementID) {
4986 case _VENDOR_SPECIFIC_IE_:
4987 if (!memcmp(pIE->data, WMM_OUI, 4))
4988 pmlmeinfo->WMM_enable = 1;
4989 break;
4990 case _HT_CAPABILITY_IE_:
4991 pmlmeinfo->HT_caps_enable = 1;
4992 break;
4993 case _HT_EXTRA_INFO_IE_:
4994 pmlmeinfo->HT_info_enable = 1;
4995
4996
4997 {
4998 struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data);
4999
5000 if ((pregpriv->cbw40_enable) && (pht_info->infos[0] & BIT(2))) {
5001
5002 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
5003 switch (pht_info->infos[0] & 0x3) {
5004 case 1:
5005 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
5006 break;
5007 case 3:
5008 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
5009 break;
5010 default:
5011 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5012 break;
5013 }
5014
5015 DBG_88E("set ch/bw before connected\n");
5016 }
5017 }
5018 break;
5019 default:
5020 break;
5021 }
5022
5023 i += (pIE->Length + 2);
5024 }
5025
5026
5027
5028
5029 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
5030 join_type = 0;
5031 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
5032
5033
5034 del_timer_sync(&pmlmeext->link_timer);
5035
5036 start_clnt_join(padapter);
5037
5038 return H2C_SUCCESS;
5039}
5040
5041u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf)
5042{
5043 struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
5044 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5045 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5046 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
5047 u8 val8;
5048
5049 if (is_client_associated_to_ap(padapter))
5050 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
5051
5052 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL);
5053 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
5054
5055
5056 update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
5057
5058 if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) {
5059
5060 val8 = 0;
5061 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
5062 }
5063
5064
5065 Set_MSR(padapter, _HW_STATE_STATION_);
5066
5067 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5068
5069
5070 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5071 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5072
5073 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5074
5075 flush_all_cam_entry(padapter);
5076
5077 del_timer_sync(&pmlmeext->link_timer);
5078
5079 rtw_free_uc_swdec_pending_queue(padapter);
5080
5081 return H2C_SUCCESS;
5082}
5083
5084static int rtw_scan_ch_decision(struct adapter *padapter,
5085 struct rtw_ieee80211_channel *out,
5086 u32 out_num,
5087 struct rtw_ieee80211_channel *in, u32 in_num)
5088{
5089 int i, j;
5090 int set_idx;
5091 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5092
5093
5094 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
5095
5096
5097 j = 0;
5098 for (i = 0; i < in_num; i++) {
5099 set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value);
5100 if (in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED) &&
5101 set_idx >= 0) {
5102 out[j] = in[i];
5103
5104 if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
5105 out[j].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
5106
5107 j++;
5108 }
5109 if (j >= out_num)
5110 break;
5111 }
5112
5113
5114 if (j == 0) {
5115 for (i = 0; i < pmlmeext->max_chan_nums; i++) {
5116 out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
5117
5118 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
5119 out[i].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
5120
5121 j++;
5122 }
5123 }
5124
5125 return j;
5126}
5127
5128u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf)
5129{
5130 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5131 struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
5132 u8 bdelayscan = false;
5133 u8 val8;
5134 u32 initialgain;
5135 u32 i;
5136
5137 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
5138
5139 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, NULL);
5140
5141 pmlmeext->sitesurvey_res.state = SCAN_START;
5142 pmlmeext->sitesurvey_res.bss_cnt = 0;
5143 pmlmeext->sitesurvey_res.channel_idx = 0;
5144
5145 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
5146 if (pparm->ssid[i].SsidLength) {
5147 memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
5148 pmlmeext->sitesurvey_res.ssid[i].SsidLength = pparm->ssid[i].SsidLength;
5149 } else {
5150 pmlmeext->sitesurvey_res.ssid[i].SsidLength = 0;
5151 }
5152 }
5153
5154 pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter
5155 , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT
5156 , pparm->ch, pparm->ch_num
5157 );
5158
5159 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
5160
5161
5162 if (is_client_associated_to_ap(padapter)) {
5163 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
5164
5165 issue_nulldata(padapter, NULL, 1, 3, 500);
5166
5167 bdelayscan = true;
5168 }
5169 if (bdelayscan) {
5170
5171 set_survey_timer(pmlmeext, 50);
5172 return H2C_SUCCESS;
5173 }
5174 }
5175
5176 if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) {
5177
5178 Save_DM_Func_Flag(padapter);
5179 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
5180
5181
5182 initialgain = 0x1E;
5183
5184 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
5185
5186
5187 Set_MSR(padapter, _HW_STATE_NOLINK_);
5188
5189 val8 = 1;
5190 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
5191
5192 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
5193 }
5194
5195 site_survey(padapter);
5196
5197 return H2C_SUCCESS;
5198}
5199
5200u8 setauth_hdl(struct adapter *padapter, unsigned char *pbuf)
5201{
5202 struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
5203 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5204 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5205
5206 if (pparm->mode < 4)
5207 pmlmeinfo->auth_algo = pparm->mode;
5208 return H2C_SUCCESS;
5209}
5210
5211u8 setkey_hdl(struct adapter *padapter, u8 *pbuf)
5212{
5213 unsigned short ctrl;
5214 struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
5215 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5216 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5217 unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
5218
5219
5220 if (pparm->set_tx)
5221 pmlmeinfo->key_index = pparm->keyid;
5222
5223
5224 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
5225
5226 DBG_88E_LEVEL(_drv_info_, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
5227 "keyid:%d\n", pparm->algorithm, pparm->keyid);
5228 write_cam(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
5229
5230 return H2C_SUCCESS;
5231}
5232
5233u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf)
5234{
5235 u16 ctrl = 0;
5236 u8 cam_id;
5237 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5238 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5239 struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254 cam_id = 4;
5255
5256 DBG_88E_LEVEL(_drv_info_, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n",
5257 pparm->algorithm, cam_id);
5258 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
5259 struct sta_info *psta;
5260 struct sta_priv *pstapriv = &padapter->stapriv;
5261
5262 if (pparm->algorithm == _NO_PRIVACY_) {
5263 clear_cam_entry(padapter, pparm->id);
5264 return H2C_SUCCESS_RSP;
5265 }
5266
5267 psta = rtw_get_stainfo(pstapriv, pparm->addr);
5268 if (psta) {
5269 ctrl = BIT(15) | ((pparm->algorithm) << 2);
5270
5271 DBG_88E("r871x_set_stakey_hdl(): enc_algorithm=%d\n", pparm->algorithm);
5272
5273 if ((psta->mac_id < 1) || (psta->mac_id > (NUM_STA-4))) {
5274 DBG_88E("r871x_set_stakey_hdl():set_stakey failed, mac_id(aid)=%d\n", psta->mac_id);
5275 return H2C_REJECTED;
5276 }
5277
5278 cam_id = psta->mac_id + 3;
5279
5280 DBG_88E("Write CAM, mac_addr =%pM, cam_entry=%d\n",
5281 pparm->addr, cam_id);
5282
5283 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
5284
5285 return H2C_SUCCESS_RSP;
5286 } else {
5287 DBG_88E("r871x_set_stakey_hdl(): sta has been free\n");
5288 return H2C_REJECTED;
5289 }
5290 }
5291
5292
5293
5294 if (pparm->algorithm == _NO_PRIVACY_) {
5295 clear_cam_entry(padapter, pparm->id);
5296 return H2C_SUCCESS;
5297 }
5298 ctrl = BIT(15) | ((pparm->algorithm) << 2);
5299 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
5300 pmlmeinfo->enc_algo = pparm->algorithm;
5301 return H2C_SUCCESS;
5302}
5303
5304u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf)
5305{
5306 struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
5307 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5308 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5309
5310 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
5311
5312 if (!psta)
5313 return H2C_SUCCESS;
5314
5315 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
5316 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) {
5317 issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
5318 mod_timer(&psta->addba_retry_timer,
5319 jiffies + msecs_to_jiffies(ADDBA_TO));
5320 } else {
5321 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
5322 }
5323 return H2C_SUCCESS;
5324}
5325
5326u8 set_tx_beacon_cmd(struct adapter *padapter)
5327{
5328 struct cmd_obj *ph2c;
5329 struct wlan_bssid_ex *ptxBeacon_parm;
5330 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
5331 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5332 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5333 u8 res = _SUCCESS;
5334 int len_diff = 0;
5335
5336 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
5337 if (!ph2c) {
5338 res = _FAIL;
5339 goto exit;
5340 }
5341
5342 ptxBeacon_parm = kmemdup(&(pmlmeinfo->network),
5343 sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
5344 if (ptxBeacon_parm == NULL) {
5345 kfree(ph2c);
5346 res = _FAIL;
5347 goto exit;
5348 }
5349
5350 len_diff = update_hidden_ssid(ptxBeacon_parm->ies+_BEACON_IE_OFFSET_,
5351 ptxBeacon_parm->ie_length-_BEACON_IE_OFFSET_,
5352 pmlmeinfo->hidden_ssid_mode);
5353 ptxBeacon_parm->ie_length += len_diff;
5354
5355 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, _TX_Beacon_CMD_);
5356
5357 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
5358
5359exit:
5360 return res;
5361}
5362
5363u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf)
5364{
5365 u8 evt_code;
5366 u16 evt_sz;
5367 uint *peventbuf;
5368 void (*event_callback)(struct adapter *dev, u8 *pbuf);
5369
5370 peventbuf = (uint *)pbuf;
5371 evt_sz = (u16)(*peventbuf&0xffff);
5372 evt_code = (u8)((*peventbuf>>16)&0xff);
5373
5374
5375 if (evt_code >= MAX_C2HEVT) {
5376 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent Code(%d) mismatch!\n", evt_code));
5377 goto _abort_event_;
5378 }
5379
5380
5381 if ((wlanevents[evt_code].parmsize != 0) &&
5382 (wlanevents[evt_code].parmsize != evt_sz)) {
5383 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
5384 ("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
5385 evt_code, wlanevents[evt_code].parmsize, evt_sz));
5386 goto _abort_event_;
5387 }
5388
5389 peventbuf += 2;
5390
5391 if (peventbuf) {
5392 event_callback = wlanevents[evt_code].event_callback;
5393 event_callback(padapter, (u8 *)peventbuf);
5394 }
5395
5396_abort_event_:
5397 return H2C_SUCCESS;
5398}
5399
5400u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf)
5401{
5402 if (send_beacon(padapter) == _FAIL) {
5403 DBG_88E("issue_beacon, fail!\n");
5404 return H2C_PARAMETERS_ERROR;
5405 }
5406#ifdef CONFIG_88EU_AP_MODE
5407 else {
5408 struct sta_info *psta_bmc;
5409 struct list_head *xmitframe_plist, *xmitframe_phead;
5410 struct xmit_frame *pxmitframe = NULL;
5411 struct sta_priv *pstapriv = &padapter->stapriv;
5412
5413
5414 psta_bmc = rtw_get_bcmc_stainfo(padapter);
5415 if (!psta_bmc)
5416 return H2C_SUCCESS;
5417
5418 if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len > 0)) {
5419 msleep(10);
5420 spin_lock_bh(&psta_bmc->sleep_q.lock);
5421
5422 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
5423 xmitframe_plist = xmitframe_phead->next;
5424
5425 while (xmitframe_phead != xmitframe_plist) {
5426 pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
5427
5428 xmitframe_plist = xmitframe_plist->next;
5429
5430 list_del_init(&pxmitframe->list);
5431
5432 psta_bmc->sleepq_len--;
5433 if (psta_bmc->sleepq_len > 0)
5434 pxmitframe->attrib.mdata = 1;
5435 else
5436 pxmitframe->attrib.mdata = 0;
5437
5438 pxmitframe->attrib.triggered = 1;
5439
5440 pxmitframe->attrib.qsel = 0x11;
5441
5442 spin_unlock_bh(&psta_bmc->sleep_q.lock);
5443 if (rtw_hal_xmit(padapter, pxmitframe))
5444 rtw_os_xmit_complete(padapter, pxmitframe);
5445 spin_lock_bh(&psta_bmc->sleep_q.lock);
5446 }
5447 spin_unlock_bh(&psta_bmc->sleep_q.lock);
5448 }
5449 }
5450#endif
5451 return H2C_SUCCESS;
5452}
5453
5454u8 set_ch_hdl(struct adapter *padapter, u8 *pbuf)
5455{
5456 struct set_ch_parm *set_ch_parm;
5457 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5458
5459 if (!pbuf)
5460 return H2C_PARAMETERS_ERROR;
5461
5462 set_ch_parm = (struct set_ch_parm *)pbuf;
5463
5464 DBG_88E(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
5465 FUNC_NDEV_ARG(padapter->pnetdev),
5466 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
5467
5468 pmlmeext->cur_channel = set_ch_parm->ch;
5469 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
5470 pmlmeext->cur_bwmode = set_ch_parm->bw;
5471
5472 set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
5473
5474 return H2C_SUCCESS;
5475}
5476
5477u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf)
5478{
5479 struct SetChannelPlan_param *setChannelPlan_param;
5480 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5481
5482 if (!pbuf)
5483 return H2C_PARAMETERS_ERROR;
5484
5485 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
5486
5487 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
5488 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
5489
5490 return H2C_SUCCESS;
5491}
5492