8723BU: Update 8723BU wifi driver to version v4.3.16_14189.20150519_BTCOEX2015119...
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723bu / core / rtw_mlme.c
index df6dfc85ccdcf43a992ceafa551c1218cc33ea14..c6c707952c265705fba96befeef4e50573f5da5e 100755 (executable)
@@ -155,7 +155,10 @@ void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
 void _rtw_free_mlme_priv (struct mlme_priv *pmlmepriv)
 {
 _func_enter_;
-
+       if (NULL == pmlmepriv){
+               rtw_warn_on(1);
+               goto exit;
+       }
        rtw_free_mlme_priv_ie_data(pmlmepriv);
 
        if(pmlmepriv){
@@ -165,6 +168,7 @@ _func_enter_;
                        rtw_vmfree(pmlmepriv->free_bss_buf, MAX_BSS_CNT * sizeof(struct wlan_network));
                }
        }
+exit:
 _func_exit_;   
 }
 
@@ -863,7 +867,9 @@ void rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target)
        ULONG   bssid_ex_sz;
        struct mlme_priv        *pmlmepriv = &(adapter->mlmepriv);
        struct mlme_ext_priv    *pmlmeext = &(adapter->mlmeextpriv);
-       struct wifidirect_info *pwdinfo= &(adapter->wdinfo);    
+#ifdef CONFIG_P2P
+       struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
+#endif // CONFIG_P2P
        _queue  *queue  = &(pmlmepriv->scanned_queue);
        struct wlan_network     *pnetwork = NULL;
        struct wlan_network     *oldest = NULL;
@@ -891,7 +897,7 @@ _func_enter_;
                rtw_bug_check(pnetwork, pnetwork, pnetwork, pnetwork);
 
 #ifdef CONFIG_P2P
-               if (!rtw_p2p_chk_state(&(adapter->wdinfo), P2P_STATE_NONE) &&
+               if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
                        (_rtw_memcmp(pnetwork->network.MacAddress, target->MacAddress, ETH_ALEN) == _TRUE))
                {
                        target_find = 1;
@@ -1019,7 +1025,8 @@ _func_enter_;
        //_enter_critical_bh(&queue->lock, &irqL);
 
        #if defined(CONFIG_P2P) && defined(CONFIG_P2P_REMOVE_GROUP_INFO)
-       rtw_WLAN_BSSID_EX_remove_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO);
+       if (adapter->registrypriv.wifi_spec == 0)
+               rtw_WLAN_BSSID_EX_remove_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO);
        #endif
        
        update_current_network(adapter, pnetwork);
