1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 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 ******************************************************************************/
22 #include <linux/ieee80211.h>
24 #include <osdep_service.h>
25 #include <drv_types.h>
26 #include <recv_osdep.h>
27 #include <xmit_osdep.h>
29 #include <mlme_osdep.h>
32 #include <wlan_bssdef.h>
33 #include <rtw_ioctl_set.h>
34 #include <linux/vmalloc.h>
36 extern unsigned char MCS_rate_2R
[16];
37 extern unsigned char MCS_rate_1R
[16];
39 int rtw_init_mlme_priv(struct adapter
*padapter
)
43 struct wlan_network
*pnetwork
;
44 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
47 /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */
49 pmlmepriv
->nic_hdl
= (u8
*)padapter
;
51 pmlmepriv
->pscanned
= NULL
;
52 pmlmepriv
->fw_state
= 0;
53 pmlmepriv
->cur_network
.network
.InfrastructureMode
= Ndis802_11AutoUnknown
;
54 pmlmepriv
->scan_mode
= SCAN_ACTIVE
;/* 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) */
56 spin_lock_init(&(pmlmepriv
->lock
));
57 _rtw_init_queue(&(pmlmepriv
->free_bss_pool
));
58 _rtw_init_queue(&(pmlmepriv
->scanned_queue
));
60 set_scanned_network_val(pmlmepriv
, 0);
62 memset(&pmlmepriv
->assoc_ssid
, 0, sizeof(struct ndis_802_11_ssid
));
64 pbuf
= vzalloc(MAX_BSS_CNT
* (sizeof(struct wlan_network
)));
70 pmlmepriv
->free_bss_buf
= pbuf
;
72 pnetwork
= (struct wlan_network
*)pbuf
;
74 for (i
= 0; i
< MAX_BSS_CNT
; i
++) {
75 INIT_LIST_HEAD(&(pnetwork
->list
));
77 list_add_tail(&(pnetwork
->list
), &(pmlmepriv
->free_bss_pool
.queue
));
82 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
84 rtw_clear_scan_deny(padapter
);
86 rtw_init_mlme_timer(padapter
);
92 #if defined(CONFIG_88EU_AP_MODE)
93 static void rtw_free_mlme_ie_data(u8
**ppie
, u32
*plen
)
100 void rtw_free_mlme_priv_ie_data(struct mlme_priv
*pmlmepriv
)
102 rtw_buf_free(&pmlmepriv
->assoc_req
, &pmlmepriv
->assoc_req_len
);
103 rtw_buf_free(&pmlmepriv
->assoc_rsp
, &pmlmepriv
->assoc_rsp_len
);
104 rtw_free_mlme_ie_data(&pmlmepriv
->wps_beacon_ie
, &pmlmepriv
->wps_beacon_ie_len
);
105 rtw_free_mlme_ie_data(&pmlmepriv
->wps_probe_req_ie
, &pmlmepriv
->wps_probe_req_ie_len
);
106 rtw_free_mlme_ie_data(&pmlmepriv
->wps_probe_resp_ie
, &pmlmepriv
->wps_probe_resp_ie_len
);
107 rtw_free_mlme_ie_data(&pmlmepriv
->wps_assoc_resp_ie
, &pmlmepriv
->wps_assoc_resp_ie_len
);
109 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_beacon_ie
, &pmlmepriv
->p2p_beacon_ie_len
);
110 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_probe_req_ie
, &pmlmepriv
->p2p_probe_req_ie_len
);
111 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_probe_resp_ie
, &pmlmepriv
->p2p_probe_resp_ie_len
);
112 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_go_probe_resp_ie
, &pmlmepriv
->p2p_go_probe_resp_ie_len
);
113 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_assoc_req_ie
, &pmlmepriv
->p2p_assoc_req_ie_len
);
116 void rtw_free_mlme_priv_ie_data(struct mlme_priv
*pmlmepriv
)
121 void rtw_free_mlme_priv(struct mlme_priv
*pmlmepriv
)
123 rtw_free_mlme_priv_ie_data(pmlmepriv
);
126 if (pmlmepriv
->free_bss_buf
)
127 vfree(pmlmepriv
->free_bss_buf
);
131 struct wlan_network
*_rtw_alloc_network(struct mlme_priv
*pmlmepriv
)/* _queue *free_queue) */
133 struct wlan_network
*pnetwork
;
134 struct __queue
*free_queue
= &pmlmepriv
->free_bss_pool
;
135 struct list_head
*plist
= NULL
;
137 spin_lock_bh(&free_queue
->lock
);
139 if (list_empty(&free_queue
->queue
)) {
143 plist
= free_queue
->queue
.next
;
145 pnetwork
= container_of(plist
, struct wlan_network
, list
);
147 list_del_init(&pnetwork
->list
);
149 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("_rtw_alloc_network: ptr=%p\n", plist
));
150 pnetwork
->network_type
= 0;
151 pnetwork
->fixed
= false;
152 pnetwork
->last_scanned
= jiffies
;
154 pnetwork
->join_res
= 0;
156 pmlmepriv
->num_of_scanned
++;
159 spin_unlock_bh(&free_queue
->lock
);
164 static void _rtw_free_network(struct mlme_priv
*pmlmepriv
, struct wlan_network
*pnetwork
, u8 isfreeall
)
166 unsigned long curr_time
;
168 u32 lifetime
= SCANQUEUE_LIFETIME
;
169 struct __queue
*free_queue
= &(pmlmepriv
->free_bss_pool
);
171 if (pnetwork
== NULL
)
177 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) ||
178 (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)))
181 delta_time
= (curr_time
- pnetwork
->last_scanned
)/HZ
;
182 if (delta_time
< lifetime
)/* unit:sec */
185 spin_lock_bh(&free_queue
->lock
);
186 list_del_init(&(pnetwork
->list
));
187 list_add_tail(&(pnetwork
->list
), &(free_queue
->queue
));
188 pmlmepriv
->num_of_scanned
--;
189 spin_unlock_bh(&free_queue
->lock
);
192 void _rtw_free_network_nolock(struct mlme_priv
*pmlmepriv
, struct wlan_network
*pnetwork
)
194 struct __queue
*free_queue
= &(pmlmepriv
->free_bss_pool
);
196 if (pnetwork
== NULL
)
200 list_del_init(&(pnetwork
->list
));
201 list_add_tail(&(pnetwork
->list
), get_list_head(free_queue
));
202 pmlmepriv
->num_of_scanned
--;
206 return the wlan_network with the matching addr
208 Shall be calle under atomic context... to avoid possible racing condition...
210 struct wlan_network
*rtw_find_network(struct __queue
*scanned_queue
, u8
*addr
)
212 struct list_head
*phead
, *plist
;
213 struct wlan_network
*pnetwork
= NULL
;
214 u8 zero_addr
[ETH_ALEN
] = {0, 0, 0, 0, 0, 0};
216 if (!memcmp(zero_addr
, addr
, ETH_ALEN
)) {
220 phead
= get_list_head(scanned_queue
);
223 while (plist
!= phead
) {
224 pnetwork
= container_of(plist
, struct wlan_network
, list
);
225 if (!memcmp(addr
, pnetwork
->network
.MacAddress
, ETH_ALEN
))
236 void rtw_free_network_queue(struct adapter
*padapter
, u8 isfreeall
)
238 struct list_head
*phead
, *plist
;
239 struct wlan_network
*pnetwork
;
240 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
241 struct __queue
*scanned_queue
= &pmlmepriv
->scanned_queue
;
243 spin_lock_bh(&scanned_queue
->lock
);
245 phead
= get_list_head(scanned_queue
);
248 while (phead
!= plist
) {
249 pnetwork
= container_of(plist
, struct wlan_network
, list
);
253 _rtw_free_network(pmlmepriv
, pnetwork
, isfreeall
);
255 spin_unlock_bh(&scanned_queue
->lock
);
258 int rtw_if_up(struct adapter
*padapter
)
262 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
||
263 (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) == false)) {
264 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
265 ("rtw_if_up:bDriverStopped(%d) OR bSurpriseRemoved(%d)",
266 padapter
->bDriverStopped
, padapter
->bSurpriseRemoved
));
274 void rtw_generate_random_ibss(u8
*pibss
)
276 unsigned long curtime
= jiffies
;
278 pibss
[0] = 0x02; /* in ad-hoc mode bit1 must set to 1 */
281 pibss
[3] = (u8
)(curtime
& 0xff);/* p[0]; */
282 pibss
[4] = (u8
)((curtime
>>8) & 0xff);/* p[1]; */
283 pibss
[5] = (u8
)((curtime
>>16) & 0xff);/* p[2]; */
287 u8
*rtw_get_capability_from_ie(u8
*ie
)
293 u16
rtw_get_capability(struct wlan_bssid_ex
*bss
)
297 memcpy((u8
*)&val
, rtw_get_capability_from_ie(bss
->IEs
), 2);
299 return le16_to_cpu(val
);
302 u8
*rtw_get_beacon_interval_from_ie(u8
*ie
)
307 static struct wlan_network
*rtw_alloc_network(struct mlme_priv
*pmlmepriv
)
309 return _rtw_alloc_network(pmlmepriv
);
312 static void rtw_free_network_nolock(struct mlme_priv
*pmlmepriv
,
313 struct wlan_network
*pnetwork
)
315 _rtw_free_network_nolock(pmlmepriv
, pnetwork
);
318 int rtw_is_same_ibss(struct adapter
*adapter
, struct wlan_network
*pnetwork
)
321 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
323 if ((psecuritypriv
->dot11PrivacyAlgrthm
!= _NO_PRIVACY_
) &&
324 (pnetwork
->network
.Privacy
== 0))
326 else if ((psecuritypriv
->dot11PrivacyAlgrthm
== _NO_PRIVACY_
) &&
327 (pnetwork
->network
.Privacy
== 1))
334 static int is_same_ess(struct wlan_bssid_ex
*a
, struct wlan_bssid_ex
*b
)
336 return (a
->Ssid
.SsidLength
== b
->Ssid
.SsidLength
) &&
337 !memcmp(a
->Ssid
.Ssid
, b
->Ssid
.Ssid
, a
->Ssid
.SsidLength
);
340 int is_same_network(struct wlan_bssid_ex
*src
, struct wlan_bssid_ex
*dst
)
343 __le16 le_scap
, le_dcap
;
345 memcpy((u8
*)&le_scap
, rtw_get_capability_from_ie(src
->IEs
), 2);
346 memcpy((u8
*)&le_dcap
, rtw_get_capability_from_ie(dst
->IEs
), 2);
349 s_cap
= le16_to_cpu(le_scap
);
350 d_cap
= le16_to_cpu(le_dcap
);
352 return ((src
->Ssid
.SsidLength
== dst
->Ssid
.SsidLength
) &&
353 ((!memcmp(src
->MacAddress
, dst
->MacAddress
, ETH_ALEN
)) == true) &&
354 ((!memcmp(src
->Ssid
.Ssid
, dst
->Ssid
.Ssid
, src
->Ssid
.SsidLength
)) == true) &&
355 ((s_cap
& WLAN_CAPABILITY_IBSS
) ==
356 (d_cap
& WLAN_CAPABILITY_IBSS
)) &&
357 ((s_cap
& WLAN_CAPABILITY_ESS
) ==
358 (d_cap
& WLAN_CAPABILITY_ESS
)));
361 struct wlan_network
*rtw_get_oldest_wlan_network(struct __queue
*scanned_queue
)
363 struct list_head
*plist
, *phead
;
364 struct wlan_network
*pwlan
= NULL
;
365 struct wlan_network
*oldest
= NULL
;
367 phead
= get_list_head(scanned_queue
);
369 for (plist
= phead
->next
; plist
!= phead
; plist
= plist
->next
) {
370 pwlan
= container_of(plist
, struct wlan_network
, list
);
373 if (oldest
== NULL
|| time_after(oldest
->last_scanned
, pwlan
->last_scanned
))
380 void update_network(struct wlan_bssid_ex
*dst
, struct wlan_bssid_ex
*src
,
381 struct adapter
*padapter
, bool update_ie
)
383 long rssi_ori
= dst
->Rssi
;
384 u8 sq_smp
= src
->PhyInfo
.SignalQuality
;
389 rtw_hal_antdiv_rssi_compared(padapter
, dst
, src
); /* this will update src.Rssi, need consider again */
391 /* The rule below is 1/5 for sample value, 4/5 for history value */
392 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) && is_same_network(&(padapter
->mlmepriv
.cur_network
.network
), src
)) {
393 /* Take the recvpriv's value for the connected AP*/
394 ss_final
= padapter
->recvpriv
.signal_strength
;
395 sq_final
= padapter
->recvpriv
.signal_qual
;
396 /* the rssi value here is undecorated, and will be used for antenna diversity */
397 if (sq_smp
!= 101) /* from the right channel */
398 rssi_final
= (src
->Rssi
+dst
->Rssi
*4)/5;
400 rssi_final
= rssi_ori
;
402 if (sq_smp
!= 101) { /* from the right channel */
403 ss_final
= ((u32
)(src
->PhyInfo
.SignalStrength
)+(u32
)(dst
->PhyInfo
.SignalStrength
)*4)/5;
404 sq_final
= ((u32
)(src
->PhyInfo
.SignalQuality
)+(u32
)(dst
->PhyInfo
.SignalQuality
)*4)/5;
405 rssi_final
= (src
->Rssi
+dst
->Rssi
*4)/5;
407 /* bss info not receiving from the right channel, use the original RX signal infos */
408 ss_final
= dst
->PhyInfo
.SignalStrength
;
409 sq_final
= dst
->PhyInfo
.SignalQuality
;
410 rssi_final
= dst
->Rssi
;
414 memcpy((u8
*)dst
, (u8
*)src
, get_wlan_bssid_ex_sz(src
));
415 dst
->PhyInfo
.SignalStrength
= ss_final
;
416 dst
->PhyInfo
.SignalQuality
= sq_final
;
417 dst
->Rssi
= rssi_final
;
421 static void update_current_network(struct adapter
*adapter
, struct wlan_bssid_ex
*pnetwork
)
423 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
425 if ((check_fwstate(pmlmepriv
, _FW_LINKED
) == true) &&
426 (is_same_network(&(pmlmepriv
->cur_network
.network
), pnetwork
))) {
427 update_network(&(pmlmepriv
->cur_network
.network
), pnetwork
, adapter
, true);
428 rtw_update_protection(adapter
, (pmlmepriv
->cur_network
.network
.IEs
) + sizeof(struct ndis_802_11_fixed_ie
),
429 pmlmepriv
->cur_network
.network
.IELength
);
434 Caller must hold pmlmepriv->lock first.
436 void rtw_update_scanned_network(struct adapter
*adapter
, struct wlan_bssid_ex
*target
)
438 struct list_head
*plist
, *phead
;
440 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
441 struct __queue
*queue
= &(pmlmepriv
->scanned_queue
);
442 struct wlan_network
*pnetwork
= NULL
;
443 struct wlan_network
*oldest
= NULL
;
445 spin_lock_bh(&queue
->lock
);
446 phead
= get_list_head(queue
);
449 while (phead
!= plist
) {
450 pnetwork
= container_of(plist
, struct wlan_network
, list
);
452 if (is_same_network(&(pnetwork
->network
), target
))
454 if ((oldest
== ((struct wlan_network
*)0)) ||
455 time_after(oldest
->last_scanned
, pnetwork
->last_scanned
))
459 /* If we didn't find a match, then get a new network slot to initialize
460 * with this beacon's information */
461 if (phead
== plist
) {
462 if (list_empty(&(pmlmepriv
->free_bss_pool
.queue
))) {
463 /* If there are no more slots, expire the oldest */
466 rtw_hal_get_def_var(adapter
, HAL_DEF_CURRENT_ANTENNA
, &(target
->PhyInfo
.Optimum_antenna
));
467 memcpy(&(pnetwork
->network
), target
, get_wlan_bssid_ex_sz(target
));
468 /* variable initialize */
469 pnetwork
->fixed
= false;
470 pnetwork
->last_scanned
= jiffies
;
472 pnetwork
->network_type
= 0;
474 pnetwork
->join_res
= 0;
476 /* bss info not receiving from the right channel */
477 if (pnetwork
->network
.PhyInfo
.SignalQuality
== 101)
478 pnetwork
->network
.PhyInfo
.SignalQuality
= 0;
480 /* Otherwise just pull from the free list */
482 pnetwork
= rtw_alloc_network(pmlmepriv
); /* will update scan_time */
484 if (pnetwork
== NULL
) {
485 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("\n\n\nsomething wrong here\n\n\n"));
489 bssid_ex_sz
= get_wlan_bssid_ex_sz(target
);
490 target
->Length
= bssid_ex_sz
;
491 rtw_hal_get_def_var(adapter
, HAL_DEF_CURRENT_ANTENNA
, &(target
->PhyInfo
.Optimum_antenna
));
492 memcpy(&(pnetwork
->network
), target
, bssid_ex_sz
);
494 pnetwork
->last_scanned
= jiffies
;
496 /* bss info not receiving from the right channel */
497 if (pnetwork
->network
.PhyInfo
.SignalQuality
== 101)
498 pnetwork
->network
.PhyInfo
.SignalQuality
= 0;
499 list_add_tail(&(pnetwork
->list
), &(queue
->queue
));
502 /* we have an entry and we are going to update it. But this entry may
503 * be already expired. In this case we do the same as we found a new
504 * net and call the new_net handler
506 bool update_ie
= true;
508 pnetwork
->last_scanned
= jiffies
;
510 /* target.Reserved[0]== 1, means that scanned network is a bcn frame. */
511 if ((pnetwork
->network
.IELength
> target
->IELength
) && (target
->Reserved
[0] == 1))
514 update_network(&(pnetwork
->network
), target
, adapter
, update_ie
);
518 spin_unlock_bh(&queue
->lock
);
522 static void rtw_add_network(struct adapter
*adapter
,
523 struct wlan_bssid_ex
*pnetwork
)
525 update_current_network(adapter
, pnetwork
);
526 rtw_update_scanned_network(adapter
, pnetwork
);
530 * select the desired network based on the capability of the (i)bss.
531 * check items: (1) security
537 static int rtw_is_desired_network(struct adapter
*adapter
, struct wlan_network
*pnetwork
)
539 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
540 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
544 /* u8 wps_ie[512]; */
547 int bselected
= true;
549 desired_encmode
= psecuritypriv
->ndisencryptstatus
;
550 privacy
= pnetwork
->network
.Privacy
;
552 if (check_fwstate(pmlmepriv
, WIFI_UNDER_WPS
)) {
553 if (rtw_get_wps_ie(pnetwork
->network
.IEs
+_FIXED_IE_LENGTH_
, pnetwork
->network
.IELength
-_FIXED_IE_LENGTH_
, NULL
, &wps_ielen
) != NULL
)
558 if (adapter
->registrypriv
.wifi_spec
== 1) { /* for correct flow of 8021X to do.... */
559 if ((desired_encmode
== Ndis802_11EncryptionDisabled
) && (privacy
!= 0))
564 if ((desired_encmode
!= Ndis802_11EncryptionDisabled
) && (privacy
== 0)) {
565 DBG_88E("desired_encmode: %d, privacy: %d\n", desired_encmode
, privacy
);
569 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) == true) {
570 if (pnetwork
->network
.InfrastructureMode
!= pmlmepriv
->cur_network
.network
.InfrastructureMode
)
578 /* TODO: Perry: For Power Management */
579 void rtw_atimdone_event_callback(struct adapter
*adapter
, u8
*pbuf
)
581 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("receive atimdone_evet\n"));
586 void rtw_survey_event_callback(struct adapter
*adapter
, u8
*pbuf
)
589 struct wlan_bssid_ex
*pnetwork
;
590 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
592 pnetwork
= (struct wlan_bssid_ex
*)pbuf
;
594 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_survey_event_callback, ssid=%s\n", pnetwork
->Ssid
.Ssid
));
596 len
= get_wlan_bssid_ex_sz(pnetwork
);
597 if (len
> (sizeof(struct wlan_bssid_ex
))) {
598 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("\n****rtw_survey_event_callback: return a wrong bss ***\n"));
601 spin_lock_bh(&pmlmepriv
->lock
);
603 /* update IBSS_network 's timestamp */
604 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) == true) {
605 if (!memcmp(&(pmlmepriv
->cur_network
.network
.MacAddress
), pnetwork
->MacAddress
, ETH_ALEN
)) {
606 struct wlan_network
*ibss_wlan
= NULL
;
608 memcpy(pmlmepriv
->cur_network
.network
.IEs
, pnetwork
->IEs
, 8);
609 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
610 ibss_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, pnetwork
->MacAddress
);
612 memcpy(ibss_wlan
->network
.IEs
, pnetwork
->IEs
, 8);
613 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
616 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
620 /* lock pmlmepriv->lock when you accessing network_q */
621 if ((check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
)) == false) {
622 if (pnetwork
->Ssid
.Ssid
[0] == 0)
623 pnetwork
->Ssid
.SsidLength
= 0;
624 rtw_add_network(adapter
, pnetwork
);
629 spin_unlock_bh(&pmlmepriv
->lock
);
633 void rtw_surveydone_event_callback(struct adapter
*adapter
, u8
*pbuf
)
635 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
637 spin_lock_bh(&pmlmepriv
->lock
);
639 if (pmlmepriv
->wps_probe_req_ie
) {
640 pmlmepriv
->wps_probe_req_ie_len
= 0;
641 kfree(pmlmepriv
->wps_probe_req_ie
);
642 pmlmepriv
->wps_probe_req_ie
= NULL
;
645 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_surveydone_event_callback: fw_state:%x\n\n", get_fwstate(pmlmepriv
)));
647 if (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
)) {
648 del_timer_sync(&pmlmepriv
->scan_to_timer
);
649 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
651 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("nic status=%x, survey done event comes too late!\n", get_fwstate(pmlmepriv
)));
654 rtw_set_signal_stat_timer(&adapter
->recvpriv
);
656 if (pmlmepriv
->to_join
) {
657 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) == true)) {
658 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == false) {
659 set_fwstate(pmlmepriv
, _FW_UNDER_LINKING
);
661 if (rtw_select_and_join_from_scanned_queue(pmlmepriv
) == _SUCCESS
) {
662 mod_timer(&pmlmepriv
->assoc_timer
,
663 jiffies
+ msecs_to_jiffies(MAX_JOIN_TIMEOUT
));
665 struct wlan_bssid_ex
*pdev_network
= &(adapter
->registrypriv
.dev_network
);
666 u8
*pibss
= adapter
->registrypriv
.dev_network
.MacAddress
;
668 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
670 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("switching to adhoc master\n"));
672 memcpy(&pdev_network
->Ssid
, &pmlmepriv
->assoc_ssid
, sizeof(struct ndis_802_11_ssid
));
674 rtw_update_registrypriv_dev_network(adapter
);
675 rtw_generate_random_ibss(pibss
);
677 pmlmepriv
->fw_state
= WIFI_ADHOC_MASTER_STATE
;
679 if (rtw_createbss_cmd(adapter
) != _SUCCESS
)
680 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Error=>rtw_createbss_cmd status FAIL\n"));
681 pmlmepriv
->to_join
= false;
686 set_fwstate(pmlmepriv
, _FW_UNDER_LINKING
);
687 pmlmepriv
->to_join
= false;
688 s_ret
= rtw_select_and_join_from_scanned_queue(pmlmepriv
);
689 if (_SUCCESS
== s_ret
) {
690 mod_timer(&pmlmepriv
->assoc_timer
,
691 jiffies
+ msecs_to_jiffies(MAX_JOIN_TIMEOUT
));
692 } else if (s_ret
== 2) { /* there is no need to wait for join */
693 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
694 rtw_indicate_connect(adapter
);
696 DBG_88E("try_to_join, but select scanning queue fail, to_roaming:%d\n", pmlmepriv
->to_roaming
);
697 if (pmlmepriv
->to_roaming
!= 0) {
698 if (--pmlmepriv
->to_roaming
== 0 ||
699 _SUCCESS
!= rtw_sitesurvey_cmd(adapter
, &pmlmepriv
->assoc_ssid
, 1, NULL
, 0)) {
700 pmlmepriv
->to_roaming
= 0;
701 rtw_free_assoc_resources(adapter
);
702 rtw_indicate_disconnect(adapter
);
704 pmlmepriv
->to_join
= true;
707 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
712 indicate_wx_scan_complete_event(adapter
);
714 spin_unlock_bh(&pmlmepriv
->lock
);
716 rtw_os_xmit_schedule(adapter
);
719 void rtw_dummy_event_callback(struct adapter
*adapter
, u8
*pbuf
)
723 void rtw_fwdbg_event_callback(struct adapter
*adapter
, u8
*pbuf
)
727 static void free_scanqueue(struct mlme_priv
*pmlmepriv
)
729 struct __queue
*free_queue
= &pmlmepriv
->free_bss_pool
;
730 struct __queue
*scan_queue
= &pmlmepriv
->scanned_queue
;
731 struct list_head
*plist
, *phead
, *ptemp
;
733 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
, ("+free_scanqueue\n"));
734 spin_lock_bh(&scan_queue
->lock
);
735 spin_lock_bh(&free_queue
->lock
);
737 phead
= get_list_head(scan_queue
);
740 while (plist
!= phead
) {
742 list_del_init(plist
);
743 list_add_tail(plist
, &free_queue
->queue
);
745 pmlmepriv
->num_of_scanned
--;
748 spin_unlock_bh(&free_queue
->lock
);
749 spin_unlock_bh(&scan_queue
->lock
);
753 *rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock
755 void rtw_free_assoc_resources(struct adapter
*adapter
)
757 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
759 spin_lock_bh(&pmlmepriv
->scanned_queue
.lock
);
760 rtw_free_assoc_resources_locked(adapter
);
761 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
765 *rtw_free_assoc_resources_locked: the caller has to lock pmlmepriv->lock
767 void rtw_free_assoc_resources_locked(struct adapter
*adapter
)
769 struct wlan_network
*pwlan
= NULL
;
770 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
771 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
772 struct wlan_network
*tgt_network
= &pmlmepriv
->cur_network
;
774 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
, ("+rtw_free_assoc_resources\n"));
775 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
776 ("tgt_network->network.MacAddress=%pM ssid=%s\n",
777 tgt_network
->network
.MacAddress
, tgt_network
->network
.Ssid
.Ssid
));
779 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
| WIFI_AP_STATE
)) {
780 struct sta_info
*psta
;
782 psta
= rtw_get_stainfo(&adapter
->stapriv
, tgt_network
->network
.MacAddress
);
784 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
785 rtw_free_stainfo(adapter
, psta
);
786 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
789 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
| WIFI_ADHOC_MASTER_STATE
| WIFI_AP_STATE
)) {
790 struct sta_info
*psta
;
792 rtw_free_all_stainfo(adapter
);
794 psta
= rtw_get_bcmc_stainfo(adapter
);
795 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
796 rtw_free_stainfo(adapter
, psta
);
797 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
799 rtw_init_bcmc_stainfo(adapter
);
803 pwlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, tgt_network
->network
.MacAddress
);
805 pwlan
->fixed
= false;
807 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("rtw_free_assoc_resources:pwlan==NULL\n\n"));
809 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) && (adapter
->stapriv
.asoc_sta_count
== 1)))
810 rtw_free_network_nolock(pmlmepriv
, pwlan
);
812 pmlmepriv
->key_mask
= 0;
816 *rtw_indicate_connect: the caller has to lock pmlmepriv->lock
818 void rtw_indicate_connect(struct adapter
*padapter
)
820 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
822 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("+rtw_indicate_connect\n"));
824 pmlmepriv
->to_join
= false;
826 if (!check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
)) {
827 set_fwstate(pmlmepriv
, _FW_LINKED
);
829 rtw_led_control(padapter
, LED_CTL_LINK
);
831 rtw_os_indicate_connect(padapter
);
834 pmlmepriv
->to_roaming
= 0;
836 rtw_set_scan_deny(padapter
, 3000);
838 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("-rtw_indicate_connect: fw_state=0x%08x\n", get_fwstate(pmlmepriv
)));
842 *rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock
844 void rtw_indicate_disconnect(struct adapter
*padapter
)
846 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
848 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("+rtw_indicate_disconnect\n"));
850 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
| WIFI_UNDER_WPS
);
853 if (pmlmepriv
->to_roaming
> 0)
854 _clr_fwstate_(pmlmepriv
, _FW_LINKED
);
856 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) ||
857 (pmlmepriv
->to_roaming
<= 0)) {
858 rtw_os_indicate_disconnect(padapter
);
860 _clr_fwstate_(pmlmepriv
, _FW_LINKED
);
861 rtw_led_control(padapter
, LED_CTL_NO_LINK
);
862 rtw_clear_scan_deny(padapter
);
865 rtw_lps_ctrl_wk_cmd(padapter
, LPS_CTRL_DISCONNECT
, 1);
868 inline void rtw_indicate_scan_done(struct adapter
*padapter
, bool aborted
)
870 rtw_os_indicate_scan_done(padapter
, aborted
);
873 void rtw_scan_abort(struct adapter
*adapter
)
876 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
877 struct mlme_ext_priv
*pmlmeext
= &(adapter
->mlmeextpriv
);
880 pmlmeext
->scan_abort
= true;
881 while (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
) &&
882 jiffies_to_msecs(jiffies
- start
) <= 200) {
883 if (adapter
->bDriverStopped
|| adapter
->bSurpriseRemoved
)
885 DBG_88E(FUNC_NDEV_FMT
"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter
->pnetdev
));
888 if (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
)) {
889 if (!adapter
->bDriverStopped
&& !adapter
->bSurpriseRemoved
)
890 DBG_88E(FUNC_NDEV_FMT
"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter
->pnetdev
));
891 rtw_indicate_scan_done(adapter
, true);
893 pmlmeext
->scan_abort
= false;
896 static struct sta_info
*rtw_joinbss_update_stainfo(struct adapter
*padapter
, struct wlan_network
*pnetwork
)
899 struct sta_info
*bmc_sta
, *psta
= NULL
;
900 struct recv_reorder_ctrl
*preorder_ctrl
;
901 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
903 psta
= rtw_get_stainfo(pstapriv
, pnetwork
->network
.MacAddress
);
905 psta
= rtw_alloc_stainfo(pstapriv
, pnetwork
->network
.MacAddress
);
907 if (psta
) { /* update ptarget_sta */
908 DBG_88E("%s\n", __func__
);
909 psta
->aid
= pnetwork
->join_res
;
912 rtw_hal_set_odm_var(padapter
, HAL_ODM_STA_INFO
, psta
, true);
913 /* security related */
914 if (padapter
->securitypriv
.dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
) {
915 padapter
->securitypriv
.binstallGrpkey
= false;
916 padapter
->securitypriv
.busetkipkey
= false;
917 padapter
->securitypriv
.bgrpkey_handshake
= false;
918 psta
->ieee8021x_blocked
= true;
919 psta
->dot118021XPrivacy
= padapter
->securitypriv
.dot11PrivacyAlgrthm
;
920 memset((u8
*)&psta
->dot118021x_UncstKey
, 0, sizeof(union Keytype
));
921 memset((u8
*)&psta
->dot11tkiprxmickey
, 0, sizeof(union Keytype
));
922 memset((u8
*)&psta
->dot11tkiptxmickey
, 0, sizeof(union Keytype
));
923 memset((u8
*)&psta
->dot11txpn
, 0, sizeof(union pn48
));
924 memset((u8
*)&psta
->dot11rxpn
, 0, sizeof(union pn48
));
927 * Commented by Albert 2012/07/21
928 * When doing the WPS, the wps_ie_len won't equal to 0
929 * And the Wi-Fi driver shouldn't allow the data
930 * packet to be tramsmitted.
932 if (padapter
->securitypriv
.wps_ie_len
!= 0) {
933 psta
->ieee8021x_blocked
= true;
934 padapter
->securitypriv
.wps_ie_len
= 0;
936 /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */
937 /* if A-MPDU Rx is enabled, resetting rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */
938 /* todo: check if AP can send A-MPDU packets */
939 for (i
= 0; i
< 16; i
++) {
940 /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
941 preorder_ctrl
= &psta
->recvreorder_ctrl
[i
];
942 preorder_ctrl
->enable
= false;
943 preorder_ctrl
->indicate_seq
= 0xffff;
944 preorder_ctrl
->wend_b
= 0xffff;
945 preorder_ctrl
->wsize_b
= 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
947 bmc_sta
= rtw_get_bcmc_stainfo(padapter
);
949 for (i
= 0; i
< 16; i
++) {
950 /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
951 preorder_ctrl
= &bmc_sta
->recvreorder_ctrl
[i
];
952 preorder_ctrl
->enable
= false;
953 preorder_ctrl
->indicate_seq
= 0xffff;
954 preorder_ctrl
->wend_b
= 0xffff;
955 preorder_ctrl
->wsize_b
= 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
959 update_sta_info(padapter
, psta
);
964 /* pnetwork: returns from rtw_joinbss_event_callback */
965 /* ptarget_wlan: found from scanned_queue */
966 static void rtw_joinbss_update_network(struct adapter
*padapter
, struct wlan_network
*ptarget_wlan
, struct wlan_network
*pnetwork
)
968 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
969 struct wlan_network
*cur_network
= &(pmlmepriv
->cur_network
);
971 DBG_88E("%s\n", __func__
);
973 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
974 ("\nfw_state:%x, BSSID:%pM\n",
975 get_fwstate(pmlmepriv
), pnetwork
->network
.MacAddress
));
978 /* why not use ptarget_wlan?? */
979 memcpy(&cur_network
->network
, &pnetwork
->network
, pnetwork
->network
.Length
);
980 /* some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
981 cur_network
->network
.IELength
= ptarget_wlan
->network
.IELength
;
982 memcpy(&cur_network
->network
.IEs
[0], &ptarget_wlan
->network
.IEs
[0], MAX_IE_SZ
);
984 cur_network
->aid
= pnetwork
->join_res
;
987 rtw_set_signal_stat_timer(&padapter
->recvpriv
);
988 padapter
->recvpriv
.signal_strength
= ptarget_wlan
->network
.PhyInfo
.SignalStrength
;
989 padapter
->recvpriv
.signal_qual
= ptarget_wlan
->network
.PhyInfo
.SignalQuality
;
990 /* the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) */
991 padapter
->recvpriv
.rssi
= translate_percentage_to_dbm(ptarget_wlan
->network
.PhyInfo
.SignalStrength
);
992 rtw_set_signal_stat_timer(&padapter
->recvpriv
);
994 /* update fw_state will clr _FW_UNDER_LINKING here indirectly */
995 switch (pnetwork
->network
.InfrastructureMode
) {
996 case Ndis802_11Infrastructure
:
997 if (pmlmepriv
->fw_state
&WIFI_UNDER_WPS
)
998 pmlmepriv
->fw_state
= WIFI_STATION_STATE
|WIFI_UNDER_WPS
;
1000 pmlmepriv
->fw_state
= WIFI_STATION_STATE
;
1002 case Ndis802_11IBSS
:
1003 pmlmepriv
->fw_state
= WIFI_ADHOC_STATE
;
1006 pmlmepriv
->fw_state
= WIFI_NULL_STATE
;
1007 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Invalid network_mode\n"));
1011 rtw_update_protection(padapter
, (cur_network
->network
.IEs
) +
1012 sizeof(struct ndis_802_11_fixed_ie
),
1013 (cur_network
->network
.IELength
));
1014 rtw_update_ht_cap(padapter
, cur_network
->network
.IEs
, cur_network
->network
.IELength
);
1017 /* Notes: the function could be > passive_level (the same context as Rx tasklet) */
1018 /* pnetwork: returns from rtw_joinbss_event_callback */
1019 /* ptarget_wlan: found from scanned_queue */
1020 /* if join_res > 0, for (fw_state == WIFI_STATION_STATE), we check if "ptarget_sta" & "ptarget_wlan" exist. */
1021 /* if join_res > 0, for (fw_state == WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. */
1022 /* if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan != NULL). */
1024 void rtw_joinbss_event_prehandle(struct adapter
*adapter
, u8
*pbuf
)
1026 struct sta_info
*ptarget_sta
= NULL
, *pcur_sta
= NULL
;
1027 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
1028 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1029 struct wlan_network
*pnetwork
= (struct wlan_network
*)pbuf
;
1030 struct wlan_network
*cur_network
= &(pmlmepriv
->cur_network
);
1031 struct wlan_network
*pcur_wlan
= NULL
, *ptarget_wlan
= NULL
;
1032 unsigned int the_same_macaddr
= false;
1034 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("joinbss event call back received with res=%d\n", pnetwork
->join_res
));
1036 rtw_get_encrypt_decrypt_from_registrypriv(adapter
);
1039 if (pmlmepriv
->assoc_ssid
.SsidLength
== 0)
1040 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("@@@@@ joinbss event call back for Any SSid\n"));
1042 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("@@@@@ rtw_joinbss_event_callback for SSid:%s\n", pmlmepriv
->assoc_ssid
.Ssid
));
1044 the_same_macaddr
= !memcmp(pnetwork
->network
.MacAddress
, cur_network
->network
.MacAddress
, ETH_ALEN
);
1046 pnetwork
->network
.Length
= get_wlan_bssid_ex_sz(&pnetwork
->network
);
1047 if (pnetwork
->network
.Length
> sizeof(struct wlan_bssid_ex
)) {
1048 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("\n\n ***joinbss_evt_callback return a wrong bss ***\n\n"));
1052 spin_lock_bh(&pmlmepriv
->lock
);
1054 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("\nrtw_joinbss_event_callback!! _enter_critical\n"));
1056 if (pnetwork
->join_res
> 0) {
1057 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1058 if (check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
)) {
1059 /* s1. find ptarget_wlan */
1060 if (check_fwstate(pmlmepriv
, _FW_LINKED
)) {
1061 if (the_same_macaddr
) {
1062 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, cur_network
->network
.MacAddress
);
1064 pcur_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, cur_network
->network
.MacAddress
);
1066 pcur_wlan
->fixed
= false;
1068 pcur_sta
= rtw_get_stainfo(pstapriv
, cur_network
->network
.MacAddress
);
1070 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
1071 rtw_free_stainfo(adapter
, pcur_sta
);
1072 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
1075 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, pnetwork
->network
.MacAddress
);
1076 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1078 ptarget_wlan
->fixed
= true;
1082 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, pnetwork
->network
.MacAddress
);
1083 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1085 ptarget_wlan
->fixed
= true;
1089 /* s2. update cur_network */
1091 rtw_joinbss_update_network(adapter
, ptarget_wlan
, pnetwork
);
1093 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Can't find ptarget_wlan when joinbss_event callback\n"));
1094 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1095 goto ignore_joinbss_callback
;
1099 /* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */
1100 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1101 ptarget_sta
= rtw_joinbss_update_stainfo(adapter
, pnetwork
);
1102 if (ptarget_sta
== NULL
) {
1103 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Can't update stainfo when joinbss_event callback\n"));
1104 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1105 goto ignore_joinbss_callback
;
1109 /* s4. indicate connect */
1110 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1111 rtw_indicate_connect(adapter
);
1113 /* adhoc mode will rtw_indicate_connect when rtw_stassoc_event_callback */
1114 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("adhoc mode, fw_state:%x", get_fwstate(pmlmepriv
)));
1117 /* s5. Cancle assoc_timer */
1118 del_timer_sync(&pmlmepriv
->assoc_timer
);
1120 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("Cancle assoc_timer\n"));
1123 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("rtw_joinbss_event_callback err: fw_state:%x", get_fwstate(pmlmepriv
)));
1124 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1125 goto ignore_joinbss_callback
;
1128 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1130 } else if (pnetwork
->join_res
== -4) {
1131 rtw_reset_securitypriv(adapter
);
1132 mod_timer(&pmlmepriv
->assoc_timer
,
1133 jiffies
+ msecs_to_jiffies(1));
1135 if ((check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
)) == true) {
1136 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n", get_fwstate(pmlmepriv
)));
1137 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
1139 } else { /* if join_res < 0 (join fails), then try again */
1140 mod_timer(&pmlmepriv
->assoc_timer
,
1141 jiffies
+ msecs_to_jiffies(1));
1142 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
1145 ignore_joinbss_callback
:
1146 spin_unlock_bh(&pmlmepriv
->lock
);
1149 void rtw_joinbss_event_callback(struct adapter
*adapter
, u8
*pbuf
)
1151 struct wlan_network
*pnetwork
= (struct wlan_network
*)pbuf
;
1153 mlmeext_joinbss_event_callback(adapter
, pnetwork
->join_res
);
1155 rtw_os_xmit_schedule(adapter
);
1158 static u8
search_max_mac_id(struct adapter
*padapter
)
1161 #if defined(CONFIG_88EU_AP_MODE)
1163 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1164 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1166 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1167 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1169 #if defined(CONFIG_88EU_AP_MODE)
1170 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1171 for (aid
= (pstapriv
->max_num_sta
); aid
> 0; aid
--) {
1172 if (pstapriv
->sta_aid
[aid
-1] != NULL
)
1178 {/* adhoc id = 31~2 */
1179 for (mac_id
= (NUM_STA
-1); mac_id
>= IBSS_START_MAC_ID
; mac_id
--) {
1180 if (pmlmeinfo
->FW_sta_info
[mac_id
].status
== 1)
1187 /* FOR AP , AD-HOC mode */
1188 void rtw_stassoc_hw_rpt(struct adapter
*adapter
, struct sta_info
*psta
)
1196 macid
= search_max_mac_id(adapter
);
1197 rtw_hal_set_hwreg(adapter
, HW_VAR_TX_RPT_MAX_MACID
, (u8
*)&macid
);
1198 media_status
= (psta
->mac_id
<<8)|1; /* MACID|OPMODE:1 connect */
1199 rtw_hal_set_hwreg(adapter
, HW_VAR_H2C_MEDIA_STATUS_RPT
, (u8
*)&media_status
);
1202 void rtw_stassoc_event_callback(struct adapter
*adapter
, u8
*pbuf
)
1204 struct sta_info
*psta
;
1205 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1206 struct stassoc_event
*pstassoc
= (struct stassoc_event
*)pbuf
;
1207 struct wlan_network
*cur_network
= &(pmlmepriv
->cur_network
);
1208 struct wlan_network
*ptarget_wlan
= NULL
;
1210 if (rtw_access_ctrl(adapter
, pstassoc
->macaddr
) == false)
1213 #if defined(CONFIG_88EU_AP_MODE)
1214 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1215 psta
= rtw_get_stainfo(&adapter
->stapriv
, pstassoc
->macaddr
);
1217 ap_sta_info_defer_update(adapter
, psta
);
1218 rtw_stassoc_hw_rpt(adapter
, psta
);
1223 /* for AD-HOC mode */
1224 psta
= rtw_get_stainfo(&adapter
->stapriv
, pstassoc
->macaddr
);
1226 /* the sta have been in sta_info_queue => do nothing */
1227 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Error: rtw_stassoc_event_callback: sta has been in sta_hash_queue\n"));
1228 return; /* between drv has received this event before and fw have not yet to set key to CAM_ENTRY) */
1230 psta
= rtw_alloc_stainfo(&adapter
->stapriv
, pstassoc
->macaddr
);
1232 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Can't alloc sta_info when rtw_stassoc_event_callback\n"));
1235 /* to do: init sta_info variable */
1236 psta
->qos_option
= 0;
1237 psta
->mac_id
= (uint
)pstassoc
->cam_id
;
1238 DBG_88E("%s\n", __func__
);
1239 /* for ad-hoc mode */
1240 rtw_hal_set_odm_var(adapter
, HAL_ODM_STA_INFO
, psta
, true);
1241 rtw_stassoc_hw_rpt(adapter
, psta
);
1242 if (adapter
->securitypriv
.dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
)
1243 psta
->dot118021XPrivacy
= adapter
->securitypriv
.dot11PrivacyAlgrthm
;
1244 psta
->ieee8021x_blocked
= false;
1245 spin_lock_bh(&pmlmepriv
->lock
);
1246 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) ||
1247 (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
))) {
1248 if (adapter
->stapriv
.asoc_sta_count
== 2) {
1249 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1250 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, cur_network
->network
.MacAddress
);
1252 ptarget_wlan
->fixed
= true;
1253 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1254 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1255 rtw_indicate_connect(adapter
);
1258 spin_unlock_bh(&pmlmepriv
->lock
);
1259 mlmeext_sta_add_event_callback(adapter
, psta
);
1262 void rtw_stadel_event_callback(struct adapter
*adapter
, u8
*pbuf
)
1265 struct sta_info
*psta
;
1266 struct wlan_network
*pwlan
= NULL
;
1267 struct wlan_bssid_ex
*pdev_network
= NULL
;
1269 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1270 struct stadel_event
*pstadel
= (struct stadel_event
*)pbuf
;
1271 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
1272 struct wlan_network
*tgt_network
= &(pmlmepriv
->cur_network
);
1274 psta
= rtw_get_stainfo(&adapter
->stapriv
, pstadel
->macaddr
);
1276 mac_id
= psta
->mac_id
;
1278 mac_id
= pstadel
->mac_id
;
1280 DBG_88E("%s(mac_id=%d)=%pM\n", __func__
, mac_id
, pstadel
->macaddr
);
1284 media_status
= (mac_id
<<8)|0; /* MACID|OPMODE:0 means disconnect */
1285 /* for STA, AP, ADHOC mode, report disconnect stauts to FW */
1286 rtw_hal_set_hwreg(adapter
, HW_VAR_H2C_MEDIA_STATUS_RPT
, (u8
*)&media_status
);
1289 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
))
1292 mlmeext_sta_del_event_callback(adapter
);
1294 spin_lock_bh(&pmlmepriv
->lock
);
1296 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
)) {
1297 if (pmlmepriv
->to_roaming
> 0)
1298 pmlmepriv
->to_roaming
--; /* this stadel_event is caused by roaming, decrease to_roaming */
1299 else if (pmlmepriv
->to_roaming
== 0)
1300 pmlmepriv
->to_roaming
= adapter
->registrypriv
.max_roaming_times
;
1302 if (*((unsigned short *)(pstadel
->rsvd
)) != WLAN_REASON_EXPIRATION_CHK
)
1303 pmlmepriv
->to_roaming
= 0; /* don't roam */
1305 rtw_free_uc_swdec_pending_queue(adapter
);
1307 rtw_free_assoc_resources(adapter
);
1308 rtw_indicate_disconnect(adapter
);
1309 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1310 /* remove the network entry in scanned_queue */
1311 pwlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, tgt_network
->network
.MacAddress
);
1313 pwlan
->fixed
= false;
1314 rtw_free_network_nolock(pmlmepriv
, pwlan
);
1316 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1317 _rtw_roaming(adapter
, tgt_network
);
1319 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) ||
1320 check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)) {
1321 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
1322 rtw_free_stainfo(adapter
, psta
);
1323 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
1325 if (adapter
->stapriv
.asoc_sta_count
== 1) { /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1326 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1327 /* free old ibss network */
1328 pwlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, tgt_network
->network
.MacAddress
);
1330 pwlan
->fixed
= false;
1331 rtw_free_network_nolock(pmlmepriv
, pwlan
);
1333 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1334 /* re-create ibss */
1335 pdev_network
= &(adapter
->registrypriv
.dev_network
);
1336 pibss
= adapter
->registrypriv
.dev_network
.MacAddress
;
1338 memcpy(pdev_network
, &tgt_network
->network
, get_wlan_bssid_ex_sz(&tgt_network
->network
));
1340 memcpy(&pdev_network
->Ssid
, &pmlmepriv
->assoc_ssid
, sizeof(struct ndis_802_11_ssid
));
1342 rtw_update_registrypriv_dev_network(adapter
);
1344 rtw_generate_random_ibss(pibss
);
1346 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)) {
1347 set_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
);
1348 _clr_fwstate_(pmlmepriv
, WIFI_ADHOC_STATE
);
1351 if (rtw_createbss_cmd(adapter
) != _SUCCESS
)
1352 RT_TRACE(_module_rtl871x_ioctl_set_c_
, _drv_err_
, ("***Error=>stadel_event_callback: rtw_createbss_cmd status FAIL***\n "));
1355 spin_unlock_bh(&pmlmepriv
->lock
);
1358 void rtw_cpwm_event_callback(struct adapter
*padapter
, u8
*pbuf
)
1360 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("+rtw_cpwm_event_callback !!!\n"));
1364 * _rtw_join_timeout_handler - Timeout/faliure handler for CMD JoinBss
1365 * @adapter: pointer to struct adapter structure
1367 void _rtw_join_timeout_handler (unsigned long data
)
1369 struct adapter
*adapter
= (struct adapter
*)data
;
1370 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1373 DBG_88E("%s, fw_state=%x\n", __func__
, get_fwstate(pmlmepriv
));
1375 if (adapter
->bDriverStopped
|| adapter
->bSurpriseRemoved
)
1379 spin_lock_bh(&pmlmepriv
->lock
);
1381 if (pmlmepriv
->to_roaming
> 0) { /* join timeout caused by roaming */
1383 pmlmepriv
->to_roaming
--;
1384 if (pmlmepriv
->to_roaming
!= 0) { /* try another , */
1385 DBG_88E("%s try another roaming\n", __func__
);
1386 do_join_r
= rtw_do_join(adapter
);
1387 if (_SUCCESS
!= do_join_r
) {
1388 DBG_88E("%s roaming do_join return %d\n", __func__
, do_join_r
);
1393 DBG_88E("%s We've try roaming but fail\n", __func__
);
1394 rtw_indicate_disconnect(adapter
);
1399 rtw_indicate_disconnect(adapter
);
1400 free_scanqueue(pmlmepriv
);/* */
1402 spin_unlock_bh(&pmlmepriv
->lock
);
1406 * rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey
1407 * @adapter: pointer to struct adapter structure
1409 void rtw_scan_timeout_handler (unsigned long data
)
1411 struct adapter
*adapter
= (struct adapter
*)data
;
1412 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1414 DBG_88E(FUNC_ADPT_FMT
" fw_state=%x\n", FUNC_ADPT_ARG(adapter
), get_fwstate(pmlmepriv
));
1415 spin_lock_bh(&pmlmepriv
->lock
);
1416 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
1417 spin_unlock_bh(&pmlmepriv
->lock
);
1418 rtw_indicate_scan_done(adapter
, true);
1421 static void rtw_auto_scan_handler(struct adapter
*padapter
)
1423 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1425 /* auto site survey per 60sec */
1426 if (pmlmepriv
->scan_interval
> 0) {
1427 pmlmepriv
->scan_interval
--;
1428 if (pmlmepriv
->scan_interval
== 0) {
1429 DBG_88E("%s\n", __func__
);
1430 rtw_set_802_11_bssid_list_scan(padapter
, NULL
, 0);
1431 pmlmepriv
->scan_interval
= SCAN_INTERVAL
;/* 30*2 sec = 60sec */
1436 void rtw_dynamic_check_timer_handlder(unsigned long data
)
1438 struct adapter
*adapter
= (struct adapter
*)data
;
1439 struct registry_priv
*pregistrypriv
= &adapter
->registrypriv
;
1443 if (!adapter
->hw_init_completed
)
1445 if ((adapter
->bDriverStopped
) || (adapter
->bSurpriseRemoved
))
1447 if (adapter
->net_closed
)
1449 rtw_dynamic_chk_wk_cmd(adapter
);
1451 if (pregistrypriv
->wifi_spec
== 1) {
1452 /* auto site survey */
1453 rtw_auto_scan_handler(adapter
);
1456 mod_timer(&adapter
->mlmepriv
.dynamic_chk_timer
,
1457 jiffies
+ msecs_to_jiffies(2000));
1460 #define RTW_SCAN_RESULT_EXPIRE 2000
1463 * Select a new join candidate from the original @param candidate and @param competitor
1464 * @return true: candidate is updated
1465 * @return false: candidate is not updated
1467 static int rtw_check_join_candidate(struct mlme_priv
*pmlmepriv
1468 , struct wlan_network
**candidate
, struct wlan_network
*competitor
)
1470 int updated
= false;
1471 unsigned long since_scan
;
1472 struct adapter
*adapter
= container_of(pmlmepriv
, struct adapter
, mlmepriv
);
1475 /* check bssid, if needed */
1476 if (pmlmepriv
->assoc_by_bssid
) {
1477 if (memcmp(competitor
->network
.MacAddress
, pmlmepriv
->assoc_bssid
, ETH_ALEN
))
1481 /* check ssid, if needed */
1482 if (pmlmepriv
->assoc_ssid
.SsidLength
) {
1483 if (competitor
->network
.Ssid
.SsidLength
!= pmlmepriv
->assoc_ssid
.SsidLength
||
1484 !memcmp(competitor
->network
.Ssid
.Ssid
, pmlmepriv
->assoc_ssid
.Ssid
, pmlmepriv
->assoc_ssid
.SsidLength
) == false)
1488 if (rtw_is_desired_network(adapter
, competitor
) == false)
1491 if (pmlmepriv
->to_roaming
) {
1492 since_scan
= jiffies
- competitor
->last_scanned
;
1493 if (jiffies_to_msecs(since_scan
) >= RTW_SCAN_RESULT_EXPIRE
||
1494 is_same_ess(&competitor
->network
, &pmlmepriv
->cur_network
.network
) == false)
1498 if (*candidate
== NULL
|| (*candidate
)->network
.Rssi
< competitor
->network
.Rssi
) {
1499 *candidate
= competitor
;
1503 DBG_88E("[by_bssid:%u][assoc_ssid:%s]new candidate: %s(%pM rssi:%d\n",
1504 pmlmepriv
->assoc_by_bssid
,
1505 pmlmepriv
->assoc_ssid
.Ssid
,
1506 (*candidate
)->network
.Ssid
.Ssid
,
1507 (*candidate
)->network
.MacAddress
,
1508 (int)(*candidate
)->network
.Rssi
);
1509 DBG_88E("[to_roaming:%u]\n", pmlmepriv
->to_roaming
);
1518 The caller of the sub-routine will be in critical section...
1519 The caller must hold the following spinlock
1523 int rtw_select_and_join_from_scanned_queue(struct mlme_priv
*pmlmepriv
)
1526 struct list_head
*phead
;
1527 struct adapter
*adapter
;
1528 struct __queue
*queue
= &(pmlmepriv
->scanned_queue
);
1529 struct wlan_network
*pnetwork
= NULL
;
1530 struct wlan_network
*candidate
= NULL
;
1531 u8 supp_ant_div
= false;
1533 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1534 phead
= get_list_head(queue
);
1535 adapter
= (struct adapter
*)pmlmepriv
->nic_hdl
;
1536 pmlmepriv
->pscanned
= phead
->next
;
1537 while (phead
!= pmlmepriv
->pscanned
) {
1538 pnetwork
= container_of(pmlmepriv
->pscanned
, struct wlan_network
, list
);
1539 if (pnetwork
== NULL
) {
1540 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("%s return _FAIL:(pnetwork==NULL)\n", __func__
));
1544 pmlmepriv
->pscanned
= pmlmepriv
->pscanned
->next
;
1545 rtw_check_join_candidate(pmlmepriv
, &candidate
, pnetwork
);
1547 if (candidate
== NULL
) {
1548 DBG_88E("%s: return _FAIL(candidate==NULL)\n", __func__
);
1552 DBG_88E("%s: candidate: %s(%pM ch:%u)\n", __func__
,
1553 candidate
->network
.Ssid
.Ssid
, candidate
->network
.MacAddress
,
1554 candidate
->network
.Configuration
.DSConfig
);
1558 /* check for situation of _FW_LINKED */
1559 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true) {
1560 DBG_88E("%s: _FW_LINKED while ask_for_joinbss!!!\n", __func__
);
1562 rtw_disassoc_cmd(adapter
, 0, true);
1563 rtw_indicate_disconnect(adapter
);
1564 rtw_free_assoc_resources_locked(adapter
);
1567 rtw_hal_get_def_var(adapter
, HAL_DEF_IS_SUPPORT_ANT_DIV
, &(supp_ant_div
));
1570 rtw_hal_get_def_var(adapter
, HAL_DEF_CURRENT_ANTENNA
, &(cur_ant
));
1571 DBG_88E("#### Opt_Ant_(%s), cur_Ant(%s)\n",
1572 (2 == candidate
->network
.PhyInfo
.Optimum_antenna
) ? "A" : "B",
1573 (2 == cur_ant
) ? "A" : "B"
1577 ret
= rtw_joinbss_cmd(adapter
, candidate
);
1580 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1584 int rtw_set_auth(struct adapter
*adapter
, struct security_priv
*psecuritypriv
)
1586 struct cmd_obj
*pcmd
;
1587 struct setauth_parm
*psetauthparm
;
1588 struct cmd_priv
*pcmdpriv
= &(adapter
->cmdpriv
);
1591 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
1593 res
= _FAIL
; /* try again */
1597 psetauthparm
= kzalloc(sizeof(struct setauth_parm
), GFP_KERNEL
);
1598 if (psetauthparm
== NULL
) {
1603 memset(psetauthparm
, 0, sizeof(struct setauth_parm
));
1604 psetauthparm
->mode
= (unsigned char)psecuritypriv
->dot11AuthAlgrthm
;
1605 pcmd
->cmdcode
= _SetAuth_CMD_
;
1606 pcmd
->parmbuf
= (unsigned char *)psetauthparm
;
1607 pcmd
->cmdsz
= (sizeof(struct setauth_parm
));
1610 INIT_LIST_HEAD(&pcmd
->list
);
1611 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1612 ("after enqueue set_auth_cmd, auth_mode=%x\n",
1613 psecuritypriv
->dot11AuthAlgrthm
));
1614 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
1619 int rtw_set_key(struct adapter
*adapter
, struct security_priv
*psecuritypriv
, int keyid
, u8 set_tx
)
1622 struct cmd_obj
*pcmd
;
1623 struct setkey_parm
*psetkeyparm
;
1624 struct cmd_priv
*pcmdpriv
= &(adapter
->cmdpriv
);
1625 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1628 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
1630 return _FAIL
; /* try again */
1632 psetkeyparm
= kzalloc(sizeof(struct setkey_parm
), GFP_KERNEL
);
1633 if (psetkeyparm
== NULL
) {
1638 memset(psetkeyparm
, 0, sizeof(struct setkey_parm
));
1640 if (psecuritypriv
->dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
) {
1641 psetkeyparm
->algorithm
= (unsigned char)psecuritypriv
->dot118021XGrpPrivacy
;
1642 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1643 ("\n rtw_set_key: psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy=%d\n",
1644 psetkeyparm
->algorithm
));
1646 psetkeyparm
->algorithm
= (u8
)psecuritypriv
->dot11PrivacyAlgrthm
;
1647 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1648 ("\n rtw_set_key: psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm=%d\n",
1649 psetkeyparm
->algorithm
));
1651 psetkeyparm
->keyid
= (u8
)keyid
;/* 0~3 */
1652 psetkeyparm
->set_tx
= set_tx
;
1653 pmlmepriv
->key_mask
|= BIT(psetkeyparm
->keyid
);
1654 DBG_88E("==> rtw_set_key algorithm(%x), keyid(%x), key_mask(%x)\n",
1655 psetkeyparm
->algorithm
, psetkeyparm
->keyid
, pmlmepriv
->key_mask
);
1656 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1657 ("\n rtw_set_key: psetkeyparm->algorithm=%d psetkeyparm->keyid=(u8)keyid=%d\n",
1658 psetkeyparm
->algorithm
, keyid
));
1660 switch (psetkeyparm
->algorithm
) {
1663 memcpy(&(psetkeyparm
->key
[0]), &(psecuritypriv
->dot11DefKey
[keyid
].skey
[0]), keylen
);
1667 memcpy(&(psetkeyparm
->key
[0]), &(psecuritypriv
->dot11DefKey
[keyid
].skey
[0]), keylen
);
1671 memcpy(&psetkeyparm
->key
, &psecuritypriv
->dot118021XGrpKey
[keyid
], keylen
);
1672 psetkeyparm
->grpkey
= 1;
1676 memcpy(&psetkeyparm
->key
, &psecuritypriv
->dot118021XGrpKey
[keyid
], keylen
);
1677 psetkeyparm
->grpkey
= 1;
1680 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1681 ("\n rtw_set_key:psecuritypriv->dot11PrivacyAlgrthm=%x (must be 1 or 2 or 4 or 5)\n",
1682 psecuritypriv
->dot11PrivacyAlgrthm
));
1686 pcmd
->cmdcode
= _SetKey_CMD_
;
1687 pcmd
->parmbuf
= (u8
*)psetkeyparm
;
1688 pcmd
->cmdsz
= (sizeof(struct setkey_parm
));
1691 INIT_LIST_HEAD(&pcmd
->list
);
1692 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
1702 /* adjust IEs for rtw_joinbss_cmd in WMM */
1703 int rtw_restruct_wmm_ie(struct adapter
*adapter
, u8
*in_ie
, u8
*out_ie
, uint in_len
, uint initial_out_len
)
1705 unsigned int ielength
= 0;
1708 /* i = 12; after the fixed IE */
1709 for (i
= 12; i
< in_len
; i
+= (in_ie
[i
+ 1] + 2) /* to the next IE element */) {
1710 ielength
= initial_out_len
;
1712 if (in_ie
[i
] == 0xDD && in_ie
[i
+2] == 0x00 && in_ie
[i
+3] == 0x50 && in_ie
[i
+4] == 0xF2 && in_ie
[i
+5] == 0x02 && i
+5 < in_len
) {
1713 /* WMM element ID and OUI */
1714 /* Append WMM IE to the last index of out_ie */
1716 for (j
= i
; j
< i
+ 9; j
++) {
1717 out_ie
[ielength
] = in_ie
[j
];
1720 out_ie
[initial_out_len
+ 1] = 0x07;
1721 out_ie
[initial_out_len
+ 6] = 0x00;
1722 out_ie
[initial_out_len
+ 8] = 0x00;
1730 * Ported from 8185: IsInPreAuthKeyList().
1731 * (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.)
1732 * Added by Annie, 2006-05-07.
1735 * -1 :if there is no pre-auth key in the table
1736 * >= 0 :if there is pre-auth key, and return the entry id
1738 static int SecIsInPMKIDList(struct adapter
*Adapter
, u8
*bssid
)
1740 struct security_priv
*psecuritypriv
= &Adapter
->securitypriv
;
1744 if ((psecuritypriv
->PMKIDList
[i
].bUsed
) &&
1745 (!memcmp(psecuritypriv
->PMKIDList
[i
].Bssid
, bssid
, ETH_ALEN
))) {
1752 } while (i
< NUM_PMKID_CACHE
);
1754 if (i
== NUM_PMKID_CACHE
)
1755 i
= -1;/* Could not find. */
1761 /* Check the RSN IE length */
1762 /* If the RSN IE length <= 20, the RSN IE didn't include the PMKID information */
1763 /* 0-11th element in the array are the fixed IE */
1764 /* 12th element in the array is the IE */
1765 /* 13th element in the array is the IE length */
1768 static int rtw_append_pmkid(struct adapter
*Adapter
, int iEntry
, u8
*ie
, uint ie_len
)
1770 struct security_priv
*psecuritypriv
= &Adapter
->securitypriv
;
1773 /* The RSN IE didn't include the PMK ID, append the PMK information */
1776 ie
[ie_len
] = 0; /* PMKID count = 0x0100 */
1778 memcpy(&ie
[ie_len
], &psecuritypriv
->PMKIDList
[iEntry
].PMKID
, 16);
1781 ie
[13] += 18;/* PMKID length = 2+16 */
1786 int rtw_restruct_sec_ie(struct adapter
*adapter
, u8
*in_ie
, u8
*out_ie
, uint in_len
)
1792 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1793 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
1794 uint ndisauthmode
= psecuritypriv
->ndisauthtype
;
1795 uint ndissecuritytype
= psecuritypriv
->ndisencryptstatus
;
1797 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
1798 ("+rtw_restruct_sec_ie: ndisauthmode=%d ndissecuritytype=%d\n",
1799 ndisauthmode
, ndissecuritytype
));
1801 /* copy fixed ie only */
1802 memcpy(out_ie
, in_ie
, 12);
1804 if ((ndisauthmode
== Ndis802_11AuthModeWPA
) ||
1805 (ndisauthmode
== Ndis802_11AuthModeWPAPSK
))
1806 authmode
= _WPA_IE_ID_
;
1807 if ((ndisauthmode
== Ndis802_11AuthModeWPA2
) ||
1808 (ndisauthmode
== Ndis802_11AuthModeWPA2PSK
))
1809 authmode
= _WPA2_IE_ID_
;
1811 if (check_fwstate(pmlmepriv
, WIFI_UNDER_WPS
)) {
1812 memcpy(out_ie
+ielength
, psecuritypriv
->wps_ie
, psecuritypriv
->wps_ie_len
);
1814 ielength
+= psecuritypriv
->wps_ie_len
;
1815 } else if ((authmode
== _WPA_IE_ID_
) || (authmode
== _WPA2_IE_ID_
)) {
1816 /* copy RSN or SSN */
1817 memcpy(&out_ie
[ielength
], &psecuritypriv
->supplicant_ie
[0], psecuritypriv
->supplicant_ie
[1]+2);
1818 ielength
+= psecuritypriv
->supplicant_ie
[1]+2;
1819 rtw_report_sec_ie(adapter
, authmode
, psecuritypriv
->supplicant_ie
);
1822 iEntry
= SecIsInPMKIDList(adapter
, pmlmepriv
->assoc_bssid
);
1826 if (authmode
== _WPA2_IE_ID_
)
1827 ielength
= rtw_append_pmkid(adapter
, iEntry
, out_ie
, ielength
);
1832 void rtw_init_registrypriv_dev_network(struct adapter
*adapter
)
1834 struct registry_priv
*pregistrypriv
= &adapter
->registrypriv
;
1835 struct eeprom_priv
*peepriv
= &adapter
->eeprompriv
;
1836 struct wlan_bssid_ex
*pdev_network
= &pregistrypriv
->dev_network
;
1837 u8
*myhwaddr
= myid(peepriv
);
1839 memcpy(pdev_network
->MacAddress
, myhwaddr
, ETH_ALEN
);
1841 memcpy(&pdev_network
->Ssid
, &pregistrypriv
->ssid
, sizeof(struct ndis_802_11_ssid
));
1843 pdev_network
->Configuration
.Length
= sizeof(struct ndis_802_11_config
);
1844 pdev_network
->Configuration
.BeaconPeriod
= 100;
1845 pdev_network
->Configuration
.FHConfig
.Length
= 0;
1846 pdev_network
->Configuration
.FHConfig
.HopPattern
= 0;
1847 pdev_network
->Configuration
.FHConfig
.HopSet
= 0;
1848 pdev_network
->Configuration
.FHConfig
.DwellTime
= 0;
1851 void rtw_update_registrypriv_dev_network(struct adapter
*adapter
)
1854 struct registry_priv
*pregistrypriv
= &adapter
->registrypriv
;
1855 struct wlan_bssid_ex
*pdev_network
= &pregistrypriv
->dev_network
;
1856 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
1857 struct wlan_network
*cur_network
= &adapter
->mlmepriv
.cur_network
;
1859 pdev_network
->Privacy
= (psecuritypriv
->dot11PrivacyAlgrthm
> 0 ? 1 : 0); /* adhoc no 802.1x */
1861 pdev_network
->Rssi
= 0;
1863 switch (pregistrypriv
->wireless_mode
) {
1865 pdev_network
->NetworkTypeInUse
= (Ndis802_11DS
);
1869 case WIRELESS_11_24N
:
1870 case WIRELESS_11G_24N
:
1871 case WIRELESS_11BG_24N
:
1872 pdev_network
->NetworkTypeInUse
= (Ndis802_11OFDM24
);
1875 case WIRELESS_11A_5N
:
1876 pdev_network
->NetworkTypeInUse
= (Ndis802_11OFDM5
);
1878 case WIRELESS_11ABGN
:
1879 if (pregistrypriv
->channel
> 14)
1880 pdev_network
->NetworkTypeInUse
= (Ndis802_11OFDM5
);
1882 pdev_network
->NetworkTypeInUse
= (Ndis802_11OFDM24
);
1889 pdev_network
->Configuration
.DSConfig
= (pregistrypriv
->channel
);
1890 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
1891 ("pregistrypriv->channel=%d, pdev_network->Configuration.DSConfig=0x%x\n",
1892 pregistrypriv
->channel
, pdev_network
->Configuration
.DSConfig
));
1894 if (cur_network
->network
.InfrastructureMode
== Ndis802_11IBSS
)
1895 pdev_network
->Configuration
.ATIMWindow
= (0);
1897 pdev_network
->InfrastructureMode
= (cur_network
->network
.InfrastructureMode
);
1899 /* 1. Supported rates */
1902 sz
= rtw_generate_ie(pregistrypriv
);
1903 pdev_network
->IELength
= sz
;
1904 pdev_network
->Length
= get_wlan_bssid_ex_sz((struct wlan_bssid_ex
*)pdev_network
);
1906 /* notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); */
1907 /* pdev_network->IELength = cpu_to_le32(sz); */
1910 void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter
*adapter
)
1914 /* the function is at passive_level */
1915 void rtw_joinbss_reset(struct adapter
*padapter
)
1918 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1919 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
1921 /* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */
1922 pmlmepriv
->num_FortyMHzIntolerant
= 0;
1924 pmlmepriv
->num_sta_no_ht
= 0;
1926 phtpriv
->ampdu_enable
= false;/* reset to disabled */
1928 /* TH = 1 => means that invalidate usb rx aggregation */
1929 /* TH = 0 => means that validate usb rx aggregation, use init value. */
1930 if (phtpriv
->ht_option
) {
1931 if (padapter
->registrypriv
.wifi_spec
== 1)
1935 rtw_hal_set_hwreg(padapter
, HW_VAR_RXDMA_AGG_PG_TH
, (u8
*)(&threshold
));
1938 rtw_hal_set_hwreg(padapter
, HW_VAR_RXDMA_AGG_PG_TH
, (u8
*)(&threshold
));
1942 /* the function is >= passive_level */
1943 unsigned int rtw_restructure_ht_ie(struct adapter
*padapter
, u8
*in_ie
, u8
*out_ie
, uint in_len
, uint
*pout_len
)
1946 enum ht_cap_ampdu_factor max_rx_ampdu_factor
;
1948 struct rtw_ieee80211_ht_cap ht_capie
;
1949 unsigned char WMM_IE
[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
1950 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1951 struct qos_priv
*pqospriv
= &pmlmepriv
->qospriv
;
1952 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
1953 u32 rx_packet_offset
, max_recvbuf_sz
;
1956 phtpriv
->ht_option
= false;
1958 p
= rtw_get_ie(in_ie
+12, _HT_CAPABILITY_IE_
, &ielen
, in_len
-12);
1960 if (p
&& ielen
> 0) {
1961 if (pqospriv
->qos_option
== 0) {
1962 out_len
= *pout_len
;
1963 rtw_set_ie(out_ie
+out_len
, _VENDOR_SPECIFIC_IE_
,
1964 _WMM_IE_Length_
, WMM_IE
, pout_len
);
1966 pqospriv
->qos_option
= 1;
1969 out_len
= *pout_len
;
1971 memset(&ht_capie
, 0, sizeof(struct rtw_ieee80211_ht_cap
));
1973 ht_capie
.cap_info
= IEEE80211_HT_CAP_SUP_WIDTH
|
1974 IEEE80211_HT_CAP_SGI_20
|
1975 IEEE80211_HT_CAP_SGI_40
|
1976 IEEE80211_HT_CAP_TX_STBC
|
1977 IEEE80211_HT_CAP_DSSSCCK40
;
1979 rtw_hal_get_def_var(padapter
, HAL_DEF_RX_PACKET_OFFSET
, &rx_packet_offset
);
1980 rtw_hal_get_def_var(padapter
, HAL_DEF_MAX_RECVBUF_SZ
, &max_recvbuf_sz
);
1983 AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
1984 AMPDU_para [4:2]:Min MPDU Start Spacing
1987 rtw_hal_get_def_var(padapter
, HW_VAR_MAX_RX_AMPDU_FACTOR
, &max_rx_ampdu_factor
);
1988 ht_capie
.ampdu_params_info
= (max_rx_ampdu_factor
&0x03);
1990 if (padapter
->securitypriv
.dot11PrivacyAlgrthm
== _AES_
)
1991 ht_capie
.ampdu_params_info
|= (IEEE80211_HT_CAP_AMPDU_DENSITY
&(0x07<<2));
1993 ht_capie
.ampdu_params_info
|= (IEEE80211_HT_CAP_AMPDU_DENSITY
&0x00);
1996 rtw_set_ie(out_ie
+out_len
, _HT_CAPABILITY_IE_
,
1997 sizeof(struct rtw_ieee80211_ht_cap
), (unsigned char *)&ht_capie
, pout_len
);
1999 phtpriv
->ht_option
= true;
2001 p
= rtw_get_ie(in_ie
+12, _HT_ADD_INFO_IE_
, &ielen
, in_len
-12);
2002 if (p
&& (ielen
== sizeof(struct ieee80211_ht_addt_info
))) {
2003 out_len
= *pout_len
;
2004 rtw_set_ie(out_ie
+out_len
, _HT_ADD_INFO_IE_
, ielen
, p
+2, pout_len
);
2007 return phtpriv
->ht_option
;
2010 /* the function is > passive_level (in critical_section) */
2011 void rtw_update_ht_cap(struct adapter
*padapter
, u8
*pie
, uint ie_len
)
2013 u8
*p
, max_ampdu_sz
;
2015 struct rtw_ieee80211_ht_cap
*pht_capie
;
2016 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2017 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
2018 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
2019 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2020 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2022 if (!phtpriv
->ht_option
)
2025 if ((!pmlmeinfo
->HT_info_enable
) || (!pmlmeinfo
->HT_caps_enable
))
2028 DBG_88E("+rtw_update_ht_cap()\n");
2030 /* maybe needs check if ap supports rx ampdu. */
2031 if ((!phtpriv
->ampdu_enable
) && (pregistrypriv
->ampdu_enable
== 1)) {
2032 if (pregistrypriv
->wifi_spec
== 1)
2033 phtpriv
->ampdu_enable
= false;
2035 phtpriv
->ampdu_enable
= true;
2036 } else if (pregistrypriv
->ampdu_enable
== 2) {
2037 phtpriv
->ampdu_enable
= true;
2041 /* check Max Rx A-MPDU Size */
2043 p
= rtw_get_ie(pie
+sizeof(struct ndis_802_11_fixed_ie
), _HT_CAPABILITY_IE_
, &len
, ie_len
-sizeof(struct ndis_802_11_fixed_ie
));
2045 pht_capie
= (struct rtw_ieee80211_ht_cap
*)(p
+2);
2046 max_ampdu_sz
= pht_capie
->ampdu_params_info
& IEEE80211_HT_CAP_AMPDU_FACTOR
;
2047 max_ampdu_sz
= 1 << (max_ampdu_sz
+3); /* max_ampdu_sz (kbytes); */
2048 phtpriv
->rx_ampdu_maxlen
= max_ampdu_sz
;
2051 p
= rtw_get_ie(pie
+sizeof(struct ndis_802_11_fixed_ie
), _HT_ADD_INFO_IE_
, &len
, ie_len
-sizeof(struct ndis_802_11_fixed_ie
));
2053 /* update cur_bwmode & cur_ch_offset */
2054 if ((pregistrypriv
->cbw40_enable
) &&
2055 (le16_to_cpu(pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
) & BIT(1)) &&
2056 (pmlmeinfo
->HT_info
.infos
[0] & BIT(2))) {
2060 padapter
->HalFunc
.GetHwRegHandler(padapter
, HW_VAR_RF_TYPE
, (u8
*)(&rf_type
));
2062 /* update the MCS rates */
2063 for (i
= 0; i
< 16; i
++) {
2064 if ((rf_type
== RF_1T1R
) || (rf_type
== RF_1T2R
))
2065 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.MCS_rate
[i
] &= MCS_rate_1R
[i
];
2067 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.MCS_rate
[i
] &= MCS_rate_2R
[i
];
2069 /* switch to the 40M Hz mode according to the AP */
2070 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_40
;
2071 switch ((pmlmeinfo
->HT_info
.infos
[0] & 0x3)) {
2072 case HT_EXTCHNL_OFFSET_UPPER
:
2073 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_LOWER
;
2075 case HT_EXTCHNL_OFFSET_LOWER
:
2076 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_UPPER
;
2079 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
2084 /* Config SM Power Save setting */
2085 pmlmeinfo
->SM_PS
= (le16_to_cpu(pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
) & 0x0C) >> 2;
2086 if (pmlmeinfo
->SM_PS
== WLAN_HT_CAP_SM_PS_STATIC
)
2087 DBG_88E("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__
);
2089 /* Config current HT Protection mode. */
2090 pmlmeinfo
->HT_protection
= pmlmeinfo
->HT_info
.infos
[1] & 0x3;
2093 void rtw_issue_addbareq_cmd(struct adapter
*padapter
, struct xmit_frame
*pxmitframe
)
2097 struct sta_info
*psta
= NULL
;
2098 struct ht_priv
*phtpriv
;
2099 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
2100 s32 bmcst
= IS_MCAST(pattrib
->ra
);
2102 if (bmcst
|| (padapter
->mlmepriv
.LinkDetectInfo
.NumTxOkInPeriod
< 100))
2105 priority
= pattrib
->priority
;
2108 psta
= pattrib
->psta
;
2110 psta
= rtw_get_stainfo(&padapter
->stapriv
, pattrib
->ra
);
2115 phtpriv
= &psta
->htpriv
;
2117 if ((phtpriv
->ht_option
) && (phtpriv
->ampdu_enable
)) {
2118 issued
= (phtpriv
->agg_enable_bitmap
>>priority
)&0x1;
2119 issued
|= (phtpriv
->candidate_tid_bitmap
>>priority
)&0x1;
2122 DBG_88E("rtw_issue_addbareq_cmd, p=%d\n", priority
);
2123 psta
->htpriv
.candidate_tid_bitmap
|= BIT((u8
)priority
);
2124 rtw_addbareq_cmd(padapter
, (u8
)priority
, pattrib
->ra
);
2129 void rtw_roaming(struct adapter
*padapter
, struct wlan_network
*tgt_network
)
2131 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2133 spin_lock_bh(&pmlmepriv
->lock
);
2134 _rtw_roaming(padapter
, tgt_network
);
2135 spin_unlock_bh(&pmlmepriv
->lock
);
2137 void _rtw_roaming(struct adapter
*padapter
, struct wlan_network
*tgt_network
)
2139 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2142 struct wlan_network
*pnetwork
;
2144 if (tgt_network
!= NULL
)
2145 pnetwork
= tgt_network
;
2147 pnetwork
= &pmlmepriv
->cur_network
;
2149 if (0 < pmlmepriv
->to_roaming
) {
2150 DBG_88E("roaming from %s(%pM length:%d\n",
2151 pnetwork
->network
.Ssid
.Ssid
, pnetwork
->network
.MacAddress
,
2152 pnetwork
->network
.Ssid
.SsidLength
);
2153 memcpy(&pmlmepriv
->assoc_ssid
, &pnetwork
->network
.Ssid
, sizeof(struct ndis_802_11_ssid
));
2155 pmlmepriv
->assoc_by_bssid
= false;
2158 do_join_r
= rtw_do_join(padapter
);
2159 if (_SUCCESS
== do_join_r
) {
2162 DBG_88E("roaming do_join return %d\n", do_join_r
);
2163 pmlmepriv
->to_roaming
--;
2165 if (0 < pmlmepriv
->to_roaming
) {
2168 DBG_88E("%s(%d) -to roaming fail, indicate_disconnect\n", __func__
, __LINE__
);
2169 rtw_indicate_disconnect(padapter
);