1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
20 #define _RTW_MLME_EXT_C_
22 #include <linux/ieee80211.h>
24 #include <osdep_service.h>
25 #include <drv_types.h>
27 #include <rtw_mlme_ext.h>
28 #include <wlan_bssdef.h>
29 #include <mlme_osdep.h>
30 #include <recv_osdep.h>
32 static u8 null_addr
[ETH_ALEN
] = {0, 0, 0, 0, 0, 0};
34 /**************************************************
35 OUI definitions for the vendor specific IE
36 ***************************************************/
37 unsigned char RTW_WPA_OUI
[] = {0x00, 0x50, 0xf2, 0x01};
38 unsigned char WMM_OUI
[] = {0x00, 0x50, 0xf2, 0x02};
39 unsigned char WPS_OUI
[] = {0x00, 0x50, 0xf2, 0x04};
40 unsigned char P2P_OUI
[] = {0x50, 0x6F, 0x9A, 0x09};
41 unsigned char WFD_OUI
[] = {0x50, 0x6F, 0x9A, 0x0A};
43 unsigned char WMM_INFO_OUI
[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
44 unsigned char WMM_PARA_OUI
[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
46 unsigned char WPA_TKIP_CIPHER
[4] = {0x00, 0x50, 0xf2, 0x02};
47 unsigned char RSN_TKIP_CIPHER
[4] = {0x00, 0x0f, 0xac, 0x02};
49 extern unsigned char REALTEK_96B_IE
[];
51 /********************************************************
53 *********************************************************/
54 unsigned char MCS_rate_2R
[16] = {0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
55 unsigned char MCS_rate_1R
[16] = {0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
57 /********************************************************
58 ChannelPlan definitions
59 *********************************************************/
60 static struct rt_channel_plan_2g RTW_ChannelPlan2G
[RT_CHANNEL_DOMAIN_2G_MAX
] = {
61 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
62 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
63 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
64 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
65 {{10, 11, 12, 13}, 4}, /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
66 {{}, 0}, /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
69 static struct rt_channel_plan_map RTW_ChannelPlanMap
[RT_CHANNEL_DOMAIN_MAX
] = {
70 /* 0x00 ~ 0x1F , Old Define ===== */
71 {0x02}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
72 {0x02}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
73 {0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
74 {0x01}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
75 {0x01}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
76 {0x03}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
77 {0x03}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
78 {0x01}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
79 {0x03}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
80 {0x03}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
81 {0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
82 {0x02}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
83 {0x01}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
84 {0x02}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
85 {0x02}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
86 {0x02}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
87 {0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
88 {0x02}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
89 {0x01}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
90 {0x00}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
91 {0x02}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
92 {0x00}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
93 {0x00}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
94 {0x03}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
95 {0x05}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
96 {0x02}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
102 {0x05}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
103 /* 0x20 ~ 0x7F , New Define ===== */
104 {0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
105 {0x01}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
106 {0x02}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
107 {0x03}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
108 {0x04}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
109 {0x02}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
110 {0x00}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
111 {0x03}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
112 {0x00}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
113 {0x00}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
120 {0x00}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
121 {0x00}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
122 {0x00}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
123 {0x00}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
124 {0x02}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
125 {0x00}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
126 {0x00}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
127 {0x03}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
128 {0x03}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
129 {0x02}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
136 {0x02}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
137 {0x03}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
140 static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE
= {0x03}; /* use the combination for max channel numbers */
143 * Search the @param channel_num in given @param channel_set
144 * @ch_set: the given channel set
145 * @ch: the given channel number
147 * return the index of channel_num in channel_set, -1 if not found
149 int rtw_ch_set_search_ch(struct rt_channel_info
*ch_set
, const u32 ch
)
152 for (i
= 0; ch_set
[i
].ChannelNum
!= 0; i
++) {
153 if (ch
== ch_set
[i
].ChannelNum
)
157 if (i
>= ch_set
[i
].ChannelNum
)
162 struct xmit_frame
*alloc_mgtxmitframe(struct xmit_priv
*pxmitpriv
)
164 struct xmit_frame
*pmgntframe
;
165 struct xmit_buf
*pxmitbuf
;
167 pmgntframe
= rtw_alloc_xmitframe(pxmitpriv
);
168 if (pmgntframe
== NULL
) {
169 DBG_88E("%s, alloc xmitframe fail\n", __func__
);
173 pxmitbuf
= rtw_alloc_xmitbuf_ext(pxmitpriv
);
174 if (pxmitbuf
== NULL
) {
175 DBG_88E("%s, alloc xmitbuf fail\n", __func__
);
176 rtw_free_xmitframe(pxmitpriv
, pmgntframe
);
179 pmgntframe
->frame_tag
= MGNT_FRAMETAG
;
180 pmgntframe
->pxmitbuf
= pxmitbuf
;
181 pmgntframe
->buf_addr
= pxmitbuf
->pbuf
;
182 pxmitbuf
->priv_data
= pmgntframe
;
186 /****************************************************************************
188 Following are some TX functions for WiFi MLME
190 *****************************************************************************/
192 void update_mgnt_tx_rate(struct adapter
*padapter
, u8 rate
)
194 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
196 pmlmeext
->tx_rate
= rate
;
197 DBG_88E("%s(): rate = %x\n", __func__
, rate
);
200 void update_mgntframe_attrib(struct adapter
*padapter
, struct pkt_attrib
*pattrib
)
202 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
204 memset((u8
*)(pattrib
), 0, sizeof(struct pkt_attrib
));
206 pattrib
->hdrlen
= 24;
207 pattrib
->nr_frags
= 1;
208 pattrib
->priority
= 7;
210 pattrib
->qsel
= 0x12;
214 if (pmlmeext
->cur_wireless_mode
& WIRELESS_11B
)
215 pattrib
->raid
= 6;/* b mode */
217 pattrib
->raid
= 5;/* a/g mode */
219 pattrib
->encrypt
= _NO_PRIVACY_
;
220 pattrib
->bswenc
= false;
222 pattrib
->qos_en
= false;
223 pattrib
->ht_en
= false;
224 pattrib
->bwmode
= HT_CHANNEL_WIDTH_20
;
225 pattrib
->ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
226 pattrib
->sgi
= false;
228 pattrib
->seqnum
= pmlmeext
->mgnt_seq
;
230 pattrib
->retry_ctrl
= true;
233 static void dump_mgntframe(struct adapter
*padapter
,
234 struct xmit_frame
*pmgntframe
)
236 if (padapter
->bSurpriseRemoved
|| padapter
->bDriverStopped
)
239 rtw_hal_mgnt_xmit(padapter
, pmgntframe
);
242 static s32
dump_mgntframe_and_wait(struct adapter
*padapter
,
243 struct xmit_frame
*pmgntframe
,
247 struct xmit_buf
*pxmitbuf
= pmgntframe
->pxmitbuf
;
248 struct submit_ctx sctx
;
250 if (padapter
->bSurpriseRemoved
|| padapter
->bDriverStopped
)
253 rtw_sctx_init(&sctx
, timeout_ms
);
254 pxmitbuf
->sctx
= &sctx
;
256 ret
= rtw_hal_mgnt_xmit(padapter
, pmgntframe
);
259 ret
= rtw_sctx_wait(&sctx
);
264 static s32
dump_mgntframe_and_wait_ack(struct adapter
*padapter
,
265 struct xmit_frame
*pmgntframe
)
268 u32 timeout_ms
= 500;/* 500ms */
269 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
271 if (padapter
->bSurpriseRemoved
|| padapter
->bDriverStopped
)
274 _enter_critical_mutex(&pxmitpriv
->ack_tx_mutex
, NULL
);
275 pxmitpriv
->ack_tx
= true;
277 pmgntframe
->ack_report
= 1;
278 if (rtw_hal_mgnt_xmit(padapter
, pmgntframe
) == _SUCCESS
) {
279 ret
= rtw_ack_tx_wait(pxmitpriv
, timeout_ms
);
282 pxmitpriv
->ack_tx
= false;
283 mutex_unlock(&pxmitpriv
->ack_tx_mutex
);
288 static int update_hidden_ssid(u8
*ies
, u32 ies_len
, u8 hidden_ssid_mode
)
294 ssid_ie
= rtw_get_ie(ies
, WLAN_EID_SSID
, &ssid_len_ori
, ies_len
);
296 if (ssid_ie
&& ssid_len_ori
> 0) {
297 switch (hidden_ssid_mode
) {
299 u8
*next_ie
= ssid_ie
+ 2 + ssid_len_ori
;
302 remain_len
= ies_len
- (next_ie
- ies
);
305 memcpy(ssid_ie
+2, next_ie
, remain_len
);
306 len_diff
-= ssid_len_ori
;
311 memset(&ssid_ie
[2], 0, ssid_len_ori
);
321 static void issue_beacon(struct adapter
*padapter
, int timeout_ms
)
323 struct xmit_frame
*pmgntframe
;
324 struct pkt_attrib
*pattrib
;
325 unsigned char *pframe
;
326 struct rtw_ieee80211_hdr
*pwlanhdr
;
328 unsigned int rate_len
;
329 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
330 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
331 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
332 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
333 struct wlan_bssid_ex
*cur_network
= &(pmlmeinfo
->network
);
334 u8 bc_addr
[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
336 pmgntframe
= alloc_mgtxmitframe(pxmitpriv
);
337 if (pmgntframe
== NULL
) {
338 DBG_88E("%s, alloc mgnt frame fail\n", __func__
);
341 #if defined(CONFIG_88EU_AP_MODE)
342 spin_lock_bh(&pmlmepriv
->bcn_update_lock
);
343 #endif /* if defined (CONFIG_88EU_AP_MODE) */
345 /* update attribute */
346 pattrib
= &pmgntframe
->attrib
;
347 update_mgntframe_attrib(padapter
, pattrib
);
348 pattrib
->qsel
= 0x10;
350 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
352 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
353 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
356 fctrl
= &(pwlanhdr
->frame_ctl
);
359 memcpy(pwlanhdr
->addr1
, bc_addr
, ETH_ALEN
);
360 memcpy(pwlanhdr
->addr2
, myid(&(padapter
->eeprompriv
)), ETH_ALEN
);
361 memcpy(pwlanhdr
->addr3
, cur_network
->MacAddress
, ETH_ALEN
);
363 SetSeqNum(pwlanhdr
, 0/*pmlmeext->mgnt_seq*/);
364 /* pmlmeext->mgnt_seq++; */
365 SetFrameSubType(pframe
, WIFI_BEACON
);
367 pframe
+= sizeof(struct rtw_ieee80211_hdr_3addr
);
368 pattrib
->pktlen
= sizeof(struct rtw_ieee80211_hdr_3addr
);
370 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
) {
375 memcpy(pframe
, cur_network
->IEs
, cur_network
->IELength
);
376 len_diff
= update_hidden_ssid(
377 pframe
+_BEACON_IE_OFFSET_
378 , cur_network
->IELength
-_BEACON_IE_OFFSET_
379 , pmlmeinfo
->hidden_ssid_mode
381 pframe
+= (cur_network
->IELength
+len_diff
);
382 pattrib
->pktlen
+= (cur_network
->IELength
+len_diff
);
383 wps_ie
= rtw_get_wps_ie(pmgntframe
->buf_addr
+TXDESC_OFFSET
+sizeof(struct rtw_ieee80211_hdr_3addr
)+_BEACON_IE_OFFSET_
,
384 pattrib
->pktlen
-sizeof(struct rtw_ieee80211_hdr_3addr
)-_BEACON_IE_OFFSET_
, NULL
, &wps_ielen
);
385 if (wps_ie
&& wps_ielen
> 0)
386 rtw_get_wps_attr_content(wps_ie
, wps_ielen
, WPS_ATTR_SELECTED_REGISTRAR
, (u8
*)(&sr
), NULL
);
388 set_fwstate(pmlmepriv
, WIFI_UNDER_WPS
);
390 _clr_fwstate_(pmlmepriv
, WIFI_UNDER_WPS
);
395 /* below for ad-hoc mode */
397 /* timestamp will be inserted by hardware */
399 pattrib
->pktlen
+= 8;
401 /* beacon interval: 2 bytes */
403 memcpy(pframe
, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network
->IEs
)), 2);
406 pattrib
->pktlen
+= 2;
408 /* capability info: 2 bytes */
410 memcpy(pframe
, (unsigned char *)(rtw_get_capability_from_ie(cur_network
->IEs
)), 2);
413 pattrib
->pktlen
+= 2;
416 pframe
= rtw_set_ie(pframe
, _SSID_IE_
, cur_network
->Ssid
.SsidLength
, cur_network
->Ssid
.Ssid
, &pattrib
->pktlen
);
418 /* supported rates... */
419 rate_len
= rtw_get_rateset_len(cur_network
->SupportedRates
);
420 pframe
= rtw_set_ie(pframe
, _SUPPORTEDRATES_IE_
, ((rate_len
> 8) ? 8 : rate_len
), cur_network
->SupportedRates
, &pattrib
->pktlen
);
422 /* DS parameter set */
423 pframe
= rtw_set_ie(pframe
, _DSSET_IE_
, 1, (unsigned char *)&(cur_network
->Configuration
.DSConfig
), &pattrib
->pktlen
);
428 /* IBSS Parameter Set... */
430 pframe
= rtw_set_ie(pframe
, _IBSS_PARA_IE_
, 2, (unsigned char *)(&ATIMWindow
), &pattrib
->pktlen
);
433 pframe
= rtw_set_ie(pframe
, _ERPINFO_IE_
, 1, &erpinfo
, &pattrib
->pktlen
);
436 /* EXTERNDED SUPPORTED RATE */
438 pframe
= rtw_set_ie(pframe
, _EXT_SUPPORTEDRATES_IE_
, (rate_len
- 8), (cur_network
->SupportedRates
+ 8), &pattrib
->pktlen
);
439 /* todo:HT for adhoc */
442 #if defined(CONFIG_88EU_AP_MODE)
443 pmlmepriv
->update_bcn
= false;
445 spin_unlock_bh(&pmlmepriv
->bcn_update_lock
);
446 #endif /* if defined (CONFIG_88EU_AP_MODE) */
448 if ((pattrib
->pktlen
+ TXDESC_SIZE
) > 512) {
449 DBG_88E("beacon frame too large\n");
453 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
455 /* DBG_88E("issue bcn_sz=%d\n", pattrib->last_txcmdsz); */
457 dump_mgntframe_and_wait(padapter
, pmgntframe
, timeout_ms
);
459 dump_mgntframe(padapter
, pmgntframe
);
462 static void issue_probersp(struct adapter
*padapter
, unsigned char *da
)
464 struct xmit_frame
*pmgntframe
;
465 struct pkt_attrib
*pattrib
;
466 unsigned char *pframe
;
467 struct rtw_ieee80211_hdr
*pwlanhdr
;
469 unsigned char *mac
, *bssid
;
470 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
471 #if defined(CONFIG_88EU_AP_MODE)
474 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
475 #endif /* if defined (CONFIG_88EU_AP_MODE) */
476 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
477 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
478 struct wlan_bssid_ex
*cur_network
= &(pmlmeinfo
->network
);
479 unsigned int rate_len
;
481 pmgntframe
= alloc_mgtxmitframe(pxmitpriv
);
482 if (pmgntframe
== NULL
) {
483 DBG_88E("%s, alloc mgnt frame fail\n", __func__
);
487 /* update attribute */
488 pattrib
= &pmgntframe
->attrib
;
489 update_mgntframe_attrib(padapter
, pattrib
);
491 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
493 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
494 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
496 mac
= myid(&(padapter
->eeprompriv
));
497 bssid
= cur_network
->MacAddress
;
499 fctrl
= &(pwlanhdr
->frame_ctl
);
501 memcpy(pwlanhdr
->addr1
, da
, ETH_ALEN
);
502 memcpy(pwlanhdr
->addr2
, mac
, ETH_ALEN
);
503 memcpy(pwlanhdr
->addr3
, bssid
, ETH_ALEN
);
505 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
506 pmlmeext
->mgnt_seq
++;
507 SetFrameSubType(fctrl
, WIFI_PROBERSP
);
509 pattrib
->hdrlen
= sizeof(struct rtw_ieee80211_hdr_3addr
);
510 pattrib
->pktlen
= pattrib
->hdrlen
;
511 pframe
+= pattrib
->hdrlen
;
513 if (cur_network
->IELength
> MAX_IE_SZ
)
516 #if defined(CONFIG_88EU_AP_MODE)
517 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
) {
518 pwps_ie
= rtw_get_wps_ie(cur_network
->IEs
+_FIXED_IE_LENGTH_
, cur_network
->IELength
-_FIXED_IE_LENGTH_
, NULL
, &wps_ielen
);
520 /* inerset & update wps_probe_resp_ie */
521 if ((pmlmepriv
->wps_probe_resp_ie
!= NULL
) && pwps_ie
&& (wps_ielen
> 0)) {
522 uint wps_offset
, remainder_ielen
;
525 wps_offset
= (uint
)(pwps_ie
- cur_network
->IEs
);
527 premainder_ie
= pwps_ie
+ wps_ielen
;
529 remainder_ielen
= cur_network
->IELength
- wps_offset
- wps_ielen
;
531 memcpy(pframe
, cur_network
->IEs
, wps_offset
);
532 pframe
+= wps_offset
;
533 pattrib
->pktlen
+= wps_offset
;
535 wps_ielen
= (uint
)pmlmepriv
->wps_probe_resp_ie
[1];/* to get ie data len */
536 if ((wps_offset
+wps_ielen
+2) <= MAX_IE_SZ
) {
537 memcpy(pframe
, pmlmepriv
->wps_probe_resp_ie
, wps_ielen
+2);
538 pframe
+= wps_ielen
+2;
539 pattrib
->pktlen
+= wps_ielen
+2;
542 if ((wps_offset
+wps_ielen
+2+remainder_ielen
) <= MAX_IE_SZ
) {
543 memcpy(pframe
, premainder_ie
, remainder_ielen
);
544 pframe
+= remainder_ielen
;
545 pattrib
->pktlen
+= remainder_ielen
;
548 memcpy(pframe
, cur_network
->IEs
, cur_network
->IELength
);
549 pframe
+= cur_network
->IELength
;
550 pattrib
->pktlen
+= cur_network
->IELength
;
555 /* timestamp will be inserted by hardware */
557 pattrib
->pktlen
+= 8;
559 /* beacon interval: 2 bytes */
561 memcpy(pframe
, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network
->IEs
)), 2);
564 pattrib
->pktlen
+= 2;
566 /* capability info: 2 bytes */
568 memcpy(pframe
, (unsigned char *)(rtw_get_capability_from_ie(cur_network
->IEs
)), 2);
571 pattrib
->pktlen
+= 2;
573 /* below for ad-hoc mode */
576 pframe
= rtw_set_ie(pframe
, _SSID_IE_
, cur_network
->Ssid
.SsidLength
, cur_network
->Ssid
.Ssid
, &pattrib
->pktlen
);
578 /* supported rates... */
579 rate_len
= rtw_get_rateset_len(cur_network
->SupportedRates
);
580 pframe
= rtw_set_ie(pframe
, _SUPPORTEDRATES_IE_
, ((rate_len
> 8) ? 8 : rate_len
), cur_network
->SupportedRates
, &pattrib
->pktlen
);
582 /* DS parameter set */
583 pframe
= rtw_set_ie(pframe
, _DSSET_IE_
, 1, (unsigned char *)&(cur_network
->Configuration
.DSConfig
), &pattrib
->pktlen
);
585 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_ADHOC_STATE
) {
588 /* IBSS Parameter Set... */
589 /* ATIMWindow = cur->Configuration.ATIMWindow; */
591 pframe
= rtw_set_ie(pframe
, _IBSS_PARA_IE_
, 2, (unsigned char *)(&ATIMWindow
), &pattrib
->pktlen
);
594 pframe
= rtw_set_ie(pframe
, _ERPINFO_IE_
, 1, &erpinfo
, &pattrib
->pktlen
);
598 /* EXTERNDED SUPPORTED RATE */
600 pframe
= rtw_set_ie(pframe
, _EXT_SUPPORTEDRATES_IE_
, (rate_len
- 8), (cur_network
->SupportedRates
+ 8), &pattrib
->pktlen
);
601 /* todo:HT for adhoc */
604 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
606 dump_mgntframe(padapter
, pmgntframe
);
611 static int _issue_probereq(struct adapter
*padapter
, struct ndis_802_11_ssid
*pssid
, u8
*da
, int wait_ack
)
614 struct xmit_frame
*pmgntframe
;
615 struct pkt_attrib
*pattrib
;
616 unsigned char *pframe
;
617 struct rtw_ieee80211_hdr
*pwlanhdr
;
620 unsigned char bssrate
[NumRates
];
621 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
622 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
623 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
625 u8 bc_addr
[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
627 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
, ("+issue_probereq\n"));
629 pmgntframe
= alloc_mgtxmitframe(pxmitpriv
);
630 if (pmgntframe
== NULL
)
633 /* update attribute */
634 pattrib
= &pmgntframe
->attrib
;
635 update_mgntframe_attrib(padapter
, pattrib
);
638 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
640 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
641 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
643 mac
= myid(&(padapter
->eeprompriv
));
645 fctrl
= &(pwlanhdr
->frame_ctl
);
649 /* unicast probe request frame */
650 memcpy(pwlanhdr
->addr1
, da
, ETH_ALEN
);
651 memcpy(pwlanhdr
->addr3
, da
, ETH_ALEN
);
653 /* broadcast probe request frame */
654 memcpy(pwlanhdr
->addr1
, bc_addr
, ETH_ALEN
);
655 memcpy(pwlanhdr
->addr3
, bc_addr
, ETH_ALEN
);
658 memcpy(pwlanhdr
->addr2
, mac
, ETH_ALEN
);
660 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
661 pmlmeext
->mgnt_seq
++;
662 SetFrameSubType(pframe
, WIFI_PROBEREQ
);
664 pframe
+= sizeof(struct rtw_ieee80211_hdr_3addr
);
665 pattrib
->pktlen
= sizeof(struct rtw_ieee80211_hdr_3addr
);
668 pframe
= rtw_set_ie(pframe
, _SSID_IE_
, pssid
->SsidLength
, pssid
->Ssid
, &(pattrib
->pktlen
));
670 pframe
= rtw_set_ie(pframe
, _SSID_IE_
, 0, NULL
, &(pattrib
->pktlen
));
672 get_rate_set(padapter
, bssrate
, &bssrate_len
);
674 if (bssrate_len
> 8) {
675 pframe
= rtw_set_ie(pframe
, _SUPPORTEDRATES_IE_
, 8, bssrate
, &(pattrib
->pktlen
));
676 pframe
= rtw_set_ie(pframe
, _EXT_SUPPORTEDRATES_IE_
, (bssrate_len
- 8), (bssrate
+ 8), &(pattrib
->pktlen
));
678 pframe
= rtw_set_ie(pframe
, _SUPPORTEDRATES_IE_
, bssrate_len
, bssrate
, &(pattrib
->pktlen
));
681 /* add wps_ie for wps2.0 */
682 if (pmlmepriv
->wps_probe_req_ie_len
> 0 && pmlmepriv
->wps_probe_req_ie
) {
683 memcpy(pframe
, pmlmepriv
->wps_probe_req_ie
, pmlmepriv
->wps_probe_req_ie_len
);
684 pframe
+= pmlmepriv
->wps_probe_req_ie_len
;
685 pattrib
->pktlen
+= pmlmepriv
->wps_probe_req_ie_len
;
688 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
690 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
691 ("issuing probe_req, tx_len=%d\n", pattrib
->last_txcmdsz
));
694 ret
= dump_mgntframe_and_wait_ack(padapter
, pmgntframe
);
696 dump_mgntframe(padapter
, pmgntframe
);
704 static inline void issue_probereq(struct adapter
*padapter
,
705 struct ndis_802_11_ssid
*pssid
, u8
*da
)
707 _issue_probereq(padapter
, pssid
, da
, false);
710 static int issue_probereq_ex(struct adapter
*padapter
,
711 struct ndis_802_11_ssid
*pssid
, u8
*da
,
712 int try_cnt
, int wait_ms
)
719 ret
= _issue_probereq(padapter
, pssid
, da
, wait_ms
> 0 ? true : false);
723 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
)
726 if (i
< try_cnt
&& wait_ms
> 0 && ret
== _FAIL
)
729 } while ((i
< try_cnt
) && ((ret
== _FAIL
) || (wait_ms
== 0)));
736 if (try_cnt
&& wait_ms
) {
738 DBG_88E(FUNC_ADPT_FMT
" to %pM, ch:%u%s, %d/%d in %u ms\n",
739 FUNC_ADPT_ARG(padapter
), da
, rtw_get_oper_ch(padapter
),
740 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
, rtw_get_passing_time_ms(start
));
742 DBG_88E(FUNC_ADPT_FMT
", ch:%u%s, %d/%d in %u ms\n",
743 FUNC_ADPT_ARG(padapter
), rtw_get_oper_ch(padapter
),
744 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
, rtw_get_passing_time_ms(start
));
750 /* if psta == NULL, indicate we are station(client) now... */
751 static void issue_auth(struct adapter
*padapter
, struct sta_info
*psta
,
752 unsigned short status
)
754 struct xmit_frame
*pmgntframe
;
755 struct pkt_attrib
*pattrib
;
756 unsigned char *pframe
;
757 struct rtw_ieee80211_hdr
*pwlanhdr
;
761 #ifdef CONFIG_88EU_AP_MODE
764 int use_shared_key
= 0;
765 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
766 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
767 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
768 struct wlan_bssid_ex
*pnetwork
= &(pmlmeinfo
->network
);
770 pmgntframe
= alloc_mgtxmitframe(pxmitpriv
);
771 if (pmgntframe
== NULL
)
774 /* update attribute */
775 pattrib
= &pmgntframe
->attrib
;
776 update_mgntframe_attrib(padapter
, pattrib
);
778 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
780 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
781 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
783 fctrl
= &(pwlanhdr
->frame_ctl
);
786 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
787 pmlmeext
->mgnt_seq
++;
788 SetFrameSubType(pframe
, WIFI_AUTH
);
790 pframe
+= sizeof(struct rtw_ieee80211_hdr_3addr
);
791 pattrib
->pktlen
= sizeof(struct rtw_ieee80211_hdr_3addr
);
794 if (psta
) {/* for AP mode */
795 #ifdef CONFIG_88EU_AP_MODE
797 memcpy(pwlanhdr
->addr1
, psta
->hwaddr
, ETH_ALEN
);
798 memcpy(pwlanhdr
->addr2
, myid(&(padapter
->eeprompriv
)), ETH_ALEN
);
799 memcpy(pwlanhdr
->addr3
, myid(&(padapter
->eeprompriv
)), ETH_ALEN
);
802 /* setting auth algo number */
803 val16
= (u16
)psta
->authalg
;
805 if (status
!= _STATS_SUCCESSFUL_
)
809 le_val16
= cpu_to_le16(val16
);
815 pframe
= rtw_set_fixed_ie(pframe
, _AUTH_ALGM_NUM_
, (unsigned char *)&le_val16
, &(pattrib
->pktlen
));
817 /* setting auth seq number */
818 val16
= (u16
)psta
->auth_seq
;
819 le_val16
= cpu_to_le16(val16
);
820 pframe
= rtw_set_fixed_ie(pframe
, _AUTH_SEQ_NUM_
, (unsigned char *)&le_val16
, &(pattrib
->pktlen
));
822 /* setting status code... */
824 le_val16
= cpu_to_le16(val16
);
825 pframe
= rtw_set_fixed_ie(pframe
, _STATUS_CODE_
, (unsigned char *)&le_val16
, &(pattrib
->pktlen
));
827 /* added challenging text... */
828 if ((psta
->auth_seq
== 2) && (psta
->state
& WIFI_FW_AUTH_STATE
) && (use_shared_key
== 1))
829 pframe
= rtw_set_ie(pframe
, _CHLGETXT_IE_
, 128, psta
->chg_txt
, &(pattrib
->pktlen
));
834 memcpy(pwlanhdr
->addr1
, pnetwork
->MacAddress
, ETH_ALEN
);
835 memcpy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
), ETH_ALEN
);
836 memcpy(pwlanhdr
->addr3
, pnetwork
->MacAddress
, ETH_ALEN
);
838 /* setting auth algo number */
839 val16
= (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_Shared
) ? 1 : 0;/* 0:OPEN System, 1:Shared key */
843 /* setting IV for auth seq #3 */
844 if ((pmlmeinfo
->auth_seq
== 3) && (pmlmeinfo
->state
& WIFI_FW_AUTH_STATE
) && (use_shared_key
== 1)) {
845 val32
= (pmlmeinfo
->iv
++) | (pmlmeinfo
->key_index
<< 30);
846 le_tmp32
= cpu_to_le32(val32
);
847 pframe
= rtw_set_fixed_ie(pframe
, 4, (unsigned char *)&le_tmp32
, &(pattrib
->pktlen
));
852 le_tmp16
= cpu_to_le16(val16
);
853 pframe
= rtw_set_fixed_ie(pframe
, _AUTH_ALGM_NUM_
, (unsigned char *)&le_tmp16
, &(pattrib
->pktlen
));
855 /* setting auth seq number */
856 val16
= pmlmeinfo
->auth_seq
;
857 le_tmp16
= cpu_to_le16(val16
);
858 pframe
= rtw_set_fixed_ie(pframe
, _AUTH_SEQ_NUM_
, (unsigned char *)&le_tmp16
, &(pattrib
->pktlen
));
861 /* setting status code... */
862 le_tmp16
= cpu_to_le16(status
);
863 pframe
= rtw_set_fixed_ie(pframe
, _STATUS_CODE_
, (unsigned char *)&le_tmp16
, &(pattrib
->pktlen
));
865 /* then checking to see if sending challenging text... */
866 if ((pmlmeinfo
->auth_seq
== 3) && (pmlmeinfo
->state
& WIFI_FW_AUTH_STATE
) && (use_shared_key
== 1)) {
867 pframe
= rtw_set_ie(pframe
, _CHLGETXT_IE_
, 128, pmlmeinfo
->chg_txt
, &(pattrib
->pktlen
));
871 pattrib
->hdrlen
= sizeof(struct rtw_ieee80211_hdr_3addr
);
873 pattrib
->encrypt
= _WEP40_
;
875 pattrib
->icv_len
= 4;
877 pattrib
->pktlen
+= pattrib
->icv_len
;
881 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
883 rtw_wep_encrypt(padapter
, (u8
*)pmgntframe
);
884 DBG_88E("%s\n", __func__
);
885 dump_mgntframe(padapter
, pmgntframe
);
891 #ifdef CONFIG_88EU_AP_MODE
892 static void issue_asocrsp(struct adapter
*padapter
, unsigned short status
,
893 struct sta_info
*pstat
, int pkt_type
)
895 struct xmit_frame
*pmgntframe
;
896 struct rtw_ieee80211_hdr
*pwlanhdr
;
897 struct pkt_attrib
*pattrib
;
898 unsigned char *pbuf
, *pframe
;
901 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
902 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
903 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
904 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
905 struct wlan_bssid_ex
*pnetwork
= &(pmlmeinfo
->network
);
906 u8
*ie
= pnetwork
->IEs
;
907 __le16 lestatus
, leval
;
909 DBG_88E("%s\n", __func__
);
911 pmgntframe
= alloc_mgtxmitframe(pxmitpriv
);
912 if (pmgntframe
== NULL
)
915 /* update attribute */
916 pattrib
= &pmgntframe
->attrib
;
917 update_mgntframe_attrib(padapter
, pattrib
);
920 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
922 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
923 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
925 fctrl
= &(pwlanhdr
->frame_ctl
);
928 memcpy((void *)GetAddr1Ptr(pwlanhdr
), pstat
->hwaddr
, ETH_ALEN
);
929 memcpy((void *)GetAddr2Ptr(pwlanhdr
), myid(&(padapter
->eeprompriv
)), ETH_ALEN
);
930 memcpy((void *)GetAddr3Ptr(pwlanhdr
), pnetwork
->MacAddress
, ETH_ALEN
);
933 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
934 pmlmeext
->mgnt_seq
++;
935 if ((pkt_type
== WIFI_ASSOCRSP
) || (pkt_type
== WIFI_REASSOCRSP
))
936 SetFrameSubType(pwlanhdr
, pkt_type
);
940 pattrib
->hdrlen
= sizeof(struct rtw_ieee80211_hdr_3addr
);
941 pattrib
->pktlen
+= pattrib
->hdrlen
;
942 pframe
+= pattrib
->hdrlen
;
945 val
= *(unsigned short *)rtw_get_capability_from_ie(ie
);
947 pframe
= rtw_set_fixed_ie(pframe
, _CAPABILITY_
, (unsigned char *)&val
, &(pattrib
->pktlen
));
949 lestatus
= cpu_to_le16(status
);
950 pframe
= rtw_set_fixed_ie(pframe
, _STATUS_CODE_
, (unsigned char *)&lestatus
, &(pattrib
->pktlen
));
952 leval
= cpu_to_le16(pstat
->aid
| BIT(14) | BIT(15));
953 pframe
= rtw_set_fixed_ie(pframe
, _ASOC_ID_
, (unsigned char *)&leval
, &(pattrib
->pktlen
));
955 if (pstat
->bssratelen
<= 8) {
956 pframe
= rtw_set_ie(pframe
, _SUPPORTEDRATES_IE_
, pstat
->bssratelen
, pstat
->bssrateset
, &(pattrib
->pktlen
));
958 pframe
= rtw_set_ie(pframe
, _SUPPORTEDRATES_IE_
, 8, pstat
->bssrateset
, &(pattrib
->pktlen
));
959 pframe
= rtw_set_ie(pframe
, _EXT_SUPPORTEDRATES_IE_
, (pstat
->bssratelen
-8), pstat
->bssrateset
+8, &(pattrib
->pktlen
));
962 if ((pstat
->flags
& WLAN_STA_HT
) && (pmlmepriv
->htpriv
.ht_option
)) {
965 /* FILL HT CAP INFO IE */
966 pbuf
= rtw_get_ie(ie
+ _BEACON_IE_OFFSET_
, _HT_CAPABILITY_IE_
, &ie_len
, (pnetwork
->IELength
- _BEACON_IE_OFFSET_
));
967 if (pbuf
&& ie_len
> 0) {
968 memcpy(pframe
, pbuf
, ie_len
+2);
969 pframe
+= (ie_len
+2);
970 pattrib
->pktlen
+= (ie_len
+2);
973 /* FILL HT ADD INFO IE */
974 pbuf
= rtw_get_ie(ie
+ _BEACON_IE_OFFSET_
, _HT_ADD_INFO_IE_
, &ie_len
, (pnetwork
->IELength
- _BEACON_IE_OFFSET_
));
975 if (pbuf
&& ie_len
> 0) {
976 memcpy(pframe
, pbuf
, ie_len
+2);
977 pframe
+= (ie_len
+2);
978 pattrib
->pktlen
+= (ie_len
+2);
983 if ((pstat
->flags
& WLAN_STA_WME
) && (pmlmepriv
->qospriv
.qos_option
)) {
985 unsigned char WMM_PARA_IE
[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
987 for (pbuf
= ie
+ _BEACON_IE_OFFSET_
;; pbuf
+= (ie_len
+ 2)) {
988 pbuf
= rtw_get_ie(pbuf
, _VENDOR_SPECIFIC_IE_
, &ie_len
, (pnetwork
->IELength
- _BEACON_IE_OFFSET_
- (ie_len
+ 2)));
989 if (pbuf
&& !memcmp(pbuf
+2, WMM_PARA_IE
, 6)) {
990 memcpy(pframe
, pbuf
, ie_len
+2);
991 pframe
+= (ie_len
+2);
992 pattrib
->pktlen
+= (ie_len
+2);
996 if ((pbuf
== NULL
) || (ie_len
== 0))
1001 if (pmlmeinfo
->assoc_AP_vendor
== HT_IOT_PEER_REALTEK
)
1002 pframe
= rtw_set_ie(pframe
, _VENDOR_SPECIFIC_IE_
, 6 , REALTEK_96B_IE
, &(pattrib
->pktlen
));
1004 /* add WPS IE ie for wps 2.0 */
1005 if (pmlmepriv
->wps_assoc_resp_ie
&& pmlmepriv
->wps_assoc_resp_ie_len
> 0) {
1006 memcpy(pframe
, pmlmepriv
->wps_assoc_resp_ie
, pmlmepriv
->wps_assoc_resp_ie_len
);
1008 pframe
+= pmlmepriv
->wps_assoc_resp_ie_len
;
1009 pattrib
->pktlen
+= pmlmepriv
->wps_assoc_resp_ie_len
;
1012 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
1013 dump_mgntframe(padapter
, pmgntframe
);
1015 #endif /* CONFIG_88EU_AP_MODE */
1017 static void issue_assocreq(struct adapter
*padapter
)
1020 struct xmit_frame
*pmgntframe
;
1021 struct pkt_attrib
*pattrib
;
1022 unsigned char *pframe
, *p
;
1023 struct rtw_ieee80211_hdr
*pwlanhdr
;
1026 unsigned int i
, j
, ie_len
, index
= 0;
1027 unsigned char rf_type
, bssrate
[NumRates
], sta_bssrate
[NumRates
];
1028 struct ndis_802_11_var_ie
*pIE
;
1029 struct registry_priv
*pregpriv
= &padapter
->registrypriv
;
1030 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
1031 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1032 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1033 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1034 int bssrate_len
= 0, sta_bssrate_len
= 0;
1035 struct wlan_bssid_ex
*pnetwork
= &(pmlmeinfo
->network
);
1037 pmgntframe
= alloc_mgtxmitframe(pxmitpriv
);
1038 if (pmgntframe
== NULL
)
1041 /* update attribute */
1042 pattrib
= &pmgntframe
->attrib
;
1043 update_mgntframe_attrib(padapter
, pattrib
);
1045 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
1046 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
1047 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
1049 fctrl
= &(pwlanhdr
->frame_ctl
);
1051 memcpy(pwlanhdr
->addr1
, pnetwork
->MacAddress
, ETH_ALEN
);
1052 memcpy(pwlanhdr
->addr2
, myid(&(padapter
->eeprompriv
)), ETH_ALEN
);
1053 memcpy(pwlanhdr
->addr3
, pnetwork
->MacAddress
, ETH_ALEN
);
1055 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
1056 pmlmeext
->mgnt_seq
++;
1057 SetFrameSubType(pframe
, WIFI_ASSOCREQ
);
1059 pframe
+= sizeof(struct rtw_ieee80211_hdr_3addr
);
1060 pattrib
->pktlen
= sizeof(struct rtw_ieee80211_hdr_3addr
);
1064 memcpy(pframe
, rtw_get_capability_from_ie(pmlmeinfo
->network
.IEs
), 2);
1067 pattrib
->pktlen
+= 2;
1069 /* listen interval */
1070 /* todo: listen interval for power saving */
1071 le_tmp
= cpu_to_le16(3);
1072 memcpy(pframe
, (unsigned char *)&le_tmp
, 2);
1074 pattrib
->pktlen
+= 2;
1077 pframe
= rtw_set_ie(pframe
, _SSID_IE_
, pmlmeinfo
->network
.Ssid
.SsidLength
, pmlmeinfo
->network
.Ssid
.Ssid
, &(pattrib
->pktlen
));
1079 /* supported rate & extended supported rate */
1081 /* Check if the AP's supported rates are also supported by STA. */
1082 get_rate_set(padapter
, sta_bssrate
, &sta_bssrate_len
);
1084 if (pmlmeext
->cur_channel
== 14)/* for JAPAN, channel 14 can only uses B Mode(CCK) */
1085 sta_bssrate_len
= 4;
1087 for (i
= 0; i
< NDIS_802_11_LENGTH_RATES_EX
; i
++) {
1088 if (pmlmeinfo
->network
.SupportedRates
[i
] == 0)
1090 DBG_88E("network.SupportedRates[%d]=%02X\n", i
, pmlmeinfo
->network
.SupportedRates
[i
]);
1093 for (i
= 0; i
< NDIS_802_11_LENGTH_RATES_EX
; i
++) {
1094 if (pmlmeinfo
->network
.SupportedRates
[i
] == 0)
1097 /* Check if the AP's supported rates are also supported by STA. */
1098 for (j
= 0; j
< sta_bssrate_len
; j
++) {
1099 /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
1100 if ((pmlmeinfo
->network
.SupportedRates
[i
]|IEEE80211_BASIC_RATE_MASK
)
1101 == (sta_bssrate
[j
]|IEEE80211_BASIC_RATE_MASK
))
1105 if (j
== sta_bssrate_len
) {
1106 /* the rate is not supported by STA */
1107 DBG_88E("%s(): the rate[%d]=%02X is not supported by STA!\n", __func__
, i
, pmlmeinfo
->network
.SupportedRates
[i
]);
1109 /* the rate is supported by STA */
1110 bssrate
[index
++] = pmlmeinfo
->network
.SupportedRates
[i
];
1114 bssrate_len
= index
;
1115 DBG_88E("bssrate_len=%d\n", bssrate_len
);
1117 if (bssrate_len
== 0) {
1118 rtw_free_xmitbuf(pxmitpriv
, pmgntframe
->pxmitbuf
);
1119 rtw_free_xmitframe(pxmitpriv
, pmgntframe
);
1120 goto exit
; /* don't connect to AP if no joint supported rate */
1124 if (bssrate_len
> 8) {
1125 pframe
= rtw_set_ie(pframe
, _SUPPORTEDRATES_IE_
, 8, bssrate
, &(pattrib
->pktlen
));
1126 pframe
= rtw_set_ie(pframe
, _EXT_SUPPORTEDRATES_IE_
, (bssrate_len
- 8), (bssrate
+ 8), &(pattrib
->pktlen
));
1128 pframe
= rtw_set_ie(pframe
, _SUPPORTEDRATES_IE_
, bssrate_len
, bssrate
, &(pattrib
->pktlen
));
1132 p
= rtw_get_ie((pmlmeinfo
->network
.IEs
+ sizeof(struct ndis_802_11_fixed_ie
)), _RSN_IE_2_
, &ie_len
, (pmlmeinfo
->network
.IELength
- sizeof(struct ndis_802_11_fixed_ie
)));
1134 pframe
= rtw_set_ie(pframe
, _RSN_IE_2_
, ie_len
, (p
+ 2), &(pattrib
->pktlen
));
1137 if (padapter
->mlmepriv
.htpriv
.ht_option
) {
1138 p
= rtw_get_ie((pmlmeinfo
->network
.IEs
+ sizeof(struct ndis_802_11_fixed_ie
)), _HT_CAPABILITY_IE_
, &ie_len
, (pmlmeinfo
->network
.IELength
- sizeof(struct ndis_802_11_fixed_ie
)));
1139 if ((p
!= NULL
) && (!(is_ap_in_tkip(padapter
)))) {
1140 memcpy(&(pmlmeinfo
->HT_caps
), (p
+ 2), sizeof(struct HT_caps_element
));
1142 /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
1143 if (pregpriv
->cbw40_enable
== 0)
1144 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
&= cpu_to_le16(~(BIT(6) | BIT(1)));
1146 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
|= cpu_to_le16(BIT(1));
1148 /* todo: disable SM power save mode */
1149 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
|= cpu_to_le16(0x000c);
1151 rtw_hal_get_hwreg(padapter
, HW_VAR_RF_TYPE
, (u8
*)(&rf_type
));
1154 if (pregpriv
->rx_stbc
)
1155 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
|= cpu_to_le16(0x0100);/* RX STBC One spatial stream */
1156 memcpy(pmlmeinfo
->HT_caps
.u
.HT_cap_element
.MCS_rate
, MCS_rate_1R
, 16);
1161 if ((pregpriv
->rx_stbc
== 0x3) ||/* enable for 2.4/5 GHz */
1162 ((pmlmeext
->cur_wireless_mode
& WIRELESS_11_24N
) && (pregpriv
->rx_stbc
== 0x1)) || /* enable for 2.4GHz */
1163 (pregpriv
->wifi_spec
== 1)) {
1164 DBG_88E("declare supporting RX STBC\n");
1165 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
|= cpu_to_le16(0x0200);/* RX STBC two spatial stream */
1167 memcpy(pmlmeinfo
->HT_caps
.u
.HT_cap_element
.MCS_rate
, MCS_rate_2R
, 16);
1170 pframe
= rtw_set_ie(pframe
, _HT_CAPABILITY_IE_
, ie_len
, (u8
*)(&(pmlmeinfo
->HT_caps
)), &(pattrib
->pktlen
));
1174 /* vendor specific IE, such as WPA, WMM, WPS */
1175 for (i
= sizeof(struct ndis_802_11_fixed_ie
); i
< pmlmeinfo
->network
.IELength
;) {
1176 pIE
= (struct ndis_802_11_var_ie
*)(pmlmeinfo
->network
.IEs
+ i
);
1178 switch (pIE
->ElementID
) {
1179 case _VENDOR_SPECIFIC_IE_
:
1180 if ((!memcmp(pIE
->data
, RTW_WPA_OUI
, 4)) ||
1181 (!memcmp(pIE
->data
, WMM_OUI
, 4)) ||
1182 (!memcmp(pIE
->data
, WPS_OUI
, 4))) {
1183 if (!padapter
->registrypriv
.wifi_spec
) {
1184 /* Commented by Kurt 20110629 */
1185 /* In some older APs, WPS handshake */
1186 /* would be fail if we append vender extensions informations to AP */
1187 if (!memcmp(pIE
->data
, WPS_OUI
, 4))
1190 pframe
= rtw_set_ie(pframe
, _VENDOR_SPECIFIC_IE_
, pIE
->Length
, pIE
->data
, &(pattrib
->pktlen
));
1196 i
+= (pIE
->Length
+ 2);
1199 if (pmlmeinfo
->assoc_AP_vendor
== HT_IOT_PEER_REALTEK
)
1200 pframe
= rtw_set_ie(pframe
, _VENDOR_SPECIFIC_IE_
, 6 , REALTEK_96B_IE
, &(pattrib
->pktlen
));
1202 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
1203 dump_mgntframe(padapter
, pmgntframe
);
1208 if (ret
== _SUCCESS
)
1209 rtw_buf_update(&pmlmepriv
->assoc_req
, &pmlmepriv
->assoc_req_len
, (u8
*)pwlanhdr
, pattrib
->pktlen
);
1211 rtw_buf_free(&pmlmepriv
->assoc_req
, &pmlmepriv
->assoc_req_len
);
1216 /* when wait_ack is true, this function should be called at process context */
1217 static int _issue_nulldata(struct adapter
*padapter
, unsigned char *da
, unsigned int power_mode
, int wait_ack
)
1220 struct xmit_frame
*pmgntframe
;
1221 struct pkt_attrib
*pattrib
;
1222 unsigned char *pframe
;
1223 struct rtw_ieee80211_hdr
*pwlanhdr
;
1225 struct xmit_priv
*pxmitpriv
;
1226 struct mlme_ext_priv
*pmlmeext
;
1227 struct mlme_ext_info
*pmlmeinfo
;
1228 struct wlan_bssid_ex
*pnetwork
;
1233 pxmitpriv
= &(padapter
->xmitpriv
);
1234 pmlmeext
= &(padapter
->mlmeextpriv
);
1235 pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1236 pnetwork
= &(pmlmeinfo
->network
);
1238 pmgntframe
= alloc_mgtxmitframe(pxmitpriv
);
1239 if (pmgntframe
== NULL
)
1242 /* update attribute */
1243 pattrib
= &pmgntframe
->attrib
;
1244 update_mgntframe_attrib(padapter
, pattrib
);
1245 pattrib
->retry_ctrl
= false;
1247 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
1249 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
1250 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
1252 fctrl
= &(pwlanhdr
->frame_ctl
);
1255 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
)
1257 else if ((pmlmeinfo
->state
&0x03) == WIFI_FW_STATION_STATE
)
1263 memcpy(pwlanhdr
->addr1
, da
, ETH_ALEN
);
1264 memcpy(pwlanhdr
->addr2
, myid(&(padapter
->eeprompriv
)), ETH_ALEN
);
1265 memcpy(pwlanhdr
->addr3
, pnetwork
->MacAddress
, ETH_ALEN
);
1267 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
1268 pmlmeext
->mgnt_seq
++;
1269 SetFrameSubType(pframe
, WIFI_DATA_NULL
);
1271 pframe
+= sizeof(struct rtw_ieee80211_hdr_3addr
);
1272 pattrib
->pktlen
= sizeof(struct rtw_ieee80211_hdr_3addr
);
1274 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
1277 ret
= dump_mgntframe_and_wait_ack(padapter
, pmgntframe
);
1279 dump_mgntframe(padapter
, pmgntframe
);
1288 /* when wait_ms > 0 , this function should be called at process context */
1289 /* da == NULL for station mode */
1290 int issue_nulldata(struct adapter
*padapter
, unsigned char *da
, unsigned int power_mode
, int try_cnt
, int wait_ms
)
1294 u32 start
= jiffies
;
1295 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1296 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1297 struct wlan_bssid_ex
*pnetwork
= &(pmlmeinfo
->network
);
1299 /* da == NULL, assume it's null data for sta to ap*/
1301 da
= pnetwork
->MacAddress
;
1304 ret
= _issue_nulldata(padapter
, da
, power_mode
, wait_ms
> 0 ? true : false);
1308 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
)
1311 if (i
< try_cnt
&& wait_ms
> 0 && ret
== _FAIL
)
1313 } while ((i
< try_cnt
) && ((ret
== _FAIL
) || (wait_ms
== 0)));
1320 if (try_cnt
&& wait_ms
) {
1322 DBG_88E(FUNC_ADPT_FMT
" to %pM, ch:%u%s, %d/%d in %u ms\n",
1323 FUNC_ADPT_ARG(padapter
), da
, rtw_get_oper_ch(padapter
),
1324 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
, rtw_get_passing_time_ms(start
));
1326 DBG_88E(FUNC_ADPT_FMT
", ch:%u%s, %d/%d in %u ms\n",
1327 FUNC_ADPT_ARG(padapter
), rtw_get_oper_ch(padapter
),
1328 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
, rtw_get_passing_time_ms(start
));
1334 /* when wait_ack is true, this function should be called at process context */
1335 static int _issue_qos_nulldata(struct adapter
*padapter
, unsigned char *da
, u16 tid
, int wait_ack
)
1338 struct xmit_frame
*pmgntframe
;
1339 struct pkt_attrib
*pattrib
;
1340 unsigned char *pframe
;
1341 struct rtw_ieee80211_hdr
*pwlanhdr
;
1344 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
1345 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1346 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1347 struct wlan_bssid_ex
*pnetwork
= &(pmlmeinfo
->network
);
1349 DBG_88E("%s\n", __func__
);
1351 pmgntframe
= alloc_mgtxmitframe(pxmitpriv
);
1352 if (pmgntframe
== NULL
)
1355 /* update attribute */
1356 pattrib
= &pmgntframe
->attrib
;
1357 update_mgntframe_attrib(padapter
, pattrib
);
1359 pattrib
->hdrlen
+= 2;
1360 pattrib
->qos_en
= true;
1362 pattrib
->ack_policy
= 0;
1365 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
1367 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
1368 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
1370 fctrl
= &(pwlanhdr
->frame_ctl
);
1373 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
)
1375 else if ((pmlmeinfo
->state
&0x03) == WIFI_FW_STATION_STATE
)
1381 qc
= (unsigned short *)(pframe
+ pattrib
->hdrlen
- 2);
1383 SetPriority(qc
, tid
);
1385 SetEOSP(qc
, pattrib
->eosp
);
1387 SetAckpolicy(qc
, pattrib
->ack_policy
);
1389 memcpy(pwlanhdr
->addr1
, da
, ETH_ALEN
);
1390 memcpy(pwlanhdr
->addr2
, myid(&(padapter
->eeprompriv
)), ETH_ALEN
);
1391 memcpy(pwlanhdr
->addr3
, pnetwork
->MacAddress
, ETH_ALEN
);
1393 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
1394 pmlmeext
->mgnt_seq
++;
1395 SetFrameSubType(pframe
, WIFI_QOS_DATA_NULL
);
1397 pframe
+= sizeof(struct rtw_ieee80211_hdr_3addr_qos
);
1398 pattrib
->pktlen
= sizeof(struct rtw_ieee80211_hdr_3addr_qos
);
1400 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
1403 ret
= dump_mgntframe_and_wait_ack(padapter
, pmgntframe
);
1405 dump_mgntframe(padapter
, pmgntframe
);
1413 /* when wait_ms > 0 , this function should be called at process context */
1414 /* da == NULL for station mode */
1415 int issue_qos_nulldata(struct adapter
*padapter
, unsigned char *da
, u16 tid
, int try_cnt
, int wait_ms
)
1419 u32 start
= jiffies
;
1420 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1421 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1422 struct wlan_bssid_ex
*pnetwork
= &(pmlmeinfo
->network
);
1424 /* da == NULL, assume it's null data for sta to ap*/
1426 da
= pnetwork
->MacAddress
;
1429 ret
= _issue_qos_nulldata(padapter
, da
, tid
, wait_ms
> 0 ? true : false);
1433 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
)
1436 if (i
< try_cnt
&& wait_ms
> 0 && ret
== _FAIL
)
1438 } while ((i
< try_cnt
) && ((ret
== _FAIL
) || (wait_ms
== 0)));
1445 if (try_cnt
&& wait_ms
) {
1447 DBG_88E(FUNC_ADPT_FMT
" to %pM, ch:%u%s, %d/%d in %u ms\n",
1448 FUNC_ADPT_ARG(padapter
), da
, rtw_get_oper_ch(padapter
),
1449 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
, rtw_get_passing_time_ms(start
));
1451 DBG_88E(FUNC_ADPT_FMT
", ch:%u%s, %d/%d in %u ms\n",
1452 FUNC_ADPT_ARG(padapter
), rtw_get_oper_ch(padapter
),
1453 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
, rtw_get_passing_time_ms(start
));
1459 static int _issue_deauth(struct adapter
*padapter
, unsigned char *da
, unsigned short reason
, u8 wait_ack
)
1461 struct xmit_frame
*pmgntframe
;
1462 struct pkt_attrib
*pattrib
;
1463 unsigned char *pframe
;
1464 struct rtw_ieee80211_hdr
*pwlanhdr
;
1466 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
1467 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1468 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1469 struct wlan_bssid_ex
*pnetwork
= &(pmlmeinfo
->network
);
1473 pmgntframe
= alloc_mgtxmitframe(pxmitpriv
);
1474 if (pmgntframe
== NULL
)
1477 /* update attribute */
1478 pattrib
= &pmgntframe
->attrib
;
1479 update_mgntframe_attrib(padapter
, pattrib
);
1480 pattrib
->retry_ctrl
= false;
1482 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
1484 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
1485 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
1487 fctrl
= &(pwlanhdr
->frame_ctl
);
1490 memcpy(pwlanhdr
->addr1
, da
, ETH_ALEN
);
1491 memcpy(pwlanhdr
->addr2
, myid(&(padapter
->eeprompriv
)), ETH_ALEN
);
1492 memcpy(pwlanhdr
->addr3
, pnetwork
->MacAddress
, ETH_ALEN
);
1494 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
1495 pmlmeext
->mgnt_seq
++;
1496 SetFrameSubType(pframe
, WIFI_DEAUTH
);
1498 pframe
+= sizeof(struct rtw_ieee80211_hdr_3addr
);
1499 pattrib
->pktlen
= sizeof(struct rtw_ieee80211_hdr_3addr
);
1501 le_tmp
= cpu_to_le16(reason
);
1502 pframe
= rtw_set_fixed_ie(pframe
, _RSON_CODE_
, (unsigned char *)&le_tmp
, &(pattrib
->pktlen
));
1504 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
1508 ret
= dump_mgntframe_and_wait_ack(padapter
, pmgntframe
);
1510 dump_mgntframe(padapter
, pmgntframe
);
1518 int issue_deauth(struct adapter
*padapter
, unsigned char *da
, unsigned short reason
)
1520 DBG_88E("%s to %pM\n", __func__
, da
);
1521 return _issue_deauth(padapter
, da
, reason
, false);
1524 static int issue_deauth_ex(struct adapter
*padapter
, u8
*da
,
1525 unsigned short reason
, int try_cnt
,
1530 u32 start
= jiffies
;
1533 ret
= _issue_deauth(padapter
, da
, reason
, wait_ms
> 0 ? true : false);
1537 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
)
1540 if (i
< try_cnt
&& wait_ms
> 0 && ret
== _FAIL
)
1542 } while ((i
< try_cnt
) && ((ret
== _FAIL
) || (wait_ms
== 0)));
1549 if (try_cnt
&& wait_ms
) {
1551 DBG_88E(FUNC_ADPT_FMT
" to %pM, ch:%u%s, %d/%d in %u ms\n",
1552 FUNC_ADPT_ARG(padapter
), da
, rtw_get_oper_ch(padapter
),
1553 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
, rtw_get_passing_time_ms(start
));
1555 DBG_88E(FUNC_ADPT_FMT
", ch:%u%s, %d/%d in %u ms\n",
1556 FUNC_ADPT_ARG(padapter
), rtw_get_oper_ch(padapter
),
1557 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
, rtw_get_passing_time_ms(start
));
1563 void issue_action_spct_ch_switch(struct adapter
*padapter
, u8
*ra
, u8 new_ch
, u8 ch_offset
)
1565 struct xmit_frame
*pmgntframe
;
1566 struct pkt_attrib
*pattrib
;
1567 unsigned char *pframe
;
1568 struct rtw_ieee80211_hdr
*pwlanhdr
;
1570 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
1571 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1574 DBG_88E(FUNC_NDEV_FMT
" ra =%pM, ch:%u, offset:%u\n",
1575 FUNC_NDEV_ARG(padapter
->pnetdev
), ra
, new_ch
, ch_offset
);
1577 pmgntframe
= alloc_mgtxmitframe(pxmitpriv
);
1578 if (pmgntframe
== NULL
)
1581 /* update attribute */
1582 pattrib
= &pmgntframe
->attrib
;
1583 update_mgntframe_attrib(padapter
, pattrib
);
1585 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
1587 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
1588 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
1590 fctrl
= &(pwlanhdr
->frame_ctl
);
1593 memcpy(pwlanhdr
->addr1
, ra
, ETH_ALEN
); /* RA */
1594 memcpy(pwlanhdr
->addr2
, myid(&(padapter
->eeprompriv
)), ETH_ALEN
); /* TA */
1595 memcpy(pwlanhdr
->addr3
, ra
, ETH_ALEN
); /* DA = RA */
1597 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
1598 pmlmeext
->mgnt_seq
++;
1599 SetFrameSubType(pframe
, WIFI_ACTION
);
1601 pframe
+= sizeof(struct rtw_ieee80211_hdr_3addr
);
1602 pattrib
->pktlen
= sizeof(struct rtw_ieee80211_hdr_3addr
);
1604 /* category, action */
1606 u8 category
, action
;
1607 category
= RTW_WLAN_CATEGORY_SPECTRUM_MGMT
;
1608 action
= RTW_WLAN_ACTION_SPCT_CHL_SWITCH
;
1610 pframe
= rtw_set_fixed_ie(pframe
, 1, &(category
), &(pattrib
->pktlen
));
1611 pframe
= rtw_set_fixed_ie(pframe
, 1, &(action
), &(pattrib
->pktlen
));
1614 pframe
= rtw_set_ie_ch_switch(pframe
, &(pattrib
->pktlen
), 0, new_ch
, 0);
1615 pframe
= rtw_set_ie_secondary_ch_offset(pframe
, &(pattrib
->pktlen
),
1616 hal_ch_offset_to_secondary_ch_offset(ch_offset
));
1618 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
1620 dump_mgntframe(padapter
, pmgntframe
);
1623 static void issue_action_BA(struct adapter
*padapter
, unsigned char *raddr
,
1624 unsigned char action
, unsigned short status
)
1626 u8 category
= RTW_WLAN_CATEGORY_BACK
;
1630 u16 BA_timeout_value
;
1632 u16 BA_starting_seqctrl
= 0;
1633 enum ht_cap_ampdu_factor max_rx_ampdu_factor
;
1634 struct xmit_frame
*pmgntframe
;
1635 struct pkt_attrib
*pattrib
;
1637 struct rtw_ieee80211_hdr
*pwlanhdr
;
1639 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
1640 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1641 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1642 struct sta_info
*psta
;
1643 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1644 struct registry_priv
*pregpriv
= &padapter
->registrypriv
;
1645 struct wlan_bssid_ex
*pnetwork
= &(pmlmeinfo
->network
);
1647 DBG_88E("%s, category=%d, action=%d, status=%d\n", __func__
, category
, action
, status
);
1649 pmgntframe
= alloc_mgtxmitframe(pxmitpriv
);
1650 if (pmgntframe
== NULL
)
1653 /* update attribute */
1654 pattrib
= &pmgntframe
->attrib
;
1655 update_mgntframe_attrib(padapter
, pattrib
);
1657 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
1659 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
1660 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
1662 fctrl
= &(pwlanhdr
->frame_ctl
);
1665 /* memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */
1666 memcpy(pwlanhdr
->addr1
, raddr
, ETH_ALEN
);
1667 memcpy(pwlanhdr
->addr2
, myid(&(padapter
->eeprompriv
)), ETH_ALEN
);
1668 memcpy(pwlanhdr
->addr3
, pnetwork
->MacAddress
, ETH_ALEN
);
1670 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
1671 pmlmeext
->mgnt_seq
++;
1672 SetFrameSubType(pframe
, WIFI_ACTION
);
1674 pframe
+= sizeof(struct rtw_ieee80211_hdr_3addr
);
1675 pattrib
->pktlen
= sizeof(struct rtw_ieee80211_hdr_3addr
);
1677 pframe
= rtw_set_fixed_ie(pframe
, 1, &(category
), &(pattrib
->pktlen
));
1678 pframe
= rtw_set_fixed_ie(pframe
, 1, &(action
), &(pattrib
->pktlen
));
1680 if (category
== 3) {
1682 case 0: /* ADDBA req */
1684 pmlmeinfo
->dialogToken
++;
1685 } while (pmlmeinfo
->dialogToken
== 0);
1686 pframe
= rtw_set_fixed_ie(pframe
, 1, &(pmlmeinfo
->dialogToken
), &(pattrib
->pktlen
));
1688 BA_para_set
= 0x1002 | ((status
& 0xf) << 2); /* immediate ack & 64 buffer size */
1689 le_tmp
= cpu_to_le16(BA_para_set
);
1690 pframe
= rtw_set_fixed_ie(pframe
, 2, (unsigned char *)(&(le_tmp
)), &(pattrib
->pktlen
));
1692 BA_timeout_value
= 5000;/* 5ms */
1693 le_tmp
= cpu_to_le16(BA_timeout_value
);
1694 pframe
= rtw_set_fixed_ie(pframe
, 2, (unsigned char *)(&(le_tmp
)), &(pattrib
->pktlen
));
1696 psta
= rtw_get_stainfo(pstapriv
, raddr
);
1698 start_seq
= (psta
->sta_xmitpriv
.txseq_tid
[status
& 0x07]&0xfff) + 1;
1700 DBG_88E("BA_starting_seqctrl=%d for TID=%d\n", start_seq
, status
& 0x07);
1702 psta
->BA_starting_seqctrl
[status
& 0x07] = start_seq
;
1704 BA_starting_seqctrl
= start_seq
<< 4;
1706 le_tmp
= cpu_to_le16(BA_starting_seqctrl
);
1707 pframe
= rtw_set_fixed_ie(pframe
, 2, (unsigned char *)(&(le_tmp
)), &(pattrib
->pktlen
));
1709 case 1: /* ADDBA rsp */
1710 pframe
= rtw_set_fixed_ie(pframe
, 1, &(pmlmeinfo
->ADDBA_req
.dialog_token
), &(pattrib
->pktlen
));
1711 pframe
= rtw_set_fixed_ie(pframe
, 2, (unsigned char *)(&status
), &(pattrib
->pktlen
));
1713 BA_para_set
= le16_to_cpu(pmlmeinfo
->ADDBA_req
.BA_para_set
) & 0x3f;
1714 rtw_hal_get_def_var(padapter
, HW_VAR_MAX_RX_AMPDU_FACTOR
, &max_rx_ampdu_factor
);
1715 switch (max_rx_ampdu_factor
) {
1716 case MAX_AMPDU_FACTOR_64K
:
1717 BA_para_set
|= 0x1000; /* 64 buffer size */
1719 case MAX_AMPDU_FACTOR_32K
:
1720 BA_para_set
|= 0x0800; /* 32 buffer size */
1722 case MAX_AMPDU_FACTOR_16K
:
1723 BA_para_set
|= 0x0400; /* 16 buffer size */
1725 case MAX_AMPDU_FACTOR_8K
:
1726 BA_para_set
|= 0x0200; /* 8 buffer size */
1729 BA_para_set
|= 0x1000; /* 64 buffer size */
1733 if (pregpriv
->ampdu_amsdu
== 0)/* disabled */
1734 BA_para_set
= BA_para_set
& ~BIT(0);
1735 else if (pregpriv
->ampdu_amsdu
== 1)/* enabled */
1736 BA_para_set
= BA_para_set
| BIT(0);
1737 le_tmp
= cpu_to_le16(BA_para_set
);
1739 pframe
= rtw_set_fixed_ie(pframe
, 2, (unsigned char *)(&(le_tmp
)), &(pattrib
->pktlen
));
1740 pframe
= rtw_set_fixed_ie(pframe
, 2, (unsigned char *)(&(pmlmeinfo
->ADDBA_req
.BA_timeout_value
)), &(pattrib
->pktlen
));
1743 BA_para_set
= (status
& 0x1F) << 3;
1744 le_tmp
= cpu_to_le16(BA_para_set
);
1745 pframe
= rtw_set_fixed_ie(pframe
, 2, (unsigned char *)(&(le_tmp
)), &(pattrib
->pktlen
));
1747 reason_code
= 37;/* Requested from peer STA as it does not want to use the mechanism */
1748 le_tmp
= cpu_to_le16(reason_code
);
1749 pframe
= rtw_set_fixed_ie(pframe
, 2, (unsigned char *)(&(le_tmp
)), &(pattrib
->pktlen
));
1756 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
1758 dump_mgntframe(padapter
, pmgntframe
);
1761 static void issue_action_BSSCoexistPacket(struct adapter
*padapter
)
1763 struct list_head
*plist
, *phead
;
1764 unsigned char category
, action
;
1765 struct xmit_frame
*pmgntframe
;
1766 struct pkt_attrib
*pattrib
;
1767 unsigned char *pframe
;
1768 struct rtw_ieee80211_hdr
*pwlanhdr
;
1770 struct wlan_network
*pnetwork
= NULL
;
1771 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
1772 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1773 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1774 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1775 struct __queue
*queue
= &(pmlmepriv
->scanned_queue
);
1776 u8 InfoContent
[16] = {0};
1778 struct wlan_bssid_ex
*cur_network
= &(pmlmeinfo
->network
);
1780 if ((pmlmepriv
->num_FortyMHzIntolerant
== 0) || (pmlmepriv
->num_sta_no_ht
== 0))
1783 if (pmlmeinfo
->bwmode_updated
)
1787 DBG_88E("%s\n", __func__
);
1790 category
= RTW_WLAN_CATEGORY_PUBLIC
;
1791 action
= ACT_PUBLIC_BSSCOEXIST
;
1793 pmgntframe
= alloc_mgtxmitframe(pxmitpriv
);
1794 if (pmgntframe
== NULL
)
1797 /* update attribute */
1798 pattrib
= &pmgntframe
->attrib
;
1799 update_mgntframe_attrib(padapter
, pattrib
);
1801 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
1803 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
1804 pwlanhdr
= (struct rtw_ieee80211_hdr
*)pframe
;
1806 fctrl
= &(pwlanhdr
->frame_ctl
);
1809 memcpy(pwlanhdr
->addr1
, cur_network
->MacAddress
, ETH_ALEN
);
1810 memcpy(pwlanhdr
->addr2
, myid(&(padapter
->eeprompriv
)), ETH_ALEN
);
1811 memcpy(pwlanhdr
->addr3
, cur_network
->MacAddress
, ETH_ALEN
);
1813 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
1814 pmlmeext
->mgnt_seq
++;
1815 SetFrameSubType(pframe
, WIFI_ACTION
);
1817 pframe
+= sizeof(struct rtw_ieee80211_hdr_3addr
);
1818 pattrib
->pktlen
= sizeof(struct rtw_ieee80211_hdr_3addr
);
1820 pframe
= rtw_set_fixed_ie(pframe
, 1, &(category
), &(pattrib
->pktlen
));
1821 pframe
= rtw_set_fixed_ie(pframe
, 1, &(action
), &(pattrib
->pktlen
));
1825 if (pmlmepriv
->num_FortyMHzIntolerant
> 0) {
1828 iedata
|= BIT(2);/* 20 MHz BSS Width Request */
1830 pframe
= rtw_set_ie(pframe
, EID_BSSCoexistence
, 1, &iedata
, &(pattrib
->pktlen
));
1835 memset(ICS
, 0, sizeof(ICS
));
1836 if (pmlmepriv
->num_sta_no_ht
> 0) {
1839 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1841 phead
= get_list_head(queue
);
1842 plist
= phead
->next
;
1844 while (phead
!= plist
) {
1847 struct wlan_bssid_ex
*pbss_network
;
1849 pnetwork
= container_of(plist
, struct wlan_network
, list
);
1851 plist
= plist
->next
;
1853 pbss_network
= (struct wlan_bssid_ex
*)&pnetwork
->network
;
1855 p
= rtw_get_ie(pbss_network
->IEs
+ _FIXED_IE_LENGTH_
, _HT_CAPABILITY_IE_
, &len
, pbss_network
->IELength
- _FIXED_IE_LENGTH_
);
1856 if ((p
== NULL
) || (len
== 0)) { /* non-HT */
1857 if ((pbss_network
->Configuration
.DSConfig
<= 0) || (pbss_network
->Configuration
.DSConfig
> 14))
1860 ICS
[0][pbss_network
->Configuration
.DSConfig
] = 1;
1866 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1868 for (i
= 0; i
< 8; i
++) {
1869 if (ICS
[i
][0] == 1) {
1873 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */
1876 for (j
= 1; j
<= 14; j
++) {
1877 if (ICS
[i
][j
] == 1) {
1879 InfoContent
[k
] = j
; /* channel number */
1880 /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */
1886 pframe
= rtw_set_ie(pframe
, EID_BSSIntolerantChlReport
, k
, InfoContent
, &(pattrib
->pktlen
));
1892 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
1894 dump_mgntframe(padapter
, pmgntframe
);
1897 unsigned int send_delba(struct adapter
*padapter
, u8 initiator
, u8
*addr
)
1899 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1900 struct sta_info
*psta
= NULL
;
1901 /* struct recv_reorder_ctrl *preorder_ctrl; */
1902 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1903 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1906 if ((pmlmeinfo
->state
&0x03) != WIFI_FW_AP_STATE
)
1907 if (!(pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
))
1910 psta
= rtw_get_stainfo(pstapriv
, addr
);
1914 if (initiator
== 0) { /* recipient */
1915 for (tid
= 0; tid
< MAXTID
; tid
++) {
1916 if (psta
->recvreorder_ctrl
[tid
].enable
) {
1917 DBG_88E("rx agg disable tid(%d)\n", tid
);
1918 issue_action_BA(padapter
, addr
, RTW_WLAN_ACTION_DELBA
, (((tid
<< 1) | initiator
)&0x1F));
1919 psta
->recvreorder_ctrl
[tid
].enable
= false;
1920 psta
->recvreorder_ctrl
[tid
].indicate_seq
= 0xffff;
1923 } else if (initiator
== 1) { /* originator */
1924 for (tid
= 0; tid
< MAXTID
; tid
++) {
1925 if (psta
->htpriv
.agg_enable_bitmap
& BIT(tid
)) {
1926 DBG_88E("tx agg disable tid(%d)\n", tid
);
1927 issue_action_BA(padapter
, addr
, RTW_WLAN_ACTION_DELBA
, (((tid
<< 1) | initiator
)&0x1F));
1928 psta
->htpriv
.agg_enable_bitmap
&= ~BIT(tid
);
1929 psta
->htpriv
.candidate_tid_bitmap
&= ~BIT(tid
);
1937 unsigned int send_beacon(struct adapter
*padapter
)
1943 u32 start
= jiffies
;
1945 rtw_hal_set_hwreg(padapter
, HW_VAR_BCN_VALID
, NULL
);
1947 issue_beacon(padapter
, 100);
1951 rtw_hal_get_hwreg(padapter
, HW_VAR_BCN_VALID
, (u8
*)(&bxmitok
));
1953 } while ((poll
%10) != 0 && !bxmitok
&& !padapter
->bSurpriseRemoved
&& !padapter
->bDriverStopped
);
1954 } while (!bxmitok
&& issue
< 100 && !padapter
->bSurpriseRemoved
&& !padapter
->bDriverStopped
);
1956 if (padapter
->bSurpriseRemoved
|| padapter
->bDriverStopped
)
1959 DBG_88E("%s fail! %u ms\n", __func__
, rtw_get_passing_time_ms(start
));
1962 u32 passing_time
= rtw_get_passing_time_ms(start
);
1964 if (passing_time
> 100 || issue
> 3)
1965 DBG_88E("%s success, issue:%d, poll:%d, %u ms\n", __func__
, issue
, poll
, rtw_get_passing_time_ms(start
));
1970 /****************************************************************************
1972 Following are some utility functions for WiFi MLME
1974 *****************************************************************************/
1976 static void site_survey(struct adapter
*padapter
)
1978 unsigned char survey_channel
= 0, val8
;
1979 enum rt_scan_type ScanType
= SCAN_PASSIVE
;
1980 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1981 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1982 u32 initialgain
= 0;
1983 struct rtw_ieee80211_channel
*ch
;
1985 if (pmlmeext
->sitesurvey_res
.channel_idx
< pmlmeext
->sitesurvey_res
.ch_num
) {
1986 ch
= &pmlmeext
->sitesurvey_res
.ch
[pmlmeext
->sitesurvey_res
.channel_idx
];
1987 survey_channel
= ch
->hw_value
;
1988 ScanType
= (ch
->flags
& RTW_IEEE80211_CHAN_PASSIVE_SCAN
) ? SCAN_PASSIVE
: SCAN_ACTIVE
;
1992 if (survey_channel
!= 0) {
1993 /* PAUSE 4-AC Queue when site_survey */
1994 /* rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
1996 /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
1997 if (pmlmeext
->sitesurvey_res
.channel_idx
== 0)
1998 set_channel_bwmode(padapter
, survey_channel
, HAL_PRIME_CHNL_OFFSET_DONT_CARE
, HT_CHANNEL_WIDTH_20
);
2000 SelectChannel(padapter
, survey_channel
);
2002 if (ScanType
== SCAN_ACTIVE
) { /* obey the channel plan setting... */
2004 for (i
= 0; i
< RTW_SSID_SCAN_AMOUNT
; i
++) {
2005 if (pmlmeext
->sitesurvey_res
.ssid
[i
].SsidLength
) {
2006 /* todo: to issue two probe req??? */
2007 issue_probereq(padapter
, &(pmlmeext
->sitesurvey_res
.ssid
[i
]), NULL
);
2008 /* msleep(SURVEY_TO>>1); */
2009 issue_probereq(padapter
, &(pmlmeext
->sitesurvey_res
.ssid
[i
]), NULL
);
2013 if (pmlmeext
->sitesurvey_res
.scan_mode
== SCAN_ACTIVE
) {
2014 /* todo: to issue two probe req??? */
2015 issue_probereq(padapter
, NULL
, NULL
);
2016 /* msleep(SURVEY_TO>>1); */
2017 issue_probereq(padapter
, NULL
, NULL
);
2020 if (pmlmeext
->sitesurvey_res
.scan_mode
== SCAN_ACTIVE
) {
2021 /* todo: to issue two probe req??? */
2022 issue_probereq(padapter
, NULL
, NULL
);
2023 /* msleep(SURVEY_TO>>1); */
2024 issue_probereq(padapter
, NULL
, NULL
);
2028 set_survey_timer(pmlmeext
, pmlmeext
->chan_scan_time
);
2031 /* 20100721:Interrupt scan operation here. */
2032 /* For SW antenna diversity before link, it needs to switch to another antenna and scan again. */
2033 /* It compares the scan result and select better one to do connection. */
2034 if (rtw_hal_antdiv_before_linked(padapter
)) {
2035 pmlmeext
->sitesurvey_res
.bss_cnt
= 0;
2036 pmlmeext
->sitesurvey_res
.channel_idx
= -1;
2037 pmlmeext
->chan_scan_time
= SURVEY_TO
/ 2;
2038 set_survey_timer(pmlmeext
, pmlmeext
->chan_scan_time
);
2042 pmlmeext
->sitesurvey_res
.state
= SCAN_COMPLETE
;
2044 /* switch back to the original channel */
2046 set_channel_bwmode(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
2048 /* flush 4-AC Queue after site_survey */
2050 /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
2053 Set_MSR(padapter
, (pmlmeinfo
->state
& 0x3));
2055 initialgain
= 0xff; /* restore RX GAIN */
2056 rtw_hal_set_hwreg(padapter
, HW_VAR_INITIAL_GAIN
, (u8
*)(&initialgain
));
2057 /* turn on dynamic functions */
2058 Restore_DM_Func_Flag(padapter
);
2059 /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */
2061 if (is_client_associated_to_ap(padapter
))
2062 issue_nulldata(padapter
, NULL
, 0, 3, 500);
2064 val8
= 0; /* survey done */
2065 rtw_hal_set_hwreg(padapter
, HW_VAR_MLME_SITESURVEY
, (u8
*)(&val8
));
2067 report_surveydone_event(padapter
);
2069 pmlmeext
->chan_scan_time
= SURVEY_TO
;
2070 pmlmeext
->sitesurvey_res
.state
= SCAN_DISABLE
;
2072 issue_action_BSSCoexistPacket(padapter
);
2073 issue_action_BSSCoexistPacket(padapter
);
2074 issue_action_BSSCoexistPacket(padapter
);
2079 /* collect bss info from Beacon and Probe request/response frames. */
2080 static u8
collect_bss_info(struct adapter
*padapter
,
2081 struct recv_frame
*precv_frame
,
2082 struct wlan_bssid_ex
*bssid
)
2088 u8
*pframe
= precv_frame
->rx_data
;
2089 u32 packet_len
= precv_frame
->len
;
2091 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
2092 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2093 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2095 len
= packet_len
- sizeof(struct rtw_ieee80211_hdr_3addr
);
2097 if (len
> MAX_IE_SZ
)
2100 memset(bssid
, 0, sizeof(struct wlan_bssid_ex
));
2102 subtype
= GetFrameSubType(pframe
);
2104 if (subtype
== WIFI_BEACON
) {
2105 bssid
->Reserved
[0] = 1;
2106 ie_offset
= _BEACON_IE_OFFSET_
;
2108 /* FIXME : more type */
2109 if (subtype
== WIFI_PROBEREQ
) {
2110 ie_offset
= _PROBEREQ_IE_OFFSET_
;
2111 bssid
->Reserved
[0] = 2;
2112 } else if (subtype
== WIFI_PROBERSP
) {
2113 ie_offset
= _PROBERSP_IE_OFFSET_
;
2114 bssid
->Reserved
[0] = 3;
2116 bssid
->Reserved
[0] = 0;
2117 ie_offset
= _FIXED_IE_LENGTH_
;
2121 bssid
->Length
= sizeof(struct wlan_bssid_ex
) - MAX_IE_SZ
+ len
;
2123 /* below is to copy the information element */
2124 bssid
->IELength
= len
;
2125 memcpy(bssid
->IEs
, (pframe
+ sizeof(struct rtw_ieee80211_hdr_3addr
)), bssid
->IELength
);
2127 /* get the signal strength in dBM.raw data */
2128 bssid
->Rssi
= precv_frame
->attrib
.phy_info
.recvpower
;
2129 bssid
->PhyInfo
.SignalQuality
= precv_frame
->attrib
.phy_info
.SignalQuality
;/* in percentage */
2130 bssid
->PhyInfo
.SignalStrength
= precv_frame
->attrib
.phy_info
.SignalStrength
;/* in percentage */
2131 rtw_hal_get_def_var(padapter
, HAL_DEF_CURRENT_ANTENNA
, &bssid
->PhyInfo
.Optimum_antenna
);
2134 p
= rtw_get_ie(bssid
->IEs
+ ie_offset
, _SSID_IE_
, &len
, bssid
->IELength
- ie_offset
);
2136 DBG_88E("marc: cannot find SSID for survey event\n");
2141 if (len
> NDIS_802_11_LENGTH_SSID
) {
2142 DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__
, __LINE__
, len
);
2145 memcpy(bssid
->Ssid
.Ssid
, (p
+ 2), len
);
2146 bssid
->Ssid
.SsidLength
= len
;
2148 bssid
->Ssid
.SsidLength
= 0;
2151 memset(bssid
->SupportedRates
, 0, NDIS_802_11_LENGTH_RATES_EX
);
2153 /* checking rate info... */
2155 p
= rtw_get_ie(bssid
->IEs
+ ie_offset
, _SUPPORTEDRATES_IE_
, &len
, bssid
->IELength
- ie_offset
);
2157 if (len
> NDIS_802_11_LENGTH_RATES_EX
) {
2158 DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__
, __LINE__
, len
);
2161 memcpy(bssid
->SupportedRates
, (p
+ 2), len
);
2165 p
= rtw_get_ie(bssid
->IEs
+ ie_offset
, _EXT_SUPPORTEDRATES_IE_
, &len
, bssid
->IELength
- ie_offset
);
2167 if (len
> (NDIS_802_11_LENGTH_RATES_EX
-i
)) {
2168 DBG_88E("%s()-%d: IE too long (%d) for survey event\n", __func__
, __LINE__
, len
);
2171 memcpy(bssid
->SupportedRates
+ i
, (p
+ 2), len
);
2175 bssid
->NetworkTypeInUse
= Ndis802_11OFDM24
;
2177 if (bssid
->IELength
< 12)
2180 /* Checking for DSConfig */
2181 p
= rtw_get_ie(bssid
->IEs
+ ie_offset
, _DSSET_IE_
, &len
, bssid
->IELength
- ie_offset
);
2183 bssid
->Configuration
.DSConfig
= 0;
2184 bssid
->Configuration
.Length
= 0;
2187 bssid
->Configuration
.DSConfig
= *(p
+ 2);
2188 } else {/* In 5G, some ap do not have DSSET IE */
2189 /* checking HT info for channel */
2190 p
= rtw_get_ie(bssid
->IEs
+ ie_offset
, _HT_ADD_INFO_IE_
, &len
, bssid
->IELength
- ie_offset
);
2192 struct HT_info_element
*HT_info
= (struct HT_info_element
*)(p
+ 2);
2193 bssid
->Configuration
.DSConfig
= HT_info
->primary_channel
;
2194 } else { /* use current channel */
2195 bssid
->Configuration
.DSConfig
= rtw_get_oper_ch(padapter
);
2199 if (subtype
== WIFI_PROBEREQ
) {
2201 bssid
->InfrastructureMode
= Ndis802_11Infrastructure
;
2202 memcpy(bssid
->MacAddress
, GetAddr2Ptr(pframe
), ETH_ALEN
);
2207 bssid
->Configuration
.BeaconPeriod
=
2208 get_unaligned_le16(rtw_get_beacon_interval_from_ie(bssid
->IEs
));
2210 val16
= rtw_get_capability((struct wlan_bssid_ex
*)bssid
);
2212 if (val16
& BIT(0)) {
2213 bssid
->InfrastructureMode
= Ndis802_11Infrastructure
;
2214 memcpy(bssid
->MacAddress
, GetAddr2Ptr(pframe
), ETH_ALEN
);
2216 bssid
->InfrastructureMode
= Ndis802_11IBSS
;
2217 memcpy(bssid
->MacAddress
, GetAddr3Ptr(pframe
), ETH_ALEN
);
2225 bssid
->Configuration
.ATIMWindow
= 0;
2227 /* 20/40 BSS Coexistence check */
2228 if ((pregistrypriv
->wifi_spec
== 1) && (!pmlmeinfo
->bwmode_updated
)) {
2229 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2230 p
= rtw_get_ie(bssid
->IEs
+ ie_offset
, _HT_CAPABILITY_IE_
, &len
, bssid
->IELength
- ie_offset
);
2232 struct HT_caps_element
*pHT_caps
;
2233 pHT_caps
= (struct HT_caps_element
*)(p
+ 2);
2235 if (le16_to_cpu(pHT_caps
->u
.HT_cap_element
.HT_caps_info
)&BIT(14))
2236 pmlmepriv
->num_FortyMHzIntolerant
++;
2238 pmlmepriv
->num_sta_no_ht
++;
2242 /* mark bss info receiving from nearby channel as SignalQuality 101 */
2243 if (bssid
->Configuration
.DSConfig
!= rtw_get_oper_ch(padapter
))
2244 bssid
->PhyInfo
.SignalQuality
= 101;
2248 static void start_create_ibss(struct adapter
*padapter
)
2250 unsigned short caps
;
2253 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2254 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2255 struct wlan_bssid_ex
*pnetwork
= (struct wlan_bssid_ex
*)(&(pmlmeinfo
->network
));
2256 pmlmeext
->cur_channel
= (u8
)pnetwork
->Configuration
.DSConfig
;
2257 pmlmeinfo
->bcn_interval
= get_beacon_interval(pnetwork
);
2259 /* update wireless mode */
2260 update_wireless_mode(padapter
);
2262 /* update capability */
2263 caps
= rtw_get_capability((struct wlan_bssid_ex
*)pnetwork
);
2264 update_capinfo(padapter
, caps
);
2265 if (caps
&cap_IBSS
) {/* adhoc master */
2267 rtw_hal_set_hwreg(padapter
, HW_VAR_SEC_CFG
, (u8
*)(&val8
));
2269 /* switch channel */
2270 /* SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
2271 set_channel_bwmode(padapter
, pmlmeext
->cur_channel
, HAL_PRIME_CHNL_OFFSET_DONT_CARE
, HT_CHANNEL_WIDTH_20
);
2273 beacon_timing_control(padapter
);
2275 /* set msr to WIFI_FW_ADHOC_STATE */
2276 pmlmeinfo
->state
= WIFI_FW_ADHOC_STATE
;
2277 Set_MSR(padapter
, (pmlmeinfo
->state
& 0x3));
2280 if (send_beacon(padapter
) == _FAIL
) {
2281 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("issuing beacon frame fail....\n"));
2283 report_join_res(padapter
, -1);
2284 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
2286 rtw_hal_set_hwreg(padapter
, HW_VAR_BSSID
, padapter
->registrypriv
.dev_network
.MacAddress
);
2288 rtw_hal_set_hwreg(padapter
, HW_VAR_MLME_JOIN
, (u8
*)(&join_type
));
2290 report_join_res(padapter
, 1);
2291 pmlmeinfo
->state
|= WIFI_FW_ASSOC_SUCCESS
;
2294 DBG_88E("start_create_ibss, invalid cap:%x\n", caps
);
2299 static void start_clnt_join(struct adapter
*padapter
)
2301 unsigned short caps
;
2303 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2304 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2305 struct wlan_bssid_ex
*pnetwork
= (struct wlan_bssid_ex
*)(&(pmlmeinfo
->network
));
2308 pmlmeext
->cur_channel
= (u8
)pnetwork
->Configuration
.DSConfig
;
2309 pmlmeinfo
->bcn_interval
= get_beacon_interval(pnetwork
);
2311 /* update wireless mode */
2312 update_wireless_mode(padapter
);
2314 /* update capability */
2315 caps
= rtw_get_capability((struct wlan_bssid_ex
*)pnetwork
);
2316 update_capinfo(padapter
, caps
);
2318 Set_MSR(padapter
, WIFI_FW_STATION_STATE
);
2320 val8
= (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_8021X
) ? 0xcc : 0xcf;
2322 rtw_hal_set_hwreg(padapter
, HW_VAR_SEC_CFG
, (u8
*)(&val8
));
2324 /* switch channel */
2325 set_channel_bwmode(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
2327 /* here wait for receiving the beacon to start auth */
2328 /* and enable a timer */
2329 beacon_timeout
= decide_wait_for_beacon_timeout(pmlmeinfo
->bcn_interval
);
2330 set_link_timer(pmlmeext
, beacon_timeout
);
2331 mod_timer(&padapter
->mlmepriv
.assoc_timer
, jiffies
+
2332 msecs_to_jiffies((REAUTH_TO
* REAUTH_LIMIT
) + (REASSOC_TO
* REASSOC_LIMIT
) + beacon_timeout
));
2334 pmlmeinfo
->state
= WIFI_FW_AUTH_NULL
| WIFI_FW_STATION_STATE
;
2335 } else if (caps
&cap_IBSS
) { /* adhoc client */
2336 Set_MSR(padapter
, WIFI_FW_ADHOC_STATE
);
2339 rtw_hal_set_hwreg(padapter
, HW_VAR_SEC_CFG
, (u8
*)(&val8
));
2341 /* switch channel */
2342 set_channel_bwmode(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
2344 beacon_timing_control(padapter
);
2346 pmlmeinfo
->state
= WIFI_FW_ADHOC_STATE
;
2348 report_join_res(padapter
, 1);
2354 static void start_clnt_auth(struct adapter
*padapter
)
2356 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2357 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2359 del_timer_sync(&pmlmeext
->link_timer
);
2361 pmlmeinfo
->state
&= (~WIFI_FW_AUTH_NULL
);
2362 pmlmeinfo
->state
|= WIFI_FW_AUTH_STATE
;
2364 pmlmeinfo
->auth_seq
= 1;
2365 pmlmeinfo
->reauth_count
= 0;
2366 pmlmeinfo
->reassoc_count
= 0;
2367 pmlmeinfo
->link_count
= 0;
2368 pmlmeext
->retry
= 0;
2371 /* Because of AP's not receiving deauth before */
2372 /* AP may: 1)not response auth or 2)deauth us after link is complete */
2373 /* issue deauth before issuing auth to deal with the situation */
2374 /* Commented by Albert 2012/07/21 */
2375 /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
2376 issue_deauth(padapter
, (&(pmlmeinfo
->network
))->MacAddress
, WLAN_REASON_DEAUTH_LEAVING
);
2378 DBG_88E_LEVEL(_drv_info_
, "start auth\n");
2379 issue_auth(padapter
, NULL
, 0);
2381 set_link_timer(pmlmeext
, REAUTH_TO
);
2385 static void start_clnt_assoc(struct adapter
*padapter
)
2387 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2388 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2390 del_timer_sync(&pmlmeext
->link_timer
);
2392 pmlmeinfo
->state
&= (~(WIFI_FW_AUTH_NULL
| WIFI_FW_AUTH_STATE
));
2393 pmlmeinfo
->state
|= (WIFI_FW_AUTH_SUCCESS
| WIFI_FW_ASSOC_STATE
);
2395 issue_assocreq(padapter
);
2397 set_link_timer(pmlmeext
, REASSOC_TO
);
2400 static unsigned int receive_disconnect(struct adapter
*padapter
,
2401 unsigned char *MacAddr
,
2402 unsigned short reason
)
2404 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2405 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2406 struct wlan_bssid_ex
*pnetwork
= &(pmlmeinfo
->network
);
2409 if (memcmp(MacAddr
, pnetwork
->MacAddress
, ETH_ALEN
))
2412 DBG_88E("%s\n", __func__
);
2414 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_STATION_STATE
) {
2415 if (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
) {
2416 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
2417 report_del_sta_event(padapter
, MacAddr
, reason
);
2418 } else if (pmlmeinfo
->state
& WIFI_FW_LINKING_STATE
) {
2419 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
2420 report_join_res(padapter
, -2);
2426 static void process_80211d(struct adapter
*padapter
, struct wlan_bssid_ex
*bssid
)
2428 struct registry_priv
*pregistrypriv
;
2429 struct mlme_ext_priv
*pmlmeext
;
2430 struct rt_channel_info
*chplan_new
;
2434 pregistrypriv
= &padapter
->registrypriv
;
2435 pmlmeext
= &padapter
->mlmeextpriv
;
2437 /* Adjust channel plan by AP Country IE */
2438 if (pregistrypriv
->enable80211d
&&
2439 (!pmlmeext
->update_channel_plan_by_ap_done
)) {
2442 struct rt_channel_plan chplan_ap
;
2443 struct rt_channel_info chplan_sta
[MAX_CHANNEL_NUM
];
2445 u8 fcn
; /* first channel number */
2446 u8 noc
; /* number of channel */
2449 ie
= rtw_get_ie(bssid
->IEs
+ _FIXED_IE_LENGTH_
, _COUNTRY_IE_
, &len
, bssid
->IELength
- _FIXED_IE_LENGTH_
);
2458 memset(country
, 0, 4);
2459 memcpy(country
, p
, 3);
2461 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
2462 ("%s: 802.11d country =%s\n", __func__
, country
));
2465 while ((ie
- p
) >= 3) {
2470 for (j
= 0; j
< noc
; j
++) {
2472 channel
= fcn
+ j
; /* 2.4 GHz */
2474 channel
= fcn
+ j
*4; /* 5 GHz */
2476 chplan_ap
.Channel
[i
++] = channel
;
2481 memcpy(chplan_sta
, pmlmeext
->channel_set
, sizeof(chplan_sta
));
2483 memset(pmlmeext
->channel_set
, 0, sizeof(pmlmeext
->channel_set
));
2484 chplan_new
= pmlmeext
->channel_set
;
2489 if (pregistrypriv
->wireless_mode
& WIRELESS_11G
) {
2491 if ((i
== MAX_CHANNEL_NUM
) ||
2492 (chplan_sta
[i
].ChannelNum
== 0) ||
2493 (chplan_sta
[i
].ChannelNum
> 14))
2496 if ((j
== chplan_ap
.Len
) || (chplan_ap
.Channel
[j
] > 14))
2499 if (chplan_sta
[i
].ChannelNum
== chplan_ap
.Channel
[j
]) {
2500 chplan_new
[k
].ChannelNum
= chplan_ap
.Channel
[j
];
2501 chplan_new
[k
].ScanType
= SCAN_ACTIVE
;
2505 } else if (chplan_sta
[i
].ChannelNum
< chplan_ap
.Channel
[j
]) {
2506 chplan_new
[k
].ChannelNum
= chplan_sta
[i
].ChannelNum
;
2507 chplan_new
[k
].ScanType
= SCAN_PASSIVE
;
2510 } else if (chplan_sta
[i
].ChannelNum
> chplan_ap
.Channel
[j
]) {
2511 chplan_new
[k
].ChannelNum
= chplan_ap
.Channel
[j
];
2512 chplan_new
[k
].ScanType
= SCAN_ACTIVE
;
2518 /* change AP not support channel to Passive scan */
2519 while ((i
< MAX_CHANNEL_NUM
) &&
2520 (chplan_sta
[i
].ChannelNum
!= 0) &&
2521 (chplan_sta
[i
].ChannelNum
<= 14)) {
2522 chplan_new
[k
].ChannelNum
= chplan_sta
[i
].ChannelNum
;
2523 chplan_new
[k
].ScanType
= SCAN_PASSIVE
;
2528 /* add channel AP supported */
2529 while ((j
< chplan_ap
.Len
) && (chplan_ap
.Channel
[j
] <= 14)) {
2530 chplan_new
[k
].ChannelNum
= chplan_ap
.Channel
[j
];
2531 chplan_new
[k
].ScanType
= SCAN_ACTIVE
;
2536 /* keep original STA 2.4G channel plan */
2537 while ((i
< MAX_CHANNEL_NUM
) &&
2538 (chplan_sta
[i
].ChannelNum
!= 0) &&
2539 (chplan_sta
[i
].ChannelNum
<= 14)) {
2540 chplan_new
[k
].ChannelNum
= chplan_sta
[i
].ChannelNum
;
2541 chplan_new
[k
].ScanType
= chplan_sta
[i
].ScanType
;
2546 /* skip AP 2.4G channel plan */
2547 while ((j
< chplan_ap
.Len
) && (chplan_ap
.Channel
[j
] <= 14))
2551 /* keep original STA 5G channel plan */
2552 while ((i
< MAX_CHANNEL_NUM
) && (chplan_sta
[i
].ChannelNum
!= 0)) {
2553 chplan_new
[k
].ChannelNum
= chplan_sta
[i
].ChannelNum
;
2554 chplan_new
[k
].ScanType
= chplan_sta
[i
].ScanType
;
2559 pmlmeext
->update_channel_plan_by_ap_done
= 1;
2562 /* If channel is used by AP, set channel scan type to active */
2563 channel
= bssid
->Configuration
.DSConfig
;
2564 chplan_new
= pmlmeext
->channel_set
;
2566 while ((i
< MAX_CHANNEL_NUM
) && (chplan_new
[i
].ChannelNum
!= 0)) {
2567 if (chplan_new
[i
].ChannelNum
== channel
) {
2568 if (chplan_new
[i
].ScanType
== SCAN_PASSIVE
) {
2569 chplan_new
[i
].ScanType
= SCAN_ACTIVE
;
2570 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
2571 ("%s: change channel %d scan type from passive to active\n",
2572 __func__
, channel
));
2580 /****************************************************************************
2582 Following are the callback functions for each subtype of the management frames
2584 *****************************************************************************/
2586 static unsigned int OnProbeReq(struct adapter
*padapter
,
2587 struct recv_frame
*precv_frame
)
2591 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2592 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2593 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2594 struct wlan_bssid_ex
*cur
= &(pmlmeinfo
->network
);
2595 u8
*pframe
= precv_frame
->rx_data
;
2596 uint len
= precv_frame
->len
;
2598 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
))
2601 if (!check_fwstate(pmlmepriv
, _FW_LINKED
) &&
2602 !check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
|WIFI_AP_STATE
))
2605 p
= rtw_get_ie(pframe
+ WLAN_HDR_A3_LEN
+ _PROBEREQ_IE_OFFSET_
, _SSID_IE_
, (int *)&ielen
,
2606 len
- WLAN_HDR_A3_LEN
- _PROBEREQ_IE_OFFSET_
);
2608 /* check (wildcard) SSID */
2610 if ((ielen
!= 0 && memcmp((void *)(p
+2), (void *)cur
->Ssid
.Ssid
, cur
->Ssid
.SsidLength
)) ||
2611 (ielen
== 0 && pmlmeinfo
->hidden_ssid_mode
))
2614 if (check_fwstate(pmlmepriv
, _FW_LINKED
) &&
2615 pmlmepriv
->cur_network
.join_res
)
2616 issue_probersp(padapter
, get_sa(pframe
));
2621 static unsigned int OnProbeRsp(struct adapter
*padapter
,
2622 struct recv_frame
*precv_frame
)
2624 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2626 if (pmlmeext
->sitesurvey_res
.state
== SCAN_PROCESS
) {
2627 report_survey_event(padapter
, precv_frame
);
2634 static unsigned int OnBeacon(struct adapter
*padapter
,
2635 struct recv_frame
*precv_frame
)
2638 struct sta_info
*psta
;
2639 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2640 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2641 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2642 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2643 u8
*pframe
= precv_frame
->rx_data
;
2644 uint len
= precv_frame
->len
;
2645 struct wlan_bssid_ex
*pbss
;
2647 struct wlan_bssid_ex
*pnetwork
= &(pmlmeinfo
->network
);
2649 if (pmlmeext
->sitesurvey_res
.state
== SCAN_PROCESS
) {
2650 report_survey_event(padapter
, precv_frame
);
2654 if (!memcmp(GetAddr3Ptr(pframe
), pnetwork
->MacAddress
, ETH_ALEN
)) {
2655 if (pmlmeinfo
->state
& WIFI_FW_AUTH_NULL
) {
2656 /* we should update current network before auth, or some IE is wrong */
2657 pbss
= (struct wlan_bssid_ex
*)rtw_malloc(sizeof(struct wlan_bssid_ex
));
2659 if (collect_bss_info(padapter
, precv_frame
, pbss
) == _SUCCESS
) {
2660 update_network(&(pmlmepriv
->cur_network
.network
), pbss
, padapter
, true);
2661 rtw_get_bcn_info(&(pmlmepriv
->cur_network
));
2666 /* check the vendor of the assoc AP */
2667 pmlmeinfo
->assoc_AP_vendor
= check_assoc_AP(pframe
+sizeof(struct rtw_ieee80211_hdr_3addr
), len
-sizeof(struct rtw_ieee80211_hdr_3addr
));
2669 /* update TSF Value */
2670 update_TSF(pmlmeext
, pframe
, len
);
2673 start_clnt_auth(padapter
);
2678 if (((pmlmeinfo
->state
&0x03) == WIFI_FW_STATION_STATE
) && (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
)) {
2679 psta
= rtw_get_stainfo(pstapriv
, GetAddr2Ptr(pframe
));
2681 ret
= rtw_check_bcn_info(padapter
, pframe
, len
);
2683 DBG_88E_LEVEL(_drv_info_
, "ap has changed, disconnect now\n ");
2684 receive_disconnect(padapter
, pmlmeinfo
->network
.MacAddress
, 65535);
2687 /* update WMM, ERP in the beacon */
2688 /* todo: the timer is used instead of the number of the beacon received */
2689 if ((sta_rx_pkts(psta
) & 0xf) == 0)
2690 update_beacon_info(padapter
, pframe
, len
, psta
);
2692 } else if ((pmlmeinfo
->state
&0x03) == WIFI_FW_ADHOC_STATE
) {
2693 psta
= rtw_get_stainfo(pstapriv
, GetAddr2Ptr(pframe
));
2695 /* update WMM, ERP in the beacon */
2696 /* todo: the timer is used instead of the number of the beacon received */
2697 if ((sta_rx_pkts(psta
) & 0xf) == 0)
2698 update_beacon_info(padapter
, pframe
, len
, psta
);
2700 /* allocate a new CAM entry for IBSS station */
2701 cam_idx
= allocate_fw_sta_entry(padapter
);
2702 if (cam_idx
== NUM_STA
)
2703 goto _END_ONBEACON_
;
2705 /* get supported rate */
2706 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
) {
2707 pmlmeinfo
->FW_sta_info
[cam_idx
].status
= 0;
2708 goto _END_ONBEACON_
;
2711 /* update TSF Value */
2712 update_TSF(pmlmeext
, pframe
, len
);
2714 /* report sta add event */
2715 report_add_sta_event(padapter
, GetAddr2Ptr(pframe
), cam_idx
);
2725 #ifdef CONFIG_88EU_AP_MODE
2726 static unsigned int OnAuth(struct adapter
*padapter
,
2727 struct recv_frame
*precv_frame
)
2729 unsigned int auth_mode
, ie_len
;
2731 unsigned char *sa
, *p
;
2734 static struct sta_info stat
;
2735 struct sta_info
*pstat
= NULL
;
2736 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2737 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
2738 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2739 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2740 u8
*pframe
= precv_frame
->rx_data
;
2741 uint len
= precv_frame
->len
;
2743 if ((pmlmeinfo
->state
&0x03) != WIFI_FW_AP_STATE
)
2746 DBG_88E("+OnAuth\n");
2748 sa
= GetAddr2Ptr(pframe
);
2750 auth_mode
= psecuritypriv
->dot11AuthAlgrthm
;
2751 seq
= le16_to_cpu(*(__le16
*)((size_t)pframe
+ WLAN_HDR_A3_LEN
+ 2));
2752 algorithm
= le16_to_cpu(*(__le16
*)((size_t)pframe
+ WLAN_HDR_A3_LEN
));
2754 DBG_88E("auth alg=%x, seq=%X\n", algorithm
, seq
);
2756 if (auth_mode
== 2 && psecuritypriv
->dot11PrivacyAlgrthm
!= _WEP40_
&&
2757 psecuritypriv
->dot11PrivacyAlgrthm
!= _WEP104_
)
2760 if ((algorithm
> 0 && auth_mode
== 0) || /* rx a shared-key auth but shared not enabled */
2761 (algorithm
== 0 && auth_mode
== 1)) { /* rx a open-system auth but shared-key is enabled */
2762 DBG_88E("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
2763 algorithm
, auth_mode
, sa
[0], sa
[1], sa
[2], sa
[3], sa
[4], sa
[5]);
2765 status
= _STATS_NO_SUPP_ALG_
;
2770 if (!rtw_access_ctrl(padapter
, sa
)) {
2771 status
= _STATS_UNABLE_HANDLE_STA_
;
2775 pstat
= rtw_get_stainfo(pstapriv
, sa
);
2776 if (pstat
== NULL
) {
2777 /* allocate a new one */
2778 DBG_88E("going to alloc stainfo for sa=%pM\n", sa
);
2779 pstat
= rtw_alloc_stainfo(pstapriv
, sa
);
2780 if (pstat
== NULL
) {
2781 DBG_88E(" Exceed the upper limit of supported clients...\n");
2782 status
= _STATS_UNABLE_HANDLE_STA_
;
2786 pstat
->state
= WIFI_FW_AUTH_NULL
;
2787 pstat
->auth_seq
= 0;
2789 spin_lock_bh(&pstapriv
->asoc_list_lock
);
2790 if (!list_empty(&pstat
->asoc_list
)) {
2791 list_del_init(&pstat
->asoc_list
);
2792 pstapriv
->asoc_list_cnt
--;
2794 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
2797 /* TODO: STA re_auth and auth timeout */
2801 spin_lock_bh(&pstapriv
->auth_list_lock
);
2802 if (list_empty(&pstat
->auth_list
)) {
2803 list_add_tail(&pstat
->auth_list
, &pstapriv
->auth_list
);
2804 pstapriv
->auth_list_cnt
++;
2806 spin_unlock_bh(&pstapriv
->auth_list_lock
);
2808 if (pstat
->auth_seq
== 0)
2809 pstat
->expire_to
= pstapriv
->auth_to
;
2811 if ((pstat
->auth_seq
+ 1) != seq
) {
2812 DBG_88E("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2813 seq
, pstat
->auth_seq
+1);
2814 status
= _STATS_OUT_OF_AUTH_SEQ_
;
2818 if (algorithm
== 0 && (auth_mode
== 0 || auth_mode
== 2)) {
2820 pstat
->state
&= ~WIFI_FW_AUTH_NULL
;
2821 pstat
->state
|= WIFI_FW_AUTH_SUCCESS
;
2822 pstat
->expire_to
= pstapriv
->assoc_to
;
2823 pstat
->authalg
= algorithm
;
2825 DBG_88E("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2826 seq
, pstat
->auth_seq
+1);
2827 status
= _STATS_OUT_OF_AUTH_SEQ_
;
2830 } else { /* shared system or auto authentication */
2832 /* prepare for the challenging txt... */
2834 pstat
->state
&= ~WIFI_FW_AUTH_NULL
;
2835 pstat
->state
|= WIFI_FW_AUTH_STATE
;
2836 pstat
->authalg
= algorithm
;
2837 pstat
->auth_seq
= 2;
2838 } else if (seq
== 3) {
2839 /* checking for challenging txt... */
2840 DBG_88E("checking for challenging txt...\n");
2842 p
= rtw_get_ie(pframe
+ WLAN_HDR_A3_LEN
+ 4 + _AUTH_IE_OFFSET_
, _CHLGETXT_IE_
, (int *)&ie_len
,
2843 len
- WLAN_HDR_A3_LEN
- _AUTH_IE_OFFSET_
- 4);
2845 if ((p
== NULL
) || (ie_len
<= 0)) {
2846 DBG_88E("auth rejected because challenge failure!(1)\n");
2847 status
= _STATS_CHALLENGE_FAIL_
;
2851 if (!memcmp((void *)(p
+ 2), pstat
->chg_txt
, 128)) {
2852 pstat
->state
&= (~WIFI_FW_AUTH_STATE
);
2853 pstat
->state
|= WIFI_FW_AUTH_SUCCESS
;
2854 /* challenging txt is correct... */
2855 pstat
->expire_to
= pstapriv
->assoc_to
;
2857 DBG_88E("auth rejected because challenge failure!\n");
2858 status
= _STATS_CHALLENGE_FAIL_
;
2862 DBG_88E("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2863 seq
, pstat
->auth_seq
+1);
2864 status
= _STATS_OUT_OF_AUTH_SEQ_
;
2869 /* Now, we are going to issue_auth... */
2870 pstat
->auth_seq
= seq
+ 1;
2872 issue_auth(padapter
, pstat
, (unsigned short)(_STATS_SUCCESSFUL_
));
2874 if (pstat
->state
& WIFI_FW_AUTH_SUCCESS
)
2875 pstat
->auth_seq
= 0;
2882 rtw_free_stainfo(padapter
, pstat
);
2885 memset((char *)pstat
, '\0', sizeof(stat
));
2886 pstat
->auth_seq
= 2;
2887 memcpy(pstat
->hwaddr
, sa
, 6);
2889 issue_auth(padapter
, pstat
, (unsigned short)status
);
2893 #endif /* CONFIG_88EU_AP_MODE */
2895 static unsigned int OnAuthClient(struct adapter
*padapter
,
2896 struct recv_frame
*precv_frame
)
2898 unsigned int seq
, len
, status
, offset
;
2900 unsigned int go2asoc
= 0;
2901 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2902 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2903 u8
*pframe
= precv_frame
->rx_data
;
2904 uint pkt_len
= precv_frame
->len
;
2906 DBG_88E("%s\n", __func__
);
2908 /* check A1 matches or not */
2909 if (memcmp(myid(&(padapter
->eeprompriv
)), get_da(pframe
), ETH_ALEN
))
2912 if (!(pmlmeinfo
->state
& WIFI_FW_AUTH_STATE
))
2915 offset
= (GetPrivacy(pframe
)) ? 4 : 0;
2917 seq
= le16_to_cpu(*(__le16
*)((size_t)pframe
+ WLAN_HDR_A3_LEN
+ offset
+ 2));
2918 status
= le16_to_cpu(*(__le16
*)((size_t)pframe
+ WLAN_HDR_A3_LEN
+ offset
+ 4));
2921 DBG_88E("clnt auth fail, status: %d\n", status
);
2922 if (status
== 13) { /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
2923 if (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_Shared
)
2924 pmlmeinfo
->auth_algo
= dot11AuthAlgrthm_Open
;
2926 pmlmeinfo
->auth_algo
= dot11AuthAlgrthm_Shared
;
2929 set_link_timer(pmlmeext
, 1);
2934 if (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_Shared
) {
2935 /* legendary shared system */
2936 p
= rtw_get_ie(pframe
+ WLAN_HDR_A3_LEN
+ _AUTH_IE_OFFSET_
, _CHLGETXT_IE_
, (int *)&len
,
2937 pkt_len
- WLAN_HDR_A3_LEN
- _AUTH_IE_OFFSET_
);
2942 memcpy((void *)(pmlmeinfo
->chg_txt
), (void *)(p
+ 2), len
);
2943 pmlmeinfo
->auth_seq
= 3;
2944 issue_auth(padapter
, NULL
, 0);
2945 set_link_timer(pmlmeext
, REAUTH_TO
);
2952 } else if (seq
== 4) {
2953 if (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_Shared
)
2958 /* this is also illegal */
2963 DBG_88E_LEVEL(_drv_info_
, "auth success, start assoc\n");
2964 start_clnt_assoc(padapter
);
2971 static unsigned int OnAssocReq(struct adapter
*padapter
,
2972 struct recv_frame
*precv_frame
)
2974 #ifdef CONFIG_88EU_AP_MODE
2976 struct rtw_ieee802_11_elems elems
;
2977 struct sta_info
*pstat
;
2978 unsigned char reassoc
, *p
, *pos
, *wpa_ie
;
2979 unsigned char WMM_IE
[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
2980 int i
, ie_len
, wpa_ie_len
, left
;
2981 unsigned char supportRate
[16];
2983 unsigned short status
= _STATS_SUCCESSFUL_
;
2984 unsigned short frame_type
, ie_offset
= 0;
2985 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2986 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
2987 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2988 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2989 struct wlan_bssid_ex
*cur
= &(pmlmeinfo
->network
);
2990 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2991 u8
*pframe
= precv_frame
->rx_data
;
2992 uint pkt_len
= precv_frame
->len
;
2994 if ((pmlmeinfo
->state
&0x03) != WIFI_FW_AP_STATE
)
2997 frame_type
= GetFrameSubType(pframe
);
2998 if (frame_type
== WIFI_ASSOCREQ
) {
3000 ie_offset
= _ASOCREQ_IE_OFFSET_
;
3001 } else { /* WIFI_REASSOCREQ */
3003 ie_offset
= _REASOCREQ_IE_OFFSET_
;
3007 if (pkt_len
< IEEE80211_3ADDR_LEN
+ ie_offset
) {
3008 DBG_88E("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
3009 "\n", reassoc
, (unsigned long)pkt_len
);
3013 pstat
= rtw_get_stainfo(pstapriv
, GetAddr2Ptr(pframe
));
3014 if (pstat
== NULL
) {
3015 status
= _RSON_CLS2_
;
3016 goto asoc_class2_error
;
3019 capab_info
= get_unaligned_le16(pframe
+ WLAN_HDR_A3_LEN
);
3021 left
= pkt_len
- (IEEE80211_3ADDR_LEN
+ ie_offset
);
3022 pos
= pframe
+ (IEEE80211_3ADDR_LEN
+ ie_offset
);
3025 DBG_88E("%s\n", __func__
);
3027 /* check if this stat has been successfully authenticated/assocated */
3028 if (!((pstat
->state
) & WIFI_FW_AUTH_SUCCESS
)) {
3029 if (!((pstat
->state
) & WIFI_FW_ASSOC_SUCCESS
)) {
3030 status
= _RSON_CLS2_
;
3031 goto asoc_class2_error
;
3033 pstat
->state
&= (~WIFI_FW_ASSOC_SUCCESS
);
3034 pstat
->state
|= WIFI_FW_ASSOC_STATE
;
3037 pstat
->state
&= (~WIFI_FW_AUTH_SUCCESS
);
3038 pstat
->state
|= WIFI_FW_ASSOC_STATE
;
3040 pstat
->capability
= capab_info
;
3041 /* now parse all ieee802_11 ie to point to elems */
3042 if (rtw_ieee802_11_parse_elems(pos
, left
, &elems
, 1) == ParseFailed
||
3044 DBG_88E("STA %pM sent invalid association request\n",
3046 status
= _STATS_FAILURE_
;
3047 goto OnAssocReqFail
;
3051 /* now we should check all the fields... */
3053 p
= rtw_get_ie(pframe
+ WLAN_HDR_A3_LEN
+ ie_offset
, _SSID_IE_
, &ie_len
,
3054 pkt_len
- WLAN_HDR_A3_LEN
- ie_offset
);
3056 status
= _STATS_FAILURE_
;
3058 if (ie_len
== 0) { /* broadcast ssid, however it is not allowed in assocreq */
3059 status
= _STATS_FAILURE_
;
3061 /* check if ssid match */
3062 if (memcmp((void *)(p
+2), cur
->Ssid
.Ssid
, cur
->Ssid
.SsidLength
))
3063 status
= _STATS_FAILURE_
;
3065 if (ie_len
!= cur
->Ssid
.SsidLength
)
3066 status
= _STATS_FAILURE_
;
3069 if (_STATS_SUCCESSFUL_
!= status
)
3070 goto OnAssocReqFail
;
3072 /* check if the supported rate is ok */
3073 p
= rtw_get_ie(pframe
+ WLAN_HDR_A3_LEN
+ ie_offset
, _SUPPORTEDRATES_IE_
, &ie_len
, pkt_len
- WLAN_HDR_A3_LEN
- ie_offset
);
3075 DBG_88E("Rx a sta assoc-req which supported rate is empty!\n");
3076 /* use our own rate set as statoin used */
3077 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
3078 /* supportRateNum = AP_BSSRATE_LEN; */
3080 status
= _STATS_FAILURE_
;
3081 goto OnAssocReqFail
;
3083 memcpy(supportRate
, p
+2, ie_len
);
3084 supportRateNum
= ie_len
;
3086 p
= rtw_get_ie(pframe
+ WLAN_HDR_A3_LEN
+ ie_offset
, _EXT_SUPPORTEDRATES_IE_
, &ie_len
,
3087 pkt_len
- WLAN_HDR_A3_LEN
- ie_offset
);
3089 if (supportRateNum
<= sizeof(supportRate
)) {
3090 memcpy(supportRate
+supportRateNum
, p
+2, ie_len
);
3091 supportRateNum
+= ie_len
;
3096 /* todo: mask supportRate between AP & STA -> move to update raid */
3097 /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
3099 /* update station supportRate */
3100 pstat
->bssratelen
= supportRateNum
;
3101 memcpy(pstat
->bssrateset
, supportRate
, supportRateNum
);
3102 UpdateBrateTblForSoftAP(pstat
->bssrateset
, pstat
->bssratelen
);
3104 /* check RSN/WPA/WPS */
3105 pstat
->dot8021xalg
= 0;
3107 pstat
->wpa_group_cipher
= 0;
3108 pstat
->wpa2_group_cipher
= 0;
3109 pstat
->wpa_pairwise_cipher
= 0;
3110 pstat
->wpa2_pairwise_cipher
= 0;
3111 memset(pstat
->wpa_ie
, 0, sizeof(pstat
->wpa_ie
));
3112 if ((psecuritypriv
->wpa_psk
& BIT(1)) && elems
.rsn_ie
) {
3113 int group_cipher
= 0, pairwise_cipher
= 0;
3115 wpa_ie
= elems
.rsn_ie
;
3116 wpa_ie_len
= elems
.rsn_ie_len
;
3118 if (rtw_parse_wpa2_ie(wpa_ie
-2, wpa_ie_len
+2, &group_cipher
, &pairwise_cipher
, NULL
) == _SUCCESS
) {
3119 pstat
->dot8021xalg
= 1;/* psk, todo:802.1x */
3120 pstat
->wpa_psk
|= BIT(1);
3122 pstat
->wpa2_group_cipher
= group_cipher
&psecuritypriv
->wpa2_group_cipher
;
3123 pstat
->wpa2_pairwise_cipher
= pairwise_cipher
&psecuritypriv
->wpa2_pairwise_cipher
;
3125 if (!pstat
->wpa2_group_cipher
)
3126 status
= WLAN_STATUS_INVALID_GROUP_CIPHER
;
3128 if (!pstat
->wpa2_pairwise_cipher
)
3129 status
= WLAN_STATUS_INVALID_PAIRWISE_CIPHER
;
3131 status
= WLAN_STATUS_INVALID_IE
;
3133 } else if ((psecuritypriv
->wpa_psk
& BIT(0)) && elems
.wpa_ie
) {
3134 int group_cipher
= 0, pairwise_cipher
= 0;
3136 wpa_ie
= elems
.wpa_ie
;
3137 wpa_ie_len
= elems
.wpa_ie_len
;
3139 if (rtw_parse_wpa_ie(wpa_ie
-2, wpa_ie_len
+2, &group_cipher
, &pairwise_cipher
, NULL
) == _SUCCESS
) {
3140 pstat
->dot8021xalg
= 1;/* psk, todo:802.1x */
3141 pstat
->wpa_psk
|= BIT(0);
3143 pstat
->wpa_group_cipher
= group_cipher
&psecuritypriv
->wpa_group_cipher
;
3144 pstat
->wpa_pairwise_cipher
= pairwise_cipher
&psecuritypriv
->wpa_pairwise_cipher
;
3146 if (!pstat
->wpa_group_cipher
)
3147 status
= WLAN_STATUS_INVALID_GROUP_CIPHER
;
3149 if (!pstat
->wpa_pairwise_cipher
)
3150 status
= WLAN_STATUS_INVALID_PAIRWISE_CIPHER
;
3152 status
= WLAN_STATUS_INVALID_IE
;
3159 if (_STATS_SUCCESSFUL_
!= status
)
3160 goto OnAssocReqFail
;
3162 pstat
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
);
3163 if (wpa_ie
== NULL
) {
3165 DBG_88E("STA included WPS IE in "
3166 "(Re)Association Request - assume WPS is "
3168 pstat
->flags
|= WLAN_STA_WPS
;
3169 /* wpabuf_free(sta->wps_ie); */
3170 /* sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, */
3171 /* elems.wps_ie_len - 4); */
3173 DBG_88E("STA did not include WPA/RSN IE "
3174 "in (Re)Association Request - possible WPS "
3176 pstat
->flags
|= WLAN_STA_MAYBE_WPS
;
3180 /* AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */
3181 /* that the selected registrar of AP is _FLASE */
3182 if ((psecuritypriv
->wpa_psk
> 0) && (pstat
->flags
& (WLAN_STA_WPS
|WLAN_STA_MAYBE_WPS
))) {
3183 if (pmlmepriv
->wps_beacon_ie
) {
3184 u8 selected_registrar
= 0;
3186 rtw_get_wps_attr_content(pmlmepriv
->wps_beacon_ie
, pmlmepriv
->wps_beacon_ie_len
, WPS_ATTR_SELECTED_REGISTRAR
, &selected_registrar
, NULL
);
3188 if (!selected_registrar
) {
3189 DBG_88E("selected_registrar is false , or AP is not ready to do WPS\n");
3191 status
= _STATS_UNABLE_HANDLE_STA_
;
3193 goto OnAssocReqFail
;
3200 if (psecuritypriv
->wpa_psk
== 0) {
3201 DBG_88E("STA %pM: WPA/RSN IE in association "
3202 "request, but AP don't support WPA/RSN\n", pstat
->hwaddr
);
3204 status
= WLAN_STATUS_INVALID_IE
;
3206 goto OnAssocReqFail
;
3210 DBG_88E("STA included WPS IE in "
3211 "(Re)Association Request - WPS is "
3213 pstat
->flags
|= WLAN_STA_WPS
;
3216 copy_len
= ((wpa_ie_len
+2) > sizeof(pstat
->wpa_ie
)) ? (sizeof(pstat
->wpa_ie
)) : (wpa_ie_len
+2);
3219 memcpy(pstat
->wpa_ie
, wpa_ie
-2, copy_len
);
3221 /* check if there is WMM IE & support WWM-PS */
3222 pstat
->flags
&= ~WLAN_STA_WME
;
3223 pstat
->qos_option
= 0;
3224 pstat
->qos_info
= 0;
3225 pstat
->has_legacy_ac
= true;
3226 pstat
->uapsd_vo
= 0;
3227 pstat
->uapsd_vi
= 0;
3228 pstat
->uapsd_be
= 0;
3229 pstat
->uapsd_bk
= 0;
3230 if (pmlmepriv
->qospriv
.qos_option
) {
3231 p
= pframe
+ WLAN_HDR_A3_LEN
+ ie_offset
; ie_len
= 0;
3233 p
= rtw_get_ie(p
, _VENDOR_SPECIFIC_IE_
, &ie_len
, pkt_len
- WLAN_HDR_A3_LEN
- ie_offset
);
3235 if (!memcmp(p
+2, WMM_IE
, 6)) {
3236 pstat
->flags
|= WLAN_STA_WME
;
3238 pstat
->qos_option
= 1;
3239 pstat
->qos_info
= *(p
+8);
3241 pstat
->max_sp_len
= (pstat
->qos_info
>>5)&0x3;
3243 if ((pstat
->qos_info
&0xf) != 0xf)
3244 pstat
->has_legacy_ac
= true;
3246 pstat
->has_legacy_ac
= false;
3248 if (pstat
->qos_info
&0xf) {
3249 if (pstat
->qos_info
&BIT(0))
3250 pstat
->uapsd_vo
= BIT(0)|BIT(1);
3252 pstat
->uapsd_vo
= 0;
3254 if (pstat
->qos_info
&BIT(1))
3255 pstat
->uapsd_vi
= BIT(0)|BIT(1);
3257 pstat
->uapsd_vi
= 0;
3259 if (pstat
->qos_info
&BIT(2))
3260 pstat
->uapsd_bk
= BIT(0)|BIT(1);
3262 pstat
->uapsd_bk
= 0;
3264 if (pstat
->qos_info
&BIT(3))
3265 pstat
->uapsd_be
= BIT(0)|BIT(1);
3267 pstat
->uapsd_be
= 0;
3278 /* save HT capabilities in the sta object */
3279 memset(&pstat
->htpriv
.ht_cap
, 0, sizeof(struct rtw_ieee80211_ht_cap
));
3280 if (elems
.ht_capabilities
&& elems
.ht_capabilities_len
>= sizeof(struct rtw_ieee80211_ht_cap
)) {
3281 pstat
->flags
|= WLAN_STA_HT
;
3283 pstat
->flags
|= WLAN_STA_WME
;
3285 memcpy(&pstat
->htpriv
.ht_cap
, elems
.ht_capabilities
, sizeof(struct rtw_ieee80211_ht_cap
));
3287 pstat
->flags
&= ~WLAN_STA_HT
;
3289 if ((!pmlmepriv
->htpriv
.ht_option
) && (pstat
->flags
&WLAN_STA_HT
)) {
3290 status
= _STATS_FAILURE_
;
3291 goto OnAssocReqFail
;
3294 if ((pstat
->flags
& WLAN_STA_HT
) &&
3295 ((pstat
->wpa2_pairwise_cipher
&WPA_CIPHER_TKIP
) ||
3296 (pstat
->wpa_pairwise_cipher
&WPA_CIPHER_TKIP
))) {
3297 DBG_88E("HT: %pM tried to "
3298 "use TKIP with HT association\n", pstat
->hwaddr
);
3300 /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
3301 /* goto OnAssocReqFail; */
3304 pstat
->flags
|= WLAN_STA_NONERP
;
3305 for (i
= 0; i
< pstat
->bssratelen
; i
++) {
3306 if ((pstat
->bssrateset
[i
] & 0x7f) > 22) {
3307 pstat
->flags
&= ~WLAN_STA_NONERP
;
3312 if (pstat
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
3313 pstat
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
3315 pstat
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
3319 if (status
!= _STATS_SUCCESSFUL_
)
3320 goto OnAssocReqFail
;
3322 /* TODO: identify_proprietary_vendor_ie(); */
3323 /* Realtek proprietary IE */
3324 /* identify if this is Broadcom sta */
3325 /* identify if this is ralink sta */
3326 /* Customer proprietary IE */
3328 /* get a unique AID */
3329 if (pstat
->aid
> 0) {
3330 DBG_88E(" old AID %d\n", pstat
->aid
);
3332 for (pstat
->aid
= 1; pstat
->aid
<= NUM_STA
; pstat
->aid
++)
3333 if (pstapriv
->sta_aid
[pstat
->aid
- 1] == NULL
)
3336 /* if (pstat->aid > NUM_STA) { */
3337 if (pstat
->aid
> pstapriv
->max_num_sta
) {
3340 DBG_88E(" no room for more AIDs\n");
3342 status
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3344 goto OnAssocReqFail
;
3346 pstapriv
->sta_aid
[pstat
->aid
- 1] = pstat
;
3347 DBG_88E("allocate new AID=(%d)\n", pstat
->aid
);
3351 pstat
->state
&= (~WIFI_FW_ASSOC_STATE
);
3352 pstat
->state
|= WIFI_FW_ASSOC_SUCCESS
;
3354 spin_lock_bh(&pstapriv
->auth_list_lock
);
3355 if (!list_empty(&pstat
->auth_list
)) {
3356 list_del_init(&pstat
->auth_list
);
3357 pstapriv
->auth_list_cnt
--;
3359 spin_unlock_bh(&pstapriv
->auth_list_lock
);
3361 spin_lock_bh(&pstapriv
->asoc_list_lock
);
3362 if (list_empty(&pstat
->asoc_list
)) {
3363 pstat
->expire_to
= pstapriv
->expire_to
;
3364 list_add_tail(&pstat
->asoc_list
, &pstapriv
->asoc_list
);
3365 pstapriv
->asoc_list_cnt
++;
3367 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
3369 /* now the station is qualified to join our BSS... */
3370 if ((pstat
->state
& WIFI_FW_ASSOC_SUCCESS
) && (_STATS_SUCCESSFUL_
== status
)) {
3371 /* 1 bss_cap_update & sta_info_update */
3372 bss_cap_update_on_sta_join(padapter
, pstat
);
3373 sta_info_update(padapter
, pstat
);
3375 /* issue assoc rsp before notify station join event. */
3376 if (frame_type
== WIFI_ASSOCREQ
)
3377 issue_asocrsp(padapter
, status
, pstat
, WIFI_ASSOCRSP
);
3379 issue_asocrsp(padapter
, status
, pstat
, WIFI_REASSOCRSP
);
3381 /* 2 - report to upper layer */
3382 DBG_88E("indicate_sta_join_event to upper layer - hostapd\n");
3383 rtw_indicate_sta_assoc_event(padapter
, pstat
);
3385 /* 3-(1) report sta add event */
3386 report_add_sta_event(padapter
, pstat
->hwaddr
, pstat
->aid
);
3393 issue_deauth(padapter
, (void *)GetAddr2Ptr(pframe
), status
);
3400 if (frame_type
== WIFI_ASSOCREQ
)
3401 issue_asocrsp(padapter
, status
, pstat
, WIFI_ASSOCRSP
);
3403 issue_asocrsp(padapter
, status
, pstat
, WIFI_REASSOCRSP
);
3405 #endif /* CONFIG_88EU_AP_MODE */
3410 static unsigned int OnAssocRsp(struct adapter
*padapter
,
3411 struct recv_frame
*precv_frame
)
3415 unsigned short status
;
3416 struct ndis_802_11_var_ie
*pIE
;
3417 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
3418 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3419 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
3420 /* struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); */
3421 u8
*pframe
= precv_frame
->rx_data
;
3422 uint pkt_len
= precv_frame
->len
;
3424 DBG_88E("%s\n", __func__
);
3426 /* check A1 matches or not */
3427 if (memcmp(myid(&(padapter
->eeprompriv
)), get_da(pframe
), ETH_ALEN
))
3430 if (!(pmlmeinfo
->state
& (WIFI_FW_AUTH_SUCCESS
| WIFI_FW_ASSOC_STATE
)))
3433 if (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
)
3436 del_timer_sync(&pmlmeext
->link_timer
);
3439 status
= le16_to_cpu(*(__le16
*)(pframe
+ WLAN_HDR_A3_LEN
+ 2));
3441 DBG_88E("assoc reject, status code: %d\n", status
);
3442 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
3444 goto report_assoc_result
;
3447 /* get capabilities */
3448 pmlmeinfo
->capability
= le16_to_cpu(*(__le16
*)(pframe
+ WLAN_HDR_A3_LEN
));
3451 pmlmeinfo
->slotTime
= (pmlmeinfo
->capability
& BIT(10)) ? 9 : 20;
3454 pmlmeinfo
->aid
= (int)(le16_to_cpu(*(__le16
*)(pframe
+ WLAN_HDR_A3_LEN
+ 4))&0x3fff);
3455 res
= pmlmeinfo
->aid
;
3457 /* following are moved to join event callback function */
3458 /* to handle HT, WMM, rate adaptive, update MAC reg */
3459 /* for not to handle the synchronous IO in the tasklet */
3460 for (i
= (6 + WLAN_HDR_A3_LEN
); i
< pkt_len
;) {
3461 pIE
= (struct ndis_802_11_var_ie
*)(pframe
+ i
);
3463 switch (pIE
->ElementID
) {
3464 case _VENDOR_SPECIFIC_IE_
:
3465 if (!memcmp(pIE
->data
, WMM_PARA_OUI
, 6)) /* WMM */
3466 WMM_param_handler(padapter
, pIE
);
3468 case _HT_CAPABILITY_IE_
: /* HT caps */
3469 HT_caps_handler(padapter
, pIE
);
3471 case _HT_EXTRA_INFO_IE_
: /* HT info */
3472 HT_info_handler(padapter
, pIE
);
3475 ERP_IE_handler(padapter
, pIE
);
3480 i
+= (pIE
->Length
+ 2);
3483 pmlmeinfo
->state
&= (~WIFI_FW_ASSOC_STATE
);
3484 pmlmeinfo
->state
|= WIFI_FW_ASSOC_SUCCESS
;
3486 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
3487 UpdateBrateTbl(padapter
, pmlmeinfo
->network
.SupportedRates
);
3489 report_assoc_result
:
3491 rtw_buf_update(&pmlmepriv
->assoc_rsp
, &pmlmepriv
->assoc_rsp_len
, pframe
, pkt_len
);
3493 rtw_buf_free(&pmlmepriv
->assoc_rsp
, &pmlmepriv
->assoc_rsp_len
);
3496 report_join_res(padapter
, res
);
3501 static unsigned int OnDeAuth(struct adapter
*padapter
,
3502 struct recv_frame
*precv_frame
)
3504 unsigned short reason
;
3505 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
3506 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3507 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
3508 u8
*pframe
= precv_frame
->rx_data
;
3509 struct wlan_bssid_ex
*pnetwork
= &(pmlmeinfo
->network
);
3512 if (memcmp(GetAddr3Ptr(pframe
), pnetwork
->MacAddress
, ETH_ALEN
))
3515 reason
= le16_to_cpu(*(__le16
*)(pframe
+ WLAN_HDR_A3_LEN
));
3517 DBG_88E("%s Reason code(%d)\n", __func__
, reason
);
3519 #ifdef CONFIG_88EU_AP_MODE
3520 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
3521 struct sta_info
*psta
;
3522 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
3524 DBG_88E_LEVEL(_drv_always_
, "ap recv deauth reason code(%d) sta:%pM\n",
3525 reason
, GetAddr2Ptr(pframe
));
3527 psta
= rtw_get_stainfo(pstapriv
, GetAddr2Ptr(pframe
));
3531 spin_lock_bh(&pstapriv
->asoc_list_lock
);
3532 if (!list_empty(&psta
->asoc_list
)) {
3533 list_del_init(&psta
->asoc_list
);
3534 pstapriv
->asoc_list_cnt
--;
3535 updated
= ap_free_sta(padapter
, psta
, false, reason
);
3537 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
3539 associated_clients_update(padapter
, updated
);
3547 DBG_88E_LEVEL(_drv_always_
, "sta recv deauth reason code(%d) sta:%pM\n",
3548 reason
, GetAddr3Ptr(pframe
));
3550 receive_disconnect(padapter
, GetAddr3Ptr(pframe
) , reason
);
3552 pmlmepriv
->LinkDetectInfo
.bBusyTraffic
= false;
3556 static unsigned int OnDisassoc(struct adapter
*padapter
,
3557 struct recv_frame
*precv_frame
)
3560 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
3561 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3562 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
3563 u8
*pframe
= precv_frame
->rx_data
;
3564 struct wlan_bssid_ex
*pnetwork
= &(pmlmeinfo
->network
);
3567 if (memcmp(GetAddr3Ptr(pframe
), pnetwork
->MacAddress
, ETH_ALEN
))
3570 reason
= le16_to_cpu(*(__le16
*)(pframe
+ WLAN_HDR_A3_LEN
));
3572 DBG_88E("%s Reason code(%d)\n", __func__
, reason
);
3574 #ifdef CONFIG_88EU_AP_MODE
3575 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
3576 struct sta_info
*psta
;
3577 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
3579 DBG_88E_LEVEL(_drv_always_
, "ap recv disassoc reason code(%d) sta:%pM\n",
3580 reason
, GetAddr2Ptr(pframe
));
3582 psta
= rtw_get_stainfo(pstapriv
, GetAddr2Ptr(pframe
));
3586 spin_lock_bh(&pstapriv
->asoc_list_lock
);
3587 if (!list_empty(&psta
->asoc_list
)) {
3588 list_del_init(&psta
->asoc_list
);
3589 pstapriv
->asoc_list_cnt
--;
3590 updated
= ap_free_sta(padapter
, psta
, false, reason
);
3592 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
3594 associated_clients_update(padapter
, updated
);
3601 DBG_88E_LEVEL(_drv_always_
, "ap recv disassoc reason code(%d) sta:%pM\n",
3602 reason
, GetAddr3Ptr(pframe
));
3604 receive_disconnect(padapter
, GetAddr3Ptr(pframe
), reason
);
3606 pmlmepriv
->LinkDetectInfo
.bBusyTraffic
= false;
3610 static unsigned int OnAtim(struct adapter
*padapter
,
3611 struct recv_frame
*precv_frame
)
3613 DBG_88E("%s\n", __func__
);
3617 static unsigned int on_action_spct(struct adapter
*padapter
,
3618 struct recv_frame
*precv_frame
)
3620 struct sta_info
*psta
= NULL
;
3621 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
3622 u8
*pframe
= precv_frame
->rx_data
;
3623 u8
*frame_body
= (u8
*)(pframe
+ sizeof(struct rtw_ieee80211_hdr_3addr
));
3627 DBG_88E(FUNC_NDEV_FMT
"\n", FUNC_NDEV_ARG(padapter
->pnetdev
));
3629 psta
= rtw_get_stainfo(pstapriv
, GetAddr2Ptr(pframe
));
3634 category
= frame_body
[0];
3635 if (category
!= RTW_WLAN_CATEGORY_SPECTRUM_MGMT
)
3638 action
= frame_body
[1];
3640 case RTW_WLAN_ACTION_SPCT_MSR_REQ
:
3641 case RTW_WLAN_ACTION_SPCT_MSR_RPRT
:
3642 case RTW_WLAN_ACTION_SPCT_TPC_REQ
:
3643 case RTW_WLAN_ACTION_SPCT_TPC_RPRT
:
3645 case RTW_WLAN_ACTION_SPCT_CHL_SWITCH
:
3655 static unsigned int OnAction_qos(struct adapter
*padapter
,
3656 struct recv_frame
*precv_frame
)
3661 static unsigned int OnAction_dls(struct adapter
*padapter
,
3662 struct recv_frame
*precv_frame
)
3667 static unsigned int OnAction_back(struct adapter
*padapter
,
3668 struct recv_frame
*precv_frame
)
3671 struct sta_info
*psta
= NULL
;
3672 struct recv_reorder_ctrl
*preorder_ctrl
;
3673 unsigned char *frame_body
;
3674 unsigned char category
, action
;
3675 unsigned short tid
, status
, reason_code
= 0;
3676 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3677 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
3678 u8
*pframe
= precv_frame
->rx_data
;
3679 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
3680 /* check RA matches or not */
3681 if (memcmp(myid(&(padapter
->eeprompriv
)), GetAddr1Ptr(pframe
),
3682 ETH_ALEN
))/* for if1, sta/ap mode */
3685 DBG_88E("%s\n", __func__
);
3687 if ((pmlmeinfo
->state
&0x03) != WIFI_FW_AP_STATE
)
3688 if (!(pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
))
3691 addr
= GetAddr2Ptr(pframe
);
3692 psta
= rtw_get_stainfo(pstapriv
, addr
);
3697 frame_body
= (unsigned char *)(pframe
+ sizeof(struct rtw_ieee80211_hdr_3addr
));
3699 category
= frame_body
[0];
3700 if (category
== RTW_WLAN_CATEGORY_BACK
) { /* representing Block Ack */
3701 if (!pmlmeinfo
->HT_enable
)
3703 action
= frame_body
[1];
3704 DBG_88E("%s, action=%d\n", __func__
, action
);
3706 case RTW_WLAN_ACTION_ADDBA_REQ
: /* ADDBA request */
3707 memcpy(&(pmlmeinfo
->ADDBA_req
), &(frame_body
[2]), sizeof(struct ADDBA_request
));
3708 process_addba_req(padapter
, (u8
*)&(pmlmeinfo
->ADDBA_req
), addr
);
3710 if (pmlmeinfo
->bAcceptAddbaReq
)
3711 issue_action_BA(padapter
, addr
, RTW_WLAN_ACTION_ADDBA_RESP
, 0);
3713 issue_action_BA(padapter
, addr
, RTW_WLAN_ACTION_ADDBA_RESP
, 37);/* reject ADDBA Req */
3715 case RTW_WLAN_ACTION_ADDBA_RESP
: /* ADDBA response */
3716 status
= get_unaligned_le16(&frame_body
[3]);
3717 tid
= (frame_body
[5] >> 2) & 0x7;
3718 if (status
== 0) { /* successful */
3719 DBG_88E("agg_enable for TID=%d\n", tid
);
3720 psta
->htpriv
.agg_enable_bitmap
|= 1 << tid
;
3721 psta
->htpriv
.candidate_tid_bitmap
&= ~BIT(tid
);
3723 psta
->htpriv
.agg_enable_bitmap
&= ~BIT(tid
);
3726 case RTW_WLAN_ACTION_DELBA
: /* DELBA */
3727 if ((frame_body
[3] & BIT(3)) == 0) {
3728 psta
->htpriv
.agg_enable_bitmap
&= ~(1 << ((frame_body
[3] >> 4) & 0xf));
3729 psta
->htpriv
.candidate_tid_bitmap
&= ~(1 << ((frame_body
[3] >> 4) & 0xf));
3730 reason_code
= get_unaligned_le16(&frame_body
[4]);
3731 } else if ((frame_body
[3] & BIT(3)) == BIT(3)) {
3732 tid
= (frame_body
[3] >> 4) & 0x0F;
3733 preorder_ctrl
= &psta
->recvreorder_ctrl
[tid
];
3734 preorder_ctrl
->enable
= false;
3735 preorder_ctrl
->indicate_seq
= 0xffff;
3737 DBG_88E("%s(): DELBA: %x(%x)\n", __func__
, pmlmeinfo
->agg_enable_bitmap
, reason_code
);
3738 /* todo: how to notify the host while receiving DELETE BA */
3747 static s32
rtw_action_public_decache(struct recv_frame
*recv_frame
, s32 token
)
3749 struct adapter
*adapter
= recv_frame
->adapter
;
3750 struct mlme_ext_priv
*mlmeext
= &(adapter
->mlmeextpriv
);
3751 u8
*frame
= recv_frame
->rx_data
;
3752 u16 seq_ctrl
= ((recv_frame
->attrib
.seq_num
&0xffff) << 4) |
3753 (recv_frame
->attrib
.frag_num
& 0xf);
3755 if (GetRetry(frame
)) {
3757 if ((seq_ctrl
== mlmeext
->action_public_rxseq
) && (token
== mlmeext
->action_public_dialog_token
)) {
3758 DBG_88E(FUNC_ADPT_FMT
" seq_ctrl = 0x%x, rxseq = 0x%x, token:%d\n",
3759 FUNC_ADPT_ARG(adapter
), seq_ctrl
, mlmeext
->action_public_rxseq
, token
);
3763 if (seq_ctrl
== mlmeext
->action_public_rxseq
) {
3764 DBG_88E(FUNC_ADPT_FMT
" seq_ctrl = 0x%x, rxseq = 0x%x\n",
3765 FUNC_ADPT_ARG(adapter
), seq_ctrl
, mlmeext
->action_public_rxseq
);
3771 mlmeext
->action_public_rxseq
= seq_ctrl
;
3774 mlmeext
->action_public_dialog_token
= token
;
3779 static unsigned int on_action_public_p2p(struct recv_frame
*precv_frame
)
3781 u8
*pframe
= precv_frame
->rx_data
;
3784 frame_body
= (unsigned char *)(pframe
+ sizeof(struct rtw_ieee80211_hdr_3addr
));
3786 dialogToken
= frame_body
[7];
3788 if (rtw_action_public_decache(precv_frame
, dialogToken
) == _FAIL
)
3794 static unsigned int on_action_public_vendor(struct recv_frame
*precv_frame
)
3796 unsigned int ret
= _FAIL
;
3797 u8
*pframe
= precv_frame
->rx_data
;
3798 u8
*frame_body
= pframe
+ sizeof(struct rtw_ieee80211_hdr_3addr
);
3800 if (!memcmp(frame_body
+ 2, P2P_OUI
, 4))
3801 ret
= on_action_public_p2p(precv_frame
);
3806 static unsigned int on_action_public_default(struct recv_frame
*precv_frame
, u8 action
)
3808 unsigned int ret
= _FAIL
;
3809 u8
*pframe
= precv_frame
->rx_data
;
3810 u8
*frame_body
= pframe
+ sizeof(struct rtw_ieee80211_hdr_3addr
);
3813 token
= frame_body
[2];
3815 if (rtw_action_public_decache(precv_frame
, token
) == _FAIL
)
3824 static unsigned int on_action_public(struct adapter
*padapter
,
3825 struct recv_frame
*precv_frame
)
3827 unsigned int ret
= _FAIL
;
3828 u8
*pframe
= precv_frame
->rx_data
;
3829 u8
*frame_body
= pframe
+ sizeof(struct rtw_ieee80211_hdr_3addr
);
3830 u8 category
, action
;
3832 /* check RA matches or not */
3833 if (memcmp(myid(&(padapter
->eeprompriv
)), GetAddr1Ptr(pframe
), ETH_ALEN
))
3836 category
= frame_body
[0];
3837 if (category
!= RTW_WLAN_CATEGORY_PUBLIC
)
3840 action
= frame_body
[1];
3842 case ACT_PUBLIC_VENDOR
:
3843 ret
= on_action_public_vendor(precv_frame
);
3846 ret
= on_action_public_default(precv_frame
, action
);
3854 static unsigned int OnAction_ht(struct adapter
*padapter
,
3855 struct recv_frame
*precv_frame
)
3860 static unsigned int OnAction_wmm(struct adapter
*padapter
,
3861 struct recv_frame
*precv_frame
)
3866 static unsigned int OnAction_p2p(struct adapter
*padapter
,
3867 struct recv_frame
*precv_frame
)
3872 static unsigned int DoReserved(struct adapter
*padapter
,
3873 struct recv_frame
*precv_frame
)
3878 static struct action_handler OnAction_tbl
[] = {
3879 {RTW_WLAN_CATEGORY_SPECTRUM_MGMT
, "ACTION_SPECTRUM_MGMT", on_action_spct
},
3880 {RTW_WLAN_CATEGORY_QOS
, "ACTION_QOS", &OnAction_qos
},
3881 {RTW_WLAN_CATEGORY_DLS
, "ACTION_DLS", &OnAction_dls
},
3882 {RTW_WLAN_CATEGORY_BACK
, "ACTION_BACK", &OnAction_back
},
3883 {RTW_WLAN_CATEGORY_PUBLIC
, "ACTION_PUBLIC", on_action_public
},
3884 {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT
, "ACTION_RADIO_MEASUREMENT", &DoReserved
},
3885 {RTW_WLAN_CATEGORY_FT
, "ACTION_FT", &DoReserved
},
3886 {RTW_WLAN_CATEGORY_HT
, "ACTION_HT", &OnAction_ht
},
3887 {RTW_WLAN_CATEGORY_SA_QUERY
, "ACTION_SA_QUERY", &DoReserved
},
3888 {RTW_WLAN_CATEGORY_WMM
, "ACTION_WMM", &OnAction_wmm
},
3889 {RTW_WLAN_CATEGORY_P2P
, "ACTION_P2P", &OnAction_p2p
},
3892 static unsigned int OnAction(struct adapter
*padapter
,
3893 struct recv_frame
*precv_frame
)
3896 unsigned char category
;
3897 struct action_handler
*ptable
;
3898 unsigned char *frame_body
;
3899 u8
*pframe
= precv_frame
->rx_data
;
3901 frame_body
= (unsigned char *)(pframe
+ sizeof(struct rtw_ieee80211_hdr_3addr
));
3903 category
= frame_body
[0];
3905 for (i
= 0; i
< sizeof(OnAction_tbl
)/sizeof(struct action_handler
); i
++) {
3906 ptable
= &OnAction_tbl
[i
];
3907 if (category
== ptable
->num
)
3908 ptable
->func(padapter
, precv_frame
);
3913 /****************************************************************************
3915 Following are the initialization functions for WiFi MLME
3917 *****************************************************************************/
3919 static struct mlme_handler mlme_sta_tbl
[] = {
3920 {WIFI_ASSOCREQ
, "OnAssocReq", &OnAssocReq
},
3921 {WIFI_ASSOCRSP
, "OnAssocRsp", &OnAssocRsp
},
3922 {WIFI_REASSOCREQ
, "OnReAssocReq", &OnAssocReq
},
3923 {WIFI_REASSOCRSP
, "OnReAssocRsp", &OnAssocRsp
},
3924 {WIFI_PROBEREQ
, "OnProbeReq", &OnProbeReq
},
3925 {WIFI_PROBERSP
, "OnProbeRsp", &OnProbeRsp
},
3927 /*----------------------------------------------------------
3928 below 2 are reserved
3929 -----------------------------------------------------------*/
3930 {0, "DoReserved", &DoReserved
},
3931 {0, "DoReserved", &DoReserved
},
3932 {WIFI_BEACON
, "OnBeacon", &OnBeacon
},
3933 {WIFI_ATIM
, "OnATIM", &OnAtim
},
3934 {WIFI_DISASSOC
, "OnDisassoc", &OnDisassoc
},
3935 {WIFI_AUTH
, "OnAuth", &OnAuthClient
},
3936 {WIFI_DEAUTH
, "OnDeAuth", &OnDeAuth
},
3937 {WIFI_ACTION
, "OnAction", &OnAction
},
3940 int init_hw_mlme_ext(struct adapter
*padapter
)
3942 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3944 set_channel_bwmode(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
3948 static void init_mlme_ext_priv_value(struct adapter
*padapter
)
3950 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3951 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
3952 unsigned char mixed_datarate
[NumRates
] = {
3953 _1M_RATE_
, _2M_RATE_
, _5M_RATE_
, _11M_RATE_
, _6M_RATE_
,
3954 _9M_RATE_
, _12M_RATE_
, _18M_RATE_
, _24M_RATE_
, _36M_RATE_
,
3955 _48M_RATE_
, _54M_RATE_
, 0xff
3957 unsigned char mixed_basicrate
[NumRates
] = {
3958 _1M_RATE_
, _2M_RATE_
, _5M_RATE_
, _11M_RATE_
, _6M_RATE_
,
3959 _12M_RATE_
, _24M_RATE_
, 0xff,
3962 atomic_set(&pmlmeext
->event_seq
, 0);
3963 pmlmeext
->mgnt_seq
= 0;/* reset to zero when disconnect at client mode */
3965 pmlmeext
->cur_channel
= padapter
->registrypriv
.channel
;
3966 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
3967 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
3968 pmlmeext
->oper_channel
= pmlmeext
->cur_channel
;
3969 pmlmeext
->oper_bwmode
= pmlmeext
->cur_bwmode
;
3970 pmlmeext
->oper_ch_offset
= pmlmeext
->cur_ch_offset
;
3971 pmlmeext
->retry
= 0;
3973 pmlmeext
->cur_wireless_mode
= padapter
->registrypriv
.wireless_mode
;
3975 memcpy(pmlmeext
->datarate
, mixed_datarate
, NumRates
);
3976 memcpy(pmlmeext
->basicrate
, mixed_basicrate
, NumRates
);
3978 pmlmeext
->tx_rate
= IEEE80211_CCK_RATE_1MB
;
3980 pmlmeext
->sitesurvey_res
.state
= SCAN_DISABLE
;
3981 pmlmeext
->sitesurvey_res
.channel_idx
= 0;
3982 pmlmeext
->sitesurvey_res
.bss_cnt
= 0;
3983 pmlmeext
->scan_abort
= false;
3985 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
3986 pmlmeinfo
->reauth_count
= 0;
3987 pmlmeinfo
->reassoc_count
= 0;
3988 pmlmeinfo
->link_count
= 0;
3989 pmlmeinfo
->auth_seq
= 0;
3990 pmlmeinfo
->auth_algo
= dot11AuthAlgrthm_Open
;
3991 pmlmeinfo
->key_index
= 0;
3994 pmlmeinfo
->enc_algo
= _NO_PRIVACY_
;
3995 pmlmeinfo
->authModeToggle
= 0;
3997 memset(pmlmeinfo
->chg_txt
, 0, 128);
3999 pmlmeinfo
->slotTime
= SHORT_SLOT_TIME
;
4000 pmlmeinfo
->preamble_mode
= PREAMBLE_AUTO
;
4002 pmlmeinfo
->dialogToken
= 0;
4004 pmlmeext
->action_public_rxseq
= 0xffff;
4005 pmlmeext
->action_public_dialog_token
= 0xff;
4008 static int has_channel(struct rt_channel_info
*channel_set
,
4013 for (i
= 0; i
< chanset_size
; i
++) {
4014 if (channel_set
[i
].ChannelNum
== chan
)
4020 static void init_channel_list(struct adapter
*padapter
, struct rt_channel_info
*channel_set
,
4022 struct p2p_channels
*channel_list
) {
4023 struct p2p_oper_class_map op_class
[] = {
4024 { IEEE80211G
, 81, 1, 13, 1, BW20
},
4025 { IEEE80211G
, 82, 14, 14, 1, BW20
},
4026 { -1, 0, 0, 0, 0, BW20
}
4033 for (op
= 0; op_class
[op
].op_class
; op
++) {
4035 struct p2p_oper_class_map
*o
= &op_class
[op
];
4036 struct p2p_reg_class
*reg
= NULL
;
4038 for (ch
= o
->min_chan
; ch
<= o
->max_chan
; ch
+= o
->inc
) {
4039 if (!has_channel(channel_set
, chanset_size
, ch
)) {
4043 if ((0 == padapter
->registrypriv
.ht_enable
) && (8 == o
->inc
))
4046 if ((0 == (padapter
->registrypriv
.cbw40_enable
& BIT(1))) &&
4047 ((BW40MINUS
== o
->bw
) || (BW40PLUS
== o
->bw
)))
4051 reg
= &channel_list
->reg_class
[cla
];
4053 reg
->reg_class
= o
->op_class
;
4056 reg
->channel
[reg
->channels
] = ch
;
4060 channel_list
->reg_classes
= cla
;
4063 static u8
init_channel_set(struct adapter
*padapter
, u8 ChannelPlan
, struct rt_channel_info
*channel_set
)
4065 u8 index
, chanset_size
= 0;
4066 u8 b2_4GBand
= false;
4069 memset(channel_set
, 0, sizeof(struct rt_channel_info
) * MAX_CHANNEL_NUM
);
4071 if (ChannelPlan
>= RT_CHANNEL_DOMAIN_MAX
&& ChannelPlan
!= RT_CHANNEL_DOMAIN_REALTEK_DEFINE
) {
4072 DBG_88E("ChannelPlan ID %x error !!!!!\n", ChannelPlan
);
4073 return chanset_size
;
4076 if (padapter
->registrypriv
.wireless_mode
& WIRELESS_11G
) {
4078 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE
== ChannelPlan
)
4079 Index2G
= RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE
.Index2G
;
4081 Index2G
= RTW_ChannelPlanMap
[ChannelPlan
].Index2G
;
4085 for (index
= 0; index
< RTW_ChannelPlan2G
[Index2G
].Len
; index
++) {
4086 channel_set
[chanset_size
].ChannelNum
= RTW_ChannelPlan2G
[Index2G
].Channel
[index
];
4088 if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN
== ChannelPlan
) ||/* Channel 1~11 is active, and 12~14 is passive */
4089 (RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G
== ChannelPlan
)) {
4090 if (channel_set
[chanset_size
].ChannelNum
>= 1 && channel_set
[chanset_size
].ChannelNum
<= 11)
4091 channel_set
[chanset_size
].ScanType
= SCAN_ACTIVE
;
4092 else if ((channel_set
[chanset_size
].ChannelNum
>= 12 && channel_set
[chanset_size
].ChannelNum
<= 14))
4093 channel_set
[chanset_size
].ScanType
= SCAN_PASSIVE
;
4094 } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13
== ChannelPlan
||
4095 RT_CHANNEL_DOMAIN_2G_WORLD
== Index2G
) {/* channel 12~13, passive scan */
4096 if (channel_set
[chanset_size
].ChannelNum
<= 11)
4097 channel_set
[chanset_size
].ScanType
= SCAN_ACTIVE
;
4099 channel_set
[chanset_size
].ScanType
= SCAN_PASSIVE
;
4101 channel_set
[chanset_size
].ScanType
= SCAN_ACTIVE
;
4107 return chanset_size
;
4110 int init_mlme_ext_priv(struct adapter
*padapter
)
4112 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
4113 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4114 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
4115 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
4117 pmlmeext
->padapter
= padapter
;
4119 init_mlme_ext_priv_value(padapter
);
4120 pmlmeinfo
->bAcceptAddbaReq
= pregistrypriv
->bAcceptAddbaReq
;
4122 init_mlme_ext_timer(padapter
);
4124 #ifdef CONFIG_88EU_AP_MODE
4125 init_mlme_ap_info(padapter
);
4128 pmlmeext
->max_chan_nums
= init_channel_set(padapter
, pmlmepriv
->ChannelPlan
, pmlmeext
->channel_set
);
4129 init_channel_list(padapter
, pmlmeext
->channel_set
, pmlmeext
->max_chan_nums
, &pmlmeext
->channel_list
);
4131 pmlmeext
->chan_scan_time
= SURVEY_TO
;
4132 pmlmeext
->mlmeext_init
= true;
4135 pmlmeext
->active_keep_alive_check
= true;
4140 void free_mlme_ext_priv(struct mlme_ext_priv
*pmlmeext
)
4142 struct adapter
*padapter
= pmlmeext
->padapter
;
4147 if (padapter
->bDriverStopped
) {
4148 del_timer_sync(&pmlmeext
->survey_timer
);
4149 del_timer_sync(&pmlmeext
->link_timer
);
4153 static void _mgt_dispatcher(struct adapter
*padapter
, struct mlme_handler
*ptable
, struct recv_frame
*precv_frame
)
4155 u8 bc_addr
[ETH_ALEN
] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4156 u8
*pframe
= precv_frame
->rx_data
;
4159 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
4160 if (memcmp(GetAddr1Ptr(pframe
), myid(&padapter
->eeprompriv
), ETH_ALEN
) &&
4161 memcmp(GetAddr1Ptr(pframe
), bc_addr
, ETH_ALEN
))
4163 ptable
->func(padapter
, precv_frame
);
4167 void mgt_dispatcher(struct adapter
*padapter
, struct recv_frame
*precv_frame
)
4170 struct mlme_handler
*ptable
;
4171 #ifdef CONFIG_88EU_AP_MODE
4172 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
4173 #endif /* CONFIG_88EU_AP_MODE */
4174 u8 bc_addr
[ETH_ALEN
] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4175 u8
*pframe
= precv_frame
->rx_data
;
4176 struct sta_info
*psta
= rtw_get_stainfo(&padapter
->stapriv
, GetAddr2Ptr(pframe
));
4178 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
4179 ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n",
4180 GetFrameType(pframe
), GetFrameSubType(pframe
)));
4182 if (GetFrameType(pframe
) != WIFI_MGT_TYPE
) {
4183 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe
)));
4187 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
4188 if (memcmp(GetAddr1Ptr(pframe
), myid(&padapter
->eeprompriv
), ETH_ALEN
) &&
4189 memcmp(GetAddr1Ptr(pframe
), bc_addr
, ETH_ALEN
))
4192 ptable
= mlme_sta_tbl
;
4194 index
= GetFrameSubType(pframe
) >> 4;
4197 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Currently we do not support reserved sub-fr-type=%d\n", index
));
4203 if (GetRetry(pframe
)) {
4204 if (precv_frame
->attrib
.seq_num
==
4205 psta
->RxMgmtFrameSeqNum
) {
4206 /* drop the duplicate management frame */
4207 DBG_88E("Drop duplicate management frame with seq_num=%d.\n",
4208 precv_frame
->attrib
.seq_num
);
4212 psta
->RxMgmtFrameSeqNum
= precv_frame
->attrib
.seq_num
;
4215 #ifdef CONFIG_88EU_AP_MODE
4216 switch (GetFrameSubType(pframe
)) {
4218 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
))
4219 ptable
->func
= &OnAuth
;
4221 ptable
->func
= &OnAuthClient
;
4224 case WIFI_REASSOCREQ
:
4228 _mgt_dispatcher(padapter
, ptable
, precv_frame
);
4231 _mgt_dispatcher(padapter
, ptable
, precv_frame
);
4235 _mgt_dispatcher(padapter
, ptable
, precv_frame
);
4239 /****************************************************************************
4241 Following are the functions to report events
4243 *****************************************************************************/
4245 void report_survey_event(struct adapter
*padapter
,
4246 struct recv_frame
*precv_frame
)
4248 struct cmd_obj
*pcmd_obj
;
4251 struct survey_event
*psurvey_evt
;
4252 struct C2HEvent_Header
*pc2h_evt_hdr
;
4253 struct mlme_ext_priv
*pmlmeext
;
4254 struct cmd_priv
*pcmdpriv
;
4259 pmlmeext
= &padapter
->mlmeextpriv
;
4260 pcmdpriv
= &padapter
->cmdpriv
;
4263 pcmd_obj
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
4264 if (pcmd_obj
== NULL
)
4267 cmdsz
= sizeof(struct survey_event
) + sizeof(struct C2HEvent_Header
);
4268 pevtcmd
= kzalloc(cmdsz
, GFP_ATOMIC
);
4269 if (pevtcmd
== NULL
) {
4274 INIT_LIST_HEAD(&pcmd_obj
->list
);
4276 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
4277 pcmd_obj
->cmdsz
= cmdsz
;
4278 pcmd_obj
->parmbuf
= pevtcmd
;
4280 pcmd_obj
->rsp
= NULL
;
4281 pcmd_obj
->rspsz
= 0;
4283 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
4284 pc2h_evt_hdr
->len
= sizeof(struct survey_event
);
4285 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_Survey
);
4286 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
4288 psurvey_evt
= (struct survey_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
4290 if (collect_bss_info(padapter
, precv_frame
, (struct wlan_bssid_ex
*)&psurvey_evt
->bss
) == _FAIL
) {
4296 process_80211d(padapter
, &psurvey_evt
->bss
);
4298 rtw_enqueue_cmd(pcmdpriv
, pcmd_obj
);
4300 pmlmeext
->sitesurvey_res
.bss_cnt
++;
4305 void report_surveydone_event(struct adapter
*padapter
)
4307 struct cmd_obj
*pcmd_obj
;
4310 struct surveydone_event
*psurveydone_evt
;
4311 struct C2HEvent_Header
*pc2h_evt_hdr
;
4312 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4313 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
4315 pcmd_obj
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
4316 if (pcmd_obj
== NULL
)
4319 cmdsz
= sizeof(struct surveydone_event
) + sizeof(struct C2HEvent_Header
);
4320 pevtcmd
= kzalloc(cmdsz
, GFP_KERNEL
);
4321 if (pevtcmd
== NULL
) {
4326 INIT_LIST_HEAD(&pcmd_obj
->list
);
4328 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
4329 pcmd_obj
->cmdsz
= cmdsz
;
4330 pcmd_obj
->parmbuf
= pevtcmd
;
4332 pcmd_obj
->rsp
= NULL
;
4333 pcmd_obj
->rspsz
= 0;
4335 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
4336 pc2h_evt_hdr
->len
= sizeof(struct surveydone_event
);
4337 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_SurveyDone
);
4338 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
4340 psurveydone_evt
= (struct surveydone_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
4341 psurveydone_evt
->bss_cnt
= pmlmeext
->sitesurvey_res
.bss_cnt
;
4343 DBG_88E("survey done event(%x)\n", psurveydone_evt
->bss_cnt
);
4345 rtw_enqueue_cmd(pcmdpriv
, pcmd_obj
);
4350 void report_join_res(struct adapter
*padapter
, int res
)
4352 struct cmd_obj
*pcmd_obj
;
4355 struct joinbss_event
*pjoinbss_evt
;
4356 struct C2HEvent_Header
*pc2h_evt_hdr
;
4357 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4358 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
4359 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
4361 pcmd_obj
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
4362 if (pcmd_obj
== NULL
)
4365 cmdsz
= sizeof(struct joinbss_event
) + sizeof(struct C2HEvent_Header
);
4366 pevtcmd
= kzalloc(cmdsz
, GFP_ATOMIC
);
4367 if (pevtcmd
== NULL
) {
4372 INIT_LIST_HEAD(&pcmd_obj
->list
);
4374 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
4375 pcmd_obj
->cmdsz
= cmdsz
;
4376 pcmd_obj
->parmbuf
= pevtcmd
;
4378 pcmd_obj
->rsp
= NULL
;
4379 pcmd_obj
->rspsz
= 0;
4381 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
4382 pc2h_evt_hdr
->len
= sizeof(struct joinbss_event
);
4383 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_JoinBss
);
4384 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
4386 pjoinbss_evt
= (struct joinbss_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
4387 memcpy((unsigned char *)(&(pjoinbss_evt
->network
.network
)), &(pmlmeinfo
->network
), sizeof(struct wlan_bssid_ex
));
4388 pjoinbss_evt
->network
.join_res
= res
;
4389 pjoinbss_evt
->network
.aid
= res
;
4391 DBG_88E("report_join_res(%d)\n", res
);
4394 rtw_joinbss_event_prehandle(padapter
, (u8
*)&pjoinbss_evt
->network
);
4397 rtw_enqueue_cmd(pcmdpriv
, pcmd_obj
);
4402 void report_del_sta_event(struct adapter
*padapter
, unsigned char *MacAddr
, unsigned short reason
)
4404 struct cmd_obj
*pcmd_obj
;
4407 struct sta_info
*psta
;
4409 struct stadel_event
*pdel_sta_evt
;
4410 struct C2HEvent_Header
*pc2h_evt_hdr
;
4411 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4412 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
4414 pcmd_obj
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
4415 if (pcmd_obj
== NULL
)
4418 cmdsz
= sizeof(struct stadel_event
) + sizeof(struct C2HEvent_Header
);
4419 pevtcmd
= kzalloc(cmdsz
, GFP_KERNEL
);
4420 if (pevtcmd
== NULL
) {
4425 INIT_LIST_HEAD(&pcmd_obj
->list
);
4427 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
4428 pcmd_obj
->cmdsz
= cmdsz
;
4429 pcmd_obj
->parmbuf
= pevtcmd
;
4431 pcmd_obj
->rsp
= NULL
;
4432 pcmd_obj
->rspsz
= 0;
4434 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
4435 pc2h_evt_hdr
->len
= sizeof(struct stadel_event
);
4436 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_DelSTA
);
4437 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
4439 pdel_sta_evt
= (struct stadel_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
4440 memcpy((unsigned char *)(&(pdel_sta_evt
->macaddr
)), MacAddr
, ETH_ALEN
);
4441 memcpy((unsigned char *)(pdel_sta_evt
->rsvd
), (unsigned char *)(&reason
), 2);
4444 psta
= rtw_get_stainfo(&padapter
->stapriv
, MacAddr
);
4446 mac_id
= (int)psta
->mac_id
;
4450 pdel_sta_evt
->mac_id
= mac_id
;
4452 DBG_88E("report_del_sta_event: delete STA, mac_id =%d\n", mac_id
);
4454 rtw_enqueue_cmd(pcmdpriv
, pcmd_obj
);
4459 void report_add_sta_event(struct adapter
*padapter
, unsigned char *MacAddr
, int cam_idx
)
4461 struct cmd_obj
*pcmd_obj
;
4464 struct stassoc_event
*padd_sta_evt
;
4465 struct C2HEvent_Header
*pc2h_evt_hdr
;
4466 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4467 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
4469 pcmd_obj
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
4470 if (pcmd_obj
== NULL
)
4473 cmdsz
= sizeof(struct stassoc_event
) + sizeof(struct C2HEvent_Header
);
4474 pevtcmd
= kzalloc(cmdsz
, GFP_KERNEL
);
4475 if (pevtcmd
== NULL
) {
4480 INIT_LIST_HEAD(&pcmd_obj
->list
);
4482 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
4483 pcmd_obj
->cmdsz
= cmdsz
;
4484 pcmd_obj
->parmbuf
= pevtcmd
;
4486 pcmd_obj
->rsp
= NULL
;
4487 pcmd_obj
->rspsz
= 0;
4489 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
4490 pc2h_evt_hdr
->len
= sizeof(struct stassoc_event
);
4491 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_AddSTA
);
4492 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
4494 padd_sta_evt
= (struct stassoc_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
4495 memcpy((unsigned char *)(&(padd_sta_evt
->macaddr
)), MacAddr
, ETH_ALEN
);
4496 padd_sta_evt
->cam_id
= cam_idx
;
4498 DBG_88E("report_add_sta_event: add STA\n");
4500 rtw_enqueue_cmd(pcmdpriv
, pcmd_obj
);
4506 /****************************************************************************
4508 Following are the event callback functions
4510 *****************************************************************************/
4512 /* for sta/adhoc mode */
4513 void update_sta_info(struct adapter
*padapter
, struct sta_info
*psta
)
4515 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
4516 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4517 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
4520 VCS_update(padapter
, psta
);
4523 if (pmlmepriv
->htpriv
.ht_option
) {
4524 psta
->htpriv
.ht_option
= true;
4526 psta
->htpriv
.ampdu_enable
= pmlmepriv
->htpriv
.ampdu_enable
;
4528 if (support_short_GI(padapter
, &(pmlmeinfo
->HT_caps
)))
4529 psta
->htpriv
.sgi
= true;
4531 psta
->qos_option
= true;
4533 psta
->htpriv
.ht_option
= false;
4535 psta
->htpriv
.ampdu_enable
= false;
4537 psta
->htpriv
.sgi
= false;
4538 psta
->qos_option
= false;
4540 psta
->htpriv
.bwmode
= pmlmeext
->cur_bwmode
;
4541 psta
->htpriv
.ch_offset
= pmlmeext
->cur_ch_offset
;
4543 psta
->htpriv
.agg_enable_bitmap
= 0x0;/* reset */
4544 psta
->htpriv
.candidate_tid_bitmap
= 0x0;/* reset */
4547 if (pmlmepriv
->qospriv
.qos_option
)
4548 psta
->qos_option
= true;
4551 psta
->state
= _FW_LINKED
;
4554 void mlmeext_joinbss_event_callback(struct adapter
*padapter
, int join_res
)
4556 struct sta_info
*psta
, *psta_bmc
;
4557 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4558 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
4559 struct wlan_bssid_ex
*cur_network
= &(pmlmeinfo
->network
);
4560 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
4566 rtw_hal_set_hwreg(padapter
, HW_VAR_MLME_JOIN
, (u8
*)(&join_type
));
4567 rtw_hal_set_hwreg(padapter
, HW_VAR_BSSID
, null_addr
);
4569 /* restore to initial setting. */
4570 update_tx_basic_rate(padapter
, padapter
->registrypriv
.wireless_mode
);
4572 goto exit_mlmeext_joinbss_event_callback
;
4575 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_ADHOC_STATE
) {
4577 psta_bmc
= rtw_get_bcmc_stainfo(padapter
);
4579 pmlmeinfo
->FW_sta_info
[psta_bmc
->mac_id
].psta
= psta_bmc
;
4580 update_bmc_sta_support_rate(padapter
, psta_bmc
->mac_id
);
4581 Update_RA_Entry(padapter
, psta_bmc
->mac_id
);
4586 /* turn on dynamic functions */
4587 Switch_DM_Func(padapter
, DYNAMIC_ALL_FUNC_ENABLE
, true);
4589 /* update IOT-related issue */
4590 update_IOT_info(padapter
);
4592 rtw_hal_set_hwreg(padapter
, HW_VAR_BASIC_RATE
, cur_network
->SupportedRates
);
4595 rtw_hal_set_hwreg(padapter
, HW_VAR_BEACON_INTERVAL
, (u8
*)(&pmlmeinfo
->bcn_interval
));
4597 /* update capability */
4598 update_capinfo(padapter
, pmlmeinfo
->capability
);
4600 /* WMM, Update EDCA param */
4601 WMMOnAssocRsp(padapter
);
4604 HTOnAssocRsp(padapter
);
4606 set_channel_bwmode(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
4608 psta
= rtw_get_stainfo(pstapriv
, cur_network
->MacAddress
);
4609 if (psta
) { /* only for infra. mode */
4610 pmlmeinfo
->FW_sta_info
[psta
->mac_id
].psta
= psta
;
4612 psta
->wireless_mode
= pmlmeext
->cur_wireless_mode
;
4614 /* set per sta rate after updating HT cap. */
4615 set_sta_rate(padapter
, psta
);
4616 rtw_hal_set_hwreg(padapter
, HW_VAR_TX_RPT_MAX_MACID
, (u8
*)&psta
->mac_id
);
4617 media_status
= (psta
->mac_id
<<8)|1; /* MACID|OPMODE: 1 means connect */
4618 rtw_hal_set_hwreg(padapter
, HW_VAR_H2C_MEDIA_STATUS_RPT
, (u8
*)&media_status
);
4622 rtw_hal_set_hwreg(padapter
, HW_VAR_MLME_JOIN
, (u8
*)(&join_type
));
4624 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_STATION_STATE
) {
4625 /* correcting TSF */
4626 correct_TSF(padapter
, pmlmeext
);
4628 rtw_lps_ctrl_wk_cmd(padapter
, LPS_CTRL_CONNECT
, 0);
4630 exit_mlmeext_joinbss_event_callback
:
4632 DBG_88E("=>%s\n", __func__
);
4635 void mlmeext_sta_add_event_callback(struct adapter
*padapter
, struct sta_info
*psta
)
4637 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
4638 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
4641 DBG_88E("%s\n", __func__
);
4643 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_ADHOC_STATE
) {
4644 if (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
) {/* adhoc master or sta_count>1 */
4646 } else { /* adhoc client */
4647 /* correcting TSF */
4648 correct_TSF(padapter
, pmlmeext
);
4651 if (send_beacon(padapter
) == _FAIL
) {
4652 pmlmeinfo
->FW_sta_info
[psta
->mac_id
].status
= 0;
4653 pmlmeinfo
->state
^= WIFI_FW_ADHOC_STATE
;
4656 pmlmeinfo
->state
|= WIFI_FW_ASSOC_SUCCESS
;
4660 rtw_hal_set_hwreg(padapter
, HW_VAR_MLME_JOIN
, (u8
*)(&join_type
));
4663 pmlmeinfo
->FW_sta_info
[psta
->mac_id
].psta
= psta
;
4665 /* rate radaptive */
4666 Update_RA_Entry(padapter
, psta
->mac_id
);
4668 /* update adhoc sta_info */
4669 update_sta_info(padapter
, psta
);
4672 void mlmeext_sta_del_event_callback(struct adapter
*padapter
)
4674 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4675 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
4677 if (is_client_associated_to_ap(padapter
) || is_IBSS_empty(padapter
)) {
4678 rtw_hal_set_hwreg(padapter
, HW_VAR_MLME_DISCONNECT
, NULL
);
4679 rtw_hal_set_hwreg(padapter
, HW_VAR_BSSID
, null_addr
);
4681 /* restore to initial setting. */
4682 update_tx_basic_rate(padapter
, padapter
->registrypriv
.wireless_mode
);
4684 /* switch to the 20M Hz mode after disconnect */
4685 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
4686 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
4688 /* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
4689 set_channel_bwmode(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
4692 flush_all_cam_entry(padapter
);
4694 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
4696 /* set MSR to no link state -> infra. mode */
4697 Set_MSR(padapter
, _HW_STATE_STATION_
);
4699 del_timer_sync(&pmlmeext
->link_timer
);
4703 /****************************************************************************
4705 Following are the functions for the timer handlers
4707 *****************************************************************************/
4708 void _linked_rx_signal_strehgth_display(struct adapter
*padapter
);
4709 void _linked_rx_signal_strehgth_display(struct adapter
*padapter
)
4711 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4712 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
4714 int UndecoratedSmoothedPWDB
;
4715 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_STATION_STATE
)
4717 else if ((pmlmeinfo
->state
&0x03) == _HW_STATE_AP_
)
4720 rtw_hal_get_def_var(padapter
, HW_DEF_RA_INFO_DUMP
, &mac_id
);
4722 rtw_hal_get_def_var(padapter
, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB
, &UndecoratedSmoothedPWDB
);
4723 DBG_88E("UndecoratedSmoothedPWDB:%d\n", UndecoratedSmoothedPWDB
);
4726 static u8
chk_ap_is_alive(struct adapter
*padapter
, struct sta_info
*psta
)
4730 if ((sta_rx_data_pkts(psta
) == sta_last_rx_data_pkts(psta
)) &&
4731 sta_rx_beacon_pkts(psta
) == sta_last_rx_beacon_pkts(psta
) &&
4732 sta_rx_probersp_pkts(psta
) == sta_last_rx_probersp_pkts(psta
))
4737 sta_update_last_rx_pkts(psta
);
4742 void linked_status_chk(struct adapter
*padapter
)
4745 struct sta_info
*psta
;
4746 struct xmit_priv
*pxmitpriv
= &(padapter
->xmitpriv
);
4747 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4748 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
4749 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
4751 if (padapter
->bRxRSSIDisplay
)
4752 _linked_rx_signal_strehgth_display(padapter
);
4754 if (is_client_associated_to_ap(padapter
)) {
4755 /* linked infrastructure client mode */
4757 int tx_chk
= _SUCCESS
, rx_chk
= _SUCCESS
;
4761 psta
= rtw_get_stainfo(pstapriv
, pmlmeinfo
->network
.MacAddress
);
4763 bool is_p2p_enable
= false;
4765 if (!chk_ap_is_alive(padapter
, psta
))
4768 if (pxmitpriv
->last_tx_pkts
== pxmitpriv
->tx_pkts
)
4771 if (pmlmeext
->active_keep_alive_check
&& (rx_chk
== _FAIL
|| tx_chk
== _FAIL
)) {
4772 u8 backup_oper_channel
= 0;
4774 /* switch to correct channel of current network before issue keep-alive frames */
4775 if (rtw_get_oper_ch(padapter
) != pmlmeext
->cur_channel
) {
4776 backup_oper_channel
= rtw_get_oper_ch(padapter
);
4777 SelectChannel(padapter
, pmlmeext
->cur_channel
);
4780 if (rx_chk
!= _SUCCESS
)
4781 issue_probereq_ex(padapter
, &pmlmeinfo
->network
.Ssid
, psta
->hwaddr
, 3, 1);
4783 if ((tx_chk
!= _SUCCESS
&& pmlmeinfo
->link_count
++ == 0xf) || rx_chk
!= _SUCCESS
) {
4784 tx_chk
= issue_nulldata(padapter
, psta
->hwaddr
, 0, 3, 1);
4785 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
4786 if (tx_chk
== _SUCCESS
&& !is_p2p_enable
)
4790 /* back to the original operation channel */
4791 if (backup_oper_channel
> 0)
4792 SelectChannel(padapter
, backup_oper_channel
);
4794 if (rx_chk
!= _SUCCESS
) {
4795 if (pmlmeext
->retry
== 0) {
4796 issue_probereq(padapter
, &pmlmeinfo
->network
.Ssid
, pmlmeinfo
->network
.MacAddress
);
4797 issue_probereq(padapter
, &pmlmeinfo
->network
.Ssid
, pmlmeinfo
->network
.MacAddress
);
4798 issue_probereq(padapter
, &pmlmeinfo
->network
.Ssid
, pmlmeinfo
->network
.MacAddress
);
4802 if (tx_chk
!= _SUCCESS
&& pmlmeinfo
->link_count
++ == 0xf) {
4803 tx_chk
= issue_nulldata(padapter
, NULL
, 0, 1, 0);
4807 if (rx_chk
== _FAIL
) {
4809 if (pmlmeext
->retry
> rx_chk_limit
) {
4810 DBG_88E_LEVEL(_drv_always_
, FUNC_ADPT_FMT
" disconnect or roaming\n",
4811 FUNC_ADPT_ARG(padapter
));
4812 receive_disconnect(padapter
, pmlmeinfo
->network
.MacAddress
,
4813 WLAN_REASON_EXPIRATION_CHK
);
4817 pmlmeext
->retry
= 0;
4820 if (tx_chk
== _FAIL
) {
4821 pmlmeinfo
->link_count
&= 0xf;
4823 pxmitpriv
->last_tx_pkts
= pxmitpriv
->tx_pkts
;
4824 pmlmeinfo
->link_count
= 0;
4826 } /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */
4827 } else if (is_client_associated_to_ibss(padapter
)) {
4828 /* linked IBSS mode */
4829 /* for each assoc list entry to check the rx pkt counter */
4830 for (i
= IBSS_START_MAC_ID
; i
< NUM_STA
; i
++) {
4831 if (pmlmeinfo
->FW_sta_info
[i
].status
== 1) {
4832 psta
= pmlmeinfo
->FW_sta_info
[i
].psta
;
4836 if (pmlmeinfo
->FW_sta_info
[i
].rx_pkt
== sta_rx_pkts(psta
)) {
4837 if (pmlmeinfo
->FW_sta_info
[i
].retry
< 3) {
4838 pmlmeinfo
->FW_sta_info
[i
].retry
++;
4840 pmlmeinfo
->FW_sta_info
[i
].retry
= 0;
4841 pmlmeinfo
->FW_sta_info
[i
].status
= 0;
4842 report_del_sta_event(padapter
, psta
->hwaddr
4843 , 65535/* indicate disconnect caused by no rx */
4847 pmlmeinfo
->FW_sta_info
[i
].retry
= 0;
4848 pmlmeinfo
->FW_sta_info
[i
].rx_pkt
= (u32
)sta_rx_pkts(psta
);
4855 void survey_timer_hdl(unsigned long data
)
4857 struct adapter
*padapter
= (struct adapter
*)data
;
4858 struct cmd_obj
*ph2c
;
4859 struct sitesurvey_parm
*psurveyPara
;
4860 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
4861 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4863 /* issue rtw_sitesurvey_cmd */
4864 if (pmlmeext
->sitesurvey_res
.state
> SCAN_START
) {
4865 if (pmlmeext
->sitesurvey_res
.state
== SCAN_PROCESS
)
4866 pmlmeext
->sitesurvey_res
.channel_idx
++;
4868 if (pmlmeext
->scan_abort
) {
4869 pmlmeext
->sitesurvey_res
.channel_idx
= pmlmeext
->sitesurvey_res
.ch_num
;
4870 DBG_88E("%s idx:%d\n", __func__
4871 , pmlmeext
->sitesurvey_res
.channel_idx
);
4873 pmlmeext
->scan_abort
= false;/* reset */
4876 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
4878 goto exit_survey_timer_hdl
;
4880 psurveyPara
= kzalloc(sizeof(struct sitesurvey_parm
), GFP_ATOMIC
);
4881 if (psurveyPara
== NULL
) {
4883 goto exit_survey_timer_hdl
;
4886 init_h2fwcmd_w_parm_no_rsp(ph2c
, psurveyPara
, GEN_CMD_CODE(_SiteSurvey
));
4887 rtw_enqueue_cmd(pcmdpriv
, ph2c
);
4891 exit_survey_timer_hdl
:
4895 void link_timer_hdl(unsigned long data
)
4897 struct adapter
*padapter
= (struct adapter
*)data
;
4898 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4899 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
4901 if (pmlmeinfo
->state
& WIFI_FW_AUTH_NULL
) {
4902 DBG_88E("link_timer_hdl:no beacon while connecting\n");
4903 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
4904 report_join_res(padapter
, -3);
4905 } else if (pmlmeinfo
->state
& WIFI_FW_AUTH_STATE
) {
4907 if (++pmlmeinfo
->reauth_count
> REAUTH_LIMIT
) {
4908 pmlmeinfo
->state
= 0;
4909 report_join_res(padapter
, -1);
4913 DBG_88E("link_timer_hdl: auth timeout and try again\n");
4914 pmlmeinfo
->auth_seq
= 1;
4915 issue_auth(padapter
, NULL
, 0);
4916 set_link_timer(pmlmeext
, REAUTH_TO
);
4917 } else if (pmlmeinfo
->state
& WIFI_FW_ASSOC_STATE
) {
4918 /* re-assoc timer */
4919 if (++pmlmeinfo
->reassoc_count
> REASSOC_LIMIT
) {
4920 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
4921 report_join_res(padapter
, -2);
4925 DBG_88E("link_timer_hdl: assoc timeout and try again\n");
4926 issue_assocreq(padapter
);
4927 set_link_timer(pmlmeext
, REASSOC_TO
);
4932 void addba_timer_hdl(unsigned long data
)
4934 struct sta_info
*psta
= (struct sta_info
*)data
;
4935 struct ht_priv
*phtpriv
;
4940 phtpriv
= &psta
->htpriv
;
4942 if ((phtpriv
->ht_option
) && (phtpriv
->ampdu_enable
)) {
4943 if (phtpriv
->candidate_tid_bitmap
)
4944 phtpriv
->candidate_tid_bitmap
= 0x0;
4948 u8
setopmode_hdl(struct adapter
*padapter
, u8
*pbuf
)
4951 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4952 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
4953 struct setopmode_parm
*psetop
= (struct setopmode_parm
*)pbuf
;
4955 if (psetop
->mode
== Ndis802_11APMode
) {
4956 pmlmeinfo
->state
= WIFI_FW_AP_STATE
;
4957 type
= _HW_STATE_AP_
;
4958 } else if (psetop
->mode
== Ndis802_11Infrastructure
) {
4959 pmlmeinfo
->state
&= ~(BIT(0)|BIT(1));/* clear state */
4960 pmlmeinfo
->state
|= WIFI_FW_STATION_STATE
;/* set to STATION_STATE */
4961 type
= _HW_STATE_STATION_
;
4962 } else if (psetop
->mode
== Ndis802_11IBSS
) {
4963 type
= _HW_STATE_ADHOC_
;
4965 type
= _HW_STATE_NOLINK_
;
4968 rtw_hal_set_hwreg(padapter
, HW_VAR_SET_OPMODE
, (u8
*)(&type
));
4969 /* Set_NETYPE0_MSR(padapter, type); */
4974 u8
createbss_hdl(struct adapter
*padapter
, u8
*pbuf
)
4976 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4977 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
4978 struct wlan_bssid_ex
*pnetwork
= (struct wlan_bssid_ex
*)(&(pmlmeinfo
->network
));
4979 struct wlan_bssid_ex
*pparm
= (struct wlan_bssid_ex
*)pbuf
;
4980 /* u32 initialgain; */
4983 if (pparm
->InfrastructureMode
== Ndis802_11APMode
) {
4984 #ifdef CONFIG_88EU_AP_MODE
4986 if (pmlmeinfo
->state
== WIFI_FW_AP_STATE
) {
4993 /* below is for ad-hoc master */
4994 if (pparm
->InfrastructureMode
== Ndis802_11IBSS
) {
4995 rtw_joinbss_reset(padapter
);
4997 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
4998 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
4999 pmlmeinfo
->ERP_enable
= 0;
5000 pmlmeinfo
->WMM_enable
= 0;
5001 pmlmeinfo
->HT_enable
= 0;
5002 pmlmeinfo
->HT_caps_enable
= 0;
5003 pmlmeinfo
->HT_info_enable
= 0;
5004 pmlmeinfo
->agg_enable_bitmap
= 0;
5005 pmlmeinfo
->candidate_tid_bitmap
= 0;
5007 /* disable dynamic functions, such as high power, DIG */
5008 Save_DM_Func_Flag(padapter
);
5009 Switch_DM_Func(padapter
, DYNAMIC_FUNC_DISABLE
, false);
5011 /* config the initial gain under linking, need to write the BB registers */
5012 /* initialgain = 0x1E; */
5013 /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
5015 /* cancel link timer */
5016 del_timer_sync(&pmlmeext
->link_timer
);
5019 flush_all_cam_entry(padapter
);
5021 memcpy(pnetwork
, pbuf
, FIELD_OFFSET(struct wlan_bssid_ex
, IELength
));
5022 pnetwork
->IELength
= ((struct wlan_bssid_ex
*)pbuf
)->IELength
;
5024 if (pnetwork
->IELength
> MAX_IE_SZ
)/* Check pbuf->IELength */
5025 return H2C_PARAMETERS_ERROR
;
5027 memcpy(pnetwork
->IEs
, ((struct wlan_bssid_ex
*)pbuf
)->IEs
, pnetwork
->IELength
);
5029 start_create_ibss(padapter
);
5035 u8
join_cmd_hdl(struct adapter
*padapter
, u8
*pbuf
)
5038 struct ndis_802_11_var_ie
*pIE
;
5039 struct registry_priv
*pregpriv
= &padapter
->registrypriv
;
5040 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5041 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
5042 struct wlan_bssid_ex
*pnetwork
= (struct wlan_bssid_ex
*)(&(pmlmeinfo
->network
));
5043 struct wlan_bssid_ex
*pparm
= (struct wlan_bssid_ex
*)pbuf
;
5046 /* check already connecting to AP or not */
5047 if (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
) {
5048 if (pmlmeinfo
->state
& WIFI_FW_STATION_STATE
)
5049 issue_deauth_ex(padapter
, pnetwork
->MacAddress
, WLAN_REASON_DEAUTH_LEAVING
, 5, 100);
5051 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
5054 flush_all_cam_entry(padapter
);
5056 del_timer_sync(&pmlmeext
->link_timer
);
5058 /* set MSR to nolink -> infra. mode */
5059 Set_MSR(padapter
, _HW_STATE_STATION_
);
5062 rtw_hal_set_hwreg(padapter
, HW_VAR_MLME_DISCONNECT
, NULL
);
5065 rtw_antenna_select_cmd(padapter
, pparm
->PhyInfo
.Optimum_antenna
, false);
5067 rtw_joinbss_reset(padapter
);
5069 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
5070 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
5071 pmlmeinfo
->ERP_enable
= 0;
5072 pmlmeinfo
->WMM_enable
= 0;
5073 pmlmeinfo
->HT_enable
= 0;
5074 pmlmeinfo
->HT_caps_enable
= 0;
5075 pmlmeinfo
->HT_info_enable
= 0;
5076 pmlmeinfo
->agg_enable_bitmap
= 0;
5077 pmlmeinfo
->candidate_tid_bitmap
= 0;
5078 pmlmeinfo
->bwmode_updated
= false;
5080 memcpy(pnetwork
, pbuf
, FIELD_OFFSET(struct wlan_bssid_ex
, IELength
));
5081 pnetwork
->IELength
= ((struct wlan_bssid_ex
*)pbuf
)->IELength
;
5083 if (pnetwork
->IELength
> MAX_IE_SZ
)/* Check pbuf->IELength */
5084 return H2C_PARAMETERS_ERROR
;
5086 memcpy(pnetwork
->IEs
, ((struct wlan_bssid_ex
*)pbuf
)->IEs
, pnetwork
->IELength
);
5088 /* Check AP vendor to move rtw_joinbss_cmd() */
5090 for (i
= sizeof(struct ndis_802_11_fixed_ie
); i
< pnetwork
->IELength
;) {
5091 pIE
= (struct ndis_802_11_var_ie
*)(pnetwork
->IEs
+ i
);
5093 switch (pIE
->ElementID
) {
5094 case _VENDOR_SPECIFIC_IE_
:/* Get WMM IE. */
5095 if (!memcmp(pIE
->data
, WMM_OUI
, 4))
5096 pmlmeinfo
->WMM_enable
= 1;
5098 case _HT_CAPABILITY_IE_
: /* Get HT Cap IE. */
5099 pmlmeinfo
->HT_caps_enable
= 1;
5101 case _HT_EXTRA_INFO_IE_
: /* Get HT Info IE. */
5102 pmlmeinfo
->HT_info_enable
= 1;
5104 /* spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz */
5106 struct HT_info_element
*pht_info
= (struct HT_info_element
*)(pIE
->data
);
5108 if ((pregpriv
->cbw40_enable
) && (pht_info
->infos
[0] & BIT(2))) {
5109 /* switch to the 40M Hz mode according to the AP */
5110 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_40
;
5111 switch (pht_info
->infos
[0] & 0x3) {
5113 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_LOWER
;
5116 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_UPPER
;
5119 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
5123 DBG_88E("set ch/bw before connected\n");
5131 i
+= (pIE
->Length
+ 2);
5133 /* disable dynamic functions, such as high power, DIG */
5135 /* config the initial gain under linking, need to write the BB registers */
5137 rtw_hal_set_hwreg(padapter
, HW_VAR_BSSID
, pmlmeinfo
->network
.MacAddress
);
5139 rtw_hal_set_hwreg(padapter
, HW_VAR_MLME_JOIN
, (u8
*)(&join_type
));
5141 /* cancel link timer */
5142 del_timer_sync(&pmlmeext
->link_timer
);
5144 start_clnt_join(padapter
);
5149 u8
disconnect_hdl(struct adapter
*padapter
, unsigned char *pbuf
)
5151 struct disconnect_parm
*param
= (struct disconnect_parm
*)pbuf
;
5152 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5153 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
5154 struct wlan_bssid_ex
*pnetwork
= (struct wlan_bssid_ex
*)(&(pmlmeinfo
->network
));
5157 if (is_client_associated_to_ap(padapter
))
5158 issue_deauth_ex(padapter
, pnetwork
->MacAddress
, WLAN_REASON_DEAUTH_LEAVING
, param
->deauth_timeout_ms
/100, 100);
5160 rtw_hal_set_hwreg(padapter
, HW_VAR_MLME_DISCONNECT
, NULL
);
5161 rtw_hal_set_hwreg(padapter
, HW_VAR_BSSID
, null_addr
);
5163 /* restore to initial setting. */
5164 update_tx_basic_rate(padapter
, padapter
->registrypriv
.wireless_mode
);
5166 if (((pmlmeinfo
->state
&0x03) == WIFI_FW_ADHOC_STATE
) || ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
)) {
5169 rtw_hal_set_hwreg(padapter
, HW_VAR_BCN_FUNC
, (u8
*)(&val8
));
5173 /* set MSR to no link state -> infra. mode */
5174 Set_MSR(padapter
, _HW_STATE_STATION_
);
5176 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
5178 /* switch to the 20M Hz mode after disconnect */
5179 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
5180 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
5182 set_channel_bwmode(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
5184 flush_all_cam_entry(padapter
);
5186 del_timer_sync(&pmlmeext
->link_timer
);
5188 rtw_free_uc_swdec_pending_queue(padapter
);
5193 static int rtw_scan_ch_decision(struct adapter
*padapter
, struct rtw_ieee80211_channel
*out
,
5194 u32 out_num
, struct rtw_ieee80211_channel
*in
, u32 in_num
)
5198 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5200 /* clear out first */
5201 memset(out
, 0, sizeof(struct rtw_ieee80211_channel
)*out_num
);
5203 /* acquire channels from in */
5205 for (i
= 0; i
< in_num
; i
++) {
5206 set_idx
= rtw_ch_set_search_ch(pmlmeext
->channel_set
, in
[i
].hw_value
);
5207 if (in
[i
].hw_value
&& !(in
[i
].flags
& RTW_IEEE80211_CHAN_DISABLED
) &&
5211 if (pmlmeext
->channel_set
[set_idx
].ScanType
== SCAN_PASSIVE
)
5212 out
[j
].flags
&= RTW_IEEE80211_CHAN_PASSIVE_SCAN
;
5220 /* if out is empty, use channel_set as default */
5222 for (i
= 0; i
< pmlmeext
->max_chan_nums
; i
++) {
5223 out
[i
].hw_value
= pmlmeext
->channel_set
[i
].ChannelNum
;
5225 if (pmlmeext
->channel_set
[i
].ScanType
== SCAN_PASSIVE
)
5226 out
[i
].flags
&= RTW_IEEE80211_CHAN_PASSIVE_SCAN
;
5235 u8
sitesurvey_cmd_hdl(struct adapter
*padapter
, u8
*pbuf
)
5237 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5238 struct sitesurvey_parm
*pparm
= (struct sitesurvey_parm
*)pbuf
;
5239 u8 bdelayscan
= false;
5244 if (pmlmeext
->sitesurvey_res
.state
== SCAN_DISABLE
) {
5245 /* for first time sitesurvey_cmd */
5246 rtw_hal_set_hwreg(padapter
, HW_VAR_CHECK_TXBUF
, NULL
);
5248 pmlmeext
->sitesurvey_res
.state
= SCAN_START
;
5249 pmlmeext
->sitesurvey_res
.bss_cnt
= 0;
5250 pmlmeext
->sitesurvey_res
.channel_idx
= 0;
5252 for (i
= 0; i
< RTW_SSID_SCAN_AMOUNT
; i
++) {
5253 if (pparm
->ssid
[i
].SsidLength
) {
5254 memcpy(pmlmeext
->sitesurvey_res
.ssid
[i
].Ssid
, pparm
->ssid
[i
].Ssid
, IW_ESSID_MAX_SIZE
);
5255 pmlmeext
->sitesurvey_res
.ssid
[i
].SsidLength
= pparm
->ssid
[i
].SsidLength
;
5257 pmlmeext
->sitesurvey_res
.ssid
[i
].SsidLength
= 0;
5261 pmlmeext
->sitesurvey_res
.ch_num
= rtw_scan_ch_decision(padapter
5262 , pmlmeext
->sitesurvey_res
.ch
, RTW_CHANNEL_SCAN_AMOUNT
5263 , pparm
->ch
, pparm
->ch_num
5266 pmlmeext
->sitesurvey_res
.scan_mode
= pparm
->scan_mode
;
5268 /* issue null data if associating to the AP */
5269 if (is_client_associated_to_ap(padapter
)) {
5270 pmlmeext
->sitesurvey_res
.state
= SCAN_TXNULL
;
5272 issue_nulldata(padapter
, NULL
, 1, 3, 500);
5277 /* delay 50ms to protect nulldata(1). */
5278 set_survey_timer(pmlmeext
, 50);
5283 if ((pmlmeext
->sitesurvey_res
.state
== SCAN_START
) || (pmlmeext
->sitesurvey_res
.state
== SCAN_TXNULL
)) {
5284 /* disable dynamic functions, such as high power, DIG */
5285 Save_DM_Func_Flag(padapter
);
5286 Switch_DM_Func(padapter
, DYNAMIC_FUNC_DISABLE
, false);
5288 /* config the initial gain under scanning, need to write the BB registers */
5291 rtw_hal_set_hwreg(padapter
, HW_VAR_INITIAL_GAIN
, (u8
*)(&initialgain
));
5293 /* set MSR to no link state */
5294 Set_MSR(padapter
, _HW_STATE_NOLINK_
);
5296 val8
= 1; /* under site survey */
5297 rtw_hal_set_hwreg(padapter
, HW_VAR_MLME_SITESURVEY
, (u8
*)(&val8
));
5299 pmlmeext
->sitesurvey_res
.state
= SCAN_PROCESS
;
5302 site_survey(padapter
);
5307 u8
setauth_hdl(struct adapter
*padapter
, unsigned char *pbuf
)
5309 struct setauth_parm
*pparm
= (struct setauth_parm
*)pbuf
;
5310 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5311 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
5313 if (pparm
->mode
< 4)
5314 pmlmeinfo
->auth_algo
= pparm
->mode
;
5318 u8
setkey_hdl(struct adapter
*padapter
, u8
*pbuf
)
5320 unsigned short ctrl
;
5321 struct setkey_parm
*pparm
= (struct setkey_parm
*)pbuf
;
5322 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5323 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
5324 unsigned char null_sta
[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
5326 /* main tx key for wep. */
5328 pmlmeinfo
->key_index
= pparm
->keyid
;
5331 ctrl
= BIT(15) | ((pparm
->algorithm
) << 2) | pparm
->keyid
;
5333 DBG_88E_LEVEL(_drv_info_
, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
5334 "keyid:%d\n", pparm
->algorithm
, pparm
->keyid
);
5335 write_cam(padapter
, pparm
->keyid
, ctrl
, null_sta
, pparm
->key
);
5340 u8
set_stakey_hdl(struct adapter
*padapter
, u8
*pbuf
)
5343 u8 cam_id
;/* cam_entry */
5344 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5345 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
5346 struct set_stakey_parm
*pparm
= (struct set_stakey_parm
*)pbuf
;
5349 /* 0~3 for default key */
5351 /* for concurrent mode (ap+sta): */
5352 /* default key is disable, using sw encrypt/decrypt */
5353 /* cam_entry = 4 for sta mode (macid = 0) */
5354 /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
5356 /* for concurrent mode (sta+sta): */
5357 /* default key is disable, using sw encrypt/decrypt */
5358 /* cam_entry = 4 mapping to macid = 0 */
5359 /* cam_entry = 5 mapping to macid = 2 */
5363 DBG_88E_LEVEL(_drv_info_
, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n",
5364 pparm
->algorithm
, cam_id
);
5365 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
) {
5366 struct sta_info
*psta
;
5367 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
5369 if (pparm
->algorithm
== _NO_PRIVACY_
) /* clear cam entry */ {
5370 clear_cam_entry(padapter
, pparm
->id
);
5371 return H2C_SUCCESS_RSP
;
5374 psta
= rtw_get_stainfo(pstapriv
, pparm
->addr
);
5376 ctrl
= BIT(15) | ((pparm
->algorithm
) << 2);
5378 DBG_88E("r871x_set_stakey_hdl(): enc_algorithm=%d\n", pparm
->algorithm
);
5380 if ((psta
->mac_id
< 1) || (psta
->mac_id
> (NUM_STA
-4))) {
5381 DBG_88E("r871x_set_stakey_hdl():set_stakey failed, mac_id(aid)=%d\n", psta
->mac_id
);
5382 return H2C_REJECTED
;
5385 cam_id
= psta
->mac_id
+ 3;/* 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
5387 DBG_88E("Write CAM, mac_addr =%pM, cam_entry=%d\n",
5388 pparm
->addr
, cam_id
);
5390 write_cam(padapter
, cam_id
, ctrl
, pparm
->addr
, pparm
->key
);
5392 return H2C_SUCCESS_RSP
;
5394 DBG_88E("r871x_set_stakey_hdl(): sta has been free\n");
5395 return H2C_REJECTED
;
5399 /* below for sta mode */
5401 if (pparm
->algorithm
== _NO_PRIVACY_
) { /* clear cam entry */
5402 clear_cam_entry(padapter
, pparm
->id
);
5405 ctrl
= BIT(15) | ((pparm
->algorithm
) << 2);
5406 write_cam(padapter
, cam_id
, ctrl
, pparm
->addr
, pparm
->key
);
5407 pmlmeinfo
->enc_algo
= pparm
->algorithm
;
5411 u8
add_ba_hdl(struct adapter
*padapter
, unsigned char *pbuf
)
5413 struct addBaReq_parm
*pparm
= (struct addBaReq_parm
*)pbuf
;
5414 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5415 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
5417 struct sta_info
*psta
= rtw_get_stainfo(&padapter
->stapriv
, pparm
->addr
);
5422 if (((pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
) && (pmlmeinfo
->HT_enable
)) ||
5423 ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
)) {
5424 issue_action_BA(padapter
, pparm
->addr
, RTW_WLAN_ACTION_ADDBA_REQ
, (u16
)pparm
->tid
);
5425 mod_timer(&psta
->addba_retry_timer
,
5426 jiffies
+ msecs_to_jiffies(ADDBA_TO
));
5428 psta
->htpriv
.candidate_tid_bitmap
&= ~BIT(pparm
->tid
);
5433 u8
set_tx_beacon_cmd(struct adapter
*padapter
)
5435 struct cmd_obj
*ph2c
;
5436 struct wlan_bssid_ex
*ptxBeacon_parm
;
5437 struct cmd_priv
*pcmdpriv
= &(padapter
->cmdpriv
);
5438 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5439 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
5444 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
5450 ptxBeacon_parm
= kmemdup(&(pmlmeinfo
->network
),
5451 sizeof(struct wlan_bssid_ex
), GFP_KERNEL
);
5452 if (ptxBeacon_parm
== NULL
) {
5458 len_diff
= update_hidden_ssid(ptxBeacon_parm
->IEs
+_BEACON_IE_OFFSET_
,
5459 ptxBeacon_parm
->IELength
-_BEACON_IE_OFFSET_
,
5460 pmlmeinfo
->hidden_ssid_mode
);
5461 ptxBeacon_parm
->IELength
+= len_diff
;
5463 init_h2fwcmd_w_parm_no_rsp(ph2c
, ptxBeacon_parm
, GEN_CMD_CODE(_TX_Beacon
));
5465 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
5474 u8
mlme_evt_hdl(struct adapter
*padapter
, unsigned char *pbuf
)
5479 void (*event_callback
)(struct adapter
*dev
, u8
*pbuf
);
5481 peventbuf
= (uint
*)pbuf
;
5482 evt_sz
= (u16
)(*peventbuf
&0xffff);
5483 evt_code
= (u8
)((*peventbuf
>>16)&0xff);
5485 /* checking if event code is valid */
5486 if (evt_code
>= MAX_C2HEVT
) {
5487 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\nEvent Code(%d) mismatch!\n", evt_code
));
5491 /* checking if event size match the event parm size */
5492 if ((wlanevents
[evt_code
].parmsize
!= 0) &&
5493 (wlanevents
[evt_code
].parmsize
!= evt_sz
)) {
5494 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
,
5495 ("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
5496 evt_code
, wlanevents
[evt_code
].parmsize
, evt_sz
));
5503 event_callback
= wlanevents
[evt_code
].event_callback
;
5504 event_callback(padapter
, (u8
*)peventbuf
);
5512 u8
tx_beacon_hdl(struct adapter
*padapter
, unsigned char *pbuf
)
5514 if (send_beacon(padapter
) == _FAIL
) {
5515 DBG_88E("issue_beacon, fail!\n");
5516 return H2C_PARAMETERS_ERROR
;
5518 #ifdef CONFIG_88EU_AP_MODE
5519 else { /* tx bc/mc frames after update TIM */
5520 struct sta_info
*psta_bmc
;
5521 struct list_head
*xmitframe_plist
, *xmitframe_phead
;
5522 struct xmit_frame
*pxmitframe
= NULL
;
5523 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
5525 /* for BC/MC Frames */
5526 psta_bmc
= rtw_get_bcmc_stainfo(padapter
);
5530 if ((pstapriv
->tim_bitmap
&BIT(0)) && (psta_bmc
->sleepq_len
> 0)) {
5531 msleep(10);/* 10ms, ATIM(HIQ) Windows */
5532 spin_lock_bh(&psta_bmc
->sleep_q
.lock
);
5534 xmitframe_phead
= get_list_head(&psta_bmc
->sleep_q
);
5535 xmitframe_plist
= xmitframe_phead
->next
;
5537 while (xmitframe_phead
!= xmitframe_plist
) {
5538 pxmitframe
= container_of(xmitframe_plist
, struct xmit_frame
, list
);
5540 xmitframe_plist
= xmitframe_plist
->next
;
5542 list_del_init(&pxmitframe
->list
);
5544 psta_bmc
->sleepq_len
--;
5545 if (psta_bmc
->sleepq_len
> 0)
5546 pxmitframe
->attrib
.mdata
= 1;
5548 pxmitframe
->attrib
.mdata
= 0;
5550 pxmitframe
->attrib
.triggered
= 1;
5552 pxmitframe
->attrib
.qsel
= 0x11;/* HIQ */
5554 spin_unlock_bh(&psta_bmc
->sleep_q
.lock
);
5555 if (rtw_hal_xmit(padapter
, pxmitframe
))
5556 rtw_os_xmit_complete(padapter
, pxmitframe
);
5557 spin_lock_bh(&psta_bmc
->sleep_q
.lock
);
5559 spin_unlock_bh(&psta_bmc
->sleep_q
.lock
);
5566 u8
set_ch_hdl(struct adapter
*padapter
, u8
*pbuf
)
5568 struct set_ch_parm
*set_ch_parm
;
5569 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5572 return H2C_PARAMETERS_ERROR
;
5574 set_ch_parm
= (struct set_ch_parm
*)pbuf
;
5576 DBG_88E(FUNC_NDEV_FMT
" ch:%u, bw:%u, ch_offset:%u\n",
5577 FUNC_NDEV_ARG(padapter
->pnetdev
),
5578 set_ch_parm
->ch
, set_ch_parm
->bw
, set_ch_parm
->ch_offset
);
5580 pmlmeext
->cur_channel
= set_ch_parm
->ch
;
5581 pmlmeext
->cur_ch_offset
= set_ch_parm
->ch_offset
;
5582 pmlmeext
->cur_bwmode
= set_ch_parm
->bw
;
5584 set_channel_bwmode(padapter
, set_ch_parm
->ch
, set_ch_parm
->ch_offset
, set_ch_parm
->bw
);
5589 u8
set_chplan_hdl(struct adapter
*padapter
, unsigned char *pbuf
)
5591 struct SetChannelPlan_param
*setChannelPlan_param
;
5592 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5595 return H2C_PARAMETERS_ERROR
;
5597 setChannelPlan_param
= (struct SetChannelPlan_param
*)pbuf
;
5599 pmlmeext
->max_chan_nums
= init_channel_set(padapter
, setChannelPlan_param
->channel_plan
, pmlmeext
->channel_set
);
5600 init_channel_list(padapter
, pmlmeext
->channel_set
, pmlmeext
->max_chan_nums
, &pmlmeext
->channel_list
);