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