@@ -1197,46 +1204,34 @@ _func_exit_;
 void rtw_surveydone_event_callback(_adapter    *adapter, u8 *pbuf)
 {
        _irqL  irqL;
-       u8 timer_cancelled = _FALSE;
+       u8 timer_cancelled;
        struct  mlme_priv       *pmlmepriv = &(adapter->mlmepriv);
-       
-#ifdef CONFIG_MLME_EXT 
 
+#ifdef CONFIG_MLME_EXT
        mlmeext_surveydone_event_callback(adapter);
-
 #endif
 
-_func_enter_;                  
+_func_enter_;
 
        _enter_critical_bh(&pmlmepriv->lock, &irqL);
-       if(pmlmepriv->wps_probe_req_ie)
-       {
+       if (pmlmepriv->wps_probe_req_ie) {
                u32 free_len = pmlmepriv->wps_probe_req_ie_len;
                pmlmepriv->wps_probe_req_ie_len = 0;
                rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
-               pmlmepriv->wps_probe_req_ie = NULL;                     
+               pmlmepriv->wps_probe_req_ie = NULL;
        }
-       
+
        RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_surveydone_event_callback: fw_state:%x\n\n", get_fwstate(pmlmepriv)));
-       
-       if (check_fwstate(pmlmepriv,_FW_UNDER_SURVEY))
-       {
-               //u8 timer_cancelled;
 
-               timer_cancelled = _TRUE;
-               //_cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled);
-               
-               _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
+       if (check_fwstate(pmlmepriv,_FW_UNDER_SURVEY) == _FALSE) {
+               DBG_871X(FUNC_ADPT_FMT" fw_state:0x%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
+               //rtw_warn_on(1);
        }
-       else {
-       
-               RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("nic status =%x, survey done event comes too late!\n", get_fwstate(pmlmepriv)));    
-       }
-       _exit_critical_bh(&pmlmepriv->lock, &irqL);
 
-       if(timer_cancelled)
-               _cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled);
+       _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
+       _exit_critical_bh(&pmlmepriv->lock, &irqL);
 
+       _cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled);
 
        _enter_critical_bh(&pmlmepriv->lock, &irqL);
 
@@ -1252,12 +1247,12 @@ _func_enter_;
                        {
                                set_fwstate(pmlmepriv, _FW_UNDER_LINKING);      
                                
-                               if(rtw_select_and_join_from_scanned_queue(pmlmepriv)==_SUCCESS)
-                               {
-                                       _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT );
-                               }
-                               else    
-                               {
+                               if(rtw_select_and_join_from_scanned_queue(pmlmepriv)==_SUCCESS)
+                               {
+                                       _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
+                               }
+                               else
+                               {
                                        WLAN_BSSID_EX    *pdev_network = &(adapter->registrypriv.dev_network);                  
                                        u8 *pibss = adapter->registrypriv.dev_network.MacAddress;
 
@@ -1272,7 +1267,8 @@ _func_enter_;
                                        rtw_update_registrypriv_dev_network(adapter);
                                        rtw_generate_random_ibss(pibss);
 
-                                               pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
+       
+                                       pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
                        
                                        if(rtw_createbss_cmd(adapter)!=_SUCCESS)
                                        {
@@ -1354,9 +1350,6 @@ _func_enter_;
 #ifdef CONFIG_CONCURRENT_MODE  
        rtw_os_xmit_schedule(adapter->pbuddy_adapter);
 #endif
-#ifdef CONFIG_DUALMAC_CONCURRENT
-       dc_resume_xmit(adapter);
-#endif
 
 #ifdef CONFIG_DRVEXT_MODULE_WSC
        drvext_surveydone_callback(&adapter->drvextpriv);
@@ -1484,21 +1477,20 @@ _func_enter_;
                psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress);
 
 #ifdef CONFIG_TDLS
-               if(ptdlsinfo->link_established == _TRUE)
-               {
-                       rtw_tdls_cmd(adapter, myid(&(adapter->eeprompriv)), TDLS_RS_RCR);
+               if (ptdlsinfo->link_established == _TRUE) {
+                       rtw_tdls_cmd(adapter, NULL, TDLS_RS_RCR);
                        rtw_reset_tdls_info(adapter);
                        rtw_free_all_stainfo(adapter);
-                       _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+                       //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
                }
                else
 #endif //CONFIG_TDLS
                {
-                       _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+                       //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
                        rtw_free_stainfo(adapter,  psta);
                }
 
-               _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+               //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
                
        }
 
@@ -1509,46 +1501,28 @@ _func_enter_;
                rtw_free_all_stainfo(adapter);
 
                psta = rtw_get_bcmc_stainfo(adapter);
-               _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);          
+               //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);                
                rtw_free_stainfo(adapter, psta);
-               _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);           
+               //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);         
 
                rtw_init_bcmc_stainfo(adapter); 
        }
 
        if(lock_scanned_queue)
                _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
-       
-       pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
+
+       pwlan = _rtw_find_same_network(&pmlmepriv->scanned_queue, tgt_network);
        if(pwlan)               
        {
                pwlan->fixed = _FALSE;
+
+                DBG_871X("free disconnecting network\n");
+               rtw_free_network_nolock(adapter, pwlan);
 #ifdef CONFIG_P2P
                if(!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE))
                {
-                       u32 p2p_ielen=0;
-                       u8  *p2p_ie;
-                       //u16 capability;
-                       u8 *pcap = NULL;
-                       u32 capability_len=0;
-                       
-                       //DBG_871X("free disconnecting network\n");
-                       //rtw_free_network_nolock(pmlmepriv, pwlan);
-
-                       if((p2p_ie=rtw_get_p2p_ie(pwlan->network.IEs+_FIXED_IE_LENGTH_, pwlan->network.IELength-_FIXED_IE_LENGTH_, NULL, &p2p_ielen)))
-                       {                       
-                               pcap = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, NULL, &capability_len);
-                               if(pcap && capability_len==2)
-                               {
-                                       u16 cap = *(u16*)pcap ;
-                                       *(u16*)pcap = cap&0x00ff;//clear group capability when free this network
-                               }
-
-       }       
-
                        rtw_set_scan_deny(adapter, 2000);
-                       //rtw_clear_scan_deny(adapter);
-                       
+                       //rtw_clear_scan_deny(adapter);                 
                }
 #endif //CONFIG_P2P
        }       
@@ -1644,6 +1618,8 @@ void rtw_indicate_disconnect( _adapter *padapter )
        WLAN_BSSID_EX   *cur_network = &(pmlmeinfo->network);
        struct sta_info *psta;
        struct sta_priv *pstapriv = &padapter->stapriv;
+       u8 *wps_ie=NULL;
+       uint wpsie_len=0;
 
 _func_enter_;  
        
@@ -1651,6 +1627,22 @@ _func_enter_;
 
        _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS);
 
+       // force to clear cur_network_scanned's SELECTED REGISTRAR
+       if (pmlmepriv->cur_network_scanned) {
+               WLAN_BSSID_EX   *current_joined_bss = &(pmlmepriv->cur_network_scanned->network);
+               if (current_joined_bss) {
+                       wps_ie=rtw_get_wps_ie(current_joined_bss->IEs +_FIXED_IE_LENGTH_,
+                               current_joined_bss->IELength-_FIXED_IE_LENGTH_, NULL, &wpsie_len);
+                       if (wps_ie && wpsie_len>0) {
+                               u8 *attr = NULL;
+                               u32 attr_len;
+                               attr=rtw_get_wps_attr(wps_ie, wpsie_len, WPS_ATTR_SELECTED_REGISTRAR,
+                                                      NULL, &attr_len);
+                               if (attr)
+                                       *(attr + 4) = 0;
+                       }
+               }
+       }
         //DBG_871X("clear wps when %s\n", __func__);
 
        if(rtw_to_roam(padapter) > 0)
@@ -1724,17 +1716,17 @@ inline void rtw_indicate_scan_done( _adapter *padapter, bool aborted)
 #endif // CONFIG_IPS
 }
 
-void rtw_scan_abort(_adapter *adapter)
+u32 rtw_scan_abort_timeout(_adapter *adapter, u32 timeout_ms)
 {
-       u32 cnt=0;
        u32 start;
+       u32 pass_ms;
        struct mlme_priv        *pmlmepriv = &(adapter->mlmepriv);
        struct mlme_ext_priv    *pmlmeext = &(adapter->mlmeextpriv);
 
        start = rtw_get_current_time();
        pmlmeext->scan_abort = _TRUE;
        while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)
-               && rtw_get_passing_time_ms(start) <= 200) {
+               && rtw_get_passing_time_ms(start) <= timeout_ms) {
 
                if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
                        break;
@@ -1749,11 +1741,28 @@ void rtw_scan_abort(_adapter *adapter)
                #ifdef CONFIG_PLATFORM_MSTAR
                //_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
                set_survey_timer(pmlmeext, 0);
-               _set_timer(&pmlmepriv->scan_to_timer, 50);
+               mlme_set_scan_to_timer(pmlmepriv, 50);
                #endif
                rtw_indicate_scan_done(adapter, _TRUE);
        }
        pmlmeext->scan_abort = _FALSE;
+       pass_ms = rtw_get_passing_time_ms(start);
+
+       return pass_ms;
+}
+
+void rtw_scan_abort_no_wait(_adapter *adapter)
+{
+       struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
+       struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
+
+       if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
+               pmlmeext->scan_abort = _TRUE;
+}
+
+void rtw_scan_abort(_adapter *adapter)
+{
+       rtw_scan_abort_timeout(adapter, 200);
 }
 
 static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wlan_network *pnetwork)
@@ -1849,6 +1858,7 @@ static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wl
                        #endif
                        preorder_ctrl->wend_b= 0xffff;
                        preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32
