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 ******************************************************************************/
17 #include <linux/ieee80211.h>
19 #include <osdep_service.h>
20 #include <drv_types.h>
21 #include <recv_osdep.h>
22 #include <xmit_osdep.h>
24 #include <mlme_osdep.h>
27 #include <wlan_bssdef.h>
28 #include <rtw_ioctl_set.h>
29 #include <linux/vmalloc.h>
31 extern unsigned char MCS_rate_2R
[16];
32 extern unsigned char MCS_rate_1R
[16];
34 int rtw_init_mlme_priv(struct adapter
*padapter
)
38 struct wlan_network
*pnetwork
;
39 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
42 /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */
44 pmlmepriv
->nic_hdl
= (u8
*)padapter
;
46 pmlmepriv
->pscanned
= NULL
;
47 pmlmepriv
->fw_state
= 0;
48 pmlmepriv
->cur_network
.network
.InfrastructureMode
= Ndis802_11AutoUnknown
;
49 pmlmepriv
->scan_mode
= SCAN_ACTIVE
;/* 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) */
51 spin_lock_init(&(pmlmepriv
->lock
));
52 _rtw_init_queue(&(pmlmepriv
->free_bss_pool
));
53 _rtw_init_queue(&(pmlmepriv
->scanned_queue
));
55 set_scanned_network_val(pmlmepriv
, 0);
57 memset(&pmlmepriv
->assoc_ssid
, 0, sizeof(struct ndis_802_11_ssid
));
59 pbuf
= vzalloc(MAX_BSS_CNT
* (sizeof(struct wlan_network
)));
65 pmlmepriv
->free_bss_buf
= pbuf
;
67 pnetwork
= (struct wlan_network
*)pbuf
;
69 for (i
= 0; i
< MAX_BSS_CNT
; i
++) {
70 INIT_LIST_HEAD(&(pnetwork
->list
));
72 list_add_tail(&(pnetwork
->list
), &(pmlmepriv
->free_bss_pool
.queue
));
77 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
79 rtw_clear_scan_deny(padapter
);
81 rtw_init_mlme_timer(padapter
);
87 #if defined(CONFIG_88EU_AP_MODE)
88 static void rtw_free_mlme_ie_data(u8
**ppie
, u32
*plen
)
95 void rtw_free_mlme_priv_ie_data(struct mlme_priv
*pmlmepriv
)
97 rtw_buf_free(&pmlmepriv
->assoc_req
, &pmlmepriv
->assoc_req_len
);
98 rtw_buf_free(&pmlmepriv
->assoc_rsp
, &pmlmepriv
->assoc_rsp_len
);
99 rtw_free_mlme_ie_data(&pmlmepriv
->wps_beacon_ie
, &pmlmepriv
->wps_beacon_ie_len
);
100 rtw_free_mlme_ie_data(&pmlmepriv
->wps_probe_req_ie
, &pmlmepriv
->wps_probe_req_ie_len
);
101 rtw_free_mlme_ie_data(&pmlmepriv
->wps_probe_resp_ie
, &pmlmepriv
->wps_probe_resp_ie_len
);
102 rtw_free_mlme_ie_data(&pmlmepriv
->wps_assoc_resp_ie
, &pmlmepriv
->wps_assoc_resp_ie_len
);
104 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_beacon_ie
, &pmlmepriv
->p2p_beacon_ie_len
);
105 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_probe_req_ie
, &pmlmepriv
->p2p_probe_req_ie_len
);
106 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_probe_resp_ie
, &pmlmepriv
->p2p_probe_resp_ie_len
);
107 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_go_probe_resp_ie
, &pmlmepriv
->p2p_go_probe_resp_ie_len
);
108 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_assoc_req_ie
, &pmlmepriv
->p2p_assoc_req_ie_len
);
111 void rtw_free_mlme_priv_ie_data(struct mlme_priv
*pmlmepriv
)
116 void rtw_free_mlme_priv(struct mlme_priv
*pmlmepriv
)
118 rtw_free_mlme_priv_ie_data(pmlmepriv
);
121 vfree(pmlmepriv
->free_bss_buf
);
124 struct wlan_network
*_rtw_alloc_network(struct mlme_priv
*pmlmepriv
)
125 /* _queue *free_queue) */
127 struct wlan_network
*pnetwork
;
128 struct __queue
*free_queue
= &pmlmepriv
->free_bss_pool
;
130 spin_lock_bh(&free_queue
->lock
);
131 pnetwork
= list_first_entry_or_null(&free_queue
->queue
,
132 struct wlan_network
, list
);
136 list_del_init(&pnetwork
->list
);
138 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
139 ("_rtw_alloc_network: ptr=%p\n", &pnetwork
->list
));
140 pnetwork
->network_type
= 0;
141 pnetwork
->fixed
= false;
142 pnetwork
->last_scanned
= jiffies
;
144 pnetwork
->join_res
= 0;
146 pmlmepriv
->num_of_scanned
++;
149 spin_unlock_bh(&free_queue
->lock
);
154 static void _rtw_free_network(struct mlme_priv
*pmlmepriv
, struct wlan_network
*pnetwork
, u8 isfreeall
)
156 unsigned long curr_time
;
158 u32 lifetime
= SCANQUEUE_LIFETIME
;
159 struct __queue
*free_queue
= &(pmlmepriv
->free_bss_pool
);
161 if (pnetwork
== NULL
)
167 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) ||
168 (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)))
171 delta_time
= (curr_time
- pnetwork
->last_scanned
)/HZ
;
172 if (delta_time
< lifetime
)/* unit:sec */
175 spin_lock_bh(&free_queue
->lock
);
176 list_del_init(&(pnetwork
->list
));
177 list_add_tail(&(pnetwork
->list
), &(free_queue
->queue
));
178 pmlmepriv
->num_of_scanned
--;
179 spin_unlock_bh(&free_queue
->lock
);
182 void _rtw_free_network_nolock(struct mlme_priv
*pmlmepriv
, struct wlan_network
*pnetwork
)
184 struct __queue
*free_queue
= &(pmlmepriv
->free_bss_pool
);
186 if (pnetwork
== NULL
)
190 list_del_init(&(pnetwork
->list
));
191 list_add_tail(&(pnetwork
->list
), get_list_head(free_queue
));
192 pmlmepriv
->num_of_scanned
--;
196 return the wlan_network with the matching addr
198 Shall be calle under atomic context... to avoid possible racing condition...
200 struct wlan_network
*rtw_find_network(struct __queue
*scanned_queue
, u8
*addr
)
202 struct list_head
*phead
, *plist
;
203 struct wlan_network
*pnetwork
= NULL
;
204 u8 zero_addr
[ETH_ALEN
] = {0, 0, 0, 0, 0, 0};
206 if (!memcmp(zero_addr
, addr
, ETH_ALEN
)) {
210 phead
= get_list_head(scanned_queue
);
213 while (plist
!= phead
) {
214 pnetwork
= container_of(plist
, struct wlan_network
, list
);
215 if (!memcmp(addr
, pnetwork
->network
.MacAddress
, ETH_ALEN
))
226 void rtw_free_network_queue(struct adapter
*padapter
, u8 isfreeall
)
228 struct list_head
*phead
, *plist
;
229 struct wlan_network
*pnetwork
;
230 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
231 struct __queue
*scanned_queue
= &pmlmepriv
->scanned_queue
;
233 spin_lock_bh(&scanned_queue
->lock
);
235 phead
= get_list_head(scanned_queue
);
238 while (phead
!= plist
) {
239 pnetwork
= container_of(plist
, struct wlan_network
, list
);
243 _rtw_free_network(pmlmepriv
, pnetwork
, isfreeall
);
245 spin_unlock_bh(&scanned_queue
->lock
);
248 int rtw_if_up(struct adapter
*padapter
)
252 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
||
253 (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) == false)) {
254 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
255 ("rtw_if_up:bDriverStopped(%d) OR bSurpriseRemoved(%d)",
256 padapter
->bDriverStopped
, padapter
->bSurpriseRemoved
));
264 void rtw_generate_random_ibss(u8
*pibss
)
266 unsigned long curtime
= jiffies
;
268 pibss
[0] = 0x02; /* in ad-hoc mode bit1 must set to 1 */
271 pibss
[3] = (u8
)(curtime
& 0xff);/* p[0]; */
272 pibss
[4] = (u8
)((curtime
>>8) & 0xff);/* p[1]; */
273 pibss
[5] = (u8
)((curtime
>>16) & 0xff);/* p[2]; */
277 u8
*rtw_get_capability_from_ie(u8
*ie
)
283 u16
rtw_get_capability(struct wlan_bssid_ex
*bss
)
287 memcpy((u8
*)&val
, rtw_get_capability_from_ie(bss
->IEs
), 2);
289 return le16_to_cpu(val
);
292 u8
*rtw_get_beacon_interval_from_ie(u8
*ie
)
297 static struct wlan_network
*rtw_alloc_network(struct mlme_priv
*pmlmepriv
)
299 return _rtw_alloc_network(pmlmepriv
);
302 static void rtw_free_network_nolock(struct mlme_priv
*pmlmepriv
,
303 struct wlan_network
*pnetwork
)
305 _rtw_free_network_nolock(pmlmepriv
, pnetwork
);
308 int rtw_is_same_ibss(struct adapter
*adapter
, struct wlan_network
*pnetwork
)
311 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
313 if ((psecuritypriv
->dot11PrivacyAlgrthm
!= _NO_PRIVACY_
) &&
314 (pnetwork
->network
.Privacy
== 0))
316 else if ((psecuritypriv
->dot11PrivacyAlgrthm
== _NO_PRIVACY_
) &&
317 (pnetwork
->network
.Privacy
== 1))
324 static int is_same_ess(struct wlan_bssid_ex
*a
, struct wlan_bssid_ex
*b
)
326 return (a
->Ssid
.SsidLength
== b
->Ssid
.SsidLength
) &&
327 !memcmp(a
->Ssid
.Ssid
, b
->Ssid
.Ssid
, a
->Ssid
.SsidLength
);
330 int is_same_network(struct wlan_bssid_ex
*src
, struct wlan_bssid_ex
*dst
)
333 __le16 le_scap
, le_dcap
;
335 memcpy((u8
*)&le_scap
, rtw_get_capability_from_ie(src
->IEs
), 2);
336 memcpy((u8
*)&le_dcap
, rtw_get_capability_from_ie(dst
->IEs
), 2);
339 s_cap
= le16_to_cpu(le_scap
);
340 d_cap
= le16_to_cpu(le_dcap
);
342 return ((src
->Ssid
.SsidLength
== dst
->Ssid
.SsidLength
) &&
343 ((!memcmp(src
->MacAddress
, dst
->MacAddress
, ETH_ALEN
)) == true) &&
344 ((!memcmp(src
->Ssid
.Ssid
, dst
->Ssid
.Ssid
, src
->Ssid
.SsidLength
)) == true) &&
345 ((s_cap
& WLAN_CAPABILITY_IBSS
) ==
346 (d_cap
& WLAN_CAPABILITY_IBSS
)) &&
347 ((s_cap
& WLAN_CAPABILITY_ESS
) ==
348 (d_cap
& WLAN_CAPABILITY_ESS
)));
351 struct wlan_network
*rtw_get_oldest_wlan_network(struct __queue
*scanned_queue
)
353 struct list_head
*plist
, *phead
;
354 struct wlan_network
*pwlan
= NULL
;
355 struct wlan_network
*oldest
= NULL
;
357 phead
= get_list_head(scanned_queue
);
359 for (plist
= phead
->next
; plist
!= phead
; plist
= plist
->next
) {
360 pwlan
= container_of(plist
, struct wlan_network
, list
);
363 if (oldest
== NULL
|| time_after(oldest
->last_scanned
, pwlan
->last_scanned
))
370 void update_network(struct wlan_bssid_ex
*dst
, struct wlan_bssid_ex
*src
,
371 struct adapter
*padapter
, bool update_ie
)
373 long rssi_ori
= dst
->Rssi
;
374 u8 sq_smp
= src
->PhyInfo
.SignalQuality
;
379 rtw_hal_antdiv_rssi_compared(padapter
, dst
, src
); /* this will update src.Rssi, need consider again */
381 /* The rule below is 1/5 for sample value, 4/5 for history value */
382 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) && is_same_network(&(padapter
->mlmepriv
.cur_network
.network
), src
)) {
383 /* Take the recvpriv's value for the connected AP*/
384 ss_final
= padapter
->recvpriv
.signal_strength
;
385 sq_final
= padapter
->recvpriv
.signal_qual
;
386 /* the rssi value here is undecorated, and will be used for antenna diversity */
387 if (sq_smp
!= 101) /* from the right channel */
388 rssi_final
= (src
->Rssi
+dst
->Rssi
*4)/5;
390 rssi_final
= rssi_ori
;
392 if (sq_smp
!= 101) { /* from the right channel */
393 ss_final
= ((u32
)(src
->PhyInfo
.SignalStrength
)+(u32
)(dst
->PhyInfo
.SignalStrength
)*4)/5;
394 sq_final
= ((u32
)(src
->PhyInfo
.SignalQuality
)+(u32
)(dst
->PhyInfo
.SignalQuality
)*4)/5;
395 rssi_final
= (src
->Rssi
+dst
->Rssi
*4)/5;
397 /* bss info not receiving from the right channel, use the original RX signal infos */
398 ss_final
= dst
->PhyInfo
.SignalStrength
;
399 sq_final
= dst
->PhyInfo
.SignalQuality
;
400 rssi_final
= dst
->Rssi
;
404 memcpy((u8
*)dst
, (u8
*)src
, get_wlan_bssid_ex_sz(src
));
405 dst
->PhyInfo
.SignalStrength
= ss_final
;
406 dst
->PhyInfo
.SignalQuality
= sq_final
;
407 dst
->Rssi
= rssi_final
;
411 static void update_current_network(struct adapter
*adapter
, struct wlan_bssid_ex
*pnetwork
)
413 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
415 if ((check_fwstate(pmlmepriv
, _FW_LINKED
) == true) &&
416 (is_same_network(&(pmlmepriv
->cur_network
.network
), pnetwork
))) {
417 update_network(&(pmlmepriv
->cur_network
.network
), pnetwork
, adapter
, true);
418 rtw_update_protection(adapter
, (pmlmepriv
->cur_network
.network
.IEs
) + sizeof(struct ndis_802_11_fixed_ie
),
419 pmlmepriv
->cur_network
.network
.IELength
);
424 Caller must hold pmlmepriv->lock first.
426 void rtw_update_scanned_network(struct adapter
*adapter
, struct wlan_bssid_ex
*target
)
428 struct list_head
*plist
, *phead
;
430 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
431 struct __queue
*queue
= &(pmlmepriv
->scanned_queue
);
432 struct wlan_network
*pnetwork
= NULL
;
433 struct wlan_network
*oldest
= NULL
;
435 spin_lock_bh(&queue
->lock
);
436 phead
= get_list_head(queue
);
439 while (phead
!= plist
) {
440 pnetwork
= container_of(plist
, struct wlan_network
, list
);
442 if (is_same_network(&(pnetwork
->network
), target
))
444 if ((oldest
== ((struct wlan_network
*)0)) ||
445 time_after(oldest
->last_scanned
, pnetwork
->last_scanned
))
449 /* If we didn't find a match, then get a new network slot to initialize
450 * with this beacon's information */
451 if (phead
== plist
) {
452 if (list_empty(&(pmlmepriv
->free_bss_pool
.queue
))) {
453 /* If there are no more slots, expire the oldest */
456 rtw_hal_get_def_var(adapter
, HAL_DEF_CURRENT_ANTENNA
, &(target
->PhyInfo
.Optimum_antenna
));
457 memcpy(&(pnetwork
->network
), target
, get_wlan_bssid_ex_sz(target
));
458 /* variable initialize */
459 pnetwork
->fixed
= false;
460 pnetwork
->last_scanned
= jiffies
;
462 pnetwork
->network_type
= 0;
464 pnetwork
->join_res
= 0;
466 /* bss info not receiving from the right channel */
467 if (pnetwork
->network
.PhyInfo
.SignalQuality
== 101)
468 pnetwork
->network
.PhyInfo
.SignalQuality
= 0;
470 /* Otherwise just pull from the free list */
472 pnetwork
= rtw_alloc_network(pmlmepriv
); /* will update scan_time */
474 if (pnetwork
== NULL
) {
475 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("\n\n\nsomething wrong here\n\n\n"));
479 bssid_ex_sz
= get_wlan_bssid_ex_sz(target
);
480 target
->Length
= bssid_ex_sz
;
481 rtw_hal_get_def_var(adapter
, HAL_DEF_CURRENT_ANTENNA
, &(target
->PhyInfo
.Optimum_antenna
));
482 memcpy(&(pnetwork
->network
), target
, bssid_ex_sz
);
484 pnetwork
->last_scanned
= jiffies
;
486 /* bss info not receiving from the right channel */
487 if (pnetwork
->network
.PhyInfo
.SignalQuality
== 101)
488 pnetwork
->network
.PhyInfo
.SignalQuality
= 0;
489 list_add_tail(&(pnetwork
->list
), &(queue
->queue
));
492 /* we have an entry and we are going to update it. But this entry may
493 * be already expired. In this case we do the same as we found a new
494 * net and call the new_net handler
496 bool update_ie
= true;
498 pnetwork
->last_scanned
= jiffies
;
500 /* target.Reserved[0]== 1, means that scanned network is a bcn frame. */
501 if ((pnetwork
->network
.IELength
> target
->IELength
) && (target
->Reserved
[0] == 1))
504 update_network(&(pnetwork
->network
), target
, adapter
, update_ie
);
508 spin_unlock_bh(&queue
->lock
);
512 static void rtw_add_network(struct adapter
*adapter
,
513 struct wlan_bssid_ex
*pnetwork
)
515 update_current_network(adapter
, pnetwork
);
516 rtw_update_scanned_network(adapter
, pnetwork
);
520 * select the desired network based on the capability of the (i)bss.
521 * check items: (1) security
527 static int rtw_is_desired_network(struct adapter
*adapter
, struct wlan_network
*pnetwork
)
529 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
530 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
534 /* u8 wps_ie[512]; */
537 int bselected
= true;
539 desired_encmode
= psecuritypriv
->ndisencryptstatus
;
540 privacy
= pnetwork
->network
.Privacy
;
542 if (check_fwstate(pmlmepriv
, WIFI_UNDER_WPS
)) {
543 if (rtw_get_wps_ie(pnetwork
->network
.IEs
+_FIXED_IE_LENGTH_
, pnetwork
->network
.IELength
-_FIXED_IE_LENGTH_
, NULL
, &wps_ielen
) != NULL
)
548 if (adapter
->registrypriv
.wifi_spec
== 1) { /* for correct flow of 8021X to do.... */
549 if ((desired_encmode
== Ndis802_11EncryptionDisabled
) && (privacy
!= 0))
554 if ((desired_encmode
!= Ndis802_11EncryptionDisabled
) && (privacy
== 0)) {
555 DBG_88E("desired_encmode: %d, privacy: %d\n", desired_encmode
, privacy
);
559 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) == true) {
560 if (pnetwork
->network
.InfrastructureMode
!= pmlmepriv
->cur_network
.network
.InfrastructureMode
)
568 /* TODO: Perry: For Power Management */
569 void rtw_atimdone_event_callback(struct adapter
*adapter
, u8
*pbuf
)
571 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("receive atimdone_evet\n"));
576 void rtw_survey_event_callback(struct adapter
*adapter
, u8
*pbuf
)
579 struct wlan_bssid_ex
*pnetwork
;
580 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
582 pnetwork
= (struct wlan_bssid_ex
*)pbuf
;
584 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_survey_event_callback, ssid=%s\n", pnetwork
->Ssid
.Ssid
));
586 len
= get_wlan_bssid_ex_sz(pnetwork
);
587 if (len
> (sizeof(struct wlan_bssid_ex
))) {
588 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("\n****rtw_survey_event_callback: return a wrong bss ***\n"));
591 spin_lock_bh(&pmlmepriv
->lock
);
593 /* update IBSS_network 's timestamp */
594 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) == true) {
595 if (!memcmp(&(pmlmepriv
->cur_network
.network
.MacAddress
), pnetwork
->MacAddress
, ETH_ALEN
)) {
596 struct wlan_network
*ibss_wlan
= NULL
;
598 memcpy(pmlmepriv
->cur_network
.network
.IEs
, pnetwork
->IEs
, 8);
599 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
600 ibss_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, pnetwork
->MacAddress
);
602 memcpy(ibss_wlan
->network
.IEs
, pnetwork
->IEs
, 8);
603 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
606 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
610 /* lock pmlmepriv->lock when you accessing network_q */
611 if ((check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
)) == false) {
612 if (pnetwork
->Ssid
.Ssid
[0] == 0)
613 pnetwork
->Ssid
.SsidLength
= 0;
614 rtw_add_network(adapter
, pnetwork
);
619 spin_unlock_bh(&pmlmepriv
->lock
);
623 void rtw_surveydone_event_callback(struct adapter
*adapter
, u8
*pbuf
)
625 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
627 spin_lock_bh(&pmlmepriv
->lock
);
629 if (pmlmepriv
->wps_probe_req_ie
) {
630 pmlmepriv
->wps_probe_req_ie_len
= 0;
631 kfree(pmlmepriv
->wps_probe_req_ie
);
632 pmlmepriv
->wps_probe_req_ie
= NULL
;
635 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_surveydone_event_callback: fw_state:%x\n\n", get_fwstate(pmlmepriv
)));
637 if (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
)) {
638 del_timer_sync(&pmlmepriv
->scan_to_timer
);
639 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
641 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("nic status=%x, survey done event comes too late!\n", get_fwstate(pmlmepriv
)));
644 rtw_set_signal_stat_timer(&adapter
->recvpriv
);
646 if (pmlmepriv
->to_join
) {
647 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) == true)) {
648 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == false) {
649 set_fwstate(pmlmepriv
, _FW_UNDER_LINKING
);
651 if (rtw_select_and_join_from_scanned_queue(pmlmepriv
) == _SUCCESS
) {
652 mod_timer(&pmlmepriv
->assoc_timer
,
653 jiffies
+ msecs_to_jiffies(MAX_JOIN_TIMEOUT
));
655 struct wlan_bssid_ex
*pdev_network
= &(adapter
->registrypriv
.dev_network
);
656 u8
*pibss
= adapter
->registrypriv
.dev_network
.MacAddress
;
658 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
660 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("switching to adhoc master\n"));
662 memcpy(&pdev_network
->Ssid
, &pmlmepriv
->assoc_ssid
, sizeof(struct ndis_802_11_ssid
));
664 rtw_update_registrypriv_dev_network(adapter
);
665 rtw_generate_random_ibss(pibss
);
667 pmlmepriv
->fw_state
= WIFI_ADHOC_MASTER_STATE
;
669 if (rtw_createbss_cmd(adapter
) != _SUCCESS
)
670 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Error=>rtw_createbss_cmd status FAIL\n"));
671 pmlmepriv
->to_join
= false;
676 set_fwstate(pmlmepriv
, _FW_UNDER_LINKING
);
677 pmlmepriv
->to_join
= false;
678 s_ret
= rtw_select_and_join_from_scanned_queue(pmlmepriv
);
679 if (_SUCCESS
== s_ret
) {
680 mod_timer(&pmlmepriv
->assoc_timer
,
681 jiffies
+ msecs_to_jiffies(MAX_JOIN_TIMEOUT
));
682 } else if (s_ret
== 2) { /* there is no need to wait for join */
683 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
684 rtw_indicate_connect(adapter
);
686 DBG_88E("try_to_join, but select scanning queue fail, to_roaming:%d\n", pmlmepriv
->to_roaming
);
687 if (pmlmepriv
->to_roaming
!= 0) {
688 if (--pmlmepriv
->to_roaming
== 0 ||
689 _SUCCESS
!= rtw_sitesurvey_cmd(adapter
, &pmlmepriv
->assoc_ssid
, 1, NULL
, 0)) {
690 pmlmepriv
->to_roaming
= 0;
691 rtw_free_assoc_resources(adapter
);
692 rtw_indicate_disconnect(adapter
);
694 pmlmepriv
->to_join
= true;
697 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
702 indicate_wx_scan_complete_event(adapter
);
704 spin_unlock_bh(&pmlmepriv
->lock
);
706 rtw_os_xmit_schedule(adapter
);
709 void rtw_dummy_event_callback(struct adapter
*adapter
, u8
*pbuf
)
713 void rtw_fwdbg_event_callback(struct adapter
*adapter
, u8
*pbuf
)
717 static void free_scanqueue(struct mlme_priv
*pmlmepriv
)
719 struct __queue
*free_queue
= &pmlmepriv
->free_bss_pool
;
720 struct __queue
*scan_queue
= &pmlmepriv
->scanned_queue
;
721 struct list_head
*plist
, *phead
, *ptemp
;
723 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
, ("+free_scanqueue\n"));
724 spin_lock_bh(&scan_queue
->lock
);
725 spin_lock_bh(&free_queue
->lock
);
727 phead
= get_list_head(scan_queue
);
730 while (plist
!= phead
) {
732 list_del_init(plist
);
733 list_add_tail(plist
, &free_queue
->queue
);
735 pmlmepriv
->num_of_scanned
--;
738 spin_unlock_bh(&free_queue
->lock
);
739 spin_unlock_bh(&scan_queue
->lock
);
743 *rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock
745 void rtw_free_assoc_resources(struct adapter
*adapter
)
747 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
749 spin_lock_bh(&pmlmepriv
->scanned_queue
.lock
);
750 rtw_free_assoc_resources_locked(adapter
);
751 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
755 *rtw_free_assoc_resources_locked: the caller has to lock pmlmepriv->lock
757 void rtw_free_assoc_resources_locked(struct adapter
*adapter
)
759 struct wlan_network
*pwlan
= NULL
;
760 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
761 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
762 struct wlan_network
*tgt_network
= &pmlmepriv
->cur_network
;
764 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
, ("+rtw_free_assoc_resources\n"));
765 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
766 ("tgt_network->network.MacAddress=%pM ssid=%s\n",
767 tgt_network
->network
.MacAddress
, tgt_network
->network
.Ssid
.Ssid
));
769 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
| WIFI_AP_STATE
)) {
770 struct sta_info
*psta
;
772 psta
= rtw_get_stainfo(&adapter
->stapriv
, tgt_network
->network
.MacAddress
);
774 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
775 rtw_free_stainfo(adapter
, psta
);
776 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
779 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
| WIFI_ADHOC_MASTER_STATE
| WIFI_AP_STATE
)) {
780 struct sta_info
*psta
;
782 rtw_free_all_stainfo(adapter
);
784 psta
= rtw_get_bcmc_stainfo(adapter
);
785 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
786 rtw_free_stainfo(adapter
, psta
);
787 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
789 rtw_init_bcmc_stainfo(adapter
);
793 pwlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, tgt_network
->network
.MacAddress
);
795 pwlan
->fixed
= false;
797 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("rtw_free_assoc_resources:pwlan==NULL\n\n"));
799 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) && (adapter
->stapriv
.asoc_sta_count
== 1)))
800 rtw_free_network_nolock(pmlmepriv
, pwlan
);
802 pmlmepriv
->key_mask
= 0;
806 *rtw_indicate_connect: the caller has to lock pmlmepriv->lock
808 void rtw_indicate_connect(struct adapter
*padapter
)
810 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
812 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("+rtw_indicate_connect\n"));
814 pmlmepriv
->to_join
= false;
816 if (!check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
)) {
817 set_fwstate(pmlmepriv
, _FW_LINKED
);
819 rtw_led_control(padapter
, LED_CTL_LINK
);
821 rtw_os_indicate_connect(padapter
);
824 pmlmepriv
->to_roaming
= 0;
826 rtw_set_scan_deny(padapter
, 3000);
828 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("-rtw_indicate_connect: fw_state=0x%08x\n", get_fwstate(pmlmepriv
)));
832 *rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock
834 void rtw_indicate_disconnect(struct adapter
*padapter
)
836 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
838 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("+rtw_indicate_disconnect\n"));
840 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
| WIFI_UNDER_WPS
);
843 if (pmlmepriv
->to_roaming
> 0)
844 _clr_fwstate_(pmlmepriv
, _FW_LINKED
);
846 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) ||
847 (pmlmepriv
->to_roaming
<= 0)) {
848 rtw_os_indicate_disconnect(padapter
);
850 _clr_fwstate_(pmlmepriv
, _FW_LINKED
);
851 rtw_led_control(padapter
, LED_CTL_NO_LINK
);
852 rtw_clear_scan_deny(padapter
);
855 rtw_lps_ctrl_wk_cmd(padapter
, LPS_CTRL_DISCONNECT
, 1);
858 inline void rtw_indicate_scan_done(struct adapter
*padapter
, bool aborted
)
860 rtw_os_indicate_scan_done(padapter
, aborted
);
863 void rtw_scan_abort(struct adapter
*adapter
)
866 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
867 struct mlme_ext_priv
*pmlmeext
= &(adapter
->mlmeextpriv
);
870 pmlmeext
->scan_abort
= true;
871 while (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
) &&
872 jiffies_to_msecs(jiffies
- start
) <= 200) {
873 if (adapter
->bDriverStopped
|| adapter
->bSurpriseRemoved
)
875 DBG_88E(FUNC_NDEV_FMT
"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter
->pnetdev
));
878 if (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
)) {
879 if (!adapter
->bDriverStopped
&& !adapter
->bSurpriseRemoved
)
880 DBG_88E(FUNC_NDEV_FMT
"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter
->pnetdev
));
881 rtw_indicate_scan_done(adapter
, true);
883 pmlmeext
->scan_abort
= false;
886 static struct sta_info
*rtw_joinbss_update_stainfo(struct adapter
*padapter
, struct wlan_network
*pnetwork
)
889 struct sta_info
*bmc_sta
, *psta
= NULL
;
890 struct recv_reorder_ctrl
*preorder_ctrl
;
891 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
893 psta
= rtw_get_stainfo(pstapriv
, pnetwork
->network
.MacAddress
);
895 psta
= rtw_alloc_stainfo(pstapriv
, pnetwork
->network
.MacAddress
);
897 if (psta
) { /* update ptarget_sta */
898 DBG_88E("%s\n", __func__
);
899 psta
->aid
= pnetwork
->join_res
;
902 rtw_hal_set_odm_var(padapter
, HAL_ODM_STA_INFO
, psta
, true);
903 /* security related */
904 if (padapter
->securitypriv
.dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
) {
905 padapter
->securitypriv
.binstallGrpkey
= false;
906 padapter
->securitypriv
.busetkipkey
= false;
907 padapter
->securitypriv
.bgrpkey_handshake
= false;
908 psta
->ieee8021x_blocked
= true;
909 psta
->dot118021XPrivacy
= padapter
->securitypriv
.dot11PrivacyAlgrthm
;
910 memset((u8
*)&psta
->dot118021x_UncstKey
, 0, sizeof(union Keytype
));
911 memset((u8
*)&psta
->dot11tkiprxmickey
, 0, sizeof(union Keytype
));
912 memset((u8
*)&psta
->dot11tkiptxmickey
, 0, sizeof(union Keytype
));
913 memset((u8
*)&psta
->dot11txpn
, 0, sizeof(union pn48
));
914 memset((u8
*)&psta
->dot11rxpn
, 0, sizeof(union pn48
));
917 * Commented by Albert 2012/07/21
918 * When doing the WPS, the wps_ie_len won't equal to 0
919 * And the Wi-Fi driver shouldn't allow the data
920 * packet to be tramsmitted.
922 if (padapter
->securitypriv
.wps_ie_len
!= 0) {
923 psta
->ieee8021x_blocked
= true;
924 padapter
->securitypriv
.wps_ie_len
= 0;
926 /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */
927 /* if A-MPDU Rx is enabled, resetting rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */
928 /* todo: check if AP can send A-MPDU packets */
929 for (i
= 0; i
< 16; i
++) {
930 /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
931 preorder_ctrl
= &psta
->recvreorder_ctrl
[i
];
932 preorder_ctrl
->enable
= false;
933 preorder_ctrl
->indicate_seq
= 0xffff;
934 preorder_ctrl
->wend_b
= 0xffff;
935 preorder_ctrl
->wsize_b
= 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
937 bmc_sta
= rtw_get_bcmc_stainfo(padapter
);
939 for (i
= 0; i
< 16; i
++) {
940 /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
941 preorder_ctrl
= &bmc_sta
->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 */
949 update_sta_info(padapter
, psta
);
954 /* pnetwork: returns from rtw_joinbss_event_callback */
955 /* ptarget_wlan: found from scanned_queue */
956 static void rtw_joinbss_update_network(struct adapter
*padapter
, struct wlan_network
*ptarget_wlan
, struct wlan_network
*pnetwork
)
958 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
959 struct wlan_network
*cur_network
= &(pmlmepriv
->cur_network
);
961 DBG_88E("%s\n", __func__
);
963 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
964 ("\nfw_state:%x, BSSID:%pM\n",
965 get_fwstate(pmlmepriv
), pnetwork
->network
.MacAddress
));
968 /* why not use ptarget_wlan?? */
969 memcpy(&cur_network
->network
, &pnetwork
->network
, pnetwork
->network
.Length
);
970 /* some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
971 cur_network
->network
.IELength
= ptarget_wlan
->network
.IELength
;
972 memcpy(&cur_network
->network
.IEs
[0], &ptarget_wlan
->network
.IEs
[0], MAX_IE_SZ
);
974 cur_network
->aid
= pnetwork
->join_res
;
977 rtw_set_signal_stat_timer(&padapter
->recvpriv
);
978 padapter
->recvpriv
.signal_strength
= ptarget_wlan
->network
.PhyInfo
.SignalStrength
;
979 padapter
->recvpriv
.signal_qual
= ptarget_wlan
->network
.PhyInfo
.SignalQuality
;
980 /* the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) */
981 padapter
->recvpriv
.rssi
= translate_percentage_to_dbm(ptarget_wlan
->network
.PhyInfo
.SignalStrength
);
982 rtw_set_signal_stat_timer(&padapter
->recvpriv
);
984 /* update fw_state will clr _FW_UNDER_LINKING here indirectly */
985 switch (pnetwork
->network
.InfrastructureMode
) {
986 case Ndis802_11Infrastructure
:
987 if (pmlmepriv
->fw_state
&WIFI_UNDER_WPS
)
988 pmlmepriv
->fw_state
= WIFI_STATION_STATE
|WIFI_UNDER_WPS
;
990 pmlmepriv
->fw_state
= WIFI_STATION_STATE
;
993 pmlmepriv
->fw_state
= WIFI_ADHOC_STATE
;
996 pmlmepriv
->fw_state
= WIFI_NULL_STATE
;
997 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Invalid network_mode\n"));
1001 rtw_update_protection(padapter
, (cur_network
->network
.IEs
) +
1002 sizeof(struct ndis_802_11_fixed_ie
),
1003 (cur_network
->network
.IELength
));
1004 rtw_update_ht_cap(padapter
, cur_network
->network
.IEs
, cur_network
->network
.IELength
);
1007 /* Notes: the function could be > passive_level (the same context as Rx tasklet) */
1008 /* pnetwork: returns from rtw_joinbss_event_callback */
1009 /* ptarget_wlan: found from scanned_queue */
1010 /* if join_res > 0, for (fw_state == WIFI_STATION_STATE), we check if "ptarget_sta" & "ptarget_wlan" exist. */
1011 /* if join_res > 0, for (fw_state == WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. */
1012 /* if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan != NULL). */
1014 void rtw_joinbss_event_prehandle(struct adapter
*adapter
, u8
*pbuf
)
1016 struct sta_info
*ptarget_sta
= NULL
, *pcur_sta
= NULL
;
1017 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
1018 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1019 struct wlan_network
*pnetwork
= (struct wlan_network
*)pbuf
;
1020 struct wlan_network
*cur_network
= &(pmlmepriv
->cur_network
);
1021 struct wlan_network
*pcur_wlan
= NULL
, *ptarget_wlan
= NULL
;
1022 unsigned int the_same_macaddr
= false;
1024 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("joinbss event call back received with res=%d\n", pnetwork
->join_res
));
1026 rtw_get_encrypt_decrypt_from_registrypriv(adapter
);
1029 if (pmlmepriv
->assoc_ssid
.SsidLength
== 0)
1030 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("@@@@@ joinbss event call back for Any SSid\n"));
1032 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("@@@@@ rtw_joinbss_event_callback for SSid:%s\n", pmlmepriv
->assoc_ssid
.Ssid
));
1034 the_same_macaddr
= !memcmp(pnetwork
->network
.MacAddress
, cur_network
->network
.MacAddress
, ETH_ALEN
);
1036 pnetwork
->network
.Length
= get_wlan_bssid_ex_sz(&pnetwork
->network
);
1037 if (pnetwork
->network
.Length
> sizeof(struct wlan_bssid_ex
)) {
1038 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("\n\n ***joinbss_evt_callback return a wrong bss ***\n\n"));
1042 spin_lock_bh(&pmlmepriv
->lock
);
1044 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("\nrtw_joinbss_event_callback!! _enter_critical\n"));
1046 if (pnetwork
->join_res
> 0) {
1047 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1048 if (check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
)) {
1049 /* s1. find ptarget_wlan */
1050 if (check_fwstate(pmlmepriv
, _FW_LINKED
)) {
1051 if (the_same_macaddr
) {
1052 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, cur_network
->network
.MacAddress
);
1054 pcur_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, cur_network
->network
.MacAddress
);
1056 pcur_wlan
->fixed
= false;
1058 pcur_sta
= rtw_get_stainfo(pstapriv
, cur_network
->network
.MacAddress
);
1060 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
1061 rtw_free_stainfo(adapter
, pcur_sta
);
1062 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
1065 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, pnetwork
->network
.MacAddress
);
1066 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1068 ptarget_wlan
->fixed
= true;
1072 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, pnetwork
->network
.MacAddress
);
1073 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1075 ptarget_wlan
->fixed
= true;
1079 /* s2. update cur_network */
1081 rtw_joinbss_update_network(adapter
, ptarget_wlan
, pnetwork
);
1083 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Can't find ptarget_wlan when joinbss_event callback\n"));
1084 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1085 goto ignore_joinbss_callback
;
1089 /* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */
1090 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1091 ptarget_sta
= rtw_joinbss_update_stainfo(adapter
, pnetwork
);
1092 if (ptarget_sta
== NULL
) {
1093 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Can't update stainfo when joinbss_event callback\n"));
1094 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1095 goto ignore_joinbss_callback
;
1099 /* s4. indicate connect */
1100 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1101 rtw_indicate_connect(adapter
);
1103 /* adhoc mode will rtw_indicate_connect when rtw_stassoc_event_callback */
1104 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("adhoc mode, fw_state:%x", get_fwstate(pmlmepriv
)));
1107 /* s5. Cancle assoc_timer */
1108 del_timer_sync(&pmlmepriv
->assoc_timer
);
1110 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("Cancle assoc_timer\n"));
1113 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("rtw_joinbss_event_callback err: fw_state:%x", get_fwstate(pmlmepriv
)));
1114 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1115 goto ignore_joinbss_callback
;
1118 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1120 } else if (pnetwork
->join_res
== -4) {
1121 rtw_reset_securitypriv(adapter
);
1122 mod_timer(&pmlmepriv
->assoc_timer
,
1123 jiffies
+ msecs_to_jiffies(1));
1125 if ((check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
)) == true) {
1126 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n", get_fwstate(pmlmepriv
)));
1127 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
1129 } else { /* if join_res < 0 (join fails), then try again */
1130 mod_timer(&pmlmepriv
->assoc_timer
,
1131 jiffies
+ msecs_to_jiffies(1));
1132 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
1135 ignore_joinbss_callback
:
1136 spin_unlock_bh(&pmlmepriv
->lock
);
1139 void rtw_joinbss_event_callback(struct adapter
*adapter
, u8
*pbuf
)
1141 struct wlan_network
*pnetwork
= (struct wlan_network
*)pbuf
;
1143 mlmeext_joinbss_event_callback(adapter
, pnetwork
->join_res
);
1145 rtw_os_xmit_schedule(adapter
);
1148 static u8
search_max_mac_id(struct adapter
*padapter
)
1151 #if defined(CONFIG_88EU_AP_MODE)
1153 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1154 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1156 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1157 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1159 #if defined(CONFIG_88EU_AP_MODE)
1160 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1161 for (aid
= (pstapriv
->max_num_sta
); aid
> 0; aid
--) {
1162 if (pstapriv
->sta_aid
[aid
-1] != NULL
)
1168 {/* adhoc id = 31~2 */
1169 for (mac_id
= (NUM_STA
-1); mac_id
>= IBSS_START_MAC_ID
; mac_id
--) {
1170 if (pmlmeinfo
->FW_sta_info
[mac_id
].status
== 1)
1177 /* FOR AP , AD-HOC mode */
1178 void rtw_stassoc_hw_rpt(struct adapter
*adapter
, struct sta_info
*psta
)
1186 macid
= search_max_mac_id(adapter
);
1187 rtw_hal_set_hwreg(adapter
, HW_VAR_TX_RPT_MAX_MACID
, (u8
*)&macid
);
1188 media_status
= (psta
->mac_id
<<8)|1; /* MACID|OPMODE:1 connect */
1189 rtw_hal_set_hwreg(adapter
, HW_VAR_H2C_MEDIA_STATUS_RPT
, (u8
*)&media_status
);
1192 void rtw_stassoc_event_callback(struct adapter
*adapter
, u8
*pbuf
)
1194 struct sta_info
*psta
;
1195 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1196 struct stassoc_event
*pstassoc
= (struct stassoc_event
*)pbuf
;
1197 struct wlan_network
*cur_network
= &(pmlmepriv
->cur_network
);
1198 struct wlan_network
*ptarget_wlan
= NULL
;
1200 if (rtw_access_ctrl(adapter
, pstassoc
->macaddr
) == false)
1203 #if defined(CONFIG_88EU_AP_MODE)
1204 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1205 psta
= rtw_get_stainfo(&adapter
->stapriv
, pstassoc
->macaddr
);
1207 ap_sta_info_defer_update(adapter
, psta
);
1208 rtw_stassoc_hw_rpt(adapter
, psta
);
1213 /* for AD-HOC mode */
1214 psta
= rtw_get_stainfo(&adapter
->stapriv
, pstassoc
->macaddr
);
1216 /* the sta have been in sta_info_queue => do nothing */
1217 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Error: rtw_stassoc_event_callback: sta has been in sta_hash_queue\n"));
1218 return; /* between drv has received this event before and fw have not yet to set key to CAM_ENTRY) */
1220 psta
= rtw_alloc_stainfo(&adapter
->stapriv
, pstassoc
->macaddr
);
1222 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Can't alloc sta_info when rtw_stassoc_event_callback\n"));
1225 /* to do: init sta_info variable */
1226 psta
->qos_option
= 0;
1227 psta
->mac_id
= (uint
)pstassoc
->cam_id
;
1228 DBG_88E("%s\n", __func__
);
1229 /* for ad-hoc mode */
1230 rtw_hal_set_odm_var(adapter
, HAL_ODM_STA_INFO
, psta
, true);
1231 rtw_stassoc_hw_rpt(adapter
, psta
);
1232 if (adapter
->securitypriv
.dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
)
1233 psta
->dot118021XPrivacy
= adapter
->securitypriv
.dot11PrivacyAlgrthm
;
1234 psta
->ieee8021x_blocked
= false;
1235 spin_lock_bh(&pmlmepriv
->lock
);
1236 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) ||
1237 (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
))) {
1238 if (adapter
->stapriv
.asoc_sta_count
== 2) {
1239 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1240 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, cur_network
->network
.MacAddress
);
1242 ptarget_wlan
->fixed
= true;
1243 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1244 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1245 rtw_indicate_connect(adapter
);
1248 spin_unlock_bh(&pmlmepriv
->lock
);
1249 mlmeext_sta_add_event_callback(adapter
, psta
);
1252 void rtw_stadel_event_callback(struct adapter
*adapter
, u8
*pbuf
)
1255 struct sta_info
*psta
;
1256 struct wlan_network
*pwlan
= NULL
;
1257 struct wlan_bssid_ex
*pdev_network
= NULL
;
1259 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1260 struct stadel_event
*pstadel
= (struct stadel_event
*)pbuf
;
1261 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
1262 struct wlan_network
*tgt_network
= &(pmlmepriv
->cur_network
);
1264 psta
= rtw_get_stainfo(&adapter
->stapriv
, pstadel
->macaddr
);
1266 mac_id
= psta
->mac_id
;
1268 mac_id
= pstadel
->mac_id
;
1270 DBG_88E("%s(mac_id=%d)=%pM\n", __func__
, mac_id
, pstadel
->macaddr
);
1274 media_status
= (mac_id
<<8)|0; /* MACID|OPMODE:0 means disconnect */
1275 /* for STA, AP, ADHOC mode, report disconnect stauts to FW */
1276 rtw_hal_set_hwreg(adapter
, HW_VAR_H2C_MEDIA_STATUS_RPT
, (u8
*)&media_status
);
1279 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
))
1282 mlmeext_sta_del_event_callback(adapter
);
1284 spin_lock_bh(&pmlmepriv
->lock
);
1286 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
)) {
1287 if (pmlmepriv
->to_roaming
> 0)
1288 pmlmepriv
->to_roaming
--; /* this stadel_event is caused by roaming, decrease to_roaming */
1289 else if (pmlmepriv
->to_roaming
== 0)
1290 pmlmepriv
->to_roaming
= adapter
->registrypriv
.max_roaming_times
;
1292 if (*((unsigned short *)(pstadel
->rsvd
)) != WLAN_REASON_EXPIRATION_CHK
)
1293 pmlmepriv
->to_roaming
= 0; /* don't roam */
1295 rtw_free_uc_swdec_pending_queue(adapter
);
1297 rtw_free_assoc_resources(adapter
);
1298 rtw_indicate_disconnect(adapter
);
1299 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1300 /* remove the network entry in scanned_queue */
1301 pwlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, tgt_network
->network
.MacAddress
);
1303 pwlan
->fixed
= false;
1304 rtw_free_network_nolock(pmlmepriv
, pwlan
);
1306 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1307 _rtw_roaming(adapter
, tgt_network
);
1309 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) ||
1310 check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)) {
1311 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
1312 rtw_free_stainfo(adapter
, psta
);
1313 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
1315 if (adapter
->stapriv
.asoc_sta_count
== 1) { /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1316 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1317 /* free old ibss network */
1318 pwlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, tgt_network
->network
.MacAddress
);
1320 pwlan
->fixed
= false;
1321 rtw_free_network_nolock(pmlmepriv
, pwlan
);
1323 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1324 /* re-create ibss */
1325 pdev_network
= &(adapter
->registrypriv
.dev_network
);
1326 pibss
= adapter
->registrypriv
.dev_network
.MacAddress
;
1328 memcpy(pdev_network
, &tgt_network
->network
, get_wlan_bssid_ex_sz(&tgt_network
->network
));
1330 memcpy(&pdev_network
->Ssid
, &pmlmepriv
->assoc_ssid
, sizeof(struct ndis_802_11_ssid
));
1332 rtw_update_registrypriv_dev_network(adapter
);
1334 rtw_generate_random_ibss(pibss
);
1336 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)) {
1337 set_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
);
1338 _clr_fwstate_(pmlmepriv
, WIFI_ADHOC_STATE
);
1341 if (rtw_createbss_cmd(adapter
) != _SUCCESS
)
1342 RT_TRACE(_module_rtl871x_ioctl_set_c_
, _drv_err_
, ("***Error=>stadel_event_callback: rtw_createbss_cmd status FAIL***\n "));
1345 spin_unlock_bh(&pmlmepriv
->lock
);
1348 void rtw_cpwm_event_callback(struct adapter
*padapter
, u8
*pbuf
)
1350 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("+rtw_cpwm_event_callback !!!\n"));
1354 * _rtw_join_timeout_handler - Timeout/faliure handler for CMD JoinBss
1355 * @adapter: pointer to struct adapter structure
1357 void _rtw_join_timeout_handler (unsigned long data
)
1359 struct adapter
*adapter
= (struct adapter
*)data
;
1360 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1363 DBG_88E("%s, fw_state=%x\n", __func__
, get_fwstate(pmlmepriv
));
1365 if (adapter
->bDriverStopped
|| adapter
->bSurpriseRemoved
)
1369 spin_lock_bh(&pmlmepriv
->lock
);
1371 if (pmlmepriv
->to_roaming
> 0) { /* join timeout caused by roaming */
1373 pmlmepriv
->to_roaming
--;
1374 if (pmlmepriv
->to_roaming
!= 0) { /* try another , */
1375 DBG_88E("%s try another roaming\n", __func__
);
1376 do_join_r
= rtw_do_join(adapter
);
1377 if (_SUCCESS
!= do_join_r
) {
1378 DBG_88E("%s roaming do_join return %d\n", __func__
, do_join_r
);
1383 DBG_88E("%s We've try roaming but fail\n", __func__
);
1384 rtw_indicate_disconnect(adapter
);
1389 rtw_indicate_disconnect(adapter
);
1390 free_scanqueue(pmlmepriv
);/* */
1392 spin_unlock_bh(&pmlmepriv
->lock
);
1396 * rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey
1397 * @adapter: pointer to struct adapter structure
1399 void rtw_scan_timeout_handler (unsigned long data
)
1401 struct adapter
*adapter
= (struct adapter
*)data
;
1402 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1404 DBG_88E(FUNC_ADPT_FMT
" fw_state=%x\n", FUNC_ADPT_ARG(adapter
), get_fwstate(pmlmepriv
));
1405 spin_lock_bh(&pmlmepriv
->lock
);
1406 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
1407 spin_unlock_bh(&pmlmepriv
->lock
);
1408 rtw_indicate_scan_done(adapter
, true);
1411 static void rtw_auto_scan_handler(struct adapter
*padapter
)
1413 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1415 /* auto site survey per 60sec */
1416 if (pmlmepriv
->scan_interval
> 0) {
1417 pmlmepriv
->scan_interval
--;
1418 if (pmlmepriv
->scan_interval
== 0) {
1419 DBG_88E("%s\n", __func__
);
1420 rtw_set_802_11_bssid_list_scan(padapter
, NULL
, 0);
1421 pmlmepriv
->scan_interval
= SCAN_INTERVAL
;/* 30*2 sec = 60sec */
1426 void rtw_dynamic_check_timer_handlder(unsigned long data
)
1428 struct adapter
*adapter
= (struct adapter
*)data
;
1429 struct registry_priv
*pregistrypriv
= &adapter
->registrypriv
;
1433 if (!adapter
->hw_init_completed
)
1435 if ((adapter
->bDriverStopped
) || (adapter
->bSurpriseRemoved
))
1437 if (adapter
->net_closed
)
1439 rtw_dynamic_chk_wk_cmd(adapter
);
1441 if (pregistrypriv
->wifi_spec
== 1) {
1442 /* auto site survey */
1443 rtw_auto_scan_handler(adapter
);
1446 mod_timer(&adapter
->mlmepriv
.dynamic_chk_timer
,
1447 jiffies
+ msecs_to_jiffies(2000));
1450 #define RTW_SCAN_RESULT_EXPIRE 2000
1453 * Select a new join candidate from the original @param candidate and @param competitor
1454 * @return true: candidate is updated
1455 * @return false: candidate is not updated
1457 static int rtw_check_join_candidate(struct mlme_priv
*pmlmepriv
1458 , struct wlan_network
**candidate
, struct wlan_network
*competitor
)
1460 int updated
= false;
1461 unsigned long since_scan
;
1462 struct adapter
*adapter
= container_of(pmlmepriv
, struct adapter
, mlmepriv
);
1465 /* check bssid, if needed */
1466 if (pmlmepriv
->assoc_by_bssid
) {
1467 if (memcmp(competitor
->network
.MacAddress
, pmlmepriv
->assoc_bssid
, ETH_ALEN
))
1471 /* check ssid, if needed */
1472 if (pmlmepriv
->assoc_ssid
.SsidLength
) {
1473 if (competitor
->network
.Ssid
.SsidLength
!= pmlmepriv
->assoc_ssid
.SsidLength
||
1474 !memcmp(competitor
->network
.Ssid
.Ssid
, pmlmepriv
->assoc_ssid
.Ssid
, pmlmepriv
->assoc_ssid
.SsidLength
) == false)
1478 if (rtw_is_desired_network(adapter
, competitor
) == false)
1481 if (pmlmepriv
->to_roaming
) {
1482 since_scan
= jiffies
- competitor
->last_scanned
;
1483 if (jiffies_to_msecs(since_scan
) >= RTW_SCAN_RESULT_EXPIRE
||
1484 is_same_ess(&competitor
->network
, &pmlmepriv
->cur_network
.network
) == false)
1488 if (*candidate
== NULL
|| (*candidate
)->network
.Rssi
< competitor
->network
.Rssi
) {
1489 *candidate
= competitor
;
1493 DBG_88E("[by_bssid:%u][assoc_ssid:%s]new candidate: %s(%pM rssi:%d\n",
1494 pmlmepriv
->assoc_by_bssid
,
1495 pmlmepriv
->assoc_ssid
.Ssid
,
1496 (*candidate
)->network
.Ssid
.Ssid
,
1497 (*candidate
)->network
.MacAddress
,
1498 (int)(*candidate
)->network
.Rssi
);
1499 DBG_88E("[to_roaming:%u]\n", pmlmepriv
->to_roaming
);
1508 The caller of the sub-routine will be in critical section...
1509 The caller must hold the following spinlock
1513 int rtw_select_and_join_from_scanned_queue(struct mlme_priv
*pmlmepriv
)
1516 struct list_head
*phead
;
1517 struct adapter
*adapter
;
1518 struct __queue
*queue
= &(pmlmepriv
->scanned_queue
);
1519 struct wlan_network
*pnetwork
= NULL
;
1520 struct wlan_network
*candidate
= NULL
;
1521 u8 supp_ant_div
= false;
1523 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1524 phead
= get_list_head(queue
);
1525 adapter
= (struct adapter
*)pmlmepriv
->nic_hdl
;
1526 pmlmepriv
->pscanned
= phead
->next
;
1527 while (phead
!= pmlmepriv
->pscanned
) {
1528 pnetwork
= container_of(pmlmepriv
->pscanned
, struct wlan_network
, list
);
1529 if (pnetwork
== NULL
) {
1530 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("%s return _FAIL:(pnetwork==NULL)\n", __func__
));
1534 pmlmepriv
->pscanned
= pmlmepriv
->pscanned
->next
;
1535 rtw_check_join_candidate(pmlmepriv
, &candidate
, pnetwork
);
1537 if (candidate
== NULL
) {
1538 DBG_88E("%s: return _FAIL(candidate==NULL)\n", __func__
);
1542 DBG_88E("%s: candidate: %s(%pM ch:%u)\n", __func__
,
1543 candidate
->network
.Ssid
.Ssid
, candidate
->network
.MacAddress
,
1544 candidate
->network
.Configuration
.DSConfig
);
1548 /* check for situation of _FW_LINKED */
1549 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true) {
1550 DBG_88E("%s: _FW_LINKED while ask_for_joinbss!!!\n", __func__
);
1552 rtw_disassoc_cmd(adapter
, 0, true);
1553 rtw_indicate_disconnect(adapter
);
1554 rtw_free_assoc_resources_locked(adapter
);
1557 rtw_hal_get_def_var(adapter
, HAL_DEF_IS_SUPPORT_ANT_DIV
, &(supp_ant_div
));
1560 rtw_hal_get_def_var(adapter
, HAL_DEF_CURRENT_ANTENNA
, &(cur_ant
));
1561 DBG_88E("#### Opt_Ant_(%s), cur_Ant(%s)\n",
1562 (2 == candidate
->network
.PhyInfo
.Optimum_antenna
) ? "A" : "B",
1563 (2 == cur_ant
) ? "A" : "B"
1567 ret
= rtw_joinbss_cmd(adapter
, candidate
);
1570 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1574 int rtw_set_auth(struct adapter
*adapter
, struct security_priv
*psecuritypriv
)
1576 struct cmd_obj
*pcmd
;
1577 struct setauth_parm
*psetauthparm
;
1578 struct cmd_priv
*pcmdpriv
= &(adapter
->cmdpriv
);
1581 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
1583 res
= _FAIL
; /* try again */
1587 psetauthparm
= kzalloc(sizeof(struct setauth_parm
), GFP_KERNEL
);
1588 if (!psetauthparm
) {
1593 memset(psetauthparm
, 0, sizeof(struct setauth_parm
));
1594 psetauthparm
->mode
= (unsigned char)psecuritypriv
->dot11AuthAlgrthm
;
1595 pcmd
->cmdcode
= _SetAuth_CMD_
;
1596 pcmd
->parmbuf
= (unsigned char *)psetauthparm
;
1597 pcmd
->cmdsz
= (sizeof(struct setauth_parm
));
1600 INIT_LIST_HEAD(&pcmd
->list
);
1601 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1602 ("after enqueue set_auth_cmd, auth_mode=%x\n",
1603 psecuritypriv
->dot11AuthAlgrthm
));
1604 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
1609 int rtw_set_key(struct adapter
*adapter
, struct security_priv
*psecuritypriv
, int keyid
, u8 set_tx
)
1612 struct cmd_obj
*pcmd
;
1613 struct setkey_parm
*psetkeyparm
;
1614 struct cmd_priv
*pcmdpriv
= &(adapter
->cmdpriv
);
1615 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1618 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
1620 return _FAIL
; /* try again */
1622 psetkeyparm
= kzalloc(sizeof(struct setkey_parm
), GFP_KERNEL
);
1628 memset(psetkeyparm
, 0, sizeof(struct setkey_parm
));
1630 if (psecuritypriv
->dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
) {
1631 psetkeyparm
->algorithm
= (unsigned char)psecuritypriv
->dot118021XGrpPrivacy
;
1632 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1633 ("\n rtw_set_key: psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy=%d\n",
1634 psetkeyparm
->algorithm
));
1636 psetkeyparm
->algorithm
= (u8
)psecuritypriv
->dot11PrivacyAlgrthm
;
1637 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1638 ("\n rtw_set_key: psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm=%d\n",
1639 psetkeyparm
->algorithm
));
1641 psetkeyparm
->keyid
= (u8
)keyid
;/* 0~3 */
1642 psetkeyparm
->set_tx
= set_tx
;
1643 pmlmepriv
->key_mask
|= BIT(psetkeyparm
->keyid
);
1644 DBG_88E("==> rtw_set_key algorithm(%x), keyid(%x), key_mask(%x)\n",
1645 psetkeyparm
->algorithm
, psetkeyparm
->keyid
, pmlmepriv
->key_mask
);
1646 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1647 ("\n rtw_set_key: psetkeyparm->algorithm=%d psetkeyparm->keyid=(u8)keyid=%d\n",
1648 psetkeyparm
->algorithm
, keyid
));
1650 switch (psetkeyparm
->algorithm
) {
1653 memcpy(&(psetkeyparm
->key
[0]), &(psecuritypriv
->dot11DefKey
[keyid
].skey
[0]), keylen
);
1657 memcpy(&(psetkeyparm
->key
[0]), &(psecuritypriv
->dot11DefKey
[keyid
].skey
[0]), keylen
);
1661 memcpy(&psetkeyparm
->key
, &psecuritypriv
->dot118021XGrpKey
[keyid
], keylen
);
1662 psetkeyparm
->grpkey
= 1;
1666 memcpy(&psetkeyparm
->key
, &psecuritypriv
->dot118021XGrpKey
[keyid
], keylen
);
1667 psetkeyparm
->grpkey
= 1;
1670 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1671 ("\n rtw_set_key:psecuritypriv->dot11PrivacyAlgrthm=%x (must be 1 or 2 or 4 or 5)\n",
1672 psecuritypriv
->dot11PrivacyAlgrthm
));
1676 pcmd
->cmdcode
= _SetKey_CMD_
;
1677 pcmd
->parmbuf
= (u8
*)psetkeyparm
;
1678 pcmd
->cmdsz
= (sizeof(struct setkey_parm
));
1681 INIT_LIST_HEAD(&pcmd
->list
);
1682 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
1692 /* adjust IEs for rtw_joinbss_cmd in WMM */
1693 int rtw_restruct_wmm_ie(struct adapter
*adapter
, u8
*in_ie
, u8
*out_ie
, uint in_len
, uint initial_out_len
)
1695 unsigned int ielength
= 0;
1698 /* i = 12; after the fixed IE */
1699 for (i
= 12; i
< in_len
; i
+= (in_ie
[i
+ 1] + 2) /* to the next IE element */) {
1700 ielength
= initial_out_len
;
1702 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
) {
1703 /* WMM element ID and OUI */
1704 /* Append WMM IE to the last index of out_ie */
1706 for (j
= i
; j
< i
+ 9; j
++) {
1707 out_ie
[ielength
] = in_ie
[j
];
1710 out_ie
[initial_out_len
+ 1] = 0x07;
1711 out_ie
[initial_out_len
+ 6] = 0x00;
1712 out_ie
[initial_out_len
+ 8] = 0x00;
1720 * Ported from 8185: IsInPreAuthKeyList().
1721 * (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.)
1722 * Added by Annie, 2006-05-07.
1725 * -1 :if there is no pre-auth key in the table
1726 * >= 0 :if there is pre-auth key, and return the entry id
1728 static int SecIsInPMKIDList(struct adapter
*Adapter
, u8
*bssid
)
1730 struct security_priv
*psecuritypriv
= &Adapter
->securitypriv
;
1734 if ((psecuritypriv
->PMKIDList
[i
].bUsed
) &&
1735 (!memcmp(psecuritypriv
->PMKIDList
[i
].Bssid
, bssid
, ETH_ALEN
))) {
1742 } while (i
< NUM_PMKID_CACHE
);
1744 if (i
== NUM_PMKID_CACHE
)
1745 i
= -1;/* Could not find. */
1751 /* Check the RSN IE length */
1752 /* If the RSN IE length <= 20, the RSN IE didn't include the PMKID information */
1753 /* 0-11th element in the array are the fixed IE */
1754 /* 12th element in the array is the IE */
1755 /* 13th element in the array is the IE length */
1758 static int rtw_append_pmkid(struct adapter
*Adapter
, int iEntry
, u8
*ie
, uint ie_len
)
1760 struct security_priv
*psecuritypriv
= &Adapter
->securitypriv
;
1763 /* The RSN IE didn't include the PMK ID, append the PMK information */
1766 ie
[ie_len
] = 0; /* PMKID count = 0x0100 */
1768 memcpy(&ie
[ie_len
], &psecuritypriv
->PMKIDList
[iEntry
].PMKID
, 16);
1771 ie
[13] += 18;/* PMKID length = 2+16 */
1776 int rtw_restruct_sec_ie(struct adapter
*adapter
, u8
*in_ie
, u8
*out_ie
, uint in_len
)
1782 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1783 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
1784 uint ndisauthmode
= psecuritypriv
->ndisauthtype
;
1785 uint ndissecuritytype
= psecuritypriv
->ndisencryptstatus
;
1787 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
1788 ("+rtw_restruct_sec_ie: ndisauthmode=%d ndissecuritytype=%d\n",
1789 ndisauthmode
, ndissecuritytype
));
1791 /* copy fixed ie only */
1792 memcpy(out_ie
, in_ie
, 12);
1794 if ((ndisauthmode
== Ndis802_11AuthModeWPA
) ||
1795 (ndisauthmode
== Ndis802_11AuthModeWPAPSK
))
1796 authmode
= _WPA_IE_ID_
;
1797 if ((ndisauthmode
== Ndis802_11AuthModeWPA2
) ||
1798 (ndisauthmode
== Ndis802_11AuthModeWPA2PSK
))
1799 authmode
= _WPA2_IE_ID_
;
1801 if (check_fwstate(pmlmepriv
, WIFI_UNDER_WPS
)) {
1802 memcpy(out_ie
+ielength
, psecuritypriv
->wps_ie
, psecuritypriv
->wps_ie_len
);
1804 ielength
+= psecuritypriv
->wps_ie_len
;
1805 } else if ((authmode
== _WPA_IE_ID_
) || (authmode
== _WPA2_IE_ID_
)) {
1806 /* copy RSN or SSN */
1807 memcpy(&out_ie
[ielength
], &psecuritypriv
->supplicant_ie
[0], psecuritypriv
->supplicant_ie
[1]+2);
1808 ielength
+= psecuritypriv
->supplicant_ie
[1]+2;
1809 rtw_report_sec_ie(adapter
, authmode
, psecuritypriv
->supplicant_ie
);
1812 iEntry
= SecIsInPMKIDList(adapter
, pmlmepriv
->assoc_bssid
);
1816 if (authmode
== _WPA2_IE_ID_
)
1817 ielength
= rtw_append_pmkid(adapter
, iEntry
, out_ie
, ielength
);
1822 void rtw_init_registrypriv_dev_network(struct adapter
*adapter
)
1824 struct registry_priv
*pregistrypriv
= &adapter
->registrypriv
;
1825 struct eeprom_priv
*peepriv
= &adapter
->eeprompriv
;
1826 struct wlan_bssid_ex
*pdev_network
= &pregistrypriv
->dev_network
;
1827 u8
*myhwaddr
= myid(peepriv
);
1829 memcpy(pdev_network
->MacAddress
, myhwaddr
, ETH_ALEN
);
1831 memcpy(&pdev_network
->Ssid
, &pregistrypriv
->ssid
, sizeof(struct ndis_802_11_ssid
));
1833 pdev_network
->Configuration
.Length
= sizeof(struct ndis_802_11_config
);
1834 pdev_network
->Configuration
.BeaconPeriod
= 100;
1835 pdev_network
->Configuration
.FHConfig
.Length
= 0;
1836 pdev_network
->Configuration
.FHConfig
.HopPattern
= 0;
1837 pdev_network
->Configuration
.FHConfig
.HopSet
= 0;
1838 pdev_network
->Configuration
.FHConfig
.DwellTime
= 0;
1841 void rtw_update_registrypriv_dev_network(struct adapter
*adapter
)
1844 struct registry_priv
*pregistrypriv
= &adapter
->registrypriv
;
1845 struct wlan_bssid_ex
*pdev_network
= &pregistrypriv
->dev_network
;
1846 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
1847 struct wlan_network
*cur_network
= &adapter
->mlmepriv
.cur_network
;
1849 pdev_network
->Privacy
= (psecuritypriv
->dot11PrivacyAlgrthm
> 0 ? 1 : 0); /* adhoc no 802.1x */
1851 pdev_network
->Rssi
= 0;
1853 switch (pregistrypriv
->wireless_mode
) {
1855 pdev_network
->NetworkTypeInUse
= (Ndis802_11DS
);
1859 case WIRELESS_11_24N
:
1860 case WIRELESS_11G_24N
:
1861 case WIRELESS_11BG_24N
:
1862 pdev_network
->NetworkTypeInUse
= (Ndis802_11OFDM24
);
1865 case WIRELESS_11A_5N
:
1866 pdev_network
->NetworkTypeInUse
= (Ndis802_11OFDM5
);
1868 case WIRELESS_11ABGN
:
1869 if (pregistrypriv
->channel
> 14)
1870 pdev_network
->NetworkTypeInUse
= (Ndis802_11OFDM5
);
1872 pdev_network
->NetworkTypeInUse
= (Ndis802_11OFDM24
);
1879 pdev_network
->Configuration
.DSConfig
= (pregistrypriv
->channel
);
1880 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
1881 ("pregistrypriv->channel=%d, pdev_network->Configuration.DSConfig=0x%x\n",
1882 pregistrypriv
->channel
, pdev_network
->Configuration
.DSConfig
));
1884 if (cur_network
->network
.InfrastructureMode
== Ndis802_11IBSS
)
1885 pdev_network
->Configuration
.ATIMWindow
= (0);
1887 pdev_network
->InfrastructureMode
= (cur_network
->network
.InfrastructureMode
);
1889 /* 1. Supported rates */
1892 sz
= rtw_generate_ie(pregistrypriv
);
1893 pdev_network
->IELength
= sz
;
1894 pdev_network
->Length
= get_wlan_bssid_ex_sz((struct wlan_bssid_ex
*)pdev_network
);
1896 /* notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); */
1897 /* pdev_network->IELength = cpu_to_le32(sz); */
1900 void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter
*adapter
)
1904 /* the function is at passive_level */
1905 void rtw_joinbss_reset(struct adapter
*padapter
)
1908 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1909 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
1911 /* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */
1912 pmlmepriv
->num_FortyMHzIntolerant
= 0;
1914 pmlmepriv
->num_sta_no_ht
= 0;
1916 phtpriv
->ampdu_enable
= false;/* reset to disabled */
1918 /* TH = 1 => means that invalidate usb rx aggregation */
1919 /* TH = 0 => means that validate usb rx aggregation, use init value. */
1920 if (phtpriv
->ht_option
) {
1921 if (padapter
->registrypriv
.wifi_spec
== 1)
1925 rtw_hal_set_hwreg(padapter
, HW_VAR_RXDMA_AGG_PG_TH
, (u8
*)(&threshold
));
1928 rtw_hal_set_hwreg(padapter
, HW_VAR_RXDMA_AGG_PG_TH
, (u8
*)(&threshold
));
1932 /* the function is >= passive_level */
1933 unsigned int rtw_restructure_ht_ie(struct adapter
*padapter
, u8
*in_ie
, u8
*out_ie
, uint in_len
, uint
*pout_len
)
1936 enum ht_cap_ampdu_factor max_rx_ampdu_factor
;
1938 struct rtw_ieee80211_ht_cap ht_capie
;
1939 unsigned char WMM_IE
[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
1940 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1941 struct qos_priv
*pqospriv
= &pmlmepriv
->qospriv
;
1942 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
1943 u32 rx_packet_offset
, max_recvbuf_sz
;
1946 phtpriv
->ht_option
= false;
1948 p
= rtw_get_ie(in_ie
+12, _HT_CAPABILITY_IE_
, &ielen
, in_len
-12);
1950 if (p
&& ielen
> 0) {
1951 if (pqospriv
->qos_option
== 0) {
1952 out_len
= *pout_len
;
1953 rtw_set_ie(out_ie
+out_len
, _VENDOR_SPECIFIC_IE_
,
1954 _WMM_IE_Length_
, WMM_IE
, pout_len
);
1956 pqospriv
->qos_option
= 1;
1959 out_len
= *pout_len
;
1961 memset(&ht_capie
, 0, sizeof(struct rtw_ieee80211_ht_cap
));
1963 ht_capie
.cap_info
= IEEE80211_HT_CAP_SUP_WIDTH
|
1964 IEEE80211_HT_CAP_SGI_20
|
1965 IEEE80211_HT_CAP_SGI_40
|
1966 IEEE80211_HT_CAP_TX_STBC
|
1967 IEEE80211_HT_CAP_DSSSCCK40
;
1969 rtw_hal_get_def_var(padapter
, HAL_DEF_RX_PACKET_OFFSET
, &rx_packet_offset
);
1970 rtw_hal_get_def_var(padapter
, HAL_DEF_MAX_RECVBUF_SZ
, &max_recvbuf_sz
);
1973 AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
1974 AMPDU_para [4:2]:Min MPDU Start Spacing
1977 rtw_hal_get_def_var(padapter
, HW_VAR_MAX_RX_AMPDU_FACTOR
, &max_rx_ampdu_factor
);
1978 ht_capie
.ampdu_params_info
= (max_rx_ampdu_factor
&0x03);
1980 if (padapter
->securitypriv
.dot11PrivacyAlgrthm
== _AES_
)
1981 ht_capie
.ampdu_params_info
|= (IEEE80211_HT_CAP_AMPDU_DENSITY
&(0x07<<2));
1983 ht_capie
.ampdu_params_info
|= (IEEE80211_HT_CAP_AMPDU_DENSITY
&0x00);
1986 rtw_set_ie(out_ie
+out_len
, _HT_CAPABILITY_IE_
,
1987 sizeof(struct rtw_ieee80211_ht_cap
), (unsigned char *)&ht_capie
, pout_len
);
1989 phtpriv
->ht_option
= true;
1991 p
= rtw_get_ie(in_ie
+12, _HT_ADD_INFO_IE_
, &ielen
, in_len
-12);
1992 if (p
&& (ielen
== sizeof(struct ieee80211_ht_addt_info
))) {
1993 out_len
= *pout_len
;
1994 rtw_set_ie(out_ie
+out_len
, _HT_ADD_INFO_IE_
, ielen
, p
+2, pout_len
);
1997 return phtpriv
->ht_option
;
2000 /* the function is > passive_level (in critical_section) */
2001 void rtw_update_ht_cap(struct adapter
*padapter
, u8
*pie
, uint ie_len
)
2003 u8
*p
, max_ampdu_sz
;
2005 struct rtw_ieee80211_ht_cap
*pht_capie
;
2006 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2007 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
2008 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
2009 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2010 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
2012 if (!phtpriv
->ht_option
)
2015 if ((!pmlmeinfo
->HT_info_enable
) || (!pmlmeinfo
->HT_caps_enable
))
2018 DBG_88E("+rtw_update_ht_cap()\n");
2020 /* maybe needs check if ap supports rx ampdu. */
2021 if ((!phtpriv
->ampdu_enable
) && (pregistrypriv
->ampdu_enable
== 1)) {
2022 if (pregistrypriv
->wifi_spec
== 1)
2023 phtpriv
->ampdu_enable
= false;
2025 phtpriv
->ampdu_enable
= true;
2026 } else if (pregistrypriv
->ampdu_enable
== 2) {
2027 phtpriv
->ampdu_enable
= true;
2031 /* check Max Rx A-MPDU Size */
2033 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
));
2035 pht_capie
= (struct rtw_ieee80211_ht_cap
*)(p
+2);
2036 max_ampdu_sz
= pht_capie
->ampdu_params_info
& IEEE80211_HT_CAP_AMPDU_FACTOR
;
2037 max_ampdu_sz
= 1 << (max_ampdu_sz
+3); /* max_ampdu_sz (kbytes); */
2038 phtpriv
->rx_ampdu_maxlen
= max_ampdu_sz
;
2041 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
));
2043 /* update cur_bwmode & cur_ch_offset */
2044 if ((pregistrypriv
->cbw40_enable
) &&
2045 (le16_to_cpu(pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
) & BIT(1)) &&
2046 (pmlmeinfo
->HT_info
.infos
[0] & BIT(2))) {
2050 padapter
->HalFunc
.GetHwRegHandler(padapter
, HW_VAR_RF_TYPE
, (u8
*)(&rf_type
));
2052 /* update the MCS rates */
2053 for (i
= 0; i
< 16; i
++) {
2054 if ((rf_type
== RF_1T1R
) || (rf_type
== RF_1T2R
))
2055 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.MCS_rate
[i
] &= MCS_rate_1R
[i
];
2057 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.MCS_rate
[i
] &= MCS_rate_2R
[i
];
2059 /* switch to the 40M Hz mode according to the AP */
2060 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_40
;
2061 switch ((pmlmeinfo
->HT_info
.infos
[0] & 0x3)) {
2062 case HT_EXTCHNL_OFFSET_UPPER
:
2063 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_LOWER
;
2065 case HT_EXTCHNL_OFFSET_LOWER
:
2066 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_UPPER
;
2069 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
2074 /* Config SM Power Save setting */
2075 pmlmeinfo
->SM_PS
= (le16_to_cpu(pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
) & 0x0C) >> 2;
2076 if (pmlmeinfo
->SM_PS
== WLAN_HT_CAP_SM_PS_STATIC
)
2077 DBG_88E("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__
);
2079 /* Config current HT Protection mode. */
2080 pmlmeinfo
->HT_protection
= pmlmeinfo
->HT_info
.infos
[1] & 0x3;
2083 void rtw_issue_addbareq_cmd(struct adapter
*padapter
, struct xmit_frame
*pxmitframe
)
2087 struct sta_info
*psta
= NULL
;
2088 struct ht_priv
*phtpriv
;
2089 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
2090 s32 bmcst
= IS_MCAST(pattrib
->ra
);
2092 if (bmcst
|| (padapter
->mlmepriv
.LinkDetectInfo
.NumTxOkInPeriod
< 100))
2095 priority
= pattrib
->priority
;
2098 psta
= pattrib
->psta
;
2100 psta
= rtw_get_stainfo(&padapter
->stapriv
, pattrib
->ra
);
2105 phtpriv
= &psta
->htpriv
;
2107 if ((phtpriv
->ht_option
) && (phtpriv
->ampdu_enable
)) {
2108 issued
= (phtpriv
->agg_enable_bitmap
>>priority
)&0x1;
2109 issued
|= (phtpriv
->candidate_tid_bitmap
>>priority
)&0x1;
2112 DBG_88E("rtw_issue_addbareq_cmd, p=%d\n", priority
);
2113 psta
->htpriv
.candidate_tid_bitmap
|= BIT((u8
)priority
);
2114 rtw_addbareq_cmd(padapter
, (u8
)priority
, pattrib
->ra
);
2119 void rtw_roaming(struct adapter
*padapter
, struct wlan_network
*tgt_network
)
2121 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2123 spin_lock_bh(&pmlmepriv
->lock
);
2124 _rtw_roaming(padapter
, tgt_network
);
2125 spin_unlock_bh(&pmlmepriv
->lock
);
2127 void _rtw_roaming(struct adapter
*padapter
, struct wlan_network
*tgt_network
)
2129 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2132 struct wlan_network
*pnetwork
;
2134 if (tgt_network
!= NULL
)
2135 pnetwork
= tgt_network
;
2137 pnetwork
= &pmlmepriv
->cur_network
;
2139 if (0 < pmlmepriv
->to_roaming
) {
2140 DBG_88E("roaming from %s(%pM length:%d\n",
2141 pnetwork
->network
.Ssid
.Ssid
, pnetwork
->network
.MacAddress
,
2142 pnetwork
->network
.Ssid
.SsidLength
);
2143 memcpy(&pmlmepriv
->assoc_ssid
, &pnetwork
->network
.Ssid
, sizeof(struct ndis_802_11_ssid
));
2145 pmlmepriv
->assoc_by_bssid
= false;
2148 do_join_r
= rtw_do_join(padapter
);
2149 if (_SUCCESS
== do_join_r
) {
2152 DBG_88E("roaming do_join return %d\n", do_join_r
);
2153 pmlmepriv
->to_roaming
--;
2155 if (0 < pmlmepriv
->to_roaming
) {
2158 DBG_88E("%s(%d) -to roaming fail, indicate_disconnect\n", __func__
, __LINE__
);
2159 rtw_indicate_disconnect(padapter
);