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_1R
[16];
33 int rtw_init_mlme_priv(struct adapter
*padapter
)
37 struct wlan_network
*pnetwork
;
38 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
41 /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */
43 pmlmepriv
->nic_hdl
= (u8
*)padapter
;
45 pmlmepriv
->pscanned
= NULL
;
46 pmlmepriv
->fw_state
= 0;
47 pmlmepriv
->cur_network
.network
.InfrastructureMode
= Ndis802_11AutoUnknown
;
48 pmlmepriv
->scan_mode
= SCAN_ACTIVE
;/* 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) */
50 spin_lock_init(&(pmlmepriv
->lock
));
51 _rtw_init_queue(&(pmlmepriv
->free_bss_pool
));
52 _rtw_init_queue(&(pmlmepriv
->scanned_queue
));
54 memset(&pmlmepriv
->assoc_ssid
, 0, sizeof(struct ndis_802_11_ssid
));
56 pbuf
= vzalloc(MAX_BSS_CNT
* (sizeof(struct wlan_network
)));
62 pmlmepriv
->free_bss_buf
= pbuf
;
64 pnetwork
= (struct wlan_network
*)pbuf
;
66 for (i
= 0; i
< MAX_BSS_CNT
; i
++) {
67 INIT_LIST_HEAD(&(pnetwork
->list
));
69 list_add_tail(&(pnetwork
->list
), &(pmlmepriv
->free_bss_pool
.queue
));
74 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
76 rtw_clear_scan_deny(padapter
);
78 rtw_init_mlme_timer(padapter
);
84 #if defined(CONFIG_88EU_AP_MODE)
85 static void rtw_free_mlme_ie_data(u8
**ppie
, u32
*plen
)
92 void rtw_free_mlme_priv_ie_data(struct mlme_priv
*pmlmepriv
)
94 rtw_buf_free(&pmlmepriv
->assoc_req
, &pmlmepriv
->assoc_req_len
);
95 rtw_buf_free(&pmlmepriv
->assoc_rsp
, &pmlmepriv
->assoc_rsp_len
);
96 rtw_free_mlme_ie_data(&pmlmepriv
->wps_beacon_ie
, &pmlmepriv
->wps_beacon_ie_len
);
97 rtw_free_mlme_ie_data(&pmlmepriv
->wps_probe_req_ie
, &pmlmepriv
->wps_probe_req_ie_len
);
98 rtw_free_mlme_ie_data(&pmlmepriv
->wps_probe_resp_ie
, &pmlmepriv
->wps_probe_resp_ie_len
);
99 rtw_free_mlme_ie_data(&pmlmepriv
->wps_assoc_resp_ie
, &pmlmepriv
->wps_assoc_resp_ie_len
);
102 void rtw_free_mlme_priv_ie_data(struct mlme_priv
*pmlmepriv
)
107 void rtw_free_mlme_priv(struct mlme_priv
*pmlmepriv
)
110 rtw_free_mlme_priv_ie_data(pmlmepriv
);
111 vfree(pmlmepriv
->free_bss_buf
);
115 struct wlan_network
*_rtw_alloc_network(struct mlme_priv
*pmlmepriv
)
116 /* _queue *free_queue) */
118 struct wlan_network
*pnetwork
;
119 struct __queue
*free_queue
= &pmlmepriv
->free_bss_pool
;
121 spin_lock_bh(&free_queue
->lock
);
122 pnetwork
= list_first_entry_or_null(&free_queue
->queue
,
123 struct wlan_network
, list
);
127 list_del_init(&pnetwork
->list
);
129 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
130 ("_rtw_alloc_network: ptr=%p\n", &pnetwork
->list
));
131 pnetwork
->network_type
= 0;
132 pnetwork
->fixed
= false;
133 pnetwork
->last_scanned
= jiffies
;
135 pnetwork
->join_res
= 0;
138 spin_unlock_bh(&free_queue
->lock
);
143 static void _rtw_free_network(struct mlme_priv
*pmlmepriv
, struct wlan_network
*pnetwork
, u8 isfreeall
)
145 unsigned long curr_time
;
147 u32 lifetime
= SCANQUEUE_LIFETIME
;
148 struct __queue
*free_queue
= &(pmlmepriv
->free_bss_pool
);
156 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) ||
157 (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)))
160 delta_time
= (curr_time
- pnetwork
->last_scanned
)/HZ
;
161 if (delta_time
< lifetime
)/* unit:sec */
164 spin_lock_bh(&free_queue
->lock
);
165 list_del_init(&(pnetwork
->list
));
166 list_add_tail(&(pnetwork
->list
), &(free_queue
->queue
));
167 spin_unlock_bh(&free_queue
->lock
);
170 void _rtw_free_network_nolock(struct mlme_priv
*pmlmepriv
, struct wlan_network
*pnetwork
)
172 struct __queue
*free_queue
= &(pmlmepriv
->free_bss_pool
);
178 list_del_init(&(pnetwork
->list
));
179 list_add_tail(&(pnetwork
->list
), get_list_head(free_queue
));
183 * return the wlan_network with the matching addr
185 * Shall be called under atomic context... to avoid possible racing condition...
187 struct wlan_network
*rtw_find_network(struct __queue
*scanned_queue
, u8
*addr
)
189 struct list_head
*phead
, *plist
;
190 struct wlan_network
*pnetwork
= NULL
;
191 u8 zero_addr
[ETH_ALEN
] = {0, 0, 0, 0, 0, 0};
193 if (!memcmp(zero_addr
, addr
, ETH_ALEN
)) {
197 phead
= get_list_head(scanned_queue
);
200 while (plist
!= phead
) {
201 pnetwork
= container_of(plist
, struct wlan_network
, list
);
202 if (!memcmp(addr
, pnetwork
->network
.MacAddress
, ETH_ALEN
))
213 void rtw_free_network_queue(struct adapter
*padapter
, u8 isfreeall
)
215 struct list_head
*phead
, *plist
;
216 struct wlan_network
*pnetwork
;
217 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
218 struct __queue
*scanned_queue
= &pmlmepriv
->scanned_queue
;
220 spin_lock_bh(&scanned_queue
->lock
);
222 phead
= get_list_head(scanned_queue
);
225 while (phead
!= plist
) {
226 pnetwork
= container_of(plist
, struct wlan_network
, list
);
230 _rtw_free_network(pmlmepriv
, pnetwork
, isfreeall
);
232 spin_unlock_bh(&scanned_queue
->lock
);
235 int rtw_if_up(struct adapter
*padapter
)
239 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
||
240 (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) == false)) {
241 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
242 ("rtw_if_up:bDriverStopped(%d) OR bSurpriseRemoved(%d)",
243 padapter
->bDriverStopped
, padapter
->bSurpriseRemoved
));
251 void rtw_generate_random_ibss(u8
*pibss
)
253 unsigned long curtime
= jiffies
;
255 pibss
[0] = 0x02; /* in ad-hoc mode bit1 must set to 1 */
258 pibss
[3] = (u8
)(curtime
& 0xff);/* p[0]; */
259 pibss
[4] = (u8
)((curtime
>>8) & 0xff);/* p[1]; */
260 pibss
[5] = (u8
)((curtime
>>16) & 0xff);/* p[2]; */
263 u8
*rtw_get_capability_from_ie(u8
*ie
)
269 u16
rtw_get_capability(struct wlan_bssid_ex
*bss
)
273 memcpy((u8
*)&val
, rtw_get_capability_from_ie(bss
->IEs
), 2);
275 return le16_to_cpu(val
);
278 u8
*rtw_get_beacon_interval_from_ie(u8
*ie
)
283 static struct wlan_network
*rtw_alloc_network(struct mlme_priv
*pmlmepriv
)
285 return _rtw_alloc_network(pmlmepriv
);
288 static void rtw_free_network_nolock(struct mlme_priv
*pmlmepriv
,
289 struct wlan_network
*pnetwork
)
291 _rtw_free_network_nolock(pmlmepriv
, pnetwork
);
294 int rtw_is_same_ibss(struct adapter
*adapter
, struct wlan_network
*pnetwork
)
297 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
299 if ((psecuritypriv
->dot11PrivacyAlgrthm
!= _NO_PRIVACY_
) &&
300 (pnetwork
->network
.Privacy
== 0))
302 else if ((psecuritypriv
->dot11PrivacyAlgrthm
== _NO_PRIVACY_
) &&
303 (pnetwork
->network
.Privacy
== 1))
310 static int is_same_ess(struct wlan_bssid_ex
*a
, struct wlan_bssid_ex
*b
)
312 return (a
->Ssid
.SsidLength
== b
->Ssid
.SsidLength
) &&
313 !memcmp(a
->Ssid
.Ssid
, b
->Ssid
.Ssid
, a
->Ssid
.SsidLength
);
316 int is_same_network(struct wlan_bssid_ex
*src
, struct wlan_bssid_ex
*dst
)
319 __le16 le_scap
, le_dcap
;
321 memcpy((u8
*)&le_scap
, rtw_get_capability_from_ie(src
->IEs
), 2);
322 memcpy((u8
*)&le_dcap
, rtw_get_capability_from_ie(dst
->IEs
), 2);
324 s_cap
= le16_to_cpu(le_scap
);
325 d_cap
= le16_to_cpu(le_dcap
);
327 return ((src
->Ssid
.SsidLength
== dst
->Ssid
.SsidLength
) &&
328 ((!memcmp(src
->MacAddress
, dst
->MacAddress
, ETH_ALEN
)) == true) &&
329 ((!memcmp(src
->Ssid
.Ssid
, dst
->Ssid
.Ssid
, src
->Ssid
.SsidLength
)) == true) &&
330 ((s_cap
& WLAN_CAPABILITY_IBSS
) ==
331 (d_cap
& WLAN_CAPABILITY_IBSS
)) &&
332 ((s_cap
& WLAN_CAPABILITY_ESS
) ==
333 (d_cap
& WLAN_CAPABILITY_ESS
)));
336 struct wlan_network
*rtw_get_oldest_wlan_network(struct __queue
*scanned_queue
)
338 struct list_head
*plist
, *phead
;
339 struct wlan_network
*pwlan
= NULL
;
340 struct wlan_network
*oldest
= NULL
;
342 phead
= get_list_head(scanned_queue
);
344 for (plist
= phead
->next
; plist
!= phead
; plist
= plist
->next
) {
345 pwlan
= container_of(plist
, struct wlan_network
, list
);
348 if (!oldest
|| time_after(oldest
->last_scanned
, pwlan
->last_scanned
))
355 void update_network(struct wlan_bssid_ex
*dst
, struct wlan_bssid_ex
*src
,
356 struct adapter
*padapter
, bool update_ie
)
358 long rssi_ori
= dst
->Rssi
;
359 u8 sq_smp
= src
->PhyInfo
.SignalQuality
;
364 rtw_hal_antdiv_rssi_compared(padapter
, dst
, src
); /* this will update src.Rssi, need consider again */
366 /* The rule below is 1/5 for sample value, 4/5 for history value */
367 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) && is_same_network(&(padapter
->mlmepriv
.cur_network
.network
), src
)) {
368 /* Take the recvpriv's value for the connected AP*/
369 ss_final
= padapter
->recvpriv
.signal_strength
;
370 sq_final
= padapter
->recvpriv
.signal_qual
;
371 /* the rssi value here is undecorated, and will be used for antenna diversity */
372 if (sq_smp
!= 101) /* from the right channel */
373 rssi_final
= (src
->Rssi
+ dst
->Rssi
* 4) / 5;
375 rssi_final
= rssi_ori
;
377 if (sq_smp
!= 101) { /* from the right channel */
378 ss_final
= ((u32
)(src
->PhyInfo
.SignalStrength
)+(u32
)(dst
->PhyInfo
.SignalStrength
)*4)/5;
379 sq_final
= ((u32
)(src
->PhyInfo
.SignalQuality
)+(u32
)(dst
->PhyInfo
.SignalQuality
)*4)/5;
380 rssi_final
= (src
->Rssi
+dst
->Rssi
*4)/5;
382 /* bss info not receiving from the right channel, use the original RX signal infos */
383 ss_final
= dst
->PhyInfo
.SignalStrength
;
384 sq_final
= dst
->PhyInfo
.SignalQuality
;
385 rssi_final
= dst
->Rssi
;
389 memcpy((u8
*)dst
, (u8
*)src
, get_wlan_bssid_ex_sz(src
));
390 dst
->PhyInfo
.SignalStrength
= ss_final
;
391 dst
->PhyInfo
.SignalQuality
= sq_final
;
392 dst
->Rssi
= rssi_final
;
395 static void update_current_network(struct adapter
*adapter
, struct wlan_bssid_ex
*pnetwork
)
397 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
399 if ((check_fwstate(pmlmepriv
, _FW_LINKED
) == true) &&
400 (is_same_network(&(pmlmepriv
->cur_network
.network
), pnetwork
))) {
401 update_network(&(pmlmepriv
->cur_network
.network
), pnetwork
, adapter
, true);
402 rtw_update_protection(adapter
, (pmlmepriv
->cur_network
.network
.IEs
) + sizeof(struct ndis_802_11_fixed_ie
),
403 pmlmepriv
->cur_network
.network
.IELength
);
408 * Caller must hold pmlmepriv->lock first.
410 void rtw_update_scanned_network(struct adapter
*adapter
, struct wlan_bssid_ex
*target
)
412 struct list_head
*plist
, *phead
;
414 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
415 struct __queue
*queue
= &(pmlmepriv
->scanned_queue
);
416 struct wlan_network
*pnetwork
= NULL
;
417 struct wlan_network
*oldest
= NULL
;
419 spin_lock_bh(&queue
->lock
);
420 phead
= get_list_head(queue
);
423 while (phead
!= plist
) {
424 pnetwork
= container_of(plist
, struct wlan_network
, list
);
426 if (is_same_network(&(pnetwork
->network
), target
))
428 if ((oldest
== ((struct wlan_network
*)0)) ||
429 time_after(oldest
->last_scanned
, pnetwork
->last_scanned
))
433 /* If we didn't find a match, then get a new network slot to initialize
434 * with this beacon's information
436 if (phead
== plist
) {
437 if (list_empty(&(pmlmepriv
->free_bss_pool
.queue
))) {
438 /* If there are no more slots, expire the oldest */
441 rtw_hal_get_def_var(adapter
, HAL_DEF_CURRENT_ANTENNA
, &(target
->PhyInfo
.Optimum_antenna
));
442 memcpy(&(pnetwork
->network
), target
, get_wlan_bssid_ex_sz(target
));
443 /* variable initialize */
444 pnetwork
->fixed
= false;
445 pnetwork
->last_scanned
= jiffies
;
447 pnetwork
->network_type
= 0;
449 pnetwork
->join_res
= 0;
451 /* bss info not receiving from the right channel */
452 if (pnetwork
->network
.PhyInfo
.SignalQuality
== 101)
453 pnetwork
->network
.PhyInfo
.SignalQuality
= 0;
455 /* Otherwise just pull from the free list */
457 pnetwork
= rtw_alloc_network(pmlmepriv
); /* will update scan_time */
460 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("\n\n\nsomething wrong here\n\n\n"));
464 bssid_ex_sz
= get_wlan_bssid_ex_sz(target
);
465 target
->Length
= bssid_ex_sz
;
466 rtw_hal_get_def_var(adapter
, HAL_DEF_CURRENT_ANTENNA
, &(target
->PhyInfo
.Optimum_antenna
));
467 memcpy(&(pnetwork
->network
), target
, bssid_ex_sz
);
469 pnetwork
->last_scanned
= jiffies
;
471 /* bss info not receiving from the right channel */
472 if (pnetwork
->network
.PhyInfo
.SignalQuality
== 101)
473 pnetwork
->network
.PhyInfo
.SignalQuality
= 0;
474 list_add_tail(&(pnetwork
->list
), &(queue
->queue
));
477 /* we have an entry and we are going to update it. But this entry may
478 * be already expired. In this case we do the same as we found a new
479 * net and call the new_net handler
481 bool update_ie
= true;
483 pnetwork
->last_scanned
= jiffies
;
485 /* target.Reserved[0]== 1, means that scanned network is a bcn frame. */
486 if ((pnetwork
->network
.IELength
> target
->IELength
) && (target
->Reserved
[0] == 1))
489 update_network(&(pnetwork
->network
), target
, adapter
, update_ie
);
493 spin_unlock_bh(&queue
->lock
);
496 static void rtw_add_network(struct adapter
*adapter
,
497 struct wlan_bssid_ex
*pnetwork
)
499 update_current_network(adapter
, pnetwork
);
500 rtw_update_scanned_network(adapter
, pnetwork
);
504 * select the desired network based on the capability of the (i)bss.
505 * check items: (1) security
511 static int rtw_is_desired_network(struct adapter
*adapter
, struct wlan_network
*pnetwork
)
513 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
514 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
518 /* u8 wps_ie[512]; */
521 int bselected
= true;
523 desired_encmode
= psecuritypriv
->ndisencryptstatus
;
524 privacy
= pnetwork
->network
.Privacy
;
526 if (check_fwstate(pmlmepriv
, WIFI_UNDER_WPS
)) {
527 if (rtw_get_wps_ie(pnetwork
->network
.IEs
+_FIXED_IE_LENGTH_
, pnetwork
->network
.IELength
-_FIXED_IE_LENGTH_
, NULL
, &wps_ielen
))
532 if (adapter
->registrypriv
.wifi_spec
== 1) { /* for correct flow of 8021X to do.... */
533 if ((desired_encmode
== Ndis802_11EncryptionDisabled
) && (privacy
!= 0))
538 if ((desired_encmode
!= Ndis802_11EncryptionDisabled
) && (privacy
== 0)) {
539 DBG_88E("desired_encmode: %d, privacy: %d\n", desired_encmode
, privacy
);
543 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) == true) {
544 if (pnetwork
->network
.InfrastructureMode
!= pmlmepriv
->cur_network
.network
.InfrastructureMode
)
551 /* TODO: Perry: For Power Management */
552 void rtw_atimdone_event_callback(struct adapter
*adapter
, u8
*pbuf
)
554 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("receive atimdone_evet\n"));
557 void rtw_survey_event_callback(struct adapter
*adapter
, u8
*pbuf
)
560 struct wlan_bssid_ex
*pnetwork
;
561 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
563 pnetwork
= (struct wlan_bssid_ex
*)pbuf
;
565 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_survey_event_callback, ssid=%s\n", pnetwork
->Ssid
.Ssid
));
567 len
= get_wlan_bssid_ex_sz(pnetwork
);
568 if (len
> (sizeof(struct wlan_bssid_ex
))) {
569 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("\n****rtw_survey_event_callback: return a wrong bss ***\n"));
572 spin_lock_bh(&pmlmepriv
->lock
);
574 /* update IBSS_network 's timestamp */
575 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) == true) {
576 if (!memcmp(&(pmlmepriv
->cur_network
.network
.MacAddress
), pnetwork
->MacAddress
, ETH_ALEN
)) {
577 struct wlan_network
*ibss_wlan
= NULL
;
579 memcpy(pmlmepriv
->cur_network
.network
.IEs
, pnetwork
->IEs
, 8);
580 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
581 ibss_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, pnetwork
->MacAddress
);
583 memcpy(ibss_wlan
->network
.IEs
, pnetwork
->IEs
, 8);
584 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
587 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
591 /* lock pmlmepriv->lock when you accessing network_q */
592 if ((check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
)) == false) {
593 if (pnetwork
->Ssid
.Ssid
[0] == 0)
594 pnetwork
->Ssid
.SsidLength
= 0;
595 rtw_add_network(adapter
, pnetwork
);
600 spin_unlock_bh(&pmlmepriv
->lock
);
604 void rtw_surveydone_event_callback(struct adapter
*adapter
, u8
*pbuf
)
606 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
608 spin_lock_bh(&pmlmepriv
->lock
);
610 if (pmlmepriv
->wps_probe_req_ie
) {
611 pmlmepriv
->wps_probe_req_ie_len
= 0;
612 kfree(pmlmepriv
->wps_probe_req_ie
);
613 pmlmepriv
->wps_probe_req_ie
= NULL
;
616 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("rtw_surveydone_event_callback: fw_state:%x\n\n", get_fwstate(pmlmepriv
)));
618 if (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
)) {
619 del_timer_sync(&pmlmepriv
->scan_to_timer
);
620 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
622 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("nic status=%x, survey done event comes too late!\n", get_fwstate(pmlmepriv
)));
625 rtw_set_signal_stat_timer(&adapter
->recvpriv
);
627 if (pmlmepriv
->to_join
) {
628 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) == true)) {
629 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == false) {
630 set_fwstate(pmlmepriv
, _FW_UNDER_LINKING
);
632 if (rtw_select_and_join_from_scanned_queue(pmlmepriv
) == _SUCCESS
) {
633 mod_timer(&pmlmepriv
->assoc_timer
,
634 jiffies
+ msecs_to_jiffies(MAX_JOIN_TIMEOUT
));
636 struct wlan_bssid_ex
*pdev_network
= &(adapter
->registrypriv
.dev_network
);
637 u8
*pibss
= adapter
->registrypriv
.dev_network
.MacAddress
;
639 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
641 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("switching to adhoc master\n"));
643 memcpy(&pdev_network
->Ssid
, &pmlmepriv
->assoc_ssid
, sizeof(struct ndis_802_11_ssid
));
645 rtw_update_registrypriv_dev_network(adapter
);
646 rtw_generate_random_ibss(pibss
);
648 pmlmepriv
->fw_state
= WIFI_ADHOC_MASTER_STATE
;
650 if (rtw_createbss_cmd(adapter
) != _SUCCESS
)
651 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Error=>rtw_createbss_cmd status FAIL\n"));
652 pmlmepriv
->to_join
= false;
658 set_fwstate(pmlmepriv
, _FW_UNDER_LINKING
);
659 pmlmepriv
->to_join
= false;
660 s_ret
= rtw_select_and_join_from_scanned_queue(pmlmepriv
);
661 if (s_ret
== _SUCCESS
) {
662 mod_timer(&pmlmepriv
->assoc_timer
,
663 jiffies
+ msecs_to_jiffies(MAX_JOIN_TIMEOUT
));
664 } else if (s_ret
== 2) { /* there is no need to wait for join */
665 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
666 rtw_indicate_connect(adapter
);
668 DBG_88E("try_to_join, but select scanning queue fail, to_roaming:%d\n", pmlmepriv
->to_roaming
);
669 if (pmlmepriv
->to_roaming
!= 0) {
670 if (--pmlmepriv
->to_roaming
== 0 ||
671 rtw_sitesurvey_cmd(adapter
, &pmlmepriv
->assoc_ssid
, 1, NULL
, 0) != _SUCCESS
) {
672 pmlmepriv
->to_roaming
= 0;
673 rtw_free_assoc_resources(adapter
);
674 rtw_indicate_disconnect(adapter
);
676 pmlmepriv
->to_join
= true;
679 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
684 indicate_wx_scan_complete_event(adapter
);
686 spin_unlock_bh(&pmlmepriv
->lock
);
688 rtw_os_xmit_schedule(adapter
);
691 void rtw_dummy_event_callback(struct adapter
*adapter
, u8
*pbuf
)
695 void rtw_fwdbg_event_callback(struct adapter
*adapter
, u8
*pbuf
)
699 static void free_scanqueue(struct mlme_priv
*pmlmepriv
)
701 struct __queue
*free_queue
= &pmlmepriv
->free_bss_pool
;
702 struct __queue
*scan_queue
= &pmlmepriv
->scanned_queue
;
703 struct list_head
*plist
, *phead
, *ptemp
;
705 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
, ("+free_scanqueue\n"));
706 spin_lock_bh(&scan_queue
->lock
);
707 spin_lock_bh(&free_queue
->lock
);
709 phead
= get_list_head(scan_queue
);
712 while (plist
!= phead
) {
714 list_del_init(plist
);
715 list_add_tail(plist
, &free_queue
->queue
);
719 spin_unlock_bh(&free_queue
->lock
);
720 spin_unlock_bh(&scan_queue
->lock
);
724 * rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock
726 void rtw_free_assoc_resources(struct adapter
*adapter
)
728 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
730 spin_lock_bh(&pmlmepriv
->scanned_queue
.lock
);
731 rtw_free_assoc_resources_locked(adapter
);
732 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
736 * rtw_free_assoc_resources_locked: the caller has to lock pmlmepriv->lock
738 void rtw_free_assoc_resources_locked(struct adapter
*adapter
)
740 struct wlan_network
*pwlan
= NULL
;
741 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
742 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
743 struct wlan_network
*tgt_network
= &pmlmepriv
->cur_network
;
745 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
, ("+rtw_free_assoc_resources\n"));
746 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
747 ("tgt_network->network.MacAddress=%pM ssid=%s\n",
748 tgt_network
->network
.MacAddress
, tgt_network
->network
.Ssid
.Ssid
));
750 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
| WIFI_AP_STATE
)) {
751 struct sta_info
*psta
;
753 psta
= rtw_get_stainfo(&adapter
->stapriv
, tgt_network
->network
.MacAddress
);
755 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
756 rtw_free_stainfo(adapter
, psta
);
757 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
760 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
| WIFI_ADHOC_MASTER_STATE
| WIFI_AP_STATE
)) {
761 struct sta_info
*psta
;
763 rtw_free_all_stainfo(adapter
);
765 psta
= rtw_get_bcmc_stainfo(adapter
);
766 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
767 rtw_free_stainfo(adapter
, psta
);
768 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
770 rtw_init_bcmc_stainfo(adapter
);
774 pwlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, tgt_network
->network
.MacAddress
);
776 pwlan
->fixed
= false;
778 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("rtw_free_assoc_resources:pwlan==NULL\n\n"));
780 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) && (adapter
->stapriv
.asoc_sta_count
== 1)))
781 rtw_free_network_nolock(pmlmepriv
, pwlan
);
783 pmlmepriv
->key_mask
= 0;
787 * rtw_indicate_connect: the caller has to lock pmlmepriv->lock
789 void rtw_indicate_connect(struct adapter
*padapter
)
791 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
793 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("+%s\n", __func__
));
795 pmlmepriv
->to_join
= false;
797 if (!check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
)) {
798 set_fwstate(pmlmepriv
, _FW_LINKED
);
800 LedControl8188eu(padapter
, LED_CTL_LINK
);
802 rtw_os_indicate_connect(padapter
);
805 pmlmepriv
->to_roaming
= 0;
807 rtw_set_scan_deny(padapter
, 3000);
809 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("-%s: fw_state=0x%08x\n", __func__
, get_fwstate(pmlmepriv
)));
813 * rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock
815 void rtw_indicate_disconnect(struct adapter
*padapter
)
817 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
819 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("+rtw_indicate_disconnect\n"));
821 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
| WIFI_UNDER_WPS
);
823 if (pmlmepriv
->to_roaming
> 0)
824 _clr_fwstate_(pmlmepriv
, _FW_LINKED
);
826 if (check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
) ||
827 (pmlmepriv
->to_roaming
<= 0)) {
828 rtw_os_indicate_disconnect(padapter
);
830 _clr_fwstate_(pmlmepriv
, _FW_LINKED
);
831 LedControl8188eu(padapter
, LED_CTL_NO_LINK
);
832 rtw_clear_scan_deny(padapter
);
835 rtw_lps_ctrl_wk_cmd(padapter
, LPS_CTRL_DISCONNECT
, 1);
838 inline void rtw_indicate_scan_done(struct adapter
*padapter
, bool aborted
)
840 rtw_os_indicate_scan_done(padapter
, aborted
);
843 void rtw_scan_abort(struct adapter
*adapter
)
846 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
847 struct mlme_ext_priv
*pmlmeext
= &(adapter
->mlmeextpriv
);
850 pmlmeext
->scan_abort
= true;
851 while (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
) &&
852 jiffies_to_msecs(jiffies
- start
) <= 200) {
853 if (adapter
->bDriverStopped
|| adapter
->bSurpriseRemoved
)
855 DBG_88E(FUNC_NDEV_FMT
"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter
->pnetdev
));
858 if (check_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
)) {
859 if (!adapter
->bDriverStopped
&& !adapter
->bSurpriseRemoved
)
860 DBG_88E(FUNC_NDEV_FMT
"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter
->pnetdev
));
861 rtw_indicate_scan_done(adapter
, true);
863 pmlmeext
->scan_abort
= false;
866 static struct sta_info
*rtw_joinbss_update_stainfo(struct adapter
*padapter
, struct wlan_network
*pnetwork
)
869 struct sta_info
*bmc_sta
, *psta
= NULL
;
870 struct recv_reorder_ctrl
*preorder_ctrl
;
871 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
873 psta
= rtw_get_stainfo(pstapriv
, pnetwork
->network
.MacAddress
);
875 psta
= rtw_alloc_stainfo(pstapriv
, pnetwork
->network
.MacAddress
);
877 if (psta
) { /* update ptarget_sta */
878 DBG_88E("%s\n", __func__
);
879 psta
->aid
= pnetwork
->join_res
;
882 rtw_hal_set_odm_var(padapter
, HAL_ODM_STA_INFO
, psta
, true);
883 /* security related */
884 if (padapter
->securitypriv
.dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
) {
885 padapter
->securitypriv
.binstallGrpkey
= false;
886 padapter
->securitypriv
.busetkipkey
= false;
887 padapter
->securitypriv
.bgrpkey_handshake
= false;
888 psta
->ieee8021x_blocked
= true;
889 psta
->dot118021XPrivacy
= padapter
->securitypriv
.dot11PrivacyAlgrthm
;
890 memset((u8
*)&psta
->dot118021x_UncstKey
, 0, sizeof(union Keytype
));
891 memset((u8
*)&psta
->dot11tkiprxmickey
, 0, sizeof(union Keytype
));
892 memset((u8
*)&psta
->dot11tkiptxmickey
, 0, sizeof(union Keytype
));
893 memset((u8
*)&psta
->dot11txpn
, 0, sizeof(union pn48
));
894 memset((u8
*)&psta
->dot11rxpn
, 0, sizeof(union pn48
));
897 * Commented by Albert 2012/07/21
898 * When doing the WPS, the wps_ie_len won't equal to 0
899 * And the Wi-Fi driver shouldn't allow the data
900 * packet to be transmitted.
902 if (padapter
->securitypriv
.wps_ie_len
!= 0) {
903 psta
->ieee8021x_blocked
= true;
904 padapter
->securitypriv
.wps_ie_len
= 0;
906 /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */
907 /* if A-MPDU Rx is enabled, resetting rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */
908 /* todo: check if AP can send A-MPDU packets */
909 for (i
= 0; i
< 16; i
++) {
910 /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
911 preorder_ctrl
= &psta
->recvreorder_ctrl
[i
];
912 preorder_ctrl
->enable
= false;
913 preorder_ctrl
->indicate_seq
= 0xffff;
914 preorder_ctrl
->wend_b
= 0xffff;
915 preorder_ctrl
->wsize_b
= 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
917 bmc_sta
= rtw_get_bcmc_stainfo(padapter
);
919 for (i
= 0; i
< 16; i
++) {
920 /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
921 preorder_ctrl
= &bmc_sta
->recvreorder_ctrl
[i
];
922 preorder_ctrl
->enable
= false;
923 preorder_ctrl
->indicate_seq
= 0xffff;
924 preorder_ctrl
->wend_b
= 0xffff;
925 preorder_ctrl
->wsize_b
= 64;/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
929 update_sta_info(padapter
, psta
);
934 /* pnetwork: returns from rtw_joinbss_event_callback */
935 /* ptarget_wlan: found from scanned_queue */
936 static void rtw_joinbss_update_network(struct adapter
*padapter
, struct wlan_network
*ptarget_wlan
, struct wlan_network
*pnetwork
)
938 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
939 struct wlan_network
*cur_network
= &(pmlmepriv
->cur_network
);
941 DBG_88E("%s\n", __func__
);
943 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
944 ("\nfw_state:%x, BSSID:%pM\n",
945 get_fwstate(pmlmepriv
), pnetwork
->network
.MacAddress
));
948 /* why not use ptarget_wlan?? */
949 memcpy(&cur_network
->network
, &pnetwork
->network
, pnetwork
->network
.Length
);
950 /* some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
951 cur_network
->network
.IELength
= ptarget_wlan
->network
.IELength
;
952 memcpy(&cur_network
->network
.IEs
[0], &ptarget_wlan
->network
.IEs
[0], MAX_IE_SZ
);
954 cur_network
->aid
= pnetwork
->join_res
;
956 rtw_set_signal_stat_timer(&padapter
->recvpriv
);
957 padapter
->recvpriv
.signal_strength
= ptarget_wlan
->network
.PhyInfo
.SignalStrength
;
958 padapter
->recvpriv
.signal_qual
= ptarget_wlan
->network
.PhyInfo
.SignalQuality
;
959 /* the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) */
960 padapter
->recvpriv
.rssi
= translate_percentage_to_dbm(ptarget_wlan
->network
.PhyInfo
.SignalStrength
);
961 rtw_set_signal_stat_timer(&padapter
->recvpriv
);
963 /* update fw_state will clr _FW_UNDER_LINKING here indirectly */
964 switch (pnetwork
->network
.InfrastructureMode
) {
965 case Ndis802_11Infrastructure
:
966 if (pmlmepriv
->fw_state
&WIFI_UNDER_WPS
)
967 pmlmepriv
->fw_state
= WIFI_STATION_STATE
|WIFI_UNDER_WPS
;
969 pmlmepriv
->fw_state
= WIFI_STATION_STATE
;
972 pmlmepriv
->fw_state
= WIFI_ADHOC_STATE
;
975 pmlmepriv
->fw_state
= WIFI_NULL_STATE
;
976 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Invalid network_mode\n"));
980 rtw_update_protection(padapter
, (cur_network
->network
.IEs
) +
981 sizeof(struct ndis_802_11_fixed_ie
),
982 (cur_network
->network
.IELength
));
983 rtw_update_ht_cap(padapter
, cur_network
->network
.IEs
, cur_network
->network
.IELength
);
986 /* Notes: the function could be > passive_level (the same context as Rx tasklet) */
987 /* pnetwork: returns from rtw_joinbss_event_callback */
988 /* ptarget_wlan: found from scanned_queue */
989 /* if join_res > 0, for (fw_state == WIFI_STATION_STATE), we check if "ptarget_sta" & "ptarget_wlan" exist. */
990 /* if join_res > 0, for (fw_state == WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. */
991 /* if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan != NULL). */
993 void rtw_joinbss_event_prehandle(struct adapter
*adapter
, u8
*pbuf
)
995 struct sta_info
*ptarget_sta
= NULL
, *pcur_sta
= NULL
;
996 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
997 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
998 struct wlan_network
*pnetwork
= (struct wlan_network
*)pbuf
;
999 struct wlan_network
*cur_network
= &(pmlmepriv
->cur_network
);
1000 struct wlan_network
*pcur_wlan
= NULL
, *ptarget_wlan
= NULL
;
1001 unsigned int the_same_macaddr
= false;
1003 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("joinbss event call back received with res=%d\n", pnetwork
->join_res
));
1005 rtw_get_encrypt_decrypt_from_registrypriv(adapter
);
1007 if (pmlmepriv
->assoc_ssid
.SsidLength
== 0)
1008 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("@@@@@ joinbss event call back for Any SSid\n"));
1010 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("@@@@@ rtw_joinbss_event_callback for SSid:%s\n", pmlmepriv
->assoc_ssid
.Ssid
));
1012 the_same_macaddr
= !memcmp(pnetwork
->network
.MacAddress
, cur_network
->network
.MacAddress
, ETH_ALEN
);
1014 pnetwork
->network
.Length
= get_wlan_bssid_ex_sz(&pnetwork
->network
);
1015 if (pnetwork
->network
.Length
> sizeof(struct wlan_bssid_ex
)) {
1016 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("\n\n ***joinbss_evt_callback return a wrong bss ***\n\n"));
1020 spin_lock_bh(&pmlmepriv
->lock
);
1022 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("\nrtw_joinbss_event_callback!! _enter_critical\n"));
1024 if (pnetwork
->join_res
> 0) {
1025 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1026 if (check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
)) {
1027 /* s1. find ptarget_wlan */
1028 if (check_fwstate(pmlmepriv
, _FW_LINKED
)) {
1029 if (the_same_macaddr
) {
1030 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, cur_network
->network
.MacAddress
);
1032 pcur_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, cur_network
->network
.MacAddress
);
1034 pcur_wlan
->fixed
= false;
1036 pcur_sta
= rtw_get_stainfo(pstapriv
, cur_network
->network
.MacAddress
);
1038 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
1039 rtw_free_stainfo(adapter
, pcur_sta
);
1040 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
1043 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, pnetwork
->network
.MacAddress
);
1044 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1046 ptarget_wlan
->fixed
= true;
1050 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, pnetwork
->network
.MacAddress
);
1051 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1053 ptarget_wlan
->fixed
= true;
1057 /* s2. update cur_network */
1059 rtw_joinbss_update_network(adapter
, ptarget_wlan
, pnetwork
);
1061 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Can't find ptarget_wlan when joinbss_event callback\n"));
1062 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1063 goto ignore_joinbss_callback
;
1066 /* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */
1067 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1068 ptarget_sta
= rtw_joinbss_update_stainfo(adapter
, pnetwork
);
1070 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Can't update stainfo when joinbss_event callback\n"));
1071 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1072 goto ignore_joinbss_callback
;
1076 /* s4. indicate connect */
1077 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true) {
1078 rtw_indicate_connect(adapter
);
1080 /* adhoc mode will rtw_indicate_connect when rtw_stassoc_event_callback */
1081 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("adhoc mode, fw_state:%x", get_fwstate(pmlmepriv
)));
1084 /* s5. Cancel assoc_timer */
1085 del_timer_sync(&pmlmepriv
->assoc_timer
);
1087 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
, ("Cancel assoc_timer\n"));
1090 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("rtw_joinbss_event_callback err: fw_state:%x", get_fwstate(pmlmepriv
)));
1091 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1092 goto ignore_joinbss_callback
;
1095 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1097 } else if (pnetwork
->join_res
== -4) {
1098 rtw_reset_securitypriv(adapter
);
1099 mod_timer(&pmlmepriv
->assoc_timer
,
1100 jiffies
+ msecs_to_jiffies(1));
1102 if ((check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
)) == true) {
1103 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n", get_fwstate(pmlmepriv
)));
1104 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
1106 } else { /* if join_res < 0 (join fails), then try again */
1107 mod_timer(&pmlmepriv
->assoc_timer
,
1108 jiffies
+ msecs_to_jiffies(1));
1109 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
1112 ignore_joinbss_callback
:
1113 spin_unlock_bh(&pmlmepriv
->lock
);
1116 void rtw_joinbss_event_callback(struct adapter
*adapter
, u8
*pbuf
)
1118 struct wlan_network
*pnetwork
= (struct wlan_network
*)pbuf
;
1120 mlmeext_joinbss_event_callback(adapter
, pnetwork
->join_res
);
1122 rtw_os_xmit_schedule(adapter
);
1125 static u8
search_max_mac_id(struct adapter
*padapter
)
1128 #if defined(CONFIG_88EU_AP_MODE)
1130 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
1131 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1133 struct mlme_ext_priv
*pmlmeext
= &(padapter
->mlmeextpriv
);
1134 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1136 #if defined(CONFIG_88EU_AP_MODE)
1137 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1138 for (aid
= pstapriv
->max_num_sta
; aid
> 0; aid
--) {
1139 if (pstapriv
->sta_aid
[aid
-1])
1145 {/* adhoc id = 31~2 */
1146 for (mac_id
= NUM_STA
-1; mac_id
>= IBSS_START_MAC_ID
; mac_id
--) {
1147 if (pmlmeinfo
->FW_sta_info
[mac_id
].status
== 1)
1154 /* FOR AP , AD-HOC mode */
1155 void rtw_stassoc_hw_rpt(struct adapter
*adapter
, struct sta_info
*psta
)
1163 macid
= search_max_mac_id(adapter
);
1164 rtw_hal_set_hwreg(adapter
, HW_VAR_TX_RPT_MAX_MACID
, (u8
*)&macid
);
1165 media_status
= (psta
->mac_id
<<8)|1; /* MACID|OPMODE:1 connect */
1166 rtw_hal_set_hwreg(adapter
, HW_VAR_H2C_MEDIA_STATUS_RPT
, (u8
*)&media_status
);
1169 void rtw_stassoc_event_callback(struct adapter
*adapter
, u8
*pbuf
)
1171 struct sta_info
*psta
;
1172 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1173 struct stassoc_event
*pstassoc
= (struct stassoc_event
*)pbuf
;
1174 struct wlan_network
*cur_network
= &(pmlmepriv
->cur_network
);
1175 struct wlan_network
*ptarget_wlan
= NULL
;
1177 if (rtw_access_ctrl(adapter
, pstassoc
->macaddr
) == false)
1180 #if defined(CONFIG_88EU_AP_MODE)
1181 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1182 psta
= rtw_get_stainfo(&adapter
->stapriv
, pstassoc
->macaddr
);
1184 ap_sta_info_defer_update(adapter
, psta
);
1185 rtw_stassoc_hw_rpt(adapter
, psta
);
1190 /* for AD-HOC mode */
1191 psta
= rtw_get_stainfo(&adapter
->stapriv
, pstassoc
->macaddr
);
1193 /* the sta have been in sta_info_queue => do nothing */
1194 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Error: rtw_stassoc_event_callback: sta has been in sta_hash_queue\n"));
1195 return; /* between drv has received this event before and fw have not yet to set key to CAM_ENTRY) */
1197 psta
= rtw_alloc_stainfo(&adapter
->stapriv
, pstassoc
->macaddr
);
1199 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("Can't alloc sta_info when rtw_stassoc_event_callback\n"));
1202 /* to do: init sta_info variable */
1203 psta
->qos_option
= 0;
1204 psta
->mac_id
= (uint
)pstassoc
->cam_id
;
1205 DBG_88E("%s\n", __func__
);
1206 /* for ad-hoc mode */
1207 rtw_hal_set_odm_var(adapter
, HAL_ODM_STA_INFO
, psta
, true);
1208 rtw_stassoc_hw_rpt(adapter
, psta
);
1209 if (adapter
->securitypriv
.dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
)
1210 psta
->dot118021XPrivacy
= adapter
->securitypriv
.dot11PrivacyAlgrthm
;
1211 psta
->ieee8021x_blocked
= false;
1212 spin_lock_bh(&pmlmepriv
->lock
);
1213 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) ||
1214 (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
))) {
1215 if (adapter
->stapriv
.asoc_sta_count
== 2) {
1216 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1217 ptarget_wlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, cur_network
->network
.MacAddress
);
1219 ptarget_wlan
->fixed
= true;
1220 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1221 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1222 rtw_indicate_connect(adapter
);
1225 spin_unlock_bh(&pmlmepriv
->lock
);
1226 mlmeext_sta_add_event_callback(adapter
, psta
);
1229 void rtw_stadel_event_callback(struct adapter
*adapter
, u8
*pbuf
)
1232 struct sta_info
*psta
;
1233 struct wlan_network
*pwlan
= NULL
;
1234 struct wlan_bssid_ex
*pdev_network
= NULL
;
1236 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1237 struct stadel_event
*pstadel
= (struct stadel_event
*)pbuf
;
1238 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
1239 struct wlan_network
*tgt_network
= &(pmlmepriv
->cur_network
);
1241 psta
= rtw_get_stainfo(&adapter
->stapriv
, pstadel
->macaddr
);
1243 mac_id
= psta
->mac_id
;
1245 mac_id
= pstadel
->mac_id
;
1247 DBG_88E("%s(mac_id=%d)=%pM\n", __func__
, mac_id
, pstadel
->macaddr
);
1252 media_status
= (mac_id
<<8)|0; /* MACID|OPMODE:0 means disconnect */
1253 /* for STA, AP, ADHOC mode, report disconnect stauts to FW */
1254 rtw_hal_set_hwreg(adapter
, HW_VAR_H2C_MEDIA_STATUS_RPT
, (u8
*)&media_status
);
1257 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
))
1260 mlmeext_sta_del_event_callback(adapter
);
1262 spin_lock_bh(&pmlmepriv
->lock
);
1264 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
)) {
1265 if (pmlmepriv
->to_roaming
> 0)
1266 pmlmepriv
->to_roaming
--; /* this stadel_event is caused by roaming, decrease to_roaming */
1267 else if (pmlmepriv
->to_roaming
== 0)
1268 pmlmepriv
->to_roaming
= adapter
->registrypriv
.max_roaming_times
;
1270 if (*((unsigned short *)(pstadel
->rsvd
)) != WLAN_REASON_EXPIRATION_CHK
)
1271 pmlmepriv
->to_roaming
= 0; /* don't roam */
1273 rtw_free_uc_swdec_pending_queue(adapter
);
1275 rtw_free_assoc_resources(adapter
);
1276 rtw_indicate_disconnect(adapter
);
1277 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1278 /* remove the network entry in scanned_queue */
1279 pwlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, tgt_network
->network
.MacAddress
);
1281 pwlan
->fixed
= false;
1282 rtw_free_network_nolock(pmlmepriv
, pwlan
);
1284 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1285 _rtw_roaming(adapter
, tgt_network
);
1287 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) ||
1288 check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)) {
1289 spin_lock_bh(&(pstapriv
->sta_hash_lock
));
1290 rtw_free_stainfo(adapter
, psta
);
1291 spin_unlock_bh(&pstapriv
->sta_hash_lock
);
1293 if (adapter
->stapriv
.asoc_sta_count
== 1) { /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1294 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1295 /* free old ibss network */
1296 pwlan
= rtw_find_network(&pmlmepriv
->scanned_queue
, tgt_network
->network
.MacAddress
);
1298 pwlan
->fixed
= false;
1299 rtw_free_network_nolock(pmlmepriv
, pwlan
);
1301 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1302 /* re-create ibss */
1303 pdev_network
= &(adapter
->registrypriv
.dev_network
);
1304 pibss
= adapter
->registrypriv
.dev_network
.MacAddress
;
1306 memcpy(pdev_network
, &tgt_network
->network
, get_wlan_bssid_ex_sz(&tgt_network
->network
));
1308 memcpy(&pdev_network
->Ssid
, &pmlmepriv
->assoc_ssid
, sizeof(struct ndis_802_11_ssid
));
1310 rtw_update_registrypriv_dev_network(adapter
);
1312 rtw_generate_random_ibss(pibss
);
1314 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
)) {
1315 set_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
);
1316 _clr_fwstate_(pmlmepriv
, WIFI_ADHOC_STATE
);
1319 if (rtw_createbss_cmd(adapter
) != _SUCCESS
)
1320 RT_TRACE(_module_rtl871x_ioctl_set_c_
, _drv_err_
, ("***Error=>stadel_event_callback: rtw_createbss_cmd status FAIL***\n "));
1323 spin_unlock_bh(&pmlmepriv
->lock
);
1326 void rtw_cpwm_event_callback(struct adapter
*padapter
, u8
*pbuf
)
1328 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("+rtw_cpwm_event_callback !!!\n"));
1332 * _rtw_join_timeout_handler - Timeout/failure handler for CMD JoinBss
1333 * @adapter: pointer to struct adapter structure
1335 void _rtw_join_timeout_handler (struct timer_list
*t
)
1337 struct adapter
*adapter
=
1338 from_timer(adapter
, t
, mlmepriv
.assoc_timer
);
1339 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1342 DBG_88E("%s, fw_state=%x\n", __func__
, get_fwstate(pmlmepriv
));
1344 if (adapter
->bDriverStopped
|| adapter
->bSurpriseRemoved
)
1347 spin_lock_bh(&pmlmepriv
->lock
);
1349 if (pmlmepriv
->to_roaming
> 0) { /* join timeout caused by roaming */
1351 pmlmepriv
->to_roaming
--;
1352 if (pmlmepriv
->to_roaming
!= 0) { /* try another , */
1353 DBG_88E("%s try another roaming\n", __func__
);
1354 do_join_r
= rtw_do_join(adapter
);
1355 if (do_join_r
!= _SUCCESS
) {
1356 DBG_88E("%s roaming do_join return %d\n", __func__
, do_join_r
);
1361 DBG_88E("%s We've try roaming but fail\n", __func__
);
1362 rtw_indicate_disconnect(adapter
);
1367 rtw_indicate_disconnect(adapter
);
1368 free_scanqueue(pmlmepriv
);/* */
1370 spin_unlock_bh(&pmlmepriv
->lock
);
1374 * rtw_scan_timeout_handler - Timeout/Failure handler for CMD SiteSurvey
1375 * @adapter: pointer to struct adapter structure
1377 void rtw_scan_timeout_handler (struct timer_list
*t
)
1379 struct adapter
*adapter
=
1380 from_timer(adapter
, t
, mlmepriv
.scan_to_timer
);
1381 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1383 DBG_88E(FUNC_ADPT_FMT
" fw_state=%x\n", FUNC_ADPT_ARG(adapter
), get_fwstate(pmlmepriv
));
1384 spin_lock_bh(&pmlmepriv
->lock
);
1385 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
1386 spin_unlock_bh(&pmlmepriv
->lock
);
1387 rtw_indicate_scan_done(adapter
, true);
1390 static void rtw_auto_scan_handler(struct adapter
*padapter
)
1392 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1394 /* auto site survey per 60sec */
1395 if (pmlmepriv
->scan_interval
> 0) {
1396 pmlmepriv
->scan_interval
--;
1397 if (pmlmepriv
->scan_interval
== 0) {
1398 DBG_88E("%s\n", __func__
);
1399 rtw_set_802_11_bssid_list_scan(padapter
, NULL
, 0);
1400 pmlmepriv
->scan_interval
= SCAN_INTERVAL
;/* 30*2 sec = 60sec */
1405 void rtw_dynamic_check_timer_handlder(struct timer_list
*t
)
1407 struct adapter
*adapter
=
1408 from_timer(adapter
, t
, mlmepriv
.dynamic_chk_timer
);
1409 struct registry_priv
*pregistrypriv
= &adapter
->registrypriv
;
1413 if (!adapter
->hw_init_completed
)
1415 if ((adapter
->bDriverStopped
) || (adapter
->bSurpriseRemoved
))
1417 if (adapter
->net_closed
)
1419 rtw_dynamic_chk_wk_cmd(adapter
);
1421 if (pregistrypriv
->wifi_spec
== 1) {
1422 /* auto site survey */
1423 rtw_auto_scan_handler(adapter
);
1426 mod_timer(&adapter
->mlmepriv
.dynamic_chk_timer
,
1427 jiffies
+ msecs_to_jiffies(2000));
1430 #define RTW_SCAN_RESULT_EXPIRE 2000
1433 * Select a new join candidate from the original @param candidate and @param competitor
1434 * @return true: candidate is updated
1435 * @return false: candidate is not updated
1437 static int rtw_check_join_candidate(struct mlme_priv
*pmlmepriv
1438 , struct wlan_network
**candidate
, struct wlan_network
*competitor
)
1440 int updated
= false;
1441 unsigned long since_scan
;
1442 struct adapter
*adapter
= container_of(pmlmepriv
, struct adapter
, mlmepriv
);
1444 /* check bssid, if needed */
1445 if (pmlmepriv
->assoc_by_bssid
) {
1446 if (memcmp(competitor
->network
.MacAddress
, pmlmepriv
->assoc_bssid
, ETH_ALEN
))
1450 /* check ssid, if needed */
1451 if (pmlmepriv
->assoc_ssid
.SsidLength
) {
1452 if (competitor
->network
.Ssid
.SsidLength
!= pmlmepriv
->assoc_ssid
.SsidLength
||
1453 !memcmp(competitor
->network
.Ssid
.Ssid
, pmlmepriv
->assoc_ssid
.Ssid
, pmlmepriv
->assoc_ssid
.SsidLength
) == false)
1457 if (rtw_is_desired_network(adapter
, competitor
) == false)
1460 if (pmlmepriv
->to_roaming
) {
1461 since_scan
= jiffies
- competitor
->last_scanned
;
1462 if (jiffies_to_msecs(since_scan
) >= RTW_SCAN_RESULT_EXPIRE
||
1463 is_same_ess(&competitor
->network
, &pmlmepriv
->cur_network
.network
) == false)
1467 if (*candidate
== NULL
|| (*candidate
)->network
.Rssi
< competitor
->network
.Rssi
) {
1468 *candidate
= competitor
;
1472 DBG_88E("[by_bssid:%u][assoc_ssid:%s]new candidate: %s(%pM rssi:%d\n",
1473 pmlmepriv
->assoc_by_bssid
,
1474 pmlmepriv
->assoc_ssid
.Ssid
,
1475 (*candidate
)->network
.Ssid
.Ssid
,
1476 (*candidate
)->network
.MacAddress
,
1477 (int)(*candidate
)->network
.Rssi
);
1478 DBG_88E("[to_roaming:%u]\n", pmlmepriv
->to_roaming
);
1487 * The caller of the sub-routine will be in critical section...
1488 * The caller must hold the following spinlock
1492 int rtw_select_and_join_from_scanned_queue(struct mlme_priv
*pmlmepriv
)
1495 struct list_head
*phead
;
1496 struct adapter
*adapter
;
1497 struct __queue
*queue
= &(pmlmepriv
->scanned_queue
);
1498 struct wlan_network
*pnetwork
= NULL
;
1499 struct wlan_network
*candidate
= NULL
;
1500 u8 supp_ant_div
= false;
1502 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1503 phead
= get_list_head(queue
);
1504 adapter
= (struct adapter
*)pmlmepriv
->nic_hdl
;
1505 pmlmepriv
->pscanned
= phead
->next
;
1506 while (phead
!= pmlmepriv
->pscanned
) {
1507 pnetwork
= container_of(pmlmepriv
->pscanned
, struct wlan_network
, list
);
1509 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("%s return _FAIL:(pnetwork==NULL)\n", __func__
));
1513 pmlmepriv
->pscanned
= pmlmepriv
->pscanned
->next
;
1514 rtw_check_join_candidate(pmlmepriv
, &candidate
, pnetwork
);
1517 DBG_88E("%s: return _FAIL(candidate==NULL)\n", __func__
);
1521 DBG_88E("%s: candidate: %s(%pM ch:%u)\n", __func__
,
1522 candidate
->network
.Ssid
.Ssid
, candidate
->network
.MacAddress
,
1523 candidate
->network
.Configuration
.DSConfig
);
1526 /* check for situation of _FW_LINKED */
1527 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true) {
1528 DBG_88E("%s: _FW_LINKED while ask_for_joinbss!!!\n", __func__
);
1530 rtw_disassoc_cmd(adapter
, 0, true);
1531 rtw_indicate_disconnect(adapter
);
1532 rtw_free_assoc_resources_locked(adapter
);
1535 rtw_hal_get_def_var(adapter
, HAL_DEF_IS_SUPPORT_ANT_DIV
, &(supp_ant_div
));
1539 rtw_hal_get_def_var(adapter
, HAL_DEF_CURRENT_ANTENNA
, &(cur_ant
));
1540 DBG_88E("#### Opt_Ant_(%s), cur_Ant(%s)\n",
1541 (candidate
->network
.PhyInfo
.Optimum_antenna
== 2) ? "A" : "B",
1542 (cur_ant
== 2) ? "A" : "B"
1546 ret
= rtw_joinbss_cmd(adapter
, candidate
);
1549 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1553 int rtw_set_auth(struct adapter
*adapter
, struct security_priv
*psecuritypriv
)
1555 struct cmd_obj
*pcmd
;
1556 struct setauth_parm
*psetauthparm
;
1557 struct cmd_priv
*pcmdpriv
= &(adapter
->cmdpriv
);
1560 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
1562 res
= _FAIL
; /* try again */
1566 psetauthparm
= kzalloc(sizeof(struct setauth_parm
), GFP_KERNEL
);
1567 if (!psetauthparm
) {
1572 psetauthparm
->mode
= (unsigned char)psecuritypriv
->dot11AuthAlgrthm
;
1573 pcmd
->cmdcode
= _SetAuth_CMD_
;
1574 pcmd
->parmbuf
= (unsigned char *)psetauthparm
;
1575 pcmd
->cmdsz
= sizeof(struct setauth_parm
);
1578 INIT_LIST_HEAD(&pcmd
->list
);
1579 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1580 ("after enqueue set_auth_cmd, auth_mode=%x\n",
1581 psecuritypriv
->dot11AuthAlgrthm
));
1582 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
1587 int rtw_set_key(struct adapter
*adapter
, struct security_priv
*psecuritypriv
, int keyid
, u8 set_tx
)
1590 struct cmd_obj
*pcmd
;
1591 struct setkey_parm
*psetkeyparm
;
1592 struct cmd_priv
*pcmdpriv
= &(adapter
->cmdpriv
);
1593 struct mlme_priv
*pmlmepriv
= &(adapter
->mlmepriv
);
1596 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
1598 return _FAIL
; /* try again */
1600 psetkeyparm
= kzalloc(sizeof(struct setkey_parm
), GFP_KERNEL
);
1606 if (psecuritypriv
->dot11AuthAlgrthm
== dot11AuthAlgrthm_8021X
) {
1607 psetkeyparm
->algorithm
= (unsigned char)psecuritypriv
->dot118021XGrpPrivacy
;
1608 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1609 ("\n rtw_set_key: psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy=%d\n",
1610 psetkeyparm
->algorithm
));
1612 psetkeyparm
->algorithm
= (u8
)psecuritypriv
->dot11PrivacyAlgrthm
;
1613 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1614 ("\n rtw_set_key: psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm=%d\n",
1615 psetkeyparm
->algorithm
));
1617 psetkeyparm
->keyid
= (u8
)keyid
;/* 0~3 */
1618 psetkeyparm
->set_tx
= set_tx
;
1619 pmlmepriv
->key_mask
|= BIT(psetkeyparm
->keyid
);
1620 DBG_88E("==> rtw_set_key algorithm(%x), keyid(%x), key_mask(%x)\n",
1621 psetkeyparm
->algorithm
, psetkeyparm
->keyid
, pmlmepriv
->key_mask
);
1622 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1623 ("\n rtw_set_key: psetkeyparm->algorithm=%d psetkeyparm->keyid=(u8)keyid=%d\n",
1624 psetkeyparm
->algorithm
, keyid
));
1626 switch (psetkeyparm
->algorithm
) {
1629 memcpy(&(psetkeyparm
->key
[0]), &(psecuritypriv
->dot11DefKey
[keyid
].skey
[0]), keylen
);
1633 memcpy(&(psetkeyparm
->key
[0]), &(psecuritypriv
->dot11DefKey
[keyid
].skey
[0]), keylen
);
1637 memcpy(&psetkeyparm
->key
, &psecuritypriv
->dot118021XGrpKey
[keyid
], keylen
);
1638 psetkeyparm
->grpkey
= 1;
1642 memcpy(&psetkeyparm
->key
, &psecuritypriv
->dot118021XGrpKey
[keyid
], keylen
);
1643 psetkeyparm
->grpkey
= 1;
1646 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
1647 ("\n rtw_set_key:psecuritypriv->dot11PrivacyAlgrthm=%x (must be 1 or 2 or 4 or 5)\n",
1648 psecuritypriv
->dot11PrivacyAlgrthm
));
1652 pcmd
->cmdcode
= _SetKey_CMD_
;
1653 pcmd
->parmbuf
= (u8
*)psetkeyparm
;
1654 pcmd
->cmdsz
= sizeof(struct setkey_parm
);
1657 INIT_LIST_HEAD(&pcmd
->list
);
1658 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
1668 /* adjust IEs for rtw_joinbss_cmd in WMM */
1669 int rtw_restruct_wmm_ie(struct adapter
*adapter
, u8
*in_ie
, u8
*out_ie
, uint in_len
, uint initial_out_len
)
1671 unsigned int ielength
= 0;
1674 /* i = 12; after the fixed IE */
1675 for (i
= 12; i
< in_len
; i
+= (in_ie
[i
+ 1] + 2) /* to the next IE element */) {
1676 ielength
= initial_out_len
;
1678 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
) {
1679 /* WMM element ID and OUI */
1680 /* Append WMM IE to the last index of out_ie */
1682 for (j
= i
; j
< i
+ 9; j
++) {
1683 out_ie
[ielength
] = in_ie
[j
];
1686 out_ie
[initial_out_len
+ 1] = 0x07;
1687 out_ie
[initial_out_len
+ 6] = 0x00;
1688 out_ie
[initial_out_len
+ 8] = 0x00;
1696 * Ported from 8185: IsInPreAuthKeyList().
1697 * (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.)
1698 * Added by Annie, 2006-05-07.
1701 * -1 :if there is no pre-auth key in the table
1702 * >= 0 :if there is pre-auth key, and return the entry id
1704 static int SecIsInPMKIDList(struct adapter
*Adapter
, u8
*bssid
)
1706 struct security_priv
*psecuritypriv
= &Adapter
->securitypriv
;
1710 if ((psecuritypriv
->PMKIDList
[i
].bUsed
) &&
1711 (!memcmp(psecuritypriv
->PMKIDList
[i
].Bssid
, bssid
, ETH_ALEN
)))
1713 } while (++i
< NUM_PMKID_CACHE
);
1715 if (i
== NUM_PMKID_CACHE
)
1716 i
= -1;/* Could not find. */
1722 /* Check the RSN IE length */
1723 /* If the RSN IE length <= 20, the RSN IE didn't include the PMKID information */
1724 /* 0-11th element in the array are the fixed IE */
1725 /* 12th element in the array is the IE */
1726 /* 13th element in the array is the IE length */
1729 static int rtw_append_pmkid(struct adapter
*Adapter
, int iEntry
, u8
*ie
, uint ie_len
)
1731 struct security_priv
*psecuritypriv
= &Adapter
->securitypriv
;
1734 /* The RSN IE didn't include the PMK ID, append the PMK information */
1737 ie
[ie_len
] = 0; /* PMKID count = 0x0100 */
1739 memcpy(&ie
[ie_len
], &psecuritypriv
->PMKIDList
[iEntry
].PMKID
, 16);
1742 ie
[13] += 18;/* PMKID length = 2+16 */
1747 int rtw_restruct_sec_ie(struct adapter
*adapter
, u8
*in_ie
, u8
*out_ie
, uint in_len
)
1753 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1754 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
1755 uint ndisauthmode
= psecuritypriv
->ndisauthtype
;
1756 uint ndissecuritytype
= psecuritypriv
->ndisencryptstatus
;
1758 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
1759 ("+%s: ndisauthmode=%d ndissecuritytype=%d\n", __func__
,
1760 ndisauthmode
, ndissecuritytype
));
1762 /* copy fixed ie only */
1763 memcpy(out_ie
, in_ie
, 12);
1765 if ((ndisauthmode
== Ndis802_11AuthModeWPA
) ||
1766 (ndisauthmode
== Ndis802_11AuthModeWPAPSK
))
1767 authmode
= _WPA_IE_ID_
;
1768 if ((ndisauthmode
== Ndis802_11AuthModeWPA2
) ||
1769 (ndisauthmode
== Ndis802_11AuthModeWPA2PSK
))
1770 authmode
= _WPA2_IE_ID_
;
1772 if (check_fwstate(pmlmepriv
, WIFI_UNDER_WPS
)) {
1773 memcpy(out_ie
+ielength
, psecuritypriv
->wps_ie
, psecuritypriv
->wps_ie_len
);
1775 ielength
+= psecuritypriv
->wps_ie_len
;
1776 } else if ((authmode
== _WPA_IE_ID_
) || (authmode
== _WPA2_IE_ID_
)) {
1777 /* copy RSN or SSN */
1778 memcpy(&out_ie
[ielength
], &psecuritypriv
->supplicant_ie
[0], psecuritypriv
->supplicant_ie
[1]+2);
1779 ielength
+= psecuritypriv
->supplicant_ie
[1]+2;
1780 rtw_report_sec_ie(adapter
, authmode
, psecuritypriv
->supplicant_ie
);
1783 iEntry
= SecIsInPMKIDList(adapter
, pmlmepriv
->assoc_bssid
);
1787 if (authmode
== _WPA2_IE_ID_
)
1788 ielength
= rtw_append_pmkid(adapter
, iEntry
, out_ie
, ielength
);
1793 void rtw_init_registrypriv_dev_network(struct adapter
*adapter
)
1795 struct registry_priv
*pregistrypriv
= &adapter
->registrypriv
;
1796 struct eeprom_priv
*peepriv
= &adapter
->eeprompriv
;
1797 struct wlan_bssid_ex
*pdev_network
= &pregistrypriv
->dev_network
;
1798 u8
*myhwaddr
= myid(peepriv
);
1800 memcpy(pdev_network
->MacAddress
, myhwaddr
, ETH_ALEN
);
1802 memcpy(&pdev_network
->Ssid
, &pregistrypriv
->ssid
, sizeof(struct ndis_802_11_ssid
));
1804 pdev_network
->Configuration
.Length
= sizeof(struct ndis_802_11_config
);
1805 pdev_network
->Configuration
.BeaconPeriod
= 100;
1806 pdev_network
->Configuration
.FHConfig
.Length
= 0;
1807 pdev_network
->Configuration
.FHConfig
.HopPattern
= 0;
1808 pdev_network
->Configuration
.FHConfig
.HopSet
= 0;
1809 pdev_network
->Configuration
.FHConfig
.DwellTime
= 0;
1812 void rtw_update_registrypriv_dev_network(struct adapter
*adapter
)
1815 struct registry_priv
*pregistrypriv
= &adapter
->registrypriv
;
1816 struct wlan_bssid_ex
*pdev_network
= &pregistrypriv
->dev_network
;
1817 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
1818 struct wlan_network
*cur_network
= &adapter
->mlmepriv
.cur_network
;
1820 pdev_network
->Privacy
= psecuritypriv
->dot11PrivacyAlgrthm
> 0 ? 1 : 0; /* adhoc no 802.1x */
1822 pdev_network
->Rssi
= 0;
1824 switch (pregistrypriv
->wireless_mode
) {
1826 pdev_network
->NetworkTypeInUse
= Ndis802_11DS
;
1830 case WIRELESS_11_24N
:
1831 case WIRELESS_11G_24N
:
1832 case WIRELESS_11BG_24N
:
1833 pdev_network
->NetworkTypeInUse
= Ndis802_11OFDM24
;
1836 case WIRELESS_11A_5N
:
1837 pdev_network
->NetworkTypeInUse
= Ndis802_11OFDM5
;
1839 case WIRELESS_11ABGN
:
1840 if (pregistrypriv
->channel
> 14)
1841 pdev_network
->NetworkTypeInUse
= Ndis802_11OFDM5
;
1843 pdev_network
->NetworkTypeInUse
= Ndis802_11OFDM24
;
1850 pdev_network
->Configuration
.DSConfig
= pregistrypriv
->channel
;
1851 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_info_
,
1852 ("pregistrypriv->channel=%d, pdev_network->Configuration.DSConfig=0x%x\n",
1853 pregistrypriv
->channel
, pdev_network
->Configuration
.DSConfig
));
1855 if (cur_network
->network
.InfrastructureMode
== Ndis802_11IBSS
)
1856 pdev_network
->Configuration
.ATIMWindow
= 0;
1858 pdev_network
->InfrastructureMode
= cur_network
->network
.InfrastructureMode
;
1860 /* 1. Supported rates */
1863 sz
= rtw_generate_ie(pregistrypriv
);
1864 pdev_network
->IELength
= sz
;
1865 pdev_network
->Length
= get_wlan_bssid_ex_sz((struct wlan_bssid_ex
*)pdev_network
);
1867 /* notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); */
1868 /* pdev_network->IELength = cpu_to_le32(sz); */
1871 void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter
*adapter
)
1875 /* the function is at passive_level */
1876 void rtw_joinbss_reset(struct adapter
*padapter
)
1879 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1880 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
1882 /* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */
1883 pmlmepriv
->num_FortyMHzIntolerant
= 0;
1885 pmlmepriv
->num_sta_no_ht
= 0;
1887 phtpriv
->ampdu_enable
= false;/* reset to disabled */
1889 /* TH = 1 => means that invalidate usb rx aggregation */
1890 /* TH = 0 => means that validate usb rx aggregation, use init value. */
1891 if (phtpriv
->ht_option
) {
1892 if (padapter
->registrypriv
.wifi_spec
== 1)
1896 rtw_hal_set_hwreg(padapter
, HW_VAR_RXDMA_AGG_PG_TH
, (u8
*)(&threshold
));
1899 rtw_hal_set_hwreg(padapter
, HW_VAR_RXDMA_AGG_PG_TH
, (u8
*)(&threshold
));
1903 /* the function is >= passive_level */
1904 unsigned int rtw_restructure_ht_ie(struct adapter
*padapter
, u8
*in_ie
, u8
*out_ie
, uint in_len
, uint
*pout_len
)
1907 enum ht_cap_ampdu_factor max_rx_ampdu_factor
;
1909 unsigned char WMM_IE
[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
1910 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1911 struct qos_priv
*pqospriv
= &pmlmepriv
->qospriv
;
1912 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
1913 u32 rx_packet_offset
, max_recvbuf_sz
;
1915 phtpriv
->ht_option
= false;
1917 p
= rtw_get_ie(in_ie
+12, _HT_CAPABILITY_IE_
, &ielen
, in_len
-12);
1919 if (p
&& ielen
> 0) {
1920 struct ieee80211_ht_cap ht_cap
;
1922 if (pqospriv
->qos_option
== 0) {
1923 out_len
= *pout_len
;
1924 rtw_set_ie(out_ie
+ out_len
, _VENDOR_SPECIFIC_IE_
,
1925 _WMM_IE_Length_
, WMM_IE
, pout_len
);
1927 pqospriv
->qos_option
= 1;
1930 out_len
= *pout_len
;
1932 memset(&ht_cap
, 0, sizeof(struct ieee80211_ht_cap
));
1934 ht_cap
.cap_info
= cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH
|
1935 IEEE80211_HT_CAP_SGI_20
|
1936 IEEE80211_HT_CAP_SGI_40
|
1937 IEEE80211_HT_CAP_TX_STBC
|
1938 IEEE80211_HT_CAP_DSSSCCK40
);
1940 rtw_hal_get_def_var(padapter
, HAL_DEF_RX_PACKET_OFFSET
, &rx_packet_offset
);
1941 rtw_hal_get_def_var(padapter
, HAL_DEF_MAX_RECVBUF_SZ
, &max_recvbuf_sz
);
1944 ampdu_params_info [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
1945 ampdu_params_info [4:2]:Min MPDU Start Spacing
1948 rtw_hal_get_def_var(padapter
, HW_VAR_MAX_RX_AMPDU_FACTOR
, &max_rx_ampdu_factor
);
1949 ht_cap
.ampdu_params_info
= max_rx_ampdu_factor
& 0x03;
1951 if (padapter
->securitypriv
.dot11PrivacyAlgrthm
== _AES_
)
1952 ht_cap
.ampdu_params_info
|= IEEE80211_HT_CAP_AMPDU_DENSITY
& (0x07 << 2);
1954 ht_cap
.ampdu_params_info
|= IEEE80211_HT_CAP_AMPDU_DENSITY
& 0x00;
1956 rtw_set_ie(out_ie
+out_len
, _HT_CAPABILITY_IE_
,
1957 sizeof(struct ieee80211_ht_cap
),
1958 (unsigned char *)&ht_cap
, pout_len
);
1960 phtpriv
->ht_option
= true;
1962 p
= rtw_get_ie(in_ie
+12, _HT_ADD_INFO_IE_
, &ielen
, in_len
-12);
1963 if (p
&& (ielen
== sizeof(struct ieee80211_ht_addt_info
))) {
1964 out_len
= *pout_len
;
1965 rtw_set_ie(out_ie
+out_len
, _HT_ADD_INFO_IE_
, ielen
, p
+2, pout_len
);
1968 return phtpriv
->ht_option
;
1971 /* the function is > passive_level (in critical_section) */
1972 void rtw_update_ht_cap(struct adapter
*padapter
, u8
*pie
, uint ie_len
)
1974 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1975 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
1976 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
1977 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1978 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
1980 if (!phtpriv
->ht_option
)
1983 if ((!pmlmeinfo
->HT_info_enable
) || (!pmlmeinfo
->HT_caps_enable
))
1986 DBG_88E("+%s()\n", __func__
);
1988 /* maybe needs check if ap supports rx ampdu. */
1989 if ((!phtpriv
->ampdu_enable
) && (pregistrypriv
->ampdu_enable
== 1)) {
1990 if (pregistrypriv
->wifi_spec
== 1)
1991 phtpriv
->ampdu_enable
= false;
1993 phtpriv
->ampdu_enable
= true;
1994 } else if (pregistrypriv
->ampdu_enable
== 2) {
1995 phtpriv
->ampdu_enable
= true;
1998 /* update cur_bwmode & cur_ch_offset */
1999 if ((pregistrypriv
->cbw40_enable
) &&
2000 (le16_to_cpu(pmlmeinfo
->HT_caps
.cap_info
) & BIT(1)) &&
2001 (pmlmeinfo
->HT_info
.infos
[0] & BIT(2))) {
2004 /* update the MCS rates */
2005 for (i
= 0; i
< 16; i
++)
2006 ((u8
*)&pmlmeinfo
->HT_caps
.mcs
)[i
] &= MCS_rate_1R
[i
];
2007 /* switch to the 40M Hz mode according to the AP */
2008 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_40
;
2009 switch ((pmlmeinfo
->HT_info
.infos
[0] & 0x3)) {
2010 case HT_EXTCHNL_OFFSET_UPPER
:
2011 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_LOWER
;
2013 case HT_EXTCHNL_OFFSET_LOWER
:
2014 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_UPPER
;
2017 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
2022 /* Config SM Power Save setting */
2023 pmlmeinfo
->SM_PS
= (le16_to_cpu(pmlmeinfo
->HT_caps
.cap_info
) & 0x0C) >> 2;
2024 if (pmlmeinfo
->SM_PS
== WLAN_HT_CAP_SM_PS_STATIC
)
2025 DBG_88E("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__
);
2027 /* Config current HT Protection mode. */
2028 pmlmeinfo
->HT_protection
= pmlmeinfo
->HT_info
.infos
[1] & 0x3;
2031 void rtw_issue_addbareq_cmd(struct adapter
*padapter
, struct xmit_frame
*pxmitframe
)
2035 struct sta_info
*psta
= NULL
;
2036 struct ht_priv
*phtpriv
;
2037 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
2038 s32 bmcst
= IS_MCAST(pattrib
->ra
);
2040 if (bmcst
|| (padapter
->mlmepriv
.LinkDetectInfo
.NumTxOkInPeriod
< 100))
2043 priority
= pattrib
->priority
;
2046 psta
= pattrib
->psta
;
2048 psta
= rtw_get_stainfo(&padapter
->stapriv
, pattrib
->ra
);
2053 phtpriv
= &psta
->htpriv
;
2055 if ((phtpriv
->ht_option
) && (phtpriv
->ampdu_enable
)) {
2056 issued
= (phtpriv
->agg_enable_bitmap
>> priority
) & 0x1;
2057 issued
|= (phtpriv
->candidate_tid_bitmap
>> priority
) & 0x1;
2060 DBG_88E("%s, p=%d\n", __func__
, priority
);
2061 psta
->htpriv
.candidate_tid_bitmap
|= BIT((u8
)priority
);
2062 rtw_addbareq_cmd(padapter
, (u8
)priority
, pattrib
->ra
);
2067 void rtw_roaming(struct adapter
*padapter
, struct wlan_network
*tgt_network
)
2069 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2071 spin_lock_bh(&pmlmepriv
->lock
);
2072 _rtw_roaming(padapter
, tgt_network
);
2073 spin_unlock_bh(&pmlmepriv
->lock
);
2076 void _rtw_roaming(struct adapter
*padapter
, struct wlan_network
*tgt_network
)
2078 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2081 struct wlan_network
*pnetwork
;
2084 pnetwork
= tgt_network
;
2086 pnetwork
= &pmlmepriv
->cur_network
;
2088 if (pmlmepriv
->to_roaming
> 0) {
2089 DBG_88E("roaming from %s(%pM length:%d\n",
2090 pnetwork
->network
.Ssid
.Ssid
, pnetwork
->network
.MacAddress
,
2091 pnetwork
->network
.Ssid
.SsidLength
);
2092 memcpy(&pmlmepriv
->assoc_ssid
, &pnetwork
->network
.Ssid
, sizeof(struct ndis_802_11_ssid
));
2094 pmlmepriv
->assoc_by_bssid
= false;
2097 do_join_r
= rtw_do_join(padapter
);
2098 if (do_join_r
== _SUCCESS
) {
2101 DBG_88E("roaming do_join return %d\n", do_join_r
);
2102 pmlmepriv
->to_roaming
--;
2104 if (pmlmepriv
->to_roaming
> 0) {
2107 DBG_88E("%s(%d) -to roaming fail, indicate_disconnect\n", __func__
, __LINE__
);
2108 rtw_indicate_disconnect(padapter
);