+                       preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
                }
 
                
@@ -1867,6 +1877,7 @@ static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wl
                                #endif
                                preorder_ctrl->wend_b= 0xffff;
                                preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32
+                               preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
                        }
                }
        }
@@ -2039,9 +2050,9 @@ _func_enter_;
 
                                        pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
                                        if(pcur_sta){
-                                               _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2);
+                                               //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2);
                                                rtw_free_stainfo(adapter,  pcur_sta);
-                                               _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2);
+                                               //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2);
                                        }
 
                                        ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
@@ -2183,10 +2194,6 @@ _func_enter_;
        rtw_os_xmit_schedule(adapter->pbuddy_adapter);
 #endif 
 
-#ifdef CONFIG_DUALMAC_CONCURRENT
-       dc_resume_xmit(adapter);
-#endif
-
 _func_exit_;
 }
 
@@ -2392,7 +2399,7 @@ _func_enter_;
        
 #ifdef CONFIG_RTL8711
        //submit SetStaKey_cmd to tell fw, fw will allocate an CAM entry for this sta   
-       rtw_setstakey_cmd(adapter, psta, _FALSE, _TRUE);
+       rtw_setstakey_cmd(adapter, psta, GROUP_KEY, _TRUE);
 #endif
                
 exit:
@@ -2487,6 +2494,7 @@ _func_enter_;
 
                rtw_free_assoc_resources(adapter, 1);
                rtw_indicate_disconnect(adapter);
+               rtw_free_mlme_priv_ie_data(pmlmepriv);
 
                _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
                // remove the network entry in scanned_queue
@@ -2509,9 +2517,9 @@ _func_enter_;
              check_fwstate(pmlmepriv,WIFI_ADHOC_STATE))
        {
                
-               _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+               //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
                rtw_free_stainfo(adapter,  psta);
-               _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+               //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
                
                if(adapter->stapriv.asoc_sta_count== 1) //a sta + bc/mc_stainfo (not Ibss_stainfo)
                { 
@@ -2680,16 +2688,19 @@ _func_exit_;
 void rtw_scan_timeout_handler (_adapter *adapter)
 {      
        _irqL irqL;
-       struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
-       
+       struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
        DBG_871X(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
 
        _enter_critical_bh(&pmlmepriv->lock, &irqL);
        
        _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
-
+       
        _exit_critical_bh(&pmlmepriv->lock, &irqL);
-
+       
+#ifdef CONFIG_IOCTL_CFG80211
+       rtw_cfg80211_surveydone_event_callback(adapter);
+#endif //CONFIG_IOCTL_CFG80211
+       
        rtw_indicate_scan_done(adapter, _TRUE);
 
 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_IOCTL_CFG80211)
@@ -2829,7 +2840,7 @@ void rtw_dynamic_check_timer_handlder(_adapter *adapter)
                DBG_871X("IsBtDisabled=%d, IsBtControlLps=%d\n", rtw_btcoex_IsBtDisabled(adapter), rtw_btcoex_IsBtControlLps(adapter));
 #endif
 
-#ifdef CONFIG_LPS_LCLK_WD_TIMER
+#ifdef CONFIG_LPS_LCLK_WD_TIMER /* to avoid leaving lps 32k frequently*/
        if ((adapter_to_pwrctl(adapter)->bFwCurrentInPSMode ==_TRUE )
 #ifdef CONFIG_BT_COEXIST
                && (rtw_btcoex_IsBtControlLps(adapter) == _FALSE)
@@ -2838,7 +2849,7 @@ void rtw_dynamic_check_timer_handlder(_adapter *adapter)
        {
                u8 bEnterPS;    
                
-               linked_status_chk(adapter);     
+               linked_status_chk(adapter, 1);  
                        
                bEnterPS = traffic_status_watchdog(adapter, 1);
                if(bEnterPS)
@@ -2921,7 +2932,7 @@ inline void rtw_clear_scan_deny(_adapter *adapter)
        struct mlme_priv *mlmepriv = &adapter->mlmepriv;
        ATOMIC_SET(&mlmepriv->set_scan_deny, 0);
        if (0)
-       DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
+               DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
 }
 
 void rtw_set_scan_deny_timer_hdl(_adapter *adapter)
@@ -2937,7 +2948,7 @@ void rtw_set_scan_deny(_adapter *adapter, u32 ms)
 #endif
 
        if (0)
-       DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
+               DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
        ATOMIC_SET(&mlmepriv->set_scan_deny, 1);
        _set_timer(&mlmepriv->set_scan_deny_timer, ms);
        
@@ -2946,7 +2957,7 @@ void rtw_set_scan_deny(_adapter *adapter, u32 ms)
                return;
 
        if (0)
-       DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter->pbuddy_adapter));
+               DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter->pbuddy_adapter));
        b_mlmepriv = &adapter->pbuddy_adapter->mlmepriv;
        ATOMIC_SET(&b_mlmepriv->set_scan_deny, 1);
        _set_timer(&b_mlmepriv->set_scan_deny_timer, ms);       
@@ -3046,11 +3057,11 @@ _func_enter_;
                mlme->pscanned = get_next(mlme->pscanned);
 
                if (0)
-               DBG_871X("%s("MAC_FMT", ch%u) rssi:%d\n"
-                       , pnetwork->network.Ssid.Ssid
-                       , MAC_ARG(pnetwork->network.MacAddress)
-                       , pnetwork->network.Configuration.DSConfig
-                       , (int)pnetwork->network.Rssi);
+                       DBG_871X("%s("MAC_FMT", ch%u) rssi:%d\n"
+                               , pnetwork->network.Ssid.Ssid
+                               , MAC_ARG(pnetwork->network.MacAddress)
+                               , pnetwork->network.Configuration.DSConfig
+                               , (int)pnetwork->network.Rssi);
 
                rtw_check_roaming_candidate(mlme, &candidate, pnetwork);
  
@@ -3124,16 +3135,11 @@ static int rtw_check_join_candidate(struct mlme_priv *mlme
        }
 
        if(updated){
-               DBG_871X("[by_bssid:%u][assoc_ssid:%s]"
-                       #ifdef  CONFIG_LAYER2_ROAMING
-                       "[to_roam:%u] "
-                       #endif
+               DBG_871X("[by_bssid:%u][assoc_ssid:%s][to_roam:%u] "
                        "new candidate: %s("MAC_FMT", ch%u) rssi:%d\n",
                        mlme->assoc_by_bssid,
                        mlme->assoc_ssid.Ssid,
-                       #ifdef  CONFIG_LAYER2_ROAMING
                        rtw_to_roam(adapter),
-                       #endif
                        (*candidate)->network.Ssid.Ssid,
                        MAC_ARG((*candidate)->network.MacAddress),
                        (*candidate)->network.Configuration.DSConfig,
@@ -3196,11 +3202,11 @@ _func_enter_;
                pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
 
                if (0)
-               DBG_871X("%s("MAC_FMT", ch%u) rssi:%d\n"
-                       , pnetwork->network.Ssid.Ssid
-                       , MAC_ARG(pnetwork->network.MacAddress)
-                       , pnetwork->network.Configuration.DSConfig
-                       , (int)pnetwork->network.Rssi);
+                       DBG_871X("%s("MAC_FMT", ch%u) rssi:%d\n"
+                               , pnetwork->network.Ssid.Ssid
+                               , MAC_ARG(pnetwork->network.MacAddress)
+                               , pnetwork->network.Configuration.DSConfig
+                               , (int)pnetwork->network.Rssi);
 
                rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
  
@@ -3506,22 +3512,67 @@ static int SecIsInPMKIDList(_adapter *Adapter, u8 *bssid)
 // 13th element in the array is the IE length  
 //
 
-static int rtw_append_pmkid(_adapter *Adapter,int iEntry, u8 *ie, uint ie_len)
+static int rtw_append_pmkid(_adapter *adapter,int iEntry, u8 *ie, uint ie_len)
 {
-       struct security_priv *psecuritypriv=&Adapter->securitypriv;
+       struct security_priv *sec=&adapter->securitypriv;
 
-       if(ie[13]<=20){ 
-               // The RSN IE didn't include the PMK ID, append the PMK information 
-                       ie[ie_len]=1;
-                       ie_len++;
-                       ie[ie_len]=0;   //PMKID count = 0x0100
-                       ie_len++;
-                       _rtw_memcpy(    &ie[ie_len], &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
-               
-                       ie_len+=16;
-                       ie[13]+=18;//PMKID length = 2+16
+       if (ie[13] > 20) {
+               int i;
+               u16 pmkid_cnt = RTW_GET_LE16(ie+14+20);
+               if (pmkid_cnt == 1 && _rtw_memcmp(ie+14+20+2, &sec->PMKIDList[iEntry].PMKID, 16)) {
+                       DBG_871X(FUNC_ADPT_FMT" has carried the same PMKID:"KEY_FMT"\n"
+                               , FUNC_ADPT_ARG(adapter), KEY_ARG(&sec->PMKIDList[iEntry].PMKID));
+                       goto exit;
+               }
+
+               DBG_871X(FUNC_ADPT_FMT" remove original PMKID, count:%u\n"
+                       , FUNC_ADPT_ARG(adapter), pmkid_cnt);
+
+               for (i=0;i<pmkid_cnt;i++)
+                       DBG_871X("    "KEY_FMT"\n", KEY_ARG(ie+14+20+2+i*16));
 
+               ie_len -= 2+pmkid_cnt*16;
+               ie[13] = 20;
        }
+
+       if (ie[13] <= 20) {     
+               /* The RSN IE didn't include the PMK ID, append the PMK information */
+
+               DBG_871X(FUNC_ADPT_FMT" append PMKID:"KEY_FMT"\n"
+                               , FUNC_ADPT_ARG(adapter), KEY_ARG(&sec->PMKIDList[iEntry].PMKID));
+
+               RTW_PUT_LE16(&ie[ie_len], 1);
+               ie_len += 2;
+
+               _rtw_memcpy(&ie[ie_len], &sec->PMKIDList[iEntry].PMKID, 16);
+               ie_len += 16;
+
+               ie[13] += 18;//PMKID length = 2+16
+       }
+
+exit:
+       return (ie_len);
+}
+
+static int rtw_remove_pmkid(_adapter *adapter, u8 *ie, uint ie_len)
+{
+       struct security_priv *sec=&adapter->securitypriv;
+       int i;
+       u16 pmkid_cnt = RTW_GET_LE16(ie+14+20);
+
+       if (ie[13] <= 20)
+               goto exit;
+
+       DBG_871X(FUNC_ADPT_FMT" remove original PMKID, count:%u\n"
+               , FUNC_ADPT_ARG(adapter), pmkid_cnt);
+
+       for (i=0;i<pmkid_cnt;i++)
+               DBG_871X("    "KEY_FMT"\n", KEY_ARG(ie+14+20+2+i*16));
+
+       ie_len -= 2+pmkid_cnt*16;
+       ie[13] = 20;
+
+exit:
        return (ie_len);
 }
 
@@ -3581,14 +3632,13 @@ _func_enter_;
        iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
        if(iEntry<0)
        {
-               return ielength;
+               if(authmode == _WPA2_IE_ID_)
+                       ielength = rtw_remove_pmkid(adapter, out_ie, ielength);
        }
        else
        {
                if(authmode == _WPA2_IE_ID_)
-               {
                        ielength=rtw_append_pmkid(adapter, iEntry, out_ie, ielength);
-               }
        }
 
 _func_exit_;
@@ -3599,9 +3649,8 @@ _func_exit_;
 void rtw_init_registrypriv_dev_network(        _adapter* adapter)
 {
        struct registry_priv* pregistrypriv = &adapter->registrypriv;
-       struct eeprom_priv* peepriv = &adapter->eeprompriv;
        WLAN_BSSID_EX    *pdev_network = &pregistrypriv->dev_network;
-       u8 *myhwaddr = myid(peepriv);
+       u8 *myhwaddr = adapter_mac_addr(adapter);
        
 _func_enter_;
 
@@ -3629,6 +3678,7 @@ void rtw_update_registrypriv_dev_network(_adapter* adapter)
        struct  security_priv*  psecuritypriv = &adapter->securitypriv;
        struct  wlan_network    *cur_network = &adapter->mlmepriv.cur_network;
        //struct        xmit_priv       *pxmitpriv = &adapter->xmitpriv;
+       struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
 
 _func_enter_;
 
@@ -3676,9 +3726,15 @@ _func_enter_;
        pdev_network->Configuration.DSConfig = (pregistrypriv->channel);
        RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("pregistrypriv->channel=%d, pdev_network->Configuration.DSConfig=0x%x\n", pregistrypriv->channel, pdev_network->Configuration.DSConfig));  
 
-       if(cur_network->network.InfrastructureMode == Ndis802_11IBSS)
+       if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) {
                pdev_network->Configuration.ATIMWindow = (0);
 
+               if (pmlmeext->cur_channel != 0)
+                       pdev_network->Configuration.DSConfig = pmlmeext->cur_channel;
+               else 
+                       pdev_network->Configuration.DSConfig = 1;
+       }
+
        pdev_network->InfrastructureMode = (cur_network->network.InfrastructureMode);
 
        // 1. Supported rates
@@ -3712,17 +3768,10 @@ void rtw_joinbss_reset(_adapter *padapter)
 {
        u8      threshold;
        struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
-
-#ifdef CONFIG_80211N_HT        
-       struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
-#endif
-
        //todo: if you want to do something io/reg/hw setting before join_bss, please add code here
        
-
-
-
-#ifdef CONFIG_80211N_HT
+#ifdef CONFIG_80211N_HT        
+       struct ht_priv          *phtpriv = &pmlmepriv->htpriv;  
 
        pmlmepriv->num_FortyMHzIntolerant = 0;
 
@@ -3746,9 +3795,9 @@ void rtw_joinbss_reset(_adapter *padapter)
                threshold = 1;
                rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
        }
-#endif
+#endif//#if defined( CONFIG_USB_HCI) || defined (CONFIG_SDIO_HCI)
 
-#endif 
+#endif//#ifdef CONFIG_80211N_HT
 
 }
 
@@ -3911,6 +3960,12 @@ unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, ui
        /* todo: disable SM power save mode */
        ht_capie.cap_info |= IEEE80211_HT_CAP_SM_PS;
 
+       /* RX LDPC */
+       if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX)) {
+               ht_capie.cap_info |= IEEE80211_HT_CAP_LDPC_CODING;
+               DBG_871X("[HT] Declare supporting RX LDPC\n");
+       }
+
        if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX)) {
                if((pregistrypriv->rx_stbc == 0x3) ||                                                   /* enable for 2.4/5 GHz */
                        ((channel <= 14) && (pregistrypriv->rx_stbc == 0x1)) || /* enable for 2.4GHz */
@@ -3939,8 +3994,6 @@ unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, ui
 
        case RF_2T2R:
        case RF_1T2R:
-       default:
-
                if (stbc_rx_enable)
                        ht_capie.cap_info |= IEEE80211_HT_CAP_RX_STBC_2R;//RX STBC two spatial stream
 
@@ -3950,9 +4003,14 @@ unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, ui
                else
                                set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R);       
                #else //CONFIG_DISABLE_MCS13TO15
-                       set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R);       
+                       set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R);
                #endif //CONFIG_DISABLE_MCS13TO15
                break;
+       case RF_3T3R:
+               set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_3R);
+               break;
+       default:
+               DBG_871X("[warning] rf_type %d is not expected\n", rf_type);
        }
 
        {
@@ -3985,11 +4043,17 @@ unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, ui
        //rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
        ht_capie.ampdu_params_info = (max_rx_ampdu_factor&0x03);
 
-       if(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_ )
-               ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
+       if(padapter->driver_rx_ampdu_spacing != 0xFF) 
+       {
+               ht_capie.ampdu_params_info |= (( padapter->driver_rx_ampdu_spacing&0x07) <<2);  
+       }
        else
-               ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
-
+       {
+               if(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_ )
+                       ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
+               else
+                       ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
+       }
 #ifdef CONFIG_BEAMFORMING
        ht_capie.tx_BF_cap_info = 0;
 
@@ -4118,7 +4182,7 @@ void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel)
                (pmlmeinfo->HT_info.infos[0] & BIT(2)))
        {
                int i;
-               u8      rf_type;
+               u8      rf_type = RF_1T1R;
 
                rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
 
@@ -4133,9 +4197,8 @@ void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel)
                        case RF_1T2R:
                                set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R);                                                        
                                break;
-                       case RF_2T2R:                   
-                       default:
-#ifdef CONFIG_DISABLE_MCS13TO15
+                       case RF_2T2R:
+                               #ifdef CONFIG_DISABLE_MCS13TO15
                                if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 && pregistrypriv->wifi_spec != 1 )                          
                                        set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R_13TO15_OFF);                             
                                else
