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_sreset.h>
29 static struct wlan_network *
30 rtw_select_candidate_from_queue(struct mlme_priv *pmlmepriv);
31 static int rtw_do_join(struct rtw_adapter *padapter);
33 static void rtw_init_mlme_timer(struct rtw_adapter *padapter)
35 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
37 setup_timer(&pmlmepriv->assoc_timer, rtw23a_join_to_handler,
38 (unsigned long)padapter);
40 setup_timer(&pmlmepriv->scan_to_timer, rtw_scan_timeout_handler23a,
41 (unsigned long)padapter);
43 setup_timer(&pmlmepriv->dynamic_chk_timer,
44 rtw_dynamic_check_timer_handler, (unsigned long)padapter);
46 setup_timer(&pmlmepriv->set_scan_deny_timer,
47 rtw_set_scan_deny_timer_hdl, (unsigned long)padapter);
50 int rtw_init_mlme_priv23a(struct rtw_adapter *padapter)
52 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
54 pmlmepriv->nic_hdl = padapter;
56 pmlmepriv->fw_state = 0;
57 pmlmepriv->cur_network.network.ifmode = NL80211_IFTYPE_UNSPECIFIED;
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_probe_req_ie,
90 &pmlmepriv->wps_probe_req_ie_len);
94 void rtw_free_mlme_priv23a(struct mlme_priv *pmlmepriv)
96 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
97 "rtw_free_mlme_priv23a\n");
99 rtw23a_free_mlme_priv_ie_data(pmlmepriv);
102 struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv, gfp_t gfp)
104 struct wlan_network *pnetwork;
106 pnetwork = kzalloc(sizeof(struct wlan_network), gfp);
108 INIT_LIST_HEAD(&pnetwork->list);
109 pnetwork->network_type = 0;
110 pnetwork->fixed = false;
111 pnetwork->last_scanned = jiffies;
112 pnetwork->join_res = 0;
118 static void _rtw_free_network23a(struct mlme_priv *pmlmepriv,
119 struct wlan_network *pnetwork)
124 if (pnetwork->fixed == true)
127 list_del_init(&pnetwork->list);
133 return the wlan_network with the matching addr
135 Shall be called under atomic context... to avoid possible racing condition...
137 struct wlan_network *
138 rtw_find_network23a(struct rtw_queue *scanned_queue, u8 *addr)
140 struct list_head *phead, *plist;
141 struct wlan_network *pnetwork = NULL;
143 if (is_zero_ether_addr(addr)) {
148 /* spin_lock_bh(&scanned_queue->lock); */
150 phead = get_list_head(scanned_queue);
153 while (plist != phead) {
154 pnetwork = container_of(plist, struct wlan_network, list);
156 if (ether_addr_equal(addr, pnetwork->network.MacAddress))
165 /* spin_unlock_bh(&scanned_queue->lock); */
172 void rtw_free_network_queue23a(struct rtw_adapter *padapter)
174 struct list_head *phead, *plist, *ptmp;
175 struct wlan_network *pnetwork;
176 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
177 struct rtw_queue *scanned_queue = &pmlmepriv->scanned_queue;
179 spin_lock_bh(&scanned_queue->lock);
181 phead = get_list_head(scanned_queue);
183 list_for_each_safe(plist, ptmp, phead) {
184 pnetwork = container_of(plist, struct wlan_network, list);
186 _rtw_free_network23a(pmlmepriv, pnetwork);
189 spin_unlock_bh(&scanned_queue->lock);
192 int rtw_if_up23a(struct rtw_adapter *padapter)
196 if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
197 !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
198 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
199 "rtw_if_up23a:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
200 padapter->bDriverStopped, padapter->bSurpriseRemoved);
208 void rtw_generate_random_ibss23a(u8 *pibss)
210 unsigned long curtime = jiffies;
212 pibss[0] = 0x02; /* in ad-hoc mode bit1 must set to 1 */
215 pibss[3] = curtime & 0xff;/* p[0]; */
216 pibss[4] = (curtime >> 8) & 0xff;/* p[1]; */
217 pibss[5] = (curtime >> 16) & 0xff;/* p[2]; */
220 void rtw_set_roaming(struct rtw_adapter *adapter, u8 to_roaming)
223 adapter->mlmepriv.to_join = false;
224 adapter->mlmepriv.to_roaming = to_roaming;
227 static void _rtw_roaming(struct rtw_adapter *padapter,
228 struct wlan_network *tgt_network)
230 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
231 struct wlan_network *pnetwork;
235 pnetwork = tgt_network;
237 pnetwork = &pmlmepriv->cur_network;
239 if (padapter->mlmepriv.to_roaming > 0) {
240 DBG_8723A("roaming from %s(%pM), length:%d\n",
241 pnetwork->network.Ssid.ssid,
242 pnetwork->network.MacAddress,
243 pnetwork->network.Ssid.ssid_len);
244 memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid,
245 sizeof(struct cfg80211_ssid));
247 pmlmepriv->assoc_by_bssid = false;
250 do_join_r = rtw_do_join(padapter);
251 if (do_join_r == _SUCCESS)
254 DBG_8723A("roaming do_join return %d\n",
256 pmlmepriv->to_roaming--;
258 if (padapter->mlmepriv.to_roaming > 0)
261 DBG_8723A("%s(%d) -to roaming fail, "
262 "indicate_disconnect\n",
264 rtw_indicate_disconnect23a(padapter);
272 void rtw23a_roaming(struct rtw_adapter *padapter,
273 struct wlan_network *tgt_network)
275 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
277 spin_lock_bh(&pmlmepriv->lock);
278 _rtw_roaming(padapter, tgt_network);
279 spin_unlock_bh(&pmlmepriv->lock);
282 static void rtw_free_network_nolock(struct mlme_priv *pmlmepriv,
283 struct wlan_network *pnetwork)
285 _rtw_free_network23a(pmlmepriv, pnetwork);
288 bool rtw_is_same_ibss23a(struct rtw_adapter *adapter,
289 struct wlan_network *pnetwork)
292 struct security_priv *psecuritypriv = &adapter->securitypriv;
294 if (psecuritypriv->dot11PrivacyAlgrthm != 0 &&
295 pnetwork->network.Privacy == 0)
297 else if (psecuritypriv->dot11PrivacyAlgrthm == 0 &&
298 pnetwork->network.Privacy == 1)
306 inline int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b);
307 inline int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b)
309 return (a->Ssid.ssid_len == b->Ssid.ssid_len) &&
310 !memcmp(a->Ssid.ssid, b->Ssid.ssid, a->Ssid.ssid_len);
313 int is_same_network23a(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst)
317 s_cap = src->capability;
318 d_cap = dst->capability;
320 return ((src->Ssid.ssid_len == dst->Ssid.ssid_len) &&
321 /* (src->DSConfig == dst->DSConfig) && */
322 ether_addr_equal(src->MacAddress, dst->MacAddress) &&
323 !memcmp(src->Ssid.ssid, dst->Ssid.ssid, src->Ssid.ssid_len) &&
324 (s_cap & WLAN_CAPABILITY_IBSS) ==
325 (d_cap & WLAN_CAPABILITY_IBSS) &&
326 (s_cap & WLAN_CAPABILITY_ESS) == (d_cap & WLAN_CAPABILITY_ESS));
329 struct wlan_network *
330 rtw_get_oldest_wlan_network23a(struct rtw_queue *scanned_queue)
332 struct list_head *plist, *phead;
333 struct wlan_network *pwlan;
334 struct wlan_network *oldest = NULL;
336 phead = get_list_head(scanned_queue);
338 list_for_each(plist, phead) {
339 pwlan = container_of(plist, struct wlan_network, list);
341 if (pwlan->fixed != true) {
342 if (!oldest || time_after(oldest->last_scanned,
343 pwlan->last_scanned))
351 void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
352 struct rtw_adapter *padapter, bool update_ie)
354 u8 ss_ori = dst->SignalStrength;
355 u8 sq_ori = dst->SignalQuality;
356 long rssi_ori = dst->Rssi;
358 u8 ss_smp = src->SignalStrength;
359 u8 sq_smp = src->SignalQuality;
360 long rssi_smp = src->Rssi;
366 DBG_8723A("%s %s(%pM, ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, "
367 "ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n",
368 __func__, src->Ssid.ssid, src->MacAddress,
369 src->DSConfig, ss_ori, sq_ori, rssi_ori,
370 ss_smp, sq_smp, rssi_smp
373 /* The rule below is 1/5 for sample value, 4/5 for history value */
374 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) &&
375 is_same_network23a(&padapter->mlmepriv.cur_network.network, src)) {
376 /* Take the recvpriv's value for the connected AP*/
377 ss_final = padapter->recvpriv.signal_strength;
378 sq_final = padapter->recvpriv.signal_qual;
379 /* the rssi value here is undecorated, and will be
380 used for antenna diversity */
381 if (sq_smp != 101) /* from the right channel */
382 rssi_final = (src->Rssi+dst->Rssi*4)/5;
384 rssi_final = rssi_ori;
386 if (sq_smp != 101) { /* from the right channel */
387 ss_final = ((u32)src->SignalStrength +
388 (u32)dst->SignalStrength * 4) / 5;
389 sq_final = ((u32)src->SignalQuality +
390 (u32)dst->SignalQuality * 4) / 5;
391 rssi_final = src->Rssi+dst->Rssi * 4 / 5;
393 /* bss info not receiving from the right channel, use
394 the original RX signal infos */
395 ss_final = dst->SignalStrength;
396 sq_final = dst->SignalQuality;
397 rssi_final = dst->Rssi;
403 memcpy(dst, src, get_wlan_bssid_ex_sz(src));
405 dst->SignalStrength = ss_final;
406 dst->SignalQuality = sq_final;
407 dst->Rssi = rssi_final;
409 DBG_8723A("%s %s(%pM), SignalStrength:%u, SignalQuality:%u, "
410 "RawRSSI:%ld\n", __func__, dst->Ssid.ssid, dst->MacAddress,
411 dst->SignalStrength, dst->SignalQuality, dst->Rssi);
414 static void update_current_network(struct rtw_adapter *adapter,
415 struct wlan_bssid_ex *pnetwork)
417 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
419 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
420 is_same_network23a(&pmlmepriv->cur_network.network, pnetwork)) {
421 update_network23a(&pmlmepriv->cur_network.network,
422 pnetwork, adapter, true);
424 rtw_update_protection23a(adapter,
425 pmlmepriv->cur_network.network.IEs,
426 pmlmepriv->cur_network.network.IELength);
432 Caller must hold pmlmepriv->lock first.
435 static void rtw_update_scanned_network(struct rtw_adapter *adapter,
436 struct wlan_bssid_ex *target)
438 struct list_head *plist, *phead;
439 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
440 struct wlan_network *pnetwork = NULL;
441 struct wlan_network *oldest = NULL;
442 struct rtw_queue *queue = &pmlmepriv->scanned_queue;
446 spin_lock_bh(&queue->lock);
447 phead = get_list_head(queue);
449 list_for_each(plist, phead) {
450 pnetwork = container_of(plist, struct wlan_network, list);
452 if (is_same_network23a(&pnetwork->network, target)) {
456 if (!oldest || time_after(oldest->last_scanned,
457 pnetwork->last_scanned))
461 /* If we didn't find a match, then get a new network slot to initialize
462 * with this beacon's information */
464 pnetwork = rtw_alloc_network(pmlmepriv, GFP_ATOMIC);
467 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
468 "something wrong here\n");
473 list_add_tail(&pnetwork->list, &queue->queue);
475 bssid_ex_sz = get_wlan_bssid_ex_sz(target);
476 target->Length = bssid_ex_sz;
477 memcpy(&pnetwork->network, target, bssid_ex_sz);
479 /* variable initialize */
480 pnetwork->fixed = false;
481 pnetwork->last_scanned = jiffies;
483 pnetwork->network_type = 0;
484 pnetwork->join_res = 0;
486 /* bss info not receiving from the right channel */
487 if (pnetwork->network.SignalQuality == 101)
488 pnetwork->network.SignalQuality = 0;
491 * we have an entry and we are going to update it. But
492 * this entry may be already expired. In this case we
493 * do the same as we found a new net and call the
496 bool update_ie = true;
498 pnetwork->last_scanned = jiffies;
500 /* target.reserved == 1, means that scanned network is
502 if (pnetwork->network.IELength > target->IELength &&
503 target->reserved == 1)
506 update_network23a(&pnetwork->network, target, adapter,
511 spin_unlock_bh(&queue->lock);
514 static void rtw_add_network(struct rtw_adapter *adapter,
515 struct wlan_bssid_ex *pnetwork)
517 update_current_network(adapter, pnetwork);
518 rtw_update_scanned_network(adapter, pnetwork);
521 /* select the desired network based on the capability of the (i)bss. */
522 /* check items: (1) security */
523 /* (2) network_type */
527 static int rtw_is_desired_network(struct rtw_adapter *adapter,
528 struct wlan_network *pnetwork)
530 struct security_priv *psecuritypriv = &adapter->securitypriv;
531 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
534 int bselected = true;
536 desired_encmode = psecuritypriv->ndisencryptstatus;
537 privacy = pnetwork->network.Privacy;
539 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
540 if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
541 WLAN_OUI_TYPE_MICROSOFT_WPA,
542 pnetwork->network.IEs,
543 pnetwork->network.IELength))
548 if (adapter->registrypriv.wifi_spec == 1) {
549 /* for correct flow of 8021X to do.... */
550 if (desired_encmode == Ndis802_11EncryptionDisabled &&
555 if (desired_encmode != Ndis802_11EncryptionDisabled && privacy == 0) {
556 DBG_8723A("desired_encmode: %d, privacy: %d\n",
557 desired_encmode, privacy);
561 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
562 if (pnetwork->network.ifmode !=
563 pmlmepriv->cur_network.network.ifmode)
570 void rtw_survey_event_cb23a(struct rtw_adapter *adapter, const u8 *pbuf)
573 struct wlan_bssid_ex *pnetwork;
574 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
575 struct survey_event *survey = (struct survey_event *)pbuf;
577 pnetwork = survey->bss;
579 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
580 "rtw_survey_event_cb23a, ssid=%s\n", pnetwork->Ssid.ssid);
582 len = get_wlan_bssid_ex_sz(pnetwork);
583 if (len > (sizeof(struct wlan_bssid_ex))) {
584 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
585 "****rtw_survey_event_cb23a: return a wrong bss ***\n");
589 spin_lock_bh(&pmlmepriv->lock);
591 /* update IBSS_network 's timestamp */
592 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
593 if (ether_addr_equal(pmlmepriv->cur_network.network.MacAddress,
594 pnetwork->MacAddress)) {
595 struct wlan_network *ibss_wlan;
597 pmlmepriv->cur_network.network.beacon_interval =
598 pnetwork->beacon_interval;
599 pmlmepriv->cur_network.network.capability =
600 pnetwork->capability;
601 pmlmepriv->cur_network.network.tsf = pnetwork->tsf;
602 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
603 ibss_wlan = rtw_find_network23a(
604 &pmlmepriv->scanned_queue,
605 pnetwork->MacAddress);
607 pmlmepriv->cur_network.network.beacon_interval =
608 ibss_wlan->network.beacon_interval;
609 pmlmepriv->cur_network.network.capability =
610 ibss_wlan->network.capability;
611 pmlmepriv->cur_network.network.tsf =
612 ibss_wlan->network.tsf;
613 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
616 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
620 /* lock pmlmepriv->lock when you accessing network_q */
621 if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
622 if (pnetwork->Ssid.ssid[0] == 0)
623 pnetwork->Ssid.ssid_len = 0;
625 rtw_add_network(adapter, pnetwork);
630 spin_unlock_bh(&pmlmepriv->lock);
637 rtw_surveydone_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
639 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
640 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
643 spin_lock_bh(&pmlmepriv->lock);
645 if (pmlmepriv->wps_probe_req_ie) {
646 pmlmepriv->wps_probe_req_ie_len = 0;
647 kfree(pmlmepriv->wps_probe_req_ie);
648 pmlmepriv->wps_probe_req_ie = NULL;
651 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
652 "rtw_surveydone_event_callback23a: fw_state:%x\n",
653 get_fwstate(pmlmepriv));
655 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
656 del_timer_sync(&pmlmepriv->scan_to_timer);
658 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
660 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
661 "nic status =%x, survey done event comes too late!\n",
662 get_fwstate(pmlmepriv));
665 rtw_set_signal_stat_timer(&adapter->recvpriv);
667 if (pmlmepriv->to_join == true) {
668 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
669 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
670 ret = rtw_select_and_join_from_scanned_queue23a(
673 rtw_do_join_adhoc(adapter);
675 pmlmepriv->to_join = false;
676 ret = rtw_select_and_join_from_scanned_queue23a(
678 if (ret != _SUCCESS) {
679 DBG_8723A("try_to_join, but select scanning "
680 "queue fail, to_roaming:%d\n",
681 adapter->mlmepriv.to_roaming);
682 if (adapter->mlmepriv.to_roaming) {
683 if (--pmlmepriv->to_roaming == 0 ||
684 rtw_sitesurvey_cmd23a(
686 &pmlmepriv->assoc_ssid, 1,
687 NULL, 0) != _SUCCESS) {
688 rtw_set_roaming(adapter, 0);
689 rtw_free_assoc_resources23a(
691 rtw_indicate_disconnect23a(
694 pmlmepriv->to_join = true;
696 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
701 spin_unlock_bh(&pmlmepriv->lock);
703 rtw_os_xmit_schedule23a(adapter);
705 if (pmlmeext->sitesurvey_res.bss_cnt == 0)
706 rtw_sreset_reset(adapter);
708 rtw_cfg80211_surveydone_event_callback(adapter);
711 static void free_scanqueue(struct mlme_priv *pmlmepriv)
713 struct wlan_network *pnetwork;
714 struct rtw_queue *scan_queue = &pmlmepriv->scanned_queue;
715 struct list_head *plist, *phead, *ptemp;
717 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, "+free_scanqueue\n");
718 spin_lock_bh(&scan_queue->lock);
720 phead = get_list_head(scan_queue);
722 list_for_each_safe(plist, ptemp, phead) {
723 pnetwork = container_of(plist, struct wlan_network, list);
724 pnetwork->fixed = false;
725 _rtw_free_network23a(pmlmepriv, pnetwork);
728 spin_unlock_bh(&scan_queue->lock);
732 *rtw_free_assoc_resources23a: the caller has to lock pmlmepriv->lock
734 void rtw_free_assoc_resources23a(struct rtw_adapter *adapter,
735 int lock_scanned_queue)
737 struct wlan_network *pwlan;
738 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
739 struct sta_priv *pstapriv = &adapter->stapriv;
740 struct wlan_network *tgt_network = &pmlmepriv->cur_network;
741 struct sta_info *psta;
743 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
744 "+rtw_free_assoc_resources23a\n");
745 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
746 "tgt_network->network.MacAddress=%pM ssid=%s\n",
747 tgt_network->network.MacAddress,
748 tgt_network->network.Ssid.ssid);
750 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE)) {
751 psta = rtw_get_stainfo23a(&adapter->stapriv,
752 tgt_network->network.MacAddress);
754 spin_lock_bh(&pstapriv->sta_hash_lock);
755 rtw_free_stainfo23a(adapter, psta);
756 spin_unlock_bh(&pstapriv->sta_hash_lock);
759 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE |
760 WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) {
761 rtw_free_all_stainfo23a(adapter);
763 psta = rtw_get_bcmc_stainfo23a(adapter);
764 spin_lock_bh(&pstapriv->sta_hash_lock);
765 rtw_free_stainfo23a(adapter, psta);
766 spin_unlock_bh(&pstapriv->sta_hash_lock);
768 rtw_init_bcmc_stainfo23a(adapter);
771 if (lock_scanned_queue)
772 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
774 pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
775 tgt_network->network.MacAddress);
777 pwlan->fixed = false;
779 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
780 "rtw_free_assoc_resources23a : pwlan== NULL\n");
782 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) &&
783 adapter->stapriv.asoc_sta_count == 1)
784 rtw_free_network_nolock(pmlmepriv, pwlan);
786 if (lock_scanned_queue)
787 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
789 pmlmepriv->key_mask = 0;
793 *rtw_indicate_connect23a: the caller has to lock pmlmepriv->lock
795 void rtw_indicate_connect23a(struct rtw_adapter *padapter)
797 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
799 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
800 "+rtw_indicate_connect23a\n");
802 pmlmepriv->to_join = false;
804 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
805 set_fwstate(pmlmepriv, _FW_LINKED);
807 rtw_cfg80211_indicate_connect(padapter);
809 netif_carrier_on(padapter->pnetdev);
811 if (padapter->pid[2] != 0)
812 kill_pid(find_vpid(padapter->pid[2]), SIGALRM, 1);
815 rtw_set_roaming(padapter, 0);
817 rtw_set_scan_deny(padapter, 3000);
819 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
820 "-rtw_indicate_connect23a: fw_state=0x%08x\n",
821 get_fwstate(pmlmepriv));
825 *rtw_indicate_disconnect23a: the caller has to lock pmlmepriv->lock
827 void rtw_indicate_disconnect23a(struct rtw_adapter *padapter)
829 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
831 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
832 "+rtw_indicate_disconnect23a\n");
834 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS);
836 /* DBG_8723A("clear wps when %s\n", __func__); */
838 if (padapter->mlmepriv.to_roaming > 0)
839 _clr_fwstate_(pmlmepriv, _FW_LINKED);
841 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) ||
842 padapter->mlmepriv.to_roaming <= 0) {
843 rtw_os_indicate_disconnect23a(padapter);
845 /* set ips_deny_time to avoid enter IPS before LPS leave */
846 padapter->pwrctrlpriv.ips_deny_time =
847 jiffies + msecs_to_jiffies(3000);
849 _clr_fwstate_(pmlmepriv, _FW_LINKED);
851 rtw_clear_scan_deny(padapter);
854 rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_DISCONNECT, 1);
857 void rtw_scan_abort23a(struct rtw_adapter *adapter)
860 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
861 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
864 pmlmeext->scan_abort = true;
865 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) &&
866 jiffies_to_msecs(jiffies - start) <= 200) {
867 if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
870 DBG_8723A("%s(%s): fw_state = _FW_UNDER_SURVEY!\n",
871 __func__, adapter->pnetdev->name);
875 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
876 if (!adapter->bDriverStopped && !adapter->bSurpriseRemoved)
877 DBG_8723A("%s(%s): waiting for scan_abort time out!\n",
878 __func__, adapter->pnetdev->name);
879 rtw_cfg80211_indicate_scan_done(wdev_to_priv(adapter->rtw_wdev),
882 pmlmeext->scan_abort = false;
885 static struct sta_info *
886 rtw_joinbss_update_stainfo(struct rtw_adapter *padapter,
887 struct wlan_network *pnetwork)
890 struct sta_info *bmc_sta, *psta;
891 struct recv_reorder_ctrl *preorder_ctrl;
892 struct sta_priv *pstapriv = &padapter->stapriv;
894 psta = rtw_get_stainfo23a(pstapriv, pnetwork->network.MacAddress);
896 psta = rtw_alloc_stainfo23a(pstapriv,
897 pnetwork->network.MacAddress,
900 if (psta) { /* update ptarget_sta */
901 DBG_8723A("%s\n", __func__);
903 psta->aid = pnetwork->join_res;
907 rtl8723a_SetHalODMVar(padapter, HAL_ODM_STA_INFO, psta, true);
909 /* security related */
910 if (padapter->securitypriv.dot11AuthAlgrthm ==
911 dot11AuthAlgrthm_8021X) {
912 padapter->securitypriv.binstallGrpkey = 0;
913 padapter->securitypriv.busetkipkey = 0;
915 psta->ieee8021x_blocked = true;
916 psta->dot118021XPrivacy =
917 padapter->securitypriv.dot11PrivacyAlgrthm;
919 memset(&psta->dot118021x_UncstKey, 0,
920 sizeof (union Keytype));
922 memset(&psta->dot11tkiprxmickey, 0,
923 sizeof (union Keytype));
924 memset(&psta->dot11tkiptxmickey, 0,
925 sizeof (union Keytype));
927 memset(&psta->dot11txpn, 0, sizeof (union pn48));
928 memset(&psta->dot11rxpn, 0, sizeof (union pn48));
931 /* Commented by Albert 2012/07/21 */
932 /* When doing the WPS, the wps_ie_len won't equal to 0 */
933 /* And the Wi-Fi driver shouldn't allow the data packet
934 to be transmitted. */
935 if (padapter->securitypriv.wps_ie_len != 0) {
936 psta->ieee8021x_blocked = true;
937 padapter->securitypriv.wps_ie_len = 0;
940 /* for A-MPDU Rx reordering buffer control for bmc_sta &
942 /* if A-MPDU Rx is enabled, resetting
943 rx_ordering_ctrl wstart_b(indicate_seq) to default
945 /* todo: check if AP can send A-MPDU packets */
946 for (i = 0; i < 16 ; i++) {
947 /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
948 preorder_ctrl = &psta->recvreorder_ctrl[i];
949 preorder_ctrl->enable = false;
950 preorder_ctrl->indicate_seq = 0xffff;
951 preorder_ctrl->wend_b = 0xffff;
952 /* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
953 preorder_ctrl->wsize_b = 64;
956 bmc_sta = rtw_get_bcmc_stainfo23a(padapter);
958 for (i = 0; i < 16 ; i++) {
959 preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
960 preorder_ctrl->enable = false;
961 preorder_ctrl->indicate_seq = 0xffff;
962 preorder_ctrl->wend_b = 0xffff;
963 /* max_ampdu_sz; ex. 32(kbytes) ->
965 preorder_ctrl->wsize_b = 64;
970 update_sta_info23a(padapter, psta);
977 /* pnetwork : returns from rtw23a_joinbss_event_cb */
978 /* ptarget_wlan: found from scanned_queue */
980 rtw_joinbss_update_network23a(struct rtw_adapter *padapter,
981 struct wlan_network *ptarget_wlan,
982 struct wlan_network *pnetwork)
984 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
985 struct wlan_network *cur_network = &pmlmepriv->cur_network;
987 DBG_8723A("%s\n", __func__);
989 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
990 "fw_state:%x, BSSID:%pM\n",
991 get_fwstate(pmlmepriv),
992 pnetwork->network.MacAddress);
994 /* why not use ptarget_wlan?? */
995 memcpy(&cur_network->network, &pnetwork->network,
996 pnetwork->network.Length);
997 /* some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
998 cur_network->network.IELength = ptarget_wlan->network.IELength;
999 memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0],
1002 cur_network->network.capability = ptarget_wlan->network.capability;
1003 cur_network->network.beacon_interval =
1004 ptarget_wlan->network.beacon_interval;
1005 cur_network->network.tsf = ptarget_wlan->network.tsf;
1007 rtw_set_signal_stat_timer(&padapter->recvpriv);
1008 padapter->recvpriv.signal_strength =
1009 ptarget_wlan->network.SignalStrength;
1010 padapter->recvpriv.signal_qual = ptarget_wlan->network.SignalQuality;
1012 * the ptarget_wlan->network.Rssi is raw data, we use
1013 * ptarget_wlan->network.SignalStrength instead (has scaled)
1015 DBG_8723A("%s signal_strength:%3u, signal_qual:%3u\n",
1016 __func__, padapter->recvpriv.signal_strength,
1017 padapter->recvpriv.signal_qual);
1018 rtw_set_signal_stat_timer(&padapter->recvpriv);
1020 /* update fw_state will clr _FW_UNDER_LINKING here indirectly */
1021 switch (pnetwork->network.ifmode) {
1022 case NL80211_IFTYPE_P2P_CLIENT:
1023 case NL80211_IFTYPE_STATION:
1024 if (pmlmepriv->fw_state & WIFI_UNDER_WPS)
1025 pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS;
1027 pmlmepriv->fw_state = WIFI_STATION_STATE;
1029 case NL80211_IFTYPE_ADHOC:
1030 pmlmepriv->fw_state = WIFI_ADHOC_STATE;
1033 pmlmepriv->fw_state = WIFI_NULL_STATE;
1034 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1035 "Invalid network_mode\n");
1039 rtw_update_protection23a(padapter, cur_network->network.IEs,
1040 cur_network->network.IELength);
1042 rtw_update_ht_cap23a(padapter, cur_network->network.IEs,
1043 cur_network->network.IELength);
1048 * the function could be > passive_level (the same context as Rx tasklet)
1049 * pnetwork : returns from rtw23a_joinbss_event_cb
1050 * ptarget_wlan: found from scanned_queue
1051 * if join_res > 0, for (fw_state==WIFI_STATION_STATE),
1052 * we check if "ptarget_sta" & "ptarget_wlan" exist.
1053 * if join_res > 0, for (fw_state==WIFI_ADHOC_STATE),
1054 * we only check if "ptarget_wlan" exist.
1055 * if join_res > 0, update "cur_network->network" from "pnetwork->network"
1056 * if (ptarget_wlan !=NULL).
1059 void rtw_joinbss_event_prehandle23a(struct rtw_adapter *adapter, u8 *pbuf)
1061 struct sta_info *ptarget_sta, *pcur_sta;
1062 struct sta_priv *pstapriv = &adapter->stapriv;
1063 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1064 struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
1065 struct wlan_network *cur_network = &pmlmepriv->cur_network;
1066 struct wlan_network *pcur_wlan, *ptarget_wlan = NULL;
1067 bool the_same_macaddr;
1069 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1070 "joinbss event call back received with res=%d\n",
1071 pnetwork->join_res);
1073 if (pmlmepriv->assoc_ssid.ssid_len == 0) {
1074 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1075 "@@@@@ joinbss event call back for Any SSid\n");
1077 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1078 "@@@@@ rtw23a_joinbss_event_cb for SSid:%s\n",
1079 pmlmepriv->assoc_ssid.ssid);
1082 if (ether_addr_equal(pnetwork->network.MacAddress,
1083 cur_network->network.MacAddress))
1084 the_same_macaddr = true;
1086 the_same_macaddr = false;
1088 pnetwork->network.Length = get_wlan_bssid_ex_sz(&pnetwork->network);
1089 if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex)) {
1090 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1091 "***joinbss_evt_callback return a wrong bss ***\n");
1095 spin_lock_bh(&pmlmepriv->lock);
1097 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1098 "rtw23a_joinbss_event_cb !! _enter_critical\n");
1100 if (pnetwork->join_res > 0) {
1101 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1102 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
1103 /* s1. find ptarget_wlan */
1104 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1105 if (the_same_macaddr) {
1106 ptarget_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
1108 pcur_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
1110 pcur_wlan->fixed = false;
1112 pcur_sta = rtw_get_stainfo23a(pstapriv, cur_network->network.MacAddress);
1114 spin_lock_bh(&pstapriv->sta_hash_lock);
1115 rtw_free_stainfo23a(adapter,
1117 spin_unlock_bh(&pstapriv->sta_hash_lock);
1120 ptarget_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
1121 if (check_fwstate(pmlmepriv,
1122 WIFI_STATION_STATE)) {
1124 ptarget_wlan->fixed =
1130 ptarget_wlan = rtw_find_network23a(
1131 &pmlmepriv->scanned_queue,
1132 pnetwork->network.MacAddress);
1133 if (check_fwstate(pmlmepriv,
1134 WIFI_STATION_STATE)) {
1136 ptarget_wlan->fixed = true;
1140 /* s2. update cur_network */
1142 rtw_joinbss_update_network23a(adapter,
1146 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1147 "Can't find ptarget_wlan when joinbss_event callback\n");
1148 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1149 goto ignore_joinbss_callback;
1152 /* s3. find ptarget_sta & update ptarget_sta after
1153 update cur_network only for station mode */
1154 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1155 ptarget_sta = rtw_joinbss_update_stainfo(
1158 RT_TRACE(_module_rtl871x_mlme_c_,
1160 "Can't update stainfo when joinbss_event callback\n");
1161 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1162 goto ignore_joinbss_callback;
1166 /* s4. indicate connect */
1167 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1168 rtw_indicate_connect23a(adapter);
1170 /* adhoc mode will rtw_indicate_connect23a
1171 when rtw_stassoc_event_callback23a */
1172 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1173 "adhoc mode, fw_state:%x\n",
1174 get_fwstate(pmlmepriv));
1177 /* s5. Cancle assoc_timer */
1178 del_timer_sync(&pmlmepriv->assoc_timer);
1180 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1181 "Cancle assoc_timer\n");
1183 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1184 "rtw23a_joinbss_event_cb err: fw_state:%x\n",
1185 get_fwstate(pmlmepriv));
1186 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1187 goto ignore_joinbss_callback;
1189 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1190 } else if (pnetwork->join_res == -4) {
1191 rtw_reset_securitypriv23a(adapter);
1192 mod_timer(&pmlmepriv->assoc_timer,
1193 jiffies + msecs_to_jiffies(1));
1195 /* rtw_free_assoc_resources23a(adapter, 1); */
1197 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
1198 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1199 "fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n",
1200 get_fwstate(pmlmepriv));
1201 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1204 /* if join_res < 0 (join fails), then try again */
1205 mod_timer(&pmlmepriv->assoc_timer,
1206 jiffies + msecs_to_jiffies(1));
1207 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1210 ignore_joinbss_callback:
1212 spin_unlock_bh(&pmlmepriv->lock);
1215 void rtw23a_joinbss_event_cb(struct rtw_adapter *adapter, const u8 *pbuf)
1217 struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
1219 mlmeext_joinbss_event_callback23a(adapter, pnetwork->join_res);
1221 rtw_os_xmit_schedule23a(adapter);
1224 void rtw_stassoc_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
1226 struct sta_info *psta;
1227 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1228 struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf;
1229 struct wlan_network *cur_network = &pmlmepriv->cur_network;
1230 struct wlan_network *ptarget_wlan;
1232 if (rtw_access_ctrl23a(adapter, pstassoc->macaddr) == false)
1235 #ifdef CONFIG_8723AU_AP_MODE
1236 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1237 psta = rtw_get_stainfo23a(&adapter->stapriv, pstassoc->macaddr);
1239 /* bss_cap_update_on_sta_join23a(adapter, psta); */
1240 /* sta_info_update23a(adapter, psta); */
1241 ap_sta_info_defer_update23a(adapter, psta);
1246 /* for AD-HOC mode */
1247 psta = rtw_get_stainfo23a(&adapter->stapriv, pstassoc->macaddr);
1249 /* the sta have been in sta_info_queue => do nothing */
1250 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1251 "Error: rtw_stassoc_event_callback23a: sta has been in sta_hash_queue\n");
1252 /* between drv has received this event before and
1253 fw have not yet to set key to CAM_ENTRY) */
1257 psta = rtw_alloc_stainfo23a(&adapter->stapriv, pstassoc->macaddr,
1260 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1261 "Can't alloc sta_info when rtw_stassoc_event_callback23a\n");
1265 /* to do : init sta_info variable */
1266 psta->qos_option = 0;
1267 psta->mac_id = (uint)pstassoc->cam_id;
1268 /* psta->aid = (uint)pstassoc->cam_id; */
1269 DBG_8723A("%s\n", __func__);
1270 /* for ad-hoc mode */
1271 rtl8723a_SetHalODMVar(adapter, HAL_ODM_STA_INFO, psta, true);
1273 if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
1274 psta->dot118021XPrivacy =
1275 adapter->securitypriv.dot11PrivacyAlgrthm;
1277 psta->ieee8021x_blocked = false;
1279 spin_lock_bh(&pmlmepriv->lock);
1281 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1282 check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1283 if (adapter->stapriv.asoc_sta_count == 2) {
1284 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1286 rtw_find_network23a(&pmlmepriv->scanned_queue,
1287 cur_network->network.MacAddress);
1289 ptarget_wlan->fixed = true;
1290 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1291 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1292 rtw_indicate_connect23a(adapter);
1296 spin_unlock_bh(&pmlmepriv->lock);
1298 mlmeext_sta_add_event_callback23a(adapter, psta);
1301 void rtw_stadel_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
1304 struct sta_info *psta;
1305 struct wlan_network *pwlan;
1306 struct wlan_bssid_ex *pdev_network;
1307 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1308 struct stadel_event *pstadel = (struct stadel_event *)pbuf;
1309 struct sta_priv *pstapriv = &adapter->stapriv;
1310 struct wlan_network *tgt_network = &pmlmepriv->cur_network;
1312 psta = rtw_get_stainfo23a(&adapter->stapriv, pstadel->macaddr);
1314 mac_id = psta->mac_id;
1316 mac_id = pstadel->mac_id;
1318 DBG_8723A("%s(mac_id=%d)=%pM\n", __func__, mac_id, pstadel->macaddr);
1320 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
1323 mlmeext_sta_del_event_callback23a(adapter);
1325 spin_lock_bh(&pmlmepriv->lock);
1327 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1328 if (adapter->mlmepriv.to_roaming > 0) {
1329 /* this stadel_event is caused by roaming,
1330 decrease to_roaming */
1331 pmlmepriv->to_roaming--;
1332 } else if (adapter->mlmepriv.to_roaming == 0)
1333 rtw_set_roaming(adapter, adapter->registrypriv.max_roaming_times);
1334 if (*((u16 *)pstadel->rsvd) != WLAN_REASON_EXPIRATION_CHK)
1335 rtw_set_roaming(adapter, 0); /* don't roam */
1337 rtw_free_uc_swdec_pending_queue23a(adapter);
1339 rtw_free_assoc_resources23a(adapter, 1);
1340 rtw_indicate_disconnect23a(adapter);
1341 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1342 /* remove the network entry in scanned_queue */
1343 pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
1344 tgt_network->network.MacAddress);
1346 pwlan->fixed = false;
1347 rtw_free_network_nolock(pmlmepriv, pwlan);
1349 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1351 _rtw_roaming(adapter, tgt_network);
1354 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1355 check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1357 spin_lock_bh(&pstapriv->sta_hash_lock);
1358 rtw_free_stainfo23a(adapter, psta);
1359 spin_unlock_bh(&pstapriv->sta_hash_lock);
1361 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1362 if (adapter->stapriv.asoc_sta_count == 1) {
1363 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1364 /* free old ibss network */
1365 /* pwlan = rtw_find_network23a(
1366 &pmlmepriv->scanned_queue, pstadel->macaddr); */
1367 pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
1368 tgt_network->network.MacAddress);
1370 pwlan->fixed = false;
1371 rtw_free_network_nolock(pmlmepriv, pwlan);
1373 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1374 /* re-create ibss */
1375 pdev_network = &adapter->registrypriv.dev_network;
1377 memcpy(pdev_network, &tgt_network->network,
1378 get_wlan_bssid_ex_sz(&tgt_network->network));
1380 rtw_do_join_adhoc(adapter);
1384 spin_unlock_bh(&pmlmepriv->lock);
1388 * rtw23a_join_to_handler - Timeout/failure handler for CMD JoinBss
1389 * @adapter: pointer to _adapter structure
1391 void rtw23a_join_to_handler (unsigned long data)
1393 struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1394 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1397 DBG_8723A("%s, fw_state=%x\n", __func__, get_fwstate(pmlmepriv));
1399 if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
1402 spin_lock_bh(&pmlmepriv->lock);
1404 if (adapter->mlmepriv.to_roaming > 0) {
1405 /* join timeout caused by roaming */
1407 pmlmepriv->to_roaming--;
1408 if (adapter->mlmepriv.to_roaming != 0) {
1410 DBG_8723A("%s try another roaming\n", __func__);
1411 do_join_r = rtw_do_join(adapter);
1412 if (do_join_r != _SUCCESS) {
1413 DBG_8723A("%s roaming do_join return "
1414 "%d\n", __func__ , do_join_r);
1419 DBG_8723A("%s We've try roaming but fail\n",
1421 rtw_indicate_disconnect23a(adapter);
1426 rtw_indicate_disconnect23a(adapter);
1427 free_scanqueue(pmlmepriv);/* */
1429 /* indicate disconnect for the case that join_timeout and
1430 check_fwstate != FW_LINKED */
1431 rtw_cfg80211_indicate_disconnect(adapter);
1434 spin_unlock_bh(&pmlmepriv->lock);
1439 * rtw_scan_timeout_handler23a - Timeout/Failure handler for CMD SiteSurvey
1440 * @data: pointer to _adapter structure
1442 void rtw_scan_timeout_handler23a(unsigned long data)
1444 struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1445 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1447 DBG_8723A("%s(%s): fw_state =%x\n", __func__, adapter->pnetdev->name,
1448 get_fwstate(pmlmepriv));
1450 spin_lock_bh(&pmlmepriv->lock);
1452 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1454 spin_unlock_bh(&pmlmepriv->lock);
1456 rtw_cfg80211_indicate_scan_done(wdev_to_priv(adapter->rtw_wdev), true);
1459 void rtw_dynamic_check_timer_handler(unsigned long data)
1461 struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1463 if (adapter->hw_init_completed == false)
1466 if (adapter->bDriverStopped == true ||
1467 adapter->bSurpriseRemoved == true)
1470 if (adapter->net_closed == true)
1473 rtw_dynamic_chk_wk_cmd23a(adapter);
1476 mod_timer(&adapter->mlmepriv.dynamic_chk_timer,
1477 jiffies + msecs_to_jiffies(2000));
1480 inline bool rtw_is_scan_deny(struct rtw_adapter *adapter)
1482 struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1484 return (atomic_read(&mlmepriv->set_scan_deny) != 0) ? true : false;
1487 void rtw_clear_scan_deny(struct rtw_adapter *adapter)
1489 struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1491 atomic_set(&mlmepriv->set_scan_deny, 0);
1494 void rtw_set_scan_deny_timer_hdl(unsigned long data)
1496 struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1498 rtw_clear_scan_deny(adapter);
1501 void rtw_set_scan_deny(struct rtw_adapter *adapter, u32 ms)
1503 struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1505 atomic_set(&mlmepriv->set_scan_deny, 1);
1506 mod_timer(&mlmepriv->set_scan_deny_timer,
1507 jiffies + msecs_to_jiffies(ms));
1510 #if defined(IEEE80211_SCAN_RESULT_EXPIRE)
1511 #define RTW_SCAN_RESULT_EXPIRE \
1512 ((IEEE80211_SCAN_RESULT_EXPIRE / (HZ*1000)) - 1000) /* 3000 -1000 */
1514 #define RTW_SCAN_RESULT_EXPIRE 2000
1518 * Select a new join candidate from the original @param candidate and
1520 * @return true: candidate is updated
1521 * @return false: candidate is not updated
1523 static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv,
1524 struct wlan_network **candidate,
1525 struct wlan_network *competitor)
1527 int updated = false;
1528 struct rtw_adapter *adapter;
1530 adapter = container_of(pmlmepriv, struct rtw_adapter, mlmepriv);
1532 /* check bssid, if needed */
1533 if (pmlmepriv->assoc_by_bssid == true) {
1534 if (!ether_addr_equal(competitor->network.MacAddress,
1535 pmlmepriv->assoc_bssid))
1539 /* check ssid, if needed */
1540 if (pmlmepriv->assoc_ssid.ssid_len) {
1541 if (competitor->network.Ssid.ssid_len !=
1542 pmlmepriv->assoc_ssid.ssid_len ||
1543 memcmp(competitor->network.Ssid.ssid,
1544 pmlmepriv->assoc_ssid.ssid,
1545 pmlmepriv->assoc_ssid.ssid_len))
1549 if (rtw_is_desired_network(adapter, competitor) == false)
1552 if (adapter->mlmepriv.to_roaming > 0) {
1553 unsigned int passed;
1555 passed = jiffies_to_msecs(jiffies - competitor->last_scanned);
1556 if (passed >= RTW_SCAN_RESULT_EXPIRE ||
1557 is_same_ess(&competitor->network,
1558 &pmlmepriv->cur_network.network) == false)
1563 (*candidate)->network.Rssi<competitor->network.Rssi) {
1564 *candidate = competitor;
1569 DBG_8723A("[by_bssid:%u][assoc_ssid:%s][to_roaming:%u] new candidate: %s(%pM) rssi:%d\n",
1570 pmlmepriv->assoc_by_bssid,
1571 pmlmepriv->assoc_ssid.ssid,
1572 adapter->mlmepriv.to_roaming,
1573 (*candidate)->network.Ssid.ssid,
1574 (*candidate)->network.MacAddress,
1575 (int)(*candidate)->network.Rssi);
1584 The caller of the sub-routine will be in critical section...
1586 The caller must hold the following spinlock
1592 static int rtw_do_join(struct rtw_adapter *padapter)
1594 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1597 pmlmepriv->cur_network.join_res = -2;
1599 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
1601 pmlmepriv->to_join = true;
1603 ret = rtw_select_and_join_from_scanned_queue23a(pmlmepriv);
1604 if (ret == _SUCCESS) {
1605 pmlmepriv->to_join = false;
1607 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1608 /* switch to ADHOC_MASTER */
1609 ret = rtw_do_join_adhoc(padapter);
1610 if (ret != _SUCCESS)
1613 /* can't associate ; reset under-linking */
1614 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1617 pmlmepriv->to_join = false;
1625 static struct wlan_network *
1626 rtw_select_candidate_from_queue(struct mlme_priv *pmlmepriv)
1628 struct wlan_network *pnetwork, *candidate = NULL;
1629 struct rtw_queue *queue = &pmlmepriv->scanned_queue;
1630 struct list_head *phead, *plist, *ptmp;
1632 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1633 phead = get_list_head(queue);
1635 list_for_each_safe(plist, ptmp, phead) {
1636 pnetwork = container_of(plist, struct wlan_network, list);
1638 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1639 "%s: return _FAIL:(pnetwork == NULL)\n",
1644 rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
1648 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1653 int rtw_do_join_adhoc(struct rtw_adapter *adapter)
1655 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1656 struct wlan_bssid_ex *pdev_network;
1660 pdev_network = &adapter->registrypriv.dev_network;
1661 ibss = adapter->registrypriv.dev_network.MacAddress;
1663 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1665 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1666 "switching to adhoc master\n");
1668 memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid,
1669 sizeof(struct cfg80211_ssid));
1671 rtw_update_registrypriv_dev_network23a(adapter);
1672 rtw_generate_random_ibss23a(ibss);
1674 pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
1676 ret = rtw_createbss_cmd23a(adapter);
1677 if (ret != _SUCCESS) {
1678 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1679 "Error =>rtw_createbss_cmd23a status FAIL\n");
1681 pmlmepriv->to_join = false;
1687 int rtw_do_join_network(struct rtw_adapter *adapter,
1688 struct wlan_network *candidate)
1692 /* check for situation of _FW_LINKED */
1693 if (check_fwstate(&adapter->mlmepriv, _FW_LINKED)) {
1694 DBG_8723A("%s: _FW_LINKED while ask_for_joinbss!\n", __func__);
1696 rtw_disassoc_cmd23a(adapter, 0, true);
1697 rtw_indicate_disconnect23a(adapter);
1698 rtw_free_assoc_resources23a(adapter, 0);
1700 set_fwstate(&adapter->mlmepriv, _FW_UNDER_LINKING);
1702 ret = rtw_joinbss_cmd23a(adapter, candidate);
1704 if (ret == _SUCCESS)
1705 mod_timer(&adapter->mlmepriv.assoc_timer,
1706 jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
1711 int rtw_select_and_join_from_scanned_queue23a(struct mlme_priv *pmlmepriv)
1713 struct rtw_adapter *adapter;
1714 struct wlan_network *candidate = NULL;
1717 adapter = pmlmepriv->nic_hdl;
1719 candidate = rtw_select_candidate_from_queue(pmlmepriv);
1721 DBG_8723A("%s: return _FAIL(candidate == NULL)\n", __func__);
1725 DBG_8723A("%s: candidate: %s(%pM, ch:%u)\n",
1727 candidate->network.Ssid.ssid,
1728 candidate->network.MacAddress,
1729 candidate->network.DSConfig);
1732 ret = rtw_do_join_network(adapter, candidate);
1738 int rtw_set_auth23a(struct rtw_adapter *adapter,
1739 struct security_priv *psecuritypriv)
1741 struct cmd_obj *pcmd;
1742 struct setauth_parm *psetauthparm;
1743 struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1746 pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1748 res = _FAIL; /* try again */
1752 psetauthparm = kzalloc(sizeof(struct setauth_parm), GFP_KERNEL);
1753 if (!psetauthparm) {
1759 psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
1761 pcmd->cmdcode = _SetAuth_CMD_;
1762 pcmd->parmbuf = (unsigned char *)psetauthparm;
1763 pcmd->cmdsz = (sizeof(struct setauth_parm));
1767 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1768 "after enqueue set_auth_cmd, auth_mode=%x\n",
1769 psecuritypriv->dot11AuthAlgrthm);
1771 res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
1778 int rtw_set_key23a(struct rtw_adapter *adapter,
1779 struct security_priv *psecuritypriv, int keyid, u8 set_tx)
1782 struct cmd_obj *pcmd;
1783 struct setkey_parm *psetkeyparm;
1784 struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1785 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1793 pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1795 res = _FAIL; /* try again */
1798 psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
1805 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
1806 psetkeyparm->algorithm = (unsigned char)
1807 psecuritypriv->dot118021XGrpPrivacy;
1808 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1809 "rtw_set_key23a: psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy =%d\n",
1810 psetkeyparm->algorithm);
1812 psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm;
1813 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1814 "rtw_set_key23a: psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm =%d\n",
1815 psetkeyparm->algorithm);
1817 psetkeyparm->keyid = keyid;/* 0~3 */
1818 psetkeyparm->set_tx = set_tx;
1819 if (is_wep_enc(psetkeyparm->algorithm))
1820 pmlmepriv->key_mask |= BIT(psetkeyparm->keyid);
1822 DBG_8723A("==> rtw_set_key23a algorithm(%x), keyid(%x), key_mask(%x)\n",
1823 psetkeyparm->algorithm, psetkeyparm->keyid,
1824 pmlmepriv->key_mask);
1825 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1826 "rtw_set_key23a: psetkeyparm->algorithm =%d psetkeyparm->keyid = (u8)keyid =%d\n",
1827 psetkeyparm->algorithm, keyid);
1829 switch (psetkeyparm->algorithm) {
1830 case WLAN_CIPHER_SUITE_WEP40:
1832 memcpy(&psetkeyparm->key[0],
1833 &psecuritypriv->wep_key[keyid].key, keylen);
1835 case WLAN_CIPHER_SUITE_WEP104:
1837 memcpy(&psetkeyparm->key[0],
1838 &psecuritypriv->wep_key[keyid].key, keylen);
1840 case WLAN_CIPHER_SUITE_TKIP:
1842 memcpy(&psetkeyparm->key,
1843 &psecuritypriv->dot118021XGrpKey[keyid], keylen);
1844 psetkeyparm->grpkey = 1;
1846 case WLAN_CIPHER_SUITE_CCMP:
1848 memcpy(&psetkeyparm->key,
1849 &psecuritypriv->dot118021XGrpKey[keyid], keylen);
1850 psetkeyparm->grpkey = 1;
1853 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1854 "rtw_set_key23a:psecuritypriv->dot11PrivacyAlgrthm = %x (must be 1 or 2 or 4 or 5)\n",
1855 psecuritypriv->dot11PrivacyAlgrthm);
1862 pcmd->cmdcode = _SetKey_CMD_;
1863 pcmd->parmbuf = (u8 *)psetkeyparm;
1864 pcmd->cmdsz = (sizeof(struct setkey_parm));
1868 /* sema_init(&pcmd->cmd_sem, 0); */
1870 res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
1877 /* adjust IEs for rtw_joinbss_cmd23a in WMM */
1878 int rtw_restruct_wmm_ie23a(struct rtw_adapter *adapter, u8 *in_ie,
1879 u8 *out_ie, uint in_len, uint initial_out_len)
1884 ielength = initial_out_len;
1886 p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1887 WLAN_OUI_TYPE_MICROSOFT_WMM,
1891 memcpy(out_ie + initial_out_len, p, 9);
1893 out_ie[initial_out_len + 1] = 7;
1894 out_ie[initial_out_len + 6] = 0;
1895 out_ie[initial_out_len + 8] = 0;
1904 /* Ported from 8185: IsInPreAuthKeyList().
1905 (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.) */
1906 /* Added by Annie, 2006-05-07. */
1908 /* Search by BSSID, */
1910 /* -1 :if there is no pre-auth key in the table */
1911 /* >= 0 :if there is pre-auth key, and return the entry id */
1915 static int SecIsInPMKIDList(struct rtw_adapter *Adapter, u8 *bssid)
1917 struct security_priv *psecuritypriv = &Adapter->securitypriv;
1921 if (psecuritypriv->PMKIDList[i].bUsed &&
1922 ether_addr_equal(psecuritypriv->PMKIDList[i].Bssid, bssid)) {
1928 } while (i < NUM_PMKID_CACHE);
1930 if (i == NUM_PMKID_CACHE)
1931 i = -1;/* Could not find. */
1933 /* There is one Pre-Authentication Key for
1934 the specific BSSID. */
1941 /* Check the RSN IE length */
1942 /* If the RSN IE length <= 20, the RSN IE didn't include
1943 the PMKID information */
1944 /* 0-11th element in the array are the fixed IE */
1945 /* 12th element in the array is the IE */
1946 /* 13th element in the array is the IE length */
1949 static int rtw_append_pmkid(struct rtw_adapter *Adapter, int iEntry,
1950 u8 *ie, uint ie_len)
1952 struct security_priv *psecuritypriv = &Adapter->securitypriv;
1955 /* The RSN IE didn't include the PMK ID,
1956 append the PMK information */
1959 ie[ie_len] = 0; /* PMKID count = 0x0100 */
1962 &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
1965 ie[1] += 18;/* PMKID length = 2+16 */
1970 int rtw_restruct_sec_ie23a(struct rtw_adapter *adapter, u8 *in_ie, u8 *out_ie,
1976 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1977 struct security_priv *psecuritypriv = &adapter->securitypriv;
1978 uint ndisauthmode = psecuritypriv->ndisauthtype;
1979 uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
1981 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
1982 "+rtw_restruct_sec_ie23a: ndisauthmode=%d ndissecuritytype=%d\n",
1983 ndisauthmode, ndissecuritytype);
1986 if (ndisauthmode == Ndis802_11AuthModeWPA ||
1987 ndisauthmode == Ndis802_11AuthModeWPAPSK)
1988 authmode = WLAN_EID_VENDOR_SPECIFIC;
1989 if (ndisauthmode == Ndis802_11AuthModeWPA2 ||
1990 ndisauthmode == Ndis802_11AuthModeWPA2PSK)
1991 authmode = WLAN_EID_RSN;
1993 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
1994 memcpy(out_ie + ielength, psecuritypriv->wps_ie,
1995 psecuritypriv->wps_ie_len);
1997 ielength += psecuritypriv->wps_ie_len;
1998 } else if (authmode == WLAN_EID_VENDOR_SPECIFIC ||
1999 authmode == WLAN_EID_RSN) {
2000 /* copy RSN or SSN */
2001 memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0],
2002 psecuritypriv->supplicant_ie[1] + 2);
2003 ielength += psecuritypriv->supplicant_ie[1] + 2;
2006 iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
2010 if (authmode == WLAN_EID_RSN)
2011 ielength = rtw_append_pmkid(adapter, iEntry,
2018 void rtw_init_registrypriv_dev_network23a(struct rtw_adapter *adapter)
2020 struct registry_priv *pregistrypriv = &adapter->registrypriv;
2021 struct eeprom_priv *peepriv = &adapter->eeprompriv;
2022 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
2023 u8 *myhwaddr = myid(peepriv);
2025 ether_addr_copy(pdev_network->MacAddress, myhwaddr);
2027 memcpy(&pdev_network->Ssid, &pregistrypriv->ssid,
2028 sizeof(struct cfg80211_ssid));
2030 pdev_network->beacon_interval = 100;
2033 void rtw_update_registrypriv_dev_network23a(struct rtw_adapter *adapter)
2036 struct registry_priv *pregistrypriv = &adapter->registrypriv;
2037 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
2038 struct security_priv *psecuritypriv = &adapter->securitypriv;
2039 struct wlan_network *cur_network = &adapter->mlmepriv.cur_network;
2040 /* struct xmit_priv *pxmitpriv = &adapter->xmitpriv; */
2042 pdev_network->Privacy =
2043 (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0);
2045 pdev_network->Rssi = 0;
2047 pdev_network->DSConfig = pregistrypriv->channel;
2048 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
2049 "pregistrypriv->channel =%d, pdev_network->DSConfig = 0x%x\n",
2050 pregistrypriv->channel, pdev_network->DSConfig);
2052 if (cur_network->network.ifmode == NL80211_IFTYPE_ADHOC)
2053 pdev_network->ATIMWindow = 0;
2055 pdev_network->ifmode = cur_network->network.ifmode;
2057 /* 1. Supported rates */
2060 sz = rtw_generate_ie23a(pregistrypriv);
2062 pdev_network->IELength = sz;
2064 pdev_network->Length =
2065 get_wlan_bssid_ex_sz(pdev_network);
2067 /* notes: translate IELength & Length after assign the
2068 Length to cmdsz in createbss_cmd(); */
2069 /* pdev_network->IELength = cpu_to_le32(sz); */
2072 /* the function is at passive_level */
2073 void rtw_joinbss_reset23a(struct rtw_adapter *padapter)
2076 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2077 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2079 /* todo: if you want to do something io/reg/hw setting
2080 before join_bss, please add code here */
2082 pmlmepriv->num_FortyMHzIntolerant = 0;
2084 pmlmepriv->num_sta_no_ht = 0;
2086 phtpriv->ampdu_enable = false;/* reset to disabled */
2088 /* TH = 1 => means that invalidate usb rx aggregation */
2089 /* TH = 0 => means that validate usb rx aggregation, use init value. */
2090 if (phtpriv->ht_option) {
2091 if (padapter->registrypriv.wifi_spec == 1)
2098 rtl8723a_set_rxdma_agg_pg_th(padapter, threshold);
2101 /* the function is >= passive_level */
2102 bool rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie,
2103 u8 *out_ie, uint in_len, uint *pout_len)
2106 int max_rx_ampdu_factor;
2107 unsigned char *pframe;
2109 struct ieee80211_ht_cap ht_capie;
2110 u8 WMM_IE[7] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
2111 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2112 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2114 phtpriv->ht_option = false;
2116 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, in_ie, in_len);
2118 if (p && p[1] > 0) {
2119 u32 rx_packet_offset, max_recvbuf_sz;
2121 if (pmlmepriv->qos_option == 0) {
2122 out_len = *pout_len;
2123 pframe = rtw_set_ie23a(out_ie + out_len,
2124 WLAN_EID_VENDOR_SPECIFIC,
2125 sizeof(WMM_IE), WMM_IE,
2128 pmlmepriv->qos_option = 1;
2131 out_len = *pout_len;
2133 memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap));
2135 ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
2136 IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
2137 IEEE80211_HT_CAP_TX_STBC | IEEE80211_HT_CAP_DSSSCCK40);
2139 GetHalDefVar8192CUsb(padapter, HAL_DEF_RX_PACKET_OFFSET,
2141 GetHalDefVar8192CUsb(padapter, HAL_DEF_MAX_RECVBUF_SZ,
2144 GetHalDefVar8192CUsb(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
2145 &max_rx_ampdu_factor);
2146 ht_capie.ampdu_params_info = max_rx_ampdu_factor & 0x03;
2148 if (padapter->securitypriv.dot11PrivacyAlgrthm ==
2149 WLAN_CIPHER_SUITE_CCMP)
2150 ht_capie.ampdu_params_info |=
2151 (IEEE80211_HT_AMPDU_PARM_DENSITY& (0x07 << 2));
2153 ht_capie.ampdu_params_info |=
2154 (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00);
2156 pframe = rtw_set_ie23a(out_ie + out_len, WLAN_EID_HT_CAPABILITY,
2157 sizeof(struct ieee80211_ht_cap),
2158 (unsigned char *)&ht_capie, pout_len);
2160 phtpriv->ht_option = true;
2162 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, in_ie, in_len);
2163 if (p && (p[1] == sizeof(struct ieee80211_ht_operation))) {
2164 out_len = *pout_len;
2165 pframe = rtw_set_ie23a(out_ie + out_len,
2166 WLAN_EID_HT_OPERATION,
2167 p[1], p + 2 , pout_len);
2171 return phtpriv->ht_option;
2174 /* the function is > passive_level (in critical_section) */
2175 void rtw_update_ht_cap23a(struct rtw_adapter *padapter, u8 *pie, uint ie_len)
2179 struct ieee80211_ht_cap *pht_capie;
2180 struct ieee80211_ht_operation *pht_addtinfo;
2181 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2182 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2183 struct registry_priv *pregistrypriv = &padapter->registrypriv;
2184 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2185 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2187 if (!phtpriv->ht_option)
2190 if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
2193 DBG_8723A("+rtw_update_ht_cap23a()\n");
2195 /* maybe needs check if ap supports rx ampdu. */
2196 if (!phtpriv->ampdu_enable && pregistrypriv->ampdu_enable == 1) {
2197 if (pregistrypriv->wifi_spec == 1)
2198 phtpriv->ampdu_enable = false;
2200 phtpriv->ampdu_enable = true;
2201 } else if (pregistrypriv->ampdu_enable == 2)
2202 phtpriv->ampdu_enable = true;
2204 /* check Max Rx A-MPDU Size */
2205 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, ie_len);
2207 if (p && p[1] > 0) {
2208 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
2209 max_ampdu_sz = pht_capie->ampdu_params_info &
2210 IEEE80211_HT_AMPDU_PARM_FACTOR;
2211 /* max_ampdu_sz (kbytes); */
2212 max_ampdu_sz = 1 << (max_ampdu_sz + 3);
2214 phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
2217 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, pie, ie_len);
2218 if (p && p[1] > 0) {
2219 pht_addtinfo = (struct ieee80211_ht_operation *)(p + 2);
2223 /* update cur_bwmode & cur_ch_offset */
2224 if (pregistrypriv->cbw40_enable &&
2225 pmlmeinfo->ht_cap.cap_info &
2226 cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
2227 pmlmeinfo->HT_info.ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) {
2231 rf_type = rtl8723a_get_rf_type(padapter);
2233 /* update the MCS rates */
2234 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2235 if (rf_type == RF_1T1R || rf_type == RF_1T2R)
2236 pmlmeinfo->ht_cap.mcs.rx_mask[i] &=
2239 pmlmeinfo->ht_cap.mcs.rx_mask[i] &=
2242 /* switch to the 40M Hz mode according to the AP */
2243 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
2244 switch (pmlmeinfo->HT_info.ht_param &
2245 IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
2246 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
2247 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
2250 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
2251 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
2255 pmlmeext->cur_ch_offset =
2256 HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2262 /* Config SM Power Save setting */
2265 (le16_to_cpu(pmlmeinfo->ht_cap.cap_info) &
2266 IEEE80211_HT_CAP_SM_PS) >> IEEE80211_HT_CAP_SM_PS_SHIFT;
2267 if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
2268 DBG_8723A("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
2271 /* Config current HT Protection mode. */
2273 pmlmeinfo->HT_protection =
2274 le16_to_cpu(pmlmeinfo->HT_info.operation_mode) &
2275 IEEE80211_HT_OP_MODE_PROTECTION;
2278 void rtw_issue_addbareq_cmd23a(struct rtw_adapter *padapter,
2279 struct xmit_frame *pxmitframe)
2283 struct sta_info *psta;
2284 struct ht_priv *phtpriv;
2285 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2286 s32 bmcst = is_multicast_ether_addr(pattrib->ra);
2288 if (bmcst || padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100)
2291 priority = pattrib->priority;
2294 psta = pattrib->psta;
2296 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
2297 psta = rtw_get_stainfo23a(&padapter->stapriv, pattrib->ra);
2301 DBG_8723A("%s, psta == NUL\n", __func__);
2305 if (!(psta->state &_FW_LINKED)) {
2306 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
2307 __func__, psta->state);
2311 phtpriv = &psta->htpriv;
2313 if (phtpriv->ht_option && phtpriv->ampdu_enable) {
2314 issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
2315 issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
2318 DBG_8723A("rtw_issue_addbareq_cmd23a, p =%d\n",
2320 psta->htpriv.candidate_tid_bitmap |= BIT(priority);
2321 rtw_addbareq_cmd23a(padapter, (u8) priority,
2327 int rtw_linked_check(struct rtw_adapter *padapter)
2329 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) ||
2330 check_fwstate(&padapter->mlmepriv,
2331 WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) {
2332 if (padapter->stapriv.asoc_sta_count > 2)
2334 } else { /* Station mode */
2335 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED))