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 <osdep_service.h>
18 #include <drv_types.h>
19 #include <recv_osdep.h>
20 #include <xmit_osdep.h>
22 #include <mlme_osdep.h>
24 #include <linux/ieee80211.h>
26 #include <wlan_bssdef.h>
27 #include <rtw_ioctl_set.h>
29 extern u8
rtw_do_join23a(struct rtw_adapter
* padapter
);
31 static void rtw_init_mlme_timer(struct rtw_adapter
*padapter
)
33 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
35 setup_timer(&pmlmepriv
->assoc_timer
, rtw23a_join_to_handler
,
36 (unsigned long)padapter
);
38 setup_timer(&pmlmepriv
->scan_to_timer
, rtw_scan_timeout_handler23a
,
39 (unsigned long)padapter
);
41 setup_timer(&pmlmepriv
->dynamic_chk_timer
,
42 rtw_dynamic_check_timer_handler
, (unsigned long)padapter
);
44 setup_timer(&pmlmepriv
->set_scan_deny_timer
,
45 rtw_set_scan_deny_timer_hdl
, (unsigned long)padapter
);
48 int rtw_init_mlme_priv23a(struct rtw_adapter
*padapter
)
50 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
53 pmlmepriv
->nic_hdl
= padapter
;
55 pmlmepriv
->fw_state
= 0;
56 pmlmepriv
->cur_network
.network
.InfrastructureMode
=
57 Ndis802_11AutoUnknown
;
58 /* 1: active, 0: pasive. Maybe someday we should rename this
59 varable to "active_mode" (Jeff) */
60 pmlmepriv
->scan_mode
= SCAN_ACTIVE
;
62 spin_lock_init(&pmlmepriv
->lock
);
63 _rtw_init_queue23a(&pmlmepriv
->scanned_queue
);
65 memset(&pmlmepriv
->assoc_ssid
, 0, sizeof(struct cfg80211_ssid
));
67 rtw_clear_scan_deny(padapter
);
69 rtw_init_mlme_timer(padapter
);
73 #ifdef CONFIG_8723AU_AP_MODE
74 static void rtw_free_mlme_ie_data(u8
**ppie
, u32
*plen
)
84 void rtw23a_free_mlme_priv_ie_data(struct mlme_priv
*pmlmepriv
)
86 #ifdef CONFIG_8723AU_AP_MODE
87 kfree(pmlmepriv
->assoc_req
);
88 kfree(pmlmepriv
->assoc_rsp
);
89 rtw_free_mlme_ie_data(&pmlmepriv
->wps_beacon_ie
,
90 &pmlmepriv
->wps_beacon_ie_len
);
91 rtw_free_mlme_ie_data(&pmlmepriv
->wps_probe_req_ie
,
92 &pmlmepriv
->wps_probe_req_ie_len
);
93 rtw_free_mlme_ie_data(&pmlmepriv
->wps_probe_resp_ie
,
94 &pmlmepriv
->wps_probe_resp_ie_len
);
95 rtw_free_mlme_ie_data(&pmlmepriv
->wps_assoc_resp_ie
,
96 &pmlmepriv
->wps_assoc_resp_ie_len
);
98 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_beacon_ie
,
99 &pmlmepriv
->p2p_beacon_ie_len
);
100 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_probe_req_ie
,
101 &pmlmepriv
->p2p_probe_req_ie_len
);
102 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_probe_resp_ie
,
103 &pmlmepriv
->p2p_probe_resp_ie_len
);
104 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_go_probe_resp_ie
,
105 &pmlmepriv
->p2p_go_probe_resp_ie_len
);
106 rtw_free_mlme_ie_data(&pmlmepriv
->p2p_assoc_req_ie
,
107 &pmlmepriv
->p2p_assoc_req_ie_len
);
109 rtw_free_mlme_ie_data(&pmlmepriv
->wfd_beacon_ie
,
110 &pmlmepriv
->wfd_beacon_ie_len
);
111 rtw_free_mlme_ie_data(&pmlmepriv
->wfd_probe_req_ie
,
112 &pmlmepriv
->wfd_probe_req_ie_len
);
113 rtw_free_mlme_ie_data(&pmlmepriv
->wfd_probe_resp_ie
,
114 &pmlmepriv
->wfd_probe_resp_ie_len
);
115 rtw_free_mlme_ie_data(&pmlmepriv
->wfd_go_probe_resp_ie
,
116 &pmlmepriv
->wfd_go_probe_resp_ie_len
);
117 rtw_free_mlme_ie_data(&pmlmepriv
->wfd_assoc_req_ie
,
118 &pmlmepriv
->wfd_assoc_req_ie_len
);
122 void rtw_free_mlme_priv23a(struct mlme_priv
*pmlmepriv
)
124 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
125 ("rtw_free_mlme_priv23a\n"));
127 rtw23a_free_mlme_priv_ie_data(pmlmepriv
);
130 struct wlan_network
*rtw_alloc_network(struct mlme_priv
*pmlmepriv
, int gfp
)
132 struct wlan_network
*pnetwork
;
134 pnetwork
= kzalloc(sizeof(struct wlan_network
), gfp
);
136 INIT_LIST_HEAD(&pnetwork
->list
);
137 pnetwork
->network_type
= 0;
138 pnetwork
->fixed
= false;
139 pnetwork
->last_scanned
= jiffies
;
141 pnetwork
->join_res
= 0;
147 static void _rtw_free_network23a(struct mlme_priv
*pmlmepriv
,
148 struct wlan_network
*pnetwork
)
153 if (pnetwork
->fixed
== true)
156 list_del_init(&pnetwork
->list
);
162 return the wlan_network with the matching addr
164 Shall be calle under atomic context... to avoid possible racing condition...
166 struct wlan_network
*
167 rtw_find_network23a(struct rtw_queue
*scanned_queue
, u8
*addr
)
169 struct list_head
*phead
, *plist
;
170 struct wlan_network
*pnetwork
= NULL
;
172 if (is_zero_ether_addr(addr
)) {
177 /* spin_lock_bh(&scanned_queue->lock); */
179 phead
= get_list_head(scanned_queue
);
182 while (plist
!= phead
) {
183 pnetwork
= container_of(plist
, struct wlan_network
, list
);
185 if (ether_addr_equal(addr
, pnetwork
->network
.MacAddress
))
194 /* spin_unlock_bh(&scanned_queue->lock); */
201 void rtw_free_network_queue23a(struct rtw_adapter
*padapter
)
203 struct list_head
*phead
, *plist
, *ptmp
;
204 struct wlan_network
*pnetwork
;
205 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
206 struct rtw_queue
*scanned_queue
= &pmlmepriv
->scanned_queue
;
208 spin_lock_bh(&scanned_queue
->lock
);
210 phead
= get_list_head(scanned_queue
);
212 list_for_each_safe(plist
, ptmp
, phead
) {
213 pnetwork
= container_of(plist
, struct wlan_network
, list
);
215 _rtw_free_network23a(pmlmepriv
, pnetwork
);
218 spin_unlock_bh(&scanned_queue
->lock
);
221 int rtw_if_up23a(struct rtw_adapter
*padapter
)
225 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
||
226 check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) == false) {
227 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
228 ("rtw_if_up23a:bDriverStopped(%d) OR "
229 "bSurpriseRemoved(%d)", padapter
->bDriverStopped
,
230 padapter
->bSurpriseRemoved
));
238 void rtw_generate_random_ibss23a(u8
* pibss
)
240 unsigned long curtime
= jiffies
;
242 pibss
[0] = 0x02; /* in ad-hoc mode bit1 must set to 1 */
245 pibss
[3] = curtime
& 0xff;/* p[0]; */
246 pibss
[4] = (curtime
>> 8) & 0xff;/* p[1]; */
247 pibss
[5] = (curtime
>> 16) & 0xff;/* p[2]; */
252 void rtw_set_roaming(struct rtw_adapter
*adapter
, u8 to_roaming
)
255 adapter
->mlmepriv
.to_join
= false;
256 adapter
->mlmepriv
.to_roaming
= to_roaming
;
259 static void _rtw_roaming(struct rtw_adapter
*padapter
,
260 struct wlan_network
*tgt_network
)
262 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
263 struct wlan_network
*pnetwork
;
267 pnetwork
= tgt_network
;
269 pnetwork
= &pmlmepriv
->cur_network
;
271 if (padapter
->mlmepriv
.to_roaming
> 0) {
272 DBG_8723A("roaming from %s("MAC_FMT
"), length:%d\n",
273 pnetwork
->network
.Ssid
.ssid
,
274 MAC_ARG(pnetwork
->network
.MacAddress
),
275 pnetwork
->network
.Ssid
.ssid_len
);
276 memcpy(&pmlmepriv
->assoc_ssid
, &pnetwork
->network
.Ssid
,
277 sizeof(struct cfg80211_ssid
));
279 pmlmepriv
->assoc_by_bssid
= false;
282 do_join_r
= rtw_do_join23a(padapter
);
283 if (do_join_r
== _SUCCESS
)
286 DBG_8723A("roaming do_join return %d\n",
288 pmlmepriv
->to_roaming
--;
290 if (padapter
->mlmepriv
.to_roaming
> 0)
293 DBG_8723A("%s(%d) -to roaming fail, "
294 "indicate_disconnect\n",
296 rtw_indicate_disconnect23a(padapter
);
304 void rtw23a_roaming(struct rtw_adapter
*padapter
,
305 struct wlan_network
*tgt_network
)
307 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
309 spin_lock_bh(&pmlmepriv
->lock
);
310 _rtw_roaming(padapter
, tgt_network
);
311 spin_unlock_bh(&pmlmepriv
->lock
);
314 __le16
*rtw_get_capability23a_from_ie(u8
*ie
)
316 return (__le16
*)(ie
+ 8 + 2);
319 u16
rtw_get_capability23a(struct wlan_bssid_ex
*bss
)
323 memcpy(&val
, rtw_get_capability23a_from_ie(bss
->IEs
), 2);
325 return le16_to_cpu(val
);
328 __le16
*rtw_get_beacon_interval23a_from_ie(u8
*ie
)
330 return (__le16
*)(ie
+ 8);
333 static void rtw_free_network_nolock(struct mlme_priv
*pmlmepriv
,
334 struct wlan_network
*pnetwork
)
336 _rtw_free_network23a(pmlmepriv
, pnetwork
);
339 int rtw_is_same_ibss23a(struct rtw_adapter
*adapter
,
340 struct wlan_network
*pnetwork
)
343 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
345 if (psecuritypriv
->dot11PrivacyAlgrthm
!= _NO_PRIVACY_
&&
346 pnetwork
->network
.Privacy
== 0)
348 else if (psecuritypriv
->dot11PrivacyAlgrthm
== _NO_PRIVACY_
&&
349 pnetwork
->network
.Privacy
== 1)
357 inline int is_same_ess(struct wlan_bssid_ex
*a
, struct wlan_bssid_ex
*b
);
358 inline int is_same_ess(struct wlan_bssid_ex
*a
, struct wlan_bssid_ex
*b
)
360 return (a
->Ssid
.ssid_len
== b
->Ssid
.ssid_len
) &&
361 !memcmp(a
->Ssid
.ssid
, b
->Ssid
.ssid
, a
->Ssid
.ssid_len
);
364 int is_same_network23a(struct wlan_bssid_ex
*src
, struct wlan_bssid_ex
*dst
)
368 s_cap
= get_unaligned_le16(rtw_get_capability23a_from_ie(src
->IEs
));
369 d_cap
= get_unaligned_le16(rtw_get_capability23a_from_ie(dst
->IEs
));
371 return ((src
->Ssid
.ssid_len
== dst
->Ssid
.ssid_len
) &&
372 /* (src->Configuration.DSConfig == dst->Configuration.DSConfig) && */
373 ether_addr_equal(src
->MacAddress
, dst
->MacAddress
) &&
374 ((!memcmp(src
->Ssid
.ssid
, dst
->Ssid
.ssid
, src
->Ssid
.ssid_len
))) &&
375 ((s_cap
& WLAN_CAPABILITY_IBSS
) ==
376 (d_cap
& WLAN_CAPABILITY_IBSS
)) &&
377 ((s_cap
& WLAN_CAPABILITY_ESS
) ==
378 (d_cap
& WLAN_CAPABILITY_ESS
)));
381 struct wlan_network
*
382 rtw_get_oldest_wlan_network23a(struct rtw_queue
*scanned_queue
)
384 struct list_head
*plist
, *phead
;
385 struct wlan_network
*pwlan
;
386 struct wlan_network
*oldest
= NULL
;
388 phead
= get_list_head(scanned_queue
);
390 list_for_each(plist
, phead
) {
391 pwlan
= container_of(plist
, struct wlan_network
, list
);
393 if (pwlan
->fixed
!= true) {
394 if (!oldest
|| time_after(oldest
->last_scanned
,
395 pwlan
->last_scanned
))
403 void update_network23a(struct wlan_bssid_ex
*dst
, struct wlan_bssid_ex
*src
,
404 struct rtw_adapter
*padapter
, bool update_ie
)
406 u8 ss_ori
= dst
->PhyInfo
.SignalStrength
;
407 u8 sq_ori
= dst
->PhyInfo
.SignalQuality
;
408 long rssi_ori
= dst
->Rssi
;
410 u8 ss_smp
= src
->PhyInfo
.SignalStrength
;
411 u8 sq_smp
= src
->PhyInfo
.SignalQuality
;
412 long rssi_smp
= src
->Rssi
;
418 DBG_8723A("%s %s(%pM, ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, "
419 "ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n",
420 __func__
, src
->Ssid
.ssid
, src
->MacAddress
,
421 src
->Configuration
.DSConfig
, ss_ori
, sq_ori
, rssi_ori
,
422 ss_smp
, sq_smp
, rssi_smp
425 /* The rule below is 1/5 for sample value, 4/5 for history value */
426 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) &&
427 is_same_network23a(&padapter
->mlmepriv
.cur_network
.network
, src
)) {
428 /* Take the recvpriv's value for the connected AP*/
429 ss_final
= padapter
->recvpriv
.signal_strength
;
430 sq_final
= padapter
->recvpriv
.signal_qual
;
431 /* the rssi value here is undecorated, and will be
432 used for antenna diversity */
433 if (sq_smp
!= 101) /* from the right channel */
434 rssi_final
= (src
->Rssi
+dst
->Rssi
*4)/5;
436 rssi_final
= rssi_ori
;
438 if (sq_smp
!= 101) { /* from the right channel */
439 ss_final
= ((u32
)src
->PhyInfo
.SignalStrength
+
440 (u32
)dst
->PhyInfo
.SignalStrength
* 4) / 5;
441 sq_final
= ((u32
)src
->PhyInfo
.SignalQuality
+
442 (u32
)dst
->PhyInfo
.SignalQuality
* 4) / 5;
443 rssi_final
= src
->Rssi
+dst
->Rssi
* 4 / 5;
445 /* bss info not receving from the right channel, use
446 the original RX signal infos */
447 ss_final
= dst
->PhyInfo
.SignalStrength
;
448 sq_final
= dst
->PhyInfo
.SignalQuality
;
449 rssi_final
= dst
->Rssi
;
455 memcpy(dst
, src
, get_wlan_bssid_ex_sz(src
));
457 dst
->PhyInfo
.SignalStrength
= ss_final
;
458 dst
->PhyInfo
.SignalQuality
= sq_final
;
459 dst
->Rssi
= rssi_final
;
461 DBG_8723A("%s %s(%pM), SignalStrength:%u, SignalQuality:%u, "
462 "RawRSSI:%ld\n", __func__
, dst
->Ssid
.ssid
, dst
->MacAddress
,
463 dst
->PhyInfo
.SignalStrength
,
464 dst
->PhyInfo
.SignalQuality
, dst
->Rssi
);
467 static void update_current_network(struct rtw_adapter
*adapter
,
468 struct wlan_bssid_ex
*pnetwork
)
470 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
472 if (check_fwstate(pmlmepriv
, _FW_LINKED
) &&
473 is_same_network23a(&pmlmepriv
->cur_network
.network
, pnetwork
)) {
474 update_network23a(&pmlmepriv
->cur_network
.network
,
475 pnetwork
,adapter
, true);
476 rtw_update_protection23a(adapter
,
477 pmlmepriv
->cur_network
.network
.IEs
+
478 sizeof (struct ndis_802_11_fixed_ies
),
479 pmlmepriv
->cur_network
.network
.IELength
);
485 Caller must hold pmlmepriv->lock first.
488 void rtw_update_scanned_network23a(struct rtw_adapter
*adapter
,
489 struct wlan_bssid_ex
*target
)
491 struct list_head
*plist
, *phead
;
492 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
493 struct wlan_network
*pnetwork
= NULL
;
494 struct wlan_network
*oldest
= NULL
;
495 struct rtw_queue
*queue
= &pmlmepriv
->scanned_queue
;
499 spin_lock_bh(&queue
->lock
);
500 phead
= get_list_head(queue
);
502 list_for_each(plist
, phead
) {
503 pnetwork
= container_of(plist
, struct wlan_network
, list
);
505 if (is_same_network23a(&pnetwork
->network
, target
)) {
509 if (!oldest
|| time_after(oldest
->last_scanned
,
510 pnetwork
->last_scanned
))
514 /* If we didn't find a match, then get a new network slot to initialize
515 * with this beacon's information */
517 pnetwork
= rtw_alloc_network(pmlmepriv
, GFP_ATOMIC
);
520 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
521 ("\n\n\nsomething wrong here\n\n\n"));
526 list_add_tail(&pnetwork
->list
, &queue
->queue
);
528 bssid_ex_sz
= get_wlan_bssid_ex_sz(target
);
529 target
->Length
= bssid_ex_sz
;
530 memcpy(&pnetwork
->network
, target
, bssid_ex_sz
);
532 /* variable initialize */
533 pnetwork
->fixed
= false;
534 pnetwork
->last_scanned
= jiffies
;
536 pnetwork
->network_type
= 0;
538 pnetwork
->join_res
= 0;
540 /* bss info not receving from the right channel */
541 if (pnetwork
->network
.PhyInfo
.SignalQuality
== 101)
542 pnetwork
->network
.PhyInfo
.SignalQuality
= 0;
545 * we have an entry and we are going to update it. But
546 * this entry may be already expired. In this case we
547 * do the same as we found a new net and call the
550 bool update_ie
= true;
552 pnetwork
->last_scanned
= jiffies
;
554 /* target.reserved == 1, means that scanned network is
556 if (pnetwork
->network
.IELength
> target
->IELength
&&
557 target
->reserved
== 1)
560 update_network23a(&pnetwork
->network
, target
,adapter
,
565 spin_unlock_bh(&queue
->lock
);
568 static void rtw_add_network(struct rtw_adapter
*adapter
,
569 struct wlan_bssid_ex
*pnetwork
)
571 update_current_network(adapter
, pnetwork
);
572 rtw_update_scanned_network23a(adapter
, pnetwork
);
575 /* select the desired network based on the capability of the (i)bss. */
576 /* check items: (1) security */
577 /* (2) network_type */
581 static int rtw_is_desired_network(struct rtw_adapter
*adapter
,
582 struct wlan_network
*pnetwork
)
584 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
585 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
589 /* u8 wps_ie[512]; */
592 int bselected
= true;
594 desired_encmode
= psecuritypriv
->ndisencryptstatus
;
595 privacy
= pnetwork
->network
.Privacy
;
597 if (check_fwstate(pmlmepriv
, WIFI_UNDER_WPS
)) {
598 if (rtw_get_wps_ie23a(pnetwork
->network
.IEs
+ _FIXED_IE_LENGTH_
,
599 pnetwork
->network
.IELength
-
600 _FIXED_IE_LENGTH_
, NULL
, &wps_ielen
))
605 if (adapter
->registrypriv
.wifi_spec
== 1) {
606 /* for correct flow of 8021X to do.... */
607 if (desired_encmode
== Ndis802_11EncryptionDisabled
&&
612 if (desired_encmode
!= Ndis802_11EncryptionDisabled
&&
614 DBG_8723A("desired_encmode: %d, privacy: %d\n",
615 desired_encmode
, privacy
);
619 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)) {
620 if (pnetwork
->network
.InfrastructureMode
!=
621 pmlmepriv
->cur_network
.network
.InfrastructureMode
)
628 /* TODO: Perry : For Power Management */
629 void rtw_atimdone_event_callback23a(struct rtw_adapter
*adapter
, const u8
*pbuf
)
631 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_err_
,("receive atimdone_evet\n"));
636 void rtw_survey_event_cb23a(struct rtw_adapter
*adapter
, const u8
*pbuf
)
639 struct wlan_bssid_ex
*pnetwork
;
640 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
642 pnetwork
= (struct wlan_bssid_ex
*)pbuf
;
644 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_info_
,
645 ("rtw_survey_event_cb23a, ssid=%s\n", pnetwork
->Ssid
.ssid
));
647 len
= get_wlan_bssid_ex_sz(pnetwork
);
648 if (len
> (sizeof(struct wlan_bssid_ex
))) {
649 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_err_
,
650 ("\n ****rtw_survey_event_cb23a: return a wrong "
655 spin_lock_bh(&pmlmepriv
->lock
);
657 /* update IBSS_network 's timestamp */
658 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) {
659 /* RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
660 "rtw_survey_event_cb23a : WIFI_ADHOC_MASTER_STATE\n\n"); */
661 if (ether_addr_equal(pmlmepriv
->cur_network
.network
.MacAddress
,
662 pnetwork
->MacAddress
)) {
663 struct wlan_network
* ibss_wlan
;
665 memcpy(pmlmepriv
->cur_network
.network
.IEs
,
667 spin_lock_bh(&pmlmepriv
->scanned_queue
.lock
);
668 ibss_wlan
= rtw_find_network23a(
669 &pmlmepriv
->scanned_queue
,
670 pnetwork
->MacAddress
);
672 memcpy(ibss_wlan
->network
.IEs
,
674 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
677 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
681 /* lock pmlmepriv->lock when you accessing network_q */
682 if (check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
) == false) {
683 if (pnetwork
->Ssid
.ssid
[0] == 0)
684 pnetwork
->Ssid
.ssid_len
= 0;
686 rtw_add_network(adapter
, pnetwork
);
691 spin_unlock_bh(&pmlmepriv
->lock
);
697 rtw_surveydone_event_callback23a(struct rtw_adapter
*adapter
, const u8
*pbuf
)
699 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
700 struct mlme_ext_priv
*pmlmeext
= &adapter
->mlmeextpriv
;
701 struct wlan_bssid_ex
*pdev_network
;
704 spin_lock_bh(&pmlmepriv
->lock
);
706 if (pmlmepriv
->wps_probe_req_ie
) {
707 pmlmepriv
->wps_probe_req_ie_len
= 0;
708 kfree(pmlmepriv
->wps_probe_req_ie
);
709 pmlmepriv
->wps_probe_req_ie
= NULL
;
712 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
713 ("rtw_surveydone_event_callback23a: fw_state:%x\n\n",
714 get_fwstate(pmlmepriv
)));
716 if (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
)) {
717 del_timer_sync(&pmlmepriv
->scan_to_timer
);
719 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
721 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
722 ("nic status =%x, survey done event comes too late!\n",
723 get_fwstate(pmlmepriv
)));
726 rtw_set_signal_stat_timer(&adapter
->recvpriv
);
728 if (pmlmepriv
->to_join
== true) {
729 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)) {
730 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == false) {
731 set_fwstate(pmlmepriv
, _FW_UNDER_LINKING
);
733 if (rtw_select_and_join_from_scanned_queue23a(
734 pmlmepriv
) == _SUCCESS
) {
735 mod_timer(&pmlmepriv
->assoc_timer
,
736 jiffies
+ msecs_to_jiffies(MAX_JOIN_TIMEOUT
));
738 pdev_network
= &adapter
->registrypriv
.dev_network
;
739 pibss
= adapter
->registrypriv
.dev_network
.MacAddress
;
741 _clr_fwstate_(pmlmepriv
,
744 RT_TRACE(_module_rtl871x_mlme_c_
,
746 ("switching to adhoc "
749 memset(&pdev_network
->Ssid
, 0,
750 sizeof(struct cfg80211_ssid
));
751 memcpy(&pdev_network
->Ssid
,
752 &pmlmepriv
->assoc_ssid
,
753 sizeof(struct cfg80211_ssid
));
755 rtw_update_registrypriv_dev_network23a(
757 rtw_generate_random_ibss23a(pibss
);
759 pmlmepriv
->fw_state
=
760 WIFI_ADHOC_MASTER_STATE
;
762 if (rtw_createbss_cmd23a(adapter
) !=
764 RT_TRACE(_module_rtl871x_mlme_c_
,
766 ("Error =>rtw_createbss_cmd23a"
769 pmlmepriv
->to_join
= false;
774 set_fwstate(pmlmepriv
, _FW_UNDER_LINKING
);
775 pmlmepriv
->to_join
= false;
776 ret
= rtw_select_and_join_from_scanned_queue23a(
778 if (ret
== _SUCCESS
) {
780 e
= msecs_to_jiffies(MAX_JOIN_TIMEOUT
);
781 mod_timer(&pmlmepriv
->assoc_timer
, jiffies
+ e
);
782 } else if (ret
== 2) {/* there is no need to wait */
783 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
784 rtw_indicate_connect23a(adapter
);
786 DBG_8723A("try_to_join, but select scanning "
787 "queue fail, to_roaming:%d\n",
788 adapter
->mlmepriv
.to_roaming
);
789 if (adapter
->mlmepriv
.to_roaming
) {
790 if (--pmlmepriv
->to_roaming
== 0 ||
791 rtw_sitesurvey_cmd23a(
793 &pmlmepriv
->assoc_ssid
, 1,
794 NULL
, 0) != _SUCCESS
) {
795 rtw_set_roaming(adapter
, 0);
796 rtw_free_assoc_resources23a(
798 rtw_indicate_disconnect23a(
801 pmlmepriv
->to_join
= true;
803 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
808 spin_unlock_bh(&pmlmepriv
->lock
);
810 rtw_os_xmit_schedule23a(adapter
);
812 if (pmlmeext
->sitesurvey_res
.bss_cnt
== 0)
813 rtw_hal_sreset_reset23a(adapter
);
815 rtw_cfg80211_surveydone_event_callback(adapter
);
818 void rtw_dummy_event_callback23a(struct rtw_adapter
*adapter
, const u8
*pbuf
)
822 void rtw23a_fwdbg_event_callback(struct rtw_adapter
*adapter
, const u8
*pbuf
)
826 static void free_scanqueue(struct mlme_priv
*pmlmepriv
)
828 struct wlan_network
*pnetwork
;
829 struct rtw_queue
*scan_queue
= &pmlmepriv
->scanned_queue
;
830 struct list_head
*plist
, *phead
, *ptemp
;
832 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
, ("+free_scanqueue\n"));
833 spin_lock_bh(&scan_queue
->lock
);
835 phead
= get_list_head(scan_queue
);
837 list_for_each_safe(plist
, ptemp
, phead
) {
838 list_del_init(plist
);
839 pnetwork
= container_of(plist
, struct wlan_network
, list
);
843 spin_unlock_bh(&scan_queue
->lock
);
847 *rtw_free_assoc_resources23a: the caller has to lock pmlmepriv->lock
849 void rtw_free_assoc_resources23a(struct rtw_adapter
*adapter
,
850 int lock_scanned_queue
)
852 struct wlan_network
* pwlan
;
853 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
854 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
855 struct wlan_network
*tgt_network
= &pmlmepriv
->cur_network
;
856 struct sta_info
* psta
;
858 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
859 ("+rtw_free_assoc_resources23a\n"));
860 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
861 ("tgt_network->network.MacAddress="MAC_FMT
" ssid=%s\n",
862 MAC_ARG(tgt_network
->network
.MacAddress
),
863 tgt_network
->network
.Ssid
.ssid
));
865 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
|WIFI_AP_STATE
)) {
866 psta
= rtw_get_stainfo23a(&adapter
->stapriv
,
867 tgt_network
->network
.MacAddress
);
869 spin_lock_bh(&pstapriv
->sta_hash_lock
);
870 rtw_free_stainfo23a(adapter
, psta
);
871 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
874 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
|
875 WIFI_ADHOC_MASTER_STATE
|WIFI_AP_STATE
)) {
876 rtw_free_all_stainfo23a(adapter
);
878 psta
= rtw_get_bcmc_stainfo23a(adapter
);
879 spin_lock_bh(&pstapriv
->sta_hash_lock
);
880 rtw_free_stainfo23a(adapter
, psta
);
881 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
883 rtw_init_bcmc_stainfo23a(adapter
);
886 if (lock_scanned_queue
)
887 spin_lock_bh(&pmlmepriv
->scanned_queue
.lock
);
889 pwlan
= rtw_find_network23a(&pmlmepriv
->scanned_queue
,
890 tgt_network
->network
.MacAddress
);
892 pwlan
->fixed
= false;
894 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_err_
,
895 ("rtw_free_assoc_resources23a : pwlan== NULL\n"));
897 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) &&
898 adapter
->stapriv
.asoc_sta_count
== 1)
899 rtw_free_network_nolock(pmlmepriv
, pwlan
);
901 if (lock_scanned_queue
)
902 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
904 pmlmepriv
->key_mask
= 0;
908 *rtw_indicate_connect23a: the caller has to lock pmlmepriv->lock
910 void rtw_indicate_connect23a(struct rtw_adapter
*padapter
)
912 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
914 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
915 ("+rtw_indicate_connect23a\n"));
917 pmlmepriv
->to_join
= false;
919 if (!check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
)) {
920 set_fwstate(pmlmepriv
, _FW_LINKED
);
922 rtw_led_control(padapter
, LED_CTL_LINK
);
924 rtw_cfg80211_indicate_connect(padapter
);
926 netif_carrier_on(padapter
->pnetdev
);
928 if (padapter
->pid
[2] != 0)
929 kill_pid(find_vpid(padapter
->pid
[2]), SIGALRM
, 1);
932 rtw_set_roaming(padapter
, 0);
934 rtw_set_scan_deny(padapter
, 3000);
936 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
937 ("-rtw_indicate_connect23a: fw_state=0x%08x\n",
938 get_fwstate(pmlmepriv
)));
942 *rtw_indicate_disconnect23a: the caller has to lock pmlmepriv->lock
944 void rtw_indicate_disconnect23a(struct rtw_adapter
*padapter
)
946 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
948 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
949 ("+rtw_indicate_disconnect23a\n"));
951 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
|WIFI_UNDER_WPS
);
953 /* DBG_8723A("clear wps when %s\n", __func__); */
955 if (padapter
->mlmepriv
.to_roaming
> 0)
956 _clr_fwstate_(pmlmepriv
, _FW_LINKED
);
958 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) ||
959 padapter
->mlmepriv
.to_roaming
<= 0) {
960 rtw_os_indicate_disconnect23a(padapter
);
962 /* set ips_deny_time to avoid enter IPS before LPS leave */
963 padapter
->pwrctrlpriv
.ips_deny_time
=
964 jiffies
+ msecs_to_jiffies(3000);
966 _clr_fwstate_(pmlmepriv
, _FW_LINKED
);
968 rtw_led_control(padapter
, LED_CTL_NO_LINK
);
970 rtw_clear_scan_deny(padapter
);
974 rtw_lps_ctrl_wk_cmd23a(padapter
, LPS_CTRL_DISCONNECT
, 1);
977 void rtw_scan_abort23a(struct rtw_adapter
*adapter
)
980 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
981 struct mlme_ext_priv
*pmlmeext
= &adapter
->mlmeextpriv
;
984 pmlmeext
->scan_abort
= true;
985 while (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
) &&
986 jiffies_to_msecs(jiffies
- start
) <= 200) {
987 if (adapter
->bDriverStopped
|| adapter
->bSurpriseRemoved
)
990 DBG_8723A(FUNC_NDEV_FMT
"fw_state = _FW_UNDER_SURVEY!\n",
991 FUNC_NDEV_ARG(adapter
->pnetdev
));
995 if (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
)) {
996 if (!adapter
->bDriverStopped
&& !adapter
->bSurpriseRemoved
)
997 DBG_8723A(FUNC_NDEV_FMT
"waiting for scan_abort time "
998 "out!\n", FUNC_NDEV_ARG(adapter
->pnetdev
));
999 rtw_cfg80211_indicate_scan_done(wdev_to_priv(adapter
->rtw_wdev
),
1002 pmlmeext
->scan_abort
= false;
1005 static struct sta_info
*
1006 rtw_joinbss_update_stainfo(struct rtw_adapter
*padapter
,
1007 struct wlan_network
*pnetwork
)
1010 struct sta_info
*bmc_sta
, *psta
;
1011 struct recv_reorder_ctrl
*preorder_ctrl
;
1012 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1014 psta
= rtw_get_stainfo23a(pstapriv
, pnetwork
->network
.MacAddress
);
1016 psta
= rtw_alloc_stainfo23a(pstapriv
,
1017 pnetwork
->network
.MacAddress
,
1020 if (psta
) { /* update ptarget_sta */
1021 DBG_8723A("%s\n", __func__
);
1023 psta
->aid
= pnetwork
->join_res
;
1027 rtw_hal_set_odm_var23a(padapter
, HAL_ODM_STA_INFO
, psta
, true);
1029 /* security related */
1030 if (padapter
->securitypriv
.dot11AuthAlgrthm
==
1031 dot11AuthAlgrthm_8021X
) {
1032 padapter
->securitypriv
.binstallGrpkey
= false;
1033 padapter
->securitypriv
.busetkipkey
= false;
1034 padapter
->securitypriv
.bgrpkey_handshake
= false;
1036 psta
->ieee8021x_blocked
= true;
1037 psta
->dot118021XPrivacy
=
1038 padapter
->securitypriv
.dot11PrivacyAlgrthm
;
1040 memset(&psta
->dot118021x_UncstKey
, 0,
1041 sizeof (union Keytype
));
1043 memset(&psta
->dot11tkiprxmickey
, 0,
1044 sizeof (union Keytype
));
1045 memset(&psta
->dot11tkiptxmickey
, 0,
1046 sizeof (union Keytype
));
1048 memset(&psta
->dot11txpn
, 0, sizeof (union pn48
));
1049 memset(&psta
->dot11rxpn
, 0, sizeof (union pn48
));
1052 /* Commented by Albert 2012/07/21 */
1053 /* When doing the WPS, the wps_ie_len won't equal to 0 */
1054 /* And the Wi-Fi driver shouldn't allow the data packet
1055 to be tramsmitted. */
1056 if (padapter
->securitypriv
.wps_ie_len
!= 0) {
1057 psta
->ieee8021x_blocked
= true;
1058 padapter
->securitypriv
.wps_ie_len
= 0;
1061 /* for A-MPDU Rx reordering buffer control for bmc_sta &
1063 /* if A-MPDU Rx is enabled, reseting
1064 rx_ordering_ctrl wstart_b(indicate_seq) to default
1066 /* todo: check if AP can send A-MPDU packets */
1067 for (i
= 0; i
< 16 ; i
++) {
1068 /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
1069 preorder_ctrl
= &psta
->recvreorder_ctrl
[i
];
1070 preorder_ctrl
->enable
= false;
1071 preorder_ctrl
->indicate_seq
= 0xffff;
1072 preorder_ctrl
->wend_b
= 0xffff;
1073 /* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
1074 preorder_ctrl
->wsize_b
= 64;
1077 bmc_sta
= rtw_get_bcmc_stainfo23a(padapter
);
1079 for (i
= 0; i
< 16 ; i
++) {
1080 preorder_ctrl
= &bmc_sta
->recvreorder_ctrl
[i
];
1081 preorder_ctrl
->enable
= false;
1082 preorder_ctrl
->indicate_seq
= 0xffff;
1083 preorder_ctrl
->wend_b
= 0xffff;
1084 /* max_ampdu_sz; ex. 32(kbytes) ->
1086 preorder_ctrl
->wsize_b
= 64;
1091 update_sta_info23a(padapter
, psta
);
1098 /* pnetwork : returns from rtw23a_joinbss_event_cb */
1099 /* ptarget_wlan: found from scanned_queue */
1101 rtw_joinbss_update_network23a(struct rtw_adapter
*padapter
,
1102 struct wlan_network
*ptarget_wlan
,
1103 struct wlan_network
*pnetwork
)
1105 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1106 struct wlan_network
*cur_network
= &pmlmepriv
->cur_network
;
1108 DBG_8723A("%s\n", __func__
);
1110 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
1111 ("\nfw_state:%x, BSSID:"MAC_FMT
"\n", get_fwstate(pmlmepriv
),
1112 MAC_ARG(pnetwork
->network
.MacAddress
)));
1114 /* why not use ptarget_wlan?? */
1115 memcpy(&cur_network
->network
, &pnetwork
->network
,
1116 pnetwork
->network
.Length
);
1117 /* some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
1118 cur_network
->network
.IELength
= ptarget_wlan
->network
.IELength
;
1119 memcpy(&cur_network
->network
.IEs
[0], &ptarget_wlan
->network
.IEs
[0],
1122 cur_network
->aid
= pnetwork
->join_res
;
1124 rtw_set_signal_stat_timer(&padapter
->recvpriv
);
1125 padapter
->recvpriv
.signal_strength
=
1126 ptarget_wlan
->network
.PhyInfo
.SignalStrength
;
1127 padapter
->recvpriv
.signal_qual
=
1128 ptarget_wlan
->network
.PhyInfo
.SignalQuality
;
1130 * the ptarget_wlan->network.Rssi is raw data, we use
1131 * ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled)
1133 padapter
->recvpriv
.rssi
= translate_percentage_to_dbm(
1134 ptarget_wlan
->network
.PhyInfo
.SignalStrength
);
1135 DBG_8723A("%s signal_strength:%3u, rssi:%3d, signal_qual:%3u\n",
1136 __func__
, padapter
->recvpriv
.signal_strength
,
1137 padapter
->recvpriv
.rssi
, padapter
->recvpriv
.signal_qual
);
1138 rtw_set_signal_stat_timer(&padapter
->recvpriv
);
1140 /* update fw_state will clr _FW_UNDER_LINKING here indirectly */
1141 switch (pnetwork
->network
.InfrastructureMode
) {
1142 case Ndis802_11Infrastructure
:
1143 if (pmlmepriv
->fw_state
&WIFI_UNDER_WPS
)
1144 pmlmepriv
->fw_state
= WIFI_STATION_STATE
|WIFI_UNDER_WPS
;
1146 pmlmepriv
->fw_state
= WIFI_STATION_STATE
;
1148 case Ndis802_11IBSS
:
1149 pmlmepriv
->fw_state
= WIFI_ADHOC_STATE
;
1152 pmlmepriv
->fw_state
= WIFI_NULL_STATE
;
1153 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1154 ("Invalid network_mode\n"));
1158 rtw_update_protection23a(padapter
, cur_network
->network
.IEs
+
1159 sizeof (struct ndis_802_11_fixed_ies
),
1160 cur_network
->network
.IELength
);
1162 rtw_update_ht_cap23a(padapter
, cur_network
->network
.IEs
,
1163 cur_network
->network
.IELength
);
1168 * the fucntion could be > passive_level (the same context as Rx tasklet)
1169 * pnetwork : returns from rtw23a_joinbss_event_cb
1170 * ptarget_wlan: found from scanned_queue
1171 * if join_res > 0, for (fw_state==WIFI_STATION_STATE),
1172 * we check if "ptarget_sta" & "ptarget_wlan" exist.
1173 * if join_res > 0, for (fw_state==WIFI_ADHOC_STATE),
1174 * we only check if "ptarget_wlan" exist.
1175 * if join_res > 0, update "cur_network->network" from "pnetwork->network"
1176 * if (ptarget_wlan !=NULL).
1179 void rtw_joinbss_event_prehandle23a(struct rtw_adapter
*adapter
, u8
*pbuf
)
1181 struct sta_info
*ptarget_sta
, *pcur_sta
;
1182 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
1183 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1184 struct wlan_network
*pnetwork
= (struct wlan_network
*)pbuf
;
1185 struct wlan_network
*cur_network
= &pmlmepriv
->cur_network
;
1186 struct wlan_network
*pcur_wlan
, *ptarget_wlan
= NULL
;
1187 bool the_same_macaddr
;
1189 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_info_
,
1190 ("joinbss event call back received with res=%d\n",
1191 pnetwork
->join_res
));
1193 rtw_get_encrypt_decrypt_from_registrypriv23a(adapter
);
1195 if (pmlmepriv
->assoc_ssid
.ssid_len
== 0) {
1196 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_err_
,
1197 ("@@@@@ joinbss event call back for Any SSid\n"));
1199 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_err_
,
1200 ("@@@@@ rtw23a_joinbss_event_cb for SSid:%s\n",
1201 pmlmepriv
->assoc_ssid
.ssid
));
1204 if (ether_addr_equal(pnetwork
->network
.MacAddress
,
1205 cur_network
->network
.MacAddress
))
1206 the_same_macaddr
= true;
1208 the_same_macaddr
= false;
1210 pnetwork
->network
.Length
= get_wlan_bssid_ex_sz(&pnetwork
->network
);
1211 if (pnetwork
->network
.Length
> sizeof(struct wlan_bssid_ex
)) {
1212 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_err_
,
1213 ("\n\n ***joinbss_evt_callback return a wrong bss "
1218 spin_lock_bh(&pmlmepriv
->lock
);
1220 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_info_
,
1221 ("\n rtw23a_joinbss_event_cb !! _enter_critical\n"));
1223 if (pnetwork
->join_res
> 0) {
1224 spin_lock_bh(&pmlmepriv
->scanned_queue
.lock
);
1225 if (check_fwstate(pmlmepriv
,_FW_UNDER_LINKING
)) {
1226 /* s1. find ptarget_wlan */
1227 if (check_fwstate(pmlmepriv
, _FW_LINKED
)) {
1228 if (the_same_macaddr
== true) {
1229 ptarget_wlan
= rtw_find_network23a(&pmlmepriv
->scanned_queue
, cur_network
->network
.MacAddress
);
1231 pcur_wlan
= rtw_find_network23a(&pmlmepriv
->scanned_queue
, cur_network
->network
.MacAddress
);
1233 pcur_wlan
->fixed
= false;
1235 pcur_sta
= rtw_get_stainfo23a(pstapriv
, cur_network
->network
.MacAddress
);
1237 spin_lock_bh(&pstapriv
->sta_hash_lock
);
1238 rtw_free_stainfo23a(adapter
,
1240 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
1243 ptarget_wlan
= rtw_find_network23a(&pmlmepriv
->scanned_queue
, pnetwork
->network
.MacAddress
);
1244 if (check_fwstate(pmlmepriv
,
1245 WIFI_STATION_STATE
)) {
1247 ptarget_wlan
->fixed
=
1253 ptarget_wlan
= rtw_find_network23a(
1254 &pmlmepriv
->scanned_queue
,
1255 pnetwork
->network
.MacAddress
);
1256 if (check_fwstate(pmlmepriv
,
1257 WIFI_STATION_STATE
)) {
1259 ptarget_wlan
->fixed
= true;
1263 /* s2. update cur_network */
1265 rtw_joinbss_update_network23a(adapter
,
1269 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_err_
,
1270 ("Can't find ptarget_wlan when "
1271 "joinbss_event callback\n"));
1272 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1273 goto ignore_joinbss_callback
;
1276 /* s3. find ptarget_sta & update ptarget_sta after
1277 update cur_network only for station mode */
1278 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
)) {
1279 ptarget_sta
= rtw_joinbss_update_stainfo(
1282 RT_TRACE(_module_rtl871x_mlme_c_
,
1284 ("Can't update stainfo when "
1285 "joinbss_event callback\n"));
1286 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1287 goto ignore_joinbss_callback
;
1291 /* s4. indicate connect */
1292 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
))
1293 rtw_indicate_connect23a(adapter
);
1295 /* adhoc mode will rtw_indicate_connect23a
1296 when rtw_stassoc_event_callback23a */
1297 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_info_
,
1298 ("adhoc mode, fw_state:%x",
1299 get_fwstate(pmlmepriv
)));
1302 /* s5. Cancle assoc_timer */
1303 del_timer_sync(&pmlmepriv
->assoc_timer
);
1305 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_info_
,
1306 ("Cancle assoc_timer\n"));
1308 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1309 ("rtw23a_joinbss_event_cb err: fw_state:%x",
1310 get_fwstate(pmlmepriv
)));
1311 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1312 goto ignore_joinbss_callback
;
1314 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1315 } else if (pnetwork
->join_res
== -4) {
1316 rtw_reset_securitypriv23a(adapter
);
1317 mod_timer(&pmlmepriv
->assoc_timer
,
1318 jiffies
+ msecs_to_jiffies(1));
1320 /* rtw_free_assoc_resources23a(adapter, 1); */
1322 if (check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
)) {
1323 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1324 ("fail! clear _FW_UNDER_LINKING ^^^fw_state="
1325 "%x\n", get_fwstate(pmlmepriv
)));
1326 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
1329 /* if join_res < 0 (join fails), then try again */
1330 mod_timer(&pmlmepriv
->assoc_timer
,
1331 jiffies
+ msecs_to_jiffies(1));
1332 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
1335 ignore_joinbss_callback
:
1337 spin_unlock_bh(&pmlmepriv
->lock
);
1340 void rtw23a_joinbss_event_cb(struct rtw_adapter
*adapter
, const u8
*pbuf
)
1342 struct wlan_network
*pnetwork
= (struct wlan_network
*)pbuf
;
1344 mlmeext_joinbss_event_callback23a(adapter
, pnetwork
->join_res
);
1346 rtw_os_xmit_schedule23a(adapter
);
1349 void rtw_stassoc_event_callback23a(struct rtw_adapter
*adapter
, const u8
*pbuf
)
1351 struct sta_info
*psta
;
1352 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1353 struct stassoc_event
*pstassoc
= (struct stassoc_event
*)pbuf
;
1354 struct wlan_network
*cur_network
= &pmlmepriv
->cur_network
;
1355 struct wlan_network
*ptarget_wlan
;
1357 if (rtw_access_ctrl23a(adapter
, pstassoc
->macaddr
) == false)
1360 #ifdef CONFIG_8723AU_AP_MODE
1361 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1362 psta
= rtw_get_stainfo23a(&adapter
->stapriv
, pstassoc
->macaddr
);
1364 /* bss_cap_update_on_sta_join23a(adapter, psta); */
1365 /* sta_info_update23a(adapter, psta); */
1366 ap_sta_info_defer_update23a(adapter
, psta
);
1371 /* for AD-HOC mode */
1372 psta
= rtw_get_stainfo23a(&adapter
->stapriv
, pstassoc
->macaddr
);
1374 /* the sta have been in sta_info_queue => do nothing */
1375 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_err_
,
1376 ("Error: rtw_stassoc_event_callback23a: sta has "
1377 "been in sta_hash_queue\n"));
1378 /* between drv has received this event before and
1379 fw have not yet to set key to CAM_ENTRY) */
1383 psta
= rtw_alloc_stainfo23a(&adapter
->stapriv
, pstassoc
->macaddr
,
1386 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_err_
,
1387 ("Can't alloc sta_info when "
1388 "rtw_stassoc_event_callback23a\n"));
1392 /* to do : init sta_info variable */
1393 psta
->qos_option
= 0;
1394 psta
->mac_id
= (uint
)pstassoc
->cam_id
;
1395 /* psta->aid = (uint)pstassoc->cam_id; */
1396 DBG_8723A("%s\n",__func__
);
1397 /* for ad-hoc mode */
1398 rtw_hal_set_odm_var23a(adapter
, HAL_ODM_STA_INFO
, psta
, true);
1400 if (adapter
->securitypriv
.dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
)
1401 psta
->dot118021XPrivacy
=
1402 adapter
->securitypriv
.dot11PrivacyAlgrthm
;
1404 psta
->ieee8021x_blocked
= false;
1406 spin_lock_bh(&pmlmepriv
->lock
);
1408 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) ||
1409 check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)) {
1410 if (adapter
->stapriv
.asoc_sta_count
== 2) {
1411 spin_lock_bh(&pmlmepriv
->scanned_queue
.lock
);
1413 rtw_find_network23a(&pmlmepriv
->scanned_queue
,
1414 cur_network
->network
.MacAddress
);
1416 ptarget_wlan
->fixed
= true;
1417 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1418 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1419 rtw_indicate_connect23a(adapter
);
1423 spin_unlock_bh(&pmlmepriv
->lock
);
1425 mlmeext_sta_add_event_callback23a(adapter
, psta
);
1428 void rtw_stadel_event_callback23a(struct rtw_adapter
*adapter
, const u8
*pbuf
)
1431 struct sta_info
*psta
;
1432 struct wlan_network
* pwlan
;
1433 struct wlan_bssid_ex
*pdev_network
;
1435 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1436 struct stadel_event
*pstadel
= (struct stadel_event
*)pbuf
;
1437 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
1438 struct wlan_network
*tgt_network
= &pmlmepriv
->cur_network
;
1440 psta
= rtw_get_stainfo23a(&adapter
->stapriv
, pstadel
->macaddr
);
1442 mac_id
= psta
->mac_id
;
1444 mac_id
= pstadel
->mac_id
;
1446 DBG_8723A("%s(mac_id=%d)=" MAC_FMT
"\n", __func__
, mac_id
,
1447 MAC_ARG(pstadel
->macaddr
));
1449 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
))
1452 mlmeext_sta_del_event_callback23a(adapter
);
1454 spin_lock_bh(&pmlmepriv
->lock
);
1456 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
)) {
1457 if (adapter
->mlmepriv
.to_roaming
> 0) {
1458 /* this stadel_event is caused by roaming,
1459 decrease to_roaming */
1460 pmlmepriv
->to_roaming
--;
1461 } else if (adapter
->mlmepriv
.to_roaming
== 0)
1462 rtw_set_roaming(adapter
, adapter
->registrypriv
.max_roaming_times
);
1463 if (*((u16
*)pstadel
->rsvd
) != WLAN_REASON_EXPIRATION_CHK
)
1464 rtw_set_roaming(adapter
, 0); /* don't roam */
1466 rtw_free_uc_swdec_pending_queue23a(adapter
);
1468 rtw_free_assoc_resources23a(adapter
, 1);
1469 rtw_indicate_disconnect23a(adapter
);
1470 spin_lock_bh(&pmlmepriv
->scanned_queue
.lock
);
1471 /* remove the network entry in scanned_queue */
1472 pwlan
= rtw_find_network23a(&pmlmepriv
->scanned_queue
,
1473 tgt_network
->network
.MacAddress
);
1475 pwlan
->fixed
= false;
1476 rtw_free_network_nolock(pmlmepriv
, pwlan
);
1478 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1480 _rtw_roaming(adapter
, tgt_network
);
1483 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) ||
1484 check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)) {
1486 spin_lock_bh(&pstapriv
->sta_hash_lock
);
1487 rtw_free_stainfo23a(adapter
, psta
);
1488 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
1490 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1491 if (adapter
->stapriv
.asoc_sta_count
== 1) {
1492 spin_lock_bh(&pmlmepriv
->scanned_queue
.lock
);
1493 /* free old ibss network */
1494 /* pwlan = rtw_find_network23a(
1495 &pmlmepriv->scanned_queue, pstadel->macaddr); */
1496 pwlan
= rtw_find_network23a(&pmlmepriv
->scanned_queue
,
1497 tgt_network
->network
.MacAddress
);
1499 pwlan
->fixed
= false;
1500 rtw_free_network_nolock(pmlmepriv
, pwlan
);
1502 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1503 /* re-create ibss */
1504 pdev_network
= &adapter
->registrypriv
.dev_network
;
1505 pibss
= adapter
->registrypriv
.dev_network
.MacAddress
;
1507 memcpy(pdev_network
, &tgt_network
->network
,
1508 get_wlan_bssid_ex_sz(&tgt_network
->network
));
1510 memset(&pdev_network
->Ssid
, 0,
1511 sizeof(struct cfg80211_ssid
));
1512 memcpy(&pdev_network
->Ssid
, &pmlmepriv
->assoc_ssid
,
1513 sizeof(struct cfg80211_ssid
));
1515 rtw_update_registrypriv_dev_network23a(adapter
);
1517 rtw_generate_random_ibss23a(pibss
);
1519 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)) {
1520 set_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
);
1521 _clr_fwstate_(pmlmepriv
, WIFI_ADHOC_STATE
);
1524 if (rtw_createbss_cmd23a(adapter
) != _SUCCESS
) {
1525 RT_TRACE(_module_rtl871x_ioctl_set_c_
,
1527 ("***Error =>stadel_event_callback: "
1528 "rtw_createbss_cmd23a status "
1534 spin_unlock_bh(&pmlmepriv
->lock
);
1537 void rtw_cpwm_event_callback23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
1539 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1540 ("+rtw_cpwm_event_callback23a !!!\n"));
1544 * rtw23a_join_to_handler - Timeout/faliure handler for CMD JoinBss
1545 * @adapter: pointer to _adapter structure
1547 void rtw23a_join_to_handler (unsigned long data
)
1549 struct rtw_adapter
*adapter
= (struct rtw_adapter
*)data
;
1550 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1553 DBG_8723A("%s, fw_state=%x\n", __func__
, get_fwstate(pmlmepriv
));
1555 if (adapter
->bDriverStopped
||adapter
->bSurpriseRemoved
)
1558 spin_lock_bh(&pmlmepriv
->lock
);
1560 if (adapter
->mlmepriv
.to_roaming
> 0) {
1561 /* join timeout caused by roaming */
1563 pmlmepriv
->to_roaming
--;
1564 if (adapter
->mlmepriv
.to_roaming
!= 0) {
1566 DBG_8723A("%s try another roaming\n", __func__
);
1567 do_join_r
= rtw_do_join23a(adapter
);
1568 if (do_join_r
!= _SUCCESS
) {
1569 DBG_8723A("%s roaming do_join return "
1570 "%d\n", __func__
, do_join_r
);
1575 DBG_8723A("%s We've try roaming but fail\n",
1577 rtw_indicate_disconnect23a(adapter
);
1582 rtw_indicate_disconnect23a(adapter
);
1583 free_scanqueue(pmlmepriv
);/* */
1585 /* indicate disconnect for the case that join_timeout and
1586 check_fwstate != FW_LINKED */
1587 rtw_cfg80211_indicate_disconnect(adapter
);
1590 spin_unlock_bh(&pmlmepriv
->lock
);
1595 * rtw_scan_timeout_handler23a - Timeout/Faliure handler for CMD SiteSurvey
1596 * @data: pointer to _adapter structure
1598 void rtw_scan_timeout_handler23a(unsigned long data
)
1600 struct rtw_adapter
*adapter
= (struct rtw_adapter
*)data
;
1601 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1603 DBG_8723A("%s(%s): fw_state =%x\n", __func__
, adapter
->pnetdev
->name
,
1604 get_fwstate(pmlmepriv
));
1606 spin_lock_bh(&pmlmepriv
->lock
);
1608 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
1610 spin_unlock_bh(&pmlmepriv
->lock
);
1612 rtw_cfg80211_indicate_scan_done(wdev_to_priv(adapter
->rtw_wdev
), true);
1615 static void rtw_auto_scan_handler(struct rtw_adapter
*padapter
)
1617 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1619 /* auto site survey per 60sec */
1620 if (pmlmepriv
->scan_interval
> 0) {
1621 pmlmepriv
->scan_interval
--;
1622 if (pmlmepriv
->scan_interval
== 0) {
1623 DBG_8723A("%s\n", __func__
);
1624 rtw_set_802_11_bssid23a_list_scan(padapter
, NULL
, 0);
1625 /* 30*2 sec = 60sec */
1626 pmlmepriv
->scan_interval
= SCAN_INTERVAL
;
1631 void rtw_dynamic_check_timer_handler(unsigned long data
)
1633 struct rtw_adapter
*adapter
= (struct rtw_adapter
*)data
;
1634 struct registry_priv
*pregistrypriv
= &adapter
->registrypriv
;
1636 if (adapter
->hw_init_completed
== false)
1639 if (adapter
->bDriverStopped
== true ||
1640 adapter
->bSurpriseRemoved
== true)
1643 if (adapter
->net_closed
== true)
1646 rtw_dynamic_chk_wk_cmd23a(adapter
);
1648 if (pregistrypriv
->wifi_spec
== 1) {
1649 /* auto site survey */
1650 rtw_auto_scan_handler(adapter
);
1653 mod_timer(&adapter
->mlmepriv
.dynamic_chk_timer
,
1654 jiffies
+ msecs_to_jiffies(2000));
1657 inline bool rtw_is_scan_deny(struct rtw_adapter
*adapter
)
1659 struct mlme_priv
*mlmepriv
= &adapter
->mlmepriv
;
1660 return (atomic_read(&mlmepriv
->set_scan_deny
) != 0) ? true : false;
1663 void rtw_clear_scan_deny(struct rtw_adapter
*adapter
)
1665 struct mlme_priv
*mlmepriv
= &adapter
->mlmepriv
;
1666 atomic_set(&mlmepriv
->set_scan_deny
, 0);
1669 void rtw_set_scan_deny_timer_hdl(unsigned long data
)
1671 struct rtw_adapter
*adapter
= (struct rtw_adapter
*)data
;
1672 rtw_clear_scan_deny(adapter
);
1675 void rtw_set_scan_deny(struct rtw_adapter
*adapter
, u32 ms
)
1677 struct mlme_priv
*mlmepriv
= &adapter
->mlmepriv
;
1679 atomic_set(&mlmepriv
->set_scan_deny
, 1);
1680 mod_timer(&mlmepriv
->set_scan_deny_timer
,
1681 jiffies
+ msecs_to_jiffies(ms
));
1684 #if defined(IEEE80211_SCAN_RESULT_EXPIRE)
1685 #define RTW_SCAN_RESULT_EXPIRE IEEE80211_SCAN_RESULT_EXPIRE/HZ*1000 -1000 /* 3000 -1000 */
1687 #define RTW_SCAN_RESULT_EXPIRE 2000
1691 * Select a new join candidate from the original @param candidate and
1693 * @return true: candidate is updated
1694 * @return false: candidate is not updated
1696 static int rtw_check_join_candidate(struct mlme_priv
*pmlmepriv
,
1697 struct wlan_network
**candidate
,
1698 struct wlan_network
*competitor
)
1700 int updated
= false;
1701 struct rtw_adapter
*adapter
;
1703 adapter
= container_of(pmlmepriv
, struct rtw_adapter
, mlmepriv
);
1705 /* check bssid, if needed */
1706 if (pmlmepriv
->assoc_by_bssid
== true) {
1707 if (!ether_addr_equal(competitor
->network
.MacAddress
,
1708 pmlmepriv
->assoc_bssid
))
1712 /* check ssid, if needed */
1713 if (pmlmepriv
->assoc_ssid
.ssid_len
) {
1714 if (competitor
->network
.Ssid
.ssid_len
!=
1715 pmlmepriv
->assoc_ssid
.ssid_len
||
1716 memcmp(competitor
->network
.Ssid
.ssid
,
1717 pmlmepriv
->assoc_ssid
.ssid
,
1718 pmlmepriv
->assoc_ssid
.ssid_len
))
1722 if (rtw_is_desired_network(adapter
, competitor
) == false)
1725 if (adapter
->mlmepriv
.to_roaming
> 0) {
1726 unsigned int passed
;
1728 passed
= jiffies_to_msecs(jiffies
- competitor
->last_scanned
);
1729 if (passed
>= RTW_SCAN_RESULT_EXPIRE
||
1730 is_same_ess(&competitor
->network
,
1731 &pmlmepriv
->cur_network
.network
) == false)
1736 (*candidate
)->network
.Rssi
<competitor
->network
.Rssi
) {
1737 *candidate
= competitor
;
1742 DBG_8723A("[by_bssid:%u][assoc_ssid:%s][to_roaming:%u] "
1743 "new candidate: %s("MAC_FMT
") rssi:%d\n",
1744 pmlmepriv
->assoc_by_bssid
,
1745 pmlmepriv
->assoc_ssid
.ssid
,
1746 adapter
->mlmepriv
.to_roaming
,
1747 (*candidate
)->network
.Ssid
.ssid
,
1748 MAC_ARG((*candidate
)->network
.MacAddress
),
1749 (int)(*candidate
)->network
.Rssi
);
1758 The caller of the sub-routine will be in critical section...
1760 The caller must hold the following spinlock
1766 int rtw_select_and_join_from_scanned_queue23a(struct mlme_priv
*pmlmepriv
)
1769 struct list_head
*phead
, *plist
, *ptmp
;
1770 struct rtw_adapter
*adapter
;
1771 struct rtw_queue
*queue
= &pmlmepriv
->scanned_queue
;
1772 struct wlan_network
*pnetwork
;
1773 struct wlan_network
*candidate
= NULL
;
1775 spin_lock_bh(&pmlmepriv
->scanned_queue
.lock
);
1776 phead
= get_list_head(queue
);
1777 adapter
= pmlmepriv
->nic_hdl
;
1779 list_for_each_safe(plist
, ptmp
, phead
) {
1780 pnetwork
= container_of(plist
, struct wlan_network
, list
);
1782 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1783 ("%s return _FAIL:(pnetwork == NULL)\n",
1789 rtw_check_join_candidate(pmlmepriv
, &candidate
, pnetwork
);
1793 DBG_8723A("%s: return _FAIL(candidate == NULL)\n", __func__
);
1797 DBG_8723A("%s: candidate: %s("MAC_FMT
", ch:%u)\n", __func__
,
1798 candidate
->network
.Ssid
.ssid
,
1799 MAC_ARG(candidate
->network
.MacAddress
),
1800 candidate
->network
.Configuration
.DSConfig
);
1803 /* check for situation of _FW_LINKED */
1804 if (check_fwstate(pmlmepriv
, _FW_LINKED
)) {
1805 DBG_8723A("%s: _FW_LINKED while ask_for_joinbss!!!\n",
1808 rtw_disassoc_cmd23a(adapter
, 0, true);
1809 rtw_indicate_disconnect23a(adapter
);
1810 rtw_free_assoc_resources23a(adapter
, 0);
1812 set_fwstate(pmlmepriv
, _FW_UNDER_LINKING
);
1813 ret
= rtw_joinbss_cmd23a(adapter
, candidate
);
1816 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1821 int rtw_set_auth23a(struct rtw_adapter
* adapter
,
1822 struct security_priv
*psecuritypriv
)
1824 struct cmd_obj
* pcmd
;
1825 struct setauth_parm
*psetauthparm
;
1826 struct cmd_priv
*pcmdpriv
= &adapter
->cmdpriv
;
1829 pcmd
= (struct cmd_obj
*)kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
1831 res
= _FAIL
; /* try again */
1835 psetauthparm
= (struct setauth_parm
*)
1836 kzalloc(sizeof(struct setauth_parm
), GFP_KERNEL
);
1837 if (!psetauthparm
) {
1843 psetauthparm
->mode
= (unsigned char)psecuritypriv
->dot11AuthAlgrthm
;
1845 pcmd
->cmdcode
= _SetAuth_CMD_
;
1846 pcmd
->parmbuf
= (unsigned char *)psetauthparm
;
1847 pcmd
->cmdsz
= (sizeof(struct setauth_parm
));
1851 RT_TRACE(_module_rtl871x_mlme_c_
,_drv_err_
,
1852 ("after enqueue set_auth_cmd, auth_mode=%x\n",
1853 psecuritypriv
->dot11AuthAlgrthm
));
1855 res
= rtw_enqueue_cmd23a(pcmdpriv
, pcmd
);
1862 int rtw_set_key23a(struct rtw_adapter
*adapter
,
1863 struct security_priv
*psecuritypriv
, int keyid
, u8 set_tx
)
1866 struct cmd_obj
*pcmd
;
1867 struct setkey_parm
*psetkeyparm
;
1868 struct cmd_priv
*pcmdpriv
= &adapter
->cmdpriv
;
1869 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1872 pcmd
= (struct cmd_obj
*)kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
1874 res
= _FAIL
; /* try again */
1877 psetkeyparm
= kzalloc(sizeof(struct setkey_parm
), GFP_KERNEL
);
1884 if (psecuritypriv
->dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
) {
1885 psetkeyparm
->algorithm
= (unsigned char)
1886 psecuritypriv
->dot118021XGrpPrivacy
;
1887 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1888 ("\n rtw_set_key23a: psetkeyparm->algorithm = "
1889 "(unsigned char)psecuritypriv->dot118021XGrpPrivacy "
1890 "=%d\n", psetkeyparm
->algorithm
));
1892 psetkeyparm
->algorithm
= (u8
)psecuritypriv
->dot11PrivacyAlgrthm
;
1893 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1894 ("\n rtw_set_key23a: psetkeyparm->algorithm = (u8)"
1895 "psecuritypriv->dot11PrivacyAlgrthm =%d\n",
1896 psetkeyparm
->algorithm
));
1898 psetkeyparm
->keyid
= (u8
)keyid
;/* 0~3 */
1899 psetkeyparm
->set_tx
= set_tx
;
1900 if (is_wep_enc(psetkeyparm
->algorithm
))
1901 pmlmepriv
->key_mask
|= CHKBIT(psetkeyparm
->keyid
);
1903 DBG_8723A("==> rtw_set_key23a algorithm(%x), keyid(%x), key_mask(%x)\n",
1904 psetkeyparm
->algorithm
, psetkeyparm
->keyid
,
1905 pmlmepriv
->key_mask
);
1906 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1907 ("\n rtw_set_key23a: psetkeyparm->algorithm =%d psetkeyparm->"
1908 "keyid = (u8)keyid =%d\n", psetkeyparm
->algorithm
, keyid
));
1910 switch (psetkeyparm
->algorithm
) {
1913 memcpy(&psetkeyparm
->key
[0],
1914 &psecuritypriv
->dot11DefKey
[keyid
].skey
[0], keylen
);
1918 memcpy(&psetkeyparm
->key
[0],
1919 &psecuritypriv
->dot11DefKey
[keyid
].skey
[0], keylen
);
1923 memcpy(&psetkeyparm
->key
,
1924 &psecuritypriv
->dot118021XGrpKey
[keyid
], keylen
);
1925 psetkeyparm
->grpkey
= 1;
1929 memcpy(&psetkeyparm
->key
,
1930 &psecuritypriv
->dot118021XGrpKey
[keyid
], keylen
);
1931 psetkeyparm
->grpkey
= 1;
1934 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1935 ("\n rtw_set_key23a:psecuritypriv->dot11PrivacyAlgrthm"
1936 " = %x (must be 1 or 2 or 4 or 5)\n",
1937 psecuritypriv
->dot11PrivacyAlgrthm
));
1944 pcmd
->cmdcode
= _SetKey_CMD_
;
1945 pcmd
->parmbuf
= (u8
*)psetkeyparm
;
1946 pcmd
->cmdsz
= (sizeof(struct setkey_parm
));
1950 /* sema_init(&pcmd->cmd_sem, 0); */
1952 res
= rtw_enqueue_cmd23a(pcmdpriv
, pcmd
);
1959 /* adjust IEs for rtw_joinbss_cmd23a in WMM */
1960 int rtw_restruct_wmm_ie23a(struct rtw_adapter
*adapter
, u8
*in_ie
,
1961 u8
*out_ie
, uint in_len
, uint initial_out_len
)
1963 unsigned int ielength
= 0;
1966 i
= 12; /* after the fixed IE */
1967 while (i
< in_len
) {
1968 ielength
= initial_out_len
;
1970 /* WMM element ID and OUI */
1971 if (in_ie
[i
] == 0xDD && in_ie
[i
+ 2] == 0x00 &&
1972 in_ie
[i
+ 3] == 0x50 && in_ie
[i
+ 4] == 0xF2 &&
1973 in_ie
[i
+ 5] == 0x02 && i
+5 < in_len
) {
1975 /* Append WMM IE to the last index of out_ie */
1976 for (j
= i
; j
< i
+ 9; j
++) {
1977 out_ie
[ielength
] = in_ie
[j
];
1980 out_ie
[initial_out_len
+ 1] = 0x07;
1981 out_ie
[initial_out_len
+ 6] = 0x00;
1982 out_ie
[initial_out_len
+ 8] = 0x00;
1987 i
+= (in_ie
[i
+ 1] + 2); /* to the next IE element */
1994 /* Ported from 8185: IsInPreAuthKeyList().
1995 (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.) */
1996 /* Added by Annie, 2006-05-07. */
1998 /* Search by BSSID, */
2000 /* -1 :if there is no pre-auth key in the table */
2001 /* >= 0 :if there is pre-auth key, and return the entry id */
2005 static int SecIsInPMKIDList(struct rtw_adapter
*Adapter
, u8
*bssid
)
2007 struct security_priv
*psecuritypriv
= &Adapter
->securitypriv
;
2011 if (psecuritypriv
->PMKIDList
[i
].bUsed
&&
2012 ether_addr_equal(psecuritypriv
->PMKIDList
[i
].Bssid
, bssid
)) {
2018 } while (i
< NUM_PMKID_CACHE
);
2020 if (i
== NUM_PMKID_CACHE
)
2021 i
= -1;/* Could not find. */
2023 /* There is one Pre-Authentication Key for
2024 the specific BSSID. */
2031 /* Check the RSN IE length */
2032 /* If the RSN IE length <= 20, the RSN IE didn't include
2033 the PMKID information */
2034 /* 0-11th element in the array are the fixed IE */
2035 /* 12th element in the array is the IE */
2036 /* 13th element in the array is the IE length */
2039 static int rtw_append_pmkid(struct rtw_adapter
*Adapter
, int iEntry
,
2040 u8
*ie
, uint ie_len
)
2042 struct security_priv
*psecuritypriv
= &Adapter
->securitypriv
;
2045 /* The RSN IE didn't include the PMK ID,
2046 append the PMK information */
2049 ie
[ie_len
] = 0; /* PMKID count = 0x0100 */
2052 &psecuritypriv
->PMKIDList
[iEntry
].PMKID
, 16);
2055 ie
[13] += 18;/* PMKID length = 2+16 */
2060 int rtw_restruct_sec_ie23a(struct rtw_adapter
*adapter
, u8
*in_ie
, u8
*out_ie
,
2066 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
2067 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
2068 uint ndisauthmode
= psecuritypriv
->ndisauthtype
;
2069 uint ndissecuritytype
= psecuritypriv
->ndisencryptstatus
;
2071 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
2072 ("+rtw_restruct_sec_ie23a: ndisauthmode=%d "
2073 "ndissecuritytype=%d\n", ndisauthmode
, ndissecuritytype
));
2075 /* copy fixed ie only */
2076 memcpy(out_ie
, in_ie
, 12);
2078 if (ndisauthmode
== Ndis802_11AuthModeWPA
||
2079 ndisauthmode
== Ndis802_11AuthModeWPAPSK
)
2080 authmode
= WLAN_EID_VENDOR_SPECIFIC
;
2081 if (ndisauthmode
== Ndis802_11AuthModeWPA2
||
2082 ndisauthmode
== Ndis802_11AuthModeWPA2PSK
)
2083 authmode
= _WPA2_IE_ID_
;
2085 if (check_fwstate(pmlmepriv
, WIFI_UNDER_WPS
)) {
2086 memcpy(out_ie
+ ielength
, psecuritypriv
->wps_ie
,
2087 psecuritypriv
->wps_ie_len
);
2089 ielength
+= psecuritypriv
->wps_ie_len
;
2090 } else if (authmode
== WLAN_EID_VENDOR_SPECIFIC
||
2091 authmode
== _WPA2_IE_ID_
) {
2092 /* copy RSN or SSN */
2093 memcpy(&out_ie
[ielength
], &psecuritypriv
->supplicant_ie
[0],
2094 psecuritypriv
->supplicant_ie
[1] + 2);
2095 ielength
+= psecuritypriv
->supplicant_ie
[1] + 2;
2098 iEntry
= SecIsInPMKIDList(adapter
, pmlmepriv
->assoc_bssid
);
2102 if (authmode
== _WPA2_IE_ID_
)
2103 ielength
= rtw_append_pmkid(adapter
, iEntry
,
2110 void rtw_init_registrypriv_dev_network23a(struct rtw_adapter
* adapter
)
2112 struct registry_priv
* pregistrypriv
= &adapter
->registrypriv
;
2113 struct eeprom_priv
* peepriv
= &adapter
->eeprompriv
;
2114 struct wlan_bssid_ex
*pdev_network
= &pregistrypriv
->dev_network
;
2115 u8
*myhwaddr
= myid(peepriv
);
2117 ether_addr_copy(pdev_network
->MacAddress
, myhwaddr
);
2119 memcpy(&pdev_network
->Ssid
, &pregistrypriv
->ssid
,
2120 sizeof(struct cfg80211_ssid
));
2122 pdev_network
->Configuration
.Length
=sizeof(struct ndis_802_11_config
);
2123 pdev_network
->Configuration
.BeaconPeriod
= 100;
2124 pdev_network
->Configuration
.FHConfig
.Length
= 0;
2125 pdev_network
->Configuration
.FHConfig
.HopPattern
= 0;
2126 pdev_network
->Configuration
.FHConfig
.HopSet
= 0;
2127 pdev_network
->Configuration
.FHConfig
.DwellTime
= 0;
2131 void rtw_update_registrypriv_dev_network23a(struct rtw_adapter
* adapter
)
2134 struct registry_priv
* pregistrypriv
= &adapter
->registrypriv
;
2135 struct wlan_bssid_ex
*pdev_network
= &pregistrypriv
->dev_network
;
2136 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
2137 struct wlan_network
*cur_network
= &adapter
->mlmepriv
.cur_network
;
2138 /* struct xmit_priv *pxmitpriv = &adapter->xmitpriv; */
2140 pdev_network
->Privacy
=
2141 (psecuritypriv
->dot11PrivacyAlgrthm
> 0 ? 1 : 0);
2143 pdev_network
->Rssi
= 0;
2145 switch (pregistrypriv
->wireless_mode
)
2148 pdev_network
->NetworkTypeInUse
= Ndis802_11DS
;
2152 case WIRELESS_11_24N
:
2153 case WIRELESS_11G_24N
:
2154 case WIRELESS_11BG_24N
:
2155 pdev_network
->NetworkTypeInUse
= Ndis802_11OFDM24
;
2158 case WIRELESS_11A_5N
:
2159 pdev_network
->NetworkTypeInUse
= Ndis802_11OFDM5
;
2161 case WIRELESS_11ABGN
:
2162 if (pregistrypriv
->channel
> 14)
2163 pdev_network
->NetworkTypeInUse
= Ndis802_11OFDM5
;
2165 pdev_network
->NetworkTypeInUse
= Ndis802_11OFDM24
;
2172 pdev_network
->Configuration
.DSConfig
= pregistrypriv
->channel
;
2173 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
2174 ("pregistrypriv->channel =%d, pdev_network->Configuration."
2175 "DSConfig = 0x%x\n", pregistrypriv
->channel
,
2176 pdev_network
->Configuration
.DSConfig
));
2178 if (cur_network
->network
.InfrastructureMode
== Ndis802_11IBSS
)
2179 pdev_network
->Configuration
.ATIMWindow
= 0;
2181 pdev_network
->InfrastructureMode
=
2182 cur_network
->network
.InfrastructureMode
;
2184 /* 1. Supported rates */
2187 sz
= rtw_generate_ie23a(pregistrypriv
);
2189 pdev_network
->IELength
= sz
;
2191 pdev_network
->Length
=
2192 get_wlan_bssid_ex_sz(pdev_network
);
2194 /* notes: translate IELength & Length after assign the
2195 Length to cmdsz in createbss_cmd(); */
2196 /* pdev_network->IELength = cpu_to_le32(sz); */
2199 void rtw_get_encrypt_decrypt_from_registrypriv23a(struct rtw_adapter
* adapter
)
2204 /* the fucntion is at passive_level */
2205 void rtw_joinbss_reset23a(struct rtw_adapter
*padapter
)
2208 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2209 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
2211 /* todo: if you want to do something io/reg/hw setting
2212 before join_bss, please add code here */
2214 pmlmepriv
->num_FortyMHzIntolerant
= 0;
2216 pmlmepriv
->num_sta_no_ht
= 0;
2218 phtpriv
->ampdu_enable
= false;/* reset to disabled */
2220 /* TH = 1 => means that invalidate usb rx aggregation */
2221 /* TH = 0 => means that validate usb rx aggregation, use init value. */
2222 if (phtpriv
->ht_option
) {
2223 if (padapter
->registrypriv
.wifi_spec
== 1)
2230 rtl8723a_set_rxdma_agg_pg_th(padapter
, threshold
);
2233 /* the fucntion is >= passive_level */
2234 unsigned int rtw_restructure_ht_ie23a(struct rtw_adapter
*padapter
, u8
*in_ie
,
2235 u8
*out_ie
, uint in_len
, uint
*pout_len
)
2238 int max_rx_ampdu_factor
;
2239 unsigned char *pframe
;
2241 struct ieee80211_ht_cap ht_capie
;
2242 unsigned char WMM_IE
[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
2243 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2244 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
2246 phtpriv
->ht_option
= false;
2248 p
= cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
, in_ie
+ 12, in_len
-12);
2250 if (p
&& p
[1] > 0) {
2251 u32 rx_packet_offset
, max_recvbuf_sz
;
2252 if (pmlmepriv
->qos_option
== 0) {
2253 out_len
= *pout_len
;
2254 pframe
= rtw_set_ie23a(out_ie
+ out_len
,
2255 WLAN_EID_VENDOR_SPECIFIC
,
2256 _WMM_IE_Length_
, WMM_IE
, pout_len
);
2258 pmlmepriv
->qos_option
= 1;
2261 out_len
= *pout_len
;
2263 memset(&ht_capie
, 0, sizeof(struct ieee80211_ht_cap
));
2265 ht_capie
.cap_info
= IEEE80211_HT_CAP_SUP_WIDTH_20_40
|
2266 IEEE80211_HT_CAP_SGI_20
| IEEE80211_HT_CAP_SGI_40
|
2267 IEEE80211_HT_CAP_TX_STBC
| IEEE80211_HT_CAP_DSSSCCK40
;
2269 rtw_hal_get_def_var23a(padapter
, HAL_DEF_RX_PACKET_OFFSET
,
2271 rtw_hal_get_def_var23a(padapter
, HAL_DEF_MAX_RECVBUF_SZ
,
2274 rtw_hal_get_def_var23a(padapter
, HW_VAR_MAX_RX_AMPDU_FACTOR
,
2275 &max_rx_ampdu_factor
);
2276 ht_capie
.ampdu_params_info
= max_rx_ampdu_factor
& 0x03;
2278 if (padapter
->securitypriv
.dot11PrivacyAlgrthm
== _AES_
)
2279 ht_capie
.ampdu_params_info
|=
2280 (IEEE80211_HT_AMPDU_PARM_DENSITY
& (0x07 << 2));
2282 ht_capie
.ampdu_params_info
|=
2283 (IEEE80211_HT_AMPDU_PARM_DENSITY
& 0x00);
2285 pframe
= rtw_set_ie23a(out_ie
+ out_len
, WLAN_EID_HT_CAPABILITY
,
2286 sizeof(struct ieee80211_ht_cap
),
2287 (unsigned char*)&ht_capie
, pout_len
);
2289 phtpriv
->ht_option
= true;
2291 p
= cfg80211_find_ie(WLAN_EID_HT_OPERATION
, in_ie
+ 12,
2293 if (p
&& (p
[1] == sizeof(struct ieee80211_ht_addt_info
))) {
2294 out_len
= *pout_len
;
2295 pframe
= rtw_set_ie23a(out_ie
+ out_len
,
2296 WLAN_EID_HT_OPERATION
,
2297 p
[1], p
+ 2 , pout_len
);
2301 return phtpriv
->ht_option
;
2304 /* the fucntion is > passive_level (in critical_section) */
2305 void rtw_update_ht_cap23a(struct rtw_adapter
*padapter
, u8
*pie
, uint ie_len
)
2309 struct ieee80211_ht_cap
*pht_capie
;
2310 struct ieee80211_ht_addt_info
*pht_addtinfo
;
2311 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2312 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
2313 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
2314 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2315 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
2317 if (!phtpriv
->ht_option
)
2320 if ((!pmlmeinfo
->HT_info_enable
) || (!pmlmeinfo
->HT_caps_enable
))
2323 DBG_8723A("+rtw_update_ht_cap23a()\n");
2325 /* Adjust pie + ie_len for our searches */
2326 pie
+= sizeof (struct ndis_802_11_fixed_ies
);
2327 ie_len
-= sizeof (struct ndis_802_11_fixed_ies
);
2329 /* maybe needs check if ap supports rx ampdu. */
2330 if (phtpriv
->ampdu_enable
== false &&
2331 pregistrypriv
->ampdu_enable
== 1) {
2332 if (pregistrypriv
->wifi_spec
== 1)
2333 phtpriv
->ampdu_enable
= false;
2335 phtpriv
->ampdu_enable
= true;
2336 } else if (pregistrypriv
->ampdu_enable
== 2)
2337 phtpriv
->ampdu_enable
= true;
2339 /* check Max Rx A-MPDU Size */
2340 p
= cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
, pie
, ie_len
);
2342 if (p
&& p
[1] > 0) {
2343 pht_capie
= (struct ieee80211_ht_cap
*)(p
+ 2);
2344 max_ampdu_sz
= pht_capie
->ampdu_params_info
&
2345 IEEE80211_HT_AMPDU_PARM_FACTOR
;
2346 /* max_ampdu_sz (kbytes); */
2347 max_ampdu_sz
= 1 << (max_ampdu_sz
+ 3);
2349 phtpriv
->rx_ampdu_maxlen
= max_ampdu_sz
;
2352 p
= cfg80211_find_ie(WLAN_EID_HT_OPERATION
, pie
, ie_len
);
2353 if (p
&& p
[1] > 0) {
2354 pht_addtinfo
= (struct ieee80211_ht_addt_info
*)(p
+ 2);
2358 /* update cur_bwmode & cur_ch_offset */
2359 if (pregistrypriv
->cbw40_enable
&&
2360 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
& BIT(1) &&
2361 pmlmeinfo
->HT_info
.infos
[0] & BIT(2)) {
2365 rf_type
= rtl8723a_get_rf_type(padapter
);
2367 /* update the MCS rates */
2368 for (i
= 0; i
< 16; i
++) {
2369 if (rf_type
== RF_1T1R
|| rf_type
== RF_1T2R
)
2370 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.MCS_rate
[i
] &= MCS_rate_1R23A
[i
];
2372 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.MCS_rate
[i
] &= MCS_rate_2R23A
[i
];
2374 /* switch to the 40M Hz mode accoring to the AP */
2375 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_40
;
2376 switch ((pmlmeinfo
->HT_info
.infos
[0] & 0x3))
2378 case HT_EXTCHNL_OFFSET_UPPER
:
2379 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_LOWER
;
2382 case HT_EXTCHNL_OFFSET_LOWER
:
2383 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_UPPER
;
2387 pmlmeext
->cur_ch_offset
=
2388 HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
2394 /* Config SM Power Save setting */
2396 pmlmeinfo
->SM_PS
= (pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
&
2398 if (pmlmeinfo
->SM_PS
== WLAN_HT_CAP_SM_PS_STATIC
)
2399 DBG_8723A("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__
);
2402 /* Config current HT Protection mode. */
2404 pmlmeinfo
->HT_protection
= pmlmeinfo
->HT_info
.infos
[1] & 0x3;
2407 void rtw_issue_addbareq_cmd23a(struct rtw_adapter
*padapter
,
2408 struct xmit_frame
*pxmitframe
)
2412 struct sta_info
*psta
;
2413 struct ht_priv
*phtpriv
;
2414 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
2415 s32 bmcst
= is_multicast_ether_addr(pattrib
->ra
);
2417 if (bmcst
|| padapter
->mlmepriv
.LinkDetectInfo
.NumTxOkInPeriod
< 100)
2420 priority
= pattrib
->priority
;
2423 psta
= pattrib
->psta
;
2425 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__
);
2426 psta
= rtw_get_stainfo23a(&padapter
->stapriv
, pattrib
->ra
);
2430 DBG_8723A("%s, psta == NUL\n", __func__
);
2434 if (!(psta
->state
&_FW_LINKED
)) {
2435 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
2436 __func__
, psta
->state
);
2440 phtpriv
= &psta
->htpriv
;
2442 if (phtpriv
->ht_option
== true && phtpriv
->ampdu_enable
== true) {
2443 issued
= (phtpriv
->agg_enable_bitmap
>>priority
)&0x1;
2444 issued
|= (phtpriv
->candidate_tid_bitmap
>>priority
)&0x1;
2447 DBG_8723A("rtw_issue_addbareq_cmd23a, p =%d\n",
2449 psta
->htpriv
.candidate_tid_bitmap
|=
2450 CHKBIT((u8
)priority
);
2451 rtw_addbareq_cmd23a(padapter
, (u8
) priority
,
2457 int rtw_linked_check(struct rtw_adapter
*padapter
)
2459 if (check_fwstate(&padapter
->mlmepriv
, WIFI_AP_STATE
) ||
2460 check_fwstate(&padapter
->mlmepriv
,
2461 WIFI_ADHOC_STATE
|WIFI_ADHOC_MASTER_STATE
)) {
2462 if (padapter
->stapriv
.asoc_sta_count
> 2)
2464 } else { /* Station mode */
2465 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
))