@@ -4143,6 +4206,12 @@ void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel)
 #else //CONFIG_DISABLE_MCS13TO15
                                set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R);
 #endif //CONFIG_DISABLE_MCS13TO15
+                               break;
+                       case RF_3T3R:
+                               set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_3R);
+                               break;
+                       default:
+                               DBG_871X("[warning] rf_type %d is not expected\n", rf_type);
                }
 
                //switch to the 40M Hz mode accoring to the AP
@@ -4239,21 +4308,17 @@ void rtw_issue_addbareq_cmd_tdls(_adapter *padapter, struct xmit_frame *pxmitfra
 
        priority = pattrib->priority;
 
-       if(pattrib->direct_link == _TRUE)
-       {
+       if (pattrib->direct_link == _TRUE) {
                ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
-               if((ptdls_sta != NULL) && (ptdls_sta->tdls_sta_state & TDLS_ESTABLISHED))
-               {
+               if ((ptdls_sta != NULL) && (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)) {
                        phtpriv = &ptdls_sta->htpriv;
 
-                       if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE)) 
-                       {
+                       if ((phtpriv->ht_option == _TRUE) && (phtpriv->ampdu_enable == _TRUE)) {
                                issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
                                issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
 
-                               if(0==issued)
-                               {
-                                       DBG_871X("rtw_issue_addbareq_cmd, p=%d\n", priority);
+                               if (0 == issued) {
+                                       DBG_871X("[%s], p=%d\n", __FUNCTION__, priority);
                                        ptdls_sta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
                                        rtw_addbareq_cmd(padapter,(u8)priority, pattrib->dst);
                                }
@@ -4328,7 +4393,7 @@ void rtw_append_exented_cap(_adapter *padapter, u8 *out_ie, uint *pout_len)
 #endif //CONFIG_80211AC_VHT
        u8      cap_content[8] = {0};
        u8      *pframe;
-
+       u8   null_content[8] = {0};
 
        if (phtpriv->bss_coexist) {
                SET_EXT_CAPABILITY_ELE_BSS_COEXIST(cap_content, 1);
@@ -4339,8 +4404,13 @@ void rtw_append_exented_cap(_adapter *padapter, u8 *out_ie, uint *pout_len)
                SET_EXT_CAPABILITY_ELE_OP_MODE_NOTIF(cap_content, 1);
        }
 #endif //CONFIG_80211AC_VHT
-
-       pframe = rtw_set_ie(out_ie+*pout_len, EID_EXTCapability, 8, cap_content , pout_len);
+       /*
+               From 802.11 specification,if a STA does not support any of capabilities defined
+               in the Extended Capabilities element, then the STA is not required to 
+               transmit the Extended Capabilities element. 
+       */
+       if (_FALSE == _rtw_memcmp(cap_content, null_content, 8))
+               pframe = rtw_set_ie(out_ie + *pout_len, EID_EXTCapability, 8, cap_content , pout_len);
 }
 #endif
 
@@ -4484,3 +4554,19 @@ u8 rtw_get_buddy_bBusyTraffic(_adapter *padapter)
 }
 
 #endif //CONFIG_CONCURRENT_MODE
+
+static const char *miracast_mode_str[] = {
+       "DISABLED",
+       "SOURCE",
+       "SINK",
+       "INVALID",
+};
+
+const char *get_miracast_mode_str(int mode)
+{
+       if (mode < MIRACAST_DISABLED || mode >= MIRACAST_INVALID)
+               mode = MIRACAST_INVALID;
+
+       return miracast_mode_str[mode];
+}
+