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 ******************************************************************************/
23 #include <osdep_service.h>
24 #include <drv_types.h>
25 #include <recv_osdep.h>
26 #include <xmit_osdep.h>
28 #include <mlme_osdep.h>
31 #include <wlan_bssdef.h>
32 #include <rtw_ioctl_set.h>
33 #include <linux/vmalloc.h>
35 extern unsigned char MCS_rate_2R
[16];
36 extern unsigned char MCS_rate_1R
[16];
38 int rtw_init_mlme_priv(struct adapter
*padapter
)
42 struct wlan_network
*pnetwork
;
43 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
46 /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */
48 pmlmepriv
->nic_hdl
= (u8
*)padapter
;
50 pmlmepriv
->pscanned
= NULL
;
51 pmlmepriv
->fw_state
= 0;
52 pmlmepriv
->cur_network
.network
.InfrastructureMode
= Ndis802_11AutoUnknown
;
53 pmlmepriv
->scan_mode
= SCAN_ACTIVE
;/* 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) */
55 spin_lock_init(&(pmlmepriv
->lock
));
56 _rtw_init_queue(&(pmlmepriv
->free_bss_pool
));
57 _rtw_init_queue(&(pmlmepriv
->scanned_queue
));
59 set_scanned_network_val(pmlmepriv
, 0);
61 memset(&pmlmepriv
->assoc_ssid
, 0, sizeof(struct ndis_802_11_ssid
));
63 pbuf
= vzalloc(MAX_BSS_CNT
* (sizeof(struct wlan_network
)));
69 pmlmepriv
->free_bss_buf
= pbuf
;
71 pnetwork
= (struct wlan_network
*)pbuf
;
73 for (i
= 0; i
< MAX_BSS_CNT
; i
++) {
74 INIT_LIST_HEAD(&(pnetwork
->list
));
76 list_add_tail(&(pnetwork
->list
), &(pmlmepriv
->free_bss_pool
.queue
));
81 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
83 rtw_clear_scan_deny(padapter
);
85 rtw_init_mlme_timer(padapter
);
91 #if defined(CONFIG_88EU_AP_MODE)
92 static void rtw_free_mlme_ie_data(u8
**ppie
, u32
*plen
)
99 void rtw_free_mlme_priv_ie_data(struct mlme_priv
*pmlmepriv
)
101 rtw_buf_free(&pmlmepriv
->assoc_req
, &pmlmepriv
->assoc_req_len
);
102 rtw_buf_free(&pmlmepriv
->assoc_rsp
, &pmlmepriv
->assoc_rsp_len
);
103 rtw_free_mlme_ie_data(&pmlmepriv
->wps_beacon_ie
, &pmlmepriv
->wps_beacon_ie_len
);
104 rtw_free_mlme_ie_data(&pmlmepriv
->wps_probe_req_ie
, &pmlmepriv
->wps_probe_req_ie_len
);
105 rtw_free_mlme_ie_data(&pmlmepriv
->wps_probe_resp_ie
, &pmlmepriv
->wps_probe_resp_ie_len
);
106 rtw_free_mlme_ie_data(&pmlmepriv
->wps_assoc_resp_ie
, &pmlmepriv
->wps_assoc_resp_ie_len
);
108 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_beacon_ie
, &pmlmepriv
->p2p_beacon_ie_len
);
109 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_probe_req_ie
, &pmlmepriv
->p2p_probe_req_ie_len
);
110 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_probe_resp_ie
, &pmlmepriv
->p2p_probe_resp_ie_len
);
111 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_go_probe_resp_ie
, &pmlmepriv
->p2p_go_probe_resp_ie_len
);
112 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_assoc_req_ie
, &pmlmepriv
->p2p_assoc_req_ie_len
);
115 void rtw_free_mlme_priv_ie_data(struct mlme_priv
*pmlmepriv
)
120 void rtw_free_mlme_priv(struct mlme_priv
*pmlmepriv
)
122 rtw_free_mlme_priv_ie_data(pmlmepriv
);
125 if (pmlmepriv
->free_bss_buf
)
126 vfree(pmlmepriv
->free_bss_buf
);
130 struct wlan_network
*_rtw_alloc_network(struct mlme_priv
*pmlmepriv
)/* _queue *free_queue) */
132 struct wlan_network
*pnetwork
;
133 struct __queue
*free_queue
= &pmlmepriv
->free_bss_pool
;
134 struct list_head
*plist
= NULL
;
136 spin_lock_bh(&free_queue
->lock
);
138 if (list_empty(&free_queue
->queue
)) {
142 plist
= free_queue
->queue
.next
;
144 pnetwork
= container_of(plist
, struct wlan_network
, list
);
146 list_del_init(&pnetwork
->list
);
148 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("_rtw_alloc_network: ptr=%p\n", plist
));
149 pnetwork
->network_type
= 0;
150 pnetwork
->fixed
= false;
151 pnetwork
->last_scanned
= jiffies
;
153 pnetwork
->join_res
= 0;
155 pmlmepriv
->num_of_scanned
++;
158 spin_unlock_bh(&free_queue
->lock
);
163 static void _rtw_free_network(struct mlme_priv
*pmlmepriv
, struct wlan_network
*pnetwork
, u8 isfreeall
)
165 u32 curr_time
, delta_time
;
166 u32 lifetime
= SCANQUEUE_LIFETIME
;
167 struct __queue
*free_queue
= &(pmlmepriv
->free_bss_pool
);
169 if (pnetwork
== NULL
)
175 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) ||
176 (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)))
179 delta_time
= (curr_time
- pnetwork
->last_scanned
)/HZ
;
180 if (delta_time
< lifetime
)/* unit:sec */
183 spin_lock_bh(&free_queue
->lock
);
184 list_del_init(&(pnetwork
->list
));
185 list_add_tail(&(pnetwork
->list
), &(free_queue
->queue
));
186 pmlmepriv
->num_of_scanned
--;
187 spin_unlock_bh(&free_queue
->lock
);
190 void _rtw_free_network_nolock(struct mlme_priv
*pmlmepriv
, struct wlan_network
*pnetwork
)
192 struct __queue
*free_queue
= &(pmlmepriv
->free_bss_pool
);
194 if (pnetwork
== NULL
)
198 list_del_init(&(pnetwork
->list
));
199 list_add_tail(&(pnetwork
->list
), get_list_head(free_queue
));
200 pmlmepriv
->num_of_scanned
--;
204 return the wlan_network with the matching addr
206 Shall be calle under atomic context... to avoid possible racing condition...
208 struct wlan_network
*rtw_find_network(struct __queue
*scanned_queue
, u8
*addr
)
210 struct list_head
*phead
, *plist
;
211 struct wlan_network
*pnetwork
= NULL
;
212 u8 zero_addr
[ETH_ALEN
] = {0, 0, 0, 0, 0, 0};
214 if (!memcmp(zero_addr
, addr
, ETH_ALEN
)) {
218 phead
= get_list_head(scanned_queue
);
221 while (plist
!= phead
) {
222 pnetwork
= container_of(plist
, struct wlan_network
, list
);
223 if (!memcmp(addr
, pnetwork
->network
.MacAddress
, ETH_ALEN
))
234 void rtw_free_network_queue(struct adapter
*padapter
, u8 isfreeall
)
236 struct list_head
*phead
, *plist
;
237 struct wlan_network
*pnetwork
;
238 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
239 struct __queue
*scanned_queue
= &pmlmepriv
->scanned_queue
;
241 spin_lock_bh(&scanned_queue
->lock
);
243 phead
= get_list_head(scanned_queue
);
246 while (phead
!= plist
) {
247 pnetwork
= container_of(plist
, struct wlan_network
, list
);
251 _rtw_free_network(pmlmepriv
, pnetwork
, isfreeall
);
253 spin_unlock_bh(&scanned_queue
->lock
);
256 int rtw_if_up(struct adapter
*padapter
)
260 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
||
261 (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) == false)) {
262 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
263 ("rtw_if_up:bDriverStopped(%d) OR bSurpriseRemoved(%d)",
264 padapter
->bDriverStopped
, padapter
->bSurpriseRemoved
));
272 void rtw_generate_random_ibss(u8
*pibss
)
274 u32 curtime
= jiffies
;
276 pibss
[0] = 0x02; /* in ad-hoc mode bit1 must set to 1 */
279 pibss
[3] = (u8
)(curtime
& 0xff);/* p[0]; */
280 pibss
[4] = (u8
)((curtime
>>8) & 0xff);/* p[1]; */
281 pibss
[5] = (u8
)((curtime
>>16) & 0xff);/* p[2]; */
285 u8
*rtw_get_capability_from_ie(u8
*ie
)
291 u16
rtw_get_capability(struct wlan_bssid_ex
*bss
)
295 memcpy((u8
*)&val
, rtw_get_capability_from_ie(bss
->IEs
), 2);
297 return le16_to_cpu(val
);
300 u8
*rtw_get_beacon_interval_from_ie(u8
*ie
)
305 static struct wlan_network
*rtw_alloc_network(struct mlme_priv
*pmlmepriv
)
307 return _rtw_alloc_network(pmlmepriv
);
310 static void rtw_free_network_nolock(struct mlme_priv
*pmlmepriv
,
311 struct wlan_network
*pnetwork
)
313 _rtw_free_network_nolock(pmlmepriv
, pnetwork
);
316 int rtw_is_same_ibss(struct adapter
*adapter
, struct wlan_network
*pnetwork
)
319 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
321 if ((psecuritypriv
->dot11PrivacyAlgrthm
!= _NO_PRIVACY_
) &&
322 (pnetwork
->network
.Privacy
== 0))
324 else if ((psecuritypriv
->dot11PrivacyAlgrthm
== _NO_PRIVACY_
) &&
325 (pnetwork
->network
.Privacy
== 1))
332 static int is_same_ess(struct wlan_bssid_ex
*a
, struct wlan_bssid_ex
*b
)
334 return (a
->Ssid
.SsidLength
== b
->Ssid
.SsidLength
) &&
335 !memcmp(a
->Ssid
.Ssid
, b
->Ssid
.Ssid
, a
->Ssid
.SsidLength
);
338 int is_same_network(struct wlan_bssid_ex
*src
, struct wlan_bssid_ex
*dst
)
341 __le16 le_scap
, le_dcap
;
343 memcpy((u8
*)&le_scap
, rtw_get_capability_from_ie(src
->IEs
), 2);
344 memcpy((u8
*)&le_dcap
, rtw_get_capability_from_ie(dst
->IEs
), 2);
347 s_cap
= le16_to_cpu(le_scap
);
348 d_cap
= le16_to_cpu(le_dcap
);
350 return ((src
->Ssid
.SsidLength
== dst
->Ssid
.SsidLength
) &&
351 ((!memcmp(src
->MacAddress
, dst
->MacAddress
, ETH_ALEN
)) == true) &&
352 ((!memcmp(src
->Ssid
.Ssid
, dst
->Ssid
.Ssid
, src
->Ssid
.SsidLength
)) == true) &&
353 ((s_cap
& WLAN_CAPABILITY_IBSS
) ==
354 (d_cap
& WLAN_CAPABILITY_IBSS
)) &&
355 ((s_cap
& WLAN_CAPABILITY_BSS
) ==
356 (d_cap
& WLAN_CAPABILITY_BSS
)));
359 struct wlan_network
*rtw_get_oldest_wlan_network(struct __queue
*scanned_queue
)
361 struct list_head
*plist
, *phead
;
362 struct wlan_network
*pwlan
= NULL
;
363 struct wlan_network
*oldest
= NULL
;
365 phead
= get_list_head(scanned_queue
);
373 pwlan
= container_of(plist
, struct wlan_network
, list
);
376 if (oldest
== NULL
|| time_after(oldest
->last_scanned
, pwlan
->last_scanned
))
385 void update_network(struct wlan_bssid_ex
*dst
, struct wlan_bssid_ex
*src
,
386 struct adapter
*padapter
, bool update_ie
)
388 long rssi_ori
= dst
->Rssi
;
389 u8 sq_smp
= src
->PhyInfo
.SignalQuality
;
394 rtw_hal_antdiv_rssi_compared(padapter
, dst
, src
); /* this will update src.Rssi, need consider again */
396 /* The rule below is 1/5 for sample value, 4/5 for history value */
397 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) && is_same_network(&(padapter
->mlmepriv
.cur_network
.network
), src
)) {
398 /* Take the recvpriv's value for the connected AP*/
399 ss_final
= padapter
->recvpriv
.signal_strength
;
400 sq_final
= padapter
->recvpriv
.signal_qual
;
401 /* the rssi value here is undecorated, and will be used for antenna diversity */
402 if (sq_smp
!= 101) /* from the right channel */
403 rssi_final
= (src
->Rssi
+dst
->Rssi
*4)/5;
405 rssi_final
= rssi_ori
;
407 if (sq_smp
!= 101) { /* from the right channel */
408 ss_final
= ((u32
)(src
->PhyInfo
.SignalStrength
)+(u32
)(dst
->PhyInfo
.SignalStrength
)*4)/5;
409 sq_final
= ((u32
)(src
->PhyInfo
.SignalQuality
)+(u32
)(dst
->PhyInfo
.SignalQuality
)*4)/5;
410 rssi_final
= (src
->Rssi
+dst
->Rssi
*4)/5;
412 /* bss info not receiving from the right channel, use the original RX signal infos */
413 ss_final
= dst
->PhyInfo
.SignalStrength
;
414 sq_final
= dst
->PhyInfo
.SignalQuality
;
415 rssi_final
= dst
->Rssi
;
419 memcpy((u8
*)dst
, (u8
*)src
, get_wlan_bssid_ex_sz(src
));
420 dst
->PhyInfo
.SignalStrength
= ss_final
;
421 dst
->PhyInfo
.SignalQuality
= sq_final
;
422 dst
->Rssi
= rssi_final
;
426 static void update_current_network(struct adapter
*adapter
, struct wlan_bssid_ex
*pnetwork
)
428 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
430 if ((check_fwstate(pmlmepriv
, _FW_LINKED
) == true) &&
431 (is_same_network(&(pmlmepriv
->cur_network
.network
), pnetwork
))) {
432 update_network(&(pmlmepriv
->cur_network
.network
), pnetwork
, adapter
, true);
433 rtw_update_protection(adapter
, (pmlmepriv
->cur_network
.network
.IEs
) + sizeof(struct ndis_802_11_fixed_ie
),
434 pmlmepriv
->cur_network
.network
.IELength
);
439 Caller must hold pmlmepriv->lock first.
441 void rtw_update_scanned_network(struct adapter
*adapter
, struct wlan_bssid_ex
*target
)
443 struct list_head
*plist
, *phead
;
445 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
446 struct __queue
*queue
= &(pmlmepriv
->scanned_queue
);
447 struct wlan_network
*pnetwork
= NULL
;
448 struct wlan_network
*oldest
= NULL
;
450 spin_lock_bh(&queue
->lock
);
451 phead
= get_list_head(queue
);
454 while (phead
!= plist
) {
455 pnetwork
= container_of(plist
, struct wlan_network
, list
);
457 if (is_same_network(&(pnetwork
->network
), target
))
459 if ((oldest
== ((struct wlan_network
*)0)) ||
460 time_after(oldest
->last_scanned
, pnetwork
->last_scanned
))
464 /* If we didn't find a match, then get a new network slot to initialize
465 * with this beacon's information */
466 if (phead
== plist
) {
467 if (list_empty(&(pmlmepriv
->free_bss_pool
.queue
))) {
468 /* If there are no more slots, expire the oldest */
471 rtw_hal_get_def_var(adapter
, HAL_DEF_CURRENT_ANTENNA
, &(target
->PhyInfo
.Optimum_antenna
));
472 memcpy(&(pnetwork
->network
), target
, get_wlan_bssid_ex_sz(target
));
473 /* variable initialize */
474 pnetwork
->fixed
= false;
475 pnetwork
->last_scanned
= jiffies
;
477 pnetwork
->network_type
= 0;
479 pnetwork
->join_res
= 0;
481 /* bss info not receiving from the right channel */
482 if (pnetwork
->network
.PhyInfo
.SignalQuality
== 101)
483 pnetwork
->network
.PhyInfo
.SignalQuality
= 0;
485 /* Otherwise just pull from the free list */
487 pnetwork
= rtw_alloc_network(pmlmepriv
); /* will update scan_time */
489 if (pnetwork
== NULL
) {
490 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("\n\n\nsomething wrong here\n\n\n"));
494 bssid_ex_sz
= get_wlan_bssid_ex_sz(target
);
495 target
->Length
= bssid_ex_sz
;
496 rtw_hal_get_def_var(adapter
, HAL_DEF_CURRENT_ANTENNA
, &(target
->PhyInfo
.Optimum_antenna
));
497 memcpy(&(pnetwork
->network
), target
, bssid_ex_sz
);
499 pnetwork
->last_scanned
= jiffies
;
501 /* bss info not receiving from the right channel */
502 if (pnetwork
->network
.PhyInfo
.SignalQuality
== 101)
503 pnetwork
->network
.PhyInfo
.SignalQuality
= 0;
504 list_add_tail(&(pnetwork
->list
), &(queue
->queue
));
507 /* we have an entry and we are going to update it. But this entry may
508 * be already expired. In this case we do the same as we found a new
509 * net and call the new_net handler
511 bool update_ie
= true;
513 pnetwork
->last_scanned
= jiffies
;
515 /* target.Reserved[0]== 1, means that scanned network is a bcn frame. */
516 if ((pnetwork
->network
.IELength
> target
->IELength
) && (target
->Reserved
[0] == 1))
519 update_network(&(pnetwork
->network
), target
, adapter
, update_ie
);
523 spin_unlock_bh(&queue
->lock
);
527 static void rtw_add_network(struct adapter
*adapter
,
528 struct wlan_bssid_ex
*pnetwork
)
530 update_current_network(adapter
, pnetwork
);
531 rtw_update_scanned_network(adapter
, pnetwork
);
535 * select the desired network based on the capability of the (i)bss.
536 * check items: (1) security
542 static int rtw_is_desired_network(struct adapter
*adapter
, struct wlan_network
*pnetwork
)
544 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
545 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
549 /* u8 wps_ie[512]; */
552 int bselected
= true;
554 desired_encmode
= psecuritypriv
->ndisencryptstatus
;
555 privacy
= pnetwork
->network
.Privacy
;
557 if (check_fwstate(pmlmepriv
, WIFI_UNDER_WPS
)) {
558 if (rtw_get_wps_ie(pnetwork
->network
.IEs
+_FIXED_IE_LENGTH_
, pnetwork
->network
.IELength
-_FIXED_IE_LENGTH_
, NULL
, &wps_ielen
) != NULL
)
563 if (adapter
->registrypriv
.wifi_spec
== 1) { /* for correct flow of 8021X to do.... */
564 if ((desired_encmode
== Ndis802_11EncryptionDisabled
) && (privacy
!= 0))
569 if ((desired_encmode
!= Ndis802_11EncryptionDisabled
) && (privacy
== 0)) {
570 DBG_88E("desired_encmode: %d, privacy: %d\n", desired_encmode
, privacy
);
574 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) == true) {
575 if (pnetwork
->network
.InfrastructureMode
!= pmlmepriv
->cur_network
.network
.InfrastructureMode
)
583 /* TODO: Perry: For Power Management */
584 void rtw_atimdone_event_callback(struct adapter
*adapter
, u8
*pbuf
)
586 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("receive atimdone_evet\n"));
591 void rtw_survey_event_callback(struct adapter
*adapter
, u8
*pbuf
)
594 struct wlan_bssid_ex
*pnetwork
;
595 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
597 pnetwork
= (struct wlan_bssid_ex
*)pbuf
;
599 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_survey_event_callback, ssid=%s\n", pnetwork
->Ssid
.Ssid
));
601 len
= get_wlan_bssid_ex_sz(pnetwork
);
602 if (len
> (sizeof(struct wlan_bssid_ex
))) {
603 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("\n****rtw_survey_event_callback: return a wrong bss ***\n"));
606 spin_lock_bh(&pmlmepriv
->lock
);
608 /* update IBSS_network 's timestamp */
609 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) == true) {
610 if (!memcmp(&(pmlmepriv
->cur_network
.network
.MacAddress
), pnetwork
->MacAddress
, ETH_ALEN
)) {
611 struct wlan_network
*ibss_wlan
= NULL
;
613 memcpy(pmlmepriv
->cur_network
.network
.IEs
, pnetwork
->IEs
, 8);
614 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
615 ibss_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, pnetwork
->MacAddress
);
617 memcpy(ibss_wlan
->network
.IEs
, pnetwork
->IEs
, 8);
618 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
621 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
625 /* lock pmlmepriv->lock when you accessing network_q */
626 if ((check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
)) == false) {
627 if (pnetwork
->Ssid
.Ssid
[0] == 0)
628 pnetwork
->Ssid
.SsidLength
= 0;
629 rtw_add_network(adapter
, pnetwork
);
634 spin_unlock_bh(&pmlmepriv
->lock
);
638 void rtw_surveydone_event_callback(struct adapter
*adapter
, u8
*pbuf
)
640 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
641 struct mlme_ext_priv
*pmlmeext
;
643 spin_lock_bh(&pmlmepriv
->lock
);
645 if (pmlmepriv
->wps_probe_req_ie
) {
646 pmlmepriv
->wps_probe_req_ie_len
= 0;
647 kfree(pmlmepriv
->wps_probe_req_ie
);
648 pmlmepriv
->wps_probe_req_ie
= NULL
;
651 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_surveydone_event_callback: fw_state:%x\n\n", get_fwstate(pmlmepriv
)));
653 if (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
)) {
654 del_timer_sync(&pmlmepriv
->scan_to_timer
);
655 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
657 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("nic status=%x, survey done event comes too late!\n", get_fwstate(pmlmepriv
)));
660 rtw_set_signal_stat_timer(&adapter
->recvpriv
);
662 if (pmlmepriv
->to_join
) {
663 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) == true)) {
664 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == false) {
665 set_fwstate(pmlmepriv
, _FW_UNDER_LINKING
);
667 if (rtw_select_and_join_from_scanned_queue(pmlmepriv
) == _SUCCESS
) {
668 _set_timer(&pmlmepriv
->assoc_timer
, MAX_JOIN_TIMEOUT
);
670 struct wlan_bssid_ex
*pdev_network
= &(adapter
->registrypriv
.dev_network
);
671 u8
*pibss
= adapter
->registrypriv
.dev_network
.MacAddress
;
673 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
675 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("switching to adhoc master\n"));
677 memcpy(&pdev_network
->Ssid
, &pmlmepriv
->assoc_ssid
, sizeof(struct ndis_802_11_ssid
));
679 rtw_update_registrypriv_dev_network(adapter
);
680 rtw_generate_random_ibss(pibss
);
682 pmlmepriv
->fw_state
= WIFI_ADHOC_MASTER_STATE
;
684 if (rtw_createbss_cmd(adapter
) != _SUCCESS
)
685 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Error=>rtw_createbss_cmd status FAIL\n"));
686 pmlmepriv
->to_join
= false;
691 set_fwstate(pmlmepriv
, _FW_UNDER_LINKING
);
692 pmlmepriv
->to_join
= false;
693 s_ret
= rtw_select_and_join_from_scanned_queue(pmlmepriv
);
694 if (_SUCCESS
== s_ret
) {
695 _set_timer(&pmlmepriv
->assoc_timer
, MAX_JOIN_TIMEOUT
);
696 } else if (s_ret
== 2) { /* there is no need to wait for join */
697 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
698 rtw_indicate_connect(adapter
);
700 DBG_88E("try_to_join, but select scanning queue fail, to_roaming:%d\n", pmlmepriv
->to_roaming
);
701 if (pmlmepriv
->to_roaming
!= 0) {
702 if (--pmlmepriv
->to_roaming
== 0 ||
703 _SUCCESS
!= rtw_sitesurvey_cmd(adapter
, &pmlmepriv
->assoc_ssid
, 1, NULL
, 0)) {
704 pmlmepriv
->to_roaming
= 0;
705 rtw_free_assoc_resources(adapter
, 1);
706 rtw_indicate_disconnect(adapter
);
708 pmlmepriv
->to_join
= true;
711 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
716 indicate_wx_scan_complete_event(adapter
);
718 spin_unlock_bh(&pmlmepriv
->lock
);
720 rtw_os_xmit_schedule(adapter
);
722 pmlmeext
= &adapter
->mlmeextpriv
;
725 void rtw_dummy_event_callback(struct adapter
*adapter
, u8
*pbuf
)
729 void rtw_fwdbg_event_callback(struct adapter
*adapter
, u8
*pbuf
)
733 static void free_scanqueue(struct mlme_priv
*pmlmepriv
)
735 struct __queue
*free_queue
= &pmlmepriv
->free_bss_pool
;
736 struct __queue
*scan_queue
= &pmlmepriv
->scanned_queue
;
737 struct list_head
*plist
, *phead
, *ptemp
;
739 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
, ("+free_scanqueue\n"));
740 spin_lock_bh(&scan_queue
->lock
);
741 spin_lock_bh(&free_queue
->lock
);
743 phead
= get_list_head(scan_queue
);
746 while (plist
!= phead
) {
748 list_del_init(plist
);
749 list_add_tail(plist
, &free_queue
->queue
);
751 pmlmepriv
->num_of_scanned
--;
754 spin_unlock_bh(&free_queue
->lock
);
755 spin_unlock_bh(&scan_queue
->lock
);
759 *rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock
761 void rtw_free_assoc_resources(struct adapter
*adapter
, int lock_scanned_queue
)
763 struct wlan_network
*pwlan
= NULL
;
764 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
765 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
766 struct wlan_network
*tgt_network
= &pmlmepriv
->cur_network
;
768 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
, ("+rtw_free_assoc_resources\n"));
769 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
770 ("tgt_network->network.MacAddress=%pM ssid=%s\n",
771 tgt_network
->network
.MacAddress
, tgt_network
->network
.Ssid
.Ssid
));
773 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
| WIFI_AP_STATE
)) {
774 struct sta_info
*psta
;
776 psta
= rtw_get_stainfo(&adapter
->stapriv
, tgt_network
->network
.MacAddress
);
778 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
779 rtw_free_stainfo(adapter
, psta
);
780 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
783 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
| WIFI_ADHOC_MASTER_STATE
| WIFI_AP_STATE
)) {
784 struct sta_info
*psta
;
786 rtw_free_all_stainfo(adapter
);
788 psta
= rtw_get_bcmc_stainfo(adapter
);
789 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
790 rtw_free_stainfo(adapter
, psta
);
791 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
793 rtw_init_bcmc_stainfo(adapter
);
796 if (lock_scanned_queue
)
797 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
799 pwlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, tgt_network
->network
.MacAddress
);
801 pwlan
->fixed
= false;
803 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("rtw_free_assoc_resources:pwlan==NULL\n\n"));
805 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) && (adapter
->stapriv
.asoc_sta_count
== 1)))
806 rtw_free_network_nolock(pmlmepriv
, pwlan
);
808 if (lock_scanned_queue
)
809 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
810 pmlmepriv
->key_mask
= 0;
814 *rtw_indicate_connect: the caller has to lock pmlmepriv->lock
816 void rtw_indicate_connect(struct adapter
*padapter
)
818 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
820 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("+rtw_indicate_connect\n"));
822 pmlmepriv
->to_join
= false;
824 if (!check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
)) {
825 set_fwstate(pmlmepriv
, _FW_LINKED
);
827 rtw_led_control(padapter
, LED_CTL_LINK
);
829 rtw_os_indicate_connect(padapter
);
832 pmlmepriv
->to_roaming
= 0;
834 rtw_set_scan_deny(padapter
, 3000);
836 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("-rtw_indicate_connect: fw_state=0x%08x\n", get_fwstate(pmlmepriv
)));
840 *rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock
842 void rtw_indicate_disconnect(struct adapter
*padapter
)
844 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
846 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("+rtw_indicate_disconnect\n"));
848 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
| WIFI_UNDER_WPS
);
851 if (pmlmepriv
->to_roaming
> 0)
852 _clr_fwstate_(pmlmepriv
, _FW_LINKED
);
854 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) ||
855 (pmlmepriv
->to_roaming
<= 0)) {
856 rtw_os_indicate_disconnect(padapter
);
858 _clr_fwstate_(pmlmepriv
, _FW_LINKED
);
859 rtw_led_control(padapter
, LED_CTL_NO_LINK
);
860 rtw_clear_scan_deny(padapter
);
863 rtw_lps_ctrl_wk_cmd(padapter
, LPS_CTRL_DISCONNECT
, 1);
866 inline void rtw_indicate_scan_done(struct adapter
*padapter
, bool aborted
)
868 rtw_os_indicate_scan_done(padapter
, aborted
);
871 void rtw_scan_abort(struct adapter
*adapter
)
874 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
875 struct mlme_ext_priv
*pmlmeext
= &(adapter
->mlmeextpriv
);
878 pmlmeext
->scan_abort
= true;
879 while (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
) &&
880 rtw_get_passing_time_ms(start
) <= 200) {
881 if (adapter
->bDriverStopped
|| adapter
->bSurpriseRemoved
)
883 DBG_88E(FUNC_NDEV_FMT
"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter
->pnetdev
));
886 if (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
)) {
887 if (!adapter
->bDriverStopped
&& !adapter
->bSurpriseRemoved
)
888 DBG_88E(FUNC_NDEV_FMT
"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter
->pnetdev
));
889 rtw_indicate_scan_done(adapter
, true);
891 pmlmeext
->scan_abort
= false;
894 static struct sta_info
*rtw_joinbss_update_stainfo(struct adapter
*padapter
, struct wlan_network
*pnetwork
)
897 struct sta_info
*bmc_sta
, *psta
= NULL
;
898 struct recv_reorder_ctrl
*preorder_ctrl
;
899 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
901 psta
= rtw_get_stainfo(pstapriv
, pnetwork
->network
.MacAddress
);
903 psta
= rtw_alloc_stainfo(pstapriv
, pnetwork
->network
.MacAddress
);
905 if (psta
) { /* update ptarget_sta */
906 DBG_88E("%s\n", __func__
);
907 psta
->aid
= pnetwork
->join_res
;
910 rtw_hal_set_odm_var(padapter
, HAL_ODM_STA_INFO
, psta
, true);
911 /* security related */
912 if (padapter
->securitypriv
.dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
) {
913 padapter
->securitypriv
.binstallGrpkey
= false;
914 padapter
->securitypriv
.busetkipkey
= false;
915 padapter
->securitypriv
.bgrpkey_handshake
= false;
916 psta
->ieee8021x_blocked
= true;
917 psta
->dot118021XPrivacy
= padapter
->securitypriv
.dot11PrivacyAlgrthm
;
918 memset((u8
*)&psta
->dot118021x_UncstKey
, 0, sizeof(union Keytype
));
919 memset((u8
*)&psta
->dot11tkiprxmickey
, 0, sizeof(union Keytype
));
920 memset((u8
*)&psta
->dot11tkiptxmickey
, 0, sizeof(union Keytype
));
921 memset((u8
*)&psta
->dot11txpn
, 0, sizeof(union pn48
));
922 memset((u8
*)&psta
->dot11rxpn
, 0, sizeof(union pn48
));
925 * Commented by Albert 2012/07/21
926 * When doing the WPS, the wps_ie_len won't equal to 0
927 * And the Wi-Fi driver shouldn't allow the data
928 * packet to be tramsmitted.
930 if (padapter
->securitypriv
.wps_ie_len
!= 0) {
931 psta
->ieee8021x_blocked
= true;
932 padapter
->securitypriv
.wps_ie_len
= 0;
934 /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */
935 /* if A-MPDU Rx is enabled, resetting rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */
936 /* todo: check if AP can send A-MPDU packets */
937 for (i
= 0; i
< 16; i
++) {
938 /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
939 preorder_ctrl
= &psta
->recvreorder_ctrl
[i
];
940 preorder_ctrl
->enable
= false;
941 preorder_ctrl
->indicate_seq
= 0xffff;
942 preorder_ctrl
->wend_b
= 0xffff;
943 preorder_ctrl
->wsize_b
= 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
945 bmc_sta
= rtw_get_bcmc_stainfo(padapter
);
947 for (i
= 0; i
< 16; i
++) {
948 /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
949 preorder_ctrl
= &bmc_sta
->recvreorder_ctrl
[i
];
950 preorder_ctrl
->enable
= false;
951 preorder_ctrl
->indicate_seq
= 0xffff;
952 preorder_ctrl
->wend_b
= 0xffff;
953 preorder_ctrl
->wsize_b
= 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
957 update_sta_info(padapter
, psta
);
962 /* pnetwork: returns from rtw_joinbss_event_callback */
963 /* ptarget_wlan: found from scanned_queue */
964 static void rtw_joinbss_update_network(struct adapter
*padapter
, struct wlan_network
*ptarget_wlan
, struct wlan_network
*pnetwork
)
966 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
967 struct wlan_network
*cur_network
= &(pmlmepriv
->cur_network
);
969 DBG_88E("%s\n", __func__
);
971 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
972 ("\nfw_state:%x, BSSID:%pM\n",
973 get_fwstate(pmlmepriv
), pnetwork
->network
.MacAddress
));
976 /* why not use ptarget_wlan?? */
977 memcpy(&cur_network
->network
, &pnetwork
->network
, pnetwork
->network
.Length
);
978 /* some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
979 cur_network
->network
.IELength
= ptarget_wlan
->network
.IELength
;
980 memcpy(&cur_network
->network
.IEs
[0], &ptarget_wlan
->network
.IEs
[0], MAX_IE_SZ
);
982 cur_network
->aid
= pnetwork
->join_res
;
985 rtw_set_signal_stat_timer(&padapter
->recvpriv
);
986 padapter
->recvpriv
.signal_strength
= ptarget_wlan
->network
.PhyInfo
.SignalStrength
;
987 padapter
->recvpriv
.signal_qual
= ptarget_wlan
->network
.PhyInfo
.SignalQuality
;
988 /* the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) */
989 padapter
->recvpriv
.rssi
= translate_percentage_to_dbm(ptarget_wlan
->network
.PhyInfo
.SignalStrength
);
990 rtw_set_signal_stat_timer(&padapter
->recvpriv
);
992 /* update fw_state will clr _FW_UNDER_LINKING here indirectly */
993 switch (pnetwork
->network
.InfrastructureMode
) {
994 case Ndis802_11Infrastructure
:
995 if (pmlmepriv
->fw_state
&WIFI_UNDER_WPS
)
996 pmlmepriv
->fw_state
= WIFI_STATION_STATE
|WIFI_UNDER_WPS
;
998 pmlmepriv
->fw_state
= WIFI_STATION_STATE
;
1000 case Ndis802_11IBSS
:
1001 pmlmepriv
->fw_state
= WIFI_ADHOC_STATE
;
1004 pmlmepriv
->fw_state
= WIFI_NULL_STATE
;
1005 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Invalid network_mode\n"));
1009 rtw_update_protection(padapter
, (cur_network
->network
.IEs
) +
1010 sizeof(struct ndis_802_11_fixed_ie
),
1011 (cur_network
->network
.IELength
));
1012 rtw_update_ht_cap(padapter
, cur_network
->network
.IEs
, cur_network
->network
.IELength
);
1015 /* Notes: the function could be > passive_level (the same context as Rx tasklet) */
1016 /* pnetwork: returns from rtw_joinbss_event_callback */
1017 /* ptarget_wlan: found from scanned_queue */
1018 /* if join_res > 0, for (fw_state == WIFI_STATION_STATE), we check if "ptarget_sta" & "ptarget_wlan" exist. */
1019 /* if join_res > 0, for (fw_state == WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. */
1020 /* if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan != NULL). */
1022 void rtw_joinbss_event_prehandle(struct adapter
*adapter
, u8
*pbuf
)
1024 struct sta_info
*ptarget_sta
= NULL
, *pcur_sta
= NULL
;
1025 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
1026 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1027 struct wlan_network
*pnetwork
= (struct wlan_network
*)pbuf
;
1028 struct wlan_network
*cur_network
= &(pmlmepriv
->cur_network
);
1029 struct wlan_network
*pcur_wlan
= NULL
, *ptarget_wlan
= NULL
;
1030 unsigned int the_same_macaddr
= false;
1032 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("joinbss event call back received with res=%d\n", pnetwork
->join_res
));
1034 rtw_get_encrypt_decrypt_from_registrypriv(adapter
);
1037 if (pmlmepriv
->assoc_ssid
.SsidLength
== 0)
1038 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("@@@@@ joinbss event call back for Any SSid\n"));
1040 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("@@@@@ rtw_joinbss_event_callback for SSid:%s\n", pmlmepriv
->assoc_ssid
.Ssid
));
1042 the_same_macaddr
= !memcmp(pnetwork
->network
.MacAddress
, cur_network
->network
.MacAddress
, ETH_ALEN
);
1044 pnetwork
->network
.Length
= get_wlan_bssid_ex_sz(&pnetwork
->network
);
1045 if (pnetwork
->network
.Length
> sizeof(struct wlan_bssid_ex
)) {
1046 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("\n\n ***joinbss_evt_callback return a wrong bss ***\n\n"));
1050 spin_lock_bh(&pmlmepriv
->lock
);
1052 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("\nrtw_joinbss_event_callback!! _enter_critical\n"));
1054 if (pnetwork
->join_res
> 0) {
1055 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1056 if (check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
)) {
1057 /* s1. find ptarget_wlan */
1058 if (check_fwstate(pmlmepriv
, _FW_LINKED
)) {
1059 if (the_same_macaddr
) {
1060 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, cur_network
->network
.MacAddress
);
1062 pcur_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, cur_network
->network
.MacAddress
);
1064 pcur_wlan
->fixed
= false;
1066 pcur_sta
= rtw_get_stainfo(pstapriv
, cur_network
->network
.MacAddress
);
1068 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
1069 rtw_free_stainfo(adapter
, pcur_sta
);
1070 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
1073 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, pnetwork
->network
.MacAddress
);
1074 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1076 ptarget_wlan
->fixed
= true;
1080 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, pnetwork
->network
.MacAddress
);
1081 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1083 ptarget_wlan
->fixed
= true;
1087 /* s2. update cur_network */
1089 rtw_joinbss_update_network(adapter
, ptarget_wlan
, pnetwork
);
1091 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Can't find ptarget_wlan when joinbss_event callback\n"));
1092 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1093 goto ignore_joinbss_callback
;
1097 /* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */
1098 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1099 ptarget_sta
= rtw_joinbss_update_stainfo(adapter
, pnetwork
);
1100 if (ptarget_sta
== NULL
) {
1101 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Can't update stainfo when joinbss_event callback\n"));
1102 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1103 goto ignore_joinbss_callback
;
1107 /* s4. indicate connect */
1108 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1109 rtw_indicate_connect(adapter
);
1111 /* adhoc mode will rtw_indicate_connect when rtw_stassoc_event_callback */
1112 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("adhoc mode, fw_state:%x", get_fwstate(pmlmepriv
)));
1115 /* s5. Cancle assoc_timer */
1116 del_timer_sync(&pmlmepriv
->assoc_timer
);
1118 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("Cancle assoc_timer\n"));
1121 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("rtw_joinbss_event_callback err: fw_state:%x", get_fwstate(pmlmepriv
)));
1122 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1123 goto ignore_joinbss_callback
;
1126 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1128 } else if (pnetwork
->join_res
== -4) {
1129 rtw_reset_securitypriv(adapter
);
1130 _set_timer(&pmlmepriv
->assoc_timer
, 1);
1132 if ((check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
)) == true) {
1133 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n", get_fwstate(pmlmepriv
)));
1134 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
1136 } else { /* if join_res < 0 (join fails), then try again */
1137 _set_timer(&pmlmepriv
->assoc_timer
, 1);
1138 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
1141 ignore_joinbss_callback
:
1142 spin_unlock_bh(&pmlmepriv
->lock
);
1145 void rtw_joinbss_event_callback(struct adapter
*adapter
, u8
*pbuf
)
1147 struct wlan_network
*pnetwork
= (struct wlan_network
*)pbuf
;
1149 mlmeext_joinbss_event_callback(adapter
, pnetwork
->join_res
);
1151 rtw_os_xmit_schedule(adapter
);
1154 static u8
search_max_mac_id(struct adapter
*padapter
)
1157 #if defined(CONFIG_88EU_AP_MODE)
1159 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1160 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1162 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1163 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1165 #if defined(CONFIG_88EU_AP_MODE)
1166 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1167 for (aid
= (pstapriv
->max_num_sta
); aid
> 0; aid
--) {
1168 if (pstapriv
->sta_aid
[aid
-1] != NULL
)
1174 {/* adhoc id = 31~2 */
1175 for (mac_id
= (NUM_STA
-1); mac_id
>= IBSS_START_MAC_ID
; mac_id
--) {
1176 if (pmlmeinfo
->FW_sta_info
[mac_id
].status
== 1)
1183 /* FOR AP , AD-HOC mode */
1184 void rtw_stassoc_hw_rpt(struct adapter
*adapter
, struct sta_info
*psta
)
1192 macid
= search_max_mac_id(adapter
);
1193 rtw_hal_set_hwreg(adapter
, HW_VAR_TX_RPT_MAX_MACID
, (u8
*)&macid
);
1194 media_status
= (psta
->mac_id
<<8)|1; /* MACID|OPMODE:1 connect */
1195 rtw_hal_set_hwreg(adapter
, HW_VAR_H2C_MEDIA_STATUS_RPT
, (u8
*)&media_status
);
1198 void rtw_stassoc_event_callback(struct adapter
*adapter
, u8
*pbuf
)
1200 struct sta_info
*psta
;
1201 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1202 struct stassoc_event
*pstassoc
= (struct stassoc_event
*)pbuf
;
1203 struct wlan_network
*cur_network
= &(pmlmepriv
->cur_network
);
1204 struct wlan_network
*ptarget_wlan
= NULL
;
1206 if (rtw_access_ctrl(adapter
, pstassoc
->macaddr
) == false)
1209 #if defined(CONFIG_88EU_AP_MODE)
1210 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1211 psta
= rtw_get_stainfo(&adapter
->stapriv
, pstassoc
->macaddr
);
1213 ap_sta_info_defer_update(adapter
, psta
);
1214 rtw_stassoc_hw_rpt(adapter
, psta
);
1219 /* for AD-HOC mode */
1220 psta
= rtw_get_stainfo(&adapter
->stapriv
, pstassoc
->macaddr
);
1222 /* the sta have been in sta_info_queue => do nothing */
1223 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Error: rtw_stassoc_event_callback: sta has been in sta_hash_queue\n"));
1224 return; /* between drv has received this event before and fw have not yet to set key to CAM_ENTRY) */
1226 psta
= rtw_alloc_stainfo(&adapter
->stapriv
, pstassoc
->macaddr
);
1228 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Can't alloc sta_info when rtw_stassoc_event_callback\n"));
1231 /* to do: init sta_info variable */
1232 psta
->qos_option
= 0;
1233 psta
->mac_id
= (uint
)pstassoc
->cam_id
;
1234 DBG_88E("%s\n", __func__
);
1235 /* for ad-hoc mode */
1236 rtw_hal_set_odm_var(adapter
, HAL_ODM_STA_INFO
, psta
, true);
1237 rtw_stassoc_hw_rpt(adapter
, psta
);
1238 if (adapter
->securitypriv
.dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
)
1239 psta
->dot118021XPrivacy
= adapter
->securitypriv
.dot11PrivacyAlgrthm
;
1240 psta
->ieee8021x_blocked
= false;
1241 spin_lock_bh(&pmlmepriv
->lock
);
1242 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) ||
1243 (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
))) {
1244 if (adapter
->stapriv
.asoc_sta_count
== 2) {
1245 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1246 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, cur_network
->network
.MacAddress
);
1248 ptarget_wlan
->fixed
= true;
1249 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1250 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1251 rtw_indicate_connect(adapter
);
1254 spin_unlock_bh(&pmlmepriv
->lock
);
1255 mlmeext_sta_add_event_callback(adapter
, psta
);
1258 void rtw_stadel_event_callback(struct adapter
*adapter
, u8
*pbuf
)
1261 struct sta_info
*psta
;
1262 struct wlan_network
*pwlan
= NULL
;
1263 struct wlan_bssid_ex
*pdev_network
= NULL
;
1265 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1266 struct stadel_event
*pstadel
= (struct stadel_event
*)pbuf
;
1267 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
1268 struct wlan_network
*tgt_network
= &(pmlmepriv
->cur_network
);
1270 psta
= rtw_get_stainfo(&adapter
->stapriv
, pstadel
->macaddr
);
1272 mac_id
= psta
->mac_id
;
1274 mac_id
= pstadel
->mac_id
;
1276 DBG_88E("%s(mac_id=%d)=%pM\n", __func__
, mac_id
, pstadel
->macaddr
);
1280 media_status
= (mac_id
<<8)|0; /* MACID|OPMODE:0 means disconnect */
1281 /* for STA, AP, ADHOC mode, report disconnect stauts to FW */
1282 rtw_hal_set_hwreg(adapter
, HW_VAR_H2C_MEDIA_STATUS_RPT
, (u8
*)&media_status
);
1285 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
))
1288 mlmeext_sta_del_event_callback(adapter
);
1290 spin_lock_bh(&pmlmepriv
->lock
);
1292 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
)) {
1293 if (pmlmepriv
->to_roaming
> 0)
1294 pmlmepriv
->to_roaming
--; /* this stadel_event is caused by roaming, decrease to_roaming */
1295 else if (pmlmepriv
->to_roaming
== 0)
1296 pmlmepriv
->to_roaming
= adapter
->registrypriv
.max_roaming_times
;
1298 if (*((unsigned short *)(pstadel
->rsvd
)) != WLAN_REASON_EXPIRATION_CHK
)
1299 pmlmepriv
->to_roaming
= 0; /* don't roam */
1301 rtw_free_uc_swdec_pending_queue(adapter
);
1303 rtw_free_assoc_resources(adapter
, 1);
1304 rtw_indicate_disconnect(adapter
);
1305 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1306 /* remove the network entry in scanned_queue */
1307 pwlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, tgt_network
->network
.MacAddress
);
1309 pwlan
->fixed
= false;
1310 rtw_free_network_nolock(pmlmepriv
, pwlan
);
1312 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1313 _rtw_roaming(adapter
, tgt_network
);
1315 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) ||
1316 check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)) {
1317 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
1318 rtw_free_stainfo(adapter
, psta
);
1319 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
1321 if (adapter
->stapriv
.asoc_sta_count
== 1) { /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1322 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1323 /* free old ibss network */
1324 pwlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, tgt_network
->network
.MacAddress
);
1326 pwlan
->fixed
= false;
1327 rtw_free_network_nolock(pmlmepriv
, pwlan
);
1329 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1330 /* re-create ibss */
1331 pdev_network
= &(adapter
->registrypriv
.dev_network
);
1332 pibss
= adapter
->registrypriv
.dev_network
.MacAddress
;
1334 memcpy(pdev_network
, &tgt_network
->network
, get_wlan_bssid_ex_sz(&tgt_network
->network
));
1336 memcpy(&pdev_network
->Ssid
, &pmlmepriv
->assoc_ssid
, sizeof(struct ndis_802_11_ssid
));
1338 rtw_update_registrypriv_dev_network(adapter
);
1340 rtw_generate_random_ibss(pibss
);
1342 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)) {
1343 set_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
);
1344 _clr_fwstate_(pmlmepriv
, WIFI_ADHOC_STATE
);
1347 if (rtw_createbss_cmd(adapter
) != _SUCCESS
)
1348 RT_TRACE(_module_rtl871x_ioctl_set_c_
, _drv_err_
, ("***Error=>stadel_event_callback: rtw_createbss_cmd status FAIL***\n "));
1351 spin_unlock_bh(&pmlmepriv
->lock
);
1354 void rtw_cpwm_event_callback(struct adapter
*padapter
, u8
*pbuf
)
1356 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("+rtw_cpwm_event_callback !!!\n"));
1360 * _rtw_join_timeout_handler - Timeout/faliure handler for CMD JoinBss
1361 * @adapter: pointer to struct adapter structure
1363 void _rtw_join_timeout_handler (void *function_context
)
1365 struct adapter
*adapter
= function_context
;
1366 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1369 DBG_88E("%s, fw_state=%x\n", __func__
, get_fwstate(pmlmepriv
));
1371 if (adapter
->bDriverStopped
|| adapter
->bSurpriseRemoved
)
1375 spin_lock_bh(&pmlmepriv
->lock
);
1377 if (pmlmepriv
->to_roaming
> 0) { /* join timeout caused by roaming */
1379 pmlmepriv
->to_roaming
--;
1380 if (pmlmepriv
->to_roaming
!= 0) { /* try another , */
1381 DBG_88E("%s try another roaming\n", __func__
);
1382 do_join_r
= rtw_do_join(adapter
);
1383 if (_SUCCESS
!= do_join_r
) {
1384 DBG_88E("%s roaming do_join return %d\n", __func__
, do_join_r
);
1389 DBG_88E("%s We've try roaming but fail\n", __func__
);
1390 rtw_indicate_disconnect(adapter
);
1395 rtw_indicate_disconnect(adapter
);
1396 free_scanqueue(pmlmepriv
);/* */
1398 spin_unlock_bh(&pmlmepriv
->lock
);
1402 * rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey
1403 * @adapter: pointer to struct adapter structure
1405 void rtw_scan_timeout_handler (void *function_context
)
1407 struct adapter
*adapter
= function_context
;
1408 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1410 DBG_88E(FUNC_ADPT_FMT
" fw_state=%x\n", FUNC_ADPT_ARG(adapter
), get_fwstate(pmlmepriv
));
1411 spin_lock_bh(&pmlmepriv
->lock
);
1412 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
1413 spin_unlock_bh(&pmlmepriv
->lock
);
1414 rtw_indicate_scan_done(adapter
, true);
1417 static void rtw_auto_scan_handler(struct adapter
*padapter
)
1419 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1421 /* auto site survey per 60sec */
1422 if (pmlmepriv
->scan_interval
> 0) {
1423 pmlmepriv
->scan_interval
--;
1424 if (pmlmepriv
->scan_interval
== 0) {
1425 DBG_88E("%s\n", __func__
);
1426 rtw_set_802_11_bssid_list_scan(padapter
, NULL
, 0);
1427 pmlmepriv
->scan_interval
= SCAN_INTERVAL
;/* 30*2 sec = 60sec */
1432 void rtw_dynamic_check_timer_handlder(void *function_context
)
1434 struct adapter
*adapter
= (struct adapter
*)function_context
;
1435 struct registry_priv
*pregistrypriv
= &adapter
->registrypriv
;
1439 if (!adapter
->hw_init_completed
)
1441 if ((adapter
->bDriverStopped
) || (adapter
->bSurpriseRemoved
))
1443 if (adapter
->net_closed
)
1445 rtw_dynamic_chk_wk_cmd(adapter
);
1447 if (pregistrypriv
->wifi_spec
== 1) {
1448 /* auto site survey */
1449 rtw_auto_scan_handler(adapter
);
1452 _set_timer(&adapter
->mlmepriv
.dynamic_chk_timer
, 2000);
1455 #define RTW_SCAN_RESULT_EXPIRE 2000
1458 * Select a new join candidate from the original @param candidate and @param competitor
1459 * @return true: candidate is updated
1460 * @return false: candidate is not updated
1462 static int rtw_check_join_candidate(struct mlme_priv
*pmlmepriv
1463 , struct wlan_network
**candidate
, struct wlan_network
*competitor
)
1465 int updated
= false;
1466 struct adapter
*adapter
= container_of(pmlmepriv
, struct adapter
, mlmepriv
);
1469 /* check bssid, if needed */
1470 if (pmlmepriv
->assoc_by_bssid
) {
1471 if (memcmp(competitor
->network
.MacAddress
, pmlmepriv
->assoc_bssid
, ETH_ALEN
))
1475 /* check ssid, if needed */
1476 if (pmlmepriv
->assoc_ssid
.SsidLength
) {
1477 if (competitor
->network
.Ssid
.SsidLength
!= pmlmepriv
->assoc_ssid
.SsidLength
||
1478 !memcmp(competitor
->network
.Ssid
.Ssid
, pmlmepriv
->assoc_ssid
.Ssid
, pmlmepriv
->assoc_ssid
.SsidLength
) == false)
1482 if (rtw_is_desired_network(adapter
, competitor
) == false)
1485 if (pmlmepriv
->to_roaming
) {
1486 if (rtw_get_passing_time_ms((u32
)competitor
->last_scanned
) >= RTW_SCAN_RESULT_EXPIRE
||
1487 is_same_ess(&competitor
->network
, &pmlmepriv
->cur_network
.network
) == false)
1491 if (*candidate
== NULL
|| (*candidate
)->network
.Rssi
< competitor
->network
.Rssi
) {
1492 *candidate
= competitor
;
1496 DBG_88E("[by_bssid:%u][assoc_ssid:%s]new candidate: %s(%pM rssi:%d\n",
1497 pmlmepriv
->assoc_by_bssid
,
1498 pmlmepriv
->assoc_ssid
.Ssid
,
1499 (*candidate
)->network
.Ssid
.Ssid
,
1500 (*candidate
)->network
.MacAddress
,
1501 (int)(*candidate
)->network
.Rssi
);
1502 DBG_88E("[to_roaming:%u]\n", pmlmepriv
->to_roaming
);
1511 The caller of the sub-routine will be in critical section...
1512 The caller must hold the following spinlock
1516 int rtw_select_and_join_from_scanned_queue(struct mlme_priv
*pmlmepriv
)
1519 struct list_head
*phead
;
1520 struct adapter
*adapter
;
1521 struct __queue
*queue
= &(pmlmepriv
->scanned_queue
);
1522 struct wlan_network
*pnetwork
= NULL
;
1523 struct wlan_network
*candidate
= NULL
;
1524 u8 supp_ant_div
= false;
1526 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1527 phead
= get_list_head(queue
);
1528 adapter
= (struct adapter
*)pmlmepriv
->nic_hdl
;
1529 pmlmepriv
->pscanned
= phead
->next
;
1530 while (phead
!= pmlmepriv
->pscanned
) {
1531 pnetwork
= container_of(pmlmepriv
->pscanned
, struct wlan_network
, list
);
1532 if (pnetwork
== NULL
) {
1533 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("%s return _FAIL:(pnetwork==NULL)\n", __func__
));
1537 pmlmepriv
->pscanned
= pmlmepriv
->pscanned
->next
;
1538 rtw_check_join_candidate(pmlmepriv
, &candidate
, pnetwork
);
1540 if (candidate
== NULL
) {
1541 DBG_88E("%s: return _FAIL(candidate==NULL)\n", __func__
);
1545 DBG_88E("%s: candidate: %s(%pM ch:%u)\n", __func__
,
1546 candidate
->network
.Ssid
.Ssid
, candidate
->network
.MacAddress
,
1547 candidate
->network
.Configuration
.DSConfig
);
1551 /* check for situation of _FW_LINKED */
1552 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true) {
1553 DBG_88E("%s: _FW_LINKED while ask_for_joinbss!!!\n", __func__
);
1555 rtw_disassoc_cmd(adapter
, 0, true);
1556 rtw_indicate_disconnect(adapter
);
1557 rtw_free_assoc_resources(adapter
, 0);
1560 rtw_hal_get_def_var(adapter
, HAL_DEF_IS_SUPPORT_ANT_DIV
, &(supp_ant_div
));
1563 rtw_hal_get_def_var(adapter
, HAL_DEF_CURRENT_ANTENNA
, &(cur_ant
));
1564 DBG_88E("#### Opt_Ant_(%s), cur_Ant(%s)\n",
1565 (2 == candidate
->network
.PhyInfo
.Optimum_antenna
) ? "A" : "B",
1566 (2 == cur_ant
) ? "A" : "B"
1570 ret
= rtw_joinbss_cmd(adapter
, candidate
);
1573 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1577 int rtw_set_auth(struct adapter
*adapter
, struct security_priv
*psecuritypriv
)
1579 struct cmd_obj
*pcmd
;
1580 struct setauth_parm
*psetauthparm
;
1581 struct cmd_priv
*pcmdpriv
= &(adapter
->cmdpriv
);
1584 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
1586 res
= _FAIL
; /* try again */
1590 psetauthparm
= kzalloc(sizeof(struct setauth_parm
), GFP_KERNEL
);
1591 if (psetauthparm
== NULL
) {
1596 memset(psetauthparm
, 0, sizeof(struct setauth_parm
));
1597 psetauthparm
->mode
= (unsigned char)psecuritypriv
->dot11AuthAlgrthm
;
1598 pcmd
->cmdcode
= _SetAuth_CMD_
;
1599 pcmd
->parmbuf
= (unsigned char *)psetauthparm
;
1600 pcmd
->cmdsz
= (sizeof(struct setauth_parm
));
1603 INIT_LIST_HEAD(&pcmd
->list
);
1604 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1605 ("after enqueue set_auth_cmd, auth_mode=%x\n",
1606 psecuritypriv
->dot11AuthAlgrthm
));
1607 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
1612 int rtw_set_key(struct adapter
*adapter
, struct security_priv
*psecuritypriv
, int keyid
, u8 set_tx
)
1615 struct cmd_obj
*pcmd
;
1616 struct setkey_parm
*psetkeyparm
;
1617 struct cmd_priv
*pcmdpriv
= &(adapter
->cmdpriv
);
1618 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1621 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
1623 return _FAIL
; /* try again */
1625 psetkeyparm
= kzalloc(sizeof(struct setkey_parm
), GFP_KERNEL
);
1626 if (psetkeyparm
== NULL
) {
1631 memset(psetkeyparm
, 0, sizeof(struct setkey_parm
));
1633 if (psecuritypriv
->dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
) {
1634 psetkeyparm
->algorithm
= (unsigned char)psecuritypriv
->dot118021XGrpPrivacy
;
1635 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1636 ("\n rtw_set_key: psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy=%d\n",
1637 psetkeyparm
->algorithm
));
1639 psetkeyparm
->algorithm
= (u8
)psecuritypriv
->dot11PrivacyAlgrthm
;
1640 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1641 ("\n rtw_set_key: psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm=%d\n",
1642 psetkeyparm
->algorithm
));
1644 psetkeyparm
->keyid
= (u8
)keyid
;/* 0~3 */
1645 psetkeyparm
->set_tx
= set_tx
;
1646 pmlmepriv
->key_mask
|= BIT(psetkeyparm
->keyid
);
1647 DBG_88E("==> rtw_set_key algorithm(%x), keyid(%x), key_mask(%x)\n",
1648 psetkeyparm
->algorithm
, psetkeyparm
->keyid
, pmlmepriv
->key_mask
);
1649 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1650 ("\n rtw_set_key: psetkeyparm->algorithm=%d psetkeyparm->keyid=(u8)keyid=%d\n",
1651 psetkeyparm
->algorithm
, keyid
));
1653 switch (psetkeyparm
->algorithm
) {
1656 memcpy(&(psetkeyparm
->key
[0]), &(psecuritypriv
->dot11DefKey
[keyid
].skey
[0]), keylen
);
1660 memcpy(&(psetkeyparm
->key
[0]), &(psecuritypriv
->dot11DefKey
[keyid
].skey
[0]), keylen
);
1664 memcpy(&psetkeyparm
->key
, &psecuritypriv
->dot118021XGrpKey
[keyid
], keylen
);
1665 psetkeyparm
->grpkey
= 1;
1669 memcpy(&psetkeyparm
->key
, &psecuritypriv
->dot118021XGrpKey
[keyid
], keylen
);
1670 psetkeyparm
->grpkey
= 1;
1673 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1674 ("\n rtw_set_key:psecuritypriv->dot11PrivacyAlgrthm=%x (must be 1 or 2 or 4 or 5)\n",
1675 psecuritypriv
->dot11PrivacyAlgrthm
));
1679 pcmd
->cmdcode
= _SetKey_CMD_
;
1680 pcmd
->parmbuf
= (u8
*)psetkeyparm
;
1681 pcmd
->cmdsz
= (sizeof(struct setkey_parm
));
1684 INIT_LIST_HEAD(&pcmd
->list
);
1685 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
1695 /* adjust IEs for rtw_joinbss_cmd in WMM */
1696 int rtw_restruct_wmm_ie(struct adapter
*adapter
, u8
*in_ie
, u8
*out_ie
, uint in_len
, uint initial_out_len
)
1698 unsigned int ielength
= 0;
1701 i
= 12; /* after the fixed IE */
1702 while (i
< in_len
) {
1703 ielength
= initial_out_len
;
1705 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
) {
1706 /* WMM element ID and OUI */
1707 /* Append WMM IE to the last index of out_ie */
1709 for (j
= i
; j
< i
+ 9; j
++) {
1710 out_ie
[ielength
] = in_ie
[j
];
1713 out_ie
[initial_out_len
+ 1] = 0x07;
1714 out_ie
[initial_out_len
+ 6] = 0x00;
1715 out_ie
[initial_out_len
+ 8] = 0x00;
1718 i
+= (in_ie
[i
+1]+2); /* to the next IE element */
1724 * Ported from 8185: IsInPreAuthKeyList().
1725 * (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.)
1726 * Added by Annie, 2006-05-07.
1729 * -1 :if there is no pre-auth key in the table
1730 * >= 0 :if there is pre-auth key, and return the entry id
1732 static int SecIsInPMKIDList(struct adapter
*Adapter
, u8
*bssid
)
1734 struct security_priv
*psecuritypriv
= &Adapter
->securitypriv
;
1738 if ((psecuritypriv
->PMKIDList
[i
].bUsed
) &&
1739 (!memcmp(psecuritypriv
->PMKIDList
[i
].Bssid
, bssid
, ETH_ALEN
))) {
1746 } while (i
< NUM_PMKID_CACHE
);
1748 if (i
== NUM_PMKID_CACHE
)
1749 i
= -1;/* Could not find. */
1755 /* Check the RSN IE length */
1756 /* If the RSN IE length <= 20, the RSN IE didn't include the PMKID information */
1757 /* 0-11th element in the array are the fixed IE */
1758 /* 12th element in the array is the IE */
1759 /* 13th element in the array is the IE length */
1762 static int rtw_append_pmkid(struct adapter
*Adapter
, int iEntry
, u8
*ie
, uint ie_len
)
1764 struct security_priv
*psecuritypriv
= &Adapter
->securitypriv
;
1767 /* The RSN IE didn't include the PMK ID, append the PMK information */
1770 ie
[ie_len
] = 0; /* PMKID count = 0x0100 */
1772 memcpy(&ie
[ie_len
], &psecuritypriv
->PMKIDList
[iEntry
].PMKID
, 16);
1775 ie
[13] += 18;/* PMKID length = 2+16 */
1780 int rtw_restruct_sec_ie(struct adapter
*adapter
, u8
*in_ie
, u8
*out_ie
, uint in_len
)
1786 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1787 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
1788 uint ndisauthmode
= psecuritypriv
->ndisauthtype
;
1789 uint ndissecuritytype
= psecuritypriv
->ndisencryptstatus
;
1791 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
1792 ("+rtw_restruct_sec_ie: ndisauthmode=%d ndissecuritytype=%d\n",
1793 ndisauthmode
, ndissecuritytype
));
1795 /* copy fixed ie only */
1796 memcpy(out_ie
, in_ie
, 12);
1798 if ((ndisauthmode
== Ndis802_11AuthModeWPA
) ||
1799 (ndisauthmode
== Ndis802_11AuthModeWPAPSK
))
1800 authmode
= _WPA_IE_ID_
;
1801 if ((ndisauthmode
== Ndis802_11AuthModeWPA2
) ||
1802 (ndisauthmode
== Ndis802_11AuthModeWPA2PSK
))
1803 authmode
= _WPA2_IE_ID_
;
1805 if (check_fwstate(pmlmepriv
, WIFI_UNDER_WPS
)) {
1806 memcpy(out_ie
+ielength
, psecuritypriv
->wps_ie
, psecuritypriv
->wps_ie_len
);
1808 ielength
+= psecuritypriv
->wps_ie_len
;
1809 } else if ((authmode
== _WPA_IE_ID_
) || (authmode
== _WPA2_IE_ID_
)) {
1810 /* copy RSN or SSN */
1811 memcpy(&out_ie
[ielength
], &psecuritypriv
->supplicant_ie
[0], psecuritypriv
->supplicant_ie
[1]+2);
1812 ielength
+= psecuritypriv
->supplicant_ie
[1]+2;
1813 rtw_report_sec_ie(adapter
, authmode
, psecuritypriv
->supplicant_ie
);
1816 iEntry
= SecIsInPMKIDList(adapter
, pmlmepriv
->assoc_bssid
);
1820 if (authmode
== _WPA2_IE_ID_
)
1821 ielength
= rtw_append_pmkid(adapter
, iEntry
, out_ie
, ielength
);
1826 void rtw_init_registrypriv_dev_network(struct adapter
*adapter
)
1828 struct registry_priv
*pregistrypriv
= &adapter
->registrypriv
;
1829 struct eeprom_priv
*peepriv
= &adapter
->eeprompriv
;
1830 struct wlan_bssid_ex
*pdev_network
= &pregistrypriv
->dev_network
;
1831 u8
*myhwaddr
= myid(peepriv
);
1833 memcpy(pdev_network
->MacAddress
, myhwaddr
, ETH_ALEN
);
1835 memcpy(&pdev_network
->Ssid
, &pregistrypriv
->ssid
, sizeof(struct ndis_802_11_ssid
));
1837 pdev_network
->Configuration
.Length
= sizeof(struct ndis_802_11_config
);
1838 pdev_network
->Configuration
.BeaconPeriod
= 100;
1839 pdev_network
->Configuration
.FHConfig
.Length
= 0;
1840 pdev_network
->Configuration
.FHConfig
.HopPattern
= 0;
1841 pdev_network
->Configuration
.FHConfig
.HopSet
= 0;
1842 pdev_network
->Configuration
.FHConfig
.DwellTime
= 0;
1845 void rtw_update_registrypriv_dev_network(struct adapter
*adapter
)
1848 struct registry_priv
*pregistrypriv
= &adapter
->registrypriv
;
1849 struct wlan_bssid_ex
*pdev_network
= &pregistrypriv
->dev_network
;
1850 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
1851 struct wlan_network
*cur_network
= &adapter
->mlmepriv
.cur_network
;
1853 pdev_network
->Privacy
= (psecuritypriv
->dot11PrivacyAlgrthm
> 0 ? 1 : 0); /* adhoc no 802.1x */
1855 pdev_network
->Rssi
= 0;
1857 switch (pregistrypriv
->wireless_mode
) {
1859 pdev_network
->NetworkTypeInUse
= (Ndis802_11DS
);
1863 case WIRELESS_11_24N
:
1864 case WIRELESS_11G_24N
:
1865 case WIRELESS_11BG_24N
:
1866 pdev_network
->NetworkTypeInUse
= (Ndis802_11OFDM24
);
1869 case WIRELESS_11A_5N
:
1870 pdev_network
->NetworkTypeInUse
= (Ndis802_11OFDM5
);
1872 case WIRELESS_11ABGN
:
1873 if (pregistrypriv
->channel
> 14)
1874 pdev_network
->NetworkTypeInUse
= (Ndis802_11OFDM5
);
1876 pdev_network
->NetworkTypeInUse
= (Ndis802_11OFDM24
);
1883 pdev_network
->Configuration
.DSConfig
= (pregistrypriv
->channel
);
1884 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
1885 ("pregistrypriv->channel=%d, pdev_network->Configuration.DSConfig=0x%x\n",
1886 pregistrypriv
->channel
, pdev_network
->Configuration
.DSConfig
));
1888 if (cur_network
->network
.InfrastructureMode
== Ndis802_11IBSS
)
1889 pdev_network
->Configuration
.ATIMWindow
= (0);
1891 pdev_network
->InfrastructureMode
= (cur_network
->network
.InfrastructureMode
);
1893 /* 1. Supported rates */
1896 sz
= rtw_generate_ie(pregistrypriv
);
1897 pdev_network
->IELength
= sz
;
1898 pdev_network
->Length
= get_wlan_bssid_ex_sz((struct wlan_bssid_ex
*)pdev_network
);
1900 /* notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); */
1901 /* pdev_network->IELength = cpu_to_le32(sz); */
1904 void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter
*adapter
)
1908 /* the function is at passive_level */
1909 void rtw_joinbss_reset(struct adapter
*padapter
)
1912 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1913 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
1915 /* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */
1916 pmlmepriv
->num_FortyMHzIntolerant
= 0;
1918 pmlmepriv
->num_sta_no_ht
= 0;
1920 phtpriv
->ampdu_enable
= false;/* reset to disabled */
1922 /* TH = 1 => means that invalidate usb rx aggregation */
1923 /* TH = 0 => means that validate usb rx aggregation, use init value. */
1924 if (phtpriv
->ht_option
) {
1925 if (padapter
->registrypriv
.wifi_spec
== 1)
1929 rtw_hal_set_hwreg(padapter
, HW_VAR_RXDMA_AGG_PG_TH
, (u8
*)(&threshold
));
1932 rtw_hal_set_hwreg(padapter
, HW_VAR_RXDMA_AGG_PG_TH
, (u8
*)(&threshold
));
1936 /* the function is >= passive_level */
1937 unsigned int rtw_restructure_ht_ie(struct adapter
*padapter
, u8
*in_ie
, u8
*out_ie
, uint in_len
, uint
*pout_len
)
1940 enum ht_cap_ampdu_factor max_rx_ampdu_factor
;
1942 struct rtw_ieee80211_ht_cap ht_capie
;
1943 unsigned char WMM_IE
[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
1944 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1945 struct qos_priv
*pqospriv
= &pmlmepriv
->qospriv
;
1946 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
1947 u32 rx_packet_offset
, max_recvbuf_sz
;
1950 phtpriv
->ht_option
= false;
1952 p
= rtw_get_ie(in_ie
+12, _HT_CAPABILITY_IE_
, &ielen
, in_len
-12);
1954 if (p
&& ielen
> 0) {
1955 if (pqospriv
->qos_option
== 0) {
1956 out_len
= *pout_len
;
1957 rtw_set_ie(out_ie
+out_len
, _VENDOR_SPECIFIC_IE_
,
1958 _WMM_IE_Length_
, WMM_IE
, pout_len
);
1960 pqospriv
->qos_option
= 1;
1963 out_len
= *pout_len
;
1965 memset(&ht_capie
, 0, sizeof(struct rtw_ieee80211_ht_cap
));
1967 ht_capie
.cap_info
= IEEE80211_HT_CAP_SUP_WIDTH
|
1968 IEEE80211_HT_CAP_SGI_20
|
1969 IEEE80211_HT_CAP_SGI_40
|
1970 IEEE80211_HT_CAP_TX_STBC
|
1971 IEEE80211_HT_CAP_DSSSCCK40
;
1973 rtw_hal_get_def_var(padapter
, HAL_DEF_RX_PACKET_OFFSET
, &rx_packet_offset
);
1974 rtw_hal_get_def_var(padapter
, HAL_DEF_MAX_RECVBUF_SZ
, &max_recvbuf_sz
);
1977 AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
1978 AMPDU_para [4:2]:Min MPDU Start Spacing
1981 rtw_hal_get_def_var(padapter
, HW_VAR_MAX_RX_AMPDU_FACTOR
, &max_rx_ampdu_factor
);
1982 ht_capie
.ampdu_params_info
= (max_rx_ampdu_factor
&0x03);
1984 if (padapter
->securitypriv
.dot11PrivacyAlgrthm
== _AES_
)
1985 ht_capie
.ampdu_params_info
|= (IEEE80211_HT_CAP_AMPDU_DENSITY
&(0x07<<2));
1987 ht_capie
.ampdu_params_info
|= (IEEE80211_HT_CAP_AMPDU_DENSITY
&0x00);
1990 rtw_set_ie(out_ie
+out_len
, _HT_CAPABILITY_IE_
,
1991 sizeof(struct rtw_ieee80211_ht_cap
), (unsigned char *)&ht_capie
, pout_len
);
1993 phtpriv
->ht_option
= true;
1995 p
= rtw_get_ie(in_ie
+12, _HT_ADD_INFO_IE_
, &ielen
, in_len
-12);
1996 if (p
&& (ielen
== sizeof(struct ieee80211_ht_addt_info
))) {
1997 out_len
= *pout_len
;
1998 rtw_set_ie(out_ie
+out_len
, _HT_ADD_INFO_IE_
, ielen
, p
+2 , pout_len
);
2001 return phtpriv
->ht_option
;
2004 /* the function is > passive_level (in critical_section) */
2005 void rtw_update_ht_cap(struct adapter
*padapter
, u8
*pie
, uint ie_len
)
2007 u8
*p
, max_ampdu_sz
;
2009 struct rtw_ieee80211_ht_cap
*pht_capie
;
2010 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2011 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
2012 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
2013 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2014 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2016 if (!phtpriv
->ht_option
)
2019 if ((!pmlmeinfo
->HT_info_enable
) || (!pmlmeinfo
->HT_caps_enable
))
2022 DBG_88E("+rtw_update_ht_cap()\n");
2024 /* maybe needs check if ap supports rx ampdu. */
2025 if ((!phtpriv
->ampdu_enable
) && (pregistrypriv
->ampdu_enable
== 1)) {
2026 if (pregistrypriv
->wifi_spec
== 1)
2027 phtpriv
->ampdu_enable
= false;
2029 phtpriv
->ampdu_enable
= true;
2030 } else if (pregistrypriv
->ampdu_enable
== 2) {
2031 phtpriv
->ampdu_enable
= true;
2035 /* check Max Rx A-MPDU Size */
2037 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
));
2039 pht_capie
= (struct rtw_ieee80211_ht_cap
*)(p
+2);
2040 max_ampdu_sz
= (pht_capie
->ampdu_params_info
& IEEE80211_HT_CAP_AMPDU_FACTOR
);
2041 max_ampdu_sz
= 1 << (max_ampdu_sz
+3); /* max_ampdu_sz (kbytes); */
2042 phtpriv
->rx_ampdu_maxlen
= max_ampdu_sz
;
2045 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
));
2047 /* update cur_bwmode & cur_ch_offset */
2048 if ((pregistrypriv
->cbw40_enable
) &&
2049 (le16_to_cpu(pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
) & BIT(1)) &&
2050 (pmlmeinfo
->HT_info
.infos
[0] & BIT(2))) {
2054 padapter
->HalFunc
.GetHwRegHandler(padapter
, HW_VAR_RF_TYPE
, (u8
*)(&rf_type
));
2056 /* update the MCS rates */
2057 for (i
= 0; i
< 16; i
++) {
2058 if ((rf_type
== RF_1T1R
) || (rf_type
== RF_1T2R
))
2059 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.MCS_rate
[i
] &= MCS_rate_1R
[i
];
2061 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.MCS_rate
[i
] &= MCS_rate_2R
[i
];
2063 /* switch to the 40M Hz mode according to the AP */
2064 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_40
;
2065 switch ((pmlmeinfo
->HT_info
.infos
[0] & 0x3)) {
2066 case HT_EXTCHNL_OFFSET_UPPER
:
2067 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_LOWER
;
2069 case HT_EXTCHNL_OFFSET_LOWER
:
2070 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_UPPER
;
2073 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
2078 /* Config SM Power Save setting */
2079 pmlmeinfo
->SM_PS
= (le16_to_cpu(pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
) & 0x0C) >> 2;
2080 if (pmlmeinfo
->SM_PS
== WLAN_HT_CAP_SM_PS_STATIC
)
2081 DBG_88E("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__
);
2083 /* Config current HT Protection mode. */
2084 pmlmeinfo
->HT_protection
= pmlmeinfo
->HT_info
.infos
[1] & 0x3;
2087 void rtw_issue_addbareq_cmd(struct adapter
*padapter
, struct xmit_frame
*pxmitframe
)
2091 struct sta_info
*psta
= NULL
;
2092 struct ht_priv
*phtpriv
;
2093 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
2094 s32 bmcst
= IS_MCAST(pattrib
->ra
);
2096 if (bmcst
|| (padapter
->mlmepriv
.LinkDetectInfo
.NumTxOkInPeriod
< 100))
2099 priority
= pattrib
->priority
;
2102 psta
= pattrib
->psta
;
2104 psta
= rtw_get_stainfo(&padapter
->stapriv
, pattrib
->ra
);
2109 phtpriv
= &psta
->htpriv
;
2111 if ((phtpriv
->ht_option
) && (phtpriv
->ampdu_enable
)) {
2112 issued
= (phtpriv
->agg_enable_bitmap
>>priority
)&0x1;
2113 issued
|= (phtpriv
->candidate_tid_bitmap
>>priority
)&0x1;
2116 DBG_88E("rtw_issue_addbareq_cmd, p=%d\n", priority
);
2117 psta
->htpriv
.candidate_tid_bitmap
|= BIT((u8
)priority
);
2118 rtw_addbareq_cmd(padapter
, (u8
)priority
, pattrib
->ra
);
2123 void rtw_roaming(struct adapter
*padapter
, struct wlan_network
*tgt_network
)
2125 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2127 spin_lock_bh(&pmlmepriv
->lock
);
2128 _rtw_roaming(padapter
, tgt_network
);
2129 spin_unlock_bh(&pmlmepriv
->lock
);
2131 void _rtw_roaming(struct adapter
*padapter
, struct wlan_network
*tgt_network
)
2133 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2136 struct wlan_network
*pnetwork
;
2138 if (tgt_network
!= NULL
)
2139 pnetwork
= tgt_network
;
2141 pnetwork
= &pmlmepriv
->cur_network
;
2143 if (0 < pmlmepriv
->to_roaming
) {
2144 DBG_88E("roaming from %s(%pM length:%d\n",
2145 pnetwork
->network
.Ssid
.Ssid
, pnetwork
->network
.MacAddress
,
2146 pnetwork
->network
.Ssid
.SsidLength
);
2147 memcpy(&pmlmepriv
->assoc_ssid
, &pnetwork
->network
.Ssid
, sizeof(struct ndis_802_11_ssid
));
2149 pmlmepriv
->assoc_by_bssid
= false;
2152 do_join_r
= rtw_do_join(padapter
);
2153 if (_SUCCESS
== do_join_r
) {
2156 DBG_88E("roaming do_join return %d\n", do_join_r
);
2157 pmlmepriv
->to_roaming
--;
2159 if (0 < pmlmepriv
->to_roaming
) {
2162 DBG_88E("%s(%d) -to roaming fail, indicate_disconnect\n", __func__
, __LINE__
);
2163 rtw_indicate_disconnect(padapter
);