From 287f6491f3db01ff294b745509cf8dd3f9e093d0 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 20 Nov 2014 00:12:27 -0600 Subject: [PATCH] rtl8188eu: Part 3 of the upgrades from rtl8188EUS_rtl8189ES_linux_v4.1.8_9499.20131104 Signed-off-by: Larry Finger --- core/rtw_mlme_ext.c | 32 ++++++++++++----- core/rtw_mp.c | 31 ++++++++++++----- core/rtw_pwrctrl.c | 22 +++++++----- core/rtw_recv.c | 84 ++++++++++++++++++++++++--------------------- hal/hal_intf.c | 8 +++++ include/hal_intf.h | 4 +++ 6 files changed, 117 insertions(+), 64 deletions(-) diff --git a/core/rtw_mlme_ext.c b/core/rtw_mlme_ext.c index a807e69..afff594 100644 --- a/core/rtw_mlme_ext.c +++ b/core/rtw_mlme_ext.c @@ -227,9 +227,6 @@ static void init_mlme_ext_priv_value(struct adapter *padapter) pmlmeext->cur_channel = padapter->registrypriv.channel; pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20; pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - pmlmeext->oper_channel = pmlmeext->cur_channel ; - pmlmeext->oper_bwmode = pmlmeext->cur_bwmode; - pmlmeext->oper_ch_offset = pmlmeext->cur_ch_offset; pmlmeext->retry = 0; pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode; @@ -603,7 +600,8 @@ _continue: _issue_probersp: if (check_fwstate(pmlmepriv, _FW_LINKED) && - pmlmepriv->cur_network.join_res) + (pmlmepriv->cur_network.join_res || + check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq); } return _SUCCESS; @@ -711,7 +709,7 @@ unsigned int OnBeacon(struct adapter *padapter, union recv_frame *precv_frame) ret = rtw_check_bcn_info(padapter, pframe, len); if (!ret) { DBG_88E_LEVEL(_drv_info_, "ap has changed, disconnect now\n "); - receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 65535); + receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0); return _SUCCESS; } /* update WMM, ERP in the beacon */ @@ -1617,10 +1615,28 @@ unsigned int OnDeAuth(struct adapter *padapter, union recv_frame *precv_frame) } else #endif { - DBG_88E_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM\n", - reason, GetAddr3Ptr(pframe)); + int ignore_received_deauth = 0; - receive_disconnect(padapter, GetAddr3Ptr(pframe) , reason); + /* Before sending the auth frame to start the STA/GC mode connection with AP/GO, + * we will send the deauth first. + * However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth. + * Added the following code to avoid this case. + */ + if ((pmlmeinfo->state & WIFI_FW_AUTH_STATE) || + (pmlmeinfo->state & WIFI_FW_ASSOC_STATE )) { + if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA) { + ignore_received_deauth = 1; + } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) { + // TODO: 802.11r + ignore_received_deauth = 1; + } + } + + DBG_88E_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM, ignore = %d\n", + reason, GetAddr3Ptr(pframe), ignore_received_deauth); + + if (!ignore_received_deauth) + receive_disconnect(padapter, GetAddr3Ptr(pframe), reason); } pmlmepriv->LinkDetectInfo.bBusyTraffic = false; return _SUCCESS; diff --git a/core/rtw_mp.c b/core/rtw_mp.c index 9832dcb..185ec1f 100644 --- a/core/rtw_mp.c +++ b/core/rtw_mp.c @@ -789,9 +789,11 @@ void SetPacketRx(struct adapter *pAdapter, u8 bStartRx) if (bStartRx) { /* Accept CRC error and destination address */ - pHalData->ReceiveConfig = AAP | APM | AM | AB | APP_ICV | ADF | AMF | HTC_LOC_CTRL | APP_MIC | APP_PHYSTS; + pHalData->ReceiveConfig = AAP | APM | AM | AB | APP_ICV | + AMF | ADF | APP_FCS | HTC_LOC_CTRL | + APP_MIC | APP_PHYSTS; - pHalData->ReceiveConfig |= ACRC32; + pHalData->ReceiveConfig |= (RCR_ACRC32 | RCR_AAP); rtw_write32(pAdapter, REG_RCR, pHalData->ReceiveConfig); @@ -881,7 +883,6 @@ static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point) * 256 128 128 + 256 = 384 * 512 256 256 + 512 = 768 * 1024 512 512 + 1024 = 1536 - * */ u32 mp_query_psd(struct adapter *pAdapter, u8 *data) { @@ -926,8 +927,8 @@ u32 mp_query_psd(struct adapter *pAdapter, u8 *data) void _rtw_mp_xmit_priv(struct xmit_priv *pxmitpriv) { - int i, res; - struct adapter *padapter = pxmitpriv->adapter; + int i, res; + struct adapter *padapter = pxmitpriv->adapter; struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; @@ -936,8 +937,8 @@ void _rtw_mp_xmit_priv(struct xmit_priv *pxmitpriv) max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; num_xmit_extbuf = NR_XMIT_EXTBUFF; } else { - max_xmit_extbuf_size = 20000; - num_xmit_extbuf = 1; + max_xmit_extbuf_size = 6000; + num_xmit_extbuf = 8; } pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; @@ -951,8 +952,8 @@ void _rtw_mp_xmit_priv(struct xmit_priv *pxmitpriv) rtw_vmfree(pxmitpriv->pallocated_xmit_extbuf, num_xmit_extbuf * sizeof(struct xmit_buf) + 4); if (padapter->registrypriv.mp_mode == 0) { - max_xmit_extbuf_size = 20000; - num_xmit_extbuf = 1; + max_xmit_extbuf_size = 6000; + num_xmit_extbuf = 8; } else { max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; num_xmit_extbuf = NR_XMIT_EXTBUFF; @@ -995,3 +996,15 @@ void _rtw_mp_xmit_priv(struct xmit_priv *pxmitpriv) exit: ; } + +void Hal_ProSetCrystalCap (struct adapter *pAdapter, u32 CrystalCapVal) +{ + struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter); + + CrystalCapVal = CrystalCapVal & 0x3F; + + // write 0x24[16:11] = 0x24[22:17] = CrystalCap + PHY_SetBBReg(pAdapter, REG_AFE_XTAL_CTRL, 0x7FF800, + (CrystalCapVal | (CrystalCapVal << 6))); +} + diff --git a/core/rtw_pwrctrl.c b/core/rtw_pwrctrl.c index b45461f..3e8c8a7 100644 --- a/core/rtw_pwrctrl.c +++ b/core/rtw_pwrctrl.c @@ -127,6 +127,7 @@ static bool rtw_pwr_unassociated_idle(struct adapter *adapter) if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) || check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) || + check_fwstate(pmlmepriv, WIFI_UNDER_WPS) || check_fwstate(pmlmepriv, WIFI_AP_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) || #if defined(CONFIG_88EU_P2P) @@ -422,7 +423,8 @@ _func_enter_; pwrpriv->bpower_saving = true; DBG_88E("%s smart_ps:%d\n", __func__, pwrpriv->smart_ps); /* For Tenda W311R IOT issue */ - rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, pwrpriv->smart_ps, 0); + rtw_set_ps_mode(padapter, pwrpriv->power_mgnt, + pwrpriv->smart_ps, 0x40); } } else { pwrpriv->LpsIdleCount++; @@ -444,7 +446,7 @@ _func_enter_; if (pwrpriv->bLeisurePs) { if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) { - rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0); + rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0x40); if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) LPS_RF_ON_check(padapter, LPS_LEAVE_TIMEOUT_MS); @@ -560,12 +562,11 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; int ret = _SUCCESS; + u32 start = rtw_get_current_time(); if (pwrpriv->ips_deny_time < rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms)) pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ips_deffer_ms); -{ - u32 start = rtw_get_current_time(); if (pwrpriv->ps_processing) { DBG_88E("%s wait ps_processing...\n", __func__); while (pwrpriv->ps_processing && rtw_get_passing_time_ms(start) <= 3000) @@ -575,12 +576,17 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal else DBG_88E("%s wait ps_processing done\n", __func__); } -} /* System suspend is not allowed to wakeup */ - if ((!pwrpriv->bInternalAutoSuspend) && (pwrpriv->bInSuspend)) { - ret = _FAIL; - goto exit; + if ((!pwrpriv->bInternalAutoSuspend) && pwrpriv->bInSuspend) { + while (pwrpriv->bInSuspend && + (rtw_get_passing_time_ms(start) <= 3000 || + (rtw_get_passing_time_ms(start) <= 500))) + rtw_msleep_os(10); + if (pwrpriv->bInSuspend) + DBG_88E("%s wait bInSuspend timeout\n", __func__); + else + DBG_88E("%s wait bInSuspend done\n", __func__); } /* block??? */ diff --git a/core/rtw_recv.c b/core/rtw_recv.c index adacbde..82443ab 100644 --- a/core/rtw_recv.c +++ b/core/rtw_recv.c @@ -548,6 +548,8 @@ _func_enter_; if (res == _FAIL) { rtw_free_recvframe(return_packet, &padapter->recvpriv.free_recv_queue); return_packet = NULL; + } else { + prxattrib->bdecrypted = true; } _func_exit_; @@ -572,7 +574,6 @@ static union recv_frame *portctrl(struct adapter *adapter, union recv_frame *pre _func_enter_; pstapriv = &adapter->stapriv; - psta = rtw_get_stainfo(pstapriv, psta_addr); auth_alg = adapter->securitypriv.dot11AuthAlgrthm; @@ -583,7 +584,10 @@ _func_enter_; prtnframe = NULL; - RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:adapter->securitypriv.dot11AuthAlgrthm=%d\n", adapter->securitypriv.dot11AuthAlgrthm)); + psta = rtw_get_stainfo(pstapriv, psta_addr); + RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, + ("########portctrl:adapter->securitypriv.dot11AuthAlgrthm=%d\n", + adapter->securitypriv.dot11AuthAlgrthm)); if (auth_alg == 2) { if ((psta != NULL) && (psta->ieee8021x_blocked)) { @@ -1111,8 +1115,9 @@ static int validate_recv_ctrl_frame(struct adapter *padapter, unsigned long irqL; struct list_head *xmitframe_plist, *xmitframe_phead; struct xmit_frame *pxmitframe = NULL; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - _enter_critical_bh(&psta->sleep_q.lock, &irqL); + _enter_critical_bh(&pxmitpriv->lock, &irqL); xmitframe_phead = get_list_head(&psta->sleep_q); xmitframe_plist = get_next(xmitframe_phead); @@ -1133,10 +1138,7 @@ static int validate_recv_ctrl_frame(struct adapter *padapter, pxmitframe->attrib.triggered = 1; - _exit_critical_bh(&psta->sleep_q.lock, &irqL); - if (rtw_hal_xmit(padapter, pxmitframe) == true) - rtw_os_xmit_complete(padapter, pxmitframe); - _enter_critical_bh(&psta->sleep_q.lock, &irqL); + rtw_hal_xmitframe_enqueue(padapter, pxmitframe); if (psta->sleepq_len == 0) { pstapriv->tim_bitmap &= ~BIT(psta->aid); @@ -1164,8 +1166,7 @@ static int validate_recv_ctrl_frame(struct adapter *padapter, update_beacon(padapter, _TIM_IE_, NULL, false); } } - - _exit_critical_bh(&psta->sleep_q.lock, &irqL); + _exit_critical_bh(&pxmitpriv->lock, &irqL); } } @@ -1953,11 +1954,11 @@ static int recv_indicatepkt_reorder(struct adapter *padapter, union recv_frame * /* s1. */ wlanhdr_to_ethhdr(prframe); - if ((pattrib->qos != 1) || (pattrib->eth_type == 0x0806) || - (pattrib->ack_policy != 0)) { - if ((!padapter->bDriverStopped) && - (!padapter->bSurpriseRemoved)) { - RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ recv_indicatepkt_reorder -recv_func recv_indicatepkt\n")); + if (pattrib->qos != 1) { + if (!padapter->bDriverStopped && + !padapter->bSurpriseRemoved) { + RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, + ("@@@@ recv_indicatepkt_reorder -recv_func recv_indicatepkt\n")); rtw_recv_indicatepkt(padapter, prframe); return _SUCCESS; @@ -1991,13 +1992,8 @@ static int recv_indicatepkt_reorder(struct adapter *padapter, union recv_frame * preorder_ctrl->indicate_seq, pattrib->seq_num)); /* s2. check if winstart_b(indicate_seq) needs to been updated */ - if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) { - rtw_recv_indicatepkt(padapter, prframe); - - _exit_critical_bh(&ppending_recvframe_queue->lock, &irql); - - goto _success_exit; - } + if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) + goto _err_exit; /* s3. Insert all packet into Reorder Queue to maintain its ordering. */ if (!enqueue_reorder_recvframe(preorder_ctrl, prframe)) @@ -2102,18 +2098,16 @@ static int recv_func_prehandle(struct adapter *padapter, union recv_frame *rfram struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if (padapter->registrypriv.mp_mode == 1) { - if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)) { /* padapter->mppriv.check_mp_pkt == 0)) */ - if (pattrib->crc_err == 1) - padapter->mppriv.rx_crcerrpktcount++; - else - padapter->mppriv.rx_pktcount++; + if (pattrib->crc_err == 1) + padapter->mppriv.rx_crcerrpktcount++; + else + padapter->mppriv.rx_pktcount++; - if (check_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE) == false) { - RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("MP - Not in loopback mode , drop pkt\n")); - ret = _FAIL; - rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */ - goto exit; - } + if (check_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE) == false) { + RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("MP - Not in loopback mode , drop pkt\n")); + ret = _FAIL; + rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */ + goto exit; } } @@ -2180,14 +2174,18 @@ static int recv_func(struct adapter *padapter, union recv_frame *rframe) struct rx_pkt_attrib *prxattrib = &rframe->u.hdr.attrib; struct security_priv *psecuritypriv = &padapter->securitypriv; struct mlme_priv *mlmepriv = &padapter->mlmepriv; + struct recv_priv *recvpriv = &padapter->recvpriv; /* check if need to handle uc_swdec_pending_queue*/ - if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && psecuritypriv->busetkipkey) { + if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && + psecuritypriv->busetkipkey) { union recv_frame *pending_frame; + int cnt = 0; - while ((pending_frame = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue))) { - if (recv_func_posthandle(padapter, pending_frame) == _SUCCESS) - DBG_88E("%s: dequeue uc_swdec_pending_queue\n", __func__); + pending_frame = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue); + while (pending_frame) { + cnt++; + recv_func_posthandle(padapter, pending_frame); } } @@ -2198,13 +2196,21 @@ static int recv_func(struct adapter *padapter, union recv_frame *rframe) if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && !IS_MCAST(prxattrib->ra) && prxattrib->encrypt > 0 && (prxattrib->bdecrypted == 0 || psecuritypriv->sw_decrypt) && - !is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm) && - !psecuritypriv->busetkipkey) { + psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK && + !psecuritypriv->busetkipkey) { rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue); DBG_88E("%s: no key, enqueue uc_swdec_pending_queue\n", __func__); + if (recvpriv->free_recvframe_cnt < NR_RECVFRAME/4) { + /* to prevent from recvframe starvation, + * get recvframe from uc_swdec_pending_queue to + * free_recvframe_cnt */ + rframe = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue); + if (rframe) + goto do_posthandle; + } goto exit; } - +do_posthandle: ret = recv_func_posthandle(padapter, rframe); } diff --git a/hal/hal_intf.c b/hal/hal_intf.c index 5981404..fa5d50d 100644 --- a/hal/hal_intf.c +++ b/hal/hal_intf.c @@ -220,6 +220,14 @@ u8 rtw_hal_intf_ps_func(struct adapter *adapt, return _FAIL; } +s32 rtw_hal_xmitframe_enqueue(struct adapter *padapter, + struct xmit_frame *pxmitframe) +{ + if(padapter->HalFunc.hal_xmitframe_enqueue) + return padapter->HalFunc.hal_xmitframe_enqueue(padapter, pxmitframe); + return false; +} + s32 rtw_hal_xmit(struct adapter *adapt, struct xmit_frame *pxmitframe) { if (adapt->HalFunc.hal_xmit) diff --git a/include/hal_intf.h b/include/hal_intf.h index 439c3c9..49539b8 100644 --- a/include/hal_intf.h +++ b/include/hal_intf.h @@ -225,6 +225,8 @@ struct hal_ops { struct xmit_frame *pxmitframe); s32 (*mgnt_xmit)(struct adapter *padapter, struct xmit_frame *pmgntframe); + s32 (*hal_xmitframe_enqueue)(struct adapter *padapter, + struct xmit_frame *pxmitframe); u32 (*read_bbreg)(struct adapter *padapter, u32 RegAddr, u32 BitMask); @@ -363,6 +365,8 @@ u32 rtw_hal_inirp_deinit(struct adapter *padapter); u8 rtw_hal_intf_ps_func(struct adapter *padapter, enum hal_intf_ps_func efunc_id, u8 *val); +s32 rtw_hal_xmitframe_enqueue(struct adapter *padapter, + struct xmit_frame *pxmitframe); s32 rtw_hal_xmit(struct adapter *padapter, struct xmit_frame *pxmitframe); s32 rtw_hal_mgnt_xmit(struct adapter *padapter,